ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/WATER.cpp
Revision: 976
Committed: Thu Jan 22 17:34:20 2004 UTC (20 years, 5 months ago) by chrisfen
File size: 27504 byte(s)
Log Message:
Corrected spelling in several directories, and stated WATER.cpp

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