ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/LJ_FF.cpp
Revision: 377
Committed: Fri Mar 21 17:42:12 2003 UTC (21 years, 3 months ago) by mmeineke
Original Path: branches/mmeineke/OOPSE/libmdtools/LJ_FF.cpp
File size: 12520 byte(s)
Log Message:
New OOPSE Tree

File Contents

# User Rev Content
1 mmeineke 377 #include <cstdlib>
2     #include <cstdio>
3     #include <cstring>
4    
5     #include <iostream>
6     using namespace std;
7    
8     #ifdef IS_MPI
9     #include <mpi.h>
10     #include <mpi++.h>
11     #endif //is_mpi
12    
13     #include "ForceFields.hpp"
14     #include "SRI.hpp"
15     #include "simError.h"
16    
17     #include "fortranWrappers.hpp"
18    
19     #ifdef IS_MPI
20     #include "mpiForceField.h"
21     #endif // is_mpi
22    
23    
24    
25     namespace LJ_NS{
26    
27     // Declare the structures that will be passed by the parser and MPI
28    
29     typedef struct{
30     char name[15];
31     double mass;
32     double epslon;
33     double sigma;
34     int ident;
35     int last; // 0 -> default
36     // 1 -> in MPI: tells nodes to stop listening
37     } atomStruct;
38    
39     int parseAtom( char *lineBuffer, int lineNum, atomStruct &info );
40    
41     #ifdef IS_MPI
42    
43     MPI_Datatype mpiAtomStructType;
44    
45     #endif
46     }
47    
48     using namespace LJ_NS;
49    
50     //****************************************************************
51     // begins the actual forcefield stuff.
52     //****************************************************************
53    
54    
55     LJ_FF::LJ_FF(){
56    
57     char fileName[200];
58     char* ffPath_env = "FORCE_PARAM_PATH";
59     char* ffPath;
60     char temp[200];
61     char errMsg[1000];
62    
63     // do the funtion wrapping
64     wrapMeFF( this );
65    
66     #ifdef IS_MPI
67     int i;
68    
69     // **********************************************************************
70     // Init the atomStruct mpi type
71    
72     atomStruct atomProto; // mpiPrototype
73     int atomBC[3] = {15,3,2}; // block counts
74     MPI_Aint atomDspls[3]; // displacements
75     MPI_Datatype atomMbrTypes[3]; // member mpi types
76    
77     MPI_Address(&atomProto.name, &atomDspls[0]);
78     MPI_Address(&atomProto.mass, &atomDspls[1]);
79     MPI_Address(&atomProto.ident, &atomDspls[2]);
80    
81     atomMbrTypes[0] = MPI_CHAR;
82     atomMbrTypes[1] = MPI_DOUBLE;
83     atomMbrTypes[2] = MPI_INT;
84    
85     for (i=2; i >= 0; i--) atomDspls[i] -= atomDspls[0];
86    
87     MPI_Type_struct(3, atomBC, atomDspls, atomMbrTypes, &mpiAtomStructType);
88     MPI_Type_commit(&mpiAtomStructType);
89    
90     // ***********************************************************************
91    
92     if( worldRank == 0 ){
93     #endif
94    
95     // generate the force file name
96    
97     strcpy( fileName, "LJ_FF.frc" );
98     // fprintf( stderr,"Trying to open %s\n", fileName );
99    
100     // attempt to open the file in the current directory first.
101    
102     frcFile = fopen( fileName, "r" );
103    
104     if( frcFile == NULL ){
105    
106     // next see if the force path enviorment variable is set
107    
108     ffPath = getenv( ffPath_env );
109     if( ffPath == NULL ) {
110     STR_DEFINE(ffPath, FRC_PATH );
111     }
112    
113    
114     strcpy( temp, ffPath );
115     strcat( temp, "/" );
116     strcat( temp, fileName );
117     strcpy( fileName, temp );
118    
119     frcFile = fopen( fileName, "r" );
120    
121     if( frcFile == NULL ){
122    
123     sprintf( painCave.errMsg,
124     "Error opening the force field parameter file: %s\n"
125     "Have you tried setting the FORCE_PARAM_PATH environment "
126     "vairable?\n",
127     fileName );
128     painCave.isFatal = 1;
129     simError();
130     }
131     }
132    
133     #ifdef IS_MPI
134     }
135    
136     sprintf( checkPointMsg, "LJ_FF file opened sucessfully." );
137     MPIcheckPoint();
138    
139     #endif // is_mpi
140     }
141    
142    
143     LJ_FF::~LJ_FF(){
144    
145     #ifdef IS_MPI
146     if( worldRank == 0 ){
147     #endif // is_mpi
148    
149     fclose( frcFile );
150    
151     #ifdef IS_MPI
152     }
153     #endif // is_mpi
154     }
155    
156     void LJ_FF::initForceField( int ljMixRule ){
157    
158     initFortran( ljMixRule, 0 );
159     }
160    
161    
162     void LJ_FF::initializeAtoms( void ){
163    
164     class LinkedType {
165     public:
166     LinkedType(){
167     next = NULL;
168     name[0] = '\0';
169     }
170     ~LinkedType(){ if( next != NULL ) delete next; }
171    
172     LinkedType* find(char* key){
173     if( !strcmp(name, key) ) return this;
174     if( next != NULL ) return next->find(key);
175     return NULL;
176     }
177    
178    
179     void add( atomStruct &info ){
180    
181     // check for duplicates
182    
183     if( !strcmp( info.name, name ) ){
184     sprintf( painCave.errMsg,
185     "Duplicate LJ atom type \"%s\" found in "
186     "the LJ_FF param file./n",
187     name );
188     painCave.isFatal = 1;
189     simError();
190     }
191    
192     if( next != NULL ) next->add(info);
193     else{
194     next = new LinkedType();
195     strcpy(next->name, info.name);
196     next->mass = info.mass;
197     next->epslon = info.epslon;
198     next->sigma = info.sigma;
199     next->ident = info.ident;
200     }
201     }
202    
203    
204     #ifdef IS_MPI
205    
206     void duplicate( atomStruct &info ){
207     strcpy(info.name, name);
208     info.mass = mass;
209     info.epslon = epslon;
210     info.sigma = sigma;
211     info.ident = ident;
212     info.last = 0;
213     }
214    
215    
216     #endif
217    
218     char name[15];
219     double mass;
220     double epslon;
221     double sigma;
222     int ident;
223     LinkedType* next;
224     };
225    
226     LinkedType* headAtomType;
227     LinkedType* currentAtomType;
228     atomStruct info;
229     info.last = 1; // initialize last to have the last set.
230     // if things go well, last will be set to 0
231    
232     int i;
233     int identNum;
234    
235     Atom** the_atoms;
236     int nAtoms;
237     the_atoms = entry_plug->atoms;
238     nAtoms = entry_plug->n_atoms;
239    
240    
241     #ifdef IS_MPI
242     if( worldRank == 0 ){
243     #endif
244    
245     // read in the atom types.
246    
247     headAtomType = new LinkedType;
248    
249     fastForward( "AtomTypes", "initializeAtoms" );
250    
251     // we are now at the AtomTypes section.
252    
253     eof_test = fgets( readLine, sizeof(readLine), frcFile );
254     lineNum++;
255    
256    
257     // read a line, and start parseing out the atom types
258    
259     if( eof_test == NULL ){
260     sprintf( painCave.errMsg,
261     "Error in reading Atoms from force file at line %d.\n",
262     lineNum );
263     painCave.isFatal = 1;
264     simError();
265     }
266    
267     identNum = 1;
268     // stop reading at end of file, or at next section
269     while( readLine[0] != '#' && eof_test != NULL ){
270    
271     // toss comment lines
272     if( readLine[0] != '!' ){
273    
274     // the parser returns 0 if the line was blank
275     if( parseAtom( readLine, lineNum, info ) ){
276     info.ident = identNum;
277     headAtomType->add( info );;
278     identNum++;
279     }
280     }
281     eof_test = fgets( readLine, sizeof(readLine), frcFile );
282     lineNum++;
283     }
284    
285     #ifdef IS_MPI
286    
287     // send out the linked list to all the other processes
288    
289     sprintf( checkPointMsg,
290     "LJ_FF atom structures read successfully." );
291     MPIcheckPoint();
292    
293     currentAtomType = headAtomType->next; //skip the first element who is a place holder.
294     while( currentAtomType != NULL ){
295     currentAtomType->duplicate( info );
296    
297    
298    
299     sendFrcStruct( &info, mpiAtomStructType );
300    
301     sprintf( checkPointMsg,
302     "successfully sent lJ force type: \"%s\"\n",
303     info.name );
304     MPIcheckPoint();
305    
306     currentAtomType = currentAtomType->next;
307     }
308     info.last = 1;
309     sendFrcStruct( &info, mpiAtomStructType );
310    
311     }
312    
313     else{
314    
315     // listen for node 0 to send out the force params
316    
317     MPIcheckPoint();
318    
319     headAtomType = new LinkedType;
320     recieveFrcStruct( &info, mpiAtomStructType );
321    
322     while( !info.last ){
323    
324    
325    
326     headAtomType->add( info );
327    
328     MPIcheckPoint();
329    
330     recieveFrcStruct( &info, mpiAtomStructType );
331     }
332     }
333     #endif // is_mpi
334    
335     // call new A_types in fortran
336    
337     int isError;
338    
339     // dummy variables
340     int isLJ = 1;
341     int isDipole = 0;
342     int isSSD = 0;
343     int isGB = 0;
344     double w0 = 0.0;
345     double v0 = 0.0;
346     double dipole = 0.0;
347     double GB_dummy = 0.0;
348    
349    
350     currentAtomType = headAtomType;
351     while( currentAtomType != NULL ){
352    
353     if( currentAtomType->name[0] != '\0' ){
354     isError = 0;
355     makeAtype( &(currentAtomType->ident),
356     &isLJ,
357     &isSSD,
358     &isDipole,
359     &isGB,
360     &(currentAtomType->epslon),
361     &(currentAtomType->sigma),
362     &dipole,
363     &w0,
364     &v0,
365     &GB_dummy,
366     &GB_dummy,
367     &GB_dummy,
368     &GB_dummy,
369     &GB_dummy,
370     &GB_dummy,
371     &isError );
372     if( isError ){
373     sprintf( painCave.errMsg,
374     "Error initializing the \"%s\" atom type in fortran\n",
375     currentAtomType->name );
376     painCave.isFatal = 1;
377     simError();
378     }
379     }
380     currentAtomType = currentAtomType->next;
381     }
382    
383     #ifdef IS_MPI
384     sprintf( checkPointMsg,
385     "LJ_FF atom structures successfully sent to fortran\n" );
386     MPIcheckPoint();
387     #endif // is_mpi
388    
389    
390    
391     // initialize the atoms
392    
393     double bigSigma = 0.0;
394     Atom* thisAtom;
395    
396     for( i=0; i<nAtoms; i++ ){
397    
398     currentAtomType = headAtomType->find( the_atoms[i]->getType() );
399     if( currentAtomType == NULL ){
400     sprintf( painCave.errMsg,
401     "AtomType error, %s not found in force file.\n",
402     the_atoms[i]->getType() );
403     painCave.isFatal = 1;
404     simError();
405     }
406    
407     the_atoms[i]->setMass( currentAtomType->mass );
408     the_atoms[i]->setEpslon( currentAtomType->epslon );
409     the_atoms[i]->setSigma( currentAtomType->sigma );
410     the_atoms[i]->setIdent( currentAtomType->ident );
411     the_atoms[i]->setLJ();
412    
413     if( bigSigma < currentAtomType->sigma ) bigSigma = currentAtomType->sigma;
414     }
415    
416    
417     #ifdef IS_MPI
418     double tempBig = bigSigma;
419     MPI::COMM_WORLD.Allreduce( &tempBig, &bigSigma, 1, MPI_DOUBLE, MPI_MAX );
420     #endif //is_mpi
421    
422     //calc rCut and rList
423    
424     entry_plug->rCut = 2.5 * bigSigma;
425     if(entry_plug->rCut > (entry_plug->box_x / 2.0))
426     entry_plug->rCut = entry_plug->box_x / 2.0;
427     if(entry_plug->rCut > (entry_plug->box_y / 2.0))
428     entry_plug->rCut = entry_plug->box_y / 2.0;
429     if(entry_plug->rCut > (entry_plug->box_z / 2.0))
430     entry_plug->rCut = entry_plug->box_z / 2.0;
431    
432     entry_plug->rList = entry_plug->rCut + 1.0;
433    
434     entry_plug->useLJ = 1;
435    
436     // clean up the memory
437    
438     delete headAtomType;
439    
440     #ifdef IS_MPI
441     sprintf( checkPointMsg, "LJ_FF atoms initialized succesfully" );
442     MPIcheckPoint();
443     #endif // is_mpi
444    
445     }
446    
447     void LJ_FF::initializeBonds( bond_pair* the_bonds ){
448    
449     if( entry_plug->n_bonds ){
450     sprintf( painCave.errMsg,
451     "LJ_FF does not support bonds.\n" );
452     painCave.isFatal = 1;
453     simError();
454     }
455     #ifdef IS_MPI
456     MPIcheckPoint();
457     #endif // is_mpi
458    
459     }
460    
461     void LJ_FF::initializeBends( bend_set* the_bends ){
462    
463     if( entry_plug->n_bends ){
464     sprintf( painCave.errMsg,
465     "LJ_FF does not support bends.\n" );
466     painCave.isFatal = 1;
467     simError();
468     }
469     #ifdef IS_MPI
470     MPIcheckPoint();
471     #endif // is_mpi
472    
473     }
474    
475     void LJ_FF::initializeTorsions( torsion_set* the_torsions ){
476    
477     if( entry_plug->n_torsions ){
478     sprintf( painCave.errMsg,
479     "LJ_FF does not support torsions.\n" );
480     painCave.isFatal = 1;
481     simError();
482     }
483     #ifdef IS_MPI
484     MPIcheckPoint();
485     #endif // is_mpi
486    
487     }
488    
489     void LJ_FF::fastForward( char* stopText, char* searchOwner ){
490    
491     int foundText = 0;
492     char* the_token;
493    
494     rewind( frcFile );
495     lineNum = 0;
496    
497     eof_test = fgets( readLine, sizeof(readLine), frcFile );
498     lineNum++;
499     if( eof_test == NULL ){
500     sprintf( painCave.errMsg, "Error fast forwarding force file for %s: "
501     " file is empty.\n",
502     searchOwner );
503     painCave.isFatal = 1;
504     simError();
505     }
506    
507    
508     while( !foundText ){
509     while( eof_test != NULL && readLine[0] != '#' ){
510     eof_test = fgets( readLine, sizeof(readLine), frcFile );
511     lineNum++;
512     }
513     if( eof_test == NULL ){
514     sprintf( painCave.errMsg,
515     "Error fast forwarding force file for %s at "
516     "line %d: file ended unexpectedly.\n",
517     searchOwner,
518     lineNum );
519     painCave.isFatal = 1;
520     simError();
521     }
522    
523     the_token = strtok( readLine, " ,;\t#\n" );
524     foundText = !strcmp( stopText, the_token );
525    
526     if( !foundText ){
527     eof_test = fgets( readLine, sizeof(readLine), frcFile );
528     lineNum++;
529    
530     if( eof_test == NULL ){
531     sprintf( painCave.errMsg,
532     "Error fast forwarding force file for %s at "
533     "line %d: file ended unexpectedly.\n",
534     searchOwner,
535     lineNum );
536     painCave.isFatal = 1;
537     simError();
538     }
539     }
540     }
541     }
542    
543    
544    
545     int LJ_NS::parseAtom( char *lineBuffer, int lineNum, atomStruct &info ){
546    
547     char* the_token;
548    
549     the_token = strtok( lineBuffer, " \n\t,;" );
550     if( the_token != NULL ){
551    
552     strcpy( info.name, the_token );
553    
554     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
555     sprintf( painCave.errMsg,
556     "Error parseing AtomTypes: line %d\n", lineNum );
557     painCave.isFatal = 1;
558     simError();
559     }
560    
561     info.mass = atof( the_token );
562    
563     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
564     sprintf( painCave.errMsg,
565     "Error parseing AtomTypes: line %d\n", lineNum );
566     painCave.isFatal = 1;
567     simError();
568     }
569    
570     info.epslon = atof( the_token );
571    
572     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
573     sprintf( painCave.errMsg,
574     "Error parseing AtomTypes: line %d\n", lineNum );
575     painCave.isFatal = 1;
576     simError();
577     }
578    
579     info.sigma = atof( the_token );
580    
581     return 1;
582     }
583     else return 0;
584     }