OpenMD 3.2
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
InteractionManager.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 "nonbonded/InteractionManager.hpp"
49
50#include "types/InversePowerSeriesInteractionType.hpp"
51#include "types/LennardJonesInteractionType.hpp"
52#include "types/MAWInteractionType.hpp"
53#include "types/MieInteractionType.hpp"
54#include "types/MorseInteractionType.hpp"
55#include "types/RepulsivePowerInteractionType.hpp"
56
57namespace OpenMD {
58
59 InteractionManager::InteractionManager() {
60 initialized_ = false;
61
62 lj_ = std::make_shared<LJ>();
63 gb_ = std::make_shared<GB>();
64 sticky_ = std::make_shared<Sticky>();
65 morse_ = std::make_shared<Morse>();
66 repulsivePower_ = std::make_shared<RepulsivePower>();
67 mie_ = std::make_shared<Mie>();
68 eam_ = std::make_shared<EAM>();
69 sc_ = std::make_shared<SC>();
70 electrostatic_ = std::make_shared<Electrostatic>();
71 maw_ = std::make_shared<MAW>();
72 inversePowerSeries_ = std::make_shared<InversePowerSeries>();
73 }
74
75 void InteractionManager::initialize() {
76 if (initialized_) return;
77
78 ForceField* forceField_ = info_->getForceField();
79
80 lj_->setForceField(forceField_);
81 gb_->setForceField(forceField_);
82 sticky_->setForceField(forceField_);
83 eam_->setForceField(forceField_);
84 eam_->setElectrostatic(electrostatic_.get());
85 sc_->setForceField(forceField_);
86 morse_->setForceField(forceField_);
87 electrostatic_->setSimInfo(info_);
88 electrostatic_->setForceField(forceField_);
89 maw_->setForceField(forceField_);
90 repulsivePower_->setForceField(forceField_);
91 mie_->setForceField(forceField_);
92 inversePowerSeries_->setForceField(forceField_);
93
94 ForceField::AtomTypeContainer* atomTypes = forceField_->getAtomTypes();
95 int nTypes = atomTypes->size();
96 sHash_.resize(nTypes);
97 iHash_.resize(nTypes);
98 interactions_.resize(nTypes);
99 ForceField::AtomTypeContainer::MapTypeIterator i1, i2;
100 AtomType* atype1;
101 AtomType* atype2;
102 int atid1, atid2;
103
104 // We only need to worry about the types that are actually in the
105 // simulation:
106
107 AtomTypeSet atypes = info_->getSimulatedAtomTypes();
108
109 lj_->setSimulatedAtomTypes(atypes);
110 gb_->setSimulatedAtomTypes(atypes);
111 sticky_->setSimulatedAtomTypes(atypes);
112 eam_->setSimulatedAtomTypes(atypes);
113 sc_->setSimulatedAtomTypes(atypes);
114 morse_->setSimulatedAtomTypes(atypes);
115 electrostatic_->setSimInfo(info_);
116 electrostatic_->setSimulatedAtomTypes(atypes);
117 maw_->setSimulatedAtomTypes(atypes);
118 repulsivePower_->setSimulatedAtomTypes(atypes);
119 mie_->setSimulatedAtomTypes(atypes);
120 inversePowerSeries_->setSimulatedAtomTypes(atypes);
121
122 AtomTypeSet::iterator at;
123 set<NonBondedInteractionPtr>::iterator it;
124
125 for (at = atypes.begin(); at != atypes.end(); ++at) {
126 atype1 = *at;
127 atid1 = atype1->getIdent();
128 iHash_[atid1].resize(nTypes);
129 interactions_[atid1].resize(nTypes);
130
131 // add it to the map:
132 pair<map<int, AtomType*>::iterator, bool> ret;
133 ret = typeMap_.insert(pair<int, AtomType*>(atid1, atype1));
134 if (ret.second == false) {
135 snprintf(
136 painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
137 "InteractionManager already had a previous entry with ident %d\n",
138 atype1->getIdent());
139 painCave.severity = OPENMD_INFO;
140 painCave.isFatal = 0;
141 simError();
142 }
143
144 if (atype1->isLennardJones()) { sHash_[atid1] |= LJ_INTERACTION; }
145 if (atype1->isElectrostatic()) {
146 sHash_[atid1] |= ELECTROSTATIC_INTERACTION;
147 }
148 if (atype1->isSticky()) { sHash_[atid1] |= STICKY_INTERACTION; }
149 if (atype1->isStickyPower()) { sHash_[atid1] |= STICKY_INTERACTION; }
150 if (atype1->isEAM()) { sHash_[atid1] |= EAM_INTERACTION; }
151 if (atype1->isSC()) { sHash_[atid1] |= SC_INTERACTION; }
152 if (atype1->isGayBerne()) { sHash_[atid1] |= GB_INTERACTION; }
153 }
154 // Now, iterate over all known types and add to the interaction map:
155
156 map<int, AtomType*>::iterator it1, it2;
157 for (it1 = typeMap_.begin(); it1 != typeMap_.end(); ++it1) {
158 atype1 = (*it1).second;
159 atid1 = atype1->getIdent();
160
161 for (it2 = typeMap_.begin(); it2 != typeMap_.end(); ++it2) {
162 atype2 = (*it2).second;
163 atid2 = atype2->getIdent();
164
165 iHash_[atid1][atid2] = 0;
166
167 if (atype1->isLennardJones() && atype2->isLennardJones()) {
168 interactions_[atid1][atid2].insert(lj_);
169 iHash_[atid1][atid2] |= LJ_INTERACTION;
170 }
171 if (atype1->isElectrostatic() && atype2->isElectrostatic()) {
172 interactions_[atid1][atid2].insert(electrostatic_);
173 iHash_[atid1][atid2] |= ELECTROSTATIC_INTERACTION;
174 }
175
176 // A special case for calculating local fields:
177 if (info_->getSimParams()->getOutputElectricField()) {
178 if (atype1->isElectrostatic() || atype2->isElectrostatic()) {
179 interactions_[atid1][atid2].insert(electrostatic_);
180 iHash_[atid1][atid2] |= ELECTROSTATIC_INTERACTION;
181 }
182 }
183
184 if (atype1->isSticky() && atype2->isSticky()) {
185 interactions_[atid1][atid2].insert(sticky_);
186 iHash_[atid1][atid2] |= STICKY_INTERACTION;
187 }
188 if (atype1->isStickyPower() && atype2->isStickyPower()) {
189 interactions_[atid1][atid2].insert(sticky_);
190 iHash_[atid1][atid2] |= STICKY_INTERACTION;
191 }
192 if (atype1->isEAM() && atype2->isEAM()) {
193 interactions_[atid1][atid2].insert(eam_);
194 iHash_[atid1][atid2] |= EAM_INTERACTION;
195 }
196 if (atype1->isSC() && atype2->isSC()) {
197 interactions_[atid1][atid2].insert(sc_);
198 iHash_[atid1][atid2] |= SC_INTERACTION;
199 }
200 if (atype1->isGayBerne() && atype2->isGayBerne()) {
201 interactions_[atid1][atid2].insert(gb_);
202 iHash_[atid1][atid2] |= GB_INTERACTION;
203 }
204 if ((atype1->isGayBerne() && atype2->isLennardJones()) ||
205 (atype1->isLennardJones() && atype2->isGayBerne())) {
206 interactions_[atid1][atid2].insert(gb_);
207 iHash_[atid1][atid2] |= GB_INTERACTION;
208 }
209
210 // look for an explicitly-set non-bonded interaction type using the
211 // two atom types.
212 NonBondedInteractionType* nbiType =
213 forceField_->getNonBondedInteractionType(atype1->getName(),
214 atype2->getName());
215
216 if (nbiType != NULL) {
217 bool vdwExplicit = false;
218 bool metExplicit = false;
219 // bool hbExplicit = false;
220
221 if (nbiType->isLennardJones()) {
222 // We found an explicit Lennard-Jones interaction.
223 // override all other vdw entries for this pair of atom types:
224 for (it = interactions_[atid1][atid2].begin();
225 it != interactions_[atid1][atid2].end();) {
226 InteractionFamily ifam = (*it)->getFamily();
227 if (ifam == VANDERWAALS_FAMILY) {
228 iHash_[atid1][atid2] ^= (*it)->getHash();
229 interactions_[atid1][atid2].erase(it++);
230 } else {
231 ++it;
232 }
233 }
234 interactions_[atid1][atid2].insert(lj_);
235 iHash_[atid1][atid2] |= LJ_INTERACTION;
236 LennardJonesInteractionType* ljit =
237 dynamic_cast<LennardJonesInteractionType*>(nbiType);
238 lj_->addExplicitInteraction(atype1, atype2, ljit->getSigma(),
239 ljit->getEpsilon());
240 vdwExplicit = true;
241 }
242
243 if (nbiType->isMorse()) {
244 if (vdwExplicit) {
245 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
246 "InteractionManager::initialize found more than one "
247 "explicit \n"
248 "\tvan der Waals interaction for atom types %s - %s\n",
249 atype1->getName().c_str(), atype2->getName().c_str());
250 painCave.severity = OPENMD_ERROR;
251 painCave.isFatal = 1;
252 simError();
253 }
254 // We found an explicit Morse interaction.
255 // override all other vdw entries for this pair of atom types:
256 for (it = interactions_[atid1][atid2].begin();
257 it != interactions_[atid1][atid2].end();) {
258 InteractionFamily ifam = (*it)->getFamily();
259 if (ifam == VANDERWAALS_FAMILY) {
260 iHash_[atid1][atid2] ^= (*it)->getHash();
261 interactions_[atid1][atid2].erase(it++);
262 } else {
263 ++it;
264 }
265 }
266 interactions_[atid1][atid2].insert(morse_);
267 iHash_[atid1][atid2] |= MORSE_INTERACTION;
268 MorseInteractionType* mit =
269 dynamic_cast<MorseInteractionType*>(nbiType);
270 morse_->addExplicitInteraction(atype1, atype2, mit->getD(),
271 mit->getR(), mit->getBeta(),
272 mit->getInteractionType());
273 vdwExplicit = true;
274 }
275
276 if (nbiType->isRepulsivePower()) {
277 if (vdwExplicit) {
278 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
279 "InteractionManager::initialize found more than one "
280 "explicit \n"
281 "\tvan der Waals interaction for atom types %s - %s\n",
282 atype1->getName().c_str(), atype2->getName().c_str());
283 painCave.severity = OPENMD_ERROR;
284 painCave.isFatal = 1;
285 simError();
286 }
287 // We found an explicit RepulsivePower interaction.
288 // override all other vdw entries for this pair of atom types:
289 for (it = interactions_[atid1][atid2].begin();
290 it != interactions_[atid1][atid2].end();) {
291 InteractionFamily ifam = (*it)->getFamily();
292 if (ifam == VANDERWAALS_FAMILY) {
293 iHash_[atid1][atid2] ^= (*it)->getHash();
294 interactions_[atid1][atid2].erase(it++);
295 } else {
296 ++it;
297 }
298 }
299 interactions_[atid1][atid2].insert(repulsivePower_);
300 iHash_[atid1][atid2] |= REPULSIVEPOWER_INTERACTION;
301 RepulsivePowerInteractionType* rpit =
302 dynamic_cast<RepulsivePowerInteractionType*>(nbiType);
303
304 repulsivePower_->addExplicitInteraction(
305 atype1, atype2, rpit->getSigma(), rpit->getEpsilon(),
306 rpit->getNrep());
307
308 vdwExplicit = true;
309 }
310
311 if (nbiType->isMie()) {
312 if (vdwExplicit) {
313 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
314 "InteractionManager::initialize found more than one "
315 "explicit \n"
316 "\tvan der Waals interaction for atom types %s - %s\n",
317 atype1->getName().c_str(), atype2->getName().c_str());
318 painCave.severity = OPENMD_ERROR;
319 painCave.isFatal = 1;
320 simError();
321 }
322 // We found an explicit Mie interaction.
323 // override all other vdw entries for this pair of atom types:
324 for (it = interactions_[atid1][atid2].begin();
325 it != interactions_[atid1][atid2].end();) {
326 InteractionFamily ifam = (*it)->getFamily();
327 if (ifam == VANDERWAALS_FAMILY) {
328 iHash_[atid1][atid2] ^= (*it)->getHash();
329 interactions_[atid1][atid2].erase(it++);
330 } else {
331 ++it;
332 }
333 }
334 interactions_[atid1][atid2].insert(mie_);
335 iHash_[atid1][atid2] |= MIE_INTERACTION;
336 MieInteractionType* mit =
337 dynamic_cast<MieInteractionType*>(nbiType);
338
339 mie_->addExplicitInteraction(atype1, atype2, mit->getSigma(),
340 mit->getEpsilon(), mit->getNrep(),
341 mit->getMatt());
342
343 vdwExplicit = true;
344 }
345
346 if (nbiType->isEAMTable() || nbiType->isEAMZhou()) {
347 // We found an explicit EAM interaction.
348 // override all other metallic entries for this pair of atom types:
349 for (it = interactions_[atid1][atid2].begin();
350 it != interactions_[atid1][atid2].end();) {
351 InteractionFamily ifam = (*it)->getFamily();
352 if (ifam == METALLIC_EMBEDDING_FAMILY) {
353 iHash_[atid1][atid2] ^= (*it)->getHash();
354 interactions_[atid1][atid2].erase(it++);
355 } else {
356 ++it;
357 }
358 }
359 interactions_[atid1][atid2].insert(eam_);
360 iHash_[atid1][atid2] |= EAM_INTERACTION;
361 metExplicit = true;
362 }
363
364 if (nbiType->isSC()) {
365 if (metExplicit) {
366 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
367 "InteractionManager::initialize found more than one "
368 "explicit\n"
369 "\tmetallic interaction for atom types %s - %s\n",
370 atype1->getName().c_str(), atype2->getName().c_str());
371 painCave.severity = OPENMD_ERROR;
372 painCave.isFatal = 1;
373 simError();
374 }
375 // We found an explicit Sutton-Chen interaction.
376 // override all other metallic entries for this pair of atom types:
377 for (it = interactions_[atid1][atid2].begin();
378 it != interactions_[atid1][atid2].end();) {
379 InteractionFamily ifam = (*it)->getFamily();
380 if (ifam == METALLIC_EMBEDDING_FAMILY) {
381 iHash_[atid1][atid2] ^= (*it)->getHash();
382 interactions_[atid1][atid2].erase(it++);
383 } else {
384 ++it;
385 }
386 }
387 interactions_[atid1][atid2].insert(sc_);
388 iHash_[atid1][atid2] |= SC_INTERACTION;
389 metExplicit = true;
390 }
391
392 if (nbiType->isMAW()) {
393 if (vdwExplicit) {
394 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
395 "InteractionManager::initialize found more than one "
396 "explicit\n"
397 "\tvan der Waals interaction for atom types %s - %s\n",
398 atype1->getName().c_str(), atype2->getName().c_str());
399 painCave.severity = OPENMD_ERROR;
400 painCave.isFatal = 1;
401 simError();
402 }
403 // We found an explicit MAW interaction.
404 // override all other vdw entries for this pair of atom types:
405 for (it = interactions_[atid1][atid2].begin();
406 it != interactions_[atid1][atid2].end();) {
407 InteractionFamily ifam = (*it)->getFamily();
408 if (ifam == VANDERWAALS_FAMILY) {
409 iHash_[atid1][atid2] ^= (*it)->getHash();
410 interactions_[atid1][atid2].erase(it++);
411 } else {
412 ++it;
413 }
414 }
415 interactions_[atid1][atid2].insert(maw_);
416 iHash_[atid1][atid2] |= MAW_INTERACTION;
417 MAWInteractionType* mit =
418 dynamic_cast<MAWInteractionType*>(nbiType);
419 maw_->addExplicitInteraction(atype1, atype2, mit->getD(),
420 mit->getBeta(), mit->getR(),
421 mit->getCA1(), mit->getCB1());
422 vdwExplicit = true;
423 }
424
425 if (nbiType->isInversePowerSeries()) {
426 if (vdwExplicit) {
427 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
428 "InteractionManager::initialize found more than one "
429 "explicit \n"
430 "\tvan der Waals interaction for atom types %s - %s\n",
431 atype1->getName().c_str(), atype2->getName().c_str());
432 painCave.severity = OPENMD_ERROR;
433 painCave.isFatal = 1;
434 simError();
435 }
436 // We found an explicit InversePowerSeries interaction.
437 // override all other vdw entries for this pair of atom types:
438 for (it = interactions_[atid1][atid2].begin();
439 it != interactions_[atid1][atid2].end();) {
440 InteractionFamily ifam = (*it)->getFamily();
441 if (ifam == VANDERWAALS_FAMILY) {
442 iHash_[atid1][atid2] ^= (*it)->getHash();
443 interactions_[atid1][atid2].erase(it++);
444 } else {
445 ++it;
446 }
447 }
448 interactions_[atid1][atid2].insert(inversePowerSeries_);
449 iHash_[atid1][atid2] |= INVERSEPOWERSERIES_INTERACTION;
450 InversePowerSeriesInteractionType* ipsit =
451 dynamic_cast<InversePowerSeriesInteractionType*>(nbiType);
452
453 inversePowerSeries_->addExplicitInteraction(
454 atype1, atype2, ipsit->getPowers(), ipsit->getCoefficients());
455 vdwExplicit = true;
456 }
457 }
458 }
459 }
460
461 // Make sure every pair of atom types in this simulation has a
462 // non-bonded interaction. If not, just inform the user.
463
464 AtomTypeSet simTypes = info_->getSimulatedAtomTypes();
465 AtomTypeSet::iterator bt;
466
467 for (at = simTypes.begin(); at != simTypes.end(); ++at) {
468 atype1 = (*at);
469 atid1 = atype1->getIdent();
470 for (bt = at; bt != simTypes.end(); ++bt) {
471 atype2 = (*bt);
472 atid2 = atype2->getIdent();
473
474 if (interactions_[atid1][atid2].size() == 0) {
475 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
476 "InteractionManager could not find a matching non-bonded\n"
477 "\tinteraction for atom types %s - %s\n"
478 "\tProceeding without this interaction.\n",
479 atype1->getName().c_str(), atype2->getName().c_str());
480 painCave.severity = OPENMD_INFO;
481 painCave.isFatal = 0;
482 simError();
483 }
484 }
485 }
486
487 initialized_ = true;
488 }
489
490 void InteractionManager::setCutoffRadius(RealType rcut) {
491 electrostatic_->setCutoffRadius(rcut);
492 eam_->setCutoffRadius(rcut);
493 }
494
495 void InteractionManager::doPrePair(InteractionData& idat) {
496 if (!initialized_) initialize();
497
498 // excluded interaction, so just return
499 if (idat.excluded) return;
500
501 int& iHash = iHash_[idat.atid1][idat.atid2];
502
503 if ((iHash & EAM_INTERACTION) != 0) eam_->calcDensity(idat);
504 if ((iHash & SC_INTERACTION) != 0) sc_->calcDensity(idat);
505
506 // set<NonBondedInteraction*>::iterator it;
507 //
508 // for (it = interactions_[ idat.atypes ].begin();
509 // it != interactions_[ idat.atypes ].end(); ++it){
510 // if ((*it)->getFamily() == METALLIC_EMBEDDING_FAMILY) {
511 // dynamic_cast<MetallicInteraction*>(*it)->calcDensity(idat);
512 // }
513 // }
514
515 return;
516 }
517
518 void InteractionManager::doPreForce(SelfData& sdat) {
519 if (!initialized_) initialize();
520
521 int& sHash = sHash_[sdat.atid];
522
523 if ((sHash & EAM_INTERACTION) != 0) eam_->calcFunctional(sdat);
524 if ((sHash & SC_INTERACTION) != 0) sc_->calcFunctional(sdat);
525
526 // set<NonBondedInteraction*>::iterator it;
527 //
528 // for (it = interactions_[atid1][atid2].begin();
529 // it != interactions_[atid1][atid2].end(); ++it){
530 // if ((*it)->getFamily() == METALLIC_EMBEDDING_FAMILY) {
531 // dynamic_cast<MetallicInteraction*>(*it)->calcFunctional(sdat);
532 // }
533 // }
534
535 return;
536 }
537
538 void InteractionManager::doPair(InteractionData& idat) {
539 if (!initialized_) initialize();
540
541 int& iHash = iHash_[idat.atid1][idat.atid2];
542
543 if ((iHash & ELECTROSTATIC_INTERACTION) != 0)
544 electrostatic_->calcForce(idat);
545
546 // electrostatics still has to worry about indirect
547 // contributions from excluded pairs of atoms, but nothing else does:
548
549 if (idat.excluded) return;
550
551 if ((iHash & LJ_INTERACTION) != 0) lj_->calcForce(idat);
552 if ((iHash & GB_INTERACTION) != 0) gb_->calcForce(idat);
553 if ((iHash & STICKY_INTERACTION) != 0) sticky_->calcForce(idat);
554 if ((iHash & MORSE_INTERACTION) != 0) morse_->calcForce(idat);
555 if ((iHash & REPULSIVEPOWER_INTERACTION) != 0)
556 repulsivePower_->calcForce(idat);
557 if ((iHash & MIE_INTERACTION) != 0) mie_->calcForce(idat);
558 if ((iHash & EAM_INTERACTION) != 0) eam_->calcForce(idat);
559 if ((iHash & SC_INTERACTION) != 0) sc_->calcForce(idat);
560 if ((iHash & MAW_INTERACTION) != 0) maw_->calcForce(idat);
561 if ((iHash & INVERSEPOWERSERIES_INTERACTION) != 0)
562 inversePowerSeries_->calcForce(idat);
563
564 // set<NonBondedInteraction*>::iterator it;
565 //
566 // for (it = interactions_[ idat.atypes ].begin();
567 // it != interactions_[ idat.atypes ].end(); ++it) {
568 //
569 // if (!idat.excluded || (*it)->getFamily() == ELECTROSTATIC_FAMILY) {
570 // (*it)->calcForce(idat);
571 // }
572 // }
573
574 return;
575 }
576
577 void InteractionManager::doSelfCorrection(SelfData& sdat) {
578 if (!initialized_) initialize();
579
580 int& sHash = sHash_[sdat.atid];
581
582 if ((sHash & ELECTROSTATIC_INTERACTION) != 0) {
583 electrostatic_->calcSelfCorrection(sdat);
584 }
585
586 // set<NonBondedInteraction*>::iterator it;
587 //
588 // for (it = interactions_[atid1][atid2].begin();
589 // it != interactions_[atid1][atid2].end(); ++it){
590 // if ((*it)->getFamily() == ELECTROSTATIC_FAMILY) {
591 // dynamic_cast<ElectrostaticInteraction*>(*it)->calcSelfCorrection(sdat);
592 // }
593 // }
594
595 return;
596 }
597
598 void InteractionManager::doSurfaceTerm(bool slabGeometry, int axis,
599 RealType& pot) {
600 if (!initialized_) initialize();
601 electrostatic_->calcSurfaceTerm(slabGeometry, axis, pot);
602 }
603
604 void InteractionManager::doReciprocalSpaceSum(RealType& pot) {
605 if (!initialized_) initialize();
606 electrostatic_->ReciprocalSpaceSum(pot);
607 }
608
609 RealType InteractionManager::getSuggestedCutoffRadius(int* atid) {
610 if (!initialized_) initialize();
611
612 AtomType* atype = typeMap_[*atid];
613
614 set<NonBondedInteractionPtr>::iterator it;
615 RealType cutoff = 0.0;
616
617 for (it = interactions_[*atid][*atid].begin();
618 it != interactions_[*atid][*atid].end(); ++it) {
619 cutoff =
620 max(cutoff, (*it)->getSuggestedCutoffRadius(make_pair(atype, atype)));
621 }
622 return cutoff;
623 }
624
625 RealType InteractionManager::getSuggestedCutoffRadius(AtomType* atype) {
626 if (!initialized_) initialize();
627
628 int atid = atype->getIdent();
629
630 set<NonBondedInteractionPtr>::iterator it;
631 RealType cutoff = 0.0;
632
633 for (it = interactions_[atid][atid].begin();
634 it != interactions_[atid][atid].end(); ++it) {
635 cutoff =
636 max(cutoff, (*it)->getSuggestedCutoffRadius(make_pair(atype, atype)));
637 }
638 return cutoff;
639 }
640} // namespace OpenMD
AtomType is what OpenMD looks to for unchanging data about an atom.
Definition AtomType.hpp:69
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
static const int ELECTROSTATIC_INTERACTION
Boolean flags for the iHash_ and sHash_ data structures.
InteractionFamily
The InteractionFamily enum.
@ VANDERWAALS_FAMILY
Long-range dispersion and short-range pauli repulsion.
@ METALLIC_EMBEDDING_FAMILY
Transition metal interactions involving electron density.
The InteractionData struct.
The SelfData struct.