ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
oif_global_forces.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2012-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#include "oif_global_forces.hpp"
21
22#include "BoxGeometry.hpp"
23#include "Particle.hpp"
25
27
28#include <utils/Span.hpp>
29#include <utils/Vector.hpp>
30#include <utils/constants.hpp>
32
34
35Utils::Vector2d calc_oif_global(int molType, BoxGeometry const &box_geo,
36 CellStructure &cs) {
37 // first-fold-then-the-same approach
38 double partArea = 0.0;
39 // z volume
40 double VOL_partVol = 0.;
41
42 cs.bond_loop([&partArea, &VOL_partVol, &box_geo,
43 molType](Particle &p1, int bond_id,
44 Utils::Span<Particle *> partners) {
45 if (p1.mol_id() != molType)
46 return false;
47
48 if (boost::get<OifGlobalForcesBond>(bonded_ia_params.at(bond_id).get()) !=
49 nullptr) {
50 // remaining neighbors fetched
51 auto const p11 = box_geo.unfolded_position(p1.pos(), p1.image_box());
52 auto const p22 = p11 + box_geo.get_mi_vector(partners[0]->pos(), p11);
53 auto const p33 = p11 + box_geo.get_mi_vector(partners[1]->pos(), p11);
54
55 // unfolded positions correct
56 auto const VOL_A = Utils::area_triangle(p11, p22, p33);
57 partArea += VOL_A;
58
59 auto const VOL_norm = Utils::get_n_triangle(p11, p22, p33);
60 auto const VOL_dn = VOL_norm.norm();
61 auto const VOL_hz = 1.0 / 3.0 * (p11[2] + p22[2] + p33[2]);
62 VOL_partVol -= VOL_A * VOL_norm[2] / VOL_dn * VOL_hz;
63 }
64
65 return false;
66 });
67
68 return {{partArea, VOL_partVol}};
69}
70
71void add_oif_global_forces(Utils::Vector2d const &area_volume, int molType,
72 BoxGeometry const &box_geo, CellStructure &cs) {
73 // first-fold-then-the-same approach
74 double area = area_volume[0];
75 double VOL_volume = area_volume[1];
76
77 cs.bond_loop([&box_geo, area, VOL_volume,
78 molType](Particle &p1, int bond_id,
79 Utils::Span<Particle *> partners) {
80 if (p1.mol_id() != molType)
81 return false;
82
83 if (auto const *iaparams = boost::get<OifGlobalForcesBond>(
84 bonded_ia_params.at(bond_id).get())) {
85 auto const p11 = box_geo.unfolded_position(p1.pos(), p1.image_box());
86 auto const p22 = p11 + box_geo.get_mi_vector(partners[0]->pos(), p11);
87 auto const p33 = p11 + box_geo.get_mi_vector(partners[1]->pos(), p11);
88
89 // unfolded positions correct
90 // starting code from volume force
91 auto const VOL_norm = Utils::get_n_triangle(p11, p22, p33).normalize();
92 auto const VOL_A = Utils::area_triangle(p11, p22, p33);
93 auto const VOL_vv = (VOL_volume - iaparams->V0) / iaparams->V0;
94
95 auto const VOL_force =
96 (1.0 / 3.0) * iaparams->kv * VOL_vv * VOL_A * VOL_norm;
97
98 auto const h = (1. / 3.) * (p11 + p22 + p33);
99
100 auto const deltaA = (area - iaparams->A0_g) / iaparams->A0_g;
101
102 auto const m1 = h - p11;
103 auto const m2 = h - p22;
104 auto const m3 = h - p33;
105
106 auto const m1_length = m1.norm();
107 auto const m2_length = m2.norm();
108 auto const m3_length = m3.norm();
109
110 auto const fac = iaparams->ka_g * VOL_A * deltaA /
111 (m1_length * m1_length + m2_length * m2_length +
112 m3_length * m3_length);
113
114 p1.force() += fac * m1 + VOL_force;
115 partners[0]->force() += fac * m2 + VOL_force;
116 partners[1]->force() += fac * m3 + VOL_force;
117 }
118
119 return false;
120 });
121}
Vector implementation and trait types for boost qvm interoperability.
__shared__ int pos[MAXDEPTH *THREADS5/WARPSIZE]
float h[3]
BondedInteractionsMap bonded_ia_params
Field containing the parameters of the bonded ia types.
Data structures for bonded interactions.
mapped_type at(key_type const &key) const
auto unfolded_position(Utils::Vector3d const &pos, Utils::Vector3i const &image_box) const
Unfold particle coordinates to image box.
Utils::Vector< T, 3 > get_mi_vector(const Utils::Vector< T, 3 > &a, const Utils::Vector< T, 3 > &b) const
Get the minimum-image vector between two coordinates.
A stripped-down version of std::span from C++17.
Definition Span.hpp:38
Vector & normalize()
Definition Vector.hpp:140
double area_triangle(const Vector3d &P1, const Vector3d &P2, const Vector3d &P3)
Computes the area of triangle between vectors P1,P2,P3, by computing the cross product P1P2 x P1P3 an...
Vector3d get_n_triangle(const Vector3d &P1, const Vector3d &P2, const Vector3d &P3)
Computes the normal vector of a triangle.
void add_oif_global_forces(Utils::Vector2d const &area_volume, int molType, BoxGeometry const &box_geo, CellStructure &cs)
Distribute the OIF global forces to all particles in the mesh.
int max_oif_objects
Utils::Vector2d calc_oif_global(int molType, BoxGeometry const &box_geo, CellStructure &cs)
Calculate the OIF global force.
Routines to calculate the OIF global forces energy or/and and force for a particle triple (triangle f...
Describes a cell structure / cell system.
void bond_loop(BondKernel const &bond_kernel)
Bonded pair loop.
Struct holding all information for one particle.
Definition Particle.hpp:393
auto const & image_box() const
Definition Particle.hpp:442
auto const & mol_id() const
Definition Particle.hpp:414
auto const & pos() const
Definition Particle.hpp:429
auto const & force() const
Definition Particle.hpp:433