Changeset 85bac0
- 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:
- c30cda
- Parents:
- a1fe77
- git-author:
- Frederik Heber <heber@…> (09/09/08 15:29:58)
- git-committer:
- Frederik Heber <heber@…> (09/11/08 13:28:25)
- Location:
- src
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/builder.cpp
ra1fe77 r85bac0 820 820 cout << "\t-p <file>\tParse given xyz file and create raw config file from it." << endl; 821 821 cout << "\t-P <file>\tParse given forces file and append as an MD step to config file via Verlet." << endl; 822 cout << "\t-L <step0> <step1> <prefix>\tStore a linear interpolation between two configurations <step0> and <step1> into single config files with prefix <prefix> and as Trajectories into the current config file." << endl; 822 823 cout << "\t-r\t\tConvert file from an old pcp syntax." << endl; 823 824 cout << "\t-t x1 x2 x3\tTranslate all atoms by this vector (x1,x2,x3)." << endl; … … 989 990 argptr+=1; 990 991 break; 992 case 'L': 993 ExitFlag = 1; 994 SaveFlag = true; 995 cout << Verbose(1) << "Linear interpolation between configuration " << argv[argptr] << " and " << argv[argptr+1] << "." << endl; 996 if (!mol->LinearInterpolationBetweenConfiguration((ofstream *)&cout, atoi(argv[argptr]), atoi(argv[argptr+1]), argv[argptr+2], configuration)) 997 cout << Verbose(2) << "Could not store " << argv[argptr+2] << " files." << endl; 998 else 999 cout << Verbose(2) << "Steps created and " << argv[argptr+2] << " files stored." << endl; 1000 argptr+=3; 1001 break; 991 1002 case 'P': 992 1003 ExitFlag = 1; -
src/moleculelist.cpp
ra1fe77 r85bac0 378 378 * \param *configuration standard configuration to attach atoms in fragment molecule to. 379 379 * \param *SortIndex Index to map from the BFS labeling to the sequence how of Ion_Type in the config 380 * \param DoPeriodic true - call ScanForPeriodicCorrection, false - don't 381 * \param DoCentering true - call molecule::CenterEdge(), false - don't 380 382 * \return true - success (each file was written), false - something went wrong. 381 383 */ 382 bool MoleculeListClass::OutputConfigForListOfFragments(ofstream *out, con fig *configuration, int *SortIndex)384 bool MoleculeListClass::OutputConfigForListOfFragments(ofstream *out, const char *fragmentprefix, config *configuration, int *SortIndex, bool DoPeriodic, bool DoCentering) 383 385 { 384 386 ofstream outputFragment; … … 404 406 405 407 // correct periodic 406 ListOfMolecules[i]->ScanForPeriodicCorrection(out); 408 if (DoPeriodic) 409 ListOfMolecules[i]->ScanForPeriodicCorrection(out); 407 410 408 411 // output xyz file 409 412 FragmentNumber = FixedDigitNumber(NumberOfMolecules, FragmentCounter++); 410 sprintf(FragmentName, "%s/%s%s.conf.xyz", configuration->configpath, FRAGMENTPREFIX, FragmentNumber);413 sprintf(FragmentName, "%s/%s%s.conf.xyz", configuration->configpath, fragmentprefix, FragmentNumber); 411 414 outputFragment.open(FragmentName, ios::out); 412 *out << Verbose(2) << "Saving bond fragmentNo. " << FragmentNumber << "/" << FragmentCounter-1 << " as XYZ ...";415 *out << Verbose(2) << "Saving " << fragmentprefix << " No. " << FragmentNumber << "/" << FragmentCounter-1 << " as XYZ ..."; 413 416 if ((intermediateResult = ListOfMolecules[i]->OutputXYZ(&outputFragment))) 414 417 *out << " done." << endl; … … 429 432 430 433 // center on edge 431 ListOfMolecules[i]->CenterEdge(out, &BoxDimension); 432 ListOfMolecules[i]->SetBoxDimension(&BoxDimension); // update Box of atoms by boundary 433 int j = -1; 434 for (int k=0;k<NDIM;k++) { 435 j += k+1; 436 BoxDimension.x[k] = 2.5* (configuration->GetIsAngstroem() ? 1. : 1./AtomicLengthToAngstroem); 437 ListOfMolecules[i]->cell_size[j] += BoxDimension.x[k]*2.; 438 } 439 ListOfMolecules[i]->Translate(&BoxDimension); 434 if (DoCentering) { 435 ListOfMolecules[i]->CenterEdge(out, &BoxDimension); 436 ListOfMolecules[i]->SetBoxDimension(&BoxDimension); // update Box of atoms by boundary 437 int j = -1; 438 for (int k=0;k<NDIM;k++) { 439 j += k+1; 440 BoxDimension.x[k] = 2.5* (configuration->GetIsAngstroem() ? 1. : 1./AtomicLengthToAngstroem); 441 ListOfMolecules[i]->cell_size[j] += BoxDimension.x[k]*2.; 442 } 443 ListOfMolecules[i]->Translate(&BoxDimension); 444 } 440 445 441 446 // also calculate necessary orbitals … … 445 450 // change path in config 446 451 //strcpy(PathBackup, configuration->configpath); 447 sprintf(FragmentName, "%s/%s%s/", PathBackup, FRAGMENTPREFIX, FragmentNumber);452 sprintf(FragmentName, "%s/%s%s/", PathBackup, fragmentprefix, FragmentNumber); 448 453 configuration->SetDefaultPath(FragmentName); 449 454 450 455 // and save as config 451 sprintf(FragmentName, "%s/%s%s.conf", configuration->configpath, FRAGMENTPREFIX, FragmentNumber);456 sprintf(FragmentName, "%s/%s%s.conf", configuration->configpath, fragmentprefix, FragmentNumber); 452 457 outputFragment.open(FragmentName, ios::out); 453 *out << Verbose(2) << "Saving bond fragmentNo. " << FragmentNumber << "/" << FragmentCounter-1 << " as config ...";458 *out << Verbose(2) << "Saving " << fragmentprefix << " No. " << FragmentNumber << "/" << FragmentCounter-1 << " as config ..."; 454 459 if ((intermediateResult = configuration->Save(&outputFragment, ListOfMolecules[i]->elemente, ListOfMolecules[i]))) 455 460 *out << " done." << endl; … … 465 470 466 471 // and save as mpqc input file 467 sprintf(FragmentName, "%s/%s%s.in", configuration->configpath, FRAGMENTPREFIX, FragmentNumber);472 sprintf(FragmentName, "%s/%s%s.in", configuration->configpath, fragmentprefix, FragmentNumber); 468 473 outputFragment.open(FragmentName, ios::out); 469 *out << Verbose(2) << "Saving bond fragmentNo. " << FragmentNumber << "/" << FragmentCounter-1 << " as mpqc input ...";474 *out << Verbose(2) << "Saving " << fragmentprefix << " No. " << FragmentNumber << "/" << FragmentCounter-1 << " as mpqc input ..."; 470 475 if ((intermediateResult = configuration->SaveMPQC(&outputFragment, ListOfMolecules[i]))) 471 476 *out << " done." << endl; -
src/molecules.cpp
ra1fe77 r85bac0 1008 1008 1009 1009 /** Evaluates the potential energy used for constrained molecular dynamics. 1010 * \f$V_i^{con} = c^{bond} \cdot | r_{P(i)} - R_i | + sum_{i \neq j} C^{min} \cdot \ tfrac{1}{C_{ij}} + C^{inj} \Bigl (1 - \theta \bigl (\prod_{i \neq j} (P(i) - P(j)) \bigr ) \Bigr )\f$1010 * \f$V_i^{con} = c^{bond} \cdot | r_{P(i)} - R_i | + sum_{i \neq j} C^{min} \cdot \frac{1}{C_{ij}} + C^{inj} \Bigl (1 - \theta \bigl (\prod_{i \neq j} (P(i) - P(j)) \bigr ) \Bigr )\f$ 1011 1011 * where the first term points to the target in minimum distance, the second is a penalty for trajectories lying too close to each other (\f$C_{ij}$ is minimum distance between 1012 1012 * trajectories i and j) and the third term is a penalty for two atoms trying to each the same target point. … … 1024 1024 * \return potential energy 1025 1025 * \note This routine is scaling quadratically which is not optimal. 1026 * \todo There's a bit double counting going on for the first time, bu nothing to worry really about. 1026 1027 */ 1027 1028 double molecule::ConstrainedPotential(ofstream *out, atom **PermutationMap, int startstep, int endstep, double *constants, bool IsAngstroem) 1028 1029 { 1029 double result = 0., tmp ;1030 double result = 0., tmp, Norm1, Norm2; 1030 1031 atom *Walker = NULL, *Runner = NULL, *Sprinter = NULL; 1031 1032 Vector trajectory1, trajectory2, normal, TestVector; … … 1042 1043 tmp *= IsAngstroem ? 1. : 1./AtomicLengthToAngstroem; 1043 1044 result += constants[0] * tmp; 1045 //*out << Verbose(4) << "Adding " << tmp*constants[0] << "." << endl; 1044 1046 1045 1047 // second term: sum of distances to other trajectories … … 1047 1049 while (Runner->next != end) { 1048 1050 Runner = Runner->next; 1051 if (Runner == Walker) // hence, we only go up to the Walker, not beyond (similar to i=0; i<j; i++) 1052 break; 1049 1053 // determine normalized trajectories direction vector (n1, n2) 1050 Sprinter = PermutationMap[Walker->nr]; // find target point1054 Sprinter = PermutationMap[Walker->nr]; // find first target point 1051 1055 trajectory1.CopyVector(&Trajectories[Sprinter].R.at(endstep)); 1052 1056 trajectory1.SubtractVector(&Trajectories[Walker].R.at(startstep)); 1053 1057 trajectory1.Normalize(); 1054 Sprinter = PermutationMap[Runner->nr]; // find target point 1058 Norm1 = trajectory1.Norm(); 1059 Sprinter = PermutationMap[Runner->nr]; // find second target point 1055 1060 trajectory2.CopyVector(&Trajectories[Sprinter].R.at(endstep)); 1056 1061 trajectory2.SubtractVector(&Trajectories[Runner].R.at(startstep)); 1057 1062 trajectory2.Normalize(); 1058 // check whether they're linear dependent 1059 if (fabs(trajectory1.ScalarProduct(&trajectory2)/trajectory1.Norm()/trajectory2.Norm() - 1.) < MYEPSILON) { 1060 *out << "Both trajectories of " << *Walker << " and " << *Runner << " are linear dependent: "; 1061 *out << trajectory1; 1062 *out << " and "; 1063 *out << trajectory2 << endl; 1063 Norm2 = trajectory1.Norm(); 1064 // check whether either is zero() 1065 if ((Norm1 < MYEPSILON) && (Norm2 < MYEPSILON)) { 1064 1066 tmp = Trajectories[Walker].R.at(startstep).Distance(&Trajectories[Runner].R.at(startstep)); 1067 } else if (Norm1 < MYEPSILON) { 1068 Sprinter = PermutationMap[Walker->nr]; // find first target point 1069 trajectory1.CopyVector(&Trajectories[Sprinter].R.at(endstep)); // copy first offset 1070 trajectory1.SubtractVector(&Trajectories[Runner].R.at(startstep)); // subtract second offset 1071 trajectory2.Scale( trajectory1.ScalarProduct(&trajectory2) ); // trajectory2 is scaled to unity, hence we don't need to divide by anything 1072 trajectory1.SubtractVector(&trajectory2); // project the part in norm direction away 1073 tmp = trajectory1.Norm(); // remaining norm is distance 1074 } else if (Norm2 < MYEPSILON) { 1075 Sprinter = PermutationMap[Runner->nr]; // find second target point 1076 trajectory2.CopyVector(&Trajectories[Sprinter].R.at(endstep)); // copy second offset 1077 trajectory2.SubtractVector(&Trajectories[Walker].R.at(startstep)); // subtract first offset 1078 trajectory1.Scale( trajectory2.ScalarProduct(&trajectory1) ); // trajectory1 is scaled to unity, hence we don't need to divide by anything 1079 trajectory2.SubtractVector(&trajectory1); // project the part in norm direction away 1080 tmp = trajectory2.Norm(); // remaining norm is distance 1081 } else if ((fabs(trajectory1.ScalarProduct(&trajectory2)/Norm1/Norm2) - 1.) < MYEPSILON) { // check whether they're linear dependent 1082 // *out << Verbose(3) << "Both trajectories of " << *Walker << " and " << *Runner << " are linear dependent: "; 1083 // *out << trajectory1; 1084 // *out << " and "; 1085 // *out << trajectory2; 1086 tmp = Trajectories[Walker].R.at(startstep).Distance(&Trajectories[Runner].R.at(startstep)); 1087 // *out << " with distance " << tmp << "." << endl; 1065 1088 } else { // determine distance by finding minimum distance 1066 *out << "Both trajectories of " << *Walker << " and " << *Runner << " are linear independent." << endl; 1089 // *out << Verbose(3) << "Both trajectories of " << *Walker << " and " << *Runner << " are linear independent "; 1090 // *out << endl; 1091 // *out << "First Trajectory: "; 1092 // *out << trajectory1 << endl; 1093 // *out << "Second Trajectory: "; 1094 // *out << trajectory2 << endl; 1067 1095 // determine normal vector for both 1068 1096 normal.MakeNormalVector(&trajectory1, &trajectory2); 1097 // print all vectors for debugging 1098 // *out << "Normal vector in between: "; 1099 // *out << normal << endl; 1069 1100 // setup matrix 1070 1101 for (int i=NDIM;i--;) { … … 1077 1108 gsl_linalg_HH_svx(A, x); 1078 1109 // distance from last component 1079 tmp = gsl_vector_get(x,2); 1110 tmp = gsl_vector_get(x,2); 1111 // *out << " with distance " << tmp << "." << endl; 1080 1112 // test whether we really have the intersection (by checking on c_1 and c_2) 1081 1113 TestVector.CopyVector(&Trajectories[Runner].R.at(startstep)); … … 1088 1120 TestVector.SubtractVector(&trajectory1); 1089 1121 if (TestVector.Norm() < MYEPSILON) { 1090 *out<< "Test: ok.\tDistance of " << tmp << " is correct." << endl;1122 // *out << Verbose(2) << "Test: ok.\tDistance of " << tmp << " is correct." << endl; 1091 1123 } else { 1092 *out<< "Test: failed.\tIntersection is off by ";1093 *out << TestVector;1094 *out << "." << endl;1124 // *out << Verbose(2) << "Test: failed.\tIntersection is off by "; 1125 // *out << TestVector; 1126 // *out << "." << endl; 1095 1127 } 1096 1128 } 1097 1129 // add up 1098 1130 tmp *= IsAngstroem ? 1. : 1./AtomicLengthToAngstroem; 1099 result += constants[1] * 1./tmp; 1131 if (fabs(tmp) > MYEPSILON) { 1132 result += constants[1] * 1./tmp; 1133 //*out << Verbose(4) << "Adding " << 1./tmp*constants[1] << "." << endl; 1134 } 1100 1135 } 1101 1136 … … 1106 1141 if ((PermutationMap[Walker->nr] == PermutationMap[Runner->nr]) && (Walker->nr < Runner->nr)) { 1107 1142 Sprinter = PermutationMap[Walker->nr]; 1108 *out << *Walker << " and " << *Runner << " are heading to the same target at ";1109 *out << Trajectories[Sprinter].R.at(endstep);1110 *out << ", penalting." << endl;1143 // *out << *Walker << " and " << *Runner << " are heading to the same target at "; 1144 // *out << Trajectories[Sprinter].R.at(endstep); 1145 // *out << ", penalting." << endl; 1111 1146 result += constants[2]; 1147 //*out << Verbose(4) << "Adding " << constants[2] << "." << endl; 1112 1148 } 1113 1149 } … … 1123 1159 zeile2 << " "; 1124 1160 for (int i=0;i<Nr;i++) { 1125 zeile1 << i << " \t";1126 zeile2 << PermutationMap[i]->nr << " \t";1127 } 1128 *out << zeile1 << endl << zeile2<< endl;1161 zeile1 << i << " "; 1162 zeile2 << PermutationMap[i]->nr << " "; 1163 } 1164 // *out << zeile1.str() << endl << zeile2.str() << endl; 1129 1165 }; 1130 1166 … … 1137 1173 * -# If so, we go through each source point, stepping down in the sorted target point distance list and re-checking potential. 1138 1174 * -# Next, we only apply transformations that keep the injectivity of the permutations list. 1139 * -# Hence, wefor one source point we step down the ladder and seek the corresponding owner of this new target1175 * -# Hence, for one source point we step down the ladder and seek the corresponding owner of this new target 1140 1176 * point and try to change it for one with lesser distance, or for the next one with greater distance, but only 1141 1177 * if this decreases the conditional potential. … … 1146 1182 * -# Finally, we calculate the potential energy and return. 1147 1183 * \param *out output stream for debugging 1148 * \param * Force ForceMatrix containing force vectors from the external energy functional minimisation.1184 * \param **PermutationMap on return: mapping between the atom label of the initial and the final configuration 1149 1185 * \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 1186 * \param endstep step giving final position in constrained MD 1151 1187 * \param IsAngstroem whether coordinates are in angstroem (true) or bohrradius (false) 1152 1188 * \sa molecule::VerletForceIntegration() 1153 * \return potential energy 1154 */ 1155 double molecule::MinimiseConstrainedPotential(ofstream *out, ForceMatrix *Force, int startstep, int endstep, bool IsAngstroem) 1189 * \return potential energy (and allocated **PermutationMap (array of molecule::AtomCount ^2) 1190 * \todo The constrained potential's constants are set to fixed values right now, but they should scale based on checks of the system in order 1191 * to ensure they're properties (e.g. constants[2] always greater than the energy of the system). 1192 * \bug this all is not O(N log N) but O(N^2) 1193 */ 1194 double molecule::MinimiseConstrainedPotential(ofstream *out, atom **&PermutationMap, int startstep, int endstep, bool IsAngstroem) 1156 1195 { 1157 1196 double Potential, OldPotential; 1158 atom **PermutationMap = (atom **) Malloc(AtomCount*sizeof(atom *), "molecule::MinimiseConstrainedPotential:*PermutationMap");1197 PermutationMap = (atom **) Malloc(AtomCount*sizeof(atom *), "molecule::MinimiseConstrainedPotential: **PermutationMap"); 1159 1198 DistanceMap **DistanceList = (DistanceMap **) Malloc(AtomCount*sizeof(DistanceMap *), "molecule::MinimiseConstrainedPotential: **DistanceList"); 1160 DistanceMap::iterator *DistanceIterators = (DistanceMap::iterator *) Malloc(AtomCount*sizeof(DistanceMap::iterator), "molecule::MinimiseConstrainedPotential: *DistanceIterators"); 1199 DistanceMap::iterator *DistanceIterators = (DistanceMap::iterator *) Malloc(AtomCount*sizeof(DistanceMap::iterator), "molecule::MinimiseConstrainedPotential: *DistanceIterators"); 1200 int *DoubleList = (int *) Malloc(AtomCount*sizeof(int), "molecule::MinimiseConstrainedPotential: *DoubleList"); 1161 1201 double constants[3]; 1162 1202 atom *Walker = NULL, *Runner = NULL, *Sprinter = NULL; 1163 1203 DistanceMap::iterator Rider; 1204 1164 1205 /// Minimise the potential 1165 // set constants (TODO)1206 // set Lagrange multiplier constants 1166 1207 constants[0] = 10.; 1167 1208 constants[1] = 1.; 1168 1209 constants[2] = 1e+7; // just a huge penalty 1169 1210 // generate the distance list 1170 *out << Verbose(1) << " Generating the distance list ... " << endl;1211 *out << Verbose(1) << "Creating the distance list ... " << endl; 1171 1212 for (int i=AtomCount; i--;) { 1172 DistanceList[i] = new DistanceMap; 1213 DoubleList[i] = 0; // store's for how many atoms in startstep this atom is a target in endstep 1214 DistanceList[i] = new DistanceMap; // is the distance sorted target list per atom 1173 1215 DistanceList[i]->clear(); 1174 1216 } 1217 *out << Verbose(1) << "Filling the distance list ... " << endl; 1175 1218 Walker = start; 1176 while (Walker->next != NULL) {1219 while (Walker->next != end) { 1177 1220 Walker = Walker->next; 1178 1221 Runner = start; 1179 while(Runner->next != NULL) {1222 while(Runner->next != end) { 1180 1223 Runner = Runner->next; 1181 1224 DistanceList[Walker->nr]->insert( DistancePair(Trajectories[Walker].R.at(startstep).Distance(&Trajectories[Runner].R.at(endstep)), Runner) ); 1182 1225 } 1183 1226 } 1184 // create the initial PermutationMap 1227 // create the initial PermutationMap (source -> target) 1185 1228 Walker = start; 1186 while (Walker->next != NULL) {1229 while (Walker->next != end) { 1187 1230 Walker = Walker->next; 1188 PermutationMap[Walker->nr] = DistanceList[Walker->nr]->begin()->second; 1189 DistanceIterators[Walker->nr] = DistanceList[Walker->nr]->begin(); 1231 PermutationMap[Walker->nr] = DistanceList[Walker->nr]->begin()->second; // always pick target with the smallest distance 1232 DoubleList[DistanceList[Walker->nr]->begin()->second->nr]++; // increase this target's source count (>1? not injective) 1233 DistanceIterators[Walker->nr] = DistanceList[Walker->nr]->begin(); // and remember which one we picked 1190 1234 *out << *Walker << " starts with distance " << DistanceList[Walker->nr]->begin()->first << "." << endl; 1191 1235 } 1192 // make the PermutationMap injective 1236 *out << Verbose(1) << "done." << endl; 1237 // make the PermutationMap injective by checking whether we have a non-zero constants[2] term in it 1193 1238 *out << Verbose(1) << "Making the PermutationMap injective ... " << endl; 1194 1239 Walker = start; 1195 while ((OldPotential = fabs(ConstrainedPotential(out, PermutationMap, startstep, endstep, constants, IsAngstroem)) > constants[2])) { 1240 DistanceMap::iterator NewBase; 1241 OldPotential = fabs(ConstrainedPotential(out, PermutationMap, startstep, endstep, constants, IsAngstroem)); 1242 while ((OldPotential) > constants[2]) { 1196 1243 PrintPermutationMap(out, PermutationMap, AtomCount); 1197 1244 Walker = Walker->next; 1198 1245 if (Walker == end) // round-robin at the end 1199 1246 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 } 1247 if (DoubleList[DistanceIterators[Walker->nr]->second->nr] <= 1) // no need to make those injective that aren't 1248 continue; 1249 // now, try finding a new one 1250 NewBase = DistanceIterators[Walker->nr]; // store old base 1251 do { 1252 NewBase++; // take next further distance in distance to targets list that's a target of no one 1253 } while ((DoubleList[NewBase->second->nr] != 0) && (NewBase != DistanceList[Walker->nr]->end())); 1254 if (NewBase != DistanceList[Walker->nr]->end()) { 1255 DoubleList[DistanceIterators[Walker->nr]->second->nr]--; // decrease the old entry in the doubles list 1256 DoubleList[NewBase->second->nr]++; // increase the old entry in the doubles list 1257 PermutationMap[Walker->nr] = NewBase->second; 1258 Potential = fabs(ConstrainedPotential(out, PermutationMap, startstep, endstep, constants, IsAngstroem)); 1259 if (Potential > OldPotential) { // undo 1260 DoubleList[NewBase->second->nr]--; 1261 DistanceIterators[Walker->nr] = NewBase; 1262 PermutationMap[Walker->nr] = DistanceIterators[Walker->nr]->second; 1263 DoubleList[DistanceIterators[Walker->nr]->second->nr]++; 1264 } else { 1265 OldPotential = Potential; 1266 *out << Verbose(3) << "Found a new permutation, new potential is " << OldPotential << "." << endl; 1267 } 1268 } 1269 } 1270 for (int i=AtomCount; i--;) // now each single entry in the DoubleList should be <=1 1271 if (DoubleList[i] > 1) { 1272 cerr << "Failed to create an injective PermutationMap!" << endl; 1273 exit(1); 1274 } 1275 *out << Verbose(1) << "done." << endl; 1276 Free((void **)&DoubleList, "molecule::MinimiseConstrainedPotential: *DoubleList"); 1203 1277 // argument minimise the constrained potential in this injective PermutationMap 1204 *out << Verbose(1) << "Argument minimising the PermutationMap ... " << endl;1278 *out << Verbose(1) << "Argument minimising the PermutationMap, at current potential " << OldPotential << " ... " << endl; 1205 1279 do { 1206 PrintPermutationMap(out, PermutationMap, AtomCount);1207 1280 Walker = start; 1208 1281 while (Walker->next != end) { // pick one 1209 1282 Walker = Walker->next; 1283 PrintPermutationMap(out, PermutationMap, AtomCount); 1210 1284 Sprinter = DistanceIterators[Walker->nr]->second; // store initial partner 1211 1285 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 1286 if (DistanceIterators[Walker->nr] == DistanceList[Walker->nr]->end()) // stop, before we run through the list and still on 1287 break; 1288 *out << Verbose(2) << "Current Walker: " << *Walker << " with old/next candidate " << *Sprinter << "/" << *DistanceIterators[Walker->nr]->second << "." << endl; 1289 Runner = start->next; 1290 while(Runner != end) { // find the other one whose toes we might be stepping on (this target should be used by another already) 1291 if (PermutationMap[Runner->nr] == DistanceIterators[Walker->nr]->second) { 1292 *out << Verbose(2) << "Found the corresponding owner " << *Runner << " to " << *DistanceIterators[Walker->nr]->second << "." << endl; 1293 break; 1294 } 1215 1295 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 1296 } 1297 if (Runner != end) { // we found one a tripel 1220 1298 // then look in distance list for Sprinter 1221 DistanceMap::iterator Rider = DistanceList[Walker->nr]->begin();1222 for (; Rider != DistanceList[ Walker->nr]->end(); Rider++)1299 Rider = DistanceList[Runner->nr]->begin(); 1300 for (; Rider != DistanceList[Runner->nr]->end(); Rider++) 1223 1301 if (Rider->second == Sprinter) 1224 1302 break; 1225 if (Rider != DistanceList[Walker->nr]->end()) { // if we have found one 1303 if (Rider != DistanceList[Runner->nr]->end()) { // if we have found one 1304 *out << Verbose(2) << "Current Other: " << *Runner << " with old/next candidate " << *PermutationMap[Runner->nr] << "/" << *Rider->second << "." << endl; 1226 1305 // exchange the second also 1227 PermutationMap[Runner->nr] = Rider->second; 1306 PermutationMap[Walker->nr] = DistanceIterators[Walker->nr]->second; // put next farther distance into PermutationMap 1307 PermutationMap[Runner->nr] = Sprinter; // and hand the old target to its respective owner 1228 1308 // calculate the new potential 1309 PrintPermutationMap(out, PermutationMap, AtomCount); 1310 *out << Verbose(2) << "Checking new potential ..." << endl; 1229 1311 Potential = ConstrainedPotential(out, PermutationMap, startstep, endstep, constants, IsAngstroem); 1230 1312 if (Potential > OldPotential) { // we made everything worse! Undo ... 1313 *out << Verbose(3) << "Nay, made the potential worse: " << Potential << " vs. " << OldPotential << "!" << endl; 1231 1314 // Undo for Walker 1232 1315 DistanceIterators[Walker->nr]--; // take next farther distance target … … 1234 1317 // Undo for Runner (note, we haven't moved the iteration yet, we may use this) 1235 1318 PermutationMap[Runner->nr] = DistanceIterators[Runner->nr]->second; 1319 Potential = OldPotential; 1236 1320 } else { 1237 1321 DistanceIterators[Runner->nr] = Rider; // if successful also move the pointer in the iterator list 1322 *out << Verbose(3) << "Found a better permutation, new potential is " << Potential << " vs." << OldPotential << "." << endl; 1238 1323 OldPotential = Potential; 1239 *out << "Found a better permutation, new potential is " << OldPotential << "." << endl;1240 1324 break; 1241 1325 } 1242 if (Potential > constants[2]) 1326 if (Potential > constants[2]) { 1243 1327 cerr << "ERROR: The two-step permutation procedure did not maintain injectivity!" << endl; 1328 exit(255); 1329 } 1330 *out << endl; 1244 1331 } 1245 1332 } else { 1246 DistanceIterators[Walker->nr]--; // take next farther distance target 1247 PermutationMap[Walker->nr] = DistanceIterators[Walker->nr]->second; 1333 DistanceIterators[Walker->nr]--; // take old distance target 1248 1334 } 1249 1335 } 1250 1336 } while (Walker->next != end); 1251 1337 *out << Verbose(1) << "done." << endl; 1338 1339 1340 /// free memory and return with evaluated potential 1341 for (int i=AtomCount; i--;) 1342 DistanceList[i]->clear(); 1343 Free((void **)&DistanceList, "molecule::MinimiseConstrainedPotential: **DistanceList"); 1344 Free((void **)&DistanceIterators, "molecule::MinimiseConstrainedPotential: *DistanceIterators"); 1345 return ConstrainedPotential(out, PermutationMap, startstep, endstep, constants, IsAngstroem); 1346 }; 1347 1348 /** Evaluates the (distance-related part) of the constrained potential for the constrained forces. 1349 * \param *out output stream for debugging 1350 * \param startstep current MD step giving initial position between which and \a endstep we perform the constrained MD (as further steps are always concatenated) 1351 * \param endstep step giving final position in constrained MD 1352 * \param **PermutationMap mapping between the atom label of the initial and the final configuration 1353 * \param *Force ForceMatrix containing force vectors from the external energy functional minimisation. 1354 * \todo the constant for the constrained potential distance part is hard-coded independently of the hard-coded value in MinimiseConstrainedPotential() 1355 */ 1356 void molecule::EvaluateConstrainedForces(ofstream *out, int startstep, int endstep, atom **PermutationMap, ForceMatrix *Force) 1357 { 1358 double constant = 10.; 1359 atom *Walker = NULL, *Sprinter = NULL; 1360 1252 1361 /// evaluate forces (only the distance to target dependent part) with the final PermutationMap 1253 1362 *out << Verbose(1) << "Calculating forces and adding onto ForceMatrix ... " << endl; … … 1258 1367 // set forces 1259 1368 for (int i=NDIM;i++;) 1260 Force->Matrix[0][Walker->nr][5+i] += 2.*constant s[0]*sqrt(Trajectories[Walker].R.at(startstep).Distance(&Trajectories[Sprinter].R.at(endstep)));1369 Force->Matrix[0][Walker->nr][5+i] += 2.*constant*sqrt(Trajectories[Walker].R.at(startstep).Distance(&Trajectories[Sprinter].R.at(endstep))); 1261 1370 } 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"); 1371 *out << Verbose(1) << "done." << endl; 1372 }; 1373 1374 /** Performs a linear interpolation between two desired atomic configurations with a given number of steps. 1375 * Note, step number is config::MaxOuterStep 1376 * \param *out output stream for debugging 1377 * \param startstep stating initial configuration in molecule::Trajectories 1378 * \param endstep stating final configuration in molecule::Trajectories 1379 * \param &config configuration structure 1380 * \return true - success in writing step files, false - error writing files or only one step in molecule::Trajectories 1381 */ 1382 bool molecule::LinearInterpolationBetweenConfiguration(ofstream *out, int startstep, int endstep, const char *prefix, config &configuration) 1383 { 1384 bool status = true; 1385 int MaxSteps = configuration.MaxOuterStep; 1386 MoleculeListClass *MoleculePerStep = new MoleculeListClass(MaxSteps+1, AtomCount); 1387 // Get the Permutation Map by MinimiseConstrainedPotential 1388 atom **PermutationMap = NULL; 1389 atom *Walker = NULL, *Sprinter = NULL; 1390 MinimiseConstrainedPotential(out, PermutationMap, startstep, endstep, configuration.GetIsAngstroem()); 1391 1392 // check whether we have sufficient space in Trajectories for each atom 1393 Walker = start; 1394 while (Walker->next != end) { 1395 Walker = Walker->next; 1396 if (Trajectories[Walker].R.size() <= (unsigned int)(MaxSteps)) { 1397 //cout << "Increasing size for trajectory array of " << keyword << " to " << (MaxSteps+1) << "." << endl; 1398 Trajectories[Walker].R.resize(MaxSteps+1); 1399 Trajectories[Walker].U.resize(MaxSteps+1); 1400 Trajectories[Walker].F.resize(MaxSteps+1); 1401 } 1402 } 1403 // push endstep to last one 1404 Walker = start; 1405 while (Walker->next != end) { // remove the endstep (is now the very last one) 1406 Walker = Walker->next; 1407 for (int n=NDIM;n--;) { 1408 Trajectories[Walker].R.at(MaxSteps).x[n] = Trajectories[Walker].R.at(endstep).x[n]; 1409 Trajectories[Walker].U.at(MaxSteps).x[n] = Trajectories[Walker].U.at(endstep).x[n]; 1410 Trajectories[Walker].F.at(MaxSteps).x[n] = Trajectories[Walker].F.at(endstep).x[n]; 1411 } 1412 } 1413 endstep = MaxSteps; 1414 1415 // go through all steps and add the molecular configuration to the list and to the Trajectories of \a this molecule 1416 *out << Verbose(1) << "Filling intermediate " << MaxSteps << " steps with MDSteps of " << MDSteps << "." << endl; 1417 for (int step = 0; step <= MaxSteps; step++) { 1418 MoleculePerStep->ListOfMolecules[step] = new molecule(elemente); 1419 Walker = start; 1420 while (Walker->next != end) { 1421 Walker = Walker->next; 1422 // add to molecule list 1423 Sprinter = MoleculePerStep->ListOfMolecules[step]->AddCopyAtom(Walker); 1424 for (int n=NDIM;n--;) { 1425 Sprinter->x.x[n] = Trajectories[Walker].R.at(startstep).x[n] + (Trajectories[PermutationMap[Walker->nr]].R.at(endstep).x[n] - Trajectories[Walker].R.at(startstep).x[n])*((double)step/(double)MaxSteps); 1426 // add to Trajectories 1427 //*out << Verbose(3) << step << ">=" << MDSteps-1 << endl; 1428 //if (step >= MDSteps-1) { 1429 Trajectories[Walker].R.at(step).x[n] = Trajectories[Walker].R.at(startstep).x[n] + (Trajectories[PermutationMap[Walker->nr]].R.at(endstep).x[n] - Trajectories[Walker].R.at(startstep).x[n])*((double)step/(double)MaxSteps); 1430 Trajectories[Walker].U.at(step).x[n] = 0.; 1431 Trajectories[Walker].F.at(step).x[n] = 0.; 1432 //} 1433 } 1434 } 1435 } 1436 MDSteps = MaxSteps+1; // otherwise new Trajectories' points aren't stored on save&exit 1437 1438 // store the list to single step files 1439 int *SortIndex = (int *) Malloc(AtomCount*sizeof(int), "molecule::LinearInterpolationBetweenConfiguration: *SortIndex"); 1440 for (int i=AtomCount; i--; ) 1441 SortIndex[i] = i; 1442 status = MoleculePerStep->OutputConfigForListOfFragments(out, "ConstrainedStep", &configuration, SortIndex, false, false); 1443 1444 // free and return 1268 1445 Free((void **)&PermutationMap, "molecule::MinimiseConstrainedPotential: *PermutationMap"); 1269 return ConstrainedPotential(out, PermutationMap, startstep, endstep, constants, IsAngstroem); 1446 delete(MoleculePerStep); 1447 return status; 1270 1448 }; 1271 1449 … … 1280 1458 * \param DoConstrained whether we perform a constrained (>0, target step in molecule::trajectories) or unconstrained (0) molecular dynamics, \sa molecule::MinimiseConstrainedPotential() 1281 1459 * \return true - file found and parsed, false - file not found or imparsable 1460 * \todo This is not yet checked if it is correctly working with DoConstrained set to true. 1282 1461 */ 1283 1462 bool molecule::VerletForceIntegration(ofstream *out, char *file, double delta_t, bool IsAngstroem, int DoConstrained) … … 1321 1500 if (DoConstrained) { 1322 1501 // calculate forces and potential 1323 ConstrainedPotentialEnergy = MinimiseConstrainedPotential(out, &Force, DoConstrained, 0, IsAngstroem); 1502 atom **PermutationMap = NULL; 1503 ConstrainedPotentialEnergy = MinimiseConstrainedPotential(out, PermutationMap, DoConstrained, 0, IsAngstroem); 1504 EvaluateConstrainedForces(out, DoConstrained, 0, PermutationMap, &Force); 1505 Free((void **)&PermutationMap, "molecule::MinimiseConstrainedPotential: *PermutationMap"); 1324 1506 } 1325 1507 … … 3292 3474 3293 3475 *out << Verbose(1) << "Writing " << BondFragments->NumberOfMolecules << " possible bond fragmentation configs" << endl; 3294 if (BondFragments->OutputConfigForListOfFragments(out, configuration, SortIndex))3476 if (BondFragments->OutputConfigForListOfFragments(out, FRAGMENTPREFIX, configuration, SortIndex, true, true)) 3295 3477 *out << Verbose(1) << "All configs written." << endl; 3296 3478 else -
src/molecules.hpp
ra1fe77 r85bac0 262 262 bool VerletForceIntegration(ofstream *out, char *file, double delta_t, bool IsAngstroem, int DoConstrained); 263 263 double ConstrainedPotential(ofstream *out, atom **permutation, int start, int end, double *constants, bool IsAngstroem); 264 double MinimiseConstrainedPotential(ofstream *out, ForceMatrix *Force, int startstep, int endstep, bool IsAngstroem); 264 double MinimiseConstrainedPotential(ofstream *out, atom **&permutation, int startstep, int endstep, bool IsAngstroem); 265 void EvaluateConstrainedForces(ofstream *out, int startstep, int endstep, atom **PermutationMap, ForceMatrix *Force); 266 bool LinearInterpolationBetweenConfiguration(ofstream *out, int startstep, int endstep, const char *prefix, config &configuration); 265 267 266 268 bool CheckBounds(const Vector *x) const; … … 340 342 bool AddHydrogenCorrection(ofstream *out, char *path); 341 343 bool StoreForcesFile(ofstream *out, char *path, int *SortIndex); 342 bool OutputConfigForListOfFragments(ofstream *out, con fig *configuration, int *SortIndex);344 bool OutputConfigForListOfFragments(ofstream *out, const char *fragmentprefix, config *configuration, int *SortIndex, bool DoPeriodic, bool DoCentering); 343 345 void Output(ofstream *out); 344 346 … … 389 391 double Deltat; 390 392 int DoConstrainedMD; 393 int MaxOuterStep; 391 394 392 395 private: … … 410 413 int Seed; 411 414 412 int MaxOuterStep;413 415 int OutVisStep; 414 416 int OutSrcStep;
Note:
See TracChangeset
for help on using the changeset viewer.