Changeset 8754b1
- Timestamp:
- Jul 5, 2017, 7:46:00 PM (8 years ago)
- Branches:
- ForceAnnealing_oldresults
- Parents:
- bd0159
- git-author:
- Frederik Heber <frederik.heber@…> (05/19/17 14:29:40)
- git-committer:
- Frederik Heber <frederik.heber@…> (07/05/17 19:46:00)
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Actions/MoleculeAction/ForceAnnealingAction.cpp
rbd0159 r8754b1 93 93 set, 94 94 true, 95 params.steps.get()); 95 params.steps.get(), 96 params.MaxDistance.get()); 96 97 // parse forces into next step 97 98 if (!params.forcesfile.get().string().empty()) { -
src/Actions/MoleculeAction/ForceAnnealingAction.def
rbd0159 r8754b1 16 16 // ValueStorage by the token "Z" -> first column: int, Z, "Z" 17 17 // "undefine" if no parameters are required, use (NOPARAM_DEFAULT) for each (undefined) default value 18 #define paramtypes (boost::filesystem::path)(unsigned int)(bool) 19 #define paramtokens ("forces-file")("steps")("output-every-step") 20 #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") 21 #define paramdefaults (PARAM_DEFAULT(""))(NOPARAM_DEFAULT)(PARAM_DEFAULT("0")) 22 #define paramreferences (forcesfile)(steps)(DoOutput) 18 #define paramtypes (boost::filesystem::path)(unsigned int)(bool)(int) 19 #define paramtokens ("forces-file")("steps")("output-every-step")("max-distance") 20 #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") 21 #define paramdefaults (PARAM_DEFAULT(""))(NOPARAM_DEFAULT)(PARAM_DEFAULT("0"))(PARAM_DEFAULT(0)) 22 #define paramreferences (forcesfile)(steps)(DoOutput)(MaxDistance) 23 23 #define paramvalids \ 24 24 (DummyValidator< boost::filesystem::path >()) \ 25 25 (NotZeroValidator< unsigned int >()) \ 26 (DummyValidator<bool>()) 26 (DummyValidator<bool>()) \ 27 (DummyValidator< int >()) 27 28 28 29 #define statetypes (std::vector<AtomicInfo>)(std::vector<AtomicInfo>) -
src/Dynamics/ForceAnnealing.hpp
rbd0159 r8754b1 20 20 #include "CodePatterns/Log.hpp" 21 21 #include "CodePatterns/Verbose.hpp" 22 #include "Descriptors/AtomIdDescriptor.hpp" 22 23 #include "Dynamics/AtomicForceManipulator.hpp" 23 24 #include "Fragmentation/ForceMatrix.hpp" 25 #include "Graph/BoostGraphCreator.hpp" 26 #include "Graph/BoostGraphHelpers.hpp" 27 #include "Graph/BreadthFirstSearchGatherer.hpp" 24 28 #include "Helpers/helpers.hpp" 25 29 #include "Helpers/defs.hpp" … … 29 33 #include "World.hpp" 30 34 31 /** This class is the essential build block for performing structu al optimization.35 /** This class is the essential build block for performing structural optimization. 32 36 * 33 37 * Sadly, we have to use some static instances as so far values cannot be passed 34 38 * between actions. Hence, we need to store the current step and the adaptive- 35 * step width (we cannot perform a line search, as we have no control over the39 * step width (we cannot perform a line search, as we have no control over the 36 40 * calculation of the forces). 41 * 42 * However, we do use the bond graph, i.e. if a single atom needs to be shifted 43 * to the left, then the whole molecule left of it is shifted, too. This is 44 * controlled by the \a max_distance parameter. 37 45 */ 38 46 template <class T> … … 48 56 * \param _IsAngstroem whether length units are in angstroem or bohr radii 49 57 * \param _maxSteps number of optimization steps to perform 58 * \param _max_distance up to this bond order is bond graph taken into account. 50 59 */ 51 60 ForceAnnealing( 52 61 AtomSetMixin<T> &_atoms, 53 62 bool _IsAngstroem, 54 const size_t _maxSteps) : 63 const size_t _maxSteps, 64 const int _max_distance) : 55 65 AtomicForceManipulator<T>(_atoms, 1., _IsAngstroem), 56 maxSteps(_maxSteps) 66 maxSteps(_maxSteps), 67 max_distance(_max_distance), 68 damping_factor(0.5) 57 69 {} 58 70 /** Destructor of class ForceAnnealing. … … 86 98 } 87 99 100 // get nodes on either side of selected bond via BFS discovery 101 // std::vector<atomId_t> atomids; 102 // for(typename AtomSetMixin<T>::iterator iter = AtomicForceManipulator<T>::atoms.begin(); 103 // iter != AtomicForceManipulator<T>::atoms.end(); ++iter) { 104 // atomids.push_back((*iter)->getId()); 105 // } 106 // ASSERT( atomids.size() == AtomicForceManipulator<T>::atoms.size(), 107 // "ForceAnnealing() - could not gather all atomic ids?"); 108 BoostGraphCreator BGcreator; 109 BGcreator.createFromRange( 110 AtomicForceManipulator<T>::atoms.begin(), 111 AtomicForceManipulator<T>::atoms.end(), 112 AtomicForceManipulator<T>::atoms.size(), 113 BreadthFirstSearchGatherer::AlwaysTruePredicate); 114 BreadthFirstSearchGatherer NodeGatherer(BGcreator); 115 116 std::map<atomId_t, Vector> GatheredUpdates; //!< gathers all updates which are applied at the end 88 117 Vector maxComponents(zeroVec); 89 118 for(typename AtomSetMixin<T>::iterator iter = AtomicForceManipulator<T>::atoms.begin(); … … 110 139 LOG(3, "DEBUG: Update would be " << PositionUpdate); 111 140 141 // // add update to central atom 142 // const atomId_t atomid = (*iter)->getId(); 143 // if (GatheredUpdates.count(atomid)) { 144 // GatheredUpdates[atomid] += PositionUpdate; 145 // } else 146 // GatheredUpdates.insert( std::make_pair(atomid, PositionUpdate) ); 147 148 // We assume that a force is local, i.e. a bond is too short yet and hence 149 // the atom needs to be moved. However, all the adjacent (bound) atoms might 150 // already be at the perfect distance. If we just move the atom alone, we ruin 151 // all the other bonds. Hence, it would be sensible to move every atom found 152 // through the bond graph in the direction of the force as well by the same 153 // PositionUpdate. This is just what we are going to do. 154 155 /// get all nodes from bonds in the direction of the current force 156 157 // remove edges facing in the wrong direction 158 std::vector<bond::ptr> removed_bonds; 159 const BondList& ListOfBonds = (*iter)->getListOfBonds(); 160 for(BondList::const_iterator bonditer = ListOfBonds.begin(); 161 bonditer != ListOfBonds.end(); ++bonditer) { 162 const bond ¤t_bond = *(*bonditer); 163 LOG(2, "DEBUG: Looking at bond " << current_bond); 164 Vector BondVector = (*iter)->getPosition(); 165 BondVector -= ((*iter)->getId() == current_bond.rightatom->getId()) 166 ? current_bond.rightatom->getPosition() : current_bond.leftatom->getPosition(); 167 BondVector.Normalize(); 168 if (BondVector.ScalarProduct(currentGradient) < 0) { 169 removed_bonds.push_back(*bonditer); 170 #ifndef NDEBUG 171 const bool status = 172 #endif 173 BGcreator.removeEdge(current_bond.leftatom->getId(), current_bond.rightatom->getId()); 174 ASSERT( status, "ForceAnnealing() - edge to found bond is not present?"); 175 } 176 } 177 BoostGraphHelpers::Nodeset_t bondside_set = NodeGatherer((*iter)->getId(), max_distance); 178 const BreadthFirstSearchGatherer::distance_map_t &distance_map = NodeGatherer.getDistances(); 179 std::sort(bondside_set.begin(), bondside_set.end()); 180 // re-add those edges 181 for (std::vector<bond::ptr>::const_iterator bonditer = removed_bonds.begin(); 182 bonditer != removed_bonds.end(); ++bonditer) 183 BGcreator.addEdge((*bonditer)->leftatom->getId(), (*bonditer)->rightatom->getId()); 184 185 // apply PositionUpdate to all nodes in the bondside_set 186 for (BoostGraphHelpers::Nodeset_t::const_iterator setiter = bondside_set.begin(); 187 setiter != bondside_set.end(); ++setiter) { 188 const BreadthFirstSearchGatherer::distance_map_t::const_iterator diter 189 = distance_map.find(*setiter); 190 ASSERT( diter != distance_map.end(), 191 "ForceAnnealing() - could not find distance to an atom."); 192 const double factor = pow(damping_factor, diter->second); 193 LOG(3, "DEBUG: Update for atom #" << *setiter << " will be " 194 << factor << "*" << PositionUpdate); 195 if (GatheredUpdates.count((*setiter))) { 196 GatheredUpdates[(*setiter)] += factor*PositionUpdate; 197 } else { 198 GatheredUpdates.insert( 199 std::make_pair( 200 (*setiter), 201 factor*PositionUpdate) ); 202 } 203 } 204 112 205 // extract largest components for showing progress of annealing 113 206 for(size_t i=0;i<NDIM;++i) … … 115 208 maxComponents[i] = currentGradient[i]; 116 209 117 // are we in initial step? Then don't check against velocity118 if ((currentStep > 1) && (!(*iter)->getAtomicVelocity().IsZero()))119 // update with currentDelta tells us how the current gradient relates to120 // the last one: If it has become larger, reduce currentDelta121 if ((PositionUpdate.ScalarProduct((*iter)->getAtomicVelocity()) < 0)122 && (currentDeltat > MinimumDeltat)) {123 currentDeltat = .5*currentDeltat;124 LOG(2, "DEBUG: Upgrade in other direction: " << PositionUpdate.NormSquared()125 << " > " << (*iter)->getAtomicVelocity().NormSquared()126 << ", decreasing deltat: " << currentDeltat);127 PositionUpdate = currentDeltat * currentGradient;128 }129 130 // finally set new values131 (*iter)->setPosition(currentPosition + PositionUpdate);132 (*iter)->setAtomicVelocity(PositionUpdate);133 //std::cout << "Id of atom is " << (*iter)->getId() << std::endl;134 // (*iter)->VelocityVerletUpdateU((*iter)->getId(), NextStep-1, Deltat, IsAngstroem);135 136 210 // reset force vector for next step except on final one 137 211 if (currentStep != maxSteps) 138 212 (*iter)->setAtomicForce(zeroVec); 213 } 214 // apply the gathered updates 215 for (std::map<atomId_t, Vector>::const_iterator iter = GatheredUpdates.begin(); 216 iter != GatheredUpdates.end(); ++iter) { 217 const atomId_t &atomid = iter->first; 218 const Vector &update = iter->second; 219 atom* const walker = World::getInstance().getAtom(AtomById(atomid)); 220 ASSERT( walker != NULL, 221 "ForceAnnealing() - walker with id "+toString(atomid)+" has suddenly disappeared."); 222 walker->setPosition( walker->getPosition() + update ); 223 walker->setAtomicVelocity(update); 224 LOG(3, "DEBUG: Applying update " << update << " to atom " << *walker); 139 225 } 140 226 … … 171 257 //!> minimum deltat for internal while loop (adaptive step width) 172 258 static double MinimumDeltat; 259 //!> contains the maximum bond graph distance up to which shifts of a single atom are spread 260 const int max_distance; 261 //!> the shifted is dampened by this factor with the power of the bond graph distance to the shift causing atom 262 const double damping_factor; 173 263 }; 174 264 -
tests/Python/AllActions/options.dat
rbd0159 r8754b1 104 104 load-session "test.py" 105 105 MaxDistance "-1" 106 max-distance "0" 106 107 max-meshwidth "0.3" 107 108 mesh-offset "0.5,0.5,0.5"
Note:
See TracChangeset
for help on using the changeset viewer.