#pragma once #include #include namespace kel { namespace lbm { namespace sch { using namespace saw::schema; template using ParticleRigidBody = Struct< Member, "position">, Member, "position_old">, Member, Member, Member, "acceleration">, Member >; template using ParticleMask = Struct< Member, "grid"> >; template using Particle = Struct< Member, "rigid_body">, Member, "mask">, Member >; } template > class particle_system { private: saw::data>> particles_; void verlet_step(saw::data>& particle, saw::data time_step_delta){ auto& body = particle.template get<"rigid_body">(); auto& pos = body.template get<"position">(); auto& pos_old = body.template get<"position_old">(); auto& rot = body.template get<"rotation">(); auto& acc = body.template get<"acceleration">(); auto tsd_squared = time_step_delta * time_step_delta; saw::data> pos_new; // Actual step for(uint64_t i = 0u; i < D; ++i){ pos_new.at({{i}}) = saw::data{2.0} * pos.at({{i}}) - pos_old.at({{i}}) + acc.at({{i}}) * tsd_squared; } pos_old = pos; pos = pos_new; } public: /** * Add particle to this class and return an id representing this particle */ saw::error_or> add_particle(saw::data> particle__){ auto size = particles_.size(); auto eov = particles_.add(std::move(particle__)); if(eov.is_error()){ return std::move(eov.get_error()); } return size; } /* saw::data>& get_particle(saw::data id){ } */ void step(saw::data time_step_delta){ for(saw::data i{0u}; i < particles_.size(); ++i){ verlet_step(particles_.at(i), time_step_delta); } } template void update_particle_border(saw::data& latt){ (void) latt; for(auto& iter : particles_){ auto& par = iter; auto& body = par.template get<"rigid_body">(); auto& size = par.template get<"size">(); } } saw::data size() const { return particles_.size(); } /** * Mostly meant for unforeseen use cases. */ saw::data>& at(saw::data i){ return particles_.at(i); } }; } }