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

# Content
1 #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 }