25#include "communication.hpp"
27#include "system/System.hpp"
31#include <boost/mpi/collectives/all_reduce.hpp>
32#include <boost/range/algorithm/find_if.hpp>
44 if (VolumeInitDone && !BoundariesFound) {
48 calc_volume_force(cs);
53 auto const &bonded_ias = *
get_system().bonded_ias;
56 if (
not BoundariesFound) {
57 BoundariesFound = std::ranges::any_of(
58 std::views::elements<1>(bonded_ias), [](
auto const &
handle) {
59 return std::holds_alternative<IBMVolCons>(*
handle);
63 if (!VolumeInitDone && BoundariesFound) {
69 for (
auto &
handle : std::views::elements<1>(bonded_ias)) {
70 if (
auto *v = std::get_if<IBMVolCons>(
handle.get())) {
74 BoundariesFound =
true;
75 if (v->volRef == 0.) {
76 v->volRef = VolumesCurrent[v->softID];
81 VolumeInitDone =
true;
88 auto const it = boost::find_if(
p1.bonds(), [&](
auto const &
bond) ->
bool {
89 return std::holds_alternative<IBMVolCons>(*bonded_ias.at(bond.bond_id()));
92 return (
it !=
p1.bonds().end())
93 ? std::get_if<IBMVolCons>(bonded_ias.
at(
it->bond_id()).get())
102 if (!BoundariesFound)
106 auto const &bonded_ias = *
get_system().bonded_ias;
109 std::vector<double>
tempVol(VolumesCurrent.size());
117 std::holds_alternative<IBMTriel>(*bonded_ias.at(bond_id).get())) {
126 auto const x1 = box_geo.unfolded_position(
p1.pos(),
p1.image_box());
127 auto const x2 =
x1 + box_geo.get_mi_vector(
p2.pos(),
x1);
128 auto const x3 =
x1 + box_geo.get_mi_vector(
p3.pos(),
x1);
155 static_cast<int>(
tempVol.size()),
156 VolumesCurrent.data(), std::plus<double>());
160void ImmersedBoundaries::calc_volume_force(
CellStructure &cs) {
161 if (!BoundariesFound)
165 auto const &bonded_ias = *
get_system().bonded_ias;
169 if (std::holds_alternative<IBMTriel>(*bonded_ias.at(bond_id).get())) {
174 auto const vol_cons_params = vol_cons_parameters(bonded_ias, p1);
175 if (not vol_cons_params)
178 auto const current_volume =
179 VolumesCurrent[static_cast<unsigned int>(vol_cons_params->softID)];
183 Particle &p2 = *partners[0];
184 Particle &p3 = *partners[1];
189 auto const x1 = box_geo.unfolded_position(p1.pos(), p1.image_box());
193 auto const a12 = box_geo.get_mi_vector(p2.pos(), x1);
194 auto const a13 = box_geo.get_mi_vector(p3.pos(), x1);
198 auto const n = vector_product(a12, a13);
199 const double ln = n.norm();
200 const double A = 0.5 * ln;
201 const double fact = vol_cons_params->kappaV *
202 (current_volume - vol_cons_params->volRef) /
205 auto const nHat = n / ln;
206 auto const force = -fact * A * nHat;
217 auto const new_size =
bond.softID + 1u;
218 if (new_size > VolumesCurrent.size()) {
219 VolumesCurrent.resize(new_size);
221 bond.set_volumes_view(VolumesCurrent);
static IBMVolCons const * vol_cons_parameters(BondedInteractionsMap const &bonded_ias, Particle const &p1)
Data structures for bonded interactions.
container for bonded interactions.
mapped_type at(key_type const &key) const
Describes a cell structure / cell system.
void bond_loop(BondKernel const &bond_kernel)
Bonded pair loop.
void volume_conservation(CellStructure &cs)
Calculate volumes, volume force and add it to each virtual particle.
void init_volume_conservation(CellStructure &cs)
Initialize volume conservation.
void register_softID(IBMVolCons &bond)
cudaStream_t stream[1]
CUDA streams for parallel computing on CPU and GPU.
boost::mpi::communicator comm_cart
The communicator.
Parameters for IBM volume conservation bond.
Struct holding all information for one particle.