diff --git a/include/openmc/mesh.h b/include/openmc/mesh.h index 21c58862d9..02bd3bc5a2 100644 --- a/include/openmc/mesh.h +++ b/include/openmc/mesh.h @@ -7,13 +7,14 @@ #include #include "hdf5.h" -#include "pugixml.hpp" #include "xtensor/xtensor.hpp" +#include "pugixml.hpp" #include "openmc/memory.h" // for unique_ptr #include "openmc/particle.h" #include "openmc/position.h" #include "openmc/vector.h" +#include "openmc/xml_interface.h" #ifdef DAGMC #include "moab/AdaptiveKDTree.hpp" @@ -53,7 +54,7 @@ extern vector> meshes; #ifdef LIBMESH namespace settings { -// used when creating new libMesh::Mesh instances +// used when creating new libMesh::MeshBase instances extern unique_ptr libmesh_init; extern const libMesh::Parallel::Communicator* libmesh_comm; } // namespace settings @@ -671,7 +672,8 @@ class LibMesh : public UnstructuredMesh { public: // Constructors LibMesh(pugi::xml_node node); - LibMesh(const std::string& filename, double length_multiplier = 1.0); + LibMesh(const std::string & filename, double length_multiplier = 1.0); + LibMesh(libMesh::MeshBase & input_mesh, double length_multiplier = 1.0); static const std::string mesh_lib_type; @@ -703,8 +705,11 @@ public: double volume(int bin) const override; + libMesh::MeshBase* mesh_ptr() const { return m_; }; + private: void initialize() override; + void set_mesh_pointer_from_filename(const std::string& filename); // Methods @@ -715,7 +720,8 @@ private: int get_bin_from_element(const libMesh::Elem* elem) const; // Data members - unique_ptr m_; //!< pointer to the libMesh mesh instance + 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 diff --git a/src/mesh.cpp b/src/mesh.cpp index e8f79aa37a..a8d57eef15 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -2324,16 +2324,37 @@ const std::string LibMesh::mesh_lib_type = "libmesh"; LibMesh::LibMesh(pugi::xml_node node) : UnstructuredMesh(node) { + // filename_ and length_multiplier_ will already be set by the UnstructuredMesh constructor + set_mesh_pointer_from_filename(filename_); + set_length_multiplier(length_multiplier_); initialize(); } -LibMesh::LibMesh(const std::string& filename, double length_multiplier) +// create the mesh from a pointer to a libMesh Mesh +LibMesh::LibMesh(libMesh::MeshBase & input_mesh, double length_multiplier) { - filename_ = filename; + m_ = &input_mesh; set_length_multiplier(length_multiplier); initialize(); } +// create the mesh from an input file +LibMesh::LibMesh(const std::string& filename, double length_multiplier) +{ + set_mesh_pointer_from_filename(filename); + set_length_multiplier(length_multiplier); + initialize(); +} + +void LibMesh::set_mesh_pointer_from_filename(const std::string& filename) +{ + filename_ = filename; + unique_m_ = make_unique(*settings::libmesh_comm, n_dimension_); + m_ = unique_m_.get(); + m_->read(filename_); +} + +// intialize from mesh file void LibMesh::initialize() { if (!settings::libmesh_comm) { @@ -2344,14 +2365,14 @@ void LibMesh::initialize() // assuming that unstructured meshes used in OpenMC are 3D n_dimension_ = 3; - m_ = make_unique(*settings::libmesh_comm, n_dimension_); - m_->read(filename_); - if (specified_length_multiplier_) { libMesh::MeshTools::Modification::scale(*m_, length_multiplier_); } - - m_->prepare_for_use(); + // if OpenMC is managing the libMesh::MeshBase instance, prepare the mesh. + // Otherwise assume that it is prepared by its owning application + if (unique_m_) { + m_->prepare_for_use(); + } // ensure that the loaded mesh is 3 dimensional if (m_->mesh_dimension() != n_dimension_) {