Changeset a1fe77 for src/molecules.cpp
- Timestamp:
- Sep 11, 2008, 1:28:25 PM (16 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, 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:
- 85bac0
- Parents:
- 6e9353
- git-author:
- Frederik Heber <heber@…> (09/05/08 16:56:31)
- git-committer:
- Frederik Heber <heber@…> (09/11/08 13:28:25)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/molecules.cpp
r6e9353 ra1fe77 1017 1017 * \sa molecule::MinimiseConstrainedPotential(), molecule::VerletForceIntegration() 1018 1018 * \param *out output stream for debugging 1019 * \param * permutation gives target indexfor each atom, array of size molecule::AtomCount (this is "x" in \f$V^{con}(x)\f$)1019 * \param *PermutationMap gives target ptr for each atom, array of size molecule::AtomCount (this is "x" in \f$V^{con}(x)\f$) 1020 1020 * \param startstep start configuration (MDStep in molecule::trajectories) 1021 1021 * \param endstep end configuration (MDStep in molecule::trajectories) … … 1025 1025 * \note This routine is scaling quadratically which is not optimal. 1026 1026 */ 1027 double molecule::ConstrainedPotential(ofstream *out, int *permutation, int startstep, int endstep, double *constants, bool IsAngstroem)1027 double molecule::ConstrainedPotential(ofstream *out, atom **PermutationMap, int startstep, int endstep, double *constants, bool IsAngstroem) 1028 1028 { 1029 1029 double result = 0., tmp; … … 1038 1038 Walker = Walker->next; 1039 1039 // first term: distance to target 1040 Runner = FindAtom(permutation[Walker->nr]); // find target point 1041 result += constants[0] * (Trajectories[Walker].R.at(startstep).Distance(&Trajectories[Runner].R.at(endstep))); 1040 Runner = PermutationMap[Walker->nr]; // find target point 1041 tmp = (Trajectories[Walker].R.at(startstep).Distance(&Trajectories[Runner].R.at(endstep))); 1042 tmp *= IsAngstroem ? 1. : 1./AtomicLengthToAngstroem; 1043 result += constants[0] * tmp; 1042 1044 1043 1045 // second term: sum of distances to other trajectories … … 1046 1048 Runner = Runner->next; 1047 1049 // determine normalized trajectories direction vector (n1, n2) 1048 Sprinter = FindAtom(permutation[Walker->nr]); // find target point1050 Sprinter = PermutationMap[Walker->nr]; // find target point 1049 1051 trajectory1.CopyVector(&Trajectories[Sprinter].R.at(endstep)); 1050 1052 trajectory1.SubtractVector(&Trajectories[Walker].R.at(startstep)); 1051 1053 trajectory1.Normalize(); 1052 Sprinter = FindAtom(permutation[Runner->nr]); // find target point1054 Sprinter = PermutationMap[Runner->nr]; // find target point 1053 1055 trajectory2.CopyVector(&Trajectories[Sprinter].R.at(endstep)); 1054 1056 trajectory2.SubtractVector(&Trajectories[Runner].R.at(startstep)); … … 1088 1090 *out << "Test: ok.\tDistance of " << tmp << " is correct." << endl; 1089 1091 } else { 1090 *out << "Test: failed.\t Difference in intersection is";1092 *out << "Test: failed.\tIntersection is off by "; 1091 1093 *out << TestVector; 1092 1094 *out << "." << endl; … … 1094 1096 } 1095 1097 // add up 1098 tmp *= IsAngstroem ? 1. : 1./AtomicLengthToAngstroem; 1096 1099 result += constants[1] * 1./tmp; 1097 1100 } … … 1101 1104 while (Runner->next != end) { 1102 1105 Runner = Runner->next; 1103 if (( permutation[Walker->nr] == permutation[Runner->nr]) && (Walker->nr < Runner->nr)) {1104 Sprinter = FindAtom(permutation[Walker->nr]);1106 if ((PermutationMap[Walker->nr] == PermutationMap[Runner->nr]) && (Walker->nr < Runner->nr)) { 1107 Sprinter = PermutationMap[Walker->nr]; 1105 1108 *out << *Walker << " and " << *Runner << " are heading to the same target at "; 1106 1109 *out << Trajectories[Sprinter].R.at(endstep); … … 1114 1117 }; 1115 1118 1119 void PrintPermutationMap(ofstream *out, atom **PermutationMap, int Nr) 1120 { 1121 stringstream zeile1, zeile2; 1122 zeile1 << "PermutationMap: "; 1123 zeile2 << " "; 1124 for (int i=0;i<Nr;i++) { 1125 zeile1 << i << "\t"; 1126 zeile2 << PermutationMap[i]->nr << "\t"; 1127 } 1128 *out << zeile1 << endl << zeile2 << endl; 1129 }; 1130 1116 1131 /** Minimises the extra potential for constrained molecular dynamics and gives forces and the constrained potential energy. 1117 1132 * We do the following: 1118 * -# First, we minimise the potential, see molecule::ConstrainedPotential() 1133 * -# Generate a distance list from all source to all target points 1134 * -# Sort this per source point 1135 * -# Take for each source point the target point with minimum distance, use this as initial permutation 1136 * -# check whether molecule::ConstrainedPotential() is greater than injective penalty 1137 * -# If so, we go through each source point, stepping down in the sorted target point distance list and re-checking potential. 1138 * -# Next, we only apply transformations that keep the injectivity of the permutations list. 1139 * -# Hence, we for one source point we step down the ladder and seek the corresponding owner of this new target 1140 * point and try to change it for one with lesser distance, or for the next one with greater distance, but only 1141 * if this decreases the conditional potential. 1142 * -# finished. 1119 1143 * -# Then, we calculate the forces by taking the spatial derivative, where we scale the potential to such a degree, 1120 1144 * that the total force is always pointing in direction of the constraint force (ensuring that we move in the … … 1123 1147 * \param *out output stream for debugging 1124 1148 * \param *Force ForceMatrix containing force vectors from the external energy functional minimisation. 1125 * \param targetstep target step between which and the predecessor we perform the constrained MD 1149 * \param startstep current MD step giving initial position between which and \a endstep we perform the constrained MD (as further steps are always concatenated) 1150 * \param endstep step giving final position in constrained MD 1151 * \param IsAngstroem whether coordinates are in angstroem (true) or bohrradius (false) 1126 1152 * \sa molecule::VerletForceIntegration() 1127 1153 * \return potential energy 1128 1154 */ 1129 double molecule::MinimiseConstrainedPotential(ofstream *out, ForceMatrix *Force, int targetstep) 1130 { 1131 double potential = 0.; 1132 // Minimise the potential 1133 1134 // evaluate forces 1135 1136 // evaluate potential and return 1137 return potential; 1155 double molecule::MinimiseConstrainedPotential(ofstream *out, ForceMatrix *Force, int startstep, int endstep, bool IsAngstroem) 1156 { 1157 double Potential, OldPotential; 1158 atom **PermutationMap = (atom **) Malloc(AtomCount*sizeof(atom *), "molecule::MinimiseConstrainedPotential: *PermutationMap"); 1159 DistanceMap **DistanceList = (DistanceMap **) Malloc(AtomCount*sizeof(DistanceMap *), "molecule::MinimiseConstrainedPotential: **DistanceList"); 1160 DistanceMap::iterator *DistanceIterators = (DistanceMap::iterator *) Malloc(AtomCount*sizeof(DistanceMap::iterator), "molecule::MinimiseConstrainedPotential: *DistanceIterators"); 1161 double constants[3]; 1162 atom *Walker = NULL, *Runner = NULL, *Sprinter = NULL; 1163 1164 /// Minimise the potential 1165 // set constants (TODO) 1166 constants[0] = 10.; 1167 constants[1] = 1.; 1168 constants[2] = 1e+7; // just a huge penalty 1169 // generate the distance list 1170 *out << Verbose(1) << "Generating the distance list ... " << endl; 1171 for (int i=AtomCount; i--;) { 1172 DistanceList[i] = new DistanceMap; 1173 DistanceList[i]->clear(); 1174 } 1175 Walker = start; 1176 while (Walker->next != NULL) { 1177 Walker = Walker->next; 1178 Runner = start; 1179 while(Runner->next != NULL) { 1180 Runner = Runner->next; 1181 DistanceList[Walker->nr]->insert( DistancePair(Trajectories[Walker].R.at(startstep).Distance(&Trajectories[Runner].R.at(endstep)), Runner) ); 1182 } 1183 } 1184 // create the initial PermutationMap 1185 Walker = start; 1186 while (Walker->next != NULL) { 1187 Walker = Walker->next; 1188 PermutationMap[Walker->nr] = DistanceList[Walker->nr]->begin()->second; 1189 DistanceIterators[Walker->nr] = DistanceList[Walker->nr]->begin(); 1190 *out << *Walker << " starts with distance " << DistanceList[Walker->nr]->begin()->first << "." << endl; 1191 } 1192 // make the PermutationMap injective 1193 *out << Verbose(1) << "Making the PermutationMap injective ... " << endl; 1194 Walker = start; 1195 while ((OldPotential = fabs(ConstrainedPotential(out, PermutationMap, startstep, endstep, constants, IsAngstroem)) > constants[2])) { 1196 PrintPermutationMap(out, PermutationMap, AtomCount); 1197 Walker = Walker->next; 1198 if (Walker == end) // round-robin at the end 1199 Walker = start->next; 1200 DistanceIterators[Walker->nr]++; // take next further distance in distance to targets list 1201 PermutationMap[Walker->nr] = DistanceIterators[Walker->nr]->second; 1202 } 1203 // argument minimise the constrained potential in this injective PermutationMap 1204 *out << Verbose(1) << "Argument minimising the PermutationMap ... " << endl; 1205 do { 1206 PrintPermutationMap(out, PermutationMap, AtomCount); 1207 Walker = start; 1208 while (Walker->next != end) { // pick one 1209 Walker = Walker->next; 1210 Sprinter = DistanceIterators[Walker->nr]->second; // store initial partner 1211 DistanceIterators[Walker->nr]++; // take next farther distance target 1212 PermutationMap[Walker->nr] = DistanceIterators[Walker->nr]->second; 1213 Runner = start; 1214 while(Runner->next != end) { // find the other whose toes were stepping on (this target should be used by another already 1215 Runner = Runner->next; 1216 if (PermutationMap[Runner->nr] == DistanceIterators[Walker->nr]->second) 1217 break; 1218 } 1219 if (Runner->next != end) { // we found one a tripel 1220 // then look in distance list for Sprinter 1221 DistanceMap::iterator Rider = DistanceList[Walker->nr]->begin(); 1222 for (; Rider != DistanceList[Walker->nr]->end(); Rider++) 1223 if (Rider->second == Sprinter) 1224 break; 1225 if (Rider != DistanceList[Walker->nr]->end()) { // if we have found one 1226 // exchange the second also 1227 PermutationMap[Runner->nr] = Rider->second; 1228 // calculate the new potential 1229 Potential = ConstrainedPotential(out, PermutationMap, startstep, endstep, constants, IsAngstroem); 1230 if (Potential > OldPotential) { // we made everything worse! Undo ... 1231 // Undo for Walker 1232 DistanceIterators[Walker->nr]--; // take next farther distance target 1233 PermutationMap[Walker->nr] = Sprinter; 1234 // Undo for Runner (note, we haven't moved the iteration yet, we may use this) 1235 PermutationMap[Runner->nr] = DistanceIterators[Runner->nr]->second; 1236 } else { 1237 DistanceIterators[Runner->nr] = Rider; // if successful also move the pointer in the iterator list 1238 OldPotential = Potential; 1239 *out << "Found a better permutation, new potential is " << OldPotential << "." << endl; 1240 break; 1241 } 1242 if (Potential > constants[2]) 1243 cerr << "ERROR: The two-step permutation procedure did not maintain injectivity!" << endl; 1244 } 1245 } else { 1246 DistanceIterators[Walker->nr]--; // take next farther distance target 1247 PermutationMap[Walker->nr] = DistanceIterators[Walker->nr]->second; 1248 } 1249 } 1250 } while (Walker->next != end); 1251 1252 /// evaluate forces (only the distance to target dependent part) with the final PermutationMap 1253 *out << Verbose(1) << "Calculating forces and adding onto ForceMatrix ... " << endl; 1254 Walker = start; 1255 while (Walker->next != NULL) { 1256 Walker = Walker->next; 1257 Sprinter = PermutationMap[Walker->nr]; 1258 // set forces 1259 for (int i=NDIM;i++;) 1260 Force->Matrix[0][Walker->nr][5+i] += 2.*constants[0]*sqrt(Trajectories[Walker].R.at(startstep).Distance(&Trajectories[Sprinter].R.at(endstep))); 1261 } 1262 1263 /// evaluate potential, free memory and return 1264 for (int i=AtomCount; i--;) 1265 DistanceList[i]->clear(); 1266 Free((void **)&DistanceList, "molecule::MinimiseConstrainedPotential: **DistanceList"); 1267 Free((void **)&DistanceIterators, "molecule::MinimiseConstrainedPotential: *DistanceIterators"); 1268 Free((void **)&PermutationMap, "molecule::MinimiseConstrainedPotential: *PermutationMap"); 1269 return ConstrainedPotential(out, PermutationMap, startstep, endstep, constants, IsAngstroem); 1138 1270 }; 1139 1271 … … 1188 1320 // solve a constrained potential if we are meant to 1189 1321 if (DoConstrained) { 1190 ConstrainedPotentialEnergy = MinimiseConstrainedPotential(out, &Force, DoConstrained); 1322 // calculate forces and potential 1323 ConstrainedPotentialEnergy = MinimiseConstrainedPotential(out, &Force, DoConstrained, 0, IsAngstroem); 1191 1324 } 1192 1325
Note:
See TracChangeset
for help on using the changeset viewer.