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

# 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
13 // Declare the structures that will be passed by the parser and MPI
14
15 typedef struct{
16 char name[15];
17 double mass;
18 double epslon;
19 double sigma;
20 int ident;
21 int last; // 0 -> default
22 // 1 -> in MPI: tells nodes to stop listening
23 } atomStruct;
24
25 int parseAtomLJ( char *lineBuffer, int lineNum, atomStruct &info );
26
27 #ifdef IS_MPI
28
29 #include "mpiForceField.h"
30
31 MPI_Datatype mpiAtomStructType;
32
33 #endif
34
35
36 // declaration of functions needed to wrap the fortran module
37
38 extern "C" {
39 void forcefactory_( char* forceName,
40 int* status,
41 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
54
55 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
62 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 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 // do the funtion wrapping
83 currentLJwrap = this;
84 wrapMe();
85
86 #ifdef IS_MPI
87 int i;
88
89 // **********************************************************************
90 // Init the atomStruct mpi type
91
92 atomStruct atomProto; // mpiPrototype
93 int atomBC[3] = {15,3,2}; // block counts
94 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 MPI_Address(&atomProto.ident, &atomDspls[2]);
100
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
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 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
238 void add( atomStruct &info ){
239
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 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 next->ident = info.ident;
259 }
260 }
261
262
263 #ifdef IS_MPI
264
265 void duplicate( atomStruct &info ){
266 strcpy(info.name, name);
267 info.mass = mass;
268 info.epslon = epslon;
269 info.sigma = sigma;
270 info.ident = ident;
271 info.last = 0;
272 }
273
274
275 #endif
276
277 char name[15];
278 double mass;
279 double epslon;
280 double sigma;
281 int ident;
282 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 int identNum;
293
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
306 headAtomType = new LinkedType;
307
308 fastFoward( "AtomTypes", "initializeAtoms" );
309
310 // we are now at the AtomTypes section.
311
312 eof_test = fgets( readLine, sizeof(readLine), frcFile );
313 lineNum++;
314
315
316 // read a line, and start parseing out the atom types
317
318 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 identNum = 1;
327 // stop reading at end of file, or at next section
328 while( readLine[0] != '#' && eof_test != NULL ){
329
330 // toss comment lines
331 if( readLine[0] != '!' ){
332
333 // 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 }
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 // call new A_types in fortran
380
381
382 // 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 the_atoms[i]->setIdent( currentAtomType->ident );
401 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
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 }