libMesh
Public Member Functions | Static Public Member Functions | Protected Member Functions | Protected Attributes | Private Attributes | List of all members
libMesh::ExodusII_IO Class Reference

The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs. More...

#include <exodusII_io.h>

Inheritance diagram for libMesh::ExodusII_IO:
[legend]

Public Member Functions

 ExodusII_IO (MeshBase &mesh, bool single_precision=false)
 Constructor. More...
 
 ExodusII_IO (const MeshBase &mesh, bool single_precision=false)
 Constructor. More...
 
 ExodusII_IO (ExodusII_IO &&)=default
 ExodusII_IO special functions: More...
 
 ExodusII_IO (const ExodusII_IO &)=delete
 
ExodusII_IOoperator= (const ExodusII_IO &)=delete
 
ExodusII_IOoperator= (ExodusII_IO &&)=delete
 
virtual ~ExodusII_IO ()
 
virtual void read (const std::string &name) override
 This method implements reading a mesh from a specified file. More...
 
ExodusHeaderInfo read_header (const std::string &name)
 Read only the header information, instead of the entire mesh. More...
 
virtual void write (const std::string &fname) override
 This method implements writing a mesh to a specified file. More...
 
void verbose (bool set_verbosity)
 Set the flag indicating if we should be verbose. More...
 
void write_complex_magnitude (bool val)
 Set the flag indicating whether the complex modulus should be written when complex numbers are enabled. More...
 
void set_unique_ids_from_maps (bool val)
 If true, this flag enforces the following behaviors: More...
 
void write_added_sides (bool val)
 By default, we only write out the elements physically stored in the mesh. More...
 
virtual bool get_add_sides () override
 
const std::vector< Real > & get_time_steps ()
 
int get_num_time_steps ()
 
void copy_nodal_solution (System &system, std::string system_var_name, std::string exodus_var_name, unsigned int timestep=1)
 If we read in a nodal solution while reading in a mesh, we can attempt to copy that nodal solution into an EquationSystems object. More...
 
void copy_elemental_solution (System &system, std::string system_var_name, std::string exodus_var_name, unsigned int timestep=1)
 If we read in a elemental solution while reading in a mesh, we can attempt to copy that elemental solution into an EquationSystems object. More...
 
void copy_scalar_solution (System &system, std::vector< std::string > system_var_names, std::vector< std::string > exodus_var_names, unsigned int timestep=1)
 Copy global variables into scalar variables of a System object. More...
 
void read_elemental_variable (std::string elemental_var_name, unsigned int timestep, std::map< unsigned int, Real > &unique_id_to_value_map)
 Given an elemental variable and a time step, returns a mapping from the elements (top parent) unique IDs to the value of the elemental variable at the corresponding time step index. More...
 
void read_global_variable (std::vector< std::string > global_var_names, unsigned int timestep, std::vector< Real > &global_values)
 Given a vector of global variables and a time step, returns the values of the global variable at the corresponding time step index. More...
 
void write_discontinuous_exodusII (const std::string &name, const EquationSystems &es, const std::set< std::string > *system_names=nullptr)
 Writes a exodusII file with discontinuous data. More...
 
void write_timestep_discontinuous (const std::string &fname, const EquationSystems &es, const int timestep, const Real time, const std::set< std::string > *system_names=nullptr)
 Writes a discontinuous solution at a specific timestep. More...
 
void write_element_data (const EquationSystems &es)
 Write out element solution. More...
 
void write_element_data_from_discontinuous_nodal_data (const EquationSystems &es, const std::set< std::string > *system_names=nullptr, const std::string &var_suffix="_elem_node_")
 Similar to the function above, but instead of only handling (CONSTANT, MONOMIAL) data, writes out a general discontinuous solution field, e.g. More...
 
virtual void write_nodal_data (const std::string &, const std::vector< Number > &, const std::vector< std::string > &) override
 Write out a nodal solution. More...
 
void write_nodal_data_discontinuous (const std::string &, const std::vector< Number > &, const std::vector< std::string > &) override
 Write out a discontinuous nodal solution. More...
 
void write_global_data (const std::vector< Number > &, const std::vector< std::string > &)
 Write out global variables. More...
 
void write_information_records (const std::vector< std::string > &)
 Write out information records. More...
 
void write_timestep (const std::string &fname, const EquationSystems &es, const int timestep, const Real time, const std::set< std::string > *system_names=nullptr)
 Writes out the solution at a specific timestep. More...
 
virtual void write_equation_systems (const std::string &fname, const EquationSystems &es, const std::set< std::string > *system_names=nullptr) override
 Writes out the solution for no specific time or timestep. More...
 
void write_elemsets ()
 Write elemsets stored on the Mesh to file. More...
 
void write_sideset_data (int timestep, const std::vector< std::string > &var_names, const std::vector< std::set< boundary_id_type >> &side_ids, const std::vector< std::map< BoundaryInfo::BCTuple, Real >> &bc_vals)
 The Exodus format can also store values on sidesets. More...
 
void read_sideset_data (int timestep, std::vector< std::string > &var_names, std::vector< std::set< boundary_id_type >> &side_ids, std::vector< std::map< BoundaryInfo::BCTuple, Real >> &bc_vals)
 Similar to write_sideset_data(), this function is used to read the data at a particular timestep. More...
 
void get_sideset_data_indices (std::map< BoundaryInfo::BCTuple, unsigned int > &bc_array_indices)
 Similar to read_sideset_data(), but instead of creating one std::map per sideset per variable, creates a single map of (elem, side, boundary_id) tuples, and stores the exo file array indices for any/all sideset variables on that sideset (they are all the same). More...
 
void write_nodeset_data (int timestep, const std::vector< std::string > &var_names, const std::vector< std::set< boundary_id_type >> &node_boundary_ids, const std::vector< std::map< BoundaryInfo::NodeBCTuple, Real >> &bc_vals)
 The Exodus format can also store values on nodesets. More...
 
void read_nodeset_data (int timestep, std::vector< std::string > &var_names, std::vector< std::set< boundary_id_type >> &node_boundary_ids, std::vector< std::map< BoundaryInfo::NodeBCTuple, Real >> &bc_vals)
 Read all the nodeset data at a particular timestep. More...
 
void get_nodeset_data_indices (std::map< BoundaryInfo::NodeBCTuple, unsigned int > &bc_array_indices)
 Similar to read_nodeset_data(), but instead of creating one std::map per nodeset per variable, creates a single map of (node_id, boundary_id) tuples, and stores the exo file array indices for any/all nodeset variables on that nodeset (they are all the same). More...
 
void write_elemset_data (int timestep, const std::vector< std::string > &var_names, const std::vector< std::set< elemset_id_type >> &elemset_ids_in, const std::vector< std::map< std::pair< dof_id_type, elemset_id_type >, Real >> &elemset_vals)
 The Exodus format can also store values on elemsets. More...
 
void read_elemset_data (int timestep, std::vector< std::string > &var_names, std::vector< std::set< elemset_id_type >> &elemset_ids_in, std::vector< std::map< std::pair< dof_id_type, elemset_id_type >, Real >> &elemset_vals)
 Read all the elemset data at a particular timestep. More...
 
void get_elemset_data_indices (std::map< std::pair< dof_id_type, elemset_id_type >, unsigned int > &elemset_array_indices)
 Similar to read_elemset_data(), but instead of creating one std::map per nodeset per variable, creates a single map of (elem_id, elemset_id) pairs -> exo file array indices for any/all variables on that elemset (they are all the same). More...
 
void set_extra_integer_vars (const std::vector< std::string > &extra_integer_vars)
 Set the elemental variables in the Exodus file to be read into extra element integers. More...
 
void set_output_variables (const std::vector< std::string > &output_variables, bool allow_empty=true)
 Sets the list of variable names to be included in the output. More...
 
void use_mesh_dimension_instead_of_spatial_dimension (bool val)
 In the general case, meshes containing 2D elements can be manifolds living in 3D space, thus by default we write all meshes with the Exodus dimension set to LIBMESH_DIM = mesh.spatial_dimension(). More...
 
void write_as_dimension (unsigned dim)
 Directly control the num_dim which is written to the Exodus file. More...
 
void set_coordinate_offset (Point p)
 Allows you to set a vector that is added to the coordinates of all of the nodes. More...
 
void append (bool val)
 If true, this flag will cause the ExodusII_IO object to attempt to open an existing file for writing, rather than creating a new file. More...
 
void set_max_name_length (unsigned int max_length)
 For backwards compatibility, libMesh currently truncates names in ExodusII output to the old default of 32 characters, but user code can expand that to up to 80 characters by setting a larger max_length manually. More...
 
const std::vector< std::string > & get_elem_var_names ()
 Return list of the elemental variable names. More...
 
const std::vector< std::string > & get_nodal_var_names ()
 Return list of the nodal variable names. More...
 
const std::vector< std::string > & get_global_var_names ()
 Return list of the global variable names. More...
 
const std::vector< int > & get_elem_num_map () const
 Returns a const reference to the elem_num_map, which is a vector that is created when a Mesh is read from file. More...
 
const std::vector< int > & get_node_num_map () const
 Identical to the behavior of get_elem_num_map(), but for the node_num_map instead. More...
 
ExodusII_IO_Helperget_exio_helper ()
 Return a reference to the ExodusII_IO_Helper object. More...
 
void set_hdf5_writing (bool write_hdf5)
 Set to true (the default) to write files in an HDF5-based file format (when HDF5 is available), or to false to write files in the old NetCDF3-based format. More...
 
void set_discontinuous_bex (bool disc_bex)
 Set to true (false is the default) to generate independent nodes for every Bezier Extraction element in an input file containing them, causing those elements to be disconnected from each other. More...
 
void write_nodal_data_common (std::string fname, const std::vector< std::string > &names, bool continuous=true)
 This function factors out a bunch of code which is common to the write_nodal_data() and write_nodal_data_discontinuous() functions. More...
 
bool is_parallel_format () const
 Returns true iff this mesh file format and input class are parallelized, so that all processors can read their share of the data at once. More...
 
virtual void write_discontinuous_equation_systems (const std::string &, const EquationSystems &, const std::set< std::string > *system_names=nullptr)
 This method implements writing a mesh with discontinuous data to a specified file where the data is taken from the EquationSystems object. More...
 
virtual void write_nodal_data (const std::string &, const NumericVector< Number > &, const std::vector< std::string > &)
 This method may be overridden by "parallel" output formats for writing nodal data. More...
 
virtual void write_nodal_data (const std::string &, const EquationSystems &, const std::set< std::string > *)
 This method should be overridden by "parallel" output formats for writing nodal data. More...
 
unsigned intascii_precision ()
 Return/set the precision to use when writing ASCII files. More...
 
const Parallel::Communicatorcomm () const
 
processor_id_type n_processors () const
 
processor_id_type processor_id () const
 

Static Public Member Functions

static int get_exodus_version ()
 

Protected Member Functions

MeshBasemesh ()
 
void set_n_partitions (unsigned int n_parts)
 Sets the number of partitions in the mesh. More...
 
void skip_comment_lines (std::istream &in, const char comment_start)
 Reads input from in, skipping all the lines that start with the character comment_start. More...
 
const MeshBasemesh () const
 

Protected Attributes

std::vector< bool > elems_of_dimension
 A vector of bools describing what dimension elements have been encountered when reading a mesh. More...
 
const bool _is_parallel_format
 Flag specifying whether this format is parallel-capable. More...
 
const bool _serial_only_needed_on_proc_0
 Flag specifying whether this format can be written by only serializing the mesh to processor zero. More...
 
const Parallel::Communicator_communicator
 

Private Attributes

std::unique_ptr< ExodusII_IO_Helperexio_helper
 Only attempt to instantiate an ExodusII helper class if the Exodus API is defined. More...
 
int _timestep
 Stores the current value of the timestep when calling ExodusII_IO::write_timestep(). More...
 
bool _verbose
 should we be verbose? More...
 
bool _append
 Default false. More...
 
std::vector< std::string > _extra_integer_vars
 An optional list of variables in the EXODUS file that are to be used to set extra integers when loading the file into a mesh. More...
 
std::vector< std::string > _output_variables
 The names of the variables to be output. More...
 
bool _allow_empty_variables
 Flag which controls the behavior of _output_variables: .) If true, _output_variables is allowed to remain empty. More...
 
bool _write_complex_abs
 By default, when complex numbers are enabled, for each variable we write out three values: the real part, "r_u" the imaginary part, "i_u", and the complex modulus, a_u := sqrt(r_u*r_u + i_u*i_u), which is also the value returned by std::abs(std::complex). More...
 
bool _set_unique_ids_from_maps
 Set Elem/Node unique_ids based on the elem_num_map and node_num_map contents during reading, populate those maps with unique_ids during writing. More...
 
bool _disc_bex
 Set to true (false is the default) to generate independent nodes for every Bezier Extraction element. More...
 

Detailed Description

The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs.

Author
Benjamin Kirk
John Peterson
Date
2004 Handles reading and writing of Exodus binary files.

Definition at line 50 of file exodusII_io.h.

Constructor & Destructor Documentation

◆ ExodusII_IO() [1/4]

libMesh::ExodusII_IO::ExodusII_IO ( MeshBase mesh,
bool  single_precision = false 
)
explicit

Constructor.

Takes a writable reference to a mesh object. This is the constructor required to read a mesh.

Definition at line 122 of file exodusII_io.C.

References libMesh::libmesh_ignore().

123  :
126  /* is_parallel_format = */ false,
127  /* serial_only_needed_on_proc_0 = */ true),
129 #ifdef LIBMESH_HAVE_EXODUS_API
130  exio_helper(std::make_unique<ExodusII_IO_Helper>(*this, false, true, single_precision)),
131  _timestep(1),
132  _verbose(false),
133  _append(false),
134 #endif
135  _allow_empty_variables(false),
136  _write_complex_abs(true),
138  _disc_bex(false)
139 {
140  // if !LIBMESH_HAVE_EXODUS_API, we didn't use this
141  libmesh_ignore(single_precision);
142 }
ParallelObject(const Parallel::Communicator &comm_in)
Constructor.
int _timestep
Stores the current value of the timestep when calling ExodusII_IO::write_timestep().
Definition: exodusII_io.h:682
void libmesh_ignore(const Args &...)
bool _verbose
should we be verbose?
Definition: exodusII_io.h:687
bool _append
Default false.
Definition: exodusII_io.h:693
bool _disc_bex
Set to true (false is the default) to generate independent nodes for every Bezier Extraction element...
Definition: exodusII_io.h:742
bool _write_complex_abs
By default, when complex numbers are enabled, for each variable we write out three values: the real p...
Definition: exodusII_io.h:728
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676
bool _allow_empty_variables
Flag which controls the behavior of _output_variables: .) If true, _output_variables is allowed to re...
Definition: exodusII_io.h:717
bool _set_unique_ids_from_maps
Set Elem/Node unique_ids based on the elem_num_map and node_num_map contents during reading...
Definition: exodusII_io.h:736

◆ ExodusII_IO() [2/4]

libMesh::ExodusII_IO::ExodusII_IO ( const MeshBase mesh,
bool  single_precision = false 
)
explicit

Constructor.

Takes a const reference to a mesh object. This constructor is acceptable to write meshes.

Definition at line 146 of file exodusII_io.C.

References libMesh::libmesh_ignore().

147  :
150  /* is_parallel_format = */ false,
151  /* serial_only_needed_on_proc_0 = */ true),
153 #ifdef LIBMESH_HAVE_EXODUS_API
154  exio_helper(std::make_unique<ExodusII_IO_Helper>(*this, false, true, single_precision)),
155  _timestep(1),
156  _verbose(false),
157  _append(false),
158 #endif
159  _allow_empty_variables(false),
160  _write_complex_abs(true),
162  _disc_bex(false)
163 {
164  // if !LIBMESH_HAVE_EXODUS_API, we didn't use this
165  libmesh_ignore(single_precision);
166 }
ParallelObject(const Parallel::Communicator &comm_in)
Constructor.
int _timestep
Stores the current value of the timestep when calling ExodusII_IO::write_timestep().
Definition: exodusII_io.h:682
void libmesh_ignore(const Args &...)
bool _verbose
should we be verbose?
Definition: exodusII_io.h:687
bool _append
Default false.
Definition: exodusII_io.h:693
bool _disc_bex
Set to true (false is the default) to generate independent nodes for every Bezier Extraction element...
Definition: exodusII_io.h:742
bool _write_complex_abs
By default, when complex numbers are enabled, for each variable we write out three values: the real p...
Definition: exodusII_io.h:728
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676
bool _allow_empty_variables
Flag which controls the behavior of _output_variables: .) If true, _output_variables is allowed to re...
Definition: exodusII_io.h:717
bool _set_unique_ids_from_maps
Set Elem/Node unique_ids based on the elem_num_map and node_num_map contents during reading...
Definition: exodusII_io.h:736

◆ ExodusII_IO() [3/4]

libMesh::ExodusII_IO::ExodusII_IO ( ExodusII_IO &&  )
default

ExodusII_IO special functions:

  • Can't be (default) copy constructed or assigned since they contain a unique_ptr member.
  • Can't be (default) move assigned because the helper class contains references.
  • The destructor is responsible for closing the file

◆ ExodusII_IO() [4/4]

libMesh::ExodusII_IO::ExodusII_IO ( const ExodusII_IO )
delete

◆ ~ExodusII_IO()

libMesh::ExodusII_IO::~ExodusII_IO ( )
virtualdefault

Definition at line 240 of file exodusII_io.C.

References exio_helper.

241 {
242  exio_helper->close();
243 }
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

Member Function Documentation

◆ append()

void libMesh::ExodusII_IO::append ( bool  val)

If true, this flag will cause the ExodusII_IO object to attempt to open an existing file for writing, rather than creating a new file.

Obviously this will only work if the file already exists.

Definition at line 1009 of file exodusII_io.C.

References _append.

Referenced by main().

1010 {
1011  _append = val;
1012 }
bool _append
Default false.
Definition: exodusII_io.h:693

◆ ascii_precision()

unsigned int & libMesh::MeshOutput< MeshBase >::ascii_precision ( )
inlineinherited

Return/set the precision to use when writing ASCII files.

By default we use numeric_limits<Real>::max_digits10, which should be enough to write out to ASCII and get the exact same Real back when reading in.

Definition at line 269 of file mesh_output.h.

Referenced by libMesh::UNVIO::nodes_out(), libMesh::FroIO::write(), libMesh::STLIO::write(), libMesh::MEDITIO::write_ascii(), libMesh::TecplotIO::write_ascii(), libMesh::GMVIO::write_ascii_new_impl(), and libMesh::GMVIO::write_ascii_old_impl().

270 {
271  return _ascii_precision;
272 }
unsigned int _ascii_precision
Precision to use when writing ASCII files.
Definition: mesh_output.h:207

◆ comm()

const Parallel::Communicator& libMesh::ParallelObject::comm ( ) const
inlineinherited
Returns
A reference to the Parallel::Communicator object used by this mesh.

Definition at line 97 of file parallel_object.h.

References libMesh::ParallelObject::_communicator.

Referenced by libMesh::__libmesh_petsc_diff_solver_jacobian(), libMesh::__libmesh_petsc_diff_solver_monitor(), libMesh::__libmesh_petsc_diff_solver_residual(), libMesh::__libmesh_tao_equality_constraints(), libMesh::__libmesh_tao_equality_constraints_jacobian(), libMesh::__libmesh_tao_gradient(), libMesh::__libmesh_tao_hessian(), libMesh::__libmesh_tao_inequality_constraints(), libMesh::__libmesh_tao_inequality_constraints_jacobian(), libMesh::__libmesh_tao_objective(), libMesh::MeshRefinement::_coarsen_elements(), libMesh::ExactSolution::_compute_error(), libMesh::UniformRefinementEstimator::_estimate_error(), libMesh::Partitioner::_find_global_index_by_pid_map(), libMesh::BoundaryInfo::_find_id_maps(), libMesh::PetscLinearSolver< Number >::_petsc_shell_matrix_get_diagonal(), libMesh::SlepcEigenSolver< libMesh::Number >::_petsc_shell_matrix_get_diagonal(), libMesh::PetscLinearSolver< Number >::_petsc_shell_matrix_mult(), libMesh::SlepcEigenSolver< libMesh::Number >::_petsc_shell_matrix_mult(), libMesh::PetscLinearSolver< Number >::_petsc_shell_matrix_mult_add(), libMesh::MeshRefinement::_refine_elements(), libMesh::MeshRefinement::_smooth_flags(), libMesh::DofMap::add_constraints_to_send_list(), add_cube_convex_hull_to_mesh(), libMesh::PetscDMWrapper::add_dofs_helper(), libMesh::PetscDMWrapper::add_dofs_to_section(), libMesh::TransientRBConstruction::add_IC_to_RB_space(), libMesh::RBEIMEvaluation::add_interpolation_data(), libMesh::CondensedEigenSystem::add_matrices(), libMesh::EigenSystem::add_matrices(), libMesh::System::add_matrix(), libMesh::RBConstruction::add_scaled_matrix_and_vector(), libMesh::DofMap::add_variable(), libMesh::DofMap::add_variables(), libMesh::System::add_vector(), libMesh::MeshTools::Modification::all_tri(), libMesh::LaplaceMeshSmoother::allgather_graph(), libMesh::DofMap::allgather_recursive_constraints(), libMesh::TransientRBConstruction::allocate_data_structures(), libMesh::RBConstruction::allocate_data_structures(), libMesh::TransientRBConstruction::assemble_affine_expansion(), libMesh::AdvectionSystem::assemble_claw_rhs(), libMesh::FEMSystem::assemble_qoi(), libMesh::Nemesis_IO::assert_symmetric_cmaps(), libMesh::MeshCommunication::assign_global_indices(), libMesh::Partitioner::assign_partitioning(), libMesh::MeshTools::Generation::build_extrusion(), libMesh::Partitioner::build_graph(), libMesh::InfElemBuilder::build_inf_elem(), libMesh::BoundaryInfo::build_node_list_from_side_list(), libMesh::EquationSystems::build_parallel_elemental_solution_vector(), libMesh::EquationSystems::build_parallel_solution_vector(), libMesh::PetscDMWrapper::build_section(), libMesh::PetscDMWrapper::build_sf(), libMesh::MeshBase::cache_elem_data(), libMesh::System::calculate_norm(), libMesh::DofMap::check_dirichlet_bcid_consistency(), libMesh::MeshTetInterface::check_hull_integrity(), libMesh::MeshBase::complete_preparation(), libMesh::RBConstruction::compute_Fq_representor_innerprods(), libMesh::RBConstruction::compute_max_error_bound(), libMesh::Nemesis_IO_Helper::compute_num_global_elem_blocks(), libMesh::Nemesis_IO_Helper::compute_num_global_nodesets(), libMesh::Nemesis_IO_Helper::compute_num_global_sidesets(), libMesh::RBConstruction::compute_output_dual_innerprods(), libMesh::RBConstruction::compute_residual_dual_norm_slow(), libMesh::RBSCMConstruction::compute_SCM_bounds_on_training_set(), libMesh::DofMap::computed_sparsity_already(), libMesh::Problem_Interface::computeF(), libMesh::Problem_Interface::computeJacobian(), libMesh::Problem_Interface::computePreconditioner(), libMesh::ContinuationSystem::ContinuationSystem(), libMesh::MeshBase::copy_constraint_rows(), copy_elemental_solution(), copy_nodal_solution(), copy_scalar_solution(), libMesh::CondensedEigenSystem::copy_super_to_sub(), libMesh::MeshTools::correct_node_proc_ids(), libMesh::MeshTools::create_bounding_box(), libMesh::DofMap::create_dof_constraints(), libMesh::MeshTools::create_nodal_bounding_box(), libMesh::MeshRefinement::create_parent_error_vector(), libMesh::MeshTools::create_processor_bounding_box(), libMesh::MeshTools::create_subdomain_bounding_box(), libMesh::PetscMatrix< T >::create_submatrix_nosort(), create_wrapped_function(), libMesh::MeshCommunication::delete_remote_elements(), libMesh::RBEIMEvaluation::distribute_bfs(), DMlibMeshFunction(), DMlibMeshJacobian(), DMlibMeshSetSystem_libMesh(), DMVariableBounds_libMesh(), libMesh::DTKSolutionTransfer::DTKSolutionTransfer(), libMesh::MeshRefinement::eliminate_unrefined_patches(), libMesh::RBEIMConstruction::enrich_eim_approximation_on_interiors(), libMesh::RBEIMConstruction::enrich_eim_approximation_on_nodes(), libMesh::RBEIMConstruction::enrich_eim_approximation_on_sides(), libMesh::TransientRBConstruction::enrich_RB_space(), libMesh::EpetraVector< T >::EpetraVector(), AssembleOptimization::equality_constraints(), libMesh::PatchRecoveryErrorEstimator::estimate_error(), libMesh::WeightedPatchRecoveryErrorEstimator::estimate_error(), libMesh::AdjointRefinementEstimator::estimate_error(), libMesh::ExactErrorEstimator::estimate_error(), libMesh::SmoothnessEstimator::estimate_smoothness(), libMesh::MeshRefinement::flag_elements_by_elem_fraction(), libMesh::MeshRefinement::flag_elements_by_error_fraction(), libMesh::MeshRefinement::flag_elements_by_error_tolerance(), libMesh::MeshRefinement::flag_elements_by_mean_stddev(), libMesh::MeshRefinement::flag_elements_by_nelem_target(), libMesh::RBEIMEvaluation::gather_bfs(), libMesh::DofMap::gather_constraints(), libMesh::MeshfreeInterpolation::gather_remote_data(), libMesh::CondensedEigenSystem::get_eigenpair(), libMesh::RBEIMEvaluation::get_eim_basis_function_node_value(), libMesh::RBEIMEvaluation::get_eim_basis_function_side_value(), libMesh::RBEIMEvaluation::get_eim_basis_function_value(), libMesh::System::get_info(), libMesh::MeshBase::get_info(), libMesh::DofMap::get_info(), libMesh::RBEIMEvaluation::get_interior_basis_functions_as_vecs(), libMesh::ImplicitSystem::get_linear_solver(), libMesh::RBEIMConstruction::get_max_abs_value(), libMesh::RBEIMConstruction::get_node_max_abs_value(), libMesh::RBEIMEvaluation::get_parametrized_function_node_value(), libMesh::RBEIMEvaluation::get_parametrized_function_side_value(), libMesh::RBEIMEvaluation::get_parametrized_function_value(), libMesh::RBEIMConstruction::get_random_point(), libMesh::MeshTetInterface::improve_hull_integrity(), AssembleOptimization::inequality_constraints(), AssembleOptimization::inequality_constraints_jacobian(), libMesh::LocationMap< T >::init(), libMesh::TimeSolver::init(), libMesh::StaticCondensation::init(), libMesh::SystemSubsetBySubdomain::init(), libMesh::PetscDMWrapper::init_and_attach_petscdm(), libMesh::AdvectionSystem::init_data(), libMesh::ClawSystem::init_data(), libMesh::PetscDMWrapper::init_petscdm(), libMesh::ExodusII_IO_Helper::initialize(), libMesh::OptimizationSystem::initialize_equality_constraints_storage(), libMesh::OptimizationSystem::initialize_inequality_constraints_storage(), libMesh::RBEIMConstruction::initialize_parametrized_functions_in_training_set(), libMesh::RBEIMConstruction::inner_product(), integrate_function(), libMesh::MeshTools::libmesh_assert_consistent_distributed(), libMesh::MeshTools::libmesh_assert_consistent_distributed_nodes(), libMesh::MeshTools::libmesh_assert_contiguous_dof_ids(), libMesh::MeshTools::libmesh_assert_equal_connectivity(), libMesh::MeshTools::libmesh_assert_equal_points(), libMesh::MeshTools::libmesh_assert_parallel_consistent_new_node_procids(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Elem >(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Node >(), libMesh::MeshTools::libmesh_assert_topology_consistent_procids< Node >(), libMesh::MeshTools::libmesh_assert_valid_boundary_ids(), libMesh::MeshTools::libmesh_assert_valid_constraint_rows(), libMesh::MeshTools::libmesh_assert_valid_dof_ids(), libMesh::MeshTools::libmesh_assert_valid_neighbors(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_flags(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_object_ids(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_p_levels(), libMesh::MeshTools::libmesh_assert_valid_refinement_flags(), libMesh::MeshTools::libmesh_assert_valid_unique_ids(), libMesh::libmesh_petsc_linesearch_shellfunc(), libMesh::libmesh_petsc_preconditioner_apply(), libMesh::libmesh_petsc_recalculate_monitor(), libMesh::libmesh_petsc_snes_fd_residual(), libMesh::libmesh_petsc_snes_jacobian(), libMesh::libmesh_petsc_snes_mffd_interface(), libMesh::libmesh_petsc_snes_mffd_residual(), libMesh::libmesh_petsc_snes_postcheck(), libMesh::libmesh_petsc_snes_precheck(), libMesh::libmesh_petsc_snes_residual(), libMesh::libmesh_petsc_snes_residual_helper(), libMesh::MeshRefinement::limit_level_mismatch_at_edge(), libMesh::MeshRefinement::limit_level_mismatch_at_node(), libMesh::MeshRefinement::limit_overrefined_boundary(), libMesh::MeshRefinement::limit_underrefined_boundary(), libMesh::LinearImplicitSystem::LinearImplicitSystem(), main(), libMesh::MeshRefinement::make_coarsening_compatible(), libMesh::MeshCommunication::make_elems_parallel_consistent(), libMesh::MeshRefinement::make_flags_parallel_consistent(), libMesh::MeshCommunication::make_new_node_proc_ids_parallel_consistent(), libMesh::MeshCommunication::make_new_nodes_parallel_consistent(), libMesh::MeshCommunication::make_node_bcids_parallel_consistent(), libMesh::MeshCommunication::make_node_ids_parallel_consistent(), libMesh::MeshCommunication::make_node_proc_ids_parallel_consistent(), libMesh::MeshCommunication::make_node_unique_ids_parallel_consistent(), libMesh::MeshCommunication::make_nodes_parallel_consistent(), libMesh::MeshCommunication::make_p_levels_parallel_consistent(), libMesh::MeshRefinement::make_refinement_compatible(), libMesh::TransientRBConstruction::mass_matrix_scaled_matvec(), libMesh::FEMSystem::mesh_position_set(), libMesh::TriangulatorInterface::MeshedHole::MeshedHole(), LinearElasticityWithContact::move_mesh(), libMesh::DistributedMesh::n_active_elem(), libMesh::MeshTools::n_active_levels(), libMesh::BoundaryInfo::n_boundary_conds(), libMesh::MeshTools::n_connected_components(), libMesh::DofMap::n_constrained_dofs(), libMesh::MeshBase::n_constraint_rows(), libMesh::DofMap::n_dofs(), libMesh::DofMap::n_dofs_per_processor(), libMesh::BoundaryInfo::n_edge_conds(), libMesh::CondensedEigenSystem::n_global_non_condensed_dofs(), libMesh::MeshTools::n_levels(), MixedOrderTest::n_neighbor_links(), libMesh::BoundaryInfo::n_nodeset_conds(), libMesh::SparsityPattern::Build::n_nonzeros(), libMesh::MeshTools::n_p_levels(), libMesh::BoundaryInfo::n_shellface_conds(), libMesh::RBEIMEvaluation::node_distribute_bfs(), libMesh::RBEIMEvaluation::node_gather_bfs(), libMesh::RBEIMConstruction::node_inner_product(), libMesh::PetscVector< libMesh::Number >::operator=(), libMesh::MeshBase::operator==(), libMesh::DistributedMesh::parallel_max_elem_id(), libMesh::DistributedMesh::parallel_max_node_id(), libMesh::ReplicatedMesh::parallel_max_unique_id(), libMesh::DistributedMesh::parallel_max_unique_id(), libMesh::DistributedMesh::parallel_n_elem(), libMesh::DistributedMesh::parallel_n_nodes(), libMesh::SparsityPattern::Build::parallel_sync(), libMesh::BoundaryInfo::parallel_sync_node_ids(), libMesh::BoundaryInfo::parallel_sync_side_ids(), libMesh::MeshTools::paranoid_n_levels(), libMesh::Partitioner::partition(), libMesh::Partitioner::partition_unpartitioned_elements(), libMesh::petsc_auto_fieldsplit(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), libMesh::MeshBase::print_constraint_rows(), libMesh::DofMap::print_dof_constraints(), libMesh::DofMap::process_mesh_constraint_rows(), libMesh::Partitioner::processor_pairs_to_interface_nodes(), libMesh::InterMeshProjection::project_system_vectors(), FEMParameters::read(), libMesh::Nemesis_IO::read(), libMesh::XdrIO::read(), libMesh::EquationSystems::read(), read_header(), libMesh::CheckpointIO::read_header(), libMesh::XdrIO::read_header(), libMesh::System::read_header(), libMesh::RBEIMEvaluation::read_in_interior_basis_functions(), libMesh::RBEIMEvaluation::read_in_node_basis_functions(), libMesh::RBEIMEvaluation::read_in_side_basis_functions(), libMesh::RBEvaluation::read_in_vectors_from_multiple_files(), libMesh::TransientRBConstruction::read_riesz_representors_from_files(), libMesh::RBConstruction::read_riesz_representors_from_files(), libMesh::System::read_SCALAR_dofs(), libMesh::XdrIO::read_serialized_bc_names(), libMesh::XdrIO::read_serialized_bcs_helper(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::XdrIO::read_serialized_connectivity(), libMesh::XdrIO::read_serialized_nodes(), libMesh::XdrIO::read_serialized_nodesets(), libMesh::XdrIO::read_serialized_subdomain_names(), libMesh::System::read_serialized_vector(), libMesh::Nemesis_IO_Helper::read_var_names_impl(), MeshFunctionTest::read_variable_info_from_output_data(), libMesh::MeshBase::recalculate_n_partitions(), libMesh::MeshRefinement::refine_and_coarsen_elements(), libMesh::SimplexRefiner::refine_via_edges(), libMesh::StaticCondensationDofMap::reinit(), libMesh::BoundaryInfo::remove_edge_id(), libMesh::BoundaryInfo::remove_node_id(), libMesh::BoundaryInfo::remove_shellface_id(), libMesh::BoundaryInfo::remove_side_id(), libMesh::DistributedMesh::renumber_dof_objects(), libMesh::DistributedMesh::renumber_nodes_and_elements(), LinearElasticityWithContact::residual_and_jacobian(), OverlappingAlgebraicGhostingTest::run_ghosting_test(), OverlappingCouplingGhostingTest::run_sparsity_pattern_test(), scale_mesh_and_plot(), libMesh::DofMap::scatter_constraints(), libMesh::CheckpointIO::select_split_config(), libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::send_and_insert_dof_values(), libMesh::TransientRBConstruction::set_error_temporal_data(), libMesh::Partitioner::set_interface_node_processor_ids_BFS(), libMesh::Partitioner::set_interface_node_processor_ids_linear(), libMesh::Partitioner::set_interface_node_processor_ids_petscpartitioner(), libMesh::Partitioner::set_node_processor_ids(), libMesh::DofMap::set_nonlocal_dof_objects(), libMesh::Partitioner::set_parent_processor_ids(), libMesh::PetscDMWrapper::set_point_range_in_section(), libMesh::PetscDiffSolver::setup_petsc_data(), libMesh::RBEIMEvaluation::side_distribute_bfs(), libMesh::RBEIMEvaluation::side_gather_bfs(), libMesh::RBEIMConstruction::side_inner_product(), libMesh::Partitioner::single_partition(), libMesh::LaplaceMeshSmoother::smooth(), libMesh::VariationalMeshSmoother::smooth(), libMesh::ClawSystem::solve_conservation_law(), libMesh::split_mesh(), libMesh::RBEIMConstruction::store_eim_solutions_for_training_set(), libMesh::MeshBase::subdomain_ids(), libMesh::BoundaryInfo::sync(), libMesh::MeshBase::sync_subdomain_name_map(), ConstraintOperatorTest::test1DCoarseningNewNodes(), ConstraintOperatorTest::test1DCoarseningOperator(), MeshFunctionTest::test_bad_gradient_var_with_out_of_mesh_value(), MeshFunctionTest::test_bad_hessian_var_with_out_of_mesh_value(), libMesh::MeshRefinement::test_level_one(), MeshfunctionDFEM::test_mesh_function_dfem(), MeshfunctionDFEM::test_mesh_function_dfem_grad(), MeshFunctionTest::test_p_level(), libMesh::MeshRefinement::test_unflagged(), DofMapTest::testBadElemFECombo(), SystemsTest::testBlockRestrictedVarNDofs(), BoundaryInfoTest::testBoundaryOnChildrenErrors(), VolumeTest::testC0PolygonMethods(), VolumeTest::testC0PolyhedronMethods(), ConstraintOperatorTest::testCoreform(), ConnectedComponentsTest::testEdge(), MeshInputTest::testExodusIGASidesets(), MeshTriangulationTest::testFoundCenters(), PointLocatorTest::testLocator(), BoundaryInfoTest::testMesh(), PointLocatorTest::testPlanar(), MeshTriangulationTest::testPoly2TriRefinementBase(), SystemsTest::testProjectCubeWithMeshFunction(), BoundaryInfoTest::testRenumber(), BoundaryInfoTest::testSelectiveRenumber(), CheckpointIOTest::testSplitter(), MeshInputTest::testTetgenIO(), MeshTriangulationTest::testTriangulatorInterp(), MeshTriangulationTest::testTriangulatorMeshedHoles(), MeshTriangulationTest::testTriangulatorRoundHole(), MeshSmootherTest::testVariationalSmoother(), libMesh::MeshTools::total_weight(), libMesh::RBConstruction::train_reduced_basis_with_POD(), libMesh::MeshFunctionSolutionTransfer::transfer(), libMesh::MeshfreeSolutionTransfer::transfer(), libMesh::Poly2TriTriangulator::triangulate(), libMesh::TransientRBConstruction::truth_assembly(), libMesh::RBConstruction::truth_assembly(), libMesh::MeshRefinement::uniformly_coarsen(), update_current_local_solution(), libMesh::TransientRBConstruction::update_RB_initial_condition_all_N(), libMesh::TransientRBConstruction::update_RB_system_matrices(), libMesh::RBConstruction::update_RB_system_matrices(), libMesh::TransientRBConstruction::update_residual_terms(), libMesh::RBConstruction::update_residual_terms(), libMesh::MeshTools::volume(), libMesh::STLIO::write(), libMesh::NameBasedIO::write(), libMesh::XdrIO::write(), libMesh::VTKIO::write_nodal_data(), libMesh::RBEIMEvaluation::write_out_interior_basis_functions(), libMesh::RBEIMEvaluation::write_out_node_basis_functions(), libMesh::RBEIMEvaluation::write_out_side_basis_functions(), libMesh::RBEvaluation::write_out_vectors(), libMesh::TransientRBConstruction::write_riesz_representors_to_files(), libMesh::RBConstruction::write_riesz_representors_to_files(), libMesh::System::write_SCALAR_dofs(), libMesh::XdrIO::write_serialized_bcs_helper(), libMesh::System::write_serialized_blocked_dof_objects(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::XdrIO::write_serialized_nodes(), libMesh::XdrIO::write_serialized_nodesets(), libMesh::RBDataSerialization::RBEvaluationSerialization::write_to_file(), libMesh::RBDataSerialization::TransientRBEvaluationSerialization::write_to_file(), libMesh::RBDataSerialization::RBEIMEvaluationSerialization::write_to_file(), and libMesh::RBDataSerialization::RBSCMEvaluationSerialization::write_to_file().

98  { return _communicator; }
const Parallel::Communicator & _communicator

◆ copy_elemental_solution()

void libMesh::ExodusII_IO::copy_elemental_solution ( System system,
std::string  system_var_name,
std::string  exodus_var_name,
unsigned int  timestep = 1 
)

If we read in a elemental solution while reading in a mesh, we can attempt to copy that elemental solution into an EquationSystems object.

Note
This function cannot be used with renumbering. For more information, see MeshBase::allow_renumbering(). If you need both renumbering and nodal solution vectors, then disable renumbering, load the solution vectors, and then reenable renumbering.

Definition at line 1161 of file exodusII_io.C.

References libMesh::MeshBase::allow_renumbering(), libMesh::ParallelObject::comm(), libMesh::CONSTANT, libMesh::DofObject::dof_number(), exio_helper, libMesh::System::get_dof_map(), libMesh::MeshBase::is_serial_on_zero(), libMesh::libmesh_isnan(), libMesh::DofMap::local_index(), libMesh::MeshInput< MeshBase >::mesh(), libMesh::MeshInput< MT >::mesh(), libMesh::MONOMIAL, libMesh::MONOMIAL_VEC, libMesh::DofObject::n_comp(), libMesh::System::number(), libMesh::ParallelObject::processor_id(), libMesh::MeshBase::query_elem_ptr(), TIMPI::Communicator::rank(), libMesh::Real, libMesh::System::solution, libMesh::System::update(), libMesh::System::variable_number(), and libMesh::System::variable_type().

Referenced by MeshInputTest::testExodusWriteElementDataFromDiscontinuousNodalData().

1165 {
1166  LOG_SCOPE("copy_elemental_solution()", "ExodusII_IO");
1167 
1168  const unsigned int var_num = system.variable_number(system_var_name);
1169  // Assert that variable is an elemental one.
1170  //
1171  // NOTE: Currently, this reader is capable of reading only individual components of MONOMIAL_VEC
1172  // types, and each must be written out to its own CONSTANT MONOMIAL variable
1173  libmesh_error_msg_if((system.variable_type(var_num) != FEType(CONSTANT, MONOMIAL))
1174  && (system.variable_type(var_num) != FEType(CONSTANT, MONOMIAL_VEC)),
1175  "Error! Trying to copy elemental solution into a variable that is not of CONSTANT MONOMIAL nor CONSTANT MONOMIAL_VEC type.");
1176 
1178  const DofMap & dof_map = system.get_dof_map();
1179 
1180  libmesh_error_msg_if(mesh.allow_renumbering(),
1181  "ERROR, elemental data cannot be loaded if the mesh may be renumbered!");
1182 
1183  // Map from element ID to elemental variable value. We need to use
1184  // a map here rather than a vector (e.g. elem_var_values) since the
1185  // libmesh element numbering can contain "holes". This is the case
1186  // if we are reading elemental var values from an adaptively refined
1187  // mesh that has not been sequentially renumbered.
1188  std::map<dof_id_type, Real> elem_var_value_map;
1189 
1190  // With Exodus files we only open them on processor 0, so that's the
1191  // where we have to do the data read too.
1192  if (system.comm().rank() == 0)
1193  {
1194  libmesh_error_msg_if(!exio_helper->opened_for_reading,
1195  "ERROR, ExodusII file must be opened for reading before copying an elemental solution!");
1196 
1197  exio_helper->read_elemental_var_values(exodus_var_name, timestep, elem_var_value_map);
1198  }
1199 
1200  const bool serial_on_zero = mesh.is_serial_on_zero();
1201 
1202  // If our mesh isn't serial, then non-root processors need to
1203  // request the data for their parts of the mesh and insert it
1204  // themselves.
1205  if (!serial_on_zero)
1206  {
1207  std::unordered_map<processor_id_type, std::vector<dof_id_type>> elem_ids_to_request;
1208  if (this->processor_id() != 0)
1209  {
1210  std::vector<dof_id_type> elem_ids;
1211  for (auto & elem : mesh.active_local_element_ptr_range())
1212  elem_ids.push_back(elem->id());
1213 
1214  if (!elem_ids.empty())
1215  elem_ids_to_request[0] = std::move(elem_ids);
1216  }
1217 
1218  auto value_gather_functor =
1219  [& elem_var_value_map]
1221  const std::vector<dof_id_type> & ids,
1222  std::vector<Real> & values)
1223  {
1224  const std::size_t query_size = ids.size();
1225  values.resize(query_size);
1226  for (std::size_t i=0; i != query_size; ++i)
1227  {
1228  if (const auto it = elem_var_value_map.find(ids[i]);
1229  it != elem_var_value_map.end())
1230  {
1231  values[i] = it->second;
1232  elem_var_value_map.erase(it);
1233  }
1234  else
1235  values[i] = std::numeric_limits<Real>::quiet_NaN();
1236  }
1237  };
1238 
1239  auto value_action_functor =
1240  [& elem_var_value_map]
1242  const std::vector<dof_id_type> & ids,
1243  const std::vector<Real> & values)
1244  {
1245  const std::size_t query_size = ids.size();
1246  for (std::size_t i=0; i != query_size; ++i)
1247  if (!libmesh_isnan(values[i]))
1248  elem_var_value_map[ids[i]] = values[i];
1249  };
1250 
1251  Real * value_ex = nullptr;
1252  Parallel::pull_parallel_vector_data
1253  (system.comm(), elem_ids_to_request, value_gather_functor,
1254  value_action_functor, value_ex);
1255  }
1256 
1257  std::map<dof_id_type, Real>::iterator
1258  it = elem_var_value_map.begin(),
1259  end = elem_var_value_map.end();
1260 
1261  // Everybody inserts the data they've received. If we're
1262  // serial_on_zero then proc 0 inserts everybody's data and other
1263  // procs have empty map ranges.
1264  for (; it!=end; ++it)
1265  {
1266  const Elem * elem = mesh.query_elem_ptr(it->first);
1267 
1268  if (elem && elem->n_comp(system.number(), var_num) > 0)
1269  {
1270  dof_id_type dof_index = elem->dof_number(system.number(), var_num, 0);
1271  if (serial_on_zero || dof_map.local_index(dof_index ))
1272  system.solution->set (dof_index, it->second);
1273  }
1274  }
1275 
1276  system.solution->close();
1277  system.update();
1278 }
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:196
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
Definition: dof_object.h:1008
unsigned int n_comp(const unsigned int s, const unsigned int var) const
Definition: dof_object.h:978
void allow_renumbering(bool allow)
If false is passed in then this mesh will no longer be renumbered when being prepared for use...
Definition: mesh_base.h:1345
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
processor_id_type rank() const
const Parallel::Communicator & comm() const
bool libmesh_isnan(T x)
uint8_t processor_id_type
Definition: id_types.h:104
This is the MeshBase class.
Definition: mesh_base.h:80
unsigned int variable_number(std::string_view var) const
Definition: system.C:1398
virtual bool is_serial_on_zero() const
Definition: mesh_base.h:354
This class handles the numbering of degrees of freedom on a mesh.
Definition: dof_map.h:179
unsigned int number() const
Definition: system.h:2393
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition: system.h:1655
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676
virtual void update()
Update the local values to reflect the solution on neighboring processors.
Definition: system.C:498
const FEType & variable_type(const unsigned int i) const
Definition: system.C:2721
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0
processor_id_type processor_id() const
const DofMap & get_dof_map() const
Definition: system.h:2417
uint8_t dof_id_type
Definition: id_types.h:67
bool local_index(dof_id_type dof_index) const
Definition: dof_map.h:967

◆ copy_nodal_solution()

void libMesh::ExodusII_IO::copy_nodal_solution ( System system,
std::string  system_var_name,
std::string  exodus_var_name,
unsigned int  timestep = 1 
)

If we read in a nodal solution while reading in a mesh, we can attempt to copy that nodal solution into an EquationSystems object.

Note
This function cannot be used with renumbering. For more information, see MeshBase::allow_renumbering(). If you need both renumbering and nodal solution vectors, then disable renumbering, load the solution vectors, and then reenable renumbering.

Definition at line 1054 of file exodusII_io.C.

References libMesh::MeshBase::allow_renumbering(), libMesh::ParallelObject::comm(), libMesh::DofObject::dof_number(), exio_helper, libMesh::MeshBase::is_serial_on_zero(), libMesh::libmesh_isnan(), libMesh::MeshInput< MeshBase >::mesh(), libMesh::MeshInput< MT >::mesh(), libMesh::DofObject::n_comp(), libMesh::System::number(), libMesh::ParallelObject::processor_id(), libMesh::DofObject::processor_id(), TIMPI::Communicator::rank(), libMesh::Real, libMesh::System::solution, libMesh::System::update(), and libMesh::System::variable_number().

Referenced by WriteVecAndScalar::testWriteExodus().

1058 {
1059  LOG_SCOPE("copy_nodal_solution()", "ExodusII_IO");
1060 
1061  const unsigned int var_num = system.variable_number(system_var_name);
1062 
1064 
1065  libmesh_error_msg_if(mesh.allow_renumbering(),
1066  "ERROR, nodal data cannot be loaded if the mesh may be renumbered!");
1067 
1068  // With Exodus files we only open them on processor 0, so that's the
1069  // where we have to do the data read too.
1070  if (system.comm().rank() == 0)
1071  {
1072  libmesh_error_msg_if(!exio_helper->opened_for_reading,
1073  "ERROR, ExodusII file must be opened for reading before copying a nodal solution!");
1074 
1075  exio_helper->read_nodal_var_values(exodus_var_name, timestep);
1076  }
1077 
1078  auto & node_var_value_map = exio_helper->nodal_var_values;
1079 
1080  const bool serial_on_zero = mesh.is_serial_on_zero();
1081 
1082  // If our mesh isn't serial, then non-root processors need to
1083  // request the data for their parts of the mesh and insert it
1084  // themselves.
1085  if (!serial_on_zero)
1086  {
1087  std::unordered_map<processor_id_type, std::vector<dof_id_type>> node_ids_to_request;
1088  if (this->processor_id() != 0)
1089  {
1090  std::vector<dof_id_type> node_ids;
1091  for (auto & node : mesh.local_node_ptr_range())
1092  node_ids.push_back(node->id());
1093  if (!node_ids.empty())
1094  node_ids_to_request[0] = std::move(node_ids);
1095  }
1096 
1097  auto value_gather_functor =
1098  [& node_var_value_map]
1100  const std::vector<dof_id_type> & ids,
1101  std::vector<Real> & values)
1102  {
1103  const std::size_t query_size = ids.size();
1104  values.resize(query_size);
1105  for (std::size_t i=0; i != query_size; ++i)
1106  {
1107  if (const auto it = node_var_value_map.find(ids[i]);
1108  it != node_var_value_map.end())
1109  {
1110  values[i] = it->second;
1111  node_var_value_map.erase(it);
1112  }
1113  else
1114  values[i] = std::numeric_limits<Real>::quiet_NaN();
1115  }
1116  };
1117 
1118  auto value_action_functor =
1119  [& node_var_value_map]
1121  const std::vector<dof_id_type> & ids,
1122  const std::vector<Real> & values)
1123  {
1124  const std::size_t query_size = ids.size();
1125  for (std::size_t i=0; i != query_size; ++i)
1126  if (!libmesh_isnan(values[i]))
1127  node_var_value_map[ids[i]] = values[i];
1128  };
1129 
1130  Real * value_ex = nullptr;
1131  Parallel::pull_parallel_vector_data
1132  (system.comm(), node_ids_to_request, value_gather_functor,
1133  value_action_functor, value_ex);
1134  }
1135 
1136  // Everybody inserts the data they've received. If we're
1137  // serial_on_zero then proc 0 inserts everybody's data and other
1138  // procs have empty map ranges.
1139  for (auto p : exio_helper->nodal_var_values)
1140  {
1141  dof_id_type i = p.first;
1142  const Node * node = MeshInput<MeshBase>::mesh().query_node_ptr(i);
1143 
1144  if (node &&
1145  (serial_on_zero || node->processor_id() == system.processor_id()) &&
1146  node->n_comp(system.number(), var_num) > 0)
1147  {
1148  dof_id_type dof_index = node->dof_number(system.number(), var_num, 0);
1149 
1150  // If the dof_index is local to this processor, set the value
1151  system.solution->set (dof_index, p.second);
1152  }
1153  }
1154 
1155  system.solution->close();
1156  system.update();
1157 }
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
Definition: dof_object.h:1008
A Node is like a Point, but with more information.
Definition: node.h:52
unsigned int n_comp(const unsigned int s, const unsigned int var) const
Definition: dof_object.h:978
void allow_renumbering(bool allow)
If false is passed in then this mesh will no longer be renumbered when being prepared for use...
Definition: mesh_base.h:1345
processor_id_type rank() const
const Parallel::Communicator & comm() const
bool libmesh_isnan(T x)
uint8_t processor_id_type
Definition: id_types.h:104
This is the MeshBase class.
Definition: mesh_base.h:80
unsigned int variable_number(std::string_view var) const
Definition: system.C:1398
virtual bool is_serial_on_zero() const
Definition: mesh_base.h:354
unsigned int number() const
Definition: system.h:2393
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition: system.h:1655
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676
virtual void update()
Update the local values to reflect the solution on neighboring processors.
Definition: system.C:498
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
processor_id_type processor_id() const
processor_id_type processor_id() const
Definition: dof_object.h:881
uint8_t dof_id_type
Definition: id_types.h:67

◆ copy_scalar_solution()

void libMesh::ExodusII_IO::copy_scalar_solution ( System system,
std::vector< std::string >  system_var_names,
std::vector< std::string >  exodus_var_names,
unsigned int  timestep = 1 
)

Copy global variables into scalar variables of a System object.

Definition at line 1280 of file exodusII_io.C.

References libMesh::ParallelObject::comm(), exio_helper, libMesh::System::get_dof_map(), TIMPI::Communicator::get_unique_tag(), libMesh::index_range(), libMesh::ParallelObject::n_processors(), libMesh::ParallelObject::processor_id(), read_global_variable(), TIMPI::Communicator::receive(), libMesh::DofMap::SCALAR_dof_indices(), TIMPI::Communicator::send(), libMesh::System::solution, libMesh::System::update(), and libMesh::System::variable_scalar_number().

1284 {
1285  LOG_SCOPE("copy_scalar_solution()", "ExodusII_IO");
1286 
1287  libmesh_error_msg_if(!exio_helper->opened_for_reading,
1288  "ERROR, ExodusII file must be opened for reading before copying a scalar solution!");
1289 
1290  libmesh_error_msg_if(system_var_names.size() != exodus_var_names.size(),
1291  "ERROR, the number of system_var_names must match exodus_var_names.");
1292 
1293  std::vector<Real> values_from_exodus;
1294  read_global_variable(exodus_var_names, timestep, values_from_exodus);
1295 
1296 #ifdef LIBMESH_HAVE_MPI
1297  if (this->n_processors() > 1)
1298  {
1299  const Parallel::MessageTag tag = this->comm().get_unique_tag(1);
1300  if (this->processor_id() == this->n_processors()-1)
1301  this->comm().receive(0, values_from_exodus, tag);
1302  if (this->processor_id() == 0)
1303  this->comm().send(this->n_processors()-1, values_from_exodus, tag);
1304  }
1305 #endif
1306 
1307  if (system.processor_id() == (system.n_processors()-1))
1308  {
1309  const DofMap & dof_map = system.get_dof_map();
1310 
1311  for (auto i : index_range(system_var_names))
1312  {
1313  const unsigned int var_num = system.variable_scalar_number(system_var_names[i], 0);
1314 
1315  std::vector<dof_id_type> SCALAR_dofs;
1316  dof_map.SCALAR_dof_indices(SCALAR_dofs, var_num);
1317 
1318  system.solution->set (SCALAR_dofs[0], values_from_exodus[i]);
1319  }
1320  }
1321 
1322  system.solution->close();
1323  system.update();
1324 }
unsigned int variable_scalar_number(std::string_view var, unsigned int component) const
Definition: system.h:2474
MessageTag get_unique_tag(int tagvalue=MessageTag::invalid_tag) const
const Parallel::Communicator & comm() const
void SCALAR_dof_indices(std::vector< dof_id_type > &di, const unsigned int vn, const bool old_dofs=false) const
Fills the vector di with the global degree of freedom indices corresponding to the SCALAR variable vn...
Definition: dof_map.C:2605
This class handles the numbering of degrees of freedom on a mesh.
Definition: dof_map.h:179
processor_id_type n_processors() const
Status receive(const unsigned int dest_processor_id, T &buf, const MessageTag &tag=any_tag) const
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition: system.h:1655
void read_global_variable(std::vector< std::string > global_var_names, unsigned int timestep, std::vector< Real > &global_values)
Given a vector of global variables and a time step, returns the values of the global variable at the ...
Definition: exodusII_io.C:1343
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676
virtual void update()
Update the local values to reflect the solution on neighboring processors.
Definition: system.C:498
void send(const unsigned int dest_processor_id, const T &buf, const MessageTag &tag=no_tag) const
processor_id_type processor_id() const
const DofMap & get_dof_map() const
Definition: system.h:2417
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:153

◆ get_add_sides()

bool libMesh::ExodusII_IO::get_add_sides ( )
overridevirtual
Returns
Whether or not added sides are expected to be output, to plot SIDE_DISCONTINUOUS data. Subclasses should override this if they are capable of plotting such data.

Reimplemented from libMesh::MeshOutput< MeshBase >.

Definition at line 1023 of file exodusII_io.C.

References exio_helper.

Referenced by write_discontinuous_exodusII(), and write_nodal_data_discontinuous().

1024 {
1025  return exio_helper->get_add_sides();
1026 }
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ get_elem_num_map()

const std::vector< int > & libMesh::ExodusII_IO::get_elem_num_map ( ) const

Returns a const reference to the elem_num_map, which is a vector that is created when a Mesh is read from file.

LibMesh will number its mesh elements consistently with the elem_num_map array, except that the indices in this array are 1-based, and libmesh always uses a 0-based numbering. For example, given: elem_num_map = [4,2,3,1] libmesh will assign the first element it reads from the Exodus file elem->id() == 3, the second will get elem->id() == 1, and so on. We note that not all Exodus files contain an elem_num_map, and in that case, calling this function will return a reference to a vector containing the 1-based identity array, [1,2,3,...]

Definition at line 2398 of file exodusII_io.C.

References exio_helper.

Referenced by ExtraIntegersTest::testExtraIntegersExodusReading().

2399 {
2400  // We could make this function non-const and have it call
2401  // exio_helper->read_elem_num_map() before returning a reference...
2402  // but the intention is that this will be called some time after a
2403  // mesh is read in, in which case it would be doing extra work to
2404  // read in the elem_num_map twice.
2405  return exio_helper->elem_num_map;
2406 }
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ get_elem_var_names()

const std::vector< std::string > & libMesh::ExodusII_IO::get_elem_var_names ( )

Return list of the elemental variable names.

Definition at line 2386 of file exodusII_io.C.

References libMesh::ExodusII_IO_Helper::ELEMENTAL, and exio_helper.

2387 {
2388  exio_helper->read_var_names(ExodusII_IO_Helper::ELEMENTAL);
2389  return exio_helper->elem_var_names;
2390 }
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ get_elemset_data_indices()

void libMesh::ExodusII_IO::get_elemset_data_indices ( std::map< std::pair< dof_id_type, elemset_id_type >, unsigned int > &  elemset_array_indices)

Similar to read_elemset_data(), but instead of creating one std::map per nodeset per variable, creates a single map of (elem_id, elemset_id) pairs -> exo file array indices for any/all variables on that elemset (they are all the same).

In cases where there are hundreds of elemset variables on a single elemset, it is more efficient to store the array indices in a quickly searchable data structure than to repeat the indexing once per variable as is done in the read_elemset_data() case.

Definition at line 2187 of file exodusII_io.C.

References exio_helper.

2188 {
2189  libmesh_error_msg_if(!exio_helper->opened_for_reading,
2190  "ERROR, ExodusII file must be opened for reading "
2191  "before calling ExodusII_IO::get_elemset_data_indices()!");
2192 
2193  exio_helper->get_elemset_data_indices(elemset_array_indices);
2194 }
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ get_exio_helper()

ExodusII_IO_Helper & libMesh::ExodusII_IO::get_exio_helper ( )

Return a reference to the ExodusII_IO_Helper object.

Definition at line 2413 of file exodusII_io.C.

References exio_helper.

2414 {
2415  // Provide a warning when accessing the helper object
2416  // since it is a non-public API and is likely to see
2417  // future API changes
2418  libmesh_experimental();
2419 
2420  return *exio_helper;
2421 }
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ get_exodus_version()

int libMesh::ExodusII_IO::get_exodus_version ( )
static
Returns
The ExodusII API version, in "nodot" format (e.g. 822 for 8.22), or 0 if ExodusII support is not available.

Definition at line 170 of file exodusII_io.C.

References libMesh::ExodusII_IO_Helper::get_exodus_version().

Referenced by MeshInputTest::testExodusFileMappings(), and MeshInputTest::testExodusIGASidesets().

171 {
172 #ifdef LIBMESH_HAVE_EXODUS_API
174 #else
175  return 0;
176 #endif
177 }

◆ get_global_var_names()

const std::vector< std::string > & libMesh::ExodusII_IO::get_global_var_names ( )

Return list of the global variable names.

Definition at line 2392 of file exodusII_io.C.

References exio_helper, and libMesh::ExodusII_IO_Helper::GLOBAL.

2393 {
2394  exio_helper->read_var_names(ExodusII_IO_Helper::GLOBAL);
2395  return exio_helper->global_var_names;
2396 }
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ get_nodal_var_names()

const std::vector< std::string > & libMesh::ExodusII_IO::get_nodal_var_names ( )

Return list of the nodal variable names.

Definition at line 2380 of file exodusII_io.C.

References exio_helper, and libMesh::ExodusII_IO_Helper::NODAL.

Referenced by WriteVecAndScalar::testWriteExodus().

2381 {
2382  exio_helper->read_var_names(ExodusII_IO_Helper::NODAL);
2383  return exio_helper->nodal_var_names;
2384 }
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ get_node_num_map()

const std::vector< int > & libMesh::ExodusII_IO::get_node_num_map ( ) const

Identical to the behavior of get_elem_num_map(), but for the node_num_map instead.

Definition at line 2408 of file exodusII_io.C.

References exio_helper.

Referenced by ExtraIntegersTest::testExtraIntegersExodusReading().

2409 {
2410  return exio_helper->node_num_map;
2411 }
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ get_nodeset_data_indices()

void libMesh::ExodusII_IO::get_nodeset_data_indices ( std::map< BoundaryInfo::NodeBCTuple, unsigned int > &  bc_array_indices)

Similar to read_nodeset_data(), but instead of creating one std::map per nodeset per variable, creates a single map of (node_id, boundary_id) tuples, and stores the exo file array indices for any/all nodeset variables on that nodeset (they are all the same).

In cases where there are hundreds of nodeset variables on a single nodeset, it is more efficient to store the array indices in a quickly searchable data structure than to repeat the indexing once per variable as is done in the read_nodeset_data() case.

Definition at line 2117 of file exodusII_io.C.

References exio_helper.

2118 {
2119  libmesh_error_msg_if(!exio_helper->opened_for_reading,
2120  "ERROR, ExodusII file must be opened for reading "
2121  "before calling ExodusII_IO::get_nodeset_data_indices()!");
2122 
2123  exio_helper->get_nodeset_data_indices(bc_array_indices);
2124 }
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ get_num_time_steps()

int libMesh::ExodusII_IO::get_num_time_steps ( )
Returns
The number of timesteps currently stored in the Exodus file.

Knowing the number of time steps currently stored in the file is sometimes necessary when appending, so we can know where to start writing new data. Throws an error if the file is not currently open for reading or writing.

Definition at line 1043 of file exodusII_io.C.

References exio_helper.

1044 {
1045  libmesh_error_msg_if(!exio_helper->opened_for_reading && !exio_helper->opened_for_writing,
1046  "ERROR, ExodusII file must be opened for reading or writing before calling ExodusII_IO::get_num_time_steps()!");
1047 
1048  exio_helper->read_num_time_steps();
1049  return exio_helper->num_time_steps;
1050 }
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ get_sideset_data_indices()

void libMesh::ExodusII_IO::get_sideset_data_indices ( std::map< BoundaryInfo::BCTuple, unsigned int > &  bc_array_indices)

Similar to read_sideset_data(), but instead of creating one std::map per sideset per variable, creates a single map of (elem, side, boundary_id) tuples, and stores the exo file array indices for any/all sideset variables on that sideset (they are all the same).

In cases where there are hundreds of sideset variables on a single sideset, it is more efficient to store the array indices in a quickly searchable data structure than to repeat the indexing once per variable as is done in the read_sideset_data() case.

Definition at line 2104 of file exodusII_io.C.

References exio_helper, libMesh::MeshInput< MeshBase >::mesh(), and libMesh::MeshOutput< MT >::mesh().

2106 {
2107  libmesh_error_msg_if(!exio_helper->opened_for_reading,
2108  "ERROR, ExodusII file must be opened for reading "
2109  "before calling ExodusII_IO::get_sideset_data_indices()!");
2110 
2112  exio_helper->get_sideset_data_indices(mesh, bc_array_indices);
2113 }
const MT & mesh() const
Definition: mesh_output.h:259
This is the MeshBase class.
Definition: mesh_base.h:80
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ get_time_steps()

const std::vector< Real > & libMesh::ExodusII_IO::get_time_steps ( )
Returns
An array containing the timesteps in the file.

Definition at line 1031 of file exodusII_io.C.

References exio_helper.

1032 {
1033  libmesh_error_msg_if
1034  (!exio_helper->opened_for_reading,
1035  "ERROR, ExodusII file must be opened for reading before calling ExodusII_IO::get_time_steps()!");
1036 
1037  exio_helper->read_time_steps();
1038  return exio_helper->time_steps;
1039 }
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ is_parallel_format()

bool libMesh::MeshInput< MeshBase >::is_parallel_format ( ) const
inlineinherited

Returns true iff this mesh file format and input class are parallelized, so that all processors can read their share of the data at once.

Definition at line 87 of file mesh_input.h.

References libMesh::MeshInput< MT >::_is_parallel_format.

87 { return this->_is_parallel_format; }
const bool _is_parallel_format
Flag specifying whether this format is parallel-capable.
Definition: mesh_input.h:130

◆ mesh() [1/2]

MeshBase & libMesh::MeshInput< MeshBase >::mesh ( )
inlineprotectedinherited
Returns
The object as a writable reference.

Definition at line 178 of file mesh_input.h.

Referenced by libMesh::GMVIO::_read_one_cell(), libMesh::VTKIO::cells_to_vtk(), libMesh::Nemesis_IO::copy_elemental_solution(), copy_elemental_solution(), copy_nodal_solution(), libMesh::TetGenIO::element_in(), libMesh::UNVIO::elements_in(), libMesh::UNVIO::elements_out(), libMesh::VTKIO::get_local_node_values(), get_sideset_data_indices(), libMesh::UNVIO::groups_in(), libMesh::TetGenIO::node_in(), libMesh::UNVIO::nodes_in(), libMesh::UNVIO::nodes_out(), libMesh::VTKIO::nodes_to_vtk(), libMesh::Nemesis_IO::prepare_to_write_nodal_data(), libMesh::GMVIO::read(), libMesh::STLIO::read(), libMesh::Nemesis_IO::read(), libMesh::XdrIO::read(), read(), libMesh::CheckpointIO::read(), libMesh::VTKIO::read(), libMesh::STLIO::read_ascii(), libMesh::CheckpointIO::read_bcs(), libMesh::STLIO::read_binary(), libMesh::CheckpointIO::read_connectivity(), read_header(), libMesh::CheckpointIO::read_header(), libMesh::XdrIO::read_header(), libMesh::UCDIO::read_implementation(), libMesh::UNVIO::read_implementation(), libMesh::GmshIO::read_mesh(), libMesh::DynaIO::read_mesh(), libMesh::CheckpointIO::read_nodes(), libMesh::CheckpointIO::read_nodesets(), libMesh::CheckpointIO::read_remote_elem(), libMesh::XdrIO::read_serialized_bcs_helper(), libMesh::XdrIO::read_serialized_connectivity(), libMesh::XdrIO::read_serialized_nodes(), libMesh::XdrIO::read_serialized_nodesets(), libMesh::XdrIO::read_serialized_subdomain_names(), read_sideset_data(), libMesh::OFFIO::read_stream(), libMesh::MatlabIO::read_stream(), libMesh::CheckpointIO::read_subdomain_names(), libMesh::STLIO::write(), libMesh::TetGenIO::write(), libMesh::Nemesis_IO::write(), libMesh::XdrIO::write(), libMesh::CheckpointIO::write(), write(), libMesh::GMVIO::write_ascii_new_impl(), libMesh::GMVIO::write_ascii_old_impl(), libMesh::GMVIO::write_binary(), libMesh::GMVIO::write_discontinuous_gmv(), libMesh::Nemesis_IO::write_element_data(), write_element_data(), write_elemsets(), libMesh::UCDIO::write_header(), libMesh::UCDIO::write_implementation(), libMesh::UCDIO::write_interior_elems(), libMesh::GmshIO::write_mesh(), libMesh::UCDIO::write_nodal_data(), libMesh::VTKIO::write_nodal_data(), write_nodal_data(), write_nodal_data_common(), write_nodal_data_discontinuous(), libMesh::UCDIO::write_nodes(), libMesh::CheckpointIO::write_nodesets(), libMesh::XdrIO::write_parallel(), libMesh::GmshIO::write_post(), libMesh::XdrIO::write_serialized_bcs_helper(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::XdrIO::write_serialized_nodes(), libMesh::XdrIO::write_serialized_nodesets(), libMesh::XdrIO::write_serialized_subdomain_names(), write_sideset_data(), libMesh::UCDIO::write_soln(), and libMesh::CheckpointIO::write_subdomain_names().

179 {
180  libmesh_error_msg_if(_obj == nullptr, "ERROR: _obj should not be nullptr!");
181  return *_obj;
182 }
MeshBase * _obj
A pointer to a non-const object object.
Definition: mesh_input.h:123

◆ mesh() [2/2]

const MeshBase & libMesh::MeshOutput< MeshBase >::mesh ( ) const
inlineprotectedinherited

◆ n_processors()

processor_id_type libMesh::ParallelObject::n_processors ( ) const
inlineinherited
Returns
The number of processors in the group.

Definition at line 103 of file parallel_object.h.

References libMesh::ParallelObject::_communicator, libMesh::libmesh_assert(), and TIMPI::Communicator::size().

Referenced by libMesh::Partitioner::_find_global_index_by_pid_map(), libMesh::BoundaryInfo::_find_id_maps(), libMesh::DofMap::add_constraints_to_send_list(), libMesh::PetscDMWrapper::add_dofs_to_section(), libMesh::DistributedMesh::add_elem(), libMesh::DofMap::add_neighbors_to_send_list(), libMesh::DistributedMesh::add_node(), libMesh::System::add_vector(), libMesh::LaplaceMeshSmoother::allgather_graph(), libMesh::DofMap::allgather_recursive_constraints(), libMesh::FEMSystem::assembly(), libMesh::Nemesis_IO::assert_symmetric_cmaps(), libMesh::Partitioner::assign_partitioning(), libMesh::AztecLinearSolver< T >::AztecLinearSolver(), libMesh::Partitioner::build_graph(), libMesh::EquationSystems::build_parallel_elemental_solution_vector(), libMesh::DistributedMesh::clear(), libMesh::DistributedMesh::clear_elems(), libMesh::Nemesis_IO_Helper::compute_border_node_ids(), libMesh::Nemesis_IO_Helper::construct_nemesis_filename(), libMesh::UnstructuredMesh::copy_nodes_and_elements(), libMesh::Nemesis_IO::copy_scalar_solution(), copy_scalar_solution(), libMesh::UnstructuredMesh::create_pid_mesh(), libMesh::MeshTools::create_processor_bounding_box(), libMesh::DofMap::distribute_dofs(), libMesh::DofMap::distribute_scalar_dofs(), libMesh::DistributedMesh::DistributedMesh(), libMesh::EnsightIO::EnsightIO(), libMesh::RBEIMEvaluation::gather_bfs(), libMesh::MeshBase::get_info(), libMesh::StaticCondensation::init(), libMesh::SystemSubsetBySubdomain::init(), libMesh::PetscDMWrapper::init_petscdm(), libMesh::Nemesis_IO_Helper::initialize(), libMesh::ExodusII_IO_Helper::initialize(), libMesh::DistributedMesh::insert_elem(), libMesh::NumericVector< Number >::is_effectively_ghosted(), libMesh::NumericVector< Number >::is_effectively_serial(), libMesh::MeshTools::libmesh_assert_contiguous_dof_ids(), libMesh::MeshTools::libmesh_assert_parallel_consistent_new_node_procids(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Elem >(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Node >(), libMesh::MeshTools::libmesh_assert_topology_consistent_procids< Node >(), libMesh::MeshTools::libmesh_assert_valid_boundary_ids(), libMesh::MeshTools::libmesh_assert_valid_dof_ids(), libMesh::MeshTools::libmesh_assert_valid_neighbors(), libMesh::MeshTools::libmesh_assert_valid_refinement_flags(), libMesh::DofMap::local_variable_indices(), libMesh::MeshRefinement::make_coarsening_compatible(), libMesh::MeshBase::n_active_elem_on_proc(), libMesh::DofMap::n_dofs_per_processor(), libMesh::MeshBase::n_elem_on_proc(), libMesh::MeshBase::n_nodes_on_proc(), libMesh::RBEIMEvaluation::node_gather_bfs(), libMesh::Partitioner::partition(), libMesh::MeshBase::partition(), libMesh::Partitioner::partition_unpartitioned_elements(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), libMesh::DofMap::prepare_send_list(), libMesh::MeshBase::print_constraint_rows(), libMesh::DofMap::print_dof_constraints(), libMesh::NameBasedIO::read(), libMesh::Nemesis_IO::read(), libMesh::CheckpointIO::read(), libMesh::CheckpointIO::read_connectivity(), libMesh::XdrIO::read_header(), libMesh::CheckpointIO::read_nodes(), libMesh::System::read_parallel_data(), libMesh::System::read_SCALAR_dofs(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::System::read_serialized_vector(), libMesh::DistributedMesh::renumber_dof_objects(), libMesh::Partitioner::repartition(), OverlappingFunctorTest::run_partitioner_test(), libMesh::DofMap::scatter_constraints(), libMesh::DistributedMesh::set_next_unique_id(), libMesh::DofMap::set_nonlocal_dof_objects(), libMesh::PetscDMWrapper::set_point_range_in_section(), WriteVecAndScalar::setupTests(), libMesh::RBEIMEvaluation::side_gather_bfs(), DistributedMeshTest::testRemoteElemError(), CheckpointIOTest::testSplitter(), libMesh::MeshRefinement::uniformly_coarsen(), libMesh::DistributedMesh::update_parallel_id_counts(), libMesh::GMVIO::write_binary(), libMesh::GMVIO::write_discontinuous_gmv(), libMesh::ExodusII_IO_Helper::write_nodal_coordinates(), libMesh::VTKIO::write_nodal_data(), write_nodal_data(), libMesh::System::write_parallel_data(), libMesh::System::write_SCALAR_dofs(), libMesh::XdrIO::write_serialized_bcs_helper(), libMesh::System::write_serialized_blocked_dof_objects(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::XdrIO::write_serialized_nodes(), and libMesh::XdrIO::write_serialized_nodesets().

104  {
105  processor_id_type returnval =
106  cast_int<processor_id_type>(_communicator.size());
107  libmesh_assert(returnval); // We never have an empty comm
108  return returnval;
109  }
const Parallel::Communicator & _communicator
processor_id_type size() const
uint8_t processor_id_type
libmesh_assert(ctx)

◆ operator=() [1/2]

ExodusII_IO& libMesh::ExodusII_IO::operator= ( const ExodusII_IO )
delete

◆ operator=() [2/2]

ExodusII_IO& libMesh::ExodusII_IO::operator= ( ExodusII_IO &&  )
delete

◆ processor_id()

processor_id_type libMesh::ParallelObject::processor_id ( ) const
inlineinherited
Returns
The rank of this processor in the group.

Definition at line 114 of file parallel_object.h.

References libMesh::ParallelObject::_communicator, and TIMPI::Communicator::rank().

Referenced by libMesh::BoundaryInfo::_find_id_maps(), libMesh::PetscDMWrapper::add_dofs_to_section(), libMesh::DistributedMesh::add_elem(), libMesh::BoundaryInfo::add_elements(), libMesh::DofMap::add_neighbors_to_send_list(), libMesh::DistributedMesh::add_node(), libMesh::MeshTools::Modification::all_tri(), libMesh::DofMap::allgather_recursive_constraints(), libMesh::FEMSystem::assembly(), libMesh::Nemesis_IO::assert_symmetric_cmaps(), libMesh::Partitioner::assign_partitioning(), libMesh::Nemesis_IO_Helper::build_element_and_node_maps(), libMesh::Partitioner::build_graph(), libMesh::InfElemBuilder::build_inf_elem(), libMesh::BoundaryInfo::build_node_list_from_side_list(), libMesh::EquationSystems::build_parallel_elemental_solution_vector(), libMesh::EquationSystems::build_parallel_solution_vector(), libMesh::MeshFunction::check_found_elem(), libMesh::DistributedMesh::clear(), libMesh::DistributedMesh::clear_elems(), libMesh::ExodusII_IO_Helper::close(), libMesh::Nemesis_IO_Helper::compute_border_node_ids(), libMesh::Nemesis_IO_Helper::compute_communication_map_parameters(), libMesh::Nemesis_IO_Helper::compute_internal_and_border_elems_and_internal_nodes(), libMesh::RBConstruction::compute_max_error_bound(), libMesh::Nemesis_IO_Helper::compute_node_communication_maps(), libMesh::Nemesis_IO_Helper::compute_num_global_elem_blocks(), libMesh::Nemesis_IO_Helper::compute_num_global_nodesets(), libMesh::Nemesis_IO_Helper::compute_num_global_sidesets(), libMesh::Nemesis_IO_Helper::construct_nemesis_filename(), copy_elemental_solution(), copy_nodal_solution(), libMesh::Nemesis_IO::copy_scalar_solution(), copy_scalar_solution(), libMesh::MeshTools::correct_node_proc_ids(), libMesh::ExodusII_IO_Helper::create(), libMesh::DistributedMesh::delete_elem(), libMesh::MeshCommunication::delete_remote_elements(), libMesh::DofMap::distribute_dofs(), libMesh::DofMap::distribute_scalar_dofs(), libMesh::DistributedMesh::DistributedMesh(), libMesh::DofMapBase::end_dof(), libMesh::DofMapBase::end_old_dof(), libMesh::EnsightIO::EnsightIO(), libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::find_dofs_to_send(), libMesh::UnstructuredMesh::find_neighbors(), libMesh::DofMapBase::first_dof(), libMesh::DofMapBase::first_old_dof(), libMesh::RBEIMEvaluation::gather_bfs(), libMesh::Nemesis_IO_Helper::get_cmap_params(), libMesh::Nemesis_IO_Helper::get_eb_info_global(), libMesh::Nemesis_IO_Helper::get_elem_cmap(), libMesh::Nemesis_IO_Helper::get_elem_map(), libMesh::MeshBase::get_info(), libMesh::DofMap::get_info(), libMesh::Nemesis_IO_Helper::get_init_global(), libMesh::Nemesis_IO_Helper::get_init_info(), libMesh::RBEIMEvaluation::get_interior_basis_functions_as_vecs(), libMesh::Nemesis_IO_Helper::get_loadbal_param(), libMesh::DofMap::get_local_constraints(), libMesh::MeshBase::get_local_constraints(), libMesh::Nemesis_IO_Helper::get_node_cmap(), libMesh::Nemesis_IO_Helper::get_node_map(), libMesh::Nemesis_IO_Helper::get_ns_param_global(), libMesh::Nemesis_IO_Helper::get_ss_param_global(), libMesh::SparsityPattern::Build::handle_vi_vj(), libMesh::LaplaceMeshSmoother::init(), libMesh::SystemSubsetBySubdomain::init(), HeatSystem::init_data(), libMesh::ExodusII_IO_Helper::initialize(), libMesh::ExodusII_IO_Helper::initialize_element_variables(), libMesh::ExodusII_IO_Helper::initialize_global_variables(), libMesh::ExodusII_IO_Helper::initialize_nodal_variables(), libMesh::DistributedMesh::insert_elem(), libMesh::DofMap::is_evaluable(), libMesh::SparsityPattern::Build::join(), libMesh::TransientRBEvaluation::legacy_write_offline_data_to_files(), libMesh::RBSCMEvaluation::legacy_write_offline_data_to_files(), libMesh::RBEvaluation::legacy_write_offline_data_to_files(), libMesh::MeshTools::libmesh_assert_consistent_distributed(), libMesh::MeshTools::libmesh_assert_consistent_distributed_nodes(), libMesh::MeshTools::libmesh_assert_contiguous_dof_ids(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Elem >(), libMesh::MeshTools::libmesh_assert_valid_neighbors(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_object_ids(), libMesh::DofMap::local_variable_indices(), main(), libMesh::MeshRefinement::make_coarsening_compatible(), AugmentSparsityOnInterface::mesh_reinit(), libMesh::TriangulatorInterface::MeshedHole::MeshedHole(), libMesh::MeshBase::n_active_local_elem(), libMesh::BoundaryInfo::n_boundary_conds(), libMesh::MeshTools::n_connected_components(), libMesh::MeshBase::n_constraint_rows(), libMesh::BoundaryInfo::n_edge_conds(), libMesh::DofMapBase::n_local_dofs(), libMesh::MeshBase::n_local_elem(), libMesh::MeshBase::n_local_nodes(), libMesh::BoundaryInfo::n_nodeset_conds(), libMesh::BoundaryInfo::n_shellface_conds(), libMesh::RBEIMEvaluation::node_gather_bfs(), libMesh::DistributedMesh::own_node(), libMesh::BoundaryInfo::parallel_sync_node_ids(), libMesh::BoundaryInfo::parallel_sync_side_ids(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), libMesh::MeshBase::print_constraint_rows(), libMesh::DofMap::print_dof_constraints(), libMesh::DofMap::process_mesh_constraint_rows(), libMesh::Nemesis_IO_Helper::put_cmap_params(), libMesh::Nemesis_IO_Helper::put_elem_cmap(), libMesh::Nemesis_IO_Helper::put_elem_map(), libMesh::Nemesis_IO_Helper::put_loadbal_param(), libMesh::Nemesis_IO_Helper::put_node_cmap(), libMesh::Nemesis_IO_Helper::put_node_map(), libMesh::NameBasedIO::read(), libMesh::Nemesis_IO::read(), libMesh::XdrIO::read(), libMesh::CheckpointIO::read(), libMesh::EquationSystems::read(), libMesh::ExodusII_IO_Helper::read_elem_num_map(), libMesh::ExodusII_IO_Helper::read_global_values(), read_header(), libMesh::CheckpointIO::read_header(), libMesh::XdrIO::read_header(), libMesh::System::read_header(), libMesh::DynaIO::read_mesh(), libMesh::ExodusII_IO_Helper::read_node_num_map(), libMesh::System::read_parallel_data(), libMesh::TransientRBConstruction::read_riesz_representors_from_files(), libMesh::RBConstruction::read_riesz_representors_from_files(), libMesh::System::read_SCALAR_dofs(), libMesh::XdrIO::read_serialized_bc_names(), libMesh::XdrIO::read_serialized_bcs_helper(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::XdrIO::read_serialized_connectivity(), libMesh::System::read_serialized_data(), libMesh::XdrIO::read_serialized_nodes(), libMesh::XdrIO::read_serialized_nodesets(), libMesh::XdrIO::read_serialized_subdomain_names(), libMesh::System::read_serialized_vector(), libMesh::System::read_serialized_vectors(), libMesh::Nemesis_IO_Helper::read_var_names_impl(), libMesh::SimplexRefiner::refine_via_edges(), libMesh::StaticCondensationDofMap::reinit(), libMesh::DistributedMesh::renumber_dof_objects(), libMesh::DistributedMesh::renumber_nodes_and_elements(), libMesh::DofMap::scatter_constraints(), libMesh::CheckpointIO::select_split_config(), libMesh::DistributedMesh::set_next_unique_id(), libMesh::DofMap::set_nonlocal_dof_objects(), libMesh::PetscDMWrapper::set_point_range_in_section(), libMesh::RBEIMEvaluation::side_gather_bfs(), MeshFunctionTest::test_bad_gradient_var_with_out_of_mesh_value(), MeshFunctionTest::test_bad_hessian_var_with_out_of_mesh_value(), ExodusTest< elem_type >::test_read_gold(), ExodusTest< elem_type >::test_write(), MeshInputTest::testAbaqusRead(), MeshInputTest::testBadGmsh(), BoundaryInfoTest::testBoundaryIDs(), MeshInputTest::testCopyElementSolutionImpl(), MeshInputTest::testCopyElementVectorImpl(), MeshInputTest::testCopyNodalSolutionImpl(), DefaultCouplingTest::testCoupling(), PointNeighborCouplingTest::testCoupling(), MeshInputTest::testDynaFileMappings(), MeshInputTest::testDynaNoSplines(), MeshInputTest::testDynaReadElem(), MeshInputTest::testDynaReadPatch(), MeshInputTest::testExodusFileMappings(), MeshInputTest::testExodusIGASidesets(), MeshInputTest::testExodusWriteElementDataFromDiscontinuousNodalData(), MeshInputTest::testGmshBCIDOverlap(), MeshInputTest::testGoodGmsh(), MeshInputTest::testGoodSTL(), MeshInputTest::testGoodSTLBinary(), BoundaryInfoTest::testInternalBoundary(), MeshInputTest::testLowOrderEdgeBlocks(), SystemsTest::testProjectMatrix3D(), BoundaryInfoTest::testShellFaceConstraints(), MeshInputTest::testSingleElementImpl(), WriteVecAndScalar::testSolution(), CheckpointIOTest::testSplitter(), MeshInputTest::testTetgenIO(), MeshSmootherTest::testVariationalSmoother(), libMesh::MeshTools::total_weight(), libMesh::NetGenMeshInterface::triangulate(), libMesh::MeshRefinement::uniformly_coarsen(), libMesh::DistributedMesh::update_parallel_id_counts(), libMesh::DTKAdapter::update_variable_values(), libMesh::MeshTools::volume(), libMesh::STLIO::write(), libMesh::NameBasedIO::write(), libMesh::XdrIO::write(), libMesh::CheckpointIO::write(), libMesh::EquationSystems::write(), libMesh::GMVIO::write_discontinuous_gmv(), write_element_data(), libMesh::ExodusII_IO_Helper::write_element_values(), libMesh::ExodusII_IO_Helper::write_element_values_element_major(), libMesh::ExodusII_IO_Helper::write_elements(), libMesh::ExodusII_IO_Helper::write_elemset_data(), libMesh::ExodusII_IO_Helper::write_elemsets(), write_global_data(), libMesh::ExodusII_IO_Helper::write_global_values(), libMesh::System::write_header(), write_information_records(), libMesh::ExodusII_IO_Helper::write_information_records(), libMesh::ExodusII_IO_Helper::write_nodal_coordinates(), libMesh::UCDIO::write_nodal_data(), libMesh::VTKIO::write_nodal_data(), write_nodal_data(), write_nodal_data_common(), write_nodal_data_discontinuous(), libMesh::ExodusII_IO_Helper::write_nodal_values(), libMesh::ExodusII_IO_Helper::write_nodeset_data(), libMesh::Nemesis_IO_Helper::write_nodesets(), libMesh::ExodusII_IO_Helper::write_nodesets(), libMesh::RBEIMEvaluation::write_out_interior_basis_functions(), libMesh::RBEIMEvaluation::write_out_node_basis_functions(), libMesh::RBEIMEvaluation::write_out_side_basis_functions(), write_output_solvedata(), libMesh::System::write_parallel_data(), libMesh::RBConstruction::write_riesz_representors_to_files(), libMesh::System::write_SCALAR_dofs(), libMesh::XdrIO::write_serialized_bc_names(), libMesh::XdrIO::write_serialized_bcs_helper(), libMesh::System::write_serialized_blocked_dof_objects(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::System::write_serialized_data(), libMesh::XdrIO::write_serialized_nodes(), libMesh::XdrIO::write_serialized_nodesets(), libMesh::XdrIO::write_serialized_subdomain_names(), libMesh::System::write_serialized_vector(), libMesh::System::write_serialized_vectors(), libMesh::ExodusII_IO_Helper::write_sideset_data(), libMesh::Nemesis_IO_Helper::write_sidesets(), libMesh::ExodusII_IO_Helper::write_sidesets(), write_timestep(), libMesh::ExodusII_IO_Helper::write_timestep(), and write_timestep_discontinuous().

115  { return cast_int<processor_id_type>(_communicator.rank()); }
processor_id_type rank() const
const Parallel::Communicator & _communicator

◆ read()

void libMesh::ExodusII_IO::read ( const std::string &  name)
overridevirtual

This method implements reading a mesh from a specified file.

Open the file named name and read the mesh in Sandia National Lab's ExodusII format. This is the method to use for reading in meshes generated by cubit. Works in 2D for TRIs, TRI6s, QUAD s, and QUAD9s. Works in 3D for TET4s, TET10s, HEX8s, and HEX27s.

Implements libMesh::MeshInput< MeshBase >.

Definition at line 246 of file exodusII_io.C.

References _disc_bex, _extra_integer_vars, _set_unique_ids_from_maps, libMesh::MeshBase::add_elem(), libMesh::MeshBase::add_elem_integer(), libMesh::MeshBase::add_elemset_code(), libMesh::BoundaryInfo::add_node(), libMesh::MeshBase::add_node_datum(), libMesh::MeshBase::add_point(), libMesh::TypeVector< T >::add_scaled(), libMesh::BoundaryInfo::add_shellface(), libMesh::BoundaryInfo::add_side(), libMesh::MeshBase::allow_node_and_elem_unique_id_overlap(), libMesh::Elem::build(), libMesh::MeshBase::clear(), libMesh::Elem::default_order(), libMesh::Elem::dim(), libMesh::MeshBase::elem_ptr(), libMesh::MeshBase::elem_ref(), libMesh::MeshInput< MeshBase >::elems_of_dimension, libMesh::Utility::enum_to_string(), exio_helper, libMesh::DynaIO::find_elem_definition(), libMesh::MeshBase::get_boundary_info(), libMesh::MeshBase::get_constraint_rows(), libMesh::MeshBase::get_elemset_code(), libMesh::DofObject::get_extra_datum(), libMesh::DofObject::id(), libMesh::index_range(), int, libMesh::DofObject::invalid_id, libMesh::ExodusII_IO_Helper::Conversion::invalid_id, libMesh::make_range(), libMesh::MeshInput< MT >::mesh(), libMesh::MeshInput< MeshBase >::mesh(), libMesh::MeshBase::mesh_dimension(), libMesh::MeshBase::n_elemsets(), n_nodes, libMesh::MeshBase::n_nodes(), libMesh::Elem::n_nodes(), libMesh::Elem::n_sides(), libMesh::Quality::name(), libMesh::MeshBase::node_ptr(), libMesh::MeshBase::node_ref(), libMesh::NODEELEM, libMesh::DynaIO::ElementDefinition::nodes, libMesh::BoundaryInfo::nodeset_name(), libMesh::RATIONAL_BERNSTEIN_MAP, libMesh::Real, libMesh::MeshBase::reserve_elem(), libMesh::MeshBase::reserve_nodes(), libMesh::MeshBase::set_default_mapping_data(), libMesh::MeshBase::set_default_mapping_type(), libMesh::DofObject::set_extra_datum(), libMesh::DofObject::set_extra_integer(), libMesh::MeshBase::set_mesh_dimension(), libMesh::Elem::set_node(), libMesh::BoundaryInfo::sideset_name(), libMesh::MeshBase::subdomain_name(), and libMesh::Elem::type().

Referenced by libMesh::NameBasedIO::read(), ExodusTest< elem_type >::test_read_gold(), ExodusTest< elem_type >::test_write(), ExtraIntegersTest::testBadExtraIntegersExodusReading(), MeshInputTest::testExodusFileMappings(), MeshInputTest::testExodusIGASidesets(), MeshInputTest::testExodusSetElemUniqueIdsFromMaps_implementation(), MeshInputTest::testExodusSetNodeUniqueIdsFromMaps_implementation(), MeshInputTest::testExodusWriteElementDataFromDiscontinuousNodalData(), ExtraIntegersTest::testExtraIntegersExodusReading(), MeshInputTest::testLowOrderEdgeBlocks(), and WriteVecAndScalar::testWriteExodus().

247 {
248  LOG_SCOPE("read()", "ExodusII_IO");
249 
250  // Get a reference to the mesh we are reading
252 
253  // Add extra integers into the mesh
254  std::vector<unsigned int> extra_ids;
255  for (auto & name : _extra_integer_vars)
256  extra_ids.push_back(mesh.add_elem_integer(name));
257 
258  // Clear any existing mesh data
259  mesh.clear();
260 
261  // Keep track of what kinds of elements this file contains
262  elems_of_dimension.clear();
263  elems_of_dimension.resize(4, false);
264 
265  // Open the exodus file in EX_READ mode
266  exio_helper->open(fname.c_str(), /*read_only=*/true);
267 
268  // Get header information from exodus file
269  exio_helper->read_and_store_header_info();
270 
271  // Read the QA records
272  exio_helper->read_qa_records();
273 
274  // Print header information
275  exio_helper->print_header();
276 
277  // Read nodes from the exodus file
278  exio_helper->read_nodes();
279 
280  // Reserve space for the nodes.
281  mesh.reserve_nodes(exio_helper->num_nodes);
282 
283  // Read the node number map from the Exodus file. This is
284  // required if we want to preserve the numbering of nodes as it
285  // exists in the Exodus file. If the Exodus file does not contain
286  // a node_num_map, the identity map is returned by this call.
287  exio_helper->read_node_num_map();
288 
289  // Read the element number map from the Exodus file. This is
290  // required if we want to preserve the numbering of elements as it
291  // exists in the Exodus file. If the Exodus file does not contain
292  // an elem_num_map, the identity map is returned by this call.
293  //
294  // We now do this before creating nodes, so if we have any spline
295  // nodes that need a NodeElem attached we can give them unused elem
296  // ids.
297  exio_helper->read_elem_num_map();
298 
299  // Read any Bezier Extraction coefficient vectors from the file,
300  // such as might occur in an IsoGeometric Analysis (IGA) mesh.
301  exio_helper->read_bex_cv_blocks();
302 
303  // If we have Rational Bezier weights, we'll need to
304  // store them.
305  unsigned char weight_index = 0;
306  const bool weights_exist = !exio_helper->w.empty();
307 
308  // If we have Bezier extraction coefficients, we'll need to put
309  // NODEELEM elements on spline nodes, since our Rational Bezier
310  // elements will be connected to nodes derived from those; nothing
311  // else will be directly connected to the spline nodes.
312  const bool bex_cv_exist = !exio_helper->bex_dense_constraint_vecs.empty();
313 
314  // If the user requests to set Node/Elem unique_ids based on the
315  // node/elem_num_maps, then it is very likely that those unique_ids
316  // will not be "unique" across the entire set of DofObjects (Nodes
317  // and Elems), although they should of course still be unique within
318  // the set of Nodes and the set of Elems on an individual basis. We
319  // therefore need to relax some of the uniqueness checking that is
320  // done in debug mode by setting the following flag on the Mesh.
323 
324  // Even if weights don't exist, we still use RATIONAL_BERNSTEIN for
325  // Bezier-Bernstein BEX elements, we just use 1.0 as the weight on
326  // every node.
327  if (bex_cv_exist)
328  {
329  const Real default_weight = 1.0;
330  weight_index = cast_int<unsigned char>
331  (mesh.add_node_datum<Real>("rational_weight", true,
332  &default_weight));
334  mesh.set_default_mapping_data(weight_index);
335  }
336 
337  std::unordered_map<const Node *, Elem *> spline_nodeelem_ptrs;
338 
339  // Loop over the nodes, create Nodes with local processor_id 0.
340  for (auto i : make_range(exio_helper->num_nodes))
341  {
342  // Determine the libmesh node id implied by "i". The
343  // get_libmesh_node_id() helper function expects a 1-based
344  // Exodus node id, so we construct the "implied" Exodus node id
345  // from "i" by adding 1.
346  auto libmesh_node_id = exio_helper->get_libmesh_node_id(/*exodus_node_id=*/i+1);
347 
348  // Catch the node that was added to the mesh
349  Node * added_node = mesh.add_point (Point(exio_helper->x[i], exio_helper->y[i], exio_helper->z[i]), libmesh_node_id);
350 
351  // Sanity check: throw an error if the Mesh assigned an ID to
352  // the Node which does not match the libmesh_id we just determined.
353  libmesh_error_msg_if(added_node->id() != static_cast<unsigned>(libmesh_node_id),
354  "Error! Mesh assigned node ID "
355  << added_node->id()
356  << " which is different from the (zero-based) Exodus ID "
357  << libmesh_node_id
358  << "!");
359 
360  // If the _set_unique_ids_from_maps flag is true, set the
361  // unique_id for "node", otherwise do nothing.
362  exio_helper->conditionally_set_node_unique_id(mesh, added_node, i);
363 
364  // If we have a set of spline weights, these nodes are going to
365  // be used as control points for Bezier elements, and we need
366  // to attach a NodeElem to each to make sure it doesn't get
367  // flagged as an unused node.
368  if (weights_exist)
369  {
370  const auto w = exio_helper->w[i];
371  Point & p = *added_node;
372  p /= w; // Exodus Bezier Extraction stores spline nodes in projective space
373 
374  added_node->set_extra_datum<Real>(weight_index, exio_helper->w[i]);
375  }
376 
377  if (bex_cv_exist)
378  {
379  std::unique_ptr<Elem> elem = Elem::build(NODEELEM);
380 
381  // Give the NodeElem ids at the end, so we can match any
382  // existing ids in the file for other elements
383  //
384  // We don't set the unique_id for this NodeElem here even if
385  // the user has set the _set_unique_ids_from_maps flag
386  // because these NodeElems don't have entries in the
387  // elem_num_map. Therefore, we just let the Mesh assign
388  // whatever unique_id is "next" as the Elem is added to the
389  // Mesh.
390  elem->set_id() = exio_helper->end_elem_id() + i;
391 
392  elem->set_node(0, added_node);
393  Elem * added_elem = mesh.add_elem(std::move(elem));
394  spline_nodeelem_ptrs[added_node] = added_elem;
395  }
396  }
397 
398  // This assert is no longer valid if the nodes are not numbered
399  // sequentially starting from 1 in the Exodus file.
400  // libmesh_assert_equal_to (static_cast<unsigned int>(exio_helper->num_nodes), mesh.n_nodes());
401 
402  // Get information about all the element and edge blocks
403  exio_helper->read_block_info();
404 
405  // Reserve space for the elements. Account for any NodeElem that
406  // have already been attached to spline control nodes.
407  mesh.reserve_elem(exio_helper->w.size() + exio_helper->num_elem);
408 
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
412  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]);
416 
417  // Read in the element connectivity for each block.
418  int nelem_last_block = 0;
419 
420  // If we're building Bezier elements from spline nodes, we need to
421  // calculate those elements' local nodes on the fly, and we'll be
422  // calculating them from constraint matrix columns, and we'll need
423  // to make sure that the same node is found each time it's
424  // calculated from multiple neighboring elements.
425  std::map<std::vector<std::pair<dof_id_type, Real>>, Node *> local_nodes;
426 
427  // We'll set any spline NodeElem subdomain_id() values to exceed the
428  // maximum of subdomain_id() values set via Exodus block ids.
429  subdomain_id_type max_subdomain_id = std::numeric_limits<subdomain_id_type>::min();
430 
431  // We've already added all the nodes explicitly specified in the
432  // file, but if we have spline nodes we may need to add assembly
433  // element nodes based on them. Add them contiguously so we're
434  // compatible with any subsequent code paths (including our
435  // ExodusII_IO::write()!) that don't support sparse ids.
437 
438  // Loop over all the element blocks
439  for (int i=0; i<exio_helper->num_elem_blk; i++)
440  {
441  // Read the information for block i
442  exio_helper->read_elem_in_block (i);
443  const subdomain_id_type subdomain_id =
444  restrict_int<subdomain_id_type>(exio_helper->get_block_id(i));
445  max_subdomain_id = std::max(max_subdomain_id, subdomain_id);
446 
447  // populate the map of names
448  std::string subdomain_name = exio_helper->get_block_name(i);
449  if (!subdomain_name.empty())
450  mesh.subdomain_name(subdomain_id) = subdomain_name;
451 
452  // Set any relevant node/edge maps for this element
453  const std::string type_str (exio_helper->get_elem_type());
454  const auto & conv = exio_helper->get_conversion(type_str);
455 
456  // Loop over all the faces in this block
457  int jmax = nelem_last_block+exio_helper->num_elem_this_blk;
458  for (int j=nelem_last_block; j<jmax; j++)
459  {
460  auto uelem = Elem::build(conv.libmesh_elem_type());
461 
462  const int elem_num = j - nelem_last_block;
463 
464  // Make sure that Exodus's number of nodes per Elem matches
465  // the number of Nodes for this type of Elem. We only check
466  // this for the first Elem in each block, since these values
467  // are the same for every Elem in the block.
468  if (!elem_num)
469  libmesh_error_msg_if(exio_helper->num_nodes_per_elem != static_cast<int>(uelem->n_nodes()),
470  "Error: Exodus file says "
471  << exio_helper->num_nodes_per_elem
472  << " nodes per Elem, but Elem type "
473  << Utility::enum_to_string(uelem->type())
474  << " has " << uelem->n_nodes() << " nodes.");
475 
476  // Assign the current subdomain to this Elem
477  uelem->subdomain_id() = subdomain_id;
478 
479  // Determine the libmesh elem id implied by "j". The
480  // ExodusII_IO_Helper::get_libmesh_elem_id() helper function
481  // expects a 1-based Exodus elem id, so we construct the
482  // "implied" Exodus elem id from "j" by adding 1.
483  auto libmesh_elem_id = exio_helper->get_libmesh_elem_id(/*exodus_elem_id=*/j+1);
484 
485  uelem->set_id(libmesh_elem_id);
486 
487  // Record that we have seen an element of dimension uelem->dim()
488  elems_of_dimension[uelem->dim()] = true;
489 
490  // Catch the Elem pointer that the Mesh throws back
491  Elem * elem = mesh.add_elem(std::move(uelem));
492 
493  // If the _set_unique_ids_from_maps flag is true, set the
494  // unique_id for "elem", otherwise do nothing.
495  exio_helper->conditionally_set_elem_unique_id(mesh, elem, j);
496 
497  // If the Mesh assigned an ID different from the one we
498  // tried to give it, we should probably error.
499  libmesh_error_msg_if(elem->id() != static_cast<unsigned>(libmesh_elem_id),
500  "Error! Mesh assigned ID "
501  << elem->id()
502  << " which is different from the (zero-based) Exodus ID "
503  << libmesh_elem_id
504  << "!");
505 
506  // Assign extra integer IDs
507  for (auto & id : extra_ids)
508  {
509  const Real v = elem_ids[id][elem->id()];
510 
511  if (v == Real(-1))
512  {
514  continue;
515  }
516 
517  // Ignore FE_INVALID here even if we've enabled FPEs; a
518  // thrown exception is preferred over an FPE signal.
519  FPEDisabler disable_fpes;
520  const long long iv = std::llround(v);
521 
522  // Check if the real number is outside of the range we can
523  // convert exactly
524 
525  long long max_representation = 1;
526  max_representation = (max_representation << std::min(std::numeric_limits<Real>::digits,
527  std::numeric_limits<double>::digits));
528  libmesh_error_msg_if(iv > max_representation,
529  "Error! An element integer value higher than "
530  << max_representation
531  << " was found! Exodus uses real numbers for storing element "
532  " integers, which can only represent integers from 0 to "
533  << max_representation
534  << ".");
535 
536  libmesh_error_msg_if(iv < 0,
537  "Error! An element integer value less than -1"
538  << " was found! Exodus uses real numbers for storing element "
539  " integers, which can only represent integers from 0 to "
540  << max_representation
541  << ".");
542 
543 
544  elem->set_extra_integer(id, cast_int<dof_id_type>(iv));
545  }
546 
547  // Set all the nodes for this element
548  //
549  // If we don't have any Bezier extraction operators, this
550  // is easy: we've already built all our nodes and just need
551  // to link to them.
552  if (exio_helper->bex_cv_conn.empty())
553  {
554  for (int k=0; k<exio_helper->num_nodes_per_elem; k++)
555  {
556  // Get index into this block's connectivity array
557  int gi = elem_num * exio_helper->num_nodes_per_elem + conv.get_node_map(k);
558 
559  // Get the 1-based Exodus node id from the "connect" array
560  auto exodus_node_id = exio_helper->connect[gi];
561 
562  // Convert this index to a libMesh Node id
563  auto libmesh_node_id = exio_helper->get_libmesh_node_id(exodus_node_id);
564 
565  // Set the node pointer in the Elem
566  elem->set_node(k, mesh.node_ptr(libmesh_node_id));
567  }
568  }
569  else // We have Bezier Extraction data
570  {
571  auto & constraint_rows = mesh.get_constraint_rows();
572 
573  const DynaIO::ElementDefinition & dyna_elem_defn =
575  elem->dim(),
576  int(elem->default_order()));
577 
578  std::vector<std::vector<Real>>
579  my_constraint_mat(exio_helper->bex_num_elem_cvs);
580  for (auto spline_node_index :
581  make_range(exio_helper->bex_num_elem_cvs))
582  {
583  my_constraint_mat[spline_node_index].resize(elem->n_nodes());
584 
585  const auto & my_constraint_rows = exio_helper->bex_cv_conn[elem_num];
586  const unsigned long elem_coef_vec_index =
587  my_constraint_rows[spline_node_index] - 1; // Exodus isn't 0-based
588  const auto & my_vec = bex_constraint_vec(elem_coef_vec_index, *exio_helper);
589  for (auto elem_node_index :
590  make_range(elem->n_nodes()))
591  {
592  my_constraint_mat[spline_node_index][elem_node_index] =
593  my_vec[elem_node_index];
594  }
595 
596  }
597 
598  // The tailing entries in each element's connectivity
599  // vector are indices to Exodus constraint coefficient
600  // rows.
601 
602  // Concatenating these rows gives a matrix with
603  // all the constraints for the element nodes: each
604  // column of that matrix is the constraint coefficients
605  // for the node associated with that column (via the
606  // Exodus numbering, not the libMesh numbering).
607  const auto & my_constraint_rows = exio_helper->bex_cv_conn[elem_num];
608 
609  for (auto elem_node_index :
610  make_range(elem->n_nodes()))
611  {
612  // New finite element node data = dot product of
613  // constraint matrix columns with spline node data.
614  // Store each column's non-zero entries, along with
615  // the global spline node indices, as a key to
616  // identify shared finite element nodes.
617  std::vector<std::pair<dof_id_type, Real>> key;
618 
619  for (auto spline_node_index :
620  make_range(exio_helper->bex_num_elem_cvs))
621  {
622  // Pick out a row of the element constraint matrix
623  const unsigned long elem_coef_vec_index =
624  my_constraint_rows[spline_node_index] - 1; // Exodus isn't 0-based
625 
626  auto & coef_vec =
627  bex_constraint_vec(elem_coef_vec_index, *exio_helper);
628 
629  // Get coef from this node's column intersect that row
630  const Real coef =
631  libmesh_vector_at(coef_vec, elem_node_index);
632 
633  // Get the libMesh node corresponding to that row
634  const int gi = elem_num * exio_helper->bex_num_elem_cvs + spline_node_index;
635 
636  // Get the 1-based Exodus node id from the "connect" array
637  auto exodus_node_id = exio_helper->connect[gi];
638 
639  // Convert this index to a libMesh Node id
640  auto libmesh_node_id = exio_helper->get_libmesh_node_id(exodus_node_id);
641 
642  if (coef != 0) // Ignore irrelevant spline nodes
643  key.emplace_back(libmesh_node_id, coef);
644  }
645 
646  // Have we already created this node? Connect it.
647  if (const auto local_node_it = local_nodes.find(key);
648  local_node_it != local_nodes.end())
649  elem->set_node(dyna_elem_defn.nodes[elem_node_index], local_node_it->second);
650  // Have we not yet created this node? Construct it,
651  // along with its weight and libMesh constraint row,
652  // then connect it.
653  else
654  {
655  Point p(0);
656  Real w = 0;
657  std::vector<std::pair<std::pair<const Elem *, unsigned int>, Real>> constraint_row;
658 
659  for (auto [libmesh_spline_node_id, coef] : key)
660  {
661  const Node & spline_node = mesh.node_ref(libmesh_spline_node_id);
662 
663  p.add_scaled(spline_node, coef);
664  const Real spline_w = weights_exist ?
665  spline_node.get_extra_datum<Real>(weight_index) : 1;
666  w += coef * spline_w;
667 
668  const Elem * nodeelem =
669  libmesh_map_find(spline_nodeelem_ptrs, &spline_node);
670  constraint_row.emplace_back(std::make_pair(nodeelem, 0), coef);
671  }
672 
673  Node *n = mesh.add_point(p, n_nodes++);
674  if (weights_exist)
675  n->set_extra_datum<Real>(weight_index, w);
676 
677  // If we're building disconnected Bezier
678  // extraction elements then we don't want to
679  // find the new nodes to reuse later; each
680  // finite element node will connect to only one
681  // element.
682  if (!_disc_bex)
683  local_nodes[key] = n;
684  elem->set_node(dyna_elem_defn.nodes[elem_node_index], n);
685 
686  constraint_rows[n] = constraint_row;
687  }
688  }
689  }
690  }
691 
692  // running sum of # of elements per block,
693  // (should equal total number of elements in the end)
694  nelem_last_block += exio_helper->num_elem_this_blk;
695  }
696 
697  // Now we know enough to fix any spline NodeElem subdomains
698  max_subdomain_id++;
699  for (auto p : spline_nodeelem_ptrs)
700  p.second->subdomain_id() = max_subdomain_id;
701 
702  // Read in edge blocks, storing information in the BoundaryInfo object.
703  // Edge blocks are treated as BCs.
704  exio_helper->read_edge_blocks(mesh);
705 
706  // Set the mesh dimension to the largest encountered for an element
707  for (unsigned char i=0; i!=4; ++i)
708  if (elems_of_dimension[i])
710 
711  // Read in sideset information -- this is useful for applying boundary conditions
712  {
713  // Get basic information about all sidesets
714  exio_helper->read_sideset_info();
715  int offset=0;
716  for (int i=0; i<exio_helper->num_side_sets; i++)
717  {
718  // Compute new offset
719  offset += (i > 0 ? exio_helper->num_sides_per_set[i-1] : 0);
720  exio_helper->read_sideset (i, offset);
721 
722  std::string sideset_name = exio_helper->get_side_set_name(i);
723  if (!sideset_name.empty())
725  (cast_int<boundary_id_type>(exio_helper->get_side_set_id(i)))
726  = sideset_name;
727  }
728 
729  for (auto e : index_range(exio_helper->elem_list))
730  {
731  // Call helper function to get the libmesh Elem id for the
732  // e'th entry in the current elem_list.
733  dof_id_type libmesh_elem_id =
734  exio_helper->get_libmesh_elem_id(exio_helper->elem_list[e]);
735 
736  // Set any relevant node/edge maps for this element
737  Elem & elem = mesh.elem_ref(libmesh_elem_id);
738 
739  const auto & conv = exio_helper->get_conversion(elem.type());
740 
741  // Map the zero-based Exodus side numbering to the libmesh side numbering
742  unsigned int raw_side_index = exio_helper->side_list[e]-1;
743  std::size_t side_index_offset = conv.get_shellface_index_offset();
744 
745  if (raw_side_index < side_index_offset)
746  {
747  // We assume this is a "shell face"
748  int mapped_shellface = raw_side_index;
749 
750  // Check for errors
751  libmesh_error_msg_if(mapped_shellface < 0 || mapped_shellface >= 2,
752  "Bad 0-based shellface id: "
753  << mapped_shellface
754  << " detected in Exodus file "
755  << exio_helper->current_filename);
756 
757  // Add this (elem,shellface,id) triplet to the BoundaryInfo object.
758  mesh.get_boundary_info().add_shellface (libmesh_elem_id,
759  cast_int<unsigned short>(mapped_shellface),
760  cast_int<boundary_id_type>(exio_helper->id_list[e]));
761  }
762  else
763  {
764  unsigned int side_index = static_cast<unsigned int>(raw_side_index - side_index_offset);
765  int mapped_side = conv.get_side_map(side_index);
766 
767  // Check for errors
768  libmesh_error_msg_if(mapped_side == ExodusII_IO_Helper::Conversion::invalid_id,
769  "Invalid 1-based side id: "
770  << side_index
771  << " detected for "
772  << Utility::enum_to_string(elem.type())
773  << " in Exodus file "
774  << exio_helper->current_filename);
775 
776  libmesh_error_msg_if(mapped_side < 0 ||
777  cast_int<unsigned int>(mapped_side) >= elem.n_sides(),
778  "Bad 0-based side id: "
779  << mapped_side
780  << " detected for "
781  << Utility::enum_to_string(elem.type())
782  << " in Exodus file "
783  << exio_helper->current_filename);
784 
785  // Add this (elem,side,id) triplet to the BoundaryInfo object.
786  mesh.get_boundary_info().add_side (libmesh_elem_id,
787  cast_int<unsigned short>(mapped_side),
788  cast_int<boundary_id_type>(exio_helper->id_list[e]));
789  }
790  } // end for (elem_list)
791  } // end read sideset info
792 
793  // Read in elemset information and apply to Mesh elements if present
794  {
795  exio_helper->read_elemset_info();
796 
797  // Mimic behavior of sideset case where we store all the set
798  // information in a single array with offsets.
799  int offset=0;
800  for (int i=0; i<exio_helper->num_elem_sets; i++)
801  {
802  // Compute new offset
803  offset += (i > 0 ? exio_helper->num_elems_per_set[i-1] : 0);
804  exio_helper->read_elemset (i, offset);
805 
806  // TODO: add support for elemset names
807  // std::string elemset_name = exio_helper->get_elem_set_name(i);
808  // if (!elemset_name.empty())
809  // mesh.get_boundary_info().elemset_name(cast_int<boundary_id_type>(exio_helper->get_elem_set_id(i))) = elemset_name;
810  }
811 
812  // Debugging: print the concatenated list of elemset ids
813  // libMesh::out << "Concatenated list of elemset Elem ids (Exodus numbering):" << std::endl;
814  // for (const auto & id : exio_helper->elemset_list)
815  // libMesh::out << id << " ";
816  // libMesh::out << std::endl;
817 
818  // Next we need to assign the elemset ids to the mesh using the
819  // Elem's "extra_integers" support, if we have any.
820  if (exio_helper->num_elem_all_elemsets)
821  {
822  // Build map from Elem -> {elemsets}. This is needed only
823  // temporarily to determine a unique set of elemset codes.
824  std::map<Elem *, MeshBase::elemset_type> elem_to_elemsets;
825  for (auto e : index_range(exio_helper->elemset_list))
826  {
827  // Call helper function to get the libmesh Elem id for the
828  // e'th entry in the current elemset_list.
829  dof_id_type libmesh_elem_id =
830  exio_helper->get_libmesh_elem_id(exio_helper->elemset_list[e]);
831 
832  // Get a pointer to this Elem
833  Elem * elem = mesh.elem_ptr(libmesh_elem_id);
834 
835  // Debugging:
836  // libMesh::out << "Elem " << elem->id() << " is in elemset " << exio_helper->elemset_id_list[e] << std::endl;
837 
838  // Store elemset id in the map
839  elem_to_elemsets[elem].insert(exio_helper->elemset_id_list[e]);
840  }
841 
842  // Create a set of unique elemsets
843  std::set<MeshBase::elemset_type> unique_elemsets;
844  for (const auto & pr : elem_to_elemsets)
845  unique_elemsets.insert(pr.second);
846 
847  // Debugging: print the unique elemsets
848  // libMesh::out << "The set of unique elemsets which exist on the Mesh:" << std::endl;
849  // for (const auto & s : unique_elemsets)
850  // {
851  // for (const auto & elemset_id : s)
852  // libMesh::out << elemset_id << " ";
853  // libMesh::out << std::endl;
854  // }
855 
856  // Enumerate the unique_elemsets and tell the mesh about them
857  dof_id_type code = 0;
858  for (const auto & s : unique_elemsets)
859  mesh.add_elemset_code(code++, s);
860 
861  // Sanity check: make sure that MeshBase::n_elemsets() reports
862  // the expected value after calling MeshBase::add_elemset_code()
863  // one or more times.
864  libmesh_assert_msg(exio_helper->num_elem_sets == cast_int<int>(mesh.n_elemsets()),
865  "Error: mesh.n_elemsets() is " << mesh.n_elemsets()
866  << ", but mesh should have " << exio_helper->num_elem_sets << " elemsets.");
867 
868  // Create storage for the extra integer on all Elems. Elems which
869  // are not in any set will use the default value of DofObject::invalid_id
870  unsigned int elemset_index =
871  mesh.add_elem_integer("elemset_code",
872  /*allocate_data=*/true);
873 
874  // Store the appropriate extra_integer value on all Elems that need it.
875  for (const auto & [elem, s] : elem_to_elemsets)
876  elem->set_extra_integer(elemset_index, mesh.get_elemset_code(s));
877  }
878  } // done reading elemset info
879 
880  // Read nodeset info
881  {
882  // This fills in the following fields of the helper for later use:
883  // nodeset_ids
884  // num_nodes_per_set
885  // num_node_df_per_set
886  // node_sets_node_index
887  // node_sets_dist_index
888  // node_sets_node_list
889  // node_sets_dist_fact
890  exio_helper->read_all_nodesets();
891 
892  for (int nodeset=0; nodeset<exio_helper->num_node_sets; nodeset++)
893  {
894  boundary_id_type nodeset_id =
895  cast_int<boundary_id_type>(exio_helper->nodeset_ids[nodeset]);
896 
897  std::string nodeset_name = exio_helper->get_node_set_name(nodeset);
898  if (!nodeset_name.empty())
899  mesh.get_boundary_info().nodeset_name(nodeset_id) = nodeset_name;
900 
901  // Get starting index of node ids for current nodeset.
902  unsigned int offset = exio_helper->node_sets_node_index[nodeset];
903 
904  for (int i=0; i<exio_helper->num_nodes_per_set[nodeset]; ++i)
905  {
906  int exodus_node_id = exio_helper->node_sets_node_list[i + offset];
907  auto libmesh_node_id = exio_helper->get_libmesh_node_id(exodus_node_id);
908  mesh.get_boundary_info().add_node(libmesh_node_id, nodeset_id);
909  }
910  }
911  }
912 
913 #if LIBMESH_DIM < 3
914  libmesh_error_msg_if(mesh.mesh_dimension() > LIBMESH_DIM,
915  "Cannot open dimension "
916  << mesh.mesh_dimension()
917  << " mesh file when configured without "
918  << mesh.mesh_dimension()
919  << "D support.");
920 #endif
921 }
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
Definition: elem_quality.C:42
The FPEDisabler class puts Floating-Point Exception (FPE) trapping on hold during its lifetime...
Definition: fpe_disabler.h:49
virtual void reserve_nodes(const dof_id_type nn)=0
Reserves space for a known number of nodes.
void add_scaled(const TypeVector< T2 > &, const T &)
Add a scaled value to this vector without creating a temporary.
Definition: type_vector.h:629
constraint_rows_type & get_constraint_rows()
Constraint rows accessors.
Definition: mesh_base.h:1905
virtual Node *& set_node(const unsigned int i)
Definition: elem.h:2564
A Node is like a Point, but with more information.
Definition: node.h:52
std::string & nodeset_name(boundary_id_type id)
std::vector< std::string > _extra_integer_vars
An optional list of variables in the EXODUS file that are to be used to set extra integers when loadi...
Definition: exodusII_io.h:701
static const int invalid_id
An invalid_id that can be returned to signal failure in case something goes wrong.
std::vector< bool > elems_of_dimension
A vector of bools describing what dimension elements have been encountered when reading a mesh...
Definition: mesh_input.h:107
unsigned int add_elem_integer(std::string name, bool allocate_data=true, dof_id_type default_value=DofObject::invalid_id)
Register an integer datum (of type dof_id_type) to be added to each element in the mesh...
Definition: mesh_base.C:623
void add_elemset_code(dof_id_type code, MeshBase::elemset_type id_set)
Tabulate a user-defined "code" for elements which belong to the element sets specified in id_set...
Definition: mesh_base.C:456
Defines mapping from libMesh element types to LS-DYNA element types or vice-versa.
Definition: dyna_io.h:114
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
dof_id_type get_elemset_code(const MeshBase::elemset_type &id_set) const
Definition: mesh_base.C:497
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Definition: mesh_base.h:170
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
Add a new Node at Point p to the end of the vertex array, with processor_id procid.
This is the MeshBase class.
Definition: mesh_base.h:80
static const ElementDefinition & find_elem_definition(dyna_int_type dyna_elem, int dim, int p)
Finds the ElementDefinition corresponding to a particular element type.
Definition: dyna_io.C:741
void add_node(const Node *node, const boundary_id_type id)
Add Node node with boundary id id to the boundary information data structures.
const dof_id_type n_nodes
Definition: tecplot_io.C:67
int8_t boundary_id_type
Definition: id_types.h:51
dof_id_type id() const
Definition: dof_object.h:819
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:473
virtual unsigned int n_nodes() const =0
virtual Elem * add_elem(Elem *e)=0
Add elem e to the end of the element array.
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
Definition: elem.C:442
void set_default_mapping_type(const ElemMappingType type)
Set the default master space to physical space mapping basis functions to be used on newly added elem...
Definition: mesh_base.h:940
unsigned int n_elemsets() const
Returns the number of unique elemset ids which have been added via add_elemset_code(), which is the size of the _all_elemset_ids set.
Definition: mesh_base.C:482
void allow_node_and_elem_unique_id_overlap(bool allow)
If true is passed, then this mesh will no longer require unique_ids to be unique across the set of al...
Definition: mesh_base.h:1377
void set_extra_datum(const unsigned int index, const T value)
Sets the value on this object of the extra datum associated with index, which should have been obtain...
Definition: dof_object.h:1102
std::string & subdomain_name(subdomain_id_type id)
Definition: mesh_base.C:1880
void set_mesh_dimension(unsigned char d)
Resets the logical dimension of the mesh.
Definition: mesh_base.h:413
bool _disc_bex
Set to true (false is the default) to generate independent nodes for every Bezier Extraction element...
Definition: exodusII_io.h:742
virtual void clear()
Deletes all the element and node data that is currently stored.
Definition: mesh_base.C:1029
unsigned int add_node_datum(const std::string &name, bool allocate_data=true, const T *default_value=nullptr)
Register a datum (of type T) to be added to each node in the mesh.
Definition: mesh_base.h:2646
std::string & sideset_name(boundary_id_type id)
std::string enum_to_string(const T e)
virtual const Elem * elem_ptr(const dof_id_type i) const =0
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676
virtual unsigned int n_sides() const =0
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual unsigned short dim() const =0
void add_side(const dof_id_type elem, const unsigned short int side, const boundary_id_type id)
Add side side of element number elem with boundary id id to the boundary information data structure...
void add_shellface(const dof_id_type elem, const unsigned short int shellface, const boundary_id_type id)
Add shell face shellface of element number elem with boundary id id to the boundary information data ...
virtual const Elem & elem_ref(const dof_id_type i) const
Definition: mesh_base.h:778
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:176
unsigned int mesh_dimension() const
Definition: mesh_base.C:430
void set_default_mapping_data(const unsigned char data)
Set the default master space to physical space mapping basis functions to be used on newly added elem...
Definition: mesh_base.h:958
virtual const Node & node_ref(const dof_id_type i) const
Definition: mesh_base.h:735
T get_extra_datum(const unsigned int index) const
Gets the value on this object of the extra datum associated with index, which should have been obtain...
Definition: dof_object.h:1122
virtual const Node * node_ptr(const dof_id_type i) const =0
std::vector< unsigned int > nodes
Definition: dyna_io.h:131
virtual Order default_order() const =0
virtual ElemType type() const =0
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
virtual void reserve_elem(const dof_id_type ne)=0
Reserves space for a known number of elements.
void ErrorVector unsigned int
Definition: adjoints_ex3.C:360
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:153
void set_extra_integer(const unsigned int index, const dof_id_type value)
Sets the value on this object of the extra integer associated with index, which should have been obta...
Definition: dof_object.h:1062
virtual dof_id_type n_nodes() const =0
bool _set_unique_ids_from_maps
Set Elem/Node unique_ids based on the elem_num_map and node_num_map contents during reading...
Definition: exodusII_io.h:736
uint8_t dof_id_type
Definition: id_types.h:67

◆ read_elemental_variable()

void libMesh::ExodusII_IO::read_elemental_variable ( std::string  elemental_var_name,
unsigned int  timestep,
std::map< unsigned int, Real > &  unique_id_to_value_map 
)

Given an elemental variable and a time step, returns a mapping from the elements (top parent) unique IDs to the value of the elemental variable at the corresponding time step index.

Note that this function MUST only be called before renumbering! This function is essentially a wrapper for read_elemental_var_values from the exodus helper (which is not accessible outside this class).

Parameters
elemental_var_nameName of an elemental variable
timestepThe corresponding time step index
unique_id_to_value_mapThe map to be filled

Definition at line 1326 of file exodusII_io.C.

References exio_helper, libMesh::MeshInput< MT >::mesh(), libMesh::Elem::top_parent(), and libMesh::DofObject::unique_id().

1329 {
1330  LOG_SCOPE("read_elemental_variable()", "ExodusII_IO");
1331 
1332  // Note that this function MUST be called before renumbering
1333  std::map<dof_id_type, Real> elem_var_value_map;
1334 
1335  exio_helper->read_elemental_var_values(elemental_var_name, timestep, elem_var_value_map);
1336  for (auto & pr : elem_var_value_map)
1337  {
1338  const Elem * elem = MeshInput<MeshBase>::mesh().query_elem_ptr(pr.first);
1339  unique_id_to_value_map.emplace(elem->top_parent()->unique_id(), pr.second);
1340  }
1341 }
const Elem * top_parent() const
Definition: elem.h:3070
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
unique_id_type unique_id() const
Definition: dof_object.h:835
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ read_elemset_data()

void libMesh::ExodusII_IO::read_elemset_data ( int  timestep,
std::vector< std::string > &  var_names,
std::vector< std::set< elemset_id_type >> &  elemset_ids_in,
std::vector< std::map< std::pair< dof_id_type, elemset_id_type >, Real >> &  elemset_vals 
)

Read all the elemset data at a particular timestep.

Definition at line 2174 of file exodusII_io.C.

References exio_helper.

2178 {
2179  libmesh_error_msg_if(!exio_helper->opened_for_reading,
2180  "ERROR, ExodusII file must be opened for reading "
2181  "before calling ExodusII_IO::read_elemset_data()!");
2182 
2183  exio_helper->read_elemset_data(timestep, var_names, elemset_ids_in, elemset_vals);
2184 }
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ read_global_variable()

void libMesh::ExodusII_IO::read_global_variable ( std::vector< std::string >  global_var_names,
unsigned int  timestep,
std::vector< Real > &  global_values 
)

Given a vector of global variables and a time step, returns the values of the global variable at the corresponding time step index.

Parameters
global_var_namesVector of names of global variables
timestepThe corresponding time step index
global_valuesThe vector to be filled

Definition at line 1343 of file exodusII_io.C.

References exio_helper, and libMesh::ExodusII_IO_Helper::GLOBAL.

Referenced by copy_scalar_solution().

1346 {
1347  LOG_SCOPE("read_global_variable()", "ExodusII_IO");
1348 
1349  std::size_t size = global_var_names.size();
1350  libmesh_error_msg_if(size == 0, "ERROR, empty list of global variables to read from the Exodus file.");
1351 
1352  // read the values for all global variables
1353  std::vector<Real> values_from_exodus;
1354  exio_helper->read_var_names(ExodusII_IO_Helper::GLOBAL);
1355  exio_helper->read_global_values(values_from_exodus, timestep);
1356  std::vector<std::string> global_var_names_exodus = exio_helper->global_var_names;
1357 
1358  if (values_from_exodus.size() == 0)
1359  return; // This will happen in parallel on procs that are not 0
1360 
1361  global_values.clear();
1362  for (std::size_t i = 0; i != size; ++i)
1363  {
1364  // for each global variable in global_var_names, look the corresponding one in global_var_names_from_exodus
1365  // and fill global_values accordingly
1366  auto it = find(global_var_names_exodus.begin(), global_var_names_exodus.end(), global_var_names[i]);
1367  if (it != global_var_names_exodus.end())
1368  global_values.push_back(values_from_exodus[it - global_var_names_exodus.begin()]);
1369  else
1370  libmesh_error_msg("ERROR, Global variable " << global_var_names[i] << \
1371  " not found in Exodus file.");
1372  }
1373 
1374 }
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ read_header()

ExodusHeaderInfo libMesh::ExodusII_IO::read_header ( const std::string &  name)

Read only the header information, instead of the entire mesh.

After the header is read, the file is closed and the MeshBase object remains unchanged. This capability is useful if you only need to know the mesh "metadata" and should be faster than reading in all the nodes and elems.

The header information currently includes: .) Title string .) Mesh spatial dimension .) Number of nodes .) Number of elements .) Number of element blocks .) Number of node sets .) Number of side sets .) Number of edge blocks/edges

Definition at line 926 of file exodusII_io.C.

References libMesh::ExodusHeaderInfo::broadcast(), libMesh::ParallelObject::comm(), exio_helper, libMesh::MeshInput< MT >::mesh(), libMesh::MeshInput< MeshBase >::mesh(), and libMesh::ParallelObject::processor_id().

Referenced by MeshInputTest::testExodusReadHeader().

927 {
928  // We will need the Communicator of the Mesh we were created with.
930 
931  // Eventual return value
932  ExodusHeaderInfo header_info;
933 
934  // File I/O is done on processor 0, then broadcast to other procs
935  if (mesh.processor_id() == 0)
936  {
937  // Open the exodus file in EX_READ mode
938  exio_helper->open(fname.c_str(), /*read_only=*/true);
939 
940  // Get header information from exodus file without updating the
941  // Helper object's internal data structures.
942  header_info = exio_helper->read_header();
943 
944  // Close the file, we are now done with it. The goal is to keep the
945  // exio_helper object unchanged while calling this function,
946  // although it can't quite be marked "const" because we do have to
947  // actually open/close the file. This way, it should be possible to
948  // use the same ExodusII_IO object to read the headers of multiple
949  // different mesh files.
950  exio_helper->close();
951  }
952 
953  // Broadcast header_info to other procs before returning
954  header_info.broadcast(mesh.comm());
955 
956  // Return the information we read back to the user.
957  return header_info;
958 }
This class is used as both an external data structure for passing around Exodus file header informati...
const Parallel::Communicator & comm() const
This is the MeshBase class.
Definition: mesh_base.h:80
void broadcast(const Parallel::Communicator &comm)
Broadcasts data from processor 0 to other procs using the provided Communicator.
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676
processor_id_type processor_id() const

◆ read_nodeset_data()

void libMesh::ExodusII_IO::read_nodeset_data ( int  timestep,
std::vector< std::string > &  var_names,
std::vector< std::set< boundary_id_type >> &  node_boundary_ids,
std::vector< std::map< BoundaryInfo::NodeBCTuple, Real >> &  bc_vals 
)

Read all the nodeset data at a particular timestep.

TODO: currently all the nodeset variables are read, but we might want to change this to only read the requested ones.

Definition at line 2144 of file exodusII_io.C.

References exio_helper.

2148 {
2149  libmesh_error_msg_if(!exio_helper->opened_for_reading,
2150  "ERROR, ExodusII file must be opened for reading "
2151  "before calling ExodusII_IO::read_nodeset_data()!");
2152 
2153  exio_helper->read_nodeset_data(timestep, var_names, node_boundary_ids, bc_vals);
2154 }
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ read_sideset_data()

void libMesh::ExodusII_IO::read_sideset_data ( int  timestep,
std::vector< std::string > &  var_names,
std::vector< std::set< boundary_id_type >> &  side_ids,
std::vector< std::map< BoundaryInfo::BCTuple, Real >> &  bc_vals 
)

Similar to write_sideset_data(), this function is used to read the data at a particular timestep.

TODO: currently all the sideset variables are read, but we might want to change this to only read the requested ones.

Definition at line 2087 of file exodusII_io.C.

References exio_helper, libMesh::MeshInput< MeshBase >::mesh(), and libMesh::MeshOutput< MT >::mesh().

2091 {
2092  libmesh_error_msg_if(!exio_helper->opened_for_reading,
2093  "ERROR, ExodusII file must be opened for reading "
2094  "before calling ExodusII_IO::read_sideset_data()!");
2095 
2097  exio_helper->read_sideset_data(mesh, timestep, var_names, side_ids, bc_vals);
2098 }
const MT & mesh() const
Definition: mesh_output.h:259
This is the MeshBase class.
Definition: mesh_base.h:80
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ set_coordinate_offset()

void libMesh::ExodusII_IO::set_coordinate_offset ( Point  p)

Allows you to set a vector that is added to the coordinates of all of the nodes.

Effectively, this "moves" the mesh to a particular position.

Deprecated:
As requested by Roy in libmesh PR #90, this function was "deprecated on arrival". There is not really a suitable replacement for it in the works, however. The same effect could be achieved by calling MeshTools::Modification::translate() twice, but that approach seems inefficient in the case of very large problems with millions of nodes. That said, this should probably become a base class API so that it works for all the different IO subclasses.

Definition at line 1001 of file exodusII_io.C.

References exio_helper.

1002 {
1003  libmesh_warning("This method may be deprecated in the future");
1004  exio_helper->set_coordinate_offset(p);
1005 }
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ set_discontinuous_bex()

void libMesh::ExodusII_IO::set_discontinuous_bex ( bool  disc_bex)

Set to true (false is the default) to generate independent nodes for every Bezier Extraction element in an input file containing them, causing those elements to be disconnected from each other.

(Their vertices will be multiple distinct nodes at overlapping points.) If this is false, Bezier Extraction elements will be connected where possible, thereby using fewer redundancies and less memory, but the input mesh will need to be conforming.

Definition at line 2436 of file exodusII_io.C.

References _disc_bex.

Referenced by MeshInputTest::testExodusFileMappings().

2437 {
2438  _disc_bex = disc_bex;
2439 }
bool _disc_bex
Set to true (false is the default) to generate independent nodes for every Bezier Extraction element...
Definition: exodusII_io.h:742

◆ set_extra_integer_vars()

void libMesh::ExodusII_IO::set_extra_integer_vars ( const std::vector< std::string > &  extra_integer_vars)

Set the elemental variables in the Exodus file to be read into extra element integers.

The names of these elemental variables will be used to name the extra element integers.

Definition at line 181 of file exodusII_io.C.

References _extra_integer_vars.

Referenced by ExtraIntegersTest::testBadExtraIntegersExodusReading(), and ExtraIntegersTest::testExtraIntegersExodusReading().

182 {
183  _extra_integer_vars = extra_integer_vars;
184 }
std::vector< std::string > _extra_integer_vars
An optional list of variables in the EXODUS file that are to be used to set extra integers when loadi...
Definition: exodusII_io.h:701

◆ set_hdf5_writing()

void libMesh::ExodusII_IO::set_hdf5_writing ( bool  write_hdf5)

Set to true (the default) to write files in an HDF5-based file format (when HDF5 is available), or to false to write files in the old NetCDF3-based format.

If HDF5 is unavailable, this setting does nothing.

Definition at line 2424 of file exodusII_io.C.

References exio_helper.

2425 {
2426  exio_helper->set_hdf5_writing(write_hdf5);
2427 }
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ set_max_name_length()

void libMesh::ExodusII_IO::set_max_name_length ( unsigned int  max_length)

For backwards compatibility, libMesh currently truncates names in ExodusII output to the old default of 32 characters, but user code can expand that to up to 80 characters by setting a larger max_length manually.

This must be set before a file is opened for writing.

Definition at line 2430 of file exodusII_io.C.

References exio_helper.

Referenced by ExodusTest< elem_type >::test_write().

2431 {
2432  exio_helper->set_max_name_length(max_length);
2433 }
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ set_n_partitions()

void libMesh::MeshInput< MeshBase >::set_n_partitions ( unsigned int  n_parts)
inlineprotectedinherited

Sets the number of partitions in the mesh.

Typically this gets done by the partitioner, but some parallel file formats begin "pre-partitioned".

Definition at line 101 of file mesh_input.h.

References libMesh::MeshInput< MT >::mesh().

Referenced by libMesh::Nemesis_IO::read(), and libMesh::XdrIO::read_header().

101 { this->mesh().set_n_partitions() = n_parts; }
unsigned int & set_n_partitions()
Definition: mesh_base.h:2131

◆ set_output_variables()

void libMesh::ExodusII_IO::set_output_variables ( const std::vector< std::string > &  output_variables,
bool  allow_empty = true 
)

Sets the list of variable names to be included in the output.

This is optional. If this is never called then all variables will be present. If this is called and an empty vector is supplied no variables will be output. Setting the allow_empty = false will result in empty vectors supplied here to also be populated with all variables.

Definition at line 186 of file exodusII_io.C.

References _allow_empty_variables, and _output_variables.

Referenced by main().

188 {
189  _output_variables = output_variables;
190  _allow_empty_variables = allow_empty;
191 }
std::vector< std::string > _output_variables
The names of the variables to be output.
Definition: exodusII_io.h:707
bool _allow_empty_variables
Flag which controls the behavior of _output_variables: .) If true, _output_variables is allowed to re...
Definition: exodusII_io.h:717

◆ set_unique_ids_from_maps()

void libMesh::ExodusII_IO::set_unique_ids_from_maps ( bool  val)

If true, this flag enforces the following behaviors:

.) When reading an Exodus file, instead of setting the elem_num_map and node_num_map ids directly on Nodes and Elems read in from the Exodus file, set their unique_ids instead. Normally libmesh chooses the unique_ids automatically, but in this case we override that choice. As a consequence, the libMesh Elems/Nodes will be numbered based on their implied ordering in the exo file (sequentially by block and without any gaps in the numbering). .) When writing an Exodus file, populate the elem_num_map and node_num_map with the unique_ids of the Elems/Nodes being written.

There are a few reasons why one might want to employ this behavior. One case is if you are using a ReplicatedMesh and the {node,elem}_num_map contains "large" (much larger than num_nodes) ids. This could happen either because the {node,elem}_num_map starts with a large id, or because there is a large gap in the {node,elem}_num_map numbering. Because the ReplicatedMesh always constructs std::vectors of size "largest_id" rather than size "num_nodes" or "num_elems", this mesh will be stored inefficiently, allocating nullptrs in the std::vector for the "missing" Nodes/Elems. Setting this flag to true will ensure that only vectors of size "num_nodes" and "num_elems" are allocated.

Another case is when you delete Nodes/Elems during a simulation and/or renumber them, but don't want the original Nodes/Elems to be renumbered when the Mesh is written back out to an Exodus file. Setting this flag to true causes the original Node/Elem ids to be "saved" in the unique_id fields, so that they can later be written back to disk with their original numbering.

This capability is relatively new, and should be considered experimental.

Definition at line 977 of file exodusII_io.C.

References _set_unique_ids_from_maps, and exio_helper.

Referenced by MeshInputTest::testExodusSetElemUniqueIdsFromMaps_implementation(), and MeshInputTest::testExodusSetNodeUniqueIdsFromMaps_implementation().

978 {
980 
981  // Set this flag on the helper object as well. The helper needs to know about this
982  // flag, since it sometimes needs to construct libmesh Node ids from nodal connectivity
983  // arrays (see e.g. ExodusII_IO_Helper::read_edge_blocks()).
984  exio_helper->set_unique_ids_from_maps = val;
985 }
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676
bool _set_unique_ids_from_maps
Set Elem/Node unique_ids based on the elem_num_map and node_num_map contents during reading...
Definition: exodusII_io.h:736

◆ skip_comment_lines()

void libMesh::MeshInput< MeshBase >::skip_comment_lines ( std::istream &  in,
const char  comment_start 
)
protectedinherited

Reads input from in, skipping all the lines that start with the character comment_start.

Definition at line 187 of file mesh_input.h.

Referenced by libMesh::TetGenIO::read(), and libMesh::UCDIO::read_implementation().

189 {
190  char c, line[256];
191 
192  while (in.get(c), c==comment_start)
193  in.getline (line, 255);
194 
195  // put back first character of
196  // first non-comment line
197  in.putback (c);
198 }

◆ use_mesh_dimension_instead_of_spatial_dimension()

void libMesh::ExodusII_IO::use_mesh_dimension_instead_of_spatial_dimension ( bool  val)

In the general case, meshes containing 2D elements can be manifolds living in 3D space, thus by default we write all meshes with the Exodus dimension set to LIBMESH_DIM = mesh.spatial_dimension().

In certain cases, however, the user may know his 2D mesh actually lives in the z=0 plane, and therefore wants to write a truly 2D Exodus mesh. In such a case, he should call this function with val=true.

Definition at line 987 of file exodusII_io.C.

References exio_helper.

988 {
989  exio_helper->use_mesh_dimension_instead_of_spatial_dimension(val);
990 }
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ verbose()

void libMesh::ExodusII_IO::verbose ( bool  set_verbosity)

Set the flag indicating if we should be verbose.

Definition at line 962 of file exodusII_io.C.

References _verbose, and exio_helper.

963 {
964  _verbose = set_verbosity;
965 
966  // Set the verbose flag in the helper object as well.
967  exio_helper->verbose = _verbose;
968 }
bool _verbose
should we be verbose?
Definition: exodusII_io.h:687
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ write()

void libMesh::ExodusII_IO::write ( const std::string &  fname)
overridevirtual

This method implements writing a mesh to a specified file.

Note that writes may be buffered for efficiency, and so may not reach disk until after the file has been closed, which happens when the ExodusII_IO object is destructed.

Implements libMesh::MeshOutput< MeshBase >.

Definition at line 2197 of file exodusII_io.C.

References _append, _verbose, exio_helper, libMesh::MeshBase::get_boundary_info(), libMesh::libmesh_assert(), libMesh::MeshInput< MeshBase >::mesh(), libMesh::MeshOutput< MT >::mesh(), and libMesh::BoundaryInfo::n_edge_conds().

Referenced by main(), libMesh::ErrorVector::plot_error(), ExodusTest< elem_type >::test_write(), MeshInputTest::testExodusFileMappings(), MeshInputTest::testExodusIGASidesets(), and libMesh::NameBasedIO::write().

2198 {
2199  LOG_SCOPE("write()", "ExodusII_IO");
2200 
2202 
2203  // We may need to gather a DistributedMesh to output it, making that
2204  // const qualifier in our constructor a dirty lie
2205  // The "true" specifies that we only need the mesh serialized to processor 0
2206  MeshSerializer serialize
2207  (const_cast<MeshBase &>(mesh),
2209 
2210  libmesh_assert( !exio_helper->opened_for_writing );
2211 
2212  // If the user has set the append flag here, it doesn't really make
2213  // sense: the intent of this function is to write a Mesh with no
2214  // data, while "appending" is really intended to add data to an
2215  // existing file. If we're verbose, print a message to this effect.
2216  if (_append && _verbose)
2217  libmesh_warning("Warning: Appending in ExodusII_IO::write() does not make sense.\n"
2218  "Creating a new file instead!");
2219 
2220  exio_helper->create(fname);
2221  exio_helper->initialize(fname,mesh);
2222  exio_helper->write_nodal_coordinates(mesh);
2223  exio_helper->write_elements(mesh);
2224  exio_helper->write_sidesets(mesh);
2225  exio_helper->write_nodesets(mesh);
2226  exio_helper->write_elemsets(mesh);
2227 
2228  if ((mesh.get_boundary_info().n_edge_conds() > 0) && _verbose)
2229  libmesh_warning("Warning: Mesh contains edge boundary IDs, but these "
2230  "are not supported by the ExodusII format.");
2231 }
const MT & mesh() const
Definition: mesh_output.h:259
std::size_t n_edge_conds() const
This class defines an abstract interface for Mesh output.
Definition: mesh_output.h:53
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Definition: mesh_base.h:170
This is the MeshBase class.
Definition: mesh_base.h:80
bool _verbose
should we be verbose?
Definition: exodusII_io.h:687
bool _append
Default false.
Definition: exodusII_io.h:693
libmesh_assert(ctx)
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676
Temporarily serialize a DistributedMesh for non-distributed-mesh capable code paths.

◆ write_added_sides()

void libMesh::ExodusII_IO::write_added_sides ( bool  val)

By default, we only write out the elements physically stored in the mesh.

If we have any SIDE_DISCONTINUOUS variables, however, we cannot easily output them on elements with sides that share vertices (and in 3D, edges). We can set this flag to instead create extra "side elements" on which to visualize such variables.

By default this flag is set to false.

Definition at line 1016 of file exodusII_io.C.

References exio_helper.

1017 {
1018  exio_helper->set_add_sides(val);
1019 }
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ write_as_dimension()

void libMesh::ExodusII_IO::write_as_dimension ( unsigned  dim)

Directly control the num_dim which is written to the Exodus file.

If non-zero, this value supersedes all other dimensions, including: 1.) MeshBase::spatial_dimension() 2.) MeshBase::mesh_dimension() 3.) Any value passed to use_mesh_dimension_instead_of_spatial_dimension() This is useful/necessary for working around a bug in Paraview which prevents the "Plot Over Line" filter from working on 1D meshes.

Definition at line 994 of file exodusII_io.C.

References dim, and exio_helper.

995 {
996  exio_helper->write_as_dimension(dim);
997 }
unsigned int dim
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ write_complex_magnitude()

void libMesh::ExodusII_IO::write_complex_magnitude ( bool  val)

Set the flag indicating whether the complex modulus should be written when complex numbers are enabled.

By default this flag is set to true.

Definition at line 972 of file exodusII_io.C.

References _write_complex_abs.

973 {
974  _write_complex_abs = val;
975 }
bool _write_complex_abs
By default, when complex numbers are enabled, for each variable we write out three values: the real p...
Definition: exodusII_io.h:728

◆ write_discontinuous_equation_systems()

void libMesh::MeshOutput< MeshBase >::write_discontinuous_equation_systems ( const std::string &  fname,
const EquationSystems es,
const std::set< std::string > *  system_names = nullptr 
)
virtualinherited

This method implements writing a mesh with discontinuous data to a specified file where the data is taken from the EquationSystems object.

Definition at line 89 of file mesh_output.C.

References libMesh::EquationSystems::build_discontinuous_solution_vector(), libMesh::EquationSystems::build_variable_names(), libMesh::EquationSystems::get_mesh(), libMesh::libmesh_assert(), and libMesh::out.

Referenced by write_timestep_discontinuous().

92 {
93  LOG_SCOPE("write_discontinuous_equation_systems()", "MeshOutput");
94 
95  // We may need to gather and/or renumber a DistributedMesh to output
96  // it, making that const qualifier in our constructor a dirty lie
97  MT & my_mesh = const_cast<MT &>(*_obj);
98 
99  // If we're asked to write data that's associated with a different
100  // mesh, output files full of garbage are the result.
101  libmesh_assert_equal_to(&es.get_mesh(), _obj);
102 
103  // A non-renumbered mesh may not have a contiguous numbering, and
104  // that needs to be fixed before we can build a solution vector.
105  if (my_mesh.max_elem_id() != my_mesh.n_elem() ||
106  my_mesh.max_node_id() != my_mesh.n_nodes())
107  {
108  // If we were allowed to renumber then we should have already
109  // been properly renumbered...
110  libmesh_assert(!my_mesh.allow_renumbering());
111 
112  libmesh_do_once(libMesh::out <<
113  "Warning: This MeshOutput subclass only supports meshes which are contiguously renumbered!"
114  << std::endl;);
115 
116  my_mesh.allow_renumbering(true);
117 
118  my_mesh.renumber_nodes_and_elements();
119 
120  // Not sure what good going back to false will do here, the
121  // renumbering horses have already left the barn...
122  my_mesh.allow_renumbering(false);
123  }
124 
125  MeshSerializer serialize(const_cast<MT &>(*_obj), !_is_parallel_format, _serial_only_needed_on_proc_0);
126 
127  // Build the list of variable names that will be written.
128  std::vector<std::string> names;
129  es.build_variable_names (names, nullptr, system_names);
130 
131  if (!_is_parallel_format)
132  {
133  // Build the nodal solution values & get the variable
134  // names from the EquationSystems object
135  std::vector<Number> soln;
136  es.build_discontinuous_solution_vector (soln, system_names,
137  nullptr, false, /* defaults */
138  this->get_add_sides());
139 
140  this->write_nodal_data_discontinuous (fname, soln, names);
141  }
142  else // _is_parallel_format
143  {
144  libmesh_not_implemented();
145  }
146 }
virtual void write_nodal_data_discontinuous(const std::string &, const std::vector< Number > &, const std::vector< std::string > &)
This method implements writing a mesh with discontinuous data to a specified file where the nodal dat...
Definition: mesh_output.h:118
const MeshBase *const _obj
A pointer to a constant object.
Definition: mesh_output.h:202
const bool _is_parallel_format
Flag specifying whether this format is parallel-capable.
Definition: mesh_output.h:184
libmesh_assert(ctx)
OStreamProxy out
const bool _serial_only_needed_on_proc_0
Flag specifying whether this format can be written by only serializing the mesh to processor zero...
Definition: mesh_output.h:193

◆ write_discontinuous_exodusII()

void libMesh::ExodusII_IO::write_discontinuous_exodusII ( const std::string &  name,
const EquationSystems es,
const std::set< std::string > *  system_names = nullptr 
)

Writes a exodusII file with discontinuous data.

Definition at line 195 of file exodusII_io.C.

References libMesh::EquationSystems::build_discontinuous_solution_vector(), libMesh::EquationSystems::build_variable_names(), get_add_sides(), and write_nodal_data_discontinuous().

Referenced by main().

198 {
199  std::vector<std::string> solution_names;
200  std::vector<Number> v;
201 
202  es.build_variable_names (solution_names, nullptr, system_names);
203  es.build_discontinuous_solution_vector (v, system_names,
204  nullptr, false, /* defaults */
205  this->get_add_sides());
206  this->write_nodal_data_discontinuous(name, v, solution_names);
207 }
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
Definition: elem_quality.C:42
void build_variable_names(std::vector< std::string > &var_names, const FEType *type=nullptr, const std::set< std::string > *system_names=nullptr) const
Fill the input vector var_names with the names of the variables for each system.
void build_discontinuous_solution_vector(std::vector< Number > &soln, const std::set< std::string > *system_names=nullptr, const std::vector< std::string > *var_names=nullptr, bool vertices_only=false, bool add_sides=false) const
Fill the input vector soln with solution values.
virtual bool get_add_sides() override
Definition: exodusII_io.C:1023
void write_nodal_data_discontinuous(const std::string &, const std::vector< Number > &, const std::vector< std::string > &) override
Write out a discontinuous nodal solution.
Definition: exodusII_io.C:2235

◆ write_element_data()

void libMesh::ExodusII_IO::write_element_data ( const EquationSystems es)

Write out element solution.

Definition at line 1376 of file exodusII_io.C.

References _output_variables, _timestep, _write_complex_abs, libMesh::EquationSystems::build_elemental_solution_vector(), libMesh::EquationSystems::build_variable_names(), libMesh::CONSTANT, exio_helper, libMesh::EquationSystems::get_vars_active_subdomains(), libMesh::MeshInput< MeshBase >::mesh(), libMesh::MeshOutput< MT >::mesh(), libMesh::MONOMIAL, libMesh::MONOMIAL_VEC, and libMesh::ParallelObject::processor_id().

Referenced by main(), and libMesh::ErrorVector::plot_error().

1377 {
1378  LOG_SCOPE("write_element_data()", "ExodusII_IO");
1379 
1380  // Be sure the file has been opened for writing!
1381  libmesh_error_msg_if(MeshOutput<MeshBase>::mesh().processor_id() == 0 && !exio_helper->opened_for_writing,
1382  "ERROR, ExodusII file must be initialized before outputting element variables.");
1383 
1384  // This function currently only works on serialized meshes. We rely
1385  // on having a reference to a non-const MeshBase object from our
1386  // MeshInput parent class to construct a MeshSerializer object,
1387  // similar to what is done in ExodusII_IO::write(). Note that
1388  // calling ExodusII_IO::write_timestep() followed by
1389  // ExodusII_IO::write_element_data() when the underlying Mesh is a
1390  // DistributedMesh will result in an unnecessary additional
1391  // serialization/re-parallelization step.
1392  // The "true" specifies that we only need the mesh serialized to processor 0
1394 
1395  // To be (possibly) filled with a filtered list of variable names to output.
1396  std::vector<std::string> names;
1397 
1398  // If _output_variables is populated, only output the monomials which are
1399  // also in the _output_variables vector.
1400  if (_output_variables.size() > 0)
1401  {
1402  // Create a list of CONSTANT MONOMIAL variable names
1403  std::vector<std::string> monomials;
1404  FEType type(CONSTANT, MONOMIAL);
1405  es.build_variable_names(monomials, &type);
1406 
1407  // Now concatenate a list of CONSTANT MONOMIAL_VEC variable names
1408  type = FEType(CONSTANT, MONOMIAL_VEC);
1409  es.build_variable_names(monomials, &type);
1410 
1411  // Filter that list against the _output_variables list. Note: if names is still empty after
1412  // all this filtering, all the monomial variables will be gathered
1413  for (const auto & var : monomials)
1414  if (std::find(_output_variables.begin(), _output_variables.end(), var) != _output_variables.end())
1415  names.push_back(var);
1416  }
1417 
1418  // If we pass in a list of names to "build_elemental_solution_vector()"
1419  // it'll filter the variables coming back.
1420  std::vector<Number> soln;
1421  es.build_elemental_solution_vector(soln, names);
1422 
1423  // Also, store the list of subdomains on which each variable is active
1424  std::vector<std::set<subdomain_id_type>> vars_active_subdomains;
1425  es.get_vars_active_subdomains(names, vars_active_subdomains);
1426 
1427  if (soln.empty()) // If there is nothing to write just return
1428  return;
1429 
1430  // The data must ultimately be written block by block. This means that this data
1431  // must be sorted appropriately.
1432  if (MeshOutput<MeshBase>::mesh().processor_id())
1433  return;
1434 
1436 
1437 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
1438 
1439  std::vector<std::string> complex_names =
1440  exio_helper->get_complex_names(names, _write_complex_abs);
1441 
1442  std::vector<std::set<subdomain_id_type>>
1443  complex_vars_active_subdomains =
1444  exio_helper->get_complex_vars_active_subdomains(vars_active_subdomains,
1446  exio_helper->initialize_element_variables(complex_names, complex_vars_active_subdomains);
1447 
1448  const std::vector<Real> complex_soln =
1449  complex_soln_components(soln, names.size(), _write_complex_abs);
1450 
1451  exio_helper->write_element_values(mesh, complex_soln, _timestep, complex_vars_active_subdomains);
1452 
1453 #else
1454  exio_helper->initialize_element_variables(names, vars_active_subdomains);
1455  exio_helper->write_element_values(mesh, soln, _timestep, vars_active_subdomains);
1456 #endif
1457 }
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:196
const MT & mesh() const
Definition: mesh_output.h:259
void build_variable_names(std::vector< std::string > &var_names, const FEType *type=nullptr, const std::set< std::string > *system_names=nullptr) const
Fill the input vector var_names with the names of the variables for each system.
This class defines an abstract interface for Mesh output.
Definition: mesh_output.h:53
This is the MeshBase class.
Definition: mesh_base.h:80
void get_vars_active_subdomains(const std::vector< std::string > &names, std::vector< std::set< subdomain_id_type >> &vars_active_subdomains) const
Retrieve vars_active_subdomains, which indicates the active subdomains for each variable in names...
int _timestep
Stores the current value of the timestep when calling ExodusII_IO::write_timestep().
Definition: exodusII_io.h:682
This class defines an abstract interface for Mesh input.
Definition: mesh_base.h:60
std::vector< std::string > _output_variables
The names of the variables to be output.
Definition: exodusII_io.h:707
bool _write_complex_abs
By default, when complex numbers are enabled, for each variable we write out three values: the real p...
Definition: exodusII_io.h:728
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676
Temporarily serialize a DistributedMesh for non-distributed-mesh capable code paths.
processor_id_type processor_id() const
void build_elemental_solution_vector(std::vector< Number > &soln, std::vector< std::string > &names) const
Retrieve the solution data for CONSTANT MONOMIALs and/or components of CONSTANT MONOMIAL_VECs.

◆ write_element_data_from_discontinuous_nodal_data()

void libMesh::ExodusII_IO::write_element_data_from_discontinuous_nodal_data ( const EquationSystems es,
const std::set< std::string > *  system_names = nullptr,
const std::string &  var_suffix = "_elem_node_" 
)

Similar to the function above, but instead of only handling (CONSTANT, MONOMIAL) data, writes out a general discontinuous solution field, e.g.

(FIRST, L2_LAGRANGE) or (SECOND, MONOMIAL) as a number of elemental fields equal to the number of vertices in each element. For example, if you have a (FIRST, L2_LAGRANGE) variable "u" defined on HEX8 elements, calling this function would by default write 8 elemental fields named u_elem_node_0, u_elem_node_1, u_elem_node_2, etc.

This may be useful if you have a viz tool which is capable of interpreting this element data as a discontinuous solution field. Note that (CONSTANT, MONOMIAL) data is still written as a single value per element, as it makes no sense to write n_vertices copies of the same value.

The 'var_suffix' parameter, which defaults to "_elem_node_", is used to generate the elemental variable names, and is inserted between the base variable name and the node id which the variable applies to, e.g. "u_elem_node_0", "u_elem_node_1", etc.

Definition at line 1463 of file exodusII_io.C.

References libMesh::EquationSystems::build_discontinuous_solution_vector(), libMesh::EquationSystems::build_variable_names(), libMesh::CONSTANT, distance(), libMesh::EquationSystems::get_vars_active_subdomains(), libMesh::index_range(), libMesh::MeshOutput< MT >::mesh(), mesh, libMesh::MONOMIAL, and libMesh::Quality::name().

Referenced by MeshInputTest::testExodusWriteElementDataFromDiscontinuousNodalData().

1466 {
1467  LOG_SCOPE("write_element_data_from_discontinuous_nodal_data()", "ExodusII_IO");
1468 
1469  // Be sure that some other function has already opened the file and prepared it
1470  // for writing. This is the same behavior as the write_element_data() function
1471  // which we are trying to mimic.
1472  libmesh_error_msg_if(MeshOutput<MeshBase>::mesh().processor_id() == 0 && !exio_helper->opened_for_writing,
1473  "ERROR, ExodusII file must be initialized before outputting element variables.");
1474 
1475  // This function currently only works on serialized meshes. The
1476  // "true" flag specifies that we only need the mesh serialized to
1477  // processor 0
1480  true);
1481 
1482  // Note: in general we want to respect the contents of
1483  // _output_variables, only building a solution vector with values
1484  // from the requested variables. First build a list of all variable
1485  // names, then throw out ones that aren't in _output_variables, if
1486  // any.
1487  std::vector<std::string> var_names;
1488  es.build_variable_names (var_names, /*fetype=*/nullptr, system_names);
1489 
1490  // Get a subset of all variable names that are CONSTANT,
1491  // MONOMIALs. We treat those slightly differently since they can
1492  // truly only have a single value per Elem.
1493  //
1494  // Should the same apply here for CONSTANT MONOMIAL_VECs? [CW]
1495  // That is, get rid of 'const' on 'fe_type' and rerun:
1496  // fe_type = FEType(CONSTANT, MONOMIAL_VEC);
1497  // es.build_variable_names(monomial_var_names, &fe_type);
1498  // Then, es.find_variable_numbers() can be used without a type
1499  // (since we know for sure they're monomials) like:
1500  // var_nums = es.find_variable_numbers(monomial_var_names)
1501  // for which the DOF indices for 'var_nums' have to be resolved
1502  // manually like in build_elemental_solution_vector()
1503  std::vector<std::string> monomial_var_names;
1504  const FEType fe_type(CONSTANT, MONOMIAL);
1505  es.build_variable_names(monomial_var_names, &fe_type);
1506 
1507  // Remove all names from var_names that are not in _output_variables.
1508  // Note: This approach avoids errors when the user provides invalid
1509  // variable names in _output_variables, as the code will not try to
1510  // write a variable that doesn't exist.
1511  if (!_output_variables.empty())
1512  {
1513  var_names.erase
1514  (std::remove_if
1515  (var_names.begin(),
1516  var_names.end(),
1517  [this](const std::string & name)
1518  {return !std::count(_output_variables.begin(),
1519  _output_variables.end(),
1520  name);}),
1521  var_names.end());
1522 
1523  // Also filter the monomial variable names.
1524  monomial_var_names.erase
1525  (std::remove_if
1526  (monomial_var_names.begin(),
1527  monomial_var_names.end(),
1528  [this](const std::string & name)
1529  {return !std::count(_output_variables.begin(),
1530  _output_variables.end(),
1531  name);}),
1532  monomial_var_names.end());
1533  }
1534 
1535  // Build a solution vector, limiting the results to the variables in
1536  // var_names and the Systems in system_names, and only computing values
1537  // at the vertices.
1538  std::vector<Number> v;
1540  (v, system_names, &var_names, /*vertices_only=*/true);
1541 
1542  // Get active subdomains for each variable in var_names.
1543  std::vector<std::set<subdomain_id_type>> vars_active_subdomains;
1544  es.get_vars_active_subdomains(var_names, vars_active_subdomains);
1545 
1546  // Determine names of variables to write based on the number of
1547  // nodes/vertices the elements in different subdomains have.
1549  std::map<subdomain_id_type, unsigned int> subdomain_id_to_vertices_per_elem;
1550  for (const auto & elem : mesh.active_element_ptr_range())
1551  {
1552  // Try to insert key/value pair into the map. If this returns
1553  // false, check the returned iterator's value to make sure it
1554  // matches. It shouldn't actually be possible for this to fail
1555  // (since if the Mesh was like this it would have already
1556  // failed) but it doesn't hurt to be on the safe side.
1557  auto pr2 = subdomain_id_to_vertices_per_elem.emplace
1558  (elem->subdomain_id(), elem->n_vertices());
1559  libmesh_error_msg_if(!pr2.second && pr2.first->second != elem->n_vertices(),
1560  "Elem with different number of vertices found.");
1561  }
1562 
1563  // Determine "derived" variable names. These names are created by
1564  // starting with the base variable name and appending the user's
1565  // variable_suffix (default: "_elem_node_") followed by a node id.
1566  //
1567  // Not every derived variable will be active on every subdomain,
1568  // even if the original variable _is_ active. Subdomains can have
1569  // different geometric element types (with differing numbers of
1570  // nodes), so some of the derived variable names will be inactive on
1571  // those subdomains.
1572  //
1573  // Since we would otherwise generate the same name once per
1574  // subdomain, we keep the list of names unique as we are creating
1575  // it. We can't use a std::set for this because we don't want the
1576  // variables names to be in a different order from the order
1577  // they were written in the call to: build_discontinuous_solution_vector()
1578  //
1579  // The list of derived variable names includes one for each vertex,
1580  // for higher-order elements we currently only write out vertex
1581  // values, but this could be changed in the future without too much
1582  // trouble.
1583  std::vector<std::string> derived_var_names;
1584 
1585  // Keep track of mapping from derived_name to (orig_name, node_id)
1586  // pair. We will use this later to determine whether a given
1587  // variable is active on a given subdomain.
1588  std::map<std::string, std::pair<std::string, unsigned int>>
1589  derived_name_to_orig_name_and_node_id;
1590 
1591  for (const auto & pr : subdomain_id_to_vertices_per_elem)
1592  {
1593  const subdomain_id_type sbd_id = pr.first;
1594  const unsigned int vertices_per_elem =
1595  subdomain_id_to_vertices_per_elem[sbd_id];
1596 
1597  std::ostringstream oss;
1598  for (unsigned int n=0; n<vertices_per_elem; ++n)
1599  for (const auto & orig_var_name : var_names)
1600  {
1601  oss.str("");
1602  oss.clear();
1603  oss << orig_var_name << var_suffix << n;
1604  std::string derived_name = oss.str();
1605 
1606  // Only add this var name if it's not already in the list.
1607  if (!std::count(derived_var_names.begin(), derived_var_names.end(), derived_name))
1608  {
1609  derived_var_names.push_back(derived_name);
1610  // Add entry for derived_name -> (orig_name, node_id) mapping.
1611  derived_name_to_orig_name_and_node_id[derived_name] =
1612  std::make_pair(orig_var_name, n);
1613  }
1614  }
1615  }
1616 
1617  // For each derived variable name, determine whether it is active
1618  // based on how many nodes/vertices the elements in a given subdomain have,
1619  // and whether they were active on the subdomain to begin with.
1620  std::vector<std::set<subdomain_id_type>>
1621  derived_vars_active_subdomains(derived_var_names.size());
1622 
1623  // A new data structure for keeping track of a list of variable names
1624  // that are in the discontinuous solution vector on each subdomain. Used
1625  // for indexing. Note: if a variable was inactive at the System level,
1626  // an entry for it will still be in the discontinuous solution vector,
1627  // but it will just have a value of zero. On the other hand, when we
1628  // create the derived variable names some of them are "inactive" on
1629  // different subdomains in the sense that they don't exist at all, i.e.
1630  // there is no zero padding for them. We need to be able to distinguish
1631  // between these two types in order to do the indexing into this vector
1632  // correctly.
1633  std::map<subdomain_id_type, std::vector<std::string>>
1634  subdomain_to_var_names;
1635 
1636  for (auto derived_var_id : index_range(derived_var_names))
1637  {
1638  const auto & derived_name = derived_var_names[derived_var_id];
1639  const auto & [orig_name, node_id] =
1640  libmesh_map_find (derived_name_to_orig_name_and_node_id,
1641  derived_name);
1642 
1643  // For each subdomain, determine whether the current variable
1644  // should be active on that subdomain.
1645  for (const auto & pr : subdomain_id_to_vertices_per_elem)
1646  {
1647  // Convenience variables for the current subdomain and the
1648  // number of nodes elements in this subdomain have.
1649  subdomain_id_type sbd_id = pr.first;
1650  unsigned int vertices_per_elem_this_sbd =
1651  subdomain_id_to_vertices_per_elem[sbd_id];
1652 
1653  // Check whether variable orig_name was active on this
1654  // subdomain to begin with by looking in the
1655  // vars_active_subdomains container. We assume that the
1656  // location of orig_name in the var_names vector matches its
1657  // index in the vars_active_subdomains container.
1658  auto var_loc = std::find(var_names.begin(), var_names.end(), orig_name);
1659  libmesh_error_msg_if(var_loc == var_names.end(),
1660  "Variable " << orig_name << " somehow not found in var_names array.");
1661  auto var_id = std::distance(var_names.begin(), var_loc);
1662 
1663  // The derived_var will only be active if this subdomain has
1664  // enough vertices for that to be the case.
1665  if (node_id < vertices_per_elem_this_sbd)
1666  {
1667  // Regardless of whether the original variable was not active on this subdomain,
1668  // the discontinuous solution vector will have zero padding for it, and
1669  // we will need to account for it. Therefore it should still be added to
1670  // the subdomain_to_var_names data structure!
1671  subdomain_to_var_names[sbd_id].push_back(derived_name);
1672 
1673  // If the original variable was not active on the
1674  // current subdomain, it should not be added to the
1675  // derived_vars_active_subdomains data structure, since
1676  // it will not be written to the Exodus file.
1677 
1678  // Determine if the original variable was active on the
1679  // current subdomain.
1680  bool orig_var_active =
1681  (vars_active_subdomains[var_id].empty() ||
1682  vars_active_subdomains[var_id].count(sbd_id));
1683 
1684  // And only if it was, add it to the
1685  // derived_vars_active_subdomains data structure.
1686  if (orig_var_active)
1687  derived_vars_active_subdomains[derived_var_id].insert(sbd_id);
1688  }
1689  } // end loop over subdomain_id_to_vertices_per_elem
1690  } // end loop over derived_var_names
1691 
1692  // At this point we've built the "true" list of derived names, but
1693  // if there are any CONSTANT MONOMIALS in this list, we now want to
1694  // remove all but one copy of them from the derived_var_names list,
1695  // and rename them in (but not remove them from) the
1696  // subdomain_to_var_names list, and then update the
1697  // derived_vars_active_subdomains containers before finally calling
1698  // the Exodus helper functions.
1699  for (auto & derived_var_name : derived_var_names)
1700  {
1701  // Get the original name associated with this derived name.
1702  const auto & name_and_id =
1703  libmesh_map_find (derived_name_to_orig_name_and_node_id,
1704  derived_var_name);
1705 
1706  // Convenience variables for the map entry's contents.
1707  const std::string & orig_name = name_and_id.first;
1708 
1709  // Was the original name a constant monomial?
1710  if (std::count(monomial_var_names.begin(),
1711  monomial_var_names.end(),
1712  orig_name))
1713  {
1714  // Rename this variable in the subdomain_to_var_names vectors.
1715  for (auto & pr : subdomain_to_var_names)
1716  {
1717  // Reference to ordered list of variable names on this subdomain.
1718  auto & name_vec = pr.second;
1719 
1720  auto name_vec_it =
1721  std::find(name_vec.begin(),
1722  name_vec.end(),
1723  derived_var_name);
1724 
1725  if (name_vec_it != name_vec.end())
1726  {
1727  // Actually rename it back to the orig_name, dropping
1728  // the "_elem_corner_" stuff.
1729  *name_vec_it = orig_name;
1730  }
1731  }
1732 
1733  // Finally, rename the variable in the derived_var_names vector itself.
1734  derived_var_name = orig_name;
1735  } // if (monomial)
1736  } // end loop over derived names
1737 
1738  // Now remove duplicate entries from derived_var_names after the first.
1739  // Also update the derived_vars_active_subdomains container in a consistent way.
1740  {
1741  std::vector<std::string> derived_var_names_edited;
1742  std::vector<std::set<subdomain_id_type>> derived_vars_active_subdomains_edited;
1743  std::vector<unsigned int> found_first(monomial_var_names.size());
1744 
1745  for (auto i : index_range(derived_var_names))
1746  {
1747  const auto & derived_var_name = derived_var_names[i];
1748  const auto & active_set = derived_vars_active_subdomains[i];
1749 
1750  // Determine whether we will keep this derived variable name in
1751  // the final container.
1752  bool keep = true;
1753  for (auto j : index_range(monomial_var_names))
1754  if (derived_var_name == monomial_var_names[j])
1755  {
1756  if (!found_first[j])
1757  found_first[j] = 1;
1758 
1759  else
1760  keep = false;
1761  }
1762 
1763  // We also don't keep variables that are not active on any subdomains.
1764  // Contrary to other uses of the var_active_subdomains container where
1765  // the empty set means "all" subdomains, here it really means "none".
1766  if (active_set.empty())
1767  keep = false;
1768 
1769  if (keep)
1770  {
1771  derived_var_names_edited.push_back(derived_var_name);
1772  derived_vars_active_subdomains_edited.push_back(active_set);
1773  }
1774  }
1775 
1776  // We built the filtered ranges, now swap them with the originals.
1777  derived_var_names.swap(derived_var_names_edited);
1778  derived_vars_active_subdomains.swap(derived_vars_active_subdomains_edited);
1779  }
1780 
1781 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
1782  // Build complex variable names "r_foo", "i_foo", "a_foo" and the lists of
1783  // subdomains on which they are active.
1784  auto complex_var_names =
1785  exio_helper->get_complex_names(derived_var_names,
1787  auto complex_vars_active_subdomains =
1788  exio_helper->get_complex_vars_active_subdomains(derived_vars_active_subdomains,
1790  auto complex_subdomain_to_var_names =
1791  exio_helper->get_complex_subdomain_to_var_names(subdomain_to_var_names,
1793 
1794  // Make expanded version of vector "v" in which each entry in the
1795  // original expands to an ("r_", "i_", "a_") triple.
1796  // "nco" is the number of complex outputs, which depends on whether
1797  // or not we are writing out the complex magnitudes.
1798  std::vector<Real> complex_v;
1799  int nco = _write_complex_abs ? 3 : 2;
1800  complex_v.reserve(nco * v.size());
1801  for (const auto & val : v)
1802  {
1803  complex_v.push_back(val.real());
1804  complex_v.push_back(val.imag());
1805  if (_write_complex_abs)
1806  complex_v.push_back(std::abs(val));
1807  }
1808 
1809  // Finally, initialize storage for the variables and write them to file.
1810  exio_helper->initialize_element_variables
1811  (complex_var_names, complex_vars_active_subdomains);
1812  exio_helper->write_element_values_element_major
1813  (mesh, complex_v, _timestep,
1814  complex_vars_active_subdomains,
1815  complex_var_names,
1816  complex_subdomain_to_var_names);
1817 #else
1818 
1819  // Call function which writes the derived variable names to the
1820  // Exodus file.
1821  exio_helper->initialize_element_variables(derived_var_names, derived_vars_active_subdomains);
1822 
1823  // ES::build_discontinuous_solution_vector() creates a vector with
1824  // an element-major ordering, so call Helper::write_element_values()
1825  // passing false for the last argument.
1826  exio_helper->write_element_values_element_major
1827  (mesh, v, _timestep,
1828  derived_vars_active_subdomains,
1829  derived_var_names,
1830  subdomain_to_var_names);
1831 #endif
1832 }
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
Definition: elem_quality.C:42
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:196
const MT & mesh() const
Definition: mesh_output.h:259
void build_variable_names(std::vector< std::string > &var_names, const FEType *type=nullptr, const std::set< std::string > *system_names=nullptr) const
Fill the input vector var_names with the names of the variables for each system.
void build_discontinuous_solution_vector(std::vector< Number > &soln, const std::set< std::string > *system_names=nullptr, const std::vector< std::string > *var_names=nullptr, bool vertices_only=false, bool add_sides=false) const
Fill the input vector soln with solution values.
This class defines an abstract interface for Mesh output.
Definition: mesh_output.h:53
Real distance(const Point &p)
This is the MeshBase class.
Definition: mesh_base.h:80
void get_vars_active_subdomains(const std::vector< std::string > &names, std::vector< std::set< subdomain_id_type >> &vars_active_subdomains) const
Retrieve vars_active_subdomains, which indicates the active subdomains for each variable in names...
int _timestep
Stores the current value of the timestep when calling ExodusII_IO::write_timestep().
Definition: exodusII_io.h:682
This class defines an abstract interface for Mesh input.
Definition: mesh_base.h:60
std::vector< std::string > _output_variables
The names of the variables to be output.
Definition: exodusII_io.h:707
bool _write_complex_abs
By default, when complex numbers are enabled, for each variable we write out three values: the real p...
Definition: exodusII_io.h:728
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676
Temporarily serialize a DistributedMesh for non-distributed-mesh capable code paths.
processor_id_type processor_id() const
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:153

◆ write_elemset_data()

void libMesh::ExodusII_IO::write_elemset_data ( int  timestep,
const std::vector< std::string > &  var_names,
const std::vector< std::set< elemset_id_type >> &  elemset_ids_in,
const std::vector< std::map< std::pair< dof_id_type, elemset_id_type >, Real >> &  elemset_vals 
)

The Exodus format can also store values on elemsets.

The inputs to the function are: .) var_names[i] is the name of the ith elemset variable to be written to file. .) elemset_ids_in[i] is a set of elemset ids where var_names[i] is active. .) elemset_vals[i] is a map from (elem-id, elemset-id) pairs to the corresponding real-valued data.

Note
You must have already written the mesh by calling e.g. write() (and write_elemsets()) before calling this function, because it uses the ordering of the elemsets that have already been written to the Exodus file.

Definition at line 2158 of file exodusII_io.C.

References exio_helper.

2162 {
2163  libmesh_error_msg_if(!exio_helper->opened_for_writing,
2164  "ERROR, ExodusII file must be opened for writing "
2165  "before calling ExodusII_IO::write_elemset_data()!");
2166 
2167  exio_helper->write_elemset_data(timestep, var_names, elemset_ids_in, elemset_vals);
2168 }
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ write_elemsets()

void libMesh::ExodusII_IO::write_elemsets ( )

Write elemsets stored on the Mesh to file.

Note
An elemset is a concept which is related to (but distinct from) both elem blocks and sidesets/nodesets. Elements in an elemset can be from multiple different blocks. In addition, one can define an elemset variable, which is like an elemental variable but exists only on the elements defined in the set.

Definition at line 2058 of file exodusII_io.C.

References exio_helper, libMesh::MeshInput< MeshBase >::mesh(), and libMesh::MeshOutput< MT >::mesh().

2059 {
2060  libmesh_error_msg_if(!exio_helper->opened_for_writing,
2061  "ERROR, ExodusII file must be opened for writing "
2062  "before calling ExodusII_IO::write_elemsets()!");
2063 
2065  exio_helper->write_elemsets(mesh);
2066 }
const MT & mesh() const
Definition: mesh_output.h:259
This is the MeshBase class.
Definition: mesh_base.h:80
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ write_equation_systems()

void libMesh::ExodusII_IO::write_equation_systems ( const std::string &  fname,
const EquationSystems es,
const std::set< std::string > *  system_names = nullptr 
)
overridevirtual

Writes out the solution for no specific time or timestep.

Parameters
fnameName of the file to write to
esEquationSystems object which contains the solution vector.
system_namesOptional list of systems to write solutions for.

Reimplemented from libMesh::MeshOutput< MeshBase >.

Definition at line 2050 of file exodusII_io.C.

References write_timestep().

Referenced by libMesh::RBConstruction::enrich_basis_from_rhs_terms(), main(), scale_mesh_and_plot(), MeshInputTest::testExodusWriteElementDataFromDiscontinuousNodalData(), PeriodicBCTest::testPeriodicBC(), WriteVecAndScalar::testWriteExodus(), transform_mesh_and_plot(), libMesh::TransientRBConstruction::truth_solve(), and libMesh::RBConstruction::truth_solve().

2053 {
2054  write_timestep(fname, es, 1, 0, system_names);
2055 }
void write_timestep(const std::string &fname, const EquationSystems &es, const int timestep, const Real time, const std::set< std::string > *system_names=nullptr)
Writes out the solution at a specific timestep.
Definition: exodusII_io.C:2034

◆ write_global_data()

void libMesh::ExodusII_IO::write_global_data ( const std::vector< Number > &  soln,
const std::vector< std::string > &  names 
)

Write out global variables.

Definition at line 2002 of file exodusII_io.C.

References _timestep, _write_complex_abs, exio_helper, and libMesh::ParallelObject::processor_id().

2004 {
2005  LOG_SCOPE("write_global_data()", "ExodusII_IO");
2006 
2008  return;
2009 
2010  libmesh_error_msg_if(!exio_helper->opened_for_writing,
2011  "ERROR, ExodusII file must be initialized before outputting global variables.");
2012 
2013 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
2014 
2015  std::vector<std::string> complex_names =
2016  exio_helper->get_complex_names(names,
2018 
2019  exio_helper->initialize_global_variables(complex_names);
2020 
2021  const std::vector<Real> complex_soln =
2022  complex_soln_components(soln, names.size(), _write_complex_abs);
2023 
2024  exio_helper->write_global_values(complex_soln, _timestep);
2025 
2026 #else
2027  exio_helper->initialize_global_variables(names);
2028  exio_helper->write_global_values(soln, _timestep);
2029 #endif
2030 }
This class defines an abstract interface for Mesh output.
Definition: mesh_output.h:53
int _timestep
Stores the current value of the timestep when calling ExodusII_IO::write_timestep().
Definition: exodusII_io.h:682
bool _write_complex_abs
By default, when complex numbers are enabled, for each variable we write out three values: the real p...
Definition: exodusII_io.h:728
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676
processor_id_type processor_id() const

◆ write_information_records()

void libMesh::ExodusII_IO::write_information_records ( const std::vector< std::string > &  records)

Write out information records.

Definition at line 1989 of file exodusII_io.C.

References exio_helper, and libMesh::ParallelObject::processor_id().

1990 {
1992  return;
1993 
1994  libmesh_error_msg_if(!exio_helper->opened_for_writing,
1995  "ERROR, ExodusII file must be initialized before outputting information records.");
1996 
1997  exio_helper->write_information_records(records);
1998 }
This class defines an abstract interface for Mesh output.
Definition: mesh_output.h:53
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676
processor_id_type processor_id() const

◆ write_nodal_data() [1/3]

void libMesh::MeshOutput< MeshBase >::write_nodal_data ( const std::string &  fname,
const NumericVector< Number > &  parallel_soln,
const std::vector< std::string > &  names 
)
virtualinherited

This method may be overridden by "parallel" output formats for writing nodal data.

Instead of getting a localized copy of the nodal solution vector, it is passed a NumericVector of type=PARALLEL which is in node-major order i.e. (u0,v0,w0, u1,v1,w1, u2,v2,w2, u3,v3,w3, ...) and contains n_nodes*n_vars total entries. Then, it is up to the individual I/O class to extract the required solution values from this vector and write them in parallel.

If not implemented, localizes the parallel vector into a std::vector and calls the other version of this function.

Reimplemented in libMesh::Nemesis_IO.

Definition at line 149 of file mesh_output.C.

References libMesh::NumericVector< T >::localize().

152 {
153  // This is the fallback implementation for parallel I/O formats that
154  // do not yet implement proper writing in parallel, and instead rely
155  // on the full solution vector being available on all processors.
156  std::vector<Number> soln;
157  parallel_soln.localize(soln);
158  this->write_nodal_data(fname, soln, names);
159 }
virtual void write_nodal_data(const std::string &, const std::vector< Number > &, const std::vector< std::string > &)
This method implements writing a mesh with nodal data to a specified file where the nodal data and va...
Definition: mesh_output.h:109
virtual void localize(std::vector< T > &v_local) const =0
Creates a copy of the global vector in the local vector v_local.

◆ write_nodal_data() [2/3]

void libMesh::MeshOutput< MeshBase >::write_nodal_data ( const std::string &  fname,
const EquationSystems es,
const std::set< std::string > *  system_names 
)
virtualinherited

This method should be overridden by "parallel" output formats for writing nodal data.

Instead of getting a localized copy of the nodal solution vector, it directly uses EquationSystems current_local_solution vectors to look up nodal values.

If not implemented, reorders the solutions into a nodal-only NumericVector and calls the above version of this function.

Reimplemented in libMesh::Nemesis_IO.

Definition at line 162 of file mesh_output.C.

References libMesh::EquationSystems::build_parallel_solution_vector(), and libMesh::EquationSystems::build_variable_names().

165 {
166  std::vector<std::string> names;
167  es.build_variable_names (names, nullptr, system_names);
168 
169  std::unique_ptr<NumericVector<Number>> parallel_soln =
170  es.build_parallel_solution_vector(system_names);
171 
172  this->write_nodal_data (fname, *parallel_soln, names);
173 }
virtual void write_nodal_data(const std::string &, const std::vector< Number > &, const std::vector< std::string > &)
This method implements writing a mesh with nodal data to a specified file where the nodal data and va...
Definition: mesh_output.h:109

◆ write_nodal_data() [3/3]

void libMesh::ExodusII_IO::write_nodal_data ( const std::string &  fname,
const std::vector< Number > &  soln,
const std::vector< std::string > &  names 
)
overridevirtual

Write out a nodal solution.

Reimplemented from libMesh::MeshOutput< MeshBase >.

Definition at line 1836 of file exodusII_io.C.

References _allow_empty_variables, _output_variables, _timestep, _write_complex_abs, exio_helper, libMesh::MeshTools::Generation::Private::idx(), std::imag(), libMesh::index_range(), libMesh::libmesh_ignore(), libMesh::MeshInput< MeshBase >::mesh(), libMesh::MeshOutput< MT >::mesh(), libMesh::MeshBase::n_nodes(), libMesh::ParallelObject::n_processors(), libMesh::ParallelObject::processor_id(), std::real(), libMesh::EquationSystems::redundant_added_side(), and write_nodal_data_common().

Referenced by libMesh::NameBasedIO::write_nodal_data().

1839 {
1840  LOG_SCOPE("write_nodal_data()", "ExodusII_IO");
1841 
1843 
1844  int num_vars = cast_int<int>(names.size());
1845  dof_id_type num_nodes = mesh.n_nodes();
1846 
1847  // The names of the variables to be output
1848  std::vector<std::string> output_names;
1849 
1850  if (_allow_empty_variables || !_output_variables.empty())
1851  output_names = _output_variables;
1852  else
1853  output_names = names;
1854 
1855 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
1856  std::vector<std::string> complex_names =
1857  exio_helper->get_complex_names(output_names,
1859 
1860  // Call helper function for opening/initializing data, giving it the
1861  // complex variable names
1862  this->write_nodal_data_common(fname, complex_names, /*continuous=*/true);
1863 #else
1864  // Call helper function for opening/initializing data
1865  this->write_nodal_data_common(fname, output_names, /*continuous=*/true);
1866 #endif
1867 
1868  if (mesh.processor_id())
1869  return;
1870 
1871  // This will count the number of variables actually output
1872  for (int c=0; c<num_vars; c++)
1873  {
1874  std::stringstream name_to_find;
1875 
1876  std::vector<std::string>::iterator pos =
1877  std::find(output_names.begin(), output_names.end(), names[c]);
1878  if (pos == output_names.end())
1879  continue;
1880 
1881  unsigned int variable_name_position =
1882  cast_int<unsigned int>(pos - output_names.begin());
1883 
1884  // Set up temporary vectors to be passed to Exodus to write the
1885  // nodal values for a single variable at a time.
1886 #ifdef LIBMESH_USE_REAL_NUMBERS
1887  std::vector<Number> cur_soln;
1888 
1889  // num_nodes is either exactly how much space we will need for
1890  // each vector, or a safe upper bound for the amount of memory
1891  // we will require when there are gaps in the numbering.
1892  cur_soln.reserve(num_nodes);
1893 #else
1894  std::vector<Real> real_parts;
1895  std::vector<Real> imag_parts;
1896  std::vector<Real> magnitudes;
1897  real_parts.reserve(num_nodes);
1898  imag_parts.reserve(num_nodes);
1899  if (_write_complex_abs)
1900  magnitudes.reserve(num_nodes);
1901 #endif
1902 
1903  // There could be gaps in soln based on node numbering, but in
1904  // serial the empty numbers are left empty.
1905  // There could also be offsets in soln based on "fake" nodes
1906  // inserted on each processor (because NumericVector indices
1907  // have to be contiguous); the helper keeps track of those.
1908  // We now copy the proper solution values contiguously into
1909  // "cur_soln", removing the gaps.
1910  for (const auto & node : mesh.node_ptr_range())
1911  {
1912  const dof_id_type idx =
1913  (exio_helper->node_id_to_vec_id(node->id()))
1914  * num_vars + c;
1915 #ifdef LIBMESH_USE_REAL_NUMBERS
1916  cur_soln.push_back(soln[idx]);
1917 #else
1918  real_parts.push_back(soln[idx].real());
1919  imag_parts.push_back(soln[idx].imag());
1920  if (_write_complex_abs)
1921  magnitudes.push_back(std::abs(soln[idx]));
1922 #endif
1923  }
1924 
1925  // If we're adding extra sides, we need to add their data too.
1926  //
1927  // Because soln was created from a parallel NumericVector, its
1928  // numbering was contiguous on each processor; we need to use
1929  // the same offsets here, and we need to loop through elements
1930  // from earlier ranks first.
1931  if (exio_helper->get_add_sides())
1932  {
1933  std::vector<std::vector<const Elem *>>
1934  elems_by_pid(mesh.n_processors());
1935 
1936  for (const auto & elem : mesh.active_element_ptr_range())
1937  elems_by_pid[elem->processor_id()].push_back(elem);
1938 
1939  for (auto p : index_range(elems_by_pid))
1940  {
1941  dof_id_type global_idx =
1942  exio_helper->added_node_offset_on(p) * num_vars + c;
1943  for (const Elem * elem : elems_by_pid[p])
1944  {
1945  for (auto s : elem->side_index_range())
1946  {
1948  continue;
1949 
1950  const std::vector<unsigned int> side_nodes =
1951  elem->nodes_on_side(s);
1952 
1953  for (auto n : index_range(side_nodes))
1954  {
1955  libmesh_ignore(n);
1956  libmesh_assert_less(global_idx, soln.size());
1957 #ifdef LIBMESH_USE_REAL_NUMBERS
1958  cur_soln.push_back(soln[global_idx]);
1959 #else
1960  real_parts.push_back(soln[global_idx].real());
1961  imag_parts.push_back(soln[global_idx].imag());
1962  if (_write_complex_abs)
1963  magnitudes.push_back(std::abs(soln[global_idx]));
1964 #endif
1965  global_idx += num_vars;
1966  }
1967  }
1968  }
1969  }
1970  }
1971 
1972  // Finally, actually call the Exodus API to write to file.
1973 #ifdef LIBMESH_USE_REAL_NUMBERS
1974  exio_helper->write_nodal_values(variable_name_position+1, cur_soln, _timestep);
1975 #else
1976  int nco = _write_complex_abs ? 3 : 2;
1977  exio_helper->write_nodal_values(nco*variable_name_position+1, real_parts, _timestep);
1978  exio_helper->write_nodal_values(nco*variable_name_position+2, imag_parts, _timestep);
1979  if (_write_complex_abs)
1980  exio_helper->write_nodal_values(3*variable_name_position+3, magnitudes, _timestep);
1981 #endif
1982 
1983  }
1984 }
const MT & mesh() const
Definition: mesh_output.h:259
boost::multiprecision::float128 real(const boost::multiprecision::float128 in)
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
This is the MeshBase class.
Definition: mesh_base.h:80
int _timestep
Stores the current value of the timestep when calling ExodusII_IO::write_timestep().
Definition: exodusII_io.h:682
processor_id_type n_processors() const
void libmesh_ignore(const Args &...)
std::vector< std::string > _output_variables
The names of the variables to be output.
Definition: exodusII_io.h:707
void write_nodal_data_common(std::string fname, const std::vector< std::string > &names, bool continuous=true)
This function factors out a bunch of code which is common to the write_nodal_data() and write_nodal_d...
Definition: exodusII_io.C:2313
bool _write_complex_abs
By default, when complex numbers are enabled, for each variable we write out three values: the real p...
Definition: exodusII_io.h:728
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676
bool _allow_empty_variables
Flag which controls the behavior of _output_variables: .) If true, _output_variables is allowed to re...
Definition: exodusII_io.h:717
boost::multiprecision::float128 imag(const boost::multiprecision::float128)
processor_id_type processor_id() const
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:153
virtual dof_id_type n_nodes() const =0
unsigned int idx(const ElemType type, const unsigned int nx, const unsigned int i, const unsigned int j)
A useful inline function which replaces the macros used previously.
uint8_t dof_id_type
Definition: id_types.h:67
static bool redundant_added_side(const Elem &elem, unsigned int side)

◆ write_nodal_data_common()

void libMesh::ExodusII_IO::write_nodal_data_common ( std::string  fname,
const std::vector< std::string > &  names,
bool  continuous = true 
)

This function factors out a bunch of code which is common to the write_nodal_data() and write_nodal_data_discontinuous() functions.

Definition at line 2313 of file exodusII_io.C.

References _append, exio_helper, libMesh::MeshInput< MeshBase >::mesh(), libMesh::MeshOutput< MT >::mesh(), and libMesh::ParallelObject::processor_id().

Referenced by write_nodal_data(), and write_nodal_data_discontinuous().

2316 {
2318 
2319  // This function can be called multiple times, we only want to open
2320  // the ExodusII file the first time it's called.
2321  if (!exio_helper->opened_for_writing)
2322  {
2323  // If we're appending, open() the file with read_only=false,
2324  // otherwise create() it and write the contents of the mesh to
2325  // it.
2326  if (_append)
2327  {
2328  // We do our writing only from proc 0, to avoid race
2329  // conditions with Exodus 8
2331  {
2332  exio_helper->open(fname.c_str(), /*read_only=*/false);
2333  // If we're appending, it's not valid to call exio_helper->initialize()
2334  // or exio_helper->initialize_nodal_variables(), but we do need to set up
2335  // certain aspects of the Helper object itself, such as the number of nodes
2336  // and elements. We do that by reading the header...
2337  exio_helper->read_and_store_header_info();
2338 
2339  // ...and reading the block info
2340  exio_helper->read_block_info();
2341  }
2342  // Keep other processors aware of what we've done on root
2343  else
2344  {
2345  exio_helper->opened_for_writing = true;
2346  exio_helper->current_filename = fname;
2347  }
2348  }
2349  else
2350  {
2351  exio_helper->create(fname);
2352 
2353  // But some of our write calls are parallel-only, due to
2354  // calls to parallel-only getter functions.
2355  exio_helper->initialize(fname, mesh, !continuous);
2356 
2357  exio_helper->write_nodal_coordinates(mesh, !continuous);
2358  exio_helper->write_elements(mesh, !continuous);
2359 
2360  exio_helper->write_sidesets(mesh);
2361  exio_helper->write_nodesets(mesh);
2362  exio_helper->write_elemsets(mesh);
2363 
2364  exio_helper->initialize_nodal_variables(names);
2365  }
2366  }
2367  else
2368  {
2369  // We are already open for writing, so check that the filename
2370  // passed to this function matches the filename currently in use
2371  // by the helper.
2372  libmesh_error_msg_if(fname != exio_helper->current_filename,
2373  "Error! This ExodusII_IO object is already associated with file: "
2374  << exio_helper->current_filename
2375  << ", cannot use it with requested file: "
2376  << fname);
2377  }
2378 }
const MT & mesh() const
Definition: mesh_output.h:259
This class defines an abstract interface for Mesh output.
Definition: mesh_output.h:53
This is the MeshBase class.
Definition: mesh_base.h:80
bool _append
Default false.
Definition: exodusII_io.h:693
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676
processor_id_type processor_id() const

◆ write_nodal_data_discontinuous()

void libMesh::ExodusII_IO::write_nodal_data_discontinuous ( const std::string &  fname,
const std::vector< Number > &  soln,
const std::vector< std::string > &  names 
)
overridevirtual

Write out a discontinuous nodal solution.

Reimplemented from libMesh::MeshOutput< MeshBase >.

Definition at line 2235 of file exodusII_io.C.

References _timestep, _write_complex_abs, exio_helper, get_add_sides(), libMesh::MeshInput< MeshBase >::mesh(), libMesh::MeshOutput< MT >::mesh(), libMesh::ParallelObject::processor_id(), and write_nodal_data_common().

Referenced by write_discontinuous_exodusII().

2238 {
2239  LOG_SCOPE("write_nodal_data_discontinuous()", "ExodusII_IO");
2240 
2242 
2243 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
2244 
2245  std::vector<std::string> complex_names =
2246  exio_helper->get_complex_names(names,
2248 
2249  // Call helper function for opening/initializing data, giving it the
2250  // complex variable names
2251  this->write_nodal_data_common(fname, complex_names, /*continuous=*/false);
2252 #else
2253  // Call helper function for opening/initializing data
2254  this->write_nodal_data_common(fname, names, /*continuous=*/false);
2255 #endif
2256 
2257  if (mesh.processor_id())
2258  return;
2259 
2260  int num_vars = cast_int<int>(names.size());
2261  libmesh_assert_equal_to(soln.size() % num_vars, 0);
2262  int num_nodes = soln.size() / num_vars;
2263  libmesh_assert_equal_to(exio_helper->num_nodes, num_nodes);
2264 
2265 #ifndef NDEBUG
2266  if (!this->get_add_sides())
2267  {
2268  int num_real_nodes = 0;
2269  for (const auto & elem : mesh.active_element_ptr_range())
2270  num_real_nodes += elem->n_nodes();
2271  libmesh_assert_equal_to(num_real_nodes, num_nodes);
2272  }
2273 #endif
2274 
2275  for (int c=0; c<num_vars; c++)
2276  {
2277 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
2278  std::vector<Real> real_parts(num_nodes);
2279  std::vector<Real> imag_parts(num_nodes);
2280  std::vector<Real> magnitudes;
2281  if (_write_complex_abs)
2282  magnitudes.resize(num_nodes);
2283 
2284  // The number of complex outputs depends on whether or not we are
2285  // writing out the absolute values.
2286  int nco = _write_complex_abs ? 3 : 2;
2287 
2288  for (int i=0; i<num_nodes; ++i)
2289  {
2290  real_parts[i] = soln[i*num_vars + c].real();
2291  imag_parts[i] = soln[i*num_vars + c].imag();
2292  if (_write_complex_abs)
2293  magnitudes[i] = std::abs(soln[i*num_vars + c]);
2294  }
2295  exio_helper->write_nodal_values(nco*c+1, real_parts, _timestep);
2296  exio_helper->write_nodal_values(nco*c+2, imag_parts, _timestep);
2297  if (_write_complex_abs)
2298  exio_helper->write_nodal_values(3*c+3, magnitudes, _timestep);
2299 #else
2300  // Copy out this variable's solution
2301  std::vector<Number> cur_soln(num_nodes);
2302 
2303  for (int i=0; i<num_nodes; i++)
2304  cur_soln[i] = soln[i*num_vars + c];
2305 
2306  exio_helper->write_nodal_values(c+1,cur_soln,_timestep);
2307 #endif
2308  }
2309 }
const MT & mesh() const
Definition: mesh_output.h:259
This is the MeshBase class.
Definition: mesh_base.h:80
int _timestep
Stores the current value of the timestep when calling ExodusII_IO::write_timestep().
Definition: exodusII_io.h:682
virtual bool get_add_sides() override
Definition: exodusII_io.C:1023
void write_nodal_data_common(std::string fname, const std::vector< std::string > &names, bool continuous=true)
This function factors out a bunch of code which is common to the write_nodal_data() and write_nodal_d...
Definition: exodusII_io.C:2313
bool _write_complex_abs
By default, when complex numbers are enabled, for each variable we write out three values: the real p...
Definition: exodusII_io.h:728
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676
processor_id_type processor_id() const

◆ write_nodeset_data()

void libMesh::ExodusII_IO::write_nodeset_data ( int  timestep,
const std::vector< std::string > &  var_names,
const std::vector< std::set< boundary_id_type >> &  node_boundary_ids,
const std::vector< std::map< BoundaryInfo::NodeBCTuple, Real >> &  bc_vals 
)

The Exodus format can also store values on nodesets.

This can be thought of as an alternative to defining a nodal variable field on lower-dimensional elements making up a part of the boundary. The inputs to the function are: .) var_names[i] is the name of the ith sideset variable to be written to file. .) node_boundary_ids[i] is a set of node_ids where var_names[i] is active. .) bc_vals[i] is a map from (node-id, boundary-id) NodeBCTuple objects to the corresponding real-valued data.

Note
You must have already written the mesh by calling e.g. write() before calling this function, because it uses the existing ordering of the Exodus nodesets.

Definition at line 2128 of file exodusII_io.C.

References exio_helper.

2132 {
2133  libmesh_error_msg_if(!exio_helper->opened_for_writing,
2134  "ERROR, ExodusII file must be opened for writing "
2135  "before calling ExodusII_IO::write_nodeset_data()!");
2136 
2137  exio_helper->write_nodeset_data(timestep, var_names, node_boundary_ids, bc_vals);
2138 }
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ write_sideset_data()

void libMesh::ExodusII_IO::write_sideset_data ( int  timestep,
const std::vector< std::string > &  var_names,
const std::vector< std::set< boundary_id_type >> &  side_ids,
const std::vector< std::map< BoundaryInfo::BCTuple, Real >> &  bc_vals 
)

The Exodus format can also store values on sidesets.

This can be thought of as an alternative to defining an elemental variable field on lower-dimensional elements making up a part of the boundary. The inputs to the function are: .) var_names[i] is the name of the ith sideset variable to be written to file. .) side_ids[i] is a set of side_ids where var_names[i] is active. .) bc_vals[i] is a map from (elem,side,id) BCTuple objects to the corresponding real-valued data.

Note
You must have already written the mesh by calling e.g. write() before calling this function, because it uses the existing ordering of the Exodus sidesets.

Definition at line 2070 of file exodusII_io.C.

References exio_helper, libMesh::MeshInput< MeshBase >::mesh(), and libMesh::MeshOutput< MT >::mesh().

2074 {
2075  libmesh_error_msg_if(!exio_helper->opened_for_writing,
2076  "ERROR, ExodusII file must be opened for writing "
2077  "before calling ExodusII_IO::write_sideset_data()!");
2078 
2080  exio_helper->write_sideset_data(mesh, timestep, var_names, side_ids, bc_vals);
2081 }
const MT & mesh() const
Definition: mesh_output.h:259
This is the MeshBase class.
Definition: mesh_base.h:80
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676

◆ write_timestep()

void libMesh::ExodusII_IO::write_timestep ( const std::string &  fname,
const EquationSystems es,
const int  timestep,
const Real  time,
const std::set< std::string > *  system_names = nullptr 
)

Writes out the solution at a specific timestep.

Parameters
fnameName of the file to write to
esEquationSystems object which contains the solution vector.
timestepThe timestep to write out, should be 1 indexed.
timeThe current simulation time.
system_namesOptional list of systems to write solutions for.

Definition at line 2034 of file exodusII_io.C.

References _timestep, exio_helper, libMesh::ParallelObject::processor_id(), and libMesh::MeshOutput< MT >::write_equation_systems().

Referenced by main(), libMesh::ClawSystem::solve_conservation_law(), write_equation_systems(), and write_output().

2039 {
2040  _timestep = timestep;
2041  MeshOutput<MeshBase>::write_equation_systems(fname,es,system_names);
2042 
2044  return;
2045 
2046  exio_helper->write_timestep(timestep, time);
2047 }
virtual void write_equation_systems(const std::string &, const EquationSystems &, const std::set< std::string > *system_names=nullptr)
This method implements writing a mesh with data to a specified file where the data is taken from the ...
Definition: mesh_output.C:31
This class defines an abstract interface for Mesh output.
Definition: mesh_output.h:53
int _timestep
Stores the current value of the timestep when calling ExodusII_IO::write_timestep().
Definition: exodusII_io.h:682
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676
processor_id_type processor_id() const

◆ write_timestep_discontinuous()

void libMesh::ExodusII_IO::write_timestep_discontinuous ( const std::string &  fname,
const EquationSystems es,
const int  timestep,
const Real  time,
const std::set< std::string > *  system_names = nullptr 
)

Writes a discontinuous solution at a specific timestep.

Parameters
fnameName of the file to be written
esEquationSystems object which contains the solution vector
timestepThe timestep to write out. (should be 1 indexed)
timeThe current simulation time
system_namesOptional list of systems to write solutions for.

Definition at line 211 of file exodusII_io.C.

References _timestep, exio_helper, libMesh::ParallelObject::processor_id(), and libMesh::MeshOutput< MeshBase >::write_discontinuous_equation_systems().

216 {
217  _timestep = timestep;
218  write_discontinuous_equation_systems (fname,es,system_names);
219 
221  return;
222 
223  exio_helper->write_timestep(timestep, time);
224 }
This class defines an abstract interface for Mesh output.
Definition: mesh_output.h:53
int _timestep
Stores the current value of the timestep when calling ExodusII_IO::write_timestep().
Definition: exodusII_io.h:682
virtual void write_discontinuous_equation_systems(const std::string &, const EquationSystems &, const std::set< std::string > *system_names=nullptr)
This method implements writing a mesh with discontinuous data to a specified file where the data is t...
Definition: mesh_output.C:89
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
Definition: exodusII_io.h:676
processor_id_type processor_id() const

Member Data Documentation

◆ _allow_empty_variables

bool libMesh::ExodusII_IO::_allow_empty_variables
private

Flag which controls the behavior of _output_variables: .) If true, _output_variables is allowed to remain empty.

.) If false, if _output_variables is empty it will be populated with a complete list of all variables. .) By default, calling set_output_variables() sets this flag to true, but it provides an override.

Definition at line 717 of file exodusII_io.h.

Referenced by set_output_variables(), and write_nodal_data().

◆ _append

bool libMesh::ExodusII_IO::_append
private

Default false.

If true, files will be opened with EX_WRITE rather than created from scratch when writing.

Definition at line 693 of file exodusII_io.h.

Referenced by append(), write(), and write_nodal_data_common().

◆ _communicator

const Parallel::Communicator& libMesh::ParallelObject::_communicator
protectedinherited

◆ _disc_bex

bool libMesh::ExodusII_IO::_disc_bex
private

Set to true (false is the default) to generate independent nodes for every Bezier Extraction element.

Definition at line 742 of file exodusII_io.h.

Referenced by read(), and set_discontinuous_bex().

◆ _extra_integer_vars

std::vector<std::string> libMesh::ExodusII_IO::_extra_integer_vars
private

An optional list of variables in the EXODUS file that are to be used to set extra integers when loading the file into a mesh.

The variable names will be used to name the extra integers.

Definition at line 701 of file exodusII_io.h.

Referenced by read(), and set_extra_integer_vars().

◆ _is_parallel_format

const bool libMesh::MeshOutput< MeshBase >::_is_parallel_format
protectedinherited

Flag specifying whether this format is parallel-capable.

If this is false (default) I/O is only permitted when the mesh has been serialized.

Definition at line 184 of file mesh_output.h.

Referenced by libMesh::FroIO::write(), libMesh::PostscriptIO::write(), and libMesh::EnsightIO::write().

◆ _output_variables

std::vector<std::string> libMesh::ExodusII_IO::_output_variables
private

The names of the variables to be output.

If this is empty then all variables are output.

Definition at line 707 of file exodusII_io.h.

Referenced by set_output_variables(), write_element_data(), and write_nodal_data().

◆ _serial_only_needed_on_proc_0

const bool libMesh::MeshOutput< MeshBase >::_serial_only_needed_on_proc_0
protectedinherited

Flag specifying whether this format can be written by only serializing the mesh to processor zero.

If this is false (default) the mesh will be serialized to all processors

Definition at line 193 of file mesh_output.h.

◆ _set_unique_ids_from_maps

bool libMesh::ExodusII_IO::_set_unique_ids_from_maps
private

Set Elem/Node unique_ids based on the elem_num_map and node_num_map contents during reading, populate those maps with unique_ids during writing.

See also: docs for set_unique_ids_from_maps(bool) function.

Definition at line 736 of file exodusII_io.h.

Referenced by read(), and set_unique_ids_from_maps().

◆ _timestep

int libMesh::ExodusII_IO::_timestep
private

◆ _verbose

bool libMesh::ExodusII_IO::_verbose
private

should we be verbose?

Definition at line 687 of file exodusII_io.h.

Referenced by verbose(), and write().

◆ _write_complex_abs

bool libMesh::ExodusII_IO::_write_complex_abs
private

By default, when complex numbers are enabled, for each variable we write out three values: the real part, "r_u" the imaginary part, "i_u", and the complex modulus, a_u := sqrt(r_u*r_u + i_u*i_u), which is also the value returned by std::abs(std::complex).

Since the modulus is not an independent quantity, we can set this flag to false and save some file space by not writing out.

Definition at line 728 of file exodusII_io.h.

Referenced by write_complex_magnitude(), write_element_data(), write_global_data(), write_nodal_data(), and write_nodal_data_discontinuous().

◆ elems_of_dimension

std::vector<bool> libMesh::MeshInput< MeshBase >::elems_of_dimension
protectedinherited

◆ exio_helper

std::unique_ptr<ExodusII_IO_Helper> libMesh::ExodusII_IO::exio_helper
private

The documentation for this class was generated from the following files: