ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-1.0/libmdtools/DUFF.cpp
Revision: 1334
Committed: Fri Jul 16 18:58:03 2004 UTC (19 years, 11 months ago) by gezelter
File size: 43413 byte(s)
Log Message:
Initial import of OOPSE-1.0 source tree

File Contents

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