Changeset 6e9353 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:
- a1fe77
- Parents:
- 18913c
- git-author:
- Frederik Heber <heber@…> (09/05/08 08:22:51)
- git-committer:
- Frederik Heber <heber@…> (09/11/08 13:28:25)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/molecules.cpp
r18913c r6e9353 1007 1007 }; 1008 1008 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$ 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 * trajectories i and j) and the third term is a penalty for two atoms trying to each the same target point. 1013 * Note that for the second term we have to solve the following linear system: 1014 * \f$-c_1 \cdot n_1 + c_2 \cdot n_2 + C \cdot n_3 = - p_2 + p_1\f$, where \f$c_1\f$, \f$c_2\f$ and \f$C\f$ are constants, 1015 * offset vector \f$p_1\f$ in direction \f$n_1\f$, offset vector \f$p_2\f$ in direction \f$n_2\f$, 1016 * \f$n_3\f$ is the normal vector to both directions. \f$C\f$ would be the minimum distance between the two lines. 1017 * \sa molecule::MinimiseConstrainedPotential(), molecule::VerletForceIntegration() 1018 * \param *out output stream for debugging 1019 * \param *permutation gives target index for each atom, array of size molecule::AtomCount (this is "x" in \f$V^{con}(x)\f$) 1020 * \param startstep start configuration (MDStep in molecule::trajectories) 1021 * \param endstep end configuration (MDStep in molecule::trajectories) 1022 * \param *constants constant in front of each term 1023 * \param IsAngstroem whether coordinates are in angstroem (true) or bohrradius (false) 1024 * \return potential energy 1025 * \note This routine is scaling quadratically which is not optimal. 1026 */ 1027 double molecule::ConstrainedPotential(ofstream *out, int *permutation, int startstep, int endstep, double *constants, bool IsAngstroem) 1028 { 1029 double result = 0., tmp; 1030 atom *Walker = NULL, *Runner = NULL, *Sprinter = NULL; 1031 Vector trajectory1, trajectory2, normal, TestVector; 1032 gsl_matrix *A = gsl_matrix_alloc(NDIM,NDIM); 1033 gsl_vector *x = gsl_vector_alloc(NDIM); 1034 1035 // go through every atom 1036 Walker = start; 1037 while (Walker->next != end) { 1038 Walker = Walker->next; 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))); 1042 1043 // second term: sum of distances to other trajectories 1044 Runner = start; 1045 while (Runner->next != end) { 1046 Runner = Runner->next; 1047 // determine normalized trajectories direction vector (n1, n2) 1048 Sprinter = FindAtom(permutation[Walker->nr]); // find target point 1049 trajectory1.CopyVector(&Trajectories[Sprinter].R.at(endstep)); 1050 trajectory1.SubtractVector(&Trajectories[Walker].R.at(startstep)); 1051 trajectory1.Normalize(); 1052 Sprinter = FindAtom(permutation[Runner->nr]); // find target point 1053 trajectory2.CopyVector(&Trajectories[Sprinter].R.at(endstep)); 1054 trajectory2.SubtractVector(&Trajectories[Runner].R.at(startstep)); 1055 trajectory2.Normalize(); 1056 // check whether they're linear dependent 1057 if (fabs(trajectory1.ScalarProduct(&trajectory2)/trajectory1.Norm()/trajectory2.Norm() - 1.) < MYEPSILON) { 1058 *out << "Both trajectories of " << *Walker << " and " << *Runner << " are linear dependent: "; 1059 *out << trajectory1; 1060 *out << " and "; 1061 *out << trajectory2 << endl; 1062 tmp = Trajectories[Walker].R.at(startstep).Distance(&Trajectories[Runner].R.at(startstep)); 1063 } else { // determine distance by finding minimum distance 1064 *out << "Both trajectories of " << *Walker << " and " << *Runner << " are linear independent." << endl; 1065 // determine normal vector for both 1066 normal.MakeNormalVector(&trajectory1, &trajectory2); 1067 // setup matrix 1068 for (int i=NDIM;i--;) { 1069 gsl_matrix_set(A, 0, i, trajectory1.x[i]); 1070 gsl_matrix_set(A, 1, i, trajectory2.x[i]); 1071 gsl_matrix_set(A, 2, i, normal.x[i]); 1072 gsl_vector_set(x,i, (Trajectories[Walker].R.at(startstep).x[i] - Trajectories[Runner].R.at(startstep).x[i])); 1073 } 1074 // solve the linear system by Householder transformations 1075 gsl_linalg_HH_svx(A, x); 1076 // distance from last component 1077 tmp = gsl_vector_get(x,2); 1078 // test whether we really have the intersection (by checking on c_1 and c_2) 1079 TestVector.CopyVector(&Trajectories[Runner].R.at(startstep)); 1080 trajectory2.Scale(gsl_vector_get(x,1)); 1081 TestVector.AddVector(&trajectory2); 1082 normal.Scale(gsl_vector_get(x,2)); 1083 TestVector.AddVector(&normal); 1084 TestVector.SubtractVector(&Trajectories[Walker].R.at(startstep)); 1085 trajectory1.Scale(gsl_vector_get(x,0)); 1086 TestVector.SubtractVector(&trajectory1); 1087 if (TestVector.Norm() < MYEPSILON) { 1088 *out << "Test: ok.\tDistance of " << tmp << " is correct." << endl; 1089 } else { 1090 *out << "Test: failed.\tDifference in intersection is "; 1091 *out << TestVector; 1092 *out << "." << endl; 1093 } 1094 } 1095 // add up 1096 result += constants[1] * 1./tmp; 1097 } 1098 1099 // third term: penalty for equal targets 1100 Runner = start; 1101 while (Runner->next != end) { 1102 Runner = Runner->next; 1103 if ((permutation[Walker->nr] == permutation[Runner->nr]) && (Walker->nr < Runner->nr)) { 1104 Sprinter = FindAtom(permutation[Walker->nr]); 1105 *out << *Walker << " and " << *Runner << " are heading to the same target at "; 1106 *out << Trajectories[Sprinter].R.at(endstep); 1107 *out << ", penalting." << endl; 1108 result += constants[2]; 1109 } 1110 } 1111 } 1112 1113 return result; 1114 }; 1115 1116 /** Minimises the extra potential for constrained molecular dynamics and gives forces and the constrained potential energy. 1117 * We do the following: 1118 * -# First, we minimise the potential, see molecule::ConstrainedPotential() 1119 * -# Then, we calculate the forces by taking the spatial derivative, where we scale the potential to such a degree, 1120 * that the total force is always pointing in direction of the constraint force (ensuring that we move in the 1121 * right direction). 1122 * -# Finally, we calculate the potential energy and return. 1123 * \param *out output stream for debugging 1124 * \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 1126 * \sa molecule::VerletForceIntegration() 1127 * \return potential energy 1128 */ 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; 1138 }; 1139 1009 1140 /** Parses nuclear forces from file and performs Verlet integration. 1010 1141 * Note that we assume the parsed forces to be in atomic units (hence, if coordinates are in angstroem, we 1011 1142 * have to transform them). 1012 1143 * This adds a new MD step to the config file. 1144 * \param *out output stream for debugging 1013 1145 * \param *file filename 1014 1146 * \param delta_t time step width in atomic units 1015 1147 * \param IsAngstroem whether coordinates are in angstroem (true) or bohrradius (false) 1148 * \param DoConstrained whether we perform a constrained (>0, target step in molecule::trajectories) or unconstrained (0) molecular dynamics, \sa molecule::MinimiseConstrainedPotential() 1016 1149 * \return true - file found and parsed, false - file not found or imparsable 1017 1150 */ 1018 bool molecule::VerletForceIntegration( char *file, double delta_t, bool IsAngstroem)1151 bool molecule::VerletForceIntegration(ofstream *out, char *file, double delta_t, bool IsAngstroem, int DoConstrained) 1019 1152 { 1020 1153 element *runner = elemente->start; … … 1024 1157 string token; 1025 1158 stringstream item; 1026 double a, IonMass, Vector[NDIM] ;1159 double a, IonMass, Vector[NDIM], ConstrainedPotentialEnergy; 1027 1160 ForceMatrix Force; 1028 1161 … … 1053 1186 Force.Matrix[0][i][d+5] -= Vector[d]/(double)AtomCount; 1054 1187 } 1188 // solve a constrained potential if we are meant to 1189 if (DoConstrained) { 1190 ConstrainedPotentialEnergy = MinimiseConstrainedPotential(out, &Force, DoConstrained); 1191 } 1192 1055 1193 // and perform Verlet integration for each atom with position, velocity and force vector 1056 1194 runner = elemente->start; … … 1067 1205 // check size of vectors 1068 1206 if (Trajectories[walker].R.size() <= (unsigned int)(MDSteps)) { 1069 // cout << "Increasing size for trajectory array of " << *walker << " to " << (size+10) << "." << endl;1207 //out << "Increasing size for trajectory array of " << *walker << " to " << (size+10) << "." << endl; 1070 1208 Trajectories[walker].R.resize(MDSteps+10); 1071 1209 Trajectories[walker].U.resize(MDSteps+10); … … 1085 1223 Trajectories[walker].U.at(MDSteps).x[d] += a * (Trajectories[walker].F.at(MDSteps).x[d]+Trajectories[walker].F.at(MDSteps-1).x[d]); 1086 1224 } 1087 // cout << "Integrated position&velocity of step " << (MDSteps) << ": (";1225 // out << "Integrated position&velocity of step " << (MDSteps) << ": ("; 1088 1226 // for (int d=0;d<NDIM;d++) 1089 // cout << Trajectories[walker].R.at(MDSteps).x[d] << " "; // next step1090 // cout << ")\t(";1227 // out << Trajectories[walker].R.at(MDSteps).x[d] << " "; // next step 1228 // out << ")\t("; 1091 1229 // for (int d=0;d<NDIM;d++) 1092 1230 // cout << Trajectories[walker].U.at(MDSteps).x[d] << " "; // next step 1093 // cout << ")" << endl;1231 // out << ")" << endl; 1094 1232 // next atom 1095 1233 AtomNo++;
Note:
See TracChangeset
for help on using the changeset viewer.