source: src/parser.cpp@ ad28ef

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 ad28ef was 4e855e, checked in by Frederik Heber <heber@…>, 14 years ago

BondGraph::LoadBondLengthTable() now accepts istream instead of const char *.

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