diff --git a/include/base/OpenMCCellAverageProblem.h b/include/base/OpenMCCellAverageProblem.h index 3ff51e059..00848eed1 100644 --- a/include/base/OpenMCCellAverageProblem.h +++ b/include/base/OpenMCCellAverageProblem.h @@ -21,6 +21,7 @@ #include "OpenMCProblemBase.h" #include "SymmetryPointGenerator.h" #include "OpenMCVolumeCalculation.h" +#include "MooseMesh.h" /// Tally/filter includes. #include "TallyBase.h" @@ -870,6 +871,9 @@ class OpenMCCellAverageProblem : public OpenMCProblemBase */ const bool _needs_global_tally; + /// Whether OpenMCCellAverageProblem should use the displaced mesh + const bool & _use_displaced; + /** * A map of the filter objects created by the [Problem/Filters] block. The key for each filter is * it's corresponding MOOSE name to allow tallies to look up filters. @@ -1030,6 +1034,9 @@ class OpenMCCellAverageProblem : public OpenMCProblemBase /// Number of particles simulated in the first iteration unsigned int _n_particles_1; + // Get a modifyable reference to the Moose mesh + virtual const MooseMesh & getMooseMesh() const; + /// Mapping from temperature variable name to the subdomains on which to read it from std::map> _temp_vars_to_blocks; diff --git a/include/tallies/CellTally.h b/include/tallies/CellTally.h index 5de5e7ac1..69ac3dd1d 100644 --- a/include/tallies/CellTally.h +++ b/include/tallies/CellTally.h @@ -20,9 +20,13 @@ #include "TallyBase.h" #include "OpenMCCellAverageProblem.h" +#include "MooseMesh.h" #include "openmc/tallies/filter_cell.h" +class OpenMCCellAverageProblem; +class MooseMesh; + class CellTally : public TallyBase { public: @@ -97,4 +101,10 @@ class CellTally : public TallyBase /// Absolute tolerance for checking equal tally mapped volumes const Real & _equal_tally_volume_abs_tol; + + /// Whether the skinned mesh should be generated from a displaced mesh + const bool & _use_displaced; + + /// Moose mesh + MooseMesh & getMooseMesh(); }; diff --git a/include/tallies/MeshTally.h b/include/tallies/MeshTally.h index b0c162bfb..e04131375 100644 --- a/include/tallies/MeshTally.h +++ b/include/tallies/MeshTally.h @@ -20,9 +20,13 @@ #include "TallyBase.h" #include "OpenMCCellAverageProblem.h" +#include "MooseMesh.h" #include "openmc/tallies/filter_mesh.h" +class OpenMCCellAverageProblem; +class MooseMesh; + class MeshTally : public TallyBase { public: @@ -63,7 +67,7 @@ class MeshTally : public TallyBase * each element. This function performs as many checks as possible to ensure that the meshes * are indeed identical. */ - void checkMeshTemplateAndTranslations() const; + void checkMeshTemplateAndTranslations(); /** * Mesh template file to use for creating mesh tallies in OpenMC; currently, this mesh @@ -90,4 +94,10 @@ class MeshTally : public TallyBase /// OpenMC unstructured mesh instance for use with mesh tallies const openmc::LibMesh * _mesh_template; + + /// Whether the skinned mesh should be generated from a displaced mesh + const bool & _use_displaced; + + /// Moose mesh + MooseMesh & getMooseMesh(); }; diff --git a/include/tallies/TallyBase.h b/include/tallies/TallyBase.h index 6d0e6337c..826160545 100644 --- a/include/tallies/TallyBase.h +++ b/include/tallies/TallyBase.h @@ -20,6 +20,7 @@ #include "MooseObject.h" #include "CardinalEnums.h" +#include "MooseMesh.h" #include "openmc/tallies/tally.h" #include "xtensor/xview.hpp" @@ -301,4 +302,10 @@ class TallyBase : public MooseObject /// Tolerance for setting zero tally static constexpr Real ZERO_TALLY_THRESHOLD = 1e-12; + + /// Whether the skinned mesh should be generated from a displaced mesh + const bool & _use_displaced; + + /// Moose mesh + MooseMesh & getMooseMesh(); }; diff --git a/include/userobjects/OpenMCVolumeCalculation.h b/include/userobjects/OpenMCVolumeCalculation.h index c0db52f03..c73184808 100644 --- a/include/userobjects/OpenMCVolumeCalculation.h +++ b/include/userobjects/OpenMCVolumeCalculation.h @@ -79,6 +79,9 @@ class OpenMCVolumeCalculation : public GeneralUserObject /// Upper right of the box within which to compute OpenMC volumes Point _upper_right; + /// Get a modifyable reference to the Moose mesh + MooseMesh & getMooseMesh(); + /// Volume calculation object std::unique_ptr _volume_calc; diff --git a/src/base/OpenMCCellAverageProblem.C b/src/base/OpenMCCellAverageProblem.C index b047818ee..309320b1a 100644 --- a/src/base/OpenMCCellAverageProblem.C +++ b/src/base/OpenMCCellAverageProblem.C @@ -20,6 +20,7 @@ #include "OpenMCCellAverageProblem.h" #include "DelimitedFileReader.h" +#include "DisplacedProblem.h" #include "TallyBase.h" #include "CellTally.h" #include "AddTallyAction.h" @@ -164,7 +165,9 @@ OpenMCCellAverageProblem::validParams() params.addParam("first_iteration_particles", "Number of particles to use for first iteration " "when using Dufek-Gudowski relaxation"); - + params.addParam("use_displaced_mesh", + false, + "Whether OpenMCCellAverageProblem should use the displaced mesh "); params.addParam( "symmetry_mapper", "User object (of type SymmetryPointGenerator) " @@ -207,6 +210,7 @@ OpenMCCellAverageProblem::OpenMCCellAverageProblem(const InputParameters & param _specified_temperature_feedback(params.isParamSetByUser("temperature_blocks")), _needs_to_map_cells(_specified_density_feedback || _specified_temperature_feedback), _needs_global_tally(_check_tally_sum || _normalize_by_global), + _use_displaced(getParam("use_displaced_mesh")), _volume_calc(nullptr), _symmetry(nullptr) { @@ -368,6 +372,16 @@ OpenMCCellAverageProblem::OpenMCCellAverageProblem(const InputParameters & param } } +const MooseMesh & +OpenMCCellAverageProblem::getMooseMesh() const +{ + if (_use_displaced && !_displaced_problem && !_first_transfer) + mooseWarning("Displaced mesh was requested but the displaced problem does not exist. " + "Regular mesh will be returned"); + return ((_use_displaced && _displaced_problem && !_first_transfer) ? _displaced_problem->mesh() + : mesh()); +} + void OpenMCCellAverageProblem::readBlockVariables( const std::string & param, @@ -545,9 +559,9 @@ OpenMCCellAverageProblem::setupProblem() { // establish the local -> global element mapping for convenience _local_to_global_elem.clear(); - for (unsigned int e = 0; e < _mesh.nElem(); ++e) + for (unsigned int e = 0; e < getMooseMesh().nElem(); ++e) { - const auto * elem = _mesh.queryElemPtr(e); + const auto * elem = getMooseMesh().queryElemPtr(e); if (!isLocalElem(elem)) continue; @@ -633,7 +647,7 @@ OpenMCCellAverageProblem::readBlockParameters(const std::string name, auto names = getParam>(name); checkEmptyVector(names, "'" + name + "'"); - auto b_ids = _mesh.getSubdomainIDs(names); + auto b_ids = getMooseMesh().getSubdomainIDs(names); std::copy(b_ids.begin(), b_ids.end(), std::inserter(blocks, blocks.end())); checkBlocksInMesh(name, b_ids, names); } @@ -644,7 +658,7 @@ OpenMCCellAverageProblem::checkBlocksInMesh(const std::string name, const std::vector & ids, const std::vector & names) const { - const auto & subdomains = _mesh.meshSubdomains(); + const auto & subdomains = getMooseMesh().meshSubdomains(); for (std::size_t b = 0; b < names.size(); ++b) if (subdomains.find(ids[b]) == subdomains.end()) mooseError("Block '" + names[b] + "' specified in '" + name + "' " + "not found in mesh!"); @@ -672,7 +686,7 @@ OpenMCCellAverageProblem::read2DBlockParameters(const std::string name, for (const auto & i : slice) flattened_names.push_back(i); - flattened_ids = _mesh.getSubdomainIDs(flattened_names); + flattened_ids = getMooseMesh().getSubdomainIDs(flattened_names); checkBlocksInMesh(name, flattened_ids, flattened_names); // should not be any duplicate blocks @@ -742,8 +756,8 @@ OpenMCCellAverageProblem::storeElementPhase() for (const auto & s : excl_density_blocks) _n_moose_density_elems += numElemsInSubdomain(s); - _n_moose_none_elems = - _mesh.nElem() - _n_moose_temp_density_elems - _n_moose_temp_elems - _n_moose_density_elems; + _n_moose_none_elems = getMooseMesh().nElem() - _n_moose_temp_density_elems - _n_moose_temp_elems - + _n_moose_density_elems; } void @@ -757,7 +771,7 @@ OpenMCCellAverageProblem::computeCellMappedVolumes() for (const auto & e : c.second) { // we are looping over local elements, so no need to check for nullptr - const auto * elem = _mesh.queryElemPtr(globalElemID(e)); + const auto * elem = getMooseMesh().queryElemPtr(globalElemID(e)); vol += elem->volume(); } @@ -837,7 +851,7 @@ OpenMCCellAverageProblem::getCellMappedPhase() // we are looping over local elements, so no need to check for nullptr for (const auto & e : c.second) - f[elemFeedback(_mesh.queryElemPtr(globalElemID(e)))]++; + f[elemFeedback(getMooseMesh().queryElemPtr(globalElemID(e)))]++; cells_n_temp.push_back(f[coupling::temperature]); cells_n_temp_rho.push_back(f[coupling::density_and_temperature]); @@ -998,7 +1012,7 @@ OpenMCCellAverageProblem::printAuxVariableIO() VariadicTable aux( {"Subdomain", "Temperature", "Density"}); - for (const auto & s : _mesh.meshSubdomains()) + for (const auto & s : getMooseMesh().meshSubdomains()) { std::string temp = _subdomain_to_temp_vars.count(s) ? _subdomain_to_temp_vars[s].second : ""; std::string rho = @@ -1058,7 +1072,7 @@ OpenMCCellAverageProblem::getCellMappedSubdomains() for (const auto & e : c.second) { // we are looping over local elements, so no need to check for nullptr - const auto * elem = _mesh.queryElemPtr(globalElemID(e)); + const auto * elem = getMooseMesh().queryElemPtr(globalElemID(e)); elem_ids.push_back(elem->subdomain_id()); } } @@ -1325,9 +1339,10 @@ OpenMCCellAverageProblem::initializeElementToCellMapping() mooseError("Did not find any overlap between MOOSE elements and OpenMC cells for " "the specified blocks!"); - _console << "\nMapping between " + Moose::stringify(_mesh.nElem()) + " MOOSE elements and " + - Moose::stringify(_n_openmc_cells) + " OpenMC cells (on " + - Moose::stringify(openmc::model::n_coord_levels) + " coordinate levels):" + _console << "\nMapping between " + Moose::stringify(getMooseMesh().nElem()) + + " MOOSE elements and " + Moose::stringify(_n_openmc_cells) + + " OpenMC cells (on " + Moose::stringify(openmc::model::n_coord_levels) + + " coordinate levels):" << std::endl; VariadicTable vt( @@ -1633,13 +1648,14 @@ OpenMCCellAverageProblem::mapElemsToCells() // reset data structures _elem_to_cell.clear(); _cell_to_elem.clear(); + _subdomain_to_material.clear(); _flattened_ids.clear(); _flattened_instances.clear(); int local_elem = -1; - for (unsigned int e = 0; e < _mesh.nElem(); ++e) + for (unsigned int e = 0; e < getMooseMesh().nElem(); ++e) { - const auto * elem = _mesh.queryElemPtr(e); + const auto * elem = getMooseMesh().queryElemPtr(e); if (!isLocalElem(elem)) continue; @@ -1764,8 +1780,8 @@ OpenMCCellAverageProblem::mapElemsToCells() gatherCellVector(elems, n_elems, _cell_to_elem); // fill out the elem_to_cell structure - _elem_to_cell.resize(_mesh.nElem()); - for (unsigned int e = 0; e < _mesh.nElem(); ++e) + _elem_to_cell.resize(getMooseMesh().nElem()); + for (unsigned int e = 0; e < getMooseMesh().nElem(); ++e) _elem_to_cell[e] = {UNMAPPED, UNMAPPED}; for (const auto & c : _cell_to_elem) @@ -1784,7 +1800,7 @@ OpenMCCellAverageProblem::getPointInCell() for (const auto & c : _local_cell_to_elem) { // we are only dealing with local elements here, no need to check for nullptr - const Elem * elem = _mesh.queryElemPtr(globalElemID(c.second[0])); + const Elem * elem = getMooseMesh().queryElemPtr(globalElemID(c.second[0])); const Point & p = elem->vertex_average(); x.push_back(p(0)); @@ -1974,7 +1990,7 @@ OpenMCCellAverageProblem::addExternalVariables() { auto number = addExternalVariable(v.first, &v.second); - auto ids = _mesh.getSubdomainIDs(v.second); + auto ids = getMooseMesh().getSubdomainIDs(v.second); for (const auto & s : ids) _subdomain_to_density_vars[s] = {number, v.first}; } @@ -1984,7 +2000,7 @@ OpenMCCellAverageProblem::addExternalVariables() { auto number = addExternalVariable(v.first, &v.second); - auto ids = _mesh.getSubdomainIDs(v.second); + auto ids = getMooseMesh().getSubdomainIDs(v.second); for (const auto & s : ids) _subdomain_to_temp_vars[s] = {number, v.first}; } @@ -2049,7 +2065,7 @@ OpenMCCellAverageProblem::computeVolumeWeightedCellInput( for (const auto & e : c.second) { // we are only accessing local elements here, so no need to check for nullptr - const auto * elem = _mesh.queryElemPtr(globalElemID(e)); + const auto * elem = getMooseMesh().queryElemPtr(globalElemID(e)); auto v = var_num.at(elem->subdomain_id()).first; auto dof_idx = elem->dof_number(sys_number, v, 0); product += (*_serialized_solution)(dof_idx) * elem->volume(); @@ -2322,6 +2338,10 @@ OpenMCCellAverageProblem::syncSolutions(ExternalProblem::Direction direction) if (_volume_calc) _volume_calc->resetVolumeCalculation(); + if (_use_displaced) + { + _displaced_problem->updateMesh(); + } resetTallies(); setupProblem(); } diff --git a/src/tallies/CellTally.C b/src/tallies/CellTally.C index c55af7065..b7d1f3348 100644 --- a/src/tallies/CellTally.C +++ b/src/tallies/CellTally.C @@ -18,6 +18,7 @@ #ifdef ENABLE_OPENMC_COUPLING #include "CellTally.h" +#include "DisplacedProblem.h" registerMooseObject("CardinalApp", CellTally); @@ -41,6 +42,9 @@ CellTally::validParams() 1e-8, "equal_tally_volume_abs_tol > 0", "Absolute tolerance for comparing tally volumes"); + params.addParam("use_displaced_mesh", + false, + "Whether the skinned mesh should be generated from a displaced mesh "); return params; } @@ -48,7 +52,8 @@ CellTally::validParams() CellTally::CellTally(const InputParameters & parameters) : TallyBase(parameters), _check_equal_mapped_tally_volumes(getParam("check_equal_mapped_tally_volumes")), - _equal_tally_volume_abs_tol(getParam("equal_tally_volume_abs_tol")) + _equal_tally_volume_abs_tol(getParam("equal_tally_volume_abs_tol")), + _use_displaced(getParam("use_displaced_mesh")) { if (isParamValid("blocks")) { @@ -56,12 +61,12 @@ CellTally::CellTally(const InputParameters & parameters) if (block_names.empty()) mooseError("Subdomain names must be provided if using 'blocks'!"); - auto block_ids = _mesh.getSubdomainIDs(block_names); + auto block_ids = getMooseMesh().getSubdomainIDs(block_names); std::copy( block_ids.begin(), block_ids.end(), std::inserter(_tally_blocks, _tally_blocks.end())); // Check to make sure all of the blocks are in the mesh. - const auto & subdomains = _mesh.meshSubdomains(); + const auto & subdomains = getMooseMesh().meshSubdomains(); for (std::size_t b = 0; b < block_names.size(); ++b) if (subdomains.find(block_ids[b]) == subdomains.end()) mooseError("Block '" + block_names[b] + "' specified in 'blocks' not found in mesh!"); @@ -69,7 +74,7 @@ CellTally::CellTally(const InputParameters & parameters) else { // Tally over all mesh blocks if no blocks are provided. - for (const auto & s : _mesh.meshSubdomains()) + for (const auto & s : getMooseMesh().meshSubdomains()) _tally_blocks.insert(s); } } @@ -179,9 +184,24 @@ CellTally::checkCellMappedSubdomains() } } +MooseMesh & +CellTally::getMooseMesh() +{ + if (_use_displaced && _openmc_problem.getDisplacedProblem() == nullptr) + mooseError("Displaced mesh was requested but the displaced problem does not exist. " + "set use_displaced_mesh = False"); + return ((_use_displaced && _openmc_problem.getDisplacedProblem()) + ? _openmc_problem.getDisplacedProblem()->mesh() + : _openmc_problem.mesh()); +} + std::vector CellTally::getTallyCells() const { + if (_use_displaced) + { + _openmc_problem.getDisplacedProblem()->updateMesh(); + } bool is_first_tally_cell = true; OpenMCCellAverageProblem::cellInfo first_tally_cell; Real mapped_tally_volume; diff --git a/src/tallies/MeshTally.C b/src/tallies/MeshTally.C index eca317453..430943d71 100644 --- a/src/tallies/MeshTally.C +++ b/src/tallies/MeshTally.C @@ -18,6 +18,7 @@ #ifdef ENABLE_OPENMC_COUPLING #include "MeshTally.h" +#include "DisplacedProblem.h" registerMooseObject("CardinalApp", MeshTally); @@ -37,6 +38,9 @@ MeshTally::validParams() // The index of this tally into an array of mesh translations. Defaults to zero. params.addPrivateParam("instance", 0); + params.addParam("use_displaced_mesh", + false, + "Whether the skinned mesh should be generated from a displaced mesh "); return params; } @@ -45,7 +49,8 @@ MeshTally::MeshTally(const InputParameters & parameters) : TallyBase(parameters), _mesh_translation(isParamValid("mesh_translation") ? getParam("mesh_translation") : Point(0.0, 0.0, 0.0)), - _instance(getParam("instance")) + _instance(getParam("instance")), + _use_displaced(getParam("use_displaced_mesh")) { // Error check the estimators. if (isParamValid("estimator")) @@ -57,7 +62,7 @@ MeshTally::MeshTally(const InputParameters & parameters) _estimator = openmc::TallyEstimator::COLLISION; // Error check the mesh template. - if (_mesh.getMesh().allow_renumbering() && !_mesh.getMesh().is_replicated()) + if (getMooseMesh().getMesh().allow_renumbering() && !getMooseMesh().getMesh().is_replicated()) mooseError( "Mesh tallies currently require 'allow_renumbering = false' to be set in the [Mesh]!"); @@ -75,7 +80,7 @@ MeshTally::MeshTally(const InputParameters & parameters) // for distributed meshes, each rank only owns a portion of the mesh information, but // OpenMC wants the entire mesh to be available on every rank. We might be able to add // this feature in the future, but will need to investigate - if (!_mesh.getMesh().is_replicated()) + if (!getMooseMesh().getMesh().is_replicated()) mooseError("Directly tallying on the [Mesh] block by OpenMC is not yet supported " "for distributed meshes!"); @@ -99,7 +104,8 @@ MeshTally::spatialFilter() // Create the OpenMC mesh which will be tallied on. std::unique_ptr tally_mesh; if (!_mesh_template_filename) - tally_mesh = std::make_unique(_mesh.getMesh(), _openmc_problem.scaling()); + tally_mesh = + std::make_unique(getMooseMesh().getMesh(), _openmc_problem.scaling()); else tally_mesh = std::make_unique(*_mesh_template_filename, _openmc_problem.scaling()); @@ -165,18 +171,33 @@ MeshTally::storeResultsInner(const std::vector & var_numbers, return total; } +MooseMesh & +MeshTally::getMooseMesh() +{ + if (_use_displaced && _openmc_problem.getDisplacedProblem() == nullptr) + mooseError("Displaced mesh was requested but the displaced problem does not exist. " + "set use_displaced_mesh = False"); + return ((_use_displaced && _openmc_problem.getDisplacedProblem()) + ? _openmc_problem.getDisplacedProblem()->mesh() + : _openmc_problem.mesh()); +} + void -MeshTally::checkMeshTemplateAndTranslations() const +MeshTally::checkMeshTemplateAndTranslations() { // we can do some rudimentary checking on the mesh template by comparing the centroid // coordinates compared to centroids in the [Mesh] (because right now, we just doing a simple // copy transfer that necessitates the meshes to have the same elements in the same order). In // other words, you might have two meshes that represent the same geometry, the element ordering // could be different. + if (_use_displaced) + { + _openmc_problem.getDisplacedProblem()->updateMesh(); + } unsigned int mesh_offset = _instance * _mesh_filter->n_bins(); for (int e = 0; e < _mesh_filter->n_bins(); ++e) { - auto elem_ptr = _mesh.queryElemPtr(mesh_offset + e); + auto elem_ptr = getMooseMesh().queryElemPtr(mesh_offset + e); // if element is not on this part of the distributed mesh, skip it if (!elem_ptr) diff --git a/src/tallies/TallyBase.C b/src/tallies/TallyBase.C index 99b378520..adf405cc5 100644 --- a/src/tallies/TallyBase.C +++ b/src/tallies/TallyBase.C @@ -18,6 +18,7 @@ #ifdef ENABLE_OPENMC_COUPLING #include "TallyBase.h" +#include "DisplacedProblem.h" #include "OpenMCCellAverageProblem.h" #include "UserErrorChecking.h" @@ -73,6 +74,9 @@ TallyBase::validParams() params.registerBase("Tally"); params.registerSystemAttributeName("Tally"); + params.addParam("use_displaced_mesh", + false, + "Whether the skinned mesh should be generated from a displaced mesh "); return params; } @@ -85,7 +89,8 @@ TallyBase::TallyBase(const InputParameters & parameters) _tally_trigger(isParamValid("trigger") ? &getParam("trigger") : nullptr), _trigger_ignore_zeros(getParam>("trigger_ignore_zeros")), _renames_tally_vars(isParamValid("name")), - _has_outputs(isParamValid("output")) + _has_outputs(isParamValid("output")), + _use_displaced(getParam("use_displaced_mesh")) { if (isParamValid("score")) { @@ -232,6 +237,17 @@ TallyBase::TallyBase(const InputParameters & parameters) _previous_tally.resize(_tally_score.size()); } +MooseMesh & +TallyBase::getMooseMesh() +{ + if (_use_displaced && _openmc_problem.getDisplacedProblem() == nullptr) + mooseError("Displaced mesh was requested but the displaced problem does not exist. " + "set use_displaced_mesh = False"); + return ((_use_displaced && _openmc_problem.getDisplacedProblem()) + ? _openmc_problem.getDisplacedProblem()->mesh() + : _openmc_problem.mesh()); +} + void TallyBase::initializeTally() { @@ -281,6 +297,10 @@ TallyBase::storeResults(const std::vector & var_numbers, unsigned int global_score, const std::string & output_type) { + if (_use_displaced) + { + _openmc_problem.getDisplacedProblem()->updateMesh(); + } Real total = 0.0; if (output_type == "relaxed") @@ -382,7 +402,7 @@ TallyBase::fillElementalAuxVariable(const unsigned int & var_num, // loop over all the elements and set the specified variable to the specified value for (const auto & e : elem_ids) { - auto elem_ptr = _mesh.queryElemPtr(e); + auto elem_ptr = getMooseMesh().queryElemPtr(e); if (!_openmc_problem.isLocalElem(elem_ptr)) continue; diff --git a/src/userobjects/OpenMCVolumeCalculation.C b/src/userobjects/OpenMCVolumeCalculation.C index 34622d2e1..6c9b4e702 100644 --- a/src/userobjects/OpenMCVolumeCalculation.C +++ b/src/userobjects/OpenMCVolumeCalculation.C @@ -21,6 +21,7 @@ #include "OpenMCVolumeCalculation.h" #include "OpenMCCellAverageProblem.h" #include "UserErrorChecking.h" +#include "DisplacedProblem.h" registerMooseObject("CardinalApp", OpenMCVolumeCalculation); @@ -73,13 +74,10 @@ OpenMCVolumeCalculation::OpenMCVolumeCalculation(const InputParameters & paramet _scaling = openmc_problem->scaling(); - BoundingBox box = MeshTools::create_bounding_box(_fe_problem.mesh()); - _lower_left = isParamValid("lower_left") ? getParam("lower_left") : box.min(); - _upper_right = isParamValid("upper_right") ? getParam("upper_right") : box.max(); - - if (_lower_left >= _upper_right) - mooseError("The 'upper_right' (", _upper_right(0), ", ", _upper_right(1), ", ", _upper_right(2), ") " - "must be greater than the 'lower_left' (", _lower_left(0), ", ", _lower_left(1), ", ", _lower_left(2), ")!"); + if (isParamValid("lower_left")) + _lower_left = getParam("lower_left"); + if (isParamValid("upper_right")) + _upper_right = getParam("upper_right"); } openmc::Position @@ -96,9 +94,41 @@ OpenMCVolumeCalculation::resetVolumeCalculation() openmc::model::volume_calcs.erase(idx); } +MooseMesh & +OpenMCVolumeCalculation::getMooseMesh() +{ + return ((_fe_problem.getDisplacedProblem()) ? _fe_problem.getDisplacedProblem()->mesh() + : _fe_problem.mesh()); +} + void OpenMCVolumeCalculation::initializeVolumeCalculation() { + BoundingBox box = MeshTools::create_bounding_box(getMooseMesh().getMesh()); + if (_fe_problem.getDisplacedProblem() != nullptr) + _fe_problem.getDisplacedProblem()->updateMesh(); + + if (!isParamValid("lower_left")) + _lower_left = box.min(); + if (!isParamValid("upper_right")) + _upper_right = box.max(); + + if ((_lower_left >= _upper_right) && (isParamValid("lower_left") || isParamValid("lower_left"))) + mooseError("The 'upper_right' (", + _upper_right(0), + ", ", + _upper_right(1), + ", ", + _upper_right(2), + ") " + "must be greater than the 'lower_left' (", + _lower_left(0), + ", ", + _lower_left(1), + ", ", + _lower_left(2), + ")!"); + auto openmc_problem = dynamic_cast(&_fe_problem); _volume_calc.reset(new openmc::VolumeCalculation());