libMesh
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | Protected Member Functions | Protected Attributes | Private Types | Private Member Functions | Private Attributes | List of all members
libMesh::Nemesis_IO_Helper Class Reference

This is the Nemesis_IO_Helper class. More...

#include <nemesis_io_helper.h>

Inheritance diagram for libMesh::Nemesis_IO_Helper:
[legend]

Public Types

enum  ExodusVarType {
  NODAL =0 , ELEMENTAL =1 , GLOBAL =2 , SIDESET =3 ,
  NODESET =4 , ELEMSET =5
}
 Wraps calls to exII::ex_get_var_names() and exII::ex_get_var_param(). More...
 

Public Member Functions

 Nemesis_IO_Helper (const ParallelObject &parent, bool verbose=false, bool single_precision=false)
 Constructor.
 
virtual ~Nemesis_IO_Helper ()
 Destructor.
 
void write_complex_magnitude (bool val)
 Set the flag indicating whether the complex modulus should be written when complex numbers are enabled.
 
void read_nodeset (int id)
 Reading functions.
 
void get_init_global ()
 Fills: num_nodes_global, num_elems_global, num_elem_blks_global, num_node_sets_global, num_side_sets_global Call after: read_and_store_header_info() Call before: Any other get_* function from this class.
 
void get_ss_param_global ()
 Fills: global_sideset_ids, num_global_side_counts, num_global_side_df_counts Call after: get_init_global()
 
void get_ns_param_global ()
 
void get_eb_info_global ()
 
void get_init_info ()
 
void get_loadbal_param ()
 
void get_elem_map ()
 
void get_node_map ()
 
void get_cmap_params ()
 
void get_node_cmap ()
 
void get_elem_cmap ()
 
void put_init_info (unsigned num_proc, unsigned num_proc_in_file, const char *ftype)
 Writing functions.
 
void put_init_global (dof_id_type num_nodes_global, dof_id_type num_elems_global, unsigned num_elem_blks_global, unsigned num_node_sets_global, unsigned num_side_sets_global)
 Writes global information including: .) global number of nodes .) global number of elems .) global number of element blocks .) global number of node sets .) global number of side sets.
 
void put_eb_info_global (std::vector< int > &global_elem_blk_ids, std::vector< int > &global_elem_blk_cnts)
 Writes global block information to the file .) global_elem_blk_ids - list of block IDs for all blocks present in the mesh .) global_elem_blk_cnts - number of elements in each block for the global mesh.
 
void put_ns_param_global (std::vector< int > &global_nodeset_ids, std::vector< int > &num_global_node_counts, std::vector< int > &num_global_node_df_counts)
 This function writes information about global node sets.
 
void put_ss_param_global (std::vector< int > &global_sideset_ids, std::vector< int > &num_global_side_counts, std::vector< int > &num_global_side_df_counts)
 This function writes information about global side sets.
 
void put_loadbal_param (unsigned num_internal_nodes, unsigned num_border_nodes, unsigned num_external_nodes, unsigned num_internal_elems, unsigned num_border_elems, unsigned num_node_cmaps, unsigned num_elem_cmaps)
 Writes load balance parameters, some of which are described below: .) num_internal_nodes - nodes "wholly" owned by the current processor .) num_border_nodes - nodes local to a processor but residing in an element which also has nodes on other processors .) num_external_nodes - nodes that reside on other processors but whose element "partially" resides on the current processor – we assert this should be zero on reading! .) num_border_elems - elements local to this processor but whose nodes reside on other processors as well.
 
void put_cmap_params (std::vector< int > &node_cmap_ids, std::vector< int > &node_cmap_node_cnts, std::vector< int > &elem_cmap_ids, std::vector< int > &elem_cmap_elem_cnts)
 Outputs initial information for communication maps.
 
void put_node_cmap (std::vector< std::vector< int > > &node_cmap_node_ids, std::vector< std::vector< int > > &node_cmap_proc_ids)
 Outputs all of the nodal communication maps for this processor.
 
void put_node_map (std::vector< int > &node_mapi, std::vector< int > &node_mapb, std::vector< int > &node_mape)
 Outputs IDs of internal, border, and external nodes.
 
void put_elem_cmap (std::vector< std::vector< int > > &elem_cmap_elem_ids, std::vector< std::vector< int > > &elem_cmap_side_ids, std::vector< std::vector< int > > &elem_cmap_proc_ids)
 Writes information about elemental communication map.
 
void put_elem_map (std::vector< int > &elem_mapi, std::vector< int > &elem_mapb)
 Outputs IDs of internal and border elements.
 
virtual void write_nodal_coordinates (const MeshBase &mesh, bool use_discontinuous=false) override
 This function is specialized from ExodusII_IO_Helper to write only the nodal coordinates stored on the local piece of the Mesh.
 
virtual void write_elements (const MeshBase &mesh, bool use_discontinuous=false) override
 This function is specialized to write the connectivity.
 
virtual void write_sidesets (const MeshBase &mesh) override
 Writes the sidesets for this processor.
 
virtual void write_nodesets (const MeshBase &mesh) override
 Writes the nodesets for this processor.
 
virtual void initialize (std::string title, const MeshBase &mesh, bool use_discontinuous=false) override
 Specialization of the initialize function from ExodusII_IO_Helper that also writes global initial data to file.
 
void compute_num_global_elem_blocks (const MeshBase &pmesh)
 This function uses global communication routines to determine the number of element blocks across the entire mesh.
 
void build_element_and_node_maps (const MeshBase &pmesh)
 This function builds the libmesh -> exodus and exodus -> libmesh node and element maps.
 
void write_nodal_solution (const NumericVector< Number > &parallel_soln, const std::vector< std::string > &names, int timestep, const std::vector< std::string > &output_names)
 Takes a parallel solution vector containing the node-major solution vector for all variables and outputs it to the files.
 
void write_nodal_solution (const EquationSystems &es, const std::vector< std::pair< unsigned int, unsigned int > > &var_nums, int timestep, const std::vector< std::string > &output_names)
 Outputs EquationSystems current_local_solution nodal values.
 
void write_nodal_solution (const std::vector< Number > &values, const std::vector< std::string > &names, int timestep)
 Takes a solution vector containing the solution for all variables and outputs it to the files.
 
virtual void initialize_element_variables (std::vector< std::string > names, const std::vector< std::set< subdomain_id_type > > &vars_active_subdomains) override
 Override the Exodus Helper's implementation of this function so that it works correctly in parallel.
 
void write_element_values (const MeshBase &mesh, const EquationSystems &es, const std::vector< std::pair< unsigned int, unsigned int > > &var_nums, int timestep, const std::vector< std::set< subdomain_id_type > > &vars_active_subdomains)
 Writes the vector of elemental variable values, one variable and one subdomain at a time.
 
std::string construct_nemesis_filename (std::string_view base_filename)
 Given base_filename, foo.e, constructs the Nemesis filename foo.e.X.Y, where X=n.
 
const char * get_elem_type () const
 
void set_add_sides (bool add_sides)
 Sets whether or not to write extra "side" elements.
 
bool get_add_sides ()
 
void open (const char *filename, bool read_only)
 Opens an ExodusII mesh file named filename.
 
ExodusHeaderInfo read_header () const
 Reads an ExodusII mesh file header, leaving this object's internal data structures unchanged.
 
void read_and_store_header_info ()
 Reads an ExodusII mesh file header, and stores required information on this object.
 
void read_qa_records ()
 Reads the QA records from an ExodusII file.
 
void print_header ()
 Prints the ExodusII mesh file header, which includes the mesh title, the number of nodes, number of elements, mesh dimension, number of sidesets, and number of nodesets.
 
void read_nodes ()
 Reads the nodal data (x,y,z coordinates) from the ExodusII mesh file.
 
void read_node_num_map ()
 Reads the optional node_num_map from the ExodusII mesh file.
 
void read_bex_cv_blocks ()
 Reads the optional bex_cv_blocks from the ExodusII mesh file.
 
void print_nodes (std::ostream &out_stream=libMesh::out)
 Prints the nodal information, by default to libMesh::out.
 
void read_block_info ()
 Reads information for all of the blocks in the ExodusII mesh file.
 
int get_block_id (int index)
 Get the block number for the given block index.
 
std::string get_block_name (int index)
 Get the block name for the given block index if supplied in the mesh file.
 
int get_side_set_id (int index)
 Get the side set id for the given side set index.
 
std::string get_side_set_name (int index)
 Get the side set name for the given side set index if supplied in the mesh file.
 
int get_node_set_id (int index)
 Get the node set id for the given node set index.
 
std::string get_node_set_name (int index)
 Get the node set name for the given node set index if supplied in the mesh file.
 
void read_elem_in_block (int block)
 Reads all of the element connectivity for block block in the ExodusII mesh file.
 
void read_face_blocks ()
 Reads NSIDED face blocks used by NFACED element blocks.
 
void read_edge_blocks (MeshBase &mesh)
 Read in edge blocks, storing information in the BoundaryInfo object.
 
void read_elem_num_map ()
 Reads the optional node_num_map from the ExodusII mesh file.
 
void read_sideset_info ()
 Reads information about all of the sidesets in the ExodusII mesh file.
 
void read_nodeset_info ()
 Reads information about all of the nodesets in the ExodusII mesh file.
 
void read_elemset_info ()
 Reads information about all of the elemsets in the ExodusII mesh file.
 
void read_sideset (int id, int offset)
 Reads information about sideset id and inserts it into the global sideset array at the position offset.
 
void read_elemset (int id, int offset)
 Reads information about elemset id and inserts it into the global elemset array at the position offset.
 
void read_all_nodesets ()
 New API that reads all nodesets simultaneously.
 
void close () noexcept
 Closes the ExodusII mesh file.
 
void read_time_steps ()
 Reads and stores the timesteps in the 'time_steps' array.
 
void read_num_time_steps ()
 Reads the number of timesteps currently stored in the Exodus file and stores it in the num_time_steps variable.
 
void read_nodal_var_values (std::string nodal_var_name, int time_step)
 Reads the nodal values for the variable 'nodal_var_name' at the specified time into the 'nodal_var_values' array.
 
void read_elemental_var_values (std::string elemental_var_name, int time_step, std::map< dof_id_type, Real > &elem_var_value_map)
 Reads elemental values for the variable 'elemental_var_name' at the specified timestep into the 'elem_var_value_map' which is passed in.
 
dof_id_type get_libmesh_node_id (int exodus_node_id)
 Helper function that takes a (1-based) Exodus node/elem id and determines the corresponding libMesh Node/Elem id.
 
dof_id_type get_libmesh_elem_id (int exodus_elem_id)
 
void conditionally_set_node_unique_id (MeshBase &mesh, Node *node, int zero_based_node_num_map_index)
 Helper function that conditionally sets the unique_id of the passed-in Node/Elem.
 
void conditionally_set_elem_unique_id (MeshBase &mesh, Elem *elem, int zero_based_elem_num_map_index)
 
virtual void create (std::string filename)
 Opens an ExodusII mesh file named filename for writing.
 
void initialize_nodal_variables (std::vector< std::string > names)
 Sets up the nodal variables.
 
void initialize_global_variables (std::vector< std::string > names)
 Sets up the global variables.
 
void write_timestep (int timestep, Real time)
 Writes the time for the timestep.
 
void write_elemsets (const MeshBase &mesh)
 Write elemsets stored on the Mesh to the exo file.
 
void write_sideset_data (const MeshBase &mesh, 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)
 Write sideset data for the requested timestep.
 
void read_sideset_data (const MeshBase &mesh, 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)
 Read sideset variables, if any, into the provided data structures.
 
void get_sideset_data_indices (const MeshBase &mesh, 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 indexing 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)
 Write nodeset data for the requested timestep.
 
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 nodeset variables, if any, into the provided data structures.
 
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 indexing 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)
 Write elemset data for the requested timestep.
 
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 elemset variables, if any, into the provided data structures.
 
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 elemset per variable, creates a single map of (elem_id, elemset_id) tuples, and stores the exo file array indexing for any/all elemset variables on that elemset (they are all the same).
 
void write_element_values (const MeshBase &mesh, const std::vector< Real > &values, int timestep, const std::vector< std::set< subdomain_id_type > > &vars_active_subdomains)
 Writes the vector of values to the element variables.
 
void write_element_values_element_major (const MeshBase &mesh, const std::vector< Real > &values, int timestep, const std::vector< std::set< subdomain_id_type > > &vars_active_subdomains, const std::vector< std::string > &derived_var_names, const std::map< subdomain_id_type, std::vector< std::string > > &subdomain_to_var_names)
 Same as the function above, but assume the input 'values' vector is in element-major order, i.e.
 
void write_nodal_values (int var_id, const std::vector< Real > &values, int timestep)
 Writes the vector of values to a nodal variable.
 
void write_information_records (const std::vector< std::string > &records)
 Writes the vector of information records.
 
void write_global_values (const std::vector< Real > &values, int timestep)
 Writes the vector of global variables.
 
void update ()
 Uses ex_update() to flush buffers to file.
 
void read_global_values (std::vector< Real > &values, int timestep)
 Reads the vector of global variables.
 
void use_mesh_dimension_instead_of_spatial_dimension (bool val)
 Sets the underlying value of the boolean flag _use_mesh_dimension_instead_of_spatial_dimension.
 
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 write_as_dimension (unsigned dim)
 Sets the value of _write_as_dimension.
 
void set_coordinate_offset (Point p)
 Allows you to set a vector that is added to the coordinates of all of the nodes.
 
void set_max_name_length (unsigned int max_length)
 Set how many characters to use in names when opening a file for writing.
 
std::vector< std::string > get_complex_names (const std::vector< std::string > &names, bool write_complex_abs) const
 
std::vector< std::set< subdomain_id_type > > get_complex_vars_active_subdomains (const std::vector< std::set< subdomain_id_type > > &vars_active_subdomains, bool write_complex_abs) const
 returns a "tripled" copy of vars_active_subdomains, which is necessary in the complex-valued case.
 
std::map< subdomain_id_type, std::vector< std::string > > get_complex_subdomain_to_var_names (const std::map< subdomain_id_type, std::vector< std::string > > &subdomain_to_var_names, bool write_complex_abs) const
 Takes a map from subdomain id -> vector of active variable names as input and returns a corresponding map where the original variable names have been replaced by their complex counterparts.
 
void message (std::string_view msg)
 Prints the message defined in msg.
 
void message (std::string_view msg, int i)
 Prints the message defined in msg, and appends the number i to the end of the message.
 
int end_elem_id () const
 
void read_var_names (ExodusVarType type)
 
const ExodusII_IO_Helper::Conversionget_conversion (const ElemType type) const
 
const ExodusII_IO_Helper::Conversionget_conversion (std::string type_str) const
 
dof_id_type node_id_to_vec_id (dof_id_type n) const
 
dof_id_type added_node_offset_on (processor_id_type p) const
 
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 ()
 

Public Attributes

int nemesis_err_flag
 Member data.
 
int num_nodes_global
 Global initial information.
 
int num_elems_global
 
int num_elem_blks_global
 
int num_node_sets_global
 
int num_side_sets_global
 
int num_proc
 The number of processors for which the NEMESIS I file was created.
 
int num_proc_in_file
 The number of processors for which the NEMESIS I file stores information.
 
char ftype
 The type of file to be written.
 
std::vector< intnode_list
 
std::vector< intglobal_sideset_ids
 Containers for reading global sideset (boundary conditions) information.
 
std::vector< intnum_global_side_counts
 
std::vector< intnum_global_side_df_counts
 
std::vector< intglobal_nodeset_ids
 Containers for reading global nodeset information.
 
std::vector< intnum_global_node_counts
 
std::vector< intnum_global_node_df_counts
 
std::vector< intglobal_elem_blk_ids
 Read the global element block IDs and counts.
 
std::vector< intglobal_elem_blk_cnts
 
std::set< intnodes_attached_to_local_elems
 libMesh numbered node ids attached to local elems.
 
std::map< subdomain_id_type, std::vector< dof_id_type > > subdomain_map
 Map of subdomains to element numbers.
 
std::map< int, std::vector< int > > block_id_to_elem_connectivity
 This is the block connectivity, i.e.
 
int num_internal_nodes
 To be used with the Nemesis::ne_get_loadbal_param() routine.
 
int num_border_nodes
 The number of FEM nodes local to a processor but residing in an element which also has FEM nodes on other processors.
 
int num_external_nodes
 The number of FEM nodes that reside on another processor but whose element partially resides on the current processor.
 
int num_internal_elems
 The number of internal FEM elements.
 
int num_border_elems
 The number of border FEM elements.
 
int num_node_cmaps
 The number of nodal communication maps for this processor.
 
int num_elem_cmaps
 The number of elemental communication maps for this processor.
 
std::vector< intelem_mapi
 Vector which stores internal element IDs.
 
std::vector< intelem_mapb
 Vector which stores border element IDs.
 
std::vector< intnode_mapi
 Vector which stores internal node IDs.
 
std::vector< intnode_mapb
 Vector which stores border node IDs.
 
std::vector< intnode_mape
 Vector which stores external node IDs.
 
std::vector< intnode_cmap_ids
 Vectors for storing the communication map parameters.
 
std::vector< intnode_cmap_node_cnts
 
std::vector< intelem_cmap_ids
 
std::vector< intelem_cmap_elem_cnts
 
std::vector< std::vector< int > > node_cmap_node_ids
 2 vectors of vectors for storing the node communication IDs for this processor.
 
std::vector< std::vector< int > > node_cmap_proc_ids
 
std::vector< std::vector< int > > elem_cmap_elem_ids
 3 vectors of vectors for storing element communication IDs for this processor.
 
std::vector< std::vector< int > > elem_cmap_side_ids
 
std::vector< std::vector< int > > elem_cmap_proc_ids
 
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).
 
int ex_id
 
int ex_err
 
ExodusHeaderInfo header_info
 
std::vector< char > & title
 
intnum_dim
 
intnum_nodes
 
intnum_elem
 
intnum_elem_blk
 
intnum_edge
 
intnum_edge_blk
 
intnum_face
 
intnum_face_blk
 
intnum_node_sets
 
intnum_side_sets
 
intnum_elem_sets
 
int num_global_vars
 
int num_sideset_vars
 
int num_nodeset_vars
 
int num_elemset_vars
 
int num_elem_this_blk
 
int num_nodes_per_elem
 
int num_attr
 
int num_elem_all_sidesets
 
int num_elem_all_elemsets
 
std::vector< intblock_ids
 
std::vector< intedge_block_ids
 
std::vector< intconnect
 
std::vector< intelem_node_counts
 
std::vector< intelem_face_counts
 
std::vector< std::vector< int > > c0polyhedron_face_connect
 
std::vector< intss_ids
 
std::vector< intnodeset_ids
 
std::vector< intelemset_ids
 
std::vector< intnum_sides_per_set
 
std::vector< intnum_nodes_per_set
 
std::vector< intnum_elems_per_set
 
std::vector< intnum_df_per_set
 
std::vector< intnum_node_df_per_set
 
std::vector< intnum_elem_df_per_set
 
std::vector< intnode_sets_node_index
 
std::vector< intnode_sets_dist_index
 
std::vector< intnode_sets_node_list
 
std::vector< Realnode_sets_dist_fact
 
std::vector< intelem_list
 
std::vector< intside_list
 
std::vector< intid_list
 
std::vector< intelemset_list
 
std::vector< intelemset_id_list
 
std::vector< intnode_num_map
 
std::vector< intelem_num_map
 
std::vector< Realx
 
std::vector< Realy
 
std::vector< Realz
 
std::vector< Realw
 
unsigned int bex_num_elem_cvs
 
std::vector< std::vector< long unsigned int > > bex_cv_conn
 
std::vector< std::vector< std::vector< Real > > > bex_dense_constraint_vecs
 
std::vector< char > elem_type
 
std::map< dof_id_type, dof_id_typelibmesh_elem_num_to_exodus
 
std::vector< intexodus_elem_num_to_libmesh
 
std::map< dof_id_type, dof_id_typelibmesh_node_num_to_exodus
 
std::vector< intexodus_node_num_to_libmesh
 
int num_time_steps
 
std::vector< Realtime_steps
 
int num_nodal_vars
 
std::vector< std::string > nodal_var_names
 
std::map< dof_id_type, Realnodal_var_values
 
int num_elem_vars
 
std::vector< std::string > elem_var_names
 
std::vector< Realelem_var_values
 
std::vector< std::string > global_var_names
 
std::vector< std::string > sideset_var_names
 
std::vector< std::string > nodeset_var_names
 
std::vector< std::string > elemset_var_names
 
std::map< int, std::string > id_to_block_names
 
std::map< int, std::string > id_to_edge_block_names
 
std::map< int, std::string > id_to_ss_names
 
std::map< int, std::string > id_to_ns_names
 
std::map< int, std::string > id_to_elemset_names
 
bool verbose
 
bool set_unique_ids_from_maps
 
bool opened_for_writing
 
bool opened_for_reading
 
std::string current_filename
 

Protected Member Functions

virtual void read_var_names_impl (const char *var_type, int &count, std::vector< std::string > &result) override
 read_var_names() dispatches to this function.
 
void check_existing_vars (ExodusVarType type, std::vector< std::string > &names, std::vector< std::string > &names_from_file)
 When appending: during initialization, check that variable names in the file match those you attempt to initialize with.
 
void write_var_names (ExodusVarType type, const std::vector< std::string > &names)
 Wraps calls to exII::ex_put_var_names() and exII::ex_put_var_param().
 

Protected Attributes

bool _run_only_on_proc0
 
bool _opened_by_create
 
bool _elem_vars_initialized
 
bool _global_vars_initialized
 
bool _nodal_vars_initialized
 
bool _use_mesh_dimension_instead_of_spatial_dimension
 
bool _write_hdf5
 
unsigned int _max_name_length
 
int _end_elem_id
 
unsigned _write_as_dimension
 
Point _coordinate_offset
 
bool _single_precision
 
std::vector< dof_id_type_added_side_node_offsets
 If we're adding "fake" sides to visualize SIDE_DISCONTINUOUS variables, _added_side_node_offsets[p] gives us the total solution vector offset to use on processor p+1 from the nodes on those previous ranks' sides.
 
std::vector< dof_id_type_true_node_offsets
 If we're adding "fake" sides to visualize SIDE_DISCONTINUOUS variables, we also need to know how many real nodes from previous ranks are taking up space in a solution vector.
 
const Parallel::Communicator_communicator
 

Private Types

typedef std::map< unsigned, std::set< unsigned > >::iterator proc_nodes_touched_iterator
 Typedef for an iterator into the data structure above.
 
typedef std::map< unsigned, std::set< std::pair< unsigned, unsigned > > >::iterator proc_border_elem_sets_iterator
 Typedef for an iterator into the data structure above.
 

Private Member Functions

void compute_num_global_nodesets (const MeshBase &pmesh)
 This function uses global communication routines to determine the number of nodesets across the entire mesh.
 
void compute_num_global_sidesets (const MeshBase &pmesh)
 This function uses global communication routines to determine the number of sidesets across the entire mesh.
 
void compute_border_node_ids (const MeshBase &pmesh)
 This function constructs the set of border node IDs present on the current mesh.
 
void compute_internal_and_border_elems_and_internal_nodes (const MeshBase &pmesh)
 This function constructs the set of border and internal element IDs and internal node IDs present on the current mesh.
 
void compute_communication_map_parameters ()
 This function determines the communication map parameters which will eventually be written to file.
 
void compute_node_communication_maps ()
 Compute the node communication maps (really just pack vectors) in preparation for writing them to file.
 
void compute_node_maps ()
 Compute the node maps (really just pack vectors) which map the nodes to internal, border, and external nodes in the file.
 
void compute_elem_communication_maps ()
 This function computes element communication maps (really just packs vectors) in preparation for writing them to file.
 
void compute_element_maps ()
 This function computes element maps (really just packs vectors) which map the elements to internal and border elements.
 
void write_exodus_initialization_info (const MeshBase &pmesh, const std::string &title)
 This function writes exodus-specific initialization information.
 
dof_id_type get_libmesh_id (int exodus_id, const std::vector< int > &num_map)
 Internal implementation for the two sets of functions above.
 
void set_dof_object_unique_id (MeshBase &mesh, DofObject *dof_object, int exodus_mapped_id)
 
void write_var_names_impl (const char *var_type, int &count, const std::vector< std::string > &names)
 write_var_names() dispatches to this function.
 
void init_element_equivalence_map ()
 
void init_conversion_map ()
 

Private Attributes

std::map< subdomain_id_type, unsigned > local_subdomain_counts
 This map keeps track of the number of elements in each subdomain (block) for this processor.
 
std::set< unsigned > border_node_ids
 The set which will eventually contain the IDs of "border nodes".
 
std::map< unsigned, std::set< unsigned > > proc_nodes_touched_intersections
 Another map to store sets of intersections with each other processor (other than ourself, of course).
 
std::map< unsigned, std::set< std::pair< unsigned, unsigned > > > proc_border_elem_sets
 Map between processor ID and (element,side) pairs bordering that processor ID.
 
std::set< unsigned > internal_node_ids
 A set of internal node IDs for this processor.
 
std::set< unsigned > internal_elem_ids
 A set of internal elem IDs for this processor.
 
std::set< unsigned > border_elem_ids
 A set of border elem IDs for this processor.
 
bool _add_sides = false
 Set to true iff we want to write separate "side" elements too.
 
std::map< std::string, ElemTypeelement_equivalence_map
 Defines equivalence classes of Exodus element types that map to libmesh ElemTypes.
 
std::map< int, std::map< ElemType, ExodusII_IO_Helper::Conversion > > conversion_map
 Associates libMesh ElemTypes with node/face/edge/etc.
 

Detailed Description

This is the Nemesis_IO_Helper class.

Think of it as a big struct with storage for all the stuff one might want to pull from a Nemesis file. Derived from ExodusII_IO_Helper object, since Nemesis is based on the same file format.

Author
John W. Peterson
Roy Stogner
Date
2008
2020

Definition at line 52 of file nemesis_io_helper.h.

Member Typedef Documentation

◆ proc_border_elem_sets_iterator

typedef std::map<unsigned,std::set<std::pair<unsigned,unsigned>>>::iterator libMesh::Nemesis_IO_Helper::proc_border_elem_sets_iterator
private

Typedef for an iterator into the data structure above.

Definition at line 626 of file nemesis_io_helper.h.

◆ proc_nodes_touched_iterator

typedef std::map<unsigned,std::set<unsigned>>::iterator libMesh::Nemesis_IO_Helper::proc_nodes_touched_iterator
private

Typedef for an iterator into the data structure above.

Definition at line 616 of file nemesis_io_helper.h.

Member Enumeration Documentation

◆ ExodusVarType

Wraps calls to exII::ex_get_var_names() and exII::ex_get_var_param().

The enumeration controls whether nodal, elemental, global, etc. variable names are read and which class members are filled in. NODAL: num_nodal_vars nodal_var_names ELEMENTAL: num_elem_vars elem_var_names GLOBAL: num_global_vars global_var_names SIDESET: num_sideset_vars sideset_var_names NODESET: num_nodeset_vars nodeset_var_names

Enumerator
NODAL 
ELEMENTAL 
GLOBAL 
SIDESET 
NODESET 
ELEMSET 

Definition at line 951 of file exodusII_io_helper.h.

Constructor & Destructor Documentation

◆ Nemesis_IO_Helper()

libMesh::Nemesis_IO_Helper::Nemesis_IO_Helper ( const ParallelObject parent,
bool  verbose = false,
bool  single_precision = false 
)
explicit

Constructor.

Definition at line 77 of file nemesis_io_helper.C.

78 :
79 ExodusII_IO_Helper(parent, verbose_in, /*run_only_on_proc0=*/false, /*single_precision=*/single_precision),
86 num_proc(0),
88 ftype('\0'),
97{
98 // Warn about using untested code!
99 libmesh_experimental();
100}
ExodusII_IO_Helper(const ParallelObject &parent, bool v=false, bool run_only_on_proc0=true, bool single_precision=false)
Constructor.
int num_border_elems
The number of border FEM elements.
int num_external_nodes
The number of FEM nodes that reside on another processor but whose element partially resides on the c...
int num_internal_nodes
To be used with the Nemesis::ne_get_loadbal_param() routine.
int num_internal_elems
The number of internal FEM elements.
char ftype
The type of file to be written.
int num_border_nodes
The number of FEM nodes local to a processor but residing in an element which also has FEM nodes on o...
int num_proc_in_file
The number of processors for which the NEMESIS I file stores information.
int num_node_cmaps
The number of nodal communication maps for this processor.
int num_nodes_global
Global initial information.
bool write_complex_abs
By default, when complex numbers are enabled, for each variable we write out three values: the real p...
int num_elem_cmaps
The number of elemental communication maps for this processor.
int num_proc
The number of processors for which the NEMESIS I file was created.

◆ ~Nemesis_IO_Helper()

libMesh::Nemesis_IO_Helper::~Nemesis_IO_Helper ( )
virtual

Destructor.

Definition at line 103 of file nemesis_io_helper.C.

104{
105 // Our destructor is called from Nemesis_IO. We close the Exodus file here since we have
106 // responsibility for managing the file's lifetime. Only call ex_update() if the file was
107 // opened for writing!
108 if (this->opened_for_writing)
109 {
110 this->ex_err = exII::ex_update(this->ex_id);
111 EX_EXCEPTIONLESS_CHECK_ERR(ex_err, "Error flushing buffers to file.");
112 }
113 this->close();
114}
void close() noexcept
Closes the ExodusII mesh file.

References libMesh::ExodusII_IO_Helper::close(), libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, and libMesh::ExodusII_IO_Helper::opened_for_writing.

Member Function Documentation

◆ added_node_offset_on()

dof_id_type libMesh::ExodusII_IO_Helper::added_node_offset_on ( processor_id_type  p) const
inlineinherited

Definition at line 985 of file exodusII_io_helper.h.

986 {
988 const dof_id_type added_node_offsets =
989 (_added_side_node_offsets.empty() || !p) ? 0 :
991 return _true_node_offsets[p] + added_node_offsets;
992 }
std::vector< dof_id_type > _true_node_offsets
If we're adding "fake" sides to visualize SIDE_DISCONTINUOUS variables, we also need to know how many...
std::vector< dof_id_type > _added_side_node_offsets
If we're adding "fake" sides to visualize SIDE_DISCONTINUOUS variables, _added_side_node_offsets[p] g...
libmesh_assert(ctx)
uint8_t dof_id_type
Definition id_types.h:67

References libMesh::ExodusII_IO_Helper::_added_side_node_offsets, libMesh::ExodusII_IO_Helper::_true_node_offsets, and libMesh::libmesh_assert().

◆ build_element_and_node_maps()

void libMesh::Nemesis_IO_Helper::build_element_and_node_maps ( const MeshBase pmesh)

This function builds the libmesh -> exodus and exodus -> libmesh node and element maps.

These maps allow us to have a consistent numbering scheme within an Exodus file, given an existing globally consistent numbering scheme from LibMesh.

Definition at line 1649 of file nemesis_io_helper.C.

1650{
1651 // If we don't have any local subdomains, it had better be because
1652 // we don't have any local elements
1653#ifdef DEBUG
1654 if (local_subdomain_counts.empty())
1655 {
1656 libmesh_assert(pmesh.active_local_elements_begin() ==
1657 pmesh.active_local_elements_end());
1659 }
1660#endif
1661
1662 // Elements have to be numbered contiguously based on what block
1663 // number they are in. Therefore we have to do a bit of work to get
1664 // the block (ie subdomain) numbers first and store them off as
1665 // block_ids.
1666
1667 // Make sure there is no leftover information in the subdomain_map, and reserve
1668 // enough space to store the elements we need.
1669 this->subdomain_map.clear();
1670 for (const auto & [sbd_id, cnt] : local_subdomain_counts)
1671 {
1672 if (verbose)
1673 {
1674 libMesh::out << "[" << this->processor_id() << "] "
1675 << "local_subdomain_counts [" << static_cast<unsigned>(sbd_id) << "]= "
1676 << cnt
1677 << std::endl;
1678 }
1679
1680 this->subdomain_map[sbd_id].reserve(cnt);
1681 }
1682
1683
1684 // First loop over the elements to figure out which elements are in which subdomain
1685 for (const auto & elem : pmesh.active_local_element_ptr_range())
1686 {
1687 // Grab the nodes while we're here.
1688 for (auto n : elem->node_index_range())
1689 this->nodes_attached_to_local_elems.insert( elem->node_id(n) );
1690
1691 subdomain_id_type cur_subdomain = elem->subdomain_id();
1692
1693 this->subdomain_map[cur_subdomain].push_back(elem->id());
1694 }
1695
1696 // Set num_nodes which is used by exodusII_io_helper
1697 this->num_nodes =
1698 cast_int<int>(this->nodes_attached_to_local_elems.size());
1699
1700 // Now come up with a 1-based numbering for these nodes
1701 this->exodus_node_num_to_libmesh.clear(); // Make sure it's empty
1703
1704 // Also make sure there's no leftover information in the map which goes the
1705 // other direction.
1706 this->libmesh_node_num_to_exodus.clear();
1707
1708 // Set the map for nodes
1709 for (const auto & id : nodes_attached_to_local_elems)
1710 {
1711 // I.e. given exodus_node_id,
1712 // exodus_node_num_to_libmesh[ exodus_node_id ] returns the
1713 // libmesh ID for that node, plus one.
1714 // Here we index libMesh IDs with an offset of 1 because they're
1715 // the literal numbers that get written to the exodus file, but
1716 // we index Exodus IDs with an offset of 0 because we read that
1717 // exodus data into a C++ vector. Confused yet?
1718 this->exodus_node_num_to_libmesh.push_back(id+1);
1719
1720 // Likewise, given libmesh_node_id,
1721 // libmesh_node_num_to_exodus[ libmesh_node_id] returns the
1722 // *Exodus* ID for that node. Unlike the
1723 // exodus_node_num_to_libmesh vector above, this one is a
1724 // std::map. We're never handing a data buffer from it over to
1725 // another API so we don't need to do any weird offsets with it.
1726 this->libmesh_node_num_to_exodus[id] =
1727 this->exodus_node_num_to_libmesh.size(); // should never be zero...
1728 }
1729
1730 // Now we're going to loop over the subdomain map and build a few things right
1731 // now that we'll use later.
1732
1733 // First make sure our data structures don't have any leftover data...
1734 this->exodus_elem_num_to_libmesh.clear();
1735 this->block_ids.clear();
1736 this->libmesh_elem_num_to_exodus.clear();
1737
1738 // Now loop over each subdomain and get a unique numbering for the elements
1739 for (auto & [block_id, elem_ids_this_subdomain] : subdomain_map)
1740 {
1741 block_ids.push_back(block_id);
1742
1743 // The code below assumes this subdomain block is not empty, make sure that's the case!
1744 libmesh_error_msg_if(elem_ids_this_subdomain.size() == 0,
1745 "Error, no element IDs found in subdomain " << block_id);
1746
1747 // Use the first element in this block to get representative information.
1748 // Note that Exodus assumes all elements in a block are of the same type!
1749 // We are using that same assumption here!
1750 const auto & conv = get_conversion
1751 (pmesh.elem_ref(elem_ids_this_subdomain[0]).type());
1752 this->num_nodes_per_elem =
1753 pmesh.elem_ref(elem_ids_this_subdomain[0]).n_nodes();
1754
1755 // Get a reference to the connectivity vector for this subdomain. This vector
1756 // is most likely empty, we are going to fill it up now.
1757 std::vector<int> & current_block_connectivity = this->block_id_to_elem_connectivity[block_id];
1758
1759 // Just in case it's not already empty...
1760 current_block_connectivity.clear();
1761 current_block_connectivity.resize(elem_ids_this_subdomain.size() * this->num_nodes_per_elem);
1762
1763 for (auto i : index_range(elem_ids_this_subdomain))
1764 {
1765 auto elem_id = elem_ids_this_subdomain[i];
1766
1767 // Set the number map for elements
1768 // exodus_elem_num_to_libmesh[ exodus_node_id ] returns the
1769 // libmesh ID for that element, plus one.
1770 // Like with nodes above, we index libMesh IDs with an
1771 // offset of 1 because they're the literal numbers that get
1772 // written to the exodus file, but we index Exodus IDs with
1773 // an offset of 0 because we read that exodus data into a
1774 // C++ vector.
1775 this->exodus_elem_num_to_libmesh.push_back(elem_id+1);
1776
1777 // Likewise, given libmesh elem_id,
1778 // libmesh_elem_num_to_exodus[ elem_id ] returns the
1779 // *Exodus* ID for that node. Unlike the
1780 // exodus_elem_num_to_libmesh vector above, this one is a
1781 // std::map. We're never handing a data buffer from it over to
1782 // another API so we don't need to do any weird offsets with it.
1783 this->libmesh_elem_num_to_exodus[elem_id] =
1784 this->exodus_elem_num_to_libmesh.size();
1785
1786 const Elem & elem = pmesh.elem_ref(elem_id);
1787
1788 // Exodus/Nemesis want every block to have the same element type
1789 // libmesh_assert_equal_to (elem->type(), conv.libmesh_elem_type());
1790
1791 // But we can get away with writing e.g. HEX8 and INFHEX8 in
1792 // the same block...
1793 libmesh_assert_equal_to (elem.n_nodes(), Elem::build(conv.libmesh_elem_type(), nullptr)->n_nodes());
1794
1795 for (auto j : make_range(this->num_nodes_per_elem))
1796 {
1797 const unsigned int connect_index = (i*this->num_nodes_per_elem)+j;
1798 const unsigned int elem_node_index = conv.get_inverse_node_map(j); // inverse node map is used for writing
1799
1800 current_block_connectivity[connect_index] =
1801 libmesh_map_find(libmesh_node_num_to_exodus,
1802 elem.node_id(elem_node_index));
1803 }
1804 } // End loop over elems in this subdomain
1805 } // end loop over subdomain_map
1806}
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
Definition elem.C:442
std::vector< int > exodus_node_num_to_libmesh
std::vector< int > exodus_elem_num_to_libmesh
std::map< dof_id_type, dof_id_type > libmesh_elem_num_to_exodus
std::map< dof_id_type, dof_id_type > libmesh_node_num_to_exodus
const ExodusII_IO_Helper::Conversion & get_conversion(const ElemType type) const
std::map< subdomain_id_type, unsigned > local_subdomain_counts
This map keeps track of the number of elements in each subdomain (block) for this processor.
std::map< subdomain_id_type, std::vector< dof_id_type > > subdomain_map
Map of subdomains to element numbers.
std::set< int > nodes_attached_to_local_elems
libMesh numbered node ids attached to local elems.
std::map< int, std::vector< int > > block_id_to_elem_connectivity
This is the block connectivity, i.e.
processor_id_type processor_id() const
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition int_range.h:153
OStreamProxy out
TestClass subdomain_id_type
Based on the 4-byte comment warning above, this probably doesn't work with exodusII at all....
Definition id_types.h:43
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

References block_id_to_elem_connectivity, libMesh::ExodusII_IO_Helper::block_ids, libMesh::Elem::build(), libMesh::MeshBase::elem_ref(), libMesh::ExodusII_IO_Helper::exodus_elem_num_to_libmesh, libMesh::ExodusII_IO_Helper::exodus_node_num_to_libmesh, libMesh::ExodusII_IO_Helper::get_conversion(), libMesh::index_range(), libMesh::libmesh_assert(), libMesh::ExodusII_IO_Helper::libmesh_elem_num_to_exodus, libMesh::ExodusII_IO_Helper::libmesh_node_num_to_exodus, local_subdomain_counts, libMesh::make_range(), libMesh::Elem::n_nodes(), libMesh::Elem::node_id(), nodes_attached_to_local_elems, libMesh::ExodusII_IO_Helper::num_nodes, libMesh::ExodusII_IO_Helper::num_nodes_per_elem, libMesh::out, libMesh::ParallelObject::processor_id(), subdomain_map, libMesh::Elem::type(), and libMesh::ExodusII_IO_Helper::verbose.

Referenced by initialize().

◆ check_existing_vars()

void libMesh::ExodusII_IO_Helper::check_existing_vars ( ExodusVarType  type,
std::vector< std::string > &  names,
std::vector< std::string > &  names_from_file 
)
protectedinherited

When appending: during initialization, check that variable names in the file match those you attempt to initialize with.

Definition at line 4022 of file exodusII_io_helper.C.

4025{
4026 // There may already be global variables in the file (for example,
4027 // if we're appending) and in that case, we
4028 // 1.) Cannot initialize them again.
4029 // 2.) Should check to be sure that the global variable names are the same.
4030
4031 // Fills up names_from_file for us
4032 this->read_var_names(type);
4033
4034 // Both the number of variables and their names (up to the first
4035 // MAX_STR_LENGTH characters) must match for the names we are
4036 // planning to write and the names already in the file.
4037 bool match =
4038 std::equal(names.begin(), names.end(),
4039 names_from_file.begin(),
4040 [this](const std::string & a,
4041 const std::string & b) -> bool
4042 {
4043 return a.compare(/*pos=*/0, /*len=*/_max_name_length, b) == 0;
4044 });
4045
4046 if (!match)
4047 {
4048 libMesh::err << "Error! The Exodus file already contains the variables:" << std::endl;
4049 for (const auto & name : names_from_file)
4050 libMesh::err << name << std::endl;
4051
4052 libMesh::err << "And you asked to write:" << std::endl;
4053 for (const auto & name : names)
4054 libMesh::err << name << std::endl;
4055
4056 libmesh_error_msg("Cannot overwrite existing variables in Exodus II file.");
4057 }
4058}
void read_var_names(ExodusVarType type)
static const Real b
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
The libMesh namespace provides an interface to certain functionality in the library.
OStreamProxy err

References b, libMesh::err, and libMesh::ExodusII_IO_Helper::read_var_names().

Referenced by libMesh::ExodusII_IO_Helper::initialize_element_variables(), initialize_element_variables(), libMesh::ExodusII_IO_Helper::initialize_global_variables(), and libMesh::ExodusII_IO_Helper::initialize_nodal_variables().

◆ close()

void libMesh::ExodusII_IO_Helper::close ( )
noexceptinherited

Closes the ExodusII mesh file.

This function is called from the ExodusII_IO destructor, so it should not throw an exception.

Definition at line 2040 of file exodusII_io_helper.C.

2041{
2042 // Call ex_close on every processor that did ex_open or ex_create;
2043 // newer Exodus versions error if we try to reopen a file that
2044 // hasn't been officially closed. Don't close the file if we didn't
2045 // open it; this also raises an Exodus error.
2046
2047 // We currently do read-only ex_open on every proc (to do read
2048 // operations on every proc), but we do ex_open and ex_create for
2049 // writes on every proc only with Nemesis files.
2051 (this->processor_id() == 0) ||
2053 {
2055 {
2056 ex_err = exII::ex_close(ex_id);
2057 // close() is called from the destructor, so it may be called e.g.
2058 // during stack unwinding while processing an exception. In that case
2059 // we don't want to throw another exception or immediately terminate
2060 // the code, since that would prevent any possible recovery from the
2061 // exception in question. So we just log the error closing the file
2062 // and continue.
2063 if (ex_err < 0)
2064 message("Error closing Exodus file.");
2065 else
2066 message("Exodus file closed successfully.");
2067 }
2068 }
2069
2070 // Now that the file is closed, it's no longer opened for
2071 // reading or writing.
2072 opened_for_writing = false;
2073 opened_for_reading = false;
2074 _opened_by_create = false;
2075}
void message(std::string_view msg)
Prints the message defined in msg.

References libMesh::ExodusII_IO_Helper::_opened_by_create, libMesh::ExodusII_IO_Helper::_run_only_on_proc0, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::message(), libMesh::ExodusII_IO_Helper::opened_for_reading, libMesh::ExodusII_IO_Helper::opened_for_writing, and libMesh::ParallelObject::processor_id().

Referenced by ~Nemesis_IO_Helper().

◆ 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(), compute_num_global_elem_blocks(), compute_num_global_nodesets(), 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(), libMesh::ExodusII_IO::copy_elemental_solution(), libMesh::ExodusII_IO::copy_nodal_solution(), libMesh::ExodusII_IO::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(), libMesh::ExodusII_IO::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(), 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().

◆ compute_border_node_ids()

void libMesh::Nemesis_IO_Helper::compute_border_node_ids ( const MeshBase pmesh)
private

This function constructs the set of border node IDs present on the current mesh.

These are nodes which live on the "border" between elements which live on different processors.

Definition at line 1812 of file nemesis_io_helper.C.

1813{
1814 // The set which will eventually contain the IDs of "border nodes". These are nodes
1815 // that lie on the boundary between one or more processors.
1816 //std::set<unsigned> border_node_ids;
1817
1818 // map from processor ID to set of nodes which elements from this processor "touch",
1819 // that is,
1820 // proc_nodes_touched[p] = (set all node IDs found in elements owned by processor p)
1821 std::map<unsigned, std::set<unsigned>> proc_nodes_touched;
1822
1823
1824 // We are going to create a lot of intermediate data structures here, so make sure
1825 // as many as possible all cleaned up by creating scope!
1826 {
1827 // Loop over active (not just active local) elements, make sets of node IDs for each
1828 // processor which has an element that "touches" a node.
1829 for (const auto & elem : pmesh.active_element_ptr_range())
1830 {
1831 // Get reference to the set for this processor. If it does not exist
1832 // it will be created.
1833 std::set<unsigned> & set_p = proc_nodes_touched[ elem->processor_id() ];
1834
1835 // Insert all nodes touched by this element into the set
1836 for (auto node : elem->node_index_range())
1837 set_p.insert(elem->node_id(node));
1838 }
1839
1840 if (verbose)
1841 {
1842 libMesh::out << "[" << this->processor_id()
1843 << "] proc_nodes_touched contains "
1844 << proc_nodes_touched.size()
1845 << " sets of nodes."
1846 << std::endl;
1847
1848 for (const auto & [proc_id, set] : proc_nodes_touched)
1849 libMesh::out << "[" << this->processor_id()
1850 << "] proc_nodes_touched[" << proc_id << "] has "
1851 << set.size()
1852 << " entries."
1853 << std::endl;
1854 }
1855
1856
1857 // Loop over all the sets we just created and compute intersections with the
1858 // this processor's set. Obviously, don't intersect with ourself.
1860 for (auto & [proc_id, other_set] : proc_nodes_touched)
1861 {
1862 // Don't compute intersections with ourself
1863 if (proc_id == this->processor_id())
1864 continue;
1865
1866 std::set<unsigned int> this_intersection;
1867
1868 // Otherwise, compute intersection with other processor and ourself
1869 std::set<unsigned> & my_set = proc_nodes_touched[this->processor_id()];
1870
1871 std::set_intersection(my_set.begin(), my_set.end(),
1872 other_set.begin(), other_set.end(),
1873 std::inserter(this_intersection, this_intersection.end()));
1874
1875 if (!this_intersection.empty())
1877 (proc_id, std::move(this_intersection));
1878 }
1879
1880 if (verbose)
1881 {
1882 for (const auto & [proc_id, set] : proc_nodes_touched_intersections)
1883 libMesh::out << "[" << this->processor_id()
1884 << "] this->proc_nodes_touched_intersections[" << proc_id << "] has "
1885 << set.size()
1886 << " entries."
1887 << std::endl;
1888 }
1889
1890 // The number of node communication maps is the number of other processors
1891 // with which we share nodes.
1892 this->num_node_cmaps =
1893 cast_int<int>(proc_nodes_touched_intersections.size());
1894
1895 // We can't be connecting to more processors than exist outside
1896 // ourselves
1897 libmesh_assert_less (this->num_node_cmaps, this->n_processors());
1898
1899 // Compute the set_union of all the preceding intersections. This will be the set of
1900 // border node IDs for this processor.
1901 for (auto & pr : proc_nodes_touched_intersections)
1902 {
1903 std::set<unsigned> & other_set = pr.second;
1904 std::set<unsigned> intermediate_result; // Don't think we can insert into one of the sets we're unioning...
1905
1906 std::set_union(this->border_node_ids.begin(), this->border_node_ids.end(),
1907 other_set.begin(), other_set.end(),
1908 std::inserter(intermediate_result, intermediate_result.end()));
1909
1910 // Swap our intermediate result into the final set
1911 this->border_node_ids.swap(intermediate_result);
1912 }
1913
1914 libmesh_assert_less_equal
1916 std::size_t(this->num_node_cmaps));
1917
1918 if (verbose)
1919 {
1920 libMesh::out << "[" << this->processor_id()
1921 << "] border_node_ids.size()=" << this->border_node_ids.size()
1922 << std::endl;
1923 }
1924 } // end scope for border node ID creation
1925
1926 // Store the number of border node IDs to be written to Nemesis file
1927 this->num_border_nodes = cast_int<int>(this->border_node_ids.size());
1928}
std::map< unsigned, std::set< unsigned > > proc_nodes_touched_intersections
Another map to store sets of intersections with each other processor (other than ourself,...
std::set< unsigned > border_node_ids
The set which will eventually contain the IDs of "border nodes".
processor_id_type n_processors() const

References border_node_ids, libMesh::ParallelObject::n_processors(), num_border_nodes, num_node_cmaps, libMesh::out, proc_nodes_touched_intersections, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::verbose.

Referenced by initialize().

◆ compute_communication_map_parameters()

void libMesh::Nemesis_IO_Helper::compute_communication_map_parameters ( )
private

This function determines the communication map parameters which will eventually be written to file.

Definition at line 1129 of file nemesis_io_helper.C.

1130{
1131 // For the nodes, these are the number of entries in the sets in proc_nodes_touched_intersections
1132 // map computed above. Note: this map does not contain self-intersections so we can loop over it
1133 // directly.
1134 this->node_cmap_node_cnts.clear(); // Make sure we don't have any leftover information...
1135 this->node_cmap_ids.clear(); // Make sure we don't have any leftover information...
1136 this->node_cmap_node_cnts.resize(this->num_node_cmaps);
1137 this->node_cmap_ids.resize(this->num_node_cmaps);
1138
1139 {
1140 unsigned cnt=0; // Index into the vector
1142 it = this->proc_nodes_touched_intersections.begin(),
1143 end = this->proc_nodes_touched_intersections.end();
1144
1145 for (; it != end; ++it)
1146 {
1147 this->node_cmap_ids[cnt] = it->first; // The ID of the proc we communicate with
1148 this->node_cmap_node_cnts[cnt] = cast_int<int>(it->second.size()); // The number of nodes we communicate
1149 cnt++; // increment vector index!
1150 }
1151 }
1152
1153 // Print the packed vectors we just filled
1154 if (verbose)
1155 {
1156 libMesh::out << "[" << this->processor_id() << "] node_cmap_node_cnts = ";
1157 for (const auto & node_cnt : node_cmap_node_cnts)
1158 libMesh::out << node_cnt << ", ";
1159 libMesh::out << std::endl;
1160
1161 libMesh::out << "[" << this->processor_id() << "] node_cmap_ids = ";
1162 for (const auto & node_id : node_cmap_ids)
1163 libMesh::out << node_id << ", ";
1164 libMesh::out << std::endl;
1165 }
1166
1167 // For the elements, we have not yet computed all this information..
1168 this->elem_cmap_elem_cnts.clear(); // Make sure we don't have any leftover information...
1169 this->elem_cmap_ids.clear(); // Make sure we don't have any leftover information...
1170 this->elem_cmap_elem_cnts.resize(this->num_elem_cmaps);
1171 this->elem_cmap_ids.resize(this->num_elem_cmaps);
1172
1173 // Pack the elem_cmap_ids and elem_cmap_elem_cnts vectors
1174 {
1175 unsigned cnt=0; // Index into the vectors we're filling
1177 it = this->proc_border_elem_sets.begin(),
1178 end = this->proc_border_elem_sets.end();
1179
1180 for (; it != end; ++it)
1181 {
1182 this->elem_cmap_ids[cnt] = it->first; // The ID of the proc we communicate with
1183 this->elem_cmap_elem_cnts[cnt] = cast_int<int>(it->second.size()); // The number of elems we communicate to/from that proc
1184 cnt++; // increment vector index!
1185 }
1186 }
1187
1188 // Print the packed vectors we just filled
1189 if (verbose)
1190 {
1191 libMesh::out << "[" << this->processor_id() << "] elem_cmap_elem_cnts = ";
1192 for (const auto & elem_cnt : elem_cmap_elem_cnts)
1193 libMesh::out << elem_cnt << ", ";
1194 libMesh::out << std::endl;
1195
1196 libMesh::out << "[" << this->processor_id() << "] elem_cmap_ids = ";
1197 for (const auto & elem_id : elem_cmap_ids)
1198 libMesh::out << elem_id << ", ";
1199 libMesh::out << std::endl;
1200 }
1201}
std::vector< int > elem_cmap_elem_cnts
std::map< unsigned, std::set< unsigned > >::iterator proc_nodes_touched_iterator
Typedef for an iterator into the data structure above.
std::vector< int > node_cmap_node_cnts
std::vector< int > node_cmap_ids
Vectors for storing the communication map parameters.
std::vector< int > elem_cmap_ids
std::map< unsigned, std::set< std::pair< unsigned, unsigned > > >::iterator proc_border_elem_sets_iterator
Typedef for an iterator into the data structure above.
std::map< unsigned, std::set< std::pair< unsigned, unsigned > > > proc_border_elem_sets
Map between processor ID and (element,side) pairs bordering that processor ID.

References elem_cmap_elem_cnts, elem_cmap_ids, node_cmap_ids, node_cmap_node_cnts, num_elem_cmaps, num_node_cmaps, libMesh::out, proc_border_elem_sets, proc_nodes_touched_intersections, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::verbose.

Referenced by initialize().

◆ compute_elem_communication_maps()

void libMesh::Nemesis_IO_Helper::compute_elem_communication_maps ( )
private

This function computes element communication maps (really just packs vectors) in preparation for writing them to file.

Definition at line 977 of file nemesis_io_helper.C.

978{
979 // Make sure there is no leftover information
980 this->elem_cmap_elem_ids.clear();
981 this->elem_cmap_side_ids.clear();
982 this->elem_cmap_proc_ids.clear();
983
984 // Allocate enough space for all our element maps
985 this->elem_cmap_elem_ids.resize(this->num_elem_cmaps);
986 this->elem_cmap_side_ids.resize(this->num_elem_cmaps);
987 this->elem_cmap_proc_ids.resize(this->num_elem_cmaps);
988 {
989 unsigned cnt=0; // Index into vectors
991 it = this->proc_border_elem_sets.begin(),
992 end = this->proc_border_elem_sets.end();
993
994 for (; it != end; ++it)
995 {
996 // Make sure the current elem_cmap_id matches the index in our map of node intersections
997 libmesh_assert_equal_to (static_cast<unsigned>(this->elem_cmap_ids[cnt]), it->first);
998
999 // Get reference to the set of IDs to be packed into the vector
1000 std::set<std::pair<unsigned,unsigned>> & elem_set = it->second;
1001
1002 // Resize the vectors to receive their payload
1003 this->elem_cmap_elem_ids[cnt].resize(elem_set.size());
1004 this->elem_cmap_side_ids[cnt].resize(elem_set.size());
1005 this->elem_cmap_proc_ids[cnt].resize(elem_set.size());
1006
1007 std::set<std::pair<unsigned,unsigned>>::iterator elem_set_iter = elem_set.begin();
1008
1009 // Pack the vectors with elem IDs, side IDs, and processor IDs.
1010 for (std::size_t j=0, eceis=this->elem_cmap_elem_ids[cnt].size(); j<eceis; ++j, ++elem_set_iter)
1011 {
1012 this->elem_cmap_elem_ids[cnt][j] =
1013 libmesh_map_find(libmesh_elem_num_to_exodus, elem_set_iter->first);
1014 this->elem_cmap_side_ids[cnt][j] = elem_set_iter->second; // Side ID, this has already been converted above
1015 this->elem_cmap_proc_ids[cnt][j] = it->first; // All have the same processor ID
1016 }
1017
1018 // increment vector index to go to next processor
1019 cnt++;
1020 }
1021 } // end scope for packing
1022}
std::vector< std::vector< int > > elem_cmap_proc_ids
std::vector< std::vector< int > > elem_cmap_elem_ids
3 vectors of vectors for storing element communication IDs for this processor.
std::vector< std::vector< int > > elem_cmap_side_ids

References elem_cmap_elem_ids, elem_cmap_ids, elem_cmap_proc_ids, elem_cmap_side_ids, libMesh::ExodusII_IO_Helper::libmesh_elem_num_to_exodus, num_elem_cmaps, and proc_border_elem_sets.

Referenced by initialize().

◆ compute_element_maps()

void libMesh::Nemesis_IO_Helper::compute_element_maps ( )
private

This function computes element maps (really just packs vectors) which map the elements to internal and border elements.

Definition at line 952 of file nemesis_io_helper.C.

953{
954 // Make sure we don't have any leftover info
955 this->elem_mapi.clear();
956 this->elem_mapb.clear();
957
958 // Copy set contents into vectors
959 this->elem_mapi.resize(this->internal_elem_ids.size());
960 this->elem_mapb.resize(this->border_elem_ids.size());
961
962 {
963 unsigned cnt = 0;
964 for (const auto & id : this->internal_elem_ids)
965 this->elem_mapi[cnt++] = libmesh_map_find(libmesh_elem_num_to_exodus, id);
966 }
967
968 {
969 unsigned cnt = 0;
970 for (const auto & id : this->border_elem_ids)
971 this->elem_mapb[cnt++] = libmesh_map_find(libmesh_elem_num_to_exodus, id);
972 }
973}
std::set< unsigned > internal_elem_ids
A set of internal elem IDs for this processor.
std::vector< int > elem_mapb
Vector which stores border element IDs.
std::set< unsigned > border_elem_ids
A set of border elem IDs for this processor.
std::vector< int > elem_mapi
Vector which stores internal element IDs.

References border_elem_ids, elem_mapb, elem_mapi, internal_elem_ids, and libMesh::ExodusII_IO_Helper::libmesh_elem_num_to_exodus.

Referenced by initialize().

◆ compute_internal_and_border_elems_and_internal_nodes()

void libMesh::Nemesis_IO_Helper::compute_internal_and_border_elems_and_internal_nodes ( const MeshBase pmesh)
private

This function constructs the set of border and internal element IDs and internal node IDs present on the current mesh.

Definition at line 1207 of file nemesis_io_helper.C.

1208{
1209 // Set of all local, active element IDs. After we have identified border element
1210 // IDs, the set_difference between this set and the border_elem_ids set will give us
1211 // the set of internal_elem_ids.
1212 std::set<unsigned> all_elem_ids;
1213
1214 // A set of processor IDs which elements on this processor have as
1215 // neighbors. The size of this set will determine the number of
1216 // element communication maps in Exodus.
1217 std::set<unsigned> neighboring_processor_ids;
1218
1219 for (const auto & elem : pmesh.active_local_element_ptr_range())
1220 {
1221 // Add this Elem's ID to all_elem_ids, later we will take the difference
1222 // between this set and the set of border_elem_ids, to get the set of
1223 // internal_elem_ids.
1224 all_elem_ids.insert(elem->id());
1225
1226 // Will be set to true if element is determined to be a border element
1227 bool is_border_elem = false;
1228
1229 // Construct a conversion object for this Element. This will help us map
1230 // Libmesh numberings into Nemesis numberings for sides.
1231 const auto & conv = get_conversion(elem->type());
1232
1233 // Add all this element's node IDs to the set of all node IDs.
1234 // The set of internal_node_ids will be the set difference between
1235 // the set of all nodes and the set of border nodes.
1236 //
1237 // In addition, if any node of a local node is listed in the
1238 // border nodes list, then this element goes into the proc_border_elem_sets.
1239 // Note that there is not a 1:1 correspondence between
1240 // border_elem_ids and the entries which go into proc_border_elem_sets.
1241 // The latter is for communication purposes, ie determining which elements
1242 // should be shared between processors.
1243 for (auto node : elem->node_index_range())
1244 this->nodes_attached_to_local_elems.insert(elem->node_id(node));
1245
1246 // Loop over element's neighbors, see if it has a neighbor which is off-processor
1247 for (auto n : elem->side_index_range())
1248 {
1249 if (elem->neighbor_ptr(n) != nullptr)
1250 {
1251 unsigned neighbor_proc_id = elem->neighbor_ptr(n)->processor_id();
1252
1253 // If my neighbor has a different processor ID, I must be a border element.
1254 // Also track the neighboring processor ID if it is are different from our processor ID
1255 if (neighbor_proc_id != this->processor_id())
1256 {
1257 is_border_elem = true;
1258 neighboring_processor_ids.insert(neighbor_proc_id);
1259
1260 // Convert libmesh side(n) of this element into a side ID for Nemesis
1261 unsigned nemesis_side_id = conv.get_inverse_side_map(n);
1262
1263 if (verbose)
1264 libMesh::out << "[" << this->processor_id() << "] LibMesh side "
1265 << n
1266 << " mapped to (1-based) Exodus side "
1267 << nemesis_side_id
1268 << std::endl;
1269
1270 // Add this element's ID and the ID of the side which is on the boundary
1271 // to the set of border elements for this processor.
1272 // Note: if the set does not already exist, this creates it.
1273 this->proc_border_elem_sets[ neighbor_proc_id ].emplace(elem->id(), nemesis_side_id);
1274 }
1275 }
1276 } // end for loop over neighbors
1277
1278 // If we're on a border element, add it to the set
1279 if (is_border_elem)
1280 this->border_elem_ids.insert( elem->id() );
1281
1282 } // end for loop over active local elements
1283
1284 // Take the set_difference between all elements and border elements to get internal
1285 // element IDs
1286 std::set_difference(all_elem_ids.begin(), all_elem_ids.end(),
1287 this->border_elem_ids.begin(), this->border_elem_ids.end(),
1288 std::inserter(this->internal_elem_ids, this->internal_elem_ids.end()));
1289
1290 // Take the set_difference between all nodes and border nodes to get internal nodes
1291 std::set_difference(this->nodes_attached_to_local_elems.begin(), this->nodes_attached_to_local_elems.end(),
1292 this->border_node_ids.begin(), this->border_node_ids.end(),
1293 std::inserter(this->internal_node_ids, this->internal_node_ids.end()));
1294
1295 if (verbose)
1296 {
1297 libMesh::out << "[" << this->processor_id() << "] neighboring_processor_ids = ";
1298 for (const auto & id : neighboring_processor_ids)
1299 libMesh::out << id << " ";
1300 libMesh::out << std::endl;
1301 }
1302
1303 // The size of the neighboring_processor_ids set should be the number of element communication maps
1304 this->num_elem_cmaps =
1305 cast_int<int>(neighboring_processor_ids.size());
1306
1307 if (verbose)
1308 libMesh::out << "[" << this->processor_id() << "] "
1309 << "Number of neighboring processor IDs="
1310 << this->num_elem_cmaps
1311 << std::endl;
1312
1313 if (verbose)
1314 {
1315 // Print out counts of border elements for each processor
1316 for (const auto & [proc_id, set] : proc_border_elem_sets)
1317 {
1318 libMesh::out << "[" << this->processor_id() << "] "
1319 << "Proc "
1320 << proc_id << " communicates "
1321 << set.size() << " elements." << std::endl;
1322 }
1323 }
1324
1325 // Store the number of internal and border elements, and the number of internal nodes,
1326 // to be written to the Nemesis file.
1327 this->num_internal_elems =
1328 cast_int<int>(this->internal_elem_ids.size());
1329 this->num_border_elems =
1330 cast_int<int>(this->border_elem_ids.size());
1331 this->num_internal_nodes =
1332 cast_int<int>(this->internal_node_ids.size());
1333
1334 if (verbose)
1335 {
1336 libMesh::out << "[" << this->processor_id() << "] num_internal_nodes=" << this->num_internal_nodes << std::endl;
1337 libMesh::out << "[" << this->processor_id() << "] num_border_nodes=" << this->num_border_nodes << std::endl;
1338 libMesh::out << "[" << this->processor_id() << "] num_border_elems=" << this->num_border_elems << std::endl;
1339 libMesh::out << "[" << this->processor_id() << "] num_internal_elems=" << this->num_internal_elems << std::endl;
1340 }
1341}
std::set< unsigned > internal_node_ids
A set of internal node IDs for this processor.

References border_elem_ids, libMesh::ExodusII_IO_Helper::get_conversion(), internal_elem_ids, internal_node_ids, nodes_attached_to_local_elems, num_border_elems, num_border_nodes, num_elem_cmaps, num_internal_elems, num_internal_nodes, libMesh::out, proc_border_elem_sets, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::verbose.

Referenced by initialize().

◆ compute_node_communication_maps()

void libMesh::Nemesis_IO_Helper::compute_node_communication_maps ( )
private

Compute the node communication maps (really just pack vectors) in preparation for writing them to file.

Definition at line 1057 of file nemesis_io_helper.C.

1058{
1059 // Make sure there's no left-over information
1060 this->node_cmap_node_ids.clear();
1061 this->node_cmap_proc_ids.clear();
1062
1063 libmesh_assert_less_equal
1065 std::size_t(this->num_node_cmaps));
1066
1067 // Allocate enough space for all our node maps
1068 this->node_cmap_node_ids.resize(this->num_node_cmaps);
1069 this->node_cmap_proc_ids.resize(this->num_node_cmaps);
1070 {
1071 unsigned cnt=0; // Index into vectors
1073 it = this->proc_nodes_touched_intersections.begin(),
1074 end = this->proc_nodes_touched_intersections.end();
1075
1076 for (; it != end; ++it)
1077 {
1078 // Make sure the current node_cmap_id matches the index in our map of node intersections
1079 libmesh_assert_equal_to (static_cast<unsigned>(this->node_cmap_ids[cnt]), it->first);
1080
1081 // Get reference to the set of IDs to be packed into the vector.
1082 std::set<unsigned> & node_set = it->second;
1083
1084 // Resize the vectors to receive their payload
1085 this->node_cmap_node_ids[cnt].resize(node_set.size());
1086 this->node_cmap_proc_ids[cnt].resize(node_set.size());
1087
1088 std::set<unsigned>::iterator node_set_iter = node_set.begin();
1089
1090 // Pack the vectors with node IDs and processor IDs.
1091 for (std::size_t j=0, nceis=this->node_cmap_node_ids[cnt].size(); j<nceis; ++j, ++node_set_iter)
1092 {
1093 this->node_cmap_node_ids[cnt][j] =
1094 libmesh_map_find(libmesh_node_num_to_exodus, *node_set_iter);
1095 this->node_cmap_proc_ids[cnt][j] = it->first;
1096 }
1097
1098 // increment vector index to go to next processor
1099 cnt++;
1100 }
1101 } // end scope for packing
1102
1103 // Print out the vectors we just packed
1104 if (verbose)
1105 {
1106 for (auto i : index_range(this->node_cmap_node_ids))
1107 {
1108 libMesh::out << "[" << this->processor_id() << "] nodes communicated to proc "
1109 << this->node_cmap_ids[i]
1110 << " = ";
1111 for (const auto & node_id : this->node_cmap_node_ids[i])
1112 libMesh::out << node_id << " ";
1113 libMesh::out << std::endl;
1114 }
1115
1116 for (const auto & id_vec : this->node_cmap_node_ids)
1117 {
1118 libMesh::out << "[" << this->processor_id() << "] processor ID node communicated to = ";
1119 for (const auto & proc_id : id_vec)
1120 libMesh::out << proc_id << " ";
1121 libMesh::out << std::endl;
1122 }
1123 }
1124}
std::vector< std::vector< int > > node_cmap_proc_ids
std::vector< std::vector< int > > node_cmap_node_ids
2 vectors of vectors for storing the node communication IDs for this processor.
std::unordered_set< const Node * > & node_set

References libMesh::index_range(), libMesh::ExodusII_IO_Helper::libmesh_node_num_to_exodus, node_cmap_ids, node_cmap_node_ids, node_cmap_proc_ids, node_set, num_node_cmaps, libMesh::out, proc_nodes_touched_intersections, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::verbose.

Referenced by initialize().

◆ compute_node_maps()

void libMesh::Nemesis_IO_Helper::compute_node_maps ( )
private

Compute the node maps (really just pack vectors) which map the nodes to internal, border, and external nodes in the file.

Definition at line 1028 of file nemesis_io_helper.C.

1029{
1030 // Make sure we don't have any leftover information
1031 this->node_mapi.clear();
1032 this->node_mapb.clear();
1033 this->node_mape.clear();
1034
1035 // Make sure there's enough space to hold all our node IDs
1036 this->node_mapi.resize(this->internal_node_ids.size());
1037 this->node_mapb.resize(this->border_node_ids.size());
1038
1039 // Copy set contents into vectors
1040 {
1041 unsigned cnt = 0;
1042 for (const auto & id : this->internal_node_ids)
1043 this->node_mapi[cnt++] = libmesh_map_find(libmesh_node_num_to_exodus, id);
1044 }
1045
1046 {
1047 unsigned cnt=0;
1048 for (const auto & id : this->border_node_ids)
1049 this->node_mapb[cnt++] = libmesh_map_find(libmesh_node_num_to_exodus, id);
1050 }
1051}
std::vector< int > node_mape
Vector which stores external node IDs.
std::vector< int > node_mapb
Vector which stores border node IDs.
std::vector< int > node_mapi
Vector which stores internal node IDs.

References border_node_ids, internal_node_ids, libMesh::ExodusII_IO_Helper::libmesh_node_num_to_exodus, node_mapb, node_mape, and node_mapi.

Referenced by initialize().

◆ compute_num_global_elem_blocks()

void libMesh::Nemesis_IO_Helper::compute_num_global_elem_blocks ( const MeshBase pmesh)

This function uses global communication routines to determine the number of element blocks across the entire mesh.

Definition at line 1549 of file nemesis_io_helper.C.

1550{
1551 // 1.) Loop over active local elements, build up set of subdomain IDs.
1552 std::set<subdomain_id_type> global_subdomain_ids;
1553
1554 // This map keeps track of the number of elements in each subdomain over all processors
1555 std::map<subdomain_id_type, unsigned> global_subdomain_counts;
1556
1557 for (const auto & elem : pmesh.active_local_element_ptr_range())
1558 {
1559 subdomain_id_type cur_subdomain = elem->subdomain_id();
1560
1561 /*
1562 // We can't have a zero subdomain ID in Exodus (for some reason?)
1563 // so map zero subdomains to a max value...
1564 if (cur_subdomain == 0)
1565 cur_subdomain = std::numeric_limits<subdomain_id_type>::max();
1566 */
1567
1568 global_subdomain_ids.insert(cur_subdomain);
1569
1570 // Increment the count of elements in this subdomain
1571 global_subdomain_counts[cur_subdomain]++;
1572 }
1573
1574 // We're next going to this->comm().sum the subdomain counts, so save the local counts
1575 this->local_subdomain_counts = global_subdomain_counts;
1576
1577 {
1578 // 2.) Copy local subdomain IDs into a vector for communication
1579 std::vector<subdomain_id_type> global_subdomain_ids_vector(global_subdomain_ids.begin(),
1580 global_subdomain_ids.end());
1581
1582 // 3.) Gather them into an enlarged vector
1583 this->comm().allgather(global_subdomain_ids_vector);
1584
1585 // 4.) Insert any new IDs into the set (any duplicates will be dropped)
1586 global_subdomain_ids.insert(global_subdomain_ids_vector.begin(),
1587 global_subdomain_ids_vector.end());
1588 }
1589
1590 // 5.) Now global_subdomain_ids actually contains a global list of all subdomain IDs
1591 this->num_elem_blks_global =
1592 cast_int<int>(global_subdomain_ids.size());
1593
1594 // Print the number of elements found locally in each subdomain
1595 if (verbose)
1596 {
1597 libMesh::out << "[" << this->processor_id() << "] ";
1598 for (const auto & [subdomain_id, cnt] : global_subdomain_counts)
1599 {
1600 libMesh::out << "ID: "
1601 << static_cast<unsigned>(subdomain_id)
1602 << ", Count: " << cnt << ", ";
1603 }
1604 libMesh::out << std::endl;
1605 }
1606
1607 // 6.) this->comm().sum up the number of elements in each block. We know the global
1608 // subdomain IDs, so pack them into a vector one by one. Use a vector of int since
1609 // that is what Nemesis wants
1610 this->global_elem_blk_cnts.resize(global_subdomain_ids.size());
1611
1612 unsigned cnt=0;
1613 // Find the entry in the local map, note: if not found, will be created with 0 default value, which is OK...
1614 for (const auto & id : global_subdomain_ids)
1615 this->global_elem_blk_cnts[cnt++] = global_subdomain_counts[id];
1616
1617 // Sum up subdomain counts from all processors
1618 this->comm().sum(this->global_elem_blk_cnts);
1619
1620 if (verbose)
1621 {
1622 libMesh::out << "[" << this->processor_id() << "] global_elem_blk_cnts = ";
1623 for (const auto & bc : this->global_elem_blk_cnts)
1624 libMesh::out << bc << ", ";
1625 libMesh::out << std::endl;
1626 }
1627
1628 // 7.) Create a vector<int> from the global_subdomain_ids set, for passing to Nemesis
1629 this->global_elem_blk_ids.clear();
1630 this->global_elem_blk_ids.insert(this->global_elem_blk_ids.end(), // pos
1631 global_subdomain_ids.begin(),
1632 global_subdomain_ids.end());
1633
1634 if (verbose)
1635 {
1636 libMesh::out << "[" << this->processor_id() << "] global_elem_blk_ids = ";
1637 for (const auto & id : this->global_elem_blk_ids)
1638 libMesh::out << id << ", ";
1639 libMesh::out << std::endl;
1640 }
1641
1642
1643 // 8.) We will call put_eb_info_global later, it must be called after this->put_init_global().
1644}
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
std::vector< int > global_elem_blk_cnts
std::vector< int > global_elem_blk_ids
Read the global element block IDs and counts.
const Parallel::Communicator & comm() const

References libMesh::Parallel::Communicator::allgather(), libMesh::ParallelObject::comm(), global_elem_blk_cnts, global_elem_blk_ids, local_subdomain_counts, num_elem_blks_global, libMesh::out, libMesh::ParallelObject::processor_id(), libMesh::Parallel::Communicator::sum(), and libMesh::ExodusII_IO_Helper::verbose.

Referenced by initialize().

◆ compute_num_global_nodesets()

void libMesh::Nemesis_IO_Helper::compute_num_global_nodesets ( const MeshBase pmesh)
private

This function uses global communication routines to determine the number of nodesets across the entire mesh.

Definition at line 1438 of file nemesis_io_helper.C.

1439{
1440 std::set<boundary_id_type> local_node_boundary_ids;
1441
1442 // 1.) Get reference to the set of node boundary IDs *for this processor*
1443 std::set<boundary_id_type> global_node_boundary_ids
1444 (pmesh.get_boundary_info().get_node_boundary_ids().begin(),
1445 pmesh.get_boundary_info().get_node_boundary_ids().end());
1446
1447 // Save a copy of the local_node_boundary_ids...
1448 local_node_boundary_ids = global_node_boundary_ids;
1449
1450 // 2.) Gather boundary node IDs from other processors
1451 this->comm().set_union(global_node_boundary_ids);
1452
1453 // 3.) Now global_node_boundary_ids actually contains a global list of all node boundary IDs
1454 this->num_node_sets_global =
1455 cast_int<int>(global_node_boundary_ids.size());
1456
1457 // 4.) Create a vector<int> from the global_node_boundary_ids set
1458 this->global_nodeset_ids.clear();
1459 this->global_nodeset_ids.insert(this->global_nodeset_ids.end(),
1460 global_node_boundary_ids.begin(),
1461 global_node_boundary_ids.end());
1462
1463 if (verbose)
1464 {
1465 libMesh::out << "[" << this->processor_id() << "] global_nodeset_ids = ";
1466 for (const auto & id : global_nodeset_ids)
1467 libMesh::out << id << ", ";
1468 libMesh::out << std::endl;
1469
1470 libMesh::out << "[" << this->processor_id() << "] local_node_boundary_ids = ";
1471 for (const auto & id : local_node_boundary_ids)
1472 libMesh::out << id << ", ";
1473 libMesh::out << std::endl;
1474 }
1475
1476 // 7.) We also need to know the number of nodes which is in each of the nodesets, globally.
1477
1478 // Build list of (node-id, bc-id) tuples.
1479 typedef std::tuple<dof_id_type, boundary_id_type> Tuple;
1480 std::vector<Tuple> bc_tuples = pmesh.get_boundary_info().build_node_list();
1481
1482 if (verbose)
1483 {
1484 libMesh::out << "[" << this->processor_id() << "] boundary_node_list.size()="
1485 << bc_tuples.size() << std::endl;
1486 libMesh::out << "[" << this->processor_id() << "] (boundary_node_id, boundary_id) = ";
1487 for (const auto & t : bc_tuples)
1488 libMesh::out << "(" << std::get<0>(t) << ", " << std::get<1>(t) << ") ";
1489 libMesh::out << std::endl;
1490 }
1491
1492 // Now get the global information. In this case, we only want to count boundary
1493 // information for nodes *owned* by this processor, so there are no duplicates.
1494
1495 // Make sure we don't have any left over information
1496 this->num_global_node_counts.clear();
1497 this->num_global_node_counts.resize(this->global_nodeset_ids.size());
1498
1499 // Unfortunately, we can't just count up all occurrences of a given id,
1500 // that would give us duplicate entries when we do the parallel summation.
1501 // So instead, only count entries for nodes owned by this processor.
1502 // Start by getting rid of all non-local node entries from the vectors.
1503 std::vector<Tuple>::iterator
1504 it = bc_tuples.begin(),
1505 new_end = bc_tuples.end();
1506
1507 while (it != new_end)
1508 {
1509 if (pmesh.node_ptr(std::get<0>(*it))->processor_id() != this->processor_id())
1510 {
1511 // Back up the new end iterators to prepare for swap
1512 --new_end;
1513
1514 // Swap places, the non-local node will now be "past-the-end"
1515 std::swap(*it, *new_end);
1516 }
1517 else // node is local, go to next
1518 ++it;
1519 }
1520
1521 // Erase from "new" end to old end.
1522 bc_tuples.erase(new_end, bc_tuples.end());
1523
1524 // Now we can do the local count for each ID...
1525 for (auto i : index_range(global_nodeset_ids))
1526 {
1527 int id = this->global_nodeset_ids[i];
1528 this->num_global_node_counts[i] =
1529 cast_int<int>(std::count_if(bc_tuples.begin(),
1530 bc_tuples.end(),
1531 [id](const Tuple & t)->bool { return std::get<1>(t) == id; }));
1532 }
1533
1534 // And finally we can sum them up
1535 this->comm().sum(this->num_global_node_counts);
1536
1537 if (verbose)
1538 {
1539 libMesh::out << "[" << this->processor_id() << "] num_global_node_counts = ";
1540 for (const auto & cnt : num_global_node_counts)
1541 libMesh::out << cnt << ", ";
1542 libMesh::out << std::endl;
1543 }
1544}
void set_union(T &data, const unsigned int root_id) const
std::vector< int > global_nodeset_ids
Containers for reading global nodeset information.
std::vector< int > num_global_node_counts
const Elem & get(const ElemType type_in)

References libMesh::BoundaryInfo::build_node_list(), libMesh::ParallelObject::comm(), libMesh::MeshBase::get_boundary_info(), libMesh::BoundaryInfo::get_node_boundary_ids(), global_nodeset_ids, libMesh::index_range(), libMesh::MeshBase::node_ptr(), num_global_node_counts, num_node_sets_global, libMesh::out, libMesh::DofObject::processor_id(), libMesh::ParallelObject::processor_id(), libMesh::Parallel::Communicator::set_union(), libMesh::Parallel::Communicator::sum(), and libMesh::ExodusII_IO_Helper::verbose.

Referenced by initialize().

◆ compute_num_global_sidesets()

void libMesh::Nemesis_IO_Helper::compute_num_global_sidesets ( const MeshBase pmesh)
private

This function uses global communication routines to determine the number of sidesets across the entire mesh.

Definition at line 1345 of file nemesis_io_helper.C.

1346{
1347 // 1.) Get reference to the set of side boundary IDs
1348 std::set<boundary_id_type> global_side_boundary_ids
1349 (pmesh.get_boundary_info().get_side_boundary_ids().begin(),
1350 pmesh.get_boundary_info().get_side_boundary_ids().end());
1351
1352 // 2.) Gather boundary side IDs from other processors
1353 this->comm().set_union(global_side_boundary_ids);
1354
1355 // 3.) Now global_side_boundary_ids actually contains a global list of all side boundary IDs
1356 this->num_side_sets_global =
1357 cast_int<int>(global_side_boundary_ids.size());
1358
1359 // 4.) Pack these sidesets into a vector so they can be written by Nemesis
1360 this->global_sideset_ids.clear(); // Make sure there is no leftover information
1361 this->global_sideset_ids.insert(this->global_sideset_ids.end(),
1362 global_side_boundary_ids.begin(),
1363 global_side_boundary_ids.end());
1364
1365 if (verbose)
1366 {
1367 libMesh::out << "[" << this->processor_id() << "] global_sideset_ids = ";
1368 for (const auto & id : this->global_sideset_ids)
1369 libMesh::out << id << ", ";
1370 libMesh::out << std::endl;
1371 }
1372
1373 // We also need global counts of sides in each of the sidesets.
1374 // Build a list of (elem, side, bc) tuples.
1375 typedef std::tuple<dof_id_type, unsigned short int, boundary_id_type> Tuple;
1376 std::vector<Tuple> bc_triples = pmesh.get_boundary_info().build_side_list();
1377
1378 // Iterators to the beginning and end of the current range.
1379 std::vector<Tuple>::iterator
1380 it = bc_triples.begin(),
1381 new_end = bc_triples.end();
1382
1383 while (it != new_end)
1384 {
1385 if (pmesh.elem_ref(std::get<0>(*it)).processor_id() != this->processor_id())
1386 {
1387 // Back up the new end iterators to prepare for swap
1388 --new_end;
1389
1390 // Swap places, the non-local elem will now be "past-the-end"
1391 std::swap (*it, *new_end);
1392 }
1393 else // elem is local, go to next
1394 ++it;
1395 }
1396
1397 // Erase from "new" end to old.
1398 bc_triples.erase(new_end, bc_triples.end());
1399
1400 this->num_global_side_counts.clear(); // Make sure we don't have any leftover information
1401 this->num_global_side_counts.resize(this->global_sideset_ids.size());
1402
1403 // Get the count for each global sideset ID
1404 for (auto i : index_range(global_sideset_ids))
1405 {
1406 int id = global_sideset_ids[i];
1407 this->num_global_side_counts[i] =
1408 cast_int<int>(std::count_if(bc_triples.begin(),
1409 bc_triples.end(),
1410 [id](const Tuple & t)->bool { return std::get<2>(t) == id; }));
1411 }
1412
1413 if (verbose)
1414 {
1415 libMesh::out << "[" << this->processor_id() << "] num_global_side_counts = ";
1416 for (const auto & cnt : this->num_global_side_counts)
1417 libMesh::out << cnt << ", ";
1418 libMesh::out << std::endl;
1419 }
1420
1421 // Finally sum up the result
1422 this->comm().sum(this->num_global_side_counts);
1423
1424 if (verbose)
1425 {
1426 libMesh::out << "[" << this->processor_id() << "] num_global_side_counts = ";
1427 for (const auto & cnt : this->num_global_side_counts)
1428 libMesh::out << cnt << ", ";
1429 libMesh::out << std::endl;
1430 }
1431}
std::vector< int > num_global_side_counts
std::vector< int > global_sideset_ids
Containers for reading global sideset (boundary conditions) information.

References libMesh::BoundaryInfo::build_side_list(), libMesh::ParallelObject::comm(), libMesh::MeshBase::elem_ref(), libMesh::MeshBase::get_boundary_info(), libMesh::BoundaryInfo::get_side_boundary_ids(), global_sideset_ids, libMesh::index_range(), num_global_side_counts, num_side_sets_global, libMesh::out, libMesh::DofObject::processor_id(), libMesh::ParallelObject::processor_id(), libMesh::Parallel::Communicator::set_union(), libMesh::Parallel::Communicator::sum(), and libMesh::ExodusII_IO_Helper::verbose.

Referenced by initialize().

◆ conditionally_set_elem_unique_id()

void libMesh::ExodusII_IO_Helper::conditionally_set_elem_unique_id ( MeshBase mesh,
Elem elem,
int  zero_based_elem_num_map_index 
)
inherited

Definition at line 2469 of file exodusII_io_helper.C.

2471{
2472 this->set_dof_object_unique_id(mesh, elem, libmesh_vector_at(this->elem_num_map, zero_based_elem_num_map_index));
2473}
void set_dof_object_unique_id(MeshBase &mesh, DofObject *dof_object, int exodus_mapped_id)

References libMesh::ExodusII_IO_Helper::elem_num_map, and libMesh::ExodusII_IO_Helper::set_dof_object_unique_id().

◆ conditionally_set_node_unique_id()

void libMesh::ExodusII_IO_Helper::conditionally_set_node_unique_id ( MeshBase mesh,
Node node,
int  zero_based_node_num_map_index 
)
inherited

Helper function that conditionally sets the unique_id of the passed-in Node/Elem.

Calling this function does nothing if _set_unique_ids_from_maps == false, otherwise it sets the unique_id based on the entries of the {node,elem_num_map}. The input index is assumed to be a zero-based index into the {node,elem}_num_map array.

Definition at line 2462 of file exodusII_io_helper.C.

2464{
2465 this->set_dof_object_unique_id(mesh, node, libmesh_vector_at(this->node_num_map, zero_based_node_num_map_index));
2466}

References libMesh::ExodusII_IO_Helper::node_num_map, and libMesh::ExodusII_IO_Helper::set_dof_object_unique_id().

◆ construct_nemesis_filename()

std::string libMesh::Nemesis_IO_Helper::construct_nemesis_filename ( std::string_view  base_filename)

Given base_filename, foo.e, constructs the Nemesis filename foo.e.X.Y, where X=n.

CPUs and Y=processor ID

Definition at line 2791 of file nemesis_io_helper.C.

2792{
2793 // Build a filename for this processor. This code is cut-n-pasted from the read function
2794 // and should probably be put into a separate function...
2795 std::ostringstream file_oss;
2796
2797 // We have to be a little careful here: Nemesis left pads its file
2798 // numbers based on the number of processors, so for example on 10
2799 // processors, we'd have:
2800 // mesh.e.10.00
2801 // mesh.e.10.01
2802 // mesh.e.10.02
2803 // ...
2804 // mesh.e.10.09
2805
2806 // And on 100 you'd have:
2807 // mesh.e.100.000
2808 // mesh.e.100.001
2809 // ...
2810 // mesh.e.128.099
2811
2812 // Find the length of the highest processor ID
2813 file_oss << (this->n_processors());
2814 unsigned int field_width = cast_int<unsigned int>(file_oss.str().size());
2815
2816 if (verbose)
2817 libMesh::out << "field_width=" << field_width << std::endl;
2818
2819 file_oss.str(""); // reset the string stream
2820 file_oss << base_filename
2821 << '.' << this->n_processors()
2822 << '.' << std::setfill('0') << std::setw(field_width) << this->processor_id();
2823
2824 // Return the resulting string
2825 return file_oss.str();
2826}

References libMesh::ParallelObject::n_processors(), libMesh::out, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::verbose.

◆ create()

void libMesh::ExodusII_IO_Helper::create ( std::string  filename)
virtualinherited

Opens an ExodusII mesh file named filename for writing.

Definition at line 2513 of file exodusII_io_helper.C.

2514{
2515 // If we're processor 0, always create the file.
2516 // If we running on all procs, e.g. as one of several Nemesis files, also
2517 // call create there.
2518 if ((this->processor_id() == 0) || (!_run_only_on_proc0))
2519 {
2520 int
2521 comp_ws = 0,
2522 io_ws = 0;
2523
2525 {
2526 comp_ws = cast_int<int>(sizeof(float));
2527 io_ws = cast_int<int>(sizeof(float));
2528 }
2529 // Fall back on double precision when necessary since ExodusII
2530 // doesn't seem to support long double
2531 else
2532 {
2533 comp_ws = cast_int<int>
2534 (std::min(sizeof(Real), sizeof(double)));
2535 io_ws = cast_int<int>
2536 (std::min(sizeof(Real), sizeof(double)));
2537 }
2538
2539 // By default we just open the Exodus file in "EX_CLOBBER" mode,
2540 // which, according to "ncdump -k", writes the file in "64-bit
2541 // offset" mode, which is a NETCDF3 file format.
2542 int mode = EX_CLOBBER;
2543
2544 // If HDF5 is available, by default we will write Exodus files
2545 // in a more modern NETCDF4-compatible format. For this file
2546 // type, "ncdump -k" will report "netCDF-4".
2547#ifdef LIBMESH_HAVE_HDF5
2548 if (this->_write_hdf5)
2549 {
2550 mode |= EX_NETCDF4;
2551 mode |= EX_NOCLASSIC;
2552 }
2553#endif
2554
2555 {
2556 FPEDisabler disable_fpes;
2557 ex_id = exII::ex_create(filename.c_str(), mode, &comp_ws, &io_ws);
2558 }
2559
2560 EX_CHECK_ERR(ex_id, "Error creating ExodusII/Nemesis mesh file.");
2561
2562 // We don't have access to the names we might be writing until we
2563 // write them, so we can't set a guaranteed max name length here.
2564 // But it looks like the most ExodusII can support is 80, so we'll
2565 // just waste 48 bytes here and there.
2566 ex_err = exII::ex_set_max_name_length(ex_id, _max_name_length);
2567 EX_CHECK_ERR(ex_err, "Error setting max ExodusII name length.");
2568
2569 if (verbose)
2570 libMesh::out << "File created successfully." << std::endl;
2571 }
2572
2573 opened_for_writing = true;
2574 _opened_by_create = true;
2575 current_filename = filename;
2576}
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
The FPEDisabler class puts Floating-Point Exception (FPE) trapping on hold during its lifetime,...

References libMesh::ExodusII_IO_Helper::_max_name_length, libMesh::ExodusII_IO_Helper::_opened_by_create, libMesh::ExodusII_IO_Helper::_run_only_on_proc0, libMesh::ExodusII_IO_Helper::_single_precision, libMesh::ExodusII_IO_Helper::_write_hdf5, libMesh::ExodusII_IO_Helper::current_filename, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::opened_for_writing, libMesh::out, libMesh::ParallelObject::processor_id(), libMesh::Real, and libMesh::ExodusII_IO_Helper::verbose.

◆ end_elem_id()

int libMesh::ExodusII_IO_Helper::end_elem_id ( ) const
inlineinherited

◆ get_add_sides()

bool libMesh::ExodusII_IO_Helper::get_add_sides ( )
inlineinherited

Definition at line 1368 of file exodusII_io_helper.h.

1369{
1370 return _add_sides;
1371}
bool _add_sides
Set to true iff we want to write separate "side" elements too.

References libMesh::ExodusII_IO_Helper::_add_sides.

◆ get_block_id()

int libMesh::ExodusII_IO_Helper::get_block_id ( int  index)
inherited

Get the block number for the given block index.

Definition at line 1149 of file exodusII_io_helper.C.

1150{
1151 libmesh_assert_less (index, block_ids.size());
1152
1153 return block_ids[index];
1154}

References libMesh::ExodusII_IO_Helper::block_ids.

Referenced by libMesh::ExodusII_IO_Helper::write_element_values(), and libMesh::ExodusII_IO_Helper::write_element_values_element_major().

◆ get_block_name()

std::string libMesh::ExodusII_IO_Helper::get_block_name ( int  index)
inherited

Get the block name for the given block index if supplied in the mesh file.

Otherwise an empty string is returned.

Definition at line 1158 of file exodusII_io_helper.C.

1159{
1160 libmesh_assert_less (index, block_ids.size());
1161
1162 return id_to_block_names[block_ids[index]];
1163}
std::map< int, std::string > id_to_block_names

References libMesh::ExodusII_IO_Helper::block_ids, and libMesh::ExodusII_IO_Helper::id_to_block_names.

◆ get_cmap_params()

void libMesh::Nemesis_IO_Helper::get_cmap_params ( )

Definition at line 388 of file nemesis_io_helper.C.

389{
394
396 Nemesis::ne_get_cmap_params(ex_id,
397 node_cmap_ids.empty() ? nullptr : node_cmap_ids.data(),
398 node_cmap_node_cnts.empty() ? nullptr : node_cmap_node_cnts.data(),
399 elem_cmap_ids.empty() ? nullptr : elem_cmap_ids.data(),
400 elem_cmap_elem_cnts.empty() ? nullptr : elem_cmap_elem_cnts.data(),
401 this->processor_id());
402 EX_CHECK_ERR(nemesis_err_flag, "Error reading cmap parameters!");
403
404
405 if (verbose)
406 {
407 libMesh::out << "[" << this->processor_id() << "] ";
408 for (auto i : index_range(node_cmap_ids))
409 libMesh::out << "node_cmap_ids[" << i << "]=" << node_cmap_ids[i] << " ";
410 libMesh::out << std::endl;
411
412 libMesh::out << "[" << this->processor_id() << "] ";
413 for (auto i : index_range(node_cmap_node_cnts))
414 libMesh::out << "node_cmap_node_cnts[" << i << "]=" << node_cmap_node_cnts[i] << " ";
415 libMesh::out << std::endl;
416
417 libMesh::out << "[" << this->processor_id() << "] ";
418 for (auto i : index_range(elem_cmap_ids))
419 libMesh::out << "elem_cmap_ids[" << i << "]=" << elem_cmap_ids[i] << " ";
420 libMesh::out << std::endl;
421
422 libMesh::out << "[" << this->processor_id() << "] ";
423 for (auto i : index_range(elem_cmap_elem_cnts))
424 libMesh::out << "elem_cmap_elem_cnts[" << i << "]=" << elem_cmap_elem_cnts[i] << " ";
425 libMesh::out << std::endl;
426 }
427}

References elem_cmap_elem_cnts, elem_cmap_ids, libMesh::ExodusII_IO_Helper::ex_id, libMesh::index_range(), nemesis_err_flag, node_cmap_ids, node_cmap_node_cnts, num_elem_cmaps, num_node_cmaps, libMesh::out, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::verbose.

◆ get_complex_names()

std::vector< std::string > libMesh::ExodusII_IO_Helper::get_complex_names ( const std::vector< std::string > &  names,
bool  write_complex_abs 
) const
inherited
Returns
A vector with three copies of each element in the provided name vector, starting with r_, i_ and a_ respectively. If the "write_complex_abs" parameter is true (default), the complex modulus is written, otherwise only the real and imaginary parts are written.

Definition at line 5379 of file exodusII_io_helper.C.

5381{
5382 std::vector<std::string> complex_names;
5383
5384 // This will loop over all names and create new "complex" names
5385 // (i.e. names that start with r_, i_ or a_)
5386 for (const auto & name : names)
5387 {
5388 complex_names.push_back("r_" + name);
5389 complex_names.push_back("i_" + name);
5390 if (write_complex_abs)
5391 complex_names.push_back("a_" + name);
5392 }
5393
5394 return complex_names;
5395}

◆ get_complex_subdomain_to_var_names()

std::map< subdomain_id_type, std::vector< std::string > > libMesh::ExodusII_IO_Helper::get_complex_subdomain_to_var_names ( const std::map< subdomain_id_type, std::vector< std::string > > &  subdomain_to_var_names,
bool  write_complex_abs 
) const
inherited

Takes a map from subdomain id -> vector of active variable names as input and returns a corresponding map where the original variable names have been replaced by their complex counterparts.

Used by the ExodusII_IO::write_element_data_from_discontinuous_nodal_data() function.

Definition at line 5423 of file exodusII_io_helper.C.

5427{
5428 // Eventual return value
5429 std::map<subdomain_id_type, std::vector<std::string>> ret;
5430
5431 unsigned int num_complex_outputs = write_complex_abs ? 3 : 2;
5432
5433 for (const auto & pr : subdomain_to_var_names)
5434 {
5435 // Initialize entry for current subdomain
5436 auto & vec = ret[pr.first];
5437
5438 // Get list of non-complex variable names active on this subdomain.
5439 const auto & varnames = pr.second;
5440
5441 // Allocate space for the complex-valued entries
5442 vec.reserve(num_complex_outputs * varnames.size());
5443
5444 // For each varname in the input map, write three variable names
5445 // to the output formed by prepending "r_", "i_", and "a_",
5446 // respectively.
5447 for (const auto & varname : varnames)
5448 {
5449 vec.push_back("r_" + varname);
5450 vec.push_back("i_" + varname);
5451 if (write_complex_abs)
5452 vec.push_back("a_" + varname);
5453 }
5454 }
5455 return ret;
5456}

◆ get_complex_vars_active_subdomains()

std::vector< std::set< subdomain_id_type > > libMesh::ExodusII_IO_Helper::get_complex_vars_active_subdomains ( const std::vector< std::set< subdomain_id_type > > &  vars_active_subdomains,
bool  write_complex_abs 
) const
inherited

returns a "tripled" copy of vars_active_subdomains, which is necessary in the complex-valued case.

Definition at line 5400 of file exodusII_io_helper.C.

5404{
5405 std::vector<std::set<subdomain_id_type>> complex_vars_active_subdomains;
5406
5407 for (auto & s : vars_active_subdomains)
5408 {
5409 // Push back the same data enough times for the real, imag, (and
5410 // possibly modulus) for the complex-valued solution.
5411 complex_vars_active_subdomains.push_back(s);
5412 complex_vars_active_subdomains.push_back(s);
5413 if (write_complex_abs)
5414 complex_vars_active_subdomains.push_back(s);
5415 }
5416
5417 return complex_vars_active_subdomains;
5418}

◆ get_conversion() [1/2]

const ExodusII_IO_Helper::Conversion & libMesh::ExodusII_IO_Helper::get_conversion ( const ElemType  type) const
inherited

◆ get_conversion() [2/2]

const ExodusII_IO_Helper::Conversion & libMesh::ExodusII_IO_Helper::get_conversion ( std::string  type_str) const
inherited

Definition at line 579 of file exodusII_io_helper.C.

580{
581 // Do only upper-case comparisons
582 std::transform(type_str.begin(), type_str.end(), type_str.begin(), ::toupper);
583 return get_conversion (libmesh_map_find(element_equivalence_map, type_str));
584}
std::map< std::string, ElemType > element_equivalence_map
Defines equivalence classes of Exodus element types that map to libmesh ElemTypes.

References libMesh::ExodusII_IO_Helper::element_equivalence_map, and libMesh::ExodusII_IO_Helper::get_conversion().

◆ get_eb_info_global()

void libMesh::Nemesis_IO_Helper::get_eb_info_global ( )

Definition at line 242 of file nemesis_io_helper.C.

243{
246
247 if (num_elem_blks_global > 0)
248 {
250 Nemesis::ne_get_eb_info_global(ex_id,
251 global_elem_blk_ids.data(),
252 global_elem_blk_cnts.data());
253 EX_CHECK_ERR(nemesis_err_flag, "Error reading global element block info!");
254 }
255
256 if (verbose)
257 {
258 libMesh::out << "[" << this->processor_id() << "] " << "Global Element Block IDs and Counts:" << std::endl;
259 for (auto bn : index_range(global_elem_blk_ids))
260 {
261 libMesh::out << " [" << this->processor_id() << "] "
262 << "global_elem_blk_ids[" << bn << "]=" << global_elem_blk_ids[bn]
263 << ", global_elem_blk_cnts[" << bn << "]=" << global_elem_blk_cnts[bn]
264 << std::endl;
265 }
266 }
267}

References libMesh::ExodusII_IO_Helper::ex_id, global_elem_blk_cnts, global_elem_blk_ids, libMesh::index_range(), nemesis_err_flag, num_elem_blks_global, libMesh::out, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::verbose.

◆ get_elem_cmap()

void libMesh::Nemesis_IO_Helper::get_elem_cmap ( )

Definition at line 473 of file nemesis_io_helper.C.

474{
478
479 for (auto i : index_range(elem_cmap_elem_ids))
480 {
484
485 if (elem_cmap_elem_cnts[i] > 0)
486 {
488 Nemesis::ne_get_elem_cmap(ex_id,
489 elem_cmap_ids[i],
490 elem_cmap_elem_ids[i].data(),
491 elem_cmap_side_ids[i].data(),
492 elem_cmap_proc_ids[i].data(),
493 this->processor_id());
494 EX_CHECK_ERR(nemesis_err_flag, "Error reading elem cmap elem, side, and processor ids!");
495 }
496
497 if (verbose)
498 {
499 libMesh::out << "[" << this->processor_id() << "] elem_cmap_elem_ids[" << i << "]=";
500 for (const auto & dof : elem_cmap_elem_ids[i])
501 libMesh::out << dof << " ";
502 libMesh::out << std::endl;
503
504 // These must be the (local) side IDs (in the ExodusII face numbering scheme)
505 // of the sides shared across processors.
506 libMesh::out << "[" << this->processor_id() << "] elem_cmap_side_ids[" << i << "]=";
507 for (const auto & dof : elem_cmap_side_ids[i])
508 libMesh::out << dof << " ";
509 libMesh::out << std::endl;
510
511 // This is basically a vector, all entries of which are = elem_cmap_ids[i]
512 // Not sure if it's always guaranteed to be that or what...
513 libMesh::out << "[" << this->processor_id() << "] elem_cmap_proc_ids[" << i << "]=";
514 for (const auto & dof : elem_cmap_proc_ids[i])
515 libMesh::out << dof << " ";
516 libMesh::out << std::endl;
517 }
518 }
519}

References elem_cmap_elem_cnts, elem_cmap_elem_ids, elem_cmap_ids, elem_cmap_proc_ids, elem_cmap_side_ids, libMesh::ExodusII_IO_Helper::ex_id, libMesh::index_range(), nemesis_err_flag, num_elem_cmaps, libMesh::out, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::verbose.

◆ get_elem_map()

void libMesh::Nemesis_IO_Helper::get_elem_map ( )

Definition at line 320 of file nemesis_io_helper.C.

321{
324
326 Nemesis::ne_get_elem_map(ex_id,
327 elem_mapi.empty() ? nullptr : elem_mapi.data(),
328 elem_mapb.empty() ? nullptr : elem_mapb.data(),
329 this->processor_id()
330 );
331 EX_CHECK_ERR(nemesis_err_flag, "Error reading element maps!");
332
333
334 if (verbose)
335 {
336 libMesh::out << "[" << this->processor_id() << "] elem_mapi[i] = ";
337 for (auto i : make_range(num_internal_elems-1))
338 libMesh::out << elem_mapi[i] << ", ";
339 libMesh::out << "... " << elem_mapi.back() << std::endl;
340
341 libMesh::out << "[" << this->processor_id() << "] elem_mapb[i] = ";
342 for (auto i : make_range(std::min(10, num_border_elems-1)))
343 libMesh::out << elem_mapb[i] << ", ";
344 libMesh::out << "... " << elem_mapb.back() << std::endl;
345 }
346}

References elem_mapb, elem_mapi, libMesh::ExodusII_IO_Helper::ex_id, libMesh::make_range(), nemesis_err_flag, num_border_elems, num_internal_elems, libMesh::out, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::verbose.

◆ get_elem_type()

const char * libMesh::ExodusII_IO_Helper::get_elem_type ( ) const
inherited
Returns
The current element type.
Note
The default behavior is for this value to be in all capital letters, e.g. HEX27.

Definition at line 586 of file exodusII_io_helper.C.

587{
588 return elem_type.data();
589}

References libMesh::ExodusII_IO_Helper::elem_type.

◆ get_elemset_data_indices()

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

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

Definition at line 4810 of file exodusII_io_helper.C.

4812{
4813 // Clear existing data, we are going to build these data structures from scratch
4814 elemset_array_indices.clear();
4815
4816 // Read the elemset data.
4817 //
4818 // Note: we assume that the functions
4819 // 1.) this->read_elemset_info() and
4820 // 2.) this->read_elemset()
4821 // have already been called, so that we already know e.g. how
4822 // many elems are in each set, their ids, etc.
4823 int offset=0;
4824 for (int es=0; es<num_elem_sets; ++es)
4825 {
4826 offset += (es > 0 ? num_elems_per_set[es-1] : 0);
4827
4828 // Note: we don't actually call exII::ex_get_var() here because
4829 // we don't need the values. We only need the indices into that vector
4830 // for each (elem_id, elemset_id) tuple.
4831 for (int i=0; i<num_elems_per_set[es]; ++i)
4832 {
4833 dof_id_type exodus_elem_id = elemset_list[i + offset];
4834
4835 // FIXME: We should use exodus_elem_num_to_libmesh for this,
4836 // but it apparently is never set up, so just
4837 // subtract 1 from the Exodus elem id.
4838 dof_id_type converted_elem_id = exodus_elem_id - 1;
4839
4840 // Make key based on the elem and set ids
4841 // Make a NodeBCTuple key from the converted information.
4842 auto key = std::make_pair(converted_elem_id,
4843 static_cast<elemset_id_type>(elemset_ids[es]));
4844
4845 // Store the array index of this (node, b_id) tuple
4846 elemset_array_indices.emplace(key, cast_int<unsigned int>(i));
4847 } // end for (i)
4848 } // end for (es)
4849}
std::vector< int > num_elems_per_set

References libMesh::ExodusII_IO_Helper::elemset_ids, libMesh::ExodusII_IO_Helper::elemset_list, libMesh::ExodusII_IO_Helper::num_elem_sets, and libMesh::ExodusII_IO_Helper::num_elems_per_set.

◆ get_exodus_version()

int libMesh::ExodusII_IO_Helper::get_exodus_version ( )
staticinherited
Returns
The ExodusII API version, in "nodot" format; e.g. 822 for 8.22

Definition at line 332 of file exodusII_io_helper.C.

333{
334 return EX_API_VERS_NODOT;
335}

Referenced by libMesh::ExodusII_IO::get_exodus_version().

◆ get_init_global()

void libMesh::Nemesis_IO_Helper::get_init_global ( )

Fills: num_nodes_global, num_elems_global, num_elem_blks_global, num_node_sets_global, num_side_sets_global Call after: read_and_store_header_info() Call before: Any other get_* function from this class.

Definition at line 151 of file nemesis_io_helper.C.

152{
154 Nemesis::ne_get_init_global(ex_id,
160 EX_CHECK_ERR(nemesis_err_flag, "Error reading initial global data!");
161
162 if (verbose)
163 {
164 libMesh::out << "[" << this->processor_id() << "] " << "num_nodes_global=" << num_nodes_global << std::endl;
165 libMesh::out << "[" << this->processor_id() << "] " << "num_elems_global=" << num_elems_global << std::endl;
166 libMesh::out << "[" << this->processor_id() << "] " << "num_elem_blks_global=" << num_elem_blks_global << std::endl;
167 libMesh::out << "[" << this->processor_id() << "] " << "num_node_sets_global=" << num_node_sets_global << std::endl;
168 libMesh::out << "[" << this->processor_id() << "] " << "num_side_sets_global=" << num_side_sets_global << std::endl;
169 }
170}

References libMesh::ExodusII_IO_Helper::ex_id, nemesis_err_flag, num_elem_blks_global, num_elems_global, num_node_sets_global, num_nodes_global, num_side_sets_global, libMesh::out, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::verbose.

◆ get_init_info()

void libMesh::Nemesis_IO_Helper::get_init_info ( )

Definition at line 271 of file nemesis_io_helper.C.

272{
274 Nemesis::ne_get_init_info(ex_id,
275 &num_proc,
277 &ftype);
278 EX_CHECK_ERR(nemesis_err_flag, "Error reading initial info!");
279
280 if (verbose)
281 {
282 libMesh::out << "[" << this->processor_id() << "] " << "num_proc=" << num_proc << std::endl;
283 libMesh::out << "[" << this->processor_id() << "] " << "num_proc_in_file=" << num_proc_in_file << std::endl;
284 libMesh::out << "[" << this->processor_id() << "] " << "ftype=" << ftype << std::endl;
285 }
286}

References libMesh::ExodusII_IO_Helper::ex_id, ftype, nemesis_err_flag, num_proc, num_proc_in_file, libMesh::out, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::verbose.

◆ get_libmesh_elem_id()

dof_id_type libMesh::ExodusII_IO_Helper::get_libmesh_elem_id ( int  exodus_elem_id)
inherited

Definition at line 2423 of file exodusII_io_helper.C.

2424{
2425 return this->get_libmesh_id(exodus_elem_id, this->elem_num_map);
2426}
dof_id_type get_libmesh_id(int exodus_id, const std::vector< int > &num_map)
Internal implementation for the two sets of functions above.

References libMesh::ExodusII_IO_Helper::elem_num_map, and libMesh::ExodusII_IO_Helper::get_libmesh_id().

Referenced by libMesh::ExodusII_IO_Helper::read_elemental_var_values().

◆ get_libmesh_id()

dof_id_type libMesh::ExodusII_IO_Helper::get_libmesh_id ( int  exodus_id,
const std::vector< int > &  num_map 
)
privateinherited

Internal implementation for the two sets of functions above.

Definition at line 2429 of file exodusII_io_helper.C.

2431{
2432 // The input exodus_id is assumed to be a (1-based) index into
2433 // the {node,elem}_num_map, so in order to use exodus_id as an index
2434 // in C++, we need to first make it zero-based.
2435 auto exodus_id_zero_based =
2436 cast_int<dof_id_type>(exodus_id - 1);
2437
2438 // Throw an informative error message rather than accessing past the
2439 // end of the provided num_map. If we are setting Elem unique_ids
2440 // based on the num_map, we don't need to do this check.
2441 if (!this->set_unique_ids_from_maps)
2442 libmesh_error_msg_if(exodus_id_zero_based >= num_map.size(),
2443 "Cannot get LibMesh id for Exodus id: " << exodus_id);
2444
2445 // If the user set the flag which stores Exodus node/elem ids as
2446 // unique_ids instead of regular ids, then the libmesh id we are
2447 // looking for is actually just "exodus_id_zero_based". Otherwise,
2448 // we need to look up the Node/Elem's id in the provided num_map,
2449 // *and* then subtract 1 from that because the entries in the
2450 // num_map are also 1-based.
2451 dof_id_type libmesh_id =
2453 cast_int<dof_id_type>(exodus_id_zero_based) :
2454 cast_int<dof_id_type>(num_map[exodus_id_zero_based] - 1);
2455
2456 return libmesh_id;
2457}
Tnew cast_int(Told oldvar)

References libMesh::ExodusII_IO_Helper::set_unique_ids_from_maps.

Referenced by libMesh::ExodusII_IO_Helper::get_libmesh_elem_id(), and libMesh::ExodusII_IO_Helper::get_libmesh_node_id().

◆ get_libmesh_node_id()

dof_id_type libMesh::ExodusII_IO_Helper::get_libmesh_node_id ( int  exodus_node_id)
inherited

Helper function that takes a (1-based) Exodus node/elem id and determines the corresponding libMesh Node/Elem id.

Takes into account whether the user has chosen to set the Node/Elem unique ids based on the {node,elem}_num_map or to let libMesh set them.

Definition at line 2418 of file exodusII_io_helper.C.

2419{
2420 return this->get_libmesh_id(exodus_node_id, this->node_num_map);
2421}

References libMesh::ExodusII_IO_Helper::get_libmesh_id(), and libMesh::ExodusII_IO_Helper::node_num_map.

Referenced by libMesh::ExodusII_IO_Helper::read_edge_blocks(), and libMesh::ExodusII_IO_Helper::read_nodal_var_values().

◆ get_loadbal_param()

void libMesh::Nemesis_IO_Helper::get_loadbal_param ( )

Definition at line 290 of file nemesis_io_helper.C.

291{
293 Nemesis::ne_get_loadbal_param(ex_id,
301 this->processor_id() // The ID of the processor for which info is to be read
302 );
303 EX_CHECK_ERR(nemesis_err_flag, "Error reading load balance parameters!");
304
305
306 if (verbose)
307 {
308 libMesh::out << "[" << this->processor_id() << "] " << "num_internal_nodes=" << num_internal_nodes << std::endl;
309 libMesh::out << "[" << this->processor_id() << "] " << "num_border_nodes=" << num_border_nodes << std::endl;
310 libMesh::out << "[" << this->processor_id() << "] " << "num_external_nodes=" << num_external_nodes << std::endl;
311 libMesh::out << "[" << this->processor_id() << "] " << "num_internal_elems=" << num_internal_elems << std::endl;
312 libMesh::out << "[" << this->processor_id() << "] " << "num_border_elems=" << num_border_elems << std::endl;
313 libMesh::out << "[" << this->processor_id() << "] " << "num_node_cmaps=" << num_node_cmaps << std::endl;
314 libMesh::out << "[" << this->processor_id() << "] " << "num_elem_cmaps=" << num_elem_cmaps << std::endl;
315 }
316}

References libMesh::ExodusII_IO_Helper::ex_id, nemesis_err_flag, num_border_elems, num_border_nodes, num_elem_cmaps, num_external_nodes, num_internal_elems, num_internal_nodes, num_node_cmaps, libMesh::out, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::verbose.

◆ get_node_cmap()

void libMesh::Nemesis_IO_Helper::get_node_cmap ( )

Definition at line 431 of file nemesis_io_helper.C.

432{
435
436 for (auto i : index_range(node_cmap_node_ids))
437 {
440
441 // Don't call ne_get_node_cmap() if there is nothing there to
442 // get, Nemesis throws an error in this case.
443 if (node_cmap_node_cnts[i] > 0)
444 {
446 Nemesis::ne_get_node_cmap(ex_id,
447 node_cmap_ids[i],
448 node_cmap_node_ids[i].data(),
449 node_cmap_proc_ids[i].data(),
450 this->processor_id());
451 EX_CHECK_ERR(nemesis_err_flag, "Error reading node cmap node and processor ids!");
452 }
453
454 if (verbose)
455 {
456 libMesh::out << "[" << this->processor_id() << "] node_cmap_node_ids[" << i << "]=";
457 for (const auto & dof : node_cmap_node_ids[i])
458 libMesh::out << dof << " ";
459 libMesh::out << std::endl;
460
461 // This is basically a vector, all entries of which are = node_cmap_ids[i]
462 // Not sure if it's always guaranteed to be that or what...
463 libMesh::out << "[" << this->processor_id() << "] node_cmap_proc_ids[" << i << "]=";
464 for (const auto & dof : node_cmap_proc_ids[i])
465 libMesh::out << dof << " ";
466 libMesh::out << std::endl;
467 }
468 }
469}

References libMesh::ExodusII_IO_Helper::ex_id, libMesh::index_range(), nemesis_err_flag, node_cmap_ids, node_cmap_node_cnts, node_cmap_node_ids, node_cmap_proc_ids, num_node_cmaps, libMesh::out, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::verbose.

◆ get_node_map()

void libMesh::Nemesis_IO_Helper::get_node_map ( )

Definition at line 351 of file nemesis_io_helper.C.

352{
356
358 Nemesis::ne_get_node_map(ex_id,
359 node_mapi.empty() ? nullptr : node_mapi.data(),
360 node_mapb.empty() ? nullptr : node_mapb.data(),
361 node_mape.empty() ? nullptr : node_mape.data(),
362 this->processor_id()
363 );
364 EX_CHECK_ERR(nemesis_err_flag, "Error reading node maps!");
365
366 if (verbose)
367 {
368 // Remark: The Exodus/Nemesis node numbering is always (?) 1-based! This means the first interior node id will
369 // always be == 1.
370 libMesh::out << "[" << this->processor_id() << "] " << "first interior node id=" << node_mapi[0] << std::endl;
371 libMesh::out << "[" << this->processor_id() << "] " << "last interior node id=" << node_mapi.back() << std::endl;
372
373 libMesh::out << "[" << this->processor_id() << "] " << "first boundary node id=" << node_mapb[0] << std::endl;
374 libMesh::out << "[" << this->processor_id() << "] " << "last boundary node id=" << node_mapb.back() << std::endl;
375
376 // The number of external nodes is sometimes zero, don't try to access
377 // node_mape.back() in this case!
378 if (num_external_nodes > 0)
379 {
380 libMesh::out << "[" << this->processor_id() << "] " << "first external node id=" << node_mape[0] << std::endl;
381 libMesh::out << "[" << this->processor_id() << "] " << "last external node id=" << node_mape.back() << std::endl;
382 }
383 }
384}

References libMesh::ExodusII_IO_Helper::ex_id, nemesis_err_flag, node_mapb, node_mape, node_mapi, num_border_nodes, num_external_nodes, num_internal_nodes, libMesh::out, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::verbose.

◆ get_node_set_id()

int libMesh::ExodusII_IO_Helper::get_node_set_id ( int  index)
inherited

Get the node set id for the given node set index.

Definition at line 1185 of file exodusII_io_helper.C.

1186{
1187 libmesh_assert_less (index, nodeset_ids.size());
1188
1189 return nodeset_ids[index];
1190}

References libMesh::ExodusII_IO_Helper::nodeset_ids.

◆ get_node_set_name()

std::string libMesh::ExodusII_IO_Helper::get_node_set_name ( int  index)
inherited

Get the node set name for the given node set index if supplied in the mesh file.

Otherwise an empty string is returned.

Definition at line 1194 of file exodusII_io_helper.C.

1195{
1196 libmesh_assert_less (index, nodeset_ids.size());
1197
1198 return id_to_ns_names[nodeset_ids[index]];
1199}
std::map< int, std::string > id_to_ns_names

References libMesh::ExodusII_IO_Helper::id_to_ns_names, and libMesh::ExodusII_IO_Helper::nodeset_ids.

◆ get_nodeset_data_indices()

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

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 indexing for any/all nodeset variables on that nodeset (they are all the same).

Definition at line 4952 of file exodusII_io_helper.C.

4954{
4955 // Clear existing data, we are going to build these data structures from scratch
4956 bc_array_indices.clear();
4957
4958 // Read the nodeset data.
4959 //
4960 // Note: we assume that the functions
4961 // 1.) this->read_nodeset_info() and
4962 // 2.) this->read_all_nodesets()
4963 // have already been called, so that we already know e.g. how
4964 // many nodes are in each set, their ids, etc.
4965 int offset=0;
4966 for (int ns=0; ns<num_node_sets; ++ns)
4967 {
4968 offset += (ns > 0 ? num_nodes_per_set[ns-1] : 0);
4969 // Note: we don't actually call exII::ex_get_var() here because
4970 // we don't need the values. We only need the indices into that vector
4971 // for each (node_id, boundary_id) tuple.
4972 for (int i=0; i<num_nodes_per_set[ns]; ++i)
4973 {
4974 // The read_all_nodesets() function now reads all the node ids into the
4975 // node_sets_node_list vector, which is of length "total_nodes_in_all_sets"
4976 // The old read_nodset() function is no longer called as far as I can tell,
4977 // and should probably be removed? The "offset" that we are using only
4978 // depends on the current nodeset index and the num_nodes_per_set vector,
4979 // which gets filled in by the call to read_all_nodesets().
4980 dof_id_type exodus_node_id = node_sets_node_list[i + offset];
4981
4982 // FIXME: We should use exodus_node_num_to_libmesh for this,
4983 // but it apparently is never set up, so just
4984 // subtract 1 from the Exodus node id.
4985 dof_id_type converted_node_id = exodus_node_id - 1;
4986
4987 // Make a NodeBCTuple key from the converted information.
4988 BoundaryInfo::NodeBCTuple key = std::make_tuple
4989 (converted_node_id, nodeset_ids[ns]);
4990
4991 // Store the array index of this (node, b_id) tuple
4992 bc_array_indices.emplace(key, cast_int<unsigned int>(i));
4993 } // end for (i)
4994 } // end for (ns)
4995}
std::tuple< dof_id_type, boundary_id_type > NodeBCTuple
Create a list of (node_id, boundary_id) tuples for all relevant nodes.
std::vector< int > num_nodes_per_set
std::vector< int > node_sets_node_list

References libMesh::ExodusII_IO_Helper::node_sets_node_list, libMesh::ExodusII_IO_Helper::nodeset_ids, libMesh::ExodusII_IO_Helper::num_node_sets, and libMesh::ExodusII_IO_Helper::num_nodes_per_set.

◆ get_ns_param_global()

void libMesh::Nemesis_IO_Helper::get_ns_param_global ( )

Definition at line 210 of file nemesis_io_helper.C.

211{
212 if (num_node_sets_global > 0)
213 {
217
219 Nemesis::ne_get_ns_param_global(ex_id,
220 global_nodeset_ids.data(),
223 EX_CHECK_ERR(nemesis_err_flag, "Error reading global nodeset parameters!");
224
225 if (verbose)
226 {
227 libMesh::out << "[" << this->processor_id() << "] " << "Global Nodeset IDs, Node Counts, and DF counts:" << std::endl;
228 for (auto bn : index_range(global_nodeset_ids))
229 {
230 libMesh::out << " [" << this->processor_id() << "] "
231 << "global_nodeset_ids["<<bn<<"]=" << global_nodeset_ids[bn]
232 << ", num_global_node_counts["<<bn<<"]=" << num_global_node_counts[bn]
233 << ", num_global_node_df_counts["<<bn<<"]=" << num_global_node_df_counts[bn]
234 << std::endl;
235 }
236 }
237 }
238}
std::vector< int > num_global_node_df_counts

References libMesh::ExodusII_IO_Helper::ex_id, global_nodeset_ids, libMesh::index_range(), nemesis_err_flag, num_global_node_counts, num_global_node_df_counts, num_node_sets_global, libMesh::out, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::verbose.

◆ get_side_set_id()

int libMesh::ExodusII_IO_Helper::get_side_set_id ( int  index)
inherited

Get the side set id for the given side set index.

Definition at line 1167 of file exodusII_io_helper.C.

1168{
1169 libmesh_assert_less (index, ss_ids.size());
1170
1171 return ss_ids[index];
1172}

References libMesh::ExodusII_IO_Helper::ss_ids.

◆ get_side_set_name()

std::string libMesh::ExodusII_IO_Helper::get_side_set_name ( int  index)
inherited

Get the side set name for the given side set index if supplied in the mesh file.

Otherwise an empty string is returned.

Definition at line 1176 of file exodusII_io_helper.C.

1177{
1178 libmesh_assert_less (index, ss_ids.size());
1179
1180 return id_to_ss_names[ss_ids[index]];
1181}
std::map< int, std::string > id_to_ss_names

References libMesh::ExodusII_IO_Helper::id_to_ss_names, and libMesh::ExodusII_IO_Helper::ss_ids.

◆ get_sideset_data_indices()

void libMesh::ExodusII_IO_Helper::get_sideset_data_indices ( const MeshBase mesh,
std::map< BoundaryInfo::BCTuple, unsigned int > &  bc_array_indices 
)
inherited

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 indexing for any/all sideset variables on that sideset (they are all the same).

This function does not actually call exII::ex_get_sset_var() to get values, and can be useful if only the original ordering of (elem, side) pairs in the exo file is required in cases where a separate approach is used to read the sideset data arrays.

Definition at line 4425 of file exodusII_io_helper.C.

4428{
4429 // Clear any existing data, we are going to build this data structure from scratch
4430 bc_array_indices.clear();
4431
4432 // Store the sideset data array indices.
4433 //
4434 // Note: we assume that read_sideset() has already been called
4435 // for each sideset, so the required values in elem_list and
4436 // side_list are already present.
4437 int offset=0;
4438 for (int ss=0; ss<num_side_sets; ++ss)
4439 {
4440 offset += (ss > 0 ? num_sides_per_set[ss-1] : 0);
4441 for (int i=0; i<num_sides_per_set[ss]; ++i)
4442 {
4443 dof_id_type exodus_elem_id = elem_list[i + offset];
4444 unsigned int exodus_side_id = side_list[i + offset];
4445
4446 // FIXME: We should use exodus_elem_num_to_libmesh for this,
4447 // but it apparently is never set up, so just
4448 // subtract 1 from the Exodus elem id.
4449 dof_id_type converted_elem_id = exodus_elem_id - 1;
4450
4451 // Conversion operator for this Elem type
4452 const auto & conv = get_conversion(mesh.elem_ptr(converted_elem_id)->type());
4453
4454 // Map from Exodus side id to libmesh side id.
4455 // Note: the mapping is defined on 0-based indices, so subtract
4456 // 1 before doing the mapping.
4457 unsigned int converted_side_id = conv.get_side_map(exodus_side_id - 1);
4458
4459 // Make a BCTuple key from the converted information.
4460 BoundaryInfo::BCTuple key = std::make_tuple
4461 (converted_elem_id,
4462 converted_side_id,
4463 ss_ids[ss]);
4464
4465 // Store (elem, side, b_id) tuple with corresponding array index
4466 bc_array_indices.emplace(key, cast_int<unsigned int>(i));
4467 } // end for (i)
4468 } // end for (ss)
4469}
std::tuple< dof_id_type, unsigned short int, boundary_id_type > BCTuple
Create a list of (element_id, side_id, boundary_id) tuples for relevant sides.
virtual ElemType type() const =0
std::vector< int > num_sides_per_set
virtual const Elem * elem_ptr(const dof_id_type i) const =0
MeshBase & mesh

References libMesh::ExodusII_IO_Helper::elem_list, libMesh::MeshBase::elem_ptr(), libMesh::ExodusII_IO_Helper::get_conversion(), mesh, libMesh::ExodusII_IO_Helper::num_side_sets, libMesh::ExodusII_IO_Helper::num_sides_per_set, libMesh::ExodusII_IO_Helper::side_list, libMesh::ExodusII_IO_Helper::ss_ids, and libMesh::Elem::type().

◆ get_ss_param_global()

void libMesh::Nemesis_IO_Helper::get_ss_param_global ( )

Fills: global_sideset_ids, num_global_side_counts, num_global_side_df_counts Call after: get_init_global()

Definition at line 174 of file nemesis_io_helper.C.

175{
176 if (num_side_sets_global > 0)
177 {
180
181 // df = "distribution factor", not really sure what that is. I don't yet have a file
182 // which has distribution factors so I guess we'll worry about it later...
184
186 Nemesis::ne_get_ss_param_global(ex_id,
187 global_sideset_ids.data(),
190 EX_CHECK_ERR(nemesis_err_flag, "Error reading global sideset parameters!");
191
192 if (verbose)
193 {
194 libMesh::out << "[" << this->processor_id() << "] " << "Global Sideset IDs, Side Counts, and DF counts:" << std::endl;
195 for (auto bn : index_range(global_sideset_ids))
196 {
197 libMesh::out << " [" << this->processor_id() << "] "
198 << "global_sideset_ids["<<bn<<"]=" << global_sideset_ids[bn]
199 << ", num_global_side_counts["<<bn<<"]=" << num_global_side_counts[bn]
200 << ", num_global_side_df_counts["<<bn<<"]=" << num_global_side_df_counts[bn]
201 << std::endl;
202 }
203 }
204 }
205}
std::vector< int > num_global_side_df_counts

References libMesh::ExodusII_IO_Helper::ex_id, global_sideset_ids, libMesh::index_range(), nemesis_err_flag, num_global_side_counts, num_global_side_df_counts, num_side_sets_global, libMesh::out, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::verbose.

◆ init_conversion_map()

void libMesh::ExodusII_IO_Helper::init_conversion_map ( )
privateinherited

Definition at line 340 of file exodusII_io_helper.C.

341{
342 auto convert_type = [this](ElemType type,
343 std::string_view exodus_type,
344 const std::vector<int> * node_map = nullptr,
345 const std::vector<int> * inverse_node_map = nullptr,
346 const std::vector<int> * side_map = nullptr,
347 const std::vector<int> * inverse_side_map = nullptr,
348 const std::vector<int> * shellface_map = nullptr,
349 const std::vector<int> * inverse_shellface_map = nullptr,
350 size_t shellface_index_offset = 0)
351 {
352 std::unique_ptr<Elem> elem = Elem::build(type);
353 auto & conv = conversion_map[elem->dim()][type];
354 conv.libmesh_type = type;
355 conv.exodus_type = exodus_type;
356 conv.node_map = node_map;
357 conv.inverse_node_map = inverse_node_map;
358 conv.side_map = side_map;
359 conv.inverse_side_map = inverse_side_map;
360 conv.shellface_map = shellface_map;
361 conv.inverse_shellface_map = inverse_shellface_map;
362 conv.shellface_index_offset = shellface_index_offset;
363 conv.n_nodes = elem->n_nodes();
364 for (int d = elem->dim()+1; d <= 3; ++d)
365 conversion_map[d][type] = conv;
366 };
367
368 convert_type(NODEELEM, "SPHERE");
369 convert_type(EDGE2, "EDGE2");
370 convert_type(EDGE3, "EDGE3");
371 convert_type(EDGE4, "EDGE4");
372 convert_type(QUAD4, "QUAD4");
373 convert_type(QUAD8, "QUAD8");
374 convert_type(QUAD9, "QUAD9");
375 convert_type(C0POLYGON, "NSIDED");
376 {
377 auto & conv = conversion_map[3][C0POLYHEDRON];
378 conv.libmesh_type = C0POLYHEDRON;
379 conv.exodus_type = "NFACED";
380 conv.dim = 3;
381 conv.n_nodes = 0;
382 }
383 convert_type(QUADSHELL4, "SHELL4", nullptr, nullptr, nullptr,
384 /* inverse_side_map = */ &quadshell4_inverse_edge_map,
385 nullptr, nullptr, /* shellface_index_offset = */ 2);
386 convert_type(QUADSHELL8, "SHELL8", nullptr, nullptr, nullptr,
387 /* inverse_side_map = */ &quadshell4_inverse_edge_map,
388 nullptr, nullptr, /* shellface_index_offset = */ 2);
389 convert_type(QUADSHELL9, "SHELL9", nullptr, nullptr, nullptr,
390 /* inverse_side_map = */ &quadshell4_inverse_edge_map,
391 nullptr, nullptr, /* shellface_index_offset = */ 2);
392
393 convert_type(TRI3, "TRI3");
394 convert_type(TRI6, "TRI6");
395 convert_type(TRI7, "TRI7");
396 // Exodus does weird things to triangle side mapping in 3D. See
397 // https://sandialabs.github.io/seacas-docs/html/element_types.html#tri
398 conversion_map[3][TRI3].inverse_side_map = &trishell3_inverse_edge_map;
399 conversion_map[3][TRI3].shellface_index_offset = 2;
400 conversion_map[3][TRI6].inverse_side_map = &trishell3_inverse_edge_map;
401 conversion_map[3][TRI6].shellface_index_offset = 2;
402 conversion_map[3][TRI7].inverse_side_map = &trishell3_inverse_edge_map;
403 conversion_map[3][TRI7].shellface_index_offset = 2;
404
405 convert_type(TRISHELL3, "TRISHELL3", nullptr, nullptr, nullptr,
406 /* inverse_side_map = */ &trishell3_inverse_edge_map,
407 nullptr, nullptr, /* shellface_index_offset = */ 2);
408 convert_type(TRI3SUBDIVISION, "TRI3");
409 convert_type(HEX8, "HEX8", nullptr, nullptr,
410 &hex_face_map, &hex_inverse_face_map);
411 convert_type(HEX20, "HEX20", nullptr, nullptr,
412 &hex_face_map, &hex_inverse_face_map);
413 convert_type(HEX27, "HEX27", &hex27_node_map,
414 &hex27_inverse_node_map,
415 &hex_face_map, &hex_inverse_face_map);
416 convert_type(TET4, "TETRA4", nullptr, nullptr,
417 &tet_face_map, &tet_inverse_face_map);
418 convert_type(TET10, "TETRA10", nullptr, nullptr,
419 &tet_face_map, &tet_inverse_face_map);
420 convert_type(TET14, "TETRA14", &tet14_node_map,
421 &tet14_inverse_node_map,
422 &tet_face_map, &tet_inverse_face_map);
423 convert_type(PRISM6, "WEDGE", nullptr, nullptr,
424 &prism_face_map, &prism_inverse_face_map);
425 convert_type(PRISM15, "WEDGE15", nullptr, nullptr,
426 &prism_face_map, &prism_inverse_face_map);
427 convert_type(PRISM18, "WEDGE18", nullptr, nullptr,
428 &prism_face_map, &prism_inverse_face_map);
429 convert_type(PRISM20, "WEDGE20", &prism20_node_map,
430 &prism20_inverse_node_map,
431 &prism_face_map, &prism_inverse_face_map);
432 convert_type(PRISM21, "WEDGE21", &prism21_node_map,
433 &prism21_inverse_node_map,
434 &prism_face_map, &prism_inverse_face_map);
435 convert_type(PYRAMID5, "PYRAMID5");
436 convert_type(PYRAMID13, "PYRAMID13");
437 convert_type(PYRAMID14, "PYRAMID14");
438 convert_type(PYRAMID18, "PYRAMID18");
439}
ElemType
Defines an enum for geometric element types.

References libMesh::Elem::build(), libMesh::C0POLYGON, libMesh::C0POLYHEDRON, libMesh::ExodusII_IO_Helper::conversion_map, libMesh::EDGE2, libMesh::EDGE3, libMesh::EDGE4, libMesh::HEX20, libMesh::HEX27, libMesh::HEX8, libMesh::NODEELEM, libMesh::PRISM15, libMesh::PRISM18, libMesh::PRISM20, libMesh::PRISM21, libMesh::PRISM6, libMesh::PYRAMID13, libMesh::PYRAMID14, libMesh::PYRAMID18, libMesh::PYRAMID5, libMesh::QUAD4, libMesh::QUAD8, libMesh::QUAD9, libMesh::QUADSHELL4, libMesh::QUADSHELL8, libMesh::QUADSHELL9, libMesh::TET10, libMesh::TET14, libMesh::TET4, libMesh::TRI3, libMesh::TRI3SUBDIVISION, libMesh::TRI6, libMesh::TRI7, and libMesh::TRISHELL3.

Referenced by libMesh::ExodusII_IO_Helper::ExodusII_IO_Helper().

◆ init_element_equivalence_map()

void libMesh::ExodusII_IO_Helper::init_element_equivalence_map ( )
privateinherited

Definition at line 445 of file exodusII_io_helper.C.

446{
447 // We use an ExodusII SPHERE element to represent a NodeElem
449
450 // EDGE2 equivalences
456 element_equivalence_map["TRUSS2"] = EDGE2;
459
460 // EDGE3 equivalences
462 element_equivalence_map["TRUSS3"] = EDGE3;
465
466 // EDGE4 equivalences
468 element_equivalence_map["TRUSS4"] = EDGE4;
471
472 // This whole design is going to need to be refactored whenever we
473 // support higher-order IGA, with one element type having variable
474 // polynomiaal degree...
475 element_equivalence_map["BEX_CURVE"] = EDGE3;
476
477 // QUAD4 equivalences
480
481 // QUADSHELL4 equivalences
484
485 // QUAD8 equivalences
487
488 // QUADSHELL8 equivalences
490
491 // QUAD9 equivalences
493 // This only supports p==2 IGA:
494 element_equivalence_map["BEX_QUAD"] = QUAD9;
495
496 // QUADSHELL9 equivalences
498
499 // Runtime-topology polytope equivalences
502
503 // TRI3 equivalences
506 element_equivalence_map["TRIANGLE"] = TRI3;
507
508 // TRISHELL3 equivalences
510 element_equivalence_map["TRISHELL3"] = TRISHELL3;
511
512 // TRI6 equivalences
514 // element_equivalence_map["TRISHELL6"] = TRI6;
515 // This only supports p==2 IGA:
516 element_equivalence_map["BEX_TRIANGLE"] = TRI6;
517
518 // TRI7 equivalences
520
521 // HEX8 equivalences
524
525 // HEX20 equivalences
527
528 // HEX27 equivalences
530 // This only supports p==2 IGA:
531 element_equivalence_map["BEX_HEX"] = HEX27;
532
533 // TET4 equivalences
534 element_equivalence_map["TETRA"] = TET4;
535 element_equivalence_map["TETRA4"] = TET4;
536
537 // TET10 equivalences
538 element_equivalence_map["TETRA10"] = TET10;
539 // This only supports p==2 IGA:
540 element_equivalence_map["BEX_TETRA"] = TET10;
541
542 // TET14 (in Exodus 8) equivalence
543 element_equivalence_map["TETRA14"] = TET14;
544
545 // PRISM6 equivalences
548
549 // PRISM15 equivalences
550 element_equivalence_map["WEDGE15"] = PRISM15;
551
552 // PRISM18 equivalences
553 element_equivalence_map["WEDGE18"] = PRISM18;
554 // This only supports p==2 IGA:
555 element_equivalence_map["BEX_WEDGE"] = PRISM18;
556
557 // PRISM20 equivalences
558 element_equivalence_map["WEDGE20"] = PRISM20;
559
560 // PRISM21 equivalences
561 element_equivalence_map["WEDGE21"] = PRISM21;
562
563 // PYRAMID equivalences
565 element_equivalence_map["PYRAMID5"] = PYRAMID5;
566 element_equivalence_map["PYRAMID13"] = PYRAMID13;
567 element_equivalence_map["PYRAMID14"] = PYRAMID14;
568 element_equivalence_map["PYRAMID18"] = PYRAMID18;
569}

References libMesh::C0POLYGON, libMesh::C0POLYHEDRON, libMesh::EDGE2, libMesh::EDGE3, libMesh::EDGE4, libMesh::ExodusII_IO_Helper::element_equivalence_map, libMesh::HEX20, libMesh::HEX27, libMesh::HEX8, libMesh::NODEELEM, libMesh::PRISM15, libMesh::PRISM18, libMesh::PRISM20, libMesh::PRISM21, libMesh::PRISM6, libMesh::PYRAMID13, libMesh::PYRAMID14, libMesh::PYRAMID18, libMesh::PYRAMID5, libMesh::QUAD4, libMesh::QUAD8, libMesh::QUAD9, libMesh::QUADSHELL4, libMesh::QUADSHELL8, libMesh::QUADSHELL9, libMesh::TET10, libMesh::TET14, libMesh::TET4, libMesh::TRI3, libMesh::TRI6, libMesh::TRI7, and libMesh::TRISHELL3.

Referenced by libMesh::ExodusII_IO_Helper::ExodusII_IO_Helper().

◆ initialize()

void libMesh::Nemesis_IO_Helper::initialize ( std::string  title,
const MeshBase mesh,
bool  use_discontinuous = false 
)
overridevirtual

Specialization of the initialize function from ExodusII_IO_Helper that also writes global initial data to file.

Reimplemented from libMesh::ExodusII_IO_Helper.

Definition at line 754 of file nemesis_io_helper.C.

755{
756 // Make sure that the reference passed in is really a DistributedMesh
757 // const DistributedMesh & pmesh = cast_ref<const DistributedMesh &>(mesh);
758 const MeshBase & pmesh = mesh;
759
760 // If _write_as_dimension is nonzero, use it to set num_dim later in the Exodus file.
764 num_dim = mesh.mesh_dimension();
765 else
766 num_dim = mesh.spatial_dimension();
767
768 // According to Nemesis documentation, first call when writing should be to
769 // ne_put_init_info(). Our reader doesn't actually call this, but we should
770 // strive to be as close to a normal nemesis file as possible...
771 this->put_init_info(this->n_processors(), 1, "p");
772
773
774 // Gather global "initial" information for Nemesis. This consists of
775 // three parts labeled I, II, and III below...
776
777 //
778 // I.) Need to compute the number of global element blocks. To be consistent with
779 // Exodus, we also incorrectly associate the number of element blocks with the
780 // number of libmesh subdomains...
781 //
783
784 //
785 // II.) Determine the global number of nodesets by communication.
786 // This code relies on BoundaryInfo storing side and node
787 // boundary IDs separately at the time they are added to the
788 // BoundaryInfo object.
789 //
790 this->compute_num_global_nodesets(pmesh);
791
792 //
793 // III.) Need to compute the global number of sidesets by communication:
794 // This code relies on BoundaryInfo storing side and node
795 // boundary IDs separately at the time they are added to the
796 // BoundaryInfo object.
797 //
798 this->compute_num_global_sidesets(pmesh);
799
800 // Now write the global data obtained in steps I, II, and III to the Nemesis file
801 this->put_init_global(pmesh.parallel_n_nodes(),
802 pmesh.parallel_n_elem(),
803 this->num_elem_blks_global, /* I. */
804 this->num_node_sets_global, /* II. */
805 this->num_side_sets_global /* III. */
806 );
807
808 // Next, we'll write global element block information to the file. This was already
809 // gathered in step I. above
812
813
814 // Next, write global nodeset information to the file. This was already gathered in
815 // step II. above.
816 this->num_global_node_df_counts.clear();
817 this->num_global_node_df_counts.resize(this->global_nodeset_ids.size()); // distribution factors all zero...
821
822
823 // Next, write global sideset information to the file. This was already gathered in
824 // step III. above.
825 this->num_global_side_df_counts.clear();
826 this->num_global_side_df_counts.resize(this->global_sideset_ids.size()); // distribution factors all zero...
830
831
832 // Before we go any further we need to derive consistent node and
833 // element numbering schemes for all local elems and nodes connected
834 // to local elements.
835 //
836 // Must be called *after* the local_subdomain_counts map has been constructed
837 // by the compute_num_global_elem_blocks() function!
838 this->build_element_and_node_maps(pmesh);
839
840 // Next step is to write "load balance" parameters. Several things need to
841 // be computed first though...
842
843 // First we'll collect IDs of border nodes.
844 this->compute_border_node_ids(pmesh);
845
846 // Next we'll collect numbers of internal and border elements, and internal nodes.
847 // Note: "A border node does not a border element make...", that is, just because one
848 // of an element's nodes has been identified as a border node, the element is not
849 // necessarily a border element. It must have a side on the boundary between processors,
850 // i.e. have a face neighbor with a different processor id...
852
853 // Finally we are ready to write the loadbal information to the file
855 this->num_border_nodes,
856 this->num_external_nodes,
857 this->num_internal_elems,
858 this->num_border_elems,
859 this->num_node_cmaps,
860 this->num_elem_cmaps);
861
862
863 // Now we need to compute the "communication map" parameters. These are basically
864 // lists of nodes and elements which need to be communicated between different processors
865 // when the mesh file is read back in.
867
868 // Write communication map parameters to file.
869 this->put_cmap_params(this->node_cmap_ids,
871 this->elem_cmap_ids,
872 this->elem_cmap_elem_cnts);
873
874 // Ready the node communication maps. The node IDs which
875 // are communicated are the ones currently stored in
876 // proc_nodes_touched_intersections.
878
879 // Write the packed node communication vectors to file.
881 this->node_cmap_proc_ids);
882
883 // Ready the node maps. These have nothing to do with communication, they map
884 // the nodes to internal, border, and external nodes in the file.
885 this->compute_node_maps();
886
887 // Call the Nemesis API to write the node maps to file.
888 this->put_node_map(this->node_mapi,
889 this->node_mapb,
890 this->node_mape);
891
892 // Ready the element communication maps. This includes border
893 // element IDs, sides which are on the border, and the processors to which
894 // they are to be communicated...
896
897 // Call the Nemesis API to write the packed element communication maps vectors to file
899 this->elem_cmap_side_ids,
900 this->elem_cmap_proc_ids);
901
902 // Ready the Nemesis element maps (internal and border) for writing to file.
903 this->compute_element_maps();
904
905 // Call the Nemesis API to write the internal and border element IDs.
906 this->put_elem_map(this->elem_mapi,
907 this->elem_mapb);
908
909 // Now write Exodus-specific initialization information, some of which is
910 // different when you are using Nemesis.
911 this->write_exodus_initialization_info(pmesh, title_in);
912} // end initialize()
void compute_node_maps()
Compute the node maps (really just pack vectors) which map the nodes to internal, border,...
void put_node_map(std::vector< int > &node_mapi, std::vector< int > &node_mapb, std::vector< int > &node_mape)
Outputs IDs of internal, border, and external nodes.
void put_loadbal_param(unsigned num_internal_nodes, unsigned num_border_nodes, unsigned num_external_nodes, unsigned num_internal_elems, unsigned num_border_elems, unsigned num_node_cmaps, unsigned num_elem_cmaps)
Writes load balance parameters, some of which are described below: .) num_internal_nodes - nodes "who...
void put_node_cmap(std::vector< std::vector< int > > &node_cmap_node_ids, std::vector< std::vector< int > > &node_cmap_proc_ids)
Outputs all of the nodal communication maps for this processor.
void put_ns_param_global(std::vector< int > &global_nodeset_ids, std::vector< int > &num_global_node_counts, std::vector< int > &num_global_node_df_counts)
This function writes information about global node sets.
void put_init_info(unsigned num_proc, unsigned num_proc_in_file, const char *ftype)
Writing functions.
void put_ss_param_global(std::vector< int > &global_sideset_ids, std::vector< int > &num_global_side_counts, std::vector< int > &num_global_side_df_counts)
This function writes information about global side sets.
void compute_communication_map_parameters()
This function determines the communication map parameters which will eventually be written to file.
void compute_num_global_elem_blocks(const MeshBase &pmesh)
This function uses global communication routines to determine the number of element blocks across the...
void compute_num_global_nodesets(const MeshBase &pmesh)
This function uses global communication routines to determine the number of nodesets across the entir...
void put_elem_cmap(std::vector< std::vector< int > > &elem_cmap_elem_ids, std::vector< std::vector< int > > &elem_cmap_side_ids, std::vector< std::vector< int > > &elem_cmap_proc_ids)
Writes information about elemental communication map.
void write_exodus_initialization_info(const MeshBase &pmesh, const std::string &title)
This function writes exodus-specific initialization information.
void compute_elem_communication_maps()
This function computes element communication maps (really just packs vectors) in preparation for writ...
void compute_element_maps()
This function computes element maps (really just packs vectors) which map the elements to internal an...
void put_elem_map(std::vector< int > &elem_mapi, std::vector< int > &elem_mapb)
Outputs IDs of internal and border elements.
void compute_internal_and_border_elems_and_internal_nodes(const MeshBase &pmesh)
This function constructs the set of border and internal element IDs and internal node IDs present on ...
void compute_num_global_sidesets(const MeshBase &pmesh)
This function uses global communication routines to determine the number of sidesets across the entir...
void put_cmap_params(std::vector< int > &node_cmap_ids, std::vector< int > &node_cmap_node_cnts, std::vector< int > &elem_cmap_ids, std::vector< int > &elem_cmap_elem_cnts)
Outputs initial information for communication maps.
void compute_border_node_ids(const MeshBase &pmesh)
This function constructs the set of border node IDs present on the current mesh.
void build_element_and_node_maps(const MeshBase &pmesh)
This function builds the libmesh -> exodus and exodus -> libmesh node and element maps.
void put_eb_info_global(std::vector< int > &global_elem_blk_ids, std::vector< int > &global_elem_blk_cnts)
Writes global block information to the file .) global_elem_blk_ids - list of block IDs for all blocks...
void put_init_global(dof_id_type num_nodes_global, dof_id_type num_elems_global, unsigned num_elem_blks_global, unsigned num_node_sets_global, unsigned num_side_sets_global)
Writes global information including: .) global number of nodes .) global number of elems ....
void compute_node_communication_maps()
Compute the node communication maps (really just pack vectors) in preparation for writing them to fil...

References libMesh::ExodusII_IO_Helper::_use_mesh_dimension_instead_of_spatial_dimension, libMesh::ExodusII_IO_Helper::_write_as_dimension, build_element_and_node_maps(), compute_border_node_ids(), compute_communication_map_parameters(), compute_elem_communication_maps(), compute_element_maps(), compute_internal_and_border_elems_and_internal_nodes(), compute_node_communication_maps(), compute_node_maps(), compute_num_global_elem_blocks(), compute_num_global_nodesets(), compute_num_global_sidesets(), elem_cmap_elem_cnts, elem_cmap_elem_ids, elem_cmap_ids, elem_cmap_proc_ids, elem_cmap_side_ids, elem_mapb, elem_mapi, global_elem_blk_cnts, global_elem_blk_ids, global_nodeset_ids, global_sideset_ids, mesh, libMesh::MeshBase::mesh_dimension(), libMesh::ParallelObject::n_processors(), node_cmap_ids, node_cmap_node_cnts, node_cmap_node_ids, node_cmap_proc_ids, node_mapb, node_mape, node_mapi, num_border_elems, num_border_nodes, libMesh::ExodusII_IO_Helper::num_dim, num_elem_cmaps, num_external_nodes, num_global_node_counts, num_global_node_df_counts, num_global_side_counts, num_global_side_df_counts, num_internal_elems, num_internal_nodes, num_node_cmaps, libMesh::MeshBase::parallel_n_elem(), libMesh::MeshBase::parallel_n_nodes(), put_cmap_params(), put_eb_info_global(), put_elem_cmap(), put_elem_map(), put_init_global(), put_init_info(), put_loadbal_param(), put_node_cmap(), put_node_map(), put_ns_param_global(), put_ss_param_global(), and write_exodus_initialization_info().

◆ initialize_element_variables()

void libMesh::Nemesis_IO_Helper::initialize_element_variables ( std::vector< std::string >  names,
const std::vector< std::set< subdomain_id_type > > &  vars_active_subdomains 
)
overridevirtual

Override the Exodus Helper's implementation of this function so that it works correctly in parallel.

Reimplemented from libMesh::ExodusII_IO_Helper.

Definition at line 2582 of file nemesis_io_helper.C.

2584{
2585 // Quick return if there are no element variables to write
2586 if (names.size() == 0)
2587 return;
2588
2589 // Quick return if we have already called this function
2591 return;
2592
2593 // Be sure that variables in the file match what we are asking for
2594 if (num_elem_vars > 0)
2595 {
2596 this->check_existing_vars(ELEMENTAL, names, this->elem_var_names);
2597 return;
2598 }
2599
2600 // Set the flag so we can skip this stuff on subsequent calls to
2601 // initialize_element_variables()
2603
2604 this->write_var_names(ELEMENTAL, names);
2605
2606 // Create a truth table from global_elem_blk_ids and the information
2607 // in vars_active_subdomains. Create a truth table of
2608 // size global_elem_blk_ids.size() * names.size().
2609 std::vector<int> truth_tab(global_elem_blk_ids.size() * names.size());
2610 for (auto blk : index_range(global_elem_blk_ids))
2611 for (auto var : index_range(names))
2612 if (vars_active_subdomains[var].empty() ||
2613 vars_active_subdomains[var].count(cast_int<subdomain_id_type>(global_elem_blk_ids[blk])))
2614 truth_tab[names.size() * blk + var] = 1;
2615
2616 // Write truth table to file.
2617 if (truth_tab.size())
2618 {
2619 ex_err = exII::ex_put_elem_var_tab(ex_id,
2620 cast_int<int>(global_elem_blk_ids.size()),
2621 cast_int<int>(names.size()),
2622 truth_tab.data());
2623 EX_CHECK_ERR(ex_err, "Error writing element truth table.");
2624 }
2625}
void write_var_names(ExodusVarType type, const std::vector< std::string > &names)
Wraps calls to exII::ex_put_var_names() and exII::ex_put_var_param().
std::vector< std::string > elem_var_names
void check_existing_vars(ExodusVarType type, std::vector< std::string > &names, std::vector< std::string > &names_from_file)
When appending: during initialization, check that variable names in the file match those you attempt ...

References libMesh::ExodusII_IO_Helper::_elem_vars_initialized, libMesh::ExodusII_IO_Helper::check_existing_vars(), libMesh::ExodusII_IO_Helper::elem_var_names, libMesh::ExodusII_IO_Helper::ELEMENTAL, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, global_elem_blk_ids, libMesh::index_range(), libMesh::ExodusII_IO_Helper::num_elem_vars, and libMesh::ExodusII_IO_Helper::write_var_names().

◆ initialize_global_variables()

void libMesh::ExodusII_IO_Helper::initialize_global_variables ( std::vector< std::string >  names)
inherited

Sets up the global variables.

Definition at line 3996 of file exodusII_io_helper.C.

3997{
3998 if ((_run_only_on_proc0) && (this->processor_id() != 0))
3999 return;
4000
4001 // Quick return if there are no global variables to write
4002 if (names.size() == 0)
4003 return;
4004
4006 return;
4007
4008 // Be sure that variables in the file match what we are asking for
4009 if (num_global_vars > 0)
4010 {
4011 this->check_existing_vars(GLOBAL, names, this->global_var_names);
4012 return;
4013 }
4014
4016
4017 this->write_var_names(GLOBAL, names);
4018}
std::vector< std::string > global_var_names

References libMesh::ExodusII_IO_Helper::_global_vars_initialized, libMesh::ExodusII_IO_Helper::_run_only_on_proc0, libMesh::ExodusII_IO_Helper::check_existing_vars(), libMesh::ExodusII_IO_Helper::GLOBAL, libMesh::ExodusII_IO_Helper::global_var_names, libMesh::ExodusII_IO_Helper::num_global_vars, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::write_var_names().

◆ initialize_nodal_variables()

void libMesh::ExodusII_IO_Helper::initialize_nodal_variables ( std::vector< std::string >  names)
inherited

Sets up the nodal variables.

Definition at line 3968 of file exodusII_io_helper.C.

3969{
3970 if ((_run_only_on_proc0) && (this->processor_id() != 0))
3971 return;
3972
3973 // Quick return if there are no nodal variables to write
3974 if (names.size() == 0)
3975 return;
3976
3977 // Quick return if we have already called this function
3979 return;
3980
3981 // Be sure that variables in the file match what we are asking for
3982 if (num_nodal_vars > 0)
3983 {
3984 this->check_existing_vars(NODAL, names, this->nodal_var_names);
3985 return;
3986 }
3987
3988 // Set the flag so we can skip the rest of this function on subsequent calls.
3990
3991 this->write_var_names(NODAL, names);
3992}
std::vector< std::string > nodal_var_names

References libMesh::ExodusII_IO_Helper::_nodal_vars_initialized, libMesh::ExodusII_IO_Helper::_run_only_on_proc0, libMesh::ExodusII_IO_Helper::check_existing_vars(), libMesh::ExodusII_IO_Helper::NODAL, libMesh::ExodusII_IO_Helper::nodal_var_names, libMesh::ExodusII_IO_Helper::num_nodal_vars, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::write_var_names().

◆ message() [1/2]

void libMesh::ExodusII_IO_Helper::message ( std::string_view  msg)
inherited

◆ message() [2/2]

void libMesh::ExodusII_IO_Helper::message ( std::string_view  msg,
int  i 
)
inherited

Prints the message defined in msg, and appends the number i to the end of the message.

Useful for printing messages in loops. Can be turned off if verbosity is set to 0.

Definition at line 600 of file exodusII_io_helper.C.

601{
602 if (verbose) libMesh::out << msg << i << "." << std::endl;
603}

References libMesh::out, and libMesh::ExodusII_IO_Helper::verbose.

◆ 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
uint8_t processor_id_type
Definition id_types.h:104

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(), compute_border_node_ids(), construct_nemesis_filename(), libMesh::UnstructuredMesh::copy_nodes_and_elements(), libMesh::ExodusII_IO::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(), 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(), libMesh::ExodusII_IO::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().

◆ node_id_to_vec_id()

dof_id_type libMesh::ExodusII_IO_Helper::node_id_to_vec_id ( dof_id_type  n) const
inlineinherited

Definition at line 966 of file exodusII_io_helper.h.

967 {
968 if (_added_side_node_offsets.empty())
969 return n;
970
971 // Find the processor id that has node_id in the parallel vec
972 const auto lb = std::upper_bound(_true_node_offsets.begin(),
973 _true_node_offsets.end(), n);
975 const processor_id_type p = lb - _true_node_offsets.begin();
976
977 return n + (p ? _added_side_node_offsets[p-1] : 0);
978 }

References libMesh::ExodusII_IO_Helper::_added_side_node_offsets, libMesh::ExodusII_IO_Helper::_true_node_offsets, and libMesh::libmesh_assert().

◆ open()

void libMesh::ExodusII_IO_Helper::open ( const char *  filename,
bool  read_only 
)
inherited

Opens an ExodusII mesh file named filename.

If read_only==true, the file will be opened with the EX_READ flag, otherwise it will be opened with the EX_WRITE flag.

Definition at line 692 of file exodusII_io_helper.C.

693{
694 // Version of Exodus you are using
695 float ex_version = 0.;
696
697 int comp_ws = 0;
698
700 comp_ws = cast_int<int>(sizeof(float));
701
702 // Fall back on double precision when necessary since ExodusII
703 // doesn't seem to support long double
704 else
705 comp_ws = cast_int<int>(std::min(sizeof(Real), sizeof(double)));
706
707 // Word size in bytes of the floating point data as they are stored
708 // in the ExodusII file. "If this argument is 0, the word size of the
709 // floating point data already stored in the file is returned"
710 int io_ws = 0;
711
712 {
713 FPEDisabler disable_fpes;
714 ex_id = exII::ex_open(filename,
715 read_only ? EX_READ : EX_WRITE,
716 &comp_ws,
717 &io_ws,
718 &ex_version);
719 }
720
721 std::string err_msg = std::string("Error opening ExodusII mesh file: ") + std::string(filename);
722 EX_CHECK_ERR(ex_id, err_msg);
723 if (verbose) libMesh::out << "File opened successfully." << std::endl;
724
725 // If we're writing then we'll want to use the specified length;
726 // if we're reading then we'll override this by what's in the file.
727 int max_name_length_to_set = _max_name_length;
728
729 if (read_only)
730 {
731 opened_for_reading = true;
732 elem_node_counts.clear();
733 elem_face_counts.clear();
735
736 // ExodusII reads truncate to 32-char strings by default; we'd
737 // like to support whatever's in the file, so as early as possible
738 // let's find out what that is.
739 int max_name_length = exII::ex_inquire_int(ex_id, exII::EX_INQ_DB_MAX_USED_NAME_LENGTH);
740
741 libmesh_error_msg_if(max_name_length > MAX_LINE_LENGTH,
742 "Unexpected maximum name length of " <<
743 max_name_length << " in file " << filename <<
744 " exceeds expected " << MAX_LINE_LENGTH);
745
746 // I don't think the 32 here should be necessary, but let's make
747 // sure we don't accidentally make things *worse* for anyone.
748 max_name_length_to_set = std::max(max_name_length, 32);
749 }
750 else
751 opened_for_writing = true;
752
753 ex_err = exII::ex_set_max_name_length(ex_id, max_name_length_to_set);
754 EX_CHECK_ERR(ex_err, "Error setting max ExodusII name length.");
755
756 current_filename = std::string(filename);
757}
std::vector< int > elem_face_counts
std::vector< std::vector< int > > c0polyhedron_face_connect
std::vector< int > elem_node_counts

References libMesh::ExodusII_IO_Helper::_max_name_length, libMesh::ExodusII_IO_Helper::_single_precision, libMesh::ExodusII_IO_Helper::c0polyhedron_face_connect, libMesh::ExodusII_IO_Helper::current_filename, libMesh::ExodusII_IO_Helper::elem_face_counts, libMesh::ExodusII_IO_Helper::elem_node_counts, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::opened_for_reading, libMesh::ExodusII_IO_Helper::opened_for_writing, libMesh::out, libMesh::Real, and libMesh::ExodusII_IO_Helper::verbose.

◆ print_header()

void libMesh::ExodusII_IO_Helper::print_header ( )
inherited

Prints the ExodusII mesh file header, which includes the mesh title, the number of nodes, number of elements, mesh dimension, number of sidesets, and number of nodesets.

Definition at line 889 of file exodusII_io_helper.C.

890{
891 if (verbose)
892 libMesh::out << "Title: \t" << title.data() << std::endl
893 << "Mesh Dimension: \t" << num_dim << std::endl
894 << "Number of Nodes: \t" << num_nodes << std::endl
895 << "Number of elements: \t" << num_elem << std::endl
896 << "Number of elt blocks: \t" << num_elem_blk << std::endl
897 << "Number of node sets: \t" << num_node_sets << std::endl
898 << "Number of side sets: \t" << num_side_sets << std::endl
899 << "Number of elem sets: \t" << num_elem_sets << std::endl;
900}

References libMesh::ExodusII_IO_Helper::num_dim, libMesh::ExodusII_IO_Helper::num_elem, libMesh::ExodusII_IO_Helper::num_elem_blk, libMesh::ExodusII_IO_Helper::num_elem_sets, libMesh::ExodusII_IO_Helper::num_node_sets, libMesh::ExodusII_IO_Helper::num_nodes, libMesh::ExodusII_IO_Helper::num_side_sets, libMesh::out, libMesh::ExodusII_IO_Helper::title, and libMesh::ExodusII_IO_Helper::verbose.

◆ print_nodes()

void libMesh::ExodusII_IO_Helper::print_nodes ( std::ostream &  out_stream = libMesh::out)
inherited

Prints the nodal information, by default to libMesh::out.

Definition at line 1091 of file exodusII_io_helper.C.

1092{
1093 for (int i=0; i<num_nodes; i++)
1094 out_stream << "(" << x[i] << ", " << y[i] << ", " << z[i] << ")" << std::endl;
1095}

References libMesh::ExodusII_IO_Helper::num_nodes, libMesh::ExodusII_IO_Helper::x, libMesh::ExodusII_IO_Helper::y, and libMesh::ExodusII_IO_Helper::z.

◆ 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()); }
processor_id_type rank() const

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(), 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(), compute_border_node_ids(), compute_communication_map_parameters(), compute_internal_and_border_elems_and_internal_nodes(), libMesh::RBConstruction::compute_max_error_bound(), compute_node_communication_maps(), compute_num_global_elem_blocks(), compute_num_global_nodesets(), compute_num_global_sidesets(), construct_nemesis_filename(), libMesh::ExodusII_IO::copy_elemental_solution(), libMesh::ExodusII_IO::copy_nodal_solution(), libMesh::ExodusII_IO::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(), get_cmap_params(), get_eb_info_global(), get_elem_cmap(), get_elem_map(), libMesh::MeshBase::get_info(), get_init_global(), get_init_info(), libMesh::RBEIMEvaluation::get_interior_basis_functions_as_vecs(), get_loadbal_param(), libMesh::DofMap::get_local_constraints(), libMesh::MeshBase::get_local_constraints(), get_node_cmap(), get_node_map(), get_ns_param_global(), 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(), put_cmap_params(), put_elem_cmap(), put_elem_map(), put_loadbal_param(), put_node_cmap(), 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(), libMesh::ExodusII_IO::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(), 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(), libMesh::ExodusII_IO::write_element_data(), libMesh::ExodusII_IO::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(), libMesh::ExodusII_IO::write_global_data(), libMesh::ExodusII_IO_Helper::write_global_values(), libMesh::System::write_header(), libMesh::ExodusII_IO::write_information_records(), libMesh::ExodusII_IO_Helper::write_information_records(), libMesh::ExodusII_IO_Helper::write_nodal_coordinates(), libMesh::ExodusII_IO::write_nodal_data(), libMesh::VTKIO::write_nodal_data(), libMesh::UCDIO::write_nodal_data(), libMesh::ExodusII_IO::write_nodal_data_common(), libMesh::ExodusII_IO::write_nodal_data_discontinuous(), libMesh::ExodusII_IO_Helper::write_nodal_values(), libMesh::ExodusII_IO_Helper::write_nodeset_data(), libMesh::ExodusII_IO_Helper::write_nodesets(), 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(), write_sidesets(), libMesh::ExodusII_IO::write_timestep(), libMesh::ExodusII_IO_Helper::write_timestep(), and libMesh::ExodusII_IO::write_timestep_discontinuous().

◆ put_cmap_params()

void libMesh::Nemesis_IO_Helper::put_cmap_params ( std::vector< int > &  node_cmap_ids,
std::vector< int > &  node_cmap_node_cnts,
std::vector< int > &  elem_cmap_ids,
std::vector< int > &  elem_cmap_elem_cnts 
)

Outputs initial information for communication maps.

Note
The order of the arguments specified in the Nemesis User's Manual is wrong. The correct order is (ids, counts, ids, counts). Must be called after put_loadbal_param().

Definition at line 639 of file nemesis_io_helper.C.

643{
645 Nemesis::ne_put_cmap_params(ex_id,
646 node_cmap_ids_in.empty() ? nullptr : node_cmap_ids_in.data(),
647 node_cmap_node_cnts_in.empty() ? nullptr : node_cmap_node_cnts_in.data(),
648 elem_cmap_ids_in.empty() ? nullptr : elem_cmap_ids_in.data(),
649 elem_cmap_elem_cnts_in.empty() ? nullptr : elem_cmap_elem_cnts_in.data(),
650 this->processor_id());
651
652 EX_CHECK_ERR(nemesis_err_flag, "Error writing cmap parameters!");
653}

References libMesh::ExodusII_IO_Helper::ex_id, nemesis_err_flag, and libMesh::ParallelObject::processor_id().

Referenced by initialize().

◆ put_eb_info_global()

void libMesh::Nemesis_IO_Helper::put_eb_info_global ( std::vector< int > &  global_elem_blk_ids,
std::vector< int > &  global_elem_blk_cnts 
)

Writes global block information to the file .) global_elem_blk_ids - list of block IDs for all blocks present in the mesh .) global_elem_blk_cnts - number of elements in each block for the global mesh.

Must be called after put_init_global().

Definition at line 559 of file nemesis_io_helper.C.

561{
563 Nemesis::ne_put_eb_info_global(ex_id,
564 global_elem_blk_ids_in.data(),
565 global_elem_blk_cnts_in.data());
566
567 EX_CHECK_ERR(nemesis_err_flag, "Error writing global element block information!");
568}

References libMesh::ExodusII_IO_Helper::ex_id, and nemesis_err_flag.

Referenced by initialize().

◆ put_elem_cmap()

void libMesh::Nemesis_IO_Helper::put_elem_cmap ( std::vector< std::vector< int > > &  elem_cmap_elem_ids,
std::vector< std::vector< int > > &  elem_cmap_side_ids,
std::vector< std::vector< int > > &  elem_cmap_proc_ids 
)

Writes information about elemental communication map.

Note
This class contains elem_cmap_elem_ids, elem_cmap_side_ids, abd elem_cmap_proc_ids which can be used when calling this function.

Must be called after put_cmap_params().

Definition at line 719 of file nemesis_io_helper.C.

722{
723 for (auto i : index_range(elem_cmap_ids))
724 {
726 Nemesis::ne_put_elem_cmap(ex_id,
727 this->elem_cmap_ids[i],
728 elem_cmap_elem_ids_in[i].data(),
729 elem_cmap_side_ids_in[i].data(),
730 elem_cmap_proc_ids_in[i].data(),
731 this->processor_id());
732
733 EX_CHECK_ERR(nemesis_err_flag, "Error writing elem communication map to file!");
734 }
735}

References elem_cmap_ids, libMesh::ExodusII_IO_Helper::ex_id, libMesh::index_range(), nemesis_err_flag, and libMesh::ParallelObject::processor_id().

Referenced by initialize().

◆ put_elem_map()

void libMesh::Nemesis_IO_Helper::put_elem_map ( std::vector< int > &  elem_mapi,
std::vector< int > &  elem_mapb 
)

Outputs IDs of internal and border elements.

Must be called after ne_put_loadbal_param().

Definition at line 740 of file nemesis_io_helper.C.

742{
744 Nemesis::ne_put_elem_map(ex_id,
745 elem_mapi_in.empty() ? nullptr : elem_mapi_in.data(),
746 elem_mapb_in.empty() ? nullptr : elem_mapb_in.data(),
747 this->processor_id());
748
749 EX_CHECK_ERR(nemesis_err_flag, "Error writing Nemesis internal and border element maps to file!");
750}

References libMesh::ExodusII_IO_Helper::ex_id, nemesis_err_flag, and libMesh::ParallelObject::processor_id().

Referenced by initialize().

◆ put_init_global()

void libMesh::Nemesis_IO_Helper::put_init_global ( dof_id_type  num_nodes_global,
dof_id_type  num_elems_global,
unsigned  num_elem_blks_global,
unsigned  num_node_sets_global,
unsigned  num_side_sets_global 
)

Writes global information including: .) global number of nodes .) global number of elems .) global number of element blocks .) global number of node sets .) global number of side sets.

Definition at line 540 of file nemesis_io_helper.C.

545{
547 Nemesis::ne_put_init_global(ex_id,
548 num_nodes_global_in,
549 num_elems_global_in,
550 num_elem_blks_global_in,
551 num_node_sets_global_in,
552 num_side_sets_global_in);
553
554 EX_CHECK_ERR(nemesis_err_flag, "Error writing initial global data!");
555}

References libMesh::ExodusII_IO_Helper::ex_id, and nemesis_err_flag.

Referenced by initialize().

◆ put_init_info()

void libMesh::Nemesis_IO_Helper::put_init_info ( unsigned  num_proc,
unsigned  num_proc_in_file,
const char *  ftype 
)

Writing functions.

Writes basic info about the partitioning to file .) num_proc - number of processors .) num_proc_in_file - number of processors in the current file - generally equal to 1 .) ftype = "s" for scalar load-balance file, "p" for parallel file

Definition at line 524 of file nemesis_io_helper.C.

527{
529 Nemesis::ne_put_init_info(ex_id,
530 num_proc_in,
531 num_proc_in_file_in,
532 const_cast<char *>(ftype_in));
533
534 EX_CHECK_ERR(nemesis_err_flag, "Error writing initial information!");
535}

References libMesh::ExodusII_IO_Helper::ex_id, and nemesis_err_flag.

Referenced by initialize().

◆ put_loadbal_param()

void libMesh::Nemesis_IO_Helper::put_loadbal_param ( unsigned  num_internal_nodes,
unsigned  num_border_nodes,
unsigned  num_external_nodes,
unsigned  num_internal_elems,
unsigned  num_border_elems,
unsigned  num_node_cmaps,
unsigned  num_elem_cmaps 
)

Writes load balance parameters, some of which are described below: .) num_internal_nodes - nodes "wholly" owned by the current processor .) num_border_nodes - nodes local to a processor but residing in an element which also has nodes on other processors .) num_external_nodes - nodes that reside on other processors but whose element "partially" resides on the current processor – we assert this should be zero on reading! .) num_border_elems - elements local to this processor but whose nodes reside on other processors as well.

.) processor - ID of the processor for which information is to be written

Definition at line 613 of file nemesis_io_helper.C.

620{
622 Nemesis::ne_put_loadbal_param(ex_id,
623 num_internal_nodes_in,
624 num_border_nodes_in,
625 num_external_nodes_in,
626 num_internal_elems_in,
627 num_border_elems_in,
628 num_node_cmaps_in,
629 num_elem_cmaps_in,
630 this->processor_id());
631
632 EX_CHECK_ERR(nemesis_err_flag, "Error writing loadbal parameters!");
633}

References libMesh::ExodusII_IO_Helper::ex_id, nemesis_err_flag, and libMesh::ParallelObject::processor_id().

Referenced by initialize().

◆ put_node_cmap()

void libMesh::Nemesis_IO_Helper::put_node_cmap ( std::vector< std::vector< int > > &  node_cmap_node_ids,
std::vector< std::vector< int > > &  node_cmap_proc_ids 
)

Outputs all of the nodal communication maps for this processor.

Internally, this function loops over all communication maps and calls Nemesis::ne_put_node_cmap() for each one.

.) node_cmap_node_ids = Nodal IDs of the FEM nodes in this communication map .) node_cmap_proc_ids = processor IDs associated with each of the nodes in node_ids

In the Nemesis file, these all appear to be written to the same chunks of data: n_comm_nids and n_comm_proc, but don't rely on these names...

Note
This class contains node_cmap_node_ids and node_cmap_proc_ids which can be used when calling this function.

Must be called after put_cmap_params().

Definition at line 658 of file nemesis_io_helper.C.

660{
661 // Print to screen what we are about to print to Nemesis file
662 if (verbose)
663 {
664 for (auto i : index_range(node_cmap_node_ids_in))
665 {
666 libMesh::out << "[" << this->processor_id() << "] put_node_cmap() : nodes communicated to proc "
667 << this->node_cmap_ids[i]
668 << " = ";
669 for (const auto & node_id : node_cmap_node_ids_in[i])
670 libMesh::out << node_id << " ";
671 libMesh::out << std::endl;
672 }
673
674 for (auto i : index_range(node_cmap_node_ids_in))
675 {
676 libMesh::out << "[" << this->processor_id() << "] put_node_cmap() : processor IDs = ";
677 for (const auto & proc_id : node_cmap_proc_ids_in[i])
678 libMesh::out << proc_id << " ";
679 libMesh::out << std::endl;
680 }
681 }
682
683 for (auto i : index_range(node_cmap_node_ids_in))
684 {
685 int * node_ids_ptr = node_cmap_node_ids_in[i].empty() ?
686 nullptr : node_cmap_node_ids_in[i].data();
687 int * proc_ids_ptr = node_cmap_proc_ids_in[i].empty() ?
688 nullptr : node_cmap_proc_ids_in[i].data();
689
691 Nemesis::ne_put_node_cmap(ex_id, this->node_cmap_ids[i],
692 node_ids_ptr, proc_ids_ptr,
693 this->processor_id());
694
695 EX_CHECK_ERR(nemesis_err_flag, "Error writing node communication map to file!");
696 }
697}

References libMesh::ExodusII_IO_Helper::ex_id, libMesh::index_range(), nemesis_err_flag, node_cmap_ids, libMesh::out, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::verbose.

Referenced by initialize().

◆ put_node_map()

void libMesh::Nemesis_IO_Helper::put_node_map ( std::vector< int > &  node_mapi,
std::vector< int > &  node_mapb,
std::vector< int > &  node_mape 
)

Outputs IDs of internal, border, and external nodes.

LibMesh asserts that the number of external nodes is zero in the Nemesis files it reads

Definition at line 702 of file nemesis_io_helper.C.

705{
707 Nemesis::ne_put_node_map(ex_id,
708 node_mapi_in.empty() ? nullptr : node_mapi_in.data(),
709 node_mapb_in.empty() ? nullptr : node_mapb_in.data(),
710 node_mape_in.empty() ? nullptr : node_mape_in.data(),
711 this->processor_id());
712
713 EX_CHECK_ERR(nemesis_err_flag, "Error writing Nemesis internal and border node maps to file!");
714}

References libMesh::ExodusII_IO_Helper::ex_id, nemesis_err_flag, and libMesh::ParallelObject::processor_id().

Referenced by initialize().

◆ put_ns_param_global()

void libMesh::Nemesis_IO_Helper::put_ns_param_global ( std::vector< int > &  global_nodeset_ids,
std::vector< int > &  num_global_node_counts,
std::vector< int > &  num_global_node_df_counts 
)

This function writes information about global node sets.

.) global_nodeset_ids - vector of global node set IDs .) num_global_node_counts - vector of global node counts contained in each global node set .) num_global_df_count - vector of global distribution factors in each global node set

Must be called after put_init_global()

Definition at line 573 of file nemesis_io_helper.C.

576{
577 // Only add nodesets if there are some
578 if (global_nodeset_ids.size())
579 {
581 Nemesis::ne_put_ns_param_global(ex_id,
582 global_nodeset_ids_in.data(),
583 num_global_node_counts_in.data(),
584 num_global_node_df_counts_in.data());
585 }
586
587 EX_CHECK_ERR(nemesis_err_flag, "Error writing global nodeset parameters!");
588}

References libMesh::ExodusII_IO_Helper::ex_id, global_nodeset_ids, and nemesis_err_flag.

Referenced by initialize().

◆ put_ss_param_global()

void libMesh::Nemesis_IO_Helper::put_ss_param_global ( std::vector< int > &  global_sideset_ids,
std::vector< int > &  num_global_side_counts,
std::vector< int > &  num_global_side_df_counts 
)

This function writes information about global side sets.

.) global_sideset_ids - vector of global side set IDs .) num_global_side_counts - vector of global side counts contained in each global side set .) num_global_df_count - vector of global distribution factors in each global side set

Must be called after put_init_global()

Definition at line 593 of file nemesis_io_helper.C.

596{
597 // Only add sidesets if there are some
598 if (global_sideset_ids.size())
599 {
601 Nemesis::ne_put_ss_param_global(ex_id,
602 global_sideset_ids_in.data(),
603 num_global_side_counts_in.data(),
604 num_global_side_df_counts_in.data());
605 }
606
607 EX_CHECK_ERR(nemesis_err_flag, "Error writing global sideset parameters!");
608}

References libMesh::ExodusII_IO_Helper::ex_id, global_sideset_ids, and nemesis_err_flag.

Referenced by initialize().

◆ read_all_nodesets()

void libMesh::ExodusII_IO_Helper::read_all_nodesets ( )
inherited

New API that reads all nodesets simultaneously.

This may be slightly faster than reading them one at a time. Calls ex_get_concat_node_sets() under the hood.

Definition at line 1970 of file exodusII_io_helper.C.

1971{
1972 LOG_SCOPE("read_all_nodesets()", "ExodusII_IO_Helper");
1973
1974 // Figure out how many nodesets there are in the file so we can
1975 // properly resize storage as necessary.
1977 inquire
1978 (*this, exII::EX_INQ_NODE_SETS,
1979 "Error retrieving number of node sets");
1980
1981 // Figure out how many nodes there are in all the nodesets.
1982 int total_nodes_in_all_sets =
1983 inquire
1984 (*this, exII::EX_INQ_NS_NODE_LEN,
1985 "Error retrieving number of nodes in all node sets.");
1986
1987 // Figure out how many distribution factors there are in all the nodesets.
1988 int total_df_in_all_sets =
1989 inquire
1990 (*this, exII::EX_INQ_NS_DF_LEN,
1991 "Error retrieving number of distribution factors in all node sets.");
1992
1993 // If there are no nodesets, there's nothing to read in.
1994 if (num_node_sets == 0)
1995 return;
1996
1997 // Allocate space to read all the nodeset data.
1998 // Use existing class members where possible to avoid shadowing
1999 nodeset_ids.clear(); nodeset_ids.resize(num_node_sets);
2004 node_sets_node_list.clear(); node_sets_node_list.resize(total_nodes_in_all_sets);
2005 node_sets_dist_fact.clear(); node_sets_dist_fact.resize(total_df_in_all_sets);
2006
2007 // Handle single-precision files
2008 MappedInputVector mapped_node_sets_dist_fact(node_sets_dist_fact, _single_precision);
2009
2010 // Build exII::ex_set_spec struct
2011 exII::ex_set_specs set_specs = {};
2012 set_specs.sets_ids = nodeset_ids.data();
2013 set_specs.num_entries_per_set = num_nodes_per_set.data();
2014 set_specs.num_dist_per_set = num_node_df_per_set.data();
2015 set_specs.sets_entry_index = node_sets_node_index.data();
2016 set_specs.sets_dist_index = node_sets_dist_index.data();
2017 set_specs.sets_entry_list = node_sets_node_list.data();
2018 set_specs.sets_extra_list = nullptr;
2019 set_specs.sets_dist_fact = total_df_in_all_sets ? mapped_node_sets_dist_fact.data() : nullptr;
2020
2021 ex_err = exII::ex_get_concat_sets(ex_id, exII::EX_NODE_SET, &set_specs);
2022 EX_CHECK_ERR(ex_err, "Error reading concatenated nodesets");
2023
2024 // Read the nodeset names from file!
2025 char name_buffer[libmesh_max_str_length+1];
2026 for (int i=0; i<num_node_sets; ++i)
2027 {
2028 ex_err = exII::ex_get_name
2029 (ex_id,
2030 exII::EX_NODE_SET,
2031 nodeset_ids[i],
2032 name_buffer);
2033 EX_CHECK_ERR(ex_err, "Error getting node set name.");
2034 id_to_ns_names[nodeset_ids[i]] = name_buffer;
2035 }
2036}
std::vector< int > node_sets_dist_index
std::vector< int > node_sets_node_index
std::vector< int > num_node_df_per_set
std::vector< Real > node_sets_dist_fact

References libMesh::ExodusII_IO_Helper::_single_precision, libMesh::ExodusII_IO_Helper::MappedInputVector::data(), libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::id_to_ns_names, libMesh::ExodusII_IO_Helper::node_sets_dist_fact, libMesh::ExodusII_IO_Helper::node_sets_dist_index, libMesh::ExodusII_IO_Helper::node_sets_node_index, libMesh::ExodusII_IO_Helper::node_sets_node_list, libMesh::ExodusII_IO_Helper::nodeset_ids, libMesh::ExodusII_IO_Helper::num_node_df_per_set, libMesh::ExodusII_IO_Helper::num_node_sets, and libMesh::ExodusII_IO_Helper::num_nodes_per_set.

Referenced by libMesh::ExodusII_IO_Helper::write_nodeset_data().

◆ read_and_store_header_info()

void libMesh::ExodusII_IO_Helper::read_and_store_header_info ( )
inherited

Reads an ExodusII mesh file header, and stores required information on this object.

Definition at line 794 of file exodusII_io_helper.C.

795{
796 // Read header params from file, storing them in this class's
797 // ExodusHeaderInfo struct. This automatically updates the local
798 // num_dim, num_elem, etc. references.
799 this->header_info = this->read_header();
800
801 // Read the number of timesteps which are present in the file
802 this->read_num_time_steps();
803
804 ex_err = exII::ex_get_variable_param(ex_id, exII::EX_NODAL, &num_nodal_vars);
805 EX_CHECK_ERR(ex_err, "Error reading number of nodal variables.");
806
807 ex_err = exII::ex_get_variable_param(ex_id, exII::EX_ELEM_BLOCK, &num_elem_vars);
808 EX_CHECK_ERR(ex_err, "Error reading number of elemental variables.");
809
810 ex_err = exII::ex_get_variable_param(ex_id, exII::EX_GLOBAL, &num_global_vars);
811 EX_CHECK_ERR(ex_err, "Error reading number of global variables.");
812
813 ex_err = exII::ex_get_variable_param(ex_id, exII::EX_SIDE_SET, &num_sideset_vars);
814 EX_CHECK_ERR(ex_err, "Error reading number of sideset variables.");
815
816 ex_err = exII::ex_get_variable_param(ex_id, exII::EX_NODE_SET, &num_nodeset_vars);
817 EX_CHECK_ERR(ex_err, "Error reading number of nodeset variables.");
818
819 ex_err = exII::ex_get_variable_param(ex_id, exII::EX_ELEM_SET, &num_elemset_vars);
820 EX_CHECK_ERR(ex_err, "Error reading number of elemset variables.");
821
822 message("Exodus header info retrieved successfully.");
823}
ExodusHeaderInfo read_header() const
Reads an ExodusII mesh file header, leaving this object's internal data structures unchanged.
void read_num_time_steps()
Reads the number of timesteps currently stored in the Exodus file and stores it in the num_time_steps...

References libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::header_info, libMesh::ExodusII_IO_Helper::message(), libMesh::ExodusII_IO_Helper::num_elem_vars, libMesh::ExodusII_IO_Helper::num_elemset_vars, libMesh::ExodusII_IO_Helper::num_global_vars, libMesh::ExodusII_IO_Helper::num_nodal_vars, libMesh::ExodusII_IO_Helper::num_nodeset_vars, libMesh::ExodusII_IO_Helper::num_sideset_vars, libMesh::ExodusII_IO_Helper::read_header(), and libMesh::ExodusII_IO_Helper::read_num_time_steps().

◆ read_bex_cv_blocks()

void libMesh::ExodusII_IO_Helper::read_bex_cv_blocks ( )
inherited

Reads the optional bex_cv_blocks from the ExodusII mesh file.

Definition at line 979 of file exodusII_io_helper.C.

980{
981 // If a bex blob exists, we look for Bezier Extraction coefficient
982 // data there.
983
984 // These APIs require newer Exodus than 5.22
985#if EX_API_VERS_NODOT >= 800
986 int n_blobs = exII::ex_inquire_int(ex_id, exII::EX_INQ_BLOB);
987
988 if (n_blobs > 0)
989 {
990 std::vector<exII::ex_blob> blobs(n_blobs);
991 std::vector<std::vector<char>> blob_names(n_blobs);
992 for (auto i : make_range(n_blobs))
993 {
994 blob_names[i].resize(libmesh_max_str_length+1);
995 blobs[i].name = blob_names[i].data();
996 }
997
998 ex_err = exII::ex_get_blobs(ex_id, blobs.data());
999 EX_CHECK_ERR(ex_err, "Error getting blobs.");
1000
1001 bool found_blob = false;
1002 const exII::ex_blob * my_blob = &blobs[0];
1003 for (const auto & blob : blobs)
1004 {
1005 if (std::string("bex_cv_blob") == blob.name)
1006 {
1007 found_blob = true;
1008 my_blob = &blob;
1009 }
1010 }
1011
1012 if (!found_blob)
1013 libmesh_error_msg("Found no bex_cv_blob for bezier elements");
1014
1015 const int n_blob_attr =
1016 exII::ex_get_attribute_count(ex_id, exII::EX_BLOB,
1017 my_blob->id);
1018
1019 std::vector<exII::ex_attribute> attributes(n_blob_attr);
1020 ex_err = exII::ex_get_attribute_param(ex_id, exII::EX_BLOB,
1021 my_blob->id,
1022 attributes.data());
1023 EX_CHECK_ERR(ex_err, "Error getting bex blob attribute parameters.");
1024
1025 int bex_num_dense_cv_blocks = 0;
1026 std::vector<int> bex_dense_cv_info;
1027 for (auto & attr : attributes)
1028 {
1029 if (std::string("bex_dense_cv_info") == attr.name)
1030 {
1031 const std::size_t value_count = attr.value_count;
1032 if (value_count % 2)
1033 libmesh_error_msg("Found odd number of bex_dense_cv_info");
1034
1035 bex_dense_cv_info.resize(value_count);
1036 attr.values = bex_dense_cv_info.data();
1037 exII::ex_get_attribute(ex_id, &attr);
1038
1039 bex_num_dense_cv_blocks = value_count / 2;
1040
1041 libmesh_error_msg_if(bex_num_dense_cv_blocks > 1,
1042 "Found more than 1 dense bex CV block; unsure how to handle that");
1043 }
1044 }
1045
1046 if (bex_dense_cv_info.empty())
1047 libmesh_error_msg("No bex_dense_cv_info found");
1048
1049 int n_blob_vars;
1050 exII::ex_get_variable_param(ex_id, exII::EX_BLOB, &n_blob_vars);
1051 std::vector<char> var_name (libmesh_max_str_length + 1);
1052 for (auto v_id : make_range(1,n_blob_vars+1))
1053 {
1054 ex_err = exII::ex_get_variable_name(ex_id, exII::EX_BLOB, v_id, var_name.data());
1055 EX_CHECK_ERR(ex_err, "Error reading bex blob var name.");
1056
1057 if (std::string("bex_dense_cv_blocks") == var_name.data())
1058 {
1059 std::vector<double> bex_dense_cv_blocks(my_blob->num_entry);
1060
1061 ex_err = exII::ex_get_var(ex_id, 1, exII::EX_BLOB, v_id,
1062 my_blob->id, my_blob->num_entry,
1063 bex_dense_cv_blocks.data());
1064 EX_CHECK_ERR(ex_err, "Error reading bex_dense_cv_blocks.");
1065
1067 bex_dense_constraint_vecs.resize(bex_num_dense_cv_blocks);
1068
1069 std::size_t offset = 0;
1070 for (auto i : IntRange<std::size_t>(0, bex_num_dense_cv_blocks))
1071 {
1072 bex_dense_constraint_vecs[i].resize(bex_dense_cv_info[2*i]);
1073 const int vecsize = bex_dense_cv_info[2*i+1];
1074 for (auto & vec : bex_dense_constraint_vecs[i])
1075 {
1076 vec.resize(vecsize);
1077 std::copy(std::next(bex_dense_cv_blocks.begin(), offset),
1078 std::next(bex_dense_cv_blocks.begin(), offset + vecsize),
1079 vec.begin());
1080 offset += vecsize;
1081 }
1082 }
1083 libmesh_assert(offset == bex_dense_cv_blocks.size());
1084 }
1085 }
1086 }
1087#endif // EX_API_VERS_NODOT >= 800
1088}
std::vector< std::vector< std::vector< Real > > > bex_dense_constraint_vecs
The IntRange templated class is intended to make it easy to loop over integers which are indices of a...
Definition int_range.h:54

References libMesh::ExodusII_IO_Helper::bex_dense_constraint_vecs, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::libmesh_assert(), and libMesh::make_range().

◆ read_block_info()

void libMesh::ExodusII_IO_Helper::read_block_info ( )
inherited

Reads information for all of the blocks in the ExodusII mesh file.

Definition at line 1099 of file exodusII_io_helper.C.

1100{
1101 if (num_elem_blk)
1102 {
1103 // Read all element block IDs.
1104 block_ids.resize(num_elem_blk);
1105 ex_err = exII::ex_get_ids(ex_id,
1106 exII::EX_ELEM_BLOCK,
1107 block_ids.data());
1108
1109 EX_CHECK_ERR(ex_err, "Error getting block IDs.");
1110 message("All block IDs retrieved successfully.");
1111
1112 char name_buffer[libmesh_max_str_length+1];
1113 for (int i=0; i<num_elem_blk; ++i)
1114 {
1115 ex_err = exII::ex_get_name(ex_id, exII::EX_ELEM_BLOCK,
1116 block_ids[i], name_buffer);
1117 EX_CHECK_ERR(ex_err, "Error getting block name.");
1118 id_to_block_names[block_ids[i]] = name_buffer;
1119 }
1120 message("All block names retrieved successfully.");
1121 }
1122
1123 if (num_edge_blk)
1124 {
1125 // Read all edge block IDs.
1127 ex_err = exII::ex_get_ids(ex_id,
1128 exII::EX_EDGE_BLOCK,
1129 edge_block_ids.data());
1130
1131 EX_CHECK_ERR(ex_err, "Error getting edge block IDs.");
1132 message("All edge block IDs retrieved successfully.");
1133
1134 // Read in edge block names
1135 char name_buffer[libmesh_max_str_length+1];
1136 for (int i=0; i<num_edge_blk; ++i)
1137 {
1138 ex_err = exII::ex_get_name(ex_id, exII::EX_EDGE_BLOCK,
1139 edge_block_ids[i], name_buffer);
1140 EX_CHECK_ERR(ex_err, "Error getting block name.");
1141 id_to_edge_block_names[edge_block_ids[i]] = name_buffer;
1142 }
1143 message("All edge block names retrieved successfully.");
1144 }
1145}
std::map< int, std::string > id_to_edge_block_names

References libMesh::ExodusII_IO_Helper::block_ids, libMesh::ExodusII_IO_Helper::edge_block_ids, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::id_to_block_names, libMesh::ExodusII_IO_Helper::id_to_edge_block_names, libMesh::ExodusII_IO_Helper::message(), libMesh::ExodusII_IO_Helper::num_edge_blk, and libMesh::ExodusII_IO_Helper::num_elem_blk.

◆ read_edge_blocks()

void libMesh::ExodusII_IO_Helper::read_edge_blocks ( MeshBase mesh)
inherited

Read in edge blocks, storing information in the BoundaryInfo object.

Definition at line 1567 of file exodusII_io_helper.C.

1568{
1569 LOG_SCOPE("read_edge_blocks()", "ExodusII_IO_Helper");
1570
1571 // Check for quick return if there are no edge blocks.
1572 if (num_edge_blk == 0)
1573 return;
1574
1575 // Build data structure that we can quickly search for edges
1576 // and then add required BoundaryInfo information. This is a
1577 // map from edge->key() to a list of (elem_id, edge_id) pairs
1578 // for the Edge in question. Since edge->key() is edge orientation
1579 // invariant, this map does not distinguish different orientations
1580 // of the same Edge. Since edge->key() is also not guaranteed to be
1581 // unique (though it is very unlikely for two distinct edges to have
1582 // the same key()), when we later look up an (elem_id, edge_id) pair
1583 // in the edge_map, we need to verify that the edge indeed matches
1584 // the searched edge by doing some further checks.
1585 typedef std::pair<dof_id_type, unsigned int> ElemEdgePair;
1586 std::unordered_map<dof_id_type, std::vector<ElemEdgePair>> edge_map;
1587 std::unique_ptr<Elem> edge_ptr;
1588 for (const auto & elem : mesh.element_ptr_range())
1589 for (auto e : elem->edge_index_range())
1590 {
1591 elem->build_edge_ptr(edge_ptr, e);
1592 dof_id_type edge_key = edge_ptr->key();
1593
1594 // Creates vector if not already there
1595 auto & vec = edge_map[edge_key];
1596 vec.emplace_back(elem->id(), e);
1597
1598 // If edge_ptr is a higher-order Elem (EDGE3 or higher) then also add
1599 // a map entry for the lower-order (EDGE2) element which has matching
1600 // vertices. This allows us to match lower-order edge blocks to edges
1601 // of higher-order 3D elems (e.g. HEX20, TET10) and simplifies the
1602 // definition of edge blocks.
1603 if (edge_ptr->default_order() != FIRST)
1604 {
1605 // Construct a temporary low-order edge so that we can compute its key()
1606 auto low_order_edge =
1608
1609 // Assign node pointers to low-order edge
1610 for (unsigned int v=0; v<edge_ptr->n_vertices(); ++v)
1611 low_order_edge->set_node(v, edge_ptr->node_ptr(v));
1612
1613 // Compute the key for the temporary low-order edge we just built
1614 dof_id_type low_order_edge_key = low_order_edge->key();
1615
1616 // Add this key to the map associated with the same (elem,
1617 // edge) pair as the higher-order edge
1618 auto & low_order_vec = edge_map[low_order_edge_key];
1619 low_order_vec.emplace_back(elem->id(), e);
1620 }
1621 }
1622
1623 // Get reference to the mesh's BoundaryInfo object, as we will be
1624 // adding edges to this below.
1626
1627 for (const auto & edge_block_id : edge_block_ids)
1628 {
1629 // exII::ex_get_block() output parameters. Unlike the other
1630 // "extended" APIs, exII::ex_get_block() does not use a
1631 // parameter struct.
1632 int num_edge_this_blk = 0;
1633 int num_nodes_per_edge = 0;
1634 int num_edges_per_edge = 0;
1635 int num_faces_per_edge = 0;
1636 int num_attr_per_edge = 0;
1637 ex_err = exII::ex_get_block(ex_id,
1638 exII::EX_EDGE_BLOCK,
1639 edge_block_id,
1640 elem_type.data(),
1641 &num_edge_this_blk,
1642 &num_nodes_per_edge,
1643 &num_edges_per_edge, // 0 or -1 for edge blocks
1644 &num_faces_per_edge, // 0 or -1 for edge blocks
1645 &num_attr_per_edge);
1646
1647 EX_CHECK_ERR(ex_err, "Error getting edge block info.");
1648 message("Info retrieved successfully for block: ", edge_block_id);
1649
1650 // Read in the connectivity of the edges of this block,
1651 // watching out for the case where we actually have no
1652 // elements in this block (possible with parallel files)
1653 connect.resize(num_nodes_per_edge * num_edge_this_blk);
1654
1655 if (!connect.empty())
1656 {
1657 ex_err = exII::ex_get_conn(ex_id,
1658 exII::EX_EDGE_BLOCK,
1659 edge_block_id,
1660 connect.data(), // node_conn
1661 nullptr, // elem_edge_conn (unused)
1662 nullptr); // elem_face_conn (unused)
1663
1664 EX_CHECK_ERR(ex_err, "Error reading block connectivity.");
1665 message("Connectivity retrieved successfully for block: ", edge_block_id);
1666
1667 // All edge types have an identity mapping from the corresponding
1668 // Exodus type, so we don't need to bother with mapping ids, but
1669 // we do need to know what kind of elements to build.
1670 const auto & conv = get_conversion(std::string(elem_type.data()));
1671
1672 // Loop over indices in connectivity array, build edge elements,
1673 // look them up in the edge_map.
1674 for (auto [i, sz] = std::make_tuple(0u, connect.size()); i<sz; i+=num_nodes_per_edge)
1675 {
1676 auto edge = Elem::build(conv.libmesh_elem_type());
1677 for (int n=0; n<num_nodes_per_edge; ++n)
1678 {
1679 auto exodus_node_id = this->connect[i+n];
1680 dof_id_type libmesh_node_id = this->get_libmesh_node_id(exodus_node_id);
1681 edge->set_node(n, mesh.node_ptr(libmesh_node_id));
1682 }
1683
1684 // Compute key for the edge Elem we just built.
1685 dof_id_type edge_key = edge->key();
1686
1687 // If this key is not found in the edge_map, which is
1688 // supposed to include every edge in the Mesh, then we
1689 // will throw an error now.
1690 auto & elem_edge_pair_vec =
1691 libmesh_map_find(edge_map, edge_key);
1692
1693 for (const auto & elem_edge_pair : elem_edge_pair_vec)
1694 {
1695 // We only want to match edges which have the same
1696 // nodes (possibly with different orientation) to the one in the
1697 // Exodus file, otherwise we ignore this elem_edge_pair.
1698 //
1699 // Note: this also handles the situation where two
1700 // edges have the same key (hash collision) as then
1701 // this check avoids a false positive.
1702
1703 // Build edge indicated by elem_edge_pair
1704 mesh.elem_ptr(elem_edge_pair.first)->
1705 build_edge_ptr(edge_ptr, elem_edge_pair.second);
1706
1707 // Determine whether this candidate edge is a "real" match,
1708 // i.e. has the same nodes with a possibly different
1709 // orientation. Note that here we only check that
1710 // the vertices match regardless of how many nodes
1711 // the edge has, which allows us to match a
1712 // lower-order edge to a higher-order Elem.
1713 bool is_match =
1714 ((edge_ptr->node_id(0) == edge->node_id(0)) && (edge_ptr->node_id(1) == edge->node_id(1))) ||
1715 ((edge_ptr->node_id(0) == edge->node_id(1)) && (edge_ptr->node_id(1) == edge->node_id(0)));
1716
1717 if (is_match)
1718 {
1719 // Add this (elem, edge, id) combo to the BoundaryInfo object.
1720 bi.add_edge(elem_edge_pair.first,
1721 elem_edge_pair.second,
1722 edge_block_id);
1723 }
1724 } // end loop over elem_edge_pairs
1725 } // end loop over connectivity array
1726
1727 // Set edgeset name in the BoundaryInfo object.
1728 bi.edgeset_name(edge_block_id) = id_to_edge_block_names[edge_block_id];
1729 } // end if !connect.empty()
1730 } // end for edge_block_id : edge_block_ids
1731}
The BoundaryInfo class contains information relevant to boundary conditions including storing faces,...
void add_edge(const dof_id_type elem, const unsigned short int edge, const boundary_id_type id)
Add edge edge of element number elem with boundary id id to the boundary information data structure.
std::string & edgeset_name(boundary_id_type id)
static ElemType first_order_equivalent_type(const ElemType et)
Definition elem.C:3099
dof_id_type get_libmesh_node_id(int exodus_node_id)
Helper function that takes a (1-based) Exodus node/elem id and determines the corresponding libMesh N...
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

References libMesh::BoundaryInfo::add_edge(), libMesh::Elem::build(), libMesh::ExodusII_IO_Helper::connect, libMesh::ExodusII_IO_Helper::edge_block_ids, libMesh::BoundaryInfo::edgeset_name(), libMesh::MeshBase::elem_ptr(), libMesh::ExodusII_IO_Helper::elem_type, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::FIRST, libMesh::Elem::first_order_equivalent_type(), libMesh::MeshBase::get_boundary_info(), libMesh::ExodusII_IO_Helper::get_conversion(), libMesh::ExodusII_IO_Helper::get_libmesh_node_id(), libMesh::ExodusII_IO_Helper::id_to_edge_block_names, mesh, libMesh::ExodusII_IO_Helper::message(), libMesh::MeshBase::node_ptr(), and libMesh::ExodusII_IO_Helper::num_edge_blk.

◆ read_elem_in_block()

void libMesh::ExodusII_IO_Helper::read_elem_in_block ( int  block)
inherited

Reads all of the element connectivity for block block in the ExodusII mesh file.

Definition at line 1322 of file exodusII_io_helper.C.

1323{
1324 LOG_SCOPE("read_elem_in_block()", "ExodusII_IO_Helper");
1325
1326 libmesh_assert_less (block, block_ids.size());
1327 elem_node_counts.clear();
1328 elem_face_counts.clear();
1329
1330 // Unlike the other "extended" APIs, this one does not use a parameter struct.
1331 int num_edges_per_elem = 0;
1332 int num_faces_per_elem = 0;
1333 int num_node_data_per_elem = 0;
1334 ex_err = exII::ex_get_block(ex_id,
1335 exII::EX_ELEM_BLOCK,
1336 block_ids[block],
1337 elem_type.data(),
1339 &num_node_data_per_elem,
1340 &num_edges_per_elem, // 0 or -1 if no "extended" block info
1341 &num_faces_per_elem, // 0 or -1 if no "extended" block info
1342 &num_attr);
1343
1344 EX_CHECK_ERR(ex_err, "Error getting block info.");
1345 message("Info retrieved successfully for block: ", block);
1346
1347 // Nemesis uses "Empty" as the element type for blocks with no
1348 // elements on the current processor. There is no element conversion
1349 // for that sentinel type, nor is one needed for an empty block.
1350 const bool is_bezier = is_bezier_elem(elem_type.data());
1351 const Conversion * conversion = nullptr;
1352 if (num_elem_this_blk || is_bezier)
1353 conversion = &get_conversion(std::string(elem_type.data()));
1354
1355 const bool is_c0polygon =
1356 conversion && conversion->libmesh_elem_type() == C0POLYGON;
1357 const bool is_c0polyhedron =
1358 conversion && conversion->libmesh_elem_type() == C0POLYHEDRON;
1359
1360 // Warn or error when we don't currently support reading blocks with extended info.
1361 // Note: the docs say -1 will be returned for this but I found that it was
1362 // actually 0, so not sure which it will be in general.
1363 if (is_c0polyhedron && !(num_edges_per_elem == 0) && !(num_edges_per_elem == -1))
1364 libmesh_error_msg("Error: Exodus NFACED element blocks with edge "
1365 "connectivity are not currently supported.");
1366 else if (!(num_edges_per_elem == 0) && !(num_edges_per_elem == -1))
1367 libmesh_warning("Exodus files with extended edge connectivity not currently supported.");
1368 if (!is_c0polyhedron && !(num_faces_per_elem == 0) && !(num_faces_per_elem == -1))
1369 libmesh_warning("Exodus files with extended face connectivity not currently supported.");
1370
1371 // If we have a Bezier element here, then we've packed constraint
1372 // vector connectivity at the end of the nodal connectivity, and
1373 // num_nodes_per_elem reflected both.
1374 if (is_bezier)
1375 {
1376 libmesh_assert(conversion);
1377 num_nodes_per_elem = conversion->n_nodes;
1378 }
1379 else if (is_c0polygon)
1380 {
1382
1383 if (!elem_node_counts.empty())
1384 {
1385 ex_err = exII::ex_get_entity_count_per_polyhedra
1386 (ex_id,
1387 exII::EX_ELEM_BLOCK,
1388 block_ids[block],
1389 elem_node_counts.data());
1390 EX_CHECK_ERR(ex_err, "Error reading polygon node counts");
1391 }
1392
1393 int counted_nodes = 0;
1394 for (const auto count : elem_node_counts)
1395 counted_nodes += count;
1396
1397 libmesh_error_msg_if(counted_nodes != num_node_data_per_elem,
1398 "Error: Exodus NSIDED block "
1399 << block_ids[block]
1400 << " says it has " << num_node_data_per_elem
1401 << " total node entries, but its per-element "
1402 << "node counts sum to " << counted_nodes << ".");
1403
1405 }
1406 else if (is_c0polyhedron)
1407 {
1408 if (c0polyhedron_face_connect.empty())
1409 this->read_face_blocks();
1410
1412
1413 if (!elem_face_counts.empty())
1414 {
1415 ex_err = exII::ex_get_entity_count_per_polyhedra
1416 (ex_id,
1417 exII::EX_ELEM_BLOCK,
1418 block_ids[block],
1419 elem_face_counts.data());
1420 EX_CHECK_ERR(ex_err, "Error reading polyhedron face counts");
1421 }
1422
1423 int counted_faces = 0;
1424 for (const auto count : elem_face_counts)
1425 counted_faces += count;
1426
1427 libmesh_error_msg_if(counted_faces != num_faces_per_elem,
1428 "Error: Exodus NFACED block "
1429 << block_ids[block]
1430 << " says it has " << num_faces_per_elem
1431 << " total face entries, but its per-element "
1432 << "face counts sum to " << counted_faces << ".");
1433
1435 }
1436 else
1437 num_nodes_per_elem = num_node_data_per_elem;
1438
1439 if (verbose)
1440 {
1441 libMesh::out << "Read a block of " << num_elem_this_blk
1442 << " " << elem_type.data() << "(s)";
1443 if (is_c0polygon)
1444 libMesh::out << " having " << num_node_data_per_elem
1445 << " total node entries.";
1446 else if (is_c0polyhedron)
1447 libMesh::out << " having " << num_faces_per_elem
1448 << " total face entries.";
1449 else
1450 libMesh::out << " having " << num_nodes_per_elem
1451 << " nodes per element.";
1452 libMesh::out << std::endl;
1453 }
1454
1455 // Read in the connectivity of the elements of this block,
1456 // watching out for the case where we actually have no
1457 // elements in this block (possible with parallel files)
1458 connect.resize(is_c0polygon ?
1459 num_node_data_per_elem :
1460 is_c0polyhedron ?
1461 num_faces_per_elem :
1462 num_node_data_per_elem*num_elem_this_blk);
1463
1464 if (!connect.empty())
1465 {
1466 ex_err = exII::ex_get_conn(ex_id,
1467 exII::EX_ELEM_BLOCK,
1468 block_ids[block],
1469 is_c0polyhedron ? nullptr : connect.data(),
1470 nullptr, // elem_edge_conn (unused)
1471 is_c0polyhedron ? connect.data() : nullptr);
1472
1473 EX_CHECK_ERR(ex_err, "Error reading block connectivity.");
1474 message("Connectivity retrieved successfully for block: ", block);
1475 }
1476
1477 // If we had any attributes for this block, check to see if some of
1478 // them were Bezier-extension attributes.
1479
1480 // num_attr above is zero, not actually the number of block attributes?
1481 // ex_get_attr_param *also* gives me zero? Really, Exodus?
1482#if EX_API_VERS_NODOT >= 800
1483 int real_n_attr = exII::ex_get_attribute_count(ex_id, exII::EX_ELEM_BLOCK, block_ids[block]);
1484 EX_CHECK_ERR(real_n_attr, "Error getting number of element block attributes.");
1485
1486 if (real_n_attr > 0)
1487 {
1488 std::vector<exII::ex_attribute> attributes(real_n_attr);
1489
1490 ex_err = exII::ex_get_attribute_param(ex_id, exII::EX_ELEM_BLOCK, block_ids[block], attributes.data());
1491 EX_CHECK_ERR(ex_err, "Error getting element block attribute parameters.");
1492
1493 ex_err = exII::ex_get_attributes(ex_id, real_n_attr, attributes.data());
1494 EX_CHECK_ERR(ex_err, "Error getting element block attribute values.");
1495
1496 for (auto attr : attributes)
1497 {
1498 if (std::string("bex_elem_degrees") == attr.name)
1499 {
1500 if (attr.type != exII::EX_INTEGER)
1501 libmesh_error_msg("Found non-integer bex_elem_degrees");
1502
1503 if (attr.value_count > 3)
1504 libmesh_error_msg("Looking for at most 3 bex_elem_degrees; found " << attr.value_count);
1505
1506 libmesh_assert(is_bezier);
1507
1508 std::vector<int> bex_elem_degrees(3); // max dim
1509
1510 const int * as_int = static_cast<int *>(attr.values);
1511 std::copy(as_int, as_int+attr.value_count, bex_elem_degrees.begin());
1512
1513
1514 // Right now Bezier extraction elements aren't possible
1515 // for p>2 and aren't useful for p<2, and we don't
1516 // support anisotropic p...
1517#ifndef NDEBUG
1518 libmesh_assert(conversion);
1519 for (auto d : IntRange<int>(0, conversion->dim))
1520 libmesh_assert_equal_to(bex_elem_degrees[d], 2);
1521#endif
1522 }
1523 // ex_get_attributes did a values=calloc(); free() is our job.
1524 if (attr.values)
1525 free(attr.values);
1526 }
1527 }
1528
1529 if (is_bezier)
1530 {
1531 // We'd better have the number of cvs we expect
1532 if( num_node_data_per_elem > num_nodes_per_elem )
1533 bex_num_elem_cvs = num_node_data_per_elem / 2;
1534 else
1536 libmesh_assert_greater_equal(bex_num_elem_cvs, 0);
1537
1538 // The old connect vector is currently a mix of the expected
1539 // connectivity and any Bezier extraction connectivity;
1540 // disentangle that, if necessary.
1542 if (num_node_data_per_elem > num_nodes_per_elem)
1543 {
1544 std::vector<int> old_connect(bex_num_elem_cvs * num_elem_this_blk);
1545 old_connect.swap(connect);
1546 auto src = old_connect.data();
1547 auto dst = connect.data();
1548 for (auto e : IntRange<std::size_t>(0, num_elem_this_blk))
1549 {
1550 std::copy(src, src + bex_num_elem_cvs, dst);
1551 src += bex_num_elem_cvs;
1552 dst += bex_num_elem_cvs;
1553
1554 bex_cv_conn[e].resize(bex_num_elem_cvs);
1555 std::copy(src, src + bex_num_elem_cvs,
1556 bex_cv_conn[e].begin());
1557 src += bex_num_elem_cvs;
1558 }
1559 }
1560 }
1561
1562#endif // EX_API_VERS_NODOT >= 800
1563}
unsigned int dim
void ErrorVector unsigned int
void read_face_blocks()
Reads NSIDED face blocks used by NFACED element blocks.
std::vector< std::vector< long unsigned int > > bex_cv_conn

References libMesh::ExodusII_IO_Helper::bex_cv_conn, libMesh::ExodusII_IO_Helper::bex_num_elem_cvs, libMesh::ExodusII_IO_Helper::block_ids, libMesh::C0POLYGON, libMesh::C0POLYHEDRON, libMesh::ExodusII_IO_Helper::c0polyhedron_face_connect, libMesh::ExodusII_IO_Helper::connect, libMesh::ExodusII_IO_Helper::Conversion::dim, libMesh::ExodusII_IO_Helper::elem_face_counts, libMesh::ExodusII_IO_Helper::elem_node_counts, libMesh::ExodusII_IO_Helper::elem_type, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::get_conversion(), libMesh::libmesh_assert(), libMesh::ExodusII_IO_Helper::Conversion::libmesh_elem_type(), libMesh::ExodusII_IO_Helper::message(), libMesh::ExodusII_IO_Helper::Conversion::n_nodes, libMesh::ExodusII_IO_Helper::num_attr, libMesh::ExodusII_IO_Helper::num_elem_this_blk, libMesh::ExodusII_IO_Helper::num_nodes_per_elem, libMesh::out, libMesh::ExodusII_IO_Helper::read_face_blocks(), and libMesh::ExodusII_IO_Helper::verbose.

◆ read_elem_num_map()

void libMesh::ExodusII_IO_Helper::read_elem_num_map ( )
inherited

Reads the optional node_num_map from the ExodusII mesh file.

Definition at line 1735 of file exodusII_io_helper.C.

1736{
1737 elem_num_map.resize(num_elem);
1738
1739 // Note: we cannot use the exII::ex_get_num_map() here because it
1740 // (apparently) does not behave like ex_get_elem_num_map() when
1741 // there is no elem number map in the file: it throws an error
1742 // instead of returning a default identity array (1,2,3,...).
1743 ex_err = exII::ex_get_elem_num_map
1744 (ex_id, elem_num_map.empty() ? nullptr : elem_num_map.data());
1745
1746 EX_CHECK_ERR(ex_err, "Error retrieving element number map.");
1747 message("Element numbering map retrieved successfully.");
1748
1749 if (num_elem)
1750 {
1751 // The elem_num_map may contain ids larger than num_elem. In
1752 // other words, the elem_num_map is not necessarily just a
1753 // permutation of the "trivial" 1,2,3,... mapping, it can
1754 // contain effectively "any" numbers. Therefore, to get
1755 // "_end_elem_id", we need to check what the max entry in the
1756 // elem_num_map is.
1757 auto it = std::max_element(elem_num_map.begin(), elem_num_map.end());
1758 _end_elem_id = *it;
1759 }
1760 else
1761 _end_elem_id = 0;
1762
1763 if (verbose)
1764 {
1765 libMesh::out << "[" << this->processor_id() << "] elem_num_map[i] = ";
1766 for (unsigned int i=0; i<static_cast<unsigned int>(std::min(10, num_elem-1)); ++i)
1767 libMesh::out << elem_num_map[i] << ", ";
1768 libMesh::out << "... " << elem_num_map.back() << std::endl;
1769 }
1770}

References libMesh::ExodusII_IO_Helper::_end_elem_id, libMesh::ExodusII_IO_Helper::elem_num_map, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::message(), libMesh::ExodusII_IO_Helper::num_elem, libMesh::out, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::verbose.

◆ read_elemental_var_values()

void libMesh::ExodusII_IO_Helper::read_elemental_var_values ( std::string  elemental_var_name,
int  time_step,
std::map< dof_id_type, Real > &  elem_var_value_map 
)
inherited

Reads elemental values for the variable 'elemental_var_name' at the specified timestep into the 'elem_var_value_map' which is passed in.

Definition at line 2329 of file exodusII_io_helper.C.

2332{
2333 LOG_SCOPE("read_elemental_var_values()", "ExodusII_IO_Helper");
2334
2336
2337 // See if we can find the variable we are looking for
2338 unsigned int var_index = 0;
2339 bool found = false;
2340
2341 // Do a linear search for elem_var_name in elemental_var_names
2342 for (; var_index != elem_var_names.size(); ++var_index)
2343 if (elem_var_names[var_index] == elemental_var_name)
2344 {
2345 found = true;
2346 break;
2347 }
2348
2349 if (!found)
2350 {
2351 libMesh::err << "Available variables: " << std::endl;
2352 for (const auto & var_name : elem_var_names)
2353 libMesh::err << var_name << std::endl;
2354
2355 libmesh_error_msg("Unable to locate variable named: " << elemental_var_name);
2356 }
2357
2358 // Sequential index which we can use to look up the element ID in the elem_num_map.
2359 unsigned ex_el_num = 0;
2360
2361 // Element variable truth table
2362 std::vector<int> var_table(block_ids.size() * elem_var_names.size());
2363 exII::ex_get_truth_table(ex_id, exII::EX_ELEM_BLOCK, block_ids.size(), elem_var_names.size(), var_table.data());
2364
2365 for (unsigned i=0; i<static_cast<unsigned>(num_elem_blk); i++)
2366 {
2367 ex_err = exII::ex_get_block(ex_id,
2368 exII::EX_ELEM_BLOCK,
2369 block_ids[i],
2370 /*elem_type=*/nullptr,
2372 /*num_nodes_per_entry=*/nullptr,
2373 /*num_edges_per_entry=*/nullptr,
2374 /*num_faces_per_entry=*/nullptr,
2375 /*num_attr=*/nullptr);
2376 EX_CHECK_ERR(ex_err, "Error getting number of elements in block.");
2377
2378 // If the current variable isn't active on this subdomain, advance
2379 // the index by the number of elements on this block and go to the
2380 // next loop iteration.
2381 if (!var_table[elem_var_names.size()*i + var_index])
2382 {
2383 ex_el_num += num_elem_this_blk;
2384 continue;
2385 }
2386
2387 std::vector<Real> block_elem_var_values(num_elem_this_blk);
2388
2389 ex_err = exII::ex_get_var
2390 (ex_id,
2391 time_step,
2392 exII::EX_ELEM_BLOCK,
2393 var_index+1,
2394 block_ids[i],
2396 MappedInputVector(block_elem_var_values, _single_precision).data());
2397 EX_CHECK_ERR(ex_err, "Error getting elemental values.");
2398
2399 for (unsigned j=0; j<static_cast<unsigned>(num_elem_this_blk); j++)
2400 {
2401 // Determine the libmesh id of the element with zero-based
2402 // index "ex_el_num". This function expects a one-based
2403 // index, so we add 1 to ex_el_num when we pass it in.
2404 auto libmesh_elem_id =
2405 this->get_libmesh_elem_id(ex_el_num + 1);
2406
2407 // Store the elemental value in the map.
2408 elem_var_value_map[libmesh_elem_id] = block_elem_var_values[j];
2409
2410 // Go to the next sequential element ID.
2411 ex_el_num++;
2412 }
2413 }
2414}
dof_id_type get_libmesh_elem_id(int exodus_elem_id)

References libMesh::ExodusII_IO_Helper::_single_precision, libMesh::ExodusII_IO_Helper::block_ids, libMesh::ExodusII_IO_Helper::elem_var_names, libMesh::ExodusII_IO_Helper::ELEMENTAL, libMesh::err, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::get_libmesh_elem_id(), libMesh::ExodusII_IO_Helper::num_elem_blk, libMesh::ExodusII_IO_Helper::num_elem_this_blk, and libMesh::ExodusII_IO_Helper::read_var_names().

◆ read_elemset()

void libMesh::ExodusII_IO_Helper::read_elemset ( int  id,
int  offset 
)
inherited

Reads information about elemset id and inserts it into the global elemset array at the position offset.

Definition at line 1925 of file exodusII_io_helper.C.

1926{
1927 LOG_SCOPE("read_elemset()", "ExodusII_IO_Helper");
1928
1929 libmesh_assert_less (id, elemset_ids.size());
1930 libmesh_assert_less (id, num_elems_per_set.size());
1931 libmesh_assert_less (id, num_elem_df_per_set.size());
1932 libmesh_assert_less_equal (offset, elemset_list.size());
1933
1934 ex_err = exII::ex_get_set_param(ex_id,
1935 exII::EX_ELEM_SET,
1936 elemset_ids[id],
1937 &num_elems_per_set[id],
1938 &num_elem_df_per_set[id]);
1939 EX_CHECK_ERR(ex_err, "Error retrieving elemset parameters.");
1940 message("Parameters retrieved successfully for elemset: ", id);
1941
1942
1943 // It's OK for offset==elemset_list.size() as long as num_elems_per_set[id]==0
1944 // because in that case we don't actually read anything...
1945 #ifdef DEBUG
1946 if (static_cast<unsigned int>(offset) == elemset_list.size())
1947 libmesh_assert_equal_to (num_elems_per_set[id], 0);
1948 #endif
1949
1950 // Don't call ex_get_set() unless there are actually elems there to get.
1951 // Exodus prints an annoying warning in DEBUG mode otherwise...
1952 if (num_elems_per_set[id] > 0)
1953 {
1954 ex_err = exII::ex_get_set(ex_id,
1955 exII::EX_ELEM_SET,
1956 elemset_ids[id],
1957 &elemset_list[offset],
1958 /*set_extra_list=*/nullptr);
1959 EX_CHECK_ERR(ex_err, "Error retrieving elemset data.");
1960 message("Data retrieved successfully for elemset: ", id);
1961
1962 // Create vector containing elemset ids for each element in the set
1963 for (int i=0; i<num_elems_per_set[id]; i++)
1964 elemset_id_list[i+offset] = elemset_ids[id];
1965 }
1966}
std::vector< int > num_elem_df_per_set

References libMesh::ExodusII_IO_Helper::elemset_id_list, libMesh::ExodusII_IO_Helper::elemset_ids, libMesh::ExodusII_IO_Helper::elemset_list, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::message(), libMesh::ExodusII_IO_Helper::num_elem_df_per_set, and libMesh::ExodusII_IO_Helper::num_elems_per_set.

Referenced by libMesh::ExodusII_IO_Helper::write_elemset_data().

◆ read_elemset_data()

void libMesh::ExodusII_IO_Helper::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 
)
inherited

Read elemset variables, if any, into the provided data structures.

Definition at line 4701 of file exodusII_io_helper.C.

4706{
4707 LOG_SCOPE("read_elemset_data()", "ExodusII_IO_Helper");
4708
4709 // This reads the elemset variable names into the local
4710 // elemset_var_names data structure.
4711 this->read_var_names(ELEMSET);
4712
4713 // Debugging
4714 // libMesh::out << "elmeset variable names:" << std::endl;
4715 // for (const auto & name : elemset_var_names)
4716 // libMesh::out << name << " ";
4717 // libMesh::out << std::endl;
4718
4719 if (num_elemset_vars)
4720 {
4721 // Debugging
4722 // std::cout << "Reading " << num_elem_sets
4723 // << " elemsets and " << num_elemset_vars
4724 // << " elemset variables." << std::endl;
4725
4726 // Read the elemset data truth table.
4727 std::vector<int> elemset_var_tab(num_elem_sets * num_elemset_vars);
4728 exII::ex_get_truth_table(ex_id,
4729 exII::EX_ELEM_SET, // exII::ex_entity_type
4732 elemset_var_tab.data());
4733 EX_CHECK_ERR(ex_err, "Error reading elemset variable truth table.");
4734
4735 // Debugging
4736 // libMesh::out << "Elemset variable truth table:" << std::endl;
4737 // for (const auto & val : elemset_var_tab)
4738 // libMesh::out << val << " ";
4739 // libMesh::out << std::endl;
4740
4741 // Debugging
4742 // for (auto i : make_range(num_elem_sets))
4743 // {
4744 // for (auto j : make_range(num_elemset_vars))
4745 // libMesh::out << elemset_var_tab[num_elemset_vars*i + j] << " ";
4746 // libMesh::out << std::endl;
4747 // }
4748
4749 // Set up/allocate space in incoming data structures. All vectors are
4750 // num_elemset_vars in length.
4751 var_names = elemset_var_names;
4752 elemset_ids_in.resize(num_elemset_vars);
4753 elemset_vals.resize(num_elemset_vars);
4754
4755 // Read the elemset data
4756 int offset=0;
4757 for (int es=0; es<num_elem_sets; ++es)
4758 {
4759 offset += (es > 0 ? num_elems_per_set[es-1] : 0);
4760 for (int var=0; var<num_elemset_vars; ++var)
4761 {
4762 int is_present = elemset_var_tab[num_elemset_vars*es + var];
4763
4764 if (is_present)
4765 {
4766 // Debugging
4767 // libMesh::out << "Variable " << var << " is present on elemset " << es << std::endl;
4768
4769 // Record the fact that this variable is defined on this elemset.
4770 elemset_ids_in[var].insert(elemset_ids[es]);
4771
4772 // Note: the assumption here is that a previous call
4773 // to this->read_elemset_info() has already set the
4774 // values of num_elems_per_set, so we just use those values here.
4775 std::vector<Real> elemset_var_vals(num_elems_per_set[es]);
4776 ex_err = exII::ex_get_var
4777 (ex_id,
4778 timestep,
4779 exII::EX_ELEM_SET, // exII::ex_entity_type
4780 var + 1, // 1-based sideset variable index!
4781 elemset_ids[es],
4783 MappedInputVector(elemset_var_vals, _single_precision).data());
4784 EX_CHECK_ERR(ex_err, "Error reading elemset variable.");
4785
4786 for (int i=0; i<num_elems_per_set[es]; ++i)
4787 {
4788 dof_id_type exodus_elem_id = elemset_list[i + offset];
4789
4790 // FIXME: We should use exodus_elem_num_to_libmesh for this,
4791 // but it apparently is never set up, so just
4792 // subtract 1 from the Exodus elem id.
4793 dof_id_type converted_elem_id = exodus_elem_id - 1;
4794
4795 // Make key based on the elem and set ids
4796 auto key = std::make_pair(converted_elem_id,
4797 static_cast<elemset_id_type>(elemset_ids[es]));
4798
4799 // Store value in the map
4800 elemset_vals[var].emplace(key, elemset_var_vals[i]);
4801 } // end for (i)
4802 } // end if (present)
4803 } // end for (var)
4804 } // end for (es)
4805 } // end if (num_elemset_vars)
4806}
std::vector< std::string > elemset_var_names

References libMesh::ExodusII_IO_Helper::_single_precision, libMesh::ExodusII_IO_Helper::ELEMSET, libMesh::ExodusII_IO_Helper::elemset_ids, libMesh::ExodusII_IO_Helper::elemset_list, libMesh::ExodusII_IO_Helper::elemset_var_names, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::num_elem_sets, libMesh::ExodusII_IO_Helper::num_elems_per_set, libMesh::ExodusII_IO_Helper::num_elemset_vars, and libMesh::ExodusII_IO_Helper::read_var_names().

◆ read_elemset_info()

void libMesh::ExodusII_IO_Helper::read_elemset_info ( )
inherited

Reads information about all of the elemsets in the ExodusII mesh file.

Definition at line 1838 of file exodusII_io_helper.C.

1839{
1840 elemset_ids.resize(num_elem_sets);
1841 if (num_elem_sets > 0)
1842 {
1843 ex_err = exII::ex_get_ids(ex_id,
1844 exII::EX_ELEM_SET,
1845 elemset_ids.data());
1846 EX_CHECK_ERR(ex_err, "Error retrieving elemset information.");
1847 message("All elemset information retrieved successfully.");
1848
1849 // Resize appropriate data structures -- only do this once outside the loop
1852
1853 // Inquire about the length of the concatenated elemset list
1855 inquire(*this, exII::EX_INQ_ELS_LEN,
1856 "Error retrieving length of the concatenated elem sets element list!");
1857
1860
1861 // Debugging
1862 // libMesh::out << "num_elem_all_elemsets = " << num_elem_all_elemsets << std::endl;
1863 }
1864
1865 char name_buffer[libmesh_max_str_length+1];
1866 for (int i=0; i<num_elem_sets; ++i)
1867 {
1868 ex_err = exII::ex_get_name(ex_id, exII::EX_ELEM_SET,
1869 elemset_ids[i], name_buffer);
1870 EX_CHECK_ERR(ex_err, "Error getting node set name.");
1871 id_to_elemset_names[elemset_ids[i]] = name_buffer;
1872 }
1873 message("All elem set names retrieved successfully.");
1874}
std::map< int, std::string > id_to_elemset_names

References libMesh::ExodusII_IO_Helper::elemset_id_list, libMesh::ExodusII_IO_Helper::elemset_ids, libMesh::ExodusII_IO_Helper::elemset_list, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::id_to_elemset_names, libMesh::ExodusII_IO_Helper::message(), libMesh::ExodusII_IO_Helper::num_elem_all_elemsets, libMesh::ExodusII_IO_Helper::num_elem_df_per_set, libMesh::ExodusII_IO_Helper::num_elem_sets, and libMesh::ExodusII_IO_Helper::num_elems_per_set.

Referenced by libMesh::ExodusII_IO_Helper::write_elemset_data().

◆ read_face_blocks()

void libMesh::ExodusII_IO_Helper::read_face_blocks ( )
inherited

Reads NSIDED face blocks used by NFACED element blocks.

Definition at line 1202 of file exodusII_io_helper.C.

1203{
1204 LOG_SCOPE("read_face_blocks()", "ExodusII_IO_Helper");
1205
1206 if (!c0polyhedron_face_connect.empty())
1207 return;
1208
1209 libmesh_error_msg_if(num_face_blk == 0,
1210 "Error: Exodus NFACED element block found, "
1211 "but the file has no face blocks.");
1212
1213 std::vector<int> face_block_ids(num_face_blk);
1214 ex_err = exII::ex_get_ids(ex_id,
1215 exII::EX_FACE_BLOCK,
1216 face_block_ids.data());
1217 EX_CHECK_ERR(ex_err, "Error getting face block IDs.");
1218
1221
1222 for (auto block : index_range(face_block_ids))
1223 {
1224 std::vector<char> face_type(libmesh_max_str_length+1);
1225 int num_face_this_blk = 0;
1226 int num_node_data_this_blk = 0;
1227 int num_edges_per_face = 0;
1228 int num_faces_per_face = 0;
1229 int num_attr_face = 0;
1230
1231 ex_err = exII::ex_get_block(ex_id,
1232 exII::EX_FACE_BLOCK,
1233 face_block_ids[block],
1234 face_type.data(),
1235 &num_face_this_blk,
1236 &num_node_data_this_blk,
1237 &num_edges_per_face,
1238 &num_faces_per_face,
1239 &num_attr_face);
1240 EX_CHECK_ERR(ex_err, "Error getting face block info.");
1241
1242 const auto & conv = get_conversion(std::string(face_type.data()));
1243 libmesh_error_msg_if(conv.libmesh_elem_type() != C0POLYGON,
1244 "Error: NFACED polyhedron input currently expects "
1245 "NSIDED face blocks, but face block "
1246 << face_block_ids[block] << " has Exodus type "
1247 << face_type.data() << ".");
1248
1249 libmesh_error_msg_if
1250 (!(num_edges_per_face == 0) && !(num_edges_per_face == -1),
1251 "Error: Exodus NSIDED face block "
1252 << face_block_ids[block]
1253 << " has edge connectivity, which NFACED polyhedron input "
1254 << "does not currently support.");
1255 libmesh_error_msg_if
1256 (!(num_faces_per_face == 0) && !(num_faces_per_face == -1),
1257 "Error: Exodus NSIDED face block "
1258 << face_block_ids[block]
1259 << " has face-in-face connectivity, which NFACED polyhedron "
1260 << "input does not currently support.");
1261
1262 std::vector<int> face_node_counts(num_face_this_blk);
1263 if (!face_node_counts.empty())
1264 {
1265 ex_err = exII::ex_get_entity_count_per_polyhedra
1266 (ex_id,
1267 exII::EX_FACE_BLOCK,
1268 face_block_ids[block],
1269 face_node_counts.data());
1270 EX_CHECK_ERR(ex_err, "Error reading polyhedron face node counts");
1271 }
1272
1273 int counted_nodes = 0;
1274 for (const auto count : face_node_counts)
1275 counted_nodes += count;
1276
1277 libmesh_error_msg_if(counted_nodes != num_node_data_this_blk,
1278 "Error: Exodus NSIDED face block "
1279 << face_block_ids[block]
1280 << " says it has " << num_node_data_this_blk
1281 << " total node entries, but its per-face "
1282 << "node counts sum to " << counted_nodes << ".");
1283
1284 std::vector<int> face_connect(num_node_data_this_blk);
1285 if (!face_connect.empty())
1286 {
1287 ex_err = exII::ex_get_conn(ex_id,
1288 exII::EX_FACE_BLOCK,
1289 face_block_ids[block],
1290 face_connect.data(),
1291 nullptr,
1292 nullptr);
1293 EX_CHECK_ERR(ex_err, "Error reading polyhedron face connectivity.");
1294 }
1295
1296 std::size_t offset = 0;
1297 for (const auto count : face_node_counts)
1298 {
1299 libmesh_error_msg_if(count < 3,
1300 "Error: Exodus NSIDED face block "
1301 << face_block_ids[block]
1302 << " has a face with only "
1303 << count << " nodes.");
1304
1305 c0polyhedron_face_connect.emplace_back
1306 (face_connect.begin() + offset,
1307 face_connect.begin() + offset + count);
1308 offset += count;
1309 }
1310 }
1311
1312 libmesh_error_msg_if(c0polyhedron_face_connect.size() !=
1313 cast_int<std::size_t>(num_face),
1314 "Error: Exodus file says it has "
1315 << num_face << " faces, but its face blocks contain "
1316 << c0polyhedron_face_connect.size() << " faces.");
1317}

References libMesh::C0POLYGON, libMesh::ExodusII_IO_Helper::c0polyhedron_face_connect, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::get_conversion(), libMesh::index_range(), libMesh::ExodusII_IO_Helper::num_face, and libMesh::ExodusII_IO_Helper::num_face_blk.

Referenced by libMesh::ExodusII_IO_Helper::read_elem_in_block().

◆ read_global_values()

void libMesh::ExodusII_IO_Helper::read_global_values ( std::vector< Real > &  values,
int  timestep 
)
inherited

Reads the vector of global variables.

Definition at line 5318 of file exodusII_io_helper.C.

5319{
5320 if ((_run_only_on_proc0) && (this->processor_id() != 0))
5321 return;
5322
5323 values.clear();
5324 values.resize(num_global_vars);
5325 ex_err = exII::ex_get_var
5326 (ex_id,
5327 timestep,
5328 exII::EX_GLOBAL,
5329 1, // var_index
5330 1, // obj_id
5332 MappedInputVector(values, _single_precision).data());
5333
5334 EX_CHECK_ERR(ex_err, "Error reading global values.");
5335}

References libMesh::ExodusII_IO_Helper::_run_only_on_proc0, libMesh::ExodusII_IO_Helper::_single_precision, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::num_global_vars, and libMesh::ParallelObject::processor_id().

◆ read_header()

ExodusHeaderInfo libMesh::ExodusII_IO_Helper::read_header ( ) const
inherited

Reads an ExodusII mesh file header, leaving this object's internal data structures unchanged.

Definition at line 762 of file exodusII_io_helper.C.

763{
764 // Read init params using newer API that reads into a struct. For
765 // backwards compatibility, assign local member values from struct
766 // afterwards. Note: using the new API allows us to automatically
767 // read edge and face block/set information if it's present in the
768 // file.
769 exII::ex_init_params params = {};
770 int err_flag = exII::ex_get_init_ext(ex_id, &params);
771 EX_CHECK_ERR(err_flag, "Error retrieving header info.");
772
773 // Extract required data into our struct
775 h.title.assign(params.title, params.title + MAX_LINE_LENGTH);
776 h.num_dim = params.num_dim;
777 h.num_nodes = params.num_nodes;
778 h.num_elem = params.num_elem;
779 h.num_elem_blk = params.num_elem_blk;
780 h.num_node_sets = params.num_node_sets;
781 h.num_side_sets = params.num_side_sets;
782 h.num_elem_sets = params.num_elem_sets;
783 h.num_edge_blk = params.num_edge_blk;
784 h.num_edge = params.num_edge;
785 h.num_face_blk = params.num_face_blk;
786 h.num_face = params.num_face;
787
788 // And return it
789 return h;
790}
This class is used as both an external data structure for passing around Exodus file header informati...

References libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusHeaderInfo::num_dim, libMesh::ExodusHeaderInfo::num_edge, libMesh::ExodusHeaderInfo::num_edge_blk, libMesh::ExodusHeaderInfo::num_elem, libMesh::ExodusHeaderInfo::num_elem_blk, libMesh::ExodusHeaderInfo::num_elem_sets, libMesh::ExodusHeaderInfo::num_face, libMesh::ExodusHeaderInfo::num_face_blk, libMesh::ExodusHeaderInfo::num_node_sets, libMesh::ExodusHeaderInfo::num_nodes, libMesh::ExodusHeaderInfo::num_side_sets, and libMesh::ExodusHeaderInfo::title.

Referenced by libMesh::ExodusII_IO_Helper::read_and_store_header_info().

◆ read_nodal_var_values()

void libMesh::ExodusII_IO_Helper::read_nodal_var_values ( std::string  nodal_var_name,
int  time_step 
)
inherited

Reads the nodal values for the variable 'nodal_var_name' at the specified time into the 'nodal_var_values' array.

Definition at line 2104 of file exodusII_io_helper.C.

2105{
2106 LOG_SCOPE("read_nodal_var_values()", "ExodusII_IO_Helper");
2107
2108 // Read the nodal variable names from file, so we can see if we have the one we're looking for
2109 this->read_var_names(NODAL);
2110
2111 // See if we can find the variable we are looking for
2112 unsigned int var_index = 0;
2113 bool found = false;
2114
2115 // Do a linear search for nodal_var_name in nodal_var_names
2116 for (; var_index<nodal_var_names.size(); ++var_index)
2117 {
2118 found = (nodal_var_names[var_index] == nodal_var_name);
2119 if (found)
2120 break;
2121 }
2122
2123 if (!found)
2124 {
2125 libMesh::err << "Available variables: " << std::endl;
2126 for (const auto & var_name : nodal_var_names)
2127 libMesh::err << var_name << std::endl;
2128
2129 libmesh_error_msg("Unable to locate variable named: " << nodal_var_name);
2130 }
2131
2132 // Clear out any previously read nodal variable values
2133 this->nodal_var_values.clear();
2134
2135 std::vector<Real> unmapped_nodal_var_values(num_nodes);
2136
2137 // Call the Exodus API to read the nodal variable values
2138 ex_err = exII::ex_get_var
2139 (ex_id,
2140 time_step,
2141 exII::EX_NODAL,
2142 var_index+1,
2143 1, // exII::ex_entity_id, not sure exactly what this is but in the ex_get_nodal_var.c shim, they pass 1
2144 num_nodes,
2145 MappedInputVector(unmapped_nodal_var_values, _single_precision).data());
2146 EX_CHECK_ERR(ex_err, "Error reading nodal variable values!");
2147
2148 for (auto i : make_range(num_nodes))
2149 {
2150 // Determine the libmesh node id implied by "i". The
2151 // get_libmesh_node_id() helper function expects a 1-based
2152 // Exodus node id, so we construct the "implied" Exodus node id
2153 // from "i" by adding 1.
2154 //
2155 // If the user has set the "set_unique_ids_from_maps" flag to
2156 // true, then calling get_libmesh_node_id(i+1) will just return
2157 // i, otherwise it will determine the value (with error
2158 // checking) using this->node_num_map.
2159 auto libmesh_node_id = this->get_libmesh_node_id(/*exodus_node_id=*/i+1);
2160
2161 // Store the nodal value in the map.
2162 this->nodal_var_values[libmesh_node_id] = unmapped_nodal_var_values[i];
2163 }
2164}
std::map< dof_id_type, Real > nodal_var_values

References libMesh::ExodusII_IO_Helper::_single_precision, libMesh::err, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::get_libmesh_node_id(), libMesh::make_range(), libMesh::ExodusII_IO_Helper::NODAL, libMesh::ExodusII_IO_Helper::nodal_var_names, libMesh::ExodusII_IO_Helper::nodal_var_values, libMesh::ExodusII_IO_Helper::num_nodes, and libMesh::ExodusII_IO_Helper::read_var_names().

◆ read_node_num_map()

void libMesh::ExodusII_IO_Helper::read_node_num_map ( )
inherited

Reads the optional node_num_map from the ExodusII mesh file.

Definition at line 955 of file exodusII_io_helper.C.

956{
957 node_num_map.resize(num_nodes);
958
959 // Note: we cannot use the exII::ex_get_num_map() here because it
960 // (apparently) does not behave like ex_get_node_num_map() when
961 // there is no node number map in the file: it throws an error
962 // instead of returning a default identity array (1,2,3,...).
963 ex_err = exII::ex_get_node_num_map
964 (ex_id, node_num_map.empty() ? nullptr : node_num_map.data());
965
966 EX_CHECK_ERR(ex_err, "Error retrieving nodal number map.");
967 message("Nodal numbering map retrieved successfully.");
968
969 if (verbose)
970 {
971 libMesh::out << "[" << this->processor_id() << "] node_num_map[i] = ";
972 for (unsigned int i=0; i<static_cast<unsigned int>(std::min(10, num_nodes-1)); ++i)
973 libMesh::out << node_num_map[i] << ", ";
974 libMesh::out << "... " << node_num_map.back() << std::endl;
975 }
976}

References libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::message(), libMesh::ExodusII_IO_Helper::node_num_map, libMesh::ExodusII_IO_Helper::num_nodes, libMesh::out, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::verbose.

◆ read_nodes()

void libMesh::ExodusII_IO_Helper::read_nodes ( )
inherited

Reads the nodal data (x,y,z coordinates) from the ExodusII mesh file.

Definition at line 904 of file exodusII_io_helper.C.

905{
906 LOG_SCOPE("read_nodes()", "ExodusII_IO_Helper");
907
908 x.resize(num_nodes);
909 y.resize(num_nodes);
910 z.resize(num_nodes);
911
912 if (num_nodes)
913 {
914 ex_err = exII::ex_get_coord
915 (ex_id,
916 MappedInputVector(x, _single_precision).data(),
917 MappedInputVector(y, _single_precision).data(),
918 MappedInputVector(z, _single_precision).data());
919
920 EX_CHECK_ERR(ex_err, "Error retrieving nodal data.");
921 message("Nodal data retrieved successfully.");
922 }
923
924 // If a nodal attribute bex_weight exists, we get spline weights
925 // from it
926 int n_nodal_attr = 0;
927 ex_err = exII::ex_get_attr_param(ex_id, exII::EX_NODAL, 0, & n_nodal_attr);
928 EX_CHECK_ERR(ex_err, "Error getting number of nodal attributes.");
929
930 if (n_nodal_attr > 0)
931 {
932 std::vector<std::vector<char>> attr_name_data
933 (n_nodal_attr, std::vector<char>(libmesh_max_str_length + 1));
934 std::vector<char *> attr_names(n_nodal_attr);
935 for (auto i : index_range(attr_names))
936 attr_names[i] = attr_name_data[i].data();
937
938 ex_err = exII::ex_get_attr_names(ex_id, exII::EX_NODAL, 0, attr_names.data());
939 EX_CHECK_ERR(ex_err, "Error getting nodal attribute names.");
940
941 for (auto i : index_range(attr_names))
942 if (std::string("bex_weight") == attr_names[i])
943 {
944 w.resize(num_nodes);
945 ex_err =
946 exII::ex_get_one_attr (ex_id, exII::EX_NODAL, 0, i+1,
947 MappedInputVector(w, _single_precision).data());
948 EX_CHECK_ERR(ex_err, "Error getting Bezier Extraction nodal weights");
949 }
950 }
951}

References libMesh::ExodusII_IO_Helper::_single_precision, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::index_range(), libMesh::ExodusII_IO_Helper::message(), libMesh::ExodusII_IO_Helper::num_nodes, libMesh::ExodusII_IO_Helper::w, libMesh::ExodusII_IO_Helper::x, libMesh::ExodusII_IO_Helper::y, and libMesh::ExodusII_IO_Helper::z.

◆ read_nodeset()

void libMesh::Nemesis_IO_Helper::read_nodeset ( int  id)

Reading functions.

These just allocate memory for you and call the Nemesis routines of the same name. They also handle error checking for the Nemesis return value. Be careful calling these at random, some depend on others being called first... Reads the node ids of nodeset id and stores them in the node_list member of this class.

Note
This used to be an ExodusII_IO_Helper function but it use was completely replaced by read_all_nodesets(). For now, it is still used by the Nemesis reader so we have moved it here.

Definition at line 118 of file nemesis_io_helper.C.

119{
120 libmesh_assert_less (id, nodeset_ids.size());
121 libmesh_assert_less (id, num_nodes_per_set.size());
122 libmesh_assert_less (id, num_node_df_per_set.size());
123
124 ex_err = exII::ex_get_set_param(ex_id,
125 exII::EX_NODE_SET,
126 nodeset_ids[id],
129 EX_CHECK_ERR(ex_err, "Error retrieving nodeset parameters.");
130 message("Parameters retrieved successfully for nodeset: ", id);
131
132 node_list.resize(num_nodes_per_set[id]);
133
134 // Don't call ex_get_set unless there are actually nodes there to get.
135 // Exodus prints an annoying warning message in DEBUG mode otherwise...
136 if (num_nodes_per_set[id] > 0)
137 {
138 ex_err = exII::ex_get_set(ex_id,
139 exII::EX_NODE_SET,
140 nodeset_ids[id],
141 node_list.data(),
142 nullptr); // set_extra_list, ignored for node sets
143
144 EX_CHECK_ERR(ex_err, "Error retrieving nodeset data.");
145 message("Data retrieved successfully for nodeset: ", id);
146 }
147}

References libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::message(), node_list, libMesh::ExodusII_IO_Helper::nodeset_ids, libMesh::ExodusII_IO_Helper::num_node_df_per_set, and libMesh::ExodusII_IO_Helper::num_nodes_per_set.

◆ read_nodeset_data()

void libMesh::ExodusII_IO_Helper::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 
)
inherited

Read nodeset variables, if any, into the provided data structures.

Definition at line 4853 of file exodusII_io_helper.C.

4858{
4859 LOG_SCOPE("read_nodeset_data()", "ExodusII_IO_Helper");
4860
4861 // This reads the sideset variable names into the local
4862 // sideset_var_names data structure.
4863 this->read_var_names(NODESET);
4864
4865 if (num_nodeset_vars)
4866 {
4867 // Read the nodeset data truth table
4868 std::vector<int> nset_var_tab(num_node_sets * num_nodeset_vars);
4869 ex_err = exII::ex_get_truth_table
4870 (ex_id,
4871 exII::EX_NODE_SET,
4874 nset_var_tab.data());
4875 EX_CHECK_ERR(ex_err, "Error reading nodeset variable truth table.");
4876
4877 // Set up/allocate space in incoming data structures.
4878 var_names = nodeset_var_names;
4879 node_boundary_ids.resize(num_nodeset_vars);
4880 bc_vals.resize(num_nodeset_vars);
4881
4882 // Read the nodeset data.
4883 //
4884 // Note: we assume that the functions
4885 // 1.) this->read_nodeset_info() and
4886 // 2.) this->read_all_nodesets()
4887 // have already been called, so that we already know e.g. how
4888 // many nodes are in each set, their ids, etc.
4889 //
4890 // TODO: As a future optimization, we could read only the values
4891 // requested by the user by looking at the input parameter
4892 // var_names and checking whether it already has entries in
4893 // it.
4894 int offset=0;
4895 for (int ns=0; ns<num_node_sets; ++ns)
4896 {
4897 offset += (ns > 0 ? num_nodes_per_set[ns-1] : 0);
4898 for (int var=0; var<num_nodeset_vars; ++var)
4899 {
4900 int is_present = nset_var_tab[num_nodeset_vars*ns + var];
4901
4902 if (is_present)
4903 {
4904 // Record the fact that this variable is defined on this nodeset.
4905 node_boundary_ids[var].insert(nodeset_ids[ns]);
4906
4907 // Note: the assumption here is that a previous call
4908 // to this->read_nodeset_info() has already set the
4909 // values of num_nodes_per_set, so we just use those values here.
4910 std::vector<Real> nset_var_vals(num_nodes_per_set[ns]);
4911 ex_err = exII::ex_get_var
4912 (ex_id,
4913 timestep,
4914 exII::EX_NODE_SET,
4915 var + 1, // 1-based nodeset variable index!
4916 nodeset_ids[ns],
4918 MappedInputVector(nset_var_vals, _single_precision).data());
4919 EX_CHECK_ERR(ex_err, "Error reading nodeset variable.");
4920
4921 for (int i=0; i<num_nodes_per_set[ns]; ++i)
4922 {
4923 // The read_all_nodesets() function now reads all the node ids into the
4924 // node_sets_node_list vector, which is of length "total_nodes_in_all_sets"
4925 // The old read_nodset() function is no longer called as far as I can tell,
4926 // and should probably be removed? The "offset" that we are using only
4927 // depends on the current nodeset index and the num_nodes_per_set vector,
4928 // which gets filled in by the call to read_all_nodesets().
4929 dof_id_type exodus_node_id = node_sets_node_list[i + offset];
4930
4931 // FIXME: We should use exodus_node_num_to_libmesh for this,
4932 // but it apparently is never set up, so just
4933 // subtract 1 from the Exodus node id.
4934 dof_id_type converted_node_id = exodus_node_id - 1;
4935
4936 // Make a NodeBCTuple key from the converted information.
4937 BoundaryInfo::NodeBCTuple key = std::make_tuple
4938 (converted_node_id, nodeset_ids[ns]);
4939
4940 // Store (node, b_id) tuples in bc_vals[var]
4941 bc_vals[var].emplace(key, nset_var_vals[i]);
4942 } // end for (i)
4943 } // end if (present)
4944 } // end for (var)
4945 } // end for (ns)
4946 } // end if (num_nodeset_vars)
4947}
std::vector< std::string > nodeset_var_names

References libMesh::ExodusII_IO_Helper::_single_precision, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::node_sets_node_list, libMesh::ExodusII_IO_Helper::NODESET, libMesh::ExodusII_IO_Helper::nodeset_ids, libMesh::ExodusII_IO_Helper::nodeset_var_names, libMesh::ExodusII_IO_Helper::num_node_sets, libMesh::ExodusII_IO_Helper::num_nodes_per_set, libMesh::ExodusII_IO_Helper::num_nodeset_vars, and libMesh::ExodusII_IO_Helper::read_var_names().

◆ read_nodeset_info()

void libMesh::ExodusII_IO_Helper::read_nodeset_info ( )
inherited

Reads information about all of the nodesets in the ExodusII mesh file.

Definition at line 1809 of file exodusII_io_helper.C.

1810{
1811 nodeset_ids.resize(num_node_sets);
1812 if (num_node_sets > 0)
1813 {
1814 ex_err = exII::ex_get_ids(ex_id,
1815 exII::EX_NODE_SET,
1816 nodeset_ids.data());
1817 EX_CHECK_ERR(ex_err, "Error retrieving nodeset information.");
1818 message("All nodeset information retrieved successfully.");
1819
1820 // Resize appropriate data structures -- only do this once outside the loop
1823 }
1824
1825 char name_buffer[libmesh_max_str_length+1];
1826 for (int i=0; i<num_node_sets; ++i)
1827 {
1828 ex_err = exII::ex_get_name(ex_id, exII::EX_NODE_SET,
1829 nodeset_ids[i], name_buffer);
1830 EX_CHECK_ERR(ex_err, "Error getting node set name.");
1831 id_to_ns_names[nodeset_ids[i]] = name_buffer;
1832 }
1833 message("All node set names retrieved successfully.");
1834}

References libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::id_to_ns_names, libMesh::ExodusII_IO_Helper::message(), libMesh::ExodusII_IO_Helper::nodeset_ids, libMesh::ExodusII_IO_Helper::num_node_df_per_set, libMesh::ExodusII_IO_Helper::num_node_sets, and libMesh::ExodusII_IO_Helper::num_nodes_per_set.

◆ read_num_time_steps()

void libMesh::ExodusII_IO_Helper::read_num_time_steps ( )
inherited

Reads the number of timesteps currently stored in the Exodus file and stores it in the num_time_steps variable.

Definition at line 2096 of file exodusII_io_helper.C.

2097{
2099 inquire(*this, exII::EX_INQ_TIME, "Error retrieving number of time steps");
2100}

References libMesh::ExodusII_IO_Helper::num_time_steps.

Referenced by libMesh::ExodusII_IO_Helper::read_and_store_header_info(), and libMesh::ExodusII_IO_Helper::read_time_steps().

◆ read_qa_records()

void libMesh::ExodusII_IO_Helper::read_qa_records ( )
inherited

Reads the QA records from an ExodusII file.

We can use this to detect when e.g. CUBIT 14+ was used to generate a Mesh file, and work around certain known bugs in that version.

Definition at line 828 of file exodusII_io_helper.C.

829{
830 // The QA records are four MAX_STR_LENGTH-byte character strings.
831 int num_qa_rec =
832 inquire(*this, exII::EX_INQ_QA, "Error retrieving number of QA records");
833
834 if (verbose)
835 libMesh::out << "Found "
836 << num_qa_rec
837 << " QA record(s) in the Exodus file."
838 << std::endl;
839
840 if (num_qa_rec > 0)
841 {
842 // Actual (num_qa_rec x 4) storage for strings. The object we
843 // pass to the Exodus API will just contain pointers into the
844 // qa_storage object, which will have all automatic memory
845 // management.
846 std::vector<std::vector<std::vector<char>>> qa_storage(num_qa_rec);
847 for (auto i : make_range(num_qa_rec))
848 {
849 qa_storage[i].resize(4);
850 for (auto j : make_range(4))
851 qa_storage[i][j].resize(libmesh_max_str_length+1);
852 }
853
854 // inner_array_t is a fixed-size array of 4 strings
855 typedef char * inner_array_t[4];
856
857 // There is at least one compiler (Clang 12.0.1) that complains about
858 // "a non-scalar type used in a pseudo-destructor expression" when
859 // we try to instantiate a std::vector of inner_array_t objects as in:
860 // std::vector<inner_array_t> qa_record(num_qa_rec);
861 // So, we instead attempt to achieve the same effect with a std::unique_ptr.
862 auto qa_record = std::make_unique<inner_array_t[]>(num_qa_rec);
863
864 // Create data structure to be passed to Exodus API by setting
865 // pointers to the actual strings which are in qa_storage.
866 for (auto i : make_range(num_qa_rec))
867 for (auto j : make_range(4))
868 qa_record[i][j] = qa_storage[i][j].data();
869
870 ex_err = exII::ex_get_qa (ex_id, qa_record.get());
871 EX_CHECK_ERR(ex_err, "Error reading the QA records.");
872
873 // Print the QA records
874 if (verbose)
875 {
876 for (auto i : make_range(num_qa_rec))
877 {
878 libMesh::out << "QA Record: " << i << std::endl;
879 for (auto j : make_range(4))
880 libMesh::out << qa_record[i][j] << std::endl;
881 }
882 }
883 }
884}

References libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::make_range(), libMesh::out, and libMesh::ExodusII_IO_Helper::verbose.

◆ read_sideset()

void libMesh::ExodusII_IO_Helper::read_sideset ( int  id,
int  offset 
)
inherited

Reads information about sideset id and inserts it into the global sideset array at the position offset.

Definition at line 1878 of file exodusII_io_helper.C.

1879{
1880 LOG_SCOPE("read_sideset()", "ExodusII_IO_Helper");
1881
1882 libmesh_assert_less (id, ss_ids.size());
1883 libmesh_assert_less (id, num_sides_per_set.size());
1884 libmesh_assert_less (id, num_df_per_set.size());
1885 libmesh_assert_less_equal (offset, elem_list.size());
1886 libmesh_assert_less_equal (offset, side_list.size());
1887
1888 ex_err = exII::ex_get_set_param(ex_id,
1889 exII::EX_SIDE_SET,
1890 ss_ids[id],
1891 &num_sides_per_set[id],
1892 &num_df_per_set[id]);
1893 EX_CHECK_ERR(ex_err, "Error retrieving sideset parameters.");
1894 message("Parameters retrieved successfully for sideset: ", id);
1895
1896
1897 // It's OK for offset==elem_list.size() as long as num_sides_per_set[id]==0
1898 // because in that case we don't actually read anything...
1899#ifdef DEBUG
1900 if (static_cast<unsigned int>(offset) == elem_list.size() ||
1901 static_cast<unsigned int>(offset) == side_list.size() )
1902 libmesh_assert_equal_to (num_sides_per_set[id], 0);
1903#endif
1904
1905
1906 // Don't call ex_get_set unless there are actually sides there to get.
1907 // Exodus prints an annoying warning in DEBUG mode otherwise...
1908 if (num_sides_per_set[id] > 0)
1909 {
1910 ex_err = exII::ex_get_set(ex_id,
1911 exII::EX_SIDE_SET,
1912 ss_ids[id],
1913 &elem_list[offset],
1914 &side_list[offset]);
1915 EX_CHECK_ERR(ex_err, "Error retrieving sideset data.");
1916 message("Data retrieved successfully for sideset: ", id);
1917
1918 for (int i=0; i<num_sides_per_set[id]; i++)
1919 id_list[i+offset] = ss_ids[id];
1920 }
1921}

References libMesh::ExodusII_IO_Helper::elem_list, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::id_list, libMesh::ExodusII_IO_Helper::message(), libMesh::ExodusII_IO_Helper::num_df_per_set, libMesh::ExodusII_IO_Helper::num_sides_per_set, libMesh::ExodusII_IO_Helper::side_list, and libMesh::ExodusII_IO_Helper::ss_ids.

Referenced by libMesh::ExodusII_IO_Helper::write_sideset_data().

◆ read_sideset_data()

void libMesh::ExodusII_IO_Helper::read_sideset_data ( const MeshBase mesh,
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 
)
inherited

Read sideset variables, if any, into the provided data structures.

Definition at line 4321 of file exodusII_io_helper.C.

4327{
4328 LOG_SCOPE("read_sideset_data()", "ExodusII_IO_Helper");
4329
4330 // This reads the sideset variable names into the local
4331 // sideset_var_names data structure.
4332 this->read_var_names(SIDESET);
4333
4334 if (num_sideset_vars)
4335 {
4336 // Read the sideset data truth table
4337 std::vector<int> sset_var_tab(num_side_sets * num_sideset_vars);
4338 ex_err = exII::ex_get_truth_table
4339 (ex_id,
4340 exII::EX_SIDE_SET,
4343 sset_var_tab.data());
4344 EX_CHECK_ERR(ex_err, "Error reading sideset variable truth table.");
4345
4346 // Set up/allocate space in incoming data structures.
4347 var_names = sideset_var_names;
4348 side_ids.resize(num_sideset_vars);
4349 bc_vals.resize(num_sideset_vars);
4350
4351 // Read the sideset data.
4352 //
4353 // Note: we assume that read_sideset() has already been called
4354 // for each sideset, so the required values in elem_list and
4355 // side_list are already present.
4356 //
4357 // TODO: As a future optimization, we could read only the values
4358 // requested by the user by looking at the input parameter
4359 // var_names and checking whether it already has entries in
4360 // it. We could do the same thing with the input side_ids
4361 // container and only read values for requested sidesets.
4362 int offset=0;
4363 for (int ss=0; ss<num_side_sets; ++ss)
4364 {
4365 offset += (ss > 0 ? num_sides_per_set[ss-1] : 0);
4366 for (int var=0; var<num_sideset_vars; ++var)
4367 {
4368 int is_present = sset_var_tab[num_sideset_vars*ss + var];
4369
4370 if (is_present)
4371 {
4372 // Record the fact that this variable is defined on this sideset.
4373 side_ids[var].insert(ss_ids[ss]);
4374
4375 // Note: the assumption here is that a previous call
4376 // to this->read_sideset_info() has already set the
4377 // values of num_sides_per_set, so we just use those values here.
4378 std::vector<Real> sset_var_vals(num_sides_per_set[ss]);
4379 ex_err = exII::ex_get_var
4380 (ex_id,
4381 timestep,
4382 exII::EX_SIDE_SET,
4383 var + 1, // 1-based sideset variable index!
4384 ss_ids[ss],
4386 MappedInputVector(sset_var_vals, _single_precision).data());
4387 EX_CHECK_ERR(ex_err, "Error reading sideset variable.");
4388
4389 for (int i=0; i<num_sides_per_set[ss]; ++i)
4390 {
4391 dof_id_type exodus_elem_id = elem_list[i + offset];
4392 unsigned int exodus_side_id = side_list[i + offset];
4393
4394 // FIXME: We should use exodus_elem_num_to_libmesh for this,
4395 // but it apparently is never set up, so just
4396 // subtract 1 from the Exodus elem id.
4397 dof_id_type converted_elem_id = exodus_elem_id - 1;
4398
4399 // Map Exodus side id to libmesh side id.
4400 // Map from Exodus side ids to libmesh side ids.
4401 const auto & conv = get_conversion(mesh.elem_ptr(converted_elem_id)->type());
4402
4403 // Map from Exodus side id to libmesh side id.
4404 // Note: the mapping is defined on 0-based indices, so subtract
4405 // 1 before doing the mapping.
4406 unsigned int converted_side_id = conv.get_side_map(exodus_side_id - 1);
4407
4408 // Make a BCTuple key from the converted information.
4409 BoundaryInfo::BCTuple key = std::make_tuple
4410 (converted_elem_id,
4411 converted_side_id,
4412 ss_ids[ss]);
4413
4414 // Store (elem, side, b_id) tuples in bc_vals[var]
4415 bc_vals[var].emplace(key, sset_var_vals[i]);
4416 } // end for (i)
4417 } // end if (present)
4418 } // end for (var)
4419 } // end for (ss)
4420 } // end if (num_sideset_vars)
4421}
std::vector< std::string > sideset_var_names

References libMesh::ExodusII_IO_Helper::_single_precision, libMesh::ExodusII_IO_Helper::elem_list, libMesh::MeshBase::elem_ptr(), libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::get_conversion(), mesh, libMesh::ExodusII_IO_Helper::num_side_sets, libMesh::ExodusII_IO_Helper::num_sides_per_set, libMesh::ExodusII_IO_Helper::num_sideset_vars, libMesh::ExodusII_IO_Helper::read_var_names(), libMesh::ExodusII_IO_Helper::side_list, libMesh::ExodusII_IO_Helper::SIDESET, libMesh::ExodusII_IO_Helper::sideset_var_names, libMesh::ExodusII_IO_Helper::ss_ids, and libMesh::Elem::type().

◆ read_sideset_info()

void libMesh::ExodusII_IO_Helper::read_sideset_info ( )
inherited

Reads information about all of the sidesets in the ExodusII mesh file.

Definition at line 1774 of file exodusII_io_helper.C.

1775{
1776 ss_ids.resize(num_side_sets);
1777 if (num_side_sets > 0)
1778 {
1779 ex_err = exII::ex_get_ids(ex_id,
1780 exII::EX_SIDE_SET,
1781 ss_ids.data());
1782 EX_CHECK_ERR(ex_err, "Error retrieving sideset information.");
1783 message("All sideset information retrieved successfully.");
1784
1785 // Resize appropriate data structures -- only do this once outside the loop
1788
1789 // Inquire about the length of the concatenated side sets element list
1790 num_elem_all_sidesets = inquire(*this, exII::EX_INQ_SS_ELEM_LEN, "Error retrieving length of the concatenated side sets element list!");
1791
1795 }
1796
1797 char name_buffer[libmesh_max_str_length+1];
1798 for (int i=0; i<num_side_sets; ++i)
1799 {
1800 ex_err = exII::ex_get_name(ex_id, exII::EX_SIDE_SET,
1801 ss_ids[i], name_buffer);
1802 EX_CHECK_ERR(ex_err, "Error getting side set name.");
1803 id_to_ss_names[ss_ids[i]] = name_buffer;
1804 }
1805 message("All side set names retrieved successfully.");
1806}

References libMesh::ExodusII_IO_Helper::elem_list, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::id_list, libMesh::ExodusII_IO_Helper::id_to_ss_names, libMesh::ExodusII_IO_Helper::message(), libMesh::ExodusII_IO_Helper::num_df_per_set, libMesh::ExodusII_IO_Helper::num_elem_all_sidesets, libMesh::ExodusII_IO_Helper::num_side_sets, libMesh::ExodusII_IO_Helper::num_sides_per_set, libMesh::ExodusII_IO_Helper::side_list, and libMesh::ExodusII_IO_Helper::ss_ids.

Referenced by libMesh::ExodusII_IO_Helper::write_sideset_data().

◆ read_time_steps()

void libMesh::ExodusII_IO_Helper::read_time_steps ( )
inherited

Reads and stores the timesteps in the 'time_steps' array.

Definition at line 2079 of file exodusII_io_helper.C.

2080{
2081 // Make sure we have an up-to-date count of the number of time steps in the file.
2082 this->read_num_time_steps();
2083
2084 if (num_time_steps > 0)
2085 {
2086 time_steps.resize(num_time_steps);
2087 ex_err = exII::ex_get_all_times
2088 (ex_id,
2089 MappedInputVector(time_steps, _single_precision).data());
2090 EX_CHECK_ERR(ex_err, "Error reading timesteps!");
2091 }
2092}

References libMesh::ExodusII_IO_Helper::_single_precision, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::num_time_steps, libMesh::ExodusII_IO_Helper::read_num_time_steps(), and libMesh::ExodusII_IO_Helper::time_steps.

◆ read_var_names()

void libMesh::ExodusII_IO_Helper::read_var_names ( ExodusVarType  type)
inherited

Definition at line 2168 of file exodusII_io_helper.C.

2169{
2170 switch (type)
2171 {
2172 case NODAL:
2174 break;
2175 case ELEMENTAL:
2177 break;
2178 case GLOBAL:
2180 break;
2181 case SIDESET:
2183 break;
2184 case NODESET:
2186 break;
2187 case ELEMSET:
2189 break;
2190 default:
2191 libmesh_error_msg("Unrecognized ExodusVarType " << type);
2192 }
2193}
virtual void read_var_names_impl(const char *var_type, int &count, std::vector< std::string > &result)
read_var_names() dispatches to this function.

References libMesh::ExodusII_IO_Helper::elem_var_names, libMesh::ExodusII_IO_Helper::ELEMENTAL, libMesh::ExodusII_IO_Helper::ELEMSET, libMesh::ExodusII_IO_Helper::elemset_var_names, libMesh::ExodusII_IO_Helper::GLOBAL, libMesh::ExodusII_IO_Helper::global_var_names, libMesh::ExodusII_IO_Helper::NODAL, libMesh::ExodusII_IO_Helper::nodal_var_names, libMesh::ExodusII_IO_Helper::NODESET, libMesh::ExodusII_IO_Helper::nodeset_var_names, libMesh::ExodusII_IO_Helper::num_elem_vars, libMesh::ExodusII_IO_Helper::num_elemset_vars, libMesh::ExodusII_IO_Helper::num_global_vars, libMesh::ExodusII_IO_Helper::num_nodal_vars, libMesh::ExodusII_IO_Helper::num_nodeset_vars, libMesh::ExodusII_IO_Helper::num_sideset_vars, libMesh::ExodusII_IO_Helper::read_var_names_impl(), libMesh::ExodusII_IO_Helper::SIDESET, and libMesh::ExodusII_IO_Helper::sideset_var_names.

Referenced by libMesh::ExodusII_IO_Helper::check_existing_vars(), libMesh::ExodusII_IO_Helper::read_elemental_var_values(), libMesh::ExodusII_IO_Helper::read_elemset_data(), libMesh::ExodusII_IO_Helper::read_nodal_var_values(), libMesh::ExodusII_IO_Helper::read_nodeset_data(), and libMesh::ExodusII_IO_Helper::read_sideset_data().

◆ read_var_names_impl()

void libMesh::Nemesis_IO_Helper::read_var_names_impl ( const char *  var_type,
int count,
std::vector< std::string > &  result 
)
overrideprotectedvirtual

read_var_names() dispatches to this function.

We need to override it slightly for Nemesis.

Reimplemented from libMesh::ExodusII_IO_Helper.

Definition at line 2763 of file nemesis_io_helper.C.

2766{
2767 // Most of what we need to do is the same as for Exodus
2768 this->ExodusII_IO_Helper::read_var_names_impl(var_type, count, result);
2769
2770 // But with tests where we have more processors than elements,
2771 // Nemesis doesn't let us put variable names in files written by
2772 // processors owning nothing, but we may still *need* those
2773 // variable names on every processor, so let's sync them up...
2774
2775 processor_id_type pid_broadcasting_names = this->processor_id();
2776 const std::size_t n_names = result.size();
2777 if (!n_names)
2778 pid_broadcasting_names = DofObject::invalid_processor_id;
2779
2780 libmesh_assert(this->comm().semiverify
2781 (n_names ? nullptr : &n_names));
2782
2783 this->comm().min(pid_broadcasting_names);
2784
2785 if (pid_broadcasting_names != DofObject::invalid_processor_id)
2786 this->comm().broadcast(result, pid_broadcasting_names);
2787}
void min(const T &r, T &o, Request &req) const
void broadcast(T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
static constexpr processor_id_type invalid_processor_id
An invalid processor_id to distinguish DoFs that have not been assigned to a processor.
Definition dof_object.h:484

References libMesh::Parallel::Communicator::broadcast(), libMesh::ParallelObject::comm(), libMesh::DofObject::invalid_processor_id, libMesh::libmesh_assert(), libMesh::Parallel::Communicator::min(), libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::read_var_names_impl().

◆ set_add_sides()

void libMesh::ExodusII_IO_Helper::set_add_sides ( bool  add_sides)
inlineinherited

Sets whether or not to write extra "side" elements.

This is useful for plotting SIDE_DISCONTINUOUS data.

Definition at line 1362 of file exodusII_io_helper.h.

1363{
1364 _add_sides = add_sides;
1365}

References libMesh::ExodusII_IO_Helper::_add_sides.

◆ set_coordinate_offset()

void libMesh::ExodusII_IO_Helper::set_coordinate_offset ( Point  p)
inherited

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

Definition at line 5372 of file exodusII_io_helper.C.

5373{
5375}

References libMesh::ExodusII_IO_Helper::_coordinate_offset.

◆ set_dof_object_unique_id()

void libMesh::ExodusII_IO_Helper::set_dof_object_unique_id ( MeshBase mesh,
DofObject dof_object,
int  exodus_mapped_id 
)
privateinherited

Definition at line 2476 of file exodusII_io_helper.C.

2480{
2481 if (this->set_unique_ids_from_maps)
2482 {
2483 // Exodus ids are always 1-based while libmesh ids are always
2484 // 0-based, so to make a libmesh unique_id here, we subtract 1
2485 // from the exodus_mapped_id to make it 0-based.
2486 auto exodus_mapped_id_zero_based =
2487 cast_int<dof_id_type>(exodus_mapped_id - 1);
2488
2489 // Set added_node's unique_id to "exodus_mapped_id_zero_based".
2490 dof_object->set_unique_id(cast_int<unique_id_type>(exodus_mapped_id_zero_based));
2491
2492 // Normally the Mesh is responsible for setting the unique_ids
2493 // of Nodes/Elems in a consistent manner, so when we set the unique_id
2494 // of a Node/Elem manually based on the {node,elem}_num_map, we need to
2495 // make sure that the "next" unique id assigned by the Mesh
2496 // will still be valid. We do this by making sure that the
2497 // next_unique_id is greater than the one we set manually. The
2498 // APIs for doing this are only defined when unique ids are
2499 // enabled.
2500#ifdef LIBMESH_ENABLE_UNIQUE_ID
2501 unique_id_type next_unique_id = mesh.next_unique_id();
2502 mesh.set_next_unique_id(std::max(next_unique_id, static_cast<unique_id_type>(exodus_mapped_id_zero_based + 1)));
2503#else
2504 // Avoid compiler warnings about the unused variable
2506#endif
2507 }
2508}
void set_unique_id(unique_id_type new_id)
Sets the unique_id for this DofObject.
Definition dof_object.h:848
virtual void set_next_unique_id(unique_id_type id)=0
Sets the next available unique id to be used.
unique_id_type next_unique_id() const
Definition mesh_base.h:610
uint8_t unique_id_type
Definition id_types.h:86
void libmesh_ignore(const Args &...)

References libMesh::libmesh_ignore(), mesh, libMesh::MeshBase::next_unique_id(), libMesh::MeshBase::set_next_unique_id(), libMesh::DofObject::set_unique_id(), and libMesh::ExodusII_IO_Helper::set_unique_ids_from_maps.

Referenced by libMesh::ExodusII_IO_Helper::conditionally_set_elem_unique_id(), and libMesh::ExodusII_IO_Helper::conditionally_set_node_unique_id().

◆ set_hdf5_writing()

void libMesh::ExodusII_IO_Helper::set_hdf5_writing ( bool  write_hdf5)
inherited

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 5345 of file exodusII_io_helper.C.

5346{
5347 _write_hdf5 = write_hdf5;
5348}

References libMesh::ExodusII_IO_Helper::_write_hdf5.

◆ set_max_name_length()

void libMesh::ExodusII_IO_Helper::set_max_name_length ( unsigned int  max_length)
inherited

Set how many characters to use in names when opening a file for writing.

Definition at line 5351 of file exodusII_io_helper.C.

5352{
5353 // Opt mode error, because this may be exposed to users
5354 libmesh_error_msg_if (max_length > libmesh_max_str_length,
5355 "Exodus maximum name length is limited to " <<
5356 libmesh_max_str_length << " characters");
5357
5358 // Devel+dbg mode assertion, because developers should do better
5360
5361 _max_name_length = max_length;
5362}

References libMesh::ExodusII_IO_Helper::_max_name_length, libMesh::libmesh_assert(), and libMesh::ExodusII_IO_Helper::opened_for_writing.

◆ update()

void libMesh::ExodusII_IO_Helper::update ( )
inherited

◆ use_mesh_dimension_instead_of_spatial_dimension()

void libMesh::ExodusII_IO_Helper::use_mesh_dimension_instead_of_spatial_dimension ( bool  val)
inherited

Sets the underlying value of the boolean flag _use_mesh_dimension_instead_of_spatial_dimension.

By default, the value of this flag is false.

See the ExodusII_IO class documentation for a detailed description of this flag.

Definition at line 5339 of file exodusII_io_helper.C.

References libMesh::ExodusII_IO_Helper::_use_mesh_dimension_instead_of_spatial_dimension.

◆ write_as_dimension()

void libMesh::ExodusII_IO_Helper::write_as_dimension ( unsigned  dim)
inherited

Sets the value of _write_as_dimension.

This directly controls 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 5365 of file exodusII_io_helper.C.

5366{
5368}

References libMesh::ExodusII_IO_Helper::_write_as_dimension, and dim.

◆ write_complex_magnitude()

void libMesh::Nemesis_IO_Helper::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.

◆ write_element_values() [1/2]

void libMesh::Nemesis_IO_Helper::write_element_values ( const MeshBase mesh,
const EquationSystems es,
const std::vector< std::pair< unsigned int, unsigned int > > &  var_nums,
int  timestep,
const std::vector< std::set< subdomain_id_type > > &  vars_active_subdomains 
)

Writes the vector of elemental variable values, one variable and one subdomain at a time.

Definition at line 2630 of file nemesis_io_helper.C.

2635{
2636 // For each variable in names,
2637 // For each subdomain in subdomain_map,
2638 // If this (subdomain, variable) combination is active
2639 // For each component in variable
2640 // Extract element values into local_soln (localize is a collective)
2641 // Write local_soln to file
2642 // Update var_ctr with number of vector components for variable
2643 //
2644 unsigned int var_ctr = 0;
2645 for (auto v : index_range(var_nums))
2646 {
2647 const unsigned int sys_num = var_nums[v].first;
2648 const unsigned int var = var_nums[v].second;
2649 const System & system = es.get_system(sys_num);
2650
2651 // We need to check if the constant monomial is a scalar or a vector and set the number of
2652 // components for the latter as per es.find_variable_numbers().
2653 // Even for the case where a variable is not active on any subdomain belonging to the
2654 // processor, we still need to know this number to update 'var_ctr'.
2655 const auto & var_type = system.variable_type(var);
2656 const unsigned int n_comps =
2657 (FEInterface::field_type(var_type) == TYPE_VECTOR) ?
2658 FEInterface::n_vec_dim(mesh, var_type) : 1;
2659
2660 // Get list of active subdomains for variable v
2661 const auto & active_subdomains = vars_active_subdomains[v];
2662
2663 for (const int sbd_id_int : global_elem_blk_ids)
2664 {
2665 const subdomain_id_type sbd_id =
2666 restrict_int<subdomain_id_type>(sbd_id_int);
2667 auto it = subdomain_map.find(sbd_id);
2668 const std::vector<dof_id_type> empty_vec;
2669 const std::vector<dof_id_type> & elem_ids =
2670 (it == subdomain_map.end()) ? empty_vec : it->second;
2671
2672 // Possibly skip this (variable, subdomain) combination. Also, check that there is at
2673 // least one element on the subdomain... Indeed, it is possible to have zero elements,
2674 // e.g., when running "adaptivity_ex3" in parallel with the 'dimension=1' argument.
2675 if ((active_subdomains.empty() || active_subdomains.count(sbd_id)) && elem_ids.size())
2676 {
2677 std::vector<numeric_index_type> required_indices;
2678 required_indices.reserve(elem_ids.size());
2679
2680 // The number of DOF components needs to be equal to the expected number so that we
2681 // know where to store data to correctly correspond to variable names - verify this by
2682 // accessing the n_comp method for the last element ID, which should return the same
2683 // value for all elements on a given subdomain, so we only need to check this once.
2684 libmesh_assert_equal_to(n_comps, mesh.elem_ref(elem_ids.back()).n_comp(sys_num, var));
2685
2686 // Loop through the DOFs of the variable and write the values for it on each element.
2687 // The variable name should have been decomposed by es.find_variable_numbers().
2688 for (unsigned int comp = 0; comp < n_comps; ++comp)
2689 {
2690 for (const auto & id : elem_ids)
2691 required_indices.push_back(mesh.elem_ref(id).dof_number(sys_num, var, comp));
2692
2693 std::vector<Number> local_soln;
2694 system.current_local_solution->get(required_indices, local_soln);
2695
2696 // reset for the next component
2697 required_indices.clear();
2698
2699 // It's possible that there's nothing for us to write:
2700 // we may not be responsible for any elements on the
2701 // current subdomain. We did still have to participate
2702 // in the localize() call above, however, since it is a
2703 // collective.
2704 if (local_soln.size())
2705 {
2706#ifdef LIBMESH_USE_COMPLEX_NUMBERS
2707 int stride = write_complex_abs ? 3 : 2;
2708 std::vector<Real> local_soln_buffer(local_soln.size());
2709 std::transform(local_soln.begin(), local_soln.end(),
2710 local_soln_buffer.begin(), [](Number n) { return n.real(); });
2711 ex_err = exII::ex_put_elem_var(ex_id,
2712 timestep,
2713 static_cast<int>(stride*(var_ctr+comp)+1),
2714 static_cast<int>(sbd_id),
2715 static_cast<int>(local_soln.size()),
2716 MappedOutputVector(local_soln_buffer, _single_precision).data());
2717 EX_CHECK_ERR(ex_err, "Error writing element real values.");
2718
2719 std::transform(local_soln.begin(), local_soln.end(),
2720 local_soln_buffer.begin(), [](Number n) { return n.imag(); });
2721 ex_err = exII::ex_put_elem_var(ex_id,
2722 timestep,
2723 static_cast<int>(stride*(var_ctr+comp)+2),
2724 static_cast<int>(sbd_id),
2725 static_cast<int>(local_soln.size()),
2726 MappedOutputVector(local_soln_buffer, _single_precision).data());
2727 EX_CHECK_ERR(ex_err, "Error writing element imaginary values.");
2728
2730 {
2731 std::transform(local_soln.begin(), local_soln.end(),
2732 local_soln_buffer.begin(), [](Number n) { return std::abs(n); });
2733 ex_err = exII::ex_put_elem_var(ex_id,
2734 timestep,
2735 static_cast<int>(stride*(var_ctr+comp)+2),
2736 static_cast<int>(sbd_id),
2737 static_cast<int>(local_soln.size()),
2738 MappedOutputVector(local_soln_buffer, _single_precision).data());
2739 EX_CHECK_ERR(ex_err, "Error writing element magnitudes.");
2740 }
2741#else // LIBMESH_USE_COMPLEX_NUMBERS
2742 ex_err = exII::ex_put_elem_var(ex_id,
2743 timestep,
2744 static_cast<int>(var_ctr+comp+1),
2745 static_cast<int>(sbd_id),
2746 static_cast<int>(local_soln.size()),
2747 MappedOutputVector(local_soln, _single_precision).data());
2748 EX_CHECK_ERR(ex_err, "Error writing element values.");
2749#endif // LIBMESH_USE_COMPLEX_NUMBERS
2750 }
2751 } // end loop over vector components
2752 }
2753 } // end loop over active subdomains
2754
2755 var_ctr += n_comps;
2756 } // end loop over vars
2757
2758 this->update();
2759}
void update()
Uses ex_update() to flush buffers to file.
static unsigned int n_vec_dim(const MeshBase &mesh, const FEType &fe_type)
static FEFieldType field_type(const FEType &fe_type)

References libMesh::ExodusII_IO_Helper::_single_precision, libMesh::System::current_local_solution, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::FEInterface::field_type(), libMesh::EquationSystems::get_system(), global_elem_blk_ids, libMesh::index_range(), mesh, libMesh::FEInterface::n_vec_dim(), subdomain_map, libMesh::TYPE_VECTOR, libMesh::ExodusII_IO_Helper::update(), libMesh::System::variable_type(), and write_complex_abs.

◆ write_element_values() [2/2]

void libMesh::ExodusII_IO_Helper::write_element_values ( const MeshBase mesh,
const std::vector< Real > &  values,
int  timestep,
const std::vector< std::set< subdomain_id_type > > &  vars_active_subdomains 
)
inherited

Writes the vector of values to the element variables.

The 'values' vector is assumed to be in the order: {(u1, u2, u3, ..., uN), (v1, v2, v3, ..., vN), (w1, w2, w3, ..., wN)} where N is the number of elements.

This ordering is produced by calls to ES::build_elemental_solution_vector(). ES::build_discontinuous_solution_vector(), on the other hand, produces an element-major ordering. See the function below for that case.

Definition at line 4997 of file exodusII_io_helper.C.

5002{
5003 LOG_SCOPE("write_element_values()", "ExodusII_IO_Helper");
5004
5005 if ((_run_only_on_proc0) && (this->processor_id() != 0))
5006 return;
5007
5008 // Ask the file how many element vars it has, store it in the num_elem_vars variable.
5009 ex_err = exII::ex_get_variable_param(ex_id, exII::EX_ELEM_BLOCK, &num_elem_vars);
5010 EX_CHECK_ERR(ex_err, "Error reading number of elemental variables.");
5011
5012 // We will eventually loop over the element blocks (subdomains) and
5013 // write the data one block at a time. Build a data structure that
5014 // maps each subdomain to a list of element ids it contains.
5015 std::map<subdomain_id_type, std::vector<unsigned int>> subdomain_map;
5016 for (const auto & elem : mesh.active_element_ptr_range())
5017 subdomain_map[elem->subdomain_id()].push_back(elem->id());
5018
5019 // Use mesh.n_elem() to access into the values vector rather than
5020 // the number of elements the Exodus writer thinks the mesh has,
5021 // which may not include inactive elements.
5023
5024 // Sanity check: we must have an entry in vars_active_subdomains for
5025 // each variable that we are potentially writing out.
5026 libmesh_assert_equal_to
5027 (vars_active_subdomains.size(),
5028 static_cast<unsigned>(num_elem_vars));
5029
5030 // For each variable, create a 'data' array which holds all the elemental variable
5031 // values *for a given block* on this processor, then write that data vector to file
5032 // before moving onto the next block.
5033 for (unsigned int var_id=0; var_id<static_cast<unsigned>(num_elem_vars); ++var_id)
5034 {
5035 // The size of the subdomain map is the number of blocks.
5036 auto it = subdomain_map.begin();
5037
5038 // Reference to the set of active subdomains for the current variable.
5039 const auto & active_subdomains
5040 = vars_active_subdomains[var_id];
5041
5042 for (unsigned int j=0; it!=subdomain_map.end(); ++it, ++j)
5043 {
5044 // Skip any variable/subdomain pairs that are inactive.
5045 // Note that if active_subdomains is empty, it is interpreted
5046 // as being active on *all* subdomains.
5047 if (!(active_subdomains.empty() || active_subdomains.count(it->first)))
5048 continue;
5049
5050 // Get reference to list of elem ids which are in the
5051 // current subdomain and count, allocate storage to hold
5052 // data that will be written to file.
5053 const auto & elem_nums = it->second;
5054 const unsigned int num_elems_this_block =
5055 cast_int<unsigned int>(elem_nums.size());
5056 std::vector<Real> data(num_elems_this_block);
5057
5058 // variable-major ordering is:
5059 // (u1, u2, u3, ..., uN), (v1, v2, v3, ..., vN), ...
5060 // where N is the number of elements.
5061 for (unsigned int k=0; k<num_elems_this_block; ++k)
5062 data[k] = values[var_id*n_elem + elem_nums[k]];
5063
5064 ex_err = exII::ex_put_var
5065 (ex_id,
5066 timestep,
5067 exII::EX_ELEM_BLOCK,
5068 var_id+1,
5069 this->get_block_id(j),
5070 num_elems_this_block,
5071 MappedOutputVector(data, _single_precision).data());
5072
5073 EX_CHECK_ERR(ex_err, "Error writing element values.");
5074 }
5075 }
5076
5077 this->update();
5078}
int get_block_id(int index)
Get the block number for the given block index.
virtual dof_id_type n_elem() const =0
dof_id_type n_elem(const MeshBase::const_element_iterator &begin, const MeshBase::const_element_iterator &end)
Count up the number of elements of a specific type (as defined by an iterator range).

References libMesh::ExodusII_IO_Helper::_run_only_on_proc0, libMesh::ExodusII_IO_Helper::_single_precision, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::get_block_id(), mesh, libMesh::MeshBase::n_elem(), libMesh::ExodusII_IO_Helper::num_elem_vars, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::update().

◆ write_element_values_element_major()

void libMesh::ExodusII_IO_Helper::write_element_values_element_major ( const MeshBase mesh,
const std::vector< Real > &  values,
int  timestep,
const std::vector< std::set< subdomain_id_type > > &  vars_active_subdomains,
const std::vector< std::string > &  derived_var_names,
const std::map< subdomain_id_type, std::vector< std::string > > &  subdomain_to_var_names 
)
inherited

Same as the function above, but assume the input 'values' vector is in element-major order, i.e.

{(u1,v1,w1), (u2,v2,w2), ... (uN,vN,wN)} This function is called by ExodusII_IO::write_element_data_from_discontinuous_nodal_data() because ES::build_discontinuous_solution_vector() builds the solution vector in this order.

Note
If some variables are subdomain-restricted, then the tuples will be of different lengths for each element, i.e. {(u1,v1,w1), (u2,v2), ... (uN,vN,wN)} if variable w is not active on element 2.

Definition at line 5082 of file exodusII_io_helper.C.

5089{
5090 if ((_run_only_on_proc0) && (this->processor_id() != 0))
5091 return;
5092
5093 // Ask the file how many element vars it has, store it in the num_elem_vars variable.
5094 ex_err = exII::ex_get_variable_param(ex_id, exII::EX_ELEM_BLOCK, &num_elem_vars);
5095 EX_CHECK_ERR(ex_err, "Error reading number of elemental variables.");
5096
5097 // We will eventually loop over the element blocks (subdomains) and
5098 // write the data one block (subdomain) at a time. Build a data
5099 // structure that keeps track of how many elements are in each
5100 // subdomain. This will allow us to reserve space in the data vector
5101 // we are going to write.
5102 std::map<subdomain_id_type, unsigned int> subdomain_to_n_elem;
5103 for (const auto & elem : mesh.active_element_ptr_range())
5104 subdomain_to_n_elem[elem->subdomain_id()] += 1;
5105
5106 // Sanity check: we must have an entry in vars_active_subdomains for
5107 // each variable that we are potentially writing out.
5108 libmesh_assert_equal_to
5109 (vars_active_subdomains.size(),
5110 static_cast<unsigned>(num_elem_vars));
5111
5112 // The size of the subdomain map is the number of blocks.
5113 auto subdomain_to_n_elem_iter = subdomain_to_n_elem.begin();
5114
5115 // Store range of active Elem pointers. We are going to loop over
5116 // the elements n_vars * n_subdomains times, so let's make sure
5117 // the predicated iterators aren't slowing us down too much.
5118 ConstElemRange elem_range
5119 (mesh.active_elements_begin(),
5120 mesh.active_elements_end());
5121
5122 for (unsigned int sbd_idx=0;
5123 subdomain_to_n_elem_iter != subdomain_to_n_elem.end();
5124 ++subdomain_to_n_elem_iter, ++sbd_idx)
5125 for (unsigned int var_id=0; var_id<static_cast<unsigned>(num_elem_vars); ++var_id)
5126 {
5127 // Reference to the set of active subdomains for the current variable.
5128 const auto & active_subdomains
5129 = vars_active_subdomains[var_id];
5130
5131 // If the vars_active_subdomains container passed to this function
5132 // has an empty entry, it means the variable really is not active on
5133 // _any_ subdomains, not that it is active on _all_ subdomains. This
5134 // is just due to the way that we build the vars_active_subdomains
5135 // container.
5136 if (!active_subdomains.count(subdomain_to_n_elem_iter->first))
5137 continue;
5138
5139 // Vector to hold values that will be written to Exodus file.
5140 std::vector<Real> data;
5141 data.reserve(subdomain_to_n_elem_iter->second);
5142
5143 unsigned int values_offset = 0;
5144 for (auto & elem : elem_range)
5145 {
5146 // We'll use the Elem's subdomain id in several places below.
5147 subdomain_id_type sbd_id = elem->subdomain_id();
5148
5149 // Get reference to the list of variable names defining
5150 // the indexing for the current Elem's subdomain.
5151 auto subdomain_to_var_names_iter =
5152 subdomain_to_var_names.find(sbd_id);
5153
5154 // It's possible, but unusual, for there to be an Elem
5155 // from a subdomain that has no active variables from the
5156 // set of variables we are currently writing. If that
5157 // happens, we can just go to the next Elem because we
5158 // don't need to advance the offset into the values
5159 // vector, etc.
5160 if (subdomain_to_var_names_iter == subdomain_to_var_names.end())
5161 continue;
5162
5163 const auto & var_names_this_sbd
5164 = subdomain_to_var_names_iter->second;
5165
5166 // Only extract values if Elem is in the current subdomain.
5167 if (sbd_id == subdomain_to_n_elem_iter->first)
5168 {
5169 // Location of current var_id in the list of all variables on this
5170 // subdomain. FIXME: linear search but it's over a typically relatively
5171 // short vector of active variable names on this subdomain. We could do
5172 // a nested std::map<string,index> instead of a std::vector where the
5173 // location of the string is implicitly the index..
5174 auto pos =
5175 std::find(var_names_this_sbd.begin(),
5176 var_names_this_sbd.end(),
5177 derived_var_names[var_id]);
5178
5179 libmesh_error_msg_if(pos == var_names_this_sbd.end(),
5180 "Derived name " << derived_var_names[var_id] << " not found!");
5181
5182 // Find the current variable's location in the list of all variable
5183 // names on the current Elem's subdomain.
5184 auto true_index =
5185 std::distance(var_names_this_sbd.begin(), pos);
5186
5187 data.push_back(values[values_offset + true_index]);
5188 }
5189
5190 // The "true" offset is how much we have to advance the index for each Elem
5191 // in this subdomain.
5192 auto true_offset = var_names_this_sbd.size();
5193
5194 // Increment to the next Elem's values
5195 values_offset += true_offset;
5196 } // for elem
5197
5198 // Now write 'data' to Exodus file, in single precision if requested.
5199 if (!data.empty())
5200 {
5201 ex_err = exII::ex_put_var
5202 (ex_id,
5203 timestep,
5204 exII::EX_ELEM_BLOCK,
5205 var_id+1,
5206 this->get_block_id(sbd_idx),
5207 data.size(),
5208 MappedOutputVector(data, _single_precision).data());
5209
5210 EX_CHECK_ERR(ex_err, "Error writing element values.");
5211 }
5212 } // for each var_id
5213
5214 this->update();
5215}
The StoredRange class defines a contiguous, divisible set of objects.

References libMesh::ExodusII_IO_Helper::_run_only_on_proc0, libMesh::ExodusII_IO_Helper::_single_precision, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::get_block_id(), mesh, libMesh::ExodusII_IO_Helper::num_elem_vars, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::update().

◆ write_elements()

void libMesh::Nemesis_IO_Helper::write_elements ( const MeshBase mesh,
bool  use_discontinuous = false 
)
overridevirtual

This function is specialized to write the connectivity.

Reimplemented from libMesh::ExodusII_IO_Helper.

Definition at line 2269 of file nemesis_io_helper.C.

2270{
2271 // Only write elements if there are elements blocks available.
2272 if (this->num_elem_blks_global > 0)
2273 {
2274 // Data structure to store element block names that will be used to
2275 // write the element block names to file.
2276 NamesData names_table(this->num_elem_blks_global, MAX_STR_LENGTH);
2277
2278 // Loop over all blocks, even if we don't have elements in each block.
2279 // If we don't have elements we need to write out a 0 for that block...
2280 for (auto i : make_range(this->num_elem_blks_global))
2281 {
2282 // Even if there are no elements for this block on the current
2283 // processor, we still want to write its name to file, if
2284 // possible. MeshBase::subdomain_name() will just return an
2285 // empty string if there is no name associated with the current
2286 // block.
2287 names_table.push_back_entry
2288 (mesh.subdomain_name(restrict_int<subdomain_id_type>(this->global_elem_blk_ids[i])));
2289
2290 // Search for the current global block ID in the map
2291 if (const auto it = this->block_id_to_elem_connectivity.find( this->global_elem_blk_ids[i] );
2292 it == this->block_id_to_elem_connectivity.end())
2293 {
2294 // If not found, write a zero to file....
2295 this->ex_err = exII::ex_put_elem_block(this->ex_id,
2296 this->global_elem_blk_ids[i],
2297 "Empty",
2298 0, /* n. elements in this block */
2299 0, /* n. nodes per element */
2300 0); /* number of attributes per element */
2301
2302 EX_CHECK_ERR(this->ex_err, "Error writing element block from Nemesis.");
2303 }
2304
2305 // Otherwise, write the actual block information and connectivity to file
2306 else
2307 {
2308 subdomain_id_type block =
2309 cast_int<subdomain_id_type>(it->first);
2310 const std::vector<int> & this_block_connectivity = it->second;
2311 std::vector<dof_id_type> & elements_in_this_block = subdomain_map[block];
2312
2313 // Use the first element in this block to get representative information.
2314 // Note that Exodus assumes all elements in a block are of the same type!
2315 // We are using that same assumption here!
2316 const auto & conv =
2317 get_conversion(mesh.elem_ref(elements_in_this_block[0]).type());
2318
2319 this->num_nodes_per_elem =
2320 mesh.elem_ref(elements_in_this_block[0]).n_nodes();
2321
2322 ex_err = exII::ex_put_elem_block(ex_id,
2323 block,
2324 conv.exodus_elem_type().c_str(),
2325 elements_in_this_block.size(),
2327 0);
2328 EX_CHECK_ERR(ex_err, "Error writing element block from Nemesis.");
2329
2330 ex_err = exII::ex_put_elem_conn(ex_id,
2331 block,
2332 this_block_connectivity.data());
2333 EX_CHECK_ERR(ex_err, "Error writing element connectivities from Nemesis.");
2334 }
2335 } // end loop over global block IDs
2336
2337 // Only call this once, not in the loop above!
2338 ex_err = exII::ex_put_elem_num_map(ex_id,
2339 exodus_elem_num_to_libmesh.empty() ? nullptr : exodus_elem_num_to_libmesh.data());
2340 EX_CHECK_ERR(ex_err, "Error writing element map");
2341
2342 // Write the element block names to file.
2343 ex_err = exII::ex_put_names(ex_id, exII::EX_ELEM_BLOCK, names_table.get_char_star_star());
2344 EX_CHECK_ERR(ex_err, "Error writing element block names");
2345 } // end if (this->num_elem_blks_global > 0)
2346}

References block_id_to_elem_connectivity, libMesh::MeshBase::elem_ref(), libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::exodus_elem_num_to_libmesh, libMesh::ExodusII_IO_Helper::NamesData::get_char_star_star(), libMesh::ExodusII_IO_Helper::get_conversion(), global_elem_blk_ids, libMesh::make_range(), mesh, libMesh::Elem::n_nodes(), num_elem_blks_global, libMesh::ExodusII_IO_Helper::num_nodes_per_elem, libMesh::ExodusII_IO_Helper::NamesData::push_back_entry(), and subdomain_map.

◆ write_elemset_data()

void libMesh::ExodusII_IO_Helper::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 
)
inherited

Write elemset data for the requested timestep.

Definition at line 4578 of file exodusII_io_helper.C.

4583{
4584 LOG_SCOPE("write_elemset_data()", "ExodusII_IO_Helper");
4585
4586 if ((_run_only_on_proc0) && (this->processor_id() != 0))
4587 return;
4588
4589 // Write the elemset variable names to file. This function should
4590 // only be called once for ELEMSET variables, repeated calls to
4591 // write_var_names() overwrites/changes the order of names that were
4592 // there previously, and will mess up any data that has already been
4593 // written.
4594 this->write_var_names(ELEMSET, var_names);
4595
4596 // We now call the API to read the elemset info even though we are
4597 // in the middle of writing. This is a bit counter-intuitive, but it
4598 // seems to work provided that you have already written the mesh
4599 // itself... read_elemset_info() fills in the following data
4600 // members:
4601 // .) id_to_elemset_names
4602 // .) num_elems_per_set
4603 // .) num_elem_df_per_set
4604 // .) elemset_list
4605 // .) elemset_id_list
4606 // .) id_to_elemset_names
4607 this->read_elemset_info();
4608
4609 // The "truth" table for elemset variables. elemset_var_tab is a
4610 // logically (num_elem_sets x num_elemset_vars) integer array of 0s and
4611 // 1s indicating which elemsets a given elemset variable is defined
4612 // on.
4613 std::vector<int> elemset_var_tab(num_elem_sets * var_names.size());
4614
4615 int offset=0;
4616 for (int es=0; es<num_elem_sets; ++es)
4617 {
4618 // Debugging
4619 // libMesh::out << "Writing elemset variable values for elemset "
4620 // << es << ", elemset_id = " << elemset_ids[es]
4621 // << std::endl;
4622
4623 // We know num_elems_per_set because we called read_elemset_info() above.
4624 offset += (es > 0 ? num_elems_per_set[es-1] : 0);
4625 this->read_elemset(es, offset);
4626
4627 // For each variable in var_names, write the values for the
4628 // current elemset, if any.
4629 for (auto var : index_range(var_names))
4630 {
4631 // Debugging
4632 // libMesh::out << "Writing elemset variable values for var " << var << std::endl;
4633
4634 // If this var has no values on this elemset, go to the next one.
4635 if (!elemset_ids_in[var].count(elemset_ids[es]))
4636 continue;
4637
4638 // Otherwise, fill in this entry of the nodeset truth table.
4639 elemset_var_tab[es*var_names.size() + var] = 1;
4640
4641 // Data vector that will eventually be passed to exII::ex_put_var().
4642 std::vector<Real> elemset_var_vals(num_elems_per_set[es]);
4643
4644 // Get reference to the (elem_id, elemset_id) -> Real map for this variable.
4645 const auto & data_map = elemset_vals[var];
4646
4647 // Loop over entries in current elemset.
4648 for (int i=0; i<num_elems_per_set[es]; ++i)
4649 {
4650 // Here we convert Exodus elem ids to libMesh node ids
4651 // simply by subtracting 1. We should probably use the
4652 // exodus_elem_num_to_libmesh data structure for this,
4653 // but I don't think it is set up at the time when this
4654 // function is normally called.
4655 dof_id_type libmesh_elem_id = elemset_list[i + offset] - 1;
4656
4657 // Construct a key to look up values in data_map.
4658 std::pair<dof_id_type, elemset_id_type> key =
4659 std::make_pair(libmesh_elem_id, elemset_ids[es]);
4660
4661 // Debugging:
4662 // libMesh::out << "Searching for key = (" << key.first << ", " << key.second << ")" << std::endl;
4663
4664 // We require that the user provided either no values for
4665 // this (var, elemset) combination (in which case we don't
4666 // reach this point) or a value for _every_ elem in this
4667 // elemset for this var, so we use the libmesh_map_find()
4668 // macro to check for this.
4669 elemset_var_vals[i] = libmesh_map_find(data_map, key);
4670 } // end for (node in nodeset[ns])
4671
4672 // Write elemset values to Exodus file
4673 if (elemset_var_vals.size() > 0)
4674 {
4675 ex_err = exII::ex_put_var
4676 (ex_id,
4677 timestep,
4678 exII::EX_ELEM_SET,
4679 var + 1, // 1-based variable index of current variable
4680 elemset_ids[es],
4682 MappedOutputVector(elemset_var_vals, _single_precision).data());
4683 EX_CHECK_ERR(ex_err, "Error writing elemset vars.");
4684 }
4685 } // end for (var in var_names)
4686 } // end for (ns)
4687
4688 // Finally, write the elemset truth table to file.
4689 ex_err =
4690 exII::ex_put_truth_table(ex_id,
4691 exII::EX_ELEM_SET, // exII::ex_entity_type
4693 cast_int<int>(var_names.size()),
4694 elemset_var_tab.data());
4695 EX_CHECK_ERR(ex_err, "Error writing elemset var truth table.");
4696}
void read_elemset_info()
Reads information about all of the elemsets in the ExodusII mesh file.
void read_elemset(int id, int offset)
Reads information about elemset id and inserts it into the global elemset array at the position offse...

References libMesh::ExodusII_IO_Helper::_run_only_on_proc0, libMesh::ExodusII_IO_Helper::_single_precision, libMesh::ExodusII_IO_Helper::ELEMSET, libMesh::ExodusII_IO_Helper::elemset_ids, libMesh::ExodusII_IO_Helper::elemset_list, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::index_range(), libMesh::ExodusII_IO_Helper::num_elem_sets, libMesh::ExodusII_IO_Helper::num_elems_per_set, libMesh::ParallelObject::processor_id(), libMesh::ExodusII_IO_Helper::read_elemset(), libMesh::ExodusII_IO_Helper::read_elemset_info(), and libMesh::ExodusII_IO_Helper::write_var_names().

◆ write_elemsets()

void libMesh::ExodusII_IO_Helper::write_elemsets ( const MeshBase mesh)
inherited

Write elemsets stored on the Mesh to the exo file.

Definition at line 4085 of file exodusII_io_helper.C.

4086{
4087 LOG_SCOPE("write_elemsets()", "ExodusII_IO_Helper");
4088
4089 if ((_run_only_on_proc0) && (this->processor_id() != 0))
4090 return;
4091
4092 // TODO: Add support for named elemsets
4093 // NamesData names_table(elemsets.size(), _max_name_length);
4094
4095 // We only need to write elemsets if the Mesh has an extra elem
4096 // integer called "elemset_code" defined on it.
4097 if (mesh.has_elem_integer("elemset_code"))
4098 {
4099 std::map<elemset_id_type, std::vector<int>> exodus_elemsets;
4100
4101 unsigned int elemset_index =
4102 mesh.get_elem_integer_index("elemset_code");
4103
4104 // Catch ids returned from MeshBase::get_elemsets() calls
4105 MeshBase::elemset_type set_ids;
4106 for (const auto & elem : mesh.element_ptr_range())
4107 {
4108 dof_id_type elemset_code =
4109 elem->get_extra_integer(elemset_index);
4110
4111 // Look up which element set ids (if any) this elemset_code corresponds to.
4112 mesh.get_elemsets(elemset_code, set_ids);
4113
4114 // Debugging
4115 // libMesh::out << "elemset_code = " << elemset_code << std::endl;
4116 // for (const auto & set_id : set_ids)
4117 // libMesh::out << set_id << " ";
4118 // libMesh::out << std::endl;
4119
4120 // Store this Elem id in every set to which it belongs.
4121 for (const auto & set_id : set_ids)
4122 exodus_elemsets[set_id].push_back(libmesh_elem_num_to_exodus[elem->id()]);
4123 }
4124
4125 // Debugging: print contents of exodus_elemsets map
4126 // for (const auto & [set_id, elem_ids] : exodus_elemsets)
4127 // {
4128 // libMesh::out << "elemset " << set_id << ": ";
4129 // for (const auto & elem_id : elem_ids)
4130 // libMesh::out << elem_id << " ";
4131 // libMesh::out << std::endl;
4132 // }
4133
4134 // Only continue if we actually had some elements in sets
4135 if (!exodus_elemsets.empty())
4136 {
4137 // Reserve space, loop over newly-created map, construct
4138 // exII::ex_set objects to be passed to exII::ex_put_sets(). Note:
4139 // we do non-const iteration since Exodus requires non-const pointers
4140 // to be passed to its APIs.
4141 std::vector<exII::ex_set> sets;
4142 sets.reserve(exodus_elemsets.size());
4143
4144 for (auto & [elem_set_id, ids_vec] : exodus_elemsets)
4145 {
4146 // TODO: Add support for named elemsets
4147 // names_table.push_back_entry(mesh.get_elemset_name(elem_set_id));
4148
4149 exII::ex_set & current_set = sets.emplace_back();
4150 current_set.id = elem_set_id;
4151 current_set.type = exII::EX_ELEM_SET;
4152 current_set.num_entry = ids_vec.size();
4153 current_set.num_distribution_factor = 0;
4154 current_set.entry_list = ids_vec.data();
4155 current_set.extra_list = nullptr; // extra_list is used for sidesets, not needed for elemsets
4156 current_set.distribution_factor_list = nullptr; // not used for elemsets
4157 }
4158
4159 // Sanity check: make sure the number of elemsets we already wrote to the header
4160 // matches the number of elemsets we just constructed by looping over the Mesh.
4161 libmesh_assert_msg(num_elem_sets == cast_int<int>(exodus_elemsets.size()),
4162 "Mesh has " << exodus_elemsets.size()
4163 << " elemsets, but header was written with num_elem_sets == " << num_elem_sets);
4164 libmesh_assert_msg(num_elem_sets == cast_int<int>(mesh.n_elemsets()),
4165 "mesh.n_elemsets() == " << mesh.n_elemsets()
4166 << ", but header was written with num_elem_sets == " << num_elem_sets);
4167
4168 ex_err = exII::ex_put_sets(ex_id, exodus_elemsets.size(), sets.data());
4169 EX_CHECK_ERR(ex_err, "Error writing elemsets");
4170
4171 // TODO: Add support for named elemsets
4172 // ex_err = exII::ex_put_names(ex_id, exII::EX_ELEM_SET, names_table.get_char_star_star());
4173 // EX_CHECK_ERR(ex_err, "Error writing elemset names");
4174 } // end if (!exodus_elemsets.empty())
4175 } // end if (mesh.has_elem_integer("elemset_code"))
4176}
unsigned int get_elem_integer_index(std::string_view name) const
Definition mesh_base.C:689
bool has_elem_integer(std::string_view name) const
Definition mesh_base.C:701
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
void get_elemsets(dof_id_type elemset_code, MeshBase::elemset_type &id_set_to_fill) const
Look up the element sets for a given elemset code and vice-versa.
Definition mesh_base.C:487
std::set< elemset_id_type > elemset_type
Typedef for the "set" container used to store elemset ids.
Definition mesh_base.h:466

References libMesh::ExodusII_IO_Helper::_run_only_on_proc0, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::MeshBase::get_elem_integer_index(), libMesh::MeshBase::get_elemsets(), libMesh::MeshBase::has_elem_integer(), libMesh::ExodusII_IO_Helper::libmesh_elem_num_to_exodus, mesh, libMesh::MeshBase::n_elemsets(), libMesh::ExodusII_IO_Helper::num_elem_sets, and libMesh::ParallelObject::processor_id().

◆ write_exodus_initialization_info()

void libMesh::Nemesis_IO_Helper::write_exodus_initialization_info ( const MeshBase pmesh,
const std::string &  title 
)
private

This function writes exodus-specific initialization information.

This information is slightly different when you are working with Nemesis, as it depends on some global information being known.

Definition at line 919 of file nemesis_io_helper.C.

921{
922 this->num_elem = static_cast<unsigned int>(std::distance (pmesh.active_local_elements_begin(),
923 pmesh.active_local_elements_end()));
924
925 // Exodus will also use *global* number of side and node sets,
926 // though it will not write out entries for all of them...
927 this->num_side_sets =
928 cast_int<int>(this->global_sideset_ids.size());
929 this->num_node_sets =
930 cast_int<int>(this->global_nodeset_ids.size());
931
932 // We need to write the global number of blocks, even though this processor might not have
933 // elements in some of them!
935
936 ex_err = exII::ex_put_init(ex_id,
937 title_in.c_str(),
938 this->num_dim,
939 this->num_nodes,
940 this->num_elem,
941 this->num_elem_blk,
942 this->num_node_sets,
943 this->num_side_sets);
944
945 EX_CHECK_ERR(ex_err, "Error initializing new Nemesis file.");
946}

References libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, global_nodeset_ids, global_sideset_ids, libMesh::ExodusII_IO_Helper::num_elem, libMesh::ExodusII_IO_Helper::num_elem_blk, num_elem_blks_global, libMesh::ExodusII_IO_Helper::num_node_sets, and libMesh::ExodusII_IO_Helper::num_side_sets.

Referenced by initialize().

◆ write_global_values()

void libMesh::ExodusII_IO_Helper::write_global_values ( const std::vector< Real > &  values,
int  timestep 
)
inherited

Writes the vector of global variables.

Definition at line 5286 of file exodusII_io_helper.C.

5287{
5288 if ((_run_only_on_proc0) && (this->processor_id() != 0))
5289 return;
5290
5291 if (!values.empty())
5292 {
5293 ex_err = exII::ex_put_var
5294 (ex_id,
5295 timestep,
5296 exII::EX_GLOBAL,
5297 1, // var index
5298 0, // obj_id (not used)
5300 MappedOutputVector(values, _single_precision).data());
5301
5302 EX_CHECK_ERR(ex_err, "Error writing global values.");
5303
5304 this->update();
5305 }
5306}

References libMesh::ExodusII_IO_Helper::_run_only_on_proc0, libMesh::ExodusII_IO_Helper::_single_precision, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::num_global_vars, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::update().

◆ write_information_records()

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

Writes the vector of information records.

Definition at line 5248 of file exodusII_io_helper.C.

5249{
5250 if ((_run_only_on_proc0) && (this->processor_id() != 0))
5251 return;
5252
5253 // There may already be information records in the file (for
5254 // example, if we're appending) and in that case, according to the
5255 // Exodus documentation, writing more information records is not
5256 // supported.
5257 int num_info = inquire(*this, exII::EX_INQ_INFO, "Error retrieving the number of information records from file!");
5258 if (num_info > 0)
5259 {
5260 libMesh::err << "Warning! The Exodus file already contains information records.\n"
5261 << "Exodus does not support writing additional records in this situation."
5262 << std::endl;
5263 return;
5264 }
5265
5266 int num_records = cast_int<int>(records.size());
5267
5268 if (num_records > 0)
5269 {
5270 NamesData info(num_records, MAX_LINE_LENGTH);
5271
5272 // If an entry is longer than MAX_LINE_LENGTH characters it's not an error, we just
5273 // write the first MAX_LINE_LENGTH characters to the file.
5274 for (const auto & record : records)
5275 info.push_back_entry(record);
5276
5277 ex_err = exII::ex_put_info(ex_id, num_records, info.get_char_star_star());
5278 EX_CHECK_ERR(ex_err, "Error writing global values.");
5279
5280 this->update();
5281 }
5282}
MPI_Info info

References libMesh::ExodusII_IO_Helper::_run_only_on_proc0, libMesh::err, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::update().

◆ write_nodal_coordinates()

void libMesh::Nemesis_IO_Helper::write_nodal_coordinates ( const MeshBase mesh,
bool  use_discontinuous = false 
)
overridevirtual

This function is specialized from ExodusII_IO_Helper to write only the nodal coordinates stored on the local piece of the Mesh.

Reimplemented from libMesh::ExodusII_IO_Helper.

Definition at line 2224 of file nemesis_io_helper.C.

2225{
2226 auto local_num_nodes = this->exodus_node_num_to_libmesh.size();
2227
2228 x.resize(local_num_nodes);
2229 y.resize(local_num_nodes);
2230 z.resize(local_num_nodes);
2231
2232 // Just loop over our list outputting the nodes the way we built the map
2233 for (auto i : make_range(local_num_nodes))
2234 {
2235 const Point & pt = mesh.point(this->exodus_node_num_to_libmesh[i]-1);
2236 x[i]=pt(0);
2237 y[i]=pt(1);
2238 z[i]=pt(2);
2239 }
2240
2241 if (local_num_nodes)
2242 {
2243 // Call Exodus API to write nodal coordinates...
2244 ex_err = exII::ex_put_coord
2245 (ex_id,
2246 x.empty() ? nullptr : MappedOutputVector(x, _single_precision).data(),
2247 y.empty() ? nullptr : MappedOutputVector(y, _single_precision).data(),
2248 z.empty() ? nullptr : MappedOutputVector(z, _single_precision).data());
2249 EX_CHECK_ERR(ex_err, "Error writing node coordinates");
2250
2251 // And write the nodal map we created for them
2252 ex_err = exII::ex_put_node_num_map(ex_id, this->exodus_node_num_to_libmesh.data());
2253 EX_CHECK_ERR(ex_err, "Error writing node num map");
2254 }
2255 else // Does the Exodus API want us to write empty nodal coordinates?
2256 {
2257 ex_err = exII::ex_put_coord(ex_id, nullptr, nullptr, nullptr);
2258 EX_CHECK_ERR(ex_err, "Error writing empty node coordinates");
2259
2260 ex_err = exII::ex_put_node_num_map(ex_id, nullptr);
2261 EX_CHECK_ERR(ex_err, "Error writing empty node num map");
2262 }
2263}

References libMesh::ExodusII_IO_Helper::_single_precision, libMesh::ExodusII_IO_Helper::MappedOutputVector::data(), libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::exodus_node_num_to_libmesh, libMesh::make_range(), mesh, libMesh::ExodusII_IO_Helper::x, libMesh::ExodusII_IO_Helper::y, and libMesh::ExodusII_IO_Helper::z.

◆ write_nodal_solution() [1/3]

void libMesh::Nemesis_IO_Helper::write_nodal_solution ( const EquationSystems es,
const std::vector< std::pair< unsigned int, unsigned int > > &  var_nums,
int  timestep,
const std::vector< std::string > &  output_names 
)

Outputs EquationSystems current_local_solution nodal values.

Definition at line 2450 of file nemesis_io_helper.C.

2454{
2455 const MeshBase & mesh = es.get_mesh();
2456
2457 // FIXME - half this code might be replaceable with a call to
2458 // EquationSystems::build_parallel_solution_vector()...
2459
2460 for (auto [sys_num, var] : var_nums)
2461 {
2462 const System & sys = es.get_system(sys_num);
2463 const std::string & name = sys.variable_name(var);
2464
2465 auto pos = std::find(output_names.begin(), output_names.end(), name);
2466
2467 // Skip this name if it's not supposed to be output.
2468 if (pos == output_names.end())
2469 continue;
2470
2471 // Compute the (zero-based) index which determines which
2472 // variable this will be as far as Nemesis is concerned. This
2473 // will be used below in the write_nodal_values() call.
2474 int variable_name_position =
2475 cast_int<int>(std::distance(output_names.begin(), pos));
2476
2477 // Fill up a std::vector with the dofs for the current variable
2478 std::vector<numeric_index_type> required_indices(this->num_nodes);
2479
2480 // Get the dof values required to write just our local part of
2481 // the solution vector.
2482 std::vector<Number> local_soln;
2483
2484 const FEType type = sys.variable_type(var);
2485 if (type.family == SCALAR)
2486 {
2487 std::vector<numeric_index_type> scalar_indices;
2488 sys.get_dof_map().SCALAR_dof_indices(scalar_indices, var);
2489 for (int i=0; i<this->num_nodes; i++)
2490 required_indices[i] = scalar_indices[0];
2491 sys.current_local_solution->get(required_indices, local_soln);
2492 }
2493 else
2494 {
2495 // If we have DoFs at all nodes, e.g. for isoparametric
2496 // elements, this is easy:
2497 bool found_all_indices = true;
2498 for (int i=0; i<this->num_nodes; i++)
2499 {
2500 const Node & node = mesh.node_ref(this->exodus_node_num_to_libmesh[i]-1);
2501 if (node.n_comp(sys_num, var))
2502 required_indices[i] = node.dof_number(sys_num, var, 0);
2503 else
2504 {
2505 found_all_indices = false;
2506 break;
2507 }
2508 }
2509
2510 if (found_all_indices)
2511 sys.current_local_solution->get(required_indices, local_soln);
2512 // Fine, we'll do it the hard way
2513 if (!found_all_indices)
2514 {
2515 local_soln.resize(num_nodes);
2516
2517 const Variable & var_description = sys.variable(var);
2518 const DofMap & dof_map = sys.get_dof_map();
2519
2520 NumericVector<Number> & sys_soln(*sys.current_local_solution);
2521 std::vector<Number> elem_soln; // The finite element solution
2522 std::vector<Number> nodal_soln; // The FE solution interpolated to the nodes
2523 std::vector<dof_id_type> dof_indices; // The DOF indices for the finite element
2524
2525 for (const auto & elem : mesh.active_local_element_ptr_range())
2526 if (var_description.active_on_subdomain(elem->subdomain_id()))
2527 {
2528 dof_map.dof_indices (elem, dof_indices, var);
2529 elem_soln.resize(dof_indices.size());
2530
2531 for (auto i : index_range(dof_indices))
2532 elem_soln[i] = sys_soln(dof_indices[i]);
2533
2534 FEInterface::nodal_soln (elem->dim(),
2535 type,
2536 elem,
2537 elem_soln,
2538 nodal_soln);
2539
2540 // infinite elements should be skipped...
2541 if (!elem->infinite())
2542 for (auto n : elem->node_index_range())
2543 {
2544 const std::size_t exodus_num =
2545 libmesh_node_num_to_exodus[elem->node_id(n)];
2546 libmesh_assert_greater(exodus_num, 0);
2547 libmesh_assert_less(exodus_num-1, local_soln.size());
2548 local_soln[exodus_num-1] = nodal_soln[n];
2549 }
2550 }
2551 }
2552 }
2553
2554#ifndef LIBMESH_USE_COMPLEX_NUMBERS
2555 // Call the ExodusII_IO_Helper function to write the data.
2556 write_nodal_values(variable_name_position + 1, local_soln, timestep);
2557#else
2558 // We have the local (complex) values. Now extract the real,
2559 // imaginary, and magnitude values from them.
2560 std::vector<Real> real_parts(num_nodes);
2561 std::vector<Real> imag_parts(num_nodes);
2562 std::vector<Real> magnitudes(num_nodes);
2563
2564 for (int i=0; i<num_nodes; ++i)
2565 {
2566 real_parts[i] = local_soln[i].real();
2567 imag_parts[i] = local_soln[i].imag();
2568 magnitudes[i] = std::abs(local_soln[i]);
2569 }
2570
2571 // Write the real, imaginary, and magnitude values to file.
2572 write_nodal_values(3 * variable_name_position + 1, real_parts, timestep);
2573 write_nodal_values(3 * variable_name_position + 2, imag_parts, timestep);
2574 write_nodal_values(3 * variable_name_position + 3, magnitudes, timestep);
2575#endif
2576 }
2577}
void write_nodal_values(int var_id, const std::vector< Real > &values, int timestep)
Writes the vector of values to a nodal variable.
static void nodal_soln(const unsigned int dim, const FEType &fe_t, const Elem *elem, const std::vector< Number > &elem_soln, std::vector< Number > &nodal_soln, const bool add_p_level=true, const unsigned int vdim=1)
Build the nodal soln from the element soln.
template class LIBMESH_EXPORT NumericVector< Number >

References libMesh::Variable::active_on_subdomain(), libMesh::System::current_local_solution, libMesh::DofMap::dof_indices(), libMesh::DofObject::dof_number(), libMesh::ExodusII_IO_Helper::exodus_node_num_to_libmesh, libMesh::FEType::family, libMesh::System::get_dof_map(), libMesh::EquationSystems::get_mesh(), libMesh::EquationSystems::get_system(), libMesh::index_range(), libMesh::ExodusII_IO_Helper::libmesh_node_num_to_exodus, mesh, libMesh::DofObject::n_comp(), libMesh::FEInterface::nodal_soln(), libMesh::ExodusII_IO_Helper::num_nodes, libMesh::SCALAR, libMesh::DofMap::SCALAR_dof_indices(), libMesh::System::variable(), libMesh::System::variable_name(), libMesh::System::variable_type(), and libMesh::ExodusII_IO_Helper::write_nodal_values().

◆ write_nodal_solution() [2/3]

void libMesh::Nemesis_IO_Helper::write_nodal_solution ( const NumericVector< Number > &  parallel_soln,
const std::vector< std::string > &  names,
int  timestep,
const std::vector< std::string > &  output_names 
)

Takes a parallel solution vector containing the node-major solution vector for all variables and outputs it to the files.

Parameters
parallel_soln
namesA vector containing the names of all variables in parallel_soln.
timestepTo be passed to the ExodusII_IO_Helper::write_nodal_values() function.
output_namesA vector containing the names of variables in parallel_soln that should actually be written (whitelist).
Note
This version of write_nodal_solution() is called by the parallel version of Nemesis_IO::write_nodal_data(), which is called by MeshOutput::write_equation_systems() for parallel I/O formats like Nemesis. The other version is still available to continue supporting things like NamebasedIO::write_nodal_data(), but this version should be preferred when running in parallel.

Definition at line 2390 of file nemesis_io_helper.C.

2394{
2395 int num_vars = cast_int<int>(names.size());
2396
2397 for (int c=0; c<num_vars; c++)
2398 {
2399 // Find the position of names[c] in the output_names vector, if it exists.
2400 auto pos = std::find(output_names.begin(), output_names.end(), names[c]);
2401
2402 // Skip names[c] if it's not supposed to be output.
2403 if (pos == output_names.end())
2404 continue;
2405
2406 // Compute the (zero-based) index which determines which
2407 // variable this will be as far as Nemesis is concerned. This
2408 // will be used below in the write_nodal_values() call.
2409 int variable_name_position =
2410 cast_int<int>(std::distance(output_names.begin(), pos));
2411
2412 // Fill up a std::vector with the dofs for the current variable
2413 std::vector<numeric_index_type> required_indices(this->num_nodes);
2414
2415 for (int i=0; i<this->num_nodes; i++)
2416 required_indices[i] = static_cast<dof_id_type>(this->exodus_node_num_to_libmesh[i]-1) * num_vars + c;
2417
2418 // Get the dof values required to write just our local part of
2419 // the solution vector.
2420 std::vector<Number> local_soln;
2421 parallel_soln.localize(local_soln, required_indices);
2422
2423#ifndef LIBMESH_USE_COMPLEX_NUMBERS
2424 // Call the ExodusII_IO_Helper function to write the data.
2425 write_nodal_values(variable_name_position + 1, local_soln, timestep);
2426#else
2427 // We have the local (complex) values. Now extract the real,
2428 // imaginary, and magnitude values from them.
2429 std::vector<Real> real_parts(num_nodes);
2430 std::vector<Real> imag_parts(num_nodes);
2431 std::vector<Real> magnitudes(num_nodes);
2432
2433 for (int i=0; i<num_nodes; ++i)
2434 {
2435 real_parts[i] = local_soln[i].real();
2436 imag_parts[i] = local_soln[i].imag();
2437 magnitudes[i] = std::abs(local_soln[i]);
2438 }
2439
2440 // Write the real, imaginary, and magnitude values to file.
2441 write_nodal_values(3 * variable_name_position + 1, real_parts, timestep);
2442 write_nodal_values(3 * variable_name_position + 2, imag_parts, timestep);
2443 write_nodal_values(3 * variable_name_position + 3, magnitudes, timestep);
2444#endif
2445 }
2446}
virtual void localize(std::vector< T > &v_local) const =0
Creates a copy of the global vector in the local vector v_local.

References libMesh::ExodusII_IO_Helper::exodus_node_num_to_libmesh, libMesh::NumericVector< T >::localize(), libMesh::ExodusII_IO_Helper::num_nodes, and libMesh::ExodusII_IO_Helper::write_nodal_values().

◆ write_nodal_solution() [3/3]

void libMesh::Nemesis_IO_Helper::write_nodal_solution ( const std::vector< Number > &  values,
const std::vector< std::string > &  names,
int  timestep 
)

Takes a solution vector containing the solution for all variables and outputs it to the files.

Definition at line 2352 of file nemesis_io_helper.C.

2355{
2356 int num_vars = cast_int<int>(names.size());
2357 //int num_values = values.size(); // Not used?
2358
2359 for (int c=0; c<num_vars; c++)
2360 {
2361#ifdef LIBMESH_USE_COMPLEX_NUMBERS
2362 std::vector<Real> real_parts(num_nodes);
2363 std::vector<Real> imag_parts(num_nodes);
2364 std::vector<Real> magnitudes(num_nodes);
2365
2366 for (int i=0; i<num_nodes; ++i)
2367 {
2368 Number value = values[(this->exodus_node_num_to_libmesh[i]-1)*num_vars + c];
2369 real_parts[i] = value.real();
2370 imag_parts[i] = value.imag();
2371 magnitudes[i] = std::abs(value);
2372 }
2373 write_nodal_values(3*c+1,real_parts,timestep);
2374 write_nodal_values(3*c+2,imag_parts,timestep);
2375 write_nodal_values(3*c+3,magnitudes,timestep);
2376#else
2377 std::vector<Number> cur_soln(this->num_nodes);
2378
2379 // Copy out this variable's solution
2380 for (int i=0; i<this->num_nodes; i++)
2381 cur_soln[i] = values[(this->exodus_node_num_to_libmesh[i]-1)*num_vars + c];
2382
2383 write_nodal_values(c+1,cur_soln,timestep);
2384#endif
2385 }
2386}
static const bool value
Definition xdr_io.C:55

References libMesh::ExodusII_IO_Helper::exodus_node_num_to_libmesh, libMesh::ExodusII_IO_Helper::num_nodes, value, and libMesh::ExodusII_IO_Helper::write_nodal_values().

◆ write_nodal_values()

void libMesh::ExodusII_IO_Helper::write_nodal_values ( int  var_id,
const std::vector< Real > &  values,
int  timestep 
)
inherited

Writes the vector of values to a nodal variable.

Definition at line 5220 of file exodusII_io_helper.C.

5223{
5224 if ((_run_only_on_proc0) && (this->processor_id() != 0))
5225 return;
5226
5227 if (!values.empty())
5228 {
5229 libmesh_assert_equal_to(values.size(), std::size_t(num_nodes));
5230
5231 ex_err = exII::ex_put_var
5232 (ex_id,
5233 timestep,
5234 exII::EX_NODAL,
5235 var_id,
5236 1, // exII::ex_entity_id, not sure exactly what this is but in the ex_put_nodal_var.c shim, they pass 1
5237 num_nodes,
5238 MappedOutputVector(values, _single_precision).data());
5239
5240 EX_CHECK_ERR(ex_err, "Error writing nodal values.");
5241
5242 this->update();
5243 }
5244}

References libMesh::ExodusII_IO_Helper::_run_only_on_proc0, libMesh::ExodusII_IO_Helper::_single_precision, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::num_nodes, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::update().

Referenced by write_nodal_solution(), write_nodal_solution(), and write_nodal_solution().

◆ write_nodeset_data()

void libMesh::ExodusII_IO_Helper::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 
)
inherited

Write nodeset data for the requested timestep.

Definition at line 4473 of file exodusII_io_helper.C.

4478{
4479 LOG_SCOPE("write_nodeset_data()", "ExodusII_IO_Helper");
4480
4481 if ((_run_only_on_proc0) && (this->processor_id() != 0))
4482 return;
4483
4484 // Write the nodeset variable names to file. This function should
4485 // only be called once for NODESET variables, repeated calls to
4486 // write_var_names() overwrites/changes the order of names that were
4487 // there previously, and will mess up any data that has already been
4488 // written.
4489 this->write_var_names(NODESET, var_names);
4490
4491 // For all nodesets, reads and fills in the arrays:
4492 // nodeset_ids
4493 // num_nodes_per_set
4494 // node_sets_node_index - starting index for each nodeset in the node_sets_node_list vector
4495 // node_sets_node_list
4496 // Note: we need these arrays so that we know what data to write
4497 this->read_all_nodesets();
4498
4499 // The "truth" table for nodeset variables. nset_var_tab is a
4500 // logically (num_node_sets x num_nset_var) integer array of 0s and
4501 // 1s indicating which nodesets a given nodeset variable is defined
4502 // on.
4503 std::vector<int> nset_var_tab(num_node_sets * var_names.size());
4504
4505 for (int ns=0; ns<num_node_sets; ++ns)
4506 {
4507 // The offset into the node_sets_node_list for the current nodeset
4508 int offset = node_sets_node_index[ns];
4509
4510 // For each variable in var_names, write the values for the
4511 // current nodeset, if any.
4512 for (auto var : index_range(var_names))
4513 {
4514 // If this var has no values on this nodeset, go to the next one.
4515 if (!node_boundary_ids[var].count(nodeset_ids[ns]))
4516 continue;
4517
4518 // Otherwise, fill in this entry of the nodeset truth table.
4519 nset_var_tab[ns*var_names.size() + var] = 1;
4520
4521 // Data vector that will eventually be passed to exII::ex_put_var().
4522 std::vector<Real> nset_var_vals(num_nodes_per_set[ns]);
4523
4524 // Get reference to the NodeBCTuple -> Real map for this variable.
4525 const auto & data_map = bc_vals[var];
4526
4527 // Loop over entries in current nodeset.
4528 for (int i=0; i<num_nodes_per_set[ns]; ++i)
4529 {
4530 // Here we convert Exodus node ids to libMesh node ids by
4531 // subtracting 1. We should probably use the
4532 // exodus_node_num_to_libmesh data structure for this, but
4533 // I don't think it is set up at the time when
4534 // write_nodeset_data() would normally be called.
4535 dof_id_type libmesh_node_id = node_sets_node_list[i + offset] - 1;
4536
4537 // Construct a key to look up values in data_map.
4539 std::make_tuple(libmesh_node_id, nodeset_ids[ns]);
4540
4541 // We require that the user provided either no values for
4542 // this (var, nodeset) combination (in which case we don't
4543 // reach this point) or a value for _every_ node in this
4544 // nodeset for this var, so we use the libmesh_map_find()
4545 // macro to check for this.
4546 nset_var_vals[i] = libmesh_map_find(data_map, key);
4547 } // end for (node in nodeset[ns])
4548
4549 // Write nodeset values to Exodus file
4550 if (nset_var_vals.size() > 0)
4551 {
4552 ex_err = exII::ex_put_var
4553 (ex_id,
4554 timestep,
4555 exII::EX_NODE_SET,
4556 var + 1, // 1-based variable index of current variable
4557 nodeset_ids[ns],
4559 MappedOutputVector(nset_var_vals, _single_precision).data());
4560 EX_CHECK_ERR(ex_err, "Error writing nodeset vars.");
4561 }
4562 } // end for (var in var_names)
4563 } // end for (ns)
4564
4565 // Finally, write the nodeset truth table.
4566 ex_err =
4567 exII::ex_put_truth_table(ex_id,
4568 exII::EX_NODE_SET,
4570 cast_int<int>(var_names.size()),
4571 nset_var_tab.data());
4572 EX_CHECK_ERR(ex_err, "Error writing nodeset var truth table.");
4573}
void read_all_nodesets()
New API that reads all nodesets simultaneously.

References libMesh::ExodusII_IO_Helper::_run_only_on_proc0, libMesh::ExodusII_IO_Helper::_single_precision, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::index_range(), libMesh::ExodusII_IO_Helper::node_sets_node_index, libMesh::ExodusII_IO_Helper::node_sets_node_list, libMesh::ExodusII_IO_Helper::NODESET, libMesh::ExodusII_IO_Helper::nodeset_ids, libMesh::ExodusII_IO_Helper::num_node_sets, libMesh::ExodusII_IO_Helper::num_nodes_per_set, libMesh::ParallelObject::processor_id(), libMesh::ExodusII_IO_Helper::read_all_nodesets(), and libMesh::ExodusII_IO_Helper::write_var_names().

◆ write_nodesets()

void libMesh::Nemesis_IO_Helper::write_nodesets ( const MeshBase mesh)
overridevirtual

Writes the nodesets for this processor.

Reimplemented from libMesh::ExodusII_IO_Helper.

Definition at line 1934 of file nemesis_io_helper.C.

1935{
1936 // Write the nodesets. In Nemesis, the idea is to "create space" for the global
1937 // set of boundary nodesets, but to only write node IDs which are local to the current
1938 // processor. This is what is done in Nemesis files created by the "loadbal" script.
1939
1940 // Store a map of vectors for boundary node IDs on this processor.
1941 // Use a vector of int here so it can be passed directly to Exodus.
1942 std::map<boundary_id_type, std::vector<int>> local_node_boundary_id_lists;
1943
1944 // FIXME: We should build this list only one time!! We already built it above, but we
1945 // did not have the libmesh to exodus node mapping at that time... for now we'll just
1946 // build it here again, hopefully it's small relative to the size of the entire mesh.
1947
1948 // Build list of (node-id, bc-id) tuples.
1949 typedef std::tuple<dof_id_type, boundary_id_type> Tuple;
1950 std::vector<Tuple> bc_tuples = mesh.get_boundary_info().build_node_list();
1951
1952 if (verbose)
1953 {
1954 libMesh::out << "[" << this->processor_id() << "] boundary_node_list.size()="
1955 << bc_tuples.size() << std::endl;
1956 libMesh::out << "[" << this->processor_id() << "] (boundary_node_id, boundary_id) = ";
1957 for (const auto & t : bc_tuples)
1958 libMesh::out << "(" << std::get<0>(t) << ", " << std::get<1>(t) << ") ";
1959 libMesh::out << std::endl;
1960 }
1961
1962 // For each node in the node list, add it to the vector of node IDs for that
1963 // set for the local processor. This will be used later when writing Exodus
1964 // nodesets.
1965 for (const auto & t : bc_tuples)
1966 {
1967 // Don't try to grab a reference to the vector unless the current node is attached
1968 // to a local element. Otherwise, another processor will be responsible for writing it in its nodeset.
1969 if (const auto it = this->libmesh_node_num_to_exodus.find(std::get<0>(t));
1970 it != this->libmesh_node_num_to_exodus.end())
1971 {
1972 // Get reference to the vector where this node ID will be inserted. If it
1973 // doesn't yet exist, this will create it.
1974 std::vector<int> & current_id_set = local_node_boundary_id_lists[std::get<1>(t)];
1975
1976 // Push back Exodus-mapped node ID for this set
1977 // TODO: reserve space in these vectors somehow.
1978 current_id_set.push_back( it->second );
1979 }
1980 }
1981
1982 // See what we got
1983 if (verbose)
1984 {
1985 for (const auto & [bndry_id, set] : local_node_boundary_id_lists)
1986 {
1987 libMesh::out << "[" << this->processor_id() << "] ID: " << bndry_id << ", ";
1988
1989 // Libmesh node ID (Exodus Node ID)
1990 for (const auto & id : set)
1991 libMesh::out << id << ", ";
1992 libMesh::out << std::endl;
1993 }
1994 }
1995
1996 // Loop over *global* nodeset IDs, call the Exodus API. Note that some nodesets may be empty
1997 // for a given processor.
1998 if (global_nodeset_ids.size() > 0)
1999 {
2000 NamesData names_table(global_nodeset_ids.size(), MAX_STR_LENGTH);
2001
2002 for (const auto & nodeset_id : this->global_nodeset_ids)
2003 {
2004 const std::string & current_ns_name =
2005 mesh.get_boundary_info().get_nodeset_name
2006 (cast_int<boundary_id_type>(nodeset_id));
2007
2008 // Store this name in a data structure that will be used to
2009 // write sideset names to file.
2010 names_table.push_back_entry(current_ns_name);
2011
2012 if (verbose)
2013 {
2014 libMesh::out << "[" << this->processor_id()
2015 << "] Writing out Exodus nodeset info for ID: " << nodeset_id
2016 << ", Name: " << current_ns_name
2017 << std::endl;
2018 }
2019
2020 // Convert current global_nodeset_id into an exodus ID, which can't be zero...
2021 int exodus_id = nodeset_id;
2022
2023 /*
2024 // Exodus can't handle zero nodeset IDs (?) Use max short here since
2025 // when libmesh reads it back in, it will want to store it as a short...
2026 if (exodus_id==0)
2027 exodus_id = std::numeric_limits<short>::max();
2028 */
2029
2030 // Try to find this boundary ID in the local list we created
2031 if (const auto it = local_node_boundary_id_lists.find (cast_int<boundary_id_type>(nodeset_id));
2032 it == local_node_boundary_id_lists.end())
2033 {
2034 // No nodes found for this boundary ID on this processor
2035 if (verbose)
2036 libMesh::out << "[" << this->processor_id()
2037 << "] No nodeset data for ID: " << nodeset_id
2038 << " on this processor." << std::endl;
2039
2040 // Call the Exodus interface to write the parameters of this node set
2041 this->ex_err = exII::ex_put_node_set_param(this->ex_id,
2042 exodus_id,
2043 0, /* No nodes for this ID */
2044 0 /* No distribution factors */);
2045 EX_CHECK_ERR(this->ex_err, "Error writing nodeset parameters in Nemesis");
2046
2047 }
2048 else // Boundary ID *was* found in list
2049 {
2050 // Get reference to the vector of node IDs
2051 const std::vector<int> & current_nodeset_ids = it->second;
2052
2053 // Call the Exodus interface to write the parameters of this node set
2054 this->ex_err = exII::ex_put_node_set_param(this->ex_id,
2055 exodus_id,
2056 current_nodeset_ids.size(),
2057 0 /* No distribution factors */);
2058
2059 EX_CHECK_ERR(this->ex_err, "Error writing nodeset parameters in Nemesis");
2060
2061 // Call Exodus interface to write the actual node IDs for this boundary ID
2062 this->ex_err = exII::ex_put_node_set(this->ex_id,
2063 exodus_id,
2064 current_nodeset_ids.data());
2065
2066 EX_CHECK_ERR(this->ex_err, "Error writing nodesets in Nemesis");
2067
2068 }
2069 } // end loop over global nodeset IDs
2070
2071 // Write out the nodeset names
2072 ex_err = exII::ex_put_names(ex_id,
2073 exII::EX_NODE_SET,
2074 names_table.get_char_star_star());
2075 EX_CHECK_ERR(ex_err, "Error writing nodeset names");
2076 } // end for loop over global nodeset IDs
2077}

References libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::NamesData::get_char_star_star(), global_nodeset_ids, libMesh::ExodusII_IO_Helper::libmesh_node_num_to_exodus, mesh, libMesh::out, libMesh::ParallelObject::processor_id(), libMesh::ExodusII_IO_Helper::NamesData::push_back_entry(), and libMesh::ExodusII_IO_Helper::verbose.

◆ write_sideset_data()

void libMesh::ExodusII_IO_Helper::write_sideset_data ( const MeshBase mesh,
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 
)
inherited

Write sideset data for the requested timestep.

Definition at line 4181 of file exodusII_io_helper.C.

4187{
4188 LOG_SCOPE("write_sideset_data()", "ExodusII_IO_Helper");
4189
4190 if ((_run_only_on_proc0) && (this->processor_id() != 0))
4191 return;
4192
4193 // Write the sideset variable names to file. This function should
4194 // only be called once for SIDESET variables, repeated calls to
4195 // write_var_names overwrites/changes the order of names that were
4196 // there previously, and will mess up any data that has already been
4197 // written.
4198 this->write_var_names(SIDESET, var_names);
4199
4200 // I hope that we are allowed to call read_sideset_info() even
4201 // though we are in the middle of writing? It seems to work provided
4202 // that you have already written the mesh itself... read_sideset_info()
4203 // fills in the following data members:
4204 // .) num_side_sets
4205 // .) ss_ids
4206 this->read_sideset_info();
4207
4208 // Write "truth" table for sideset variables. The function
4209 // exII::ex_put_variable_param() must be called before
4210 // exII::ex_put_truth_table(). For us, this happens during the call
4211 // to ExodusII_IO_Helper::write_var_names(). sset_var_tab is a logically
4212 // (num_side_sets x num_sset_var) integer array of 0s and 1s
4213 // indicating which sidesets a given sideset variable is defined on.
4214 std::vector<int> sset_var_tab(num_side_sets * var_names.size());
4215
4216 // We now call read_sideset() once per sideset and write any sideset
4217 // variable values which are defined there.
4218 int offset=0;
4219 for (int ss=0; ss<num_side_sets; ++ss)
4220 {
4221 // We don't know num_sides_per_set for each set until we call
4222 // read_sideset(). The values for each sideset are stored (using
4223 // the offsets) into the 'elem_list' and 'side_list' arrays of
4224 // this class.
4225 offset += (ss > 0 ? num_sides_per_set[ss-1] : 0);
4226 this->read_sideset(ss, offset);
4227
4228 // For each variable in var_names, write the values for the
4229 // current sideset, if any.
4230 for (auto var : index_range(var_names))
4231 {
4232 // If this var has no values on this sideset, go to the next one.
4233 if (!side_ids[var].count(ss_ids[ss]))
4234 continue;
4235
4236 // Otherwise, fill in this entry of the sideset truth table.
4237 sset_var_tab[ss*var_names.size() + var] = 1;
4238
4239 // Data vector that will eventually be passed to exII::ex_put_var().
4240 std::vector<Real> sset_var_vals(num_sides_per_set[ss]);
4241
4242 // Get reference to the BCTuple -> Real map for this variable.
4243 const auto & data_map = bc_vals[var];
4244
4245 // Loop over elem_list, side_list entries in current sideset.
4246 for (int i=0; i<num_sides_per_set[ss]; ++i)
4247 {
4248 // Get elem_id and side_id from the respective lists that
4249 // are filled in by calling read_sideset().
4250 //
4251 // Note: these are Exodus-specific ids, so we have to convert them
4252 // to libmesh ids, as that is what will be in the bc_tuples.
4253 //
4254 // TODO: we should probably consult the exodus_elem_num_to_libmesh
4255 // mapping in order to figure out which libmesh element id 'elem_id'
4256 // actually corresponds to here, instead of just assuming it will be
4257 // off by one. Unfortunately that data structure does not seem to
4258 // be used at the moment. If we assume that write_sideset_data() is
4259 // always called following write(), then this should be a fairly safe
4260 // assumption...
4261 dof_id_type elem_id = elem_list[i + offset] - 1;
4262 unsigned int side_id = side_list[i + offset] - 1;
4263
4264 // Sanity check: make sure that the "off by one"
4265 // assumption we used above to set 'elem_id' is valid.
4266 libmesh_error_msg_if
4267 (libmesh_map_find(libmesh_elem_num_to_exodus, cast_int<int>(elem_id)) !=
4268 cast_int<dof_id_type>(elem_list[i + offset]),
4269 "Error mapping Exodus elem id to libmesh elem id.");
4270
4271 // Map from Exodus side ids to libmesh side ids.
4272 const auto & conv = get_conversion(mesh.elem_ptr(elem_id)->type());
4273
4274 // Map from Exodus side ids to libmesh side ids.
4275 unsigned int converted_side_id = conv.get_side_map(side_id);
4276
4277 // Construct a key so we can quickly see whether there is any
4278 // data for this variable in the map.
4279 BoundaryInfo::BCTuple key = std::make_tuple
4280 (elem_id,
4281 converted_side_id,
4282 ss_ids[ss]);
4283
4284 // Find the data for this (elem,side,id) tuple. Throw an
4285 // error if not found. Then store value in vector which
4286 // will be passed to Exodus.
4287 sset_var_vals[i] = libmesh_map_find(data_map, key);
4288 } // end for (i)
4289
4290 // As far as I can tell, there is no "concat" version of writing
4291 // sideset data, you have to call ex_put_sset_var() once per (variable,
4292 // sideset) pair.
4293 if (sset_var_vals.size() > 0)
4294 {
4295 ex_err = exII::ex_put_var
4296 (ex_id,
4297 timestep,
4298 exII::EX_SIDE_SET,
4299 var + 1, // 1-based variable index of current variable
4300 ss_ids[ss],
4302 MappedOutputVector(sset_var_vals, _single_precision).data());
4303 EX_CHECK_ERR(ex_err, "Error writing sideset vars.");
4304 }
4305 } // end for (var)
4306 } // end for (ss)
4307
4308 // Finally, write the sideset truth table.
4309 ex_err =
4310 exII::ex_put_truth_table(ex_id,
4311 exII::EX_SIDE_SET,
4313 cast_int<int>(var_names.size()),
4314 sset_var_tab.data());
4315 EX_CHECK_ERR(ex_err, "Error writing sideset var truth table.");
4316}
void read_sideset(int id, int offset)
Reads information about sideset id and inserts it into the global sideset array at the position offse...
void read_sideset_info()
Reads information about all of the sidesets in the ExodusII mesh file.
const boundary_id_type side_id

References libMesh::ExodusII_IO_Helper::_run_only_on_proc0, libMesh::ExodusII_IO_Helper::_single_precision, libMesh::ExodusII_IO_Helper::elem_list, libMesh::MeshBase::elem_ptr(), libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::get_conversion(), libMesh::index_range(), libMesh::ExodusII_IO_Helper::libmesh_elem_num_to_exodus, mesh, libMesh::ExodusII_IO_Helper::num_side_sets, libMesh::ExodusII_IO_Helper::num_sides_per_set, libMesh::ParallelObject::processor_id(), libMesh::ExodusII_IO_Helper::read_sideset(), libMesh::ExodusII_IO_Helper::read_sideset_info(), side_id, libMesh::ExodusII_IO_Helper::side_list, libMesh::ExodusII_IO_Helper::SIDESET, libMesh::ExodusII_IO_Helper::ss_ids, libMesh::Elem::type(), and libMesh::ExodusII_IO_Helper::write_var_names().

◆ write_sidesets()

void libMesh::Nemesis_IO_Helper::write_sidesets ( const MeshBase mesh)
overridevirtual

Writes the sidesets for this processor.

Reimplemented from libMesh::ExodusII_IO_Helper.

Definition at line 2082 of file nemesis_io_helper.C.

2083{
2084 // Write the sidesets. In Nemesis, the idea is to "create space" for the global
2085 // set of boundary sidesets, but to only write sideset IDs which are local to the current
2086 // processor. This is what is done in Nemesis files created by the "loadbal" script.
2087 // See also: ExodusII_IO_Helper::write_sidesets()...
2088
2089
2090 // Store a map of vectors for boundary side IDs on this processor.
2091 // Use a vector of int here so it can be passed directly to Exodus.
2092 std::map<boundary_id_type, std::vector<int>> local_elem_boundary_id_lists;
2093 std::map<boundary_id_type, std::vector<int>> local_elem_boundary_id_side_lists;
2094
2095 // FIXME: We already built this list once, we should reuse that information!
2096 std::vector<std::tuple<dof_id_type, unsigned short int, boundary_id_type>> bndry_elem_side_id_list =
2097 mesh.get_boundary_info().build_side_list();
2098
2099 // Integer looping, skipping non-local elements
2100 for (const auto & t : bndry_elem_side_id_list)
2101 {
2102 // Get pointer to current Elem
2103 const Elem * elem = mesh.elem_ptr(std::get<0>(t));
2104
2105 std::vector<const Elem *> family;
2106#ifdef LIBMESH_ENABLE_AMR
2107 // We need to build up active elements if AMR is enabled and add
2108 // them to the exodus sidesets instead of the potentially inactive "parent" elements
2109 // Technically we don't need to "reset" the tree since the vector was just created.
2110 elem->active_family_tree_by_side(family, std::get<1>(t), /*reset tree=*/false);
2111#else
2112 // If AMR is not even enabled, just push back the element itself
2113 family.push_back( elem );
2114#endif
2115
2116 // Loop over all the elements in the family tree, store their converted IDs
2117 // and side IDs to the map's vectors. TODO: Somehow reserve enough space for these
2118 // push_back's...
2119 for (const auto & tree_elem : family)
2120 {
2121 const dof_id_type f_id = tree_elem->id();
2122 const Elem & f = mesh.elem_ref(f_id);
2123
2124 // If element is local, process it
2125 if (f.processor_id() == this->processor_id())
2126 {
2127 const auto & conv = get_conversion(f.type());
2128
2129 // Use the libmesh to exodus data structure map to get the proper sideset IDs
2130 // The data structure contains the "collapsed" contiguous ids.
2131 //
2132 // We know the parent element is local, but let's be absolutely sure that all the children have been
2133 // actually mapped to Exodus IDs before we blindly try to add them...
2134 local_elem_boundary_id_lists[ std::get<2>(t) ].push_back( libmesh_map_find(libmesh_elem_num_to_exodus, f_id) );
2135 local_elem_boundary_id_side_lists[ std::get<2>(t) ].push_back(conv.get_inverse_side_map( std::get<1>(t) ));
2136 }
2137 }
2138 }
2139
2140
2141 // Loop over *global* sideset IDs, call the Exodus API. Note that some sidesets may be empty
2142 // for a given processor.
2143 if (global_sideset_ids.size() > 0)
2144 {
2145 NamesData names_table(global_sideset_ids.size(), MAX_STR_LENGTH);
2146
2147 for (const auto & exodus_id : this->global_sideset_ids)
2148 {
2149 const std::string & current_ss_name =
2150 mesh.get_boundary_info().get_sideset_name
2151 (cast_int<boundary_id_type>(exodus_id));
2152
2153 // Store this name in a data structure that will be used to
2154 // write sideset names to file.
2155 names_table.push_back_entry(current_ss_name);
2156
2157 if (verbose)
2158 {
2159 libMesh::out << "[" << this->processor_id()
2160 << "] Writing out Exodus sideset info for ID: " << exodus_id
2161 << ", Name: " << current_ss_name
2162 << std::endl;
2163 }
2164
2165 // Try to find this boundary ID in the local list we created
2166 if (const auto it = local_elem_boundary_id_lists.find (cast_int<boundary_id_type>(exodus_id));
2167 it == local_elem_boundary_id_lists.end())
2168 {
2169 // No sides found for this boundary ID on this processor
2170 if (verbose)
2171 libMesh::out << "[" << this->processor_id()
2172 << "] No sideset data for ID: " << exodus_id
2173 << " on this processor." << std::endl;
2174
2175 // Call the Exodus interface to write the parameters of this side set
2176 this->ex_err = exII::ex_put_side_set_param(this->ex_id,
2177 exodus_id,
2178 0, /* No sides for this ID */
2179 0 /* No distribution factors */);
2180 EX_CHECK_ERR(this->ex_err, "Error writing sideset parameters in Nemesis");
2181
2182 }
2183 else // Boundary ID *was* found in list
2184 {
2185 // Get reference to the vector of elem IDs
2186 const std::vector<int> & current_sideset_elem_ids = it->second;
2187
2188 // Get reference to the vector of side IDs
2189 std::vector<int> & current_sideset_side_ids =
2190 libmesh_map_find(local_elem_boundary_id_side_lists,
2191 cast_int<boundary_id_type>(exodus_id));
2192
2193 // Call the Exodus interface to write the parameters of this side set
2194 this->ex_err = exII::ex_put_side_set_param(this->ex_id,
2195 exodus_id,
2196 current_sideset_elem_ids.size(),
2197 0 /* No distribution factors */);
2198
2199 EX_CHECK_ERR(this->ex_err, "Error writing sideset parameters in Nemesis");
2200
2201 // Call Exodus interface to write the actual side IDs for this boundary ID
2202 this->ex_err = exII::ex_put_side_set(this->ex_id,
2203 exodus_id,
2204 current_sideset_elem_ids.data(),
2205 current_sideset_side_ids.data());
2206
2207 EX_CHECK_ERR(this->ex_err, "Error writing sidesets in Nemesis");
2208 }
2209 } // end for loop over global sideset IDs
2210
2211 // Write sideset names to file. Some of these may be blank strings
2212 // if the current processor didn't have all the sideset names for
2213 // any reason...
2214 ex_err = exII::ex_put_names(this->ex_id,
2215 exII::EX_SIDE_SET,
2216 names_table.get_char_star_star());
2217 EX_CHECK_ERR(ex_err, "Error writing sideset names");
2218
2219 } // end if (global_sideset_ids.size() > 0)
2220}

References libMesh::Elem::active_family_tree_by_side(), libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::NamesData::get_char_star_star(), libMesh::ExodusII_IO_Helper::get_conversion(), global_sideset_ids, libMesh::ExodusII_IO_Helper::libmesh_elem_num_to_exodus, mesh, libMesh::out, libMesh::DofObject::processor_id(), libMesh::ParallelObject::processor_id(), libMesh::ExodusII_IO_Helper::NamesData::push_back_entry(), libMesh::Elem::type(), and libMesh::ExodusII_IO_Helper::verbose.

◆ write_timestep()

void libMesh::ExodusII_IO_Helper::write_timestep ( int  timestep,
Real  time 
)
inherited

Writes the time for the timestep.

Definition at line 4062 of file exodusII_io_helper.C.

4063{
4064 if ((_run_only_on_proc0) && (this->processor_id() != 0))
4065 return;
4066
4068 {
4069 float cast_time = float(time);
4070 ex_err = exII::ex_put_time(ex_id, timestep, &cast_time);
4071 }
4072 else
4073 {
4074 double cast_time = double(time);
4075 ex_err = exII::ex_put_time(ex_id, timestep, &cast_time);
4076 }
4077 EX_CHECK_ERR(ex_err, "Error writing timestep.");
4078
4079 this->update();
4080}

References libMesh::ExodusII_IO_Helper::_run_only_on_proc0, libMesh::ExodusII_IO_Helper::_single_precision, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::update().

◆ write_var_names()

void libMesh::ExodusII_IO_Helper::write_var_names ( ExodusVarType  type,
const std::vector< std::string > &  names 
)
protectedinherited

Wraps calls to exII::ex_put_var_names() and exII::ex_put_var_param().

The enumeration controls whether nodal, elemental, or global variable names are read and which class members are filled in.

Definition at line 2238 of file exodusII_io_helper.C.

2240{
2241 switch (type)
2242 {
2243 case NODAL:
2244 this->write_var_names_impl("n", num_nodal_vars, names);
2245 break;
2246 case ELEMENTAL:
2247 this->write_var_names_impl("e", num_elem_vars, names);
2248 break;
2249 case GLOBAL:
2250 this->write_var_names_impl("g", num_global_vars, names);
2251 break;
2252 case SIDESET:
2253 {
2254 // Note: calling this function *sets* num_sideset_vars to the
2255 // number of entries in the 'names' vector, num_sideset_vars
2256 // does not already need to be set before calling this.
2257 this->write_var_names_impl("s", num_sideset_vars, names);
2258 break;
2259 }
2260 case NODESET:
2261 {
2262 this->write_var_names_impl("m", num_nodeset_vars, names);
2263 break;
2264 }
2265 case ELEMSET:
2266 {
2267 this->write_var_names_impl("t", num_elemset_vars, names);
2268 break;
2269 }
2270 default:
2271 libmesh_error_msg("Unrecognized ExodusVarType " << type);
2272 }
2273}
void write_var_names_impl(const char *var_type, int &count, const std::vector< std::string > &names)
write_var_names() dispatches to this function.

References libMesh::ExodusII_IO_Helper::ELEMENTAL, libMesh::ExodusII_IO_Helper::ELEMSET, libMesh::ExodusII_IO_Helper::GLOBAL, libMesh::ExodusII_IO_Helper::NODAL, libMesh::ExodusII_IO_Helper::NODESET, libMesh::ExodusII_IO_Helper::num_elem_vars, libMesh::ExodusII_IO_Helper::num_elemset_vars, libMesh::ExodusII_IO_Helper::num_global_vars, libMesh::ExodusII_IO_Helper::num_nodal_vars, libMesh::ExodusII_IO_Helper::num_nodeset_vars, libMesh::ExodusII_IO_Helper::num_sideset_vars, libMesh::ExodusII_IO_Helper::SIDESET, and libMesh::ExodusII_IO_Helper::write_var_names_impl().

Referenced by libMesh::ExodusII_IO_Helper::initialize_element_variables(), initialize_element_variables(), libMesh::ExodusII_IO_Helper::initialize_global_variables(), libMesh::ExodusII_IO_Helper::initialize_nodal_variables(), libMesh::ExodusII_IO_Helper::write_elemset_data(), libMesh::ExodusII_IO_Helper::write_nodeset_data(), and libMesh::ExodusII_IO_Helper::write_sideset_data().

◆ write_var_names_impl()

void libMesh::ExodusII_IO_Helper::write_var_names_impl ( const char *  var_type,
int count,
const std::vector< std::string > &  names 
)
privateinherited

write_var_names() dispatches to this function.

Definition at line 2278 of file exodusII_io_helper.C.

2281{
2282 // Update the count variable so that it's available to other parts of the class.
2283 count = cast_int<int>(names.size());
2284
2285 // Write that number of variables to the file.
2286 ex_err = exII::ex_put_var_param(ex_id, var_type, count);
2287 EX_CHECK_ERR(ex_err, "Error setting number of vars.");
2288
2289 // Nemesis doesn't like trying to write nodal variable names in
2290 // files with no nodes.
2291 if (!this->num_nodes)
2292 return;
2293
2294 if (count > 0)
2295 {
2296 NamesData names_table(count, _max_name_length);
2297
2298 // Store the input names in the format required by Exodus.
2299 for (int i=0; i != count; ++i)
2300 {
2301 if(names[i].length() > _max_name_length)
2302 libmesh_warning(
2303 "*** Warning, Exodus variable name \"" <<
2304 names[i] << "\" too long (current max " <<
2305 _max_name_length << "/" << libmesh_max_str_length <<
2306 " characters). Name will be truncated. ");
2307 names_table.push_back_entry(names[i]);
2308 }
2309
2310 if (verbose)
2311 {
2312 libMesh::out << "Writing variable name(s) to file: " << std::endl;
2313 for (int i=0; i != count; ++i)
2314 libMesh::out << names_table.get_char_star(i) << std::endl;
2315 }
2316
2317 ex_err = exII::ex_put_var_names(ex_id,
2318 var_type,
2319 count,
2320 names_table.get_char_star_star()
2321 );
2322
2323 EX_CHECK_ERR(ex_err, "Error writing variable names.");
2324 }
2325}

References libMesh::ExodusII_IO_Helper::_max_name_length, libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::ExodusII_IO_Helper::NamesData::get_char_star(), libMesh::ExodusII_IO_Helper::NamesData::get_char_star_star(), libMesh::ExodusII_IO_Helper::num_nodes, libMesh::out, libMesh::ExodusII_IO_Helper::NamesData::push_back_entry(), and libMesh::ExodusII_IO_Helper::verbose.

Referenced by libMesh::ExodusII_IO_Helper::write_var_names().

Member Data Documentation

◆ _add_sides

bool libMesh::ExodusII_IO_Helper::_add_sides = false
privateinherited

◆ _added_side_node_offsets

std::vector<dof_id_type> libMesh::ExodusII_IO_Helper::_added_side_node_offsets
protectedinherited

If we're adding "fake" sides to visualize SIDE_DISCONTINUOUS variables, _added_side_node_offsets[p] gives us the total solution vector offset to use on processor p+1 from the nodes on those previous ranks' sides.

Definition at line 1055 of file exodusII_io_helper.h.

Referenced by libMesh::ExodusII_IO_Helper::added_node_offset_on(), libMesh::ExodusII_IO_Helper::initialize(), and libMesh::ExodusII_IO_Helper::node_id_to_vec_id().

◆ _communicator

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

◆ _coordinate_offset

Point libMesh::ExodusII_IO_Helper::_coordinate_offset
protectedinherited

◆ _elem_vars_initialized

bool libMesh::ExodusII_IO_Helper::_elem_vars_initialized
protectedinherited

◆ _end_elem_id

int libMesh::ExodusII_IO_Helper::_end_elem_id
protectedinherited

◆ _global_vars_initialized

bool libMesh::ExodusII_IO_Helper::_global_vars_initialized
protectedinherited

◆ _max_name_length

unsigned int libMesh::ExodusII_IO_Helper::_max_name_length
protectedinherited

◆ _nodal_vars_initialized

bool libMesh::ExodusII_IO_Helper::_nodal_vars_initialized
protectedinherited

◆ _opened_by_create

bool libMesh::ExodusII_IO_Helper::_opened_by_create
protectedinherited

◆ _run_only_on_proc0

bool libMesh::ExodusII_IO_Helper::_run_only_on_proc0
protectedinherited

◆ _single_precision

bool libMesh::ExodusII_IO_Helper::_single_precision
protectedinherited

◆ _true_node_offsets

std::vector<dof_id_type> libMesh::ExodusII_IO_Helper::_true_node_offsets
protectedinherited

If we're adding "fake" sides to visualize SIDE_DISCONTINUOUS variables, we also need to know how many real nodes from previous ranks are taking up space in a solution vector.

Definition at line 1062 of file exodusII_io_helper.h.

Referenced by libMesh::ExodusII_IO_Helper::added_node_offset_on(), libMesh::ExodusII_IO_Helper::initialize(), and libMesh::ExodusII_IO_Helper::node_id_to_vec_id().

◆ _use_mesh_dimension_instead_of_spatial_dimension

bool libMesh::ExodusII_IO_Helper::_use_mesh_dimension_instead_of_spatial_dimension
protectedinherited

◆ _write_as_dimension

unsigned libMesh::ExodusII_IO_Helper::_write_as_dimension
protectedinherited

◆ _write_hdf5

bool libMesh::ExodusII_IO_Helper::_write_hdf5
protectedinherited

◆ bex_cv_conn

std::vector<std::vector<long unsigned int> > libMesh::ExodusII_IO_Helper::bex_cv_conn
inherited

◆ bex_dense_constraint_vecs

std::vector<std::vector<std::vector<Real> > > libMesh::ExodusII_IO_Helper::bex_dense_constraint_vecs
inherited

◆ bex_num_elem_cvs

unsigned int libMesh::ExodusII_IO_Helper::bex_num_elem_cvs
inherited

◆ block_id_to_elem_connectivity

std::map<int, std::vector<int> > libMesh::Nemesis_IO_Helper::block_id_to_elem_connectivity

This is the block connectivity, i.e.

for each subdomain (block) there is an element connectivity list. This map associates the block ID to that vector.

Definition at line 447 of file nemesis_io_helper.h.

Referenced by build_element_and_node_maps(), and write_elements().

◆ block_ids

std::vector<int> libMesh::ExodusII_IO_Helper::block_ids
inherited

◆ border_elem_ids

std::set<unsigned> libMesh::Nemesis_IO_Helper::border_elem_ids
private

A set of border elem IDs for this processor.

Definition at line 641 of file nemesis_io_helper.h.

Referenced by compute_element_maps(), and compute_internal_and_border_elems_and_internal_nodes().

◆ border_node_ids

std::set<unsigned> libMesh::Nemesis_IO_Helper::border_node_ids
private

The set which will eventually contain the IDs of "border nodes".

These are nodes that lie on the boundary between one or more processors.

Definition at line 604 of file nemesis_io_helper.h.

Referenced by compute_border_node_ids(), and compute_node_maps().

◆ c0polyhedron_face_connect

std::vector<std::vector<int> > libMesh::ExodusII_IO_Helper::c0polyhedron_face_connect
inherited

◆ connect

std::vector<int> libMesh::ExodusII_IO_Helper::connect
inherited

◆ conversion_map

std::map<int, std::map<ElemType, ExodusII_IO_Helper::Conversion> > libMesh::ExodusII_IO_Helper::conversion_map
privateinherited

Associates libMesh ElemTypes with node/face/edge/etc.

mappings of the corresponding Exodus element types.

We have to map based on both ElemType and mesh dimension, because Exodus treats "TRI" side numbering in two different ways depending on whether a triangle is embedded in a 2D or a 3D mesh.

Definition at line 1157 of file exodusII_io_helper.h.

Referenced by libMesh::ExodusII_IO_Helper::get_conversion(), and libMesh::ExodusII_IO_Helper::init_conversion_map().

◆ current_filename

std::string libMesh::ExodusII_IO_Helper::current_filename
inherited

◆ edge_block_ids

std::vector<int> libMesh::ExodusII_IO_Helper::edge_block_ids
inherited

◆ elem_cmap_elem_cnts

std::vector<int> libMesh::Nemesis_IO_Helper::elem_cmap_elem_cnts

◆ elem_cmap_elem_ids

std::vector<std::vector<int> > libMesh::Nemesis_IO_Helper::elem_cmap_elem_ids

3 vectors of vectors for storing element communication IDs for this processor.

There will be num_elem_cmaps rows, row i will have elem_cmap_elem_cnts[i] entries. To be used with Nemesis::ne_get_elem_cmap().

Definition at line 569 of file nemesis_io_helper.h.

Referenced by compute_elem_communication_maps(), get_elem_cmap(), and initialize().

◆ elem_cmap_ids

std::vector<int> libMesh::Nemesis_IO_Helper::elem_cmap_ids

◆ elem_cmap_proc_ids

std::vector<std::vector<int> > libMesh::Nemesis_IO_Helper::elem_cmap_proc_ids

Definition at line 571 of file nemesis_io_helper.h.

Referenced by compute_elem_communication_maps(), get_elem_cmap(), and initialize().

◆ elem_cmap_side_ids

std::vector<std::vector<int> > libMesh::Nemesis_IO_Helper::elem_cmap_side_ids

Definition at line 570 of file nemesis_io_helper.h.

Referenced by compute_elem_communication_maps(), get_elem_cmap(), and initialize().

◆ elem_face_counts

std::vector<int> libMesh::ExodusII_IO_Helper::elem_face_counts
inherited

◆ elem_list

std::vector<int> libMesh::ExodusII_IO_Helper::elem_list
inherited

◆ elem_mapb

std::vector<int> libMesh::Nemesis_IO_Helper::elem_mapb

Vector which stores border element IDs.

Will have length num_border_elems. To be used with Nemesis::ne_get_elem_map().

Definition at line 514 of file nemesis_io_helper.h.

Referenced by compute_element_maps(), get_elem_map(), and initialize().

◆ elem_mapi

std::vector<int> libMesh::Nemesis_IO_Helper::elem_mapi

Vector which stores internal element IDs.

Will have length num_internal_elems. To be used with Nemesis::ne_get_elem_map().

Definition at line 507 of file nemesis_io_helper.h.

Referenced by compute_element_maps(), get_elem_map(), and initialize().

◆ elem_node_counts

std::vector<int> libMesh::ExodusII_IO_Helper::elem_node_counts
inherited

◆ elem_num_map

std::vector<int> libMesh::ExodusII_IO_Helper::elem_num_map
inherited

◆ elem_type

std::vector<char> libMesh::ExodusII_IO_Helper::elem_type
inherited

◆ elem_var_names

std::vector<std::string> libMesh::ExodusII_IO_Helper::elem_var_names
inherited

◆ elem_var_values

std::vector<Real> libMesh::ExodusII_IO_Helper::elem_var_values
inherited

Definition at line 895 of file exodusII_io_helper.h.

◆ element_equivalence_map

std::map<std::string, ElemType> libMesh::ExodusII_IO_Helper::element_equivalence_map
privateinherited

Defines equivalence classes of Exodus element types that map to libmesh ElemTypes.

Definition at line 1146 of file exodusII_io_helper.h.

Referenced by libMesh::ExodusII_IO_Helper::get_conversion(), and libMesh::ExodusII_IO_Helper::init_element_equivalence_map().

◆ elemset_id_list

std::vector<int> libMesh::ExodusII_IO_Helper::elemset_id_list
inherited

◆ elemset_ids

std::vector<int> libMesh::ExodusII_IO_Helper::elemset_ids
inherited

◆ elemset_list

std::vector<int> libMesh::ExodusII_IO_Helper::elemset_list
inherited

◆ elemset_var_names

std::vector<std::string> libMesh::ExodusII_IO_Helper::elemset_var_names
inherited

◆ ex_err

int libMesh::ExodusII_IO_Helper::ex_err
inherited

Definition at line 680 of file exodusII_io_helper.h.

Referenced by libMesh::ExodusII_IO_Helper::close(), libMesh::ExodusII_IO_Helper::create(), libMesh::ExodusII_IO_Helper::initialize(), libMesh::ExodusII_IO_Helper::initialize_element_variables(), initialize_element_variables(), libMesh::ExodusII_IO_Helper::open(), libMesh::ExodusII_IO_Helper::read_all_nodesets(), libMesh::ExodusII_IO_Helper::read_and_store_header_info(), libMesh::ExodusII_IO_Helper::read_bex_cv_blocks(), libMesh::ExodusII_IO_Helper::read_block_info(), libMesh::ExodusII_IO_Helper::read_edge_blocks(), libMesh::ExodusII_IO_Helper::read_elem_in_block(), libMesh::ExodusII_IO_Helper::read_elem_num_map(), libMesh::ExodusII_IO_Helper::read_elemental_var_values(), libMesh::ExodusII_IO_Helper::read_elemset(), libMesh::ExodusII_IO_Helper::read_elemset_data(), libMesh::ExodusII_IO_Helper::read_elemset_info(), libMesh::ExodusII_IO_Helper::read_face_blocks(), libMesh::ExodusII_IO_Helper::read_global_values(), libMesh::ExodusII_IO_Helper::read_nodal_var_values(), libMesh::ExodusII_IO_Helper::read_node_num_map(), libMesh::ExodusII_IO_Helper::read_nodes(), read_nodeset(), libMesh::ExodusII_IO_Helper::read_nodeset_data(), libMesh::ExodusII_IO_Helper::read_nodeset_info(), libMesh::ExodusII_IO_Helper::read_qa_records(), libMesh::ExodusII_IO_Helper::read_sideset(), libMesh::ExodusII_IO_Helper::read_sideset_data(), libMesh::ExodusII_IO_Helper::read_sideset_info(), libMesh::ExodusII_IO_Helper::read_time_steps(), libMesh::ExodusII_IO_Helper::read_var_names_impl(), libMesh::ExodusII_IO_Helper::update(), write_element_values(), libMesh::ExodusII_IO_Helper::write_element_values(), libMesh::ExodusII_IO_Helper::write_element_values_element_major(), libMesh::ExodusII_IO_Helper::write_elements(), write_elements(), libMesh::ExodusII_IO_Helper::write_elemset_data(), libMesh::ExodusII_IO_Helper::write_elemsets(), write_exodus_initialization_info(), libMesh::ExodusII_IO_Helper::write_global_values(), libMesh::ExodusII_IO_Helper::write_information_records(), libMesh::ExodusII_IO_Helper::write_nodal_coordinates(), write_nodal_coordinates(), libMesh::ExodusII_IO_Helper::write_nodal_values(), libMesh::ExodusII_IO_Helper::write_nodeset_data(), libMesh::ExodusII_IO_Helper::write_nodesets(), write_nodesets(), libMesh::ExodusII_IO_Helper::write_sideset_data(), libMesh::ExodusII_IO_Helper::write_sidesets(), write_sidesets(), libMesh::ExodusII_IO_Helper::write_timestep(), libMesh::ExodusII_IO_Helper::write_var_names_impl(), and ~Nemesis_IO_Helper().

◆ ex_id

int libMesh::ExodusII_IO_Helper::ex_id
inherited

Definition at line 677 of file exodusII_io_helper.h.

Referenced by libMesh::ExodusII_IO_Helper::close(), libMesh::ExodusII_IO_Helper::create(), get_cmap_params(), get_eb_info_global(), get_elem_cmap(), get_elem_map(), get_init_global(), get_init_info(), get_loadbal_param(), get_node_cmap(), get_node_map(), get_ns_param_global(), get_ss_param_global(), libMesh::ExodusII_IO_Helper::initialize(), libMesh::ExodusII_IO_Helper::initialize_element_variables(), initialize_element_variables(), libMesh::ExodusII_IO_Helper::open(), put_cmap_params(), put_eb_info_global(), put_elem_cmap(), put_elem_map(), put_init_global(), put_init_info(), put_loadbal_param(), put_node_cmap(), put_node_map(), put_ns_param_global(), put_ss_param_global(), libMesh::ExodusII_IO_Helper::read_all_nodesets(), libMesh::ExodusII_IO_Helper::read_and_store_header_info(), libMesh::ExodusII_IO_Helper::read_bex_cv_blocks(), libMesh::ExodusII_IO_Helper::read_block_info(), libMesh::ExodusII_IO_Helper::read_edge_blocks(), libMesh::ExodusII_IO_Helper::read_elem_in_block(), libMesh::ExodusII_IO_Helper::read_elem_num_map(), libMesh::ExodusII_IO_Helper::read_elemental_var_values(), libMesh::ExodusII_IO_Helper::read_elemset(), libMesh::ExodusII_IO_Helper::read_elemset_data(), libMesh::ExodusII_IO_Helper::read_elemset_info(), libMesh::ExodusII_IO_Helper::read_face_blocks(), libMesh::ExodusII_IO_Helper::read_global_values(), libMesh::ExodusII_IO_Helper::read_header(), libMesh::ExodusII_IO_Helper::read_nodal_var_values(), libMesh::ExodusII_IO_Helper::read_node_num_map(), libMesh::ExodusII_IO_Helper::read_nodes(), read_nodeset(), libMesh::ExodusII_IO_Helper::read_nodeset_data(), libMesh::ExodusII_IO_Helper::read_nodeset_info(), libMesh::ExodusII_IO_Helper::read_qa_records(), libMesh::ExodusII_IO_Helper::read_sideset(), libMesh::ExodusII_IO_Helper::read_sideset_data(), libMesh::ExodusII_IO_Helper::read_sideset_info(), libMesh::ExodusII_IO_Helper::read_time_steps(), libMesh::ExodusII_IO_Helper::read_var_names_impl(), libMesh::ExodusII_IO_Helper::update(), write_element_values(), libMesh::ExodusII_IO_Helper::write_element_values(), libMesh::ExodusII_IO_Helper::write_element_values_element_major(), libMesh::ExodusII_IO_Helper::write_elements(), write_elements(), libMesh::ExodusII_IO_Helper::write_elemset_data(), libMesh::ExodusII_IO_Helper::write_elemsets(), write_exodus_initialization_info(), libMesh::ExodusII_IO_Helper::write_global_values(), libMesh::ExodusII_IO_Helper::write_information_records(), libMesh::ExodusII_IO_Helper::write_nodal_coordinates(), write_nodal_coordinates(), libMesh::ExodusII_IO_Helper::write_nodal_values(), libMesh::ExodusII_IO_Helper::write_nodeset_data(), libMesh::ExodusII_IO_Helper::write_nodesets(), write_nodesets(), libMesh::ExodusII_IO_Helper::write_sideset_data(), libMesh::ExodusII_IO_Helper::write_sidesets(), write_sidesets(), libMesh::ExodusII_IO_Helper::write_timestep(), libMesh::ExodusII_IO_Helper::write_var_names_impl(), and ~Nemesis_IO_Helper().

◆ exodus_elem_num_to_libmesh

std::vector<int> libMesh::ExodusII_IO_Helper::exodus_elem_num_to_libmesh
inherited

Definition at line 864 of file exodusII_io_helper.h.

Referenced by build_element_and_node_maps(), and write_elements().

◆ exodus_node_num_to_libmesh

std::vector<int> libMesh::ExodusII_IO_Helper::exodus_node_num_to_libmesh
inherited

◆ ftype

char libMesh::Nemesis_IO_Helper::ftype

The type of file to be written.

Either 's', for a scalar load-balance file, or 'p' for a parallel file. To be used with Nemesis::ne_get_init_info().

Definition at line 396 of file nemesis_io_helper.h.

Referenced by get_init_info().

◆ global_elem_blk_cnts

std::vector<int> libMesh::Nemesis_IO_Helper::global_elem_blk_cnts

◆ global_elem_blk_ids

std::vector<int> libMesh::Nemesis_IO_Helper::global_elem_blk_ids

Read the global element block IDs and counts.

These vectors will eventually have num_elem_blks_global entries. To be used with Nemesis::ne_get_eb_info_global().

Definition at line 430 of file nemesis_io_helper.h.

Referenced by compute_num_global_elem_blocks(), get_eb_info_global(), initialize(), initialize_element_variables(), write_element_values(), and write_elements().

◆ global_nodeset_ids

std::vector<int> libMesh::Nemesis_IO_Helper::global_nodeset_ids

Containers for reading global nodeset information.

One vector entry per nodeset. Each vector will eventually have num_node_sets_global entries, and will be used in calls to Nemesis::ne_get_ns_param_global().

It's an error to call ne_get_ns_param_global when num_node_sets_global==0

Definition at line 420 of file nemesis_io_helper.h.

Referenced by compute_num_global_nodesets(), get_ns_param_global(), initialize(), put_ns_param_global(), write_exodus_initialization_info(), and write_nodesets().

◆ global_sideset_ids

std::vector<int> libMesh::Nemesis_IO_Helper::global_sideset_ids

Containers for reading global sideset (boundary conditions) information.

Each vector will eventually have num_side_sets_global entries, and be used in calls to Nemesis::ne_get_ss_param_global().

It's an error to call ne_get_ss_param_global when num_side_sets_global==0

Definition at line 408 of file nemesis_io_helper.h.

Referenced by compute_num_global_sidesets(), get_ss_param_global(), initialize(), put_ss_param_global(), write_exodus_initialization_info(), and write_sidesets().

◆ global_var_names

std::vector<std::string> libMesh::ExodusII_IO_Helper::global_var_names
inherited

◆ header_info

ExodusHeaderInfo libMesh::ExodusII_IO_Helper::header_info
inherited

◆ id_list

std::vector<int> libMesh::ExodusII_IO_Helper::id_list
inherited

◆ id_to_block_names

std::map<int, std::string> libMesh::ExodusII_IO_Helper::id_to_block_names
inherited

◆ id_to_edge_block_names

std::map<int, std::string> libMesh::ExodusII_IO_Helper::id_to_edge_block_names
inherited

◆ id_to_elemset_names

std::map<int, std::string> libMesh::ExodusII_IO_Helper::id_to_elemset_names
inherited

◆ id_to_ns_names

std::map<int, std::string> libMesh::ExodusII_IO_Helper::id_to_ns_names
inherited

◆ id_to_ss_names

std::map<int, std::string> libMesh::ExodusII_IO_Helper::id_to_ss_names
inherited

◆ internal_elem_ids

std::set<unsigned> libMesh::Nemesis_IO_Helper::internal_elem_ids
private

A set of internal elem IDs for this processor.

Definition at line 636 of file nemesis_io_helper.h.

Referenced by compute_element_maps(), and compute_internal_and_border_elems_and_internal_nodes().

◆ internal_node_ids

std::set<unsigned> libMesh::Nemesis_IO_Helper::internal_node_ids
private

A set of internal node IDs for this processor.

Definition at line 631 of file nemesis_io_helper.h.

Referenced by compute_internal_and_border_elems_and_internal_nodes(), and compute_node_maps().

◆ libmesh_elem_num_to_exodus

std::map<dof_id_type, dof_id_type> libMesh::ExodusII_IO_Helper::libmesh_elem_num_to_exodus
inherited

◆ libmesh_node_num_to_exodus

std::map<dof_id_type, dof_id_type> libMesh::ExodusII_IO_Helper::libmesh_node_num_to_exodus
inherited

◆ local_subdomain_counts

std::map<subdomain_id_type, unsigned> libMesh::Nemesis_IO_Helper::local_subdomain_counts
private

This map keeps track of the number of elements in each subdomain (block) for this processor.

Definition at line 598 of file nemesis_io_helper.h.

Referenced by build_element_and_node_maps(), and compute_num_global_elem_blocks().

◆ nemesis_err_flag

int libMesh::Nemesis_IO_Helper::nemesis_err_flag

◆ nodal_var_names

std::vector<std::string> libMesh::ExodusII_IO_Helper::nodal_var_names
inherited

◆ nodal_var_values

std::map<dof_id_type, Real> libMesh::ExodusII_IO_Helper::nodal_var_values
inherited

◆ node_cmap_ids

std::vector<int> libMesh::Nemesis_IO_Helper::node_cmap_ids

Vectors for storing the communication map parameters.

Each will eventually have length num_node_cmaps OR num_elem_cmaps as appropriate. For use with Nemesis::ne_get_cmap_params().

Definition at line 546 of file nemesis_io_helper.h.

Referenced by compute_communication_map_parameters(), compute_node_communication_maps(), get_cmap_params(), get_node_cmap(), initialize(), and put_node_cmap().

◆ node_cmap_node_cnts

std::vector<int> libMesh::Nemesis_IO_Helper::node_cmap_node_cnts

◆ node_cmap_node_ids

std::vector<std::vector<int> > libMesh::Nemesis_IO_Helper::node_cmap_node_ids

2 vectors of vectors for storing the node communication IDs for this processor.

There will be num_node_cmaps rows, row i will have node_cmap_node_cnts[i] entries. To be used with Nemesis::ne_get_node_cmap().

Remark: node_cmap_proc_ids is a vector, all entries of which are = node_cmap_ids[i] Not sure what the point of that is...

Definition at line 560 of file nemesis_io_helper.h.

Referenced by compute_node_communication_maps(), get_node_cmap(), and initialize().

◆ node_cmap_proc_ids

std::vector<std::vector<int> > libMesh::Nemesis_IO_Helper::node_cmap_proc_ids

Definition at line 561 of file nemesis_io_helper.h.

Referenced by compute_node_communication_maps(), get_node_cmap(), and initialize().

◆ node_list

std::vector<int> libMesh::Nemesis_IO_Helper::node_list

Definition at line 399 of file nemesis_io_helper.h.

Referenced by read_nodeset().

◆ node_mapb

std::vector<int> libMesh::Nemesis_IO_Helper::node_mapb

Vector which stores border node IDs.

Will have length num_border_nodes. To be used with Nemesis::ne_get_node_map().

Definition at line 530 of file nemesis_io_helper.h.

Referenced by compute_node_maps(), get_node_map(), and initialize().

◆ node_mape

std::vector<int> libMesh::Nemesis_IO_Helper::node_mape

Vector which stores external node IDs.

Will have length num_external_nodes. To be used with Nemesis::ne_get_node_map().

Definition at line 537 of file nemesis_io_helper.h.

Referenced by compute_node_maps(), get_node_map(), and initialize().

◆ node_mapi

std::vector<int> libMesh::Nemesis_IO_Helper::node_mapi

Vector which stores internal node IDs.

Will have length num_internal_nodes. To be used with Nemesis::ne_get_node_map().

Definition at line 523 of file nemesis_io_helper.h.

Referenced by compute_node_maps(), get_node_map(), and initialize().

◆ node_num_map

std::vector<int> libMesh::ExodusII_IO_Helper::node_num_map
inherited

◆ node_sets_dist_fact

std::vector<Real> libMesh::ExodusII_IO_Helper::node_sets_dist_fact
inherited

◆ node_sets_dist_index

std::vector<int> libMesh::ExodusII_IO_Helper::node_sets_dist_index
inherited

◆ node_sets_node_index

std::vector<int> libMesh::ExodusII_IO_Helper::node_sets_node_index
inherited

◆ node_sets_node_list

std::vector<int> libMesh::ExodusII_IO_Helper::node_sets_node_list
inherited

◆ nodes_attached_to_local_elems

std::set<int> libMesh::Nemesis_IO_Helper::nodes_attached_to_local_elems

libMesh numbered node ids attached to local elems.

Definition at line 436 of file nemesis_io_helper.h.

Referenced by build_element_and_node_maps(), and compute_internal_and_border_elems_and_internal_nodes().

◆ nodeset_ids

std::vector<int> libMesh::ExodusII_IO_Helper::nodeset_ids
inherited

◆ nodeset_var_names

std::vector<std::string> libMesh::ExodusII_IO_Helper::nodeset_var_names
inherited

◆ num_attr

int libMesh::ExodusII_IO_Helper::num_attr
inherited

◆ num_border_elems

int libMesh::Nemesis_IO_Helper::num_border_elems

The number of border FEM elements.

Elements local to this processor but whose FEM nodes reside on other processors as well. To be used with the Nemesis::ne_get_loadbal_param() routine.

Definition at line 484 of file nemesis_io_helper.h.

Referenced by compute_internal_and_border_elems_and_internal_nodes(), get_elem_map(), get_loadbal_param(), and initialize().

◆ num_border_nodes

int libMesh::Nemesis_IO_Helper::num_border_nodes

The number of FEM nodes local to a processor but residing in an element which also has FEM nodes on other processors.

To be used with the Nemesis::ne_get_loadbal_param() routine.

Definition at line 464 of file nemesis_io_helper.h.

Referenced by compute_border_node_ids(), compute_internal_and_border_elems_and_internal_nodes(), get_loadbal_param(), get_node_map(), and initialize().

◆ num_df_per_set

std::vector<int> libMesh::ExodusII_IO_Helper::num_df_per_set
inherited

◆ num_dim

int& libMesh::ExodusII_IO_Helper::num_dim
inherited

◆ num_edge

int& libMesh::ExodusII_IO_Helper::num_edge
inherited

Definition at line 705 of file exodusII_io_helper.h.

Referenced by libMesh::ExodusII_IO_Helper::initialize().

◆ num_edge_blk

int& libMesh::ExodusII_IO_Helper::num_edge_blk
inherited

◆ num_elem

int& libMesh::ExodusII_IO_Helper::num_elem
inherited

◆ num_elem_all_elemsets

int libMesh::ExodusII_IO_Helper::num_elem_all_elemsets
inherited

◆ num_elem_all_sidesets

int libMesh::ExodusII_IO_Helper::num_elem_all_sidesets
inherited

◆ num_elem_blk

int& libMesh::ExodusII_IO_Helper::num_elem_blk
inherited

◆ num_elem_blks_global

int libMesh::Nemesis_IO_Helper::num_elem_blks_global

◆ num_elem_cmaps

int libMesh::Nemesis_IO_Helper::num_elem_cmaps

The number of elemental communication maps for this processor.

(One per neighboring proc?) To be used with the Nemesis::ne_get_loadbal_param() routine.

Definition at line 498 of file nemesis_io_helper.h.

Referenced by compute_communication_map_parameters(), compute_elem_communication_maps(), compute_internal_and_border_elems_and_internal_nodes(), get_cmap_params(), get_elem_cmap(), get_loadbal_param(), and initialize().

◆ num_elem_df_per_set

std::vector<int> libMesh::ExodusII_IO_Helper::num_elem_df_per_set
inherited

◆ num_elem_sets

int& libMesh::ExodusII_IO_Helper::num_elem_sets
inherited

◆ num_elem_this_blk

int libMesh::ExodusII_IO_Helper::num_elem_this_blk
inherited

◆ num_elem_vars

int libMesh::ExodusII_IO_Helper::num_elem_vars
inherited

◆ num_elems_global

int libMesh::Nemesis_IO_Helper::num_elems_global

Definition at line 373 of file nemesis_io_helper.h.

Referenced by get_init_global().

◆ num_elems_per_set

std::vector<int> libMesh::ExodusII_IO_Helper::num_elems_per_set
inherited

◆ num_elemset_vars

int libMesh::ExodusII_IO_Helper::num_elemset_vars
inherited

◆ num_external_nodes

int libMesh::Nemesis_IO_Helper::num_external_nodes

The number of FEM nodes that reside on another processor but whose element partially resides on the current processor.

To be used with the Nemesis::ne_get_loadbal_param() routine.

Definition at line 471 of file nemesis_io_helper.h.

Referenced by get_loadbal_param(), get_node_map(), and initialize().

◆ num_face

int& libMesh::ExodusII_IO_Helper::num_face
inherited

◆ num_face_blk

int& libMesh::ExodusII_IO_Helper::num_face_blk
inherited

◆ num_global_node_counts

std::vector<int> libMesh::Nemesis_IO_Helper::num_global_node_counts

◆ num_global_node_df_counts

std::vector<int> libMesh::Nemesis_IO_Helper::num_global_node_df_counts

Definition at line 422 of file nemesis_io_helper.h.

Referenced by get_ns_param_global(), and initialize().

◆ num_global_side_counts

std::vector<int> libMesh::Nemesis_IO_Helper::num_global_side_counts

◆ num_global_side_df_counts

std::vector<int> libMesh::Nemesis_IO_Helper::num_global_side_df_counts

Definition at line 410 of file nemesis_io_helper.h.

Referenced by get_ss_param_global(), and initialize().

◆ num_global_vars

int libMesh::ExodusII_IO_Helper::num_global_vars
inherited

◆ num_internal_elems

int libMesh::Nemesis_IO_Helper::num_internal_elems

The number of internal FEM elements.

Elements local to this processor. To be used with the Nemesis::ne_get_loadbal_param() routine.

Definition at line 477 of file nemesis_io_helper.h.

Referenced by compute_internal_and_border_elems_and_internal_nodes(), get_elem_map(), get_loadbal_param(), and initialize().

◆ num_internal_nodes

int libMesh::Nemesis_IO_Helper::num_internal_nodes

To be used with the Nemesis::ne_get_loadbal_param() routine.

The number of FEM nodes contained in FEM elements wholly owned by the current processor. To be used with the Nemesis::ne_get_loadbal_param() routine.

Definition at line 457 of file nemesis_io_helper.h.

Referenced by compute_internal_and_border_elems_and_internal_nodes(), get_loadbal_param(), get_node_map(), and initialize().

◆ num_nodal_vars

int libMesh::ExodusII_IO_Helper::num_nodal_vars
inherited

◆ num_node_cmaps

int libMesh::Nemesis_IO_Helper::num_node_cmaps

The number of nodal communication maps for this processor.

(One per neighboring proc?) To be used with the Nemesis::ne_get_loadbal_param() routine.

Definition at line 491 of file nemesis_io_helper.h.

Referenced by compute_border_node_ids(), compute_communication_map_parameters(), compute_node_communication_maps(), get_cmap_params(), get_loadbal_param(), get_node_cmap(), and initialize().

◆ num_node_df_per_set

std::vector<int> libMesh::ExodusII_IO_Helper::num_node_df_per_set
inherited

◆ num_node_sets

int& libMesh::ExodusII_IO_Helper::num_node_sets
inherited

◆ num_node_sets_global

int libMesh::Nemesis_IO_Helper::num_node_sets_global

◆ num_nodes

int& libMesh::ExodusII_IO_Helper::num_nodes
inherited

◆ num_nodes_global

int libMesh::Nemesis_IO_Helper::num_nodes_global

Global initial information.

The names are self-explanatory for the most part. Used with Nemesis::ne_get_init_global().

Definition at line 372 of file nemesis_io_helper.h.

Referenced by get_init_global().

◆ num_nodes_per_elem

int libMesh::ExodusII_IO_Helper::num_nodes_per_elem
inherited

◆ num_nodes_per_set

std::vector<int> libMesh::ExodusII_IO_Helper::num_nodes_per_set
inherited

◆ num_nodeset_vars

int libMesh::ExodusII_IO_Helper::num_nodeset_vars
inherited

◆ num_proc

int libMesh::Nemesis_IO_Helper::num_proc

The number of processors for which the NEMESIS I file was created.

To be used with Nemesis::ne_get_init_info().

Definition at line 382 of file nemesis_io_helper.h.

Referenced by get_init_info().

◆ num_proc_in_file

int libMesh::Nemesis_IO_Helper::num_proc_in_file

The number of processors for which the NEMESIS I file stores information.

This is generally equal to 1 (1 CPU/file) at least for the splitting Derek gave us. To be used with Nemesis::ne_get_init_info().

Definition at line 389 of file nemesis_io_helper.h.

Referenced by get_init_info().

◆ num_side_sets

int& libMesh::ExodusII_IO_Helper::num_side_sets
inherited

◆ num_side_sets_global

int libMesh::Nemesis_IO_Helper::num_side_sets_global

◆ num_sides_per_set

std::vector<int> libMesh::ExodusII_IO_Helper::num_sides_per_set
inherited

◆ num_sideset_vars

int libMesh::ExodusII_IO_Helper::num_sideset_vars
inherited

◆ num_time_steps

int libMesh::ExodusII_IO_Helper::num_time_steps
inherited

◆ opened_for_reading

bool libMesh::ExodusII_IO_Helper::opened_for_reading
inherited

◆ opened_for_writing

bool libMesh::ExodusII_IO_Helper::opened_for_writing
inherited

◆ proc_border_elem_sets

std::map<unsigned, std::set<std::pair<unsigned,unsigned> > > libMesh::Nemesis_IO_Helper::proc_border_elem_sets
private

Map between processor ID and (element,side) pairs bordering that processor ID.

Definition at line 621 of file nemesis_io_helper.h.

Referenced by compute_communication_map_parameters(), compute_elem_communication_maps(), and compute_internal_and_border_elems_and_internal_nodes().

◆ proc_nodes_touched_intersections

std::map<unsigned, std::set<unsigned> > libMesh::Nemesis_IO_Helper::proc_nodes_touched_intersections
private

Another map to store sets of intersections with each other processor (other than ourself, of course).

A node which appears in one of these vectors belongs to element owned by at least this processor and one other.

Definition at line 611 of file nemesis_io_helper.h.

Referenced by compute_border_node_ids(), compute_communication_map_parameters(), and compute_node_communication_maps().

◆ set_unique_ids_from_maps

bool libMesh::ExodusII_IO_Helper::set_unique_ids_from_maps
inherited

◆ side_list

std::vector<int> libMesh::ExodusII_IO_Helper::side_list
inherited

◆ sideset_var_names

std::vector<std::string> libMesh::ExodusII_IO_Helper::sideset_var_names
inherited

◆ ss_ids

std::vector<int> libMesh::ExodusII_IO_Helper::ss_ids
inherited

◆ subdomain_map

std::map<subdomain_id_type, std::vector<dof_id_type> > libMesh::Nemesis_IO_Helper::subdomain_map

Map of subdomains to element numbers.

Definition at line 441 of file nemesis_io_helper.h.

Referenced by build_element_and_node_maps(), write_element_values(), and write_elements().

◆ time_steps

std::vector<Real> libMesh::ExodusII_IO_Helper::time_steps
inherited

Definition at line 875 of file exodusII_io_helper.h.

Referenced by libMesh::ExodusII_IO_Helper::read_time_steps().

◆ title

std::vector<char>& libMesh::ExodusII_IO_Helper::title
inherited

◆ verbose

bool libMesh::ExodusII_IO_Helper::verbose
inherited

◆ w

std::vector<Real> libMesh::ExodusII_IO_Helper::w
inherited

Definition at line 846 of file exodusII_io_helper.h.

Referenced by libMesh::ExodusII_IO_Helper::read_nodes().

◆ write_complex_abs

bool libMesh::Nemesis_IO_Helper::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).

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 582 of file nemesis_io_helper.h.

Referenced by write_element_values().

◆ x

std::vector<Real> libMesh::ExodusII_IO_Helper::x
inherited

◆ y

std::vector<Real> libMesh::ExodusII_IO_Helper::y
inherited

◆ z

std::vector<Real> libMesh::ExodusII_IO_Helper::z
inherited

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