source: src/parser.cpp@ 0e01b4

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 0e01b4 was a67d19, checked in by Frederik Heber <heber@…>, 15 years ago

Huge change: Log() << Verbose(.) --> DoLog(.) && (Log() << Verbose(.) << ...);

Most of the files are affected, but this is necessary as if DoLog() says verbosity is not enough, all the stream operators won"t get executed which saves substantial amount of computation time.

Signed-off-by: Frederik Heber <heber@…>

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