ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
oif_local_forces.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2012-2026 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/** \file
23 * Routines to calculate the OIF local forces for a particle quadruple
24 * (two neighboring triangles with common edge).
25 * See @cite dupin07a.
26 */
27
28#include "config/config.hpp"
29
30#include "BoxGeometry.hpp"
31#include "Particle.hpp"
32
33#include <utils/Vector.hpp>
35
36#include <cmath>
37#include <tuple>
38
39/** Tiny OIF elasticity cutoff. */
40inline constexpr auto tiny_oif_elasticity_coefficient{1e-10};
41
42/** Parameters for OIF local forces
43 *
44 * Characterize the deformation of two triangles sharing an edge.
45 */
47 /** Equilibrium bond length of triangle edges */
48 double r0;
49 /** Non-linear stretching coefficient of triangle edges */
50 double ks;
51 /** Linear stretching coefficient of triangle edges */
52 double kslin;
53 /** Equilibrium angle between the two triangles */
54 double phi0;
55 /** Bending coefficient for the angle between the two triangles */
56 double kb;
57 /** Equilibrium surface of the first triangle */
58 double A01;
59 /** Equilibrium surface of the second triangle */
60 double A02;
61 /** Stretching coefficient of a triangle surface */
62 double kal;
63 /** Viscous damping coefficient of triangle edges */
64 double kvisc;
65
66 double cutoff() const { return 0.; }
67
68 static constexpr int num = 3;
69
70 OifLocalForcesBond(double r0, double ks, double kslin, double phi0, double kb,
71 double A01, double A02, double kal, double kvisc) {
72 this->phi0 = phi0;
73 this->kb = kb;
74 this->r0 = r0;
75 this->ks = ks;
76 this->kslin = kslin;
77 this->A01 = A01;
78 this->A02 = A02;
79 this->kal = kal;
80 this->kvisc = kvisc;
81 }
82
83 std::tuple<Utils::Vector3d, Utils::Vector3d, Utils::Vector3d, Utils::Vector3d>
84 calc_forces(Utils::Vector3d const &fp2, Utils::Vector3d const &fp1,
85 Utils::Vector3d const &fp3, Utils::Vector3d const &fp4,
86 Utils::Vector3d const &vel2, Utils::Vector3d const &vel3) const;
87};
88
89/** Compute the OIF local forces.
90 * See @cite dupin07a, @cite jancigova16a.
91 * @param fp1 Unfolded position of particle of triangle 1.
92 * @param fp2 , fp3 Unfolded position of particles common to triangle 1 and
93 * triangle 2.
94 * @param fp4 Unfolded position of particle of triangle 2.
95 * @param vel2 The velocity of particle of triangle 1.
96 * @param vel3 The velocity of particle of triangle 2.
97 * @return forces on @p p1, @p p2, @p p3, @p p4
98 */
102 Utils::Vector3d const &fp1,
103 Utils::Vector3d const &fp3,
104 Utils::Vector3d const &fp4,
105 Utils::Vector3d const &vel2,
106 Utils::Vector3d const &vel3) const {
107 Utils::Vector3d force1{}, force2{}, force3{}, force4{};
108
109 // surface strain constraint
112 auto const dx = fp2 - fp3;
113 auto const len = dx.norm();
114 auto const dr = len - r0;
115 auto fac = 0.;
116 // linear stretching
118 fac -= kslin * dr; // no normalization
119 }
120 // non-linear stretching
122 /** For non-linear stretching, see eq. (19) in @cite dupin07a */
123 auto const lambda = len / r0;
124 auto const spring = (std::pow(lambda, 0.5) + std::pow(lambda, -2.5)) /
125 (lambda + std::pow(lambda, -3.));
126 fac -= ks * spring * dr; // no normalization
127 }
128 auto const f = (fac / len) * dx;
129 force2 += f;
130 force3 -= f;
131 }
132
133 // viscous force
135 auto const dx = fp2 - fp3;
136 auto const len_sq = dx.norm2();
137 auto const v_ij = vel3 - vel2;
138 auto const fac = kvisc * (dx * v_ij) / len_sq;
139 auto const f = fac * dx;
140 force2 += f;
141 force3 -= f;
142 }
143
144 /* bending
145 forceT1 is restoring force for triangle p1,p2,p3 and forceT2 restoring
146 force for triangle p2,p3,p4 p1 += forceT1; p2 -= 0.5*forceT1+0.5*forceT2;
147 p3 -= 0.5*forceT1+0.5*forceT2; p4 += forceT2; */
149 auto const phi = Utils::angle_btw_triangles(fp1, fp2, fp3, fp4);
150 auto const aa = (phi - phi0); // no renormalization by phi0, to be
151 // consistent with Krueger and Fedosov
152 auto const fac = kb * aa;
153
154 // calculates (fp2 - fp1)x(fp3 - fp1), thus Nc = (A - C)x(B - C)
155 auto const Nc = Utils::get_n_triangle(fp1, fp2, fp3);
156 // calculates (fp3 - fp4)x(fp2 - fp4), thus Nd = (B - D)x(A - D)
157 auto const Nd = Utils::get_n_triangle(fp4, fp3, fp2);
158
159 auto const BminA = fp3 - fp2;
160
161 auto const factorFaNc =
162 (fp2 - fp3) * (fp1 - fp3) / BminA.norm() / Nc.norm2();
163 auto const factorFaNd =
164 (fp2 - fp3) * (fp4 - fp3) / BminA.norm() / Nd.norm2();
165 auto const factorFbNc =
166 (fp2 - fp3) * (fp2 - fp1) / BminA.norm() / Nc.norm2();
167 auto const factorFbNd =
168 (fp2 - fp3) * (fp2 - fp4) / BminA.norm() / Nd.norm2();
169
170 force1 -= fac * BminA.norm() / Nc.norm2() * Nc; // Fc
171 force2 += fac * (factorFaNc * Nc + factorFaNd * Nd); // Fa
172 force3 += fac * (factorFbNc * Nc + factorFbNd * Nd); // Fb
173 force4 -= fac * BminA.norm() / Nd.norm2() * Nd; // Fc
174 }
175
176 /* local area
177 * for both triangles, only 1/3 of calculated forces are added, because each
178 * triangle will enter this calculation 3 times (one time per edge).
179 * Proportional distribution of forces, implemented according to
180 * @cite jancigova16a.
181 */
183 auto handle_triangle =
184 [this](double A0, Utils::Vector3d const &c1, Utils::Vector3d const &c2,
185 Utils::Vector3d const &c3, Utils::Vector3d &f1,
187 // calculate triangle barycenter and surface
188 auto const h = (1. / 3.) * (c1 + c2 + c3);
189 auto const A = Utils::area_triangle(c1, c2, c3);
190 auto const t = sqrt(A / A0) - 1.0;
191
192 auto const m1 = h - c1;
193 auto const m2 = h - c2;
194 auto const m3 = h - c3;
195
196 auto const fac = kal * A0 * (2 * t + t * t) /
197 (m1.norm2() + m2.norm2() + m3.norm2());
198
199 // local area force for triangle
200 f1 += (fac / 3.0) * m1;
201 f2 += (fac / 3.0) * m2;
202 f3 += (fac / 3.0) * m3;
203 };
204
205 handle_triangle(A01, fp1, fp2, fp3, force1, force2, force3);
206 handle_triangle(A02, fp2, fp3, fp4, force2, force3, force4);
207 }
208 return std::make_tuple(force2, force1, force3, force4);
209}
Vector implementation and trait types for boost qvm interoperability.
T norm() const
Definition Vector.hpp:159
constexpr T norm2() const
Definition Vector.hpp:158
VectorXd< 3 > Vector3d
Definition Vector.hpp:184
double angle_btw_triangles(const Vector3d &P1, const Vector3d &P2, const Vector3d &P3, const Vector3d &P4)
Computes the angle between two triangles in 3D space.
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.
constexpr auto tiny_oif_elasticity_coefficient
Tiny OIF elasticity cutoff.
Parameters for OIF local forces.
double A02
Equilibrium surface of the second triangle.
OifLocalForcesBond(double r0, double ks, double kslin, double phi0, double kb, double A01, double A02, double kal, double kvisc)
double phi0
Equilibrium angle between the two triangles.
double r0
Equilibrium bond length of triangle edges.
double kslin
Linear stretching coefficient of triangle edges.
std::tuple< Utils::Vector3d, Utils::Vector3d, Utils::Vector3d, Utils::Vector3d > calc_forces(Utils::Vector3d const &fp2, Utils::Vector3d const &fp1, Utils::Vector3d const &fp3, Utils::Vector3d const &fp4, Utils::Vector3d const &vel2, Utils::Vector3d const &vel3) const
Compute the OIF local forces.
double kb
Bending coefficient for the angle between the two triangles.
static constexpr int num
double A01
Equilibrium surface of the first triangle.
double kvisc
Viscous damping coefficient of triangle edges.
double ks
Non-linear stretching coefficient of triangle edges.
double kal
Stretching coefficient of a triangle surface.