Unverified Commit bd3ffe13 authored by Axel Kohlmeyer's avatar Axel Kohlmeyer Committed by GitHub
Browse files

Merge pull request #1603 from eagunn/iss1572clean

Iss1572clean: Clean fix for error handling, clarify data requirements for fix bocs input
parents 11198e9d d750cc02
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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
+58 −18
Original line number Diff line number Diff line
@@ -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);
  }

    // 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;
  fpi = fopen(filename,"r");
  if (fpi) {
    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