粒子生成

generateParticles<BaseParticles, Lattice>()

当用户调用water_block.generateParticles<BaseParticles, Lattice>()时,会进入以下函数:

//----------------------------------------------------------------------
// 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被推断为BaseParticlesParameters被推断为LatticeArgsargs为空参数包。

运行阶段

  1. 创建BaseParticlesunique_ptr。此时会调用BaseParticles的构造函数。构造函数主要做的是初始化粒子属性(位置、密度、体积、质量等)为nullptr

  2. 调用ParticleGenerator<BaseParticles, Lattice> particle_generator(*this, *particles);。此时调用ParticleGenerator<BaseParticles, Lattice>的构造函数:

    • 进入ParticleGenerator<BaseParticles>构造函数。

      ParticleGenerator<BaseParticles>构造完毕。

    • 进入GeneratingMethod<Lattice>构造函数:

      GeneratingMethod<Lattice>构造完毕。

    ParticleGenerator<BaseParticles, Lattice>构造完毕。

  3. 调用particle_generator对象的generateParticlesWithGeometricVariables()成员函数。这不是一个虚函数,对所有派生类来说都一样:

    • 进入prepareGeometricData(),对于ParticleGenerator<BaseParticles, Lattice>类,这个成员函数没有在shared目录中实现,而是在for_2D_buildfor_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()

  4. 调用particles->initializeBasicParticleVariables()。进入initializeBasicParticleVariables()

    退出initializeBasicParticleVariables()

  5. 调用sph_adaptation_->initializeAdaptationVariables(*particles)。如果没有特别adaptation,什么也不做。

  6. 调用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_bufferis_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成员函数:

  1. 调用ReserveSizeFactor()运算符:

    用户指定size_factor_为0.5,所以返回给buffer_size的值是当前real particle数目的一半。

    退出ReserveSizeFactor()运算。

  2. 调用allocateBufferParticles(base_particles, buffer_size),不是虚函数,直接调用基类的:

    particles_bound_递增buffer_size

    退出allocateBufferParticles(base_particles, buffer_size)

  3. is_particles_reserved_ = true

Last updated