1#ifndef COLVAR_ROTATION_DERIVATIVE
2#define COLVAR_ROTATION_DERIVATIVE
4#include "colvartypes.h"
9#if defined(__INTEL_COMPILER) || (defined(__PGI) && !defined(__NVCOMPILER))
10#define _noalias restrict
11#elif defined(__GNUC__) || defined(__INTEL_LLVM_COMPILER) || defined(__NVCOMPILER)
12#define _noalias __restrict
19enum class rotation_derivative_dldq {
26inline constexpr rotation_derivative_dldq operator|(rotation_derivative_dldq Lhs, rotation_derivative_dldq Rhs) {
27 return static_cast<rotation_derivative_dldq
>(
28 static_cast<std::underlying_type<rotation_derivative_dldq>::type
>(Lhs) |
29 static_cast<std::underlying_type<rotation_derivative_dldq>::type
>(Rhs));
32inline constexpr bool operator&(rotation_derivative_dldq Lhs, rotation_derivative_dldq Rhs)
34 return (
static_cast<std::underlying_type<rotation_derivative_dldq>::type
>(Lhs) &
35 static_cast<std::underlying_type<rotation_derivative_dldq>::type
>(Rhs));
44 const std::vector<cvm::real> &
m_pos1;
46 const std::vector<cvm::real> &
m_pos2;
66 const std::vector<cvm::real> &pos1,
67 const std::vector<cvm::real> &pos2,
68 const size_t num_atoms_pos1,
69 const size_t num_atoms_pos2):
80 if (require_dl_dq & rotation_derivative_dldq::use_dl) {
99 if (require_dl_dq & rotation_derivative_dldq::use_dq) {
109 tmp_Q0Q0_L[0][0][0] = (Q1[0] * Q0[0]) / (L0-L1) * Q1[0] +
110 (Q2[0] * Q0[0]) / (L0-L2) * Q2[0] +
111 (Q3[0] * Q0[0]) / (L0-L3) * Q3[0];
112 tmp_Q0Q0_L[1][0][0] = (Q1[0] * Q0[0]) / (L0-L1) * Q1[1] +
113 (Q2[0] * Q0[0]) / (L0-L2) * Q2[1] +
114 (Q3[0] * Q0[0]) / (L0-L3) * Q3[1];
115 tmp_Q0Q0_L[2][0][0] = (Q1[0] * Q0[0]) / (L0-L1) * Q1[2] +
116 (Q2[0] * Q0[0]) / (L0-L2) * Q2[2] +
117 (Q3[0] * Q0[0]) / (L0-L3) * Q3[2];
118 tmp_Q0Q0_L[3][0][0] = (Q1[0] * Q0[0]) / (L0-L1) * Q1[3] +
119 (Q2[0] * Q0[0]) / (L0-L2) * Q2[3] +
120 (Q3[0] * Q0[0]) / (L0-L3) * Q3[3];
122 tmp_Q0Q0_L[0][0][1] = (Q1[0] * Q0[1]) / (L0-L1) * Q1[0] +
123 (Q2[0] * Q0[1]) / (L0-L2) * Q2[0] +
124 (Q3[0] * Q0[1]) / (L0-L3) * Q3[0];
125 tmp_Q0Q0_L[1][0][1] = (Q1[0] * Q0[1]) / (L0-L1) * Q1[1] +
126 (Q2[0] * Q0[1]) / (L0-L2) * Q2[1] +
127 (Q3[0] * Q0[1]) / (L0-L3) * Q3[1];
128 tmp_Q0Q0_L[2][0][1] = (Q1[0] * Q0[1]) / (L0-L1) * Q1[2] +
129 (Q2[0] * Q0[1]) / (L0-L2) * Q2[2] +
130 (Q3[0] * Q0[1]) / (L0-L3) * Q3[2];
131 tmp_Q0Q0_L[3][0][1] = (Q1[0] * Q0[1]) / (L0-L1) * Q1[3] +
132 (Q2[0] * Q0[1]) / (L0-L2) * Q2[3] +
133 (Q3[0] * Q0[1]) / (L0-L3) * Q3[3];
136 tmp_Q0Q0_L[0][0][2] = (Q1[0] * Q0[2]) / (L0-L1) * Q1[0] +
137 (Q2[0] * Q0[2]) / (L0-L2) * Q2[0] +
138 (Q3[0] * Q0[2]) / (L0-L3) * Q3[0];
139 tmp_Q0Q0_L[1][0][2] = (Q1[0] * Q0[2]) / (L0-L1) * Q1[1] +
140 (Q2[0] * Q0[2]) / (L0-L2) * Q2[1] +
141 (Q3[0] * Q0[2]) / (L0-L3) * Q3[1];
142 tmp_Q0Q0_L[2][0][2] = (Q1[0] * Q0[2]) / (L0-L1) * Q1[2] +
143 (Q2[0] * Q0[2]) / (L0-L2) * Q2[2] +
144 (Q3[0] * Q0[2]) / (L0-L3) * Q3[2];
145 tmp_Q0Q0_L[3][0][2] = (Q1[0] * Q0[2]) / (L0-L1) * Q1[3] +
146 (Q2[0] * Q0[2]) / (L0-L2) * Q2[3] +
147 (Q3[0] * Q0[2]) / (L0-L3) * Q3[3];
149 tmp_Q0Q0_L[0][0][3] = (Q1[0] * Q0[3]) / (L0-L1) * Q1[0] +
150 (Q2[0] * Q0[3]) / (L0-L2) * Q2[0] +
151 (Q3[0] * Q0[3]) / (L0-L3) * Q3[0];
152 tmp_Q0Q0_L[1][0][3] = (Q1[0] * Q0[3]) / (L0-L1) * Q1[1] +
153 (Q2[0] * Q0[3]) / (L0-L2) * Q2[1] +
154 (Q3[0] * Q0[3]) / (L0-L3) * Q3[1];
155 tmp_Q0Q0_L[2][0][3] = (Q1[0] * Q0[3]) / (L0-L1) * Q1[2] +
156 (Q2[0] * Q0[3]) / (L0-L2) * Q2[2] +
157 (Q3[0] * Q0[3]) / (L0-L3) * Q3[2];
158 tmp_Q0Q0_L[3][0][3] = (Q1[0] * Q0[3]) / (L0-L1) * Q1[3] +
159 (Q2[0] * Q0[3]) / (L0-L2) * Q2[3] +
160 (Q3[0] * Q0[3]) / (L0-L3) * Q3[3];
162 tmp_Q0Q0_L[0][1][0] = (Q1[1] * Q0[0]) / (L0-L1) * Q1[0] +
163 (Q2[1] * Q0[0]) / (L0-L2) * Q2[0] +
164 (Q3[1] * Q0[0]) / (L0-L3) * Q3[0];
165 tmp_Q0Q0_L[1][1][0] = (Q1[1] * Q0[0]) / (L0-L1) * Q1[1] +
166 (Q2[1] * Q0[0]) / (L0-L2) * Q2[1] +
167 (Q3[1] * Q0[0]) / (L0-L3) * Q3[1];
168 tmp_Q0Q0_L[2][1][0] = (Q1[1] * Q0[0]) / (L0-L1) * Q1[2] +
169 (Q2[1] * Q0[0]) / (L0-L2) * Q2[2] +
170 (Q3[1] * Q0[0]) / (L0-L3) * Q3[2];
171 tmp_Q0Q0_L[3][1][0] = (Q1[1] * Q0[0]) / (L0-L1) * Q1[3] +
172 (Q2[1] * Q0[0]) / (L0-L2) * Q2[3] +
173 (Q3[1] * Q0[0]) / (L0-L3) * Q3[3];
175 tmp_Q0Q0_L[0][1][1] = (Q1[1] * Q0[1]) / (L0-L1) * Q1[0] +
176 (Q2[1] * Q0[1]) / (L0-L2) * Q2[0] +
177 (Q3[1] * Q0[1]) / (L0-L3) * Q3[0];
178 tmp_Q0Q0_L[1][1][1] = (Q1[1] * Q0[1]) / (L0-L1) * Q1[1] +
179 (Q2[1] * Q0[1]) / (L0-L2) * Q2[1] +
180 (Q3[1] * Q0[1]) / (L0-L3) * Q3[1];
181 tmp_Q0Q0_L[2][1][1] = (Q1[1] * Q0[1]) / (L0-L1) * Q1[2] +
182 (Q2[1] * Q0[1]) / (L0-L2) * Q2[2] +
183 (Q3[1] * Q0[1]) / (L0-L3) * Q3[2];
184 tmp_Q0Q0_L[3][1][1] = (Q1[1] * Q0[1]) / (L0-L1) * Q1[3] +
185 (Q2[1] * Q0[1]) / (L0-L2) * Q2[3] +
186 (Q3[1] * Q0[1]) / (L0-L3) * Q3[3];
188 tmp_Q0Q0_L[0][1][2] = (Q1[1] * Q0[2]) / (L0-L1) * Q1[0] +
189 (Q2[1] * Q0[2]) / (L0-L2) * Q2[0] +
190 (Q3[1] * Q0[2]) / (L0-L3) * Q3[0];
191 tmp_Q0Q0_L[1][1][2] = (Q1[1] * Q0[2]) / (L0-L1) * Q1[1] +
192 (Q2[1] * Q0[2]) / (L0-L2) * Q2[1] +
193 (Q3[1] * Q0[2]) / (L0-L3) * Q3[1];
194 tmp_Q0Q0_L[2][1][2] = (Q1[1] * Q0[2]) / (L0-L1) * Q1[2] +
195 (Q2[1] * Q0[2]) / (L0-L2) * Q2[2] +
196 (Q3[1] * Q0[2]) / (L0-L3) * Q3[2];
197 tmp_Q0Q0_L[3][1][2] = (Q1[1] * Q0[2]) / (L0-L1) * Q1[3] +
198 (Q2[1] * Q0[2]) / (L0-L2) * Q2[3] +
199 (Q3[1] * Q0[2]) / (L0-L3) * Q3[3];
201 tmp_Q0Q0_L[0][1][3] = (Q1[1] * Q0[3]) / (L0-L1) * Q1[0] +
202 (Q2[1] * Q0[3]) / (L0-L2) * Q2[0] +
203 (Q3[1] * Q0[3]) / (L0-L3) * Q3[0];
204 tmp_Q0Q0_L[1][1][3] = (Q1[1] * Q0[3]) / (L0-L1) * Q1[1] +
205 (Q2[1] * Q0[3]) / (L0-L2) * Q2[1] +
206 (Q3[1] * Q0[3]) / (L0-L3) * Q3[1];
207 tmp_Q0Q0_L[2][1][3] = (Q1[1] * Q0[3]) / (L0-L1) * Q1[2] +
208 (Q2[1] * Q0[3]) / (L0-L2) * Q2[2] +
209 (Q3[1] * Q0[3]) / (L0-L3) * Q3[2];
210 tmp_Q0Q0_L[3][1][3] = (Q1[1] * Q0[3]) / (L0-L1) * Q1[3] +
211 (Q2[1] * Q0[3]) / (L0-L2) * Q2[3] +
212 (Q3[1] * Q0[3]) / (L0-L3) * Q3[3];
215 tmp_Q0Q0_L[0][2][0] = (Q1[2] * Q0[0]) / (L0-L1) * Q1[0] +
216 (Q2[2] * Q0[0]) / (L0-L2) * Q2[0] +
217 (Q3[2] * Q0[0]) / (L0-L3) * Q3[0];
218 tmp_Q0Q0_L[1][2][0] = (Q1[2] * Q0[0]) / (L0-L1) * Q1[1] +
219 (Q2[2] * Q0[0]) / (L0-L2) * Q2[1] +
220 (Q3[2] * Q0[0]) / (L0-L3) * Q3[1];
221 tmp_Q0Q0_L[2][2][0] = (Q1[2] * Q0[0]) / (L0-L1) * Q1[2] +
222 (Q2[2] * Q0[0]) / (L0-L2) * Q2[2] +
223 (Q3[2] * Q0[0]) / (L0-L3) * Q3[2];
224 tmp_Q0Q0_L[3][2][0] = (Q1[2] * Q0[0]) / (L0-L1) * Q1[3] +
225 (Q2[2] * Q0[0]) / (L0-L2) * Q2[3] +
226 (Q3[2] * Q0[0]) / (L0-L3) * Q3[3];
228 tmp_Q0Q0_L[0][2][1] = (Q1[2] * Q0[1]) / (L0-L1) * Q1[0] +
229 (Q2[2] * Q0[1]) / (L0-L2) * Q2[0] +
230 (Q3[2] * Q0[1]) / (L0-L3) * Q3[0];
231 tmp_Q0Q0_L[1][2][1] = (Q1[2] * Q0[1]) / (L0-L1) * Q1[1] +
232 (Q2[2] * Q0[1]) / (L0-L2) * Q2[1] +
233 (Q3[2] * Q0[1]) / (L0-L3) * Q3[1];
234 tmp_Q0Q0_L[2][2][1] = (Q1[2] * Q0[1]) / (L0-L1) * Q1[2] +
235 (Q2[2] * Q0[1]) / (L0-L2) * Q2[2] +
236 (Q3[2] * Q0[1]) / (L0-L3) * Q3[2];
237 tmp_Q0Q0_L[3][2][1] = (Q1[2] * Q0[1]) / (L0-L1) * Q1[3] +
238 (Q2[2] * Q0[1]) / (L0-L2) * Q2[3] +
239 (Q3[2] * Q0[1]) / (L0-L3) * Q3[3];
241 tmp_Q0Q0_L[0][2][2] = (Q1[2] * Q0[2]) / (L0-L1) * Q1[0] +
242 (Q2[2] * Q0[2]) / (L0-L2) * Q2[0] +
243 (Q3[2] * Q0[2]) / (L0-L3) * Q3[0];
244 tmp_Q0Q0_L[1][2][2] = (Q1[2] * Q0[2]) / (L0-L1) * Q1[1] +
245 (Q2[2] * Q0[2]) / (L0-L2) * Q2[1] +
246 (Q3[2] * Q0[2]) / (L0-L3) * Q3[1];
247 tmp_Q0Q0_L[2][2][2] = (Q1[2] * Q0[2]) / (L0-L1) * Q1[2] +
248 (Q2[2] * Q0[2]) / (L0-L2) * Q2[2] +
249 (Q3[2] * Q0[2]) / (L0-L3) * Q3[2];
250 tmp_Q0Q0_L[3][2][2] = (Q1[2] * Q0[2]) / (L0-L1) * Q1[3] +
251 (Q2[2] * Q0[2]) / (L0-L2) * Q2[3] +
252 (Q3[2] * Q0[2]) / (L0-L3) * Q3[3];
254 tmp_Q0Q0_L[0][2][3] = (Q1[2] * Q0[3]) / (L0-L1) * Q1[0] +
255 (Q2[2] * Q0[3]) / (L0-L2) * Q2[0] +
256 (Q3[2] * Q0[3]) / (L0-L3) * Q3[0];
257 tmp_Q0Q0_L[1][2][3] = (Q1[2] * Q0[3]) / (L0-L1) * Q1[1] +
258 (Q2[2] * Q0[3]) / (L0-L2) * Q2[1] +
259 (Q3[2] * Q0[3]) / (L0-L3) * Q3[1];
260 tmp_Q0Q0_L[2][2][3] = (Q1[2] * Q0[3]) / (L0-L1) * Q1[2] +
261 (Q2[2] * Q0[3]) / (L0-L2) * Q2[2] +
262 (Q3[2] * Q0[3]) / (L0-L3) * Q3[2];
263 tmp_Q0Q0_L[3][2][3] = (Q1[2] * Q0[3]) / (L0-L1) * Q1[3] +
264 (Q2[2] * Q0[3]) / (L0-L2) * Q2[3] +
265 (Q3[2] * Q0[3]) / (L0-L3) * Q3[3];
267 tmp_Q0Q0_L[0][3][0] = (Q1[3] * Q0[0]) / (L0-L1) * Q1[0] +
268 (Q2[3] * Q0[0]) / (L0-L2) * Q2[0] +
269 (Q3[3] * Q0[0]) / (L0-L3) * Q3[0];
270 tmp_Q0Q0_L[1][3][0] = (Q1[3] * Q0[0]) / (L0-L1) * Q1[1] +
271 (Q2[3] * Q0[0]) / (L0-L2) * Q2[1] +
272 (Q3[3] * Q0[0]) / (L0-L3) * Q3[1];
273 tmp_Q0Q0_L[2][3][0] = (Q1[3] * Q0[0]) / (L0-L1) * Q1[2] +
274 (Q2[3] * Q0[0]) / (L0-L2) * Q2[2] +
275 (Q3[3] * Q0[0]) / (L0-L3) * Q3[2];
276 tmp_Q0Q0_L[3][3][0] = (Q1[3] * Q0[0]) / (L0-L1) * Q1[3] +
277 (Q2[3] * Q0[0]) / (L0-L2) * Q2[3] +
278 (Q3[3] * Q0[0]) / (L0-L3) * Q3[3];
280 tmp_Q0Q0_L[0][3][1] = (Q1[3] * Q0[1]) / (L0-L1) * Q1[0] +
281 (Q2[3] * Q0[1]) / (L0-L2) * Q2[0] +
282 (Q3[3] * Q0[1]) / (L0-L3) * Q3[0];
283 tmp_Q0Q0_L[1][3][1] = (Q1[3] * Q0[1]) / (L0-L1) * Q1[1] +
284 (Q2[3] * Q0[1]) / (L0-L2) * Q2[1] +
285 (Q3[3] * Q0[1]) / (L0-L3) * Q3[1];
286 tmp_Q0Q0_L[2][3][1] = (Q1[3] * Q0[1]) / (L0-L1) * Q1[2] +
287 (Q2[3] * Q0[1]) / (L0-L2) * Q2[2] +
288 (Q3[3] * Q0[1]) / (L0-L3) * Q3[2];
289 tmp_Q0Q0_L[3][3][1] = (Q1[3] * Q0[1]) / (L0-L1) * Q1[3] +
290 (Q2[3] * Q0[1]) / (L0-L2) * Q2[3] +
291 (Q3[3] * Q0[1]) / (L0-L3) * Q3[3];
293 tmp_Q0Q0_L[0][3][2] = (Q1[3] * Q0[2]) / (L0-L1) * Q1[0] +
294 (Q2[3] * Q0[2]) / (L0-L2) * Q2[0] +
295 (Q3[3] * Q0[2]) / (L0-L3) * Q3[0];
296 tmp_Q0Q0_L[1][3][2] = (Q1[3] * Q0[2]) / (L0-L1) * Q1[1] +
297 (Q2[3] * Q0[2]) / (L0-L2) * Q2[1] +
298 (Q3[3] * Q0[2]) / (L0-L3) * Q3[1];
299 tmp_Q0Q0_L[2][3][2] = (Q1[3] * Q0[2]) / (L0-L1) * Q1[2] +
300 (Q2[3] * Q0[2]) / (L0-L2) * Q2[2] +
301 (Q3[3] * Q0[2]) / (L0-L3) * Q3[2];
302 tmp_Q0Q0_L[3][3][2] = (Q1[3] * Q0[2]) / (L0-L1) * Q1[3] +
303 (Q2[3] * Q0[2]) / (L0-L2) * Q2[3] +
304 (Q3[3] * Q0[2]) / (L0-L3) * Q3[3];
306 tmp_Q0Q0_L[0][3][3] = (Q1[3] * Q0[3]) / (L0-L1) * Q1[0] +
307 (Q2[3] * Q0[3]) / (L0-L2) * Q2[0] +
308 (Q3[3] * Q0[3]) / (L0-L3) * Q3[0];
309 tmp_Q0Q0_L[1][3][3] = (Q1[3] * Q0[3]) / (L0-L1) * Q1[1] +
310 (Q2[3] * Q0[3]) / (L0-L2) * Q2[1] +
311 (Q3[3] * Q0[3]) / (L0-L3) * Q3[1];
312 tmp_Q0Q0_L[2][3][3] = (Q1[3] * Q0[3]) / (L0-L1) * Q1[2] +
313 (Q2[3] * Q0[3]) / (L0-L2) * Q2[2] +
314 (Q3[3] * Q0[3]) / (L0-L3) * Q3[2];
315 tmp_Q0Q0_L[3][3][3] = (Q1[3] * Q0[3]) / (L0-L1) * Q1[3] +
316 (Q2[3] * Q0[3]) / (L0-L2) * Q2[3] +
317 (Q3[3] * Q0[3]) / (L0-L3) * Q3[3];
327 template <
bool use_dl,
bool use_dq,
bool use_ds>
336 for (
int i = 0; i < 4; ++i) {
337 for (
int j = 0; j < 4; ++j) {
338 (*ds_out)[i][j] = ds[i][j];
351 *dl0_out =
tmp_Q0Q0[0][0] * ds[0][0] +
370 if (dq0_out->size() != 4) dq0_out->resize(4);
384 (*dq0_out)[0] = tmp_Q0Q0_L[0][0][0] * ds[0][0] +
385 tmp_Q0Q0_L[0][0][1] * ds[0][1] +
386 tmp_Q0Q0_L[0][0][2] * ds[0][2] +
387 tmp_Q0Q0_L[0][0][3] * ds[0][3] +
388 tmp_Q0Q0_L[0][1][0] * ds[1][0] +
389 tmp_Q0Q0_L[0][1][1] * ds[1][1] +
390 tmp_Q0Q0_L[0][1][2] * ds[1][2] +
391 tmp_Q0Q0_L[0][1][3] * ds[1][3] +
392 tmp_Q0Q0_L[0][2][0] * ds[2][0] +
393 tmp_Q0Q0_L[0][2][1] * ds[2][1] +
394 tmp_Q0Q0_L[0][2][2] * ds[2][2] +
395 tmp_Q0Q0_L[0][2][3] * ds[2][3] +
396 tmp_Q0Q0_L[0][3][0] * ds[3][0] +
397 tmp_Q0Q0_L[0][3][1] * ds[3][1] +
398 tmp_Q0Q0_L[0][3][2] * ds[3][2] +
399 tmp_Q0Q0_L[0][3][3] * ds[3][3];
401 (*dq0_out)[1] = tmp_Q0Q0_L[1][0][0] * ds[0][0] +
402 tmp_Q0Q0_L[1][0][1] * ds[0][1] +
403 tmp_Q0Q0_L[1][0][2] * ds[0][2] +
404 tmp_Q0Q0_L[1][0][3] * ds[0][3] +
405 tmp_Q0Q0_L[1][1][0] * ds[1][0] +
406 tmp_Q0Q0_L[1][1][1] * ds[1][1] +
407 tmp_Q0Q0_L[1][1][2] * ds[1][2] +
408 tmp_Q0Q0_L[1][1][3] * ds[1][3] +
409 tmp_Q0Q0_L[1][2][0] * ds[2][0] +
410 tmp_Q0Q0_L[1][2][1] * ds[2][1] +
411 tmp_Q0Q0_L[1][2][2] * ds[2][2] +
412 tmp_Q0Q0_L[1][2][3] * ds[2][3] +
413 tmp_Q0Q0_L[1][3][0] * ds[3][0] +
414 tmp_Q0Q0_L[1][3][1] * ds[3][1] +
415 tmp_Q0Q0_L[1][3][2] * ds[3][2] +
416 tmp_Q0Q0_L[1][3][3] * ds[3][3];
418 (*dq0_out)[2] = tmp_Q0Q0_L[2][0][0] * ds[0][0] +
419 tmp_Q0Q0_L[2][0][1] * ds[0][1] +
420 tmp_Q0Q0_L[2][0][2] * ds[0][2] +
421 tmp_Q0Q0_L[2][0][3] * ds[0][3] +
422 tmp_Q0Q0_L[2][1][0] * ds[1][0] +
423 tmp_Q0Q0_L[2][1][1] * ds[1][1] +
424 tmp_Q0Q0_L[2][1][2] * ds[1][2] +
425 tmp_Q0Q0_L[2][1][3] * ds[1][3] +
426 tmp_Q0Q0_L[2][2][0] * ds[2][0] +
427 tmp_Q0Q0_L[2][2][1] * ds[2][1] +
428 tmp_Q0Q0_L[2][2][2] * ds[2][2] +
429 tmp_Q0Q0_L[2][2][3] * ds[2][3] +
430 tmp_Q0Q0_L[2][3][0] * ds[3][0] +
431 tmp_Q0Q0_L[2][3][1] * ds[3][1] +
432 tmp_Q0Q0_L[2][3][2] * ds[3][2] +
433 tmp_Q0Q0_L[2][3][3] * ds[3][3];
435 (*dq0_out)[3] = tmp_Q0Q0_L[3][0][0] * ds[0][0] +
436 tmp_Q0Q0_L[3][0][1] * ds[0][1] +
437 tmp_Q0Q0_L[3][0][2] * ds[0][2] +
438 tmp_Q0Q0_L[3][0][3] * ds[0][3] +
439 tmp_Q0Q0_L[3][1][0] * ds[1][0] +
440 tmp_Q0Q0_L[3][1][1] * ds[1][1] +
441 tmp_Q0Q0_L[3][1][2] * ds[1][2] +
442 tmp_Q0Q0_L[3][1][3] * ds[1][3] +
443 tmp_Q0Q0_L[3][2][0] * ds[2][0] +
444 tmp_Q0Q0_L[3][2][1] * ds[2][1] +
445 tmp_Q0Q0_L[3][2][2] * ds[2][2] +
446 tmp_Q0Q0_L[3][2][3] * ds[2][3] +
447 tmp_Q0Q0_L[3][3][0] * ds[3][0] +
448 tmp_Q0Q0_L[3][3][1] * ds[3][1] +
449 tmp_Q0Q0_L[3][3][2] * ds[3][2] +
450 tmp_Q0Q0_L[3][3][3] * ds[3][3];
463 template <
bool use_dl,
bool use_dq,
bool use_ds>
465 size_t ia,
cvm::rvector* _noalias
const dl0_1_out =
nullptr,
473 {{ a2x, a2y, a2z}, { 0.0, a2z, -a2y}, {-a2z, 0.0, a2x}, { a2y, -a2x, 0.0}},
474 {{ 0.0, a2z, -a2y}, { a2x, -a2y, -a2z}, { a2y, a2x, 0.0}, { a2z, 0.0, a2x}},
475 {{-a2z, 0.0, a2x}, { a2y, a2x, 0.0}, {-a2x, a2y, -a2z}, { 0.0, a2z, a2y}},
476 {{ a2y, -a2x, 0.0}, { a2z, 0.0, a2x}, { 0.0, a2z, a2y}, {-a2x, -a2y, a2z}}};
477 calc_derivative_impl<use_dl, use_dq, use_ds>(ds_1, dl0_1_out, dq0_1_out, ds_1_out);
489 template <
bool use_dl,
bool use_dq,
bool use_ds>
491 size_t ia,
cvm::rvector* _noalias
const dl0_2_out =
nullptr,
499 {{ a1x, a1y, a1z}, { 0.0, -a1z, a1y}, { a1z, 0.0, -a1x}, {-a1y, a1x, 0.0}},
500 {{ 0.0, -a1z, a1y}, { a1x, -a1y, -a1z}, { a1y, a1x, 0.0}, { a1z, 0.0, a1x}},
501 {{ a1z, 0.0, -a1x}, { a1y, a1x, 0.0}, {-a1x, a1y, -a1z}, { 0.0, a1z, a1y}},
502 {{-a1y, a1x, 0.0}, { a1z, 0.0, a1x}, { 0.0, a1z, a1y}, {-a1x, -a1y, a1z}}};
503 calc_derivative_impl<use_dl, use_dq, use_ds>(ds_2, dl0_2_out, dq0_2_out, ds_2_out);
Arbitrary size array (two dimensions) suitable for linear algebra operations (i.e....
Definition: colvartypes.h:372
A rotation between two sets of coordinates (for the moment a wrapper for colvarmodule::quaternion)
Definition: colvartypes.h:1359
cvm::real S_eigval[4]
Eigenvalues of S.
Definition: colvartypes.h:1368
cvm::real S_eigvec[4][4]
Eigenvectors of S.
Definition: colvartypes.h:1371
vector of real numbers with three components
Definition: colvartypes.h:723
Arbitrary size array (one dimensions) suitable for linear algebra operations (i.e....
Definition: colvartypes.h:33
double real
Defining an abstract real number allows to switch precision.
Definition: colvarmodule.h:150
Helper class for calculating the derivative of rotation.
Definition: colvar_rotation_derivative.h:40
rotation_derivative(const cvm::rotation &rot, const std::vector< cvm::real > &pos1, const std::vector< cvm::real > &pos2, const size_t num_atoms_pos1, const size_t num_atoms_pos2)
Constructor of the cvm::rotation::derivative class for SOA.
Definition: colvar_rotation_derivative.h:64
void prepare_derivative(rotation_derivative_dldq require_dl_dq)
This function must be called before calc_derivative_wrt_group1 and calc_derivative_wrt_group2 in orde...
Definition: colvar_rotation_derivative.h:79
size_t m_num_atoms_pos1
Number of atoms in group1 (used in SOA)
Definition: colvar_rotation_derivative.h:48
void calc_derivative_wrt_group1(size_t ia, cvm::rvector *_noalias const dl0_1_out=nullptr, cvm::vector1d< cvm::rvector > *_noalias const dq0_1_out=nullptr, cvm::matrix2d< cvm::rvector > *_noalias const ds_1_out=nullptr) const
Calculate the derivatives of S, the leading eigenvalue L and the leading eigenvector Q with respect t...
Definition: colvar_rotation_derivative.h:464
cvm::real tmp_Q0Q0[4][4]
Temporary variable that will be updated if prepare_derivative called.
Definition: colvar_rotation_derivative.h:52
const std::vector< cvm::real > & m_pos1
Reference to the atom positions of group 1.
Definition: colvar_rotation_derivative.h:44
void calc_derivative_impl(const cvm::rvector(&ds)[4][4], cvm::rvector *_noalias const dl0_out, cvm::vector1d< cvm::rvector > *_noalias const dq0_out, cvm::matrix2d< cvm::rvector > *_noalias const ds_out) const
Actual implementation of the derivative calculation.
Definition: colvar_rotation_derivative.h:328
void calc_derivative_wrt_group2(size_t ia, cvm::rvector *_noalias const dl0_2_out=nullptr, cvm::vector1d< cvm::rvector > *_noalias const dq0_2_out=nullptr, cvm::matrix2d< cvm::rvector > *_noalias const ds_2_out=nullptr) const
Calculate the derivatives of S, the leading eigenvalue L and the leading eigenvector Q with respect t...
Definition: colvar_rotation_derivative.h:490
const cvm::rotation & m_rot
Reference to the rotation.
Definition: colvar_rotation_derivative.h:42
size_t m_num_atoms_pos2
Number of atoms in group1 (used in SOA)
Definition: colvar_rotation_derivative.h:50
const std::vector< cvm::real > & m_pos2
Reference to the atom positions of group 2.
Definition: colvar_rotation_derivative.h:46