Exemple #1
0
int ex_put_set_param (int exoid,
                      ex_entity_type set_type,
                      int set_id,
                      int num_entries_in_set,
                      int num_dist_fact_in_set)
{
  int status;
  size_t temp;
  int dimid, varid, set_id_ndx, dims[1]; 
  size_t start[1]; 
  int num_sets;
  int ldum;
  int cur_num_sets, set_stat;
  char *cdum;
  char errmsg[MAX_ERR_LENGTH];
  char* dimptr;
  char* idsptr;
  char* statptr;
  char* numentryptr = NULL;
  char* numdfptr = NULL;
  char* factptr = NULL;
  char* entryptr = NULL;
  char* extraptr = NULL;

  exerrval = 0; /* clear error code */

  cdum = 0;

  /* setup pointers based on set_type 
     NOTE: there is another block that sets more stuff later ... */
  if (set_type == EX_NODE_SET) {
    dimptr = DIM_NUM_NS;
    idsptr = VAR_NS_IDS;
    statptr = VAR_NS_STAT;
  }
  else if (set_type == EX_EDGE_SET) {
    dimptr = DIM_NUM_ES;
    idsptr = VAR_ES_IDS;
    statptr = VAR_ES_STAT;
  }
  else if (set_type == EX_FACE_SET) {
    dimptr = DIM_NUM_FS;
    idsptr = VAR_FS_IDS;
    statptr = VAR_FS_STAT;
  }
  else if (set_type == EX_SIDE_SET) {
    dimptr = DIM_NUM_SS;
    idsptr = VAR_SS_IDS;
    statptr = VAR_SS_STAT;
  }
  else if (set_type == EX_ELEM_SET) {
    dimptr = DIM_NUM_ELS;
    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 of that set type is specified */

  if ((status = nc_inq_dimid(exoid, dimptr, &dimid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: no %ss specified in file id %d", ex_name_of_object(set_type),
	    exoid);
    ex_err("ex_put_set_param",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* Check for duplicate set id entry */
  ex_id_lkup(exoid, set_type, set_id);
  if (exerrval != EX_LOOKUPFAIL) {  /* found the side set id */
    sprintf(errmsg,
	    "Error: %s %d already defined in file id %d", ex_name_of_object(set_type),
	    set_id,exoid);
    ex_err("ex_put_set_param",errmsg,exerrval);
    return(EX_FATAL);
  }

  /* Get number of sets specified for this file */
  if ((status = nc_inq_dimlen(exoid,dimid,&temp)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
            "Error: failed to get number of %ss in file id %d",
	    ex_name_of_object(set_type), exoid);
    ex_err("ex_put_set_param",errmsg,exerrval);
    return (EX_FATAL);
  }
  num_sets = temp;


  /* 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 finds the maximum number of sets defined
     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_set_param",errmsg,exerrval);
    return (EX_FATAL);
  }

  /*   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(set_type));
  set_id_ndx = cur_num_sets + 1;

  /* setup more pointers based on set_type */
  if (set_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 (set_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 (set_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 (set_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);
  }
  if (set_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);
  }

  /* write out information to previously defined variable */

  /* 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 %d in file id %d", ex_name_of_object(set_type),
	    set_id, exoid);
    ex_err("ex_put_set_param",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* write out set id */
  start[0] = cur_num_sets;

  ldum = (int)set_id;
  if ((status = nc_put_var1_int(exoid, varid, start, &ldum)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to store %s id %d in file id %d", ex_name_of_object(set_type),
	    set_id, exoid);
    ex_err("ex_put_set_param",errmsg,exerrval);
    return (EX_FATAL);
  }

  if (num_entries_in_set == 0) /* Is this a NULL  set? */
    set_stat = 0; /* change set status to NULL */
  else
    set_stat = 1; /* change set status to TRUE */

  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_set_param",errmsg,exerrval);
    return (EX_FATAL);
  }

  ldum = (int)set_stat;
  if ((status = nc_put_var1_int(exoid, varid, start, &ldum)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to store %s %d status to file id %d", ex_name_of_object(set_type),
	    set_id, exoid);
    ex_err("ex_put_set_param",errmsg,exerrval);
    return (EX_FATAL);
  }

  if (num_entries_in_set == 0) {/* Is this a NULL set? */
    return(EX_NOERR);
  }

  /* 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_set_param",errmsg,exerrval);
    return (EX_FATAL);
  }


  /* define dimensions and variables */
  if ((status = nc_def_dim(exoid, numentryptr,
			   num_entries_in_set, &dimid)) != NC_NOERR) {
    exerrval = status;
    if (status == NC_ENAMEINUSE)
      {
	sprintf(errmsg,
		"Error: %s %d size already defined in file id %d",
		ex_name_of_object(set_type), set_id,exoid);
	ex_err("ex_put_set_param",errmsg,exerrval);
      }
    else {
      sprintf(errmsg,
	      "Error: failed to define number of entries in %s %d in file id %d",
	      ex_name_of_object(set_type), set_id,exoid);
      ex_err("ex_put_set_param",errmsg,exerrval);
    }
    goto error_ret;
  }

  /* create variable array in which to store the entry lists */

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

  if (extraptr) {
    if ((status = nc_def_var(exoid, extraptr, NC_INT, 1, dims, &varid)) != NC_NOERR) {
      exerrval = status;
      if (status == NC_ENAMEINUSE) {
	sprintf(errmsg,
		"Error: extra list already exists for %s %d in file id %d",
		ex_name_of_object(set_type), set_id, exoid);
	ex_err("ex_put_set_param",errmsg,exerrval);
      } else {
	sprintf(errmsg,
		"Error: failed to create extra list for %s %d in file id %d",
		ex_name_of_object(set_type), set_id,exoid);
	ex_err("ex_put_set_param",errmsg,exerrval);
      }
      goto error_ret;         /* exit define mode and return */
           
    }
  }

  /* Create distribution factors variable if required */

  if (num_dist_fact_in_set > 0) {

    if (set_type == EX_NODE_SET) {
      /* but num_dist_fact_in_set must equal number of nodes */
      if (num_dist_fact_in_set != num_entries_in_set) {
	exerrval = EX_FATAL;
	sprintf(errmsg,
		"Error: # dist fact (%d) not equal to # nodes (%d) in node  set %d file id %d",
		num_dist_fact_in_set, num_entries_in_set, set_id, exoid);
	ex_err("ex_put_set_param",errmsg,exerrval);
	goto error_ret;    /* exit define mode and return */
      }

      /* resuse dimid from entry lists */

    } else {
      if ((status = nc_def_dim(exoid, numdfptr, 
			       num_dist_fact_in_set, &dimid)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to define number of dist factors in %s %d in file id %d",
		ex_name_of_object(set_type), set_id,exoid);
	ex_err("ex_put_set_param",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 %d in file id %d",
		ex_name_of_object(set_type), set_id,exoid);
	ex_err("ex_put_set_param",errmsg,exerrval);
      } else {
	sprintf(errmsg,
		"Error: failed to create dist factors list for %s %d in file id %d",
		ex_name_of_object(set_type), set_id,exoid);
	ex_err("ex_put_set_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 definition in file id %d", exoid);
    ex_err("ex_put_set_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_set_param",errmsg,exerrval);
  }
  return (EX_FATAL);
}
Exemple #2
0
/*!

The function ex_close() updates and then closes an open exodus file.

\return In case of an error, ex_close() returns a negative number; a
        warning will return a positive number. Possible causes of errors
	include:
 - data file not properly opened with call to ex_create() or ex_open()

 \param exoid      exodus file ID returned from a previous call to ex_create() or ex_open().

The following code segment closes an open exodus file:

\code
int error,exoid;
error = ex_close (exoid);
\endcode

 */
int ex_close (int exoid)
{
   char errmsg[MAX_ERR_LENGTH];
   int status;
   int parent_id = 0;

   exerrval = 0; /* clear error code */
   /*
    * NOTE: If using netcdf-4, exoid must refer to the root group.
    * Need to determine whether there are any groups and if so,
    * call ex_rm_file_item and ex_rm_stat_ptr on each group.
    */

#if defined(ENABLE_NETCDF4)
   /* nc_inq_grp_parent() will return NC_ENOGRP error if exoid
    * refers to the root group (which is what we want)
    */
   if ((status = nc_inq_grp_parent(exoid, &parent_id)) != NC_ENOGRP) {
     exerrval = EX_NOTROOTID;
     sprintf(errmsg,"Error: file id %d does not refer to root group.",exoid);
     ex_err("ex_close",errmsg,exerrval);
     return(EX_FATAL);
   }
#endif
   
   if ((status = nc_sync(exoid)) != NC_NOERR) {
     exerrval = status;
     sprintf(errmsg,"Error: failed to update file id %d",exoid);
     ex_err("ex_close",errmsg,exerrval);
     return(EX_FATAL);
   }
   if ((status = nc_close (exoid)) == NC_NOERR) {
     ex_conv_exit(exoid);

     ex_rm_file_item(exoid, ex_get_counter_list(EX_ELEM_BLOCK));
     ex_rm_file_item(exoid, ex_get_counter_list(EX_FACE_BLOCK));
     ex_rm_file_item(exoid, ex_get_counter_list(EX_EDGE_BLOCK));
     ex_rm_file_item(exoid, ex_get_counter_list(EX_NODE_SET));
     ex_rm_file_item(exoid, ex_get_counter_list(EX_EDGE_SET));
     ex_rm_file_item(exoid, ex_get_counter_list(EX_FACE_SET));
     ex_rm_file_item(exoid, ex_get_counter_list(EX_SIDE_SET));
     ex_rm_file_item(exoid, ex_get_counter_list(EX_ELEM_SET));
     ex_rm_file_item(exoid, ex_get_counter_list(EX_NODE_MAP));
     ex_rm_file_item(exoid, ex_get_counter_list(EX_EDGE_MAP));
     ex_rm_file_item(exoid, ex_get_counter_list(EX_FACE_MAP));
     ex_rm_file_item(exoid, ex_get_counter_list(EX_ELEM_MAP));

     ex_rm_stat_ptr (exoid, &exoII_ed);
     ex_rm_stat_ptr (exoid, &exoII_fa);
     ex_rm_stat_ptr (exoid, &exoII_eb);
     ex_rm_stat_ptr (exoid, &exoII_ns);
     ex_rm_stat_ptr (exoid, &exoII_es);
     ex_rm_stat_ptr (exoid, &exoII_fs);
     ex_rm_stat_ptr (exoid, &exoII_ss);
     ex_rm_stat_ptr (exoid, &exoII_els);
     ex_rm_stat_ptr (exoid, &exoII_nm);
     ex_rm_stat_ptr (exoid, &exoII_edm);
     ex_rm_stat_ptr (exoid, &exoII_fam);
     ex_rm_stat_ptr (exoid, &exoII_em);
   }
   else {
     exerrval = status;
     sprintf(errmsg, "Error: failed to close file id %d",exoid);
     ex_err("ex_close",errmsg, status);
     return(EX_FATAL);
   }
   return(EX_NOERR);
}
Exemple #3
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);
}
Exemple #4
0
int ex_copy (int in_exoid, int out_exoid)
{
   int status;
   int ndims;                   /* number of dimensions */
   int nvars;                   /* number of variables */
   int ngatts;                  /* number of global attributes */
   int recdimid;                /* id of unlimited dimension */
   int dimid;                   /* dimension id */
   int dim_out_id;              /* dimension id */
   int varid;                   /* variable id */
   int var_out_id;              /* variable id */
   struct ncvar var;            /* variable */
   struct ncatt att;            /* attribute */
   nc_type att_type = NC_NAT;
   size_t att_len = 0;
   size_t i;
   size_t numrec;
   size_t dim_sz;
   char dim_nm[NC_MAX_NAME];
   int in_large, out_large;
   char errmsg[MAX_ERR_LENGTH];

   exerrval = 0; /* clear error code */

   /*
    * Get exodus_large_model setting on both input and output
    * databases so know how to handle coordinates.
    */
   in_large  = ex_large_model(in_exoid);
   out_large = ex_large_model(out_exoid);
   
   /*
    * get number of dimensions, number of variables, number of global
    * atts, and dimension id of unlimited dimension, if any
    */

   (void)nc_inq(in_exoid, &ndims, &nvars, &ngatts, &recdimid);
   (void)nc_inq_dimlen(in_exoid, recdimid, &numrec);

   /* put output file into define mode */
   (void)nc_redef(out_exoid);

   /* copy global attributes */
   for (i = 0; i < (size_t)ngatts; i++) {

     (void)nc_inq_attname(in_exoid, NC_GLOBAL, i, att.name);
        
     /* if attribute exists in output file, don't overwrite it; compute 
      * word size, I/O word size etc. are global attributes stored when
      * file is created with ex_create;  we don't want to overwrite those
      */
     if ((status = nc_inq_att(out_exoid, NC_GLOBAL, att.name, &att.type, &att.len)) != NC_NOERR) {

        /* The "last_written_time" attribute is a special attribute
           used by the Sierra IO system to determine whether a
           timestep has been fully written to the database in order to
           try to detect a database crash that happens in the middle
           of a database output step. Don't want to copy that attribute.
        */
        if (strcmp(att.name,"last_written_time") != 0) {
          /* attribute doesn't exist in new file so OK to create it */
          nc_copy_att(in_exoid,NC_GLOBAL,att.name,out_exoid,NC_GLOBAL);
        }
      }
   }

   /* copy dimensions */

   /* Get the dimension sizes and names */

   for(dimid = 0; dimid < ndims; dimid++){

     (void)nc_inq_dim(in_exoid,dimid,dim_nm,&dim_sz);

     /* If the dimension isn't one we specifically don't want 
      * to copy (ie, number of QA or INFO records) and it 
      * hasn't been defined, copy it */
     
     if ( ( strcmp(dim_nm,DIM_NUM_QA)        != 0) &&
	  ( strcmp(dim_nm,DIM_NUM_INFO)      != 0) &&
	  ( strcmp(dim_nm,DIM_NUM_NOD_VAR)   != 0) &&
	  ( strcmp(dim_nm,DIM_NUM_EDG_VAR)   != 0) &&
	  ( strcmp(dim_nm,DIM_NUM_FAC_VAR)   != 0) &&
	  ( strcmp(dim_nm,DIM_NUM_ELE_VAR)   != 0) &&
	  ( strcmp(dim_nm,DIM_NUM_NSET_VAR)  != 0) &&
	  ( strcmp(dim_nm,DIM_NUM_ESET_VAR)  != 0) &&
	  ( strcmp(dim_nm,DIM_NUM_FSET_VAR)  != 0) &&
	  ( strcmp(dim_nm,DIM_NUM_SSET_VAR)  != 0) &&
	  ( strcmp(dim_nm,DIM_NUM_ELSET_VAR) != 0) &&
	  ( strcmp(dim_nm,DIM_NUM_GLO_VAR)   != 0) ) {
       
       /* See if the dimension has already been defined */
       status = nc_inq_dimid(out_exoid, dim_nm, &dim_out_id);
       
       if(status != NC_NOERR) {
	 if(dimid != recdimid) {
	   status = nc_def_dim(out_exoid, dim_nm, dim_sz,       &dim_out_id);
	 } else {
	   status = nc_def_dim(out_exoid, dim_nm, NC_UNLIMITED, &dim_out_id);
	 } /* end else */
	 if (status != NC_NOERR) {
	   exerrval = status;
	   sprintf(errmsg,
		   "Error: failed to define %s dimension in file id %d",
		   dim_nm, out_exoid);
	   ex_err("ex_copy",errmsg,exerrval);
	   return (EX_FATAL);
	 }
       } /* end if */
     } /* end if */
   } /* end loop over dim */

   /* DIM_STR_NAME is a newly added dimension required by current API.
    * If it doesn't exist on the source database, we need to add it to
    * the target...
    */
   status = nc_inq_dimid(in_exoid, DIM_STR_NAME, &dim_out_id);
   if (status != NC_NOERR) {
     /* Not found; set to default value of 32+1. */
     if ((status = nc_def_dim(out_exoid, DIM_STR_NAME, 33, &dim_out_id)) != NC_NOERR) {
       exerrval = status;
       sprintf(errmsg,
	       "Error: failed to define string name dimension in file id %d",
	       out_exoid);
       ex_err("ex_copy",errmsg,exerrval);
       return (EX_FATAL);
     }
   }

   status = nc_inq_att(in_exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, &att_type, &att_len);
   if (status != NC_NOERR) {
      int max_so_far = 32;
      nc_put_att_int(out_exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, NC_INT, 1, &max_so_far);
    }

   /* copy variable definitions and variable attributes */
   for (varid = 0; varid < nvars; varid++) {

     (void)nc_inq_var(in_exoid, varid, var.name, &var.type, &var.ndims, 
		 var.dims, &var.natts);

      /* we don't want to copy some variables because there is not a
       * simple way to add to them;
       * QA records, info records and all results variables (nodal
       * element, and global results) are examples
       */

      if ( ( strcmp(var.name,VAR_QA_TITLE)      != 0) &&
           ( strcmp(var.name,VAR_INFO)          != 0) &&
           ( strcmp(var.name,VAR_EBLK_TAB)      != 0) &&
           ( strcmp(var.name,VAR_FBLK_TAB)      != 0) &&
           ( strcmp(var.name,VAR_ELEM_TAB)      != 0) &&
           ( strcmp(var.name,VAR_ELSET_TAB)     != 0) &&
           ( strcmp(var.name,VAR_SSET_TAB)      != 0) &&
           ( strcmp(var.name,VAR_FSET_TAB)      != 0) &&
           ( strcmp(var.name,VAR_ESET_TAB)      != 0) &&
           ( strcmp(var.name,VAR_NSET_TAB)      != 0) &&
           ( strcmp(var.name,VAR_NAME_GLO_VAR)  != 0) &&
           ( strcmp(var.name,VAR_GLO_VAR)       != 0) &&
           ( strcmp(var.name,VAR_NAME_NOD_VAR)  != 0) &&
           ( strcmp(var.name,VAR_NOD_VAR)       != 0) &&
           ( strcmp(var.name,VAR_NAME_EDG_VAR)  != 0) &&
           ( strcmp(var.name,VAR_NAME_FAC_VAR)  != 0) &&
           ( strcmp(var.name,VAR_NAME_ELE_VAR)  != 0) &&
           ( strcmp(var.name,VAR_NAME_NSET_VAR) != 0) &&
           ( strcmp(var.name,VAR_NAME_ESET_VAR) != 0) &&
           ( strcmp(var.name,VAR_NAME_FSET_VAR) != 0) &&
           ( strcmp(var.name,VAR_NAME_SSET_VAR) != 0) &&
           ( strcmp(var.name,VAR_NAME_ELSET_VAR) != 0)&&
           ( strncmp(var.name,"vals_elset_var", 14) != 0) &&
           ( strncmp(var.name,"vals_sset_var",  13) != 0) &&
           ( strncmp(var.name,"vals_fset_var",  13) != 0) &&
           ( strncmp(var.name,"vals_eset_var",  13) != 0) &&
           ( strncmp(var.name,"vals_nset_var",  13) != 0) &&
           ( strncmp(var.name,"vals_nod_var",   12) != 0) &&
           ( strncmp(var.name,"vals_edge_var",  13) != 0) &&
           ( strncmp(var.name,"vals_face_var",  13) != 0) &&
           ( strncmp(var.name,"vals_elem_var",  13) != 0) ) {

        if (strncmp(var.name,VAR_COORD,5) == 0) {
          var_out_id = cpy_coord_def (in_exoid, out_exoid, recdimid, var.name,
                                      in_large, out_large);
        } else {
          var_out_id = cpy_var_def (in_exoid, out_exoid, recdimid, var.name);
        }

         /* copy the variable's attributes */
         (void) cpy_att (in_exoid, out_exoid, varid, var_out_id);

      }
   }

   /* take the output file out of define mode */
   if ((exerrval=nc_enddef (out_exoid)) != NC_NOERR) {
     sprintf(errmsg,
	     "Error: failed to complete definition in file id %d", 
	     out_exoid);
     ex_err("ex_copy",errmsg,exerrval);
     return (EX_FATAL);
   }

   /* output variable data */

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

      /* we don't want to copy some variable values;
       * QA records and info records shouldn't be copied because there
       * isn't an easy way to add to them;
       * the time value array ("time_whole") and any results variables
       * (nodal, elemental, or global) shouldn't be copied 
       */

      if ( ( strcmp(var.name,VAR_QA_TITLE) != 0)        &&
           ( strcmp(var.name,VAR_INFO) != 0)            &&
           ( strcmp(var.name,VAR_EBLK_TAB) != 0)        &&
           ( strcmp(var.name,VAR_FBLK_TAB) != 0)        &&
           ( strcmp(var.name,VAR_ELEM_TAB) != 0)        &&
           ( strcmp(var.name,VAR_ELSET_TAB) != 0)       &&
           ( strcmp(var.name,VAR_SSET_TAB) != 0)        &&
           ( strcmp(var.name,VAR_FSET_TAB) != 0)        &&
           ( strcmp(var.name,VAR_ESET_TAB) != 0)        &&
           ( strcmp(var.name,VAR_NSET_TAB) != 0)        &&
           ( strcmp(var.name,VAR_NAME_GLO_VAR) != 0)    &&
           ( strcmp(var.name,VAR_GLO_VAR) != 0)         &&
           ( strcmp(var.name,VAR_NAME_NOD_VAR) != 0)    &&
           ( strcmp(var.name,VAR_NOD_VAR) != 0)         &&
           ( strcmp(var.name,VAR_NAME_EDG_VAR) != 0)    &&
           ( strcmp(var.name,VAR_NAME_FAC_VAR) != 0)    &&
           ( strcmp(var.name,VAR_NAME_ELE_VAR) != 0)    &&
           ( strcmp(var.name,VAR_NAME_NSET_VAR) != 0)   &&
           ( strcmp(var.name,VAR_NAME_ESET_VAR) != 0)   &&
           ( strcmp(var.name,VAR_NAME_FSET_VAR) != 0)   &&
           ( strcmp(var.name,VAR_NAME_SSET_VAR) != 0)   &&
           ( strcmp(var.name,VAR_NAME_ELSET_VAR) != 0)  &&
           ( strncmp(var.name,"vals_elset_var", 14) != 0)&&
           ( strncmp(var.name,"vals_sset_var", 13) != 0)&&
           ( strncmp(var.name,"vals_fset_var", 13) != 0)&&
           ( strncmp(var.name,"vals_eset_var", 13) != 0)&&
           ( strncmp(var.name,"vals_nset_var", 13) != 0)&&
           ( strncmp(var.name,"vals_nod_var", 12) != 0) &&
           ( strncmp(var.name,"vals_edge_var",13) != 0) &&
           ( strncmp(var.name,"vals_face_var",13) != 0) &&
           ( strncmp(var.name,"vals_elem_var",13) != 0) &&
           ( strcmp(var.name,VAR_WHOLE_TIME) != 0) ) {

        if (strncmp(var.name,VAR_COORD,5) == 0) {
          (void) cpy_coord_val (in_exoid, out_exoid, var.name,
                                in_large, out_large);
        } else {
          (void) cpy_var_val (in_exoid, out_exoid, var.name);
        }

      }
   }

   /* ensure internal data structures are updated */

   /* if number of blocks > 0 */
   update_internal_structs( out_exoid, EX_INQ_EDGE_BLK, ex_get_counter_list(EX_EDGE_BLOCK));
   update_internal_structs( out_exoid, EX_INQ_FACE_BLK, ex_get_counter_list(EX_FACE_BLOCK));
   update_internal_structs( out_exoid, EX_INQ_ELEM_BLK, ex_get_counter_list(EX_ELEM_BLOCK));

   /* if number of sets > 0 */
   update_internal_structs( out_exoid, EX_INQ_NODE_SETS, ex_get_counter_list(EX_NODE_SET));
   update_internal_structs( out_exoid, EX_INQ_EDGE_SETS, ex_get_counter_list(EX_EDGE_SET));
   update_internal_structs( out_exoid, EX_INQ_FACE_SETS, ex_get_counter_list(EX_FACE_SET));
   update_internal_structs( out_exoid, EX_INQ_SIDE_SETS, ex_get_counter_list(EX_SIDE_SET));
   update_internal_structs( out_exoid, EX_INQ_ELEM_SETS, ex_get_counter_list(EX_ELEM_SET));

   /* if number of maps > 0 */
   update_internal_structs( out_exoid, EX_INQ_NODE_MAP, ex_get_counter_list(EX_NODE_MAP));
   update_internal_structs( out_exoid, EX_INQ_EDGE_MAP, ex_get_counter_list(EX_EDGE_MAP));
   update_internal_structs( out_exoid, EX_INQ_FACE_MAP, ex_get_counter_list(EX_FACE_MAP));
   update_internal_structs( out_exoid, EX_INQ_ELEM_MAP, ex_get_counter_list(EX_ELEM_MAP));

   return(EX_NOERR);
}
Exemple #5
0
int ex_put_num_map ( int exoid,
                     ex_entity_type map_type,
                     int map_id,
                     const int *map )
{
   int dimid, varid;
   size_t start[1]; 
   int ldum;
   int num_maps;
   size_t num_entries;
   int cur_num_maps;
   char errmsg[MAX_ERR_LENGTH];
   const char* dnumentries;
   const char* dnummaps;
   const char* vmapids;
   const char* vmap;
   int status;
   
   exerrval = 0; /* clear error code */

   switch ( map_type ) {
   case EX_NODE_MAP:
     dnumentries = DIM_NUM_NODES;
     dnummaps = DIM_NUM_NM;
     vmapids = VAR_NM_PROP(1);
     break;
   case EX_EDGE_MAP:
     dnumentries = DIM_NUM_EDGE;
     dnummaps = DIM_NUM_EDM;
     vmapids = VAR_EDM_PROP(1);
     break;
   case EX_FACE_MAP:
     dnumentries = DIM_NUM_FACE;
     dnummaps = DIM_NUM_FAM;
     vmapids = VAR_FAM_PROP(1);
     break;
   case EX_ELEM_MAP:
     dnumentries = DIM_NUM_ELEM;
     dnummaps = DIM_NUM_EM;
     vmapids = VAR_EM_PROP(1);
     break;
   default:
     exerrval = EX_BADPARAM;
     sprintf( errmsg,
       "Error: Bad map type (%d) specified for file id %d",
       map_type, exoid );
     ex_err( "ex_put_num_map", errmsg, exerrval );
     return (EX_FATAL);
   }

   /* Make sure the file contains entries */
   if (nc_inq_dimid (exoid, dnumentries, &dimid) != NC_NOERR )
   {
     return (EX_NOERR);
   }

   /* first check if any maps are specified */
   if ((status = nc_inq_dimid (exoid, dnummaps, &dimid)) != NC_NOERR )
   {
     exerrval = status;
     sprintf(errmsg,
            "Error: no %ss specified in file id %d",
             ex_name_of_object(map_type),exoid);
     ex_err("ex_put_num_map",errmsg,exerrval);
     return (EX_FATAL);
   }

   /* Check for duplicate map id entry */
   ex_id_lkup(exoid,map_type,map_id); 
   if (exerrval != EX_LOOKUPFAIL)   /* found the map id */
   {
     sprintf(errmsg,
            "Error: %s %d already defined in file id %d",
             ex_name_of_object(map_type),map_id,exoid);
     ex_err("ex_put_num_map",errmsg,exerrval);
     return(EX_FATAL);
   }

   /* Get number of maps initialized for this file */
   if ((status = nc_inq_dimlen(exoid,dimid,&num_entries)) != NC_NOERR)
   {
     exerrval = status;
     sprintf(errmsg,
            "Error: failed to get number of %ss in file id %d",
             ex_name_of_object(map_type),exoid);
     ex_err("ex_put_num_map",errmsg,exerrval);
     return (EX_FATAL);
   }
   num_maps = num_entries;

   /* Keep track of the total number of maps defined using a counter stored
      in a linked list keyed by exoid.
      NOTE: ex_get_file_item  is used to find the number of maps
      for a specific file and returns that value.
   */
   cur_num_maps = ex_get_file_item(exoid, ex_get_counter_list(map_type));
   if (cur_num_maps >= num_maps) {
     exerrval = EX_FATAL;
     sprintf(errmsg,
          "Error: exceeded number of %ss (%d) specified in file id %d",
             ex_name_of_object(map_type),num_maps,exoid);
     ex_err("ex_put_num_map",errmsg,exerrval);
     return (EX_FATAL);
   }

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

   /* write out information to previously defined variable */

   /* first get id of variable */
   if ((status = nc_inq_varid (exoid, vmapids, &varid)) == -1)
   {
     exerrval = status;
     sprintf(errmsg,
            "Error: failed to locate %s ids in file id %d",
             ex_name_of_object(map_type),exoid);
     ex_err("ex_put_num_map",errmsg,exerrval);
     return (EX_FATAL);
   }

   /* then, write out map id */
   start[0] = cur_num_maps;

   ldum = (int)map_id;
   if ((status = nc_put_var1_int(exoid, varid, start, &ldum)) != NC_NOERR)
   {
     exerrval = status;
     sprintf(errmsg,
            "Error: failed to store %s id %d in file id %d",
             ex_name_of_object(map_type),map_id,exoid);
     ex_err("ex_put_num_map",errmsg,exerrval);
     return (EX_FATAL);
   }

   switch ( map_type ) {
   case EX_NODE_MAP:
     vmap = VAR_NODE_MAP(cur_num_maps+1);
     break;
   case EX_EDGE_MAP:
     vmap = VAR_EDGE_MAP(cur_num_maps+1);
     break;
   case EX_FACE_MAP:
     vmap = VAR_FACE_MAP(cur_num_maps+1);
     break;
   case EX_ELEM_MAP:
     vmap = VAR_ELEM_MAP(cur_num_maps+1);
     break;
  default:
    exerrval = 1005;
    sprintf(errmsg,
	    "Internal Error: unrecognized map type in switch: %d in file id %d",
	    map_type,exoid);
    ex_err("ex_putt_n_one_attr",errmsg,EX_MSG);
    return (EX_FATAL);
   }

   /* locate variable array in which to store the map */
   if ((status = nc_inq_varid(exoid,vmap,&varid)) != NC_NOERR)
     {
       int dims[2];

       /* determine number of entries */
       if ((status = nc_inq_dimid (exoid, dnumentries, &dimid)) == -1 )
	 {
	   exerrval = status;
	   sprintf(errmsg,
		   "Error: couldn't determine number of %s entries in file id %d",
		   ex_name_of_object(map_type),exoid);
	   ex_err("ex_put_num_map",errmsg,exerrval);
	   return (EX_FATAL);
	 }
       
       status = 0;
       
       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_num_map",errmsg,exerrval);
         return (EX_FATAL);
       }

       dims[0] = dimid;
       if ((status = nc_def_var( exoid, vmap, NC_INT, 1, dims, &varid )) == -1 ) {
         exerrval = status;
         sprintf(errmsg, "Error: failed to define map %s in file id %d", vmap, exoid);
         ex_err("ex_put_num_map",errmsg,exerrval);
       }

       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_num_map", errmsg, exerrval );
         varid = -1; /* force early exit */
       }

       if ( varid == -1 ) /* we couldn't define variable and have prepared error message. */
         return (EX_FATAL);
     }

   /* write out the map  */
   if ((status = nc_put_var_int(exoid, varid, map)) != NC_NOERR)
   {
     exerrval = status;
     sprintf(errmsg,
            "Error: failed to store %s in file id %d",
             ex_name_of_object(map_type),exoid);
     ex_err("ex_put_num_map",errmsg,exerrval);
     return (EX_FATAL);
   }

   return (EX_NOERR);
}
Exemple #6
0
/*!
 * 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                number of attributes
 * \param    define_maps             if != 0, write maps, else don't
 */
int ex_put_concat_elem_block (int    exoid,
                              const int*   elem_blk_id,
                              char *elem_type[],
                              const int*   num_elem_this_blk,
                              const int*   num_nodes_per_elem,
                              const int*   num_attr,
                              int    define_maps)
{
  int i, varid, dimid, dims[2], strdim, *eb_array;
  int temp;
  int iblk;
  int status;
  int num_elem_blk;
  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);
  }

  for (i=0;i<num_elem_blk;i++) {
    if (num_elem_this_blk[i] == 0) /* Is this a NULL element block? */
      eb_array[i] = 0; /* change element block status to NULL */
    else
      eb_array[i] = 1; /* change element block status to TRUE */
  }

  /* 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 */
  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, &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);
  }

  /* Iterate over element blocks ... */
  for (iblk = 0; iblk < num_elem_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 (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),
			     num_elem_this_blk[iblk], &numelbdim)) != NC_NOERR) {
      exerrval = status;
      if (status == NC_ENAMEINUSE) {     /* duplicate entry */
	sprintf(errmsg,
		"Error: element block %d already defined in file id %d",
		elem_blk_id[iblk],exoid);
      } else {
	sprintf(errmsg,
		"Error: failed to define number of elements/block for block %d file id %d",
		elem_blk_id[iblk],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_nodes_per_elem[iblk], &nelnoddim)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to define number of nodes/element for block %d in file id %d",
	      elem_blk_id[iblk],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),
			      NC_INT, 2, dims, &connid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to create connectivity array for block %d in file id %d",
	      elem_blk_id[iblk],exoid);
      ex_err("ex_put_concat_elem_block",errmsg,exerrval);
      goto error_ret;         /* exit define mode and return */
    }

    /* 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[iblk] > 0) {
      if ((status = nc_def_dim (exoid, 
				DIM_NUM_ATT_IN_BLK(cur_num_elem_blk+1),
				num_attr[iblk], &numattrdim)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to define number of attributes in block %d in file id %d",
		elem_blk_id[iblk],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 %d in file id %d",
		elem_blk_id[iblk],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, NC_INT, 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 */
	}
      }
    }

    /* 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, NC_INT, 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 */
	}
      }
    }
  }

  /* 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++) {
      if (num_elem_this_blk[iblk] == 0) /* Is this a NULL element block? */
	continue;
      for (i = 0; i < num_attr[iblk]; 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);
}
Exemple #7
0
/*!
 * 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;
  int status;
  size_t num_elem_blk, num_edge_blk, num_face_blk, i;
  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 */
  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]);

  exerrval  = 0; /* clear error code */

  /* 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_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;
        sprintf( errmsg, "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;
	sprintf( errmsg, "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;						\
	sprintf(errmsg,							\
		"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;						\
	sprintf(errmsg,							\
		"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 TRUE */		\
      }									\
									\
      /* Next, get variable id of status array */			\
      if ((status = nc_inq_varid(exoid, VSTATNAME, &varid)) != NC_NOERR) { \
	exerrval = status;						\
	sprintf(errmsg,							\
		"Error: failed to locate " TNAME " block status in file id %d", \
		exoid);							\
	ex_err("ex_put_concat_all_blocks",errmsg,exerrval);		\
	return (EX_FATAL);						\
      }									\
									\
      status = nc_put_var_int(exoid, varid, GSTAT);			\
									\
      if (status != NC_NOERR) {						\
	exerrval = status;						\
	sprintf(errmsg,							\
		"Error: failed to store " TNAME " block status array to file id %d", \
		exoid);							\
	ex_err("ex_put_concat_all_blocks",errmsg,exerrval);		\
	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;						\
	sprintf(errmsg,							\
		"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 */					\
      status = nc_put_var_int(exoid, varid, SIDNAME);			\
									\
      if (status != NC_NOERR) {						\
	exerrval = status;						\
	sprintf(errmsg,							\
		"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;
    sprintf(errmsg,"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;						\
      sprintf(errmsg,							\
	      "Error: failed to define number of attributes in " TNAME " block %d in file id %d", \
	      ID[iblk],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;						\
      sprintf(errmsg,							\
	      "Error:  failed to define attributes for " TNAME " block %d in file id %d", \
	      ID[iblk],exoid);						\
      ex_err("ex_put_concat_all_blocks",errmsg,exerrval);		\
      goto error_ret;         /* exit define mode and return */		\
    }									\
									\
    /* 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;						\
      sprintf(errmsg,							\
	      "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 ) {							\
    dims[0] = BLKSZ;							\
    dims[1] = DNAME;							\
									\
    if ((status = nc_def_var(exoid, VNAME(BLK+1),			\
			     NC_INT, 2, dims, &connid)) != NC_NOERR) {	\
      exerrval = status;						\
      sprintf(errmsg,							\
	      "Error: failed to create " TNAME " connectivity array for block %d in file id %d", \
	      BLKID[iblk],exoid);					\
      ex_err("ex_put_concat_all_blocks",errmsg,exerrval);		\
      goto error_ret;         /* exit define mode and return */		\
    }									\
  }


  /* Iterate over edge blocks ... */
  for (iblk = 0; iblk < num_edge_blk; ++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;
      sprintf(errmsg,
	      "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 */
	sprintf(errmsg,
		"Error: edge block %d already defined in file id %d",
		param->edge_blk_id[iblk],exoid);
      } else {
	sprintf(errmsg,
		"Error: failed to define number of edges/block for block %d file id %d",
		param->edge_blk_id[iblk],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;
      sprintf(errmsg,
	      "Error: failed to define number of nodes/edge for block %d in file id %d",
	      param->edge_blk_id[iblk],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,param->edge_blk_id,VAR_EATTRIB,numedbdim,numattrdim,VAR_NAME_EATTRIB);

    EX_PREPARE_CONN("edge block",cur_num_edge_blk,param->edge_blk_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;
      sprintf(errmsg,
	      "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) {

    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;
      sprintf(errmsg,
	      "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 */
	sprintf(errmsg,
		"Error: face block %d already defined in file id %d",
		param->face_blk_id[iblk],exoid);
      } else {
	sprintf(errmsg,
		"Error: failed to define number of faces/block for block %d file id %d",
		param->face_blk_id[iblk],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;
      sprintf(errmsg,
	      "Error: failed to define number of nodes/face for block %d in file id %d",
	      param->face_blk_id[iblk],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("face",cur_num_face_blk,DIM_NUM_ATT_IN_FBLK,param->num_attr_face,param->face_blk_id,VAR_FATTRIB,numfabdim,numattrdim,VAR_NAME_FATTRIB);

    EX_PREPARE_CONN("face block",cur_num_face_blk,param->face_blk_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;
      sprintf(errmsg,
	      "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) {

    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;
      sprintf(errmsg,
	      "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 */
	sprintf(errmsg,
		"Error: element block %d already defined in file id %d",
		param->elem_blk_id[iblk],exoid);
      } else {
	sprintf(errmsg,
		"Error: failed to define number of elements/block for block %d file id %d",
		param->elem_blk_id[iblk],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;
      sprintf(errmsg,
	      "Error: failed to define number of nodes/element for block %d in file id %d",
	      param->elem_blk_id[iblk],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;
	sprintf(errmsg,
		"Error: failed to define number of edges/element for block %d in file id %d",
		param->elem_blk_id[iblk],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;
	sprintf(errmsg,
		"Error: failed to define number of faces/element for block %d in file id %d",
		param->elem_blk_id[iblk],exoid);
	ex_err("ex_put_concat_all_blocks",errmsg,exerrval);
	goto error_ret;         /* exit define mode and return */
      }
    }

    /* element attribute array */
    EX_PREPARE_ATTRIB_ARRAY("element",cur_num_elem_blk,DIM_NUM_ATT_IN_BLK,param->num_attr_elem,param->elem_blk_id,VAR_ATTRIB,numelbdim,numattrdim,VAR_NAME_ATTRIB);
    
    /* element connectivity array */
    EX_PREPARE_CONN("nodal",cur_num_elem_blk,param->elem_blk_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;
      sprintf(errmsg,
	      "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,param->elem_blk_id,numelbdim,VAR_ECONN,neledgdim);
    EX_PREPARE_CONN( "face",cur_num_elem_blk,param->elem_blk_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;
	sprintf( errmsg,
		 "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) {
	  if ((status = nc_def_var(exoid, mapname, NC_INT, 1, dims, &temp)) != NC_NOERR) {
	    exerrval = status;
	    if ( status == NC_ENAMEINUSE ) {
	      sprintf( errmsg, "Error: number map %s already exists in file id %d", mapname, exoid );
	    } else {
	      sprintf( errmsg, "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 */
	  }
	}
      }
    }
  }

  /* 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_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 */
    sprintf(errmsg,
	    "Error: failed to complete definition for file id %d",
	    exoid);
    ex_err("ex_put_concat_all_blocks",errmsg,exerrval);
  }
  return (EX_FATAL);
}
Exemple #8
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 #9
0
int ex_put_block( int         exoid,
                  ex_entity_type blk_type,
                  int         blk_id,
                  const char* entry_descrip,
                  int         num_entries_this_blk,
                  int         num_nodes_per_entry,
                  int         num_edges_per_entry,
                  int         num_faces_per_entry,
                  int         num_attr_per_entry )
{
  int status;
  int arbitrary_polyhedra = 0; /* 1 if block is arbitrary 2d polyhedra type; 2 if 3d polyhedra */
  int varid, dimid, dims[2], blk_id_ndx, blk_stat, strdim;
  size_t start[2];
  int num_blk;
  size_t temp;
  int cur_num_blk, numblkdim, numattrdim;
  int nnodperentdim, nedgperentdim, nfacperentdim;
  int connid;
  int npeid;
  char errmsg[MAX_ERR_LENGTH];
  char entity_type1[5];
  char entity_type2[5];
  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 */

  switch (blk_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 file id %d",
             blk_type, exoid );
    ex_err( "ex_put_block", errmsg, exerrval );
    return (EX_FATAL);
  }

  /* first check if any element blocks are specified */

  if ((status = ex_get_dimension(exoid, dnumblk, ex_name_of_object(blk_type),
                                 &temp, &dimid, "ex_put_block")) != NC_NOERR) {
    return EX_FATAL;
  }
  num_blk = (int)temp;
  
  /* Next: Make sure that this is not a duplicate element block id 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(blk_type), exoid);
    ex_err("ex_put_block",errmsg,exerrval);
  }

  blk_id_ndx = ex_id_lkup(exoid,blk_type,blk_id);
  if (exerrval != EX_LOOKUPFAIL) {   /* found the element block id */
    exerrval = EX_FATAL;
    sprintf(errmsg,
            "Error: %s id %d already exists in file id %d",
            ex_name_of_object(blk_type), blk_id,exoid);
    ex_err("ex_put_block",errmsg,exerrval);
    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 incremented.
  */
  cur_num_blk=ex_get_file_item(exoid, ex_get_counter_list(blk_type));
  if (cur_num_blk >= num_blk) {
    exerrval = EX_FATAL;
    sprintf(errmsg,
            "Error: exceeded number of %ss (%d) defined in file id %d",
            ex_name_of_object(blk_type), num_blk,exoid);
    ex_err("ex_put_block",errmsg,exerrval);
    return (EX_FATAL);
  }


  /*   NOTE: ex_get_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(blk_type));
  start[0] = cur_num_blk;

  /* write out element block id to previously defined id array variable*/
  if ((status = nc_put_var1_int(exoid, varid, start, &blk_id)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
            "Error: failed to store %s id to file id %d",
            ex_name_of_object(blk_type), exoid);
    ex_err("ex_put_block",errmsg,exerrval);
    return (EX_FATAL);
  }

  blk_id_ndx = ((int)start[0])+1; /* element id index into vblkids array*/

  if (num_entries_this_blk == 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 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(blk_type), exoid);
    ex_err("ex_put_block",errmsg,exerrval);
    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 %d status to file id %d",
            ex_name_of_object(blk_type), blk_id, exoid);
    ex_err("ex_put_block",errmsg,exerrval);
    return (EX_FATAL);
  }

  if (num_entries_this_blk == 0) {/* Is this a NULL element block? */
    return(EX_NOERR);
  }


  /* 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",errmsg,exerrval);
    return (EX_FATAL);
  }

  switch (blk_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:
    exerrval = 1005;
    sprintf(errmsg,
            "Internal Error: unrecognized block type in switch: %d in file id %d",
            blk_type,exoid);
    ex_err("ex_put_block",errmsg,EX_MSG);
    return (EX_FATAL);              /* number of attributes not defined */
  }
  /* define some dimensions and variables*/

  if ((status = nc_def_dim(exoid,dneblk,num_entries_this_blk, &numblkdim )) != NC_NOERR) {
    if (status == NC_ENAMEINUSE) {        /* duplicate entry */
      exerrval = status;
      sprintf(errmsg,
              "Error: %s %d already defined in file id %d",
              ex_name_of_object(blk_type), blk_id,exoid);
      ex_err("ex_put_block",errmsg,exerrval);
    } else {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to define number of entities/block for %s %d file id %d",
              ex_name_of_object(blk_type), blk_id,exoid);
      ex_err("ex_put_block",errmsg,exerrval);
    }
    goto error_ret;         /* exit define mode and return */
  }

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

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

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

  /* element attribute array */
  if (num_attr_per_entry > 0) {

    if ((status = nc_def_dim(exoid, dnape, num_attr_per_entry, &numattrdim)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to define number of attributes in %s %d in file id %d",
              ex_name_of_object(blk_type), blk_id,exoid);
      ex_err("ex_put_block",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 %d in file id %d",
              ex_name_of_object(blk_type), blk_id,exoid);
      ex_err("ex_put_block",errmsg,exerrval);
      goto error_ret;         /* exit define mode and return */
    }

    /* inquire previously defined dimensions  */
    if ((status = nc_inq_dimid(exoid, DIM_STR, &strdim)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to get string length in file id %d",exoid);
      ex_err("ex_put_block",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(blk_type), exoid);
      ex_err("ex_put_block",errmsg,exerrval);
      goto error_ret;         /* exit define mode and return */
    }
  }

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

  /* element connectivity array */
  if (arbitrary_polyhedra > 0) {
    if (blk_type != EX_FACE_BLOCK && blk_type != EX_ELEM_BLOCK) {
      exerrval = EX_BADPARAM;
      sprintf( errmsg, "Error: Bad block type (%d) for nsided/nfaced block in file id %d",
               blk_type, exoid );
      ex_err( "ex_put_block", errmsg, exerrval );
      return (EX_FATAL);
    }

    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 (blk_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, NC_INT, 1, dims, &connid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to create connectivity array for %s %d in file id %d",
              ex_name_of_object(blk_type), blk_id,exoid);
      ex_err("ex_put_block",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, NC_INT, 1, dims, &npeid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to create face- or node- per-entity count array for %s %d in file id %d",
              ex_name_of_object(blk_type), blk_id, exoid);
      ex_err("ex_put_block",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 %d in file id %d",
              ex_name_of_object(blk_type), blk_id, exoid);
      ex_err("ex_put_block",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 %d in file id %d",
              ex_name_of_object(blk_type), blk_id, exoid);
      ex_err("ex_put_block",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, NC_INT, 2, dims, &connid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to create connectivity array for %s %d in file id %d",
              ex_name_of_object(blk_type), blk_id,exoid);
      ex_err("ex_put_block",errmsg,exerrval);
      goto error_ret;         /* exit define mode and return */
    }
  }
  /* store element type as attribute of connectivity variable */
  if ((status = nc_put_att_text(exoid, connid, ATT_NAME_ELB, strlen(entry_descrip)+1, 
                                entry_descrip)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
            "Error: failed to store %s type name %s in file id %d",
            ex_name_of_object(blk_type), entry_descrip,exoid);
    ex_err("ex_put_block",errmsg,exerrval);
    goto error_ret;         /* exit define mode and return */
  }

  if (arbitrary_polyhedra == 0) {
    if (vedgcon && num_edges_per_entry ) {
      dims[0] = numblkdim;
      dims[1] = nedgperentdim;
      
      if ((status = nc_def_var(exoid, vedgcon, NC_INT, 2, dims, &varid)) != NC_NOERR) {
        exerrval = status;
        sprintf(errmsg,
                "Error: failed to create edge connectivity array for %s %d in file id %d",
                ex_name_of_object(blk_type), blk_id,exoid);
        ex_err("ex_put_block",errmsg,exerrval);
        goto error_ret;         /* exit define mode and return */
      }
    }
    
    if ( vfaccon && num_faces_per_entry ) {
      dims[0] = numblkdim;
      dims[1] = nfacperentdim;
      
      if ((status = nc_def_var(exoid, vfaccon, NC_INT, 2, dims, &varid)) != NC_NOERR) {
        exerrval = status;
        sprintf(errmsg,
                "Error: failed to create face connectivity array for %s %d in file id %d",
                ex_name_of_object(blk_type), blk_id,exoid);
        ex_err("ex_put_block",errmsg,exerrval);
        goto error_ret;         /* exit define mode and return */
      }
    }
  }
  /* 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(blk_type), exoid);
    ex_err("ex_put_block",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_block",errmsg,exerrval);
  }
  return (EX_FATAL);
}
/*!
 * writes a map; this is a vector of integers of length number of mesh
 * objects of that type (element, node, face, edge)
 */
int ex_put_partial_num_map (int exoid,
			    ex_entity_type map_type,
			    ex_entity_id map_id,
			    int64_t ent_start,
			    int64_t ent_count, 
			    const void_int *map)
{
  int status;
  int dimid, varid, map_ndx, map_exists;
  size_t start[1]; 
  size_t num_maps, num_mobj, count[1];
  int cur_num_maps;
  char errmsg[MAX_ERR_LENGTH];
  const char* dnumentries;
  const char* dnummaps;
  const char* vmapids;
  const char* vmap;

  exerrval = 0; /* clear error code */

  switch ( map_type ) {
  case EX_NODE_MAP:
    dnumentries = DIM_NUM_NODES;
    dnummaps = DIM_NUM_NM;
    vmapids = VAR_NM_PROP(1);
    break;
  case EX_EDGE_MAP:
    dnumentries = DIM_NUM_EDGE;
    dnummaps = DIM_NUM_EDM;
    vmapids = VAR_EDM_PROP(1);
    break;
  case EX_FACE_MAP:
    dnumentries = DIM_NUM_FACE;
    dnummaps = DIM_NUM_FAM;
    vmapids = VAR_FAM_PROP(1);
    break;
  case EX_ELEM_MAP:
    dnumentries = DIM_NUM_ELEM;
    dnummaps = DIM_NUM_EM;
    vmapids = VAR_EM_PROP(1);
    break;
  default:
    exerrval = EX_BADPARAM;
    sprintf( errmsg,
	     "Error: Bad map type (%d) specified for file id %d",
	     map_type, exoid );
    ex_err( "ex_put_num_map", errmsg, exerrval );
    return (EX_FATAL);
  }

  /* Make sure the file contains entries */
  if (nc_inq_dimid (exoid, dnumentries, &dimid) != NC_NOERR ) {
    return (EX_NOERR);
  }

  /* first check if any maps are specified */
  if ((status = nc_inq_dimid (exoid, dnummaps, &dimid)) != NC_NOERR )
    {
      exerrval = status;
      sprintf(errmsg,
	      "Error: no %ss specified in file id %d",
	      ex_name_of_object(map_type),exoid);
      ex_err("ex_put_partial_num_map",errmsg,exerrval);
      return (EX_FATAL);
    }
  
  /* Check for duplicate map id entry */
  ex_id_lkup(exoid,map_type,map_id); 
  if (exerrval == EX_LOOKUPFAIL) {   /* did not find the map id */
    map_exists = 0; /* Map is being defined */
  } else {
    map_exists = 1; /* A portion of this map has already been written */
  }
   
  /* Check for duplicate map id entry */
  if (!map_exists) {
    /* Get number of maps initialized for this file */
    if ((status = nc_inq_dimlen(exoid,dimid,&num_maps)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to get number of %ss in file id %d",
	      ex_name_of_object(map_type),exoid);
      ex_err("ex_put_partial_num_map",errmsg,exerrval);
      return (EX_FATAL);
    }

    /* Keep track of the total number of maps defined using a
       counter stored in a linked list keyed by exoid.  NOTE:
       ex_get_file_item is used to find the number of element maps for a
       specific file and returns that value.
    */
    cur_num_maps = ex_get_file_item(exoid, ex_get_counter_list(map_type));
    if (cur_num_maps >= (int)num_maps) {
      exerrval = EX_FATAL;
      sprintf(errmsg,
	      "Error: exceeded number of %ss (%"ST_ZU") specified in file id %d",
	      ex_name_of_object(map_type),num_maps,exoid);
      ex_err("ex_put_num_map",errmsg,exerrval);
      return (EX_FATAL);
    }
    
    /*   NOTE: ex_inc_file_item  is used to find the number of element maps
	 for a specific file and returns that value incremented. */
    cur_num_maps = ex_inc_file_item(exoid, ex_get_counter_list(map_type));
  } else {
    map_ndx = ex_id_lkup(exoid,map_type,map_id); 
    cur_num_maps = map_ndx-1;
  }

  /* determine number of elements */
  if ((status = nc_inq_dimid(exoid, dnumentries, &dimid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: couldn't determine number of mesh objects in file id %d",
	    exoid);
    ex_err("ex_put_partial_num_map",errmsg,exerrval);
    return (EX_FATAL);
  }

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

  /* Check input parameters for a valid range of numbers */
  if (ent_start <= 0 || ent_start > num_mobj) {
    exerrval = EX_FATAL;
    sprintf(errmsg,
	    "Error: start count is invalid in file id %d",
	    exoid);
    ex_err("ex_put_partial_num_map",errmsg,exerrval);
    return (EX_FATAL);
  }
  if (ent_count < 0) {
    exerrval = EX_FATAL;
    sprintf(errmsg,
	    "Error: Invalid count value in file id %d",
	    exoid);
    ex_err("ex_put_partial_num_map",errmsg,exerrval);
    return (EX_FATAL);
  }
  if (ent_start+ent_count-1 > num_mobj) {
    exerrval = EX_FATAL;
    sprintf(errmsg,
	    "Error: start+count-1 is larger than mesh object count in file id %d",
	    exoid);
    ex_err("ex_put_partial_num_map",errmsg,exerrval);
    return (EX_FATAL);
  }
  

  /* write out information to previously defined variable */

  /* first get id of variable */
  if ((status = nc_inq_varid (exoid, vmapids, &varid)) == -1)
    {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to locate %s ids in file id %d",
	      ex_name_of_object(map_type),exoid);
      ex_err("ex_put_num_map",errmsg,exerrval);
      return (EX_FATAL);
    }

  /* then, write out map id */
  if (!map_exists) {
    start[0] = cur_num_maps;
    {
      if ((status = nc_put_var1_longlong(exoid, varid, start, (long long*)&map_id)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to store %s id %"PRId64" in file id %d",
		ex_name_of_object(map_type),map_id,exoid);
	ex_err("ex_put_num_map",errmsg,exerrval);
	return (EX_FATAL);
      }
    }
  }
  
  switch ( map_type ) {
  case EX_NODE_MAP:
    vmap = VAR_NODE_MAP(cur_num_maps+1);
    break;
  case EX_EDGE_MAP:
    vmap = VAR_EDGE_MAP(cur_num_maps+1);
    break;
  case EX_FACE_MAP:
    vmap = VAR_FACE_MAP(cur_num_maps+1);
    break;
  case EX_ELEM_MAP:
    vmap = VAR_ELEM_MAP(cur_num_maps+1);
    break;
  default:
    exerrval = 1005;
    sprintf(errmsg,
	    "Internal Error: unrecognized map type in switch: %d in file id %d",
	    map_type,exoid);
    ex_err("ex_putt_partial_one_attr",errmsg,EX_MSG);
    return (EX_FATAL);
  }

  /* locate variable array in which to store the map */
  if ((status = nc_inq_varid(exoid,vmap, &varid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to locate %s %"PRId64" in file id %d",
	    ex_name_of_object(map_type),map_id,exoid);
    ex_err("ex_put_partial_num_map",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* write out the map  */
  start[0] = ent_start-1;
  count[0] = ent_count;

  if (count[0] == 0)
    start[0] = 0;
  
  if (ex_int64_status(exoid) & EX_MAPS_INT64_API) {
    status = nc_put_vara_longlong(exoid, varid, start, count, map);
  } else {
    status = nc_put_vara_int(exoid, varid, start, count, map);
  }

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

  return (EX_NOERR);
}
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);
}
Exemple #12
0
/*!
 * updates and then closes an open EXODUS II file
 */
int ex_close (int exoid)
{
   char errmsg[MAX_ERR_LENGTH];
   int status;
   
   exerrval = 0; /* clear error code */

   if ((status = nc_sync(exoid)) != NC_NOERR) {
     exerrval = status;
     sprintf(errmsg,"Error: failed to update file id %d",exoid);
     ex_err("ex_close",errmsg,exerrval);
     return(EX_FATAL);
   }
   /* Check header size.  Will print message if too big... */
   ex_header_size(exoid);

   if ((status = nc_close (exoid)) == NC_NOERR) {
     ex_conv_exit(exoid);

     ex_rm_file_item(exoid, ex_get_counter_list(EX_ELEM_BLOCK));
     ex_rm_file_item(exoid, ex_get_counter_list(EX_FACE_BLOCK));
     ex_rm_file_item(exoid, ex_get_counter_list(EX_EDGE_BLOCK));
     ex_rm_file_item(exoid, ex_get_counter_list(EX_NODE_SET));
     ex_rm_file_item(exoid, ex_get_counter_list(EX_EDGE_SET));
     ex_rm_file_item(exoid, ex_get_counter_list(EX_FACE_SET));
     ex_rm_file_item(exoid, ex_get_counter_list(EX_SIDE_SET));
     ex_rm_file_item(exoid, ex_get_counter_list(EX_ELEM_SET));
     ex_rm_file_item(exoid, ex_get_counter_list(EX_NODE_MAP));
     ex_rm_file_item(exoid, ex_get_counter_list(EX_EDGE_MAP));
     ex_rm_file_item(exoid, ex_get_counter_list(EX_FACE_MAP));
     ex_rm_file_item(exoid, ex_get_counter_list(EX_ELEM_MAP));

     ex_rm_stat_ptr (exoid, &exoII_ed);
     ex_rm_stat_ptr (exoid, &exoII_fa);
     ex_rm_stat_ptr (exoid, &exoII_eb);
     ex_rm_stat_ptr (exoid, &exoII_ns);
     ex_rm_stat_ptr (exoid, &exoII_es);
     ex_rm_stat_ptr (exoid, &exoII_fs);
     ex_rm_stat_ptr (exoid, &exoII_ss);
     ex_rm_stat_ptr (exoid, &exoII_els);
     ex_rm_stat_ptr (exoid, &exoII_nm);
     ex_rm_stat_ptr (exoid, &exoII_edm);
     ex_rm_stat_ptr (exoid, &exoII_fam);
     ex_rm_stat_ptr (exoid, &exoII_em);
   }
   else {
     exerrval = status;
     sprintf(errmsg, "Error: failed to close file id %d",exoid);
     ex_err("ex_close",errmsg, status);
     return(EX_FATAL);
   }
   return(EX_NOERR);
}
/*!
 * writes an element map; this is a vector of integers of length number
 * of elements
 */
int ex_put_partial_elem_map (int exoid,
			     int map_id,
			     int ent_start,
			     int ent_count, 
			     const int *elem_map)
{
  int status;
  int dimid, varid, map_ndx, map_exists;
  size_t start[1]; 
  size_t num_elem_maps, num_elem, count[1];
  int cur_num_elem_maps;
  char *cdum;
  char errmsg[MAX_ERR_LENGTH];

  exerrval = 0; /* clear error code */
  map_exists = 0;
  cdum = 0;


  /* Make sure the file contains elements */
  if (nc_inq_dimid (exoid, DIM_NUM_ELEM, &dimid) != NC_NOERR ) {
    return (EX_NOERR);
  }

  /* first check if any element maps are specified */
  if ((status = nc_inq_dimid(exoid, DIM_NUM_EM, &dimid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: no element maps specified in file id %d",
	    exoid);
    ex_err("ex_put_partial_elem_map",errmsg,exerrval);
    return (EX_FATAL);
  }
  
  /* Check for duplicate element map id entry */
  map_ndx = ex_id_lkup(exoid,EX_ELEM_MAP,map_id); 
  if (exerrval == EX_LOOKUPFAIL) {   /* did not find the element map id */
    map_exists = 0; /* Map is being defined */
    map_ndx    = -1;
  } else {
    map_exists = 1; /* A portion of this map has already been written */
  }

  if (!map_exists) {
    /* Get number of element maps initialized for this file */
    if ((status = nc_inq_dimlen(exoid,dimid,&num_elem_maps)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to get number of element maps in file id %d",
	      exoid);
      ex_err("ex_put_partial_elem_map",errmsg,exerrval);
      return (EX_FATAL);
    }

    /* Keep track of the total number of element maps defined using a
       counter stored in a linked list keyed by exoid.  NOTE:
       ex_get_file_item is used to find the number of element maps for a
       specific file and returns that value.
    */
    cur_num_elem_maps = ex_get_file_item(exoid, ex_get_counter_list(EX_ELEM_MAP));
    if (cur_num_elem_maps >= (int)num_elem_maps) {
      exerrval = EX_FATAL;
      sprintf(errmsg,
	      "Error: exceeded number of element maps (%ld) specified in file id %d",
	      (long)num_elem_maps,exoid);
      ex_err("ex_put_partial_elem_map",errmsg,exerrval);
      return (EX_FATAL);
    }
    
    /*   NOTE: ex_inc_file_item  is used to find the number of element maps
	 for a specific file and returns that value incremented. */
    cur_num_elem_maps = ex_inc_file_item(exoid, ex_get_counter_list(EX_ELEM_MAP));
  } else {
    cur_num_elem_maps = map_ndx-1;
  }

  /* determine number of elements */
  if ((status = nc_inq_dimid(exoid, DIM_NUM_ELEM, &dimid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: couldn't determine number of elements in file id %d",
	    exoid);
    ex_err("ex_put_partial_elem_map",errmsg,exerrval);
    return (EX_FATAL);
  }

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

  /* Check input parameters for a valid range of numbers */
  if (ent_start <= 0 || (size_t)ent_start > num_elem) {
    exerrval = EX_FATAL;
    sprintf(errmsg,
	    "Error: start count is invalid in file id %d",
	    exoid);
    ex_err("ex_put_partial_elem_map",errmsg,exerrval);
    return (EX_FATAL);
  }
  if (ent_count < 0) {
    exerrval = EX_FATAL;
    sprintf(errmsg,
	    "Error: Invalid count value in file id %d",
	    exoid);
    ex_err("ex_put_partial_elem_map",errmsg,exerrval);
    return (EX_FATAL);
  }
  if ((size_t)(ent_start+ent_count-1) > num_elem) {
    exerrval = EX_FATAL;
    sprintf(errmsg,
	    "Error: start+count-1 is larger than element count in file id %d",
	    exoid);
    ex_err("ex_put_partial_elem_map",errmsg,exerrval);
    return (EX_FATAL);
  }
  

  /* write out information to previously defined variable */

  /* first get id of variable */
  if ((status = nc_inq_varid(exoid, VAR_EM_PROP(1), &varid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to locate element map ids in file id %d",
	    exoid);
    ex_err("ex_put_partial_elem_map",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* then, write out element map id */
  if (!map_exists) {
    start[0] = cur_num_elem_maps;

    if ((status = nc_put_var1_int(exoid, varid, start, &map_id)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to store element map id %d in file id %d",
	      map_id,exoid);
      ex_err("ex_put_partial_elem_map",errmsg,exerrval);
      return (EX_FATAL);
    }
  }
  
  /* locate variable array in which to store the element map */
  if ((status = nc_inq_varid(exoid,VAR_ELEM_MAP(cur_num_elem_maps+1),
			     &varid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to locate element map %d in file id %d",
	    map_id,exoid);
    ex_err("ex_put_partial_elem_map",errmsg,exerrval);
    return (EX_FATAL);
  }

  /* write out the element map  */
  start[0] = ent_start-1;
  count[0] = ent_count;

  status = nc_put_vara_int(exoid, varid, start, count, elem_map);

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

  return (EX_NOERR);
}
/*!

The function ex_close() updates and then closes an open exodus file.

\return In case of an error, ex_close() returns a negative number; a
        warning will return a positive number. Possible causes of errors
        include:
 - data file not properly opened with call to ex_create() or ex_open()

 \param exoid      exodus file ID returned from a previous call to ex_create()
or ex_open().

The following code segment closes an open exodus file:

~~~{.c}
int error,exoid;
error = ex_close (exoid);
~~~

 */
int ex_close(int exoid)
{
  char errmsg[MAX_ERR_LENGTH];
  int  status;
  int  status1;
  int  status2;
#if NC_HAS_HDF5
  int parent_id = 0;
#endif

  EX_FUNC_ENTER();

  ex_check_valid_file_id(exoid, __func__);

  /*
   * NOTE: If using netcdf-4, exoid must refer to the root group.
   * Need to determine whether there are any groups and if so,
   * call ex_rm_file_item and ex_rm_stat_ptr on each group.
   */

#if NC_HAS_HDF5
  /* nc_inq_grp_parent() will return NC_ENOGRP error if exoid
   * refers to the root group (which is what we want)
   */
  if ((status = nc_inq_grp_parent(exoid, &parent_id)) != NC_ENOGRP) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: file id %d does not refer to root group.", exoid);
    ex_err(__func__, errmsg, EX_NOTROOTID);
    EX_FUNC_LEAVE(EX_FATAL);
  }
#endif

  if ((status1 = nc_sync(exoid)) != NC_NOERR) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to update file id %d", exoid);
    ex_err(__func__, errmsg, status1);
  }

  if ((status2 = nc_close(exoid)) != NC_NOERR) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to close file id %d", exoid);
    ex_err(__func__, errmsg, status2);
  }

  /* Even if we have failures above due to nc_sync() or nc_close(), we still need to clean up our
   * internal datastructures.
   */

  ex_rm_file_item(exoid, ex_get_counter_list(EX_ELEM_BLOCK));
  ex_rm_file_item(exoid, ex_get_counter_list(EX_FACE_BLOCK));
  ex_rm_file_item(exoid, ex_get_counter_list(EX_EDGE_BLOCK));
  ex_rm_file_item(exoid, ex_get_counter_list(EX_NODE_SET));
  ex_rm_file_item(exoid, ex_get_counter_list(EX_EDGE_SET));
  ex_rm_file_item(exoid, ex_get_counter_list(EX_FACE_SET));
  ex_rm_file_item(exoid, ex_get_counter_list(EX_SIDE_SET));
  ex_rm_file_item(exoid, ex_get_counter_list(EX_ELEM_SET));
  ex_rm_file_item(exoid, ex_get_counter_list(EX_NODE_MAP));
  ex_rm_file_item(exoid, ex_get_counter_list(EX_EDGE_MAP));
  ex_rm_file_item(exoid, ex_get_counter_list(EX_FACE_MAP));
  ex_rm_file_item(exoid, ex_get_counter_list(EX_ELEM_MAP));

  ex_rm_stat_ptr(exoid, &exoII_ed);
  ex_rm_stat_ptr(exoid, &exoII_fa);
  ex_rm_stat_ptr(exoid, &exoII_eb);
  ex_rm_stat_ptr(exoid, &exoII_ns);
  ex_rm_stat_ptr(exoid, &exoII_es);
  ex_rm_stat_ptr(exoid, &exoII_fs);
  ex_rm_stat_ptr(exoid, &exoII_ss);
  ex_rm_stat_ptr(exoid, &exoII_els);
  ex_rm_stat_ptr(exoid, &exoII_nm);
  ex_rm_stat_ptr(exoid, &exoII_edm);
  ex_rm_stat_ptr(exoid, &exoII_fam);
  ex_rm_stat_ptr(exoid, &exoII_em);

  ex_conv_exit(exoid);

  status = EX_NOERR;
  if (status1 != NC_NOERR || status2 != NC_NOERR) {
    status = EX_FATAL;
  }
  EX_FUNC_LEAVE(status);
}