ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
particle_coupling.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010-2022 The ESPResSo project
3 *
4 * This file is part of ESPResSo.
5 *
6 * ESPResSo is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * ESPResSo is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#pragma once
21
22#include <config/config.hpp>
23
24#include "BoxGeometry.hpp"
25#include "LocalBox.hpp"
26#include "Particle.hpp"
27#include "PropagationMode.hpp"
29#include "lb/Solver.hpp"
30#include "thermostat.hpp"
31
32#include <utils/Vector.hpp>
33#include <utils/math/sqr.hpp>
34
35#include <cmath>
36#include <unordered_set>
37#include <vector>
38
39/**
40 * @brief Check if a position is within the local LB domain plus halo.
41 *
42 * @return True iff the point is inside of the domain.
43 */
44bool in_local_halo(LocalBox const &local_box, Utils::Vector3d const &pos,
45 double agrid);
46
47// internal function exposed for unit testing
48std::vector<Utils::Vector3d> positions_in_halo(Utils::Vector3d const &pos,
49 BoxGeometry const &box_geo,
50 LocalBox const &local_box,
51 double agrid);
52
53/** @brief Calculate drag force on a single particle.
54 *
55 * See section II.C. and eq. 9 in @cite ahlrichs99a.
56 *
57 * @param[in] lb The coupled fluid
58 * @param[in] lb_gamma The friction coefficient
59 * @param[in] p The coupled particle
60 * @param[in] shifted_pos The particle position in MD units with optional shift
61 *
62 * @return The viscous coupling force
63 */
64Utils::Vector3d lb_drag_force(LB::Solver const &lb, double lb_gamma,
65 Particle const &p,
66 Utils::Vector3d const &shifted_pos);
67
68namespace LB {
69
71 LBThermostat const &m_thermostat;
72 LB::Solver &m_lb;
73 BoxGeometry const &m_box_geo;
74 LocalBox const &m_local_box;
75 double m_noise_pref_wo_gamma;
76 bool m_thermalized;
77
78public:
80 BoxGeometry const &box_geo, LocalBox const &local_box)
81 : m_thermostat{thermostat}, m_lb{lb}, m_box_geo{box_geo},
82 m_local_box{local_box} {
83 /* Eq. (16) @cite ahlrichs99a, without the gamma term.
84 * The factor 12 comes from the fact that we use random numbers
85 * from -0.5 to 0.5 (equally distributed) which have variance 1/12.
86 * The time step comes from the discretization.
87 */
88 auto constexpr variance_inv = 12.;
89 auto const kT = lb.get_kT() * Utils::sqr(lb.get_lattice_speed());
90 m_thermalized = (kT != 0.);
91 m_noise_pref_wo_gamma = std::sqrt(variance_inv * 2. * kT / lb.get_tau());
92 }
93
95 void kernel(std::vector<Particle *> const &particles);
96};
97
98/**
99 * @brief Keep track of ghost particles that have already been coupled once.
100 * In certain cases, there may be more than one ghost for the same particle.
101 * To make sure these are only coupled once, ghosts' ids are recorded.
102 */
104 std::unordered_set<int> m_coupled_ghosts;
105 CellStructure const &m_cell_structure;
106
107 /** @brief Check if there is locally a real particle for the given ghost. */
108 bool is_ghost_for_local_particle(Particle const &p) const {
109 return not m_cell_structure.get_local_particle(p.id())->is_ghost();
110 }
111
112public:
113 explicit CouplingBookkeeping(CellStructure const &cell_structure)
114 : m_cell_structure{cell_structure} {}
115
116 /** @brief Determine if a given particle should be coupled. */
118 auto const propagation = p.propagation();
119 if ((propagation & PropagationMode::TRANS_LB_MOMENTUM_EXCHANGE) == 0 and
120 (propagation & PropagationMode::SYSTEM_DEFAULT) == 0 and
121 (propagation & PropagationMode::TRANS_LB_TRACER) == 0) {
122 return false;
123 }
124#ifdef ESPRESSO_VIRTUAL_SITES_RELATIVE
125 if ((propagation & PropagationMode::TRANS_LB_MOMENTUM_EXCHANGE) == 0 and
129 return false;
130 }
131#endif
132 // real particles: always couple
133 if (not p.is_ghost()) {
134 return true;
135 }
136 // ghosts: check we don't have the corresponding real particle on the same
137 // node, and that a ghost for the same particle hasn't been coupled already
138 if (m_coupled_ghosts.contains(p.id()) or is_ghost_for_local_particle(p)) {
139 return false;
140 }
141 m_coupled_ghosts.insert(p.id());
142 return true;
143 }
144};
145
146inline bool is_tracer(Particle const &p) {
148}
149
150} // namespace LB
Vector implementation and trait types for boost qvm interoperability.
Describes a cell structure / cell system.
Particle * get_local_particle(int id)
Get a local particle by id.
Keep track of ghost particles that have already been coupled once.
CouplingBookkeeping(CellStructure const &cell_structure)
bool should_be_coupled(Particle const &p)
Determine if a given particle should be coupled.
void kernel(std::vector< Particle * > const &particles)
ParticleCoupling(LBThermostat const &thermostat, LB::Solver &lb, BoxGeometry const &box_geo, LocalBox const &local_box)
Utils::Vector3d get_noise_term(Particle const &p) const
bool is_tracer(Particle const &p)
DEVICE_QUALIFIER constexpr T sqr(T x)
Calculates the SQuaRe of x.
Definition sqr.hpp:28
Utils::Vector3d lb_drag_force(LB::Solver const &lb, double lb_gamma, Particle const &p, Utils::Vector3d const &shifted_pos)
Calculate drag force on a single particle.
bool in_local_halo(LocalBox const &local_box, Utils::Vector3d const &pos, double agrid)
Check if a position is within the local LB domain plus halo.
std::vector< Utils::Vector3d > positions_in_halo(Utils::Vector3d const &pos, BoxGeometry const &box_geo, LocalBox const &local_box, double agrid)
Return a vector of positions shifted by +,- box length in each coordinate.
Thermostat for lattice-Boltzmann particle coupling.
double get_tau() const
Get the LB time step.
auto get_lattice_speed() const
Get the lattice speed (agrid/tau).
double get_kT() const
Get the thermal energy parameter of the LB fluid.
Struct holding all information for one particle.
Definition Particle.hpp:450
auto const & propagation() const
Definition Particle.hpp:476
bool is_ghost() const
Definition Particle.hpp:495
auto const & id() const
Definition Particle.hpp:469