47#include "types/FragmentStamp.hpp"
61 template<
class ContainerType>
62 bool hasDuplicateElement(
const ContainerType& cont) {
63 ContainerType tmp = cont;
64 std::sort(tmp.begin(), tmp.end());
65 tmp.erase(std::unique(tmp.begin(), tmp.end()), tmp.end());
66 return tmp.size() != cont.size();
69 FragmentStamp::FragmentStamp() { DefineParameter(Name,
"name"); }
71 FragmentStamp::~FragmentStamp() {
72 Utils::deletePointers(atomStamps_);
73 Utils::deletePointers(bondStamps_);
74 Utils::deletePointers(bendStamps_);
75 Utils::deletePointers(torsionStamps_);
76 Utils::deletePointers(inversionStamps_);
77 Utils::deletePointers(rigidBodyStamps_);
78 Utils::deletePointers(cutoffGroupStamps_);
79 Utils::deletePointers(nodesStamps_);
80 Utils::deletePointers(constraintStamps_);
83 bool FragmentStamp::addAtomStamp(
AtomStamp* atom) {
84 bool ret = addIndexSensitiveStamp(atomStamps_, atom);
86 std::ostringstream oss;
87 oss <<
"Error in Fragment " << getName()
88 <<
": multiple atoms have the same indices" << atom->getIndex()
90 throw OpenMDException(oss.str());
95 bool FragmentStamp::addBondStamp(
BondStamp* bond) {
96 bondStamps_.push_back(bond);
100 bool FragmentStamp::addBendStamp(
BendStamp* bend) {
101 bendStamps_.push_back(bend);
105 bool FragmentStamp::addTorsionStamp(
TorsionStamp* torsion) {
106 torsionStamps_.push_back(torsion);
109 bool FragmentStamp::addInversionStamp(
InversionStamp* inversion) {
110 inversionStamps_.push_back(inversion);
114 bool FragmentStamp::addRigidBodyStamp(
RigidBodyStamp* rigidbody) {
115 bool ret = addIndexSensitiveStamp(rigidBodyStamps_, rigidbody);
117 std::ostringstream oss;
118 oss <<
"Error in Fragment " << getName()
119 <<
": multiple rigidbodies have the same indices: "
120 << rigidbody->getIndex() <<
"\n";
121 throw OpenMDException(oss.str());
127 cutoffGroupStamps_.push_back(cutoffgroup);
131 bool FragmentStamp::addNodesStamp(
NodesStamp* nodes) {
132 nodesStamps_.push_back(nodes);
137 constraintStamps_.push_back(constraint);
141 void FragmentStamp::validate() {
142 DataHolder::validate();
143 CheckParameter(Name, isNotEmpty());
145 atom2Rigidbody.resize(getNAtoms());
151 for (
unsigned int i = 0; i < atom2Rigidbody.size(); ++i) {
152 atom2Rigidbody[i] = -1 - int(i);
154 for (std::size_t i = 0; i < getNRigidBodies(); ++i) {
155 RigidBodyStamp* rbStamp = getRigidBodyStamp(i);
156 std::vector<int> members = rbStamp->getMembers();
157 for (std::vector<int>::iterator j = members.begin(); j != members.end();
159 atom2Rigidbody[*j] = i;
174 void FragmentStamp::checkAtoms() {
175 std::vector<AtomStamp*>::iterator ai = std::find(
176 atomStamps_.begin(), atomStamps_.end(),
static_cast<AtomStamp*
>(NULL));
177 if (ai != atomStamps_.end()) {
178 std::ostringstream oss;
179 oss <<
"Error in Fragment " << getName() <<
": atom["
180 << ai - atomStamps_.begin() <<
"] is missing\n";
181 throw OpenMDException(oss.str());
185 void FragmentStamp::checkBonds() {
186 std::ostringstream oss;
188 int natoms = getNAtoms();
189 for (std::size_t i = 0; i < getNBonds(); ++i) {
190 BondStamp* bondStamp = getBondStamp(i);
191 if (bondStamp->getA() > natoms - 1 || bondStamp->getA() < 0 ||
192 bondStamp->getB() > natoms - 1 || bondStamp->getB() < 0 ||
193 bondStamp->getA() == bondStamp->getB()) {
194 oss <<
"Error in Fragment " << getName() <<
": bond("
195 << bondStamp->getA() <<
", " << bondStamp->getB()
197 throw OpenMDException(oss.str());
202 std::set<std::pair<int, int>> allBonds;
203 for (std::size_t i = 0; i < getNBonds(); ++i) {
204 BondStamp* bondStamp = getBondStamp(i);
205 std::pair<int, int> bondPair(bondStamp->getA(), bondStamp->getB());
208 if (bondPair.first > bondPair.second) {
209 std::swap(bondPair.first, bondPair.second);
212 std::set<std::pair<int, int>>::iterator iter = allBonds.find(bondPair);
213 if (iter != allBonds.end()) {
214 oss <<
"Error in Fragment " << getName() <<
": "
215 <<
"bond(" << iter->first <<
", " << iter->second
216 <<
") appears multiple times\n";
217 throw OpenMDException(oss.str());
219 allBonds.insert(bondPair);
224 for (std::size_t i = 0; i < getNBonds(); ++i) {
225 BondStamp* bondStamp = getBondStamp(i);
226 if (atom2Rigidbody[bondStamp->getA()] ==
227 atom2Rigidbody[bondStamp->getB()]) {
228 oss <<
"Error in Fragment " << getName() <<
": "
229 <<
"bond(" << bondStamp->getA() <<
", " << bondStamp->getB()
230 <<
") belong to same rigidbody "
231 << atom2Rigidbody[bondStamp->getA()] <<
"\n";
232 throw OpenMDException(oss.str());
237 void FragmentStamp::checkBends() {
238 std::ostringstream oss;
239 for (std::size_t i = 0; i < getNBends(); ++i) {
240 BendStamp* bendStamp = getBendStamp(i);
241 std::vector<int> bendAtoms = bendStamp->getMembers();
242 std::vector<int>::iterator j = std::find_if(
243 bendAtoms.begin(), bendAtoms.end(),
244 std::bind(std::greater<int>(), placeholders::_1, getNAtoms() - 1));
245 std::vector<int>::iterator k =
246 std::find_if(bendAtoms.begin(), bendAtoms.end(),
247 std::bind(std::less<int>(), placeholders::_1, 0));
249 if (j != bendAtoms.end() || k != bendAtoms.end()) {
250 oss <<
"Error in Fragment " << getName() <<
" : atoms of bend"
251 << containerToString(bendAtoms) <<
" have invalid indices\n";
252 throw OpenMDException(oss.str());
255 if (hasDuplicateElement(bendAtoms)) {
256 oss <<
"Error in Fragment " << getName() <<
" : atoms of bend"
257 << containerToString(bendAtoms) <<
" have duplicated indices\n";
258 throw OpenMDException(oss.str());
261 if (bendAtoms.size() == 2) {
262 if (!bendStamp->haveGhostVectorSource()) {
263 oss <<
"Error in Fragment " << getName()
264 <<
": ghostVectorSouce is missing\n";
265 throw OpenMDException(oss.str());
267 std::size_t ghostIndex = bendStamp->getGhostVectorSource();
268 if (ghostIndex < getNAtoms()) {
269 if (std::find(bendAtoms.begin(), bendAtoms.end(), ghostIndex) ==
271 oss <<
"Error in Fragment " << getName() <<
": ghostVectorSouce "
272 << ghostIndex <<
"is invalid\n";
273 throw OpenMDException(oss.str());
275 if (!getAtomStamp(ghostIndex)->haveOrientation()) {
276 oss <<
"Error in Fragment " << getName()
277 <<
": ghost atom must be a directional atom\n";
278 throw OpenMDException(oss.str());
281 oss <<
"Error in Fragment " << getName() <<
": ghostVectorSource "
282 << ghostIndex <<
" is invalid\n";
283 throw OpenMDException(oss.str());
286 }
else if (bendAtoms.size() == 3 && bendStamp->haveGhostVectorSource()) {
287 oss <<
"Error in Fragment " << getName()
288 <<
": normal bend should not have ghostVectorSouce\n";
289 throw OpenMDException(oss.str());
293 for (std::size_t i = 0; i < getNBends(); ++i) {
294 BendStamp* bendStamp = getBendStamp(i);
295 std::vector<int> bendAtoms = bendStamp->getMembers();
296 std::vector<int> rigidSet(getNRigidBodies(), 0);
297 std::vector<int>::iterator j;
298 for (j = bendAtoms.begin(); j != bendAtoms.end(); ++j) {
299 int rigidbodyIndex = atom2Rigidbody[*j];
300 if (rigidbodyIndex >= 0) {
301 ++rigidSet[rigidbodyIndex];
302 if (rigidSet[rigidbodyIndex] > 2) {
303 oss <<
"Error in Fragment " << getName() <<
": bend"
304 << containerToString(bendAtoms)
305 <<
"has three atoms on the same rigid body\n";
306 throw OpenMDException(oss.str());
312 std::set<std::tuple<int, int, int>> allBends;
313 std::set<std::tuple<int, int, int>>::iterator iter;
314 for (std::size_t i = 0; i < getNBends(); ++i) {
315 BendStamp* bendStamp = getBendStamp(i);
316 std::vector<int> bend = bendStamp->getMembers();
317 if (bend.size() == 2) {
331 int ghostIndex = bendStamp->getGhostVectorSource();
332 std::vector<int>::iterator j =
333 std::find(bend.begin(), bend.end(), ghostIndex);
334 if (j != bend.end()) { bend.insert(j, ghostIndex); }
337 std::tuple<int, int, int> bendTuple {bend[0], bend[1], bend[2]};
338 auto& [first, second, third] = bendTuple;
342 if (first > third) { std::swap(first, third); }
344 iter = allBends.find(bendTuple);
345 if (iter != allBends.end()) {
346 oss <<
"Error in Fragment " << getName() <<
": "
347 <<
"Bend" << containerToString(bend) <<
" appears multiple times\n";
348 throw OpenMDException(oss.str());
350 allBends.insert(bendTuple);
355 void FragmentStamp::checkTorsions() {
356 std::ostringstream oss;
357 for (std::size_t i = 0; i < getNTorsions(); ++i) {
358 TorsionStamp* torsionStamp = getTorsionStamp(i);
359 std::vector<int> torsionAtoms = torsionStamp->getMembers();
360 std::vector<int>::iterator j = std::find_if(
361 torsionAtoms.begin(), torsionAtoms.end(),
362 std::bind(std::greater<int>(), placeholders::_1, getNAtoms() - 1));
363 std::vector<int>::iterator k =
364 std::find_if(torsionAtoms.begin(), torsionAtoms.end(),
365 std::bind(std::less<int>(), placeholders::_1, 0));
367 if (j != torsionAtoms.end() || k != torsionAtoms.end()) {
368 oss <<
"Error in Fragment " << getName() <<
": atoms of torsion"
369 << containerToString(torsionAtoms) <<
" have invalid indices\n";
370 throw OpenMDException(oss.str());
372 if (hasDuplicateElement(torsionAtoms)) {
373 oss <<
"Error in Fragment " << getName() <<
" : atoms of torsion"
374 << containerToString(torsionAtoms) <<
" have duplicated indices\n";
375 throw OpenMDException(oss.str());
379 for (std::size_t i = 0; i < getNTorsions(); ++i) {
380 TorsionStamp* torsionStamp = getTorsionStamp(i);
381 std::vector<int> torsionAtoms = torsionStamp->getMembers();
382 std::vector<int> rigidSet(getNRigidBodies(), 0);
383 std::vector<int>::iterator j;
384 for (j = torsionAtoms.begin(); j != torsionAtoms.end(); ++j) {
385 int rigidbodyIndex = atom2Rigidbody[*j];
386 if (rigidbodyIndex >= 0) {
387 ++rigidSet[rigidbodyIndex];
388 if (rigidSet[rigidbodyIndex] > 3) {
389 oss <<
"Error in Fragment " << getName() <<
": torsion"
390 << containerToString(torsionAtoms)
391 <<
"has four atoms on the same rigid body\n";
392 throw OpenMDException(oss.str());
398 std::set<std::tuple<int, int, int, int>> allTorsions;
399 std::set<std::tuple<int, int, int, int>>::iterator iter;
400 for (std::size_t i = 0; i < getNTorsions(); ++i) {
401 TorsionStamp* torsionStamp = getTorsionStamp(i);
402 std::vector<int> torsion = torsionStamp->getMembers();
403 if (torsion.size() == 3) {
404 int ghostIndex = torsionStamp->getGhostVectorSource();
405 std::vector<int>::iterator j =
406 std::find(torsion.begin(), torsion.end(), ghostIndex);
407 if (j != torsion.end()) { torsion.insert(j, ghostIndex); }
410 std::tuple<int, int, int, int> torsionTuple(torsion[0], torsion[1],
411 torsion[2], torsion[3]);
412 auto& [first, second, third, fourth] = torsionTuple;
414 if (first > fourth) {
415 std::swap(first, fourth);
416 std::swap(second, third);
419 iter = allTorsions.find(torsionTuple);
420 if (iter == allTorsions.end()) {
421 allTorsions.insert(torsionTuple);
423 oss <<
"Error in Fragment " << getName() <<
": "
424 <<
"Torsion" << containerToString(torsion)
425 <<
" appears multiple times\n";
426 throw OpenMDException(oss.str());
431 void FragmentStamp::checkInversions() {
432 std::ostringstream oss;
437 for (std::size_t i = 0; i < getNInversions(); ++i) {
438 InversionStamp* inversionStamp = getInversionStamp(i);
439 int center = inversionStamp->getCenter();
440 std::vector<int> satellites;
445 if (inversionStamp->getNSatellites() != 3) {
446 for (std::size_t j = 0; j < getNBonds(); ++j) {
447 BondStamp* bondStamp = getBondStamp(j);
448 int a = bondStamp->getA();
449 int b = bondStamp->getB();
451 if (a == center) { satellites.push_back(b); }
452 if (b == center) { satellites.push_back(a); }
455 if (satellites.size() == 3) {
456 std::sort(satellites.begin(), satellites.end());
457 inversionStamp->setSatellites(satellites);
459 oss <<
"Error in Fragment " << getName() <<
": found wrong number"
460 <<
" of bonds for inversion center " << center;
461 throw OpenMDException(oss.str());
468 for (std::size_t i = 0; i < getNInversions(); ++i) {
469 InversionStamp* inversionStamp = getInversionStamp(i);
471 std::vector<int> inversionAtoms = inversionStamp->getSatellites();
473 inversionAtoms.insert(inversionAtoms.begin(),
474 inversionStamp->getCenter());
476 std::vector<int>::iterator j = std::find_if(
477 inversionAtoms.begin(), inversionAtoms.end(),
478 std::bind(std::greater<int>(), placeholders::_1, getNAtoms() - 1));
479 std::vector<int>::iterator k =
480 std::find_if(inversionAtoms.begin(), inversionAtoms.end(),
481 std::bind(std::less<int>(), placeholders::_1, 0));
483 if (j != inversionAtoms.end() || k != inversionAtoms.end()) {
484 oss <<
"Error in Fragment " << getName() <<
": atoms of inversion"
485 << containerToString(inversionAtoms) <<
" have invalid indices\n";
486 throw OpenMDException(oss.str());
489 if (hasDuplicateElement(inversionAtoms)) {
490 oss <<
"Error in Fragment " << getName() <<
" : atoms of inversion"
491 << containerToString(inversionAtoms)
492 <<
" have duplicated indices\n";
493 throw OpenMDException(oss.str());
497 for (std::size_t i = 0; i < getNInversions(); ++i) {
498 InversionStamp* inversionStamp = getInversionStamp(i);
499 std::vector<int> inversionAtoms = inversionStamp->getSatellites();
500 inversionAtoms.push_back(inversionStamp->getCenter());
501 std::vector<int> rigidSet(getNRigidBodies(), 0);
502 std::vector<int>::iterator j;
503 for (j = inversionAtoms.begin(); j != inversionAtoms.end(); ++j) {
504 int rigidbodyIndex = atom2Rigidbody[*j];
505 if (rigidbodyIndex >= 0) {
506 ++rigidSet[rigidbodyIndex];
507 if (rigidSet[rigidbodyIndex] > 3) {
508 oss <<
"Error in Fragment " << getName()
509 <<
": inversion centered on atom "
510 << inversionStamp->getCenter()
511 <<
" has four atoms that belong to same rigidbody "
512 << rigidbodyIndex <<
"\n";
513 throw OpenMDException(oss.str());
519 std::set<std::tuple<int, int, int, int>> allInversions;
520 std::set<std::tuple<int, int, int, int>>::iterator iter;
521 for (std::size_t i = 0; i < getNInversions(); ++i) {
522 InversionStamp* inversionStamp = getInversionStamp(i);
523 int cent = inversionStamp->getCenter();
524 std::vector<int> inversion = inversionStamp->getSatellites();
526 std::tuple<int, int, int, int> inversionTuple(cent, inversion[0],
527 inversion[1], inversion[2]);
528 auto& [first, second, third, fourth] = inversionTuple;
535 if (third > fourth) std::swap(third, fourth);
536 if (second > third) std::swap(second, third);
537 if (third > fourth) std::swap(third, fourth);
539 iter = allInversions.find(inversionTuple);
540 if (iter == allInversions.end()) {
541 allInversions.insert(inversionTuple);
543 oss <<
"Error in Fragment " << getName() <<
": "
544 <<
"Inversion" << containerToString(inversion)
545 <<
" appears multiple times\n";
546 throw OpenMDException(oss.str());
551 void FragmentStamp::checkRigidBodies() {
552 std::ostringstream oss;
553 std::vector<RigidBodyStamp*>::iterator ri =
554 std::find(rigidBodyStamps_.begin(), rigidBodyStamps_.end(),
555 static_cast<RigidBodyStamp*
>(NULL));
556 if (ri != rigidBodyStamps_.end()) {
557 oss <<
"Error in Fragment " << getName() <<
":rigidBody["
558 << ri - rigidBodyStamps_.begin() <<
"] is missing\n";
559 throw OpenMDException(oss.str());
562 for (std::size_t i = 0; i < getNRigidBodies(); ++i) {
563 RigidBodyStamp* rbStamp = getRigidBodyStamp(i);
564 std::vector<int> rigidAtoms = rbStamp->getMembers();
565 std::vector<int>::iterator j = std::find_if(
566 rigidAtoms.begin(), rigidAtoms.end(),
567 std::bind(std::greater<int>(), placeholders::_1, getNAtoms() - 1));
568 if (j != rigidAtoms.end()) {
569 oss <<
"Error in Fragment " << getName();
570 throw OpenMDException(oss.str());
575 void FragmentStamp::checkCutoffGroups() {
576 std::vector<AtomStamp*>::iterator ai;
577 std::vector<int>::iterator fai;
580 for (ai = atomStamps_.begin(); ai != atomStamps_.end(); ++ai) {
581 freeAtoms_.push_back((*ai)->getIndex());
584 for (std::size_t i = 0; i < getNCutoffGroups(); ++i) {
585 CutoffGroupStamp* cutoffGroupStamp = getCutoffGroupStamp(i);
586 std::vector<int> cutoffGroupAtoms = cutoffGroupStamp->getMembers();
587 std::vector<int>::iterator j = std::find_if(
588 cutoffGroupAtoms.begin(), cutoffGroupAtoms.end(),
589 std::bind(std::greater<int>(), placeholders::_1, getNAtoms() - 1));
590 if (j != cutoffGroupAtoms.end()) {
591 std::ostringstream oss;
592 oss <<
"Error in Fragment " << getName() <<
": cutoffGroup"
593 <<
" is out of range\n";
594 throw OpenMDException(oss.str());
597 for (fai = cutoffGroupAtoms.begin(); fai != cutoffGroupAtoms.end();
601 std::remove(freeAtoms_.begin(), freeAtoms_.end(), (*fai)),
607 void FragmentStamp::checkConstraints() {
608 std::ostringstream oss;
610 int natoms = getNAtoms();
611 for (std::size_t i = 0; i < getNConstraints(); ++i) {
612 ConstraintStamp* constraintStamp = getConstraintStamp(i);
613 if (constraintStamp->getA() > natoms - 1 || constraintStamp->getA() < 0 ||
614 constraintStamp->getB() > natoms - 1 || constraintStamp->getB() < 0 ||
615 constraintStamp->getA() == constraintStamp->getB()) {
616 oss <<
"Error in Fragment " << getName() <<
": constraint("
617 << constraintStamp->getA() <<
", " << constraintStamp->getB()
619 throw OpenMDException(oss.str());
624 std::set<std::pair<int, int>> allConstraints;
625 for (std::size_t i = 0; i < getNConstraints(); ++i) {
626 ConstraintStamp* constraintStamp = getConstraintStamp(i);
627 std::pair<int, int> constraintPair(constraintStamp->getA(),
628 constraintStamp->getB());
631 if (constraintPair.first > constraintPair.second) {
632 std::swap(constraintPair.first, constraintPair.second);
635 std::set<std::pair<int, int>>::iterator iter =
636 allConstraints.find(constraintPair);
637 if (iter != allConstraints.end()) {
638 oss <<
"Error in Fragment " << getName() <<
": "
639 <<
"constraint(" << iter->first <<
", " << iter->second
640 <<
") appears multiple times\n";
641 throw OpenMDException(oss.str());
643 allConstraints.insert(constraintPair);
649 for (std::size_t i = 0; i < getNConstraints(); ++i) {
650 ConstraintStamp* constraintStamp = getConstraintStamp(i);
651 if (atom2Rigidbody[constraintStamp->getA()] ==
652 atom2Rigidbody[constraintStamp->getB()]) {
653 oss <<
"Error in Fragment " << getName() <<
": "
654 <<
"constraint(" << constraintStamp->getA() <<
", "
655 << constraintStamp->getB() <<
") belong to same rigidbody "
656 << atom2Rigidbody[constraintStamp->getA()] <<
"\n";
657 throw OpenMDException(oss.str());
662 void FragmentStamp::checkNodes() {
663 std::ostringstream oss;
664 std::vector<NodesStamp*>::iterator ni =
665 std::find(nodesStamps_.begin(), nodesStamps_.end(),
666 static_cast<NodesStamp*
>(NULL));
667 if (ni != nodesStamps_.end()) {
668 oss <<
"Error in Molecule " << getName() <<
":nodes["
669 << ni - nodesStamps_.begin() <<
"] is missing\n";
670 throw OpenMDException(oss.str());
673 for (std::size_t i = 0; i < getNNodes(); ++i) {
674 NodesStamp* nStamp = getNodesStamp(i);
675 std::vector<int> nodeAtoms = nStamp->getMembers();
676 std::vector<int>::iterator j = std::find_if(
677 nodeAtoms.begin(), nodeAtoms.end(),
678 std::bind(std::greater<int>(), placeholders::_1, getNAtoms() - 1));
679 if (j != nodeAtoms.end()) {
680 oss <<
"Error in Fragment " << getName();
681 throw OpenMDException(oss.str());
686 void FragmentStamp::fillBondInfo() {
687 for (std::size_t i = 0; i < getNBonds(); ++i) {
688 BondStamp* bondStamp = getBondStamp(i);
689 int a = bondStamp->getA();
690 int b = bondStamp->getB();
691 AtomStamp* atomA = getAtomStamp(a);
692 AtomStamp* atomB = getAtomStamp(b);
694 atomA->addBondedAtom(b);
696 atomB->addBondedAtom(a);
703 bool FragmentStamp::isBondInSameRigidBody(
BondStamp* bond) {
709 if (!isAtomInRigidBody(bond->getA(), rbA, consAtomA))
return false;
711 if (!isAtomInRigidBody(bond->getB(), rbB, consAtomB))
return false;
722 bool FragmentStamp::isAtomInRigidBody(
int atomIndex) {
723 return atom2Rigidbody[atomIndex] >= 0;
733 bool FragmentStamp::isAtomInRigidBody(
int atomIndex,
int& whichRigidBody,
734 int& consAtomIndex) {
738 if (atom2Rigidbody[atomIndex] >= 0) {
739 whichRigidBody = atom2Rigidbody[atomIndex];
740 RigidBodyStamp* rbStamp = getRigidBodyStamp(whichRigidBody);
741 int numAtom = rbStamp->getNMembers();
742 for (
int j = 0; j < numAtom; j++) {
743 if (rbStamp->getMemberAt(j) == atomIndex) {
758 std::vector<std::pair<int, int>> FragmentStamp::getJointAtoms(
int rb1,
760 RigidBodyStamp* rbStamp1;
761 RigidBodyStamp* rbStamp2;
766 std::vector<std::pair<int, int>> jointAtomIndexPair;
768 rbStamp1 = this->getRigidBodyStamp(rb1);
769 natomInRb1 = rbStamp1->getNMembers();
771 rbStamp2 = this->getRigidBodyStamp(rb2);
772 natomInRb2 = rbStamp2->getNMembers();
774 for (
int i = 0; i < natomInRb1; i++) {
775 atomIndex1 = rbStamp1->getMemberAt(i);
777 for (
int j = 0; j < natomInRb2; j++) {
778 atomIndex2 = rbStamp2->getMemberAt(j);
780 if (atomIndex1 == atomIndex2) {
781 jointAtomIndexPair.push_back(std::make_pair(i, j));
787 return jointAtomIndexPair;
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.