47#include "parallel/ForceMatrixDecomposition.hpp"
49#include "brains/PairList.hpp"
52#include "nonbonded/NonBondedInteraction.hpp"
57 ForceMatrixDecomposition::ForceMatrixDecomposition(
SimInfo* info,
62 cellOffsets_.push_back(Vector3i(-1, -1, -1));
63 cellOffsets_.push_back(Vector3i(0, -1, -1));
64 cellOffsets_.push_back(Vector3i(1, -1, -1));
65 cellOffsets_.push_back(Vector3i(-1, 0, -1));
66 cellOffsets_.push_back(Vector3i(0, 0, -1));
67 cellOffsets_.push_back(Vector3i(1, 0, -1));
68 cellOffsets_.push_back(Vector3i(-1, 1, -1));
69 cellOffsets_.push_back(Vector3i(0, 1, -1));
70 cellOffsets_.push_back(Vector3i(1, 1, -1));
71 cellOffsets_.push_back(Vector3i(-1, -1, 0));
72 cellOffsets_.push_back(Vector3i(0, -1, 0));
73 cellOffsets_.push_back(Vector3i(1, -1, 0));
74 cellOffsets_.push_back(Vector3i(-1, 0, 0));
75 cellOffsets_.push_back(Vector3i(0, 0, 0));
76 cellOffsets_.push_back(Vector3i(1, 0, 0));
77 cellOffsets_.push_back(Vector3i(-1, 1, 0));
78 cellOffsets_.push_back(Vector3i(0, 1, 0));
79 cellOffsets_.push_back(Vector3i(1, 1, 0));
80 cellOffsets_.push_back(Vector3i(-1, -1, 1));
81 cellOffsets_.push_back(Vector3i(0, -1, 1));
82 cellOffsets_.push_back(Vector3i(1, -1, 1));
83 cellOffsets_.push_back(Vector3i(-1, 0, 1));
84 cellOffsets_.push_back(Vector3i(0, 0, 1));
85 cellOffsets_.push_back(Vector3i(1, 0, 1));
86 cellOffsets_.push_back(Vector3i(-1, 1, 1));
87 cellOffsets_.push_back(Vector3i(0, 1, 1));
88 cellOffsets_.push_back(Vector3i(1, 1, 1));
91 ForceMatrixDecomposition::~ForceMatrixDecomposition() {
93 delete AtomPlanIntRow;
94 delete AtomPlanRealRow;
95 delete AtomPlanVectorRow;
96 delete AtomPlanMatrixRow;
97 delete AtomPlanPotRow;
98 delete AtomPlanIntColumn;
99 delete AtomPlanRealColumn;
100 delete AtomPlanVectorColumn;
101 delete AtomPlanMatrixColumn;
102 delete AtomPlanPotColumn;
104 delete cgPlanVectorRow;
105 delete cgPlanIntColumn;
106 delete cgPlanVectorColumn;
115 snap_ = sman_->getCurrentSnapshot();
116 atomStorageLayout_ = sman_->getAtomStorageLayout();
117 ff_ = info_->getForceField();
118 nLocal_ = snap_->getNumberOfAtoms();
120 nGroups_ = info_->getNLocalCutoffGroups();
122 idents = info_->getIdentArray();
123 regions = info_->getRegions();
124 AtomLocalToGlobal = info_->getGlobalAtomIndices();
125 cgLocalToGlobal = info_->getGlobalGroupIndices();
126 vector<int> globalGroupMembership = info_->getGlobalGroupMembership();
128 massFactors = info_->getMassFactors();
130 PairList* excludes = info_->getExcludedInteractions();
131 PairList* oneTwo = info_->getOneTwoInteractions();
132 PairList* oneThree = info_->getOneThreeInteractions();
133 PairList* oneFour = info_->getOneFourInteractions();
136 snap_->cgData.setStorageLayout(DataStorage::dslPosition |
137 DataStorage::dslVelocity);
139 snap_->cgData.setStorageLayout(DataStorage::dslPosition);
143 MPI_Comm row = rowComm.getComm();
144 MPI_Comm col = colComm.getComm();
146 AtomPlanIntRow =
new Plan<int>(row, nLocal_);
152 AtomPlanIntColumn =
new Plan<int>(col, nLocal_);
158 cgPlanIntRow =
new Plan<int>(row, nGroups_);
160 cgPlanIntColumn =
new Plan<int>(col, nGroups_);
163 nAtomsInRow_ = AtomPlanIntRow->getSize();
164 nAtomsInCol_ = AtomPlanIntColumn->getSize();
165 nGroupsInRow_ = cgPlanIntRow->getSize();
166 nGroupsInCol_ = cgPlanIntColumn->getSize();
169 atomRowData.resize(nAtomsInRow_);
170 atomRowData.setStorageLayout(atomStorageLayout_);
171 atomColData.resize(nAtomsInCol_);
172 atomColData.setStorageLayout(atomStorageLayout_);
173 cgRowData.resize(nGroupsInRow_);
174 cgRowData.setStorageLayout(DataStorage::dslPosition);
175 cgColData.resize(nGroupsInCol_);
178 cgColData.setStorageLayout(DataStorage::dslPosition |
179 DataStorage::dslVelocity);
181 cgColData.setStorageLayout(DataStorage::dslPosition);
183 identsRow.resize(nAtomsInRow_);
184 identsCol.resize(nAtomsInCol_);
186 AtomPlanIntRow->gather(idents, identsRow);
187 AtomPlanIntColumn->gather(idents, identsCol);
189 regionsRow.resize(nAtomsInRow_);
190 regionsCol.resize(nAtomsInCol_);
192 AtomPlanIntRow->gather(regions, regionsRow);
193 AtomPlanIntColumn->gather(regions, regionsCol);
196 atypesRow.resize(nAtomsInRow_);
197 atypesCol.resize(nAtomsInCol_);
199 for (
int i = 0; i < nAtomsInRow_; i++)
200 atypesRow[i] = ff_->getAtomType(identsRow[i]);
201 for (
int i = 0; i < nAtomsInCol_; i++)
202 atypesCol[i] = ff_->getAtomType(identsCol[i]);
204 pot_row.resize(nAtomsInRow_);
205 pot_col.resize(nAtomsInCol_);
207 expot_row.resize(nAtomsInRow_);
208 expot_col.resize(nAtomsInCol_);
210 selepot_row.resize(nAtomsInRow_);
211 selepot_col.resize(nAtomsInCol_);
213 AtomRowToGlobal.resize(nAtomsInRow_);
214 AtomColToGlobal.resize(nAtomsInCol_);
215 AtomPlanIntRow->gather(AtomLocalToGlobal, AtomRowToGlobal);
216 AtomPlanIntColumn->gather(AtomLocalToGlobal, AtomColToGlobal);
218 cgRowToGlobal.resize(nGroupsInRow_);
219 cgColToGlobal.resize(nGroupsInCol_);
220 cgPlanIntRow->gather(cgLocalToGlobal, cgRowToGlobal);
221 cgPlanIntColumn->gather(cgLocalToGlobal, cgColToGlobal);
223 massFactorsRow.resize(nAtomsInRow_);
224 massFactorsCol.resize(nAtomsInCol_);
225 AtomPlanRealRow->gather(massFactors, massFactorsRow);
226 AtomPlanRealColumn->gather(massFactors, massFactorsCol);
228 groupListRow_.clear();
229 groupListRow_.resize(nGroupsInRow_);
230 for (
int i = 0; i < nGroupsInRow_; i++) {
231 int gid = cgRowToGlobal[i];
232 for (
int j = 0; j < nAtomsInRow_; j++) {
233 int aid = AtomRowToGlobal[j];
234 if (globalGroupMembership[aid] == gid) groupListRow_[i].push_back(j);
238 groupListCol_.clear();
239 groupListCol_.resize(nGroupsInCol_);
240 for (
int i = 0; i < nGroupsInCol_; i++) {
241 int gid = cgColToGlobal[i];
242 for (
int j = 0; j < nAtomsInCol_; j++) {
243 int aid = AtomColToGlobal[j];
244 if (globalGroupMembership[aid] == gid) groupListCol_[i].push_back(j);
248 excludesForAtom.clear();
249 excludesForAtom.resize(nAtomsInRow_);
253 topoDist.resize(nAtomsInRow_);
254 for (
int i = 0; i < nAtomsInRow_; i++) {
255 int iglob = AtomRowToGlobal[i];
257 for (
int j = 0; j < nAtomsInCol_; j++) {
258 int jglob = AtomColToGlobal[j];
260 if (excludes->
hasPair(iglob, jglob)) excludesForAtom[i].push_back(j);
262 if (oneTwo->
hasPair(iglob, jglob)) {
264 topoDist[i].push_back(1);
266 if (oneThree->
hasPair(iglob, jglob)) {
268 topoDist[i].push_back(2);
270 if (oneFour->
hasPair(iglob, jglob)) {
272 topoDist[i].push_back(3);
280 excludesForAtom.clear();
281 excludesForAtom.resize(nLocal_);
285 topoDist.resize(nLocal_);
287 for (
int i = 0; i < nLocal_; i++) {
288 int iglob = AtomLocalToGlobal[i];
290 for (
int j = 0; j < nLocal_; j++) {
291 int jglob = AtomLocalToGlobal[j];
293 if (excludes->
hasPair(iglob, jglob)) excludesForAtom[i].push_back(j);
295 if (oneTwo->
hasPair(iglob, jglob)) {
297 topoDist[i].push_back(1);
299 if (oneThree->
hasPair(iglob, jglob)) {
301 topoDist[i].push_back(2);
303 if (oneFour->
hasPair(iglob, jglob)) {
305 topoDist[i].push_back(3);
314 atypesLocal.resize(nLocal_);
316 for (
int i = 0; i < nLocal_; i++)
317 atypesLocal[i] = ff_->getAtomType(idents[i]);
320 groupList_.resize(nGroups_);
321 for (
int i = 0; i < nGroups_; i++) {
322 int gid = cgLocalToGlobal[i];
323 for (
int j = 0; j < nLocal_; j++) {
324 int aid = AtomLocalToGlobal[j];
325 if (globalGroupMembership[aid] == gid) { groupList_[i].push_back(j); }
330 int ForceMatrixDecomposition::getTopologicalDistance(
int atom1,
int atom2) {
331 for (
unsigned int j = 0; j < toposForAtom[atom1].size(); j++) {
332 if (toposForAtom[atom1][j] == atom2)
return topoDist[atom1][j];
337 void ForceMatrixDecomposition::zeroWorkArrays() {
341 excludedSelfPot = 0.0;
343 selectedSelfPot = 0.0;
346 if (atomStorageLayout_ & DataStorage::dslForce) {
347 fill(atomRowData.force.begin(), atomRowData.force.end(), V3Zero);
348 fill(atomColData.force.begin(), atomColData.force.end(), V3Zero);
351 if (atomStorageLayout_ & DataStorage::dslTorque) {
352 fill(atomRowData.torque.begin(), atomRowData.torque.end(), V3Zero);
353 fill(atomColData.torque.begin(), atomColData.torque.end(), V3Zero);
356 fill(pot_row.begin(), pot_row.end(),
357 Vector<RealType, N_INTERACTION_FAMILIES>(0.0));
359 fill(pot_col.begin(), pot_col.end(),
360 Vector<RealType, N_INTERACTION_FAMILIES>(0.0));
362 fill(expot_row.begin(), expot_row.end(),
363 Vector<RealType, N_INTERACTION_FAMILIES>(0.0));
365 fill(expot_col.begin(), expot_col.end(),
366 Vector<RealType, N_INTERACTION_FAMILIES>(0.0));
368 fill(selepot_row.begin(), selepot_row.end(),
369 Vector<RealType, N_INTERACTION_FAMILIES>(0.0));
371 fill(selepot_col.begin(), selepot_col.end(),
372 Vector<RealType, N_INTERACTION_FAMILIES>(0.0));
374 if (atomStorageLayout_ & DataStorage::dslParticlePot) {
375 fill(atomRowData.particlePot.begin(), atomRowData.particlePot.end(), 0.0);
376 fill(atomColData.particlePot.begin(), atomColData.particlePot.end(), 0.0);
379 if (atomStorageLayout_ & DataStorage::dslDensity) {
380 fill(atomRowData.density.begin(), atomRowData.density.end(), 0.0);
381 fill(atomColData.density.begin(), atomColData.density.end(), 0.0);
384 if (atomStorageLayout_ & DataStorage::dslFunctional) {
385 fill(atomRowData.functional.begin(), atomRowData.functional.end(), 0.0);
386 fill(atomColData.functional.begin(), atomColData.functional.end(), 0.0);
389 if (atomStorageLayout_ & DataStorage::dslFunctionalDerivative) {
390 fill(atomRowData.functionalDerivative.begin(),
391 atomRowData.functionalDerivative.end(), 0.0);
392 fill(atomColData.functionalDerivative.begin(),
393 atomColData.functionalDerivative.end(), 0.0);
396 if (atomStorageLayout_ & DataStorage::dslSkippedCharge) {
397 fill(atomRowData.skippedCharge.begin(), atomRowData.skippedCharge.end(),
399 fill(atomColData.skippedCharge.begin(), atomColData.skippedCharge.end(),
403 if (atomStorageLayout_ & DataStorage::dslFlucQForce) {
404 fill(atomRowData.flucQFrc.begin(), atomRowData.flucQFrc.end(), 0.0);
405 fill(atomColData.flucQFrc.begin(), atomColData.flucQFrc.end(), 0.0);
408 if (atomStorageLayout_ & DataStorage::dslElectricField) {
409 fill(atomRowData.electricField.begin(), atomRowData.electricField.end(),
411 fill(atomColData.electricField.begin(), atomColData.electricField.end(),
415 if (atomStorageLayout_ & DataStorage::dslSitePotential) {
416 fill(atomRowData.sitePotential.begin(), atomRowData.sitePotential.end(),
418 fill(atomColData.sitePotential.begin(), atomColData.sitePotential.end(),
425 if (atomStorageLayout_ & DataStorage::dslParticlePot) {
426 fill(snap_->atomData.particlePot.begin(),
427 snap_->atomData.particlePot.end(), 0.0);
430 if (atomStorageLayout_ & DataStorage::dslDensity) {
431 fill(snap_->atomData.density.begin(), snap_->atomData.density.end(), 0.0);
434 if (atomStorageLayout_ & DataStorage::dslFunctional) {
435 fill(snap_->atomData.functional.begin(), snap_->atomData.functional.end(),
439 if (atomStorageLayout_ & DataStorage::dslFunctionalDerivative) {
440 fill(snap_->atomData.functionalDerivative.begin(),
441 snap_->atomData.functionalDerivative.end(), 0.0);
444 if (atomStorageLayout_ & DataStorage::dslSkippedCharge) {
445 fill(snap_->atomData.skippedCharge.begin(),
446 snap_->atomData.skippedCharge.end(), 0.0);
449 if (atomStorageLayout_ & DataStorage::dslElectricField) {
450 fill(snap_->atomData.electricField.begin(),
451 snap_->atomData.electricField.end(), V3Zero);
453 if (atomStorageLayout_ & DataStorage::dslSitePotential) {
454 fill(snap_->atomData.sitePotential.begin(),
455 snap_->atomData.sitePotential.end(), 0.0);
459 void ForceMatrixDecomposition::distributeData() {
462 snap_ = sman_->getCurrentSnapshot();
463 atomStorageLayout_ = sman_->getAtomStorageLayout();
466 if (info_->getNCutoffGroups() != info_->getNAtoms()) needsCG =
false;
469 AtomPlanVectorRow->gather(snap_->atomData.position, atomRowData.position);
470 AtomPlanVectorColumn->gather(snap_->atomData.position,
471 atomColData.position);
476 cgPlanVectorRow->gather(snap_->cgData.position, cgRowData.position);
478 cgPlanVectorColumn->gather(snap_->cgData.position, cgColData.position);
481 if (needVelocities_) {
483 AtomPlanVectorColumn->gather(snap_->atomData.velocity,
484 atomColData.velocity);
487 cgPlanVectorColumn->gather(snap_->cgData.velocity, cgColData.velocity);
492 if (atomStorageLayout_ & DataStorage::dslAmat) {
493 AtomPlanMatrixRow->gather(snap_->atomData.aMat, atomRowData.aMat);
494 AtomPlanMatrixColumn->gather(snap_->atomData.aMat, atomColData.aMat);
498 if (atomStorageLayout_ & DataStorage::dslDipole) {
499 AtomPlanVectorRow->gather(snap_->atomData.dipole, atomRowData.dipole);
500 AtomPlanVectorColumn->gather(snap_->atomData.dipole, atomColData.dipole);
503 if (atomStorageLayout_ & DataStorage::dslQuadrupole) {
504 AtomPlanMatrixRow->gather(snap_->atomData.quadrupole,
505 atomRowData.quadrupole);
506 AtomPlanMatrixColumn->gather(snap_->atomData.quadrupole,
507 atomColData.quadrupole);
511 if (atomStorageLayout_ & DataStorage::dslFlucQPosition) {
512 AtomPlanRealRow->gather(snap_->atomData.flucQPos, atomRowData.flucQPos);
513 AtomPlanRealColumn->gather(snap_->atomData.flucQPos,
514 atomColData.flucQPos);
523 void ForceMatrixDecomposition::collectIntermediateData() {
526 snap_ = sman_->getCurrentSnapshot();
527 atomStorageLayout_ = sman_->getAtomStorageLayout();
529 if (atomStorageLayout_ & DataStorage::dslDensity) {
530 AtomPlanRealRow->scatter(atomRowData.density, snap_->atomData.density);
532 int n = snap_->atomData.density.size();
533 vector<RealType> rho_tmp(n, 0.0);
534 AtomPlanRealColumn->scatter(atomColData.density, rho_tmp);
535 for (
int i = 0; i < n; i++)
536 snap_->atomData.density[i] += rho_tmp[i];
541 if (atomStorageLayout_ & DataStorage::dslElectricField) {
542 AtomPlanVectorRow->scatter(atomRowData.electricField,
543 snap_->atomData.electricField);
545 int n = snap_->atomData.electricField.size();
546 vector<Vector3d> field_tmp(n, V3Zero);
547 AtomPlanVectorColumn->scatter(atomColData.electricField, field_tmp);
548 for (
int i = 0; i < n; i++)
549 snap_->atomData.electricField[i] += field_tmp[i];
558 void ForceMatrixDecomposition::distributeIntermediateData() {
560 snap_ = sman_->getCurrentSnapshot();
561 atomStorageLayout_ = sman_->getAtomStorageLayout();
563 if (atomStorageLayout_ & DataStorage::dslFunctional) {
564 AtomPlanRealRow->gather(snap_->atomData.functional,
565 atomRowData.functional);
566 AtomPlanRealColumn->gather(snap_->atomData.functional,
567 atomColData.functional);
570 if (atomStorageLayout_ & DataStorage::dslFunctionalDerivative) {
571 AtomPlanRealRow->gather(snap_->atomData.functionalDerivative,
572 atomRowData.functionalDerivative);
573 AtomPlanRealColumn->gather(snap_->atomData.functionalDerivative,
574 atomColData.functionalDerivative);
579 void ForceMatrixDecomposition::collectData() {
581 snap_ = sman_->getCurrentSnapshot();
582 atomStorageLayout_ = sman_->getAtomStorageLayout();
584 int n = snap_->atomData.force.size();
585 vector<Vector3d> frc_tmp(n, V3Zero);
587 AtomPlanVectorRow->scatter(atomRowData.force, frc_tmp);
588 for (
int i = 0; i < n; i++) {
589 snap_->atomData.force[i] += frc_tmp[i];
593 AtomPlanVectorColumn->scatter(atomColData.force, frc_tmp);
594 for (
int i = 0; i < n; i++) {
595 snap_->atomData.force[i] += frc_tmp[i];
598 if (atomStorageLayout_ & DataStorage::dslTorque) {
599 int nt = snap_->atomData.torque.size();
600 vector<Vector3d> trq_tmp(nt, V3Zero);
602 AtomPlanVectorRow->scatter(atomRowData.torque, trq_tmp);
603 for (
int i = 0; i < nt; i++) {
604 snap_->atomData.torque[i] += trq_tmp[i];
608 AtomPlanVectorColumn->scatter(atomColData.torque, trq_tmp);
609 for (
int i = 0; i < nt; i++)
610 snap_->atomData.torque[i] += trq_tmp[i];
613 if (atomStorageLayout_ & DataStorage::dslSkippedCharge) {
614 int ns = snap_->atomData.skippedCharge.size();
615 vector<RealType> skch_tmp(ns, 0.0);
617 AtomPlanRealRow->scatter(atomRowData.skippedCharge, skch_tmp);
618 for (
int i = 0; i < ns; i++) {
619 snap_->atomData.skippedCharge[i] += skch_tmp[i];
623 AtomPlanRealColumn->scatter(atomColData.skippedCharge, skch_tmp);
624 for (
int i = 0; i < ns; i++)
625 snap_->atomData.skippedCharge[i] += skch_tmp[i];
628 if (atomStorageLayout_ & DataStorage::dslFlucQForce) {
629 int nq = snap_->atomData.flucQFrc.size();
630 vector<RealType> fqfrc_tmp(nq, 0.0);
632 AtomPlanRealRow->scatter(atomRowData.flucQFrc, fqfrc_tmp);
633 for (
int i = 0; i < nq; i++) {
634 snap_->atomData.flucQFrc[i] += fqfrc_tmp[i];
638 AtomPlanRealColumn->scatter(atomColData.flucQFrc, fqfrc_tmp);
639 for (
int i = 0; i < nq; i++)
640 snap_->atomData.flucQFrc[i] += fqfrc_tmp[i];
643 if (atomStorageLayout_ & DataStorage::dslElectricField) {
644 int nef = snap_->atomData.electricField.size();
645 vector<Vector3d> efield_tmp(nef, V3Zero);
647 AtomPlanVectorRow->scatter(atomRowData.electricField, efield_tmp);
648 for (
int i = 0; i < nef; i++) {
649 snap_->atomData.electricField[i] += efield_tmp[i];
653 AtomPlanVectorColumn->scatter(atomColData.electricField, efield_tmp);
654 for (
int i = 0; i < nef; i++)
655 snap_->atomData.electricField[i] += efield_tmp[i];
658 if (atomStorageLayout_ & DataStorage::dslSitePotential) {
659 int nsp = snap_->atomData.sitePotential.size();
660 vector<RealType> sp_tmp(nsp, 0.0);
662 AtomPlanRealRow->scatter(atomRowData.sitePotential, sp_tmp);
663 for (
int i = 0; i < nsp; i++) {
664 snap_->atomData.sitePotential[i] += sp_tmp[i];
668 AtomPlanRealColumn->scatter(atomColData.sitePotential, sp_tmp);
669 for (
int i = 0; i < nsp; i++)
670 snap_->atomData.sitePotential[i] += sp_tmp[i];
673 nLocal_ = snap_->getNumberOfAtoms();
675 vector<potVec> pot_temp(nLocal_,
676 Vector<RealType, N_INTERACTION_FAMILIES>(0.0));
677 vector<potVec> expot_temp(nLocal_,
678 Vector<RealType, N_INTERACTION_FAMILIES>(0.0));
679 vector<potVec> selepot_temp(nLocal_,
680 Vector<RealType, N_INTERACTION_FAMILIES>(0.0));
684 AtomPlanPotRow->scatter(pot_row, pot_temp);
685 AtomPlanPotRow->scatter(expot_row, expot_temp);
686 AtomPlanPotRow->scatter(selepot_row, selepot_temp);
688 for (std::size_t ii = 0; ii < pot_temp.size(); ii++)
689 pairwisePot += pot_temp[ii];
691 for (std::size_t ii = 0; ii < expot_temp.size(); ii++)
692 excludedPot += expot_temp[ii];
694 for (std::size_t ii = 0; ii < selepot_temp.size(); ii++)
695 selectedPot += selepot_temp[ii];
697 if (atomStorageLayout_ & DataStorage::dslParticlePot) {
702 for (
int ii = 0; ii < N_INTERACTION_FAMILIES; ii++) {
703 for (
int i = 0; i < nLocal_; i++) {
706 snap_->atomData.particlePot[i] += 2.0 * pot_temp[i](ii);
711 fill(pot_temp.begin(), pot_temp.end(),
712 Vector<RealType, N_INTERACTION_FAMILIES>(0.0));
713 fill(expot_temp.begin(), expot_temp.end(),
714 Vector<RealType, N_INTERACTION_FAMILIES>(0.0));
715 fill(selepot_temp.begin(), selepot_temp.end(),
716 Vector<RealType, N_INTERACTION_FAMILIES>(0.0));
718 AtomPlanPotColumn->scatter(pot_col, pot_temp);
719 AtomPlanPotColumn->scatter(expot_col, expot_temp);
720 AtomPlanPotColumn->scatter(selepot_col, selepot_temp);
722 for (std::size_t ii = 0; ii < pot_temp.size(); ii++)
723 pairwisePot += pot_temp[ii];
725 for (std::size_t ii = 0; ii < expot_temp.size(); ii++)
726 excludedPot += expot_temp[ii];
728 for (std::size_t ii = 0; ii < selepot_temp.size(); ii++)
729 selectedPot += selepot_temp[ii];
731 if (atomStorageLayout_ & DataStorage::dslParticlePot) {
736 for (
int ii = 0; ii < N_INTERACTION_FAMILIES; ii++) {
737 for (
int i = 0; i < nLocal_; i++) {
740 snap_->atomData.particlePot[i] += 2.0 * pot_temp[i](ii);
745 if (atomStorageLayout_ & DataStorage::dslParticlePot) {
746 int npp = snap_->atomData.particlePot.size();
747 vector<RealType> ppot_temp(npp, 0.0);
752 AtomPlanRealRow->scatter(atomRowData.particlePot, ppot_temp);
753 for (
int i = 0; i < npp; i++) {
754 snap_->atomData.particlePot[i] += ppot_temp[i];
757 fill(ppot_temp.begin(), ppot_temp.end(), 0.0);
759 AtomPlanRealColumn->scatter(atomColData.particlePot, ppot_temp);
760 for (
int i = 0; i < npp; i++) {
761 snap_->atomData.particlePot[i] += ppot_temp[i];
765 MPI_Allreduce(MPI_IN_PLACE, &pairwisePot[0], N_INTERACTION_FAMILIES,
766 MPI_REALTYPE, MPI_SUM, MPI_COMM_WORLD);
768 MPI_Allreduce(MPI_IN_PLACE, &excludedPot[0], N_INTERACTION_FAMILIES,
769 MPI_REALTYPE, MPI_SUM, MPI_COMM_WORLD);
771 MPI_Allreduce(MPI_IN_PLACE, &selectedPot[0], N_INTERACTION_FAMILIES,
772 MPI_REALTYPE, MPI_SUM, MPI_COMM_WORLD);
775 MPI_Comm col = colComm.getComm();
777 MPI_Allreduce(MPI_IN_PLACE, &snap_->frameData.conductiveHeatFlux[0], 3,
778 MPI_REALTYPE, MPI_SUM, col);
788 MPI_Allreduce(MPI_IN_PLACE, &selfPot[0], N_INTERACTION_FAMILIES,
789 MPI_REALTYPE, MPI_SUM, MPI_COMM_WORLD);
791 MPI_Allreduce(MPI_IN_PLACE, &excludedSelfPot[0], N_INTERACTION_FAMILIES,
792 MPI_REALTYPE, MPI_SUM, MPI_COMM_WORLD);
794 MPI_Allreduce(MPI_IN_PLACE, &selectedSelfPot[0], N_INTERACTION_FAMILIES,
795 MPI_REALTYPE, MPI_SUM, MPI_COMM_WORLD);
799 int& ForceMatrixDecomposition::getNAtomsInRow() {
812 return groupListRow_[cg1];
814 return groupList_[cg1];
818 vector<int>& ForceMatrixDecomposition::getAtomsInGroupColumn(
int cg2) {
820 return groupListCol_[cg2];
822 return groupList_[cg2];
826 Vector3d ForceMatrixDecomposition::getIntergroupVector(
int cg1,
int cg2) {
829 d = cgColData.position[cg2] - cgRowData.position[cg1];
831 d = snap_->cgData.position[cg2] - snap_->cgData.position[cg1];
834 if (usePeriodicBoundaryConditions_) { snap_->wrapVector(d); }
838 Vector3d& ForceMatrixDecomposition::getGroupVelocityColumn(
int cg2) {
840 return cgColData.velocity[cg2];
842 return snap_->cgData.velocity[cg2];
846 Vector3d& ForceMatrixDecomposition::getAtomVelocityColumn(
int atom2) {
848 return atomColData.velocity[atom2];
850 return snap_->atomData.velocity[atom2];
854 Vector3d ForceMatrixDecomposition::getAtomToGroupVectorRow(
int atom1,
859 d = cgRowData.position[cg1] - atomRowData.position[atom1];
861 d = snap_->cgData.position[cg1] - snap_->atomData.position[atom1];
863 if (usePeriodicBoundaryConditions_) { snap_->wrapVector(d); }
867 Vector3d ForceMatrixDecomposition::getAtomToGroupVectorColumn(
int atom2,
872 d = cgColData.position[cg2] - atomColData.position[atom2];
874 d = snap_->cgData.position[cg2] - snap_->atomData.position[atom2];
876 if (usePeriodicBoundaryConditions_) { snap_->wrapVector(d); }
880 RealType& ForceMatrixDecomposition::getMassFactorRow(
int atom1) {
882 return massFactorsRow[atom1];
884 return massFactors[atom1];
888 RealType& ForceMatrixDecomposition::getMassFactorColumn(
int atom2) {
890 return massFactorsCol[atom2];
892 return massFactors[atom2];
896 Vector3d ForceMatrixDecomposition::getInteratomicVector(
int atom1,
901 d = atomColData.position[atom2] - atomRowData.position[atom1];
903 d = snap_->atomData.position[atom2] - snap_->atomData.position[atom1];
905 if (usePeriodicBoundaryConditions_) { snap_->wrapVector(d); }
909 vector<int>& ForceMatrixDecomposition::getExcludesForAtom(
int atom1) {
910 return excludesForAtom[atom1];
920 int unique_id_1 = AtomRowToGlobal[atom1];
921 int unique_id_2 = AtomColToGlobal[atom2];
923 if (unique_id_1 == unique_id_2)
return true;
926 if (unique_id_1 < unique_id_2) {
927 if ((unique_id_1 + unique_id_2) % 2 == 0)
return true;
929 if ((unique_id_1 + unique_id_2) % 2 == 1)
return true;
938 int unique_id_1 = AtomLocalToGlobal[atom1];
939 int unique_id_2 = AtomLocalToGlobal[atom2];
940 int group1 = cgLocalToGlobal[cg1];
941 int group2 = cgLocalToGlobal[cg2];
943 if (unique_id_1 == unique_id_2)
return true;
945 if (group1 == group2) {
946 if (unique_id_1 < unique_id_2)
return true;
966 for (vector<int>::iterator i = excludesForAtom[atom1].begin();
967 i != excludesForAtom[atom1].end(); ++i) {
968 if ((*i) == atom2)
return true;
974 void ForceMatrixDecomposition::addForceToAtomRow(
int atom1, Vector3d fg) {
976 atomRowData.force[atom1] += fg;
978 snap_->atomData.force[atom1] += fg;
982 void ForceMatrixDecomposition::addForceToAtomColumn(
int atom2, Vector3d fg) {
984 atomColData.force[atom2] += fg;
986 snap_->atomData.force[atom2] += fg;
991 void ForceMatrixDecomposition::fillInteractionData(InteractionData& idat,
992 int atom1,
int atom2,
994 idat.excluded = excludeAtomPair(atom1, atom2);
998 idat.atid1 = identsRow[atom1];
999 idat.atid2 = identsCol[atom2];
1001 if (regionsRow[atom1] >= 0 && regionsCol[atom2] >= 0) {
1002 idat.sameRegion = (regionsRow[atom1] == regionsCol[atom2]);
1004 idat.sameRegion =
false;
1007 if (atomStorageLayout_ & DataStorage::dslAmat) {
1008 idat.A1 = atomRowData.aMat[atom1];
1009 idat.A2 = atomColData.aMat[atom2];
1012 if (atomStorageLayout_ & DataStorage::dslTorque) {
1013 idat.t1 = atomRowData.torque[atom1];
1014 idat.t2 = atomColData.torque[atom2];
1017 if (atomStorageLayout_ & DataStorage::dslDipole) {
1018 idat.D_1 = atomRowData.dipole[atom1];
1019 idat.D_2 = atomColData.dipole[atom2];
1022 if (atomStorageLayout_ & DataStorage::dslQuadrupole) {
1023 idat.Q_1 = atomRowData.quadrupole[atom1];
1024 idat.Q_2 = atomColData.quadrupole[atom2];
1027 if (atomStorageLayout_ & DataStorage::dslDensity) {
1028 idat.rho1 = atomRowData.density[atom1];
1029 idat.rho2 = atomColData.density[atom2];
1032 if (atomStorageLayout_ & DataStorage::dslFunctional) {
1033 idat.frho1 = atomRowData.functional[atom1];
1034 idat.frho2 = atomColData.functional[atom2];
1037 if (atomStorageLayout_ & DataStorage::dslFunctionalDerivative) {
1038 idat.dfrho1 = atomRowData.functionalDerivative[atom1];
1039 idat.dfrho2 = atomColData.functionalDerivative[atom2];
1042 if (atomStorageLayout_ & DataStorage::dslParticlePot) {
1043 idat.particlePot1 = atomRowData.particlePot[atom1];
1044 idat.particlePot2 = atomColData.particlePot[atom2];
1047 if (atomStorageLayout_ & DataStorage::dslSkippedCharge) {
1048 idat.skippedCharge1 = atomRowData.skippedCharge[atom1];
1049 idat.skippedCharge2 = atomColData.skippedCharge[atom2];
1052 if (atomStorageLayout_ & DataStorage::dslFlucQPosition) {
1053 idat.flucQ1 = atomRowData.flucQPos[atom1];
1054 idat.flucQ2 = atomColData.flucQPos[atom2];
1059 idat.atid1 = idents[atom1];
1060 idat.atid2 = idents[atom2];
1062 if (regions[atom1] >= 0 && regions[atom2] >= 0) {
1063 idat.sameRegion = (regions[atom1] == regions[atom2]);
1065 idat.sameRegion =
false;
1068 if (atomStorageLayout_ & DataStorage::dslAmat) {
1069 idat.A1 = snap_->atomData.aMat[atom1];
1070 idat.A2 = snap_->atomData.aMat[atom2];
1073 if (atomStorageLayout_ & DataStorage::dslTorque) {
1074 idat.t1 = snap_->atomData.torque[atom1];
1075 idat.t2 = snap_->atomData.torque[atom2];
1078 if (atomStorageLayout_ & DataStorage::dslDipole) {
1079 idat.D_1 = snap_->atomData.dipole[atom1];
1080 idat.D_2 = snap_->atomData.dipole[atom2];
1083 if (atomStorageLayout_ & DataStorage::dslQuadrupole) {
1084 idat.Q_1 = snap_->atomData.quadrupole[atom1];
1085 idat.Q_2 = snap_->atomData.quadrupole[atom2];
1088 if (atomStorageLayout_ & DataStorage::dslDensity) {
1089 idat.rho1 = snap_->atomData.density[atom1];
1090 idat.rho2 = snap_->atomData.density[atom2];
1093 if (atomStorageLayout_ & DataStorage::dslFunctional) {
1094 idat.frho1 = snap_->atomData.functional[atom1];
1095 idat.frho2 = snap_->atomData.functional[atom2];
1098 if (atomStorageLayout_ & DataStorage::dslFunctionalDerivative) {
1099 idat.dfrho1 = snap_->atomData.functionalDerivative[atom1];
1100 idat.dfrho2 = snap_->atomData.functionalDerivative[atom2];
1103 if (atomStorageLayout_ & DataStorage::dslParticlePot) {
1104 idat.particlePot1 = snap_->atomData.particlePot[atom1];
1105 idat.particlePot2 = snap_->atomData.particlePot[atom2];
1108 if (atomStorageLayout_ & DataStorage::dslSkippedCharge) {
1109 idat.skippedCharge1 = snap_->atomData.skippedCharge[atom1];
1110 idat.skippedCharge2 = snap_->atomData.skippedCharge[atom2];
1113 if (atomStorageLayout_ & DataStorage::dslFlucQPosition) {
1114 idat.flucQ1 = snap_->atomData.flucQPos[atom1];
1115 idat.flucQ2 = snap_->atomData.flucQPos[atom2];
1122 idat.atid2 = identsCol[atom2];
1124 if (regionsRow[atom1] >= 0 && regionsCol[atom2] >= 0) {
1125 idat.sameRegion = (regionsRow[atom1] == regionsCol[atom2]);
1127 idat.sameRegion =
false;
1130 if (atomStorageLayout_ & DataStorage::dslAmat) {
1131 idat.A2 = atomColData.aMat[atom2];
1134 if (atomStorageLayout_ & DataStorage::dslTorque) {
1135 idat.t2 = atomColData.torque[atom2];
1138 if (atomStorageLayout_ & DataStorage::dslDipole) {
1139 idat.D_2 = atomColData.dipole[atom2];
1142 if (atomStorageLayout_ & DataStorage::dslQuadrupole) {
1143 idat.Q_2 = atomColData.quadrupole[atom2];
1146 if (atomStorageLayout_ & DataStorage::dslDensity) {
1147 idat.rho2 = atomColData.density[atom2];
1150 if (atomStorageLayout_ & DataStorage::dslFunctional) {
1151 idat.frho2 = atomColData.functional[atom2];
1154 if (atomStorageLayout_ & DataStorage::dslFunctionalDerivative) {
1155 idat.dfrho2 = atomColData.functionalDerivative[atom2];
1158 if (atomStorageLayout_ & DataStorage::dslParticlePot) {
1159 idat.particlePot2 = atomColData.particlePot[atom2];
1162 if (atomStorageLayout_ & DataStorage::dslSkippedCharge) {
1163 idat.skippedCharge2 = atomColData.skippedCharge[atom2];
1166 if (atomStorageLayout_ & DataStorage::dslFlucQPosition) {
1167 idat.flucQ2 = atomColData.flucQPos[atom2];
1171 idat.atid2 = idents[atom2];
1173 if (regions[atom1] >= 0 && regions[atom2] >= 0) {
1174 idat.sameRegion = (regions[atom1] == regions[atom2]);
1176 idat.sameRegion =
false;
1179 if (atomStorageLayout_ & DataStorage::dslAmat) {
1180 idat.A2 = snap_->atomData.aMat[atom2];
1183 if (atomStorageLayout_ & DataStorage::dslTorque) {
1184 idat.t2 = snap_->atomData.torque[atom2];
1187 if (atomStorageLayout_ & DataStorage::dslDipole) {
1188 idat.D_2 = snap_->atomData.dipole[atom2];
1191 if (atomStorageLayout_ & DataStorage::dslQuadrupole) {
1192 idat.Q_2 = snap_->atomData.quadrupole[atom2];
1195 if (atomStorageLayout_ & DataStorage::dslDensity) {
1196 idat.rho2 = snap_->atomData.density[atom2];
1199 if (atomStorageLayout_ & DataStorage::dslFunctional) {
1200 idat.frho2 = snap_->atomData.functional[atom2];
1203 if (atomStorageLayout_ & DataStorage::dslFunctionalDerivative) {
1204 idat.dfrho2 = snap_->atomData.functionalDerivative[atom2];
1207 if (atomStorageLayout_ & DataStorage::dslParticlePot) {
1208 idat.particlePot2 = snap_->atomData.particlePot[atom2];
1211 if (atomStorageLayout_ & DataStorage::dslSkippedCharge) {
1212 idat.skippedCharge2 = snap_->atomData.skippedCharge[atom2];
1215 if (atomStorageLayout_ & DataStorage::dslFlucQPosition) {
1216 idat.flucQ2 = snap_->atomData.flucQPos[atom2];
1223 void ForceMatrixDecomposition::unpackInteractionData(InteractionData& idat,
1224 int atom1,
int atom2) {
1226 pot_row[atom1] += 0.5 * idat.pot;
1227 pot_col[atom2] += 0.5 * idat.pot;
1228 expot_row[atom1] += 0.5 * idat.excludedPot;
1229 expot_col[atom2] += 0.5 * idat.excludedPot;
1230 selepot_row[atom1] += 0.5 * idat.selePot;
1231 selepot_col[atom2] += 0.5 * idat.selePot;
1233 atomRowData.force[atom1] += idat.f1;
1234 atomColData.force[atom2] -= idat.f1;
1236 if (atomStorageLayout_ & DataStorage::dslFlucQForce) {
1237 atomRowData.flucQFrc[atom1] -= idat.dVdFQ1;
1238 atomColData.flucQFrc[atom2] -= idat.dVdFQ2;
1241 if (atomStorageLayout_ & DataStorage::dslElectricField) {
1242 atomRowData.electricField[atom1] += idat.eField1;
1243 atomColData.electricField[atom2] += idat.eField2;
1246 if (atomStorageLayout_ & DataStorage::dslSitePotential) {
1247 atomRowData.sitePotential[atom1] += idat.sPot1;
1248 atomColData.sitePotential[atom2] += idat.sPot2;
1251 if (atomStorageLayout_ & DataStorage::dslTorque) {
1252 atomRowData.torque[atom1] = idat.t1;
1253 atomColData.torque[atom2] = idat.t2;
1256 if (atomStorageLayout_ & DataStorage::dslSkippedCharge) {
1257 atomRowData.skippedCharge[atom1] = idat.skippedCharge1;
1258 atomColData.skippedCharge[atom2] = idat.skippedCharge2;
1262 pairwisePot += idat.pot;
1263 excludedPot += idat.excludedPot;
1264 selectedPot += idat.selePot;
1266 snap_->atomData.force[atom1] += idat.f1;
1267 snap_->atomData.force[atom2] -= idat.f1;
1269 if (idat.doParticlePot) {
1274 snap_->atomData.particlePot[atom1] += idat.vpair * idat.sw;
1275 snap_->atomData.particlePot[atom2] += idat.vpair * idat.sw;
1278 if (atomStorageLayout_ & DataStorage::dslFlucQForce) {
1279 snap_->atomData.flucQFrc[atom1] -= idat.dVdFQ1;
1280 snap_->atomData.flucQFrc[atom2] -= idat.dVdFQ2;
1283 if (atomStorageLayout_ & DataStorage::dslElectricField) {
1284 snap_->atomData.electricField[atom1] += idat.eField1;
1285 snap_->atomData.electricField[atom2] += idat.eField2;
1288 if (atomStorageLayout_ & DataStorage::dslSitePotential) {
1289 snap_->atomData.sitePotential[atom1] += idat.sPot1;
1290 snap_->atomData.sitePotential[atom2] += idat.sPot2;
1293 if (atomStorageLayout_ & DataStorage::dslTorque) {
1294 snap_->atomData.torque[atom1] = idat.t1;
1295 snap_->atomData.torque[atom2] = idat.t2;
1298 if (atomStorageLayout_ & DataStorage::dslSkippedCharge) {
1299 snap_->atomData.skippedCharge[atom1] = idat.skippedCharge1;
1300 snap_->atomData.skippedCharge[atom2] = idat.skippedCharge2;
1305 void ForceMatrixDecomposition::unpackPrePairData(InteractionData& idat,
1306 int atom1,
int atom2) {
1309 if (atomStorageLayout_ & DataStorage::dslDensity) {
1310 atomRowData.density[atom1] = idat.rho1;
1311 atomColData.density[atom2] = idat.rho2;
1316 if (atomStorageLayout_ & DataStorage::dslDensity) {
1317 snap_->atomData.density[atom1] = idat.rho1;
1318 snap_->atomData.density[atom2] = idat.rho2;
1336 void ForceMatrixDecomposition::buildNeighborList(
1337 vector<int>& neighborList, vector<int>& point,
1338 vector<Vector3d>& savedPositions) {
1339 neighborList.clear();
1343 bool doAllPairs =
false;
1345 Snapshot* snap_ = sman_->getCurrentSnapshot();
1349 Vector3d rs, scaled, dr;
1354 cellListRow_.clear();
1355 cellListCol_.clear();
1356 point.resize(nGroupsInRow_ + 1);
1359 point.resize(nGroups_ + 1);
1362 if (!usePeriodicBoundaryConditions_) {
1363 box = snap_->getBoundingBox();
1364 invBox = snap_->getInvBoundingBox();
1366 box = snap_->getHmat();
1367 invBox = snap_->getInvHmat();
1370 Vector3d A = box.getColumn(0);
1371 Vector3d B = box.getColumn(1);
1372 Vector3d C = box.getColumn(2);
1375 Vector3d AxB =
cross(A, B);
1376 Vector3d BxC =
cross(B, C);
1377 Vector3d CxA =
cross(C, A);
1385 RealType Wa = abs(
dot(A, BxC));
1386 RealType Wb = abs(
dot(B, CxA));
1387 RealType Wc = abs(
dot(C, AxB));
1389 nCells_.x() = int(Wa / rList_);
1390 nCells_.y() = int(Wb / rList_);
1391 nCells_.z() = int(Wc / rList_);
1394 if (nCells_.x() < 3) doAllPairs =
true;
1395 if (nCells_.y() < 3) doAllPairs =
true;
1396 if (nCells_.z() < 3) doAllPairs =
true;
1398 int nCtot = nCells_.x() * nCells_.y() * nCells_.z();
1401 cellListRow_.resize(nCtot);
1402 cellListCol_.resize(nCtot);
1404 cellList_.resize(nCtot);
1410 for (
int i = 0; i < nGroupsInRow_; i++) {
1411 rs = cgRowData.position[i];
1414 scaled = invBox * rs;
1418 for (
int j = 0; j < 3; j++) {
1419 scaled[j] -= roundMe(scaled[j]);
1424 if (scaled[j] >= 1.0) scaled[j] -= 1.0;
1428 whichCell.x() = int(nCells_.x() * scaled.x());
1429 whichCell.y() = int(nCells_.y() * scaled.y());
1430 whichCell.z() = int(nCells_.z() * scaled.z());
1433 cellIndex =
Vlinear(whichCell, nCells_);
1436 cellListRow_[cellIndex].push_back(i);
1438 for (
int i = 0; i < nGroupsInCol_; i++) {
1439 rs = cgColData.position[i];
1442 scaled = invBox * rs;
1446 for (
int j = 0; j < 3; j++) {
1447 scaled[j] -= roundMe(scaled[j]);
1452 if (scaled[j] >= 1.0) scaled[j] -= 1.0;
1456 whichCell.x() = int(nCells_.x() * scaled.x());
1457 whichCell.y() = int(nCells_.y() * scaled.y());
1458 whichCell.z() = int(nCells_.z() * scaled.z());
1461 cellIndex =
Vlinear(whichCell, nCells_);
1464 cellListCol_[cellIndex].push_back(i);
1468 for (
int i = 0; i < nGroups_; i++) {
1469 rs = snap_->cgData.position[i];
1472 scaled = invBox * rs;
1476 for (
int j = 0; j < 3; j++) {
1477 scaled[j] -= roundMe(scaled[j]);
1482 if (scaled[j] >= 1.0) scaled[j] -= 1.0;
1486 whichCell.x() = int(nCells_.x() * scaled.x());
1487 whichCell.y() = int(nCells_.y() * scaled.y());
1488 whichCell.z() = int(nCells_.z() * scaled.z());
1491 cellIndex =
Vlinear(whichCell, nCells_);
1494 cellList_[cellIndex].push_back(i);
1500 for (
int j1 = 0; j1 < nGroupsInRow_; j1++) {
1501 rs = cgRowData.position[j1];
1504 for (
int j1 = 0; j1 < nGroups_; j1++) {
1505 rs = snap_->cgData.position[j1];
1510 scaled = invBox * rs;
1514 for (
int j = 0; j < 3; j++) {
1515 scaled[j] -= roundMe(scaled[j]);
1520 if (scaled[j] >= 1.0) scaled[j] -= 1.0;
1524 whichCell.x() = int(nCells_.x() * scaled.x());
1525 whichCell.y() = int(nCells_.y() * scaled.y());
1526 whichCell.z() = int(nCells_.z() * scaled.z());
1528 for (vector<Vector3i>::iterator os = cellOffsets_.begin();
1529 os != cellOffsets_.end(); ++os) {
1530 Vector3i m2v = whichCell + (*os);
1532 if (m2v.x() >= nCells_.x()) {
1534 }
else if (m2v.x() < 0) {
1535 m2v.x() = nCells_.x() - 1;
1538 if (m2v.y() >= nCells_.y()) {
1540 }
else if (m2v.y() < 0) {
1541 m2v.y() = nCells_.y() - 1;
1544 if (m2v.z() >= nCells_.z()) {
1546 }
else if (m2v.z() < 0) {
1547 m2v.z() = nCells_.z() - 1;
1549 int m2 =
Vlinear(m2v, nCells_);
1551 for (vector<int>::iterator j2 = cellListCol_[m2].begin();
1552 j2 != cellListCol_[m2].end(); ++j2) {
1556 dr = cgColData.position[(*j2)] - rs;
1557 if (usePeriodicBoundaryConditions_) { snap_->wrapVector(dr); }
1558 if (dr.lengthSquare() < rListSq_) {
1559 neighborList.push_back((*j2));
1564 for (vector<int>::iterator j2 = cellList_[m2].begin();
1565 j2 != cellList_[m2].end(); ++j2) {
1576 dr = snap_->cgData.position[(*j2)] - rs;
1577 if (usePeriodicBoundaryConditions_) { snap_->wrapVector(dr); }
1578 if (dr.lengthSquare() < rListSq_) {
1579 neighborList.push_back((*j2));
1590 for (
int j1 = 0; j1 < nGroupsInRow_; j1++) {
1592 rs = cgRowData.position[j1];
1593 for (
int j2 = 0; j2 < nGroupsInCol_; j2++) {
1594 dr = cgColData.position[j2] - rs;
1595 if (usePeriodicBoundaryConditions_) { snap_->wrapVector(dr); }
1596 if (dr.lengthSquare() < rListSq_) {
1597 neighborList.push_back(j2);
1604 for (
int j1 = 0; j1 < nGroups_; j1++) {
1606 rs = snap_->cgData.position[j1];
1608 for (
int j2 = j1; j2 < nGroups_; j2++) {
1609 dr = snap_->cgData.position[j2] - rs;
1610 if (usePeriodicBoundaryConditions_) { snap_->wrapVector(dr); }
1611 if (dr.lengthSquare() < rListSq_) {
1612 neighborList.push_back(j2);
1621 point[nGroupsInRow_] = len;
1623 point[nGroups_] = len;
1628 savedPositions.clear();
1629 savedPositions.reserve(nGroups_);
1630 for (
int i = 0; i < nGroups_; i++)
1631 savedPositions.push_back(snap_->cgData.position[i]);
1634 int ForceMatrixDecomposition::getGlobalIDRow(
int atom1) {
1636 return AtomRowToGlobal[atom1];
1642 int ForceMatrixDecomposition::getGlobalIDCol(
int atom2) {
1644 return AtomColToGlobal[atom2];
1650 int ForceMatrixDecomposition::getGlobalID(
int atom1) {
1652 return AtomLocalToGlobal[atom1];
ForceDecomposition is an interface for passing out and collecting information from many processors at...
vector< vector< int > > toposForAtom
The topological distance between two atomic sites is handled via two vector structures for speed.
bool excludeAtomPair(int atom1, int atom2)
We need to handle the interactions for atoms who are involved in the same rigid body as well as some ...
vector< int > & getAtomsInGroupRow(int cg1)
returns the list of atoms belonging to this group.
bool skipAtomPair(int atom1, int atom2, int cg1, int cg2)
We need to exclude some overcounted interactions that result from the parallel decomposition.
void distributeInitialData()
distributeInitialData is essentially a copy of the older fortran SimulationSetup
void collectSelfData()
Collects information obtained during the post-pair (and embedding functional) loops onto local data s...
InteractionManager is responsible for keeping track of the non-bonded interactions (C++).
PairList class maintains a general purpose list of atom pairs using the global indices of the atoms.
bool hasPair(int i, int j)
Checks whether pair (i, j) is in this PairList class.
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
Vector3< Real > cross(const Vector3< Real > &v1, const Vector3< Real > &v2)
Returns the cross product of two Vectors.
Real dot(const DynamicVector< Real > &v1, const DynamicVector< Real > &v2)
Returns the dot product of two DynamicVectors.
std::size_t Vlinear(const Vector2< std::size_t > &p, const Vector2< std::size_t > &s)
Returns the linear indexing for size_t vectors.