OpenMD 3.2
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
TimeCorrFunc.cpp
1/*
2 * Copyright (c) 2004-present, The University of Notre Dame. All rights
3 * reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 * SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your
32 * research, please cite the following paper when you publish your work:
33 *
34 * [1] Drisko et al., J. Open Source Softw. 9, 7004 (2024).
35 *
36 * Good starting points for code and simulation methodology are:
37 *
38 * [2] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
39 * [3] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
40 * [4] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).
41 * [5] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
42 * [6] Kuang & Gezelter, Mol. Phys., 110, 691-701 (2012).
43 * [7] Lamichhane, Gezelter & Newman, J. Chem. Phys. 141, 134109 (2014).
44 * [8] Bhattarai, Newman & Gezelter, Phys. Rev. B 99, 094106 (2019).
45 * [9] Drisko & Gezelter, J. Chem. Theory Comput. 20, 4986-4997 (2024).
46 */
47
48#include "applications/dynamicProps/TimeCorrFunc.hpp"
49
50#include <memory>
51
54#include "utils/Revision.hpp"
55#include "utils/simError.h"
56
57using namespace std;
58namespace OpenMD {
59
60 template<typename T>
61 TimeCorrFunc<T>::TimeCorrFunc(SimInfo* info, const string& filename,
62 const string& sele1, const string& sele2) :
63 info_(info),
64 dumpFilename_(filename), seleMan1_(info_), seleMan2_(info_),
65 selectionScript1_(sele1), selectionScript2_(sele2), evaluator1_(info_),
66 evaluator2_(info_), autoCorrFunc_(false), doSystemProperties_(false),
67 doMolecularProperties_(false), doObjectProperties_(false),
68 doBondProperties_(false), allowTimeFuzz_(false) {
69 reader_ = new DumpReader(info_, dumpFilename_);
70
71 uniqueSelections_ = (sele1.compare(sele2) != 0) ? true : false;
72
73 Globals* simParams = info_->getSimParams();
74 if (simParams->haveSampleTime()) {
75 deltaTime_ = simParams->getSampleTime();
76 } else {
77 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
78 "TimeCorrFunc Error: can not figure out deltaTime\n");
79 painCave.isFatal = 1;
80 simError();
81 }
82
83 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH, "Scanning for frames.");
84 painCave.isFatal = 0;
85 painCave.severity = OPENMD_INFO;
86 simError();
87
88 nFrames_ = reader_->getNFrames();
89 nTimeBins_ = nFrames_;
90
91 T zeroType(0.0);
92 histogram_.resize(nTimeBins_, zeroType);
93 count_.resize(nTimeBins_, 0);
94
95 times_.resize(nFrames_);
96 sele1ToIndex_.resize(nFrames_);
97 if (uniqueSelections_) { sele2ToIndex_.resize(nFrames_); }
98
99 progressBar_ = std::make_unique<ProgressBar>();
100 }
101
102 template<typename T>
103 void TimeCorrFunc<T>::preCorrelate() {
104 evaluator1_.loadScriptString(selectionScript1_);
105 // if selection is static, we only need to evaluate it once
106 if (!evaluator1_.isDynamic()) {
107 seleMan1_.setSelectionSet(evaluator1_.evaluate());
108 validateSelection(seleMan1_);
109 }
110
111 if (uniqueSelections_) {
112 evaluator2_.loadScriptString(selectionScript2_);
113 if (!evaluator2_.isDynamic()) {
114 seleMan2_.setSelectionSet(evaluator2_.evaluate());
115 validateSelection(seleMan2_);
116 }
117 }
118
119 progressBar_->clear();
120
121 for (int istep = 0; istep < nFrames_; istep++) {
122 reader_->readFrame(istep);
123 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
124 times_[istep] = currentSnapshot_->getTime();
125
126 progressBar_->setStatus(istep + 1, nFrames_);
127 progressBar_->update();
128
129 computeFrame(istep);
130 }
131
132 RealType dt2Avg(0.0);
133 for (int istep = 1; istep < nFrames_; istep++) {
134 RealType dt = times_[istep] - times_[istep - 1];
135 dtMean_ += dt;
136 dt2Avg += dt * dt;
137 }
138 dtMean_ /= RealType(nFrames_ - 1);
139 dt2Avg /= RealType(nFrames_ - 1);
140 dtSigma_ = std::sqrt(dt2Avg - dtMean_ * dtMean_);
141
142 if (dtSigma_ > 1.0e-6) {
143 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
144 "TimeCorrFunc::preCorrelate: sampleTime (%f) does not match\n"
145 "\tthe mean spacing between configurations (%f), with\n"
146 "\tsigma (%f). Proceeding with the mean value.\n",
147 deltaTime_, dtMean_, dtSigma_);
148 allowTimeFuzz_ = true;
149 painCave.isFatal = 0;
150 painCave.severity = OPENMD_INFO;
151 simError();
152 }
153 }
154
155 template<typename T>
156 void TimeCorrFunc<T>::computeFrame(int istep) {
157 Molecule* mol;
158 StuntDouble* sd;
159 Bond* bond;
160 int imol1, imol2, isd1, isd2, ibond1, ibond2;
161 unsigned int index;
162
163 if (evaluator1_.isDynamic()) {
164 seleMan1_.setSelectionSet(evaluator1_.evaluate());
165 validateSelection(seleMan1_);
166 }
167
168 if (uniqueSelections_ && evaluator2_.isDynamic()) {
169 seleMan2_.setSelectionSet(evaluator2_.evaluate());
170 validateSelection(seleMan2_);
171 }
172
173 if (doSystemProperties_) {
174 computeProperty1(istep);
175 if (!autoCorrFunc_) computeProperty2(istep);
176 }
177
178 if (doMolecularProperties_) {
179 for (mol = seleMan1_.beginSelectedMolecule(imol1); mol != NULL;
180 mol = seleMan1_.nextSelectedMolecule(imol1)) {
181 index = computeProperty1(istep, mol);
182
183 if (index == sele1ToIndex_[istep].size()) {
184 sele1ToIndex_[istep].push_back(mol->getGlobalIndex());
185 } else {
186 sele1ToIndex_[istep].resize(index + 1);
187 sele1ToIndex_[istep][index] = mol->getGlobalIndex();
188 }
189
190 if (!uniqueSelections_) { index = computeProperty2(istep, mol); }
191 }
192
193 if (uniqueSelections_) {
194 for (mol = seleMan2_.beginSelectedMolecule(imol2); mol != NULL;
195 mol = seleMan2_.nextSelectedMolecule(imol2)) {
196 if (autoCorrFunc_) {
197 index = computeProperty1(istep, mol);
198 } else {
199 index = computeProperty2(istep, mol);
200 }
201 if (index == sele2ToIndex_[istep].size()) {
202 sele2ToIndex_[istep].push_back(mol->getGlobalIndex());
203 } else {
204 sele2ToIndex_[istep].resize(index + 1);
205 sele2ToIndex_[istep][index] = mol->getGlobalIndex();
206 }
207 }
208 }
209 }
210
211 if (doObjectProperties_) {
212 for (sd = seleMan1_.beginSelected(isd1); sd != NULL;
213 sd = seleMan1_.nextSelected(isd1)) {
214 index = computeProperty1(istep, sd);
215
216 if (index == sele1ToIndex_[istep].size()) {
217 sele1ToIndex_[istep].push_back(sd->getGlobalIndex());
218 } else {
219 sele1ToIndex_[istep].resize(index + 1);
220 sele1ToIndex_[istep][index] = sd->getGlobalIndex();
221 }
222
223 if (!uniqueSelections_) { index = computeProperty2(istep, sd); }
224 }
225
226 if (uniqueSelections_) {
227 for (sd = seleMan2_.beginSelected(isd2); sd != NULL;
228 sd = seleMan2_.nextSelected(isd2)) {
229 if (autoCorrFunc_) {
230 index = computeProperty1(istep, sd);
231 } else {
232 index = computeProperty2(istep, sd);
233 }
234 if (index == sele2ToIndex_[istep].size()) {
235 sele2ToIndex_[istep].push_back(sd->getGlobalIndex());
236 } else {
237 sele2ToIndex_[istep].resize(index + 1);
238 sele2ToIndex_[istep][index] = sd->getGlobalIndex();
239 }
240 }
241 }
242 }
243
244 if (doBondProperties_) {
245 for (bond = seleMan1_.beginSelectedBond(ibond1); bond != NULL;
246 bond = seleMan1_.nextSelectedBond(ibond1)) {
247 index = computeProperty1(istep, bond);
248
249 if (index == sele1ToIndex_[istep].size()) {
250 sele1ToIndex_[istep].push_back(bond->getGlobalIndex());
251 } else {
252 sele1ToIndex_[istep].resize(index + 1);
253 sele1ToIndex_[istep][index] = bond->getGlobalIndex();
254 }
255
256 if (!uniqueSelections_) { index = computeProperty2(istep, bond); }
257 }
258
259 if (uniqueSelections_) {
260 for (bond = seleMan2_.beginSelectedBond(ibond2); bond != NULL;
261 bond = seleMan2_.nextSelectedBond(ibond2)) {
262 if (autoCorrFunc_) {
263 index = computeProperty1(istep, bond);
264 } else {
265 index = computeProperty2(istep, bond);
266 }
267 if (index == sele2ToIndex_[istep].size()) {
268 sele2ToIndex_[istep].push_back(bond->getGlobalIndex());
269 } else {
270 sele2ToIndex_[istep].resize(index + 1);
271 sele2ToIndex_[istep][index] = bond->getGlobalIndex();
272 }
273 }
274 }
275 }
276 }
277
278 template<typename T>
279 void TimeCorrFunc<T>::doCorrelate() {
280 painCave.isFatal = 0;
281 painCave.severity = OPENMD_INFO;
282 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
283 "Starting pre-correlate scan.");
284 simError();
285 preCorrelate();
286
287 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
288 "Calculating correlation function.");
289 simError();
290 correlation();
291
292 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
293 "Doing post-correlation calculations.");
294 simError();
295 postCorrelate();
296
297 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH, "Writing output.");
298 simError();
299 writeCorrelate();
300 }
301
302 template<typename T>
303 void TimeCorrFunc<T>::correlation() {
304 T zeroType(0.0);
305 for (unsigned int i = 0; i < nTimeBins_; ++i) {
306 histogram_[i] = zeroType;
307 count_[i] = 0;
308 }
309
310 progressBar_->clear();
311 RealType samples = 0.5 * (nFrames_ + 1) * nFrames_;
312 int visited = 0;
313
314 for (int i = 0; i < nFrames_; ++i) {
315 RealType time1 = times_[i];
316
317 for (int j = i; j < nFrames_; ++j) {
318 visited++;
319 progressBar_->setStatus(visited, samples);
320 progressBar_->update();
321
322 // Perform a sanity check on the actual configuration times to
323 // make sure the configurations are spaced the same amount the
324 // sample time said they were spaced:
325
326 RealType time2 = times_[j];
327
328 if (std::fabs((time2 - time1) - (j - i) * dtMean_) >
329 6 * dtSigma_ * (j - i)) {
330 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
331 "TimeCorrFunc::correlateBlocks: mean sampleTime (%f)\n"
332 "\tin %s does not match actual time-spacing between\n"
333 "\tconfigurations %d (t = %f) and %d (t = %f).\n",
334 dtMean_, dumpFilename_.c_str(), i, time1, j, time2);
335 if (allowTimeFuzz_) {
336 painCave.isFatal = 0;
337 painCave.severity = OPENMD_INFO;
338 } else {
339 painCave.isFatal = 1;
340 painCave.severity = OPENMD_ERROR;
341 }
342 simError();
343 }
344
345 int timeBin = int((time2 - time1) / dtMean_ + 0.5);
346 correlateFrames(i, j, timeBin);
347 }
348 }
349 }
350
351 /*
352template<typename T>
353void TimeCorrFunc<T>::validateSelection(SelectionManager& seleMan) {
354}
355*/
356
357 template<typename T>
358 void TimeCorrFunc<T>::correlateFrames(int frame1, int frame2, int timeBin) {
359 std::vector<int> s1;
360 std::vector<int> s2;
361
362 std::vector<int>::iterator i1;
363 std::vector<int>::iterator i2;
364
365 T corrVal(0.0);
366
367 if (doSystemProperties_) {
368 corrVal = calcCorrVal(frame1, frame2);
369 histogram_[timeBin] += corrVal;
370 count_[timeBin]++;
371
372 } else {
373 s1 = sele1ToIndex_[frame1];
374
375 if (uniqueSelections_)
376 s2 = sele2ToIndex_[frame2];
377 else
378 s2 = sele1ToIndex_[frame2];
379
380 for (i1 = s1.begin(), i2 = s2.begin(); i1 != s1.end() && i2 != s2.end();
381 ++i1, ++i2) {
382 // If the selections are dynamic, they might not have the
383 // same objects in both frames, so we need to roll either of
384 // the selections until we have the same object to
385 // correlate.
386
387 while (i1 != s1.end() && *i1 < *i2) {
388 ++i1;
389 }
390
391 while (i2 != s2.end() && *i2 < *i1) {
392 ++i2;
393 }
394
395 if (i1 == s1.end() || i2 == s2.end()) break;
396
397 corrVal = calcCorrVal(frame1, frame2, i1 - s1.begin(), i2 - s2.begin());
398 histogram_[timeBin] += corrVal;
399 count_[timeBin]++;
400 }
401 }
402 }
403
404 template<typename T>
405 void TimeCorrFunc<T>::postCorrelate() {
406 T zeroType(0.0);
407 for (unsigned int i = 0; i < nTimeBins_; ++i) {
408 if (count_[i] > 0) {
409 histogram_[i] /= count_[i];
410 } else {
411 histogram_[i] = zeroType;
412 }
413 }
414 }
415
416 template<typename T>
417 void TimeCorrFunc<T>::validateSelection(SelectionManager&) {}
418
419 template<typename T>
420 void TimeCorrFunc<T>::writeCorrelate() {
421 ofstream ofs(outputFilename_.c_str());
422
423 if (ofs.is_open()) {
424 Revision r;
425
426 ofs << "# " << getCorrFuncType() << "\n";
427 ofs << "# OpenMD " << r.getFullRevision() << "\n";
428 ofs << "# " << r.getBuildDate() << "\n";
429 ofs << "# selection script1: \"" << selectionScript1_;
430 ofs << "\"\tselection script2: \"" << selectionScript2_ << "\"\n";
431 if (!paramString_.empty())
432 ofs << "# parameters: " << paramString_ << "\n";
433 if (!labelString_.empty())
434 ofs << "#time\t" << labelString_ << "\n";
435 else
436 ofs << "#time\tcorrVal\n";
437
438 for (unsigned int i = 0; i < nTimeBins_; ++i) {
439 ofs << times_[i] - times_[0] << "\t" << histogram_[i] << "\n";
440 }
441
442 } else {
443 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
444 "TimeCorrFunc::writeCorrelate Error: fail to open %s\n",
445 outputFilename_.c_str());
446 painCave.isFatal = 1;
447 simError();
448 }
449
450 ofs.close();
451 }
452
453 // Template specialization of writeCorrelate for Vector3d
454 template<>
455 void TimeCorrFunc<Vector3d>::writeCorrelate() {
456 ofstream ofs(outputFilename_.c_str());
457
458 if (ofs.is_open()) {
459 Revision r;
460
461 ofs << "# " << getCorrFuncType() << "\n";
462 ofs << "# OpenMD " << r.getFullRevision() << "\n";
463 ofs << "# " << r.getBuildDate() << "\n";
464 ofs << "# selection script1: \"" << selectionScript1_;
465 ofs << "\"\tselection script2: \"" << selectionScript2_ << "\"\n";
466 if (!paramString_.empty())
467 ofs << "# parameters: " << paramString_ << "\n";
468 if (!labelString_.empty())
469 ofs << "#time\t" << labelString_ << "\n";
470 else
471 ofs << "#time\tcorrVal\n";
472
473 for (unsigned int i = 0; i < nTimeBins_; ++i) {
474 ofs << times_[i] - times_[0] << "\t";
475 for (int j = 0; j < 3; j++) {
476 ofs << histogram_[i](j) << '\t';
477 }
478 ofs << '\n';
479 }
480
481 } else {
482 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
483 "TimeCorrFunc::writeCorrelate Error: fail to open %s\n",
484 outputFilename_.c_str());
485 painCave.isFatal = 1;
486 simError();
487 }
488
489 ofs.close();
490 }
491
492 // Template specialization of writeCorrelate for Mat3x3d
493 template<>
494 void TimeCorrFunc<Mat3x3d>::writeCorrelate() {
495 ofstream ofs(outputFilename_.c_str());
496
497 if (ofs.is_open()) {
498 Revision r;
499
500 ofs << "# " << getCorrFuncType() << "\n";
501 ofs << "# OpenMD " << r.getFullRevision() << "\n";
502 ofs << "# " << r.getBuildDate() << "\n";
503 ofs << "# selection script1: \"" << selectionScript1_;
504 ofs << "\"\tselection script2: \"" << selectionScript2_ << "\"\n";
505 if (!paramString_.empty())
506 ofs << "# parameters: " << paramString_ << "\n";
507 if (!labelString_.empty())
508 ofs << "#time\t" << labelString_ << "\n";
509 else
510 ofs << "#time\tcorrVal\n";
511
512 for (unsigned int i = 0; i < nTimeBins_; ++i) {
513 ofs << times_[i] - times_[0] << "\t";
514 for (int j = 0; j < 3; j++) {
515 for (int k = 0; k < 3; k++) {
516 ofs << histogram_[i](j, k) << '\t';
517 }
518 }
519 ofs << '\n';
520 }
521
522 } else {
523 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
524 "TimeCorrFunc::writeCorrelate Error: fail to open %s\n",
525 outputFilename_.c_str());
526 painCave.isFatal = 1;
527 simError();
528 }
529
530 ofs.close();
531 }
532
533 // it is necessary to keep the constructor definitions here or the code wont
534 // be generated and linking issues will occur. Blame templating
535 template<typename T>
536 CrossCorrFunc<T>::CrossCorrFunc(SimInfo* info, const std::string& filename,
537 const std::string& sele1,
538 const std::string& sele2) :
539 TimeCorrFunc<T>(info, filename, sele1, sele2) {
540 this->autoCorrFunc_ = false;
541 }
542
543 template<typename T>
544 AutoCorrFunc<T>::AutoCorrFunc(SimInfo* info, const std::string& filename,
545 const std::string& sele1,
546 const std::string& sele2) :
547 TimeCorrFunc<T>(info, filename, sele1, sele2) {
548 this->autoCorrFunc_ = true;
549 }
550
551 template<typename T>
552 SystemACF<T>::SystemACF(SimInfo* info, const std::string& filename,
553 const std::string& sele1, const std::string& sele2) :
554 AutoCorrFunc<T>(info, filename, sele1, sele2) {
555 this->autoCorrFunc_ = true;
556 this->doSystemProperties_ = true;
557 this->doMolecularProperties_ = false;
558 this->doObjectProperties_ = false;
559 this->doBondProperties_ = false;
560 }
561
562 template<typename T>
563 SystemCCF<T>::SystemCCF(SimInfo* info, const std::string& filename,
564 const std::string& sele1, const std::string& sele2) :
565 CrossCorrFunc<T>(info, filename, sele1, sele2) {
566 this->autoCorrFunc_ = false;
567 this->doSystemProperties_ = true;
568 this->doMolecularProperties_ = false;
569 this->doObjectProperties_ = false;
570 this->doBondProperties_ = false;
571 }
572
573 template<typename T>
574 ObjectACF<T>::ObjectACF(SimInfo* info, const std::string& filename,
575 const std::string& sele1, const std::string& sele2) :
576 AutoCorrFunc<T>(info, filename, sele1, sele2) {
577 this->autoCorrFunc_ = true;
578 this->doSystemProperties_ = false;
579 this->doMolecularProperties_ = false;
580 this->doObjectProperties_ = true;
581 this->doBondProperties_ = false;
582 }
583
584 template<typename T>
585 ObjectCCF<T>::ObjectCCF(SimInfo* info, const std::string& filename,
586 const std::string& sele1, const std::string& sele2) :
587 CrossCorrFunc<T>(info, filename, sele1, sele2) {
588 this->autoCorrFunc_ = false;
589 this->doSystemProperties_ = false;
590 this->doMolecularProperties_ = false;
591 this->doObjectProperties_ = true;
592 this->doBondProperties_ = false;
593 }
594
595 template<typename T>
596 MoleculeACF<T>::MoleculeACF(SimInfo* info, const std::string& filename,
597 const std::string& sele1,
598 const std::string& sele2) :
599 AutoCorrFunc<T>(info, filename, sele1, sele2) {
600 this->autoCorrFunc_ = true;
601 this->doSystemProperties_ = false;
602 this->doMolecularProperties_ = true;
603 this->doObjectProperties_ = false;
604 this->doBondProperties_ = false;
605 }
606
607 template<typename T>
608 MoleculeCCF<T>::MoleculeCCF(SimInfo* info, const std::string& filename,
609 const std::string& sele1,
610 const std::string& sele2) :
611 CrossCorrFunc<T>(info, filename, sele1, sele2) {
612 this->autoCorrFunc_ = false;
613 this->doSystemProperties_ = false;
614 this->doMolecularProperties_ = true;
615 this->doObjectProperties_ = false;
616 this->doBondProperties_ = false;
617 }
618
619 template class AutoCorrFunc<RealType>;
620 template class TimeCorrFunc<RealType>;
621 template class CrossCorrFunc<RealType>;
622
623 template class AutoCorrFunc<Vector3d>;
624 template class TimeCorrFunc<Vector3d>;
625 template class CrossCorrFunc<Vector3d>;
626
627 template class AutoCorrFunc<Mat3x3d>;
628 template class TimeCorrFunc<Mat3x3d>;
629 template class CrossCorrFunc<Mat3x3d>;
630
631 template class TimeCorrFunc<DynamicVector<RealType>>;
632
633 template class AutoCorrFunc<Vector<RealType, 4>>;
634 template class TimeCorrFunc<Vector<RealType, 4>>;
635 template class CrossCorrFunc<Vector<RealType, 4>>;
636
637 template class SystemACF<RealType>;
638 template class SystemACF<Vector3d>;
639 template class SystemACF<Mat3x3d>;
640
641 template class SystemCCF<RealType>;
642 template class SystemCCF<Vector3d>;
643 template class SystemCCF<Mat3x3d>;
644
645 template class ObjectACF<RealType>;
646 template class ObjectACF<Vector3d>;
647 template class ObjectACF<Mat3x3d>;
648
649 template class ObjectCCF<RealType>;
650 template class ObjectCCF<Vector3d>;
651 template class ObjectCCF<Mat3x3d>;
652 template class ObjectCCF<int>;
653
654 template class MoleculeACF<RealType>;
655 template class MoleculeACF<Vector3d>;
656 template class MoleculeACF<Mat3x3d>;
657 template class MoleculeACF<Vector<RealType, 4>>;
658
659 template class MoleculeCCF<RealType>;
660 template class MoleculeCCF<Vector3d>;
661 template class MoleculeCCF<Mat3x3d>;
662} // namespace OpenMD
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
Definition SimInfo.hpp:96
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.