Collective Variables Module - Developer Documentation
Loading...
Searching...
No Matches
colvars_system.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#ifndef COLVARS_SYSTEM_H
11#define COLVARS_SYSTEM_H
12
13#include "colvartypes.h"
14
17public:
18
20 enum class types {
21 non_periodic,
22 mixed,
26 };
27
29 inline COLVARS_HOST_DEVICE system_boundary_conditions() { reset(); }
30
33
35 inline COLVARS_HOST_DEVICE types type() const { return type_; }
36
38 inline COLVARS_HOST_DEVICE void set_type(types t) { type_ = t; }
39
41 inline COLVARS_HOST_DEVICE cvm::rvector position_distance(cvm::atom_pos const &pos1,
42 cvm::atom_pos const &pos2) const;
43
45 inline COLVARS_HOST_DEVICE cvm::rvector get_triclinic_shift(cvm::rvector const &diff) const;
46
48 inline COLVARS_HOST_DEVICE void reset() {
49 periodic_x = periodic_y = periodic_z = false;
50 type_ = types::non_periodic;
52 unit_cell_y.reset();
53 unit_cell_z.reset();
55 reciprocal_cell_y.reset();
56 reciprocal_cell_z.reset();
57 }
58
60 inline COLVARS_HOST_DEVICE void set_boundaries(bool periodic_x_in, bool periodic_y_in,
61 bool periodic_z_in, cvm::rvector const &A,
62 cvm::rvector const &B, cvm::rvector const &C);
63protected:
64
66 types type_ = types::non_periodic;
67
69 cvm::rvector unit_cell_x, unit_cell_y, unit_cell_z;
70
72 cvm::rvector reciprocal_cell_x, reciprocal_cell_y, reciprocal_cell_z;
73
75 bool periodic_x = false, periodic_y = false, periodic_z = false;
76};
77
78
80inline COLVARS_HOST_DEVICE void
81cvm::system_boundary_conditions::set_boundaries(bool periodic_x_in, bool periodic_y_in,
82 bool periodic_z_in, cvm::rvector const &A,
83 cvm::rvector const &B, cvm::rvector const &C)
84{
85 constexpr double diagonal_tol2 = 1.0e-10;
86
87 periodic_x = periodic_x_in;
88 periodic_y = periodic_y_in;
89 periodic_z = periodic_z_in;
90
91 // Avoid using stale reciprocal vectors when switching boundary types (especially for mixed periodicity)
93 reciprocal_cell_y.reset();
94 reciprocal_cell_z.reset();
95 if ((periodic_x == periodic_y) && (periodic_x == periodic_z)) {
96 if (periodic_x) {
97 // Temporarily set as fully-periodic & orthogonal; will check below for triclinic
99 } else {
100 reset();
101 return;
102 }
103 } else {
105 }
106
107 bool off_diagonal = false;
108
109 if (periodic_x) {
110 unit_cell_x = A;
111 if ((A.y * A.y) > diagonal_tol2 || (A.z * A.z) > diagonal_tol2) {
112 off_diagonal = true;
113 } else {
115 }
116 } else {
119 }
120
121 if (periodic_y) {
122 unit_cell_y = B;
123 if ((B.x * B.x) > diagonal_tol2 || (B.z * B.z) > diagonal_tol2) {
124 off_diagonal = true;
125 } else {
126 reciprocal_cell_y = unit_cell_y/unit_cell_y.norm2();
127 }
128 } else {
129 unit_cell_y.reset();
130 reciprocal_cell_y.reset();
131 }
132
133 if (periodic_z) {
134 unit_cell_z = C;
135 if ((C.x * C.x) > diagonal_tol2 || (C.y * C.y) > diagonal_tol2) {
136 off_diagonal = true;
137 } else {
138 reciprocal_cell_z = unit_cell_z/unit_cell_z.norm2();
139 }
140 } else {
141 unit_cell_z.reset();
142 reciprocal_cell_z.reset();
143 }
144
145 if (type() == types::pbc_orthogonal && off_diagonal) {
147 }
148
149 if (type() == types::pbc_triclinic) {
150 cvm::rvector const v_yz = cvm::rvector::outer(unit_cell_y, unit_cell_z);
151 reciprocal_cell_x = v_yz / (v_yz * unit_cell_x);
152 cvm::rvector const v_zx = cvm::rvector::outer(unit_cell_z, unit_cell_x);
153 reciprocal_cell_y = v_zx / (v_zx * unit_cell_y);
154 cvm::rvector const v_xy = cvm::rvector::outer(unit_cell_x, unit_cell_y);
155 reciprocal_cell_z = v_xy / (v_xy * unit_cell_z);
156 }
157}
158
159
160inline COLVARS_HOST_DEVICE
161cvm::rvector cvm::system_boundary_conditions::position_distance(cvm::atom_pos const &pos1,
162 cvm::atom_pos const &pos2) const
163{
164 cvm::rvector diff = (pos2 - pos1);
165
166 if (type() == types::non_periodic) {
167 return diff;
168 }
169
170 if (type() == types::unsupported) {
171#if !(defined(__HIP_DEVICE_COMPILE__)) && !(defined(__CUDA_ARCH__))
172 cvm::error_static("Error: unsupported boundary conditions.\n", COLVARS_INPUT_ERROR);
173#endif
174 return diff;
175 }
176
177 cvm::real const x_shift = ::floor(reciprocal_cell_x * diff + 0.5);
178 cvm::real const y_shift = ::floor(reciprocal_cell_y * diff + 0.5);
179 cvm::real const z_shift = ::floor(reciprocal_cell_z * diff + 0.5);
180
181 diff.x -= x_shift * unit_cell_x.x + y_shift * unit_cell_y.x + z_shift * unit_cell_z.x;
182 diff.y -= x_shift * unit_cell_x.y + y_shift * unit_cell_y.y + z_shift * unit_cell_z.y;
183 diff.z -= x_shift * unit_cell_x.z + y_shift * unit_cell_y.z + z_shift * unit_cell_z.z;
184
185 if (type() != types::pbc_orthogonal) {
186 // Matches both "mixed" and "pbc_triclinic", because reciprocal cell vectors are not used
187 diff += get_triclinic_shift(diff);
188 }
189
190 return diff;
191}
192
193
194inline COLVARS_HOST_DEVICE cvm::rvector
195cvm::system_boundary_conditions::get_triclinic_shift(cvm::rvector const &diff) const
196{
197 cvm::real min_dist2 = diff.norm2();
198 cvm::rvector result{0.0, 0.0, 0.0};
199
200 int const nx = periodic_x ? 1 : 0;
201 int const ny = periodic_y ? 1 : 0;
202 int const nz = periodic_z ? 1 : 0;
203
204 // Loop over neighboring cells to find a shorter distance
205 for (int ix = -nx; ix <= nx; ix++) {
206 for (int iy = -ny; iy <= ny; iy++) {
207 for (int iz = -nz; iz <= nz; iz++) {
208 cvm::rvector const shift = ix * unit_cell_x + iy * unit_cell_y + iz * unit_cell_z;
209 cvm::real const this_dist2 = (diff + shift).norm2();
210 if (this_dist2 < min_dist2) {
211 result = shift;
212 min_dist2 = this_dist2;
213 }
214 }
215 }
216 }
217
218 return result;
219}
220
221
222#endif
vector of real numbers with three components
Definition: colvartypes.h:728
COLVARS_HOST_DEVICE void reset()
Set all components to zero.
Definition: colvartypes.h:740
Class to store the system's boundary conditions.
Definition: colvars_system.h:16
COLVARS_HOST_DEVICE void set_boundaries(bool periodic_x_in, bool periodic_y_in, bool periodic_z_in, cvm::rvector const &A, cvm::rvector const &B, cvm::rvector const &C)
Set from explicit boundary configuration.
Definition: colvars_system.h:81
system_boundary_conditions(system_boundary_conditions const &)=default
Copy constructor.
types type_
Type of boundary conditions in the current computation.
Definition: colvars_system.h:66
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
cvm::rvector unit_cell_x
Bravais lattice vectors.
Definition: colvars_system.h:69
bool periodic_x
Periodic flags in each dimension.
Definition: colvars_system.h:75
COLVARS_HOST_DEVICE cvm::rvector get_triclinic_shift(cvm::rvector const &diff) const
Compute a shift vector that accounts for tilt factors up to 0.5.
Definition: colvars_system.h:195
COLVARS_HOST_DEVICE void reset()
Reset to defaults (non-periodic)
Definition: colvars_system.h:48
COLVARS_HOST_DEVICE system_boundary_conditions()
Default constructor.
Definition: colvars_system.h:29
types
Type of boundary conditions defined for the current computation.
Definition: colvars_system.h:20
@ mixed
All three dimensions are non-periodic.
@ pbc_triclinic
All three dimensions are periodic, lattice vectors are orthogonal.
@ unsupported
All three dimensions are periodic, lattice vectors are not orthogonal.
@ pbc_orthogonal
Some dimensions are periodic, but others are not.
cvm::rvector reciprocal_cell_x
Reciprocal lattice vectors.
Definition: colvars_system.h:72
COLVARS_HOST_DEVICE void set_type(types t)
Set the type of boundary explicitly.
Definition: colvars_system.h:38
COLVARS_HOST_DEVICE types type() const
Type of boundary conditions in the current computation.
Definition: colvars_system.h:35
double real
Defining an abstract real number allows to switch precision.
Definition: colvarmodule.h:99
static real floor(real const &x)
Reimplemented to work around MS compiler issues.
Definition: colvarmodule.h:125
static int error_static(std::string const &message, int code=-1)
Definition: colvarmodule.h:775