libMesh
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. More...
 
virtual ~Nemesis_IO_Helper ()
 Destructor. More...
 
void write_complex_magnitude (bool val)
 Set the flag indicating whether the complex modulus should be written when complex numbers are enabled. More...
 
void read_nodeset (int id)
 Reading functions. More...
 
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. More...
 
void get_ss_param_global ()
 Fills: global_sideset_ids, num_global_side_counts, num_global_side_df_counts Call after: get_init_global() More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
void put_elem_map (std::vector< int > &elem_mapi, std::vector< int > &elem_mapb)
 Outputs IDs of internal and border elements. More...
 
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. More...
 
virtual void write_elements (const MeshBase &mesh, bool use_discontinuous=false) override
 This function is specialized to write the connectivity. More...
 
virtual void write_sidesets (const MeshBase &mesh) override
 Writes the sidesets for this processor. More...
 
virtual void write_nodesets (const MeshBase &mesh) override
 Writes the nodesets for this processor. More...
 
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. More...
 
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. More...
 
void build_element_and_node_maps (const MeshBase &pmesh)
 This function builds the libmesh -> exodus and exodus -> libmesh node and element maps. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
const char * get_elem_type () const
 
void set_add_sides (bool add_sides)
 Sets whether or not to write extra "side" elements. More...
 
bool get_add_sides ()
 
void open (const char *filename, bool read_only)
 Opens an ExodusII mesh file named filename. More...
 
ExodusHeaderInfo read_header () const
 Reads an ExodusII mesh file header, leaving this object's internal data structures unchanged. More...
 
void read_and_store_header_info ()
 Reads an ExodusII mesh file header, and stores required information on this object. More...
 
void read_qa_records ()
 Reads the QA records from an ExodusII file. More...
 
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. More...
 
void read_nodes ()
 Reads the nodal data (x,y,z coordinates) from the ExodusII mesh file. More...
 
void read_node_num_map ()
 Reads the optional node_num_map from the ExodusII mesh file. More...
 
void read_bex_cv_blocks ()
 Reads the optional bex_cv_blocks from the ExodusII mesh file. More...
 
void print_nodes (std::ostream &out_stream=libMesh::out)
 Prints the nodal information, by default to libMesh::out. More...
 
void read_block_info ()
 Reads information for all of the blocks in the ExodusII mesh file. More...
 
int get_block_id (int index)
 Get the block number for the given block index. More...
 
std::string get_block_name (int index)
 Get the block name for the given block index if supplied in the mesh file. More...
 
int get_side_set_id (int index)
 Get the side set id for the given side set index. More...
 
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. More...
 
int get_node_set_id (int index)
 Get the node set id for the given node set index. More...
 
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. More...
 
void read_elem_in_block (int block)
 Reads all of the element connectivity for block block in the ExodusII mesh file. More...
 
void read_edge_blocks (MeshBase &mesh)
 Read in edge blocks, storing information in the BoundaryInfo object. More...
 
void read_elem_num_map ()
 Reads the optional node_num_map from the ExodusII mesh file. More...
 
void read_sideset_info ()
 Reads information about all of the sidesets in the ExodusII mesh file. More...
 
void read_nodeset_info ()
 Reads information about all of the nodesets in the ExodusII mesh file. More...
 
void read_elemset_info ()
 Reads information about all of the elemsets in the ExodusII mesh file. More...
 
void read_sideset (int id, int offset)
 Reads information about sideset id and inserts it into the global sideset array at the position offset. More...
 
void read_elemset (int id, int offset)
 Reads information about elemset id and inserts it into the global elemset array at the position offset. More...
 
void read_all_nodesets ()
 New API that reads all nodesets simultaneously. More...
 
void close () noexcept
 Closes the ExodusII mesh file. More...
 
void read_time_steps ()
 Reads and stores the timesteps in the 'time_steps' array. More...
 
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. More...
 
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. More...
 
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. More...
 
virtual void create (std::string filename)
 Opens an ExodusII mesh file named filename for writing. More...
 
void initialize_nodal_variables (std::vector< std::string > names)
 Sets up the nodal variables. More...
 
void initialize_global_variables (std::vector< std::string > names)
 Sets up the global variables. More...
 
void write_timestep (int timestep, Real time)
 Writes the time for the timestep. More...
 
void write_elemsets (const MeshBase &mesh)
 Write elemsets stored on the Mesh to the exo file. More...
 
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. More...
 
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. More...
 
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). More...
 
void write_nodeset_data (int timestep, const std::vector< std::string > &var_names, const std::vector< std::set< boundary_id_type >> &node_boundary_ids, const std::vector< std::map< BoundaryInfo::NodeBCTuple, Real >> &bc_vals)
 Write nodeset data for the requested timestep. More...
 
void read_nodeset_data (int timestep, std::vector< std::string > &var_names, std::vector< std::set< boundary_id_type >> &node_boundary_ids, std::vector< std::map< BoundaryInfo::NodeBCTuple, Real >> &bc_vals)
 Read nodeset variables, if any, into the provided data structures. More...
 
void get_nodeset_data_indices (std::map< BoundaryInfo::NodeBCTuple, unsigned int > &bc_array_indices)
 Similar to read_nodeset_data(), but instead of creating one std::map per nodeset per variable, creates a single map of (node_id, boundary_id) tuples, and stores the exo file array indexing for any/all nodeset variables on that nodeset (they are all the same). More...
 
void write_elemset_data (int timestep, const std::vector< std::string > &var_names, const std::vector< std::set< elemset_id_type >> &elemset_ids_in, const std::vector< std::map< std::pair< dof_id_type, elemset_id_type >, Real >> &elemset_vals)
 Write elemset data for the requested timestep. More...
 
void read_elemset_data (int timestep, std::vector< std::string > &var_names, std::vector< std::set< elemset_id_type >> &elemset_ids_in, std::vector< std::map< std::pair< dof_id_type, elemset_id_type >, Real >> &elemset_vals)
 Read elemset variables, if any, into the provided data structures. More...
 
void get_elemset_data_indices (std::map< std::pair< dof_id_type, elemset_id_type >, unsigned int > &elemset_array_indices)
 Similar to read_elemset_data(), but instead of creating one std::map per 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). More...
 
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. More...
 
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. More...
 
void write_nodal_values (int var_id, const std::vector< Real > &values, int timestep)
 Writes the vector of values to a nodal variable. More...
 
void write_information_records (const std::vector< std::string > &records)
 Writes the vector of information records. More...
 
void write_global_values (const std::vector< Real > &values, int timestep)
 Writes the vector of global variables. More...
 
void update ()
 Uses ex_update() to flush buffers to file. More...
 
void read_global_values (std::vector< Real > &values, int timestep)
 Reads the vector of global variables. More...
 
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. More...
 
void set_hdf5_writing (bool write_hdf5)
 Set to true (the default) to write files in an HDF5-based file format (when HDF5 is available), or to false to write files in the old NetCDF3-based format. More...
 
void write_as_dimension (unsigned dim)
 Sets the value of _write_as_dimension. More...
 
void set_coordinate_offset (Point p)
 Allows you to set a vector that is added to the coordinates of all of the nodes. More...
 
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. More...
 
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. More...
 
void message (std::string_view msg)
 Prints the message defined in msg. More...
 
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. More...
 
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. More...
 
int num_nodes_global
 Global initial information. More...
 
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. More...
 
int num_proc_in_file
 The number of processors for which the NEMESIS I file stores information. More...
 
char ftype
 The type of file to be written. More...
 
std::vector< intnode_list
 
std::vector< intglobal_sideset_ids
 Containers for reading global sideset (boundary conditions) information. More...
 
std::vector< intnum_global_side_counts
 
std::vector< intnum_global_side_df_counts
 
std::vector< intglobal_nodeset_ids
 Containers for reading global nodeset information. More...
 
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. More...
 
std::vector< intglobal_elem_blk_cnts
 
std::set< intnodes_attached_to_local_elems
 libMesh numbered node ids attached to local elems. More...
 
std::map< subdomain_id_type, std::vector< dof_id_type > > subdomain_map
 Map of subdomains to element numbers. More...
 
std::map< int, std::vector< int > > block_id_to_elem_connectivity
 This is the block connectivity, i.e. More...
 
int num_internal_nodes
 To be used with the Nemesis::ne_get_loadbal_param() routine. More...
 
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. More...
 
int num_external_nodes
 The number of FEM nodes that reside on another processor but whose element partially resides on the current processor. More...
 
int num_internal_elems
 The number of internal FEM elements. More...
 
int num_border_elems
 The number of border FEM elements. More...
 
int num_node_cmaps
 The number of nodal communication maps for this processor. More...
 
int num_elem_cmaps
 The number of elemental communication maps for this processor. More...
 
std::vector< intelem_mapi
 Vector which stores internal element IDs. More...
 
std::vector< intelem_mapb
 Vector which stores border element IDs. More...
 
std::vector< intnode_mapi
 Vector which stores internal node IDs. More...
 
std::vector< intnode_mapb
 Vector which stores border node IDs. More...
 
std::vector< intnode_mape
 Vector which stores external node IDs. More...
 
std::vector< intnode_cmap_ids
 Vectors for storing the communication map parameters. More...
 
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. More...
 
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. More...
 
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). More...
 
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_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< 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 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. More...
 
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. More...
 
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(). More...
 

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

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. More...
 
void compute_num_global_sidesets (const MeshBase &pmesh)
 This function uses global communication routines to determine the number of sidesets across the entire mesh. More...
 
void compute_border_node_ids (const MeshBase &pmesh)
 This function constructs the set of border node IDs present on the current mesh. More...
 
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. More...
 
void compute_communication_map_parameters ()
 This function determines the communication map parameters which will eventually be written to file. More...
 
void compute_node_communication_maps ()
 Compute the node communication maps (really just pack vectors) in preparation for writing them to file. More...
 
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. More...
 
void compute_elem_communication_maps ()
 This function computes element communication maps (really just packs vectors) in preparation for writing them to file. More...
 
void compute_element_maps ()
 This function computes element maps (really just packs vectors) which map the elements to internal and border elements. More...
 
void write_exodus_initialization_info (const MeshBase &pmesh, const std::string &title)
 This function writes exodus-specific initialization information. More...
 

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. More...
 
std::set< unsigned > border_node_ids
 The set which will eventually contain the IDs of "border nodes". More...
 
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). More...
 
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. More...
 
std::set< unsigned > internal_node_ids
 A set of internal node IDs for this processor. More...
 
std::set< unsigned > internal_elem_ids
 A set of internal elem IDs for this processor. More...
 
std::set< unsigned > border_elem_ids
 A set of border elem IDs for this processor. More...
 

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 70 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 644 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 634 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 881 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 58 of file nemesis_io_helper.C.

59  :
60  ExodusII_IO_Helper(parent, verbose_in, /*run_only_on_proc0=*/false, /*single_precision=*/single_precision),
67  num_proc(0),
69  ftype('\0'),
75  num_node_cmaps(0),
76  num_elem_cmaps(0),
77  write_complex_abs(true)
78 {
79  // Warn about using untested code!
80  libmesh_experimental();
81 }
char ftype
The type of file to be written.
ExodusII_IO_Helper(const ParallelObject &parent, bool v=false, bool run_only_on_proc0=true, bool single_precision=false)
Constructor.
int num_external_nodes
The number of FEM nodes that reside on another processor but whose element partially resides on the c...
int nemesis_err_flag
Member data.
int num_node_cmaps
The number of nodal communication maps for this processor.
bool write_complex_abs
By default, when complex numbers are enabled, for each variable we write out three values: the real p...
int num_nodes_global
Global initial information.
int num_proc
The number of processors for which the NEMESIS I file was created.
int num_internal_elems
The number of internal FEM elements.
int num_elem_cmaps
The number of elemental communication maps for this processor.
int num_proc_in_file
The number of processors for which the NEMESIS I file stores information.
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_internal_nodes
To be used with the Nemesis::ne_get_loadbal_param() routine.
int num_border_elems
The number of border FEM elements.

◆ ~Nemesis_IO_Helper()

libMesh::Nemesis_IO_Helper::~Nemesis_IO_Helper ( )
virtual

Destructor.

Definition at line 84 of file nemesis_io_helper.C.

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.

85 {
86  // Our destructor is called from Nemesis_IO. We close the Exodus file here since we have
87  // responsibility for managing the file's lifetime. Only call ex_update() if the file was
88  // opened for writing!
89  if (this->opened_for_writing)
90  {
91  this->ex_err = exII::ex_update(this->ex_id);
92  EX_EXCEPTIONLESS_CHECK_ERR(ex_err, "Error flushing buffers to file.");
93  }
94  this->close();
95 }
void close() noexcept
Closes the ExodusII mesh file.

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 915 of file exodusII_io_helper.h.

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

916  {
917  libmesh_assert (p < _true_node_offsets.size());
918  const dof_id_type added_node_offsets =
919  (_added_side_node_offsets.empty() || !p) ? 0 :
921  return _true_node_offsets[p] + added_node_offsets;
922  }
libmesh_assert(ctx)
std::vector< dof_id_type > _true_node_offsets
If we&#39;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&#39;re adding "fake" sides to visualize SIDE_DISCONTINUOUS variables, _added_side_node_offsets[p] g...
uint8_t dof_id_type
Definition: id_types.h:67

◆ 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 1630 of file nemesis_io_helper.C.

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

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

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

References libMesh::err, libMesh::Quality::name(), 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().

3357 {
3358  // There may already be global variables in the file (for example,
3359  // if we're appending) and in that case, we
3360  // 1.) Cannot initialize them again.
3361  // 2.) Should check to be sure that the global variable names are the same.
3362 
3363  // Fills up names_from_file for us
3364  this->read_var_names(type);
3365 
3366  // Both the number of variables and their names (up to the first
3367  // MAX_STR_LENGTH characters) must match for the names we are
3368  // planning to write and the names already in the file.
3369  bool match =
3370  std::equal(names.begin(), names.end(),
3371  names_from_file.begin(),
3372  [](const std::string & a,
3373  const std::string & b) -> bool
3374  {
3375  return a.compare(/*pos=*/0, /*len=*/MAX_STR_LENGTH, b) == 0;
3376  });
3377 
3378  if (!match)
3379  {
3380  libMesh::err << "Error! The Exodus file already contains the variables:" << std::endl;
3381  for (const auto & name : names_from_file)
3382  libMesh::err << name << std::endl;
3383 
3384  libMesh::err << "And you asked to write:" << std::endl;
3385  for (const auto & name : names)
3386  libMesh::err << name << std::endl;
3387 
3388  libmesh_error_msg("Cannot overwrite existing variables in Exodus II file.");
3389  }
3390 }
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
Definition: elem_quality.C:42
OStreamProxy err
void read_var_names(ExodusVarType type)

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

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

1774 {
1775  // Call ex_close on every processor that did ex_open or ex_create;
1776  // newer Exodus versions error if we try to reopen a file that
1777  // hasn't been officially closed. Don't close the file if we didn't
1778  // open it; this also raises an Exodus error.
1779 
1780  // We currently do read-only ex_open on every proc (to do read
1781  // operations on every proc), but we do ex_open and ex_create for
1782  // writes on every proc only with Nemesis files.
1784  (this->processor_id() == 0) ||
1785  (!_run_only_on_proc0))
1786  {
1788  {
1789  ex_err = exII::ex_close(ex_id);
1790  // close() is called from the destructor, so it may be called e.g.
1791  // during stack unwinding while processing an exception. In that case
1792  // we don't want to throw another exception or immediately terminate
1793  // the code, since that would prevent any possible recovery from the
1794  // exception in question. So we just log the error closing the file
1795  // and continue.
1796  if (ex_err < 0)
1797  message("Error closing Exodus file.");
1798  else
1799  message("Exodus file closed successfully.");
1800  }
1801  }
1802 
1803  // Now that the file is closed, it's no longer opened for
1804  // reading or writing.
1805  opened_for_writing = false;
1806  opened_for_reading = false;
1807  _opened_by_create = false;
1808 }
void message(std::string_view msg)
Prints the message defined in msg.
processor_id_type processor_id() const

◆ comm()

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

Definition at line 97 of file parallel_object.h.

References libMesh::ParallelObject::_communicator.

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

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

◆ 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 1793 of file nemesis_io_helper.C.

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

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

◆ 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 1110 of file nemesis_io_helper.C.

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

1111 {
1112  // For the nodes, these are the number of entries in the sets in proc_nodes_touched_intersections
1113  // map computed above. Note: this map does not contain self-intersections so we can loop over it
1114  // directly.
1115  this->node_cmap_node_cnts.clear(); // Make sure we don't have any leftover information...
1116  this->node_cmap_ids.clear(); // Make sure we don't have any leftover information...
1117  this->node_cmap_node_cnts.resize(this->num_node_cmaps);
1118  this->node_cmap_ids.resize(this->num_node_cmaps);
1119 
1120  {
1121  unsigned cnt=0; // Index into the vector
1123  it = this->proc_nodes_touched_intersections.begin(),
1124  end = this->proc_nodes_touched_intersections.end();
1125 
1126  for (; it != end; ++it)
1127  {
1128  this->node_cmap_ids[cnt] = it->first; // The ID of the proc we communicate with
1129  this->node_cmap_node_cnts[cnt] = cast_int<int>(it->second.size()); // The number of nodes we communicate
1130  cnt++; // increment vector index!
1131  }
1132  }
1133 
1134  // Print the packed vectors we just filled
1135  if (verbose)
1136  {
1137  libMesh::out << "[" << this->processor_id() << "] node_cmap_node_cnts = ";
1138  for (const auto & node_cnt : node_cmap_node_cnts)
1139  libMesh::out << node_cnt << ", ";
1140  libMesh::out << std::endl;
1141 
1142  libMesh::out << "[" << this->processor_id() << "] node_cmap_ids = ";
1143  for (const auto & node_id : node_cmap_ids)
1144  libMesh::out << node_id << ", ";
1145  libMesh::out << std::endl;
1146  }
1147 
1148  // For the elements, we have not yet computed all this information..
1149  this->elem_cmap_elem_cnts.clear(); // Make sure we don't have any leftover information...
1150  this->elem_cmap_ids.clear(); // Make sure we don't have any leftover information...
1151  this->elem_cmap_elem_cnts.resize(this->num_elem_cmaps);
1152  this->elem_cmap_ids.resize(this->num_elem_cmaps);
1153 
1154  // Pack the elem_cmap_ids and elem_cmap_elem_cnts vectors
1155  {
1156  unsigned cnt=0; // Index into the vectors we're filling
1158  it = this->proc_border_elem_sets.begin(),
1159  end = this->proc_border_elem_sets.end();
1160 
1161  for (; it != end; ++it)
1162  {
1163  this->elem_cmap_ids[cnt] = it->first; // The ID of the proc we communicate with
1164  this->elem_cmap_elem_cnts[cnt] = cast_int<int>(it->second.size()); // The number of elems we communicate to/from that proc
1165  cnt++; // increment vector index!
1166  }
1167  }
1168 
1169  // Print the packed vectors we just filled
1170  if (verbose)
1171  {
1172  libMesh::out << "[" << this->processor_id() << "] elem_cmap_elem_cnts = ";
1173  for (const auto & elem_cnt : elem_cmap_elem_cnts)
1174  libMesh::out << elem_cnt << ", ";
1175  libMesh::out << std::endl;
1176 
1177  libMesh::out << "[" << this->processor_id() << "] elem_cmap_ids = ";
1178  for (const auto & elem_id : elem_cmap_ids)
1179  libMesh::out << elem_id << ", ";
1180  libMesh::out << std::endl;
1181  }
1182 }
std::vector< int > node_cmap_ids
Vectors for storing the communication map parameters.
int num_node_cmaps
The number of nodal communication maps for this processor.
std::map< unsigned, std::set< unsigned > >::iterator proc_nodes_touched_iterator
Typedef for an iterator into the data structure above.
std::vector< int > elem_cmap_elem_cnts
int num_elem_cmaps
The number of elemental communication maps for this processor.
OStreamProxy out
std::vector< int > elem_cmap_ids
std::vector< int > node_cmap_node_cnts
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).
processor_id_type processor_id() const
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.

◆ 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 958 of file nemesis_io_helper.C.

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

959 {
960  // Make sure there is no leftover information
961  this->elem_cmap_elem_ids.clear();
962  this->elem_cmap_side_ids.clear();
963  this->elem_cmap_proc_ids.clear();
964 
965  // Allocate enough space for all our element maps
966  this->elem_cmap_elem_ids.resize(this->num_elem_cmaps);
967  this->elem_cmap_side_ids.resize(this->num_elem_cmaps);
968  this->elem_cmap_proc_ids.resize(this->num_elem_cmaps);
969  {
970  unsigned cnt=0; // Index into vectors
972  it = this->proc_border_elem_sets.begin(),
973  end = this->proc_border_elem_sets.end();
974 
975  for (; it != end; ++it)
976  {
977  // Make sure the current elem_cmap_id matches the index in our map of node intersections
978  libmesh_assert_equal_to (static_cast<unsigned>(this->elem_cmap_ids[cnt]), it->first);
979 
980  // Get reference to the set of IDs to be packed into the vector
981  std::set<std::pair<unsigned,unsigned>> & elem_set = it->second;
982 
983  // Resize the vectors to receive their payload
984  this->elem_cmap_elem_ids[cnt].resize(elem_set.size());
985  this->elem_cmap_side_ids[cnt].resize(elem_set.size());
986  this->elem_cmap_proc_ids[cnt].resize(elem_set.size());
987 
988  std::set<std::pair<unsigned,unsigned>>::iterator elem_set_iter = elem_set.begin();
989 
990  // Pack the vectors with elem IDs, side IDs, and processor IDs.
991  for (std::size_t j=0, eceis=this->elem_cmap_elem_ids[cnt].size(); j<eceis; ++j, ++elem_set_iter)
992  {
993  this->elem_cmap_elem_ids[cnt][j] =
994  libmesh_map_find(libmesh_elem_num_to_exodus, elem_set_iter->first);
995  this->elem_cmap_side_ids[cnt][j] = elem_set_iter->second; // Side ID, this has already been converted above
996  this->elem_cmap_proc_ids[cnt][j] = it->first; // All have the same processor ID
997  }
998 
999  // increment vector index to go to next processor
1000  cnt++;
1001  }
1002  } // end scope for packing
1003 }
std::vector< std::vector< int > > elem_cmap_side_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_proc_ids
std::map< dof_id_type, dof_id_type > libmesh_elem_num_to_exodus
int num_elem_cmaps
The number of elemental communication maps for this processor.
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.

◆ 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 933 of file nemesis_io_helper.C.

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

Referenced by initialize().

934 {
935  // Make sure we don't have any leftover info
936  this->elem_mapi.clear();
937  this->elem_mapb.clear();
938 
939  // Copy set contents into vectors
940  this->elem_mapi.resize(this->internal_elem_ids.size());
941  this->elem_mapb.resize(this->border_elem_ids.size());
942 
943  {
944  unsigned cnt = 0;
945  for (const auto & id : this->internal_elem_ids)
946  this->elem_mapi[cnt++] = libmesh_map_find(libmesh_elem_num_to_exodus, id);
947  }
948 
949  {
950  unsigned cnt = 0;
951  for (const auto & id : this->border_elem_ids)
952  this->elem_mapb[cnt++] = libmesh_map_find(libmesh_elem_num_to_exodus, id);
953  }
954 }
std::set< unsigned > border_elem_ids
A set of border elem IDs for this processor.
std::map< dof_id_type, dof_id_type > libmesh_elem_num_to_exodus
std::vector< int > elem_mapb
Vector which stores border element IDs.
std::vector< int > elem_mapi
Vector which stores internal element IDs.
std::set< unsigned > internal_elem_ids
A set of internal elem IDs for this processor.

◆ 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 1188 of file nemesis_io_helper.C.

References border_elem_ids, border_node_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().

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

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

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

1039 {
1040  // Make sure there's no left-over information
1041  this->node_cmap_node_ids.clear();
1042  this->node_cmap_proc_ids.clear();
1043 
1044  libmesh_assert_less_equal
1045  (this->proc_nodes_touched_intersections.size(),
1046  std::size_t(this->num_node_cmaps));
1047 
1048  // Allocate enough space for all our node maps
1049  this->node_cmap_node_ids.resize(this->num_node_cmaps);
1050  this->node_cmap_proc_ids.resize(this->num_node_cmaps);
1051  {
1052  unsigned cnt=0; // Index into vectors
1054  it = this->proc_nodes_touched_intersections.begin(),
1055  end = this->proc_nodes_touched_intersections.end();
1056 
1057  for (; it != end; ++it)
1058  {
1059  // Make sure the current node_cmap_id matches the index in our map of node intersections
1060  libmesh_assert_equal_to (static_cast<unsigned>(this->node_cmap_ids[cnt]), it->first);
1061 
1062  // Get reference to the set of IDs to be packed into the vector.
1063  std::set<unsigned> & node_set = it->second;
1064 
1065  // Resize the vectors to receive their payload
1066  this->node_cmap_node_ids[cnt].resize(node_set.size());
1067  this->node_cmap_proc_ids[cnt].resize(node_set.size());
1068 
1069  std::set<unsigned>::iterator node_set_iter = node_set.begin();
1070 
1071  // Pack the vectors with node IDs and processor IDs.
1072  for (std::size_t j=0, nceis=this->node_cmap_node_ids[cnt].size(); j<nceis; ++j, ++node_set_iter)
1073  {
1074  this->node_cmap_node_ids[cnt][j] =
1075  libmesh_map_find(libmesh_node_num_to_exodus, *node_set_iter);
1076  this->node_cmap_proc_ids[cnt][j] = it->first;
1077  }
1078 
1079  // increment vector index to go to next processor
1080  cnt++;
1081  }
1082  } // end scope for packing
1083 
1084  // Print out the vectors we just packed
1085  if (verbose)
1086  {
1087  for (auto i : index_range(this->node_cmap_node_ids))
1088  {
1089  libMesh::out << "[" << this->processor_id() << "] nodes communicated to proc "
1090  << this->node_cmap_ids[i]
1091  << " = ";
1092  for (const auto & node_id : this->node_cmap_node_ids[i])
1093  libMesh::out << node_id << " ";
1094  libMesh::out << std::endl;
1095  }
1096 
1097  for (const auto & id_vec : this->node_cmap_node_ids)
1098  {
1099  libMesh::out << "[" << this->processor_id() << "] processor ID node communicated to = ";
1100  for (const auto & proc_id : id_vec)
1101  libMesh::out << proc_id << " ";
1102  libMesh::out << std::endl;
1103  }
1104  }
1105 }
std::vector< int > node_cmap_ids
Vectors for storing the communication map parameters.
int num_node_cmaps
The number of nodal communication maps for this processor.
std::vector< std::vector< int > > node_cmap_proc_ids
std::map< dof_id_type, dof_id_type > libmesh_node_num_to_exodus
std::map< unsigned, std::set< unsigned > >::iterator proc_nodes_touched_iterator
Typedef for an iterator into the data structure above.
std::unordered_set< const Node * > & node_set
Definition: mesh_tools.C:2276
OStreamProxy out
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::vector< std::vector< int > > node_cmap_node_ids
2 vectors of vectors for storing the node communication IDs for this processor.
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:117

◆ 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 1009 of file nemesis_io_helper.C.

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

1010 {
1011  // Make sure we don't have any leftover information
1012  this->node_mapi.clear();
1013  this->node_mapb.clear();
1014  this->node_mape.clear();
1015 
1016  // Make sure there's enough space to hold all our node IDs
1017  this->node_mapi.resize(this->internal_node_ids.size());
1018  this->node_mapb.resize(this->border_node_ids.size());
1019 
1020  // Copy set contents into vectors
1021  {
1022  unsigned cnt = 0;
1023  for (const auto & id : this->internal_node_ids)
1024  this->node_mapi[cnt++] = libmesh_map_find(libmesh_node_num_to_exodus, id);
1025  }
1026 
1027  {
1028  unsigned cnt=0;
1029  for (const auto & id : this->border_node_ids)
1030  this->node_mapb[cnt++] = libmesh_map_find(libmesh_node_num_to_exodus, id);
1031  }
1032 }
std::vector< int > node_mape
Vector which stores external node IDs.
std::map< dof_id_type, dof_id_type > libmesh_node_num_to_exodus
std::set< unsigned > internal_node_ids
A set of internal node IDs for this processor.
std::vector< int > node_mapi
Vector which stores internal node IDs.
std::set< unsigned > border_node_ids
The set which will eventually contain the IDs of "border nodes".
std::vector< int > node_mapb
Vector which stores border node IDs.

◆ 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 1530 of file nemesis_io_helper.C.

References TIMPI::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(), TIMPI::Communicator::sum(), and libMesh::ExodusII_IO_Helper::verbose.

Referenced by initialize().

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

◆ 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 1419 of file nemesis_io_helper.C.

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::ParallelObject::processor_id(), libMesh::DofObject::processor_id(), TIMPI::Communicator::set_union(), TIMPI::Communicator::sum(), and libMesh::ExodusII_IO_Helper::verbose.

Referenced by initialize().

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

◆ 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 1326 of file nemesis_io_helper.C.

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::ParallelObject::processor_id(), libMesh::DofObject::processor_id(), TIMPI::Communicator::set_union(), TIMPI::Communicator::sum(), and libMesh::ExodusII_IO_Helper::verbose.

Referenced by initialize().

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

◆ 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 2770 of file nemesis_io_helper.C.

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

2771 {
2772  // Build a filename for this processor. This code is cut-n-pasted from the read function
2773  // and should probably be put into a separate function...
2774  std::ostringstream file_oss;
2775 
2776  // We have to be a little careful here: Nemesis left pads its file
2777  // numbers based on the number of processors, so for example on 10
2778  // processors, we'd have:
2779  // mesh.e.10.00
2780  // mesh.e.10.01
2781  // mesh.e.10.02
2782  // ...
2783  // mesh.e.10.09
2784 
2785  // And on 100 you'd have:
2786  // mesh.e.100.000
2787  // mesh.e.100.001
2788  // ...
2789  // mesh.e.128.099
2790 
2791  // Find the length of the highest processor ID
2792  file_oss << (this->n_processors());
2793  unsigned int field_width = cast_int<unsigned int>(file_oss.str().size());
2794 
2795  if (verbose)
2796  libMesh::out << "field_width=" << field_width << std::endl;
2797 
2798  file_oss.str(""); // reset the string stream
2799  file_oss << base_filename
2800  << '.' << this->n_processors()
2801  << '.' << std::setfill('0') << std::setw(field_width) << this->processor_id();
2802 
2803  // Return the resulting string
2804  return file_oss.str();
2805 }
processor_id_type n_processors() const
OStreamProxy out
processor_id_type processor_id() const

◆ create()

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

Opens an ExodusII mesh file named filename for writing.

Definition at line 2146 of file exodusII_io_helper.C.

References 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_id, libMesh::ExodusII_IO_Helper::opened_for_writing, libMesh::out, libMesh::ParallelObject::processor_id(), libMesh::Real, and libMesh::ExodusII_IO_Helper::verbose.

2147 {
2148  // If we're processor 0, always create the file.
2149  // If we running on all procs, e.g. as one of several Nemesis files, also
2150  // call create there.
2151  if ((this->processor_id() == 0) || (!_run_only_on_proc0))
2152  {
2153  int
2154  comp_ws = 0,
2155  io_ws = 0;
2156 
2157  if (_single_precision)
2158  {
2159  comp_ws = cast_int<int>(sizeof(float));
2160  io_ws = cast_int<int>(sizeof(float));
2161  }
2162  // Fall back on double precision when necessary since ExodusII
2163  // doesn't seem to support long double
2164  else
2165  {
2166  comp_ws = cast_int<int>
2167  (std::min(sizeof(Real), sizeof(double)));
2168  io_ws = cast_int<int>
2169  (std::min(sizeof(Real), sizeof(double)));
2170  }
2171 
2172  // By default we just open the Exodus file in "EX_CLOBBER" mode,
2173  // which, according to "ncdump -k", writes the file in "64-bit
2174  // offset" mode, which is a NETCDF3 file format.
2175  int mode = EX_CLOBBER;
2176 
2177  // If HDF5 is available, by default we will write Exodus files
2178  // in a more modern NETCDF4-compatible format. For this file
2179  // type, "ncdump -k" will report "netCDF-4".
2180 #ifdef LIBMESH_HAVE_HDF5
2181  if (this->_write_hdf5)
2182  {
2183  mode |= EX_NETCDF4;
2184  mode |= EX_NOCLASSIC;
2185  }
2186 #endif
2187 
2188  {
2189  FPEDisabler disable_fpes;
2190  ex_id = exII::ex_create(filename.c_str(), mode, &comp_ws, &io_ws);
2191  }
2192 
2193  EX_CHECK_ERR(ex_id, "Error creating ExodusII/Nemesis mesh file.");
2194 
2195  if (verbose)
2196  libMesh::out << "File created successfully." << std::endl;
2197  }
2198 
2199  opened_for_writing = true;
2200  _opened_by_create = true;
2201  current_filename = filename;
2202 }
The FPEDisabler class puts Floating-Point Exception (FPE) trapping on hold during its lifetime...
Definition: fpe_disabler.h:49
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
OStreamProxy out
processor_id_type processor_id() const

◆ 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 1295 of file exodusII_io_helper.h.

References libMesh::ExodusII_IO_Helper::_add_sides.

1296 {
1297  return _add_sides;
1298 }
bool _add_sides
Set to true iff we want to write separate "side" elements too.

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

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

1092 {
1093  libmesh_assert_less (index, block_ids.size());
1094 
1095  return block_ids[index];
1096 }

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

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

1101 {
1102  libmesh_assert_less (index, block_ids.size());
1103 
1104  return id_to_block_names[block_ids[index]];
1105 }
std::map< int, std::string > id_to_block_names

◆ get_cmap_params()

void libMesh::Nemesis_IO_Helper::get_cmap_params ( )

Definition at line 369 of file nemesis_io_helper.C.

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.

370 {
375 
377  Nemesis::ne_get_cmap_params(ex_id,
378  node_cmap_ids.empty() ? nullptr : node_cmap_ids.data(),
379  node_cmap_node_cnts.empty() ? nullptr : node_cmap_node_cnts.data(),
380  elem_cmap_ids.empty() ? nullptr : elem_cmap_ids.data(),
381  elem_cmap_elem_cnts.empty() ? nullptr : elem_cmap_elem_cnts.data(),
382  this->processor_id());
383  EX_CHECK_ERR(nemesis_err_flag, "Error reading cmap parameters!");
384 
385 
386  if (verbose)
387  {
388  libMesh::out << "[" << this->processor_id() << "] ";
389  for (auto i : index_range(node_cmap_ids))
390  libMesh::out << "node_cmap_ids[" << i << "]=" << node_cmap_ids[i] << " ";
391  libMesh::out << std::endl;
392 
393  libMesh::out << "[" << this->processor_id() << "] ";
394  for (auto i : index_range(node_cmap_node_cnts))
395  libMesh::out << "node_cmap_node_cnts[" << i << "]=" << node_cmap_node_cnts[i] << " ";
396  libMesh::out << std::endl;
397 
398  libMesh::out << "[" << this->processor_id() << "] ";
399  for (auto i : index_range(elem_cmap_ids))
400  libMesh::out << "elem_cmap_ids[" << i << "]=" << elem_cmap_ids[i] << " ";
401  libMesh::out << std::endl;
402 
403  libMesh::out << "[" << this->processor_id() << "] ";
404  for (auto i : index_range(elem_cmap_elem_cnts))
405  libMesh::out << "elem_cmap_elem_cnts[" << i << "]=" << elem_cmap_elem_cnts[i] << " ";
406  libMesh::out << std::endl;
407  }
408 }
std::vector< int > node_cmap_ids
Vectors for storing the communication map parameters.
int nemesis_err_flag
Member data.
int num_node_cmaps
The number of nodal communication maps for this processor.
std::vector< int > elem_cmap_elem_cnts
int num_elem_cmaps
The number of elemental communication maps for this processor.
OStreamProxy out
std::vector< int > elem_cmap_ids
std::vector< int > node_cmap_node_cnts
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:117

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

References libMesh::Quality::name().

4701 {
4702  std::vector<std::string> complex_names;
4703 
4704  // This will loop over all names and create new "complex" names
4705  // (i.e. names that start with r_, i_ or a_)
4706  for (const auto & name : names)
4707  {
4708  complex_names.push_back("r_" + name);
4709  complex_names.push_back("i_" + name);
4710  if (write_complex_abs)
4711  complex_names.push_back("a_" + name);
4712  }
4713 
4714  return complex_names;
4715 }
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
Definition: elem_quality.C:42

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

4747 {
4748  // Eventual return value
4749  std::map<subdomain_id_type, std::vector<std::string>> ret;
4750 
4751  unsigned int num_complex_outputs = write_complex_abs ? 3 : 2;
4752 
4753  for (const auto & pr : subdomain_to_var_names)
4754  {
4755  // Initialize entry for current subdomain
4756  auto & vec = ret[pr.first];
4757 
4758  // Get list of non-complex variable names active on this subdomain.
4759  const auto & varnames = pr.second;
4760 
4761  // Allocate space for the complex-valued entries
4762  vec.reserve(num_complex_outputs * varnames.size());
4763 
4764  // For each varname in the input map, write three variable names
4765  // to the output formed by prepending "r_", "i_", and "a_",
4766  // respectively.
4767  for (const auto & varname : varnames)
4768  {
4769  vec.push_back("r_" + varname);
4770  vec.push_back("i_" + varname);
4771  if (write_complex_abs)
4772  vec.push_back("a_" + varname);
4773  }
4774  }
4775  return ret;
4776 }

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

4724 {
4725  std::vector<std::set<subdomain_id_type>> complex_vars_active_subdomains;
4726 
4727  for (auto & s : vars_active_subdomains)
4728  {
4729  // Push back the same data enough times for the real, imag, (and
4730  // possibly modulus) for the complex-valued solution.
4731  complex_vars_active_subdomains.push_back(s);
4732  complex_vars_active_subdomains.push_back(s);
4733  if (write_complex_abs)
4734  complex_vars_active_subdomains.push_back(s);
4735  }
4736 
4737  return complex_vars_active_subdomains;
4738 }

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

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

550 {
551  // Do only upper-case comparisons
552  std::transform(type_str.begin(), type_str.end(), type_str.begin(), ::toupper);
553  return get_conversion (libmesh_map_find(element_equivalence_map, type_str));
554 }
const ExodusII_IO_Helper::Conversion & get_conversion(const ElemType type) const
std::map< std::string, ElemType > element_equivalence_map
Defines equivalence classes of Exodus element types that map to libmesh ElemTypes.

◆ get_eb_info_global()

void libMesh::Nemesis_IO_Helper::get_eb_info_global ( )

Definition at line 223 of file nemesis_io_helper.C.

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.

224 {
227 
228  if (num_elem_blks_global > 0)
229  {
231  Nemesis::ne_get_eb_info_global(ex_id,
232  global_elem_blk_ids.data(),
233  global_elem_blk_cnts.data());
234  EX_CHECK_ERR(nemesis_err_flag, "Error reading global element block info!");
235  }
236 
237  if (verbose)
238  {
239  libMesh::out << "[" << this->processor_id() << "] " << "Global Element Block IDs and Counts:" << std::endl;
240  for (auto bn : index_range(global_elem_blk_ids))
241  {
242  libMesh::out << " [" << this->processor_id() << "] "
243  << "global_elem_blk_ids[" << bn << "]=" << global_elem_blk_ids[bn]
244  << ", global_elem_blk_cnts[" << bn << "]=" << global_elem_blk_cnts[bn]
245  << std::endl;
246  }
247  }
248 }
int nemesis_err_flag
Member data.
std::vector< int > global_elem_blk_ids
Read the global element block IDs and counts.
OStreamProxy out
processor_id_type processor_id() const
std::vector< int > global_elem_blk_cnts
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:117

◆ get_elem_cmap()

void libMesh::Nemesis_IO_Helper::get_elem_cmap ( )

Definition at line 454 of file nemesis_io_helper.C.

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.

455 {
459 
460  for (auto i : index_range(elem_cmap_elem_ids))
461  {
465 
466  if (elem_cmap_elem_cnts[i] > 0)
467  {
469  Nemesis::ne_get_elem_cmap(ex_id,
470  elem_cmap_ids[i],
471  elem_cmap_elem_ids[i].data(),
472  elem_cmap_side_ids[i].data(),
473  elem_cmap_proc_ids[i].data(),
474  this->processor_id());
475  EX_CHECK_ERR(nemesis_err_flag, "Error reading elem cmap elem, side, and processor ids!");
476  }
477 
478  if (verbose)
479  {
480  libMesh::out << "[" << this->processor_id() << "] elem_cmap_elem_ids[" << i << "]=";
481  for (const auto & dof : elem_cmap_elem_ids[i])
482  libMesh::out << dof << " ";
483  libMesh::out << std::endl;
484 
485  // These must be the (local) side IDs (in the ExodusII face numbering scheme)
486  // of the sides shared across processors.
487  libMesh::out << "[" << this->processor_id() << "] elem_cmap_side_ids[" << i << "]=";
488  for (const auto & dof : elem_cmap_side_ids[i])
489  libMesh::out << dof << " ";
490  libMesh::out << std::endl;
491 
492  // This is basically a vector, all entries of which are = elem_cmap_ids[i]
493  // Not sure if it's always guaranteed to be that or what...
494  libMesh::out << "[" << this->processor_id() << "] elem_cmap_proc_ids[" << i << "]=";
495  for (const auto & dof : elem_cmap_proc_ids[i])
496  libMesh::out << dof << " ";
497  libMesh::out << std::endl;
498  }
499  }
500 }
int nemesis_err_flag
Member data.
std::vector< std::vector< int > > elem_cmap_side_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_proc_ids
std::vector< int > elem_cmap_elem_cnts
int num_elem_cmaps
The number of elemental communication maps for this processor.
OStreamProxy out
std::vector< int > elem_cmap_ids
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:117

◆ get_elem_map()

void libMesh::Nemesis_IO_Helper::get_elem_map ( )

Definition at line 301 of file nemesis_io_helper.C.

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.

302 {
304  elem_mapb.resize(num_border_elems);
305 
307  Nemesis::ne_get_elem_map(ex_id,
308  elem_mapi.empty() ? nullptr : elem_mapi.data(),
309  elem_mapb.empty() ? nullptr : elem_mapb.data(),
310  this->processor_id()
311  );
312  EX_CHECK_ERR(nemesis_err_flag, "Error reading element maps!");
313 
314 
315  if (verbose)
316  {
317  libMesh::out << "[" << this->processor_id() << "] elem_mapi[i] = ";
318  for (auto i : make_range(num_internal_elems-1))
319  libMesh::out << elem_mapi[i] << ", ";
320  libMesh::out << "... " << elem_mapi.back() << std::endl;
321 
322  libMesh::out << "[" << this->processor_id() << "] elem_mapb[i] = ";
323  for (auto i : make_range(std::min(10, num_border_elems-1)))
324  libMesh::out << elem_mapb[i] << ", ";
325  libMesh::out << "... " << elem_mapb.back() << std::endl;
326  }
327 }
int nemesis_err_flag
Member data.
int num_internal_elems
The number of internal FEM elements.
OStreamProxy out
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:140
std::vector< int > elem_mapb
Vector which stores border element IDs.
processor_id_type processor_id() const
std::vector< int > elem_mapi
Vector which stores internal element IDs.
int num_border_elems
The number of border FEM elements.

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

References libMesh::ExodusII_IO_Helper::elem_type.

557 {
558  return elem_type.data();
559 }

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

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.

4144 {
4145  // Clear existing data, we are going to build these data structures from scratch
4146  elemset_array_indices.clear();
4147 
4148  // Read the elemset data.
4149  //
4150  // Note: we assume that the functions
4151  // 1.) this->read_elemset_info() and
4152  // 2.) this->read_elemset()
4153  // have already been called, so that we already know e.g. how
4154  // many elems are in each set, their ids, etc.
4155  int offset=0;
4156  for (int es=0; es<num_elem_sets; ++es)
4157  {
4158  offset += (es > 0 ? num_elems_per_set[es-1] : 0);
4159 
4160  // Note: we don't actually call exII::ex_get_var() here because
4161  // we don't need the values. We only need the indices into that vector
4162  // for each (elem_id, elemset_id) tuple.
4163  for (int i=0; i<num_elems_per_set[es]; ++i)
4164  {
4165  dof_id_type exodus_elem_id = elemset_list[i + offset];
4166 
4167  // FIXME: We should use exodus_elem_num_to_libmesh for this,
4168  // but it apparently is never set up, so just
4169  // subtract 1 from the Exodus elem id.
4170  dof_id_type converted_elem_id = exodus_elem_id - 1;
4171 
4172  // Make key based on the elem and set ids
4173  // Make a NodeBCTuple key from the converted information.
4174  auto key = std::make_pair(converted_elem_id,
4175  static_cast<elemset_id_type>(elemset_ids[es]));
4176 
4177  // Store the array index of this (node, b_id) tuple
4178  elemset_array_indices.emplace(key, cast_int<unsigned int>(i));
4179  } // end for (i)
4180  } // end for (es)
4181 }
std::vector< int > num_elems_per_set
uint8_t dof_id_type
Definition: id_types.h:67

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

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

315 {
316  return EX_API_VERS_NODOT;
317 }

◆ 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 132 of file nemesis_io_helper.C.

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.

133 {
135  Nemesis::ne_get_init_global(ex_id,
141  EX_CHECK_ERR(nemesis_err_flag, "Error reading initial global data!");
142 
143  if (verbose)
144  {
145  libMesh::out << "[" << this->processor_id() << "] " << "num_nodes_global=" << num_nodes_global << std::endl;
146  libMesh::out << "[" << this->processor_id() << "] " << "num_elems_global=" << num_elems_global << std::endl;
147  libMesh::out << "[" << this->processor_id() << "] " << "num_elem_blks_global=" << num_elem_blks_global << std::endl;
148  libMesh::out << "[" << this->processor_id() << "] " << "num_node_sets_global=" << num_node_sets_global << std::endl;
149  libMesh::out << "[" << this->processor_id() << "] " << "num_side_sets_global=" << num_side_sets_global << std::endl;
150  }
151 }
int nemesis_err_flag
Member data.
int num_nodes_global
Global initial information.
OStreamProxy out
processor_id_type processor_id() const

◆ get_init_info()

void libMesh::Nemesis_IO_Helper::get_init_info ( )

Definition at line 252 of file nemesis_io_helper.C.

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.

253 {
255  Nemesis::ne_get_init_info(ex_id,
256  &num_proc,
258  &ftype);
259  EX_CHECK_ERR(nemesis_err_flag, "Error reading initial info!");
260 
261  if (verbose)
262  {
263  libMesh::out << "[" << this->processor_id() << "] " << "num_proc=" << num_proc << std::endl;
264  libMesh::out << "[" << this->processor_id() << "] " << "num_proc_in_file=" << num_proc_in_file << std::endl;
265  libMesh::out << "[" << this->processor_id() << "] " << "ftype=" << ftype << std::endl;
266  }
267 }
char ftype
The type of file to be written.
int nemesis_err_flag
Member data.
int num_proc
The number of processors for which the NEMESIS I file was created.
OStreamProxy out
int num_proc_in_file
The number of processors for which the NEMESIS I file stores information.
processor_id_type processor_id() const

◆ get_loadbal_param()

void libMesh::Nemesis_IO_Helper::get_loadbal_param ( )

Definition at line 271 of file nemesis_io_helper.C.

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.

272 {
274  Nemesis::ne_get_loadbal_param(ex_id,
282  this->processor_id() // The ID of the processor for which info is to be read
283  );
284  EX_CHECK_ERR(nemesis_err_flag, "Error reading load balance parameters!");
285 
286 
287  if (verbose)
288  {
289  libMesh::out << "[" << this->processor_id() << "] " << "num_internal_nodes=" << num_internal_nodes << std::endl;
290  libMesh::out << "[" << this->processor_id() << "] " << "num_border_nodes=" << num_border_nodes << std::endl;
291  libMesh::out << "[" << this->processor_id() << "] " << "num_external_nodes=" << num_external_nodes << std::endl;
292  libMesh::out << "[" << this->processor_id() << "] " << "num_internal_elems=" << num_internal_elems << std::endl;
293  libMesh::out << "[" << this->processor_id() << "] " << "num_border_elems=" << num_border_elems << std::endl;
294  libMesh::out << "[" << this->processor_id() << "] " << "num_node_cmaps=" << num_node_cmaps << std::endl;
295  libMesh::out << "[" << this->processor_id() << "] " << "num_elem_cmaps=" << num_elem_cmaps << std::endl;
296  }
297 }
int num_external_nodes
The number of FEM nodes that reside on another processor but whose element partially resides on the c...
int nemesis_err_flag
Member data.
int num_node_cmaps
The number of nodal communication maps for this processor.
int num_internal_elems
The number of internal FEM elements.
int num_elem_cmaps
The number of elemental communication maps for this processor.
OStreamProxy out
processor_id_type processor_id() const
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_internal_nodes
To be used with the Nemesis::ne_get_loadbal_param() routine.
int num_border_elems
The number of border FEM elements.

◆ get_node_cmap()

void libMesh::Nemesis_IO_Helper::get_node_cmap ( )

Definition at line 412 of file nemesis_io_helper.C.

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.

413 {
416 
417  for (auto i : index_range(node_cmap_node_ids))
418  {
421 
422  // Don't call ne_get_node_cmap() if there is nothing there to
423  // get, Nemesis throws an error in this case.
424  if (node_cmap_node_cnts[i] > 0)
425  {
427  Nemesis::ne_get_node_cmap(ex_id,
428  node_cmap_ids[i],
429  node_cmap_node_ids[i].data(),
430  node_cmap_proc_ids[i].data(),
431  this->processor_id());
432  EX_CHECK_ERR(nemesis_err_flag, "Error reading node cmap node and processor ids!");
433  }
434 
435  if (verbose)
436  {
437  libMesh::out << "[" << this->processor_id() << "] node_cmap_node_ids[" << i << "]=";
438  for (const auto & dof : node_cmap_node_ids[i])
439  libMesh::out << dof << " ";
440  libMesh::out << std::endl;
441 
442  // This is basically a vector, all entries of which are = node_cmap_ids[i]
443  // Not sure if it's always guaranteed to be that or what...
444  libMesh::out << "[" << this->processor_id() << "] node_cmap_proc_ids[" << i << "]=";
445  for (const auto & dof : node_cmap_proc_ids[i])
446  libMesh::out << dof << " ";
447  libMesh::out << std::endl;
448  }
449  }
450 }
std::vector< int > node_cmap_ids
Vectors for storing the communication map parameters.
int nemesis_err_flag
Member data.
int num_node_cmaps
The number of nodal communication maps for this processor.
std::vector< std::vector< int > > node_cmap_proc_ids
OStreamProxy out
std::vector< int > node_cmap_node_cnts
std::vector< std::vector< int > > node_cmap_node_ids
2 vectors of vectors for storing the node communication IDs for this processor.
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:117

◆ get_node_map()

void libMesh::Nemesis_IO_Helper::get_node_map ( )

Definition at line 332 of file nemesis_io_helper.C.

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.

333 {
335  node_mapb.resize(num_border_nodes);
337 
339  Nemesis::ne_get_node_map(ex_id,
340  node_mapi.empty() ? nullptr : node_mapi.data(),
341  node_mapb.empty() ? nullptr : node_mapb.data(),
342  node_mape.empty() ? nullptr : node_mape.data(),
343  this->processor_id()
344  );
345  EX_CHECK_ERR(nemesis_err_flag, "Error reading node maps!");
346 
347  if (verbose)
348  {
349  // Remark: The Exodus/Nemesis node numbering is always (?) 1-based! This means the first interior node id will
350  // always be == 1.
351  libMesh::out << "[" << this->processor_id() << "] " << "first interior node id=" << node_mapi[0] << std::endl;
352  libMesh::out << "[" << this->processor_id() << "] " << "last interior node id=" << node_mapi.back() << std::endl;
353 
354  libMesh::out << "[" << this->processor_id() << "] " << "first boundary node id=" << node_mapb[0] << std::endl;
355  libMesh::out << "[" << this->processor_id() << "] " << "last boundary node id=" << node_mapb.back() << std::endl;
356 
357  // The number of external nodes is sometimes zero, don't try to access
358  // node_mape.back() in this case!
359  if (num_external_nodes > 0)
360  {
361  libMesh::out << "[" << this->processor_id() << "] " << "first external node id=" << node_mape[0] << std::endl;
362  libMesh::out << "[" << this->processor_id() << "] " << "last external node id=" << node_mape.back() << std::endl;
363  }
364  }
365 }
int num_external_nodes
The number of FEM nodes that reside on another processor but whose element partially resides on the c...
int nemesis_err_flag
Member data.
std::vector< int > node_mape
Vector which stores external node IDs.
std::vector< int > node_mapi
Vector which stores internal node IDs.
OStreamProxy out
std::vector< int > node_mapb
Vector which stores border node IDs.
processor_id_type processor_id() const
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_internal_nodes
To be used with the Nemesis::ne_get_loadbal_param() routine.

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

References libMesh::ExodusII_IO_Helper::nodeset_ids.

1128 {
1129  libmesh_assert_less (index, nodeset_ids.size());
1130 
1131  return nodeset_ids[index];
1132 }

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

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

1137 {
1138  libmesh_assert_less (index, nodeset_ids.size());
1139 
1140  return id_to_ns_names[nodeset_ids[index]];
1141 }
std::map< int, std::string > id_to_ns_names

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

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.

4286 {
4287  // Clear existing data, we are going to build these data structures from scratch
4288  bc_array_indices.clear();
4289 
4290  // Read the nodeset data.
4291  //
4292  // Note: we assume that the functions
4293  // 1.) this->read_nodeset_info() and
4294  // 2.) this->read_all_nodesets()
4295  // have already been called, so that we already know e.g. how
4296  // many nodes are in each set, their ids, etc.
4297  int offset=0;
4298  for (int ns=0; ns<num_node_sets; ++ns)
4299  {
4300  offset += (ns > 0 ? num_nodes_per_set[ns-1] : 0);
4301  // Note: we don't actually call exII::ex_get_var() here because
4302  // we don't need the values. We only need the indices into that vector
4303  // for each (node_id, boundary_id) tuple.
4304  for (int i=0; i<num_nodes_per_set[ns]; ++i)
4305  {
4306  // The read_all_nodesets() function now reads all the node ids into the
4307  // node_sets_node_list vector, which is of length "total_nodes_in_all_sets"
4308  // The old read_nodset() function is no longer called as far as I can tell,
4309  // and should probably be removed? The "offset" that we are using only
4310  // depends on the current nodeset index and the num_nodes_per_set vector,
4311  // which gets filled in by the call to read_all_nodesets().
4312  dof_id_type exodus_node_id = node_sets_node_list[i + offset];
4313 
4314  // FIXME: We should use exodus_node_num_to_libmesh for this,
4315  // but it apparently is never set up, so just
4316  // subtract 1 from the Exodus node id.
4317  dof_id_type converted_node_id = exodus_node_id - 1;
4318 
4319  // Make a NodeBCTuple key from the converted information.
4320  BoundaryInfo::NodeBCTuple key = std::make_tuple
4321  (converted_node_id, nodeset_ids[ns]);
4322 
4323  // Store the array index of this (node, b_id) tuple
4324  bc_array_indices.emplace(key, cast_int<unsigned int>(i));
4325  } // end for (i)
4326  } // end for (ns)
4327 }
std::tuple< dof_id_type, boundary_id_type > NodeBCTuple
As above, but the library creates and fills in a vector of (node-id, bc-id) pairs and returns it to t...
std::vector< int > node_sets_node_list
std::vector< int > num_nodes_per_set
uint8_t dof_id_type
Definition: id_types.h:67

◆ get_ns_param_global()

void libMesh::Nemesis_IO_Helper::get_ns_param_global ( )

Definition at line 191 of file nemesis_io_helper.C.

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.

192 {
193  if (num_node_sets_global > 0)
194  {
198 
200  Nemesis::ne_get_ns_param_global(ex_id,
201  global_nodeset_ids.data(),
202  num_global_node_counts.data(),
204  EX_CHECK_ERR(nemesis_err_flag, "Error reading global nodeset parameters!");
205 
206  if (verbose)
207  {
208  libMesh::out << "[" << this->processor_id() << "] " << "Global Nodeset IDs, Node Counts, and DF counts:" << std::endl;
209  for (auto bn : index_range(global_nodeset_ids))
210  {
211  libMesh::out << " [" << this->processor_id() << "] "
212  << "global_nodeset_ids["<<bn<<"]=" << global_nodeset_ids[bn]
213  << ", num_global_node_counts["<<bn<<"]=" << num_global_node_counts[bn]
214  << ", num_global_node_df_counts["<<bn<<"]=" << num_global_node_df_counts[bn]
215  << std::endl;
216  }
217  }
218  }
219 }
std::vector< int > num_global_node_counts
std::vector< int > global_nodeset_ids
Containers for reading global nodeset information.
int nemesis_err_flag
Member data.
std::vector< int > num_global_node_df_counts
OStreamProxy out
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:117

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

References libMesh::ExodusII_IO_Helper::ss_ids.

1110 {
1111  libmesh_assert_less (index, ss_ids.size());
1112 
1113  return ss_ids[index];
1114 }

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

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

1119 {
1120  libmesh_assert_less (index, ss_ids.size());
1121 
1122  return id_to_ss_names[ss_ids[index]];
1123 }
std::map< int, std::string > id_to_ss_names

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

References libMesh::ExodusII_IO_Helper::elem_list, libMesh::MeshBase::elem_ptr(), libMesh::ExodusII_IO_Helper::get_conversion(), libMesh::ExodusII_IO_Helper::Conversion::get_side_map(), 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().

3760 {
3761  // Clear any existing data, we are going to build this data structure from scratch
3762  bc_array_indices.clear();
3763 
3764  // Store the sideset data array indices.
3765  //
3766  // Note: we assume that read_sideset() has already been called
3767  // for each sideset, so the required values in elem_list and
3768  // side_list are already present.
3769  int offset=0;
3770  for (int ss=0; ss<num_side_sets; ++ss)
3771  {
3772  offset += (ss > 0 ? num_sides_per_set[ss-1] : 0);
3773  for (int i=0; i<num_sides_per_set[ss]; ++i)
3774  {
3775  dof_id_type exodus_elem_id = elem_list[i + offset];
3776  unsigned int exodus_side_id = side_list[i + offset];
3777 
3778  // FIXME: We should use exodus_elem_num_to_libmesh for this,
3779  // but it apparently is never set up, so just
3780  // subtract 1 from the Exodus elem id.
3781  dof_id_type converted_elem_id = exodus_elem_id - 1;
3782 
3783  // Conversion operator for this Elem type
3784  const auto & conv = get_conversion(mesh.elem_ptr(converted_elem_id)->type());
3785 
3786  // Map from Exodus side id to libmesh side id.
3787  // Note: the mapping is defined on 0-based indices, so subtract
3788  // 1 before doing the mapping.
3789  unsigned int converted_side_id = conv.get_side_map(exodus_side_id - 1);
3790 
3791  // Make a BCTuple key from the converted information.
3792  BoundaryInfo::BCTuple key = std::make_tuple
3793  (converted_elem_id,
3794  converted_side_id,
3795  ss_ids[ss]);
3796 
3797  // Store (elem, side, b_id) tuple with corresponding array index
3798  bc_array_indices.emplace(key, cast_int<unsigned int>(i));
3799  } // end for (i)
3800  } // end for (ss)
3801 }
std::tuple< dof_id_type, unsigned short int, boundary_id_type > BCTuple
As above, but the library creates and fills in a vector of (elem-id, side-id, bc-id) triplets and ret...
std::vector< int > num_sides_per_set
MeshBase & mesh
const ExodusII_IO_Helper::Conversion & get_conversion(const ElemType type) const
virtual const Elem * elem_ptr(const dof_id_type i) const =0
virtual ElemType type() const =0
uint8_t dof_id_type
Definition: id_types.h:67

◆ 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 155 of file nemesis_io_helper.C.

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.

156 {
157  if (num_side_sets_global > 0)
158  {
161 
162  // df = "distribution factor", not really sure what that is. I don't yet have a file
163  // which has distribution factors so I guess we'll worry about it later...
165 
167  Nemesis::ne_get_ss_param_global(ex_id,
168  global_sideset_ids.data(),
169  num_global_side_counts.data(),
171  EX_CHECK_ERR(nemesis_err_flag, "Error reading global sideset parameters!");
172 
173  if (verbose)
174  {
175  libMesh::out << "[" << this->processor_id() << "] " << "Global Sideset IDs, Side Counts, and DF counts:" << std::endl;
176  for (auto bn : index_range(global_sideset_ids))
177  {
178  libMesh::out << " [" << this->processor_id() << "] "
179  << "global_sideset_ids["<<bn<<"]=" << global_sideset_ids[bn]
180  << ", num_global_side_counts["<<bn<<"]=" << num_global_side_counts[bn]
181  << ", num_global_side_df_counts["<<bn<<"]=" << num_global_side_df_counts[bn]
182  << std::endl;
183  }
184  }
185  }
186 }
std::vector< int > global_sideset_ids
Containers for reading global sideset (boundary conditions) information.
int nemesis_err_flag
Member data.
std::vector< int > num_global_side_df_counts
std::vector< int > num_global_side_counts
OStreamProxy out
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:117

◆ 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 735 of file nemesis_io_helper.C.

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::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_blks_global, 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, num_node_sets_global, num_side_sets_global, 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().

736 {
737  // Make sure that the reference passed in is really a DistributedMesh
738  // const DistributedMesh & pmesh = cast_ref<const DistributedMesh &>(mesh);
739  const MeshBase & pmesh = mesh;
740 
741  // If _write_as_dimension is nonzero, use it to set num_dim later in the Exodus file.
745  num_dim = mesh.mesh_dimension();
746  else
747  num_dim = mesh.spatial_dimension();
748 
749  // According to Nemesis documentation, first call when writing should be to
750  // ne_put_init_info(). Our reader doesn't actually call this, but we should
751  // strive to be as close to a normal nemesis file as possible...
752  this->put_init_info(this->n_processors(), 1, "p");
753 
754 
755  // Gather global "initial" information for Nemesis. This consists of
756  // three parts labeled I, II, and III below...
757 
758  //
759  // I.) Need to compute the number of global element blocks. To be consistent with
760  // Exodus, we also incorrectly associate the number of element blocks with the
761  // number of libmesh subdomains...
762  //
763  this->compute_num_global_elem_blocks(pmesh);
764 
765  //
766  // II.) Determine the global number of nodesets by communication.
767  // This code relies on BoundaryInfo storing side and node
768  // boundary IDs separately at the time they are added to the
769  // BoundaryInfo object.
770  //
771  this->compute_num_global_nodesets(pmesh);
772 
773  //
774  // III.) Need to compute the global number of sidesets by communication:
775  // This code relies on BoundaryInfo storing side and node
776  // boundary IDs separately at the time they are added to the
777  // BoundaryInfo object.
778  //
779  this->compute_num_global_sidesets(pmesh);
780 
781  // Now write the global data obtained in steps I, II, and III to the Nemesis file
782  this->put_init_global(pmesh.parallel_n_nodes(),
783  pmesh.parallel_n_elem(),
784  this->num_elem_blks_global, /* I. */
785  this->num_node_sets_global, /* II. */
786  this->num_side_sets_global /* III. */
787  );
788 
789  // Next, we'll write global element block information to the file. This was already
790  // gathered in step I. above
792  this->global_elem_blk_cnts);
793 
794 
795  // Next, write global nodeset information to the file. This was already gathered in
796  // step II. above.
797  this->num_global_node_df_counts.clear();
798  this->num_global_node_df_counts.resize(this->global_nodeset_ids.size()); // distribution factors all zero...
802 
803 
804  // Next, write global sideset information to the file. This was already gathered in
805  // step III. above.
806  this->num_global_side_df_counts.clear();
807  this->num_global_side_df_counts.resize(this->global_sideset_ids.size()); // distribution factors all zero...
811 
812 
813  // Before we go any further we need to derive consistent node and
814  // element numbering schemes for all local elems and nodes connected
815  // to local elements.
816  //
817  // Must be called *after* the local_subdomain_counts map has been constructed
818  // by the compute_num_global_elem_blocks() function!
819  this->build_element_and_node_maps(pmesh);
820 
821  // Next step is to write "load balance" parameters. Several things need to
822  // be computed first though...
823 
824  // First we'll collect IDs of border nodes.
825  this->compute_border_node_ids(pmesh);
826 
827  // Next we'll collect numbers of internal and border elements, and internal nodes.
828  // Note: "A border node does not a border element make...", that is, just because one
829  // of an element's nodes has been identified as a border node, the element is not
830  // necessarily a border element. It must have a side on the boundary between processors,
831  // i.e. have a face neighbor with a different processor id...
833 
834  // Finally we are ready to write the loadbal information to the file
836  this->num_border_nodes,
837  this->num_external_nodes,
838  this->num_internal_elems,
839  this->num_border_elems,
840  this->num_node_cmaps,
841  this->num_elem_cmaps);
842 
843 
844  // Now we need to compute the "communication map" parameters. These are basically
845  // lists of nodes and elements which need to be communicated between different processors
846  // when the mesh file is read back in.
848 
849  // Write communication map parameters to file.
850  this->put_cmap_params(this->node_cmap_ids,
851  this->node_cmap_node_cnts,
852  this->elem_cmap_ids,
853  this->elem_cmap_elem_cnts);
854 
855  // Ready the node communication maps. The node IDs which
856  // are communicated are the ones currently stored in
857  // proc_nodes_touched_intersections.
859 
860  // Write the packed node communication vectors to file.
861  this->put_node_cmap(this->node_cmap_node_ids,
862  this->node_cmap_proc_ids);
863 
864  // Ready the node maps. These have nothing to do with communication, they map
865  // the nodes to internal, border, and external nodes in the file.
866  this->compute_node_maps();
867 
868  // Call the Nemesis API to write the node maps to file.
869  this->put_node_map(this->node_mapi,
870  this->node_mapb,
871  this->node_mape);
872 
873  // Ready the element communication maps. This includes border
874  // element IDs, sides which are on the border, and the processors to which
875  // they are to be communicated...
877 
878  // Call the Nemesis API to write the packed element communication maps vectors to file
879  this->put_elem_cmap(this->elem_cmap_elem_ids,
880  this->elem_cmap_side_ids,
881  this->elem_cmap_proc_ids);
882 
883  // Ready the Nemesis element maps (internal and border) for writing to file.
884  this->compute_element_maps();
885 
886  // Call the Nemesis API to write the internal and border element IDs.
887  this->put_elem_map(this->elem_mapi,
888  this->elem_mapb);
889 
890  // Now write Exodus-specific initialization information, some of which is
891  // different when you are using Nemesis.
892  this->write_exodus_initialization_info(pmesh, title_in);
893 } // end initialize()
std::vector< int > num_global_node_counts
void compute_element_maps()
This function computes element maps (really just packs vectors) which map the elements to internal an...
std::vector< int > global_nodeset_ids
Containers for reading global nodeset information.
std::vector< int > global_sideset_ids
Containers for reading global sideset (boundary conditions) information.
void compute_num_global_nodesets(const MeshBase &pmesh)
This function uses global communication routines to determine the number of nodesets across the entir...
std::vector< int > node_cmap_ids
Vectors for storing the communication map parameters.
int num_external_nodes
The number of FEM nodes that reside on another processor but whose element partially resides on the c...
std::vector< int > node_mape
Vector which stores external node IDs.
void compute_elem_communication_maps()
This function computes element communication maps (really just packs vectors) in preparation for writ...
void compute_num_global_elem_blocks(const MeshBase &pmesh)
This function uses global communication routines to determine the number of element blocks across the...
MeshBase & mesh
int num_node_cmaps
The number of nodal communication maps for this processor.
void put_elem_map(std::vector< int > &elem_mapi, std::vector< int > &elem_mapb)
Outputs IDs of internal and border elements.
std::vector< int > num_global_node_df_counts
std::vector< std::vector< int > > elem_cmap_side_ids
std::vector< std::vector< int > > node_cmap_proc_ids
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_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 compute_border_node_ids(const MeshBase &pmesh)
This function constructs the set of border 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 fil...
std::vector< int > num_global_side_df_counts
void build_element_and_node_maps(const MeshBase &pmesh)
This function builds the libmesh -> exodus and exodus -> libmesh node and element maps...
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 ...
processor_id_type n_processors() const
std::vector< int > num_global_side_counts
std::vector< int > global_elem_blk_ids
Read the global element block IDs and counts.
std::vector< std::vector< int > > elem_cmap_elem_ids
3 vectors of vectors for storing element communication IDs for this processor.
std::vector< int > node_mapi
Vector which stores internal node IDs.
std::vector< std::vector< int > > elem_cmap_proc_ids
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_num_global_sidesets(const MeshBase &pmesh)
This function uses global communication routines to determine the number of sidesets across the entir...
int num_internal_elems
The number of internal FEM 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_node_maps()
Compute the node maps (really just pack vectors) which map the nodes to internal, border...
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_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.
std::vector< int > elem_cmap_elem_cnts
int num_elem_cmaps
The number of elemental communication maps for this processor.
std::vector< int > elem_cmap_ids
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.
std::vector< int > node_cmap_node_cnts
void write_exodus_initialization_info(const MeshBase &pmesh, const std::string &title)
This function writes exodus-specific initialization information.
void put_init_info(unsigned num_proc, unsigned num_proc_in_file, const char *ftype)
Writing functions.
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.
std::vector< int > elem_mapb
Vector which stores border element IDs.
std::vector< int > node_mapb
Vector which stores border node IDs.
std::vector< std::vector< int > > node_cmap_node_ids
2 vectors of vectors for storing the node communication IDs for this processor.
std::vector< int > global_elem_blk_cnts
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...
std::vector< int > elem_mapi
Vector which stores internal element IDs.
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_internal_nodes
To be used with the Nemesis::ne_get_loadbal_param() routine.
int num_border_elems
The number of border FEM elements.

◆ 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 2563 of file nemesis_io_helper.C.

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

2565 {
2566  // Quick return if there are no element variables to write
2567  if (names.size() == 0)
2568  return;
2569 
2570  // Quick return if we have already called this function
2572  return;
2573 
2574  // Be sure that variables in the file match what we are asking for
2575  if (num_elem_vars > 0)
2576  {
2577  this->check_existing_vars(ELEMENTAL, names, this->elem_var_names);
2578  return;
2579  }
2580 
2581  // Set the flag so we can skip this stuff on subsequent calls to
2582  // initialize_element_variables()
2583  _elem_vars_initialized = true;
2584 
2585  this->write_var_names(ELEMENTAL, names);
2586 
2587  // Create a truth table from global_elem_blk_ids and the information
2588  // in vars_active_subdomains. Create a truth table of
2589  // size global_elem_blk_ids.size() * names.size().
2590  std::vector<int> truth_tab(global_elem_blk_ids.size() * names.size());
2591  for (auto blk : index_range(global_elem_blk_ids))
2592  for (auto var : index_range(names))
2593  if (vars_active_subdomains[var].empty() ||
2594  vars_active_subdomains[var].count(cast_int<subdomain_id_type>(global_elem_blk_ids[blk])))
2595  truth_tab[names.size() * blk + var] = 1;
2596 
2597  // Write truth table to file.
2598  if (truth_tab.size())
2599  {
2600  ex_err = exII::ex_put_elem_var_tab(ex_id,
2601  cast_int<int>(global_elem_blk_ids.size()),
2602  cast_int<int>(names.size()),
2603  truth_tab.data());
2604  EX_CHECK_ERR(ex_err, "Error writing element truth table.");
2605  }
2606 }
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 ...
std::vector< int > global_elem_blk_ids
Read the global element block IDs and counts.
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:117

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

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

3329 {
3330  if ((_run_only_on_proc0) && (this->processor_id() != 0))
3331  return;
3332 
3333  // Quick return if there are no global variables to write
3334  if (names.size() == 0)
3335  return;
3336 
3338  return;
3339 
3340  // Be sure that variables in the file match what we are asking for
3341  if (num_global_vars > 0)
3342  {
3343  this->check_existing_vars(GLOBAL, names, this->global_var_names);
3344  return;
3345  }
3346 
3347  _global_vars_initialized = true;
3348 
3349  this->write_var_names(GLOBAL, names);
3350 }
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().
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 ...
std::vector< std::string > global_var_names
processor_id_type processor_id() const

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

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

3301 {
3302  if ((_run_only_on_proc0) && (this->processor_id() != 0))
3303  return;
3304 
3305  // Quick return if there are no nodal variables to write
3306  if (names.size() == 0)
3307  return;
3308 
3309  // Quick return if we have already called this function
3311  return;
3312 
3313  // Be sure that variables in the file match what we are asking for
3314  if (num_nodal_vars > 0)
3315  {
3316  this->check_existing_vars(NODAL, names, this->nodal_var_names);
3317  return;
3318  }
3319 
3320  // Set the flag so we can skip the rest of this function on subsequent calls.
3321  _nodal_vars_initialized = true;
3322 
3323  this->write_var_names(NODAL, names);
3324 }
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().
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 ...
std::vector< std::string > nodal_var_names
processor_id_type processor_id() const

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

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

571 {
572  if (verbose) libMesh::out << msg << i << "." << std::endl;
573 }
OStreamProxy out

◆ n_processors()

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

Definition at line 103 of file parallel_object.h.

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

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

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

◆ 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 896 of file exodusII_io_helper.h.

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

897  {
898  if (_added_side_node_offsets.empty())
899  return n;
900 
901  // Find the processor id that has node_id in the parallel vec
902  const auto lb = std::upper_bound(_true_node_offsets.begin(),
903  _true_node_offsets.end(), n);
904  libmesh_assert(lb != _true_node_offsets.end());
905  const processor_id_type p = lb - _true_node_offsets.begin();
906 
907  return n + (p ? _added_side_node_offsets[p-1] : 0);
908  }
uint8_t processor_id_type
libmesh_assert(ctx)
std::vector< dof_id_type > _true_node_offsets
If we&#39;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&#39;re adding "fake" sides to visualize SIDE_DISCONTINUOUS variables, _added_side_node_offsets[p] g...

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

References libMesh::ExodusII_IO_Helper::_single_precision, libMesh::ExodusII_IO_Helper::current_filename, 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.

663 {
664  // Version of Exodus you are using
665  float ex_version = 0.;
666 
667  int comp_ws = 0;
668 
669  if (_single_precision)
670  comp_ws = cast_int<int>(sizeof(float));
671 
672  // Fall back on double precision when necessary since ExodusII
673  // doesn't seem to support long double
674  else
675  comp_ws = cast_int<int>(std::min(sizeof(Real), sizeof(double)));
676 
677  // Word size in bytes of the floating point data as they are stored
678  // in the ExodusII file. "If this argument is 0, the word size of the
679  // floating point data already stored in the file is returned"
680  int io_ws = 0;
681 
682  {
683  FPEDisabler disable_fpes;
684  ex_id = exII::ex_open(filename,
685  read_only ? EX_READ : EX_WRITE,
686  &comp_ws,
687  &io_ws,
688  &ex_version);
689  }
690 
691  std::string err_msg = std::string("Error opening ExodusII mesh file: ") + std::string(filename);
692  EX_CHECK_ERR(ex_id, err_msg);
693  if (verbose) libMesh::out << "File opened successfully." << std::endl;
694 
695  if (read_only)
696  opened_for_reading = true;
697  else
698  opened_for_writing = true;
699 
700  current_filename = std::string(filename);
701 }
The FPEDisabler class puts Floating-Point Exception (FPE) trapping on hold during its lifetime...
Definition: fpe_disabler.h:49
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
OStreamProxy out

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

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.

832 {
833  if (verbose)
834  libMesh::out << "Title: \t" << title.data() << std::endl
835  << "Mesh Dimension: \t" << num_dim << std::endl
836  << "Number of Nodes: \t" << num_nodes << std::endl
837  << "Number of elements: \t" << num_elem << std::endl
838  << "Number of elt blocks: \t" << num_elem_blk << std::endl
839  << "Number of node sets: \t" << num_node_sets << std::endl
840  << "Number of side sets: \t" << num_side_sets << std::endl
841  << "Number of elem sets: \t" << num_elem_sets << std::endl;
842 }
std::vector< char > & title
OStreamProxy out

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

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

1034 {
1035  for (int i=0; i<num_nodes; i++)
1036  out_stream << "(" << x[i] << ", " << y[i] << ", " << z[i] << ")" << std::endl;
1037 }

◆ processor_id()

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

Definition at line 114 of file parallel_object.h.

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

Referenced by libMesh::BoundaryInfo::_find_id_maps(), libMesh::PetscDMWrapper::add_dofs_to_section(), libMesh::DistributedMesh::add_elem(), libMesh::BoundaryInfo::add_elements(), libMesh::DofMap::add_neighbors_to_send_list(), libMesh::DistributedMesh::add_node(), libMesh::MeshTools::Modification::all_tri(), libMesh::DofMap::allgather_recursive_constraints(), libMesh::FEMSystem::assembly(), libMesh::Nemesis_IO::assert_symmetric_cmaps(), libMesh::Partitioner::assign_partitioning(), 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::DistributedMesh::delete_elem(), libMesh::MeshCommunication::delete_remote_elements(), libMesh::DofMap::distribute_dofs(), libMesh::DofMap::distribute_scalar_dofs(), libMesh::DistributedMesh::DistributedMesh(), libMesh::DofMapBase::end_dof(), libMesh::DofMapBase::end_old_dof(), libMesh::EnsightIO::EnsightIO(), libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::find_dofs_to_send(), libMesh::UnstructuredMesh::find_neighbors(), libMesh::DofMapBase::first_dof(), libMesh::DofMapBase::first_old_dof(), libMesh::RBEIMEvaluation::gather_bfs(), get_cmap_params(), get_eb_info_global(), get_elem_cmap(), get_elem_map(), libMesh::MeshBase::get_info(), libMesh::DofMap::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::DofMap::is_evaluable(), libMesh::SparsityPattern::Build::join(), libMesh::TransientRBEvaluation::legacy_write_offline_data_to_files(), libMesh::RBSCMEvaluation::legacy_write_offline_data_to_files(), libMesh::RBEvaluation::legacy_write_offline_data_to_files(), libMesh::MeshTools::libmesh_assert_consistent_distributed(), libMesh::MeshTools::libmesh_assert_consistent_distributed_nodes(), libMesh::MeshTools::libmesh_assert_contiguous_dof_ids(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Elem >(), libMesh::MeshTools::libmesh_assert_valid_neighbors(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_object_ids(), libMesh::DofMap::local_variable_indices(), main(), libMesh::MeshRefinement::make_coarsening_compatible(), AugmentSparsityOnInterface::mesh_reinit(), libMesh::TriangulatorInterface::MeshedHole::MeshedHole(), libMesh::MeshBase::n_active_local_elem(), libMesh::BoundaryInfo::n_boundary_conds(), libMesh::MeshTools::n_connected_components(), libMesh::MeshBase::n_constraint_rows(), libMesh::BoundaryInfo::n_edge_conds(), libMesh::DofMapBase::n_local_dofs(), libMesh::MeshBase::n_local_elem(), libMesh::MeshBase::n_local_nodes(), libMesh::BoundaryInfo::n_nodeset_conds(), libMesh::BoundaryInfo::n_shellface_conds(), libMesh::RBEIMEvaluation::node_gather_bfs(), libMesh::DistributedMesh::own_node(), libMesh::BoundaryInfo::parallel_sync_node_ids(), libMesh::BoundaryInfo::parallel_sync_side_ids(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), libMesh::MeshBase::print_constraint_rows(), libMesh::DofMap::print_dof_constraints(), libMesh::DofMap::process_mesh_constraint_rows(), put_cmap_params(), put_elem_cmap(), put_elem_map(), put_loadbal_param(), put_node_cmap(), put_node_map(), libMesh::NameBasedIO::read(), libMesh::Nemesis_IO::read(), libMesh::XdrIO::read(), libMesh::CheckpointIO::read(), libMesh::EquationSystems::read(), libMesh::ExodusII_IO_Helper::read_elem_num_map(), libMesh::ExodusII_IO_Helper::read_global_values(), libMesh::ExodusII_IO::read_header(), libMesh::CheckpointIO::read_header(), libMesh::XdrIO::read_header(), libMesh::System::read_header(), libMesh::System::read_legacy_data(), libMesh::DynaIO::read_mesh(), libMesh::ExodusII_IO_Helper::read_node_num_map(), libMesh::System::read_parallel_data(), libMesh::TransientRBConstruction::read_riesz_representors_from_files(), libMesh::RBConstruction::read_riesz_representors_from_files(), libMesh::System::read_SCALAR_dofs(), libMesh::XdrIO::read_serialized_bc_names(), libMesh::XdrIO::read_serialized_bcs_helper(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::XdrIO::read_serialized_connectivity(), libMesh::System::read_serialized_data(), libMesh::XdrIO::read_serialized_nodes(), libMesh::XdrIO::read_serialized_nodesets(), libMesh::XdrIO::read_serialized_subdomain_names(), libMesh::System::read_serialized_vector(), libMesh::System::read_serialized_vectors(), read_var_names_impl(), libMesh::SimplexRefiner::refine_via_edges(), libMesh::StaticCondensationDofMap::reinit(), libMesh::DistributedMesh::renumber_dof_objects(), libMesh::DistributedMesh::renumber_nodes_and_elements(), libMesh::DofMap::scatter_constraints(), libMesh::CheckpointIO::select_split_config(), libMesh::DistributedMesh::set_next_unique_id(), libMesh::DofMap::set_nonlocal_dof_objects(), libMesh::PetscDMWrapper::set_point_range_in_section(), libMesh::RBEIMEvaluation::side_gather_bfs(), ExodusTest< elem_type >::test_read_gold(), ExodusTest< elem_type >::test_write(), MeshInputTest::testAbaqusRead(), MeshInputTest::testBadGmsh(), 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(), MeshInputTest::testLowOrderEdgeBlocks(), SystemsTest::testProjectMatrix3D(), BoundaryInfoTest::testShellFaceConstraints(), MeshInputTest::testSingleElementImpl(), WriteVecAndScalar::testSolution(), CheckpointIOTest::testSplitter(), MeshInputTest::testTetgenIO(), libMesh::MeshTools::total_weight(), libMesh::NetGenMeshInterface::triangulate(), libMesh::MeshRefinement::uniformly_coarsen(), libMesh::DistributedMesh::update_parallel_id_counts(), libMesh::DTKAdapter::update_variable_values(), libMesh::MeshTools::volume(), libMesh::STLIO::write(), libMesh::NameBasedIO::write(), libMesh::XdrIO::write(), libMesh::CheckpointIO::write(), libMesh::EquationSystems::write(), libMesh::GMVIO::write_discontinuous_gmv(), libMesh::ExodusII_IO::write_element_data(), libMesh::ExodusII_IO_Helper::write_element_values(), libMesh::ExodusII_IO_Helper::write_element_values_element_major(), libMesh::ExodusII_IO_Helper::write_elements(), libMesh::ExodusII_IO_Helper::write_elemset_data(), libMesh::ExodusII_IO_Helper::write_elemsets(), 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::UCDIO::write_nodal_data(), libMesh::VTKIO::write_nodal_data(), libMesh::ExodusII_IO::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(), write_nodesets(), libMesh::ExodusII_IO_Helper::write_nodesets(), libMesh::RBEIMEvaluation::write_out_interior_basis_functions(), libMesh::RBEIMEvaluation::write_out_node_basis_functions(), libMesh::RBEIMEvaluation::write_out_side_basis_functions(), write_output_solvedata(), libMesh::System::write_parallel_data(), libMesh::RBConstruction::write_riesz_representors_to_files(), libMesh::System::write_SCALAR_dofs(), libMesh::XdrIO::write_serialized_bc_names(), libMesh::XdrIO::write_serialized_bcs_helper(), libMesh::System::write_serialized_blocked_dof_objects(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::System::write_serialized_data(), libMesh::XdrIO::write_serialized_nodes(), libMesh::XdrIO::write_serialized_nodesets(), libMesh::XdrIO::write_serialized_subdomain_names(), libMesh::System::write_serialized_vector(), libMesh::System::write_serialized_vectors(), libMesh::ExodusII_IO_Helper::write_sideset_data(), write_sidesets(), libMesh::ExodusII_IO_Helper::write_sidesets(), libMesh::ExodusII_IO::write_timestep(), libMesh::ExodusII_IO_Helper::write_timestep(), and libMesh::ExodusII_IO::write_timestep_discontinuous().

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

◆ 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 620 of file nemesis_io_helper.C.

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

Referenced by initialize().

624 {
626  Nemesis::ne_put_cmap_params(ex_id,
627  node_cmap_ids_in.empty() ? nullptr : node_cmap_ids_in.data(),
628  node_cmap_node_cnts_in.empty() ? nullptr : node_cmap_node_cnts_in.data(),
629  elem_cmap_ids_in.empty() ? nullptr : elem_cmap_ids_in.data(),
630  elem_cmap_elem_cnts_in.empty() ? nullptr : elem_cmap_elem_cnts_in.data(),
631  this->processor_id());
632 
633  EX_CHECK_ERR(nemesis_err_flag, "Error writing cmap parameters!");
634 }
int nemesis_err_flag
Member data.
processor_id_type processor_id() const

◆ 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 540 of file nemesis_io_helper.C.

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

Referenced by initialize().

542 {
544  Nemesis::ne_put_eb_info_global(ex_id,
545  global_elem_blk_ids_in.data(),
546  global_elem_blk_cnts_in.data());
547 
548  EX_CHECK_ERR(nemesis_err_flag, "Error writing global element block information!");
549 }
int nemesis_err_flag
Member data.

◆ 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 700 of file nemesis_io_helper.C.

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

Referenced by initialize().

703 {
704  for (auto i : index_range(elem_cmap_ids))
705  {
707  Nemesis::ne_put_elem_cmap(ex_id,
708  this->elem_cmap_ids[i],
709  elem_cmap_elem_ids_in[i].data(),
710  elem_cmap_side_ids_in[i].data(),
711  elem_cmap_proc_ids_in[i].data(),
712  this->processor_id());
713 
714  EX_CHECK_ERR(nemesis_err_flag, "Error writing elem communication map to file!");
715  }
716 }
int nemesis_err_flag
Member data.
std::vector< int > elem_cmap_ids
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:117

◆ 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 721 of file nemesis_io_helper.C.

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

Referenced by initialize().

723 {
725  Nemesis::ne_put_elem_map(ex_id,
726  elem_mapi_in.empty() ? nullptr : elem_mapi_in.data(),
727  elem_mapb_in.empty() ? nullptr : elem_mapb_in.data(),
728  this->processor_id());
729 
730  EX_CHECK_ERR(nemesis_err_flag, "Error writing Nemesis internal and border element maps to file!");
731 }
int nemesis_err_flag
Member data.
processor_id_type processor_id() const

◆ 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 521 of file nemesis_io_helper.C.

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

Referenced by initialize().

526 {
528  Nemesis::ne_put_init_global(ex_id,
529  num_nodes_global_in,
530  num_elems_global_in,
531  num_elem_blks_global_in,
532  num_node_sets_global_in,
533  num_side_sets_global_in);
534 
535  EX_CHECK_ERR(nemesis_err_flag, "Error writing initial global data!");
536 }
int nemesis_err_flag
Member data.

◆ 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 505 of file nemesis_io_helper.C.

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

Referenced by initialize().

508 {
510  Nemesis::ne_put_init_info(ex_id,
511  num_proc_in,
512  num_proc_in_file_in,
513  const_cast<char *>(ftype_in));
514 
515  EX_CHECK_ERR(nemesis_err_flag, "Error writing initial information!");
516 }
int nemesis_err_flag
Member data.

◆ 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 594 of file nemesis_io_helper.C.

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

Referenced by initialize().

601 {
603  Nemesis::ne_put_loadbal_param(ex_id,
604  num_internal_nodes_in,
605  num_border_nodes_in,
606  num_external_nodes_in,
607  num_internal_elems_in,
608  num_border_elems_in,
609  num_node_cmaps_in,
610  num_elem_cmaps_in,
611  this->processor_id());
612 
613  EX_CHECK_ERR(nemesis_err_flag, "Error writing loadbal parameters!");
614 }
int nemesis_err_flag
Member data.
processor_id_type processor_id() const

◆ 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 639 of file nemesis_io_helper.C.

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

641 {
642  // Print to screen what we are about to print to Nemesis file
643  if (verbose)
644  {
645  for (auto i : index_range(node_cmap_node_ids_in))
646  {
647  libMesh::out << "[" << this->processor_id() << "] put_node_cmap() : nodes communicated to proc "
648  << this->node_cmap_ids[i]
649  << " = ";
650  for (const auto & node_id : node_cmap_node_ids_in[i])
651  libMesh::out << node_id << " ";
652  libMesh::out << std::endl;
653  }
654 
655  for (auto i : index_range(node_cmap_node_ids_in))
656  {
657  libMesh::out << "[" << this->processor_id() << "] put_node_cmap() : processor IDs = ";
658  for (const auto & proc_id : node_cmap_proc_ids_in[i])
659  libMesh::out << proc_id << " ";
660  libMesh::out << std::endl;
661  }
662  }
663 
664  for (auto i : index_range(node_cmap_node_ids_in))
665  {
666  int * node_ids_ptr = node_cmap_node_ids_in[i].empty() ?
667  nullptr : node_cmap_node_ids_in[i].data();
668  int * proc_ids_ptr = node_cmap_proc_ids_in[i].empty() ?
669  nullptr : node_cmap_proc_ids_in[i].data();
670 
672  Nemesis::ne_put_node_cmap(ex_id, this->node_cmap_ids[i],
673  node_ids_ptr, proc_ids_ptr,
674  this->processor_id());
675 
676  EX_CHECK_ERR(nemesis_err_flag, "Error writing node communication map to file!");
677  }
678 }
std::vector< int > node_cmap_ids
Vectors for storing the communication map parameters.
int nemesis_err_flag
Member data.
OStreamProxy out
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:117

◆ 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 683 of file nemesis_io_helper.C.

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

Referenced by initialize().

686 {
688  Nemesis::ne_put_node_map(ex_id,
689  node_mapi_in.empty() ? nullptr : node_mapi_in.data(),
690  node_mapb_in.empty() ? nullptr : node_mapb_in.data(),
691  node_mape_in.empty() ? nullptr : node_mape_in.data(),
692  this->processor_id());
693 
694  EX_CHECK_ERR(nemesis_err_flag, "Error writing Nemesis internal and border node maps to file!");
695 }
int nemesis_err_flag
Member data.
processor_id_type processor_id() const

◆ 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 554 of file nemesis_io_helper.C.

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

Referenced by initialize().

557 {
558  // Only add nodesets if there are some
559  if (global_nodeset_ids.size())
560  {
562  Nemesis::ne_put_ns_param_global(ex_id,
563  global_nodeset_ids_in.data(),
564  num_global_node_counts_in.data(),
565  num_global_node_df_counts_in.data());
566  }
567 
568  EX_CHECK_ERR(nemesis_err_flag, "Error writing global nodeset parameters!");
569 }
std::vector< int > global_nodeset_ids
Containers for reading global nodeset information.
int nemesis_err_flag
Member data.

◆ 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 574 of file nemesis_io_helper.C.

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

Referenced by initialize().

577 {
578  // Only add sidesets if there are some
579  if (global_sideset_ids.size())
580  {
582  Nemesis::ne_put_ss_param_global(ex_id,
583  global_sideset_ids_in.data(),
584  num_global_side_counts_in.data(),
585  num_global_side_df_counts_in.data());
586  }
587 
588  EX_CHECK_ERR(nemesis_err_flag, "Error writing global sideset parameters!");
589 }
std::vector< int > global_sideset_ids
Containers for reading global sideset (boundary conditions) information.
int nemesis_err_flag
Member data.

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

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

1704 {
1705  LOG_SCOPE("read_all_nodesets()", "ExodusII_IO_Helper");
1706 
1707  // Figure out how many nodesets there are in the file so we can
1708  // properly resize storage as necessary.
1709  num_node_sets =
1710  inquire
1711  (*this, exII::EX_INQ_NODE_SETS,
1712  "Error retrieving number of node sets");
1713 
1714  // Figure out how many nodes there are in all the nodesets.
1715  int total_nodes_in_all_sets =
1716  inquire
1717  (*this, exII::EX_INQ_NS_NODE_LEN,
1718  "Error retrieving number of nodes in all node sets.");
1719 
1720  // Figure out how many distribution factors there are in all the nodesets.
1721  int total_df_in_all_sets =
1722  inquire
1723  (*this, exII::EX_INQ_NS_DF_LEN,
1724  "Error retrieving number of distribution factors in all node sets.");
1725 
1726  // If there are no nodesets, there's nothing to read in.
1727  if (num_node_sets == 0)
1728  return;
1729 
1730  // Allocate space to read all the nodeset data.
1731  // Use existing class members where possible to avoid shadowing
1732  nodeset_ids.clear(); nodeset_ids.resize(num_node_sets);
1737  node_sets_node_list.clear(); node_sets_node_list.resize(total_nodes_in_all_sets);
1738  node_sets_dist_fact.clear(); node_sets_dist_fact.resize(total_df_in_all_sets);
1739 
1740  // Handle single-precision files
1741  MappedInputVector mapped_node_sets_dist_fact(node_sets_dist_fact, _single_precision);
1742 
1743  // Build exII::ex_set_spec struct
1744  exII::ex_set_specs set_specs = {};
1745  set_specs.sets_ids = nodeset_ids.data();
1746  set_specs.num_entries_per_set = num_nodes_per_set.data();
1747  set_specs.num_dist_per_set = num_node_df_per_set.data();
1748  set_specs.sets_entry_index = node_sets_node_index.data();
1749  set_specs.sets_dist_index = node_sets_dist_index.data();
1750  set_specs.sets_entry_list = node_sets_node_list.data();
1751  set_specs.sets_extra_list = nullptr;
1752  set_specs.sets_dist_fact = total_df_in_all_sets ? mapped_node_sets_dist_fact.data() : nullptr;
1753 
1754  ex_err = exII::ex_get_concat_sets(ex_id, exII::EX_NODE_SET, &set_specs);
1755  EX_CHECK_ERR(ex_err, "Error reading concatenated nodesets");
1756 
1757  // Read the nodeset names from file!
1758  char name_buffer[MAX_STR_LENGTH+1];
1759  for (int i=0; i<num_node_sets; ++i)
1760  {
1761  ex_err = exII::ex_get_name
1762  (ex_id,
1763  exII::EX_NODE_SET,
1764  nodeset_ids[i],
1765  name_buffer);
1766  EX_CHECK_ERR(ex_err, "Error getting node set name.");
1767  id_to_ns_names[nodeset_ids[i]] = name_buffer;
1768  }
1769 }
std::vector< int > node_sets_node_index
std::vector< int > num_node_df_per_set
std::vector< int > node_sets_node_list
std::map< int, std::string > id_to_ns_names
std::vector< int > num_nodes_per_set
std::vector< Real > node_sets_dist_fact
std::vector< int > node_sets_dist_index

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

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

737 {
738  // Read header params from file, storing them in this class's
739  // ExodusHeaderInfo struct. This automatically updates the local
740  // num_dim, num_elem, etc. references.
741  this->header_info = this->read_header();
742 
743  // Read the number of timesteps which are present in the file
744  this->read_num_time_steps();
745 
746  ex_err = exII::ex_get_variable_param(ex_id, exII::EX_NODAL, &num_nodal_vars);
747  EX_CHECK_ERR(ex_err, "Error reading number of nodal variables.");
748 
749  ex_err = exII::ex_get_variable_param(ex_id, exII::EX_ELEM_BLOCK, &num_elem_vars);
750  EX_CHECK_ERR(ex_err, "Error reading number of elemental variables.");
751 
752  ex_err = exII::ex_get_variable_param(ex_id, exII::EX_GLOBAL, &num_global_vars);
753  EX_CHECK_ERR(ex_err, "Error reading number of global variables.");
754 
755  ex_err = exII::ex_get_variable_param(ex_id, exII::EX_SIDE_SET, &num_sideset_vars);
756  EX_CHECK_ERR(ex_err, "Error reading number of sideset variables.");
757 
758  ex_err = exII::ex_get_variable_param(ex_id, exII::EX_NODE_SET, &num_nodeset_vars);
759  EX_CHECK_ERR(ex_err, "Error reading number of nodeset variables.");
760 
761  ex_err = exII::ex_get_variable_param(ex_id, exII::EX_ELEM_SET, &num_elemset_vars);
762  EX_CHECK_ERR(ex_err, "Error reading number of elemset variables.");
763 
764  message("Exodus header info retrieved successfully.");
765 }
ExodusHeaderInfo read_header() const
Reads an ExodusII mesh file header, leaving this object&#39;s internal data structures unchanged...
void message(std::string_view msg)
Prints the message defined in msg.
void read_num_time_steps()
Reads the number of timesteps currently stored in the Exodus file and stores it in the 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 921 of file exodusII_io_helper.C.

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

922 {
923  // If a bex blob exists, we look for Bezier Extraction coefficient
924  // data there.
925 
926  // These APIs require newer Exodus than 5.22
927 #if EX_API_VERS_NODOT >= 800
928  int n_blobs = exII::ex_inquire_int(ex_id, exII::EX_INQ_BLOB);
929 
930  if (n_blobs > 0)
931  {
932  std::vector<exII::ex_blob> blobs(n_blobs);
933  std::vector<std::vector<char>> blob_names(n_blobs);
934  for (auto i : make_range(n_blobs))
935  {
936  blob_names[i].resize(MAX_STR_LENGTH+1);
937  blobs[i].name = blob_names[i].data();
938  }
939 
940  ex_err = exII::ex_get_blobs(ex_id, blobs.data());
941  EX_CHECK_ERR(ex_err, "Error getting blobs.");
942 
943  bool found_blob = false;
944  const exII::ex_blob * my_blob = &blobs[0];
945  for (const auto & blob : blobs)
946  {
947  if (std::string("bex_cv_blob") == blob.name)
948  {
949  found_blob = true;
950  my_blob = &blob;
951  }
952  }
953 
954  if (!found_blob)
955  libmesh_error_msg("Found no bex_cv_blob for bezier elements");
956 
957  const int n_blob_attr =
958  exII::ex_get_attribute_count(ex_id, exII::EX_BLOB,
959  my_blob->id);
960 
961  std::vector<exII::ex_attribute> attributes(n_blob_attr);
962  ex_err = exII::ex_get_attribute_param(ex_id, exII::EX_BLOB,
963  my_blob->id,
964  attributes.data());
965  EX_CHECK_ERR(ex_err, "Error getting bex blob attribute parameters.");
966 
967  int bex_num_dense_cv_blocks = 0;
968  std::vector<int> bex_dense_cv_info;
969  for (auto & attr : attributes)
970  {
971  if (std::string("bex_dense_cv_info") == attr.name)
972  {
973  const std::size_t value_count = attr.value_count;
974  if (value_count % 2)
975  libmesh_error_msg("Found odd number of bex_dense_cv_info");
976 
977  bex_dense_cv_info.resize(value_count);
978  attr.values = bex_dense_cv_info.data();
979  exII::ex_get_attribute(ex_id, &attr);
980 
981  bex_num_dense_cv_blocks = value_count / 2;
982 
983  libmesh_error_msg_if(bex_num_dense_cv_blocks > 1,
984  "Found more than 1 dense bex CV block; unsure how to handle that");
985  }
986  }
987 
988  if (bex_dense_cv_info.empty())
989  libmesh_error_msg("No bex_dense_cv_info found");
990 
991  int n_blob_vars;
992  exII::ex_get_variable_param(ex_id, exII::EX_BLOB, &n_blob_vars);
993  std::vector<char> var_name (MAX_STR_LENGTH + 1);
994  for (auto v_id : make_range(1,n_blob_vars+1))
995  {
996  ex_err = exII::ex_get_variable_name(ex_id, exII::EX_BLOB, v_id, var_name.data());
997  EX_CHECK_ERR(ex_err, "Error reading bex blob var name.");
998 
999  if (std::string("bex_dense_cv_blocks") == var_name.data())
1000  {
1001  std::vector<double> bex_dense_cv_blocks(my_blob->num_entry);
1002 
1003  ex_err = exII::ex_get_var(ex_id, 1, exII::EX_BLOB, v_id,
1004  my_blob->id, my_blob->num_entry,
1005  bex_dense_cv_blocks.data());
1006  EX_CHECK_ERR(ex_err, "Error reading bex_dense_cv_blocks.");
1007 
1008  bex_dense_constraint_vecs.clear();
1009  bex_dense_constraint_vecs.resize(bex_num_dense_cv_blocks);
1010 
1011  std::size_t offset = 0;
1012  for (auto i : IntRange<std::size_t>(0, bex_num_dense_cv_blocks))
1013  {
1014  bex_dense_constraint_vecs[i].resize(bex_dense_cv_info[2*i]);
1015  const int vecsize = bex_dense_cv_info[2*i+1];
1016  for (auto & vec : bex_dense_constraint_vecs[i])
1017  {
1018  vec.resize(vecsize);
1019  std::copy(std::next(bex_dense_cv_blocks.begin(), offset),
1020  std::next(bex_dense_cv_blocks.begin(), offset + vecsize),
1021  vec.begin());
1022  offset += vecsize;
1023  }
1024  }
1025  libmesh_assert(offset == bex_dense_cv_blocks.size());
1026  }
1027  }
1028  }
1029 #endif // EX_API_VERS_NODOT >= 800
1030 }
The IntRange templated class is intended to make it easy to loop over integers which are indices of a...
Definition: int_range.h:53
libmesh_assert(ctx)
static const unsigned int next[3]
A lookup table for the increment modulo 3 operation, for iterating through the three nodes per elemen...
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:140
std::vector< std::vector< std::vector< Real > > > bex_dense_constraint_vecs

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

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.

1042 {
1043  if (num_elem_blk)
1044  {
1045  // Read all element block IDs.
1046  block_ids.resize(num_elem_blk);
1047  ex_err = exII::ex_get_ids(ex_id,
1048  exII::EX_ELEM_BLOCK,
1049  block_ids.data());
1050 
1051  EX_CHECK_ERR(ex_err, "Error getting block IDs.");
1052  message("All block IDs retrieved successfully.");
1053 
1054  char name_buffer[MAX_STR_LENGTH+1];
1055  for (int i=0; i<num_elem_blk; ++i)
1056  {
1057  ex_err = exII::ex_get_name(ex_id, exII::EX_ELEM_BLOCK,
1058  block_ids[i], name_buffer);
1059  EX_CHECK_ERR(ex_err, "Error getting block name.");
1060  id_to_block_names[block_ids[i]] = name_buffer;
1061  }
1062  message("All block names retrieved successfully.");
1063  }
1064 
1065  if (num_edge_blk)
1066  {
1067  // Read all edge block IDs.
1068  edge_block_ids.resize(num_edge_blk);
1069  ex_err = exII::ex_get_ids(ex_id,
1070  exII::EX_EDGE_BLOCK,
1071  edge_block_ids.data());
1072 
1073  EX_CHECK_ERR(ex_err, "Error getting edge block IDs.");
1074  message("All edge block IDs retrieved successfully.");
1075 
1076  // Read in edge block names
1077  char name_buffer[MAX_STR_LENGTH+1];
1078  for (int i=0; i<num_edge_blk; ++i)
1079  {
1080  ex_err = exII::ex_get_name(ex_id, exII::EX_EDGE_BLOCK,
1081  edge_block_ids[i], name_buffer);
1082  EX_CHECK_ERR(ex_err, "Error getting block name.");
1083  id_to_edge_block_names[edge_block_ids[i]] = name_buffer;
1084  }
1085  message("All edge block names retrieved successfully.");
1086  }
1087 }
std::map< int, std::string > id_to_edge_block_names
void message(std::string_view msg)
Prints the message defined in msg.
std::map< int, std::string > id_to_block_names
std::vector< int > edge_block_ids

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

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::id_to_edge_block_names, mesh, libMesh::ExodusII_IO_Helper::message(), libMesh::ExodusII_IO_Helper::node_num_map, libMesh::MeshBase::node_ptr(), and libMesh::ExodusII_IO_Helper::num_edge_blk.

1305 {
1306  LOG_SCOPE("read_edge_blocks()", "ExodusII_IO_Helper");
1307 
1308  // Check for quick return if there are no edge blocks.
1309  if (num_edge_blk == 0)
1310  return;
1311 
1312  // Build data structure that we can quickly search for edges
1313  // and then add required BoundaryInfo information. This is a
1314  // map from edge->key() to a list of (elem_id, edge_id) pairs
1315  // for the Edge in question. Since edge->key() is edge orientation
1316  // invariant, this map does not distinguish different orientations
1317  // of the same Edge. Since edge->key() is also not guaranteed to be
1318  // unique (though it is very unlikely for two distinct edges to have
1319  // the same key()), when we later look up an (elem_id, edge_id) pair
1320  // in the edge_map, we need to verify that the edge indeed matches
1321  // the searched edge by doing some further checks.
1322  typedef std::pair<dof_id_type, unsigned int> ElemEdgePair;
1323  std::unordered_map<dof_id_type, std::vector<ElemEdgePair>> edge_map;
1324  std::unique_ptr<Elem> edge_ptr;
1325  for (const auto & elem : mesh.element_ptr_range())
1326  for (auto e : elem->edge_index_range())
1327  {
1328  elem->build_edge_ptr(edge_ptr, e);
1329  dof_id_type edge_key = edge_ptr->key();
1330 
1331  // Creates vector if not already there
1332  auto & vec = edge_map[edge_key];
1333  vec.emplace_back(elem->id(), e);
1334 
1335  // If edge_ptr is a higher-order Elem (EDGE3 or higher) then also add
1336  // a map entry for the lower-order (EDGE2) element which has matching
1337  // vertices. This allows us to match lower-order edge blocks to edges
1338  // of higher-order 3D elems (e.g. HEX20, TET10) and simplifies the
1339  // definition of edge blocks.
1340  if (edge_ptr->default_order() != FIRST)
1341  {
1342  // Construct a temporary low-order edge so that we can compute its key()
1343  auto low_order_edge =
1345 
1346  // Assign node pointers to low-order edge
1347  for (unsigned int v=0; v<edge_ptr->n_vertices(); ++v)
1348  low_order_edge->set_node(v, edge_ptr->node_ptr(v));
1349 
1350  // Compute the key for the temporary low-order edge we just built
1351  dof_id_type low_order_edge_key = low_order_edge->key();
1352 
1353  // Add this key to the map associated with the same (elem,
1354  // edge) pair as the higher-order edge
1355  auto & low_order_vec = edge_map[low_order_edge_key];
1356  low_order_vec.emplace_back(elem->id(), e);
1357  }
1358  }
1359 
1360  // Get reference to the mesh's BoundaryInfo object, as we will be
1361  // adding edges to this below.
1363 
1364  for (const auto & edge_block_id : edge_block_ids)
1365  {
1366  // exII::ex_get_block() output parameters. Unlike the other
1367  // "extended" APIs, exII::ex_get_block() does not use a
1368  // parameter struct.
1369  int num_edge_this_blk = 0;
1370  int num_nodes_per_edge = 0;
1371  int num_edges_per_edge = 0;
1372  int num_faces_per_edge = 0;
1373  int num_attr_per_edge = 0;
1374  ex_err = exII::ex_get_block(ex_id,
1375  exII::EX_EDGE_BLOCK,
1376  edge_block_id,
1377  elem_type.data(),
1378  &num_edge_this_blk,
1379  &num_nodes_per_edge,
1380  &num_edges_per_edge, // 0 or -1 for edge blocks
1381  &num_faces_per_edge, // 0 or -1 for edge blocks
1382  &num_attr_per_edge);
1383 
1384  EX_CHECK_ERR(ex_err, "Error getting edge block info.");
1385  message("Info retrieved successfully for block: ", edge_block_id);
1386 
1387  // Read in the connectivity of the edges of this block,
1388  // watching out for the case where we actually have no
1389  // elements in this block (possible with parallel files)
1390  connect.resize(num_nodes_per_edge * num_edge_this_blk);
1391 
1392  if (!connect.empty())
1393  {
1394  ex_err = exII::ex_get_conn(ex_id,
1395  exII::EX_EDGE_BLOCK,
1396  edge_block_id,
1397  connect.data(), // node_conn
1398  nullptr, // elem_edge_conn (unused)
1399  nullptr); // elem_face_conn (unused)
1400 
1401  EX_CHECK_ERR(ex_err, "Error reading block connectivity.");
1402  message("Connectivity retrieved successfully for block: ", edge_block_id);
1403 
1404  // All edge types have an identity mapping from the corresponding
1405  // Exodus type, so we don't need to bother with mapping ids, but
1406  // we do need to know what kind of elements to build.
1407  const auto & conv = get_conversion(std::string(elem_type.data()));
1408 
1409  // Loop over indices in connectivity array, build edge elements,
1410  // look them up in the edge_map.
1411  for (unsigned int i=0, sz=connect.size(); i<sz; i+=num_nodes_per_edge)
1412  {
1413  auto edge = Elem::build(conv.libmesh_elem_type());
1414  for (int n=0; n<num_nodes_per_edge; ++n)
1415  {
1416  int exodus_node_id = connect[i+n];
1417  int exodus_node_id_zero_based = exodus_node_id - 1;
1418  int libmesh_node_id = node_num_map[exodus_node_id_zero_based] - 1;
1419 
1420  edge->set_node(n, mesh.node_ptr(libmesh_node_id));
1421  }
1422 
1423  // Compute key for the edge Elem we just built.
1424  dof_id_type edge_key = edge->key();
1425 
1426  // If this key is not found in the edge_map, which is
1427  // supposed to include every edge in the Mesh, then we
1428  // will throw an error now.
1429  auto & elem_edge_pair_vec =
1430  libmesh_map_find(edge_map, edge_key);
1431 
1432  for (const auto & elem_edge_pair : elem_edge_pair_vec)
1433  {
1434  // We only want to match edges which have the same
1435  // nodes (possibly with different orientation) to the one in the
1436  // Exodus file, otherwise we ignore this elem_edge_pair.
1437  //
1438  // Note: this also handles the situation where two
1439  // edges have the same key (hash collision) as then
1440  // this check avoids a false positive.
1441 
1442  // Build edge indicated by elem_edge_pair
1443  mesh.elem_ptr(elem_edge_pair.first)->
1444  build_edge_ptr(edge_ptr, elem_edge_pair.second);
1445 
1446  // Determine whether this candidate edge is a "real" match,
1447  // i.e. has the same nodes with a possibly different
1448  // orientation. Note that here we only check that
1449  // the vertices match regardless of how many nodes
1450  // the edge has, which allows us to match a
1451  // lower-order edge to a higher-order Elem.
1452  bool is_match =
1453  ((edge_ptr->node_id(0) == edge->node_id(0)) && (edge_ptr->node_id(1) == edge->node_id(1))) ||
1454  ((edge_ptr->node_id(0) == edge->node_id(1)) && (edge_ptr->node_id(1) == edge->node_id(0)));
1455 
1456  if (is_match)
1457  {
1458  // Add this (elem, edge, id) combo to the BoundaryInfo object.
1459  bi.add_edge(elem_edge_pair.first,
1460  elem_edge_pair.second,
1461  edge_block_id);
1462  }
1463  } // end loop over elem_edge_pairs
1464  } // end loop over connectivity array
1465 
1466  // Set edgeset name in the BoundaryInfo object.
1467  bi.edgeset_name(edge_block_id) = id_to_edge_block_names[edge_block_id];
1468  } // end if !connect.empty()
1469  } // end for edge_block_id : edge_block_ids
1470 }
std::map< int, std::string > id_to_edge_block_names
MeshBase & mesh
const ExodusII_IO_Helper::Conversion & get_conversion(const ElemType type) const
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Definition: mesh_base.h:165
void message(std::string_view msg)
Prints the message defined in msg.
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
Definition: elem.C:444
The BoundaryInfo class contains information relevant to boundary conditions including storing faces...
Definition: boundary_info.h:57
virtual const Elem * elem_ptr(const dof_id_type i) const =0
std::string & edgeset_name(boundary_id_type id)
virtual const Node * node_ptr(const dof_id_type i) const =0
std::vector< int > edge_block_ids
static ElemType first_order_equivalent_type(const ElemType et)
Definition: elem.C:3066
uint8_t dof_id_type
Definition: id_types.h:67
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...

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

References libMesh::ExodusII_IO_Helper::bex_cv_conn, libMesh::ExodusII_IO_Helper::bex_num_elem_cvs, libMesh::ExodusII_IO_Helper::block_ids, libMesh::ExodusII_IO_Helper::connect, 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::message(), libMesh::ExodusII_IO_Helper::num_attr, libMesh::ExodusII_IO_Helper::num_elem_this_blk, libMesh::ExodusII_IO_Helper::num_nodes_per_elem, libMesh::out, and libMesh::ExodusII_IO_Helper::verbose.

1147 {
1148  LOG_SCOPE("read_elem_in_block()", "ExodusII_IO_Helper");
1149 
1150  libmesh_assert_less (block, block_ids.size());
1151 
1152  // Unlike the other "extended" APIs, this one does not use a parameter struct.
1153  int num_edges_per_elem = 0;
1154  int num_faces_per_elem = 0;
1155  int num_node_data_per_elem = 0;
1156  ex_err = exII::ex_get_block(ex_id,
1157  exII::EX_ELEM_BLOCK,
1158  block_ids[block],
1159  elem_type.data(),
1161  &num_node_data_per_elem,
1162  &num_edges_per_elem, // 0 or -1 if no "extended" block info
1163  &num_faces_per_elem, // 0 or -1 if no "extended" block info
1164  &num_attr);
1165 
1166  EX_CHECK_ERR(ex_err, "Error getting block info.");
1167  message("Info retrieved successfully for block: ", block);
1168 
1169  // Warn that we don't currently support reading blocks with extended info.
1170  // Note: the docs say -1 will be returned for this but I found that it was
1171  // actually 0, so not sure which it will be in general.
1172  if (!(num_edges_per_elem == 0) && !(num_edges_per_elem == -1))
1173  libmesh_warning("Exodus files with extended edge connectivity not currently supported.");
1174  if (!(num_faces_per_elem == 0) && !(num_faces_per_elem == -1))
1175  libmesh_warning("Exodus files with extended face connectivity not currently supported.");
1176 
1177  // If we have a Bezier element here, then we've packed constraint
1178  // vector connectivity at the end of the nodal connectivity, and
1179  // num_nodes_per_elem reflected both.
1180  const bool is_bezier = is_bezier_elem(elem_type.data());
1181  if (is_bezier)
1182  {
1183  const auto & conv = get_conversion(std::string(elem_type.data()));
1184  num_nodes_per_elem = conv.n_nodes;
1185  }
1186  else
1187  num_nodes_per_elem = num_node_data_per_elem;
1188 
1189  if (verbose)
1190  libMesh::out << "Read a block of " << num_elem_this_blk
1191  << " " << elem_type.data() << "(s)"
1192  << " having " << num_nodes_per_elem
1193  << " nodes per element." << std::endl;
1194 
1195  // Read in the connectivity of the elements of this block,
1196  // watching out for the case where we actually have no
1197  // elements in this block (possible with parallel files)
1198  connect.resize(num_node_data_per_elem*num_elem_this_blk);
1199 
1200  if (!connect.empty())
1201  {
1202  ex_err = exII::ex_get_conn(ex_id,
1203  exII::EX_ELEM_BLOCK,
1204  block_ids[block],
1205  connect.data(), // node_conn
1206  nullptr, // elem_edge_conn (unused)
1207  nullptr); // elem_face_conn (unused)
1208 
1209  EX_CHECK_ERR(ex_err, "Error reading block connectivity.");
1210  message("Connectivity retrieved successfully for block: ", block);
1211  }
1212 
1213  // If we had any attributes for this block, check to see if some of
1214  // them were Bezier-extension attributes.
1215 
1216  // num_attr above is zero, not actually the number of block attributes?
1217  // ex_get_attr_param *also* gives me zero? Really, Exodus?
1218 #if EX_API_VERS_NODOT >= 800
1219  int real_n_attr = exII::ex_get_attribute_count(ex_id, exII::EX_ELEM_BLOCK, block_ids[block]);
1220  EX_CHECK_ERR(real_n_attr, "Error getting number of element block attributes.");
1221 
1222  if (real_n_attr > 0)
1223  {
1224  std::vector<exII::ex_attribute> attributes(real_n_attr);
1225 
1226  ex_err = exII::ex_get_attribute_param(ex_id, exII::EX_ELEM_BLOCK, block_ids[block], attributes.data());
1227  EX_CHECK_ERR(ex_err, "Error getting element block attribute parameters.");
1228 
1229  ex_err = exII::ex_get_attributes(ex_id, real_n_attr, attributes.data());
1230  EX_CHECK_ERR(ex_err, "Error getting element block attribute values.");
1231 
1232  for (auto attr : attributes)
1233  {
1234  if (std::string("bex_elem_degrees") == attr.name)
1235  {
1236  if (attr.type != exII::EX_INTEGER)
1237  libmesh_error_msg("Found non-integer bex_elem_degrees");
1238 
1239  if (attr.value_count > 3)
1240  libmesh_error_msg("Looking for at most 3 bex_elem_degrees; found " << attr.value_count);
1241 
1242  libmesh_assert(is_bezier);
1243 
1244  std::vector<int> bex_elem_degrees(3); // max dim
1245 
1246  const int * as_int = static_cast<int *>(attr.values);
1247  std::copy(as_int, as_int+attr.value_count, bex_elem_degrees.begin());
1248 
1249 
1250  // Right now Bezier extraction elements aren't possible
1251  // for p>2 and aren't useful for p<2, and we don't
1252  // support anisotropic p...
1253 #ifndef NDEBUG
1254  const auto & conv = get_conversion(std::string(elem_type.data()));
1255 
1256  for (auto d : IntRange<int>(0, conv.dim))
1257  libmesh_assert_equal_to(bex_elem_degrees[d], 2);
1258 #endif
1259  }
1260  // ex_get_attributes did a values=calloc(); free() is our job.
1261  if (attr.values)
1262  free(attr.values);
1263  }
1264  }
1265 
1266  if (is_bezier)
1267  {
1268  // We'd better have the number of cvs we expect
1269  if( num_node_data_per_elem > num_nodes_per_elem )
1270  bex_num_elem_cvs = num_node_data_per_elem / 2;
1271  else
1273  libmesh_assert_greater_equal(bex_num_elem_cvs, 0);
1274 
1275  // The old connect vector is currently a mix of the expected
1276  // connectivity and any Bezier extraction connectivity;
1277  // disentangle that, if necessary.
1279  if (num_node_data_per_elem > num_nodes_per_elem)
1280  {
1281  std::vector<int> old_connect(bex_num_elem_cvs * num_elem_this_blk);
1282  old_connect.swap(connect);
1283  auto src = old_connect.data();
1284  auto dst = connect.data();
1285  for (auto e : IntRange<std::size_t>(0, num_elem_this_blk))
1286  {
1287  std::copy(src, src + bex_num_elem_cvs, dst);
1288  src += bex_num_elem_cvs;
1289  dst += bex_num_elem_cvs;
1290 
1291  bex_cv_conn[e].resize(bex_num_elem_cvs);
1292  std::copy(src, src + bex_num_elem_cvs,
1293  bex_cv_conn[e].begin());
1294  src += bex_num_elem_cvs;
1295  }
1296  }
1297  }
1298 
1299 #endif // EX_API_VERS_NODOT >= 800
1300 }
The IntRange templated class is intended to make it easy to loop over integers which are indices of a...
Definition: int_range.h:53
const ExodusII_IO_Helper::Conversion & get_conversion(const ElemType type) const
void message(std::string_view msg)
Prints the message defined in msg.
libmesh_assert(ctx)
OStreamProxy out
std::vector< std::vector< long unsigned int > > bex_cv_conn

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

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.

1475 {
1476  elem_num_map.resize(num_elem);
1477 
1478  // Note: we cannot use the exII::ex_get_num_map() here because it
1479  // (apparently) does not behave like ex_get_elem_num_map() when
1480  // there is no elem number map in the file: it throws an error
1481  // instead of returning a default identity array (1,2,3,...).
1482  ex_err = exII::ex_get_elem_num_map
1483  (ex_id, elem_num_map.empty() ? nullptr : elem_num_map.data());
1484 
1485  EX_CHECK_ERR(ex_err, "Error retrieving element number map.");
1486  message("Element numbering map retrieved successfully.");
1487 
1488  if (num_elem)
1489  {
1490  auto it = std::max_element(elem_num_map.begin(), elem_num_map.end());
1491  _end_elem_id = *it;
1492  }
1493  else
1494  _end_elem_id = 0;
1495 
1496  if (verbose)
1497  {
1498  libMesh::out << "[" << this->processor_id() << "] elem_num_map[i] = ";
1499  for (unsigned int i=0; i<static_cast<unsigned int>(std::min(10, num_elem-1)); ++i)
1500  libMesh::out << elem_num_map[i] << ", ";
1501  libMesh::out << "... " << elem_num_map.back() << std::endl;
1502  }
1503 }
void message(std::string_view msg)
Prints the message defined in msg.
OStreamProxy out
processor_id_type processor_id() const

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

References libMesh::ExodusII_IO_Helper::_single_precision, libMesh::ExodusII_IO_Helper::block_ids, libMesh::ExodusII_IO_Helper::elem_num_map, 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::num_elem_blk, libMesh::ExodusII_IO_Helper::num_elem_this_blk, and libMesh::ExodusII_IO_Helper::read_var_names().

2061 {
2062  LOG_SCOPE("read_elemental_var_values()", "ExodusII_IO_Helper");
2063 
2064  this->read_var_names(ELEMENTAL);
2065 
2066  // See if we can find the variable we are looking for
2067  unsigned int var_index = 0;
2068  bool found = false;
2069 
2070  // Do a linear search for elem_var_name in elemental_var_names
2071  for (; var_index != elem_var_names.size(); ++var_index)
2072  if (elem_var_names[var_index] == elemental_var_name)
2073  {
2074  found = true;
2075  break;
2076  }
2077 
2078  if (!found)
2079  {
2080  libMesh::err << "Available variables: " << std::endl;
2081  for (const auto & var_name : elem_var_names)
2082  libMesh::err << var_name << std::endl;
2083 
2084  libmesh_error_msg("Unable to locate variable named: " << elemental_var_name);
2085  }
2086 
2087  // Sequential index which we can use to look up the element ID in the elem_num_map.
2088  unsigned ex_el_num = 0;
2089 
2090  // Element variable truth table
2091  std::vector<int> var_table(block_ids.size() * elem_var_names.size());
2092  exII::ex_get_truth_table(ex_id, exII::EX_ELEM_BLOCK, block_ids.size(), elem_var_names.size(), var_table.data());
2093 
2094  for (unsigned i=0; i<static_cast<unsigned>(num_elem_blk); i++)
2095  {
2096  ex_err = exII::ex_get_block(ex_id,
2097  exII::EX_ELEM_BLOCK,
2098  block_ids[i],
2099  /*elem_type=*/nullptr,
2101  /*num_nodes_per_entry=*/nullptr,
2102  /*num_edges_per_entry=*/nullptr,
2103  /*num_faces_per_entry=*/nullptr,
2104  /*num_attr=*/nullptr);
2105  EX_CHECK_ERR(ex_err, "Error getting number of elements in block.");
2106 
2107  // If the current variable isn't active on this subdomain, advance
2108  // the index by the number of elements on this block and go to the
2109  // next loop iteration.
2110  if (!var_table[elem_var_names.size()*i + var_index])
2111  {
2112  ex_el_num += num_elem_this_blk;
2113  continue;
2114  }
2115 
2116  std::vector<Real> block_elem_var_values(num_elem_this_blk);
2117 
2118  ex_err = exII::ex_get_var
2119  (ex_id,
2120  time_step,
2121  exII::EX_ELEM_BLOCK,
2122  var_index+1,
2123  block_ids[i],
2125  MappedInputVector(block_elem_var_values, _single_precision).data());
2126  EX_CHECK_ERR(ex_err, "Error getting elemental values.");
2127 
2128  for (unsigned j=0; j<static_cast<unsigned>(num_elem_this_blk); j++)
2129  {
2130  // Use the elem_num_map to obtain the ID of this element in the Exodus file,
2131  // and remember to subtract 1 since libmesh is zero-based and Exodus is 1-based.
2132  unsigned mapped_elem_id = this->elem_num_map[ex_el_num] - 1;
2133 
2134  // Store the elemental value in the map.
2135  elem_var_value_map[mapped_elem_id] = block_elem_var_values[j];
2136 
2137  // Go to the next sequential element ID.
2138  ex_el_num++;
2139  }
2140  }
2141 }
OStreamProxy err
std::vector< std::string > elem_var_names
void read_var_names(ExodusVarType type)

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

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

1659 {
1660  LOG_SCOPE("read_elemset()", "ExodusII_IO_Helper");
1661 
1662  libmesh_assert_less (id, elemset_ids.size());
1663  libmesh_assert_less (id, num_elems_per_set.size());
1664  libmesh_assert_less (id, num_elem_df_per_set.size());
1665  libmesh_assert_less_equal (offset, elemset_list.size());
1666 
1667  ex_err = exII::ex_get_set_param(ex_id,
1668  exII::EX_ELEM_SET,
1669  elemset_ids[id],
1670  &num_elems_per_set[id],
1671  &num_elem_df_per_set[id]);
1672  EX_CHECK_ERR(ex_err, "Error retrieving elemset parameters.");
1673  message("Parameters retrieved successfully for elemset: ", id);
1674 
1675 
1676  // It's OK for offset==elemset_list.size() as long as num_elems_per_set[id]==0
1677  // because in that case we don't actually read anything...
1678  #ifdef DEBUG
1679  if (static_cast<unsigned int>(offset) == elemset_list.size())
1680  libmesh_assert_equal_to (num_elems_per_set[id], 0);
1681  #endif
1682 
1683  // Don't call ex_get_set() unless there are actually elems there to get.
1684  // Exodus prints an annoying warning in DEBUG mode otherwise...
1685  if (num_elems_per_set[id] > 0)
1686  {
1687  ex_err = exII::ex_get_set(ex_id,
1688  exII::EX_ELEM_SET,
1689  elemset_ids[id],
1690  &elemset_list[offset],
1691  /*set_extra_list=*/nullptr);
1692  EX_CHECK_ERR(ex_err, "Error retrieving elemset data.");
1693  message("Data retrieved successfully for elemset: ", id);
1694 
1695  // Create vector containing elemset ids for each element in the set
1696  for (int i=0; i<num_elems_per_set[id]; i++)
1697  elemset_id_list[i+offset] = elemset_ids[id];
1698  }
1699 }
std::vector< int > num_elems_per_set
void message(std::string_view msg)
Prints the message defined in msg.
std::vector< int > elemset_id_list
std::vector< int > num_elem_df_per_set

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

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

4038 {
4039  LOG_SCOPE("read_elemset_data()", "ExodusII_IO_Helper");
4040 
4041  // This reads the elemset variable names into the local
4042  // elemset_var_names data structure.
4043  this->read_var_names(ELEMSET);
4044 
4045  // Debugging
4046  // libMesh::out << "elmeset variable names:" << std::endl;
4047  // for (const auto & name : elemset_var_names)
4048  // libMesh::out << name << " ";
4049  // libMesh::out << std::endl;
4050 
4051  if (num_elemset_vars)
4052  {
4053  // Debugging
4054  // std::cout << "Reading " << num_elem_sets
4055  // << " elemsets and " << num_elemset_vars
4056  // << " elemset variables." << std::endl;
4057 
4058  // Read the elemset data truth table.
4059  std::vector<int> elemset_var_tab(num_elem_sets * num_elemset_vars);
4060  exII::ex_get_truth_table(ex_id,
4061  exII::EX_ELEM_SET, // exII::ex_entity_type
4062  num_elem_sets,
4064  elemset_var_tab.data());
4065  EX_CHECK_ERR(ex_err, "Error reading elemset variable truth table.");
4066 
4067  // Debugging
4068  // libMesh::out << "Elemset variable truth table:" << std::endl;
4069  // for (const auto & val : elemset_var_tab)
4070  // libMesh::out << val << " ";
4071  // libMesh::out << std::endl;
4072 
4073  // Debugging
4074  // for (auto i : make_range(num_elem_sets))
4075  // {
4076  // for (auto j : make_range(num_elemset_vars))
4077  // libMesh::out << elemset_var_tab[num_elemset_vars*i + j] << " ";
4078  // libMesh::out << std::endl;
4079  // }
4080 
4081  // Set up/allocate space in incoming data structures. All vectors are
4082  // num_elemset_vars in length.
4083  var_names = elemset_var_names;
4084  elemset_ids_in.resize(num_elemset_vars);
4085  elemset_vals.resize(num_elemset_vars);
4086 
4087  // Read the elemset data
4088  int offset=0;
4089  for (int es=0; es<num_elem_sets; ++es)
4090  {
4091  offset += (es > 0 ? num_elems_per_set[es-1] : 0);
4092  for (int var=0; var<num_elemset_vars; ++var)
4093  {
4094  int is_present = elemset_var_tab[num_elemset_vars*es + var];
4095 
4096  if (is_present)
4097  {
4098  // Debugging
4099  // libMesh::out << "Variable " << var << " is present on elemset " << es << std::endl;
4100 
4101  // Record the fact that this variable is defined on this elemset.
4102  elemset_ids_in[var].insert(elemset_ids[es]);
4103 
4104  // Note: the assumption here is that a previous call
4105  // to this->read_elemset_info() has already set the
4106  // values of num_elems_per_set, so we just use those values here.
4107  std::vector<Real> elemset_var_vals(num_elems_per_set[es]);
4108  ex_err = exII::ex_get_var
4109  (ex_id,
4110  timestep,
4111  exII::EX_ELEM_SET, // exII::ex_entity_type
4112  var + 1, // 1-based sideset variable index!
4113  elemset_ids[es],
4114  num_elems_per_set[es],
4115  MappedInputVector(elemset_var_vals, _single_precision).data());
4116  EX_CHECK_ERR(ex_err, "Error reading elemset variable.");
4117 
4118  for (int i=0; i<num_elems_per_set[es]; ++i)
4119  {
4120  dof_id_type exodus_elem_id = elemset_list[i + offset];
4121 
4122  // FIXME: We should use exodus_elem_num_to_libmesh for this,
4123  // but it apparently is never set up, so just
4124  // subtract 1 from the Exodus elem id.
4125  dof_id_type converted_elem_id = exodus_elem_id - 1;
4126 
4127  // Make key based on the elem and set ids
4128  auto key = std::make_pair(converted_elem_id,
4129  static_cast<elemset_id_type>(elemset_ids[es]));
4130 
4131  // Store value in the map
4132  elemset_vals[var].emplace(key, elemset_var_vals[i]);
4133  } // end for (i)
4134  } // end if (present)
4135  } // end for (var)
4136  } // end for (es)
4137  } // end if (num_elemset_vars)
4138 }
std::vector< int > num_elems_per_set
void read_var_names(ExodusVarType type)
std::vector< std::string > elemset_var_names
uint8_t dof_id_type
Definition: id_types.h:67

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

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

1572 {
1573  elemset_ids.resize(num_elem_sets);
1574  if (num_elem_sets > 0)
1575  {
1576  ex_err = exII::ex_get_ids(ex_id,
1577  exII::EX_ELEM_SET,
1578  elemset_ids.data());
1579  EX_CHECK_ERR(ex_err, "Error retrieving elemset information.");
1580  message("All elemset information retrieved successfully.");
1581 
1582  // Resize appropriate data structures -- only do this once outside the loop
1585 
1586  // Inquire about the length of the concatenated elemset list
1588  inquire(*this, exII::EX_INQ_ELS_LEN,
1589  "Error retrieving length of the concatenated elem sets element list!");
1590 
1593 
1594  // Debugging
1595  // libMesh::out << "num_elem_all_elemsets = " << num_elem_all_elemsets << std::endl;
1596  }
1597 
1598  char name_buffer[MAX_STR_LENGTH+1];
1599  for (int i=0; i<num_elem_sets; ++i)
1600  {
1601  ex_err = exII::ex_get_name(ex_id, exII::EX_ELEM_SET,
1602  elemset_ids[i], name_buffer);
1603  EX_CHECK_ERR(ex_err, "Error getting node set name.");
1604  id_to_elemset_names[elemset_ids[i]] = name_buffer;
1605  }
1606  message("All elem set names retrieved successfully.");
1607 }
std::vector< int > num_elems_per_set
void message(std::string_view msg)
Prints the message defined in msg.
std::map< int, std::string > id_to_elemset_names
std::vector< int > elemset_id_list
std::vector< int > num_elem_df_per_set

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

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

4651 {
4652  if ((_run_only_on_proc0) && (this->processor_id() != 0))
4653  return;
4654 
4655  values.clear();
4656  values.resize(num_global_vars);
4657  ex_err = exII::ex_get_var
4658  (ex_id,
4659  timestep,
4660  exII::EX_GLOBAL,
4661  1, // var_index
4662  1, // obj_id
4664  MappedInputVector(values, _single_precision).data());
4665 
4666  EX_CHECK_ERR(ex_err, "Error reading global values.");
4667 }
processor_id_type processor_id() const

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

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

707 {
708  // Read init params using newer API that reads into a struct. For
709  // backwards compatibility, assign local member values from struct
710  // afterwards. Note: using the new API allows us to automatically
711  // read edge and face block/set information if it's present in the
712  // file.
713  exII::ex_init_params params = {};
714  int err_flag = exII::ex_get_init_ext(ex_id, &params);
715  EX_CHECK_ERR(err_flag, "Error retrieving header info.");
716 
717  // Extract required data into our struct
719  h.title.assign(params.title, params.title + MAX_LINE_LENGTH);
720  h.num_dim = params.num_dim;
721  h.num_nodes = params.num_nodes;
722  h.num_elem = params.num_elem;
723  h.num_elem_blk = params.num_elem_blk;
724  h.num_node_sets = params.num_node_sets;
725  h.num_side_sets = params.num_side_sets;
726  h.num_elem_sets = params.num_elem_sets;
727  h.num_edge_blk = params.num_edge_blk;
728  h.num_edge = params.num_edge;
729 
730  // And return it
731  return h;
732 }
This class is used as both an external data structure for passing around Exodus file header informati...
std::vector< char > title

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

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::NODAL, libMesh::ExodusII_IO_Helper::nodal_var_names, libMesh::ExodusII_IO_Helper::nodal_var_values, libMesh::ExodusII_IO_Helper::node_num_map, libMesh::ExodusII_IO_Helper::num_nodes, and libMesh::ExodusII_IO_Helper::read_var_names().

1838 {
1839  LOG_SCOPE("read_nodal_var_values()", "ExodusII_IO_Helper");
1840 
1841  // Read the nodal variable names from file, so we can see if we have the one we're looking for
1842  this->read_var_names(NODAL);
1843 
1844  // See if we can find the variable we are looking for
1845  unsigned int var_index = 0;
1846  bool found = false;
1847 
1848  // Do a linear search for nodal_var_name in nodal_var_names
1849  for (; var_index<nodal_var_names.size(); ++var_index)
1850  {
1851  found = (nodal_var_names[var_index] == nodal_var_name);
1852  if (found)
1853  break;
1854  }
1855 
1856  if (!found)
1857  {
1858  libMesh::err << "Available variables: " << std::endl;
1859  for (const auto & var_name : nodal_var_names)
1860  libMesh::err << var_name << std::endl;
1861 
1862  libmesh_error_msg("Unable to locate variable named: " << nodal_var_name);
1863  }
1864 
1865  // Clear out any previously read nodal variable values
1866  nodal_var_values.clear();
1867 
1868  std::vector<Real> unmapped_nodal_var_values(num_nodes);
1869 
1870  // Call the Exodus API to read the nodal variable values
1871  ex_err = exII::ex_get_var
1872  (ex_id,
1873  time_step,
1874  exII::EX_NODAL,
1875  var_index+1,
1876  1, // exII::ex_entity_id, not sure exactly what this is but in the ex_get_nodal_var.c shim, they pass 1
1877  num_nodes,
1878  MappedInputVector(unmapped_nodal_var_values, _single_precision).data());
1879  EX_CHECK_ERR(ex_err, "Error reading nodal variable values!");
1880 
1881  for (unsigned i=0; i<static_cast<unsigned>(num_nodes); i++)
1882  {
1883  libmesh_assert_less(i, this->node_num_map.size());
1884 
1885  // Use the node_num_map to obtain the ID of this node in the Exodus file,
1886  // and remember to subtract 1 since libmesh is zero-based and Exodus is 1-based.
1887  const unsigned mapped_node_id = this->node_num_map[i] - 1;
1888 
1889  libmesh_assert_less(i, unmapped_nodal_var_values.size());
1890 
1891  // Store the nodal value in the map.
1892  nodal_var_values[mapped_node_id] = unmapped_nodal_var_values[i];
1893  }
1894 }
OStreamProxy err
std::map< dof_id_type, Real > nodal_var_values
void read_var_names(ExodusVarType type)
std::vector< std::string > nodal_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 897 of file exodusII_io_helper.C.

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.

898 {
899  node_num_map.resize(num_nodes);
900 
901  // Note: we cannot use the exII::ex_get_num_map() here because it
902  // (apparently) does not behave like ex_get_node_num_map() when
903  // there is no node number map in the file: it throws an error
904  // instead of returning a default identity array (1,2,3,...).
905  ex_err = exII::ex_get_node_num_map
906  (ex_id, node_num_map.empty() ? nullptr : node_num_map.data());
907 
908  EX_CHECK_ERR(ex_err, "Error retrieving nodal number map.");
909  message("Nodal numbering map retrieved successfully.");
910 
911  if (verbose)
912  {
913  libMesh::out << "[" << this->processor_id() << "] node_num_map[i] = ";
914  for (unsigned int i=0; i<static_cast<unsigned int>(std::min(10, num_nodes-1)); ++i)
915  libMesh::out << node_num_map[i] << ", ";
916  libMesh::out << "... " << node_num_map.back() << std::endl;
917  }
918 }
void message(std::string_view msg)
Prints the message defined in msg.
OStreamProxy out
processor_id_type processor_id() const

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

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.

847 {
848  LOG_SCOPE("read_nodes()", "ExodusII_IO_Helper");
849 
850  x.resize(num_nodes);
851  y.resize(num_nodes);
852  z.resize(num_nodes);
853 
854  if (num_nodes)
855  {
856  ex_err = exII::ex_get_coord
857  (ex_id,
858  MappedInputVector(x, _single_precision).data(),
859  MappedInputVector(y, _single_precision).data(),
860  MappedInputVector(z, _single_precision).data());
861 
862  EX_CHECK_ERR(ex_err, "Error retrieving nodal data.");
863  message("Nodal data retrieved successfully.");
864  }
865 
866  // If a nodal attribute bex_weight exists, we get spline weights
867  // from it
868  int n_nodal_attr = 0;
869  ex_err = exII::ex_get_attr_param(ex_id, exII::EX_NODAL, 0, & n_nodal_attr);
870  EX_CHECK_ERR(ex_err, "Error getting number of nodal attributes.");
871 
872  if (n_nodal_attr > 0)
873  {
874  std::vector<std::vector<char>> attr_name_data
875  (n_nodal_attr, std::vector<char>(MAX_STR_LENGTH + 1));
876  std::vector<char *> attr_names(n_nodal_attr);
877  for (auto i : index_range(attr_names))
878  attr_names[i] = attr_name_data[i].data();
879 
880  ex_err = exII::ex_get_attr_names(ex_id, exII::EX_NODAL, 0, attr_names.data());
881  EX_CHECK_ERR(ex_err, "Error getting nodal attribute names.");
882 
883  for (auto i : index_range(attr_names))
884  if (std::string("bex_weight") == attr_names[i])
885  {
886  w.resize(num_nodes);
887  ex_err =
888  exII::ex_get_one_attr (ex_id, exII::EX_NODAL, 0, i+1,
889  MappedInputVector(w, _single_precision).data());
890  EX_CHECK_ERR(ex_err, "Error getting Bezier Extraction nodal weights");
891  }
892  }
893 }
void message(std::string_view msg)
Prints the message defined in msg.
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:117

◆ 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 99 of file nemesis_io_helper.C.

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.

100 {
101  libmesh_assert_less (id, nodeset_ids.size());
102  libmesh_assert_less (id, num_nodes_per_set.size());
103  libmesh_assert_less (id, num_node_df_per_set.size());
104 
105  ex_err = exII::ex_get_set_param(ex_id,
106  exII::EX_NODE_SET,
107  nodeset_ids[id],
108  &num_nodes_per_set[id],
109  &num_node_df_per_set[id]);
110  EX_CHECK_ERR(ex_err, "Error retrieving nodeset parameters.");
111  message("Parameters retrieved successfully for nodeset: ", id);
112 
113  node_list.resize(num_nodes_per_set[id]);
114 
115  // Don't call ex_get_set unless there are actually nodes there to get.
116  // Exodus prints an annoying warning message in DEBUG mode otherwise...
117  if (num_nodes_per_set[id] > 0)
118  {
119  ex_err = exII::ex_get_set(ex_id,
120  exII::EX_NODE_SET,
121  nodeset_ids[id],
122  node_list.data(),
123  nullptr); // set_extra_list, ignored for node sets
124 
125  EX_CHECK_ERR(ex_err, "Error retrieving nodeset data.");
126  message("Data retrieved successfully for nodeset: ", id);
127  }
128 }
std::vector< int > node_list
void message(std::string_view msg)
Prints the message defined in msg.
std::vector< int > num_node_df_per_set
std::vector< int > 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 4186 of file exodusII_io_helper.C.

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

4190 {
4191  LOG_SCOPE("read_nodeset_data()", "ExodusII_IO_Helper");
4192 
4193  // This reads the sideset variable names into the local
4194  // sideset_var_names data structure.
4195  this->read_var_names(NODESET);
4196 
4197  if (num_nodeset_vars)
4198  {
4199  // Read the nodeset data truth table
4200  std::vector<int> nset_var_tab(num_node_sets * num_nodeset_vars);
4201  ex_err = exII::ex_get_truth_table
4202  (ex_id,
4203  exII::EX_NODE_SET,
4204  num_node_sets,
4206  nset_var_tab.data());
4207  EX_CHECK_ERR(ex_err, "Error reading nodeset variable truth table.");
4208 
4209  // Set up/allocate space in incoming data structures.
4210  var_names = nodeset_var_names;
4211  node_boundary_ids.resize(num_nodeset_vars);
4212  bc_vals.resize(num_nodeset_vars);
4213 
4214  // Read the nodeset data.
4215  //
4216  // Note: we assume that the functions
4217  // 1.) this->read_nodeset_info() and
4218  // 2.) this->read_all_nodesets()
4219  // have already been called, so that we already know e.g. how
4220  // many nodes are in each set, their ids, etc.
4221  //
4222  // TODO: As a future optimization, we could read only the values
4223  // requested by the user by looking at the input parameter
4224  // var_names and checking whether it already has entries in
4225  // it.
4226  int offset=0;
4227  for (int ns=0; ns<num_node_sets; ++ns)
4228  {
4229  offset += (ns > 0 ? num_nodes_per_set[ns-1] : 0);
4230  for (int var=0; var<num_nodeset_vars; ++var)
4231  {
4232  int is_present = nset_var_tab[num_nodeset_vars*ns + var];
4233 
4234  if (is_present)
4235  {
4236  // Record the fact that this variable is defined on this nodeset.
4237  node_boundary_ids[var].insert(nodeset_ids[ns]);
4238 
4239  // Note: the assumption here is that a previous call
4240  // to this->read_nodeset_info() has already set the
4241  // values of num_nodes_per_set, so we just use those values here.
4242  std::vector<Real> nset_var_vals(num_nodes_per_set[ns]);
4243  ex_err = exII::ex_get_var
4244  (ex_id,
4245  timestep,
4246  exII::EX_NODE_SET,
4247  var + 1, // 1-based nodeset variable index!
4248  nodeset_ids[ns],
4249  num_nodes_per_set[ns],
4250  MappedInputVector(nset_var_vals, _single_precision).data());
4251  EX_CHECK_ERR(ex_err, "Error reading nodeset variable.");
4252 
4253  for (int i=0; i<num_nodes_per_set[ns]; ++i)
4254  {
4255  // The read_all_nodesets() function now reads all the node ids into the
4256  // node_sets_node_list vector, which is of length "total_nodes_in_all_sets"
4257  // The old read_nodset() function is no longer called as far as I can tell,
4258  // and should probably be removed? The "offset" that we are using only
4259  // depends on the current nodeset index and the num_nodes_per_set vector,
4260  // which gets filled in by the call to read_all_nodesets().
4261  dof_id_type exodus_node_id = node_sets_node_list[i + offset];
4262 
4263  // FIXME: We should use exodus_node_num_to_libmesh for this,
4264  // but it apparently is never set up, so just
4265  // subtract 1 from the Exodus node id.
4266  dof_id_type converted_node_id = exodus_node_id - 1;
4267 
4268  // Make a NodeBCTuple key from the converted information.
4269  BoundaryInfo::NodeBCTuple key = std::make_tuple
4270  (converted_node_id, nodeset_ids[ns]);
4271 
4272  // Store (node, b_id) tuples in bc_vals[var]
4273  bc_vals[var].emplace(key, nset_var_vals[i]);
4274  } // end for (i)
4275  } // end if (present)
4276  } // end for (var)
4277  } // end for (ns)
4278  } // end if (num_nodeset_vars)
4279 }
std::vector< std::string > nodeset_var_names
std::tuple< dof_id_type, boundary_id_type > NodeBCTuple
As above, but the library creates and fills in a vector of (node-id, bc-id) pairs and returns it to t...
void read_var_names(ExodusVarType type)
std::vector< int > node_sets_node_list
std::vector< int > num_nodes_per_set
uint8_t dof_id_type
Definition: id_types.h:67

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

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.

1543 {
1544  nodeset_ids.resize(num_node_sets);
1545  if (num_node_sets > 0)
1546  {
1547  ex_err = exII::ex_get_ids(ex_id,
1548  exII::EX_NODE_SET,
1549  nodeset_ids.data());
1550  EX_CHECK_ERR(ex_err, "Error retrieving nodeset information.");
1551  message("All nodeset information retrieved successfully.");
1552 
1553  // Resize appropriate data structures -- only do this once outside the loop
1556  }
1557 
1558  char name_buffer[MAX_STR_LENGTH+1];
1559  for (int i=0; i<num_node_sets; ++i)
1560  {
1561  ex_err = exII::ex_get_name(ex_id, exII::EX_NODE_SET,
1562  nodeset_ids[i], name_buffer);
1563  EX_CHECK_ERR(ex_err, "Error getting node set name.");
1564  id_to_ns_names[nodeset_ids[i]] = name_buffer;
1565  }
1566  message("All node set names retrieved successfully.");
1567 }
void message(std::string_view msg)
Prints the message defined in msg.
std::vector< int > num_node_df_per_set
std::map< int, std::string > id_to_ns_names
std::vector< int > 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 1829 of file exodusII_io_helper.C.

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

1830 {
1831  num_time_steps =
1832  inquire(*this, exII::EX_INQ_TIME, "Error retrieving number of time steps");
1833 }

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

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

771 {
772  // The QA records are four MAX_STR_LENGTH-byte character strings.
773  int num_qa_rec =
774  inquire(*this, exII::EX_INQ_QA, "Error retrieving number of QA records");
775 
776  if (verbose)
777  libMesh::out << "Found "
778  << num_qa_rec
779  << " QA record(s) in the Exodus file."
780  << std::endl;
781 
782  if (num_qa_rec > 0)
783  {
784  // Actual (num_qa_rec x 4) storage for strings. The object we
785  // pass to the Exodus API will just contain pointers into the
786  // qa_storage object, which will have all automatic memory
787  // management.
788  std::vector<std::vector<std::vector<char>>> qa_storage(num_qa_rec);
789  for (auto i : make_range(num_qa_rec))
790  {
791  qa_storage[i].resize(4);
792  for (auto j : make_range(4))
793  qa_storage[i][j].resize(MAX_STR_LENGTH+1);
794  }
795 
796  // inner_array_t is a fixed-size array of 4 strings
797  typedef char * inner_array_t[4];
798 
799  // There is at least one compiler (Clang 12.0.1) that complains about
800  // "a non-scalar type used in a pseudo-destructor expression" when
801  // we try to instantiate a std::vector of inner_array_t objects as in:
802  // std::vector<inner_array_t> qa_record(num_qa_rec);
803  // So, we instead attempt to achieve the same effect with a std::unique_ptr.
804  auto qa_record = std::make_unique<inner_array_t[]>(num_qa_rec);
805 
806  // Create data structure to be passed to Exodus API by setting
807  // pointers to the actual strings which are in qa_storage.
808  for (auto i : make_range(num_qa_rec))
809  for (auto j : make_range(4))
810  qa_record[i][j] = qa_storage[i][j].data();
811 
812  ex_err = exII::ex_get_qa (ex_id, qa_record.get());
813  EX_CHECK_ERR(ex_err, "Error reading the QA records.");
814 
815  // Print the QA records
816  if (verbose)
817  {
818  for (auto i : make_range(num_qa_rec))
819  {
820  libMesh::out << "QA Record: " << i << std::endl;
821  for (auto j : make_range(4))
822  libMesh::out << qa_record[i][j] << std::endl;
823  }
824  }
825  }
826 }
OStreamProxy out
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:140

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

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

1612 {
1613  LOG_SCOPE("read_sideset()", "ExodusII_IO_Helper");
1614 
1615  libmesh_assert_less (id, ss_ids.size());
1616  libmesh_assert_less (id, num_sides_per_set.size());
1617  libmesh_assert_less (id, num_df_per_set.size());
1618  libmesh_assert_less_equal (offset, elem_list.size());
1619  libmesh_assert_less_equal (offset, side_list.size());
1620 
1621  ex_err = exII::ex_get_set_param(ex_id,
1622  exII::EX_SIDE_SET,
1623  ss_ids[id],
1624  &num_sides_per_set[id],
1625  &num_df_per_set[id]);
1626  EX_CHECK_ERR(ex_err, "Error retrieving sideset parameters.");
1627  message("Parameters retrieved successfully for sideset: ", id);
1628 
1629 
1630  // It's OK for offset==elem_list.size() as long as num_sides_per_set[id]==0
1631  // because in that case we don't actually read anything...
1632 #ifdef DEBUG
1633  if (static_cast<unsigned int>(offset) == elem_list.size() ||
1634  static_cast<unsigned int>(offset) == side_list.size() )
1635  libmesh_assert_equal_to (num_sides_per_set[id], 0);
1636 #endif
1637 
1638 
1639  // Don't call ex_get_set unless there are actually sides there to get.
1640  // Exodus prints an annoying warning in DEBUG mode otherwise...
1641  if (num_sides_per_set[id] > 0)
1642  {
1643  ex_err = exII::ex_get_set(ex_id,
1644  exII::EX_SIDE_SET,
1645  ss_ids[id],
1646  &elem_list[offset],
1647  &side_list[offset]);
1648  EX_CHECK_ERR(ex_err, "Error retrieving sideset data.");
1649  message("Data retrieved successfully for sideset: ", id);
1650 
1651  for (int i=0; i<num_sides_per_set[id]; i++)
1652  id_list[i+offset] = ss_ids[id];
1653  }
1654 }
std::vector< int > num_sides_per_set
void message(std::string_view msg)
Prints the message defined in msg.
std::vector< int > num_df_per_set

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

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(), libMesh::ExodusII_IO_Helper::Conversion::get_side_map(), 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().

3659 {
3660  LOG_SCOPE("read_sideset_data()", "ExodusII_IO_Helper");
3661 
3662  // This reads the sideset variable names into the local
3663  // sideset_var_names data structure.
3664  this->read_var_names(SIDESET);
3665 
3666  if (num_sideset_vars)
3667  {
3668  // Read the sideset data truth table
3669  std::vector<int> sset_var_tab(num_side_sets * num_sideset_vars);
3670  ex_err = exII::ex_get_truth_table
3671  (ex_id,
3672  exII::EX_SIDE_SET,
3673  num_side_sets,
3675  sset_var_tab.data());
3676  EX_CHECK_ERR(ex_err, "Error reading sideset variable truth table.");
3677 
3678  // Set up/allocate space in incoming data structures.
3679  var_names = sideset_var_names;
3680  side_ids.resize(num_sideset_vars);
3681  bc_vals.resize(num_sideset_vars);
3682 
3683  // Read the sideset data.
3684  //
3685  // Note: we assume that read_sideset() has already been called
3686  // for each sideset, so the required values in elem_list and
3687  // side_list are already present.
3688  //
3689  // TODO: As a future optimization, we could read only the values
3690  // requested by the user by looking at the input parameter
3691  // var_names and checking whether it already has entries in
3692  // it. We could do the same thing with the input side_ids
3693  // container and only read values for requested sidesets.
3694  int offset=0;
3695  for (int ss=0; ss<num_side_sets; ++ss)
3696  {
3697  offset += (ss > 0 ? num_sides_per_set[ss-1] : 0);
3698  for (int var=0; var<num_sideset_vars; ++var)
3699  {
3700  int is_present = sset_var_tab[num_sideset_vars*ss + var];
3701 
3702  if (is_present)
3703  {
3704  // Record the fact that this variable is defined on this sideset.
3705  side_ids[var].insert(ss_ids[ss]);
3706 
3707  // Note: the assumption here is that a previous call
3708  // to this->read_sideset_info() has already set the
3709  // values of num_sides_per_set, so we just use those values here.
3710  std::vector<Real> sset_var_vals(num_sides_per_set[ss]);
3711  ex_err = exII::ex_get_var
3712  (ex_id,
3713  timestep,
3714  exII::EX_SIDE_SET,
3715  var + 1, // 1-based sideset variable index!
3716  ss_ids[ss],
3717  num_sides_per_set[ss],
3718  MappedInputVector(sset_var_vals, _single_precision).data());
3719  EX_CHECK_ERR(ex_err, "Error reading sideset variable.");
3720 
3721  for (int i=0; i<num_sides_per_set[ss]; ++i)
3722  {
3723  dof_id_type exodus_elem_id = elem_list[i + offset];
3724  unsigned int exodus_side_id = side_list[i + offset];
3725 
3726  // FIXME: We should use exodus_elem_num_to_libmesh for this,
3727  // but it apparently is never set up, so just
3728  // subtract 1 from the Exodus elem id.
3729  dof_id_type converted_elem_id = exodus_elem_id - 1;
3730 
3731  // Map Exodus side id to libmesh side id.
3732  // Map from Exodus side ids to libmesh side ids.
3733  const auto & conv = get_conversion(mesh.elem_ptr(converted_elem_id)->type());
3734 
3735  // Map from Exodus side id to libmesh side id.
3736  // Note: the mapping is defined on 0-based indices, so subtract
3737  // 1 before doing the mapping.
3738  unsigned int converted_side_id = conv.get_side_map(exodus_side_id - 1);
3739 
3740  // Make a BCTuple key from the converted information.
3741  BoundaryInfo::BCTuple key = std::make_tuple
3742  (converted_elem_id,
3743  converted_side_id,
3744  ss_ids[ss]);
3745 
3746  // Store (elem, side, b_id) tuples in bc_vals[var]
3747  bc_vals[var].emplace(key, sset_var_vals[i]);
3748  } // end for (i)
3749  } // end if (present)
3750  } // end for (var)
3751  } // end for (ss)
3752  } // end if (num_sideset_vars)
3753 }
std::tuple< dof_id_type, unsigned short int, boundary_id_type > BCTuple
As above, but the library creates and fills in a vector of (elem-id, side-id, bc-id) triplets and ret...
std::vector< std::string > sideset_var_names
std::vector< int > num_sides_per_set
MeshBase & mesh
const ExodusII_IO_Helper::Conversion & get_conversion(const ElemType type) const
void read_var_names(ExodusVarType type)
virtual const Elem * elem_ptr(const dof_id_type i) const =0
virtual ElemType type() const =0
uint8_t dof_id_type
Definition: id_types.h:67

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

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

1508 {
1509  ss_ids.resize(num_side_sets);
1510  if (num_side_sets > 0)
1511  {
1512  ex_err = exII::ex_get_ids(ex_id,
1513  exII::EX_SIDE_SET,
1514  ss_ids.data());
1515  EX_CHECK_ERR(ex_err, "Error retrieving sideset information.");
1516  message("All sideset information retrieved successfully.");
1517 
1518  // Resize appropriate data structures -- only do this once outside the loop
1520  num_df_per_set.resize(num_side_sets);
1521 
1522  // Inquire about the length of the concatenated side sets element list
1523  num_elem_all_sidesets = inquire(*this, exII::EX_INQ_SS_ELEM_LEN, "Error retrieving length of the concatenated side sets element list!");
1524 
1527  id_list.resize (num_elem_all_sidesets);
1528  }
1529 
1530  char name_buffer[MAX_STR_LENGTH+1];
1531  for (int i=0; i<num_side_sets; ++i)
1532  {
1533  ex_err = exII::ex_get_name(ex_id, exII::EX_SIDE_SET,
1534  ss_ids[i], name_buffer);
1535  EX_CHECK_ERR(ex_err, "Error getting side set name.");
1536  id_to_ss_names[ss_ids[i]] = name_buffer;
1537  }
1538  message("All side set names retrieved successfully.");
1539 }
std::vector< int > num_sides_per_set
std::map< int, std::string > id_to_ss_names
void message(std::string_view msg)
Prints the message defined in msg.
std::vector< int > num_df_per_set

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

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.

1813 {
1814  // Make sure we have an up-to-date count of the number of time steps in the file.
1815  this->read_num_time_steps();
1816 
1817  if (num_time_steps > 0)
1818  {
1819  time_steps.resize(num_time_steps);
1820  ex_err = exII::ex_get_all_times
1821  (ex_id,
1822  MappedInputVector(time_steps, _single_precision).data());
1823  EX_CHECK_ERR(ex_err, "Error reading timesteps!");
1824  }
1825 }
std::vector< Real > time_steps
void read_num_time_steps()
Reads the number of timesteps currently stored in the Exodus file and stores it in the num_time_steps...

◆ read_var_names()

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

Definition at line 1898 of file exodusII_io_helper.C.

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

1899 {
1900  switch (type)
1901  {
1902  case NODAL:
1904  break;
1905  case ELEMENTAL:
1907  break;
1908  case GLOBAL:
1910  break;
1911  case SIDESET:
1913  break;
1914  case NODESET:
1916  break;
1917  case ELEMSET:
1919  break;
1920  default:
1921  libmesh_error_msg("Unrecognized ExodusVarType " << type);
1922  }
1923 }
std::vector< std::string > sideset_var_names
std::vector< std::string > elem_var_names
virtual void read_var_names_impl(const char *var_type, int &count, std::vector< std::string > &result)
read_var_names() dispatches to this function.
std::vector< std::string > nodeset_var_names
std::vector< std::string > global_var_names
std::vector< std::string > elemset_var_names
std::vector< std::string > nodal_var_names

◆ 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 2742 of file nemesis_io_helper.C.

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

2745 {
2746  // Most of what we need to do is the same as for Exodus
2747  this->ExodusII_IO_Helper::read_var_names_impl(var_type, count, result);
2748 
2749  // But with tests where we have more processors than elements,
2750  // Nemesis doesn't let us put variable names in files written by
2751  // processors owning nothing, but we may still *need* those
2752  // variable names on every processor, so let's sync them up...
2753 
2754  processor_id_type pid_broadcasting_names = this->processor_id();
2755  const std::size_t n_names = result.size();
2756  if (!n_names)
2757  pid_broadcasting_names = DofObject::invalid_processor_id;
2758 
2759  libmesh_assert(this->comm().semiverify
2760  (n_names ? nullptr : &n_names));
2761 
2762  this->comm().min(pid_broadcasting_names);
2763 
2764  if (pid_broadcasting_names != DofObject::invalid_processor_id)
2765  this->comm().broadcast(result, pid_broadcasting_names);
2766 }
virtual void read_var_names_impl(const char *var_type, int &count, std::vector< std::string > &result)
read_var_names() dispatches to this function.
const Parallel::Communicator & comm() const
uint8_t processor_id_type
void min(const T &r, T &o, Request &req) const
static const 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:493
libmesh_assert(ctx)
void broadcast(T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
processor_id_type processor_id() const

◆ 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 1289 of file exodusII_io_helper.h.

References libMesh::ExodusII_IO_Helper::_add_sides.

1290 {
1291  _add_sides = add_sides;
1292 }
bool _add_sides
Set to true iff we want to write separate "side" elements too.

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

References libMesh::ExodusII_IO_Helper::_coordinate_offset.

4693 {
4694  _coordinate_offset = p;
4695 }

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

References libMesh::ExodusII_IO_Helper::_write_hdf5.

4678 {
4679  _write_hdf5 = write_hdf5;
4680 }

◆ 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 4671 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 4685 of file exodusII_io_helper.C.

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

4686 {
4688 }
unsigned int 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 2611 of file nemesis_io_helper.C.

References libMesh::ExodusII_IO_Helper::_single_precision, libMesh::CONSTANT, libMesh::System::current_local_solution, libMesh::ExodusII_IO_Helper::MappedOutputVector::data(), libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, libMesh::EquationSystems::get_system(), global_elem_blk_ids, libMesh::if(), libMesh::index_range(), mesh, libMesh::MONOMIAL_VEC, subdomain_map, libMesh::ExodusII_IO_Helper::update(), libMesh::System::variable_type(), and write_complex_abs.

2616 {
2617  // For each variable in names,
2618  // For each subdomain in subdomain_map,
2619  // If this (subdomain, variable) combination is active
2620  // For each component in variable
2621  // Extract element values into local_soln (localize is a collective)
2622  // Write local_soln to file
2623  // Update var_ctr with number of vector components for variable
2624  //
2625  unsigned int var_ctr = 0;
2626  for (auto v : index_range(var_nums))
2627  {
2628  const unsigned int sys_num = var_nums[v].first;
2629  const unsigned int var = var_nums[v].second;
2630  const System & system = es.get_system(sys_num);
2631 
2632  // We need to check if the constant monomial is a scalar or a vector and set the number of
2633  // components as the mesh spatial dimension for the latter as per es.find_variable_numbers().
2634  // Even for the case where a variable is not active on any subdomain belonging to the
2635  // processor, we still need to know this number to update 'var_ctr'.
2636  const unsigned int n_comps =
2637  (system.variable_type(var) == FEType(CONSTANT, MONOMIAL_VEC)) ? mesh.spatial_dimension() : 1;
2638 
2639  // Get list of active subdomains for variable v
2640  const auto & active_subdomains = vars_active_subdomains[v];
2641 
2642  for (const int sbd_id_int : global_elem_blk_ids)
2643  {
2644  const subdomain_id_type sbd_id =
2645  cast_int<subdomain_id_type>(sbd_id_int);
2646  auto it = subdomain_map.find(sbd_id);
2647  const std::vector<dof_id_type> empty_vec;
2648  const std::vector<dof_id_type> & elem_ids =
2649  (it == subdomain_map.end()) ? empty_vec : it->second;
2650 
2651  // Possibly skip this (variable, subdomain) combination. Also, check that there is at
2652  // least one element on the subdomain... Indeed, it is possible to have zero elements,
2653  // e.g., when running "adaptivity_ex3" in parallel with the 'dimension=1' argument.
2654  if ((active_subdomains.empty() || active_subdomains.count(sbd_id)) && elem_ids.size())
2655  {
2656  std::vector<numeric_index_type> required_indices;
2657  required_indices.reserve(elem_ids.size());
2658 
2659  // The number of DOF components needs to be equal to the expected number so that we
2660  // know where to store data to correctly correspond to variable names - verify this by
2661  // accessing the n_comp method for the last element ID, which should return the same
2662  // value for all elements on a given subdomain, so we only need to check this once.
2663  libmesh_assert_equal_to(n_comps, mesh.elem_ref(elem_ids.back()).n_comp(sys_num, var));
2664 
2665  // Loop through the DOFs of the variable and write the values for it on each element.
2666  // The variable name should have been decomposed by es.find_variable_numbers().
2667  for (unsigned int comp = 0; comp < n_comps; ++comp)
2668  {
2669  for (const auto & id : elem_ids)
2670  required_indices.push_back(mesh.elem_ref(id).dof_number(sys_num, var, comp));
2671 
2672  std::vector<Number> local_soln;
2673  system.current_local_solution->get(required_indices, local_soln);
2674 
2675  // reset for the next component
2676  required_indices.clear();
2677 
2678  // It's possible that there's nothing for us to write:
2679  // we may not be responsible for any elements on the
2680  // current subdomain. We did still have to participate
2681  // in the localize() call above, however, since it is a
2682  // collective.
2683  if (local_soln.size())
2684  {
2685 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
2686  int stride = write_complex_abs ? 3 : 2;
2687  std::vector<Real> local_soln_buffer(local_soln.size());
2688  std::transform(local_soln.begin(), local_soln.end(),
2689  local_soln_buffer.begin(), [](Number n) { return n.real(); });
2690  ex_err = exII::ex_put_elem_var(ex_id,
2691  timestep,
2692  static_cast<int>(stride*(var_ctr+comp)+1),
2693  static_cast<int>(sbd_id),
2694  static_cast<int>(local_soln.size()),
2695  MappedOutputVector(local_soln_buffer, _single_precision).data());
2696  EX_CHECK_ERR(ex_err, "Error writing element real values.");
2697 
2698  std::transform(local_soln.begin(), local_soln.end(),
2699  local_soln_buffer.begin(), [](Number n) { return n.imag(); });
2700  ex_err = exII::ex_put_elem_var(ex_id,
2701  timestep,
2702  static_cast<int>(stride*(var_ctr+comp)+2),
2703  static_cast<int>(sbd_id),
2704  static_cast<int>(local_soln.size()),
2705  MappedOutputVector(local_soln_buffer, _single_precision).data());
2706  EX_CHECK_ERR(ex_err, "Error writing element imaginary values.");
2707 
2708  if (write_complex_abs)
2709  {
2710  std::transform(local_soln.begin(), local_soln.end(),
2711  local_soln_buffer.begin(), [](Number n) { return std::abs(n); });
2712  ex_err = exII::ex_put_elem_var(ex_id,
2713  timestep,
2714  static_cast<int>(stride*(var_ctr+comp)+2),
2715  static_cast<int>(sbd_id),
2716  static_cast<int>(local_soln.size()),
2717  MappedOutputVector(local_soln_buffer, _single_precision).data());
2718  EX_CHECK_ERR(ex_err, "Error writing element magnitudes.");
2719  }
2720 #else // LIBMESH_USE_COMPLEX_NUMBERS
2721  ex_err = exII::ex_put_elem_var(ex_id,
2722  timestep,
2723  static_cast<int>(var_ctr+comp+1),
2724  static_cast<int>(sbd_id),
2725  static_cast<int>(local_soln.size()),
2726  MappedOutputVector(local_soln, _single_precision).data());
2727  EX_CHECK_ERR(ex_err, "Error writing element values.");
2728 #endif // LIBMESH_USE_COMPLEX_NUMBERS
2729  }
2730  } // end loop over vector components
2731  }
2732  } // end loop over active subdomains
2733 
2734  var_ctr += n_comps;
2735  } // end loop over vars
2736 
2737  this->update();
2738 }
std::map< subdomain_id_type, std::vector< dof_id_type > > subdomain_map
Map of subdomains to element numbers.
TestClass subdomain_id_type
Based on the 4-byte comment warning above, this probably doesn&#39;t work with exodusII at all...
Definition: id_types.h:43
MeshBase & mesh
bool write_complex_abs
By default, when complex numbers are enabled, for each variable we write out three values: the real p...
void update()
Uses ex_update() to flush buffers to file.
std::vector< int > global_elem_blk_ids
Read the global element block IDs and counts.
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:117

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

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::MeshTools::n_elem(), libMesh::MeshBase::n_elem(), libMesh::ExodusII_IO_Helper::num_elem_vars, libMesh::ParallelObject::processor_id(), and libMesh::ExodusII_IO_Helper::update().

4334 {
4335  LOG_SCOPE("write_element_values()", "ExodusII_IO_Helper");
4336 
4337  if ((_run_only_on_proc0) && (this->processor_id() != 0))
4338  return;
4339 
4340  // Ask the file how many element vars it has, store it in the num_elem_vars variable.
4341  ex_err = exII::ex_get_variable_param(ex_id, exII::EX_ELEM_BLOCK, &num_elem_vars);
4342  EX_CHECK_ERR(ex_err, "Error reading number of elemental variables.");
4343 
4344  // We will eventually loop over the element blocks (subdomains) and
4345  // write the data one block at a time. Build a data structure that
4346  // maps each subdomain to a list of element ids it contains.
4347  std::map<subdomain_id_type, std::vector<unsigned int>> subdomain_map;
4348  for (const auto & elem : mesh.active_element_ptr_range())
4349  subdomain_map[elem->subdomain_id()].push_back(elem->id());
4350 
4351  // Use mesh.n_elem() to access into the values vector rather than
4352  // the number of elements the Exodus writer thinks the mesh has,
4353  // which may not include inactive elements.
4355 
4356  // Sanity check: we must have an entry in vars_active_subdomains for
4357  // each variable that we are potentially writing out.
4358  libmesh_assert_equal_to
4359  (vars_active_subdomains.size(),
4360  static_cast<unsigned>(num_elem_vars));
4361 
4362  // For each variable, create a 'data' array which holds all the elemental variable
4363  // values *for a given block* on this processor, then write that data vector to file
4364  // before moving onto the next block.
4365  for (unsigned int var_id=0; var_id<static_cast<unsigned>(num_elem_vars); ++var_id)
4366  {
4367  // The size of the subdomain map is the number of blocks.
4368  auto it = subdomain_map.begin();
4369 
4370  // Reference to the set of active subdomains for the current variable.
4371  const auto & active_subdomains
4372  = vars_active_subdomains[var_id];
4373 
4374  for (unsigned int j=0; it!=subdomain_map.end(); ++it, ++j)
4375  {
4376  // Skip any variable/subdomain pairs that are inactive.
4377  // Note that if active_subdomains is empty, it is interpreted
4378  // as being active on *all* subdomains.
4379  if (!(active_subdomains.empty() || active_subdomains.count(it->first)))
4380  continue;
4381 
4382  // Get reference to list of elem ids which are in the
4383  // current subdomain and count, allocate storage to hold
4384  // data that will be written to file.
4385  const auto & elem_nums = it->second;
4386  const unsigned int num_elems_this_block =
4387  cast_int<unsigned int>(elem_nums.size());
4388  std::vector<Real> data(num_elems_this_block);
4389 
4390  // variable-major ordering is:
4391  // (u1, u2, u3, ..., uN), (v1, v2, v3, ..., vN), ...
4392  // where N is the number of elements.
4393  for (unsigned int k=0; k<num_elems_this_block; ++k)
4394  data[k] = values[var_id*n_elem + elem_nums[k]];
4395 
4396  ex_err = exII::ex_put_var
4397  (ex_id,
4398  timestep,
4399  exII::EX_ELEM_BLOCK,
4400  var_id+1,
4401  this->get_block_id(j),
4402  num_elems_this_block,
4403  MappedOutputVector(data, _single_precision).data());
4404 
4405  EX_CHECK_ERR(ex_err, "Error writing element values.");
4406  }
4407  }
4408 
4409  this->update();
4410 }
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).
Definition: mesh_tools.C:969
MeshBase & mesh
void update()
Uses ex_update() to flush buffers to file.
virtual dof_id_type n_elem() const =0
processor_id_type processor_id() const
int get_block_id(int index)
Get the block number for the given block index.
uint8_t dof_id_type
Definition: id_types.h:67

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

References libMesh::ExodusII_IO_Helper::_run_only_on_proc0, libMesh::ExodusII_IO_Helper::_single_precision, libMesh::ExodusII_IO_Helper::MappedOutputVector::data(), distance(), 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().

4421 {
4422  if ((_run_only_on_proc0) && (this->processor_id() != 0))
4423  return;
4424 
4425  // Ask the file how many element vars it has, store it in the num_elem_vars variable.
4426  ex_err = exII::ex_get_variable_param(ex_id, exII::EX_ELEM_BLOCK, &num_elem_vars);
4427  EX_CHECK_ERR(ex_err, "Error reading number of elemental variables.");
4428 
4429  // We will eventually loop over the element blocks (subdomains) and
4430  // write the data one block (subdomain) at a time. Build a data
4431  // structure that keeps track of how many elements are in each
4432  // subdomain. This will allow us to reserve space in the data vector
4433  // we are going to write.
4434  std::map<subdomain_id_type, unsigned int> subdomain_to_n_elem;
4435  for (const auto & elem : mesh.active_element_ptr_range())
4436  subdomain_to_n_elem[elem->subdomain_id()] += 1;
4437 
4438  // Sanity check: we must have an entry in vars_active_subdomains for
4439  // each variable that we are potentially writing out.
4440  libmesh_assert_equal_to
4441  (vars_active_subdomains.size(),
4442  static_cast<unsigned>(num_elem_vars));
4443 
4444  // The size of the subdomain map is the number of blocks.
4445  auto subdomain_to_n_elem_iter = subdomain_to_n_elem.begin();
4446 
4447  // Store range of active Elem pointers. We are going to loop over
4448  // the elements n_vars * n_subdomains times, so let's make sure
4449  // the predicated iterators aren't slowing us down too much.
4450  ConstElemRange elem_range
4451  (mesh.active_elements_begin(),
4452  mesh.active_elements_end());
4453 
4454  for (unsigned int sbd_idx=0;
4455  subdomain_to_n_elem_iter != subdomain_to_n_elem.end();
4456  ++subdomain_to_n_elem_iter, ++sbd_idx)
4457  for (unsigned int var_id=0; var_id<static_cast<unsigned>(num_elem_vars); ++var_id)
4458  {
4459  // Reference to the set of active subdomains for the current variable.
4460  const auto & active_subdomains
4461  = vars_active_subdomains[var_id];
4462 
4463  // If the vars_active_subdomains container passed to this function
4464  // has an empty entry, it means the variable really is not active on
4465  // _any_ subdomains, not that it is active on _all_ subdomains. This
4466  // is just due to the way that we build the vars_active_subdomains
4467  // container.
4468  if (!active_subdomains.count(subdomain_to_n_elem_iter->first))
4469  continue;
4470 
4471  // Vector to hold values that will be written to Exodus file.
4472  std::vector<Real> data;
4473  data.reserve(subdomain_to_n_elem_iter->second);
4474 
4475  unsigned int values_offset = 0;
4476  for (auto & elem : elem_range)
4477  {
4478  // We'll use the Elem's subdomain id in several places below.
4479  subdomain_id_type sbd_id = elem->subdomain_id();
4480 
4481  // Get reference to the list of variable names defining
4482  // the indexing for the current Elem's subdomain.
4483  auto subdomain_to_var_names_iter =
4484  subdomain_to_var_names.find(sbd_id);
4485 
4486  // It's possible, but unusual, for there to be an Elem
4487  // from a subdomain that has no active variables from the
4488  // set of variables we are currently writing. If that
4489  // happens, we can just go to the next Elem because we
4490  // don't need to advance the offset into the values
4491  // vector, etc.
4492  if (subdomain_to_var_names_iter == subdomain_to_var_names.end())
4493  continue;
4494 
4495  const auto & var_names_this_sbd
4496  = subdomain_to_var_names_iter->second;
4497 
4498  // Only extract values if Elem is in the current subdomain.
4499  if (sbd_id == subdomain_to_n_elem_iter->first)
4500  {
4501  // Location of current var_id in the list of all variables on this
4502  // subdomain. FIXME: linear search but it's over a typically relatively
4503  // short vector of active variable names on this subdomain. We could do
4504  // a nested std::map<string,index> instead of a std::vector where the
4505  // location of the string is implicitly the index..
4506  auto pos =
4507  std::find(var_names_this_sbd.begin(),
4508  var_names_this_sbd.end(),
4509  derived_var_names[var_id]);
4510 
4511  libmesh_error_msg_if(pos == var_names_this_sbd.end(),
4512  "Derived name " << derived_var_names[var_id] << " not found!");
4513 
4514  // Find the current variable's location in the list of all variable
4515  // names on the current Elem's subdomain.
4516  auto true_index =
4517  std::distance(var_names_this_sbd.begin(), pos);
4518 
4519  data.push_back(values[values_offset + true_index]);
4520  }
4521 
4522  // The "true" offset is how much we have to advance the index for each Elem
4523  // in this subdomain.
4524  auto true_offset = var_names_this_sbd.size();
4525 
4526  // Increment to the next Elem's values
4527  values_offset += true_offset;
4528  } // for elem
4529 
4530  // Now write 'data' to Exodus file, in single precision if requested.
4531  if (!data.empty())
4532  {
4533  ex_err = exII::ex_put_var
4534  (ex_id,
4535  timestep,
4536  exII::EX_ELEM_BLOCK,
4537  var_id+1,
4538  this->get_block_id(sbd_idx),
4539  data.size(),
4540  MappedOutputVector(data, _single_precision).data());
4541 
4542  EX_CHECK_ERR(ex_err, "Error writing element values.");
4543  }
4544  } // for each var_id
4545 
4546  this->update();
4547 }
MeshBase & mesh
The StoredRange class defines a contiguous, divisible set of objects.
Definition: stored_range.h:54
Real distance(const Point &p)
void update()
Uses ex_update() to flush buffers to file.
processor_id_type processor_id() const
int get_block_id(int index)
Get the block number for the given block index.

◆ 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 2250 of file nemesis_io_helper.C.

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.

2251 {
2252  // Only write elements if there are elements blocks available.
2253  if (this->num_elem_blks_global > 0)
2254  {
2255  // Data structure to store element block names that will be used to
2256  // write the element block names to file.
2257  NamesData names_table(this->num_elem_blks_global, MAX_STR_LENGTH);
2258 
2259  // Loop over all blocks, even if we don't have elements in each block.
2260  // If we don't have elements we need to write out a 0 for that block...
2261  for (auto i : make_range(this->num_elem_blks_global))
2262  {
2263  // Even if there are no elements for this block on the current
2264  // processor, we still want to write its name to file, if
2265  // possible. MeshBase::subdomain_name() will just return an
2266  // empty string if there is no name associated with the current
2267  // block.
2268  names_table.push_back_entry
2269  (mesh.subdomain_name(cast_int<subdomain_id_type>(this->global_elem_blk_ids[i])));
2270 
2271  // Search for the current global block ID in the map
2272  if (const auto it = this->block_id_to_elem_connectivity.find( this->global_elem_blk_ids[i] );
2273  it == this->block_id_to_elem_connectivity.end())
2274  {
2275  // If not found, write a zero to file....
2276  this->ex_err = exII::ex_put_elem_block(this->ex_id,
2277  this->global_elem_blk_ids[i],
2278  "Empty",
2279  0, /* n. elements in this block */
2280  0, /* n. nodes per element */
2281  0); /* number of attributes per element */
2282 
2283  EX_CHECK_ERR(this->ex_err, "Error writing element block from Nemesis.");
2284  }
2285 
2286  // Otherwise, write the actual block information and connectivity to file
2287  else
2288  {
2289  subdomain_id_type block =
2290  cast_int<subdomain_id_type>(it->first);
2291  const std::vector<int> & this_block_connectivity = it->second;
2292  std::vector<dof_id_type> & elements_in_this_block = subdomain_map[block];
2293 
2294  // Use the first element in this block to get representative information.
2295  // Note that Exodus assumes all elements in a block are of the same type!
2296  // We are using that same assumption here!
2297  const auto & conv =
2298  get_conversion(mesh.elem_ref(elements_in_this_block[0]).type());
2299 
2300  this->num_nodes_per_elem =
2301  mesh.elem_ref(elements_in_this_block[0]).n_nodes();
2302 
2303  ex_err = exII::ex_put_elem_block(ex_id,
2304  block,
2305  conv.exodus_elem_type().c_str(),
2306  elements_in_this_block.size(),
2308  0);
2309  EX_CHECK_ERR(ex_err, "Error writing element block from Nemesis.");
2310 
2311  ex_err = exII::ex_put_elem_conn(ex_id,
2312  block,
2313  this_block_connectivity.data());
2314  EX_CHECK_ERR(ex_err, "Error writing element connectivities from Nemesis.");
2315  }
2316  } // end loop over global block IDs
2317 
2318  // Only call this once, not in the loop above!
2319  ex_err = exII::ex_put_elem_num_map(ex_id,
2320  exodus_elem_num_to_libmesh.empty() ? nullptr : exodus_elem_num_to_libmesh.data());
2321  EX_CHECK_ERR(ex_err, "Error writing element map");
2322 
2323  // Write the element block names to file.
2324  ex_err = exII::ex_put_names(ex_id, exII::EX_ELEM_BLOCK, names_table.get_char_star_star());
2325  EX_CHECK_ERR(ex_err, "Error writing element block names");
2326  } // end if (this->num_elem_blks_global > 0)
2327 }
std::map< subdomain_id_type, std::vector< dof_id_type > > subdomain_map
Map of subdomains to element numbers.
TestClass subdomain_id_type
Based on the 4-byte comment warning above, this probably doesn&#39;t work with exodusII at all...
Definition: id_types.h:43
std::vector< int > exodus_elem_num_to_libmesh
MeshBase & mesh
const ExodusII_IO_Helper::Conversion & get_conversion(const ElemType type) const
std::vector< int > global_elem_blk_ids
Read the global element block IDs and counts.
std::map< int, std::vector< int > > block_id_to_elem_connectivity
This is the block connectivity, i.e.
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:140

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

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

3915 {
3916  LOG_SCOPE("write_elemset_data()", "ExodusII_IO_Helper");
3917 
3918  if ((_run_only_on_proc0) && (this->processor_id() != 0))
3919  return;
3920 
3921  // Write the elemset variable names to file. This function should
3922  // only be called once for ELEMSET variables, repeated calls to
3923  // write_var_names() overwrites/changes the order of names that were
3924  // there previously, and will mess up any data that has already been
3925  // written.
3926  this->write_var_names(ELEMSET, var_names);
3927 
3928  // We now call the API to read the elemset info even though we are
3929  // in the middle of writing. This is a bit counter-intuitive, but it
3930  // seems to work provided that you have already written the mesh
3931  // itself... read_elemset_info() fills in the following data
3932  // members:
3933  // .) id_to_elemset_names
3934  // .) num_elems_per_set
3935  // .) num_elem_df_per_set
3936  // .) elemset_list
3937  // .) elemset_id_list
3938  // .) id_to_elemset_names
3939  this->read_elemset_info();
3940 
3941  // The "truth" table for elemset variables. elemset_var_tab is a
3942  // logically (num_elem_sets x num_elemset_vars) integer array of 0s and
3943  // 1s indicating which elemsets a given elemset variable is defined
3944  // on.
3945  std::vector<int> elemset_var_tab(num_elem_sets * var_names.size());
3946 
3947  int offset=0;
3948  for (int es=0; es<num_elem_sets; ++es)
3949  {
3950  // Debugging
3951  // libMesh::out << "Writing elemset variable values for elemset "
3952  // << es << ", elemset_id = " << elemset_ids[es]
3953  // << std::endl;
3954 
3955  // We know num_elems_per_set because we called read_elemset_info() above.
3956  offset += (es > 0 ? num_elems_per_set[es-1] : 0);
3957  this->read_elemset(es, offset);
3958 
3959  // For each variable in var_names, write the values for the
3960  // current elemset, if any.
3961  for (auto var : index_range(var_names))
3962  {
3963  // Debugging
3964  // libMesh::out << "Writing elemset variable values for var " << var << std::endl;
3965 
3966  // If this var has no values on this elemset, go to the next one.
3967  if (!elemset_ids_in[var].count(elemset_ids[es]))
3968  continue;
3969 
3970  // Otherwise, fill in this entry of the nodeset truth table.
3971  elemset_var_tab[es*var_names.size() + var] = 1;
3972 
3973  // Data vector that will eventually be passed to exII::ex_put_var().
3974  std::vector<Real> elemset_var_vals(num_elems_per_set[es]);
3975 
3976  // Get reference to the (elem_id, elemset_id) -> Real map for this variable.
3977  const auto & data_map = elemset_vals[var];
3978 
3979  // Loop over entries in current elemset.
3980  for (int i=0; i<num_elems_per_set[es]; ++i)
3981  {
3982  // Here we convert Exodus elem ids to libMesh node ids
3983  // simply by subtracting 1. We should probably use the
3984  // exodus_elem_num_to_libmesh data structure for this,
3985  // but I don't think it is set up at the time when this
3986  // function is normally called.
3987  dof_id_type libmesh_elem_id = elemset_list[i + offset] - 1;
3988 
3989  // Construct a key to look up values in data_map.
3990  std::pair<dof_id_type, elemset_id_type> key =
3991  std::make_pair(libmesh_elem_id, elemset_ids[es]);
3992 
3993  // Debugging:
3994  // libMesh::out << "Searching for key = (" << key.first << ", " << key.second << ")" << std::endl;
3995 
3996  // We require that the user provided either no values for
3997  // this (var, elemset) combination (in which case we don't
3998  // reach this point) or a value for _every_ elem in this
3999  // elemset for this var, so we use the libmesh_map_find()
4000  // macro to check for this.
4001  elemset_var_vals[i] = libmesh_map_find(data_map, key);
4002  } // end for (node in nodeset[ns])
4003 
4004  // Write elemset values to Exodus file
4005  if (elemset_var_vals.size() > 0)
4006  {
4007  ex_err = exII::ex_put_var
4008  (ex_id,
4009  timestep,
4010  exII::EX_ELEM_SET,
4011  var + 1, // 1-based variable index of current variable
4012  elemset_ids[es],
4013  num_elems_per_set[es],
4014  MappedOutputVector(elemset_var_vals, _single_precision).data());
4015  EX_CHECK_ERR(ex_err, "Error writing elemset vars.");
4016  }
4017  } // end for (var in var_names)
4018  } // end for (ns)
4019 
4020  // Finally, write the elemset truth table to file.
4021  ex_err =
4022  exII::ex_put_truth_table(ex_id,
4023  exII::EX_ELEM_SET, // exII::ex_entity_type
4024  num_elem_sets,
4025  cast_int<int>(var_names.size()),
4026  elemset_var_tab.data());
4027  EX_CHECK_ERR(ex_err, "Error writing elemset var truth table.");
4028 }
std::vector< int > num_elems_per_set
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().
void read_elemset(int id, int offset)
Reads information about elemset id and inserts it into the global elemset array at the position offse...
void read_elemset_info()
Reads information about all of the elemsets in the ExodusII mesh file.
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:117
uint8_t dof_id_type
Definition: id_types.h:67

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

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

3418 {
3419  LOG_SCOPE("write_elemsets()", "ExodusII_IO_Helper");
3420 
3421  if ((_run_only_on_proc0) && (this->processor_id() != 0))
3422  return;
3423 
3424  // TODO: Add support for named elemsets
3425  // NamesData names_table(elemsets.size(), MAX_STR_LENGTH);
3426 
3427  // We only need to write elemsets if the Mesh has an extra elem
3428  // integer called "elemset_code" defined on it.
3429  if (mesh.has_elem_integer("elemset_code"))
3430  {
3431  std::map<elemset_id_type, std::vector<int>> exodus_elemsets;
3432 
3433  unsigned int elemset_index =
3434  mesh.get_elem_integer_index("elemset_code");
3435 
3436  // Catch ids returned from MeshBase::get_elemsets() calls
3437  MeshBase::elemset_type set_ids;
3438  for (const auto & elem : mesh.element_ptr_range())
3439  {
3440  dof_id_type elemset_code =
3441  elem->get_extra_integer(elemset_index);
3442 
3443  // Look up which element set ids (if any) this elemset_code corresponds to.
3444  mesh.get_elemsets(elemset_code, set_ids);
3445 
3446  // Debugging
3447  // libMesh::out << "elemset_code = " << elemset_code << std::endl;
3448  // for (const auto & set_id : set_ids)
3449  // libMesh::out << set_id << " ";
3450  // libMesh::out << std::endl;
3451 
3452  // Store this Elem id in every set to which it belongs.
3453  for (const auto & set_id : set_ids)
3454  exodus_elemsets[set_id].push_back(libmesh_elem_num_to_exodus[elem->id()]);
3455  }
3456 
3457  // Debugging: print contents of exodus_elemsets map
3458  // for (const auto & [set_id, elem_ids] : exodus_elemsets)
3459  // {
3460  // libMesh::out << "elemset " << set_id << ": ";
3461  // for (const auto & elem_id : elem_ids)
3462  // libMesh::out << elem_id << " ";
3463  // libMesh::out << std::endl;
3464  // }
3465 
3466  // Only continue if we actually had some elements in sets
3467  if (!exodus_elemsets.empty())
3468  {
3469  // Reserve space, loop over newly-created map, construct
3470  // exII::ex_set objects to be passed to exII::ex_put_sets(). Note:
3471  // we do non-const iteration since Exodus requires non-const pointers
3472  // to be passed to its APIs.
3473  std::vector<exII::ex_set> sets;
3474  sets.reserve(exodus_elemsets.size());
3475 
3476  for (auto & [elem_set_id, ids_vec] : exodus_elemsets)
3477  {
3478  // TODO: Add support for named elemsets
3479  // names_table.push_back_entry(mesh.get_elemset_name(elem_set_id));
3480 
3481  exII::ex_set & current_set = sets.emplace_back();
3482  current_set.id = elem_set_id;
3483  current_set.type = exII::EX_ELEM_SET;
3484  current_set.num_entry = ids_vec.size();
3485  current_set.num_distribution_factor = 0;
3486  current_set.entry_list = ids_vec.data();
3487  current_set.extra_list = nullptr; // extra_list is used for sidesets, not needed for elemsets
3488  current_set.distribution_factor_list = nullptr; // not used for elemsets
3489  }
3490 
3491  // Sanity check: make sure the number of elemsets we already wrote to the header
3492  // matches the number of elemsets we just constructed by looping over the Mesh.
3493  libmesh_assert_msg(num_elem_sets == cast_int<int>(exodus_elemsets.size()),
3494  "Mesh has " << exodus_elemsets.size()
3495  << " elemsets, but header was written with num_elem_sets == " << num_elem_sets);
3496  libmesh_assert_msg(num_elem_sets == cast_int<int>(mesh.n_elemsets()),
3497  "mesh.n_elemsets() == " << mesh.n_elemsets()
3498  << ", but header was written with num_elem_sets == " << num_elem_sets);
3499 
3500  ex_err = exII::ex_put_sets(ex_id, exodus_elemsets.size(), sets.data());
3501  EX_CHECK_ERR(ex_err, "Error writing elemsets");
3502 
3503  // TODO: Add support for named elemsets
3504  // ex_err = exII::ex_put_names(ex_id, exII::EX_ELEM_SET, names_table.get_char_star_star());
3505  // EX_CHECK_ERR(ex_err, "Error writing elemset names");
3506  } // end if (!exodus_elemsets.empty())
3507  } // end if (mesh.has_elem_integer("elemset_code"))
3508 }
bool has_elem_integer(std::string_view name) const
Definition: mesh_base.C:638
MeshBase & mesh
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:429
unsigned int get_elem_integer_index(std::string_view name) const
Definition: mesh_base.C:626
unsigned int n_elemsets() const
Returns the number of unique elemset ids which have been added via add_elemset_code(), which is the size of the _all_elemset_ids set.
Definition: mesh_base.C:424
std::map< dof_id_type, dof_id_type > libmesh_elem_num_to_exodus
std::set< elemset_id_type > elemset_type
Typedef for the "set" container used to store elemset ids.
Definition: mesh_base.h:318
processor_id_type processor_id() const
uint8_t dof_id_type
Definition: id_types.h:67

◆ 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 900 of file nemesis_io_helper.C.

References distance(), libMesh::ExodusII_IO_Helper::ex_err, libMesh::ExodusII_IO_Helper::ex_id, global_nodeset_ids, global_sideset_ids, libMesh::ExodusII_IO_Helper::num_dim, libMesh::ExodusII_IO_Helper::num_elem, libMesh::ExodusII_IO_Helper::num_elem_blk, num_elem_blks_global, libMesh::ExodusII_IO_Helper::num_node_sets, libMesh::ExodusII_IO_Helper::num_nodes, and libMesh::ExodusII_IO_Helper::num_side_sets.

Referenced by initialize().

902 {
903  this->num_elem = static_cast<unsigned int>(std::distance (pmesh.active_local_elements_begin(),
904  pmesh.active_local_elements_end()));
905 
906  // Exodus will also use *global* number of side and node sets,
907  // though it will not write out entries for all of them...
908  this->num_side_sets =
909  cast_int<int>(this->global_sideset_ids.size());
910  this->num_node_sets =
911  cast_int<int>(this->global_nodeset_ids.size());
912 
913  // We need to write the global number of blocks, even though this processor might not have
914  // elements in some of them!
915  this->num_elem_blk = this->num_elem_blks_global;
916 
917  ex_err = exII::ex_put_init(ex_id,
918  title_in.c_str(),
919  this->num_dim,
920  this->num_nodes,
921  this->num_elem,
922  this->num_elem_blk,
923  this->num_node_sets,
924  this->num_side_sets);
925 
926  EX_CHECK_ERR(ex_err, "Error initializing new Nemesis file.");
927 }
std::vector< int > global_nodeset_ids
Containers for reading global nodeset information.
std::vector< int > global_sideset_ids
Containers for reading global sideset (boundary conditions) information.
Real distance(const Point &p)

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

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

4619 {
4620  if ((_run_only_on_proc0) && (this->processor_id() != 0))
4621  return;
4622 
4623  if (!values.empty())
4624  {
4625  ex_err = exII::ex_put_var
4626  (ex_id,
4627  timestep,
4628  exII::EX_GLOBAL,
4629  1, // var index
4630  0, // obj_id (not used)
4632  MappedOutputVector(values, _single_precision).data());
4633 
4634  EX_CHECK_ERR(ex_err, "Error writing global values.");
4635 
4636  this->update();
4637  }
4638 }
void update()
Uses ex_update() to flush buffers to file.
processor_id_type processor_id() const

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

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

4581 {
4582  if ((_run_only_on_proc0) && (this->processor_id() != 0))
4583  return;
4584 
4585  // There may already be information records in the file (for
4586  // example, if we're appending) and in that case, according to the
4587  // Exodus documentation, writing more information records is not
4588  // supported.
4589  int num_info = inquire(*this, exII::EX_INQ_INFO, "Error retrieving the number of information records from file!");
4590  if (num_info > 0)
4591  {
4592  libMesh::err << "Warning! The Exodus file already contains information records.\n"
4593  << "Exodus does not support writing additional records in this situation."
4594  << std::endl;
4595  return;
4596  }
4597 
4598  int num_records = cast_int<int>(records.size());
4599 
4600  if (num_records > 0)
4601  {
4602  NamesData info(num_records, MAX_LINE_LENGTH);
4603 
4604  // If an entry is longer than MAX_LINE_LENGTH characters it's not an error, we just
4605  // write the first MAX_LINE_LENGTH characters to the file.
4606  for (const auto & record : records)
4607  info.push_back_entry(record);
4608 
4609  ex_err = exII::ex_put_info(ex_id, num_records, info.get_char_star_star());
4610  EX_CHECK_ERR(ex_err, "Error writing global values.");
4611 
4612  this->update();
4613  }
4614 }
OStreamProxy err
MPI_Info info
void update()
Uses ex_update() to flush buffers to file.
processor_id_type processor_id() const

◆ 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 2205 of file nemesis_io_helper.C.

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.

2206 {
2207  auto local_num_nodes = this->exodus_node_num_to_libmesh.size();
2208 
2209  x.resize(local_num_nodes);
2210  y.resize(local_num_nodes);
2211  z.resize(local_num_nodes);
2212 
2213  // Just loop over our list outputting the nodes the way we built the map
2214  for (auto i : make_range(local_num_nodes))
2215  {
2216  const Point & pt = mesh.point(this->exodus_node_num_to_libmesh[i]-1);
2217  x[i]=pt(0);
2218  y[i]=pt(1);
2219  z[i]=pt(2);
2220  }
2221 
2222  if (local_num_nodes)
2223  {
2224  // Call Exodus API to write nodal coordinates...
2225  ex_err = exII::ex_put_coord
2226  (ex_id,
2227  x.empty() ? nullptr : MappedOutputVector(x, _single_precision).data(),
2228  y.empty() ? nullptr : MappedOutputVector(y, _single_precision).data(),
2229  z.empty() ? nullptr : MappedOutputVector(z, _single_precision).data());
2230  EX_CHECK_ERR(ex_err, "Error writing node coordinates");
2231 
2232  // And write the nodal map we created for them
2233  ex_err = exII::ex_put_node_num_map(ex_id, this->exodus_node_num_to_libmesh.data());
2234  EX_CHECK_ERR(ex_err, "Error writing node num map");
2235  }
2236  else // Does the Exodus API want us to write empty nodal coordinates?
2237  {
2238  ex_err = exII::ex_put_coord(ex_id, nullptr, nullptr, nullptr);
2239  EX_CHECK_ERR(ex_err, "Error writing empty node coordinates");
2240 
2241  ex_err = exII::ex_put_node_num_map(ex_id, nullptr);
2242  EX_CHECK_ERR(ex_err, "Error writing empty node num map");
2243  }
2244 }
MeshBase & mesh
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:140
std::vector< int > exodus_node_num_to_libmesh

◆ write_nodal_solution() [1/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 2371 of file nemesis_io_helper.C.

References distance(), 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().

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

◆ write_nodal_solution() [2/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 2431 of file nemesis_io_helper.C.

References libMesh::Variable::active_on_subdomain(), libMesh::System::current_local_solution, distance(), 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::Quality::name(), 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().

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

◆ 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 2333 of file nemesis_io_helper.C.

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

2336 {
2337  int num_vars = cast_int<int>(names.size());
2338  //int num_values = values.size(); // Not used?
2339 
2340  for (int c=0; c<num_vars; c++)
2341  {
2342 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
2343  std::vector<Real> real_parts(num_nodes);
2344  std::vector<Real> imag_parts(num_nodes);
2345  std::vector<Real> magnitudes(num_nodes);
2346 
2347  for (int i=0; i<num_nodes; ++i)
2348  {
2349  Number value = values[(this->exodus_node_num_to_libmesh[i]-1)*num_vars + c];
2350  real_parts[i] = value.real();
2351  imag_parts[i] = value.imag();
2352  magnitudes[i] = std::abs(value);
2353  }
2354  write_nodal_values(3*c+1,real_parts,timestep);
2355  write_nodal_values(3*c+2,imag_parts,timestep);
2356  write_nodal_values(3*c+3,magnitudes,timestep);
2357 #else
2358  std::vector<Number> cur_soln(this->num_nodes);
2359 
2360  // Copy out this variable's solution
2361  for (int i=0; i<this->num_nodes; i++)
2362  cur_soln[i] = values[(this->exodus_node_num_to_libmesh[i]-1)*num_vars + c];
2363 
2364  write_nodal_values(c+1,cur_soln,timestep);
2365 #endif
2366  }
2367 }
void write_nodal_values(int var_id, const std::vector< Real > &values, int timestep)
Writes the vector of values to a nodal variable.
static const bool value
Definition: xdr_io.C:55
std::vector< int > exodus_node_num_to_libmesh

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

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

4555 {
4556  if ((_run_only_on_proc0) && (this->processor_id() != 0))
4557  return;
4558 
4559  if (!values.empty())
4560  {
4561  libmesh_assert_equal_to(values.size(), std::size_t(num_nodes));
4562 
4563  ex_err = exII::ex_put_var
4564  (ex_id,
4565  timestep,
4566  exII::EX_NODAL,
4567  var_id,
4568  1, // exII::ex_entity_id, not sure exactly what this is but in the ex_put_nodal_var.c shim, they pass 1
4569  num_nodes,
4570  MappedOutputVector(values, _single_precision).data());
4571 
4572  EX_CHECK_ERR(ex_err, "Error writing nodal values.");
4573 
4574  this->update();
4575  }
4576 }
void update()
Uses ex_update() to flush buffers to file.
processor_id_type processor_id() const

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

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

3810 {
3811  LOG_SCOPE("write_nodeset_data()", "ExodusII_IO_Helper");
3812 
3813  if ((_run_only_on_proc0) && (this->processor_id() != 0))
3814  return;
3815 
3816  // Write the nodeset variable names to file. This function should
3817  // only be called once for NODESET variables, repeated calls to
3818  // write_var_names() overwrites/changes the order of names that were
3819  // there previously, and will mess up any data that has already been
3820  // written.
3821  this->write_var_names(NODESET, var_names);
3822 
3823  // For all nodesets, reads and fills in the arrays:
3824  // nodeset_ids
3825  // num_nodes_per_set
3826  // node_sets_node_index - starting index for each nodeset in the node_sets_node_list vector
3827  // node_sets_node_list
3828  // Note: we need these arrays so that we know what data to write
3829  this->read_all_nodesets();
3830 
3831  // The "truth" table for nodeset variables. nset_var_tab is a
3832  // logically (num_node_sets x num_nset_var) integer array of 0s and
3833  // 1s indicating which nodesets a given nodeset variable is defined
3834  // on.
3835  std::vector<int> nset_var_tab(num_node_sets * var_names.size());
3836 
3837  for (int ns=0; ns<num_node_sets; ++ns)
3838  {
3839  // The offset into the node_sets_node_list for the current nodeset
3840  int offset = node_sets_node_index[ns];
3841 
3842  // For each variable in var_names, write the values for the
3843  // current nodeset, if any.
3844  for (auto var : index_range(var_names))
3845  {
3846  // If this var has no values on this nodeset, go to the next one.
3847  if (!node_boundary_ids[var].count(nodeset_ids[ns]))
3848  continue;
3849 
3850  // Otherwise, fill in this entry of the nodeset truth table.
3851  nset_var_tab[ns*var_names.size() + var] = 1;
3852 
3853  // Data vector that will eventually be passed to exII::ex_put_var().
3854  std::vector<Real> nset_var_vals(num_nodes_per_set[ns]);
3855 
3856  // Get reference to the NodeBCTuple -> Real map for this variable.
3857  const auto & data_map = bc_vals[var];
3858 
3859  // Loop over entries in current nodeset.
3860  for (int i=0; i<num_nodes_per_set[ns]; ++i)
3861  {
3862  // Here we convert Exodus node ids to libMesh node ids by
3863  // subtracting 1. We should probably use the
3864  // exodus_node_num_to_libmesh data structure for this, but
3865  // I don't think it is set up at the time when
3866  // write_nodeset_data() would normally be called.
3867  dof_id_type libmesh_node_id = node_sets_node_list[i + offset] - 1;
3868 
3869  // Construct a key to look up values in data_map.
3871  std::make_tuple(libmesh_node_id, nodeset_ids[ns]);
3872 
3873  // We require that the user provided either no values for
3874  // this (var, nodeset) combination (in which case we don't
3875  // reach this point) or a value for _every_ node in this
3876  // nodeset for this var, so we use the libmesh_map_find()
3877  // macro to check for this.
3878  nset_var_vals[i] = libmesh_map_find(data_map, key);
3879  } // end for (node in nodeset[ns])
3880 
3881  // Write nodeset values to Exodus file
3882  if (nset_var_vals.size() > 0)
3883  {
3884  ex_err = exII::ex_put_var
3885  (ex_id,
3886  timestep,
3887  exII::EX_NODE_SET,
3888  var + 1, // 1-based variable index of current variable
3889  nodeset_ids[ns],
3890  num_nodes_per_set[ns],
3891  MappedOutputVector(nset_var_vals, _single_precision).data());
3892  EX_CHECK_ERR(ex_err, "Error writing nodeset vars.");
3893  }
3894  } // end for (var in var_names)
3895  } // end for (ns)
3896 
3897  // Finally, write the nodeset truth table.
3898  ex_err =
3899  exII::ex_put_truth_table(ex_id,
3900  exII::EX_NODE_SET,
3901  num_node_sets,
3902  cast_int<int>(var_names.size()),
3903  nset_var_tab.data());
3904  EX_CHECK_ERR(ex_err, "Error writing nodeset var truth table.");
3905 }
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< int > node_sets_node_index
std::tuple< dof_id_type, boundary_id_type > NodeBCTuple
As above, but the library creates and fills in a vector of (node-id, bc-id) pairs and returns it to t...
void read_all_nodesets()
New API that reads all nodesets simultaneously.
std::vector< int > node_sets_node_list
std::vector< int > num_nodes_per_set
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:117
uint8_t dof_id_type
Definition: id_types.h:67

◆ 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 1915 of file nemesis_io_helper.C.

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

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

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

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::ExodusII_IO_Helper::Conversion::get_side_map(), 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().

3519 {
3520  LOG_SCOPE("write_sideset_data()", "ExodusII_IO_Helper");
3521 
3522  if ((_run_only_on_proc0) && (this->processor_id() != 0))
3523  return;
3524 
3525  // Write the sideset variable names to file. This function should
3526  // only be called once for SIDESET variables, repeated calls to
3527  // write_var_names overwrites/changes the order of names that were
3528  // there previously, and will mess up any data that has already been
3529  // written.
3530  this->write_var_names(SIDESET, var_names);
3531 
3532  // I hope that we are allowed to call read_sideset_info() even
3533  // though we are in the middle of writing? It seems to work provided
3534  // that you have already written the mesh itself... read_sideset_info()
3535  // fills in the following data members:
3536  // .) num_side_sets
3537  // .) ss_ids
3538  this->read_sideset_info();
3539 
3540  // Write "truth" table for sideset variables. The function
3541  // exII::ex_put_variable_param() must be called before
3542  // exII::ex_put_truth_table(). For us, this happens during the call
3543  // to ExodusII_IO_Helper::write_var_names(). sset_var_tab is a logically
3544  // (num_side_sets x num_sset_var) integer array of 0s and 1s
3545  // indicating which sidesets a given sideset variable is defined on.
3546  std::vector<int> sset_var_tab(num_side_sets * var_names.size());
3547 
3548  // We now call read_sideset() once per sideset and write any sideset
3549  // variable values which are defined there.
3550  int offset=0;
3551  for (int ss=0; ss<num_side_sets; ++ss)
3552  {
3553  // We don't know num_sides_per_set for each set until we call
3554  // read_sideset(). The values for each sideset are stored (using
3555  // the offsets) into the 'elem_list' and 'side_list' arrays of
3556  // this class.
3557  offset += (ss > 0 ? num_sides_per_set[ss-1] : 0);
3558  this->read_sideset(ss, offset);
3559 
3560  // For each variable in var_names, write the values for the
3561  // current sideset, if any.
3562  for (auto var : index_range(var_names))
3563  {
3564  // If this var has no values on this sideset, go to the next one.
3565  if (!side_ids[var].count(ss_ids[ss]))
3566  continue;
3567 
3568  // Otherwise, fill in this entry of the sideset truth table.
3569  sset_var_tab[ss*var_names.size() + var] = 1;
3570 
3571  // Data vector that will eventually be passed to exII::ex_put_var().
3572  std::vector<Real> sset_var_vals(num_sides_per_set[ss]);
3573 
3574  // Get reference to the BCTuple -> Real map for this variable.
3575  const auto & data_map = bc_vals[var];
3576 
3577  // Loop over elem_list, side_list entries in current sideset.
3578  for (int i=0; i<num_sides_per_set[ss]; ++i)
3579  {
3580  // Get elem_id and side_id from the respective lists that
3581  // are filled in by calling read_sideset().
3582  //
3583  // Note: these are Exodus-specific ids, so we have to convert them
3584  // to libmesh ids, as that is what will be in the bc_tuples.
3585  //
3586  // TODO: we should probably consult the exodus_elem_num_to_libmesh
3587  // mapping in order to figure out which libmesh element id 'elem_id'
3588  // actually corresponds to here, instead of just assuming it will be
3589  // off by one. Unfortunately that data structure does not seem to
3590  // be used at the moment. If we assume that write_sideset_data() is
3591  // always called following write(), then this should be a fairly safe
3592  // assumption...
3593  dof_id_type elem_id = elem_list[i + offset] - 1;
3594  unsigned int side_id = side_list[i + offset] - 1;
3595 
3596  // Sanity check: make sure that the "off by one"
3597  // assumption we used above to set 'elem_id' is valid.
3598  libmesh_error_msg_if
3599  (libmesh_map_find(libmesh_elem_num_to_exodus, cast_int<int>(elem_id)) !=
3600  cast_int<dof_id_type>(elem_list[i + offset]),
3601  "Error mapping Exodus elem id to libmesh elem id.");
3602 
3603  // Map from Exodus side ids to libmesh side ids.
3604  const auto & conv = get_conversion(mesh.elem_ptr(elem_id)->type());
3605 
3606  // Map from Exodus side ids to libmesh side ids.
3607  unsigned int converted_side_id = conv.get_side_map(side_id);
3608 
3609  // Construct a key so we can quickly see whether there is any
3610  // data for this variable in the map.
3611  BoundaryInfo::BCTuple key = std::make_tuple
3612  (elem_id,
3613  converted_side_id,
3614  ss_ids[ss]);
3615 
3616  // Find the data for this (elem,side,id) tuple. Throw an
3617  // error if not found. Then store value in vector which
3618  // will be passed to Exodus.
3619  sset_var_vals[i] = libmesh_map_find(data_map, key);
3620  } // end for (i)
3621 
3622  // As far as I can tell, there is no "concat" version of writing
3623  // sideset data, you have to call ex_put_sset_var() once per (variable,
3624  // sideset) pair.
3625  if (sset_var_vals.size() > 0)
3626  {
3627  ex_err = exII::ex_put_var
3628  (ex_id,
3629  timestep,
3630  exII::EX_SIDE_SET,
3631  var + 1, // 1-based variable index of current variable
3632  ss_ids[ss],
3633  num_sides_per_set[ss],
3634  MappedOutputVector(sset_var_vals, _single_precision).data());
3635  EX_CHECK_ERR(ex_err, "Error writing sideset vars.");
3636  }
3637  } // end for (var)
3638  } // end for (ss)
3639 
3640  // Finally, write the sideset truth table.
3641  ex_err =
3642  exII::ex_put_truth_table(ex_id,
3643  exII::EX_SIDE_SET,
3644  num_side_sets,
3645  cast_int<int>(var_names.size()),
3646  sset_var_tab.data());
3647  EX_CHECK_ERR(ex_err, "Error writing sideset var truth table.");
3648 }
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::tuple< dof_id_type, unsigned short int, boundary_id_type > BCTuple
As above, but the library creates and fills in a vector of (elem-id, side-id, bc-id) triplets and ret...
std::vector< int > num_sides_per_set
void read_sideset_info()
Reads information about all of the sidesets in the ExodusII mesh file.
const boundary_id_type side_id
MeshBase & mesh
const ExodusII_IO_Helper::Conversion & get_conversion(const ElemType type) const
std::map< dof_id_type, dof_id_type > libmesh_elem_num_to_exodus
virtual const Elem * elem_ptr(const dof_id_type i) const =0
void read_sideset(int id, int offset)
Reads information about sideset id and inserts it into the global sideset array at the position offse...
processor_id_type processor_id() const
virtual ElemType type() const =0
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:117
uint8_t dof_id_type
Definition: id_types.h:67

◆ 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 2063 of file nemesis_io_helper.C.

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

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

◆ write_timestep()

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

Writes the time for the timestep.

Definition at line 3394 of file exodusII_io_helper.C.

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

3395 {
3396  if ((_run_only_on_proc0) && (this->processor_id() != 0))
3397  return;
3398 
3399  if (_single_precision)
3400  {
3401  float cast_time = float(time);
3402  ex_err = exII::ex_put_time(ex_id, timestep, &cast_time);
3403  }
3404  else
3405  {
3406  double cast_time = double(time);
3407  ex_err = exII::ex_put_time(ex_id, timestep, &cast_time);
3408  }
3409  EX_CHECK_ERR(ex_err, "Error writing timestep.");
3410 
3411  this->update();
3412 }
void update()
Uses ex_update() to flush buffers to file.
processor_id_type processor_id() const

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

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

1970 {
1971  switch (type)
1972  {
1973  case NODAL:
1974  this->write_var_names_impl("n", num_nodal_vars, names);
1975  break;
1976  case ELEMENTAL:
1977  this->write_var_names_impl("e", num_elem_vars, names);
1978  break;
1979  case GLOBAL:
1980  this->write_var_names_impl("g", num_global_vars, names);
1981  break;
1982  case SIDESET:
1983  {
1984  // Note: calling this function *sets* num_sideset_vars to the
1985  // number of entries in the 'names' vector, num_sideset_vars
1986  // does not already need to be set before calling this.
1987  this->write_var_names_impl("s", num_sideset_vars, names);
1988  break;
1989  }
1990  case NODESET:
1991  {
1992  this->write_var_names_impl("m", num_nodeset_vars, names);
1993  break;
1994  }
1995  case ELEMSET:
1996  {
1997  this->write_var_names_impl("t", num_elemset_vars, names);
1998  break;
1999  }
2000  default:
2001  libmesh_error_msg("Unrecognized ExodusVarType " << type);
2002  }
2003 }
void write_var_names_impl(const char *var_type, int &count, const std::vector< std::string > &names)
write_var_names() dispatches to this function.

Member Data Documentation

◆ _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 982 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

◆ _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 989 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 465 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 659 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 622 of file nemesis_io_helper.h.

Referenced by compute_border_node_ids(), compute_internal_and_border_elems_and_internal_nodes(), and compute_node_maps().

◆ connect

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

◆ 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 587 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 589 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 588 of file nemesis_io_helper.h.

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

◆ 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 532 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 525 of file nemesis_io_helper.h.

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

◆ 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 829 of file exodusII_io_helper.h.

◆ 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 630 of file exodusII_io_helper.h.

Referenced by libMesh::ExodusII_IO_Helper::close(), libMesh::ExodusII_IO_Helper::initialize(), libMesh::ExodusII_IO_Helper::initialize_element_variables(), initialize_element_variables(), 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_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(), write_elements(), libMesh::ExodusII_IO_Helper::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(), write_nodal_coordinates(), libMesh::ExodusII_IO_Helper::write_nodal_coordinates(), libMesh::ExodusII_IO_Helper::write_nodal_values(), libMesh::ExodusII_IO_Helper::write_nodeset_data(), write_nodesets(), libMesh::ExodusII_IO_Helper::write_nodesets(), libMesh::ExodusII_IO_Helper::write_sideset_data(), write_sidesets(), libMesh::ExodusII_IO_Helper::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 627 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_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(), write_elements(), libMesh::ExodusII_IO_Helper::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(), write_nodal_coordinates(), libMesh::ExodusII_IO_Helper::write_nodal_coordinates(), libMesh::ExodusII_IO_Helper::write_nodal_values(), libMesh::ExodusII_IO_Helper::write_nodeset_data(), write_nodesets(), libMesh::ExodusII_IO_Helper::write_nodesets(), libMesh::ExodusII_IO_Helper::write_sideset_data(), write_sidesets(), libMesh::ExodusII_IO_Helper::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 798 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 414 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 448 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 438 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 426 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 654 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 649 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 616 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 564 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 578 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 579 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 417 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 548 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 555 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 541 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 454 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 502 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 482 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 655 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 516 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 391 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 489 of file nemesis_io_helper.h.

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

◆ 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 440 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 428 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 495 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 475 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 509 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 390 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 400 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 407 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 639 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 629 of file nemesis_io_helper.h.

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

◆ 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 459 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 809 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 780 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 600 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: