source: src/Fragmentation/parser.cpp@ 5f61dde

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 Candidate_v1.7.0 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 5f61dde was 5f61dde, checked in by Frederik Heber <heber@…>, 14 years ago

Removed usage of namespace std in module parser.[ch]pp.

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