libMesh
Loading...
Searching...
No Matches
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.
 
 ExodusII_IO (const MeshBase &mesh, bool single_precision=false)
 Constructor.
 
 ExodusII_IO (ExodusII_IO &&)=default
 ExodusII_IO special functions:
 
 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.
 
ExodusHeaderInfo read_header (const std::string &name)
 Read only the header information, instead of the entire mesh.
 
virtual void write (const std::string &fname) override
 This method implements writing a mesh to a specified file.
 
void verbose (bool set_verbosity)
 Set the flag indicating if we should be verbose.
 
void write_complex_magnitude (bool val)
 Set the flag indicating whether the complex modulus should be written when complex numbers are enabled.
 
void set_unique_ids_from_maps (bool val)
 If true, this flag enforces the following behaviors:
 
void write_added_sides (bool val)
 By default, we only write out the elements physically stored in the mesh.
 
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.
 
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.
 
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.
 
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.
 
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.
 
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.
 
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.
 
void write_element_data (const EquationSystems &es)
 Write out element solution.
 
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.
 
virtual void write_nodal_data (const std::string &, const std::vector< Number > &, const std::vector< std::string > &) override
 Write out a nodal solution.
 
void write_nodal_data_discontinuous (const std::string &, const std::vector< Number > &, const std::vector< std::string > &) override
 Write out a discontinuous nodal solution.
 
void write_global_data (const std::vector< Number > &, const std::vector< std::string > &)
 Write out global variables.
 
void write_information_records (const std::vector< std::string > &)
 Write out information records.
 
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.
 
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.
 
void write_elemsets ()
 Write elemsets stored on the Mesh to file.
 
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.
 
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.
 
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).
 
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.
 
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.
 
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).
 
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.
 
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.
 
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).
 
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.
 
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.
 
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().
 
void write_as_dimension (unsigned dim)
 Directly control the num_dim which is written to the Exodus file.
 
void set_coordinate_offset (Point p)
 Allows you to set a vector that is added to the coordinates of all of the nodes.
 
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.
 
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.
 
const std::vector< std::string > & get_elem_var_names ()
 Return list of the elemental variable names.
 
const std::vector< std::string > & get_nodal_var_names ()
 Return list of the nodal variable names.
 
const std::vector< std::string > & get_global_var_names ()
 Return list of the global variable names.
 
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.
 
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.
 
ExodusII_IO_Helperget_exio_helper ()
 Return a reference to the ExodusII_IO_Helper object.
 
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.
 
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.
 
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.
 
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.
 
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.
 
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.
 
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.
 
unsigned intascii_precision ()
 Return/set the precision to use when writing ASCII files.
 
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.
 
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.
 
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.
 
const bool _is_parallel_format
 Flag specifying whether this format is parallel-capable.
 
const bool _serial_only_needed_on_proc_0
 Flag specifying whether this format can be written by only serializing the mesh to processor zero.
 
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.
 
int _timestep
 Stores the current value of the timestep when calling ExodusII_IO::write_timestep().
 
bool _verbose
 should we be verbose?
 
bool _append
 Default false.
 
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.
 
std::vector< std::string > _output_variables
 The names of the variables to be output.
 
bool _allow_empty_variables
 Flag which controls the behavior of _output_variables: .) If true, _output_variables is allowed to remain empty.
 
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).
 
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.
 
bool _disc_bex
 Set to true (false is the default) to generate independent nodes for every Bezier Extraction element.
 
MeshBase_obj
 A pointer to a non-const object object.
 
const bool _is_parallel_format
 Flag specifying whether this format is parallel-capable.
 
unsigned int _ascii_precision
 Precision to use when writing ASCII files.
 

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 146 of file exodusII_io.C.

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
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}
std::unique_ptr< ExodusII_IO_Helper > exio_helper
Only attempt to instantiate an ExodusII helper class if the Exodus API is defined.
bool _set_unique_ids_from_maps
Set Elem/Node unique_ids based on the elem_num_map and node_num_map contents during reading,...
int _timestep
Stores the current value of the timestep when calling ExodusII_IO::write_timestep().
bool _verbose
should we be verbose?
bool _write_complex_abs
By default, when complex numbers are enabled, for each variable we write out three values: the real p...
bool _disc_bex
Set to true (false is the default) to generate independent nodes for every Bezier Extraction element.
bool _append
Default false.
bool _allow_empty_variables
Flag which controls the behavior of _output_variables: .) If true, _output_variables is allowed to re...
This class defines an abstract interface for Mesh input.
Definition mesh_input.h:49
An object whose state is distributed along a set of processors.
void libmesh_ignore(const Args &...)
template class LIBMESH_EXPORT MeshOutput< MeshBase >

References libMesh::libmesh_ignore().

◆ 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 170 of file exodusII_io.C.

171 :
174 /* is_parallel_format = */ false,
175 /* serial_only_needed_on_proc_0 = */ true),
177#ifdef LIBMESH_HAVE_EXODUS_API
178 exio_helper(std::make_unique<ExodusII_IO_Helper>(*this, false, true, single_precision)),
179 _timestep(1),
180 _verbose(false),
181 _append(false),
182#endif
184 _write_complex_abs(true),
186 _disc_bex(false)
187{
188 // if !LIBMESH_HAVE_EXODUS_API, we didn't use this
189 libmesh_ignore(single_precision);
190}

References libMesh::libmesh_ignore().

◆ 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 264 of file exodusII_io.C.

265{
266 exio_helper->close();
267}

References exio_helper.

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 1121 of file exodusII_io.C.

1122{
1123 _append = val;
1124}

References _append.

Referenced by main().

◆ 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 160 of file mesh_output.h.

270{
271 return _ascii_precision;
272}
unsigned int _ascii_precision
Precision to use when writing ASCII files.

◆ 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.

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

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::ExactSolution::_compute_error(), libMesh::UniformRefinementEstimator::_estimate_error(), libMesh::Partitioner::_find_global_index_by_pid_map(), libMesh::BoundaryInfo::_find_id_maps(), libMesh::PetscLinearSolver< T >::_petsc_shell_matrix_get_diagonal(), libMesh::SlepcEigenSolver< T >::_petsc_shell_matrix_get_diagonal(), libMesh::PetscLinearSolver< T >::_petsc_shell_matrix_mult(), libMesh::SlepcEigenSolver< T >::_petsc_shell_matrix_mult(), libMesh::PetscLinearSolver< T >::_petsc_shell_matrix_mult_add(), 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::System::add_matrix(), libMesh::System::add_matrix(), libMesh::RBConstruction::add_scaled_matrix_and_vector(), libMesh::System::add_vector(), libMesh::MeshTools::Modification::all_tri(), libMesh::LaplaceMeshSmoother::allgather_graph(), libMesh::DofMap::allgather_recursive_constraints(), libMesh::RBConstruction::allocate_data_structures(), libMesh::TransientRBConstruction::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::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::computeJacobian(), libMesh::Problem_Interface::computePreconditioner(), PetscSolverConfiguration::configure_solver(), 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::MeshBase::detect_interior_parents(), 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::AdjointRefinementEstimator::estimate_error(), libMesh::ExactErrorEstimator::estimate_error(), libMesh::JumpErrorEstimator::estimate_error(), libMesh::PatchRecoveryErrorEstimator::estimate_error(), libMesh::WeightedPatchRecoveryErrorEstimator::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::MeshBase::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::RBEIMConstruction::get_random_point(), libMesh::RBEIMConstruction::get_random_point(), libMesh::MeshTetInterface::improve_hull_integrity(), AssembleOptimization::inequality_constraints(), AssembleOptimization::inequality_constraints_jacobian(), libMesh::StaticCondensation::init(), libMesh::TimeSolver::init(), libMesh::SystemSubsetBySubdomain::init(), libMesh::LocationMap< T >::init(), libMesh::PetscDMWrapper::init_and_attach_petscdm(), libMesh::PetscDMWrapper::init_and_attach_petscdm(), ElasticitySystem::init_data(), 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::Modification::interpolate_surface(), 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_snes_mffd_interface(), libMesh::libmesh_petsc_snes_postcheck(), 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::MeshCommunication::make_elems_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::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< T >::operator=(), libMesh::MeshBase::operator==(), libMesh::DistributedMesh::parallel_max_elem_id(), libMesh::DistributedMesh::parallel_max_node_id(), libMesh::DistributedMesh::parallel_max_unique_id(), libMesh::ReplicatedMesh::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(), LaplaceSystem::postprocess(), PoissonSystem::postprocess(), 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(), libMesh::XdrIO::read(), libMesh::Nemesis_IO::read(), FEMParameters::read(), libMesh::EquationSystems::read(), libMesh::CheckpointIO::read_header(), read_header(), libMesh::System::read_header(), libMesh::XdrIO::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::RBConstruction::read_riesz_representors_from_files(), libMesh::TransientRBConstruction::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::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::NoxNonlinearSolver< Number >::solve(), 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(), MeshfunctionDFEM::test_mesh_function_dfem(), MeshfunctionDFEM::test_mesh_function_dfem_grad(), MeshFunctionTest::test_p_level(), ExodusC0PolyhedronTest::test_write_and_read_hexagonal_prism(), ExodusC0PolygonTest::test_write_and_read_pentagon(), DofMapTest::testBadElemFECombo(), SystemsTest::testBlockRestrictedVarNDofs(), BoundaryInfoTest::testBoundaryOnChildrenErrors(), CheckpointIOTest::testC0PolygonCheckpoint(), VolumeTest::testC0PolygonMethods(), CheckpointIOTest::testC0PolyhedronCheckpoint(), VolumeTest::testC0PolyhedronMethods(), ConstraintOperatorTest::testCoreform(), ConnectedComponentsTest::testEdge(), MeshInputTest::testExodusIGASidesets(), MeshTriangulationTest::testFoundCenters(), PointLocatorTest::testLocator(), BoundaryInfoTest::testMesh(), BoundaryMeshSubdomainTest::testPerBoundarySubdomain(), PointLocatorTest::testPlanar(), MeshTriangulationTest::testPoly2TriEdge3ToTri7CenterFixup(), MeshTriangulationTest::testPoly2TriRefinementBase(), SystemsTest::testProjectCubeWithMeshFunction(), SystemsTest::testProjectScalarCoarsening(), BoundaryInfoTest::testRenumber(), BoundaryInfoTest::testSelectiveRenumber(), BoundaryMeshSubdomainTest::testSingleSubdomain(), CheckpointIOTest::testSplitter(), MeshInputTest::testTetgenIO(), MeshTriangulationTest::testTriangulatorInterp(), MeshTriangulationTest::testTriangulatorMeshedHoles(), MeshTriangulationTest::testTriangulatorRoundHole(), MeshSmootherTest::testVariationalSmoother(), libMesh::MeshTools::total_weight(), libMesh::RBConstruction::train_reduced_basis_with_POD(), libMesh::MeshfreeSolutionTransfer::transfer(), libMesh::MeshFunctionSolutionTransfer::transfer(), libMesh::Poly2TriTriangulator::triangulate(), libMesh::RBConstruction::truth_assembly(), libMesh::TransientRBConstruction::truth_assembly(), update_current_local_solution(), libMesh::TransientRBConstruction::update_RB_initial_condition_all_N(), libMesh::RBConstruction::update_RB_system_matrices(), libMesh::TransientRBConstruction::update_RB_system_matrices(), libMesh::TransientRBConstruction::update_residual_terms(), libMesh::RBConstruction::update_residual_terms(), libMesh::MeshTools::volume(), libMesh::STLIO::write(), libMesh::XdrIO::write(), libMesh::NameBasedIO::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::RBConstruction::write_riesz_representors_to_files(), libMesh::TransientRBConstruction::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().

◆ 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 1273 of file exodusII_io.C.

1277{
1278 LOG_SCOPE("copy_elemental_solution()", "ExodusII_IO");
1279
1280 const unsigned int var_num = system.variable_number(system_var_name);
1281 // Assert that variable is an elemental data variable.
1282 //
1283 // NOTE: Currently, this reader is capable of reading only individual components of vector types,
1284 // and each must be written out to its own scalar elemental data variable.
1285 const auto & var_type = system.variable_type(var_num);
1286 libmesh_error_msg_if(!EquationSystems::is_elemental_data_fe_type(var_type),
1287 "Error! Trying to copy elemental solution into a variable that is not elemental data.");
1288
1290 const DofMap & dof_map = system.get_dof_map();
1291
1292 libmesh_error_msg_if(mesh.allow_renumbering(),
1293 "ERROR, elemental data cannot be loaded if the mesh may be renumbered!");
1294
1295 // Map from element ID to elemental variable value. We need to use
1296 // a map here rather than a vector (e.g. elem_var_values) since the
1297 // libmesh element numbering can contain "holes". This is the case
1298 // if we are reading elemental var values from an adaptively refined
1299 // mesh that has not been sequentially renumbered.
1300 std::map<dof_id_type, Real> elem_var_value_map;
1301
1302 // With Exodus files we only open them on processor 0, so that's the
1303 // where we have to do the data read too.
1304 if (system.comm().rank() == 0)
1305 {
1306 libmesh_error_msg_if(!exio_helper->opened_for_reading,
1307 "ERROR, ExodusII file must be opened for reading before copying an elemental solution!");
1308
1309 exio_helper->read_elemental_var_values(exodus_var_name, timestep, elem_var_value_map);
1310 }
1311
1312 const bool serial_on_zero = mesh.is_serial_on_zero();
1313
1314 // If our mesh isn't serial, then non-root processors need to
1315 // request the data for their parts of the mesh and insert it
1316 // themselves.
1317 if (!serial_on_zero)
1318 {
1319 std::unordered_map<processor_id_type, std::vector<dof_id_type>> elem_ids_to_request;
1320 if (this->processor_id() != 0)
1321 {
1322 std::vector<dof_id_type> elem_ids;
1323 for (auto & elem : mesh.active_local_element_ptr_range())
1324 elem_ids.push_back(elem->id());
1325
1326 if (!elem_ids.empty())
1327 elem_ids_to_request[0] = std::move(elem_ids);
1328 }
1329
1330 auto value_gather_functor =
1331 [& elem_var_value_map]
1333 const std::vector<dof_id_type> & ids,
1334 std::vector<Real> & values)
1335 {
1336 const std::size_t query_size = ids.size();
1337 values.resize(query_size);
1338 for (std::size_t i=0; i != query_size; ++i)
1339 {
1340 if (const auto it = elem_var_value_map.find(ids[i]);
1341 it != elem_var_value_map.end())
1342 {
1343 values[i] = it->second;
1344 elem_var_value_map.erase(it);
1345 }
1346 else
1347 values[i] = std::numeric_limits<Real>::quiet_NaN();
1348 }
1349 };
1350
1351 auto value_action_functor =
1352 [& elem_var_value_map]
1354 const std::vector<dof_id_type> & ids,
1355 const std::vector<Real> & values)
1356 {
1357 const std::size_t query_size = ids.size();
1358 for (std::size_t i=0; i != query_size; ++i)
1359 if (!libmesh_isnan(values[i]))
1360 elem_var_value_map[ids[i]] = values[i];
1361 };
1362
1363 Real * value_ex = nullptr;
1365 (system.comm(), elem_ids_to_request, value_gather_functor,
1366 value_action_functor, value_ex);
1367 }
1368
1369 std::map<dof_id_type, Real>::iterator
1370 it = elem_var_value_map.begin(),
1371 end = elem_var_value_map.end();
1372
1373 // Everybody inserts the data they've received. If we're
1374 // serial_on_zero then proc 0 inserts everybody's data and other
1375 // procs have empty map ranges.
1376 for (; it!=end; ++it)
1377 {
1378 const Elem * elem = mesh.query_elem_ptr(it->first);
1379
1380 if (elem && elem->n_comp(system.number(), var_num) > 0)
1381 {
1382 dof_id_type dof_index = elem->dof_number(system.number(), var_num, 0);
1383 if (serial_on_zero || dof_map.local_index(dof_index ))
1384 system.solution->set (dof_index, it->second);
1385 }
1386 }
1387
1388 system.solution->close();
1389 system.update();
1390}
processor_id_type rank() const
This class handles the numbering of degrees of freedom on a mesh.
Definition dof_map.h:181
bool local_index(dof_id_type dof_index) const
Definition dof_map.h:967
unsigned int n_comp(const unsigned int s, const unsigned int var) const
Definition dof_object.h:978
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
This is the base class from which all geometric element types are derived.
Definition elem.h:96
static bool is_elemental_data_fe_type(const FEType &type)
This is the MeshBase class.
Definition mesh_base.h:81
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:1355
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0
virtual bool is_serial_on_zero() const
Definition mesh_base.h:364
processor_id_type processor_id() const
const Parallel::Communicator & comm() const
const FEType & variable_type(const unsigned int i) const
Definition system.C:2721
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition system.h:1655
virtual void update()
Update the local values to reflect the solution on neighboring processors.
Definition system.C:498
unsigned int variable_number(std::string_view var) const
Definition system.C:1398
const DofMap & get_dof_map() const
Definition system.h:2417
unsigned int number() const
Definition system.h:2393
void pull_parallel_vector_data(const Communicator &comm, const MapToVectors &queries, GatherFunctor &gather_data, const ActionFunctor &act_on_data, const datum *example)
uint8_t dof_id_type
Definition id_types.h:67
bool libmesh_isnan(T x)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
uint8_t processor_id_type
Definition id_types.h:104

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

Referenced by MeshInputTest::testExodusWriteElementDataFromDiscontinuousNodalData().

◆ 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 1166 of file exodusII_io.C.

1170{
1171 LOG_SCOPE("copy_nodal_solution()", "ExodusII_IO");
1172
1173 const unsigned int var_num = system.variable_number(system_var_name);
1174
1176
1177 libmesh_error_msg_if(mesh.allow_renumbering(),
1178 "ERROR, nodal data cannot be loaded if the mesh may be renumbered!");
1179
1180 // With Exodus files we only open them on processor 0, so that's the
1181 // where we have to do the data read too.
1182 if (system.comm().rank() == 0)
1183 {
1184 libmesh_error_msg_if(!exio_helper->opened_for_reading,
1185 "ERROR, ExodusII file must be opened for reading before copying a nodal solution!");
1186
1187 exio_helper->read_nodal_var_values(exodus_var_name, timestep);
1188 }
1189
1190 auto & node_var_value_map = exio_helper->nodal_var_values;
1191
1192 const bool serial_on_zero = mesh.is_serial_on_zero();
1193
1194 // If our mesh isn't serial, then non-root processors need to
1195 // request the data for their parts of the mesh and insert it
1196 // themselves.
1197 if (!serial_on_zero)
1198 {
1199 std::unordered_map<processor_id_type, std::vector<dof_id_type>> node_ids_to_request;
1200 if (this->processor_id() != 0)
1201 {
1202 std::vector<dof_id_type> node_ids;
1203 for (auto & node : mesh.local_node_ptr_range())
1204 node_ids.push_back(node->id());
1205 if (!node_ids.empty())
1206 node_ids_to_request[0] = std::move(node_ids);
1207 }
1208
1209 auto value_gather_functor =
1210 [& node_var_value_map]
1212 const std::vector<dof_id_type> & ids,
1213 std::vector<Real> & values)
1214 {
1215 const std::size_t query_size = ids.size();
1216 values.resize(query_size);
1217 for (std::size_t i=0; i != query_size; ++i)
1218 {
1219 if (const auto it = node_var_value_map.find(ids[i]);
1220 it != node_var_value_map.end())
1221 {
1222 values[i] = it->second;
1223 node_var_value_map.erase(it);
1224 }
1225 else
1226 values[i] = std::numeric_limits<Real>::quiet_NaN();
1227 }
1228 };
1229
1230 auto value_action_functor =
1231 [& node_var_value_map]
1233 const std::vector<dof_id_type> & ids,
1234 const std::vector<Real> & values)
1235 {
1236 const std::size_t query_size = ids.size();
1237 for (std::size_t i=0; i != query_size; ++i)
1238 if (!libmesh_isnan(values[i]))
1239 node_var_value_map[ids[i]] = values[i];
1240 };
1241
1242 Real * value_ex = nullptr;
1244 (system.comm(), node_ids_to_request, value_gather_functor,
1245 value_action_functor, value_ex);
1246 }
1247
1248 // Everybody inserts the data they've received. If we're
1249 // serial_on_zero then proc 0 inserts everybody's data and other
1250 // procs have empty map ranges.
1251 for (auto p : exio_helper->nodal_var_values)
1252 {
1253 dof_id_type i = p.first;
1254 const Node * node = MeshInput<MeshBase>::mesh().query_node_ptr(i);
1255
1256 if (node &&
1257 (serial_on_zero || node->processor_id() == system.processor_id()) &&
1258 node->n_comp(system.number(), var_num) > 0)
1259 {
1260 dof_id_type dof_index = node->dof_number(system.number(), var_num, 0);
1261
1262 // If the dof_index is local to this processor, set the value
1263 system.solution->set (dof_index, p.second);
1264 }
1265 }
1266
1267 system.solution->close();
1268 system.update();
1269}
processor_id_type processor_id() const
Definition dof_object.h:881
A Node is like a Point, but with more information.
Definition node.h:55

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::DofObject::processor_id(), libMesh::ParallelObject::processor_id(), TIMPI::pull_parallel_vector_data(), libMesh::Parallel::Communicator::rank(), libMesh::Real, libMesh::System::solution, libMesh::System::update(), and libMesh::System::variable_number().

Referenced by WriteVecAndScalar::testWriteExodus().

◆ 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 1392 of file exodusII_io.C.

1396{
1397 LOG_SCOPE("copy_scalar_solution()", "ExodusII_IO");
1398
1399 libmesh_error_msg_if(!exio_helper->opened_for_reading,
1400 "ERROR, ExodusII file must be opened for reading before copying a scalar solution!");
1401
1402 libmesh_error_msg_if(system_var_names.size() != exodus_var_names.size(),
1403 "ERROR, the number of system_var_names must match exodus_var_names.");
1404
1405 std::vector<Real> values_from_exodus;
1406 read_global_variable(exodus_var_names, timestep, values_from_exodus);
1407
1408#ifdef LIBMESH_HAVE_MPI
1409 if (this->n_processors() > 1)
1410 {
1411 const Parallel::MessageTag tag = this->comm().get_unique_tag(1);
1412 if (this->processor_id() == this->n_processors()-1)
1413 this->comm().receive(0, values_from_exodus, tag);
1414 if (this->processor_id() == 0)
1415 this->comm().send(this->n_processors()-1, values_from_exodus, tag);
1416 }
1417#endif
1418
1419 if (system.processor_id() == (system.n_processors()-1))
1420 {
1421 const DofMap & dof_map = system.get_dof_map();
1422
1423 for (auto i : index_range(system_var_names))
1424 {
1425 const unsigned int var_num = system.variable_scalar_number(system_var_names[i], 0);
1426
1427 std::vector<dof_id_type> SCALAR_dofs;
1428 dof_map.SCALAR_dof_indices(SCALAR_dofs, var_num);
1429
1430 system.solution->set (SCALAR_dofs[0], values_from_exodus[i]);
1431 }
1432 }
1433
1434 system.solution->close();
1435 system.update();
1436}
MessageTag get_unique_tag(int tagvalue=MessageTag::invalid_tag) const
Status receive(const unsigned int dest_processor_id, T &buf, const MessageTag &tag=any_tag) const
void send(const unsigned int dest_processor_id, const T &buf, const MessageTag &tag=no_tag) 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
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 ...
processor_id_type n_processors() const
unsigned int variable_scalar_number(std::string_view var, unsigned int component) const
Definition system.h:2474
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

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

◆ 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 1135 of file exodusII_io.C.

1136{
1137 return exio_helper->get_add_sides();
1138}

References exio_helper.

Referenced by write_discontinuous_exodusII(), and write_nodal_data_discontinuous().

◆ 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 2478 of file exodusII_io.C.

2479{
2480 // We could make this function non-const and have it call
2481 // exio_helper->read_elem_num_map() before returning a reference...
2482 // but the intention is that this will be called some time after a
2483 // mesh is read in, in which case it would be doing extra work to
2484 // read in the elem_num_map twice.
2485 return exio_helper->elem_num_map;
2486}

References exio_helper.

Referenced by ExtraIntegersTest::testExtraIntegersExodusReading().

◆ 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 2466 of file exodusII_io.C.

2467{
2469 return exio_helper->elem_var_names;
2470}

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

◆ 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 2267 of file exodusII_io.C.

2268{
2269 libmesh_error_msg_if(!exio_helper->opened_for_reading,
2270 "ERROR, ExodusII file must be opened for reading "
2271 "before calling ExodusII_IO::get_elemset_data_indices()!");
2272
2273 exio_helper->get_elemset_data_indices(elemset_array_indices);
2274}

References exio_helper.

◆ get_exio_helper()

ExodusII_IO_Helper & libMesh::ExodusII_IO::get_exio_helper ( )

Return a reference to the ExodusII_IO_Helper object.

Definition at line 2493 of file exodusII_io.C.

2494{
2495 // Provide a warning when accessing the helper object
2496 // since it is a non-public API and is likely to see
2497 // future API changes
2498 libmesh_experimental();
2499
2500 return *exio_helper;
2501}

References exio_helper.

◆ 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 194 of file exodusII_io.C.

195{
196#ifdef LIBMESH_HAVE_EXODUS_API
198#else
199 return 0;
200#endif
201}

References libMesh::ExodusII_IO_Helper::get_exodus_version().

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

◆ 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 2472 of file exodusII_io.C.

2473{
2474 exio_helper->read_var_names(ExodusII_IO_Helper::GLOBAL);
2475 return exio_helper->global_var_names;
2476}

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

◆ 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 2460 of file exodusII_io.C.

2461{
2462 exio_helper->read_var_names(ExodusII_IO_Helper::NODAL);
2463 return exio_helper->nodal_var_names;
2464}

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

Referenced by WriteVecAndScalar::testWriteExodus().

◆ 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 2488 of file exodusII_io.C.

2489{
2490 return exio_helper->node_num_map;
2491}

References exio_helper.

Referenced by ExtraIntegersTest::testExtraIntegersExodusReading().

◆ 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 2196 of file exodusII_io.C.

2198{
2199 libmesh_error_msg_if(!exio_helper->opened_for_reading,
2200 "ERROR, ExodusII file must be opened for reading "
2201 "before calling ExodusII_IO::get_nodeset_data_indices()!");
2202
2203 exio_helper->get_nodeset_data_indices(bc_array_indices);
2204}

References exio_helper.

◆ 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 1155 of file exodusII_io.C.

1156{
1157 libmesh_error_msg_if(!exio_helper->opened_for_reading && !exio_helper->opened_for_writing,
1158 "ERROR, ExodusII file must be opened for reading or writing before calling ExodusII_IO::get_num_time_steps()!");
1159
1160 exio_helper->read_num_time_steps();
1161 return exio_helper->num_time_steps;
1162}

References exio_helper.

◆ 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 2183 of file exodusII_io.C.

2186{
2187 libmesh_error_msg_if(!exio_helper->opened_for_reading,
2188 "ERROR, ExodusII file must be opened for reading "
2189 "before calling ExodusII_IO::get_sideset_data_indices()!");
2190
2192 exio_helper->get_sideset_data_indices(mesh, bc_array_indices);
2193}
const MT & mesh() const

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

◆ 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 1143 of file exodusII_io.C.

1144{
1145 libmesh_error_msg_if
1146 (!exio_helper->opened_for_reading,
1147 "ERROR, ExodusII file must be opened for reading before calling ExodusII_IO::get_time_steps()!");
1148
1149 exio_helper->read_time_steps();
1150 return exio_helper->time_steps;
1151}

References exio_helper.

◆ 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.

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 94 of file mesh_input.h.

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
Returns
The object as a read-only reference.

Definition at line 168 of file mesh_output.h.

260{
261 libmesh_assert(_obj);
262 return *_obj;
263}
const MeshBase *const _obj
A pointer to a constant object.
libmesh_assert(ctx)

◆ 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.

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 }
processor_id_type size() const

References libMesh::ParallelObject::_communicator, libMesh::libmesh_assert(), and libMesh::Parallel::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::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(), copy_scalar_solution(), libMesh::Nemesis_IO::copy_scalar_solution(), libMesh::UnstructuredMesh::create_pid_mesh(), libMesh::MeshTools::create_processor_bounding_box(), 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::ExodusII_IO_Helper::initialize(), libMesh::Nemesis_IO_Helper::initialize(), libMesh::DistributedMesh::insert_elem(), libMesh::NumericVector< T >::is_effectively_ghosted(), libMesh::NumericVector< T >::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::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::MeshBase::partition(), libMesh::Partitioner::partition(), libMesh::Partitioner::partition_unpartitioned_elements(), libMesh::Partitioner::partition_unpartitioned_elements(), libMesh::MeshBase::print_constraint_rows(), libMesh::DofMap::print_dof_constraints(), libMesh::Nemesis_IO::read(), libMesh::CheckpointIO::read(), libMesh::NameBasedIO::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::DistributedMesh::update_parallel_id_counts(), libMesh::GMVIO::write_binary(), libMesh::GMVIO::write_discontinuous_gmv(), libMesh::ExodusII_IO_Helper::write_nodal_coordinates(), write_nodal_data(), libMesh::VTKIO::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().

◆ 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.

115 { return cast_int<processor_id_type>(_communicator.rank()); }

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

Referenced by libMesh::BoundaryInfo::_find_id_maps(), libMesh::PetscDMWrapper::add_dofs_to_section(), libMesh::DistributedMesh::add_elem(), libMesh::BoundaryInfo::add_elements(), libMesh::DistributedMesh::add_node(), libMesh::MeshTools::Modification::all_tri(), 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(), copy_scalar_solution(), libMesh::Nemesis_IO::copy_scalar_solution(), libMesh::MeshTools::correct_node_proc_ids(), libMesh::ExodusII_IO_Helper::create(), libMesh::MeshCommunication::delete_remote_elements(), libMesh::DistributedMesh::DistributedMesh(), 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::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::MeshTools::Modification::interpolate_surface(), libMesh::SparsityPattern::Build::join(), libMesh::RBEvaluation::legacy_write_offline_data_to_files(), libMesh::RBSCMEvaluation::legacy_write_offline_data_to_files(), libMesh::TransientRBEvaluation::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(), main(), 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::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::XdrIO::read(), libMesh::Nemesis_IO::read(), libMesh::CheckpointIO::read(), libMesh::NameBasedIO::read(), libMesh::EquationSystems::read(), libMesh::EquationSystems::read(), libMesh::ExodusII_IO_Helper::read_elem_num_map(), libMesh::ExodusII_IO_Helper::read_global_values(), libMesh::CheckpointIO::read_header(), read_header(), libMesh::System::read_header(), libMesh::XdrIO::read_header(), libMesh::DynaIO::read_mesh(), libMesh::ExodusII_IO_Helper::read_node_num_map(), libMesh::System::read_parallel_data(), libMesh::RBConstruction::read_riesz_representors_from_files(), libMesh::TransientRBConstruction::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::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(), ExodusC0PolyhedronTest::test_write_and_read_hexagonal_prism(), ExodusC0PolygonTest::test_write_and_read_pentagon(), 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(), BoundaryMeshSubdomainTest::testPerBoundarySubdomain(), SystemsTest::testProjectMatrix3D(), BoundaryInfoTest::testShellFaceConstraints(), MeshInputTest::testSingleElementImpl(), BoundaryMeshSubdomainTest::testSingleSubdomain(), WriteVecAndScalar::testSolution(), CheckpointIOTest::testSplitter(), MeshInputTest::testTetgenIO(), MeshSmootherTest::testVariationalSmoother(), libMesh::MeshTools::total_weight(), libMesh::NetGenMeshInterface::triangulate(), libMesh::Parallel::Packing< Elem * >::unpack(), libMesh::Parallel::Packing< Node * >::unpack(), libMesh::DistributedMesh::update_parallel_id_counts(), libMesh::DTKAdapter::update_variable_values(), libMesh::MeshTools::volume(), libMesh::STLIO::write(), libMesh::XdrIO::write(), libMesh::NameBasedIO::write(), libMesh::CheckpointIO::write(), libMesh::EquationSystems::write(), libMesh::EquationSystems::write(), libMesh::GMVIO::write_discontinuous_gmv(), write_element_data(), write_element_data_from_discontinuous_nodal_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(), write_nodal_data(), libMesh::VTKIO::write_nodal_data(), libMesh::UCDIO::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::ExodusII_IO_Helper::write_nodesets(), libMesh::Nemesis_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::ExodusII_IO_Helper::write_sidesets(), libMesh::Nemesis_IO_Helper::write_sidesets(), write_timestep(), libMesh::ExodusII_IO_Helper::write_timestep(), and write_timestep_discontinuous().

◆ 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 270 of file exodusII_io.C.

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

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(), 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::C0POLYGON, libMesh::C0POLYHEDRON, 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(), libMesh::DofObject::invalid_id, libMesh::ExodusII_IO_Helper::Conversion::invalid_id, libMesh::libmesh_assert(), libMesh::make_range(), libMesh::MeshInput< MeshBase >::mesh(), libMesh::MeshInput< MT >::mesh(), libMesh::MeshBase::mesh_dimension(), libMesh::MeshBase::n_elemsets(), libMesh::Elem::n_nodes(), libMesh::MeshBase::n_nodes(), n_nodes, libMesh::Elem::n_sides(), 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::MeshBase::set_subdomain_name(), libMesh::BoundaryInfo::sideset_name(), and libMesh::Elem::type().

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

◆ 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 1438 of file exodusII_io.C.

1441{
1442 LOG_SCOPE("read_elemental_variable()", "ExodusII_IO");
1443
1444 // Note that this function MUST be called before renumbering
1445 std::map<dof_id_type, Real> elem_var_value_map;
1446
1447 exio_helper->read_elemental_var_values(elemental_var_name, timestep, elem_var_value_map);
1448 for (auto & pr : elem_var_value_map)
1449 {
1450 const Elem * elem = MeshInput<MeshBase>::mesh().query_elem_ptr(pr.first);
1451 unique_id_to_value_map.emplace(elem->top_parent()->unique_id(), pr.second);
1452 }
1453}
unique_id_type unique_id() const
Definition dof_object.h:835
const Elem * top_parent() const
Definition elem.h:3073

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

◆ 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 2253 of file exodusII_io.C.

2258{
2259 libmesh_error_msg_if(!exio_helper->opened_for_reading,
2260 "ERROR, ExodusII file must be opened for reading "
2261 "before calling ExodusII_IO::read_elemset_data()!");
2262
2263 exio_helper->read_elemset_data(timestep, var_names, elemset_ids_in, elemset_vals);
2264}

References exio_helper.

◆ 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 1455 of file exodusII_io.C.

1458{
1459 LOG_SCOPE("read_global_variable()", "ExodusII_IO");
1460
1461 std::size_t size = global_var_names.size();
1462 libmesh_error_msg_if(size == 0, "ERROR, empty list of global variables to read from the Exodus file.");
1463
1464 // read the values for all global variables
1465 std::vector<Real> values_from_exodus;
1466 exio_helper->read_var_names(ExodusII_IO_Helper::GLOBAL);
1467 exio_helper->read_global_values(values_from_exodus, timestep);
1468 std::vector<std::string> global_var_names_exodus = exio_helper->global_var_names;
1469
1470 if (values_from_exodus.size() == 0)
1471 return; // This will happen in parallel on procs that are not 0
1472
1473 global_values.clear();
1474 for (std::size_t i = 0; i != size; ++i)
1475 {
1476 // for each global variable in global_var_names, look the corresponding one in global_var_names_from_exodus
1477 // and fill global_values accordingly
1478 auto it = find(global_var_names_exodus.begin(), global_var_names_exodus.end(), global_var_names[i]);
1479 if (it != global_var_names_exodus.end())
1480 global_values.push_back(values_from_exodus[it - global_var_names_exodus.begin()]);
1481 else
1482 libmesh_error_msg("ERROR, Global variable " << global_var_names[i] << \
1483 " not found in Exodus file.");
1484 }
1485
1486}

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

Referenced by copy_scalar_solution().

◆ 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 1038 of file exodusII_io.C.

1039{
1040 // We will need the Communicator of the Mesh we were created with.
1042
1043 // Eventual return value
1044 ExodusHeaderInfo header_info;
1045
1046 // File I/O is done on processor 0, then broadcast to other procs
1047 if (mesh.processor_id() == 0)
1048 {
1049 // Open the exodus file in EX_READ mode
1050 exio_helper->open(fname.c_str(), /*read_only=*/true);
1051
1052 // Get header information from exodus file without updating the
1053 // Helper object's internal data structures.
1054 header_info = exio_helper->read_header();
1055
1056 // Close the file, we are now done with it. The goal is to keep the
1057 // exio_helper object unchanged while calling this function,
1058 // although it can't quite be marked "const" because we do have to
1059 // actually open/close the file. This way, it should be possible to
1060 // use the same ExodusII_IO object to read the headers of multiple
1061 // different mesh files.
1062 exio_helper->close();
1063 }
1064
1065 // Broadcast header_info to other procs before returning
1066 header_info.broadcast(mesh.comm());
1067
1068 // Return the information we read back to the user.
1069 return header_info;
1070}
This class is used as both an external data structure for passing around Exodus file header informati...
void broadcast(const Parallel::Communicator &comm)
Broadcasts data from processor 0 to other procs using the provided Communicator.

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(), and ExodusC0PolyhedronTest::write_and_read_header().

◆ 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 2223 of file exodusII_io.C.

2228{
2229 libmesh_error_msg_if(!exio_helper->opened_for_reading,
2230 "ERROR, ExodusII file must be opened for reading "
2231 "before calling ExodusII_IO::read_nodeset_data()!");
2232
2233 exio_helper->read_nodeset_data(timestep, var_names, node_boundary_ids, bc_vals);
2234}

References exio_helper.

◆ 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 2166 of file exodusII_io.C.

2171{
2172 libmesh_error_msg_if(!exio_helper->opened_for_reading,
2173 "ERROR, ExodusII file must be opened for reading "
2174 "before calling ExodusII_IO::read_sideset_data()!");
2175
2177 exio_helper->read_sideset_data(mesh, timestep, var_names, side_ids, bc_vals);
2178}

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

◆ 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 1113 of file exodusII_io.C.

1114{
1115 libmesh_warning("This method may be deprecated in the future");
1116 exio_helper->set_coordinate_offset(p);
1117}

References exio_helper.

◆ 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 2516 of file exodusII_io.C.

2517{
2518 _disc_bex = disc_bex;
2519}

References _disc_bex.

Referenced by MeshInputTest::testExodusFileMappings().

◆ 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 205 of file exodusII_io.C.

206{
207 _extra_integer_vars = extra_integer_vars;
208}

References _extra_integer_vars.

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

◆ 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 2504 of file exodusII_io.C.

2505{
2506 exio_helper->set_hdf5_writing(write_hdf5);
2507}

References exio_helper.

◆ 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 2510 of file exodusII_io.C.

2511{
2512 exio_helper->set_max_name_length(max_length);
2513}

References exio_helper.

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

◆ 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.

101{ this->mesh().set_n_partitions() = n_parts; }
MeshBase & mesh

◆ 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 210 of file exodusII_io.C.

212{
213 _output_variables = output_variables;
214 _allow_empty_variables = allow_empty;
215}
std::vector< std::string > _output_variables
The names of the variables to be output.

References _allow_empty_variables, and _output_variables.

Referenced by main().

◆ 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 1089 of file exodusII_io.C.

1090{
1092
1093 // Set this flag on the helper object as well. The helper needs to know about this
1094 // flag, since it sometimes needs to construct libmesh Node ids from nodal connectivity
1095 // arrays (see e.g. ExodusII_IO_Helper::read_edge_blocks()).
1096 exio_helper->set_unique_ids_from_maps = val;
1097}

References _set_unique_ids_from_maps, and exio_helper.

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

◆ 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 113 of file mesh_input.h.

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 1099 of file exodusII_io.C.

1100{
1101 exio_helper->use_mesh_dimension_instead_of_spatial_dimension(val);
1102}

References exio_helper.

◆ verbose()

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

Set the flag indicating if we should be verbose.

Definition at line 1074 of file exodusII_io.C.

1075{
1076 _verbose = set_verbosity;
1077
1078 // Set the verbose flag in the helper object as well.
1079 exio_helper->verbose = _verbose;
1080}

References _verbose, and exio_helper.

◆ 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 2277 of file exodusII_io.C.

2278{
2279 LOG_SCOPE("write()", "ExodusII_IO");
2280
2282
2283 // We may need to gather a DistributedMesh to output it, making that
2284 // const qualifier in our constructor a dirty lie
2285 // The "true" specifies that we only need the mesh serialized to processor 0
2286 MeshSerializer serialize
2287 (const_cast<MeshBase &>(mesh),
2289
2290 libmesh_assert( !exio_helper->opened_for_writing );
2291
2292 // If the user has set the append flag here, it doesn't really make
2293 // sense: the intent of this function is to write a Mesh with no
2294 // data, while "appending" is really intended to add data to an
2295 // existing file. If we're verbose, print a message to this effect.
2296 if (_append && _verbose)
2297 libmesh_warning("Warning: Appending in ExodusII_IO::write() does not make sense.\n"
2298 "Creating a new file instead!");
2299
2300 exio_helper->create(fname);
2301 exio_helper->initialize(fname,mesh);
2302 exio_helper->write_nodal_coordinates(mesh);
2303 exio_helper->write_elements(mesh);
2304 exio_helper->write_sidesets(mesh);
2305 exio_helper->write_nodesets(mesh);
2306 exio_helper->write_elemsets(mesh);
2307
2309 libmesh_warning("Warning: Mesh contains edge boundary IDs, but these "
2310 "are not supported by the ExodusII format.");
2311}
std::size_t n_edge_conds() const
This class defines an abstract interface for Mesh output.
Definition mesh_output.h:54
Temporarily serialize a DistributedMesh for non-distributed-mesh capable code paths.

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(), ExodusC0PolyhedronTest::test_write_and_read_hexagonal_prism(), ExodusC0PolygonTest::test_write_and_read_pentagon(), MeshInputTest::testExodusFileMappings(), MeshInputTest::testExodusIGASidesets(), libMesh::NameBasedIO::write(), and ExodusC0PolyhedronTest::write_and_read_header().

◆ 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 1128 of file exodusII_io.C.

1129{
1130 exio_helper->set_add_sides(val);
1131}

References exio_helper.

◆ 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 1106 of file exodusII_io.C.

1107{
1108 exio_helper->write_as_dimension(dim);
1109}
unsigned int dim

References dim, and exio_helper.

◆ 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 1084 of file exodusII_io.C.

1085{
1086 _write_complex_abs = val;
1087}

References _write_complex_abs.

◆ 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 101 of file mesh_output.C.

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...
OStreamProxy out

◆ 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 219 of file exodusII_io.C.

222{
223 std::vector<std::string> solution_names;
224 std::vector<Number> v;
225
226 es.build_variable_names (solution_names, nullptr, system_names);
227 es.build_discontinuous_solution_vector (v, system_names,
228 nullptr, false, /* defaults */
229 this->get_add_sides());
230 this->write_nodal_data_discontinuous(name, v, solution_names);
231}
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
void write_nodal_data_discontinuous(const std::string &, const std::vector< Number > &, const std::vector< std::string > &) override
Write out a discontinuous nodal solution.

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

Referenced by main().

◆ write_element_data()

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

Write out element solution.

Definition at line 1488 of file exodusII_io.C.

1489{
1490 LOG_SCOPE("write_element_data()", "ExodusII_IO");
1491
1492 // Be sure the file has been opened for writing!
1493 libmesh_error_msg_if(MeshOutput<MeshBase>::mesh().processor_id() == 0 && !exio_helper->opened_for_writing,
1494 "ERROR, ExodusII file must be initialized before outputting element variables.");
1495
1496 // This function currently only works on serialized meshes. We rely
1497 // on having a reference to a non-const MeshBase object from our
1498 // MeshInput parent class to construct a MeshSerializer object,
1499 // similar to what is done in ExodusII_IO::write(). Note that
1500 // calling ExodusII_IO::write_timestep() followed by
1501 // ExodusII_IO::write_element_data() when the underlying Mesh is a
1502 // DistributedMesh will result in an unnecessary additional
1503 // serialization/re-parallelization step.
1504 // The "true" specifies that we only need the mesh serialized to processor 0
1506
1507 // To be (possibly) filled with a filtered list of variable names to output.
1508 std::vector<std::string> names;
1509
1510 // If _output_variables is populated, build_elemental_solution_vector() will filter this list to
1511 // the variables that can be written as elemental data.
1512 if (_output_variables.size() > 0)
1513 names.assign(_output_variables.begin(), _output_variables.end());
1514
1515 // If we pass in a list of names to "build_elemental_solution_vector()"
1516 // it'll filter the variables coming back.
1517 std::vector<Number> soln;
1518 es.build_elemental_solution_vector(soln, names);
1519
1520 // Also, store the list of subdomains on which each variable is active
1521 std::vector<std::set<subdomain_id_type>> vars_active_subdomains;
1522 es.get_vars_active_subdomains(names, vars_active_subdomains);
1523
1524 if (soln.empty()) // If there is nothing to write just return
1525 return;
1526
1527 // The data must ultimately be written block by block. This means that this data
1528 // must be sorted appropriately.
1530 return;
1531
1533
1534#ifdef LIBMESH_USE_COMPLEX_NUMBERS
1535
1536 std::vector<std::string> complex_names =
1537 exio_helper->get_complex_names(names, _write_complex_abs);
1538
1539 std::vector<std::set<subdomain_id_type>>
1540 complex_vars_active_subdomains =
1541 exio_helper->get_complex_vars_active_subdomains(vars_active_subdomains,
1543 exio_helper->initialize_element_variables(complex_names, complex_vars_active_subdomains);
1544
1545 const std::vector<Real> complex_soln =
1546 complex_soln_components(soln, names.size(), _write_complex_abs,
1547 SolutionOrdering::variable_major,
1548 SolutionOrdering::variable_major);
1549
1550 exio_helper->write_element_values(mesh, complex_soln, _timestep, complex_vars_active_subdomains);
1551
1552#else
1553 exio_helper->initialize_element_variables(names, vars_active_subdomains);
1554 exio_helper->write_element_values(mesh, soln, _timestep, vars_active_subdomains);
1555#endif
1556}
void build_elemental_solution_vector(std::vector< Number > &soln, std::vector< std::string > &names) const
Retrieve the solution data for elemental data variables.
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.

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

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

◆ 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 1561 of file exodusII_io.C.

1565{
1566 LOG_SCOPE("write_element_data_from_discontinuous_nodal_data()", "ExodusII_IO");
1567
1568 // Be sure that some other function has already opened the file and prepared it
1569 // for writing. This is the same behavior as the write_element_data() function
1570 // which we are trying to mimic.
1571 libmesh_error_msg_if(MeshOutput<MeshBase>::mesh().processor_id() == 0 && !exio_helper->opened_for_writing,
1572 "ERROR, ExodusII file must be initialized before outputting element variables.");
1573
1574 // This function currently only works on serialized meshes. The
1575 // "true" flag specifies that we only need the mesh serialized to
1576 // processor 0
1579 true);
1580
1581 // Note: in general we want to respect the contents of
1582 // _output_variables, only building a solution vector with values
1583 // from the requested variables. First build a list of all variable
1584 // names, then throw out ones that aren't in _output_variables, if
1585 // any.
1586 std::vector<std::string> var_names;
1587 es.build_variable_names (var_names, /*fetype=*/nullptr, system_names);
1588
1589 // Get a subset of all variable names that can be written directly
1590 // as elemental data. We treat those slightly differently since they
1591 // truly only have a single value per Elem.
1592 std::vector<std::string> elemental_var_names;
1593 if (!_output_variables.empty())
1594 elemental_var_names.assign(_output_variables.begin(), _output_variables.end());
1595 es.build_elemental_data_variable_names(elemental_var_names, system_names);
1596
1597 // Remove all names from var_names that are not in _output_variables.
1598 // Note: This approach avoids errors when the user provides invalid
1599 // variable names in _output_variables, as the code will not try to
1600 // write a variable that doesn't exist.
1601 if (!_output_variables.empty())
1602 {
1603 var_names.erase
1604 (std::remove_if
1605 (var_names.begin(),
1606 var_names.end(),
1607 [this](const std::string & name)
1608 {return !std::count(_output_variables.begin(),
1609 _output_variables.end(),
1610 name);}),
1611 var_names.end());
1612 }
1613
1614 // Build a solution vector, limiting the results to the variables in
1615 // var_names and the Systems in system_names, and only computing values
1616 // at the vertices.
1617 std::vector<Number> v;
1619 (v, system_names, &var_names, /*vertices_only=*/true);
1620
1621 // Get active subdomains for each variable in var_names.
1622 std::vector<std::set<subdomain_id_type>> vars_active_subdomains;
1623 es.get_vars_active_subdomains(var_names, vars_active_subdomains);
1624
1625 // Determine names of variables to write based on the number of
1626 // nodes/vertices the elements in different subdomains have.
1628 std::map<subdomain_id_type, unsigned int> subdomain_id_to_vertices_per_elem;
1629 for (const auto & elem : mesh.active_element_ptr_range())
1630 {
1631 // Try to insert key/value pair into the map. If this returns
1632 // false, check the returned iterator's value to make sure it
1633 // matches. It shouldn't actually be possible for this to fail
1634 // (since if the Mesh was like this it would have already
1635 // failed) but it doesn't hurt to be on the safe side.
1636 auto pr2 = subdomain_id_to_vertices_per_elem.emplace
1637 (elem->subdomain_id(), elem->n_vertices());
1638 libmesh_error_msg_if(!pr2.second && pr2.first->second != elem->n_vertices(),
1639 "Elem with different number of vertices found.");
1640 }
1641
1642 // Determine "derived" variable names. These names are created by
1643 // starting with the base variable name and appending the user's
1644 // variable_suffix (default: "_elem_node_") followed by a node id.
1645 //
1646 // Not every derived variable will be active on every subdomain,
1647 // even if the original variable _is_ active. Subdomains can have
1648 // different geometric element types (with differing numbers of
1649 // nodes), so some of the derived variable names will be inactive on
1650 // those subdomains.
1651 //
1652 // Since we would otherwise generate the same name once per
1653 // subdomain, we keep the list of names unique as we are creating
1654 // it. We can't use a std::set for this because we don't want the
1655 // variables names to be in a different order from the order
1656 // they were written in the call to: build_discontinuous_solution_vector()
1657 //
1658 // The list of derived variable names includes one for each vertex,
1659 // for higher-order elements we currently only write out vertex
1660 // values, but this could be changed in the future without too much
1661 // trouble.
1662 std::vector<std::string> derived_var_names;
1663
1664 // Keep track of mapping from derived_name to (orig_name, node_id)
1665 // pair. We will use this later to determine whether a given
1666 // variable is active on a given subdomain.
1667 std::map<std::string, std::pair<std::string, unsigned int>>
1668 derived_name_to_orig_name_and_node_id;
1669
1670 for (const auto & pr : subdomain_id_to_vertices_per_elem)
1671 {
1672 const subdomain_id_type sbd_id = pr.first;
1673 const unsigned int vertices_per_elem =
1674 subdomain_id_to_vertices_per_elem[sbd_id];
1675
1676 std::ostringstream oss;
1677 for (unsigned int n=0; n<vertices_per_elem; ++n)
1678 for (const auto & orig_var_name : var_names)
1679 {
1680 oss.str("");
1681 oss.clear();
1682 oss << orig_var_name << var_suffix << n;
1683 std::string derived_name = oss.str();
1684
1685 // Only add this var name if it's not already in the list.
1686 if (!std::count(derived_var_names.begin(), derived_var_names.end(), derived_name))
1687 {
1688 derived_var_names.push_back(derived_name);
1689 // Add entry for derived_name -> (orig_name, node_id) mapping.
1690 derived_name_to_orig_name_and_node_id[derived_name] =
1691 std::make_pair(orig_var_name, n);
1692 }
1693 }
1694 }
1695
1696 // For each derived variable name, determine whether it is active
1697 // based on how many nodes/vertices the elements in a given subdomain have,
1698 // and whether they were active on the subdomain to begin with.
1699 std::vector<std::set<subdomain_id_type>>
1700 derived_vars_active_subdomains(derived_var_names.size());
1701
1702 // A new data structure for keeping track of a list of variable names
1703 // that are in the discontinuous solution vector on each subdomain. Used
1704 // for indexing. Note: if a variable was inactive at the System level,
1705 // an entry for it will still be in the discontinuous solution vector,
1706 // but it will just have a value of zero. On the other hand, when we
1707 // create the derived variable names some of them are "inactive" on
1708 // different subdomains in the sense that they don't exist at all, i.e.
1709 // there is no zero padding for them. We need to be able to distinguish
1710 // between these two types in order to do the indexing into this vector
1711 // correctly.
1712 std::map<subdomain_id_type, std::vector<std::string>>
1713 subdomain_to_var_names;
1714
1715 for (auto derived_var_id : index_range(derived_var_names))
1716 {
1717 const auto & derived_name = derived_var_names[derived_var_id];
1718 const auto & [orig_name, node_id] =
1719 libmesh_map_find (derived_name_to_orig_name_and_node_id,
1720 derived_name);
1721
1722 // For each subdomain, determine whether the current variable
1723 // should be active on that subdomain.
1724 for (const auto & pr : subdomain_id_to_vertices_per_elem)
1725 {
1726 // Convenience variables for the current subdomain and the
1727 // number of nodes elements in this subdomain have.
1728 subdomain_id_type sbd_id = pr.first;
1729 unsigned int vertices_per_elem_this_sbd =
1730 subdomain_id_to_vertices_per_elem[sbd_id];
1731
1732 // Check whether variable orig_name was active on this
1733 // subdomain to begin with by looking in the
1734 // vars_active_subdomains container. We assume that the
1735 // location of orig_name in the var_names vector matches its
1736 // index in the vars_active_subdomains container.
1737 auto var_loc = std::find(var_names.begin(), var_names.end(), orig_name);
1738 libmesh_error_msg_if(var_loc == var_names.end(),
1739 "Variable " << orig_name << " somehow not found in var_names array.");
1740 auto var_id = std::distance(var_names.begin(), var_loc);
1741
1742 // The derived_var will only be active if this subdomain has
1743 // enough vertices for that to be the case.
1744 if (node_id < vertices_per_elem_this_sbd)
1745 {
1746 // Regardless of whether the original variable was not active on this subdomain,
1747 // the discontinuous solution vector will have zero padding for it, and
1748 // we will need to account for it. Therefore it should still be added to
1749 // the subdomain_to_var_names data structure!
1750 subdomain_to_var_names[sbd_id].push_back(derived_name);
1751
1752 // If the original variable was not active on the
1753 // current subdomain, it should not be added to the
1754 // derived_vars_active_subdomains data structure, since
1755 // it will not be written to the Exodus file.
1756
1757 // Determine if the original variable was active on the
1758 // current subdomain.
1759 bool orig_var_active =
1760 (vars_active_subdomains[var_id].empty() ||
1761 vars_active_subdomains[var_id].count(sbd_id));
1762
1763 // And only if it was, add it to the
1764 // derived_vars_active_subdomains data structure.
1765 if (orig_var_active)
1766 derived_vars_active_subdomains[derived_var_id].insert(sbd_id);
1767 }
1768 } // end loop over subdomain_id_to_vertices_per_elem
1769 } // end loop over derived_var_names
1770
1771 // At this point we've built the "true" list of derived names, but
1772 // if there are any elemental data variables in this list, we now want
1773 // to remove all but one copy of them from the derived_var_names list,
1774 // and rename them in (but not remove them from) the subdomain_to_var_names
1775 // list, and then update the derived_vars_active_subdomains containers
1776 // before finally calling the Exodus helper functions.
1777 for (auto & derived_var_name : derived_var_names)
1778 {
1779 // Get the original name associated with this derived name.
1780 const auto & name_and_id =
1781 libmesh_map_find (derived_name_to_orig_name_and_node_id,
1782 derived_var_name);
1783
1784 // Convenience variables for the map entry's contents.
1785 const std::string & orig_name = name_and_id.first;
1786
1787 // Was the original name an elemental data variable?
1788 if (std::count(elemental_var_names.begin(),
1789 elemental_var_names.end(),
1790 orig_name))
1791 {
1792 // Rename this variable in the subdomain_to_var_names vectors.
1793 for (auto & pr : subdomain_to_var_names)
1794 {
1795 // Reference to ordered list of variable names on this subdomain.
1796 auto & name_vec = pr.second;
1797
1798 auto name_vec_it =
1799 std::find(name_vec.begin(),
1800 name_vec.end(),
1801 derived_var_name);
1802
1803 if (name_vec_it != name_vec.end())
1804 {
1805 // Actually rename it back to the orig_name, dropping
1806 // the "_elem_corner_" stuff.
1807 *name_vec_it = orig_name;
1808 }
1809 }
1810
1811 // Finally, rename the variable in the derived_var_names vector itself.
1812 derived_var_name = orig_name;
1813 } // if (elemental data)
1814 } // end loop over derived names
1815
1816 // Now remove duplicate entries from derived_var_names after the first.
1817 // Also update the derived_vars_active_subdomains container in a consistent way.
1818 {
1819 std::vector<std::string> derived_var_names_edited;
1820 std::vector<std::set<subdomain_id_type>> derived_vars_active_subdomains_edited;
1821 std::vector<unsigned int> found_first(elemental_var_names.size());
1822
1823 for (auto i : index_range(derived_var_names))
1824 {
1825 const auto & derived_var_name = derived_var_names[i];
1826 const auto & active_set = derived_vars_active_subdomains[i];
1827
1828 // Determine whether we will keep this derived variable name in
1829 // the final container.
1830 bool keep = true;
1831 for (auto j : index_range(elemental_var_names))
1832 if (derived_var_name == elemental_var_names[j])
1833 {
1834 if (!found_first[j])
1835 found_first[j] = 1;
1836
1837 else
1838 keep = false;
1839 }
1840
1841 // We also don't keep variables that are not active on any subdomains.
1842 // Contrary to other uses of the var_active_subdomains container where
1843 // the empty set means "all" subdomains, here it really means "none".
1844 if (active_set.empty())
1845 keep = false;
1846
1847 if (keep)
1848 {
1849 derived_var_names_edited.push_back(derived_var_name);
1850 derived_vars_active_subdomains_edited.push_back(active_set);
1851 }
1852 }
1853
1854 // We built the filtered ranges, now swap them with the originals.
1855 derived_var_names.swap(derived_var_names_edited);
1856 derived_vars_active_subdomains.swap(derived_vars_active_subdomains_edited);
1857 }
1858
1859#ifdef LIBMESH_USE_COMPLEX_NUMBERS
1860 // Build complex variable names "r_foo", "i_foo", "a_foo" and the lists of
1861 // subdomains on which they are active.
1862 auto complex_var_names =
1863 exio_helper->get_complex_names(derived_var_names,
1865 auto complex_vars_active_subdomains =
1866 exio_helper->get_complex_vars_active_subdomains(derived_vars_active_subdomains,
1868 auto complex_subdomain_to_var_names =
1869 exio_helper->get_complex_subdomain_to_var_names(subdomain_to_var_names,
1871
1872 // Make expanded version of vector "v" in which each entry in the
1873 // original expands to an ("r_", "i_", "a_") triple.
1874 // "nco" is the number of complex outputs, which depends on whether
1875 // or not we are writing out the complex magnitudes.
1876 std::vector<Real> complex_v;
1877 int nco = _write_complex_abs ? 3 : 2;
1878 complex_v.reserve(nco * v.size());
1879 for (const auto & val : v)
1880 {
1881 complex_v.push_back(val.real());
1882 complex_v.push_back(val.imag());
1884 complex_v.push_back(std::abs(val));
1885 }
1886
1887 // Finally, initialize storage for the variables and write them to file.
1888 exio_helper->initialize_element_variables
1889 (complex_var_names, complex_vars_active_subdomains);
1890 exio_helper->write_element_values_element_major
1891 (mesh, complex_v, _timestep,
1892 complex_vars_active_subdomains,
1893 complex_var_names,
1894 complex_subdomain_to_var_names);
1895#else
1896
1897 // Call function which writes the derived variable names to the
1898 // Exodus file.
1899 exio_helper->initialize_element_variables(derived_var_names, derived_vars_active_subdomains);
1900
1901 // ES::build_discontinuous_solution_vector() creates a vector with
1902 // an element-major ordering, so call Helper::write_element_values()
1903 // passing false for the last argument.
1904 exio_helper->write_element_values_element_major
1905 (mesh, v, _timestep,
1906 derived_vars_active_subdomains,
1907 derived_var_names,
1908 subdomain_to_var_names);
1909#endif
1910}
void build_elemental_data_variable_names(std::vector< std::string > &var_names, const std::set< std::string > *system_names=nullptr) const
Filter var_names to names of variables that can be represented as elemental data.

References _output_variables, _timestep, _write_complex_abs, libMesh::EquationSystems::build_discontinuous_solution_vector(), libMesh::EquationSystems::build_elemental_data_variable_names(), libMesh::EquationSystems::build_variable_names(), exio_helper, libMesh::EquationSystems::get_vars_active_subdomains(), libMesh::index_range(), libMesh::MeshInput< MeshBase >::mesh(), libMesh::MeshOutput< MT >::mesh(), and libMesh::ParallelObject::processor_id().

Referenced by MeshInputTest::testExodusWriteElementDataFromDiscontinuousNodalData().

◆ 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 2237 of file exodusII_io.C.

2242{
2243 libmesh_error_msg_if(!exio_helper->opened_for_writing,
2244 "ERROR, ExodusII file must be opened for writing "
2245 "before calling ExodusII_IO::write_elemset_data()!");
2246
2247 exio_helper->write_elemset_data(timestep, var_names, elemset_ids_in, elemset_vals);
2248}

References exio_helper.

◆ 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 2138 of file exodusII_io.C.

2139{
2140 libmesh_error_msg_if(!exio_helper->opened_for_writing,
2141 "ERROR, ExodusII file must be opened for writing "
2142 "before calling ExodusII_IO::write_elemsets()!");
2143
2145 exio_helper->write_elemsets(mesh);
2146}

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

◆ 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 2130 of file exodusII_io.C.

2133{
2134 write_timestep(fname, es, 1, 0, system_names);
2135}
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.

References write_timestep().

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

◆ 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 2080 of file exodusII_io.C.

2082{
2083 LOG_SCOPE("write_global_data()", "ExodusII_IO");
2084
2086 return;
2087
2088 libmesh_error_msg_if(!exio_helper->opened_for_writing,
2089 "ERROR, ExodusII file must be initialized before outputting global variables.");
2090
2091#ifdef LIBMESH_USE_COMPLEX_NUMBERS
2092
2093 std::vector<std::string> complex_names =
2094 exio_helper->get_complex_names(names,
2096
2097 exio_helper->initialize_global_variables(complex_names);
2098
2099 const std::vector<Real> complex_soln =
2100 complex_soln_components(soln, names.size(), _write_complex_abs,
2101 SolutionOrdering::variable_major,
2102 SolutionOrdering::variable_major);
2103
2104 exio_helper->write_global_values(complex_soln, _timestep);
2105
2106#else
2107 exio_helper->initialize_global_variables(names);
2108 exio_helper->write_global_values(soln, _timestep);
2109#endif
2110}

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

◆ write_information_records()

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

Write out information records.

Definition at line 2067 of file exodusII_io.C.

2068{
2070 return;
2071
2072 libmesh_error_msg_if(!exio_helper->opened_for_writing,
2073 "ERROR, ExodusII file must be initialized before outputting information records.");
2074
2075 exio_helper->write_information_records(records);
2076}

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

◆ write_nodal_data() [1/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 149 of file mesh_output.C.

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...

◆ write_nodal_data() [2/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 136 of file mesh_output.C.

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 localize(std::vector< T > &v_local) const =0
Creates a copy of the global vector in the local vector v_local.

◆ 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 1914 of file exodusII_io.C.

1917{
1918 LOG_SCOPE("write_nodal_data()", "ExodusII_IO");
1919
1921
1922 int num_vars = cast_int<int>(names.size());
1923 dof_id_type num_nodes = mesh.n_nodes();
1924
1925 // The names of the variables to be output
1926 std::vector<std::string> output_names;
1927
1929 output_names = _output_variables;
1930 else
1931 output_names = names;
1932
1933#ifdef LIBMESH_USE_COMPLEX_NUMBERS
1934 std::vector<std::string> complex_names =
1935 exio_helper->get_complex_names(output_names,
1937
1938 // Call helper function for opening/initializing data, giving it the
1939 // complex variable names
1940 this->write_nodal_data_common(fname, complex_names, /*continuous=*/true);
1941#else
1942 // Call helper function for opening/initializing data
1943 this->write_nodal_data_common(fname, output_names, /*continuous=*/true);
1944#endif
1945
1946 if (mesh.processor_id())
1947 return;
1948
1949 // This will count the number of variables actually output
1950 for (int c=0; c<num_vars; c++)
1951 {
1952 std::stringstream name_to_find;
1953
1954 std::vector<std::string>::iterator pos =
1955 std::find(output_names.begin(), output_names.end(), names[c]);
1956 if (pos == output_names.end())
1957 continue;
1958
1959 unsigned int variable_name_position =
1960 cast_int<unsigned int>(pos - output_names.begin());
1961
1962 // Set up temporary vectors to be passed to Exodus to write the
1963 // nodal values for a single variable at a time.
1964#ifdef LIBMESH_USE_REAL_NUMBERS
1965 std::vector<Number> cur_soln;
1966
1967 // num_nodes is either exactly how much space we will need for
1968 // each vector, or a safe upper bound for the amount of memory
1969 // we will require when there are gaps in the numbering.
1970 cur_soln.reserve(num_nodes);
1971#else
1972 std::vector<Real> real_parts;
1973 std::vector<Real> imag_parts;
1974 std::vector<Real> magnitudes;
1975 real_parts.reserve(num_nodes);
1976 imag_parts.reserve(num_nodes);
1978 magnitudes.reserve(num_nodes);
1979#endif
1980
1981 // There could be gaps in soln based on node numbering, but in
1982 // serial the empty numbers are left empty.
1983 // There could also be offsets in soln based on "fake" nodes
1984 // inserted on each processor (because NumericVector indices
1985 // have to be contiguous); the helper keeps track of those.
1986 // We now copy the proper solution values contiguously into
1987 // "cur_soln", removing the gaps.
1988 for (const auto & node : mesh.node_ptr_range())
1989 {
1990 const dof_id_type idx =
1991 (exio_helper->node_id_to_vec_id(node->id()))
1992 * num_vars + c;
1993#ifdef LIBMESH_USE_REAL_NUMBERS
1994 cur_soln.push_back(soln[idx]);
1995#else
1996 real_parts.push_back(soln[idx].real());
1997 imag_parts.push_back(soln[idx].imag());
1999 magnitudes.push_back(std::abs(soln[idx]));
2000#endif
2001 }
2002
2003 // If we're adding extra sides, we need to add their data too.
2004 //
2005 // Because soln was created from a parallel NumericVector, its
2006 // numbering was contiguous on each processor; we need to use
2007 // the same offsets here, and we need to loop through elements
2008 // from earlier ranks first.
2009 if (exio_helper->get_add_sides())
2010 {
2011 std::vector<std::vector<const Elem *>>
2012 elems_by_pid(mesh.n_processors());
2013
2014 for (const auto & elem : mesh.active_element_ptr_range())
2015 elems_by_pid[elem->processor_id()].push_back(elem);
2016
2017 for (auto p : index_range(elems_by_pid))
2018 {
2019 dof_id_type global_idx =
2020 exio_helper->added_node_offset_on(p) * num_vars + c;
2021 for (const Elem * elem : elems_by_pid[p])
2022 {
2023 for (auto s : elem->side_index_range())
2024 {
2026 continue;
2027
2028 const std::vector<unsigned int> side_nodes =
2029 elem->nodes_on_side(s);
2030
2031 for (auto n : index_range(side_nodes))
2032 {
2033 libmesh_ignore(n);
2034 libmesh_assert_less(global_idx, soln.size());
2035#ifdef LIBMESH_USE_REAL_NUMBERS
2036 cur_soln.push_back(soln[global_idx]);
2037#else
2038 real_parts.push_back(soln[global_idx].real());
2039 imag_parts.push_back(soln[global_idx].imag());
2041 magnitudes.push_back(std::abs(soln[global_idx]));
2042#endif
2043 global_idx += num_vars;
2044 }
2045 }
2046 }
2047 }
2048 }
2049
2050 // Finally, actually call the Exodus API to write to file.
2051#ifdef LIBMESH_USE_REAL_NUMBERS
2052 exio_helper->write_nodal_values(variable_name_position+1, cur_soln, _timestep);
2053#else
2054 int nco = _write_complex_abs ? 3 : 2;
2055 exio_helper->write_nodal_values(nco*variable_name_position+1, real_parts, _timestep);
2056 exio_helper->write_nodal_values(nco*variable_name_position+2, imag_parts, _timestep);
2058 exio_helper->write_nodal_values(3*variable_name_position+3, magnitudes, _timestep);
2059#endif
2060
2061 }
2062}
static bool redundant_added_side(const Elem &elem, unsigned int side)
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...
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.
boost::multiprecision::float128 real(const boost::multiprecision::float128 in)
boost::multiprecision::float128 imag(const boost::multiprecision::float128)

References _allow_empty_variables, _output_variables, _timestep, _write_complex_abs, exio_helper, 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(), libMesh::EquationSystems::redundant_added_side(), and write_nodal_data_common().

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

◆ 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 2393 of file exodusII_io.C.

2396{
2398
2399 // This function can be called multiple times, we only want to open
2400 // the ExodusII file the first time it's called.
2401 if (!exio_helper->opened_for_writing)
2402 {
2403 // If we're appending, open() the file with read_only=false,
2404 // otherwise create() it and write the contents of the mesh to
2405 // it.
2406 if (_append)
2407 {
2408 // We do our writing only from proc 0, to avoid race
2409 // conditions with Exodus 8
2411 {
2412 exio_helper->open(fname.c_str(), /*read_only=*/false);
2413 // If we're appending, it's not valid to call exio_helper->initialize()
2414 // or exio_helper->initialize_nodal_variables(), but we do need to set up
2415 // certain aspects of the Helper object itself, such as the number of nodes
2416 // and elements. We do that by reading the header...
2417 exio_helper->read_and_store_header_info();
2418
2419 // ...and reading the block info
2420 exio_helper->read_block_info();
2421 }
2422 // Keep other processors aware of what we've done on root
2423 else
2424 {
2425 exio_helper->opened_for_writing = true;
2426 exio_helper->current_filename = fname;
2427 }
2428 }
2429 else
2430 {
2431 exio_helper->create(fname);
2432
2433 // But some of our write calls are parallel-only, due to
2434 // calls to parallel-only getter functions.
2435 exio_helper->initialize(fname, mesh, !continuous);
2436
2437 exio_helper->write_nodal_coordinates(mesh, !continuous);
2438 exio_helper->write_elements(mesh, !continuous);
2439
2440 exio_helper->write_sidesets(mesh);
2441 exio_helper->write_nodesets(mesh);
2442 exio_helper->write_elemsets(mesh);
2443
2444 exio_helper->initialize_nodal_variables(names);
2445 }
2446 }
2447 else
2448 {
2449 // We are already open for writing, so check that the filename
2450 // passed to this function matches the filename currently in use
2451 // by the helper.
2452 libmesh_error_msg_if(fname != exio_helper->current_filename,
2453 "Error! This ExodusII_IO object is already associated with file: "
2454 << exio_helper->current_filename
2455 << ", cannot use it with requested file: "
2456 << fname);
2457 }
2458}

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().

◆ 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 2315 of file exodusII_io.C.

2318{
2319 LOG_SCOPE("write_nodal_data_discontinuous()", "ExodusII_IO");
2320
2322
2323#ifdef LIBMESH_USE_COMPLEX_NUMBERS
2324
2325 std::vector<std::string> complex_names =
2326 exio_helper->get_complex_names(names,
2328
2329 // Call helper function for opening/initializing data, giving it the
2330 // complex variable names
2331 this->write_nodal_data_common(fname, complex_names, /*continuous=*/false);
2332#else
2333 // Call helper function for opening/initializing data
2334 this->write_nodal_data_common(fname, names, /*continuous=*/false);
2335#endif
2336
2337 if (mesh.processor_id())
2338 return;
2339
2340 int num_vars = cast_int<int>(names.size());
2341 libmesh_assert_equal_to(soln.size() % num_vars, 0);
2342 int num_nodes = soln.size() / num_vars;
2343 libmesh_assert_equal_to(exio_helper->num_nodes, num_nodes);
2344
2345#ifndef NDEBUG
2346 if (!this->get_add_sides())
2347 {
2348 int num_real_nodes = 0;
2349 for (const auto & elem : mesh.active_element_ptr_range())
2350 num_real_nodes += elem->n_nodes();
2351 libmesh_assert_equal_to(num_real_nodes, num_nodes);
2352 }
2353#endif
2354
2355 for (int c=0; c<num_vars; c++)
2356 {
2357#ifdef LIBMESH_USE_COMPLEX_NUMBERS
2358 std::vector<Real> real_parts(num_nodes);
2359 std::vector<Real> imag_parts(num_nodes);
2360 std::vector<Real> magnitudes;
2362 magnitudes.resize(num_nodes);
2363
2364 // The number of complex outputs depends on whether or not we are
2365 // writing out the absolute values.
2366 int nco = _write_complex_abs ? 3 : 2;
2367
2368 for (int i=0; i<num_nodes; ++i)
2369 {
2370 real_parts[i] = soln[i*num_vars + c].real();
2371 imag_parts[i] = soln[i*num_vars + c].imag();
2373 magnitudes[i] = std::abs(soln[i*num_vars + c]);
2374 }
2375 exio_helper->write_nodal_values(nco*c+1, real_parts, _timestep);
2376 exio_helper->write_nodal_values(nco*c+2, imag_parts, _timestep);
2378 exio_helper->write_nodal_values(3*c+3, magnitudes, _timestep);
2379#else
2380 // Copy out this variable's solution
2381 std::vector<Number> cur_soln(num_nodes);
2382
2383 for (int i=0; i<num_nodes; i++)
2384 cur_soln[i] = soln[i*num_vars + c];
2385
2386 exio_helper->write_nodal_values(c+1,cur_soln,_timestep);
2387#endif
2388 }
2389}

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().

◆ 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 2207 of file exodusII_io.C.

2212{
2213 libmesh_error_msg_if(!exio_helper->opened_for_writing,
2214 "ERROR, ExodusII file must be opened for writing "
2215 "before calling ExodusII_IO::write_nodeset_data()!");
2216
2217 exio_helper->write_nodeset_data(timestep, var_names, node_boundary_ids, bc_vals);
2218}

References exio_helper.

◆ 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 2149 of file exodusII_io.C.

2154{
2155 libmesh_error_msg_if(!exio_helper->opened_for_writing,
2156 "ERROR, ExodusII file must be opened for writing "
2157 "before calling ExodusII_IO::write_sideset_data()!");
2158
2160 exio_helper->write_sideset_data(mesh, timestep, var_names, side_ids, bc_vals);
2161}

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

◆ 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 2114 of file exodusII_io.C.

2119{
2120 _timestep = timestep;
2121 MeshOutput<MeshBase>::write_equation_systems(fname,es,system_names);
2122
2124 return;
2125
2126 exio_helper->write_timestep(timestep, time);
2127}
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

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(), write_output(), and write_output().

◆ 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 235 of file exodusII_io.C.

240{
241 _timestep = timestep;
242 write_discontinuous_equation_systems (fname,es,system_names);
243
245 return;
246
247 exio_helper->write_timestep(timestep, time);
248}
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

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

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().

◆ _ascii_precision

unsigned int libMesh::MeshOutput< MeshBase >::_ascii_precision
privateinherited

Precision to use when writing ASCII files.

Definition at line 207 of file mesh_output.h.

◆ _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 [1/2]

const bool libMesh::MeshInput< MeshBase >::_is_parallel_format
privateinherited

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 130 of file mesh_input.h.

◆ _is_parallel_format [2/2]

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.

◆ _obj

MeshBase * libMesh::MeshInput< MeshBase >::_obj
privateinherited

A pointer to a non-const object object.

This allows us to read the object from file.

Definition at line 123 of file mesh_input.h.

◆ _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(), write_element_data_from_discontinuous_nodal_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_element_data_from_discontinuous_nodal_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

A vector of bools describing what dimension elements have been encountered when reading a mesh.

Definition at line 107 of file mesh_input.h.

◆ 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: