ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE_old/src/mdtools/libmdCode/TraPPE_ExFF.cpp
Revision: 362
Committed: Tue Mar 18 21:25:45 2003 UTC (21 years, 3 months ago) by mmeineke
File size: 41819 byte(s)
Log Message:
shed implementation of the Fortran interfaces.

File Contents

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