ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-1.0/libmdtools/WATER.cpp
Revision: 1426
Committed: Wed Jul 28 16:26:33 2004 UTC (19 years, 11 months ago) by gezelter
File size: 27113 byte(s)
Log Message:
Added utility functions to grab the mass from the force field.

File Contents

# Content
1 #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 Ixx;
45 double Iyy;
46 double Izz;
47 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 next->Ixx = info.Ixx;
179 next->Iyy = info.Iyy;
180 next->Izz = info.Izz;
181 next->dipole = info.dipole;
182 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 info.Ixx = Ixx;
199 info.Iyy = Iyy;
200 info.Izz = Izz;
201 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 double Ixx;
218 double Iyy;
219 double Izz;
220 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 } // namespace
236
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 MPI_Address(&atomProto.isDirectional, &atomDspls[2]);
273
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 int directionalBC[3] = {15,11,3}; // block counts
290 MPI_Aint directionalDspls[3]; // displacements
291 MPI_Datatype directionalMbrTypes[3]; // member mpi types
292
293 MPI_Address(&directionalProto.name, &directionalDspls[0]);
294 MPI_Address(&directionalProto.Ixx, &directionalDspls[1]);
295 MPI_Address(&directionalProto.isDipole, &directionalDspls[2]);
296
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
309 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:\n"
342 "\t%s\n"
343 "\tHave you tried setting the FORCE_PARAM_PATH environment "
344 "variable?\n",
345 fileName );
346 painCave.severity = OOPSE_ERROR;
347 painCave.isFatal = 1;
348 simError();
349 }
350 }
351
352 #ifdef IS_MPI
353 }
354
355 sprintf( checkPointMsg, "WATER file opened sucessfully." );
356 MPIcheckPoint();
357
358 #endif // is_mpi
359 }
360
361
362 WATER::~WATER(){
363
364 if( headAtomType != NULL ) delete headAtomType;
365 if( headDirectionalType != NULL ) delete headDirectionalType;
366
367 #ifdef IS_MPI
368 if( worldRank == 0 ){
369 #endif // is_mpi
370
371 fclose( frcFile );
372
373 #ifdef IS_MPI
374 }
375 #endif // is_mpi
376 }
377
378 void WATER::cleanMe( void ){
379
380 #ifdef IS_MPI
381
382 // keep the linked list in the mpi version
383
384 #else // is_mpi
385
386 // delete the linked list in the single processor version
387
388 if( headAtomType != NULL ) delete headAtomType;
389 if( headDirectionalType != NULL ) delete headDirectionalType;
390
391 #endif // is_mpi
392 }
393
394
395 void WATER::initForceField( int ljMixRule ){
396
397 initFortran( ljMixRule, entry_plug->useReactionField );
398 }
399
400
401 void WATER::readParams( void ){
402
403 int identNum;
404 int tempDirect0, tempDirect1;
405
406 atomStruct atomInfo;
407 directionalStruct directionalInfo;
408 fpos_t *atomPos;
409
410 atomInfo.last = 1; // initialize last to have the last set.
411 directionalInfo.last = 1; // if things go well, last will be set to 0
412
413 atomPos = new fpos_t;
414 bigSigma = 0.0;
415
416 #ifdef IS_MPI
417 if( worldRank == 0 ){
418 #endif
419
420 // read in the atom types.
421
422 headAtomType = new LinkedAtomType;
423 headDirectionalType = new LinkedDirectionalType;
424
425 fastForward( "AtomTypes", "initializeAtoms" );
426
427 // we are now at the AtomTypes section.
428
429 eof_test = fgets( readLine, sizeof(readLine), frcFile );
430 lineNum++;
431
432
433 // read a line, and start parsing out the atom types
434
435 if( eof_test == NULL ){
436 sprintf( painCave.errMsg,
437 "Error in reading Atoms from force file at line %d.\n",
438 lineNum );
439 painCave.isFatal = 1;
440 simError();
441 }
442
443 identNum = 1;
444 // stop reading at end of file, or at next section
445 while( readLine[0] != '#' && eof_test != NULL ){
446
447 // toss comment lines
448 if( readLine[0] != '!' ){
449
450 // the parser returns 0 if the line was blank
451 if( parseAtom( readLine, lineNum, atomInfo ) ){
452 atomInfo.ident = identNum;
453 headAtomType->add( atomInfo );
454 if ( atomInfo.isDirectional ) {
455
456 // if the atom is directional, skip to the directional section
457 // and parse directional info.
458 fgetpos( frcFile, atomPos );
459 sectionSearch( "DirectionalTypes", atomInfo.name,
460 "initializeDirectional" );
461 parseDirectional( readLine, lineNum, directionalInfo );
462 headDirectionalType->add( directionalInfo );
463
464 // return to the AtomTypes section
465 fsetpos( frcFile, atomPos );
466 }
467 identNum++;
468 }
469 }
470 eof_test = fgets( readLine, sizeof(readLine), frcFile );
471 lineNum++;
472 }
473
474 #ifdef IS_MPI
475
476 // send out the linked list to all the other processes
477
478 sprintf( checkPointMsg,
479 "WATER atom and directional structures read successfully." );
480 MPIcheckPoint();
481 currentAtomType = headAtomType->next; //skip the first element place holder
482 currentDirectionalType = headDirectionalType->next; // same w/ directional
483
484 while( currentAtomType != NULL ){
485 currentAtomType->duplicate( atomInfo );
486
487 sendFrcStruct( &atomInfo, mpiAtomStructType );
488
489 sprintf( checkPointMsg,
490 "successfully sent WATER force type: \"%s\"\n",
491 atomInfo.name );
492
493 if ( atomInfo.isDirectional ){
494 // send out the directional linked list to all the other processes
495
496 currentDirectionalType->duplicate( directionalInfo );
497 sendFrcStruct( &directionalInfo, mpiDirectionalStructType );
498
499 sprintf( checkPointMsg,
500 "successfully sent WATER directional type: \"%s\"\n",
501 directionalInfo.name );
502 }
503
504 MPIcheckPoint();
505 tempDirect0 = atomInfo.isDirectional;
506 currentAtomType = currentAtomType->next;
507 if( tempDirect0 )
508 currentDirectionalType = currentDirectionalType->next;
509 }
510
511 atomInfo.last = 1;
512 sendFrcStruct( &atomInfo, mpiAtomStructType );
513 directionalInfo.last = 1;
514 if ( atomInfo.isDirectional )
515 sendFrcStruct( &directionalInfo, mpiDirectionalStructType );
516 }
517
518 else{
519 // listen for node 0 to send out the force params
520
521 MPIcheckPoint();
522
523 headAtomType = new LinkedAtomType;
524 headDirectionalType = new LinkedDirectionalType;
525 receiveFrcStruct( &atomInfo, mpiAtomStructType );
526
527 if ( atomInfo.isDirectional )
528 receiveFrcStruct( &directionalInfo, mpiDirectionalStructType );
529
530 while( !atomInfo.last ){
531
532 headAtomType->add( atomInfo );
533
534 MPIcheckPoint();
535
536 receiveFrcStruct( &atomInfo, mpiAtomStructType );
537
538 if( atomInfo.isDirectional ){
539 headDirectionalType->add( directionalInfo );
540
541 receiveFrcStruct( &directionalInfo, mpiDirectionalStructType );
542 }
543 }
544 }
545
546 #endif // is_mpi
547
548 // call new A_types in fortran
549
550 int isError;
551
552 // dummy variables
553 int isGB = 0;
554 int isEAM = 0;
555 int notDipole = 0;
556 int notSSD = 0;
557 double noDipMoment = 0.0;
558
559
560 currentAtomType = headAtomType->next;
561 currentDirectionalType = headDirectionalType->next;
562
563 while( currentAtomType != NULL ){
564
565 if( currentAtomType->isLJ ) entry_plug->useLJ = 1;
566 if( currentAtomType->isCharge ) entry_plug->useCharges = 1;
567 if( currentAtomType->isDirectional ){
568 // only directional atoms can have dipoles or be sticky
569 if ( currentDirectionalType->isDipole ) entry_plug->useDipoles = 1;
570 if ( currentDirectionalType->isSticky ) {
571 entry_plug->useSticky = 1;
572 set_sticky_params( &(currentDirectionalType->w0),
573 &(currentDirectionalType->v0),
574 &(currentDirectionalType->v0p),
575 &(currentDirectionalType->rl),
576 &(currentDirectionalType->ru),
577 &(currentDirectionalType->rlp),
578 &(currentDirectionalType->rup));
579 }
580 if( currentAtomType->name[0] != '\0' ){
581 isError = 0;
582 makeAtype( &(currentAtomType->ident),
583 &(currentAtomType->isLJ),
584 &(currentDirectionalType->isSticky),
585 &(currentDirectionalType->isDipole),
586 &isGB,
587 &isEAM,
588 &(currentAtomType->isCharge),
589 &(currentAtomType->epslon),
590 &(currentAtomType->sigma),
591 &(currentAtomType->charge),
592 &(currentDirectionalType->dipole),
593 &isError );
594 if( isError ){
595 sprintf( painCave.errMsg,
596 "Error initializing the \"%s\" atom type in fortran\n",
597 currentAtomType->name );
598 painCave.isFatal = 1;
599 simError();
600 }
601 }
602 currentDirectionalType->next;
603 }
604
605 else {
606 // use all dummy variables if this is not a directional atom
607 if( currentAtomType->name[0] != '\0' ){
608 isError = 0;
609 makeAtype( &(currentAtomType->ident),
610 &(currentAtomType->isLJ),
611 &notSSD,
612 &notDipole,
613 &isGB,
614 &isEAM,
615 &(currentAtomType->isCharge),
616 &(currentAtomType->epslon),
617 &(currentAtomType->sigma),
618 &(currentAtomType->charge),
619 &noDipMoment,
620 &isError );
621 if( isError ){
622 sprintf( painCave.errMsg,
623 "Error initializing the \"%s\" atom type in fortran\n",
624 currentAtomType->name );
625 painCave.isFatal = 1;
626 simError();
627 }
628 }
629 }
630 currentAtomType = currentAtomType->next;
631 }
632
633 #ifdef IS_MPI
634 sprintf( checkPointMsg,
635 "WATER atom and directional structures successfully"
636 "sent to fortran\n" );
637 MPIcheckPoint();
638 #endif // is_mpi
639
640 }
641
642
643 void WATER::initializeAtoms( int nAtoms, Atom** the_atoms ){
644
645 int i,j,k;
646
647 // initialize the atoms
648 DirectionalAtom* dAtom;
649 double ji[3];
650 double inertialMat[3][3];
651
652 for( i=0; i<nAtoms; i++ ){
653 currentAtomType = headAtomType->find( the_atoms[i]->getType() );
654 if( currentAtomType == NULL ){
655 sprintf( painCave.errMsg,
656 "AtomType error, %s not found in force file.\n",
657 the_atoms[i]->getType() );
658 painCave.isFatal = 1;
659 simError();
660 }
661 the_atoms[i]->setMass( currentAtomType->mass );
662 the_atoms[i]->setIdent( currentAtomType->ident );
663
664 if( bigSigma < currentAtomType->sigma ) bigSigma = currentAtomType->sigma;
665
666 the_atoms[i]->setHasCharge(currentAtomType->isCharge);
667
668 if( currentAtomType->isDirectional ){
669 currentDirectionalType =
670 headDirectionalType->find( the_atoms[i]->getType() );
671 if( currentDirectionalType == NULL ){
672 sprintf( painCave.errMsg,
673 "DirectionalType error, %s not found in force file.\n",
674 the_atoms[i]->getType() );
675 painCave.isFatal = 1;
676 simError();
677 }
678
679 // zero out the moments of inertia matrix
680 for( j=0; j<3; j++ )
681 for( k=0; k<3; k++ )
682 inertialMat[j][k] = 0.0;
683
684 // load the force file moments of inertia
685 inertialMat[0][0] = currentDirectionalType->Ixx;
686 inertialMat[1][1] = currentDirectionalType->Iyy;
687 inertialMat[2][2] = currentDirectionalType->Izz;
688
689 dAtom = (DirectionalAtom *) the_atoms[i];
690 dAtom->setHasDipole( currentDirectionalType->isDipole );
691
692 ji[0] = 0.0;
693 ji[1] = 0.0;
694 ji[2] = 0.0;
695 dAtom->setJ( ji );
696 dAtom->setI( inertialMat );
697
698 entry_plug->n_dipoles++;
699 }
700 }
701 }
702
703 void WATER::initializeBonds( int nBonds, Bond** BondArray,
704 bond_pair* the_bonds ){
705
706 if( nBonds ){
707 sprintf( painCave.errMsg,
708 "WATER does not support bonds.\n" );
709 painCave.isFatal = 1;
710 simError();
711 }
712 }
713
714 void WATER::initializeBends( int nBends, Bend** bendArray,
715 bend_set* the_bends ){
716
717 if( nBends ){
718 sprintf( painCave.errMsg,
719 "WATER does not support bends.\n" );
720 painCave.isFatal = 1;
721 simError();
722 }
723 }
724
725 void WATER::initializeTorsions( int nTorsions, Torsion** torsionArray,
726 torsion_set* the_torsions ){
727
728 if( nTorsions ){
729 sprintf( painCave.errMsg,
730 "WATER does not support torsions.\n" );
731 painCave.isFatal = 1;
732 simError();
733 }
734 }
735
736 void WATER::fastForward( char* stopText, char* searchOwner ){
737
738 int foundText = 0;
739 char* the_token;
740
741 rewind( frcFile );
742 lineNum = 0;
743
744 eof_test = fgets( readLine, sizeof(readLine), frcFile );
745 lineNum++;
746 if( eof_test == NULL ){
747 sprintf( painCave.errMsg, "Error fast forwarding force file for %s: "
748 " file is empty.\n",
749 searchOwner );
750 painCave.isFatal = 1;
751 simError();
752 }
753
754
755 while( !foundText ){
756 while( eof_test != NULL && readLine[0] != '#' ){
757 eof_test = fgets( readLine, sizeof(readLine), frcFile );
758 lineNum++;
759 }
760 if( eof_test == NULL ){
761 sprintf( painCave.errMsg,
762 "Error fast forwarding force file for %s at "
763 "line %d: file ended unexpectedly.\n",
764 searchOwner,
765 lineNum );
766 painCave.isFatal = 1;
767 simError();
768 }
769
770 the_token = strtok( readLine, " ,;\t#\n" );
771 foundText = !strcmp( stopText, the_token );
772
773 if( !foundText ){
774 eof_test = fgets( readLine, sizeof(readLine), frcFile );
775 lineNum++;
776
777 if( eof_test == NULL ){
778 sprintf( painCave.errMsg,
779 "Error fast forwarding force file for %s at "
780 "line %d: file ended unexpectedly.\n",
781 searchOwner,
782 lineNum );
783 painCave.isFatal = 1;
784 simError();
785 }
786 }
787 }
788 }
789
790 void WATER::sectionSearch( char* secHead, char* stopText, char* searchOwner ){
791
792 int foundSection = 0;
793 int foundText = 0;
794 char* the_token;
795 fpos_t *tempPos;
796
797 rewind( frcFile );
798 lineNum = 0;
799 tempPos = new fpos_t;
800
801 eof_test = fgets( readLine, sizeof(readLine), frcFile );
802 lineNum++;
803 if( eof_test == NULL ){
804 sprintf( painCave.errMsg, "Error fast forwarding force file for %s: "
805 " file is empty.\n",
806 searchOwner );
807 painCave.isFatal = 1;
808 simError();
809 }
810
811 while( !foundSection ){
812 while( eof_test != NULL && readLine[0] != '#' ){
813 eof_test = fgets( readLine, sizeof(readLine), frcFile );
814 lineNum++;
815 }
816 if( eof_test == NULL ){
817 sprintf( painCave.errMsg,
818 "Error fast forwarding force file for %s at "
819 "line %d: file ended unexpectedly.\n",
820 searchOwner,
821 lineNum );
822 painCave.isFatal = 1;
823 simError();
824 }
825 the_token = strtok( readLine, " ,;\t#\n" );
826 foundSection = !strcmp( secHead, the_token );
827
828 if( !foundSection ){
829 eof_test = fgets( readLine, sizeof(readLine), frcFile );
830 lineNum++;
831
832 if( eof_test == NULL ){
833 sprintf( painCave.errMsg,
834 "Error section searching force file for %s at "
835 "line %d: file ended unexpectedly.\n",
836 searchOwner,
837 lineNum );
838 painCave.isFatal = 1;
839 simError();
840 }
841 }
842 }
843
844 while( !foundText ){
845
846 fgetpos( frcFile, tempPos );
847 eof_test = fgets( readLine, sizeof(readLine), frcFile );
848 lineNum++;
849
850 if( eof_test == NULL ){
851 sprintf( painCave.errMsg,
852 "Error fast forwarding force file for %s at "
853 "line %d: file ended unexpectedly.\n",
854 searchOwner,
855 lineNum );
856 painCave.isFatal = 1;
857 simError();
858 }
859
860 the_token = strtok( readLine, " ,;\t#\n" );
861 if( the_token != NULL ){
862 foundText = !strcmp( stopText, the_token );
863 }
864 }
865 fsetpos( frcFile, tempPos );
866 eof_test = fgets( readLine, sizeof(readLine), frcFile );
867 lineNum++;
868 }
869
870
871 int WATER_NS::parseAtom( char *lineBuffer, int lineNum, atomStruct &info ){
872
873 char* the_token;
874
875 the_token = strtok( lineBuffer, " \n\t,;" );
876 if( the_token != NULL ){
877
878 strcpy( info.name, the_token );
879
880 if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
881 sprintf( painCave.errMsg,
882 "Error parseing AtomTypes: line %d\n", lineNum );
883 painCave.isFatal = 1;
884 simError();
885 }
886
887 info.isDirectional = atoi( the_token );
888
889 if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
890 sprintf( painCave.errMsg,
891 "Error parseing AtomTypes: line %d\n", lineNum );
892 painCave.isFatal = 1;
893 simError();
894 }
895
896 info.isLJ = atoi( the_token );
897
898 if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
899 sprintf( painCave.errMsg,
900 "Error parseing AtomTypes: line %d\n", lineNum );
901 painCave.isFatal = 1;
902 simError();
903 }
904
905 info.isCharge = atoi( the_token );
906
907 if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
908 sprintf( painCave.errMsg,
909 "Error parseing AtomTypes: line %d\n", lineNum );
910 painCave.isFatal = 1;
911 simError();
912 }
913
914 info.mass = atof( 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.epslon = atof( 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.sigma = atof( 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.charge = atof( the_token );
942
943 return 1;
944 }
945 else return 0;
946 }
947
948 int WATER_NS::parseDirectional( char *lineBuffer, int lineNum, directionalStruct &info ){
949
950 char* the_token;
951
952 the_token = strtok( lineBuffer, " \n\t,;" );
953 if( the_token != NULL ){
954
955 strcpy( info.name, the_token );
956
957 if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
958 sprintf( painCave.errMsg,
959 "Error parseing DirectionalTypes: line %d\n", lineNum );
960 painCave.isFatal = 1;
961 simError();
962 }
963
964 info.isDipole = atoi( the_token );
965
966 if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
967 sprintf( painCave.errMsg,
968 "Error parseing DirectionalTypes: line %d\n", lineNum );
969 painCave.isFatal = 1;
970 simError();
971 }
972
973 info.isSticky = atoi( the_token );
974
975 if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
976 sprintf( painCave.errMsg,
977 "Error parseing DirectionalTypes: line %d\n", lineNum );
978 painCave.isFatal = 1;
979 simError();
980 }
981
982 info.Ixx = atof( the_token );
983
984 if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
985 sprintf( painCave.errMsg,
986 "Error parseing DirectionalTypes: line %d\n", lineNum );
987 painCave.isFatal = 1;
988 simError();
989 }
990
991 info.Iyy = atof( 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.Izz = atof( 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
1010 info.dipole = atof( the_token );
1011
1012 if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1013 sprintf( painCave.errMsg,
1014 "Error parseing DirectionalTypes: line %d\n", lineNum );
1015 painCave.isFatal = 1;
1016 simError();
1017 }
1018
1019 info.w0 = atof( the_token );
1020
1021 if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1022 sprintf( painCave.errMsg,
1023 "Error parseing DirectionalTypes: line %d\n", lineNum );
1024 painCave.isFatal = 1;
1025 simError();
1026 }
1027
1028 info.v0 = atof( the_token );
1029
1030 if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1031 sprintf( painCave.errMsg,
1032 "Error parseing DirectionalTypes: line %d\n", lineNum );
1033 painCave.isFatal = 1;
1034 simError();
1035 }
1036
1037 info.v0p = atof( the_token );
1038
1039 if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1040 sprintf( painCave.errMsg,
1041 "Error parseing DirectionalTypes: line %d\n", lineNum );
1042 painCave.isFatal = 1;
1043 simError();
1044 }
1045
1046 info.rl = 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.ru = 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.rlp = 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.rup = atof( the_token );
1074
1075 return 1;
1076 }
1077 else return 0;
1078 }
1079 double WATER::getAtomTypeMass (char* atomType) {
1080
1081 currentAtomType = headAtomType->find( atomType );
1082 if( currentAtomType == NULL ){
1083 sprintf( painCave.errMsg,
1084 "AtomType error, %s not found in force file.\n",
1085 atomType );
1086 painCave.isFatal = 1;
1087 simError();
1088 }
1089
1090 return currentAtomType->mass;
1091 }