Ignore:
Timestamp:
Jul 20, 2017, 9:38:39 AM (8 years ago)
Author:
Frederik Heber <frederik.heber@…>
Branches:
ForceAnnealing_with_BondGraph_continued
Children:
ccbdf4
Parents:
6d7c73
git-author:
Frederik Heber <frederik.heber@…> (07/18/17 22:24:12)
git-committer:
Frederik Heber <frederik.heber@…> (07/20/17 09:38:39)
Message:

We now obtain weights via levmar minimization.

  • this should yield the best possible weights within the interval of [1/n,1.].
  • note that we cannot always get an exact solution because of this constraint.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Dynamics/ForceAnnealing.hpp

    r6d7c73 r90e540  
    117117      LOG(2, "DEBUG: current step is #" << currentStep);
    118118
     119      // bond graph annealing is always followed by a normal annealing
    119120      if (_UseBondgraph)
    120121        annealWithBondGraph(_CurrentTimeStep, _offset, maxComponents);
    121       else
    122         anneal(_CurrentTimeStep, _offset, maxComponents);
     122      anneal(_CurrentTimeStep, _offset, maxComponents);
    123123    }
    124124
     
    203203  }
    204204
     205  // knowing the number of bonds in total, we can setup the storage for the
     206  // projected forces
     207  enum whichatom_t {
     208    leftside=0,
     209    rightside=1,
     210    MAX_sides
     211  };
     212
     213  /** Helper function to put bond force into a container.
     214   *
     215   * \param _walker atom
     216   * \param _current_bond current bond of \a _walker
     217   * \param _timestep time step
     218   * \param _force calculated bond force
     219   * \param _bv bondvectors for obtaining the correct index
     220   * \param _projected_forces container
     221   */
     222  static void ForceStore(
     223      const atom &_walker,
     224      const bond::ptr &_current_bond,
     225      const size_t &_timestep,
     226      const double _force,
     227      const BondVectors &_bv,
     228      std::vector< // time step
     229            std::vector< // which bond side
     230              std::vector<double> > // over all bonds
     231                > &_projected_forces)
     232  {
     233    std::vector<double> &forcelist = (&_walker == _current_bond->leftatom) ?
     234        _projected_forces[_timestep][leftside] : _projected_forces[_timestep][rightside];
     235    const size_t index = _bv.getIndexForBond(_current_bond);
     236    ASSERT( index != (size_t)-1,
     237        "ForceAnnealing() - could not find bond "+toString(*_current_bond)
     238        +" in bondvectors");
     239    forcelist[index] = _force;
     240  }
     241
    205242  /** Performs Gradient optimization on the bonds.
    206243   *
     
    260297    const BondVectors::container_t &sorted_bonds = bv.getSorted();
    261298
    262     // knowing the number of bonds in total, we can setup the storage for the
    263     // projected forces
    264     enum whichatom_t {
    265       leftside=0,
    266       rightside=1,
    267       MAX_sides
    268     };
    269299    std::vector< // time step
    270300      std::vector< // which bond side
     
    280310    typedef std::map<atomId_t, BondVectors::weights_t > weights_per_atom_t;
    281311    std::vector<weights_per_atom_t> weights_per_atom(2);
     312    typedef std::map<atomId_t, Vector> RemnantGradient_per_atom_t;
     313    RemnantGradient_per_atom_t RemnantGradient_per_atom;
    282314    for (size_t timestep = 0; timestep <= 1; ++timestep) {
    283315      // TODO: We have this extra step in between because of DoOutput copying
     
    304336              weights_per_atom[timestep].insert(
    305337                  std::make_pair(walker.getId(),
    306                   bv.getWeightsForAtomAtStep(walker, CurrentStep)) );
     338                  bv.getWeightsForAtomAtStep(walker, BondVectors, CurrentStep)) );
    307339          ASSERT( inserter.second,
    308340              "ForceAnnealing::operator() - weight map for atom "+toString(walker)
     
    316348          // projected gradient over all bonds and place in one of projected_forces
    317349          // using the obtained weights
    318           {
    319             BondVectors::weights_t::const_iterator weightiter = weights.begin();
    320             std::vector<Vector>::const_iterator vectoriter = BondVectors.begin();
    321             Vector forcesum_check;
    322             for(BondList::const_iterator bonditer = ListOfBonds.begin();
    323                 bonditer != ListOfBonds.end(); ++bonditer, ++weightiter, ++vectoriter) {
    324               const bond::ptr &current_bond = *bonditer;
    325               const Vector &BondVector = *vectoriter;
    326 
    327               std::vector<double> &forcelist = (&walker == current_bond->leftatom) ?
    328                   projected_forces[timestep][leftside] : projected_forces[timestep][rightside];
    329               const size_t index = bv.getIndexForBond(current_bond);
    330               ASSERT( index != (size_t)-1,
    331                   "ForceAnnealing() - could not find bond "+toString(*current_bond)
    332                   +" in bondvectors");
    333               forcelist[index] = (*weightiter)*walkerGradient.ScalarProduct(BondVector);
    334               LOG(4, "DEBUG: BondVector " << BondVector << " receives projected force of "
    335                   << forcelist[index]);
    336               forcesum_check += forcelist[index] * BondVector;
    337             }
    338             ASSERT( weightiter == weights.end(),
    339                 "ForceAnnealing - weightiter is not at end when it should be.");
    340             ASSERT( vectoriter == BondVectors.end(),
    341                 "ForceAnnealing - vectoriter is not at end when it should be.");
    342             LOG(3, "DEBUG: sum of projected forces is " << forcesum_check);
    343           }
    344 
     350          BondVectors::forcestore_t forcestoring =
     351              boost::bind(&ForceAnnealing::ForceStore, _1, _2, _3, _4,
     352                  boost::cref(bv), boost::ref(projected_forces));
     353          const Vector RemnantGradient = bv.getRemnantGradientForAtomAtStep(
     354              walker, BondVectors, weights, timestep, forcestoring
     355          );
     356          RemnantGradient_per_atom.insert( std::make_pair(walker.getId(), RemnantGradient) );
    345357        } else {
    346358          LOG(2, "DEBUG: Gradient is " << walkerGradient << " less than "
     
    465477    }
    466478
    467     // apply the gathered updates
     479    // apply the gathered updates and set remnant gradients for atomic annealing
    468480    for (std::map<atomId_t, Vector>::const_iterator iter = GatheredUpdates.begin();
    469481        iter != GatheredUpdates.end(); ++iter) {
     
    476488          << ", namely " << *walker);
    477489      walker->setPosition( walker->getPosition() + update );
     490      walker->setAtomicForce( RemnantGradient_per_atom[walker->getId()] );
    478491    }
    479492  }
Note: See TracChangeset for help on using the changeset viewer.