source: src/parser.cpp@ e670e4

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
Last change on this file since e670e4 was f7c19e, checked in by Frederik Heber <heber@…>, 13 years ago

Some fixes to parsing files.

  • MpqcParser::save() does not store all atoms but those given in the parameters.
  • FIX: MoleculeListClass::AddHydrogenCorrection() and FilePresent() check with bad() and eof() whether file is missing or has ended.
  • Property mode set to 100755
File size: 48.2 KB
RevLine 
[bcf653]1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
[14de469]8/** \file parsing.cpp
9 *
10 * Declarations of various class functions for the parsing of value files.
[6ac7ee]11 *
[14de469]12 */
13
14// ======================================= INCLUDES ==========================================
15
[bf3817]16// include config.h
17#ifdef HAVE_CONFIG_H
18#include <config.h>
19#endif
20
[ad011c]21#include "CodePatterns/MemDebug.hpp"
[112b09]22
[49e1ae]23#include <cstring>
[255829]24#include <fstream>
[4e855e]25#include <iomanip>
[49e1ae]26
[14de469]27#include "parser.hpp"
[255829]28#include "CodePatterns/Log.hpp"
[ad011c]29#include "CodePatterns/Verbose.hpp"
[255829]30#include "Helpers/defs.hpp"
31#include "Helpers/helpers.hpp"
32
33using namespace std;
[14de469]34
35// ======================================= FUNCTIONS ==========================================
36
37/** Test if given filename can be opened.
38 * \param filename name of file
[68cb0f]39 * \param test true - no error message, false - print error
[14de469]40 * \return given file exists
41 */
[68cb0f]42bool FilePresent(const char *filename, bool test)
[14de469]43{
[042f82]44 ifstream input;
45
46 input.open(filename, ios::in);
[f7c19e]47 if (input.fail()) {
[042f82]48 if (!test)
[68f03d]49 DoLog(0) && (Log() << Verbose(0) << endl << "FilePresent: Unable to open " << filename << ", is the directory correct?" << endl);
[042f82]50 return false;
51 }
52 input.close();
53 return true;
[14de469]54};
55
56/** Test the given parameters.
57 * \param argc argument count
58 * \param **argv arguments array
59 * \return given inputdir is valid
60 */
61bool TestParams(int argc, char **argv)
62{
[042f82]63 ifstream input;
64 stringstream line;
[14de469]65
[042f82]66 line << argv[1] << FRAGMENTPREFIX << KEYSETFILE;
67 return FilePresent(line.str().c_str(), false);
[14de469]68};
69
[0d0316]70/** Returns a string with \a i prefixed with 0s to match order of total number of molecules in digits.
71 * \param FragmentNumber total number of fragments to determine necessary number of digits
72 * \param digits number to create with 0 prefixed
73 * \return allocated(!) char array with number in digits, ten base.
74 */
75inline char *FixedDigitNumber(const int FragmentNumber, const int digits)
76{
77 char *returnstring;
78 int number = FragmentNumber;
79 int order = 0;
80 while (number != 0) { // determine number of digits needed
81 number = (int)floor(((double)number / 10.));
82 order++;
83 //Log() << Verbose(0) << "Number is " << number << ", order is " << order << "." << endl;
84 }
85 // allocate string
86 returnstring = new char[order + 2];
87 // terminate and fill string array from end backward
88 returnstring[order] = '\0';
89 number = digits;
90 for (int i=order;i--;) {
91 returnstring[i] = '0' + (char)(number % 10);
92 number = (int)floor(((double)number / 10.));
93 }
94 //Log() << Verbose(0) << returnstring << endl;
95 return returnstring;
96};
97
[14de469]98// ======================================= CLASS MatrixContainer =============================
99
100/** Constructor of MatrixContainer class.
101 */
[97b825]102MatrixContainer::MatrixContainer() :
103 Indices(NULL)
104{
[920c70]105 Header = new char*[1];
106 Matrix = new double**[1]; // one more each for the total molecule
107 RowCounter = new int[1];
108 ColumnCounter = new int[1];
[b12a35]109 Header[0] = NULL;
[042f82]110 Matrix[0] = NULL;
111 RowCounter[0] = -1;
112 MatrixCounter = 0;
[f731ae]113 ColumnCounter[0] = -1;
[14de469]114};
115
116/** Destructor of MatrixContainer class.
117 */
118MatrixContainer::~MatrixContainer() {
[042f82]119 if (Matrix != NULL) {
[8e0c63]120 // free Matrix[MatrixCounter]
121 if ((ColumnCounter != NULL) && (RowCounter != NULL) && (Matrix[MatrixCounter] != NULL))
122 for(int j=RowCounter[MatrixCounter]+1;j--;)
123 delete[](Matrix[MatrixCounter][j]);
124 //if (MatrixCounter != 0)
125 delete[](Matrix[MatrixCounter]);
126 // free all matrices but ultimate one
[042f82]127 for(int i=MatrixCounter;i--;) {
[f731ae]128 if ((ColumnCounter != NULL) && (RowCounter != NULL)) {
[042f82]129 for(int j=RowCounter[i]+1;j--;)
[920c70]130 delete[](Matrix[i][j]);
131 delete[](Matrix[i]);
[042f82]132 }
133 }
[920c70]134 delete[](Matrix);
[042f82]135 }
[8e0c63]136 // free indices
[042f82]137 if (Indices != NULL)
138 for(int i=MatrixCounter+1;i--;) {
[920c70]139 delete[](Indices[i]);
[042f82]140 }
[920c70]141 delete[](Indices);
[14de469]142
[8e0c63]143 // free header and counters
[b12a35]144 if (Header != NULL)
145 for(int i=MatrixCounter+1;i--;)
[920c70]146 delete[](Header[i]);
147 delete[](Header);
148 delete[](RowCounter);
149 delete[](ColumnCounter);
[14de469]150};
151
[f731ae]152/** Either copies index matrix from another MatrixContainer or initialises with trivial mapping if NULL.
153 * This either copies the index matrix or just maps 1 to 1, 2 to 2 and so on for all fragments.
154 * \param *Matrix pointer to other MatrixContainer
155 * \return true - copy/initialisation sucessful, false - dimension false for copying
156 */
157bool MatrixContainer::InitialiseIndices(class MatrixContainer *Matrix)
158{
[a67d19]159 DoLog(0) && (Log() << Verbose(0) << "Initialising indices");
[f731ae]160 if (Matrix == NULL) {
[a67d19]161 DoLog(0) && (Log() << Verbose(0) << " with trivial mapping." << endl);
[920c70]162 Indices = new int*[MatrixCounter + 1];
[f731ae]163 for(int i=MatrixCounter+1;i--;) {
[920c70]164 Indices[i] = new int[RowCounter[i]];
[f731ae]165 for(int j=RowCounter[i];j--;)
166 Indices[i][j] = j;
167 }
168 } else {
[a67d19]169 DoLog(0) && (Log() << Verbose(0) << " from other MatrixContainer." << endl);
[f731ae]170 if (MatrixCounter != Matrix->MatrixCounter)
171 return false;
[920c70]172 Indices = new int*[MatrixCounter + 1];
[f731ae]173 for(int i=MatrixCounter+1;i--;) {
174 if (RowCounter[i] != Matrix->RowCounter[i])
175 return false;
[920c70]176 Indices[i] = new int[Matrix->RowCounter[i]];
[b12a35]177 for(int j=Matrix->RowCounter[i];j--;) {
[f731ae]178 Indices[i][j] = Matrix->Indices[i][j];
[e138de]179 //Log() << Verbose(0) << Indices[i][j] << "\t";
[b12a35]180 }
[e138de]181 //Log() << Verbose(0) << endl;
[f731ae]182 }
183 }
184 return true;
185};
[8f019c]186
187/** Parsing a number of matrices.
[042f82]188 * -# open the matrix file
189 * -# skip some lines (\a skiplines)
190 * -# scan header lines for number of columns
191 * -# scan lines for number of rows
192 * -# allocate matrix
193 * -# loop over found column and row counts and parse in each entry
[4e855e]194 * \param &input input stream
[8f019c]195 * \param skiplines number of inital lines to skip
196 * \param skiplines number of inital columns to skip
197 * \param MatrixNr index number in Matrix array to parse into
[6ac7ee]198 * \return parsing successful
[8f019c]199 */
[4e855e]200bool MatrixContainer::ParseMatrix(std::istream &input, int skiplines, int skipcolumns, int MatrixNr)
[8f019c]201{
[042f82]202 stringstream line;
203 string token;
204 char filename[1023];
205
[f7c19e]206 if (input.fail()) {
[4e855e]207 DoeLog(1) && (eLog()<< Verbose(1) << endl << "MatrixContainer::ParseMatrix: Unable to parse istream." << endl);
[5e8f82]208 //performCriticalExit();
[042f82]209 return false;
210 }
211
[b12a35]212 // parse header
[8e0c63]213 if (Header[MatrixNr] != NULL)
214 delete[] Header[MatrixNr];
[920c70]215 Header[MatrixNr] = new char[1024];
[042f82]216 for (int m=skiplines+1;m--;)
[b12a35]217 input.getline(Header[MatrixNr], 1023);
[8f019c]218
[042f82]219 // scan header for number of columns
[b12a35]220 line.str(Header[MatrixNr]);
[042f82]221 for(int k=skipcolumns;k--;)
[b12a35]222 line >> Header[MatrixNr];
[4e855e]223 Log() << Verbose(0) << line.str() << endl;
[f731ae]224 ColumnCounter[MatrixNr]=0;
[042f82]225 while ( getline(line,token, '\t') ) {
226 if (token.length() > 0)
[f731ae]227 ColumnCounter[MatrixNr]++;
[042f82]228 }
[4e855e]229 Log() << Verbose(0) << line.str() << endl;
230 Log() << Verbose(1) << "ColumnCounter[" << MatrixNr << "]: " << ColumnCounter[MatrixNr] << "." << endl;
[e359a8]231 if (ColumnCounter[MatrixNr] == 0) {
[4e855e]232 DoeLog(0) && (eLog()<< Verbose(0) << "ColumnCounter[" << MatrixNr << "]: " << ColumnCounter[MatrixNr] << " from ostream." << endl);
[e359a8]233 performCriticalExit();
234 }
[8f019c]235
[042f82]236 // scan rest for number of rows/lines
237 RowCounter[MatrixNr]=-1; // counts one line too much
238 while (!input.eof()) {
239 input.getline(filename, 1023);
[4e855e]240 Log() << Verbose(0) << "Comparing: " << strncmp(filename,"MeanForce",9) << endl;
[042f82]241 RowCounter[MatrixNr]++; // then line was not last MeanForce
242 if (strncmp(filename,"MeanForce", 9) == 0) {
243 break;
244 }
245 }
[4e855e]246 Log() << Verbose(1) << "RowCounter[" << MatrixNr << "]: " << RowCounter[MatrixNr] << " from input stream." << endl;
[e359a8]247 if (RowCounter[MatrixNr] == 0) {
[4e855e]248 DoeLog(0) && (eLog()<< Verbose(0) << "RowCounter[" << MatrixNr << "]: " << RowCounter[MatrixNr] << " from input stream." << endl);
[e359a8]249 performCriticalExit();
250 }
[042f82]251
252 // allocate matrix if it's not zero dimension in one direction
[f731ae]253 if ((ColumnCounter[MatrixNr] > 0) && (RowCounter[MatrixNr] > -1)) {
[8e0c63]254 if (Matrix[MatrixNr] != NULL)
255 delete[] Matrix[MatrixNr];
[920c70]256 Matrix[MatrixNr] = new double*[RowCounter[MatrixNr] + 1];
[8e0c63]257 for(int j=0;j<RowCounter[MatrixNr]+1;j++)
258 Matrix[MatrixNr][j] = 0;
259
[042f82]260 // parse in each entry for this matrix
261 input.clear();
262 input.seekg(ios::beg);
263 for (int m=skiplines+1;m--;)
[b12a35]264 input.getline(Header[MatrixNr], 1023); // skip header
265 line.str(Header[MatrixNr]);
[4e855e]266 Log() << Verbose(0) << "Header: " << line.str() << endl;
[042f82]267 for(int k=skipcolumns;k--;) // skip columns in header too
268 line >> filename;
[b12a35]269 strncpy(Header[MatrixNr], line.str().c_str(), 1023);
[042f82]270 for(int j=0;j<RowCounter[MatrixNr];j++) {
[8e0c63]271 if (Matrix[MatrixNr][j] != NULL)
272 delete[] Matrix[MatrixNr][j];
[920c70]273 Matrix[MatrixNr][j] = new double[ColumnCounter[MatrixNr]];
[8e0c63]274 for(int k=0;k<ColumnCounter[MatrixNr];k++)
275 Matrix[MatrixNr][j][k] = 0;
276
[042f82]277 input.getline(filename, 1023);
278 stringstream lines(filename);
[4e855e]279 Log() << Verbose(2) << "Matrix at level " << j << ":";// << filename << endl;
[042f82]280 for(int k=skipcolumns;k--;)
281 lines >> filename;
[f731ae]282 for(int k=0;(k<ColumnCounter[MatrixNr]) && (!lines.eof());k++) {
[042f82]283 lines >> Matrix[MatrixNr][j][k];
[4e855e]284 Log() << Verbose(1) << " " << setprecision(2) << Matrix[MatrixNr][j][k] << endl;
[042f82]285 }
[8e0c63]286 if (Matrix[MatrixNr][ RowCounter[MatrixNr] ] != NULL)
287 delete[] Matrix[MatrixNr][ RowCounter[MatrixNr] ];
[920c70]288 Matrix[MatrixNr][ RowCounter[MatrixNr] ] = new double[ColumnCounter[MatrixNr]];
[f731ae]289 for(int j=ColumnCounter[MatrixNr];j--;)
[042f82]290 Matrix[MatrixNr][ RowCounter[MatrixNr] ][j] = 0.;
291 }
292 } else {
[255829]293 DoeLog(1) && (eLog()<< Verbose(1) << "Matrix nr. " << MatrixNr << " has column and row count of (" << ColumnCounter[MatrixNr] << "," << RowCounter[MatrixNr] << "), could not allocate nor parse!" << endl);
[042f82]294 }
295 return true;
[8f019c]296};
297
[14de469]298/** Parsing a number of matrices.
[68cb0f]299 * -# First, count the number of matrices by counting lines in KEYSETFILE
[6ac7ee]300 * -# Then,
[042f82]301 * -# construct the fragment number
302 * -# open the matrix file
303 * -# skip some lines (\a skiplines)
304 * -# scan header lines for number of columns
305 * -# scan lines for number of rows
306 * -# allocate matrix
307 * -# loop over found column and row counts and parse in each entry
[6ac7ee]308 * -# Finally, allocate one additional matrix (\a MatrixCounter) containing combined or temporary values
[14de469]309 * \param *name directory with files
310 * \param *prefix prefix of each matrix file
311 * \param *suffix suffix of each matrix file
312 * \param skiplines number of inital lines to skip
313 * \param skiplines number of inital columns to skip
[6ac7ee]314 * \return parsing successful
[14de469]315 */
[1c6081]316bool MatrixContainer::ParseFragmentMatrix(const char *name, const char *prefix, string suffix, int skiplines, int skipcolumns)
[14de469]317{
[042f82]318 char filename[1023];
319 ifstream input;
320 char *FragmentNumber = NULL;
321 stringstream file;
322 string token;
323
324 // count the number of matrices
325 MatrixCounter = -1; // we count one too much
326 file << name << FRAGMENTPREFIX << KEYSETFILE;
327 input.open(file.str().c_str(), ios::in);
[f7c19e]328 if (input.bad()) {
[68f03d]329 DoLog(0) && (Log() << Verbose(0) << endl << "MatrixContainer::ParseFragmentMatrix: Unable to open " << file.str() << ", is the directory correct?" << endl);
[042f82]330 return false;
331 }
332 while (!input.eof()) {
333 input.getline(filename, 1023);
334 stringstream zeile(filename);
335 MatrixCounter++;
336 }
337 input.close();
[a67d19]338 DoLog(0) && (Log() << Verbose(0) << "Determined " << MatrixCounter << " fragments." << endl);
[042f82]339
[a67d19]340 DoLog(0) && (Log() << Verbose(0) << "Parsing through each fragment and retrieving " << prefix << suffix << "." << endl);
[920c70]341 delete[](Header);
342 delete[](Matrix);
343 delete[](RowCounter);
344 delete[](ColumnCounter);
345 Header = new char*[MatrixCounter + 1]; // one more each for the total molecule
346 Matrix = new double**[MatrixCounter + 1]; // one more each for the total molecule
347 RowCounter = new int[MatrixCounter + 1];
348 ColumnCounter = new int[MatrixCounter + 1];
[042f82]349 for(int i=MatrixCounter+1;i--;) {
350 Matrix[i] = NULL;
[b12a35]351 Header[i] = NULL;
[042f82]352 RowCounter[i] = -1;
[f731ae]353 ColumnCounter[i] = -1;
[042f82]354 }
355 for(int i=0; i < MatrixCounter;i++) {
356 // open matrix file
357 FragmentNumber = FixedDigitNumber(MatrixCounter, i);
358 file.str(" ");
359 file << name << FRAGMENTPREFIX << FragmentNumber << prefix << suffix;
[4e855e]360 std::ifstream input(file.str().c_str());
[f7c19e]361 DoLog(0) &&( Log() << Verbose(0) << "Opening " << file.str() << " ... " << endl);
[4e855e]362 if (!ParseMatrix(input, skiplines, skipcolumns, i)) {
363 input.close();
[042f82]364 return false;
[4e855e]365 }
366 input.close();
[920c70]367 delete[](FragmentNumber);
[042f82]368 }
369 return true;
[14de469]370};
371
372/** Allocates and resets the memory for a number \a MCounter of matrices.
[b12a35]373 * \param **GivenHeader Header line for each matrix
[14de469]374 * \param MCounter number of matrices
375 * \param *RCounter number of rows for each matrix
[b12a35]376 * \param *CCounter number of columns for each matrix
[14de469]377 * \return Allocation successful
378 */
[b12a35]379bool MatrixContainer::AllocateMatrix(char **GivenHeader, int MCounter, int *RCounter, int *CCounter)
[14de469]380{
[042f82]381 MatrixCounter = MCounter;
[920c70]382 Header = new char*[MatrixCounter + 1];
383 Matrix = new double**[MatrixCounter + 1]; // one more each for the total molecule
384 RowCounter = new int[MatrixCounter + 1];
385 ColumnCounter = new int[MatrixCounter + 1];
[042f82]386 for(int i=MatrixCounter+1;i--;) {
[920c70]387 Header[i] = new char[1024];
[b12a35]388 strncpy(Header[i], GivenHeader[i], 1023);
[042f82]389 RowCounter[i] = RCounter[i];
[f731ae]390 ColumnCounter[i] = CCounter[i];
[920c70]391 Matrix[i] = new double*[RowCounter[i] + 1];
[042f82]392 for(int j=RowCounter[i]+1;j--;) {
[920c70]393 Matrix[i][j] = new double[ColumnCounter[i]];
[f731ae]394 for(int k=ColumnCounter[i];k--;)
[042f82]395 Matrix[i][j][k] = 0.;
396 }
397 }
398 return true;
[14de469]399};
400
401/** Resets all values in MatrixContainer::Matrix.
402 * \return true if successful
403 */
404bool MatrixContainer::ResetMatrix()
405{
[042f82]406 for(int i=MatrixCounter+1;i--;)
407 for(int j=RowCounter[i]+1;j--;)
[f731ae]408 for(int k=ColumnCounter[i];k--;)
[042f82]409 Matrix[i][j][k] = 0.;
410 return true;
[14de469]411};
412
[390248]413/** Scans all elements of MatrixContainer::Matrix for greatest absolute value.
414 * \return greatest value of MatrixContainer::Matrix
415 */
416double MatrixContainer::FindMaxValue()
417{
[042f82]418 double max = Matrix[0][0][0];
419 for(int i=MatrixCounter+1;i--;)
420 for(int j=RowCounter[i]+1;j--;)
[f731ae]421 for(int k=ColumnCounter[i];k--;)
[042f82]422 if (fabs(Matrix[i][j][k]) > max)
423 max = fabs(Matrix[i][j][k]);
424 if (fabs(max) < MYEPSILON)
425 max += MYEPSILON;
[390248]426 return max;
427};
428
429/** Scans all elements of MatrixContainer::Matrix for smallest absolute value.
430 * \return smallest value of MatrixContainer::Matrix
431 */
432double MatrixContainer::FindMinValue()
433{
[042f82]434 double min = Matrix[0][0][0];
435 for(int i=MatrixCounter+1;i--;)
436 for(int j=RowCounter[i]+1;j--;)
[f731ae]437 for(int k=ColumnCounter[i];k--;)
[042f82]438 if (fabs(Matrix[i][j][k]) < min)
439 min = fabs(Matrix[i][j][k]);
440 if (fabs(min) < MYEPSILON)
441 min += MYEPSILON;
442 return min;
[390248]443};
444
[14de469]445/** Sets all values in the last of MatrixContainer::Matrix to \a value.
446 * \param value reset value
447 * \param skipcolumns skip initial columns
448 * \return true if successful
449 */
450bool MatrixContainer::SetLastMatrix(double value, int skipcolumns)
451{
[042f82]452 for(int j=RowCounter[MatrixCounter]+1;j--;)
[f731ae]453 for(int k=skipcolumns;k<ColumnCounter[MatrixCounter];k++)
[042f82]454 Matrix[MatrixCounter][j][k] = value;
455 return true;
[14de469]456};
457
458/** Sets all values in the last of MatrixContainer::Matrix to \a value.
459 * \param **values matrix with each value (must have at least same dimensions!)
460 * \param skipcolumns skip initial columns
461 * \return true if successful
462 */
463bool MatrixContainer::SetLastMatrix(double **values, int skipcolumns)
464{
[042f82]465 for(int j=RowCounter[MatrixCounter]+1;j--;)
[f731ae]466 for(int k=skipcolumns;k<ColumnCounter[MatrixCounter];k++)
[042f82]467 Matrix[MatrixCounter][j][k] = values[j][k];
468 return true;
[14de469]469};
470
[b12a35]471/** Sums the entries with each factor and put into last element of \a ***Matrix.
[6f6a8e]472 * Sums over "E"-terms to create the "F"-terms
[f731ae]473 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies.
[f66195]474 * \param KeySets KeySetContainer with bond Order and association mapping of each fragment to an order
[14de469]475 * \param Order bond order
476 * \return true if summing was successful
477 */
[f66195]478bool MatrixContainer::SumSubManyBodyTerms(class MatrixContainer &MatrixValues, class KeySetsContainer &KeySets, int Order)
[14de469]479{
[042f82]480 // go through each order
[f66195]481 for (int CurrentFragment=0;CurrentFragment<KeySets.FragmentsPerOrder[Order];CurrentFragment++) {
[e138de]482 //Log() << Verbose(0) << "Current Fragment is " << CurrentFragment << "/" << KeySets.OrderSet[Order][CurrentFragment] << "." << endl;
[042f82]483 // then go per order through each suborder and pick together all the terms that contain this fragment
484 for(int SubOrder=0;SubOrder<=Order;SubOrder++) { // go through all suborders up to the desired order
[f66195]485 for (int j=0;j<KeySets.FragmentsPerOrder[SubOrder];j++) { // go through all possible fragments of size suborder
486 if (KeySets.Contains(KeySets.OrderSet[Order][CurrentFragment], KeySets.OrderSet[SubOrder][j])) {
[e138de]487 //Log() << Verbose(0) << "Current other fragment is " << j << "/" << KeySets.OrderSet[SubOrder][j] << "." << endl;
[042f82]488 // if the fragment's indices are all in the current fragment
[f66195]489 for(int k=0;k<RowCounter[ KeySets.OrderSet[SubOrder][j] ];k++) { // go through all atoms in this fragment
490 int m = MatrixValues.Indices[ KeySets.OrderSet[SubOrder][j] ][k];
[e138de]491 //Log() << Verbose(0) << "Current index is " << k << "/" << m << "." << endl;
[042f82]492 if (m != -1) { // if it's not an added hydrogen
[f66195]493 for (int l=0;l<RowCounter[ KeySets.OrderSet[Order][CurrentFragment] ];l++) { // look for the corresponding index in the current fragment
[e138de]494 //Log() << Verbose(0) << "Comparing " << m << " with " << MatrixValues.Indices[ KeySets.OrderSet[Order][CurrentFragment] ][l] << "." << endl;
[f66195]495 if (m == MatrixValues.Indices[ KeySets.OrderSet[Order][CurrentFragment] ][l]) {
[042f82]496 m = l;
497 break;
498 }
499 }
[e138de]500 //Log() << Verbose(0) << "Corresponding index in CurrentFragment is " << m << "." << endl;
[f66195]501 if (m > RowCounter[ KeySets.OrderSet[Order][CurrentFragment] ]) {
[58ed4a]502 DoeLog(0) && (eLog()<< Verbose(0) << "In fragment No. " << KeySets.OrderSet[Order][CurrentFragment] << " current force index " << m << " is greater than " << RowCounter[ KeySets.OrderSet[Order][CurrentFragment] ] << "!" << endl);
[e359a8]503 performCriticalExit();
[042f82]504 return false;
505 }
506 if (Order == SubOrder) { // equal order is always copy from Energies
[f66195]507 for(int l=ColumnCounter[ KeySets.OrderSet[SubOrder][j] ];l--;) // then adds/subtract each column
508 Matrix[ KeySets.OrderSet[Order][CurrentFragment] ][m][l] += MatrixValues.Matrix[ KeySets.OrderSet[SubOrder][j] ][k][l];
[042f82]509 } else {
[f66195]510 for(int l=ColumnCounter[ KeySets.OrderSet[SubOrder][j] ];l--;)
511 Matrix[ KeySets.OrderSet[Order][CurrentFragment] ][m][l] -= Matrix[ KeySets.OrderSet[SubOrder][j] ][k][l];
[042f82]512 }
513 }
[f66195]514 //if ((ColumnCounter[ KeySets.OrderSet[SubOrder][j] ]>1) && (RowCounter[0]-1 >= 1))
[e138de]515 //Log() << Verbose(0) << "Fragments[ KeySets.OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySets.OrderSet[Order][CurrentFragment] << " ][" << RowCounter[0]-1 << "][" << 1 << "] = " << Matrix[ KeySets.OrderSet[Order][CurrentFragment] ][RowCounter[0]-1][1] << endl;
[042f82]516 }
517 } else {
[e138de]518 //Log() << Verbose(0) << "Fragment " << KeySets.OrderSet[SubOrder][j] << " is not contained in fragment " << KeySets.OrderSet[Order][CurrentFragment] << "." << endl;
[042f82]519 }
520 }
521 }
[e138de]522 //Log() << Verbose(0) << "Final Fragments[ KeySets.OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySets.OrderSet[Order][CurrentFragment] << " ][" << KeySets.AtomCounter[0]-1 << "][" << 1 << "] = " << Matrix[ KeySets.OrderSet[Order][CurrentFragment] ][KeySets.AtomCounter[0]-1][1] << endl;
[042f82]523 }
524
525 return true;
[14de469]526};
527
528/** Writes the summed total fragment terms \f$F_{ij}\f$ to file.
529 * \param *name inputdir
530 * \param *prefix prefix before \a EnergySuffix
531 * \return file was written
532 */
533bool MatrixContainer::WriteTotalFragments(const char *name, const char *prefix)
534{
[042f82]535 ofstream output;
536 char *FragmentNumber = NULL;
537
[a67d19]538 DoLog(0) && (Log() << Verbose(0) << "Writing fragment files." << endl);
[042f82]539 for(int i=0;i<MatrixCounter;i++) {
540 stringstream line;
541 FragmentNumber = FixedDigitNumber(MatrixCounter, i);
542 line << name << FRAGMENTPREFIX << FragmentNumber << "/" << prefix;
[920c70]543 delete[](FragmentNumber);
[042f82]544 output.open(line.str().c_str(), ios::out);
545 if (output == NULL) {
[68f03d]546 DoeLog(0) && (eLog()<< Verbose(0) << "MatrixContainer::WriteTotalFragments: Unable to open output energy file " << line.str() << "!" << endl);
[e359a8]547 performCriticalExit();
[042f82]548 return false;
549 }
[b12a35]550 output << Header[i] << endl;
[042f82]551 for(int j=0;j<RowCounter[i];j++) {
[f731ae]552 for(int k=0;k<ColumnCounter[i];k++)
[042f82]553 output << scientific << Matrix[i][j][k] << "\t";
554 output << endl;
555 }
556 output.close();
557 }
558 return true;
[14de469]559};
560
561/** Writes the summed total values in the last matrix to file.
562 * \param *name inputdir
563 * \param *prefix prefix
564 * \param *suffix suffix
565 * \return file was written
566 */
567bool MatrixContainer::WriteLastMatrix(const char *name, const char *prefix, const char *suffix)
568{
[042f82]569 ofstream output;
570 stringstream line;
571
[a67d19]572 DoLog(0) && (Log() << Verbose(0) << "Writing matrix values of " << suffix << "." << endl);
[042f82]573 line << name << prefix << suffix;
574 output.open(line.str().c_str(), ios::out);
575 if (output == NULL) {
[68f03d]576 DoeLog(0) && (eLog()<< Verbose(0) << "MatrixContainer::WriteLastMatrix: Unable to open output matrix file " << line.str() << "!" << endl);
[e359a8]577 performCriticalExit();
[042f82]578 return false;
579 }
[b12a35]580 output << Header[MatrixCounter] << endl;
[042f82]581 for(int j=0;j<RowCounter[MatrixCounter];j++) {
[f731ae]582 for(int k=0;k<ColumnCounter[MatrixCounter];k++)
[042f82]583 output << scientific << Matrix[MatrixCounter][j][k] << "\t";
584 output << endl;
585 }
586 output.close();
587 return true;
[14de469]588};
589
[b23e26]590std::ostream & operator << (std::ostream &ost, const MatrixContainer &m)
591{
592 for (int i=0;i<=m.MatrixCounter;++i) {
593 ost << "Printing matrix " << i << ":" << std::endl;
594 for (int j=0;j<=m.RowCounter[i];++j) {
595 for (int k=0;k<m.ColumnCounter[i];++k) {
596 ost << m.Matrix[i][j][k] << " ";
597 }
598 ost << std::endl;
599 }
600 }
601 ost << std::endl;
602 return ost;
603}
604
[14de469]605// ======================================= CLASS EnergyMatrix =============================
606
607/** Create a trivial energy index mapping.
608 * This just maps 1 to 1, 2 to 2 and so on for all fragments.
609 * \return creation sucessful
610 */
[6ac7ee]611bool EnergyMatrix::ParseIndices()
[14de469]612{
[a67d19]613 DoLog(0) && (Log() << Verbose(0) << "Parsing energy indices." << endl);
[920c70]614 Indices = new int*[MatrixCounter + 1];
[042f82]615 for(int i=MatrixCounter+1;i--;) {
[920c70]616 Indices[i] = new int[RowCounter[i]];
[042f82]617 for(int j=RowCounter[i];j--;)
618 Indices[i][j] = j;
619 }
620 return true;
[14de469]621};
622
623/** Sums the energy with each factor and put into last element of \a EnergyMatrix::Matrix.
[6f6a8e]624 * Sums over the "F"-terms in ANOVA decomposition.
[f731ae]625 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies.
[390248]626 * \param CorrectionFragments MatrixContainer with hydrogen saturation correction per fragments
[f66195]627 * \param KeySets KeySetContainer with bond Order and association mapping of each fragment to an order
[14de469]628 * \param Order bond order
[390248]629 * \parsm sign +1 or -1
[14de469]630 * \return true if summing was successful
631 */
[f66195]632bool EnergyMatrix::SumSubEnergy(class EnergyMatrix &Fragments, class EnergyMatrix *CorrectionFragments, class KeySetsContainer &KeySets, int Order, double sign)
[14de469]633{
[042f82]634 // sum energy
635 if (CorrectionFragments == NULL)
[f66195]636 for(int i=KeySets.FragmentsPerOrder[Order];i--;)
637 for(int j=RowCounter[ KeySets.OrderSet[Order][i] ];j--;)
638 for(int k=ColumnCounter[ KeySets.OrderSet[Order][i] ];k--;)
639 Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ KeySets.OrderSet[Order][i] ][j][k];
[042f82]640 else
[f66195]641 for(int i=KeySets.FragmentsPerOrder[Order];i--;)
642 for(int j=RowCounter[ KeySets.OrderSet[Order][i] ];j--;)
643 for(int k=ColumnCounter[ KeySets.OrderSet[Order][i] ];k--;)
644 Matrix[MatrixCounter][j][k] += sign*(Fragments.Matrix[ KeySets.OrderSet[Order][i] ][j][k] + CorrectionFragments->Matrix[ KeySets.OrderSet[Order][i] ][j][k]);
[042f82]645 return true;
[14de469]646};
647
[8f019c]648/** Calls MatrixContainer::ParseFragmentMatrix() and additionally allocates last plus one matrix.
649 * \param *name directory with files
650 * \param *prefix prefix of each matrix file
651 * \param *suffix suffix of each matrix file
652 * \param skiplines number of inital lines to skip
653 * \param skiplines number of inital columns to skip
654 * \return parsing successful
[6ac7ee]655 */
[1c6081]656bool EnergyMatrix::ParseFragmentMatrix(const char *name, const char *prefix, string suffix, int skiplines, int skipcolumns)
[8f019c]657{
[042f82]658 char filename[1024];
659 bool status = MatrixContainer::ParseFragmentMatrix(name, prefix, suffix, skiplines, skipcolumns);
660
661 if (status) {
662 // count maximum of columns
663 RowCounter[MatrixCounter] = 0;
[f731ae]664 ColumnCounter[MatrixCounter] = 0;
665 for(int j=0; j < MatrixCounter;j++) { // (energy matrix might be bigger than number of atoms in terms of rows)
[042f82]666 if (RowCounter[j] > RowCounter[MatrixCounter])
667 RowCounter[MatrixCounter] = RowCounter[j];
[f731ae]668 if (ColumnCounter[j] > ColumnCounter[MatrixCounter]) // take maximum of all for last matrix
669 ColumnCounter[MatrixCounter] = ColumnCounter[j];
670 }
[042f82]671 // allocate last plus one matrix
[a67d19]672 DoLog(0) && (Log() << Verbose(0) << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter[MatrixCounter] << " columns." << endl);
[920c70]673 Matrix[MatrixCounter] = new double*[RowCounter[MatrixCounter] + 1];
[042f82]674 for(int j=0;j<=RowCounter[MatrixCounter];j++)
[920c70]675 Matrix[MatrixCounter][j] = new double[ColumnCounter[MatrixCounter]];
[8f019c]676
[042f82]677 // try independently to parse global energysuffix file if present
678 strncpy(filename, name, 1023);
679 strncat(filename, prefix, 1023-strlen(filename));
680 strncat(filename, suffix.c_str(), 1023-strlen(filename));
[4e855e]681 std::ifstream input(filename);
682 ParseMatrix(input, skiplines, skipcolumns, MatrixCounter);
683 input.close();
[042f82]684 }
685 return status;
[8f019c]686};
687
[14de469]688// ======================================= CLASS ForceMatrix =============================
689
690/** Parsing force Indices of each fragment
691 * \param *name directory with \a ForcesFile
[6ac7ee]692 * \return parsing successful
[14de469]693 */
[1c6081]694bool ForceMatrix::ParseIndices(const char *name)
[14de469]695{
[042f82]696 ifstream input;
697 char *FragmentNumber = NULL;
698 char filename[1023];
699 stringstream line;
700
[a67d19]701 DoLog(0) && (Log() << Verbose(0) << "Parsing force indices for " << MatrixCounter << " matrices." << endl);
[920c70]702 Indices = new int*[MatrixCounter + 1];
[042f82]703 line << name << FRAGMENTPREFIX << FORCESFILE;
704 input.open(line.str().c_str(), ios::in);
[e138de]705 //Log() << Verbose(0) << "Opening " << line.str() << " ... " << input << endl;
[f7c19e]706 if (input.fail()) {
[68f03d]707 DoLog(0) && (Log() << Verbose(0) << endl << "ForceMatrix::ParseIndices: Unable to open " << line.str() << ", is the directory correct?" << endl);
[042f82]708 return false;
709 }
710 for (int i=0;(i<MatrixCounter) && (!input.eof());i++) {
711 // get the number of atoms for this fragment
712 input.getline(filename, 1023);
713 line.str(filename);
714 // parse the values
[920c70]715 Indices[i] = new int[RowCounter[i]];
[042f82]716 FragmentNumber = FixedDigitNumber(MatrixCounter, i);
[e138de]717 //Log() << Verbose(0) << FRAGMENTPREFIX << FragmentNumber << "[" << RowCounter[i] << "]:";
[920c70]718 delete[](FragmentNumber);
[042f82]719 for(int j=0;(j<RowCounter[i]) && (!line.eof());j++) {
720 line >> Indices[i][j];
[e138de]721 //Log() << Verbose(0) << " " << Indices[i][j];
[042f82]722 }
[e138de]723 //Log() << Verbose(0) << endl;
[042f82]724 }
[920c70]725 Indices[MatrixCounter] = new int[RowCounter[MatrixCounter]];
[042f82]726 for(int j=RowCounter[MatrixCounter];j--;) {
727 Indices[MatrixCounter][j] = j;
728 }
729 input.close();
730 return true;
[14de469]731};
732
733
734/** Sums the forces and puts into last element of \a ForceMatrix::Matrix.
[f731ae]735 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies.
[f66195]736 * \param KeySets KeySetContainer with bond Order and association mapping of each fragment to an order
[14de469]737 * \param Order bond order
[042f82]738 * \param sign +1 or -1
[14de469]739 * \return true if summing was successful
740 */
[f66195]741bool ForceMatrix::SumSubForces(class ForceMatrix &Fragments, class KeySetsContainer &KeySets, int Order, double sign)
[14de469]742{
[042f82]743 int FragmentNr;
744 // sum forces
[f66195]745 for(int i=0;i<KeySets.FragmentsPerOrder[Order];i++) {
746 FragmentNr = KeySets.OrderSet[Order][i];
[042f82]747 for(int l=0;l<RowCounter[ FragmentNr ];l++) {
748 int j = Indices[ FragmentNr ][l];
749 if (j > RowCounter[MatrixCounter]) {
[58ed4a]750 DoeLog(0) && (eLog()<< Verbose(0) << "Current force index " << j << " is greater than " << RowCounter[MatrixCounter] << "!" << endl);
[e359a8]751 performCriticalExit();
[042f82]752 return false;
753 }
754 if (j != -1) {
[e138de]755 //if (j == 0) Log() << Verbose(0) << "Summing onto ion 0, type 0 from fragment " << FragmentNr << ", ion " << l << "." << endl;
[f731ae]756 for(int k=2;k<ColumnCounter[MatrixCounter];k++)
[042f82]757 Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ FragmentNr ][l][k];
758 }
759 }
760 }
761 return true;
[14de469]762};
763
764
[8f019c]765/** Calls MatrixContainer::ParseFragmentMatrix() and additionally allocates last plus one matrix.
766 * \param *name directory with files
767 * \param *prefix prefix of each matrix file
768 * \param *suffix suffix of each matrix file
769 * \param skiplines number of inital lines to skip
770 * \param skiplines number of inital columns to skip
771 * \return parsing successful
[6ac7ee]772 */
[1c6081]773bool ForceMatrix::ParseFragmentMatrix(const char *name, const char *prefix, string suffix, int skiplines, int skipcolumns)
[8f019c]774{
[042f82]775 char filename[1023];
776 ifstream input;
777 stringstream file;
778 int nr;
779 bool status = MatrixContainer::ParseFragmentMatrix(name, prefix, suffix, skiplines, skipcolumns);
780
781 if (status) {
782 // count number of atoms for last plus one matrix
783 file << name << FRAGMENTPREFIX << KEYSETFILE;
784 input.open(file.str().c_str(), ios::in);
[f7c19e]785 if (input.fail()) {
[68f03d]786 DoLog(0) && (Log() << Verbose(0) << endl << "ForceMatrix::ParseFragmentMatrix: Unable to open " << file.str() << ", is the directory correct?" << endl);
[042f82]787 return false;
788 }
789 RowCounter[MatrixCounter] = 0;
790 while (!input.eof()) {
791 input.getline(filename, 1023);
792 stringstream zeile(filename);
793 while (!zeile.eof()) {
794 zeile >> nr;
[735b1c]795 //Log() << Verbose(0) << "Current index: " << getNr() << "." << endl;
[042f82]796 if (nr > RowCounter[MatrixCounter])
797 RowCounter[MatrixCounter] = nr;
798 }
799 }
[5309ba]800 RowCounter[MatrixCounter]++; // Nr start at 0, count starts at 1
[042f82]801 input.close();
802
[f731ae]803 ColumnCounter[MatrixCounter] = 0;
804 for(int j=0; j < MatrixCounter;j++) { // (energy matrix might be bigger than number of atoms in terms of rows)
805 if (ColumnCounter[j] > ColumnCounter[MatrixCounter]) // take maximum of all for last matrix
806 ColumnCounter[MatrixCounter] = ColumnCounter[j];
807 }
[85d278]808
809 // allocate last plus one matrix
[a67d19]810 DoLog(0) && (Log() << Verbose(0) << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter[MatrixCounter] << " columns." << endl);
[920c70]811 Matrix[MatrixCounter] = new double*[RowCounter[MatrixCounter] + 1];
[85d278]812 for(int j=0;j<=RowCounter[MatrixCounter];j++)
[920c70]813 Matrix[MatrixCounter][j] = new double[ColumnCounter[MatrixCounter]];
[85d278]814
815 // try independently to parse global forcesuffix file if present
816 strncpy(filename, name, 1023);
817 strncat(filename, prefix, 1023-strlen(filename));
818 strncat(filename, suffix.c_str(), 1023-strlen(filename));
[4e855e]819 std::ifstream input(filename);
820 ParseMatrix(input, skiplines, skipcolumns, MatrixCounter);
821 input.close();
[85d278]822 }
823
824
825 return status;
826};
827
828// ======================================= CLASS HessianMatrix =============================
829
830/** Parsing force Indices of each fragment
831 * \param *name directory with \a ForcesFile
832 * \return parsing successful
833 */
834bool HessianMatrix::ParseIndices(char *name)
835{
836 ifstream input;
837 char *FragmentNumber = NULL;
838 char filename[1023];
839 stringstream line;
840
[a67d19]841 DoLog(0) && (Log() << Verbose(0) << "Parsing hessian indices for " << MatrixCounter << " matrices." << endl);
[920c70]842 Indices = new int*[MatrixCounter + 1];
[85d278]843 line << name << FRAGMENTPREFIX << FORCESFILE;
844 input.open(line.str().c_str(), ios::in);
[e138de]845 //Log() << Verbose(0) << "Opening " << line.str() << " ... " << input << endl;
[f7c19e]846 if (input.fail()) {
[68f03d]847 DoLog(0) && (Log() << Verbose(0) << endl << "HessianMatrix::ParseIndices: Unable to open " << line.str() << ", is the directory correct?" << endl);
[85d278]848 return false;
849 }
850 for (int i=0;(i<MatrixCounter) && (!input.eof());i++) {
851 // get the number of atoms for this fragment
852 input.getline(filename, 1023);
853 line.str(filename);
854 // parse the values
[920c70]855 Indices[i] = new int[RowCounter[i]];
[85d278]856 FragmentNumber = FixedDigitNumber(MatrixCounter, i);
[e138de]857 //Log() << Verbose(0) << FRAGMENTPREFIX << FragmentNumber << "[" << RowCounter[i] << "]:";
[920c70]858 delete[](FragmentNumber);
[85d278]859 for(int j=0;(j<RowCounter[i]) && (!line.eof());j++) {
860 line >> Indices[i][j];
[e138de]861 //Log() << Verbose(0) << " " << Indices[i][j];
[85d278]862 }
[e138de]863 //Log() << Verbose(0) << endl;
[85d278]864 }
[920c70]865 Indices[MatrixCounter] = new int[RowCounter[MatrixCounter]];
[85d278]866 for(int j=RowCounter[MatrixCounter];j--;) {
867 Indices[MatrixCounter][j] = j;
868 }
869 input.close();
870 return true;
871};
872
873
874/** Sums the hessian entries and puts into last element of \a HessianMatrix::Matrix.
[f731ae]875 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies.
[f66195]876 * \param KeySets KeySetContainer with bond Order and association mapping of each fragment to an order
[85d278]877 * \param Order bond order
878 * \param sign +1 or -1
879 * \return true if summing was successful
880 */
[f66195]881bool HessianMatrix::SumSubHessians(class HessianMatrix &Fragments, class KeySetsContainer &KeySets, int Order, double sign)
[85d278]882{
883 int FragmentNr;
884 // sum forces
[f66195]885 for(int i=0;i<KeySets.FragmentsPerOrder[Order];i++) {
886 FragmentNr = KeySets.OrderSet[Order][i];
[85d278]887 for(int l=0;l<RowCounter[ FragmentNr ];l++) {
888 int j = Indices[ FragmentNr ][l];
889 if (j > RowCounter[MatrixCounter]) {
[58ed4a]890 DoeLog(0) && (eLog()<< Verbose(0) << "Current hessian index " << j << " is greater than " << RowCounter[MatrixCounter] << ", where i=" << i << ", Order=" << Order << ", l=" << l << " and FragmentNr=" << FragmentNr << "!" << endl);
[e359a8]891 performCriticalExit();
[85d278]892 return false;
893 }
894 if (j != -1) {
[f731ae]895 for(int m=0;m<ColumnCounter[ FragmentNr ];m++) {
[85d278]896 int k = Indices[ FragmentNr ][m];
[f731ae]897 if (k > ColumnCounter[MatrixCounter]) {
[58ed4a]898 DoeLog(0) && (eLog()<< Verbose(0) << "Current hessian index " << k << " is greater than " << ColumnCounter[MatrixCounter] << ", where m=" << m << ", j=" << j << ", i=" << i << ", Order=" << Order << ", l=" << l << " and FragmentNr=" << FragmentNr << "!" << endl);
[e359a8]899 performCriticalExit();
[85d278]900 return false;
901 }
902 if (k != -1) {
[e138de]903 //Log() << Verbose(0) << "Adding " << sign*Fragments.Matrix[ FragmentNr ][l][m] << " from [" << l << "][" << m << "] onto [" << j << "][" << k << "]." << endl;
[85d278]904 Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ FragmentNr ][l][m];
905 }
906 }
907 }
908 }
909 }
910 return true;
911};
912
[b12a35]913/** Constructor for class HessianMatrix.
914 */
[97b825]915HessianMatrix::HessianMatrix() :
916 MatrixContainer(),
917 IsSymmetric(true)
918{}
[b12a35]919
920/** Sums the hessian entries with each factor and put into last element of \a ***Matrix.
921 * Sums over "E"-terms to create the "F"-terms
922 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies.
[f66195]923 * \param KeySets KeySetContainer with bond Order and association mapping of each fragment to an order
[b12a35]924 * \param Order bond order
925 * \return true if summing was successful
926 */
[f66195]927bool HessianMatrix::SumSubManyBodyTerms(class MatrixContainer &MatrixValues, class KeySetsContainer &KeySets, int Order)
[b12a35]928{
929 // go through each order
[f66195]930 for (int CurrentFragment=0;CurrentFragment<KeySets.FragmentsPerOrder[Order];CurrentFragment++) {
[e138de]931 //Log() << Verbose(0) << "Current Fragment is " << CurrentFragment << "/" << KeySets.OrderSet[Order][CurrentFragment] << "." << endl;
[b12a35]932 // then go per order through each suborder and pick together all the terms that contain this fragment
933 for(int SubOrder=0;SubOrder<=Order;SubOrder++) { // go through all suborders up to the desired order
[f66195]934 for (int j=0;j<KeySets.FragmentsPerOrder[SubOrder];j++) { // go through all possible fragments of size suborder
935 if (KeySets.Contains(KeySets.OrderSet[Order][CurrentFragment], KeySets.OrderSet[SubOrder][j])) {
[e138de]936 //Log() << Verbose(0) << "Current other fragment is " << j << "/" << KeySets.OrderSet[SubOrder][j] << "." << endl;
[b12a35]937 // if the fragment's indices are all in the current fragment
[f66195]938 for(int k=0;k<RowCounter[ KeySets.OrderSet[SubOrder][j] ];k++) { // go through all atoms in this fragment
939 int m = MatrixValues.Indices[ KeySets.OrderSet[SubOrder][j] ][k];
[e138de]940 //Log() << Verbose(0) << "Current row index is " << k << "/" << m << "." << endl;
[b12a35]941 if (m != -1) { // if it's not an added hydrogen
[f66195]942 for (int l=0;l<RowCounter[ KeySets.OrderSet[Order][CurrentFragment] ];l++) { // look for the corresponding index in the current fragment
[e138de]943 //Log() << Verbose(0) << "Comparing " << m << " with " << MatrixValues.Indices[ KeySets.OrderSet[Order][CurrentFragment] ][l] << "." << endl;
[f66195]944 if (m == MatrixValues.Indices[ KeySets.OrderSet[Order][CurrentFragment] ][l]) {
[b12a35]945 m = l;
946 break;
947 }
948 }
[e138de]949 //Log() << Verbose(0) << "Corresponding row index for " << k << " in CurrentFragment is " << m << "." << endl;
[f66195]950 if (m > RowCounter[ KeySets.OrderSet[Order][CurrentFragment] ]) {
[58ed4a]951 DoeLog(0) && (eLog()<< Verbose(0) << "In fragment No. " << KeySets.OrderSet[Order][CurrentFragment] << " current row index " << m << " is greater than " << RowCounter[ KeySets.OrderSet[Order][CurrentFragment] ] << "!" << endl);
[e359a8]952 performCriticalExit();
[b12a35]953 return false;
954 }
955
[f66195]956 for(int l=0;l<ColumnCounter[ KeySets.OrderSet[SubOrder][j] ];l++) {
957 int n = MatrixValues.Indices[ KeySets.OrderSet[SubOrder][j] ][l];
[e138de]958 //Log() << Verbose(0) << "Current column index is " << l << "/" << n << "." << endl;
[b12a35]959 if (n != -1) { // if it's not an added hydrogen
[f66195]960 for (int p=0;p<ColumnCounter[ KeySets.OrderSet[Order][CurrentFragment] ];p++) { // look for the corresponding index in the current fragment
[e138de]961 //Log() << Verbose(0) << "Comparing " << n << " with " << MatrixValues.Indices[ KeySets.OrderSet[Order][CurrentFragment] ][p] << "." << endl;
[f66195]962 if (n == MatrixValues.Indices[ KeySets.OrderSet[Order][CurrentFragment] ][p]) {
[b12a35]963 n = p;
964 break;
965 }
966 }
[e138de]967 //Log() << Verbose(0) << "Corresponding column index for " << l << " in CurrentFragment is " << n << "." << endl;
[f66195]968 if (n > ColumnCounter[ KeySets.OrderSet[Order][CurrentFragment] ]) {
[58ed4a]969 DoeLog(0) && (eLog()<< Verbose(0) << "In fragment No. " << KeySets.OrderSet[Order][CurrentFragment] << " current column index " << n << " is greater than " << ColumnCounter[ KeySets.OrderSet[Order][CurrentFragment] ] << "!" << endl);
[e359a8]970 performCriticalExit();
[b12a35]971 return false;
972 }
973 if (Order == SubOrder) { // equal order is always copy from Energies
[e138de]974 //Log() << Verbose(0) << "Adding " << MatrixValues.Matrix[ KeySets.OrderSet[SubOrder][j] ][k][l] << " from [" << k << "][" << l << "] onto [" << m << "][" << n << "]." << endl;
[f66195]975 Matrix[ KeySets.OrderSet[Order][CurrentFragment] ][m][n] += MatrixValues.Matrix[ KeySets.OrderSet[SubOrder][j] ][k][l];
[b12a35]976 } else {
[e138de]977 //Log() << Verbose(0) << "Subtracting " << Matrix[ KeySets.OrderSet[SubOrder][j] ][k][l] << " from [" << k << "][" << l << "] onto [" << m << "][" << n << "]." << endl;
[f66195]978 Matrix[ KeySets.OrderSet[Order][CurrentFragment] ][m][n] -= Matrix[ KeySets.OrderSet[SubOrder][j] ][k][l];
[b12a35]979 }
980 }
981 }
982 }
[f66195]983 //if ((ColumnCounter[ KeySets.OrderSet[SubOrder][j] ]>1) && (RowCounter[0]-1 >= 1))
[e138de]984 //Log() << Verbose(0) << "Fragments[ KeySets.OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySets.OrderSet[Order][CurrentFragment] << " ][" << RowCounter[0]-1 << "][" << 1 << "] = " << Matrix[ KeySets.OrderSet[Order][CurrentFragment] ][RowCounter[0]-1][1] << endl;
[b12a35]985 }
986 } else {
[e138de]987 //Log() << Verbose(0) << "Fragment " << KeySets.OrderSet[SubOrder][j] << " is not contained in fragment " << KeySets.OrderSet[Order][CurrentFragment] << "." << endl;
[b12a35]988 }
989 }
990 }
[e138de]991 //Log() << Verbose(0) << "Final Fragments[ KeySets.OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySets.OrderSet[Order][CurrentFragment] << " ][" << KeySets.AtomCounter[0]-1 << "][" << 1 << "] = " << Matrix[ KeySets.OrderSet[Order][CurrentFragment] ][KeySets.AtomCounter[0]-1][1] << endl;
[b12a35]992 }
993
994 return true;
995};
[85d278]996
997/** Calls MatrixContainer::ParseFragmentMatrix() and additionally allocates last plus one matrix.
998 * \param *name directory with files
999 * \param *prefix prefix of each matrix file
1000 * \param *suffix suffix of each matrix file
1001 * \param skiplines number of inital lines to skip
1002 * \param skiplines number of inital columns to skip
1003 * \return parsing successful
1004 */
[36ec71]1005bool HessianMatrix::ParseFragmentMatrix(const char *name, const char *prefix, string suffix, int skiplines, int skipcolumns)
[8f019c]1006{
1007 char filename[1023];
1008 ifstream input;
1009 stringstream file;
1010 int nr;
1011 bool status = MatrixContainer::ParseFragmentMatrix(name, prefix, suffix, skiplines, skipcolumns);
1012
1013 if (status) {
1014 // count number of atoms for last plus one matrix
1015 file << name << FRAGMENTPREFIX << KEYSETFILE;
1016 input.open(file.str().c_str(), ios::in);
[f7c19e]1017 if (input.fail()) {
[68f03d]1018 DoLog(0) && (Log() << Verbose(0) << endl << "HessianMatrix::ParseFragmentMatrix: Unable to open " << file.str() << ", is the directory correct?" << endl);
[8f019c]1019 return false;
1020 }
1021 RowCounter[MatrixCounter] = 0;
[f731ae]1022 ColumnCounter[MatrixCounter] = 0;
[8f019c]1023 while (!input.eof()) {
1024 input.getline(filename, 1023);
1025 stringstream zeile(filename);
1026 while (!zeile.eof()) {
1027 zeile >> nr;
[735b1c]1028 //Log() << Verbose(0) << "Current index: " << getNr() << "." << endl;
[f731ae]1029 if (nr > RowCounter[MatrixCounter]) {
[8f019c]1030 RowCounter[MatrixCounter] = nr;
[f731ae]1031 ColumnCounter[MatrixCounter] = nr;
1032 }
[8f019c]1033 }
1034 }
[5309ba]1035 RowCounter[MatrixCounter]++; // Nr start at 0, count starts at 1
1036 ColumnCounter[MatrixCounter]++; // Nr start at 0, count starts at 1
[8f019c]1037 input.close();
1038
[042f82]1039 // allocate last plus one matrix
[a67d19]1040 DoLog(0) && (Log() << Verbose(0) << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter[MatrixCounter] << " columns." << endl);
[920c70]1041 Matrix[MatrixCounter] = new double*[RowCounter[MatrixCounter] + 1];
[042f82]1042 for(int j=0;j<=RowCounter[MatrixCounter];j++)
[920c70]1043 Matrix[MatrixCounter][j] = new double[ColumnCounter[MatrixCounter]];
[042f82]1044
1045 // try independently to parse global forcesuffix file if present
1046 strncpy(filename, name, 1023);
1047 strncat(filename, prefix, 1023-strlen(filename));
1048 strncat(filename, suffix.c_str(), 1023-strlen(filename));
[4e855e]1049 std::ifstream input(filename);
1050 ParseMatrix(input, skiplines, skipcolumns, MatrixCounter);
1051 input.close();
[042f82]1052 }
1053
1054
1055 return status;
[8f019c]1056};
1057
[14de469]1058// ======================================= CLASS KeySetsContainer =============================
1059
1060/** Constructor of KeySetsContainer class.
1061 */
[97b825]1062KeySetsContainer::KeySetsContainer() :
1063 KeySets(NULL),
1064 AtomCounter(NULL),
1065 FragmentCounter(0),
1066 Order(0),
1067 FragmentsPerOrder(0),
1068 OrderSet(NULL)
1069{};
[14de469]1070
1071/** Destructor of KeySetsContainer class.
1072 */
1073KeySetsContainer::~KeySetsContainer() {
[042f82]1074 for(int i=FragmentCounter;i--;)
[920c70]1075 delete[](KeySets[i]);
[042f82]1076 for(int i=Order;i--;)
[920c70]1077 delete[](OrderSet[i]);
1078 delete[](KeySets);
1079 delete[](OrderSet);
1080 delete[](AtomCounter);
1081 delete[](FragmentsPerOrder);
[14de469]1082};
1083
1084/** Parsing KeySets into array.
1085 * \param *name directory with keyset file
1086 * \param *ACounter number of atoms per fragment
1087 * \param FCounter number of fragments
1088 * \return parsing succesful
1089 */
1090bool KeySetsContainer::ParseKeySets(const char *name, const int *ACounter, const int FCounter) {
[042f82]1091 ifstream input;
1092 char *FragmentNumber = NULL;
1093 stringstream file;
1094 char filename[1023];
1095
1096 FragmentCounter = FCounter;
[a67d19]1097 DoLog(0) && (Log() << Verbose(0) << "Parsing key sets." << endl);
[920c70]1098 KeySets = new int*[FragmentCounter];
[042f82]1099 for(int i=FragmentCounter;i--;)
1100 KeySets[i] = NULL;
1101 file << name << FRAGMENTPREFIX << KEYSETFILE;
1102 input.open(file.str().c_str(), ios::in);
[f7c19e]1103 if (input.fail()) {
[68f03d]1104 DoLog(0) && (Log() << Verbose(0) << endl << "KeySetsContainer::ParseKeySets: Unable to open " << file.str() << ", is the directory correct?" << endl);
[042f82]1105 return false;
1106 }
1107
[920c70]1108 AtomCounter = new int[FragmentCounter];
[042f82]1109 for(int i=0;(i<FragmentCounter) && (!input.eof());i++) {
1110 stringstream line;
1111 AtomCounter[i] = ACounter[i];
1112 // parse the values
[920c70]1113 KeySets[i] = new int[AtomCounter[i]];
[042f82]1114 for(int j=AtomCounter[i];j--;)
1115 KeySets[i][j] = -1;
1116 FragmentNumber = FixedDigitNumber(FragmentCounter, i);
[e138de]1117 //Log() << Verbose(0) << FRAGMENTPREFIX << FragmentNumber << "[" << AtomCounter[i] << "]:";
[920c70]1118 delete[](FragmentNumber);
[042f82]1119 input.getline(filename, 1023);
1120 line.str(filename);
1121 for(int j=0;(j<AtomCounter[i]) && (!line.eof());j++) {
1122 line >> KeySets[i][j];
[e138de]1123 //Log() << Verbose(0) << " " << KeySets[i][j];
[042f82]1124 }
[e138de]1125 //Log() << Verbose(0) << endl;
[042f82]1126 }
1127 input.close();
1128 return true;
[14de469]1129};
1130
1131/** Parse many body terms, associating each fragment to a certain bond order.
1132 * \return parsing succesful
1133 */
1134bool KeySetsContainer::ParseManyBodyTerms()
1135{
[042f82]1136 int Counter;
1137
[a67d19]1138 DoLog(0) && (Log() << Verbose(0) << "Creating Fragment terms." << endl);
[042f82]1139 // scan through all to determine maximum order
1140 Order=0;
1141 for(int i=FragmentCounter;i--;) {
1142 Counter=0;
1143 for(int j=AtomCounter[i];j--;)
1144 if (KeySets[i][j] != -1)
1145 Counter++;
1146 if (Counter > Order)
1147 Order = Counter;
1148 }
[a67d19]1149 DoLog(0) && (Log() << Verbose(0) << "Found Order is " << Order << "." << endl);
[042f82]1150
1151 // scan through all to determine fragments per order
[920c70]1152 FragmentsPerOrder = new int[Order];
[042f82]1153 for(int i=Order;i--;)
1154 FragmentsPerOrder[i] = 0;
1155 for(int i=FragmentCounter;i--;) {
1156 Counter=0;
1157 for(int j=AtomCounter[i];j--;)
1158 if (KeySets[i][j] != -1)
1159 Counter++;
1160 FragmentsPerOrder[Counter-1]++;
1161 }
1162 for(int i=0;i<Order;i++)
[a67d19]1163 DoLog(0) && (Log() << Verbose(0) << "Found No. of Fragments of Order " << i+1 << " is " << FragmentsPerOrder[i] << "." << endl);
[042f82]1164
1165 // scan through all to gather indices to each order set
[920c70]1166 OrderSet = new int*[Order];
[042f82]1167 for(int i=Order;i--;)
[920c70]1168 OrderSet[i] = new int[FragmentsPerOrder[i]];
[042f82]1169 for(int i=Order;i--;)
1170 FragmentsPerOrder[i] = 0;
1171 for(int i=FragmentCounter;i--;) {
1172 Counter=0;
1173 for(int j=AtomCounter[i];j--;)
1174 if (KeySets[i][j] != -1)
1175 Counter++;
1176 OrderSet[Counter-1][FragmentsPerOrder[Counter-1]] = i;
1177 FragmentsPerOrder[Counter-1]++;
1178 }
[a67d19]1179 DoLog(0) && (Log() << Verbose(0) << "Printing OrderSet." << endl);
[042f82]1180 for(int i=0;i<Order;i++) {
1181 for (int j=0;j<FragmentsPerOrder[i];j++) {
[a67d19]1182 DoLog(0) && (Log() << Verbose(0) << " " << OrderSet[i][j]);
[042f82]1183 }
[a67d19]1184 DoLog(0) && (Log() << Verbose(0) << endl);
[042f82]1185 }
[a67d19]1186 DoLog(0) && (Log() << Verbose(0) << endl);
[042f82]1187
1188
1189 return true;
[14de469]1190};
1191
1192/** Compares each entry in \a *SmallerSet if it is containted in \a *GreaterSet.
1193 * \param GreaterSet index to greater set
1194 * \param SmallerSet index to smaller set
1195 * \return true if all keys of SmallerSet contained in GreaterSet
1196 */
1197bool KeySetsContainer::Contains(const int GreaterSet, const int SmallerSet)
1198{
[042f82]1199 bool result = true;
1200 bool intermediate;
1201 if ((GreaterSet < 0) || (SmallerSet < 0) || (GreaterSet > FragmentCounter) || (SmallerSet > FragmentCounter)) // index out of bounds
1202 return false;
1203 for(int i=AtomCounter[SmallerSet];i--;) {
1204 intermediate = false;
1205 for (int j=AtomCounter[GreaterSet];j--;)
1206 intermediate = (intermediate || ((KeySets[SmallerSet][i] == KeySets[GreaterSet][j]) || (KeySets[SmallerSet][i] == -1)));
1207 result = result && intermediate;
1208 }
1209
1210 return result;
[14de469]1211};
1212
1213
1214// ======================================= END =============================================
Note: See TracBrowser for help on using the repository browser.