ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/WATER.cpp
Revision: 999
Committed: Fri Jan 30 15:01:09 2004 UTC (20 years, 5 months ago) by chrisfen
File size: 27219 byte(s)
Log Message:
Substantial changes. OOPSE now has a working WATER.cpp forcefield and parser.
This involved changes to WATER.cpp and ForceFields amoung other files. One important
note: a hardwiring of LJ_rcut was made in calc_LJ_FF.F90. This will be removed on
the next commit...

File Contents

# User Rev Content
1 chrisfen 976 #include <stdlib.h>
2     #include <stdio.h>
3     #include <string.h>
4    
5     #include <iostream>
6     using namespace std;
7    
8     #ifdef IS_MPI
9     #include <mpi.h>
10     #endif //is_mpi
11    
12     #include "ForceFields.hpp"
13     #include "SRI.hpp"
14     #include "simError.h"
15    
16     #include "fortranWrappers.hpp"
17    
18     #ifdef IS_MPI
19     #include "mpiForceField.h"
20     #endif // is_mpi
21    
22    
23    
24     namespace WATER_NS{
25    
26 gezelter 989 // Declare the structures that will be passed by the parser and MPI
27 chrisfen 976
28     typedef struct{
29     char name[15];
30     double mass;
31     double epslon;
32     double sigma;
33     double charge;
34     int isDirectional;
35     int isLJ;
36     int isCharge;
37     int ident;
38     int last; // 0 -> default
39     // 1 -> in MPI: tells nodes to stop listening
40     } atomStruct;
41    
42     typedef struct{
43     char name[15];
44 gezelter 989 double Ixx;
45     double Iyy;
46     double Izz;
47 chrisfen 976 double dipole;
48     double w0;
49     double v0;
50     double v0p;
51     double rl;
52     double ru;
53     double rlp;
54     double rup;
55     int isDipole;
56     int isSticky;
57     int last; // 0 -> default
58     // 1 -> in MPI: tells nodes to stop listening
59     } directionalStruct;
60    
61     int parseAtom( char *lineBuffer, int lineNum, atomStruct &info );
62     int parseDirectional( char *lineBuffer, int lineNum, directionalStruct &info );
63    
64    
65     #ifdef IS_MPI
66    
67     MPI_Datatype mpiAtomStructType;
68     MPI_Datatype mpiDirectionalStructType;
69    
70     #endif
71    
72     class LinkedAtomType {
73     public:
74     LinkedAtomType(){
75     next = NULL;
76     name[0] = '\0';
77     }
78     ~LinkedAtomType(){ if( next != NULL ) delete next; }
79    
80     LinkedAtomType* find(char* key){
81     if( !strcmp(name, key) ) return this;
82     if( next != NULL ) return next->find(key);
83     return NULL;
84     }
85    
86    
87     void add( atomStruct &info ){
88    
89     // check for duplicates
90    
91     if( !strcmp( info.name, name ) ){
92     sprintf( painCave.errMsg,
93     "Duplicate WATER atom type \"%s\" found in "
94     "the WATER param file./n",
95     name );
96     painCave.isFatal = 1;
97     simError();
98     }
99    
100     if( next != NULL ) next->add(info);
101     else{
102     next = new LinkedAtomType();
103     strcpy(next->name, info.name);
104     next->isDirectional = info.isDirectional;
105     next->isLJ = info.isLJ;
106     next->isCharge = info.isCharge;
107     next->mass = info.mass;
108     next->epslon = info.epslon;
109     next->sigma = info.sigma;
110     next->charge = info.charge;
111     next->ident = info.ident;
112     }
113     }
114    
115     #ifdef IS_MPI
116    
117     void duplicate( atomStruct &info ){
118     strcpy(info.name, name);
119     info.isDirectional = isDirectional;
120     info.isLJ = isLJ;
121     info.isCharge = isCharge;
122     info.mass = mass;
123     info.epslon = epslon;
124     info.sigma = sigma;
125     info.charge = charge;
126     info.ident = ident;
127     info.last = 0;
128     }
129    
130     #endif
131    
132     char name[15];
133     int isDirectional;
134     int isLJ;
135     int isCharge;
136     double mass;
137     double epslon;
138     double sigma;
139     double charge;
140     int ident;
141     LinkedAtomType* next;
142     };
143    
144     class LinkedDirectionalType {
145     public:
146     LinkedDirectionalType(){
147     next = NULL;
148     name[0] = '\0';
149     }
150     ~LinkedDirectionalType(){ if( next != NULL ) delete next; }
151    
152     LinkedDirectionalType* find(char* key){
153     if( !strcmp(name, key) ) return this;
154     if( next != NULL ) return next->find(key);
155     return NULL;
156     }
157    
158    
159     void add( directionalStruct &info ){
160    
161     // check for duplicates
162    
163     if( !strcmp( info.name, name ) ){
164     sprintf( painCave.errMsg,
165     "Duplicate WATER directional type \"%s\" found in "
166     "the WATER param file./n",
167     name );
168     painCave.isFatal = 1;
169     simError();
170     }
171    
172     if( next != NULL ) next->add(info);
173     else{
174     next = new LinkedDirectionalType();
175     strcpy(next->name, info.name);
176     next->isDipole = info.isDipole;
177     next->isSticky = info.isSticky;
178 gezelter 989 next->Ixx = info.Ixx;
179     next->Iyy = info.Iyy;
180     next->Izz = info.Izz;
181     next->dipole = info.dipole;
182 chrisfen 976 next->w0 = info.w0;
183     next->v0 = info.v0;
184     next->v0p = info.v0p;
185     next->rl = info.rl;
186     next->ru = info.ru;
187     next->rlp = info.rlp;
188     next->rup = info.rup;
189     }
190     }
191    
192     #ifdef IS_MPI
193    
194     void duplicate( directionalStruct &info ){
195     strcpy(info.name, name);
196     info.isDipole = isDipole;
197     info.isSticky = isSticky;
198 gezelter 989 info.Ixx = Ixx;
199     info.Iyy = Iyy;
200     info.Izz = Izz;
201 chrisfen 976 info.dipole = dipole;
202     info.w0 = w0;
203     info.v0 = v0;
204     info.v0p = v0p;
205     info.rl = rl;
206     info.ru = ru;
207     info.rlp = rlp;
208     info.rup = rup;
209     info.last = 0;
210     }
211    
212     #endif
213    
214     char name[15];
215     int isDipole;
216     int isSticky;
217 gezelter 989 double Ixx;
218     double Iyy;
219     double Izz;
220 chrisfen 976 double dipole;
221     double w0;
222     double v0;
223     double v0p;
224     double rl;
225     double ru;
226     double rlp;
227     double rup;
228     LinkedDirectionalType* next;
229     };
230    
231     LinkedAtomType* headAtomType;
232     LinkedAtomType* currentAtomType;
233     LinkedDirectionalType* headDirectionalType;
234     LinkedDirectionalType* currentDirectionalType;
235 gezelter 989 } // namespace
236 chrisfen 976
237     using namespace WATER_NS;
238    
239     //****************************************************************
240     // begins the actual forcefield stuff.
241     //****************************************************************
242    
243    
244     WATER::WATER(){
245    
246     char fileName[200];
247     char* ffPath_env = "FORCE_PARAM_PATH";
248     char* ffPath;
249     char temp[200];
250    
251     headAtomType = NULL;
252     currentAtomType = NULL;
253     headDirectionalType = NULL;
254     currentDirectionalType = NULL;
255    
256     // do the funtion wrapping
257     wrapMeFF( this );
258    
259     #ifdef IS_MPI
260     int i;
261    
262     // **********************************************************************
263     // Init the atomStruct mpi type
264    
265     atomStruct atomProto; // mpiPrototype
266     int atomBC[3] = {15,4,5}; // block counts
267     MPI_Aint atomDspls[3]; // displacements
268     MPI_Datatype atomMbrTypes[3]; // member mpi types
269    
270     MPI_Address(&atomProto.name, &atomDspls[0]);
271     MPI_Address(&atomProto.mass, &atomDspls[1]);
272 gezelter 989 MPI_Address(&atomProto.isDirectional, &atomDspls[2]);
273 chrisfen 976
274     atomMbrTypes[0] = MPI_CHAR;
275     atomMbrTypes[1] = MPI_DOUBLE;
276     atomMbrTypes[2] = MPI_INT;
277    
278     for (i=2; i >= 0; i--) atomDspls[i] -= atomDspls[0];
279    
280     MPI_Type_struct(3, atomBC, atomDspls, atomMbrTypes, &mpiAtomStructType);
281     MPI_Type_commit(&mpiAtomStructType);
282    
283     // ***********************************************************************
284    
285     // **********************************************************************
286     // Init the directionalStruct mpi type
287    
288     directionalStruct directionalProto; // mpiPrototype
289 gezelter 989 int directionalBC[3] = {15,11,3}; // block counts
290 chrisfen 976 MPI_Aint directionalDspls[3]; // displacements
291     MPI_Datatype directionalMbrTypes[3]; // member mpi types
292    
293     MPI_Address(&directionalProto.name, &directionalDspls[0]);
294 gezelter 989 MPI_Address(&directionalProto.Ixx, &directionalDspls[1]);
295     MPI_Address(&directionalProto.isDipole, &directionalDspls[2]);
296 chrisfen 976
297     directionalMbrTypes[0] = MPI_CHAR;
298     directionalMbrTypes[1] = MPI_DOUBLE;
299     directionalMbrTypes[2] = MPI_INT;
300    
301     for (i=2; i >= 0; i--) directionalDspls[i] -= directionalDspls[0];
302    
303     MPI_Type_struct(3, directionalBC, directionalDspls, directionalMbrTypes,
304     &mpiDirectionalStructType);
305     MPI_Type_commit(&mpiDirectionalStructType);
306    
307     // ***********************************************************************
308 chrisfen 999
309 chrisfen 976 if( worldRank == 0 ){
310     #endif
311    
312     // generate the force file name
313    
314     strcpy( fileName, "WATER.frc" );
315     // fprintf( stderr,"Trying to open %s\n", fileName );
316    
317     // attempt to open the file in the current directory first.
318    
319     frcFile = fopen( fileName, "r" );
320    
321     if( frcFile == NULL ){
322    
323     // next see if the force path enviorment variable is set
324    
325     ffPath = getenv( ffPath_env );
326     if( ffPath == NULL ) {
327     STR_DEFINE(ffPath, FRC_PATH );
328     }
329    
330    
331     strcpy( temp, ffPath );
332     strcat( temp, "/" );
333     strcat( temp, fileName );
334     strcpy( fileName, temp );
335    
336     frcFile = fopen( fileName, "r" );
337    
338     if( frcFile == NULL ){
339    
340     sprintf( painCave.errMsg,
341     "Error opening the force field parameter file: %s\n"
342     "Have you tried setting the FORCE_PARAM_PATH environment "
343     "variable?\n",
344     fileName );
345     painCave.isFatal = 1;
346     simError();
347     }
348     }
349    
350     #ifdef IS_MPI
351     }
352    
353     sprintf( checkPointMsg, "WATER file opened sucessfully." );
354     MPIcheckPoint();
355    
356     #endif // is_mpi
357     }
358    
359    
360     WATER::~WATER(){
361    
362     if( headAtomType != NULL ) delete headAtomType;
363     if( headDirectionalType != NULL ) delete headDirectionalType;
364    
365     #ifdef IS_MPI
366     if( worldRank == 0 ){
367     #endif // is_mpi
368    
369     fclose( frcFile );
370    
371     #ifdef IS_MPI
372     }
373     #endif // is_mpi
374     }
375    
376     void WATER::cleanMe( void ){
377    
378     #ifdef IS_MPI
379    
380     // keep the linked list in the mpi version
381    
382     #else // is_mpi
383    
384     // delete the linked list in the single processor version
385    
386     if( headAtomType != NULL ) delete headAtomType;
387     if( headDirectionalType != NULL ) delete headDirectionalType;
388    
389     #endif // is_mpi
390     }
391    
392    
393     void WATER::initForceField( int ljMixRule ){
394    
395     initFortran( ljMixRule, entry_plug->useReactionField );
396     }
397    
398    
399     void WATER::readParams( void ){
400    
401     int identNum;
402 chrisfen 999 int tempDirect0, tempDirect1;
403 chrisfen 976
404     atomStruct atomInfo;
405     directionalStruct directionalInfo;
406 gezelter 989 fpos_t *atomPos;
407 chrisfen 976
408     atomInfo.last = 1; // initialize last to have the last set.
409     directionalInfo.last = 1; // if things go well, last will be set to 0
410    
411     atomPos = new fpos_t;
412     bigSigma = 0.0;
413 chrisfen 999
414 chrisfen 976 #ifdef IS_MPI
415     if( worldRank == 0 ){
416     #endif
417    
418     // read in the atom types.
419    
420     headAtomType = new LinkedAtomType;
421 gezelter 989 headDirectionalType = new LinkedDirectionalType;
422 chrisfen 976
423     fastForward( "AtomTypes", "initializeAtoms" );
424 chrisfen 999
425 chrisfen 976 // we are now at the AtomTypes section.
426    
427     eof_test = fgets( readLine, sizeof(readLine), frcFile );
428     lineNum++;
429    
430    
431     // read a line, and start parsing out the atom types
432 chrisfen 999
433 chrisfen 976 if( eof_test == NULL ){
434     sprintf( painCave.errMsg,
435     "Error in reading Atoms from force file at line %d.\n",
436     lineNum );
437     painCave.isFatal = 1;
438     simError();
439     }
440    
441     identNum = 1;
442     // stop reading at end of file, or at next section
443     while( readLine[0] != '#' && eof_test != NULL ){
444    
445     // toss comment lines
446     if( readLine[0] != '!' ){
447    
448     // the parser returns 0 if the line was blank
449     if( parseAtom( readLine, lineNum, atomInfo ) ){
450     atomInfo.ident = identNum;
451     headAtomType->add( atomInfo );
452     if ( atomInfo.isDirectional ) {
453    
454     // if the atom is directional, skip to the directional section
455     // and parse directional info.
456     fgetpos( frcFile, atomPos );
457     sectionSearch( "DirectionalTypes", atomInfo.name,
458     "initializeDirectional" );
459     parseDirectional( readLine, lineNum, directionalInfo );
460 gezelter 989 headDirectionalType->add( directionalInfo );
461 chrisfen 976
462     // return to the AtomTypes section
463     fsetpos( frcFile, atomPos );
464     }
465     identNum++;
466     }
467     }
468     eof_test = fgets( readLine, sizeof(readLine), frcFile );
469     lineNum++;
470     }
471    
472     #ifdef IS_MPI
473 chrisfen 999
474 chrisfen 976 // send out the linked list to all the other processes
475    
476     sprintf( checkPointMsg,
477 chrisfen 999 "WATER atom and directional structures read successfully." );
478 chrisfen 976 MPIcheckPoint();
479 chrisfen 999 currentAtomType = headAtomType->next; //skip the first element place holder
480     currentDirectionalType = headDirectionalType->next; // same w/ directional
481    
482 chrisfen 976 while( currentAtomType != NULL ){
483     currentAtomType->duplicate( atomInfo );
484 chrisfen 999
485 chrisfen 976 sendFrcStruct( &atomInfo, mpiAtomStructType );
486    
487     sprintf( checkPointMsg,
488     "successfully sent WATER force type: \"%s\"\n",
489     atomInfo.name );
490 chrisfen 999
491     if ( atomInfo.isDirectional ){
492     // send out the directional linked list to all the other processes
493    
494     currentDirectionalType->duplicate( directionalInfo );
495     sendFrcStruct( &directionalInfo, mpiDirectionalStructType );
496    
497     sprintf( checkPointMsg,
498     "successfully sent WATER directional type: \"%s\"\n",
499     directionalInfo.name );
500     }
501    
502 chrisfen 976 MPIcheckPoint();
503 chrisfen 999 tempDirect0 = atomInfo.isDirectional;
504 chrisfen 976 currentAtomType = currentAtomType->next;
505 chrisfen 999 if( tempDirect0 )
506     currentDirectionalType = currentDirectionalType->next;
507 chrisfen 976 }
508 chrisfen 999
509 chrisfen 976 atomInfo.last = 1;
510     sendFrcStruct( &atomInfo, mpiAtomStructType );
511 chrisfen 999 directionalInfo.last = 1;
512     if ( atomInfo.isDirectional )
513 chrisfen 976 sendFrcStruct( &directionalInfo, mpiDirectionalStructType );
514     }
515 chrisfen 999
516 chrisfen 976 else{
517     // listen for node 0 to send out the force params
518    
519     MPIcheckPoint();
520 gezelter 989
521 chrisfen 976 headAtomType = new LinkedAtomType;
522 chrisfen 999 headDirectionalType = new LinkedDirectionalType;
523 chrisfen 976 receiveFrcStruct( &atomInfo, mpiAtomStructType );
524 chrisfen 999
525     if ( atomInfo.isDirectional )
526     receiveFrcStruct( &directionalInfo, mpiDirectionalStructType );
527    
528 chrisfen 976 while( !atomInfo.last ){
529 chrisfen 999
530 chrisfen 976 headAtomType->add( atomInfo );
531    
532     MPIcheckPoint();
533 chrisfen 999
534 chrisfen 976 receiveFrcStruct( &atomInfo, mpiAtomStructType );
535    
536 chrisfen 999 if( atomInfo.isDirectional ){
537 chrisfen 976 headDirectionalType->add( directionalInfo );
538 chrisfen 999
539 chrisfen 976 receiveFrcStruct( &directionalInfo, mpiDirectionalStructType );
540     }
541     }
542     }
543    
544     #endif // is_mpi
545    
546     // call new A_types in fortran
547    
548     int isError;
549    
550     // dummy variables
551     int isGB = 0;
552     int isEAM = 0;
553 gezelter 989 int notDipole = 0;
554     int notSSD = 0;
555     double noDipMoment = 0.0;
556    
557    
558     currentAtomType = headAtomType->next;
559     currentDirectionalType = headDirectionalType->next;
560    
561 chrisfen 976 while( currentAtomType != NULL ){
562    
563     if( currentAtomType->isLJ ) entry_plug->useLJ = 1;
564 gezelter 989 if( currentAtomType->isCharge ) entry_plug->useCharges = 1;
565 chrisfen 976 if( currentAtomType->isDirectional ){
566 gezelter 989 // only directional atoms can have dipoles or be sticky
567     if ( currentDirectionalType->isDipole ) entry_plug->useDipoles = 1;
568     if ( currentDirectionalType->isSticky ) {
569 chrisfen 976 entry_plug->useSticky = 1;
570 gezelter 989 set_sticky_params( &(currentDirectionalType->w0),
571     &(currentDirectionalType->v0),
572     &(currentDirectionalType->v0p),
573     &(currentDirectionalType->rl),
574     &(currentDirectionalType->ru),
575     &(currentDirectionalType->rlp),
576     &(currentDirectionalType->rup));
577 chrisfen 976 }
578 gezelter 989 if( currentAtomType->name[0] != '\0' ){
579     isError = 0;
580     makeAtype( &(currentAtomType->ident),
581     &(currentAtomType->isLJ),
582     &(currentDirectionalType->isSticky),
583     &(currentDirectionalType->isDipole),
584     &isGB,
585     &isEAM,
586     &(currentAtomType->isCharge),
587     &(currentAtomType->epslon),
588     &(currentAtomType->sigma),
589     &(currentAtomType->charge),
590     &(currentDirectionalType->dipole),
591     &isError );
592     if( isError ){
593     sprintf( painCave.errMsg,
594     "Error initializing the \"%s\" atom type in fortran\n",
595     currentAtomType->name );
596     painCave.isFatal = 1;
597     simError();
598     }
599     }
600     currentDirectionalType->next;
601 chrisfen 976 }
602 gezelter 989
603     else {
604     // use all dummy variables if this is not a directional atom
605     if( currentAtomType->name[0] != '\0' ){
606     isError = 0;
607     makeAtype( &(currentAtomType->ident),
608     &(currentAtomType->isLJ),
609     &notSSD,
610     &notDipole,
611     &isGB,
612     &isEAM,
613     &(currentAtomType->isCharge),
614     &(currentAtomType->epslon),
615     &(currentAtomType->sigma),
616     &(currentAtomType->charge),
617     &noDipMoment,
618     &isError );
619     if( isError ){
620     sprintf( painCave.errMsg,
621     "Error initializing the \"%s\" atom type in fortran\n",
622     currentAtomType->name );
623     painCave.isFatal = 1;
624     simError();
625     }
626 chrisfen 976 }
627     }
628     currentAtomType = currentAtomType->next;
629     }
630    
631     #ifdef IS_MPI
632     sprintf( checkPointMsg,
633 chrisfen 999 "WATER atom and directional structures successfully"
634     "sent to fortran\n" );
635 chrisfen 976 MPIcheckPoint();
636     #endif // is_mpi
637    
638     }
639    
640    
641     void WATER::initializeAtoms( int nAtoms, Atom** the_atoms ){
642    
643 chrisfen 999 int i,j,k;
644 chrisfen 976
645     // initialize the atoms
646 gezelter 989 DirectionalAtom* dAtom;
647     double inertialMat[3][3];
648 chrisfen 976
649     for( i=0; i<nAtoms; i++ ){
650     currentAtomType = headAtomType->find( the_atoms[i]->getType() );
651     if( currentAtomType == NULL ){
652     sprintf( painCave.errMsg,
653     "AtomType error, %s not found in force file.\n",
654     the_atoms[i]->getType() );
655     painCave.isFatal = 1;
656     simError();
657     }
658 gezelter 989 if( currentAtomType->isLJ ) the_atoms[i]->setLJ();
659     if( currentAtomType->isCharge ) the_atoms[i]->setCharged();
660 chrisfen 976 the_atoms[i]->setMass( currentAtomType->mass );
661     the_atoms[i]->setIdent( currentAtomType->ident );
662 chrisfen 999
663 gezelter 989 if( bigSigma < currentAtomType->sigma ) bigSigma = currentAtomType->sigma;
664 chrisfen 976
665 gezelter 989 if( currentAtomType->isDirectional ){
666     currentDirectionalType =
667     headDirectionalType->find( the_atoms[i]->getType() );
668     if( currentDirectionalType == NULL ){
669     sprintf( painCave.errMsg,
670     "DirectionalType error, %s not found in force file.\n",
671     the_atoms[i]->getType() );
672     painCave.isFatal = 1;
673     simError();
674     }
675 chrisfen 976
676 gezelter 989 // zero out the moments of inertia matrix
677 chrisfen 999 for( j=0; j<3; j++ )
678     for( k=0; k<3; k++ )
679     inertialMat[j][k] = 0.0;
680 chrisfen 976
681 gezelter 989 // load the force file moments of inertia
682     inertialMat[0][0] = currentDirectionalType->Ixx;
683     inertialMat[1][1] = currentDirectionalType->Iyy;
684     inertialMat[2][2] = currentDirectionalType->Izz;
685 chrisfen 999
686 gezelter 989 dAtom = (DirectionalAtom *) the_atoms[i];
687     dAtom->setHasDipole( currentDirectionalType->isDipole );
688     dAtom->setMu( currentDirectionalType->dipole );
689     dAtom->setMu( currentDirectionalType->dipole );
690 chrisfen 999
691 gezelter 989 // if it's sticky then it's an SSD type
692     dAtom->setSSD( currentDirectionalType->isSticky );
693     dAtom->setJx( 0.0 );
694     dAtom->setJy( 0.0 );
695     dAtom->setJz( 0.0 );
696     dAtom->setI( inertialMat );
697 chrisfen 999
698 gezelter 989 entry_plug->n_dipoles++;
699     }
700     else{
701     sprintf( painCave.errMsg,
702     "WATER error: Atom \"%s\" is directional, yet no standard"
703     " orientation was specifed in the BASS file.\n",
704     currentAtomType->name );
705 chrisfen 976 painCave.isFatal = 1;
706     simError();
707     }
708     }
709     }
710    
711     void WATER::initializeBonds( int nBonds, Bond** BondArray,
712     bond_pair* the_bonds ){
713    
714     if( nBonds ){
715     sprintf( painCave.errMsg,
716     "WATER does not support bonds.\n" );
717     painCave.isFatal = 1;
718     simError();
719     }
720     }
721    
722     void WATER::initializeBends( int nBends, Bend** bendArray,
723     bend_set* the_bends ){
724    
725     if( nBends ){
726     sprintf( painCave.errMsg,
727     "WATER does not support bends.\n" );
728     painCave.isFatal = 1;
729     simError();
730     }
731     }
732    
733     void WATER::initializeTorsions( int nTorsions, Torsion** torsionArray,
734     torsion_set* the_torsions ){
735    
736     if( nTorsions ){
737     sprintf( painCave.errMsg,
738     "WATER does not support torsions.\n" );
739     painCave.isFatal = 1;
740     simError();
741     }
742     }
743    
744     void WATER::fastForward( char* stopText, char* searchOwner ){
745    
746     int foundText = 0;
747     char* the_token;
748    
749     rewind( frcFile );
750     lineNum = 0;
751    
752     eof_test = fgets( readLine, sizeof(readLine), frcFile );
753     lineNum++;
754     if( eof_test == NULL ){
755     sprintf( painCave.errMsg, "Error fast forwarding force file for %s: "
756     " file is empty.\n",
757     searchOwner );
758     painCave.isFatal = 1;
759     simError();
760     }
761    
762    
763     while( !foundText ){
764     while( eof_test != NULL && readLine[0] != '#' ){
765     eof_test = fgets( readLine, sizeof(readLine), frcFile );
766     lineNum++;
767     }
768     if( eof_test == NULL ){
769     sprintf( painCave.errMsg,
770     "Error fast forwarding force file for %s at "
771     "line %d: file ended unexpectedly.\n",
772     searchOwner,
773     lineNum );
774     painCave.isFatal = 1;
775     simError();
776     }
777    
778     the_token = strtok( readLine, " ,;\t#\n" );
779     foundText = !strcmp( stopText, the_token );
780    
781     if( !foundText ){
782     eof_test = fgets( readLine, sizeof(readLine), frcFile );
783     lineNum++;
784    
785     if( eof_test == NULL ){
786     sprintf( painCave.errMsg,
787     "Error fast forwarding force file for %s at "
788     "line %d: file ended unexpectedly.\n",
789     searchOwner,
790     lineNum );
791     painCave.isFatal = 1;
792     simError();
793     }
794     }
795     }
796     }
797    
798     void WATER::sectionSearch( char* secHead, char* stopText, char* searchOwner ){
799    
800     int foundSection = 0;
801     int foundText = 0;
802     char* the_token;
803 gezelter 989 fpos_t *tempPos;
804 chrisfen 976
805     rewind( frcFile );
806     lineNum = 0;
807 gezelter 989 tempPos = new fpos_t;
808 chrisfen 976
809     eof_test = fgets( readLine, sizeof(readLine), frcFile );
810     lineNum++;
811     if( eof_test == NULL ){
812     sprintf( painCave.errMsg, "Error fast forwarding force file for %s: "
813     " file is empty.\n",
814     searchOwner );
815     painCave.isFatal = 1;
816     simError();
817     }
818    
819     while( !foundSection ){
820     while( eof_test != NULL && readLine[0] != '#' ){
821     eof_test = fgets( readLine, sizeof(readLine), frcFile );
822     lineNum++;
823     }
824     if( eof_test == NULL ){
825     sprintf( painCave.errMsg,
826     "Error fast forwarding force file for %s at "
827     "line %d: file ended unexpectedly.\n",
828     searchOwner,
829     lineNum );
830     painCave.isFatal = 1;
831     simError();
832     }
833     the_token = strtok( readLine, " ,;\t#\n" );
834     foundSection = !strcmp( secHead, the_token );
835    
836     if( !foundSection ){
837     eof_test = fgets( readLine, sizeof(readLine), frcFile );
838     lineNum++;
839    
840     if( eof_test == NULL ){
841     sprintf( painCave.errMsg,
842     "Error section searching force file for %s at "
843     "line %d: file ended unexpectedly.\n",
844     searchOwner,
845     lineNum );
846     painCave.isFatal = 1;
847     simError();
848     }
849     }
850 gezelter 989 }
851 chrisfen 976
852     while( !foundText ){
853 gezelter 989
854     fgetpos( frcFile, tempPos );
855     eof_test = fgets( readLine, sizeof(readLine), frcFile );
856     lineNum++;
857    
858     if( eof_test == NULL ){
859     sprintf( painCave.errMsg,
860     "Error fast forwarding force file for %s at "
861     "line %d: file ended unexpectedly.\n",
862     searchOwner,
863     lineNum );
864     painCave.isFatal = 1;
865 chrisfen 976 simError();
866 gezelter 989 }
867 chrisfen 976
868     the_token = strtok( readLine, " ,;\t#\n" );
869 gezelter 989 if( the_token != NULL ){
870     foundText = !strcmp( stopText, the_token );
871     }
872 chrisfen 976 }
873 gezelter 989 fsetpos( frcFile, tempPos );
874     eof_test = fgets( readLine, sizeof(readLine), frcFile );
875     lineNum++;
876 chrisfen 976 }
877    
878    
879     int WATER_NS::parseAtom( char *lineBuffer, int lineNum, atomStruct &info ){
880    
881     char* the_token;
882    
883     the_token = strtok( lineBuffer, " \n\t,;" );
884     if( the_token != NULL ){
885    
886     strcpy( info.name, the_token );
887    
888     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
889     sprintf( painCave.errMsg,
890     "Error parseing AtomTypes: line %d\n", lineNum );
891     painCave.isFatal = 1;
892     simError();
893     }
894    
895     info.isDirectional = atoi( the_token );
896    
897     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
898     sprintf( painCave.errMsg,
899     "Error parseing AtomTypes: line %d\n", lineNum );
900     painCave.isFatal = 1;
901     simError();
902     }
903    
904     info.isLJ = atoi( the_token );
905    
906     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
907     sprintf( painCave.errMsg,
908     "Error parseing AtomTypes: line %d\n", lineNum );
909     painCave.isFatal = 1;
910     simError();
911     }
912    
913     info.isCharge = atoi( the_token );
914    
915     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
916     sprintf( painCave.errMsg,
917     "Error parseing AtomTypes: line %d\n", lineNum );
918     painCave.isFatal = 1;
919     simError();
920     }
921    
922     info.mass = atof( the_token );
923    
924     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
925     sprintf( painCave.errMsg,
926     "Error parseing AtomTypes: line %d\n", lineNum );
927     painCave.isFatal = 1;
928     simError();
929     }
930    
931     info.epslon = atof( the_token );
932    
933     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
934     sprintf( painCave.errMsg,
935     "Error parseing AtomTypes: line %d\n", lineNum );
936     painCave.isFatal = 1;
937     simError();
938     }
939    
940     info.sigma = atof( the_token );
941    
942     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
943     sprintf( painCave.errMsg,
944     "Error parseing AtomTypes: line %d\n", lineNum );
945     painCave.isFatal = 1;
946     simError();
947     }
948    
949     info.charge = atof( the_token );
950    
951     return 1;
952     }
953     else return 0;
954     }
955    
956     int WATER_NS::parseDirectional( char *lineBuffer, int lineNum, directionalStruct &info ){
957    
958     char* the_token;
959    
960     the_token = strtok( lineBuffer, " \n\t,;" );
961     if( the_token != NULL ){
962    
963     strcpy( info.name, the_token );
964    
965     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
966     sprintf( painCave.errMsg,
967     "Error parseing DirectionalTypes: line %d\n", lineNum );
968     painCave.isFatal = 1;
969     simError();
970     }
971    
972     info.isDipole = atoi( the_token );
973    
974     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
975     sprintf( painCave.errMsg,
976     "Error parseing DirectionalTypes: line %d\n", lineNum );
977     painCave.isFatal = 1;
978     simError();
979     }
980    
981     info.isSticky = atoi( the_token );
982    
983     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
984     sprintf( painCave.errMsg,
985     "Error parseing DirectionalTypes: line %d\n", lineNum );
986     painCave.isFatal = 1;
987     simError();
988     }
989    
990 gezelter 989 info.Ixx = atof( the_token );
991 chrisfen 976
992     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
993     sprintf( painCave.errMsg,
994     "Error parseing DirectionalTypes: line %d\n", lineNum );
995     painCave.isFatal = 1;
996     simError();
997     }
998    
999 gezelter 989 info.Iyy = atof( the_token );
1000 chrisfen 976
1001     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1002     sprintf( painCave.errMsg,
1003     "Error parseing DirectionalTypes: line %d\n", lineNum );
1004     painCave.isFatal = 1;
1005     simError();
1006     }
1007    
1008 gezelter 989 info.Izz = atof( the_token );
1009 chrisfen 976
1010     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1011     sprintf( painCave.errMsg,
1012     "Error parseing DirectionalTypes: line %d\n", lineNum );
1013     painCave.isFatal = 1;
1014     simError();
1015     }
1016    
1017    
1018     info.dipole = atof( the_token );
1019    
1020     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1021     sprintf( painCave.errMsg,
1022     "Error parseing DirectionalTypes: line %d\n", lineNum );
1023     painCave.isFatal = 1;
1024     simError();
1025     }
1026    
1027     info.w0 = atof( the_token );
1028    
1029     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1030     sprintf( painCave.errMsg,
1031     "Error parseing DirectionalTypes: line %d\n", lineNum );
1032     painCave.isFatal = 1;
1033     simError();
1034     }
1035    
1036     info.v0 = atof( the_token );
1037    
1038     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1039     sprintf( painCave.errMsg,
1040     "Error parseing DirectionalTypes: line %d\n", lineNum );
1041     painCave.isFatal = 1;
1042     simError();
1043     }
1044    
1045     info.v0p = atof( the_token );
1046    
1047     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1048     sprintf( painCave.errMsg,
1049     "Error parseing DirectionalTypes: line %d\n", lineNum );
1050     painCave.isFatal = 1;
1051     simError();
1052     }
1053    
1054     info.rl = atof( the_token );
1055    
1056     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1057     sprintf( painCave.errMsg,
1058     "Error parseing DirectionalTypes: line %d\n", lineNum );
1059     painCave.isFatal = 1;
1060     simError();
1061     }
1062    
1063     info.ru = atof( the_token );
1064    
1065     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1066     sprintf( painCave.errMsg,
1067     "Error parseing DirectionalTypes: line %d\n", lineNum );
1068     painCave.isFatal = 1;
1069     simError();
1070     }
1071    
1072     info.rlp = atof( the_token );
1073    
1074     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1075     sprintf( painCave.errMsg,
1076     "Error parseing DirectionalTypes: line %d\n", lineNum );
1077     painCave.isFatal = 1;
1078     simError();
1079     }
1080    
1081     info.rup = atof( the_token );
1082    
1083     return 1;
1084     }
1085     else return 0;
1086     }