Changeset e355762 for src/Dynamics/MinimiseConstrainedPotential.cpp
- Timestamp:
- Mar 1, 2011, 1:17:09 PM (15 years ago)
- Branches:
- Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, AddingActions_SaveParseParticleParameters, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, AtomFragments, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, Candidate_v1.7.0, Candidate_v1.7.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, CombiningParticlePotentialParsing, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_BoundInBox_CenterInBox_MoleculeActions, Fix_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_PopActions, Fix_QtFragmentList_sorted_selection, Fix_Restrictedkeyset_FragmentMolecule, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, Fix_fitting_potentials, Fixes, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, FragmentAction_writes_AtomFragments, FragmentMolecule_checks_bonddegrees, GeometryObjects, Gui_Fixes, Gui_displays_atomic_force_velocity, ImplicitCharges, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, MoreRobust_FragmentAutomation, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PdbParser_setsAtomName, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, Rewrite_FitPartialCharges, RotateToPrincipalAxisSystem_UndoRedo, SaturateAtoms_findBestMatching, SaturateAtoms_singleDegree, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, Switchable_LogView, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, TremoloParser_setsAtomName, Ubuntu_1604_changes, stable
- Children:
- eb33c4
- Parents:
- fe6f20
- git-author:
- Frederik Heber <heber@…> (02/25/11 11:41:34)
- git-committer:
- Frederik Heber <heber@…> (03/01/11 13:17:09)
- File:
-
- 1 edited
-
src/Dynamics/MinimiseConstrainedPotential.cpp (modified) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Dynamics/MinimiseConstrainedPotential.cpp
rfe6f20 re355762 39 39 40 40 41 MinimiseConstrainedPotential::MinimiseConstrainedPotential(molecule::atomSet &_atoms) : 42 atoms(_atoms) 41 MinimiseConstrainedPotential::MinimiseConstrainedPotential( 42 molecule::atomSet &_atoms, 43 std::map<atom*, atom *> &_PermutationMap) : 44 atoms(_atoms), 45 PermutationMap(_PermutationMap) 43 46 {} 44 47 … … 46 49 {} 47 50 48 double MinimiseConstrainedPotential::operator()( atom **&PermutationMap,int _startstep, int _endstep, bool IsAngstroem)51 double MinimiseConstrainedPotential::operator()(int _startstep, int _endstep, bool IsAngstroem) 49 52 { 50 53 double Potential, OldPotential, OlderPotential; 51 PermutationMap = new atom *[atoms.size()];52 DistanceList = new DistanceMap *[atoms.size()];53 DistanceIterators = new DistanceMap::iterator[atoms.size()];54 DoubleList = new int[atoms.size()];55 StepList = new DistanceMap::iterator[atoms.size()];56 54 int round; 57 55 atom *Sprinter = NULL; … … 59 57 60 58 // set to zero 61 for (size_t i=0;i<atoms.size();i++) { 62 PermutationMap[i] = NULL; 63 DoubleList[i] = 0; 64 } 59 PermutationMap.clear(); 60 DoubleList.clear(); 61 for (molecule::atomSet::const_iterator iter = atoms.begin(); iter != atoms.end(); ++iter) { 62 DistanceList[*iter].clear(); 63 } 64 DistanceList.clear(); 65 DistanceIterators.clear(); 66 DistanceIterators.clear(); 65 67 66 68 /// Minimise the potential … … 79 81 DoLog(1) && (Log() << Verbose(1) << "Making the PermutationMap injective ... " << endl); 80 82 MakeInjectivePermutation(); 81 delete[](DoubleList);83 DoubleList.clear(); 82 84 83 85 // argument minimise the constrained potential in this injective PermutationMap … … 92 94 iter = atoms.begin(); 93 95 for (; iter != atoms.end(); ++iter) { 96 CalculateDoubleList(); 94 97 PrintPermutationMap(); 95 Sprinter = DistanceIterators[(*iter) ->getNr()]->second; // store initial partner96 Strider = DistanceIterators[(*iter) ->getNr()]; //remember old iterator97 DistanceIterators[(*iter) ->getNr()] = StepList[(*iter)->getNr()];98 if (DistanceIterators[(*iter) ->getNr()] == DistanceList[(*iter)->getNr()]->end()) {// stop, before we run through the list and still on99 DistanceIterators[(*iter) ->getNr()] == DistanceList[(*iter)->getNr()]->begin();98 Sprinter = DistanceIterators[(*iter)]->second; // store initial partner 99 Strider = DistanceIterators[(*iter)]; //remember old iterator 100 DistanceIterators[(*iter)] = StepList[(*iter)]; 101 if (DistanceIterators[(*iter)] == DistanceList[(*iter)].end()) {// stop, before we run through the list and still on 102 DistanceIterators[(*iter)] == DistanceList[(*iter)].begin(); 100 103 break; 101 104 } 102 //Log() << Verbose(2) << "Current Walker: " << *(*iter) << " with old/next candidate " << *Sprinter << "/" << *DistanceIterators[(*iter) ->getNr()]->second << "." << endl;105 //Log() << Verbose(2) << "Current Walker: " << *(*iter) << " with old/next candidate " << *Sprinter << "/" << *DistanceIterators[(*iter)]->second << "." << endl; 103 106 // find source of the new target 104 107 molecule::atomSet::const_iterator runner = atoms.begin(); 105 108 for (; runner != atoms.end(); ++runner) { // find the source whose toes we might be stepping on (Walker's new target should be in use by another already) 106 if (PermutationMap[(*runner) ->getNr()] == DistanceIterators[(*iter)->getNr()]->second) {107 //Log() << Verbose(2) << "Found the corresponding owner " << *(*runner) << " to " << *PermutationMap[(*runner) ->getNr()] << "." << endl;109 if (PermutationMap[(*runner)] == DistanceIterators[(*iter)]->second) { 110 //Log() << Verbose(2) << "Found the corresponding owner " << *(*runner) << " to " << *PermutationMap[(*runner)] << "." << endl; 108 111 break; 109 112 } … … 111 114 if (runner != atoms.end()) { // we found the other source 112 115 // then look in its distance list for Sprinter 113 Rider = DistanceList[(*runner) ->getNr()]->begin();114 for (; Rider != DistanceList[(*runner) ->getNr()]->end(); Rider++)116 Rider = DistanceList[(*runner)].begin(); 117 for (; Rider != DistanceList[(*runner)].end(); Rider++) 115 118 if (Rider->second == Sprinter) 116 119 break; 117 if (Rider != DistanceList[(*runner) ->getNr()]->end()) { // if we have found one118 //Log() << Verbose(2) << "Current Other: " << *(*runner) << " with old/next candidate " << *PermutationMap[(*runner) ->getNr()] << "/" << *Rider->second << "." << endl;120 if (Rider != DistanceList[(*runner)].end()) { // if we have found one 121 //Log() << Verbose(2) << "Current Other: " << *(*runner) << " with old/next candidate " << *PermutationMap[(*runner)] << "/" << *Rider->second << "." << endl; 119 122 // exchange both 120 PermutationMap[(*iter)->getNr()] = DistanceIterators[(*iter)->getNr()]->second; // put next farther distance into PermutationMap 121 PermutationMap[(*runner)->getNr()] = Sprinter; // and hand the old target to its respective owner 123 PermutationMap[(*iter)] = DistanceIterators[(*iter)]->second; // put next farther distance into PermutationMap 124 PermutationMap[(*runner)] = Sprinter; // and hand the old target to its respective owner 125 CalculateDoubleList(); 122 126 PrintPermutationMap(); 123 127 // calculate the new potential … … 126 130 if (Potential > OldPotential) { // we made everything worse! Undo ... 127 131 //Log() << Verbose(3) << "Nay, made the potential worse: " << Potential << " vs. " << OldPotential << "!" << endl; 128 //Log() << Verbose(3) << "Setting " << *(*runner) << "'s source to " << *DistanceIterators[(*runner) ->getNr()]->second << "." << endl;132 //Log() << Verbose(3) << "Setting " << *(*runner) << "'s source to " << *DistanceIterators[(*runner)]->second << "." << endl; 129 133 // Undo for Runner (note, we haven't moved the iteration yet, we may use this) 130 PermutationMap[(*runner) ->getNr()] = DistanceIterators[(*runner)->getNr()]->second;134 PermutationMap[(*runner)] = DistanceIterators[(*runner)]->second; 131 135 // Undo for Walker 132 DistanceIterators[(*iter) ->getNr()] = Strider; // take next farther distance target133 //Log() << Verbose(3) << "Setting " << *(*iter) << "'s source to " << *DistanceIterators[(*iter) ->getNr()]->second << "." << endl;134 PermutationMap[(*iter) ->getNr()] = DistanceIterators[(*iter)->getNr()]->second;136 DistanceIterators[(*iter)] = Strider; // take next farther distance target 137 //Log() << Verbose(3) << "Setting " << *(*iter) << "'s source to " << *DistanceIterators[(*iter)]->second << "." << endl; 138 PermutationMap[(*iter)] = DistanceIterators[(*iter)]->second; 135 139 } else { 136 DistanceIterators[(*runner) ->getNr()] = Rider; // if successful also move the pointer in the iterator list140 DistanceIterators[(*runner)] = Rider; // if successful also move the pointer in the iterator list 137 141 DoLog(3) && (Log() << Verbose(3) << "Found a better permutation, new potential is " << Potential << " vs." << OldPotential << "." << endl); 138 142 OldPotential = Potential; … … 148 152 } 149 153 } else { 150 PermutationMap[(*iter) ->getNr()] = DistanceIterators[(*iter)->getNr()]->second; // new target has no source!154 PermutationMap[(*iter)] = DistanceIterators[(*iter)]->second; // new target has no source! 151 155 } 152 StepList[(*iter) ->getNr()]++; // take next farther distance target156 StepList[(*iter)]++; // take next farther distance target 153 157 } 154 158 } while (++iter != atoms.end()); … … 157 161 158 162 159 /// free memory and return with evaluated potential160 for (int i=atoms.size(); i--;)161 DistanceList[i]->clear();162 delete[](DistanceList);163 delete[](DistanceIterators);164 163 return ConstrainedPotential(); 165 164 }; … … 167 166 void MinimiseConstrainedPotential::FillDistanceList() 168 167 { 169 for (int i=atoms.size(); i--;) {170 DistanceList[i] = new DistanceMap; // is the distance sorted target list per atom171 DistanceList[i]->clear();172 }173 174 168 for (molecule::atomSet::const_iterator iter = atoms.begin(); iter != atoms.end(); ++iter) { 175 169 for (molecule::atomSet::const_iterator runner = atoms.begin(); runner != atoms.end(); ++runner) { 176 DistanceList[(*iter) ->getNr()]->insert( DistancePair((*iter)->getPositionAtStep(startstep).distance((*runner)->getPositionAtStep(endstep)), (*runner)) );170 DistanceList[(*iter)].insert( DistancePair((*iter)->getPositionAtStep(startstep).distance((*runner)->getPositionAtStep(endstep)), (*runner)) ); 177 171 } 178 172 } … … 182 176 { 183 177 for (molecule::atomSet::const_iterator iter = atoms.begin(); iter != atoms.end(); ++iter) { 184 StepList[(*iter) ->getNr()] = DistanceList[(*iter)->getNr()]->begin(); // stores the step to the next iterator that could be a possible next target185 PermutationMap[(*iter) ->getNr()] = DistanceList[(*iter)->getNr()]->begin()->second; // always pick target with the smallest distance186 DoubleList[DistanceList[(*iter) ->getNr()]->begin()->second->getNr()]++; // increase this target's source count (>1? not injective)187 DistanceIterators[(*iter) ->getNr()] = DistanceList[(*iter)->getNr()]->begin(); // and remember which one we picked188 DoLog(2) && (Log() << Verbose(2) << **iter << " starts with distance " << DistanceList[(*iter) ->getNr()]->begin()->first << "." << endl);178 StepList[(*iter)] = DistanceList[(*iter)].begin(); // stores the step to the next iterator that could be a possible next target 179 PermutationMap[(*iter)] = DistanceList[(*iter)].begin()->second; // always pick target with the smallest distance 180 DoubleList[DistanceList[(*iter)].begin()->second]++; // increase this target's source count (>1? not injective) 181 DistanceIterators[(*iter)] = DistanceList[(*iter)].begin(); // and remember which one we picked 182 DoLog(2) && (Log() << Verbose(2) << **iter << " starts with distance " << DistanceList[(*iter)].begin()->first << "." << endl); 189 183 } 190 184 }; … … 201 195 } 202 196 while ((Potential) > PenaltyConstants[2]) { 197 CalculateDoubleList(); 203 198 PrintPermutationMap(); 204 199 iter++; 205 200 if (iter == atoms.end()) // round-robin at the end 206 201 iter = atoms.begin(); 207 if (DoubleList[DistanceIterators[(*iter) ->getNr()]->second->getNr()] <= 1) // no need to make those injective that aren't202 if (DoubleList[DistanceIterators[(*iter)]->second] <= 1) // no need to make those injective that aren't 208 203 continue; 209 204 // now, try finding a new one 210 205 Potential = TryNextNearestNeighbourForInjectivePermutation((*iter), Potential); 211 206 } 212 for (int i=atoms.size(); i--;) // now each single entry in the DoubleList should be <=1 213 if (DoubleList[i] > 1) { 207 for (molecule::atomSet::const_iterator iter = atoms.begin(); iter != atoms.end(); ++iter) { 208 // now each single entry in the DoubleList should be <=1 209 if (DoubleList[*iter] > 1) { 214 210 DoeLog(0) && (eLog()<< Verbose(0) << "Failed to create an injective PermutationMap!" << endl); 215 211 performCriticalExit(); 216 212 } 213 } 217 214 DoLog(1) && (Log() << Verbose(1) << "done." << endl); 218 215 }; 219 216 217 unsigned int MinimiseConstrainedPotential::CalculateDoubleList() 218 { 219 for (molecule::atomSet::const_iterator iter = atoms.begin(); iter != atoms.end(); ++iter) 220 DoubleList[*iter] = 0; 221 unsigned int doubles = 0; 222 for (molecule::atomSet::const_iterator iter = atoms.begin(); iter != atoms.end(); ++iter) 223 DoubleList[ PermutationMap[*iter] ]++; 224 for (molecule::atomSet::const_iterator iter = atoms.begin(); iter != atoms.end(); ++iter) 225 if (DoubleList[*iter] > 1) 226 doubles++; 227 if (doubles >0) 228 DoLog(2) && (Log() << Verbose(2) << "Found " << doubles << " Doubles." << endl); 229 return doubles; 230 }; 231 220 232 void MinimiseConstrainedPotential::PrintPermutationMap() const 221 233 { 222 234 stringstream zeile1, zeile2; 223 const int AtomCount = atoms.size();224 int *DoubleList = new int[AtomCount];225 for(int i=0;i<AtomCount;i++)226 DoubleList[i] = 0;227 235 int doubles = 0; 228 236 zeile1 << "PermutationMap: "; 229 237 zeile2 << " "; 230 for (int i=0;i<AtomCount;i++) { 231 DoubleList[PermutationMap[i]->getNr()]++; 232 zeile1 << i << " "; 233 zeile2 << PermutationMap[i]->getNr() << " "; 234 } 235 for (int i=0;i<AtomCount;i++) 236 if (DoubleList[i] > 1) 237 doubles++; 238 for (molecule::atomSet::const_iterator iter = atoms.begin(); iter != atoms.end(); ++iter) { 239 zeile1 << (*iter)->getName() << " "; 240 zeile2 << (PermutationMap[*iter])->getName() << " "; 241 } 242 for (molecule::atomSet::const_iterator iter = atoms.begin(); iter != atoms.end(); ++iter) { 243 std::map<atom *, unsigned int>::const_iterator value_iter = DoubleList.find(*iter); 244 if (value_iter->second > (unsigned int)1) 245 doubles++; 246 } 238 247 if (doubles >0) 239 248 DoLog(2) && (Log() << Verbose(2) << "Found " << doubles << " Doubles." << endl); 240 delete[](DoubleList);241 249 // Log() << Verbose(2) << zeile1.str() << endl << zeile2.str() << endl; 242 250 }; … … 250 258 for (molecule::atomSet::const_iterator iter = atoms.begin(); iter != atoms.end(); ++iter) { 251 259 // first term: distance to target 252 Runner = PermutationMap[(*iter) ->getNr()]; // find target point260 Runner = PermutationMap[(*iter)]; // find target point 253 261 tmp = ((*iter)->getPositionAtStep(startstep).distance(Runner->getPositionAtStep(endstep))); 254 262 tmp *= IsAngstroem ? 1. : 1./AtomicLengthToAngstroem; … … 269 277 { 270 278 double Potential = 0; 271 DistanceMap::iterator NewBase = DistanceIterators[Walker ->getNr()]; // store old base279 DistanceMap::iterator NewBase = DistanceIterators[Walker]; // store old base 272 280 do { 273 281 NewBase++; // take next further distance in distance to targets list that's a target of no one 274 } while ((DoubleList[NewBase->second ->getNr()] != 0) && (NewBase != DistanceList[Walker->getNr()]->end()));275 if (NewBase != DistanceList[Walker ->getNr()]->end()) {276 PermutationMap[Walker ->getNr()] = NewBase->second;282 } while ((DoubleList[NewBase->second] != 0) && (NewBase != DistanceList[Walker].end())); 283 if (NewBase != DistanceList[Walker].end()) { 284 PermutationMap[Walker] = NewBase->second; 277 285 Potential = fabs(ConstrainedPotential()); 278 286 if (Potential > OldPotential) { // undo 279 PermutationMap[Walker ->getNr()] = DistanceIterators[Walker->getNr()]->second;287 PermutationMap[Walker] = DistanceIterators[Walker]->second; 280 288 } else { // do 281 DoubleList[DistanceIterators[Walker ->getNr()]->second->getNr()]--; // decrease the old entry in the doubles list282 DoubleList[NewBase->second ->getNr()]++; // increase the old entry in the doubles list283 DistanceIterators[Walker ->getNr()] = NewBase;289 DoubleList[DistanceIterators[Walker]->second]--; // decrease the old entry in the doubles list 290 DoubleList[NewBase->second]++; // increase the old entry in the doubles list 291 DistanceIterators[Walker] = NewBase; 284 292 OldPotential = Potential; 285 293 DoLog(3) && (Log() << Verbose(3) << "Found a new permutation, new potential is " << OldPotential << "." << endl); … … 293 301 double result = 0.; 294 302 for (molecule::atomSet::const_iterator iter = atoms.begin(); iter != atoms.end(); ++iter) { 295 if ((PermutationMap[Walker ->getNr()] == PermutationMap[(*iter)->getNr()]) && (Walker->getNr() < (*iter)->getNr())) {303 if ((PermutationMap[Walker] == PermutationMap[(*iter)]) && (Walker < (*iter))) { 296 304 // atom *Sprinter = PermutationMap[Walker->nr]; 297 305 // Log() << Verbose(0) << *Walker << " and " << *(*iter) << " are heading to the same target at "; … … 317 325 break; 318 326 // determine normalized trajectories direction vector (n1, n2) 319 Sprinter = PermutationMap[Walker ->getNr()]; // find first target point327 Sprinter = PermutationMap[Walker]; // find first target point 320 328 trajectory1 = Sprinter->getPositionAtStep(endstep) - Walker->getPositionAtStep(startstep); 321 329 trajectory1.Normalize(); 322 330 Norm1 = trajectory1.Norm(); 323 Sprinter = PermutationMap[(*iter) ->getNr()]; // find second target point331 Sprinter = PermutationMap[(*iter)]; // find second target point 324 332 trajectory2 = Sprinter->getPositionAtStep(endstep) - (*iter)->getPositionAtStep(startstep); 325 333 trajectory2.Normalize(); … … 329 337 tmp = Walker->getPositionAtStep(startstep).distance((*iter)->getPositionAtStep(startstep)); 330 338 } else if (Norm1 < MYEPSILON) { 331 Sprinter = PermutationMap[Walker ->getNr()]; // find first target point339 Sprinter = PermutationMap[Walker]; // find first target point 332 340 trajectory1 = Sprinter->getPositionAtStep(endstep) - (*iter)->getPositionAtStep(startstep); 333 341 trajectory2 *= trajectory1.ScalarProduct(trajectory2); // trajectory2 is scaled to unity, hence we don't need to divide by anything … … 335 343 tmp = trajectory1.Norm(); // remaining norm is distance 336 344 } else if (Norm2 < MYEPSILON) { 337 Sprinter = PermutationMap[(*iter) ->getNr()]; // find second target point345 Sprinter = PermutationMap[(*iter)]; // find second target point 338 346 trajectory2 = Sprinter->getPositionAtStep(endstep) - Walker->getPositionAtStep(startstep); // copy second offset 339 347 trajectory1 *= trajectory2.ScalarProduct(trajectory1); // trajectory1 is scaled to unity, hence we don't need to divide by anything … … 402 410 DoLog(1) && (Log() << Verbose(1) << "Calculating forces and adding onto ForceMatrix ... " << endl); 403 411 for(molecule::atomSet::const_iterator iter = atoms.begin(); iter != atoms.end(); ++iter) { 404 atom *Sprinter = PermutationMap[(*iter) ->getNr()];412 atom *Sprinter = PermutationMap[(*iter)]; 405 413 // set forces 406 414 for (int i=NDIM;i++;)
Note:
See TracChangeset
for help on using the changeset viewer.
