From b0656c10c100b17b37507981319baf664d837012 Mon Sep 17 00:00:00 2001 From: nuclearkevin <66632997+nuclearkevin@users.noreply.github.com> Date: Sun, 21 Sep 2025 10:58:09 -0500 Subject: [PATCH 1/5] AdaptiveLibMesh. --- include/openmc/mesh.h | 28 +++++++++-- src/mesh.cpp | 109 ++++++++++++++++++++++++------------------ 2 files changed, 88 insertions(+), 49 deletions(-) diff --git a/include/openmc/mesh.h b/include/openmc/mesh.h index fbc6c46f50c..a11bce7d916 100644 --- a/include/openmc/mesh.h +++ b/include/openmc/mesh.h @@ -1022,11 +1022,33 @@ class LibMesh : public UnstructuredMesh { libMesh::BoundingBox bbox_; //!< bounding box of the mesh libMesh::dof_id_type first_element_id_; //!< id of the first element in the mesh +}; + +class AdaptiveLibMesh : public LibMesh { +public: + // Constructors + AdaptiveLibMesh(libMesh::MeshBase& input_mesh, double length_multiplier = 1.0); + + // Overridden Methods + int n_bins() const override; + + void add_score(const std::string& var_name) override; + + void set_score_data(const std::string& var_name, const vector& values, + const vector& std_dev) override; + + void write(const std::string& filename) const override; + + int get_bin_from_element(const libMesh::Elem* elem) const override; + + const libMesh::Elem& get_element_from_bin(int bin) const override; + +private: + const libMesh::dof_id_type num_active_; //!< cached number of active elements - const bool adaptive_; //!< whether this mesh has adaptivity enabled or not std::vector - bin_to_elem_map_; //!< mapping bin indices to dof indices for active - //!< elements + bin_to_elem_map_; //!< mapping bin indices to dof indices for active + //!< elements std::vector elem_to_bin_map_; //!< mapping dof indices to bin indices for //!< active elements }; diff --git a/src/mesh.cpp b/src/mesh.cpp index b7396a25abe..b878be88ab1 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -3219,7 +3219,7 @@ void MOABMesh::write(const std::string& base_filename) const const std::string LibMesh::mesh_lib_type = "libmesh"; -LibMesh::LibMesh(pugi::xml_node node) : UnstructuredMesh(node), adaptive_(false) +LibMesh::LibMesh(pugi::xml_node node) : UnstructuredMesh(node) { // filename_ and length_multiplier_ will already be set by the // UnstructuredMesh constructor @@ -3230,7 +3230,6 @@ LibMesh::LibMesh(pugi::xml_node node) : UnstructuredMesh(node), adaptive_(false) // create the mesh from a pointer to a libMesh Mesh LibMesh::LibMesh(libMesh::MeshBase& input_mesh, double length_multiplier) - : adaptive_(input_mesh.n_active_elem() != input_mesh.n_elem()) { if (!dynamic_cast(&input_mesh)) { fatal_error("At present LibMesh tallies require a replicated mesh. Please " @@ -3244,7 +3243,6 @@ LibMesh::LibMesh(libMesh::MeshBase& input_mesh, double length_multiplier) // create the mesh from an input file LibMesh::LibMesh(const std::string& filename, double length_multiplier) - : adaptive_(false) { n_dimension_ = 3; set_mesh_pointer_from_filename(filename); @@ -3307,21 +3305,6 @@ void LibMesh::initialize() auto first_elem = *m_->elements_begin(); first_element_id_ = first_elem->id(); - // if the mesh is adaptive elements aren't guaranteed by libMesh to be - // contiguous in ID space, so we need to map from bin indices (defined over - // active elements) to global dof ids - if (adaptive_) { - bin_to_elem_map_.reserve(m_->n_active_elem()); - elem_to_bin_map_.resize(m_->n_elem(), -1); - for (auto it = m_->active_elements_begin(); it != m_->active_elements_end(); - it++) { - auto elem = *it; - - bin_to_elem_map_.push_back(elem->id()); - elem_to_bin_map_[elem->id()] = bin_to_elem_map_.size() - 1; - } - } - // bounding box for the mesh for quick rejection checks bbox_ = libMesh::MeshTools::create_bounding_box(*m_); libMesh::Point ll = bbox_.min(); @@ -3379,7 +3362,7 @@ std::string LibMesh::library() const int LibMesh::n_bins() const { - return m_->n_active_elem(); + return m_->n_elem(); } int LibMesh::n_surface_bins() const @@ -3402,14 +3385,6 @@ int LibMesh::n_surface_bins() const void LibMesh::add_score(const std::string& var_name) { - if (adaptive_) { - warning(fmt::format( - "Exodus output cannot be provided as unstructured mesh {} is adaptive.", - this->id_)); - - return; - } - if (!equation_systems_) { build_eqn_sys(); } @@ -3445,14 +3420,6 @@ void LibMesh::remove_scores() void LibMesh::set_score_data(const std::string& var_name, const vector& values, const vector& std_dev) { - if (adaptive_) { - warning(fmt::format( - "Exodus output cannot be provided as unstructured mesh {} is adaptive.", - this->id_)); - - return; - } - if (!equation_systems_) { build_eqn_sys(); } @@ -3496,14 +3463,6 @@ void LibMesh::set_score_data(const std::string& var_name, void LibMesh::write(const std::string& filename) const { - if (adaptive_) { - warning(fmt::format( - "Exodus output cannot be provided as unstructured mesh {} is adaptive.", - this->id_)); - - return; - } - write_message(fmt::format( "Writing file: {}.e for unstructured mesh {}", filename, this->id_)); libMesh::ExodusII_IO exo(*m_); @@ -3537,8 +3496,7 @@ int LibMesh::get_bin(Position r) const int LibMesh::get_bin_from_element(const libMesh::Elem* elem) const { - int bin = - adaptive_ ? elem_to_bin_map_[elem->id()] : elem->id() - first_element_id_; + int bin = elem->id() - first_element_id_; if (bin >= n_bins() || bin < 0) { fatal_error(fmt::format("Invalid bin: {}", bin)); } @@ -3553,7 +3511,7 @@ std::pair, vector> LibMesh::plot( const libMesh::Elem& LibMesh::get_element_from_bin(int bin) const { - return adaptive_ ? m_->elem_ref(bin_to_elem_map_.at(bin)) : m_->elem_ref(bin); + return m_->elem_ref(bin); } double LibMesh::volume(int bin) const @@ -3561,6 +3519,65 @@ double LibMesh::volume(int bin) const return this->get_element_from_bin(bin).volume(); } +AdaptiveLibMesh::AdaptiveLibMesh(libMesh::MeshBase& input_mesh, double length_multiplier) + : LibMesh(input_mesh, length_multiplier), + num_active_(m_->n_active_elem()) +{ + // if the mesh is adaptive elements aren't guaranteed by libMesh to be + // contiguous in ID space, so we need to map from bin indices (defined over + // active elements) to global dof ids + bin_to_elem_map_.reserve(num_active_); + elem_to_bin_map_.resize(m_->n_elem(), -1); + for (auto it = m_->active_elements_begin(); it != m_->active_elements_end(); + it++) { + auto elem = *it; + + bin_to_elem_map_.push_back(elem->id()); + elem_to_bin_map_[elem->id()] = bin_to_elem_map_.size() - 1; + } +} + +int AdaptiveLibMesh::n_bins() const +{ + return num_active_; +} + +void AdaptiveLibMesh::add_score(const std::string& var_name) +{ + warning(fmt::format( + "Exodus output cannot be provided as unstructured mesh {} is adaptive.", + this->id_)); +} + +void AdaptiveLibMesh::set_score_data(const std::string& var_name, const vector& values, + const vector& std_dev) +{ + warning(fmt::format( + "Exodus output cannot be provided as unstructured mesh {} is adaptive.", + this->id_)); +} + +void AdaptiveLibMesh::write(const std::string& filename) const +{ + warning(fmt::format( + "Exodus output cannot be provided as unstructured mesh {} is adaptive.", + this->id_)); +} + +int AdaptiveLibMesh::get_bin_from_element(const libMesh::Elem* elem) const +{ + int bin = elem_to_bin_map_[elem->id()]; + if (bin >= n_bins() || bin < 0) { + fatal_error(fmt::format("Invalid bin: {}", bin)); + } + return bin; +} + +const libMesh::Elem& AdaptiveLibMesh::get_element_from_bin(int bin) const +{ + return m_->elem_ref(bin_to_elem_map_.at(bin)); +} + #endif // OPENMC_LIBMESH_ENABLED //============================================================================== From 9363104c819d21b1cbf7e5e81d46a91fe5da584a Mon Sep 17 00:00:00 2001 From: nuclearkevin <66632997+nuclearkevin@users.noreply.github.com> Date: Sun, 21 Sep 2025 11:22:49 -0500 Subject: [PATCH 2/5] Mark as virtual and swap to protected. --- include/openmc/mesh.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/include/openmc/mesh.h b/include/openmc/mesh.h index a11bce7d916..9971f8faa09 100644 --- a/include/openmc/mesh.h +++ b/include/openmc/mesh.h @@ -990,6 +990,10 @@ class LibMesh : public UnstructuredMesh { libMesh::MeshBase* mesh_ptr() const { return m_; }; +protected: + libMesh::MeshBase* m_; //!< pointer to libMesh MeshBase instance, always set + //!< during intialization + private: void initialize() override; void set_mesh_pointer_from_filename(const std::string& filename); @@ -998,17 +1002,15 @@ class LibMesh : public UnstructuredMesh { // Methods //! Translate a bin value to an element reference - const libMesh::Elem& get_element_from_bin(int bin) const; + virtual const libMesh::Elem& get_element_from_bin(int bin) const; //! Translate an element pointer to a bin index - int get_bin_from_element(const libMesh::Elem* elem) const; + virtual int get_bin_from_element(const libMesh::Elem* elem) const; // Data members unique_ptr unique_m_ = nullptr; //!< pointer to the libMesh MeshBase instance, only used if mesh is //!< created inside OpenMC - libMesh::MeshBase* m_; //!< pointer to libMesh MeshBase instance, always set - //!< during intialization vector> pl_; //!< per-thread point locators unique_ptr From 7a0e4dcdd8800fd7e1eacfe3d481d30cac0783b5 Mon Sep 17 00:00:00 2001 From: nuclearkevin <66632997+nuclearkevin@users.noreply.github.com> Date: Sun, 21 Sep 2025 12:39:42 -0500 Subject: [PATCH 3/5] Formatting. --- include/openmc/mesh.h | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/include/openmc/mesh.h b/include/openmc/mesh.h index 9971f8faa09..b4febd5a6b2 100644 --- a/include/openmc/mesh.h +++ b/include/openmc/mesh.h @@ -991,14 +991,6 @@ class LibMesh : public UnstructuredMesh { libMesh::MeshBase* mesh_ptr() const { return m_; }; protected: - libMesh::MeshBase* m_; //!< pointer to libMesh MeshBase instance, always set - //!< during intialization - -private: - void initialize() override; - void set_mesh_pointer_from_filename(const std::string& filename); - void build_eqn_sys(); - // Methods //! Translate a bin value to an element reference @@ -1007,6 +999,13 @@ class LibMesh : public UnstructuredMesh { //! Translate an element pointer to a bin index virtual int get_bin_from_element(const libMesh::Elem* elem) const; + libMesh::MeshBase* m_; //!< pointer to libMesh MeshBase instance, always set + //!< during intialization +private: + void initialize() override; + void set_mesh_pointer_from_filename(const std::string& filename); + void build_eqn_sys(); + // Data members unique_ptr unique_m_ = nullptr; //!< pointer to the libMesh MeshBase instance, only used if mesh is @@ -1028,10 +1027,10 @@ class LibMesh : public UnstructuredMesh { class AdaptiveLibMesh : public LibMesh { public: - // Constructors + // Constructor AdaptiveLibMesh(libMesh::MeshBase& input_mesh, double length_multiplier = 1.0); - // Overridden Methods + // Overridden methods int n_bins() const override; void add_score(const std::string& var_name) override; @@ -1041,11 +1040,14 @@ class AdaptiveLibMesh : public LibMesh { void write(const std::string& filename) const override; +private: + // Overridden methods + int get_bin_from_element(const libMesh::Elem* elem) const override; const libMesh::Elem& get_element_from_bin(int bin) const override; -private: + // Data members const libMesh::dof_id_type num_active_; //!< cached number of active elements std::vector From ecec2e06daf1e69789c62e5c9515245be0ee702e Mon Sep 17 00:00:00 2001 From: nuclearkevin <66632997+nuclearkevin@users.noreply.github.com> Date: Sun, 21 Sep 2025 12:41:11 -0500 Subject: [PATCH 4/5] Protected. --- include/openmc/mesh.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/openmc/mesh.h b/include/openmc/mesh.h index b4febd5a6b2..d8a1838b03e 100644 --- a/include/openmc/mesh.h +++ b/include/openmc/mesh.h @@ -1040,13 +1040,13 @@ class AdaptiveLibMesh : public LibMesh { void write(const std::string& filename) const override; -private: +protected: // Overridden methods - int get_bin_from_element(const libMesh::Elem* elem) const override; const libMesh::Elem& get_element_from_bin(int bin) const override; +private: // Data members const libMesh::dof_id_type num_active_; //!< cached number of active elements From c2523ff093c0afb380e19fd1258b1de70299914e Mon Sep 17 00:00:00 2001 From: nuclearkevin <66632997+nuclearkevin@users.noreply.github.com> Date: Sun, 21 Sep 2025 12:51:43 -0500 Subject: [PATCH 5/5] Formatting. --- include/openmc/mesh.h | 7 ++++--- src/mesh.cpp | 10 +++++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/include/openmc/mesh.h b/include/openmc/mesh.h index d8a1838b03e..a56705c9ec5 100644 --- a/include/openmc/mesh.h +++ b/include/openmc/mesh.h @@ -1028,7 +1028,8 @@ class LibMesh : public UnstructuredMesh { class AdaptiveLibMesh : public LibMesh { public: // Constructor - AdaptiveLibMesh(libMesh::MeshBase& input_mesh, double length_multiplier = 1.0); + AdaptiveLibMesh( + libMesh::MeshBase& input_mesh, double length_multiplier = 1.0); // Overridden methods int n_bins() const override; @@ -1051,8 +1052,8 @@ class AdaptiveLibMesh : public LibMesh { const libMesh::dof_id_type num_active_; //!< cached number of active elements std::vector - bin_to_elem_map_; //!< mapping bin indices to dof indices for active - //!< elements + bin_to_elem_map_; //!< mapping bin indices to dof indices for active + //!< elements std::vector elem_to_bin_map_; //!< mapping dof indices to bin indices for //!< active elements }; diff --git a/src/mesh.cpp b/src/mesh.cpp index b878be88ab1..58d218b9cad 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -3519,9 +3519,9 @@ double LibMesh::volume(int bin) const return this->get_element_from_bin(bin).volume(); } -AdaptiveLibMesh::AdaptiveLibMesh(libMesh::MeshBase& input_mesh, double length_multiplier) - : LibMesh(input_mesh, length_multiplier), - num_active_(m_->n_active_elem()) +AdaptiveLibMesh::AdaptiveLibMesh( + libMesh::MeshBase& input_mesh, double length_multiplier) + : LibMesh(input_mesh, length_multiplier), num_active_(m_->n_active_elem()) { // if the mesh is adaptive elements aren't guaranteed by libMesh to be // contiguous in ID space, so we need to map from bin indices (defined over @@ -3549,8 +3549,8 @@ void AdaptiveLibMesh::add_score(const std::string& var_name) this->id_)); } -void AdaptiveLibMesh::set_score_data(const std::string& var_name, const vector& values, - const vector& std_dev) +void AdaptiveLibMesh::set_score_data(const std::string& var_name, + const vector& values, const vector& std_dev) { warning(fmt::format( "Exodus output cannot be provided as unstructured mesh {} is adaptive.",