ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new_design/OOPSE-4/src/UseTheForce/WATER.cpp
Revision: 1654
Committed: Wed Oct 27 02:16:34 2004 UTC (19 years, 8 months ago) by gezelter
Original Path: trunk/OOPSE-4/src/UseTheForce/WATER.cpp
File size: 26981 byte(s)
Log Message:
more char* -> string conversion

File Contents

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