source: src/parser.cpp@ eeec8f

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

HessianMatrix implemented fully, but not yet working, probably due to wrong matrix generation in script file (convertHessian.py)

HessianMatrix::IsSymmetric was though to be needed, but is NOT. As we regard full matrices, we don't need to add onto mirrored indices as well
Joiner and Analyzer have seen some small changes and bugfixes: NoHessian was not also always looked at when needed and so on

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