Changeset 36ec71
- Timestamp:
- Jul 24, 2009, 10:38:32 AM (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:
- d30402
- Parents:
- 042f82 (diff), 51c910 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - git-author:
- Frederik Heber <heber@…> (07/23/09 14:23:32)
- git-committer:
- Frederik Heber <heber@…> (07/24/09 10:38:32)
- Location:
- src
- Files:
-
- 1 added
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Makefile.am
r042f82 r36ec71 10 10 11 11 12 #EXTRA_DIST = ${molecuilder_DATA}12 EXTRA_DIST = ${molecuilder_DATA} -
src/analyzer.cpp
r042f82 r36ec71 25 25 periodentafel *periode = NULL; // and a period table of all elements 26 26 EnergyMatrix Energy; 27 EnergyMatrix EnergyFragments; 28 ForceMatrix Force; 29 ForceMatrix ForceFragments; 30 HessianMatrix Hessian; 31 HessianMatrix HessianFragments; 27 32 EnergyMatrix Hcorrection; 28 ForceMatrix Force;33 EnergyMatrix HcorrectionFragments; 29 34 ForceMatrix Shielding; 30 35 ForceMatrix ShieldingPAS; 36 ForceMatrix Chi; 37 ForceMatrix ChiPAS; 31 38 EnergyMatrix Time; 32 EnergyMatrix EnergyFragments;33 EnergyMatrix HcorrectionFragments;34 ForceMatrix ForceFragments;35 39 ForceMatrix ShieldingFragments; 36 40 ForceMatrix ShieldingPASFragments; 41 ForceMatrix ChiFragments; 42 ForceMatrix ChiPASFragments; 37 43 KeySetsContainer KeySet; 38 44 ofstream output; … … 49 55 stringstream yrange; 50 56 char *dir = NULL; 51 bool Hcorrected = true; 57 bool NoHessian = false; 58 bool NoTime = false; 59 bool NoHCorrection = true; 52 60 int counter; 53 61 … … 83 91 // ------------- Parse through all Fragment subdirs -------- 84 92 if (!Energy.ParseFragmentMatrix(argv[1], dir, EnergySuffix,0,0)) return 1; 85 Hcorrected = Hcorrection.ParseFragmentMatrix(argv[1], "", HCORRECTIONSUFFIX,0,0); 93 if (!Hcorrection.ParseFragmentMatrix(argv[1], "", HCORRECTIONSUFFIX,0,0)) { 94 NoHCorrection = true; 95 cout << "No HCorrection file found, skipping these." << endl; 96 } 97 86 98 if (!Force.ParseFragmentMatrix(argv[1], dir, ForcesSuffix,0,0)) return 1; 87 if (!Time.ParseFragmentMatrix(argv[1], dir, TimeSuffix, 10,1)) return 1; 99 if (!Hessian.ParseFragmentMatrix(argv[1], dir, HessianSuffix,0,0)) { 100 NoHessian = true; 101 cout << "No Hessian file found, skipping these." << endl; 102 } 103 if (!Time.ParseFragmentMatrix(argv[1], dir, TimeSuffix, 10,1)) { 104 NoTime = true; 105 cout << "No speed file found, skipping these." << endl; 106 } 88 107 if (periode != NULL) { // also look for PAS values 89 108 if (!Shielding.ParseFragmentMatrix(argv[1], dir, ShieldingSuffix, 1, 0)) return 1; 90 109 if (!ShieldingPAS.ParseFragmentMatrix(argv[1], dir, ShieldingPASSuffix, 1, 0)) return 1; 110 if (!Chi.ParseFragmentMatrix(argv[1], dir, ChiSuffix, 1, 0)) return 1; 111 if (!ChiPAS.ParseFragmentMatrix(argv[1], dir, ChiPASSuffix, 1, 0)) return 1; 91 112 } 92 113 93 114 // ---------- Parse the TE Factors into an array ----------------- 94 115 if (!Energy.ParseIndices()) return 1; 95 if ( Hcorrected) Hcorrection.ParseIndices();116 if (!NoHCorrection) Hcorrection.ParseIndices(); 96 117 97 118 // ---------- Parse the Force indices into an array --------------- 98 119 if (!Force.ParseIndices(argv[1])) return 1; 99 120 if (!ForceFragments.AllocateMatrix(Force.Header, Force.MatrixCounter, Force.RowCounter, Force.ColumnCounter)) return 1; 100 if (!ForceFragments.ParseIndices(argv[1])) return 1; 121 if (!ForceFragments.InitialiseIndices((class MatrixContainer *)&Force)) return 1; 122 123 // ---------- Parse hessian indices into an array ----------------- 124 if (!NoHessian) { 125 if (!Hessian.InitialiseIndices((class MatrixContainer *)&Force)) return 1; 126 if (!HessianFragments.AllocateMatrix(Hessian.Header, Hessian.MatrixCounter, Hessian.RowCounter, Hessian.ColumnCounter)) return 1; 127 if (!HessianFragments.InitialiseIndices((class MatrixContainer *)&Force)) return 1; 128 } 101 129 102 130 // ---------- Parse the shielding indices into an array --------------- … … 108 136 if(!ShieldingFragments.ParseIndices(argv[1])) return 1; 109 137 if(!ShieldingPASFragments.ParseIndices(argv[1])) return 1; 138 if(!Chi.ParseIndices(argv[1])) return 1; 139 if(!ChiPAS.ParseIndices(argv[1])) return 1; 140 if (!ChiFragments.AllocateMatrix(Chi.Header, Chi.MatrixCounter, Chi.RowCounter, Chi.ColumnCounter)) return 1; 141 if (!ChiPASFragments.AllocateMatrix(ChiPAS.Header, ChiPAS.MatrixCounter, ChiPAS.RowCounter, ChiPAS.ColumnCounter)) return 1; 142 if(!ChiFragments.ParseIndices(argv[1])) return 1; 143 if(!ChiPASFragments.ParseIndices(argv[1])) return 1; 110 144 } 111 145 … … 116 150 // ---------- Parse fragment files created by 'joiner' into an array ------------- 117 151 if (!EnergyFragments.ParseFragmentMatrix(argv[1], dir, EnergyFragmentSuffix,0,0)) return 1; 118 if (Hcorrected) HcorrectionFragments.ParseFragmentMatrix(argv[1], dir, HcorrectionFragmentSuffix,0,0); 152 if (!NoHCorrection) 153 HcorrectionFragments.ParseFragmentMatrix(argv[1], dir, HcorrectionFragmentSuffix,0,0); 119 154 if (!ForceFragments.ParseFragmentMatrix(argv[1], dir, ForceFragmentSuffix,0,0)) return 1; 155 if (!NoHessian) 156 if (!HessianFragments.ParseFragmentMatrix(argv[1], dir, HessianFragmentSuffix,0,0)) return 1; 120 157 if (periode != NULL) { // also look for PAS values 121 158 if (!ShieldingFragments.ParseFragmentMatrix(argv[1], dir, ShieldingFragmentSuffix, 1, 0)) return 1; 122 159 if (!ShieldingPASFragments.ParseFragmentMatrix(argv[1], dir, ShieldingPASFragmentSuffix, 1, 0)) return 1; 160 if (!ChiFragments.ParseFragmentMatrix(argv[1], dir, ChiFragmentSuffix, 1, 0)) return 1; 161 if (!ChiPASFragments.ParseFragmentMatrix(argv[1], dir, ChiPASFragmentSuffix, 1, 0)) return 1; 123 162 } 124 163 … … 129 168 filename << argv[3] << "/" << "energy-forces.all"; 130 169 output.open(filename.str().c_str(), ios::out); 131 output << endl << "Total Energy" << endl << "==============" << endl << Energy.Header << endl;170 output << endl << "Total Energy" << endl << "==============" << endl << Energy.Header[Energy.MatrixCounter] << endl; 132 171 for(int j=0;j<Energy.RowCounter[Energy.MatrixCounter];j++) { 133 for(int k=0;k<Energy.ColumnCounter ;k++)172 for(int k=0;k<Energy.ColumnCounter[Energy.MatrixCounter];k++) 134 173 output << scientific << Energy.Matrix[ Energy.MatrixCounter ][j][k] << "\t"; 135 174 output << endl; 136 175 } 137 176 output << endl; 138 139 output << endl << "Total Forces" << endl << "===============" << endl << Force.Header << endl;177 178 output << endl << "Total Forces" << endl << "===============" << endl << Force.Header[Force.MatrixCounter] << endl; 140 179 for(int j=0;j<Force.RowCounter[Force.MatrixCounter];j++) { 141 for(int k=0;k<Force.ColumnCounter ;k++)180 for(int k=0;k<Force.ColumnCounter[Force.MatrixCounter];k++) 142 181 output << scientific << Force.Matrix[ Force.MatrixCounter ][j][k] << "\t"; 143 182 output << endl; … … 145 184 output << endl; 146 185 186 if (!NoHessian) { 187 output << endl << "Total Hessian" << endl << "===============" << endl << Hessian.Header[Hessian.MatrixCounter] << endl; 188 for(int j=0;j<Hessian.RowCounter[Hessian.MatrixCounter];j++) { 189 for(int k=0;k<Hessian.ColumnCounter[Hessian.MatrixCounter];k++) 190 output << scientific << Hessian.Matrix[ Hessian.MatrixCounter ][j][k] << "\t"; 191 output << endl; 192 } 193 output << endl; 194 } 195 147 196 if (periode != NULL) { // also look for PAS values 148 output << endl << "Total Shieldings" << endl << "===============" << endl << Shielding.Header << endl;197 output << endl << "Total Shieldings" << endl << "===============" << endl << Shielding.Header[Hessian.MatrixCounter] << endl; 149 198 for(int j=0;j<Shielding.RowCounter[Shielding.MatrixCounter];j++) { 150 for(int k=0;k<Shielding.ColumnCounter ;k++)199 for(int k=0;k<Shielding.ColumnCounter[Shielding.MatrixCounter];k++) 151 200 output << scientific << Shielding.Matrix[ Shielding.MatrixCounter ][j][k] << "\t"; 152 201 output << endl; 153 202 } 154 203 output << endl; 155 156 output << endl << "Total Shieldings PAS" << endl << "===============" << endl << ShieldingPAS.Header << endl;204 205 output << endl << "Total Shieldings PAS" << endl << "===============" << endl << ShieldingPAS.Header[ShieldingPAS.MatrixCounter] << endl; 157 206 for(int j=0;j<ShieldingPAS.RowCounter[ShieldingPAS.MatrixCounter];j++) { 158 for(int k=0;k<ShieldingPAS.ColumnCounter ;k++)207 for(int k=0;k<ShieldingPAS.ColumnCounter[ShieldingPAS.MatrixCounter];k++) 159 208 output << scientific << ShieldingPAS.Matrix[ ShieldingPAS.MatrixCounter ][j][k] << "\t"; 160 209 output << endl; 161 210 } 162 211 output << endl; 163 } 164 165 output << endl << "Total Times" << endl << "===============" << endl << Time.Header << endl; 166 for(int j=0;j<Time.RowCounter[Time.MatrixCounter];j++) { 167 for(int k=0;k<Time.ColumnCounter;k++) { 168 output << scientific << Time.Matrix[ Time.MatrixCounter ][j][k] << "\t"; 169 } 170 output << endl; 171 } 172 output << endl; 212 213 output << endl << "Total Chis" << endl << "===============" << endl << Chi.Header[Chi.MatrixCounter] << endl; 214 for(int j=0;j<Chi.RowCounter[Chi.MatrixCounter];j++) { 215 for(int k=0;k<Chi.ColumnCounter[Chi.MatrixCounter];k++) 216 output << scientific << Chi.Matrix[ Chi.MatrixCounter ][j][k] << "\t"; 217 output << endl; 218 } 219 output << endl; 220 221 output << endl << "Total Chis PAS" << endl << "===============" << endl << ChiPAS.Header[ChiPAS.MatrixCounter] << endl; 222 for(int j=0;j<ChiPAS.RowCounter[ChiPAS.MatrixCounter];j++) { 223 for(int k=0;k<ChiPAS.ColumnCounter[ChiPAS.MatrixCounter];k++) 224 output << scientific << ChiPAS.Matrix[ ChiPAS.MatrixCounter ][j][k] << "\t"; 225 output << endl; 226 } 227 output << endl; 228 } 229 230 if (!NoTime) { 231 output << endl << "Total Times" << endl << "===============" << endl << Time.Header[Time.MatrixCounter] << endl; 232 for(int j=0;j<Time.RowCounter[Time.MatrixCounter];j++) { 233 for(int k=0;k<Time.ColumnCounter[Time.MatrixCounter];k++) { 234 output << scientific << Time.Matrix[ Time.MatrixCounter ][j][k] << "\t"; 235 } 236 output << endl; 237 } 238 output << endl; 239 } 173 240 output.close(); 174 for(int k=0;k<Time.ColumnCounter;k++) 175 Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter] ][k] = Time.Matrix[ Time.MatrixCounter ][Time.RowCounter[Time.MatrixCounter]-1][k]; 241 if (!NoTime) 242 for(int k=0;k<Time.ColumnCounter[Time.MatrixCounter];k++) 243 Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter] ][k] = Time.Matrix[ Time.MatrixCounter ][Time.RowCounter[Time.MatrixCounter]-1][k]; 176 244 177 245 // +++++++++++++++ ANALYZING ++++++++++++++++++++++++++++++ … … 183 251 // +++++++++++++++++++++++++++++++++++++++ Plotting Simtime vs Bond Order 184 252 // +++++++++++++++++++++++++++++++++++++++ Plotting Delta Simtime vs Bond Order 185 if (!OpenOutputFile(output, argv[3], "SimTime-Order.dat" )) return false; 186 if (!OpenOutputFile(output2, argv[3], "DeltaSimTime-Order.dat" )) return false; 187 for(int j=Time.RowCounter[Time.MatrixCounter];j--;) 188 for(int k=Time.ColumnCounter;k--;) { 189 Time.Matrix[ Time.MatrixCounter ][j][k] = 0.; 190 } 191 counter = 0; 192 output << "#Order\tFrag.No.\t" << Time.Header << endl; 193 output2 << "#Order\tFrag.No.\t" << Time.Header << endl; 194 for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) { 195 for(int i=KeySet.FragmentsPerOrder[BondOrder];i--;) 196 for(int j=Time.RowCounter[Time.MatrixCounter];j--;) 197 for(int k=Time.ColumnCounter;k--;) { 198 Time.Matrix[ Time.MatrixCounter ][j][k] += Time.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k]; 199 } 200 counter += KeySet.FragmentsPerOrder[BondOrder]; 201 output << BondOrder+1 << "\t" << counter; 202 output2 << BondOrder+1 << "\t" << counter; 203 for(int k=0;k<Time.ColumnCounter;k++) { 204 output << "\t" << scientific << Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter]-1 ][k]; 205 if (fabs(Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter] ][k]) > MYEPSILON) 206 output2 << "\t" << scientific << Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter]-1 ][k] / Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter] ][k]; 207 else 208 output2 << "\t" << scientific << Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter]-1 ][k]; 209 } 210 output << endl; 211 output2 << endl; 212 } 213 output.close(); 214 output2.close(); 253 if (!NoTime) { 254 if (!OpenOutputFile(output, argv[3], "SimTime-Order.dat" )) return false; 255 if (!OpenOutputFile(output2, argv[3], "DeltaSimTime-Order.dat" )) return false; 256 for(int j=Time.RowCounter[Time.MatrixCounter];j--;) 257 for(int k=Time.ColumnCounter[Time.MatrixCounter];k--;) { 258 Time.Matrix[ Time.MatrixCounter ][j][k] = 0.; 259 } 260 counter = 0; 261 output << "#Order\tFrag.No.\t" << Time.Header[Time.MatrixCounter] << endl; 262 output2 << "#Order\tFrag.No.\t" << Time.Header[Time.MatrixCounter] << endl; 263 for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) { 264 for(int i=KeySet.FragmentsPerOrder[BondOrder];i--;) 265 for(int j=Time.RowCounter[Time.MatrixCounter];j--;) 266 for(int k=Time.ColumnCounter[Time.MatrixCounter];k--;) { 267 Time.Matrix[ Time.MatrixCounter ][j][k] += Time.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k]; 268 } 269 counter += KeySet.FragmentsPerOrder[BondOrder]; 270 output << BondOrder+1 << "\t" << counter; 271 output2 << BondOrder+1 << "\t" << counter; 272 for(int k=0;k<Time.ColumnCounter[Time.MatrixCounter];k++) { 273 output << "\t" << scientific << Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter]-1 ][k]; 274 if (fabs(Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter] ][k]) > MYEPSILON) 275 output2 << "\t" << scientific << Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter]-1 ][k] / Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter] ][k]; 276 else 277 output2 << "\t" << scientific << Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter]-1 ][k]; 278 } 279 output << endl; 280 output2 << endl; 281 } 282 output.close(); 283 output2.close(); 284 } 285 286 if (!NoHessian) { 287 // +++++++++++++++++++++++++++++++++++++++ Plotting deviation in hessian to full QM 288 if (!CreateDataDeltaHessianOrderPerAtom(Hessian, HessianFragments, KeySet, argv[3], "DeltaHessian_xx-Order", "Plot of error between approximated hessian and full hessian versus the Bond Order", datum)) return 1; 289 290 if (!CreateDataDeltaFrobeniusOrderPerAtom(Hessian, HessianFragments, KeySet, argv[3], "DeltaFrobeniusHessian_xx-Order", "Plot of error between approximated hessian and full hessian in the frobenius norm versus the Bond Order", datum)) return 1; 291 292 // ++++++++++++++++++++++++++++++++++++++Plotting Hessian vs. Order 293 if (!CreateDataHessianOrderPerAtom(HessianFragments, KeySet, argv[3], "Hessian_xx-Order", "Plot of approximated hessian versus the Bond Order", datum)) return 1; 294 if (!AppendOutputFile(output, argv[3], "Hessian_xx-Order.dat" )) return false; 295 output << endl << "# Full" << endl; 296 for(int j=0;j<Hessian.RowCounter[Hessian.MatrixCounter];j++) { 297 output << j << "\t"; 298 for(int k=0;k<Hessian.ColumnCounter[Force.MatrixCounter];k++) 299 output << scientific << Hessian.Matrix[ Hessian.MatrixCounter ][j][k] << "\t"; 300 output << endl; 301 } 302 output.close(); 303 } 215 304 216 305 // +++++++++++++++++++++++++++++++++++++++ Plotting shieldings 217 218 306 if (periode != NULL) { // also look for PAS values 219 307 if (!CreateDataDeltaForcesOrderPerAtom(ShieldingPAS, ShieldingPASFragments, KeySet, argv[3], "DeltaShieldingsPAS-Order", "Plot of error between approximated shieldings and full shieldings versus the Bond Order", datum)) return 1; … … 223 311 for(int j=0;j<ShieldingPAS.RowCounter[ShieldingPAS.MatrixCounter];j++) { 224 312 output << j << "\t"; 225 for(int k=0;k<ShieldingPAS.ColumnCounter ;k++)313 for(int k=0;k<ShieldingPAS.ColumnCounter[ShieldingPAS.MatrixCounter];k++) 226 314 output << scientific << ShieldingPAS.Matrix[ ShieldingPAS.MatrixCounter ][j][k] << "\t"; //*(((k>1) && (k<6))? 1.e6 : 1.) << "\t"; 227 315 output << endl; 228 316 } 229 } 230 output.close(); 317 output.close(); 318 if (!CreateDataDeltaForcesOrderPerAtom(ChiPAS, ChiPASFragments, KeySet, argv[3], "DeltaChisPAS-Order", "Plot of error between approximated Chis and full Chis versus the Bond Order", datum)) return 1; 319 if (!CreateDataForcesOrderPerAtom(ChiPASFragments, KeySet, argv[3], "ChisPAS-Order", "Plot of approximated Chis versus the Bond Order", datum)) return 1; 320 if (!AppendOutputFile(output, argv[3], "ChisPAS-Order.dat" )) return false; 321 output << endl << "# Full" << endl; 322 for(int j=0;j<ChiPAS.RowCounter[ChiPAS.MatrixCounter];j++) { 323 output << j << "\t"; 324 for(int k=0;k<ChiPAS.ColumnCounter[ChiPAS.MatrixCounter];k++) 325 output << scientific << ChiPAS.Matrix[ ChiPAS.MatrixCounter ][j][k] << "\t"; //*(((k>1) && (k<6))? 1.e6 : 1.) << "\t"; 326 output << endl; 327 } 328 output.close(); 329 } 231 330 232 331 … … 255 354 for(int j=0;j<Force.RowCounter[Force.MatrixCounter];j++) { 256 355 output << j << "\t"; 257 for(int k=0;k<Force.ColumnCounter ;k++)356 for(int k=0;k<Force.ColumnCounter[Force.MatrixCounter];k++) 258 357 output << scientific << Force.Matrix[ Force.MatrixCounter ][j][k] << "\t"; 259 358 output << endl; … … 303 402 Fragmentxrange << "[0:" << KeySet.FragmentCounter+1 << "]"; 304 403 yrange.str("[1e-8:1e+1]"); 305 306 // +++++++++++++++++++++++++++++++++++++++ Plotting Simtime vs Bond Order 307 if (!CreatePlotOrder(Time, KeySet, argv[3], "SimTime-Order", 1, "below", "y", "", 1, 1, "bond order k", "Evaluation time [s]", Orderxrange.str().c_str(), "", "1" , "with linespoints", EnergyPlotLine)) return 1; 308 404 405 if (!NoTime) { 406 // +++++++++++++++++++++++++++++++++++++++ Plotting Simtime vs Bond Order 407 if (!CreatePlotOrder(Time, KeySet, argv[3], "SimTime-Order", 1, "below", "y", "", 1, 1, "bond order k", "Evaluation time [s]", Orderxrange.str().c_str(), "", "1" , "with linespoints", EnergyPlotLine)) return 1; 408 } 409 309 410 // +++++++++++++++++++++++++++++++++++++++ Plotting deviation in energy to full QM 310 411 if (!CreatePlotOrder(Energy, KeySet, argv[3], "DeltaEnergies-Order", 1, "outside", "y", "", 1, 1, "bond order k", "absolute error in energy [Ht]", Orderxrange.str().c_str(), yrange.str().c_str(), "1" , "with linespoints", AbsEnergyPlotLine)) return 1; … … 403 504 } 404 505 output << "'ShieldingsPAS-Order.dat' index " << KeySet.Order << " title 'Full' using ($1+" << step*(double)KeySet.Order << "):7 with boxes" << endl; 405 output.close(); 406 output2.close(); 506 output2.close(); 507 508 if(!OpenOutputFile(output, argv[3], "ChisPAS-Order.pyx")) return 1; 509 if(!OpenOutputFile(output2, argv[3], "DeltaChisPAS-Order.pyx")) return 1; 510 CreatePlotHeader(output, "ChisPAS-Order", 1, "top right", NULL, NULL, 1, 5, "nuclei index", "iso chemical Chi value [ppm]"); 511 CreatePlotHeader(output2, "DeltaChisPAS-Order", 1, "top right", NULL, NULL, 1, 5, "nuclei index", "iso chemical Chi value [ppm]"); 512 output << "set boxwidth " << step << endl; 513 output << "plot [0:" << ChiPAS.RowCounter[ChiPAS.MatrixCounter]+10 << "]\\" << endl; 514 output2 << "plot [0:" << ChiPAS.RowCounter[ChiPAS.MatrixCounter]+10 << "]\\" << endl; 515 for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) { 516 output << "'ChisPAS-Order.dat' index " << BondOrder << " title 'Order " << BondOrder+1 << "' using ($1+" << step*(double)BondOrder << "):7 with boxes, \\" << endl; 517 output2 << "'DeltaChisPAS-Order.dat' index " << BondOrder << " title 'Order " << BondOrder+1 << "' using ($1):7 with linespoints"; 518 if (BondOrder-1 != KeySet.Order) 519 output2 << ", \\" << endl; 520 } 521 output << "'ChisPAS-Order.dat' index " << KeySet.Order << " title 'Full' using ($1+" << step*(double)KeySet.Order << "):7 with boxes" << endl; 522 output.close(); 523 output2.close(); 524 525 if(!OpenOutputFile(output, argv[3], "ChisPAS-Order.pyx")) return 1; 526 if(!OpenOutputFile(output2, argv[3], "DeltaChisPAS-Order.pyx")) return 1; 527 CreatePlotHeader(output, "ChisPAS-Order", 1, "top right", NULL, NULL, 1, 5, "nuclei index", "iso chemical Chi value [ppm]"); 528 CreatePlotHeader(output2, "DeltaChisPAS-Order", 1, "top right", NULL, NULL, 1, 5, "nuclei index", "iso chemical Chi value [ppm]"); 529 output << "set boxwidth " << step << endl; 530 output << "plot [0:" << ChiPAS.RowCounter[ChiPAS.MatrixCounter]+10 << "]\\" << endl; 531 output2 << "plot [0:" << ChiPAS.RowCounter[ChiPAS.MatrixCounter]+10 << "]\\" << endl; 532 for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) { 533 output << "'ChisPAS-Order.dat' index " << BondOrder << " title 'Order " << BondOrder+1 << "' using ($1+" << step*(double)BondOrder << "):7 with boxes, \\" << endl; 534 output2 << "'DeltaChisPAS-Order.dat' index " << BondOrder << " title 'Order " << BondOrder+1 << "' using ($1):7 with linespoints"; 535 if (BondOrder-1 != KeySet.Order) 536 output2 << ", \\" << endl; 537 } 538 output << "'ChisPAS-Order.dat' index " << KeySet.Order << " title 'Full' using ($1+" << step*(double)KeySet.Order << "):7 with boxes" << endl; 539 output.close(); 540 output2.close(); 407 541 } 408 542 -
src/atom.cpp
r042f82 r36ec71 89 89 }; 90 90 91 ostream & operator << (ostream &ost, atom &a)91 ostream & operator << (ostream &ost, const atom &a) 92 92 { 93 93 ost << "[" << a.Name << "|" << &a << "]"; -
src/bond.cpp
r042f82 r36ec71 82 82 }; 83 83 84 ostream & operator << (ostream &ost, bond &b)84 ostream & operator << (ostream &ost, const bond &b) 85 85 { 86 86 ost << "[" << b.leftatom->Name << " <" << b.BondDegree << "(H" << b.HydrogenBond << ")>" << b.rightatom->Name << "]"; … … 98 98 if(rightatom == Atom) 99 99 return leftatom; 100 cerr << "Bond " << *this << " does not contain atom " << *Atom << "!" << endl; 100 101 return NULL; 101 102 }; -
src/boundary.cpp
r042f82 r36ec71 10 10 #define DoSingleStepOutput 0 11 11 #define DoTecplotOutput 1 12 #define DoRaster3DOutput 012 #define DoRaster3DOutput 1 13 13 #define DoVRMLOutput 1 14 14 #define TecplotSuffix ".dat" … … 45 45 void BoundaryPointSet::AddLine(class BoundaryLineSet *line) 46 46 { 47 cout << Verbose(6) << "Adding line " << *line << " to " << *this << "." << endl; 47 cout << Verbose(6) << "Adding " << *this << " to line " << *line << "." 48 << endl; 48 49 if (line->endpoints[0] == this) 49 50 { -
src/builder.cpp
r042f82 r36ec71 282 282 case 'a': 283 283 cout << Verbose(0) << "Centering atoms in config file on origin." << endl; 284 mol->CenterOrigin((ofstream *)&cout , &x);284 mol->CenterOrigin((ofstream *)&cout); 285 285 break; 286 286 case 'b': 287 287 cout << Verbose(0) << "Centering atoms in config file on center of gravity." << endl; 288 mol->Center Gravity((ofstream *)&cout, &x);288 mol->CenterPeriodic((ofstream *)&cout); 289 289 break; 290 290 case 'c': … … 295 295 } 296 296 mol->CenterEdge((ofstream *)&cout, &x); // make every coordinate positive 297 mol-> Translate(&y); // translate by boundary297 mol->Center.AddVector(&y); // translate by boundary 298 298 helper.CopyVector(&y); 299 299 helper.Scale(2.); … … 307 307 cin >> x.x[i]; 308 308 } 309 // update Box of atoms by boundary 310 mol->SetBoxDimension(&x); 309 311 // center 310 312 mol->CenterInBox((ofstream *)&cout); 311 // update Box of atoms by boundary312 mol->SetBoxDimension(&x);313 313 break; 314 314 } … … 463 463 cin >> tmp1; 464 464 first = mol->start; 465 while(first->next != mol->end) { 466 first = first->next; 465 second = first->next; 466 while(second != mol->end) { 467 first = second; 468 second = first->next; 467 469 if (first->x.DistanceSquared((const Vector *)&second->x) > tmp1*tmp1) // distance to first above radius ... 468 470 mol->RemoveAtom(first); … … 472 474 cout << Verbose(0) << "Which axis is it: "; 473 475 cin >> axis; 474 cout << Verbose(0) << "L eft inwardboundary: ";476 cout << Verbose(0) << "Lower boundary: "; 475 477 cin >> tmp1; 476 cout << Verbose(0) << " Right inwardboundary: ";478 cout << Verbose(0) << "Upper boundary: "; 477 479 cin >> tmp2; 478 480 first = mol->start; 479 while(first->next != mol->end) { 480 first = first->next; 481 if ((first->x.x[axis] > tmp2) || (first->x.x[axis] < tmp1)) // out of boundary ... 481 second = first->next; 482 while(second != mol->end) { 483 first = second; 484 second = first->next; 485 if ((first->x.x[axis] < tmp1) || (first->x.x[axis] > tmp2)) {// out of boundary ... 486 //cout << "Atom " << *first << " with " << first->x.x[axis] << " on axis " << axis << " is out of bounds [" << tmp1 << "," << tmp2 << "]." << endl; 482 487 mol->RemoveAtom(first); 488 } 483 489 } 484 490 break; … … 644 650 cout << Verbose(0) << "all else - go back" << endl; 645 651 cout << Verbose(0) << "===============================================" << endl; 646 if (molecules->NumberOfActiveMolecules() > 0)652 if (molecules->NumberOfActiveMolecules() > 1) 647 653 cout << Verbose(0) << "WARNING: There is more than one molecule active! Atoms will be added to each." << endl; 648 654 cout << Verbose(0) << "INPUT: "; … … 655 661 656 662 case 'a': // add atom 657 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) { 663 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 664 if ((*ListRunner)->ActiveFlag) { 658 665 mol = *ListRunner; 659 666 cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; … … 663 670 664 671 case 'b': // scale a bond 665 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) { 672 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 673 if ((*ListRunner)->ActiveFlag) { 666 674 mol = *ListRunner; 667 675 cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; … … 685 693 686 694 case 'c': // unit scaling of the metric 687 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) { 695 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 696 if ((*ListRunner)->ActiveFlag) { 688 697 mol = *ListRunner; 689 698 cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; … … 701 710 702 711 case 'l': // measure distances or angles 703 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) { 712 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 713 if ((*ListRunner)->ActiveFlag) { 704 714 mol = *ListRunner; 705 715 cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; … … 709 719 710 720 case 'r': // remove atom 711 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) { 721 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 722 if ((*ListRunner)->ActiveFlag) { 712 723 mol = *ListRunner; 713 724 cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; … … 717 728 718 729 case 'u': // change an atom's element 719 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) { 730 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 731 if ((*ListRunner)->ActiveFlag) { 720 732 int Z; 721 733 mol = *ListRunner; … … 761 773 cout << Verbose(0) << "all else - go back" << endl; 762 774 cout << Verbose(0) << "===============================================" << endl; 763 if (molecules->NumberOfActiveMolecules() > 0)775 if (molecules->NumberOfActiveMolecules() > 1) 764 776 cout << Verbose(0) << "WARNING: There is more than one molecule active! Atoms will be added to each." << endl; 765 777 cout << Verbose(0) << "INPUT: "; … … 772 784 773 785 case 'd': // duplicate the periodic cell along a given axis, given times 774 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) { 786 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 787 if ((*ListRunner)->ActiveFlag) { 775 788 mol = *ListRunner; 776 789 cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; … … 830 843 831 844 case 'g': // center the atoms 832 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) { 845 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 846 if ((*ListRunner)->ActiveFlag) { 833 847 mol = *ListRunner; 834 848 cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; … … 838 852 839 853 case 'i': // align all atoms 840 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) { 854 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 855 if ((*ListRunner)->ActiveFlag) { 841 856 mol = *ListRunner; 842 857 cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; … … 846 861 847 862 case 'm': // mirror atoms along a given axis 848 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) { 863 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 864 if ((*ListRunner)->ActiveFlag) { 849 865 mol = *ListRunner; 850 866 cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; … … 854 870 855 871 case 'o': // create the connection matrix 856 { 872 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 873 if ((*ListRunner)->ActiveFlag) { 857 874 double bonddistance; 858 875 clock_t start,end; … … 868 885 869 886 case 't': // translate all atoms 870 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) { 887 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 888 if ((*ListRunner)->ActiveFlag) { 871 889 mol = *ListRunner; 872 890 cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl; 873 891 cout << Verbose(0) << "Enter translation vector." << endl; 874 892 x.AskPosition(mol->cell_size,0); 875 mol-> Translate((const Vector *)&x);893 mol->Center.AddVector((const Vector *)&x); 876 894 } 877 895 break; … … 895 913 { 896 914 char choice; // menu choice char 897 Vector Center;915 Vector center; 898 916 int nr, count; 899 917 molecule *mol = NULL; 900 char filename[MAXSTRINGSIZE]; 901 902 cout << Verbose(0) << "==========Edit MOLECULES=====================" << endl; 918 919 cout << Verbose(0) << "==========EDIT MOLECULES=====================" << endl; 903 920 cout << Verbose(0) << "c - create new molecule" << endl; 904 921 cout << Verbose(0) << "l - load molecule from xyz file" << endl; 905 922 cout << Verbose(0) << "n - change molecule's name" << endl; 906 923 cout << Verbose(0) << "N - give molecules filename" << endl; 907 cout << Verbose(0) << "p - parse xyz file into molecule" << endl;924 cout << Verbose(0) << "p - parse atoms in xyz file into molecule" << endl; 908 925 cout << Verbose(0) << "r - remove a molecule" << endl; 909 926 cout << Verbose(0) << "all else - go back" << endl; … … 921 938 break; 922 939 923 case 'l': // laod from XYZ file 924 cout << Verbose(0) << "Format should be XYZ with: ShorthandOfElement\tX\tY\tZ" << endl; 925 mol = new molecule(periode); 926 do { 927 cout << Verbose(0) << "Enter file name: "; 940 case 'l': // load from XYZ file 941 { 942 char filename[MAXSTRINGSIZE]; 943 cout << Verbose(0) << "Format should be XYZ with: ShorthandOfElement\tX\tY\tZ" << endl; 944 mol = new molecule(periode); 945 do { 946 cout << Verbose(0) << "Enter file name: "; 947 cin >> filename; 948 } while (!mol->AddXYZFile(filename)); 949 mol->SetNameFromFilename(filename); 950 // center at set box dimensions 951 mol->CenterEdge((ofstream *)&cout, ¢er); 952 mol->cell_size[0] = center.x[0]; 953 mol->cell_size[1] = 0; 954 mol->cell_size[2] = center.x[1]; 955 mol->cell_size[3] = 0; 956 mol->cell_size[4] = 0; 957 mol->cell_size[5] = center.x[2]; 958 molecules->insert(mol); 959 } 960 break; 961 962 case 'n': 963 { 964 char filename[MAXSTRINGSIZE]; 965 do { 966 cout << Verbose(0) << "Enter index of molecule: "; 967 cin >> nr; 968 mol = molecules->ReturnIndex(nr); 969 } while (mol == NULL); 970 cout << Verbose(0) << "Enter name: "; 928 971 cin >> filename; 929 } while (!mol->AddXYZFile(filename)); 930 mol->SetNameFromFilename(filename); 931 // center at set box dimensions 932 mol->CenterEdge((ofstream *)&cout, &Center); 933 mol->cell_size[0] = Center.x[0]; 934 mol->cell_size[1] = 0; 935 mol->cell_size[2] = Center.x[1]; 936 mol->cell_size[3] = 0; 937 mol->cell_size[4] = 0; 938 mol->cell_size[5] = Center.x[2]; 939 molecules->insert(mol); 940 break; 941 942 case 'n': 943 do { 944 cout << Verbose(0) << "Enter index of molecule: "; 945 cin >> nr; 946 mol = molecules->ReturnIndex(nr); 947 } while (mol != NULL); 948 cout << Verbose(0) << "Enter name: "; 949 cin >> filename; 950 strcpy(mol->name, filename); 972 strcpy(mol->name, filename); 973 } 951 974 break; 952 975 953 976 case 'N': 954 do { 955 cout << Verbose(0) << "Enter index of molecule: "; 956 cin >> nr; 957 mol = molecules->ReturnIndex(nr); 958 } while (mol != NULL); 959 cout << Verbose(0) << "Enter name: "; 960 cin >> filename; 961 mol->SetNameFromFilename(filename); 977 { 978 char filename[MAXSTRINGSIZE]; 979 do { 980 cout << Verbose(0) << "Enter index of molecule: "; 981 cin >> nr; 982 mol = molecules->ReturnIndex(nr); 983 } while (mol == NULL); 984 cout << Verbose(0) << "Enter name: "; 985 cin >> filename; 986 mol->SetNameFromFilename(filename); 987 } 962 988 break; 963 989 964 990 case 'p': // parse XYZ file 965 mol = NULL; 966 do { 967 cout << Verbose(0) << "Enter index of molecule: "; 968 cin >> nr; 969 mol = molecules->ReturnIndex(nr); 970 } while (mol == NULL); 971 cout << Verbose(0) << "Format should be XYZ with: ShorthandOfElement\tX\tY\tZ" << endl; 972 do { 973 cout << Verbose(0) << "Enter file name: "; 974 cin >> filename; 975 } while (!mol->AddXYZFile(filename)); 976 mol->SetNameFromFilename(filename); 991 { 992 char filename[MAXSTRINGSIZE]; 993 mol = NULL; 994 do { 995 cout << Verbose(0) << "Enter index of molecule: "; 996 cin >> nr; 997 mol = molecules->ReturnIndex(nr); 998 } while (mol == NULL); 999 cout << Verbose(0) << "Format should be XYZ with: ShorthandOfElement\tX\tY\tZ" << endl; 1000 do { 1001 cout << Verbose(0) << "Enter file name: "; 1002 cin >> filename; 1003 } while (!mol->AddXYZFile(filename)); 1004 mol->SetNameFromFilename(filename); 1005 } 977 1006 break; 978 1007 … … 981 1010 cin >> nr; 982 1011 count = 1; 983 MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); 984 for(; ((ListRunner != molecules->ListOfMolecules.end()) && (count < nr)); ListRunner++); 985 mol = *ListRunner; 986 if (count == nr) { 987 molecules->ListOfMolecules.erase(ListRunner); 988 delete(mol); 989 } 1012 for( MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 1013 if (nr == (*ListRunner)->IndexNr) { 1014 mol = *ListRunner; 1015 molecules->ListOfMolecules.erase(ListRunner); 1016 delete(mol); 1017 } 990 1018 break; 991 1019 } … … 1002 1030 1003 1031 cout << Verbose(0) << "===========MERGE MOLECULES=====================" << endl; 1032 cout << Verbose(0) << "a - simple add of one molecule to another" << endl; 1004 1033 cout << Verbose(0) << "e - embedding merge of two molecules" << endl; 1005 1034 cout << Verbose(0) << "m - multi-merge of all molecules" << endl; … … 1016 1045 break; 1017 1046 1047 case 'a': 1048 { 1049 int src, dest; 1050 molecule *srcmol = NULL, *destmol = NULL; 1051 { 1052 do { 1053 cout << Verbose(0) << "Enter index of destination molecule: "; 1054 cin >> dest; 1055 destmol = molecules->ReturnIndex(dest); 1056 } while ((destmol == NULL) && (dest != -1)); 1057 do { 1058 cout << Verbose(0) << "Enter index of source molecule to add from: "; 1059 cin >> src; 1060 srcmol = molecules->ReturnIndex(src); 1061 } while ((srcmol == NULL) && (src != -1)); 1062 if ((src != -1) && (dest != -1)) 1063 molecules->SimpleAdd(srcmol, destmol); 1064 } 1065 } 1066 break; 1067 1018 1068 case 'e': 1069 cout << Verbose(0) << "Not implemented yet." << endl; 1019 1070 break; 1020 1071 1021 1072 case 'm': 1073 { 1074 int nr; 1075 molecule *mol = NULL; 1076 do { 1077 cout << Verbose(0) << "Enter index of molecule to merge into: "; 1078 cin >> nr; 1079 mol = molecules->ReturnIndex(nr); 1080 } while ((mol == NULL) && (nr != -1)); 1081 if (nr != -1) { 1082 int N = molecules->ListOfMolecules.size()-1; 1083 int *src = new int(N); 1084 for(MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 1085 if ((*ListRunner)->IndexNr != nr) 1086 src[N++] = (*ListRunner)->IndexNr; 1087 molecules->SimpleMultiMerge(mol, src, N); 1088 delete[](src); 1089 } 1090 } 1022 1091 break; 1023 1092 1024 1093 case 's': 1094 cout << Verbose(0) << "Not implemented yet." << endl; 1025 1095 break; 1026 1096 1027 1097 case 't': 1098 { 1099 int src, dest; 1100 molecule *srcmol = NULL, *destmol = NULL; 1101 { 1102 do { 1103 cout << Verbose(0) << "Enter index of destination molecule: "; 1104 cin >> dest; 1105 destmol = molecules->ReturnIndex(dest); 1106 } while ((destmol == NULL) && (dest != -1)); 1107 do { 1108 cout << Verbose(0) << "Enter index of source molecule to merge into: "; 1109 cin >> src; 1110 srcmol = molecules->ReturnIndex(src); 1111 } while ((srcmol == NULL) && (src != -1)); 1112 if ((src != -1) && (dest != -1)) 1113 molecules->SimpleMerge(srcmol, destmol); 1114 } 1115 } 1028 1116 break; 1029 1117 } … … 1125 1213 molecule *mol = new molecule(periode); 1126 1214 1127 // merge all molecules in MoleculeListClass into this molecule1215 // translate each to its center and merge all molecules in MoleculeListClass into this molecule 1128 1216 int N = molecules->ListOfMolecules.size(); 1129 1217 int *src = new int(N); 1130 1218 N=0; 1131 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 1219 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) { 1132 1220 src[N++] = (*ListRunner)->IndexNr; 1221 (*ListRunner)->Translate(&(*ListRunner)->Center); 1222 } 1133 1223 molecules->SimpleMultiAdd(mol, src, N); 1224 delete[](src); 1225 // ... and translate back 1226 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) { 1227 (*ListRunner)->Center.Scale(-1.); 1228 (*ListRunner)->Translate(&(*ListRunner)->Center); 1229 (*ListRunner)->Center.Scale(-1.); 1230 } 1134 1231 1135 1232 cout << Verbose(0) << "Storing configuration ... " << endl; … … 1137 1234 mol->CalculateOrbitals(*configuration); 1138 1235 configuration->InitMaxMinStopStep = configuration->MaxMinStopStep = configuration->MaxPsiDouble; 1139 strcpy(filename, ConfigFileName);1140 1236 if (ConfigFileName != NULL) { // test the file name 1141 output.open(ConfigFileName, ios::trunc); 1237 strcpy(filename, ConfigFileName); 1238 output.open(filename, ios::trunc); 1142 1239 } else if (strlen(configuration->configname) != 0) { 1143 1240 strcpy(filename, configuration->configname); … … 1227 1324 // simply create a new molecule, wherein the config file is loaded and the manipulation takes place 1228 1325 molecule *mol = new molecule(periode); 1326 mol->ActiveFlag = true; 1229 1327 molecules->insert(mol); 1230 1328 … … 1257 1355 cout << "\t-m <0/1>\tCalculate (0)/ Align in(1) PAS with greatest EV along z axis." << endl; 1258 1356 cout << "\t-n\tFast parsing (i.e. no trajectories are looked for)." << endl; 1259 cout << "\t-N \tGet non-convex-envelope." << endl;1357 cout << "\t-N <radius> <file>\tGet non-convex-envelope." << endl; 1260 1358 cout << "\t-o <out>\tGet volume of the convex envelope (and store to tecplot file)." << endl; 1261 1359 cout << "\t-p <file>\tParse given xyz file and create raw config file from it." << endl; 1262 1360 cout << "\t-P <file>\tParse given forces file and append as an MD step to config file via Verlet." << endl; 1361 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; 1263 1362 cout << "\t-r\t\tConvert file from an old pcp syntax." << endl; 1363 cout << "\t-R\t\tRemove all atoms out of sphere around a given one." << endl; 1264 1364 cout << "\t-t x1 x2 x3\tTranslate all atoms by this vector (x1,x2,x3)." << endl; 1265 1365 cout << "\t-T x1 x2 x3\tTranslate periodically all atoms by this vector (x1,x2,x3)." << endl; … … 1504 1604 } 1505 1605 break; 1606 case 'L': 1607 ExitFlag = 1; 1608 SaveFlag = true; 1609 cout << Verbose(1) << "Linear interpolation between configuration " << argv[argptr] << " and " << argv[argptr+1] << "." << endl; 1610 if (!mol->LinearInterpolationBetweenConfiguration((ofstream *)&cout, atoi(argv[argptr]), atoi(argv[argptr+1]), argv[argptr+2], configuration)) 1611 cout << Verbose(2) << "Could not store " << argv[argptr+2] << " files." << endl; 1612 else 1613 cout << Verbose(2) << "Steps created and " << argv[argptr+2] << " files stored." << endl; 1614 argptr+=3; 1615 break; 1506 1616 case 'P': 1507 1617 ExitFlag = 1; … … 1512 1622 SaveFlag = true; 1513 1623 cout << Verbose(1) << "Parsing forces file and Verlet integrating." << endl; 1514 if (!mol->VerletForceIntegration( argv[argptr], configuration.Deltat, configuration.GetIsAngstroem()))1624 if (!mol->VerletForceIntegration((ofstream *)&cout, argv[argptr], configuration)) 1515 1625 cout << Verbose(2) << "File not found." << endl; 1516 1626 else 1517 1627 cout << Verbose(2) << "File found and parsed." << endl; 1518 1628 argptr+=1; 1629 } 1630 break; 1631 case 'R': 1632 ExitFlag = 1; 1633 if ((argptr+1 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1]))) { 1634 ExitFlag = 255; 1635 cerr << "Not enough or invalid arguments given for removing atoms: -R <id> <distance>" << endl; 1636 } else { 1637 SaveFlag = true; 1638 cout << Verbose(1) << "Removing atoms around " << argv[argptr] << " with radius " << argv[argptr+1] << "." << endl; 1639 double tmp1 = atof(argv[argptr+1]); 1640 atom *third = mol->FindAtom(atoi(argv[argptr])); 1641 atom *first = mol->start; 1642 if ((third != NULL) && (first != mol->end)) { 1643 atom *second = first->next; 1644 while(second != mol->end) { 1645 first = second; 1646 second = first->next; 1647 if (first->x.DistanceSquared((const Vector *)&third->x) > tmp1*tmp1) // distance to first above radius ... 1648 mol->RemoveAtom(first); 1649 } 1650 } else { 1651 cerr << "Removal failed due to missing atoms on molecule or wrong id." << endl; 1652 } 1653 argptr+=2; 1519 1654 } 1520 1655 break; … … 1533 1668 argptr+=3; 1534 1669 } 1535 break;1536 1670 case 'T': 1537 1671 ExitFlag = 1; … … 1583 1717 } else { 1584 1718 SaveFlag = true; 1719 j = -1; 1585 1720 cout << Verbose(1) << "Centering atoms in config file within given simulation box." << endl; 1586 1721 for (int i=0;i<6;i++) { … … 1609 1744 for (int i=0;i<NDIM;i++) { 1610 1745 j += i+1; 1611 x.x[i] = atof(argv[argptr+ +]);1746 x.x[i] = atof(argv[argptr+i]); 1612 1747 mol->cell_size[j] += x.x[i]*2.; 1613 1748 } … … 1619 1754 ExitFlag = 1; 1620 1755 SaveFlag = true; 1621 cout << Verbose(1) << "Centering atoms in origin." << endl; 1622 mol->CenterOrigin((ofstream *)&cout, &x); 1756 cout << Verbose(1) << "Centering atoms on edge and setting box dimensions." << endl; 1757 x.Zero(); 1758 mol->CenterEdge((ofstream *)&cout, &x); 1623 1759 mol->SetBoxDimension(&x); 1624 1760 argptr+=0; … … 1802 1938 string line; 1803 1939 char *ConfigFileName = NULL; 1804 int j , count;1940 int j; 1805 1941 1806 1942 // =========================== PARSE COMMAND LINE OPTIONS ==================================== … … 1844 1980 cout << Verbose(0) << "============Menu===============================" << endl; 1845 1981 cout << Verbose(0) << "a - set molecule (in)active" << endl; 1846 cout << Verbose(0) << "e - edit new molecules" << endl;1982 cout << Verbose(0) << "e - edit molecules (load, parse, save)" << endl; 1847 1983 cout << Verbose(0) << "g - globally manipulate atoms in molecule" << endl; 1848 1984 cout << Verbose(0) << "M - Merge molecules" << endl; … … 1863 1999 cout << "Enter index of molecule: "; 1864 2000 cin >> j; 1865 count = 1; 1866 MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); 1867 for(; ((ListRunner != molecules->ListOfMolecules.end()) && (count < j)); ListRunner++); 1868 if (count == j) 1869 (*ListRunner)->ActiveFlag = !(*ListRunner)->ActiveFlag; 2001 for(MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) 2002 if ((*ListRunner)->IndexNr == j) 2003 (*ListRunner)->ActiveFlag = !(*ListRunner)->ActiveFlag; 1870 2004 } 1871 2005 break; -
src/config.cpp
r042f82 r36ec71 169 169 configpath = (char *) MallocString(sizeof(char)*MAXSTRINGSIZE,"config constructor: configpath"); 170 170 configname = (char *) MallocString(sizeof(char)*MAXSTRINGSIZE,"config constructor: configname"); 171 ThermostatImplemented = (int *) Malloc((MaxThermostats)*(sizeof(int)), "config constructor: *ThermostatImplemented"); 172 ThermostatNames = (char **) Malloc((MaxThermostats)*(sizeof(char *)), "config constructor: *ThermostatNames"); 173 for (int j=0;j<MaxThermostats;j++) 174 ThermostatNames[j] = (char *) MallocString(12*(sizeof(char)), "config constructor: ThermostatNames[]"); 175 Thermostat = 4; 176 alpha = 0.; 177 ScaleTempStep = 25; 178 TempFrequency = 2.5; 171 179 strcpy(mainname,"pcp"); 172 180 strcpy(defaultpath,"not specified"); … … 175 183 configname[0]='\0'; 176 184 basis = "3-21G"; 185 186 strcpy(ThermostatNames[0],"None"); 187 ThermostatImplemented[0] = 1; 188 strcpy(ThermostatNames[1],"Woodcock"); 189 ThermostatImplemented[1] = 1; 190 strcpy(ThermostatNames[2],"Gaussian"); 191 ThermostatImplemented[2] = 1; 192 strcpy(ThermostatNames[3],"Langevin"); 193 ThermostatImplemented[3] = 1; 194 strcpy(ThermostatNames[4],"Berendsen"); 195 ThermostatImplemented[4] = 1; 196 strcpy(ThermostatNames[5],"NoseHoover"); 197 ThermostatImplemented[5] = 1; 177 198 178 199 FastParsing = false; … … 187 208 DoFullCurrent=0; 188 209 DoWannier=0; 210 DoConstrainedMD=0; 189 211 CommonWannier=0; 190 212 SawtoothStart=0.01; … … 195 217 196 218 MaxOuterStep=0; 197 Deltat= 1;219 Deltat=0.01; 198 220 OutVisStep=10; 199 221 OutSrcStep=5; … … 247 269 Free((void **)&configpath, "config::~config: *configpath"); 248 270 Free((void **)&configname, "config::~config: *configname"); 271 Free((void **)&ThermostatImplemented, "config::~config: *ThermostatImplemented"); 272 for (int j=0;j<MaxThermostats;j++) 273 Free((void **)&ThermostatNames[j], "config::~config: *ThermostatNames[]"); 274 Free((void **)&ThermostatNames, "config::~config: **ThermostatNames"); 249 275 }; 276 277 /** Readin of Thermostat related values from parameter file. 278 * \param *source parameter file 279 */ 280 void config::InitThermostats(ifstream *source) 281 { 282 char *thermo = MallocString(12, "IonsInitRead: thermo"); 283 int verbose = 0; 284 285 // read desired Thermostat from file along with needed additional parameters 286 if (ParseForParameter(verbose,source,"Thermostat", 0, 1, 1, string_type, thermo, 1, optional)) { 287 if (strcmp(thermo, ThermostatNames[0]) == 0) { // None 288 if (ThermostatImplemented[0] == 1) { 289 Thermostat = None; 290 } else { 291 cout << Verbose(1) << "Warning: " << ThermostatNames[0] << " thermostat not implemented, falling back to None." << endl; 292 Thermostat = None; 293 } 294 } else if (strcmp(thermo, ThermostatNames[1]) == 0) { // Woodcock 295 if (ThermostatImplemented[1] == 1) { 296 Thermostat = Woodcock; 297 ParseForParameter(verbose,source,"Thermostat", 0, 2, 1, int_type, &ScaleTempStep, 1, critical); // read scaling frequency 298 } else { 299 cout << Verbose(1) << "Warning: " << ThermostatNames[0] << " thermostat not implemented, falling back to None." << endl; 300 Thermostat = None; 301 } 302 } else if (strcmp(thermo, ThermostatNames[2]) == 0) { // Gaussian 303 if (ThermostatImplemented[2] == 1) { 304 Thermostat = Gaussian; 305 ParseForParameter(verbose,source,"Thermostat", 0, 2, 1, int_type, &ScaleTempStep, 1, critical); // read collision rate 306 } else { 307 cout << Verbose(1) << "Warning: " << ThermostatNames[0] << " thermostat not implemented, falling back to None." << endl; 308 Thermostat = None; 309 } 310 } else if (strcmp(thermo, ThermostatNames[3]) == 0) { // Langevin 311 if (ThermostatImplemented[3] == 1) { 312 Thermostat = Langevin; 313 ParseForParameter(verbose,source,"Thermostat", 0, 2, 1, double_type, &TempFrequency, 1, critical); // read gamma 314 if (ParseForParameter(verbose,source,"Thermostat", 0, 3, 1, double_type, &alpha, 1, optional)) { 315 cout << Verbose(2) << "Extended Stochastic Thermostat detected with interpolation coefficient " << alpha << "." << endl; 316 } else { 317 alpha = 1.; 318 } 319 } else { 320 cout << Verbose(1) << "Warning: " << ThermostatNames[0] << " thermostat not implemented, falling back to None." << endl; 321 Thermostat = None; 322 } 323 } else if (strcmp(thermo, ThermostatNames[4]) == 0) { // Berendsen 324 if (ThermostatImplemented[4] == 1) { 325 Thermostat = Berendsen; 326 ParseForParameter(verbose,source,"Thermostat", 0, 2, 1, double_type, &TempFrequency, 1, critical); // read \tau_T 327 } else { 328 cout << Verbose(1) << "Warning: " << ThermostatNames[0] << " thermostat not implemented, falling back to None." << endl; 329 Thermostat = None; 330 } 331 } else if (strcmp(thermo, ThermostatNames[5]) == 0) { // Nose-Hoover 332 if (ThermostatImplemented[5] == 1) { 333 Thermostat = NoseHoover; 334 ParseForParameter(verbose,source,"Thermostat", 0, 2, 1, double_type, &HooverMass, 1, critical); // read Hoovermass 335 alpha = 0.; 336 } else { 337 cout << Verbose(1) << "Warning: " << ThermostatNames[0] << " thermostat not implemented, falling back to None." << endl; 338 Thermostat = None; 339 } 340 } else { 341 cout << Verbose(1) << " Warning: thermostat name was not understood!" << endl; 342 Thermostat = None; 343 } 344 } else { 345 if ((MaxOuterStep > 0) && (TargetTemp != 0)) 346 cout << Verbose(2) << "No thermostat chosen despite finite temperature MD, falling back to None." << endl; 347 Thermostat = None; 348 } 349 Free((void **)&thermo, "InitThermostats: thermo"); 350 }; 351 250 352 251 353 /** Displays menu for editing each entry of the config file. … … 597 699 void config::Load(char *filename, periodentafel *periode, molecule *mol) 598 700 { 701 ifstream *file = new ifstream(filename); 702 if (file == NULL) { 703 cerr << "ERROR: config file " << filename << " missing!" << endl; 704 return; 705 } 599 706 RetrieveConfigPathAndName(filename); 600 707 … … 614 721 int verbose = 0; 615 722 double value[3]; 616 723 724 InitThermostats(file); 725 617 726 /* Namen einlesen */ 618 727 … … 667 776 if (config::SawtoothStart > 1.) config::SawtoothStart = 1.; 668 777 } 669 778 779 if (ParseForParameter(verbose,FileBuffer,"DoConstrainedMD", 0, 1, 1, int_type, &(config::DoConstrainedMD), 1, optional)) 780 if (config::DoConstrainedMD < 0) 781 config::DoConstrainedMD = 0; 670 782 ParseForParameter(verbose,FileBuffer,"MaxOuterStep", 0, 1, 1, int_type, &(config::MaxOuterStep), 1, critical); 671 783 if (!ParseForParameter(verbose,FileBuffer,"Deltat", 0, 1, 1, double_type, &(config::Deltat), 1, optional)) … … 1168 1280 *output << "DoPerturbation\t" << config::DoPerturbation << "\t# Do perturbation calculate and determine susceptibility and shielding" << endl; 1169 1281 *output << "DoFullCurrent\t" << config::DoFullCurrent << "\t# Do full perturbation" << endl; 1282 *output << "DoConstrainedMD\t" << config::DoConstrainedMD << "\t# Do perform a constrained (>0, relating to current MD step) instead of unconstrained (0) MD" << endl; 1283 *output << "Thermostat\t" << ThermostatNames[Thermostat] << "\t"; 1284 switch(Thermostat) { 1285 default: 1286 case None: 1287 break; 1288 case Woodcock: 1289 *output << ScaleTempStep; 1290 break; 1291 case Gaussian: 1292 *output << ScaleTempStep; 1293 break; 1294 case Langevin: 1295 *output << TempFrequency << "\t" << alpha; 1296 break; 1297 case Berendsen: 1298 *output << TempFrequency; 1299 break; 1300 case NoseHoover: 1301 *output << HooverMass; 1302 break; 1303 }; 1304 *output << "\t# Which Thermostat and its parameters to use in MD case." << endl; 1170 1305 *output << "CommonWannier\t" << config::CommonWannier << "\t# Put virtual centers at indivual orbits, all common, merged by variance, to grid point, to cell center" << endl; 1171 1306 *output << "SawtoothStart\t" << config::SawtoothStart << "\t# Absolute value for smooth transition at cell border " << endl; … … 1305 1440 *output << ")" << endl; 1306 1441 *output << "basis<GaussianBasisSet>: (" << endl; 1307 *output << "\tname = \"" << basis << "\"" << endl;1442 *output << "\tname = \"" << basis << "\"" << endl; 1308 1443 *output << "\tmolecule = $:molecule" << endl; 1309 1444 *output << ")" << endl; -
src/datacreator.cpp
r042f82 r36ec71 63 63 cout << msg << endl; 64 64 output << "# " << msg << ", created on " << datum; 65 output << "#Order\tFrag.No.\t" << Fragments.Header << endl;65 output << "#Order\tFrag.No.\t" << Fragments.Header[Fragments.MatrixCounter] << endl; 66 66 for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) { 67 67 for(int i=KeySet.FragmentsPerOrder[BondOrder];i--;) { 68 68 for(int j=Fragments.RowCounter[ KeySet.OrderSet[BondOrder][i] ];j--;) 69 for(int k=Fragments.ColumnCounter ;k--;)69 for(int k=Fragments.ColumnCounter[ KeySet.OrderSet[BondOrder][i] ];k--;) 70 70 Fragments.Matrix[Fragments.MatrixCounter][j][k] += Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k]; 71 71 } 72 72 output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder]; 73 for (int l=0;l<Fragments.ColumnCounter ;l++)73 for (int l=0;l<Fragments.ColumnCounter[Fragments.MatrixCounter];l++) 74 74 output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter]-1 ][l]; 75 75 output << endl; … … 96 96 cout << msg << endl; 97 97 output << "# " << msg << ", created on " << datum; 98 output << "#Order\tFrag.No.\t" << Fragments.Header << endl;98 output << "#Order\tFrag.No.\t" << Fragments.Header[Fragments.MatrixCounter] << endl; 99 99 Fragments.SetLastMatrix(Energy.Matrix[Energy.MatrixCounter],0); 100 100 for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) { 101 101 for(int i=KeySet.FragmentsPerOrder[BondOrder];i--;) { 102 102 for(int j=Fragments.RowCounter[ KeySet.OrderSet[BondOrder][i] ];j--;) 103 for(int k=Fragments.ColumnCounter ;k--;)103 for(int k=Fragments.ColumnCounter[ KeySet.OrderSet[BondOrder][i] ];k--;) 104 104 Fragments.Matrix[Fragments.MatrixCounter][j][k] -= Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k]; 105 105 } 106 106 output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder]; 107 for (int l=0;l<Fragments.ColumnCounter ;l++)107 for (int l=0;l<Fragments.ColumnCounter[Energy.MatrixCounter];l++) 108 108 if (fabs(Energy.Matrix[Energy.MatrixCounter][ Energy.RowCounter[Energy.MatrixCounter]-1 ][l]) < MYEPSILON) 109 109 output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter]-1 ][l]; … … 133 133 cout << msg << endl; 134 134 output << "# " << msg << ", created on " << datum; 135 output << "# Order\tFrag.No.\t" << Fragments.Header << endl;135 output << "# Order\tFrag.No.\t" << Fragments.Header[Fragments.MatrixCounter] << endl; 136 136 Fragments.SetLastMatrix(0.,0); 137 137 for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) { … … 139 139 output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder]; 140 140 CreateForce(Fragments, Fragments.MatrixCounter); 141 for (int l=0;l<Fragments.ColumnCounter ;l++)141 for (int l=0;l<Fragments.ColumnCounter[Fragments.MatrixCounter];l++) 142 142 output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter] ][l]; 143 143 output << endl; … … 165 165 cout << msg << endl; 166 166 output << "# " << msg << ", created on " << datum; 167 output << "# Order\tFrag.No.\t" << Fragments.Header << endl;167 output << "# Order\tFrag.No.\t" << Fragments.Header[Fragments.MatrixCounter] << endl; 168 168 Fragments.SetLastMatrix(Force.Matrix[Force.MatrixCounter],0); 169 169 for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) { … … 171 171 output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder]; 172 172 CreateForce(Fragments, Fragments.MatrixCounter); 173 for (int l=0;l<Fragments.ColumnCounter ;l++)173 for (int l=0;l<Fragments.ColumnCounter[Fragments.MatrixCounter];l++) 174 174 output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter] ][l]; 175 175 output << endl; … … 198 198 cout << msg << endl; 199 199 output << "# " << msg << ", created on " << datum; 200 output << "# AtomNo\t" << Fragments.Header << endl;200 output << "# AtomNo\t" << Fragments.Header[Fragments.MatrixCounter] << endl; 201 201 Fragments.SetLastMatrix(Force.Matrix[Force.MatrixCounter], 0); 202 202 for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) { … … 207 207 for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) { 208 208 output << Fragments.Indices[Fragments.MatrixCounter][j] << "\t"; 209 for (int l=0;l<Fragments.ColumnCounter ;l++) {209 for (int l=0;l<Fragments.ColumnCounter[ Fragments.MatrixCounter ];l++) { 210 210 if (((l+1) % 3) == 0) { 211 211 norm = 0.; … … 213 213 norm += Force.Matrix[Force.MatrixCounter][ j ][l+m]*Force.Matrix[Force.MatrixCounter][ j ][l+m]; 214 214 norm = sqrt(norm); 215 } 215 } 216 216 // if (norm < MYEPSILON) 217 217 output << scientific << Fragments.Matrix[Fragments.MatrixCounter][ j ][l] << "\t"; … … 244 244 cout << msg << endl; 245 245 output << "# " << msg << ", created on " << datum; 246 output << "# AtomNo\t" << Fragments.Header << endl;246 output << "# AtomNo\t" << Fragments.Header[Fragments.MatrixCounter] << endl; 247 247 for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) { 248 248 //cout << "Current order is " << BondOrder << "." << endl; … … 252 252 for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) { 253 253 output << Fragments.Indices[Fragments.MatrixCounter][j] << "\t"; 254 for (int l=0;l<Fragments.ColumnCounter ;l++)254 for (int l=0;l<Fragments.ColumnCounter[ Fragments.MatrixCounter ];l++) 255 255 output << scientific << Fragments.Matrix[Fragments.MatrixCounter][ j ][l] << "\t"; 256 256 output << endl; … … 262 262 }; 263 263 264 265 /** Plot hessian error vs. vs atom vs. order. 266 * \param &Hessian HessianMatrix containing reference values (in MatrixCounter matrix) 267 * \param &Fragments HessianMatrix class containing matrix values 268 * \param KeySet KeySetContainer class holding bond KeySetContainer::Order 269 * \param *prefix prefix in filename (without ending) 270 * \param *msg message to be place in first line as a comment 271 * \param *datum current date and time 272 * \return true if file was written successfully 273 */ 274 bool CreateDataDeltaHessianOrderPerAtom(class HessianMatrix &Hessian, class HessianMatrix &Fragments, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum) 275 { 276 stringstream filename; 277 ofstream output; 278 279 filename << prefix << ".dat"; 280 if (!OpenOutputFile(output, dir, filename.str().c_str())) return false; 281 cout << msg << endl; 282 output << "# " << msg << ", created on " << datum; 283 output << "# AtomNo\t" << Fragments.Header[Fragments.MatrixCounter] << endl; 284 Fragments.SetLastMatrix(Hessian.Matrix[Hessian.MatrixCounter], 0); 285 for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) { 286 //cout << "Current order is " << BondOrder << "." << endl; 287 Fragments.SumSubHessians(Fragments, KeySet, BondOrder, -1.); 288 // errors per atom 289 output << endl << "#Order\t" << BondOrder+1 << endl; 290 for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) { 291 output << Fragments.Indices[Fragments.MatrixCounter][j] << "\t"; 292 for (int l=0;l<Fragments.ColumnCounter[ Fragments.MatrixCounter ];l++) { 293 output << scientific << Fragments.Matrix[Fragments.MatrixCounter][ j ][l] << "\t"; 294 } 295 output << endl; 296 } 297 output << endl; 298 } 299 output.close(); 300 return true; 301 }; 302 303 /** Plot hessian error vs. vs atom vs. order in the frobenius norm. 304 * \param &Hessian HessianMatrix containing reference values (in MatrixCounter matrix) 305 * \param &Fragments HessianMatrix class containing matrix values 306 * \param KeySet KeySetContainer class holding bond KeySetContainer::Order 307 * \param *prefix prefix in filename (without ending) 308 * \param *msg message to be place in first line as a comment 309 * \param *datum current date and time 310 * \return true if file was written successfully 311 */ 312 bool CreateDataDeltaFrobeniusOrderPerAtom(class HessianMatrix &Hessian, class HessianMatrix &Fragments, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum) 313 { 314 stringstream filename; 315 ofstream output; 316 double norm = 0; 317 double tmp; 318 319 filename << prefix << ".dat"; 320 if (!OpenOutputFile(output, dir, filename.str().c_str())) return false; 321 cout << msg << endl; 322 output << "# " << msg << ", created on " << datum; 323 output << "# AtomNo\t"; 324 Fragments.SetLastMatrix(Hessian.Matrix[Hessian.MatrixCounter], 0); 325 for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) { 326 output << "Order" << BondOrder+1 << "\t"; 327 } 328 output << endl; 329 output << Fragments.RowCounter[ Fragments.MatrixCounter ] << "\t"; 330 for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) { 331 //cout << "Current order is " << BondOrder << "." << endl; 332 Fragments.SumSubHessians(Fragments, KeySet, BondOrder, -1.); 333 // frobenius norm of errors per atom 334 norm = 0.; 335 for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) { 336 for (int l=0;l<Fragments.ColumnCounter[ Fragments.MatrixCounter ];l++) { 337 tmp = Fragments.Matrix[Fragments.MatrixCounter][ j ][l]; 338 norm += tmp*tmp; 339 } 340 } 341 output << scientific << sqrt(norm)/(Fragments.RowCounter[ Fragments.MatrixCounter ]*Fragments.ColumnCounter[ Fragments.MatrixCounter] ) << "\t"; 342 } 343 output << endl; 344 output.close(); 345 return true; 346 }; 347 348 /** Plot hessian error vs. vs atom vs. order. 349 * \param &Fragments HessianMatrix class containing matrix values 350 * \param KeySet KeySetContainer class holding bond KeySetContainer::Order 351 * \param *prefix prefix in filename (without ending) 352 * \param *msg message to be place in first line as a comment 353 * \param *datum current date and time 354 * \return true if file was written successfully 355 */ 356 bool CreateDataHessianOrderPerAtom(class HessianMatrix &Fragments, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum) 357 { 358 stringstream filename; 359 ofstream output; 360 361 filename << prefix << ".dat"; 362 if (!OpenOutputFile(output, dir, filename.str().c_str())) return false; 363 cout << msg << endl; 364 output << "# " << msg << ", created on " << datum; 365 output << "# AtomNo\t" << Fragments.Header[ Fragments.MatrixCounter ] << endl; 366 Fragments.SetLastMatrix(0., 0); 367 for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) { 368 //cout << "Current order is " << BondOrder << "." << endl; 369 Fragments.SumSubHessians(Fragments, KeySet, BondOrder, 1.); 370 // errors per atom 371 output << endl << "#Order\t" << BondOrder+1 << endl; 372 for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) { 373 output << Fragments.Indices[Fragments.MatrixCounter][j] << "\t"; 374 for (int l=0;l<Fragments.ColumnCounter[ Fragments.MatrixCounter ];l++) 375 output << scientific << Fragments.Matrix[Fragments.MatrixCounter][ j ][l] << "\t"; 376 output << endl; 377 } 378 output << endl; 379 } 380 output.close(); 381 return true; 382 }; 383 264 384 /** Plot matrix vs. fragment. 265 385 */ … … 273 393 cout << msg << endl; 274 394 output << "# " << msg << ", created on " << datum << endl; 275 output << "#Order\tFrag.No.\t" << Fragment.Header << endl;395 output << "#Order\tFrag.No.\t" << Fragment.Header[ Fragment.MatrixCounter ] << endl; 276 396 for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) { 277 397 for(int i=0;i<KeySet.FragmentsPerOrder[BondOrder];i++) { 278 398 output << BondOrder+1 << "\t" << KeySet.OrderSet[BondOrder][i]+1; 279 399 CreateFragment(Fragment, KeySet.OrderSet[BondOrder][i]); 280 for (int l=0;l<Fragment.ColumnCounter ;l++)400 for (int l=0;l<Fragment.ColumnCounter[ KeySet.OrderSet[BondOrder][i] ];l++) 281 401 output << scientific << "\t" << Fragment.Matrix[ KeySet.OrderSet[BondOrder][i] ][ Fragment.RowCounter[ KeySet.OrderSet[BondOrder][i] ] ][l]; 282 402 output << endl; … … 297 417 for(int i=KeySet.FragmentsPerOrder[BondOrder];i--;) { 298 418 if (fabs(Fragments.Matrix[ Fragments.MatrixCounter ][j][1]) < fabs(Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][1])) { 299 for (int k=Fragments.ColumnCounter ;k--;)419 for (int k=Fragments.ColumnCounter[ Fragments.MatrixCounter ];k--;) 300 420 Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k]; 301 421 } … … 314 434 int i=0; 315 435 do { // first get a minimum value unequal to 0 316 for (int k=Fragments.ColumnCounter ;k--;)436 for (int k=Fragments.ColumnCounter[ Fragments.MatrixCounter ];k--;) 317 437 Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k]; 318 438 i++; … … 320 440 for(;i<KeySet.FragmentsPerOrder[BondOrder];i++) { // then find lowest 321 441 if (fabs(Fragments.Matrix[ Fragments.MatrixCounter ][j][1]) > fabs(Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][1])) { 322 for (int k=Fragments.ColumnCounter ;k--;)442 for (int k=Fragments.ColumnCounter[ Fragments.MatrixCounter ];k--;) 323 443 Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k]; 324 444 } … … 338 458 cout << msg << endl; 339 459 output << "# " << msg << ", created on " << datum; 340 output << "#Order\tFrag.No.\t" << Fragment.Header << endl;460 output << "#Order\tFrag.No.\t" << Fragment.Header[ Fragment.MatrixCounter ] << endl; 341 461 // max 342 462 for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) { … … 344 464 CreateFragmentOrder(Fragment, KeySet, BondOrder); 345 465 output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder]; 346 for (int l=0;l<Fragment.ColumnCounter ;l++)466 for (int l=0;l<Fragment.ColumnCounter[ Fragment.MatrixCounter ];l++) 347 467 output << scientific << "\t" << Fragment.Matrix[ Fragment.MatrixCounter ][ Fragment.RowCounter[ Fragment.MatrixCounter ]-1 ][l]; 348 468 output << endl; … … 358 478 void CreateEnergy(class MatrixContainer &Energy, int MatrixNumber) 359 479 { 360 for(int k=0;k<Energy.ColumnCounter ;k++)480 for(int k=0;k<Energy.ColumnCounter[MatrixNumber];k++) 361 481 Energy.Matrix[MatrixNumber][ Energy.RowCounter[MatrixNumber] ] [k] = Energy.Matrix[MatrixNumber][ Energy.RowCounter[MatrixNumber]-1 ] [k]; 362 482 }; … … 369 489 void CreateMinimumForce(class MatrixContainer &Force, int MatrixNumber) 370 490 { 371 for (int l=Force.ColumnCounter ;l--;)491 for (int l=Force.ColumnCounter[MatrixNumber];l--;) 372 492 Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] = 0.; 373 for (int l=5;l<Force.ColumnCounter ;l+=3) {493 for (int l=5;l<Force.ColumnCounter[MatrixNumber];l+=3) { 374 494 double stored = 0; 375 495 int k=0; … … 404 524 { 405 525 int divisor = 0; 406 for (int l=Force.ColumnCounter ;l--;)526 for (int l=Force.ColumnCounter[MatrixNumber];l--;) 407 527 Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] = 0.; 408 for (int l=5;l<Force.ColumnCounter ;l+=3) {528 for (int l=5;l<Force.ColumnCounter[MatrixNumber];l+=3) { 409 529 double tmp = 0; 410 530 for (int k=Force.RowCounter[MatrixNumber];k--;) { … … 428 548 void CreateMaximumForce(class MatrixContainer &Force, int MatrixNumber) 429 549 { 430 for (int l=5;l<Force.ColumnCounter ;l+=3) {550 for (int l=5;l<Force.ColumnCounter[MatrixNumber];l+=3) { 431 551 double stored = 0; 432 552 for (int k=Force.RowCounter[MatrixNumber];k--;) { … … 460 580 void CreateVectorSumForce(class MatrixContainer &Force, int MatrixNumber) 461 581 { 462 for (int l=Force.ColumnCounter ;l--;)582 for (int l=Force.ColumnCounter[MatrixNumber];l--;) 463 583 Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] = 0.; 464 for (int l=0;l<Force.ColumnCounter ;l++) {584 for (int l=0;l<Force.ColumnCounter[MatrixNumber];l++) { 465 585 for (int k=Force.RowCounter[MatrixNumber];k--;) 466 586 Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] += Force.Matrix[MatrixNumber][k][l]; … … 538 658 void AbsEnergyPlotLine(ofstream &output, class MatrixContainer &Energy, const char *prefix, const char *xargument, const char *uses) 539 659 { 540 stringstream line(Energy.Header );660 stringstream line(Energy.Header[ Energy.MatrixCounter ]); 541 661 string token; 542 662 543 663 getline(line, token, '\t'); 544 for (int i=2; i<= Energy.ColumnCounter ;i++) {664 for (int i=2; i<= Energy.ColumnCounter[Energy.MatrixCounter];i++) { 545 665 getline(line, token, '\t'); 546 666 while (token[0] == ' ') // remove leading white spaces 547 667 token.erase(0,1); 548 668 output << "'" << prefix << ".dat' title '" << token << "' using " << xargument << ":(abs($" << i+2 << ")) " << uses; 549 if (i != (Energy.ColumnCounter ))669 if (i != (Energy.ColumnCounter[Energy.MatrixCounter])) 550 670 output << ", \\"; 551 671 output << endl; … … 562 682 void EnergyPlotLine(ofstream &output, class MatrixContainer &Energy, const char *prefix, const char *xargument, const char *uses) 563 683 { 564 stringstream line(Energy.Header );684 stringstream line(Energy.Header[Energy.MatrixCounter]); 565 685 string token; 566 686 567 687 getline(line, token, '\t'); 568 for (int i=1; i<= Energy.ColumnCounter ;i++) {688 for (int i=1; i<= Energy.ColumnCounter[Energy.MatrixCounter];i++) { 569 689 getline(line, token, '\t'); 570 690 while (token[0] == ' ') // remove leading white spaces 571 691 token.erase(0,1); 572 692 output << "'" << prefix << ".dat' title '" << token << "' using " << xargument << ":" << i+2 << " " << uses; 573 if (i != (Energy.ColumnCounter ))693 if (i != (Energy.ColumnCounter[Energy.MatrixCounter])) 574 694 output << ", \\"; 575 695 output << endl; … … 586 706 void ForceMagnitudePlotLine(ofstream &output, class MatrixContainer &Force, const char *prefix, const char *xargument, const char *uses) 587 707 { 588 stringstream line(Force.Header );708 stringstream line(Force.Header[Force.MatrixCounter]); 589 709 string token; 590 710 … … 594 714 getline(line, token, '\t'); 595 715 getline(line, token, '\t'); 596 for (int i=7; i< Force.ColumnCounter ;i+=NDIM) {716 for (int i=7; i< Force.ColumnCounter[Force.MatrixCounter];i+=NDIM) { 597 717 getline(line, token, '\t'); 598 718 while (token[0] == ' ') // remove leading white spaces … … 600 720 token.erase(token.length(), 1); // kill residual index char (the '0') 601 721 output << "'" << prefix << ".dat' title '" << token << "' using " << xargument << ":(sqrt($" << i+1 << "*$" << i+1 << "+$" << i+2 << "*$" << i+2 << "+$" << i+3 << "*$" << i+3 << ")) " << uses; 602 if (i != (Force.ColumnCounter -1))722 if (i != (Force.ColumnCounter[Force.MatrixCounter]-1)) 603 723 output << ", \\"; 604 724 output << endl; … … 617 737 void AbsFirstForceValuePlotLine(ofstream &output, class MatrixContainer &Force, const char *prefix, const char *xargument, const char *uses) 618 738 { 619 stringstream line(Force.Header );739 stringstream line(Force.Header[Force.MatrixCounter]); 620 740 string token; 621 741 … … 625 745 getline(line, token, '\t'); 626 746 getline(line, token, '\t'); 627 for (int i=7; i< Force.ColumnCounter ;i+=NDIM) {747 for (int i=7; i< Force.ColumnCounter[Force.MatrixCounter];i+=NDIM) { 628 748 getline(line, token, '\t'); 629 749 while (token[0] == ' ') // remove leading white spaces … … 631 751 token.erase(token.length(), 1); // kill residual index char (the '0') 632 752 output << "'" << prefix << ".dat' title '" << token << "' using " << xargument << ":(abs($" << i+1 << ")) " << uses; 633 if (i != (Force.ColumnCounter -1))753 if (i != (Force.ColumnCounter[Force.MatrixCounter]-1)) 634 754 output << ", \\"; 635 755 output << endl; … … 648 768 void BoxesForcePlotLine(ofstream &output, class MatrixContainer &Force, const char *prefix, const char *xargument, const char *uses) 649 769 { 650 stringstream line(Force.Header );651 c onst char *fillcolor[5] = {"black", "red", "blue", "green", "cyan"};770 stringstream line(Force.Header[Force.MatrixCounter]); 771 char *fillcolor[5] = {"black", "red", "blue", "green", "cyan"}; 652 772 string token; 653 773 … … 657 777 getline(line, token, '\t'); 658 778 getline(line, token, '\t'); 659 for (int i=7; i< Force.ColumnCounter ;i+=NDIM) {779 for (int i=7; i< Force.ColumnCounter[Force.MatrixCounter];i+=NDIM) { 660 780 getline(line, token, '\t'); 661 781 while (token[0] == ' ') // remove leading white spaces … … 663 783 token.erase(token.length(), 1); // kill residual index char (the '0') 664 784 output << "'" << prefix << ".dat' title '" << token << "' using ($" << xargument << "+" << fixed << setprecision(1) << (double)((i-7)/3)*0.2 << "):(sqrt($" << i+1 << "*$" << i+1 << "+$" << i+2 << "*$" << i+2 << "+$" << i+3 << "*$" << i+3 << ")) " << uses << " " << fillcolor[(i-7)/3]; 665 if (i != (Force.ColumnCounter -1))785 if (i != (Force.ColumnCounter[Force.MatrixCounter]-1)) 666 786 output << ", \\"; 667 787 output << endl; … … 680 800 void BoxesFirstForceValuePlotLine(ofstream &output, class MatrixContainer &Force, const char *prefix, const char *xargument, const char *uses) 681 801 { 682 stringstream line(Force.Header );683 c onst char *fillcolor[5] = {"black", "red", "blue", "green", "cyan"};802 stringstream line(Force.Header[Force.MatrixCounter]); 803 char *fillcolor[5] = {"black", "red", "blue", "green", "cyan"}; 684 804 string token; 685 805 … … 689 809 getline(line, token, '\t'); 690 810 getline(line, token, '\t'); 691 for (int i=7; i< Force.ColumnCounter ;i+=NDIM) {811 for (int i=7; i< Force.ColumnCounter[Force.MatrixCounter];i+=NDIM) { 692 812 getline(line, token, '\t'); 693 813 while (token[0] == ' ') // remove leading white spaces … … 695 815 token.erase(token.length(), 1); // kill residual index char (the '0') 696 816 output << "'" << prefix << ".dat' title '" << token << "' using ($" << xargument << "+" << fixed << setprecision(1) << (double)((i-7)/3)*0.2 << "):" << i+1 << " " << uses << " " << fillcolor[(i-7)/3]; 697 if (i != (Force.ColumnCounter -1))817 if (i != (Force.ColumnCounter[Force.MatrixCounter]-1)) 698 818 output << ", \\"; 699 819 output << endl; -
src/datacreator.hpp
r042f82 r36ec71 25 25 bool CreateDataForcesOrderPerAtom(class ForceMatrix &Fragments, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum); 26 26 bool CreateDataDeltaForcesOrder(class ForceMatrix &Force, class ForceMatrix &Fragments, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum, void (*CreateForce)(class MatrixContainer &, int)); 27 bool CreateDataDeltaForcesOrderPerAtom(class ForceMatrix &Force, class ForceMatrix &Fragments, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum); 27 bool CreateDataDeltaForcesOrderPerAtom(class ForceMatrix &Force, class ForceMatrix &Fragments, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum); 28 bool CreateDataHessianOrderPerAtom(class HessianMatrix &Fragments, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum); 29 bool CreateDataDeltaHessianOrderPerAtom(class HessianMatrix &Hessian, class HessianMatrix &Fragments, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum); 30 bool CreateDataDeltaFrobeniusOrderPerAtom(class HessianMatrix &Hessian, class HessianMatrix &Fragments, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum); 28 31 bool CreateDataFragment(class MatrixContainer &ForceFragments, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum, void (*CreateForce)(class MatrixContainer &, int)); 29 32 bool CreateDataFragmentOrder(class MatrixContainer &Fragment, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum, void (*CreateFragmentOrder)(class MatrixContainer &, class KeySetsContainer &, int)); -
src/defs.hpp
r042f82 r36ec71 16 16 #define BONDTHRESHOLD 0.5 //!< CSD threshold in bond check which is the width of the interval whose center is the sum of the covalent radii 17 17 #define AtomicEnergyToKelvin 315774.67 //!< conversion factor from atomic energy to kelvin via boltzmann factor 18 #define KelvinToAtomicTemperature 3.1668152e-06 //!< conversion factor for Kelvin to atomic temperature (Hartree over k_B) 19 #define KelvinToeV 8.6173422e-05 //!< conversion factor for Kelvin to Ht (k_B * T = energy), thus Boltzmann constant in eV/K 20 #define AtomicMassUnitsToeV 931494088. //!< conversion factor for atomic weight in units to mass in eV 21 #define AtomicMassUnitsToHt 34480864. //!< conversion factor for atomic weight in units to mass in Ht (protonmass/electronmass * electron_mass_in_Ht 22 #define ElectronMass_Ht 18778.865 //!< electron mass in Ht 23 #define ElectronMass_eV 510998.903 //!< electron mass in eV 24 #define Units2Electronmass (AtomicMassUnitsToeV/ElectronMass_eV) //!< atomic mass unit in eV/ electron mass in eV = 1 822.88863 25 #define Atomictime2Femtoseconds 0.024188843 //!< Atomictime in fs 26 18 27 #define VERSIONSTRING "v1.0" 19 28 -
src/graph.cpp
r042f82 r36ec71 7 7 using namespace std; 8 8 9 #include "graph.hpp" 9 10 10 #include <iostream> 11 #include <list> 12 #include <vector> 11 /***************************************** Implementations for graph classes ********************************/ 13 12 14 /***************************************** Functions for class graph ********************************/ 13 /** Constructor of class Graph. 14 */ 15 Graph::Graph() 16 { 17 }; 15 18 19 /** Destructor of class Graph. 20 * Destructor does release memory for nodes and edges contained in its lists as well. 21 */ 22 Graph::~Graph() 23 { 24 }; 16 25 26 /** Constructor of class SubGraph. 27 */ 28 SubGraph::SubGraph() 29 { 30 }; 31 32 /** Destructor of class SubGraph. 33 * Note that destructor does not deallocate either nodes or edges! (this is done by its subgraph!) 34 */ 35 SubGraph::~SubGraph() 36 { 37 }; 38 39 /** Constructor of class Node. 40 */ 41 Node::Node() 42 { 43 }; 44 45 /** Destructor of class Node. 46 */ 47 Node::~Node() 48 { 49 }; 50 51 /** Constructor of class Edge. 52 */ 53 Edge::Edge() 54 { 55 }; 56 57 /** Destructor of class Edge. 58 */ 59 Edge::~Edge() 60 { 61 }; 62 -
src/joiner.cpp
r042f82 r36ec71 19 19 periodentafel *periode = NULL; // and a period table of all elements 20 20 EnergyMatrix Energy; 21 EnergyMatrix EnergyFragments; 22 21 23 EnergyMatrix Hcorrection; 24 EnergyMatrix HcorrectionFragments; 25 22 26 ForceMatrix Force; 23 EnergyMatrix EnergyFragments;24 EnergyMatrix HcorrectionFragments;25 27 ForceMatrix ForceFragments; 28 29 HessianMatrix Hessian; 30 HessianMatrix HessianFragments; 31 26 32 ForceMatrix Shielding; 27 33 ForceMatrix ShieldingPAS; 28 34 ForceMatrix ShieldingFragments; 29 35 ForceMatrix ShieldingPASFragments; 30 KeySetsContainer KeySet; 36 ForceMatrix Chi; 37 ForceMatrix ChiPAS; 38 ForceMatrix ChiFragments; 39 ForceMatrix ChiPASFragments; 40 KeySetsContainer KeySet; 31 41 stringstream prefix; 32 42 char *dir = NULL; 33 bool Hcorrected = true; 43 bool NoHCorrection = false; 44 bool NoHessian = false; 34 45 35 46 cout << "Joiner" << endl; … … 61 72 // ------------- Parse through all Fragment subdirs -------- 62 73 if (!Energy.ParseFragmentMatrix(argv[1], dir, EnergySuffix, 0,0)) return 1; 63 Hcorrected = Hcorrection.ParseFragmentMatrix(argv[1], "", HCORRECTIONSUFFIX, 0,0); 74 if (!Hcorrection.ParseFragmentMatrix(argv[1], "", HCORRECTIONSUFFIX, 0,0)) { 75 NoHCorrection = true; 76 cout << "No HCorrection matrices found, skipping these." << endl; 77 } 64 78 if (!Force.ParseFragmentMatrix(argv[1], dir, ForcesSuffix, 0,0)) return 1; 79 if (!Hessian.ParseFragmentMatrix(argv[1], dir, HessianSuffix, 0,0)) { 80 NoHessian = true; 81 cout << "No hessian matrices found, skipping these." << endl; 82 } 65 83 if (periode != NULL) { // also look for PAS values 66 84 if (!Shielding.ParseFragmentMatrix(argv[1], dir, ShieldingSuffix, 1, 0)) return 1; 67 85 if (!ShieldingPAS.ParseFragmentMatrix(argv[1], dir, ShieldingPASSuffix, 1, 0)) return 1; 86 if (!Chi.ParseFragmentMatrix(argv[1], dir, ChiSuffix, 1, 0)) return 1; 87 if (!ChiPAS.ParseFragmentMatrix(argv[1], dir, ChiPASSuffix, 1, 0)) return 1; 68 88 } 69 89 70 90 // ---------- Parse the TE Factors into an array ----------------- 71 if (!Energy.ParseIndices()) return 1; 72 if (Hcorrected) Hcorrection.ParseIndices(); 73 91 if (!Energy.InitialiseIndices()) return 1; 92 if (!NoHCorrection) 93 Hcorrection.InitialiseIndices(); 94 74 95 // ---------- Parse the Force indices into an array --------------- 75 96 if (!Force.ParseIndices(argv[1])) return 1; 76 97 98 // ---------- Parse the Hessian (=force) indices into an array --------------- 99 if (!NoHessian) 100 if (!Hessian.InitialiseIndices((class MatrixContainer *)&Force)) return 1; 101 77 102 // ---------- Parse the shielding indices into an array --------------- 78 103 if (periode != NULL) { // also look for PAS values 79 104 if(!Shielding.ParseIndices(argv[1])) return 1; 80 105 if(!ShieldingPAS.ParseIndices(argv[1])) return 1; 106 if(!Chi.ParseIndices(argv[1])) return 1; 107 if(!ChiPAS.ParseIndices(argv[1])) return 1; 81 108 } 82 109 … … 85 112 86 113 if (!KeySet.ParseManyBodyTerms()) return 1; 114 87 115 if (!EnergyFragments.AllocateMatrix(Energy.Header, Energy.MatrixCounter, Energy.RowCounter, Energy.ColumnCounter)) return 1; 88 if (Hcorrected) HcorrectionFragments.AllocateMatrix(Hcorrection.Header, Hcorrection.MatrixCounter, Hcorrection.RowCounter, Hcorrection.ColumnCounter); 116 if (!NoHCorrection) 117 HcorrectionFragments.AllocateMatrix(Hcorrection.Header, Hcorrection.MatrixCounter, Hcorrection.RowCounter, Hcorrection.ColumnCounter); 89 118 if (!ForceFragments.AllocateMatrix(Force.Header, Force.MatrixCounter, Force.RowCounter, Force.ColumnCounter)) return 1; 119 if (!NoHessian) 120 if (!HessianFragments.AllocateMatrix(Hessian.Header, Hessian.MatrixCounter, Hessian.RowCounter, Hessian.ColumnCounter)) return 1; 90 121 if (periode != NULL) { // also look for PAS values 91 122 if (!ShieldingFragments.AllocateMatrix(Shielding.Header, Shielding.MatrixCounter, Shielding.RowCounter, Shielding.ColumnCounter)) return 1; 92 123 if (!ShieldingPASFragments.AllocateMatrix(ShieldingPAS.Header, ShieldingPAS.MatrixCounter, ShieldingPAS.RowCounter, ShieldingPAS.ColumnCounter)) return 1; 124 if (!ChiFragments.AllocateMatrix(Chi.Header, Chi.MatrixCounter, Chi.RowCounter, Chi.ColumnCounter)) return 1; 125 if (!ChiPASFragments.AllocateMatrix(ChiPAS.Header, ChiPAS.MatrixCounter, ChiPAS.RowCounter, ChiPAS.ColumnCounter)) return 1; 93 126 } 94 127 … … 96 129 if(!Energy.SetLastMatrix(0., 0)) return 1; 97 130 if(!Force.SetLastMatrix(0., 2)) return 1; 131 if (!NoHessian) 132 if (!Hessian.SetLastMatrix(0., 0)) return 1; 98 133 if (periode != NULL) { // also look for PAS values 99 134 if(!Shielding.SetLastMatrix(0., 2)) return 1; 100 135 if(!ShieldingPAS.SetLastMatrix(0., 2)) return 1; 136 if(!Chi.SetLastMatrix(0., 2)) return 1; 137 if(!ChiPAS.SetLastMatrix(0., 2)) return 1; 101 138 } 102 139 … … 108 145 cout << "Summing energy of order " << BondOrder+1 << " ..." << endl; 109 146 if (!EnergyFragments.SumSubManyBodyTerms(Energy, KeySet, BondOrder)) return 1; 110 if ( Hcorrected) {147 if (!NoHCorrection) { 111 148 HcorrectionFragments.SumSubManyBodyTerms(Hcorrection, KeySet, BondOrder); 112 149 if (!Energy.SumSubEnergy(EnergyFragments, &HcorrectionFragments, KeySet, BondOrder, 1.)) return 1; 113 if (Hcorrected)Hcorrection.SumSubEnergy(HcorrectionFragments, NULL, KeySet, BondOrder, 1.);114 } else 150 Hcorrection.SumSubEnergy(HcorrectionFragments, NULL, KeySet, BondOrder, 1.); 151 } else 115 152 if (!Energy.SumSubEnergy(EnergyFragments, NULL, KeySet, BondOrder, 1.)) return 1; 116 153 // --------- sum up Forces -------------------- … … 118 155 if (!ForceFragments.SumSubManyBodyTerms(Force, KeySet, BondOrder)) return 1; 119 156 if (!Force.SumSubForces(ForceFragments, KeySet, BondOrder, 1.)) return 1; 157 // --------- sum up Hessian -------------------- 158 if (!NoHessian) { 159 cout << "Summing Hessian of order " << BondOrder+1 << " ..." << endl; 160 if (!HessianFragments.SumSubManyBodyTerms(Hessian, KeySet, BondOrder)) return 1; 161 if (!Hessian.SumSubHessians(HessianFragments, KeySet, BondOrder, 1.)) return 1; 162 } 120 163 if (periode != NULL) { // also look for PAS values 121 cout << "Summing shieldings of order " << BondOrder+1 << " ..." << endl;164 cout << "Summing shieldings and susceptibilities of order " << BondOrder+1 << " ..." << endl; 122 165 if (!ShieldingFragments.SumSubManyBodyTerms(Shielding, KeySet, BondOrder)) return 1; 123 166 if (!Shielding.SumSubForces(ShieldingFragments, KeySet, BondOrder, 1.)) return 1; 124 167 if (!ShieldingPASFragments.SumSubManyBodyTerms(ShieldingPAS, KeySet, BondOrder)) return 1; 125 168 if (!ShieldingPAS.SumSubForces(ShieldingPASFragments, KeySet, BondOrder, 1.)) return 1; 169 if (!ChiFragments.SumSubManyBodyTerms(Chi, KeySet, BondOrder)) return 1; 170 if (!Chi.SumSubForces(ChiFragments, KeySet, BondOrder, 1.)) return 1; 171 if (!ChiPASFragments.SumSubManyBodyTerms(ChiPAS, KeySet, BondOrder)) return 1; 172 if (!ChiPAS.SumSubForces(ChiPASFragments, KeySet, BondOrder, 1.)) return 1; 126 173 } 127 174 … … 134 181 // forces 135 182 if (!Force.WriteLastMatrix(argv[1], (prefix.str()).c_str(), ForcesSuffix)) return 1; 183 // hessian 184 if (!NoHessian) 185 if (!Hessian.WriteLastMatrix(argv[1], (prefix.str()).c_str(), HessianSuffix)) return 1; 136 186 // shieldings 137 187 if (periode != NULL) { // also look for PAS values 138 188 if (!Shielding.WriteLastMatrix(argv[1], (prefix.str()).c_str(), ShieldingSuffix)) return 1; 139 189 if (!ShieldingPAS.WriteLastMatrix(argv[1], (prefix.str()).c_str(), ShieldingPASSuffix)) return 1; 190 if (!Chi.WriteLastMatrix(argv[1], (prefix.str()).c_str(), ChiSuffix)) return 1; 191 if (!ChiPAS.WriteLastMatrix(argv[1], (prefix.str()).c_str(), ChiPASSuffix)) return 1; 140 192 } 141 193 } … … 144 196 prefix << dir << EnergyFragmentSuffix; 145 197 if (!EnergyFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1; 146 if ( Hcorrected) {198 if (!NoHCorrection) { 147 199 prefix.str(" "); 148 200 prefix << dir << HcorrectionFragmentSuffix; … … 153 205 if (!ForceFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1; 154 206 if (!CreateDataFragment(EnergyFragments, KeySet, argv[1], FRAGMENTPREFIX ENERGYPERFRAGMENT, "fragment energy versus the Fragment No", "today", CreateEnergy)) return 1; 207 if (!NoHessian) { 208 prefix.str(" "); 209 prefix << dir << HessianFragmentSuffix; 210 if (!HessianFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1; 211 } 155 212 if (periode != NULL) { // also look for PAS values 156 213 prefix.str(" "); … … 160 217 prefix << dir << ShieldingPASFragmentSuffix; 161 218 if (!ShieldingPASFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1; 219 prefix.str(" "); 220 prefix << dir << ChiFragmentSuffix; 221 if (!ChiFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1; 222 prefix.str(" "); 223 prefix << dir << ChiPASFragmentSuffix; 224 if (!ChiPASFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1; 162 225 } 163 226 164 227 // write last matrices as fragments into central dir (not subdir as above), for analyzer to know index bounds 165 228 if (!Energy.WriteLastMatrix(argv[1], dir, EnergyFragmentSuffix)) return 1; 166 if ( Hcorrected) Hcorrection.WriteLastMatrix(argv[1], dir, HcorrectionFragmentSuffix);229 if (!NoHCorrection) Hcorrection.WriteLastMatrix(argv[1], dir, HcorrectionFragmentSuffix); 167 230 if (!Force.WriteLastMatrix(argv[1], dir, ForceFragmentSuffix)) return 1; 231 if (!NoHessian) 232 if (!Hessian.WriteLastMatrix(argv[1], dir, HessianFragmentSuffix)) return 1; 168 233 if (periode != NULL) { // also look for PAS values 169 234 if (!Shielding.WriteLastMatrix(argv[1], dir, ShieldingFragmentSuffix)) return 1; 170 235 if (!ShieldingPAS.WriteLastMatrix(argv[1], dir, ShieldingPASFragmentSuffix)) return 1; 236 if (!Chi.WriteLastMatrix(argv[1], dir, ChiFragmentSuffix)) return 1; 237 if (!ChiPAS.WriteLastMatrix(argv[1], dir, ChiPASFragmentSuffix)) return 1; 171 238 } 172 239 -
src/moleculelist.cpp
r042f82 r36ec71 35 35 * \return true - add successful 36 36 */ 37 boolMoleculeListClass::insert(molecule *mol)37 void MoleculeListClass::insert(molecule *mol) 38 38 { 39 39 mol->IndexNr = MaxIndex++; 40 40 ListOfMolecules.push_back(mol); 41 return true;42 41 }; 43 42 … … 128 127 atom *Walker = NULL; 129 128 int Counts[MAX_ELEMENTS]; 129 double size=0; 130 Vector Origin; 130 131 131 132 // header 132 *out << "Index\tName\t No.Atoms\tformula" << endl;133 *out << "Index\tName\t\tAtoms\tFormula\tCenter\tSize" << endl; 133 134 cout << Verbose(0) << "-----------------------------------------------" << endl; 134 135 if (ListOfMolecules.size() == 0) 135 136 *out << "\tNone" << endl; 136 137 else { 138 Origin.Zero(); 137 139 for (MoleculeList::iterator ListRunner = ListOfMolecules.begin(); ListRunner != ListOfMolecules.end(); ListRunner++) { 138 140 // reset element counts 139 141 for (int j = 0; j<MAX_ELEMENTS;j++) 140 142 Counts[j] = 0; 141 // count atoms per element 143 // count atoms per element and determine size of bounding sphere 144 size=0.; 142 145 Walker = (*ListRunner)->start; 143 146 while (Walker->next != (*ListRunner)->end) { 144 147 Walker = Walker->next; 145 148 Counts[Walker->type->Z]++; 149 if (Walker->x.DistanceSquared(&Origin) > size) 150 size = Walker->x.DistanceSquared(&Origin); 146 151 } 147 152 // output Index, Name, number of atoms, chemical formula 148 153 *out << ((*ListRunner)->ActiveFlag ? "*" : " ") << (*ListRunner)->IndexNr << "\t" << (*ListRunner)->name << "\t\t" << (*ListRunner)->AtomCount << "\t"; 149 154 Elemental = (*ListRunner)->elemente->end; 150 while(Elemental != (*ListRunner)->elemente->start) {155 while(Elemental->previous != (*ListRunner)->elemente->start) { 151 156 Elemental = Elemental->previous; 152 157 if (Counts[Elemental->Z] != 0) 153 158 *out << Elemental->symbol << Counts[Elemental->Z]; 154 159 } 155 *out << endl; 160 // Center and size 161 *out << "\t" << (*ListRunner)->Center << "\t" << sqrt(size) << endl; 156 162 } 157 163 } … … 164 170 molecule * MoleculeListClass::ReturnIndex(int index) 165 171 { 166 int count = 1; 167 MoleculeList::iterator ListRunner = ListOfMolecules.begin(); 168 for(; ((ListRunner != ListOfMolecules.end()) && (count < index)); ListRunner++); 169 if (count == index) 170 return (*ListRunner); 171 else 172 return NULL; 172 for(MoleculeList::iterator ListRunner = ListOfMolecules.begin(); ListRunner != ListOfMolecules.end(); ListRunner++) 173 if ((*ListRunner)->IndexNr == index) 174 return (*ListRunner); 175 return NULL; 173 176 }; 174 177 … … 565 568 * \param *configuration standard configuration to attach atoms in fragment molecule to. 566 569 * \param *SortIndex Index to map from the BFS labeling to the sequence how of Ion_Type in the config 570 * \param DoPeriodic true - call ScanForPeriodicCorrection, false - don't 571 * \param DoCentering true - call molecule::CenterEdge(), false - don't 567 572 * \return true - success (each file was written), false - something went wrong. 568 573 */ 569 bool MoleculeListClass::OutputConfigForListOfFragments(ofstream *out, 570 config *configuration, int *SortIndex) 574 bool MoleculeListClass::OutputConfigForListOfFragments(ofstream *out, config *configuration, int *SortIndex) 571 575 { 572 576 ofstream outputFragment; -
src/molecules.cpp
r042f82 r36ec71 63 63 cell_size[1] = cell_size[3] = cell_size[4]= 0.; 64 64 strcpy(name,"none"); 65 IndexNr = -1; 66 ActiveFlag = false; 65 67 }; 66 68 … … 602 604 * \param *filename filename 603 605 */ 604 void molecule::SetNameFromFilename(c har *filename)606 void molecule::SetNameFromFilename(const char *filename) 605 607 { 606 608 int length = 0; 607 609 char *molname = strrchr(filename, '/')+sizeof(char); // search for filename without dirs 608 char *endname = str rchr(filename, '.');610 char *endname = strchr(molname, '.'); 609 611 if ((endname == NULL) || (endname < molname)) 610 612 length = strlen(molname); … … 612 614 length = strlen(molname) - strlen(endname); 613 615 strncpy(name, molname, length); 616 name[length]='\0'; 614 617 }; 615 618 … … 669 672 } 670 673 } 671 // matrix multiply672 x.MatrixMultiplication(M);673 ptr->x.CopyVector(&x);674 674 } 675 675 } … … 710 710 max->AddVector(min); 711 711 Translate(min); 712 Center.Zero(); 712 713 } 713 714 delete(min); … … 719 720 * \param *center return vector for translation vector 720 721 */ 721 void molecule::CenterOrigin(ofstream *out , Vector *center)722 void molecule::CenterOrigin(ofstream *out) 722 723 { 723 724 int Num = 0; 724 725 atom *ptr = start->next; // start at first in list 725 726 726 for(int i=NDIM;i--;) // zero center vector 727 center->x[i] = 0.; 727 Center.Zero(); 728 728 729 729 if (ptr != end) { //list not empty? … … 731 731 ptr = ptr->next; 732 732 Num++; 733 center->AddVector(&ptr->x); 734 } 735 center->Scale(-1./Num); // divide through total number (and sign for direction) 736 Translate(center); 733 Center.AddVector(&ptr->x); 734 } 735 Center.Scale(-1./Num); // divide through total number (and sign for direction) 736 Translate(&Center); 737 Center.Zero(); 737 738 } 738 739 }; … … 799 800 * \param *center return vector for translation vector 800 801 */ 801 void molecule::CenterGravity(ofstream *out, Vector *center) 802 { 803 if (center == NULL) { 804 DetermineCenter(*center); 805 Translate(center); 806 delete(center); 807 } else { 808 Translate(center); 809 } 810 }; 802 void molecule::CenterPeriodic(ofstream *out) 803 { 804 DeterminePeriodicCenter(Center); 805 }; 806 807 808 /** Centers the center of gravity of the atoms at (0,0,0). 809 * \param *out output stream for debugging 810 * \param *center return vector for translation vector 811 */ 812 void molecule::CenterAtVector(ofstream *out, Vector *newcenter) 813 { 814 Center.CopyVector(newcenter); 815 }; 816 811 817 812 818 /** Scales all atoms by \a *factor. … … 911 917 912 918 /** Determines center of molecule (yet not considering atom masses). 913 * \param Center reference to return vector914 */ 915 void molecule::Determine Center(Vector &Center)919 * \param center reference to return vector 920 */ 921 void molecule::DeterminePeriodicCenter(Vector ¢er) 916 922 { 917 923 atom *Walker = start; … … 987 993 Vector *CenterOfGravity = DetermineCenterOfGravity(out); 988 994 989 Center Gravity(out, CenterOfGravity);995 CenterPeriodic(out); 990 996 991 997 // reset inertia tensor … … 1083 1089 }; 1084 1090 1091 /** Evaluates the potential energy used for constrained molecular dynamics. 1092 * \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$ 1093 * 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 1094 * trajectories i and j) and the third term is a penalty for two atoms trying to each the same target point. 1095 * Note that for the second term we have to solve the following linear system: 1096 * \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, 1097 * offset vector \f$p_1\f$ in direction \f$n_1\f$, offset vector \f$p_2\f$ in direction \f$n_2\f$, 1098 * \f$n_3\f$ is the normal vector to both directions. \f$C\f$ would be the minimum distance between the two lines. 1099 * \sa molecule::MinimiseConstrainedPotential(), molecule::VerletForceIntegration() 1100 * \param *out output stream for debugging 1101 * \param *PermutationMap gives target ptr for each atom, array of size molecule::AtomCount (this is "x" in \f$ V^{con}(x) \f$ ) 1102 * \param startstep start configuration (MDStep in molecule::trajectories) 1103 * \param endstep end configuration (MDStep in molecule::trajectories) 1104 * \param *constants constant in front of each term 1105 * \param IsAngstroem whether coordinates are in angstroem (true) or bohrradius (false) 1106 * \return potential energy 1107 * \note This routine is scaling quadratically which is not optimal. 1108 * \todo There's a bit double counting going on for the first time, bu nothing to worry really about. 1109 */ 1110 double molecule::ConstrainedPotential(ofstream *out, atom **PermutationMap, int startstep, int endstep, double *constants, bool IsAngstroem) 1111 { 1112 double result = 0., tmp, Norm1, Norm2; 1113 atom *Walker = NULL, *Runner = NULL, *Sprinter = NULL; 1114 Vector trajectory1, trajectory2, normal, TestVector; 1115 gsl_matrix *A = gsl_matrix_alloc(NDIM,NDIM); 1116 gsl_vector *x = gsl_vector_alloc(NDIM); 1117 1118 // go through every atom 1119 Walker = start; 1120 while (Walker->next != end) { 1121 Walker = Walker->next; 1122 // first term: distance to target 1123 Runner = PermutationMap[Walker->nr]; // find target point 1124 tmp = (Trajectories[Walker].R.at(startstep).Distance(&Trajectories[Runner].R.at(endstep))); 1125 tmp *= IsAngstroem ? 1. : 1./AtomicLengthToAngstroem; 1126 result += constants[0] * tmp; 1127 //*out << Verbose(4) << "Adding " << tmp*constants[0] << "." << endl; 1128 1129 // second term: sum of distances to other trajectories 1130 Runner = start; 1131 while (Runner->next != end) { 1132 Runner = Runner->next; 1133 if (Runner == Walker) // hence, we only go up to the Walker, not beyond (similar to i=0; i<j; i++) 1134 break; 1135 // determine normalized trajectories direction vector (n1, n2) 1136 Sprinter = PermutationMap[Walker->nr]; // find first target point 1137 trajectory1.CopyVector(&Trajectories[Sprinter].R.at(endstep)); 1138 trajectory1.SubtractVector(&Trajectories[Walker].R.at(startstep)); 1139 trajectory1.Normalize(); 1140 Norm1 = trajectory1.Norm(); 1141 Sprinter = PermutationMap[Runner->nr]; // find second target point 1142 trajectory2.CopyVector(&Trajectories[Sprinter].R.at(endstep)); 1143 trajectory2.SubtractVector(&Trajectories[Runner].R.at(startstep)); 1144 trajectory2.Normalize(); 1145 Norm2 = trajectory1.Norm(); 1146 // check whether either is zero() 1147 if ((Norm1 < MYEPSILON) && (Norm2 < MYEPSILON)) { 1148 tmp = Trajectories[Walker].R.at(startstep).Distance(&Trajectories[Runner].R.at(startstep)); 1149 } else if (Norm1 < MYEPSILON) { 1150 Sprinter = PermutationMap[Walker->nr]; // find first target point 1151 trajectory1.CopyVector(&Trajectories[Sprinter].R.at(endstep)); // copy first offset 1152 trajectory1.SubtractVector(&Trajectories[Runner].R.at(startstep)); // subtract second offset 1153 trajectory2.Scale( trajectory1.ScalarProduct(&trajectory2) ); // trajectory2 is scaled to unity, hence we don't need to divide by anything 1154 trajectory1.SubtractVector(&trajectory2); // project the part in norm direction away 1155 tmp = trajectory1.Norm(); // remaining norm is distance 1156 } else if (Norm2 < MYEPSILON) { 1157 Sprinter = PermutationMap[Runner->nr]; // find second target point 1158 trajectory2.CopyVector(&Trajectories[Sprinter].R.at(endstep)); // copy second offset 1159 trajectory2.SubtractVector(&Trajectories[Walker].R.at(startstep)); // subtract first offset 1160 trajectory1.Scale( trajectory2.ScalarProduct(&trajectory1) ); // trajectory1 is scaled to unity, hence we don't need to divide by anything 1161 trajectory2.SubtractVector(&trajectory1); // project the part in norm direction away 1162 tmp = trajectory2.Norm(); // remaining norm is distance 1163 } else if ((fabs(trajectory1.ScalarProduct(&trajectory2)/Norm1/Norm2) - 1.) < MYEPSILON) { // check whether they're linear dependent 1164 // *out << Verbose(3) << "Both trajectories of " << *Walker << " and " << *Runner << " are linear dependent: "; 1165 // *out << trajectory1; 1166 // *out << " and "; 1167 // *out << trajectory2; 1168 tmp = Trajectories[Walker].R.at(startstep).Distance(&Trajectories[Runner].R.at(startstep)); 1169 // *out << " with distance " << tmp << "." << endl; 1170 } else { // determine distance by finding minimum distance 1171 // *out << Verbose(3) << "Both trajectories of " << *Walker << " and " << *Runner << " are linear independent "; 1172 // *out << endl; 1173 // *out << "First Trajectory: "; 1174 // *out << trajectory1 << endl; 1175 // *out << "Second Trajectory: "; 1176 // *out << trajectory2 << endl; 1177 // determine normal vector for both 1178 normal.MakeNormalVector(&trajectory1, &trajectory2); 1179 // print all vectors for debugging 1180 // *out << "Normal vector in between: "; 1181 // *out << normal << endl; 1182 // setup matrix 1183 for (int i=NDIM;i--;) { 1184 gsl_matrix_set(A, 0, i, trajectory1.x[i]); 1185 gsl_matrix_set(A, 1, i, trajectory2.x[i]); 1186 gsl_matrix_set(A, 2, i, normal.x[i]); 1187 gsl_vector_set(x,i, (Trajectories[Walker].R.at(startstep).x[i] - Trajectories[Runner].R.at(startstep).x[i])); 1188 } 1189 // solve the linear system by Householder transformations 1190 gsl_linalg_HH_svx(A, x); 1191 // distance from last component 1192 tmp = gsl_vector_get(x,2); 1193 // *out << " with distance " << tmp << "." << endl; 1194 // test whether we really have the intersection (by checking on c_1 and c_2) 1195 TestVector.CopyVector(&Trajectories[Runner].R.at(startstep)); 1196 trajectory2.Scale(gsl_vector_get(x,1)); 1197 TestVector.AddVector(&trajectory2); 1198 normal.Scale(gsl_vector_get(x,2)); 1199 TestVector.AddVector(&normal); 1200 TestVector.SubtractVector(&Trajectories[Walker].R.at(startstep)); 1201 trajectory1.Scale(gsl_vector_get(x,0)); 1202 TestVector.SubtractVector(&trajectory1); 1203 if (TestVector.Norm() < MYEPSILON) { 1204 // *out << Verbose(2) << "Test: ok.\tDistance of " << tmp << " is correct." << endl; 1205 } else { 1206 // *out << Verbose(2) << "Test: failed.\tIntersection is off by "; 1207 // *out << TestVector; 1208 // *out << "." << endl; 1209 } 1210 } 1211 // add up 1212 tmp *= IsAngstroem ? 1. : 1./AtomicLengthToAngstroem; 1213 if (fabs(tmp) > MYEPSILON) { 1214 result += constants[1] * 1./tmp; 1215 //*out << Verbose(4) << "Adding " << 1./tmp*constants[1] << "." << endl; 1216 } 1217 } 1218 1219 // third term: penalty for equal targets 1220 Runner = start; 1221 while (Runner->next != end) { 1222 Runner = Runner->next; 1223 if ((PermutationMap[Walker->nr] == PermutationMap[Runner->nr]) && (Walker->nr < Runner->nr)) { 1224 Sprinter = PermutationMap[Walker->nr]; 1225 // *out << *Walker << " and " << *Runner << " are heading to the same target at "; 1226 // *out << Trajectories[Sprinter].R.at(endstep); 1227 // *out << ", penalting." << endl; 1228 result += constants[2]; 1229 //*out << Verbose(4) << "Adding " << constants[2] << "." << endl; 1230 } 1231 } 1232 } 1233 1234 return result; 1235 }; 1236 1237 void PrintPermutationMap(ofstream *out, atom **PermutationMap, int Nr) 1238 { 1239 stringstream zeile1, zeile2; 1240 int *DoubleList = (int *) Malloc(Nr*sizeof(int), "PrintPermutationMap: *DoubleList"); 1241 int doubles = 0; 1242 for (int i=0;i<Nr;i++) 1243 DoubleList[i] = 0; 1244 zeile1 << "PermutationMap: "; 1245 zeile2 << " "; 1246 for (int i=0;i<Nr;i++) { 1247 DoubleList[PermutationMap[i]->nr]++; 1248 zeile1 << i << " "; 1249 zeile2 << PermutationMap[i]->nr << " "; 1250 } 1251 for (int i=0;i<Nr;i++) 1252 if (DoubleList[i] > 1) 1253 doubles++; 1254 // *out << "Found " << doubles << " Doubles." << endl; 1255 Free((void **)&DoubleList, "PrintPermutationMap: *DoubleList"); 1256 // *out << zeile1.str() << endl << zeile2.str() << endl; 1257 }; 1258 1259 /** Minimises the extra potential for constrained molecular dynamics and gives forces and the constrained potential energy. 1260 * We do the following: 1261 * -# Generate a distance list from all source to all target points 1262 * -# Sort this per source point 1263 * -# Take for each source point the target point with minimum distance, use this as initial permutation 1264 * -# check whether molecule::ConstrainedPotential() is greater than injective penalty 1265 * -# If so, we go through each source point, stepping down in the sorted target point distance list and re-checking potential. 1266 * -# Next, we only apply transformations that keep the injectivity of the permutations list. 1267 * -# Hence, for one source point we step down the ladder and seek the corresponding owner of this new target 1268 * point and try to change it for one with lesser distance, or for the next one with greater distance, but only 1269 * if this decreases the conditional potential. 1270 * -# finished. 1271 * -# Then, we calculate the forces by taking the spatial derivative, where we scale the potential to such a degree, 1272 * that the total force is always pointing in direction of the constraint force (ensuring that we move in the 1273 * right direction). 1274 * -# Finally, we calculate the potential energy and return. 1275 * \param *out output stream for debugging 1276 * \param **PermutationMap on return: mapping between the atom label of the initial and the final configuration 1277 * \param startstep current MD step giving initial position between which and \a endstep we perform the constrained MD (as further steps are always concatenated) 1278 * \param endstep step giving final position in constrained MD 1279 * \param IsAngstroem whether coordinates are in angstroem (true) or bohrradius (false) 1280 * \sa molecule::VerletForceIntegration() 1281 * \return potential energy (and allocated **PermutationMap (array of molecule::AtomCount ^2) 1282 * \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 1283 * to ensure they're properties (e.g. constants[2] always greater than the energy of the system). 1284 * \bug this all is not O(N log N) but O(N^2) 1285 */ 1286 double molecule::MinimiseConstrainedPotential(ofstream *out, atom **&PermutationMap, int startstep, int endstep, bool IsAngstroem) 1287 { 1288 double Potential, OldPotential, OlderPotential; 1289 PermutationMap = (atom **) Malloc(AtomCount*sizeof(atom *), "molecule::MinimiseConstrainedPotential: **PermutationMap"); 1290 DistanceMap **DistanceList = (DistanceMap **) Malloc(AtomCount*sizeof(DistanceMap *), "molecule::MinimiseConstrainedPotential: **DistanceList"); 1291 DistanceMap::iterator *DistanceIterators = (DistanceMap::iterator *) Malloc(AtomCount*sizeof(DistanceMap::iterator), "molecule::MinimiseConstrainedPotential: *DistanceIterators"); 1292 int *DoubleList = (int *) Malloc(AtomCount*sizeof(int), "molecule::MinimiseConstrainedPotential: *DoubleList"); 1293 DistanceMap::iterator *StepList = (DistanceMap::iterator *) Malloc(AtomCount*sizeof(DistanceMap::iterator), "molecule::MinimiseConstrainedPotential: *StepList"); 1294 double constants[3]; 1295 int round; 1296 atom *Walker = NULL, *Runner = NULL, *Sprinter = NULL; 1297 DistanceMap::iterator Rider, Strider; 1298 1299 /// Minimise the potential 1300 // set Lagrange multiplier constants 1301 constants[0] = 10.; 1302 constants[1] = 1.; 1303 constants[2] = 1e+7; // just a huge penalty 1304 // generate the distance list 1305 *out << Verbose(1) << "Creating the distance list ... " << endl; 1306 for (int i=AtomCount; i--;) { 1307 DoubleList[i] = 0; // stores for how many atoms in startstep this atom is a target in endstep 1308 DistanceList[i] = new DistanceMap; // is the distance sorted target list per atom 1309 DistanceList[i]->clear(); 1310 } 1311 *out << Verbose(1) << "Filling the distance list ... " << endl; 1312 Walker = start; 1313 while (Walker->next != end) { 1314 Walker = Walker->next; 1315 Runner = start; 1316 while(Runner->next != end) { 1317 Runner = Runner->next; 1318 DistanceList[Walker->nr]->insert( DistancePair(Trajectories[Walker].R.at(startstep).Distance(&Trajectories[Runner].R.at(endstep)), Runner) ); 1319 } 1320 } 1321 // create the initial PermutationMap (source -> target) 1322 Walker = start; 1323 while (Walker->next != end) { 1324 Walker = Walker->next; 1325 StepList[Walker->nr] = DistanceList[Walker->nr]->begin(); // stores the step to the next iterator that could be a possible next target 1326 PermutationMap[Walker->nr] = DistanceList[Walker->nr]->begin()->second; // always pick target with the smallest distance 1327 DoubleList[DistanceList[Walker->nr]->begin()->second->nr]++; // increase this target's source count (>1? not injective) 1328 DistanceIterators[Walker->nr] = DistanceList[Walker->nr]->begin(); // and remember which one we picked 1329 *out << *Walker << " starts with distance " << DistanceList[Walker->nr]->begin()->first << "." << endl; 1330 } 1331 *out << Verbose(1) << "done." << endl; 1332 // make the PermutationMap injective by checking whether we have a non-zero constants[2] term in it 1333 *out << Verbose(1) << "Making the PermutationMap injective ... " << endl; 1334 Walker = start; 1335 DistanceMap::iterator NewBase; 1336 OldPotential = fabs(ConstrainedPotential(out, PermutationMap, startstep, endstep, constants, IsAngstroem)); 1337 while ((OldPotential) > constants[2]) { 1338 PrintPermutationMap(out, PermutationMap, AtomCount); 1339 Walker = Walker->next; 1340 if (Walker == end) // round-robin at the end 1341 Walker = start->next; 1342 if (DoubleList[DistanceIterators[Walker->nr]->second->nr] <= 1) // no need to make those injective that aren't 1343 continue; 1344 // now, try finding a new one 1345 NewBase = DistanceIterators[Walker->nr]; // store old base 1346 do { 1347 NewBase++; // take next further distance in distance to targets list that's a target of no one 1348 } while ((DoubleList[NewBase->second->nr] != 0) && (NewBase != DistanceList[Walker->nr]->end())); 1349 if (NewBase != DistanceList[Walker->nr]->end()) { 1350 PermutationMap[Walker->nr] = NewBase->second; 1351 Potential = fabs(ConstrainedPotential(out, PermutationMap, startstep, endstep, constants, IsAngstroem)); 1352 if (Potential > OldPotential) { // undo 1353 PermutationMap[Walker->nr] = DistanceIterators[Walker->nr]->second; 1354 } else { // do 1355 DoubleList[DistanceIterators[Walker->nr]->second->nr]--; // decrease the old entry in the doubles list 1356 DoubleList[NewBase->second->nr]++; // increase the old entry in the doubles list 1357 DistanceIterators[Walker->nr] = NewBase; 1358 OldPotential = Potential; 1359 *out << Verbose(3) << "Found a new permutation, new potential is " << OldPotential << "." << endl; 1360 } 1361 } 1362 } 1363 for (int i=AtomCount; i--;) // now each single entry in the DoubleList should be <=1 1364 if (DoubleList[i] > 1) { 1365 cerr << "Failed to create an injective PermutationMap!" << endl; 1366 exit(1); 1367 } 1368 *out << Verbose(1) << "done." << endl; 1369 Free((void **)&DoubleList, "molecule::MinimiseConstrainedPotential: *DoubleList"); 1370 // argument minimise the constrained potential in this injective PermutationMap 1371 *out << Verbose(1) << "Argument minimising the PermutationMap, at current potential " << OldPotential << " ... " << endl; 1372 OldPotential = 1e+10; 1373 round = 0; 1374 do { 1375 *out << "Starting round " << ++round << " ... " << endl; 1376 OlderPotential = OldPotential; 1377 do { 1378 Walker = start; 1379 while (Walker->next != end) { // pick one 1380 Walker = Walker->next; 1381 PrintPermutationMap(out, PermutationMap, AtomCount); 1382 Sprinter = DistanceIterators[Walker->nr]->second; // store initial partner 1383 Strider = DistanceIterators[Walker->nr]; //remember old iterator 1384 DistanceIterators[Walker->nr] = StepList[Walker->nr]; 1385 if (DistanceIterators[Walker->nr] == DistanceList[Walker->nr]->end()) {// stop, before we run through the list and still on 1386 DistanceIterators[Walker->nr] == DistanceList[Walker->nr]->begin(); 1387 break; 1388 } 1389 //*out << Verbose(2) << "Current Walker: " << *Walker << " with old/next candidate " << *Sprinter << "/" << *DistanceIterators[Walker->nr]->second << "." << endl; 1390 // find source of the new target 1391 Runner = start->next; 1392 while(Runner != end) { // find the source whose toes we might be stepping on (Walker's new target should be in use by another already) 1393 if (PermutationMap[Runner->nr] == DistanceIterators[Walker->nr]->second) { 1394 //*out << Verbose(2) << "Found the corresponding owner " << *Runner << " to " << *PermutationMap[Runner->nr] << "." << endl; 1395 break; 1396 } 1397 Runner = Runner->next; 1398 } 1399 if (Runner != end) { // we found the other source 1400 // then look in its distance list for Sprinter 1401 Rider = DistanceList[Runner->nr]->begin(); 1402 for (; Rider != DistanceList[Runner->nr]->end(); Rider++) 1403 if (Rider->second == Sprinter) 1404 break; 1405 if (Rider != DistanceList[Runner->nr]->end()) { // if we have found one 1406 //*out << Verbose(2) << "Current Other: " << *Runner << " with old/next candidate " << *PermutationMap[Runner->nr] << "/" << *Rider->second << "." << endl; 1407 // exchange both 1408 PermutationMap[Walker->nr] = DistanceIterators[Walker->nr]->second; // put next farther distance into PermutationMap 1409 PermutationMap[Runner->nr] = Sprinter; // and hand the old target to its respective owner 1410 PrintPermutationMap(out, PermutationMap, AtomCount); 1411 // calculate the new potential 1412 //*out << Verbose(2) << "Checking new potential ..." << endl; 1413 Potential = ConstrainedPotential(out, PermutationMap, startstep, endstep, constants, IsAngstroem); 1414 if (Potential > OldPotential) { // we made everything worse! Undo ... 1415 //*out << Verbose(3) << "Nay, made the potential worse: " << Potential << " vs. " << OldPotential << "!" << endl; 1416 //*out << Verbose(3) << "Setting " << *Runner << "'s source to " << *DistanceIterators[Runner->nr]->second << "." << endl; 1417 // Undo for Runner (note, we haven't moved the iteration yet, we may use this) 1418 PermutationMap[Runner->nr] = DistanceIterators[Runner->nr]->second; 1419 // Undo for Walker 1420 DistanceIterators[Walker->nr] = Strider; // take next farther distance target 1421 //*out << Verbose(3) << "Setting " << *Walker << "'s source to " << *DistanceIterators[Walker->nr]->second << "." << endl; 1422 PermutationMap[Walker->nr] = DistanceIterators[Walker->nr]->second; 1423 } else { 1424 DistanceIterators[Runner->nr] = Rider; // if successful also move the pointer in the iterator list 1425 *out << Verbose(3) << "Found a better permutation, new potential is " << Potential << " vs." << OldPotential << "." << endl; 1426 OldPotential = Potential; 1427 } 1428 if (Potential > constants[2]) { 1429 cerr << "ERROR: The two-step permutation procedure did not maintain injectivity!" << endl; 1430 exit(255); 1431 } 1432 //*out << endl; 1433 } else { 1434 cerr << "ERROR: " << *Runner << " was not the owner of " << *Sprinter << "!" << endl; 1435 exit(255); 1436 } 1437 } else { 1438 PermutationMap[Walker->nr] = DistanceIterators[Walker->nr]->second; // new target has no source! 1439 } 1440 StepList[Walker->nr]++; // take next farther distance target 1441 } 1442 } while (Walker->next != end); 1443 } while ((OlderPotential - OldPotential) > 1e-3); 1444 *out << Verbose(1) << "done." << endl; 1445 1446 1447 /// free memory and return with evaluated potential 1448 for (int i=AtomCount; i--;) 1449 DistanceList[i]->clear(); 1450 Free((void **)&DistanceList, "molecule::MinimiseConstrainedPotential: **DistanceList"); 1451 Free((void **)&DistanceIterators, "molecule::MinimiseConstrainedPotential: *DistanceIterators"); 1452 return ConstrainedPotential(out, PermutationMap, startstep, endstep, constants, IsAngstroem); 1453 }; 1454 1455 /** Evaluates the (distance-related part) of the constrained potential for the constrained forces. 1456 * \param *out output stream for debugging 1457 * \param startstep current MD step giving initial position between which and \a endstep we perform the constrained MD (as further steps are always concatenated) 1458 * \param endstep step giving final position in constrained MD 1459 * \param **PermutationMap mapping between the atom label of the initial and the final configuration 1460 * \param *Force ForceMatrix containing force vectors from the external energy functional minimisation. 1461 * \todo the constant for the constrained potential distance part is hard-coded independently of the hard-coded value in MinimiseConstrainedPotential() 1462 */ 1463 void molecule::EvaluateConstrainedForces(ofstream *out, int startstep, int endstep, atom **PermutationMap, ForceMatrix *Force) 1464 { 1465 double constant = 10.; 1466 atom *Walker = NULL, *Sprinter = NULL; 1467 1468 /// evaluate forces (only the distance to target dependent part) with the final PermutationMap 1469 *out << Verbose(1) << "Calculating forces and adding onto ForceMatrix ... " << endl; 1470 Walker = start; 1471 while (Walker->next != NULL) { 1472 Walker = Walker->next; 1473 Sprinter = PermutationMap[Walker->nr]; 1474 // set forces 1475 for (int i=NDIM;i++;) 1476 Force->Matrix[0][Walker->nr][5+i] += 2.*constant*sqrt(Trajectories[Walker].R.at(startstep).Distance(&Trajectories[Sprinter].R.at(endstep))); 1477 } 1478 *out << Verbose(1) << "done." << endl; 1479 }; 1480 1481 /** Performs a linear interpolation between two desired atomic configurations with a given number of steps. 1482 * Note, step number is config::MaxOuterStep 1483 * \param *out output stream for debugging 1484 * \param startstep stating initial configuration in molecule::Trajectories 1485 * \param endstep stating final configuration in molecule::Trajectories 1486 * \param &config configuration structure 1487 * \return true - success in writing step files, false - error writing files or only one step in molecule::Trajectories 1488 */ 1489 bool molecule::LinearInterpolationBetweenConfiguration(ofstream *out, int startstep, int endstep, const char *prefix, config &configuration) 1490 { 1491 molecule *mol = NULL; 1492 bool status = true; 1493 int MaxSteps = configuration.MaxOuterStep; 1494 MoleculeListClass *MoleculePerStep = new MoleculeListClass(); 1495 // Get the Permutation Map by MinimiseConstrainedPotential 1496 atom **PermutationMap = NULL; 1497 atom *Walker = NULL, *Sprinter = NULL; 1498 MinimiseConstrainedPotential(out, PermutationMap, startstep, endstep, configuration.GetIsAngstroem()); 1499 1500 // check whether we have sufficient space in Trajectories for each atom 1501 Walker = start; 1502 while (Walker->next != end) { 1503 Walker = Walker->next; 1504 if (Trajectories[Walker].R.size() <= (unsigned int)(MaxSteps)) { 1505 //cout << "Increasing size for trajectory array of " << keyword << " to " << (MaxSteps+1) << "." << endl; 1506 Trajectories[Walker].R.resize(MaxSteps+1); 1507 Trajectories[Walker].U.resize(MaxSteps+1); 1508 Trajectories[Walker].F.resize(MaxSteps+1); 1509 } 1510 } 1511 // push endstep to last one 1512 Walker = start; 1513 while (Walker->next != end) { // remove the endstep (is now the very last one) 1514 Walker = Walker->next; 1515 for (int n=NDIM;n--;) { 1516 Trajectories[Walker].R.at(MaxSteps).x[n] = Trajectories[Walker].R.at(endstep).x[n]; 1517 Trajectories[Walker].U.at(MaxSteps).x[n] = Trajectories[Walker].U.at(endstep).x[n]; 1518 Trajectories[Walker].F.at(MaxSteps).x[n] = Trajectories[Walker].F.at(endstep).x[n]; 1519 } 1520 } 1521 endstep = MaxSteps; 1522 1523 // go through all steps and add the molecular configuration to the list and to the Trajectories of \a this molecule 1524 *out << Verbose(1) << "Filling intermediate " << MaxSteps << " steps with MDSteps of " << MDSteps << "." << endl; 1525 for (int step = 0; step <= MaxSteps; step++) { 1526 mol = new molecule(elemente); 1527 MoleculePerStep->insert(mol); 1528 Walker = start; 1529 while (Walker->next != end) { 1530 Walker = Walker->next; 1531 // add to molecule list 1532 Sprinter = mol->AddCopyAtom(Walker); 1533 for (int n=NDIM;n--;) { 1534 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); 1535 // add to Trajectories 1536 //*out << Verbose(3) << step << ">=" << MDSteps-1 << endl; 1537 if (step < MaxSteps) { 1538 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); 1539 Trajectories[Walker].U.at(step).x[n] = 0.; 1540 Trajectories[Walker].F.at(step).x[n] = 0.; 1541 } 1542 } 1543 } 1544 } 1545 MDSteps = MaxSteps+1; // otherwise new Trajectories' points aren't stored on save&exit 1546 1547 // store the list to single step files 1548 int *SortIndex = (int *) Malloc(AtomCount*sizeof(int), "molecule::LinearInterpolationBetweenConfiguration: *SortIndex"); 1549 for (int i=AtomCount; i--; ) 1550 SortIndex[i] = i; 1551 status = MoleculePerStep->OutputConfigForListOfFragments(out, &configuration, SortIndex); 1552 1553 // free and return 1554 Free((void **)&PermutationMap, "molecule::MinimiseConstrainedPotential: *PermutationMap"); 1555 delete(MoleculePerStep); 1556 return status; 1557 }; 1558 1085 1559 /** Parses nuclear forces from file and performs Verlet integration. 1086 1560 * Note that we assume the parsed forces to be in atomic units (hence, if coordinates are in angstroem, we 1087 1561 * have to transform them). 1088 1562 * This adds a new MD step to the config file. 1563 * \param *out output stream for debugging 1089 1564 * \param *file filename 1565 * \param config structure with config::Deltat, config::IsAngstroem, config::DoConstrained 1090 1566 * \param delta_t time step width in atomic units 1091 1567 * \param IsAngstroem whether coordinates are in angstroem (true) or bohrradius (false) 1568 * \param DoConstrained whether we perform a constrained (>0, target step in molecule::trajectories) or unconstrained (0) molecular dynamics, \sa molecule::MinimiseConstrainedPotential() 1092 1569 * \return true - file found and parsed, false - file not found or imparsable 1093 * /1094 bool molecule::VerletForceIntegration(char *file, double delta_t, bool IsAngstroem) 1095 { 1096 element *runner = elemente->start; 1570 * \todo This is not yet checked if it is correctly working with DoConstrained set to true. 1571 */ 1572 bool molecule::VerletForceIntegration(ofstream *out, char *file, config &configuration) 1573 { 1097 1574 atom *walker = NULL; 1098 int AtomNo;1099 1575 ifstream input(file); 1100 1576 string token; 1101 1577 stringstream item; 1102 double a, IonMass;1578 double IonMass, Vector[NDIM], ConstrainedPotentialEnergy, ActualTemp; 1103 1579 ForceMatrix Force; 1104 Vector tmpvector;1105 1580 1106 1581 CountElements(); // make sure ElementsInMolecule is up to date … … 1120 1595 } 1121 1596 // correct Forces 1122 // for(int d=0;d<NDIM;d++) 1123 // tmpvector.x[d] = 0.; 1124 // for(int i=0;i<AtomCount;i++) 1125 // for(int d=0;d<NDIM;d++) { 1126 // tmpvector.x[d] += Force.Matrix[0][i][d+5]; 1127 // } 1128 // for(int i=0;i<AtomCount;i++) 1129 // for(int d=0;d<NDIM;d++) { 1130 // Force.Matrix[0][i][d+5] -= tmpvector.x[d]/(double)AtomCount; 1131 // } 1597 for(int d=0;d<NDIM;d++) 1598 Vector[d] = 0.; 1599 for(int i=0;i<AtomCount;i++) 1600 for(int d=0;d<NDIM;d++) { 1601 Vector[d] += Force.Matrix[0][i][d+5]; 1602 } 1603 for(int i=0;i<AtomCount;i++) 1604 for(int d=0;d<NDIM;d++) { 1605 Force.Matrix[0][i][d+5] -= Vector[d]/(double)AtomCount; 1606 } 1607 // solve a constrained potential if we are meant to 1608 if (configuration.DoConstrainedMD) { 1609 // calculate forces and potential 1610 atom **PermutationMap = NULL; 1611 ConstrainedPotentialEnergy = MinimiseConstrainedPotential(out, PermutationMap,configuration.DoConstrainedMD, 0, configuration.GetIsAngstroem()); 1612 EvaluateConstrainedForces(out, configuration.DoConstrainedMD, 0, PermutationMap, &Force); 1613 Free((void **)&PermutationMap, "molecule::MinimiseConstrainedPotential: *PermutationMap"); 1614 } 1615 1132 1616 // and perform Verlet integration for each atom with position, velocity and force vector 1133 runner = elemente->start; 1134 while (runner->next != elemente->end) { // go through every element 1135 runner = runner->next; 1136 IonMass = runner->mass; 1137 a = delta_t*0.5/IonMass; // (F+F_old)/2m = a and thus: v = (F+F_old)/2m * t = (F + F_old) * a 1138 if (ElementsInMolecule[runner->Z]) { // if this element got atoms 1139 AtomNo = 0; 1617 walker = start; 1618 while (walker->next != end) { // go through every atom of this element 1619 walker = walker->next; 1620 //a = configuration.Deltat*0.5/walker->type->mass; // (F+F_old)/2m = a and thus: v = (F+F_old)/2m * t = (F + F_old) * a 1621 // check size of vectors 1622 if (Trajectories[walker].R.size() <= (unsigned int)(MDSteps)) { 1623 //out << "Increasing size for trajectory array of " << *walker << " to " << (size+10) << "." << endl; 1624 Trajectories[walker].R.resize(MDSteps+10); 1625 Trajectories[walker].U.resize(MDSteps+10); 1626 Trajectories[walker].F.resize(MDSteps+10); 1627 } 1628 1629 // Update R (and F) 1630 for (int d=0; d<NDIM; d++) { 1631 Trajectories[walker].F.at(MDSteps).x[d] = -Force.Matrix[0][walker->nr][d+5]*(configuration.GetIsAngstroem() ? AtomicLengthToAngstroem : 1.); 1632 Trajectories[walker].R.at(MDSteps).x[d] = Trajectories[walker].R.at(MDSteps-1).x[d]; 1633 Trajectories[walker].R.at(MDSteps).x[d] += configuration.Deltat*(Trajectories[walker].U.at(MDSteps-1).x[d]); // s(t) = s(0) + v * deltat + 1/2 a * deltat^2 1634 Trajectories[walker].R.at(MDSteps).x[d] += 0.5*configuration.Deltat*configuration.Deltat*(Trajectories[walker].F.at(MDSteps).x[d]/walker->type->mass); // F = m * a and s = 0.5 * F/m * t^2 = F * a * t 1635 } 1636 // Update U 1637 for (int d=0; d<NDIM; d++) { 1638 Trajectories[walker].U.at(MDSteps).x[d] = Trajectories[walker].U.at(MDSteps-1).x[d]; 1639 Trajectories[walker].U.at(MDSteps).x[d] += configuration.Deltat * (Trajectories[walker].F.at(MDSteps).x[d]+Trajectories[walker].F.at(MDSteps-1).x[d]/walker->type->mass); // v = F/m * t 1640 } 1641 // out << "Integrated position&velocity of step " << (MDSteps) << ": ("; 1642 // for (int d=0;d<NDIM;d++) 1643 // out << Trajectories[walker].R.at(MDSteps).x[d] << " "; // next step 1644 // out << ")\t("; 1645 // for (int d=0;d<NDIM;d++) 1646 // cout << Trajectories[walker].U.at(MDSteps).x[d] << " "; // next step 1647 // out << ")" << endl; 1648 // next atom 1649 } 1650 } 1651 // correct velocities (rather momenta) so that center of mass remains motionless 1652 for(int d=0;d<NDIM;d++) 1653 Vector[d] = 0.; 1654 IonMass = 0.; 1655 walker = start; 1656 while (walker->next != end) { // go through every atom 1657 walker = walker->next; 1658 IonMass += walker->type->mass; // sum up total mass 1659 for(int d=0;d<NDIM;d++) { 1660 Vector[d] += Trajectories[walker].U.at(MDSteps).x[d]*walker->type->mass; 1661 } 1662 } 1663 // correct velocities (rather momenta) so that center of mass remains motionless 1664 for(int d=0;d<NDIM;d++) 1665 Vector[d] /= IonMass; 1666 ActualTemp = 0.; 1667 walker = start; 1668 while (walker->next != end) { // go through every atom of this element 1669 walker = walker->next; 1670 for(int d=0;d<NDIM;d++) { 1671 Trajectories[walker].U.at(MDSteps).x[d] -= Vector[d]; 1672 ActualTemp += 0.5 * walker->type->mass * Trajectories[walker].U.at(MDSteps).x[d] * Trajectories[walker].U.at(MDSteps).x[d]; 1673 } 1674 } 1675 Thermostats(configuration, ActualTemp, Berendsen); 1676 MDSteps++; 1677 1678 1679 // exit 1680 return true; 1681 }; 1682 1683 /** Implementation of various thermostats. 1684 * All these thermostats apply an additional force which has the following forms: 1685 * -# Woodcock 1686 * \f$p_i \rightarrow \sqrt{\frac{T_0}{T}} \cdot p_i\f$ 1687 * -# Gaussian 1688 * \f$ \frac{ \sum_i \frac{p_i}{m_i} \frac{\partial V}{\partial q_i}} {\sum_i \frac{p^2_i}{m_i}} \cdot p_i\f$ 1689 * -# Langevin 1690 * \f$p_{i,n} \rightarrow \sqrt{1-\alpha^2} p_{i,0} + \alpha p_r\f$ 1691 * -# Berendsen 1692 * \f$p_i \rightarrow \left [ 1+ \frac{\delta t}{\tau_T} \left ( \frac{T_0}{T} \right ) \right ]^{\frac{1}{2}} \cdot p_i\f$ 1693 * -# Nose-Hoover 1694 * \f$\zeta p_i \f$ with \f$\frac{\partial \zeta}{\partial t} = \frac{1}{M_s} \left ( \sum^N_{i=1} \frac{p_i^2}{m_i} - g k_B T \right )\f$ 1695 * These Thermostats either simply rescale the velocities, thus this function should be called after ion velocities have been updated, and/or 1696 * have a constraint force acting additionally on the ions. In the latter case, the ion speeds have to be modified 1697 * belatedly and the constraint force set. 1698 * \param *P Problem at hand 1699 * \param i which of the thermostats to take: 0 - none, 1 - Woodcock, 2 - Gaussian, 3 - Langevin, 4 - Berendsen, 5 - Nose-Hoover 1700 * \sa InitThermostat() 1701 */ 1702 void molecule::Thermostats(config &configuration, double ActualTemp, int Thermostat) 1703 { 1704 double ekin = 0.; 1705 double E = 0., G = 0.; 1706 double delta_alpha = 0.; 1707 double ScaleTempFactor; 1708 double sigma; 1709 double IonMass; 1710 int d; 1711 gsl_rng * r; 1712 const gsl_rng_type * T; 1713 double *U = NULL, *F = NULL, FConstraint[NDIM]; 1714 atom *walker = NULL; 1715 1716 // calculate scale configuration 1717 ScaleTempFactor = configuration.TargetTemp/ActualTemp; 1718 1719 // differentating between the various thermostats 1720 switch(Thermostat) { 1721 case None: 1722 cout << Verbose(2) << "Applying no thermostat..." << endl; 1723 break; 1724 case Woodcock: 1725 if ((configuration.ScaleTempStep > 0) && ((MDSteps-1) % configuration.ScaleTempStep == 0)) { 1726 cout << Verbose(2) << "Applying Woodcock thermostat..." << endl; 1140 1727 walker = start; 1141 1728 while (walker->next != end) { // go through every atom of this element 1142 1729 walker = walker->next; 1143 if (walker->type == runner) { // if this atom fits to element 1144 // check size of vectors 1145 if (Trajectories[walker].R.size() <= (unsigned int)(MDSteps)) { 1146 //cout << "Increasing size for trajectory array of " << *walker << " to " << (size+10) << "." << endl; 1147 Trajectories[walker].R.resize(MDSteps+10); 1148 Trajectories[walker].U.resize(MDSteps+10); 1149 Trajectories[walker].F.resize(MDSteps+10); 1730 IonMass = walker->type->mass; 1731 U = Trajectories[walker].U.at(MDSteps).x; 1732 if (walker->FixedIon == 0) // even FixedIon moves, only not by other's forces 1733 for (d=0; d<NDIM; d++) { 1734 U[d] *= sqrt(ScaleTempFactor); 1735 ekin += 0.5*IonMass * U[d]*U[d]; 1150 1736 } 1151 // 1. calculate x(t+\delta t) 1152 for (int d=0; d<NDIM; d++) { 1153 Trajectories[walker].F.at(MDSteps).x[d] = -Force.Matrix[0][AtomNo][d+5]; 1154 Trajectories[walker].R.at(MDSteps).x[d] = Trajectories[walker].R.at(MDSteps-1).x[d]; 1155 Trajectories[walker].R.at(MDSteps).x[d] += delta_t*(Trajectories[walker].U.at(MDSteps-1).x[d]); 1156 Trajectories[walker].R.at(MDSteps).x[d] += 0.5*delta_t*delta_t*(Trajectories[walker].F.at(MDSteps-1).x[d])/IonMass; // F = m * a and s = 0.5 * F/m * t^2 = F * a * t 1737 } 1738 } 1739 break; 1740 case Gaussian: 1741 cout << Verbose(2) << "Applying Gaussian thermostat..." << endl; 1742 walker = start; 1743 while (walker->next != end) { // go through every atom of this element 1744 walker = walker->next; 1745 IonMass = walker->type->mass; 1746 U = Trajectories[walker].U.at(MDSteps).x; 1747 F = Trajectories[walker].F.at(MDSteps).x; 1748 if (walker->FixedIon == 0) // even FixedIon moves, only not by other's forces 1749 for (d=0; d<NDIM; d++) { 1750 G += U[d] * F[d]; 1751 E += U[d]*U[d]*IonMass; 1752 } 1753 } 1754 cout << Verbose(1) << "Gaussian Least Constraint constant is " << G/E << "." << endl; 1755 walker = start; 1756 while (walker->next != end) { // go through every atom of this element 1757 walker = walker->next; 1758 IonMass = walker->type->mass; 1759 U = Trajectories[walker].U.at(MDSteps).x; 1760 F = Trajectories[walker].F.at(MDSteps).x; 1761 if (walker->FixedIon == 0) // even FixedIon moves, only not by other's forces 1762 for (d=0; d<NDIM; d++) { 1763 FConstraint[d] = (G/E) * (U[d]*IonMass); 1764 U[d] += configuration.Deltat/IonMass * (FConstraint[d]); 1765 ekin += IonMass * U[d]*U[d]; 1766 } 1767 } 1768 break; 1769 case Langevin: 1770 cout << Verbose(2) << "Applying Langevin thermostat..." << endl; 1771 // init random number generator 1772 gsl_rng_env_setup(); 1773 T = gsl_rng_default; 1774 r = gsl_rng_alloc (T); 1775 // Go through each ion 1776 walker = start; 1777 while (walker->next != end) { // go through every atom of this element 1778 walker = walker->next; 1779 IonMass = walker->type->mass; 1780 sigma = sqrt(configuration.TargetTemp/IonMass); // sigma = (k_b T)/m (Hartree/atomicmass = atomiclength/atomictime) 1781 U = Trajectories[walker].U.at(MDSteps).x; 1782 F = Trajectories[walker].F.at(MDSteps).x; 1783 if (walker->FixedIon == 0) { // even FixedIon moves, only not by other's forces 1784 // throw a dice to determine whether it gets hit by a heat bath particle 1785 if (((((rand()/(double)RAND_MAX))*configuration.TempFrequency) < 1.)) { 1786 cout << Verbose(3) << "Particle " << *walker << " was hit (sigma " << sigma << "): " << sqrt(U[0]*U[0]+U[1]*U[1]+U[2]*U[2]) << " -> "; 1787 // pick three random numbers from a Boltzmann distribution around the desired temperature T for each momenta axis 1788 for (d=0; d<NDIM; d++) { 1789 U[d] = gsl_ran_gaussian (r, sigma); 1157 1790 } 1158 // 2. Calculate v(t+\delta t) 1159 for (int d=0; d<NDIM; d++) { 1160 Trajectories[walker].U.at(MDSteps).x[d] = Trajectories[walker].U.at(MDSteps-1).x[d]; 1161 Trajectories[walker].U.at(MDSteps).x[d] += 0.5*delta_t*(Trajectories[walker].F.at(MDSteps-1).x[d]+Trajectories[walker].F.at(MDSteps).x[d])/IonMass; 1162 } 1163 // cout << "Integrated position&velocity of step " << (MDSteps) << ": ("; 1164 // for (int d=0;d<NDIM;d++) 1165 // cout << Trajectories[walker].R.at(MDSteps).x[d] << " "; // next step 1166 // cout << ")\t("; 1167 // for (int d=0;d<NDIM;d++) 1168 // cout << Trajectories[walker].U.at(MDSteps).x[d] << " "; // next step 1169 // cout << ")" << endl; 1170 // next atom 1171 AtomNo++; 1791 cout << sqrt(U[0]*U[0]+U[1]*U[1]+U[2]*U[2]) << endl; 1792 } 1793 for (d=0; d<NDIM; d++) 1794 ekin += 0.5*IonMass * U[d]*U[d]; 1795 } 1796 } 1797 break; 1798 case Berendsen: 1799 cout << Verbose(2) << "Applying Berendsen-VanGunsteren thermostat..." << endl; 1800 walker = start; 1801 while (walker->next != end) { // go through every atom of this element 1802 walker = walker->next; 1803 IonMass = walker->type->mass; 1804 U = Trajectories[walker].U.at(MDSteps).x; 1805 F = Trajectories[walker].F.at(MDSteps).x; 1806 if (walker->FixedIon == 0) { // even FixedIon moves, only not by other's forces 1807 for (d=0; d<NDIM; d++) { 1808 U[d] *= sqrt(1+(configuration.Deltat/configuration.TempFrequency)*(ScaleTempFactor-1)); 1809 ekin += 0.5*IonMass * U[d]*U[d]; 1172 1810 } 1173 1811 } 1174 1812 } 1175 } 1176 } 1177 // // correct velocities (rather momenta) so that center of mass remains motionless 1178 // tmpvector.zero() 1179 // IonMass = 0.; 1180 // walker = start; 1181 // while (walker->next != end) { // go through every atom 1182 // walker = walker->next; 1183 // IonMass += walker->type->mass; // sum up total mass 1184 // for(int d=0;d<NDIM;d++) { 1185 // tmpvector.x[d] += Trajectories[walker].U.at(MDSteps).x[d]*walker->type->mass; 1186 // } 1187 // } 1188 // walker = start; 1189 // while (walker->next != end) { // go through every atom of this element 1190 // walker = walker->next; 1191 // for(int d=0;d<NDIM;d++) { 1192 // Trajectories[walker].U.at(MDSteps).x[d] -= tmpvector.x[d]*walker->type->mass/IonMass; 1193 // } 1194 // } 1195 MDSteps++; 1196 1197 1198 // exit 1199 return true; 1200 }; 1201 1202 /** Align all atoms in such a manner that given vector \a *n is along z axis. 1813 break; 1814 case NoseHoover: 1815 cout << Verbose(2) << "Applying Nose-Hoover thermostat..." << endl; 1816 // dynamically evolve alpha (the additional degree of freedom) 1817 delta_alpha = 0.; 1818 walker = start; 1819 while (walker->next != end) { // go through every atom of this element 1820 walker = walker->next; 1821 IonMass = walker->type->mass; 1822 U = Trajectories[walker].U.at(MDSteps).x; 1823 if (walker->FixedIon == 0) { // even FixedIon moves, only not by other's forces 1824 for (d=0; d<NDIM; d++) { 1825 delta_alpha += U[d]*U[d]*IonMass; 1826 } 1827 } 1828 } 1829 delta_alpha = (delta_alpha - (3.*AtomCount+1.) * configuration.TargetTemp)/(configuration.HooverMass*Units2Electronmass); 1830 configuration.alpha += delta_alpha*configuration.Deltat; 1831 cout << Verbose(3) << "alpha = " << delta_alpha << " * " << configuration.Deltat << " = " << configuration.alpha << "." << endl; 1832 // apply updated alpha as additional force 1833 walker = start; 1834 while (walker->next != end) { // go through every atom of this element 1835 walker = walker->next; 1836 IonMass = walker->type->mass; 1837 U = Trajectories[walker].U.at(MDSteps).x; 1838 if (walker->FixedIon == 0) { // even FixedIon moves, only not by other's forces 1839 for (d=0; d<NDIM; d++) { 1840 FConstraint[d] = - configuration.alpha * (U[d] * IonMass); 1841 U[d] += configuration.Deltat/IonMass * (FConstraint[d]); 1842 ekin += (0.5*IonMass) * U[d]*U[d]; 1843 } 1844 } 1845 } 1846 break; 1847 } 1848 cout << Verbose(1) << "Kinetic energy is " << ekin << "." << endl; 1849 }; 1850 1851 /** Align all atoms in such a manner that given vector \a *n is along z axis. 1203 1852 * \param n[] alignment vector. 1204 1853 */ … … 1267 1916 bool molecule::RemoveAtom(atom *pointer) 1268 1917 { 1269 if (ElementsInMolecule[pointer->type->Z] != 0) // this would indicate an error1918 if (ElementsInMolecule[pointer->type->Z] != 0) { // this would indicate an error 1270 1919 ElementsInMolecule[pointer->type->Z]--; // decrease number of atom of this element 1271 else 1920 AtomCount--; 1921 } else 1272 1922 cerr << "ERROR: Atom " << pointer->Name << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl; 1273 1923 if (ElementsInMolecule[pointer->type->Z] == 0) // was last atom of this element? … … 3093 3743 while (MolecularWalker->next != NULL) { 3094 3744 MolecularWalker = MolecularWalker->next; 3745 *out << Verbose(0) << "Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl; 3095 3746 LocalBackEdgeStack = new StackClass<bond *> (MolecularWalker->Leaf->BondCount); 3096 3747 // // check the list of local atoms for debugging … … 3108 3759 delete(LocalBackEdgeStack); 3109 3760 } 3110 3761 3111 3762 // ===== 3. if structure still valid, parse key set file and others ===== 3112 3763 FragmentationToDo = FragmentationToDo && ParseKeySetFile(out, configuration->configpath, ParsedFragmentList); … … 3114 3765 // ===== 4. check globally whether there's something to do actually (first adaptivity check) 3115 3766 FragmentationToDo = FragmentationToDo && ParseOrderAtSiteFromFile(out, configuration->configpath); 3116 3117 // =================================== Begin of FRAGMENTATION =============================== 3118 // ===== 6a. assign each keyset to its respective subgraph ===== 3767 3768 // =================================== Begin of FRAGMENTATION =============================== 3769 // ===== 6a. assign each keyset to its respective subgraph ===== 3119 3770 Subgraphs->next->AssignKeySetsToFragment(out, this, ParsedFragmentList, ListOfLocalAtoms, FragmentList, (FragmentCounter = 0), true); 3120 3771 … … 3151 3802 delete(ParsedFragmentList); 3152 3803 delete[](MinimumRingSize); 3153 3804 3154 3805 3155 3806 // ==================================== End of FRAGMENTATION ============================================ … … 3244 3895 atom *Walker = NULL, *OtherAtom = NULL; 3245 3896 ReferenceStack->Push(Binder); 3246 3897 3247 3898 do { // go through all bonds and push local ones 3248 3899 Walker = ListOfLocalAtoms[Binder->leftatom->nr]; // get one atom in the reference molecule … … 3714 4365 }; 3715 4366 4367 /** Creates \a MoleculeListClass of all unique fragments of the \a molecule containing \a Order atoms or vertices. 4368 * The picture to have in mind is that of a DFS "snake" of a certain length \a Order, i.e. as in the infamous 4369 * computer game, that winds through the connected graph representing the molecule. Color (white, 4370 * lightgray, darkgray, black) indicates whether a vertex has been discovered so far or not. Labels will help in 4371 * creating only unique fragments and not additional ones with vertices simply in different sequence. 4372 * The Predecessor is always the one that came before in discovering, needed on backstepping. And 4373 * finally, the ShortestPath is needed for removing vertices from the snake stack during the back- 4374 * stepping. 4375 * \param *out output stream for debugging 4376 * \param Order number of atoms in each fragment 4377 * \param *configuration configuration for writing config files for each fragment 4378 * \return List of all unique fragments with \a Order atoms 4379 */ 4380 /* 4381 MoleculeListClass * molecule::CreateListOfUniqueFragmentsOfOrder(ofstream *out, int Order, config *configuration) 4382 { 4383 atom **PredecessorList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::CreateListOfUniqueFragmentsOfOrder: **PredecessorList"); 4384 int *ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CreateListOfUniqueFragmentsOfOrder: *ShortestPathList"); 4385 int *Labels = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CreateListOfUniqueFragmentsOfOrder: *Labels"); 4386 enum Shading *ColorVertexList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::CreateListOfUniqueFragmentsOfOrder: *ColorList"); 4387 enum Shading *ColorEdgeList = (enum Shading *) Malloc(sizeof(enum Shading)*BondCount, "molecule::CreateListOfUniqueFragmentsOfOrder: *ColorBondList"); 4388 StackClass<atom *> *RootStack = new StackClass<atom *>(AtomCount); 4389 StackClass<atom *> *TouchedStack = new StackClass<atom *>((int)pow(4,Order)+2); // number of atoms reached from one with maximal 4 bonds plus Root itself 4390 StackClass<atom *> *SnakeStack = new StackClass<atom *>(Order+1); // equal to Order is not possible, as then the StackClass<atom *> cannot discern between full and empty stack! 4391 MoleculeLeafClass *Leaflet = NULL, *TempLeaf = NULL; 4392 MoleculeListClass *FragmentList = NULL; 4393 atom *Walker = NULL, *OtherAtom = NULL, *Root = NULL, *Removal = NULL; 4394 bond *Binder = NULL; 4395 int RunningIndex = 0, FragmentCounter = 0; 4396 4397 *out << Verbose(1) << "Begin of CreateListOfUniqueFragmentsOfOrder." << endl; 4398 4399 // reset parent list 4400 *out << Verbose(3) << "Resetting labels, parent, predecessor, color and shortest path lists." << endl; 4401 for (int i=0;i<AtomCount;i++) { // reset all atom labels 4402 // initialise each vertex as white with no predecessor, empty queue, color lightgray, not labelled, no sons 4403 Labels[i] = -1; 4404 SonList[i] = NULL; 4405 PredecessorList[i] = NULL; 4406 ColorVertexList[i] = white; 4407 ShortestPathList[i] = -1; 4408 } 4409 for (int i=0;i<BondCount;i++) 4410 ColorEdgeList[i] = white; 4411 RootStack->ClearStack(); // clearstack and push first atom if exists 4412 TouchedStack->ClearStack(); 4413 Walker = start->next; 4414 while ((Walker != end) 4415 #ifdef ADDHYDROGEN 4416 && (Walker->type->Z == 1) 4417 } 4418 } 4419 *out << ", SP of " << ShortestPathList[Walker->nr] << " and its color is " << GetColor(ColorVertexList[Walker->nr]) << "." << endl; 4420 4421 // then check the stack for a newly stumbled upon fragment 4422 if (SnakeStack->ItemCount() == Order) { // is stack full? 4423 // store the fragment if it is one and get a removal candidate 4424 Removal = StoreFragmentFromStack(out, Root, Walker, Leaflet, SnakeStack, ShortestPathList, SonList, Labels, &FragmentCounter, configuration); 4425 // remove the candidate if one was found 4426 if (Removal != NULL) { 4427 *out << Verbose(2) << "Removing item " << Removal->Name << " with SP of " << ShortestPathList[Removal->nr] << " from snake stack." << endl; 4428 SnakeStack->RemoveItem(Removal); 4429 ColorVertexList[Removal->nr] = lightgray; // return back to not on snake stack but explored marking 4430 if (Walker == Removal) { // if the current atom is to be removed, we also have to take a step back 4431 Walker = PredecessorList[Removal->nr]; 4432 *out << Verbose(2) << "Stepping back to " << Walker->Name << "." << endl; 4433 } 4434 } 4435 } else 4436 Removal = NULL; 4437 4438 // finally, look for a white neighbour as the next Walker 4439 Binder = NULL; 4440 if ((Removal == NULL) || (Walker != PredecessorList[Removal->nr])) { // don't look, if a new walker has been set above 4441 *out << Verbose(2) << "Snake has currently " << SnakeStack->ItemCount() << " item(s)." << endl; 4442 OtherAtom = NULL; // this is actually not needed, every atom has at least one neighbour 4443 if (ShortestPathList[Walker->nr] < Order) { 4444 for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) { 4445 Binder = ListOfBondsPerAtom[Walker->nr][i]; 4446 *out << Verbose(2) << "Current bond is " << *Binder << ": "; 4447 OtherAtom = Binder->GetOtherAtom(Walker); 4448 if ((Labels[OtherAtom->nr] != -1) && (Labels[OtherAtom->nr] < Labels[Root->nr])) { // we don't step up to labels bigger than us 4449 *out << "Label " << Labels[OtherAtom->nr] << " is smaller than Root's " << Labels[Root->nr] << "." << endl; 4450 //ColorVertexList[OtherAtom->nr] = lightgray; // mark as explored 4451 } else { // otherwise check its colour and element 4452 if ( 4453 (OtherAtom->type->Z != 1) && 4454 #endif 4455 (ColorEdgeList[Binder->nr] == white)) { // skip hydrogen, look for unexplored vertices 4456 *out << "Moving along " << GetColor(ColorEdgeList[Binder->nr]) << " bond " << Binder << " to " << ((ColorVertexList[OtherAtom->nr] == white) ? "unexplored" : "explored") << " item: " << OtherAtom->Name << "." << endl; 4457 // i find it currently rather sensible to always set the predecessor in order to find one's way back 4458 //if (PredecessorList[OtherAtom->nr] == NULL) { 4459 PredecessorList[OtherAtom->nr] = Walker; 4460 *out << Verbose(3) << "Setting Predecessor of " << OtherAtom->Name << " to " << PredecessorList[OtherAtom->nr]->Name << "." << endl; 4461 //} else { 4462 // *out << Verbose(3) << "Predecessor of " << OtherAtom->Name << " is " << PredecessorList[OtherAtom->nr]->Name << "." << endl; 4463 //} 4464 Walker = OtherAtom; 4465 break; 4466 } else { 4467 if (OtherAtom->type->Z == 1) 4468 *out << "Links to a hydrogen atom." << endl; 4469 else 4470 *out << "Bond has not white but " << GetColor(ColorEdgeList[Binder->nr]) << " color." << endl; 4471 } 4472 } 4473 } 4474 } else { // means we have stepped beyond the horizon: Return! 4475 Walker = PredecessorList[Walker->nr]; 4476 OtherAtom = Walker; 4477 *out << Verbose(3) << "We have gone too far, stepping back to " << Walker->Name << "." << endl; 4478 } 4479 if (Walker != OtherAtom) { // if no white neighbours anymore, color it black 4480 *out << Verbose(2) << "Coloring " << Walker->Name << " black." << endl; 4481 ColorVertexList[Walker->nr] = black; 4482 Walker = PredecessorList[Walker->nr]; 4483 } 4484 } 4485 } while ((Walker != Root) || (ColorVertexList[Root->nr] != black)); 4486 *out << Verbose(2) << "Inner Looping is finished." << endl; 4487 4488 // if we reset all AtomCount atoms, we have again technically O(N^2) ... 4489 *out << Verbose(2) << "Resetting lists." << endl; 4490 Walker = NULL; 4491 Binder = NULL; 4492 while (!TouchedStack->IsEmpty()) { 4493 Walker = TouchedStack->PopLast(); 4494 *out << Verbose(3) << "Re-initialising entries of " << *Walker << "." << endl; 4495 for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) 4496 ColorEdgeList[ListOfBondsPerAtom[Walker->nr][i]->nr] = white; 4497 PredecessorList[Walker->nr] = NULL; 4498 ColorVertexList[Walker->nr] = white; 4499 ShortestPathList[Walker->nr] = -1; 4500 } 4501 } 4502 *out << Verbose(1) << "Outer Looping over all vertices is done." << endl; 4503 4504 // copy together 4505 *out << Verbose(1) << "Copying all fragments into MoleculeList structure." << endl; 4506 FragmentList = new MoleculeListClass(FragmentCounter, AtomCount); 4507 RunningIndex = 0; 4508 while ((Leaflet != NULL) && (RunningIndex < FragmentCounter)) { 4509 FragmentList->ListOfMolecules[RunningIndex++] = Leaflet->Leaf; 4510 Leaflet->Leaf = NULL; // prevent molecule from being removed 4511 TempLeaf = Leaflet; 4512 Leaflet = Leaflet->previous; 4513 delete(TempLeaf); 4514 }; 4515 4516 // free memory and exit 4517 Free((void **)&PredecessorList, "molecule::CreateListOfUniqueFragmentsOfOrder: **PredecessorList"); 4518 Free((void **)&ShortestPathList, "molecule::CreateListOfUniqueFragmentsOfOrder: *ShortestPathList"); 4519 Free((void **)&Labels, "molecule::CreateListOfUniqueFragmentsOfOrder: *Labels"); 4520 Free((void **)&ColorVertexList, "molecule::CreateListOfUniqueFragmentsOfOrder: *ColorList"); 4521 delete(RootStack); 4522 delete(TouchedStack); 4523 delete(SnakeStack); 4524 4525 *out << Verbose(1) << "End of CreateListOfUniqueFragmentsOfOrder." << endl; 4526 return FragmentList; 4527 }; 4528 */ 4529 3716 4530 /** Structure containing all values in power set combination generation. 3717 4531 */ … … 4545 5359 if (result) { 4546 5360 *out << Verbose(5) << "Calculating Centers of Gravity" << endl; 4547 Determine Center(CenterOfGravity);4548 OtherMolecule->Determine Center(OtherCenterOfGravity);5361 DeterminePeriodicCenter(CenterOfGravity); 5362 OtherMolecule->DeterminePeriodicCenter(OtherCenterOfGravity); 4549 5363 *out << Verbose(5) << "Center of Gravity: "; 4550 5364 CenterOfGravity.Output(out); -
src/molecules.hpp
r042f82 r36ec71 10 10 11 11 // GSL headers 12 #include <gsl/gsl_eigen.h> 13 #include <gsl/gsl_heapsort.h> 14 #include <gsl/gsl_linalg.h> 15 #include <gsl/gsl_matrix.h> 12 16 #include <gsl/gsl_multimin.h> 13 17 #include <gsl/gsl_vector.h> 14 #include <gsl/gsl_matrix.h> 15 #include <gsl/gsl_eigen.h> 16 #include <gsl/gsl_heapsort.h> 18 #include <gsl/gsl_randist.h> 17 19 18 20 // STL headers … … 156 158 }; 157 159 158 ostream & operator << (ostream &ost, atom &a);160 ostream & operator << (ostream &ost, const atom &a); 159 161 160 162 /** Bonds between atoms. … … 195 197 }; 196 198 197 ostream & operator << (ostream &ost, bond &b); 199 200 ostream & operator << (ostream &ost, const bond &b); 198 201 199 202 class MoleculeLeafClass; 203 204 205 #define MaxThermostats 6 //!< maximum number of thermostat entries in Ions#ThermostatNames and Ions#ThermostatImplemented 206 enum thermostats { None, Woodcock, Gaussian, Langevin, Berendsen, NoseHoover }; //!< Thermostat names for output 207 200 208 201 209 /** The complete molecule. … … 254 262 bool CenterInBox(ofstream *out); 255 263 void CenterEdge(ofstream *out, Vector *max); 256 void CenterOrigin(ofstream *out, Vector *max); 257 void CenterGravity(ofstream *out, Vector *max); 264 void CenterOrigin(ofstream *out); 265 void CenterPeriodic(ofstream *out); 266 void CenterAtVector(ofstream *out, Vector *newcenter); 258 267 void Translate(const Vector *x); 259 268 void TranslatePeriodically(const Vector *trans); … … 261 270 void Align(Vector *n); 262 271 void Scale(double **factor); 263 void Determine Center(Vector ¢er);272 void DeterminePeriodicCenter(Vector ¢er); 264 273 Vector * DetermineCenterOfGravity(ofstream *out); 265 274 Vector * DetermineCenterOfAll(ofstream *out); 266 void SetNameFromFilename(c har *filename);275 void SetNameFromFilename(const char *filename); 267 276 void SetBoxDimension(Vector *dim); 268 277 double * ReturnFullMatrixforSymmetric(double *cell_size); 269 278 void ScanForPeriodicCorrection(ofstream *out); 279 bool VerletForceIntegration(ofstream *out, char *file, config &configuration); 280 void Thermostats(config &configuration, double ActualTemp, int Thermostat); 270 281 void PrincipalAxisSystem(ofstream *out, bool DoRotate); 271 282 double VolumeOfConvexEnvelope(ofstream *out, bool IsAngstroem); 272 283 Vector* FindEmbeddingHole(ofstream *out, molecule *srcmol); 273 284 274 bool VerletForceIntegration(char *file, double delta_t, bool IsAngstroem); 275 285 286 double ConstrainedPotential(ofstream *out, atom **permutation, int start, int end, double *constants, bool IsAngstroem); 287 double MinimiseConstrainedPotential(ofstream *out, atom **&permutation, int startstep, int endstep, bool IsAngstroem); 288 void EvaluateConstrainedForces(ofstream *out, int startstep, int endstep, atom **PermutationMap, ForceMatrix *Force); 289 bool LinearInterpolationBetweenConfiguration(ofstream *out, int startstep, int endstep, const char *prefix, config &configuration); 290 276 291 bool CheckBounds(const Vector *x) const; 277 292 void GetAlignvector(struct lsq_params * par) const; … … 349 364 bool AddHydrogenCorrection(ofstream *out, char *path); 350 365 bool StoreForcesFile(ofstream *out, char *path, int *SortIndex); 351 boolinsert(molecule *mol);366 void insert(molecule *mol); 352 367 molecule * ReturnIndex(int index); 353 368 bool OutputConfigForListOfFragments(ofstream *out, config *configuration, int *SortIndex); … … 429 444 char *databasepath; 430 445 446 int DoConstrainedMD; 447 int MaxOuterStep; 448 int Thermostat; 449 int *ThermostatImplemented; 450 char **ThermostatNames; 451 double TempFrequency; 452 double alpha; 453 double HooverMass; 454 double TargetTemp; 455 int ScaleTempStep; 456 431 457 private: 432 458 char *mainname; … … 449 475 int Seed; 450 476 451 int MaxOuterStep;452 477 int OutVisStep; 453 478 int OutSrcStep; 454 double TargetTemp;455 int ScaleTempStep;456 479 int MaxPsiStep; 457 480 double EpsWannier; … … 501 524 char *GetDefaultPath() const; 502 525 void SetDefaultPath(const char *path); 526 void InitThermostats(ifstream *source); 503 527 }; 504 528 -
src/parser.cpp
r042f82 r36ec71 56 56 MatrixContainer::MatrixContainer() { 57 57 Indices = NULL; 58 Header = (char * ) Malloc(sizeof(char)*1023, "MatrixContainer::MatrixContainer:*Header");58 Header = (char **) Malloc(sizeof(char)*1, "MatrixContainer::MatrixContainer: **Header"); 59 59 Matrix = (double ***) Malloc(sizeof(double **)*(1), "MatrixContainer::MatrixContainer: ***Matrix"); // one more each for the total molecule 60 60 RowCounter = (int *) Malloc(sizeof(int)*(1), "MatrixContainer::MatrixContainer: *RowCounter"); 61 ColumnCounter = (int *) Malloc(sizeof(int)*(1), "MatrixContainer::MatrixContainer: *ColumnCounter"); 62 Header[0] = NULL; 61 63 Matrix[0] = NULL; 62 64 RowCounter[0] = -1; 63 65 MatrixCounter = 0; 64 ColumnCounter = 0;66 ColumnCounter[0] = -1; 65 67 }; 66 68 … … 70 72 if (Matrix != NULL) { 71 73 for(int i=MatrixCounter;i--;) { 72 if ( RowCounter != NULL) {74 if ((ColumnCounter != NULL) && (RowCounter != NULL)) { 73 75 for(int j=RowCounter[i]+1;j--;) 74 76 Free((void **)&Matrix[i][j], "MatrixContainer::~MatrixContainer: *Matrix[][]"); … … 76 78 } 77 79 } 78 if (( RowCounter != NULL) && (Matrix[MatrixCounter] != NULL))80 if ((ColumnCounter != NULL) && (RowCounter != NULL) && (Matrix[MatrixCounter] != NULL)) 79 81 for(int j=RowCounter[MatrixCounter]+1;j--;) 80 82 Free((void **)&Matrix[MatrixCounter][j], "MatrixContainer::~MatrixContainer: *Matrix[MatrixCounter][]"); … … 87 89 Free((void **)&Indices[i], "MatrixContainer::~MatrixContainer: *Indices[]"); 88 90 } 89 Free((void **)&Indices, "MatrixContainer::~MatrixContainer: **Indices"); 90 91 Free((void **)&Header, "MatrixContainer::~MatrixContainer: *Header"); 91 Free((void **)&Indices, "MatrixContainer::~MatrixContainer: **Indices"); 92 93 if (Header != NULL) 94 for(int i=MatrixCounter+1;i--;) 95 Free((void **)&Header[i], "MatrixContainer::~MatrixContainer: *Header[]"); 96 Free((void **)&Header, "MatrixContainer::~MatrixContainer: **Header"); 92 97 Free((void **)&RowCounter, "MatrixContainer::~MatrixContainer: *RowCounter"); 93 }; 94 98 Free((void **)&ColumnCounter, "MatrixContainer::~MatrixContainer: *RowCounter"); 99 }; 100 101 /** Either copies index matrix from another MatrixContainer or initialises with trivial mapping if NULL. 102 * This either copies the index matrix or just maps 1 to 1, 2 to 2 and so on for all fragments. 103 * \param *Matrix pointer to other MatrixContainer 104 * \return true - copy/initialisation sucessful, false - dimension false for copying 105 */ 106 bool MatrixContainer::InitialiseIndices(class MatrixContainer *Matrix) 107 { 108 cout << "Initialising indices"; 109 if (Matrix == NULL) { 110 cout << " with trivial mapping." << endl; 111 Indices = (int **) Malloc(sizeof(int *)*(MatrixCounter+1), "MatrixContainer::InitialiseIndices: **Indices"); 112 for(int i=MatrixCounter+1;i--;) { 113 Indices[i] = (int *) Malloc(sizeof(int)*RowCounter[i], "MatrixContainer::InitialiseIndices: *Indices[]"); 114 for(int j=RowCounter[i];j--;) 115 Indices[i][j] = j; 116 } 117 } else { 118 cout << " from other MatrixContainer." << endl; 119 if (MatrixCounter != Matrix->MatrixCounter) 120 return false; 121 Indices = (int **) Malloc(sizeof(int *)*(MatrixCounter+1), "MatrixContainer::InitialiseIndices: **Indices"); 122 for(int i=MatrixCounter+1;i--;) { 123 if (RowCounter[i] != Matrix->RowCounter[i]) 124 return false; 125 Indices[i] = (int *) Malloc(sizeof(int)*Matrix->RowCounter[i], "MatrixContainer::InitialiseIndices: *Indices[]"); 126 for(int j=Matrix->RowCounter[i];j--;) { 127 Indices[i][j] = Matrix->Indices[i][j]; 128 //cout << Indices[i][j] << "\t"; 129 } 130 //cout << endl; 131 } 132 } 133 return true; 134 }; 95 135 96 136 /** Parsing a number of matrices. … … 121 161 } 122 162 123 // skip some initial lines 163 // parse header 164 Header[MatrixNr] = (char *) Malloc(sizeof(char)*1024, "MatrixContainer::ParseMatrix: *Header[]"); 124 165 for (int m=skiplines+1;m--;) 125 input.getline(Header , 1023);126 166 input.getline(Header[MatrixNr], 1023); 167 127 168 // scan header for number of columns 128 line.str(Header );169 line.str(Header[MatrixNr]); 129 170 for(int k=skipcolumns;k--;) 130 line >> Header ;171 line >> Header[MatrixNr]; 131 172 //cout << line.str() << endl; 132 ColumnCounter =0;173 ColumnCounter[MatrixNr]=0; 133 174 while ( getline(line,token, '\t') ) { 134 175 if (token.length() > 0) 135 ColumnCounter ++;176 ColumnCounter[MatrixNr]++; 136 177 } 137 178 //cout << line.str() << endl; 138 //cout << "ColumnCounter : " << ColumnCounter<< "." << endl;139 if (ColumnCounter == 0)140 cerr << "ColumnCounter : " << ColumnCounter<< " from file " << name << ", this is probably an error!" << endl;141 179 //cout << "ColumnCounter[" << MatrixNr << "]: " << ColumnCounter[MatrixNr] << "." << endl; 180 if (ColumnCounter[MatrixNr] == 0) 181 cerr << "ColumnCounter[" << MatrixNr << "]: " << ColumnCounter[MatrixNr] << " from file " << name << ", this is probably an error!" << endl; 182 142 183 // scan rest for number of rows/lines 143 184 RowCounter[MatrixNr]=-1; // counts one line too much … … 155 196 156 197 // allocate matrix if it's not zero dimension in one direction 157 if ((ColumnCounter > 0) && (RowCounter[MatrixNr] > -1)) {158 Matrix[MatrixNr] = (double **) Malloc(sizeof(double *)*(RowCounter[MatrixNr]+1), "MatrixContainer::Parse FragmentMatrix: **Matrix[]");159 198 if ((ColumnCounter[MatrixNr] > 0) && (RowCounter[MatrixNr] > -1)) { 199 Matrix[MatrixNr] = (double **) Malloc(sizeof(double *)*(RowCounter[MatrixNr]+1), "MatrixContainer::ParseMatrix: **Matrix[]"); 200 160 201 // parse in each entry for this matrix 161 202 input.clear(); 162 203 input.seekg(ios::beg); 163 204 for (int m=skiplines+1;m--;) 164 input.getline(Header , 1023); // skip header165 line.str(Header );205 input.getline(Header[MatrixNr], 1023); // skip header 206 line.str(Header[MatrixNr]); 166 207 for(int k=skipcolumns;k--;) // skip columns in header too 167 208 line >> filename; 168 strncpy(Header , line.str().c_str(), 1023);209 strncpy(Header[MatrixNr], line.str().c_str(), 1023); 169 210 for(int j=0;j<RowCounter[MatrixNr];j++) { 170 Matrix[MatrixNr][j] = (double *) Malloc(sizeof(double)*ColumnCounter , "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");211 Matrix[MatrixNr][j] = (double *) Malloc(sizeof(double)*ColumnCounter[MatrixNr], "MatrixContainer::ParseMatrix: *Matrix[][]"); 171 212 input.getline(filename, 1023); 172 213 stringstream lines(filename); … … 174 215 for(int k=skipcolumns;k--;) 175 216 lines >> filename; 176 for(int k=0;(k<ColumnCounter ) && (!lines.eof());k++) {217 for(int k=0;(k<ColumnCounter[MatrixNr]) && (!lines.eof());k++) { 177 218 lines >> Matrix[MatrixNr][j][k]; 178 219 //cout << " " << setprecision(2) << Matrix[MatrixNr][j][k];; 179 220 } 180 221 //cout << endl; 181 Matrix[MatrixNr][ RowCounter[MatrixNr] ] = (double *) Malloc(sizeof(double)*ColumnCounter , "MatrixContainer::ParseFragmentMatrix: *Matrix[RowCounter[MatrixNr]][]");182 for(int j=ColumnCounter ;j--;)222 Matrix[MatrixNr][ RowCounter[MatrixNr] ] = (double *) Malloc(sizeof(double)*ColumnCounter[MatrixNr], "MatrixContainer::ParseMatrix: *Matrix[RowCounter[MatrixNr]][]"); 223 for(int j=ColumnCounter[MatrixNr];j--;) 183 224 Matrix[MatrixNr][ RowCounter[MatrixNr] ][j] = 0.; 184 225 } 185 226 } else { 186 cerr << "ERROR: Matrix nr. " << MatrixNr << " has column and row count of (" << ColumnCounter << "," << RowCounter[MatrixNr] << "), could not allocate nor parse!" << endl;227 cerr << "ERROR: Matrix nr. " << MatrixNr << " has column and row count of (" << ColumnCounter[MatrixNr] << "," << RowCounter[MatrixNr] << "), could not allocate nor parse!" << endl; 187 228 } 188 229 input.close(); … … 233 274 234 275 cout << "Parsing through each fragment and retrieving " << prefix << suffix << "." << endl; 276 Header = (char **) ReAlloc(Header, sizeof(char *)*(MatrixCounter+1), "MatrixContainer::ParseFragmentMatrix: **Header"); // one more each for the total molecule 235 277 Matrix = (double ***) ReAlloc(Matrix, sizeof(double **)*(MatrixCounter+1), "MatrixContainer::ParseFragmentMatrix: ***Matrix"); // one more each for the total molecule 236 278 RowCounter = (int *) ReAlloc(RowCounter, sizeof(int)*(MatrixCounter+1), "MatrixContainer::ParseFragmentMatrix: *RowCounter"); 279 ColumnCounter = (int *) ReAlloc(ColumnCounter, sizeof(int)*(MatrixCounter+1), "MatrixContainer::ParseFragmentMatrix: *ColumnCounter"); 237 280 for(int i=MatrixCounter+1;i--;) { 238 281 Matrix[i] = NULL; 282 Header[i] = NULL; 239 283 RowCounter[i] = -1; 284 ColumnCounter[i] = -1; 240 285 } 241 286 for(int i=0; i < MatrixCounter;i++) { … … 252 297 253 298 /** Allocates and resets the memory for a number \a MCounter of matrices. 254 * \param * GivenHeader Header line299 * \param **GivenHeader Header line for each matrix 255 300 * \param MCounter number of matrices 256 301 * \param *RCounter number of rows for each matrix 257 * \param CCounter number of columns for all matrices 258 * \return Allocation successful 259 */ 260 bool MatrixContainer::AllocateMatrix(const char *GivenHeader, int MCounter, int *RCounter, int CCounter) 261 { 262 Header = (char *) Malloc(sizeof(char)*1024, "MatrixContainer::ParseFragmentMatrix: *EnergyHeader"); 263 strncpy(Header, GivenHeader, 1023); 264 302 * \param *CCounter number of columns for each matrix 303 * \return Allocation successful 304 */ 305 bool MatrixContainer::AllocateMatrix(char **GivenHeader, int MCounter, int *RCounter, int *CCounter) 306 { 265 307 MatrixCounter = MCounter; 266 ColumnCounter = CCounter; 267 Matrix = (double ***) Malloc(sizeof(double **)*(MatrixCounter+1), "MatrixContainer::ParseFragmentMatrix: ***Matrix"); // one more each for the total molecule 268 RowCounter = (int *) Malloc(sizeof(int)*(MatrixCounter+1), "MatrixContainer::ParseFragmentMatrix: *RowCounter"); 308 Header = (char **) Malloc(sizeof(char *)*(MatrixCounter+1), "MatrixContainer::AllocateMatrix: *Header"); 309 Matrix = (double ***) Malloc(sizeof(double **)*(MatrixCounter+1), "MatrixContainer::AllocateMatrix: ***Matrix"); // one more each for the total molecule 310 RowCounter = (int *) Malloc(sizeof(int)*(MatrixCounter+1), "MatrixContainer::AllocateMatrix: *RowCounter"); 311 ColumnCounter = (int *) Malloc(sizeof(int)*(MatrixCounter+1), "MatrixContainer::AllocateMatrix: *ColumnCounter"); 269 312 for(int i=MatrixCounter+1;i--;) { 313 Header[i] = (char *) Malloc(sizeof(char)*1024, "MatrixContainer::AllocateMatrix: *Header[i]"); 314 strncpy(Header[i], GivenHeader[i], 1023); 270 315 RowCounter[i] = RCounter[i]; 271 Matrix[i] = (double **) Malloc(sizeof(double *)*(RowCounter[i]+1), "MatrixContainer::ParseFragmentMatrix: **Matrix[]"); 316 ColumnCounter[i] = CCounter[i]; 317 Matrix[i] = (double **) Malloc(sizeof(double *)*(RowCounter[i]+1), "MatrixContainer::AllocateMatrix: **Matrix[]"); 272 318 for(int j=RowCounter[i]+1;j--;) { 273 Matrix[i][j] = (double *) Malloc(sizeof(double)*ColumnCounter , "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");274 for(int k=ColumnCounter ;k--;)319 Matrix[i][j] = (double *) Malloc(sizeof(double)*ColumnCounter[i], "MatrixContainer::AllocateMatrix: *Matrix[][]"); 320 for(int k=ColumnCounter[i];k--;) 275 321 Matrix[i][j][k] = 0.; 276 322 } … … 286 332 for(int i=MatrixCounter+1;i--;) 287 333 for(int j=RowCounter[i]+1;j--;) 288 for(int k=ColumnCounter ;k--;)334 for(int k=ColumnCounter[i];k--;) 289 335 Matrix[i][j][k] = 0.; 290 336 return true; … … 299 345 for(int i=MatrixCounter+1;i--;) 300 346 for(int j=RowCounter[i]+1;j--;) 301 for(int k=ColumnCounter ;k--;)347 for(int k=ColumnCounter[i];k--;) 302 348 if (fabs(Matrix[i][j][k]) > max) 303 349 max = fabs(Matrix[i][j][k]); … … 315 361 for(int i=MatrixCounter+1;i--;) 316 362 for(int j=RowCounter[i]+1;j--;) 317 for(int k=ColumnCounter ;k--;)363 for(int k=ColumnCounter[i];k--;) 318 364 if (fabs(Matrix[i][j][k]) < min) 319 365 min = fabs(Matrix[i][j][k]); … … 331 377 { 332 378 for(int j=RowCounter[MatrixCounter]+1;j--;) 333 for(int k=skipcolumns;k<ColumnCounter ;k++)379 for(int k=skipcolumns;k<ColumnCounter[MatrixCounter];k++) 334 380 Matrix[MatrixCounter][j][k] = value; 335 381 return true; … … 344 390 { 345 391 for(int j=RowCounter[MatrixCounter]+1;j--;) 346 for(int k=skipcolumns;k<ColumnCounter ;k++)392 for(int k=skipcolumns;k<ColumnCounter[MatrixCounter];k++) 347 393 Matrix[MatrixCounter][j][k] = values[j][k]; 348 394 return true; 349 395 }; 350 396 351 /** Sums the en ergy with each factor and put into last element of \a ***Energies.397 /** Sums the entries with each factor and put into last element of \a ***Matrix. 352 398 * Sums over "E"-terms to create the "F"-terms 353 * \param Matrix MatrixContainer with matrices (LevelCounter by ColumnCounter) with all the energies.399 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies. 354 400 * \param KeySet KeySetContainer with bond Order and association mapping of each fragment to an order 355 401 * \param Order bond order … … 384 430 } 385 431 if (Order == SubOrder) { // equal order is always copy from Energies 386 for(int l=ColumnCounter ;l--;) // then adds/subtract each column432 for(int l=ColumnCounter[ KeySet.OrderSet[SubOrder][j] ];l--;) // then adds/subtract each column 387 433 Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][m][l] += MatrixValues.Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l]; 388 434 } else { 389 for(int l=ColumnCounter ;l--;)435 for(int l=ColumnCounter[ KeySet.OrderSet[SubOrder][j] ];l--;) 390 436 Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][m][l] -= Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l]; 391 437 } 392 438 } 393 //if ((ColumnCounter >1) && (RowCounter[0]-1 >= 1))439 //if ((ColumnCounter[ KeySet.OrderSet[SubOrder][j] ]>1) && (RowCounter[0]-1 >= 1)) 394 440 //cout << "Fragments[ KeySet.OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySet.OrderSet[Order][CurrentFragment] << " ][" << RowCounter[0]-1 << "][" << 1 << "] = " << Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][RowCounter[0]-1][1] << endl; 395 441 } … … 426 472 return false; 427 473 } 428 output << Header << endl;474 output << Header[i] << endl; 429 475 for(int j=0;j<RowCounter[i];j++) { 430 for(int k=0;k<ColumnCounter ;k++)476 for(int k=0;k<ColumnCounter[i];k++) 431 477 output << scientific << Matrix[i][j][k] << "\t"; 432 478 output << endl; … … 455 501 return false; 456 502 } 457 output << Header << endl;503 output << Header[MatrixCounter] << endl; 458 504 for(int j=0;j<RowCounter[MatrixCounter];j++) { 459 for(int k=0;k<ColumnCounter ;k++)505 for(int k=0;k<ColumnCounter[MatrixCounter];k++) 460 506 output << scientific << Matrix[MatrixCounter][j][k] << "\t"; 461 507 output << endl; … … 485 531 /** Sums the energy with each factor and put into last element of \a EnergyMatrix::Matrix. 486 532 * Sums over the "F"-terms in ANOVA decomposition. 487 * \param Matrix MatrixContainer with matrices (LevelCounter by ColumnCounter) with all the energies.533 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies. 488 534 * \param CorrectionFragments MatrixContainer with hydrogen saturation correction per fragments 489 535 * \param KeySet KeySetContainer with bond Order and association mapping of each fragment to an order … … 498 544 for(int i=KeySet.FragmentsPerOrder[Order];i--;) 499 545 for(int j=RowCounter[ KeySet.OrderSet[Order][i] ];j--;) 500 for(int k=ColumnCounter ;k--;)546 for(int k=ColumnCounter[ KeySet.OrderSet[Order][i] ];k--;) 501 547 Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ KeySet.OrderSet[Order][i] ][j][k]; 502 548 else 503 549 for(int i=KeySet.FragmentsPerOrder[Order];i--;) 504 550 for(int j=RowCounter[ KeySet.OrderSet[Order][i] ];j--;) 505 for(int k=ColumnCounter ;k--;)551 for(int k=ColumnCounter[ KeySet.OrderSet[Order][i] ];k--;) 506 552 Matrix[MatrixCounter][j][k] += sign*(Fragments.Matrix[ KeySet.OrderSet[Order][i] ][j][k] + CorrectionFragments->Matrix[ KeySet.OrderSet[Order][i] ][j][k]); 507 553 return true; … … 524 570 // count maximum of columns 525 571 RowCounter[MatrixCounter] = 0; 526 for(int j=0; j < MatrixCounter;j++) // (energy matrix might be bigger than number of atoms in terms of rows) 572 ColumnCounter[MatrixCounter] = 0; 573 for(int j=0; j < MatrixCounter;j++) { // (energy matrix might be bigger than number of atoms in terms of rows) 527 574 if (RowCounter[j] > RowCounter[MatrixCounter]) 528 575 RowCounter[MatrixCounter] = RowCounter[j]; 576 if (ColumnCounter[j] > ColumnCounter[MatrixCounter]) // take maximum of all for last matrix 577 ColumnCounter[MatrixCounter] = ColumnCounter[j]; 578 } 529 579 // allocate last plus one matrix 530 cout << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter << " columns." << endl;580 cout << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter[MatrixCounter] << " columns." << endl; 531 581 Matrix[MatrixCounter] = (double **) Malloc(sizeof(double *)*(RowCounter[MatrixCounter]+1), "MatrixContainer::ParseFragmentMatrix: **Matrix[]"); 532 582 for(int j=0;j<=RowCounter[MatrixCounter];j++) 533 Matrix[MatrixCounter][j] = (double *) Malloc(sizeof(double)*ColumnCounter , "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");534 583 Matrix[MatrixCounter][j] = (double *) Malloc(sizeof(double)*ColumnCounter[MatrixCounter], "MatrixContainer::ParseFragmentMatrix: *Matrix[][]"); 584 535 585 // try independently to parse global energysuffix file if present 536 586 strncpy(filename, name, 1023); … … 589 639 590 640 /** Sums the forces and puts into last element of \a ForceMatrix::Matrix. 591 * \param Matrix MatrixContainer with matrices (LevelCounter by ColumnCounter) with all the energies.641 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies. 592 642 * \param KeySet KeySetContainer with bond Order and association mapping of each fragment to an order 593 643 * \param Order bond order … … 609 659 if (j != -1) { 610 660 //if (j == 0) cout << "Summing onto ion 0, type 0 from fragment " << FragmentNr << ", ion " << l << "." << endl; 611 for(int k=2;k<ColumnCounter ;k++)661 for(int k=2;k<ColumnCounter[MatrixCounter];k++) 612 662 Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ FragmentNr ][l][k]; 613 663 } … … 656 706 input.close(); 657 707 708 ColumnCounter[MatrixCounter] = 0; 709 for(int j=0; j < MatrixCounter;j++) { // (energy matrix might be bigger than number of atoms in terms of rows) 710 if (ColumnCounter[j] > ColumnCounter[MatrixCounter]) // take maximum of all for last matrix 711 ColumnCounter[MatrixCounter] = ColumnCounter[j]; 712 } 713 658 714 // allocate last plus one matrix 659 cout << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter << " columns." << endl;715 cout << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter[MatrixCounter] << " columns." << endl; 660 716 Matrix[MatrixCounter] = (double **) Malloc(sizeof(double *)*(RowCounter[MatrixCounter]+1), "MatrixContainer::ParseFragmentMatrix: **Matrix[]"); 661 717 for(int j=0;j<=RowCounter[MatrixCounter];j++) 662 Matrix[MatrixCounter][j] = (double *) Malloc(sizeof(double)*ColumnCounter, "MatrixContainer::ParseFragmentMatrix: *Matrix[][]"); 718 Matrix[MatrixCounter][j] = (double *) Malloc(sizeof(double)*ColumnCounter[MatrixCounter], "MatrixContainer::ParseFragmentMatrix: *Matrix[][]"); 719 720 // try independently to parse global forcesuffix file if present 721 strncpy(filename, name, 1023); 722 strncat(filename, prefix, 1023-strlen(filename)); 723 strncat(filename, suffix.c_str(), 1023-strlen(filename)); 724 ParseMatrix(filename, skiplines, skipcolumns, MatrixCounter); 725 } 726 727 728 return status; 729 }; 730 731 // ======================================= CLASS HessianMatrix ============================= 732 733 /** Parsing force Indices of each fragment 734 * \param *name directory with \a ForcesFile 735 * \return parsing successful 736 */ 737 bool HessianMatrix::ParseIndices(char *name) 738 { 739 ifstream input; 740 char *FragmentNumber = NULL; 741 char filename[1023]; 742 stringstream line; 743 744 cout << "Parsing hessian indices for " << MatrixCounter << " matrices." << endl; 745 Indices = (int **) Malloc(sizeof(int *)*(MatrixCounter+1), "HessianMatrix::ParseIndices: **Indices"); 746 line << name << FRAGMENTPREFIX << FORCESFILE; 747 input.open(line.str().c_str(), ios::in); 748 //cout << "Opening " << line.str() << " ... " << input << endl; 749 if (input == NULL) { 750 cout << endl << "Unable to open " << line.str() << ", is the directory correct?" << endl; 751 return false; 752 } 753 for (int i=0;(i<MatrixCounter) && (!input.eof());i++) { 754 // get the number of atoms for this fragment 755 input.getline(filename, 1023); 756 line.str(filename); 757 // parse the values 758 Indices[i] = (int *) Malloc(sizeof(int)*RowCounter[i], "HessianMatrix::ParseIndices: *Indices[]"); 759 FragmentNumber = FixedDigitNumber(MatrixCounter, i); 760 //cout << FRAGMENTPREFIX << FragmentNumber << "[" << RowCounter[i] << "]:"; 761 Free((void **)&FragmentNumber, "HessianMatrix::ParseIndices: *FragmentNumber"); 762 for(int j=0;(j<RowCounter[i]) && (!line.eof());j++) { 763 line >> Indices[i][j]; 764 //cout << " " << Indices[i][j]; 765 } 766 //cout << endl; 767 } 768 Indices[MatrixCounter] = (int *) Malloc(sizeof(int)*RowCounter[MatrixCounter], "HessianMatrix::ParseIndices: *Indices[]"); 769 for(int j=RowCounter[MatrixCounter];j--;) { 770 Indices[MatrixCounter][j] = j; 771 } 772 input.close(); 773 return true; 774 }; 775 776 777 /** Sums the hessian entries and puts into last element of \a HessianMatrix::Matrix. 778 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies. 779 * \param KeySet KeySetContainer with bond Order and association mapping of each fragment to an order 780 * \param Order bond order 781 * \param sign +1 or -1 782 * \return true if summing was successful 783 */ 784 bool HessianMatrix::SumSubHessians(class HessianMatrix &Fragments, class KeySetsContainer &KeySet, int Order, double sign) 785 { 786 int FragmentNr; 787 // sum forces 788 for(int i=0;i<KeySet.FragmentsPerOrder[Order];i++) { 789 FragmentNr = KeySet.OrderSet[Order][i]; 790 for(int l=0;l<RowCounter[ FragmentNr ];l++) { 791 int j = Indices[ FragmentNr ][l]; 792 if (j > RowCounter[MatrixCounter]) { 793 cerr << "Current hessian index " << j << " is greater than " << RowCounter[MatrixCounter] << ", where i=" << i << ", Order=" << Order << ", l=" << l << " and FragmentNr=" << FragmentNr << "!" << endl; 794 return false; 795 } 796 if (j != -1) { 797 for(int m=0;m<ColumnCounter[ FragmentNr ];m++) { 798 int k = Indices[ FragmentNr ][m]; 799 if (k > ColumnCounter[MatrixCounter]) { 800 cerr << "Current hessian index " << k << " is greater than " << ColumnCounter[MatrixCounter] << ", where m=" << m << ", j=" << j << ", i=" << i << ", Order=" << Order << ", l=" << l << " and FragmentNr=" << FragmentNr << "!" << endl; 801 return false; 802 } 803 if (k != -1) { 804 //cout << "Adding " << sign*Fragments.Matrix[ FragmentNr ][l][m] << " from [" << l << "][" << m << "] onto [" << j << "][" << k << "]." << endl; 805 Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ FragmentNr ][l][m]; 806 } 807 } 808 } 809 } 810 } 811 return true; 812 }; 813 814 /** Constructor for class HessianMatrix. 815 */ 816 HessianMatrix::HessianMatrix() : MatrixContainer() 817 { 818 IsSymmetric = true; 819 } 820 821 /** Sums the hessian entries with each factor and put into last element of \a ***Matrix. 822 * Sums over "E"-terms to create the "F"-terms 823 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies. 824 * \param KeySet KeySetContainer with bond Order and association mapping of each fragment to an order 825 * \param Order bond order 826 * \return true if summing was successful 827 */ 828 bool HessianMatrix::SumSubManyBodyTerms(class MatrixContainer &MatrixValues, class KeySetsContainer &KeySet, int Order) 829 { 830 // go through each order 831 for (int CurrentFragment=0;CurrentFragment<KeySet.FragmentsPerOrder[Order];CurrentFragment++) { 832 //cout << "Current Fragment is " << CurrentFragment << "/" << KeySet.OrderSet[Order][CurrentFragment] << "." << endl; 833 // then go per order through each suborder and pick together all the terms that contain this fragment 834 for(int SubOrder=0;SubOrder<=Order;SubOrder++) { // go through all suborders up to the desired order 835 for (int j=0;j<KeySet.FragmentsPerOrder[SubOrder];j++) { // go through all possible fragments of size suborder 836 if (KeySet.Contains(KeySet.OrderSet[Order][CurrentFragment], KeySet.OrderSet[SubOrder][j])) { 837 //cout << "Current other fragment is " << j << "/" << KeySet.OrderSet[SubOrder][j] << "." << endl; 838 // if the fragment's indices are all in the current fragment 839 for(int k=0;k<RowCounter[ KeySet.OrderSet[SubOrder][j] ];k++) { // go through all atoms in this fragment 840 int m = MatrixValues.Indices[ KeySet.OrderSet[SubOrder][j] ][k]; 841 //cout << "Current row index is " << k << "/" << m << "." << endl; 842 if (m != -1) { // if it's not an added hydrogen 843 for (int l=0;l<RowCounter[ KeySet.OrderSet[Order][CurrentFragment] ];l++) { // look for the corresponding index in the current fragment 844 //cout << "Comparing " << m << " with " << MatrixValues.Indices[ KeySet.OrderSet[Order][CurrentFragment] ][l] << "." << endl; 845 if (m == MatrixValues.Indices[ KeySet.OrderSet[Order][CurrentFragment] ][l]) { 846 m = l; 847 break; 848 } 849 } 850 //cout << "Corresponding row index for " << k << " in CurrentFragment is " << m << "." << endl; 851 if (m > RowCounter[ KeySet.OrderSet[Order][CurrentFragment] ]) { 852 cerr << "In fragment No. " << KeySet.OrderSet[Order][CurrentFragment] << " current row index " << m << " is greater than " << RowCounter[ KeySet.OrderSet[Order][CurrentFragment] ] << "!" << endl; 853 return false; 854 } 855 856 for(int l=0;l<ColumnCounter[ KeySet.OrderSet[SubOrder][j] ];l++) { 857 int n = MatrixValues.Indices[ KeySet.OrderSet[SubOrder][j] ][l]; 858 //cout << "Current column index is " << l << "/" << n << "." << endl; 859 if (n != -1) { // if it's not an added hydrogen 860 for (int p=0;p<ColumnCounter[ KeySet.OrderSet[Order][CurrentFragment] ];p++) { // look for the corresponding index in the current fragment 861 //cout << "Comparing " << n << " with " << MatrixValues.Indices[ KeySet.OrderSet[Order][CurrentFragment] ][p] << "." << endl; 862 if (n == MatrixValues.Indices[ KeySet.OrderSet[Order][CurrentFragment] ][p]) { 863 n = p; 864 break; 865 } 866 } 867 //cout << "Corresponding column index for " << l << " in CurrentFragment is " << n << "." << endl; 868 if (n > ColumnCounter[ KeySet.OrderSet[Order][CurrentFragment] ]) { 869 cerr << "In fragment No. " << KeySet.OrderSet[Order][CurrentFragment] << " current column index " << n << " is greater than " << ColumnCounter[ KeySet.OrderSet[Order][CurrentFragment] ] << "!" << endl; 870 return false; 871 } 872 if (Order == SubOrder) { // equal order is always copy from Energies 873 //cout << "Adding " << MatrixValues.Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l] << " from [" << k << "][" << l << "] onto [" << m << "][" << n << "]." << endl; 874 Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][m][n] += MatrixValues.Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l]; 875 } else { 876 //cout << "Subtracting " << Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l] << " from [" << k << "][" << l << "] onto [" << m << "][" << n << "]." << endl; 877 Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][m][n] -= Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l]; 878 } 879 } 880 } 881 } 882 //if ((ColumnCounter[ KeySet.OrderSet[SubOrder][j] ]>1) && (RowCounter[0]-1 >= 1)) 883 //cout << "Fragments[ KeySet.OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySet.OrderSet[Order][CurrentFragment] << " ][" << RowCounter[0]-1 << "][" << 1 << "] = " << Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][RowCounter[0]-1][1] << endl; 884 } 885 } else { 886 //cout << "Fragment " << KeySet.OrderSet[SubOrder][j] << " is not contained in fragment " << KeySet.OrderSet[Order][CurrentFragment] << "." << endl; 887 } 888 } 889 } 890 //cout << "Final Fragments[ KeySet.OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySet.OrderSet[Order][CurrentFragment] << " ][" << KeySet.AtomCounter[0]-1 << "][" << 1 << "] = " << Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][KeySet.AtomCounter[0]-1][1] << endl; 891 } 892 893 return true; 894 }; 895 896 /** Calls MatrixContainer::ParseFragmentMatrix() and additionally allocates last plus one matrix. 897 * \param *name directory with files 898 * \param *prefix prefix of each matrix file 899 * \param *suffix suffix of each matrix file 900 * \param skiplines number of inital lines to skip 901 * \param skiplines number of inital columns to skip 902 * \return parsing successful 903 */ 904 bool HessianMatrix::ParseFragmentMatrix(const char *name, const char *prefix, string suffix, int skiplines, int skipcolumns) 905 { 906 char filename[1023]; 907 ifstream input; 908 stringstream file; 909 int nr; 910 bool status = MatrixContainer::ParseFragmentMatrix(name, prefix, suffix, skiplines, skipcolumns); 911 912 if (status) { 913 // count number of atoms for last plus one matrix 914 file << name << FRAGMENTPREFIX << KEYSETFILE; 915 input.open(file.str().c_str(), ios::in); 916 if (input == NULL) { 917 cout << endl << "Unable to open " << file.str() << ", is the directory correct?" << endl; 918 return false; 919 } 920 RowCounter[MatrixCounter] = 0; 921 ColumnCounter[MatrixCounter] = 0; 922 while (!input.eof()) { 923 input.getline(filename, 1023); 924 stringstream zeile(filename); 925 while (!zeile.eof()) { 926 zeile >> nr; 927 //cout << "Current index: " << nr << "." << endl; 928 if (nr > RowCounter[MatrixCounter]) { 929 RowCounter[MatrixCounter] = nr; 930 ColumnCounter[MatrixCounter] = nr; 931 } 932 } 933 } 934 RowCounter[MatrixCounter]++; // nr start at 0, count starts at 1 935 ColumnCounter[MatrixCounter]++; // nr start at 0, count starts at 1 936 input.close(); 937 938 // allocate last plus one matrix 939 cout << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter[MatrixCounter] << " columns." << endl; 940 Matrix[MatrixCounter] = (double **) Malloc(sizeof(double *)*(RowCounter[MatrixCounter]+1), "MatrixContainer::ParseFragmentMatrix: **Matrix[]"); 941 for(int j=0;j<=RowCounter[MatrixCounter];j++) 942 Matrix[MatrixCounter][j] = (double *) Malloc(sizeof(double)*ColumnCounter[MatrixCounter], "MatrixContainer::ParseFragmentMatrix: *Matrix[][]"); 663 943 664 944 // try independently to parse global forcesuffix file if present -
src/parser.hpp
r042f82 r36ec71 19 19 20 20 #define EnergySuffix ".energy.all" 21 #define EnergyFragmentSuffix ".energyfragment.all" 22 #define ForcesSuffix ".forces.all" 23 #define ForceFragmentSuffix ".forcefragment.all" 21 24 #define HcorrectionSuffix ".Hcorrection.all" 22 #define ForcesSuffix ".forces.all" 25 #define HcorrectionFragmentSuffix ".Hcorrectionfragment.all" 26 #define HessianSuffix ".hessian_xx.all" 27 #define HessianFragmentSuffix ".hessianfragment_xx.all" 28 #define OrderSuffix ".Order" 23 29 #define ShieldingSuffix ".sigma_all.csv" 24 30 #define ShieldingPASSuffix ".sigma_all_PAS.csv" 25 31 #define ShieldingFragmentSuffix ".sigma_all_fragment.all" 26 32 #define ShieldingPASFragmentSuffix ".sigma_all_PAS_fragment.all" 33 #define ChiSuffix ".chi_all.csv" 34 #define ChiPASSuffix ".chi_all_PAS.csv" 35 #define ChiFragmentSuffix ".chi_all_fragment.all" 36 #define ChiPASFragmentSuffix ".chi_all_PAS_fragment.all" 27 37 #define TimeSuffix ".speed" 28 #define EnergyFragmentSuffix ".energyfragment.all"29 #define HcorrectionFragmentSuffix ".Hcorrectionfragment.all"30 #define ForceFragmentSuffix ".forcefragment.all"31 #define OrderSuffix ".Order"32 38 33 39 // ======================================= FUNCTIONS ========================================== … … 43 49 double ***Matrix; 44 50 int **Indices; 45 char * Header;51 char **Header; 46 52 int MatrixCounter; 47 53 int *RowCounter; 48 int ColumnCounter;49 54 int *ColumnCounter; 55 50 56 MatrixContainer(); 51 virtual ~MatrixContainer(); 52 57 ~MatrixContainer(); 58 59 bool InitialiseIndices(class MatrixContainer *Matrix = NULL); 53 60 bool ParseMatrix(const char *name, int skiplines, int skipcolumns, int MatrixNr); 54 61 virtual bool ParseFragmentMatrix(const char *name, const char *prefix, string suffix, int skiplines, int skipcolumns); 55 bool AllocateMatrix(c onst char *GivenHeader, int MCounter, int *RCounter, intCCounter);62 bool AllocateMatrix(char **GivenHeader, int MCounter, int *RCounter, int *CCounter); 56 63 bool ResetMatrix(); 57 64 double FindMinValue(); … … 84 91 }; 85 92 93 // ======================================= CLASS HessianMatrix ============================= 94 95 class HessianMatrix : public MatrixContainer { 96 public: 97 HessianMatrix(); 98 //~HessianMatrix(); 99 bool ParseIndices(char *name); 100 bool SumSubManyBodyTerms(class MatrixContainer &MatrixValues, class KeySetsContainer &KeySet, int Order); 101 bool SumSubHessians(class HessianMatrix &Fragments, class KeySetsContainer &KeySet, int Order, double sign); 102 bool ParseFragmentMatrix(const char *name, const char *prefix, string suffix, int skiplines, int skipcolumns); 103 private: 104 bool IsSymmetric; 105 }; 106 86 107 // ======================================= CLASS KeySetsContainer ============================= 87 108
Note:
See TracChangeset
for help on using the changeset viewer.