diff --git a/packages/seacas/libraries/exodus/src/ex_get_init_ext.c b/packages/seacas/libraries/exodus/src/ex_get_init_ext.c index cd2fa90e2165..ac416dbd0793 100644 --- a/packages/seacas/libraries/exodus/src/ex_get_init_ext.c +++ b/packages/seacas/libraries/exodus/src/ex_get_init_ext.c @@ -1,5 +1,5 @@ /* - * Copyright(C) 1999-2022, 2024 National Technology & Engineering Solutions + * Copyright(C) 1999-2022, 2024, 2025 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. * @@ -28,14 +28,21 @@ static void exi_get_entity_count(int exoid, ex_init_params *info) { int include_parent_group = 0; // Only want dims in current group int ndims = 0; +#if NC_HAS_NC4 nc_inq_dimids(exoid, &ndims, NULL, include_parent_group); int *dimids = calloc(ndims, sizeof(int)); nc_inq_dimids(exoid, &ndims, dimids, include_parent_group); - +#else + nc_inq(exoid, &ndims, NULL, NULL, NULL); +#endif for (int dimid = 0; dimid < ndims; dimid++) { char dim_nm[NC_MAX_NAME + 1] = {'\0'}; size_t dim_sz; +#if NC_HAS_NC4 nc_inq_dim(exoid, dimids[dimid], dim_nm, &dim_sz); +#else + nc_inq_dim(exoid, dimid, dim_nm, &dim_sz); +#endif /* For assemblies, we check for a dim starting with "num_entity_assembly" */ if (strncmp(dim_nm, "num_entity_assembly", 19) == 0) { info->num_assembly++; @@ -44,7 +51,9 @@ static void exi_get_entity_count(int exoid, ex_init_params *info) info->num_blob++; } } +#if NC_HAS_NC4 free(dimids); +#endif } /* Used to reduce repeated code below */ diff --git a/packages/seacas/libraries/ioss/src/exodus/Ioex_DatabaseIO.C b/packages/seacas/libraries/ioss/src/exodus/Ioex_DatabaseIO.C index 0d49fa766328..11e742a3f25a 100644 --- a/packages/seacas/libraries/ioss/src/exodus/Ioex_DatabaseIO.C +++ b/packages/seacas/libraries/ioss/src/exodus/Ioex_DatabaseIO.C @@ -1,4 +1,4 @@ -// Copyright(C) 1999-2024 National Technology & Engineering Solutions +// Copyright(C) 1999-2025 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. // @@ -731,60 +731,65 @@ namespace Ioex { { Ioss::SerializeIO serializeIO_(this); timestepCount = ex_inquire_int(get_file_pointer(), EX_INQ_TIME); - int exTimestepCount = timestepCount; - // Need to sync timestep count across ranks if parallel... - if (isParallel) { - auto min_timestep_count = - util().global_minmax(timestepCount, Ioss::ParallelUtils::DO_MIN); - if (min_timestep_count == 0) { - auto max_timestep_count = - util().global_minmax(timestepCount, Ioss::ParallelUtils::DO_MAX); - if (max_timestep_count != 0) { - if (myProcessor == 0) { - // NOTE: Don't want to warn on all processors if the - // timestep count is zero on some, but not all ranks. - fmt::print(Ioss::WarnOut(), - "At least one database has no timesteps. No times will be read on ANY" - " database for consistency.\n"); - } - } - } - timestepCount = min_timestep_count; - } - - if (timestepCount <= 0) { - return tsteps; - } - - // For an exodus file, timesteps are global and are stored in the region. - // Read the timesteps and add to the region - tsteps.resize(exTimestepCount, -std::numeric_limits::max()); - - // The `EXODUS_CALL_GET_ALL_TIMES=NO` is typically only used in - // isSerialParallel mode and the client is responsible for - // making sure that the step times are handled correctly. All - // databases will know about the number of timesteps, but if - // this is skipped, then the times will all be zero. Use case - // is that in isSerialParallel, each call to - // `ex_get_all_times` for all files is performed sequentially, - // so if you have hundreds to thousands of files, the time for - // the call is additive and since timesteps are record - // variables in netCDF, accessing the data for all timesteps - // involves lseeks throughout the file. - bool call_ex_get_all_times = true; - Ioss::Utils::check_set_bool_property(properties, "EXODUS_CALL_GET_ALL_TIMES", - call_ex_get_all_times); - if (call_ex_get_all_times) { - int error = ex_get_all_times(get_file_pointer(), Data(tsteps)); - if (error < 0) { - Ioex::exodus_error(get_file_pointer(), __LINE__, __func__, __FILE__); - } - } - - // See if the "last_written_time" attribute exists and if it - // does, check that it matches the largest time in 'tsteps'. - exists = Ioex::read_last_time_attribute(get_file_pointer(), &last_time); } + int exTimestepCount = timestepCount; + // Need to sync timestep count across ranks if parallel... + if (isParallel) { + auto min_timestep_count = + util().global_minmax(timestepCount, Ioss::ParallelUtils::DO_MIN); + if (min_timestep_count == 0) { + auto max_timestep_count = + util().global_minmax(timestepCount, Ioss::ParallelUtils::DO_MAX); + if (max_timestep_count != 0) { + if (myProcessor == 0) { + // NOTE: Don't want to warn on all processors if the + // timestep count is zero on some, but not all ranks. + fmt::print(Ioss::WarnOut(), + "At least one database has no timesteps. No times will be read on ANY" + " database for consistency.\n"); + } + } + } + timestepCount = min_timestep_count; + } + + if (timestepCount <= 0) { + return tsteps; + } + + // For an exodus file, timesteps are global and are stored in the region. + // Read the timesteps and add to the region + tsteps.resize(exTimestepCount, -std::numeric_limits::max()); + + // The `EXODUS_CALL_GET_ALL_TIMES=NO` is typically only used in + // isSerialParallel mode and the client is responsible for + // making sure that the step times are handled correctly. All + // databases will know about the number of timesteps, but if + // this is skipped, then the times will all be zero. Use case + // is that in isSerialParallel, each call to + // `ex_get_all_times` for all files is performed sequentially, + // so if you have hundreds to thousands of files, the time for + // the call is additive and since timesteps are record + // variables in netCDF, accessing the data for all timesteps + // involves lseeks throughout the file. + bool call_ex_get_all_times = true; + Ioss::Utils::check_set_bool_property(properties, "EXODUS_CALL_GET_ALL_TIMES", + call_ex_get_all_times); + if (call_ex_get_all_times) { + Ioss::SerializeIO serializeIO_(this); + int error = ex_get_all_times(get_file_pointer(), Data(tsteps)); + if (error < 0) { + Ioex::exodus_error(get_file_pointer(), __LINE__, __func__, __FILE__); + } + } + + // See if the "last_written_time" attribute exists and if it + // does, check that it matches the largest time in 'tsteps'. + { + Ioss::SerializeIO serializeIO_(this); + exists = Ioex::read_last_time_attribute(get_file_pointer(), &last_time); + } + if (exists && isParallel) { // Assume that if it exists on 1 processor, it exists on // all... Sync value among processors since could have a