void Rattle::constraintB() { if (!doRattle_) return; doConstraint(&Rattle::constraintPairB); if (currentSnapshot_->getTime() >= currConstraintTime_){ Molecule* mol; SimInfo::MoleculeIterator mi; ConstraintPair* consPair; Molecule::ConstraintPairIterator cpi; std::list<ConstraintPair*> constraints; for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) { for (consPair = mol->beginConstraintPair(cpi); consPair != NULL; consPair = mol->nextConstraintPair(cpi)) { constraints.push_back(consPair); } } constraintWriter_->writeConstraintForces(constraints); currConstraintTime_ += constraintTime_; } }
void Shake::doConstraint(ConstraintPairFuncPtr func) { if (!doShake_) return; Molecule* mol; SimInfo::MoleculeIterator mi; ConstraintElem* consElem; Molecule::ConstraintElemIterator cei; ConstraintPair* consPair; Molecule::ConstraintPairIterator cpi; for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) { for (consElem = mol->beginConstraintElem(cei); consElem != NULL; consElem = mol->nextConstraintElem(cei)) { consElem->setMoved(true); consElem->setMoving(false); } } //main loop of constraint algorithm int done = 0; int iteration = 0; while(!done && iteration < maxConsIteration_){ done = 1; //loop over every constraint pair for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) { for (consPair = mol->beginConstraintPair(cpi); consPair != NULL; consPair = mol->nextConstraintPair(cpi)) { //dispatch constraint algorithm if(consPair->isMoved()) { int exeStatus = (this->*func)(consPair); switch(exeStatus){ case consFail: sprintf(painCave.errMsg, "Constraint failure in Shake::constrainA, " "Constraint Fail\n"); painCave.isFatal = 1; simError(); break; case consSuccess: // constrain the pair by moving two elements done = 0; consPair->getConsElem1()->setMoving(true); consPair->getConsElem2()->setMoving(true); break; case consAlready: // current pair is already constrained, do not need to // move the elements break; default: sprintf(painCave.errMsg, "ConstraintAlgorithm::doConstraint() " "Error: unrecognized status"); painCave.isFatal = 1; simError(); break; } } } }//end for(iter->first()) #ifdef IS_MPI MPI_Allreduce(MPI_IN_PLACE, &done, 1, MPI_INT, MPI_LAND, MPI_COMM_WORLD); #endif errorCheckPoint(); for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) { for (consElem = mol->beginConstraintElem(cei); consElem != NULL; consElem = mol->nextConstraintElem(cei)) { consElem->setMoved(consElem->getMoving()); consElem->setMoving(false); } } iteration++; }//end while if (!done){ sprintf(painCave.errMsg, "Constraint failure in Shake::constrainA, " "too many iterations: %d\n", iteration); painCave.isFatal = 1; simError(); } errorCheckPoint(); }