Changeset b2acca for src


Ignore:
Timestamp:
Apr 10, 2018, 6:43:11 AM (7 years ago)
Author:
Frederik Heber <frederik.heber@…>
Branches:
AutomationFragmentation_failures, Candidate_v1.6.1, ChemicalSpaceEvaluator, Enhanced_StructuralOptimization_continued, Exclude_Hydrogens_annealWithBondGraph, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_contraction-expansion, Gui_displays_atomic_force_velocity, PythonUI_with_named_parameters, StoppableMakroAction, TremoloParser_IncreasedPrecision
Children:
216840
Parents:
ecfcf6
git-author:
Frederik Heber <frederik.heber@…> (06/20/17 20:26:12)
git-committer:
Frederik Heber <frederik.heber@…> (04/10/18 06:43:11)
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.
  • TESTS: Removed XFAIL from ForceAnnealing regression tests as they work now again.
Location:
src
Files:
3 edited

Legend:

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

    recfcf6 rb2acca  
    128128  // perform optimization step
    129129  LOG(1, "Structural optimization.");
    130   optimizer(CurrentStep, 1);
     130  optimizer(CurrentStep, 1, params.UseBondGraph.get());
    131131  STATUS("Successfully optimized structure by one step.");
    132132
  • src/Actions/MoleculeAction/ForceAnnealingAction.def

    recfcf6 rb2acca  
    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

    recfcf6 rb2acca  
    8080   *
    8181   *
    82    * \param NextStep current time step (i.e. \f$ t + \Delta t \f$ in the sense of the velocity verlet)
     82   * \param CurrentTimeStep current time step (i.e. \f$ t + \Delta t \f$ in the sense of the velocity verlet)
    8383   * \param offset offset in matrix file to the first force component
    8484   * \todo This is not yet checked if it is correctly working with DoConstrainedMD set >0.
    8585   */
    86   void operator()(const int NextStep, const size_t offset)
     86  void operator()(
     87      const int _CurrentTimeStep,
     88      const size_t _offset,
     89      const bool _UseBondgraph)
    8790  {
    8891    // make sum of forces equal zero
    89     AtomicForceManipulator<T>::correctForceMatrixForFixedCenterOfMass(offset,NextStep);
     92    AtomicForceManipulator<T>::correctForceMatrixForFixedCenterOfMass(_offset, _CurrentTimeStep);
    9093
    9194    // are we in initial step? Then set static entities
     95    Vector maxComponents(zeroVec);
    9296    if (currentStep == 0) {
    9397      currentDeltat = AtomicForceManipulator<T>::Deltat;
    9498      currentStep = 1;
    9599      LOG(2, "DEBUG: Initial step, setting values, current step is #" << currentStep);
     100
     101      // always use atomic annealing on first step
     102      anneal(_CurrentTimeStep, _offset, maxComponents);
    96103    } else {
    97104      ++currentStep;
    98105      LOG(2, "DEBUG: current step is #" << currentStep);
    99     }
    100 
     106
     107      if (_UseBondgraph)
     108        annealWithBondGraph(_CurrentTimeStep, _offset, maxComponents);
     109      else
     110        anneal(_CurrentTimeStep, _offset, maxComponents);
     111    }
     112
     113
     114    LOG(1, "STATUS: Largest remaining force components at step #"
     115        << currentStep << " are " << maxComponents);
     116
     117    // are we in final step? Remember to reset static entities
     118    if (currentStep == maxSteps) {
     119      LOG(2, "DEBUG: Final step, resetting values");
     120      reset();
     121    }
     122  }
     123
     124  /** Performs Gradient optimization on the atoms.
     125   *
     126   * We assume that forces have just been calculated.
     127   *
     128   * \param CurrentTimeStep current time step (i.e. \f$ t + \Delta t \f$ in the sense of the velocity verlet)
     129   * \param offset offset in matrix file to the first force component
     130   * \param maxComponents to be filled with maximum force component over all atoms
     131   */
     132  void anneal(
     133      const int CurrentTimeStep,
     134      const size_t offset,
     135      Vector &maxComponents)
     136  {
     137    for(typename AtomSetMixin<T>::iterator iter = AtomicForceManipulator<T>::atoms.begin();
     138        iter != AtomicForceManipulator<T>::atoms.end(); ++iter) {
     139      // atom's force vector gives steepest descent direction
     140      const Vector oldPosition = (*iter)->getPositionAtStep(CurrentTimeStep-2 >= 0 ? CurrentTimeStep - 2 : 0);
     141      const Vector currentPosition = (*iter)->getPosition();
     142      const Vector oldGradient = (*iter)->getAtomicForceAtStep(CurrentTimeStep-2 >= 0 ? CurrentTimeStep - 2 : 0);
     143      const Vector currentGradient = (*iter)->getAtomicForce();
     144      LOG(4, "DEBUG: oldPosition for atom " << **iter << " is " << oldPosition);
     145      LOG(4, "DEBUG: currentPosition for atom " << **iter << " is " << currentPosition);
     146      LOG(4, "DEBUG: oldGradient for atom " << **iter << " is " << oldGradient);
     147      LOG(4, "DEBUG: currentGradient for atom " << **iter << " is " << currentGradient);
     148//      LOG(4, "DEBUG: Force for atom " << **iter << " is " << currentGradient);
     149
     150      // we use Barzilai-Borwein update with position reversed to get descent
     151      const Vector PositionDifference = currentPosition - oldPosition;
     152      const Vector GradientDifference = (currentGradient - oldGradient);
     153      double stepwidth = 0.;
     154      if (GradientDifference.Norm() > MYEPSILON)
     155        stepwidth = fabs(PositionDifference.ScalarProduct(GradientDifference))/
     156            GradientDifference.NormSquared();
     157      if (fabs(stepwidth) < 1e-10) {
     158        // dont' warn in first step, deltat usage normal
     159        if (currentStep != 1)
     160          ELOG(1, "INFO: Barzilai-Borwein stepwidth is zero, using deltat " << currentDeltat << " instead.");
     161        stepwidth = currentDeltat;
     162      }
     163      Vector PositionUpdate = stepwidth * currentGradient;
     164      LOG(3, "DEBUG: Update would be " << stepwidth << "*" << currentGradient << " = " << PositionUpdate);
     165
     166      // extract largest components for showing progress of annealing
     167      for(size_t i=0;i<NDIM;++i)
     168        if (currentGradient[i] > maxComponents[i])
     169          maxComponents[i] = currentGradient[i];
     170
     171      // are we in initial step? Then don't check against velocity
     172      if ((currentStep > 1) && (!(*iter)->getAtomicVelocity().IsZero()))
     173        // update with currentDelta tells us how the current gradient relates to
     174        // the last one: If it has become larger, reduce currentDelta
     175        if ((PositionUpdate.ScalarProduct((*iter)->getAtomicVelocity()) < 0)
     176            && (currentDeltat > MinimumDeltat)) {
     177          currentDeltat = .5*currentDeltat;
     178          LOG(2, "DEBUG: Upgrade in other direction: " << PositionUpdate.NormSquared()
     179              << " > " << (*iter)->getAtomicVelocity().NormSquared()
     180              << ", decreasing deltat: " << currentDeltat);
     181          PositionUpdate = currentDeltat * currentGradient;
     182      }
     183      // finally set new values
     184      (*iter)->setPosition(currentPosition + PositionUpdate);
     185      (*iter)->setAtomicVelocity(PositionUpdate);
     186      //std::cout << "Id of atom is " << (*iter)->getId() << std::endl;
     187//        (*iter)->VelocityVerletUpdateU((*iter)->getId(), CurrentTimeStep-1, Deltat, IsAngstroem);
     188
     189      // reset force vector for next step except on final one
     190      if (currentStep != maxSteps)
     191        (*iter)->setAtomicForce(zeroVec);
     192    }
     193
     194    LOG(1, "STATUS: Largest remaining force components at step #"
     195        << currentStep << " are " << maxComponents);
     196
     197    // are we in final step? Remember to reset static entities
     198    if (currentStep == maxSteps) {
     199      LOG(2, "DEBUG: Final step, resetting values");
     200      reset();
     201    }
     202  }
     203
     204  /** Performs Gradient optimization on the bonds.
     205   *
     206   * We assume that forces have just been calculated. These forces are projected
     207   * onto the bonds and these are annealed subsequently by moving atoms in the
     208   * bond neighborhood on either side conjunctively.
     209   *
     210   *
     211   * \param CurrentTimeStep current time step (i.e. \f$ t + \Delta t \f$ in the sense of the velocity verlet)
     212   * \param offset offset in matrix file to the first force component
     213   * \param maxComponents to be filled with maximum force component over all atoms
     214   */
     215  void annealWithBondGraph(
     216      const int CurrentTimeStep,
     217      const size_t offset,
     218      Vector &maxComponents)
     219  {
    101220    // get nodes on either side of selected bond via BFS discovery
    102221//    std::vector<atomId_t> atomids;
     
    116235
    117236    std::map<atomId_t, Vector> GatheredUpdates; //!< gathers all updates which are applied at the end
    118     Vector maxComponents(zeroVec);
    119237    for(typename AtomSetMixin<T>::iterator iter = AtomicForceManipulator<T>::atoms.begin();
    120238        iter != AtomicForceManipulator<T>::atoms.end(); ++iter) {
    121239      // atom's force vector gives steepest descent direction
    122       const Vector oldPosition = (*iter)->getPositionAtStep(NextStep-2 >= 0 ? NextStep - 2 : 0);
     240      const Vector oldPosition = (*iter)->getPositionAtStep(CurrentTimeStep-2 >= 0 ? CurrentTimeStep - 2 : 0);
    123241      const Vector currentPosition = (*iter)->getPosition();
    124       const Vector oldGradient = (*iter)->getAtomicForceAtStep(NextStep-2 >= 0 ? NextStep - 2 : 0);
     242      const Vector oldGradient = (*iter)->getAtomicForceAtStep(CurrentTimeStep-2 >= 0 ? CurrentTimeStep - 2 : 0);
    125243      const Vector currentGradient = (*iter)->getAtomicForce();
    126244      LOG(4, "DEBUG: Force for atom " << **iter << " is " << currentGradient);
     
    225343      LOG(3, "DEBUG: Applying update " << update << " to atom " << *walker);
    226344    }
    227 
    228     LOG(1, "STATUS: Largest remaining force components at step #"
    229         << currentStep << " are " << maxComponents);
    230 
    231     // are we in final step? Remember to reset static entities
    232     if (currentStep == maxSteps) {
    233       LOG(2, "DEBUG: Final step, resetting values");
    234       reset();
    235     }
    236345  }
    237346
Note: See TracChangeset for help on using the changeset viewer.