source: src/parser.cpp@ 5e0d1f

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 5e0d1f was fb9364, checked in by Frederik Heber <heber@…>, 16 years ago

The entries in the Header of ForceMatrix are now separated by tabs, not white spaces in general

This fixes problems with the headers of the speed entries of MPQC which are multiple words separated by spaces. As we already use tabs to separate each entries, we just had to rewrite the code to split by '\t' which is done by getline.

  • Property mode set to 100644
File size: 27.0 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 "helpers.hpp"
10#include "parser.hpp"
11
12// include config.h
13#ifdef HAVE_CONFIG_H
14#include <config.h>
15#endif
16
17// ======================================= FUNCTIONS ==========================================
18
19/** Test if given filename can be opened.
20 * \param filename name of file
21 * \param test true - no error message, false - print error
22 * \return given file exists
23 */
24bool FilePresent(const char *filename, bool test)
25{
26 ifstream input;
27
28 input.open(filename, ios::in);
29 if (input == NULL) {
30 if (!test)
31 cout << endl << "Unable to open " << filename << ", is the directory correct?" << endl;
32 return false;
33 }
34 input.close();
35 return true;
36};
37
38/** Test the given parameters.
39 * \param argc argument count
40 * \param **argv arguments array
41 * \return given inputdir is valid
42 */
43bool TestParams(int argc, char **argv)
44{
45 ifstream input;
46 stringstream line;
47
48 line << argv[1] << FRAGMENTPREFIX << KEYSETFILE;
49 return FilePresent(line.str().c_str(), false);
50};
51
52// ======================================= CLASS MatrixContainer =============================
53
54/** Constructor of MatrixContainer class.
55 */
56MatrixContainer::MatrixContainer() {
57 Matrix = NULL;
58 Indices = NULL;
59 Header = NULL;
60 MatrixCounter = 0;
61 RowCounter = NULL;
62 ColumnCounter = 0;
63};
64
65/** Destructor of MatrixContainer class.
66 */
67MatrixContainer::~MatrixContainer() {
68 if (Matrix != NULL) {
69 for(int i=MatrixCounter;i--;) {
70 if (RowCounter != NULL) {
71 for(int j=RowCounter[i]+1;j--;)
72 Free((void **)&Matrix[i][j], "MatrixContainer::~MatrixContainer: *Matrix[][]");
73 Free((void **)&Matrix[i], "MatrixContainer::~MatrixContainer: **Matrix[]");
74 }
75 }
76 if ((RowCounter != NULL) && (Matrix[MatrixCounter] != NULL))
77 for(int j=RowCounter[MatrixCounter]+1;j--;)
78 Free((void **)&Matrix[MatrixCounter][j], "MatrixContainer::~MatrixContainer: *Matrix[MatrixCounter][]");
79 if (MatrixCounter != 0)
80 Free((void **)&Matrix[MatrixCounter], "MatrixContainer::~MatrixContainer: **Matrix[MatrixCounter]");
81 Free((void **)&Matrix, "MatrixContainer::~MatrixContainer: ***Matrix");
82 }
83 if (Indices != NULL)
84 for(int i=MatrixCounter+1;i--;) {
85 Free((void **)&Indices[i], "MatrixContainer::~MatrixContainer: *Indices[]");
86 }
87 Free((void **)&Indices, "MatrixContainer::~MatrixContainer: **Indices");
88
89 Free((void **)&Header, "MatrixContainer::~MatrixContainer: *Header");
90 Free((void **)&RowCounter, "MatrixContainer::~MatrixContainer: *RowCounter");
91};
92
93/** Parsing a number of matrices.
94 * -# First, count the number of matrices by counting lines in KEYSETFILE
95 * -# Then,
96 * -# construct the fragment number
97 * -# open the matrix file
98 * -# skip some lines (\a skiplines)
99 * -# scan header lines for number of columns
100 * -# scan lines for number of rows
101 * -# allocate matrix
102 * -# loop over found column and row counts and parse in each entry
103 * -# Finally, allocate one additional matrix (\a MatrixCounter) containing combined or temporary values
104 * \param *name directory with files
105 * \param *prefix prefix of each matrix file
106 * \param *suffix suffix of each matrix file
107 * \param skiplines number of inital lines to skip
108 * \param skiplines number of inital columns to skip
109 * \return parsing successful
110 */
111bool MatrixContainer::ParseMatrix(char *name, char *prefix, string suffix, int skiplines, int skipcolumns)
112{
113 char filename[1023];
114 ifstream input;
115 char *FragmentNumber = NULL;
116 stringstream file;
117 string token;
118
119 Header = (char *) Malloc(sizeof(char)*1023, "MatrixContainer::ParseMatrix: *EnergyHeader");
120
121 // count the number of matrices
122 MatrixCounter = -1; // we count one too much
123 file << name << FRAGMENTPREFIX << KEYSETFILE;
124 input.open(file.str().c_str(), ios::in);
125 if (input == NULL) {
126 cout << endl << "Unable to open " << file.str() << ", is the directory correct?" << endl;
127 return false;
128 }
129 while (!input.eof()) {
130 input.getline(filename, 1023);
131 MatrixCounter++;
132 }
133 input.close();
134 cout << "Determined " << MatrixCounter << " fragments." << endl;
135
136 cout << "Parsing through each fragment and retrieving " << prefix << suffix << "." << endl;
137 Matrix = (double ***) Malloc(sizeof(double **)*(MatrixCounter+1), "MatrixContainer::ParseMatrix: ***Matrix"); // one more each for the total molecule
138 RowCounter = (int *) Malloc(sizeof(int)*(MatrixCounter+1), "MatrixContainer::ParseMatrix: *RowCounter");
139 for(int i=MatrixCounter+1;i--;) {
140 Matrix[i] = NULL;
141 RowCounter[i] = -1;
142 }
143 for(int i=MatrixCounter+1;i--;) {
144 // open matrix file
145 stringstream line;
146 FragmentNumber = FixedDigitNumber(MatrixCounter, i);
147 file.str(" ");
148 if (i != MatrixCounter)
149 file << name << FRAGMENTPREFIX << FragmentNumber << prefix << suffix;
150 else
151 file << name << prefix << suffix;
152 Free((void **)&FragmentNumber, "MatrixContainer::ParseMatrix: *FragmentNumber");
153 input.open(file.str().c_str(), ios::in);
154 //cout << "Opening " << file.str() << " ... " << input << endl;
155 if (input == NULL) {
156 cerr << endl << "Unable to open " << file.str() << ", is the directory correct?" << endl;
157 return false;
158 }
159
160 // skip some initial lines
161 for (int m=skiplines+1;m--;)
162 input.getline(Header, 1023);
163
164 // scan header for number of columns
165 line.str(Header);
166 for(int k=skipcolumns;k--;)
167 line >> Header;
168 //cout << line.str() << endl;
169 ColumnCounter=0;
170 while ( getline(line,token, '\t') ) {
171 if (token.length() > 0)
172 ColumnCounter++;
173 }
174 //cout << line.str() << endl;
175 //cout << "ColumnCounter: " << ColumnCounter << endl;
176
177 // scan rest for number of rows/lines
178 RowCounter[i]=-1; // counts one line too much
179 while (!input.eof()) {
180 input.getline(filename, 1023);
181 //cout << "Comparing: " << strncmp(filename,"MeanForce",9) << endl;
182 RowCounter[i]++; // then line was not last MeanForce
183 if (strncmp(filename,"MeanForce", 9) == 0) {
184 break;
185 }
186 }
187 //cout << "RowCounter[" << i << "]: " << RowCounter[i] << " from file " << file.str() << "." << endl;
188
189 // allocate matrix if it's not zero dimension in one direction
190 if ((ColumnCounter > 0) && (RowCounter[i] > -1)) {
191 Matrix[i] = (double **) Malloc(sizeof(double *)*(RowCounter[i]+1), "MatrixContainer::ParseMatrix: **Matrix[]");
192
193 // parse in each entry for this matrix
194 input.clear();
195 input.seekg(ios::beg);
196 for (int m=skiplines+1;m--;)
197 input.getline(Header, 1023); // skip header
198 line.str(Header);
199 for(int k=skipcolumns;k--;) // skip columns in header too
200 line >> filename;
201 strncpy(Header, line.str().c_str(), 1023);
202 for(int j=0;j<RowCounter[i];j++) {
203 Matrix[i][j] = (double *) Malloc(sizeof(double)*ColumnCounter, "MatrixContainer::ParseMatrix: *Matrix[][]");
204 input.getline(filename, 1023);
205 stringstream lines(filename);
206 //cout << "Matrix at level " << j << ":";// << filename << endl;
207 for(int k=skipcolumns;k--;)
208 lines >> filename;
209 for(int k=0;(k<ColumnCounter) && (!lines.eof());k++) {
210 lines >> Matrix[i][j][k];
211 //cout << " " << setprecision(2) << Matrix[i][j][k];;
212 }
213 //cout << endl;
214 Matrix[i][ RowCounter[i] ] = (double *) Malloc(sizeof(double)*ColumnCounter, "MatrixContainer::ParseMatrix: *Matrix[RowCounter[i]][]");
215 for(int j=ColumnCounter;j--;)
216 Matrix[i][ RowCounter[i] ][j] = 0.;
217 }
218 } else {
219 cerr << "ERROR: Matrix nr. " << i << " has column and row count of (" << ColumnCounter << "," << RowCounter[i] << "), could not allocate nor parse!" << endl;
220 }
221 input.close();
222 }
223 return true;
224};
225
226/** Allocates and resets the memory for a number \a MCounter of matrices.
227 * \param *GivenHeader Header line
228 * \param MCounter number of matrices
229 * \param *RCounter number of rows for each matrix
230 * \param CCounter number of columns for all matrices
231 * \return Allocation successful
232 */
233bool MatrixContainer::AllocateMatrix(char *GivenHeader, int MCounter, int *RCounter, int CCounter)
234{
235 Header = (char *) Malloc(sizeof(char)*1024, "MatrixContainer::ParseMatrix: *EnergyHeader");
236 strncpy(Header, GivenHeader, 1023);
237
238 MatrixCounter = MCounter;
239 ColumnCounter = CCounter;
240 Matrix = (double ***) Malloc(sizeof(double **)*(MatrixCounter+1), "MatrixContainer::ParseMatrix: ***Matrix"); // one more each for the total molecule
241 RowCounter = (int *) Malloc(sizeof(int)*(MatrixCounter+1), "MatrixContainer::ParseMatrix: *RowCounter");
242 for(int i=MatrixCounter+1;i--;) {
243 RowCounter[i] = RCounter[i];
244 Matrix[i] = (double **) Malloc(sizeof(double *)*(RowCounter[i]+1), "MatrixContainer::ParseMatrix: **Matrix[]");
245 for(int j=RowCounter[i]+1;j--;) {
246 Matrix[i][j] = (double *) Malloc(sizeof(double)*ColumnCounter, "MatrixContainer::ParseMatrix: *Matrix[][]");
247 for(int k=ColumnCounter;k--;)
248 Matrix[i][j][k] = 0.;
249 }
250 }
251 return true;
252};
253
254/** Resets all values in MatrixContainer::Matrix.
255 * \return true if successful
256 */
257bool MatrixContainer::ResetMatrix()
258{
259 for(int i=MatrixCounter+1;i--;)
260 for(int j=RowCounter[i]+1;j--;)
261 for(int k=ColumnCounter;k--;)
262 Matrix[i][j][k] = 0.;
263 return true;
264};
265
266/** Scans all elements of MatrixContainer::Matrix for greatest absolute value.
267 * \return greatest value of MatrixContainer::Matrix
268 */
269double MatrixContainer::FindMaxValue()
270{
271 double max = Matrix[0][0][0];
272 for(int i=MatrixCounter+1;i--;)
273 for(int j=RowCounter[i]+1;j--;)
274 for(int k=ColumnCounter;k--;)
275 if (fabs(Matrix[i][j][k]) > max)
276 max = fabs(Matrix[i][j][k]);
277 if (fabs(max) < MYEPSILON)
278 max += MYEPSILON;
279 return max;
280};
281
282/** Scans all elements of MatrixContainer::Matrix for smallest absolute value.
283 * \return smallest value of MatrixContainer::Matrix
284 */
285double MatrixContainer::FindMinValue()
286{
287 double min = Matrix[0][0][0];
288 for(int i=MatrixCounter+1;i--;)
289 for(int j=RowCounter[i]+1;j--;)
290 for(int k=ColumnCounter;k--;)
291 if (fabs(Matrix[i][j][k]) < min)
292 min = fabs(Matrix[i][j][k]);
293 if (fabs(min) < MYEPSILON)
294 min += MYEPSILON;
295 return min;
296};
297
298/** Sets all values in the last of MatrixContainer::Matrix to \a value.
299 * \param value reset value
300 * \param skipcolumns skip initial columns
301 * \return true if successful
302 */
303bool MatrixContainer::SetLastMatrix(double value, int skipcolumns)
304{
305 for(int j=RowCounter[MatrixCounter]+1;j--;)
306 for(int k=skipcolumns;k<ColumnCounter;k++)
307 Matrix[MatrixCounter][j][k] = value;
308 return true;
309};
310
311/** Sets all values in the last of MatrixContainer::Matrix to \a value.
312 * \param **values matrix with each value (must have at least same dimensions!)
313 * \param skipcolumns skip initial columns
314 * \return true if successful
315 */
316bool MatrixContainer::SetLastMatrix(double **values, int skipcolumns)
317{
318 for(int j=RowCounter[MatrixCounter]+1;j--;)
319 for(int k=skipcolumns;k<ColumnCounter;k++)
320 Matrix[MatrixCounter][j][k] = values[j][k];
321 return true;
322};
323
324/** Sums the energy with each factor and put into last element of \a ***Energies.
325 * Sums over "E"-terms to create the "F"-terms
326 * \param Matrix MatrixContainer with matrices (LevelCounter by ColumnCounter) with all the energies.
327 * \param KeySet KeySetContainer with bond Order and association mapping of each fragment to an order
328 * \param Order bond order
329 * \return true if summing was successful
330 */
331bool MatrixContainer::SumSubManyBodyTerms(class MatrixContainer &MatrixValues, class KeySetsContainer &KeySet, int Order)
332{
333 // go through each order
334 for (int CurrentFragment=0;CurrentFragment<KeySet.FragmentsPerOrder[Order];CurrentFragment++) {
335 //cout << "Current Fragment is " << CurrentFragment << "/" << KeySet.OrderSet[Order][CurrentFragment] << "." << endl;
336 // then go per order through each suborder and pick together all the terms that contain this fragment
337 for(int SubOrder=0;SubOrder<=Order;SubOrder++) { // go through all suborders up to the desired order
338 for (int j=0;j<KeySet.FragmentsPerOrder[SubOrder];j++) { // go through all possible fragments of size suborder
339 if (KeySet.Contains(KeySet.OrderSet[Order][CurrentFragment], KeySet.OrderSet[SubOrder][j])) {
340 //cout << "Current other fragment is " << j << "/" << KeySet.OrderSet[SubOrder][j] << "." << endl;
341 // if the fragment's indices are all in the current fragment
342 for(int k=0;k<RowCounter[ KeySet.OrderSet[SubOrder][j] ];k++) { // go through all atoms in this fragment
343 int m = MatrixValues.Indices[ KeySet.OrderSet[SubOrder][j] ][k];
344 //cout << "Current index is " << k << "/" << m << "." << endl;
345 if (m != -1) { // if it's not an added hydrogen
346 for (int l=0;l<RowCounter[ KeySet.OrderSet[Order][CurrentFragment] ];l++) { // look for the corresponding index in the current fragment
347 //cout << "Comparing " << m << " with " << MatrixValues.Indices[ KeySet.OrderSet[Order][CurrentFragment] ][l] << "." << endl;
348 if (m == MatrixValues.Indices[ KeySet.OrderSet[Order][CurrentFragment] ][l]) {
349 m = l;
350 break;
351 }
352 }
353 //cout << "Corresponding index in CurrentFragment is " << m << "." << endl;
354 if (m > RowCounter[ KeySet.OrderSet[Order][CurrentFragment] ]) {
355 cerr << "In fragment No. " << KeySet.OrderSet[Order][CurrentFragment] << " current force index " << m << " is greater than " << RowCounter[ KeySet.OrderSet[Order][CurrentFragment] ] << "!" << endl;
356 return false;
357 }
358 if (Order == SubOrder) { // equal order is always copy from Energies
359 for(int l=ColumnCounter;l--;) // then adds/subtract each column
360 Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][m][l] += MatrixValues.Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l];
361 } else {
362 for(int l=ColumnCounter;l--;)
363 Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][m][l] -= Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l];
364 }
365 }
366 //if ((ColumnCounter>1) && (RowCounter[0]-1 >= 1))
367 //cout << "Fragments[ KeySet.OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySet.OrderSet[Order][CurrentFragment] << " ][" << RowCounter[0]-1 << "][" << 1 << "] = " << Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][RowCounter[0]-1][1] << endl;
368 }
369 } else {
370 //cout << "Fragment " << KeySet.OrderSet[SubOrder][j] << " is not contained in fragment " << KeySet.OrderSet[Order][CurrentFragment] << "." << endl;
371 }
372 }
373 }
374 //cout << "Final Fragments[ KeySet.OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySet.OrderSet[Order][CurrentFragment] << " ][" << KeySet.AtomCounter[0]-1 << "][" << 1 << "] = " << Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][KeySet.AtomCounter[0]-1][1] << endl;
375 }
376
377 return true;
378};
379
380/** Writes the summed total fragment terms \f$F_{ij}\f$ to file.
381 * \param *name inputdir
382 * \param *prefix prefix before \a EnergySuffix
383 * \return file was written
384 */
385bool MatrixContainer::WriteTotalFragments(const char *name, const char *prefix)
386{
387 ofstream output;
388 char *FragmentNumber = NULL;
389
390 cout << "Writing fragment files." << endl;
391 for(int i=0;i<MatrixCounter;i++) {
392 stringstream line;
393 FragmentNumber = FixedDigitNumber(MatrixCounter, i);
394 line << name << FRAGMENTPREFIX << FragmentNumber << "/" << prefix;
395 Free((void **)&FragmentNumber, "*FragmentNumber");
396 output.open(line.str().c_str(), ios::out);
397 if (output == NULL) {
398 cerr << "Unable to open output energy file " << line.str() << "!" << endl;
399 return false;
400 }
401 output << Header << endl;
402 for(int j=0;j<RowCounter[i];j++) {
403 for(int k=0;k<ColumnCounter;k++)
404 output << scientific << Matrix[i][j][k] << "\t";
405 output << endl;
406 }
407 output.close();
408 }
409 return true;
410};
411
412/** Writes the summed total values in the last matrix to file.
413 * \param *name inputdir
414 * \param *prefix prefix
415 * \param *suffix suffix
416 * \return file was written
417 */
418bool MatrixContainer::WriteLastMatrix(const char *name, const char *prefix, const char *suffix)
419{
420 ofstream output;
421 stringstream line;
422
423 cout << "Writing matrix values of " << suffix << "." << endl;
424 line << name << prefix << suffix;
425 output.open(line.str().c_str(), ios::out);
426 if (output == NULL) {
427 cerr << "Unable to open output matrix file " << line.str() << "!" << endl;
428 return false;
429 }
430 output << Header << endl;
431 for(int j=0;j<RowCounter[MatrixCounter];j++) {
432 for(int k=0;k<ColumnCounter;k++)
433 output << scientific << Matrix[MatrixCounter][j][k] << "\t";
434 output << endl;
435 }
436 output.close();
437 return true;
438};
439
440// ======================================= CLASS EnergyMatrix =============================
441
442/** Create a trivial energy index mapping.
443 * This just maps 1 to 1, 2 to 2 and so on for all fragments.
444 * \return creation sucessful
445 */
446bool EnergyMatrix::ParseIndices()
447{
448 cout << "Parsing energy indices." << endl;
449 Indices = (int **) Malloc(sizeof(int *)*(MatrixCounter+1), "EnergyMatrix::ParseIndices: **Indices");
450 for(int i=MatrixCounter+1;i--;) {
451 Indices[i] = (int *) Malloc(sizeof(int)*RowCounter[i], "EnergyMatrix::ParseIndices: *Indices[]");
452 for(int j=RowCounter[i];j--;)
453 Indices[i][j] = j;
454 }
455 return true;
456};
457
458/** Sums the energy with each factor and put into last element of \a EnergyMatrix::Matrix.
459 * Sums over the "F"-terms in ANOVA decomposition.
460 * \param Matrix MatrixContainer with matrices (LevelCounter by ColumnCounter) with all the energies.
461 * \param CorrectionFragments MatrixContainer with hydrogen saturation correction per fragments
462 * \param KeySet KeySetContainer with bond Order and association mapping of each fragment to an order
463 * \param Order bond order
464 * \parsm sign +1 or -1
465 * \return true if summing was successful
466 */
467bool EnergyMatrix::SumSubEnergy(class EnergyMatrix &Fragments, class EnergyMatrix *CorrectionFragments, class KeySetsContainer &KeySet, int Order, double sign)
468{
469 // sum energy
470 if (CorrectionFragments == NULL)
471 for(int i=KeySet.FragmentsPerOrder[Order];i--;)
472 for(int j=RowCounter[ KeySet.OrderSet[Order][i] ];j--;)
473 for(int k=ColumnCounter;k--;)
474 Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ KeySet.OrderSet[Order][i] ][j][k];
475 else
476 for(int i=KeySet.FragmentsPerOrder[Order];i--;)
477 for(int j=RowCounter[ KeySet.OrderSet[Order][i] ];j--;)
478 for(int k=ColumnCounter;k--;)
479 Matrix[MatrixCounter][j][k] += sign*(Fragments.Matrix[ KeySet.OrderSet[Order][i] ][j][k] + CorrectionFragments->Matrix[ KeySet.OrderSet[Order][i] ][j][k]);
480 return true;
481};
482
483// ======================================= CLASS ForceMatrix =============================
484
485/** Parsing force Indices of each fragment
486 * \param *name directory with \a ForcesFile
487 * \return parsing successful
488 */
489bool ForceMatrix::ParseIndices(char *name)
490{
491 ifstream input;
492 char *FragmentNumber = NULL;
493 char filename[1023];
494 stringstream line;
495
496 cout << "Parsing force indices for " << MatrixCounter << " matrices." << endl;
497 Indices = (int **) Malloc(sizeof(int *)*(MatrixCounter+1), "ForceMatrix::ParseIndices: **Indices");
498 line << name << FRAGMENTPREFIX << FORCESFILE;
499 input.open(line.str().c_str(), ios::in);
500 //cout << "Opening " << line.str() << " ... " << input << endl;
501 if (input == NULL) {
502 cout << endl << "Unable to open " << line.str() << ", is the directory correct?" << endl;
503 return false;
504 }
505 for (int i=0;(i<MatrixCounter) && (!input.eof());i++) {
506 // get the number of atoms for this fragment
507 input.getline(filename, 1023);
508 line.str(filename);
509 // parse the values
510 Indices[i] = (int *) Malloc(sizeof(int)*RowCounter[i], "ForceMatrix::ParseIndices: *Indices[]");
511 FragmentNumber = FixedDigitNumber(MatrixCounter, i);
512 //cout << FRAGMENTPREFIX << FragmentNumber << "[" << RowCounter[i] << "]:";
513 Free((void **)&FragmentNumber, "ForceMatrix::ParseIndices: *FragmentNumber");
514 for(int j=0;(j<RowCounter[i]) && (!line.eof());j++) {
515 line >> Indices[i][j];
516 //cout << " " << Indices[i][j];
517 }
518 //cout << endl;
519 }
520 Indices[MatrixCounter] = (int *) Malloc(sizeof(int)*RowCounter[MatrixCounter], "ForceMatrix::ParseIndices: *Indices[]");
521 for(int j=RowCounter[MatrixCounter];j--;) {
522 Indices[MatrixCounter][j] = j;
523 }
524 input.close();
525 return true;
526};
527
528
529/** Sums the forces and puts into last element of \a ForceMatrix::Matrix.
530 * \param Matrix MatrixContainer with matrices (LevelCounter by ColumnCounter) with all the energies.
531 * \param KeySet KeySetContainer with bond Order and association mapping of each fragment to an order
532 * \param Order bond order
533 * \param sign +1 or -1
534 * \return true if summing was successful
535 */
536bool ForceMatrix::SumSubForces(class ForceMatrix &Fragments, class KeySetsContainer &KeySet, int Order, double sign)
537{
538 int FragmentNr;
539 // sum forces
540 for(int i=0;i<KeySet.FragmentsPerOrder[Order];i++) {
541 FragmentNr = KeySet.OrderSet[Order][i];
542 for(int l=0;l<RowCounter[ FragmentNr ];l++) {
543 int j = Indices[ FragmentNr ][l];
544 if (j > RowCounter[MatrixCounter]) {
545 cerr << "Current force index " << j << " is greater than " << RowCounter[MatrixCounter] << "!" << endl;
546 return false;
547 }
548 if (j != -1) {
549 //if (j == 0) cout << "Summing onto ion 0, type 0 from fragment " << FragmentNr << ", ion " << l << "." << endl;
550 for(int k=2;k<ColumnCounter;k++)
551 Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ FragmentNr ][l][k];
552 }
553 }
554 }
555 return true;
556};
557
558
559// ======================================= CLASS KeySetsContainer =============================
560
561/** Constructor of KeySetsContainer class.
562 */
563KeySetsContainer::KeySetsContainer() {
564 KeySets = NULL;
565 AtomCounter = NULL;
566 FragmentCounter = 0;
567 Order = 0;
568 FragmentsPerOrder = 0;
569 OrderSet = NULL;
570};
571
572/** Destructor of KeySetsContainer class.
573 */
574KeySetsContainer::~KeySetsContainer() {
575 for(int i=FragmentCounter;i--;)
576 Free((void **)&KeySets[i], "KeySetsContainer::~KeySetsContainer: *KeySets[]");
577 for(int i=Order;i--;)
578 Free((void **)&OrderSet[i], "KeySetsContainer::~KeySetsContainer: *OrderSet[]");
579 Free((void **)&KeySets, "KeySetsContainer::~KeySetsContainer: **KeySets");
580 Free((void **)&OrderSet, "KeySetsContainer::~KeySetsContainer: **OrderSet");
581 Free((void **)&AtomCounter, "KeySetsContainer::~KeySetsContainer: *AtomCounter");
582 Free((void **)&FragmentsPerOrder, "KeySetsContainer::~KeySetsContainer: *FragmentsPerOrder");
583};
584
585/** Parsing KeySets into array.
586 * \param *name directory with keyset file
587 * \param *ACounter number of atoms per fragment
588 * \param FCounter number of fragments
589 * \return parsing succesful
590 */
591bool KeySetsContainer::ParseKeySets(const char *name, const int *ACounter, const int FCounter) {
592 ifstream input;
593 char *FragmentNumber = NULL;
594 stringstream file;
595 char filename[1023];
596
597 FragmentCounter = FCounter;
598 cout << "Parsing key sets." << endl;
599 KeySets = (int **) Malloc(sizeof(int *)*FragmentCounter, "KeySetsContainer::ParseKeySets: **KeySets");
600 for(int i=FragmentCounter;i--;)
601 KeySets[i] = NULL;
602 file << name << FRAGMENTPREFIX << KEYSETFILE;
603 input.open(file.str().c_str(), ios::in);
604 if (input == NULL) {
605 cout << endl << "Unable to open " << file.str() << ", is the directory correct?" << endl;
606 return false;
607 }
608
609 AtomCounter = (int *) Malloc(sizeof(int)*FragmentCounter, "KeySetsContainer::ParseKeySets: *RowCounter");
610 for(int i=0;(i<FragmentCounter) && (!input.eof());i++) {
611 stringstream line;
612 AtomCounter[i] = ACounter[i];
613 // parse the values
614 KeySets[i] = (int *) Malloc(sizeof(int)*AtomCounter[i], "KeySetsContainer::ParseKeySets: *KeySets[]");
615 for(int j=AtomCounter[i];j--;)
616 KeySets[i][j] = -1;
617 FragmentNumber = FixedDigitNumber(FragmentCounter, i);
618 //cout << FRAGMENTPREFIX << FragmentNumber << "[" << AtomCounter[i] << "]:";
619 Free((void **)&FragmentNumber, "KeySetsContainer::ParseKeySets: *FragmentNumber");
620 input.getline(filename, 1023);
621 line.str(filename);
622 for(int j=0;(j<AtomCounter[i]) && (!line.eof());j++) {
623 line >> KeySets[i][j];
624 //cout << " " << KeySets[i][j];
625 }
626 //cout << endl;
627 }
628 input.close();
629 return true;
630};
631
632/** Parse many body terms, associating each fragment to a certain bond order.
633 * \return parsing succesful
634 */
635bool KeySetsContainer::ParseManyBodyTerms()
636{
637 int Counter;
638
639 cout << "Creating Fragment terms." << endl;
640 // scan through all to determine maximum order
641 Order=0;
642 for(int i=FragmentCounter;i--;) {
643 Counter=0;
644 for(int j=AtomCounter[i];j--;)
645 if (KeySets[i][j] != -1)
646 Counter++;
647 if (Counter > Order)
648 Order = Counter;
649 }
650 cout << "Found Order is " << Order << "." << endl;
651
652 // scan through all to determine fragments per order
653 FragmentsPerOrder = (int *) Malloc(sizeof(int)*Order, "KeySetsContainer::ParseManyBodyTerms: *FragmentsPerOrder");
654 for(int i=Order;i--;)
655 FragmentsPerOrder[i] = 0;
656 for(int i=FragmentCounter;i--;) {
657 Counter=0;
658 for(int j=AtomCounter[i];j--;)
659 if (KeySets[i][j] != -1)
660 Counter++;
661 FragmentsPerOrder[Counter-1]++;
662 }
663 for(int i=0;i<Order;i++)
664 cout << "Found No. of Fragments of Order " << i+1 << " is " << FragmentsPerOrder[i] << "." << endl;
665
666 // scan through all to gather indices to each order set
667 OrderSet = (int **) Malloc(sizeof(int *)*Order, "KeySetsContainer::ParseManyBodyTerms: **OrderSet");
668 for(int i=Order;i--;)
669 OrderSet[i] = (int *) Malloc(sizeof(int)*FragmentsPerOrder[i], "KeySetsContainer::ParseManyBodyTermsKeySetsContainer::ParseManyBodyTerms: *OrderSet[]");
670 for(int i=Order;i--;)
671 FragmentsPerOrder[i] = 0;
672 for(int i=FragmentCounter;i--;) {
673 Counter=0;
674 for(int j=AtomCounter[i];j--;)
675 if (KeySets[i][j] != -1)
676 Counter++;
677 OrderSet[Counter-1][FragmentsPerOrder[Counter-1]] = i;
678 FragmentsPerOrder[Counter-1]++;
679 }
680 cout << "Printing OrderSet." << endl;
681 for(int i=0;i<Order;i++) {
682 for (int j=0;j<FragmentsPerOrder[i];j++) {
683 cout << " " << OrderSet[i][j];
684 }
685 cout << endl;
686 }
687 cout << endl;
688
689
690 return true;
691};
692
693/** Compares each entry in \a *SmallerSet if it is containted in \a *GreaterSet.
694 * \param GreaterSet index to greater set
695 * \param SmallerSet index to smaller set
696 * \return true if all keys of SmallerSet contained in GreaterSet
697 */
698bool KeySetsContainer::Contains(const int GreaterSet, const int SmallerSet)
699{
700 bool result = true;
701 bool intermediate;
702 if ((GreaterSet < 0) || (SmallerSet < 0) || (GreaterSet > FragmentCounter) || (SmallerSet > FragmentCounter)) // index out of bounds
703 return false;
704 for(int i=AtomCounter[SmallerSet];i--;) {
705 intermediate = false;
706 for (int j=AtomCounter[GreaterSet];j--;)
707 intermediate = (intermediate || ((KeySets[SmallerSet][i] == KeySets[GreaterSet][j]) || (KeySets[SmallerSet][i] == -1)));
708 result = result && intermediate;
709 }
710
711 return result;
712};
713
714
715// ======================================= END =============================================
Note: See TracBrowser for help on using the repository browser.