Collective Variables Module - Developer Documentation
Loading...
Searching...
No Matches
colvarcomp_coordnums.h
1// -*- c++ -*-
2
3// This file is part of the Collective Variables module (Colvars).
4// The original version of Colvars and its updates are located at:
5// https://github.com/Colvars/colvars
6// Please update all Colvars source files before making any changes.
7// If you wish to distribute your changes, please submit them to the
8// Colvars repository at GitHub.
9//
10
11#ifndef COLVARCOMP_COORDNUM_H
12#define COLVARCOMP_COORDNUM_H
13
14#include <memory>
15
16#include "colvar.h"
17#include "colvarcomp.h"
18#include "colvarmodule.h"
19
20
24public:
25
26 coordnum();
27 virtual ~coordnum();
28 virtual int init(std::string const &conf);
29 virtual void calc_value();
30 virtual void calc_gradients();
31
32 enum {
33 ef_null = 0,
34 ef_gradients = 1,
35 ef_use_internal_pbc = (1 << 8),
36 ef_use_pairlist = (1 << 9),
37 ef_rebuild_pairlist = (1 << 10)
38 };
39
46 template <int flags>
47 static cvm::real switching_function(cvm::real const &l2, cvm::real &dFdl2, int en, int ed,
48 cvm::real pairlist_tol);
49
51 template <int flags>
53 cvm::rvector const &inv_r0sq_vec, int en, int ed,
54 const cvm::real a1x, const cvm::real a1y, const cvm::real a1z,
55 const cvm::real a2x, const cvm::real a2y, const cvm::real a2z,
56 cvm::real &g1x, cvm::real &g1y, cvm::real &g1z,
57 cvm::real &g2x, cvm::real &g2y, cvm::real &g2z,
58 cvm::real pairlist_tol, cvm::real pairlist_tol_l2_max,
59 colvarmodule *cvmodule);
60
62 template <bool use_group1_com, bool use_group2_com, int flags> int compute_coordnum();
63
65 template <bool use_group1_com, bool use_group2_com, int flags> void main_loop();
66
67protected:
72
75
78
81
83 void update_cutoffs(cvm::rvector const &r0_vec_i);
84
86 int en = 6;
88 int ed = 12;
89
91 size_t num_pairs = 0;
92
95
98
100 bool b_use_internal_pbc = false;
101
104
107
110
112 int pairlist_freq = 100;
113
115 std::unique_ptr<bool []> pairlist;
116
117};
118
119
123public:
124
125 selfcoordnum();
126 virtual void calc_value();
127 virtual void calc_gradients();
128
130 template <int flags> void selfcoordnum_sequential_loop();
131
133 template <int flags> int compute_selfcoordnum();
134};
135
136
140public:
142 virtual ~groupcoordnum() {}
143 virtual void calc_value();
144 virtual void calc_gradients();
145};
146
147
152public:
155 cvm::real r0, int en, int ed);
156 h_bond();
157 virtual ~h_bond() {}
158 virtual int init(std::string const &conf);
159 virtual void calc_value();
160 virtual void calc_gradients();
161
162protected:
166 int en = 6;
168 int ed = 8;
169};
170
171
172template <int flags>
174 int en, int ed,
175 cvm::real pairlist_tol)
176{
177 // Assume en and ed are even integers, and avoid sqrt in the following
178 int const en2 = en/2;
179 int const ed2 = ed/2;
180
181 cvm::real const xn = cvm::integer_power(l2, en2);
182 cvm::real const xd = cvm::integer_power(l2, ed2);
183 cvm::real const eps_l2 = 1.0e-7;
184 cvm::real const h = l2 - 1.0;
185 cvm::real const en2_r = (cvm::real) en2;
186 cvm::real const ed2_r = (cvm::real) ed2;
187 cvm::real func_no_pairlist;
188
189 if (std::abs(h) < eps_l2) {
190 // Order-2 Taylor expansion: c0 + c1*h + c2*h^2
191 cvm::real const c0 = en2_r / ed2_r;
192 cvm::real const c1 = (en2_r * (en2_r - ed2_r)) / (2.0 * ed2_r);
193 cvm::real const c2 = (en2_r * (en2_r - ed2_r) * (2.0 * en2_r - ed2_r - 3.0)) / (12.0 * ed2_r);
194 func_no_pairlist = c0 + h * (c1 + h * c2);
195 } else {
196 func_no_pairlist = (1.0 - xn) / (1.0 - xd);
197 }
198
199 cvm::real func, inv_one_pairlist_tol;
200 if (flags & ef_use_pairlist) {
201 inv_one_pairlist_tol = 1 / (1.0-pairlist_tol);
202 func = (func_no_pairlist - pairlist_tol) * inv_one_pairlist_tol;
203 } else {
204 func = func_no_pairlist;
205 }
206
207 // If the value is too small and we are correcting for the tolerance, the result is negative
208 // and we need to exclude it rather than let it contribute to the sum or the gradients.
209 if (func < 0)
210 return 0;
211
212 if (flags & ef_gradients) {
213 // Logarithmic derivative: 1st-order Taylor expansion around l2 = 1
214 cvm::real log_deriv;
215 if (std::abs(h) < eps_l2) {
216 cvm::real const g0 = 0.5 * (en2_r - ed2_r);
217 cvm::real const g1 = ((en2_r - ed2_r) * (en2_r + ed2_r - 6.0)) / 12.0;
218 log_deriv = g0 + h * g1;
219 } else {
220 log_deriv = (ed2_r * xd / ((1.0 - xd) * l2)) - (en2_r * xn / ((1.0 - xn) * l2));
221 }
222 dFdl2 = (flags & ef_use_pairlist) ?
223 func_no_pairlist * inv_one_pairlist_tol * log_deriv :
224 func * log_deriv;
225 }
226
227 return func;
228}
229
230
231template<int flags>
233 cvm::rvector const &inv_r0sq_vec,
234 int en,
235 int ed,
236 const cvm::real a1x,
237 const cvm::real a1y,
238 const cvm::real a1z,
239 const cvm::real a2x,
240 const cvm::real a2y,
241 const cvm::real a2z,
242 cvm::real& g1x,
243 cvm::real& g1y,
244 cvm::real& g1z,
245 cvm::real& g2x,
246 cvm::real& g2y,
247 cvm::real& g2z,
248 cvm::real pairlist_tol,
249 cvm::real pairlist_tol_l2_max,
250 colvarmodule *cvmodule_in)
251{
252 const cvm::atom_pos pos1{a1x, a1y, a1z};
253 const cvm::atom_pos pos2{a2x, a2y, a2z};
254 cvm::rvector const diff = (flags & ef_use_internal_pbc)
255 ? cvmodule_in->proxy->position_distance_internal(pos1, pos2)
256 : cvmodule_in->proxy->position_distance(pos1, pos2);
257
258 cvm::rvector const scal_diff(diff.x * inv_r0_vec.x,
259 diff.y * inv_r0_vec.y,
260 diff.z * inv_r0_vec.z);
261 cvm::real const l2 = scal_diff.norm2();
262 if (flags & ef_use_pairlist) {
263 if (l2 > pairlist_tol_l2_max) {
264 // Exit if the distance is such that F(l2) < pairlist_tol
265 return 0.0;
266 }
267 }
268
269 cvm::real dFdl2 = 0.0;
270 cvm::real F = switching_function<flags>(l2, dFdl2, en, ed, pairlist_tol);
271
272 if ((flags & ef_gradients) && (F > 0.0)) {
273 cvm::rvector const dl2dx((2.0 * inv_r0sq_vec.x) * diff.x,
274 (2.0 * inv_r0sq_vec.y) * diff.y,
275 (2.0 * inv_r0sq_vec.z) * diff.z);
276
277 const cvm::rvector G = dFdl2*dl2dx;
278 g1x += -1.0*G.x;
279 g1y += -1.0*G.y;
280 g1z += -1.0*G.z;
281 g2x += G.x;
282 g2y += G.y;
283 g2z += G.z;
284 }
285
286 return F;
287}
288
289#endif // COLVARCOMP_COORDNUM_H
Colvar component: coordination number between two groups (colvarvalue::type_scalar type,...
Definition: colvarcomp_coordnums.h:23
void update_cutoffs(cvm::rvector const &r0_vec_i)
Set r0_vec and related fields.
Definition: colvarcomp_coordnums.cpp:29
int en
Integer exponent of the function numerator.
Definition: colvarcomp_coordnums.h:86
std::unique_ptr< bool[]> pairlist
Pair list.
Definition: colvarcomp_coordnums.h:115
bool b_use_internal_pbc
Use the PBC functions from the Colvars library (as opposed to MD engine)
Definition: colvarcomp_coordnums.h:100
virtual void calc_value()
Calculate the variable.
Definition: colvarcomp_coordnums.cpp:288
cvm::rvector inv_r0_vec
Inverse of r0_vec.
Definition: colvarcomp_coordnums.h:77
cvm::atom_group * group2
Second atom group.
Definition: colvarcomp_coordnums.h:71
cvm::real tolerance
Tolerance for the pair list.
Definition: colvarcomp_coordnums.h:103
static cvm::real switching_function(cvm::real const &l2, cvm::real &dFdl2, int en, int ed, cvm::real pairlist_tol)
Definition: colvarcomp_coordnums.h:173
bool b_group2_center_only
If true, group2 will be treated as a single atom.
Definition: colvarcomp_coordnums.h:97
bool b_group1_center_only
If true, group1 will be treated as a single atom.
Definition: colvarcomp_coordnums.h:94
int ed
Integer exponent of the function denominator.
Definition: colvarcomp_coordnums.h:88
virtual void calc_gradients()
Calculate the atomic gradients, to be reused later in order to apply forces.
Definition: colvarcomp_coordnums.cpp:330
static cvm::real compute_pair_coordnum(cvm::rvector const &inv_r0_vec, cvm::rvector const &inv_r0sq_vec, int en, int ed, const cvm::real a1x, const cvm::real a1y, const cvm::real a1z, const cvm::real a2x, const cvm::real a2y, const cvm::real a2z, cvm::real &g1x, cvm::real &g1y, cvm::real &g1z, cvm::real &g2x, cvm::real &g2y, cvm::real &g2z, cvm::real pairlist_tol, cvm::real pairlist_tol_l2_max, colvarmodule *cvmodule)
Main kernel for the coordination number.
Definition: colvarcomp_coordnums.h:232
int pairlist_freq
Frequency of update of the pair list.
Definition: colvarcomp_coordnums.h:112
cvm::real tolerance_l2_max
Value of the squared scaled distance (l^2) that matches the given tolerance.
Definition: colvarcomp_coordnums.h:106
int compute_coordnum()
Workhorse function.
Definition: colvarcomp_coordnums.cpp:266
virtual int init(std::string const &conf)
Definition: colvarcomp_coordnums.cpp:47
size_t num_pairs
The number of pairwise distances being calculated.
Definition: colvarcomp_coordnums.h:91
cvm::atom_group * group1
First atom group.
Definition: colvarcomp_coordnums.h:69
cvm::rvector inv_r0sq_vec
Square of inv_r0_vec.
Definition: colvarcomp_coordnums.h:80
void main_loop()
Workhorse function.
Definition: colvarcomp_coordnums.cpp:195
void compute_tolerance_l2_max()
Recompute the value of tolerance_l2_max.
Definition: colvarcomp_coordnums.cpp:169
cvm::rvector r0_vec
Cutoff distances along each dimension.
Definition: colvarcomp_coordnums.h:74
Colvar component (base class for collective variables)
Definition: colvarcomp.h:72
Colvar component: coordination number between two groups (colvarvalue::type_scalar type,...
Definition: colvarcomp_coordnums.h:139
virtual void calc_value()
Calculate the variable.
Definition: colvarcomp_coordnums.cpp:588
virtual void calc_gradients()
Calculate the atomic gradients, to be reused later in order to apply forces.
Definition: colvarcomp_coordnums.cpp:601
Colvar component: hydrogen bond, defined as the product of a colvar::coordnum and 1/2*(1-cos((180-ang...
Definition: colvarcomp_coordnums.h:151
int ed
Integer exponent of the function denominator.
Definition: colvarcomp_coordnums.h:168
virtual void calc_value()
Calculate the variable.
Definition: colvarcomp_coordnums.cpp:414
int en
Integer exponent of the function numerator.
Definition: colvarcomp_coordnums.h:166
cvm::rvector r0_vec
Cutoff distances along each dimension.
Definition: colvarcomp_coordnums.h:164
virtual void calc_gradients()
Calculate the atomic gradients, to be reused later in order to apply forces.
Definition: colvarcomp_coordnums.cpp:455
virtual int init(std::string const &conf)
Definition: colvarcomp_coordnums.cpp:349
Colvar component: self-coordination number within a group (colvarvalue::type_scalar type,...
Definition: colvarcomp_coordnums.h:122
virtual void calc_gradients()
Calculate the atomic gradients, to be reused later in order to apply forces.
Definition: colvarcomp_coordnums.cpp:579
int compute_selfcoordnum()
Main workhorse function.
Definition: colvarcomp_coordnums.cpp:547
virtual void calc_value()
Calculate the variable.
Definition: colvarcomp_coordnums.cpp:568
void selfcoordnum_sequential_loop()
Workhorse function.
Definition: colvarcomp_coordnums.cpp:492
vector of real numbers with three components
Definition: colvartypes.h:728
Collective variables module (main class)
Definition: colvarmodule.h:72
double real
Defining an abstract real number allows to switch precision.
Definition: colvarmodule.h:99
static real integer_power(real const &x, int const n)
Override the STL pow() with a product for n integer.
Definition: colvarmodule.h:105
colvarproxy * proxy
Pointer to the proxy object, used to retrieve atomic data from the hosting program.
Definition: colvarmodule.h:957
cvm::rvector position_distance_internal(cvm::atom_pos const &pos1, cvm::atom_pos const &pos2) const
Inline version of position_distance()
Definition: colvarproxy_system.h:240
virtual cvm::rvector position_distance(cvm::atom_pos const &pos1, cvm::atom_pos const &pos2) const
Get the PBC-aware distance vector between two positions (using the MD engine's convention)
Definition: colvarproxy_system.cpp:130
Store the information of a group of atoms in a structure-of-arrays (SoA) style.
Definition: colvaratoms.h:52
Collective variables main module.
A simplified class of cvm::atom that can be used with cvm::atom_group::atom_modifier.
Definition: colvaratoms.h:107