ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/mdtools/interface_implementation/LJ_FF.cpp
Revision: 238
Committed: Fri Jan 17 21:53:36 2003 UTC (21 years, 8 months ago) by mmeineke
File size: 13374 byte(s)
Log Message:
*** empty log message ***

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 mmeineke 238
381     int isError;
382     currentAtomType = headAtomType;
383     while( currentAtomType != NULL ){
384    
385     if( currentAtomType->name[0] != NULL ){
386     isError = 0;
387     newLJtype( &(currentAtomType->ident),
388     &(currentAtomType->mass),
389     &(currentAtomType->epslon),
390     &(currentAtomType->sigma),
391     isError );
392     if( isError ){
393     sprintf( painCave.errMsg,
394     "Error initializing the \"%s\" atom type in fortran\n",
395     currentAtomType->name );
396     painCave.isFatal = 1;
397     simError();
398     }
399     }
400     currentAtomType = currentAtomType->next;
401     }
402    
403     #ifdef IS_MPI
404     sprintf( checkPointMsg,
405     "LJ_FF atom structures successfully sent to fortran\n" );
406     MPIcheckPoint();
407     #endif // is_mpi
408 chuckv 230
409 mmeineke 238
410 chuckv 230
411 chuckv 215 // initialize the atoms
412    
413     Atom* thisAtom;
414    
415     for( i=0; i<nAtoms; i++ ){
416    
417     currentAtomType = headAtomType->find( the_atoms[i]->getType() );
418     if( currentAtomType == NULL ){
419     sprintf( painCave.errMsg,
420     "AtomType error, %s not found in force file.\n",
421     the_atoms[i]->getType() );
422     painCave.isFatal = 1;
423     simError();
424     }
425    
426     the_atoms[i]->setMass( currentAtomType->mass );
427     the_atoms[i]->setEpslon( currentAtomType->epslon );
428     the_atoms[i]->setSigma( currentAtomType->sigma );
429 mmeineke 224 the_atoms[i]->setIdent( currentAtomType->ident );
430 chuckv 215 the_atoms[i]->setLJ();
431     }
432    
433    
434     // clean up the memory
435    
436     delete headAtomType;
437    
438     #ifdef IS_MPI
439     sprintf( checkPointMsg, "LJ_FF atoms initialized succesfully" );
440     MPIcheckPoint();
441     #endif // is_mpi
442    
443     }
444    
445     void LJ_FF::initializeBonds( bond_pair* the_bonds ){
446    
447     if( entry_plug->n_bonds ){
448     sprintf( painCave.errMsg,
449     "LJ_FF does not support bonds.\n" );
450     painCave.isFatal = 1;
451     simError();
452     }
453     #ifdef IS_MPI
454     MPIcheckPoint();
455     #endif // is_mpi
456    
457     }
458    
459     void LJ_FF::initializeBends( bend_set* the_bends ){
460    
461     if( entry_plug->n_bends ){
462     sprintf( painCave.errMsg,
463     "LJ_FF does not support bends.\n" );
464     painCave.isFatal = 1;
465     simError();
466     }
467     #ifdef IS_MPI
468     MPIcheckPoint();
469     #endif // is_mpi
470    
471     }
472    
473     void LJ_FF::initializeTorsions( torsion_set* the_torsions ){
474    
475     if( entry_plug->n_torsions ){
476     sprintf( painCave.errMsg,
477     "LJ_FF does not support torsions.\n" );
478     painCave.isFatal = 1;
479     simError();
480     }
481     #ifdef IS_MPI
482     MPIcheckPoint();
483     #endif // is_mpi
484    
485     }
486 mmeineke 224
487    
488     void LJ_FF::fastForward( char* stopText, char* searchOwner ){
489    
490     int foundText = 0;
491     char* the_token;
492    
493     rewind( frcFile );
494     lineNum = 0;
495    
496     eof_test = fgets( readLine, sizeof(readLine), frcFile );
497     lineNum++;
498     if( eof_test == NULL ){
499     sprintf( painCave.errMsg, "Error fast forwarding force file for %s: "
500     " file is empty.\n",
501     searchOwner );
502     painCave.isFatal = 1;
503     simError();
504     }
505    
506    
507     while( !foundText ){
508     while( eof_test != NULL && readLine[0] != '#' ){
509     eof_test = fgets( readLine, sizeof(readLine), frcFile );
510     lineNum++;
511     }
512     if( eof_test == NULL ){
513     sprintf( painCave.errMsg,
514     "Error fast forwarding force file for %s at "
515     "line %d: file ended unexpectedly.\n",
516     searchOwner,
517     lineNum );
518     painCave.isFatal = 1;
519     simError();
520     }
521    
522     the_token = strtok( readLine, " ,;\t#\n" );
523     foundText = !strcmp( stopText, the_token );
524    
525     if( !foundText ){
526     eof_test = fgets( readLine, sizeof(readLine), frcFile );
527     lineNum++;
528    
529     if( eof_test == NULL ){
530     sprintf( painCave.errMsg,
531     "Error fast forwarding force file for %s at "
532     "line %d: file ended unexpectedly.\n",
533     searchOwner,
534     lineNum );
535     painCave.isFatal = 1;
536     simError();
537     }
538     }
539     }
540     }
541    
542    
543    
544     int parseAtomLJ( char *lineBuffer, int lineNum, atomStruct &info ){
545    
546     char* the_token;
547    
548     the_token = strtok( lineBuffer, " \n\t,;" );
549     if( the_token != NULL ){
550    
551     strcpy( info.name, the_token );
552    
553     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
554     sprintf( painCave.errMsg,
555     "Error parseing AtomTypes: line %d\n", lineNum );
556     painCave.isFatal = 1;
557     simError();
558     }
559    
560     info.mass = atof( the_token );
561    
562     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
563     sprintf( painCave.errMsg,
564     "Error parseing AtomTypes: line %d\n", lineNum );
565     painCave.isFatal = 1;
566     simError();
567     }
568    
569     info.epslon = atof( the_token );
570    
571     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
572     sprintf( painCave.errMsg,
573     "Error parseing AtomTypes: line %d\n", lineNum );
574     painCave.isFatal = 1;
575     simError();
576     }
577    
578     info.sigma = atof( the_token );
579    
580     return 1;
581     }
582     else return 0;
583     }
584 mmeineke 238
585    
586     void LJ_FF::doForces( void ){
587    
588     int i;
589     double* frc;
590     double* pos;
591     double potE;
592     short int calcPot = 0;
593    
594     // forces are zeroed here, before any are acumulated.
595     // NOTE: do not rezero the forces in Fortran.
596    
597     for(i=0; i<entry_plug->n_atoms; i++){
598     entry_plug->atoms[i]->zeroForces();
599     }
600    
601     frc = Atom::getFrcArray();
602     pos = Atom::getPosArray();
603    
604     doLJfortran( pos, frc, potE, calcPot );
605     }
606