22#ifdef ESPRESSO_STOKESIAN_DYNAMICS
26#include "stokesian_dynamics/sd_cpu.hpp"
30#include "communication.hpp"
31#include "system/System.hpp"
32#include "thermostat.hpp"
38#include <boost/serialization/is_bitwise_serializable.hpp>
63 template <
class Archive>
void serialize(Archive &ar,
long int ) {
73template <
typename ParticleIterable>
75 std::vector<double>
const &v_sd) {
83 for (
auto &p : parts) {
85 p.v()[0] = v_sd[6 * i + 0];
86 p.v()[1] = v_sd[6 * i + 1];
87 p.v()[2] = v_sd[6 * i + 2];
89 p.omega()[0] = v_sd[6 * i + 3];
90 p.omega()[1] = v_sd[6 * i + 4];
91 p.omega()[2] = v_sd[6 * i + 5];
98 std::unordered_map<int, double> radii,
100 : viscosity{viscosity}, radii{radii}, flags{flags} {
102 throw std::domain_error(
"Viscosity has an invalid value: " +
106 for (
auto const &[p_type, radius] :
radii) {
108 throw std::domain_error(
109 "Particle radius for type " + std::to_string(p_type) +
110 " has an invalid value: " + std::to_string(radius));
118 double const kT)
const {
120 std::vector<SD_particle_data> parts_buffer{};
121 parts_buffer.reserve(particles.
size());
123 std::ranges::transform(particles, std::back_inserter(parts_buffer),
130 std::size_t n_part = parts_buffer.size();
132 x_host.resize(6 * n_part);
133 f_host.resize(6 * n_part);
134 a_host.resize(n_part);
137 for (
auto const &p : parts_buffer) {
138 x_host[6 * i + 0] = p.pos[0];
139 x_host[6 * i + 1] = p.pos[1];
140 x_host[6 * i + 2] = p.pos[2];
142 x_host[6 * i + 3] = 1;
143 x_host[6 * i + 4] = 0;
144 x_host[6 * i + 5] = 0;
146 f_host[6 * i + 0] = p.ext_force.f[0];
147 f_host[6 * i + 1] = p.ext_force.f[1];
148 f_host[6 * i + 2] = p.ext_force.f[2];
150 f_host[6 * i + 3] = p.ext_force.torque[0];
151 f_host[6 * i + 4] = p.ext_force.torque[1];
152 f_host[6 * i + 5] = p.ext_force.torque[2];
154 a_host[i] =
radii.at(p.type);
159 v_sd = sd_cpu(x_host, f_host, a_host, n_part,
viscosity,
160 std::sqrt(kT / time_step),
164 v_sd.resize(particles.
size() * 6);
Vector implementation and trait types for boost qvm interoperability.
base_type::size_type size() const
boost::mpi::communicator comm_cart
The communicator.
void gather_buffer(std::vector< T, Allocator > &buffer, boost::mpi::communicator const &comm, int root=0)
Gather buffer with different size on each node.
void scatter_buffer(T *buffer, int n_elem, boost::mpi::communicator comm, int root=0)
Scatter buffer with different size on each node.
static void sd_update_locally(ParticleIterable const &parts, std::vector< double > const &v_sd)
Update translational and rotational velocities of all particles.
See for the Stokesian dynamics method used here.
uint64_t rng_counter() const
Get current value of the RNG.
uint32_t rng_seed() const
Force information on a particle.
Struct holding all information for one particle.
SD_particle_data()=default
SD_particle_data(Particle const &p)
void serialize(Archive &ar, long int)
StokesianDynamics()=default
void propagate_vel_pos(ParticleRangeStokesian const &particles, StokesianThermostat const &stokesian, double time_step, double kT) const
Take the forces and torques on all particles and compute velocities.
std::unordered_map< int, double > radii
Thermostat for Stokesian dynamics.