From 3e6500f60268baa9bfc8ca20affa103fbc59d30a Mon Sep 17 00:00:00 2001 From: Greg Sjaardema Date: Wed, 17 Jul 2024 10:55:37 -0600 Subject: [PATCH] EXODUS: Prototype to see if can speed up field metadata output (#468) * EXODUS: Prototype to see if can speed up field metadata output * EXODUS: Check that not in define mode at update or close call * EXODUS: Initialize all members of exi_file_item struct * EXODUS: Add calling function to redef calls; increase persist count size * IOSS: Add calling function to redef calls; increase persist count size * EXODUS: Avoid writing empty type_name and default separator * EXODUS: Handle error returns when in persist redef mode * EXODUS: Fix handling of default separator * EXODUS: Remove debug printing --------- Co-authored-by: Greg Sjaardema --- .../libraries/exodus/include/exodusII.h | 2 + .../libraries/exodus/include/exodusII_int.h | 38 +++--- .../src/ex__put_homogenous_block_params.c | 2 +- .../seacas/libraries/exodus/src/ex_add_attr.c | 2 +- .../seacas/libraries/exodus/src/ex_close.c | 7 +- .../seacas/libraries/exodus/src/ex_conv.c | 2 + .../seacas/libraries/exodus/src/ex_copy.c | 4 +- .../libraries/exodus/src/ex_create_group.c | 4 +- .../exodus/src/ex_get_field_metadata.c | 16 ++- .../seacas/libraries/exodus/src/ex_open.c | 2 +- .../seacas/libraries/exodus/src/ex_open_par.c | 4 +- .../exodus/src/ex_put_all_var_param_ext.c | 2 +- .../libraries/exodus/src/ex_put_assemblies.c | 2 +- .../libraries/exodus/src/ex_put_attr_param.c | 2 +- .../libraries/exodus/src/ex_put_attribute.c | 6 +- .../libraries/exodus/src/ex_put_blobs.c | 2 +- .../exodus/src/ex_put_block_params.c | 2 +- .../libraries/exodus/src/ex_put_cmap_params.c | 2 +- .../exodus/src/ex_put_cmap_params_cc.c | 2 +- .../exodus/src/ex_put_concat_all_blocks.c | 2 +- .../exodus/src/ex_put_concat_elem_block.c | 2 +- .../libraries/exodus/src/ex_put_concat_sets.c | 2 +- .../exodus/src/ex_put_coordinate_frames.c | 2 +- .../exodus/src/ex_put_field_metadata.c | 71 ++++++++++-- .../libraries/exodus/src/ex_put_id_map.c | 2 +- .../seacas/libraries/exodus/src/ex_put_info.c | 4 +- .../libraries/exodus/src/ex_put_init_ext.c | 2 +- .../libraries/exodus/src/ex_put_init_global.c | 2 +- .../libraries/exodus/src/ex_put_init_info.c | 2 +- .../exodus/src/ex_put_loadbal_param.c | 2 +- .../exodus/src/ex_put_loadbal_param_cc.c | 2 +- .../seacas/libraries/exodus/src/ex_put_map.c | 2 +- .../libraries/exodus/src/ex_put_map_param.c | 2 +- .../seacas/libraries/exodus/src/ex_put_name.c | 2 +- .../libraries/exodus/src/ex_put_num_map.c | 2 +- .../exodus/src/ex_put_partial_id_map.c | 2 +- .../libraries/exodus/src/ex_put_partial_var.c | 2 +- .../seacas/libraries/exodus/src/ex_put_prop.c | 2 +- .../libraries/exodus/src/ex_put_prop_array.c | 2 +- .../libraries/exodus/src/ex_put_prop_names.c | 2 +- .../seacas/libraries/exodus/src/ex_put_qa.c | 4 +- .../src/ex_put_reduction_variable_param.c | 2 +- .../exodus/src/ex_put_reduction_vars.c | 2 +- .../seacas/libraries/exodus/src/ex_put_sets.c | 2 +- .../libraries/exodus/src/ex_put_truth_table.c | 2 +- .../exodus/src/ex_put_var_multi_time.c | 2 +- .../exodus/src/ex_put_variable_param.c | 2 +- .../seacas/libraries/exodus/src/ex_update.c | 9 +- .../seacas/libraries/exodus/src/ex_utils.c | 93 ++++++++++++++- .../exodus/test/testwt-field-metadata.dmp | 4 - .../ioss/src/exodus/Ioex_BaseDatabaseIO.C | 108 ++++++++++-------- 51 files changed, 304 insertions(+), 142 deletions(-) diff --git a/packages/seacas/libraries/exodus/include/exodusII.h b/packages/seacas/libraries/exodus/include/exodusII.h index dd545b5ec7..906c9b4dcd 100644 --- a/packages/seacas/libraries/exodus/include/exodusII.h +++ b/packages/seacas/libraries/exodus/include/exodusII.h @@ -1045,6 +1045,8 @@ EXODUS_EXPORT int ex_get_blob(int exoid, struct ex_blob *blob); EXODUS_EXPORT int ex_put_blobs(int exoid, size_t count, const struct ex_blob *blobs); EXODUS_EXPORT int ex_get_blobs(int exoid, struct ex_blob *blobs); +EXODUS_EXPORT int ex_put_multi_field_metadata(int exoid, const ex_field *field, + const int field_count); EXODUS_EXPORT int ex_put_field_metadata(int exoid, const ex_field field); EXODUS_EXPORT int ex_put_field_suffices(int exoid, const ex_field field, const char *suffices); EXODUS_EXPORT int ex_get_field_metadata(int exoid, ex_field *field); diff --git a/packages/seacas/libraries/exodus/include/exodusII_int.h b/packages/seacas/libraries/exodus/include/exodusII_int.h index c6e6e7e4e4..e8bb5aca4e 100644 --- a/packages/seacas/libraries/exodus/include/exodusII_int.h +++ b/packages/seacas/libraries/exodus/include/exodusII_int.h @@ -686,28 +686,31 @@ typedef enum exi_element_type exi_element_type; struct exi_file_item { int file_id; - nc_type netcdf_type_code; + nc_type netcdf_type_code; /**< NC_FLOAT or NC_DOUBLE */ int int64_status; int maximum_name_length; int time_varid; /* Store to avoid lookup each timestep */ unsigned int assembly_count; unsigned int blob_count; + unsigned int compression_level; /**< 0 (disabled) to 9 (maximum) compression level for + gzip, 4..32 and even for szip; NetCDF-4 only */ + unsigned int persist_define_mode : 10; /**< Stay in define mode until exi_persist_leavedef is + called. Set by exi_persist_redef... */ unsigned int - compression_algorithm : 2; /**< GZIP/ZLIB, SZIP, more may be supported by NetCDF soon */ - unsigned int compression_level : 6; /**< 0 (disabled) to 9 (maximum) compression level for - gzip, 4..32 and even for szip; NetCDF-4 only */ + compression_algorithm : 4; /**< GZIP/ZLIB, SZIP, more may be supported by NetCDF soon */ + unsigned int shuffle : 1; /**< 1 true, 0 false */ unsigned int user_compute_wordsize : 1; /**< 0 for 4 byte or 1 for 8 byte reals */ - unsigned int shuffle : 1; /**< 1 true, 0 false */ unsigned int file_type : 2; /**< 0 - classic, 1 -- 64 bit classic, 2 --NetCDF4, 3 --NetCDF4 classic */ - unsigned int is_write : 1; /**< for output or append */ - unsigned int is_parallel : 1; /**< 1 true, 0 false */ - unsigned int is_hdf5 : 1; /**< 1 true, 0 false */ - unsigned int is_pnetcdf : 1; /**< 1 true, 0 false */ - unsigned int has_nodes : 1; /**< for input only at this time */ - unsigned int has_edges : 1; /**< for input only at this time */ - unsigned int has_faces : 1; /**< for input only at this time */ - unsigned int has_elems : 1; /**< for input only at this time */ + unsigned int is_write : 1; /**< for output or append */ + unsigned int is_parallel : 1; /**< 1 true, 0 false */ + unsigned int is_hdf5 : 1; /**< 1 true, 0 false */ + unsigned int is_pnetcdf : 1; /**< 1 true, 0 false */ + unsigned int has_nodes : 1; /**< for input only at this time */ + unsigned int has_edges : 1; /**< for input only at this time */ + unsigned int has_faces : 1; /**< for input only at this time */ + unsigned int has_elems : 1; /**< for input only at this time */ + unsigned int in_define_mode : 1; /**< Is the file in nc define mode... */ struct exi_file_item *next; }; @@ -797,8 +800,8 @@ extern struct exi_obj_stats *exoII_fam; extern struct exi_obj_stats *exoII_nm; EXODUS_EXPORT struct exi_file_item *exi_find_file_item(int exoid); -struct exi_file_item *exi_add_file_item(int exoid); -struct exi_obj_stats *exi_get_stat_ptr(int exoid, struct exi_obj_stats **obj_ptr); +struct exi_file_item *exi_add_file_item(int exoid); +struct exi_obj_stats *exi_get_stat_ptr(int exoid, struct exi_obj_stats **obj_ptr); EXODUS_EXPORT void exi_rm_stat_ptr(int exoid, struct exi_obj_stats **obj_ptr); @@ -854,9 +857,14 @@ EXODUS_EXPORT int exi_put_names(int exoid, int varid, size_t num_entity, char * ex_entity_type obj_type, const char *subtype, const char *routine); EXODUS_EXPORT void exi_trim(char *name); EXODUS_EXPORT void exi_update_max_name_length(int exoid, int length); +EXODUS_EXPORT int exi_redef(int exoid, const char *call_func); +EXODUS_EXPORT int exi_persist_redef(int exoid, const char *call_func); EXODUS_EXPORT int exi_leavedef(int exoid, /* NemesisI file ID */ const char *call_rout /* Name of calling function */ ); +EXODUS_EXPORT int exi_persist_leavedef(int exoid, /* NemesisI file ID */ + const char *call_rout /* Name of calling function */ + ); EXODUS_EXPORT int exi_check_version(int run_version); EXODUS_EXPORT int exi_handle_mode(unsigned int my_mode, int is_parallel, int run_version); diff --git a/packages/seacas/libraries/exodus/src/ex__put_homogenous_block_params.c b/packages/seacas/libraries/exodus/src/ex__put_homogenous_block_params.c index ed4e31d720..0e16d4a9e0 100644 --- a/packages/seacas/libraries/exodus/src/ex__put_homogenous_block_params.c +++ b/packages/seacas/libraries/exodus/src/ex__put_homogenous_block_params.c @@ -118,7 +118,7 @@ int exi_put_homogenous_block_params(int exoid, size_t block_count, const struct /* ======================================================================== */ /* put netcdf file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to place file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); return (EX_FATAL); diff --git a/packages/seacas/libraries/exodus/src/ex_add_attr.c b/packages/seacas/libraries/exodus/src/ex_add_attr.c index 5d10849df2..a0f0e94776 100644 --- a/packages/seacas/libraries/exodus/src/ex_add_attr.c +++ b/packages/seacas/libraries/exodus/src/ex_add_attr.c @@ -123,7 +123,7 @@ int ex_add_attr(int exoid, ex_entity_type obj_type, ex_entity_id obj_id, int64_t /* element attribute array */ /* put netcdf file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to place file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); diff --git a/packages/seacas/libraries/exodus/src/ex_close.c b/packages/seacas/libraries/exodus/src/ex_close.c index 171f9559c9..33ac81497e 100644 --- a/packages/seacas/libraries/exodus/src/ex_close.c +++ b/packages/seacas/libraries/exodus/src/ex_close.c @@ -1,5 +1,5 @@ /* - * Copyright(C) 1999-2020, 2022, 2023 National Technology & Engineering Solutions + * Copyright(C) 1999-2020, 2022, 2023, 2024 National Technology & Engineering Solutions * of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with * NTESS, the U.S. Government retains certain rights in this software. * @@ -57,6 +57,11 @@ int ex_close(int exoid) EX_FUNC_LEAVE(EX_FATAL); } +#ifndef NDEBUG + struct exi_file_item *file = exi_find_file_item(exoid); + assert(!file->in_define_mode && file->persist_define_mode == 0); +#endif + /* * NOTE: If using netcdf-4, exoid must refer to the root group. * Need to determine whether there are any groups and if so, diff --git a/packages/seacas/libraries/exodus/src/ex_conv.c b/packages/seacas/libraries/exodus/src/ex_conv.c index bbb545e9c3..f053f185d3 100644 --- a/packages/seacas/libraries/exodus/src/ex_conv.c +++ b/packages/seacas/libraries/exodus/src/ex_conv.c @@ -249,6 +249,8 @@ int exi_conv_init(int exoid, int *comp_wordsize, int *io_wordsize, int file_word new_file->has_edges = 1; new_file->has_faces = 1; new_file->has_elems = 1; + new_file->in_define_mode = 0; + new_file->persist_define_mode = 0; new_file->is_write = is_write; new_file->next = file_list; diff --git a/packages/seacas/libraries/exodus/src/ex_copy.c b/packages/seacas/libraries/exodus/src/ex_copy.c index e7807dc9d4..8ccb00505f 100644 --- a/packages/seacas/libraries/exodus/src/ex_copy.c +++ b/packages/seacas/libraries/exodus/src/ex_copy.c @@ -1,5 +1,5 @@ /* - * Copyright(C) 1999-2023 National Technology & Engineering Solutions + * Copyright(C) 1999-2024 National Technology & Engineering Solutions * of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with * NTESS, the U.S. Government retains certain rights in this software. * @@ -108,7 +108,7 @@ static int ex_copy_internal(int in_exoid, int out_exoid, int mesh_only) } /* put output file into define mode */ - EXCHECK(nc_redef(out_exoid)); + EXCHECK(exi_redef(out_exoid, __func__)); /* copy global attributes */ EXCHECK(cpy_global_att(in_exoid, out_exoid)); diff --git a/packages/seacas/libraries/exodus/src/ex_create_group.c b/packages/seacas/libraries/exodus/src/ex_create_group.c index 3d05f0ce54..0adc0c3595 100644 --- a/packages/seacas/libraries/exodus/src/ex_create_group.c +++ b/packages/seacas/libraries/exodus/src/ex_create_group.c @@ -1,5 +1,5 @@ /* - * Copyright(C) 1999-2020, 2022 National Technology & Engineering Solutions + * Copyright(C) 1999-2020, 2022, 2024 National Technology & Engineering Solutions * of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with * NTESS, the U.S. Government retains certain rights in this software. * @@ -26,7 +26,7 @@ int ex_create_group(int parent_id, const char *group_name) EX_FUNC_LEAVE(EX_FATAL); } - if ((status = nc_redef(parent_id)) != NC_NOERR) { + if ((status = exi_redef(parent_id, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", parent_id); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); diff --git a/packages/seacas/libraries/exodus/src/ex_get_field_metadata.c b/packages/seacas/libraries/exodus/src/ex_get_field_metadata.c index 7d1dbdd70e..1d25ed3c29 100644 --- a/packages/seacas/libraries/exodus/src/ex_get_field_metadata.c +++ b/packages/seacas/libraries/exodus/src/ex_get_field_metadata.c @@ -122,11 +122,11 @@ int ex_get_field_metadata(int exoid, ex_field *field) EX_FUNC_ENTER(); int varid; - int att_count = exi_get_attribute_count(exoid, field->entity_type, field->entity_id, &varid); + int att_count = exi_get_attribute_count(exoid, field[0].entity_type, field[0].entity_id, &varid); if (att_count < 0) { char errmsg[MAX_ERR_LENGTH]; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: Negative attribute count (%d) on %s with id %" PRId64, - att_count, ex_name_of_object(field->entity_type), field->entity_id); + att_count, ex_name_of_object(field[0].entity_type), field[0].entity_id); ex_err_fn(exoid, __func__, errmsg, EX_INTERNAL); EX_FUNC_LEAVE(EX_FATAL); } @@ -140,7 +140,7 @@ int ex_get_field_metadata(int exoid, ex_field *field) char errmsg[MAX_ERR_LENGTH]; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get attribute named %s on %s with id %" PRId64, attr_name, - ex_name_of_object(field->entity_type), field->entity_id); + ex_name_of_object(field[0].entity_type), field[0].entity_id); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } @@ -165,6 +165,10 @@ int ex_get_field_metadata(int exoid, ex_field *field) if (found == -1) { which = count; strcpy(field[count].name, fld_name); + /* Set default separator type... */ + field[count].component_separator[0] = '_'; + field[count].component_separator[1] = '\0'; + count++; } @@ -174,7 +178,7 @@ int ex_get_field_metadata(int exoid, ex_field *field) char errmsg[MAX_ERR_LENGTH]; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get parameters for attribute named %s on %s with id %" PRId64, - attr_name, ex_name_of_object(field->entity_type), field->entity_id); + attr_name, ex_name_of_object(field[0].entity_type), field[0].entity_id); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } @@ -205,7 +209,7 @@ int ex_get_field_metadata(int exoid, ex_field *field) snprintf( errmsg, MAX_ERR_LENGTH, "ERROR: Invalid field metadata attribute type %s on field %s on %s with id %" PRId64, - fld_type, fld_name, ex_name_of_object(field->entity_type), field->entity_id); + fld_type, fld_name, ex_name_of_object(field[0].entity_type), field[0].entity_id); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } @@ -214,7 +218,7 @@ int ex_get_field_metadata(int exoid, ex_field *field) snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to read field metadata attribute type %s on field %s on %s with id " "%" PRId64, - fld_type, fld_name, ex_name_of_object(field->entity_type), field->entity_id); + fld_type, fld_name, ex_name_of_object(field[0].entity_type), field[0].entity_id); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } diff --git a/packages/seacas/libraries/exodus/src/ex_open.c b/packages/seacas/libraries/exodus/src/ex_open.c index f8014692d4..c67992a4ae 100644 --- a/packages/seacas/libraries/exodus/src/ex_open.c +++ b/packages/seacas/libraries/exodus/src/ex_open.c @@ -298,7 +298,7 @@ int ex_open_int(const char *path, int mode, int *comp_ws, int *io_ws, float *ver int dim_str_name = 0; int stat_dim = nc_inq_dimid(exoid, DIM_STR_NAME, &dim_str_name); if (stat_att != NC_NOERR || stat_dim != NC_NOERR) { - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to place file id %d named %s into define mode", exoid, canon_path); ex_err_fn(exoid, __func__, errmsg, status); diff --git a/packages/seacas/libraries/exodus/src/ex_open_par.c b/packages/seacas/libraries/exodus/src/ex_open_par.c index 724d301eee..10197118f1 100644 --- a/packages/seacas/libraries/exodus/src/ex_open_par.c +++ b/packages/seacas/libraries/exodus/src/ex_open_par.c @@ -313,7 +313,7 @@ int ex_open_par_int(const char *path, int mode, int *comp_ws, int *io_ws, float if (mode & EX_WRITE) { /* Appending */ /* turn off automatic filling of netCDF variables */ if (is_pnetcdf) { - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); free(canon_path); @@ -335,7 +335,7 @@ int ex_open_par_int(const char *path, int mode, int *comp_ws, int *io_ws, float int stat_dim = nc_inq_dimid(exoid, DIM_STR_NAME, &dim_str_name); if (stat_att != NC_NOERR || stat_dim != NC_NOERR) { if (!in_redef) { - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); diff --git a/packages/seacas/libraries/exodus/src/ex_put_all_var_param_ext.c b/packages/seacas/libraries/exodus/src/ex_put_all_var_param_ext.c index 074a79d84f..7bcf30eb1e 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_all_var_param_ext.c +++ b/packages/seacas/libraries/exodus/src/ex_put_all_var_param_ext.c @@ -144,7 +144,7 @@ int ex_put_all_var_param_ext(int exoid, const ex_var_params *vp) EX_ELEM_SET, VAR_ELS_STAT, elset_stat); /* put file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); goto error_ret; diff --git a/packages/seacas/libraries/exodus/src/ex_put_assemblies.c b/packages/seacas/libraries/exodus/src/ex_put_assemblies.c index c3e1f2c398..a731215b54 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_assemblies.c +++ b/packages/seacas/libraries/exodus/src/ex_put_assemblies.c @@ -45,7 +45,7 @@ int ex_put_assemblies(int exoid, size_t count, const struct ex_assembly *assembl /* Assembly has not already been defined */ /* put netcdf file into define mode */ if (!in_define) { - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); diff --git a/packages/seacas/libraries/exodus/src/ex_put_attr_param.c b/packages/seacas/libraries/exodus/src/ex_put_attr_param.c index 498d019c2d..dd7847c7da 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_attr_param.c +++ b/packages/seacas/libraries/exodus/src/ex_put_attr_param.c @@ -149,7 +149,7 @@ int ex_put_attr_param(int exoid, ex_entity_type obj_type, ex_entity_id obj_id, i } /* put netcdf file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to place file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); diff --git a/packages/seacas/libraries/exodus/src/ex_put_attribute.c b/packages/seacas/libraries/exodus/src/ex_put_attribute.c index 370cfe31ef..a63b09cc81 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_attribute.c +++ b/packages/seacas/libraries/exodus/src/ex_put_attribute.c @@ -38,7 +38,7 @@ int ex_put_double_attribute(int exoid, ex_entity_type obj_type, ex_entity_id id, } /* put netcdf file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); @@ -84,7 +84,7 @@ int ex_put_integer_attribute(int exoid, ex_entity_type obj_type, ex_entity_id id } /* put netcdf file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); @@ -137,7 +137,7 @@ int ex_put_text_attribute(int exoid, ex_entity_type obj_type, ex_entity_id id, c } /* put netcdf file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); diff --git a/packages/seacas/libraries/exodus/src/ex_put_blobs.c b/packages/seacas/libraries/exodus/src/ex_put_blobs.c index 5bd70b3fdd..89c22537bb 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_blobs.c +++ b/packages/seacas/libraries/exodus/src/ex_put_blobs.c @@ -29,7 +29,7 @@ int ex_put_blobs(int exoid, size_t count, const struct ex_blob *blobs) int *entlst_id = (int *)calloc(count, sizeof(int)); - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); free(entlst_id); diff --git a/packages/seacas/libraries/exodus/src/ex_put_block_params.c b/packages/seacas/libraries/exodus/src/ex_put_block_params.c index 3f38015130..b6d16dd3cc 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_block_params.c +++ b/packages/seacas/libraries/exodus/src/ex_put_block_params.c @@ -253,7 +253,7 @@ int ex_put_block_params(int exoid, size_t block_count, const struct ex_block *bl } /* put netcdf file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to place file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); free(blocks_to_define); diff --git a/packages/seacas/libraries/exodus/src/ex_put_cmap_params.c b/packages/seacas/libraries/exodus/src/ex_put_cmap_params.c index bf70211e32..196d1966bf 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_cmap_params.c +++ b/packages/seacas/libraries/exodus/src/ex_put_cmap_params.c @@ -87,7 +87,7 @@ int ex_put_cmap_params(int exoid, const void_int *node_cmap_ids, /* Put NetCDF file into define mode */ int status; - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to file ID %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); diff --git a/packages/seacas/libraries/exodus/src/ex_put_cmap_params_cc.c b/packages/seacas/libraries/exodus/src/ex_put_cmap_params_cc.c index 6c68093808..1df47f1eee 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_cmap_params_cc.c +++ b/packages/seacas/libraries/exodus/src/ex_put_cmap_params_cc.c @@ -215,7 +215,7 @@ file ID %d", } /* "if (num_e_comm_maps >0)" */ /* Put NetCDF file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file ID %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); diff --git a/packages/seacas/libraries/exodus/src/ex_put_concat_all_blocks.c b/packages/seacas/libraries/exodus/src/ex_put_concat_all_blocks.c index 53573ac67c..f4b4a997bc 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_concat_all_blocks.c +++ b/packages/seacas/libraries/exodus/src/ex_put_concat_all_blocks.c @@ -205,7 +205,7 @@ int ex_put_concat_all_blocks(int exoid, const ex_block_params *param) EX_FUNC_LEAVE(EX_NOERR); } /* put netcdf file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to place file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); diff --git a/packages/seacas/libraries/exodus/src/ex_put_concat_elem_block.c b/packages/seacas/libraries/exodus/src/ex_put_concat_elem_block.c index f5c7ad17bf..92ce78b781 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_concat_elem_block.c +++ b/packages/seacas/libraries/exodus/src/ex_put_concat_elem_block.c @@ -144,7 +144,7 @@ int ex_put_concat_elem_block(int exoid, const void_int *elem_blk_id, char *const } /* put netcdf file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to place file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); free(eb_array); diff --git a/packages/seacas/libraries/exodus/src/ex_put_concat_sets.c b/packages/seacas/libraries/exodus/src/ex_put_concat_sets.c index 43a8807b63..31c59c187c 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_concat_sets.c +++ b/packages/seacas/libraries/exodus/src/ex_put_concat_sets.c @@ -171,7 +171,7 @@ int ex_put_concat_sets(int exoid, ex_entity_type set_type, const struct ex_set_s } /* put netcdf file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); free(set_stat); diff --git a/packages/seacas/libraries/exodus/src/ex_put_coordinate_frames.c b/packages/seacas/libraries/exodus/src/ex_put_coordinate_frames.c index b11c10c42a..9e2edda442 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_coordinate_frames.c +++ b/packages/seacas/libraries/exodus/src/ex_put_coordinate_frames.c @@ -57,7 +57,7 @@ int ex_put_coordinate_frames(int exoid, int nframes, const void_int *cf_ids, /* make the definitions */ /* go into define mode. define num_frames, num_frames9 */ int status; - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to place file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); diff --git a/packages/seacas/libraries/exodus/src/ex_put_field_metadata.c b/packages/seacas/libraries/exodus/src/ex_put_field_metadata.c index 36ad8a30f8..ff388de656 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_field_metadata.c +++ b/packages/seacas/libraries/exodus/src/ex_put_field_metadata.c @@ -32,6 +32,28 @@ static int exi_print_attribute_error(int status, const char *name, const char *a return EX_FATAL; } +int ex_put_multi_field_metadata(int exoid, const ex_field field[], const int count) +{ + exi_persist_redef(exoid, __func__); + for (int i = 0; i < count; i++) { + if (field[i].type[0] != EX_SCALAR) { + int status = ex_put_field_metadata(exoid, field[i]); + if (status != EX_NOERR) { + char errmsg[MAX_ERR_LENGTH]; + snprintf(errmsg, MAX_ERR_LENGTH, + "ERROR: failed to store field metadata for field '%s' on %s with id %" PRId64 + " in file id %d", + field[i].name, ex_name_of_object(field[i].entity_type), field[i].entity_id, exoid); + ex_err_fn(exoid, __func__, errmsg, status); + exi_persist_leavedef(exoid, __func__); + return EX_FATAL; + } + } + } + exi_persist_leavedef(exoid, __func__); + return EX_NOERR; +} + int ex_put_field_metadata(int exoid, const ex_field field) { /* @@ -53,28 +75,38 @@ int ex_put_field_metadata(int exoid, const ex_field field) field.entity_id); #endif + exi_persist_redef(exoid, __func__); int status = 0; static char *field_template = "Field@%s@%s"; char attribute_name[NC_MAX_NAME + 1]; sprintf(attribute_name, field_template, field.name, "type"); if ((status = ex_put_integer_attribute(exoid, field.entity_type, field.entity_id, attribute_name, field.nesting, field.type)) != EX_NOERR) { + exi_persist_leavedef(exoid, __func__); return exi_print_attribute_error(status, field.name, "type", field.entity_type, field.entity_id, exoid, __func__); } - sprintf(attribute_name, field_template, field.name, "type_name"); - if ((status = ex_put_text_attribute(exoid, field.entity_type, field.entity_id, attribute_name, - field.type_name)) != EX_NOERR) { - return exi_print_attribute_error(status, field.name, "type_name", field.entity_type, - field.entity_id, exoid, __func__); + /* Do not write if empty... */ + if (field.type_name[0] != '\0') { + sprintf(attribute_name, field_template, field.name, "type_name"); + if ((status = ex_put_text_attribute(exoid, field.entity_type, field.entity_id, attribute_name, + field.type_name)) != EX_NOERR) { + exi_persist_leavedef(exoid, __func__); + return exi_print_attribute_error(status, field.name, "type_name", field.entity_type, + field.entity_id, exoid, __func__); + } } - sprintf(attribute_name, field_template, field.name, "separator"); - if ((status = ex_put_text_attribute(exoid, field.entity_type, field.entity_id, attribute_name, - field.component_separator)) != EX_NOERR) { - return exi_print_attribute_error(status, field.name, "separator", field.entity_type, - field.entity_id, exoid, __func__); + /* Default component_separator is '_'. Avoid writing if that is what it is... */ + if (field.component_separator[0] != '_' || field.nesting > 1) { + sprintf(attribute_name, field_template, field.name, "separator"); + if ((status = ex_put_text_attribute(exoid, field.entity_type, field.entity_id, attribute_name, + field.component_separator)) != EX_NOERR) { + exi_persist_leavedef(exoid, __func__); + return exi_print_attribute_error(status, field.name, "separator", field.entity_type, + field.entity_id, exoid, __func__); + } } bool needs_cardinality = false; @@ -89,11 +121,13 @@ int ex_put_field_metadata(int exoid, const ex_field field) if ((status = ex_put_integer_attribute(exoid, field.entity_type, field.entity_id, attribute_name, field.nesting, field.cardinality)) != EX_NOERR) { + exi_persist_leavedef(exoid, __func__); return exi_print_attribute_error(status, field.name, "cardinality", field.entity_type, field.entity_id, exoid, __func__); } } + exi_persist_leavedef(exoid, __func__); return EX_NOERR; } @@ -145,46 +179,56 @@ int ex_put_basis(int exoid, const ex_basis basis) * } ex_basis; */ + exi_persist_redef(exoid, __func__); int status; if ((status = exi_put_basis_attribute(exoid, basis.name, "cardinality", EX_INTEGER, 1, &basis.cardinality)) != EX_NOERR) { + exi_persist_leavedef(exoid, __func__); return exi_print_type_error(status, basis.name, "basis", "cardinality", exoid, __func__); } if ((status = exi_put_basis_attribute(exoid, basis.name, "subc_dim", EX_INTEGER, basis.cardinality, basis.subc_dim)) != EX_NOERR) { + exi_persist_leavedef(exoid, __func__); return exi_print_type_error(status, basis.name, "basis", "subc_dim", exoid, __func__); } if ((status = exi_put_basis_attribute(exoid, basis.name, "subc_ordinal", EX_INTEGER, basis.cardinality, basis.subc_ordinal)) != EX_NOERR) { + exi_persist_leavedef(exoid, __func__); return exi_print_type_error(status, basis.name, "basis", "subc_ordinal", exoid, __func__); } if ((status = exi_put_basis_attribute(exoid, basis.name, "subc_dof_ordinal", EX_INTEGER, basis.cardinality, basis.subc_dof_ordinal)) != EX_NOERR) { + exi_persist_leavedef(exoid, __func__); return exi_print_type_error(status, basis.name, "basis", "subc_dof_ordinal", exoid, __func__); } if ((status = exi_put_basis_attribute(exoid, basis.name, "subc_num_dof", EX_INTEGER, basis.cardinality, basis.subc_num_dof)) != EX_NOERR) { + exi_persist_leavedef(exoid, __func__); return exi_print_type_error(status, basis.name, "basis", "subc_num_dof", exoid, __func__); } if ((status = exi_put_basis_attribute(exoid, basis.name, "xi", EX_DOUBLE, basis.cardinality, basis.xi)) != EX_NOERR) { + exi_persist_leavedef(exoid, __func__); return exi_print_type_error(status, basis.name, "basis", "xi", exoid, __func__); } if ((status = exi_put_basis_attribute(exoid, basis.name, "eta", EX_DOUBLE, basis.cardinality, basis.eta)) != EX_NOERR) { + exi_persist_leavedef(exoid, __func__); return exi_print_type_error(status, basis.name, "basis", "eta", exoid, __func__); } if ((status = exi_put_basis_attribute(exoid, basis.name, "zeta", EX_DOUBLE, basis.cardinality, basis.zeta)) != EX_NOERR) { + exi_persist_leavedef(exoid, __func__); return exi_print_type_error(status, basis.name, "basis", "zeta", exoid, __func__); } + exi_persist_leavedef(exoid, __func__); return EX_NOERR; } @@ -204,31 +248,38 @@ int ex_put_quadrature(int exoid, const ex_quadrature quad) * } ex_quad; */ + exi_persist_redef(exoid, __func__); int status; if ((status = exi_put_quad_attribute(exoid, quad.name, "cardinality", EX_INTEGER, 1, &quad.cardinality)) != EX_NOERR) { + exi_persist_leavedef(exoid, __func__); return exi_print_type_error(status, quad.name, "quad", "cardinality", exoid, __func__); } if ((status = exi_put_quad_attribute(exoid, quad.name, "xi", EX_DOUBLE, quad.cardinality, quad.xi)) != EX_NOERR) { + exi_persist_leavedef(exoid, __func__); return exi_print_type_error(status, quad.name, "quad", "xi", exoid, __func__); } if ((status = exi_put_quad_attribute(exoid, quad.name, "eta", EX_DOUBLE, quad.cardinality, quad.eta)) != EX_NOERR) { + exi_persist_leavedef(exoid, __func__); return exi_print_type_error(status, quad.name, "quad", "eta", exoid, __func__); } if ((status = exi_put_quad_attribute(exoid, quad.name, "zeta", EX_DOUBLE, quad.cardinality, quad.zeta)) != EX_NOERR) { + exi_persist_leavedef(exoid, __func__); return exi_print_type_error(status, quad.name, "quad", "zeta", exoid, __func__); } if ((status = exi_put_quad_attribute(exoid, quad.name, "weight", EX_DOUBLE, quad.cardinality, quad.weight)) != EX_NOERR) { + exi_persist_leavedef(exoid, __func__); return exi_print_type_error(status, quad.name, "quad", "weight", exoid, __func__); } + exi_persist_leavedef(exoid, __func__); return EX_NOERR; } diff --git a/packages/seacas/libraries/exodus/src/ex_put_id_map.c b/packages/seacas/libraries/exodus/src/ex_put_id_map.c index eaae70e013..fb38531d55 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_id_map.c +++ b/packages/seacas/libraries/exodus/src/ex_put_id_map.c @@ -83,7 +83,7 @@ int ex_put_id_map(int exoid, ex_entity_type map_type, const void_int *map) /* put netcdf file into define mode */ if (nc_inq_varid(exoid, vmap, &mapid) != NC_NOERR) { - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); diff --git a/packages/seacas/libraries/exodus/src/ex_put_info.c b/packages/seacas/libraries/exodus/src/ex_put_info.c index da69df0d83..4878d1d884 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_info.c +++ b/packages/seacas/libraries/exodus/src/ex_put_info.c @@ -1,5 +1,5 @@ /* - * Copyright(C) 1999-2020, 2022 National Technology & Engineering Solutions + * Copyright(C) 1999-2020, 2022, 2024 National Technology & Engineering Solutions * of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with * NTESS, the U.S. Government retains certain rights in this software. * @@ -95,7 +95,7 @@ int ex_put_info(int exoid, int num_info, char *const info[]) if (status != NC_NOERR) { /* put file into define mode */ - if ((status = nc_redef(rootid)) != NC_NOERR) { + if ((status = exi_redef(rootid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed put file id %d into define mode", rootid); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); diff --git a/packages/seacas/libraries/exodus/src/ex_put_init_ext.c b/packages/seacas/libraries/exodus/src/ex_put_init_ext.c index 6d1ecb301a..e07e843444 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_init_ext.c +++ b/packages/seacas/libraries/exodus/src/ex_put_init_ext.c @@ -247,7 +247,7 @@ int ex_put_init_ext(int exoid, const ex_init_params *model) } /* put file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { char errmsg[MAX_ERR_LENGTH]; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); diff --git a/packages/seacas/libraries/exodus/src/ex_put_init_global.c b/packages/seacas/libraries/exodus/src/ex_put_init_global.c index 5053d37b27..f6731cd164 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_init_global.c +++ b/packages/seacas/libraries/exodus/src/ex_put_init_global.c @@ -60,7 +60,7 @@ int ex_put_init_global(int exoid, int64_t num_nodes_g, int64_t num_elems_g, int6 id_type = NC_INT64; } /* Put NetCDF file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file ID %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); diff --git a/packages/seacas/libraries/exodus/src/ex_put_init_info.c b/packages/seacas/libraries/exodus/src/ex_put_init_info.c index 0c88892b43..29c55db5eb 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_init_info.c +++ b/packages/seacas/libraries/exodus/src/ex_put_init_info.c @@ -68,7 +68,7 @@ int ex_put_init_info(int exoid, int num_proc, int num_proc_in_f, const char *fty } /* Put file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file ID %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); diff --git a/packages/seacas/libraries/exodus/src/ex_put_loadbal_param.c b/packages/seacas/libraries/exodus/src/ex_put_loadbal_param.c index f5463e8637..9307850593 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_loadbal_param.c +++ b/packages/seacas/libraries/exodus/src/ex_put_loadbal_param.c @@ -91,7 +91,7 @@ int ex_put_loadbal_param(int exoid, int64_t num_int_nodes, int64_t num_bor_nodes } /* Put NetCDF file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); diff --git a/packages/seacas/libraries/exodus/src/ex_put_loadbal_param_cc.c b/packages/seacas/libraries/exodus/src/ex_put_loadbal_param_cc.c index ed64526b49..dc1d9dc358 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_loadbal_param_cc.c +++ b/packages/seacas/libraries/exodus/src/ex_put_loadbal_param_cc.c @@ -120,7 +120,7 @@ int ex_put_loadbal_param_cc(int exoid, const void_int *num_int_nodes, const void } /* Put NetCDF file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); diff --git a/packages/seacas/libraries/exodus/src/ex_put_map.c b/packages/seacas/libraries/exodus/src/ex_put_map.c index 9861092f05..f03881a42f 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_map.c +++ b/packages/seacas/libraries/exodus/src/ex_put_map.c @@ -75,7 +75,7 @@ int ex_put_map(int exoid, const void_int *elem_map) } /* put netcdf file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); diff --git a/packages/seacas/libraries/exodus/src/ex_put_map_param.c b/packages/seacas/libraries/exodus/src/ex_put_map_param.c index f9d30aa53e..8347e5c4b2 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_map_param.c +++ b/packages/seacas/libraries/exodus/src/ex_put_map_param.c @@ -73,7 +73,7 @@ int ex_put_map_param(int exoid, int num_node_maps, int num_elem_maps) } /* put file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); diff --git a/packages/seacas/libraries/exodus/src/ex_put_name.c b/packages/seacas/libraries/exodus/src/ex_put_name.c index 0c161ab385..c0dc4a93af 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_name.c +++ b/packages/seacas/libraries/exodus/src/ex_put_name.c @@ -39,7 +39,7 @@ int exi_put_assembly_name(int exoid, ex_entity_type obj_type, ex_entity_id entit char errmsg[MAX_ERR_LENGTH]; if (nc_inq_varid(exoid, VAR_ENTITY_ASSEMBLY(entity_id), &entlst_id) == NC_NOERR) { int status; - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); diff --git a/packages/seacas/libraries/exodus/src/ex_put_num_map.c b/packages/seacas/libraries/exodus/src/ex_put_num_map.c index b4aa483fdc..85a5c9d73f 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_num_map.c +++ b/packages/seacas/libraries/exodus/src/ex_put_num_map.c @@ -190,7 +190,7 @@ int ex_put_num_map(int exoid, ex_entity_type map_type, ex_entity_id map_id, cons EX_FUNC_LEAVE(EX_FATAL); } - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to place file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); diff --git a/packages/seacas/libraries/exodus/src/ex_put_partial_id_map.c b/packages/seacas/libraries/exodus/src/ex_put_partial_id_map.c index 7c1ffcdab5..6a97fd8ee0 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_partial_id_map.c +++ b/packages/seacas/libraries/exodus/src/ex_put_partial_id_map.c @@ -106,7 +106,7 @@ int ex_put_partial_id_map(int exoid, ex_entity_type map_type, int64_t start_enti /* define the map if it doesn't already exist... */ if (nc_inq_varid(exoid, vmap, &mapid) != NC_NOERR) { - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); diff --git a/packages/seacas/libraries/exodus/src/ex_put_partial_var.c b/packages/seacas/libraries/exodus/src/ex_put_partial_var.c index 8eabaae831..bc62bca917 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_partial_var.c +++ b/packages/seacas/libraries/exodus/src/ex_put_partial_var.c @@ -127,7 +127,7 @@ static int exi_look_up_var(int exoid, ex_entity_type var_type, int var_index, ex ex_name_of_object(var_type), &num_entity, &numobjdim, __func__); /* variable doesn't exist so put file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); return (EX_FATAL); diff --git a/packages/seacas/libraries/exodus/src/ex_put_prop.c b/packages/seacas/libraries/exodus/src/ex_put_prop.c index 6b1a86598a..9300d2fb30 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_prop.c +++ b/packages/seacas/libraries/exodus/src/ex_put_prop.c @@ -152,7 +152,7 @@ int ex_put_prop(int exoid, ex_entity_type obj_type, ex_entity_id obj_id, const c name_length = ex_inquire_int(exoid, EX_INQ_DB_MAX_ALLOWED_NAME_LENGTH) + 1; /* put netcdf file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to place file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); diff --git a/packages/seacas/libraries/exodus/src/ex_put_prop_array.c b/packages/seacas/libraries/exodus/src/ex_put_prop_array.c index 1e35e2197a..c49cedcc53 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_prop_array.c +++ b/packages/seacas/libraries/exodus/src/ex_put_prop_array.c @@ -144,7 +144,7 @@ int ex_put_prop_array(int exoid, ex_entity_type obj_type, const char *prop_name, if (!found) { /* put netcdf file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to place file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); diff --git a/packages/seacas/libraries/exodus/src/ex_put_prop_names.c b/packages/seacas/libraries/exodus/src/ex_put_prop_names.c index d88b2aeccb..bcf063f050 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_prop_names.c +++ b/packages/seacas/libraries/exodus/src/ex_put_prop_names.c @@ -130,7 +130,7 @@ int ex_put_prop_names(int exoid, ex_entity_type obj_type, int num_props, char ** nc_set_fill(exoid, NC_FILL, &oldfill); /* fill with zeros per routine spec */ /* put netcdf file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to place file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); diff --git a/packages/seacas/libraries/exodus/src/ex_put_qa.c b/packages/seacas/libraries/exodus/src/ex_put_qa.c index 1b66067c9e..a4efa37936 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_qa.c +++ b/packages/seacas/libraries/exodus/src/ex_put_qa.c @@ -1,5 +1,5 @@ /* - * Copyright(C) 1999-2020, 2022 National Technology & Engineering Solutions + * Copyright(C) 1999-2020, 2022, 2024 National Technology & Engineering Solutions * of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with * NTESS, the U.S. Government retains certain rights in this software. * @@ -86,7 +86,7 @@ int ex_put_qa(int exoid, int num_qa_records, char *qa_record[][4]) if (status != NC_NOERR) { /* put file into define mode */ - if ((status = nc_redef(rootid)) != NC_NOERR) { + if ((status = exi_redef(rootid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", rootid); ex_err_fn(exoid, __func__, errmsg, status); diff --git a/packages/seacas/libraries/exodus/src/ex_put_reduction_variable_param.c b/packages/seacas/libraries/exodus/src/ex_put_reduction_variable_param.c index 2f2f4ac8a6..d3d28c8568 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_reduction_variable_param.c +++ b/packages/seacas/libraries/exodus/src/ex_put_reduction_variable_param.c @@ -165,7 +165,7 @@ int ex_put_reduction_variable_param(int exoid, ex_entity_type obj_type, int num_ } /* put file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); diff --git a/packages/seacas/libraries/exodus/src/ex_put_reduction_vars.c b/packages/seacas/libraries/exodus/src/ex_put_reduction_vars.c index b8b97e9056..f39948bcd0 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_reduction_vars.c +++ b/packages/seacas/libraries/exodus/src/ex_put_reduction_vars.c @@ -84,7 +84,7 @@ static int exi_look_up_var(int exoid, ex_entity_type var_type, ex_entity_id obj_ } /* variable doesn't exist so put file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); return (EX_FATAL); diff --git a/packages/seacas/libraries/exodus/src/ex_put_sets.c b/packages/seacas/libraries/exodus/src/ex_put_sets.c index 0a81e9439b..7729946462 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_sets.c +++ b/packages/seacas/libraries/exodus/src/ex_put_sets.c @@ -96,7 +96,7 @@ int ex_put_sets(int exoid, size_t set_count, const struct ex_set *sets) if (needs_define > 0) { /* put netcdf file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); free(sets_to_define); diff --git a/packages/seacas/libraries/exodus/src/ex_put_truth_table.c b/packages/seacas/libraries/exodus/src/ex_put_truth_table.c index ccc89a1b21..09cb4e6973 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_truth_table.c +++ b/packages/seacas/libraries/exodus/src/ex_put_truth_table.c @@ -236,7 +236,7 @@ int ex_put_truth_table(int exoid, ex_entity_type obj_type, int num_blk, int num_ } /* put netcdf file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { free(stat_vals); snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); diff --git a/packages/seacas/libraries/exodus/src/ex_put_var_multi_time.c b/packages/seacas/libraries/exodus/src/ex_put_var_multi_time.c index 821aec23ef..a34123f5fb 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_var_multi_time.c +++ b/packages/seacas/libraries/exodus/src/ex_put_var_multi_time.c @@ -128,7 +128,7 @@ static int exi_look_up_var(int exoid, ex_entity_type var_type, int var_index, ex ex_name_of_object(var_type), &num_entity, &numobjdim, __func__); /* variable doesn't exist so put file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); return EX_FATAL; diff --git a/packages/seacas/libraries/exodus/src/ex_put_variable_param.c b/packages/seacas/libraries/exodus/src/ex_put_variable_param.c index ed896f4a8c..e19a10833f 100644 --- a/packages/seacas/libraries/exodus/src/ex_put_variable_param.c +++ b/packages/seacas/libraries/exodus/src/ex_put_variable_param.c @@ -174,7 +174,7 @@ int ex_put_variable_param(int exoid, ex_entity_type obj_type, int num_vars) } /* put file into define mode */ - if ((status = nc_redef(exoid)) != NC_NOERR) { + if ((status = exi_redef(exoid, __func__)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid); ex_err_fn(exoid, __func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); diff --git a/packages/seacas/libraries/exodus/src/ex_update.c b/packages/seacas/libraries/exodus/src/ex_update.c index 02e2f8a930..52b0d91013 100644 --- a/packages/seacas/libraries/exodus/src/ex_update.c +++ b/packages/seacas/libraries/exodus/src/ex_update.c @@ -1,5 +1,5 @@ /* - * Copyright(C) 1999-2021 National Technology & Engineering Solutions + * Copyright(C) 1999-2021, 2024 National Technology & Engineering Solutions * of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with * NTESS, the U.S. Government retains certain rights in this software. * @@ -20,7 +20,7 @@ #include "exodusII.h" // for ex_err, etc #include "exodusII_int.h" // for EX_FATAL, EX_NOERR - +#include /*! * \ingroup Utilities * updates an opened EXODUS file (or EXODUS history file) @@ -35,6 +35,11 @@ int ex_update(int exoid) EX_FUNC_LEAVE(EX_FATAL); } +#ifndef NDEBUG + struct exi_file_item *file = exi_find_file_item(exoid); + assert(!file->in_define_mode && file->persist_define_mode == 0); +#endif + int status; if ((status = nc_sync(exoid)) != NC_NOERR) { char errmsg[MAX_ERR_LENGTH]; diff --git a/packages/seacas/libraries/exodus/src/ex_utils.c b/packages/seacas/libraries/exodus/src/ex_utils.c index d56969c62f..5d3bdb83f1 100644 --- a/packages/seacas/libraries/exodus/src/ex_utils.c +++ b/packages/seacas/libraries/exodus/src/ex_utils.c @@ -1781,12 +1781,92 @@ int exi_leavedef(int exoid, const char *call_rout) { int status; - if ((status = nc_enddef(exoid)) != NC_NOERR) { + struct exi_file_item *file = exi_find_file_item(exoid); + if (!file->persist_define_mode && file->in_define_mode) { + if ((status = nc_enddef(exoid)) != NC_NOERR) { + char errmsg[MAX_ERR_LENGTH]; + snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to complete definition for file id %d", + exoid); + ex_err_fn(exoid, call_rout, errmsg, status); + + return (EX_FATAL); + } + file->in_define_mode = 0; + } + return (EX_NOERR); +} + +int exi_redef(int exoid, const char *call_func) +{ + int status; + + struct exi_file_item *file = exi_find_file_item(exoid); + + if (!file) { char errmsg[MAX_ERR_LENGTH]; - snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to complete definition for file id %d", exoid); - ex_err_fn(exoid, call_rout, errmsg, status); + snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: unknown file id %d for exi_redef called from %s.", + exoid, call_func); + ex_err_fn(exoid, __func__, errmsg, EX_BADFILEID); + } - return (EX_FATAL); + if (!file->in_define_mode) { + if ((status = nc_redef(exoid)) != NC_NOERR) { + char errmsg[MAX_ERR_LENGTH]; + snprintf(errmsg, MAX_ERR_LENGTH, + "ERROR: failed to put file %d into definition mode in exi_redef called from %s", + exoid, call_func); + ex_err_fn(exoid, __func__, errmsg, status); + return (EX_FATAL); + } + file->in_define_mode = 1; + } + return (EX_NOERR); +} + +int exi_persist_redef(int exoid, const char *call_func) +{ + int status; + + struct exi_file_item *file = exi_find_file_item(exoid); + + if (!file) { + char errmsg[MAX_ERR_LENGTH]; + snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: unknown file id %d for exi_redef called from %s.", + exoid, call_func); + ex_err_fn(exoid, __func__, errmsg, EX_BADFILEID); + } + + if ((++file->persist_define_mode == 1) && !file->in_define_mode) { + if ((status = nc_redef(exoid)) != NC_NOERR) { + char errmsg[MAX_ERR_LENGTH]; + snprintf( + errmsg, MAX_ERR_LENGTH, + "ERROR: failed to put file %d into definition mode in exi_persist_redef called from %s", + exoid, call_func); + ex_err_fn(exoid, __func__, errmsg, status); + return (EX_FATAL); + } + file->in_define_mode = 1; + } + return (EX_NOERR); +} + +int exi_persist_leavedef(int exoid, const char *call_rout) +{ + int status; + + struct exi_file_item *file = exi_find_file_item(exoid); + if ((file->persist_define_mode-- == 1) && file->in_define_mode) { + if ((status = nc_enddef(exoid)) != NC_NOERR) { + char errmsg[MAX_ERR_LENGTH]; + snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to complete definition for file id %d", + exoid); + ex_err_fn(exoid, call_rout, errmsg, status); + + return (EX_FATAL); + } + file->in_define_mode = 0; + file->persist_define_mode = 0; } return (EX_NOERR); } @@ -2094,9 +2174,10 @@ int exi_handle_mode(unsigned int my_mode, int is_parallel, int run_version) /* Avoid getenv call if already in verbose mode */ char *option = getenv("EXODUS_VERBOSE"); if (option != NULL) { - exoptval = EX_VERBOSE; + exoptval = EX_VERBOSE; if (option[0] != 'q') { - fprintf(stderr, "EXODUS: Setting EX_VERBOSE mode since EXODUS_VERBOSE environment variable is set.\n"); + fprintf(stderr, "EXODUS: Setting EX_VERBOSE mode since EXODUS_VERBOSE environment " + "variable is set.\n"); } } } diff --git a/packages/seacas/libraries/exodus/test/testwt-field-metadata.dmp b/packages/seacas/libraries/exodus/test/testwt-field-metadata.dmp index 9b9e075aa8..37e75ddeb6 100644 --- a/packages/seacas/libraries/exodus/test/testwt-field-metadata.dmp +++ b/packages/seacas/libraries/exodus/test/testwt-field-metadata.dmp @@ -25,10 +25,8 @@ :Quad@2x2x2@zeta = -0.57735, -0.57735, -0.57735, -0.57735, 0.57735, 0.57735, 0.57735, 0.57735 ; connect1:Field@Disp@separator = "" ; connect1:Field@Disp@type = 8 ; - connect1:Field@Disp@type_name = "" ; connect1:Field@Velocity@separator = "%" ; connect1:Field@Velocity@type = 8 ; - connect1:Field@Velocity@type_name = "" ; connect2:Field@Curl@separator = "@" ; connect2:Field@Curl@type = 4 ; connect2:Field@Curl@type_name = "2x2x2" ; @@ -42,10 +40,8 @@ connect2:Field@Species@type_name = ",1x2x1" ; coor_names:Field@Disp@separator = "" ; coor_names:Field@Disp@type = 8 ; - coor_names:Field@Disp@type_name = "" ; coor_names:Field@Velocity@separator = "%" ; coor_names:Field@Velocity@type = 8 ; - coor_names:Field@Velocity@type_name = "" ; "Curl@1", "Curl@2", "Curl@3", diff --git a/packages/seacas/libraries/ioss/src/exodus/Ioex_BaseDatabaseIO.C b/packages/seacas/libraries/ioss/src/exodus/Ioex_BaseDatabaseIO.C index 88a929fea1..d56ed2194c 100644 --- a/packages/seacas/libraries/ioss/src/exodus/Ioex_BaseDatabaseIO.C +++ b/packages/seacas/libraries/ioss/src/exodus/Ioex_BaseDatabaseIO.C @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -2014,107 +2015,112 @@ namespace Ioex { // Get all transient fields on this entity... char default_separator = entity->get_database()->get_field_separator(); auto results_fields = entity->field_describe(Ioss::Field::TRANSIENT); - for (const auto &field_name : results_fields) { + + std::vector exo_fields(results_fields.size()); + for (const auto &[i, field_name] : Ioss::enumerate(results_fields)) { + exo_fields[i].type[0] = EX_SCALAR; + const auto &field = entity->get_fieldref(field_name); - ex_field exo_field{}; - Ioss::Utils::copy_string(exo_field.name, field_name); - exo_field.entity_type = type; - exo_field.entity_id = entity->get_optional_property("id", 0); + Ioss::Utils::copy_string(exo_fields[i].name, field_name); + exo_fields[i].entity_type = type; + exo_fields[i].entity_id = entity->get_optional_property("id", 0); auto *storage = field.transformed_storage(); auto storage_type = storage->type(); if (storage_type == Ioss::VariableType::Type::COMPOSED) { - exo_field.nesting = 2; + exo_fields[i].nesting = 2; const auto *composed = dynamic_cast(storage); assert(composed != nullptr); - exo_field.type[0] = Ioex::map_ioss_field_type(composed->get_base_type()); - exo_field.cardinality[0] = composed->get_base_type()->component_count(); - char separator0 = field.get_suffix_separator(); - exo_field.component_separator[0] = separator0 == 1 ? default_separator : separator0; + exo_fields[i].type[0] = Ioex::map_ioss_field_type(composed->get_base_type()); + exo_fields[i].cardinality[0] = composed->get_base_type()->component_count(); + char separator0 = field.get_suffix_separator(); + exo_fields[i].component_separator[0] = separator0 == 1 ? default_separator : separator0; - if (exo_field.type[0] == EX_FIELD_TYPE_USER_DEFINED) { + if (exo_fields[i].type[0] == EX_FIELD_TYPE_USER_DEFINED) { assert(composed->get_base_type()->type() == Ioss::VariableType::Type::NAMED_SUFFIX); auto nsvt = dynamic_cast(composed->get_base_type()); assert(nsvt != nullptr); std::string suffices{}; - for (int i = 0; i < nsvt->component_count(); i++) { - if (i > 0) { + for (int ii = 0; ii < nsvt->component_count(); ii++) { + if (ii > 0) { suffices += ","; } - suffices += nsvt->label(i + 1, 0); + suffices += nsvt->label(ii + 1, 0); } - Ioss::Utils::copy_string(exo_field.suffices, suffices.c_str(), EX_MAX_NAME + 1); + Ioss::Utils::copy_string(exo_fields[i].suffices, suffices.c_str(), EX_MAX_NAME + 1); } - exo_field.type[1] = Ioex::map_ioss_field_type(composed->get_secondary_type()); - exo_field.cardinality[1] = composed->get_secondary_type()->component_count(); - char separator1 = field.get_suffix_separator(1); - exo_field.component_separator[1] = separator1 == 1 ? default_separator : separator1; - if (exo_field.type[1] == EX_BASIS || exo_field.type[1] == EX_QUADRATURE) { - exo_field.type_name[0] = ','; - Ioss::Utils::copy_string(&exo_field.type_name[1], + exo_fields[i].type[1] = Ioex::map_ioss_field_type(composed->get_secondary_type()); + exo_fields[i].cardinality[1] = composed->get_secondary_type()->component_count(); + char separator1 = field.get_suffix_separator(1); + exo_fields[i].component_separator[1] = separator1 == 1 ? default_separator : separator1; + if (exo_fields[i].type[1] == EX_BASIS || exo_fields[i].type[1] == EX_QUADRATURE) { + exo_fields[i].type_name[0] = ','; + Ioss::Utils::copy_string(&exo_fields[i].type_name[1], composed->get_secondary_type()->name(), EX_MAX_NAME); } } else if (storage_type == Ioss::VariableType::Type::COMPOSITE) { - exo_field.nesting = 2; + exo_fields[i].nesting = 2; const auto *composite = dynamic_cast(storage); assert(composite != nullptr); - exo_field.type[0] = Ioex::map_ioss_field_type(composite->get_base_type()); - exo_field.cardinality[0] = composite->get_base_type()->component_count(); - char separator0 = field.get_suffix_separator(); - exo_field.component_separator[0] = separator0 == 1 ? default_separator : separator0; + exo_fields[i].type[0] = Ioex::map_ioss_field_type(composite->get_base_type()); + exo_fields[i].cardinality[0] = composite->get_base_type()->component_count(); + char separator0 = field.get_suffix_separator(); + exo_fields[i].component_separator[0] = separator0 == 1 ? default_separator : separator0; - exo_field.type[1] = EX_FIELD_TYPE_SEQUENCE; - exo_field.cardinality[1] = composite->get_num_copies(); - char separator1 = field.get_suffix_separator(1); - exo_field.component_separator[1] = separator1 == 1 ? default_separator : separator1; + exo_fields[i].type[1] = EX_FIELD_TYPE_SEQUENCE; + exo_fields[i].cardinality[1] = composite->get_num_copies(); + char separator1 = field.get_suffix_separator(1); + exo_fields[i].component_separator[1] = separator1 == 1 ? default_separator : separator1; } else { - exo_field.nesting = 1; - exo_field.type[0] = Ioex::map_ioss_field_type(storage); - if (exo_field.type[0] == EX_FIELD_TYPE_SEQUENCE) { - exo_field.cardinality[0] = storage->component_count(); + exo_fields[i].nesting = 1; + exo_fields[i].type[0] = Ioex::map_ioss_field_type(storage); + if (exo_fields[i].type[0] == EX_FIELD_TYPE_SEQUENCE) { + exo_fields[i].cardinality[0] = storage->component_count(); } - if (exo_field.type[0] == EX_BASIS) { + if (exo_fields[i].type[0] == EX_BASIS) { assert(storage->type() == Ioss::VariableType::Type::BASIS); const auto *basis = dynamic_cast(storage); assert(basis != nullptr); - exo_field.cardinality[0] = storage->component_count(); - Ioss::Utils::copy_string(exo_field.type_name, basis->name()); + exo_fields[i].cardinality[0] = storage->component_count(); + Ioss::Utils::copy_string(exo_fields[i].type_name, basis->name()); } - if (exo_field.type[0] == EX_QUADRATURE) { + if (exo_fields[i].type[0] == EX_QUADRATURE) { assert(storage->type() == Ioss::VariableType::Type::QUADRATURE); const auto *quad = dynamic_cast(storage); assert(quad != nullptr); - exo_field.cardinality[0] = storage->component_count(); - Ioss::Utils::copy_string(exo_field.type_name, quad->name()); + exo_fields[i].cardinality[0] = storage->component_count(); + Ioss::Utils::copy_string(exo_fields[i].type_name, quad->name()); } - if (exo_field.type[0] == EX_FIELD_TYPE_USER_DEFINED) { + if (exo_fields[i].type[0] == EX_FIELD_TYPE_USER_DEFINED) { assert(storage->type() == Ioss::VariableType::Type::NAMED_SUFFIX); auto nsvt = dynamic_cast(storage); assert(nsvt != nullptr); - exo_field.cardinality[0] = nsvt->component_count(); + exo_fields[i].cardinality[0] = nsvt->component_count(); std::string suffices{}; - for (int i = 0; i < nsvt->component_count(); i++) { - if (i > 0) { + for (int ii = 0; ii < nsvt->component_count(); ii++) { + if (ii > 0) { suffices += ","; } - suffices += nsvt->label(i + 1, 0); + suffices += nsvt->label(ii + 1, 0); } - Ioss::Utils::copy_string(exo_field.suffices, suffices.c_str(), EX_MAX_NAME + 1); + Ioss::Utils::copy_string(exo_fields[i].suffices, suffices.c_str(), EX_MAX_NAME + 1); } - char separator = field.get_suffix_separator(); - exo_field.component_separator[0] = separator == 1 ? default_separator : separator; + char separator = field.get_suffix_separator(); + exo_fields[i].component_separator[0] = separator == 1 ? default_separator : separator; } + } + ex_put_multi_field_metadata(exoid, Data(exo_fields), exo_fields.size()); + for (const auto &exo_field : exo_fields) { if (exo_field.type[0] != EX_SCALAR) { - ex_put_field_metadata(exoid, exo_field); if (exo_field.type[0] == EX_FIELD_TYPE_USER_DEFINED) { ex_put_field_suffices(exoid, exo_field, exo_field.suffices); } @@ -2190,6 +2196,7 @@ namespace Ioex { { Ioss::SerializeIO serializeIO_(this); // Output the 'basis' and 'quadrature' type metadata... + exi_persist_redef(get_file_pointer(), __func__); output_type_metadata(get_file_pointer()); const Ioss::NodeBlockContainer &node_blocks = get_region()->get_node_blocks(); @@ -2225,6 +2232,7 @@ namespace Ioex { const Ioss::SideSetContainer &sidesets = get_region()->get_sidesets(); internal_output_field_metadata(get_file_pointer(), EX_SIDE_SET, sidesets); + exi_persist_leavedef(get_file_pointer(), __func__); } // common