ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE_old/src/mdtools/libmdCode/TraPPE_ExFF.cpp
Revision: 291
Committed: Wed Mar 5 20:35:54 2003 UTC (21 years, 4 months ago) by mmeineke
File size: 42201 byte(s)
Log Message:
overhauled TraPPE_Ex forcfield in C++

File Contents

# User Rev Content
1 mmeineke 270 #include <cstdlib>
2     #include <cstdio>
3     #include <cstring>
4    
5     #include <iostream>
6     using namespace std;
7    
8     #include "ForceFields.hpp"
9     #include "SRI.hpp"
10     #include "simError.h"
11    
12 mmeineke 291 #ifdef IS_MPI
13     #include "mpiForceField.h"
14     #endif // is_mpi
15 mmeineke 270
16 mmeineke 291 namespace TPE { // restrict the access of the folowing to this file only.
17    
18    
19     // Declare the structures that will be passed by MPI
20    
21     typedef struct{
22     char name[15];
23     double mass;
24     double epslon;
25     double sigma;
26     double dipole;
27     double w0;
28     double v0;
29     int isSSD;
30     int isDipole;
31     int ident;
32     int last; // 0 -> default
33     // 1 -> tells nodes to stop listening
34     } atomStruct;
35    
36    
37     typedef struct{
38     char nameA[15];
39     char nameB[15];
40     char type[30];
41     double d0;
42     int last; // 0 -> default
43     // 1 -> tells nodes to stop listening
44     } bondStruct;
45    
46    
47     typedef struct{
48     char nameA[15];
49     char nameB[15];
50     char nameC[15];
51     char type[30];
52     double k1, k2, k3, t0;
53     int last; // 0 -> default
54     // 1 -> tells nodes to stop listening
55     } bendStruct;
56    
57    
58     typedef struct{
59     char nameA[15];
60     char nameB[15];
61     char nameC[15];
62     char nameD[15];
63     char type[30];
64     double k1, k2, k3, k4;
65     int last; // 0 -> default
66     // 1 -> tells nodes to stop listening
67     } torsionStruct;
68    
69    
70     int parseAtom( char *lineBuffer, int lineNum, atomStruct &info );
71     int parseBond( char *lineBuffer, int lineNum, bondStruct &info );
72     int parseBend( char *lineBuffer, int lineNum, bendStruct &info );
73     int parseTorsion( char *lineBuffer, int lineNum, torsionStruct &info );
74    
75    
76 mmeineke 270 #ifdef IS_MPI
77    
78 mmeineke 291 MPI_Datatype mpiAtomStructType;
79     MPI_Datatype mpiBondStructType;
80     MPI_Datatype mpiBendStructType;
81     MPI_Datatype mpiTorsionStructType;
82 mmeineke 270
83 mmeineke 291 #endif
84 mmeineke 270
85 mmeineke 291 } // namespace
86 mmeineke 270
87    
88 mmeineke 291 // declaration of functions needed to wrap the fortran module
89 mmeineke 270
90 mmeineke 291 extern "C" {
91 mmeineke 270
92 mmeineke 291 void forcefactory_( char* forceName,
93     int* status,
94     void (*wrapFunction)( void (*p1)( int* ident,
95     double* mass,
96     double* epslon,
97     double* sigma,
98     int* isDipole,
99     int* isSSd,
100     double* dipole,
101     double* w0,
102     double* v0,
103     int* status ),
104     void (*p2)( int *nLocal,
105     int *identArray,
106     int *isError ),
107     void (*p3)( double* positionArray,
108     double* forceArray,
109     double* potentialEnergy,
110     double* tau,
111     short int* doPotentialCalc,
112     int* isError)),
113     int forceNameLength );
114     }
115 mmeineke 270
116    
117 mmeineke 291 void TPEfunctionWrapper( void (*p1)( int* ident, double* mass, double* epslon,
118     double* sigma, int* isDipole, int* isSSD,
119     double* dipole, double* w0, double* v0,
120     int* status ),
121     void (*p2)( int *nLocal, int *identArray, int *isError ),
122     void (*p3)( double* positionArray,double* forceArray,
123     double* potentialEnergy, double* tau,
124     short int* doPotentialCalc, int* isError ) );
125 mmeineke 270
126 mmeineke 291 void (*newTPEtype)( int* ident, double* mass, double* epslon, double* sigma,
127     int* isDipole, int* isSSD, double* dipole, double* w0,
128     double* v0, int* status );
129 mmeineke 270
130 mmeineke 291 void (*initTPEfortran) ( int *nLocal, int *identArray, int *isError );
131    
132     TraPPE_ExFF* currentTPEwrap;
133    
134     using namespace TPE;
135    
136    
137     //****************************************************************
138     // begins the actual forcefield stuff.
139     //****************************************************************
140    
141    
142 mmeineke 270 TraPPE_ExFF::TraPPE_ExFF(){
143    
144     char fileName[200];
145     char* ffPath_env = "FORCE_PARAM_PATH";
146     char* ffPath;
147     char temp[200];
148     char errMsg[1000];
149    
150 mmeineke 291 // do the funtion wrapping
151     currentTPEwrap = this;
152     wrapMe();
153    
154    
155 mmeineke 270 #ifdef IS_MPI
156     int i;
157    
158 mmeineke 291 // **********************************************************************
159 mmeineke 270 // Init the atomStruct mpi type
160    
161     atomStruct atomProto; // mpiPrototype
162 mmeineke 291 int atomBC[3] = {15,6,4}; // block counts
163 mmeineke 270 MPI_Aint atomDspls[3]; // displacements
164     MPI_Datatype atomMbrTypes[3]; // member mpi types
165    
166     MPI_Address(&atomProto.name, &atomDspls[0]);
167     MPI_Address(&atomProto.mass, &atomDspls[1]);
168 mmeineke 291 MPI_Address(&atomProto.isSSD, &atomDspls[2]);
169 mmeineke 270
170     atomMbrTypes[0] = MPI_CHAR;
171     atomMbrTypes[1] = MPI_DOUBLE;
172     atomMbrTypes[2] = MPI_INT;
173    
174     for (i=2; i >= 0; i--) atomDspls[i] -= atomDspls[0];
175    
176     MPI_Type_struct(3, atomBC, atomDspls, atomMbrTypes, &mpiAtomStructType);
177     MPI_Type_commit(&mpiAtomStructType);
178    
179    
180     // **********************************************************************
181     // Init the bondStruct mpi type
182    
183     bondStruct bondProto; // mpiPrototype
184     int bondBC[3] = {60,1,1}; // block counts
185     MPI_Aint bondDspls[3]; // displacements
186     MPI_Datatype bondMbrTypes[3]; // member mpi types
187    
188     MPI_Address(&bondProto.nameA, &bondDspls[0]);
189     MPI_Address(&bondProto.d0, &bondDspls[1]);
190     MPI_Address(&bondProto.last, &bondDspls[2]);
191    
192     bondMbrTypes[0] = MPI_CHAR;
193     bondMbrTypes[1] = MPI_DOUBLE;
194     bondMbrTypes[2] = MPI_INT;
195    
196     for (i=2; i >= 0; i--) bondDspls[i] -= bondDspls[0];
197    
198     MPI_Type_struct(3, bondBC, bondDspls, bondMbrTypes, &mpiBondStructType);
199     MPI_Type_commit(&mpiBondStructType);
200    
201    
202     // **********************************************************************
203     // Init the bendStruct mpi type
204    
205     bendStruct bendProto; // mpiPrototype
206     int bendBC[3] = {75,4,1}; // block counts
207     MPI_Aint bendDspls[3]; // displacements
208     MPI_Datatype bendMbrTypes[3]; // member mpi types
209    
210     MPI_Address(&bendProto.nameA, &bendDspls[0]);
211     MPI_Address(&bendProto.k1, &bendDspls[1]);
212     MPI_Address(&bendProto.last, &bendDspls[2]);
213    
214     bendMbrTypes[0] = MPI_CHAR;
215     bendMbrTypes[1] = MPI_DOUBLE;
216     bendMbrTypes[2] = MPI_INT;
217    
218     for (i=2; i >= 0; i--) bendDspls[i] -= bendDspls[0];
219    
220     MPI_Type_struct(3, bendBC, bendDspls, bendMbrTypes, &mpiBendStructType);
221     MPI_Type_commit(&mpiBendStructType);
222    
223    
224     // **********************************************************************
225     // Init the torsionStruct mpi type
226    
227     torsionStruct torsionProto; // mpiPrototype
228     int torsionBC[3] = {90,4,1}; // block counts
229     MPI_Aint torsionDspls[3]; // displacements
230     MPI_Datatype torsionMbrTypes[3]; // member mpi types
231    
232     MPI_Address(&torsionProto.nameA, &torsionDspls[0]);
233     MPI_Address(&torsionProto.k1, &torsionDspls[1]);
234     MPI_Address(&torsionProto.last, &torsionDspls[2]);
235    
236     torsionMbrTypes[0] = MPI_CHAR;
237     torsionMbrTypes[1] = MPI_DOUBLE;
238     torsionMbrTypes[2] = MPI_INT;
239    
240     for (i=2; i >= 0; i--) torsionDspls[i] -= torsionDspls[0];
241    
242     MPI_Type_struct(3, torsionBC, torsionDspls, torsionMbrTypes,
243     &mpiTorsionStructType);
244     MPI_Type_commit(&mpiTorsionStructType);
245    
246     // ***********************************************************************
247    
248     if( worldRank == 0 ){
249     #endif
250    
251     // generate the force file name
252    
253     strcpy( fileName, "TraPPE_Ex.frc" );
254     // fprintf( stderr,"Trying to open %s\n", fileName );
255    
256     // attempt to open the file in the current directory first.
257    
258     frcFile = fopen( fileName, "r" );
259    
260     if( frcFile == NULL ){
261    
262     // next see if the force path enviorment variable is set
263    
264     ffPath = getenv( ffPath_env );
265     if( ffPath == NULL ) {
266     sprintf( painCave.errMsg,
267     "Error opening the force field parameter file: %s\n"
268     "Have you tried setting the FORCE_PARAM_PATH environment "
269     "vairable?\n",
270     fileName );
271     painCave.isFatal = 1;
272     simError();
273     }
274    
275    
276     strcpy( temp, ffPath );
277     strcat( temp, "/" );
278     strcat( temp, fileName );
279     strcpy( fileName, temp );
280    
281     frcFile = fopen( fileName, "r" );
282    
283     if( frcFile == NULL ){
284    
285     sprintf( painCave.errMsg,
286     "Error opening the force field parameter file: %s\n"
287     "Have you tried setting the FORCE_PARAM_PATH environment "
288     "vairable?\n",
289     fileName );
290     painCave.isFatal = 1;
291     simError();
292     }
293     }
294    
295     #ifdef IS_MPI
296     }
297    
298     sprintf( checkPointMsg, "TraPPE_ExFF file opened sucessfully." );
299     MPIcheckPoint();
300    
301     #endif // is_mpi
302     }
303    
304    
305     TraPPE_ExFF::~TraPPE_ExFF(){
306    
307     #ifdef IS_MPI
308     if( worldRank == 0 ){
309     #endif // is_mpi
310    
311     fclose( frcFile );
312    
313     #ifdef IS_MPI
314     }
315     #endif // is_mpi
316     }
317    
318 mmeineke 291
319     void TraPPE_ExFF::wrapMe( void ){
320    
321     char* currentFF = "TraPPE_Ex";
322     int isError = 0;
323    
324     forcefactory_( currentFF, &isError, TPEfunctionWrapper, strlen(currentFF) );
325    
326     if( isError ){
327    
328     sprintf( painCave.errMsg,
329     "TraPPE_ExFF error: an error was returned from fortran when the "
330     "the functions were being wrapped.\n" );
331     painCave.isFatal = 1;
332     simError();
333     }
334    
335     #ifdef IS_MPI
336     sprintf( checkPointMsg, "TraPPE_ExFF functions succesfully wrapped." );
337     MPIcheckPoint();
338     #endif // is_mpi
339     }
340    
341    
342     void TPEfunctionWrapper( void (*p1)( int* ident, double* mass, double* epslon,
343     double* sigma, int* isDipole,
344     int* isSSD, double* dipole, double* w0,
345     double* v0, int* isError ),
346     void (*p2)( int*, int*, int* ),
347     void (*p3)( double*,double*,double*,double*,
348     short int*, int* ) ){
349    
350    
351     newTPEtype = p1;
352     initTPEfortran = p2;
353     currentTPEwrap->setTPEfortran( p3 );
354     }
355    
356    
357    
358 mmeineke 270 void TraPPE_ExFF::initializeAtoms( void ){
359    
360     class LinkedType {
361     public:
362     LinkedType(){
363     next = NULL;
364     name[0] = '\0';
365     }
366     ~LinkedType(){ if( next != NULL ) delete next; }
367    
368     LinkedType* find(char* key){
369     if( !strcmp(name, key) ) return this;
370     if( next != NULL ) return next->find(key);
371     return NULL;
372     }
373    
374     void add( atomStruct &info ){
375 mmeineke 291
376     // check for duplicates
377    
378     if( !strcmp( info.name, name ) ){
379     sprintf( painCave.errMsg,
380     "Duplicate TraPPE_Ex atom type \"%s\" found in "
381     "the TraPPE_ExFF param file./n",
382     name );
383     painCave.isFatal = 1;
384     simError();
385     }
386    
387 mmeineke 270 if( next != NULL ) next->add(info);
388     else{
389     next = new LinkedType();
390     strcpy(next->name, info.name);
391 mmeineke 291 next->isDipole = info.isDipole;
392     next->isSSD = info.isSSD;
393 mmeineke 270 next->mass = info.mass;
394     next->epslon = info.epslon;
395     next->sigma = info.sigma;
396     next->dipole = info.dipole;
397 mmeineke 291 next->w0 = info.w0;
398     next->v0 = info.v0;
399     next->ident = info.ident;
400 mmeineke 270 }
401     }
402 mmeineke 291
403     #ifdef IS_MPI
404 mmeineke 270
405     void duplicate( atomStruct &info ){
406     strcpy(info.name, name);
407 mmeineke 291 info.isDipole = isDipole;
408     info.isSSD = isSSD;
409 mmeineke 270 info.mass = mass;
410     info.epslon = epslon;
411     info.sigma = sigma;
412     info.dipole = dipole;
413 mmeineke 291 info.w0 = w0;
414     info.v0 = v0;
415 mmeineke 270 info.last = 0;
416     }
417    
418    
419     #endif
420    
421     char name[15];
422     int isDipole;
423 mmeineke 291 int isSSD;
424 mmeineke 270 double mass;
425     double epslon;
426     double sigma;
427     double dipole;
428 mmeineke 291 double w0;
429     double v0;
430     int ident;
431 mmeineke 270 LinkedType* next;
432     };
433    
434     LinkedType* headAtomType;
435     LinkedType* currentAtomType;
436     atomStruct info;
437     info.last = 1; // initialize last to have the last set.
438     // if things go well, last will be set to 0
439 mmeineke 291
440 mmeineke 270
441    
442     int i;
443 mmeineke 291 int identNum;
444 mmeineke 270
445 mmeineke 291 Atom** the_atoms;
446     int nAtoms;
447     the_atoms = entry_plug->atoms;
448     nAtoms = entry_plug->n_atoms;
449    
450    
451 mmeineke 270 //////////////////////////////////////////////////
452     // a quick water fix
453    
454     double waterI[3][3];
455     waterI[0][0] = 1.76958347772500;
456     waterI[0][1] = 0.0;
457     waterI[0][2] = 0.0;
458    
459     waterI[1][0] = 0.0;
460     waterI[1][1] = 0.614537057924513;
461     waterI[1][2] = 0.0;
462    
463     waterI[2][0] = 0.0;
464     waterI[2][1] = 0.0;
465     waterI[2][2] = 1.15504641980049;
466    
467    
468     double headI[3][3];
469     headI[0][0] = 1125;
470     headI[0][1] = 0.0;
471     headI[0][2] = 0.0;
472    
473     headI[1][0] = 0.0;
474     headI[1][1] = 1125;
475     headI[1][2] = 0.0;
476    
477     headI[2][0] = 0.0;
478     headI[2][1] = 0.0;
479     headI[2][2] = 250;
480    
481    
482    
483     //////////////////////////////////////////////////
484    
485 mmeineke 291
486 mmeineke 270 #ifdef IS_MPI
487     if( worldRank == 0 ){
488     #endif
489    
490     // read in the atom types.
491 mmeineke 291
492 mmeineke 270 headAtomType = new LinkedType;
493    
494 mmeineke 291 fastForward( "AtomTypes", "initializeAtoms" );
495    
496 mmeineke 270 // we are now at the AtomTypes section.
497    
498     eof_test = fgets( readLine, sizeof(readLine), frcFile );
499     lineNum++;
500    
501 mmeineke 291
502     // read a line, and start parseing out the atom types
503    
504 mmeineke 270 if( eof_test == NULL ){
505     sprintf( painCave.errMsg,
506     "Error in reading Atoms from force file at line %d.\n",
507     lineNum );
508     painCave.isFatal = 1;
509     simError();
510     }
511    
512 mmeineke 291 identNum = 1;
513     // stop reading at end of file, or at next section
514 mmeineke 270 while( readLine[0] != '#' && eof_test != NULL ){
515 mmeineke 291
516     // toss comment lines
517 mmeineke 270 if( readLine[0] != '!' ){
518    
519 mmeineke 291 // the parser returns 0 if the line was blank
520     if( parseAtom( readLine, lineNum, info ) ){
521     info.ident = identNum;
522     headAtomType->add( info );;
523     identNum++;
524 mmeineke 270 }
525     }
526     eof_test = fgets( readLine, sizeof(readLine), frcFile );
527     lineNum++;
528     }
529    
530     #ifdef IS_MPI
531    
532     // send out the linked list to all the other processes
533    
534     sprintf( checkPointMsg,
535 mmeineke 291 "TraPPE_ExFF atom structures read successfully." );
536 mmeineke 270 MPIcheckPoint();
537    
538 mmeineke 291 currentAtomType = headAtomType->next; //skip the first element who is a place holder.
539 mmeineke 270 while( currentAtomType != NULL ){
540     currentAtomType->duplicate( info );
541 mmeineke 291
542    
543    
544 mmeineke 270 sendFrcStruct( &info, mpiAtomStructType );
545 mmeineke 291
546     sprintf( checkPointMsg,
547     "successfully sent TraPPE_Ex force type: \"%s\"\n",
548     info.name );
549     MPIcheckPoint();
550    
551 mmeineke 270 currentAtomType = currentAtomType->next;
552     }
553     info.last = 1;
554     sendFrcStruct( &info, mpiAtomStructType );
555    
556     }
557    
558     else{
559    
560     // listen for node 0 to send out the force params
561    
562     MPIcheckPoint();
563    
564     headAtomType = new LinkedType;
565     recieveFrcStruct( &info, mpiAtomStructType );
566 mmeineke 291
567 mmeineke 270 while( !info.last ){
568    
569 mmeineke 291
570    
571 mmeineke 270 headAtomType->add( info );
572 mmeineke 291
573     MPIcheckPoint();
574    
575 mmeineke 270 recieveFrcStruct( &info, mpiAtomStructType );
576     }
577     }
578     #endif // is_mpi
579    
580 mmeineke 291 // call new A_types in fortran
581 mmeineke 270
582 mmeineke 291 int isError;
583     currentAtomType = headAtomType;
584     while( currentAtomType != NULL ){
585    
586     if( currentAtomType->name[0] != '\0' ){
587     isError = 0;
588     newTPEtype( &(currentAtomType->ident),
589     &(currentAtomType->mass),
590     &(currentAtomType->epslon),
591     &(currentAtomType->sigma),
592     &(currentAtomType->isDipole),
593     &(currentAtomType->isSSD),
594     &(currentAtomType->dipole),
595     &(currentAtomType->w0),
596     &(currentAtomType->v0),
597     &isError );
598     if( isError ){
599     sprintf( painCave.errMsg,
600     "Error initializing the \"%s\" atom type in fortran\n",
601     currentAtomType->name );
602     painCave.isFatal = 1;
603     simError();
604     }
605     }
606     currentAtomType = currentAtomType->next;
607     }
608    
609     #ifdef IS_MPI
610     sprintf( checkPointMsg,
611     "TraPPE_ExFF atom structures successfully sent to fortran\n" );
612     MPIcheckPoint();
613     #endif // is_mpi
614    
615    
616 mmeineke 270 // initialize the atoms
617    
618 mmeineke 291 double bigSigma = 0.0;
619 mmeineke 270 DirectionalAtom* dAtom;
620    
621     for( i=0; i<nAtoms; i++ ){
622    
623     currentAtomType = headAtomType->find( the_atoms[i]->getType() );
624     if( currentAtomType == NULL ){
625     sprintf( painCave.errMsg,
626     "AtomType error, %s not found in force file.\n",
627     the_atoms[i]->getType() );
628     painCave.isFatal = 1;
629     simError();
630     }
631    
632     the_atoms[i]->setMass( currentAtomType->mass );
633     the_atoms[i]->setEpslon( currentAtomType->epslon );
634     the_atoms[i]->setSigma( currentAtomType->sigma );
635     the_atoms[i]->setLJ();
636    
637 mmeineke 291 if( bigSigma < currentAtomType->sigma ) bigSigma = currentAtomType->sigma;
638    
639 mmeineke 270 if( currentAtomType->isDipole ){
640     if( the_atoms[i]->isDirectional() ){
641    
642     dAtom = (DirectionalAtom *) the_atoms[i];
643     dAtom->setMu( currentAtomType->dipole );
644     dAtom->setHasDipole( 1 );
645     dAtom->setJx( 0.0 );
646     dAtom->setJy( 0.0 );
647     dAtom->setJz( 0.0 );
648    
649     if(!strcmp("SSD",the_atoms[i]->getType())){
650     dAtom->setI( waterI );
651     dAtom->setSSD( 1 );
652     }
653     else if(!strcmp("HEAD",the_atoms[i]->getType())){
654     dAtom->setI( headI );
655     dAtom->setSSD( 0 );
656     }
657     else{
658     sprintf(painCave.errMsg,
659     "AtmType error, %s does not have a moment of inertia set.\n",
660     the_atoms[i]->getType() );
661     painCave.isFatal = 1;
662     simError();
663     }
664     entry_plug->n_dipoles++;
665     }
666     else{
667    
668     sprintf( painCave.errMsg,
669     "TraPPE_ExFF error: Atom \"%s\" is a dipole, yet no standard"
670     " orientation was specifed in the BASS file.\n",
671     currentAtomType->name );
672     painCave.isFatal = 1;
673     simError();
674     }
675     }
676     else{
677     if( the_atoms[i]->isDirectional() ){
678     sprintf( painCave.errMsg,
679     "TraPPE_ExFF error: Atom \"%s\" was given a standard"
680     "orientation in the BASS file, yet it is not a dipole.\n",
681     currentAtomType->name);
682     painCave.isFatal = 1;
683     simError();
684     }
685     }
686     }
687    
688 mmeineke 291 #ifdef IS_MPI
689     double tempBig = bigSigma;
690     MPI::COMM_WORLD.Allreduce( &tempBig, &bigSigma, 1, MPI_DOUBLE, MPI_MAX );
691     #endif //is_mpi
692 mmeineke 270
693 mmeineke 291 //calc rCut and rList
694    
695     entry_plug->rCut = 2.5 * bigSigma;
696    
697     if(entry_plug->rCut > (entry_plug->box_x / 2.0))
698     entry_plug->rCut = entry_plug->box_x / 2.0;
699    
700     if(entry_plug->rCut > (entry_plug->box_y / 2.0))
701     entry_plug->rCut = entry_plug->box_y / 2.0;
702    
703     if(entry_plug->rCut > (entry_plug->box_z / 2.0))
704     entry_plug->rCut = entry_plug->box_z / 2.0;
705    
706     entry_plug->rList = entry_plug->rCut + 1.0;
707    
708    
709 mmeineke 270 // clean up the memory
710    
711     delete headAtomType;
712    
713     #ifdef IS_MPI
714     sprintf( checkPointMsg, "TraPPE_Ex atoms initialized succesfully" );
715     MPIcheckPoint();
716     #endif // is_mpi
717    
718     }
719    
720     void TraPPE_ExFF::initializeBonds( bond_pair* the_bonds ){
721    
722     class LinkedType {
723     public:
724     LinkedType(){
725     next = NULL;
726     nameA[0] = '\0';
727     nameB[0] = '\0';
728     type[0] = '\0';
729     }
730     ~LinkedType(){ if( next != NULL ) delete next; }
731    
732     LinkedType* find(char* key1, char* key2){
733     if( !strcmp(nameA, key1 ) && !strcmp( nameB, key2 ) ) return this;
734     if( !strcmp(nameA, key2 ) && !strcmp( nameB, key1 ) ) return this;
735     if( next != NULL ) return next->find(key1, key2);
736     return NULL;
737     }
738    
739 mmeineke 291
740 mmeineke 270 void add( bondStruct &info ){
741 mmeineke 291
742     // check for duplicates
743     int dup = 0;
744    
745     if( !strcmp(nameA, info.nameA ) && !strcmp( nameB, info.nameB ) ) dup = 1;
746     if( !strcmp(nameA, info.nameB ) && !strcmp( nameB, info.nameA ) ) dup = 1;
747    
748     if(dup){
749     sprintf( painCave.errMsg,
750     "Duplicate TraPPE_Ex bond type \"%s - %s\" found in "
751     "the TraPPE_ExFF param file./n",
752     nameA, nameB );
753     painCave.isFatal = 1;
754     simError();
755     }
756    
757    
758 mmeineke 270 if( next != NULL ) next->add(info);
759     else{
760     next = new LinkedType();
761     strcpy(next->nameA, info.nameA);
762     strcpy(next->nameB, info.nameB);
763     strcpy(next->type, info.type);
764     next->d0 = info.d0;
765     }
766     }
767    
768 mmeineke 291 #ifdef IS_MPI
769 mmeineke 270 void duplicate( bondStruct &info ){
770     strcpy(info.nameA, nameA);
771     strcpy(info.nameB, nameB);
772     strcpy(info.type, type);
773     info.d0 = d0;
774     info.last = 0;
775     }
776    
777    
778     #endif
779    
780     char nameA[15];
781     char nameB[15];
782     char type[30];
783     double d0;
784    
785     LinkedType* next;
786     };
787    
788    
789    
790     LinkedType* headBondType;
791     LinkedType* currentBondType;
792     bondStruct info;
793     info.last = 1; // initialize last to have the last set.
794     // if things go well, last will be set to 0
795    
796     SRI **the_sris;
797     Atom** the_atoms;
798     int nBonds;
799     the_sris = entry_plug->sr_interactions;
800     the_atoms = entry_plug->atoms;
801     nBonds = entry_plug->n_bonds;
802    
803 mmeineke 291 int i, a, b;
804     char* atomA;
805     char* atomB;
806 mmeineke 270
807     #ifdef IS_MPI
808     if( worldRank == 0 ){
809     #endif
810    
811     // read in the bond types.
812    
813     headBondType = new LinkedType;
814    
815 mmeineke 291 fastForward( "BondTypes", "initializeBonds" );
816    
817     // we are now at the bondTypes section
818    
819     eof_test = fgets( readLine, sizeof(readLine), frcFile );
820 mmeineke 270 lineNum++;
821    
822    
823 mmeineke 291 // read a line, and start parseing out the atom types
824    
825 mmeineke 270 if( eof_test == NULL ){
826     sprintf( painCave.errMsg,
827 mmeineke 291 "Error in reading bonds from force file at line %d.\n",
828 mmeineke 270 lineNum );
829     painCave.isFatal = 1;
830     simError();
831     }
832    
833 mmeineke 291 // stop reading at end of file, or at next section
834 mmeineke 270 while( readLine[0] != '#' && eof_test != NULL ){
835 mmeineke 291
836     // toss comment lines
837 mmeineke 270 if( readLine[0] != '!' ){
838    
839 mmeineke 291 // the parser returns 0 if the line was blank
840     if( parseBond( readLine, lineNum, info ) ){
841     headBondType->add( info );
842 mmeineke 270 }
843     }
844     eof_test = fgets( readLine, sizeof(readLine), frcFile );
845     lineNum++;
846     }
847 mmeineke 291
848 mmeineke 270 #ifdef IS_MPI
849    
850     // send out the linked list to all the other processes
851    
852     sprintf( checkPointMsg,
853     "TraPPE_Ex bond structures read successfully." );
854     MPIcheckPoint();
855    
856     currentBondType = headBondType;
857     while( currentBondType != NULL ){
858     currentBondType->duplicate( info );
859     sendFrcStruct( &info, mpiBondStructType );
860     currentBondType = currentBondType->next;
861     }
862     info.last = 1;
863     sendFrcStruct( &info, mpiBondStructType );
864    
865     }
866    
867     else{
868    
869     // listen for node 0 to send out the force params
870    
871     MPIcheckPoint();
872    
873     headBondType = new LinkedType;
874     recieveFrcStruct( &info, mpiBondStructType );
875     while( !info.last ){
876    
877     headBondType->add( info );
878     recieveFrcStruct( &info, mpiBondStructType );
879     }
880     }
881     #endif // is_mpi
882    
883    
884     // initialize the Bonds
885    
886    
887     for( i=0; i<nBonds; i++ ){
888    
889     a = the_bonds[i].a;
890     b = the_bonds[i].b;
891    
892     atomA = the_atoms[a]->getType();
893     atomB = the_atoms[b]->getType();
894     currentBondType = headBondType->find( atomA, atomB );
895     if( currentBondType == NULL ){
896     sprintf( painCave.errMsg,
897     "BondType error, %s - %s not found in force file.\n",
898     atomA, atomB );
899     painCave.isFatal = 1;
900     simError();
901     }
902    
903     if( !strcmp( currentBondType->type, "fixed" ) ){
904    
905     the_sris[i] = new ConstrainedBond( *the_atoms[a],
906     *the_atoms[b],
907     currentBondType->d0 );
908     entry_plug->n_constraints++;
909     }
910     }
911    
912    
913     // clean up the memory
914    
915     delete headBondType;
916    
917     #ifdef IS_MPI
918     sprintf( checkPointMsg, "TraPPE_Ex bonds initialized succesfully" );
919     MPIcheckPoint();
920     #endif // is_mpi
921    
922     }
923    
924     void TraPPE_ExFF::initializeBends( bend_set* the_bends ){
925    
926     class LinkedType {
927     public:
928     LinkedType(){
929     next = NULL;
930     nameA[0] = '\0';
931     nameB[0] = '\0';
932     nameC[0] = '\0';
933     type[0] = '\0';
934     }
935     ~LinkedType(){ if( next != NULL ) delete next; }
936    
937     LinkedType* find( char* key1, char* key2, char* key3 ){
938     if( !strcmp( nameA, key1 ) && !strcmp( nameB, key2 )
939     && !strcmp( nameC, key3 ) ) return this;
940     if( !strcmp( nameA, key3 ) && !strcmp( nameB, key2 )
941     && !strcmp( nameC, key1 ) ) return this;
942     if( next != NULL ) return next->find(key1, key2, key3);
943     return NULL;
944     }
945    
946 mmeineke 291 void add( bendStruct &info ){
947 mmeineke 270
948 mmeineke 291 // check for duplicates
949     int dup = 0;
950    
951     if( !strcmp( nameA, info.nameA ) && !strcmp( nameB, info.nameB )
952     && !strcmp( nameC, info.nameC ) ) dup = 1;
953     if( !strcmp( nameA, info.nameC ) && !strcmp( nameB, info.nameB )
954     && !strcmp( nameC, info.nameA ) ) dup = 1;
955    
956     if(dup){
957     sprintf( painCave.errMsg,
958     "Duplicate TraPPE_Ex bend type \"%s - %s - %s\" found in "
959     "the TraPPE_ExFF param file./n",
960     nameA, nameB, nameC );
961     painCave.isFatal = 1;
962     simError();
963     }
964    
965 mmeineke 270 if( next != NULL ) next->add(info);
966     else{
967     next = new LinkedType();
968     strcpy(next->nameA, info.nameA);
969     strcpy(next->nameB, info.nameB);
970     strcpy(next->nameC, info.nameC);
971     strcpy(next->type, info.type);
972     next->k1 = info.k1;
973     next->k2 = info.k2;
974     next->k3 = info.k3;
975     next->t0 = info.t0;
976     }
977     }
978 mmeineke 291
979     #ifdef IS_MPI
980    
981 mmeineke 270 void duplicate( bendStruct &info ){
982     strcpy(info.nameA, nameA);
983     strcpy(info.nameB, nameB);
984     strcpy(info.nameC, nameC);
985     strcpy(info.type, type);
986     info.k1 = k1;
987     info.k2 = k2;
988     info.k3 = k3;
989     info.t0 = t0;
990     info.last = 0;
991     }
992    
993     #endif // is_mpi
994    
995     char nameA[15];
996     char nameB[15];
997     char nameC[15];
998     char type[30];
999     double k1, k2, k3, t0;
1000    
1001     LinkedType* next;
1002     };
1003    
1004     LinkedType* headBendType;
1005     LinkedType* currentBendType;
1006     bendStruct info;
1007     info.last = 1; // initialize last to have the last set.
1008     // if things go well, last will be set to 0
1009    
1010     QuadraticBend* qBend;
1011     SRI **the_sris;
1012     Atom** the_atoms;
1013     int nBends;
1014     the_sris = entry_plug->sr_interactions;
1015     the_atoms = entry_plug->atoms;
1016     nBends = entry_plug->n_bends;
1017    
1018 mmeineke 291 int i, a, b, c;
1019     char* atomA;
1020     char* atomB;
1021     char* atomC;
1022 mmeineke 270
1023 mmeineke 291
1024 mmeineke 270 #ifdef IS_MPI
1025     if( worldRank == 0 ){
1026     #endif
1027    
1028     // read in the bend types.
1029    
1030     headBendType = new LinkedType;
1031    
1032 mmeineke 291 fastForward( "BendTypes", "initializeBends" );
1033 mmeineke 270
1034 mmeineke 291 // we are now at the bendTypes section
1035 mmeineke 270
1036 mmeineke 291 eof_test = fgets( readLine, sizeof(readLine), frcFile );
1037     lineNum++;
1038    
1039     // read a line, and start parseing out the bend types
1040 mmeineke 270
1041     if( eof_test == NULL ){
1042     sprintf( painCave.errMsg,
1043 mmeineke 291 "Error in reading bends from force file at line %d.\n",
1044 mmeineke 270 lineNum );
1045     painCave.isFatal = 1;
1046     simError();
1047     }
1048 mmeineke 291
1049     // stop reading at end of file, or at next section
1050 mmeineke 270 while( readLine[0] != '#' && eof_test != NULL ){
1051 mmeineke 291
1052     // toss comment lines
1053 mmeineke 270 if( readLine[0] != '!' ){
1054    
1055 mmeineke 291 // the parser returns 0 if the line was blank
1056     if( parseBend( readLine, lineNum, info ) ){
1057     headBendType->add( info );
1058 mmeineke 270 }
1059     }
1060     eof_test = fgets( readLine, sizeof(readLine), frcFile );
1061     lineNum++;
1062     }
1063 mmeineke 291
1064 mmeineke 270 #ifdef IS_MPI
1065    
1066     // send out the linked list to all the other processes
1067    
1068     sprintf( checkPointMsg,
1069     "TraPPE_Ex bend structures read successfully." );
1070     MPIcheckPoint();
1071    
1072     currentBendType = headBendType;
1073     while( currentBendType != NULL ){
1074     currentBendType->duplicate( info );
1075     sendFrcStruct( &info, mpiBendStructType );
1076     currentBendType = currentBendType->next;
1077     }
1078     info.last = 1;
1079     sendFrcStruct( &info, mpiBendStructType );
1080    
1081     }
1082    
1083     else{
1084    
1085     // listen for node 0 to send out the force params
1086    
1087     MPIcheckPoint();
1088    
1089     headBendType = new LinkedType;
1090     recieveFrcStruct( &info, mpiBendStructType );
1091     while( !info.last ){
1092    
1093     headBendType->add( info );
1094     recieveFrcStruct( &info, mpiBendStructType );
1095     }
1096     }
1097     #endif // is_mpi
1098    
1099     // initialize the Bends
1100 mmeineke 291
1101     int index;
1102 mmeineke 270
1103     for( i=0; i<nBends; i++ ){
1104    
1105     a = the_bends[i].a;
1106     b = the_bends[i].b;
1107     c = the_bends[i].c;
1108    
1109     atomA = the_atoms[a]->getType();
1110     atomB = the_atoms[b]->getType();
1111     atomC = the_atoms[c]->getType();
1112     currentBendType = headBendType->find( atomA, atomB, atomC );
1113     if( currentBendType == NULL ){
1114     sprintf( painCave.errMsg, "BendType error, %s - %s - %s not found"
1115     " in force file.\n",
1116     atomA, atomB, atomC );
1117     painCave.isFatal = 1;
1118     simError();
1119     }
1120    
1121     if( !strcmp( currentBendType->type, "quadratic" ) ){
1122    
1123     index = i + entry_plug->n_bonds;
1124     qBend = new QuadraticBend( *the_atoms[a],
1125     *the_atoms[b],
1126     *the_atoms[c] );
1127     qBend->setConstants( currentBendType->k1,
1128     currentBendType->k2,
1129     currentBendType->k3,
1130     currentBendType->t0 );
1131     the_sris[index] = qBend;
1132     }
1133     }
1134    
1135    
1136     // clean up the memory
1137    
1138     delete headBendType;
1139    
1140     #ifdef IS_MPI
1141     sprintf( checkPointMsg, "TraPPE_Ex bends initialized succesfully" );
1142     MPIcheckPoint();
1143     #endif // is_mpi
1144    
1145     }
1146    
1147     void TraPPE_ExFF::initializeTorsions( torsion_set* the_torsions ){
1148    
1149     class LinkedType {
1150     public:
1151     LinkedType(){
1152     next = NULL;
1153     nameA[0] = '\0';
1154     nameB[0] = '\0';
1155     nameC[0] = '\0';
1156     type[0] = '\0';
1157     }
1158     ~LinkedType(){ if( next != NULL ) delete next; }
1159    
1160     LinkedType* find( char* key1, char* key2, char* key3, char* key4 ){
1161     if( !strcmp( nameA, key1 ) && !strcmp( nameB, key2 ) &&
1162     !strcmp( nameC, key3 ) && !strcmp( nameD, key4 ) ) return this;
1163    
1164     if( !strcmp( nameA, key4 ) && !strcmp( nameB, key3 ) &&
1165 mmeineke 291 !strcmp( nameC, key2 ) && !strcmp( nameD, key1 ) ) return this;
1166 mmeineke 270
1167     if( next != NULL ) return next->find(key1, key2, key3, key4);
1168     return NULL;
1169     }
1170    
1171     void add( torsionStruct &info ){
1172 mmeineke 291
1173     // check for duplicates
1174     int dup = 0;
1175    
1176     if( !strcmp( nameA, info.nameA ) && !strcmp( nameB, info.nameB ) &&
1177     !strcmp( nameC, info.nameC ) && !strcmp( nameD, info.nameD ) ) dup = 1;
1178    
1179     if( !strcmp( nameA, info.nameD ) && !strcmp( nameB, info.nameC ) &&
1180     !strcmp( nameC, info.nameB ) && !strcmp( nameD, info.nameA ) ) dup = 1;
1181    
1182     if(dup){
1183     sprintf( painCave.errMsg,
1184     "Duplicate TraPPE_Ex torsion type \"%s - %s - %s - %s\" found in "
1185     "the TraPPE_ExFF param file./n", nameA, nameB, nameC, nameD );
1186     painCave.isFatal = 1;
1187     simError();
1188     }
1189    
1190 mmeineke 270 if( next != NULL ) next->add(info);
1191     else{
1192     next = new LinkedType();
1193     strcpy(next->nameA, info.nameA);
1194     strcpy(next->nameB, info.nameB);
1195     strcpy(next->nameC, info.nameC);
1196     strcpy(next->type, info.type);
1197     next->k1 = info.k1;
1198     next->k2 = info.k2;
1199     next->k3 = info.k3;
1200     next->k4 = info.k4;
1201     }
1202     }
1203 mmeineke 291
1204     #ifdef IS_MPI
1205 mmeineke 270
1206     void duplicate( torsionStruct &info ){
1207     strcpy(info.nameA, nameA);
1208     strcpy(info.nameB, nameB);
1209     strcpy(info.nameC, nameC);
1210     strcpy(info.nameD, nameD);
1211     strcpy(info.type, type);
1212     info.k1 = k1;
1213     info.k2 = k2;
1214     info.k3 = k3;
1215     info.k4 = k4;
1216     info.last = 0;
1217     }
1218    
1219     #endif
1220    
1221     char nameA[15];
1222     char nameB[15];
1223     char nameC[15];
1224     char nameD[15];
1225     char type[30];
1226     double k1, k2, k3, k4;
1227    
1228     LinkedType* next;
1229     };
1230    
1231     LinkedType* headTorsionType;
1232     LinkedType* currentTorsionType;
1233     torsionStruct info;
1234     info.last = 1; // initialize last to have the last set.
1235     // if things go well, last will be set to 0
1236    
1237     int i, a, b, c, d, index;
1238     char* atomA;
1239     char* atomB;
1240     char* atomC;
1241     char* atomD;
1242     CubicTorsion* cTors;
1243    
1244     SRI **the_sris;
1245     Atom** the_atoms;
1246     int nTorsions;
1247     the_sris = entry_plug->sr_interactions;
1248     the_atoms = entry_plug->atoms;
1249     nTorsions = entry_plug->n_torsions;
1250    
1251     #ifdef IS_MPI
1252     if( worldRank == 0 ){
1253     #endif
1254    
1255     // read in the torsion types.
1256    
1257     headTorsionType = new LinkedType;
1258 mmeineke 291
1259     fastForward( "TorsionTypes", "initializeTorsions" );
1260 mmeineke 270
1261 mmeineke 291 // we are now at the torsionTypes section
1262 mmeineke 270
1263 mmeineke 291 eof_test = fgets( readLine, sizeof(readLine), frcFile );
1264     lineNum++;
1265 mmeineke 270
1266 mmeineke 291
1267     // read a line, and start parseing out the atom types
1268 mmeineke 270
1269     if( eof_test == NULL ){
1270     sprintf( painCave.errMsg,
1271 mmeineke 291 "Error in reading torsions from force file at line %d.\n",
1272 mmeineke 270 lineNum );
1273     painCave.isFatal = 1;
1274     simError();
1275     }
1276 mmeineke 291
1277     // stop reading at end of file, or at next section
1278     while( readLine[0] != '#' && eof_test != NULL ){
1279 mmeineke 270
1280 mmeineke 291 // toss comment lines
1281 mmeineke 270 if( readLine[0] != '!' ){
1282    
1283 mmeineke 291 // the parser returns 0 if the line was blank
1284     if( parseTorsion( readLine, lineNum, info ) ){
1285     headTorsionType->add( info );
1286 mmeineke 270 }
1287     }
1288     eof_test = fgets( readLine, sizeof(readLine), frcFile );
1289     lineNum++;
1290     }
1291    
1292     #ifdef IS_MPI
1293    
1294     // send out the linked list to all the other processes
1295    
1296     sprintf( checkPointMsg,
1297     "TraPPE_Ex torsion structures read successfully." );
1298     MPIcheckPoint();
1299    
1300     currentTorsionType = headTorsionType;
1301     while( currentTorsionType != NULL ){
1302     currentTorsionType->duplicate( info );
1303     sendFrcStruct( &info, mpiTorsionStructType );
1304     currentTorsionType = currentTorsionType->next;
1305     }
1306     info.last = 1;
1307     sendFrcStruct( &info, mpiTorsionStructType );
1308    
1309     }
1310    
1311     else{
1312    
1313     // listen for node 0 to send out the force params
1314    
1315     MPIcheckPoint();
1316    
1317     headTorsionType = new LinkedType;
1318     recieveFrcStruct( &info, mpiTorsionStructType );
1319     while( !info.last ){
1320    
1321     headTorsionType->add( info );
1322     recieveFrcStruct( &info, mpiTorsionStructType );
1323     }
1324     }
1325     #endif // is_mpi
1326    
1327     // initialize the Torsions
1328    
1329     for( i=0; i<nTorsions; i++ ){
1330    
1331     a = the_torsions[i].a;
1332     b = the_torsions[i].b;
1333     c = the_torsions[i].c;
1334     d = the_torsions[i].d;
1335    
1336     atomA = the_atoms[a]->getType();
1337     atomB = the_atoms[b]->getType();
1338     atomC = the_atoms[c]->getType();
1339     atomD = the_atoms[d]->getType();
1340     currentTorsionType = headTorsionType->find( atomA, atomB, atomC, atomD );
1341     if( currentTorsionType == NULL ){
1342     sprintf( painCave.errMsg,
1343     "TorsionType error, %s - %s - %s - %s not found"
1344     " in force file.\n",
1345     atomA, atomB, atomC, atomD );
1346     painCave.isFatal = 1;
1347     simError();
1348     }
1349    
1350     if( !strcmp( currentTorsionType->type, "cubic" ) ){
1351     index = i + entry_plug->n_bonds + entry_plug->n_bends;
1352    
1353     cTors = new CubicTorsion( *the_atoms[a], *the_atoms[b],
1354     *the_atoms[c], *the_atoms[d] );
1355     cTors->setConstants( currentTorsionType->k1, currentTorsionType->k2,
1356     currentTorsionType->k3, currentTorsionType->k4 );
1357     the_sris[index] = cTors;
1358     }
1359     }
1360    
1361    
1362     // clean up the memory
1363    
1364     delete headTorsionType;
1365    
1366     #ifdef IS_MPI
1367     sprintf( checkPointMsg, "TraPPE_Ex torsions initialized succesfully" );
1368     MPIcheckPoint();
1369     #endif // is_mpi
1370    
1371     }
1372 mmeineke 291
1373     void TraPPE_ExFF::fastForward( char* stopText, char* searchOwner ){
1374    
1375     int foundText = 0;
1376     char* the_token;
1377    
1378     rewind( frcFile );
1379     lineNum = 0;
1380    
1381     eof_test = fgets( readLine, sizeof(readLine), frcFile );
1382     lineNum++;
1383     if( eof_test == NULL ){
1384     sprintf( painCave.errMsg, "Error fast forwarding force file for %s: "
1385     " file is empty.\n",
1386     searchOwner );
1387     painCave.isFatal = 1;
1388     simError();
1389     }
1390    
1391    
1392     while( !foundText ){
1393     while( eof_test != NULL && readLine[0] != '#' ){
1394     eof_test = fgets( readLine, sizeof(readLine), frcFile );
1395     lineNum++;
1396     }
1397     if( eof_test == NULL ){
1398     sprintf( painCave.errMsg,
1399     "Error fast forwarding force file for %s at "
1400     "line %d: file ended unexpectedly.\n",
1401     searchOwner,
1402     lineNum );
1403     painCave.isFatal = 1;
1404     simError();
1405     }
1406    
1407     the_token = strtok( readLine, " ,;\t#\n" );
1408     foundText = !strcmp( stopText, the_token );
1409    
1410     if( !foundText ){
1411     eof_test = fgets( readLine, sizeof(readLine), frcFile );
1412     lineNum++;
1413    
1414     if( eof_test == NULL ){
1415     sprintf( painCave.errMsg,
1416     "Error fast forwarding force file for %s at "
1417     "line %d: file ended unexpectedly.\n",
1418     searchOwner,
1419     lineNum );
1420     painCave.isFatal = 1;
1421     simError();
1422     }
1423     }
1424     }
1425     }
1426    
1427    
1428     int parseAtom( char *lineBuffer, int lineNum, atomStruct &info ){
1429    
1430     char* the_token;
1431    
1432     the_token = strtok( lineBuffer, " \n\t,;" );
1433     if( the_token != NULL ){
1434    
1435     strcpy( info.name, the_token );
1436    
1437     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1438     sprintf( painCave.errMsg,
1439     "Error parseing AtomTypes: line %d\n", lineNum );
1440     painCave.isFatal = 1;
1441     simError();
1442     }
1443    
1444     info.isDipole = atoi( the_token );
1445    
1446     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1447     sprintf( painCave.errMsg,
1448     "Error parseing AtomTypes: line %d\n", lineNum );
1449     painCave.isFatal = 1;
1450     simError();
1451     }
1452    
1453     info.isSSD = atoi( the_token );
1454    
1455     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1456     sprintf( painCave.errMsg,
1457     "Error parseing AtomTypes: line %d\n", lineNum );
1458     painCave.isFatal = 1;
1459     simError();
1460     }
1461    
1462     info.mass = atof( the_token );
1463    
1464     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1465     sprintf( painCave.errMsg,
1466     "Error parseing AtomTypes: line %d\n", lineNum );
1467     painCave.isFatal = 1;
1468     simError();
1469     }
1470    
1471     info.epslon = atof( the_token );
1472    
1473     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1474     sprintf( painCave.errMsg,
1475     "Error parseing AtomTypes: line %d\n", lineNum );
1476     painCave.isFatal = 1;
1477     simError();
1478     }
1479    
1480     info.sigma = atof( the_token );
1481    
1482     if( info.isDipole ){
1483    
1484     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1485     sprintf( painCave.errMsg,
1486     "Error parseing AtomTypes: line %d\n", lineNum );
1487     painCave.isFatal = 1;
1488     simError();
1489     }
1490    
1491     info.dipole = atof( the_token );
1492     }
1493     else info.dipole = 0.0;
1494    
1495     if( info.isSSD ){
1496    
1497     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1498     sprintf( painCave.errMsg,
1499     "Error parseing AtomTypes: line %d\n", lineNum );
1500     painCave.isFatal = 1;
1501     simError();
1502     }
1503    
1504     info.w0 = atof( the_token );
1505    
1506     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1507     sprintf( painCave.errMsg,
1508     "Error parseing AtomTypes: line %d\n", lineNum );
1509     painCave.isFatal = 1;
1510     simError();
1511     }
1512    
1513     info.v0 = atof( the_token );
1514     }
1515     else info.v0 = info.w0 = 0.0;
1516    
1517     return 1;
1518     }
1519     else return 0;
1520     }
1521    
1522     int parseBond( char *lineBuffer, int lineNum, bondStruct &info ){
1523    
1524     char* the_token;
1525    
1526     the_token = strtok( lineBuffer, " \n\t,;" );
1527     if( the_token != NULL ){
1528    
1529     strcpy( info.nameA, the_token );
1530    
1531     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1532     sprintf( painCave.errMsg,
1533     "Error parseing BondTypes: line %d\n", lineNum );
1534     painCave.isFatal = 1;
1535     simError();
1536     }
1537    
1538     strcpy( info.nameB, the_token );
1539    
1540     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1541     sprintf( painCave.errMsg,
1542     "Error parseing BondTypes: line %d\n", lineNum );
1543     painCave.isFatal = 1;
1544     simError();
1545     }
1546    
1547     strcpy( info.type, the_token );
1548    
1549     if( !strcmp( info.type, "fixed" ) ){
1550     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1551     sprintf( painCave.errMsg,
1552     "Error parseing BondTypes: line %d\n", lineNum );
1553     painCave.isFatal = 1;
1554     simError();
1555     }
1556    
1557     info.d0 = atof( the_token );
1558     }
1559     else{
1560     sprintf( painCave.errMsg,
1561     "Unknown TraPPE_Ex bond type \"%s\" at line %d\n",
1562     info.type,
1563     lineNum );
1564     painCave.isFatal = 1;
1565     simError();
1566     }
1567    
1568     return 1;
1569     }
1570     else return 0;
1571     }
1572    
1573    
1574     int parseBend( char *lineBuffer, int lineNum, bendStruct &info ){
1575    
1576     char* the_token;
1577    
1578     the_token = strtok( lineBuffer, " \n\t,;" );
1579     if( the_token != NULL ){
1580    
1581     strcpy( info.nameA, the_token );
1582    
1583     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1584     sprintf( painCave.errMsg,
1585     "Error parseing BondTypes: line %d\n", lineNum );
1586     painCave.isFatal = 1;
1587     simError();
1588     }
1589    
1590     strcpy( info.nameB, the_token );
1591    
1592     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1593     sprintf( painCave.errMsg,
1594     "Error parseing BondTypes: line %d\n", lineNum );
1595     painCave.isFatal = 1;
1596     simError();
1597     }
1598    
1599     strcpy( info.nameC, the_token );
1600    
1601     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1602     sprintf( painCave.errMsg,
1603     "Error parseing BondTypes: line %d\n", lineNum );
1604     painCave.isFatal = 1;
1605     simError();
1606     }
1607    
1608     strcpy( info.type, the_token );
1609    
1610     if( !strcmp( info.type, "quadratic" ) ){
1611     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1612     sprintf( painCave.errMsg,
1613     "Error parseing BendTypes: line %d\n", lineNum );
1614     painCave.isFatal = 1;
1615     simError();
1616     }
1617    
1618     info.k1 = atof( the_token );
1619    
1620     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1621     sprintf( painCave.errMsg,
1622     "Error parseing BendTypes: line %d\n", lineNum );
1623     painCave.isFatal = 1;
1624     simError();
1625     }
1626    
1627     info.k2 = atof( the_token );
1628    
1629     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1630     sprintf( painCave.errMsg,
1631     "Error parseing BendTypes: line %d\n", lineNum );
1632     painCave.isFatal = 1;
1633     simError();
1634     }
1635    
1636     info.k3 = atof( the_token );
1637    
1638     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1639     sprintf( painCave.errMsg,
1640     "Error parseing BendTypes: line %d\n", lineNum );
1641     painCave.isFatal = 1;
1642     simError();
1643     }
1644    
1645     info.t0 = atof( the_token );
1646     }
1647    
1648     else{
1649     sprintf( painCave.errMsg,
1650     "Unknown TraPPE_Ex bend type \"%s\" at line %d\n",
1651     info.type,
1652     lineNum );
1653     painCave.isFatal = 1;
1654     simError();
1655     }
1656    
1657     return 1;
1658     }
1659     else return 0;
1660     }
1661    
1662     int parseTorsion( char *lineBuffer, int lineNum, torsionStruct &info ){
1663    
1664     char* the_token;
1665    
1666     the_token = strtok( lineBuffer, " \n\t,;" );
1667     if( the_token != NULL ){
1668    
1669     strcpy( info.nameA, the_token );
1670    
1671     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1672     sprintf( painCave.errMsg,
1673     "Error parseing TorsionTypes: line %d\n", lineNum );
1674     painCave.isFatal = 1;
1675     simError();
1676     }
1677    
1678     strcpy( info.nameB, the_token );
1679    
1680     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1681     sprintf( painCave.errMsg,
1682     "Error parseing TorsionTypes: line %d\n", lineNum );
1683     painCave.isFatal = 1;
1684     simError();
1685     }
1686    
1687     strcpy( info.nameC, the_token );
1688    
1689     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1690     sprintf( painCave.errMsg,
1691     "Error parseing TorsionTypes: line %d\n", lineNum );
1692     painCave.isFatal = 1;
1693     simError();
1694     }
1695    
1696     strcpy( info.nameD, the_token );
1697    
1698     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1699     sprintf( painCave.errMsg,
1700     "Error parseing TorsionTypes: line %d\n", lineNum );
1701     painCave.isFatal = 1;
1702     simError();
1703     }
1704    
1705     strcpy( info.type, the_token );
1706    
1707     if( !strcmp( info.type, "cubic" ) ){
1708     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1709     sprintf( painCave.errMsg,
1710     "Error parseing TorsionTypes: line %d\n", lineNum );
1711     painCave.isFatal = 1;
1712     simError();
1713     }
1714    
1715     info.k1 = atof( the_token );
1716    
1717     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1718     sprintf( painCave.errMsg,
1719     "Error parseing TorsionTypes: line %d\n", lineNum );
1720     painCave.isFatal = 1;
1721     simError();
1722     }
1723    
1724     info.k2 = atof( the_token );
1725    
1726     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1727     sprintf( painCave.errMsg,
1728     "Error parseing TorsionTypes: line %d\n", lineNum );
1729     painCave.isFatal = 1;
1730     simError();
1731     }
1732    
1733     info.k3 = atof( the_token );
1734    
1735     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
1736     sprintf( painCave.errMsg,
1737     "Error parseing TorsionTypes: line %d\n", lineNum );
1738     painCave.isFatal = 1;
1739     simError();
1740     }
1741    
1742     info.k4 = atof( the_token );
1743    
1744     }
1745    
1746     else{
1747     sprintf( painCave.errMsg,
1748     "Unknown TraPPE_Ex torsion type \"%s\" at line %d\n",
1749     info.type,
1750     lineNum );
1751     painCave.isFatal = 1;
1752     simError();
1753     }
1754    
1755     return 1;
1756     }
1757    
1758     else return 0;
1759     }