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
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
33using namespace std;
34
35// ======================================= FUNCTIONS ==========================================
36
37/** Test if given filename can be opened.
38 * \param filename name of file
39 * \param test true - no error message, false - print error
40 * \return given file exists
41 */
42bool FilePresent(const char *filename, bool test)
43{
44 ifstream input;
45
46 input.open(filename, ios::in);
47 if (input.fail()) {
48 if (!test)
49 DoLog(0) && (Log() << Verbose(0) << endl << "FilePresent: Unable to open " << filename << ", is the directory correct?" << endl);
50 return false;
51 }
52 input.close();
53 return true;
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{
63 ifstream input;
64 stringstream line;
65
66 line << argv[1] << FRAGMENTPREFIX << KEYSETFILE;
67 return FilePresent(line.str().c_str(), false);
68};
69
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
98// ======================================= CLASS MatrixContainer =============================
99
100/** Constructor of MatrixContainer class.
101 */
102MatrixContainer::MatrixContainer() :
103 Indices(NULL)
104{
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];
109 Header[0] = NULL;
110 Matrix[0] = NULL;
111 RowCounter[0] = -1;
112 MatrixCounter = 0;
113 ColumnCounter[0] = -1;
114};
115
116/** Destructor of MatrixContainer class.
117 */
118MatrixContainer::~MatrixContainer() {
119 if (Matrix != NULL) {
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
127 for(int i=MatrixCounter;i--;) {
128 if ((ColumnCounter != NULL) && (RowCounter != NULL)) {
129 for(int j=RowCounter[i]+1;j--;)
130 delete[](Matrix[i][j]);
131 delete[](Matrix[i]);
132 }
133 }
134 delete[](Matrix);
135 }
136 // free indices
137 if (Indices != NULL)
138 for(int i=MatrixCounter+1;i--;) {
139 delete[](Indices[i]);
140 }
141 delete[](Indices);
142
143 // free header and counters
144 if (Header != NULL)
145 for(int i=MatrixCounter+1;i--;)
146 delete[](Header[i]);
147 delete[](Header);
148 delete[](RowCounter);
149 delete[](ColumnCounter);
150};
151
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{
159 DoLog(0) && (Log() << Verbose(0) << "Initialising indices");
160 if (Matrix == NULL) {
161 DoLog(0) && (Log() << Verbose(0) << " with trivial mapping." << endl);
162 Indices = new int*[MatrixCounter + 1];
163 for(int i=MatrixCounter+1;i--;) {
164 Indices[i] = new int[RowCounter[i]];
165 for(int j=RowCounter[i];j--;)
166 Indices[i][j] = j;
167 }
168 } else {
169 DoLog(0) && (Log() << Verbose(0) << " from other MatrixContainer." << endl);
170 if (MatrixCounter != Matrix->MatrixCounter)
171 return false;
172 Indices = new int*[MatrixCounter + 1];
173 for(int i=MatrixCounter+1;i--;) {
174 if (RowCounter[i] != Matrix->RowCounter[i])
175 return false;
176 Indices[i] = new int[Matrix->RowCounter[i]];
177 for(int j=Matrix->RowCounter[i];j--;) {
178 Indices[i][j] = Matrix->Indices[i][j];
179 //Log() << Verbose(0) << Indices[i][j] << "\t";
180 }
181 //Log() << Verbose(0) << endl;
182 }
183 }
184 return true;
185};
186
187/** Parsing a number of matrices.
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
194 * \param &input input stream
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
198 * \return parsing successful
199 */
200bool MatrixContainer::ParseMatrix(std::istream &input, int skiplines, int skipcolumns, int MatrixNr)
201{
202 stringstream line;
203 string token;
204 char filename[1023];
205
206 if (input.fail()) {
207 DoeLog(1) && (eLog()<< Verbose(1) << endl << "MatrixContainer::ParseMatrix: Unable to parse istream." << endl);
208 //performCriticalExit();
209 return false;
210 }
211
212 // parse header
213 if (Header[MatrixNr] != NULL)
214 delete[] Header[MatrixNr];
215 Header[MatrixNr] = new char[1024];
216 for (int m=skiplines+1;m--;)
217 input.getline(Header[MatrixNr], 1023);
218
219 // scan header for number of columns
220 line.str(Header[MatrixNr]);
221 for(int k=skipcolumns;k--;)
222 line >> Header[MatrixNr];
223 Log() << Verbose(0) << line.str() << endl;
224 ColumnCounter[MatrixNr]=0;
225 while ( getline(line,token, '\t') ) {
226 if (token.length() > 0)
227 ColumnCounter[MatrixNr]++;
228 }
229 Log() << Verbose(0) << line.str() << endl;
230 Log() << Verbose(1) << "ColumnCounter[" << MatrixNr << "]: " << ColumnCounter[MatrixNr] << "." << endl;
231 if (ColumnCounter[MatrixNr] == 0) {
232 DoeLog(0) && (eLog()<< Verbose(0) << "ColumnCounter[" << MatrixNr << "]: " << ColumnCounter[MatrixNr] << " from ostream." << endl);
233 performCriticalExit();
234 }
235
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);
240 Log() << Verbose(0) << "Comparing: " << strncmp(filename,"MeanForce",9) << endl;
241 RowCounter[MatrixNr]++; // then line was not last MeanForce
242 if (strncmp(filename,"MeanForce", 9) == 0) {
243 break;
244 }
245 }
246 Log() << Verbose(1) << "RowCounter[" << MatrixNr << "]: " << RowCounter[MatrixNr] << " from input stream." << endl;
247 if (RowCounter[MatrixNr] == 0) {
248 DoeLog(0) && (eLog()<< Verbose(0) << "RowCounter[" << MatrixNr << "]: " << RowCounter[MatrixNr] << " from input stream." << endl);
249 performCriticalExit();
250 }
251
252 // allocate matrix if it's not zero dimension in one direction
253 if ((ColumnCounter[MatrixNr] > 0) && (RowCounter[MatrixNr] > -1)) {
254 if (Matrix[MatrixNr] != NULL)
255 delete[] Matrix[MatrixNr];
256 Matrix[MatrixNr] = new double*[RowCounter[MatrixNr] + 1];
257 for(int j=0;j<RowCounter[MatrixNr]+1;j++)
258 Matrix[MatrixNr][j] = 0;
259
260 // parse in each entry for this matrix
261 input.clear();
262 input.seekg(ios::beg);
263 for (int m=skiplines+1;m--;)
264 input.getline(Header[MatrixNr], 1023); // skip header
265 line.str(Header[MatrixNr]);
266 Log() << Verbose(0) << "Header: " << line.str() << endl;
267 for(int k=skipcolumns;k--;) // skip columns in header too
268 line >> filename;
269 strncpy(Header[MatrixNr], line.str().c_str(), 1023);
270 for(int j=0;j<RowCounter[MatrixNr];j++) {
271 if (Matrix[MatrixNr][j] != NULL)
272 delete[] Matrix[MatrixNr][j];
273 Matrix[MatrixNr][j] = new double[ColumnCounter[MatrixNr]];
274 for(int k=0;k<ColumnCounter[MatrixNr];k++)
275 Matrix[MatrixNr][j][k] = 0;
276
277 input.getline(filename, 1023);
278 stringstream lines(filename);
279 Log() << Verbose(2) << "Matrix at level " << j << ":";// << filename << endl;
280 for(int k=skipcolumns;k--;)
281 lines >> filename;
282 for(int k=0;(k<ColumnCounter[MatrixNr]) && (!lines.eof());k++) {
283 lines >> Matrix[MatrixNr][j][k];
284 Log() << Verbose(1) << " " << setprecision(2) << Matrix[MatrixNr][j][k] << endl;
285 }
286 if (Matrix[MatrixNr][ RowCounter[MatrixNr] ] != NULL)
287 delete[] Matrix[MatrixNr][ RowCounter[MatrixNr] ];
288 Matrix[MatrixNr][ RowCounter[MatrixNr] ] = new double[ColumnCounter[MatrixNr]];
289 for(int j=ColumnCounter[MatrixNr];j--;)
290 Matrix[MatrixNr][ RowCounter[MatrixNr] ][j] = 0.;
291 }
292 } else {
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);
294 }
295 return true;
296};
297
298/** Parsing a number of matrices.
299 * -# First, count the number of matrices by counting lines in KEYSETFILE
300 * -# Then,
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
308 * -# Finally, allocate one additional matrix (\a MatrixCounter) containing combined or temporary values
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
314 * \return parsing successful
315 */
316bool MatrixContainer::ParseFragmentMatrix(const char *name, const char *prefix, string suffix, int skiplines, int skipcolumns)
317{
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);
328 if (input.bad()) {
329 DoLog(0) && (Log() << Verbose(0) << endl << "MatrixContainer::ParseFragmentMatrix: Unable to open " << file.str() << ", is the directory correct?" << endl);
330 return false;
331 }
332 while (!input.eof()) {
333 input.getline(filename, 1023);
334 stringstream zeile(filename);
335 MatrixCounter++;
336 }
337 input.close();
338 DoLog(0) && (Log() << Verbose(0) << "Determined " << MatrixCounter << " fragments." << endl);
339
340 DoLog(0) && (Log() << Verbose(0) << "Parsing through each fragment and retrieving " << prefix << suffix << "." << endl);
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];
349 for(int i=MatrixCounter+1;i--;) {
350 Matrix[i] = NULL;
351 Header[i] = NULL;
352 RowCounter[i] = -1;
353 ColumnCounter[i] = -1;
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;
360 std::ifstream input(file.str().c_str());
361 DoLog(0) &&( Log() << Verbose(0) << "Opening " << file.str() << " ... " << endl);
362 if (!ParseMatrix(input, skiplines, skipcolumns, i)) {
363 input.close();
364 return false;
365 }
366 input.close();
367 delete[](FragmentNumber);
368 }
369 return true;
370};
371
372/** Allocates and resets the memory for a number \a MCounter of matrices.
373 * \param **GivenHeader Header line for each matrix
374 * \param MCounter number of matrices
375 * \param *RCounter number of rows for each matrix
376 * \param *CCounter number of columns for each matrix
377 * \return Allocation successful
378 */
379bool MatrixContainer::AllocateMatrix(char **GivenHeader, int MCounter, int *RCounter, int *CCounter)
380{
381 MatrixCounter = MCounter;
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];
386 for(int i=MatrixCounter+1;i--;) {
387 Header[i] = new char[1024];
388 strncpy(Header[i], GivenHeader[i], 1023);
389 RowCounter[i] = RCounter[i];
390 ColumnCounter[i] = CCounter[i];
391 Matrix[i] = new double*[RowCounter[i] + 1];
392 for(int j=RowCounter[i]+1;j--;) {
393 Matrix[i][j] = new double[ColumnCounter[i]];
394 for(int k=ColumnCounter[i];k--;)
395 Matrix[i][j][k] = 0.;
396 }
397 }
398 return true;
399};
400
401/** Resets all values in MatrixContainer::Matrix.
402 * \return true if successful
403 */
404bool MatrixContainer::ResetMatrix()
405{
406 for(int i=MatrixCounter+1;i--;)
407 for(int j=RowCounter[i]+1;j--;)
408 for(int k=ColumnCounter[i];k--;)
409 Matrix[i][j][k] = 0.;
410 return true;
411};
412
413/** Scans all elements of MatrixContainer::Matrix for greatest absolute value.
414 * \return greatest value of MatrixContainer::Matrix
415 */
416double MatrixContainer::FindMaxValue()
417{
418 double max = Matrix[0][0][0];
419 for(int i=MatrixCounter+1;i--;)
420 for(int j=RowCounter[i]+1;j--;)
421 for(int k=ColumnCounter[i];k--;)
422 if (fabs(Matrix[i][j][k]) > max)
423 max = fabs(Matrix[i][j][k]);
424 if (fabs(max) < MYEPSILON)
425 max += MYEPSILON;
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{
434 double min = Matrix[0][0][0];
435 for(int i=MatrixCounter+1;i--;)
436 for(int j=RowCounter[i]+1;j--;)
437 for(int k=ColumnCounter[i];k--;)
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;
443};
444
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{
452 for(int j=RowCounter[MatrixCounter]+1;j--;)
453 for(int k=skipcolumns;k<ColumnCounter[MatrixCounter];k++)
454 Matrix[MatrixCounter][j][k] = value;
455 return true;
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{
465 for(int j=RowCounter[MatrixCounter]+1;j--;)
466 for(int k=skipcolumns;k<ColumnCounter[MatrixCounter];k++)
467 Matrix[MatrixCounter][j][k] = values[j][k];
468 return true;
469};
470
471/** Sums the entries with each factor and put into last element of \a ***Matrix.
472 * Sums over "E"-terms to create the "F"-terms
473 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies.
474 * \param KeySets KeySetContainer with bond Order and association mapping of each fragment to an order
475 * \param Order bond order
476 * \return true if summing was successful
477 */
478bool MatrixContainer::SumSubManyBodyTerms(class MatrixContainer &MatrixValues, class KeySetsContainer &KeySets, int Order)
479{
480 // go through each order
481 for (int CurrentFragment=0;CurrentFragment<KeySets.FragmentsPerOrder[Order];CurrentFragment++) {
482 //Log() << Verbose(0) << "Current Fragment is " << CurrentFragment << "/" << KeySets.OrderSet[Order][CurrentFragment] << "." << endl;
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
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])) {
487 //Log() << Verbose(0) << "Current other fragment is " << j << "/" << KeySets.OrderSet[SubOrder][j] << "." << endl;
488 // if the fragment's indices are all in the current fragment
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];
491 //Log() << Verbose(0) << "Current index is " << k << "/" << m << "." << endl;
492 if (m != -1) { // if it's not an added hydrogen
493 for (int l=0;l<RowCounter[ KeySets.OrderSet[Order][CurrentFragment] ];l++) { // look for the corresponding index in the current fragment
494 //Log() << Verbose(0) << "Comparing " << m << " with " << MatrixValues.Indices[ KeySets.OrderSet[Order][CurrentFragment] ][l] << "." << endl;
495 if (m == MatrixValues.Indices[ KeySets.OrderSet[Order][CurrentFragment] ][l]) {
496 m = l;
497 break;
498 }
499 }
500 //Log() << Verbose(0) << "Corresponding index in CurrentFragment is " << m << "." << endl;
501 if (m > RowCounter[ KeySets.OrderSet[Order][CurrentFragment] ]) {
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);
503 performCriticalExit();
504 return false;
505 }
506 if (Order == SubOrder) { // equal order is always copy from Energies
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];
509 } else {
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];
512 }
513 }
514 //if ((ColumnCounter[ KeySets.OrderSet[SubOrder][j] ]>1) && (RowCounter[0]-1 >= 1))
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;
516 }
517 } else {
518 //Log() << Verbose(0) << "Fragment " << KeySets.OrderSet[SubOrder][j] << " is not contained in fragment " << KeySets.OrderSet[Order][CurrentFragment] << "." << endl;
519 }
520 }
521 }
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;
523 }
524
525 return true;
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{
535 ofstream output;
536 char *FragmentNumber = NULL;
537
538 DoLog(0) && (Log() << Verbose(0) << "Writing fragment files." << endl);
539 for(int i=0;i<MatrixCounter;i++) {
540 stringstream line;
541 FragmentNumber = FixedDigitNumber(MatrixCounter, i);
542 line << name << FRAGMENTPREFIX << FragmentNumber << "/" << prefix;
543 delete[](FragmentNumber);
544 output.open(line.str().c_str(), ios::out);
545 if (output == NULL) {
546 DoeLog(0) && (eLog()<< Verbose(0) << "MatrixContainer::WriteTotalFragments: Unable to open output energy file " << line.str() << "!" << endl);
547 performCriticalExit();
548 return false;
549 }
550 output << Header[i] << endl;
551 for(int j=0;j<RowCounter[i];j++) {
552 for(int k=0;k<ColumnCounter[i];k++)
553 output << scientific << Matrix[i][j][k] << "\t";
554 output << endl;
555 }
556 output.close();
557 }
558 return true;
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{
569 ofstream output;
570 stringstream line;
571
572 DoLog(0) && (Log() << Verbose(0) << "Writing matrix values of " << suffix << "." << endl);
573 line << name << prefix << suffix;
574 output.open(line.str().c_str(), ios::out);
575 if (output == NULL) {
576 DoeLog(0) && (eLog()<< Verbose(0) << "MatrixContainer::WriteLastMatrix: Unable to open output matrix file " << line.str() << "!" << endl);
577 performCriticalExit();
578 return false;
579 }
580 output << Header[MatrixCounter] << endl;
581 for(int j=0;j<RowCounter[MatrixCounter];j++) {
582 for(int k=0;k<ColumnCounter[MatrixCounter];k++)
583 output << scientific << Matrix[MatrixCounter][j][k] << "\t";
584 output << endl;
585 }
586 output.close();
587 return true;
588};
589
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
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 */
611bool EnergyMatrix::ParseIndices()
612{
613 DoLog(0) && (Log() << Verbose(0) << "Parsing energy indices." << endl);
614 Indices = new int*[MatrixCounter + 1];
615 for(int i=MatrixCounter+1;i--;) {
616 Indices[i] = new int[RowCounter[i]];
617 for(int j=RowCounter[i];j--;)
618 Indices[i][j] = j;
619 }
620 return true;
621};
622
623/** Sums the energy with each factor and put into last element of \a EnergyMatrix::Matrix.
624 * Sums over the "F"-terms in ANOVA decomposition.
625 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies.
626 * \param CorrectionFragments MatrixContainer with hydrogen saturation correction per fragments
627 * \param KeySets KeySetContainer with bond Order and association mapping of each fragment to an order
628 * \param Order bond order
629 * \parsm sign +1 or -1
630 * \return true if summing was successful
631 */
632bool EnergyMatrix::SumSubEnergy(class EnergyMatrix &Fragments, class EnergyMatrix *CorrectionFragments, class KeySetsContainer &KeySets, int Order, double sign)
633{
634 // sum energy
635 if (CorrectionFragments == NULL)
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];
640 else
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]);
645 return true;
646};
647
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
655 */
656bool EnergyMatrix::ParseFragmentMatrix(const char *name, const char *prefix, string suffix, int skiplines, int skipcolumns)
657{
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;
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)
666 if (RowCounter[j] > RowCounter[MatrixCounter])
667 RowCounter[MatrixCounter] = RowCounter[j];
668 if (ColumnCounter[j] > ColumnCounter[MatrixCounter]) // take maximum of all for last matrix
669 ColumnCounter[MatrixCounter] = ColumnCounter[j];
670 }
671 // allocate last plus one matrix
672 DoLog(0) && (Log() << Verbose(0) << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter[MatrixCounter] << " columns." << endl);
673 Matrix[MatrixCounter] = new double*[RowCounter[MatrixCounter] + 1];
674 for(int j=0;j<=RowCounter[MatrixCounter];j++)
675 Matrix[MatrixCounter][j] = new double[ColumnCounter[MatrixCounter]];
676
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));
681 std::ifstream input(filename);
682 ParseMatrix(input, skiplines, skipcolumns, MatrixCounter);
683 input.close();
684 }
685 return status;
686};
687
688// ======================================= CLASS ForceMatrix =============================
689
690/** Parsing force Indices of each fragment
691 * \param *name directory with \a ForcesFile
692 * \return parsing successful
693 */
694bool ForceMatrix::ParseIndices(const char *name)
695{
696 ifstream input;
697 char *FragmentNumber = NULL;
698 char filename[1023];
699 stringstream line;
700
701 DoLog(0) && (Log() << Verbose(0) << "Parsing force indices for " << MatrixCounter << " matrices." << endl);
702 Indices = new int*[MatrixCounter + 1];
703 line << name << FRAGMENTPREFIX << FORCESFILE;
704 input.open(line.str().c_str(), ios::in);
705 //Log() << Verbose(0) << "Opening " << line.str() << " ... " << input << endl;
706 if (input.fail()) {
707 DoLog(0) && (Log() << Verbose(0) << endl << "ForceMatrix::ParseIndices: Unable to open " << line.str() << ", is the directory correct?" << endl);
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
715 Indices[i] = new int[RowCounter[i]];
716 FragmentNumber = FixedDigitNumber(MatrixCounter, i);
717 //Log() << Verbose(0) << FRAGMENTPREFIX << FragmentNumber << "[" << RowCounter[i] << "]:";
718 delete[](FragmentNumber);
719 for(int j=0;(j<RowCounter[i]) && (!line.eof());j++) {
720 line >> Indices[i][j];
721 //Log() << Verbose(0) << " " << Indices[i][j];
722 }
723 //Log() << Verbose(0) << endl;
724 }
725 Indices[MatrixCounter] = new int[RowCounter[MatrixCounter]];
726 for(int j=RowCounter[MatrixCounter];j--;) {
727 Indices[MatrixCounter][j] = j;
728 }
729 input.close();
730 return true;
731};
732
733
734/** Sums the forces and puts into last element of \a ForceMatrix::Matrix.
735 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies.
736 * \param KeySets KeySetContainer with bond Order and association mapping of each fragment to an order
737 * \param Order bond order
738 * \param sign +1 or -1
739 * \return true if summing was successful
740 */
741bool ForceMatrix::SumSubForces(class ForceMatrix &Fragments, class KeySetsContainer &KeySets, int Order, double sign)
742{
743 int FragmentNr;
744 // sum forces
745 for(int i=0;i<KeySets.FragmentsPerOrder[Order];i++) {
746 FragmentNr = KeySets.OrderSet[Order][i];
747 for(int l=0;l<RowCounter[ FragmentNr ];l++) {
748 int j = Indices[ FragmentNr ][l];
749 if (j > RowCounter[MatrixCounter]) {
750 DoeLog(0) && (eLog()<< Verbose(0) << "Current force index " << j << " is greater than " << RowCounter[MatrixCounter] << "!" << endl);
751 performCriticalExit();
752 return false;
753 }
754 if (j != -1) {
755 //if (j == 0) Log() << Verbose(0) << "Summing onto ion 0, type 0 from fragment " << FragmentNr << ", ion " << l << "." << endl;
756 for(int k=2;k<ColumnCounter[MatrixCounter];k++)
757 Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ FragmentNr ][l][k];
758 }
759 }
760 }
761 return true;
762};
763
764
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
772 */
773bool ForceMatrix::ParseFragmentMatrix(const char *name, const char *prefix, string suffix, int skiplines, int skipcolumns)
774{
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);
785 if (input.fail()) {
786 DoLog(0) && (Log() << Verbose(0) << endl << "ForceMatrix::ParseFragmentMatrix: Unable to open " << file.str() << ", is the directory correct?" << endl);
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;
795 //Log() << Verbose(0) << "Current index: " << getNr() << "." << endl;
796 if (nr > RowCounter[MatrixCounter])
797 RowCounter[MatrixCounter] = nr;
798 }
799 }
800 RowCounter[MatrixCounter]++; // Nr start at 0, count starts at 1
801 input.close();
802
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 }
808
809 // allocate last plus one matrix
810 DoLog(0) && (Log() << Verbose(0) << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter[MatrixCounter] << " columns." << endl);
811 Matrix[MatrixCounter] = new double*[RowCounter[MatrixCounter] + 1];
812 for(int j=0;j<=RowCounter[MatrixCounter];j++)
813 Matrix[MatrixCounter][j] = new double[ColumnCounter[MatrixCounter]];
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));
819 std::ifstream input(filename);
820 ParseMatrix(input, skiplines, skipcolumns, MatrixCounter);
821 input.close();
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
841 DoLog(0) && (Log() << Verbose(0) << "Parsing hessian indices for " << MatrixCounter << " matrices." << endl);
842 Indices = new int*[MatrixCounter + 1];
843 line << name << FRAGMENTPREFIX << FORCESFILE;
844 input.open(line.str().c_str(), ios::in);
845 //Log() << Verbose(0) << "Opening " << line.str() << " ... " << input << endl;
846 if (input.fail()) {
847 DoLog(0) && (Log() << Verbose(0) << endl << "HessianMatrix::ParseIndices: Unable to open " << line.str() << ", is the directory correct?" << endl);
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
855 Indices[i] = new int[RowCounter[i]];
856 FragmentNumber = FixedDigitNumber(MatrixCounter, i);
857 //Log() << Verbose(0) << FRAGMENTPREFIX << FragmentNumber << "[" << RowCounter[i] << "]:";
858 delete[](FragmentNumber);
859 for(int j=0;(j<RowCounter[i]) && (!line.eof());j++) {
860 line >> Indices[i][j];
861 //Log() << Verbose(0) << " " << Indices[i][j];
862 }
863 //Log() << Verbose(0) << endl;
864 }
865 Indices[MatrixCounter] = new int[RowCounter[MatrixCounter]];
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.
875 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies.
876 * \param KeySets KeySetContainer with bond Order and association mapping of each fragment to an order
877 * \param Order bond order
878 * \param sign +1 or -1
879 * \return true if summing was successful
880 */
881bool HessianMatrix::SumSubHessians(class HessianMatrix &Fragments, class KeySetsContainer &KeySets, int Order, double sign)
882{
883 int FragmentNr;
884 // sum forces
885 for(int i=0;i<KeySets.FragmentsPerOrder[Order];i++) {
886 FragmentNr = KeySets.OrderSet[Order][i];
887 for(int l=0;l<RowCounter[ FragmentNr ];l++) {
888 int j = Indices[ FragmentNr ][l];
889 if (j > RowCounter[MatrixCounter]) {
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);
891 performCriticalExit();
892 return false;
893 }
894 if (j != -1) {
895 for(int m=0;m<ColumnCounter[ FragmentNr ];m++) {
896 int k = Indices[ FragmentNr ][m];
897 if (k > ColumnCounter[MatrixCounter]) {
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);
899 performCriticalExit();
900 return false;
901 }
902 if (k != -1) {
903 //Log() << Verbose(0) << "Adding " << sign*Fragments.Matrix[ FragmentNr ][l][m] << " from [" << l << "][" << m << "] onto [" << j << "][" << k << "]." << endl;
904 Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ FragmentNr ][l][m];
905 }
906 }
907 }
908 }
909 }
910 return true;
911};
912
913/** Constructor for class HessianMatrix.
914 */
915HessianMatrix::HessianMatrix() :
916 MatrixContainer(),
917 IsSymmetric(true)
918{}
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.
923 * \param KeySets KeySetContainer with bond Order and association mapping of each fragment to an order
924 * \param Order bond order
925 * \return true if summing was successful
926 */
927bool HessianMatrix::SumSubManyBodyTerms(class MatrixContainer &MatrixValues, class KeySetsContainer &KeySets, int Order)
928{
929 // go through each order
930 for (int CurrentFragment=0;CurrentFragment<KeySets.FragmentsPerOrder[Order];CurrentFragment++) {
931 //Log() << Verbose(0) << "Current Fragment is " << CurrentFragment << "/" << KeySets.OrderSet[Order][CurrentFragment] << "." << endl;
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
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])) {
936 //Log() << Verbose(0) << "Current other fragment is " << j << "/" << KeySets.OrderSet[SubOrder][j] << "." << endl;
937 // if the fragment's indices are all in the current fragment
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];
940 //Log() << Verbose(0) << "Current row index is " << k << "/" << m << "." << endl;
941 if (m != -1) { // if it's not an added hydrogen
942 for (int l=0;l<RowCounter[ KeySets.OrderSet[Order][CurrentFragment] ];l++) { // look for the corresponding index in the current fragment
943 //Log() << Verbose(0) << "Comparing " << m << " with " << MatrixValues.Indices[ KeySets.OrderSet[Order][CurrentFragment] ][l] << "." << endl;
944 if (m == MatrixValues.Indices[ KeySets.OrderSet[Order][CurrentFragment] ][l]) {
945 m = l;
946 break;
947 }
948 }
949 //Log() << Verbose(0) << "Corresponding row index for " << k << " in CurrentFragment is " << m << "." << endl;
950 if (m > RowCounter[ KeySets.OrderSet[Order][CurrentFragment] ]) {
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);
952 performCriticalExit();
953 return false;
954 }
955
956 for(int l=0;l<ColumnCounter[ KeySets.OrderSet[SubOrder][j] ];l++) {
957 int n = MatrixValues.Indices[ KeySets.OrderSet[SubOrder][j] ][l];
958 //Log() << Verbose(0) << "Current column index is " << l << "/" << n << "." << endl;
959 if (n != -1) { // if it's not an added hydrogen
960 for (int p=0;p<ColumnCounter[ KeySets.OrderSet[Order][CurrentFragment] ];p++) { // look for the corresponding index in the current fragment
961 //Log() << Verbose(0) << "Comparing " << n << " with " << MatrixValues.Indices[ KeySets.OrderSet[Order][CurrentFragment] ][p] << "." << endl;
962 if (n == MatrixValues.Indices[ KeySets.OrderSet[Order][CurrentFragment] ][p]) {
963 n = p;
964 break;
965 }
966 }
967 //Log() << Verbose(0) << "Corresponding column index for " << l << " in CurrentFragment is " << n << "." << endl;
968 if (n > ColumnCounter[ KeySets.OrderSet[Order][CurrentFragment] ]) {
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);
970 performCriticalExit();
971 return false;
972 }
973 if (Order == SubOrder) { // equal order is always copy from Energies
974 //Log() << Verbose(0) << "Adding " << MatrixValues.Matrix[ KeySets.OrderSet[SubOrder][j] ][k][l] << " from [" << k << "][" << l << "] onto [" << m << "][" << n << "]." << endl;
975 Matrix[ KeySets.OrderSet[Order][CurrentFragment] ][m][n] += MatrixValues.Matrix[ KeySets.OrderSet[SubOrder][j] ][k][l];
976 } else {
977 //Log() << Verbose(0) << "Subtracting " << Matrix[ KeySets.OrderSet[SubOrder][j] ][k][l] << " from [" << k << "][" << l << "] onto [" << m << "][" << n << "]." << endl;
978 Matrix[ KeySets.OrderSet[Order][CurrentFragment] ][m][n] -= Matrix[ KeySets.OrderSet[SubOrder][j] ][k][l];
979 }
980 }
981 }
982 }
983 //if ((ColumnCounter[ KeySets.OrderSet[SubOrder][j] ]>1) && (RowCounter[0]-1 >= 1))
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;
985 }
986 } else {
987 //Log() << Verbose(0) << "Fragment " << KeySets.OrderSet[SubOrder][j] << " is not contained in fragment " << KeySets.OrderSet[Order][CurrentFragment] << "." << endl;
988 }
989 }
990 }
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;
992 }
993
994 return true;
995};
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 */
1005bool HessianMatrix::ParseFragmentMatrix(const char *name, const char *prefix, string suffix, int skiplines, int skipcolumns)
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);
1017 if (input.fail()) {
1018 DoLog(0) && (Log() << Verbose(0) << endl << "HessianMatrix::ParseFragmentMatrix: Unable to open " << file.str() << ", is the directory correct?" << endl);
1019 return false;
1020 }
1021 RowCounter[MatrixCounter] = 0;
1022 ColumnCounter[MatrixCounter] = 0;
1023 while (!input.eof()) {
1024 input.getline(filename, 1023);
1025 stringstream zeile(filename);
1026 while (!zeile.eof()) {
1027 zeile >> nr;
1028 //Log() << Verbose(0) << "Current index: " << getNr() << "." << endl;
1029 if (nr > RowCounter[MatrixCounter]) {
1030 RowCounter[MatrixCounter] = nr;
1031 ColumnCounter[MatrixCounter] = nr;
1032 }
1033 }
1034 }
1035 RowCounter[MatrixCounter]++; // Nr start at 0, count starts at 1
1036 ColumnCounter[MatrixCounter]++; // Nr start at 0, count starts at 1
1037 input.close();
1038
1039 // allocate last plus one matrix
1040 DoLog(0) && (Log() << Verbose(0) << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter[MatrixCounter] << " columns." << endl);
1041 Matrix[MatrixCounter] = new double*[RowCounter[MatrixCounter] + 1];
1042 for(int j=0;j<=RowCounter[MatrixCounter];j++)
1043 Matrix[MatrixCounter][j] = new double[ColumnCounter[MatrixCounter]];
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));
1049 std::ifstream input(filename);
1050 ParseMatrix(input, skiplines, skipcolumns, MatrixCounter);
1051 input.close();
1052 }
1053
1054
1055 return status;
1056};
1057
1058// ======================================= CLASS KeySetsContainer =============================
1059
1060/** Constructor of KeySetsContainer class.
1061 */
1062KeySetsContainer::KeySetsContainer() :
1063 KeySets(NULL),
1064 AtomCounter(NULL),
1065 FragmentCounter(0),
1066 Order(0),
1067 FragmentsPerOrder(0),
1068 OrderSet(NULL)
1069{};
1070
1071/** Destructor of KeySetsContainer class.
1072 */
1073KeySetsContainer::~KeySetsContainer() {
1074 for(int i=FragmentCounter;i--;)
1075 delete[](KeySets[i]);
1076 for(int i=Order;i--;)
1077 delete[](OrderSet[i]);
1078 delete[](KeySets);
1079 delete[](OrderSet);
1080 delete[](AtomCounter);
1081 delete[](FragmentsPerOrder);
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) {
1091 ifstream input;
1092 char *FragmentNumber = NULL;
1093 stringstream file;
1094 char filename[1023];
1095
1096 FragmentCounter = FCounter;
1097 DoLog(0) && (Log() << Verbose(0) << "Parsing key sets." << endl);
1098 KeySets = new int*[FragmentCounter];
1099 for(int i=FragmentCounter;i--;)
1100 KeySets[i] = NULL;
1101 file << name << FRAGMENTPREFIX << KEYSETFILE;
1102 input.open(file.str().c_str(), ios::in);
1103 if (input.fail()) {
1104 DoLog(0) && (Log() << Verbose(0) << endl << "KeySetsContainer::ParseKeySets: Unable to open " << file.str() << ", is the directory correct?" << endl);
1105 return false;
1106 }
1107
1108 AtomCounter = new int[FragmentCounter];
1109 for(int i=0;(i<FragmentCounter) && (!input.eof());i++) {
1110 stringstream line;
1111 AtomCounter[i] = ACounter[i];
1112 // parse the values
1113 KeySets[i] = new int[AtomCounter[i]];
1114 for(int j=AtomCounter[i];j--;)
1115 KeySets[i][j] = -1;
1116 FragmentNumber = FixedDigitNumber(FragmentCounter, i);
1117 //Log() << Verbose(0) << FRAGMENTPREFIX << FragmentNumber << "[" << AtomCounter[i] << "]:";
1118 delete[](FragmentNumber);
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];
1123 //Log() << Verbose(0) << " " << KeySets[i][j];
1124 }
1125 //Log() << Verbose(0) << endl;
1126 }
1127 input.close();
1128 return true;
1129};
1130
1131/** Parse many body terms, associating each fragment to a certain bond order.
1132 * \return parsing succesful
1133 */
1134bool KeySetsContainer::ParseManyBodyTerms()
1135{
1136 int Counter;
1137
1138 DoLog(0) && (Log() << Verbose(0) << "Creating Fragment terms." << endl);
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 }
1149 DoLog(0) && (Log() << Verbose(0) << "Found Order is " << Order << "." << endl);
1150
1151 // scan through all to determine fragments per order
1152 FragmentsPerOrder = new int[Order];
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++)
1163 DoLog(0) && (Log() << Verbose(0) << "Found No. of Fragments of Order " << i+1 << " is " << FragmentsPerOrder[i] << "." << endl);
1164
1165 // scan through all to gather indices to each order set
1166 OrderSet = new int*[Order];
1167 for(int i=Order;i--;)
1168 OrderSet[i] = new int[FragmentsPerOrder[i]];
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 }
1179 DoLog(0) && (Log() << Verbose(0) << "Printing OrderSet." << endl);
1180 for(int i=0;i<Order;i++) {
1181 for (int j=0;j<FragmentsPerOrder[i];j++) {
1182 DoLog(0) && (Log() << Verbose(0) << " " << OrderSet[i][j]);
1183 }
1184 DoLog(0) && (Log() << Verbose(0) << endl);
1185 }
1186 DoLog(0) && (Log() << Verbose(0) << endl);
1187
1188
1189 return true;
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{
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;
1211};
1212
1213
1214// ======================================= END =============================================
Note: See TracBrowser for help on using the repository browser.