132 auto constexpr parallel_execution_policy =
false;
138 std::unordered_map<ParticleId, MoleculeId> virtual_site_id_for_mol_id;
141 std::unordered_map<MoleculeId, ComInfo> m_com_by_mol_id;
146 assert(not virtual_site_id_for_mol_id.contains(p.
mol_id()));
147 virtual_site_id_for_mol_id[p.
mol_id()] = p.
id();
149 if (not m_com_by_mol_id.contains(p.
mol_id())) {
152 auto const pos_unfolded =
154 m_com_by_mol_id[p.
mol_id()].total_mass += p.
mass();
155 m_com_by_mol_id[p.
mol_id()].weighted_position +=
156 p.
mass() * pos_unfolded;
159 parallel_execution_policy);
163 std::unordered_set<MoleculeId> local_mol_ids;
164 for (
auto const &mol_id : m_com_by_mol_id | std::views::keys) {
165 local_mol_ids.insert(mol_id);
169 std::vector<std::unordered_set<MoleculeId>> global_mol_ids{};
170 boost::mpi::all_gather(
comm_cart, local_mol_ids, global_mol_ids);
171 std::unordered_set<MoleculeId> unique_mol_ids{};
172 for (
auto const &mol_id_set : global_mol_ids) {
173 for (
auto const &mol_id : mol_id_set) {
174 unique_mol_ids.insert(mol_id);
177 std::vector<MoleculeId> flattened_mol_ids{unique_mol_ids.begin(),
178 unique_mol_ids.end()};
179 std::ranges::sort(flattened_mol_ids);
182 for (
auto const mol_id : flattened_mol_ids) {
183 double local_total_mass = 0.;
186 if (m_com_by_mol_id.contains(mol_id)) {
187 local_total_mass = m_com_by_mol_id[mol_id].total_mass;
188 local_weighted_position = m_com_by_mol_id[mol_id].weighted_position;
191 auto const total_mass =
192 boost::mpi::all_reduce(
comm_cart, local_total_mass, std::plus{});
193 auto const weighted_position =
194 boost::mpi::all_reduce(
comm_cart, local_weighted_position, std::plus{});
196 if (m_com_by_mol_id.contains(mol_id)) {
197 m_com_by_mol_id[mol_id].total_mass = total_mass;
198 m_com_by_mol_id[mol_id].weighted_position = weighted_position;
210 for (
auto const &[mol_id, com_info] : m_com_by_mol_id) {
211 if (not virtual_site_id_for_mol_id.contains(mol_id)) {
214 auto const vs_id = virtual_site_id_for_mol_id[mol_id];
216 auto folded_pos = com_info.weighted_position / com_info.total_mass;
221 vs_ptr->image_box() = image_box;
222 vs_ptr->mass() = com_info.total_mass;
223 vs_ptr->pos() = folded_pos;
232 auto constexpr parallel_execution_policy =
false;
238 std::unordered_map<ParticleId, Utils::Vector3d> force_for_vs_id;
240 std::unordered_map<ParticleId, double> mass_for_vs_id;
244 std::unordered_map<MoleculeId, ParticleId> virtual_site_id_for_mol_id;
248 assert(not virtual_site_id_for_mol_id.contains(p.
mol_id()));
249 virtual_site_id_for_mol_id[p.
mol_id()] = p.
id();
250 force_for_vs_id[p.
id()] = p.
force();
251 mass_for_vs_id[p.
id()] = p.
mass();
254 parallel_execution_policy);
269 not virtual_site_id_for_mol_id.contains(p.
mol_id())) {
272 auto const vs_id = virtual_site_id_for_mol_id.at(p.
mol_id());
274 (p.
mass() / mass_for_vs_id.at(vs_id)) * force_for_vs_id.at(vs_id);
276 parallel_execution_policy);
void gather_buffer(std::vector< T, Allocator > &buffer, boost::mpi::communicator const &comm, int root=0)
Gather buffer with different size on each node.
int identity
unique identifier for the particle.
Struct holding all information for one particle.
auto const & propagation() const
auto const & mass() const
auto const & image_box() const
auto const & mol_id() const
auto const & force() const