-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mesh tally amalgamation #2
base: mesh_tally_post_processing
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Took a look - great work! I've left a few comments which can be divided into C++ / programming style comments and some functional comments.
The only major functional issue I can see so far is in AmalgamationMarker
which is that you're accessing _u_neighbor
, which is not initialized by the base classes (QuadraturePointMarker
and it's ancestors) as they don't participate in element neighbor loops. This is an issue with the marker system (there are no markers that loop over neighbors) which isn't easily solvable. I'll look into adding a new marker base class that addresses this since it's something that's come up a few times now as we've been working with AMR in MOOSE.
include/tallies/MeshTally.h
Outdated
@@ -23,6 +23,7 @@ | |||
|
|||
#include "openmc/tallies/filter_mesh.h" | |||
|
|||
#include "libmesh/mesh.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's generally bad form to include a header file inside another header unless absolutely necessary. In this case, #include/libmesh/mesh.h
should be in MeshTally.C
as it's only used there.
Also, are you sure you need to include libmesh/mesh.h
? We include libmesh/replicated_mesh
in MeshTally.C
, which should provide the same functionality.
src/markers/AmalgamationMarker.C
Outdated
AmalgamationMarker::AmalgamationMarker(const InputParameters& parameters) | ||
: QuadraturePointMarker(parameters) | ||
{ | ||
_tolerance = getParam<Real>("tolerance"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd recommend setting tolerance in the initializer list; it's the preferred approach in C++.
src/markers/AmalgamationMarker.C
Outdated
Real sum=0; | ||
for (unsigned int qp=0;qp<_qrule->n_points();qp++) | ||
{ | ||
sum=sum+_u_neighbor[qp]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use sum += _u_neighbor[qp];
instead.
I also don't think _u_neighbor
is well posed in QuadraturePointMarker
as this base class doesn't participate in element neighbour loops (one of my many gripes with the Indicator / Marker system). This isn't something that's easy to fix, I'll look into it and get back to you on this thought.
src/markers/AmalgamationMarker.C
Outdated
// qurle->n_points() should never be zero. But do I need to use if statement to check? | ||
local_avg=sum/_qrule->n_points(); | ||
//local_avg it could be zero. So ig it needs to be checked | ||
if (local_avg==0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comparing a double (local_avg
) to 0
will almost never return true due to the imprecise nature of floating point arithmetic. I'd use a fuzzy equals instead.
src/tallies/MeshTally.C
Outdated
const unsigned int n_sides = elem_ptr->n_sides(); | ||
for (unsigned int side_id = 0; side_id < n_sides; ++side_id) | ||
{ | ||
const libMesh::Elem* neighbor_ptr = elem_ptr->neighbor(side_id); //maybe wrong |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is correct.
src/tallies/MeshTally.C
Outdated
{ | ||
if (neighbor_ptr->refinement_flag()==Elem::AMALGAMATE) | ||
{ | ||
total_tally_of_the_cluster += tally_vals[local_score](ext_bin * _mesh_filter->n_bins() + side_id + e); //need some clarification on that |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will not work: you'd need an inverse map which goes from element DoF IDs to tally bin IDs (a _total_to_active_mapping
). You'd then do:
auto neighbor_bin = _total_to_active[neighbor_ptr->id()];
total_tally_of_the_cluster += tally_vals[local_score](ext_bin * _mesh_filter->n_bins() + neighbor_bin);
…d only work given that neighbor_ids is subset of the element_ids
include/markers/AmalgamationMarker.h
Outdated
const Real _tolerance; | ||
const Real TOLERENCE=1E-20; // to check if local_avg isn't zero. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this naming choice might be a little unintuitive. What is the difference between _tolerance
and TOLERANCE
? Hard to know from just looking, though you added a comment.
I'm also not sure comparing something to 1E-20
is the best way to check if something is non-zero. IIRC floating point precision means anything 1E-16
or smaller is basically zero. There might be some kind of C++ library function to check if a float is non-zero, but I don't know one off the top of my head.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
libMesh has a built-in tolerance which I would recommend using instead of defining another - you can access it with libMesh::TOLERANCE
.
src/markers/AmalgamationMarker.C
Outdated
Loop over the local elements and store the solution in a Real var*/ | ||
Real local_avg=0; | ||
Real sum=0; | ||
for (unsigned int qp=0;qp<_qrule->n_points();qp++) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this clang-formatted?
{ | ||
sum+=_u[qp]; | ||
} | ||
// qurle->n_points() should never be zero. But do I need to use if statement to check? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You probably want to remove this comment before merging into cardinal. It looks like many places in MOOSE use _qrule -> n_points()
without checking if it's zero.
src/tallies/MeshTally.C
Outdated
//error: 'class openmc::MeshFilter' has no member named 'get_elem' | ||
//openmc::mesh_filter doesn't have anything like get_elem |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean to have this in here? Let's learn about git add -p
src/tallies/MeshTally.C
Outdated
//TODO | ||
//I have to do an inverse map which goes from element DoF IDs to tally bin IDs | ||
//(a _total_to_active_mapping |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this still a TODO or is that what _total_to_active
does?
include/tallies/MeshTally.h
Outdated
@@ -113,4 +114,5 @@ class MeshTally : public TallyBase | |||
std::unique_ptr<libMesh::ReplicatedMesh> _libmesh_mesh_copy; | |||
/// A mapping between the elements in '_libmesh_mesh_copy' and the elements in the MooseMesh. | |||
std::vector<unsigned int> _active_to_total_mapping; | |||
std::unordered_map<unsigned int, unsigned int>_total_to_active_mapping; //hash map for inverse mapping |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be worth having a conversation about what this is named. @nuclearkevin what are your thoughts? I understand it's supposed to be the inverse mapping of element IDs to bins, but I'm not sure _total_to_active_mapping
is a very intuitive name for what it does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original intent of the name for _active_to_total_mapping
(and now _total_to_active_mapping
) was to indicate that we're mapping from active elements to all elements. This uses libMesh's AMR terminology, where active elements are the elements participating in the solve (in the case of MeshTally
the elements getting tallied on) and all elements includes the parent/child elements in the refinement hierarchy.
It's not the most intuitive naming scheme and I'm open to changing it to _bin_to_element_mapping
and _element_to_bin_mapping
(especially since we've added block restriction to MeshTally
which uses _active_to_total_mapping
) in an attempt to make the purpose of these maps clearer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@magnoxemo we've merged the proposed name change into Cardinal (_active_to_total_mapping
is now _bin_to_total_mapping
). You should be good to change the name of _total_to_active_mapping
to _element_to_bin_mapping
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am on it
Element Amalgamation - Post-Processing
This PR is for doing the element amalgamation in the post-processing. Once OpenMC is done with its simulation, Cardinal will read the mesh data. We can get the
element_id
and use it to get the current MOOSE element:libMesh::Elem* elem_ptr = _mesh_filter->get_elem(elem_id);
Then we can check if that element is marked for
AMALGAMATION
:if (elem_ptr->refinement_flag() == Elem::AMALGAMATE)
.If the element is marked for
AMALGAMATION
, we have to find the cluster (for now, elements could be clustered only with the neighboring elements).Real total_tally_of_the_cluster = tally_vals[local_score](ext_bin * _mesh_filter->n_bins() + e);
Real total_volume_of_the_cluster = elem_ptr->volume();
We iterate through the neighbor elements (todo: need to check if the mapping is correct or not), and if they are also marked for
AMALGAMATION
, we incrementtotal_tally_of_the_cluster
andtotal_volume_of_the_cluster
. Finally, the volumetric mean is calculated as:Real power_fraction = elem_ptr->volume() * total_tally_of_the_cluster / total_volume_of_the_cluster;
.If the
if (elem_ptr->refinement_flag() != Elem::AMALGAMATE)
, then presume the normal operation.confusion:
total_tally_of_the_cluster += tally_vals[local_score](ext_bin * _mesh_filter->n_bins() + side_id*e); //need some clarification on that
(not sure but igside_id
ande
they aren't of the same data type)@gonuke