ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/EAM_FF.cpp
Revision: 1261
Committed: Fri Jun 11 14:14:10 2004 UTC (20 years ago) by gezelter
File size: 26522 byte(s)
Log Message:
Modified EAM to use forceFieldVariant

File Contents

# User Rev Content
1 gezelter 829 #include <stdlib.h>
2     #include <stdio.h>
3     #include <string.h>
4 chuckv 499
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 chuckv 627 double lattice_constant;
32     double eam_drho; // The distance between each of the points indexed by rho.
33 mmeineke 814 double eam_rcut; // The cutoff radius for eam.
34 chuckv 627 double eam_dr; // The distance between each of the rho points.
35     int eam_nrho; // Number of points indexed by rho
36     int eam_nr; // The number of points based on r (Both Phi(r) and Rho(r)).
37     int eam_ident; // Atomic number
38 chuckv 499 int ident;
39     int last; // 0 -> default
40     // 1 -> in MPI: tells nodes to stop listening
41     } atomStruct;
42    
43 chuckv 627 int parseAtom( char *lineBuffer, int lineNum, atomStruct &info, char *eamPotFile );
44 chuckv 631 int parseEAM( atomStruct &info, char *eamPotFile, double **eam_rvals,
45     double **eam_rhovals, double **eam_Frhovals);
46 chuckv 499 #ifdef IS_MPI
47    
48     MPI_Datatype mpiAtomStructType;
49    
50     #endif
51    
52     class LinkedAtomType {
53     public:
54     LinkedAtomType(){
55     next = NULL;
56     name[0] = '\0';
57 chuckv 627 eam_rvals = NULL;
58     eam_rhovals = NULL;
59     eam_Frhovals = NULL;
60 chuckv 499 }
61    
62 chuckv 627 ~LinkedAtomType(){
63     if( next != NULL ) delete next;
64     if( eam_rvals != NULL ) delete[] eam_rvals;
65     if( eam_rhovals != NULL ) delete[] eam_rhovals;
66     if( eam_Frhovals != NULL ) delete[] eam_Frhovals;
67     }
68    
69 chuckv 499 LinkedAtomType* find(char* key){
70     if( !strcmp(name, key) ) return this;
71     if( next != NULL ) return next->find(key);
72     return NULL;
73     }
74    
75    
76 chuckv 627 void add( atomStruct &info, double *the_eam_rvals,
77     double *the_eam_rhovals,double *the_eam_Frhovals ){
78    
79 chuckv 499 // check for duplicates
80    
81     if( !strcmp( info.name, name ) ){
82     sprintf( painCave.errMsg,
83 gezelter 1261 "Duplicate EAM atom type \"%s\" found in "
84     "the EAM_FF param file./n",
85 chuckv 499 name );
86     painCave.isFatal = 1;
87     simError();
88     }
89    
90 chuckv 627 if( next != NULL ) next->add(info, the_eam_rvals, the_eam_rhovals, the_eam_Frhovals);
91 chuckv 499 else{
92     next = new LinkedAtomType();
93     strcpy(next->name, info.name);
94 chuckv 627 next->mass = info.mass;
95     next->lattice_constant = info.lattice_constant;
96     next->eam_nrho = info.eam_nrho;
97     next->eam_drho = info.eam_drho;
98     next->eam_nr = info.eam_nr;
99     next->eam_dr = info.eam_dr;
100     next->eam_rcut = info.eam_rcut;
101     next->eam_ident = info.eam_ident;
102     next->ident = info.ident;
103    
104     next->eam_rvals = the_eam_rvals;
105     next->eam_rhovals = the_eam_rhovals;
106     next->eam_Frhovals = the_eam_Frhovals;
107 chuckv 499 }
108     }
109    
110    
111     #ifdef IS_MPI
112    
113     void duplicate( atomStruct &info ){
114     strcpy(info.name, name);
115 chuckv 627 info.mass = mass;
116     info.lattice_constant = lattice_constant;
117     info.eam_nrho = eam_nrho;
118     info.eam_drho = eam_drho;
119     info.eam_nr = eam_nr;
120     info.eam_dr = eam_dr;
121     info.eam_rcut = eam_rcut;
122     info.eam_ident = eam_ident;
123     info.ident = ident;
124     info.last = 0;
125 chuckv 499 }
126    
127    
128     #endif
129    
130     char name[15];
131     double mass;
132 chuckv 627 double lattice_constant;
133     int eam_nrho; // Number of points indexed by rho
134     double eam_drho; // The distance between each of the points indexed by rho.
135     int eam_nr; // The number of points based on r (Both Phi(r) and Rho(r)).
136     double eam_dr; // The distance between each of the rho points.
137 chuckv 631 double eam_rcut; // The cutoff radius for eam.
138 chuckv 627
139     double *eam_rvals; // Z of r values
140     double *eam_rhovals; // rho of r values
141     double *eam_Frhovals; // F of rho values
142     int eam_ident; // eam identity (atomic number)
143 chuckv 499 int ident;
144     LinkedAtomType* next;
145     };
146    
147     LinkedAtomType* headAtomType;
148     LinkedAtomType* currentAtomType;
149    
150     }
151    
152 chuckv 631 using namespace EAM_NS;
153 chuckv 499
154     //****************************************************************
155     // begins the actual forcefield stuff.
156     //****************************************************************
157    
158 gezelter 1261 EAM_FF::EAM_FF() {
159     EAM_FF("");
160     }
161 chuckv 499
162 gezelter 1261 EAM_FF::EAM_FF(char* the_variant){
163 chuckv 499
164     char fileName[200];
165     char* ffPath_env = "FORCE_PARAM_PATH";
166     char* ffPath;
167     char temp[200];
168    
169     headAtomType = NULL;
170     currentAtomType = NULL;
171    
172 chuckv 669 // Set eamRcut to 0.0
173     eamRcut = 0.0;
174    
175 chuckv 499 // do the funtion wrapping
176     wrapMeFF( this );
177    
178     #ifdef IS_MPI
179     int i;
180    
181     // **********************************************************************
182     // Init the atomStruct mpi type
183    
184     atomStruct atomProto; // mpiPrototype
185 mmeineke 814 int atomBC[3] = {15,5,5}; // block counts
186 chuckv 499 MPI_Aint atomDspls[3]; // displacements
187     MPI_Datatype atomMbrTypes[3]; // member mpi types
188    
189     MPI_Address(&atomProto.name, &atomDspls[0]);
190     MPI_Address(&atomProto.mass, &atomDspls[1]);
191 chuckv 627 MPI_Address(&atomProto.eam_nrho, &atomDspls[2]);
192 chuckv 499
193     atomMbrTypes[0] = MPI_CHAR;
194     atomMbrTypes[1] = MPI_DOUBLE;
195     atomMbrTypes[2] = MPI_INT;
196    
197     for (i=2; i >= 0; i--) atomDspls[i] -= atomDspls[0];
198    
199     MPI_Type_struct(3, atomBC, atomDspls, atomMbrTypes, &mpiAtomStructType);
200     MPI_Type_commit(&mpiAtomStructType);
201    
202     // ***********************************************************************
203    
204     if( worldRank == 0 ){
205     #endif
206    
207 gezelter 1261 // generate the force file name
208    
209     strcpy( fileName, "EAM" );
210    
211     if (strlen(the_variant) > 0) {
212     has_variant = 1;
213     strcpy( variant, the_variant);
214     strcat( fileName, ".");
215     strcat( fileName, variant );
216    
217     sprintf( painCave.errMsg,
218     "Using %s variant of EAM force field.\n",
219     variant );
220     painCave.severity = OOPSE_INFO;
221     painCave.isFatal = 0;
222     simError();
223     }
224     strcat( fileName, ".frc");
225    
226     //fprintf( stderr,"Trying to open %s\n", fileName );
227 chuckv 499
228     // attempt to open the file in the current directory first.
229    
230     frcFile = fopen( fileName, "r" );
231    
232     if( frcFile == NULL ){
233    
234     // next see if the force path enviorment variable is set
235    
236     ffPath = getenv( ffPath_env );
237     if( ffPath == NULL ) {
238     STR_DEFINE(ffPath, FRC_PATH );
239     }
240    
241    
242     strcpy( temp, ffPath );
243     strcat( temp, "/" );
244     strcat( temp, fileName );
245     strcpy( fileName, temp );
246    
247     frcFile = fopen( fileName, "r" );
248    
249     if( frcFile == NULL ){
250 gezelter 1261
251 chuckv 499 sprintf( painCave.errMsg,
252 gezelter 1224 "Error opening the force field parameter file:\n"
253     "\t%s\n"
254     "\tHave you tried setting the FORCE_PARAM_PATH environment "
255     "variable?\n",
256 chuckv 499 fileName );
257 gezelter 1224 painCave.severity = OOPSE_ERROR;
258 chuckv 499 painCave.isFatal = 1;
259     simError();
260     }
261     }
262 gezelter 1261
263 chuckv 499
264     #ifdef IS_MPI
265     }
266    
267 chuckv 627 sprintf( checkPointMsg, "EAM_FF file opened sucessfully." );
268 chuckv 499 MPIcheckPoint();
269    
270     #endif // is_mpi
271     }
272    
273    
274     EAM_FF::~EAM_FF(){
275    
276     if( headAtomType != NULL ) delete headAtomType;
277    
278     #ifdef IS_MPI
279     if( worldRank == 0 ){
280     #endif // is_mpi
281    
282     fclose( frcFile );
283    
284     #ifdef IS_MPI
285     }
286     #endif // is_mpi
287     }
288    
289 chuckv 657
290     void EAM_FF::calcRcut( void ){
291 chuckv 669
292 tim 952 #ifdef IS_MPI
293 chuckv 669 double tempEamRcut = eamRcut;
294     MPI_Allreduce( &tempEamRcut, &eamRcut, 1, MPI_DOUBLE, MPI_MAX,
295     MPI_COMM_WORLD);
296     #endif //is_mpi
297 mmeineke 859 entry_plug->setDefaultRcut(eamRcut);
298 chuckv 657 }
299    
300    
301 chuckv 499 void EAM_FF::initForceField( int ljMixRule ){
302     initFortran( ljMixRule, 0 );
303     }
304    
305     void EAM_FF::cleanMe( void ){
306    
307     #ifdef IS_MPI
308    
309     // keep the linked list in the mpi version
310    
311     #else // is_mpi
312    
313     // delete the linked list in the single processor version
314    
315     if( headAtomType != NULL ) delete headAtomType;
316    
317     #endif // is_mpi
318     }
319    
320 chuckv 657
321 chuckv 499 void EAM_FF::readParams( void ){
322    
323     atomStruct info;
324     info.last = 1; // initialize last to have the last set.
325     // if things go well, last will be set to 0
326    
327     int identNum;
328 chuckv 627 double *eam_rvals; // Z of r values
329     double *eam_rhovals; // rho of r values
330     double *eam_Frhovals; // F of rho values
331     char eamPotFile[1000];
332 chuckv 499
333    
334     bigSigma = 0.0;
335     #ifdef IS_MPI
336     if( worldRank == 0 ){
337     #endif
338    
339     // read in the atom types.
340    
341     headAtomType = new LinkedAtomType;
342 gezelter 1261
343 chuckv 627 fastForward( "AtomTypes", "eam atom readParams" );
344 chuckv 499
345     // we are now at the AtomTypes section.
346    
347     eof_test = fgets( readLine, sizeof(readLine), frcFile );
348     lineNum++;
349    
350    
351     // read a line, and start parseing out the atom types
352    
353     if( eof_test == NULL ){
354     sprintf( painCave.errMsg,
355     "Error in reading Atoms from force file at line %d.\n",
356     lineNum );
357     painCave.isFatal = 1;
358     simError();
359     }
360    
361     identNum = 1;
362     // stop reading at end of file, or at next section
363 chuckv 627
364 chuckv 499 while( readLine[0] != '#' && eof_test != NULL ){
365    
366     // toss comment lines
367     if( readLine[0] != '!' ){
368    
369     // the parser returns 0 if the line was blank
370 chuckv 627 if( parseAtom( readLine, lineNum, info, eamPotFile ) ){
371     parseEAM(info,eamPotFile, &eam_rvals,
372 chuckv 631 &eam_rhovals, &eam_Frhovals);
373 chuckv 499 info.ident = identNum;
374 chuckv 627 headAtomType->add( info, eam_rvals,
375     eam_rhovals,eam_Frhovals );
376 chuckv 499 identNum++;
377     }
378     }
379     eof_test = fgets( readLine, sizeof(readLine), frcFile );
380     lineNum++;
381     }
382 chuckv 627
383    
384 chuckv 499
385     #ifdef IS_MPI
386 chuckv 627
387 chuckv 499
388     // send out the linked list to all the other processes
389    
390     sprintf( checkPointMsg,
391 chuckv 627 "EAM_FF atom structures read successfully." );
392 chuckv 499 MPIcheckPoint();
393    
394     currentAtomType = headAtomType->next; //skip the first element who is a place holder.
395     while( currentAtomType != NULL ){
396     currentAtomType->duplicate( info );
397    
398    
399    
400     sendFrcStruct( &info, mpiAtomStructType );
401    
402 chuckv 627 // We have to now broadcast the Arrays
403     MPI_Bcast(currentAtomType->eam_rvals,
404     currentAtomType->eam_nr,
405     MPI_DOUBLE,0,MPI_COMM_WORLD);
406     MPI_Bcast(currentAtomType->eam_rhovals,
407     currentAtomType->eam_nr,
408     MPI_DOUBLE,0,MPI_COMM_WORLD);
409     MPI_Bcast(currentAtomType->eam_Frhovals,
410     currentAtomType->eam_nrho,
411     MPI_DOUBLE,0,MPI_COMM_WORLD);
412    
413 chuckv 499 sprintf( checkPointMsg,
414 chuckv 627 "successfully sent EAM force type: \"%s\"\n",
415 chuckv 499 info.name );
416     MPIcheckPoint();
417    
418     currentAtomType = currentAtomType->next;
419     }
420     info.last = 1;
421     sendFrcStruct( &info, mpiAtomStructType );
422    
423     }
424    
425     else{
426    
427     // listen for node 0 to send out the force params
428    
429     MPIcheckPoint();
430    
431     headAtomType = new LinkedAtomType;
432 chrisfen 976 receiveFrcStruct( &info, mpiAtomStructType );
433 chuckv 627
434 chuckv 499 while( !info.last ){
435 chuckv 627
436     // allocate the arrays
437 chuckv 499
438 chuckv 627 eam_rvals = new double[info.eam_nr];
439     eam_rhovals = new double[info.eam_nr];
440     eam_Frhovals = new double[info.eam_nrho];
441 chuckv 499
442 chuckv 627 // We have to now broadcast the Arrays
443     MPI_Bcast(eam_rvals,
444     info.eam_nr,
445     MPI_DOUBLE,0,MPI_COMM_WORLD);
446     MPI_Bcast(eam_rhovals,
447     info.eam_nr,
448     MPI_DOUBLE,0,MPI_COMM_WORLD);
449     MPI_Bcast(eam_Frhovals,
450     info.eam_nrho,
451     MPI_DOUBLE,0,MPI_COMM_WORLD);
452    
453 chuckv 499
454 chuckv 627 headAtomType->add( info, eam_rvals, eam_rhovals, eam_Frhovals );
455 chuckv 499
456     MPIcheckPoint();
457    
458 chrisfen 976 receiveFrcStruct( &info, mpiAtomStructType );
459 chuckv 627
460    
461 chuckv 499 }
462     }
463     #endif // is_mpi
464    
465     // call new A_types in fortran
466    
467     int isError;
468    
469     // dummy variables
470 chuckv 627 int isLJ = 0;
471 chuckv 499 int isDipole = 0;
472     int isSSD = 0;
473     int isGB = 0;
474 gezelter 941 int isEAM = 1;
475     int isCharge = 0;
476 chuckv 499 double dipole = 0.0;
477 gezelter 941 double charge = 0.0;
478 chuckv 631 double eamSigma = 0.0;
479     double eamEpslon = 0.0;
480 chuckv 499
481 chuckv 627 currentAtomType = headAtomType->next;
482 chuckv 499 while( currentAtomType != NULL ){
483    
484     if( currentAtomType->name[0] != '\0' ){
485     isError = 0;
486     makeAtype( &(currentAtomType->ident),
487     &isLJ,
488     &isSSD,
489     &isDipole,
490     &isGB,
491 chuckv 627 &isEAM,
492 gezelter 941 &isCharge,
493 chuckv 631 &eamEpslon,
494     &eamSigma,
495 gezelter 941 &charge,
496 chuckv 499 &dipole,
497     &isError );
498     if( isError ){
499     sprintf( painCave.errMsg,
500     "Error initializing the \"%s\" atom type in fortran\n",
501     currentAtomType->name );
502     painCave.isFatal = 1;
503     simError();
504     }
505     }
506     currentAtomType = currentAtomType->next;
507     }
508    
509 chuckv 627 entry_plug->useLJ = 0;
510 chuckv 669 entry_plug->useEAM = 1;
511 chuckv 627 // Walk down again and send out EAM type
512     currentAtomType = headAtomType->next;
513     while( currentAtomType != NULL ){
514    
515     if( currentAtomType->name[0] != '\0' ){
516     isError = 0;
517 chuckv 669
518 chuckv 627 newEAMtype( &(currentAtomType->lattice_constant),
519     &(currentAtomType->eam_nrho),
520     &(currentAtomType->eam_drho),
521     &(currentAtomType->eam_nr),
522     &(currentAtomType->eam_dr),
523 chuckv 631 &(currentAtomType->eam_rcut),
524 chuckv 627 currentAtomType->eam_rvals,
525     currentAtomType->eam_rhovals,
526     currentAtomType->eam_Frhovals,
527     &(currentAtomType->eam_ident),
528     &isError);
529 chuckv 669
530 chuckv 627 if( isError ){
531     sprintf( painCave.errMsg,
532     "Error initializing the \"%s\" atom type in fortran EAM\n",
533     currentAtomType->name );
534     painCave.isFatal = 1;
535     simError();
536     }
537     }
538     currentAtomType = currentAtomType->next;
539     }
540    
541    
542    
543 chuckv 499 #ifdef IS_MPI
544     sprintf( checkPointMsg,
545 chuckv 627 "EAM_FF atom structures successfully sent to fortran\n" );
546 chuckv 499 MPIcheckPoint();
547     #endif // is_mpi
548    
549 chuckv 657
550 chuckv 669
551 chuckv 499 }
552    
553    
554     void EAM_FF::initializeAtoms( int nAtoms, Atom** the_atoms ){
555    
556     int i;
557 chuckv 669
558 chuckv 499 // initialize the atoms
559    
560     for( i=0; i<nAtoms; i++ ){
561    
562     currentAtomType = headAtomType->find( the_atoms[i]->getType() );
563     if( currentAtomType == NULL ){
564     sprintf( painCave.errMsg,
565     "AtomType error, %s not found in force file.\n",
566     the_atoms[i]->getType() );
567     painCave.isFatal = 1;
568     simError();
569     }
570    
571     the_atoms[i]->setMass( currentAtomType->mass );
572     the_atoms[i]->setIdent( currentAtomType->ident );
573    
574 chuckv 669 if (eamRcut < currentAtomType->eam_rcut) eamRcut = currentAtomType->eam_rcut;
575 gezelter 1097
576 chuckv 499 }
577     }
578    
579 chuckv 631 void EAM_FF::initializeBonds( int nBonds, Bond** BondArray,
580 chuckv 499 bond_pair* the_bonds ){
581    
582     if( nBonds ){
583     sprintf( painCave.errMsg,
584     "LJ_FF does not support bonds.\n" );
585     painCave.isFatal = 1;
586     simError();
587     }
588     }
589    
590     void EAM_FF::initializeBends( int nBends, Bend** bendArray,
591     bend_set* the_bends ){
592    
593     if( nBends ){
594     sprintf( painCave.errMsg,
595     "LJ_FF does not support bends.\n" );
596     painCave.isFatal = 1;
597     simError();
598     }
599     }
600    
601     void EAM_FF::initializeTorsions( int nTorsions, Torsion** torsionArray,
602     torsion_set* the_torsions ){
603    
604     if( nTorsions ){
605     sprintf( painCave.errMsg,
606     "LJ_FF does not support torsions.\n" );
607     painCave.isFatal = 1;
608     simError();
609     }
610     }
611    
612     void EAM_FF::fastForward( char* stopText, char* searchOwner ){
613    
614     int foundText = 0;
615     char* the_token;
616    
617     rewind( frcFile );
618     lineNum = 0;
619    
620     eof_test = fgets( readLine, sizeof(readLine), frcFile );
621     lineNum++;
622     if( eof_test == NULL ){
623     sprintf( painCave.errMsg, "Error fast forwarding force file for %s: "
624     " file is empty.\n",
625     searchOwner );
626     painCave.isFatal = 1;
627     simError();
628     }
629    
630    
631     while( !foundText ){
632     while( eof_test != NULL && readLine[0] != '#' ){
633     eof_test = fgets( readLine, sizeof(readLine), frcFile );
634     lineNum++;
635     }
636     if( eof_test == NULL ){
637     sprintf( painCave.errMsg,
638     "Error fast forwarding force file for %s at "
639     "line %d: file ended unexpectedly.\n",
640     searchOwner,
641     lineNum );
642     painCave.isFatal = 1;
643     simError();
644     }
645    
646     the_token = strtok( readLine, " ,;\t#\n" );
647     foundText = !strcmp( stopText, the_token );
648    
649     if( !foundText ){
650     eof_test = fgets( readLine, sizeof(readLine), frcFile );
651     lineNum++;
652    
653     if( eof_test == NULL ){
654     sprintf( painCave.errMsg,
655     "Error fast forwarding force file for %s at "
656     "line %d: file ended unexpectedly.\n",
657     searchOwner,
658     lineNum );
659     painCave.isFatal = 1;
660     simError();
661     }
662     }
663     }
664     }
665    
666    
667    
668 chuckv 627 int EAM_NS::parseAtom( char *lineBuffer, int lineNum, atomStruct &info, char *eamPotFile ){
669 chuckv 499
670     char* the_token;
671    
672     the_token = strtok( lineBuffer, " \n\t,;" );
673     if( the_token != NULL ){
674    
675     strcpy( info.name, the_token );
676    
677     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
678     sprintf( painCave.errMsg,
679     "Error parseing AtomTypes: line %d\n", lineNum );
680     painCave.isFatal = 1;
681     simError();
682     }
683    
684     info.mass = atof( the_token );
685    
686     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
687     sprintf( painCave.errMsg,
688     "Error parseing AtomTypes: line %d\n", lineNum );
689     painCave.isFatal = 1;
690     simError();
691     }
692    
693 chuckv 627 strcpy( eamPotFile, the_token );
694     return 1;
695     }
696     else return 0;
697     }
698    
699     int EAM_NS::parseEAM(atomStruct &info, char *eamPotFile,
700     double **eam_rvals,
701     double **eam_rhovals,
702     double **eam_Frhovals){
703 chuckv 657 double* myEam_rvals;
704     double* myEam_rhovals;
705     double* myEam_Frhovals;
706    
707 chuckv 627 char* ffPath_env = "FORCE_PARAM_PATH";
708     char* ffPath;
709     char* the_token;
710 chuckv 631 char* eam_eof_test;
711 chuckv 627 FILE *eamFile;
712 chuckv 657 const int BUFFERSIZE = 3000;
713 chuckv 631
714 chuckv 627 char temp[200];
715     int linenumber;
716     int nReadLines;
717 chuckv 631 char eam_read_buffer[BUFFERSIZE];
718 chuckv 627
719 chuckv 657
720 chuckv 627 int i,j;
721    
722     linenumber = 0;
723    
724     // Open eam file
725     eamFile = fopen( eamPotFile, "r" );
726    
727    
728 chuckv 631 if( eamFile == NULL ){
729 chuckv 627
730     // next see if the force path enviorment variable is set
731    
732     ffPath = getenv( ffPath_env );
733     if( ffPath == NULL ) {
734     STR_DEFINE(ffPath, FRC_PATH );
735     }
736    
737    
738     strcpy( temp, ffPath );
739     strcat( temp, "/" );
740     strcat( temp, eamPotFile );
741     strcpy( eamPotFile, temp );
742    
743     eamFile = fopen( eamPotFile, "r" );
744    
745    
746    
747 chuckv 631 if( eamFile == NULL ){
748 chuckv 627
749     sprintf( painCave.errMsg,
750     "Error opening the EAM force parameter file: %s\n"
751     "Have you tried setting the FORCE_PARAM_PATH environment "
752 gezelter 1224 "variable?\n",
753 chuckv 627 eamPotFile );
754     painCave.isFatal = 1;
755     simError();
756     }
757     }
758    
759     // First line is a comment line, read and toss it....
760 chuckv 631 eam_eof_test = fgets(eam_read_buffer, sizeof(eam_read_buffer),eamFile);
761 chuckv 627 linenumber++;
762 chuckv 631 if(eam_eof_test == NULL){
763 chuckv 627 sprintf( painCave.errMsg,
764     "error in reading commment in %s\n", eamPotFile);
765     painCave.isFatal = 1;
766     simError();
767     }
768    
769    
770    
771     // The Second line contains atomic number, atomic mass and a lattice constant
772 chuckv 631 eam_eof_test = fgets(eam_read_buffer, sizeof(eam_read_buffer),eamFile);
773 chuckv 627 linenumber++;
774 chuckv 631 if(eam_eof_test == NULL){
775 chuckv 627 sprintf( painCave.errMsg,
776     "error in reading Identifier line in %s\n", eamPotFile);
777     painCave.isFatal = 1;
778     simError();
779     }
780    
781    
782    
783    
784 chuckv 631 if ( (the_token = strtok( eam_read_buffer, " \n\t,;")) == NULL){
785 chuckv 627 sprintf( painCave.errMsg,
786     "Error parseing EAM ident line in %s\n", eamPotFile );
787     painCave.isFatal = 1;
788     simError();
789     }
790    
791     info.eam_ident = atoi( the_token );
792    
793     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
794     sprintf( painCave.errMsg,
795     "Error parseing EAM mass in %s\n", eamPotFile );
796     painCave.isFatal = 1;
797     simError();
798     }
799     info.mass = atof( the_token);
800    
801     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
802     sprintf( painCave.errMsg,
803     "Error parseing EAM Lattice Constant %s\n", eamPotFile );
804     painCave.isFatal = 1;
805     simError();
806     }
807     info.lattice_constant = atof( the_token);
808    
809     // Next line is nrho, drho, nr, dr and rcut
810 chuckv 631 eam_eof_test = fgets(eam_read_buffer, sizeof(eam_read_buffer),eamFile);
811     if(eam_eof_test == NULL){
812 chuckv 627 sprintf( painCave.errMsg,
813     "error in reading number of points line in %s\n", eamPotFile);
814     painCave.isFatal = 1;
815     simError();
816     }
817    
818 chuckv 631 if ( (the_token = strtok( eam_read_buffer, " \n\t,;")) == NULL){
819 chuckv 627 sprintf( painCave.errMsg,
820     "Error parseing EAM nrho: line in %s\n", eamPotFile );
821     painCave.isFatal = 1;
822     simError();
823     }
824    
825     info.eam_nrho = atoi( the_token );
826    
827     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
828     sprintf( painCave.errMsg,
829     "Error parseing EAM drho in %s\n", eamPotFile );
830     painCave.isFatal = 1;
831     simError();
832     }
833     info.eam_drho = atof( the_token);
834    
835     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
836     sprintf( painCave.errMsg,
837     "Error parseing EAM # r in %s\n", eamPotFile );
838     painCave.isFatal = 1;
839     simError();
840     }
841     info.eam_nr = atoi( the_token);
842    
843     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
844     sprintf( painCave.errMsg,
845     "Error parseing EAM dr in %s\n", eamPotFile );
846     painCave.isFatal = 1;
847     simError();
848     }
849     info.eam_dr = atof( the_token);
850    
851     if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
852     sprintf( painCave.errMsg,
853     "Error parseing EAM rcut in %s\n", eamPotFile );
854     painCave.isFatal = 1;
855     simError();
856     }
857     info.eam_rcut = atof( the_token);
858    
859    
860 chuckv 657
861    
862    
863 chuckv 627 // Ok now we have to allocate point arrays and read in number of points
864     // Index the arrays for fortran, starting at 1
865 chuckv 657 myEam_Frhovals = new double[info.eam_nrho];
866     myEam_rvals = new double[info.eam_nr];
867     myEam_rhovals = new double[info.eam_nr];
868 chuckv 627
869     // Parse F of rho vals.
870    
871     // Assume for now that we have a complete number of lines
872 chuckv 631 nReadLines = int(info.eam_nrho/5);
873 chuckv 657
874 chuckv 627
875 chuckv 657
876 chuckv 627 for (i=0;i<nReadLines;i++){
877     j = i*5;
878 chuckv 657
879 chuckv 627 // Read next line
880 chuckv 631 eam_eof_test = fgets(eam_read_buffer, sizeof(eam_read_buffer),eamFile);
881 chuckv 627 linenumber++;
882 chuckv 631 if(eam_eof_test == NULL){
883 chuckv 627 sprintf( painCave.errMsg,
884     "error in reading EAM file %s at line %d\n",
885     eamPotFile,linenumber);
886     painCave.isFatal = 1;
887     simError();
888     }
889    
890     // Parse 5 values on each line into array
891     // Value 1
892 chuckv 631 if ( (the_token = strtok( eam_read_buffer, " \n\t,;")) == NULL){
893 chuckv 499 sprintf( painCave.errMsg,
894 chuckv 627 "Error parseing EAM nrho: line in %s\n", eamPotFile );
895 chuckv 499 painCave.isFatal = 1;
896     simError();
897     }
898 chuckv 657
899     myEam_Frhovals[j+0] = atof( the_token );
900 chuckv 499
901 chuckv 627 // Value 2
902     if ( (the_token = strtok( NULL, " \n\t,;")) == NULL){
903     sprintf( painCave.errMsg,
904     "Error parseing EAM nrho: line in %s\n", eamPotFile );
905     painCave.isFatal = 1;
906     simError();
907     }
908 chuckv 657
909     myEam_Frhovals[j+1] = atof( the_token );
910 chuckv 627
911     // Value 3
912     if ( (the_token = strtok( NULL, " \n\t,;")) == NULL){
913     sprintf( painCave.errMsg,
914     "Error parseing EAM nrho: line in %s\n", eamPotFile );
915     painCave.isFatal = 1;
916     simError();
917     }
918 chuckv 657
919     myEam_Frhovals[j+2] = atof( the_token );
920 chuckv 627
921     // Value 4
922     if ( (the_token = strtok( NULL, " \n\t,;")) == NULL){
923     sprintf( painCave.errMsg,
924     "Error parseing EAM nrho: line in %s\n", eamPotFile );
925     painCave.isFatal = 1;
926     simError();
927     }
928    
929 chuckv 657 myEam_Frhovals[j+3] = atof( the_token );
930    
931 chuckv 627 // Value 5
932     if ( (the_token = strtok( NULL, " \n\t,;")) == NULL){
933     sprintf( painCave.errMsg,
934     "Error parseing EAM nrho: line in %s\n", eamPotFile );
935     painCave.isFatal = 1;
936     simError();
937     }
938 chuckv 657
939     myEam_Frhovals[j+4] = atof( the_token );
940 chuckv 627
941 chuckv 499 }
942 chuckv 627 // Parse Z of r vals
943    
944     // Assume for now that we have a complete number of lines
945 chuckv 631 nReadLines = int(info.eam_nr/5);
946 chuckv 627
947     for (i=0;i<nReadLines;i++){
948     j = i*5;
949    
950     // Read next line
951 chuckv 631 eam_eof_test = fgets(eam_read_buffer, sizeof(eam_read_buffer),eamFile);
952 chuckv 627 linenumber++;
953 chuckv 631 if(eam_eof_test == NULL){
954 chuckv 627 sprintf( painCave.errMsg,
955     "error in reading EAM file %s at line %d\n",
956     eamPotFile,linenumber);
957     painCave.isFatal = 1;
958     simError();
959     }
960    
961     // Parse 5 values on each line into array
962     // Value 1
963 chuckv 631 if ( (the_token = strtok( eam_read_buffer, " \n\t,;")) == NULL){
964 chuckv 627 sprintf( painCave.errMsg,
965     "Error parseing EAM nrho: line in %s\n", eamPotFile );
966     painCave.isFatal = 1;
967     simError();
968     }
969    
970 chuckv 657 myEam_rvals[j+0] = atof( the_token );
971 chuckv 627
972     // Value 2
973     if ( (the_token = strtok( NULL, " \n\t,;")) == NULL){
974     sprintf( painCave.errMsg,
975     "Error parseing EAM nrho: line in %s\n", eamPotFile );
976     painCave.isFatal = 1;
977     simError();
978     }
979    
980 chuckv 657 myEam_rvals[j+1] = atof( the_token );
981 chuckv 627
982     // Value 3
983     if ( (the_token = strtok( NULL, " \n\t,;")) == NULL){
984     sprintf( painCave.errMsg,
985     "Error parseing EAM nrho: line in %s\n", eamPotFile );
986     painCave.isFatal = 1;
987     simError();
988     }
989    
990 chuckv 657 myEam_rvals[j+2] = atof( the_token );
991 chuckv 627
992     // Value 4
993     if ( (the_token = strtok( NULL, " \n\t,;")) == NULL){
994     sprintf( painCave.errMsg,
995     "Error parseing EAM nrho: line in %s\n", eamPotFile );
996     painCave.isFatal = 1;
997     simError();
998     }
999    
1000 chuckv 657 myEam_rvals[j+3] = atof( the_token );
1001 chuckv 627
1002     // Value 5
1003     if ( (the_token = strtok( NULL, " \n\t,;")) == NULL){
1004     sprintf( painCave.errMsg,
1005     "Error parseing EAM nrho: line in %s\n", eamPotFile );
1006     painCave.isFatal = 1;
1007     simError();
1008     }
1009    
1010 chuckv 657 myEam_rvals[j+4] = atof( the_token );
1011 chuckv 627
1012     }
1013     // Parse rho of r vals
1014    
1015     // Assume for now that we have a complete number of lines
1016    
1017     for (i=0;i<nReadLines;i++){
1018     j = i*5;
1019    
1020     // Read next line
1021 chuckv 631 eam_eof_test = fgets(eam_read_buffer, sizeof(eam_read_buffer),eamFile);
1022 chuckv 627 linenumber++;
1023 chuckv 631 if(eam_eof_test == NULL){
1024 chuckv 627 sprintf( painCave.errMsg,
1025     "error in reading EAM file %s at line %d\n",
1026     eamPotFile,linenumber);
1027     painCave.isFatal = 1;
1028     simError();
1029     }
1030    
1031     // Parse 5 values on each line into array
1032     // Value 1
1033 chuckv 631 if ( (the_token = strtok( eam_read_buffer, " \n\t,;")) == NULL){
1034 chuckv 627 sprintf( painCave.errMsg,
1035     "Error parseing EAM nrho: line in %s\n", eamPotFile );
1036     painCave.isFatal = 1;
1037     simError();
1038     }
1039    
1040 chuckv 657 myEam_rhovals[j+0] = atof( the_token );
1041 chuckv 627
1042     // Value 2
1043 chuckv 673 if ( (the_token = strtok( NULL, " \n\t,;")) == NULL){
1044 chuckv 627 sprintf( painCave.errMsg,
1045     "Error parseing EAM nrho: line in %s\n", eamPotFile );
1046     painCave.isFatal = 1;
1047     simError();
1048     }
1049    
1050 chuckv 657 myEam_rhovals[j+1] = atof( the_token );
1051 chuckv 627
1052     // Value 3
1053 chuckv 673 if ( (the_token = strtok( NULL, " \n\t,;")) == NULL){
1054 chuckv 627 sprintf( painCave.errMsg,
1055     "Error parseing EAM nrho: line in %s\n", eamPotFile );
1056     painCave.isFatal = 1;
1057     simError();
1058     }
1059    
1060 chuckv 657 myEam_rhovals[j+2] = atof( the_token );
1061 chuckv 627
1062     // Value 4
1063 chuckv 673 if ( (the_token = strtok( NULL, " \n\t,;")) == NULL){
1064 chuckv 627 sprintf( painCave.errMsg,
1065     "Error parseing EAM nrho: line in %s\n", eamPotFile );
1066     painCave.isFatal = 1;
1067     simError();
1068     }
1069    
1070 chuckv 657 myEam_rhovals[j+3] = atof( the_token );
1071 chuckv 627
1072     // Value 5
1073 chuckv 673 if ( (the_token = strtok( NULL, " \n\t,;")) == NULL){
1074 chuckv 627 sprintf( painCave.errMsg,
1075     "Error parseing EAM nrho: line in %s\n", eamPotFile );
1076     painCave.isFatal = 1;
1077     simError();
1078     }
1079    
1080 chuckv 657 myEam_rhovals[j+4] = atof( the_token );
1081 chuckv 673
1082 chuckv 627 }
1083 chuckv 657 *eam_rvals = myEam_rvals;
1084     *eam_rhovals = myEam_rhovals;
1085     *eam_Frhovals = myEam_Frhovals;
1086 chuckv 627
1087     fclose(eamFile);
1088     return 0;
1089 chuckv 499 }