Changeset 6d360a for src/Dynamics/ForceAnnealing.hpp
- Timestamp:
- Jul 20, 2017, 9:38:38 AM (8 years ago)
- 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)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Dynamics/ForceAnnealing.hpp
r4cd46b r6d360a 90 90 * 91 91 * 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) 93 93 * \param offset offset in matrix file to the first force component 94 94 * \todo This is not yet checked if it is correctly working with DoConstrainedMD set >0. 95 95 */ 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) 97 100 { 98 101 // make sum of forces equal zero 99 AtomicForceManipulator<T>::correctForceMatrixForFixedCenterOfMass( offset,CurrentTimeStep);102 AtomicForceManipulator<T>::correctForceMatrixForFixedCenterOfMass(_offset, _CurrentTimeStep); 100 103 101 104 // are we in initial step? Then set static entities 105 Vector maxComponents(zeroVec); 102 106 if (currentStep == 0) { 103 107 currentDeltat = AtomicForceManipulator<T>::Deltat; 104 108 currentStep = 1; 105 109 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); 106 113 } else { 107 114 ++currentStep; 108 115 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 { 111 230 // get nodes on either side of selected bond via BFS discovery 112 231 BoostGraphCreator BGcreator; … … 375 494 } 376 495 377 Vector maxComponents(zeroVec);378 496 for(typename AtomSetMixin<T>::iterator iter = AtomicForceManipulator<T>::atoms.begin(); 379 497 iter != AtomicForceManipulator<T>::atoms.end(); ++iter) { … … 401 519 walker->setAtomicVelocity(update); 402 520 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 entities409 if (currentStep == maxSteps) {410 LOG(2, "DEBUG: Final step, resetting values");411 reset();412 521 } 413 522 }
Note:
See TracChangeset
for help on using the changeset viewer.