ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/InitializeFromFile.cpp
Revision: 440
Committed: Tue Apr 1 16:49:17 2003 UTC (21 years, 3 months ago) by mmeineke
File size: 13318 byte(s)
Log Message:
Fixed DumpWriter to be more robust to errors. also added a little namespace to InitFromFile to wrap it's helper functions in MPI

File Contents

# User Rev Content
1 mmeineke 377 #include <iostream>
2     #include <cmath>
3    
4     #include <stdio.h>
5     #include <stdlib.h>
6     #include <string.h>
7     #include <unistd.h>
8     #include <sys/types.h>
9     #include <sys/stat.h>
10    
11     #include "ReadWrite.hpp"
12     #include "simError.h"
13    
14     #ifdef IS_MPI
15 gezelter 417 #include <mpi.h>
16     #include <mpi++.h>
17 mmeineke 377 #include "mpiSimulation.hpp"
18 chuckv 436 #define TAKE_THIS_TAG_CHAR 0
19     #define TAKE_THIS_TAG_INT 1
20    
21 mmeineke 440 namespace initFile{
22     void nodeZeroError( void );
23     void anonymousNodeDie( void );
24     }
25 chuckv 436
26 mmeineke 440 using namespace initFile;
27    
28 mmeineke 377 #endif // is_mpi
29    
30     InitializeFromFile :: InitializeFromFile( char *in_name ){
31     #ifdef IS_MPI
32     if (worldRank == 0) {
33     #endif
34    
35     c_in_file = fopen(in_name, "r");
36     if(c_in_file == NULL){
37     sprintf(painCave.errMsg,
38     "Cannot open file: %s\n", in_name);
39     painCave.isFatal = 1;
40     simError();
41     }
42    
43     strcpy( c_in_name, in_name);
44     #ifdef IS_MPI
45     }
46     strcpy( checkPointMsg, "Infile opened for reading successfully." );
47     MPIcheckPoint();
48     #endif
49     return;
50     }
51    
52     InitializeFromFile :: ~InitializeFromFile( ){
53     #ifdef IS_MPI
54     if (worldRank == 0) {
55     #endif
56     int error;
57     error = fclose( c_in_file );
58     if( error ){
59     sprintf( painCave.errMsg,
60     "Error closing %s\n", c_in_name );
61     simError();
62     }
63     #ifdef IS_MPI
64     }
65     strcpy( checkPointMsg, "Infile closed successfully." );
66     MPIcheckPoint();
67     #endif
68    
69     return;
70     }
71    
72    
73     void InitializeFromFile :: read_xyz( SimInfo* the_entry_plug ){
74    
75 gezelter 417 int i, j, done, which_node, which_atom; // loop counter
76 mmeineke 377
77     const int BUFFERSIZE = 2000; // size of the read buffer
78     int n_atoms; // the number of atoms
79     char read_buffer[BUFFERSIZE]; //the line buffer for reading
80     #ifdef IS_MPI
81     char send_buffer[BUFFERSIZE];
82     #endif
83    
84     char *eof_test; // ptr to see when we reach the end of the file
85     char *parseErr;
86     int procIndex;
87    
88     entry_plug = the_entry_plug;
89    
90    
91     #ifndef IS_MPI
92     eof_test = fgets(read_buffer, sizeof(read_buffer), c_in_file);
93     if( eof_test == NULL ){
94     sprintf( painCave.errMsg,
95     "InitializeFromFile error: error reading 1st line of \"%s\"\n",
96     c_in_name );
97     painCave.isFatal = 1;
98     simError();
99     }
100    
101     n_atoms = atoi( read_buffer );
102    
103     Atom **atoms = entry_plug->atoms;
104     DirectionalAtom* dAtom;
105    
106     if( n_atoms != entry_plug->n_atoms ){
107     sprintf( painCave.errMsg,
108     "Initialize from File error. %s n_atoms, %d, "
109     "does not match the BASS file's n_atoms, %d.\n",
110     c_in_name, n_atoms, entry_plug->n_atoms );
111     painCave.isFatal = 1;
112     simError();
113     }
114    
115     //read and toss the comment line
116    
117     eof_test = fgets(read_buffer, sizeof(read_buffer), c_in_file);
118     if(eof_test == NULL){
119     sprintf( painCave.errMsg,
120     "error in reading commment in %s\n", c_in_name);
121     painCave.isFatal = 1;
122     simError();
123     }
124    
125     for( i=0; i < n_atoms; i++){
126    
127     eof_test = fgets(read_buffer, sizeof(read_buffer), c_in_file);
128     if(eof_test == NULL){
129     sprintf(painCave.errMsg,
130     "error in reading file %s\n"
131     "natoms = %d; index = %d\n"
132     "error reading the line from the file.\n",
133     c_in_name, n_atoms, i );
134     painCave.isFatal = 1;
135     simError();
136     }
137    
138    
139     parseErr = parseDumpLine( read_buffer, i );
140     if( parseErr != NULL ){
141     strcpy( painCave.errMsg, parseErr );
142     painCave.isFatal = 1;
143     simError();
144     }
145     }
146    
147    
148     // MPI Section of code..........
149     #else //IS_MPI
150    
151 chuckv 436 // first thing first, suspend fatalities.
152     painCave.isEventLoop = 1;
153    
154     int myStatus; // 1 = wakeup & success; 0 = error; -1 = AllDone
155     int haveError;
156    
157 gezelter 417 MPI::Status istatus;
158     int *AtomToProcMap = mpiSim->getAtomToProcMap();
159 mmeineke 377
160 chuckv 436
161     haveError = 0;
162 mmeineke 377 if (worldRank == 0) {
163 chuckv 436
164 mmeineke 377 eof_test = fgets(read_buffer, sizeof(read_buffer), c_in_file);
165     if( eof_test == NULL ){
166     sprintf( painCave.errMsg,
167     "Error reading 1st line of %d \n ",c_in_name);
168 chuckv 436 haveError = 1;
169 mmeineke 377 simError();
170     }
171    
172     n_atoms = atoi( read_buffer );
173    
174     Atom **atoms = entry_plug->atoms;
175     DirectionalAtom* dAtom;
176    
177     // Check to see that the number of atoms in the intial configuration file is the
178     // same as declared in simBass.
179    
180     if( n_atoms != mpiSim->getTotAtoms() ){
181     sprintf( painCave.errMsg,
182     "Initialize from File error. %s n_atoms, %d, "
183     "does not match the BASS file's n_atoms, %d.\n",
184     c_in_name, n_atoms, entry_plug->n_atoms );
185 chuckv 436 haveError= 1;
186 mmeineke 377 simError();
187     }
188    
189     //read and toss the comment line
190    
191     eof_test = fgets(read_buffer, sizeof(read_buffer), c_in_file);
192     if(eof_test == NULL){
193     sprintf( painCave.errMsg,
194     "error in reading commment in %s\n", c_in_name);
195 chuckv 436 haveError= 1;
196 mmeineke 377 simError();
197     }
198    
199 chuckv 436 if(haveError) nodeZeroError();
200 gezelter 417
201     for (i=0 ; i < mpiSim->getTotAtoms(); i++) {
202    
203 mmeineke 377 eof_test = fgets(read_buffer, sizeof(read_buffer), c_in_file);
204     if(eof_test == NULL){
205     sprintf(painCave.errMsg,
206     "error in reading file %s\n"
207     "natoms = %d; index = %d\n"
208     "error reading the line from the file.\n",
209     c_in_name, n_atoms, i );
210 chuckv 436 haveError= 1;
211 mmeineke 377 simError();
212     }
213    
214 chuckv 436 if(haveError) nodeZeroError();
215    
216 gezelter 417 // Get the Node number which wants this atom:
217     which_node = AtomToProcMap[i];
218 chuckv 436 if (which_node == 0) {
219 gezelter 417 parseErr = parseDumpLine( read_buffer, i );
220     if( parseErr != NULL ){
221     strcpy( painCave.errMsg, parseErr );
222 chuckv 436 haveError = 1;
223 gezelter 417 simError();
224     }
225 chuckv 436 if(haveError) nodeZeroError();
226     }
227    
228     else {
229    
230     myStatus = 1;
231     MPI::COMM_WORLD.Send(&myStatus, 1, MPI_INT, which_node,
232     TAKE_THIS_TAG_INT);
233 gezelter 417 MPI::COMM_WORLD.Send(read_buffer, BUFFERSIZE, MPI_CHAR, which_node,
234 chuckv 436 TAKE_THIS_TAG_CHAR);
235     MPI::COMM_WORLD.Send(&i, 1, MPI_INT, which_node, TAKE_THIS_TAG_INT);
236     MPI::COMM_WORLD.Recv(&myStatus, 1, MPI_INT, which_node, TAKE_THIS_TAG_INT, istatus);
237    
238     if(!myStatus) nodeZeroError();
239 mmeineke 377 }
240     }
241 chuckv 436 myStatus = -1;
242 gezelter 417 for (j = 0; j < mpiSim->getNumberProcessors(); j++) {
243 chuckv 436 MPI::COMM_WORLD.Send( &myStatus, 1, MPI_INT, j,
244     TAKE_THIS_TAG_INT);
245 gezelter 417 }
246 gezelter 419
247 gezelter 417 } else {
248 gezelter 419
249 gezelter 417 done = 0;
250     while (!done) {
251 chuckv 436
252     MPI::COMM_WORLD.Recv(&myStatus, 1, MPI_INT, 0,
253     TAKE_THIS_TAG_INT, istatus);
254    
255     if(!myStatus) anonymousNodeDie();
256    
257     if(myStatus < 0) break;
258    
259 gezelter 417 MPI::COMM_WORLD.Recv(read_buffer, BUFFERSIZE, MPI_CHAR, 0,
260 chuckv 436 TAKE_THIS_TAG_CHAR, istatus);
261     MPI::COMM_WORLD.Recv(&which_atom, 1, MPI_INT, 0,
262     TAKE_THIS_TAG_INT, istatus);
263    
264     myStatus = 1;
265     parseErr = parseDumpLine( read_buffer, which_atom );
266     if( parseErr != NULL ){
267     strcpy( painCave.errMsg, parseErr );
268     myStatus = 0;;
269     simError();
270 mmeineke 377 }
271 chuckv 436
272     MPI::COMM_WORLD.Send( &myStatus, 1, MPI_INT, 0,
273     TAKE_THIS_TAG_INT);
274    
275 mmeineke 377 }
276     }
277 chuckv 436
278     // last thing last, enable fatalities.
279     painCave.isEventLoop = 0;
280    
281 mmeineke 377 #endif
282     }
283    
284 gezelter 419 char* InitializeFromFile::parseDumpLine(char* readLine, int globalIndex){
285 mmeineke 377
286     char *foo; // the pointer to the current string token
287    
288     double rx, ry, rz; // position place holders
289     double vx, vy, vz; // velocity placeholders
290     double q[4]; // the quaternions
291     double jx, jy, jz; // angular velocity placeholders;
292     double qSqr, qLength; // needed to normalize the quaternion vector.
293    
294     Atom **atoms = entry_plug->atoms;
295     DirectionalAtom* dAtom;
296    
297 gezelter 419 int j, n_atoms, atomIndex;
298 mmeineke 377
299     #ifdef IS_MPI
300     n_atoms = mpiSim->getTotAtoms();
301 gezelter 419 atomIndex=-1;
302     for (j=0; j < mpiSim->getMyNlocal(); j++) {
303     if (atoms[j]->getGlobalIndex() == globalIndex) atomIndex = j;
304     }
305     if (atomIndex == -1) {
306     sprintf( painCave.errMsg,
307     "Initialize from file error. Atom at index %d "
308     "in file %s does not exist on processor %d .\n",
309     globalIndex, c_in_name, mpiSim->getMyNode() );
310     return strdup( painCave.errMsg );
311     }
312 mmeineke 377 #else
313     n_atoms = entry_plug->n_atoms;
314 gezelter 419 atomIndex = globalIndex;
315 mmeineke 377 #endif // is_mpi
316    
317     // set the string tokenizer
318    
319     foo = strtok(readLine, " ,;\t");
320    
321     // check the atom name to the current atom
322    
323     if( strcmp( foo, atoms[atomIndex]->getType() ) ){
324     sprintf( painCave.errMsg,
325     "Initialize from file error. Atom %s at index %d "
326     "in file %s does not"
327     " match the BASS atom %s.\n",
328     foo, atomIndex, c_in_name, atoms[atomIndex]->getType() );
329     return strdup( painCave.errMsg );
330     }
331    
332     // get the positions
333    
334     foo = strtok(NULL, " ,;\t");
335     if(foo == NULL){
336     sprintf( painCave.errMsg,
337     "error in reading postition x from %s\n"
338     "natoms = %d, index = %d\n",
339     c_in_name, n_atoms, atomIndex );
340     return strdup( painCave.errMsg );
341     }
342     rx = atof( foo );
343    
344     foo = strtok(NULL, " ,;\t");
345     if(foo == NULL){
346     sprintf( painCave.errMsg,
347     "error in reading postition y from %s\n"
348     "natoms = %d, index = %d\n",
349     c_in_name, n_atoms, atomIndex );
350     return strdup( painCave.errMsg );
351     }
352     ry = atof( foo );
353    
354     foo = strtok(NULL, " ,;\t");
355     if(foo == NULL){
356     sprintf( painCave.errMsg,
357     "error in reading postition z from %s\n"
358     "natoms = %d, index = %d\n",
359     c_in_name, n_atoms, atomIndex );
360     return strdup( painCave.errMsg );
361     }
362     rz = atof( foo );
363    
364    
365     // get the velocities
366    
367     foo = strtok(NULL, " ,;\t");
368     if(foo == NULL){
369     sprintf( painCave.errMsg,
370     "error in reading velocity x from %s\n"
371     "natoms = %d, index = %d\n",
372     c_in_name, n_atoms, atomIndex );
373     return strdup( painCave.errMsg );
374     }
375     vx = atof( foo );
376    
377     foo = strtok(NULL, " ,;\t");
378     if(foo == NULL){
379     sprintf( painCave.errMsg,
380     "error in reading velocity y from %s\n"
381     "natoms = %d, index = %d\n",
382     c_in_name, n_atoms, atomIndex );
383     return strdup( painCave.errMsg );
384     }
385     vy = atof( foo );
386    
387     foo = strtok(NULL, " ,;\t");
388     if(foo == NULL){
389     sprintf( painCave.errMsg,
390     "error in reading velocity z from %s\n"
391     "natoms = %d, index = %d\n",
392     c_in_name, n_atoms, atomIndex );
393     return strdup( painCave.errMsg );
394     }
395     vz = atof( foo );
396    
397    
398     // get the quaternions
399    
400     if( atoms[atomIndex]->isDirectional() ){
401    
402     foo = strtok(NULL, " ,;\t");
403     if(foo == NULL){
404     sprintf(painCave.errMsg,
405     "error in reading quaternion 0 from %s\n"
406     "natoms = %d, index = %d\n",
407     c_in_name, n_atoms, atomIndex );
408     return strdup( painCave.errMsg );
409     }
410     q[0] = atof( foo );
411    
412     foo = strtok(NULL, " ,;\t");
413     if(foo == NULL){
414     sprintf( painCave.errMsg,
415     "error in reading quaternion 1 from %s\n"
416     "natoms = %d, index = %d\n",
417     c_in_name, n_atoms, atomIndex );
418     return strdup( painCave.errMsg );
419     }
420     q[1] = atof( foo );
421    
422     foo = strtok(NULL, " ,;\t");
423     if(foo == NULL){
424     sprintf( painCave.errMsg,
425     "error in reading quaternion 2 from %s\n"
426     "natoms = %d, index = %d\n",
427     c_in_name, n_atoms, atomIndex );
428     return strdup( painCave.errMsg );
429     }
430     q[2] = atof( foo );
431    
432     foo = strtok(NULL, " ,;\t");
433     if(foo == NULL){
434     sprintf( painCave.errMsg,
435     "error in reading quaternion 3 from %s\n"
436     "natoms = %d, index = %d\n",
437     c_in_name, n_atoms, atomIndex );
438     return strdup( painCave.errMsg );
439     }
440     q[3] = atof( foo );
441    
442     // get the angular velocities
443    
444     foo = strtok(NULL, " ,;\t");
445     if(foo == NULL){
446     sprintf( painCave.errMsg,
447     "error in reading angular momentum jx from %s\n"
448     "natoms = %d, index = %d\n",
449     c_in_name, n_atoms, atomIndex );
450     return strdup( painCave.errMsg );
451     }
452     jx = atof( foo );
453    
454     foo = strtok(NULL, " ,;\t");
455     if(foo == NULL){
456     sprintf( painCave.errMsg,
457     "error in reading angular momentum jy from %s\n"
458     "natoms = %d, index = %d\n",
459     c_in_name, n_atoms, atomIndex );
460     return strdup( painCave.errMsg );
461     }
462     jy = atof(foo );
463    
464     foo = strtok(NULL, " ,;\t");
465     if(foo == NULL){
466     sprintf( painCave.errMsg,
467     "error in reading angular momentum jz from %s\n"
468     "natoms = %d, index = %d\n",
469     c_in_name, n_atoms, atomIndex );
470     return strdup( painCave.errMsg );
471     }
472     jz = atof( foo );
473    
474     dAtom = ( DirectionalAtom* )atoms[atomIndex];
475    
476     // check that the quaternion vector is normalized
477    
478     qSqr = (q[0] * q[0]) + (q[1] * q[1]) + (q[2] * q[2]) + (q[3] * q[3]);
479    
480     qLength = sqrt( qSqr );
481     q[0] = q[0] / qLength;
482     q[1] = q[1] / qLength;
483     q[2] = q[2] / qLength;
484     q[3] = q[3] / qLength;
485    
486     dAtom->setQ( q );
487    
488     // add the angular velocities
489    
490     dAtom->setJx( jx );
491     dAtom->setJy( jy );
492     dAtom->setJz( jz );
493     }
494    
495     // add the positions and velocities to the atom
496    
497     atoms[atomIndex]->setX( rx );
498     atoms[atomIndex]->setY( ry );
499     atoms[atomIndex]->setZ( rz );
500    
501     atoms[atomIndex]->set_vx( vx );
502     atoms[atomIndex]->set_vy( vy );
503     atoms[atomIndex]->set_vz( vz );
504    
505     return NULL;
506     }
507 chuckv 436
508    
509     #ifdef IS_MPI
510    
511     // a couple of functions to let us escape the read loop
512    
513 mmeineke 440 void initFile::nodeZeroError( void ){
514 chuckv 436 int j, myStatus;
515    
516     myStatus = 0;
517     for (j = 0; j < mpiSim->getNumberProcessors(); j++) {
518     MPI::COMM_WORLD.Send( &myStatus, 1, MPI_INT, j,
519     TAKE_THIS_TAG_INT);
520     }
521    
522    
523     MPI_Finalize();
524     exit (0);
525    
526     }
527    
528 mmeineke 440 void initFile::anonymousNodeDie( void ){
529 chuckv 436
530     MPI_Finalize();
531     exit (0);
532     }
533    
534     #endif //is_mpi