Skip to content

Commit 5847b0d

Browse files
authored
Block restriction of libMesh unstructured mesh tallies (#3694)
1 parent 51ea89c commit 5847b0d

2 files changed

Lines changed: 70 additions & 20 deletions

File tree

include/openmc/mesh.h

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#ifndef OPENMC_MESH_H
55
#define OPENMC_MESH_H
66

7+
#include <set>
78
#include <unordered_map>
89

910
#include "hdf5.h"
@@ -969,7 +970,7 @@ class LibMesh : public UnstructuredMesh {
969970

970971
Position sample_element(int32_t bin, uint64_t* seed) const override;
971972

972-
int get_bin(Position r) const override;
973+
virtual int get_bin(Position r) const override;
973974

974975
int n_bins() const override;
975976

@@ -1007,16 +1008,21 @@ class LibMesh : public UnstructuredMesh {
10071008

10081009
protected:
10091010
// Methods
1010-
10111011
//! Translate a bin value to an element reference
10121012
virtual const libMesh::Elem& get_element_from_bin(int bin) const;
10131013

10141014
//! Translate an element pointer to a bin index
10151015
virtual int get_bin_from_element(const libMesh::Elem* elem) const;
10161016

1017+
// Data members
10171018
libMesh::MeshBase* m_; //!< pointer to libMesh MeshBase instance, always set
10181019
//!< during intialization
1020+
vector<unique_ptr<libMesh::PointLocatorBase>>
1021+
pl_; //!< per-thread point locators
1022+
libMesh::BoundingBox bbox_; //!< bounding box of the mesh
1023+
10191024
private:
1025+
// Methods
10201026
void initialize() override;
10211027
void set_mesh_pointer_from_filename(const std::string& filename);
10221028
void build_eqn_sys();
@@ -1025,8 +1031,6 @@ class LibMesh : public UnstructuredMesh {
10251031
unique_ptr<libMesh::MeshBase> unique_m_ =
10261032
nullptr; //!< pointer to the libMesh MeshBase instance, only used if mesh is
10271033
//!< created inside OpenMC
1028-
vector<unique_ptr<libMesh::PointLocatorBase>>
1029-
pl_; //!< per-thread point locators
10301034
unique_ptr<libMesh::EquationSystems>
10311035
equation_systems_; //!< pointer to the libMesh EquationSystems
10321036
//!< instance
@@ -1035,16 +1039,16 @@ class LibMesh : public UnstructuredMesh {
10351039
std::unordered_map<std::string, unsigned int>
10361040
variable_map_; //!< mapping of variable names (tally scores) to libMesh
10371041
//!< variable numbers
1038-
libMesh::BoundingBox bbox_; //!< bounding box of the mesh
10391042
libMesh::dof_id_type
10401043
first_element_id_; //!< id of the first element in the mesh
10411044
};
10421045

10431046
class AdaptiveLibMesh : public LibMesh {
10441047
public:
10451048
// Constructor
1046-
AdaptiveLibMesh(
1047-
libMesh::MeshBase& input_mesh, double length_multiplier = 1.0);
1049+
AdaptiveLibMesh(libMesh::MeshBase& input_mesh, double length_multiplier = 1.0,
1050+
const std::set<libMesh::subdomain_id_type>& block_ids =
1051+
std::set<libMesh::subdomain_id_type>());
10481052

10491053
// Overridden methods
10501054
int n_bins() const override;
@@ -1056,6 +1060,8 @@ class AdaptiveLibMesh : public LibMesh {
10561060

10571061
void write(const std::string& filename) const override;
10581062

1063+
int get_bin(Position r) const override;
1064+
10591065
protected:
10601066
// Overridden methods
10611067
int get_bin_from_element(const libMesh::Elem* elem) const override;
@@ -1064,6 +1070,9 @@ class AdaptiveLibMesh : public LibMesh {
10641070

10651071
private:
10661072
// Data members
1073+
const std::set<libMesh::subdomain_id_type>
1074+
block_ids_; //!< subdomains of the mesh to tally on
1075+
const bool block_restrict_; //!< whether a subset of the mesh is being used
10671076
const libMesh::dof_id_type num_active_; //!< cached number of active elements
10681077

10691078
std::vector<libMesh::dof_id_type>

src/mesh.cpp

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3485,9 +3485,6 @@ void LibMesh::initialize()
34853485
// assuming that unstructured meshes used in OpenMC are 3D
34863486
n_dimension_ = 3;
34873487

3488-
if (length_multiplier_ > 0.0) {
3489-
libMesh::MeshTools::Modification::scale(*m_, length_multiplier_);
3490-
}
34913488
// if OpenMC is managing the libMesh::MeshBase instance, prepare the mesh.
34923489
// Otherwise assume that it is prepared by its owning application
34933490
if (unique_m_) {
@@ -3537,7 +3534,11 @@ Position LibMesh::centroid(int bin) const
35373534
{
35383535
const auto& elem = this->get_element_from_bin(bin);
35393536
auto centroid = elem.vertex_average();
3540-
return {centroid(0), centroid(1), centroid(2)};
3537+
if (length_multiplier_ > 0.0) {
3538+
return length_multiplier_ * Position(centroid(0), centroid(1), centroid(2));
3539+
} else {
3540+
return {centroid(0), centroid(1), centroid(2)};
3541+
}
35413542
}
35423543

35433544
int LibMesh::n_vertices() const
@@ -3548,7 +3549,11 @@ int LibMesh::n_vertices() const
35483549
Position LibMesh::vertex(int vertex_id) const
35493550
{
35503551
const auto node_ref = m_->node_ref(vertex_id);
3551-
return {node_ref(0), node_ref(1), node_ref(2)};
3552+
if (length_multiplier_ > 0.0) {
3553+
return length_multiplier_ * Position(node_ref(0), node_ref(1), node_ref(2));
3554+
} else {
3555+
return {node_ref(0), node_ref(1), node_ref(2)};
3556+
}
35523557
}
35533558

35543559
std::vector<int> LibMesh::connectivity(int elem_id) const
@@ -3689,6 +3694,11 @@ int LibMesh::get_bin(Position r) const
36893694
// look-up a tet using the point locator
36903695
libMesh::Point p(r.x, r.y, r.z);
36913696

3697+
if (length_multiplier_ > 0.0) {
3698+
// Scale the point down
3699+
p /= length_multiplier_;
3700+
}
3701+
36923702
// quick rejection check
36933703
if (!bbox_.contains_point(p)) {
36943704
return -1;
@@ -3722,22 +3732,32 @@ const libMesh::Elem& LibMesh::get_element_from_bin(int bin) const
37223732

37233733
double LibMesh::volume(int bin) const
37243734
{
3725-
return this->get_element_from_bin(bin).volume();
3735+
return this->get_element_from_bin(bin).volume() * length_multiplier_ *
3736+
length_multiplier_ * length_multiplier_;
37263737
}
37273738

3728-
AdaptiveLibMesh::AdaptiveLibMesh(
3729-
libMesh::MeshBase& input_mesh, double length_multiplier)
3730-
: LibMesh(input_mesh, length_multiplier), num_active_(m_->n_active_elem())
3739+
AdaptiveLibMesh::AdaptiveLibMesh(libMesh::MeshBase& input_mesh,
3740+
double length_multiplier,
3741+
const std::set<libMesh::subdomain_id_type>& block_ids)
3742+
: LibMesh(input_mesh, length_multiplier), block_ids_(block_ids),
3743+
block_restrict_(!block_ids_.empty()),
3744+
num_active_(
3745+
block_restrict_
3746+
? std::distance(m_->active_subdomain_set_elements_begin(block_ids_),
3747+
m_->active_subdomain_set_elements_end(block_ids_))
3748+
: m_->n_active_elem())
37313749
{
37323750
// if the mesh is adaptive elements aren't guaranteed by libMesh to be
37333751
// contiguous in ID space, so we need to map from bin indices (defined over
37343752
// active elements) to global dof ids
37353753
bin_to_elem_map_.reserve(num_active_);
37363754
elem_to_bin_map_.resize(m_->n_elem(), -1);
3737-
for (auto it = m_->active_elements_begin(); it != m_->active_elements_end();
3738-
it++) {
3739-
auto elem = *it;
3740-
3755+
auto begin = block_restrict_
3756+
? m_->active_subdomain_set_elements_begin(block_ids_)
3757+
: m_->active_elements_begin();
3758+
auto end = block_restrict_ ? m_->active_subdomain_set_elements_end(block_ids_)
3759+
: m_->active_elements_end();
3760+
for (const auto& elem : libMesh::as_range(begin, end)) {
37413761
bin_to_elem_map_.push_back(elem->id());
37423762
elem_to_bin_map_[elem->id()] = bin_to_elem_map_.size() - 1;
37433763
}
@@ -3770,6 +3790,27 @@ void AdaptiveLibMesh::write(const std::string& filename) const
37703790
this->id_));
37713791
}
37723792

3793+
int AdaptiveLibMesh::get_bin(Position r) const
3794+
{
3795+
// look-up a tet using the point locator
3796+
libMesh::Point p(r.x, r.y, r.z);
3797+
3798+
if (length_multiplier_ > 0.0) {
3799+
// Scale the point down
3800+
p /= length_multiplier_;
3801+
}
3802+
3803+
// quick rejection check
3804+
if (!bbox_.contains_point(p)) {
3805+
return -1;
3806+
}
3807+
3808+
const auto& point_locator = pl_.at(thread_num());
3809+
3810+
const auto elem_ptr = (*point_locator)(p, &block_ids_);
3811+
return elem_ptr ? get_bin_from_element(elem_ptr) : -1;
3812+
}
3813+
37733814
int AdaptiveLibMesh::get_bin_from_element(const libMesh::Elem* elem) const
37743815
{
37753816
int bin = elem_to_bin_map_[elem->id()];

0 commit comments

Comments
 (0)