source: src/Parser/PcpParser_helper.cpp@ 4a187d

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 4a187d was 76096d, checked in by Frederik Heber <heber@…>, 11 years ago

FIX: Several fixes found through CppCheck.

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