Skip to content

Commit db99631

Browse files
committed
Factor out read_extra_integers
1 parent e3f8d63 commit db99631

3 files changed

Lines changed: 88 additions & 44 deletions

File tree

include/mesh/exodusII_io_helper.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,18 @@ class ExodusII_IO_Helper : public ParallelObject
306306
int time_step,
307307
std::map<dof_id_type, Real> & elem_var_value_map);
308308

309+
/**
310+
* Reads element "extra integer" values, using the variable names
311+
* specified in \p extra_integer_var_names, and converting the
312+
* stored values to integer format. The returned value is a vector
313+
* (indexed in the same way as extra_integer_vars) of maps from
314+
* element id to extra integer value.
315+
*
316+
* Currently values from the last time step are used.
317+
*/
318+
std::vector<std::map<dof_id_type, dof_id_type>> read_extra_integers(
319+
const std::vector<std::string> & extra_integer_var_names);
320+
309321
/**
310322
* Helper function that takes a (1-based) Exodus node/elem id and
311323
* determines the corresponding libMesh Node/Elem id. Takes into account

src/mesh/exodusII_io.C

Lines changed: 5 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -406,13 +406,11 @@ void ExodusII_IO::read (const std::string & fname)
406406
// have already been attached to spline control nodes.
407407
mesh.reserve_elem(exio_helper->w.size() + exio_helper->num_elem);
408408

409-
// Read variables for extra integer IDs
410-
std::vector<std::map<dof_id_type, Real>> elem_ids(extra_ids.size());
411-
// We use the last time step to load the IDs
412409
exio_helper->read_num_time_steps();
413-
unsigned int last_step = exio_helper->num_time_steps;
414-
for (auto i : index_range(extra_ids))
415-
exio_helper->read_elemental_var_values(_extra_integer_vars[i], last_step, elem_ids[i]);
410+
411+
// Read variables for extra integer IDs
412+
auto extra_integer_values =
413+
exio_helper->read_extra_integers(_extra_integer_vars);
416414

417415
// Read in the element connectivity for each block.
418416
int nelem_last_block = 0;
@@ -504,44 +502,7 @@ void ExodusII_IO::read (const std::string & fname)
504502

505503
// Assign extra integer IDs
506504
for (auto & id : extra_ids)
507-
{
508-
const Real v = elem_ids[id][elem->id()];
509-
510-
if (v == Real(-1))
511-
{
512-
elem->set_extra_integer(id, DofObject::invalid_id);
513-
continue;
514-
}
515-
516-
// Ignore FE_INVALID here even if we've enabled FPEs; a
517-
// thrown exception is preferred over an FPE signal.
518-
FPEDisabler disable_fpes;
519-
const long long iv = std::llround(v);
520-
521-
// Check if the real number is outside of the range we can
522-
// convert exactly
523-
524-
long long max_representation = 1;
525-
max_representation = (max_representation << std::min(std::numeric_limits<Real>::digits,
526-
std::numeric_limits<double>::digits));
527-
libmesh_error_msg_if(iv > max_representation,
528-
"Error! An element integer value higher than "
529-
<< max_representation
530-
<< " was found! Exodus uses real numbers for storing element "
531-
" integers, which can only represent integers from 0 to "
532-
<< max_representation
533-
<< ".");
534-
535-
libmesh_error_msg_if(iv < 0,
536-
"Error! An element integer value less than -1"
537-
<< " was found! Exodus uses real numbers for storing element "
538-
" integers, which can only represent integers from 0 to "
539-
<< max_representation
540-
<< ".");
541-
542-
543-
elem->set_extra_integer(id, cast_int<dof_id_type>(iv));
544-
}
505+
elem->set_extra_integer(id, extra_integer_values[id][elem->id()]);
545506

546507
// Set all the nodes for this element
547508
//

src/mesh/exodusII_io_helper.C

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2131,6 +2131,77 @@ void ExodusII_IO_Helper::read_elemental_var_values(std::string elemental_var_nam
21312131

21322132

21332133

2134+
std::vector<std::map<dof_id_type, dof_id_type>>
2135+
ExodusII_IO_Helper::read_extra_integers
2136+
(const std::vector<std::string> & extra_integer_var_names)
2137+
{
2138+
std::vector<std::map<dof_id_type, dof_id_type>>
2139+
extra_integer_values(extra_integer_var_names.size());
2140+
2141+
if (extra_integer_var_names.empty())
2142+
return extra_integer_values;
2143+
2144+
// Make sure we have an up-to-date count of the number of time steps in the file.
2145+
this->read_num_time_steps();
2146+
2147+
// Prepare to check if each real number is outside of the
2148+
// range we can convert exactly
2149+
2150+
const int exodus_digits = _single_precision ?
2151+
std::numeric_limits<float>::digits :
2152+
std::numeric_limits<double>::digits;
2153+
2154+
const int shift = std::min(std::numeric_limits<Real>::digits,
2155+
exodus_digits);
2156+
2157+
const long long max_representation = 1LL << shift;
2158+
2159+
for (auto i : index_range(extra_integer_var_names))
2160+
{
2161+
std::map<dof_id_type, Real> raw_vals;
2162+
2163+
// Read element extra "integers" as doubles from the last time step
2164+
this->read_elemental_var_values(extra_integer_var_names[i], this->num_time_steps, raw_vals);
2165+
2166+
// Convert doubles to actual integers, at least within the
2167+
// largest convex subset of doubles where this is a bijection.
2168+
auto & values = extra_integer_values[i];
2169+
2170+
for (auto [elem_id, extra_val] : raw_vals)
2171+
{
2172+
if (extra_val == Real(-1))
2173+
{
2174+
values[elem_id] = DofObject::invalid_id;
2175+
continue;
2176+
}
2177+
2178+
// Ignore FE_INVALID here even if we've enabled FPEs; a
2179+
// thrown exception is preferred over an FPE signal.
2180+
FPEDisabler disable_fpes;
2181+
const long long int_val = std::llround(extra_val);
2182+
2183+
libmesh_error_msg_if(int_val > max_representation,
2184+
"Error! An element integer value higher than "
2185+
<< max_representation
2186+
<< " was found! Exodus uses real numbers for storing element "
2187+
" integers, which can only represent integers from 0 to "
2188+
<< max_representation << ".");
2189+
2190+
libmesh_error_msg_if(int_val < 0,
2191+
"Error! An element integer value less than -1"
2192+
<< " was found! Exodus uses real numbers for storing element "
2193+
" integers, which can only represent integers from 0 to "
2194+
<< max_representation << ".");
2195+
2196+
values[elem_id] = cast_int<dof_id_type>(int_val);
2197+
}
2198+
}
2199+
2200+
return extra_integer_values;
2201+
}
2202+
2203+
2204+
21342205
dof_id_type ExodusII_IO_Helper::get_libmesh_node_id(int exodus_node_id)
21352206
{
21362207
return this->get_libmesh_id(exodus_node_id, this->node_num_map);

0 commit comments

Comments
 (0)