modernize potential file reader for local/density

This commit is contained in:
Axel Kohlmeyer
2021-12-10 08:45:01 -05:00
parent 3fc0ea3e80
commit 14fc42833f

View File

@ -28,6 +28,7 @@
#include "memory.h" #include "memory.h"
#include "neigh_list.h" #include "neigh_list.h"
#include "neighbor.h" #include "neighbor.h"
#include "potential_file_reader.h"
#include <cstring> #include <cstring>
@ -656,40 +657,37 @@ void PairLocalDensity::interpolate_cbspl(int n, double delta,
void PairLocalDensity::parse_file(char *filename) { void PairLocalDensity::parse_file(char *filename) {
int k, n; // parse potential file header
int me = comm->me; if (comm->me == 0) {
FILE *fptr; PotentialFileReader reader(lmp, filename, "local/density");
char line[MAXLINE];
double ratio, lc2, uc2, denom;
if (me == 0) { try {
fptr = fopen(filename, "r");
if (fptr == nullptr) // ignore first 2 comment lines
error->one(FLERR,"Cannot open Local Density potential file {}: {}",filename,utils::getsyserror()); reader.skip_line();
reader.skip_line();
// extract number of potentials and number of (frho, rho) points
ValueTokenizer values = reader.next_values(2);
nLD = values.next_int();
nrho = values.next_int();
const int numld = atom->ntypes*atom->ntypes;
if (nLD != numld)
error->warning(FLERR, "Expected {} local density potentials but got {}",numld, nLD);
} catch (TokenizerException &e) {
error->one(FLERR, e.what());
}
} }
double *ftmp; // tmp var to extract the complete 2D frho array from file // broadcast number of LD potentials and number of (rho,frho) pairs and allocate storage
// broadcast number of LD potentials and number of (rho,frho) pairs
if (me == 0) {
// first 2 comment lines ignored
utils::sfgets(FLERR,line,MAXLINE,fptr,filename,error);
utils::sfgets(FLERR,line,MAXLINE,fptr,filename,error);
// extract number of potentials and number of (frho, rho) points
utils::sfgets(FLERR,line,MAXLINE,fptr,filename,error);
sscanf(line, "%d %d", &nLD, &nrho);
utils::sfgets(FLERR,line,MAXLINE,fptr,filename,error);
}
MPI_Bcast(&nLD,1,MPI_INT,0,world); MPI_Bcast(&nLD,1,MPI_INT,0,world);
MPI_Bcast(&nrho,1,MPI_INT,0,world); MPI_Bcast(&nrho,1,MPI_INT,0,world);
comm_forward = comm_reverse = nLD; comm_forward = comm_reverse = nLD;
if ((me == 0) && (nLD != atom->ntypes*atom->ntypes)) double *ftmp; // tmp var to extract the complete 2D frho array from file
error->warning(FLERR, "Expected {} local density potentials but got {}",
atom->ntypes*atom->ntypes, nLD);
// setting up all arrays to be read from files and broadcasted // setting up all arrays to be read from files and broadcasted
memory->create(uppercut, nLD, "pairLD:uppercut"); memory->create(uppercut, nLD, "pairLD:uppercut");
@ -708,54 +706,65 @@ void PairLocalDensity::parse_file(char *filename) {
// setting up central and neighbor atom filters // setting up central and neighbor atom filters
memory->create(a, nLD, atom->ntypes+1 , "pairLD:a"); memory->create(a, nLD, atom->ntypes+1 , "pairLD:a");
memory->create(b, nLD, atom->ntypes+1, "pairLD:b"); memory->create(b, nLD, atom->ntypes+1, "pairLD:b");
if (me == 0) { for (int k = 0; k < nLD; k++) {
for (n = 1; n <= atom->ntypes; n++) { for (int n = 1; n <= atom->ntypes; n++) {
for (k = 0; k < nLD; k++) { a[k][n] = 0;
a[k][n] = 0; b[k][n] = 0;
b[k][n] = 0;
}
} }
} }
// read file block by block // parse potential file body
if (comm->me == 0) {
PotentialFileReader reader(lmp, filename, "local/density");
if (me == 0) { try {
for (k = 0; k < nLD; k++) { double ratio, lc2, uc2, denom;
ValueTokenizer values("");
// ignore first 4 lines already processed
reader.skip_line();
reader.skip_line();
reader.skip_line();
reader.skip_line();
for (int k = 0; k < nLD; k++) {
// parse upper and lower cut values // parse upper and lower cut values
if (fgets(line,MAXLINE,fptr)==nullptr) break; values = reader.next_values(2);
sscanf(line, "%lf %lf", &lowercut[k], &uppercut[k]); lowercut[k] = values.next_double();
uppercut[k] = values.next_double();
// parse and broadcast central atom filter // parse central atom filter
utils::sfgets(FLERR,line, MAXLINE, fptr,filename,error); values = ValueTokenizer(reader.next_line());
char *tmp = strtok(line, " /t/n/r/f"); while (values.has_next()) {
while (tmp != nullptr) { int atype = values.next_int();
a[k][atoi(tmp)] = 1; if ((atype < 1) || (atype > atom->ntypes))
tmp = strtok(nullptr, " /t/n/r/f"); throw TokenizerException("Invalid atom type filter value",std::to_string(atype));
a[k][atype] = 1;
} }
// parse neighbor atom filter // parse neighbor atom filter
utils::sfgets(FLERR,line, MAXLINE, fptr,filename,error); values = ValueTokenizer(reader.next_line());
tmp = strtok(line, " /t/n/r/f"); while (values.has_next()) {
while (tmp != nullptr) { int btype = values.next_int();
b[k][atoi(tmp)] = 1; if ((btype < 1) || (btype > atom->ntypes))
tmp = strtok(nullptr, " /t/n/r/f"); throw TokenizerException("Invalid atom type filter value",std::to_string(btype));
b[k][btype] = 1;
} }
// parse min, max and delta rho values // parse min, max and delta rho values
utils::sfgets(FLERR,line, MAXLINE, fptr,filename,error); values = reader.next_values(3);
sscanf(line, "%lf %lf %lf", &rho_min[k], &rho_max[k], &delta_rho[k]); rho_min[k] = values.next_double();
rho_max[k] = values.next_double();
// recompute delta_rho from scratch for precision // recompute delta_rho from scratch for precision
delta_rho[k] = (rho_max[k] - rho_min[k]) / (nrho - 1); delta_rho[k] = (rho_max[k] - rho_min[k]) / (nrho - 1);
// parse tabulated frho values from each line into temporary array // parse tabulated frho values from each line into temporary array
for (n = 0; n < nrho; n++) { reader.next_dvector(ftmp+k*nrho, nrho);
utils::sfgets(FLERR,line,MAXLINE,fptr,filename,error);
sscanf(line, "%lf", &ftmp[k*nrho + n]);
}
// ignore blank line at the end of every block // ignore blank line at the end of every block
utils::sfgets(FLERR,line,MAXLINE,fptr,filename,error); reader.skip_line();
// set coefficients for local density indicator function // set coefficients for local density indicator function
uc2 = uppercut[k] * uppercut[k]; uc2 = uppercut[k] * uppercut[k];
@ -770,6 +779,10 @@ void PairLocalDensity::parse_file(char *filename) {
c4[k] = -(3.0 + 3.0*ratio) / (uc2*uc2 * denom); c4[k] = -(3.0 + 3.0*ratio) / (uc2*uc2 * denom);
c6[k] = 2.0 / (uc2*uc2*uc2 * denom); c6[k] = 2.0 / (uc2*uc2*uc2 * denom);
} }
} catch (TokenizerException &e) {
error->one(FLERR, e.what());
}
} }
// Broadcast all parsed arrays // Broadcast all parsed arrays
@ -781,7 +794,7 @@ void PairLocalDensity::parse_file(char *filename) {
MPI_Bcast(&c2[0], nLD, MPI_DOUBLE, 0, world); MPI_Bcast(&c2[0], nLD, MPI_DOUBLE, 0, world);
MPI_Bcast(&c4[0], nLD, MPI_DOUBLE, 0, world); MPI_Bcast(&c4[0], nLD, MPI_DOUBLE, 0, world);
MPI_Bcast(&c6[0], nLD, MPI_DOUBLE, 0, world); MPI_Bcast(&c6[0], nLD, MPI_DOUBLE, 0, world);
for (k = 0; k < nLD; k++) { for (int k = 0; k < nLD; k++) {
MPI_Bcast(&a[k][1], atom->ntypes, MPI_INT, 0, world); MPI_Bcast(&a[k][1], atom->ntypes, MPI_INT, 0, world);
MPI_Bcast(&b[k][1], atom->ntypes, MPI_INT, 0, world); MPI_Bcast(&b[k][1], atom->ntypes, MPI_INT, 0, world);
} }
@ -790,14 +803,12 @@ void PairLocalDensity::parse_file(char *filename) {
MPI_Bcast(&delta_rho[0], nLD, MPI_DOUBLE, 0, world); MPI_Bcast(&delta_rho[0], nLD, MPI_DOUBLE, 0, world);
MPI_Bcast(&ftmp[0], nLD*nrho, MPI_DOUBLE, 0, world); MPI_Bcast(&ftmp[0], nLD*nrho, MPI_DOUBLE, 0, world);
if (me == 0) fclose(fptr);
// set up rho and frho arrays // set up rho and frho arrays
memory->create(rho, nLD, nrho, "pairLD:rho"); memory->create(rho, nLD, nrho, "pairLD:rho");
memory->create(frho, nLD, nrho, "pairLD:frho"); memory->create(frho, nLD, nrho, "pairLD:frho");
for (k = 0; k < nLD; k++) { for (int k = 0; k < nLD; k++) {
for (n = 0; n < nrho; n++) { for (int n = 0; n < nrho; n++) {
rho[k][n] = rho_min[k] + n*delta_rho[k]; rho[k][n] = rho_min[k] + n*delta_rho[k];
frho[k][n] = ftmp[k*nrho + n]; frho[k][n] = ftmp[k*nrho + n];
} }
@ -885,4 +896,3 @@ double PairLocalDensity::memory_usage()
bytes += (double)2 * (nmax*nLD) * sizeof(double); bytes += (double)2 * (nmax*nLD) * sizeof(double);
return bytes; return bytes;
} }