Palabos ()
PalaBos 的是一款高效的流体模拟及其建模库,开发基于C ++的STL(标准模板库) ,有极强的拓展性!尽管其源代码是开放,但是基于PalaBos 的FlowKit 公司已于2011年9月开始运营(http://www.flowkit.com/),主要为流体力学相关领域提供解决方案,并定制软件。主要的开发者为我的日内瓦朋友Jonas Latt博士,另外一个重要开发成员Orestis 博士也是我的合作者和好朋友,其主要的贡献在于湍流模型和多块加密的代码的开发。在版本1.0中,目前二维的多块加密是可用的,三维的曲面边界可用,需要提供stl 几何文件(参:examples/showCases/aneurysm)。PalaBos 的主要特点在于,其在并行结构上采取并行机制与模型分离的方式,使得应用建模与并行机制不相关。这也使得PalaBos 的易于扩展。下面举例来说明其代码特点:
对于二维计算下面两个基本的文件必须包括
#include "palabos2D.h"
#include "palabos2D.hh"
#include
#include
#include
#include
#include
基本的名字空间
using namespace plb;
using namespace plb::descriptors;
using namespace std;
typedef double T;
基本模型的描述。对于PalaBos ,众多模型的应用,都是通过DnQmDescriptor 来描述的。用户可自定义!
#define DESCRIPTOR D2Q9Descriptor
初场的定义,建议使用这种方法
T poiseuilleVelocity(plintiY, IncomprFlowParamconst& parameters) { T y = (T)iY / parameters.getResolution();
return 4.*parameters.getLatticeU() * (y-y*y);
}
压力的定义
T poiseuillePressure(plintiX, IncomprFlowParamconst& parameters) { T Lx = parameters.getNx()-1;
T Ly = parameters.getNy()-1;
return 8.*parameters.getLatticeNu()*parameters.getLatticeU() / (Ly*Ly) * (Lx/(T)2-(T)iX);
}
密度场的定义
T poiseuilleDensity(plintiX, IncomprFlowParamconst& parameters) {
return poiseuillePressure(iX,parameters)*DESCRIPTOR::invCs2 + (T)1; }
根据坐标进行速度初始化
template
class PoiseuilleVelocity {
public:
PoiseuilleV elocity(IncomprFlowParam parameters_)
: parameters(parameters_)
{ }
void operator()(plintiX, plintiY, Array& u) const {
u[0] = poiseuilleVelocity(iY, parameters);
u[1] = T();
}
private:
IncomprFlowParam parameters;
};
根据坐标进行密度初始化
template
class PoiseuilleDensity {
public:
PoiseuilleDensity(IncomprFlowParam parameters_)
: parameters(parameters_)
{ }
T operator()(plintiX, plintiY) const {
return poiseuilleDensity(iX,parameters);
}
private:
IncomprFlowParam parameters;
};
零速度场初始化
template
class PoiseuilleDensityAndZeroVelocity {
public:
PoiseuilleDensityAndZeroV elocity(IncomprFlowParam parameters_)
: parameters(parameters_)
{ }
void operator()(plintiX, plintiY, T& rho, Array& u) const {
rho = poiseuilleDensity(iX,parameters);
u[0] = T();
u[1] = T();
}
private:
IncomprFlowParam parameters;
};
枚举类型,表示边界类型
enumInletOutletT {pressure, velocity};
建立几何
void channelSetup( MultiBlockLattice2D& lattice,
IncomprFlowParamconst& parameters,
OnLatticeBoundaryCondition2D&boundaryCondition, InletOutletTinletOutlet )
{
constplintnx = parameters.getNx();
constplintny = parameters.getNy();
下边界
boundaryCondition.setV elocityConditionOnBlockBoundaries (
lattice, Box2D(0, nx-1, 0, 0) );
上边界
boundaryCondition.setV elocityConditionOnBlockBoundaries (
lattice, Box2D(0, nx-1, ny-1, ny-1) );
设置相关边界
if (inletOutlet == pressure) {
boundaryCondition.setPressureConditionOnBlockBoundaries (
lattice, Box2D(0,0, 1,ny-2) );
boundaryCondition.setPressureConditionOnBlockBoundaries (
lattice, Box2D(nx-1,nx-1, 1,ny-2) );
}
else {
boundaryCondition.setV elocityConditionOnBlockBoundaries (
lattice, Box2D(0,0, 1,ny-2) );
boundaryCondition.setV elocityConditionOnBlockBoundaries (
lattice, Box2D(nx-1,nx-1, 1,ny-2) );
}
设置常密度和速度,边界的速度和密度同时被施加
setBoundaryDensity (
lattice, lattice.getBoundingBox(),
PoiseuilleDensity(parameters) );
setBoundaryV elocity (
lattice, lattice.getBoundingBox(),
PoiseuilleV elocity(parameters) );
初始化平衡态
initializeAtEquilibrium (
lattice, lattice.getBoundingBox(),
PoiseuilleDensityAndZeroV elocity(parameters) );
初始化模拟系统
lattice.initialize();
}
图片文件保存
void writeGif(MultiBlockLattice2D& lattice, plintiter)
{
constplintimSize = 600;
ImageWriterimageWriter("leeloo");
imageWriter.writeScaledGif(createFileName("u", iter, 6),
*computeVelocityNorm(lattice),
imSize, imSize );
}
VTK 保存
void writeVTK(MultiBlockLattice2D& lattice,
IncomprFlowParamconst& parameters, plintiter)
{
T dx = parameters.getDeltaX();
T dt = parameters.getDeltaT();
VtkImageOutput2DvtkOut(createFileName("vtk", iter, 6), dx);
vtkOut.writeData(*computeVelocityNorm(lattice), "velocityNorm", dx/dt); vtkOut.writeData(*computeVelocity(lattice), "velocity", dx/dt);
}
计算均方根误差
T computeRMSerror ( MultiBlockLattice2D& lattice,
IncomprFlowParamconst& parameters )
{
MultiTensorField2DanalyticalVelocity(lattice);
setToFunction( analyticalVelocity, analyticalVelocity .getBoundingBox(),
PoiseuilleV elocity(parameters) );
MultiTensorField2DnumericalVelocity(lattice);
computeV elocity(lattice, numericalVelocity, lattice.getBoundingBox());
return 1./parameters.getLatticeU() *
std::sqrt( computeAverage( *computeNormSqr(
*subtract(analyticalVelocity , numericalVelocity)
) ) );
}
主函数
int main(intargc, char* argv[]) {
plbInit(&argc, &argv);
global::directories().setOutputDir("./tmp/");
基本参数,Orestis 为我加入了另外的个构造函数,可直接在物理空间中定义这些参数!后续我将给出分析!
IncomprFlowParam parameters(
(T) 2e-2, // uMax
(T) 5., // Re
60, // N
3., // lx
1. // ly
);
const T logT = (T)0.1;
const T imSave = (T)0.5;
const T vtkSave = (T)2.;
const T maxT = (T)15.1;
constInletOutletTinletOutlet = velocity;
写日志文件
writeLogFile(parameters, "Poiseuille flow");
使用MultiBlockLattice
MultiBlockLattice2D lattice (
parameters.getNx(), parameters.getNy(),
设置松弛参数
new BGKdynamics(parameters.getOmega()) );
声明边界
OnLatticeBoundaryCondition2D*
boundaryCondition = createLocalBoundaryCondition2D();
channelSetup(lattice, parameters, *boundaryCondition, inletOutlet);
主循环
for (plintiT=0; iT*parameters.getDeltaT()
if (iT%parameters.nStep(imSave)==0) {
pcout
writeGif(lattice, iT);
}
if (iT%parameters.nStep(vtkSave)==0 &&iT>0) {
pcout
writeVTK(lattice, parameters, iT);
}
if (iT%parameters.nStep(logT)==0) {
pcout
ArrayuCenter;
lattice.get(parameters.getNx()/2,parameters.getNy()/2).computeVelocity(uCenter); pcout
碰撞迁移,此函数不再有bool 类型参数,其不同于Openlb
lattice.collideAndStream();
}
删除边界对象
delete boundaryCondition;
}
由此上面代码可以看出,PalaBos 的结构是非常清晰的,用户在实现过程也异常的简单!
——以上资料出自http://blog.sina.com.cn/s/blog_6a40fba10100znv9.html
Paraview ()
Paraview 是一种开放源代码的,多平台数据分析和可视化软件包,使用Paraview 可以快速的进行数据的定量及定性分析。利用Paraview 既可以在图形化人机交互界面中从事图形图像处理,也可以由控制台通过程序实现数据处理。ParaView 支持海量数据的分布式可视化分析,既可以在笔记本电脑上实现数据分析,也可以在巨型机上数据的并行化分析。 ParaView 是对二维和三维数据进行分析和可视化的程序,它既是一个应用程序框架,也可以直接使用(Turn-Key )。ParaView 支持并行,可以运行于单处理器的工作站,也可以运行于分布式存储器的大型计算机。ParaView 用C++编写,基于VTK (Visualization ToolKit)开发,图形用户界面用Qt 开发,开源、跨平台。
下图为其操作界面。
详细说明参见文档《ParaView 1.4使用指南》
Salome ()
Salome 是一个为数值计算提供预处理和后处理的开放源代码的通用平台,由众多可再用组件构成,这些组件适用于多种硬件架构。Salome 是一种前后处理的交叉平台解决方案,同样基于GNU GPL 协议,可以从其官方网站下载源代码及可执行文件。
Salome 既可以当作独立的应用软件包,用于数值计算的CAD 建模以及网格划分等前处理工具,以及结果分析的后处理工具。同时Salome 也可以用作集成平台,加入第三方数值模拟程序,构建完整的CAE 系统。
Palabos ()
PalaBos 的是一款高效的流体模拟及其建模库,开发基于C ++的STL(标准模板库) ,有极强的拓展性!尽管其源代码是开放,但是基于PalaBos 的FlowKit 公司已于2011年9月开始运营(http://www.flowkit.com/),主要为流体力学相关领域提供解决方案,并定制软件。主要的开发者为我的日内瓦朋友Jonas Latt博士,另外一个重要开发成员Orestis 博士也是我的合作者和好朋友,其主要的贡献在于湍流模型和多块加密的代码的开发。在版本1.0中,目前二维的多块加密是可用的,三维的曲面边界可用,需要提供stl 几何文件(参:examples/showCases/aneurysm)。PalaBos 的主要特点在于,其在并行结构上采取并行机制与模型分离的方式,使得应用建模与并行机制不相关。这也使得PalaBos 的易于扩展。下面举例来说明其代码特点:
对于二维计算下面两个基本的文件必须包括
#include "palabos2D.h"
#include "palabos2D.hh"
#include
#include
#include
#include
#include
基本的名字空间
using namespace plb;
using namespace plb::descriptors;
using namespace std;
typedef double T;
基本模型的描述。对于PalaBos ,众多模型的应用,都是通过DnQmDescriptor 来描述的。用户可自定义!
#define DESCRIPTOR D2Q9Descriptor
初场的定义,建议使用这种方法
T poiseuilleVelocity(plintiY, IncomprFlowParamconst& parameters) { T y = (T)iY / parameters.getResolution();
return 4.*parameters.getLatticeU() * (y-y*y);
}
压力的定义
T poiseuillePressure(plintiX, IncomprFlowParamconst& parameters) { T Lx = parameters.getNx()-1;
T Ly = parameters.getNy()-1;
return 8.*parameters.getLatticeNu()*parameters.getLatticeU() / (Ly*Ly) * (Lx/(T)2-(T)iX);
}
密度场的定义
T poiseuilleDensity(plintiX, IncomprFlowParamconst& parameters) {
return poiseuillePressure(iX,parameters)*DESCRIPTOR::invCs2 + (T)1; }
根据坐标进行速度初始化
template
class PoiseuilleVelocity {
public:
PoiseuilleV elocity(IncomprFlowParam parameters_)
: parameters(parameters_)
{ }
void operator()(plintiX, plintiY, Array& u) const {
u[0] = poiseuilleVelocity(iY, parameters);
u[1] = T();
}
private:
IncomprFlowParam parameters;
};
根据坐标进行密度初始化
template
class PoiseuilleDensity {
public:
PoiseuilleDensity(IncomprFlowParam parameters_)
: parameters(parameters_)
{ }
T operator()(plintiX, plintiY) const {
return poiseuilleDensity(iX,parameters);
}
private:
IncomprFlowParam parameters;
};
零速度场初始化
template
class PoiseuilleDensityAndZeroVelocity {
public:
PoiseuilleDensityAndZeroV elocity(IncomprFlowParam parameters_)
: parameters(parameters_)
{ }
void operator()(plintiX, plintiY, T& rho, Array& u) const {
rho = poiseuilleDensity(iX,parameters);
u[0] = T();
u[1] = T();
}
private:
IncomprFlowParam parameters;
};
枚举类型,表示边界类型
enumInletOutletT {pressure, velocity};
建立几何
void channelSetup( MultiBlockLattice2D& lattice,
IncomprFlowParamconst& parameters,
OnLatticeBoundaryCondition2D&boundaryCondition, InletOutletTinletOutlet )
{
constplintnx = parameters.getNx();
constplintny = parameters.getNy();
下边界
boundaryCondition.setV elocityConditionOnBlockBoundaries (
lattice, Box2D(0, nx-1, 0, 0) );
上边界
boundaryCondition.setV elocityConditionOnBlockBoundaries (
lattice, Box2D(0, nx-1, ny-1, ny-1) );
设置相关边界
if (inletOutlet == pressure) {
boundaryCondition.setPressureConditionOnBlockBoundaries (
lattice, Box2D(0,0, 1,ny-2) );
boundaryCondition.setPressureConditionOnBlockBoundaries (
lattice, Box2D(nx-1,nx-1, 1,ny-2) );
}
else {
boundaryCondition.setV elocityConditionOnBlockBoundaries (
lattice, Box2D(0,0, 1,ny-2) );
boundaryCondition.setV elocityConditionOnBlockBoundaries (
lattice, Box2D(nx-1,nx-1, 1,ny-2) );
}
设置常密度和速度,边界的速度和密度同时被施加
setBoundaryDensity (
lattice, lattice.getBoundingBox(),
PoiseuilleDensity(parameters) );
setBoundaryV elocity (
lattice, lattice.getBoundingBox(),
PoiseuilleV elocity(parameters) );
初始化平衡态
initializeAtEquilibrium (
lattice, lattice.getBoundingBox(),
PoiseuilleDensityAndZeroV elocity(parameters) );
初始化模拟系统
lattice.initialize();
}
图片文件保存
void writeGif(MultiBlockLattice2D& lattice, plintiter)
{
constplintimSize = 600;
ImageWriterimageWriter("leeloo");
imageWriter.writeScaledGif(createFileName("u", iter, 6),
*computeVelocityNorm(lattice),
imSize, imSize );
}
VTK 保存
void writeVTK(MultiBlockLattice2D& lattice,
IncomprFlowParamconst& parameters, plintiter)
{
T dx = parameters.getDeltaX();
T dt = parameters.getDeltaT();
VtkImageOutput2DvtkOut(createFileName("vtk", iter, 6), dx);
vtkOut.writeData(*computeVelocityNorm(lattice), "velocityNorm", dx/dt); vtkOut.writeData(*computeVelocity(lattice), "velocity", dx/dt);
}
计算均方根误差
T computeRMSerror ( MultiBlockLattice2D& lattice,
IncomprFlowParamconst& parameters )
{
MultiTensorField2DanalyticalVelocity(lattice);
setToFunction( analyticalVelocity, analyticalVelocity .getBoundingBox(),
PoiseuilleV elocity(parameters) );
MultiTensorField2DnumericalVelocity(lattice);
computeV elocity(lattice, numericalVelocity, lattice.getBoundingBox());
return 1./parameters.getLatticeU() *
std::sqrt( computeAverage( *computeNormSqr(
*subtract(analyticalVelocity , numericalVelocity)
) ) );
}
主函数
int main(intargc, char* argv[]) {
plbInit(&argc, &argv);
global::directories().setOutputDir("./tmp/");
基本参数,Orestis 为我加入了另外的个构造函数,可直接在物理空间中定义这些参数!后续我将给出分析!
IncomprFlowParam parameters(
(T) 2e-2, // uMax
(T) 5., // Re
60, // N
3., // lx
1. // ly
);
const T logT = (T)0.1;
const T imSave = (T)0.5;
const T vtkSave = (T)2.;
const T maxT = (T)15.1;
constInletOutletTinletOutlet = velocity;
写日志文件
writeLogFile(parameters, "Poiseuille flow");
使用MultiBlockLattice
MultiBlockLattice2D lattice (
parameters.getNx(), parameters.getNy(),
设置松弛参数
new BGKdynamics(parameters.getOmega()) );
声明边界
OnLatticeBoundaryCondition2D*
boundaryCondition = createLocalBoundaryCondition2D();
channelSetup(lattice, parameters, *boundaryCondition, inletOutlet);
主循环
for (plintiT=0; iT*parameters.getDeltaT()
if (iT%parameters.nStep(imSave)==0) {
pcout
writeGif(lattice, iT);
}
if (iT%parameters.nStep(vtkSave)==0 &&iT>0) {
pcout
writeVTK(lattice, parameters, iT);
}
if (iT%parameters.nStep(logT)==0) {
pcout
ArrayuCenter;
lattice.get(parameters.getNx()/2,parameters.getNy()/2).computeVelocity(uCenter); pcout
碰撞迁移,此函数不再有bool 类型参数,其不同于Openlb
lattice.collideAndStream();
}
删除边界对象
delete boundaryCondition;
}
由此上面代码可以看出,PalaBos 的结构是非常清晰的,用户在实现过程也异常的简单!
——以上资料出自http://blog.sina.com.cn/s/blog_6a40fba10100znv9.html
Paraview ()
Paraview 是一种开放源代码的,多平台数据分析和可视化软件包,使用Paraview 可以快速的进行数据的定量及定性分析。利用Paraview 既可以在图形化人机交互界面中从事图形图像处理,也可以由控制台通过程序实现数据处理。ParaView 支持海量数据的分布式可视化分析,既可以在笔记本电脑上实现数据分析,也可以在巨型机上数据的并行化分析。 ParaView 是对二维和三维数据进行分析和可视化的程序,它既是一个应用程序框架,也可以直接使用(Turn-Key )。ParaView 支持并行,可以运行于单处理器的工作站,也可以运行于分布式存储器的大型计算机。ParaView 用C++编写,基于VTK (Visualization ToolKit)开发,图形用户界面用Qt 开发,开源、跨平台。
下图为其操作界面。
详细说明参见文档《ParaView 1.4使用指南》
Salome ()
Salome 是一个为数值计算提供预处理和后处理的开放源代码的通用平台,由众多可再用组件构成,这些组件适用于多种硬件架构。Salome 是一种前后处理的交叉平台解决方案,同样基于GNU GPL 协议,可以从其官方网站下载源代码及可执行文件。
Salome 既可以当作独立的应用软件包,用于数值计算的CAD 建模以及网格划分等前处理工具,以及结果分析的后处理工具。同时Salome 也可以用作集成平台,加入第三方数值模拟程序,构建完整的CAE 系统。