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_pairlist = (1 << 9),
36 ef_rebuild_pairlist = (1 << 10)
37 };
38
45 template <int flags>
46 static cvm::real switching_function(cvm::real const &l2, cvm::real &dFdl2, int en, int ed,
47 cvm::real pairlist_tol);
48
50 template <int flags>
52 cvm::rvector const &inv_r0sq_vec, int en, int ed,
53 const cvm::real a1x, const cvm::real a1y, const cvm::real a1z,
54 const cvm::real a2x, const cvm::real a2y, const cvm::real a2z,
55 cvm::real &g1x, cvm::real &g1y, cvm::real &g1z,
56 cvm::real &g2x, cvm::real &g2y, cvm::real &g2z,
57 cvm::real pairlist_tol, cvm::real pairlist_tol_l2_max,
59
61 template <bool use_group1_com, bool use_group2_com, int flags> int compute_coordnum();
62
64 template <bool use_group1_com, bool use_group2_com, int flags> void main_loop();
65
66protected:
71
74
77
80
82 void update_cutoffs(cvm::rvector const &r0_vec_i);
83
85 int en = 6;
87 int ed = 12;
88
90 size_t num_pairs = 0;
91
94
97
100
103
106
108 int pairlist_freq = 100;
109
111 std::unique_ptr<bool []> pairlist;
112
113};
114
115
119public:
120
121 selfcoordnum();
122 virtual void calc_value();
123 virtual void calc_gradients();
124
126 template <int flags> void selfcoordnum_sequential_loop();
127
129 template <int flags> int compute_selfcoordnum();
130};
131
132
136public:
138 virtual ~groupcoordnum() {}
139 virtual void calc_value();
140 virtual void calc_gradients();
141};
142
143
148public:
151 cvm::real r0, int en, int ed);
152 h_bond();
153 virtual ~h_bond() {}
154 virtual int init(std::string const &conf);
155 virtual void calc_value();
156 virtual void calc_gradients();
157
158protected:
162 int en = 6;
164 int ed = 8;
165};
166
167
168template <int flags>
170 int en, int ed,
171 cvm::real pairlist_tol)
172{
173 // Assume en and ed are even integers, and avoid sqrt in the following
174 int const en2 = en/2;
175 int const ed2 = ed/2;
176
177 cvm::real const xn = cvm::integer_power(l2, en2);
178 cvm::real const xd = cvm::integer_power(l2, ed2);
179 cvm::real const eps_l2 = 1.0e-7;
180 cvm::real const h = l2 - 1.0;
181 cvm::real const en2_r = (cvm::real) en2;
182 cvm::real const ed2_r = (cvm::real) ed2;
183 cvm::real func_no_pairlist;
184
185 if (std::abs(h) < eps_l2) {
186 // Order-2 Taylor expansion: c0 + c1*h + c2*h^2
187 cvm::real const c0 = en2_r / ed2_r;
188 cvm::real const c1 = (en2_r * (en2_r - ed2_r)) / (2.0 * ed2_r);
189 cvm::real const c2 = (en2_r * (en2_r - ed2_r) * (2.0 * en2_r - ed2_r - 3.0)) / (12.0 * ed2_r);
190 func_no_pairlist = c0 + h * (c1 + h * c2);
191 } else {
192 func_no_pairlist = (1.0 - xn) / (1.0 - xd);
193 }
194
195 cvm::real func, inv_one_pairlist_tol;
196 if (flags & ef_use_pairlist) {
197 inv_one_pairlist_tol = 1 / (1.0-pairlist_tol);
198 func = (func_no_pairlist - pairlist_tol) * inv_one_pairlist_tol;
199 } else {
200 func = func_no_pairlist;
201 }
202
203 // If the value is too small and we are correcting for the tolerance, the result is negative
204 // and we need to exclude it rather than let it contribute to the sum or the gradients.
205 if (func < 0)
206 return 0;
207
208 if (flags & ef_gradients) {
209 // Logarithmic derivative: 1st-order Taylor expansion around l2 = 1
210 cvm::real log_deriv;
211 if (std::abs(h) < eps_l2) {
212 cvm::real const g0 = 0.5 * (en2_r - ed2_r);
213 cvm::real const g1 = ((en2_r - ed2_r) * (en2_r + ed2_r - 6.0)) / 12.0;
214 log_deriv = g0 + h * g1;
215 } else {
216 log_deriv = (ed2_r * xd / ((1.0 - xd) * l2)) - (en2_r * xn / ((1.0 - xn) * l2));
217 }
218 dFdl2 = (flags & ef_use_pairlist) ?
219 func_no_pairlist * inv_one_pairlist_tol * log_deriv :
220 func * log_deriv;
221 }
222
223 return func;
224}
225
226
227template<int flags>
229 cvm::rvector const &inv_r0sq_vec,
230 int en,
231 int ed,
232 const cvm::real a1x,
233 const cvm::real a1y,
234 const cvm::real a1z,
235 const cvm::real a2x,
236 const cvm::real a2y,
237 const cvm::real a2z,
238 cvm::real& g1x,
239 cvm::real& g1y,
240 cvm::real& g1z,
241 cvm::real& g2x,
242 cvm::real& g2y,
243 cvm::real& g2z,
244 cvm::real pairlist_tol,
245 cvm::real pairlist_tol_l2_max,
247{
248 const cvm::atom_pos pos1{a1x, a1y, a1z};
249 const cvm::atom_pos pos2{a2x, a2y, a2z};
250
251 cvm::rvector const diff = bc.position_distance(pos1, pos2);
252 cvm::rvector const scal_diff(diff.x * inv_r0_vec.x,
253 diff.y * inv_r0_vec.y,
254 diff.z * inv_r0_vec.z);
255 cvm::real const l2 = scal_diff.norm2();
256 if (flags & ef_use_pairlist) {
257 if (l2 > pairlist_tol_l2_max) {
258 // Exit if the distance is such that F(l2) < pairlist_tol
259 return 0.0;
260 }
261 }
262
263 cvm::real dFdl2 = 0.0;
264 cvm::real F = switching_function<flags>(l2, dFdl2, en, ed, pairlist_tol);
265
266 if ((flags & ef_gradients) && (F > 0.0)) {
267 cvm::rvector const dl2dx((2.0 * inv_r0sq_vec.x) * diff.x,
268 (2.0 * inv_r0sq_vec.y) * diff.y,
269 (2.0 * inv_r0sq_vec.z) * diff.z);
270
271 const cvm::rvector G = dFdl2*dl2dx;
272 g1x += -1.0*G.x;
273 g1y += -1.0*G.y;
274 g1z += -1.0*G.z;
275 g2x += G.x;
276 g2y += G.y;
277 g2z += G.z;
278 }
279
280 return F;
281}
282
283#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:28
int en
Integer exponent of the function numerator.
Definition: colvarcomp_coordnums.h:85
std::unique_ptr< bool[]> pairlist
Pair list.
Definition: colvarcomp_coordnums.h:111
virtual void calc_value()
Calculate the variable.
Definition: colvarcomp_coordnums.cpp:274
cvm::rvector inv_r0_vec
Inverse of r0_vec.
Definition: colvarcomp_coordnums.h:76
cvm::atom_group * group2
Second atom group.
Definition: colvarcomp_coordnums.h:70
cvm::real tolerance
Tolerance for the pair list.
Definition: colvarcomp_coordnums.h:99
static cvm::real switching_function(cvm::real const &l2, cvm::real &dFdl2, int en, int ed, cvm::real pairlist_tol)
Definition: colvarcomp_coordnums.h:169
bool b_group2_center_only
If true, group2 will be treated as a single atom.
Definition: colvarcomp_coordnums.h:96
bool b_group1_center_only
If true, group1 will be treated as a single atom.
Definition: colvarcomp_coordnums.h:93
int ed
Integer exponent of the function denominator.
Definition: colvarcomp_coordnums.h:87
virtual void calc_gradients()
Calculate the atomic gradients, to be reused later in order to apply forces.
Definition: colvarcomp_coordnums.cpp:316
int pairlist_freq
Frequency of update of the pair list.
Definition: colvarcomp_coordnums.h:108
cvm::real tolerance_l2_max
Value of the squared scaled distance (l^2) that matches the given tolerance.
Definition: colvarcomp_coordnums.h:102
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, cvm::system_boundary_conditions const &bc)
Main kernel for the coordination number.
Definition: colvarcomp_coordnums.h:228
int compute_coordnum()
Workhorse function.
Definition: colvarcomp_coordnums.cpp:252
virtual int init(std::string const &conf)
Definition: colvarcomp_coordnums.cpp:46
size_t num_pairs
The number of pairwise distances being calculated.
Definition: colvarcomp_coordnums.h:90
cvm::atom_group * group1
First atom group.
Definition: colvarcomp_coordnums.h:68
cvm::rvector inv_r0sq_vec
Square of inv_r0_vec.
Definition: colvarcomp_coordnums.h:79
void main_loop()
Workhorse function.
Definition: colvarcomp_coordnums.cpp:188
void compute_tolerance_l2_max()
Recompute the value of tolerance_l2_max.
Definition: colvarcomp_coordnums.cpp:162
cvm::rvector r0_vec
Cutoff distances along each dimension.
Definition: colvarcomp_coordnums.h:73
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:135
virtual void calc_value()
Calculate the variable.
Definition: colvarcomp_coordnums.cpp:567
virtual void calc_gradients()
Calculate the atomic gradients, to be reused later in order to apply forces.
Definition: colvarcomp_coordnums.cpp:580
Colvar component: hydrogen bond, defined as the product of a colvar::coordnum and 1/2*(1-cos((180-ang...
Definition: colvarcomp_coordnums.h:147
int ed
Integer exponent of the function denominator.
Definition: colvarcomp_coordnums.h:164
virtual void calc_value()
Calculate the variable.
Definition: colvarcomp_coordnums.cpp:400
int en
Integer exponent of the function numerator.
Definition: colvarcomp_coordnums.h:162
cvm::rvector r0_vec
Cutoff distances along each dimension.
Definition: colvarcomp_coordnums.h:160
virtual void calc_gradients()
Calculate the atomic gradients, to be reused later in order to apply forces.
Definition: colvarcomp_coordnums.cpp:441
virtual int init(std::string const &conf)
Definition: colvarcomp_coordnums.cpp:335
Colvar component: self-coordination number within a group (colvarvalue::type_scalar type,...
Definition: colvarcomp_coordnums.h:118
virtual void calc_gradients()
Calculate the atomic gradients, to be reused later in order to apply forces.
Definition: colvarcomp_coordnums.cpp:558
int compute_selfcoordnum()
Main workhorse function.
Definition: colvarcomp_coordnums.cpp:526
virtual void calc_value()
Calculate the variable.
Definition: colvarcomp_coordnums.cpp:547
void selfcoordnum_sequential_loop()
Workhorse function.
Definition: colvarcomp_coordnums.cpp:478
vector of real numbers with three components
Definition: colvartypes.h:728
Class to store the system's boundary conditions.
Definition: colvars_system.h:16
COLVARS_HOST_DEVICE cvm::rvector position_distance(cvm::atom_pos const &pos1, cvm::atom_pos const &pos2) const
Compute the distance between two positions.
Definition: colvars_system.h:161
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
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