Changeset 6d360a for src


Ignore:
Timestamp:
Jul 20, 2017, 9:38:38 AM (8 years ago)
Author:
Frederik Heber <frederik.heber@…>
Branches:
ForceAnnealing_with_BondGraph_continued
Children:
9d3846
Parents:
4cd46b
git-author:
Frederik Heber <frederik.heber@…> (06/20/17 20:26:12)
git-committer:
Frederik Heber <frederik.heber@…> (07/20/17 09:38:38)
Message:

ForceAnnealing can now be used either atom- or bond-centered.

  • new keyword "use-bondgraph" to use either case.
  • atom is old annealing method, bond graph is new annealing method where the bond neighborhood is shifted as well to anneal to force projected onto the BondVector.
  • In the first step we always use atom-centered annealing where we use the given deltat step width. Afterwards Barzilai-Borwein may then proceed.
Location:
src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/Actions/MoleculeAction/ForceAnnealingAction.cpp

    r4cd46b r6d360a  
    117117  // perform optimization step
    118118  LOG(1, "Structural optimization.");
    119   optimizer(CurrentStep, 1);
     119  optimizer(CurrentStep, 1, params.UseBondGraph.get());
    120120  STATUS("Successfully optimized structure by one step.");
    121121
  • src/Actions/MoleculeAction/ForceAnnealingAction.def

    r4cd46b r6d360a  
    1717// ValueStorage by the token "Z" -> first column: int, Z, "Z"
    1818// "undefine" if no parameters are required, use (NOPARAM_DEFAULT) for each (undefined) default value
    19 #define paramtypes (boost::filesystem::path)(unsigned int)(bool)(int)(double)
    20 #define paramtokens ("forces-file")("steps")("output-every-step")("max-distance")("damping-factor")
    21 #define paramdescriptions ("file containing")("fixed number of optimization steps to be performed")("whether WorldTime should be increased and output written after every step, useful if optimization might hang")("maximum distance to which bond graph is taken into account")("damping factor for decreasing the shift with bond graph distance from the causing site")
    22 #define paramdefaults (PARAM_DEFAULT(""))(NOPARAM_DEFAULT)(PARAM_DEFAULT("0"))(PARAM_DEFAULT(0))(PARAM_DEFAULT(0.5))
    23 #define paramreferences (forcesfile)(steps)(DoOutput)(MaxDistance)(DampingFactor)
     19#define paramtypes (boost::filesystem::path)(unsigned int)(bool)(int)(double)(bool)
     20#define paramtokens ("forces-file")("steps")("output-every-step")("max-distance")("damping-factor")("use-bondgraph")
     21#define paramdescriptions ("file containing")("fixed number of optimization steps to be performed")("whether WorldTime should be increased and output written after every step, useful if optimization might hang")("maximum distance to which bond graph is taken into account")("damping factor for decreasing the shift with bond graph distance from the causing site")("whether annealing should take place focusing on atoms alone or on the bonds (faster)")
     22#define paramdefaults (PARAM_DEFAULT(""))(NOPARAM_DEFAULT)(PARAM_DEFAULT("0"))(PARAM_DEFAULT(0))(PARAM_DEFAULT(0.5))(PARAM_DEFAULT(0))
     23#define paramreferences (forcesfile)(steps)(DoOutput)(MaxDistance)(DampingFactor)(UseBondGraph)
    2424#define paramvalids \
    2525(DummyValidator< boost::filesystem::path >()) \
     
    2727(DummyValidator<bool>()) \
    2828(DummyValidator< int >()) \
    29 (RangeValidator< double >(0,1))
     29(RangeValidator< double >(0,1)) \
     30(DummyValidator<bool>())
    3031
    3132#define statetypes (std::vector<AtomicInfo>)(std::vector<AtomicInfo>)
  • src/Dynamics/ForceAnnealing.hpp

    r4cd46b r6d360a  
    9090   *
    9191   *
    92    * \param NextStep current time step (i.e. \f$ t + \Delta t \f$ in the sense of the velocity verlet)
     92   * \param CurrentTimeStep current time step (i.e. \f$ t + \Delta t \f$ in the sense of the velocity verlet)
    9393   * \param offset offset in matrix file to the first force component
    9494   * \todo This is not yet checked if it is correctly working with DoConstrainedMD set >0.
    9595   */
    96   void operator()(const int CurrentTimeStep, const size_t offset)
     96  void operator()(
     97      const int _CurrentTimeStep,
     98      const size_t _offset,
     99      const bool _UseBondgraph)
    97100  {
    98101    // make sum of forces equal zero
    99     AtomicForceManipulator<T>::correctForceMatrixForFixedCenterOfMass(offset,CurrentTimeStep);
     102    AtomicForceManipulator<T>::correctForceMatrixForFixedCenterOfMass(_offset, _CurrentTimeStep);
    100103
    101104    // are we in initial step? Then set static entities
     105    Vector maxComponents(zeroVec);
    102106    if (currentStep == 0) {
    103107      currentDeltat = AtomicForceManipulator<T>::Deltat;
    104108      currentStep = 1;
    105109      LOG(2, "DEBUG: Initial step, setting values, current step is #" << currentStep);
     110
     111      // always use atomic annealing on first step
     112      anneal(_CurrentTimeStep, _offset, maxComponents);
    106113    } else {
    107114      ++currentStep;
    108115      LOG(2, "DEBUG: current step is #" << currentStep);
    109     }
    110 
     116
     117      if (_UseBondgraph)
     118        annealWithBondGraph(_CurrentTimeStep, _offset, maxComponents);
     119      else
     120        anneal(_CurrentTimeStep, _offset, maxComponents);
     121    }
     122
     123
     124    LOG(1, "STATUS: Largest remaining force components at step #"
     125        << currentStep << " are " << maxComponents);
     126
     127    // are we in final step? Remember to reset static entities
     128    if (currentStep == maxSteps) {
     129      LOG(2, "DEBUG: Final step, resetting values");
     130      reset();
     131    }
     132  }
     133
     134  /** Performs Gradient optimization on the atoms.
     135   *
     136   * We assume that forces have just been calculated.
     137   *
     138   * \param CurrentTimeStep current time step (i.e. \f$ t + \Delta t \f$ in the sense of the velocity verlet)
     139   * \param offset offset in matrix file to the first force component
     140   * \param maxComponents to be filled with maximum force component over all atoms
     141   */
     142  void anneal(
     143      const int CurrentTimeStep,
     144      const size_t offset,
     145      Vector &maxComponents)
     146  {
     147                for(typename AtomSetMixin<T>::iterator iter = AtomicForceManipulator<T>::atoms.begin();
     148                    iter != AtomicForceManipulator<T>::atoms.end(); ++iter) {
     149                        // atom's force vector gives steepest descent direction
     150                        const Vector oldPosition = (*iter)->getPositionAtStep(CurrentTimeStep-2 >= 0 ? CurrentTimeStep - 2 : 0);
     151                        const Vector currentPosition = (*iter)->getPosition();
     152                        const Vector oldGradient = (*iter)->getAtomicForceAtStep(CurrentTimeStep-2 >= 0 ? CurrentTimeStep - 2 : 0);
     153                        const Vector currentGradient = (*iter)->getAtomicForce();
     154      LOG(4, "DEBUG: oldPosition for atom " << **iter << " is " << oldPosition);
     155      LOG(4, "DEBUG: currentPosition for atom " << **iter << " is " << currentPosition);
     156      LOG(4, "DEBUG: oldGradient for atom " << **iter << " is " << oldGradient);
     157      LOG(4, "DEBUG: currentGradient for atom " << **iter << " is " << currentGradient);
     158//                      LOG(4, "DEBUG: Force for atom " << **iter << " is " << currentGradient);
     159
     160      // we use Barzilai-Borwein update with position reversed to get descent
     161      const Vector PositionDifference = currentPosition - oldPosition;
     162                        const Vector GradientDifference = (currentGradient - oldGradient);
     163                        double stepwidth = 0.;
     164                        if (GradientDifference.Norm() > MYEPSILON)
     165        stepwidth = fabs(PositionDifference.ScalarProduct(GradientDifference))/
     166            GradientDifference.NormSquared();
     167                        if (fabs(stepwidth) < 1e-10) {
     168                          // dont' warn in first step, deltat usage normal
     169                          if (currentStep != 1)
     170          ELOG(1, "INFO: Barzilai-Borwein stepwidth is zero, using deltat " << currentDeltat << " instead.");
     171                          stepwidth = currentDeltat;
     172                        }
     173      Vector PositionUpdate = stepwidth * currentGradient;
     174                        LOG(3, "DEBUG: Update would be " << stepwidth << "*" << currentGradient << " = " << PositionUpdate);
     175
     176                        // extract largest components for showing progress of annealing
     177                        for(size_t i=0;i<NDIM;++i)
     178                          if (currentGradient[i] > maxComponents[i])
     179                            maxComponents[i] = currentGradient[i];
     180
     181                        // are we in initial step? Then don't check against velocity
     182                        if ((currentStep > 1) && (!(*iter)->getAtomicVelocity().IsZero()))
     183                                // update with currentDelta tells us how the current gradient relates to
     184                                // the last one: If it has become larger, reduce currentDelta
     185                                if ((PositionUpdate.ScalarProduct((*iter)->getAtomicVelocity()) < 0)
     186                                    && (currentDeltat > MinimumDeltat)) {
     187                                  currentDeltat = .5*currentDeltat;
     188                                  LOG(2, "DEBUG: Upgrade in other direction: " << PositionUpdate.NormSquared()
     189                                      << " > " << (*iter)->getAtomicVelocity().NormSquared()
     190                                      << ", decreasing deltat: " << currentDeltat);
     191                                  PositionUpdate = currentDeltat * currentGradient;
     192                        }
     193                        // finally set new values
     194                        (*iter)->setPosition(currentPosition + PositionUpdate);
     195                        (*iter)->setAtomicVelocity(PositionUpdate);
     196                        //std::cout << "Id of atom is " << (*iter)->getId() << std::endl;
     197//        (*iter)->VelocityVerletUpdateU((*iter)->getId(), CurrentTimeStep-1, Deltat, IsAngstroem);
     198
     199                        // reset force vector for next step except on final one
     200                        if (currentStep != maxSteps)
     201                          (*iter)->setAtomicForce(zeroVec);
     202                }
     203
     204                LOG(1, "STATUS: Largest remaining force components at step #"
     205                    << currentStep << " are " << maxComponents);
     206
     207                // are we in final step? Remember to reset static entities
     208                if (currentStep == maxSteps) {
     209                  LOG(2, "DEBUG: Final step, resetting values");
     210                  reset();
     211                }
     212  }
     213
     214  /** Performs Gradient optimization on the bonds.
     215   *
     216   * We assume that forces have just been calculated. These forces are projected
     217   * onto the bonds and these are annealed subsequently by moving atoms in the
     218   * bond neighborhood on either side conjunctively.
     219   *
     220   *
     221   * \param CurrentTimeStep current time step (i.e. \f$ t + \Delta t \f$ in the sense of the velocity verlet)
     222   * \param offset offset in matrix file to the first force component
     223   * \param maxComponents to be filled with maximum force component over all atoms
     224   */
     225  void annealWithBondGraph(
     226      const int CurrentTimeStep,
     227      const size_t offset,
     228      Vector &maxComponents)
     229  {
    111230    // get nodes on either side of selected bond via BFS discovery
    112231    BoostGraphCreator BGcreator;
     
    375494    }
    376495
    377     Vector maxComponents(zeroVec);
    378496    for(typename AtomSetMixin<T>::iterator iter = AtomicForceManipulator<T>::atoms.begin();
    379497        iter != AtomicForceManipulator<T>::atoms.end(); ++iter) {
     
    401519      walker->setAtomicVelocity(update);
    402520      LOG(3, "DEBUG: Applying update " << update << " to atom " << *walker);
    403     }
    404 
    405     LOG(1, "STATUS: Largest remaining force components at step #"
    406         << currentStep << " are " << maxComponents);
    407 
    408     // are we in final step? Remember to reset static entities
    409     if (currentStep == maxSteps) {
    410       LOG(2, "DEBUG: Final step, resetting values");
    411       reset();
    412521    }
    413522  }
Note: See TracChangeset for help on using the changeset viewer.