Exemple #1
0
int ex_add_attr(int exoid, ex_entity_type obj_type, ex_entity_id obj_id, int64_t num_attr_per_entry)
{
  int    status;
  int    dims[2];
  int    strdim, varid, att_name_varid;
  size_t num_obj;

  char        errmsg[MAX_ERR_LENGTH];
  const char *dnumobjent;
  const char *dnumobjatt;
  const char *vobjatt;
  const char *vattnam;
  int         numobjentdim;
  int         obj_id_ndx;
  int         numattrdim;

  exerrval = 0; /* clear error code */

  if (num_attr_per_entry <= 0) {
    return (EX_NOERR);
  }

  /* Determine index of obj_id in obj_type id array */
  if (obj_type == EX_NODAL) {
    obj_id_ndx = 0;
  }
  else {
    obj_id_ndx = ex_id_lkup(exoid, obj_type, obj_id);

    if (exerrval != 0) {
      if (exerrval == EX_NULLENTITY) {
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "Warning: no attributes found for NULL %s %" PRId64 " in file id %d",
                 ex_name_of_object(obj_type), obj_id, exoid);
        ex_err("ex_add_attr", errmsg, EX_NULLENTITY);
        return (EX_WARN); /* no attributes for this object */
      }
      snprintf(errmsg, MAX_ERR_LENGTH,
               "Warning: failed to locate %s id %" PRId64 " in id array in file id %d",
               ex_name_of_object(obj_type), obj_id, exoid);
      ex_err("ex_add_attr", errmsg, exerrval);
      return (EX_WARN);
    }
  }

  switch (obj_type) {
  case EX_SIDE_SET:
    dnumobjent = DIM_NUM_SIDE_SS(obj_id_ndx);
    dnumobjatt = DIM_NUM_ATT_IN_SS(obj_id_ndx);
    vobjatt    = VAR_SSATTRIB(obj_id_ndx);
    vattnam    = VAR_NAME_SSATTRIB(obj_id_ndx);
    break;
  case EX_NODE_SET:
    dnumobjent = DIM_NUM_NOD_NS(obj_id_ndx);
    dnumobjatt = DIM_NUM_ATT_IN_NS(obj_id_ndx);
    vobjatt    = VAR_NSATTRIB(obj_id_ndx);
    vattnam    = VAR_NAME_NSATTRIB(obj_id_ndx);
    break;
  case EX_EDGE_SET:
    dnumobjent = DIM_NUM_EDGE_ES(obj_id_ndx);
    dnumobjatt = DIM_NUM_ATT_IN_ES(obj_id_ndx);
    vobjatt    = VAR_ESATTRIB(obj_id_ndx);
    vattnam    = VAR_NAME_ESATTRIB(obj_id_ndx);
    break;
  case EX_FACE_SET:
    dnumobjent = DIM_NUM_FACE_FS(obj_id_ndx);
    dnumobjatt = DIM_NUM_ATT_IN_FS(obj_id_ndx);
    vobjatt    = VAR_FSATTRIB(obj_id_ndx);
    vattnam    = VAR_NAME_FSATTRIB(obj_id_ndx);
    break;
  case EX_ELEM_SET:
    dnumobjent = DIM_NUM_ELE_ELS(obj_id_ndx);
    dnumobjatt = DIM_NUM_ATT_IN_ELS(obj_id_ndx);
    vobjatt    = VAR_ELSATTRIB(obj_id_ndx);
    vattnam    = VAR_NAME_ELSATTRIB(obj_id_ndx);
    break;
  case EX_NODAL:
    dnumobjent = DIM_NUM_NODES;
    dnumobjatt = DIM_NUM_ATT_IN_NBLK;
    vobjatt    = VAR_NATTRIB;
    vattnam    = VAR_NAME_NATTRIB;
    break;
  case EX_EDGE_BLOCK:
    dnumobjent = DIM_NUM_ED_IN_EBLK(obj_id_ndx);
    dnumobjatt = DIM_NUM_ATT_IN_EBLK(obj_id_ndx);
    vobjatt    = VAR_EATTRIB(obj_id_ndx);
    vattnam    = VAR_NAME_EATTRIB(obj_id_ndx);
    break;
  case EX_FACE_BLOCK:
    dnumobjent = DIM_NUM_FA_IN_FBLK(obj_id_ndx);
    dnumobjatt = DIM_NUM_ATT_IN_FBLK(obj_id_ndx);
    vobjatt    = VAR_FATTRIB(obj_id_ndx);
    vattnam    = VAR_NAME_FATTRIB(obj_id_ndx);
    break;
  case EX_ELEM_BLOCK:
    dnumobjent = DIM_NUM_EL_IN_BLK(obj_id_ndx);
    dnumobjatt = DIM_NUM_ATT_IN_BLK(obj_id_ndx);
    vobjatt    = VAR_ATTRIB(obj_id_ndx);
    vattnam    = VAR_NAME_ATTRIB(obj_id_ndx);
    break;
  default:
    exerrval = EX_BADPARAM;
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: Bad block type (%d) specified for file id %d",
             obj_type, exoid);
    ex_err("ex_put_attr_param", errmsg, exerrval);
    return (EX_FATAL);
  }

  /* element attribute array */
  /* put netcdf file into define mode  */
  if ((status = nc_redef(exoid)) != NC_NOERR) {
    exerrval = status;
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to place file id %d into define mode", exoid);
    ex_err("ex_add_attr", errmsg, exerrval);
    return (EX_FATAL);
  }

  if ((status = nc_def_dim(exoid, dnumobjatt, num_attr_per_entry, &numattrdim)) != NC_NOERR) {
    exerrval = status;
    snprintf(errmsg, MAX_ERR_LENGTH,
             "ERROR: failed to define number of attributes in %s %" PRId64 " in file id %d",
             ex_name_of_object(obj_type), obj_id, exoid);
    ex_err("ex_add_attr", errmsg, exerrval);
    goto error_ret; /* exit define mode and return */
  }

  ex_get_dimension(exoid, dnumobjent, ex_name_of_object(obj_type), &num_obj, &numobjentdim,
                   "ex_add_attr");
  dims[0] = numobjentdim;
  dims[1] = numattrdim;

  if ((status = nc_def_var(exoid, vobjatt, nc_flt_code(exoid), 2, dims, &varid)) != NC_NOERR) {
    exerrval = status;
    snprintf(errmsg, MAX_ERR_LENGTH,
             "ERROR:  failed to define attributes for %s %" PRId64 " in file id %d",
             ex_name_of_object(obj_type), obj_id, exoid);
    ex_err("ex_add_attr", errmsg, exerrval);
    goto error_ret; /* exit define mode and return */
  }
  ex_compress_variable(exoid, varid, 2);

  /* inquire previously defined dimensions  */
  if ((status = nc_inq_dimid(exoid, DIM_STR_NAME, &strdim)) != NC_NOERR) {
    exerrval = status;
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get string length in file id %d", exoid);
    ex_err("ex_add_attr", errmsg, exerrval);
    return (EX_FATAL);
  }

  /* Attribute names... */
  dims[0] = numattrdim;
  dims[1] = strdim;

  if ((status = nc_def_var(exoid, vattnam, NC_CHAR, 2, dims, &att_name_varid)) != NC_NOERR) {
    exerrval = status;
    snprintf(errmsg, MAX_ERR_LENGTH,
             "ERROR: failed to define %s attribute name array in file id %d",
             ex_name_of_object(obj_type), exoid);
    ex_err("ex_add_attr", errmsg, exerrval);
    goto error_ret; /* exit define mode and return */
  }

  /* leave define mode  */

  if ((exerrval = nc_enddef(exoid)) != NC_NOERR) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to complete %s definition in file id %d",
             ex_name_of_object(obj_type), exoid);
    ex_err("ex_add_attr", errmsg, exerrval);
    return (EX_FATAL);
  }

  /* Output a dummy empty attribute name in case client code doesn't
     write anything; avoids corruption in some cases.
  */
  if (att_name_varid >= 0) {
    size_t count[2];
    size_t start[2];
    char * text = "";
    size_t i;

    count[0] = 1;
    start[1] = 0;
    count[1] = strlen(text) + 1;

    for (i = 0; i < num_attr_per_entry; i++) {
      start[0] = i;
      nc_put_vara_text(exoid, att_name_varid, start, count, text);
    }
  }

  return (EX_NOERR);

/* Fatal error: exit definition mode and return */
error_ret:
  if (nc_enddef(exoid) != NC_NOERR) { /* exit define mode */
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to complete definition for file id %d", exoid);
    ex_err("ex_add_attr", errmsg, exerrval);
  }
  return (EX_FATAL);
}
int ex_put_truth_table (int  exoid,
			ex_entity_type obj_type,
			int  num_blk,
			int  num_var,
			int *var_tab)
{
  int numelblkdim, numelvardim, timedim, dims[2], varid;
  char *sta_type, *tab_type;
  size_t num_entity = 0;
  size_t num_var_db = 0;
  int *stat_vals;
  int i, j, k;
  int status;
  char errmsg[MAX_ERR_LENGTH];
  const char* routine = "ex_put_truth_table";
  
  /*
   * The ent_type and the var_name are used to build the netcdf
   * variables name.  Normally this is done via a macro defined in
   * exodusII_int.h
   */
  const char* ent_type = NULL;
  const char* var_name = NULL;
  const char* ent_size = NULL;
  exerrval = 0; /* clear error code */
   
  ex_get_dimension(exoid, ex_dim_num_objects(obj_type),
		   ex_name_of_object(obj_type), &num_entity, &numelblkdim, routine);

  if (obj_type == EX_ELEM_BLOCK) {
    ex_get_dimension(exoid, DIM_NUM_ELE_VAR,  "element variables",
		     &num_var_db, &numelvardim, routine);
    var_name = "vals_elem_var";
    ent_type = "eb";
    ent_size = "num_el_in_blk";
    sta_type = VAR_STAT_EL_BLK;
    tab_type = VAR_ELEM_TAB;
  }
  else if (obj_type == EX_EDGE_BLOCK) {
    ex_get_dimension(exoid, DIM_NUM_EDG_VAR, "edge block variables",
		     &num_var_db, &numelvardim, routine);
    var_name = "vals_edge_var";
    ent_type = "eb";
    ent_size = "num_ed_in_blk";
    sta_type = VAR_STAT_ED_BLK;
    tab_type = VAR_EBLK_TAB;
  }
  else if (obj_type  == EX_FACE_BLOCK) {
    ex_get_dimension(exoid, DIM_NUM_FAC_VAR, "face block variables",
		     &num_var_db, &numelvardim, routine);
    var_name = "vals_face_var";
    ent_type = "fb";
    ent_size = "num_fa_in_blk";
    sta_type = VAR_STAT_FA_BLK;
    tab_type = VAR_FBLK_TAB;
  }
  else if (obj_type == EX_SIDE_SET) {
    ex_get_dimension(exoid, DIM_NUM_SSET_VAR, "sideset variables",
		     &num_var_db, &numelvardim, routine);
    var_name = "vals_sset_var";
    ent_type = "ss";
    ent_size = "num_side_ss";
    sta_type = VAR_SS_STAT;
    tab_type = VAR_SSET_TAB;
  }
  else if (obj_type == EX_NODE_SET) {
    ex_get_dimension(exoid, DIM_NUM_NSET_VAR, "nodeset variables",
		     &num_var_db, &numelvardim, routine);
    var_name = "vals_nset_var";
    ent_type = "ns";
    ent_size = "num_nod_ns";
    sta_type = VAR_NS_STAT;
    tab_type = VAR_NSET_TAB;
  }
  else if (obj_type == EX_EDGE_SET) {
    ex_get_dimension(exoid, DIM_NUM_ESET_VAR, "edge set variables",
		     &num_var_db, &numelvardim, routine);
    var_name = "vals_eset_var";
    ent_type = "es";
    ent_size = "num_edge_es";
    sta_type = VAR_ES_STAT;
    tab_type = VAR_ESET_TAB;
  }
  else if (obj_type == EX_FACE_SET) {
    ex_get_dimension(exoid, DIM_NUM_FSET_VAR, "face set variables",
		     &num_var_db, &numelvardim, routine);
    var_name = "vals_fset_var";
    ent_type = "fs";
    ent_size = "num_face_fs";
    sta_type = VAR_FS_STAT;
    tab_type = VAR_FSET_TAB;
  }
  else if (obj_type == EX_ELEM_SET) {
    ex_get_dimension(exoid, DIM_NUM_ELSET_VAR, "element set variables",
		     &num_var_db, &numelvardim, routine);
    var_name = "vals_elset_var";
    ent_type = "es";
    ent_size = "num_ele_els";
    sta_type = VAR_ELS_STAT;
    tab_type = VAR_ELSET_TAB;
  }

  else {       /* invalid variable type */
    exerrval = EX_BADPARAM;
    sprintf(errmsg,
	    "Error: Invalid variable type %d specified in file id %d",
	    obj_type, exoid);
    ex_err("ex_get_varid",errmsg,exerrval);
    return (EX_WARN);
  }
       
  if ((int)num_entity != num_blk) {
    exerrval = EX_FATAL;
    sprintf(errmsg,
	    "Error: # of %s doesn't match those defined in file id %d",
	    ex_name_of_object(obj_type), exoid);
    ex_err("ex_get_var_tab",errmsg,exerrval);
    return (EX_FATAL);
  }

  if ((int)num_var_db != num_var) {
    exerrval = EX_FATAL;
    sprintf(errmsg,
	    "Error: # of %s variables doesn't match those defined in file id %d",
	    ex_name_of_object(obj_type), exoid);
    ex_err("ex_get_var_tab",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* Get status array for later use */
  if (!(stat_vals = malloc(num_blk*sizeof(int)))) {
    exerrval = EX_MEMFAIL;
    sprintf(errmsg,
	    "Error: failed to allocate memory for %s status array for file id %d",
            ex_name_of_object(obj_type), exoid);
    ex_err(routine,errmsg,exerrval);
    return (EX_FATAL);
  }

  status = nc_inq_varid (exoid, sta_type, &varid);

  /* get variable id of status array */
  if (status == NC_NOERR) {
    /* if status array exists (V 2.01+), use it, otherwise assume
       object exists to be backward compatible */

    if ((status = nc_get_var_int (exoid, varid, stat_vals)) != NC_NOERR) {
      exerrval = status;
      free(stat_vals);
      sprintf(errmsg,
	      "Error: failed to get %s status array from file id %d",
              ex_name_of_object(obj_type), exoid);
      ex_err("put_var_tab",errmsg,exerrval);
      return (EX_FATAL);
    }
  } else {
    /* status array doesn't exist (V2.00), dummy one up for later checking */
    for(i=0;i<num_blk;i++)
      stat_vals[i] = 1;
  }

  /* put netcdf file into define mode  */
  if ((status = nc_redef (exoid)) != NC_NOERR) {
    free(stat_vals);
    exerrval = status;
    sprintf(errmsg,
            "Error: failed to put file id %d into define mode",
	    exoid);
    ex_err(routine,errmsg,exerrval);
    return (EX_FATAL);
  }

  /* inquire previously defined dimensions */
  if ((status = nc_inq_dimid (exoid, DIM_TIME, &timedim)) != NC_NOERR) {
    exerrval = status;
    free(stat_vals);
    sprintf(errmsg,
	    "Error: failed to locate time variable in file id %d",
	    exoid);
    ex_err(routine,errmsg,exerrval);
    goto error_ret;          /* exit define mode and return */
  }
  
  /* define netCDF variables in which to store EXODUS II element
   * variable values
   */

  k = 0;
  for (i=0; i<num_blk; i++) {
    for (j=1; j<=num_var; j++) {

      /* check if variables are to be put out for this entity */
      if (var_tab[k] != 0) {
	if (stat_vals[i] != 0) {/* check for NULL entity */
	  /* NOTE: This code used to zero out the var_tab entry
	     if the stat_vals[i] value was zero. However, in some
	     cases it is good to know that a variable was assigned to
	     an entity even if that entity is empty. The code was
	     changed to not modify the truth table.
	  */
	  dims[0] = timedim;
	  
	  /* Determine number of entities in block */
	  if ((status = nc_inq_dimid(exoid, ex_catstr(ent_size, (i+1)), &dims[1])) != NC_NOERR) {
	    exerrval = status;
	    free(stat_vals);
	    sprintf(errmsg,
		    "Error: failed to locate number of entities in %d'th %s in file id %d",
		    i+1, ex_name_of_object(obj_type), exoid);
	    ex_err(routine,errmsg,exerrval);
	    goto error_ret;          /* exit define mode and return */
	    }


	  /* define netCDF variable to store variable values; the j
	   * index cycles from 1 through the number of variables so
	   * that the index of the EXODUS II variable (which is part
	   * of the name of the netCDF variable) will begin at 1
	   * instead of 0
	   */

	  if ((status = nc_def_var(exoid, ex_catstr2(var_name, j, ent_type, i+1),
				  nc_flt_code(exoid), 2, dims, &varid)) != NC_NOERR) {
	    if (status != NC_ENAMEINUSE) {
	      exerrval = status;
	      free(stat_vals);
	      sprintf(errmsg,
		      "Error: failed to define variable for %d'th %s in file id %d",
		      i+1, ex_name_of_object(obj_type), exoid);
	      ex_err(routine,errmsg,exerrval);
	      goto error_ret;  /* exit define mode and return */
	    }
	    ex_compress_variable(exoid, varid, 2);
	  }
	}
      }  /* if */
      k++; /* increment element truth table pointer */
    }  /* for j */
  }  /* for i */

  free (stat_vals);

  /* create a variable array in which to store the truth table
   */

  dims[0] = numelblkdim;
  dims[1] = numelvardim;
  status = nc_def_var (exoid, tab_type, NC_INT, 2, dims, &varid);
  
  if (status != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to define %s variable truth table in file id %d",
	    ex_name_of_object(obj_type), exoid);
    ex_err(routine,errmsg,exerrval);
    goto error_ret;          /* exit define mode and return */
  }

  /* leave define mode  */
  if ((status = nc_enddef (exoid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to complete definitions in file id %d",
	    exoid);
    ex_err(routine,errmsg,exerrval);
    return (EX_FATAL);
  }

  /* write out the element variable truth table */
  status = nc_put_var_int(exoid, varid, var_tab);

  if (status != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to store variable truth table in file id %d",
	    exoid);
    ex_err(routine,errmsg,exerrval);
    return (EX_FATAL);
  }


  return (EX_NOERR);

  /* Fatal error: exit definition mode and return */
 error_ret:
  if (nc_enddef (exoid) != NC_NOERR)     /* exit define mode */
    {
      sprintf(errmsg,
	      "Error: failed to complete definition for file id %d",
	      exoid);
      ex_err(routine,errmsg,exerrval);
    }
  return (EX_FATAL);
}
Exemple #3
0
static int
ex_look_up_var(int exoid, ex_entity_type var_type, int var_index, ex_entity_id obj_id, 
	       const char *VOBJID, const char *VOBJTAB, const char *DNUMOBJ,
	       const char *DNUMOBJVAR, int *varid)
{
  int status;
  int obj_id_ndx;
  int dimid,time_dim, numobjdim, dims[2];

  size_t num_obj;
  size_t num_obj_var;
  size_t num_entity;

  int *obj_var_truth_tab;
  char errmsg[MAX_ERR_LENGTH];

  /* Determine index of obj_id in VOBJID array */
  obj_id_ndx = ex_id_lkup(exoid,var_type,obj_id);
  if (exerrval != 0) {
    if (exerrval == EX_NULLENTITY) {
      sprintf(errmsg,
	      "Warning: no variables allowed for NULL block %"PRId64" in file id %d",
	      obj_id,exoid);
      ex_err("ex_put_var",errmsg,EX_MSG);
      return (EX_WARN);
    }
    else {
      sprintf(errmsg,
	      "Error: failed to locate %s id %"PRId64" in %s array in file id %d",
	      ex_name_of_object(var_type), obj_id, VOBJID, exoid);
      ex_err("ex_put_var",errmsg,exerrval);
      return (EX_FATAL);
    }
  }

  if ((status = nc_inq_varid (exoid, ex_name_var_of_object(var_type, var_index, obj_id_ndx), varid)) != NC_NOERR) {
    if (status == NC_ENOTVAR) {/* variable doesn't exist, create it! */
      /* check for the existance of an TNAME variable truth table */
      if (nc_inq_varid(exoid, VOBJTAB, varid) == NC_NOERR) {
	/* find out number of TNAMEs and TNAME variables */
	status = ex_get_dimension(exoid, DNUMOBJ, ex_name_of_object(var_type), &num_obj, &dimid, "ex_put_var");
	if (status != NC_NOERR) return status;

	status = ex_get_dimension(exoid, DNUMOBJVAR, ex_name_of_object(var_type), &num_obj_var, &dimid, "ex_put_var");
	if (status != NC_NOERR) return status;

	if (!(obj_var_truth_tab = malloc(num_obj*num_obj_var*sizeof(int)))) {
	  exerrval = EX_MEMFAIL;
	  sprintf(errmsg,
		  "Error: failed to allocate memory for %s variable truth table in file id %d",
		  ex_name_of_object(var_type), exoid);
	  ex_err("ex_put_var",errmsg,exerrval);
	  return (EX_FATAL);
	}

	/*   read in the TNAME variable truth table */
	if ((status = nc_get_var_int (exoid, *varid, obj_var_truth_tab)) != NC_NOERR) {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: failed to get truth table from file id %d", exoid);
	  ex_err("ex_put_var",errmsg,exerrval);
	  return (EX_FATAL);
	}

	if(obj_var_truth_tab[num_obj_var*(obj_id_ndx-1)+var_index-1] == 0L) {
	  free(obj_var_truth_tab);
	  exerrval = EX_BADPARAM;
	  sprintf(errmsg,
		  "Error: Invalid %s variable %d, %s %"PRId64" in file id %d",
		  ex_name_of_object(var_type), var_index, ex_name_of_object(var_type), obj_id, exoid);
	  ex_err("ex_put_var",errmsg,exerrval);
	  return (EX_FATAL);
	}
	free(obj_var_truth_tab);
      }

      if ((status = nc_inq_dimid(exoid, DIM_TIME, &time_dim)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to locate time dimension in file id %d", exoid);
	ex_err("ex_put_var",errmsg,exerrval);
	goto error_ret;         /* exit define mode and return */
      }

      ex_get_dimension(exoid, ex_dim_num_entries_in_object(var_type, obj_id_ndx),
		       ex_name_of_object(var_type), &num_entity, &numobjdim,  "ex_put_var");

      /*    variable doesn't exist so put file into define mode  */
      if ((status = nc_redef (exoid)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to put file id %d into define mode", exoid);
	ex_err("ex_put_var",errmsg,exerrval);
	return (EX_FATAL);
      }

      /* define netCDF variable to store TNAME variable values */
      dims[0] = time_dim;
      dims[1] = numobjdim;
      if ((status = nc_def_var(exoid, ex_name_var_of_object(var_type, var_index, obj_id_ndx),
			       nc_flt_code(exoid), 2, dims, varid)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to define %s variable %d in file id %d",
		ex_name_of_object(var_type), var_index,exoid);
	ex_err("ex_put_var",errmsg,exerrval);
	goto error_ret;
      }
      ex_compress_variable(exoid, *varid, 2);

      /*    leave define mode  */
      if ((status = nc_enddef (exoid)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to complete %s variable %s definition to file id %d",
		ex_name_of_object(var_type), ex_name_var_of_object(var_type, var_index, obj_id_ndx), exoid);
	ex_err("ex_put_var",errmsg,exerrval);
	return (EX_FATAL);
      }
    }
    else {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to locate %s variable %s in file id %d",
	      ex_name_of_object(var_type), ex_name_var_of_object(var_type, var_index, obj_id_ndx), exoid);
      ex_err("ex_put_var",errmsg,exerrval);
      return (EX_FATAL);
    }
  }
  return (EX_NOERR);

  /* Fatal error: exit definition mode and return */
 error_ret:
  if (nc_enddef (exoid) != NC_NOERR) {    /* exit define mode */
    sprintf(errmsg,
	    "Error: failed to complete definition for file id %d",
	    exoid);
    ex_err("ex_put_var",errmsg,exerrval);
  }
  return (EX_FATAL);
}
Exemple #4
0
int ex_put_sets (int   exoid,
		 size_t set_count,
		 const struct ex_set *sets)
{
  size_t i;
  int needs_define = 0;
  int set_stat;
  int dimid, varid, status, dims[1];
  int set_id_ndx;
  size_t start[1]; 
  int cur_num_sets;
  char errmsg[MAX_ERR_LENGTH];
  int* sets_to_define = NULL;
  char* numentryptr 	= NULL;
  char* entryptr = NULL;
  char* extraptr = NULL;
  char* idsptr = NULL;
  char* statptr = NULL;
  char* numdfptr = NULL;
  char* factptr = NULL;

  size_t int_size;
  
  exerrval = 0; /* clear error code */

  sets_to_define = malloc(set_count*sizeof(int));
  
  /* Note that this routine can be called:
     1) just define the sets
     2) just output the set data (after a previous call to define)
     3) define and output the set data in one call.
  */
  for (i=0; i < set_count; i++) {
    /* first check if any sets are specified */
    if ((status = nc_inq_dimid(exoid, ex_dim_num_objects(sets[i].type), &dimid)) != NC_NOERR) {
      if (status == NC_EBADDIM) {
	exerrval = status;
	sprintf(errmsg,
		"Error: no %ss defined for file id %d", ex_name_of_object(sets[i].type), exoid);
	ex_err("ex_put_sets",errmsg,exerrval);
      } else {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to locate %ss defined in file id %d",
		ex_name_of_object(sets[i].type), exoid);
	ex_err("ex_put_sets",errmsg,exerrval);
      }
      return (EX_FATAL);
    }

    set_id_ndx = ex_id_lkup(exoid, sets[i].type, sets[i].id);
    if (exerrval != EX_LOOKUPFAIL) {  /* found the side set id, so set is already defined... */
      sets_to_define[i] = 0;
      continue;
    } else {
      needs_define++;
      sets_to_define[i] = 1;
    }
  }
    
  if (needs_define > 0) {
    /* put netcdf file into define mode  */
    if ((status = nc_redef (exoid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to put file id %d into define mode",
	      exoid);
      ex_err("ex_put_sets",errmsg,exerrval);
      return (EX_FATAL);
    }
    
    for (i=0; i < set_count; i++) {
      if (sets_to_define[i] == 0)
	continue;
      
      /*   NOTE: ex_inc_file_item finds the current number of sets defined
	   for a specific file and returns that value incremented. */
      cur_num_sets=ex_inc_file_item(exoid, ex_get_counter_list(sets[i].type));
      set_id_ndx = cur_num_sets + 1;
      sets_to_define[i] = set_id_ndx;
      
      if (sets[i].num_entry == 0)
	continue;
      
      /* setup pointers based on set_type */
      if (sets[i].type == EX_NODE_SET) {
	numentryptr = DIM_NUM_NOD_NS(set_id_ndx);
	entryptr = VAR_NODE_NS(set_id_ndx);
	extraptr = NULL;
	/* note we are using DIM_NUM_NODE_NS instead of DIM_NUM_DF_NS */
	numdfptr = DIM_NUM_NOD_NS(set_id_ndx);
	factptr = VAR_FACT_NS(set_id_ndx);
      }
      else if (sets[i].type == EX_EDGE_SET) {
	numentryptr = DIM_NUM_EDGE_ES(set_id_ndx);
	entryptr = VAR_EDGE_ES(set_id_ndx);
	extraptr = VAR_ORNT_ES(set_id_ndx);
	numdfptr = DIM_NUM_DF_ES(set_id_ndx);
	factptr = VAR_FACT_ES(set_id_ndx);
      }
      else if (sets[i].type == EX_FACE_SET) {
	numentryptr = DIM_NUM_FACE_FS(set_id_ndx);
	entryptr = VAR_FACE_FS(set_id_ndx);
	extraptr = VAR_ORNT_FS(set_id_ndx);
	numdfptr = DIM_NUM_DF_FS(set_id_ndx);
	factptr = VAR_FACT_FS(set_id_ndx);
      }
      else if (sets[i].type == EX_SIDE_SET) {
	numentryptr = DIM_NUM_SIDE_SS(set_id_ndx);
	entryptr = VAR_ELEM_SS(set_id_ndx);
	extraptr = VAR_SIDE_SS(set_id_ndx);
	numdfptr = DIM_NUM_DF_SS(set_id_ndx);
	factptr = VAR_FACT_SS(set_id_ndx);
      }
      else if (sets[i].type == EX_ELEM_SET) {
	numentryptr = DIM_NUM_ELE_ELS(set_id_ndx);
	entryptr = VAR_ELEM_ELS(set_id_ndx);
	extraptr = NULL;
	numdfptr = DIM_NUM_DF_ELS(set_id_ndx);
	factptr = VAR_FACT_ELS(set_id_ndx);
      }

      /* define dimensions and variables */
      if ((status = nc_def_dim(exoid, numentryptr,
			       sets[i].num_entry, &dimid)) != NC_NOERR) {
	exerrval = status;
	if (status == NC_ENAMEINUSE) {
	  sprintf(errmsg,
		  "Error: %s %"PRId64" -- size already defined in file id %d",
		  ex_name_of_object(sets[i].type), sets[i].id,exoid);
	  ex_err("ex_put_sets",errmsg,exerrval);
	}
	else {
	  sprintf(errmsg,
		  "Error: failed to define number of entries in %s %"PRId64" in file id %d",
		  ex_name_of_object(sets[i].type), sets[i].id,exoid);
	  ex_err("ex_put_sets",errmsg,exerrval);
	}
	goto error_ret;
      }
      
      int_size = sizeof(int);
      if (ex_int64_status(exoid) & EX_BULK_INT64_DB) {
	int_size = sizeof(int64_t);
      }
      
      /* create variable array in which to store the entry lists */
      dims[0] = dimid;
      if ((status = nc_def_var(exoid, entryptr, int_size, 1, dims, &varid)) != NC_NOERR) {
	exerrval = status;
	if (status == NC_ENAMEINUSE) {
	  sprintf(errmsg,
		  "Error: entry list already exists for %s %"PRId64" in file id %d",
		  ex_name_of_object(sets[i].type), sets[i].id,exoid);
	  ex_err("ex_put_sets",errmsg,exerrval);
	} else {
	  sprintf(errmsg,
		  "Error: failed to create entry list for %s %"PRId64" in file id %d",
		  ex_name_of_object(sets[i].type), sets[i].id,exoid);
	  ex_err("ex_put_sets",errmsg,exerrval);
	}
	goto error_ret;            /* exit define mode and return */
      }
      ex_compress_variable(exoid, varid, 1);
      
      if (extraptr) {
	if ((status = nc_def_var(exoid, extraptr, int_size, 1, dims, &varid)) != NC_NOERR) {
	  exerrval = status;
	  if (status == NC_ENAMEINUSE) {
	    sprintf(errmsg,
		    "Error: extra list already exists for %s %"PRId64" in file id %d",
		    ex_name_of_object(sets[i].type), sets[i].id, exoid);
	    ex_err("ex_put_sets",errmsg,exerrval);
	  } else {
	    sprintf(errmsg,
		    "Error: failed to create extra list for %s %"PRId64" in file id %d",
		    ex_name_of_object(sets[i].type), sets[i].id,exoid);
	    ex_err("ex_put_sets",errmsg,exerrval);
	  }
	  goto error_ret;         /* exit define mode and return */
	}
	ex_compress_variable(exoid, varid, 1);
      }

      /* Create distribution factors variable if required */
      if (sets[i].num_distribution_factor > 0) {
	if (sets[i].type != EX_SIDE_SET) {
	  /* but sets[i].num_distribution_factor must equal number of nodes */
	  if (sets[i].num_distribution_factor != sets[i].num_entry) {
	    exerrval = EX_FATAL;
	    sprintf(errmsg,
		    "Error: # dist fact (%"PRId64") not equal to # nodes (%"PRId64") in node  set %"PRId64" file id %d",
		    sets[i].num_distribution_factor, sets[i].num_entry, sets[i].id, exoid);
	    ex_err("ex_put_sets",errmsg,exerrval);
	    goto error_ret;    /* exit define mode and return */
	  }
	} else {
	  /* resuse dimid from entry lists */
	  if ((status = nc_def_dim(exoid, numdfptr, 
				   sets[i].num_distribution_factor, &dimid)) != NC_NOERR) {
	    exerrval = status;
	    sprintf(errmsg,
		    "Error: failed to define number of dist factors in %s %"PRId64" in file id %d",
		    ex_name_of_object(sets[i].type), sets[i].id,exoid);
	    ex_err("ex_put_sets",errmsg,exerrval);
	    goto error_ret;          /* exit define mode and return */
	  }
	}
	
	/* create variable array in which to store the set distribution factors
	 */
	dims[0] = dimid;
	if ((status = nc_def_var(exoid, factptr, nc_flt_code(exoid), 1, dims, &varid)) != NC_NOERR) {
	  exerrval = status;
	  if (status == NC_ENAMEINUSE) {
	    sprintf(errmsg,
		    "Error: dist factors list already exists for %s %"PRId64" in file id %d",
		    ex_name_of_object(sets[i].type), sets[i].id,exoid);
	    ex_err("ex_put_sets",errmsg,exerrval);
	  } else {
	    sprintf(errmsg,
		    "Error: failed to create dist factors list for %s %"PRId64" in file id %d",
		    ex_name_of_object(sets[i].type), sets[i].id,exoid);
	    ex_err("ex_put_sets",errmsg,exerrval);
	  }
	  goto error_ret;            /* exit define mode and return */
	}
	ex_compress_variable(exoid, varid, 2);
      }
    }

    /* leave define mode  */
    if ((status = nc_enddef (exoid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to complete definition in file id %d", exoid);
      ex_err("ex_put_sets",errmsg,exerrval);
      return (EX_FATAL);
    }

    /* Output the set ids and status... */
    for (i=0; i < set_count; i++) {
    /* setup pointers based on sets[i].type */
      if (sets[i].type == EX_NODE_SET) {
	idsptr = VAR_NS_IDS;
	statptr = VAR_NS_STAT;
      }
      else if (sets[i].type == EX_EDGE_SET) {
	idsptr = VAR_ES_IDS;
	statptr = VAR_ES_STAT;
      }
      else if (sets[i].type == EX_FACE_SET) {
	idsptr = VAR_FS_IDS;
	statptr = VAR_FS_STAT;
      }
      else if (sets[i].type == EX_SIDE_SET) {
	idsptr = VAR_SS_IDS;
	statptr = VAR_SS_STAT;
      }
      else if (sets[i].type == EX_ELEM_SET) {
	idsptr = VAR_ELS_IDS;
	statptr = VAR_ELS_STAT;
      }
      
      /* first: get id of set id variable */
      if ((status = nc_inq_varid(exoid, idsptr, &varid)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to locate %s %"PRId64" in file id %d", ex_name_of_object(sets[i].type),
		sets[i].id, exoid);
	ex_err("ex_put_sets",errmsg,exerrval);
	return (EX_FATAL);
      }
      
      /* write out set id */
      start[0] = sets_to_define[i]-1;
      status = nc_put_var1_longlong(exoid, varid, start, (long long*)&sets[i].id);
    
      if (status != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to store %s id %"PRId64" in file id %d", ex_name_of_object(sets[i].type),
		sets[i].id, exoid);
	ex_err("ex_put_sets",errmsg,exerrval);
	return (EX_FATAL);
      }
      
      set_stat = (sets[i].num_entry == 0) ? 0 : 1;
      
      if ((status = nc_inq_varid(exoid, statptr, &varid)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to locate %s status in file id %d", ex_name_of_object(sets[i].type),
		exoid);
	ex_err("ex_put_sets",errmsg,exerrval);
	return (EX_FATAL);
      }
      
      if ((status = nc_put_var1_int(exoid, varid, start, &set_stat)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to store %s %"PRId64" status to file id %d", ex_name_of_object(sets[i].type),
		sets[i].id, exoid);
	ex_err("ex_put_sets",errmsg,exerrval);
	return (EX_FATAL);
      }
    }
    free(sets_to_define);
  }
  
  /* Sets are now all defined; see if any set data needs to be output... */
  status = EX_NOERR;
  for (i=0; i < set_count; i++) {
    int stat;
    if (sets[i].entry_list != NULL || sets[i].extra_list != NULL) {
      /* NOTE: ex_put_set will write the warning/error message... */
      stat = ex_put_set(exoid, sets[i].type, sets[i].id, sets[i].entry_list, sets[i].extra_list);
      if (stat != EX_NOERR) status = EX_FATAL;
    }
    if (sets[i].distribution_factor_list != NULL) {
      /* NOTE: ex_put_set_dist_fact will write the warning/error message... */
      stat = ex_put_set_dist_fact(exoid, sets[i].type, sets[i].id, sets[i].distribution_factor_list);
      if (stat != EX_NOERR) status = EX_FATAL;
    }
  }  
  return (status);

  /* Fatal error: exit definition mode and return */
 error_ret:
  free(sets_to_define);
  
  if (nc_enddef (exoid) != NC_NOERR) {    /* exit define mode */
    sprintf(errmsg,
	    "Error: failed to complete definition for file id %d",
	    exoid);
    ex_err("ex_put_sets",errmsg,exerrval);
  }
  return (EX_FATAL);
}
/*!
 * writes the parameters used to describe all element, edge, and face blocks
 * \param     exoid          exodus file id
 * \param     param         block parameters structure
 */
int ex_put_concat_all_blocks(int exoid, const ex_block_params *param)
{
  int    varid, dimid, dims[2], strdim, *eb_stat, *ed_stat, *fa_stat;
  int    temp;
  size_t iblk;
  size_t i;
  int    status;
  size_t num_elem_blk = 0;
  size_t num_edge_blk = 0;
  size_t num_face_blk = 0;
  int    cur_num_elem_blk, nelnoddim, numelbdim, numattrdim, connid = -1;
  int    cur_num_edge_blk, numedbdim, nednoddim, cur_num_face_blk, numfabdim, nfanoddim;
  int    neledgdim = -1, nelfacdim = -1;
  char   errmsg[MAX_ERR_LENGTH];
  int    elem_work = 0; /* is DIM_NUM_EL_BLK defined? If so, there's work to do */
  int    edge_work = 0; /* is DIM_NUM_ED_BLK defined? If so, there's work to do */
  int    face_work = 0; /* is DIM_NUM_FA_BLK defined? If so, there's work to do */

  int *edge_id_int = NULL;
  int *face_id_int = NULL;
  int *elem_id_int = NULL;

  int64_t *edge_id_int64 = NULL;
  int64_t *face_id_int64 = NULL;
  int64_t *elem_id_int64 = NULL;

  int ids_int64 = ex_int64_status(exoid) & EX_IDS_INT64_API;

  static const char *dim_num_maps[] = {
      DIM_NUM_NM, DIM_NUM_EDM, DIM_NUM_FAM, DIM_NUM_EM,
  };
  static const char *dim_size_maps[] = {
      DIM_NUM_NODES, DIM_NUM_EDGE, DIM_NUM_FACE, DIM_NUM_ELEM,
  };
  static const ex_entity_type map_enums[] = {EX_NODE_MAP, EX_EDGE_MAP, EX_FACE_MAP, EX_ELEM_MAP};

  /* If param->define_maps is true, we must fill these with values from
     ex_put_init_ext
     before entering define mode */
  size_t num_maps[sizeof(dim_num_maps) / sizeof(dim_num_maps[0])];
  size_t num_map_dims = sizeof(dim_num_maps) / sizeof(dim_num_maps[0]);

  if (ids_int64) {
    edge_id_int64 = param->edge_blk_id;
    face_id_int64 = param->face_blk_id;
    elem_id_int64 = param->elem_blk_id;
  }
  else {
    edge_id_int = param->edge_blk_id;
    face_id_int = param->face_blk_id;
    elem_id_int = param->elem_blk_id;
  }

  exerrval = 0; /* clear error code */

  /* inquire previously defined dimensions  */
  if ((status = nc_inq_dimid(exoid, DIM_STR_NAME, &strdim)) != NC_NOERR) {
    exerrval = status;
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get string length in file id %d", exoid);
    ex_err("ex_put_concat_all_blocks", errmsg, exerrval);
    return (EX_FATAL);
  }

  if (param->define_maps) {
    for (i = 0; i < num_map_dims; ++i) {
      if ((status = nc_inq_dimid(exoid, dim_num_maps[i], &dimid)) != NC_NOERR) {
        exerrval = status;
        snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to find node map size of file id %d",
                 exoid);
        ex_err("ex_put_concat_all_blocks", errmsg, exerrval);
        return (EX_FATAL);
      }
      if ((status = nc_inq_dimlen(exoid, dimid, num_maps + i)) != NC_NOERR) {
        exerrval = status;
        snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to retrieve node map size of file id %d",
                 exoid);
        ex_err("ex_put_concat_all_blocks", errmsg, exerrval);
        return (EX_FATAL);
      }
    }
  }

#define EX_PREPARE_BLOCK(TNAME, WNAME, DNUMNAME, VSTATNAME, VIDNAME, LNUMNAME, SNUMNAME, SIDNAME,  \
                         GSTAT)                                                                    \
  /* first check if any TNAME blocks are specified                                                 \
   * OK if zero...                                                                                 \
   */                                                                                              \
  if ((status = (nc_inq_dimid(exoid, DNUMNAME, &dimid))) == NC_NOERR) {                            \
    WNAME = 1;                                                                                     \
                                                                                                   \
    /* Get number of TNAME blocks defined for this file */                                         \
    if ((status = nc_inq_dimlen(exoid, dimid, &LNUMNAME)) != NC_NOERR) {                           \
      exerrval = status;                                                                           \
      snprintf(errmsg, MAX_ERR_LENGTH,                                                             \
               "ERROR: failed to get number of " TNAME " blocks in file id %d", exoid);            \
      ex_err("ex_put_concat_all_blocks", errmsg, exerrval);                                        \
      return (EX_FATAL);                                                                           \
    }                                                                                              \
                                                                                                   \
    /* Fill out the TNAME block status array */                                                    \
    if (!(GSTAT = malloc(LNUMNAME * sizeof(int)))) {                                               \
      exerrval = EX_MEMFAIL;                                                                       \
      snprintf(errmsg, MAX_ERR_LENGTH,                                                             \
               "ERROR: failed to allocate space for " TNAME " block status array in file id %d",   \
               exoid);                                                                             \
      ex_err("ex_put_concat_all_blocks", errmsg, exerrval);                                        \
      return (EX_FATAL);                                                                           \
    }                                                                                              \
                                                                                                   \
    for (i = 0; i < LNUMNAME; i++) {                                                               \
      if (SNUMNAME[i] == 0) /* Is this a NULL TNAME block? */                                      \
        GSTAT[i] = 0;       /* change TNAME block status to NULL */                                \
      else                                                                                         \
        GSTAT[i] = 1; /* change TNAME block status to EX_TRUE */                                   \
    }                                                                                              \
                                                                                                   \
    /* Next, get variable id of status array */                                                    \
    if ((status = nc_inq_varid(exoid, VSTATNAME, &varid)) != NC_NOERR) {                           \
      exerrval = status;                                                                           \
      snprintf(errmsg, MAX_ERR_LENGTH,                                                             \
               "ERROR: failed to locate " TNAME " block status in file id %d", exoid);             \
      ex_err("ex_put_concat_all_blocks", errmsg, exerrval);                                        \
      ex_safe_free(GSTAT);                                                                         \
      return (EX_FATAL);                                                                           \
    }                                                                                              \
                                                                                                   \
    status = nc_put_var_int(exoid, varid, GSTAT);                                                  \
                                                                                                   \
    if (status != NC_NOERR) {                                                                      \
      exerrval = status;                                                                           \
      snprintf(errmsg, MAX_ERR_LENGTH,                                                             \
               "ERROR: failed to store " TNAME " block status array to file id %d", exoid);        \
      ex_err("ex_put_concat_all_blocks", errmsg, exerrval);                                        \
      ex_safe_free(GSTAT);                                                                         \
      return (EX_FATAL);                                                                           \
    }                                                                                              \
                                                                                                   \
    free(GSTAT);                                                                                   \
                                                                                                   \
    /* Next, fill out ids array */                                                                 \
    /* first get id of ids array variable */                                                       \
    if ((status = nc_inq_varid(exoid, VIDNAME, &varid)) != NC_NOERR) {                             \
      exerrval = status;                                                                           \
      snprintf(errmsg, MAX_ERR_LENGTH,                                                             \
               "ERROR: failed to locate " TNAME " block ids array in file id %d", exoid);          \
      ex_err("ex_put_concat_all_blocks", errmsg, exerrval);                                        \
      return (EX_FATAL);                                                                           \
    }                                                                                              \
                                                                                                   \
    /* then, write out id list */                                                                  \
    if (ids_int64) {                                                                               \
      status = nc_put_var_longlong(exoid, varid, SIDNAME);                                         \
    }                                                                                              \
    else {                                                                                         \
      status = nc_put_var_int(exoid, varid, SIDNAME);                                              \
    }                                                                                              \
                                                                                                   \
    if (status != NC_NOERR) {                                                                      \
      exerrval = status;                                                                           \
      snprintf(errmsg, MAX_ERR_LENGTH,                                                             \
               "ERROR: failed to store " TNAME " block id array in file id %d", exoid);            \
      ex_err("ex_put_concat_all_blocks", errmsg, exerrval);                                        \
      return (EX_FATAL);                                                                           \
    }                                                                                              \
  }

  EX_PREPARE_BLOCK("element", elem_work, DIM_NUM_EL_BLK, VAR_STAT_EL_BLK, VAR_ID_EL_BLK,
                   num_elem_blk, param->num_elem_this_blk, param->elem_blk_id, eb_stat);
  EX_PREPARE_BLOCK("edge", edge_work, DIM_NUM_ED_BLK, VAR_STAT_ED_BLK, VAR_ID_ED_BLK, num_edge_blk,
                   param->num_edge_this_blk, param->edge_blk_id, ed_stat);
  EX_PREPARE_BLOCK("face", face_work, DIM_NUM_FA_BLK, VAR_STAT_FA_BLK, VAR_ID_FA_BLK, num_face_blk,
                   param->num_face_this_blk, param->face_blk_id, fa_stat);

  if (elem_work == 0 && edge_work == 0 && face_work == 0 && param->define_maps == 0) {
    /* Nothing to do. This is not an error, but we can save
     * ourselves from entering define mode by returning here.
     */
    return (EX_NOERR);
  }
  /* put netcdf file into define mode  */
  if ((status = nc_redef(exoid)) != NC_NOERR) {
    exerrval = status;
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to place file id %d into define mode", exoid);
    ex_err("ex_put_concat_all_blocks", errmsg, exerrval);
    return (EX_FATAL);
  }

#define EX_PREPARE_ATTRIB_ARRAY(TNAME, CURBLK, DNAME, DVAL, ID, VANAME, VADIM0, VADIM1, VANNAME)   \
  if (DVAL[iblk] > 0) {                                                                            \
    if ((status = nc_def_dim(exoid, DNAME(CURBLK + 1), DVAL[iblk], &VADIM1)) != NC_NOERR) {        \
      exerrval = status;                                                                           \
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to define number of attributes in " TNAME    \
                                       " block %" PRId64 " in file id %d",                         \
               ID, exoid);                                                                         \
      ex_err("ex_put_concat_all_blocks", errmsg, exerrval);                                        \
      goto error_ret; /* exit define mode and return */                                            \
    }                                                                                              \
                                                                                                   \
    dims[0] = VADIM0;                                                                              \
    dims[1] = VADIM1;                                                                              \
                                                                                                   \
    if ((status = nc_def_var(exoid, VANAME(CURBLK + 1), nc_flt_code(exoid), 2, dims, &temp)) !=    \
        NC_NOERR) {                                                                                \
      exerrval = status;                                                                           \
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR:  failed to define attributes for " TNAME            \
                                       " block %" PRId64 " in file id %d",                         \
               ID, exoid);                                                                         \
      ex_err("ex_put_concat_all_blocks", errmsg, exerrval);                                        \
      goto error_ret; /* exit define mode and return */                                            \
    }                                                                                              \
    ex_compress_variable(exoid, temp, 2);                                                          \
                                                                                                   \
    /* Attribute names... */                                                                       \
    dims[0] = VADIM1;                                                                              \
    dims[1] = strdim;                                                                              \
                                                                                                   \
    if ((status = nc_def_var(exoid, VANNAME(CURBLK + 1), NC_CHAR, 2, dims, &temp)) != NC_NOERR) {  \
      exerrval = status;                                                                           \
      snprintf(errmsg, MAX_ERR_LENGTH,                                                             \
               "ERROR: failed to define " TNAME " attribute name array in file id %d", exoid);     \
      ex_err("ex_put_concat_all_blocks", errmsg, exerrval);                                        \
      goto error_ret; /* exit define mode and return */                                            \
    }                                                                                              \
  }

#define EX_PREPARE_CONN(TNAME, BLK, BLKID, BLKSZ, VNAME, DNAME)                                    \
  if (DNAME > 0) {                                                                                 \
    int conn_int_type = NC_INT;                                                                    \
    if (ex_int64_status(exoid) & EX_BULK_INT64_DB) {                                               \
      conn_int_type = NC_INT64;                                                                    \
    }                                                                                              \
    dims[0] = BLKSZ;                                                                               \
    dims[1] = DNAME;                                                                               \
                                                                                                   \
    if ((status = nc_def_var(exoid, VNAME(BLK + 1), conn_int_type, 2, dims, &connid)) !=           \
        NC_NOERR) {                                                                                \
      exerrval = status;                                                                           \
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to create " TNAME                            \
                                       " connectivity array for block %" PRId64 " in file id %d",  \
               BLKID, exoid);                                                                      \
      ex_err("ex_put_concat_all_blocks", errmsg, exerrval);                                        \
      goto error_ret; /* exit define mode and return */                                            \
    }                                                                                              \
    ex_compress_variable(exoid, connid, 1);                                                        \
  }

  /* Iterate over edge blocks ... */
  for (iblk = 0; iblk < num_edge_blk; ++iblk) {
    ex_entity_id eb_id;
    if (ids_int64) {
      eb_id = edge_id_int64[iblk];
    }
    else {
      eb_id = edge_id_int[iblk];
    }

    cur_num_edge_blk = ex_get_file_item(exoid, ex_get_counter_list(EX_EDGE_BLOCK));
    if (cur_num_edge_blk >= (int)num_edge_blk) {
      exerrval = EX_FATAL;
      snprintf(errmsg, MAX_ERR_LENGTH,
               "ERROR: exceeded number of edge blocks (%ld) defined in file id %d",
               (long)num_edge_blk, exoid);
      ex_err("ex_put_concat_all_blocks", errmsg, exerrval);
      goto error_ret;
    }

    /* NOTE: ex_inc_file_item  is used to find the number of edge blocks
       for a specific file and returns that value incremented. */
    cur_num_edge_blk = ex_inc_file_item(exoid, ex_get_counter_list(EX_EDGE_BLOCK));

    if (param->num_edge_this_blk[iblk] == 0) { /* Is this a NULL edge block? */
      continue;
    }

    /* define some dimensions and variables*/
    if ((status = nc_def_dim(exoid, DIM_NUM_ED_IN_EBLK(cur_num_edge_blk + 1),
                             param->num_edge_this_blk[iblk], &numedbdim)) != NC_NOERR) {
      exerrval = status;
      if (status == NC_ENAMEINUSE) { /* duplicate entry */
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: edge block %" PRId64 " already defined in file id %d", eb_id, exoid);
      }
      else {
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: failed to define number of edges/block for block %" PRId64 " file id %d",
                 eb_id, exoid);
      }
      ex_err("ex_put_concat_all_blocks", errmsg, exerrval);
      goto error_ret; /* exit define mode and return */
    }

    if ((status = nc_def_dim(exoid, DIM_NUM_NOD_PER_ED(cur_num_edge_blk + 1),
                             param->num_nodes_per_edge[iblk], &nednoddim)) != NC_NOERR) {
      exerrval = status;
      snprintf(errmsg, MAX_ERR_LENGTH,
               "ERROR: failed to define number of nodes/edge for block %" PRId64 " in file id %d",
               eb_id, exoid);
      ex_err("ex_put_concat_all_blocks", errmsg, exerrval);
      goto error_ret; /* exit define mode and return */
    }

    /* edge attribute array */
    EX_PREPARE_ATTRIB_ARRAY("edge", cur_num_edge_blk, DIM_NUM_ATT_IN_EBLK, param->num_attr_edge,
                            eb_id, VAR_EATTRIB, numedbdim, numattrdim, VAR_NAME_EATTRIB);

    EX_PREPARE_CONN("edge block", cur_num_edge_blk, eb_id, numedbdim, VAR_EBCONN, nednoddim);

    /* store edge type as attribute of connectivity variable */
    if ((status = nc_put_att_text(exoid, connid, ATT_NAME_ELB, strlen(param->edge_type[iblk]) + 1,
                                  (void *)param->edge_type[iblk])) != NC_NOERR) {
      exerrval = status;
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to store edge type name %s in file id %d",
               param->edge_type[iblk], exoid);
      ex_err("ex_put_concat_all_blocks", errmsg, exerrval);
      goto error_ret; /* exit define mode and return */
    }
  }

  /* Iterate over face blocks ... */
  for (iblk = 0; iblk < num_face_blk; ++iblk) {
    ex_entity_id fb_id;
    if (ids_int64) {
      fb_id = face_id_int64[iblk];
    }
    else {
      fb_id = face_id_int[iblk];
    }

    cur_num_face_blk = ex_get_file_item(exoid, ex_get_counter_list(EX_FACE_BLOCK));
    if (cur_num_face_blk >= (int)num_face_blk) {
      exerrval = EX_FATAL;
      snprintf(errmsg, MAX_ERR_LENGTH,
               "ERROR: exceeded number of face blocks (%ld) defined in file id %d",
               (long)num_face_blk, exoid);
      ex_err("ex_put_concat_all_blocks", errmsg, exerrval);
      goto error_ret;
    }

    /* NOTE: ex_inc_file_item  is used to find the number of edge blocks
       for a specific file and returns that value incremented. */
    cur_num_face_blk = ex_inc_file_item(exoid, ex_get_counter_list(EX_FACE_BLOCK));

    if (param->num_face_this_blk[iblk] == 0) { /* Is this a NULL face block? */
      continue;
    }

    /* define some dimensions and variables*/
    if ((status = nc_def_dim(exoid, DIM_NUM_FA_IN_FBLK(cur_num_face_blk + 1),
                             param->num_face_this_blk[iblk], &numfabdim)) != NC_NOERR) {
      exerrval = status;
      if (status == NC_ENAMEINUSE) { /* duplicate entry */
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: face block %" PRId64 " already defined in file id %d", fb_id, exoid);
      }
      else {
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: failed to define number of faces/block for block %" PRId64 " file id %d",
                 fb_id, exoid);
      }
      ex_err("ex_put_concat_all_blocks", errmsg, exerrval);
      goto error_ret; /* exit define mode and return */
    }

    if ((status = nc_def_dim(exoid, DIM_NUM_NOD_PER_FA(cur_num_face_blk + 1),
                             param->num_nodes_per_face[iblk], &nfanoddim)) != NC_NOERR) {
      exerrval = status;
      snprintf(errmsg, MAX_ERR_LENGTH,
               "ERROR: failed to define number of nodes/face for block %" PRId64 " in file id %d",
               fb_id, exoid);
      ex_err("ex_put_concat_all_blocks", errmsg, exerrval);
      goto error_ret; /* exit define mode and return */
    }

    /* face attribute array */
    EX_PREPARE_ATTRIB_ARRAY("face", cur_num_face_blk, DIM_NUM_ATT_IN_FBLK, param->num_attr_face,
                            fb_id, VAR_FATTRIB, numfabdim, numattrdim, VAR_NAME_FATTRIB);

    EX_PREPARE_CONN("face block", cur_num_face_blk, fb_id, numfabdim, VAR_FBCONN, nfanoddim);

    /* store face type as attribute of connectivity variable */
    if ((status = nc_put_att_text(exoid, connid, ATT_NAME_ELB, strlen(param->face_type[iblk]) + 1,
                                  (void *)param->face_type[iblk])) != NC_NOERR) {
      exerrval = status;
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to store face type name %s in file id %d",
               param->face_type[iblk], exoid);
      ex_err("ex_put_concat_all_blocks", errmsg, exerrval);
      goto error_ret; /* exit define mode and return */
    }
  }

  /* Iterate over element blocks ... */
  for (iblk = 0; iblk < num_elem_blk; ++iblk) {
    ex_entity_id eb_id;
    if (ids_int64) {
      eb_id = elem_id_int64[iblk];
    }
    else {
      eb_id = elem_id_int[iblk];
    }

    cur_num_elem_blk = ex_get_file_item(exoid, ex_get_counter_list(EX_ELEM_BLOCK));
    if (cur_num_elem_blk >= (int)num_elem_blk) {
      exerrval = EX_FATAL;
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: exceeded number of element blocks (%ld) defined "
                                       "in file id %d",
               (long)num_elem_blk, exoid);
      ex_err("ex_put_concat_all_blocks", errmsg, exerrval);
      goto error_ret;
    }

    /* NOTE: ex_inc_file_item  is used to find the number of element blocks
       for a specific file and returns that value incremented. */
    cur_num_elem_blk = ex_inc_file_item(exoid, ex_get_counter_list(EX_ELEM_BLOCK));

    if (param->num_elem_this_blk[iblk] == 0) { /* Is this a NULL element block? */
      continue;
    }

    /* define some dimensions and variables*/
    if ((status = nc_def_dim(exoid, DIM_NUM_EL_IN_BLK(cur_num_elem_blk + 1),
                             param->num_elem_this_blk[iblk], &numelbdim)) != NC_NOERR) {
      exerrval = status;
      if (status == NC_ENAMEINUSE) { /* duplicate entry */
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: element block %" PRId64 " already defined in file id %d", eb_id, exoid);
      }
      else {
        snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to define number of elements/block for "
                                         "block %" PRId64 " file id %d",
                 eb_id, exoid);
      }
      ex_err("ex_put_concat_all_blocks", errmsg, exerrval);
      goto error_ret; /* exit define mode and return */
    }

    /* Always define DIM_NUM_NOD_PER_EL, even if zero.
     * Do not define DIM_NUM_EDG_PER_EL or DIM_NUM_FAC_PER_EL unless > 0.
     */
    if ((status = nc_def_dim(exoid, DIM_NUM_NOD_PER_EL(cur_num_elem_blk + 1),
                             param->num_nodes_per_elem[iblk], &nelnoddim)) != NC_NOERR) {
      exerrval = status;
      snprintf(errmsg, MAX_ERR_LENGTH,
               "ERROR: failed to define number of nodes/element for block %" PRId64
               " in file id %d",
               eb_id, exoid);
      ex_err("ex_put_concat_all_blocks", errmsg, exerrval);
      goto error_ret; /* exit define mode and return */
    }

    if (param->num_edges_per_elem[iblk] > 0) {
      if ((status = nc_def_dim(exoid, DIM_NUM_EDG_PER_EL(cur_num_elem_blk + 1),
                               param->num_edges_per_elem[iblk], &neledgdim)) != NC_NOERR) {
        exerrval = status;
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: failed to define number of edges/element for block %" PRId64
                 " in file id %d",
                 eb_id, exoid);
        ex_err("ex_put_concat_all_blocks", errmsg, exerrval);
        goto error_ret; /* exit define mode and return */
      }
    }

    if (param->num_faces_per_elem[iblk] > 0) {
      if ((status = nc_def_dim(exoid, DIM_NUM_FAC_PER_EL(cur_num_elem_blk + 1),
                               param->num_faces_per_elem[iblk], &nelfacdim)) != NC_NOERR) {
        exerrval = status;
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: failed to define number of faces/element for block %" PRId64
                 " in file id %d",
                 eb_id, exoid);
        ex_err("ex_put_concat_all_blocks", errmsg, exerrval);
        goto error_ret; /* exit define mode and return */
      }
    }

    EX_PREPARE_ATTRIB_ARRAY("element", cur_num_elem_blk, DIM_NUM_ATT_IN_BLK, param->num_attr_elem,
                            eb_id, VAR_ATTRIB, numelbdim, numattrdim, VAR_NAME_ATTRIB);

    EX_PREPARE_CONN("nodal", cur_num_elem_blk, eb_id, numelbdim, VAR_CONN, nelnoddim);

    /* store element type as attribute of connectivity variable */
    if ((status = nc_put_att_text(exoid, connid, ATT_NAME_ELB, strlen(param->elem_type[iblk]) + 1,
                                  (void *)param->elem_type[iblk])) != NC_NOERR) {
      exerrval = status;
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to store element type name %s in file id %d",
               param->elem_type[iblk], exoid);
      ex_err("ex_put_concat_all_blocks", errmsg, exerrval);
      goto error_ret; /* exit define mode and return */
    }

    EX_PREPARE_CONN("edge", cur_num_elem_blk, eb_id, numelbdim, VAR_ECONN, neledgdim);
    EX_PREPARE_CONN("face", cur_num_elem_blk, eb_id, numelbdim, VAR_FCONN, nelfacdim);
  }

  /* Define the element map here to avoid a later redefine call */
  if (param->define_maps != 0) {
    size_t map_type;
    for (map_type = 0; map_type < num_map_dims; ++map_type) {
      if ((status = nc_inq_dimid(exoid, dim_size_maps[map_type], &dims[0])) != NC_NOERR) {
        exerrval = status;
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: could not find map size dimension %s in file id %d",
                 dim_size_maps[map_type], exoid);
        ex_err("ex_put_concat_all_blocks", errmsg, exerrval);
      }
      for (i = 1; i <= num_maps[map_type]; ++i) {
        const char *mapname = ex_name_of_map(map_enums[map_type], i);
        if (nc_inq_varid(exoid, mapname, &temp) != NC_NOERR) {
          int map_int_type = NC_INT;
          if (ex_int64_status(exoid) & EX_MAPS_INT64_DB) {
            map_int_type = NC_INT64;
          }

          if ((status = nc_def_var(exoid, mapname, map_int_type, 1, dims, &temp)) != NC_NOERR) {
            exerrval = status;
            if (status == NC_ENAMEINUSE) {
              snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: number map %s already exists in file id %d",
                       mapname, exoid);
            }
            else {
              snprintf(errmsg, MAX_ERR_LENGTH,
                       "ERROR: failed to create number map array %s in file id %d", mapname, exoid);
            }
            ex_err("ex_put_concat_all_blocks", errmsg, exerrval);
            goto error_ret; /* exit define mode and return */
          }
          ex_compress_variable(exoid, temp, 1);
        }
      }
    }
  }

  /* leave define mode  */
  if ((status = nc_enddef(exoid)) != NC_NOERR) {
    exerrval = status;
    snprintf(errmsg, MAX_ERR_LENGTH,
             "ERROR: failed to complete element block definition in file id %d", exoid);
    ex_err("ex_put_concat_all_blocks", errmsg, exerrval);
    return (EX_FATAL);
  }

  return (EX_NOERR);

/* Fatal error: exit definition mode and return */
error_ret:
  if (nc_enddef(exoid) != NC_NOERR) { /* exit define mode */
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to complete definition for file id %d", exoid);
    ex_err("ex_put_concat_all_blocks", errmsg, exerrval);
  }
  return (EX_FATAL);
}
Exemple #6
0
/*! \internal */
int cpy_coord_def(int in_id,int out_id,int rec_dim_id,char *var_nm,
		  int in_large, int out_large)
/*
   int in_id: input netCDF input-file ID
   int out_id: input netCDF output-file ID
   int rec_dim_id: input input-file record dimension ID
   char *var_nm: input variable name
   int in_large: large file setting for input file
   int out_large: large file setting for output file
   int cpy_var_def(): output output-file variable ID
 */
{
  const char *routine = NULL;
  int status;
  size_t spatial_dim;
  int nbr_dim;
  int temp;

  int dim_out_id[2];
  int var_out_id = -1;
  
  /* Handle easiest situation first: in_large matches out_large */
  if (in_large == out_large) {
    return cpy_var_def(in_id, out_id, rec_dim_id, var_nm);
  }

  /* At this point, know that in_large != out_large, so some change to
     the coord variable definition is needed. Also will need the
     spatial dimension, so get that now.*/
  ex_get_dimension(in_id, DIM_NUM_DIM, "dimension", &spatial_dim, &temp, routine);
  
  if (in_large == 0 && out_large == 1) {
    /* output file will have coordx, coordy, coordz (if 3d).  See if
       they are already defined in output file. Assume either all or
       none are defined. */

    {
      int var_out_idx, var_out_idy, var_out_idz;
      int status1 = nc_inq_varid(out_id, VAR_COORD_X, &var_out_idx);
      int status2 = nc_inq_varid(out_id, VAR_COORD_Y, &var_out_idy);
      int status3 = nc_inq_varid(out_id, VAR_COORD_Y, &var_out_idz);

      if (status1 == NC_NOERR && status2 == NC_NOERR &&
          (spatial_dim == 2 || status3 == NC_NOERR)) {
        return NC_NOERR; /* already defined in output file */
      }
    }

    /* Get dimid of the num_nodes dimension in output file... */
    (void)nc_inq_dimid(out_id, DIM_NUM_NODES, &dim_out_id[0]);

    /* Define the variables in the output file */
    
    /* Define according to the EXODUS file's IO_word_size */
    nbr_dim = 1;
    (void)nc_def_var(out_id, VAR_COORD_X, nc_flt_code(out_id), nbr_dim, dim_out_id, &var_out_id);
    ex_compress_variable(out_id, var_out_id, 2);
    if (spatial_dim > 1) {
      (void)nc_def_var(out_id, VAR_COORD_Y, nc_flt_code(out_id), nbr_dim, dim_out_id, &var_out_id);
      ex_compress_variable(out_id, var_out_id, 2);
    }
    if (spatial_dim > 2) {
      (void)nc_def_var(out_id, VAR_COORD_Z, nc_flt_code(out_id), nbr_dim, dim_out_id, &var_out_id);
      ex_compress_variable(out_id, var_out_id, 2);
    }
  }

  if (in_large == 1 && out_large == 0) {
    /* input file has coordx, coordy, coordz (if 3d); output will only
       have "coord".  See if is already defined in output file. */
    status = nc_inq_varid(out_id, VAR_COORD, &var_out_id);
    if (status == NC_NOERR)
      return NC_NOERR; /* already defined in output file */

    /* Get dimid of the spatial dimension and num_nodes dimensions in output file... */
    (void)nc_inq_dimid(out_id, DIM_NUM_DIM,   &dim_out_id[0]);
    (void)nc_inq_dimid(out_id, DIM_NUM_NODES, &dim_out_id[1]);

    /* Define the variable in the output file */
    
    /* Define according to the EXODUS file's IO_word_size */
    nbr_dim = 2;
    (void)nc_def_var(out_id, VAR_COORD, nc_flt_code(out_id), nbr_dim, dim_out_id, &var_out_id);
  }
  return var_out_id;
}
Exemple #7
0
int ex_put_map(int exoid, const void_int *elem_map)
{
  int  numelemdim, dims[1], mapid, status;
  int  map_int_type;
  char errmsg[MAX_ERR_LENGTH];

  exerrval = 0; /* clear error code */

  /* inquire id's of previously defined dimensions  */

  /* determine number of elements. Return if zero... */
  if (nc_inq_dimid(exoid, DIM_NUM_ELEM, &numelemdim) != NC_NOERR) {
    return (EX_NOERR);
  }

  /* put netcdf file into define mode  */
  if ((status = nc_redef(exoid)) != NC_NOERR) {
    exerrval = status;
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid);
    ex_err("ex_put_map", errmsg, exerrval);
    return (EX_FATAL);
  }

  /* create a variable array in which to store the element map  */
  dims[0] = numelemdim;

  map_int_type = NC_INT;
  if (ex_int64_status(exoid) & EX_MAPS_INT64_DB) {
    map_int_type = NC_INT64;
  }

  if ((status = nc_def_var(exoid, VAR_MAP, map_int_type, 1, dims, &mapid)) != NC_NOERR) {
    if (status == NC_ENAMEINUSE) {
      exerrval = status;
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: element map already exists in file id %d", exoid);
      ex_err("ex_put_map", errmsg, exerrval);
    }
    else {
      exerrval = status;
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to create element map array in file id %d",
               exoid);
      ex_err("ex_put_map", errmsg, exerrval);
    }
    goto error_ret; /* exit define mode and return */
  }
  ex_compress_variable(exoid, mapid, 1);

  /* leave define mode  */
  if ((status = nc_enddef(exoid)) != NC_NOERR) {
    exerrval = status;
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to complete definition in file id %d", exoid);
    ex_err("ex_put_map", errmsg, exerrval);
    return (EX_FATAL);
  }

  /* write out the element order map  */
  if (ex_int64_status(exoid) & EX_MAPS_INT64_API) {
    status = nc_put_var_longlong(exoid, mapid, elem_map);
  }
  else {
    status = nc_put_var_int(exoid, mapid, elem_map);
  }

  if (status != NC_NOERR) {
    exerrval = status;
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to store element map in file id %d", exoid);
    ex_err("ex_put_map", errmsg, exerrval);
    return (EX_FATAL);
  }

  return (EX_NOERR);

/* Fatal error: exit definition mode and return */
error_ret:
  if (nc_enddef(exoid) != NC_NOERR) /* exit define mode */
  {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to complete definition for file id %d", exoid);
    ex_err("ex_put_map", errmsg, exerrval);
  }
  return (EX_FATAL);
}
Exemple #8
0
int ex_put_init_ext(int exoid, const ex_init_params *model)
{
  int numdimdim, numnoddim, elblkdim, edblkdim, fablkdim, esetdim, fsetdim, elsetdim, nsetdim,
      ssetdim, dim_str_name, dim[2], temp;
  int nmapdim, edmapdim, famapdim, emapdim, timedim;
  int status;
  int title_len;
#if 0
  /* used for header size calculations which are turned off for now */
  int header_size, fixed_var_size, iows;
#endif
  char errmsg[MAX_ERR_LENGTH];

  EX_FUNC_ENTER();
  int rootid = exoid & EX_FILE_ID_MASK;

  ex_check_valid_file_id(exoid, __func__);

  if (rootid == exoid && nc_inq_dimid(exoid, DIM_NUM_DIM, &temp) == NC_NOERR) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: initialization already done for file id %d", exoid);
    ex_err(__func__, errmsg, EX_MSG);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  /* put file into define mode */
  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);
  }

  /* define some attributes... */
  title_len = strlen(model->title) < MAX_LINE_LENGTH ? strlen(model->title) : MAX_LINE_LENGTH;
  if ((status = nc_put_att_text(rootid, NC_GLOBAL, (const char *)ATT_TITLE, title_len + 1,
                                model->title)) != NC_NOERR) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to define model->title attribute to file id %d",
             rootid);
    ex_err(__func__, errmsg, status);
    goto error_ret; /* exit define mode and return */
  }

  /* ...and some dimensions... */

  /* create name string length dimension */
  if (nc_inq_dimid(rootid, DIM_STR_NAME, &dim_str_name) != NC_NOERR) {
    if ((status = nc_def_dim(rootid, DIM_STR_NAME, NC_MAX_NAME, &dim_str_name)) != NC_NOERR) {
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to define name string length in file id %d",
               rootid);
      ex_err(__func__, errmsg, status);
      goto error_ret;
    }
  }

  if ((status = nc_def_dim(exoid, DIM_TIME, NC_UNLIMITED, &timedim)) != NC_NOERR) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to define time dimension in file id %d", exoid);
    ex_err(__func__, errmsg, status);
    goto error_ret;
  }

  dim[0] = timedim;
  if ((status = nc_def_var(exoid, VAR_WHOLE_TIME, nc_flt_code(exoid), 1, dim, &temp)) != NC_NOERR) {
    snprintf(errmsg, MAX_ERR_LENGTH,
             "ERROR: failed to define whole time step variable in file id %d", exoid);
    ex_err(__func__, errmsg, status);
    goto error_ret;
  }
  {
    struct ex_file_item *file = ex_find_file_item(exoid);
    file->time_varid          = temp;
  }
  ex_compress_variable(exoid, temp, 2);

  if ((status = nc_def_dim(exoid, DIM_NUM_DIM, model->num_dim, &numdimdim)) != NC_NOERR) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to define number of dimensions in file id %d",
             exoid);
    ex_err(__func__, errmsg, status);
    goto error_ret; /* exit define mode and return */
  }

  /*
   * Need to handle "empty file" that may be the result of a strange
   * load balance or some other strange run.  Note that if num_node
   * == 0, then model->num_elem must be zero since you cannot have elements
   * with no nodes. It *is* permissible to have zero elements with
   * non-zero node count.
   */

  if (model->num_nodes > 0) {
    if ((status = nc_def_dim(exoid, DIM_NUM_NODES, model->num_nodes, &numnoddim)) != NC_NOERR) {
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to define number of nodes in file id %d",
               exoid);
      ex_err(__func__, errmsg, status);
      goto error_ret; /* exit define mode and return */
    }
  }

  if (model->num_elem > 0) {
    if (model->num_nodes <= 0) {
      snprintf(errmsg, MAX_ERR_LENGTH,
               "ERROR: Cannot have non-zero element count if node count "
               "is zero.in file id %d",
               exoid);
      ex_err(__func__, errmsg, EX_BADPARAM);
      goto error_ret; /* exit define mode and return */
    }

    if ((status = nc_def_dim(exoid, DIM_NUM_ELEM, model->num_elem, &temp)) != NC_NOERR) {
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to define number of elements in file id %d",
               exoid);
      ex_err(__func__, errmsg, status);
      goto error_ret; /* exit define mode and return */
    }
  }

  if (model->num_edge > 0) {
    if (model->num_nodes <= 0) {
      snprintf(errmsg, MAX_ERR_LENGTH,
               "ERROR: Cannot have non-zero edge count if node count is "
               "zero.in file id %d",
               exoid);
      ex_err(__func__, errmsg, EX_BADPARAM);
      goto error_ret; /* exit define mode and return */
    }

    if ((status = nc_def_dim(exoid, DIM_NUM_EDGE, model->num_edge, &temp)) != NC_NOERR) {
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to define number of edges in file id %d",
               exoid);
      ex_err(__func__, errmsg, status);
      goto error_ret; /* exit define mode and return */
    }
  }

  if (model->num_face > 0) {
    if (model->num_nodes <= 0) {
      snprintf(errmsg, MAX_ERR_LENGTH,
               "ERROR: Cannot have non-zero face count if node count is "
               "zero.in file id %d",
               exoid);
      ex_err(__func__, errmsg, EX_BADPARAM);
      goto error_ret; /* exit define mode and return */
    }

    if ((status = nc_def_dim(exoid, DIM_NUM_FACE, model->num_face, &temp)) != NC_NOERR) {
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to define number of faces in file id %d",
               exoid);
      ex_err(__func__, errmsg, status);
      goto error_ret; /* exit define mode and return */
    }
  }

  if (ex_write_object_params(exoid, "element block", DIM_NUM_EL_BLK, VAR_STAT_EL_BLK, VAR_ID_EL_BLK,
                             model->num_elem_blk, &elblkdim)) {
    goto error_ret;
  }
  if (ex_write_object_params(exoid, "edge block", DIM_NUM_ED_BLK, VAR_STAT_ED_BLK, VAR_ID_ED_BLK,
                             model->num_edge_blk, &edblkdim)) {
    goto error_ret;
  }
  if (ex_write_object_params(exoid, "face block", DIM_NUM_FA_BLK, VAR_STAT_FA_BLK, VAR_ID_FA_BLK,
                             model->num_face_blk, &fablkdim)) {
    goto error_ret;
  }

  if (ex_write_object_params(exoid, "node set", DIM_NUM_NS, VAR_NS_STAT, VAR_NS_IDS,
                             model->num_node_sets, &nsetdim)) {
    goto error_ret;
  }
  if (ex_write_object_params(exoid, "edge set", DIM_NUM_ES, VAR_ES_STAT, VAR_ES_IDS,
                             model->num_edge_sets, &esetdim)) {
    goto error_ret;
  }
  if (ex_write_object_params(exoid, "face set", DIM_NUM_FS, VAR_FS_STAT, VAR_FS_IDS,
                             model->num_face_sets, &fsetdim)) {
    goto error_ret;
  }
  if (ex_write_object_params(exoid, "side set", DIM_NUM_SS, VAR_SS_STAT, VAR_SS_IDS,
                             model->num_side_sets, &ssetdim)) {
    goto error_ret;
  }
  if (ex_write_object_params(exoid, "elem set", DIM_NUM_ELS, VAR_ELS_STAT, VAR_ELS_IDS,
                             model->num_elem_sets, &elsetdim)) {
    goto error_ret;
  }

  if (ex_write_map_params(exoid, "node map", DIM_NUM_NM, VAR_NM_PROP(1), model->num_node_maps,
                          &nmapdim) != NC_NOERR) {
    goto error_ret;
  }
  if (ex_write_map_params(exoid, "edge map", DIM_NUM_EDM, VAR_EDM_PROP(1), model->num_edge_maps,
                          &edmapdim) != NC_NOERR) {
    goto error_ret;
  }
  if (ex_write_map_params(exoid, "face map", DIM_NUM_FAM, VAR_FAM_PROP(1), model->num_face_maps,
                          &famapdim) != NC_NOERR) {
    goto error_ret;
  }
  if (ex_write_map_params(exoid, "element map", DIM_NUM_EM, VAR_EM_PROP(1), model->num_elem_maps,
                          &emapdim) != NC_NOERR) {
    goto error_ret;
  }

  if (model->num_nodes > 0) {
    dim[0] = numnoddim;
    if (model->num_dim > 0) {
      if ((status = nc_def_var(exoid, VAR_COORD_X, nc_flt_code(exoid), 1, dim, &temp)) !=
          NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: failed to define node x coordinate array in file id %d", exoid);
        ex_err(__func__, errmsg, status);
        goto error_ret; /* exit define mode and return */
      }
      ex_compress_variable(exoid, temp, 2);
    }

    if (model->num_dim > 1) {
      if ((status = nc_def_var(exoid, VAR_COORD_Y, nc_flt_code(exoid), 1, dim, &temp)) !=
          NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: failed to define node y coordinate array in file id %d", exoid);
        ex_err(__func__, errmsg, status);
        goto error_ret; /* exit define mode and return */
      }
      ex_compress_variable(exoid, temp, 2);
    }

    if (model->num_dim > 2) {
      if ((status = nc_def_var(exoid, VAR_COORD_Z, nc_flt_code(exoid), 1, dim, &temp)) !=
          NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: failed to define node z coordinate array in file id %d", exoid);
        ex_err(__func__, errmsg, status);
        goto error_ret; /* exit define mode and return */
      }
      ex_compress_variable(exoid, temp, 2);
    }
  }

  if (ex_write_object_names(exoid, "element block", VAR_NAME_EL_BLK, elblkdim, dim_str_name,
                            model->num_elem_blk) != NC_NOERR) {
    goto error_ret;
  }
  if (ex_write_object_names(exoid, "edge block", VAR_NAME_ED_BLK, edblkdim, dim_str_name,
                            model->num_edge_blk) != NC_NOERR) {
    goto error_ret;
  }
  if (ex_write_object_names(exoid, "face block", VAR_NAME_FA_BLK, fablkdim, dim_str_name,
                            model->num_face_blk) != NC_NOERR) {
    goto error_ret;
  }
  if (ex_write_object_names(exoid, "node set", VAR_NAME_NS, nsetdim, dim_str_name,
                            model->num_node_sets) != NC_NOERR) {
    goto error_ret;
  }
  if (ex_write_object_names(exoid, "edge set", VAR_NAME_ES, esetdim, dim_str_name,
                            model->num_edge_sets) != NC_NOERR) {
    goto error_ret;
  }
  if (ex_write_object_names(exoid, "face set", VAR_NAME_FS, fsetdim, dim_str_name,
                            model->num_face_sets) != NC_NOERR) {
    goto error_ret;
  }
  if (ex_write_object_names(exoid, "side set", VAR_NAME_SS, ssetdim, dim_str_name,
                            model->num_side_sets) != NC_NOERR) {
    goto error_ret;
  }
  if (ex_write_object_names(exoid, "element set", VAR_NAME_ELS, elsetdim, dim_str_name,
                            model->num_elem_sets) != NC_NOERR) {
    goto error_ret;
  }
  if (ex_write_object_names(exoid, "node map", VAR_NAME_NM, nmapdim, dim_str_name,
                            model->num_node_maps) != NC_NOERR) {
    goto error_ret;
  }
  if (ex_write_object_names(exoid, "edge map", VAR_NAME_EDM, edmapdim, dim_str_name,
                            model->num_edge_maps) != NC_NOERR) {
    goto error_ret;
  }
  if (ex_write_object_names(exoid, "face map", VAR_NAME_FAM, famapdim, dim_str_name,
                            model->num_face_maps) != NC_NOERR) {
    goto error_ret;
  }
  if (ex_write_object_names(exoid, "element map", VAR_NAME_EM, emapdim, dim_str_name,
                            model->num_elem_maps) != NC_NOERR) {
    goto error_ret;
  }
  if (ex_write_object_names(exoid, "coordinate", VAR_NAME_COOR, numdimdim, dim_str_name,
                            model->num_dim) != NC_NOERR) {
    goto error_ret;
  }

  /* leave define mode */
  if ((status = nc_enddef(exoid)) != NC_NOERR) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to complete variable definitions in file id %d",
             exoid);
    ex_err(__func__, errmsg, status);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  /* Fill the id and status arrays with EX_INVALID_ID */
  {
    int *invalid_ids = NULL;
    int  maxset      = model->num_elem_blk;
    if (maxset < model->num_edge_blk) {
      maxset = model->num_edge_blk;
    }
    if (maxset < model->num_face_blk) {
      maxset = model->num_face_blk;
    }
    if (maxset < model->num_node_sets) {
      maxset = model->num_node_sets;
    }
    if (maxset < model->num_edge_sets) {
      maxset = model->num_edge_sets;
    }
    if (maxset < model->num_face_sets) {
      maxset = model->num_face_sets;
    }
    if (maxset < model->num_side_sets) {
      maxset = model->num_side_sets;
    }
    if (maxset < model->num_elem_sets) {
      maxset = model->num_elem_sets;
    }
    if (maxset < model->num_node_maps) {
      maxset = model->num_node_maps;
    }
    if (maxset < model->num_edge_maps) {
      maxset = model->num_edge_maps;
    }
    if (maxset < model->num_face_maps) {
      maxset = model->num_face_maps;
    }
    if (maxset < model->num_elem_maps) {
      maxset = model->num_elem_maps;
    }

    /* allocate space for id/status array */
    if (!(invalid_ids = malloc(maxset * sizeof(int)))) {
      snprintf(errmsg, MAX_ERR_LENGTH,
               "ERROR: failed to allocate memory for id/status array for file id %d", exoid);
      ex_err(__func__, errmsg, EX_MEMFAIL);
      EX_FUNC_LEAVE(EX_FATAL);
    }

    invalidate_id_status(exoid, VAR_STAT_EL_BLK, VAR_ID_EL_BLK, model->num_elem_blk, invalid_ids);
    invalidate_id_status(exoid, VAR_STAT_ED_BLK, VAR_ID_ED_BLK, model->num_edge_blk, invalid_ids);
    invalidate_id_status(exoid, VAR_STAT_FA_BLK, VAR_ID_FA_BLK, model->num_face_blk, invalid_ids);
    invalidate_id_status(exoid, VAR_NS_STAT, VAR_NS_IDS, model->num_node_sets, invalid_ids);
    invalidate_id_status(exoid, VAR_ES_STAT, VAR_ES_IDS, model->num_edge_sets, invalid_ids);
    invalidate_id_status(exoid, VAR_FS_STAT, VAR_FS_IDS, model->num_face_sets, invalid_ids);
    invalidate_id_status(exoid, VAR_SS_STAT, VAR_SS_IDS, model->num_side_sets, invalid_ids);
    invalidate_id_status(exoid, VAR_ELS_STAT, VAR_ELS_IDS, model->num_elem_sets, invalid_ids);

    invalidate_id_status(exoid, 0, VAR_NM_PROP(1), model->num_node_maps, invalid_ids);
    invalidate_id_status(exoid, 0, VAR_EDM_PROP(1), model->num_edge_maps, invalid_ids);
    invalidate_id_status(exoid, 0, VAR_FAM_PROP(1), model->num_face_maps, invalid_ids);
    invalidate_id_status(exoid, 0, VAR_EM_PROP(1), model->num_elem_maps, invalid_ids);

    if (invalid_ids != NULL) {
      free(invalid_ids);
      invalid_ids = NULL;
    }
  }

  /* Write dummy values to the names arrays to avoid corruption issues on some
   * platforms */
  write_dummy_names(exoid, EX_ELEM_BLOCK, model->num_elem_blk);
  write_dummy_names(exoid, EX_EDGE_BLOCK, model->num_edge_blk);
  write_dummy_names(exoid, EX_FACE_BLOCK, model->num_face_blk);
  write_dummy_names(exoid, EX_NODE_SET, model->num_node_sets);
  write_dummy_names(exoid, EX_EDGE_SET, model->num_edge_sets);
  write_dummy_names(exoid, EX_FACE_SET, model->num_face_sets);
  write_dummy_names(exoid, EX_SIDE_SET, model->num_side_sets);
  write_dummy_names(exoid, EX_ELEM_SET, model->num_elem_sets);
  write_dummy_names(exoid, EX_NODE_MAP, model->num_node_maps);
  write_dummy_names(exoid, EX_EDGE_MAP, model->num_edge_maps);
  write_dummy_names(exoid, EX_FACE_MAP, model->num_face_maps);
  write_dummy_names(exoid, EX_ELEM_MAP, model->num_elem_maps);

  EX_FUNC_LEAVE(EX_NOERR);

/* Fatal error: exit definition mode and return */
error_ret:
  if ((status = nc_enddef(exoid)) != NC_NOERR) /* exit define mode */
  {
    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);
}
int ex_put_block_params( int         exoid,
			 size_t      block_count,
			 const struct ex_block *blocks)
{
  size_t i;
  int conn_int_type;
  int status;
  int arbitrary_polyhedra = 0; /* 1 if block is arbitrary 2d polyhedra type; 2 if 3d polyhedra */
  int att_name_varid = -1;
  int varid, dimid, dims[2], blk_id_ndx, blk_stat, strdim;
  size_t start[2];
  size_t num_blk;
  int cur_num_blk, numblkdim, numattrdim;
  int nnodperentdim = -1;
  int nedgperentdim = -1;
  int nfacperentdim = -1;
  int connid;
  int npeid;
  char errmsg[MAX_ERR_LENGTH];
  char entity_type1[5];
  char entity_type2[5];
  int* blocks_to_define = NULL;
  const char* dnumblk = NULL;
  const char* vblkids = NULL;
  const char* vblksta = NULL;
  const char* vnodcon = NULL;
  const char* vnpecnt = NULL;
  const char* vedgcon = NULL;
  const char* vfaccon = NULL;
  const char* vconn   = NULL;
  const char* vattnam = NULL;
  const char* vblkatt = NULL;
  const char* dneblk  = NULL;
  const char* dnape   = NULL;
  const char* dnnpe   = NULL;
  const char* dnepe   = NULL;
  const char* dnfpe   = NULL;

  exerrval  = 0; /* clear error code */

  blocks_to_define = malloc(block_count*sizeof(int));

  for (i=0; i < block_count; i++) {
    switch (blocks[i].type) {
    case EX_EDGE_BLOCK:
      dnumblk = DIM_NUM_ED_BLK;
      vblkids = VAR_ID_ED_BLK;
      vblksta = VAR_STAT_ED_BLK;
      break;
    case EX_FACE_BLOCK:
      dnumblk = DIM_NUM_FA_BLK;
      vblkids = VAR_ID_FA_BLK;
      vblksta = VAR_STAT_FA_BLK;
      break;
    case EX_ELEM_BLOCK:
      dnumblk = DIM_NUM_EL_BLK;
      vblkids = VAR_ID_EL_BLK;
      vblksta = VAR_STAT_EL_BLK;
      break;
    default:
      exerrval = EX_BADPARAM;
      sprintf( errmsg, "Error: Bad block type (%d) specified for entry %d file id %d",
	       blocks[i].type, (int)i, exoid );
      ex_err( "ex_put_block_params", errmsg, exerrval );
      free(blocks_to_define);
      return (EX_FATAL);
    }

    /* first check if any blocks of that type are specified */
    if ((status = ex_get_dimension(exoid, dnumblk, ex_name_of_object(blocks[i].type),
				   &num_blk, &dimid, "ex_put_block_params")) != NC_NOERR) {
      sprintf(errmsg,
	      "Error: No %ss defined in file id %d",
	      ex_name_of_object(blocks[i].type), exoid);
      ex_err("ex_put_block_params",errmsg,exerrval);
      free(blocks_to_define);
      return EX_FATAL;
    }

    /* Next: Make sure that there are not any duplicate block ids by
       searching the vblkids array.
       WARNING: This must be done outside of define mode because id_lkup accesses
       the database to determine the position
    */

    if ((status = nc_inq_varid(exoid, vblkids, &varid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to locate %s ids in file id %d",
	      ex_name_of_object(blocks[i].type), exoid);
      ex_err("ex_put_block_params",errmsg,exerrval);
      free(blocks_to_define);
      return EX_FATAL;
    }

    ex_id_lkup(exoid,blocks[i].type,blocks[i].id); /* Error value used, but don't need return value */
    if (exerrval != EX_LOOKUPFAIL) {   /* found the element block id */
      exerrval = EX_FATAL;
      sprintf(errmsg,
	      "Error: %s id %"PRId64" already exists in file id %d",
	      ex_name_of_object(blocks[i].type), blocks[i].id,exoid);
      ex_err("ex_put_block_params",errmsg,exerrval);
      free(blocks_to_define);
      return (EX_FATAL);
    }

    /* Keep track of the total number of element blocks defined using a counter 
       stored in a linked list keyed by exoid.
       NOTE: ex_get_file_item  is a function that finds the number of element 
       blocks for a specific file and returns that value.
    */
    cur_num_blk=ex_get_file_item(exoid, ex_get_counter_list(blocks[i].type));
    if (cur_num_blk >= (int)num_blk) {
      exerrval = EX_FATAL;
      sprintf(errmsg,
	      "Error: exceeded number of %ss (%d) defined in file id %d",
	      ex_name_of_object(blocks[i].type), (int)num_blk,exoid);
      ex_err("ex_put_block_params",errmsg,exerrval);
      free(blocks_to_define);
      return (EX_FATAL);
    }

    /*   NOTE: ex_inc_file_item  is a function that finds the number of element
	 blocks for a specific file and returns that value incremented. */
    cur_num_blk=ex_inc_file_item(exoid, ex_get_counter_list(blocks[i].type));
    start[0] = cur_num_blk;

    /* write out block id to previously defined id array variable*/
    status = nc_put_var1_longlong(exoid, varid, start, (long long*)&blocks[i].id);

    if (status != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to store %s id to file id %d",
	      ex_name_of_object(blocks[i].type), exoid);
      ex_err("ex_put_block_params",errmsg,exerrval);
      free(blocks_to_define);
      return (EX_FATAL);
    }

    blocks_to_define[i] = start[0]+1; /* element id index into vblkids array*/

    if (blocks[i].num_entry == 0) /* Is this a NULL element block? */
      blk_stat = 0; /* change element block status to NULL */
    else
      blk_stat = 1; /* change element block status to EX_EX_TRUE */

    if ((status = nc_inq_varid (exoid, vblksta, &varid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to locate %s status in file id %d",
	      ex_name_of_object(blocks[i].type), exoid);
      ex_err("ex_put_block_params",errmsg,exerrval);
      free(blocks_to_define);
      return (EX_FATAL);
    }

    if ((status = nc_put_var1_int(exoid, varid, start, &blk_stat)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to store %s id %"PRId64" status to file id %d",
	      ex_name_of_object(blocks[i].type), blocks[i].id, exoid);
      ex_err("ex_put_block_params",errmsg,exerrval);
      free(blocks_to_define);
      return (EX_FATAL);
    }
  }

  /* put netcdf file into define mode  */
  if ((status=nc_redef (exoid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,"Error: failed to place file id %d into define mode",exoid);
    ex_err("ex_put_block_params",errmsg,exerrval);
    free(blocks_to_define);
    return (EX_FATAL);
  }


  for (i=0; i < block_count; i++) {
    if (blocks[i].num_entry == 0) {/* Is this a NULL element block? */
      continue;
    }

    blk_id_ndx = blocks_to_define[i];

    switch (blocks[i].type) {
    case EX_EDGE_BLOCK:
      dneblk = DIM_NUM_ED_IN_EBLK(blk_id_ndx);
      dnnpe = DIM_NUM_NOD_PER_ED(blk_id_ndx);
      dnepe = 0;
      dnfpe = 0;
      dnape = DIM_NUM_ATT_IN_EBLK(blk_id_ndx);
      vblkatt = VAR_EATTRIB(blk_id_ndx);
      vattnam = VAR_NAME_EATTRIB(blk_id_ndx);
      vnodcon = VAR_EBCONN(blk_id_ndx);
      vedgcon = 0;
      vfaccon = 0;
      break;
    case EX_FACE_BLOCK:
      dneblk = DIM_NUM_FA_IN_FBLK(blk_id_ndx);
      dnnpe = DIM_NUM_NOD_PER_FA(blk_id_ndx);
      dnepe = 0;
      dnfpe = 0;
      dnape = DIM_NUM_ATT_IN_FBLK(blk_id_ndx);
      vblkatt = VAR_FATTRIB(blk_id_ndx);
      vattnam = VAR_NAME_FATTRIB(blk_id_ndx);
      vnodcon = VAR_FBCONN(blk_id_ndx);
      vnpecnt = VAR_FBEPEC(blk_id_ndx);
      vedgcon = 0;
      vfaccon = 0;
      break;
    case EX_ELEM_BLOCK:
      dneblk = DIM_NUM_EL_IN_BLK(blk_id_ndx);
      dnnpe = DIM_NUM_NOD_PER_EL(blk_id_ndx);
      dnepe = DIM_NUM_EDG_PER_EL(blk_id_ndx);
      dnfpe = DIM_NUM_FAC_PER_EL(blk_id_ndx);
      dnape = DIM_NUM_ATT_IN_BLK(blk_id_ndx);
      vblkatt = VAR_ATTRIB(blk_id_ndx);
      vattnam = VAR_NAME_ATTRIB(blk_id_ndx);
      vnodcon = VAR_CONN(blk_id_ndx);
      vnpecnt = VAR_EBEPEC(blk_id_ndx);
      vedgcon = VAR_ECONN(blk_id_ndx);
      vfaccon = VAR_FCONN(blk_id_ndx);
      break;
    default:
      goto error_ret;
    }

    /* define some dimensions and variables*/
    if ((status = nc_def_dim(exoid,dneblk,blocks[i].num_entry, &numblkdim )) != NC_NOERR) {
      if (status == NC_ENAMEINUSE) {        /* duplicate entry */
	exerrval = status;
	sprintf(errmsg,
		"Error: %s %"PRId64" already defined in file id %d",
		ex_name_of_object(blocks[i].type), blocks[i].id,exoid);
	ex_err("ex_put_block_params",errmsg,exerrval);
      } else {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to define number of entities/block for %s %"PRId64" file id %d",
		ex_name_of_object(blocks[i].type), blocks[i].id,exoid);
	ex_err("ex_put_block_params",errmsg,exerrval);
      }
      goto error_ret;         /* exit define mode and return */
    }

    if ( dnnpe && blocks[i].num_nodes_per_entry > 0) {
      /* A nfaced block would not have any nodes defined... */
      if ((status = nc_def_dim(exoid,dnnpe,blocks[i].num_nodes_per_entry, &nnodperentdim)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to define number of nodes/entity for %s %"PRId64" in file id %d",
		ex_name_of_object(blocks[i].type), blocks[i].id,exoid);
	ex_err("ex_put_block_params",errmsg,exerrval);
	goto error_ret;         /* exit define mode and return */
      }
    }

    if (dnepe && blocks[i].num_edges_per_entry > 0 ) {
      if ((status = nc_def_dim (exoid,dnepe,blocks[i].num_edges_per_entry, &nedgperentdim)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to define number of edges/entity for %s %"PRId64" in file id %d",
		ex_name_of_object(blocks[i].type), blocks[i].id,exoid);
	ex_err("ex_put_block_params",errmsg,exerrval);
	goto error_ret;         /* exit define mode and return */
      }
    }

    if ( dnfpe && blocks[i].num_faces_per_entry > 0 ) {
      if ((status = nc_def_dim(exoid,dnfpe,blocks[i].num_faces_per_entry, &nfacperentdim)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to define number of faces/entity for %s %"PRId64" in file id %d",
		ex_name_of_object(blocks[i].type), blocks[i].id,exoid);
	ex_err("ex_put_block_params",errmsg,exerrval);
	goto error_ret;         /* exit define mode and return */
      }
    }

    /* element attribute array */
    if (blocks[i].num_attribute > 0) {

      if ((status = nc_def_dim(exoid, dnape, blocks[i].num_attribute, &numattrdim)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to define number of attributes in %s %"PRId64" in file id %d",
		ex_name_of_object(blocks[i].type), blocks[i].id,exoid);
	ex_err("ex_put_block_params",errmsg,exerrval);
	goto error_ret;         /* exit define mode and return */
      }

      dims[0] = numblkdim;
      dims[1] = numattrdim;

      if ((status = nc_def_var(exoid, vblkatt, nc_flt_code(exoid), 2, dims, &varid)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error:  failed to define attributes for %s %"PRId64" in file id %d",
		ex_name_of_object(blocks[i].type), blocks[i].id,exoid);
	ex_err("ex_put_block_params",errmsg,exerrval);
	goto error_ret;         /* exit define mode and return */
      }
      ex_compress_variable(exoid, varid, 2);

      /* inquire previously defined dimensions  */
      if ((status = nc_inq_dimid(exoid, DIM_STR_NAME, &strdim)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to get string length in file id %d",exoid);
	ex_err("ex_put_block_params",errmsg,exerrval);
	goto error_ret;
      }
     
      /* Attribute names... */
      dims[0] = numattrdim;
      dims[1] = strdim;
	    
      if ((status = nc_def_var(exoid, vattnam, NC_CHAR, 2, dims, &att_name_varid)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to define %s attribute name array in file id %d",
		ex_name_of_object(blocks[i].type), exoid);
	ex_err("ex_put_block_params",errmsg,exerrval);
	goto error_ret;         /* exit define mode and return */
      }
    }

    conn_int_type = NC_INT;
    if (ex_int64_status(exoid) & EX_BULK_INT64_DB) {
      conn_int_type = NC_INT64;
    }

    /* See if storing an 'nsided' element block (arbitrary 2d polyhedra or super element) */
    if (strlen(blocks[i].topology) >= 3) {
      if ((blocks[i].topology[0] == 'n' || blocks[i].topology[0] == 'N') &&
	  (blocks[i].topology[1] == 's' || blocks[i].topology[1] == 'S') &&
	  (blocks[i].topology[2] == 'i' || blocks[i].topology[2] == 'I'))
	arbitrary_polyhedra = 1;
      else if ((blocks[i].topology[0] == 'n' || blocks[i].topology[0] == 'N') &&
	       (blocks[i].topology[1] == 'f' || blocks[i].topology[1] == 'F') &&
	       (blocks[i].topology[2] == 'a' || blocks[i].topology[2] == 'A'))
	/* If a FACE_BLOCK, then we are dealing with the faces of the nfaced blocks[i]. */
	arbitrary_polyhedra = blocks[i].type == EX_FACE_BLOCK ? 1 : 2;
    }

    /* element connectivity array */
    if (arbitrary_polyhedra > 0) {
      if (blocks[i].type != EX_FACE_BLOCK && blocks[i].type != EX_ELEM_BLOCK) {
	exerrval = EX_BADPARAM;
	sprintf( errmsg, "Error: Bad block type (%d) for nsided/nfaced block in file id %d",
		 blocks[i].type, exoid );
	ex_err( "ex_put_block_params", errmsg, exerrval );
	goto error_ret;
      }

      if (arbitrary_polyhedra == 1) {
	dims[0] = nnodperentdim;
	vconn = vnodcon;

	/* store entity types as attribute of npeid variable -- node/elem, node/face, face/elem*/
	strcpy(entity_type1, "NODE");
	if (blocks[i].type == EX_ELEM_BLOCK)
	  strcpy(entity_type2, "ELEM");
	else
	  strcpy(entity_type2, "FACE");
      } else if (arbitrary_polyhedra == 2) {
	dims[0] = nfacperentdim;
	vconn = vfaccon;

	/* store entity types as attribute of npeid variable -- node/elem, node/face, face/elem*/
	strcpy(entity_type1, "FACE");
	strcpy(entity_type2, "ELEM");
      }

      if ((status = nc_def_var(exoid, vconn, conn_int_type, 1, dims, &connid)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to create connectivity array for %s %"PRId64" in file id %d",
		ex_name_of_object(blocks[i].type), blocks[i].id,exoid);
	ex_err("ex_put_block_params",errmsg,exerrval);
	goto error_ret;         /* exit define mode and return */
      }
    
      /* element face-per-element or node-per-element count array */
      dims[0] = numblkdim;
    
      if ((status = nc_def_var(exoid, vnpecnt, conn_int_type, 1, dims, &npeid)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to create face- or node- per-entity count array for %s %"PRId64" in file id %d",
		ex_name_of_object(blocks[i].type), blocks[i].id, exoid);
	ex_err("ex_put_block_params",errmsg,exerrval);
	goto error_ret;         /* exit define mode and return */
      }

      if ((status = nc_put_att_text(exoid, npeid, "entity_type1", strlen(entity_type1)+1,
				    entity_type1)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to store entity type attribute text for %s %"PRId64" in file id %d",
		ex_name_of_object(blocks[i].type), blocks[i].id, exoid);
	ex_err("ex_put_block_params",errmsg,exerrval);
	goto error_ret;         /* exit define mode and return */
      }
      if ((status = nc_put_att_text(exoid, npeid, "entity_type2", strlen(entity_type2)+1,
				    entity_type2)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to store entity type attribute text for %s %"PRId64" in file id %d",
		ex_name_of_object(blocks[i].type), blocks[i].id, exoid);
	ex_err("ex_put_block_params",errmsg,exerrval);
	goto error_ret;         /* exit define mode and return */
      }
    } else {
      /* "Normal" (non-polyhedra) element block type */
      dims[0] = numblkdim;
      dims[1] = nnodperentdim;
    
      if ((status = nc_def_var(exoid, vnodcon, conn_int_type, 2, dims, &connid)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to create connectivity array for %s %"PRId64" in file id %d",
		ex_name_of_object(blocks[i].type), blocks[i].id,exoid);
	ex_err("ex_put_block_params",errmsg,exerrval);
	goto error_ret;         /* exit define mode and return */
      }
      ex_compress_variable(exoid, connid, 1);
    }
    /* store element type as attribute of connectivity variable */
    if ((status = nc_put_att_text(exoid, connid, ATT_NAME_ELB, strlen(blocks[i].topology)+1, 
				  blocks[i].topology)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to store %s type name %s in file id %d",
	      ex_name_of_object(blocks[i].type), blocks[i].topology,exoid);
      ex_err("ex_put_block_params",errmsg,exerrval);
      goto error_ret;         /* exit define mode and return */
    }

    if (arbitrary_polyhedra == 0) {
      if (vedgcon && blocks[i].num_edges_per_entry ) {
	dims[0] = numblkdim;
	dims[1] = nedgperentdim;
      
	if ((status = nc_def_var(exoid, vedgcon, conn_int_type, 2, dims, &varid)) != NC_NOERR) {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: failed to create edge connectivity array for %s %"PRId64" in file id %d",
		  ex_name_of_object(blocks[i].type), blocks[i].id,exoid);
	  ex_err("ex_put_block_params",errmsg,exerrval);
	  goto error_ret;         /* exit define mode and return */
	}
      }
    
      if ( vfaccon && blocks[i].num_faces_per_entry ) {
	dims[0] = numblkdim;
	dims[1] = nfacperentdim;
      
	if ((status = nc_def_var(exoid, vfaccon, conn_int_type, 2, dims, &varid)) != NC_NOERR) {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: failed to create face connectivity array for %s %"PRId64" in file id %d",
		  ex_name_of_object(blocks[i].type), blocks[i].id,exoid);
	  ex_err("ex_put_block_params",errmsg,exerrval);
	  goto error_ret;         /* exit define mode and return */
	}
      }
    }
  }

  free(blocks_to_define);

  /* leave define mode  */
  if ((exerrval=nc_enddef (exoid)) != NC_NOERR) {
    sprintf(errmsg,
	    "Error: failed to complete %s definition in file id %d", 
	    ex_name_of_object(blocks[i].type), exoid);
    ex_err("ex_put_block_params",errmsg,exerrval);
    return (EX_FATAL);
  }


  for (i=0; i < block_count; i++) {
    switch (blocks[i].type) {
    case EX_EDGE_BLOCK:
      vblkids = VAR_ID_ED_BLK;
      break;
    case EX_FACE_BLOCK:
      vblkids = VAR_ID_FA_BLK;
      break;
    case EX_ELEM_BLOCK:
      vblkids = VAR_ID_EL_BLK;
      break;
    default:
      return (EX_FATAL); /* should have been handled earlier; quiet compiler here */
    }

    nc_inq_varid(exoid, vblkids, &att_name_varid);

    if (blocks[i].num_attribute > 0 && att_name_varid >= 0) {
      /* Output a dummy empty attribute name in case client code doesn't
	 write anything; avoids corruption in some cases.
      */
      size_t  count[2];
      char *text = "";
      size_t j;

      count[0] = 1;
      start[1] = 0;
      count[1] = strlen(text)+1;
  
      for (j = 0; j < blocks[i].num_attribute; j++) {
	start[0] = j;
	nc_put_vara_text(exoid, att_name_varid, start, count, text);
      }
    }
  }

  return (EX_NOERR);

  /* Fatal error: exit definition mode and return */
 error_ret:
  free(blocks_to_define);

  if (nc_enddef (exoid) != NC_NOERR) {    /* exit define mode */
    sprintf(errmsg,
	    "Error: failed to complete definition for file id %d",
	    exoid);
    ex_err("ex_put_block_params",errmsg,exerrval);
  }
  return (EX_FATAL);
}
int ex_put_id_map (int  exoid,
		   ex_entity_type map_type,
		   const void_int *map)
{
  int dimid, mapid, status, dims[1];
  int map_int_type;
  char errmsg[MAX_ERR_LENGTH];
  const char* tname;
  const char* dnumentries;
  const char* vmap;

  exerrval = 0; /* clear error code */

  switch ( map_type ) {
  case EX_NODE_MAP:
    tname = "node";
    dnumentries = DIM_NUM_NODES;
    vmap = VAR_NODE_NUM_MAP;
    break;
  case EX_EDGE_MAP:
    tname = "edge";
    dnumentries = DIM_NUM_EDGE;
    vmap = VAR_EDGE_NUM_MAP;
    break;
  case EX_FACE_MAP:
    tname = "face";
    dnumentries = DIM_NUM_FACE;
    vmap = VAR_FACE_NUM_MAP;
    break;
  case EX_ELEM_MAP:
    tname = "element";
    dnumentries = DIM_NUM_ELEM;
    vmap = VAR_ELEM_NUM_MAP;
    break;
  default:
    exerrval = EX_BADPARAM;
    sprintf( errmsg,
	     "Error: Bad map type (%d) specified for file id %d",
	     map_type, exoid );
    ex_err( "ex_put_id_map", errmsg, exerrval );
    return (EX_FATAL);
  }

  /* Make sure the file contains entries */
  if (nc_inq_dimid (exoid, dnumentries, &dimid) != NC_NOERR) {
    return (EX_NOERR);
  }
   
  /* put netcdf file into define mode  */
  if (nc_inq_varid (exoid, vmap, &mapid) != NC_NOERR) {
    if ((status = nc_redef (exoid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to put file id %d into define mode",
	      exoid);
      ex_err("ex_put_id_map",errmsg,exerrval);
      return (EX_FATAL);
    }
    

    /* create a variable array in which to store the id map  */
    dims[0] = dimid;
    
    /* Check type to be used for maps... */
    map_int_type = NC_INT;
    if (ex_int64_status(exoid) & EX_MAPS_INT64_DB) {
      map_int_type = NC_INT64;
    }
    
    if ((status = nc_def_var(exoid, vmap, map_int_type, 1, dims, &mapid)) != NC_NOERR) {
      if (status == NC_ENAMEINUSE) {
	exerrval = status;
	sprintf(errmsg,
		"Error: %s numbering map already exists in file id %d",
		tname, exoid);
	ex_err("ex_put_id_map",errmsg,exerrval);
      } else {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to create %s id map in file id %d",
		tname, exoid);
	ex_err("ex_put_id_map",errmsg,exerrval);
      }
      goto error_ret;         /* exit define mode and return */
    }
    ex_compress_variable(exoid, mapid, 1);
    

    /* leave define mode  */
    if ((status = nc_enddef (exoid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to complete definition in file id %d",
	      exoid);
      ex_err("ex_put_id_map",errmsg,exerrval);
      return (EX_FATAL);
    }
  }

  /* write out the entity numbering map  */
  if (ex_int64_status(exoid) & EX_MAPS_INT64_API) {
    status = nc_put_var_longlong(exoid, mapid, map);
  } else {
    status = nc_put_var_int(exoid, mapid, map);
  }

  if (status!= NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to store %s numbering map in file id %d",
	    tname, exoid);
    ex_err("ex_put_id_map",errmsg,exerrval);
    return (EX_FATAL);
  }


  return (EX_NOERR);

  /* Fatal error: exit definition mode and return */
 error_ret:
  if (nc_enddef (exoid) != NC_NOERR)     /* exit define mode */
    {
      sprintf(errmsg,
              "Error: failed to complete definition for file id %d",
              exoid);
      ex_err("ex_put_id_map",errmsg,exerrval);
    }
  return (EX_FATAL);
}
Exemple #11
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);
}
int ex_put_variable_param (int exoid,
			   ex_entity_type obj_type,
			   int num_vars)
{
  int time_dim, num_nod_dim, dimid, dim_str_name, varid;
  int dims[3];
  char errmsg[MAX_ERR_LENGTH];
  int status;

  exerrval = 0; /* clear error code */

  /* if no variables are to be stored, return with warning */
  if (num_vars == 0) {
    exerrval = EX_MSG;
    sprintf(errmsg,
	    "Warning: zero %s variables specified for file id %d",
	    ex_name_of_object(obj_type),exoid);
    ex_err("ex_put_variable_param",errmsg,exerrval);

    return (EX_WARN);
  }

  if ( obj_type != EX_NODAL      &&
       obj_type != EX_NODE_SET   &&
       obj_type != EX_EDGE_BLOCK &&
       obj_type != EX_EDGE_SET   &&
       obj_type != EX_FACE_BLOCK &&
       obj_type != EX_FACE_SET   &&
       obj_type != EX_ELEM_BLOCK &&
       obj_type != EX_ELEM_SET   &&
       obj_type != EX_SIDE_SET   &&
       obj_type != EX_GLOBAL) {
    exerrval = EX_BADPARAM;
    sprintf(errmsg,
	    "Error: Invalid variable type %d specified in file id %d",
	    obj_type, exoid);
    ex_err("ex_put_variable_param",errmsg,exerrval);
    return (EX_WARN);
  }

  /* inquire previously defined dimensions  */
  if ((status = nc_inq_dimid (exoid, DIM_TIME, &time_dim)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to locate time dimension in file id %d", exoid);
    ex_err("ex_put_variable_param",errmsg,exerrval);
    return (EX_FATAL);
  }

  if ((status = nc_inq_dimid (exoid, DIM_NUM_NODES, &num_nod_dim)) != NC_NOERR) {
    if (obj_type == EX_NODAL) {
      return (EX_NOERR); /* Probably no nodes on database (e.g., badly load-balanced parallel run) */
    }
  }

  if ((status = nc_inq_dimid (exoid, DIM_STR_NAME, &dim_str_name)) < 0) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to get name string length in file id %d",exoid);
    ex_err("ex_put_variable_param",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* put file into define mode  */
  if ((status = nc_redef (exoid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to put file id %d into define mode", exoid);
    ex_err("ex_get_var_param",errmsg,exerrval);
    return (EX_FATAL);
  }


  /* define dimensions and variables */
  if (obj_type == EX_GLOBAL) {
    if ((status = ex_prepare_result_var(exoid, num_vars, "global",
					DIM_NUM_GLO_VAR,VAR_NAME_GLO_VAR)) == 1) {
      goto error_ret;
}

    if ((status = nc_inq_dimid (exoid, DIM_NUM_GLO_VAR, &dimid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to get global variable count in file id %d",exoid);
      ex_err("ex_put_variable_param",errmsg,exerrval);
      return (EX_FATAL);
    }
    dims[0] = time_dim;
    dims[1] = dimid;
    if ((status = nc_def_var (exoid, VAR_GLO_VAR,
			      nc_flt_code(exoid), 2, dims, &varid)) != NC_NOERR)
      {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to define global variables in file id %d",
		exoid);
	ex_err("ex_put_variable_param",errmsg,exerrval);
	goto error_ret;          /* exit define mode and return */
      }
    ex_compress_variable(exoid, varid, 2);
  }

  else if (obj_type == EX_NODAL) {
    /*
     * There are two ways to store the nodal variables. The old way *
     * was a blob (#times,#vars,#nodes), but that was exceeding the
     * netcdf maximum dataset size for large models. The new way is
     * to store #vars separate datasets each of size (#times,#nodes)
     *
     * We want this routine to be capable of storing both formats
     * based on some external flag.  Since the storage format of the
     * coordinates have also been changed, we key off of their
     * storage type to decide which method to use for nodal
     * variables. If the variable 'coord' is defined, then store old
     * way; otherwise store new.
     */
    if ((status = nc_def_dim(exoid, DIM_NUM_NOD_VAR, num_vars, &dimid)) != NC_NOERR) {
      if (status == NC_ENAMEINUSE) {
	exerrval = status;
	sprintf(errmsg,
		"Error: nodal variable name parameters are already defined in file id %d",
		exoid);
	ex_err("ex_put_variable_param",errmsg,exerrval);
      } else {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to define number of nodal variables in file id %d",
		exoid);
	ex_err("ex_put_variable_param",errmsg,exerrval);
      }
      goto error_ret;          /* exit define mode and return */
    }

    if (ex_large_model(exoid) == 0) { /* Old way */
      dims[0] = time_dim;
      dims[1] = dimid;
      dims[2] = num_nod_dim;
      if ((status = nc_def_var(exoid, VAR_NOD_VAR,
			       nc_flt_code(exoid), 3, dims, &varid)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to define nodal variables in file id %d",
		exoid);
	ex_err("ex_put_variable_param",errmsg,exerrval);
	goto error_ret;          /* exit define mode and return */
      }
      ex_compress_variable(exoid, varid, 2);
    } else { /* New way */
      int i;
      for (i = 1; i <= num_vars; i++) {
	dims[0] = time_dim;
	dims[1] = num_nod_dim;
	if ((status = nc_def_var (exoid, VAR_NOD_VAR_NEW(i),
				  nc_flt_code(exoid), 2, dims, &varid)) != NC_NOERR) {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: failed to define nodal variable %d in file id %d",
		  i, exoid);
	  ex_err("ex_put_variable_param",errmsg,exerrval);
	  goto error_ret;          /* exit define mode and return */
	}
	ex_compress_variable(exoid, varid, 2);
      }
    }

    /* Now define nodal variable name variable */
    dims[0] = dimid;
    dims[1] = dim_str_name;
    if ((status = nc_def_var(exoid, VAR_NAME_NOD_VAR, NC_CHAR, 2, dims, &varid)) != NC_NOERR) {
      if (status == NC_ENAMEINUSE) {
	exerrval = status;
	sprintf(errmsg,
		"Error: nodal variable names are already defined in file id %d",
		exoid);
	ex_err("ex_put_variable_param",errmsg,exerrval);
      } else {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to define nodal variable names in file id %d",
		exoid);
	ex_err("ex_put_variable_param",errmsg,exerrval);
      }
      goto error_ret;          /* exit define mode and return */
    }
  }

  /* netCDF variables in which to store the EXODUS obj_type variable values will
   * be defined in ex_put_*_var_tab or ex_put_*_var; at this point, we
   * don't know what obj_type variables are valid for which obj_type blocks
   * (the info that is stored in the obj_type variable truth table)
   */
  else if (obj_type == EX_ELEM_BLOCK)  {
    if ((status = ex_prepare_result_var(exoid, num_vars, "element",
					DIM_NUM_ELE_VAR, VAR_NAME_ELE_VAR)) == 1) {
      goto error_ret;
}
  }
  else if (obj_type == EX_NODE_SET) {
    if ((status = ex_prepare_result_var(exoid, num_vars, "nodeset",
					DIM_NUM_NSET_VAR,VAR_NAME_NSET_VAR)) == 1) {
      goto error_ret;
}
  }
  else if (obj_type == EX_SIDE_SET) {
    if ((status = ex_prepare_result_var(exoid, num_vars, "sideset",
					DIM_NUM_SSET_VAR,VAR_NAME_SSET_VAR)) == 1) {
      goto error_ret;
}
  }
  else if (obj_type == EX_EDGE_BLOCK) {
    if ((status = ex_prepare_result_var(exoid, num_vars, "edge",
					DIM_NUM_EDG_VAR,VAR_NAME_EDG_VAR)) == 1) {
      goto error_ret;
}
  }
  else if (obj_type == EX_FACE_BLOCK) {
    if ((status = ex_prepare_result_var(exoid, num_vars, "face",
					DIM_NUM_FAC_VAR,VAR_NAME_FAC_VAR)) == 1) {
      goto error_ret;
}
  }
  else if (obj_type == EX_EDGE_SET) {
    if ((status = ex_prepare_result_var(exoid, num_vars, "edgeset",
					DIM_NUM_ESET_VAR,VAR_NAME_ESET_VAR)) == 1) {
      goto error_ret;
}
  }
  else if (obj_type == EX_FACE_SET) {
    if ((status = ex_prepare_result_var(exoid, num_vars, "faceset",
					DIM_NUM_FSET_VAR,VAR_NAME_FSET_VAR)) == 1) {
      goto error_ret;
}
  }
  else if (obj_type == EX_ELEM_SET) {
    if ((status = ex_prepare_result_var(exoid, num_vars, "elementset",
					DIM_NUM_ELSET_VAR,VAR_NAME_ELSET_VAR))==1) {
      goto error_ret;
}
  }

  /* leave define mode  */
  if ((status = nc_enddef (exoid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to complete definition in file id %d",
	    exoid);
    ex_err("ex_put_variable_param",errmsg,exerrval);
    return (EX_FATAL);
  }

  return(EX_NOERR);

  /* Fatal error: exit definition mode and return */
 error_ret:
  if ((status = nc_enddef(exoid)) != NC_NOERR) {    /* exit define mode */
    sprintf(errmsg,
	    "Error: failed to complete definition for file id %d",
	    exoid);
    ex_err("ex_put_variable_param",errmsg,exerrval);
  }
  return (EX_FATAL);
}
Exemple #13
0
int ex_put_cmap_params(int  exoid,
                       void_int *node_cmap_ids,
                       void_int *node_cmap_node_cnts,
                       void_int *elem_cmap_ids,
                       void_int *elem_cmap_elem_cnts,
                       int64_t  processor
                       )
{
  const char   *func_name="ex_put_cmap_params";

  size_t  num_n_comm_maps, num_e_comm_maps;
  size_t  ncnt_cmap, ecnt_cmap;
  size_t  icm;
  int     varid, dimid[1], n_varid, e_varid, status;
  int     n_varid_idx, e_varid_idx;
  size_t  start[1];
  char    ftype[2];
  int64_t nl_ncnt_cmap, nl_ecnt_cmap;
  int  nmstat;

  char    errmsg[MAX_ERR_LENGTH];

  int index_type = NC_INT;
  int id_type  = NC_INT;
  int format;
  nc_inq_format(exoid, &format);
  if ((ex_int64_status(exoid) & EX_BULK_INT64_DB) || (format == NC_FORMAT_NETCDF4)) {
    index_type = NC_INT64;
  }
  if (ex_int64_status(exoid) & EX_IDS_INT64_DB) {
    id_type = NC_INT64;
  }
/*-----------------------------Execution begins-----------------------------*/

  exerrval = 0; /* clear error code */

  /*
  ** with the new database format, this function sould only
  ** be used for writing a parallel file
  */
  /* Get the file type */
  if (ex_get_file_type(exoid, ftype) != EX_NOERR) {
    exerrval = EX_MSG;
    sprintf(errmsg,
            "Error: failed to get file type from file ID %d\n",
            exoid);
    ex_err(func_name, errmsg, exerrval);
    return (EX_FATAL);
  }

  /* make sure that this is a parallel file */
  if (ftype[0] != 'p') {
    exerrval = EX_MSG;
    sprintf(errmsg,
            "Error: function for use with parallel files only, file ID %d\n",
            exoid);
    ex_err(func_name, errmsg, exerrval);
    return (EX_FATAL);
  }

  /* Put NetCDF file into define mode */
  if ((status = nc_redef(exoid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
            "Error: failed to file ID %d into define mode", exoid);
    ex_err(func_name, errmsg, exerrval);
    return (EX_FATAL);
  }

  /* Check to see if there are nodal communications maps in the file */
  if ((status = nc_inq_dimid(exoid, DIM_NUM_N_CMAPS, &dimid[0])) != NC_NOERR) {
    num_n_comm_maps = 0;
  }
  else {
    if ((status = nc_inq_dimlen(exoid, dimid[0], &num_n_comm_maps)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to find length of dimension \"%s\" in file ID %d",
              DIM_NUM_N_CMAPS, exoid);
      ex_err(func_name, errmsg, exerrval);
      return (EX_FATAL);
    }
  }

  /*
   * Add dimensions for the size of the number of nodal
   * communication maps.
   */
  if (num_n_comm_maps > 0) {

    /* add the communications data index variable */
    if ((status = nc_def_var(exoid, VAR_N_COMM_DATA_IDX, index_type, 1,
			     dimid, &n_varid_idx)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to add variable \"%s\" in file ID %d",
              VAR_N_COMM_DATA_IDX, exoid);
      ex_err(func_name, errmsg, exerrval);
      /* Leave define mode before returning */
      ex_leavedef(exoid, func_name);

      return (EX_FATAL);
    }

    /* Add dimensions for all of the nodal communication maps */
    ncnt_cmap = 0;
    if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
      for(icm=0; icm < num_n_comm_maps; icm++) {
	ncnt_cmap += ((int64_t*)node_cmap_node_cnts)[icm];
      }
    } else {
      for(icm=0; icm < num_n_comm_maps; icm++) {
	ncnt_cmap += ((int*)node_cmap_node_cnts)[icm];
      }
    }

    if ((status = nc_def_dim(exoid, DIM_NCNT_CMAP, ncnt_cmap, &dimid[0])) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to add dimension for \"%s\" in file ID %d",
              DIM_NCNT_CMAP, exoid);
      ex_err(func_name, errmsg, exerrval);
      /* Leave define mode before returning */
      ex_leavedef(exoid, func_name);

      return (EX_FATAL);
    }

    /* Define variables for the nodal IDS and processor vectors */
    if ((status = nc_def_var(exoid, VAR_N_COMM_NIDS, id_type, 1, dimid, &varid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to add variable \"%s\" in file ID %d",
              VAR_N_COMM_NIDS, exoid);
      ex_err(func_name, errmsg, exerrval);
      /* Leave define mode before returning */
      ex_leavedef(exoid, func_name);

      return (EX_FATAL);
    }
    ex_compress_variable(exoid, varid, 1);

    if ((status = nc_def_var(exoid, VAR_N_COMM_PROC, NC_INT, 1, dimid, &varid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to add variable \"%s\" in file ID %d",
              VAR_N_COMM_PROC, exoid);
      ex_err(func_name, errmsg, exerrval);
      /* Leave define mode before returning */
      ex_leavedef(exoid, func_name);

      return (EX_FATAL);
    }
    ex_compress_variable(exoid, varid, 1);

  } /* End "if (num_n_comm_maps > 0)" */

  /* Check to see if there are elemental communications maps in the file */
  if ((status = nc_inq_dimid(exoid, DIM_NUM_E_CMAPS, &dimid[0])) != NC_NOERR) {
    num_e_comm_maps = 0;
  }
  else{
    if ((status = nc_inq_dimlen(exoid, dimid[0], &num_e_comm_maps)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to find length of dimension \"%s\" in file ID %d",
              DIM_NUM_E_CMAPS, exoid);
      ex_err(func_name, errmsg, exerrval);
      return (EX_FATAL);
    }

  }

  /*
   * Add dimensions for the size of the number of elemental
   * communication maps.
   */
  if (num_e_comm_maps > 0) {

    /* add the communications data index variable */
    if ((status = nc_def_var(exoid, VAR_E_COMM_DATA_IDX, index_type, 1,
			     dimid, &e_varid_idx)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to add variable \"%s\" in file ID %d",
              VAR_E_COMM_DATA_IDX, exoid);
      ex_err(func_name, errmsg, exerrval);
      /* Leave define mode before returning */
      ex_leavedef(exoid, func_name);

      return (EX_FATAL);
    }

    /* Add dimensions for each of the nodal communication maps */
    ecnt_cmap = 0;
    if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
      for(icm=0; icm < num_e_comm_maps; icm++)
	ecnt_cmap += ((int64_t*)elem_cmap_elem_cnts)[icm];
    } else {
      for(icm=0; icm < num_e_comm_maps; icm++)
	ecnt_cmap += ((int*)elem_cmap_elem_cnts)[icm];
    }
    if ((status = nc_def_dim(exoid, DIM_ECNT_CMAP, ecnt_cmap, &dimid[0])) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to add dimension for \"%s\" in file ID %d",
              DIM_ECNT_CMAP, exoid);
      ex_err(func_name, errmsg, exerrval);
      /* Leave define mode before returning */
      ex_leavedef(exoid, func_name);

      return (EX_FATAL);
    }

    /* Define variables for the element IDS and processor vectors */
    if ((status = nc_def_var(exoid, VAR_E_COMM_EIDS, id_type, 1, dimid, &varid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to add variable \"%s\" in file ID %d",
              VAR_E_COMM_EIDS, exoid);
      ex_err(func_name, errmsg, exerrval);
      /* Leave define mode before returning */
      ex_leavedef(exoid, func_name);

      return (EX_FATAL);
    }
    ex_compress_variable(exoid, varid, 1);

    if ((status = nc_def_var(exoid, VAR_E_COMM_PROC, NC_INT, 1, dimid, &varid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to add variable \"%s\" in file ID %d",
              VAR_E_COMM_PROC, exoid);
      ex_err(func_name, errmsg, exerrval);
      /* Leave define mode before returning */
      ex_leavedef(exoid, func_name);

      return (EX_FATAL);
    }
    ex_compress_variable(exoid, varid, 1);

    if ((status = nc_def_var(exoid, VAR_E_COMM_SIDS, NC_INT, 1, dimid, &varid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to add variable \"%s\" in file ID %d",
              VAR_E_COMM_SIDS, exoid);
      ex_err(func_name, errmsg, exerrval);
      /* Leave define mode before returning */
      ex_leavedef(exoid, func_name);

      return (EX_FATAL);
    }
    ex_compress_variable(exoid, varid, 1);

  } /* End "if (num_e_comm_maps > 0)" */

  /* Exit define mode */
  ex_leavedef(exoid, func_name);

  /* Set the status of the nodal communication maps */
  if (num_n_comm_maps > 0) {

    if ((status = nc_inq_varid(exoid, VAR_N_COMM_STAT, &n_varid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to find variable ID for \"%s\" in file ID %d",
              VAR_N_COMM_STAT, exoid);
      ex_err(func_name, errmsg, exerrval);
      return (EX_FATAL);
    }

    nl_ncnt_cmap = 0; /* reset this for index */
    for(icm=0; icm < num_n_comm_maps; icm++) {

      size_t ncnc;
      if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
	ncnc = ((int64_t*)node_cmap_node_cnts)[icm];
      } else {
	ncnc = ((int*)node_cmap_node_cnts)[icm];
      }

      start[0] = icm;
      if (ncnc > 0)
        nmstat = 1;
      else
        nmstat = 0;

      if ((status = nc_put_var1_int(exoid, n_varid, start, &nmstat)) != NC_NOERR) {
        exerrval = status;
        sprintf(errmsg,
                "Error: unable to output variable in file ID %d", exoid);
        ex_err(func_name, errmsg, exerrval);
        return (EX_FATAL);
      }

      /* increment to the next starting position */
      nl_ncnt_cmap += ncnc;

      /* fill the cmap data index */
      if ((status = nc_put_var1_longlong(exoid, n_varid_idx, start, (long long*)&nl_ncnt_cmap)) != NC_NOERR) {
        exerrval = status;
        sprintf(errmsg,
                "Error: failed to output int elem map index in file ID %d",
                exoid);
        ex_err(func_name, errmsg, exerrval);
        return (EX_FATAL);
      }
    } /* End "for(icm=0; icm < num_n_comm_maps; icm++)" */

    /* Get the variable ID for the comm map IDs vector */
    if ((status = nc_inq_varid(exoid, VAR_N_COMM_IDS, &n_varid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to find variable ID for \"%s\" in file ID %d",
              VAR_N_COMM_IDS, exoid);
      ex_err(func_name, errmsg, exerrval);
      return (EX_FATAL);
    }

    /* Output the nodal comm map IDs */
    if (ex_int64_status(exoid) & EX_IDS_INT64_API) {
      status  = nc_put_var_longlong(exoid, n_varid, node_cmap_ids);
    } else {
      status  = nc_put_var_int(exoid, n_varid, node_cmap_ids);
    }
    if (status != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to output variable in file ID %d", exoid);
      ex_err(func_name, errmsg, exerrval);
      return (EX_FATAL);
    }

  } /* End "if (num_n_comm_maps > 0)" */

  /* Set the status of the elemental communication maps */
  if (num_e_comm_maps > 0) {

    /* Get variable ID for elemental status vector */
    if ((status = nc_inq_varid(exoid, VAR_E_COMM_STAT, &e_varid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to find variable ID for \"%s\" in file ID %d",
              VAR_E_COMM_STAT, exoid);
      ex_err(func_name, errmsg, exerrval);
      return (EX_FATAL);
    }

    nl_ecnt_cmap = 0; /* reset this for index */
    for(icm=0; icm < num_e_comm_maps; icm++) {
      size_t ecec;
      if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
	ecec = ((int64_t*)elem_cmap_elem_cnts)[icm];
      } else {
	ecec = ((int*)elem_cmap_elem_cnts)[icm];
      }
      start[0] = icm;
      if (ecec > 0)
        nmstat = 1;
      else
        nmstat = 0;

      if ((status = nc_put_var1_int(exoid, e_varid, start, &nmstat)) != NC_NOERR) {
        exerrval = status;
        sprintf(errmsg,
                "Error: unable to output variable in file ID %d", exoid);
        ex_err(func_name, errmsg, exerrval);
        return (EX_FATAL);
      }

      /* increment to the next starting position */
      nl_ecnt_cmap += ecec;

      /* fill the cmap data index */
      if ((status = nc_put_var1_longlong(exoid, e_varid_idx, start, (long long*)&nl_ecnt_cmap)) != NC_NOERR) {
        exerrval = status;
        sprintf(errmsg,
                "Error: failed to output int elem map index in file ID %d",
                exoid);
        ex_err(func_name, errmsg, exerrval);
        return (EX_FATAL);
      }
     } /* End "for(icm=0; icm < num_e_comm_maps; icm++)" */

    /* Get the variable ID for the elemental comm map IDs vector */
    if ((status = nc_inq_varid(exoid, VAR_E_COMM_IDS, &e_varid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to find variable ID for \"%s\" in file ID %d",
              VAR_E_COMM_IDS, exoid);
      ex_err(func_name, errmsg, exerrval);
      return (EX_FATAL);
    }

    /* Output the elemental comm map IDs */
    if (ex_int64_status(exoid) & EX_IDS_INT64_API) {
      status = nc_put_var_longlong(exoid, e_varid, elem_cmap_ids);
    } else {
      status = nc_put_var_int(exoid, e_varid, elem_cmap_ids);
    }
    if (status != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to output variable in file ID %d", exoid);
      ex_err(func_name, errmsg, exerrval);

      return (EX_FATAL);
    }

  } /* End "if (num_e_comm_maps > 0)" */

  return (EX_NOERR);
}
/*!
 * writes the parameters used to describe an element block
 * \param    exoid                   exodus file id
 * \param    elem_blk_id             element block id
 * \param    elem_type               element type string
 * \param    num_elem_this_blk       number of elements in the element blk
 * \param    num_nodes_per_elem      number of nodes per element block
 * \param    num_attr_this_blk       number of attributes
 * \param    define_maps             if != 0, write maps, else don't
 */
int ex_put_concat_elem_block (int    exoid,
                              const void_int*   elem_blk_id,
                              char *elem_type[],
                              const void_int*   num_elem_this_blk,
                              const void_int*   num_nodes_per_elem,
                              const void_int*   num_attr_this_blk,
                              int    define_maps)
{
  int i, varid, dimid, dims[2], strdim, *eb_array;
  int temp;
  int iblk;
  int status;
  int num_elem_blk;
  int map_int_type, conn_int_type;
  size_t length;
  int cur_num_elem_blk, nelnoddim, numelbdim, numattrdim, connid, numelemdim, numnodedim;
  char errmsg[MAX_ERR_LENGTH];

  exerrval  = 0; /* clear error code */

  /* first check if any element blocks are specified
   * OK if zero...
   */
  if (nc_inq_dimid(exoid, DIM_NUM_EL_BLK, &dimid) != NC_NOERR) {
    return (EX_NOERR);
  }

  /* Get number of element blocks defined for this file */
  if ((status = nc_inq_dimlen(exoid,dimid,&length)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to get number of element blocks in file id %d",
	    exoid);
    ex_err("ex_put_concat_elem_block",errmsg,exerrval);
    return (EX_FATAL);
  }
  num_elem_blk = length;
  
  /* Fill out the element block status array */
  if (!(eb_array = malloc(num_elem_blk*sizeof(int)))) {
    exerrval = EX_MEMFAIL;
    sprintf(errmsg,
	    "Error: failed to allocate space for element block status array in file id %d",
	    exoid);
    ex_err("ex_put_concat_elem_block",errmsg,exerrval);
    return (EX_FATAL);
  }

  if (ex_int64_status(exoid) & EX_IDS_INT64_API) {
    for (i=0;i<num_elem_blk;i++) {
      eb_array[i] = (((int64_t*)num_elem_this_blk)[i] == 0) ? 0 : 1;
    }
  } else {
    for (i=0;i<num_elem_blk;i++) {
      eb_array[i] = (((int*)num_elem_this_blk)[i] == 0) ? 0 : 1;
    }
  }

  /* Next, get variable id of status array */
  if ((status = nc_inq_varid(exoid, VAR_STAT_EL_BLK, &varid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to locate element block status in file id %d",
	    exoid);
    ex_err("ex_put_concat_elem_block",errmsg,exerrval);
    return (EX_FATAL);
  }

  status = nc_put_var_int(exoid, varid, eb_array);

  if (status != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to store element block status array to file id %d",
            exoid);
    ex_err("ex_put_concat_elem_block",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* Next, fill out ids array */
  /* first get id of ids array variable */
  if ((status = nc_inq_varid(exoid, VAR_ID_EL_BLK, &varid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to locate element block ids array in file id %d",
            exoid);
    ex_err("ex_put_concat_elem_block",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* then, write out id list */
  if (ex_int64_status(exoid) & EX_IDS_INT64_API) {
    status = nc_put_var_longlong(exoid, varid, elem_blk_id);
  } else {
    status = nc_put_var_int(exoid, varid, elem_blk_id);
  }

  if (status != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to store element block id array in file id %d",
            exoid);
    ex_err("ex_put_concat_elem_block",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* inquire previously defined dimensions  */
  if ((status = nc_inq_dimid(exoid, DIM_STR_NAME, &strdim)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to get string length in file id %d",exoid);
    ex_err("ex_put_concat_elem_block",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* put netcdf file into define mode  */
  if ((status = nc_redef (exoid)) != NC_NOERR)  {
    exerrval = status;
    sprintf(errmsg,"Error: failed to place file id %d into define mode",exoid);
    ex_err("ex_put_concat_elem_block",errmsg,exerrval);
    return (EX_FATAL);
  }

  conn_int_type = NC_INT;
  if (ex_int64_status(exoid) & EX_BULK_INT64_DB) {
    conn_int_type = NC_INT64;
  }
  
  map_int_type = NC_INT;
  if (ex_int64_status(exoid) & EX_MAPS_INT64_DB) {
    map_int_type = NC_INT64;
  }
  
  /* Iterate over element blocks ... */
  for (iblk = 0; iblk < num_elem_blk; iblk++) {
    ex_entity_id eb_id;
    size_t num_elem;
    size_t num_npe;
    size_t num_attr;
    if (ex_int64_status(exoid) & EX_IDS_INT64_API) {
      eb_id    = ((int64_t*)elem_blk_id)[iblk];
      num_elem = ((int64_t*)num_elem_this_blk)[iblk];
      num_npe  = ((int64_t*)num_nodes_per_elem)[iblk];
      num_attr = ((int64_t*)num_attr_this_blk)[iblk];
    } else {
      eb_id    = ((int*)elem_blk_id)[iblk];
      num_elem = ((int*)num_elem_this_blk)[iblk];
      num_npe  = ((int*)num_nodes_per_elem)[iblk];
      num_attr = ((int*)num_attr_this_blk)[iblk];
    }

    cur_num_elem_blk=ex_get_file_item(exoid, ex_get_counter_list(EX_ELEM_BLOCK));
    if (cur_num_elem_blk >= num_elem_blk) {
      exerrval = EX_FATAL;
      sprintf(errmsg,
	      "Error: exceeded number of element blocks (%d) defined in file id %d",
              num_elem_blk,exoid);
      ex_err("ex_put_concat_elem_block",errmsg,exerrval);
      goto error_ret;
    }

    /* NOTE: ex_inc_file_item  is used to find the number of element blocks
       for a specific file and returns that value incremented. */
    cur_num_elem_blk=ex_inc_file_item(exoid, ex_get_counter_list(EX_ELEM_BLOCK));

    if (eb_array[iblk] == 0) /* Is this a NULL element block? */
      continue;

    /* define some dimensions and variables*/
    if ((status = nc_def_dim(exoid,
			     DIM_NUM_EL_IN_BLK(cur_num_elem_blk+1),
			     num_elem, &numelbdim)) != NC_NOERR) {
      exerrval = status;
      if (status == NC_ENAMEINUSE) {     /* duplicate entry */
	sprintf(errmsg,
		"Error: element block %"PRId64" already defined in file id %d",
		eb_id,exoid);
      } else {
	sprintf(errmsg,
		"Error: failed to define number of elements/block for block %"PRId64" file id %d",
		eb_id,exoid);
      }
      ex_err("ex_put_concat_elem_block",errmsg,exerrval);
      goto error_ret;         /* exit define mode and return */
    }

    if ((status = nc_def_dim(exoid,
			     DIM_NUM_NOD_PER_EL(cur_num_elem_blk+1),
			     num_npe, &nelnoddim)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to define number of nodes/element for block %"PRId64" in file id %d",
	      eb_id,exoid);
      ex_err("ex_put_concat_elem_block",errmsg,exerrval);
      goto error_ret;         /* exit define mode and return */
    }

    /* element connectivity array */
    dims[0] = numelbdim;
    dims[1] = nelnoddim;

    if ((status = nc_def_var (exoid, VAR_CONN(cur_num_elem_blk+1),
			      conn_int_type, 2, dims, &connid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to create connectivity array for block %"PRId64" in file id %d",
	      eb_id,exoid);
      ex_err("ex_put_concat_elem_block",errmsg,exerrval);
      goto error_ret;         /* exit define mode and return */
    }
    ex_compress_variable(exoid, connid, 1);

    /* store element type as attribute of connectivity variable */
    if ((status = nc_put_att_text(exoid, connid, ATT_NAME_ELB, strlen(elem_type[iblk])+1, 
				  (void*)elem_type[iblk])) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to store element type name %s in file id %d",
	      elem_type[iblk],exoid);
      ex_err("ex_put_concat_elem_block",errmsg,exerrval);
      goto error_ret;         /* exit define mode and return */
    }

    /* element attribute array */
    if (num_attr > 0) {
      if ((status = nc_def_dim (exoid, 
				DIM_NUM_ATT_IN_BLK(cur_num_elem_blk+1),
				num_attr, &numattrdim)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to define number of attributes in block %"PRId64" in file id %d",
		eb_id,exoid);
	ex_err("ex_put_concat_elem_block",errmsg,exerrval);
	goto error_ret;         /* exit define mode and return */
      }
      
      /* Attribute names... */
      dims[0] = numattrdim;
      dims[1] = strdim;
      
      if ((status = nc_def_var(exoid, VAR_NAME_ATTRIB(cur_num_elem_blk+1),
			       NC_CHAR, 2, dims, &temp)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to define element attribute name array in file id %d",exoid);
	ex_err("ex_put_concat_elem_block",errmsg,exerrval);
	goto error_ret;         /* exit define mode and return */
      }
      eb_array[iblk] = temp;

      dims[0] = numelbdim;
      dims[1] = numattrdim;
      
      if ((status = nc_def_var(exoid, VAR_ATTRIB(cur_num_elem_blk+1),
			       nc_flt_code(exoid), 2, dims, &temp)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error:  failed to define attributes for element block %"PRId64" in file id %d",
		eb_id,exoid);
	ex_err("ex_put_concat_elem_block",errmsg,exerrval);
	goto error_ret;         /* exit define mode and return */
      }

    }
    
  }

  /* Define the element map here to avoid a later redefine call */
  if (define_maps != 0) {
    if (nc_inq_varid(exoid, VAR_ELEM_NUM_MAP, &temp) != NC_NOERR) {
      /* Map does not exist */
      /* Possible to have zero elements but >0 element blocks.
       * Only define map if there are nonzero elements
       */
      if (nc_inq_dimid(exoid, DIM_NUM_ELEM, &numelemdim) == NC_NOERR) {
	dims[0] = numelemdim;
	
	if ((status = nc_def_var(exoid, VAR_ELEM_NUM_MAP, map_int_type, 1, dims, &temp)) != NC_NOERR) {
	  exerrval = status;
	  if (status == NC_ENAMEINUSE) {
	    sprintf(errmsg,
		    "Error: element numbering map already exists in file id %d",
		    exoid);
	  } else {
	    sprintf(errmsg,
		    "Error: failed to create element numbering map in file id %d",
		    exoid);
	  }
	  ex_err("ex_put_concat_elem_block",errmsg,exerrval);
	  goto error_ret;         /* exit define mode and return */
	}
	ex_compress_variable(exoid, temp, 1);
      }
    }

    /* Do the same for the node numbering map */
    if (nc_inq_varid(exoid, VAR_NODE_NUM_MAP, &temp) != NC_NOERR) {
      /* Map does not exist */
      if ((nc_inq_dimid(exoid, DIM_NUM_NODES, &numnodedim)) == NC_NOERR) {
	dims[0] = numnodedim;
	if ((status = nc_def_var(exoid, VAR_NODE_NUM_MAP, map_int_type, 1, dims, &temp)) != NC_NOERR) {
	  exerrval = status;
	  if (status == NC_ENAMEINUSE) {
	    sprintf(errmsg,
		    "Error: node numbering map already exists in file id %d",
		    exoid);
	  } else {
	    sprintf(errmsg,
		    "Error: failed to create node numbering map array in file id %d",
		    exoid);
	  }
	  ex_err("ex_put_concat_elem_block",errmsg,exerrval);
	  goto error_ret;         /* exit define mode and return */
	}
	ex_compress_variable(exoid, temp, 1);
      }
    }
  }

  /* leave define mode  */
  if ((status = nc_enddef(exoid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to complete element block definition in file id %d", 
	    exoid);
    ex_err("ex_put_concat_elem_block",errmsg,exerrval);
    return (EX_FATAL);
  }

  {
  /* Write dummy attribute name. Without this we get corruption in the
   * attribute name.
   */
    size_t  start[2], count[2];
    char *text = "";
    count[0] = 1;
    start[1] = 0;
    count[1] = strlen(text)+1;
    
    for (iblk = 0; iblk < num_elem_blk; iblk++) {
      size_t num_attr;
      if (eb_array[iblk] == 0) /* Is this a NULL element block? */
	continue;
      if (ex_int64_status(exoid) & EX_IDS_INT64_API) {
	num_attr = ((int64_t*)num_attr_this_blk)[iblk];
      } else {
	num_attr = ((int*)num_attr_this_blk)[iblk];
      }
      for (i = 0; i < num_attr; i++) {
	start[0] = i;
	nc_put_vara_text(exoid, eb_array[iblk], start, count, text);
      }
    }
  }
  free(eb_array);
  
  return (EX_NOERR);
  
  /* Fatal error: exit definition mode and return */
 error_ret:
  if (nc_enddef (exoid) != NC_NOERR) {     /* exit define mode */
    sprintf(errmsg,
	    "Error: failed to complete definition for file id %d",
	    exoid);
    ex_err("ex_put_concat_elem_block",errmsg,exerrval);
  }
  return (EX_FATAL);
}
static int define_truth_table(ex_entity_type obj_type, int exoid, int num_ent, int num_var,
                              int *var_tab, int *status_tab, void_int *ids, const char *label)
{
  char errmsg[MAX_ERR_LENGTH];
  int  k = 0;
  int  i, j;
  int  time_dim;
  int  dims[2];
  int  varid;
  int  status;

  if ((status = nc_inq_dimid(exoid, DIM_TIME, &time_dim)) != NC_NOERR) {
    exerrval = status;
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to locate time dimension in file id %d", exoid);
    ex_err("ex_put_all_var_param_ext", errmsg, exerrval);
    return -1;
  }

  if (var_tab == NULL) {
    exerrval = EX_BADPARAM;
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: %s variable truth table is NULL in file id %d", label,
             exoid);
    ex_err("ex_put_all_var_param_ext", errmsg, exerrval);
    return -1;
  }

  for (i = 0; i < num_ent; i++) {
    int64_t id;
    if (ex_int64_status(exoid) & EX_IDS_INT64_API) {
      id = ((int64_t *)ids)[i];
    }
    else {
      id = ((int *)ids)[i];
    }

    for (j = 1; j <= num_var; j++) {

      /* check if variables are to be put out for this block */
      if (var_tab[k] != 0) {
        if (status_tab[i] != 0) { /* only define variable if active */
          dims[0] = time_dim;

          /* Determine number of entities in entity */
          /* Need way to make this more generic... */
          status = nc_inq_dimid(exoid, ex_dim_num_entries_in_object(obj_type, i + 1), &dims[1]);
          if (status != NC_NOERR) {
            exerrval = status;
            snprintf(errmsg, MAX_ERR_LENGTH,
                     "ERROR: failed to locate number of entities in %s %" PRId64 " in file id %d",
                     label, id, exoid);
            ex_err("ex_put_all_var_param_ext", errmsg, exerrval);
            return status;
          }

          /* define netCDF variable to store variable values;
           * the j index cycles from 1 through the number of variables so
           * that the index of the EXODUS variable (which is part of
           * the name of the netCDF variable) will begin at 1 instead of 0
           */
          status = nc_def_var(exoid, ex_name_var_of_object(obj_type, j, i + 1), nc_flt_code(exoid),
                              2, dims, &varid);
          if (status != NC_NOERR) {
            if (status != NC_ENAMEINUSE) {
              exerrval = status;
              snprintf(errmsg, MAX_ERR_LENGTH,
                       "ERROR: failed to define %s variable for %s %" PRId64 " in file id %d",
                       label, label, id, exoid);
              ex_err("ex_put_all_var_param_ext", errmsg, exerrval);
              return status;
            }
          }
          ex_compress_variable(exoid, varid, 2);
        }
      }    /* if */
      k++; /* increment truth table pointer */
    }      /* for j */
  }        /* for i */
  return NC_NOERR;
}
Exemple #16
0
int ex_put_info (int   exoid, 
                 int   num_info,
                 char *info[])
{
  int status;
  int i, lindim, num_info_dim, dims[2], varid;
  size_t start[2], count[2];
  char errmsg[MAX_ERR_LENGTH];

  int rootid = exoid & EX_FILE_ID_MASK;

  exerrval = 0; /* clear error code */

  /* only do this if there are records */
  if (num_info > 0) {

    /* See if the number of info records has already been defined.
       Assume that if the DIM_NUM_INFO dimension exists, then the
       VAR_INFO variable also exists...
     */
    status =  nc_inq_dimid(rootid, DIM_NUM_INFO, &num_info_dim);
    if (status != NC_NOERR) {

      /*   inquire previously defined dimensions  */
      if ((status = nc_inq_dimid(rootid, DIM_LIN, &lindim)) != NC_NOERR) {
        exerrval = status;
        sprintf(errmsg,
                "Error: failed to get line string length in file id %d", rootid);
        ex_err("ex_put_info",errmsg,exerrval);
        return (EX_FATAL);
      }

      /* put file into define mode  */
      if ((status = nc_redef (rootid)) != NC_NOERR) {
        exerrval = status;
        sprintf(errmsg,
                "Error: failed put file id %d into define mode", rootid);
        ex_err("ex_put_info",errmsg,exerrval);
        return (EX_FATAL);
      }

      /* define dimensions */
      if ((status = nc_def_dim(rootid, DIM_NUM_INFO, num_info, &num_info_dim)) != NC_NOERR) {
        if (status == NC_ENAMEINUSE) {     /* duplicate entry? */
          exerrval = status;
          sprintf(errmsg,
                  "Error: info records already exist in file id %d",
                  rootid);
          ex_err("ex_put_info",errmsg,exerrval);
        } else {
          exerrval = status;
          sprintf(errmsg,
                  "Error: failed to define number of info records in file id %d",
                  rootid);
          ex_err("ex_put_info",errmsg,exerrval);
        }

        goto error_ret;         /* exit define mode and return */
      }

      /* define variable  */
      dims[0] = num_info_dim;
      dims[1] = lindim;

      if ((status = nc_def_var(rootid, VAR_INFO, NC_CHAR, 2, dims, &varid)) != NC_NOERR) {
        exerrval = status;
        sprintf(errmsg,
                "Error: failed to define info record in file id %d",
                rootid);
        ex_err("ex_put_info",errmsg,exerrval);
        goto error_ret;         /* exit define mode and return */
      }
      ex_compress_variable(rootid, varid, 3);

      /*   leave define mode  */
      if ((status = nc_enddef (rootid)) != NC_NOERR) {
        exerrval = status;
        sprintf(errmsg,
                "Error: failed to complete info record definition in file id %d",
                rootid);
        ex_err("ex_put_info",errmsg,exerrval);
        return (EX_FATAL);
      }
    } else {
      if ((status = nc_inq_varid(rootid, VAR_INFO, &varid)) != NC_NOERR) {
        exerrval = status;
        sprintf(errmsg,
                "Error: failed to find info record variable in file id %d",
                rootid);
        ex_err("ex_put_info",errmsg,exerrval);
        return (EX_FATAL);
      }
    }

    if (info != NULL) {
      /* write out information records */
      for (i=0; i<num_info; i++) {
        int length = strlen(info[i]);
        start[0] = i;
        start[1] = 0;

        count[0] = 1;
        count[1] = length < MAX_LINE_LENGTH ? length : MAX_LINE_LENGTH;

        if ((status = nc_put_vara_text(rootid, varid, start, count, info[i])) != NC_NOERR) {
          exerrval = status;
          sprintf(errmsg,
                  "Error: failed to store info record in file id %d",
                  rootid);
          ex_err("ex_put_info",errmsg,exerrval);
          return (EX_FATAL);
        }
      }
    } else if (ex_is_parallel(rootid)) {
      /* All processors need to call nc_put_vara_text in case in a global collective mode */
      char dummy[] = " ";
      for (i=0; i<num_info; i++) {
        start[0] = start[1] = 0;
        count[0] = count[1] = 0;
        nc_put_vara_text(rootid, varid, start, count, dummy);
      }
    }
  }
  return (EX_NOERR);

  /* Fatal error: exit definition mode and return */
  error_ret:
  if (nc_enddef (rootid) != NC_NOERR) {     /* exit define mode */
    sprintf(errmsg,
        "Error: failed to complete definition for file id %d",
        rootid);
    ex_err("ex_put_info",errmsg,exerrval);
  }
  return (EX_FATAL);
}
int ex_put_all_var_param_ext(int exoid, const ex_var_params *vp)
{
  int    in_define = 0;
  int    status;
  int    temp;
  int    time_dim, num_nod_dim, dimid;
  size_t num_elem_blk, num_edge_blk, num_face_blk;
  size_t num_nset, num_eset, num_fset, num_sset, num_elset;
  int    numelblkdim, numelvardim, numedvardim, numedblkdim, numfavardim, numfablkdim, numnsetdim,
      nsetvardim, numesetdim, esetvardim, numfsetdim, fsetvardim, numssetdim, ssetvardim,
      numelsetdim, elsetvardim;
  int i;

  int edblk_varid, fablk_varid, eblk_varid, nset_varid, eset_varid, fset_varid, sset_varid,
      elset_varid, varid;

  void_int *eblk_ids  = NULL;
  void_int *edblk_ids = NULL;
  void_int *fablk_ids = NULL;
  void_int *nset_ids  = NULL;
  void_int *eset_ids  = NULL;
  void_int *fset_ids  = NULL;
  void_int *sset_ids  = NULL;
  void_int *elset_ids = NULL;

  int *eblk_stat  = NULL;
  int *edblk_stat = NULL;
  int *fablk_stat = NULL;
  int *nset_stat  = NULL;
  int *eset_stat  = NULL;
  int *fset_stat  = NULL;
  int *sset_stat  = NULL;
  int *elset_stat = NULL;

  int         dims[3];
  char        errmsg[MAX_ERR_LENGTH];
  const char *routine = "ex_put_all_var_param_ext";

  ex_check_valid_file_id(exoid);

  exerrval = 0; /* clear error code */

  /* inquire previously defined dimensions  */

  if ((status = nc_inq_dimid(exoid, DIM_TIME, &time_dim)) != NC_NOERR) {
    exerrval = status;
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to locate time dimension in file id %d", exoid);
    ex_err("ex_put_all_var_param_ext", errmsg, exerrval);
    goto error_ret;
  }

  if ((status = nc_inq_dimid(exoid, DIM_NUM_NODES, &num_nod_dim)) != NC_NOERR) {
    num_nod_dim = -1; /* There is probably no nodes on this file */
  }

  /* Check this now so we can use it later without checking for errors */
  if ((status = nc_inq_dimid(exoid, DIM_STR_NAME, &temp)) != NC_NOERR) {
    exerrval = status;
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get string length in file id %d", exoid);
    ex_err("ex_put_all_var_param_ext", errmsg, exerrval);
    goto error_ret;
  }

  EX_GET_IDS_STATUS("edge block", vp->num_edge, DIM_NUM_ED_BLK, numedblkdim, num_edge_blk,
                    edblk_ids, EX_EDGE_BLOCK, VAR_STAT_ED_BLK, edblk_stat);
  EX_GET_IDS_STATUS("face block", vp->num_face, DIM_NUM_FA_BLK, numfablkdim, num_face_blk,
                    fablk_ids, EX_FACE_BLOCK, VAR_STAT_FA_BLK, fablk_stat);
  EX_GET_IDS_STATUS("element block", vp->num_elem, DIM_NUM_EL_BLK, numelblkdim, num_elem_blk,
                    eblk_ids, EX_ELEM_BLOCK, VAR_STAT_EL_BLK, eblk_stat);
  EX_GET_IDS_STATUS("node set", vp->num_nset, DIM_NUM_NS, numnsetdim, num_nset, nset_ids,
                    EX_NODE_SET, VAR_NS_STAT, nset_stat);
  EX_GET_IDS_STATUS("edge set", vp->num_eset, DIM_NUM_ES, numesetdim, num_eset, eset_ids,
                    EX_EDGE_SET, VAR_ES_STAT, eset_stat);
  EX_GET_IDS_STATUS("face set", vp->num_fset, DIM_NUM_FS, numfsetdim, num_fset, fset_ids,
                    EX_FACE_SET, VAR_FS_STAT, fset_stat);
  EX_GET_IDS_STATUS("side set", vp->num_sset, DIM_NUM_SS, numssetdim, num_sset, sset_ids,
                    EX_SIDE_SET, VAR_SS_STAT, sset_stat);
  EX_GET_IDS_STATUS("element set", vp->num_elset, DIM_NUM_ELS, numelsetdim, num_elset, elset_ids,
                    EX_ELEM_SET, VAR_ELS_STAT, elset_stat);

  /* put file into define mode  */
  if ((status = nc_redef(exoid)) != NC_NOERR) {
    exerrval = status;
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid);
    ex_err("ex_put_all_var_param_ext", errmsg, exerrval);
    goto error_ret;
  }
  in_define = 1;

  /* define dimensions and variables */
  if (vp->num_glob > 0) {
    if (define_dimension(exoid, DIM_NUM_GLO_VAR, vp->num_glob, "global", &dimid) != NC_NOERR) {
      goto error_ret;
    }

    dims[0] = time_dim;
    dims[1] = dimid;
    if ((status = nc_def_var(exoid, VAR_GLO_VAR, nc_flt_code(exoid), 2, dims, &varid)) !=
        NC_NOERR) {
      exerrval = status;
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to define global variables in file id %d",
               exoid);
      ex_err("ex_put_all_var_param_ext", errmsg, exerrval);
      goto error_ret; /* exit define mode and return */
    }
    ex_compress_variable(exoid, varid, 2);

    /* Now define global variable name variable */
    if (define_variable_name_variable(exoid, VAR_NAME_GLO_VAR, dimid, "global") != NC_NOERR) {
      goto error_ret;
    }
  }

  if (vp->num_node > 0) {
    /*
     * There are two ways to store the nodal variables. The old way *
     * was a blob (#times,#vars,#nodes), but that was exceeding the
     * netcdf maximum dataset size for large models. The new way is
     * to store #vars separate datasets each of size (#times,#nodes)
     *
     * We want this routine to be capable of storing both formats
     * based on some external flag.  Since the storage format of the
     * coordinates have also been changed, we key off of their
     * storage type to decide which method to use for nodal
     * variables. If the variable 'coord' is defined, then store old
     * way; otherwise store new.
     */
    if (define_dimension(exoid, DIM_NUM_NOD_VAR, vp->num_node, "nodal", &dimid) != NC_NOERR) {
      goto error_ret;
    }

    if (num_nod_dim > 0) {
      if (ex_large_model(exoid) == 0) { /* Old way */
        dims[0] = time_dim;
        dims[1] = dimid;
        dims[2] = num_nod_dim;
        if ((status = nc_def_var(exoid, VAR_NOD_VAR, nc_flt_code(exoid), 3, dims, &varid)) !=
            NC_NOERR) {
          exerrval = status;
          snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to define nodal variables in file id %d",
                   exoid);
          ex_err("ex_put_all_var_param_ext", errmsg, exerrval);
          goto error_ret; /* exit define mode and return */
        }
      }
      else { /* Store new way */
        for (i = 1; i <= vp->num_node; i++) {
          dims[0] = time_dim;
          dims[1] = num_nod_dim;
          if ((status = nc_def_var(exoid, VAR_NOD_VAR_NEW(i), nc_flt_code(exoid), 2, dims,
                                   &varid)) != NC_NOERR) {
            exerrval = status;
            snprintf(errmsg, MAX_ERR_LENGTH,
                     "ERROR: failed to define nodal variable %d in file id %d", i, exoid);
            ex_err("ex_put_var_param", errmsg, exerrval);
            goto error_ret; /* exit define mode and return */
          }
          ex_compress_variable(exoid, varid, 2);
        }
      }
    }

    /* Now define nodal variable name variable */
    if (define_variable_name_variable(exoid, VAR_NAME_NOD_VAR, dimid, "nodal") != NC_NOERR) {
      goto error_ret;
    }
  }

#define EX_DEFINE_VARS(TID, STNAME, TNAME, NUMVAR, DNAME, DID1, DID2, DVAL, VIDS, VNOV, VTV,       \
                       VSTATVAL, VTABVAL, VTABVAR)                                                 \
  if (NUMVAR > 0) {                                                                                \
    status = define_dimension(exoid, DNAME, NUMVAR, STNAME, &DID2);                                \
    if (status != NC_NOERR)                                                                        \
      goto error_ret;                                                                              \
                                                                                                   \
    /* Now define STNAME variable name variable */                                                 \
    if (define_variable_name_variable(exoid, VNOV, DID2, STNAME) != NC_NOERR)                      \
      goto error_ret;                                                                              \
                                                                                                   \
    if (define_truth_table(TID, exoid, DVAL, NUMVAR, VTABVAL, VSTATVAL, VIDS, TNAME) != NC_NOERR)  \
      goto error_ret;                                                                              \
                                                                                                   \
    free(VSTATVAL);                                                                                \
    VSTATVAL = NULL;                                                                               \
    free(VIDS);                                                                                    \
    VIDS = NULL;                                                                                   \
                                                                                                   \
    /* create a variable array in which to store the STNAME variable truth                         \
     * table                                                                                       \
     */                                                                                            \
                                                                                                   \
    dims[0] = DID1;                                                                                \
    dims[1] = DID2;                                                                                \
                                                                                                   \
    if ((status = nc_def_var(exoid, VTV, NC_INT, 2, dims, &VTABVAR)) != NC_NOERR) {                \
      exerrval = status;                                                                           \
      snprintf(errmsg, MAX_ERR_LENGTH,                                                             \
               "ERROR: failed to define " STNAME " variable truth table in file id %d", exoid);    \
      ex_err("ex_put_all_var_param_ext", errmsg, exerrval);                                        \
      goto error_ret; /* exit define mode and return */                                            \
    }                                                                                              \
  }
  EX_DEFINE_VARS(EX_EDGE_BLOCK, "edge", "edge block", vp->num_edge, DIM_NUM_EDG_VAR, numedblkdim,
                 numedvardim, num_edge_blk, edblk_ids, VAR_NAME_EDG_VAR, VAR_EBLK_TAB, edblk_stat,
                 vp->edge_var_tab, edblk_varid);
  EX_DEFINE_VARS(EX_FACE_BLOCK, "face", "face block", vp->num_face, DIM_NUM_FAC_VAR, numfablkdim,
                 numfavardim, num_face_blk, fablk_ids, VAR_NAME_FAC_VAR, VAR_FBLK_TAB, fablk_stat,
                 vp->face_var_tab, fablk_varid);
  EX_DEFINE_VARS(EX_ELEM_BLOCK, "element", "element block", vp->num_elem, DIM_NUM_ELE_VAR,
                 numelblkdim, numelvardim, num_elem_blk, eblk_ids, VAR_NAME_ELE_VAR, VAR_ELEM_TAB,
                 eblk_stat, vp->elem_var_tab, eblk_varid);
  EX_DEFINE_VARS(EX_NODE_SET, "nodeset", "node set", vp->num_nset, DIM_NUM_NSET_VAR, numnsetdim,
                 nsetvardim, num_nset, nset_ids, VAR_NAME_NSET_VAR, VAR_NSET_TAB, nset_stat,
                 vp->nset_var_tab, nset_varid);
  EX_DEFINE_VARS(EX_EDGE_SET, "edgeset", "edge set", vp->num_eset, DIM_NUM_ESET_VAR, numesetdim,
                 esetvardim, num_eset, eset_ids, VAR_NAME_ESET_VAR, VAR_ESET_TAB, eset_stat,
                 vp->eset_var_tab, eset_varid);
  EX_DEFINE_VARS(EX_FACE_SET, "faceset", "face set", vp->num_fset, DIM_NUM_FSET_VAR, numfsetdim,
                 fsetvardim, num_fset, fset_ids, VAR_NAME_FSET_VAR, VAR_FSET_TAB, fset_stat,
                 vp->fset_var_tab, fset_varid);
  EX_DEFINE_VARS(EX_SIDE_SET, "sideset", "side set", vp->num_sset, DIM_NUM_SSET_VAR, numssetdim,
                 ssetvardim, num_sset, sset_ids, VAR_NAME_SSET_VAR, VAR_SSET_TAB, sset_stat,
                 vp->sset_var_tab, sset_varid);
  EX_DEFINE_VARS(EX_ELEM_SET, "elemset", "element set", vp->num_elset, DIM_NUM_ELSET_VAR,
                 numelsetdim, elsetvardim, num_elset, elset_ids, VAR_NAME_ELSET_VAR, VAR_ELSET_TAB,
                 elset_stat, vp->elset_var_tab, elset_varid);

  /* leave define mode  */

  in_define = 0;
  if ((status = nc_enddef(exoid)) != NC_NOERR) {
    exerrval = status;
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to complete definition in file id %d", exoid);
    ex_err("ex_put_all_var_param_ext", errmsg, exerrval);
    goto error_ret;
  }

  /* write out the variable truth tables */
  if (vp->num_edge > 0) {
    if (put_truth_table(exoid, edblk_varid, vp->edge_var_tab, "edge") != NC_NOERR) {
      goto error_ret;
    }
  }

  if (vp->num_face > 0) {
    if (put_truth_table(exoid, fablk_varid, vp->face_var_tab, "face") != NC_NOERR) {
      goto error_ret;
    }
  }

  if (vp->num_elem > 0) {
    if (put_truth_table(exoid, eblk_varid, vp->elem_var_tab, "element") != NC_NOERR) {
      goto error_ret;
    }
  }

  if (vp->num_nset > 0) {
    if (put_truth_table(exoid, nset_varid, vp->nset_var_tab, "nodeset") != NC_NOERR) {
      goto error_ret;
    }
  }

  if (vp->num_eset > 0) {
    if (put_truth_table(exoid, eset_varid, vp->eset_var_tab, "edgeset") != NC_NOERR) {
      goto error_ret;
    }
  }

  if (vp->num_fset > 0) {
    if (put_truth_table(exoid, fset_varid, vp->fset_var_tab, "faceset") != NC_NOERR) {
      goto error_ret;
    }
  }

  if (vp->num_sset > 0) {
    if (put_truth_table(exoid, sset_varid, vp->sset_var_tab, "sideset") != NC_NOERR) {
      goto error_ret;
    }
  }

  if (vp->num_elset > 0) {
    if (put_truth_table(exoid, elset_varid, vp->elset_var_tab, "elemset") != NC_NOERR) {
      goto error_ret;
    }
  }

  return (EX_NOERR);

/* Fatal error: exit definition mode and return */
error_ret:
  if (in_define == 1) {
    if (nc_enddef(exoid) != NC_NOERR) /* exit define mode */
    {
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to complete definition for file id %d",
               exoid);
      ex_err("ex_put_all_var_param_ext", errmsg, exerrval);
    }
  }
  free(eblk_ids);
  free(edblk_ids);
  free(fablk_ids);
  free(nset_ids);
  free(eset_ids);
  free(fset_ids);
  free(sset_ids);
  free(elset_ids);

  free(eblk_stat);
  free(edblk_stat);
  free(fablk_stat);
  free(nset_stat);
  free(eset_stat);
  free(fset_stat);
  free(sset_stat);
  free(elset_stat);
  return (EX_FATAL);
}
int ex_put_init_ext (int   exoid,
                     const ex_init_params *model)
{
  int numdimdim, numnoddim, elblkdim, edblkdim, fablkdim, esetdim,
    fsetdim, elsetdim, nsetdim, ssetdim, dim_str_name, dim[2], temp;
  int nmapdim,edmapdim,famapdim,emapdim,timedim;
  int status;
  int title_len;
#if 0
  /* used for header size calculations which are turned off for now */
  int header_size, fixed_var_size, iows;
#endif  
  char errmsg[MAX_ERR_LENGTH];

  int rootid = exoid & EX_FILE_ID_MASK;

  exerrval = 0; /* clear error code */
  
  if (rootid == exoid && nc_inq_dimid (exoid, DIM_NUM_DIM, &temp) == NC_NOERR)
    {
      exerrval = EX_MSG;
      sprintf(errmsg,
              "Error: initialization already done for file id %d",exoid);
      ex_err("ex_put_init_ext",errmsg,exerrval);
      return (EX_FATAL);
    }


  /* put file into define mode */
  if ((status = nc_redef (exoid)) != NC_NOERR)
    {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to put file id %d into define mode", exoid);
      ex_err("ex_put_init_ext",errmsg,exerrval);
      return (EX_FATAL);
    }

  /* define some attributes... */
  title_len = strlen(model->title) < MAX_LINE_LENGTH ? strlen(model->title) : MAX_LINE_LENGTH;
  if ((status = nc_put_att_text(rootid, NC_GLOBAL, (const char*)ATT_TITLE, 
				title_len+1, model->title)) != NC_NOERR)
    {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to define model->title attribute to file id %d", rootid);
      ex_err("ex_put_init_ext",errmsg,exerrval);
      goto error_ret;         /* exit define mode and return */
    }

  /* ...and some dimensions... */

  /* create name string length dimension */
  if (nc_inq_dimid (rootid, DIM_STR_NAME, &dim_str_name) != NC_NOERR) {
    int max_name = ex_inquire_int(exoid, EX_INQ_MAX_READ_NAME_LENGTH);
    if (max_name < ex_default_max_name_length) { max_name = ex_default_max_name_length;
}

    if ((status=nc_def_dim (rootid, DIM_STR_NAME, max_name+1, &dim_str_name)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to define name string length in file id %d",rootid);
      ex_err("ex_put_init_ext",errmsg,exerrval);
      goto error_ret;
    }
  }
  
  if ((status = nc_def_dim(exoid, DIM_TIME, NC_UNLIMITED, &timedim)) != 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);
  }

  dim[0] = timedim;
  if ((status = nc_def_var(exoid, VAR_WHOLE_TIME, nc_flt_code(exoid), 1, dim, &temp)) != 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, temp, 2);

  if ((status = nc_def_dim(exoid, DIM_NUM_DIM, model->num_dim, &numdimdim)) != NC_NOERR)
    {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to define number of dimensions in file id %d",exoid);
      ex_err("ex_put_init_ext",errmsg,exerrval);
      goto error_ret;         /* exit define mode and return */
    }

  /*
   * Need to handle "empty file" that may be the result of a strange
   * load balance or some other strange run.  Note that if num_node
   * == 0, then model->num_elem must be zero since you cannot have elements
   * with no nodes. It *is* permissible to have zero elements with
   * non-zero node count.
   */
     
  if (model->num_nodes > 0) {
    if ((status = nc_def_dim(exoid, DIM_NUM_NODES, model->num_nodes, &numnoddim)) != NC_NOERR)
      {
        exerrval = status;
        sprintf(errmsg,
                "Error: failed to define number of nodes in file id %d",exoid);
        ex_err("ex_put_init_ext",errmsg,exerrval);
        goto error_ret;         /* exit define mode and return */
      }
  }
  
  if (model->num_elem > 0) {
    if (model->num_nodes <=  0) {
      exerrval = EX_MSG;
      sprintf(errmsg,
              "Error: Cannot have non-zero element count if node count is zero.in file id %d",exoid);
      ex_err("ex_put_init_ext",errmsg,exerrval);
      goto error_ret;         /* exit define mode and return */
    }
    
    if ((status = nc_def_dim(exoid, DIM_NUM_ELEM, model->num_elem, &temp)) != NC_NOERR)
      {
        exerrval = status;
        sprintf(errmsg,
                "Error: failed to define number of elements in file id %d",exoid);
        ex_err("ex_put_init_ext",errmsg,exerrval);
        goto error_ret;         /* exit define mode and return */
      }
  }

  if (model->num_edge > 0) {
    if (model->num_nodes <=  0) {
      exerrval = EX_MSG;
      sprintf(errmsg,
              "Error: Cannot have non-zero edge count if node count is zero.in file id %d",exoid);
      ex_err("ex_put_init_ext",errmsg,exerrval);
      goto error_ret;         /* exit define mode and return */
    }
    
    if ((status = nc_def_dim(exoid, DIM_NUM_EDGE, model->num_edge, &temp)) != NC_NOERR)
      {
        exerrval = status;
        sprintf(errmsg,
                "Error: failed to define number of edges in file id %d",exoid);
        ex_err("ex_put_init_ext",errmsg,exerrval);
        goto error_ret;         /* exit define mode and return */
      }
  }

  if (model->num_face > 0) {
    if (model->num_nodes <=  0) {
      exerrval = EX_MSG;
      sprintf(errmsg,
              "Error: Cannot have non-zero face count if node count is zero.in file id %d",exoid);
      ex_err("ex_put_init_ext",errmsg,exerrval);
      goto error_ret;         /* exit define mode and return */
    }
    
    if ((status = nc_def_dim(exoid, DIM_NUM_FACE, model->num_face, &temp)) != NC_NOERR)
      {
        exerrval = status;
        sprintf(errmsg,
                "Error: failed to define number of faces in file id %d",exoid);
        ex_err("ex_put_init_ext",errmsg,exerrval);
        goto error_ret;         /* exit define mode and return */
      }
  }

  if (ex_write_object_params(exoid, "element block", DIM_NUM_EL_BLK, VAR_STAT_EL_BLK, VAR_ID_EL_BLK, model->num_elem_blk, &elblkdim)) { goto error_ret;
}
  if (ex_write_object_params(exoid, "edge block",    DIM_NUM_ED_BLK, VAR_STAT_ED_BLK, VAR_ID_ED_BLK, model->num_edge_blk, &edblkdim)) { goto error_ret;
}
  if (ex_write_object_params(exoid, "face block",    DIM_NUM_FA_BLK, VAR_STAT_FA_BLK, VAR_ID_FA_BLK, model->num_face_blk, &fablkdim)) { goto error_ret;
}
  
  if (ex_write_object_params(exoid, "node set", DIM_NUM_NS,  VAR_NS_STAT,  VAR_NS_IDS, model->num_node_sets,  &nsetdim)) { goto error_ret;
}
  if (ex_write_object_params(exoid, "edge set", DIM_NUM_ES,  VAR_ES_STAT,  VAR_ES_IDS, model->num_edge_sets,  &esetdim)) { goto error_ret;
}
  if (ex_write_object_params(exoid, "face set", DIM_NUM_FS,  VAR_FS_STAT,  VAR_FS_IDS, model->num_face_sets,  &fsetdim)) { goto error_ret;
}
  if (ex_write_object_params(exoid, "side set", DIM_NUM_SS,  VAR_SS_STAT,  VAR_SS_IDS, model->num_side_sets,  &ssetdim)) { goto error_ret;
}
  if (ex_write_object_params(exoid, "elem set", DIM_NUM_ELS, VAR_ELS_STAT, VAR_ELS_IDS, model->num_elem_sets, &elsetdim)) { goto error_ret;
}

  if (ex_write_map_params(exoid,   "node map",  DIM_NUM_NM,  VAR_NM_PROP(1),  model->num_node_maps, &nmapdim)  != NC_NOERR) { goto error_ret;
}
  if (ex_write_map_params(exoid,   "edge map",  DIM_NUM_EDM, VAR_EDM_PROP(1), model->num_edge_maps, &edmapdim) != NC_NOERR) { goto error_ret;
}
  if (ex_write_map_params(exoid,   "face map",  DIM_NUM_FAM, VAR_FAM_PROP(1), model->num_face_maps, &famapdim) != NC_NOERR) { goto error_ret;
}
  if (ex_write_map_params(exoid, "element map", DIM_NUM_EM,  VAR_EM_PROP(1),  model->num_elem_maps, &emapdim)  != NC_NOERR) { goto error_ret;
}

  /*
   * To reduce the maximum dataset sizes, the storage of the nodal
   * coordinates and the nodal variables was changed from a single
   * dataset to a dataset per component or variable.  However, we
   * want to maintain some form of compatability with the old
   * exodusII version.  It is easy to do this on read; however, we
   * also want to be able to store in the old format using the new
   * library. 
   *
   * The mode is set in the ex_create call. The setting can be checked
   * via the ATT_FILESIZE attribute in the file (1=large,
   * 0=normal). Also handle old files that do not contain this
   * attribute.
   */

  if (model->num_nodes > 0) {
    if (ex_large_model(exoid) == 1) {
      /* node coordinate arrays -- separate storage... */

      dim[0] = numnoddim;
      if (model->num_dim > 0) {
        if ((status = nc_def_var (exoid, VAR_COORD_X, nc_flt_code(exoid), 1, dim, &temp)) != NC_NOERR)
          {
            exerrval = status;
            sprintf(errmsg,
                    "Error: failed to define node x coordinate array in file id %d",exoid);
            ex_err("ex_put_init_ext",errmsg,exerrval);
            goto error_ret;         /* exit define mode and return */
          }
	ex_compress_variable(exoid, temp, 2);
      }
    
      if (model->num_dim > 1) {
        if ((status = nc_def_var(exoid, VAR_COORD_Y, nc_flt_code(exoid), 1, dim, &temp)) != NC_NOERR)
          {
            exerrval = status;
            sprintf(errmsg,
                    "Error: failed to define node y coordinate array in file id %d",exoid);
            ex_err("ex_put_init_ext",errmsg,exerrval);
            goto error_ret;         /* exit define mode and return */
          }
	ex_compress_variable(exoid, temp, 2);
      }

      if (model->num_dim > 2) {
        if ((status = nc_def_var(exoid, VAR_COORD_Z, nc_flt_code(exoid), 1, dim, &temp)) != NC_NOERR)
          {
            exerrval = status;
            sprintf(errmsg,
                    "Error: failed to define node z coordinate array in file id %d",exoid);
            ex_err("ex_put_init_ext",errmsg,exerrval);
            goto error_ret;         /* exit define mode and return */
          }
	ex_compress_variable(exoid, temp, 2);
      }
    } else {
      /* node coordinate arrays: -- all stored together (old method) */

      dim[0] = numdimdim;
      dim[1] = numnoddim;
      if ((status = nc_def_var(exoid, VAR_COORD, nc_flt_code(exoid), 2, dim, &temp)) != NC_NOERR)
        {
          exerrval = status;
          sprintf(errmsg,
                  "Error: failed to define node coordinate array in file id %d",exoid);
          ex_err("ex_put_init_ext",errmsg,exerrval);
          goto error_ret;         /* exit define mode and return */
        }
    }
  }
  
  if (ex_write_object_names(exoid, "element block",VAR_NAME_EL_BLK,elblkdim, dim_str_name, model->num_elem_blk) != NC_NOERR) { goto error_ret;
}
  if (ex_write_object_names(exoid, "edge block",   VAR_NAME_ED_BLK,edblkdim, dim_str_name, model->num_edge_blk) != NC_NOERR) { goto error_ret;
}
  if (ex_write_object_names(exoid, "face block",   VAR_NAME_FA_BLK,fablkdim, dim_str_name, model->num_face_blk) != NC_NOERR) { goto error_ret;
}
  if (ex_write_object_names(exoid, "node set",     VAR_NAME_NS,    nsetdim,  dim_str_name, model->num_node_sets) != NC_NOERR) { goto error_ret;
}
  if (ex_write_object_names(exoid, "edge set",     VAR_NAME_ES,    esetdim,  dim_str_name, model->num_edge_sets) != NC_NOERR) { goto error_ret;
}
  if (ex_write_object_names(exoid, "face set",     VAR_NAME_FS,    fsetdim,  dim_str_name, model->num_face_sets) != NC_NOERR) { goto error_ret;
}
  if (ex_write_object_names(exoid, "side set",     VAR_NAME_SS,    ssetdim,  dim_str_name, model->num_side_sets) != NC_NOERR) { goto error_ret;
}
  if (ex_write_object_names(exoid, "element set",  VAR_NAME_ELS,   elsetdim, dim_str_name, model->num_elem_sets) != NC_NOERR) { goto error_ret;
}
  if (ex_write_object_names(exoid, "node map",     VAR_NAME_NM,    nmapdim,  dim_str_name, model->num_node_maps) != NC_NOERR) { goto error_ret;
}
  if (ex_write_object_names(exoid, "edge map",     VAR_NAME_EDM,   edmapdim, dim_str_name, model->num_edge_maps) != NC_NOERR) { goto error_ret;
}
  if (ex_write_object_names(exoid, "face map",     VAR_NAME_FAM,   famapdim, dim_str_name, model->num_face_maps) != NC_NOERR) { goto error_ret;
}
  if (ex_write_object_names(exoid, "element map",  VAR_NAME_EM,    emapdim,  dim_str_name, model->num_elem_maps) != NC_NOERR) { goto error_ret;
}
  if (ex_write_object_names(exoid, "coordinate",   VAR_NAME_COOR,  numdimdim,dim_str_name, model->num_dim) != NC_NOERR) { goto error_ret;
}

  /* leave define mode */
  if ((status = nc_enddef (exoid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to complete variable definitions in file id %d",exoid);
    ex_err("ex_put_init_ext",errmsg,exerrval);
    return (EX_FATAL);
  }
  
  /* Fill the id and status arrays with EX_INVALID_ID */
  {
    int *invalid_ids = NULL;
    int maxset = model->num_elem_blk;
    if (maxset < model->num_edge_blk) {  maxset = model->num_edge_blk;
}
    if (maxset < model->num_face_blk) {  maxset = model->num_face_blk;
}
    if (maxset < model->num_node_sets) { maxset = model->num_node_sets;
}
    if (maxset < model->num_edge_sets) { maxset = model->num_edge_sets;
}
    if (maxset < model->num_face_sets) { maxset = model->num_face_sets;
}
    if (maxset < model->num_side_sets) { maxset = model->num_side_sets;
}
    if (maxset < model->num_elem_sets) { maxset = model->num_elem_sets;
}
    if (maxset < model->num_node_maps) { maxset = model->num_node_maps;
}
    if (maxset < model->num_edge_maps) { maxset = model->num_edge_maps;
}
    if (maxset < model->num_face_maps) { maxset = model->num_face_maps;
}
    if (maxset < model->num_elem_maps) { maxset = model->num_elem_maps;
}

    /* allocate space for id/status array */
    if (!(invalid_ids = malloc(maxset*sizeof(int)))) {
      exerrval = EX_MEMFAIL;
      sprintf(errmsg,
	      "Error: failed to allocate memory for id/status array for file id %d", exoid);
      ex_err("ex_put_init_ext",errmsg,exerrval);
      return (EX_FATAL);
    }
    
    invalidate_id_status(exoid, VAR_STAT_EL_BLK, VAR_ID_EL_BLK,
			 model->num_elem_blk, invalid_ids);
    invalidate_id_status(exoid, VAR_STAT_ED_BLK, VAR_ID_ED_BLK,
			 model->num_edge_blk, invalid_ids);
    invalidate_id_status(exoid, VAR_STAT_FA_BLK, VAR_ID_FA_BLK,
			 model->num_face_blk, invalid_ids);
    invalidate_id_status(exoid, VAR_NS_STAT,  VAR_NS_IDS,
			 model->num_node_sets, invalid_ids);
    invalidate_id_status(exoid, VAR_ES_STAT,  VAR_ES_IDS,
			 model->num_edge_sets, invalid_ids);
    invalidate_id_status(exoid, VAR_FS_STAT,  VAR_FS_IDS,
			 model->num_face_sets, invalid_ids);
    invalidate_id_status(exoid, VAR_SS_STAT,  VAR_SS_IDS,
			 model->num_side_sets, invalid_ids);
    invalidate_id_status(exoid, VAR_ELS_STAT, VAR_ELS_IDS,
			 model->num_elem_sets, invalid_ids);

    invalidate_id_status(exoid, 0, VAR_NM_PROP(1),  model->num_node_maps, invalid_ids);
    invalidate_id_status(exoid, 0, VAR_EDM_PROP(1), model->num_edge_maps, invalid_ids);
    invalidate_id_status(exoid, 0, VAR_FAM_PROP(1), model->num_face_maps, invalid_ids);
    invalidate_id_status(exoid, 0, VAR_EM_PROP(1),  model->num_elem_maps, invalid_ids);

    if (invalid_ids != NULL) {
      free(invalid_ids);
      invalid_ids = NULL;
    }
  }

  /* Write dummy values to the names arrays to avoid corruption issues on some platforms */
  if (model->num_elem_blk > 0) { write_dummy_names(exoid, EX_ELEM_BLOCK);
}
  if (model->num_edge_blk > 0) { write_dummy_names(exoid, EX_EDGE_BLOCK);
}
  if (model->num_face_blk > 0) { write_dummy_names(exoid, EX_FACE_BLOCK);
}
  if (model->num_node_sets> 0) { write_dummy_names(exoid, EX_NODE_SET);
}
  if (model->num_edge_sets> 0) { write_dummy_names(exoid, EX_EDGE_SET);
}
  if (model->num_face_sets> 0) { write_dummy_names(exoid, EX_FACE_SET);
}
  if (model->num_side_sets> 0) { write_dummy_names(exoid, EX_SIDE_SET);
}
  if (model->num_elem_sets> 0) { write_dummy_names(exoid, EX_ELEM_SET);
}
  if (model->num_node_maps> 0) { write_dummy_names(exoid, EX_NODE_MAP);
}
  if (model->num_edge_maps> 0) { write_dummy_names(exoid, EX_EDGE_MAP);
}
  if (model->num_face_maps> 0) { write_dummy_names(exoid, EX_FACE_MAP);
}
  if (model->num_elem_maps> 0) { write_dummy_names(exoid, EX_ELEM_MAP);
}

  return (EX_NOERR);
  
  /* Fatal error: exit definition mode and return */
 error_ret:
  if (nc_enddef (exoid) != NC_NOERR)     /* exit define mode */
    {
      sprintf(errmsg,
              "Error: failed to complete definition for file id %d",
              exoid);
      ex_err("ex_put_init_ext",errmsg,exerrval);
    }
  return (EX_FATAL);
}
Exemple #19
0
/*! \internal */
int cpy_var_def(int in_id,int out_id,int rec_dim_id,char *var_nm)
/*
   int in_id: input netCDF input-file ID
   int out_id: input netCDF output-file ID
   int rec_dim_id: input input-file record dimension ID
   char *var_nm: input variable name
   int cpy_var_def(): output output-file variable ID
 */
{
  /* Routine to copy the variable metadata from an input netCDF file
   * to an output netCDF file. 
   */

  int status;
  int *dim_in_id;
  int *dim_out_id;
  int idx;
  int nbr_dim;
  int var_in_id;
  int var_out_id;

  nc_type var_type;

  /* See if the requested variable is already in the output file. */
  status = nc_inq_varid(out_id, var_nm, &var_out_id);
  if(status == NC_NOERR)
    return var_out_id;

  /* See if the requested variable is in the input file. */
  (void)nc_inq_varid(in_id, var_nm, &var_in_id);

  /* Get the type of the variable and the number of dimensions. */
  (void)nc_inq_vartype (in_id, var_in_id, &var_type);
  (void)nc_inq_varndims(in_id, var_in_id, &nbr_dim);

  /* Recall:
     1. The dimensions must be defined before the variable.
     2. The variable must be defined before the attributes. */

  /* Allocate space to hold the dimension IDs */
  dim_in_id=malloc(nbr_dim*sizeof(int)); 
  dim_out_id=malloc(nbr_dim*sizeof(int));

  /* Get the dimension IDs */
  (void)nc_inq_vardimid(in_id, var_in_id, dim_in_id);

  /* Get the dimension sizes and names */
  for(idx=0;idx<nbr_dim;idx++){
    char dim_nm[NC_MAX_NAME];
    size_t dim_sz;

    (void)nc_inq_dim(in_id, dim_in_id[idx], dim_nm, &dim_sz);

    /* See if the dimension has already been defined */
    status = nc_inq_dimid(out_id, dim_nm, &dim_out_id[idx]);

    /* If the dimension hasn't been defined, copy it */
    if (status != NC_NOERR) {
      if (dim_in_id[idx] != rec_dim_id) {
        (void)nc_def_dim(out_id, dim_nm, dim_sz, &dim_out_id[idx]);
      } else {
        (void)nc_def_dim(out_id, dim_nm, NC_UNLIMITED, &dim_out_id[idx]);
      } 
    } 
  } 

  /* Define the variable in the output file */

  /* If variable is float or double, define it according to the EXODUS
     file's IO_word_size */

  if ((var_type == NC_FLOAT) || (var_type == NC_DOUBLE)) {
    (void)nc_def_var(out_id, var_nm, nc_flt_code(out_id), nbr_dim, dim_out_id, &var_out_id);
    ex_compress_variable(out_id, var_out_id, 2);
  } else {
    (void)nc_def_var(out_id, var_nm, var_type,            nbr_dim, dim_out_id, &var_out_id);
    ex_compress_variable(out_id, var_out_id, 1);
  }

  /* Free the space holding the dimension IDs */
  (void)free(dim_in_id);
  (void)free(dim_out_id);

  return var_out_id;
} /* end cpy_var_def() */
int ex_put_cmap_params_cc(int  exoid,
                          void_int *node_cmap_ids,
                          void_int *node_cmap_node_cnts,
                          void_int *node_proc_ptrs,
                          void_int *elem_cmap_ids,
                          void_int *elem_cmap_elem_cnts,
                          void_int *elem_proc_ptrs
                          )
{
  const char   *func_name="ex_put_cmap_params_cc";

  size_t  num_n_comm_maps, num_e_comm_maps, num_procs_in_file;
  int     status, icm, n_varid[2], e_varid[2], iproc;
  int     varid, n_dimid[1], e_dimid[1];
  int     n_varid_idx, e_varid_idx;
  int     num_icm;
  size_t start[1], count[1];
  size_t ecnt_cmap, ncnt_cmap;

  long long nl_ecnt_cmap, nl_ncnt_cmap;
  void_int *n_var_idx = NULL;
  void_int *e_var_idx = NULL;

  int  nmstat;

  char    errmsg[MAX_ERR_LENGTH];
  int     format;
  int     index_type, bulk_type;
  /*-----------------------------Execution begins-----------------------------*/

  exerrval = 0; /* clear error code */

  /* See if using NC_FORMAT_NETCDF4 format... */
  nc_inq_format(exoid, &format);
  if ((ex_int64_status(exoid) & EX_BULK_INT64_DB) || (format == NC_FORMAT_NETCDF4)) {
    index_type = NC_INT64;
  } else {
    index_type = NC_INT;
  }
  if (ex_int64_status(exoid) & EX_BULK_INT64_DB) {
    bulk_type = NC_INT64;
  } else {
    bulk_type = NC_INT;
  }
  
  /* Get the number of processors in the file */
  if ((status = nc_inq_dimid(exoid, DIM_NUM_PROCS_F, &n_dimid[0])) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
            "Error: failed to get dimension ID for \"%s\" in file ID %d",
            DIM_NUM_PROCS_F, exoid);
    ex_err(func_name, errmsg, exerrval);
    return (EX_FATAL);
  }

  if ((status = nc_inq_dimlen(exoid, n_dimid[0], &num_procs_in_file)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
            "Error: failed to find length of dimension \"%s\" in file ID %d",
            DIM_NUM_PROCS_F, exoid);
    ex_err(func_name, errmsg, exerrval);
    return (EX_FATAL);
  }

  /*
   * since I cannot get variables while in define mode, I need to
   * get the cmap information index variables before I go into
   * define mode
   */

  /* Check to see if there are nodal communications maps in the file */
  if (nc_inq_dimid(exoid, DIM_NUM_N_CMAPS, &n_dimid[0]) != NC_NOERR) {
    num_n_comm_maps = 0;
  }
  else {
    if ((status = nc_inq_dimlen(exoid, n_dimid[0], &num_n_comm_maps)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to find length of dimension \"%s\" in \
file ID %d",
              DIM_NUM_N_CMAPS, exoid);
      ex_err(func_name, errmsg, exerrval);
      return (EX_FATAL);
    }
  }

  if (num_n_comm_maps > 0) {
    /* Get the variable ID for the comm map index vector */
    if ((status = nc_inq_varid(exoid, VAR_N_COMM_INFO_IDX, &n_varid_idx)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to find variable ID for \"%s\" in file ID %d",
              VAR_N_COMM_INFO_IDX, exoid);
      ex_err(func_name, errmsg, exerrval);
      return (EX_FATAL);
    }

    /* allocate space for the index variable */
    if (index_type == NC_INT64) {
      n_var_idx = malloc((num_procs_in_file + 1) * sizeof(long long));
    } else {
      n_var_idx = malloc((num_procs_in_file + 1) * sizeof(int));
    }
    if (!n_var_idx) {
      exerrval = EX_MSG;
      sprintf(errmsg,
              "Error: insufficient memory to read index variable from file ID %d",
              exoid);
      ex_err(func_name, errmsg, exerrval);
      return (EX_FATAL);
    }

    /* and set the last value of the index */

    /* get the communication map info index */
    if (index_type == NC_INT64) {
      ((long long*)n_var_idx)[0] = 0;
      status = nc_get_var_longlong(exoid, n_varid_idx, &((long long*)n_var_idx)[1]);
    } else {
      ((int*)n_var_idx)[0] = 0;
      status = nc_get_var_int(exoid, n_varid_idx, &((int*)n_var_idx)[1]);
    }
    if (status != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to get variable \"%s\" from file ID %d",
	      VAR_N_COMM_INFO_IDX, exoid);
      ex_err(func_name, errmsg, exerrval);
      return (EX_FATAL);
    }
  } /* "if (num_n_comm_maps > 0)" */

    /* Check to see if there are elemental communications maps in the file */
  if ((status = nc_inq_dimid(exoid, DIM_NUM_E_CMAPS, &e_dimid[0])) != NC_NOERR) {
    num_e_comm_maps = 0;
  }
  else {
    if ((status = nc_inq_dimlen(exoid, e_dimid[0], &num_e_comm_maps)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to find length of dimension \"%s\" in \
file ID %d",
	      DIM_NUM_E_CMAPS, exoid);
      ex_err(func_name, errmsg, exerrval);
      return (EX_FATAL);
    }
  }

  if (num_e_comm_maps > 0) {
    /* Get the variable ID for the comm map index vector */
    if ((status = nc_inq_varid(exoid, VAR_E_COMM_INFO_IDX, &e_varid_idx)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to find variable ID for \"%s\" in file ID %d",
	      VAR_E_COMM_INFO_IDX, exoid);
      ex_err(func_name, errmsg, exerrval);
      return (EX_FATAL);
    }

    /* allocate space for the index variable */
    if (index_type == NC_INT64) {
      e_var_idx = malloc((num_procs_in_file + 1) * sizeof(long long));
    } else {
      e_var_idx = malloc((num_procs_in_file + 1) * sizeof(int));
    }
    if (!e_var_idx) {
      exerrval = EX_MSG;
      sprintf(errmsg,
	      "Error: insufficient memory to read index variable from file ID %d",
	      exoid);
      ex_err(func_name, errmsg, exerrval);
      return (EX_FATAL);
    }

    /* get the communication map info index */
    if (index_type == NC_INT64) {
      ((long long*)e_var_idx)[0] = 0;
      status = nc_get_var_longlong(exoid, e_varid_idx, &((long long*)e_var_idx)[1]);
    } else {
      ((int*)e_var_idx)[0] = 0;
      status = nc_get_var_int(exoid, e_varid_idx, &((int*)e_var_idx)[1]);
    }
    if (status != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to get variable \"%s\" from file ID %d",
	      VAR_E_COMM_INFO_IDX, exoid);
      ex_err(func_name, errmsg, exerrval);
      return (EX_FATAL);
    }
  } /* "if (num_e_comm_maps >0)" */

    /* Put NetCDF file into define mode */
  if ((status = nc_redef(exoid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to put file ID %d into define mode", exoid);
    ex_err(func_name, errmsg, exerrval);
    return (EX_FATAL);
  }

  /*
   * Add dimensions for the size of the number of nodal
   * communication maps.
   */
  if (num_n_comm_maps > 0) {
    /* add the communications data index variable */
    if ((status = nc_def_var(exoid, VAR_N_COMM_DATA_IDX, index_type, 1,
			     n_dimid, &n_varid_idx)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to add variable \"%s\" in file ID %d",
	      VAR_N_COMM_DATA_IDX, exoid);
      ex_err(func_name, errmsg, exerrval);
      /* Leave define mode before returning */
      ex_leavedef(exoid, func_name);

      return (EX_FATAL);
    }

    /* now add up all of the nodal communications maps */
    ncnt_cmap = 0;
    for(iproc=0; iproc < num_procs_in_file; iproc++) {
      if (index_type == NC_INT64) {
	num_icm = ((int64_t*)n_var_idx)[iproc+1] - ((int64_t*)n_var_idx)[iproc];
      } else {
	num_icm = ((int*)n_var_idx)[iproc+1] - ((int*)n_var_idx)[iproc];
      }
      for(icm=0; icm < num_icm; icm++) {
	if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
	  ncnt_cmap += ((int64_t*)node_cmap_node_cnts)[((int64_t*)node_proc_ptrs)[iproc]+icm];
	} else {
	  ncnt_cmap += ((int*)node_cmap_node_cnts)[((int*)node_proc_ptrs)[iproc]+icm];
	}
}
    }

    if ((status = nc_def_dim(exoid, DIM_NCNT_CMAP, ncnt_cmap, &n_dimid[0])) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to add dimension for \"%s\" of size %"ST_ZU" in file ID %d",
	      DIM_NCNT_CMAP, ncnt_cmap, exoid);
      ex_err(func_name, errmsg, exerrval);
      /* Leave define mode before returning */
      ex_leavedef(exoid, func_name);

      return (EX_FATAL);
    }

    /* Define variables for the nodal IDS and processor vectors */
    if ((status = nc_def_var(exoid, VAR_N_COMM_NIDS, bulk_type, 1, n_dimid, &varid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to add variable \"%s\" in file ID %d",
	      VAR_N_COMM_NIDS, exoid);
      ex_err(func_name, errmsg, exerrval);
      /* Leave define mode before returning */
      ex_leavedef(exoid, func_name);

      return (EX_FATAL);
    }
    ex_compress_variable(exoid, varid, 1);

    if ((status = nc_def_var(exoid, VAR_N_COMM_PROC, NC_INT, 1, n_dimid, &varid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to add variable \"%s\" in file ID %d",
	      VAR_N_COMM_PROC, exoid);
      ex_err(func_name, errmsg, exerrval);
      /* Leave define mode before returning */
      ex_leavedef(exoid, func_name);

      return (EX_FATAL);
    }
    ex_compress_variable(exoid, varid, 1);

  } /* End "if (num_n_comm_maps > 0)" */

    /*
     * Add dimensions for the size of the number of elemental
     * communication maps.
     */
  if (num_e_comm_maps > 0) {
    /* add the communications data index variable */
    if ((status = nc_def_var(exoid, VAR_E_COMM_DATA_IDX, index_type, 1,
			     e_dimid, &e_varid_idx)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to add variable \"%s\" in file ID %d",
	      VAR_E_COMM_DATA_IDX, exoid);
      ex_err(func_name, errmsg, exerrval);
      /* Leave define mode before returning */
      ex_leavedef(exoid, func_name);

      return (EX_FATAL);
    }

    /* now add up all of the nodal communications maps */
    ecnt_cmap = 0;
    for(iproc=0; iproc < num_procs_in_file; iproc++) {
      if (index_type == NC_INT64) {
	num_icm = ((int64_t*)e_var_idx)[iproc+1] - ((int64_t*)e_var_idx)[iproc];
      } else {
	num_icm = ((int*)e_var_idx)[iproc+1] - ((int*)e_var_idx)[iproc];
      }
      for(icm=0; icm < num_icm; icm++) {
	if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
	  ecnt_cmap += ((int64_t*)elem_cmap_elem_cnts)[((int64_t*)elem_proc_ptrs)[iproc]+icm];
	} else {
	  ecnt_cmap += ((int*)elem_cmap_elem_cnts)[((int*)elem_proc_ptrs)[iproc]+icm];
	}
}
    }

    /* Add dimensions for elemental communications maps */
    if ((status = nc_def_dim(exoid, DIM_ECNT_CMAP, ecnt_cmap, &e_dimid[0])) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to add dimension for \"%s\" in file ID %d",
	      DIM_ECNT_CMAP, exoid);
      ex_err(func_name, errmsg, exerrval);
      /* Leave define mode before returning */
      ex_leavedef(exoid, func_name);

      return (EX_FATAL);
    }

    /* Define variables for the element IDS and processor vectors */
    if ((status = nc_def_var(exoid, VAR_E_COMM_EIDS, bulk_type, 1, e_dimid, &varid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to add variable \"%s\" in file ID %d",
	      VAR_E_COMM_EIDS, exoid);
      ex_err(func_name, errmsg, exerrval);
      /* Leave define mode before returning */
      ex_leavedef(exoid, func_name);

      return (EX_FATAL);
    }
    ex_compress_variable(exoid, varid, 1);

    if ((status = nc_def_var(exoid, VAR_E_COMM_PROC, NC_INT, 1, e_dimid, &varid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to add variable \"%s\" in file ID %d",
	      VAR_E_COMM_PROC, exoid);
      ex_err(func_name, errmsg, exerrval);
      /* Leave define mode before returning */
      ex_leavedef(exoid, func_name);

      return (EX_FATAL);
    }
    ex_compress_variable(exoid, varid, 1);

    if ((status = nc_def_var(exoid, VAR_E_COMM_SIDS, bulk_type, 1, e_dimid, &varid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to add variable \"%s\" in file ID %d",
	      VAR_E_COMM_SIDS, exoid);
      ex_err(func_name, errmsg, exerrval);
      /* Leave define mode before returning */
      ex_leavedef(exoid, func_name);

      return (EX_FATAL);
    }
    ex_compress_variable(exoid, varid, 1);

  } /* End "if (num_e_comm_maps > 0)" */


    /* Exit define mode */
  ex_leavedef(exoid, func_name);

  /* Set the status of the nodal communication maps */
  if (num_n_comm_maps > 0) {

    /* need to get the two "n_comm_*" variable ids */

    if ((status = nc_inq_varid(exoid, VAR_N_COMM_STAT, &n_varid[0])) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to find variable ID for \"%s\" in file ID %d",
	      VAR_N_COMM_STAT, exoid);
      ex_err(func_name, errmsg, exerrval);
      return (EX_FATAL);
    }

    /* Get the variable ID for the comm map IDs vector */
    if ((status = nc_inq_varid(exoid, VAR_N_COMM_IDS, &n_varid[1])) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to find variable ID for \"%s\" in file ID %d",
	      VAR_N_COMM_IDS, exoid);
      ex_err(func_name, errmsg, exerrval);
      return (EX_FATAL);
    }

    /* reset the index variable */
    nl_ncnt_cmap = 0;

    for(iproc=0; iproc < num_procs_in_file; iproc++) {
      size_t proc_ptr;
      if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
	proc_ptr = ((int64_t*)node_proc_ptrs)[iproc];
      } else {
	proc_ptr = ((int*)node_proc_ptrs)[iproc];
      }

      if (index_type == NC_INT64) {
	num_icm = ((int64_t*)n_var_idx)[iproc+1] - ((int64_t*)n_var_idx)[iproc];
      } else {
	num_icm = ((int*)n_var_idx)[iproc+1] - ((int*)n_var_idx)[iproc];
      }
      for(icm=0; icm < num_icm; icm++) {
	size_t cnt;
	if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
	  cnt = ((int64_t*)node_cmap_node_cnts)[proc_ptr+icm];
	} else {
	  cnt = ((int*)node_cmap_node_cnts)[proc_ptr+icm];
	}
	
	if (index_type == NC_INT64) {
	  start[0] = ((int64_t*)n_var_idx)[iproc] + icm;
	} else {
	  start[0] = ((int*)n_var_idx)[iproc] + icm;
	}
	if (cnt > 0) {
	  nmstat = 1;
	} else {
	  nmstat = 0;
}

	if ((status = nc_put_var1_int(exoid, n_varid[0], start, &nmstat)) != NC_NOERR) {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: unable to output variable in file ID %d", exoid);
	  ex_err(func_name, errmsg, exerrval);
	  return (EX_FATAL);
	}

	/* increment to the next starting position */
	nl_ncnt_cmap += cnt;

	/* fill the data index variable */
	status = nc_put_var1_longlong(exoid, n_varid_idx, start, &nl_ncnt_cmap);

	if (status != NC_NOERR) {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: failed to output int elem map index in file ID %d",
		  exoid);
	  ex_err(func_name, errmsg, exerrval);
	  return (EX_FATAL);
	}
      } /* End "for(icm=0; icm < num_icm; icm++)" */

      if (num_icm > 0) {
	/* Output the nodal comm map IDs */
	if (index_type == NC_INT64) {
	  start[0] = ((int64_t*)n_var_idx)[iproc];
	} else {
	  start[0] = ((int*)n_var_idx)[iproc];
	}
	count[0] =  num_icm;
	if (ex_int64_status(exoid) & EX_IDS_INT64_API) {
	  status = nc_put_vara_longlong(exoid, n_varid[1], start, count,
					&((long long*)node_cmap_ids)[proc_ptr]);
	} else {
	  status = nc_put_vara_int(exoid, n_varid[1], start, count,
				   &((int*)node_cmap_ids)[proc_ptr]);
	}
	if (status != NC_NOERR) {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: failed to output variable in file ID %d", exoid);
	  ex_err(func_name, errmsg, exerrval);

	  return (EX_FATAL);
	}
      }
    } /* End "for(iproc=0; iproc < num_procs_in_file; iproc++)" */

      /* free up memory for index */
    free(n_var_idx);

  } /* End "if (num_n_comm_maps > 0)" */


    /* Set the status of the elemental communication maps */
  if (num_e_comm_maps > 0) {

    /* need to get the two "e_comm_*" variables" */

    /* Get variable ID for elemental status vector */
    if ((status = nc_inq_varid(exoid, VAR_E_COMM_STAT, &e_varid[0])) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to find variable ID for \"%s\" in file ID %d",
	      VAR_E_COMM_STAT, exoid);
      ex_err(func_name, errmsg, exerrval);
      return (EX_FATAL);
    }

    /* Get the variable ID for the elemental comm map IDs vector */
    if ((status = nc_inq_varid(exoid, VAR_E_COMM_IDS, &e_varid[1])) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to find variable ID for \"%s\" in file ID %d",
	      VAR_E_COMM_IDS, exoid);
      ex_err(func_name, errmsg, exerrval);
      return (EX_FATAL);
    }

    /* reset the index variable */
    nl_ecnt_cmap = 0;

    for(iproc=0; iproc < num_procs_in_file; iproc++) {
      size_t proc_ptr;
      if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
	proc_ptr = ((int64_t*)elem_proc_ptrs)[iproc];
      } else {
	proc_ptr = ((int*)elem_proc_ptrs)[iproc];
      }
      if (index_type == NC_INT64) {
	num_icm = ((int64_t*)e_var_idx)[iproc+1] - ((int64_t*)e_var_idx)[iproc];
      } else {
	num_icm = ((int*)e_var_idx)[iproc+1] - ((int*)e_var_idx)[iproc];
      }
      for(icm=0; icm < num_icm; icm++) {

	size_t cnt;
	if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
	  cnt = ((int64_t*)elem_cmap_elem_cnts)[proc_ptr+icm];
	} else {
	  cnt = ((int*)elem_cmap_elem_cnts)[proc_ptr+icm];
	}

	if (index_type == NC_INT64) {
	  start[0] = ((int64_t*)e_var_idx)[iproc] + icm;
	} else {
	  start[0] = ((int*)e_var_idx)[iproc] + icm;
	}
	if (cnt > 0) {
	  nmstat = 1;
	} else {
	  nmstat = 0;
}

	if ((status = nc_put_var1_int(exoid, e_varid[0], start, &nmstat)) != NC_NOERR) {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: unable to output variable in file ID %d", exoid);
	  ex_err(func_name, errmsg, exerrval);
	  return (EX_FATAL);
	}

	/* increment to the next starting position */
	nl_ecnt_cmap += cnt;

	/* fill the data index variable */
	status = nc_put_var1_longlong(exoid, e_varid_idx, start, &nl_ecnt_cmap);

	if (status != NC_NOERR) {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: failed to output int elem map index in file ID %d",
		  exoid);
	  ex_err(func_name, errmsg, exerrval);
	  return (EX_FATAL);
	}
      } /* End "for(icm=0; icm < num_icm; icm++)" */

      if (num_icm > 0) {
	/* Output the elemental comm map IDs */
	if (index_type == NC_INT64) {
	  start[0] = ((int64_t*)e_var_idx)[iproc];
	} else {
	  start[0] = ((int*)e_var_idx)[iproc];
	}
	count[0] = num_icm;
	if (ex_int64_status(exoid) & EX_IDS_INT64_API) {
	  status = nc_put_vara_longlong(exoid, e_varid[1], start, count,
					&((long long*)elem_cmap_ids)[proc_ptr]);
	} else {
	  status = nc_put_vara_int(exoid, e_varid[1], start, count,
				   &((int*)elem_cmap_ids)[proc_ptr]);
	}
	if (status != NC_NOERR) {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: failed to output variable in file ID %d", exoid);
	  ex_err(func_name, errmsg, exerrval);
	  return (EX_FATAL);
	}
      }
    } /* End "for(iproc=0; iproc < num_procs_in_file; iproc++)" */

    free(e_var_idx);

  } /* End "if (num_e_comm_maps > 0)" */

  return (EX_NOERR);
}
int ex_put_elem_var_slab (int   exoid,
		          int   time_step,
		          int   elem_var_index,
		          ex_entity_id   elem_blk_id,
                          int64_t   start_pos,
		          int64_t   num_vals,
		          void *elem_var_vals)
{
  int status;
  int varid, dimid,time_dim, numelbdim, dims[2], elem_blk_id_ndx;
  size_t num_elem_blk, num_elem_var, start[2], count[2];
  int *elem_var_tab;
  char errmsg[MAX_ERR_LENGTH];

  exerrval = 0; /* clear error code */

  /* Determine index of elem_blk_id in VAR_ID_EL_BLK array */
  if ((elem_blk_id_ndx = ex_id_lkup(exoid, EX_ELEM_BLOCK, elem_blk_id)) < 0) {
    if (exerrval == EX_NULLENTITY) {
      sprintf(errmsg,
	      "Warning: no variables allowed for NULL block %"PRId64" in file id %d",
	      elem_blk_id, exoid);
      ex_err("ex_put_elem_var_slab", errmsg, EX_NULLENTITY);
      return (EX_WARN);
    } 
      sprintf(errmsg,
	      "Error: failed to locate element block id %"PRId64" in %s array in file id %d",
	      elem_blk_id, VAR_ID_EL_BLK, exoid);
      ex_err("ex_put_elem_var_slab", errmsg, exerrval);
      return (EX_FATAL);
    
  }

  if ((status = nc_inq_varid (exoid,
			      VAR_ELEM_VAR(elem_var_index, elem_blk_id_ndx), &varid)) != NC_NOERR) {
    if (status == NC_ENOTVAR) { /* variable doesn't exist, create it! */

      /*    inquire previously defined dimensions */

      /* check for the existance of an element variable truth table */
      if ((status = nc_inq_varid (exoid, VAR_ELEM_TAB, &varid)) == NC_NOERR) {
	/* find out number of element blocks and element variables */
	if ((status = nc_inq_dimid (exoid, DIM_NUM_EL_BLK, &dimid)) != NC_NOERR) {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: failed to locate number of element blocks in file id %d",
		  exoid);
	  ex_err("ex_put_elem_var_slab", errmsg, exerrval);
	  return (EX_FATAL);
	}

	if ((status = nc_inq_dimlen(exoid, dimid, &num_elem_blk)) != NC_NOERR) {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: failed to get number of element blocks in file id %d",
		  exoid);
	  ex_err("ex_put_elem_var_slab", errmsg, exerrval);
	  return (EX_FATAL);
	}

	if ((status = nc_inq_dimid (exoid, DIM_NUM_ELE_VAR, &dimid)) != NC_NOERR) {
	  exerrval = EX_BADPARAM;
	  sprintf(errmsg,
		  "Error: no element variables stored in file id %d",
		  exoid);
	  ex_err("ex_put_elem_var_slab", errmsg, exerrval);
	  return (EX_FATAL);
	}

	if ((status = nc_inq_dimlen(exoid, dimid, &num_elem_var)) != NC_NOERR) {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: failed to get number of element variables in file id %d",
		  exoid);
	  ex_err("ex_put_elem_var_slab", errmsg, exerrval);
	  return (EX_FATAL);
	}

	if (!(elem_var_tab =
	      (int *)malloc(num_elem_blk*num_elem_var*sizeof(int)))) {
	  exerrval = EX_MEMFAIL;
	  sprintf(errmsg,
		  "Error: failed to allocate memory for element variable truth table in file id %d",
		  exoid);
	  ex_err("ex_put_elem_var_slab", errmsg, exerrval);
	  return (EX_FATAL);
	}

	/*   read in the element variable truth table */
	if ((status = nc_get_var_int(exoid, varid, elem_var_tab)) != NC_NOERR) {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: failed to get truth table from file id %d", exoid);
	  ex_err("ex_put_elem_var_slab", errmsg, exerrval);
	  return (EX_FATAL);
	}

	if (elem_var_tab[num_elem_var*(elem_blk_id_ndx-1)+elem_var_index-1] == 0L) {
	  free(elem_var_tab);
	  exerrval = EX_BADPARAM;
	  sprintf(errmsg,
		  "Error: Invalid element variable %d, block %"PRId64" in file id %d",
		  elem_var_index, elem_blk_id, exoid);
	  ex_err("ex_put_elem_var_slab", errmsg, exerrval);
	  return (EX_FATAL);
	}
	free(elem_var_tab);
      }

      if ((status = nc_inq_dimid (exoid, DIM_TIME, &time_dim)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to locate time dimension in file id %d", exoid);
	ex_err("ex_put_elem_var_slab", errmsg, exerrval);
	goto error_ret;		/* exit define mode and return */
      }

      if ((status = nc_inq_dimid(exoid, DIM_NUM_EL_IN_BLK(elem_blk_id_ndx), &numelbdim)) != NC_NOERR) {
	if (status == NC_EBADDIM) {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: number of elements in element block %"PRId64" not defined in file id %d",
		  elem_blk_id, exoid);
	  ex_err("ex_put_elem_var_slab", errmsg, exerrval);
	} else {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: failed to locate number of elements in element block %"PRId64" in file id %d",
		  elem_blk_id, exoid);
	  ex_err("ex_put_elem_var_slab", errmsg, exerrval);
	}
	goto error_ret;
      }

      /*    variable doesn't exist so put file into define mode  */
      if ((status = nc_redef (exoid)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to put file id %d into define mode", exoid);
	ex_err("ex_put_elem_var_slab", errmsg, exerrval);
	return (EX_FATAL);
      }


      /*    define netCDF variable to store element variable values */
      dims[0] = time_dim;
      dims[1] = numelbdim;
      if ((status = nc_def_var(exoid, VAR_ELEM_VAR(elem_var_index, elem_blk_id_ndx),
			       nc_flt_code(exoid), 2, dims, &varid)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to define element variable %d in file id %d",
		elem_var_index, exoid);
	ex_err("ex_put_elem_var_slab", errmsg, exerrval);
	goto error_ret;
      }
      ex_compress_variable(exoid, varid, 2);


      /*    leave define mode  */
      if ((status = nc_enddef(exoid)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to complete element variable %s definition to file id %d",
		VAR_ELEM_VAR(elem_var_index, elem_blk_id_ndx), exoid);
	ex_err("ex_put_elem_var_slab", errmsg, exerrval);
	return (EX_FATAL);
      }
    } else {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to locate element variable %s in file id %d",
	      VAR_ELEM_VAR(elem_var_index, elem_blk_id_ndx),exoid);
      ex_err("ex_put_elem_var_slab", errmsg, exerrval);
      return (EX_FATAL);
    }
  }

  /* store element variable values */
  start[0] = --time_step;
  start[1] = --start_pos;

  count[0] = 1;
  count[1] = num_vals;

  if (ex_comp_ws(exoid) == 4) {
    status = nc_put_vara_float(exoid, varid, start, count, elem_var_vals);
  } else {
    status = nc_put_vara_double(exoid, varid, start, count, elem_var_vals);
  }

  if (status != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to store element variable %d in file id %d", 
	    elem_var_index, exoid);
    ex_err("ex_put_elem_var_slab", errmsg, exerrval);
    return (EX_FATAL);
  }

  return (EX_NOERR);

  /* Fatal error: exit definition mode and return */
 error_ret:
  if (nc_enddef (exoid) != NC_NOERR)     /* exit define mode */
    {
      sprintf(errmsg,
	      "Error: failed to complete definition for file id %d", exoid);
      ex_err("ex_put_elem_var_slab", errmsg, exerrval);
    }
  return (EX_FATAL);
}
Exemple #22
0
int ex_put_concat_sets (int   exoid,
			ex_entity_type set_type,
			const struct ex_set_specs* set_specs)
{
  int status;
  int temp;
  const void_int  *num_entries_per_set = set_specs->num_entries_per_set;
  const void_int  *num_dist_per_set = set_specs->num_dist_per_set;
  const void_int  *sets_entry_index = set_specs->sets_entry_index;
  const void_int  *sets_dist_index = set_specs->sets_dist_index;
  const void *sets_dist_fact = set_specs->sets_dist_fact;
  size_t i, num_df, num_entry;
  int cur_num_sets, num_sets;
  int dimid, varid, set_id_ndx, dims[1];
  int  *set_stat = NULL;
  int set_int_type, int_size;

  const float *flt_dist_fact = NULL;
  const double *dbl_dist_fact = NULL;
  char errmsg[MAX_ERR_LENGTH];
  char* idsptr = NULL;
  char* statptr = NULL;
  char* numdfptr = NULL;
  char* factptr = NULL;
  char* elemptr = NULL;
  char* extraptr = NULL;
  ex_inquiry ex_inq_val;

  exerrval = 0; /* clear error code */

  int_size = sizeof(int);
  if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
    int_size = sizeof(int64_t);
  }
  
  /* setup pointers based on set_type 
     NOTE: there is another block that sets more stuff later ... */

  if (set_type == EX_NODE_SET) {
    ex_inq_val = EX_INQ_NODE_SETS;
    idsptr = VAR_NS_IDS;
    statptr = VAR_NS_STAT;
  }
  else if (set_type == EX_EDGE_SET) {
    ex_inq_val = EX_INQ_EDGE_SETS;
    idsptr = VAR_ES_IDS;
    statptr = VAR_ES_STAT;
  }
  else if (set_type == EX_FACE_SET) {
    ex_inq_val = EX_INQ_FACE_SETS;
    idsptr = VAR_FS_IDS;
    statptr = VAR_FS_STAT;
  }
  else if (set_type == EX_SIDE_SET) {
    ex_inq_val = EX_INQ_SIDE_SETS;
    idsptr = VAR_SS_IDS;
    statptr = VAR_SS_STAT;
  }
  else if (set_type == EX_ELEM_SET) {
    ex_inq_val = EX_INQ_ELEM_SETS;
    idsptr = VAR_ELS_IDS;
    statptr = VAR_ELS_STAT;
  }
  else {
    exerrval = EX_FATAL;
    sprintf(errmsg,
	    "Error: invalid set type (%d)", set_type);
    ex_err("ex_put_set_param",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* first check if any sets are specified */
  if ((status = nc_inq_dimid(exoid, ex_dim_num_objects(set_type), &temp)) != NC_NOERR) {
    if (status == NC_EBADDIM) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: no %ss defined for file id %d", ex_name_of_object(set_type), exoid);
      ex_err("ex_put_concat_sets",errmsg,exerrval);
    } else {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to locate %ss defined in file id %d",
	      ex_name_of_object(set_type), exoid);
      ex_err("ex_put_concat_sets",errmsg,exerrval);
    }
    return (EX_FATAL);
  }
   
  /* inquire how many sets are to be stored */
  num_sets = ex_inquire_int(exoid, ex_inq_val);
  if (num_sets < 0) {
    sprintf(errmsg,
	    "Error: failed to get number of %ss defined for file id %d",
	    ex_name_of_object(set_type), exoid);
    /* use error val from inquire */
    ex_err("ex_put_concat_sets",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* Fill out set status array */

  /* First, allocate space for the status list */
  if (!(set_stat= malloc(num_sets*sizeof(int)))) {
    exerrval = EX_MEMFAIL;
    sprintf(errmsg,
	    "Error: failed to allocate space for %s status array in file id %d",
	    ex_name_of_object(set_type), exoid);
    ex_err("ex_put_concat_sets",errmsg,exerrval);
    return (EX_FATAL);
  }

  if (int_size == sizeof(int64_t)) {
    for (i=0;i<num_sets;i++)  {
      set_stat[i] = (((int64_t*)num_entries_per_set)[i] == 0) ? 0 : 1;
    }
  } else {
    for (i=0;i<num_sets;i++)  {
      set_stat[i] = (((int*)num_entries_per_set)[i] == 0) ? 0 : 1;
    }
  }

  /* Next, get variable id of status array */
  if ((status = nc_inq_varid(exoid, statptr, &varid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to locate %s status in file id %d", 
	    ex_name_of_object(set_type), exoid);
    ex_err("ex_put_concat_sets",errmsg,exerrval);
    ex_safe_free(set_stat);
    return (EX_FATAL);
  }

  status = nc_put_var_int(exoid, varid, set_stat);

  if (status != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to store %s status array to file id %d",
	    ex_name_of_object(set_type), exoid);
    ex_err("ex_put_concat_set",errmsg,exerrval);
    ex_safe_free(set_stat);
    return (EX_FATAL);
  }

  /* put netcdf file into define mode  */
  if ((status = nc_redef (exoid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to put file id %d into define mode",
	    exoid);
    ex_err("ex_put_concat_sets",errmsg,exerrval);
    ex_safe_free(set_stat);
    return (EX_FATAL);
  }

  /* create set definitions */
  for (i=0; i<num_sets; i++) {
    int64_t set_id;
    if (ex_int64_status(exoid) & EX_IDS_INT64_API) {
      set_id = ((int64_t*)set_specs->sets_ids)[i];
    } else {
      set_id = ((int*)set_specs->sets_ids)[i];
    }

    /* Keep track of the total number of sets defined using a counter stored
       in a linked list keyed by exoid.
       NOTE: ex_get_file_item  is used to find the number of sets of type
       for a specific file and returns that value.
    */
    cur_num_sets=ex_get_file_item(exoid, ex_get_counter_list(set_type));
    if (cur_num_sets >= num_sets) {
      exerrval = EX_FATAL;
      sprintf(errmsg,
	      "Error: exceeded number of %ss (%d) defined in file id %d",
	      ex_name_of_object(set_type), num_sets,exoid);
      ex_err("ex_put_concat_sets",errmsg,exerrval);
      goto error_ret;
    }

    /*   NOTE: ex_inc_file_item  is used to find the number of sets
	 for a specific file and returns that value incremented. */

    cur_num_sets=ex_inc_file_item(exoid, ex_get_counter_list(set_type));
    set_id_ndx = cur_num_sets + 1;
    
    /* setup more pointers based on set_type */
    if (set_type == EX_NODE_SET) {
      elemptr = VAR_NODE_NS(set_id_ndx);
      extraptr = NULL;
      /* note we are using DIM_NUM_NODE_NS instead of DIM_NUM_DF_NS */
      numdfptr = DIM_NUM_NOD_NS(set_id_ndx);
      factptr = VAR_FACT_NS(set_id_ndx);
    }
    else if (set_type == EX_EDGE_SET) {
      elemptr = VAR_EDGE_ES(set_id_ndx);
      extraptr = VAR_ORNT_ES(set_id_ndx);
      numdfptr = DIM_NUM_DF_ES(set_id_ndx);
      factptr = VAR_FACT_ES(set_id_ndx);
    }
    else if (set_type == EX_FACE_SET) {
      elemptr = VAR_FACE_FS(set_id_ndx);
      extraptr = VAR_ORNT_FS(set_id_ndx);
      numdfptr = DIM_NUM_DF_FS(set_id_ndx);
      factptr = VAR_FACT_FS(set_id_ndx);
    }
    else if (set_type == EX_SIDE_SET) {
      elemptr = VAR_ELEM_SS(set_id_ndx);
      extraptr = VAR_SIDE_SS(set_id_ndx);
      numdfptr = DIM_NUM_DF_SS(set_id_ndx);
      factptr = VAR_FACT_SS(set_id_ndx);
    }
    if (set_type == EX_ELEM_SET) {
      elemptr = VAR_ELEM_ELS(set_id_ndx);
      extraptr = NULL;
      numdfptr = DIM_NUM_DF_ELS(set_id_ndx);
      factptr = VAR_FACT_ELS(set_id_ndx);
    }

    /*  define dimension for number of entries per set */
    if (set_stat[i] == 0) /* Is this a NULL set? */
      continue; /* Do not create anything for NULL sets! */

    if (int_size == sizeof(int)) {
      status = nc_def_dim(exoid, ex_dim_num_entries_in_object(set_type, set_id_ndx),
			  ((int*)num_entries_per_set)[i], &dimid);
    } else {
      status = nc_def_dim(exoid, ex_dim_num_entries_in_object(set_type, set_id_ndx),
			  ((int64_t*)num_entries_per_set)[i], &dimid);
    }
    
    if (status != NC_NOERR) {
      if (status == NC_ENAMEINUSE) {
	exerrval = status;
	sprintf(errmsg,
		"Error: %s entry count %"PRId64" already defined in file id %d",
		ex_name_of_object(set_type), set_id,exoid);
	ex_err("ex_put_concat_sets",errmsg,exerrval);
      } else {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to define number of entries for %s %"PRId64" in file id %d",
		ex_name_of_object(set_type), set_id,exoid);
	ex_err("ex_put_concat_sets",errmsg,exerrval);
      }
      goto error_ret;
    }

    /* create element list variable for set */
    set_int_type = NC_INT;
    if (ex_int64_status(exoid) & EX_BULK_INT64_DB) {
      set_int_type = NC_INT64;
    }

    dims[0] = dimid;
    if ((status = nc_def_var(exoid,elemptr,set_int_type,1,dims, &temp)) != NC_NOERR) {
      if (status == NC_ENAMEINUSE) {
	exerrval = status;
	sprintf(errmsg,
		"Error: element list already exists for %s %"PRId64" in file id %d",
		ex_name_of_object(set_type), set_id,exoid);
	ex_err("ex_put_concat_sets",errmsg,exerrval);
      } else {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to create element list for %s %"PRId64" in file id %d",
		ex_name_of_object(set_type), set_id,exoid);
	ex_err("ex_put_concat_sets",errmsg,exerrval);
      }
      goto error_ret;            /* exit define mode and return */
    }
    ex_compress_variable(exoid, temp, 1);

    /* create extra list variable for set  (only for edge, face and side sets) */
    if (extraptr) {
      if ((status = nc_def_var(exoid,extraptr,set_int_type,1,dims, &temp)) != NC_NOERR) { 
	if (status == NC_ENAMEINUSE) {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: extra list already exists for %s %"PRId64" in file id %d",
		  ex_name_of_object(set_type), set_id,exoid);
	  ex_err("ex_put_concat_sets",errmsg,exerrval);
	} else {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: failed to create extra list for %s %"PRId64" in file id %d",
		  ex_name_of_object(set_type), set_id,exoid);
	  ex_err("ex_put_concat_sets",errmsg,exerrval);
	}
	goto error_ret;         /* exit define mode and return */
      }
      ex_compress_variable(exoid, temp, 1);
    }

    /*  define dimension for number of dist factors per set */
    /*  NOTE: only define df count if the dist factors exist! */
    if (int_size == sizeof(int64_t)) {
      num_df = ((int64_t*)num_dist_per_set)[i];
      num_entry = ((int64_t*)num_entries_per_set)[i];
    } else {
      num_df = ((int*)num_dist_per_set)[i];
      num_entry = ((int*)num_entries_per_set)[i];
    }

    if (num_df > 0) {
      
      if (set_type == EX_NODE_SET) {
	if (num_df != num_entry) {
	  exerrval = EX_FATAL;
	  sprintf(errmsg,
		  "Error: # dist fact (%"ST_ZU") not equal to # nodes (%"ST_ZU") in node set %"PRId64" file id %d",
		  num_df, num_entry, set_id,exoid);
	  ex_err("ex_put_concat_sets",errmsg,exerrval);
	  goto error_ret;          /* exit define mode and return */
	}

	/* resuse dimid from entry lists */
      } else  {
	if ((status = nc_def_dim(exoid, numdfptr,
				 num_df, &dimid)) != NC_NOERR) {
	  if (status == NC_ENAMEINUSE) {
	    exerrval = status;
	    sprintf(errmsg,
		    "Error: %s df count %"PRId64" already defined in file id %d",
		    ex_name_of_object(set_type), set_id,exoid);
	    ex_err("ex_put_concat_sets",errmsg,exerrval);
	  } else {
	    exerrval = status;
	    sprintf(errmsg,
		    "Error: failed to define %s df count for set %"PRId64" in file id %d",
		    ex_name_of_object(set_type), set_id,exoid);
	    ex_err("ex_put_concat_sets",errmsg,exerrval);
	  }
	  goto error_ret;
	}
      }

      /* create distribution factor list variable for set */
      dims[0] = dimid;
      if ((status = nc_def_var(exoid, factptr, nc_flt_code(exoid), 1, dims, &temp)) != NC_NOERR) {
	if (status == NC_ENAMEINUSE) {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: dist factor list already exists for %s %"PRId64" in file id %d",
		  ex_name_of_object(set_type), set_id,exoid);
	  ex_err("ex_put_concat_sets",errmsg,exerrval);
	} else {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: failed to create dist factor list for %s %"PRId64" in file id %d",
		  ex_name_of_object(set_type), set_id,exoid);
	  ex_err("ex_put_concat_sets",errmsg,exerrval);
	}
	goto error_ret;            /* exit define mode and return */
      }
      ex_compress_variable(exoid, temp, 2);
    } /* end define dist factors */
  }

  /* leave define mode  */
  if ((status = nc_enddef (exoid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to complete definition in file id %d",
	    exoid);
    ex_err("ex_put_concat_sets",errmsg,exerrval);
    ex_safe_free(set_stat);
    return (EX_FATAL);
  }

  /* Next, fill out set ids array */

  /* first get id of set ids array variable */
  if ((status = nc_inq_varid(exoid, idsptr, &varid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to locate %s ids array in file id %d",
	    ex_name_of_object(set_type), exoid);
    ex_err("ex_put_concat_sets",errmsg,exerrval);
    ex_safe_free(set_stat);
    return (EX_FATAL);
  }

  /* then, write out set id list */
  if (ex_int64_status(exoid) & EX_IDS_INT64_API) {
    status = nc_put_var_longlong(exoid, varid, set_specs->sets_ids);
  } else {
    status = nc_put_var_int(exoid, varid, set_specs->sets_ids);
  }

  if (status != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to store %s id array in file id %d",
	    ex_name_of_object(set_type), exoid);
    ex_err("ex_put_concat_sets",errmsg,exerrval);
    ex_safe_free(set_stat);
    return (EX_FATAL);
  }

  /* If the sets_entry_index is passed in as a NULL pointer, then
   *  the user only wants us to define the sets and not populate
   *  the data structures.
   */
  if (sets_entry_index == 0) {
    ex_safe_free(set_stat);
    return(EX_NOERR);
  }
  
  /* Now, use ExodusII call to store sets */
  for (i=0; i<num_sets; i++) {
    int64_t set_id;
    size_t df_ndx;
    
    if (set_stat[i] == 0) /* Is this a NULL set? */
      continue; /* Do not create anything for NULL sets! */

    if (ex_int64_status(exoid) & EX_IDS_INT64_API) {
      set_id = ((int64_t*)set_specs->sets_ids)[i];
    } else {
      set_id = ((int*)set_specs->sets_ids)[i];
    }

    if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
      int64_t* extra_list = NULL;
      /* set extra list */
      if (set_type == EX_EDGE_SET || set_type == EX_FACE_SET || set_type == EX_SIDE_SET)
	extra_list = &(((int64_t*)set_specs->sets_extra_list)[((int64_t*)sets_entry_index)[i]]);
      
      status = ex_put_set(exoid, set_type, set_id, 
			  &(((int64_t*)set_specs->sets_entry_list)[((int64_t*)sets_entry_index)[i]]),
			  extra_list);
    } else {
      int* extra_list = NULL;
      /* set extra list */
      if (set_type == EX_EDGE_SET || set_type == EX_FACE_SET || set_type == EX_SIDE_SET)
	extra_list = &(((int*)set_specs->sets_extra_list)[((int*)sets_entry_index)[i]]);
      
      status = ex_put_set(exoid, set_type, set_id, 
			  &(((int*)set_specs->sets_entry_list)[((int*)sets_entry_index)[i]]),
			  extra_list);
    }
    if (status != NC_NOERR) {
      ex_safe_free(set_stat);
      return(EX_FATAL); /* error will be reported by subroutine */
    }

    if (int_size == sizeof(int)) {
      num_df = ((int*)num_dist_per_set)[i];
      df_ndx = ((int*)sets_dist_index)[i];
    } else {
      num_df = ((int64_t*)num_dist_per_set)[i];
      df_ndx = ((int64_t*)sets_dist_index)[i];
    }

    if (ex_comp_ws(exoid) == sizeof(float)) {
      flt_dist_fact = sets_dist_fact;
      if (num_df > 0) {     /* store dist factors if required */
	if (ex_put_set_dist_fact(exoid, set_type, set_id,
				 &(flt_dist_fact[df_ndx])) == -1) {
	  sprintf(errmsg,
		  "Error: failed to store %s %"PRId64" dist factors for file id %d",
		  ex_name_of_object(set_type), set_id,exoid);
	  /* use error val from exodusII routine */
	  ex_err("ex_put_concat_sets",errmsg,exerrval);
	  ex_safe_free(set_stat);
	  return (EX_FATAL);
	}
      }
    } else if (ex_comp_ws(exoid) == sizeof(double)) {
      dbl_dist_fact = sets_dist_fact;
      if (num_df) {             /* only store if they exist */
	if (ex_put_set_dist_fact(exoid, set_type, set_id,
				 &(dbl_dist_fact[df_ndx])) == -1) {
	  sprintf(errmsg,
		  "Error: failed to store %s %"PRId64" dist factors for file id %d",
		  ex_name_of_object(set_type), set_id,exoid);
	  /* use error val from exodusII routine */
	  ex_err("ex_put_concat_sets",errmsg,exerrval);
	  ex_safe_free(set_stat);
	  return (EX_FATAL);
	}
      }
    } else {
      /* unknown floating point word size */
      exerrval = EX_BADPARAM;
      sprintf(errmsg,
	      "Error: unsupported floating point word size %d for file id %d",
	      ex_comp_ws(exoid), exoid);
      ex_err("ex_put_concat_sets", errmsg, exerrval);
      ex_safe_free(set_stat);
      return (EX_FATAL);
    }
  }
  ex_safe_free(set_stat);
  return(EX_NOERR);


  /* Fatal error: exit definition mode and return */
 error_ret:
  ex_safe_free(set_stat);

  if (nc_enddef (exoid) != NC_NOERR)     /* exit define mode */
    {
      sprintf(errmsg,
	      "Error: failed to complete definition for file id %d",
	      exoid);
      ex_err("ex_put_concat_sets",errmsg,exerrval);
    }
  return (EX_FATAL);
}
Exemple #23
0
int ex_put_map_param(int exoid, int num_node_maps, int num_elem_maps)
{
  int  dim[2], dimid, strdim, varid, status;
  int  var_nm_id, var_em_id;
  int  i;
  char errmsg[MAX_ERR_LENGTH];
  int  id_type  = NC_INT;
  int  int_type = NC_INT;
#if NC_HAS_HDF5
  int fill = NC_FILL_CHAR;
#endif

  EX_FUNC_ENTER();
  ex_check_valid_file_id(exoid, __func__);

  if (ex_int64_status(exoid) & EX_IDS_INT64_DB) {
    id_type = NC_INT64;
  }
  if (ex_int64_status(exoid) & EX_BULK_INT64_DB) {
    int_type = NC_INT64;
  }

  /* return if these have been defined before */
  if ((num_node_maps > 0 && ((nc_inq_dimid(exoid, DIM_NUM_NM, &dimid)) == NC_NOERR)) ||
      (num_elem_maps > 0 && ((nc_inq_dimid(exoid, DIM_NUM_EM, &dimid)) == NC_NOERR))) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: number of maps already defined for file id %d", exoid);
    ex_err(__func__, errmsg, EX_BADPARAM);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  if ((num_node_maps > 0) || (num_elem_maps > 0)) {

    /* inquire previously defined dimensions  */
    if ((status = nc_inq_dimid(exoid, DIM_STR_NAME, &strdim)) != NC_NOERR) {
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get string length in file id %d", exoid);
      ex_err(__func__, errmsg, status);
      EX_FUNC_LEAVE(EX_FATAL);
    }

    /* put file into define mode */
    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);
    }

    /* node maps: */
    if (num_node_maps > 0) {

      if ((status = nc_def_dim(exoid, DIM_NUM_NM, num_node_maps, &dimid)) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: failed to define number of node maps in file id %d", exoid);
        ex_err(__func__, errmsg, status);
        goto error_ret; /* exit define mode and return */
      }

      /* node maps id array: */
      dim[0] = dimid;
      if ((status = nc_def_var(exoid, VAR_NM_PROP(1), id_type, 1, dim, &var_nm_id)) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: failed to create node maps property array in file id %d", exoid);
        ex_err(__func__, errmsg, status);
        goto error_ret; /* exit define mode and return */
      }

      /*   store property name as attribute of property array variable */
      if ((status = nc_put_att_text(exoid, var_nm_id, ATT_PROP_NAME, 3, "ID")) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: failed to store node map property name %s in file id %d", "ID", exoid);
        ex_err(__func__, errmsg, status);
        goto error_ret; /* exit define mode and return */
      }

      /* Node map names... */
      dim[0] = dimid;
      dim[1] = strdim;

      if (nc_def_var(exoid, VAR_NAME_NM, NC_CHAR, 2, dim, &varid) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: failed to define node map name array in file id %d", exoid);
        ex_err(__func__, errmsg, status);
        goto error_ret; /* exit define mode and return */
      }
#if NC_HAS_HDF5
      nc_def_var_fill(exoid, varid, 0, &fill);
#endif

      /* determine number of nodes */
      if ((status = nc_inq_dimid(exoid, DIM_NUM_NODES, &dimid)) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: couldn't determine number of nodes in file id %d",
                 exoid);
        ex_err(__func__, errmsg, status);
        goto error_ret; /* exit define mode and return */
      }

      dim[0] = dimid;

      /* create variable array in which to store the node maps */
      for (i = 0; i < num_node_maps; i++) {
        if ((status = nc_def_var(exoid, VAR_NODE_MAP(i + 1), int_type, 1, dim, &varid)) !=
            NC_NOERR) {
          if (status == NC_ENAMEINUSE) {
            snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: node map %d already defined in file id %d", i,
                     exoid);
            ex_err(__func__, errmsg, status);
          }
          else {
            snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to create node map %d in file id %d", i,
                     exoid);
            ex_err(__func__, errmsg, status);
          }
          goto error_ret; /* exit define mode and return */
        }
        ex_compress_variable(exoid, varid, 1);
      }
    }

    /* element maps: */
    if (num_elem_maps > 0) {
      if ((status = nc_def_dim(exoid, DIM_NUM_EM, num_elem_maps, &dimid)) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: failed to define number of element maps in file id %d", exoid);
        ex_err(__func__, errmsg, status);
        goto error_ret; /* exit define mode and return */
      }

      /* element maps id array: */
      dim[0] = dimid;
      if ((status = nc_def_var(exoid, VAR_EM_PROP(1), id_type, 1, dim, &var_em_id)) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: failed to create element maps property array in file id %d", exoid);
        ex_err(__func__, errmsg, status);
        goto error_ret; /* exit define mode and return */
      }

      /*   store property name as attribute of property array variable */
      if ((status = nc_put_att_text(exoid, var_em_id, ATT_PROP_NAME, 3, "ID")) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: failed to store element map property name %s in file id %d", "ID", exoid);
        ex_err(__func__, errmsg, status);
        goto error_ret; /* exit define mode and return */
      }

      /* Element map names... */
      dim[0] = dimid;
      dim[1] = strdim;

      if ((status = nc_def_var(exoid, VAR_NAME_EM, NC_CHAR, 2, dim, &varid)) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: failed to define element map name array in file id %d", exoid);
        ex_err(__func__, errmsg, status);
        goto error_ret; /* exit define mode and return */
      }
#if NC_HAS_HDF5
      nc_def_var_fill(exoid, varid, 0, &fill);
#endif

      /* determine number of elements */
      if ((status = nc_inq_dimid(exoid, DIM_NUM_ELEM, &dimid)) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: couldn't determine number of elements in file id %d", exoid);
        ex_err(__func__, errmsg, status);
        goto error_ret; /* exit define mode and return */
      }

      /* create variable array in which to store the element maps */
      dim[0] = dimid;
      for (i = 0; i < num_elem_maps; i++) {
        if ((status = nc_def_var(exoid, VAR_ELEM_MAP(i + 1), int_type, 1, dim, &varid)) !=
            NC_NOERR) {
          if (status == NC_ENAMEINUSE) {
            snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: element map %d already defined in file id %d",
                     i, exoid);
            ex_err(__func__, errmsg, status);
          }
          else {
            snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to create element map %d in file id %d",
                     i, exoid);
            ex_err(__func__, errmsg, status);
          }
          goto error_ret; /* exit define mode and return */
        }
        ex_compress_variable(exoid, varid, 1);
      }
    }

    /* leave define mode */
    if ((status = nc_enddef(exoid)) != NC_NOERR) {
      snprintf(errmsg, MAX_ERR_LENGTH,
               "ERROR: failed to complete variable definitions in file id %d", exoid);
      ex_err(__func__, errmsg, status);
      EX_FUNC_LEAVE(EX_FATAL);
    }

    /* Fill the id arrays with EX_INVALID_ID */
    {
      int  maxset      = num_node_maps > num_elem_maps ? num_node_maps : num_elem_maps;
      int *invalid_ids = malloc(maxset * sizeof(int));
      if (invalid_ids == NULL) {
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: failed to allocate memory for invalid id "
                 "storage in file id %d",
                 exoid);
        ex_err(__func__, errmsg, EX_MEMFAIL);
        EX_FUNC_LEAVE(EX_FATAL);
      }
      for (i = 0; i < maxset; i++) {
        invalid_ids[i] = EX_INVALID_ID;
      }
      if (num_node_maps > 0) {
        status = nc_put_var_int(exoid, var_nm_id, invalid_ids);
        assert(status == NC_NOERR);
      }
      if (num_elem_maps > 0) {
        status = nc_put_var_int(exoid, var_em_id, invalid_ids);
        assert(status == NC_NOERR);
      }
      free(invalid_ids);
    }
  }

  EX_FUNC_LEAVE(EX_NOERR);

/* Fatal error: exit definition mode and return */
error_ret:
  if ((status = nc_enddef(exoid)) != NC_NOERR) /* exit define mode */
  {
    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);
}
int ex_put_attr_param (int   exoid,
		       ex_entity_type obj_type,
		       ex_entity_id   obj_id,
		       int   num_attrs)
{
  int status;
  int dims[2];
  int strdim, varid;
  
  char errmsg[MAX_ERR_LENGTH];
  const char *dnumobjent;
  const char *dnumobjatt;
  const char *vobjatt;
  const char *vattnam;
  int numobjentdim;
  int obj_id_ndx;
  int numattrdim;
  
  /* Determine index of obj_id in obj_type id array */
  if (obj_type == EX_NODAL) {
    obj_id_ndx = 0;
  } else {
    obj_id_ndx = ex_id_lkup(exoid,obj_type,obj_id);
    
    if (exerrval != 0) {
      if (exerrval == EX_NULLENTITY) {
	sprintf(errmsg,
		"Warning: no attributes found for NULL %s %"PRId64" in file id %d",
		ex_name_of_object(obj_type),obj_id,exoid);
	ex_err("ex_put_attr_param",errmsg,EX_NULLENTITY);
	return (EX_WARN);              /* no attributes for this object */
      } 
	sprintf(errmsg,
		"Warning: failed to locate %s id %"PRId64" in id array in file id %d",
		ex_name_of_object(obj_type),obj_id, exoid);
	ex_err("ex_put_attr_param",errmsg,exerrval);
	return (EX_WARN);
      
    }
  }

  switch (obj_type) {
  case EX_SIDE_SET:
    dnumobjent = DIM_NUM_SIDE_SS(obj_id_ndx);
    dnumobjatt = DIM_NUM_ATT_IN_SS(obj_id_ndx);
    vobjatt = VAR_SSATTRIB(obj_id_ndx);
    vattnam = VAR_NAME_SSATTRIB(obj_id_ndx);
    break;
  case EX_NODE_SET:
    dnumobjent = DIM_NUM_NOD_NS(obj_id_ndx);
    dnumobjatt = DIM_NUM_ATT_IN_NS(obj_id_ndx);
    vobjatt = VAR_NSATTRIB(obj_id_ndx);
    vattnam = VAR_NAME_NSATTRIB(obj_id_ndx);
    break;
  case EX_EDGE_SET:
    dnumobjent = DIM_NUM_EDGE_ES(obj_id_ndx);
    dnumobjatt = DIM_NUM_ATT_IN_ES(obj_id_ndx);
    vobjatt = VAR_ESATTRIB(obj_id_ndx);
    vattnam = VAR_NAME_ESATTRIB(obj_id_ndx);
    break;
  case EX_FACE_SET:
    dnumobjent = DIM_NUM_FACE_FS(obj_id_ndx);
    dnumobjatt = DIM_NUM_ATT_IN_FS(obj_id_ndx);
    vobjatt = VAR_FSATTRIB(obj_id_ndx);
    vattnam = VAR_NAME_FSATTRIB(obj_id_ndx);
    break;
  case EX_ELEM_SET:
    dnumobjent = DIM_NUM_ELE_ELS(obj_id_ndx);
    dnumobjatt = DIM_NUM_ATT_IN_ELS(obj_id_ndx);
    vobjatt = VAR_ELSATTRIB(obj_id_ndx);
    vattnam = VAR_NAME_ELSATTRIB(obj_id_ndx);
    break;
  case EX_NODAL:
    dnumobjent = DIM_NUM_NODES;
    dnumobjatt = DIM_NUM_ATT_IN_NBLK;
    vobjatt = VAR_NATTRIB;
    vattnam = VAR_NAME_NATTRIB;
    break;
  case EX_EDGE_BLOCK:
    dnumobjent = DIM_NUM_ED_IN_EBLK(obj_id_ndx);
    dnumobjatt = DIM_NUM_ATT_IN_EBLK(obj_id_ndx);
    vobjatt = VAR_EATTRIB(obj_id_ndx);
    vattnam = VAR_NAME_EATTRIB(obj_id_ndx);
    break;
  case EX_FACE_BLOCK:
    dnumobjent = DIM_NUM_FA_IN_FBLK(obj_id_ndx);
    dnumobjatt = DIM_NUM_ATT_IN_FBLK(obj_id_ndx);
    vobjatt = VAR_FATTRIB(obj_id_ndx);
    vattnam = VAR_NAME_FATTRIB(obj_id_ndx);
    break;
  case EX_ELEM_BLOCK:
    dnumobjent = DIM_NUM_EL_IN_BLK(obj_id_ndx);
    dnumobjatt = DIM_NUM_ATT_IN_BLK(obj_id_ndx);
    vobjatt = VAR_ATTRIB(obj_id_ndx);
    vattnam = VAR_NAME_ATTRIB(obj_id_ndx);
    break;
  default:
    exerrval = EX_BADPARAM;
    sprintf(errmsg, "Error: Bad block type (%d) specified for file id %d",
	    obj_type, exoid );
    ex_err("ex_put_attr_param",errmsg,exerrval);
    return (EX_FATAL);
  }

  exerrval = 0; /* clear error code */

  if ((status = nc_inq_dimid(exoid, dnumobjent, &numobjentdim)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to locate number of entries for %s %"PRId64" in file id %d",
	    ex_name_of_object(obj_type), obj_id, exoid);
    ex_err("ex_put_attr_param",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* put netcdf file into define mode  */
  if ((status = nc_redef (exoid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,"Error: failed to place file id %d into define mode",exoid);
    ex_err("ex_put_attr_param",errmsg,exerrval);
    return (EX_FATAL);
  }
  
  if ((status = nc_def_dim(exoid, dnumobjatt, num_attrs, &numattrdim)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to define number of attributes in %s %"PRId64" in file id %d",
	    ex_name_of_object(obj_type), obj_id,exoid);
    ex_err("ex_put_attr_param",errmsg,exerrval);
    goto error_ret;         /* exit define mode and return */
  }

  dims[0] = numobjentdim;
  dims[1] = numattrdim;
  
  if ((status = nc_def_var(exoid, vobjatt, nc_flt_code(exoid), 2, dims, &varid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error:  failed to define attributes for %s %"PRId64" in file id %d",
	    ex_name_of_object(obj_type), obj_id,exoid);
    ex_err("ex_put_attr_param",errmsg,exerrval);
    goto error_ret;         /* exit define mode and return */
  }
  ex_compress_variable(exoid, varid, 2);
  
  /* inquire previously defined dimensions  */
  if ((status = nc_inq_dimid(exoid, DIM_STR_NAME, &strdim)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to get string length in file id %d",exoid);
    ex_err("ex_put_attr_param",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* Attribute names... */
  dims[0] = numattrdim;
  dims[1] = strdim;

  if ((status = nc_def_var(exoid, vattnam, NC_CHAR, 2, dims, &varid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to define %s attribute name array in file id %d",
	    ex_name_of_object(obj_type), exoid);
    ex_err("ex_put_attr_param",errmsg,exerrval);
    goto error_ret;         /* exit define mode and return */
  }

  /* leave define mode  */
  if ((status = nc_enddef(exoid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to complete %s attribute parameter definition in file id %d",
	    ex_name_of_object(obj_type), exoid);
    ex_err("ex_put_attr_param",errmsg,exerrval);
    return (EX_FATAL);
  }

  return (EX_NOERR);

  /* Fatal error: exit definition mode and return */
 error_ret:
  if (nc_enddef (exoid) != NC_NOERR) {     /* exit define mode */       
    sprintf(errmsg,
	    "Error: failed to complete definition for file id %d",
	    exoid);
    ex_err("ex_put_attr_param",errmsg,exerrval);
  }
  return (EX_FATAL);
}