ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/InitializeFromFile.cpp
Revision: 1130
Committed: Thu Apr 22 14:55:17 2004 UTC (20 years, 2 months ago) by tim
File size: 16395 byte(s)
Log Message:
fixed another bug in InitFromFile. MPI verion of OOPSE is working again

File Contents

# Content
1 #define _FILE_OFFSET_BITS 64
2 #include <iostream>
3 #include <math.h>
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <unistd.h>
9 #include <sys/types.h>
10 #include <sys/stat.h>
11
12 #include "ReadWrite.hpp"
13 #include "simError.h"
14 #include "GenericData.hpp"
15
16 #ifdef IS_MPI
17 #include <mpi.h>
18 #include "mpiSimulation.hpp"
19 #define TAKE_THIS_TAG_CHAR 3134
20 #define TAKE_THIS_TAG_INT 3135
21
22 namespace initFile{
23 void nodeZeroError( void );
24 void anonymousNodeDie( void );
25 }
26
27 using namespace initFile;
28
29 #endif // is_mpi
30
31 InitializeFromFile::InitializeFromFile( char *in_name ){
32
33 #ifdef IS_MPI
34 if (worldRank == 0) {
35 #endif
36
37 c_in_file = fopen(in_name, "r");
38 if(c_in_file == NULL){
39 sprintf(painCave.errMsg,
40 "Cannot open file: %s\n", in_name);
41 painCave.isFatal = 1;
42 simError();
43 }
44
45 strcpy( c_in_name, in_name);
46 #ifdef IS_MPI
47 }
48 else{
49 sprintf( c_in_name, "mpiNodeParser_%d", worldRank );
50 }
51
52 strcpy( checkPointMsg, "Infile opened for reading successfully." );
53 MPIcheckPoint();
54 #endif
55 return;
56 }
57
58 InitializeFromFile::~InitializeFromFile( ){
59 #ifdef IS_MPI
60 if (worldRank == 0) {
61 #endif
62 int error;
63 error = fclose( c_in_file );
64 if( error ){
65 sprintf( painCave.errMsg,
66 "Error closing %s\n", c_in_name );
67 simError();
68 }
69 #ifdef IS_MPI
70 }
71 strcpy( checkPointMsg, "Infile closed successfully." );
72 MPIcheckPoint();
73 #endif
74
75 return;
76 }
77
78
79 void InitializeFromFile :: readInit( SimInfo* the_simnfo ){
80
81 int i, j;
82
83 #ifdef IS_MPI
84 int done, which_node, which_atom; // loop counter
85 #endif //is_mpi
86
87 const int BUFFERSIZE = 2000; // size of the read buffer
88 int nTotObjs; // the number of atoms
89 char read_buffer[BUFFERSIZE]; //the line buffer for reading
90
91 char *eof_test; // ptr to see when we reach the end of the file
92 char *parseErr;
93
94 vector<StuntDouble*> integrableObjects;
95
96 simnfo = the_simnfo;
97
98
99 #ifndef IS_MPI
100 eof_test = fgets(read_buffer, sizeof(read_buffer), c_in_file);
101 if( eof_test == NULL ){
102 sprintf( painCave.errMsg,
103 "InitializeFromFile error: error reading 1st line of \"%s\"\n",
104 c_in_name );
105 painCave.isFatal = 1;
106 simError();
107 }
108
109 nTotObjs = atoi( read_buffer );
110
111 if( nTotObjs != simnfo->getTotIntegrableObjects() ){
112 sprintf( painCave.errMsg,
113 "Initialize from File error. %s n_atoms, %d, "
114 "does not match the BASS file's n_atoms, %d.\n",
115 c_in_name, nTotObjs, simnfo->getTotIntegrableObjects());
116 painCave.isFatal = 1;
117 simError();
118 }
119
120 //read the box mat from the comment line
121
122 eof_test = fgets(read_buffer, sizeof(read_buffer), c_in_file);
123 if(eof_test == NULL){
124 sprintf( painCave.errMsg,
125 "error in reading commment in %s\n", c_in_name);
126 painCave.isFatal = 1;
127 simError();
128 }
129
130 parseErr = parseCommentLine( read_buffer, simnfo);
131 if( parseErr != NULL ){
132 strcpy( painCave.errMsg, parseErr );
133 painCave.isFatal = 1;
134 simError();
135 }
136
137 //parse dump lines
138
139 for( i=0; i < simnfo->n_mol; i++){
140
141 integrableObjects = (simnfo->molecules[i]).getIntegrableObjects();
142
143 for(j = 0; j < integrableObjects.size(); j++){
144
145 eof_test = fgets(read_buffer, sizeof(read_buffer), c_in_file);
146 if(eof_test == NULL){
147 sprintf(painCave.errMsg,
148 "error in reading file %s\n"
149 "natoms = %d; index = %d\n"
150 "error reading the line from the file.\n",
151 c_in_name, nTotObjs, i );
152 painCave.isFatal = 1;
153 simError();
154 }
155
156 parseErr = parseDumpLine( read_buffer, integrableObjects[j]);
157 if( parseErr != NULL ){
158 strcpy( painCave.errMsg, parseErr );
159 painCave.isFatal = 1;
160 simError();
161 }
162 }
163 }
164
165 // MPI Section of code..........
166 #else //IS_MPI
167
168 // first thing first, suspend fatalities.
169 painCave.isEventLoop = 1;
170
171 int myStatus; // 1 = wakeup & success; 0 = error; -1 = AllDone
172 int haveError;
173
174 MPI_Status istatus;
175 int *MolToProcMap = mpiSim->getMolToProcMap();
176 int localIndex;
177 int nCurObj;
178 int nItems;
179
180 nTotObjs = simnfo->getTotIntegrableObjects();
181 haveError = 0;
182 if (worldRank == 0) {
183
184 eof_test = fgets(read_buffer, sizeof(read_buffer), c_in_file);
185 if( eof_test == NULL ){
186 sprintf( painCave.errMsg,
187 "Error reading 1st line of %s \n ",c_in_name);
188 haveError = 1;
189 simError();
190 }
191
192 nItems = atoi( read_buffer );
193
194 // Check to see that the number of integrable objects in the intial configuration file is the
195 // same as declared in simBass.
196
197 if( nTotObjs != nItems){
198 sprintf( painCave.errMsg,
199 "Initialize from File error. %s n_atoms, %d, "
200 "does not match the BASS file's n_atoms, %d.\n",
201 c_in_name, nTotObjs, simnfo->getTotIntegrableObjects());
202 haveError= 1;
203 simError();
204 }
205
206 //read the boxMat from the comment line
207
208 eof_test = fgets(read_buffer, sizeof(read_buffer), c_in_file);
209 if(eof_test == NULL){
210 sprintf( painCave.errMsg,
211 "error in reading commment in %s\n", c_in_name);
212 haveError = 1;
213 simError();
214 }
215
216 //Every single processor will parse the comment line by itself
217 //By using this way, we might lose some efficiency, but if we want to add
218 //more parameters into comment line, we only need to modify function
219 //parseCommentLine
220
221 MPI_Bcast(read_buffer, BUFFERSIZE, MPI_CHAR, 0, MPI_COMM_WORLD);
222
223 cerr << "node " << worldRank << " finished MPI_Bcast" << endl;
224
225 parseErr = parseCommentLine( read_buffer, simnfo);
226
227 if( parseErr != NULL ){
228 strcpy( painCave.errMsg, parseErr );
229 haveError = 1;
230 simError();
231 }
232
233 for (i=0 ; i < mpiSim->getTotNmol(); i++) {
234 which_node = MolToProcMap[i];
235 if(which_node == 0){
236 //molecules belong to master node
237
238 localIndex = mpiSim->getGlobalToLocalMol(i);
239
240 if(localIndex == -1) {
241 strcpy(painCave.errMsg, "Molecule not found on node 0!");
242 haveError = 1;
243 simError();
244 }
245
246 integrableObjects = (simnfo->molecules[localIndex]).getIntegrableObjects();
247 for(j=0; j < integrableObjects.size(); j++){
248
249 eof_test = fgets(read_buffer, sizeof(read_buffer), c_in_file);
250 if(eof_test == NULL){
251 sprintf(painCave.errMsg,
252 "error in reading file %s\n"
253 "natoms = %d; index = %d\n"
254 "error reading the line from the file.\n",
255 c_in_name, nTotObjs, i );
256 haveError= 1;
257 simError();
258 }
259
260 if(haveError) nodeZeroError();
261
262 parseDumpLine(read_buffer, integrableObjects[j]);
263
264 }
265
266
267 }
268 else{
269 //molecule belongs to slave nodes
270
271 MPI_Recv(&nCurObj, 1, MPI_INT, which_node,
272 TAKE_THIS_TAG_INT, MPI_COMM_WORLD, &istatus);
273 cerr << "node " << worldRank << " finished MPI_Send" << endl;
274 for(j=0; j < nCurObj; j++){
275
276 eof_test = fgets(read_buffer, sizeof(read_buffer), c_in_file);
277 if(eof_test == NULL){
278 sprintf(painCave.errMsg,
279 "error in reading file %s\n"
280 "natoms = %d; index = %d\n"
281 "error reading the line from the file.\n",
282 c_in_name, nTotObjs, i );
283 haveError= 1;
284 simError();
285 }
286
287 if(haveError) nodeZeroError();
288
289 MPI_Send(read_buffer, BUFFERSIZE, MPI_CHAR, which_node,
290 TAKE_THIS_TAG_CHAR, MPI_COMM_WORLD);
291 cerr << "node " << worldRank << " finished MPI_Send" << endl;
292 }
293
294 }
295
296 }
297
298 }
299 else{
300 //actions taken at slave nodes
301
302 MPI_Bcast(read_buffer, BUFFERSIZE, MPI_CHAR, 0, MPI_COMM_WORLD);
303
304 cerr << "node " << worldRank << " finished MPI_Bcast" << endl;
305 parseErr = parseCommentLine( read_buffer, simnfo);
306
307 if( parseErr != NULL ){
308 strcpy( painCave.errMsg, parseErr );
309 haveError = 1;
310 simError();
311 }
312
313 for (i=0 ; i < mpiSim->getTotNmol(); i++) {
314 which_node = MolToProcMap[i];
315
316 if(which_node == worldRank){
317 //molecule with global index i belongs to this processor
318
319 localIndex = mpiSim->getGlobalToLocalMol(i);
320
321 if(localIndex == -1) {
322 sprintf(painCave.errMsg, "Molecule not found on node %d\n", worldRank);
323 haveError = 1;
324 simError();
325 }
326
327 integrableObjects = (simnfo->molecules[localIndex]).getIntegrableObjects();
328
329 nCurObj = integrableObjects.size();
330
331 MPI_Send(&nCurObj, 1, MPI_INT, 0,
332 TAKE_THIS_TAG_INT, MPI_COMM_WORLD);
333
334 cerr << "node " << worldRank << " finished MPI_Send" << endl;
335 for(j = 0; j < integrableObjects.size(); j++){
336
337 MPI_Recv(read_buffer, BUFFERSIZE, MPI_CHAR, 0,
338 TAKE_THIS_TAG_CHAR, MPI_COMM_WORLD, &istatus);
339
340 cerr << "node " << worldRank << " finished MPI_Recv" << endl;
341 parseErr = parseDumpLine(read_buffer, integrableObjects[j]);
342
343 if( parseErr != NULL ){
344 strcpy( painCave.errMsg, parseErr );
345 simError();
346 }
347
348 }
349
350 }
351
352 }
353
354 }
355 #endif
356 }
357
358 char* InitializeFromFile::parseDumpLine(char* readLine, StuntDouble* sd){
359
360 char *foo; // the pointer to the current string token
361
362 double pos[3]; // position place holders
363 double vel[3]; // velocity placeholders
364 double q[4]; // the quaternions
365 double ji[3]; // angular velocity placeholders;
366 double qSqr, qLength; // needed to normalize the quaternion vector.
367
368
369 // set the string tokenizer
370
371 foo = strtok(readLine, " ,;\t");
372
373 // check the atom name to the current atom
374
375 if( strcmp( foo, sd->getType() ) ){
376 sprintf( painCave.errMsg,
377 "Initialize from file error. Does not"
378 " match the BASS atom %s.\n",
379 sd->getType() );
380 return strdup( painCave.errMsg );
381 }
382
383 // get the positions
384
385 foo = strtok(NULL, " ,;\t");
386 if(foo == NULL){
387 sprintf( painCave.errMsg,
388 "error in reading postition x from %s\n",
389 c_in_name);
390 return strdup( painCave.errMsg );
391 }
392 pos[0] = atof( foo );
393
394 foo = strtok(NULL, " ,;\t");
395 if(foo == NULL){
396 sprintf( painCave.errMsg,
397 "error in reading postition y from %s\n",
398 c_in_name);
399 return strdup( painCave.errMsg );
400 }
401 pos[1] = atof( foo );
402
403 foo = strtok(NULL, " ,;\t");
404 if(foo == NULL){
405 sprintf( painCave.errMsg,
406 "error in reading postition z from %s\n",
407 c_in_name);
408 return strdup( painCave.errMsg );
409 }
410 pos[2] = atof( foo );
411
412
413 // get the velocities
414
415 foo = strtok(NULL, " ,;\t");
416 if(foo == NULL){
417 sprintf( painCave.errMsg,
418 "error in reading velocity x from %s\n",
419 c_in_name );
420 return strdup( painCave.errMsg );
421 }
422 vel[0] = atof( foo );
423
424 foo = strtok(NULL, " ,;\t");
425 if(foo == NULL){
426 sprintf( painCave.errMsg,
427 "error in reading velocity x from %s\n",
428 c_in_name );
429 return strdup( painCave.errMsg );
430 }
431 vel[1] = atof( foo );
432
433 foo = strtok(NULL, " ,;\t");
434 if(foo == NULL){
435 sprintf( painCave.errMsg,
436 "error in reading velocity x from %s\n",
437 c_in_name );
438 return strdup( painCave.errMsg );
439 }
440 vel[2] = atof( foo );
441
442
443 // add the positions and velocities to the atom
444
445 sd->setPos( pos );
446 sd->setVel( vel );
447
448 if (!sd->isDirectional())
449 return NULL;
450
451 // get the quaternions
452
453 if( sd->isDirectional() ){
454
455 foo = strtok(NULL, " ,;\t");
456 if(foo == NULL){
457 sprintf( painCave.errMsg,
458 "error in reading velocity x from %s\n",
459 c_in_name );
460 return strdup( painCave.errMsg );
461 }
462 q[0] = atof( foo );
463
464 foo = strtok(NULL, " ,;\t");
465 if(foo == NULL){
466 sprintf( painCave.errMsg,
467 "error in reading velocity x from %s\n",
468 c_in_name );
469 return strdup( painCave.errMsg );
470 }
471 q[1] = atof( foo );
472
473 foo = strtok(NULL, " ,;\t");
474 if(foo == NULL){
475 sprintf( painCave.errMsg,
476 "error in reading velocity x from %s\n",
477 c_in_name );
478 return strdup( painCave.errMsg );
479 }
480 q[2] = atof( foo );
481
482 foo = strtok(NULL, " ,;\t");
483 if(foo == NULL){
484 sprintf( painCave.errMsg,
485 "error in reading velocity x from %s\n",
486 c_in_name );
487 return strdup( painCave.errMsg );
488 }
489 q[3] = atof( foo );
490
491 // get the angular velocities
492
493 foo = strtok(NULL, " ,;\t");
494 if(foo == NULL){
495 sprintf( painCave.errMsg,
496 "error in reading velocity x from %s\n",
497 c_in_name );
498 return strdup( painCave.errMsg );
499 }
500 ji[0] = atof( foo );
501
502 foo = strtok(NULL, " ,;\t");
503 if(foo == NULL){
504 sprintf( painCave.errMsg,
505 "error in reading velocity x from %s\n",
506 c_in_name );
507 return strdup( painCave.errMsg );
508 }
509 ji[1] = atof(foo );
510
511 foo = strtok(NULL, " ,;\t");
512 if(foo == NULL){
513 sprintf( painCave.errMsg,
514 "error in reading velocity x from %s\n",
515 c_in_name );
516 return strdup( painCave.errMsg );
517 }
518 ji[2] = atof( foo );
519
520
521 // check that the quaternion vector is normalized
522
523 qSqr = (q[0] * q[0]) + (q[1] * q[1]) + (q[2] * q[2]) + (q[3] * q[3]);
524
525 qLength = sqrt( qSqr );
526 q[0] = q[0] / qLength;
527 q[1] = q[1] / qLength;
528 q[2] = q[2] / qLength;
529 q[3] = q[3] / qLength;
530
531 // add quaternion and angular velocities
532
533 sd->setQ( q );
534 sd->setJ( ji );
535 }
536
537
538
539 return NULL;
540 }
541
542
543 char* InitializeFromFile::parseCommentLine(char* readLine, SimInfo* entry_plug){
544
545 double currTime;
546 double boxMat[9];
547 double theBoxMat3[3][3];
548 double chi;
549 double integralOfChidt;
550 double eta[9];
551
552 char *foo; // the pointer to the current string token
553
554 // set the string tokenizer
555
556 foo = strtok(readLine, " ,;\t");
557 // set the timeToken.
558
559 if(foo == NULL){
560 sprintf( painCave.errMsg,
561 "error in reading Time from %s\n",
562 c_in_name );
563 return strdup( painCave.errMsg );
564 }
565
566 currTime = atof( foo );
567 entry_plug->setTime( currTime );
568
569 //get H-Matrix
570
571 for(int i = 0 ; i < 9; i++){
572 foo = strtok(NULL, " ,;\t");
573 if(foo == NULL){
574 sprintf( painCave.errMsg,
575 "error in reading H[%d] from %s\n", i, c_in_name );
576 return strdup( painCave.errMsg );
577 }
578 boxMat[i] = atof( foo );
579 }
580
581 for(int i=0;i<3;i++)
582 for(int j=0;j<3;j++) theBoxMat3[i][j] = boxMat[3*j+i];
583
584 //set H-Matrix
585 entry_plug->setBoxM( theBoxMat3 );
586
587 //get chi and integralOfChidt, they should appear by pair
588
589 if( entry_plug->useInitXSstate ){
590 foo = strtok(NULL, " ,;\t\n");
591 if(foo != NULL){
592 chi = atof(foo);
593
594 foo = strtok(NULL, " ,;\t\n");
595 if(foo == NULL){
596 sprintf( painCave.errMsg,
597 "chi and integralOfChidt should appear by pair in %s\n", c_in_name );
598 return strdup( painCave.errMsg );
599 }
600 integralOfChidt = atof( foo );
601
602 //push chi and integralOfChidt into SimInfo::properties which can be
603 //retrieved by integrator later
604 DoubleData* chiValue = new DoubleData();
605 chiValue->setID(CHIVALUE_ID);
606 chiValue->setData(chi);
607 entry_plug->addProperty(chiValue);
608
609 DoubleData* integralOfChidtValue = new DoubleData();
610 integralOfChidtValue->setID(INTEGRALOFCHIDT_ID);
611 integralOfChidtValue->setData(integralOfChidt);
612 entry_plug->addProperty(integralOfChidtValue);
613
614 }
615 else
616 return NULL;
617
618 //get eta
619 foo = strtok(NULL, " ,;\t\n");
620 if(foo != NULL ){
621
622 for(int i = 0 ; i < 9; i++){
623
624 if(foo == NULL){
625 sprintf( painCave.errMsg,
626 "error in reading eta[%d] from %s\n", i, c_in_name );
627 return strdup( painCave.errMsg );
628 }
629 eta[i] = atof( foo );
630 foo = strtok(NULL, " ,;\t\n");
631 }
632 }
633 else
634 return NULL;
635
636 //push eta into SimInfo::properties which can be
637 //retrieved by integrator later
638
639 DoubleArrayData* etaValue = new DoubleArrayData();
640 etaValue->setID(ETAVALUE_ID);
641 etaValue->setData(eta, 9);
642 entry_plug->addProperty(etaValue);
643 }
644
645 return NULL;
646 }
647
648 #ifdef IS_MPI
649
650 // a couple of functions to let us escape the read loop
651
652 void initFile::nodeZeroError( void ){
653 int j, myStatus;
654
655 myStatus = 0;
656 for (j = 0; j < mpiSim->getNumberProcessors(); j++) {
657 MPI_Send( &myStatus, 1, MPI_INT, j,
658 TAKE_THIS_TAG_INT, MPI_COMM_WORLD);
659 }
660
661
662 MPI_Finalize();
663 exit (0);
664
665 }
666
667 void initFile::anonymousNodeDie( void ){
668
669 MPI_Finalize();
670 exit (0);
671 }
672
673 #endif //is_mpi