modernize potential file reader for local/density
This commit is contained in:
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user