46 #ifdef LIBMESH_HAVE_EXODUS_API
57 #ifdef LIBMESH_HAVE_EXODUS_API
63 _allow_empty_variables(false)
77 #ifdef LIBMESH_ENABLE_DEPRECATED 80 unsigned int timestep)
91 const std::set<std::string> * system_names)
93 std::vector<std::string> solution_names;
94 std::vector<Number> v;
103 #ifdef LIBMESH_HAVE_EXODUS_API 108 const std::set<std::string> * system_names)
124 const std::set<std::string> * )
131 #ifdef LIBMESH_HAVE_EXODUS_API 190 if (added_node->
id() !=
static_cast<unsigned>(exodus_id-1))
191 libmesh_error_msg(
"Error! Mesh assigned node ID " \
192 << added_node->
id() \
193 <<
" which is different from the (zero-based) Exodus ID " \
215 int nelem_last_block = 0;
225 std::string subdomain_name =
exio_helper->get_block_name(i);
226 if (!subdomain_name.empty())
230 const std::string type_str (
exio_helper->get_elem_type());
234 int jmax = nelem_last_block+
exio_helper->num_elem_this_blk;
235 for (
int j=nelem_last_block; j<jmax; j++)
238 libmesh_assert (elem);
249 elem->
set_id(exodus_id-1);
259 if (elem->
id() !=
static_cast<unsigned>(exodus_id-1))
260 libmesh_error_msg(
"Error! Mesh assigned ID " \
262 <<
" which is different from the (zero-based) Exodus ID " \
267 for (
int k=0; k<
exio_helper->num_nodes_per_elem; k++)
270 int gi = (j-nelem_last_block)*
exio_helper->num_nodes_per_elem + conv.get_node_map(k);
288 nelem_last_block +=
exio_helper->num_elem_this_blk;
299 for (
unsigned char i=0; i!=4; ++i)
311 offset += (i > 0 ?
exio_helper->num_sides_per_set[i-1] : 0);
314 std::string sideset_name =
exio_helper->get_side_set_name(i);
315 if (!sideset_name.empty())
317 (cast_int<boundary_id_type>(
exio_helper->get_side_set_id(i)))
339 unsigned int raw_side_index =
exio_helper->side_list[e]-1;
342 if (raw_side_index < side_index_offset)
345 int mapped_shellface = raw_side_index;
349 libmesh_error_msg(
"Invalid 1-based side id: " \
350 << mapped_shellface \
351 <<
" detected for " \
356 cast_int<unsigned short>(mapped_shellface),
357 cast_int<boundary_id_type>(
exio_helper->id_list[e]));
361 unsigned int side_index =
static_cast<unsigned int>(raw_side_index - side_index_offset);
366 libmesh_error_msg(
"Invalid 1-based side id: " \
368 <<
" detected for " \
373 cast_int<unsigned short>(mapped_side),
374 cast_int<boundary_id_type>(
exio_helper->id_list[e]));
383 for (
int nodeset=0; nodeset<
exio_helper->num_node_sets; nodeset++)
386 cast_int<boundary_id_type>(
exio_helper->nodeset_ids[nodeset]);
388 std::string nodeset_name =
exio_helper->get_node_set_name(nodeset);
389 if (!nodeset_name.empty())
394 for (
const auto & exodus_id :
exio_helper->node_list)
399 int libmesh_node_id =
exio_helper->node_num_map[exodus_id - 1] - 1;
408 libmesh_error_msg(
"Cannot open dimension " \
410 <<
" mesh file when configured without " \
430 exio_helper->use_mesh_dimension_instead_of_spatial_dimension(val);
444 libmesh_warning(
"This method may be deprecated in the future");
460 libmesh_error_msg(
"ERROR, ExodusII file must be opened for reading before calling ExodusII_IO::get_time_steps()!");
471 libmesh_error_msg(
"ERROR, ExodusII file must be opened for reading or writing before calling ExodusII_IO::get_num_time_steps()!");
480 std::string system_var_name,
481 std::string exodus_var_name,
482 unsigned int timestep)
485 libmesh_error_msg(
"ERROR, ExodusII file must be opened for reading before copying a nodal solution!");
487 exio_helper->read_nodal_var_values(exodus_var_name, timestep);
492 n_nodal = cast_int<dof_id_type>(
exio_helper->nodal_var_values.size());
502 if ((dof_index >= system.
solution->first_local_index()) && (dof_index < system.solution->last_local_index()))
514 std::string system_var_name,
515 std::string exodus_var_name,
516 unsigned int timestep)
521 libmesh_error_msg(
"ERROR, ExodusII file must be opened for reading before copying an elemental solution!");
528 std::map<dof_id_type, Real> elem_var_value_map;
529 exio_helper->read_elemental_var_values(exodus_var_name, timestep, elem_var_value_map);
533 libmesh_error_msg(
"Error! Trying to copy elemental solution into a variable that is not of CONSTANT MONOMIAL type.");
535 std::map<dof_id_type, Real>::iterator
536 it = elem_var_value_map.begin(),
537 end = elem_var_value_map.end();
539 for (; it!=
end; ++it)
546 system.
solution->set (dof_index, it->second);
556 unsigned int timestep,
557 std::map<unsigned int, Real> & unique_id_to_value_map)
560 std::map<dof_id_type, Real> elem_var_value_map;
562 exio_helper->read_elemental_var_values(elemental_var_name, timestep, elem_var_value_map);
563 for (
auto & pr : elem_var_value_map)
571 unsigned int timestep,
572 std::vector<Real> & global_values)
574 std::size_t size = global_var_names.size();
576 libmesh_error_msg(
"ERROR, empty list of global variables to read from the Exodus file.");
579 std::vector<Real> values_from_exodus;
581 exio_helper->read_global_values(values_from_exodus, timestep);
582 std::vector<std::string> global_var_names_exodus =
exio_helper->global_var_names;
584 global_values.clear();
585 for (std::size_t i = 0; i != size; ++i)
589 auto it = find(global_var_names_exodus.begin(), global_var_names_exodus.end(), global_var_names[i]);
590 if (it != global_var_names_exodus.end())
591 global_values.push_back(values_from_exodus[it - global_var_names_exodus.begin()]);
593 libmesh_error_msg(
"ERROR, Global variable " << global_var_names[i] << \
594 " not found in Exodus file.");
603 libmesh_error_msg(
"ERROR, ExodusII file must be initialized before outputting element variables.");
617 std::vector<std::string> names;
623 std::vector<std::string> monomials;
631 for (
const auto & var : monomials)
633 names.push_back(var);
637 std::vector<Number> soln;
641 std::vector<std::set<subdomain_id_type>> vars_active_subdomains;
654 #ifdef LIBMESH_USE_COMPLEX_NUMBERS 656 std::vector<std::string> complex_names =
exio_helper->get_complex_names(names);
658 std::vector<std::set<subdomain_id_type>> complex_vars_active_subdomains =
659 exio_helper->get_complex_vars_active_subdomains(vars_active_subdomains);
660 exio_helper->initialize_element_variables(complex_names, complex_vars_active_subdomains);
662 unsigned int num_values = soln.size();
663 unsigned int num_vars = names.size();
664 unsigned int num_elems = num_values / num_vars;
668 std::vector<Real> complex_soln(3*num_values);
670 for (
unsigned i=0; i<num_vars; ++i)
673 for (
unsigned int j=0; j<num_elems; ++j)
676 complex_soln[3*i*num_elems + j] =
value.real();
678 for (
unsigned int j=0; j<num_elems; ++j)
681 complex_soln[3*i*num_elems + num_elems +j] =
value.imag();
683 for (
unsigned int j=0; j<num_elems; ++j)
686 complex_soln[3*i*num_elems + 2*num_elems + j] =
std::abs(
value);
693 exio_helper->initialize_element_variables(names, vars_active_subdomains);
701 const std::vector<Number> & soln,
702 const std::vector<std::string> & names)
704 LOG_SCOPE(
"write_nodal_data()",
"ExodusII_IO");
708 int num_vars = cast_int<int>(names.size());
712 std::vector<std::string> output_names;
717 output_names = names;
719 #ifdef LIBMESH_USE_COMPLEX_NUMBERS 721 std::vector<std::string> complex_names =
exio_helper->get_complex_names(names);
735 for (
int c=0; c<num_vars; c++)
737 std::stringstream name_to_find;
739 std::vector<std::string>::iterator pos =
740 std::find(output_names.begin(), output_names.end(), names[c]);
741 if (pos == output_names.end())
744 unsigned int variable_name_position =
745 cast_int<unsigned int>(pos - output_names.begin());
749 #ifdef LIBMESH_USE_REAL_NUMBERS 750 std::vector<Number> cur_soln;
755 cur_soln.reserve(num_nodes);
757 std::vector<Real> real_parts;
758 std::vector<Real> imag_parts;
759 std::vector<Real> magnitudes;
760 real_parts.reserve(num_nodes);
761 imag_parts.reserve(num_nodes);
762 magnitudes.reserve(num_nodes);
772 #ifdef LIBMESH_USE_REAL_NUMBERS 773 cur_soln.push_back(soln[
idx]);
775 real_parts.push_back(soln[
idx].real());
776 imag_parts.push_back(soln[
idx].imag());
782 #ifdef LIBMESH_USE_REAL_NUMBERS 802 libmesh_error_msg(
"ERROR, ExodusII file must be initialized before outputting information records.");
810 const std::vector<std::string> & names)
816 libmesh_error_msg(
"ERROR, ExodusII file must be initialized before outputting global variables.");
818 #ifdef LIBMESH_USE_COMPLEX_NUMBERS 820 std::vector<std::string> complex_names =
exio_helper->get_complex_names(names);
822 exio_helper->initialize_global_variables(complex_names);
824 unsigned int num_values = soln.size();
825 unsigned int num_vars = names.size();
826 unsigned int num_elems = num_values / num_vars;
830 std::vector<Real> complex_soln(3*num_values);
832 for (
unsigned i=0; i<num_vars; ++i)
835 for (
unsigned int j=0; j<num_elems; ++j)
838 complex_soln[3*i*num_elems + j] =
value.real();
840 for (
unsigned int j=0; j<num_elems; ++j)
843 complex_soln[3*i*num_elems + num_elems +j] =
value.imag();
845 for (
unsigned int j=0; j<num_elems; ++j)
848 complex_soln[3*i*num_elems + 2*num_elems + j] =
std::abs(
value);
866 const std::set<std::string> * system_names)
888 libmesh_assert( !
exio_helper->opened_for_writing );
895 libmesh_warning(
"Warning: Appending in ExodusII_IO::write() does not make sense.\n" 896 "Creating a new file instead!");
906 libmesh_warning(
"Warning: Mesh contains edge boundary IDs, but these " 907 "are not supported by the ExodusII format.");
913 const std::vector<Number> & soln,
914 const std::vector<std::string> & names)
916 LOG_SCOPE(
"write_nodal_data_discontinuous()",
"ExodusII_IO");
920 int num_vars = cast_int<int>(names.size());
923 num_nodes += elem->n_nodes();
925 #ifdef LIBMESH_USE_COMPLEX_NUMBERS 927 std::vector<std::string> complex_names =
exio_helper->get_complex_names(names);
940 for (
int c=0; c<num_vars; c++)
942 #ifdef LIBMESH_USE_COMPLEX_NUMBERS 943 std::vector<Real> real_parts(num_nodes);
944 std::vector<Real> imag_parts(num_nodes);
945 std::vector<Real> magnitudes(num_nodes);
947 for (
int i=0; i<num_nodes; ++i)
949 real_parts[i] = soln[i*num_vars + c].real();
950 imag_parts[i] = soln[i*num_vars + c].imag();
951 magnitudes[i] =
std::abs(soln[i*num_vars + c]);
958 std::vector<Number> cur_soln(num_nodes);
960 for (
int i=0; i<num_nodes; i++)
961 cur_soln[i] = soln[i*num_vars + c];
971 const std::vector<std::string> & names,
1007 libmesh_warning(
"Warning: Mesh contains edge boundary IDs, but these " 1008 "are not supported by the ExodusII format.");
1019 libmesh_error_msg(
"Error! This ExodusII_IO object is already associated with file: " \
1021 <<
", cannot use it with requested file: " \
1043 libmesh_experimental();
1062 libmesh_error_msg(
"ERROR, ExodusII API is not defined.");
1069 libmesh_error_msg(
"ERROR, ExodusII API is not defined.");
1076 libmesh_error_msg(
"ERROR, ExodusII API is not defined.");
1083 libmesh_error_msg(
"ERROR, ExodusII API is not defined.");
1090 libmesh_error_msg(
"ERROR, ExodusII API is not defined.");
1097 libmesh_error_msg(
"ERROR, ExodusII API is not defined.");
1104 libmesh_error_msg(
"ERROR, ExodusII API is not defined.");
1111 libmesh_error_msg(
"ERROR, ExodusII API is not defined.");
1120 libmesh_error_msg(
"ERROR, ExodusII API is not defined.");
1130 libmesh_error_msg(
"ERROR, ExodusII API is not defined.");
1137 libmesh_error_msg(
"ERROR, ExodusII API is not defined.");
1143 const std::vector<Number> &,
1144 const std::vector<std::string> &)
1146 libmesh_error_msg(
"ERROR, ExodusII API is not defined.");
1153 libmesh_error_msg(
"ERROR, ExodusII API is not defined.");
1159 const std::vector<std::string> &)
1161 libmesh_error_msg(
"ERROR, ExodusII API is not defined.");
1167 const EquationSystems &,
1170 const std::set<std::string> *)
1172 libmesh_error_msg(
"ERROR, ExodusII API is not defined.");
1179 libmesh_error_msg(
"ERROR, ExodusII API is not defined.");
1185 const std::vector<Number> &,
1186 const std::vector<std::string> &)
1188 libmesh_error_msg(
"ERROR, ExodusII API is not defined.");
1194 const std::vector<std::string> &,
1197 libmesh_error_msg(
"ERROR, ExodusII API is not defined.");
1203 libmesh_error_msg(
"ERROR, ExodusII API is not defined.");
1208 libmesh_error_msg(
"ERROR, ExodusII API is not defined.");
1211 #endif // LIBMESH_HAVE_EXODUS_API std::string name(const ElemQuality q)
Manages the family, order, etc. parameters for a given FE.
void use_mesh_dimension_instead_of_spatial_dimension(bool val)
Manages multiples systems of equations.
virtual void reserve_nodes(const dof_id_type nn)=0
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
void build_variable_names(std::vector< std::string > &var_names, const FEType *type=nullptr, const std::set< std::string > *system_names=nullptr) const
virtual Node *& set_node(const unsigned int i)
A geometric point in (x,y,z) space associated with a DOF.
std::string & nodeset_name(boundary_id_type id)
void write_as_dimension(unsigned dim)
unsigned int n_comp(const unsigned int s, const unsigned int var) const
ExodusII_IO_Helper & get_exio_helper()
virtual void write_equation_systems(const std::string &, const EquationSystems &, const std::set< std::string > *system_names=nullptr)
std::size_t n_edge_conds() const
static const int invalid_id
const Elem * top_parent() const
The base class for all geometric element types.
IntRange< std::size_t > index_range(const std::vector< T > &vec)
ExodusII_IO_Helper::Conversion assign_conversion(std::string type_str)
unique_id_type unique_id() const
const Parallel::Communicator & comm() const
void copy_nodal_solution(System &system, std::string var_name, unsigned int timestep=1)
virtual SimpleRange< element_iterator > active_element_ptr_range()=0
ExodusII_IO(MeshBase &mesh, bool single_precision=false)
const BoundaryInfo & get_boundary_info() const
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
void get_vars_active_subdomains(const std::vector< std::string > &names, std::vector< std::set< subdomain_id_type >> &vars_active_subdomains) const
void write_timestep_discontinuous(const std::string &fname, const EquationSystems &es, const int timestep, const Real time, const std::set< std::string > *system_names=nullptr)
void add_node(const Node *node, const boundary_id_type id)
unsigned int number() const
virtual void write_discontinuous_equation_systems(const std::string &, const EquationSystems &, const std::set< std::string > *system_names=nullptr)
processor_id_type rank() const
void set_output_variables(const std::vector< std::string > &output_variables, bool allow_empty=true)
Manages consistently variables, degrees of freedom, and coefficient vectors.
virtual Elem * add_elem(Elem *e)=0
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
unsigned short int variable_number(const std::string &var) const
virtual SimpleRange< node_iterator > node_ptr_range()=0
void copy_elemental_solution(System &system, std::string system_var_name, std::string exodus_var_name, unsigned int timestep=1)
std::unique_ptr< NumericVector< Number > > solution
const std::vector< Real > & get_time_steps()
std::vector< std::string > _output_variables
void write_information_records(const std::vector< std::string > &)
std::string & subdomain_name(subdomain_id_type id)
void read_elemental_variable(std::string elemental_var_name, unsigned int timestep, std::map< unsigned int, Real > &unique_id_to_value_map)
void set_mesh_dimension(unsigned char d)
void verbose(bool set_verbosity)
void write_nodal_data_common(std::string fname, const std::vector< std::string > &names, bool continuous=true)
An object whose state is distributed along a set of processors.
virtual void read(const std::string &name) override
std::size_t get_shellface_index_offset() const
void read_global_variable(std::vector< std::string > global_var_names, unsigned int timestep, std::vector< Real > &global_values)
std::string & sideset_name(boundary_id_type id)
void write_global_data(const std::vector< Number > &, const std::vector< std::string > &)
void write_nodal_data_discontinuous(const std::string &, const std::vector< Number > &, const std::vector< std::string > &) override
std::string enum_to_string(const T e)
std::unique_ptr< ExodusII_IO_Helper > exio_helper
void write_discontinuous_exodusII(const std::string &name, const EquationSystems &es, const std::set< std::string > *system_names=nullptr)
const FEType & variable_type(const unsigned int i) const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
subdomain_id_type subdomain_id() const
virtual unsigned short dim() const =0
Temporarily serializes a DistributedMesh for output.
virtual void write(const std::string &fname) override
void write_timestep(const std::string &fname, const EquationSystems &es, const int timestep, const Real time, const std::set< std::string > *system_names=nullptr)
const std::vector< std::string > & get_elem_var_names()
void add_side(const dof_id_type elem, const unsigned short int side, const boundary_id_type id)
void add_shellface(const dof_id_type elem, const unsigned short int shellface, const boundary_id_type id)
virtual const Elem & elem_ref(const dof_id_type i) const
unsigned int mesh_dimension() const
void write_element_data(const EquationSystems &es)
bool _allow_empty_variables
virtual const Node * node_ptr(const dof_id_type i) const =0
virtual void write_nodal_data(const std::string &, const std::vector< Number > &, const std::vector< std::string > &) override
processor_id_type processor_id() const
void build_discontinuous_solution_vector(std::vector< Number > &soln, const std::set< std::string > *system_names=nullptr) const
const std::vector< std::string > & get_nodal_var_names()
A geometric point in (x,y,z) space.
virtual void reserve_elem(const dof_id_type ne)=0
virtual dof_id_type n_nodes() const =0
void set_coordinate_offset(Point p)
void build_elemental_solution_vector(std::vector< Number > &soln, std::vector< std::string > &names) const
int get_side_map(int i) const