source: src/parser.cpp@ 435065

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 435065 was 5309ba, checked in by Frederik Heber <heber@…>, 14 years ago

Renamed ParticleInfo_nr back to Nr.

  • Note that this mostly affected comments.
  • Property mode set to 100755
File size: 47.1 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
557std::ostream & operator << (std::ostream &ost, const MatrixContainer &m)
558{
559 for (int i=0;i<=m.MatrixCounter;++i) {
560 ost << "Printing matrix " << i << ":" << std::endl;
561 for (int j=0;j<=m.RowCounter[i];++j) {
562 for (int k=0;k<m.ColumnCounter[i];++k) {
563 ost << m.Matrix[i][j][k] << " ";
564 }
565 ost << std::endl;
566 }
567 }
568 ost << std::endl;
569 return ost;
570}
571
572// ======================================= CLASS EnergyMatrix =============================
573
574/** Create a trivial energy index mapping.
575 * This just maps 1 to 1, 2 to 2 and so on for all fragments.
576 * \return creation sucessful
577 */
578bool EnergyMatrix::ParseIndices()
579{
580 DoLog(0) && (Log() << Verbose(0) << "Parsing energy indices." << endl);
581 Indices = new int*[MatrixCounter + 1];
582 for(int i=MatrixCounter+1;i--;) {
583 Indices[i] = new int[RowCounter[i]];
584 for(int j=RowCounter[i];j--;)
585 Indices[i][j] = j;
586 }
587 return true;
588};
589
590/** Sums the energy with each factor and put into last element of \a EnergyMatrix::Matrix.
591 * Sums over the "F"-terms in ANOVA decomposition.
592 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies.
593 * \param CorrectionFragments MatrixContainer with hydrogen saturation correction per fragments
594 * \param KeySets KeySetContainer with bond Order and association mapping of each fragment to an order
595 * \param Order bond order
596 * \parsm sign +1 or -1
597 * \return true if summing was successful
598 */
599bool EnergyMatrix::SumSubEnergy(class EnergyMatrix &Fragments, class EnergyMatrix *CorrectionFragments, class KeySetsContainer &KeySets, int Order, double sign)
600{
601 // sum energy
602 if (CorrectionFragments == NULL)
603 for(int i=KeySets.FragmentsPerOrder[Order];i--;)
604 for(int j=RowCounter[ KeySets.OrderSet[Order][i] ];j--;)
605 for(int k=ColumnCounter[ KeySets.OrderSet[Order][i] ];k--;)
606 Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ KeySets.OrderSet[Order][i] ][j][k];
607 else
608 for(int i=KeySets.FragmentsPerOrder[Order];i--;)
609 for(int j=RowCounter[ KeySets.OrderSet[Order][i] ];j--;)
610 for(int k=ColumnCounter[ KeySets.OrderSet[Order][i] ];k--;)
611 Matrix[MatrixCounter][j][k] += sign*(Fragments.Matrix[ KeySets.OrderSet[Order][i] ][j][k] + CorrectionFragments->Matrix[ KeySets.OrderSet[Order][i] ][j][k]);
612 return true;
613};
614
615/** Calls MatrixContainer::ParseFragmentMatrix() and additionally allocates last plus one matrix.
616 * \param *name directory with files
617 * \param *prefix prefix of each matrix file
618 * \param *suffix suffix of each matrix file
619 * \param skiplines number of inital lines to skip
620 * \param skiplines number of inital columns to skip
621 * \return parsing successful
622 */
623bool EnergyMatrix::ParseFragmentMatrix(const char *name, const char *prefix, string suffix, int skiplines, int skipcolumns)
624{
625 char filename[1024];
626 bool status = MatrixContainer::ParseFragmentMatrix(name, prefix, suffix, skiplines, skipcolumns);
627
628 if (status) {
629 // count maximum of columns
630 RowCounter[MatrixCounter] = 0;
631 ColumnCounter[MatrixCounter] = 0;
632 for(int j=0; j < MatrixCounter;j++) { // (energy matrix might be bigger than number of atoms in terms of rows)
633 if (RowCounter[j] > RowCounter[MatrixCounter])
634 RowCounter[MatrixCounter] = RowCounter[j];
635 if (ColumnCounter[j] > ColumnCounter[MatrixCounter]) // take maximum of all for last matrix
636 ColumnCounter[MatrixCounter] = ColumnCounter[j];
637 }
638 // allocate last plus one matrix
639 DoLog(0) && (Log() << Verbose(0) << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter[MatrixCounter] << " columns." << endl);
640 Matrix[MatrixCounter] = new double*[RowCounter[MatrixCounter] + 1];
641 for(int j=0;j<=RowCounter[MatrixCounter];j++)
642 Matrix[MatrixCounter][j] = new double[ColumnCounter[MatrixCounter]];
643
644 // try independently to parse global energysuffix file if present
645 strncpy(filename, name, 1023);
646 strncat(filename, prefix, 1023-strlen(filename));
647 strncat(filename, suffix.c_str(), 1023-strlen(filename));
648 std::ifstream input(filename);
649 ParseMatrix(input, skiplines, skipcolumns, MatrixCounter);
650 input.close();
651 }
652 return status;
653};
654
655// ======================================= CLASS ForceMatrix =============================
656
657/** Parsing force Indices of each fragment
658 * \param *name directory with \a ForcesFile
659 * \return parsing successful
660 */
661bool ForceMatrix::ParseIndices(const char *name)
662{
663 ifstream input;
664 char *FragmentNumber = NULL;
665 char filename[1023];
666 stringstream line;
667
668 DoLog(0) && (Log() << Verbose(0) << "Parsing force indices for " << MatrixCounter << " matrices." << endl);
669 Indices = new int*[MatrixCounter + 1];
670 line << name << FRAGMENTPREFIX << FORCESFILE;
671 input.open(line.str().c_str(), ios::in);
672 //Log() << Verbose(0) << "Opening " << line.str() << " ... " << input << endl;
673 if (input == NULL) {
674 DoLog(0) && (Log() << Verbose(0) << endl << "ForceMatrix::ParseIndices: Unable to open " << line.str() << ", is the directory correct?" << endl);
675 return false;
676 }
677 for (int i=0;(i<MatrixCounter) && (!input.eof());i++) {
678 // get the number of atoms for this fragment
679 input.getline(filename, 1023);
680 line.str(filename);
681 // parse the values
682 Indices[i] = new int[RowCounter[i]];
683 FragmentNumber = FixedDigitNumber(MatrixCounter, i);
684 //Log() << Verbose(0) << FRAGMENTPREFIX << FragmentNumber << "[" << RowCounter[i] << "]:";
685 delete[](FragmentNumber);
686 for(int j=0;(j<RowCounter[i]) && (!line.eof());j++) {
687 line >> Indices[i][j];
688 //Log() << Verbose(0) << " " << Indices[i][j];
689 }
690 //Log() << Verbose(0) << endl;
691 }
692 Indices[MatrixCounter] = new int[RowCounter[MatrixCounter]];
693 for(int j=RowCounter[MatrixCounter];j--;) {
694 Indices[MatrixCounter][j] = j;
695 }
696 input.close();
697 return true;
698};
699
700
701/** Sums the forces and puts into last element of \a ForceMatrix::Matrix.
702 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies.
703 * \param KeySets KeySetContainer with bond Order and association mapping of each fragment to an order
704 * \param Order bond order
705 * \param sign +1 or -1
706 * \return true if summing was successful
707 */
708bool ForceMatrix::SumSubForces(class ForceMatrix &Fragments, class KeySetsContainer &KeySets, int Order, double sign)
709{
710 int FragmentNr;
711 // sum forces
712 for(int i=0;i<KeySets.FragmentsPerOrder[Order];i++) {
713 FragmentNr = KeySets.OrderSet[Order][i];
714 for(int l=0;l<RowCounter[ FragmentNr ];l++) {
715 int j = Indices[ FragmentNr ][l];
716 if (j > RowCounter[MatrixCounter]) {
717 DoeLog(0) && (eLog()<< Verbose(0) << "Current force index " << j << " is greater than " << RowCounter[MatrixCounter] << "!" << endl);
718 performCriticalExit();
719 return false;
720 }
721 if (j != -1) {
722 //if (j == 0) Log() << Verbose(0) << "Summing onto ion 0, type 0 from fragment " << FragmentNr << ", ion " << l << "." << endl;
723 for(int k=2;k<ColumnCounter[MatrixCounter];k++)
724 Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ FragmentNr ][l][k];
725 }
726 }
727 }
728 return true;
729};
730
731
732/** Calls MatrixContainer::ParseFragmentMatrix() and additionally allocates last plus one matrix.
733 * \param *name directory with files
734 * \param *prefix prefix of each matrix file
735 * \param *suffix suffix of each matrix file
736 * \param skiplines number of inital lines to skip
737 * \param skiplines number of inital columns to skip
738 * \return parsing successful
739 */
740bool ForceMatrix::ParseFragmentMatrix(const char *name, const char *prefix, string suffix, int skiplines, int skipcolumns)
741{
742 char filename[1023];
743 ifstream input;
744 stringstream file;
745 int nr;
746 bool status = MatrixContainer::ParseFragmentMatrix(name, prefix, suffix, skiplines, skipcolumns);
747
748 if (status) {
749 // count number of atoms for last plus one matrix
750 file << name << FRAGMENTPREFIX << KEYSETFILE;
751 input.open(file.str().c_str(), ios::in);
752 if (input == NULL) {
753 DoLog(0) && (Log() << Verbose(0) << endl << "ForceMatrix::ParseFragmentMatrix: Unable to open " << file.str() << ", is the directory correct?" << endl);
754 return false;
755 }
756 RowCounter[MatrixCounter] = 0;
757 while (!input.eof()) {
758 input.getline(filename, 1023);
759 stringstream zeile(filename);
760 while (!zeile.eof()) {
761 zeile >> nr;
762 //Log() << Verbose(0) << "Current index: " << getNr() << "." << endl;
763 if (nr > RowCounter[MatrixCounter])
764 RowCounter[MatrixCounter] = nr;
765 }
766 }
767 RowCounter[MatrixCounter]++; // Nr start at 0, count starts at 1
768 input.close();
769
770 ColumnCounter[MatrixCounter] = 0;
771 for(int j=0; j < MatrixCounter;j++) { // (energy matrix might be bigger than number of atoms in terms of rows)
772 if (ColumnCounter[j] > ColumnCounter[MatrixCounter]) // take maximum of all for last matrix
773 ColumnCounter[MatrixCounter] = ColumnCounter[j];
774 }
775
776 // allocate last plus one matrix
777 DoLog(0) && (Log() << Verbose(0) << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter[MatrixCounter] << " columns." << endl);
778 Matrix[MatrixCounter] = new double*[RowCounter[MatrixCounter] + 1];
779 for(int j=0;j<=RowCounter[MatrixCounter];j++)
780 Matrix[MatrixCounter][j] = new double[ColumnCounter[MatrixCounter]];
781
782 // try independently to parse global forcesuffix file if present
783 strncpy(filename, name, 1023);
784 strncat(filename, prefix, 1023-strlen(filename));
785 strncat(filename, suffix.c_str(), 1023-strlen(filename));
786 std::ifstream input(filename);
787 ParseMatrix(input, skiplines, skipcolumns, MatrixCounter);
788 input.close();
789 }
790
791
792 return status;
793};
794
795// ======================================= CLASS HessianMatrix =============================
796
797/** Parsing force Indices of each fragment
798 * \param *name directory with \a ForcesFile
799 * \return parsing successful
800 */
801bool HessianMatrix::ParseIndices(char *name)
802{
803 ifstream input;
804 char *FragmentNumber = NULL;
805 char filename[1023];
806 stringstream line;
807
808 DoLog(0) && (Log() << Verbose(0) << "Parsing hessian indices for " << MatrixCounter << " matrices." << endl);
809 Indices = new int*[MatrixCounter + 1];
810 line << name << FRAGMENTPREFIX << FORCESFILE;
811 input.open(line.str().c_str(), ios::in);
812 //Log() << Verbose(0) << "Opening " << line.str() << " ... " << input << endl;
813 if (input == NULL) {
814 DoLog(0) && (Log() << Verbose(0) << endl << "HessianMatrix::ParseIndices: Unable to open " << line.str() << ", is the directory correct?" << endl);
815 return false;
816 }
817 for (int i=0;(i<MatrixCounter) && (!input.eof());i++) {
818 // get the number of atoms for this fragment
819 input.getline(filename, 1023);
820 line.str(filename);
821 // parse the values
822 Indices[i] = new int[RowCounter[i]];
823 FragmentNumber = FixedDigitNumber(MatrixCounter, i);
824 //Log() << Verbose(0) << FRAGMENTPREFIX << FragmentNumber << "[" << RowCounter[i] << "]:";
825 delete[](FragmentNumber);
826 for(int j=0;(j<RowCounter[i]) && (!line.eof());j++) {
827 line >> Indices[i][j];
828 //Log() << Verbose(0) << " " << Indices[i][j];
829 }
830 //Log() << Verbose(0) << endl;
831 }
832 Indices[MatrixCounter] = new int[RowCounter[MatrixCounter]];
833 for(int j=RowCounter[MatrixCounter];j--;) {
834 Indices[MatrixCounter][j] = j;
835 }
836 input.close();
837 return true;
838};
839
840
841/** Sums the hessian entries and puts into last element of \a HessianMatrix::Matrix.
842 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies.
843 * \param KeySets KeySetContainer with bond Order and association mapping of each fragment to an order
844 * \param Order bond order
845 * \param sign +1 or -1
846 * \return true if summing was successful
847 */
848bool HessianMatrix::SumSubHessians(class HessianMatrix &Fragments, class KeySetsContainer &KeySets, int Order, double sign)
849{
850 int FragmentNr;
851 // sum forces
852 for(int i=0;i<KeySets.FragmentsPerOrder[Order];i++) {
853 FragmentNr = KeySets.OrderSet[Order][i];
854 for(int l=0;l<RowCounter[ FragmentNr ];l++) {
855 int j = Indices[ FragmentNr ][l];
856 if (j > RowCounter[MatrixCounter]) {
857 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);
858 performCriticalExit();
859 return false;
860 }
861 if (j != -1) {
862 for(int m=0;m<ColumnCounter[ FragmentNr ];m++) {
863 int k = Indices[ FragmentNr ][m];
864 if (k > ColumnCounter[MatrixCounter]) {
865 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);
866 performCriticalExit();
867 return false;
868 }
869 if (k != -1) {
870 //Log() << Verbose(0) << "Adding " << sign*Fragments.Matrix[ FragmentNr ][l][m] << " from [" << l << "][" << m << "] onto [" << j << "][" << k << "]." << endl;
871 Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ FragmentNr ][l][m];
872 }
873 }
874 }
875 }
876 }
877 return true;
878};
879
880/** Constructor for class HessianMatrix.
881 */
882HessianMatrix::HessianMatrix() :
883 MatrixContainer(),
884 IsSymmetric(true)
885{}
886
887/** Sums the hessian entries with each factor and put into last element of \a ***Matrix.
888 * Sums over "E"-terms to create the "F"-terms
889 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies.
890 * \param KeySets KeySetContainer with bond Order and association mapping of each fragment to an order
891 * \param Order bond order
892 * \return true if summing was successful
893 */
894bool HessianMatrix::SumSubManyBodyTerms(class MatrixContainer &MatrixValues, class KeySetsContainer &KeySets, int Order)
895{
896 // go through each order
897 for (int CurrentFragment=0;CurrentFragment<KeySets.FragmentsPerOrder[Order];CurrentFragment++) {
898 //Log() << Verbose(0) << "Current Fragment is " << CurrentFragment << "/" << KeySets.OrderSet[Order][CurrentFragment] << "." << endl;
899 // then go per order through each suborder and pick together all the terms that contain this fragment
900 for(int SubOrder=0;SubOrder<=Order;SubOrder++) { // go through all suborders up to the desired order
901 for (int j=0;j<KeySets.FragmentsPerOrder[SubOrder];j++) { // go through all possible fragments of size suborder
902 if (KeySets.Contains(KeySets.OrderSet[Order][CurrentFragment], KeySets.OrderSet[SubOrder][j])) {
903 //Log() << Verbose(0) << "Current other fragment is " << j << "/" << KeySets.OrderSet[SubOrder][j] << "." << endl;
904 // if the fragment's indices are all in the current fragment
905 for(int k=0;k<RowCounter[ KeySets.OrderSet[SubOrder][j] ];k++) { // go through all atoms in this fragment
906 int m = MatrixValues.Indices[ KeySets.OrderSet[SubOrder][j] ][k];
907 //Log() << Verbose(0) << "Current row index is " << k << "/" << m << "." << endl;
908 if (m != -1) { // if it's not an added hydrogen
909 for (int l=0;l<RowCounter[ KeySets.OrderSet[Order][CurrentFragment] ];l++) { // look for the corresponding index in the current fragment
910 //Log() << Verbose(0) << "Comparing " << m << " with " << MatrixValues.Indices[ KeySets.OrderSet[Order][CurrentFragment] ][l] << "." << endl;
911 if (m == MatrixValues.Indices[ KeySets.OrderSet[Order][CurrentFragment] ][l]) {
912 m = l;
913 break;
914 }
915 }
916 //Log() << Verbose(0) << "Corresponding row index for " << k << " in CurrentFragment is " << m << "." << endl;
917 if (m > RowCounter[ KeySets.OrderSet[Order][CurrentFragment] ]) {
918 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);
919 performCriticalExit();
920 return false;
921 }
922
923 for(int l=0;l<ColumnCounter[ KeySets.OrderSet[SubOrder][j] ];l++) {
924 int n = MatrixValues.Indices[ KeySets.OrderSet[SubOrder][j] ][l];
925 //Log() << Verbose(0) << "Current column index is " << l << "/" << n << "." << endl;
926 if (n != -1) { // if it's not an added hydrogen
927 for (int p=0;p<ColumnCounter[ KeySets.OrderSet[Order][CurrentFragment] ];p++) { // look for the corresponding index in the current fragment
928 //Log() << Verbose(0) << "Comparing " << n << " with " << MatrixValues.Indices[ KeySets.OrderSet[Order][CurrentFragment] ][p] << "." << endl;
929 if (n == MatrixValues.Indices[ KeySets.OrderSet[Order][CurrentFragment] ][p]) {
930 n = p;
931 break;
932 }
933 }
934 //Log() << Verbose(0) << "Corresponding column index for " << l << " in CurrentFragment is " << n << "." << endl;
935 if (n > ColumnCounter[ KeySets.OrderSet[Order][CurrentFragment] ]) {
936 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);
937 performCriticalExit();
938 return false;
939 }
940 if (Order == SubOrder) { // equal order is always copy from Energies
941 //Log() << Verbose(0) << "Adding " << MatrixValues.Matrix[ KeySets.OrderSet[SubOrder][j] ][k][l] << " from [" << k << "][" << l << "] onto [" << m << "][" << n << "]." << endl;
942 Matrix[ KeySets.OrderSet[Order][CurrentFragment] ][m][n] += MatrixValues.Matrix[ KeySets.OrderSet[SubOrder][j] ][k][l];
943 } else {
944 //Log() << Verbose(0) << "Subtracting " << Matrix[ KeySets.OrderSet[SubOrder][j] ][k][l] << " from [" << k << "][" << l << "] onto [" << m << "][" << n << "]." << endl;
945 Matrix[ KeySets.OrderSet[Order][CurrentFragment] ][m][n] -= Matrix[ KeySets.OrderSet[SubOrder][j] ][k][l];
946 }
947 }
948 }
949 }
950 //if ((ColumnCounter[ KeySets.OrderSet[SubOrder][j] ]>1) && (RowCounter[0]-1 >= 1))
951 //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;
952 }
953 } else {
954 //Log() << Verbose(0) << "Fragment " << KeySets.OrderSet[SubOrder][j] << " is not contained in fragment " << KeySets.OrderSet[Order][CurrentFragment] << "." << endl;
955 }
956 }
957 }
958 //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;
959 }
960
961 return true;
962};
963
964/** Calls MatrixContainer::ParseFragmentMatrix() and additionally allocates last plus one matrix.
965 * \param *name directory with files
966 * \param *prefix prefix of each matrix file
967 * \param *suffix suffix of each matrix file
968 * \param skiplines number of inital lines to skip
969 * \param skiplines number of inital columns to skip
970 * \return parsing successful
971 */
972bool HessianMatrix::ParseFragmentMatrix(const char *name, const char *prefix, string suffix, int skiplines, int skipcolumns)
973{
974 char filename[1023];
975 ifstream input;
976 stringstream file;
977 int nr;
978 bool status = MatrixContainer::ParseFragmentMatrix(name, prefix, suffix, skiplines, skipcolumns);
979
980 if (status) {
981 // count number of atoms for last plus one matrix
982 file << name << FRAGMENTPREFIX << KEYSETFILE;
983 input.open(file.str().c_str(), ios::in);
984 if (input == NULL) {
985 DoLog(0) && (Log() << Verbose(0) << endl << "HessianMatrix::ParseFragmentMatrix: Unable to open " << file.str() << ", is the directory correct?" << endl);
986 return false;
987 }
988 RowCounter[MatrixCounter] = 0;
989 ColumnCounter[MatrixCounter] = 0;
990 while (!input.eof()) {
991 input.getline(filename, 1023);
992 stringstream zeile(filename);
993 while (!zeile.eof()) {
994 zeile >> nr;
995 //Log() << Verbose(0) << "Current index: " << getNr() << "." << endl;
996 if (nr > RowCounter[MatrixCounter]) {
997 RowCounter[MatrixCounter] = nr;
998 ColumnCounter[MatrixCounter] = nr;
999 }
1000 }
1001 }
1002 RowCounter[MatrixCounter]++; // Nr start at 0, count starts at 1
1003 ColumnCounter[MatrixCounter]++; // Nr start at 0, count starts at 1
1004 input.close();
1005
1006 // allocate last plus one matrix
1007 DoLog(0) && (Log() << Verbose(0) << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter[MatrixCounter] << " columns." << endl);
1008 Matrix[MatrixCounter] = new double*[RowCounter[MatrixCounter] + 1];
1009 for(int j=0;j<=RowCounter[MatrixCounter];j++)
1010 Matrix[MatrixCounter][j] = new double[ColumnCounter[MatrixCounter]];
1011
1012 // try independently to parse global forcesuffix file if present
1013 strncpy(filename, name, 1023);
1014 strncat(filename, prefix, 1023-strlen(filename));
1015 strncat(filename, suffix.c_str(), 1023-strlen(filename));
1016 std::ifstream input(filename);
1017 ParseMatrix(input, skiplines, skipcolumns, MatrixCounter);
1018 input.close();
1019 }
1020
1021
1022 return status;
1023};
1024
1025// ======================================= CLASS KeySetsContainer =============================
1026
1027/** Constructor of KeySetsContainer class.
1028 */
1029KeySetsContainer::KeySetsContainer() :
1030 KeySets(NULL),
1031 AtomCounter(NULL),
1032 FragmentCounter(0),
1033 Order(0),
1034 FragmentsPerOrder(0),
1035 OrderSet(NULL)
1036{};
1037
1038/** Destructor of KeySetsContainer class.
1039 */
1040KeySetsContainer::~KeySetsContainer() {
1041 for(int i=FragmentCounter;i--;)
1042 delete[](KeySets[i]);
1043 for(int i=Order;i--;)
1044 delete[](OrderSet[i]);
1045 delete[](KeySets);
1046 delete[](OrderSet);
1047 delete[](AtomCounter);
1048 delete[](FragmentsPerOrder);
1049};
1050
1051/** Parsing KeySets into array.
1052 * \param *name directory with keyset file
1053 * \param *ACounter number of atoms per fragment
1054 * \param FCounter number of fragments
1055 * \return parsing succesful
1056 */
1057bool KeySetsContainer::ParseKeySets(const char *name, const int *ACounter, const int FCounter) {
1058 ifstream input;
1059 char *FragmentNumber = NULL;
1060 stringstream file;
1061 char filename[1023];
1062
1063 FragmentCounter = FCounter;
1064 DoLog(0) && (Log() << Verbose(0) << "Parsing key sets." << endl);
1065 KeySets = new int*[FragmentCounter];
1066 for(int i=FragmentCounter;i--;)
1067 KeySets[i] = NULL;
1068 file << name << FRAGMENTPREFIX << KEYSETFILE;
1069 input.open(file.str().c_str(), ios::in);
1070 if (input == NULL) {
1071 DoLog(0) && (Log() << Verbose(0) << endl << "KeySetsContainer::ParseKeySets: Unable to open " << file.str() << ", is the directory correct?" << endl);
1072 return false;
1073 }
1074
1075 AtomCounter = new int[FragmentCounter];
1076 for(int i=0;(i<FragmentCounter) && (!input.eof());i++) {
1077 stringstream line;
1078 AtomCounter[i] = ACounter[i];
1079 // parse the values
1080 KeySets[i] = new int[AtomCounter[i]];
1081 for(int j=AtomCounter[i];j--;)
1082 KeySets[i][j] = -1;
1083 FragmentNumber = FixedDigitNumber(FragmentCounter, i);
1084 //Log() << Verbose(0) << FRAGMENTPREFIX << FragmentNumber << "[" << AtomCounter[i] << "]:";
1085 delete[](FragmentNumber);
1086 input.getline(filename, 1023);
1087 line.str(filename);
1088 for(int j=0;(j<AtomCounter[i]) && (!line.eof());j++) {
1089 line >> KeySets[i][j];
1090 //Log() << Verbose(0) << " " << KeySets[i][j];
1091 }
1092 //Log() << Verbose(0) << endl;
1093 }
1094 input.close();
1095 return true;
1096};
1097
1098/** Parse many body terms, associating each fragment to a certain bond order.
1099 * \return parsing succesful
1100 */
1101bool KeySetsContainer::ParseManyBodyTerms()
1102{
1103 int Counter;
1104
1105 DoLog(0) && (Log() << Verbose(0) << "Creating Fragment terms." << endl);
1106 // scan through all to determine maximum order
1107 Order=0;
1108 for(int i=FragmentCounter;i--;) {
1109 Counter=0;
1110 for(int j=AtomCounter[i];j--;)
1111 if (KeySets[i][j] != -1)
1112 Counter++;
1113 if (Counter > Order)
1114 Order = Counter;
1115 }
1116 DoLog(0) && (Log() << Verbose(0) << "Found Order is " << Order << "." << endl);
1117
1118 // scan through all to determine fragments per order
1119 FragmentsPerOrder = new int[Order];
1120 for(int i=Order;i--;)
1121 FragmentsPerOrder[i] = 0;
1122 for(int i=FragmentCounter;i--;) {
1123 Counter=0;
1124 for(int j=AtomCounter[i];j--;)
1125 if (KeySets[i][j] != -1)
1126 Counter++;
1127 FragmentsPerOrder[Counter-1]++;
1128 }
1129 for(int i=0;i<Order;i++)
1130 DoLog(0) && (Log() << Verbose(0) << "Found No. of Fragments of Order " << i+1 << " is " << FragmentsPerOrder[i] << "." << endl);
1131
1132 // scan through all to gather indices to each order set
1133 OrderSet = new int*[Order];
1134 for(int i=Order;i--;)
1135 OrderSet[i] = new int[FragmentsPerOrder[i]];
1136 for(int i=Order;i--;)
1137 FragmentsPerOrder[i] = 0;
1138 for(int i=FragmentCounter;i--;) {
1139 Counter=0;
1140 for(int j=AtomCounter[i];j--;)
1141 if (KeySets[i][j] != -1)
1142 Counter++;
1143 OrderSet[Counter-1][FragmentsPerOrder[Counter-1]] = i;
1144 FragmentsPerOrder[Counter-1]++;
1145 }
1146 DoLog(0) && (Log() << Verbose(0) << "Printing OrderSet." << endl);
1147 for(int i=0;i<Order;i++) {
1148 for (int j=0;j<FragmentsPerOrder[i];j++) {
1149 DoLog(0) && (Log() << Verbose(0) << " " << OrderSet[i][j]);
1150 }
1151 DoLog(0) && (Log() << Verbose(0) << endl);
1152 }
1153 DoLog(0) && (Log() << Verbose(0) << endl);
1154
1155
1156 return true;
1157};
1158
1159/** Compares each entry in \a *SmallerSet if it is containted in \a *GreaterSet.
1160 * \param GreaterSet index to greater set
1161 * \param SmallerSet index to smaller set
1162 * \return true if all keys of SmallerSet contained in GreaterSet
1163 */
1164bool KeySetsContainer::Contains(const int GreaterSet, const int SmallerSet)
1165{
1166 bool result = true;
1167 bool intermediate;
1168 if ((GreaterSet < 0) || (SmallerSet < 0) || (GreaterSet > FragmentCounter) || (SmallerSet > FragmentCounter)) // index out of bounds
1169 return false;
1170 for(int i=AtomCounter[SmallerSet];i--;) {
1171 intermediate = false;
1172 for (int j=AtomCounter[GreaterSet];j--;)
1173 intermediate = (intermediate || ((KeySets[SmallerSet][i] == KeySets[GreaterSet][j]) || (KeySets[SmallerSet][i] == -1)));
1174 result = result && intermediate;
1175 }
1176
1177 return result;
1178};
1179
1180
1181// ======================================= END =============================================
Note: See TracBrowser for help on using the repository browser.