ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
relative.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010-2025 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#include <config/config.hpp>
21
22#ifdef ESPRESSO_VIRTUAL_SITES_RELATIVE
23
24#include "BoxGeometry.hpp"
25#include "Particle.hpp"
26#include "PropagationMode.hpp"
28#include "cells.hpp"
29#include "errorhandling.hpp"
31#include "rotation.hpp"
32
33#include <utils/Vector.hpp>
36#include <utils/quaternion.hpp>
37
38#include <cassert>
39
40/**
41 * @brief Vector pointing from the real particle to the virtual site.
42 *
43 * @return Relative distance.
44 */
45static auto connection_vector(Particle const &p_ref, Particle const &p_vs) {
46 // Calculate the quaternion defining the orientation of the vector connecting
47 // the virtual site and the real particle
48 // This is obtained, by multiplying the quaternion representing the director
49 // of the real particle with the quaternion of the virtual particle, which
50 // specifies the relative orientation.
51 auto const director = Utils::convert_quaternion_to_director(
52 p_ref.quat() * p_vs.vs_relative().rel_orientation)
53 .normalize();
54
55 return p_vs.vs_relative().distance * director;
56}
57
58/**
59 * @brief Velocity of the virtual site
60 * @param p_ref Reference particle for the virtual site.
61 * @param p_vs Virtual site.
62 * @return Velocity of the virtual site.
63 */
64static Utils::Vector3d velocity(Particle const &p_ref, Particle const &p_vs) {
65 auto const d = connection_vector(p_ref, p_vs);
66
67 // Get omega of real particle in space-fixed frame
68 auto const omega_space_frame =
69 convert_vector_body_to_space(p_ref, p_ref.omega());
70 // Obtain velocity from v = v_real particle + omega_real_particle * director
71 return vector_product(omega_space_frame, d) + p_ref.v();
72}
73
75 Particle const &p) {
76 auto const &vs_rel = p.vs_relative();
77 if (vs_rel.to_particle_id == -1) {
78 runtimeErrorMsg() << "Particle with id " << p.id()
79 << " is a dangling virtual site";
80 return nullptr;
81 }
82 auto p_ref_ptr = cell_structure.get_local_particle(vs_rel.to_particle_id);
83 if (!p_ref_ptr) {
84 runtimeErrorMsg() << "No real particle with id " << vs_rel.to_particle_id
85 << " for virtual site with id " << p.id();
86 }
87 return p_ref_ptr;
88}
89
90/**
91 * @brief Constraint force to hold the particle at its prescribed position.
92 *
93 * @param p_ref Reference particle.
94 * @param p_vs Virtual site.
95 * @return Constraint force.
96 */
97static auto constraint_stress(Particle const &p_ref, Particle const &p_vs) {
98 /* The constraint force is minus the force on the particle, make it force
99 * free. The counter force is translated by the connection vector to the
100 * real particle, hence the virial stress is */
101 return tensor_product(-p_vs.force(), connection_vector(p_ref, p_vs));
102}
103
107static bool is_vs_relative_rot(Particle const &p) {
109}
113static bool is_vs_rot(Particle const &p) {
115}
116static bool is_vs(Particle const &p) {
117 return (is_vs_relative_trans(p) or is_vs_rot(p));
118}
119
121 BoxGeometry const &box_geo) {
124
125 cell_structure.for_each_local_particle([&](Particle &p) {
126 if (!is_vs(p)) {
127 return;
128 }
129
130 auto const *p_ref_ptr = get_reference_particle(cell_structure, p);
131 if (!p_ref_ptr)
132 return;
133
134 auto const &p_ref = *p_ref_ptr;
135
136 // position update
137 if (is_vs_relative_trans(p)) {
138 p.image_box() = p_ref.image_box();
139 p.pos() = p_ref.pos() + connection_vector(p_ref, p);
140 p.v() = velocity(p_ref, p);
141
142 if (box_geo.type() == BoxType::LEES_EDWARDS) {
143 auto push = LeesEdwards::Push(box_geo);
144 push(p, 1); // includes a position fold
145 } else {
146 box_geo.fold_position(p.pos(), p.image_box());
147 }
148 }
149
150 // Orientation update
151 if (is_vs_relative_rot(p)) {
152 p.quat() = p_ref.quat() * p.vs_relative().quat;
153 }
154 });
155
156 if (cell_structure.check_resort_required()) {
158 }
159}
160
161// Distribute forces that have accumulated on virtual particles to the
162// associated real particles
164 CellStructure &cell_structure) {
165 cell_structure.ghosts_reduce_forces();
166 cell_structure.ghosts_reset_forces();
167
168 // Iterate over all the particles in the local cells
169 cell_structure.for_each_local_particle(
170 [&](Particle &p) {
171 if (!is_vs(p))
172 return;
173
174 auto *p_ref_ptr = get_reference_particle(cell_structure, p);
175 assert(p_ref_ptr != nullptr);
176
177 auto &p_ref = *p_ref_ptr;
178 if (is_vs_relative_trans(p)) {
179 p_ref.force() += p.force();
180 p_ref.torque() +=
181 vector_product(connection_vector(p_ref, p), p.force());
182 }
183
184 if (is_vs_rot(p)) {
185 p_ref.torque() += p.torque();
186 }
187 },
188 /* parallel */ false);
189}
190
191// Rigid body contribution to scalar pressure and pressure tensor
195
196 for (auto const &p : cell_structure.local_particles()) {
197 if (is_vs_relative_trans(p)) {
198 if (auto const *p_ref_ptr = cell_structure.get_local_particle(
199 p.vs_relative().to_particle_id)) {
200 pressure_tensor += constraint_stress(*p_ref_ptr, p);
201 }
202 }
203 }
204
205 return pressure_tensor;
206}
207#endif // ESPRESSO_VIRTUAL_SITES_RELATIVE
@ LEES_EDWARDS
Vector implementation and trait types for boost qvm interoperability.
This file contains everything related to the global cell structure / cell system.
BoxType type() const
void fold_position(Utils::Vector3d &pos, Utils::Vector3i &image_box) const
Fold coordinates to primary simulation box in-place.
Describes a cell structure / cell system.
Particle * get_local_particle(int id)
Get a local particle by id.
void ghosts_update(unsigned data_parts)
Update ghost particles.
void ghosts_reset_forces()
Set forces and torques on all ghosts to zero.
void ghosts_reduce_forces()
Add forces and torques from ghost particles to real particles.
void for_each_local_particle(ParticleUnaryOp &&f, bool parallel=true) const
Run a kernel on all local particles.
bool check_resort_required(Utils::Vector3d const &additional_offset={}) const
Check whether a particle has moved further than half the skin since the last Verlet list update,...
void set_resort_particles(Cells::Resort level)
Increase the local resort level at least to level.
ParticleRange local_particles() const
__device__ void vector_product(float const *a, float const *b, float *out)
This file contains the errorhandling code for severe errors, like a broken bond or illegal parameter ...
#define runtimeErrorMsg()
Quaternion algebra.
@ DATA_PART_MOMENTUM
Particle::m.
@ DATA_PART_POSITION
Particle::r.
Vector< T, 3 > convert_quaternion_to_director(Quaternion< T > const &quat)
Convert quaternion to director.
Quaternion implementation and trait types for boost qvm interoperability.
static bool is_vs_independent_rot(Particle const &p)
Definition relative.cpp:110
Utils::Matrix< double, 3, 3 > vs_relative_pressure_tensor(CellStructure const &cell_structure)
Definition relative.cpp:193
static bool is_vs_relative_rot(Particle const &p)
Definition relative.cpp:107
void vs_relative_back_transfer_forces_and_torques(CellStructure &cell_structure)
Definition relative.cpp:163
static bool is_vs(Particle const &p)
Definition relative.cpp:116
static auto connection_vector(Particle const &p_ref, Particle const &p_vs)
Vector pointing from the real particle to the virtual site.
Definition relative.cpp:45
void vs_relative_update_particles(CellStructure &cell_structure, BoxGeometry const &box_geo)
Definition relative.cpp:120
static Utils::Vector3d velocity(Particle const &p_ref, Particle const &p_vs)
Velocity of the virtual site.
Definition relative.cpp:64
static bool is_vs_relative_trans(Particle const &p)
Definition relative.cpp:104
Particle * get_reference_particle(CellStructure &cell_structure, Particle const &p)
Get real particle tracked by a virtual site.
Definition relative.cpp:74
static auto constraint_stress(Particle const &p_ref, Particle const &p_vs)
Constraint force to hold the particle at its prescribed position.
Definition relative.cpp:97
static bool is_vs_rot(Particle const &p)
Definition relative.cpp:113
This file contains all subroutines required to process rotational motion.
Utils::Vector3d convert_vector_body_to_space(const Particle &p, const Utils::Vector3d &vec)
Definition rotation.hpp:58
Struct holding all information for one particle.
Definition Particle.hpp:450
auto const & propagation() const
Definition Particle.hpp:476
auto const & quat() const
Definition Particle.hpp:532
auto const & vs_relative() const
Definition Particle.hpp:614
auto const & v() const
Definition Particle.hpp:488
auto const & torque() const
Definition Particle.hpp:534
auto const & omega() const
Definition Particle.hpp:536
auto const & image_box() const
Definition Particle.hpp:499
auto const & pos() const
Definition Particle.hpp:486
auto const & force() const
Definition Particle.hpp:490
auto const & id() const
Definition Particle.hpp:469
Matrix representation with static size.
Definition matrix.hpp:65