source: src/parser.cpp@ b61043

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 b61043 was 390248, checked in by Frederik Heber <heber@…>, 17 years ago

BIG change: Hcorrection included and bugfix of analyzer (wrt forces)

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