Changeset 9190e6


Ignore:
Timestamp:
May 19, 2017, 2:29:40 PM (8 years ago)
Author:
Frederik Heber <frederik.heber@…>
Branches:
ForceAnnealing_goodresults, ForceAnnealing_tocheck
Children:
b03d7d
Parents:
d07be9
Message:

ForceAnnealing now shifts atoms in the bond graph to anneal forces, too.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified src/Dynamics/ForceAnnealing.hpp

    rd07be9 r9190e6  
    2222#include "Dynamics/AtomicForceManipulator.hpp"
    2323#include "Fragmentation/ForceMatrix.hpp"
     24#include "Graph/BoostGraphCreator.hpp"
     25#include "Graph/BoostGraphHelpers.hpp"
     26#include "Graph/BreadthFirstSearchGatherer.hpp"
    2427#include "Helpers/helpers.hpp"
    2528#include "Helpers/defs.hpp"
     
    2932#include "World.hpp"
    3033
    31 /** This class is the essential build block for performing structual optimization.
     34/** This class is the essential build block for performing structural optimization.
    3235 *
    3336 * Sadly, we have to use some static instances as so far values cannot be passed
    3437 * between actions. Hence, we need to store the current step and the adaptive-
    35  * step width (we cannot perform a linesearch, as we have no control over the
     38 * step width (we cannot perform a line search, as we have no control over the
    3639 * calculation of the forces).
    3740 */
     
    8689    }
    8790
     91    // get nodes on either side of selected bond via BFS discovery
     92//    std::vector<atomId_t> atomids;
     93//    for(typename AtomSetMixin<T>::iterator iter = AtomicForceManipulator<T>::atoms.begin();
     94//        iter != AtomicForceManipulator<T>::atoms.end(); ++iter) {
     95//      atomids.push_back((*iter)->getId());
     96//    }
     97//    ASSERT( atomids.size() == AtomicForceManipulator<T>::atoms.size(),
     98//        "ForceAnnealing() - could not gather all atomic ids?");
     99    BoostGraphCreator BGcreator;
     100    BGcreator.createFromRange(
     101        AtomicForceManipulator<T>::atoms.begin(),
     102        AtomicForceManipulator<T>::atoms.end(),
     103        AtomicForceManipulator<T>::atoms.size(),
     104        BreadthFirstSearchGatherer::AlwaysTruePredicate);
     105    BreadthFirstSearchGatherer NodeGatherer(BGcreator);
     106
     107    std::map<atomId_t, Vector> GatheredUpdates; //!< gathers all updates which are applied at the end
    88108    Vector maxComponents(zeroVec);
    89109    for(typename AtomSetMixin<T>::iterator iter = AtomicForceManipulator<T>::atoms.begin();
     
    110130      LOG(3, "DEBUG: Update would be " << PositionUpdate);
    111131
     132      // add update to central atom
     133      const atomId_t atomid = (*iter)->getId();
     134      if (GatheredUpdates.count(atomid)) {
     135        GatheredUpdates[atomid] += PositionUpdate;
     136      } else
     137        GatheredUpdates.insert( std::make_pair(atomid, PositionUpdate) );
     138
     139      // We assume that a force is local, i.e. a bond is too short yet and hence
     140      // the atom needs to be moved. However, all the adjacent (bound) atoms might
     141      // already be at the perfect distance. If we just move the atom alone, we ruin
     142      // all the other bonds. Hence, it would be sensible to move every atom found
     143      // through the bond graph in the direction of the force as well by the same
     144      // PositionUpdate. This is just what we are going to do.
     145
     146      /// get all nodes from bonds in the direction of the current force
     147      const size_t max_distance = 4;
     148      const double damping_factor = 0.9;
     149
     150      // remove edges facing in the wrong direction
     151      std::vector<bond::ptr> removed_bonds;
     152      const BondList& ListOfBonds = (*iter)->getListOfBonds();
     153      for(BondList::const_iterator bonditer = ListOfBonds.begin();
     154          bonditer != ListOfBonds.end(); ++bonditer) {
     155        const bond &current_bond = *(*bonditer);
     156        LOG(2, "DEBUG: Looking at bond " << current_bond);
     157        Vector BondVector = (*iter)->getPosition();
     158        BondVector -= ((*iter)->getId() == current_bond.rightatom->getId())
     159            ? current_bond.rightatom->getPosition() : current_bond.leftatom->getPosition();
     160        BondVector.Normalize();
     161        if (BondVector.ScalarProduct(currentGradient) < 0) {
     162          removed_bonds.push_back(*bonditer);
     163#ifndef NDEBUG
     164          const bool status =
     165#endif
     166              BGcreator.removeEdge(current_bond.leftatom->getId(), current_bond.rightatom->getId());
     167          ASSERT( status, "ForceAnnealing() - edge to found bond is not present?");
     168        }
     169      }
     170      BoostGraphHelpers::Nodeset_t bondside_set = NodeGatherer((*iter)->getId(), max_distance);
     171      const BreadthFirstSearchGatherer::distance_map_t &distance_map = NodeGatherer.getDistances();
     172      std::sort(bondside_set.begin(), bondside_set.end());
     173      // re-add those edges
     174      for (std::vector<bond::ptr>::const_iterator bonditer = removed_bonds.begin();
     175          bonditer != removed_bonds.end(); ++bonditer)
     176        BGcreator.addEdge((*bonditer)->leftatom->getId(), (*bonditer)->rightatom->getId());
     177
     178      // apply PositionUpdate to all nodes in the bondside_set
     179      for (BoostGraphHelpers::Nodeset_t::const_iterator setiter = bondside_set.begin();
     180          setiter != bondside_set.end(); ++setiter) {
     181        const BreadthFirstSearchGatherer::distance_map_t::const_iterator diter
     182          = distance_map.find(*setiter);
     183        ASSERT( diter != distance_map.end(),
     184            "ForceAnnealing() - could not find distance to an atom.");
     185        const double factor = pow(damping_factor, diter->second);
     186        if (GatheredUpdates.count((*setiter))) {
     187          GatheredUpdates[(*setiter)] += factor*PositionUpdate;
     188        } else {
     189          GatheredUpdates.insert(
     190              std::make_pair(
     191                  (*setiter),
     192                  factor*PositionUpdate) );
     193        }
     194      }
     195
    112196      // extract largest components for showing progress of annealing
    113197      for(size_t i=0;i<NDIM;++i)
Note: See TracChangeset for help on using the changeset viewer.