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

# Content
1 #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 #include <mpi.h>
16 #include <mpi++.h>
17 #include "mpiSimulation.hpp"
18 #define TAKE_THIS_TAG_CHAR 0
19 #define TAKE_THIS_TAG_INT 1
20
21 namespace initFile{
22 void nodeZeroError( void );
23 void anonymousNodeDie( void );
24 }
25
26 using namespace initFile;
27
28 #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 int i, j, done, which_node, which_atom; // loop counter
76
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 // 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 MPI::Status istatus;
158 int *AtomToProcMap = mpiSim->getAtomToProcMap();
159
160
161 haveError = 0;
162 if (worldRank == 0) {
163
164 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 haveError = 1;
169 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 haveError= 1;
186 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 haveError= 1;
196 simError();
197 }
198
199 if(haveError) nodeZeroError();
200
201 for (i=0 ; i < mpiSim->getTotAtoms(); i++) {
202
203 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 haveError= 1;
211 simError();
212 }
213
214 if(haveError) nodeZeroError();
215
216 // Get the Node number which wants this atom:
217 which_node = AtomToProcMap[i];
218 if (which_node == 0) {
219 parseErr = parseDumpLine( read_buffer, i );
220 if( parseErr != NULL ){
221 strcpy( painCave.errMsg, parseErr );
222 haveError = 1;
223 simError();
224 }
225 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 MPI::COMM_WORLD.Send(read_buffer, BUFFERSIZE, MPI_CHAR, which_node,
234 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 }
240 }
241 myStatus = -1;
242 for (j = 0; j < mpiSim->getNumberProcessors(); j++) {
243 MPI::COMM_WORLD.Send( &myStatus, 1, MPI_INT, j,
244 TAKE_THIS_TAG_INT);
245 }
246
247 } else {
248
249 done = 0;
250 while (!done) {
251
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 MPI::COMM_WORLD.Recv(read_buffer, BUFFERSIZE, MPI_CHAR, 0,
260 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 }
271
272 MPI::COMM_WORLD.Send( &myStatus, 1, MPI_INT, 0,
273 TAKE_THIS_TAG_INT);
274
275 }
276 }
277
278 // last thing last, enable fatalities.
279 painCave.isEventLoop = 0;
280
281 #endif
282 }
283
284 char* InitializeFromFile::parseDumpLine(char* readLine, int globalIndex){
285
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 int j, n_atoms, atomIndex;
298
299 #ifdef IS_MPI
300 n_atoms = mpiSim->getTotAtoms();
301 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 #else
313 n_atoms = entry_plug->n_atoms;
314 atomIndex = globalIndex;
315 #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
508
509 #ifdef IS_MPI
510
511 // a couple of functions to let us escape the read loop
512
513 void initFile::nodeZeroError( void ){
514 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 void initFile::anonymousNodeDie( void ){
529
530 MPI_Finalize();
531 exit (0);
532 }
533
534 #endif //is_mpi