forked from lijiext/lammps
Changed the code in the read_F_table function to conform to the "expected behavior" description in #1572. Adopted a best-of-both-worlds approach, though, and processed the whole input file all the way through, emitting a message for each problem found, before issuing a final error message to stop processing. Updated doc to clarify requirement for uniform spacing of pressure correction points.
This commit is contained in:
parent
de366c27e2
commit
d750cc02c0
|
@ -47,13 +47,13 @@ or {cubic_spline}.
|
|||
|
||||
With either spline method, the only argument that needs to follow it
|
||||
is the name of a file that contains the desired pressure correction
|
||||
as a function of volume. The file should be formatted so each line has:
|
||||
as a function of volume. The file must be formatted so each line has:
|
||||
|
||||
Volume_i, PressureCorrection_i :pre
|
||||
|
||||
Note both the COMMA and the SPACE separating the volume's
|
||||
value and its corresponding pressure correction. The volumes in the file
|
||||
should be uniformly spaced. Both the volumes and the pressure corrections
|
||||
must be uniformly spaced. Both the volumes and the pressure corrections
|
||||
should be provided in the proper units, e.g. if you are using {units real},
|
||||
the volumes should all be in cubic angstroms, and the pressure corrections
|
||||
should all be in atmospheres. Furthermore, the table should start/end at a
|
||||
|
|
|
@ -59,6 +59,9 @@ enum{NOBIAS,BIAS};
|
|||
enum{NONE,XYZ,XY,YZ,XZ};
|
||||
enum{ISO,ANISO,TRICLINIC};
|
||||
|
||||
// NB: Keep error and warning messages less than 255 chars long.
|
||||
const int MAX_MESSAGE_LENGTH = 256;
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
NVT,NPH,NPT integrators for improved Nose-Hoover equations of motion
|
||||
---------------------------------------------------------------------- */
|
||||
|
@ -630,24 +633,32 @@ int FixBocs::read_F_table( char *filename, int p_basis_type )
|
|||
double **data = (double **) calloc(N_columns,sizeof(double *));
|
||||
char * line = (char *) calloc(200,sizeof(char));
|
||||
|
||||
bool badInput = false;
|
||||
char badDataMsg[MAX_MESSAGE_LENGTH];
|
||||
fpi = fopen(filename,"r");
|
||||
if (fpi)
|
||||
{
|
||||
while (fgets(line,199,fpi)) { ++n_entries; }
|
||||
fclose(fpi);
|
||||
|
||||
for (i = 0; i < N_columns; ++i)
|
||||
{
|
||||
data[i] = (double *) calloc(n_entries,sizeof(double));
|
||||
}
|
||||
} else {
|
||||
char errmsg[128];
|
||||
snprintf(errmsg,128,"Unable to open file: %s\n",filename);
|
||||
error->all(FLERR,errmsg);
|
||||
}
|
||||
|
||||
n_entries = 0;
|
||||
fpi = fopen(filename,"r");
|
||||
if (fpi) {
|
||||
// Don't need to re-open the file to make a second pass through it
|
||||
// simply rewind to beginning
|
||||
rewind(fpi);
|
||||
|
||||
double stdVolumeInterval = 0.0;
|
||||
double currVolumeInterval = 0.0;
|
||||
// When comparing doubles/floats, we need an Epsilon.
|
||||
// The literature indicates getting this value right in the
|
||||
// general case can be pretty complicated. I don't think it
|
||||
// needs to be complicated here, though. At least based on the
|
||||
// sample data I've seen where the volume values are fairly
|
||||
// large.
|
||||
const double volumeIntervalTolerance = 0.001;
|
||||
n_entries = 0;
|
||||
while( fgets(line,199,fpi)) {
|
||||
++n_entries;
|
||||
test_sscanf = sscanf(line," %f , %f ",&f1, &f2);
|
||||
|
@ -655,19 +666,47 @@ int FixBocs::read_F_table( char *filename, int p_basis_type )
|
|||
{
|
||||
data[0][n_entries-1] = (double) f1;
|
||||
data[1][n_entries-1] = (double) f2;
|
||||
if (n_entries == 2) {
|
||||
stdVolumeInterval = data[0][n_entries-1] - data[0][n_entries-2];
|
||||
}
|
||||
else if (n_entries > 2) {
|
||||
currVolumeInterval = data[0][n_entries-1] - data[0][n_entries-2];
|
||||
if (fabs(currVolumeInterval - stdVolumeInterval) > volumeIntervalTolerance) {
|
||||
snprintf(badDataMsg,MAX_MESSAGE_LENGTH,
|
||||
"BAD VOLUME INTERVAL: spline analysis requires uniform"
|
||||
" volume distribution, found inconsistent volume"
|
||||
" differential, line %d of file %s\n\tline: %s",
|
||||
n_entries,filename,line);
|
||||
error->message(FLERR,badDataMsg);
|
||||
badInput = true;
|
||||
}
|
||||
}
|
||||
// no else -- first entry is simply ignored
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"WARNING: did not find 2 comma separated values in "
|
||||
"line %d of file %s\n\tline: %s",n_entries,filename,line);
|
||||
snprintf(badDataMsg,MAX_MESSAGE_LENGTH,
|
||||
"BAD INPUT FORMAT: did not find 2 comma separated numeric"
|
||||
" values in line %d of file %s\n\tline: %s",
|
||||
n_entries,filename,line);
|
||||
error->message(FLERR,badDataMsg);
|
||||
badInput = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
char errmsg[128];
|
||||
snprintf(errmsg,128,"Unable to open file: %s\n",filename);
|
||||
fclose(fpi);
|
||||
}
|
||||
else {
|
||||
char errmsg[MAX_MESSAGE_LENGTH];
|
||||
snprintf(errmsg,MAX_MESSAGE_LENGTH,"Unable to open file: %s\n",filename);
|
||||
error->all(FLERR,errmsg);
|
||||
}
|
||||
|
||||
if (badInput) {
|
||||
char errmsg[MAX_MESSAGE_LENGTH];
|
||||
snprintf(errmsg,MAX_MESSAGE_LENGTH,
|
||||
"Bad volume / pressure-correction data: %s\nSee details above",filename);
|
||||
error->all(FLERR,errmsg);
|
||||
}
|
||||
fclose(fpi);
|
||||
|
||||
if (p_basis_type == 1)
|
||||
{
|
||||
|
@ -691,9 +730,10 @@ int FixBocs::read_F_table( char *filename, int p_basis_type )
|
|||
}
|
||||
else
|
||||
{
|
||||
char * errmsg = (char *) calloc(70,sizeof(char));
|
||||
sprintf(errmsg,"ERROR: invalid p_basis_type value "
|
||||
"of %d in read_F_table",p_basis_type);
|
||||
char errmsg[MAX_MESSAGE_LENGTH];
|
||||
snprintf(errmsg, MAX_MESSAGE_LENGTH,
|
||||
"ERROR: invalid p_basis_type value of %d in read_F_table",
|
||||
p_basis_type);
|
||||
error->all(FLERR,errmsg);
|
||||
}
|
||||
// cleanup
|
||||
|
|
Loading…
Reference in New Issue