一款基于Web的动力学求解器学习和开发方案
方案一
使用Java实现Web服务器
1、技术选型
后端技术:
名称 | 版本号 |
---|---|
SpringCloud | Hoxton.SR1 |
MyBatis Plus | 3.2.0 |
SpringSecurity | 2.2.2.RELEASE |
Quartz | 2.3.2 |
SpringBoot | 2.2.2.RELEASE |
springCloud Alibaba | 2.1.0.RELEASE |
Alibaba-Nacos | 2.1.0.RELEASE |
mybatis Enhance Actable | 1.1.1.RELEASE |
anji-plus captcha | 1.2.3 |
前端技术:
名称 | 版本号 |
---|---|
VueJs | 2.6.10 |
element-ui | 2.13.0 |
2、开发工具
名称 | 工具 | 版本 |
---|---|---|
数据库 | MySql | 5.7 |
反向代理服务器 | Nginx | |
开发IDE | IntelliJ IDEA | 2019.3.3 |
数据库客户端 | HeidiSQL | 9.3 |
3、开发环境
- Jdk8+
- MySql5.6+
- Redis
- MongoDB
4、详细的架构方案
使用Java实现求解器
以一个简单的例子来说明实现思路,当然对于不同的求解具有不同的求解思路
1、高斯扩散模型
首先定义在下风向任一点(x,y,z)的污染物浓度公式如下:
$$ C(x,y,z,H)=\frac{Q}{2\pi\cdot \bar{u}\sigma_y\sigma_z}exp([-\frac{y^2}{2\sigma_y^2}]){exp[-\frac{(z-H)^2}{2\sigma_y^2}]+exp[-\frac{(z+H)^2}{2\sigma_y^2}]} $$
高斯模式的坐标系如图所示,其原点为排放点(无界点源或地面源)或高架源排放点在地面的投影点,x轴正向为平均风向,y轴在水平面上垂直于x轴,正向在x轴的左侧,z轴垂直于水平面xoy,向上为正向,即为右手坐标系。
大量的实验和理论研究证明,特别是对于连续源的平均烟流,其浓度分布是符合正态分布的。因此我们可以作如下假定:
(1) 污染物浓度在y、z轴上的分布符合高斯分布(正态分布);
(2) 在全部空间中风速是均匀的、稳定的;
(3) 源强是连续均匀的;
(4) 在扩散过程中污染物质量是守恒的(不考虑转化)。
代码实现为:
//参数定义
int emission, //污染物
int wind, //风速
int stability,//大气稳定度
int diameter, //放大比例
int w, int h
关键绘制代码
public static BufferedImage plot2D(Component paramComponent, Graphics paramGraphics, Set2D paramSet2D,
int[] paramArrayOfColor, int paramInt1, int paramInt2, int paramInt3, int paramInt4) {
int j = 0;
int k = paramSet2D.getMax();
int[][] arrayOfInt = paramSet2D.getSet();
int[] arrayOfInt1 = new int[paramInt3 * paramInt4];
//红色中心点的集合
List<Integer> centers = new ArrayList<Integer>();
for (int m = paramInt4 - 1; m >= 0; m--) {
for (int n = 0; n < paramInt3; n++) {
int i = paramArrayOfColor.length * arrayOfInt[n][m] / (k + 1);
arrayOfInt1[(j++)] = paramArrayOfColor[i];
//记录红色中心点
if(m==paramInt4/2 && paramArrayOfColor[i] == new Color(255, 0, 0, Formula.alpha).getRGB()){
centers.add(n);
}
}
}
if(centers.size() > 2){
PLOT2D_CENTER.set(centers.get(centers.size()/2));
}
// 根据数据集合生成内存图片
MemoryImageSource localMemoryImageSource = new MemoryImageSource(paramInt3, paramInt4, arrayOfInt1, 0,
paramInt3);
// 创建图片缓冲区
BufferedImage bi = new BufferedImage(paramInt3, paramInt4, BufferedImage.TYPE_3BYTE_BGR);
// 获取画笔并设置透明
Graphics2D g = bi.createGraphics();
bi = g.getDeviceConfiguration().createCompatibleImage(bi.getWidth(), bi.getHeight(), Transparency.TRANSLUCENT);
g.dispose();
g = bi.createGraphics();
// 写入图片到缓存区
g.drawImage(paramComponent.createImage(localMemoryImageSource), 0, 0, null);
return bi;
}
方案二
使用Python实现Web服务器
1、技术选型
后端技术:
名称 | 版本号 |
---|---|
Flask | 1.1.1 |
前端技术:
名称 | 版本号 |
---|---|
VueJs | 2.6.10 |
element-ui | 2.13.0 |
2、开发工具
名称 | 工具 | 版本 |
---|---|---|
数据库 | MySql | 5.7 |
反向代理服务器 | Nginx | |
开发IDE | Visual Studio Code | 1.47 |
数据库客户端 | HeidiSQL | 9.3 |
3、开发环境
- Python3
- MySql5.6+
- Redis
- MongoDB
使用Python实现求解器
以一个简单的例子说明实现思路,当然对于不同的求解具有不同的求解思路
1、2 维线性对流
首先需要明确控制2 维线性对流的偏微分方程(PDE)为:
$$ \frac{∂u}{∂t} + c \frac{∂u}{∂x} + c \frac{∂u}{∂y} = 0 $$
离散PDE方程写作:
$$ \frac{ u_{i,j}^{n+1}-u_{i,j}^n }{∆t} + c \frac{ u_{i,j}^{n}-u_{i-1,j}^n }{∆x} + c \frac{ u_{i,j}^{n}-u_{i,j-1}^n }{∆x} = 0 $$
要求解的未知量是:
$$ u_{i,j}^{n+1}=u_{i,j}^{n}-c \frac{∆t}{∆x}(u_{i,j}^n-u_{i-1,j}^n)-c \frac{∆y}{∆t} (u_{i,j}^n-u_{i,j-1}^n) $$
将在以下初始状态下求解该方程:
$$ u(x,y)=\begin{cases} 2\ for\ 0.5 \leq x,y \leq 1 \ 1\ for\ everywhere\ else\end{cases} $$
且边界条件:
$$ u=1\ for\ \begin{cases} x=0,2 \ y=0,2 \end{cases} $$
代码实现为:
from mpl_toolkits.mplot3d import Axes3D # 3 维绘图所需的库
import numpy
from matplotlib import pyplot, cm
# 声明变量
nx = 81
ny = 81
nt = 100
c = 1
dx = 2 / (nx − 1)
dy = 2 / (ny − 1)
sigma = .2
dt = sigma * dx
x = numpy.linspace(0, 2, nx)
y = numpy.linspace(0, 2, ny)
u = numpy.ones((ny, nx)) # 创建一个值均为1的1xn的向量
un = numpy.ones((ny, nx))
# 分配初始状态
# 设置帽子函数初始状态:u(.5<=x<=1&&.5<=y<=1)为2
u[int(.5 / dy):int(1 / dy + 1),int(.5 / dx):int(1 / dx + 1)] = 2
u = numpy.ones((ny, nx))
u[int(.5 / dy):int(1 / dy + 1), int(.5 / dx):int(1 / dx + 1)] = 2
for n in range(nt + 1): # 按 时 间 步 数 循 环
un = u.copy()
row, col = u.shape
for j in range(1, row):
for i in range(1, col):
u[j, i] = (un[j, i] − (c * dt / dx * (un[j, i] − un[j, i − 1]))
− (c * dt / dy * (un[j, i] − un[j − 1, i])))
u[0, :] = 1
u[−1, :] = 1
u[:, 0] = 1
u[:, −1] = 1
# 绘制初始状态
# 图形尺寸参数可用于产生不同尺寸的图像
fig = pyplot.figure(figsize=(11, 7), dpi=100)
ax = fig.gca(projection=’3d’)
X, Y = numpy.meshgrid(x, y)
surf2 = ax.plot_surface(X, Y, u[:], cmap=cm.viridis)
pyplot.show()
方案三
使用Python/Java 实现Web服务器
同方案一/方案二
使用OpenFOAM 实现求解器
1、OpenFOAM 简介
OpenFOAM (Open Source Field Operation and Manipulation 的缩写,意为 开源的场运算和处理 软件)是对连续介质力学问题进行数值计算的C++自由软件工具包,其代码遵守GNU通用公共许可证。它可进行数据预处理、后处理和自定义求解器,常用于 CFD 领域。
2. OpenFOAM使用方式
使用OpenFOAM进行CFD模拟,大致可分为 三种 类型:
- 直接利用OpenFOAM的标准求解器,替代商业软件。优点:免费,缺点:交互性差,对使用者要求较高;
- 自定义求解器,利用OpenFOAM的基本类库来按照自己的需求来编写针对某类应用的求解器。用户并不需要特别关心离散和求解的最底层的知识,如时间项、对流项的离散等,关注的重点是物理问题本身。在编程中,通常是顶层的求解流程的开发,不需要用户深入研习C++语言。商业软件中的所谓UDF和OpenFOAM是不能相提并论的;
- 自定义离散方法,属于更高级的应用,如果用户更关注时间项ddt,扩散项laplacian,对流项div是如何离散的,能否有更高效更高精度的离散方法,这需要修改finiteVolume库和OpenFOAM库中对应的代码。尤其是对流项,尽管OpenFOAM已经提供了基于NVD和TVD的模板和40多种有名的高阶高精度格式,但可以预见,这仍然是不够的,毕竟对流项的离散仍然是目前CFD的重点研究方向。
学习中ing