Example #1
0
int ex_open_int(const char *path, int mode, int *comp_ws, int *io_ws, float *version,
                int run_version)
{
  int     exoid;
  int     status, stat_att, stat_dim;
  nc_type att_type = NC_NAT;
  size_t  att_len  = 0;
  int     old_fill;
  int     file_wordsize;
  int     dim_str_name;
  int     int64_status = 0;
  int     nc_mode      = 0;

  char errmsg[MAX_ERR_LENGTH];

  EX_FUNC_ENTER();

  /* set error handling mode to no messages, non-fatal errors */
  ex_opts(exoptval); /* call required to set ncopts first time through */

  if (run_version != EX_API_VERS_NODOT && warning_output == 0) {
    int run_version_major = run_version / 100;
    int run_version_minor = run_version % 100;
    int lib_version_major = EX_API_VERS_NODOT / 100;
    int lib_version_minor = EX_API_VERS_NODOT % 100;
    fprintf(stderr,
            "EXODUS: Warning: This code was compiled with exodus "
            "version %d.%02d,\n          but was linked with exodus "
            "library version %d.%02d\n          This is probably an "
            "error in the build process of this code.\n",
            run_version_major, run_version_minor, lib_version_major, lib_version_minor);
    warning_output = 1;
  }

  if ((mode & EX_READ) && (mode & EX_WRITE)) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: Cannot specify both EX_READ and EX_WRITE");
    ex_err(__func__, errmsg, EX_BADFILEMODE);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  /* The EX_READ mode is the default if EX_WRITE is not specified... */
  if (!(mode & EX_WRITE)) { /* READ ONLY */
    nc_mode = NC_NOWRITE | NC_SHARE;

#if NC_HAS_DISKLESS
    if (mode & EX_DISKLESS) {
      nc_mode |= NC_DISKLESS;
    }
#endif

    if ((status = nc_open(path, nc_mode, &exoid)) != NC_NOERR) {
      /* NOTE: netCDF returns an id of -1 on an error - but no error code! */
      /* It is possible that the user is trying to open a netcdf4
         file, but the netcdf4 capabilities aren't available in the
         netcdf linked to this library. Note that we can't just use a
         compile-time define since we could be using a shareable
         netcdf library, so the netcdf4 capabilities aren't known
         until runtime...

         Later versions of netcdf-4.X have a function that can be
         queried to determine whether the library being used was
         compiled with --enable-netcdf4, but not everyone is using that
         version yet, so we may have to do some guessing...

         At this time, query the beginning of the file and see if it
         is an HDF-5 file and if it is assume that the open failure
         is due to the netcdf library not enabling netcdf4 features unless
         we have the define that shows it is enabled, then assume other error...
      */
      int type = 0;
      ex_check_file_type(path, &type);

      if (type == 5) {
#if NC_HAS_HDF5
        fprintf(stderr,
                "EXODUS: ERROR: Attempting to open the netcdf-4 "
                "file:\n\t'%s'\n\t failed. The netcdf library supports "
                "netcdf-4 so there must be a filesystem or some other "
                "issue \n",
                path);
#else
        /* This is an hdf5 (netcdf4) file. If NC_HAS_HDF5 is not defined,
           then we either don't have hdf5 support in this netcdf version,
           OR this is an older netcdf version that doesn't provide that define.

           In either case, we don't have enough information, so we
           assume that the netcdf doesn't have netcdf4 capabilities
           enabled.  Tell the user...
        */
        fprintf(stderr,
                "EXODUS: ERROR: Attempting to open the netcdf-4 "
                "file:\n\t'%s'\n\t. Either the netcdf library does not "
                "support netcdf-4 or there is a filesystem or some "
                "other issue \n",
                path);

#endif
      }
      else if (type == 4) {
#if defined(NC_64BIT_DATA)
        fprintf(stderr,
                "EXODUS: ERROR: Attempting to open the CDF5 "
                "file:\n\t'%s'\n\t failed. The netcdf library supports "
                "CDF5-type files so there must be a filesystem or some other "
                "issue \n",
                path);
#else
        /* This is an cdf5 (64BIT_DATA) file. If NC_64BIT_DATA is not defined,
           then we either don't have cdf5 support in this netcdf version,
           OR this is an older netcdf version that doesn't provide that define.

           In either case, we don't have enough information, so we
           assume that the netcdf doesn't have cdf5 capabilities
           enabled.  Tell the user...
        */
        fprintf(stderr,
                "EXODUS: ERROR: Attempting to open the CDF5 "
                "file:\n\t'%s'\n\t. Either the netcdf library does not "
                "support CDF5 or there is a filesystem or some "
                "other issue \n",
                path);

#endif
      }
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to open %s read only", path);
      ex_err(__func__, errmsg, status);
      EX_FUNC_LEAVE(EX_FATAL);
    }
  }
  else { /* (mode & EX_WRITE) READ/WRITE */
    nc_mode = NC_WRITE | NC_SHARE;
#if NC_HAS_DISKLESS
    if (mode & EX_DISKLESS) {
      nc_mode |= NC_DISKLESS;
    }
#endif
    if ((status = nc_open(path, nc_mode, &exoid)) != NC_NOERR) {
      /* NOTE: netCDF returns an id of -1 on an error - but no error code! */
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to open %s write only", path);
      ex_err(__func__, errmsg, status);
      EX_FUNC_LEAVE(EX_FATAL);
    }

    /* turn off automatic filling of netCDF variables */
    if ((status = nc_set_fill(exoid, NC_NOFILL, &old_fill)) != NC_NOERR) {
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to set nofill mode in file id %d", exoid);
      ex_err(__func__, errmsg, status);
      EX_FUNC_LEAVE(EX_FATAL);
    }

    stat_att = nc_inq_att(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, &att_type, &att_len);
    stat_dim = nc_inq_dimid(exoid, DIM_STR_NAME, &dim_str_name);
    if (stat_att != NC_NOERR || stat_dim != NC_NOERR) {
      if ((status = nc_redef(exoid)) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to place file id %d into define mode",
                 exoid);
        ex_err(__func__, errmsg, status);
        EX_FUNC_LEAVE(EX_FATAL);
      }

      if (stat_att != NC_NOERR) {
        int max_so_far = 32;
        nc_put_att_int(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, NC_INT, 1, &max_so_far);
      }

      /* If the DIM_STR_NAME variable does not exist on the database, we need to
       * add it now. */
      if (stat_dim != NC_NOERR) {
        /* Not found; set to default value of 32+1. */
        int max_name = ex_default_max_name_length < 32 ? 32 : ex_default_max_name_length;
        if ((status = nc_def_dim(exoid, DIM_STR_NAME, max_name + 1, &dim_str_name)) != NC_NOERR) {
          snprintf(errmsg, MAX_ERR_LENGTH,
                   "ERROR: failed to define string name dimension in file id %d", exoid);
          ex_err(__func__, errmsg, status);
          EX_FUNC_LEAVE(EX_FATAL);
        }
      }
      if ((status = nc_enddef(exoid)) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to complete definition in file id %d",
                 exoid);
        ex_err(__func__, errmsg, status);
        EX_FUNC_LEAVE(EX_FATAL);
      }
    }
  }

  /* determine version of EXODUS file, and the word size of
   * floating point and integer values stored in the file
   */

  if ((status = nc_get_att_float(exoid, NC_GLOBAL, ATT_VERSION, version)) != NC_NOERR) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get database version for file id: %d",
             exoid);
    ex_err(__func__, errmsg, status);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  /* check ExodusII file version - old version 1.x files are not supported */
  if (*version < 2.0) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: Unsupported file version %.2f in file id: %d",
             *version, exoid);
    ex_err(__func__, errmsg, EX_BADPARAM);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  if (nc_get_att_int(exoid, NC_GLOBAL, ATT_FLT_WORDSIZE, &file_wordsize) != NC_NOERR) {
    /* try old (prior to db version 2.02) attribute name */
    if ((status = nc_get_att_int(exoid, NC_GLOBAL, ATT_FLT_WORDSIZE_BLANK, &file_wordsize)) !=
        NC_NOERR) {
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get file wordsize from file id: %d",
               exoid);
      ex_err(__func__, errmsg, status);
      EX_FUNC_LEAVE(EX_FATAL);
    }
  }

  /* See if int64 status attribute exists and if so, what data is stored as
   * int64
   * Older files don't have the attribute, so it is not an error if it is
   * missing
   */
  if (nc_get_att_int(exoid, NC_GLOBAL, ATT_INT64_STATUS, &int64_status) != NC_NOERR) {
    int64_status = 0; /* Just in case it gets munged by a failed get_att_int call */
  }

  /* Merge in API int64 status flags as specified by caller of function... */
  int64_status |= (mode & EX_ALL_INT64_API);

  /* Verify that there is not an existing file_item struct for this
     exoid This could happen (and has) when application calls
     ex_open(), but then closes file using nc_close() and then reopens
     file.  NetCDF will possibly reuse the exoid which results in
     internal corruption in exodus data structures since exodus does
     not know that file was closed and possibly new file opened for
     this exoid
  */
  if (ex_find_file_item(exoid) != NULL) {
    snprintf(errmsg, MAX_ERR_LENGTH,
             "ERROR: There is an existing file already using the file "
             "id %d which was also assigned to file %s.\n\tWas "
             "nc_close() called instead of ex_close() on an open Exodus "
             "file?\n",
             exoid, path);
    ex_err(__func__, errmsg, EX_BADFILEID);
    nc_close(exoid);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  /* initialize floating point and integer size conversion. */
  if (ex_conv_ini(exoid, comp_ws, io_ws, file_wordsize, int64_status, 0, 0, 0) != EX_NOERR) {
    snprintf(errmsg, MAX_ERR_LENGTH,
             "ERROR: failed to initialize conversion routines in file id %d", exoid);
    ex_err(__func__, errmsg, EX_LASTERR);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  EX_FUNC_LEAVE(exoid);
}
Example #2
0
int ex_create (const char *path,
               int   cmode,
               int  *comp_ws,
               int  *io_ws)
{
   int exoid, time_dim, dims[1];
   nclong lio_ws;
   nclong filesiz;
   float vers;
   char errmsg[MAX_ERR_LENGTH];
   char *mode_name;
   int mode = 0;
   
   exerrval = 0; /* clear error code */

   /*
    * See if "large file" mode was specified in a ex_create cmode. If
    * so, then pass the NC_64BIT_OFFSET flag down to netcdf.
    */
   if (cmode & EX_LARGE_MODEL || ex_large_model(-1) == 1) {
     mode |= NC_64BIT_OFFSET;
   }

/*
 * set error handling mode to no messages, non-fatal errors
 */
  ex_opts(exoptval);    /* call required to set ncopts first time through */

   if (cmode & EX_NOCLOBBER) {
     mode |= NC_NOCLOBBER;
     mode_name = "NOCLOBBER";
   } else if (cmode & EX_CLOBBER) {
     mode |= NC_CLOBBER;
     mode_name = "CLOBBER";
   } else {
     exerrval = EX_BADFILEMODE;
     sprintf(errmsg,"Error: invalid file create mode: %d, for file %s",
             cmode,path);
     ex_err("ex_create",errmsg,exerrval);
     return (EX_FATAL);
   }

#ifndef TFLOP
   mode |= NC_SHARE;
#endif
   
   if ((exoid = nccreate (path, mode)) == -1) {
     exerrval = ncerr;
     sprintf(errmsg,
             "Error: file create failed for %s, mode: %s",
             path, mode_name);
     ex_err("ex_create",errmsg,exerrval);
     return (EX_FATAL);
   }

/* turn off automatic filling of netCDF variables
 */

  if (ncsetfill (exoid, NC_NOFILL) == -1)
  {
    exerrval = ncerr;
    sprintf(errmsg,
           "Error: failed to set nofill mode in file id %d",
            exoid);
    ex_err("ex_create", errmsg, exerrval);
    return (EX_FATAL);
  }

/* initialize floating point size conversion.  since creating new file, 
 * i/o wordsize attribute from file is zero.
 */

   if (ex_conv_ini( exoid, comp_ws, io_ws, 0 ) != EX_NOERR) {
     exerrval = EX_FATAL;
     sprintf(errmsg,
           "Error: failed to init conversion routines in file id %d",
            exoid);
     ex_err("ex_create", errmsg, exerrval);
     return (EX_FATAL);
   }

/* put the EXODUS version number, and i/o floating point word size as
 * netcdf global attributes
 */

/* store Exodus API version # as an attribute */
  vers = (float)(EX_API_VERS);
  if (ncattput (exoid, NC_GLOBAL, ATT_API_VERSION, NC_FLOAT, 1, &vers) == -1)
  {
    exerrval = ncerr;
    sprintf(errmsg,
         "Error: failed to store Exodus II API version attribute in file id %d",
            exoid);
    ex_err("ex_create",errmsg, exerrval);
    return (EX_FATAL);
  }

/* store Exodus file version # as an attribute */
  vers = (float)(EX_VERS);
  if (ncattput (exoid, NC_GLOBAL, ATT_VERSION, NC_FLOAT, 1, &vers) == -1)
  {
    exerrval = ncerr;
    sprintf(errmsg,
        "Error: failed to store Exodus II file version attribute in file id %d",
            exoid);
    ex_err("ex_create",errmsg, exerrval);
    return (EX_FATAL);
  }

/* store Exodus file float word size  as an attribute */
  lio_ws = (nclong)(*io_ws);
  if (ncattput (exoid, NC_GLOBAL, ATT_FLT_WORDSIZE, NC_LONG, 1, &lio_ws) == -1)
  {
    exerrval = ncerr;
    sprintf(errmsg,
 "Error: failed to store Exodus II file float word size attribute in file id %d",
           exoid);
    ex_err("ex_create",errmsg, exerrval);
    return (EX_FATAL);
  }

  /* store Exodus file size (1=large, 0=normal) as an attribute */
  filesiz = (nclong)(((cmode & EX_LARGE_MODEL) != 0) || (ex_large_model(-1) == 1));
  if (ncattput (exoid, NC_GLOBAL, ATT_FILESIZE, NC_LONG, 1, &filesiz) == -1)
    {
      exerrval = ncerr;
      sprintf(errmsg,
              "Error: failed to store Exodus II file size attribute in file id %d",
              exoid);
      ex_err("ex_create",errmsg, exerrval);
      return (EX_FATAL);
    }
  
  /* define some dimensions and variables
   */
  
  /* create string length dimension */
  if (ncdimdef (exoid, DIM_STR, (MAX_STR_LENGTH+1)) == -1)
  {
    exerrval = ncerr;
    sprintf(errmsg,
           "Error: failed to define string length in file id %d",exoid);
    ex_err("ex_create",errmsg,exerrval);
    return (EX_FATAL);
  }


  /* create line length dimension */
  if (ncdimdef (exoid, DIM_LIN, (MAX_LINE_LENGTH+1)) == -1)
  {
    exerrval = ncerr;
    sprintf(errmsg,
           "Error: failed to define line length in file id %d",exoid);
    ex_err("ex_create",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* create number "4" dimension; must be of type long */
  if (ncdimdef (exoid, DIM_N4, 4L) == -1)
  {
    exerrval = ncerr;
    sprintf(errmsg,
           "Error: failed to define number \"4\" dimension in file id %d",exoid);
    ex_err("ex_create",errmsg,exerrval);
    return (EX_FATAL);
  }


  if ((time_dim = ncdimdef (exoid, DIM_TIME, NC_UNLIMITED)) == -1)
  {
    exerrval = ncerr;
    sprintf(errmsg,
           "Error: failed to define time dimension in file id %d", exoid);
    ex_err("ex_create",errmsg,exerrval);
    return (EX_FATAL);
  }

  dims[0] = time_dim;
  if ((ncvardef (exoid, VAR_WHOLE_TIME, nc_flt_code(exoid), 1, dims)) == -1)
  {
    exerrval = ncerr;
    sprintf(errmsg,
           "Error: failed to define whole time step variable in file id %d",
            exoid);
    ex_err("ex_create",errmsg,exerrval);
    return (EX_FATAL);
  }

  if (ncendef (exoid) == -1)
  {
    exerrval = ncerr;
    sprintf(errmsg,
           "Error: failed to complete definition for file id %d", exoid);
    ex_err("ex_create",errmsg,exerrval);
    return (EX_FATAL);
  }

  return (exoid);
}
Example #3
0
int ex_open_int (const char  *path,
		 int    mode,
		 int   *comp_ws,
		 int   *io_ws,
		 float *version,
		 int    run_version)
{
  int exoid;
  int status, stat_att, stat_dim;
  nc_type att_type = NC_NAT;
  size_t att_len = 0;
  int old_fill;
  int file_wordsize;
  int dim_str_name;
  int int64_status = 0;
  
  char errmsg[MAX_ERR_LENGTH];

  exerrval = 0; /* clear error code */
 
  /* set error handling mode to no messages, non-fatal errors */
  ex_opts(exoptval);    /* call required to set ncopts first time through */

  if (run_version != EX_API_VERS_NODOT && warning_output == 0) {
    int run_version_major = run_version / 100;
    int run_version_minor = run_version % 100;
    int lib_version_major = EX_API_VERS_NODOT / 100;
    int lib_version_minor = EX_API_VERS_NODOT % 100;
    fprintf(stderr, "EXODUS: Warning: This code was compiled with exodus version %d.%02d,\n          but was linked with exodus library version %d.%02d\n          This is probably an error in the build process of this code.\n",
	    run_version_major, run_version_minor, lib_version_major, lib_version_minor);
    warning_output = 1;
  }
  

  if ((mode & EX_READ) && (mode & EX_WRITE)) {
    exerrval = EX_BADFILEMODE;
    sprintf(errmsg,"Error: Cannot specify both EX_READ and EX_WRITE");
    ex_err("ex_open",errmsg,exerrval); 
    return (EX_FATAL);
  }

  /* The EX_READ mode is the default if EX_WRITE is not specified... */
  if (!(mode & EX_WRITE)) { /* READ ONLY */
#if defined(__LIBCATAMOUNT__)
    if ((status = nc_open (path, NC_NOWRITE, &exoid)) != NC_NOERR)
#else
      if ((status = nc_open (path, NC_NOWRITE|NC_SHARE, &exoid)) != NC_NOERR)
#endif
	{
	  /* NOTE: netCDF returns an id of -1 on an error - but no error code! */
	  if (status == 0) {
	    exerrval = EX_FATAL;
	  }
	  else {
	    /* It is possible that the user is trying to open a netcdf4
	       file, but the netcdf4 capabilities aren't available in the
	       netcdf linked to this library. Note that we can't just use a
	       compile-time define since we could be using a shareable
	       netcdf library, so the netcdf4 capabilities aren't known
	       until runtime...
	  
	       Netcdf-4.X does not (yet?) have a function that can be
	       queried to determine whether the library being used was
	       compiled with --enable-netcdf4, so that isn't very
	       helpful.. 

	       At this time, query the beginning of the file and see if it
	       is an HDF-5 file and if it is assume that the open failure
	       is due to the netcdf library not enabling netcdf4 features...
	    */
	    int type = 0;
	    ex_check_file_type(path, &type);
	  
	    if (type == 5) {
	      /* This is an hdf5 (netcdf4) file. Since the nc_open failed,
		 the assumption is that the netcdf doesn't have netcdf4
		 capabilities enabled.  Tell the user...
	      */
	      fprintf(stderr,
		      "EXODUS: Error: Attempting to open the netcdf-4 file:\n\t'%s'\n\twith a netcdf library that does not support netcdf-4\n",
		      path);
	    }
	    exerrval = status;
	  }
	  sprintf(errmsg,"Error: failed to open %s read only",path);
	  ex_err("ex_open",errmsg,exerrval); 
	  return(EX_FATAL);
	} 
  }
  else /* (mode & EX_WRITE) READ/WRITE */
    {
#if defined(__LIBCATAMOUNT__)
      if ((status = nc_open (path, NC_WRITE, &exoid)) != NC_NOERR)
#else
	if ((status = nc_open (path, NC_WRITE|NC_SHARE, &exoid)) != NC_NOERR)
#endif
	  {
	    /* NOTE: netCDF returns an id of -1 on an error - but no error code! */
	    if (status == 0)
	      exerrval = EX_FATAL;
	    else
	      exerrval = status;
	    sprintf(errmsg,"Error: failed to open %s write only",path);
	    ex_err("ex_open",errmsg,exerrval); 
	    return(EX_FATAL);
	  } 

      /* turn off automatic filling of netCDF variables */
      if ((status = nc_set_fill (exoid, NC_NOFILL, &old_fill)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to set nofill mode in file id %d",
		exoid);
	ex_err("ex_open", errmsg, exerrval);
	return (EX_FATAL);
      }

      stat_att = nc_inq_att(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, &att_type, &att_len);
      stat_dim = nc_inq_dimid(exoid, DIM_STR_NAME, &dim_str_name);
      if(stat_att != NC_NOERR || stat_dim != NC_NOERR) {
	nc_redef(exoid);
	if (stat_att != NC_NOERR) {
	  int max_so_far = 32;
	  nc_put_att_int(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, NC_INT, 1, &max_so_far);
	}

	/* If the DIM_STR_NAME variable does not exist on the database, we need to add it now. */
	if(stat_dim != NC_NOERR) {
	  /* Not found; set to default value of 32+1. */
	  int max_name = ex_default_max_name_length < 32 ? 32 : ex_default_max_name_length;
	  nc_def_dim(exoid, DIM_STR_NAME, max_name+1, &dim_str_name);
	}
	nc_enddef (exoid);
      }
    }

  /* determine version of EXODUS II file, and the word size of
   * floating point and integer values stored in the file
   */

  if ((status = nc_get_att_float(exoid, NC_GLOBAL, ATT_VERSION, version)) != NC_NOERR) {
    exerrval  = status;
    sprintf(errmsg,"Error: failed to get database version for file id: %d",
	    exoid);
    ex_err("ex_open",errmsg,exerrval);
    return(EX_FATAL);
  }
   
  /* check ExodusII file version - old version 1.x files are not supported */
  if (*version < 2.0) {
    exerrval  = EX_FATAL;
    sprintf(errmsg,"Error: Unsupported file version %.2f in file id: %d",
	    *version, exoid);
    ex_err("ex_open",errmsg,exerrval);
    return(EX_FATAL);
  }
   
  if (nc_get_att_int (exoid, NC_GLOBAL, ATT_FLT_WORDSIZE, &file_wordsize) != NC_NOERR)
    {  /* try old (prior to db version 2.02) attribute name */
      if (nc_get_att_int (exoid,NC_GLOBAL,ATT_FLT_WORDSIZE_BLANK,&file_wordsize) != NC_NOERR)
	{
	  exerrval  = EX_FATAL;
	  sprintf(errmsg,"Error: failed to get file wordsize from file id: %d",
		  exoid);
	  ex_err("ex_open",errmsg,exerrval);
	  return(exerrval);
	}
    }

  /* See if int64 status attribute exists and if so, what data is stored as int64 
   * Older files don't have the attribute, so it is not an error if it is missing
   */
  if (nc_get_att_int (exoid, NC_GLOBAL, ATT_INT64_STATUS, &int64_status) != NC_NOERR) {
    int64_status = 0; /* Just in case it gets munged by a failed get_att_int call */
  }
  
  /* Merge in API int64 status flags as specified by caller of function... */
  int64_status |= (mode & EX_ALL_INT64_API);
  
  /* initialize floating point and integer size conversion. */
  if (ex_conv_ini( exoid, comp_ws, io_ws, file_wordsize, int64_status ) != EX_NOERR ) {
    exerrval = EX_FATAL;
    sprintf(errmsg,
	    "Error: failed to initialize conversion routines in file id %d",
            exoid);
    ex_err("ex_open", errmsg, exerrval);
    return (EX_FATAL);
  }

  return (exoid);
}
Example #4
0
int ex_open (const char  *path,
             int    mode,
             int   *comp_ws,
             int   *io_ws,
             float *version)
{
   int exoid;
   nclong file_wordsize;
   char errmsg[MAX_ERR_LENGTH];

  exerrval = 0; /* clear error code */
 
/* set error handling mode to no messages, non-fatal errors */
  ex_opts(exoptval);    /* call required to set ncopts first time through */


  if (mode == EX_READ)  /* READ ONLY */
  {
#if defined(__LIBCATAMOUNT__)
    if ((exoid = ncopen (path, NC_NOWRITE)) < 0)
#else
    if ((exoid = ncopen (path, NC_NOWRITE|NC_SHARE)) < 0)
#endif
    {
      /* NOTE: netCDF returns an id of -1 on an error - but no error code! */
      if (ncerr == 0)
        exerrval = EX_FATAL;
      else
        exerrval = ncerr;
      sprintf(errmsg,"Error: failed to open %s read only",path);
      ex_err("ex_open",errmsg,exerrval); 
      return(EX_FATAL);
    } 
  }

  else if (mode == EX_WRITE) /* READ/WRITE */
  {
#if defined(__LIBCATAMOUNT__)
    if ((exoid = ncopen (path, NC_WRITE)) < 0)
#else
    if ((exoid = ncopen (path, NC_WRITE|NC_SHARE)) < 0)
#endif
    {
      /* NOTE: netCDF returns an id of -1 on an error - but no error code! */
      if (ncerr == 0)
        exerrval = EX_FATAL;
      else
        exerrval = ncerr;
      sprintf(errmsg,"Error: failed to open %s write only",path);
      ex_err("ex_open",errmsg,exerrval); 
      return(EX_FATAL);
    } 

    /* turn off automatic filling of netCDF variables */

    if (ncsetfill (exoid, NC_NOFILL) == -1)
    {
      exerrval = ncerr;
      sprintf(errmsg,
             "Error: failed to set nofill mode in file id %d",
              exoid);
      ex_err("ex_open", errmsg, exerrval);
      return (EX_FATAL);
    }
  }
  else 
  {
    exerrval = EX_BADFILEMODE;
    sprintf(errmsg,"Error: invalid file open mode: %d",mode);
    ex_err("ex_open",errmsg,exerrval); 
    return (EX_FATAL);
  }

/* determine version of EXODUS II file, and the word size of
 * floating point values stored in the file
 */

   if (ncattget (exoid, NC_GLOBAL, ATT_VERSION, version) == -1)
   {
     exerrval  = ncerr;
     sprintf(errmsg,"Error: failed to get database version for file id: %d",
             exoid);
     ex_err("ex_open",errmsg,exerrval);
     return(EX_FATAL);
   }
   
/* check ExodusII file version - old version 1.x files are not supported */
   if (*version < 2.0)
   {
     exerrval  = EX_FATAL;
     sprintf(errmsg,"Error: Unsupported file version %.2f in file id: %d",
             *version, exoid);
     ex_err("ex_open",errmsg,exerrval);
     return(EX_FATAL);
   }
   
   if (ncattget (exoid, NC_GLOBAL, ATT_FLT_WORDSIZE, &file_wordsize) == -1)
   {  /* try old (prior to db version 2.02) attribute name */
     if (ncattget (exoid,NC_GLOBAL,ATT_FLT_WORDSIZE_BLANK,&file_wordsize) == -1)
     {
       exerrval  = EX_FATAL;
       sprintf(errmsg,"Error: failed to get file wordsize from file id: %d",
             exoid);
       ex_err("ex_open",errmsg,exerrval);
       return(exerrval);
     }
   }

/* initialize floating point size conversion.
 */

   if (ex_conv_ini( exoid, comp_ws, io_ws, file_wordsize ) != EX_NOERR ) {
     exerrval = EX_FATAL;
     sprintf(errmsg,
           "Error: failed to init conversion routines in file id %d",
            exoid);
     ex_err("ex_open", errmsg, exerrval);
     return (EX_FATAL);
   }

   return (exoid);
}
Example #5
0
File: excre.c Project: hpcdev/xdm
int ex_create_int (const char *path,
		   int   cmode,
		   int  *comp_ws,
		   int  *io_ws,
		   int   run_version)
{
  int exoid, time_dim, dims[1];
  int status;
  int dimid;
  int old_fill;
  int lio_ws;
  int filesiz;
  float vers;
  char errmsg[MAX_ERR_LENGTH];
  char *mode_name;
  int mode = 0;
#if defined(NC_NETCDF4)
  static int netcdf4_mode = -1;
  char *option;
#endif /* NC_NETCDF4 */
   
  exerrval = 0; /* clear error code */

  if (run_version != EX_API_VERS_NODOT) {
    int run_version_major = run_version / 100;
    int run_version_minor = run_version % 100;
    int lib_version_major = EX_API_VERS_NODOT / 100;
    int lib_version_minor = EX_API_VERS_NODOT % 100;
    fprintf(stderr, "EXODUSII: Warning: This code was compiled with exodusII version %d.%02d,\n          but was linked with exodusII library version %d.%02d\n          This is probably an error in the build process of this code.\n",
	    run_version_major, run_version_minor, lib_version_major, lib_version_minor);
  }
#if defined(NC_NETCDF4)
  if (cmode & EX_NETCDF4) {
    mode |= (NC_NETCDF4|NC_CLASSIC_MODEL);
  } else {
    if (netcdf4_mode == -1) {
      option = getenv("EXODUS_NETCDF4");
      if (option != NULL) {
	fprintf(stderr, "EXODUSII: Using netcdf version 4 selected via EXODUS_NETCDF4 environment variable\n");
	netcdf4_mode = NC_NETCDF4|NC_CLASSIC_MODEL;
      } else {
	netcdf4_mode = 0;
      }
    }
    mode |= netcdf4_mode;
  }
#endif

  /*
   * See if "large file" mode was specified in a ex_create cmode. If
   * so, then pass the NC_64BIT_OFFSET flag down to netcdf.
   * If netcdf4 mode specified, don't use NC_64BIT_OFFSET mode.
   */
  if ( (cmode & EX_LARGE_MODEL) && (cmode & EX_NORMAL_MODEL)) {
    exerrval = EX_BADPARAM;
    sprintf(errmsg,
	    "Warning: conflicting mode specification for file %s, mode %d. Using normal",
	    path, cmode);
    ex_err("ex_create",errmsg,exerrval);
  }
  if ((cmode & EX_NORMAL_MODEL) != 0)
    filesiz = 0;
#if defined(NC_NETCDF4)
  else if ((mode & NC_NETCDF4) != 0)
    filesiz = 1;
#endif
  else 
    filesiz = (int)(((cmode & EX_LARGE_MODEL) != 0) || (ex_large_model(-1) == 1));

  if (
#if defined(NC_NETCDF4)
      !(mode & NC_NETCDF4) &&
#endif
      filesiz == 1) {
    mode |= NC_64BIT_OFFSET;
  }

  if (cmode & EX_SHARE) {
    mode |= NC_SHARE;
  }

  /*
   * set error handling mode to no messages, non-fatal errors
   */
  ex_opts(exoptval);    /* call required to set ncopts first time through */

  if (cmode & EX_CLOBBER) {
    mode |= NC_CLOBBER;
    mode_name = "CLOBBER";
  } else {
    mode |= NC_NOCLOBBER;
    mode_name = "NOCLOBBER";
  }

  if ((status = nc_create (path, mode, &exoid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: file create failed for %s, mode: %s",
	    path, mode_name);
    ex_err("ex_create",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* turn off automatic filling of netCDF variables
   */

  if ((status = nc_set_fill (exoid, NC_NOFILL, &old_fill)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to set nofill mode in file id %d",
	    exoid);
    ex_err("ex_create", errmsg, exerrval);
    return (EX_FATAL);
  }

  /* initialize floating point size conversion.  since creating new file, 
   * i/o wordsize attribute from file is zero.
   */

  if (ex_conv_ini( exoid, comp_ws, io_ws, 0 ) != EX_NOERR) {
    exerrval = EX_FATAL;
    sprintf(errmsg,
	    "Error: failed to init conversion routines in file id %d",
            exoid);
    ex_err("ex_create", errmsg, exerrval);
    return (EX_FATAL);
  }

  /* put the EXODUS version number, and i/o floating point word size as
   * netcdf global attributes
   */

  /* store Exodus API version # as an attribute */
  vers = EX_API_VERS;
  if ((status=nc_put_att_float(exoid, NC_GLOBAL, ATT_API_VERSION,
			       NC_FLOAT, 1, &vers)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to store Exodus II API version attribute in file id %d",
	    exoid);
    ex_err("ex_create",errmsg, exerrval);
    return (EX_FATAL);
  }
   
  /* store Exodus file version # as an attribute */
  vers = EX_VERS;
  if ((status=nc_put_att_float(exoid, NC_GLOBAL, ATT_VERSION, NC_FLOAT, 1, &vers)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to store Exodus II file version attribute in file id %d",
	    exoid);
    ex_err("ex_create",errmsg, exerrval);
    return (EX_FATAL);
  }

  /* store Exodus file float word size  as an attribute */
  lio_ws = (int)(*io_ws);
  if ((status=nc_put_att_int (exoid, NC_GLOBAL, ATT_FLT_WORDSIZE, NC_INT, 1, &lio_ws)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to store Exodus II file float word size attribute in file id %d",
	    exoid);
    ex_err("ex_create",errmsg, exerrval);
    return (EX_FATAL);
  }

  /* store Exodus file size (1=large, 0=normal) as an attribute */
  if ((status = nc_put_att_int (exoid, NC_GLOBAL, ATT_FILESIZE, NC_INT, 1, &filesiz)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to store Exodus II file size attribute in file id %d",
	    exoid);
    ex_err("ex_create",errmsg, exerrval);
    return (EX_FATAL);
  }
  
  /* define some dimensions and variables
   */
  
  /* create string length dimension */
  if ((status=nc_def_dim (exoid, DIM_STR, (MAX_STR_LENGTH+1), &dimid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to define string length in file id %d",exoid);
    ex_err("ex_create",errmsg,exerrval);
    return (EX_FATAL);
  }


  /* create line length dimension */
  if ((status = nc_def_dim(exoid, DIM_LIN, (MAX_LINE_LENGTH+1), &dimid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to define line length in file id %d",exoid);
    ex_err("ex_create",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* create number "4" dimension; must be of type long */
  if ((status = nc_def_dim(exoid, DIM_N4, 4L, &dimid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to define number \"4\" dimension in file id %d",exoid);
    ex_err("ex_create",errmsg,exerrval);
    return (EX_FATAL);
  }


  if ((status = nc_def_dim(exoid, DIM_TIME, NC_UNLIMITED, &time_dim)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to define time dimension in file id %d", exoid);
    ex_err("ex_create",errmsg,exerrval);
    return (EX_FATAL);
  }

  dims[0] = time_dim;
  if ((status = nc_def_var(exoid, VAR_WHOLE_TIME, nc_flt_code(exoid), 1, dims, &dimid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to define whole time step variable in file id %d",
	    exoid);
    ex_err("ex_create",errmsg,exerrval);
    return (EX_FATAL);
  }

  if ((status = nc_enddef (exoid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to complete definition for file id %d", exoid);
    ex_err("ex_create",errmsg,exerrval);
    return (EX_FATAL);
  }

  return (exoid);
}
Example #6
0
int ex_create_par_int(const char *path, int cmode, int *comp_ws, int *io_ws, MPI_Comm comm,
                      MPI_Info info, int run_version)
{
  int   exoid;
  int   status;
  int   dimid;
  int   old_fill;
  int   lio_ws;
  int   filesiz;
  float vers;
  char  errmsg[MAX_ERR_LENGTH];
  char *mode_name;
  int   nc_mode = 0;

  int         int64_status;
  const char *routine    = "ex_create_par";
  int         pariomode  = 0;
  int         is_mpiio   = 0;
  int         is_pnetcdf = 0;

  unsigned int my_mode = cmode;

  /* Contains a 1 in all bits corresponding to file modes */
  static unsigned int all_modes = EX_NORMAL_MODEL | EX_64BIT_OFFSET | EX_64BIT_DATA | EX_NETCDF4;

  exerrval = 0; /* clear error code */

#if !NC_HAS_PARALLEL
  /* Library does NOT support parallel output via netcdf-4 or pnetcdf */
  exerrval = EX_BADPARAM;
  snprintf(errmsg, MAX_ERR_LENGTH, "EXODUS: ERROR: Parallel output requires the netcdf-4 and/or "
                                   "pnetcdf library format, but this netcdf library does not "
                                   "support either.\n");
  ex_err(routine, errmsg, exerrval);
  return (EX_FATAL);
#endif

  if (run_version != EX_API_VERS_NODOT && warning_output == 0) {
    int run_version_major = run_version / 100;
    int run_version_minor = run_version % 100;
    int lib_version_major = EX_API_VERS_NODOT / 100;
    int lib_version_minor = EX_API_VERS_NODOT % 100;
    fprintf(stderr, "EXODUS: Warning: This code was compiled with exodusII "
                    "version %d.%02d,\n          but was linked with exodusII "
                    "library version %d.%02d\n          This is probably an "
                    "error in the build process of this code.\n",
            run_version_major, run_version_minor, lib_version_major, lib_version_minor);
    warning_output = 1;
  }

/*
 * See if specified mode is supported in the version of netcdf we
 * are using
 */
#if !NC_HAS_HDF5
  if (my_mode & EX_NETCDF4) {
    exerrval = EX_BADPARAM;
    snprintf(errmsg, MAX_ERR_LENGTH, "EXODUS: ERROR: File format specified as netcdf-4, but the "
                                     "NetCDF library being used was not configured to enable "
                                     "this format\n");
    ex_err(routine, errmsg, exerrval);
    return (EX_FATAL);
  }
#endif

#if !defined(NC_64BIT_DATA)
  if (my_mode & EX_64BIT_DATA) {
    exerrval = EX_BADPARAM;
    snprintf(errmsg, MAX_ERR_LENGTH, "EXODUS: ERROR: File format specified as 64bit_data, but "
                                     "the NetCDF library being used does not support this "
                                     "format\n");
    ex_err(routine, errmsg, exerrval);
    return (EX_FATAL);
  }
#endif

  /* Check that one and only one format mode is specified... */
  {
    unsigned int set_modes = all_modes & my_mode;

    if (set_modes == 0) {
      my_mode |= EX_64BIT_OFFSET; /* Default if nothing specified */
    }
    else {
      /* Checks that only a single bit is set */
      set_modes = set_modes && !(set_modes & (set_modes - 1));
      if (!set_modes) {
        exerrval = EX_BADPARAM;
        snprintf(errmsg, MAX_ERR_LENGTH, "EXODUS: ERROR: More than 1 file format "
                                         "(EX_NORMAL_MODEL, EX_LARGE_MODEL, EX_64BIT_OFFSET, "
                                         "EX_64BIT_DATA, or EX_NETCDF4)\nwas specified in the "
                                         "mode argument of the ex_create call. Only a single "
                                         "format can be specified.\n");
        ex_err(routine, errmsg, exerrval);
        return (EX_FATAL);
      }
    }
  }

  /*
   * See if any integer data is to be stored as int64 (long long). If
   * so, then need to set NC_NETCDF4 and unset NC_CLASSIC_MODEL (or
   * set EX_NOCLASSIC.  Output meaningful error message if the library
   * is not NetCDF-4 enabled...
   *
   * As of netcdf-4.4.0, can also use NC_64BIT_DATA (CDF5) mode for this...
   */
  int64_status = my_mode & (EX_ALL_INT64_DB | EX_ALL_INT64_API);

  if ((int64_status & EX_ALL_INT64_DB) != 0) {
#if NC_HAS_HDF5 || defined(NC_64BIT_DATA)
    /* Library DOES support netcdf4 and/or cdf5 ... See if user
     * specified either of these and use that one; if not, pick
     * netcdf4, non-classic as default.
     */
    if (my_mode & EX_NETCDF4) {
      my_mode |= EX_NOCLASSIC;
    }
#if defined(NC_64BIT_DATA)
    else if (my_mode & EX_64BIT_DATA) {
      ; /* Do nothing, already set */
    }
#endif
    else {
      /* Unset the current mode so we don't have multiples specified */
      /* ~all_modes sets to 1 all bits not associated with file format */
      my_mode &= ~all_modes;
#if NC_HAS_HDF5
      /* Pick netcdf4 as default mode for 64-bit integers */
      my_mode |= EX_NOCLASSIC;
      my_mode |= EX_NETCDF4;
#else
      /* Pick 64bit_data as default mode for 64-bit integers */
      my_mode |= EX_64BIT_DATA;
#endif
    }
#else
    /* Library does NOT support netcdf4 or cdf5 */
    exerrval = EX_BADPARAM;
    snprintf(errmsg, MAX_ERR_LENGTH, "EXODUS: ERROR: 64-bit integer storage requested, but the "
                                     "netcdf library does not support the required netcdf-4 or "
                                     "64BIT_DATA extensions.\n");
    ex_err(routine, errmsg, exerrval);
    return (EX_FATAL);
#endif
  }

  /* Check parallel io mode.  Valid is NC_MPIPOSIX or NC_MPIIO or NC_PNETCDF
   * Exodus uses different flag values; map to netcdf values
   */
  {
    int tmp_mode = 0;
    if (my_mode & EX_MPIPOSIX) {
      pariomode = NC_MPIPOSIX;
      tmp_mode  = EX_NETCDF4;
#if !NC_HAS_HDF5
      exerrval = EX_BADPARAM;
      snprintf(errmsg, MAX_ERR_LENGTH, "EXODUS: ERROR: EX_MPIPOSIX parallel output requested "
                                       "which requires NetCDF-4 support, but the library does "
                                       "not have that option enabled.\n");
      ex_err(routine, errmsg, exerrval);
      return (EX_FATAL);
#endif
    }
    else if (my_mode & EX_MPIIO) {
      pariomode = NC_MPIIO;
      is_mpiio  = 1;
      tmp_mode  = EX_NETCDF4;
#if !NC_HAS_HDF5
      exerrval = EX_BADPARAM;
      snprintf(errmsg, MAX_ERR_LENGTH, "EXODUS: ERROR: EX_MPIIO parallel output requested which "
                                       "requires NetCDF-4 support, but the library does not "
                                       "have that option enabled.\n");
      ex_err(routine, errmsg, exerrval);
      return (EX_FATAL);
#endif
    }
    else if (my_mode & EX_PNETCDF) {
      pariomode  = NC_PNETCDF;
      is_pnetcdf = 1;
      /* See if client specified 64-bit or not... */
      if ((int64_status & EX_ALL_INT64_DB) != 0) {
        tmp_mode = EX_64BIT_DATA;
      }
      else {
        tmp_mode = EX_64BIT_OFFSET;
      }
#if !NC_HAS_PNETCDF
      exerrval = EX_BADPARAM;
      snprintf(errmsg, MAX_ERR_LENGTH, "EXODUS: ERROR: EX_PNETCDF parallel output requested "
                                       "which requires PNetCDF support, but the library does "
                                       "not have that option enabled.\n");
      ex_err(routine, errmsg, exerrval);
      return (EX_FATAL);
#endif
    }

    /* If tmp_mode was set here, then need to clear any other mode that
       was potentially already set in my_mode... */
    my_mode &= ~all_modes;
    my_mode |= tmp_mode;
  }

  if (my_mode & EX_NETCDF4) {
    nc_mode |= NC_NETCDF4;
  }

  if (!(my_mode & EX_NOCLASSIC)) {
    nc_mode |= NC_CLASSIC_MODEL;
  }

  /*
   * See if "large file" mode was specified in a ex_create my_mode. If
   * so, then pass the NC_64BIT_OFFSET flag down to netcdf.
   * If netcdf4 mode specified, don't use NC_64BIT_OFFSET mode.
   */
  if (my_mode & EX_NORMAL_MODEL) {
    filesiz = 0;
#if NC_HAS_HDF5
  }
  else if (nc_mode & NC_NETCDF4) {
    filesiz = 1;
#endif
#if defined(NC_64BIT_DATA)
  }
  else if (nc_mode & NC_64BIT_DATA) {
    filesiz = 1;
#endif
  }
  else {
    filesiz = (int)((my_mode & EX_64BIT_OFFSET) || (ex_large_model(-1) == 1));
  }

  if (
#if NC_HAS_HDF5
      !(nc_mode & NC_NETCDF4) &&
#endif
#if defined(NC_64BIT_DATA)
      !(nc_mode & NC_64BIT_DATA) &&
#endif
      filesiz == 1) {
    nc_mode |= NC_64BIT_OFFSET;
  }

  if (my_mode & EX_SHARE) {
    nc_mode |= NC_SHARE;
  }

  /*
   * set error handling mode to no messages, non-fatal errors
   */
  ex_opts(exoptval); /* call required to set ncopts first time through */

  if (my_mode & EX_CLOBBER) {
    nc_mode |= NC_CLOBBER;
    mode_name = "CLOBBER";
  }
  else {
    nc_mode |= NC_NOCLOBBER;
    mode_name = "NOCLOBBER";
  }

#if defined NC_IGNORE_MAX_DIMS
  nc_mode |= NC_IGNORE_MAX_DIMS;
#endif

#if defined NC_IGNORE_MAX_VARS
  nc_mode |= NC_IGNORE_MAX_VARS;
#endif

  if ((status = nc_create_par(path, nc_mode | pariomode, comm, info, &exoid)) != NC_NOERR) {
    exerrval = status;
#if NC_HAS_HDF5
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: file create failed for %s, mode: %s", path, mode_name);
#else
    if (my_mode & EX_NETCDF4) {
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: file create failed for %s in NETCDF4 and %s "
                                       "mode.\n\tThis library does not support netcdf-4 files.",
               path, mode_name);
    }
    else {
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: file create failed for %s, mode: %s", path,
               mode_name);
    }
#endif
    ex_err(routine, errmsg, exerrval);
    return (EX_FATAL);
  }

  /* turn off automatic filling of netCDF variables */

  if ((status = nc_set_fill(exoid, NC_NOFILL, &old_fill)) != NC_NOERR) {
    exerrval = status;
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to set nofill mode in file id %d", exoid);
    ex_err(routine, errmsg, exerrval);
    return (EX_FATAL);
  }

  /* Verify that there is not an existing file_item struct for this
     exoid This could happen (and has) when application calls
     ex_open(), but then closes file using nc_close() and then reopens
     file.  NetCDF will possibly reuse the exoid which results in
     internal corruption in exodus data structures since exodus does
     not know that file was closed and possibly new file opened for
     this exoid
  */
  if (ex_find_file_item(exoid) != NULL) {
    char errmsg[MAX_ERR_LENGTH];
    exerrval = EX_BADFILEID;
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: There is an existing file already using the file "
                                     "id %d which was also assigned to file %s.\n\tWas "
                                     "nc_close() called instead of ex_close() on an open Exodus "
                                     "file?\n",
             exoid, path);
    ex_err(routine, errmsg, exerrval);
    nc_close(exoid);
    return (EX_FATAL);
  }

  /* initialize floating point size conversion.  since creating new file,
   * i/o wordsize attribute from file is zero.
   */
  if (ex_conv_ini(exoid, comp_ws, io_ws, 0, int64_status, 1, is_mpiio, is_pnetcdf) != EX_NOERR) {
    exerrval = EX_FATAL;
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to init conversion routines in file id %d",
             exoid);
    ex_err(routine, errmsg, exerrval);
    return (EX_FATAL);
  }

  /* put the EXODUS version number, and i/o floating point word size as
   * netcdf global attributes
   */

  /* store Exodus API version # as an attribute */
  vers = EX_API_VERS;
  if ((status = nc_put_att_float(exoid, NC_GLOBAL, ATT_API_VERSION, NC_FLOAT, 1, &vers)) !=
      NC_NOERR) {
    exerrval = status;
    snprintf(errmsg, MAX_ERR_LENGTH,
             "ERROR: failed to store Exodus II API version attribute in file id %d", exoid);
    ex_err(routine, errmsg, exerrval);
    return (EX_FATAL);
  }

  /* store Exodus file version # as an attribute */
  vers = EX_VERS;
  if ((status = nc_put_att_float(exoid, NC_GLOBAL, ATT_VERSION, NC_FLOAT, 1, &vers)) != NC_NOERR) {
    exerrval = status;
    snprintf(errmsg, MAX_ERR_LENGTH,
             "ERROR: failed to store Exodus II file version attribute in file id %d", exoid);
    ex_err(routine, errmsg, exerrval);
    return (EX_FATAL);
  }

  /* store Exodus file float word size  as an attribute */
  lio_ws = (int)(*io_ws);
  if ((status = nc_put_att_int(exoid, NC_GLOBAL, ATT_FLT_WORDSIZE, NC_INT, 1, &lio_ws)) !=
      NC_NOERR) {
    exerrval = status;
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to store Exodus II file float word size "
                                     "attribute in file id %d",
             exoid);
    ex_err(routine, errmsg, exerrval);
    return (EX_FATAL);
  }

  /* store Exodus file size (1=large, 0=normal) as an attribute */
  if ((status = nc_put_att_int(exoid, NC_GLOBAL, ATT_FILESIZE, NC_INT, 1, &filesiz)) != NC_NOERR) {
    exerrval = status;
    snprintf(errmsg, MAX_ERR_LENGTH,
             "ERROR: failed to store Exodus II file size attribute in file id %d", exoid);
    ex_err(routine, errmsg, exerrval);
    return (EX_FATAL);
  }

  {
    int max_so_far = 32;
    if ((status = nc_put_att_int(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, NC_INT, 1, &max_so_far)) !=
        NC_NOERR) {
      exerrval = status;
      snprintf(errmsg, MAX_ERR_LENGTH,
               "ERROR: failed to add maximum_name_length attribute in file id %d", exoid);
      ex_err(routine, errmsg, exerrval);
      return (EX_FATAL);
    }
  }

  /* define some dimensions and variables */

  /* create string length dimension */
  if ((status = nc_def_dim(exoid, DIM_STR, (MAX_STR_LENGTH + 1), &dimid)) != NC_NOERR) {
    exerrval = status;
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to define string length in file id %d", exoid);
    ex_err(routine, errmsg, exerrval);
    return (EX_FATAL);
  }

  /* The name string length dimension is delayed until the ex_put_init function
   */

  /* create line length dimension */
  if ((status = nc_def_dim(exoid, DIM_LIN, (MAX_LINE_LENGTH + 1), &dimid)) != NC_NOERR) {
    exerrval = status;
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to define line length in file id %d", exoid);
    ex_err(routine, errmsg, exerrval);
    return (EX_FATAL);
  }

  /* create number "4" dimension; must be of type long */
  if ((status = nc_def_dim(exoid, DIM_N4, 4L, &dimid)) != NC_NOERR) {
    exerrval = status;
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to define number \"4\" dimension in file id %d",
             exoid);
    ex_err(routine, errmsg, exerrval);
    return (EX_FATAL);
  }

  {
    int int64_db_status = int64_status & EX_ALL_INT64_DB;
    if ((status = nc_put_att_int(exoid, NC_GLOBAL, ATT_INT64_STATUS, NC_INT, 1,
                                 &int64_db_status)) != NC_NOERR) {
      exerrval = status;
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to add int64_status attribute in file id %d",
               exoid);
      ex_err(routine, errmsg, exerrval);
      return (EX_FATAL);
    }
  }

  if ((status = nc_enddef(exoid)) != NC_NOERR) {
    exerrval = status;
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to complete definition for file id %d", exoid);
    ex_err(routine, errmsg, exerrval);
    return (EX_FATAL);
  }

  return (exoid);
}
Example #7
0
int ex_create_par_int (const char *path,
		       int   cmode,
		       int  *comp_ws,
		       int  *io_ws,
		       MPI_Comm comm,
		       MPI_Info info,
		       int   run_version)
{
  int exoid, dims[1];
  int status;
  int dimid, time_dim;
  int old_fill;
  int lio_ws;
  int filesiz;
  float vers;
  char errmsg[MAX_ERR_LENGTH];
  char *mode_name;
  int mode = 0;
   
  int int64_status;
  int pariomode = 0;

  unsigned int my_mode = cmode;
  assert(my_mode == cmode);
  exerrval = 0; /* clear error code */

#if !defined(NC_NETCDF4)
    /* Library does NOT support netcdf4 */
    exerrval = EX_BADPARAM;
    sprintf(errmsg,
	    "EXODUS: Error: Parallel output requires the netcdf-4 library format, but this netcdf library does not support that.\n");
    ex_err("ex_create_par",errmsg,exerrval);
    return (EX_FATAL);
#endif

  if (run_version != EX_API_VERS_NODOT && warning_output == 0) {
    int run_version_major = run_version / 100;
    int run_version_minor = run_version % 100;
    int lib_version_major = EX_API_VERS_NODOT / 100;
    int lib_version_minor = EX_API_VERS_NODOT % 100;
    fprintf(stderr, "EXODUS: Warning: This code was compiled with exodusII version %d.%02d,\n          but was linked with exodusII library version %d.%02d\n          This is probably an error in the build process of this code.\n",
	    run_version_major, run_version_minor, lib_version_major, lib_version_minor);
    warning_output = 1;
  }

  /*
   * See if any integer data is to be stored as int64 (long long). If
   * so, then need to set NC_NETCDF4 and unset NC_CLASSIC_MODEL (or
   * set EX_NOCLASSIC.  Output meaningful error message if the library
   * is not NetCDF-4 enabled...
   */
  int64_status = my_mode & (EX_ALL_INT64_DB | EX_ALL_INT64_API);
  
  if ((int64_status & EX_ALL_INT64_DB) != 0) {
    /* Library DOES support netcdf4... Set modes required to use
     * netcdf-4 in non-classic mode
     */
    my_mode |= EX_NOCLASSIC;
    my_mode |= EX_NETCDF4;
  }

  /* Check parallel io mode.  Valid is NC_MPIPOSIX or NC_MPIIO or NC_PNETCDF
   * Exodus uses different flag values; map to netcdf values
   */
  if (my_mode & EX_MPIPOSIX) {
    pariomode = NC_MPIPOSIX;
    my_mode |= EX_NETCDF4;
  }
  else if (my_mode & EX_MPIIO) {
    pariomode = NC_MPIIO;
    my_mode |= EX_NETCDF4;
  }
  else if (my_mode & EX_PNETCDF) {
    pariomode = NC_PNETCDF;
    mode |= NC_64BIT_OFFSET;
  }

  if (my_mode & EX_NETCDF4) {
    mode |= NC_NETCDF4;
  }

  if (! (my_mode & EX_NOCLASSIC)) {
    mode |= NC_CLASSIC_MODEL;
  }

  /*
   * See if "large file" mode was specified in a ex_create my_mode. If
   * so, then pass the NC_64BIT_OFFSET flag down to netcdf.
   * If netcdf4 mode specified, don't use NC_64BIT_OFFSET mode.
   */
  if ( (my_mode & EX_LARGE_MODEL) && (my_mode & EX_NORMAL_MODEL)) {
    exerrval = EX_BADPARAM;
    sprintf(errmsg,
	    "Warning: conflicting mode specification for file %s, mode %d. Using normal",
	    path, (int)my_mode);
    ex_err("ex_create",errmsg,exerrval);
  }
  filesiz = 1;
  
  if (my_mode & EX_SHARE) {
    mode |= NC_SHARE;
  }

  /*
   * set error handling mode to no messages, non-fatal errors
   */
  ex_opts(exoptval);    /* call required to set ncopts first time through */

  if (my_mode & EX_CLOBBER) {
    mode |= NC_CLOBBER;
    mode_name = "CLOBBER";
  } else {
    mode |= NC_NOCLOBBER;
    mode_name = "NOCLOBBER";
  }

  if ((status = nc_create_par (path, mode|pariomode, comm, info, &exoid)) != NC_NOERR) {
    exerrval = status;
    if (my_mode & EX_NETCDF4) {
      sprintf(errmsg,
	      "Error: file create failed for %s in NETCDF4 and %s mode.\n\tThis library probably does not support netcdf-4 files.",
	      path, mode_name);
    } else {
      sprintf(errmsg,
	      "Error: file create failed for %s, mode: %s",
	      path, mode_name);
    }
    ex_err("ex_create",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* turn off automatic filling of netCDF variables */

  if ((status = nc_set_fill (exoid, NC_NOFILL, &old_fill)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to set nofill mode in file id %d",
	    exoid);
    ex_err("ex_create", errmsg, exerrval);
    return (EX_FATAL);
  }

  /* initialize floating point size conversion.  since creating new file, 
   * i/o wordsize attribute from file is zero.
   */

  if (ex_conv_ini( exoid, comp_ws, io_ws, 0, int64_status ) != EX_NOERR) {
    exerrval = EX_FATAL;
    sprintf(errmsg,
	    "Error: failed to init conversion routines in file id %d",
            exoid);
    ex_err("ex_create", errmsg, exerrval);
    return (EX_FATAL);
  }

  /* put the EXODUS version number, and i/o floating point word size as
   * netcdf global attributes
   */

  /* store Exodus API version # as an attribute */
  vers = EX_API_VERS;
  if ((status=nc_put_att_float(exoid, NC_GLOBAL, ATT_API_VERSION,
			       NC_FLOAT, 1, &vers)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to store Exodus II API version attribute in file id %d",
	    exoid);
    ex_err("ex_create",errmsg, exerrval);
    return (EX_FATAL);
  }
   
  /* store Exodus file version # as an attribute */
  vers = EX_VERS;
  if ((status=nc_put_att_float(exoid, NC_GLOBAL, ATT_VERSION, NC_FLOAT, 1, &vers)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to store Exodus II file version attribute in file id %d",
	    exoid);
    ex_err("ex_create",errmsg, exerrval);
    return (EX_FATAL);
  }

  /* store Exodus file float word size  as an attribute */
  lio_ws = (int)(*io_ws);
  if ((status=nc_put_att_int (exoid, NC_GLOBAL, ATT_FLT_WORDSIZE, NC_INT, 1, &lio_ws)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to store Exodus II file float word size attribute in file id %d",
	    exoid);
    ex_err("ex_create",errmsg, exerrval);
    return (EX_FATAL);
  }

  /* store Exodus file size (1=large, 0=normal) as an attribute */
  if ((status = nc_put_att_int (exoid, NC_GLOBAL, ATT_FILESIZE, NC_INT, 1, &filesiz)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to store Exodus II file size attribute in file id %d",
	    exoid);
    ex_err("ex_create",errmsg, exerrval);
    return (EX_FATAL);
  }
  
  /* define some dimensions and variables
   */
  
  /* create string length dimension */
  if ((status=nc_def_dim (exoid, DIM_STR, (MAX_STR_LENGTH+1), &dimid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to define string length in file id %d",exoid);
    ex_err("ex_create",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* The name string length dimension is delayed until the ex_put_init function */

  /* create line length dimension */
  if ((status = nc_def_dim(exoid, DIM_LIN, (MAX_LINE_LENGTH+1), &dimid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to define line length in file id %d",exoid);
    ex_err("ex_create",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* create number "4" dimension; must be of type long */
  if ((status = nc_def_dim(exoid, DIM_N4, 4L, &dimid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to define number \"4\" dimension in file id %d",exoid);
    ex_err("ex_create",errmsg,exerrval);
    return (EX_FATAL);
  }

  if ((status = nc_def_dim(exoid, DIM_TIME, NC_UNLIMITED, &time_dim)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to define time dimension in file id %d", exoid);
    ex_err("ex_create",errmsg,exerrval);
    return (EX_FATAL);
  }

  dims[0] = time_dim;
  if ((status = nc_def_var(exoid, VAR_WHOLE_TIME, nc_flt_code(exoid), 1, dims, &dimid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to define whole time step variable in file id %d",
	    exoid);
    ex_err("ex_create",errmsg,exerrval);
    return (EX_FATAL);
  }
  ex_compress_variable(exoid, dimid, 2);

  {
    int int64_db_status = int64_status & EX_ALL_INT64_DB;
    if ((status=nc_put_att_int(exoid, NC_GLOBAL, ATT_INT64_STATUS, NC_INT, 1, &int64_db_status)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to add int64_status attribute in file id %d",exoid);
      ex_err("ex_put_init_ext",errmsg,exerrval);
      return (EX_FATAL);
    }
  }

  if ((status = nc_enddef (exoid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to complete definition for file id %d", exoid);
    ex_err("ex_create",errmsg,exerrval);
    return (EX_FATAL);
  }

  return (exoid);
}
Example #8
0
int ex_create_int (const char *path,
		   int   cmode,
		   int  *comp_ws,
		   int  *io_ws,
		   int   run_version)
{
  int exoid;
  int status;
  int dimid;
  int old_fill;
  int lio_ws;
  int filesiz;
  float vers;
  char errmsg[MAX_ERR_LENGTH];
  char *mode_name;
  int mode = 0;
#if defined(NC_NETCDF4)
  static int netcdf4_mode = -1;
  char *option;
#endif /* NC_NETCDF4 */
   
  int int64_status;
  unsigned int my_mode = cmode;
  assert(my_mode == cmode);
  exerrval = 0; /* clear error code */

  if (run_version != EX_API_VERS_NODOT && warning_output == 0) {
    int run_version_major = run_version / 100;
    int run_version_minor = run_version % 100;
    int lib_version_major = EX_API_VERS_NODOT / 100;
    int lib_version_minor = EX_API_VERS_NODOT % 100;
    fprintf(stderr, "EXODUS: Warning: This code was compiled with exodusII version %d.%02d,\n          but was linked with exodusII library version %d.%02d\n          This is probably an error in the build process of this code.\n",
	    run_version_major, run_version_minor, lib_version_major, lib_version_minor);
    warning_output = 1;
  }

  /*
   * See if any integer data is to be stored as int64 (long long). If
   * so, then need to set NC_NETCDF4 and unset NC_CLASSIC_MODEL (or
   * set EX_NOCLASSIC.  Output meaningful error message if the library
   * is not NetCDF-4 enabled...
   */
  int64_status = my_mode & (EX_ALL_INT64_DB | EX_ALL_INT64_API);
  
  if ((int64_status & EX_ALL_INT64_DB) != 0) {
#if defined(NC_NETCDF4)
    /* Library DOES support netcdf4... Set modes required to use
     * netcdf-4 in non-classic mode
     */
    my_mode |= EX_NOCLASSIC;
    my_mode |= EX_NETCDF4;
#else
    /* Library does NOT support netcdf4 */
    exerrval = EX_BADPARAM;
    sprintf(errmsg,
	    "EXODUS: Error: 64-bit integer storage requested, but the netcdf library does not support the required netcdf-4 extensions.\n");
    ex_err("ex_create",errmsg,exerrval);
    return (EX_FATAL);
#endif
  }

#if defined(NC_NETCDF4)
  if (my_mode & EX_NETCDF4) {
    mode |= (NC_NETCDF4);
  } else {
    if (netcdf4_mode == -1) {
      option = getenv("EXODUS_NETCDF4");
      if (option != NULL) {
	fprintf(stderr, "EXODUS: Using netcdf version 4 selected via EXODUS_NETCDF4 environment variable\n");
	netcdf4_mode = NC_NETCDF4; 
      } else {
	netcdf4_mode = 0;
      }
    }
    mode |= netcdf4_mode;
  }
  if (! (my_mode & EX_NOCLASSIC)) {
    mode |= NC_CLASSIC_MODEL;
  }
#endif

  /*
   * See if "large file" mode was specified in a ex_create my_mode. If
   * so, then pass the NC_64BIT_OFFSET flag down to netcdf.
   * If netcdf4 mode specified, don't use NC_64BIT_OFFSET mode.
   */
  if ( (my_mode & EX_LARGE_MODEL) && (my_mode & EX_NORMAL_MODEL)) {
    exerrval = EX_BADPARAM;
    sprintf(errmsg,
	    "Warning: conflicting mode specification for file %s, mode %d. Using normal",
	    path, (int)my_mode);
    ex_err("ex_create",errmsg,exerrval);
  }
  if (my_mode & EX_NORMAL_MODEL)
    filesiz = 0;
#if defined(NC_NETCDF4)
  else if (mode & NC_NETCDF4)
    filesiz = 1;
#endif
  else 
    filesiz = (int)((my_mode & EX_LARGE_MODEL) || (ex_large_model(-1) == 1));

  if (
#if defined(NC_NETCDF4)
      !(mode & NC_NETCDF4) &&
#endif
      filesiz == 1) {
    mode |= NC_64BIT_OFFSET;
  }

  if (my_mode & EX_SHARE) {
    mode |= NC_SHARE;
  }

  /*
   * set error handling mode to no messages, non-fatal errors
   */
  ex_opts(exoptval);    /* call required to set ncopts first time through */

  if (my_mode & EX_CLOBBER) {
    mode |= NC_CLOBBER;
    mode_name = "CLOBBER";
  } else {
    mode |= NC_NOCLOBBER;
    mode_name = "NOCLOBBER";
  }

  if ((status = nc_create (path, mode, &exoid)) != NC_NOERR) {
    exerrval = status;
    if (my_mode & EX_NETCDF4) {
      sprintf(errmsg,
	      "Error: file create failed for %s in NETCDF4 and %s mode.\n\tThis library probably does not support netcdf-4 files.",
	      path, mode_name);
    } else {
      sprintf(errmsg,
	      "Error: file create failed for %s, mode: %s",
	      path, mode_name);
    }
    ex_err("ex_create",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* turn off automatic filling of netCDF variables
   */

  if ((status = nc_set_fill (exoid, NC_NOFILL, &old_fill)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to set nofill mode in file id %d",
	    exoid);
    ex_err("ex_create", errmsg, exerrval);
    return (EX_FATAL);
  }

  /* initialize floating point size conversion.  since creating new file, 
   * i/o wordsize attribute from file is zero.
   */

  if (ex_conv_ini(exoid, comp_ws, io_ws, 0, int64_status, 0) != EX_NOERR) {
    exerrval = EX_FATAL;
    sprintf(errmsg,
	    "Error: failed to init conversion routines in file id %d",
            exoid);
    ex_err("ex_create", errmsg, exerrval);
    return (EX_FATAL);
  }

  /* put the EXODUS version number, and i/o floating point word size as
   * netcdf global attributes
   */

  /* store Exodus API version # as an attribute */
  vers = EX_API_VERS;
  if ((status=nc_put_att_float(exoid, NC_GLOBAL, ATT_API_VERSION,
			       NC_FLOAT, 1, &vers)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to store Exodus II API version attribute in file id %d",
	    exoid);
    ex_err("ex_create",errmsg, exerrval);
    return (EX_FATAL);
  }
   
  /* store Exodus file version # as an attribute */
  vers = EX_VERS;
  if ((status=nc_put_att_float(exoid, NC_GLOBAL, ATT_VERSION, NC_FLOAT, 1, &vers)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to store Exodus II file version attribute in file id %d",
	    exoid);
    ex_err("ex_create",errmsg, exerrval);
    return (EX_FATAL);
  }

  /* store Exodus file float word size  as an attribute */
  lio_ws = (int)(*io_ws);
  if ((status=nc_put_att_int (exoid, NC_GLOBAL, ATT_FLT_WORDSIZE, NC_INT, 1, &lio_ws)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to store Exodus II file float word size attribute in file id %d",
	    exoid);
    ex_err("ex_create",errmsg, exerrval);
    return (EX_FATAL);
  }

  /* store Exodus file size (1=large, 0=normal) as an attribute */
  if ((status = nc_put_att_int (exoid, NC_GLOBAL, ATT_FILESIZE, NC_INT, 1, &filesiz)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to store Exodus II file size attribute in file id %d",
	    exoid);
    ex_err("ex_create",errmsg, exerrval);
    return (EX_FATAL);
  }
  
  {
    int max_so_far = 32;
    if ((status=nc_put_att_int(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, NC_INT, 1, &max_so_far)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to add maximum_name_length attribute in file id %d",exoid);
      ex_err("ex_put_init_ext",errmsg,exerrval);
      return (EX_FATAL);
    }
  }

  /* define some dimensions and variables
   */
  
  /* create string length dimension */
  if ((status=nc_def_dim (exoid, DIM_STR, (MAX_STR_LENGTH+1), &dimid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to define string length in file id %d",exoid);
    ex_err("ex_create",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* The name string length dimension is delayed until the ex_put_init function */

  /* create line length dimension */
  if ((status = nc_def_dim(exoid, DIM_LIN, (MAX_LINE_LENGTH+1), &dimid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to define line length in file id %d",exoid);
    ex_err("ex_create",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* create number "4" dimension; must be of type long */
  if ((status = nc_def_dim(exoid, DIM_N4, 4L, &dimid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to define number \"4\" dimension in file id %d",exoid);
    ex_err("ex_create",errmsg,exerrval);
    return (EX_FATAL);
  }

  {
    int int64_db_status = int64_status & EX_ALL_INT64_DB;
    if ((status=nc_put_att_int(exoid, NC_GLOBAL, ATT_INT64_STATUS, NC_INT, 1, &int64_db_status)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to add int64_status attribute in file id %d",exoid);
      ex_err("ex_put_init_ext",errmsg,exerrval);
      return (EX_FATAL);
    }
  }

  if ((status = nc_enddef (exoid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to complete definition for file id %d", exoid);
    ex_err("ex_create",errmsg,exerrval);
    return (EX_FATAL);
  }

  return (exoid);
}
Example #9
0
int ex_open_par_int(const char *path, int mode, int *comp_ws, int *io_ws, float *version,
                    MPI_Comm comm, MPI_Info info, int run_version)
{
  int     exoid;
  int     status, stat_att, stat_dim;
  nc_type att_type = NC_NAT;
  size_t  att_len  = 0;
  int     nc_mode  = 0;
  int     old_fill;
  int     file_wordsize;
  int     dim_str_name;
  int     int64_status = 0;
  int     is_hdf5      = 0;
  int     is_pnetcdf   = 0;
  int     in_redef     = 0;

  char errmsg[MAX_ERR_LENGTH];

  EX_FUNC_ENTER();

  /* set error handling mode to no messages, non-fatal errors */
  ex_opts(exoptval); /* call required to set ncopts first time through */

  if (run_version != EX_API_VERS_NODOT && warning_output == 0) {
    int run_version_major = run_version / 100;
    int run_version_minor = run_version % 100;
    int lib_version_major = EX_API_VERS_NODOT / 100;
    int lib_version_minor = EX_API_VERS_NODOT % 100;
    fprintf(stderr,
            "EXODUS: Warning: This code was compiled with exodus "
            "version %d.%02d,\n          but was linked with exodus "
            "library version %d.%02d\n          This is probably an "
            "error in the build process of this code.\n",
            run_version_major, run_version_minor, lib_version_major, lib_version_minor);
    warning_output = 1;
  }

  if ((mode & EX_READ) && (mode & EX_WRITE)) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: Cannot specify both EX_READ and EX_WRITE");
    ex_err(__func__, errmsg, EX_BADFILEMODE);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  if (mode & EX_WRITE) {
    nc_mode = (NC_WRITE | NC_MPIIO);
  }
  else {
    nc_mode = (NC_NOWRITE | NC_SHARE | NC_MPIIO);
  }
  if ((status = nc_open_par(path, nc_mode, comm, info, &exoid)) != NC_NOERR) {
    /* It is possible that the user is trying to open a netcdf4
       file, but the netcdf4 capabilities aren't available in the
       netcdf linked to this library. Note that we can't just use a
       compile-time define since we could be using a shareable
       netcdf library, so the netcdf4 capabilities aren't known
       until runtime...

       Later versions of netcdf-4.X have a function that can be
       queried to determine whether the library being used was
       compiled with --enable-netcdf4, but not everyone is using that
       version yet, so we may have to do some guessing...

       At this time, query the beginning of the file and see if it
       is an HDF-5 file and if it is assume that the open failure
       is due to the netcdf library not enabling netcdf4 features unless
       we have the define that shows it is enabled, then assume other error...
    */
    int type = 0;
    ex_check_file_type(path, &type);

    if (type == 5) {
#if NC_HAS_HDF5
      fprintf(stderr,
              "EXODUS: ERROR: Attempting to open the netcdf-4 "
              "file:\n\t'%s'\n\t failed. The netcdf library supports "
              "netcdf-4 so there must be a filesystem or some other "
              "issue \n",
              path);
#else
      /* This is an hdf5 (netcdf4) file. If NC_HAS_HDF5 is not defined,
         then we either don't have hdf5 support in this netcdf version,
         OR this is an older netcdf version that doesn't provide that define.

         In either case, we don't have enough information, so we
         assume that the netcdf doesn't have netcdf4 capabilities
         enabled.  Tell the user...
      */
      fprintf(stderr,
              "EXODUS: ERROR: Attempting to open the netcdf-4 "
              "file:\n\t'%s'\n\tEither the netcdf library does not "
              "support netcdf-4 or there is a filesystem or some "
              "other issue \n",
              path);
#endif
    }
    else if (type == 4) {
#if defined(NC_64BIT_DATA)
      fprintf(stderr,
              "EXODUS: ERROR: Attempting to open the CDF5 "
              "file:\n\t'%s'\n\t failed. The netcdf library supports "
              "CDF5-type files so there must be a filesystem or some other "
              "issue \n",
              path);
#else
      /* This is an cdf5 (64BIT_DATA) file. If NC_64BIT_DATA is not defined,
         then we either don't have cdf5 support in this netcdf version,
         OR this is an older netcdf version that doesn't provide that define.

         In either case, we don't have enough information, so we
         assume that the netcdf doesn't have cdf5 capabilities
         enabled.  Tell the user...
      */
      fprintf(stderr,
              "EXODUS: ERROR: Attempting to open the CDF5 "
              "file:\n\t'%s'\n\tEither the netcdf library does not "
              "support CDF5 or there is a filesystem or some "
              "other issue \n",
              path);

#endif
    }
    else if (type == 1 || type == 2) {
#if NC_HAS_PNETCDF
      fprintf(stderr,
              "EXODUS: ERROR: Attempting to open the classic NetCDF "
              "file:\n\t'%s'\n\t failed. The netcdf library supports "
              "PNetCDF files as required for parallel readinf of this "
              "file type, so there must be a filesystem or some other "
              "issue \n",
              path);
#else
      /* This is an normal NetCDF format file, for parallel reading, the PNetCDF
         library is required but that is not compiled into this version.
      */
      fprintf(stderr,
              "EXODUS: ERROR: Attempting to open the NetCDF "
              "file:\n\t'%s'\n\tThe NetCDF library was not "
              "built with PNetCDF support as required for parallel access to this file.\n",
              path);

#endif
    }

    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to open %s of type %d read only", path, type);
    ex_err(__func__, errmsg, status);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  /* File opened correctly */
  int type = 0;
  ex_check_file_type(path, &type);
  if (type == 5) {
    is_hdf5 = 1;
  }
  else if (type == 1 || type == 2 || type == 4) {
    is_pnetcdf = 1;
  }

  if (mode & EX_WRITE) { /* Appending */
    /* turn off automatic filling of netCDF variables */
    if (is_pnetcdf) {
      if ((status = nc_redef(exoid)) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid);
        ex_err(__func__, errmsg, status);
        EX_FUNC_LEAVE(EX_FATAL);
      }
      in_redef = 1;
    }

    if ((status = nc_set_fill(exoid, NC_NOFILL, &old_fill)) != NC_NOERR) {
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to set nofill mode in file id %d", exoid);
      ex_err(__func__, errmsg, status);
      EX_FUNC_LEAVE(EX_FATAL);
    }

    stat_att = nc_inq_att(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, &att_type, &att_len);
    stat_dim = nc_inq_dimid(exoid, DIM_STR_NAME, &dim_str_name);
    if (stat_att != NC_NOERR || stat_dim != NC_NOERR) {
      if (!in_redef) {
        if ((status = nc_redef(exoid)) != NC_NOERR) {
          snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode",
                   exoid);
          ex_err(__func__, errmsg, status);
          EX_FUNC_LEAVE(EX_FATAL);
        }
        in_redef = 1;
      }
      if (stat_att != NC_NOERR) {
        int max_so_far = 32;
        nc_put_att_int(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, NC_INT, 1, &max_so_far);
      }

      /* If the DIM_STR_NAME variable does not exist on the database, we need to
       * add it now. */
      if (stat_dim != NC_NOERR) {
        /* Not found; set to default value of 32+1. */
        int max_name = ex_default_max_name_length < 32 ? 32 : ex_default_max_name_length;
        nc_def_dim(exoid, DIM_STR_NAME, max_name + 1, &dim_str_name);
      }
    }

    if (in_redef) {
      if ((status = nc_enddef(exoid)) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to complete definition in file id %d",
                 exoid);
        ex_err(__func__, errmsg, status);
        EX_FUNC_LEAVE(EX_FATAL);
      }
      in_redef = 0;
    }

    /* If this is a parallel execution and we are appending, then we
     * need to set the parallel access method for all transient variables to NC_COLLECTIVE since
     * they will be being extended.
     */
    int ndims;    /* number of dimensions */
    int nvars;    /* number of variables */
    int ngatts;   /* number of global attributes */
    int recdimid; /* id of unlimited dimension */

    int varid;

    /* Determine number of variables on the database... */
    nc_inq(exoid, &ndims, &nvars, &ngatts, &recdimid);

    for (varid = 0; varid < nvars; varid++) {
      struct ncvar var;
      nc_inq_var(exoid, varid, var.name, &var.type, &var.ndims, var.dims, &var.natts);

      if ((strcmp(var.name, VAR_GLO_VAR) == 0) || (strncmp(var.name, "vals_elset_var", 14) == 0) ||
          (strncmp(var.name, "vals_sset_var", 13) == 0) ||
          (strncmp(var.name, "vals_fset_var", 13) == 0) ||
          (strncmp(var.name, "vals_eset_var", 13) == 0) ||
          (strncmp(var.name, "vals_nset_var", 13) == 0) ||
          (strncmp(var.name, "vals_nod_var", 12) == 0) ||
          (strncmp(var.name, "vals_edge_var", 13) == 0) ||
          (strncmp(var.name, "vals_face_var", 13) == 0) ||
          (strncmp(var.name, "vals_elem_var", 13) == 0) ||
          (strcmp(var.name, VAR_WHOLE_TIME) == 0)) {
        nc_var_par_access(exoid, varid, NC_COLLECTIVE);
      }
    }
  } /* End of (mode & EX_WRITE) */

  /* determine version of EXODUS file, and the word size of
   * floating point and integer values stored in the file
   */

  if ((status = nc_get_att_float(exoid, NC_GLOBAL, ATT_VERSION, version)) != NC_NOERR) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get database version for file id: %d",
             exoid);
    ex_err(__func__, errmsg, status);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  /* check ExodusII file version - old version 1.x files are not supported */
  if (*version < 2.0) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: Unsupported file version %.2f in file id: %d",
             *version, exoid);
    ex_err(__func__, errmsg, EX_BADPARAM);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  if (nc_get_att_int(exoid, NC_GLOBAL, ATT_FLT_WORDSIZE, &file_wordsize) !=
      NC_NOERR) { /* try old (prior to db version 2.02) attribute name */
    if ((status = nc_get_att_int(exoid, NC_GLOBAL, ATT_FLT_WORDSIZE_BLANK, &file_wordsize)) !=
        NC_NOERR) {
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get file wordsize from file id: %d",
               exoid);
      ex_err(__func__, errmsg, status);
      EX_FUNC_LEAVE(EX_FATAL);
    }
  }

  /* See if int64 status attribute exists and if so, what data is stored as
   * int64
   * Older files don't have the attribute, so it is not an error if it is
   * missing
   */
  if (nc_get_att_int(exoid, NC_GLOBAL, ATT_INT64_STATUS, &int64_status) != NC_NOERR) {
    int64_status = 0; /* Just in case it gets munged by a failed get_att_int call */
  }

  /* Merge in API int64 status flags as specified by caller of function... */
  int64_status |= (mode & EX_ALL_INT64_API);

  /* Verify that there is not an existing file_item struct for this
     exoid This could happen (and has) when application calls
     ex_open(), but then closes file using nc_close() and then reopens
     file.  NetCDF will possibly reuse the exoid which results in
     internal corruption in exodus data structures since exodus does
     not know that file was closed and possibly new file opened for
     this exoid
  */
  if (ex_find_file_item(exoid) != NULL) {
    snprintf(errmsg, MAX_ERR_LENGTH,
             "ERROR: There is an existing file already using the file "
             "id %d which was also assigned to file %s.\n\tWas "
             "nc_close() called instead of ex_close() on an open Exodus "
             "file?\n",
             exoid, path);
    ex_err(__func__, errmsg, EX_BADFILEID);
    nc_close(exoid);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  /* initialize floating point and integer size conversion. */
  if (ex_conv_ini(exoid, comp_ws, io_ws, file_wordsize, int64_status, 1, is_hdf5, is_pnetcdf) !=
      EX_NOERR) {
    snprintf(errmsg, MAX_ERR_LENGTH,
             "ERROR: failed to initialize conversion routines in file id %d", exoid);
    ex_err(__func__, errmsg, EX_LASTERR);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  EX_FUNC_LEAVE(exoid);
}
/* NOTE: Do *not* call `ex_create_int()` directly.  The public API
 *       function name is `ex_create()` which is a wrapper that calls
 *       `ex_create_int` with an additional argument to make sure
 *       library and include file are consistent
 */
int ex_create_int(const char *path, int cmode, int *comp_ws, int *io_ws, int run_version)
{
  int   exoid;
  int   status;
  int   old_fill;
  int   lio_ws;
  int   filesiz = 1;
  float vers;
  char  errmsg[MAX_ERR_LENGTH];
  char *mode_name;
  int   nc_mode = 0;
#if NC_HAS_HDF5
  static int netcdf4_mode = -1;
#endif /* NC_NETCDF4 */
#if defined(NC_64BIT_DATA)
  static int netcdf5_mode = -1;
#endif
  int          int64_status;
  unsigned int my_mode = cmode;

  /* Contains a 1 in all bits corresponding to file modes */
  static unsigned int all_modes = EX_NORMAL_MODEL | EX_64BIT_OFFSET | EX_64BIT_DATA | EX_NETCDF4;

  EX_FUNC_ENTER();

  if (run_version != EX_API_VERS_NODOT && warning_output == 0) {
    int run_version_major = run_version / 100;
    int run_version_minor = run_version % 100;
    int lib_version_major = EX_API_VERS_NODOT / 100;
    int lib_version_minor = EX_API_VERS_NODOT % 100;
    fprintf(stderr,
            "EXODUS: Warning: This code was compiled with exodusII "
            "version %d.%02d,\n          but was linked with exodusII "
            "library version %d.%02d\n          This is probably an "
            "error in the build process of this code.\n",
            run_version_major, run_version_minor, lib_version_major, lib_version_minor);
    warning_output = 1;
  }

/*
 * See if specified mode is supported in the version of netcdf we
 * are using
 */
#if !NC_HAS_HDF5
  if (my_mode & EX_NETCDF4) {
    snprintf(errmsg, MAX_ERR_LENGTH,
             "EXODUS: ERROR: File format specified as netcdf-4, but the "
             "NetCDF library being used was not configured to enable "
             "this format\n");
    ex_err(__func__, errmsg, EX_BADPARAM);
    EX_FUNC_LEAVE(EX_FATAL);
  }
#endif

#if !defined(NC_64BIT_DATA)
  if (my_mode & EX_64BIT_DATA) {
    snprintf(errmsg, MAX_ERR_LENGTH,
             "EXODUS: ERROR: File format specified as 64bit_data, but "
             "the NetCDF library being used does not support this "
             "format\n");
    ex_err(__func__, errmsg, EX_BADPARAM);
    EX_FUNC_LEAVE(EX_FATAL);
  }
#endif

  /* Check that one and only one format mode is specified... */
  {
    unsigned int set_modes = all_modes & my_mode;

    if (set_modes == 0) {
      my_mode |= EX_64BIT_OFFSET; /* Default if nothing specified */
    }
    else {
      /* Checks that only a single bit is set */
      set_modes = set_modes && !(set_modes & (set_modes - 1));
      if (!set_modes) {
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "EXODUS: ERROR: More than 1 file format "
                 "(EX_NORMAL_MODEL, EX_LARGE_MODEL, EX_64BIT_OFFSET, "
                 "EX_64BIT_DATA, or EX_NETCDF4)\nwas specified in the "
                 "mode argument of the ex_create call. Only a single "
                 "format can be specified.\n");
        ex_err(__func__, errmsg, EX_BADPARAM);
        EX_FUNC_LEAVE(EX_FATAL);
      }
    }
  }

  /*
   * See if any integer data is to be stored as int64 (long long). If
   * so, then need to set NC_NETCDF4 and unset NC_CLASSIC_MODEL (or
   * set EX_NOCLASSIC.  Output meaningful error message if the library
   * is not NetCDF-4 enabled...
   *
   * As of netcdf-4.4.0, can also use NC_64BIT_DATA (CDF5) mode for this...
   */
  int64_status = my_mode & (EX_ALL_INT64_DB | EX_ALL_INT64_API);

  if ((int64_status & EX_ALL_INT64_DB) != 0) {
#if NC_HAS_HDF5 || defined(NC_64BIT_DATA)
    /* Library DOES support netcdf4 and/or cdf5 ... See if user
     * specified either of these and use that one; if not, pick
     * netcdf4, non-classic as default.
     */
    if (my_mode & EX_NETCDF4) {
      my_mode |= EX_NOCLASSIC;
    }
#if defined(NC_64BIT_DATA)
    else if (my_mode & EX_64BIT_DATA) {
      ; /* Do nothing, already set */
    }
#endif
    else {
      /* Unset the current mode so we don't have multiples specified */
      /* ~all_modes sets to 1 all bits not associated with file format */
      my_mode &= ~all_modes;
#if NC_HAS_HDF5
      /* Pick netcdf4 as default mode for 64-bit integers */
      my_mode |= EX_NOCLASSIC;
      my_mode |= EX_NETCDF4;
#else
      /* Pick 64bit_data as default mode for 64-bit integers */
      my_mode |= EX_64BIT_DATA;
#endif
    }
#else
    /* Library does NOT support netcdf4 or cdf5 */
    snprintf(errmsg, MAX_ERR_LENGTH,
             "EXODUS: ERROR: 64-bit integer storage requested, but the "
             "netcdf library does not support the required netcdf-4 or "
             "64BIT_DATA extensions.\n");
    ex_err(__func__, errmsg, EX_BADPARAM);
    EX_FUNC_LEAVE(EX_FATAL);
#endif
  }

#if NC_HAS_HDF5
  if (my_mode & EX_NETCDF4) {
    nc_mode |= (NC_NETCDF4);
  }
  else {
    if (netcdf4_mode == -1) {
      char *option = getenv("EXODUS_NETCDF4");
      if (option != NULL) {
        netcdf4_mode = NC_NETCDF4;
        if (option[0] != 'q') {
          fprintf(stderr, "EXODUS: Using netcdf version 4 selected via "
                          "EXODUS_NETCDF4 environment variable\n");
        }
      }
      else {
        netcdf4_mode = 0;
      }
    }
    nc_mode |= netcdf4_mode;
  }
  if (!(my_mode & EX_NOCLASSIC)) {
    nc_mode |= NC_CLASSIC_MODEL;
  }
#endif

#if defined(NC_64BIT_DATA)
  if (my_mode & EX_64BIT_DATA) {
    nc_mode |= (NC_64BIT_DATA);
  }
  else {
    if (netcdf5_mode == -1) {
      char *option = getenv("EXODUS_NETCDF5");
      if (option != NULL) {
        netcdf5_mode = NC_64BIT_DATA;
        if (option[0] != 'q') {
          fprintf(stderr, "EXODUS: Using netcdf version 5 (CDF5) selected via "
                          "EXODUS_NETCDF5 environment variable\n");
        }
      }
      else {
        netcdf5_mode = 0;
      }
    }
    nc_mode |= netcdf5_mode;
  }
#endif

  /*
   * Hardwire filesiz to 1 for all created files. Reduce complexity in nodal output routines.
   * has been default for a decade or so, but still support it on read...
   */
  if (
#if NC_HAS_HDF5
      !(nc_mode & NC_NETCDF4) &&
#endif
#if defined(NC_64BIT_DATA)
      !(nc_mode & NC_64BIT_DATA) &&
#endif
      filesiz == 1) {
    nc_mode |= NC_64BIT_OFFSET;
  }

  if (my_mode & EX_SHARE) {
    nc_mode |= NC_SHARE;
  }

  /*
   * set error handling mode to no messages, non-fatal errors
   */
  ex_opts(exoptval); /* call required to set ncopts first time through */

  if (my_mode & EX_CLOBBER) {
    nc_mode |= NC_CLOBBER;
    mode_name = "CLOBBER";
  }
  else {
    nc_mode |= NC_NOCLOBBER;
    mode_name = "NOCLOBBER";
  }

#if NC_HAS_DISKLESS
  if (my_mode & EX_DISKLESS) {
    nc_mode |= NC_DISKLESS;
    nc_mode |= NC_WRITE;
  }
#endif

  if ((status = nc_create(path, nc_mode, &exoid)) != NC_NOERR) {
#if NC_HAS_HDF5
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: file create failed for %s, mode: %s", path, mode_name);
#else
    if (my_mode & EX_NETCDF4) {
      snprintf(errmsg, MAX_ERR_LENGTH,
               "ERROR: file create failed for %s in NETCDF4 and %s "
               "mode.\n\tThis library does not support netcdf-4 files.",
               path, mode_name);
    }
    else {
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: file create failed for %s, mode: %s", path,
               mode_name);
    }
#endif
    ex_err(__func__, errmsg, status);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  /* turn off automatic filling of netCDF variables */
  if ((status = nc_set_fill(exoid, NC_NOFILL, &old_fill)) != NC_NOERR) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to set nofill mode in file id %d", exoid);
    ex_err(__func__, errmsg, status);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  /* Verify that there is not an existing file_item struct for this
     exoid This could happen (and has) when application calls
     ex_open(), but then closes file using nc_close() and then reopens
     file.  NetCDF will possibly reuse the exoid which results in
     internal corruption in exodus data structures since exodus does
     not know that file was closed and possibly new file opened for
     this exoid
  */
  if (ex_find_file_item(exoid) != NULL) {
    snprintf(errmsg, MAX_ERR_LENGTH,
             "ERROR: There is an existing file already using the file "
             "id %d which was also assigned to file %s.\n\tWas "
             "nc_close() called instead of ex_close() on an open Exodus "
             "file?\n",
             exoid, path);
    ex_err(__func__, errmsg, EX_BADFILEID);
    nc_close(exoid);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  /* initialize floating point size conversion.  since creating new file,
   * i/o wordsize attribute from file is zero.
   */
  if (ex_conv_ini(exoid, comp_ws, io_ws, 0, int64_status, 0, 0, 0) != EX_NOERR) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to init conversion routines in file id %d",
             exoid);
    ex_err(__func__, errmsg, EX_LASTERR);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  /* put the EXODUS version number, and i/o floating point word size as
   * netcdf global attributes
   */

  /* store Exodus API version # as an attribute */
  vers = EX_API_VERS;
  if ((status = nc_put_att_float(exoid, NC_GLOBAL, ATT_API_VERSION, NC_FLOAT, 1, &vers)) !=
      NC_NOERR) {
    snprintf(errmsg, MAX_ERR_LENGTH,
             "ERROR: failed to store Exodus II API version attribute in file id %d", exoid);
    ex_err(__func__, errmsg, status);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  /* store Exodus file version # as an attribute */
  vers = EX_VERS;
  if ((status = nc_put_att_float(exoid, NC_GLOBAL, ATT_VERSION, NC_FLOAT, 1, &vers)) != NC_NOERR) {
    snprintf(errmsg, MAX_ERR_LENGTH,
             "ERROR: failed to store Exodus II file version attribute in file id %d", exoid);
    ex_err(__func__, errmsg, status);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  /* store Exodus file float word size  as an attribute */
  lio_ws = (*io_ws);
  if ((status = nc_put_att_int(exoid, NC_GLOBAL, ATT_FLT_WORDSIZE, NC_INT, 1, &lio_ws)) !=
      NC_NOERR) {
    snprintf(errmsg, MAX_ERR_LENGTH,
             "ERROR: failed to store Exodus II file float word size "
             "attribute in file id %d",
             exoid);
    ex_err(__func__, errmsg, status);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  /* store Exodus file size (1=large, 0=normal) as an attribute */
  if ((status = nc_put_att_int(exoid, NC_GLOBAL, ATT_FILESIZE, NC_INT, 1, &filesiz)) != NC_NOERR) {
    snprintf(errmsg, MAX_ERR_LENGTH,
             "ERROR: failed to store Exodus II file size attribute in file id %d", exoid);
    ex_err(__func__, errmsg, status);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  {
    int max_so_far = 32;
    if ((status = nc_put_att_int(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, NC_INT, 1, &max_so_far)) !=
        NC_NOERR) {
      snprintf(errmsg, MAX_ERR_LENGTH,
               "ERROR: failed to add maximum_name_length attribute in file id %d", exoid);
      ex_err(__func__, errmsg, status);
      EX_FUNC_LEAVE(EX_FATAL);
    }
  }

  {
    int int64_db_status = int64_status & EX_ALL_INT64_DB;
    if ((status = nc_put_att_int(exoid, NC_GLOBAL, ATT_INT64_STATUS, NC_INT, 1,
                                 &int64_db_status)) != NC_NOERR) {
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to add int64_status attribute in file id %d",
               exoid);
      ex_err(__func__, errmsg, status);
      EX_FUNC_LEAVE(EX_FATAL);
    }
  }

  if ((status = nc_enddef(exoid)) != NC_NOERR) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to complete definition for file id %d", exoid);
    ex_err(__func__, errmsg, status);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  EX_FUNC_LEAVE(exoid);
}