# | Line 35 | Line 35 | |
---|---|---|
35 | * | |
36 | * [1] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005). | |
37 | * [2] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006). | |
38 | < | * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 24107 (2008). |
38 | > | * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008). |
39 | * [4] Kuang & Gezelter, J. Chem. Phys. 133, 164101 (2010). | |
40 | * [5] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011). | |
41 | */ | |
# | Line 44 | Line 44 | |
44 | * @file ForceManager.cpp | |
45 | * @author tlin | |
46 | * @date 11/09/2004 | |
47 | – | * @time 10:39am |
47 | * @version 1.0 | |
48 | */ | |
49 | ||
# | Line 68 | Line 67 | namespace OpenMD { | |
67 | using namespace std; | |
68 | namespace OpenMD { | |
69 | ||
70 | < | ForceManager::ForceManager(SimInfo * info) : info_(info) { |
70 | > | ForceManager::ForceManager(SimInfo * info) : info_(info), switcher_(NULL), |
71 | > | initialized_(false) { |
72 | forceField_ = info_->getForceField(); | |
73 | interactionMan_ = new InteractionManager(); | |
74 | fDecomp_ = new ForceMatrixDecomposition(info_, interactionMan_); | |
75 | + | thermo = new Thermo(info_); |
76 | } | |
77 | ||
78 | + | ForceManager::~ForceManager() { |
79 | + | perturbations_.clear(); |
80 | + | |
81 | + | delete switcher_; |
82 | + | delete interactionMan_; |
83 | + | delete fDecomp_; |
84 | + | delete thermo; |
85 | + | } |
86 | + | |
87 | /** | |
88 | * setupCutoffs | |
89 | * | |
# | Line 88 | Line 98 | namespace OpenMD { | |
98 | * simulation for suggested cutoff values (e.g. 2.5 * sigma). | |
99 | * Use the maximum suggested value that was found. | |
100 | * | |
101 | < | * cutoffMethod : (one of HARD, SWITCHED, SHIFTED_FORCE, |
102 | < | * or SHIFTED_POTENTIAL) |
101 | > | * cutoffMethod : (one of HARD, SWITCHED, SHIFTED_FORCE, TAYLOR_SHIFTED, |
102 | > | * SHIFTED_POTENTIAL, or EWALD_FULL) |
103 | * If cutoffMethod was explicitly set, use that choice. | |
104 | * If cutoffMethod was not explicitly set, use SHIFTED_FORCE | |
105 | * | |
# | Line 118 | Line 128 | namespace OpenMD { | |
128 | else | |
129 | mdFileVersion = 0; | |
130 | ||
131 | + | // We need the list of simulated atom types to figure out cutoffs |
132 | + | // as well as long range corrections. |
133 | + | |
134 | + | set<AtomType*>::iterator i; |
135 | + | set<AtomType*> atomTypes_; |
136 | + | atomTypes_ = info_->getSimulatedAtomTypes(); |
137 | + | |
138 | if (simParams_->haveCutoffRadius()) { | |
139 | rCut_ = simParams_->getCutoffRadius(); | |
140 | } else { | |
# | Line 132 | Line 149 | namespace OpenMD { | |
149 | rCut_ = 12.0; | |
150 | } else { | |
151 | RealType thisCut; | |
152 | < | set<AtomType*>::iterator i; |
136 | < | set<AtomType*> atomTypes; |
137 | < | atomTypes = info_->getSimulatedAtomTypes(); |
138 | < | for (i = atomTypes.begin(); i != atomTypes.end(); ++i) { |
152 | > | for (i = atomTypes_.begin(); i != atomTypes_.end(); ++i) { |
153 | thisCut = interactionMan_->getSuggestedCutoffRadius((*i)); | |
154 | rCut_ = max(thisCut, rCut_); | |
155 | } | |
# | Line 157 | Line 171 | namespace OpenMD { | |
171 | stringToCutoffMethod["SWITCHED"] = SWITCHED; | |
172 | stringToCutoffMethod["SHIFTED_POTENTIAL"] = SHIFTED_POTENTIAL; | |
173 | stringToCutoffMethod["SHIFTED_FORCE"] = SHIFTED_FORCE; | |
174 | + | stringToCutoffMethod["TAYLOR_SHIFTED"] = TAYLOR_SHIFTED; |
175 | + | stringToCutoffMethod["EWALD_FULL"] = EWALD_FULL; |
176 | ||
177 | if (simParams_->haveCutoffMethod()) { | |
178 | string cutMeth = toUpperCopy(simParams_->getCutoffMethod()); | |
# | Line 166 | Line 182 | namespace OpenMD { | |
182 | sprintf(painCave.errMsg, | |
183 | "ForceManager::setupCutoffs: Could not find chosen cutoffMethod %s\n" | |
184 | "\tShould be one of: " | |
185 | < | "HARD, SWITCHED, SHIFTED_POTENTIAL, or SHIFTED_FORCE\n", |
185 | > | "HARD, SWITCHED, SHIFTED_POTENTIAL, TAYLOR_SHIFTED,\n" |
186 | > | "\tSHIFTED_FORCE, or EWALD_FULL\n", |
187 | cutMeth.c_str()); | |
188 | painCave.isFatal = 1; | |
189 | painCave.severity = OPENMD_ERROR; | |
# | Line 210 | Line 227 | namespace OpenMD { | |
227 | cutoffMethod_ = SHIFTED_POTENTIAL; | |
228 | } else if (myMethod == "SHIFTED_FORCE") { | |
229 | cutoffMethod_ = SHIFTED_FORCE; | |
230 | + | } else if (myMethod == "TAYLOR_SHIFTED") { |
231 | + | cutoffMethod_ = TAYLOR_SHIFTED; |
232 | + | } else if (myMethod == "EWALD_FULL") { |
233 | + | cutoffMethod_ = EWALD_FULL; |
234 | } | |
235 | ||
236 | if (simParams_->haveSwitchingRadius()) | |
237 | rSwitch_ = simParams_->getSwitchingRadius(); | |
238 | ||
239 | < | if (myMethod == "SHIFTED_POTENTIAL" || myMethod == "SHIFTED_FORCE") { |
239 | > | if (myMethod == "SHIFTED_POTENTIAL" || myMethod == "SHIFTED_FORCE" || |
240 | > | myMethod == "TAYLOR_SHIFTED" || myMethod == "EWALD_FULL") { |
241 | if (simParams_->haveSwitchingRadius()){ | |
242 | sprintf(painCave.errMsg, | |
243 | "ForceManager::setupCutoffs : DEPRECATED ERROR MESSAGE\n" | |
# | Line 370 | Line 392 | namespace OpenMD { | |
392 | } | |
393 | switcher_->setSwitchType(sft_); | |
394 | switcher_->setSwitch(rSwitch_, rCut_); | |
373 | – | interactionMan_->setSwitchingRadius(rSwitch_); |
395 | } | |
396 | ||
397 | ||
# | Line 394 | Line 415 | namespace OpenMD { | |
415 | doParticlePot_ = info_->getSimParams()->getOutputParticlePotential(); | |
416 | doHeatFlux_ = info_->getSimParams()->getPrintHeatFlux(); | |
417 | if (doHeatFlux_) doParticlePot_ = true; | |
418 | + | |
419 | + | doElectricField_ = info_->getSimParams()->getOutputElectricField(); |
420 | ||
421 | } | |
422 | ||
# | Line 429 | Line 452 | namespace OpenMD { | |
452 | perturbations_.push_back(eField); | |
453 | } | |
454 | ||
455 | + | usePeriodicBoundaryConditions_ = info_->getSimParams()->getUsePeriodicBoundaryConditions(); |
456 | + | |
457 | fDecomp_->distributeInitialData(); | |
458 | < | |
458 | > | |
459 | initialized_ = true; | |
460 | < | |
460 | > | |
461 | } | |
462 | < | |
462 | > | |
463 | void ForceManager::calcForces() { | |
464 | ||
465 | if (!initialized_) initialize(); | |
466 | < | |
466 | > | |
467 | preCalculation(); | |
468 | shortRangeInteractions(); | |
469 | longRangeInteractions(); | |
# | Line 637 | Line 662 | namespace OpenMD { | |
662 | ||
663 | void ForceManager::longRangeInteractions() { | |
664 | ||
640 | – | |
665 | Snapshot* curSnapshot = info_->getSnapshotManager()->getCurrentSnapshot(); | |
666 | DataStorage* config = &(curSnapshot->atomData); | |
667 | DataStorage* cgConfig = &(curSnapshot->cgData); | |
# | Line 674 | Line 698 | namespace OpenMD { | |
698 | RealType vij; | |
699 | Vector3d fij, fg, f1; | |
700 | tuple3<RealType, RealType, RealType> cuts; | |
701 | < | RealType rCutSq; |
701 | > | RealType rCut, rCutSq, rListSq; |
702 | bool in_switching_region; | |
703 | RealType sw, dswdr, swderiv; | |
704 | < | vector<int> atomListColumn, atomListRow, atomListLocal; |
704 | > | vector<int> atomListColumn, atomListRow; |
705 | InteractionData idat; | |
706 | SelfData sdat; | |
707 | RealType mf; | |
708 | RealType vpair; | |
709 | RealType dVdFQ1(0.0); | |
710 | RealType dVdFQ2(0.0); | |
687 | – | Vector3d eField1(0.0); |
688 | – | Vector3d eField2(0.0); |
711 | potVec longRangePotential(0.0); | |
712 | potVec workPot(0.0); | |
713 | potVec exPot(0.0); | |
714 | + | Vector3d eField1(0.0); |
715 | + | Vector3d eField2(0.0); |
716 | vector<int>::iterator ia, jb; | |
717 | ||
718 | int loopStart, loopEnd; | |
719 | < | |
719 | > | |
720 | > | idat.rcut = &rCut; |
721 | idat.vdwMult = &vdwMult; | |
722 | idat.electroMult = &electroMult; | |
723 | idat.pot = &workPot; | |
# | Line 703 | Line 728 | namespace OpenMD { | |
728 | idat.dVdFQ1 = &dVdFQ1; | |
729 | idat.dVdFQ2 = &dVdFQ2; | |
730 | idat.eField1 = &eField1; | |
731 | < | idat.eField2 = &eField2; |
731 | > | idat.eField2 = &eField2; |
732 | idat.f1 = &f1; | |
733 | idat.sw = &sw; | |
734 | idat.shiftedPot = (cutoffMethod_ == SHIFTED_POTENTIAL) ? true : false; | |
735 | < | idat.shiftedForce = (cutoffMethod_ == SHIFTED_FORCE) ? true : false; |
735 | > | idat.shiftedForce = (cutoffMethod_ == SHIFTED_FORCE || cutoffMethod_ == TAYLOR_SHIFTED) ? true : false; |
736 | idat.doParticlePot = doParticlePot_; | |
737 | + | idat.doElectricField = doElectricField_; |
738 | sdat.doParticlePot = doParticlePot_; | |
739 | ||
740 | loopEnd = PAIR_LOOP; | |
# | Line 721 | Line 747 | namespace OpenMD { | |
747 | ||
748 | if (iLoop == loopStart) { | |
749 | bool update_nlist = fDecomp_->checkNeighborList(); | |
750 | < | if (update_nlist) |
751 | < | neighborList = fDecomp_->buildNeighborList(); |
752 | < | } |
750 | > | if (update_nlist) { |
751 | > | if (!usePeriodicBoundaryConditions_) |
752 | > | Mat3x3d bbox = thermo->getBoundingBox(); |
753 | > | fDecomp_->buildNeighborList(neighborList_); |
754 | > | } |
755 | > | } |
756 | ||
757 | < | for (vector<pair<int, int> >::iterator it = neighborList.begin(); |
758 | < | it != neighborList.end(); ++it) { |
757 | > | for (vector<pair<int, int> >::iterator it = neighborList_.begin(); |
758 | > | it != neighborList_.end(); ++it) { |
759 | ||
760 | cg1 = (*it).first; | |
761 | cg2 = (*it).second; | |
762 | ||
763 | < | cuts = fDecomp_->getGroupCutoffs(cg1, cg2); |
763 | > | fDecomp_->getGroupCutoffs(cg1, cg2, rCut, rCutSq, rListSq); |
764 | ||
765 | d_grp = fDecomp_->getIntergroupVector(cg1, cg2); | |
766 | ||
767 | < | curSnapshot->wrapVector(d_grp); |
767 | > | // already wrapped in the getIntergroupVector call: |
768 | > | // curSnapshot->wrapVector(d_grp); |
769 | rgrpsq = d_grp.lengthSquare(); | |
740 | – | rCutSq = cuts.second; |
770 | ||
771 | if (rgrpsq < rCutSq) { | |
772 | < | idat.rcut = &cuts.first; |
772 | > | |
773 | if (iLoop == PAIR_LOOP) { | |
774 | vij = 0.0; | |
775 | < | fij = V3Zero; |
775 | > | fij.zero(); |
776 | > | eField1.zero(); |
777 | > | eField2.zero(); |
778 | } | |
779 | ||
780 | in_switching_region = switcher_->getSwitch(rgrpsq, sw, dswdr, | |
# | Line 768 | Line 799 | namespace OpenMD { | |
799 | vpair = 0.0; | |
800 | workPot = 0.0; | |
801 | exPot = 0.0; | |
802 | < | f1 = V3Zero; |
802 | > | f1.zero(); |
803 | dVdFQ1 = 0.0; | |
804 | dVdFQ2 = 0.0; | |
805 | ||
# | Line 891 | Line 922 | namespace OpenMD { | |
922 | } | |
923 | } | |
924 | } | |
925 | < | |
925 | > | |
926 | // collects pairwise information | |
927 | fDecomp_->collectData(); | |
928 | + | if (cutoffMethod_ == EWALD_FULL) { |
929 | + | interactionMan_->doReciprocalSpaceSum(longRangePotential); |
930 | + | } |
931 | ||
932 | if (info_->requiresSelfCorrection()) { | |
933 | for (unsigned int atom1 = 0; atom1 < info_->getNAtoms(); atom1++) { | |
# | Line 915 | Line 949 | namespace OpenMD { | |
949 | ||
950 | } | |
951 | ||
918 | – | |
952 | void ForceManager::postCalculation() { | |
953 | ||
954 | vector<Perturbation*>::iterator pi; | |
# | Line 946 | Line 979 | namespace OpenMD { | |
979 | #endif | |
980 | curSnapshot->setStressTensor(stressTensor); | |
981 | ||
982 | + | if (info_->getSimParams()->getUseLongRangeCorrections()) { |
983 | + | /* |
984 | + | RealType vol = curSnapshot->getVolume(); |
985 | + | RealType Elrc(0.0); |
986 | + | RealType Wlrc(0.0); |
987 | + | |
988 | + | set<AtomType*>::iterator i; |
989 | + | set<AtomType*>::iterator j; |
990 | + | |
991 | + | RealType n_i, n_j; |
992 | + | RealType rho_i, rho_j; |
993 | + | pair<RealType, RealType> LRI; |
994 | + | |
995 | + | for (i = atomTypes_.begin(); i != atomTypes_.end(); ++i) { |
996 | + | n_i = RealType(info_->getGlobalCountOfType(*i)); |
997 | + | rho_i = n_i / vol; |
998 | + | for (j = atomTypes_.begin(); j != atomTypes_.end(); ++j) { |
999 | + | n_j = RealType(info_->getGlobalCountOfType(*j)); |
1000 | + | rho_j = n_j / vol; |
1001 | + | |
1002 | + | LRI = interactionMan_->getLongRangeIntegrals( (*i), (*j) ); |
1003 | + | |
1004 | + | Elrc += n_i * rho_j * LRI.first; |
1005 | + | Wlrc -= rho_i * rho_j * LRI.second; |
1006 | + | } |
1007 | + | } |
1008 | + | Elrc *= 2.0 * NumericConstant::PI; |
1009 | + | Wlrc *= 2.0 * NumericConstant::PI; |
1010 | + | |
1011 | + | RealType lrp = curSnapshot->getLongRangePotential(); |
1012 | + | curSnapshot->setLongRangePotential(lrp + Elrc); |
1013 | + | stressTensor += Wlrc * SquareMatrix3<RealType>::identity(); |
1014 | + | curSnapshot->setStressTensor(stressTensor); |
1015 | + | */ |
1016 | + | |
1017 | + | } |
1018 | } | |
1019 | < | } //end namespace OpenMD |
1019 | > | } |
– | Removed lines |
+ | Added lines |
< | Changed lines |
> | Changed lines |