ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/mdtools/interface_implementation/LJ_FF.cpp
Revision: 236
Committed: Mon Jan 13 22:06:21 2003 UTC (21 years, 5 months ago) by mmeineke
File size: 12279 byte(s)
Log Message:
this  completes the addition of fvortran function wrapping into the LJ_FF class.

File Contents

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