Ignore:
Timestamp:
Aug 14, 2017, 8:12:49 AM (8 years ago)
Author:
Frederik Heber <frederik.heber@…>
Branches:
ForceAnnealing_with_BondGraph_continued
Children:
a6574a
Parents:
0cc08c
git-author:
Frederik Heber <frederik.heber@…> (08/10/17 15:35:45)
git-committer:
Frederik Heber <frederik.heber@…> (08/14/17 08:12:49)
Message:

Rewrote annealWithBondGraph_BarzilaiBorwein() to simply distinguish expansion and contraction in bonds.

  • we shift the neighboring set away in case of expansion and towards in case of contraction.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Dynamics/ForceAnnealing.hpp

    r0cc08c r08df4a  
    185185                        "ForceAnnealing::anneal() - if currentStep is "+toString(currentStep)
    186186                        +", then there should be at least three time steps.");
    187               const Vector oldPosition = (*iter)->getPositionAtStep(OldTimeStep);
     187              const Vector &oldPosition = (*iter)->getPositionAtStep(OldTimeStep);
    188188              const Vector PositionDifference = currentPosition - oldPosition;
    189189        LOG(4, "DEBUG: oldPosition for atom #" << (*iter)->getId() << " is " << oldPosition);
     
    237237        iter != AtomicForceManipulator<T>::atoms.end(); ++iter) {
    238238      // atom's force vector gives steepest descent direction
    239       const Vector oldPosition = (*iter)->getPositionAtStep(OldTimeStep);
    240       const Vector currentPosition = (*iter)->getPositionAtStep(CurrentTimeStep);
    241       const Vector oldGradient = (*iter)->getAtomicForceAtStep(OldTimeStep);
    242       const Vector currentGradient = (*iter)->getAtomicForceAtStep(CurrentTimeStep);
     239      const Vector &oldPosition = (*iter)->getPositionAtStep(OldTimeStep);
     240      const Vector &currentPosition = (*iter)->getPositionAtStep(CurrentTimeStep);
     241      const Vector &oldGradient = (*iter)->getAtomicForceAtStep(OldTimeStep);
     242      const Vector &currentGradient = (*iter)->getAtomicForceAtStep(CurrentTimeStep);
    243243      LOG(4, "DEBUG: oldPosition for atom #" << (*iter)->getId() << " is " << oldPosition);
    244244      LOG(4, "DEBUG: currentPosition for atom #" << (*iter)->getId() << " is " << currentPosition);
     
    291291  }
    292292
    293   // knowing the number of bonds in total, we can setup the storage for the
    294   // projected forces
    295   enum whichatom_t {
    296     leftside=0,
    297     rightside=1,
    298     MAX_sides
    299   };
    300 
    301   /** Helper function to put bond force into a container.
    302    *
    303    * \param _walker atom
    304    * \param _current_bond current bond of \a _walker
    305    * \param _timestep time step
    306    * \param _force calculated bond force
    307    * \param _bv bondvectors for obtaining the correct index
    308    * \param _projected_forces container
    309    */
    310   static void ForceStore(
    311       const atom &_walker,
    312       const bond::ptr &_current_bond,
    313       const size_t &_timestep,
    314       const double _force,
    315       const BondVectors &_bv,
    316       std::vector< // time step
    317             std::vector< // which bond side
    318               std::vector<double> > // over all bonds
    319                 > &_projected_forces)
    320   {
    321     std::vector<double> &forcelist = (&_walker == _current_bond->leftatom) ?
    322         _projected_forces[_timestep][leftside] : _projected_forces[_timestep][rightside];
    323     const size_t index = _bv.getIndexForBond(_current_bond);
    324     ASSERT( index != (size_t)-1,
    325         "ForceAnnealing() - could not find bond "+toString(*_current_bond)
    326         +" in bondvectors");
    327     forcelist[index] = _force;
    328   }
    329 
    330293  /** Performs Gradient optimization on the bonds with BarzilaiBorwein stepwdith.
    331294   *
     
    364327    BreadthFirstSearchGatherer NodeGatherer(BGcreator);
    365328
    366     /// We assume that a force is local, i.e. a bond is too short yet and hence
    367     /// the atom needs to be moved. However, all the adjacent (bound) atoms might
    368     /// already be at the perfect distance. If we just move the atom alone, we ruin
    369     /// all the other bonds. Hence, it would be sensible to move every atom found
    370     /// through the bond graph in the direction of the force as well by the same
    371     /// PositionUpdate. This is almost what we are going to do.
    372 
    373     /// One issue is: If we need to shorten bond, then we use the PositionUpdate
    374     /// also on the the other bond partner already. This is because it is in the
    375     /// direction of the bond. Therefore, the update is actually performed twice on
    376     /// each bond partner, i.e. the step size is twice as large as it should be.
    377     /// This problem only occurs when bonds need to be shortened, not when they
    378     /// need to be made longer (then the force vector is facing the other
    379     /// direction than the bond vector).
    380     /// As a remedy we need to average the force on either end of the bond and
    381     /// check whether each gradient points inwards out or outwards with respect
    382     /// to the bond and then shift accordingly.
    383 
    384     /// One more issue is that the projection onto the bond directions does not
    385     /// recover the gradient but may be larger as the bond directions are a
    386     /// generating system and not a basis (e.g. 3 bonds on a plane where 2 would
    387     /// suffice to span the plane). To this end, we need to account for the
    388     /// overestimation and obtain a weighting for each bond.
     329    /** We assume that a force is local, i.e. a bond is too short yet and hence
     330     * the atom needs to be moved. However, all the adjacent (bound) atoms might
     331     * already be at the perfect distance. If we just move the atom alone, we ruin
     332     * all the other bonds. Hence, it would be sensible to move every atom found
     333     * through the bond graph in the direction of the force as well by the same
     334     * PositionUpdate. This is almost what we are going to do, see below.
     335     *
     336     * This is to make the force a little more global in the sense of a multigrid
     337     * solver that uses various coarser grids to transport errors more effectively
     338     * over finely resolved grids.
     339     *
     340     */
     341
     342    /** The idea is that we project the gradients onto the bond vectors and determine
     343     * from the sum of projected gradients from either side whether the bond is
     344     * to contract or to expand. As the gradient acting as the normal vector of
     345     * a plane supported at the position of the atom separates all bonds into two
     346     * sets, we check whether all on one side are contracting and all on the other
     347     * side are expanding. In this case we may move not only the atom itself but
     348     * may propagate its update along a limited-horizon BFS to neighboring atoms.
     349     *
     350     */
    389351
    390352    // initialize helper class for bond vectors using bonds from range of atoms
     
    394356        AtomicForceManipulator<T>::atoms.end(),
    395357        _TimeStep);
    396     const BondVectors::container_t &sorted_bonds = bv.getSorted();
    397 
    398     std::vector< // time step
    399       std::vector< // which bond side
    400         std::vector<double> > // over all bonds
    401           > projected_forces(2); // one for leftatoms, one for rightatoms (and for both time steps)
    402     for (size_t i=0;i<2;++i) {
    403       projected_forces[i].resize(MAX_sides);
    404       for (size_t j=0;j<MAX_sides;++j)
    405         projected_forces[i][j].resize(sorted_bonds.size(), 0.);
     358
     359    std::vector< // which bond side
     360      std::vector<double> > // over all bonds
     361        projected_forces; // one for leftatoms, one for rightatoms
     362    projected_forces.resize(BondVectors::MAX_sides);
     363    for (size_t j=0;j<BondVectors::MAX_sides;++j)
     364      projected_forces[j].resize(bv.size(), 0.);
     365
     366    // for each atom we need to project the gradient
     367    for(typename AtomSetMixin<T>::const_iterator iter = AtomicForceManipulator<T>::atoms.begin();
     368        iter != AtomicForceManipulator<T>::atoms.end(); ++iter) {
     369      const atom &walker = *(*iter);
     370      const Vector &walkerGradient = walker.getAtomicForceAtStep(CurrentTimeStep);
     371      const double GradientNorm = walkerGradient.Norm();
     372      LOG(3, "DEBUG: Gradient of atom #" << walker.getId() << ", namely "
     373          << walker << " is " << walkerGradient << " with magnitude of "
     374          << GradientNorm);
     375
     376      if (GradientNorm > MYEPSILON) {
     377        bv.getProjectedGradientsForAtomAtStep(
     378            walker, walkerGradient, CurrentTimeStep, projected_forces
     379        );
     380      } else {
     381        LOG(2, "DEBUG: Gradient is " << walkerGradient << " less than "
     382            << MYEPSILON << " for atom " << walker);
     383        // note that projected_forces is initialized to full length and filled
     384        // with zeros. Hence, nothing to do here
     385      }
    406386    }
    407387
    408     // for each atom we need to gather weights and then project the gradient
    409     typedef std::map<atomId_t, BondVectors::weights_t > weights_per_atom_t;
    410     std::vector<weights_per_atom_t> weights_per_atom(2);
    411     typedef std::map<atomId_t, Vector> RemnantGradient_per_atom_t;
    412     RemnantGradient_per_atom_t RemnantGradient_per_atom;
    413     for (size_t timestep = 0; timestep <= 1; ++timestep) {
    414       const size_t ReferenceTimeStep = _TimeStep-timestep-1;
    415       LOG(2, "DEBUG: given time step is " << _TimeStep
    416           << ", timestep is " << timestep
    417           << ", and ReferenceTimeStep is " << ReferenceTimeStep);
    418 
    419       for(typename AtomSetMixin<T>::const_iterator iter = AtomicForceManipulator<T>::atoms.begin();
    420           iter != AtomicForceManipulator<T>::atoms.end(); ++iter) {
    421         const atom &walker = *(*iter);
    422         const Vector &walkerGradient = walker.getAtomicForceAtStep(ReferenceTimeStep);
    423         LOG(3, "DEBUG: Gradient of atom #" << walker.getId() << ", namely "
    424             << walker << " is " << walkerGradient << " with magnitude of "
    425             << walkerGradient.Norm());
    426 
     388    std::map<atomId_t, Vector> GatheredUpdates; //!< gathers all updates which are applied at the end
     389    for(typename AtomSetMixin<T>::iterator iter = AtomicForceManipulator<T>::atoms.begin();
     390        iter != AtomicForceManipulator<T>::atoms.end(); ++iter) {
     391      atom &walker = *(*iter);
     392
     393      /// calculate step width
     394      const Vector &oldPosition = (*iter)->getPositionAtStep(OldTimeStep);
     395      const Vector &currentPosition = (*iter)->getPositionAtStep(CurrentTimeStep);
     396      const Vector &oldGradient = (*iter)->getAtomicForceAtStep(OldTimeStep);
     397      const Vector &currentGradient = (*iter)->getAtomicForceAtStep(CurrentTimeStep);
     398      LOG(4, "DEBUG: oldPosition for atom #" << (*iter)->getId() << " is " << oldPosition);
     399      LOG(4, "DEBUG: currentPosition for atom #" << (*iter)->getId() << " is " << currentPosition);
     400      LOG(4, "DEBUG: oldGradient for atom #" << (*iter)->getId() << " is " << oldGradient);
     401      LOG(4, "DEBUG: currentGradient for atom #" << (*iter)->getId() << " is " << currentGradient);
     402//      LOG(4, "DEBUG: Force for atom #" << (*iter)->getId() << " is " << currentGradient);
     403
     404      // we use Barzilai-Borwein update with position reversed to get descent
     405      const Vector PositionDifference = currentPosition - oldPosition;
     406      const Vector GradientDifference = (currentGradient - oldGradient);
     407      double stepwidth = 0.;
     408      if (GradientDifference.Norm() > MYEPSILON)
     409        stepwidth = fabs(PositionDifference.ScalarProduct(GradientDifference))/
     410            GradientDifference.NormSquared();
     411      if (fabs(stepwidth) < 1e-10) {
     412        // dont' warn in first step, deltat usage normal
     413        if (currentStep != 1)
     414          ELOG(1, "INFO: Barzilai-Borwein stepwidth is zero, using deltat " << currentDeltat << " instead.");
     415        stepwidth = currentDeltat;
     416      }
     417      Vector PositionUpdate = stepwidth * currentGradient;
     418      LOG(3, "DEBUG: Update would be " << stepwidth << "*" << currentGradient << " = " << PositionUpdate);
     419
     420      /** go through all bonds and check projected_forces and side of plane
     421       * the idea is that if all bonds on one side are contracting ones or expanding,
     422       * respectively, then we may shift not only the atom with respect to its
     423       * gradient but also its neighbors (towards contraction or towards
     424       * expansion depending on direction of gradient).
     425       * if they are mixed on both sides of the plane, then we simply shift
     426       * only the atom itself.
     427       * if they are not mixed on either side, then we also only shift the
     428       * atom, namely away from expanding and towards contracting bonds.
     429       */
     430
     431      // sign encodes side of plane and also encodes contracting(-) or expanding(+)
     432      typedef std::vector<int> sides_t;
     433      typedef std::vector<int> types_t;
     434      sides_t sides;
     435      types_t types;
     436      const BondList& ListOfBonds = walker.getListOfBonds();
     437      for(BondList::const_iterator bonditer = ListOfBonds.begin();
     438          bonditer != ListOfBonds.end(); ++bonditer) {
     439        const bond::ptr &current_bond = *bonditer;
     440
     441        // BondVector goes from bond::rightatom to bond::leftatom
     442        const size_t index = bv.getIndexForBond(current_bond);
     443        std::vector<double> &forcelist = (&walker == current_bond->leftatom) ?
     444            projected_forces[BondVectors::leftside] : projected_forces[BondVectors::rightside];
     445        const double &temp = forcelist[index];
     446        sides.push_back( -1.*temp/fabs(temp) ); // BondVectors has exactly opposite sign for sides decision
     447        const double sum =
     448            projected_forces[BondVectors::leftside][index]+projected_forces[BondVectors::rightside][index];
     449        types.push_back( sum/fabs(sum) );
     450        LOG(4, "DEBUG: Bond " << *current_bond << " is on side " << sides.back()
     451            << " and has type " << types.back());
     452      }
     453//      /// check whether both conditions are compatible:
     454//      // i.e. either we have ++/-- for all entries in sides and types
     455//      // or we have +-/-+ for all entries
     456//      // hence, multiplying and taking the sum and its absolute value
     457//      // should be equal to the maximum number of entries
     458//      sides_t results;
     459//      std::transform(
     460//          sides.begin(), sides.end(),
     461//          types.begin(),
     462//          std::back_inserter(results),
     463//          std::multiplies<int>);
     464//      int result = abs(std::accumulate(results.begin(), results.end(), 0, std::plus<int>));
     465
     466      std::vector<size_t> first_per_side(2, (size_t)-1); //!< mark down one representative from either side
     467      std::vector< std::vector<int> > types_per_side(2); //!< gather all types on each side
     468      types_t::const_iterator typesiter = types.begin();
     469      for (sides_t::const_iterator sidesiter = sides.begin();
     470          sidesiter != sides.end(); ++sidesiter, ++typesiter) {
     471        const size_t index = (*sidesiter+1)/2;
     472        types_per_side[index].push_back(*typesiter);
     473        if (first_per_side[index] == (size_t)-1)
     474          first_per_side[index] = std::distance(const_cast<const sides_t &>(sides).begin(), sidesiter);
     475      }
     476      LOG(4, "DEBUG: First on side minus is " << first_per_side[0] << ", and first on side plus is "
     477          << first_per_side[1]);
     478      //!> enumerate types per side with a little witching with the numbers to allow easy setting from types
     479      enum whichtypes_t {
     480        contracting=0,
     481        unset=1,
     482        expanding=2,
     483        mixed,
     484        MAX_types
     485      };
     486      std::vector<int> typeside(2, unset);
     487      for(size_t i=0;i<2;++i) {
     488        for (std::vector<int>::const_iterator tpsiter = types_per_side[i].begin();
     489            tpsiter != types_per_side[i].end(); ++tpsiter) {
     490          if (typeside[i] == unset) {
     491            typeside[i] = *tpsiter+1; //contracting(0) or expanding(2)
     492          } else {
     493            if (typeside[i] != (*tpsiter+1)) // no longer he same type
     494              typeside[i] = mixed;
     495          }
     496        }
     497      }
     498      LOG(4, "DEBUG: Minus side is " << typeside[0] << " and plus side is " << typeside[1]);
     499
     500      // check whether positive side is contraction, then pick negative side
     501      int sideno = 1;
     502      if (typeside[1] == contracting) {
     503        sideno = 0;
     504      }
     505
     506      typedef std::vector< std::pair<atomId_t, atomId_t> > RemovedEdges_t;
     507      RemovedEdges_t RemovedEdges;
     508      if (sideno >= 0) {
     509        sideno = ((sideno+1) % 2)*2-1; // invert and make it -1/+1
    427510        const BondList& ListOfBonds = walker.getListOfBonds();
    428         if (walkerGradient.Norm() > MYEPSILON) {
    429 
    430           // gather subset of BondVectors for the current atom
    431           const std::vector<Vector> BondVectors =
    432               bv.getAtomsBondVectorsAtStep(walker, ReferenceTimeStep);
    433 
    434           // go through all its bonds and calculate what magnitude is represented
    435           // by the others i.e. sum of scalar products against other bonds
    436           const std::pair<weights_per_atom_t::iterator, bool> inserter =
    437               weights_per_atom[timestep].insert(
    438                   std::make_pair(walker.getId(),
    439                   bv.getWeightsForAtomAtStep(walker, BondVectors, ReferenceTimeStep)) );
    440           ASSERT( inserter.second,
    441               "ForceAnnealing::operator() - weight map for atom "+toString(walker)
    442               +" and time step "+toString(timestep)+" already filled?");
    443           BondVectors::weights_t &weights = inserter.first->second;
    444           ASSERT( weights.size() == ListOfBonds.size(),
    445               "ForceAnnealing::operator() - number of weights "
    446               +toString(weights.size())+" does not match number of bonds "
    447               +toString(ListOfBonds.size())+", error in calculation?");
    448 
    449           // projected gradient over all bonds and place in one of projected_forces
    450           // using the obtained weights
    451           BondVectors::forcestore_t forcestoring =
    452               boost::bind(&ForceAnnealing::ForceStore, _1, _2, _3, _4,
    453                   boost::cref(bv), boost::ref(projected_forces));
    454           const Vector RemnantGradient = bv.getRemnantGradientForAtomAtStep(
    455               walker, walkerGradient, BondVectors, weights, timestep, forcestoring
    456           );
    457           RemnantGradient_per_atom.insert( std::make_pair(walker.getId(), RemnantGradient) );
    458         } else {
    459           LOG(2, "DEBUG: Gradient is " << walkerGradient << " less than "
    460               << MYEPSILON << " for atom " << walker);
    461           // note that projected_forces is initialized to full length and filled
    462           // with zeros. Hence, nothing to do here
     511
     512        BondList::const_iterator bonditer = ListOfBonds.begin();
     513        for (sides_t::const_iterator sidesiter = sides.begin();
     514            sidesiter != sides.end(); ++sidesiter, ++bonditer) {
     515          if (*sidesiter == sideno) {
     516            // remove the edge
     517            const bond::ptr &current_bond = *bonditer;
     518            RemovedEdges.push_back( std::make_pair(
     519                current_bond->leftatom->getId(),
     520                current_bond->rightatom->getId())
     521            );
     522            LOG(5, "DEBUG: Removing edge " << RemovedEdges.back());
     523#ifndef NDEBUG
     524            const bool status =
     525#endif
     526                BGcreator.removeEdge(RemovedEdges.back());
     527            ASSERT( status, "ForceAnnealing() - edge to found bond is not present?");
     528          }
    463529        }
    464       }
    465     }
    466 
    467     // step through each bond and shift the atoms
    468     std::map<atomId_t, Vector> GatheredUpdates; //!< gathers all updates which are applied at the end
    469 
    470     LOG(3, "DEBUG: current step is " << currentStep << ", given time step is " << CurrentTimeStep);
    471     const BondVectors::mapped_t bondvectors = bv.getBondVectorsAtStep(CurrentTimeStep);
    472 
    473     for (BondVectors::container_t::const_iterator bondsiter = sorted_bonds.begin();
    474         bondsiter != sorted_bonds.end(); ++bondsiter) {
    475       const bond::ptr &current_bond = *bondsiter;
    476       const size_t index = bv.getIndexForBond(current_bond);
    477       const atom* bondatom[MAX_sides] = {
    478           current_bond->leftatom,
    479           current_bond->rightatom
    480       };
    481 
    482       // remove the edge
    483 #ifndef NDEBUG
    484       const bool status =
    485 #endif
    486           BGcreator.removeEdge(bondatom[leftside]->getId(), bondatom[rightside]->getId());
    487       ASSERT( status, "ForceAnnealing() - edge to found bond is not present?");
    488 
    489       // gather nodes for either atom
    490       BoostGraphHelpers::Nodeset_t bondside_set[MAX_sides];
    491       BreadthFirstSearchGatherer::distance_map_t distance_map[MAX_sides];
    492       for (size_t side=leftside;side<MAX_sides;++side) {
    493         bondside_set[side] = NodeGatherer(bondatom[side]->getId(), max_distance);
    494         distance_map[side] = NodeGatherer.getDistances();
    495         std::sort(bondside_set[side].begin(), bondside_set[side].end());
    496       }
    497 
    498       // re-add edge
    499       BGcreator.addEdge(bondatom[leftside]->getId(), bondatom[rightside]->getId());
    500 
    501       // do for both leftatom and rightatom of bond
    502       for (size_t side = leftside; side < MAX_sides; ++side) {
    503         const double &bondforce = projected_forces[0][side][index];
    504         const double &oldbondforce = projected_forces[1][side][index];
    505         const double bondforcedifference = fabs(bondforce - oldbondforce);
    506         LOG(4, "DEBUG: bondforce for " << (side == leftside ? "left" : "right")
    507             << " side of bond is " << bondforce);
    508         LOG(4, "DEBUG: oldbondforce for " << (side == leftside ? "left" : "right")
    509             << " side of bond is " << oldbondforce);
    510         // if difference or bondforce itself is zero, do nothing
    511         if ((fabs(bondforce) < MYEPSILON) || (fabs(bondforcedifference) < MYEPSILON))
    512           continue;
    513 
    514         // get BondVector to bond
    515         const BondVectors::mapped_t::const_iterator bviter =
    516             bondvectors.find(current_bond);
    517         ASSERT( bviter != bondvectors.end(),
    518             "ForceAnnealing() - cannot find current_bond ?");
    519         ASSERT( fabs(bviter->second.Norm() -1.) < MYEPSILON,
    520             "ForceAnnealing() - norm of BondVector is not one");
    521         const Vector &BondVector = bviter->second;
    522 
    523         // calculate gradient and position differences for stepwidth
    524         const Vector currentGradient = bondforce * BondVector;
    525         LOG(4, "DEBUG: current projected gradient for "
    526             << (side == leftside ? "left" : "right") << " side of bond is " << currentGradient);
    527         const Vector &oldPosition = bondatom[side]->getPositionAtStep(OldTimeStep);
    528         const Vector &currentPosition = bondatom[side]->getPositionAtStep(CurrentTimeStep);
    529         const Vector PositionDifference = currentPosition - oldPosition;
    530         LOG(4, "DEBUG: old position is " << oldPosition);
    531         LOG(4, "DEBUG: current position is " << currentPosition);
    532         LOG(4, "DEBUG: difference in position is " << PositionDifference);
    533         LOG(4, "DEBUG: bondvector is " << BondVector);
    534         const double projected_PositionDifference = PositionDifference.ScalarProduct(BondVector);
    535         LOG(4, "DEBUG: difference in position projected onto bondvector is "
    536             << projected_PositionDifference);
    537         LOG(4, "DEBUG: abs. difference in forces is " << bondforcedifference);
    538 
    539         // calculate step width
    540         double stepwidth =
    541             fabs(projected_PositionDifference)/bondforcedifference;
    542         if (fabs(stepwidth) < 1e-10) {
    543           // dont' warn in first step, deltat usage normal
    544           if (currentStep != 1)
    545             ELOG(1, "INFO: Barzilai-Borwein stepwidth is zero, using deltat " << currentDeltat << " instead.");
    546           stepwidth = currentDeltat;
    547         }
    548         Vector PositionUpdate = stepwidth * currentGradient;
    549         LOG(3, "DEBUG: Update would be " << stepwidth << "*" << currentGradient << " = " << PositionUpdate);
    550 
    551         // add PositionUpdate for all nodes in the bondside_set
    552         for (BoostGraphHelpers::Nodeset_t::const_iterator setiter = bondside_set[side].begin();
    553             setiter != bondside_set[side].end(); ++setiter) {
     530        // perform limited-horizon BFS
     531        BoostGraphHelpers::Nodeset_t bondside_set;
     532        BreadthFirstSearchGatherer::distance_map_t distance_map;
     533        bondside_set = NodeGatherer(walker.getId(), max_distance);
     534        distance_map = NodeGatherer.getDistances();
     535        std::sort(bondside_set.begin(), bondside_set.end());
     536
     537        // re-add edges
     538        for (RemovedEdges_t::const_iterator iter = RemovedEdges.begin();
     539            iter != RemovedEdges.end(); ++iter)
     540          BGcreator.addEdge(*iter);
     541        RemovedEdges.clear();
     542
     543        // update position with dampening factor on the discovered bonds
     544        for (BoostGraphHelpers::Nodeset_t::const_iterator setiter = bondside_set.begin();
     545            setiter != bondside_set.end(); ++setiter) {
    554546          const BreadthFirstSearchGatherer::distance_map_t::const_iterator diter
    555             = distance_map[side].find(*setiter);
    556           ASSERT( diter != distance_map[side].end(),
     547            = distance_map.find(*setiter);
     548          ASSERT( diter != distance_map.end(),
    557549              "ForceAnnealing() - could not find distance to an atom.");
    558550          const double factor = pow(damping_factor, diter->second+1);
     
    568560          }
    569561        }
     562      } else {
     563        // simple atomic annealing, i.e. damping factor of 1
     564        LOG(3, "DEBUG: Update for atom #" << walker.getId() << " will be " << PositionUpdate);
     565        GatheredUpdates.insert(
     566            std::make_pair(
     567                walker.getId(),
     568                PositionUpdate) );
    570569      }
    571570    }
     
    580579    }
    581580
    582     // remove center of weight translation from gathered updates
    583     Vector CommonTranslation;
    584     for (std::map<atomId_t, Vector>::const_iterator iter = GatheredUpdates.begin();
    585         iter != GatheredUpdates.end(); ++iter) {
    586       const Vector &update = iter->second;
    587       CommonTranslation += update;
    588     }
    589     CommonTranslation *= 1./(double)GatheredUpdates.size();
    590     LOG(3, "DEBUG: Subtracting common translation " << CommonTranslation
    591         << " from all updates.");
     581//    // remove center of weight translation from gathered updates
     582//    Vector CommonTranslation;
     583//    for (std::map<atomId_t, Vector>::const_iterator iter = GatheredUpdates.begin();
     584//        iter != GatheredUpdates.end(); ++iter) {
     585//      const Vector &update = iter->second;
     586//      CommonTranslation += update;
     587//    }
     588//    CommonTranslation *= 1./(double)GatheredUpdates.size();
     589//    LOG(3, "DEBUG: Subtracting common translation " << CommonTranslation
     590//        << " from all updates.");
    592591
    593592    // apply the gathered updates and set remnant gradients for atomic annealing
     
    602601          << ", namely " << *walker);
    603602      walker->setPositionAtStep(_TimeStep,
    604           walker->getPositionAtStep(CurrentTimeStep) + update - CommonTranslation);
    605 //      walker->setAtomicForce( RemnantGradient_per_atom[walker->getId()] );
     603          walker->getPositionAtStep(CurrentTimeStep) + update); // - CommonTranslation);
    606604    }
    607605
Note: See TracChangeset for help on using the changeset viewer.