Changeset b2acca for src/Dynamics
- Timestamp:
- Apr 10, 2018, 6:43:11 AM (7 years ago)
- 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)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Dynamics/ForceAnnealing.hpp
recfcf6 rb2acca 80 80 * 81 81 * 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) 83 83 * \param offset offset in matrix file to the first force component 84 84 * \todo This is not yet checked if it is correctly working with DoConstrainedMD set >0. 85 85 */ 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) 87 90 { 88 91 // make sum of forces equal zero 89 AtomicForceManipulator<T>::correctForceMatrixForFixedCenterOfMass( offset,NextStep);92 AtomicForceManipulator<T>::correctForceMatrixForFixedCenterOfMass(_offset, _CurrentTimeStep); 90 93 91 94 // are we in initial step? Then set static entities 95 Vector maxComponents(zeroVec); 92 96 if (currentStep == 0) { 93 97 currentDeltat = AtomicForceManipulator<T>::Deltat; 94 98 currentStep = 1; 95 99 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); 96 103 } else { 97 104 ++currentStep; 98 105 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 { 101 220 // get nodes on either side of selected bond via BFS discovery 102 221 // std::vector<atomId_t> atomids; … … 116 235 117 236 std::map<atomId_t, Vector> GatheredUpdates; //!< gathers all updates which are applied at the end 118 Vector maxComponents(zeroVec);119 237 for(typename AtomSetMixin<T>::iterator iter = AtomicForceManipulator<T>::atoms.begin(); 120 238 iter != AtomicForceManipulator<T>::atoms.end(); ++iter) { 121 239 // 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); 123 241 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); 125 243 const Vector currentGradient = (*iter)->getAtomicForce(); 126 244 LOG(4, "DEBUG: Force for atom " << **iter << " is " << currentGradient); … … 225 343 LOG(3, "DEBUG: Applying update " << update << " to atom " << *walker); 226 344 } 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 entities232 if (currentStep == maxSteps) {233 LOG(2, "DEBUG: Final step, resetting values");234 reset();235 }236 345 } 237 346
Note:
See TracChangeset
for help on using the changeset viewer.