externalFlowAroundObstacle.cpp
这个算例里,particle是不影响流体的,文中注释表明该算例的particles仅仅是可视化的作用,用于绘制流线图。
主要内容为:
使用的是DenseParticleField3D。
typedef DenseParticleField3D<T,DESCRIPTOR> ParticleFieldT;
定义参数。
int particleTimeFactor;
// If the particle time factor is 2, then the integration time step
// for the particles is twice that of the fluid.
T particleProbabilityPerCell;
// Probability of injection of a particle at an injection cell at each time step.
T cutOffSpeedSqr;
// Criterion to eliminate particles with very small velocity.
int maxNumParticlesToWrite;
// Maximum number of particles in the output VTK files.
定义MultiParticleField3D,particleArg,particleFluidArg,particleArg与cutOffSpeedSqr一起集成到AdvanceParticlesEveryWhereFunctional3D中,用于更新particles位置,数据处理器level为0,particleFluidArg与particleTimeFactor一起集成到FluidToParticleCoupling3D,用于更新particles速度,数据处理器level为1。
定义injectionDomain,用于后续输出particles时使用。
定义PointParticle3D至模板particleTemplate,从src源码来看,第一个是tag,第二个是坐标,第三个是速度,该particleTemplate用于后续输出particles时使用。
定义particleInjectionArg,与particleTemplate,particleProbabilityPerCell,injectionDomain一起被集成到InjectRandomParticlesFunctional3D里,数据处理器level为0。
定义出口Box3D absorbtionDomain(param.outlet);
,这里直接用了流场的出口位置,集成到数据处理器AbsorbParticlesFunctional3D上,level为0。
执行数据处理器particles->executeInternalProcessors();
。
MultiParticleField3D<ParticleFieldT>* particles = 0;
particles = new MultiParticleField3D<ParticleFieldT> (
lattice->getMultiBlockManagement(),
defaultMultiBlockPolicy3D().getCombinedStatistics() );
std::vector<MultiBlock3D*> particleArg;
particleArg.push_back(particles);
std::vector<MultiBlock3D*> particleFluidArg;
particleFluidArg.push_back(particles);
particleFluidArg.push_back(lattice);
// Functional that advances the particles to their new position at each predefined time step.
integrateProcessingFunctional (
new AdvanceParticlesEveryWhereFunctional3D<T,DESCRIPTOR>(param.cutOffSpeedSqr),
lattice->getBoundingBox(), particleArg, 0);
// Functional that assigns the particle velocity according to the particle's position in the fluid.
integrateProcessingFunctional (
new FluidToParticleCoupling3D<T,DESCRIPTOR>((T) param.particleTimeFactor),
lattice->getBoundingBox(), particleFluidArg, 1 );
// Definition of a domain from which particles will be injected in the flow field.
Box3D injectionDomain(0, 0, centerLB[1]-0.25*param.ny, centerLB[1]+0.25*param.ny,
centerLB[2]-0.25*param.nz, centerLB[2]+0.25*param.nz);
// Definition of simple mass-less particles.
Particle3D<T,DESCRIPTOR>* particleTemplate=0;
particleTemplate = new PointParticle3D<T,DESCRIPTOR>(0, Array<T,3>(0.,0.,0.), Array<T,3>(0.,0.,0.));
// Functional which injects particles with predefined probability from the specified injection domain.
std::vector<MultiBlock3D*> particleInjectionArg;
particleInjectionArg.push_back(particles);
integrateProcessingFunctional (
new InjectRandomParticlesFunctional3D<T,DESCRIPTOR>(particleTemplate, param.particleProbabilityPerCell),
injectionDomain, particleInjectionArg, 0 );
// Definition of an absorbtion domain for the particles.
Box3D absorbtionDomain(param.outlet);
// Functional which absorbs the particles which reach the specified absorbtion domain.
integrateProcessingFunctional (
new AbsorbParticlesFunctional3D<T,DESCRIPTOR>, absorbtionDomain, particleArg, 0 );
particles->executeInternalProcessors();
循环时,用于输出vtk文件。
if (i % param.vtkIter == 0) {
pcout << "Writing VTK at time t = " << i*param.dt << endl;
writeVTK(*boundaryCondition, i);
if (param.useParticles) {
writeParticleVtk<T,DESCRIPTOR> (
*particles, createFileName(outputDir+"particles_", i, PADDING) + ".vtk",
param.dx, param.maxNumParticlesToWrite );
}
}
在lattice进行碰撞迁移循环的时候,对particles也进行数据处理器的执行。
lattice->executeInternalProcessors();
lattice->incrementTime();
if (param.useParticles && i % param.particleTimeFactor == 0) {
particles->executeInternalProcessors();
}
小总结
如果想在流场中定义一个仅用于绘制流线图的particles,首先需要定义必须的参数,接着定义particleArg用于更新位置,particleFluidArg用于更新速度,particleInjectionArg用于生产particles,其次还需要particleTemplate来决定生产何种种类的particles,injectionDomain和absorbtionDomain用于决定生成和消除particles的区域位置。集成完毕后在lattice碰撞迁移后面增加particles->executeInternalProcessors();即可。