From 3cf9309b0aa17182bb3fe1590b24ab3450a174d0 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Sat, 27 Jun 2026 10:25:59 +0100 Subject: [PATCH 01/12] Initial commit of HippoInterface --- include/base/HippoInterface.h | 21 +++++++++++++++++++++ src/base/HippoInterface.C | 21 +++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 include/base/HippoInterface.h create mode 100644 src/base/HippoInterface.C diff --git a/include/base/HippoInterface.h b/include/base/HippoInterface.h new file mode 100644 index 00000000..e9b78cd5 --- /dev/null +++ b/include/base/HippoInterface.h @@ -0,0 +1,21 @@ +#pragma once + +#include "InputParameters.h" +#include "MooseObject.h" +#include + +class FoamProblem; +class FoamMesh; + +class HippoInterface +{ +public: + HippoInterface(const MooseObject * moose_object); + +protected: + FoamProblem & _foam_problem; + Foam::fvMesh & _foam_fvmesh; + +private: + FoamProblem & extractFoamProblem(const MooseObject *); +}; diff --git a/src/base/HippoInterface.C b/src/base/HippoInterface.C new file mode 100644 index 00000000..99947102 --- /dev/null +++ b/src/base/HippoInterface.C @@ -0,0 +1,21 @@ +#include "FoamProblem.h" +#include "HippoInterface.h" +#include "InputParameters.h" +#include "MooseObject.h" +#include "OutputInterface.h" + +HippoInterface::HippoInterface(const MooseObject * moose_object) + : _foam_problem(extractFoamProblem(moose_object)), _foam_fvmesh(_foam_problem.mesh().fvMesh()) +{ +} + +FoamProblem & +HippoInterface::extractFoamProblem(const MooseObject * moose_object) +{ + const InputParameters & params = moose_object->parameters(); + auto * problem = params.getCheckedPointerParam("_fe_problem_base"); + auto * foam_problem = dynamic_cast(problem); + if (!foam_problem) + mooseError("This object can only be used with FoamProblem"); + return *foam_problem; +} From 92e3ba46d58863d2c3e822b24c4bd37c2751d960 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Wed, 19 Aug 2026 13:19:25 +0100 Subject: [PATCH 02/12] Update postprocessors and bcs with HippoInterface --- include/base/HippoInterface.h | 5 ++++- include/bcs/FoamBCBase.h | 8 ++------ include/postprocessors/FoamPostprocessorBase.h | 6 ++---- src/base/HippoInterface.C | 7 +++++-- src/bcs/FoamBCBase.C | 12 ++++-------- src/bcs/FoamDiffusionFluxBC.C | 12 +++++------- src/bcs/FoamDiffusionFluxPostprocessorBC.C | 13 +++++-------- src/bcs/FoamFixedGradientBC.C | 4 ++-- src/bcs/FoamFixedGradientPostprocessorBC.C | 8 +++----- src/bcs/FoamFixedValueBC.C | 4 ++-- src/bcs/FoamFixedValuePosprocessorBC.C | 4 ++-- src/bcs/FoamMassFlowRateInletBC.C | 6 ++---- src/bcs/FoamVariableBCBase.C | 6 +++--- src/postprocessors/FoamPostprocessorBase.C | 8 ++------ .../FoamSideAdvectiveFluxIntegral.C | 16 +++++++--------- src/postprocessors/FoamSideIntegratedBase.C | 12 ++++++------ .../FoamSideIntegratedFunctionObject.C | 6 +++--- src/postprocessors/FoamSideIntegratedValue.C | 4 ++-- src/postprocessors/FoamSidePostprocessor.C | 2 +- 19 files changed, 62 insertions(+), 81 deletions(-) diff --git a/include/base/HippoInterface.h b/include/base/HippoInterface.h index e9b78cd5..ad97cd6d 100644 --- a/include/base/HippoInterface.h +++ b/include/base/HippoInterface.h @@ -3,6 +3,7 @@ #include "InputParameters.h" #include "MooseObject.h" #include +#include class FoamProblem; class FoamMesh; @@ -14,7 +15,9 @@ class HippoInterface protected: FoamProblem & _foam_problem; - Foam::fvMesh & _foam_fvmesh; + FoamMesh & _mesh; + Foam::fvMesh & _fv_mesh; + Foam::Time & _foam_time; private: FoamProblem & extractFoamProblem(const MooseObject *); diff --git a/include/bcs/FoamBCBase.h b/include/bcs/FoamBCBase.h index ea091d7f..a8b47047 100644 --- a/include/bcs/FoamBCBase.h +++ b/include/bcs/FoamBCBase.h @@ -7,8 +7,7 @@ #include #include #include -#include -#include "MooseError.h" +#include "HippoInterface.h" typedef std::tuple BCInfoTableRow; @@ -20,7 +19,7 @@ enum class FoamBCType fixedGradient }; -class FoamBCBase : public MooseObject, public Coupleable +class FoamBCBase : public MooseObject, public Coupleable, public HippoInterface { public: static InputParameters validParams(); @@ -66,9 +65,6 @@ class FoamBCBase : public MooseObject, public Coupleable // Pointer to Moose variable used to impose BC MooseVariableFieldBase * _moose_var; - // Pointer to the FoamMesh object - FoamMesh * _mesh; - // Boundaries that this object applies to // TODO: Replace with inherited from BoundaryRestricted once FoamMesh is updated std::vector _boundary; diff --git a/include/postprocessors/FoamPostprocessorBase.h b/include/postprocessors/FoamPostprocessorBase.h index fbb6f01f..47c39125 100644 --- a/include/postprocessors/FoamPostprocessorBase.h +++ b/include/postprocessors/FoamPostprocessorBase.h @@ -1,12 +1,13 @@ #pragma once +#include "HippoInterface.h" #include "fvCFD_moose.h" #include "InputParameters.h" #include "Postprocessor.h" #include "ElementUserObject.h" -class FoamPostprocessorBase : public ElementUserObject, public Postprocessor +class FoamPostprocessorBase : public ElementUserObject, public Postprocessor, public HippoInterface { public: static InputParameters validParams(); @@ -26,7 +27,4 @@ class FoamPostprocessorBase : public ElementUserObject, public Postprocessor // Compute postprocessor, to be called within FoamProblem virtual void compute() = 0; - -protected: - Foam::fvMesh * _foam_mesh; }; diff --git a/src/base/HippoInterface.C b/src/base/HippoInterface.C index 99947102..618a2049 100644 --- a/src/base/HippoInterface.C +++ b/src/base/HippoInterface.C @@ -5,7 +5,10 @@ #include "OutputInterface.h" HippoInterface::HippoInterface(const MooseObject * moose_object) - : _foam_problem(extractFoamProblem(moose_object)), _foam_fvmesh(_foam_problem.mesh().fvMesh()) + : _foam_problem(extractFoamProblem(moose_object)), + _mesh(_foam_problem.mesh()), + _fv_mesh(_mesh.fvMesh()), + _foam_time(const_cast(_fv_mesh.time())) { } @@ -16,6 +19,6 @@ HippoInterface::extractFoamProblem(const MooseObject * moose_object) auto * problem = params.getCheckedPointerParam("_fe_problem_base"); auto * foam_problem = dynamic_cast(problem); if (!foam_problem) - mooseError("This object can only be used with FoamProblem"); + mooseError(moose_object->name(), " can only be used with FoamProblem"); return *foam_problem; } diff --git a/src/bcs/FoamBCBase.C b/src/bcs/FoamBCBase.C index 361ced95..253ebe5f 100644 --- a/src/bcs/FoamBCBase.C +++ b/src/bcs/FoamBCBase.C @@ -1,6 +1,7 @@ #include "FoamBCBase.h" #include "FoamProblem.h" +#include "HippoInterface.h" #include #include @@ -51,23 +52,18 @@ FoamBCBase::validParams() FoamBCBase::FoamBCBase(const InputParameters & params, const FoamBCType bc_type) : MooseObject(params), Coupleable(this, false), + HippoInterface(this), _foam_variable(params.get("foam_variable")), _boundary(params.get>("boundary")), _patch_replaced(false) { - auto * problem = dynamic_cast(&_c_fe_problem); - if (!problem) - mooseError("FoamBC system can only be used with FoamProblem"); - - _mesh = &problem->mesh(); - // check that the foam variable exists if (!params.isPrivate("foam_variable") && - !_mesh->foamHasObject(_foam_variable)) + !_mesh.foamHasObject(_foam_variable)) mooseError("There is no OpenFOAM field named '", _foam_variable, "'"); // check that the boundary is in the FoamMesh - auto all_subdomain_names = _mesh->getSubdomainNames(_mesh->getSubdomainList()); + auto all_subdomain_names = _mesh.getSubdomainNames(_mesh.getSubdomainList()); for (auto subdomain : _boundary) { auto it = std::find(all_subdomain_names.begin(), all_subdomain_names.end(), subdomain); diff --git a/src/bcs/FoamDiffusionFluxBC.C b/src/bcs/FoamDiffusionFluxBC.C index 7a6c83f0..3916f6e9 100644 --- a/src/bcs/FoamDiffusionFluxBC.C +++ b/src/bcs/FoamDiffusionFluxBC.C @@ -27,7 +27,7 @@ FoamDiffusionFluxBC::FoamDiffusionFluxBC(const InputParameters & params) : FoamVariableBCBase(params, FoamBCType::fixedGradient), _diffusivity(getParam("diffusivity")) { - if (!_mesh->fvMesh().foundObject(_diffusivity)) + if (!_fv_mesh.foundObject(_diffusivity)) { mooseError("Diffusivity '", _diffusivity, "' not a Foam volScalarField."); } @@ -36,22 +36,20 @@ FoamDiffusionFluxBC::FoamDiffusionFluxBC(const InputParameters & params) void FoamDiffusionFluxBC::imposeBoundaryCondition() { - auto & foam_mesh = _mesh->fvMesh(); - // Get subdomains this FoamBC acts on // TODO: replace with BoundaryRestriction member functions once FoamMesh is updated - auto subdomains = _mesh->getSubdomainIDs(_boundary); + auto subdomains = _mesh.getSubdomainIDs(_boundary); for (auto subdomain : subdomains) { std::vector && grad_array = getMooseVariableArray(subdomain); // Get the gradient associated with the field auto & foam_gradient = - _mesh->getGradientBCField(subdomain, _foam_variable); + _mesh.getGradientBCField(subdomain, _foam_variable); assert(grad_array.size() == static_cast(foam_gradient.size())); - auto & coeff = foam_mesh.boundary()[subdomain].lookupPatchField( - _diffusivity); + auto & coeff = + _fv_mesh.boundary()[subdomain].lookupPatchField(_diffusivity); assert(foam_gradient.size() == coeff.size()); // set gradient diff --git a/src/bcs/FoamDiffusionFluxPostprocessorBC.C b/src/bcs/FoamDiffusionFluxPostprocessorBC.C index 533fe0cc..e945bac2 100644 --- a/src/bcs/FoamDiffusionFluxPostprocessorBC.C +++ b/src/bcs/FoamDiffusionFluxPostprocessorBC.C @@ -21,7 +21,7 @@ FoamDiffusionFluxPostprocessorBC::FoamDiffusionFluxPostprocessorBC(const InputPa : FoamPostprocessorBCBase(params, FoamBCType::fixedGradient), _diffusivity(getParam("diffusivity")) { - if (!_mesh->fvMesh().foundObject(_diffusivity)) + if (!_fv_mesh.foundObject(_diffusivity)) { mooseError("Diffusivity '", _diffusivity, "' not a Foam volScalarField."); } @@ -30,21 +30,18 @@ FoamDiffusionFluxPostprocessorBC::FoamDiffusionFluxPostprocessorBC(const InputPa void FoamDiffusionFluxPostprocessorBC::imposeBoundaryCondition() { - auto & foam_mesh = _mesh->fvMesh(); - // Get subdomains this FoamBC acts on - auto subdomains = _mesh->getSubdomainIDs(_boundary); + auto subdomains = _mesh.getSubdomainIDs(_boundary); for (auto subdomain : subdomains) { - const auto & boundary = foam_mesh.boundary()[subdomain]; + const auto & boundary = _fv_mesh.boundary()[subdomain]; // Get underlying field from OpenFOAM boundary patch. auto & foam_gradient = - _mesh->getGradientBCField(subdomain, _foam_variable); + _mesh.getGradientBCField(subdomain, _foam_variable); // Get the underlying diffusivity field const auto & coeff = - foam_mesh.boundary()[subdomain].lookupPatchField( - _diffusivity); + _fv_mesh.boundary()[subdomain].lookupPatchField(_diffusivity); // Calculate the bulk value of the diffusivity coefficient const auto area = boundary.magSf(); diff --git a/src/bcs/FoamFixedGradientBC.C b/src/bcs/FoamFixedGradientBC.C index 389c8d34..3d1fa33b 100644 --- a/src/bcs/FoamFixedGradientBC.C +++ b/src/bcs/FoamFixedGradientBC.C @@ -27,14 +27,14 @@ FoamFixedGradientBC::imposeBoundaryCondition() { // Get subdomains this FoamBC acts on // TODO: replace with BoundaryRestriction member functions once FoamMesh is updated - auto subdomains = _mesh->getSubdomainIDs(_boundary); + auto subdomains = _mesh.getSubdomainIDs(_boundary); for (auto subdomain : subdomains) { std::vector && grad_array = getMooseVariableArray(subdomain); // Get the gradient associated with the field auto & foam_gradient = - _mesh->getGradientBCField(subdomain, _foam_variable); + _mesh.getGradientBCField(subdomain, _foam_variable); assert(grad_array.size() == static_cast(foam_gradient.size())); std::copy(grad_array.begin(), grad_array.end(), foam_gradient.begin()); diff --git a/src/bcs/FoamFixedGradientPostprocessorBC.C b/src/bcs/FoamFixedGradientPostprocessorBC.C index 2ecf7909..d8c34a24 100644 --- a/src/bcs/FoamFixedGradientPostprocessorBC.C +++ b/src/bcs/FoamFixedGradientPostprocessorBC.C @@ -21,16 +21,14 @@ FoamFixedGradientPostprocessorBC::FoamFixedGradientPostprocessorBC(const InputPa void FoamFixedGradientPostprocessorBC::imposeBoundaryCondition() { - auto & foam_mesh = _mesh->fvMesh(); - // Get subdomains this FoamBC acts on - auto subdomains = _mesh->getSubdomainIDs(_boundary); + auto subdomains = _mesh.getSubdomainIDs(_boundary); for (auto subdomain : subdomains) { - auto & boundary = foam_mesh.boundary()[subdomain]; + auto & boundary = _fv_mesh.boundary()[subdomain]; // Get underlying field from OpenFOAM boundary patch. auto & foam_gradient = - _mesh->getGradientBCField(subdomain, _foam_variable); + _mesh.getGradientBCField(subdomain, _foam_variable); // If diffusivity_coefficient is specified grad array is a flux, so result // must be divided by it diff --git a/src/bcs/FoamFixedValueBC.C b/src/bcs/FoamFixedValueBC.C index fa435daf..39e6a970 100644 --- a/src/bcs/FoamFixedValueBC.C +++ b/src/bcs/FoamFixedValueBC.C @@ -24,13 +24,13 @@ void FoamFixedValueBC::imposeBoundaryCondition() { // Get subdomains this FoamBC acts on - auto subdomains = _mesh->getSubdomainIDs(_boundary); + auto subdomains = _mesh.getSubdomainIDs(_boundary); for (auto subdomain : subdomains) { std::vector && var_array = getMooseVariableArray(subdomain); // Get underlying field from OpenFOAM boundary patch - auto & foam_var = _mesh->getBCField(subdomain, _foam_variable); + auto & foam_var = _mesh.getBCField(subdomain, _foam_variable); assert(var_array.size() == static_cast(foam_var.size())); diff --git a/src/bcs/FoamFixedValuePosprocessorBC.C b/src/bcs/FoamFixedValuePosprocessorBC.C index ba699095..8c9356d3 100644 --- a/src/bcs/FoamFixedValuePosprocessorBC.C +++ b/src/bcs/FoamFixedValuePosprocessorBC.C @@ -20,11 +20,11 @@ void FoamFixedValuePostprocessorBC::imposeBoundaryCondition() { // Get subdomains this FoamBC acts on - auto subdomains = _mesh->getSubdomainIDs(_boundary); + auto subdomains = _mesh.getSubdomainIDs(_boundary); for (auto subdomain : subdomains) { // Get underlying field from OpenFOAM boundary patch - auto & foam_var = _mesh->getBCField(subdomain, _foam_variable); + auto & foam_var = _mesh.getBCField(subdomain, _foam_variable); std::fill(foam_var.begin(), foam_var.end(), _pp_value); } diff --git a/src/bcs/FoamMassFlowRateInletBC.C b/src/bcs/FoamMassFlowRateInletBC.C index 89329510..7a7d53f7 100644 --- a/src/bcs/FoamMassFlowRateInletBC.C +++ b/src/bcs/FoamMassFlowRateInletBC.C @@ -27,14 +27,12 @@ FoamMassFlowRateInletBC::FoamMassFlowRateInletBC(const InputParameters & params) void FoamMassFlowRateInletBC::imposeBoundaryCondition() { - auto & foam_mesh = _mesh->fvMesh(); - // Get subdomains this FoamBC acts on // TODO: replace with BoundaryRestriction member functions once FoamMesh is updated - auto subdomains = _mesh->getSubdomainIDs(_boundary); + auto subdomains = _mesh.getSubdomainIDs(_boundary); for (auto subdomain : subdomains) { - const auto & boundary_patch = foam_mesh.boundary()[subdomain]; + const auto & boundary_patch = _fv_mesh.boundary()[subdomain]; auto & U_var = const_cast &>( boundary_patch.lookupPatchField("U")); diff --git a/src/bcs/FoamVariableBCBase.C b/src/bcs/FoamVariableBCBase.C index ec75b4bf..719e6206 100644 --- a/src/bcs/FoamVariableBCBase.C +++ b/src/bcs/FoamVariableBCBase.C @@ -74,14 +74,14 @@ FoamVariableBCBase::variableValueAtElement(const libMesh::Elem & elem) const std::vector FoamVariableBCBase::getMooseVariableArray(int subdomainId) const { - size_t patch_count = _mesh->getPatchCount(subdomainId); - size_t patch_offset = _mesh->getPatchOffset(subdomainId); + size_t patch_count = _mesh.getPatchCount(subdomainId); + size_t patch_offset = _mesh.getPatchOffset(subdomainId); std::vector var_array(patch_count); for (size_t j = 0; j < patch_count; ++j) { auto elem = patch_offset + j; - const auto elem_ptr = _mesh->getElemPtr(elem + _mesh->rank_element_offset); + const auto elem_ptr = _mesh.getElemPtr(elem + _mesh.rank_element_offset); assert(elem_ptr); var_array[j] = variableValueAtElement(*elem_ptr); } diff --git a/src/postprocessors/FoamPostprocessorBase.C b/src/postprocessors/FoamPostprocessorBase.C index 90c2b05c..7f715096 100644 --- a/src/postprocessors/FoamPostprocessorBase.C +++ b/src/postprocessors/FoamPostprocessorBase.C @@ -1,5 +1,6 @@ #include "FoamMesh.h" #include "FoamPostprocessorBase.h" +#include "HippoInterface.h" #include "InputParameters.h" #include "Postprocessor.h" #include "ElementUserObject.h" @@ -14,13 +15,8 @@ FoamPostprocessorBase::validParams() } FoamPostprocessorBase::FoamPostprocessorBase(const InputParameters & params) - : ElementUserObject(params), Postprocessor(this), _foam_mesh(nullptr) + : ElementUserObject(params), Postprocessor(this), HippoInterface(this) { - FoamProblem * problem = dynamic_cast(&getSubProblem()); - if (!problem) - mooseError("Foam-based Postprocessors can only be used with FoamProblem"); - - _foam_mesh = &problem->mesh().fvMesh(); } void diff --git a/src/postprocessors/FoamSideAdvectiveFluxIntegral.C b/src/postprocessors/FoamSideAdvectiveFluxIntegral.C index 0d3e1fd4..bdf615a1 100644 --- a/src/postprocessors/FoamSideAdvectiveFluxIntegral.C +++ b/src/postprocessors/FoamSideAdvectiveFluxIntegral.C @@ -22,10 +22,10 @@ FoamSideAdvectiveFluxIntegral::FoamSideAdvectiveFluxIntegral(const InputParamete _advection_velocity(params.get("advective_velocity")) { - if (!_foam_mesh->foundObject(_foam_scalar)) + if (!_fv_mesh.foundObject(_foam_scalar)) mooseError("foam_scalar '", _foam_scalar, "' not found."); - if (!_foam_mesh->foundObject(_advection_velocity)) + if (!_fv_mesh.foundObject(_advection_velocity)) mooseError("advective_velocity '", _advection_velocity, "' not found."); } @@ -36,15 +36,13 @@ FoamSideAdvectiveFluxIntegral::compute() for (auto & boundary : _boundary) { auto & var_array = - _foam_mesh->boundary()[boundary].lookupPatchField( - _foam_scalar); + _fv_mesh.boundary()[boundary].lookupPatchField(_foam_scalar); - auto & vel_array = - _foam_mesh->boundary()[boundary].lookupPatchField( - _advection_velocity); + auto & vel_array = _fv_mesh.boundary()[boundary].lookupPatchField( + _advection_velocity); - auto & areas = _foam_mesh->boundary()[boundary].magSf(); - auto && normals = _foam_mesh->boundary()[boundary].nf(); + auto & areas = _fv_mesh.boundary()[boundary].magSf(); + auto && normals = _fv_mesh.boundary()[boundary].nf(); // integrate locally for (int i = 0; i < var_array.size(); ++i) diff --git a/src/postprocessors/FoamSideIntegratedBase.C b/src/postprocessors/FoamSideIntegratedBase.C index 6a76cbb1..326e9a06 100644 --- a/src/postprocessors/FoamSideIntegratedBase.C +++ b/src/postprocessors/FoamSideIntegratedBase.C @@ -32,21 +32,21 @@ FoamSideIntegratedBase::integrateValue(const std::string & variable) // loop over boundary ids for (auto & boundary : _boundary) { - auto & areas = _foam_mesh->boundary()[boundary].magSf(); + auto & areas = _fv_mesh.boundary()[boundary].magSf(); Foam::Field var_array; - if (_foam_mesh->foundObject(variable)) + if (_fv_mesh.foundObject(variable)) { // get vector data associated with the boundary auto & vec_data = - _foam_mesh->boundary()[boundary].lookupPatchField(variable); + _fv_mesh.boundary()[boundary].lookupPatchField(variable); // get the component specified in parameters and get the // component of the vector in that direction auto components = parameters().get("component"); if (components == "normal") { - auto && normals = _foam_mesh->boundary()[boundary].nf(); + auto && normals = _fv_mesh.boundary()[boundary].nf(); var_array = normals & vec_data; } else if (components == "magnitude") @@ -57,7 +57,7 @@ FoamSideIntegratedBase::integrateValue(const std::string & variable) else { var_array = - _foam_mesh->boundary()[boundary].lookupPatchField(variable); + _fv_mesh.boundary()[boundary].lookupPatchField(variable); } // Integrate @@ -80,7 +80,7 @@ FoamSideIntegratedBase::getArea() // loop over boundary ids for (auto & boundary : _boundary) { - auto & areas = _foam_mesh->boundary()[boundary].magSf(); + auto & areas = _fv_mesh.boundary()[boundary].magSf(); for (int i = 0; i < areas.size(); ++i) { area += areas[i]; diff --git a/src/postprocessors/FoamSideIntegratedFunctionObject.C b/src/postprocessors/FoamSideIntegratedFunctionObject.C index f14b8b3c..e9eacfce 100644 --- a/src/postprocessors/FoamSideIntegratedFunctionObject.C +++ b/src/postprocessors/FoamSideIntegratedFunctionObject.C @@ -26,7 +26,7 @@ FoamSideIntegratedFunctionObject::FoamSideIntegratedFunctionObject(const InputPa std::unique_ptr FoamSideIntegratedFunctionObject::createFunctionObject(const std::string & fo_name) { - auto fo_dict = _foam_mesh->time().controlDict().lookupOrDefault(fo_name, Foam::dictionary()); + auto fo_dict = _fv_mesh.time().controlDict().lookupOrDefault(fo_name, Foam::dictionary()); Foam::wordList patch_names(_boundary.begin(), _boundary.end()); @@ -36,12 +36,12 @@ FoamSideIntegratedFunctionObject::createFunctionObject(const std::string & fo_na if (fo_name == "wallHeatFlux") { return std::make_unique( - "wallHeatFlux", _foam_mesh->time(), fo_dict); + "wallHeatFlux", _fv_mesh.time(), fo_dict); } else // wallShearStress { return std::make_unique( - "wallShearStress", _foam_mesh->time(), fo_dict); + "wallShearStress", _fv_mesh.time(), fo_dict); } } diff --git a/src/postprocessors/FoamSideIntegratedValue.C b/src/postprocessors/FoamSideIntegratedValue.C index 9609b599..4444d9e8 100644 --- a/src/postprocessors/FoamSideIntegratedValue.C +++ b/src/postprocessors/FoamSideIntegratedValue.C @@ -18,8 +18,8 @@ FoamSideIntegratedValue::FoamSideIntegratedValue(const InputParameters & params) : FoamSideIntegratedBase(params), _foam_variable(getParam("foam_variable")) { // determine if this is a vector scalar, ahead of computation - if (!_foam_mesh->foundObject(_foam_variable) && - !_foam_mesh->foundObject(_foam_variable)) + if (!_fv_mesh.foundObject(_foam_variable) && + !_fv_mesh.foundObject(_foam_variable)) mooseError("No Foam scalar or vector called '", _foam_variable, "'."); } diff --git a/src/postprocessors/FoamSidePostprocessor.C b/src/postprocessors/FoamSidePostprocessor.C index 98bd6b98..a7392814 100644 --- a/src/postprocessors/FoamSidePostprocessor.C +++ b/src/postprocessors/FoamSidePostprocessor.C @@ -16,7 +16,7 @@ FoamSidePostprocessor::FoamSidePostprocessor(const InputParameters & params) { for (auto & boundary : _boundary) { - if (_foam_mesh->boundary().findIndex(boundary) == -1) + if (_fv_mesh.boundary().findIndex(boundary) == -1) mooseError("Boundary '", boundary, "' not found in FoamMesh."); } } From e10bc7e4467bce0bf4866e7207d024e9a3044e6f Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Mon, 29 Jun 2026 12:34:28 +0100 Subject: [PATCH 03/12] Update variables with HippoInterface --- include/variables/FoamVariableField.h | 6 ++---- .../FoamSideIntegratedFunctionObject.C | 6 +++--- src/variables/FoamFunctionObject.C | 8 +++---- src/variables/FoamVariableField.C | 21 ++++++++----------- 4 files changed, 17 insertions(+), 24 deletions(-) diff --git a/include/variables/FoamVariableField.h b/include/variables/FoamVariableField.h index a7bf91cc..e9a2b0e4 100644 --- a/include/variables/FoamVariableField.h +++ b/include/variables/FoamVariableField.h @@ -1,9 +1,10 @@ #pragma once +#include "HippoInterface.h" #include "MooseObject.h" #include "FoamMesh.h" -class FoamVariableField : public MooseObject +class FoamVariableField : public MooseObject, public HippoInterface { public: static InputParameters validParams(); @@ -19,7 +20,4 @@ class FoamVariableField : public MooseObject protected: // variable name or functionObject to be shadowed std::string _foam_variable; - - // Pointer to the FoamMesh object - FoamMesh * _mesh; }; diff --git a/src/postprocessors/FoamSideIntegratedFunctionObject.C b/src/postprocessors/FoamSideIntegratedFunctionObject.C index e9eacfce..32b66efb 100644 --- a/src/postprocessors/FoamSideIntegratedFunctionObject.C +++ b/src/postprocessors/FoamSideIntegratedFunctionObject.C @@ -26,7 +26,7 @@ FoamSideIntegratedFunctionObject::FoamSideIntegratedFunctionObject(const InputPa std::unique_ptr FoamSideIntegratedFunctionObject::createFunctionObject(const std::string & fo_name) { - auto fo_dict = _fv_mesh.time().controlDict().lookupOrDefault(fo_name, Foam::dictionary()); + auto fo_dict = _foam_time.controlDict().lookupOrDefault(fo_name, Foam::dictionary()); Foam::wordList patch_names(_boundary.begin(), _boundary.end()); @@ -36,12 +36,12 @@ FoamSideIntegratedFunctionObject::createFunctionObject(const std::string & fo_na if (fo_name == "wallHeatFlux") { return std::make_unique( - "wallHeatFlux", _fv_mesh.time(), fo_dict); + "wallHeatFlux", _foam_time, fo_dict); } else // wallShearStress { return std::make_unique( - "wallShearStress", _fv_mesh.time(), fo_dict); + "wallShearStress", _foam_time, fo_dict); } } diff --git a/src/variables/FoamFunctionObject.C b/src/variables/FoamFunctionObject.C index a1fd9809..c4eb18ed 100644 --- a/src/variables/FoamFunctionObject.C +++ b/src/variables/FoamFunctionObject.C @@ -11,15 +11,13 @@ registerMooseObject("hippoApp", FoamFunctionObject); FoamFunctionObject::FoamFunctionObject(const InputParameters & params) : FoamVariableField(params) { - auto & mesh = _mesh->fvMesh(); - // construct input Foam dictionary for the functionObject - auto fo_dict = mesh.time().controlDict().lookupOrDefault(_foam_variable, Foam::dictionary()); + auto fo_dict = _foam_time.controlDict().lookupOrDefault(_foam_variable, Foam::dictionary()); // create patch names where functionObject applies // TODO: when volumetric mirror is implemented some of this may need to be // put in the _getFunctionObject function. - auto patch_ids{_mesh->getSubdomainList()}; + auto patch_ids{_mesh.getSubdomainList()}; Foam::wordList patch_names; for (auto id : patch_ids) patch_names.append(mesh.boundary()[id].name()); @@ -39,7 +37,7 @@ FoamFunctionObject::_getFunctionObject(Foam::dictionary fo_dict) if (_foam_variable == "wallHeatFlux") { Foam::functionObjects::wallHeatFlux * whf_func = - new Foam::functionObjects::wallHeatFlux("wallHeatFlux", _mesh->fvMesh().time(), fo_dict); + new Foam::functionObjects::wallHeatFlux("wallHeatFlux", _foam_time, fo_dict); return static_cast(whf_func); } else diff --git a/src/variables/FoamVariableField.C b/src/variables/FoamVariableField.C index 655eaa70..3ed44d5c 100644 --- a/src/variables/FoamVariableField.C +++ b/src/variables/FoamVariableField.C @@ -1,5 +1,6 @@ #include "FoamVariableField.h" #include "FoamProblem.h" +#include "HippoInterface.h" #include "InputParameters.h" #include "MooseObject.h" #include "MooseTypes.h" @@ -27,13 +28,10 @@ FoamVariableField::validParams() } FoamVariableField::FoamVariableField(const InputParameters & params) - : MooseObject(params), _foam_variable(params.get("foam_variable")) + : MooseObject(params), + HippoInterface(this), + _foam_variable(params.get("foam_variable")) { - auto * problem = dynamic_cast(&getMooseApp().feProblem()); - if (!problem) - mooseError("This Variable can only be used with FoamProblem"); - - _mesh = &problem->mesh(); } void @@ -43,18 +41,17 @@ FoamVariableField::transferVariable() auto & moose_var = getMooseApp().feProblem().getVariable(tid, _name); // Loop through subdomains extracting foam_variable and setting on libMesh elements - auto & foam_mesh = _mesh->fvMesh(); - for (auto subdomain : _mesh->getSubdomainList()) + for (auto subdomain : _mesh.getSubdomainList()) { - size_t patch_count = _mesh->getPatchCount(subdomain); - size_t patch_offset = _mesh->getPatchOffset(subdomain); + size_t patch_count = _mesh.getPatchCount(subdomain); + size_t patch_offset = _mesh.getPatchOffset(subdomain); - auto & var = foam_mesh.boundary()[subdomain].lookupPatchField( + auto & var = _fv_mesh.boundary()[subdomain].lookupPatchField( _foam_variable); for (size_t j = 0; j < patch_count; ++j) { auto elem = patch_offset + j; - auto elem_ptr = _mesh->getElemPtr(elem + _mesh->rank_element_offset); + auto elem_ptr = _mesh.getElemPtr(elem + _mesh.rank_element_offset); assert(elem_ptr); auto dof_t = elem_ptr->dof_number(moose_var.sys().number(), moose_var.number(), 0); moose_var.sys().solution().set(dof_t, var[j]); From 82922338a0998026e23a04a268f03b770e329585 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Mon, 29 Jun 2026 15:46:58 +0100 Subject: [PATCH 04/12] Add test for error if FoamProblem is not used with HippoInterface --- src/base/HippoInterface.C | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base/HippoInterface.C b/src/base/HippoInterface.C index 618a2049..ed39aeb2 100644 --- a/src/base/HippoInterface.C +++ b/src/base/HippoInterface.C @@ -19,6 +19,6 @@ HippoInterface::extractFoamProblem(const MooseObject * moose_object) auto * problem = params.getCheckedPointerParam("_fe_problem_base"); auto * foam_problem = dynamic_cast(problem); if (!foam_problem) - mooseError(moose_object->name(), " can only be used with FoamProblem"); + mooseError(moose_object->type(), " can only be used with FoamProblem"); return *foam_problem; } From 7e7aeaf1e482c0e65fd824af39c087b53cd9c885 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Tue, 30 Jun 2026 11:14:30 +0100 Subject: [PATCH 05/12] Remove FoamProblem from actions so errors get raised at the HippoInterface level --- include/actions/AddFoamBCAction.h | 2 +- src/actions/AddFoamBCAction.C | 10 +-- src/actions/AddFoamVariableAction.C | 6 +- src/bcs/FoamFixedGradientPostprocessorBC.C | 1 - test/tests/actions/foam_variable/tests | 2 +- test/tests/base/hippo_interface/foam/0/T | 56 ++++++++++++ .../foam/constant/physicalProperties | 51 +++++++++++ .../hippo_interface/foam/system/blockMeshDict | 85 +++++++++++++++++++ .../hippo_interface/foam/system/controlDict | 44 ++++++++++ .../foam/system/decomposeParDict | 26 ++++++ .../hippo_interface/foam/system/fvSchemes | 46 ++++++++++ .../hippo_interface/foam/system/fvSolution | 61 +++++++++++++ test/tests/base/hippo_interface/main.i | 43 ++++++++++ test/tests/base/hippo_interface/tests | 20 +++++ 14 files changed, 438 insertions(+), 15 deletions(-) create mode 100644 test/tests/base/hippo_interface/foam/0/T create mode 100644 test/tests/base/hippo_interface/foam/constant/physicalProperties create mode 100644 test/tests/base/hippo_interface/foam/system/blockMeshDict create mode 100644 test/tests/base/hippo_interface/foam/system/controlDict create mode 100644 test/tests/base/hippo_interface/foam/system/decomposeParDict create mode 100644 test/tests/base/hippo_interface/foam/system/fvSchemes create mode 100644 test/tests/base/hippo_interface/foam/system/fvSolution create mode 100644 test/tests/base/hippo_interface/main.i create mode 100644 test/tests/base/hippo_interface/tests diff --git a/include/actions/AddFoamBCAction.h b/include/actions/AddFoamBCAction.h index 84853b3d..bf3c2046 100644 --- a/include/actions/AddFoamBCAction.h +++ b/include/actions/AddFoamBCAction.h @@ -19,5 +19,5 @@ class AddFoamBCAction : public MooseObjectAction void createAuxVariable(); // Create Receiver for Postprocessor-based BCs - void createReceiver(FoamProblem & problem); + void createReceiver(FEProblemBase & problem); }; diff --git a/src/actions/AddFoamBCAction.C b/src/actions/AddFoamBCAction.C index f56ee815..f1a79b2b 100644 --- a/src/actions/AddFoamBCAction.C +++ b/src/actions/AddFoamBCAction.C @@ -29,14 +29,10 @@ AddFoamBCAction::AddFoamBCAction(const InputParameters & params) : MooseObjectAc void AddFoamBCAction::act() { - auto foam_problem = dynamic_cast(_problem.get()); // Adding BCs using [FoamBC] syntax if (_current_task == "add_foam_bc") { - if (!foam_problem) - mooseError("FoamBCs system can only be used with FoamProblem."); - // Do not create aux variable if variable provided. if (findParamKey(_moose_object_pars, "v") && !_moose_object_pars.isParamSetByUser("v")) createAuxVariable(); @@ -44,9 +40,9 @@ AddFoamBCAction::act() // Create receiver if pp_name not provided and pp_name is an allowed parameter if (findParamKey(_moose_object_pars, "pp_name") && !_moose_object_pars.isParamSetByUser("pp_name")) - createReceiver(*foam_problem); + createReceiver(*_problem); - foam_problem->addObject(_type, _name, _moose_object_pars, false); + _problem->addObject(_type, _name, _moose_object_pars, false); } } @@ -74,7 +70,7 @@ AddFoamBCAction::createAuxVariable() } void -AddFoamBCAction::createReceiver(FoamProblem & problem) +AddFoamBCAction::createReceiver(FEProblemBase & problem) { auto params = _factory.getValidParams("Receiver"); diff --git a/src/actions/AddFoamVariableAction.C b/src/actions/AddFoamVariableAction.C index 11426112..5d18c40e 100644 --- a/src/actions/AddFoamVariableAction.C +++ b/src/actions/AddFoamVariableAction.C @@ -25,17 +25,13 @@ AddFoamVariableAction::AddFoamVariableAction(const InputParameters & parameters) void AddFoamVariableAction::act() { - auto * foam_problem = dynamic_cast(_problem.get()); // Add variable through [FoamVariables] block if (_current_task == "add_foam_variable") { - if (!foam_problem) - mooseError("FoamVariables system can only be used with FoamProblem."); - createAuxVariable(); - foam_problem->addObject(_type, _name, _moose_object_pars, false); + _problem->addObject(_type, _name, _moose_object_pars, false); } } diff --git a/src/bcs/FoamFixedGradientPostprocessorBC.C b/src/bcs/FoamFixedGradientPostprocessorBC.C index d8c34a24..7592c023 100644 --- a/src/bcs/FoamFixedGradientPostprocessorBC.C +++ b/src/bcs/FoamFixedGradientPostprocessorBC.C @@ -25,7 +25,6 @@ FoamFixedGradientPostprocessorBC::imposeBoundaryCondition() auto subdomains = _mesh.getSubdomainIDs(_boundary); for (auto subdomain : subdomains) { - auto & boundary = _fv_mesh.boundary()[subdomain]; // Get underlying field from OpenFOAM boundary patch. auto & foam_gradient = _mesh.getGradientBCField(subdomain, _foam_variable); diff --git a/test/tests/actions/foam_variable/tests b/test/tests/actions/foam_variable/tests index 1fa573db..21732e78 100644 --- a/test/tests/actions/foam_variable/tests +++ b/test/tests/actions/foam_variable/tests @@ -13,7 +13,7 @@ type = RunException input = main.i prereq = transfer_test/setup - expect_err = "can only be used with FoamProblem" + expect_err = "FoamVariableField can only be used with FoamProblem" cli_args = "Problem/type=FEProblem" [] [] diff --git a/test/tests/base/hippo_interface/foam/0/T b/test/tests/base/hippo_interface/foam/0/T new file mode 100644 index 00000000..65a14be8 --- /dev/null +++ b/test/tests/base/hippo_interface/foam/0/T @@ -0,0 +1,56 @@ +/*--------------------------------*- C++ -*----------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | Website: https://openfoam.org + \\ / A nd | Version: 10 + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + format ascii; + class volScalarField; + location "0"; + object T; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 0 0 1 0 0 0]; + +internalField uniform 0.1; + +boundaryField +{ + left + { + type fixedValue; + value uniform 0.; + } + right + { + type fixedValue; + value uniform 0.; + } + top + { + type fixedValue; + value uniform 0.; + } + bottom + { + type fixedValue; + value uniform 0.; + } + back + { + type fixedValue; + value uniform 0.; + } + front + { + type fixedValue; + value uniform 0.; + } +} + + +// ************************************************************************* // diff --git a/test/tests/base/hippo_interface/foam/constant/physicalProperties b/test/tests/base/hippo_interface/foam/constant/physicalProperties new file mode 100644 index 00000000..96a14c15 --- /dev/null +++ b/test/tests/base/hippo_interface/foam/constant/physicalProperties @@ -0,0 +1,51 @@ +/*--------------------------------*- C++ -*----------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | Website: https://openfoam.org + \\ / A nd | Version: 10 + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + format ascii; + class dictionary; + location "constant"; + object physicalProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +thermoType +{ + type heSolidThermo; + mixture pureMixture; + transport constIsoSolid; + thermo eConst; + equationOfState rhoConst; + specie specie; + energy sensibleInternalEnergy; +} + +mixture +{ + specie + { + molWeight 1; + } + thermodynamics + { + Cv 1; // Specific heat capacity [J/(kg·K)] + Hf 1; // Heat of formation [J/kg] + Tref 0; + } + transport + { + kappa 1; // Thermal conductivity [W/(m·K)] + } + equationOfState + { + rho 1; // Density [kg/m^3] + } +} + + +// ************************************************************************* // diff --git a/test/tests/base/hippo_interface/foam/system/blockMeshDict b/test/tests/base/hippo_interface/foam/system/blockMeshDict new file mode 100644 index 00000000..face9ea6 --- /dev/null +++ b/test/tests/base/hippo_interface/foam/system/blockMeshDict @@ -0,0 +1,85 @@ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object blockMeshDict; +} + +vertices +( + ( 0.0 0.0 0.0 ) + ( 10.0 0.0 0.0 ) + ( 10.0 1.0 0.0 ) + ( 0.0 1.0 0.0 ) + + ( 0.0 0.0 1.0) + ( 10.0 0.0 1.0) + ( 10.0 1.0 1.0) + ( 0.0 1.0 1.0) +); + +blocks +( + hex (0 1 2 3 4 5 6 7) (50 1 1) simpleGrading (25 1 1) +); + +boundary +( + + // interface + left + { + type wall; + faces + ( + (4 7 3 0) + ); + } + + right + { + type wall; + faces + ( + (6 5 1 2) + ); + } + + top + { + type wall; + faces + ( + (2 3 7 6) + ); + } + + front + { + type wall; + faces + ( + (3 2 1 0) + ); + } + + bottom + { + type wall; + faces + ( + (0 1 5 4) + ); + } + + back + { + type wall; + faces + ( + (4 5 6 7) + ); + } + +); diff --git a/test/tests/base/hippo_interface/foam/system/controlDict b/test/tests/base/hippo_interface/foam/system/controlDict new file mode 100644 index 00000000..cb155c26 --- /dev/null +++ b/test/tests/base/hippo_interface/foam/system/controlDict @@ -0,0 +1,44 @@ +/*--------------------------------*- C++ -*----------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | Website: https://openfoam.org + \\ / A nd | Version: 10 + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + format ascii; + class dictionary; + object controlDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +solver bcTestSolver; + +startFrom startTime; + +startTime 0; + +stopAt endTime; + +endTime 0.32; + +deltaT 0.01; + +writeControl timeStep; + +writeInterval 1; + +writeFormat ascii; + +writePrecision 20; + +writeCompression off; + +timeFormat general; + +timePrecision 20; + +runTimeModifiable true; + +// ************************************************************************* // diff --git a/test/tests/base/hippo_interface/foam/system/decomposeParDict b/test/tests/base/hippo_interface/foam/system/decomposeParDict new file mode 100644 index 00000000..8f81e4ec --- /dev/null +++ b/test/tests/base/hippo_interface/foam/system/decomposeParDict @@ -0,0 +1,26 @@ +/*--------------------------------*- C++ -*----------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | Website: https://openfoam.org + \\ / A nd | Version: 10 + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + format ascii; + class dictionary; + location "system"; + object decomposeParDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +numberOfSubdomains 4; + +method simple; + +simpleCoeffs +{ + n (4 1 1); +} + +// ************************************************************************* // diff --git a/test/tests/base/hippo_interface/foam/system/fvSchemes b/test/tests/base/hippo_interface/foam/system/fvSchemes new file mode 100644 index 00000000..0e534821 --- /dev/null +++ b/test/tests/base/hippo_interface/foam/system/fvSchemes @@ -0,0 +1,46 @@ +/*--------------------------------*- C++ -*----------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | Website: https://openfoam.org + \\ / A nd | Version: 12 + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + format ascii; + class dictionary; + object fvSchemes; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +ddtSchemes +{ + default Euler; +} + +gradSchemes +{ + default Gauss linear; +} + +divSchemes +{ + default Gauss linear; +} + +laplacianSchemes +{ + default Gauss linear corrected; +} + +interpolationSchemes +{ + default linear; +} + +snGradSchemes +{ + default corrected; +} + +// ************************************************************************* // diff --git a/test/tests/base/hippo_interface/foam/system/fvSolution b/test/tests/base/hippo_interface/foam/system/fvSolution new file mode 100644 index 00000000..59db6a2a --- /dev/null +++ b/test/tests/base/hippo_interface/foam/system/fvSolution @@ -0,0 +1,61 @@ +/*--------------------------------*- C++ -*----------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | Website: https://openfoam.org + \\ / A nd | Version: 12 + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + format ascii; + class dictionary; + object fvSolution; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +solvers +{ + rho + { + solver diagonal; + } + + rhoFinal + { + $rho; + } + + + e + { + solver PBiCGStab; + preconditioner DIC; + tolerance 1e-8; + relTol 1e-8; + } + + eFinal + { + $e; + tolerance 1e-8; + relTol 1e-8; + } +} + +PIMPLE +{ + momentumPredictor yes; + pRefCell 0; + pRefValue 0; +} + +relaxationFactors +{ + equations + { + h 1; + U 1; + } +} + +// ************************************************************************* // diff --git a/test/tests/base/hippo_interface/main.i b/test/tests/base/hippo_interface/main.i new file mode 100644 index 00000000..639300f1 --- /dev/null +++ b/test/tests/base/hippo_interface/main.i @@ -0,0 +1,43 @@ +[Mesh] + type = FoamMesh + case = 'foam' + foam_patch = 'left right bottom top back front' +[] + +[Kernels] + [dummy] + type = NullKernel + variable = dummy + [] +[] + +[Postprocessors] + [p1] + type = FoamSideAverageValue + foam_variable=T + boundary=left + [] +[] + +[Variables] + [dummy] + family = MONOMIAL + order = CONSTANT + initial_condition = 999 + [] +[] + +[Problem] + type = FoamProblem + # Take the boundary temperature from OpenFOAM and set it on the MOOSE mesh. +[] + +[Executioner] + type = Transient + end_time = 0.01 + dt = 0.01 +[] + +[Outputs] + exodus = true +[] diff --git a/test/tests/base/hippo_interface/tests b/test/tests/base/hippo_interface/tests new file mode 100644 index 00000000..306b7ddc --- /dev/null +++ b/test/tests/base/hippo_interface/tests @@ -0,0 +1,20 @@ +[Tests] + [foam_bc_action_test] + [setup] + type = RunCommand + command = 'bash -c "foamCleanCase -case foam && blockMesh -case foam && decomposePar -force -case foam"' + [] + [run] + type = RunApp + input = main.i + prereq = foam_bc_action_test/setup + [] + [run_err] + type = RunException + input = main.i + cli_args="Problem/type=FEProblem" + prereq = foam_bc_action_test/setup + expect_err="FoamSideAverageValue can only be used with FoamProblem" + [] + [] +[] From 5cbe6839c65d3a33f3e73c9a0a660b97d49f5608 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Mon, 10 Aug 2026 10:45:25 +0100 Subject: [PATCH 06/12] Make HippoInterface protected --- include/bcs/FoamBCBase.h | 2 +- include/postprocessors/FoamPostprocessorBase.h | 4 +++- include/variables/FoamVariableField.h | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/bcs/FoamBCBase.h b/include/bcs/FoamBCBase.h index a8b47047..be7f3efc 100644 --- a/include/bcs/FoamBCBase.h +++ b/include/bcs/FoamBCBase.h @@ -19,7 +19,7 @@ enum class FoamBCType fixedGradient }; -class FoamBCBase : public MooseObject, public Coupleable, public HippoInterface +class FoamBCBase : public MooseObject, public Coupleable, protected HippoInterface { public: static InputParameters validParams(); diff --git a/include/postprocessors/FoamPostprocessorBase.h b/include/postprocessors/FoamPostprocessorBase.h index 47c39125..73e6794d 100644 --- a/include/postprocessors/FoamPostprocessorBase.h +++ b/include/postprocessors/FoamPostprocessorBase.h @@ -7,7 +7,9 @@ #include "Postprocessor.h" #include "ElementUserObject.h" -class FoamPostprocessorBase : public ElementUserObject, public Postprocessor, public HippoInterface +class FoamPostprocessorBase : public ElementUserObject, + public Postprocessor, + protected HippoInterface { public: static InputParameters validParams(); diff --git a/include/variables/FoamVariableField.h b/include/variables/FoamVariableField.h index e9a2b0e4..c84be8aa 100644 --- a/include/variables/FoamVariableField.h +++ b/include/variables/FoamVariableField.h @@ -4,7 +4,7 @@ #include "MooseObject.h" #include "FoamMesh.h" -class FoamVariableField : public MooseObject, public HippoInterface +class FoamVariableField : public MooseObject, protected HippoInterface { public: static InputParameters validParams(); From fb9bae1e450b70d98e220241868d7b3841833916 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Wed, 19 Aug 2026 17:43:33 +0100 Subject: [PATCH 07/12] Update FoamBCBase for new interface --- src/bcs/FoamBCBase.C | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/bcs/FoamBCBase.C b/src/bcs/FoamBCBase.C index 253ebe5f..0b3a64ae 100644 --- a/src/bcs/FoamBCBase.C +++ b/src/bcs/FoamBCBase.C @@ -76,9 +76,9 @@ FoamBCBase::FoamBCBase(const InputParameters & params, const FoamBCType bc_type) for (auto subdomain : _boundary) { - if (_mesh->foamHasObject(_foam_variable)) + if (_mesh.foamHasObject(_foam_variable)) constructFoamScalarPatch(subdomain, bc_type); - else if (_mesh->foamHasObject(_foam_variable)) + else if (_mesh.foamHasObject(_foam_variable)) constructFoamVectorPatch(subdomain, bc_type); else mooseError("Variable must have type scalar or vector."); @@ -88,9 +88,8 @@ FoamBCBase::FoamBCBase(const InputParameters & params, const FoamBCType bc_type) void FoamBCBase::constructFoamScalarPatch(const std::string & patch_name, const FoamBCType bc_type) { - auto & foam_mesh = _mesh->fvMesh(); - auto & var = foam_mesh.lookupObjectRef(_foam_variable); - Foam::label id = foam_mesh.boundary().findIndex(patch_name); + auto & var = _fv_mesh.lookupObjectRef(_foam_variable); + Foam::label id = _fv_mesh.boundary().findIndex(patch_name); if (bc_type_to_string(bc_type) == var.boundaryField()[id].type()) return; @@ -112,7 +111,7 @@ FoamBCBase::constructFoamScalarPatch(const std::string & patch_name, const FoamB var.boundaryFieldRef().set( id, Foam::fvPatchField::New( - foam_mesh.boundary()[id], var.boundaryField()[id].internalField(), bcDict)); + _fv_mesh.boundary()[id], var.boundaryField()[id].internalField(), bcDict)); // If temperature is replaced, internal energy or enthalpy typically needs replacing. updateEnergyPatch(var, id, bc_type); @@ -121,9 +120,8 @@ FoamBCBase::constructFoamScalarPatch(const std::string & patch_name, const FoamB void FoamBCBase::constructFoamVectorPatch(const std::string & patch_name, const FoamBCType bc_type) { - auto & foam_mesh = _mesh->fvMesh(); - auto & var = foam_mesh.lookupObjectRef(_foam_variable); - Foam::label id = foam_mesh.boundary().findIndex(patch_name); + auto & var = _fv_mesh.lookupObjectRef(_foam_variable); + Foam::label id = _fv_mesh.boundary().findIndex(patch_name); if (bc_type_to_string(bc_type) == var.boundaryField()[id].type()) return; @@ -143,7 +141,7 @@ FoamBCBase::constructFoamVectorPatch(const std::string & patch_name, const FoamB var.boundaryFieldRef().set( id, - Foam::fvPatchField::New(foam_mesh.boundary()[id], var.internalField(), bcDict)); + Foam::fvPatchField::New(_fv_mesh.boundary()[id], var.internalField(), bcDict)); } void @@ -152,7 +150,7 @@ FoamBCBase::updateEnergyPatch(const Foam::volScalarField & var, const FoamBCType bc_type) { - auto thermos = var.mesh().lookupClass(); + auto thermos = _fv_mesh.lookupClass(); for (const auto & item : thermos) { From 15143003060f09d0171d8fef5958998027705b2e Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Thu, 20 Aug 2026 13:31:23 +0100 Subject: [PATCH 08/12] Fix bug from rebase --- src/variables/FoamFunctionObject.C | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/variables/FoamFunctionObject.C b/src/variables/FoamFunctionObject.C index c4eb18ed..8168e463 100644 --- a/src/variables/FoamFunctionObject.C +++ b/src/variables/FoamFunctionObject.C @@ -20,7 +20,7 @@ FoamFunctionObject::FoamFunctionObject(const InputParameters & params) : FoamVar auto patch_ids{_mesh.getSubdomainList()}; Foam::wordList patch_names; for (auto id : patch_ids) - patch_names.append(mesh.boundary()[id].name()); + patch_names.append(_fv_mesh.boundary()[id].name()); fo_dict.set("patches", patch_names); fo_dict.set("writeToFile", false); From c34a9f8e24e70ca6e0b56d37353fd7f1a4391a96 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Thu, 20 Aug 2026 13:58:31 +0100 Subject: [PATCH 09/12] Fix interface test for OF14 --- test/tests/base/hippo_interface/foam/system/controlDict | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/tests/base/hippo_interface/foam/system/controlDict b/test/tests/base/hippo_interface/foam/system/controlDict index cb155c26..d175e452 100644 --- a/test/tests/base/hippo_interface/foam/system/controlDict +++ b/test/tests/base/hippo_interface/foam/system/controlDict @@ -13,7 +13,7 @@ FoamFile } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -solver bcTestSolver; +solver bcTest; startFrom startTime; From ac80f55294bdbcf0e8267656d1eb36b25ffb1d07 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Fri, 21 Aug 2026 10:00:41 +0100 Subject: [PATCH 10/12] Add comments to Hippo interface --- include/base/HippoInterface.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/base/HippoInterface.h b/include/base/HippoInterface.h index ad97cd6d..aa3f4b40 100644 --- a/include/base/HippoInterface.h +++ b/include/base/HippoInterface.h @@ -3,11 +3,15 @@ #include "InputParameters.h" #include "MooseObject.h" #include -#include class FoamProblem; class FoamMesh; +/* +HippoInterface is a base class containing convenient access to common +Hippo and Foam objects such as Foam::Time, Foam::fvMesh and +FoamProblem. +*/ class HippoInterface { public: From af5d6623fa8a253512efb6ba27c49e314c574546 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Tue, 25 Aug 2026 14:38:30 +0100 Subject: [PATCH 11/12] Implement HippoObject as base class for most Foam-derived objects --- include/base/HippoInterface.h | 22 ++++++++---- include/base/HippoObject.h | 16 +++++++++ include/bcs/FoamBCBase.h | 5 ++- .../postprocessors/FoamPostprocessorBase.h | 22 ++++-------- .../postprocessors/FoamSidePostprocessor.h | 2 ++ include/variables/FoamVariableField.h | 6 ++-- src/base/HippoInterface.C | 29 ++++++++++++--- src/base/HippoObject.C | 11 ++++++ src/bcs/FoamBCBase.C | 36 +++++++++---------- src/bcs/FoamDiffusionFluxBC.C | 10 +++--- src/bcs/FoamDiffusionFluxPostprocessorBC.C | 11 +++--- src/bcs/FoamFixedGradientBC.C | 4 +-- src/bcs/FoamFixedGradientPostprocessorBC.C | 4 +-- src/bcs/FoamFixedValueBC.C | 5 +-- src/bcs/FoamFixedValuePosprocessorBC.C | 5 +-- src/bcs/FoamMassFlowRateInletBC.C | 4 +-- src/bcs/FoamVariableBCBase.C | 6 ++-- src/postprocessors/FoamPostprocessorBase.C | 27 ++------------ .../FoamSideAdvectiveFluxIntegral.C | 16 +++++---- src/postprocessors/FoamSideIntegratedBase.C | 13 ++++--- .../FoamSideIntegratedFunctionObject.C | 6 ++-- src/postprocessors/FoamSideIntegratedValue.C | 4 +-- src/postprocessors/FoamSidePostprocessor.C | 2 +- src/problems/FoamProblem.C | 15 +++++--- src/variables/FoamFunctionObject.C | 9 ++--- src/variables/FoamVariableField.C | 30 +++++++--------- 26 files changed, 173 insertions(+), 147 deletions(-) create mode 100644 include/base/HippoObject.h create mode 100644 src/base/HippoObject.C diff --git a/include/base/HippoInterface.h b/include/base/HippoInterface.h index aa3f4b40..ec519cfb 100644 --- a/include/base/HippoInterface.h +++ b/include/base/HippoInterface.h @@ -2,7 +2,7 @@ #include "InputParameters.h" #include "MooseObject.h" -#include +#include "fvMesh.H" class FoamProblem; class FoamMesh; @@ -15,14 +15,22 @@ FoamProblem. class HippoInterface { public: - HippoInterface(const MooseObject * moose_object); + explicit HippoInterface(const MooseObject * moose_object); protected: - FoamProblem & _foam_problem; - FoamMesh & _mesh; - Foam::fvMesh & _fv_mesh; - Foam::Time & _foam_time; + // Retrieves FoamProblem + FoamProblem & getFoamProblem() const; + + // Retrieves FoamMesh + FoamMesh & getFoamMesh() const; + + // Retrieves Underlying OpenFOAM mesh object + Foam::fvMesh & getFvMesh() const; + + // Retrieves OpenFOAM time object + Foam::Time & getFoamTime() const; private: - FoamProblem & extractFoamProblem(const MooseObject *); + FoamProblem & _foam_problem; + static FoamProblem & extractFoamProblem(const MooseObject *); }; diff --git a/include/base/HippoObject.h b/include/base/HippoObject.h new file mode 100644 index 00000000..e89cac1f --- /dev/null +++ b/include/base/HippoObject.h @@ -0,0 +1,16 @@ +#pragma once + +#include "InputParameters.h" +#include "MooseObject.h" +#include "HippoInterface.h" + +/* +HippoObject is a base class for MooseObjects accessing OpenFOAM +objects +*/ +class HippoObject : public MooseObject, protected HippoInterface +{ +public: + static InputParameters validParams(); + HippoObject(const InputParameters & params); +}; diff --git a/include/bcs/FoamBCBase.h b/include/bcs/FoamBCBase.h index be7f3efc..0ee4b561 100644 --- a/include/bcs/FoamBCBase.h +++ b/include/bcs/FoamBCBase.h @@ -4,10 +4,9 @@ #include #include -#include #include #include -#include "HippoInterface.h" +#include "HippoObject.h" typedef std::tuple BCInfoTableRow; @@ -19,7 +18,7 @@ enum class FoamBCType fixedGradient }; -class FoamBCBase : public MooseObject, public Coupleable, protected HippoInterface +class FoamBCBase : public HippoObject, public Coupleable { public: static InputParameters validParams(); diff --git a/include/postprocessors/FoamPostprocessorBase.h b/include/postprocessors/FoamPostprocessorBase.h index 73e6794d..42a7f30a 100644 --- a/include/postprocessors/FoamPostprocessorBase.h +++ b/include/postprocessors/FoamPostprocessorBase.h @@ -1,31 +1,23 @@ #pragma once +#include "GeneralPostprocessor.h" #include "HippoInterface.h" #include "fvCFD_moose.h" -#include "InputParameters.h" -#include "Postprocessor.h" -#include "ElementUserObject.h" - -class FoamPostprocessorBase : public ElementUserObject, - public Postprocessor, - protected HippoInterface +class FoamPostprocessorBase : public GeneralPostprocessor, protected HippoInterface { public: static InputParameters validParams(); FoamPostprocessorBase(const InputParameters & params); - // We dont want the usual UserObject functions to be executed - // But we still want the Foam Postprocessors to be reported with the other - // Foam postprocessors - virtual void initialize() final; - - virtual void execute() final; + // We still want the Foam Postprocessors to be reported with the other + // postprocessors but we want to define them empty + void initialize() final {}; - virtual void finalize() final; + void execute() final {}; - virtual void threadJoin([[maybe_unused]] const UserObject & uo) final {}; + void finalize() final {}; // Compute postprocessor, to be called within FoamProblem virtual void compute() = 0; diff --git a/include/postprocessors/FoamSidePostprocessor.h b/include/postprocessors/FoamSidePostprocessor.h index 060e661e..256ea4e8 100644 --- a/include/postprocessors/FoamSidePostprocessor.h +++ b/include/postprocessors/FoamSidePostprocessor.h @@ -10,6 +10,8 @@ class FoamSidePostprocessor : public FoamPostprocessorBase FoamSidePostprocessor(const InputParameters & params); + const std::vector & boundary() const { return _boundary; } + protected: std::vector _boundary; }; diff --git a/include/variables/FoamVariableField.h b/include/variables/FoamVariableField.h index c84be8aa..da4dd2bb 100644 --- a/include/variables/FoamVariableField.h +++ b/include/variables/FoamVariableField.h @@ -1,10 +1,8 @@ #pragma once -#include "HippoInterface.h" -#include "MooseObject.h" -#include "FoamMesh.h" +#include "HippoObject.h" -class FoamVariableField : public MooseObject, protected HippoInterface +class FoamVariableField : public HippoObject { public: static InputParameters validParams(); diff --git a/src/base/HippoInterface.C b/src/base/HippoInterface.C index ed39aeb2..b477e4bc 100644 --- a/src/base/HippoInterface.C +++ b/src/base/HippoInterface.C @@ -5,13 +5,34 @@ #include "OutputInterface.h" HippoInterface::HippoInterface(const MooseObject * moose_object) - : _foam_problem(extractFoamProblem(moose_object)), - _mesh(_foam_problem.mesh()), - _fv_mesh(_mesh.fvMesh()), - _foam_time(const_cast(_fv_mesh.time())) + : _foam_problem(extractFoamProblem(moose_object)) { } +FoamProblem & +HippoInterface::getFoamProblem() const +{ + return _foam_problem; +} + +FoamMesh & +HippoInterface::getFoamMesh() const +{ + return _foam_problem.mesh(); +} + +Foam::fvMesh & +HippoInterface::getFvMesh() const +{ + return getFoamMesh().fvMesh(); +} + +Foam::Time & +HippoInterface::getFoamTime() const +{ + return const_cast(getFvMesh().time()); +} + FoamProblem & HippoInterface::extractFoamProblem(const MooseObject * moose_object) { diff --git a/src/base/HippoObject.C b/src/base/HippoObject.C new file mode 100644 index 00000000..5eed007a --- /dev/null +++ b/src/base/HippoObject.C @@ -0,0 +1,11 @@ +#include "HippoObject.h" + +InputParameters +HippoObject::validParams() +{ + return MooseObject::validParams(); +} + +HippoObject::HippoObject(const InputParameters & params) : MooseObject(params), HippoInterface(this) +{ +} diff --git a/src/bcs/FoamBCBase.C b/src/bcs/FoamBCBase.C index 0b3a64ae..4811ca18 100644 --- a/src/bcs/FoamBCBase.C +++ b/src/bcs/FoamBCBase.C @@ -1,12 +1,11 @@ #include "FoamBCBase.h" #include "FoamProblem.h" -#include "HippoInterface.h" +#include "HippoObject.h" #include #include #include -#include #include #include #include @@ -35,13 +34,11 @@ bc_type_to_string(FoamBCType const & bc_type) InputParameters FoamBCBase::validParams() { - InputParameters params = MooseObject::validParams(); + InputParameters params = HippoObject::validParams(); params.addRequiredParam("foam_variable", "Name of a Foam field. e.g. T (temperature) U (velocity)."); params.addParam>("boundary", "Boundaries that the boundary condition applies to."); - params.addRequiredParam("foam_variable", - "Name of a Foam field. e.g. T (temperature) U (velocity)."); params.registerSystemAttributeName("FoamBC"); params.registerBase("FoamBC"); @@ -50,20 +47,19 @@ FoamBCBase::validParams() } FoamBCBase::FoamBCBase(const InputParameters & params, const FoamBCType bc_type) - : MooseObject(params), + : HippoObject(params), Coupleable(this, false), - HippoInterface(this), _foam_variable(params.get("foam_variable")), _boundary(params.get>("boundary")), _patch_replaced(false) { // check that the foam variable exists if (!params.isPrivate("foam_variable") && - !_mesh.foamHasObject(_foam_variable)) + !getFoamMesh().foamHasObject(_foam_variable)) mooseError("There is no OpenFOAM field named '", _foam_variable, "'"); // check that the boundary is in the FoamMesh - auto all_subdomain_names = _mesh.getSubdomainNames(_mesh.getSubdomainList()); + auto all_subdomain_names = getFoamMesh().getSubdomainNames(getFoamMesh().getSubdomainList()); for (auto subdomain : _boundary) { auto it = std::find(all_subdomain_names.begin(), all_subdomain_names.end(), subdomain); @@ -76,9 +72,9 @@ FoamBCBase::FoamBCBase(const InputParameters & params, const FoamBCType bc_type) for (auto subdomain : _boundary) { - if (_mesh.foamHasObject(_foam_variable)) + if (getFoamMesh().foamHasObject(_foam_variable)) constructFoamScalarPatch(subdomain, bc_type); - else if (_mesh.foamHasObject(_foam_variable)) + else if (getFoamMesh().foamHasObject(_foam_variable)) constructFoamVectorPatch(subdomain, bc_type); else mooseError("Variable must have type scalar or vector."); @@ -88,8 +84,8 @@ FoamBCBase::FoamBCBase(const InputParameters & params, const FoamBCType bc_type) void FoamBCBase::constructFoamScalarPatch(const std::string & patch_name, const FoamBCType bc_type) { - auto & var = _fv_mesh.lookupObjectRef(_foam_variable); - Foam::label id = _fv_mesh.boundary().findIndex(patch_name); + auto & var = getFvMesh().lookupObjectRef(_foam_variable); + Foam::label id = getFvMesh().boundary().findIndex(patch_name); if (bc_type_to_string(bc_type) == var.boundaryField()[id].type()) return; @@ -111,7 +107,7 @@ FoamBCBase::constructFoamScalarPatch(const std::string & patch_name, const FoamB var.boundaryFieldRef().set( id, Foam::fvPatchField::New( - _fv_mesh.boundary()[id], var.boundaryField()[id].internalField(), bcDict)); + getFvMesh().boundary()[id], var.boundaryField()[id].internalField(), bcDict)); // If temperature is replaced, internal energy or enthalpy typically needs replacing. updateEnergyPatch(var, id, bc_type); @@ -120,8 +116,8 @@ FoamBCBase::constructFoamScalarPatch(const std::string & patch_name, const FoamB void FoamBCBase::constructFoamVectorPatch(const std::string & patch_name, const FoamBCType bc_type) { - auto & var = _fv_mesh.lookupObjectRef(_foam_variable); - Foam::label id = _fv_mesh.boundary().findIndex(patch_name); + auto & var = getFvMesh().lookupObjectRef(_foam_variable); + Foam::label id = getFvMesh().boundary().findIndex(patch_name); if (bc_type_to_string(bc_type) == var.boundaryField()[id].type()) return; @@ -139,9 +135,9 @@ FoamBCBase::constructFoamVectorPatch(const std::string & patch_name, const FoamB bcDict.add("value", "uniform (0. 0. 0.)"); } - var.boundaryFieldRef().set( - id, - Foam::fvPatchField::New(_fv_mesh.boundary()[id], var.internalField(), bcDict)); + var.boundaryFieldRef().set(id, + Foam::fvPatchField::New( + getFvMesh().boundary()[id], var.internalField(), bcDict)); } void @@ -150,7 +146,7 @@ FoamBCBase::updateEnergyPatch(const Foam::volScalarField & var, const FoamBCType bc_type) { - auto thermos = _fv_mesh.lookupClass(); + auto thermos = getFvMesh().lookupClass(); for (const auto & item : thermos) { diff --git a/src/bcs/FoamDiffusionFluxBC.C b/src/bcs/FoamDiffusionFluxBC.C index 3916f6e9..97d7130a 100644 --- a/src/bcs/FoamDiffusionFluxBC.C +++ b/src/bcs/FoamDiffusionFluxBC.C @@ -27,7 +27,7 @@ FoamDiffusionFluxBC::FoamDiffusionFluxBC(const InputParameters & params) : FoamVariableBCBase(params, FoamBCType::fixedGradient), _diffusivity(getParam("diffusivity")) { - if (!_fv_mesh.foundObject(_diffusivity)) + if (!getFvMesh().foundObject(_diffusivity)) { mooseError("Diffusivity '", _diffusivity, "' not a Foam volScalarField."); } @@ -38,18 +38,18 @@ FoamDiffusionFluxBC::imposeBoundaryCondition() { // Get subdomains this FoamBC acts on // TODO: replace with BoundaryRestriction member functions once FoamMesh is updated - auto subdomains = _mesh.getSubdomainIDs(_boundary); + auto subdomains = getFoamMesh().getSubdomainIDs(_boundary); for (auto subdomain : subdomains) { std::vector && grad_array = getMooseVariableArray(subdomain); // Get the gradient associated with the field auto & foam_gradient = - _mesh.getGradientBCField(subdomain, _foam_variable); + getFoamMesh().getGradientBCField(subdomain, _foam_variable); assert(grad_array.size() == static_cast(foam_gradient.size())); - auto & coeff = - _fv_mesh.boundary()[subdomain].lookupPatchField(_diffusivity); + auto & coeff = getFvMesh().boundary()[subdomain].lookupPatchField( + _diffusivity); assert(foam_gradient.size() == coeff.size()); // set gradient diff --git a/src/bcs/FoamDiffusionFluxPostprocessorBC.C b/src/bcs/FoamDiffusionFluxPostprocessorBC.C index e945bac2..6b7d184e 100644 --- a/src/bcs/FoamDiffusionFluxPostprocessorBC.C +++ b/src/bcs/FoamDiffusionFluxPostprocessorBC.C @@ -21,7 +21,7 @@ FoamDiffusionFluxPostprocessorBC::FoamDiffusionFluxPostprocessorBC(const InputPa : FoamPostprocessorBCBase(params, FoamBCType::fixedGradient), _diffusivity(getParam("diffusivity")) { - if (!_fv_mesh.foundObject(_diffusivity)) + if (!getFvMesh().foundObject(_diffusivity)) { mooseError("Diffusivity '", _diffusivity, "' not a Foam volScalarField."); } @@ -31,17 +31,18 @@ void FoamDiffusionFluxPostprocessorBC::imposeBoundaryCondition() { // Get subdomains this FoamBC acts on - auto subdomains = _mesh.getSubdomainIDs(_boundary); + auto subdomains = getFoamMesh().getSubdomainIDs(_boundary); for (auto subdomain : subdomains) { - const auto & boundary = _fv_mesh.boundary()[subdomain]; + const auto & boundary = getFvMesh().boundary()[subdomain]; // Get underlying field from OpenFOAM boundary patch. auto & foam_gradient = - _mesh.getGradientBCField(subdomain, _foam_variable); + getFoamMesh().getGradientBCField(subdomain, _foam_variable); // Get the underlying diffusivity field const auto & coeff = - _fv_mesh.boundary()[subdomain].lookupPatchField(_diffusivity); + getFvMesh().boundary()[subdomain].lookupPatchField( + _diffusivity); // Calculate the bulk value of the diffusivity coefficient const auto area = boundary.magSf(); diff --git a/src/bcs/FoamFixedGradientBC.C b/src/bcs/FoamFixedGradientBC.C index 3d1fa33b..9140a3ef 100644 --- a/src/bcs/FoamFixedGradientBC.C +++ b/src/bcs/FoamFixedGradientBC.C @@ -27,14 +27,14 @@ FoamFixedGradientBC::imposeBoundaryCondition() { // Get subdomains this FoamBC acts on // TODO: replace with BoundaryRestriction member functions once FoamMesh is updated - auto subdomains = _mesh.getSubdomainIDs(_boundary); + auto subdomains = getFoamMesh().getSubdomainIDs(_boundary); for (auto subdomain : subdomains) { std::vector && grad_array = getMooseVariableArray(subdomain); // Get the gradient associated with the field auto & foam_gradient = - _mesh.getGradientBCField(subdomain, _foam_variable); + getFoamMesh().getGradientBCField(subdomain, _foam_variable); assert(grad_array.size() == static_cast(foam_gradient.size())); std::copy(grad_array.begin(), grad_array.end(), foam_gradient.begin()); diff --git a/src/bcs/FoamFixedGradientPostprocessorBC.C b/src/bcs/FoamFixedGradientPostprocessorBC.C index 7592c023..028f4fc4 100644 --- a/src/bcs/FoamFixedGradientPostprocessorBC.C +++ b/src/bcs/FoamFixedGradientPostprocessorBC.C @@ -22,12 +22,12 @@ void FoamFixedGradientPostprocessorBC::imposeBoundaryCondition() { // Get subdomains this FoamBC acts on - auto subdomains = _mesh.getSubdomainIDs(_boundary); + auto subdomains = getFoamMesh().getSubdomainIDs(_boundary); for (auto subdomain : subdomains) { // Get underlying field from OpenFOAM boundary patch. auto & foam_gradient = - _mesh.getGradientBCField(subdomain, _foam_variable); + getFoamMesh().getGradientBCField(subdomain, _foam_variable); // If diffusivity_coefficient is specified grad array is a flux, so result // must be divided by it diff --git a/src/bcs/FoamFixedValueBC.C b/src/bcs/FoamFixedValueBC.C index 39e6a970..87627dc1 100644 --- a/src/bcs/FoamFixedValueBC.C +++ b/src/bcs/FoamFixedValueBC.C @@ -24,13 +24,14 @@ void FoamFixedValueBC::imposeBoundaryCondition() { // Get subdomains this FoamBC acts on - auto subdomains = _mesh.getSubdomainIDs(_boundary); + auto subdomains = getFoamMesh().getSubdomainIDs(_boundary); for (auto subdomain : subdomains) { std::vector && var_array = getMooseVariableArray(subdomain); // Get underlying field from OpenFOAM boundary patch - auto & foam_var = _mesh.getBCField(subdomain, _foam_variable); + auto & foam_var = + getFoamMesh().getBCField(subdomain, _foam_variable); assert(var_array.size() == static_cast(foam_var.size())); diff --git a/src/bcs/FoamFixedValuePosprocessorBC.C b/src/bcs/FoamFixedValuePosprocessorBC.C index 8c9356d3..612ec75b 100644 --- a/src/bcs/FoamFixedValuePosprocessorBC.C +++ b/src/bcs/FoamFixedValuePosprocessorBC.C @@ -20,11 +20,12 @@ void FoamFixedValuePostprocessorBC::imposeBoundaryCondition() { // Get subdomains this FoamBC acts on - auto subdomains = _mesh.getSubdomainIDs(_boundary); + auto subdomains = getFoamMesh().getSubdomainIDs(_boundary); for (auto subdomain : subdomains) { // Get underlying field from OpenFOAM boundary patch - auto & foam_var = _mesh.getBCField(subdomain, _foam_variable); + auto & foam_var = + getFoamMesh().getBCField(subdomain, _foam_variable); std::fill(foam_var.begin(), foam_var.end(), _pp_value); } diff --git a/src/bcs/FoamMassFlowRateInletBC.C b/src/bcs/FoamMassFlowRateInletBC.C index 7a7d53f7..d435e825 100644 --- a/src/bcs/FoamMassFlowRateInletBC.C +++ b/src/bcs/FoamMassFlowRateInletBC.C @@ -29,10 +29,10 @@ FoamMassFlowRateInletBC::imposeBoundaryCondition() { // Get subdomains this FoamBC acts on // TODO: replace with BoundaryRestriction member functions once FoamMesh is updated - auto subdomains = _mesh.getSubdomainIDs(_boundary); + auto subdomains = getFoamMesh().getSubdomainIDs(_boundary); for (auto subdomain : subdomains) { - const auto & boundary_patch = _fv_mesh.boundary()[subdomain]; + const auto & boundary_patch = getFvMesh().boundary()[subdomain]; auto & U_var = const_cast &>( boundary_patch.lookupPatchField("U")); diff --git a/src/bcs/FoamVariableBCBase.C b/src/bcs/FoamVariableBCBase.C index 719e6206..e5f7ea5a 100644 --- a/src/bcs/FoamVariableBCBase.C +++ b/src/bcs/FoamVariableBCBase.C @@ -74,14 +74,14 @@ FoamVariableBCBase::variableValueAtElement(const libMesh::Elem & elem) const std::vector FoamVariableBCBase::getMooseVariableArray(int subdomainId) const { - size_t patch_count = _mesh.getPatchCount(subdomainId); - size_t patch_offset = _mesh.getPatchOffset(subdomainId); + size_t patch_count = getFoamMesh().getPatchCount(subdomainId); + size_t patch_offset = getFoamMesh().getPatchOffset(subdomainId); std::vector var_array(patch_count); for (size_t j = 0; j < patch_count; ++j) { auto elem = patch_offset + j; - const auto elem_ptr = _mesh.getElemPtr(elem + _mesh.rank_element_offset); + const auto elem_ptr = getFoamMesh().getElemPtr(elem + getFoamMesh().rank_element_offset); assert(elem_ptr); var_array[j] = variableValueAtElement(*elem_ptr); } diff --git a/src/postprocessors/FoamPostprocessorBase.C b/src/postprocessors/FoamPostprocessorBase.C index 7f715096..871329d1 100644 --- a/src/postprocessors/FoamPostprocessorBase.C +++ b/src/postprocessors/FoamPostprocessorBase.C @@ -1,35 +1,12 @@ -#include "FoamMesh.h" #include "FoamPostprocessorBase.h" -#include "HippoInterface.h" -#include "InputParameters.h" -#include "Postprocessor.h" -#include "ElementUserObject.h" -#include "FoamProblem.h" InputParameters FoamPostprocessorBase::validParams() { - auto params = ElementUserObject::validParams(); - params += Postprocessor::validParams(); - return params; + return GeneralPostprocessor::validParams(); } FoamPostprocessorBase::FoamPostprocessorBase(const InputParameters & params) - : ElementUserObject(params), Postprocessor(this), HippoInterface(this) -{ -} - -void -FoamPostprocessorBase::initialize() -{ -} - -void -FoamPostprocessorBase::execute() -{ -} - -void -FoamPostprocessorBase::finalize() + : GeneralPostprocessor(params), HippoInterface(this) { } diff --git a/src/postprocessors/FoamSideAdvectiveFluxIntegral.C b/src/postprocessors/FoamSideAdvectiveFluxIntegral.C index bdf615a1..fef0964c 100644 --- a/src/postprocessors/FoamSideAdvectiveFluxIntegral.C +++ b/src/postprocessors/FoamSideAdvectiveFluxIntegral.C @@ -22,10 +22,10 @@ FoamSideAdvectiveFluxIntegral::FoamSideAdvectiveFluxIntegral(const InputParamete _advection_velocity(params.get("advective_velocity")) { - if (!_fv_mesh.foundObject(_foam_scalar)) + if (!getFvMesh().foundObject(_foam_scalar)) mooseError("foam_scalar '", _foam_scalar, "' not found."); - if (!_fv_mesh.foundObject(_advection_velocity)) + if (!getFvMesh().foundObject(_advection_velocity)) mooseError("advective_velocity '", _advection_velocity, "' not found."); } @@ -36,13 +36,15 @@ FoamSideAdvectiveFluxIntegral::compute() for (auto & boundary : _boundary) { auto & var_array = - _fv_mesh.boundary()[boundary].lookupPatchField(_foam_scalar); + getFvMesh().boundary()[boundary].lookupPatchField( + _foam_scalar); - auto & vel_array = _fv_mesh.boundary()[boundary].lookupPatchField( - _advection_velocity); + auto & vel_array = + getFvMesh().boundary()[boundary].lookupPatchField( + _advection_velocity); - auto & areas = _fv_mesh.boundary()[boundary].magSf(); - auto && normals = _fv_mesh.boundary()[boundary].nf(); + auto & areas = getFvMesh().boundary()[boundary].magSf(); + auto && normals = getFvMesh().boundary()[boundary].nf(); // integrate locally for (int i = 0; i < var_array.size(); ++i) diff --git a/src/postprocessors/FoamSideIntegratedBase.C b/src/postprocessors/FoamSideIntegratedBase.C index 326e9a06..a7958716 100644 --- a/src/postprocessors/FoamSideIntegratedBase.C +++ b/src/postprocessors/FoamSideIntegratedBase.C @@ -1,7 +1,6 @@ #include "FoamSideIntegratedBase.h" #include "MooseEnum.h" #include "MooseTypes.h" -#include InputParameters FoamSideIntegratedBase::validParams() @@ -32,21 +31,21 @@ FoamSideIntegratedBase::integrateValue(const std::string & variable) // loop over boundary ids for (auto & boundary : _boundary) { - auto & areas = _fv_mesh.boundary()[boundary].magSf(); + auto & areas = getFvMesh().boundary()[boundary].magSf(); Foam::Field var_array; - if (_fv_mesh.foundObject(variable)) + if (getFvMesh().foundObject(variable)) { // get vector data associated with the boundary auto & vec_data = - _fv_mesh.boundary()[boundary].lookupPatchField(variable); + getFvMesh().boundary()[boundary].lookupPatchField(variable); // get the component specified in parameters and get the // component of the vector in that direction auto components = parameters().get("component"); if (components == "normal") { - auto && normals = _fv_mesh.boundary()[boundary].nf(); + auto && normals = getFvMesh().boundary()[boundary].nf(); var_array = normals & vec_data; } else if (components == "magnitude") @@ -57,7 +56,7 @@ FoamSideIntegratedBase::integrateValue(const std::string & variable) else { var_array = - _fv_mesh.boundary()[boundary].lookupPatchField(variable); + getFvMesh().boundary()[boundary].lookupPatchField(variable); } // Integrate @@ -80,7 +79,7 @@ FoamSideIntegratedBase::getArea() // loop over boundary ids for (auto & boundary : _boundary) { - auto & areas = _fv_mesh.boundary()[boundary].magSf(); + auto & areas = getFvMesh().boundary()[boundary].magSf(); for (int i = 0; i < areas.size(); ++i) { area += areas[i]; diff --git a/src/postprocessors/FoamSideIntegratedFunctionObject.C b/src/postprocessors/FoamSideIntegratedFunctionObject.C index 32b66efb..9e449b80 100644 --- a/src/postprocessors/FoamSideIntegratedFunctionObject.C +++ b/src/postprocessors/FoamSideIntegratedFunctionObject.C @@ -26,7 +26,7 @@ FoamSideIntegratedFunctionObject::FoamSideIntegratedFunctionObject(const InputPa std::unique_ptr FoamSideIntegratedFunctionObject::createFunctionObject(const std::string & fo_name) { - auto fo_dict = _foam_time.controlDict().lookupOrDefault(fo_name, Foam::dictionary()); + auto fo_dict = getFoamTime().controlDict().lookupOrDefault(fo_name, Foam::dictionary()); Foam::wordList patch_names(_boundary.begin(), _boundary.end()); @@ -36,12 +36,12 @@ FoamSideIntegratedFunctionObject::createFunctionObject(const std::string & fo_na if (fo_name == "wallHeatFlux") { return std::make_unique( - "wallHeatFlux", _foam_time, fo_dict); + "wallHeatFlux", getFoamTime(), fo_dict); } else // wallShearStress { return std::make_unique( - "wallShearStress", _foam_time, fo_dict); + "wallShearStress", getFoamTime(), fo_dict); } } diff --git a/src/postprocessors/FoamSideIntegratedValue.C b/src/postprocessors/FoamSideIntegratedValue.C index 4444d9e8..c2198b16 100644 --- a/src/postprocessors/FoamSideIntegratedValue.C +++ b/src/postprocessors/FoamSideIntegratedValue.C @@ -18,8 +18,8 @@ FoamSideIntegratedValue::FoamSideIntegratedValue(const InputParameters & params) : FoamSideIntegratedBase(params), _foam_variable(getParam("foam_variable")) { // determine if this is a vector scalar, ahead of computation - if (!_fv_mesh.foundObject(_foam_variable) && - !_fv_mesh.foundObject(_foam_variable)) + if (!getFvMesh().foundObject(_foam_variable) && + !getFvMesh().foundObject(_foam_variable)) mooseError("No Foam scalar or vector called '", _foam_variable, "'."); } diff --git a/src/postprocessors/FoamSidePostprocessor.C b/src/postprocessors/FoamSidePostprocessor.C index a7392814..92605150 100644 --- a/src/postprocessors/FoamSidePostprocessor.C +++ b/src/postprocessors/FoamSidePostprocessor.C @@ -16,7 +16,7 @@ FoamSidePostprocessor::FoamSidePostprocessor(const InputParameters & params) { for (auto & boundary : _boundary) { - if (_fv_mesh.boundary().findIndex(boundary) == -1) + if (getFvMesh().boundary().findIndex(boundary) == -1) mooseError("Boundary '", boundary, "' not found in FoamMesh."); } } diff --git a/src/problems/FoamProblem.C b/src/problems/FoamProblem.C index d50dd118..0df64185 100644 --- a/src/problems/FoamProblem.C +++ b/src/problems/FoamProblem.C @@ -3,6 +3,7 @@ #include "FoamProblem.h" #include "FoamSolver.h" #include "hippoUtils.h" +#include "FoamSidePostprocessor.h" #include "Attributes.h" #include "ExternalProblem.h" @@ -189,8 +190,8 @@ FoamProblem::verifyFoamPostprocessors() theWarehouse().query().condition(Interfaces::Postprocessor); query_uos.queryInto(pps); - VariadicTable vt({ - "Foam postprocessor", + VariadicTable side_vt({ + "Foam side postprocessor", "Type", "Boundaries", }); @@ -201,9 +202,15 @@ FoamProblem::verifyFoamPostprocessors() if (fpp) { _foam_postprocessor.push_back(fpp); - vt.addRow(fpp->name(), fpp->type(), Hippo::internal::listFromVector(fpp->blocks())); + // Add side postprocessors to the side table + if (auto side_fpp = dynamic_cast(fpp)) + { + side_vt.addRow(side_fpp->name(), + side_fpp->type(), + Hippo::internal::listFromVector(side_fpp->boundary())); + } } } - vt.print(_console); + side_vt.print(_console); } diff --git a/src/variables/FoamFunctionObject.C b/src/variables/FoamFunctionObject.C index 8168e463..99237c11 100644 --- a/src/variables/FoamFunctionObject.C +++ b/src/variables/FoamFunctionObject.C @@ -1,4 +1,5 @@ #include "FoamVariableField.h" +#include "FoamMesh.h" #include "FoamFunctionObject.h" #include "InputParameters.h" #include "Registry.h" @@ -12,15 +13,15 @@ registerMooseObject("hippoApp", FoamFunctionObject); FoamFunctionObject::FoamFunctionObject(const InputParameters & params) : FoamVariableField(params) { // construct input Foam dictionary for the functionObject - auto fo_dict = _foam_time.controlDict().lookupOrDefault(_foam_variable, Foam::dictionary()); + auto fo_dict = getFoamTime().controlDict().lookupOrDefault(_foam_variable, Foam::dictionary()); // create patch names where functionObject applies // TODO: when volumetric mirror is implemented some of this may need to be // put in the _getFunctionObject function. - auto patch_ids{_mesh.getSubdomainList()}; + auto patch_ids{getFoamMesh().getSubdomainList()}; Foam::wordList patch_names; for (auto id : patch_ids) - patch_names.append(_fv_mesh.boundary()[id].name()); + patch_names.append(getFvMesh().boundary()[id].name()); fo_dict.set("patches", patch_names); fo_dict.set("writeToFile", false); @@ -37,7 +38,7 @@ FoamFunctionObject::_getFunctionObject(Foam::dictionary fo_dict) if (_foam_variable == "wallHeatFlux") { Foam::functionObjects::wallHeatFlux * whf_func = - new Foam::functionObjects::wallHeatFlux("wallHeatFlux", _foam_time, fo_dict); + new Foam::functionObjects::wallHeatFlux("wallHeatFlux", getFoamTime(), fo_dict); return static_cast(whf_func); } else diff --git a/src/variables/FoamVariableField.C b/src/variables/FoamVariableField.C index 3ed44d5c..a1e964b0 100644 --- a/src/variables/FoamVariableField.C +++ b/src/variables/FoamVariableField.C @@ -1,26 +1,22 @@ #include "FoamVariableField.h" -#include "FoamProblem.h" -#include "HippoInterface.h" +#include "HippoObject.h" #include "InputParameters.h" -#include "MooseObject.h" #include "MooseTypes.h" -#include "MooseVariableFieldBase.h" -#include "MooseVariableFieldBase.h" +#include "MooseVariableBase.h" +#include "FoamProblem.h" registerMooseObject("hippoApp", FoamVariableField); InputParameters FoamVariableField::validParams() { - auto params = MooseObject::validParams(); + auto params = HippoObject::validParams(); - params.addRequiredParam("foam_variable", - "OpenFOAM variable or functionObject to be shadowed"); params.addRequiredParam("foam_variable", "OpenFOAM variable or functionObject to be shadowed"); // Get desired parameters from Variable objects - params.transferParam>(MooseVariable::validParams(), "initial_condition"); + params.transferParam>(MooseVariableBase::validParams(), "initial_condition"); params.registerBase("FoamVariable"); params.registerSystemAttributeName("FoamVariable"); @@ -28,9 +24,7 @@ FoamVariableField::validParams() } FoamVariableField::FoamVariableField(const InputParameters & params) - : MooseObject(params), - HippoInterface(this), - _foam_variable(params.get("foam_variable")) + : HippoObject(params), _foam_variable(params.get("foam_variable")) { } @@ -38,20 +32,20 @@ void FoamVariableField::transferVariable() { THREAD_ID tid = parameters().get("_tid"); - auto & moose_var = getMooseApp().feProblem().getVariable(tid, _name); + auto & moose_var = getFoamProblem().getVariable(tid, _name); // Loop through subdomains extracting foam_variable and setting on libMesh elements - for (auto subdomain : _mesh.getSubdomainList()) + for (auto subdomain : getFoamMesh().getSubdomainList()) { - size_t patch_count = _mesh.getPatchCount(subdomain); - size_t patch_offset = _mesh.getPatchOffset(subdomain); + size_t patch_count = getFoamMesh().getPatchCount(subdomain); + size_t patch_offset = getFoamMesh().getPatchOffset(subdomain); - auto & var = _fv_mesh.boundary()[subdomain].lookupPatchField( + auto & var = getFvMesh().boundary()[subdomain].lookupPatchField( _foam_variable); for (size_t j = 0; j < patch_count; ++j) { auto elem = patch_offset + j; - auto elem_ptr = _mesh.getElemPtr(elem + _mesh.rank_element_offset); + auto elem_ptr = getFoamMesh().getElemPtr(elem + getFoamMesh().rank_element_offset); assert(elem_ptr); auto dof_t = elem_ptr->dof_number(moose_var.sys().number(), moose_var.number(), 0); moose_var.sys().solution().set(dof_t, var[j]); From 1723b30c43915f7ac830f8659e544919aec35de4 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Wed, 26 Aug 2026 13:26:14 +0100 Subject: [PATCH 12/12] Update after review with unneeded comments deleted --- test/tests/actions/foam_variable/main.i | 1 - test/tests/base/hippo_interface/main.i | 1 - test/tests/base/hippo_interface/tests | 1 + test/tests/bcs/fixed_value/main.i | 1 - test/tests/bcs/fixed_value_pp/main.i | 1 - test/tests/bcs/mass_flow_rate/main.i | 1 - 6 files changed, 1 insertion(+), 5 deletions(-) diff --git a/test/tests/actions/foam_variable/main.i b/test/tests/actions/foam_variable/main.i index a1abb855..c07d0e35 100644 --- a/test/tests/actions/foam_variable/main.i +++ b/test/tests/actions/foam_variable/main.i @@ -20,7 +20,6 @@ [] [Problem] type = FoamProblem - # Take the boundary temperature from OpenFOAM and set it on the MOOSE mesh. [] [Executioner] diff --git a/test/tests/base/hippo_interface/main.i b/test/tests/base/hippo_interface/main.i index 639300f1..2e4ae9da 100644 --- a/test/tests/base/hippo_interface/main.i +++ b/test/tests/base/hippo_interface/main.i @@ -29,7 +29,6 @@ [Problem] type = FoamProblem - # Take the boundary temperature from OpenFOAM and set it on the MOOSE mesh. [] [Executioner] diff --git a/test/tests/base/hippo_interface/tests b/test/tests/base/hippo_interface/tests index 306b7ddc..e4eff50d 100644 --- a/test/tests/base/hippo_interface/tests +++ b/test/tests/base/hippo_interface/tests @@ -1,5 +1,6 @@ [Tests] [foam_bc_action_test] + requirement = "Test HippoInterface works correctly with error ocurring if HippoObjects used without FoamProblem" [setup] type = RunCommand command = 'bash -c "foamCleanCase -case foam && blockMesh -case foam && decomposePar -force -case foam"' diff --git a/test/tests/bcs/fixed_value/main.i b/test/tests/bcs/fixed_value/main.i index ebd919d2..791aa916 100644 --- a/test/tests/bcs/fixed_value/main.i +++ b/test/tests/bcs/fixed_value/main.i @@ -58,7 +58,6 @@ [] [Problem] type = FoamProblem - # Take the boundary temperature from OpenFOAM and set it on the MOOSE mesh. [] [Executioner] diff --git a/test/tests/bcs/fixed_value_pp/main.i b/test/tests/bcs/fixed_value_pp/main.i index b1ef805d..43b297d3 100644 --- a/test/tests/bcs/fixed_value_pp/main.i +++ b/test/tests/bcs/fixed_value_pp/main.i @@ -59,7 +59,6 @@ [Problem] type = FoamProblem - # Take the boundary temperature from OpenFOAM and set it on the MOOSE mesh. [] [Executioner] diff --git a/test/tests/bcs/mass_flow_rate/main.i b/test/tests/bcs/mass_flow_rate/main.i index 6ae258c2..befbe651 100644 --- a/test/tests/bcs/mass_flow_rate/main.i +++ b/test/tests/bcs/mass_flow_rate/main.i @@ -29,7 +29,6 @@ [Problem] type = FoamProblem - # Take the boundary temperature from OpenFOAM and set it on the MOOSE mesh. [] [Executioner]