44#include "parallel/ForceMatrixDecomposition.hpp"
46#include "brains/PairList.hpp"
49#include "nonbonded/NonBondedInteraction.hpp"
54 ForceMatrixDecomposition::ForceMatrixDecomposition(
SimInfo* info,
59 cellOffsets_.push_back(
Vector3i(-1, -1, -1));
60 cellOffsets_.push_back(
Vector3i(0, -1, -1));
61 cellOffsets_.push_back(
Vector3i(1, -1, -1));
62 cellOffsets_.push_back(
Vector3i(-1, 0, -1));
63 cellOffsets_.push_back(
Vector3i(0, 0, -1));
64 cellOffsets_.push_back(
Vector3i(1, 0, -1));
65 cellOffsets_.push_back(
Vector3i(-1, 1, -1));
66 cellOffsets_.push_back(
Vector3i(0, 1, -1));
67 cellOffsets_.push_back(
Vector3i(1, 1, -1));
68 cellOffsets_.push_back(
Vector3i(-1, -1, 0));
69 cellOffsets_.push_back(
Vector3i(0, -1, 0));
70 cellOffsets_.push_back(
Vector3i(1, -1, 0));
71 cellOffsets_.push_back(
Vector3i(-1, 0, 0));
72 cellOffsets_.push_back(
Vector3i(0, 0, 0));
73 cellOffsets_.push_back(
Vector3i(1, 0, 0));
74 cellOffsets_.push_back(
Vector3i(-1, 1, 0));
75 cellOffsets_.push_back(
Vector3i(0, 1, 0));
76 cellOffsets_.push_back(
Vector3i(1, 1, 0));
77 cellOffsets_.push_back(
Vector3i(-1, -1, 1));
78 cellOffsets_.push_back(
Vector3i(0, -1, 1));
79 cellOffsets_.push_back(
Vector3i(1, -1, 1));
80 cellOffsets_.push_back(
Vector3i(-1, 0, 1));
81 cellOffsets_.push_back(
Vector3i(0, 0, 1));
82 cellOffsets_.push_back(
Vector3i(1, 0, 1));
83 cellOffsets_.push_back(
Vector3i(-1, 1, 1));
84 cellOffsets_.push_back(
Vector3i(0, 1, 1));
85 cellOffsets_.push_back(
Vector3i(1, 1, 1));
88 ForceMatrixDecomposition::~ForceMatrixDecomposition() {
90 delete AtomPlanIntRow;
91 delete AtomPlanRealRow;
92 delete AtomPlanVectorRow;
93 delete AtomPlanMatrixRow;
94 delete AtomPlanPotRow;
95 delete AtomPlanIntColumn;
96 delete AtomPlanRealColumn;
97 delete AtomPlanVectorColumn;
98 delete AtomPlanMatrixColumn;
99 delete AtomPlanPotColumn;
101 delete cgPlanVectorRow;
102 delete cgPlanIntColumn;
103 delete cgPlanVectorColumn;
113 atomStorageLayout_ = sman_->getAtomStorageLayout();
119 idents = info_->getIdentArray();
120 regions = info_->getRegions();
123 vector<int> globalGroupMembership = info_->getGlobalGroupMembership();
125 massFactors = info_->getMassFactors();
127 PairList* excludes = info_->getExcludedInteractions();
128 PairList* oneTwo = info_->getOneTwoInteractions();
129 PairList* oneThree = info_->getOneThreeInteractions();
130 PairList* oneFour = info_->getOneFourInteractions();
134 DataStorage::dslVelocity);
140 MPI_Comm row = rowComm.getComm();
141 MPI_Comm col = colComm.getComm();
143 AtomPlanIntRow =
new Plan<int>(row, nLocal_);
149 AtomPlanIntColumn =
new Plan<int>(col, nLocal_);
155 cgPlanIntRow =
new Plan<int>(row, nGroups_);
157 cgPlanIntColumn =
new Plan<int>(col, nGroups_);
160 nAtomsInRow_ = AtomPlanIntRow->getSize();
161 nAtomsInCol_ = AtomPlanIntColumn->getSize();
162 nGroupsInRow_ = cgPlanIntRow->getSize();
163 nGroupsInCol_ = cgPlanIntColumn->getSize();
166 atomRowData.
resize(nAtomsInRow_);
168 atomColData.
resize(nAtomsInCol_);
170 cgRowData.
resize(nGroupsInRow_);
172 cgColData.
resize(nGroupsInCol_);
176 DataStorage::dslVelocity);
180 identsRow.resize(nAtomsInRow_);
181 identsCol.resize(nAtomsInCol_);
183 AtomPlanIntRow->gather(idents, identsRow);
184 AtomPlanIntColumn->gather(idents, identsCol);
186 regionsRow.resize(nAtomsInRow_);
187 regionsCol.resize(nAtomsInCol_);
189 AtomPlanIntRow->gather(regions, regionsRow);
190 AtomPlanIntColumn->gather(regions, regionsCol);
193 atypesRow.resize(nAtomsInRow_);
194 atypesCol.resize(nAtomsInCol_);
196 for (
int i = 0; i < nAtomsInRow_; i++)
198 for (
int i = 0; i < nAtomsInCol_; i++)
201 pot_row.resize(nAtomsInRow_);
202 pot_col.resize(nAtomsInCol_);
204 expot_row.resize(nAtomsInRow_);
205 expot_col.resize(nAtomsInCol_);
207 selepot_row.resize(nAtomsInRow_);
208 selepot_col.resize(nAtomsInCol_);
210 AtomRowToGlobal.resize(nAtomsInRow_);
211 AtomColToGlobal.resize(nAtomsInCol_);
212 AtomPlanIntRow->gather(AtomLocalToGlobal, AtomRowToGlobal);
213 AtomPlanIntColumn->gather(AtomLocalToGlobal, AtomColToGlobal);
215 cgRowToGlobal.resize(nGroupsInRow_);
216 cgColToGlobal.resize(nGroupsInCol_);
217 cgPlanIntRow->gather(cgLocalToGlobal, cgRowToGlobal);
218 cgPlanIntColumn->gather(cgLocalToGlobal, cgColToGlobal);
220 massFactorsRow.resize(nAtomsInRow_);
221 massFactorsCol.resize(nAtomsInCol_);
222 AtomPlanRealRow->gather(massFactors, massFactorsRow);
223 AtomPlanRealColumn->gather(massFactors, massFactorsCol);
225 groupListRow_.clear();
226 groupListRow_.resize(nGroupsInRow_);
227 for (
int i = 0; i < nGroupsInRow_; i++) {
228 int gid = cgRowToGlobal[i];
229 for (
int j = 0; j < nAtomsInRow_; j++) {
230 int aid = AtomRowToGlobal[j];
231 if (globalGroupMembership[aid] == gid) groupListRow_[i].push_back(j);
235 groupListCol_.clear();
236 groupListCol_.resize(nGroupsInCol_);
237 for (
int i = 0; i < nGroupsInCol_; i++) {
238 int gid = cgColToGlobal[i];
239 for (
int j = 0; j < nAtomsInCol_; j++) {
240 int aid = AtomColToGlobal[j];
241 if (globalGroupMembership[aid] == gid) groupListCol_[i].push_back(j);
245 excludesForAtom.clear();
246 excludesForAtom.resize(nAtomsInRow_);
250 topoDist.resize(nAtomsInRow_);
251 for (
int i = 0; i < nAtomsInRow_; i++) {
252 int iglob = AtomRowToGlobal[i];
254 for (
int j = 0; j < nAtomsInCol_; j++) {
255 int jglob = AtomColToGlobal[j];
257 if (excludes->
hasPair(iglob, jglob)) excludesForAtom[i].push_back(j);
259 if (oneTwo->
hasPair(iglob, jglob)) {
261 topoDist[i].push_back(1);
263 if (oneThree->
hasPair(iglob, jglob)) {
265 topoDist[i].push_back(2);
267 if (oneFour->
hasPair(iglob, jglob)) {
269 topoDist[i].push_back(3);
277 excludesForAtom.clear();
278 excludesForAtom.resize(nLocal_);
282 topoDist.resize(nLocal_);
284 for (
int i = 0; i < nLocal_; i++) {
285 int iglob = AtomLocalToGlobal[i];
287 for (
int j = 0; j < nLocal_; j++) {
288 int jglob = AtomLocalToGlobal[j];
290 if (excludes->
hasPair(iglob, jglob)) excludesForAtom[i].push_back(j);
292 if (oneTwo->
hasPair(iglob, jglob)) {
294 topoDist[i].push_back(1);
296 if (oneThree->
hasPair(iglob, jglob)) {
298 topoDist[i].push_back(2);
300 if (oneFour->
hasPair(iglob, jglob)) {
302 topoDist[i].push_back(3);
311 atypesLocal.resize(nLocal_);
313 for (
int i = 0; i < nLocal_; i++)
317 groupList_.resize(nGroups_);
318 for (
int i = 0; i < nGroups_; i++) {
319 int gid = cgLocalToGlobal[i];
320 for (
int j = 0; j < nLocal_; j++) {
321 int aid = AtomLocalToGlobal[j];
322 if (globalGroupMembership[aid] == gid) { groupList_[i].push_back(j); }
327 int ForceMatrixDecomposition::getTopologicalDistance(
int atom1,
int atom2) {
328 for (
unsigned int j = 0; j <
toposForAtom[atom1].size(); j++) {
329 if (
toposForAtom[atom1][j] == atom2)
return topoDist[atom1][j];
334 void ForceMatrixDecomposition::zeroWorkArrays() {
338 excludedSelfPot = 0.0;
340 selectedSelfPot = 0.0;
343 if (atomStorageLayout_ & DataStorage::dslForce) {
344 fill(atomRowData.
force.begin(), atomRowData.
force.end(), V3Zero);
345 fill(atomColData.
force.begin(), atomColData.
force.end(), V3Zero);
348 if (atomStorageLayout_ & DataStorage::dslTorque) {
349 fill(atomRowData.
torque.begin(), atomRowData.
torque.end(), V3Zero);
350 fill(atomColData.
torque.begin(), atomColData.
torque.end(), V3Zero);
353 fill(pot_row.begin(), pot_row.end(),
356 fill(pot_col.begin(), pot_col.end(),
359 fill(expot_row.begin(), expot_row.end(),
362 fill(expot_col.begin(), expot_col.end(),
365 fill(selepot_row.begin(), selepot_row.end(),
368 fill(selepot_col.begin(), selepot_col.end(),
371 if (atomStorageLayout_ & DataStorage::dslParticlePot) {
376 if (atomStorageLayout_ & DataStorage::dslDensity) {
377 fill(atomRowData.
density.begin(), atomRowData.
density.end(), 0.0);
378 fill(atomColData.
density.begin(), atomColData.
density.end(), 0.0);
381 if (atomStorageLayout_ & DataStorage::dslFunctional) {
386 if (atomStorageLayout_ & DataStorage::dslFunctionalDerivative) {
393 if (atomStorageLayout_ & DataStorage::dslSkippedCharge) {
400 if (atomStorageLayout_ & DataStorage::dslFlucQForce) {
405 if (atomStorageLayout_ & DataStorage::dslElectricField) {
412 if (atomStorageLayout_ & DataStorage::dslSitePotential) {
422 if (atomStorageLayout_ & DataStorage::dslParticlePot) {
427 if (atomStorageLayout_ & DataStorage::dslDensity) {
428 fill(snap_->atomData.
density.begin(), snap_->atomData.
density.end(), 0.0);
431 if (atomStorageLayout_ & DataStorage::dslFunctional) {
436 if (atomStorageLayout_ & DataStorage::dslFunctionalDerivative) {
441 if (atomStorageLayout_ & DataStorage::dslSkippedCharge) {
446 if (atomStorageLayout_ & DataStorage::dslElectricField) {
450 if (atomStorageLayout_ & DataStorage::dslSitePotential) {
456 void ForceMatrixDecomposition::distributeData() {
460 atomStorageLayout_ = sman_->getAtomStorageLayout();
466 AtomPlanVectorRow->gather(snap_->atomData.position, atomRowData.position);
467 AtomPlanVectorColumn->gather(snap_->atomData.position,
468 atomColData.position);
473 cgPlanVectorRow->gather(snap_->cgData.position, cgRowData.position);
475 cgPlanVectorColumn->gather(snap_->cgData.position, cgColData.position);
478 if (needVelocities_) {
480 AtomPlanVectorColumn->gather(snap_->atomData.
velocity,
489 if (atomStorageLayout_ & DataStorage::dslAmat) {
490 AtomPlanMatrixRow->gather(snap_->atomData.
aMat, atomRowData.
aMat);
491 AtomPlanMatrixColumn->gather(snap_->atomData.
aMat, atomColData.
aMat);
495 if (atomStorageLayout_ & DataStorage::dslDipole) {
496 AtomPlanVectorRow->gather(snap_->atomData.
dipole, atomRowData.
dipole);
497 AtomPlanVectorColumn->gather(snap_->atomData.
dipole, atomColData.
dipole);
500 if (atomStorageLayout_ & DataStorage::dslQuadrupole) {
501 AtomPlanMatrixRow->gather(snap_->atomData.
quadrupole,
503 AtomPlanMatrixColumn->gather(snap_->atomData.
quadrupole,
508 if (atomStorageLayout_ & DataStorage::dslFlucQPosition) {
510 AtomPlanRealColumn->gather(snap_->atomData.
flucQPos,
520 void ForceMatrixDecomposition::collectIntermediateData() {
524 atomStorageLayout_ = sman_->getAtomStorageLayout();
526 if (atomStorageLayout_ & DataStorage::dslDensity) {
527 AtomPlanRealRow->scatter(atomRowData.
density, snap_->atomData.
density);
529 int n = snap_->atomData.
density.size();
530 vector<RealType> rho_tmp(n, 0.0);
531 AtomPlanRealColumn->scatter(atomColData.
density, rho_tmp);
532 for (
int i = 0; i < n; i++)
533 snap_->atomData.
density[i] += rho_tmp[i];
538 if (atomStorageLayout_ & DataStorage::dslElectricField) {
543 vector<Vector3d> field_tmp(n, V3Zero);
544 AtomPlanVectorColumn->scatter(atomColData.
electricField, field_tmp);
545 for (
int i = 0; i < n; i++)
555 void ForceMatrixDecomposition::distributeIntermediateData() {
558 atomStorageLayout_ = sman_->getAtomStorageLayout();
560 if (atomStorageLayout_ & DataStorage::dslFunctional) {
561 AtomPlanRealRow->gather(snap_->atomData.
functional,
563 AtomPlanRealColumn->gather(snap_->atomData.
functional,
567 if (atomStorageLayout_ & DataStorage::dslFunctionalDerivative) {
576 void ForceMatrixDecomposition::collectData() {
579 atomStorageLayout_ = sman_->getAtomStorageLayout();
581 int n = snap_->atomData.
force.size();
582 vector<Vector3d> frc_tmp(n, V3Zero);
584 AtomPlanVectorRow->scatter(atomRowData.
force, frc_tmp);
585 for (
int i = 0; i < n; i++) {
586 snap_->atomData.
force[i] += frc_tmp[i];
590 AtomPlanVectorColumn->scatter(atomColData.
force, frc_tmp);
591 for (
int i = 0; i < n; i++) {
592 snap_->atomData.
force[i] += frc_tmp[i];
595 if (atomStorageLayout_ & DataStorage::dslTorque) {
596 int nt = snap_->atomData.
torque.size();
597 vector<Vector3d> trq_tmp(nt, V3Zero);
599 AtomPlanVectorRow->scatter(atomRowData.
torque, trq_tmp);
600 for (
int i = 0; i < nt; i++) {
601 snap_->atomData.
torque[i] += trq_tmp[i];
605 AtomPlanVectorColumn->scatter(atomColData.
torque, trq_tmp);
606 for (
int i = 0; i < nt; i++)
607 snap_->atomData.
torque[i] += trq_tmp[i];
610 if (atomStorageLayout_ & DataStorage::dslSkippedCharge) {
612 vector<RealType> skch_tmp(ns, 0.0);
614 AtomPlanRealRow->scatter(atomRowData.
skippedCharge, skch_tmp);
615 for (
int i = 0; i < ns; i++) {
620 AtomPlanRealColumn->scatter(atomColData.
skippedCharge, skch_tmp);
621 for (
int i = 0; i < ns; i++)
625 if (atomStorageLayout_ & DataStorage::dslFlucQForce) {
626 int nq = snap_->atomData.
flucQFrc.size();
627 vector<RealType> fqfrc_tmp(nq, 0.0);
629 AtomPlanRealRow->scatter(atomRowData.
flucQFrc, fqfrc_tmp);
630 for (
int i = 0; i < nq; i++) {
631 snap_->atomData.
flucQFrc[i] += fqfrc_tmp[i];
635 AtomPlanRealColumn->scatter(atomColData.
flucQFrc, fqfrc_tmp);
636 for (
int i = 0; i < nq; i++)
637 snap_->atomData.
flucQFrc[i] += fqfrc_tmp[i];
640 if (atomStorageLayout_ & DataStorage::dslElectricField) {
642 vector<Vector3d> efield_tmp(nef, V3Zero);
644 AtomPlanVectorRow->scatter(atomRowData.
electricField, efield_tmp);
645 for (
int i = 0; i < nef; i++) {
650 AtomPlanVectorColumn->scatter(atomColData.
electricField, efield_tmp);
651 for (
int i = 0; i < nef; i++)
655 if (atomStorageLayout_ & DataStorage::dslSitePotential) {
657 vector<RealType> sp_tmp(nsp, 0.0);
660 for (
int i = 0; i < nsp; i++) {
665 AtomPlanRealColumn->scatter(atomColData.
sitePotential, sp_tmp);
666 for (
int i = 0; i < nsp; i++)
672 vector<potVec> pot_temp(nLocal_,
674 vector<potVec> expot_temp(nLocal_,
676 vector<potVec> selepot_temp(nLocal_,
681 AtomPlanPotRow->scatter(pot_row, pot_temp);
682 AtomPlanPotRow->scatter(expot_row, expot_temp);
683 AtomPlanPotRow->scatter(selepot_row, selepot_temp);
685 for (std::size_t ii = 0; ii < pot_temp.size(); ii++)
686 pairwisePot += pot_temp[ii];
688 for (std::size_t ii = 0; ii < expot_temp.size(); ii++)
689 excludedPot += expot_temp[ii];
691 for (std::size_t ii = 0; ii < selepot_temp.size(); ii++)
692 selectedPot += selepot_temp[ii];
694 if (atomStorageLayout_ & DataStorage::dslParticlePot) {
699 for (
int ii = 0; ii < N_INTERACTION_FAMILIES; ii++) {
700 for (
int i = 0; i < nLocal_; i++) {
703 snap_->atomData.
particlePot[i] += 2.0 * pot_temp[i](ii);
708 fill(pot_temp.begin(), pot_temp.end(),
710 fill(expot_temp.begin(), expot_temp.end(),
712 fill(selepot_temp.begin(), selepot_temp.end(),
715 AtomPlanPotColumn->scatter(pot_col, pot_temp);
716 AtomPlanPotColumn->scatter(expot_col, expot_temp);
717 AtomPlanPotColumn->scatter(selepot_col, selepot_temp);
719 for (std::size_t ii = 0; ii < pot_temp.size(); ii++)
720 pairwisePot += pot_temp[ii];
722 for (std::size_t ii = 0; ii < expot_temp.size(); ii++)
723 excludedPot += expot_temp[ii];
725 for (std::size_t ii = 0; ii < selepot_temp.size(); ii++)
726 selectedPot += selepot_temp[ii];
728 if (atomStorageLayout_ & DataStorage::dslParticlePot) {
733 for (
int ii = 0; ii < N_INTERACTION_FAMILIES; ii++) {
734 for (
int i = 0; i < nLocal_; i++) {
737 snap_->atomData.
particlePot[i] += 2.0 * pot_temp[i](ii);
742 if (atomStorageLayout_ & DataStorage::dslParticlePot) {
744 vector<RealType> ppot_temp(npp, 0.0);
749 AtomPlanRealRow->scatter(atomRowData.
particlePot, ppot_temp);
750 for (
int i = 0; i < npp; i++) {
754 fill(ppot_temp.begin(), ppot_temp.end(), 0.0);
756 AtomPlanRealColumn->scatter(atomColData.
particlePot, ppot_temp);
757 for (
int i = 0; i < npp; i++) {
762 MPI_Allreduce(MPI_IN_PLACE, &pairwisePot[0], N_INTERACTION_FAMILIES,
763 MPI_REALTYPE, MPI_SUM, MPI_COMM_WORLD);
765 MPI_Allreduce(MPI_IN_PLACE, &excludedPot[0], N_INTERACTION_FAMILIES,
766 MPI_REALTYPE, MPI_SUM, MPI_COMM_WORLD);
768 MPI_Allreduce(MPI_IN_PLACE, &selectedPot[0], N_INTERACTION_FAMILIES,
769 MPI_REALTYPE, MPI_SUM, MPI_COMM_WORLD);
772 MPI_Comm col = colComm.getComm();
775 MPI_REALTYPE, MPI_SUM, col);
785 MPI_Allreduce(MPI_IN_PLACE, &selfPot[0], N_INTERACTION_FAMILIES,
786 MPI_REALTYPE, MPI_SUM, MPI_COMM_WORLD);
788 MPI_Allreduce(MPI_IN_PLACE, &excludedSelfPot[0], N_INTERACTION_FAMILIES,
789 MPI_REALTYPE, MPI_SUM, MPI_COMM_WORLD);
791 MPI_Allreduce(MPI_IN_PLACE, &selectedSelfPot[0], N_INTERACTION_FAMILIES,
792 MPI_REALTYPE, MPI_SUM, MPI_COMM_WORLD);
796 int& ForceMatrixDecomposition::getNAtomsInRow() {
809 return groupListRow_[cg1];
811 return groupList_[cg1];
815 vector<int>& ForceMatrixDecomposition::getAtomsInGroupColumn(
int cg2) {
817 return groupListCol_[cg2];
819 return groupList_[cg2];
823 Vector3d ForceMatrixDecomposition::getIntergroupVector(
int cg1,
int cg2) {
826 d = cgColData.position[cg2] - cgRowData.position[cg1];
828 d = snap_->cgData.position[cg2] - snap_->cgData.position[cg1];
831 if (usePeriodicBoundaryConditions_) { snap_->
wrapVector(d); }
835 Vector3d& ForceMatrixDecomposition::getGroupVelocityColumn(
int cg2) {
843 Vector3d& ForceMatrixDecomposition::getAtomVelocityColumn(
int atom2) {
847 return snap_->atomData.
velocity[atom2];
851 Vector3d ForceMatrixDecomposition::getAtomToGroupVectorRow(
int atom1,
856 d = cgRowData.position[cg1] - atomRowData.position[atom1];
858 d = snap_->cgData.position[cg1] - snap_->atomData.position[atom1];
860 if (usePeriodicBoundaryConditions_) { snap_->
wrapVector(d); }
864 Vector3d ForceMatrixDecomposition::getAtomToGroupVectorColumn(
int atom2,
869 d = cgColData.position[cg2] - atomColData.position[atom2];
871 d = snap_->cgData.position[cg2] - snap_->atomData.position[atom2];
873 if (usePeriodicBoundaryConditions_) { snap_->
wrapVector(d); }
877 RealType& ForceMatrixDecomposition::getMassFactorRow(
int atom1) {
879 return massFactorsRow[atom1];
881 return massFactors[atom1];
885 RealType& ForceMatrixDecomposition::getMassFactorColumn(
int atom2) {
887 return massFactorsCol[atom2];
889 return massFactors[atom2];
893 Vector3d ForceMatrixDecomposition::getInteratomicVector(
int atom1,
898 d = atomColData.position[atom2] - atomRowData.position[atom1];
900 d = snap_->atomData.position[atom2] - snap_->atomData.position[atom1];
902 if (usePeriodicBoundaryConditions_) { snap_->
wrapVector(d); }
906 vector<int>& ForceMatrixDecomposition::getExcludesForAtom(
int atom1) {
907 return excludesForAtom[atom1];
917 int unique_id_1 = AtomRowToGlobal[atom1];
918 int unique_id_2 = AtomColToGlobal[atom2];
920 if (unique_id_1 == unique_id_2)
return true;
923 if (unique_id_1 < unique_id_2) {
924 if ((unique_id_1 + unique_id_2) % 2 == 0)
return true;
926 if ((unique_id_1 + unique_id_2) % 2 == 1)
return true;
935 int unique_id_1 = AtomLocalToGlobal[atom1];
936 int unique_id_2 = AtomLocalToGlobal[atom2];
937 int group1 = cgLocalToGlobal[cg1];
938 int group2 = cgLocalToGlobal[cg2];
940 if (unique_id_1 == unique_id_2)
return true;
942 if (group1 == group2) {
943 if (unique_id_1 < unique_id_2)
return true;
963 for (vector<int>::iterator i = excludesForAtom[atom1].begin();
964 i != excludesForAtom[atom1].end(); ++i) {
965 if ((*i) == atom2)
return true;
971 void ForceMatrixDecomposition::addForceToAtomRow(
int atom1,
Vector3d fg) {
973 atomRowData.
force[atom1] += fg;
975 snap_->atomData.
force[atom1] += fg;
979 void ForceMatrixDecomposition::addForceToAtomColumn(
int atom2,
Vector3d fg) {
981 atomColData.
force[atom2] += fg;
983 snap_->atomData.
force[atom2] += fg;
988 void ForceMatrixDecomposition::fillInteractionData(
InteractionData& idat,
989 int atom1,
int atom2,
995 idat.
atid1 = identsRow[atom1];
996 idat.
atid2 = identsCol[atom2];
998 if (regionsRow[atom1] >= 0 && regionsCol[atom2] >= 0) {
999 idat.
sameRegion = (regionsRow[atom1] == regionsCol[atom2]);
1004 if (atomStorageLayout_ & DataStorage::dslAmat) {
1005 idat.
A1 = atomRowData.
aMat[atom1];
1006 idat.
A2 = atomColData.
aMat[atom2];
1009 if (atomStorageLayout_ & DataStorage::dslTorque) {
1010 idat.
t1 = atomRowData.
torque[atom1];
1011 idat.
t2 = atomColData.
torque[atom2];
1014 if (atomStorageLayout_ & DataStorage::dslDipole) {
1019 if (atomStorageLayout_ & DataStorage::dslQuadrupole) {
1024 if (atomStorageLayout_ & DataStorage::dslDensity) {
1029 if (atomStorageLayout_ & DataStorage::dslFunctional) {
1034 if (atomStorageLayout_ & DataStorage::dslFunctionalDerivative) {
1039 if (atomStorageLayout_ & DataStorage::dslParticlePot) {
1044 if (atomStorageLayout_ & DataStorage::dslSkippedCharge) {
1049 if (atomStorageLayout_ & DataStorage::dslFlucQPosition) {
1056 idat.
atid1 = idents[atom1];
1057 idat.
atid2 = idents[atom2];
1059 if (regions[atom1] >= 0 && regions[atom2] >= 0) {
1060 idat.
sameRegion = (regions[atom1] == regions[atom2]);
1065 if (atomStorageLayout_ & DataStorage::dslAmat) {
1066 idat.
A1 = snap_->atomData.
aMat[atom1];
1067 idat.
A2 = snap_->atomData.
aMat[atom2];
1070 if (atomStorageLayout_ & DataStorage::dslTorque) {
1071 idat.
t1 = snap_->atomData.
torque[atom1];
1072 idat.
t2 = snap_->atomData.
torque[atom2];
1075 if (atomStorageLayout_ & DataStorage::dslDipole) {
1076 idat.
D_1 = snap_->atomData.
dipole[atom1];
1077 idat.
D_2 = snap_->atomData.
dipole[atom2];
1080 if (atomStorageLayout_ & DataStorage::dslQuadrupole) {
1085 if (atomStorageLayout_ & DataStorage::dslDensity) {
1090 if (atomStorageLayout_ & DataStorage::dslFunctional) {
1095 if (atomStorageLayout_ & DataStorage::dslFunctionalDerivative) {
1100 if (atomStorageLayout_ & DataStorage::dslParticlePot) {
1105 if (atomStorageLayout_ & DataStorage::dslSkippedCharge) {
1110 if (atomStorageLayout_ & DataStorage::dslFlucQPosition) {
1119 idat.
atid2 = identsCol[atom2];
1121 if (regionsRow[atom1] >= 0 && regionsCol[atom2] >= 0) {
1122 idat.
sameRegion = (regionsRow[atom1] == regionsCol[atom2]);
1127 if (atomStorageLayout_ & DataStorage::dslAmat) {
1128 idat.
A2 = atomColData.
aMat[atom2];
1131 if (atomStorageLayout_ & DataStorage::dslTorque) {
1132 idat.
t2 = atomColData.
torque[atom2];
1135 if (atomStorageLayout_ & DataStorage::dslDipole) {
1139 if (atomStorageLayout_ & DataStorage::dslQuadrupole) {
1143 if (atomStorageLayout_ & DataStorage::dslDensity) {
1147 if (atomStorageLayout_ & DataStorage::dslFunctional) {
1151 if (atomStorageLayout_ & DataStorage::dslFunctionalDerivative) {
1155 if (atomStorageLayout_ & DataStorage::dslParticlePot) {
1159 if (atomStorageLayout_ & DataStorage::dslSkippedCharge) {
1163 if (atomStorageLayout_ & DataStorage::dslFlucQPosition) {
1168 idat.
atid2 = idents[atom2];
1170 if (regions[atom1] >= 0 && regions[atom2] >= 0) {
1171 idat.
sameRegion = (regions[atom1] == regions[atom2]);
1176 if (atomStorageLayout_ & DataStorage::dslAmat) {
1177 idat.
A2 = snap_->atomData.
aMat[atom2];
1180 if (atomStorageLayout_ & DataStorage::dslTorque) {
1181 idat.
t2 = snap_->atomData.
torque[atom2];
1184 if (atomStorageLayout_ & DataStorage::dslDipole) {
1185 idat.
D_2 = snap_->atomData.
dipole[atom2];
1188 if (atomStorageLayout_ & DataStorage::dslQuadrupole) {
1192 if (atomStorageLayout_ & DataStorage::dslDensity) {
1196 if (atomStorageLayout_ & DataStorage::dslFunctional) {
1200 if (atomStorageLayout_ & DataStorage::dslFunctionalDerivative) {
1204 if (atomStorageLayout_ & DataStorage::dslParticlePot) {
1208 if (atomStorageLayout_ & DataStorage::dslSkippedCharge) {
1212 if (atomStorageLayout_ & DataStorage::dslFlucQPosition) {
1220 void ForceMatrixDecomposition::unpackInteractionData(
InteractionData& idat,
1221 int atom1,
int atom2) {
1223 pot_row[atom1] += 0.5 * idat.
pot;
1224 pot_col[atom2] += 0.5 * idat.
pot;
1227 selepot_row[atom1] += 0.5 * idat.
selePot;
1228 selepot_col[atom2] += 0.5 * idat.
selePot;
1230 atomRowData.
force[atom1] += idat.
f1;
1231 atomColData.
force[atom2] -= idat.
f1;
1233 if (atomStorageLayout_ & DataStorage::dslFlucQForce) {
1238 if (atomStorageLayout_ & DataStorage::dslElectricField) {
1243 if (atomStorageLayout_ & DataStorage::dslSitePotential) {
1248 if (atomStorageLayout_ & DataStorage::dslTorque) {
1249 atomRowData.
torque[atom1] = idat.
t1;
1250 atomColData.
torque[atom2] = idat.
t2;
1253 if (atomStorageLayout_ & DataStorage::dslSkippedCharge) {
1259 pairwisePot += idat.
pot;
1263 snap_->atomData.
force[atom1] += idat.
f1;
1264 snap_->atomData.
force[atom2] -= idat.
f1;
1275 if (atomStorageLayout_ & DataStorage::dslFlucQForce) {
1280 if (atomStorageLayout_ & DataStorage::dslElectricField) {
1285 if (atomStorageLayout_ & DataStorage::dslSitePotential) {
1290 if (atomStorageLayout_ & DataStorage::dslTorque) {
1291 snap_->atomData.
torque[atom1] = idat.
t1;
1292 snap_->atomData.
torque[atom2] = idat.
t2;
1295 if (atomStorageLayout_ & DataStorage::dslSkippedCharge) {
1302 void ForceMatrixDecomposition::unpackPrePairData(
InteractionData& idat,
1303 int atom1,
int atom2) {
1306 if (atomStorageLayout_ & DataStorage::dslDensity) {
1313 if (atomStorageLayout_ & DataStorage::dslDensity) {
1333 void ForceMatrixDecomposition::buildNeighborList(
1334 vector<int>& neighborList, vector<int>& point,
1335 vector<Vector3d>& savedPositions) {
1336 neighborList.clear();
1340 bool doAllPairs =
false;
1351 cellListRow_.clear();
1352 cellListCol_.clear();
1353 point.resize(nGroupsInRow_ + 1);
1356 point.resize(nGroups_ + 1);
1359 if (!usePeriodicBoundaryConditions_) {
1382 RealType Wa = abs(
dot(A, BxC));
1383 RealType Wb = abs(
dot(B, CxA));
1384 RealType Wc = abs(
dot(C, AxB));
1386 nCells_.
x() = int(Wa / rList_);
1387 nCells_.
y() = int(Wb / rList_);
1388 nCells_.
z() = int(Wc / rList_);
1391 if (nCells_.
x() < 3) doAllPairs =
true;
1392 if (nCells_.
y() < 3) doAllPairs =
true;
1393 if (nCells_.
z() < 3) doAllPairs =
true;
1395 int nCtot = nCells_.
x() * nCells_.
y() * nCells_.
z();
1398 cellListRow_.resize(nCtot);
1399 cellListCol_.resize(nCtot);
1401 cellList_.resize(nCtot);
1407 for (
int i = 0; i < nGroupsInRow_; i++) {
1408 rs = cgRowData.position[i];
1411 scaled = invBox * rs;
1415 for (
int j = 0; j < 3; j++) {
1416 scaled[j] -= roundMe(scaled[j]);
1421 if (scaled[j] >= 1.0) scaled[j] -= 1.0;
1425 whichCell.
x() = int(nCells_.
x() * scaled.
x());
1426 whichCell.
y() = int(nCells_.
y() * scaled.
y());
1427 whichCell.
z() = int(nCells_.
z() * scaled.
z());
1430 cellIndex =
Vlinear(whichCell, nCells_);
1433 cellListRow_[cellIndex].push_back(i);
1435 for (
int i = 0; i < nGroupsInCol_; i++) {
1436 rs = cgColData.position[i];
1439 scaled = invBox * rs;
1443 for (
int j = 0; j < 3; j++) {
1444 scaled[j] -= roundMe(scaled[j]);
1449 if (scaled[j] >= 1.0) scaled[j] -= 1.0;
1453 whichCell.
x() = int(nCells_.
x() * scaled.
x());
1454 whichCell.
y() = int(nCells_.
y() * scaled.
y());
1455 whichCell.
z() = int(nCells_.
z() * scaled.
z());
1458 cellIndex =
Vlinear(whichCell, nCells_);
1461 cellListCol_[cellIndex].push_back(i);
1465 for (
int i = 0; i < nGroups_; i++) {
1466 rs = snap_->cgData.position[i];
1469 scaled = invBox * rs;
1473 for (
int j = 0; j < 3; j++) {
1474 scaled[j] -= roundMe(scaled[j]);
1479 if (scaled[j] >= 1.0) scaled[j] -= 1.0;
1483 whichCell.
x() = int(nCells_.
x() * scaled.
x());
1484 whichCell.
y() = int(nCells_.
y() * scaled.
y());
1485 whichCell.
z() = int(nCells_.
z() * scaled.
z());
1488 cellIndex =
Vlinear(whichCell, nCells_);
1491 cellList_[cellIndex].push_back(i);
1497 for (
int j1 = 0; j1 < nGroupsInRow_; j1++) {
1498 rs = cgRowData.position[j1];
1501 for (
int j1 = 0; j1 < nGroups_; j1++) {
1502 rs = snap_->cgData.position[j1];
1507 scaled = invBox * rs;
1511 for (
int j = 0; j < 3; j++) {
1512 scaled[j] -= roundMe(scaled[j]);
1517 if (scaled[j] >= 1.0) scaled[j] -= 1.0;
1521 whichCell.
x() = int(nCells_.
x() * scaled.
x());
1522 whichCell.
y() = int(nCells_.
y() * scaled.
y());
1523 whichCell.
z() = int(nCells_.
z() * scaled.
z());
1525 for (vector<Vector3i>::iterator os = cellOffsets_.begin();
1526 os != cellOffsets_.end(); ++os) {
1529 if (m2v.
x() >= nCells_.
x()) {
1531 }
else if (m2v.
x() < 0) {
1532 m2v.
x() = nCells_.
x() - 1;
1535 if (m2v.
y() >= nCells_.
y()) {
1537 }
else if (m2v.
y() < 0) {
1538 m2v.
y() = nCells_.
y() - 1;
1541 if (m2v.
z() >= nCells_.
z()) {
1543 }
else if (m2v.
z() < 0) {
1544 m2v.
z() = nCells_.
z() - 1;
1546 int m2 =
Vlinear(m2v, nCells_);
1548 for (vector<int>::iterator j2 = cellListCol_[m2].begin();
1549 j2 != cellListCol_[m2].end(); ++j2) {
1553 dr = cgColData.position[(*j2)] - rs;
1554 if (usePeriodicBoundaryConditions_) { snap_->
wrapVector(dr); }
1556 neighborList.push_back((*j2));
1561 for (vector<int>::iterator j2 = cellList_[m2].begin();
1562 j2 != cellList_[m2].end(); ++j2) {
1573 dr = snap_->cgData.position[(*j2)] - rs;
1574 if (usePeriodicBoundaryConditions_) { snap_->
wrapVector(dr); }
1576 neighborList.push_back((*j2));
1587 for (
int j1 = 0; j1 < nGroupsInRow_; j1++) {
1589 rs = cgRowData.position[j1];
1590 for (
int j2 = 0; j2 < nGroupsInCol_; j2++) {
1591 dr = cgColData.position[j2] - rs;
1592 if (usePeriodicBoundaryConditions_) { snap_->
wrapVector(dr); }
1594 neighborList.push_back(j2);
1601 for (
int j1 = 0; j1 < nGroups_; j1++) {
1603 rs = snap_->cgData.position[j1];
1605 for (
int j2 = j1; j2 < nGroups_; j2++) {
1606 dr = snap_->cgData.position[j2] - rs;
1607 if (usePeriodicBoundaryConditions_) { snap_->
wrapVector(dr); }
1609 neighborList.push_back(j2);
1618 point[nGroupsInRow_] = len;
1620 point[nGroups_] = len;
1625 savedPositions.clear();
1626 savedPositions.reserve(nGroups_);
1627 for (
int i = 0; i < nGroups_; i++)
1628 savedPositions.push_back(snap_->cgData.position[i]);
1631 int ForceMatrixDecomposition::getGlobalIDRow(
int atom1) {
1633 return AtomRowToGlobal[atom1];
1639 int ForceMatrixDecomposition::getGlobalIDCol(
int atom2) {
1641 return AtomColToGlobal[atom2];
1647 int ForceMatrixDecomposition::getGlobalID(
int atom1) {
1649 return AtomLocalToGlobal[atom1];
vector< RealType > functional
electron density
void resize(std::size_t newSize)
Changes the size of this DataStorage.
vector< RealType > flucQFrc
fluctuating charge velocities
vector< RealType > particlePot
torque array
vector< RealType > sitePotential
fluctuating charge forces
vector< Mat3x3d > quadrupole
space-frame dipole vector
vector< RealType > functionalDerivative
density functional
vector< RealType > flucQPos
charge skipped during normal pairwise calculation
vector< Vector3d > velocity
position array
vector< RotMat3x3d > aMat
force array
vector< RealType > density
particle potential arrray
vector< RealType > skippedCharge
local electric field
void setStorageLayout(int layout)
Sets the storage layout
vector< Vector3d > torque
angular momentum array (body-fixed)
vector< Vector3d > force
velocity array
vector< Vector3d > electricField
space-frame quadrupole tensor
vector< Vector3d > dipole
derivative of functional
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.
AtomType * getAtomType(const std::string &at)
getAtomType by string
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.
Vector< Real, Col > getColumn(unsigned int col)
Returns a column of this matrix as a vector.
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
std::vector< int > getGlobalGroupIndices()
returns a vector which maps the local cutoff group index on this processor to the global cutoff group...
ForceField * getForceField()
Returns the force field.
unsigned int getNAtoms()
Returns the number of local atoms.
unsigned int getNCutoffGroups()
Returns the number of local cutoff groups.
unsigned int getNLocalCutoffGroups()
Returns the number of effective cutoff groups on local processor.
std::vector< int > getGlobalAtomIndices()
returns a vector which maps the local atom index on this processor to the global atom index.
The Snapshot class is a repository storing dynamic data during a Simulation.
Mat3x3d getHmat()
Returns the H-Matrix.
Mat3x3d getInvHmat()
Returns the inverse H-Matrix.
Mat3x3d getBoundingBox()
Returns the Bounding Box.
int getNumberOfAtoms()
Returns the number of atoms.
Mat3x3d getInvBoundingBox()
Returns the inverse Bounding Box.
void wrapVector(Vector3d &v)
Wrapping the vector according to periodic boundary condition.
Snapshot * getCurrentSnapshot()
Returns the pointer of current snapshot.
Real & z()
Returns reference of the third element of Vector3.
Real & x()
Returns reference of the first element of Vector3.
Real & y()
Returns reference of the second element of Vector3.
void normalize()
Normalizes this vector in place.
Real lengthSquare()
Returns the squared length of this vector.
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.
Vector3d conductiveHeatFlux
heat flux vector (conductive only)
The InteractionData struct.
RealType sPot2
site potential on second atom
Vector3d D_1
dipole vector of first atom
RealType skippedCharge1
charge skipped on atom1 in pairwise interaction loop with atom2
RealType dVdFQ1
fluctuating charge force on atom1
RealType dVdFQ2
fluctuating charge force on atom2
RealType particlePot2
particle potential for atom2
int atid1
atomType ident for atom 1
potVec pot
total potential
potVec selePot
potential energies of the selected sites
RealType flucQ2
fluctuating charge on atom2
bool sameRegion
are these atoms specified to be in the same region?
bool excluded
is this excluded from direct pairwise interactions? (some indirect interactions may still apply)
RealType rho2
total electron density at second atom
RealType sw
switching function value at rij
Vector3d eField1
electric field on first atom
RotMat3x3d A2
rotation matrix of second atom
RotMat3x3d A1
rotation matrix of first atom
RealType flucQ1
fluctuating charge on atom1
Mat3x3d Q_2
quadrupole tensor of first atom
Vector3d eField2
electric field on second atom
Vector3d t1
torque on first atom
Vector3d t2
torque on second atom
RealType vpair
pair potential
RealType sPot1
site potential on first atom
int atid2
atomType ident for atom 2
Vector3d D_2
dipole vector of first atom
RealType skippedCharge2
charge skipped on atom2 in pairwise interaction loop with atom1
RealType dfrho2
derivative of functional for atom 2
potVec excludedPot
potential energy excluded from the overall calculation
RealType frho2
density functional at second atom
bool doParticlePot
should we bother with the particle pot?
RealType dfrho1
derivative of functional for atom 1
Mat3x3d Q_1
quadrupole tensor of first atom
RealType frho1
density functional at first atom
Vector3d f1
force between the two atoms
RealType particlePot1
particle potential for atom1
RealType rho1
total electron density at first atom