ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/EAM_FF.cpp
Revision: 499
Committed: Tue Apr 15 16:37:59 2003 UTC (21 years, 2 months ago) by chuckv
File size: 11894 byte(s)
Log Message:
More eam work.

File Contents

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