source: src/Parser/PcpParser_helper.cpp@ bcfb77

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 bcfb77 was 41a467, checked in by Frederik Heber <heber@…>, 13 years ago

LARGE: config class is now just a tiny container.

  • this was loooooobg overdue. Config.cpp contained remnants from parsing pcp files and much else. Also fragmentation depended on it. Since refactoring of MoleculeListClass and the fragmentation, we don't need it anymore.
  • helper functions ParseForParameters(), LoadMolecule() extracted into new module PcpParser_helper.
  • config class now just contains 4 variables that are generally required (especially IsAngstroem) and they should probably remain with the world.
  • removed some places where config.hpp was no unnecessarily included.
  • Moved ConfigFileBuffer.* over to subfolder src/Parser/ where it rather belongs (associated with PcpParser).
  • Property mode set to 100644
File size: 29.2 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/*
9 * PcpParser_helper.cpp
10 *
11 * Created on: Oct 27, 2011
12 * Author: heber
13 */
14
15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
20#include "CodePatterns/MemDebug.hpp"
21
22#include <boost/tokenizer.hpp>
23#include <sstream>
24#include <string>
25
26#include "CodePatterns/Log.hpp"
27#include "Element/element.hpp"
28#include "Element/periodentafel.hpp"
29#include "Helpers/helpers.hpp"
30#include "molecule.hpp"
31#include "Parser/ConfigFileBuffer.hpp"
32
33/** Reads parameter from a parsed file.
34 * The file is either parsed for a certain keyword or if null is given for
35 * the value in row yth and column xth. If the keyword was necessity#critical,
36 * then an error is thrown and the programme aborted.
37 * \warning value is modified (both in contents and position)!
38 * \param verbose 1 - print found value to stderr, 0 - don't
39 * \param *file file to be parsed
40 * \param name Name of value in file (at least 3 chars!)
41 * \param sequential 1 - do not reset file pointer to begin of file, 0 - set to beginning
42 * (if file is sequentially parsed this can be way faster! However, beware of multiple values per line, as whole line is read -
43 * best approach: 0 0 0 1 (not resetted only on last value of line) - and of yth, which is now
44 * counted from this unresetted position!)
45 * \param xth Which among a number of parameters it is (in grid case it's row number as grid is read as a whole!)
46 * \param yth In grid case specifying column number, otherwise the yth \a name matching line
47 * \param type Type of the Parameter to be read
48 * \param value address of the value to be read (must have been allocated)
49 * \param repetition determines, if the keyword appears multiply in the config file, which repetition shall be parsed, i.e. 1 if not multiply
50 * \param critical necessity of this keyword being specified (optional, critical)
51 * \return 1 - found, 0 - not found
52 * \note Routine is taken from the pcp project and hack-a-slack adapted to C++
53 */
54int ParseForParameter(const int verbose, ifstream * const file, const char * const name, const int sequential, const int xth, const int yth, const int type, void * value, const int repetition, const int critical) {
55 int i = 0;
56 int j = 0; // loop variables
57 int length = 0;
58 int maxlength = -1;
59 long file_position = file->tellg(); // mark current position
60 char *dummy1 = NULL;
61 char *dummy = NULL;
62 char free_dummy[MAXSTRINGSIZE]; // pointers in the line that is read in per step
63 dummy1 = free_dummy;
64
65 //fprintf(stderr,"Parsing for %s\n",name);
66 if (repetition == 0)
67 //Error(SomeError, "ParseForParameter(): argument repetition must not be 0!");
68 return 0;
69
70 int line = 0; // marks line where parameter was found
71 int found = (type >= grid) ? 0 : (-yth + 1); // marks if yth parameter name was found
72 while((found != repetition)) {
73 dummy1 = dummy = free_dummy;
74 do {
75 file->getline(dummy1, 256); // Read the whole line
76 if (file->eof()) {
77 if ((critical) && (found == 0)) {
78 //Error(InitReading, name);
79 fprintf(stderr,"Error:InitReading, critical %s not found\n", name);
80 exit(255);
81 } else {
82 //if (!sequential)
83 file->clear();
84 file->seekg(file_position, ios::beg); // rewind to start position
85 return 0;
86 }
87 }
88 line++;
89 } while (dummy != NULL && dummy1 != NULL && ((dummy1[0] == '#') || (dummy1[0] == '\0'))); // skip commentary and empty lines
90
91 // C++ getline removes newline at end, thus re-add
92 if ((dummy1 != NULL) && (strchr(dummy1,'\n') == NULL)) {
93 i = strlen(dummy1);
94 dummy1[i] = '\n';
95 dummy1[i+1] = '\0';
96 }
97 //fprintf(stderr,"line %i ends at %i, newline at %i\n", line, strlen(dummy1), strchr(dummy1,'\n')-free_dummy);
98
99 if (dummy1 == NULL) {
100 if (verbose) fprintf(stderr,"Error reading line %i\n",line);
101 } else {
102 //fprintf(stderr,"Now parsing the line %i: %s\n", line, dummy1);
103 }
104 // Seek for possible end of keyword on line if given ...
105 if (name != NULL) {
106 dummy = strchr(dummy1,'\t'); // set dummy on first tab or space which ever's nearer
107 if (dummy == NULL) {
108 dummy = strchr(dummy1, ' '); // if not found seek for space
109 while ((dummy != NULL) && ((*dummy == '\t') || (*dummy == ' '))) // skip some more tabs and spaces if necessary
110 dummy++;
111 }
112 if (dummy == NULL) {
113 dummy = strchr(dummy1, '\n'); // set on line end then (whole line = keyword)
114 //fprintf(stderr,"Error: Cannot find tabs or spaces on line %i in search for %s\n", line, name);
115 //Error(FileOpenParams, NULL);
116 } else {
117 //fprintf(stderr,"found tab at %i\n",(char *)dummy-(char *)dummy1);
118 }
119 } else dummy = dummy1;
120 // ... and check if it is the keyword!
121 //fprintf(stderr,"name %p, dummy %i/%c, dummy1 %i/%c, strlen(name) %i\n", &name, dummy, *dummy, dummy1, *dummy1, strlen(name));
122 if ((name == NULL) || (((dummy-dummy1 >= 3) && (strncmp(dummy1, name, strlen(name)) == 0)) && ((unsigned int)(dummy-dummy1) == strlen(name)))) {
123 found++; // found the parameter!
124 //fprintf(stderr,"found %s at line %i between %i and %i\n", name, line, dummy1, dummy);
125
126 if (found == repetition) {
127 for (i=0;i<xth;i++) { // i = rows
128 if (type >= grid) {
129 // grid structure means that grid starts on the next line, not right after keyword
130 dummy1 = dummy = free_dummy;
131 do {
132 file->getline(dummy1, 256); // Read the whole line, skip commentary and empty ones
133 if (file->eof()) {
134 if ((critical) && (found == 0)) {
135 //Error(InitReading, name);
136 fprintf(stderr,"Error:InitReading, critical %s not found\n", name);
137 exit(255);
138 } else {
139 //if (!sequential)
140 file->clear();
141 file->seekg(file_position, ios::beg); // rewind to start position
142 return 0;
143 }
144 }
145 line++;
146 } while ((dummy1[0] == '#') || (dummy1[0] == '\n'));
147 if (dummy1 == NULL){
148 if (verbose) fprintf(stderr,"Error reading line %i\n", line);
149 } else {
150 //fprintf(stderr,"Reading next line %i: %s\n", line, dummy1);
151 }
152 } else { // simple int, strings or doubles start in the same line
153 while ((*dummy == '\t') || (*dummy == ' ')) // skip interjacent tabs and spaces
154 dummy++;
155 }
156 // C++ getline removes newline at end, thus re-add
157 if ((dummy1 != NULL) && (strchr(dummy1,'\n') == NULL)) {
158 j = strlen(dummy1);
159 dummy1[j] = '\n';
160 dummy1[j+1] = '\0';
161 }
162
163 int start = (type >= grid) ? 0 : yth-1 ;
164 for (j=start;j<yth;j++) { // j = columns
165 // check for lower triangular area and upper triangular area
166 if ( ((i > j) && (type == upper_trigrid)) || ((j > i) && (type == lower_trigrid))) {
167 *((double *)value) = 0.0;
168 fprintf(stderr,"%f\t",*((double *)value));
169 value = (void *)((long)value + sizeof(double));
170 //value += sizeof(double);
171 } else {
172 // otherwise we must skip all interjacent tabs and spaces and find next value
173 dummy1 = dummy;
174 dummy = strchr(dummy1, '\t'); // seek for tab or space
175 if (dummy == NULL)
176 dummy = strchr(dummy1, ' '); // if not found seek for space
177 if (dummy == NULL) { // if still zero returned ...
178 dummy = strchr(dummy1, '\n'); // ... at line end then
179 if ((j < yth-1) && (type < 4)) { // check if xth value or not yet
180 if (critical) {
181 if (verbose) fprintf(stderr,"Error: EoL at %i and still missing %i value(s) for parameter %s\n", line, yth-j, name);
182 //return 0;
183 exit(255);
184 //Error(FileOpenParams, NULL);
185 } else {
186 //if (!sequential)
187 file->clear();
188 file->seekg(file_position, ios::beg); // rewind to start position
189 return 0;
190 }
191 }
192 } else {
193 //fprintf(stderr,"found tab at %i\n",(char *)dummy-(char *)free_dummy);
194 }
195 if (*dummy1 == '#') {
196 // found comment, skipping rest of line
197 //if (verbose) fprintf(stderr,"Error: '#' at %i and still missing %i value(s) for parameter %s\n", line, yth-j, name);
198 if (!sequential) { // here we need it!
199 file->seekg(file_position, ios::beg); // rewind to start position
200 }
201 return 0;
202 }
203 //fprintf(stderr,"value from %i to %i\n",(char *)dummy1-(char *)free_dummy,(char *)dummy-(char *)free_dummy);
204 switch(type) {
205 case (row_int):
206 *((int *)value) = atoi(dummy1);
207 if ((verbose) && (i==0) && (j==0)) fprintf(stderr,"%s = ", name);
208 if (verbose) fprintf(stderr,"%i\t",*((int *)value));
209 value = (void *)((long)value + sizeof(int));
210 //value += sizeof(int);
211 break;
212 case(row_double):
213 case(grid):
214 case(lower_trigrid):
215 case(upper_trigrid):
216 *((double *)value) = atof(dummy1);
217 if ((verbose) && (i==0) && (j==0)) fprintf(stderr,"%s = ", name);
218 if (verbose) fprintf(stderr,"%lg\t",*((double *)value));
219 value = (void *)((long)value + sizeof(double));
220 //value += sizeof(double);
221 break;
222 case(double_type):
223 *((double *)value) = atof(dummy1);
224 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s = %lg\n", name, *((double *) value));
225 //value += sizeof(double);
226 break;
227 case(int_type):
228 *((int *)value) = atoi(dummy1);
229 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s = %i\n", name, *((int *) value));
230 //value += sizeof(int);
231 break;
232 default:
233 case(string_type):
234 if (value != NULL) {
235 //if (maxlength == -1) maxlength = strlen((char *)value); // get maximum size of string array
236 maxlength = MAXSTRINGSIZE;
237 length = maxlength > (dummy-dummy1) ? (dummy-dummy1) : maxlength; // cap at maximum
238 strncpy((char *)value, dummy1, length); // copy as much
239 ((char *)value)[length] = '\0'; // and set end marker
240 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s is '%s' (%i chars)\n",name,((char *) value), length);
241 //value += sizeof(char);
242 } else {
243 }
244 break;
245 }
246 }
247 while (*dummy == '\t')
248 dummy++;
249 }
250 }
251 }
252 }
253 }
254 if ((type >= row_int) && (verbose))
255 fprintf(stderr,"\n");
256 if (!sequential) {
257 file->clear();
258 file->seekg(file_position, ios::beg); // rewind to start position
259 }
260 //fprintf(stderr, "End of Parsing\n\n");
261
262 return (found); // true if found, false if not
263}
264
265
266/** Reads parameter from a parsed file.
267 * The file is either parsed for a certain keyword or if null is given for
268 * the value in row yth and column xth. If the keyword was necessity#critical,
269 * then an error is thrown and the programme aborted.
270 * \warning value is modified (both in contents and position)!
271 * \param verbose 1 - print found value to stderr, 0 - don't
272 * \param *FileBuffer pointer to buffer structure
273 * \param name Name of value in file (at least 3 chars!)
274 * \param sequential 1 - do not reset file pointer to begin of file, 0 - set to beginning
275 * (if file is sequentially parsed this can be way faster! However, beware of multiple values per line, as whole line is read -
276 * best approach: 0 0 0 1 (not resetted only on last value of line) - and of yth, which is now
277 * counted from this unresetted position!)
278 * \param xth Which among a number of parameters it is (in grid case it's row number as grid is read as a whole!)
279 * \param yth In grid case specifying column number, otherwise the yth \a name matching line
280 * \param type Type of the Parameter to be read
281 * \param value address of the value to be read (must have been allocated)
282 * \param repetition determines, if the keyword appears multiply in the config file, which repetition shall be parsed, i.e. 1 if not multiply
283 * \param critical necessity of this keyword being specified (optional, critical)
284 * \return 1 - found, 0 - not found
285 * \note Routine is taken from the pcp project and hack-a-slack adapted to C++
286 */
287int ParseForParameter(const int verbose, struct ConfigFileBuffer * const FileBuffer, const char * const name, const int sequential, const int xth, const int yth, const int type, void * value, const int repetition, const int critical) {
288 int i = 0;
289 int j = 0; // loop variables
290 int length = 0;
291 int maxlength = -1;
292 int OldCurrentLine = FileBuffer->CurrentLine;
293 char *dummy1 = NULL;
294 char *dummy = NULL; // pointers in the line that is read in per step
295 char *free_dummy = NULL;
296
297 if (verbose) fprintf(stderr,"Begin of Parsing for %s\n",name);
298 if (repetition == 0)
299 //Error(SomeError, "ParseForParameter(): argument repetition must not be 0!");
300 return 0;
301
302 int found = (type >= grid) ? 0 : (-yth + 1); // marks if yth parameter name was found
303 while((found != repetition)) {
304 dummy1 = dummy = NULL;
305 do {
306 if (FileBuffer->CurrentLine < FileBuffer->NoLines)
307 free_dummy = dummy1 = FileBuffer->buffer[ FileBuffer->LineMapping[FileBuffer->CurrentLine++] ];
308 if (FileBuffer->CurrentLine >= FileBuffer->NoLines) {
309 if ((critical) && (found == 0)) {
310 //Error(InitReading, name);
311 fprintf(stderr,"Error:InitReading, critical %s not found\n", name);
312 return 0;
313 } else {
314 //fprintf(stdout,"Rewinding to OldCurrentLine due to search till end of file.\n");
315 FileBuffer->CurrentLine = OldCurrentLine; // rewind to start position
316 return 0;
317 }
318 }
319 if (dummy1 == NULL) {
320 if (verbose) fprintf(stderr,"Error reading line %i\n",FileBuffer->CurrentLine);
321 } else {
322 if (verbose) fprintf(stderr,"Now parsing the line %i: %s\n", FileBuffer->CurrentLine, dummy1);
323 }
324 //FileBuffer->CurrentLine++;
325 } while (dummy1 != NULL && ((dummy1[0] == '#') || (dummy1[0] == '\0'))); // skip commentary and empty lines
326
327 // Seek for possible end of keyword on line if given ...
328 if (name != NULL) {
329 dummy = strchr(dummy1,'\t'); // set dummy on first tab or space which ever's nearer
330 if (dummy == NULL) {
331 dummy = strchr(dummy1, ' '); // if not found seek for space
332 while ((dummy != NULL) && ((*dummy == '\t') || (*dummy == ' '))) // skip some more tabs and spaces if necessary
333 dummy++;
334 }
335 if (dummy == NULL) {
336 dummy = strchr(dummy1, '\n'); // set on line end then (whole line = keyword)
337 //fprintf(stderr,"Error: Cannot find tabs or spaces on line %i in search for %s\n", line, name);
338 //Error(FileOpenParams, NULL);
339 } else {
340 if (verbose) fprintf(stderr,"found tab at line %i at position %li\n",FileBuffer->CurrentLine, (char *)dummy-(char *)dummy1);
341 }
342 } else dummy = dummy1;
343 // ... and check if it is the keyword!
344 //fprintf(stderr,"name %p, dummy %i/%c, dummy1 %i/%c, strlen(name) %i\n", &name, dummy, *dummy, dummy1, *dummy1, strlen(name));
345 if ((name == NULL) || (((dummy-dummy1 >= 3) && (strncmp(dummy1, name, strlen(name)) == 0)) && ((unsigned int)(dummy-dummy1) == strlen(name)))) {
346 found++; // found the parameter!
347 if (verbose) fprintf(stderr,"found %s at line %i between %li and %li\n", name, FileBuffer->CurrentLine, (unsigned long)dummy1, (unsigned long)dummy);
348
349 if (found == repetition) {
350 for (i=0;i<xth;i++) { // i = rows
351 if (type >= grid) {
352 // grid structure means that grid starts on the next line, not right after keyword
353 dummy1 = dummy = NULL;
354 do {
355 dummy1 = FileBuffer->buffer[ FileBuffer->LineMapping[ FileBuffer->CurrentLine++] ];
356 if (FileBuffer->CurrentLine >= FileBuffer->NoLines) {
357 if ((critical) && (found == 0)) {
358 //Error(InitReading, name);
359 fprintf(stderr,"Error:InitReading, critical %s not found\n", name);
360 exit(255);
361 } else {
362 //fprintf(stdout,"Rewinding to OldCurrentLine due to search till end of line.\n");
363 FileBuffer->CurrentLine = OldCurrentLine; // rewind to start position
364 return 0;
365 }
366 }
367 if (dummy1 == NULL) {
368 if (verbose) fprintf(stderr,"Error reading line %i\n", FileBuffer->CurrentLine);
369 } else {
370 if (verbose) fprintf(stderr,"Reading next line %i: %s\n", FileBuffer->CurrentLine, dummy1);
371 }
372 //FileBuffer->CurrentLine++;
373 } while ((dummy1 != NULL) && ((dummy1[0] == '#') || (dummy1[0] == '\n')));
374 dummy = dummy1;
375 } else { // simple int, strings or doubles start in the same line
376 while ((*dummy == '\t') || (*dummy == ' ')) // skip interjacent tabs and spaces
377 dummy++;
378 }
379
380 for (j=((type >= grid) ? 0 : yth-1);j<yth;j++) { // j = columns
381 // check for lower triangular area and upper triangular area
382 if ( ((i > j) && (type == upper_trigrid)) || ((j > i) && (type == lower_trigrid))) {
383 *((double *)value) = 0.0;
384 fprintf(stderr,"%f\t",*((double *)value));
385 value = (void *)((long)value + sizeof(double));
386 //value += sizeof(double);
387 } else {
388 // otherwise we must skip all interjacent tabs and spaces and find next value
389 dummy1 = dummy;
390 dummy = strchr(dummy1, '\t'); // seek for tab or space
391 if (dummy == NULL)
392 dummy = strchr(dummy1, ' '); // if not found seek for space
393 if (dummy == NULL) { // if still zero returned ...
394 dummy = strchr(dummy1, '\n'); // ... at line end then
395 if ((j < yth-1) && (type < 4)) { // check if xth value or not yet
396 if (critical) {
397 if (verbose) fprintf(stderr,"Error: EoL at %i and still missing %i value(s) for parameter %s\n", FileBuffer->CurrentLine, yth-j, name);
398 //return 0;
399 exit(255);
400 //Error(FileOpenParams, NULL);
401 } else {
402 if (!sequential) { // here we need it!
403 //fprintf(stdout,"Rewinding to OldCurrentLine due to end of line and sequential %d.\n", sequential);
404 FileBuffer->CurrentLine = OldCurrentLine; // rewind to start position
405 }
406 return 0;
407 }
408 }
409 } else {
410 if (verbose) fprintf(stderr,"found tab at line %i at position %li\n",FileBuffer->CurrentLine, (char *)dummy-(char *)free_dummy);
411 }
412 if (*dummy1 == '#') {
413 // found comment, skipping rest of line
414 //if (verbose) fprintf(stderr,"Error: '#' at %i and still missing %i value(s) for parameter %s\n", line, yth-j, name);
415 if (!sequential) { // here we need it!
416 //fprintf(stdout,"Rewinding to OldCurrentLine due to comment and sequential %d.\n", sequential);
417 FileBuffer->CurrentLine = OldCurrentLine; // rewind to start position
418 }
419 return 0;
420 }
421 if (verbose) fprintf(stderr,"value from %li to %li\n",(char *)dummy1-(char *)free_dummy,(char *)dummy-(char *)free_dummy);
422 switch(type) {
423 case (row_int):
424 *((int *)value) = atoi(dummy1);
425 if ((verbose) && (i==0) && (j==0)) fprintf(stderr,"%s = ", name);
426 if (verbose) fprintf(stderr,"%i\t",*((int *)value));
427 value = (void *)((long)value + sizeof(int));
428 //value += sizeof(int);
429 break;
430 case(row_double):
431 case(grid):
432 case(lower_trigrid):
433 case(upper_trigrid):
434 *((double *)value) = atof(dummy1);
435 if ((verbose) && (i==0) && (j==0)) fprintf(stderr,"%s = ", name);
436 if (verbose) fprintf(stderr,"%lg\t",*((double *)value));
437 value = (void *)((long)value + sizeof(double));
438 //value += sizeof(double);
439 break;
440 case(double_type):
441 *((double *)value) = atof(dummy1);
442 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s = %lg\n", name, *((double *) value));
443 //value += sizeof(double);
444 break;
445 case(int_type):
446 *((int *)value) = atoi(dummy1);
447 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s = %i\n", name, *((int *) value));
448 //value += sizeof(int);
449 break;
450 default:
451 case(string_type):
452 if (value != NULL) {
453 //if (maxlength == -1) maxlength = strlen((char *)value); // get maximum size of string array
454 maxlength = MAXSTRINGSIZE;
455 length = maxlength > (dummy-dummy1) ? (dummy-dummy1) : maxlength; // cap at maximum
456 strncpy((char *)value, dummy1, length); // copy as much
457 ((char *)value)[length] = '\0'; // and set end marker
458 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s is '%s' (%i chars)\n",name,((char *) value), length);
459 //value += sizeof(char);
460 } else {
461 }
462 break;
463 }
464 }
465 while (*dummy == '\t')
466 dummy++;
467 }
468 }
469 }
470 }
471 }
472 if ((type >= row_int) && (verbose)) fprintf(stderr,"\n");
473 if (!sequential) {
474 //fprintf(stdout,"Rewinding to OldCurrentLine due to sequential %d.\n", sequential);
475 FileBuffer->CurrentLine = OldCurrentLine; // rewind to start position
476 }
477 if (verbose) fprintf(stderr, "End of Parsing for %s\n\n",name);
478
479 return (found); // true if found, false if not
480}
481
482/** Loads a molecule from a ConfigFileBuffer.
483 * \param *mol molecule to load
484 * \param *FileBuffer ConfigFileBuffer to use
485 * \param *periode periodentafel for finding elements
486 * \param FastParsing whether to parse trajectories or not
487 */
488void LoadMolecule(molecule * const &mol, struct ConfigFileBuffer * const &FileBuffer, const periodentafel * const periode, const bool FastParsing)
489{
490 int MaxTypes = 0;
491 const element *elementhash[MAX_ELEMENTS];
492 char name[MAXSTRINGSIZE];
493 int Z = -1;
494 int No[MAX_ELEMENTS];
495 int verbose = DoLog(4);
496 double value[3];
497
498 if (mol == NULL) {
499 ELOG(0, "Molecule is not allocated in LoadMolecule(), exit.");
500 performCriticalExit();
501 }
502
503 ParseForParameter(verbose,FileBuffer,"MaxTypes", 0, 1, 1, int_type, &(MaxTypes), 1, critical);
504 if (MaxTypes == 0) {
505 ELOG(1, "There are no atoms according to MaxTypes in this config file." << endl);
506 //performCriticalExit();
507 } else {
508 // prescan number of ions per type
509 LOG(0, "STATUS: Prescanning ions per type: " << endl);
510 int NoAtoms = 0;
511 for (int i=0; i < MaxTypes; i++) {
512 sprintf(name,"Ion_Type%i",i+1);
513 ParseForParameter(verbose,FileBuffer, (const char*)name, 0, 1, 1, int_type, &No[i], 1, critical);
514 ParseForParameter(verbose,FileBuffer, name, 0, 2, 1, int_type, &Z, 1, critical);
515 elementhash[i] = periode->FindElement(Z);
516 LOG(1, i << ". Z = " << elementhash[i]->getAtomicNumber() << " with " << No[i] << " ions.");
517 NoAtoms += No[i];
518 }
519 int repetition = -1; // which repeated keyword shall be read
520
521 // sort the lines via the LineMapping
522 sprintf(name,"Ion_Type%i",MaxTypes);
523 if (!ParseForParameter(verbose,FileBuffer, (const char*)name, 1, 1, 1, int_type, &value[0], 1, critical)) {
524 ELOG(0, "There are no atoms in the config file!" << endl);
525 performCriticalExit();
526 return;
527 }
528
529 FileBuffer->CurrentLine++; // skip to next line
530 FileBuffer->MapIonTypesInBuffer(NoAtoms);
531 for (int i=FileBuffer->CurrentLine; i<FileBuffer->NoLines;++i) {
532 LOG(4, FileBuffer->buffer[ FileBuffer->LineMapping[i] ]);
533 }
534
535 map<int, atom *> AtomList[MaxTypes];
536 map<int, atom *> LinearList;
537 atom *neues = NULL;
538 Vector tempVector;
539 int _fixedion;
540
541 typedef boost::tokenizer<boost::char_separator<char> >
542 tokenizer;
543 boost::char_separator<char> sep("\t ");
544 ConvertTo<double> toDouble;
545 ConvertTo<int> toInt;
546
547 for (int i=0; i < MaxTypes; i++) {
548 for(int j=0;j<No[i];j++) {
549 int step = 0;
550 std::stringstream keyword_stream;
551 keyword_stream << "Ion_Type" << i+1 << "_" << j+1;
552 const std::string keyword = keyword_stream.str();
553 LOG(3, "INFO: Parsing for " << keyword << "." << std::endl);
554 while (true) {
555 const std::string line(FileBuffer->buffer[ FileBuffer->LineMapping[FileBuffer->CurrentLine] ]);
556 const std::string line_without_comment = line.substr(0,line.find("#"));
557 tokenizer tokens(line_without_comment, sep);
558 if (tokens.begin() != tokens.end()) {
559 tokenizer::iterator tok_iter = tokens.begin();
560 const std::string token = *tok_iter++;
561 if (token == keyword) {
562 LOG(3, "INFO: Found keyword " << keyword << " in line " << FileBuffer->CurrentLine << std::endl);
563 if (step == 0) {
564 neues = World::getInstance().createAtom();
565 AtomList[i][j] = neues;
566 LOG(4, "Filling LinearList [ (FileBuffer->LineMapping[" << FileBuffer->CurrentLine << "]) = " << FileBuffer->LineMapping[FileBuffer->CurrentLine] << " with " << neues << endl);
567 LinearList[ FileBuffer->LineMapping[FileBuffer->CurrentLine] ] = neues;
568 neues->setType(elementhash[i]); // find element type
569 } else
570 neues = AtomList[i][j];
571
572 // count tokens
573 size_t tokens_size = 0;
574 for (tokenizer::iterator tokiter = tokens.begin(); tokiter != tokens.end(); ++tokiter)
575 ++tokens_size;
576 LOG(3, "INFO: Line contains " << tokens_size << " tokens." << std::endl);
577 // and parse
578 tempVector.Zero();
579 if (tokens_size >= 5) { // only AtomicPosition and FixedIon
580 for (int i=0;i<NDIM;++i)
581 tempVector[i] = toDouble(*tok_iter++);
582 neues->setPositionAtStep(step, tempVector);
583 _fixedion = toInt(*tok_iter++);
584 neues->setFixedIon(_fixedion == 1);
585 LOG(3, "INFO: Parsing AtomicPosition " << tempVector << " and FixedIon " << _fixedion << "." << std::endl);
586 }
587 tempVector.Zero();
588 if (tokens_size >= 8) { // AtomicVelocity
589 for (int i=0;i<NDIM;++i)
590 tempVector[i] = toDouble(*tok_iter++);
591 LOG(3, "INFO: Parsing AtomicVelocity " << tempVector << "." << std::endl);
592 }
593 neues->setAtomicVelocityAtStep(step, tempVector);
594 tempVector.Zero();
595 if (tokens_size >= 11) { // AtomicForce
596 LOG(3, "INFO: Parsing AtomicForce" << std::endl);
597 for (int i=0;i<NDIM;++i)
598 tempVector[i] = toDouble(*tok_iter++);
599 }
600 neues->setAtomicForceAtStep(step, tempVector);
601 std::stringstream output;
602 output << "Parsed position of step " << (step+1) << ": ";
603 output << neues->getPositionAtStep(step); // next step
604 output << "\t";
605 output << (neues->getFixedIon() ? "true" : "false");
606 output << "\t";
607 output << neues->getAtomicVelocityAtStep(step); // next step
608 output << "\t";
609 output << neues->getAtomicForceAtStep(step); // next step
610 LOG(2, output.str());
611
612 step++;
613 } else {
614 if ((repetition > step) || (repetition == -1))
615 repetition = step;
616 break;
617 }
618 }
619 FileBuffer->CurrentLine++;
620 }
621 }
622 }
623
624 if (repetition <= 1) // if onyl one step, desactivate use of trajectories
625 mol->MDSteps = 0;
626 else {
627 LOG(0, "Found " << repetition << " trajectory step(s).");
628 mol->MDSteps = repetition;
629 }
630
631 // put atoms into the molecule in their original order
632 for(map<int, atom*>::iterator runner = LinearList.begin(); runner != LinearList.end(); ++runner) {
633 mol->AddAtom(runner->second);
634 }
635 }
636}
Note: See TracBrowser for help on using the repository browser.