generateParticles<BaseParticles, Lattice>()
当用户调用water_block.generateParticles<BaseParticles, Lattice>()时,会进入以下函数:
Copy // ----------------------------------------------------------------------
// Particle generating methods
// Initialize particle data using a particle generator for geometric data.
// The local material parameters are also initialized.
// ----------------------------------------------------------------------
template < class ParticleType , class ... Parameters , typename ... Args >
ParticleType * SPHBody :: generateParticles ( Args && ... args )
{
ParticleType * particles = base_particles_ptr_keeper_ . createPtr < ParticleType > ( * this , base_material_ ); // 1
ParticleGenerator < ParticleType , Parameters... > particle_generator ( * this , * particles , std :: forward < Args >( args ) ... ); // 2
particle_generator . generateParticlesWithGeometricVariables (); // 3
particles -> initializeBasicParticleVariables (); // 4
sph_adaptation_ -> initializeAdaptationVariables ( * particles ); // 5
base_material_ -> setLocalParameters ( sph_system_ , particles ); // 6
return particles ;
}; 编译阶段 :模板参数ParticleType被推断为BaseParticles,Parameters被推断为Lattice,Args和args为空参数包。
运行阶段 :
创建BaseParticles的unique_ptr。此时会调用BaseParticles的构造函数。构造函数主要做的是初始化粒子属性(位置、密度、体积、质量等)为nullptr。
调用ParticleGenerator<BaseParticles, Lattice> particle_generator(*this, *particles);。此时调用ParticleGenerator<BaseParticles, Lattice>的构造函数:
进入ParticleGenerator<BaseParticles>构造函数。
ParticleGenerator<BaseParticles>构造完毕。
进入GeneratingMethod<Lattice>构造函数:
GeneratingMethod<Lattice>构造完毕。
ParticleGenerator<BaseParticles, Lattice>构造完毕。
调用particle_generator对象的generateParticlesWithGeometricVariables()成员函数。这不是一个虚函数,对所有派生类来说都一样:
进入prepareGeometricData(),对于ParticleGenerator<BaseParticles, Lattice>类,这个成员函数没有在shared目录中实现,而是在for_2D_build和for_3D_build中实现。例如src\for_3D_build\particle_generator\particle_generator_lattice_3d.cpp:
退出prepareGeometricData()。
进入setAllParticleBounds()。ParticleGenerator<BaseParticles, Lattice>没有实现自己的这个成员函数,所以调用基类的成员函数:
作用是将real particles的数量(sv_total_real_particles_)和总粒子数量(particle_bound_)均设为prepareGeometricData中创建的粒子数目。
退出setAllParticleBounds()。
进入initializeParticleVariables()。目的是注册粒子的位置和体积:
进入registerPositionAndVolumetricMeasure:
退出registerPositionAndVolumetricMeasure。
退出initializeParticleVariables()。
退出generateParticlesWithGeometricVariables()。
调用particles->initializeBasicParticleVariables()。进入initializeBasicParticleVariables():
退出initializeBasicParticleVariables()。
调用sph_adaptation_->initializeAdaptationVariables(*particles)。如果没有特别adaptation,什么也不做。
调用base_material_->setLocalParameters(sph_system_, particles)。
generateParticlesWithReserve<BaseParticles, Lattice>(inlet_particle_buffer)
太长不看:generateParticlesWithReserve<BaseParticles, Lattice>(inlet_particle_buffer)在generateParticles<BaseParticles, Lattice>()的基础上,在particle_generator.generateParticlesWithGeometricVariables()的setAllParticleBounds()中将particles_bound_递增buffer_size(因为用户传入了0.5,所以递增real particle数目的一半),并设置inlet_particle_buffer的is_particles_reserved_属性为true。
首先调用generateParticles<BaseParticles, ParticleBuffer<ReserveSizeFactor>, Lattice>(inlet_particle_buffer)
进一步构造ParticleGenerator<BaseParticles, ParticleBuffer<ReserveSizeFactor>, Lattice>(*this, *particles, inlet_particle_buffer)。
ParticleGenerator<BaseParticles, ParticleBuffer<ReserveSizeFactor>, Lattice>继承于ParticleGenerator<BaseParticles, Lattice>,唯一区别是覆盖了setAllParticleBounds():
编译阶段 ,BufferSizeEstimator被推断为ReserveSizeFactor。
运行阶段 ,在ParticleGenerator<BaseParticles, ParticleBuffer<ReserveSizeFactor>, Lattice>::setAllParticleBounds()中,首先调用基类ParticleGenerator<BaseParticles, Lattice>::setAllParticleBounds(),然后调用ParticleBuffer<ReserveSizeFactor>的reserveBufferParticles成员函数:
调用ReserveSizeFactor的()运算符:
用户指定size_factor_为0.5,所以返回给buffer_size的值是当前real particle数目的一半。
退出ReserveSizeFactor的()运算。
调用allocateBufferParticles(base_particles, buffer_size),不是虚函数,直接调用基类的:
particles_bound_递增buffer_size。
退出allocateBufferParticles(base_particles, buffer_size)。
is_particles_reserved_ = true。
Last updated 2 months ago