From 2b4ae44ccc3cfc0935e301d189d4335236a4e459 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Wed, 8 Oct 2025 16:25:59 +0100 Subject: [PATCH 01/52] Create working side average postprocessor --- src/postprocessors/FoamSidePostprocessor.C | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/postprocessors/FoamSidePostprocessor.C b/src/postprocessors/FoamSidePostprocessor.C index 98bd6b98..2feca540 100644 --- a/src/postprocessors/FoamSidePostprocessor.C +++ b/src/postprocessors/FoamSidePostprocessor.C @@ -1,6 +1,8 @@ #include "FoamSidePostprocessor.h" #include "InputParameters.h" #include "MooseTypes.h" +#include "FoamProblem.h" +#include "Postprocessor.h" InputParameters FoamSidePostprocessor::validParams() From 6fa9116c38f27509cfebbf5b31dcabd9024144ec Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Thu, 9 Oct 2025 17:15:32 +0100 Subject: [PATCH 02/52] Updated FoamProcessor so it computes with FoamProblem --- src/postprocessors/FoamSidePostprocessor.C | 1 - 1 file changed, 1 deletion(-) diff --git a/src/postprocessors/FoamSidePostprocessor.C b/src/postprocessors/FoamSidePostprocessor.C index 2feca540..5a579413 100644 --- a/src/postprocessors/FoamSidePostprocessor.C +++ b/src/postprocessors/FoamSidePostprocessor.C @@ -2,7 +2,6 @@ #include "InputParameters.h" #include "MooseTypes.h" #include "FoamProblem.h" -#include "Postprocessor.h" InputParameters FoamSidePostprocessor::validParams() From 7fbd7de1e9663403cce7846d44bce158f88e361c Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Tue, 14 Oct 2025 12:45:35 +0100 Subject: [PATCH 03/52] Add initial implementation of mass flow rate inlet BC --- include/bcs/FoamMassFlowRateInletBC.h | 19 +++++++++ src/bcs/FoamMassFlowRateInletBC.C | 61 +++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 include/bcs/FoamMassFlowRateInletBC.h create mode 100644 src/bcs/FoamMassFlowRateInletBC.C diff --git a/include/bcs/FoamMassFlowRateInletBC.h b/include/bcs/FoamMassFlowRateInletBC.h new file mode 100644 index 00000000..0175a6a2 --- /dev/null +++ b/include/bcs/FoamMassFlowRateInletBC.h @@ -0,0 +1,19 @@ +#include "FoamBCBase.h" +#include "InputParameters.h" +#include "MooseTypes.h" +#include "PostprocessorInterface.h" + +class FoamMassFlowRateInletBC : public FoamBCBase, public PostprocessorInterface +{ +public: + static InputParameters validParams(); + + FoamMassFlowRateInletBC(const InputParameters & params); + + virtual void imposeBoundaryCondition() override; + + virtual void initialSetup() override; + +protected: + PostprocessorName _pp_name; +}; diff --git a/src/bcs/FoamMassFlowRateInletBC.C b/src/bcs/FoamMassFlowRateInletBC.C new file mode 100644 index 00000000..7f589ac9 --- /dev/null +++ b/src/bcs/FoamMassFlowRateInletBC.C @@ -0,0 +1,61 @@ +#include "FoamBCBase.h" +#include "FoamMassFlowRateInletBC.h" +#include "InputParameters.h" +#include "MooseTypes.h" +#include "Postprocessor.h" +#include "Registry.h" +#include "finiteVolume/fields/fvPatchFields/derived/flowRateInletVelocity/flowRateInletVelocityFvPatchVectorField.H" + +registerMooseObject("hippoApp", FoamMassFlowRateInletBC); + +InputParameters +FoamMassFlowRateInletBC::validParams() +{ + auto params = FoamBCBase::validParams(); + params.remove("v"); + params.remove("initial_condition"); + params.remove("foam_variable"); + + params.addParam( + "foam_variable", "U", "Name of foam variable associated with velocity"); + + params.addRequiredParam("postprocessor", + "Postprocessors containing mass flow rate."); + + return params; +} + +FoamMassFlowRateInletBC::FoamMassFlowRateInletBC(const InputParameters & params) + : FoamBCBase(params), + PostprocessorInterface(this), + _pp_name(params.get("postprocessor")) +{ +} + +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); + for (auto subdomain : subdomains) + { + auto pp_value = getPostprocessorValueByName(_pp_name); + + auto & U_var = const_cast &>( + foam_mesh.boundary()[subdomain].lookupPatchField( + _foam_variable)); + auto && nf = foam_mesh.boundary()[subdomain].nf(); + auto & rho = + foam_mesh.boundary()[subdomain].lookupPatchField("rho"); + + U_var = nf / rho * pp_value; + } +} + +void +FoamMassFlowRateInletBC::initialSetup() +{ +} From a21f34695621e3964019e3dddecd2d5750bf7021 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Tue, 14 Oct 2025 12:54:53 +0100 Subject: [PATCH 04/52] Simplify mass flow rate BC --- src/bcs/FoamMassFlowRateInletBC.C | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/bcs/FoamMassFlowRateInletBC.C b/src/bcs/FoamMassFlowRateInletBC.C index 7f589ac9..704f781b 100644 --- a/src/bcs/FoamMassFlowRateInletBC.C +++ b/src/bcs/FoamMassFlowRateInletBC.C @@ -2,9 +2,7 @@ #include "FoamMassFlowRateInletBC.h" #include "InputParameters.h" #include "MooseTypes.h" -#include "Postprocessor.h" #include "Registry.h" -#include "finiteVolume/fields/fvPatchFields/derived/flowRateInletVelocity/flowRateInletVelocityFvPatchVectorField.H" registerMooseObject("hippoApp", FoamMassFlowRateInletBC); @@ -43,15 +41,13 @@ FoamMassFlowRateInletBC::imposeBoundaryCondition() for (auto subdomain : subdomains) { auto pp_value = getPostprocessorValueByName(_pp_name); + auto & boundary_patch = foam_mesh.boundary()[subdomain]; auto & U_var = const_cast &>( - foam_mesh.boundary()[subdomain].lookupPatchField( - _foam_variable)); - auto && nf = foam_mesh.boundary()[subdomain].nf(); - auto & rho = - foam_mesh.boundary()[subdomain].lookupPatchField("rho"); + boundary_patch.lookupPatchField(_foam_variable)); + auto & rho = boundary_patch.lookupPatchField("rho"); - U_var = nf / rho * pp_value; + U_var = pp_value * boundary_patch.nf() / (rho * boundary_patch.magSf()); } } From a99aa4109610b64152d6d8b7ed13d67a06066215 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Tue, 14 Oct 2025 13:32:38 +0100 Subject: [PATCH 05/52] Add initial makeshift test for mass flow rate BC --- Makefile | 1 + src/bcs/FoamMassFlowRateInletBC.C | 6 +- test/tests/bcs/mass_flow_rate/foam/0/T | 56 ++++++++++++ test/tests/bcs/mass_flow_rate/foam/0/U | 31 +++++++ test/tests/bcs/mass_flow_rate/foam/0/p | 30 +++++++ test/tests/bcs/mass_flow_rate/foam/0/p_rgh | 30 +++++++ test/tests/bcs/mass_flow_rate/foam/0/rho | 56 ++++++++++++ test/tests/bcs/mass_flow_rate/foam/constant/g | 21 +++++ .../foam/constant/momentumTransport | 18 ++++ .../foam/constant/physicalProperties | 52 ++++++++++++ .../mass_flow_rate/foam/system/blockMeshDict | 85 +++++++++++++++++++ .../mass_flow_rate/foam/system/controlDict | 44 ++++++++++ .../foam/system/decomposeParDict | 42 +++++++++ .../bcs/mass_flow_rate/foam/system/fvSchemes | 51 +++++++++++ .../bcs/mass_flow_rate/foam/system/fvSolution | 61 +++++++++++++ .../bcs/mass_flow_rate/gold/main_out.csv | 34 ++++++++ test/tests/bcs/mass_flow_rate/main.i | 48 +++++++++++ test/tests/bcs/mass_flow_rate/tests | 20 +++++ 18 files changed, 683 insertions(+), 3 deletions(-) create mode 100644 test/tests/bcs/mass_flow_rate/foam/0/T create mode 100644 test/tests/bcs/mass_flow_rate/foam/0/U create mode 100644 test/tests/bcs/mass_flow_rate/foam/0/p create mode 100644 test/tests/bcs/mass_flow_rate/foam/0/p_rgh create mode 100644 test/tests/bcs/mass_flow_rate/foam/0/rho create mode 100644 test/tests/bcs/mass_flow_rate/foam/constant/g create mode 100644 test/tests/bcs/mass_flow_rate/foam/constant/momentumTransport create mode 100644 test/tests/bcs/mass_flow_rate/foam/constant/physicalProperties create mode 100644 test/tests/bcs/mass_flow_rate/foam/system/blockMeshDict create mode 100644 test/tests/bcs/mass_flow_rate/foam/system/controlDict create mode 100644 test/tests/bcs/mass_flow_rate/foam/system/decomposeParDict create mode 100644 test/tests/bcs/mass_flow_rate/foam/system/fvSchemes create mode 100644 test/tests/bcs/mass_flow_rate/foam/system/fvSolution create mode 100644 test/tests/bcs/mass_flow_rate/gold/main_out.csv create mode 100644 test/tests/bcs/mass_flow_rate/main.i create mode 100644 test/tests/bcs/mass_flow_rate/tests diff --git a/Makefile b/Makefile index 3a792393..ad5757dc 100644 --- a/Makefile +++ b/Makefile @@ -46,6 +46,7 @@ RDG := no RICHARDS := no STOCHASTIC_TOOLS := no TENSOR_MECHANICS := no +THERMAL_HYDRAULICS := yes XFEM := no include $(MOOSE_DIR)/modules/modules.mk diff --git a/src/bcs/FoamMassFlowRateInletBC.C b/src/bcs/FoamMassFlowRateInletBC.C index 704f781b..3e3991f0 100644 --- a/src/bcs/FoamMassFlowRateInletBC.C +++ b/src/bcs/FoamMassFlowRateInletBC.C @@ -15,7 +15,7 @@ FoamMassFlowRateInletBC::validParams() params.remove("foam_variable"); params.addParam( - "foam_variable", "U", "Name of foam variable associated with velocity"); + "foam_variable", "T", "Name of foam variable associated with velocity"); params.addRequiredParam("postprocessor", "Postprocessors containing mass flow rate."); @@ -44,10 +44,10 @@ FoamMassFlowRateInletBC::imposeBoundaryCondition() auto & boundary_patch = foam_mesh.boundary()[subdomain]; auto & U_var = const_cast &>( - boundary_patch.lookupPatchField(_foam_variable)); + boundary_patch.lookupPatchField("U")); auto & rho = boundary_patch.lookupPatchField("rho"); - U_var = pp_value * boundary_patch.nf() / (rho * boundary_patch.magSf()); + U_var == pp_value * boundary_patch.nf() / (rho * boundary_patch.magSf()); } } diff --git a/test/tests/bcs/mass_flow_rate/foam/0/T b/test/tests/bcs/mass_flow_rate/foam/0/T new file mode 100644 index 00000000..f8312bb2 --- /dev/null +++ b/test/tests/bcs/mass_flow_rate/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 calculated; + value uniform 0.; + } + right + { + type calculated; + value uniform 0.; + } + top + { + type calculated; + value uniform 0.; + } + bottom + { + type calculated; + value uniform 0.; + } + back + { + type calculated; + value uniform 0.; + } + front + { + type calculated; + value uniform 0.; + } +} + + +// ************************************************************************* // diff --git a/test/tests/bcs/mass_flow_rate/foam/0/U b/test/tests/bcs/mass_flow_rate/foam/0/U new file mode 100644 index 00000000..d23654bb --- /dev/null +++ b/test/tests/bcs/mass_flow_rate/foam/0/U @@ -0,0 +1,31 @@ +/*--------------------------------*- 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 volVectorField; + location "0"; + object U; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [ 0 1 -1 0 0 0 0 ]; + +internalField uniform (2 -1 0); + +boundaryField +{ + + ".*" + { + type fixedValue; + value $internalField; + } +} + +// ************************************************************************* // diff --git a/test/tests/bcs/mass_flow_rate/foam/0/p b/test/tests/bcs/mass_flow_rate/foam/0/p new file mode 100644 index 00000000..0d00fc2f --- /dev/null +++ b/test/tests/bcs/mass_flow_rate/foam/0/p @@ -0,0 +1,30 @@ +/*--------------------------------*- 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 volScalarField; + location "0"; + object p; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [ 1 -1 -2 0 0 0 0 ]; + +internalField uniform 0; + +boundaryField +{ + ".*" + { + type calculated; + value $internalField; + } +} + +// ************************************************************************* // diff --git a/test/tests/bcs/mass_flow_rate/foam/0/p_rgh b/test/tests/bcs/mass_flow_rate/foam/0/p_rgh new file mode 100644 index 00000000..cfc89a8c --- /dev/null +++ b/test/tests/bcs/mass_flow_rate/foam/0/p_rgh @@ -0,0 +1,30 @@ +/*--------------------------------*- 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 volScalarField; + location "0"; + object p_rgh; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [ 1 -1 -2 0 0 0 0 ]; + +internalField uniform 0; + +boundaryField +{ + ".*" + { + type fixedValue; + value $internalField; + } +} + +// ************************************************************************* // diff --git a/test/tests/bcs/mass_flow_rate/foam/0/rho b/test/tests/bcs/mass_flow_rate/foam/0/rho new file mode 100644 index 00000000..d30a04dc --- /dev/null +++ b/test/tests/bcs/mass_flow_rate/foam/0/rho @@ -0,0 +1,56 @@ +/*--------------------------------*- 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 volScalarField; + location "0"; + object rho; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -3 0 0 0 0 0]; + +internalField uniform 1; + +boundaryField +{ + left + { + type calculated; + value uniform 1; + } + right + { + type calculated; + value uniform 1; + } + top + { + type calculated; + value uniform 1; + } + front + { + type calculated; + value uniform 1; + } + bottom + { + type calculated; + value uniform 1; + } + back + { + type calculated; + value uniform 1; + } +} + + +// ************************************************************************* // diff --git a/test/tests/bcs/mass_flow_rate/foam/constant/g b/test/tests/bcs/mass_flow_rate/foam/constant/g new file mode 100644 index 00000000..8af96f3a --- /dev/null +++ b/test/tests/bcs/mass_flow_rate/foam/constant/g @@ -0,0 +1,21 @@ +/*--------------------------------*- 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 uniformDimensionedVectorField; + location "constant"; + object g; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 -2 0 0 0 0]; +value (0 0 0); + + +// ************************************************************************* // diff --git a/test/tests/bcs/mass_flow_rate/foam/constant/momentumTransport b/test/tests/bcs/mass_flow_rate/foam/constant/momentumTransport new file mode 100644 index 00000000..0416f1a9 --- /dev/null +++ b/test/tests/bcs/mass_flow_rate/foam/constant/momentumTransport @@ -0,0 +1,18 @@ +/*--------------------------------*- 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 RASProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +simulationType laminar; + +// ************************************************************************* // diff --git a/test/tests/bcs/mass_flow_rate/foam/constant/physicalProperties b/test/tests/bcs/mass_flow_rate/foam/constant/physicalProperties new file mode 100644 index 00000000..20dafc61 --- /dev/null +++ b/test/tests/bcs/mass_flow_rate/foam/constant/physicalProperties @@ -0,0 +1,52 @@ +/*--------------------------------*- 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 heRhoThermo; + mixture pureMixture; + transport const; + thermo hConst; + equationOfState rhoConst; + specie specie; + energy sensibleEnthalpy; +} + +mixture +{ + specie + { + molWeight 1; + } + thermodynamics + { + Cp 1; // Specific heat capacity [J/(kg·K)] + Hf 1; // Heat of formation [J/kg] + Tref 0; + } + transport + { + kappa 1; // Thermal conductivity [W/(m·K)] + mu 1.; + } + equationOfState + { + rho 1; // Density [kg/m^3] + } +} + + +// ************************************************************************* // diff --git a/test/tests/bcs/mass_flow_rate/foam/system/blockMeshDict b/test/tests/bcs/mass_flow_rate/foam/system/blockMeshDict new file mode 100644 index 00000000..face9ea6 --- /dev/null +++ b/test/tests/bcs/mass_flow_rate/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/bcs/mass_flow_rate/foam/system/controlDict b/test/tests/bcs/mass_flow_rate/foam/system/controlDict new file mode 100644 index 00000000..4e2baf59 --- /dev/null +++ b/test/tests/bcs/mass_flow_rate/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 postprocessorTestSolver; + +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/bcs/mass_flow_rate/foam/system/decomposeParDict b/test/tests/bcs/mass_flow_rate/foam/system/decomposeParDict new file mode 100644 index 00000000..0204a6b9 --- /dev/null +++ b/test/tests/bcs/mass_flow_rate/foam/system/decomposeParDict @@ -0,0 +1,42 @@ +/*--------------------------------*- 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 2; + +method simple; + +simpleCoeffs +{ + n (2 1 1); +} + +hierarchicalCoeffs +{ + n (1 1 1); + order xyz; +} + +manualCoeffs +{ + dataFile ""; +} + +distributed no; + +roots ( ); + + +// ************************************************************************* // diff --git a/test/tests/bcs/mass_flow_rate/foam/system/fvSchemes b/test/tests/bcs/mass_flow_rate/foam/system/fvSchemes new file mode 100644 index 00000000..787f3b83 --- /dev/null +++ b/test/tests/bcs/mass_flow_rate/foam/system/fvSchemes @@ -0,0 +1,51 @@ +/*--------------------------------*- 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 none; + + div(phi,U) Gauss linear; + div(phi,K) Gauss linear; + div(phi,h) Gauss linear; + div(((rho*nuEff)*dev2(T(grad(U))))) Gauss linear; +} + +laplacianSchemes +{ + default Gauss linear corrected; +} + +interpolationSchemes +{ + default linear; +} + +snGradSchemes +{ + default corrected; +} + +// ************************************************************************* // diff --git a/test/tests/bcs/mass_flow_rate/foam/system/fvSolution b/test/tests/bcs/mass_flow_rate/foam/system/fvSolution new file mode 100644 index 00000000..61143b21 --- /dev/null +++ b/test/tests/bcs/mass_flow_rate/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; + } + + + "(U|h|p_rgh)" + { + solver PBiCGStab; + preconditioner DILU; + tolerance 1e-8; + relTol 1e-8; + } + + "(U|h|p_rgh)Final" + { + $U; + tolerance 1e-8; + relTol 1e-8; + } +} + +PIMPLE +{ + momentumPredictor yes; + pRefCell 0; + pRefValue 0; +} + +relaxationFactors +{ + equations + { + h 1; + U 1; + } +} + +// ************************************************************************* // diff --git a/test/tests/bcs/mass_flow_rate/gold/main_out.csv b/test/tests/bcs/mass_flow_rate/gold/main_out.csv new file mode 100644 index 00000000..6184703c --- /dev/null +++ b/test/tests/bcs/mass_flow_rate/gold/main_out.csv @@ -0,0 +1,34 @@ +time,m_dot,pp +0,0,0 +0.01,0.01,0.01 +0.02,0.02,0.02 +0.03,0.03,0.03 +0.04,0.04,0.04 +0.05,0.05,0.05 +0.06,0.06,0.06 +0.07,0.07,0.07 +0.08,0.08,0.08 +0.09,0.09,0.09 +0.1,0.1,0.1 +0.11,0.11,0.11 +0.12,0.12,0.12 +0.13,0.13,0.13 +0.14,0.14,0.14 +0.15,0.15,0.15 +0.16,0.16,0.16 +0.17,0.17,0.17 +0.18,0.18,0.18 +0.19,0.19,0.19 +0.2,0.2,0.2 +0.21,0.21,0.21 +0.22,0.22,0.22 +0.23,0.23,0.23 +0.24,0.24,0.24 +0.25,0.25,0.25 +0.26,0.26,0.26 +0.27,0.27,0.27 +0.28,0.28,0.28 +0.29,0.29,0.29 +0.3,0.3,0.3 +0.31,0.31,0.31 +0.32,0.32,0.32 diff --git a/test/tests/bcs/mass_flow_rate/main.i b/test/tests/bcs/mass_flow_rate/main.i new file mode 100644 index 00000000..5cdc78c2 --- /dev/null +++ b/test/tests/bcs/mass_flow_rate/main.i @@ -0,0 +1,48 @@ +[Mesh] + type = FoamMesh + case = 'foam' + foam_patch = 'left right bottom top back front' +[] + +[FoamBCs] + [temp1] + type=FoamMassFlowRateInletBC + boundary = 'left' # test boundary restrictions + postprocessor = pp + [] +[] + +[Postprocessors] + [pp] + type = ParsedPostprocessor + expression = 't' + use_t = true + execute_on = TIMESTEP_BEGIN + [] + [m_dot] + type = FoamSideAdvectiveFluxIntegral + block = left + foam_scalar = rho + [] +[] + + +[Problem] + type = FoamProblem + # Take the boundary temperature from OpenFOAM and set it on the MOOSE mesh. +[] + +[Executioner] + type = Transient + end_time = 0.32 + [TimeSteppers] + [foam] + type = FoamControlledTimeStepper + [] + [] +[] + +[Outputs] + exodus = true + csv=true +[] diff --git a/test/tests/bcs/mass_flow_rate/tests b/test/tests/bcs/mass_flow_rate/tests new file mode 100644 index 00000000..91f63a7a --- /dev/null +++ b/test/tests/bcs/mass_flow_rate/tests @@ -0,0 +1,20 @@ +[Tests] + [mass_flow_rate] + [setup] + type = RunCommand + command = 'bash -c "foamCleanCase -case foam && blockMesh -case foam"' + [] + [run] + type = CSVDiff + input = main.i + prereq = mass_flow_rate/setup + csvdiff = main_out.csv + allow_warnings = true + [] + [verify] + type = PythonUnitTest + input = test.py + prereq = mass_flow_rate/run + [] + [] +[] From fe6e08e2427dc70bf6a2180d208cc59db7182962 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Tue, 14 Oct 2025 17:40:37 +0100 Subject: [PATCH 06/52] Fix bugs in mass flow rate inlet implementation --- src/bcs/FoamMassFlowRateInletBC.C | 8 ++++++-- .../bcs/mass_flow_rate/foam/constant/physicalProperties | 2 +- test/tests/bcs/mass_flow_rate/foam/system/blockMeshDict | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/bcs/FoamMassFlowRateInletBC.C b/src/bcs/FoamMassFlowRateInletBC.C index 3e3991f0..097de7a8 100644 --- a/src/bcs/FoamMassFlowRateInletBC.C +++ b/src/bcs/FoamMassFlowRateInletBC.C @@ -1,8 +1,11 @@ +#include "DimensionedField.H" #include "FoamBCBase.h" #include "FoamMassFlowRateInletBC.h" #include "InputParameters.h" #include "MooseTypes.h" +#include "PstreamReduceOps.H" #include "Registry.h" +#include registerMooseObject("hippoApp", FoamMassFlowRateInletBC); @@ -46,12 +49,13 @@ FoamMassFlowRateInletBC::imposeBoundaryCondition() auto & U_var = const_cast &>( boundary_patch.lookupPatchField("U")); auto & rho = boundary_patch.lookupPatchField("rho"); - - U_var == pp_value * boundary_patch.nf() / (rho * boundary_patch.magSf()); + Real area = Foam::returnReduce(Foam::sum(boundary_patch.magSf()), Foam::sumOp()); + U_var == -pp_value * boundary_patch.nf() / (rho * area); } } void FoamMassFlowRateInletBC::initialSetup() { + _foam_variable = ""; } diff --git a/test/tests/bcs/mass_flow_rate/foam/constant/physicalProperties b/test/tests/bcs/mass_flow_rate/foam/constant/physicalProperties index 20dafc61..8a4c6a29 100644 --- a/test/tests/bcs/mass_flow_rate/foam/constant/physicalProperties +++ b/test/tests/bcs/mass_flow_rate/foam/constant/physicalProperties @@ -44,7 +44,7 @@ mixture } equationOfState { - rho 1; // Density [kg/m^3] + rho 0.5; // Density [kg/m^3] } } diff --git a/test/tests/bcs/mass_flow_rate/foam/system/blockMeshDict b/test/tests/bcs/mass_flow_rate/foam/system/blockMeshDict index face9ea6..1adab343 100644 --- a/test/tests/bcs/mass_flow_rate/foam/system/blockMeshDict +++ b/test/tests/bcs/mass_flow_rate/foam/system/blockMeshDict @@ -21,7 +21,7 @@ vertices blocks ( - hex (0 1 2 3 4 5 6 7) (50 1 1) simpleGrading (25 1 1) + hex (0 1 2 3 4 5 6 7) (50 2 2) simpleGrading (25 1 1) ); boundary From 03b801c11252c44852b5f58608dc856a3a49b492 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Thu, 16 Oct 2025 10:40:31 +0100 Subject: [PATCH 07/52] Remove unnecessary headers --- src/bcs/FoamMassFlowRateInletBC.C | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/bcs/FoamMassFlowRateInletBC.C b/src/bcs/FoamMassFlowRateInletBC.C index 097de7a8..c62d3fd3 100644 --- a/src/bcs/FoamMassFlowRateInletBC.C +++ b/src/bcs/FoamMassFlowRateInletBC.C @@ -1,11 +1,9 @@ -#include "DimensionedField.H" #include "FoamBCBase.h" #include "FoamMassFlowRateInletBC.h" #include "InputParameters.h" #include "MooseTypes.h" #include "PstreamReduceOps.H" #include "Registry.h" -#include registerMooseObject("hippoApp", FoamMassFlowRateInletBC); From 0747b18d98ee369e496659b9faab0834e7ef7a00 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Sat, 1 Nov 2025 15:40:06 +0000 Subject: [PATCH 08/52] Add initial implementation of mapped inlet mass flow rate boundary conditions --- include/bcs/FoamMassFlowRateMappedInletBC.h | 28 ++++ src/bcs/FoamMassFlowRateMappedInletBC.C | 174 ++++++++++++++++++++ 2 files changed, 202 insertions(+) create mode 100644 include/bcs/FoamMassFlowRateMappedInletBC.h create mode 100644 src/bcs/FoamMassFlowRateMappedInletBC.C diff --git a/include/bcs/FoamMassFlowRateMappedInletBC.h b/include/bcs/FoamMassFlowRateMappedInletBC.h new file mode 100644 index 00000000..17878dde --- /dev/null +++ b/include/bcs/FoamMassFlowRateMappedInletBC.h @@ -0,0 +1,28 @@ +#include "FoamBCBase.h" +#include + +class FoamMassFlowRateMappedInletBC : public FoamBCBase, public PostprocessorInterface +{ +public: + static InputParameters validParams(); + + FoamMassFlowRateMappedInletBC(const InputParameters & params); + + virtual void imposeBoundaryCondition() override; + + virtual void initialSetup() override; + +protected: + PostprocessorName _pp_name; + + std::vector _offset; + + std::map> _send_map; + + std::map> _recv_map; + + void createPatchProcMap(); + + template + Foam::Field getMappedArray(const Foam::word & name); +}; diff --git a/src/bcs/FoamMassFlowRateMappedInletBC.C b/src/bcs/FoamMassFlowRateMappedInletBC.C new file mode 100644 index 00000000..3be8ab03 --- /dev/null +++ b/src/bcs/FoamMassFlowRateMappedInletBC.C @@ -0,0 +1,174 @@ +#include "FoamBCBase.h" +#include "FoamMassFlowRateMappedInletBC.h" +#include "InputParameters.h" +#include "MooseTypes.h" +#include "Pstream.H" +#include "PstreamReduceOps.H" +#include "Registry.h" + +#include "ops.H" +#include "mpi.h" +#include "UPstream.H" +#include "vectorField.H" +#include "volFieldsFwd.H" + +registerMooseObject("hippoApp", FoamMassFlowRateMappedInletBC); + +void +FoamMassFlowRateMappedInletBC::createPatchProcMap() +{ + // Use OpenFOAM's PStream to send local points to all processes + // A little inefficient but this is only done on initialisation + // A bounding box approach could be more efficient if there is any + // changes that require repartitioning + auto & foam_mesh = _mesh->fvMesh(); + auto & boundary = foam_mesh.boundary()[_boundary[0]]; + auto face_centres = boundary.Cf(); + + Foam::PstreamBuffers send_points(Foam::UPstream::commsTypes::nonBlocking); + for (int i = 0; i < Foam::Pstream::nProcs(); ++i) + { + Foam::UOPstream send(i, send_points); + send << face_centres; + } + send_points.finishedSends(true); + + std::vector size_requests(Foam::Pstream::nProcs()); + std::vector data_requests(Foam::Pstream::nProcs()); + std::vector sizes; + for (int i = 0; i < Foam::Pstream::nProcs(); ++i) + { + // Recieve from each process and check required point is present + Foam::vectorField field; + Foam::PstreamBuffers recv_points(Foam::UPstream::commsTypes::blocking); + + Foam::UIPstream recieve(i, recv_points); + recieve >> field; + auto & vec = _send_map[i]; + for (int j = 0; j < field.size(); ++j) + { + auto index = foam_mesh.findCell(field[j]); + if (index >= 0) + { + vec.push_back(j); // assign to send map required indices + } + } + + // Let original processes know which points will come from each rank + auto size = static_cast(vec.size()); + MPI_Isend(&size, 1, MPI_INT, i, 0, MPI_COMM_WORLD, &size_requests[i]); + MPI_Isend(vec.data(), vec.size(), MPI_INT, i, 1, MPI_COMM_WORLD, &data_requests[i]); + + MPI_Irecv(sizes.data(), 1, MPI_INT, i, 0, MPI_COMM_WORLD, &size_requests[i]); + } + + MPI_Waitall(size_requests.size(), size_requests.data(), MPI_STATUSES_IGNORE); + + for (int i = 0; i < Foam::Pstream::nProcs(); ++i) + { + std::vector recv_indices(sizes[i]); + MPI_Recv(recv_indices.data(), sizes[i], MPI_INT, i, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + for (auto index : recv_indices) + _recv_map[i].push_back(index); + } +} + +InputParameters +FoamMassFlowRateMappedInletBC::validParams() +{ + auto params = FoamBCBase::validParams(); + params.remove("v"); + params.remove("initial_condition"); + params.remove("foam_variable"); + + params.addParam( + "foam_variable", "T", "Name of foam variable associated with velocity"); + + params.addRequiredParam>("mapped_inlet_offset", + "A vector indicating the location of recycling plane"); + params.addRequiredParam("mass_flow_pp", + "Postprocessors containing mass flow rate."); + + return params; +} + +FoamMassFlowRateMappedInletBC::FoamMassFlowRateMappedInletBC(const InputParameters & params) + : FoamBCBase(params), + PostprocessorInterface(this), + _pp_name(params.get("mass_flow_pp")), + _offset(params.get>("mapped_inlet_offset")), + _send_map(), + _recv_map() +{ + if (_boundary.size() > 1) + mooseError("There can only be one boundary using this method"); + + createPatchProcMap(); +} + +template +Foam::Field +FoamMassFlowRateMappedInletBC::getMappedArray(const Foam::word & name) +{ + auto & foam_mesh = _mesh->fvMesh(); + auto & boundary_patch = foam_mesh.boundary()[_boundary[0]]; + + Foam::PstreamBuffers sendBuf(Foam::UPstream::commsTypes::nonBlocking); + auto & U_var = const_cast &>( + boundary_patch.lookupPatchField, double>("U")); + + auto & U_internal = foam_mesh.lookupObject>("U"); + for (int i = 0; i < Foam::Pstream::nProcs(); ++i) + { + Foam::Field points(_send_map[i].size()); + for (int j = 0; j < _send_map[i].size(); ++j) + points[j] = U_internal[_send_map[i][j]]; + + Foam::UOPstream send(i, sendBuf); + send << points; + } + sendBuf.finishedSends(true); + + Foam::Field boundaryData(boundary_patch.size()); + Foam::PstreamBuffers recvBuf(Foam::UPstream::commsTypes::blocking); + for (int i = 0; i < Foam::Pstream::nProcs(); ++i) + { + Foam::UIPstream recv(i, recvBuf); + Foam::Field recvData; + recv >> recvData; + for (int j = 0; _recv_map[i].size(); ++j) + { + boundaryData[_recv_map[i].at(j)] = recvData[j]; + } + } + + return boundaryData; +} + +void +FoamMassFlowRateMappedInletBC::imposeBoundaryCondition() +{ + auto & foam_mesh = _mesh->fvMesh(); + auto & boundary_patch = foam_mesh.boundary()[_boundary[0]]; + + // should we mapping rho U or just U? Fo now U but we can change it + auto && U_map = getMappedArray("U"); + auto pp_value = getPostprocessorValueByName(_pp_name); + auto & rho = boundary_patch.lookupPatchField("rho"); + auto & Af = boundary_patch.magSf(); + auto && Nf = boundary_patch.nf(); + auto mdot_f = rho * (U_map & Nf) * Af; + + Real m_dot = Foam::returnReduce(Foam::sum(mdot_f), Foam::sumOp()); + + auto & U_var = const_cast &>( + boundary_patch.lookupPatchField("U")); + + U_var == U_map * pp_value / m_dot; +} + +void +FoamMassFlowRateMappedInletBC::initialSetup() +{ + _foam_variable = ""; +} From 660baf80f01ca82caa3ff6cde811f8481d496e8e Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Sat, 1 Nov 2025 16:36:13 +0000 Subject: [PATCH 09/52] Add initial implementation of the mapped inlet test solver --- test/OpenFOAM/foam_modules.mk | 2 + .../modules/mappedInletTestSolver/Make/files | 3 + .../mappedInletTestSolver/Make/options | 20 ++ .../mappedInletTestSolver.C | 177 ++++++++++++++++++ .../mappedInletTestSolver.H | 152 +++++++++++++++ 5 files changed, 354 insertions(+) create mode 100644 test/OpenFOAM/modules/mappedInletTestSolver/Make/files create mode 100644 test/OpenFOAM/modules/mappedInletTestSolver/Make/options create mode 100644 test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.C create mode 100644 test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.H diff --git a/test/OpenFOAM/foam_modules.mk b/test/OpenFOAM/foam_modules.mk index 80bf70a8..88d13625 100644 --- a/test/OpenFOAM/foam_modules.mk +++ b/test/OpenFOAM/foam_modules.mk @@ -12,3 +12,5 @@ build_foam_tests: @$(MAKE) -s -j $(MOOSE_JOBS) test/OpenFOAM/modules/laplacianTestSolver/ @$(MAKE) -s -j $(MOOSE_JOBS) test/OpenFOAM/modules/odeTestSolver/ @$(MAKE) -s -j $(MOOSE_JOBS) test/OpenFOAM/modules/postprocessorTestSolver/ + @$(MAKE) -s -j $(MOOSE_JOBS) test/OpenFOAM/modules/mappedInletTestSolver/ + diff --git a/test/OpenFOAM/modules/mappedInletTestSolver/Make/files b/test/OpenFOAM/modules/mappedInletTestSolver/Make/files new file mode 100644 index 00000000..59e2e3c9 --- /dev/null +++ b/test/OpenFOAM/modules/mappedInletTestSolver/Make/files @@ -0,0 +1,3 @@ +SOURCE += mappedInletTestSolver.C + +LIB = $(FOAM_USER_LIBBIN)/libbmappedInletTestSolver diff --git a/test/OpenFOAM/modules/mappedInletTestSolver/Make/options b/test/OpenFOAM/modules/mappedInletTestSolver/Make/options new file mode 100644 index 00000000..cc845ca8 --- /dev/null +++ b/test/OpenFOAM/modules/mappedInletTestSolver/Make/options @@ -0,0 +1,20 @@ +EXE_INC = \ + -I$(LIB_SRC)/physicalProperties/lnInclude \ + -I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \ + -I$(LIB_SRC)/thermophysicalModels/solidThermo/lnInclude \ + -I$(LIB_SRC)/ThermophysicalTransportModels/thermophysicalTransportModel/lnInclude \ + -I$(LIB_SRC)/ThermophysicalTransportModels/solid/lnInclude \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude \ + -I$(LIB_SRC)/sampling/lnInclude + +LIB_LIBS = \ + -lsolidThermo \ + -lsolidThermophysicalTransportModels \ + -lcoupledThermophysicalTransportModels \ + -lspecie \ + -lfiniteVolume \ + -lmeshTools \ + -lsampling \ + -lfvModels \ + -lfvConstraints diff --git a/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.C b/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.C new file mode 100644 index 00000000..9d946789 --- /dev/null +++ b/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.C @@ -0,0 +1,177 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | Website: https://openfoam.org + \\ / A nd | Copyright (C) 2022-2024 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +\*---------------------------------------------------------------------------*/ + +#include "dimensionSets.H" +#include "fvMesh.H" +#include "mappedInletTestSolver.H" +#include "fvMeshMover.H" +#include "addToRunTimeSelectionTable.H" +#include "fvConstraints.H" +#include "fvmLaplacian.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace solvers +{ +defineTypeNameAndDebug(mappedInletTestSolver, 0); +addToRunTimeSelectionTable(solver, mappedInletTestSolver, fvMesh); +} +} + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * // + +bool +Foam::solvers::mappedInletTestSolver::dependenciesModified() const +{ + return runTime.controlDict().modified(); +} + +bool +Foam::solvers::mappedInletTestSolver::read() +{ + solver::read(); + + maxDeltaT_ = runTime.controlDict().found("maxDeltaT") + ? runTime.controlDict().lookup("maxDeltaT", runTime.userUnits()) + : vGreat; + + return true; +} + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // +// Solver based on solid.C module +Foam::solvers::mappedInletTestSolver::mappedInletTestSolver(fvMesh & mesh, + autoPtr thermoPtr) + : solver(mesh), + + thermoPtr_(thermoPtr), + thermo_(thermoPtr_()), + + T_(IOobject("T", mesh.time().name(), mesh, IOobject::NO_READ, IOobject::AUTO_WRITE), mesh), + + U_(IOobject("U", mesh.time().name(), mesh, IOobject::NO_READ, IOobject::AUTO_WRITE), mesh), + + thermophysicalTransport(solidThermophysicalTransportModel::New(thermo_)), + thermo(thermo_), + T(T_), + U(U_) +{ + thermo.validate("solid", "h", "e"); +} + +Foam::solvers::mappedInletTestSolver::mappedInletTestSolver(fvMesh & mesh) + : mappedInletTestSolver(mesh, solidThermo::New(mesh)) +{ + // Read the controls + read(); +} + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::solvers::mappedInletTestSolver::~mappedInletTestSolver() {} + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +Foam::scalar +Foam::solvers::mappedInletTestSolver::maxDeltaT() const +{ + return min(fvModels().maxDeltaT(), maxDeltaT_); +} + +void +Foam::solvers::mappedInletTestSolver::preSolve() +{ + fvModels().preUpdateMesh(); + + // Update the mesh for topology change, mesh to mesh mapping + mesh_.update(); +} + +void +Foam::solvers::mappedInletTestSolver::moveMesh() +{ + if (pimple.firstIter() || pimple.moveMeshOuterCorrectors()) + { + if (!mesh_.mover().solidBody()) + { + FatalErrorInFunction << "Region " << name() << " of type " << type() + << " does not support non-solid body mesh motion" << exit(FatalError); + } + + mesh_.move(); + } +} + +void +Foam::solvers::mappedInletTestSolver::motionCorrector() +{ +} + +void +Foam::solvers::mappedInletTestSolver::prePredictor() +{ +} + +void +Foam::solvers::mappedInletTestSolver::momentumPredictor() +{ + scalar rank = Pstream::myProcNo(); + vectorField & U_int = U_.primitiveFieldRef(); + vector data{rank, 2. * rank, 3 * rank}; + + U_int = vector{rank, 2. * rank, 3 * rank}; +} + +void +Foam::solvers::mappedInletTestSolver::thermophysicalPredictor() +{ + volScalarField & e = thermo.he(); + int rank = Pstream::myProcNo(); + + e == 4. * static_cast(rank); + + thermo_.correct(); +} + +void +Foam::solvers::mappedInletTestSolver::pressureCorrector() +{ +} + +void +Foam::solvers::mappedInletTestSolver::postCorrector() +{ +} + +void +Foam::solvers::mappedInletTestSolver::postSolve() +{ +} + +// ************************************************************************* // diff --git a/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.H b/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.H new file mode 100644 index 00000000..24705868 --- /dev/null +++ b/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.H @@ -0,0 +1,152 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | Website: https://openfoam.org + \\ / A nd | Copyright (C) 2022-2023 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +Class + Foam::solvers::mappedInletTestSolver + +Description + Solver module for to test mapped inlet implementation method + +SourceFiles + mappedInletTestSolver.C + +\*---------------------------------------------------------------------------*/ + +#pragma once + +#include "solver.H" +#include "solidThermophysicalTransportModel.H" +#include "volFieldsFwd.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace solvers +{ + +/*---------------------------------------------------------------------------*\ + Class mappedInletTestSolver Declaration +\*---------------------------------------------------------------------------*/ + +class mappedInletTestSolver : public solver +{ + +protected: + // Control parameters + scalar maxDeltaT_; + + // Thermophysical properties + autoPtr thermoPtr_; + + solidThermo & thermo_; + + volScalarField T_; + + volVectorField U_; + + autoPtr thermophysicalTransport; + + // Protected Member Functions + + //- Return true if the solver's dependencies have been modified + virtual bool dependenciesModified() const; + + //- Read controls + virtual bool read(); + +public: + // Public Data + // reference to thermophysical properties + solidThermo & thermo; + + //- Reference to the temperature field + const volScalarField & T; + + //- Reference velocity field + const volVectorField & U; + + //- Runtime type information + TypeName("mappedInletTestSolver"); + + // Constructors + + //- Construct from region mesh + mappedInletTestSolver(fvMesh & mesh, autoPtr thermoPtr); + + mappedInletTestSolver(fvMesh & mesh); + + //- Disallow default bitwise copy construction + mappedInletTestSolver(const mappedInletTestSolver &) = delete; + + //- Destructor + virtual ~mappedInletTestSolver(); + + // Member Functions + + //- Return the current maximum time-step for stable solution + virtual scalar maxDeltaT() const; + + //- Called at the start of the time-step, before the PIMPLE loop + virtual void preSolve(); + + //- Called at the start of the PIMPLE loop to move the mesh + virtual void moveMesh(); + + //- Corrections that follow mesh motion + virtual void motionCorrector(); + + //- Called at the beginning of the PIMPLE loop + virtual void prePredictor(); + + //- Construct and optionally solve the momentum equation + virtual void momentumPredictor(); + + //- Construct and solve the energy equation, + // convert to temperature + // and update thermophysical and transport properties + virtual void thermophysicalPredictor(); + + //- Construct and solve the pressure equation in the PISO loop + virtual void pressureCorrector(); + + //- Correct the thermophysical transport modelling + virtual void postCorrector(); + + //- Called after the PIMPLE loop at the end of the time-step + virtual void postSolve(); + + // Member Operators + + //- Disallow default bitwise assignment + void operator=(const mappedInletTestSolver &) = delete; +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace solvers +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// ************************************************************************* // From 55ab1e32edd166e07b7911b6baffd891fa3cebce Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Mon, 3 Nov 2025 13:49:15 +0000 Subject: [PATCH 10/52] Simplify mapped inlet test solver --- .../modules/mappedInletTestSolver/Make/files | 2 +- .../mappedInletTestSolver/mappedInletTestSolver.C | 15 ++++++--------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/test/OpenFOAM/modules/mappedInletTestSolver/Make/files b/test/OpenFOAM/modules/mappedInletTestSolver/Make/files index 59e2e3c9..0f5991d4 100644 --- a/test/OpenFOAM/modules/mappedInletTestSolver/Make/files +++ b/test/OpenFOAM/modules/mappedInletTestSolver/Make/files @@ -1,3 +1,3 @@ SOURCE += mappedInletTestSolver.C -LIB = $(FOAM_USER_LIBBIN)/libbmappedInletTestSolver +LIB = $(FOAM_USER_LIBBIN)/libmappedInletTestSolver diff --git a/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.C b/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.C index 9d946789..d0731116 100644 --- a/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.C +++ b/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.C @@ -24,6 +24,8 @@ License \*---------------------------------------------------------------------------*/ #include "dimensionSets.H" +#include "dimensionedScalar.H" +#include "dimensionedVector.H" #include "fvMesh.H" #include "mappedInletTestSolver.H" #include "fvMeshMover.H" @@ -141,21 +143,16 @@ Foam::solvers::mappedInletTestSolver::prePredictor() void Foam::solvers::mappedInletTestSolver::momentumPredictor() { - scalar rank = Pstream::myProcNo(); - vectorField & U_int = U_.primitiveFieldRef(); - vector data{rank, 2. * rank, 3 * rank}; - - U_int = vector{rank, 2. * rank, 3 * rank}; + auto rank_time = Pstream::myProcNo() * mesh.time().userTimeValue(); + U_.primitiveFieldRef() = vector{rank_time + 1., 2. * rank_time + 1., 3 * rank_time + 1.}; } void Foam::solvers::mappedInletTestSolver::thermophysicalPredictor() { volScalarField & e = thermo.he(); - int rank = Pstream::myProcNo(); - - e == 4. * static_cast(rank); - + auto rank_time = Pstream::myProcNo() * mesh.time().userTimeValue(); + e.primitiveFieldRef() = 4. * rank_time + 1.; thermo_.correct(); } From c31a3dd311b8b5260ebee05e958c514052f4088c Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Mon, 3 Nov 2025 13:50:13 +0000 Subject: [PATCH 11/52] Fix basic mapped inlet implementation --- include/bcs/FoamMassFlowRateMappedInletBC.h | 2 +- src/bcs/FoamMassFlowRateMappedInletBC.C | 55 +++++++++++---------- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/include/bcs/FoamMassFlowRateMappedInletBC.h b/include/bcs/FoamMassFlowRateMappedInletBC.h index 17878dde..6e18aa6b 100644 --- a/include/bcs/FoamMassFlowRateMappedInletBC.h +++ b/include/bcs/FoamMassFlowRateMappedInletBC.h @@ -15,7 +15,7 @@ class FoamMassFlowRateMappedInletBC : public FoamBCBase, public PostprocessorInt protected: PostprocessorName _pp_name; - std::vector _offset; + Foam::vector _offset; std::map> _send_map; diff --git a/src/bcs/FoamMassFlowRateMappedInletBC.C b/src/bcs/FoamMassFlowRateMappedInletBC.C index 3be8ab03..4b8dd4f2 100644 --- a/src/bcs/FoamMassFlowRateMappedInletBC.C +++ b/src/bcs/FoamMassFlowRateMappedInletBC.C @@ -35,31 +35,32 @@ FoamMassFlowRateMappedInletBC::createPatchProcMap() std::vector size_requests(Foam::Pstream::nProcs()); std::vector data_requests(Foam::Pstream::nProcs()); - std::vector sizes; + std::vector sizes(Foam::Pstream::nProcs()); for (int i = 0; i < Foam::Pstream::nProcs(); ++i) { // Recieve from each process and check required point is present Foam::vectorField field; - Foam::PstreamBuffers recv_points(Foam::UPstream::commsTypes::blocking); - - Foam::UIPstream recieve(i, recv_points); + Foam::UIPstream recieve(i, send_points); recieve >> field; auto & vec = _send_map[i]; + std::vector recv_indices; for (int j = 0; j < field.size(); ++j) { - auto index = foam_mesh.findCell(field[j]); + auto index = foam_mesh.findCell(field[j] + _offset); if (index >= 0) { - vec.push_back(j); // assign to send map required indices + vec.push_back(index); // assign to send map required indices + recv_indices.push_back(j); } } // Let original processes know which points will come from each rank auto size = static_cast(vec.size()); MPI_Isend(&size, 1, MPI_INT, i, 0, MPI_COMM_WORLD, &size_requests[i]); - MPI_Isend(vec.data(), vec.size(), MPI_INT, i, 1, MPI_COMM_WORLD, &data_requests[i]); + MPI_Isend( + recv_indices.data(), recv_indices.size(), MPI_INT, i, 1, MPI_COMM_WORLD, &data_requests[i]); - MPI_Irecv(sizes.data(), 1, MPI_INT, i, 0, MPI_COMM_WORLD, &size_requests[i]); + MPI_Irecv(&sizes[i], 1, MPI_INT, i, 0, MPI_COMM_WORLD, &size_requests[i]); } MPI_Waitall(size_requests.size(), size_requests.data(), MPI_STATUSES_IGNORE); @@ -67,7 +68,7 @@ FoamMassFlowRateMappedInletBC::createPatchProcMap() for (int i = 0; i < Foam::Pstream::nProcs(); ++i) { std::vector recv_indices(sizes[i]); - MPI_Recv(recv_indices.data(), sizes[i], MPI_INT, i, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(recv_indices.data(), sizes[i], MPI_INT, i, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); for (auto index : recv_indices) _recv_map[i].push_back(index); } @@ -84,7 +85,7 @@ FoamMassFlowRateMappedInletBC::validParams() params.addParam( "foam_variable", "T", "Name of foam variable associated with velocity"); - params.addRequiredParam>("mapped_inlet_offset", + params.addRequiredParam>("translation_vector", "A vector indicating the location of recycling plane"); params.addRequiredParam("mass_flow_pp", "Postprocessors containing mass flow rate."); @@ -96,13 +97,17 @@ FoamMassFlowRateMappedInletBC::FoamMassFlowRateMappedInletBC(const InputParamete : FoamBCBase(params), PostprocessorInterface(this), _pp_name(params.get("mass_flow_pp")), - _offset(params.get>("mapped_inlet_offset")), + _offset(), _send_map(), _recv_map() { if (_boundary.size() > 1) mooseError("There can only be one boundary using this method"); + auto param_offset = params.get>("translation_vector"); + assert(param_offset.size() == 3); + + _offset = {param_offset[0], param_offset[1], param_offset[2]}; createPatchProcMap(); } @@ -114,15 +119,12 @@ FoamMassFlowRateMappedInletBC::getMappedArray(const Foam::word & name) auto & boundary_patch = foam_mesh.boundary()[_boundary[0]]; Foam::PstreamBuffers sendBuf(Foam::UPstream::commsTypes::nonBlocking); - auto & U_var = const_cast &>( - boundary_patch.lookupPatchField, double>("U")); - - auto & U_internal = foam_mesh.lookupObject>("U"); + auto & var = foam_mesh.lookupObject>(name); for (int i = 0; i < Foam::Pstream::nProcs(); ++i) { Foam::Field points(_send_map[i].size()); - for (int j = 0; j < _send_map[i].size(); ++j) - points[j] = U_internal[_send_map[i][j]]; + for (auto j = 0lu; j < _send_map[i].size(); ++j) + points[j] = var[_send_map[i][j]]; Foam::UOPstream send(i, sendBuf); send << points; @@ -130,15 +132,14 @@ FoamMassFlowRateMappedInletBC::getMappedArray(const Foam::word & name) sendBuf.finishedSends(true); Foam::Field boundaryData(boundary_patch.size()); - Foam::PstreamBuffers recvBuf(Foam::UPstream::commsTypes::blocking); for (int i = 0; i < Foam::Pstream::nProcs(); ++i) { - Foam::UIPstream recv(i, recvBuf); + Foam::UIPstream recv(i, sendBuf); Foam::Field recvData; recv >> recvData; - for (int j = 0; _recv_map[i].size(); ++j) + for (auto j = 0lu; j < _recv_map[i].size(); ++j) { - boundaryData[_recv_map[i].at(j)] = recvData[j]; + boundaryData[_recv_map[i][j]] = recvData[j]; } } @@ -152,19 +153,19 @@ FoamMassFlowRateMappedInletBC::imposeBoundaryCondition() auto & boundary_patch = foam_mesh.boundary()[_boundary[0]]; // should we mapping rho U or just U? Fo now U but we can change it - auto && U_map = getMappedArray("U"); auto pp_value = getPostprocessorValueByName(_pp_name); + + auto && U_map = getMappedArray("U"); auto & rho = boundary_patch.lookupPatchField("rho"); - auto & Af = boundary_patch.magSf(); - auto && Nf = boundary_patch.nf(); - auto mdot_f = rho * (U_map & Nf) * Af; + auto & Sf = boundary_patch.Sf(); - Real m_dot = Foam::returnReduce(Foam::sum(mdot_f), Foam::sumOp()); + auto m_dot = Foam::sum(rho * (U_map & Sf)); + Foam::reduce(m_dot, Foam::sumOp()); auto & U_var = const_cast &>( boundary_patch.lookupPatchField("U")); - U_var == U_map * pp_value / m_dot; + U_var == -U_map * pp_value / m_dot; } void From a5b8233ec8bd6bb786a33290e6fb0e0f3bca2627 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Mon, 3 Nov 2025 16:56:18 +0000 Subject: [PATCH 12/52] Change mapped inlet test solver to use a rank independent test function --- .../mappedInletTestSolver.C | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.C b/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.C index d0731116..e9714104 100644 --- a/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.C +++ b/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.C @@ -143,16 +143,25 @@ Foam::solvers::mappedInletTestSolver::prePredictor() void Foam::solvers::mappedInletTestSolver::momentumPredictor() { - auto rank_time = Pstream::myProcNo() * mesh.time().userTimeValue(); - U_.primitiveFieldRef() = vector{rank_time + 1., 2. * rank_time + 1., 3 * rank_time + 1.}; + auto & coords = mesh.C().primitiveField(); + auto & U_field = U_.primitiveFieldRef(); + auto time = mesh.time().userTimeValue(); + + auto x = coords.component(0)(); + auto y = coords.component(1)(); + auto z = coords.component(2)(); + + U_field.replace(0, (x + y + z) * time); + U_field.replace(1, (x - y + z) * time); + U_field.replace(2, (x + y - z) * time); } void Foam::solvers::mappedInletTestSolver::thermophysicalPredictor() { volScalarField & e = thermo.he(); - auto rank_time = Pstream::myProcNo() * mesh.time().userTimeValue(); - e.primitiveFieldRef() = 4. * rank_time + 1.; + auto & coords = mesh.C().primitiveField(); + e.primitiveFieldRef() = mag(coords) * mesh.time().userTimeValue(); thermo_.correct(); } From 38d803ce6e4e33508cd49203a37a31aaf1f5f48e Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Mon, 3 Nov 2025 16:57:47 +0000 Subject: [PATCH 13/52] Add test for mapped inlet mass flow rate BC --- test/tests/bcs/mapped_mass_flow/foam/0/T | 56 ++++++++++++ test/tests/bcs/mapped_mass_flow/foam/0/U | 31 +++++++ test/tests/bcs/mapped_mass_flow/foam/0/rho | 56 ++++++++++++ .../bcs/mapped_mass_flow/foam/constant/g | 21 +++++ .../foam/constant/momentumTransport | 18 ++++ .../foam/constant/physicalProperties | 52 ++++++++++++ .../foam/system/blockMeshDict | 85 +++++++++++++++++++ .../mapped_mass_flow/foam/system/controlDict | 44 ++++++++++ .../foam/system/decomposeParDict | 42 +++++++++ .../mapped_mass_flow/foam/system/fvSchemes | 51 +++++++++++ .../mapped_mass_flow/foam/system/fvSolution | 61 +++++++++++++ test/tests/bcs/mapped_mass_flow/main.i | 44 ++++++++++ test/tests/bcs/mapped_mass_flow/test.py | 36 ++++++++ test/tests/bcs/mapped_mass_flow/tests | 26 ++++++ 14 files changed, 623 insertions(+) create mode 100644 test/tests/bcs/mapped_mass_flow/foam/0/T create mode 100644 test/tests/bcs/mapped_mass_flow/foam/0/U create mode 100644 test/tests/bcs/mapped_mass_flow/foam/0/rho create mode 100644 test/tests/bcs/mapped_mass_flow/foam/constant/g create mode 100644 test/tests/bcs/mapped_mass_flow/foam/constant/momentumTransport create mode 100644 test/tests/bcs/mapped_mass_flow/foam/constant/physicalProperties create mode 100644 test/tests/bcs/mapped_mass_flow/foam/system/blockMeshDict create mode 100644 test/tests/bcs/mapped_mass_flow/foam/system/controlDict create mode 100644 test/tests/bcs/mapped_mass_flow/foam/system/decomposeParDict create mode 100644 test/tests/bcs/mapped_mass_flow/foam/system/fvSchemes create mode 100644 test/tests/bcs/mapped_mass_flow/foam/system/fvSolution create mode 100644 test/tests/bcs/mapped_mass_flow/main.i create mode 100644 test/tests/bcs/mapped_mass_flow/test.py create mode 100644 test/tests/bcs/mapped_mass_flow/tests diff --git a/test/tests/bcs/mapped_mass_flow/foam/0/T b/test/tests/bcs/mapped_mass_flow/foam/0/T new file mode 100644 index 00000000..f8312bb2 --- /dev/null +++ b/test/tests/bcs/mapped_mass_flow/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 calculated; + value uniform 0.; + } + right + { + type calculated; + value uniform 0.; + } + top + { + type calculated; + value uniform 0.; + } + bottom + { + type calculated; + value uniform 0.; + } + back + { + type calculated; + value uniform 0.; + } + front + { + type calculated; + value uniform 0.; + } +} + + +// ************************************************************************* // diff --git a/test/tests/bcs/mapped_mass_flow/foam/0/U b/test/tests/bcs/mapped_mass_flow/foam/0/U new file mode 100644 index 00000000..15b296fa --- /dev/null +++ b/test/tests/bcs/mapped_mass_flow/foam/0/U @@ -0,0 +1,31 @@ +/*--------------------------------*- 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 volVectorField; + location "0"; + object U; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [ 0 1 -1 0 0 0 0 ]; + +internalField uniform (1 -0.5 0.25); + +boundaryField +{ + + ".*" + { + type fixedValue; + value $internalField; + } +} + +// ************************************************************************* // diff --git a/test/tests/bcs/mapped_mass_flow/foam/0/rho b/test/tests/bcs/mapped_mass_flow/foam/0/rho new file mode 100644 index 00000000..d30a04dc --- /dev/null +++ b/test/tests/bcs/mapped_mass_flow/foam/0/rho @@ -0,0 +1,56 @@ +/*--------------------------------*- 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 volScalarField; + location "0"; + object rho; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -3 0 0 0 0 0]; + +internalField uniform 1; + +boundaryField +{ + left + { + type calculated; + value uniform 1; + } + right + { + type calculated; + value uniform 1; + } + top + { + type calculated; + value uniform 1; + } + front + { + type calculated; + value uniform 1; + } + bottom + { + type calculated; + value uniform 1; + } + back + { + type calculated; + value uniform 1; + } +} + + +// ************************************************************************* // diff --git a/test/tests/bcs/mapped_mass_flow/foam/constant/g b/test/tests/bcs/mapped_mass_flow/foam/constant/g new file mode 100644 index 00000000..8af96f3a --- /dev/null +++ b/test/tests/bcs/mapped_mass_flow/foam/constant/g @@ -0,0 +1,21 @@ +/*--------------------------------*- 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 uniformDimensionedVectorField; + location "constant"; + object g; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 -2 0 0 0 0]; +value (0 0 0); + + +// ************************************************************************* // diff --git a/test/tests/bcs/mapped_mass_flow/foam/constant/momentumTransport b/test/tests/bcs/mapped_mass_flow/foam/constant/momentumTransport new file mode 100644 index 00000000..0416f1a9 --- /dev/null +++ b/test/tests/bcs/mapped_mass_flow/foam/constant/momentumTransport @@ -0,0 +1,18 @@ +/*--------------------------------*- 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 RASProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +simulationType laminar; + +// ************************************************************************* // diff --git a/test/tests/bcs/mapped_mass_flow/foam/constant/physicalProperties b/test/tests/bcs/mapped_mass_flow/foam/constant/physicalProperties new file mode 100644 index 00000000..4c5dac6a --- /dev/null +++ b/test/tests/bcs/mapped_mass_flow/foam/constant/physicalProperties @@ -0,0 +1,52 @@ +/*--------------------------------*- 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)] + mu 1.; + } + equationOfState + { + rho 0.5; // Density [kg/m^3] + } +} + + +// ************************************************************************* // diff --git a/test/tests/bcs/mapped_mass_flow/foam/system/blockMeshDict b/test/tests/bcs/mapped_mass_flow/foam/system/blockMeshDict new file mode 100644 index 00000000..c8d999e5 --- /dev/null +++ b/test/tests/bcs/mapped_mass_flow/foam/system/blockMeshDict @@ -0,0 +1,85 @@ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object blockMeshDict; +} + +vertices +( + ( 0.0 0.0 0.0 ) + ( 1.0 0.0 0.0 ) + ( 1.0 1.0 0.0 ) + ( 0.0 1.0 0.0 ) + + ( 0.0 0.0 1.0) + ( 1.0 0.0 1.0) + ( 1.0 1.0 1.0) + ( 0.0 1.0 1.0) +); + +blocks +( + hex (0 1 2 3 4 5 6 7) (9 9 9) simpleGrading (1 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/bcs/mapped_mass_flow/foam/system/controlDict b/test/tests/bcs/mapped_mass_flow/foam/system/controlDict new file mode 100644 index 00000000..2bbe0e5f --- /dev/null +++ b/test/tests/bcs/mapped_mass_flow/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 mappedInletTestSolver; + +startFrom startTime; + +startTime 0; + +stopAt endTime; + +endTime 5.; + +deltaT 1.; + +writeControl timeStep; + +writeInterval 1; + +writeFormat ascii; + +writePrecision 20; + +writeCompression off; + +timeFormat general; + +timePrecision 20; + +runTimeModifiable true; + +// ************************************************************************* // diff --git a/test/tests/bcs/mapped_mass_flow/foam/system/decomposeParDict b/test/tests/bcs/mapped_mass_flow/foam/system/decomposeParDict new file mode 100644 index 00000000..9df2378c --- /dev/null +++ b/test/tests/bcs/mapped_mass_flow/foam/system/decomposeParDict @@ -0,0 +1,42 @@ +/*--------------------------------*- 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 5; + +method scotch; + +simpleCoeffs +{ + n (2 1 1); +} + +hierarchicalCoeffs +{ + n (1 1 1); + order xyz; +} + +manualCoeffs +{ + dataFile ""; +} + +distributed no; + +roots ( ); + + +// ************************************************************************* // diff --git a/test/tests/bcs/mapped_mass_flow/foam/system/fvSchemes b/test/tests/bcs/mapped_mass_flow/foam/system/fvSchemes new file mode 100644 index 00000000..787f3b83 --- /dev/null +++ b/test/tests/bcs/mapped_mass_flow/foam/system/fvSchemes @@ -0,0 +1,51 @@ +/*--------------------------------*- 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 none; + + div(phi,U) Gauss linear; + div(phi,K) Gauss linear; + div(phi,h) Gauss linear; + div(((rho*nuEff)*dev2(T(grad(U))))) Gauss linear; +} + +laplacianSchemes +{ + default Gauss linear corrected; +} + +interpolationSchemes +{ + default linear; +} + +snGradSchemes +{ + default corrected; +} + +// ************************************************************************* // diff --git a/test/tests/bcs/mapped_mass_flow/foam/system/fvSolution b/test/tests/bcs/mapped_mass_flow/foam/system/fvSolution new file mode 100644 index 00000000..61143b21 --- /dev/null +++ b/test/tests/bcs/mapped_mass_flow/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; + } + + + "(U|h|p_rgh)" + { + solver PBiCGStab; + preconditioner DILU; + tolerance 1e-8; + relTol 1e-8; + } + + "(U|h|p_rgh)Final" + { + $U; + tolerance 1e-8; + relTol 1e-8; + } +} + +PIMPLE +{ + momentumPredictor yes; + pRefCell 0; + pRefValue 0; +} + +relaxationFactors +{ + equations + { + h 1; + U 1; + } +} + +// ************************************************************************* // diff --git a/test/tests/bcs/mapped_mass_flow/main.i b/test/tests/bcs/mapped_mass_flow/main.i new file mode 100644 index 00000000..89b319b5 --- /dev/null +++ b/test/tests/bcs/mapped_mass_flow/main.i @@ -0,0 +1,44 @@ +[Mesh] + type = FoamMesh + case = 'foam' + foam_patch = 'left right bottom top back front' +[] + +[FoamBCs] + [temp1] + type=FoamMassFlowRateMappedInletBC + boundary = 'left' # test boundary restrictions + mass_flow_pp = pp + translation_vector = '0.5 0 0' + [] +[] + +[Postprocessors] + [pp] + type = ParsedPostprocessor + expression = 't' + use_t = true + execute_on = TIMESTEP_BEGIN + [] +[] + + +[Problem] + type = FoamProblem + # Take the boundary temperature from OpenFOAM and set it on the MOOSE mesh. +[] + +[Executioner] + type = Transient + end_time = 5 + [TimeSteppers] + [foam] + type = FoamControlledTimeStepper + [] + [] +[] + +[Outputs] + exodus = true + csv=true +[] diff --git a/test/tests/bcs/mapped_mass_flow/test.py b/test/tests/bcs/mapped_mass_flow/test.py new file mode 100644 index 00000000..7b825493 --- /dev/null +++ b/test/tests/bcs/mapped_mass_flow/test.py @@ -0,0 +1,36 @@ +"""Tests for imposing BCs in OpenFOAM using MOOSE input file syntax +""" + +import unittest +import fluidfoam as ff +import numpy as np + +from read_hippo_data import get_foam_times + +class TestFoamBCMappedInlet(unittest.TestCase): + """Test class for mapped inlet BCs in Hippo.""" + def test_mapped_inlet(self): + """Test case for mapped inlet.""" + case_dir = 'foam/' + times = get_foam_times(case_dir)[1:] + + rho = 0.5 + for time in times: + u = ff.readof.readvector(case_dir, time, "U", boundary='left') + t = np.float64(time) + + if time != times[0]: + x, y, z = ff.readof.readmesh(case_dir, boundary='left') + x += 0.5 + u_ref = np.array([(x + y + z)*t, (x - y + z)*t, (x + y - z)*t,]) + else: + # first time step uses initialised value + u_ref = np.array([1, -0.5, 0.25])[:,None] + + rho = 0.5 + mdot = rho*np.mean(u_ref[0]) + mdot_pp = t + u_ref *= mdot_pp/mdot + + assert np.allclose(u_ref, u, rtol=1e-7, atol=1e-12),\ + f"Max diff ({time}): {abs(u-u_ref).max()} " diff --git a/test/tests/bcs/mapped_mass_flow/tests b/test/tests/bcs/mapped_mass_flow/tests new file mode 100644 index 00000000..adb8fde6 --- /dev/null +++ b/test/tests/bcs/mapped_mass_flow/tests @@ -0,0 +1,26 @@ +[Tests] + [mapped_mass_flow] + [setup] + type = RunCommand + command = 'bash -c "foamCleanCase -case foam && blockMesh -case foam && decomposePar -case foam"' + [] + [run] + type = RunApp + input = main.i + prereq = mapped_mass_flow/setup + allow_warnings = true + min_parallel = 5 + max_parallel = 5 + [] + [reconstruct] + type = RunCommand + command = 'reconstructPar -case foam' + prereq = mapped_mass_flow/run + [] + [verify] + type = PythonUnitTest + input = test.py + prereq = mapped_mass_flow/reconstruct + [] + [] +[] From 1595c22632a0fe0b6b0b3b3d0c1760386e63c0e8 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Mon, 3 Nov 2025 17:04:55 +0000 Subject: [PATCH 14/52] Fix error in mapped inlet test --- .../modules/mappedInletTestSolver/mappedInletTestSolver.C | 6 +++--- test/tests/bcs/mapped_mass_flow/main.i | 3 +-- test/tests/bcs/mapped_mass_flow/test.py | 8 ++++---- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.C b/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.C index e9714104..2d0e7871 100644 --- a/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.C +++ b/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.C @@ -151,9 +151,9 @@ Foam::solvers::mappedInletTestSolver::momentumPredictor() auto y = coords.component(1)(); auto z = coords.component(2)(); - U_field.replace(0, (x + y + z) * time); - U_field.replace(1, (x - y + z) * time); - U_field.replace(2, (x + y - z) * time); + U_field.replace(0, x + y + z + time); + U_field.replace(1, x - y + z + time); + U_field.replace(2, x + y - z + time); } void diff --git a/test/tests/bcs/mapped_mass_flow/main.i b/test/tests/bcs/mapped_mass_flow/main.i index 89b319b5..83c2b54a 100644 --- a/test/tests/bcs/mapped_mass_flow/main.i +++ b/test/tests/bcs/mapped_mass_flow/main.i @@ -16,8 +16,7 @@ [Postprocessors] [pp] type = ParsedPostprocessor - expression = 't' - use_t = true + expression = '1' execute_on = TIMESTEP_BEGIN [] [] diff --git a/test/tests/bcs/mapped_mass_flow/test.py b/test/tests/bcs/mapped_mass_flow/test.py index 7b825493..8cbc31ea 100644 --- a/test/tests/bcs/mapped_mass_flow/test.py +++ b/test/tests/bcs/mapped_mass_flow/test.py @@ -15,21 +15,21 @@ def test_mapped_inlet(self): times = get_foam_times(case_dir)[1:] rho = 0.5 - for time in times: + for i, time in enumerate(times): u = ff.readof.readvector(case_dir, time, "U", boundary='left') - t = np.float64(time) if time != times[0]: x, y, z = ff.readof.readmesh(case_dir, boundary='left') + t = np.float64(times[i-1]) x += 0.5 - u_ref = np.array([(x + y + z)*t, (x - y + z)*t, (x + y - z)*t,]) + u_ref = np.array([x + y + z + t, x - y + z + t, x + y - z + t,]) else: # first time step uses initialised value u_ref = np.array([1, -0.5, 0.25])[:,None] rho = 0.5 mdot = rho*np.mean(u_ref[0]) - mdot_pp = t + mdot_pp = 1 u_ref *= mdot_pp/mdot assert np.allclose(u_ref, u, rtol=1e-7, atol=1e-12),\ From 1586e43f0451626bbaa71445875dc5c446e0fd63 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Wed, 5 Nov 2025 15:00:12 +0000 Subject: [PATCH 15/52] Use BBox to reduce communication for mapped inlet --- include/bcs/FoamMassFlowRateMappedInletBC.h | 19 +- src/bcs/FoamMassFlowRateMappedInletBC.C | 288 ++++++++++++++++---- 2 files changed, 253 insertions(+), 54 deletions(-) diff --git a/include/bcs/FoamMassFlowRateMappedInletBC.h b/include/bcs/FoamMassFlowRateMappedInletBC.h index 6e18aa6b..ad607590 100644 --- a/include/bcs/FoamMassFlowRateMappedInletBC.h +++ b/include/bcs/FoamMassFlowRateMappedInletBC.h @@ -1,5 +1,5 @@ #include "FoamBCBase.h" -#include +#include "UPstream.H" class FoamMassFlowRateMappedInletBC : public FoamBCBase, public PostprocessorInterface { @@ -12,6 +12,12 @@ class FoamMassFlowRateMappedInletBC : public FoamBCBase, public PostprocessorInt virtual void initialSetup() override; + virtual ~FoamMassFlowRateMappedInletBC() + { + if (Foam::UPstream::parRun()) + Foam::UPstream::freeCommunicator(_foam_comm); + } + protected: PostprocessorName _pp_name; @@ -21,8 +27,19 @@ class FoamMassFlowRateMappedInletBC : public FoamBCBase, public PostprocessorInt std::map> _recv_map; + Foam::label _foam_comm; + + MPI_Comm _mpi_comm; + void createPatchProcMap(); template Foam::Field getMappedArray(const Foam::word & name); + + bool intersectMapPlane(const Foam::fvMesh & mesh, Real cart_bbox[6]); + + void createMapComm(const Foam::fvMesh & mesh, + Foam::vectorField face_centres, + std::vector & send_process, + std::vector & recv_process); }; diff --git a/src/bcs/FoamMassFlowRateMappedInletBC.C b/src/bcs/FoamMassFlowRateMappedInletBC.C index 4b8dd4f2..0d2b3ccb 100644 --- a/src/bcs/FoamMassFlowRateMappedInletBC.C +++ b/src/bcs/FoamMassFlowRateMappedInletBC.C @@ -3,9 +3,11 @@ #include "InputParameters.h" #include "MooseTypes.h" #include "Pstream.H" +#include "Pstream/mpi/PstreamGlobals.H" #include "PstreamReduceOps.H" #include "Registry.h" +#include "labelList.H" #include "ops.H" #include "mpi.h" #include "UPstream.H" @@ -14,63 +16,225 @@ registerMooseObject("hippoApp", FoamMassFlowRateMappedInletBC); +namespace +{ +void +getBBox(const Foam::vectorField points, Real bbox[6]) +{ + bbox[0] = DBL_MAX; + bbox[1] = DBL_MIN; + bbox[2] = DBL_MAX; + bbox[3] = DBL_MIN; + bbox[4] = DBL_MAX; + bbox[5] = DBL_MIN; + for (auto p : points) + { + bbox[0] = std::min(bbox[0], p.x()); + bbox[1] = std::max(bbox[1], p.x()); + bbox[2] = std::min(bbox[2], p.y()); + bbox[3] = std::max(bbox[3], p.y()); + bbox[4] = std::min(bbox[4], p.z()); + bbox[5] = std::max(bbox[5], p.z()); + } + + MPI_Allreduce( + MPI_IN_PLACE, &bbox[0], 1, MPI_DOUBLE, MPI_MIN, Foam::PstreamGlobals::MPI_COMM_FOAM); + MPI_Allreduce( + MPI_IN_PLACE, &bbox[1], 1, MPI_DOUBLE, MPI_MAX, Foam::PstreamGlobals::MPI_COMM_FOAM); + MPI_Allreduce( + MPI_IN_PLACE, &bbox[2], 1, MPI_DOUBLE, MPI_MIN, Foam::PstreamGlobals::MPI_COMM_FOAM); + MPI_Allreduce( + MPI_IN_PLACE, &bbox[3], 1, MPI_DOUBLE, MPI_MAX, Foam::PstreamGlobals::MPI_COMM_FOAM); + MPI_Allreduce( + MPI_IN_PLACE, &bbox[4], 1, MPI_DOUBLE, MPI_MIN, Foam::PstreamGlobals::MPI_COMM_FOAM); + MPI_Allreduce( + MPI_IN_PLACE, &bbox[5], 1, MPI_DOUBLE, MPI_MAX, Foam::PstreamGlobals::MPI_COMM_FOAM); +} +} + +bool +FoamMassFlowRateMappedInletBC::intersectMapPlane(const Foam::fvMesh & mesh, Real cart_bbox[6]) +{ + auto & vertices = mesh.points(); + for (int i = 0; i < mesh.nCells(); ++i) + { + auto points = mesh.cellPoints(i); + for (auto pointI : points) + { + // check whether cell intersects bbox + const Foam::point & p = vertices[pointI]; + if (p.x() >= cart_bbox[0] && p.x() <= cart_bbox[1] && p.y() >= cart_bbox[2] && + p.y() <= cart_bbox[3] && p.z() >= cart_bbox[4] && p.z() <= cart_bbox[5]) + { + return true; + } + } + + Real cell_bbox[6] = {DBL_MAX, DBL_MIN, DBL_MAX, DBL_MIN, DBL_MAX, DBL_MIN}; + for (auto point : points) + { + const Foam::point & p = vertices[point]; + cell_bbox[0] = std::min(cell_bbox[0], p.x()); + cell_bbox[1] = std::max(cell_bbox[1], p.x()); + cell_bbox[2] = std::min(cell_bbox[2], p.y()); + cell_bbox[3] = std::max(cell_bbox[3], p.y()); + cell_bbox[4] = std::min(cell_bbox[4], p.z()); + cell_bbox[5] = std::max(cell_bbox[5], p.z()); + } + // check is cart bbox is narrower than cell bbox in x direction + if ((cart_bbox[0] >= cell_bbox[0] && cart_bbox[1] <= cell_bbox[1]) && + (cart_bbox[3] >= cell_bbox[2] || cart_bbox[2] <= cell_bbox[3]) && + (cart_bbox[5] >= cell_bbox[4] || cart_bbox[4] <= cell_bbox[5])) + { + return true; + } + + // check is cart bbox is narrower than cell bbox in y direction + if ((cart_bbox[2] >= cell_bbox[2] && cart_bbox[3] <= cell_bbox[3]) && + (cart_bbox[1] >= cell_bbox[0] || cart_bbox[0] <= cell_bbox[1]) && + (cart_bbox[5] >= cell_bbox[4] || cart_bbox[4] <= cell_bbox[5])) + { + return true; + } + // check is cart bbox is narrower than cell bbox in z direction + if ((cart_bbox[4] >= cell_bbox[4] && cart_bbox[5] <= cell_bbox[5]) && + (cart_bbox[1] >= cell_bbox[0] || cart_bbox[0] <= cell_bbox[1]) && + (cart_bbox[3] >= cell_bbox[2] || cart_bbox[2] <= cell_bbox[3])) + { + return true; + } + } + + return false; +} + +void +FoamMassFlowRateMappedInletBC::createMapComm(const Foam::fvMesh & mesh, + const Foam::vectorField face_centres, + std::vector & map_process, + std::vector & inlet_process) +{ + Real cart_bbox[6]; + auto mapped_plane = face_centres + _offset; + getBBox(mapped_plane(), cart_bbox); + + int mappedPlaneProcess = intersectMapPlane(mesh, cart_bbox); + int inletPlaneProcess = face_centres.size() > 0; + + std::vector inlet_procs(Foam::UPstream::nProcs()); + std::vector map_procs(Foam::UPstream::nProcs()); + + MPI_Allgather(&mappedPlaneProcess, 1, MPI_INT, map_procs.data(), 1, MPI_INT, MPI_COMM_WORLD); + MPI_Allgather(&inletPlaneProcess, 1, MPI_INT, inlet_procs.data(), 1, MPI_INT, MPI_COMM_WORLD); + + map_process.clear(); + inlet_process.clear(); + + Foam::labelList processes; + int j = 0; + for (int i = 0; i < Foam::UPstream::nProcs(); ++i) + { + if (inlet_procs[i] || map_procs[i]) + { + processes.append(i); + if (inlet_procs[i]) + inlet_process.push_back(j); + if (map_procs[i]) + map_process.push_back(j); + ++j; + } + } + if (!Foam::Pstream::parRun()) + { + _foam_comm = Foam::UPstream::worldComm; + _mpi_comm = Foam::PstreamGlobals::MPI_COMM_FOAM; + } + else + { + _foam_comm = Foam::UPstream::allocateCommunicator(Foam::UPstream::worldComm, processes, true); + _mpi_comm = Foam::PstreamGlobals::MPICommunicators_[_foam_comm]; + } +} + void FoamMassFlowRateMappedInletBC::createPatchProcMap() { - // Use OpenFOAM's PStream to send local points to all processes - // A little inefficient but this is only done on initialisation - // A bounding box approach could be more efficient if there is any - // changes that require repartitioning auto & foam_mesh = _mesh->fvMesh(); auto & boundary = foam_mesh.boundary()[_boundary[0]]; auto face_centres = boundary.Cf(); - Foam::PstreamBuffers send_points(Foam::UPstream::commsTypes::nonBlocking); - for (int i = 0; i < Foam::Pstream::nProcs(); ++i) + std::vector map_procs, inlet_procs; + createMapComm(foam_mesh, face_centres, map_procs, inlet_procs); + + if (_mpi_comm == MPI_COMM_NULL) + return; + + Foam::PstreamBuffers send_points( + Foam::UPstream::commsTypes::nonBlocking, Foam::UPstream::msgType(), _foam_comm); + int rank = Foam::UPstream::myProcNo(_foam_comm); + bool isMapProc = std::find(map_procs.begin(), map_procs.end(), rank) != map_procs.end(); + bool isInletProc = std::find(inlet_procs.begin(), inlet_procs.end(), rank) != inlet_procs.end(); + + if (isInletProc) { - Foam::UOPstream send(i, send_points); - send << face_centres; + for (int proc : map_procs) + { + Foam::UOPstream send(proc, send_points); + send << face_centres; + } } + send_points.finishedSends(true); - std::vector size_requests(Foam::Pstream::nProcs()); - std::vector data_requests(Foam::Pstream::nProcs()); - std::vector sizes(Foam::Pstream::nProcs()); - for (int i = 0; i < Foam::Pstream::nProcs(); ++i) + std::vector size_requests(inlet_procs.size()); + std::vector data_requests(inlet_procs.size()); + + if (isMapProc) { - // Recieve from each process and check required point is present - Foam::vectorField field; - Foam::UIPstream recieve(i, send_points); - recieve >> field; - auto & vec = _send_map[i]; - std::vector recv_indices; - for (int j = 0; j < field.size(); ++j) + for (int proc : inlet_procs) { - auto index = foam_mesh.findCell(field[j] + _offset); - if (index >= 0) + Foam::vectorField field; + Foam::UIPstream recieve(proc, send_points); + recieve >> field; + auto & vec = _send_map[proc]; + std::vector recv_indices; + for (int j = 0; j < field.size(); ++j) { - vec.push_back(index); // assign to send map required indices - recv_indices.push_back(j); + auto index = foam_mesh.findCell(field[j] + _offset, Foam::polyMesh::FACE_PLANES); + if (index >= 0) + { + vec.push_back(index); // assign to send map required indices + recv_indices.push_back(j); + } } - } - - // Let original processes know which points will come from each rank - auto size = static_cast(vec.size()); - MPI_Isend(&size, 1, MPI_INT, i, 0, MPI_COMM_WORLD, &size_requests[i]); - MPI_Isend( - recv_indices.data(), recv_indices.size(), MPI_INT, i, 1, MPI_COMM_WORLD, &data_requests[i]); + if (vec.size() == 0) + _send_map.erase(proc); - MPI_Irecv(&sizes[i], 1, MPI_INT, i, 0, MPI_COMM_WORLD, &size_requests[i]); + // Let original processes know which points will come from each rank + auto size = static_cast(vec.size()); + MPI_Isend(&size, 1, MPI_INT, proc, 0, _mpi_comm, &size_requests[proc]); + MPI_Isend(recv_indices.data(), + recv_indices.size(), + MPI_INT, + proc, + 1, + _mpi_comm, + &data_requests[proc]); + } } - MPI_Waitall(size_requests.size(), size_requests.data(), MPI_STATUSES_IGNORE); - - for (int i = 0; i < Foam::Pstream::nProcs(); ++i) + if (isInletProc) { - std::vector recv_indices(sizes[i]); - MPI_Recv(recv_indices.data(), sizes[i], MPI_INT, i, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - for (auto index : recv_indices) - _recv_map[i].push_back(index); + for (auto & proc : map_procs) + { + int size; + MPI_Recv(&size, 1, MPI_INT, proc, 0, _mpi_comm, MPI_STATUS_IGNORE); + + std::vector recv_indices(size); + MPI_Recv(recv_indices.data(), size, MPI_INT, proc, 1, _mpi_comm, MPI_STATUS_IGNORE); + for (auto index : recv_indices) + _recv_map[proc].push_back(index); + } } } @@ -99,7 +263,9 @@ FoamMassFlowRateMappedInletBC::FoamMassFlowRateMappedInletBC(const InputParamete _pp_name(params.get("mass_flow_pp")), _offset(), _send_map(), - _recv_map() + _recv_map(), + _foam_comm(0), + _mpi_comm(MPI_COMM_NULL) { if (_boundary.size() > 1) mooseError("There can only be one boundary using this method"); @@ -115,31 +281,47 @@ template Foam::Field FoamMassFlowRateMappedInletBC::getMappedArray(const Foam::word & name) { + if (_mpi_comm == MPI_COMM_NULL) + return Foam::Field(); + auto & foam_mesh = _mesh->fvMesh(); auto & boundary_patch = foam_mesh.boundary()[_boundary[0]]; - Foam::PstreamBuffers sendBuf(Foam::UPstream::commsTypes::nonBlocking); - auto & var = foam_mesh.lookupObject>(name); - for (int i = 0; i < Foam::Pstream::nProcs(); ++i) + Foam::PstreamBuffers sendBuf( + Foam::UPstream::commsTypes::nonBlocking, Foam::UPstream::msgType(), _foam_comm); + if (_send_map.size() > 0) { - Foam::Field points(_send_map[i].size()); - for (auto j = 0lu; j < _send_map[i].size(); ++j) - points[j] = var[_send_map[i][j]]; + auto & var = foam_mesh.lookupObject>(name); + for (auto & pair : _send_map) + { + auto & proc = pair.first; + auto & send_indices = pair.second; + + Foam::Field points(send_indices.size()); + for (auto j = 0lu; j < send_indices.size(); ++j) + points[j] = var[send_indices[j]]; - Foam::UOPstream send(i, sendBuf); - send << points; + Foam::UOPstream send(proc, sendBuf); + send << points; + } } sendBuf.finishedSends(true); Foam::Field boundaryData(boundary_patch.size()); - for (int i = 0; i < Foam::Pstream::nProcs(); ++i) + if (_recv_map.size() > 0) { - Foam::UIPstream recv(i, sendBuf); - Foam::Field recvData; - recv >> recvData; - for (auto j = 0lu; j < _recv_map[i].size(); ++j) + for (auto & pair : _recv_map) { - boundaryData[_recv_map[i][j]] = recvData[j]; + auto & proc = pair.first; + auto & recv_indices = pair.second; + + Foam::UIPstream recv(proc, sendBuf); + Foam::Field recvData; + recv >> recvData; + for (auto j = 0lu; j < recv_indices.size(); ++j) + { + boundaryData[recv_indices[j]] = recvData[j]; + } } } From cb052b96958cf578f6a53e630d1e1738a007a1b4 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Wed, 5 Nov 2025 15:18:00 +0000 Subject: [PATCH 16/52] Add mapped inlet base class --- include/bcs/FoamMappedInletBCBase.h | 45 +++ include/bcs/FoamMassFlowRateMappedInletBC.h | 38 +-- src/bcs/FoamMappedInletBCBase.C | 330 ++++++++++++++++++++ src/bcs/FoamMassFlowRateMappedInletBC.C | 316 +------------------ 4 files changed, 379 insertions(+), 350 deletions(-) create mode 100644 include/bcs/FoamMappedInletBCBase.h create mode 100644 src/bcs/FoamMappedInletBCBase.C diff --git a/include/bcs/FoamMappedInletBCBase.h b/include/bcs/FoamMappedInletBCBase.h new file mode 100644 index 00000000..f4aea96e --- /dev/null +++ b/include/bcs/FoamMappedInletBCBase.h @@ -0,0 +1,45 @@ +#pragma once + +#include "FoamBCBase.h" +#include "UPstream.H" + +class FoamMappedInletBCBase : public FoamBCBase, public PostprocessorInterface +{ +public: + static InputParameters validParams(); + + FoamMappedInletBCBase(const InputParameters & params); + + virtual void initialSetup() override; + + virtual ~FoamMappedInletBCBase() + { + if (Foam::UPstream::parRun()) + Foam::UPstream::freeCommunicator(_foam_comm); + } + +protected: + PostprocessorName _pp_name; + + Foam::vector _offset; + + std::map> _send_map; + + std::map> _recv_map; + + Foam::label _foam_comm; + + MPI_Comm _mpi_comm; + + void createPatchProcMap(); + + template + Foam::Field getMappedArray(const Foam::word & name); + + bool intersectMapPlane(const Foam::fvMesh & mesh, Real cart_bbox[6]); + + void createMapComm(const Foam::fvMesh & mesh, + Foam::vectorField face_centres, + std::vector & send_process, + std::vector & recv_process); +}; diff --git a/include/bcs/FoamMassFlowRateMappedInletBC.h b/include/bcs/FoamMassFlowRateMappedInletBC.h index ad607590..1cd23269 100644 --- a/include/bcs/FoamMassFlowRateMappedInletBC.h +++ b/include/bcs/FoamMassFlowRateMappedInletBC.h @@ -1,7 +1,6 @@ -#include "FoamBCBase.h" -#include "UPstream.H" +#include "FoamMappedInletBCBase.h" -class FoamMassFlowRateMappedInletBC : public FoamBCBase, public PostprocessorInterface +class FoamMassFlowRateMappedInletBC : public FoamMappedInletBCBase { public: static InputParameters validParams(); @@ -9,37 +8,4 @@ class FoamMassFlowRateMappedInletBC : public FoamBCBase, public PostprocessorInt FoamMassFlowRateMappedInletBC(const InputParameters & params); virtual void imposeBoundaryCondition() override; - - virtual void initialSetup() override; - - virtual ~FoamMassFlowRateMappedInletBC() - { - if (Foam::UPstream::parRun()) - Foam::UPstream::freeCommunicator(_foam_comm); - } - -protected: - PostprocessorName _pp_name; - - Foam::vector _offset; - - std::map> _send_map; - - std::map> _recv_map; - - Foam::label _foam_comm; - - MPI_Comm _mpi_comm; - - void createPatchProcMap(); - - template - Foam::Field getMappedArray(const Foam::word & name); - - bool intersectMapPlane(const Foam::fvMesh & mesh, Real cart_bbox[6]); - - void createMapComm(const Foam::fvMesh & mesh, - Foam::vectorField face_centres, - std::vector & send_process, - std::vector & recv_process); }; diff --git a/src/bcs/FoamMappedInletBCBase.C b/src/bcs/FoamMappedInletBCBase.C new file mode 100644 index 00000000..eb96225c --- /dev/null +++ b/src/bcs/FoamMappedInletBCBase.C @@ -0,0 +1,330 @@ +#include "FoamBCBase.h" +#include "FoamMappedInletBCBase.h" +#include "InputParameters.h" +#include "MooseTypes.h" +#include "Pstream.H" +#include "Pstream/mpi/PstreamGlobals.H" + +#include "labelList.H" +#include "mpi.h" +#include "UPstream.H" +#include "vectorField.H" +#include "volFieldsFwd.H" + +namespace +{ +void +getBBox(const Foam::vectorField points, Real bbox[6]) +{ + bbox[0] = DBL_MAX; + bbox[1] = DBL_MIN; + bbox[2] = DBL_MAX; + bbox[3] = DBL_MIN; + bbox[4] = DBL_MAX; + bbox[5] = DBL_MIN; + for (auto p : points) + { + bbox[0] = std::min(bbox[0], p.x()); + bbox[1] = std::max(bbox[1], p.x()); + bbox[2] = std::min(bbox[2], p.y()); + bbox[3] = std::max(bbox[3], p.y()); + bbox[4] = std::min(bbox[4], p.z()); + bbox[5] = std::max(bbox[5], p.z()); + } + + MPI_Allreduce( + MPI_IN_PLACE, &bbox[0], 1, MPI_DOUBLE, MPI_MIN, Foam::PstreamGlobals::MPI_COMM_FOAM); + MPI_Allreduce( + MPI_IN_PLACE, &bbox[1], 1, MPI_DOUBLE, MPI_MAX, Foam::PstreamGlobals::MPI_COMM_FOAM); + MPI_Allreduce( + MPI_IN_PLACE, &bbox[2], 1, MPI_DOUBLE, MPI_MIN, Foam::PstreamGlobals::MPI_COMM_FOAM); + MPI_Allreduce( + MPI_IN_PLACE, &bbox[3], 1, MPI_DOUBLE, MPI_MAX, Foam::PstreamGlobals::MPI_COMM_FOAM); + MPI_Allreduce( + MPI_IN_PLACE, &bbox[4], 1, MPI_DOUBLE, MPI_MIN, Foam::PstreamGlobals::MPI_COMM_FOAM); + MPI_Allreduce( + MPI_IN_PLACE, &bbox[5], 1, MPI_DOUBLE, MPI_MAX, Foam::PstreamGlobals::MPI_COMM_FOAM); +} +} + +bool +FoamMappedInletBCBase::intersectMapPlane(const Foam::fvMesh & mesh, Real cart_bbox[6]) +{ + auto & vertices = mesh.points(); + for (int i = 0; i < mesh.nCells(); ++i) + { + auto points = mesh.cellPoints(i); + for (auto pointI : points) + { + // check whether cell intersects bbox + const Foam::point & p = vertices[pointI]; + if (p.x() >= cart_bbox[0] && p.x() <= cart_bbox[1] && p.y() >= cart_bbox[2] && + p.y() <= cart_bbox[3] && p.z() >= cart_bbox[4] && p.z() <= cart_bbox[5]) + { + return true; + } + } + + Real cell_bbox[6] = {DBL_MAX, DBL_MIN, DBL_MAX, DBL_MIN, DBL_MAX, DBL_MIN}; + for (auto point : points) + { + const Foam::point & p = vertices[point]; + cell_bbox[0] = std::min(cell_bbox[0], p.x()); + cell_bbox[1] = std::max(cell_bbox[1], p.x()); + cell_bbox[2] = std::min(cell_bbox[2], p.y()); + cell_bbox[3] = std::max(cell_bbox[3], p.y()); + cell_bbox[4] = std::min(cell_bbox[4], p.z()); + cell_bbox[5] = std::max(cell_bbox[5], p.z()); + } + // check is cart bbox is narrower than cell bbox in x direction + if ((cart_bbox[0] >= cell_bbox[0] && cart_bbox[1] <= cell_bbox[1]) && + (cart_bbox[3] >= cell_bbox[2] || cart_bbox[2] <= cell_bbox[3]) && + (cart_bbox[5] >= cell_bbox[4] || cart_bbox[4] <= cell_bbox[5])) + { + return true; + } + + // check is cart bbox is narrower than cell bbox in y direction + if ((cart_bbox[2] >= cell_bbox[2] && cart_bbox[3] <= cell_bbox[3]) && + (cart_bbox[1] >= cell_bbox[0] || cart_bbox[0] <= cell_bbox[1]) && + (cart_bbox[5] >= cell_bbox[4] || cart_bbox[4] <= cell_bbox[5])) + { + return true; + } + // check is cart bbox is narrower than cell bbox in z direction + if ((cart_bbox[4] >= cell_bbox[4] && cart_bbox[5] <= cell_bbox[5]) && + (cart_bbox[1] >= cell_bbox[0] || cart_bbox[0] <= cell_bbox[1]) && + (cart_bbox[3] >= cell_bbox[2] || cart_bbox[2] <= cell_bbox[3])) + { + return true; + } + } + + return false; +} + +void +FoamMappedInletBCBase::createMapComm(const Foam::fvMesh & mesh, + const Foam::vectorField face_centres, + std::vector & map_process, + std::vector & inlet_process) +{ + Real cart_bbox[6]; + auto mapped_plane = face_centres + _offset; + getBBox(mapped_plane(), cart_bbox); + + int mappedPlaneProcess = intersectMapPlane(mesh, cart_bbox); + int inletPlaneProcess = face_centres.size() > 0; + + std::vector inlet_procs(Foam::UPstream::nProcs()); + std::vector map_procs(Foam::UPstream::nProcs()); + + MPI_Allgather(&mappedPlaneProcess, 1, MPI_INT, map_procs.data(), 1, MPI_INT, MPI_COMM_WORLD); + MPI_Allgather(&inletPlaneProcess, 1, MPI_INT, inlet_procs.data(), 1, MPI_INT, MPI_COMM_WORLD); + + map_process.clear(); + inlet_process.clear(); + + Foam::labelList processes; + int j = 0; + for (int i = 0; i < Foam::UPstream::nProcs(); ++i) + { + if (inlet_procs[i] || map_procs[i]) + { + processes.append(i); + if (inlet_procs[i]) + inlet_process.push_back(j); + if (map_procs[i]) + map_process.push_back(j); + ++j; + } + } + if (!Foam::Pstream::parRun()) + { + _foam_comm = Foam::UPstream::worldComm; + _mpi_comm = Foam::PstreamGlobals::MPI_COMM_FOAM; + } + else + { + _foam_comm = Foam::UPstream::allocateCommunicator(Foam::UPstream::worldComm, processes, true); + _mpi_comm = Foam::PstreamGlobals::MPICommunicators_[_foam_comm]; + } +} + +void +FoamMappedInletBCBase::createPatchProcMap() +{ + auto & foam_mesh = _mesh->fvMesh(); + auto & boundary = foam_mesh.boundary()[_boundary[0]]; + auto face_centres = boundary.Cf(); + + std::vector map_procs, inlet_procs; + createMapComm(foam_mesh, face_centres, map_procs, inlet_procs); + + if (_mpi_comm == MPI_COMM_NULL) + return; + + Foam::PstreamBuffers send_points( + Foam::UPstream::commsTypes::nonBlocking, Foam::UPstream::msgType(), _foam_comm); + int rank = Foam::UPstream::myProcNo(_foam_comm); + bool isMapProc = std::find(map_procs.begin(), map_procs.end(), rank) != map_procs.end(); + bool isInletProc = std::find(inlet_procs.begin(), inlet_procs.end(), rank) != inlet_procs.end(); + + if (isInletProc) + { + for (int proc : map_procs) + { + Foam::UOPstream send(proc, send_points); + send << face_centres; + } + } + + send_points.finishedSends(true); + + std::vector size_requests(inlet_procs.size()); + std::vector data_requests(inlet_procs.size()); + + if (isMapProc) + { + for (int proc : inlet_procs) + { + Foam::vectorField field; + Foam::UIPstream recieve(proc, send_points); + recieve >> field; + auto & vec = _send_map[proc]; + std::vector recv_indices; + for (int j = 0; j < field.size(); ++j) + { + auto index = foam_mesh.findCell(field[j] + _offset, Foam::polyMesh::FACE_PLANES); + if (index >= 0) + { + vec.push_back(index); // assign to send map required indices + recv_indices.push_back(j); + } + } + if (vec.size() == 0) + _send_map.erase(proc); + + // Let original processes know which points will come from each rank + auto size = static_cast(vec.size()); + MPI_Isend(&size, 1, MPI_INT, proc, 0, _mpi_comm, &size_requests[proc]); + MPI_Isend(recv_indices.data(), + recv_indices.size(), + MPI_INT, + proc, + 1, + _mpi_comm, + &data_requests[proc]); + } + } + + if (isInletProc) + { + for (auto & proc : map_procs) + { + int size; + MPI_Recv(&size, 1, MPI_INT, proc, 0, _mpi_comm, MPI_STATUS_IGNORE); + + std::vector recv_indices(size); + MPI_Recv(recv_indices.data(), size, MPI_INT, proc, 1, _mpi_comm, MPI_STATUS_IGNORE); + for (auto index : recv_indices) + _recv_map[proc].push_back(index); + } + } +} + +InputParameters +FoamMappedInletBCBase::validParams() +{ + auto params = FoamBCBase::validParams(); + params.remove("v"); + params.remove("initial_condition"); + params.remove("foam_variable"); + + params.addParam( + "foam_variable", "T", "Name of foam variable associated with velocity"); + + params.addRequiredParam>("translation_vector", + "A vector indicating the location of recycling plane"); + params.addRequiredParam("mass_flow_pp", + "Postprocessors containing mass flow rate."); + + return params; +} + +FoamMappedInletBCBase::FoamMappedInletBCBase(const InputParameters & params) + : FoamBCBase(params), + PostprocessorInterface(this), + _pp_name(params.get("mass_flow_pp")), + _offset(), + _send_map(), + _recv_map(), + _foam_comm(0), + _mpi_comm(MPI_COMM_NULL) +{ + if (_boundary.size() > 1) + mooseError("There can only be one boundary using this method"); + + auto param_offset = params.get>("translation_vector"); + assert(param_offset.size() == 3); + + _offset = {param_offset[0], param_offset[1], param_offset[2]}; + createPatchProcMap(); +} + +template +Foam::Field +FoamMappedInletBCBase::getMappedArray(const Foam::word & name) +{ + if (_mpi_comm == MPI_COMM_NULL) + return Foam::Field(); + + auto & foam_mesh = _mesh->fvMesh(); + auto & boundary_patch = foam_mesh.boundary()[_boundary[0]]; + + Foam::PstreamBuffers sendBuf( + Foam::UPstream::commsTypes::nonBlocking, Foam::UPstream::msgType(), _foam_comm); + if (_send_map.size() > 0) + { + auto & var = foam_mesh.lookupObject>(name); + for (auto & pair : _send_map) + { + auto & proc = pair.first; + auto & send_indices = pair.second; + + Foam::Field points(send_indices.size()); + for (auto j = 0lu; j < send_indices.size(); ++j) + points[j] = var[send_indices[j]]; + + Foam::UOPstream send(proc, sendBuf); + send << points; + } + } + sendBuf.finishedSends(true); + + Foam::Field boundaryData(boundary_patch.size()); + if (_recv_map.size() > 0) + { + for (auto & pair : _recv_map) + { + auto & proc = pair.first; + auto & recv_indices = pair.second; + + Foam::UIPstream recv(proc, sendBuf); + Foam::Field recvData; + recv >> recvData; + for (auto j = 0lu; j < recv_indices.size(); ++j) + { + boundaryData[recv_indices[j]] = recvData[j]; + } + } + } + + return boundaryData; +} + +void +FoamMappedInletBCBase::initialSetup() +{ + _foam_variable = ""; +} diff --git a/src/bcs/FoamMassFlowRateMappedInletBC.C b/src/bcs/FoamMassFlowRateMappedInletBC.C index 0d2b3ccb..3de350f7 100644 --- a/src/bcs/FoamMassFlowRateMappedInletBC.C +++ b/src/bcs/FoamMassFlowRateMappedInletBC.C @@ -1,331 +1,25 @@ -#include "FoamBCBase.h" #include "FoamMassFlowRateMappedInletBC.h" #include "InputParameters.h" #include "MooseTypes.h" -#include "Pstream.H" -#include "Pstream/mpi/PstreamGlobals.H" #include "PstreamReduceOps.H" #include "Registry.h" -#include "labelList.H" #include "ops.H" -#include "mpi.h" -#include "UPstream.H" -#include "vectorField.H" #include "volFieldsFwd.H" registerMooseObject("hippoApp", FoamMassFlowRateMappedInletBC); -namespace -{ -void -getBBox(const Foam::vectorField points, Real bbox[6]) -{ - bbox[0] = DBL_MAX; - bbox[1] = DBL_MIN; - bbox[2] = DBL_MAX; - bbox[3] = DBL_MIN; - bbox[4] = DBL_MAX; - bbox[5] = DBL_MIN; - for (auto p : points) - { - bbox[0] = std::min(bbox[0], p.x()); - bbox[1] = std::max(bbox[1], p.x()); - bbox[2] = std::min(bbox[2], p.y()); - bbox[3] = std::max(bbox[3], p.y()); - bbox[4] = std::min(bbox[4], p.z()); - bbox[5] = std::max(bbox[5], p.z()); - } - - MPI_Allreduce( - MPI_IN_PLACE, &bbox[0], 1, MPI_DOUBLE, MPI_MIN, Foam::PstreamGlobals::MPI_COMM_FOAM); - MPI_Allreduce( - MPI_IN_PLACE, &bbox[1], 1, MPI_DOUBLE, MPI_MAX, Foam::PstreamGlobals::MPI_COMM_FOAM); - MPI_Allreduce( - MPI_IN_PLACE, &bbox[2], 1, MPI_DOUBLE, MPI_MIN, Foam::PstreamGlobals::MPI_COMM_FOAM); - MPI_Allreduce( - MPI_IN_PLACE, &bbox[3], 1, MPI_DOUBLE, MPI_MAX, Foam::PstreamGlobals::MPI_COMM_FOAM); - MPI_Allreduce( - MPI_IN_PLACE, &bbox[4], 1, MPI_DOUBLE, MPI_MIN, Foam::PstreamGlobals::MPI_COMM_FOAM); - MPI_Allreduce( - MPI_IN_PLACE, &bbox[5], 1, MPI_DOUBLE, MPI_MAX, Foam::PstreamGlobals::MPI_COMM_FOAM); -} -} - -bool -FoamMassFlowRateMappedInletBC::intersectMapPlane(const Foam::fvMesh & mesh, Real cart_bbox[6]) -{ - auto & vertices = mesh.points(); - for (int i = 0; i < mesh.nCells(); ++i) - { - auto points = mesh.cellPoints(i); - for (auto pointI : points) - { - // check whether cell intersects bbox - const Foam::point & p = vertices[pointI]; - if (p.x() >= cart_bbox[0] && p.x() <= cart_bbox[1] && p.y() >= cart_bbox[2] && - p.y() <= cart_bbox[3] && p.z() >= cart_bbox[4] && p.z() <= cart_bbox[5]) - { - return true; - } - } - - Real cell_bbox[6] = {DBL_MAX, DBL_MIN, DBL_MAX, DBL_MIN, DBL_MAX, DBL_MIN}; - for (auto point : points) - { - const Foam::point & p = vertices[point]; - cell_bbox[0] = std::min(cell_bbox[0], p.x()); - cell_bbox[1] = std::max(cell_bbox[1], p.x()); - cell_bbox[2] = std::min(cell_bbox[2], p.y()); - cell_bbox[3] = std::max(cell_bbox[3], p.y()); - cell_bbox[4] = std::min(cell_bbox[4], p.z()); - cell_bbox[5] = std::max(cell_bbox[5], p.z()); - } - // check is cart bbox is narrower than cell bbox in x direction - if ((cart_bbox[0] >= cell_bbox[0] && cart_bbox[1] <= cell_bbox[1]) && - (cart_bbox[3] >= cell_bbox[2] || cart_bbox[2] <= cell_bbox[3]) && - (cart_bbox[5] >= cell_bbox[4] || cart_bbox[4] <= cell_bbox[5])) - { - return true; - } - - // check is cart bbox is narrower than cell bbox in y direction - if ((cart_bbox[2] >= cell_bbox[2] && cart_bbox[3] <= cell_bbox[3]) && - (cart_bbox[1] >= cell_bbox[0] || cart_bbox[0] <= cell_bbox[1]) && - (cart_bbox[5] >= cell_bbox[4] || cart_bbox[4] <= cell_bbox[5])) - { - return true; - } - // check is cart bbox is narrower than cell bbox in z direction - if ((cart_bbox[4] >= cell_bbox[4] && cart_bbox[5] <= cell_bbox[5]) && - (cart_bbox[1] >= cell_bbox[0] || cart_bbox[0] <= cell_bbox[1]) && - (cart_bbox[3] >= cell_bbox[2] || cart_bbox[2] <= cell_bbox[3])) - { - return true; - } - } - - return false; -} - -void -FoamMassFlowRateMappedInletBC::createMapComm(const Foam::fvMesh & mesh, - const Foam::vectorField face_centres, - std::vector & map_process, - std::vector & inlet_process) -{ - Real cart_bbox[6]; - auto mapped_plane = face_centres + _offset; - getBBox(mapped_plane(), cart_bbox); - - int mappedPlaneProcess = intersectMapPlane(mesh, cart_bbox); - int inletPlaneProcess = face_centres.size() > 0; - - std::vector inlet_procs(Foam::UPstream::nProcs()); - std::vector map_procs(Foam::UPstream::nProcs()); - - MPI_Allgather(&mappedPlaneProcess, 1, MPI_INT, map_procs.data(), 1, MPI_INT, MPI_COMM_WORLD); - MPI_Allgather(&inletPlaneProcess, 1, MPI_INT, inlet_procs.data(), 1, MPI_INT, MPI_COMM_WORLD); - - map_process.clear(); - inlet_process.clear(); - - Foam::labelList processes; - int j = 0; - for (int i = 0; i < Foam::UPstream::nProcs(); ++i) - { - if (inlet_procs[i] || map_procs[i]) - { - processes.append(i); - if (inlet_procs[i]) - inlet_process.push_back(j); - if (map_procs[i]) - map_process.push_back(j); - ++j; - } - } - if (!Foam::Pstream::parRun()) - { - _foam_comm = Foam::UPstream::worldComm; - _mpi_comm = Foam::PstreamGlobals::MPI_COMM_FOAM; - } - else - { - _foam_comm = Foam::UPstream::allocateCommunicator(Foam::UPstream::worldComm, processes, true); - _mpi_comm = Foam::PstreamGlobals::MPICommunicators_[_foam_comm]; - } -} - -void -FoamMassFlowRateMappedInletBC::createPatchProcMap() -{ - auto & foam_mesh = _mesh->fvMesh(); - auto & boundary = foam_mesh.boundary()[_boundary[0]]; - auto face_centres = boundary.Cf(); - - std::vector map_procs, inlet_procs; - createMapComm(foam_mesh, face_centres, map_procs, inlet_procs); - - if (_mpi_comm == MPI_COMM_NULL) - return; - - Foam::PstreamBuffers send_points( - Foam::UPstream::commsTypes::nonBlocking, Foam::UPstream::msgType(), _foam_comm); - int rank = Foam::UPstream::myProcNo(_foam_comm); - bool isMapProc = std::find(map_procs.begin(), map_procs.end(), rank) != map_procs.end(); - bool isInletProc = std::find(inlet_procs.begin(), inlet_procs.end(), rank) != inlet_procs.end(); - - if (isInletProc) - { - for (int proc : map_procs) - { - Foam::UOPstream send(proc, send_points); - send << face_centres; - } - } - - send_points.finishedSends(true); - - std::vector size_requests(inlet_procs.size()); - std::vector data_requests(inlet_procs.size()); - - if (isMapProc) - { - for (int proc : inlet_procs) - { - Foam::vectorField field; - Foam::UIPstream recieve(proc, send_points); - recieve >> field; - auto & vec = _send_map[proc]; - std::vector recv_indices; - for (int j = 0; j < field.size(); ++j) - { - auto index = foam_mesh.findCell(field[j] + _offset, Foam::polyMesh::FACE_PLANES); - if (index >= 0) - { - vec.push_back(index); // assign to send map required indices - recv_indices.push_back(j); - } - } - if (vec.size() == 0) - _send_map.erase(proc); - - // Let original processes know which points will come from each rank - auto size = static_cast(vec.size()); - MPI_Isend(&size, 1, MPI_INT, proc, 0, _mpi_comm, &size_requests[proc]); - MPI_Isend(recv_indices.data(), - recv_indices.size(), - MPI_INT, - proc, - 1, - _mpi_comm, - &data_requests[proc]); - } - } - - if (isInletProc) - { - for (auto & proc : map_procs) - { - int size; - MPI_Recv(&size, 1, MPI_INT, proc, 0, _mpi_comm, MPI_STATUS_IGNORE); - - std::vector recv_indices(size); - MPI_Recv(recv_indices.data(), size, MPI_INT, proc, 1, _mpi_comm, MPI_STATUS_IGNORE); - for (auto index : recv_indices) - _recv_map[proc].push_back(index); - } - } -} - InputParameters FoamMassFlowRateMappedInletBC::validParams() { - auto params = FoamBCBase::validParams(); - params.remove("v"); - params.remove("initial_condition"); - params.remove("foam_variable"); - - params.addParam( - "foam_variable", "T", "Name of foam variable associated with velocity"); - - params.addRequiredParam>("translation_vector", - "A vector indicating the location of recycling plane"); - params.addRequiredParam("mass_flow_pp", - "Postprocessors containing mass flow rate."); + auto params = FoamMappedInletBCBase::validParams(); return params; } FoamMassFlowRateMappedInletBC::FoamMassFlowRateMappedInletBC(const InputParameters & params) - : FoamBCBase(params), - PostprocessorInterface(this), - _pp_name(params.get("mass_flow_pp")), - _offset(), - _send_map(), - _recv_map(), - _foam_comm(0), - _mpi_comm(MPI_COMM_NULL) -{ - if (_boundary.size() > 1) - mooseError("There can only be one boundary using this method"); - - auto param_offset = params.get>("translation_vector"); - assert(param_offset.size() == 3); - - _offset = {param_offset[0], param_offset[1], param_offset[2]}; - createPatchProcMap(); -} - -template -Foam::Field -FoamMassFlowRateMappedInletBC::getMappedArray(const Foam::word & name) + : FoamMappedInletBCBase(params) { - if (_mpi_comm == MPI_COMM_NULL) - return Foam::Field(); - - auto & foam_mesh = _mesh->fvMesh(); - auto & boundary_patch = foam_mesh.boundary()[_boundary[0]]; - - Foam::PstreamBuffers sendBuf( - Foam::UPstream::commsTypes::nonBlocking, Foam::UPstream::msgType(), _foam_comm); - if (_send_map.size() > 0) - { - auto & var = foam_mesh.lookupObject>(name); - for (auto & pair : _send_map) - { - auto & proc = pair.first; - auto & send_indices = pair.second; - - Foam::Field points(send_indices.size()); - for (auto j = 0lu; j < send_indices.size(); ++j) - points[j] = var[send_indices[j]]; - - Foam::UOPstream send(proc, sendBuf); - send << points; - } - } - sendBuf.finishedSends(true); - - Foam::Field boundaryData(boundary_patch.size()); - if (_recv_map.size() > 0) - { - for (auto & pair : _recv_map) - { - auto & proc = pair.first; - auto & recv_indices = pair.second; - - Foam::UIPstream recv(proc, sendBuf); - Foam::Field recvData; - recv >> recvData; - for (auto j = 0lu; j < recv_indices.size(); ++j) - { - boundaryData[recv_indices[j]] = recvData[j]; - } - } - } - - return boundaryData; } void @@ -349,9 +43,3 @@ FoamMassFlowRateMappedInletBC::imposeBoundaryCondition() U_var == -U_map * pp_value / m_dot; } - -void -FoamMassFlowRateMappedInletBC::initialSetup() -{ - _foam_variable = ""; -} From f62cb3eab7f133101b51b9a41528622014982143 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Wed, 5 Nov 2025 17:15:21 +0000 Subject: [PATCH 17/52] Add scalar bulk mapped inlet BC --- include/bcs/FoamMassFlowRateMappedInletBC.h | 1 + include/bcs/FoamScalarBulkMappedInletBC.h | 14 ++++++ src/bcs/FoamMappedInletBCBase.C | 20 +++----- src/bcs/FoamScalarBulkMappedInletBC.C | 53 +++++++++++++++++++++ 4 files changed, 75 insertions(+), 13 deletions(-) create mode 100644 include/bcs/FoamScalarBulkMappedInletBC.h create mode 100644 src/bcs/FoamScalarBulkMappedInletBC.C diff --git a/include/bcs/FoamMassFlowRateMappedInletBC.h b/include/bcs/FoamMassFlowRateMappedInletBC.h index 1cd23269..0f7be797 100644 --- a/include/bcs/FoamMassFlowRateMappedInletBC.h +++ b/include/bcs/FoamMassFlowRateMappedInletBC.h @@ -1,3 +1,4 @@ +#pragma once #include "FoamMappedInletBCBase.h" class FoamMassFlowRateMappedInletBC : public FoamMappedInletBCBase diff --git a/include/bcs/FoamScalarBulkMappedInletBC.h b/include/bcs/FoamScalarBulkMappedInletBC.h new file mode 100644 index 00000000..d5df7b91 --- /dev/null +++ b/include/bcs/FoamScalarBulkMappedInletBC.h @@ -0,0 +1,14 @@ +#pragma once +#include "FoamMappedInletBCBase.h" + +class FoamScalarBulkMappedInletBC : public FoamMappedInletBCBase +{ +public: + static InputParameters validParams(); + + FoamScalarBulkMappedInletBC(const InputParameters & params); + + virtual void imposeBoundaryCondition() override; + + virtual void initialSetup() override; +}; diff --git a/src/bcs/FoamMappedInletBCBase.C b/src/bcs/FoamMappedInletBCBase.C index eb96225c..37a8305d 100644 --- a/src/bcs/FoamMappedInletBCBase.C +++ b/src/bcs/FoamMappedInletBCBase.C @@ -32,18 +32,12 @@ getBBox(const Foam::vectorField points, Real bbox[6]) bbox[5] = std::max(bbox[5], p.z()); } - MPI_Allreduce( - MPI_IN_PLACE, &bbox[0], 1, MPI_DOUBLE, MPI_MIN, Foam::PstreamGlobals::MPI_COMM_FOAM); - MPI_Allreduce( - MPI_IN_PLACE, &bbox[1], 1, MPI_DOUBLE, MPI_MAX, Foam::PstreamGlobals::MPI_COMM_FOAM); - MPI_Allreduce( - MPI_IN_PLACE, &bbox[2], 1, MPI_DOUBLE, MPI_MIN, Foam::PstreamGlobals::MPI_COMM_FOAM); - MPI_Allreduce( - MPI_IN_PLACE, &bbox[3], 1, MPI_DOUBLE, MPI_MAX, Foam::PstreamGlobals::MPI_COMM_FOAM); - MPI_Allreduce( - MPI_IN_PLACE, &bbox[4], 1, MPI_DOUBLE, MPI_MIN, Foam::PstreamGlobals::MPI_COMM_FOAM); - MPI_Allreduce( - MPI_IN_PLACE, &bbox[5], 1, MPI_DOUBLE, MPI_MAX, Foam::PstreamGlobals::MPI_COMM_FOAM); + MPI_Allreduce(MPI_IN_PLACE, &bbox[0], 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD); + MPI_Allreduce(MPI_IN_PLACE, &bbox[1], 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); + MPI_Allreduce(MPI_IN_PLACE, &bbox[2], 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD); + MPI_Allreduce(MPI_IN_PLACE, &bbox[3], 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); + MPI_Allreduce(MPI_IN_PLACE, &bbox[4], 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD); + MPI_Allreduce(MPI_IN_PLACE, &bbox[5], 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); } } @@ -142,7 +136,7 @@ FoamMappedInletBCBase::createMapComm(const Foam::fvMesh & mesh, if (!Foam::Pstream::parRun()) { _foam_comm = Foam::UPstream::worldComm; - _mpi_comm = Foam::PstreamGlobals::MPI_COMM_FOAM; + _mpi_comm = MPI_COMM_WORLD; } else { diff --git a/src/bcs/FoamScalarBulkMappedInletBC.C b/src/bcs/FoamScalarBulkMappedInletBC.C new file mode 100644 index 00000000..3c57c55c --- /dev/null +++ b/src/bcs/FoamScalarBulkMappedInletBC.C @@ -0,0 +1,53 @@ +#include "FoamScalarBulkMappedInletBC.h" +#include "InputParameters.h" +#include "MooseTypes.h" +#include "PstreamReduceOps.H" +#include "Registry.h" + +#include "ops.H" +#include "volFieldsFwd.H" + +registerMooseObject("hippoApp", FoamScalarBulkMappedInletBC); + +InputParameters +FoamScalarBulkMappedInletBC::validParams() +{ + auto params = FoamMappedInletBCBase::validParams(); + + return params; +} + +FoamScalarBulkMappedInletBC::FoamScalarBulkMappedInletBC(const InputParameters & params) + : FoamMappedInletBCBase(params) +{ +} + +void +FoamScalarBulkMappedInletBC::imposeBoundaryCondition() +{ + auto & foam_mesh = _mesh->fvMesh(); + auto & boundary_patch = foam_mesh.boundary()[_boundary[0]]; + + // should we mapping rho U or just U? Fo now U but we can change it + auto pp_value = getPostprocessorValueByName(_pp_name); + + auto && var_map = getMappedArray(_foam_variable); + auto & Sf = boundary_patch.magSf(); + + auto totalArea = Foam::sum(Sf); + Foam::reduce(totalArea, Foam::sumOp()); + + auto var_bulk = Foam::sum(var_map * Sf) / totalArea; + + Foam::reduce(var_bulk, Foam::sumOp()); + + auto & var = const_cast &>( + boundary_patch.lookupPatchField("T")); + + var == var_map * pp_value / var_bulk; +} + +void +FoamScalarBulkMappedInletBC::initialSetup() +{ +} From 71179dc8250f25ccc35de5b309580df0dd32a127 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Wed, 5 Nov 2025 17:15:47 +0000 Subject: [PATCH 18/52] Rename mapped inlet test case --- .../mappedInletTestSolver/mappedInletTestSolver.C | 2 +- .../bcs/{mapped_mass_flow => mapped_inlet}/foam/0/T | 4 ++-- .../bcs/{mapped_mass_flow => mapped_inlet}/foam/0/U | 0 .../{mapped_mass_flow => mapped_inlet}/foam/0/rho | 0 .../foam/constant/g | 0 .../foam/constant/momentumTransport | 0 .../foam/constant/physicalProperties | 0 .../foam/system/blockMeshDict | 0 .../foam/system/controlDict | 0 .../foam/system/decomposeParDict | 0 .../foam/system/fvSchemes | 0 .../foam/system/fvSolution | 0 .../bcs/{mapped_mass_flow => mapped_inlet}/main.i | 11 +++++++++-- .../bcs/{mapped_mass_flow => mapped_inlet}/test.py | 12 +++++++++++- .../bcs/{mapped_mass_flow => mapped_inlet}/tests | 0 15 files changed, 23 insertions(+), 6 deletions(-) rename test/tests/bcs/{mapped_mass_flow => mapped_inlet}/foam/0/T (95%) rename test/tests/bcs/{mapped_mass_flow => mapped_inlet}/foam/0/U (100%) rename test/tests/bcs/{mapped_mass_flow => mapped_inlet}/foam/0/rho (100%) rename test/tests/bcs/{mapped_mass_flow => mapped_inlet}/foam/constant/g (100%) rename test/tests/bcs/{mapped_mass_flow => mapped_inlet}/foam/constant/momentumTransport (100%) rename test/tests/bcs/{mapped_mass_flow => mapped_inlet}/foam/constant/physicalProperties (100%) rename test/tests/bcs/{mapped_mass_flow => mapped_inlet}/foam/system/blockMeshDict (100%) rename test/tests/bcs/{mapped_mass_flow => mapped_inlet}/foam/system/controlDict (100%) rename test/tests/bcs/{mapped_mass_flow => mapped_inlet}/foam/system/decomposeParDict (100%) rename test/tests/bcs/{mapped_mass_flow => mapped_inlet}/foam/system/fvSchemes (100%) rename test/tests/bcs/{mapped_mass_flow => mapped_inlet}/foam/system/fvSolution (100%) rename test/tests/bcs/{mapped_mass_flow => mapped_inlet}/main.i (75%) rename test/tests/bcs/{mapped_mass_flow => mapped_inlet}/test.py (68%) rename test/tests/bcs/{mapped_mass_flow => mapped_inlet}/tests (100%) diff --git a/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.C b/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.C index 2d0e7871..17f910c8 100644 --- a/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.C +++ b/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.C @@ -161,7 +161,7 @@ Foam::solvers::mappedInletTestSolver::thermophysicalPredictor() { volScalarField & e = thermo.he(); auto & coords = mesh.C().primitiveField(); - e.primitiveFieldRef() = mag(coords) * mesh.time().userTimeValue(); + e.primitiveFieldRef() = mag(coords) + mesh.time().userTimeValue(); thermo_.correct(); } diff --git a/test/tests/bcs/mapped_mass_flow/foam/0/T b/test/tests/bcs/mapped_inlet/foam/0/T similarity index 95% rename from test/tests/bcs/mapped_mass_flow/foam/0/T rename to test/tests/bcs/mapped_inlet/foam/0/T index f8312bb2..8bb7faf1 100644 --- a/test/tests/bcs/mapped_mass_flow/foam/0/T +++ b/test/tests/bcs/mapped_inlet/foam/0/T @@ -16,13 +16,13 @@ FoamFile dimensions [0 0 0 1 0 0 0]; -internalField uniform 0.1; +internalField uniform 2.; boundaryField { left { - type calculated; + type fixedValue; value uniform 0.; } right diff --git a/test/tests/bcs/mapped_mass_flow/foam/0/U b/test/tests/bcs/mapped_inlet/foam/0/U similarity index 100% rename from test/tests/bcs/mapped_mass_flow/foam/0/U rename to test/tests/bcs/mapped_inlet/foam/0/U diff --git a/test/tests/bcs/mapped_mass_flow/foam/0/rho b/test/tests/bcs/mapped_inlet/foam/0/rho similarity index 100% rename from test/tests/bcs/mapped_mass_flow/foam/0/rho rename to test/tests/bcs/mapped_inlet/foam/0/rho diff --git a/test/tests/bcs/mapped_mass_flow/foam/constant/g b/test/tests/bcs/mapped_inlet/foam/constant/g similarity index 100% rename from test/tests/bcs/mapped_mass_flow/foam/constant/g rename to test/tests/bcs/mapped_inlet/foam/constant/g diff --git a/test/tests/bcs/mapped_mass_flow/foam/constant/momentumTransport b/test/tests/bcs/mapped_inlet/foam/constant/momentumTransport similarity index 100% rename from test/tests/bcs/mapped_mass_flow/foam/constant/momentumTransport rename to test/tests/bcs/mapped_inlet/foam/constant/momentumTransport diff --git a/test/tests/bcs/mapped_mass_flow/foam/constant/physicalProperties b/test/tests/bcs/mapped_inlet/foam/constant/physicalProperties similarity index 100% rename from test/tests/bcs/mapped_mass_flow/foam/constant/physicalProperties rename to test/tests/bcs/mapped_inlet/foam/constant/physicalProperties diff --git a/test/tests/bcs/mapped_mass_flow/foam/system/blockMeshDict b/test/tests/bcs/mapped_inlet/foam/system/blockMeshDict similarity index 100% rename from test/tests/bcs/mapped_mass_flow/foam/system/blockMeshDict rename to test/tests/bcs/mapped_inlet/foam/system/blockMeshDict diff --git a/test/tests/bcs/mapped_mass_flow/foam/system/controlDict b/test/tests/bcs/mapped_inlet/foam/system/controlDict similarity index 100% rename from test/tests/bcs/mapped_mass_flow/foam/system/controlDict rename to test/tests/bcs/mapped_inlet/foam/system/controlDict diff --git a/test/tests/bcs/mapped_mass_flow/foam/system/decomposeParDict b/test/tests/bcs/mapped_inlet/foam/system/decomposeParDict similarity index 100% rename from test/tests/bcs/mapped_mass_flow/foam/system/decomposeParDict rename to test/tests/bcs/mapped_inlet/foam/system/decomposeParDict diff --git a/test/tests/bcs/mapped_mass_flow/foam/system/fvSchemes b/test/tests/bcs/mapped_inlet/foam/system/fvSchemes similarity index 100% rename from test/tests/bcs/mapped_mass_flow/foam/system/fvSchemes rename to test/tests/bcs/mapped_inlet/foam/system/fvSchemes diff --git a/test/tests/bcs/mapped_mass_flow/foam/system/fvSolution b/test/tests/bcs/mapped_inlet/foam/system/fvSolution similarity index 100% rename from test/tests/bcs/mapped_mass_flow/foam/system/fvSolution rename to test/tests/bcs/mapped_inlet/foam/system/fvSolution diff --git a/test/tests/bcs/mapped_mass_flow/main.i b/test/tests/bcs/mapped_inlet/main.i similarity index 75% rename from test/tests/bcs/mapped_mass_flow/main.i rename to test/tests/bcs/mapped_inlet/main.i index 83c2b54a..27329442 100644 --- a/test/tests/bcs/mapped_mass_flow/main.i +++ b/test/tests/bcs/mapped_inlet/main.i @@ -5,12 +5,19 @@ [] [FoamBCs] - [temp1] + [mass_flow] type=FoamMassFlowRateMappedInletBC - boundary = 'left' # test boundary restrictions + boundary = 'left' mass_flow_pp = pp translation_vector = '0.5 0 0' [] + [temp] + type=FoamScalarBulkMappedInletBC + boundary = 'left' + mass_flow_pp = pp + translation_vector = '0.5 0 0' + foam_variable = 'T' + [] [] [Postprocessors] diff --git a/test/tests/bcs/mapped_mass_flow/test.py b/test/tests/bcs/mapped_inlet/test.py similarity index 68% rename from test/tests/bcs/mapped_mass_flow/test.py rename to test/tests/bcs/mapped_inlet/test.py index 8cbc31ea..22af5b04 100644 --- a/test/tests/bcs/mapped_mass_flow/test.py +++ b/test/tests/bcs/mapped_inlet/test.py @@ -17,20 +17,30 @@ def test_mapped_inlet(self): rho = 0.5 for i, time in enumerate(times): u = ff.readof.readvector(case_dir, time, "U", boundary='left') + temp = ff.readof.readscalar(case_dir, time, "T", boundary='left') if time != times[0]: x, y, z = ff.readof.readmesh(case_dir, boundary='left') t = np.float64(times[i-1]) x += 0.5 u_ref = np.array([x + y + z + t, x - y + z + t, x + y - z + t,]) + temp_ref = np.sqrt(x*x + y*y + z*z) + t else: # first time step uses initialised value u_ref = np.array([1, -0.5, 0.25])[:,None] + temp_ref = 2 rho = 0.5 mdot = rho*np.mean(u_ref[0]) mdot_pp = 1 u_ref *= mdot_pp/mdot + t_pp = 1 + t_bulk = np.mean(temp_ref) + temp_ref *= t_pp/t_bulk + assert np.allclose(u_ref, u, rtol=1e-7, atol=1e-12),\ - f"Max diff ({time}): {abs(u-u_ref).max()} " + f"Max diff (velocity) ({time}): {abs(u-u_ref).max()} " + + assert np.allclose(temp_ref, temp, rtol=1e-7, atol=1e-12),\ + f"Max diff (temperature) ({time}): {abs(temp-temp_ref).max()} {temp} {temp_ref}" diff --git a/test/tests/bcs/mapped_mass_flow/tests b/test/tests/bcs/mapped_inlet/tests similarity index 100% rename from test/tests/bcs/mapped_mass_flow/tests rename to test/tests/bcs/mapped_inlet/tests From aac3e4d27c2260183ccf37b9d8dc05188f2d7e10 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Wed, 5 Nov 2025 17:33:12 +0000 Subject: [PATCH 19/52] Correct gold file reference for mass flow rate BC --- .../bcs/mass_flow_rate/gold/main_out.csv | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/test/tests/bcs/mass_flow_rate/gold/main_out.csv b/test/tests/bcs/mass_flow_rate/gold/main_out.csv index 6184703c..bb1c32b8 100644 --- a/test/tests/bcs/mass_flow_rate/gold/main_out.csv +++ b/test/tests/bcs/mass_flow_rate/gold/main_out.csv @@ -1,34 +1,34 @@ time,m_dot,pp 0,0,0 -0.01,0.01,0.01 -0.02,0.02,0.02 -0.03,0.03,0.03 -0.04,0.04,0.04 -0.05,0.05,0.05 -0.06,0.06,0.06 -0.07,0.07,0.07 -0.08,0.08,0.08 -0.09,0.09,0.09 -0.1,0.1,0.1 -0.11,0.11,0.11 -0.12,0.12,0.12 -0.13,0.13,0.13 -0.14,0.14,0.14 -0.15,0.15,0.15 -0.16,0.16,0.16 -0.17,0.17,0.17 -0.18,0.18,0.18 -0.19,0.19,0.19 -0.2,0.2,0.2 -0.21,0.21,0.21 -0.22,0.22,0.22 -0.23,0.23,0.23 -0.24,0.24,0.24 -0.25,0.25,0.25 -0.26,0.26,0.26 -0.27,0.27,0.27 -0.28,0.28,0.28 -0.29,0.29,0.29 -0.3,0.3,0.3 -0.31,0.31,0.31 -0.32,0.32,0.32 +0.01,-0.01,0.01 +0.02,-0.02,0.02 +0.03,-0.03,0.03 +0.04,-0.04,0.04 +0.05,-0.05,0.05 +0.06,-0.06,0.06 +0.07,-0.07,0.07 +0.08,-0.08,0.08 +0.09,-0.09,0.09 +0.1,-0.1,0.1 +0.11,-0.11,0.11 +0.12,-0.12,0.12 +0.13,-0.13,0.13 +0.14,-0.14,0.14 +0.15,-0.15,0.15 +0.16,-0.16,0.16 +0.17,-0.17,0.17 +0.18,-0.18,0.18 +0.19,-0.19,0.19 +0.2,-0.2,0.2 +0.21,-0.21,0.21 +0.22,-0.22,0.22 +0.23,-0.23,0.23 +0.24,-0.24,0.24 +0.25,-0.25,0.25 +0.26,-0.26,0.26 +0.27,-0.27,0.27 +0.28,-0.28,0.28 +0.29,-0.29,0.29 +0.3,-0.3,0.3 +0.31,-0.31,0.31 +0.32,-0.32,0.32 From 0d794746b9f1db5cd1ba762665175297b9c0bc05 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Thu, 6 Nov 2025 13:01:47 +0000 Subject: [PATCH 20/52] Implement new FoamVariableBCBase class and propagate changes --- include/bcs/FoamBCBase.h | 22 ++++++- include/bcs/FoamFixedGradientBC.h | 4 +- include/bcs/FoamFixedValueBC.h | 4 +- include/bcs/FoamMappedInletBCBase.h | 4 +- include/bcs/FoamMassFlowRateInletBC.h | 4 +- include/bcs/FoamVariableBCBase.h | 29 ++++++++++ src/bcs/FoamBCBase.C | 60 -------------------- src/bcs/FoamFixedGradientBC.C | 4 +- src/bcs/FoamFixedValueBC.C | 7 ++- src/bcs/FoamMappedInletBCBase.C | 6 +- src/bcs/FoamMassFlowRateInletBC.C | 6 +- src/bcs/FoamVariableBCBase.C | 82 +++++++++++++++++++++++++++ src/problems/FoamProblem.C | 27 +-------- test/include/bcs/FoamTestBC.h | 6 +- 14 files changed, 158 insertions(+), 107 deletions(-) create mode 100644 include/bcs/FoamVariableBCBase.h create mode 100644 src/bcs/FoamVariableBCBase.C diff --git a/include/bcs/FoamBCBase.h b/include/bcs/FoamBCBase.h index 11b865ee..cf09ef31 100644 --- a/include/bcs/FoamBCBase.h +++ b/include/bcs/FoamBCBase.h @@ -7,6 +7,24 @@ #include #include #include +#include "VariadicTable.h" + +typedef VariadicTable BCInfoTable; + +template +inline std::string +listFromVector(std::vector vec, StrType sep = ", ") +{ + if (vec.size() == 0) + return std::string(); + else if (vec.size() == 1) + return vec.at(0); + + std::string str; + auto binary_op = [&](const std::string & acc, const std::string & it) { return acc + sep + it; }; + std::accumulate(vec.begin(), vec.end(), str, binary_op); + return str; +} class FoamBCBase : public MooseObject, public Coupleable { @@ -26,7 +44,9 @@ class FoamBCBase : public MooseObject, public Coupleable // returns the name of the foam boundaries the BC applies to std::vector boundary() const { return _boundary; }; - virtual void initialSetup(); + virtual void initialSetup() = 0; + + virtual void addInfoRow(BCInfoTable table) = 0; protected: // OpenFOAM variable which this BC is to be imposed on diff --git a/include/bcs/FoamFixedGradientBC.h b/include/bcs/FoamFixedGradientBC.h index 97041d43..0672b563 100644 --- a/include/bcs/FoamFixedGradientBC.h +++ b/include/bcs/FoamFixedGradientBC.h @@ -1,9 +1,9 @@ #pragma once -#include "FoamBCBase.h" +#include "FoamVariableBCBase.h" #include "InputParameters.h" -class FoamFixedGradientBC : public FoamBCBase +class FoamFixedGradientBC : public FoamVariableBCBase { public: // Validate input file parameters diff --git a/include/bcs/FoamFixedValueBC.h b/include/bcs/FoamFixedValueBC.h index 70a9f865..00932728 100644 --- a/include/bcs/FoamFixedValueBC.h +++ b/include/bcs/FoamFixedValueBC.h @@ -1,9 +1,9 @@ #pragma once -#include "FoamBCBase.h" +#include "FoamVariableBCBase.h" #include "InputParameters.h" -class FoamFixedValueBC : public FoamBCBase +class FoamFixedValueBC : public FoamVariableBCBase { public: // Validate input file parameters diff --git a/include/bcs/FoamMappedInletBCBase.h b/include/bcs/FoamMappedInletBCBase.h index f4aea96e..d1eeaa1a 100644 --- a/include/bcs/FoamMappedInletBCBase.h +++ b/include/bcs/FoamMappedInletBCBase.h @@ -1,9 +1,9 @@ #pragma once -#include "FoamBCBase.h" +#include "FoamVariableBCBase.h" #include "UPstream.H" -class FoamMappedInletBCBase : public FoamBCBase, public PostprocessorInterface +class FoamMappedInletBCBase : public FoamVariableBCBase, public PostprocessorInterface { public: static InputParameters validParams(); diff --git a/include/bcs/FoamMassFlowRateInletBC.h b/include/bcs/FoamMassFlowRateInletBC.h index 0175a6a2..02309e64 100644 --- a/include/bcs/FoamMassFlowRateInletBC.h +++ b/include/bcs/FoamMassFlowRateInletBC.h @@ -1,9 +1,9 @@ -#include "FoamBCBase.h" +#include "FoamVariableBCBase.h" #include "InputParameters.h" #include "MooseTypes.h" #include "PostprocessorInterface.h" -class FoamMassFlowRateInletBC : public FoamBCBase, public PostprocessorInterface +class FoamMassFlowRateInletBC : public FoamVariableBCBase, public PostprocessorInterface { public: static InputParameters validParams(); diff --git a/include/bcs/FoamVariableBCBase.h b/include/bcs/FoamVariableBCBase.h new file mode 100644 index 00000000..1d351b10 --- /dev/null +++ b/include/bcs/FoamVariableBCBase.h @@ -0,0 +1,29 @@ +#pragma once + +#include "FoamBCBase.h" +#include "InputParameters.h" + +class FoamVariableBCBase : public FoamBCBase +{ +public: + static InputParameters validParams(); + + explicit FoamVariableBCBase(const InputParameters & params); + + // returns the moose AuxVariable imposed on OpenFOAM + VariableName mooseVariable() const { return _moose_var->name(); } + + virtual void initialSetup(); + + virtual void addInfoRow(BCInfoTable table); + +protected: + // Get the value of the MOOSE variable at an element + Real variableValueAtElement(const libMesh::Elem * elem); + + // Get the data vector of the MOOSE field on a subdomain + std::vector getMooseVariableArray(int subdomainId); + + // Pointer to Moose variable used to impose BC + MooseVariableFieldBase * _moose_var; +}; diff --git a/src/bcs/FoamBCBase.C b/src/bcs/FoamBCBase.C index b2879f11..72de2273 100644 --- a/src/bcs/FoamBCBase.C +++ b/src/bcs/FoamBCBase.C @@ -14,16 +14,6 @@ #include #include -namespace -{ -// Private function to check if variables are constant monomials -inline bool -is_constant_monomial(const MooseVariableFieldBase & var) -{ - return var.order() == libMesh::Order::CONSTANT && var.feType().family == FEFamily::MONOMIAL; -} -} - InputParameters FoamBCBase::validParams() { @@ -33,13 +23,6 @@ FoamBCBase::validParams() params.addParam>("boundary", "Boundaries that the boundary condition applies to."); - params.addParam( - "v", - "Optional variable to use in BC. This allows existing AuxVariables to be" - " used rather than creating a new one under the hood."); - // Get desired parameters from Variable objects - params.transferParam>(MooseVariable::validParams(), "initial_condition"); - params.registerSystemAttributeName("FoamBC"); params.registerBase("FoamBC"); @@ -50,7 +33,6 @@ FoamBCBase::FoamBCBase(const InputParameters & params) : MooseObject(params), Coupleable(this, false), _foam_variable(params.get("foam_variable")), - _moose_var(nullptr), _boundary(params.get>("boundary")) { auto * problem = dynamic_cast(&_c_fe_problem); @@ -75,45 +57,3 @@ FoamBCBase::FoamBCBase(const InputParameters & params) if (_boundary.empty()) _boundary = all_subdomain_names; } - -void -FoamBCBase::initialSetup() -{ - // Check variable exists - auto var_name = parameters().isParamValid("v") ? parameters().get("v") : _name; - if (!_c_fe_problem.hasVariable(var_name)) - mooseError("Variable '", var_name, "' doesn't exist"); - - THREAD_ID tid = parameters().get("_tid"); - _moose_var = &_c_fe_problem.getVariable(tid, var_name); - - // Check variable is constant monomial in case it is provided. - if (!is_constant_monomial(*_moose_var)) - mooseError("Variable '", var_name, "' must be a constant monomial."); -} - -Real -FoamBCBase::variableValueAtElement(const libMesh::Elem * elem) -{ - auto & sys = _moose_var->sys(); - auto dof = elem->dof_number(sys.number(), _moose_var->number(), 0); - return sys.solution()(dof); -} - -std::vector -FoamBCBase::getMooseVariableArray(int subdomain_id) -{ - size_t patch_count = _mesh->getPatchCount(subdomain_id); - size_t patch_offset = _mesh->getPatchOffset(subdomain_id); - - std::vector var_array(patch_count); - for (size_t j = 0; j < patch_count; ++j) - { - auto elem = patch_offset + j; - auto elem_ptr = _mesh->getElemPtr(elem + _mesh->rank_element_offset); - assert(elem_ptr); - var_array[j] = variableValueAtElement(elem_ptr); - } - - return var_array; -} diff --git a/src/bcs/FoamFixedGradientBC.C b/src/bcs/FoamFixedGradientBC.C index 7434d077..120bb6b7 100644 --- a/src/bcs/FoamFixedGradientBC.C +++ b/src/bcs/FoamFixedGradientBC.C @@ -10,7 +10,7 @@ registerMooseObject("hippoApp", FoamFixedGradientBC); InputParameters FoamFixedGradientBC::validParams() { - auto params = FoamBCBase::validParams(); + auto params = FoamVariableBCBase::validParams(); params.addClassDescription("A FoamBC that imposes a fixed gradient dirichlet boundary condition " "on the OpenFOAM simulation"); params.addParam("diffusivity_coefficient", @@ -20,7 +20,7 @@ FoamFixedGradientBC::validParams() } FoamFixedGradientBC::FoamFixedGradientBC(const InputParameters & parameters) - : FoamBCBase(parameters), + : FoamVariableBCBase(parameters), _diffusivity_coefficient(parameters.get("diffusivity_coefficient")) { // check that the diffusivity coefficient is a OpenFOAM scalar field diff --git a/src/bcs/FoamFixedValueBC.C b/src/bcs/FoamFixedValueBC.C index 11c74268..b072695b 100644 --- a/src/bcs/FoamFixedValueBC.C +++ b/src/bcs/FoamFixedValueBC.C @@ -7,13 +7,16 @@ registerMooseObject("hippoApp", FoamFixedValueBC); InputParameters FoamFixedValueBC::validParams() { - auto params = FoamBCBase::validParams(); + auto params = FoamVariableBCBase::validParams(); params.addClassDescription("A FoamBC that imposes a fixed value dirichlet boundary condition " "on the OpenFOAM simulation"); return params; } -FoamFixedValueBC::FoamFixedValueBC(const InputParameters & parameters) : FoamBCBase(parameters) {} +FoamFixedValueBC::FoamFixedValueBC(const InputParameters & parameters) + : FoamVariableBCBase(parameters) +{ +} void FoamFixedValueBC::imposeBoundaryCondition() diff --git a/src/bcs/FoamMappedInletBCBase.C b/src/bcs/FoamMappedInletBCBase.C index 37a8305d..13c87439 100644 --- a/src/bcs/FoamMappedInletBCBase.C +++ b/src/bcs/FoamMappedInletBCBase.C @@ -1,4 +1,4 @@ -#include "FoamBCBase.h" +#include "FoamVariableBCBase.h" #include "FoamMappedInletBCBase.h" #include "InputParameters.h" #include "MooseTypes.h" @@ -230,7 +230,7 @@ FoamMappedInletBCBase::createPatchProcMap() InputParameters FoamMappedInletBCBase::validParams() { - auto params = FoamBCBase::validParams(); + auto params = FoamVariableBCBase::validParams(); params.remove("v"); params.remove("initial_condition"); params.remove("foam_variable"); @@ -247,7 +247,7 @@ FoamMappedInletBCBase::validParams() } FoamMappedInletBCBase::FoamMappedInletBCBase(const InputParameters & params) - : FoamBCBase(params), + : FoamVariableBCBase(params), PostprocessorInterface(this), _pp_name(params.get("mass_flow_pp")), _offset(), diff --git a/src/bcs/FoamMassFlowRateInletBC.C b/src/bcs/FoamMassFlowRateInletBC.C index c62d3fd3..da0d60fe 100644 --- a/src/bcs/FoamMassFlowRateInletBC.C +++ b/src/bcs/FoamMassFlowRateInletBC.C @@ -1,4 +1,4 @@ -#include "FoamBCBase.h" +#include "FoamVariableBCBase.h" #include "FoamMassFlowRateInletBC.h" #include "InputParameters.h" #include "MooseTypes.h" @@ -10,7 +10,7 @@ registerMooseObject("hippoApp", FoamMassFlowRateInletBC); InputParameters FoamMassFlowRateInletBC::validParams() { - auto params = FoamBCBase::validParams(); + auto params = FoamVariableBCBase::validParams(); params.remove("v"); params.remove("initial_condition"); params.remove("foam_variable"); @@ -25,7 +25,7 @@ FoamMassFlowRateInletBC::validParams() } FoamMassFlowRateInletBC::FoamMassFlowRateInletBC(const InputParameters & params) - : FoamBCBase(params), + : FoamVariableBCBase(params), PostprocessorInterface(this), _pp_name(params.get("postprocessor")) { diff --git a/src/bcs/FoamVariableBCBase.C b/src/bcs/FoamVariableBCBase.C new file mode 100644 index 00000000..3a47acd0 --- /dev/null +++ b/src/bcs/FoamVariableBCBase.C @@ -0,0 +1,82 @@ +#include "FEProblemBase.h" +#include "FoamVariableBCBase.h" + +namespace +{ +// Private function to check if variables are constant monomials +inline bool +is_constant_monomial(const MooseVariableFieldBase & var) +{ + return var.order() == libMesh::Order::CONSTANT && var.feType().family == FEFamily::MONOMIAL; +} +} + +InputParameters +FoamVariableBCBase::validParams() +{ + InputParameters params = FoamBCBase::validParams(); + + params.addParam( + "v", + "Optional variable to use in BC. This allows existing AuxVariables to be" + " used rather than creating a new one under the hood."); + // Get desired parameters from Variable objects + params.transferParam>(MooseVariable::validParams(), "initial_condition"); + + return params; +} + +FoamVariableBCBase::FoamVariableBCBase(const InputParameters & params) + : FoamBCBase(params), _moose_var(nullptr) +{ +} + +void +FoamVariableBCBase::initialSetup() +{ + // Check variable exists + auto var_name = parameters().isParamValid("v") ? parameters().get("v") : _name; + if (!_c_fe_problem.hasVariable(var_name)) + mooseError("Variable '", var_name, "' doesn't exist"); + + THREAD_ID tid = parameters().get("_tid"); + _moose_var = &_c_fe_problem.getVariable(tid, var_name); + + // Check variable is constant monomial in case it is provided. + if (!is_constant_monomial(*_moose_var)) + mooseError("Variable '", var_name, "' must be a constant monomial."); +} + +void +FoamVariableBCBase::addInfoRow(BCInfoTable table) +{ + // List info about BC + if (_moose_var) + table.addRow(name(), type(), foamVariable(), mooseVariable(), listFromVector(boundary())); +} + +Real +FoamVariableBCBase::variableValueAtElement(const libMesh::Elem * elem) +{ + auto & sys = _moose_var->sys(); + auto dof = elem->dof_number(sys.number(), _moose_var->number(), 0); + return sys.solution()(dof); +} + +std::vector +FoamVariableBCBase::getMooseVariableArray(int 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; + auto elem_ptr = _mesh->getElemPtr(elem + _mesh->rank_element_offset); + assert(elem_ptr); + var_array[j] = variableValueAtElement(elem_ptr); + } + + return var_array; +} diff --git a/src/problems/FoamProblem.C b/src/problems/FoamProblem.C index d1c470f9..7146148d 100644 --- a/src/problems/FoamProblem.C +++ b/src/problems/FoamProblem.C @@ -24,25 +24,6 @@ registerMooseObject("hippoApp", FoamProblem); -namespace -{ -// Create comma separated list from vector -template -inline std::string -listFromVector(std::vector vec, StrType sep = ", ") -{ - if (vec.size() == 0) - return std::string(); - else if (vec.size() == 1) - return vec.at(0); - - std::string str; - auto binary_op = [&](const std::string & acc, const std::string & it) { return acc + sep + it; }; - std::accumulate(vec.begin(), vec.end(), str, binary_op); - return str; -} -} - InputParameters FoamProblem::validParams() { @@ -154,7 +135,7 @@ FoamProblem::verifyFoamBCs() "FoamBC name", "Type", "Foam variable", - "Moose variable", + "Moose variable/postprocessor", "Boundaries", }); @@ -172,11 +153,7 @@ FoamProblem::verifyFoamBCs() auto && boundary = bc->boundary(); used_bcs.insert(used_bcs.end(), boundary.begin(), boundary.end()); // List info about BC - vt.addRow(bc->name(), - bc->type(), - bc->foamVariable(), - bc->mooseVariable(), - listFromVector(boundary)); + bc->addInfoRow(vt); } } diff --git a/test/include/bcs/FoamTestBC.h b/test/include/bcs/FoamTestBC.h index 28cd2a91..0ae3cf71 100644 --- a/test/include/bcs/FoamTestBC.h +++ b/test/include/bcs/FoamTestBC.h @@ -1,10 +1,10 @@ -#include "FoamBCBase.h" +#include "FoamVariableBCBase.h" #include "InputParameters.h" -class FoamTestBC : public FoamBCBase +class FoamTestBC : public FoamVariableBCBase { public: - explicit FoamTestBC(const InputParameters & params) : FoamBCBase(params) {}; + explicit FoamTestBC(const InputParameters & params) : FoamVariableBCBase(params) {}; void imposeBoundaryCondition() {}; }; From 0e62203f72562064eadc783efec44235acd46bda Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Thu, 6 Nov 2025 14:10:54 +0000 Subject: [PATCH 21/52] Implement new FoamPostprocessorBCBase class and propagate --- include/bcs/FoamBCBase.h | 2 +- include/bcs/FoamMappedInletBCBase.h | 8 ++----- include/bcs/FoamMassFlowRateInletBC.h | 9 ++----- include/bcs/FoamPostprocessorBCBase.h | 27 +++++++++++++++++++++ include/bcs/FoamScalarBulkMappedInletBC.h | 2 -- include/bcs/FoamVariableBCBase.h | 2 +- src/bcs/FoamBCBase.C | 3 +++ src/bcs/FoamMappedInletBCBase.C | 22 ++--------------- src/bcs/FoamMassFlowRateInletBC.C | 26 ++++---------------- src/bcs/FoamMassFlowRateMappedInletBC.C | 7 +++--- src/bcs/FoamPostprocessorBCBase.C | 29 +++++++++++++++++++++++ src/bcs/FoamScalarBulkMappedInletBC.C | 10 +------- src/bcs/FoamVariableBCBase.C | 5 ++-- test/tests/bcs/mapped_inlet/main.i | 4 ++-- test/tests/bcs/mass_flow_rate/main.i | 2 +- 15 files changed, 82 insertions(+), 76 deletions(-) create mode 100644 include/bcs/FoamPostprocessorBCBase.h create mode 100644 src/bcs/FoamPostprocessorBCBase.C diff --git a/include/bcs/FoamBCBase.h b/include/bcs/FoamBCBase.h index cf09ef31..78c0d0b4 100644 --- a/include/bcs/FoamBCBase.h +++ b/include/bcs/FoamBCBase.h @@ -46,7 +46,7 @@ class FoamBCBase : public MooseObject, public Coupleable virtual void initialSetup() = 0; - virtual void addInfoRow(BCInfoTable table) = 0; + virtual void addInfoRow(BCInfoTable & table) = 0; protected: // OpenFOAM variable which this BC is to be imposed on diff --git a/include/bcs/FoamMappedInletBCBase.h b/include/bcs/FoamMappedInletBCBase.h index d1eeaa1a..7b879c8e 100644 --- a/include/bcs/FoamMappedInletBCBase.h +++ b/include/bcs/FoamMappedInletBCBase.h @@ -1,17 +1,15 @@ #pragma once -#include "FoamVariableBCBase.h" +#include "FoamPostprocessorBCBase.h" #include "UPstream.H" -class FoamMappedInletBCBase : public FoamVariableBCBase, public PostprocessorInterface +class FoamMappedInletBCBase : public FoamPostprocessorBCBase { public: static InputParameters validParams(); FoamMappedInletBCBase(const InputParameters & params); - virtual void initialSetup() override; - virtual ~FoamMappedInletBCBase() { if (Foam::UPstream::parRun()) @@ -19,8 +17,6 @@ class FoamMappedInletBCBase : public FoamVariableBCBase, public PostprocessorInt } protected: - PostprocessorName _pp_name; - Foam::vector _offset; std::map> _send_map; diff --git a/include/bcs/FoamMassFlowRateInletBC.h b/include/bcs/FoamMassFlowRateInletBC.h index 02309e64..0167e169 100644 --- a/include/bcs/FoamMassFlowRateInletBC.h +++ b/include/bcs/FoamMassFlowRateInletBC.h @@ -1,9 +1,9 @@ -#include "FoamVariableBCBase.h" +#include "FoamPostprocessorBCBase.h" #include "InputParameters.h" #include "MooseTypes.h" #include "PostprocessorInterface.h" -class FoamMassFlowRateInletBC : public FoamVariableBCBase, public PostprocessorInterface +class FoamMassFlowRateInletBC : public FoamPostprocessorBCBase { public: static InputParameters validParams(); @@ -11,9 +11,4 @@ class FoamMassFlowRateInletBC : public FoamVariableBCBase, public PostprocessorI FoamMassFlowRateInletBC(const InputParameters & params); virtual void imposeBoundaryCondition() override; - - virtual void initialSetup() override; - -protected: - PostprocessorName _pp_name; }; diff --git a/include/bcs/FoamPostprocessorBCBase.h b/include/bcs/FoamPostprocessorBCBase.h new file mode 100644 index 00000000..be37f63d --- /dev/null +++ b/include/bcs/FoamPostprocessorBCBase.h @@ -0,0 +1,27 @@ +#pragma once + +#include "FoamBCBase.h" +#include "InputParameters.h" +#include "MooseTypes.h" +#include "PostprocessorInterface.h" + +class FoamPostprocessorBCBase : public FoamBCBase, public PostprocessorInterface +{ +public: + static InputParameters validParams(); + + explicit FoamPostprocessorBCBase(const InputParameters & params); + + // returns the moose AuxVariable imposed on OpenFOAM + VariableName moosePostprocessor() const { return _pp_name; } + + virtual void initialSetup() {}; + + virtual void addInfoRow(BCInfoTable & table); + +protected: + const PostprocessorName _pp_name; + + // Pointer to Moose variable used to impose BC + const PostprocessorValue & _pp_value; +}; diff --git a/include/bcs/FoamScalarBulkMappedInletBC.h b/include/bcs/FoamScalarBulkMappedInletBC.h index d5df7b91..bac4dbc7 100644 --- a/include/bcs/FoamScalarBulkMappedInletBC.h +++ b/include/bcs/FoamScalarBulkMappedInletBC.h @@ -9,6 +9,4 @@ class FoamScalarBulkMappedInletBC : public FoamMappedInletBCBase FoamScalarBulkMappedInletBC(const InputParameters & params); virtual void imposeBoundaryCondition() override; - - virtual void initialSetup() override; }; diff --git a/include/bcs/FoamVariableBCBase.h b/include/bcs/FoamVariableBCBase.h index 1d351b10..00300294 100644 --- a/include/bcs/FoamVariableBCBase.h +++ b/include/bcs/FoamVariableBCBase.h @@ -15,7 +15,7 @@ class FoamVariableBCBase : public FoamBCBase virtual void initialSetup(); - virtual void addInfoRow(BCInfoTable table); + virtual void addInfoRow(BCInfoTable & table); protected: // Get the value of the MOOSE variable at an element diff --git a/src/bcs/FoamBCBase.C b/src/bcs/FoamBCBase.C index 72de2273..742a00f5 100644 --- a/src/bcs/FoamBCBase.C +++ b/src/bcs/FoamBCBase.C @@ -22,7 +22,10 @@ FoamBCBase::validParams() "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.addPrivateParam("_foam_var_settable", true); params.registerSystemAttributeName("FoamBC"); params.registerBase("FoamBC"); diff --git a/src/bcs/FoamMappedInletBCBase.C b/src/bcs/FoamMappedInletBCBase.C index 13c87439..466c0c60 100644 --- a/src/bcs/FoamMappedInletBCBase.C +++ b/src/bcs/FoamMappedInletBCBase.C @@ -1,4 +1,3 @@ -#include "FoamVariableBCBase.h" #include "FoamMappedInletBCBase.h" #include "InputParameters.h" #include "MooseTypes.h" @@ -230,26 +229,15 @@ FoamMappedInletBCBase::createPatchProcMap() InputParameters FoamMappedInletBCBase::validParams() { - auto params = FoamVariableBCBase::validParams(); - params.remove("v"); - params.remove("initial_condition"); - params.remove("foam_variable"); - - params.addParam( - "foam_variable", "T", "Name of foam variable associated with velocity"); - + auto params = FoamPostprocessorBCBase::validParams(); params.addRequiredParam>("translation_vector", "A vector indicating the location of recycling plane"); - params.addRequiredParam("mass_flow_pp", - "Postprocessors containing mass flow rate."); return params; } FoamMappedInletBCBase::FoamMappedInletBCBase(const InputParameters & params) - : FoamVariableBCBase(params), - PostprocessorInterface(this), - _pp_name(params.get("mass_flow_pp")), + : FoamPostprocessorBCBase(params), _offset(), _send_map(), _recv_map(), @@ -316,9 +304,3 @@ FoamMappedInletBCBase::getMappedArray(const Foam::word & name) return boundaryData; } - -void -FoamMappedInletBCBase::initialSetup() -{ - _foam_variable = ""; -} diff --git a/src/bcs/FoamMassFlowRateInletBC.C b/src/bcs/FoamMassFlowRateInletBC.C index da0d60fe..322f4698 100644 --- a/src/bcs/FoamMassFlowRateInletBC.C +++ b/src/bcs/FoamMassFlowRateInletBC.C @@ -1,4 +1,3 @@ -#include "FoamVariableBCBase.h" #include "FoamMassFlowRateInletBC.h" #include "InputParameters.h" #include "MooseTypes.h" @@ -10,24 +9,16 @@ registerMooseObject("hippoApp", FoamMassFlowRateInletBC); InputParameters FoamMassFlowRateInletBC::validParams() { - auto params = FoamVariableBCBase::validParams(); - params.remove("v"); - params.remove("initial_condition"); - params.remove("foam_variable"); - - params.addParam( - "foam_variable", "T", "Name of foam variable associated with velocity"); + auto params = FoamPostprocessorBCBase::validParams(); - params.addRequiredParam("postprocessor", - "Postprocessors containing mass flow rate."); + params.remove("foam_variable"); + params.addPrivateParam("foam_variable", "U"); return params; } FoamMassFlowRateInletBC::FoamMassFlowRateInletBC(const InputParameters & params) - : FoamVariableBCBase(params), - PostprocessorInterface(this), - _pp_name(params.get("postprocessor")) + : FoamPostprocessorBCBase(params) { } @@ -41,19 +32,12 @@ FoamMassFlowRateInletBC::imposeBoundaryCondition() auto subdomains = _mesh->getSubdomainIDs(_boundary); for (auto subdomain : subdomains) { - auto pp_value = getPostprocessorValueByName(_pp_name); auto & boundary_patch = foam_mesh.boundary()[subdomain]; auto & U_var = const_cast &>( boundary_patch.lookupPatchField("U")); auto & rho = boundary_patch.lookupPatchField("rho"); Real area = Foam::returnReduce(Foam::sum(boundary_patch.magSf()), Foam::sumOp()); - U_var == -pp_value * boundary_patch.nf() / (rho * area); + U_var == -_pp_value * boundary_patch.nf() / (rho * area); } } - -void -FoamMassFlowRateInletBC::initialSetup() -{ - _foam_variable = ""; -} diff --git a/src/bcs/FoamMassFlowRateMappedInletBC.C b/src/bcs/FoamMassFlowRateMappedInletBC.C index 3de350f7..17b39e2b 100644 --- a/src/bcs/FoamMassFlowRateMappedInletBC.C +++ b/src/bcs/FoamMassFlowRateMappedInletBC.C @@ -14,6 +14,9 @@ FoamMassFlowRateMappedInletBC::validParams() { auto params = FoamMappedInletBCBase::validParams(); + params.remove("foam_variable"); + params.addPrivateParam("foam_variable", "U"); + return params; } @@ -29,8 +32,6 @@ FoamMassFlowRateMappedInletBC::imposeBoundaryCondition() auto & boundary_patch = foam_mesh.boundary()[_boundary[0]]; // should we mapping rho U or just U? Fo now U but we can change it - auto pp_value = getPostprocessorValueByName(_pp_name); - auto && U_map = getMappedArray("U"); auto & rho = boundary_patch.lookupPatchField("rho"); auto & Sf = boundary_patch.Sf(); @@ -41,5 +42,5 @@ FoamMassFlowRateMappedInletBC::imposeBoundaryCondition() auto & U_var = const_cast &>( boundary_patch.lookupPatchField("U")); - U_var == -U_map * pp_value / m_dot; + U_var == -U_map * _pp_value / m_dot; } diff --git a/src/bcs/FoamPostprocessorBCBase.C b/src/bcs/FoamPostprocessorBCBase.C new file mode 100644 index 00000000..06154835 --- /dev/null +++ b/src/bcs/FoamPostprocessorBCBase.C @@ -0,0 +1,29 @@ +#include "FoamBCBase.h" +#include "FoamPostprocessorBCBase.h" +#include "InputParameters.h" +#include "MooseTypes.h" +#include "PostprocessorInterface.h" + +InputParameters +FoamPostprocessorBCBase::validParams() +{ + auto params = FoamBCBase::validParams(); + + params.addParam("pp", "optional postprocessor to be used in BC"); + + return params; +} + +FoamPostprocessorBCBase::FoamPostprocessorBCBase(const InputParameters & params) + : FoamBCBase(params), + PostprocessorInterface(this), + _pp_name(params.get("pp")), + _pp_value(getPostprocessorValueByName(_pp_name)) +{ +} + +void +FoamPostprocessorBCBase::addInfoRow(BCInfoTable & table) +{ + table.addRow(name(), type(), foamVariable(), moosePostprocessor(), listFromVector(boundary())); +} diff --git a/src/bcs/FoamScalarBulkMappedInletBC.C b/src/bcs/FoamScalarBulkMappedInletBC.C index 3c57c55c..4599ff0e 100644 --- a/src/bcs/FoamScalarBulkMappedInletBC.C +++ b/src/bcs/FoamScalarBulkMappedInletBC.C @@ -28,9 +28,6 @@ FoamScalarBulkMappedInletBC::imposeBoundaryCondition() auto & foam_mesh = _mesh->fvMesh(); auto & boundary_patch = foam_mesh.boundary()[_boundary[0]]; - // should we mapping rho U or just U? Fo now U but we can change it - auto pp_value = getPostprocessorValueByName(_pp_name); - auto && var_map = getMappedArray(_foam_variable); auto & Sf = boundary_patch.magSf(); @@ -44,10 +41,5 @@ FoamScalarBulkMappedInletBC::imposeBoundaryCondition() auto & var = const_cast &>( boundary_patch.lookupPatchField("T")); - var == var_map * pp_value / var_bulk; -} - -void -FoamScalarBulkMappedInletBC::initialSetup() -{ + var == var_map * _pp_value / var_bulk; } diff --git a/src/bcs/FoamVariableBCBase.C b/src/bcs/FoamVariableBCBase.C index 3a47acd0..4caa83b6 100644 --- a/src/bcs/FoamVariableBCBase.C +++ b/src/bcs/FoamVariableBCBase.C @@ -48,11 +48,10 @@ FoamVariableBCBase::initialSetup() } void -FoamVariableBCBase::addInfoRow(BCInfoTable table) +FoamVariableBCBase::addInfoRow(BCInfoTable & table) { // List info about BC - if (_moose_var) - table.addRow(name(), type(), foamVariable(), mooseVariable(), listFromVector(boundary())); + table.addRow(name(), type(), foamVariable(), mooseVariable(), listFromVector(boundary())); } Real diff --git a/test/tests/bcs/mapped_inlet/main.i b/test/tests/bcs/mapped_inlet/main.i index 27329442..c2133945 100644 --- a/test/tests/bcs/mapped_inlet/main.i +++ b/test/tests/bcs/mapped_inlet/main.i @@ -8,13 +8,13 @@ [mass_flow] type=FoamMassFlowRateMappedInletBC boundary = 'left' - mass_flow_pp = pp + pp = pp translation_vector = '0.5 0 0' [] [temp] type=FoamScalarBulkMappedInletBC boundary = 'left' - mass_flow_pp = pp + pp = pp translation_vector = '0.5 0 0' foam_variable = 'T' [] diff --git a/test/tests/bcs/mass_flow_rate/main.i b/test/tests/bcs/mass_flow_rate/main.i index 5cdc78c2..dbe15311 100644 --- a/test/tests/bcs/mass_flow_rate/main.i +++ b/test/tests/bcs/mass_flow_rate/main.i @@ -8,7 +8,7 @@ [temp1] type=FoamMassFlowRateInletBC boundary = 'left' # test boundary restrictions - postprocessor = pp + pp = pp [] [] From 692cfaa2a063bf2a19f90f82e9ff46c16468842b Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Thu, 6 Nov 2025 16:25:57 +0000 Subject: [PATCH 22/52] Add default creation of Receiver for Postprocessor-based BCs --- include/actions/AddFoamBCAction.h | 3 +++ src/actions/AddFoamBCAction.C | 5 ++++- src/bcs/FoamPostprocessorBCBase.C | 6 +++++- test/tests/bcs/mapped_inlet/main.i | 6 +++--- test/tests/bcs/mapped_inlet/tests | 26 ++++++++++++++++++++++++++ 5 files changed, 41 insertions(+), 5 deletions(-) diff --git a/include/actions/AddFoamBCAction.h b/include/actions/AddFoamBCAction.h index cc90072b..33ec6c4e 100644 --- a/include/actions/AddFoamBCAction.h +++ b/include/actions/AddFoamBCAction.h @@ -15,4 +15,7 @@ class AddFoamBCAction : public MooseObjectAction protected: // Create AuxVariable associated with new-style BCs void createAuxVariable(); + + // Create Receiver for Postprocessor-based BCs + void createReceiver(FoamProblem & problem); }; diff --git a/src/actions/AddFoamBCAction.C b/src/actions/AddFoamBCAction.C index f2ffce49..5ef83a81 100644 --- a/src/actions/AddFoamBCAction.C +++ b/src/actions/AddFoamBCAction.C @@ -27,9 +27,12 @@ AddFoamBCAction::act() mooseError("FoamBCs system can only be used with FoamProblem."); // Do not create aux variable if variable provided. - if (!_moose_object_pars.isParamSetByUser("v")) + if (findParamKey(_moose_object_pars, "v") && !_moose_object_pars.isParamSetByUser("v")) createAuxVariable(); + if (findParamKey(_moose_object_pars, "pp") && !_moose_object_pars.isParamSetByUser("pp")) + createReceiver(*foam_problem); + foam_problem->addObject(_type, _name, _moose_object_pars, false); } } diff --git a/src/bcs/FoamPostprocessorBCBase.C b/src/bcs/FoamPostprocessorBCBase.C index 06154835..f01508e0 100644 --- a/src/bcs/FoamPostprocessorBCBase.C +++ b/src/bcs/FoamPostprocessorBCBase.C @@ -3,6 +3,7 @@ #include "InputParameters.h" #include "MooseTypes.h" #include "PostprocessorInterface.h" +#include "Receiver.h" InputParameters FoamPostprocessorBCBase::validParams() @@ -10,6 +11,7 @@ FoamPostprocessorBCBase::validParams() auto params = FoamBCBase::validParams(); params.addParam("pp", "optional postprocessor to be used in BC"); + params.transferParam(Receiver::validParams(), "default"); return params; } @@ -17,9 +19,11 @@ FoamPostprocessorBCBase::validParams() FoamPostprocessorBCBase::FoamPostprocessorBCBase(const InputParameters & params) : FoamBCBase(params), PostprocessorInterface(this), - _pp_name(params.get("pp")), + _pp_name((params.isParamSetByUser("pp")) ? params.get("pp") : _name), _pp_value(getPostprocessorValueByName(_pp_name)) { + if (params.isParamSetByUser("pp") && params.isParamSetByUser("default")) + mooseWarning("'pp' and 'default' should not be set. 'default' ignored."); } void diff --git a/test/tests/bcs/mapped_inlet/main.i b/test/tests/bcs/mapped_inlet/main.i index c2133945..7641e38b 100644 --- a/test/tests/bcs/mapped_inlet/main.i +++ b/test/tests/bcs/mapped_inlet/main.i @@ -8,13 +8,13 @@ [mass_flow] type=FoamMassFlowRateMappedInletBC boundary = 'left' - pp = pp + default = 1 translation_vector = '0.5 0 0' [] [temp] type=FoamScalarBulkMappedInletBC boundary = 'left' - pp = pp + default = 1 translation_vector = '0.5 0 0' foam_variable = 'T' [] @@ -23,7 +23,7 @@ [Postprocessors] [pp] type = ParsedPostprocessor - expression = '1' + expression = '2' execute_on = TIMESTEP_BEGIN [] [] diff --git a/test/tests/bcs/mapped_inlet/tests b/test/tests/bcs/mapped_inlet/tests index adb8fde6..9ec3256f 100644 --- a/test/tests/bcs/mapped_inlet/tests +++ b/test/tests/bcs/mapped_inlet/tests @@ -1,8 +1,33 @@ [Tests] + [mapped_mass_flow_receiver] + [setup] + type = RunCommand + command = 'bash -c "foamCleanCase -case foam && blockMesh -case foam && decomposePar -case foam"' + [] + [run] + type = RunApp + input = main.i + prereq = mapped_mass_flow_receiver/setup + allow_warnings = true + min_parallel = 5 + max_parallel = 5 + [] + [reconstruct] + type = RunCommand + command = 'reconstructPar -case foam' + prereq = mapped_mass_flow_receiver/run + [] + [verify] + type = PythonUnitTest + input = test.py + prereq = mapped_mass_flow_receiver/reconstruct + [] + [] [mapped_mass_flow] [setup] type = RunCommand command = 'bash -c "foamCleanCase -case foam && blockMesh -case foam && decomposePar -case foam"' + prereq = mapped_mass_flow_receiver/reconstruct [] [run] type = RunApp @@ -11,6 +36,7 @@ allow_warnings = true min_parallel = 5 max_parallel = 5 + cli_args = 'FoamBCs/mass_flow/pp=pp FoamBCs/temp/pp=pp Postprocessors/pp/expression=1' [] [reconstruct] type = RunCommand From 691b27011c83bf6ee1847d84cb8db160e3ead4cf Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Thu, 6 Nov 2025 17:25:48 +0000 Subject: [PATCH 23/52] Implement different scaling approaches for the scalar bulk mapped inlet --- include/bcs/FoamScalarBulkMappedInletBC.h | 7 ++++++ src/bcs/FoamMassFlowRateMappedInletBC.C | 10 ++++++-- src/bcs/FoamScalarBulkMappedInletBC.C | 30 +++++++++++++++++++++-- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/include/bcs/FoamScalarBulkMappedInletBC.h b/include/bcs/FoamScalarBulkMappedInletBC.h index bac4dbc7..2a68fd0c 100644 --- a/include/bcs/FoamScalarBulkMappedInletBC.h +++ b/include/bcs/FoamScalarBulkMappedInletBC.h @@ -1,5 +1,6 @@ #pragma once #include "FoamMappedInletBCBase.h" +#include "MooseEnum.h" class FoamScalarBulkMappedInletBC : public FoamMappedInletBCBase { @@ -9,4 +10,10 @@ class FoamScalarBulkMappedInletBC : public FoamMappedInletBCBase FoamScalarBulkMappedInletBC(const InputParameters & params); virtual void imposeBoundaryCondition() override; + +protected: + MooseEnum _scale_method; + + template + T applyScaleMethod(T & var, const Real bulk_ref, const Real bulk); }; diff --git a/src/bcs/FoamMassFlowRateMappedInletBC.C b/src/bcs/FoamMassFlowRateMappedInletBC.C index 17b39e2b..8aacad37 100644 --- a/src/bcs/FoamMassFlowRateMappedInletBC.C +++ b/src/bcs/FoamMassFlowRateMappedInletBC.C @@ -5,6 +5,7 @@ #include "Registry.h" #include "ops.H" +#include "vectorField.H" #include "volFieldsFwd.H" registerMooseObject("hippoApp", FoamMassFlowRateMappedInletBC); @@ -33,14 +34,19 @@ FoamMassFlowRateMappedInletBC::imposeBoundaryCondition() // should we mapping rho U or just U? Fo now U but we can change it auto && U_map = getMappedArray("U"); + auto && rho_map = getMappedArray("rho"); + auto g_map = rho_map * U_map; + auto & rho = boundary_patch.lookupPatchField("rho"); auto & Sf = boundary_patch.Sf(); - auto m_dot = Foam::sum(rho * (U_map & Sf)); + auto m_dot = Foam::sum(g_map & -Sf); Foam::reduce(m_dot, Foam::sumOp()); auto & U_var = const_cast &>( boundary_patch.lookupPatchField("U")); - U_var == -U_map * _pp_value / m_dot; + Foam::vectorField g_var(U_var.size()); + g_var = rho_map * U_map * _pp_value / m_dot; + U_var == g_var / rho; } diff --git a/src/bcs/FoamScalarBulkMappedInletBC.C b/src/bcs/FoamScalarBulkMappedInletBC.C index 4599ff0e..f14b7518 100644 --- a/src/bcs/FoamScalarBulkMappedInletBC.C +++ b/src/bcs/FoamScalarBulkMappedInletBC.C @@ -1,5 +1,6 @@ #include "FoamScalarBulkMappedInletBC.h" #include "InputParameters.h" +#include "MooseError.h" #include "MooseTypes.h" #include "PstreamReduceOps.H" #include "Registry.h" @@ -13,12 +14,18 @@ InputParameters FoamScalarBulkMappedInletBC::validParams() { auto params = FoamMappedInletBCBase::validParams(); + MooseEnum scaleEnum("SCALE SUBTRACT", "SCALE"); + params.addParam("scale_method", + scaleEnum, + "Method used to maintain inlet bulk variable. " + "SCALE means the variable is multiplied by a factor, " + "SUBTRACT means the variable is reduced by constant."); return params; } FoamScalarBulkMappedInletBC::FoamScalarBulkMappedInletBC(const InputParameters & params) - : FoamMappedInletBCBase(params) + : FoamMappedInletBCBase(params), _scale_method(params.get("scale_method")) { } @@ -41,5 +48,24 @@ FoamScalarBulkMappedInletBC::imposeBoundaryCondition() auto & var = const_cast &>( boundary_patch.lookupPatchField("T")); - var == var_map * _pp_value / var_bulk; + var == applyScaleMethod(var_map, _pp_value, var_bulk); +} + +template +T +FoamScalarBulkMappedInletBC::applyScaleMethod(T & var, const Real bulk_ref, const Real bulk) +{ + if (_scale_method == "SCALE") + { + std::cout << bulk << " " << bulk_ref << std::endl; + return (var * bulk_ref / bulk)(); + } + else if (_scale_method == "SUBTRACT") + { + return (var + bulk_ref - bulk)(); + } + else + { + mooseError("Invalid scale method '", _scale_method, "'."); + } } From 27b097415fad99a2a540a164f57f018b0fe1da72 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Fri, 7 Nov 2025 10:45:31 +0000 Subject: [PATCH 24/52] Implement fixed value and fixed gradient postprocessor BCs --- .../bcs/FoamFixedGradientPostprocessorBC.h | 18 ++++++ include/bcs/FoamFixedValuePostprocessorBC.h | 14 ++++ src/bcs/FoamFixedGradientPostprocessorBC.C | 64 +++++++++++++++++++ src/bcs/FoamFixedValuePosprocessorBC.C | 33 ++++++++++ 4 files changed, 129 insertions(+) create mode 100644 include/bcs/FoamFixedGradientPostprocessorBC.h create mode 100644 include/bcs/FoamFixedValuePostprocessorBC.h create mode 100644 src/bcs/FoamFixedGradientPostprocessorBC.C create mode 100644 src/bcs/FoamFixedValuePosprocessorBC.C diff --git a/include/bcs/FoamFixedGradientPostprocessorBC.h b/include/bcs/FoamFixedGradientPostprocessorBC.h new file mode 100644 index 00000000..4e0199b8 --- /dev/null +++ b/include/bcs/FoamFixedGradientPostprocessorBC.h @@ -0,0 +1,18 @@ +#pragma once + +#include "FoamPostprocessorBCBase.h" +#include "InputParameters.h" + +class FoamFixedGradientPostprocessorBC : public FoamPostprocessorBCBase +{ +public: + static InputParameters validParams(); + + FoamFixedGradientPostprocessorBC(const InputParameters & params); + + virtual void imposeBoundaryCondition() override; + +protected: + // name of diffusivity coefficient used to divide flux + std::string _diffusivity_coefficient; +}; diff --git a/include/bcs/FoamFixedValuePostprocessorBC.h b/include/bcs/FoamFixedValuePostprocessorBC.h new file mode 100644 index 00000000..c32041cf --- /dev/null +++ b/include/bcs/FoamFixedValuePostprocessorBC.h @@ -0,0 +1,14 @@ +#pragma once + +#include "FoamPostprocessorBCBase.h" +#include "InputParameters.h" + +class FoamFixedValuePostprocessorBC : public FoamPostprocessorBCBase +{ +public: + static InputParameters validParams(); + + FoamFixedValuePostprocessorBC(const InputParameters & params); + + virtual void imposeBoundaryCondition() override; +}; diff --git a/src/bcs/FoamFixedGradientPostprocessorBC.C b/src/bcs/FoamFixedGradientPostprocessorBC.C new file mode 100644 index 00000000..c0fba39f --- /dev/null +++ b/src/bcs/FoamFixedGradientPostprocessorBC.C @@ -0,0 +1,64 @@ +#include "FoamFixedGradientPostprocessorBC.h" +#include "PstreamReduceOps.H" +#include "fixedGradientFvPatchFields.H" +#include + +InputParameters +FoamFixedGradientPostprocessorBC::validParams() +{ + auto params = FoamPostprocessorBCBase::validParams(); + params.addParam("diffusivity_coefficient", + "", + "OpenFOAM scalar field name to be specified if 'v' is " + "a flux rather than a gradient"); + return params; +} + +FoamFixedGradientPostprocessorBC::FoamFixedGradientPostprocessorBC(const InputParameters & params) + : FoamPostprocessorBCBase(params), + _diffusivity_coefficient(params.get("diffusivity_coefficient")) +{ +} + +void +FoamFixedGradientPostprocessorBC::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); + for (auto subdomain : subdomains) + { + auto & boundary = foam_mesh.boundary()[subdomain]; + // Get underlying field from OpenFOAM boundary patch. + // TODO: Change to function on rebase + auto & var = const_cast &>( + boundary.lookupPatchField(_foam_variable)); + + // Get the gradient associated with the field + Foam::scalarField & foam_gradient( + Foam::refCast(var).gradient()); + + // If diffusivity_coefficient is specified grad array is a flux, so result + // must be divided by it + if (!_diffusivity_coefficient.empty()) + { + // Get the underlying diffusivity field + auto & coeff = foam_mesh.boundary()[subdomain].lookupPatchField( + _diffusivity_coefficient); + + auto area = boundary.magSf(); + auto total_area = Foam::returnReduce(Foam::sum(area), Foam::sumOp()); + auto coeff_bulk = + Foam::returnReduce(Foam::sum(coeff * area), Foam::sumOp()) / total_area; + + // set gradient + std::fill(foam_gradient.begin(), foam_gradient.end(), _pp_value / coeff_bulk); + } + else // if no diffusivity coefficient grad_array is just the gradient so fill + { + std::fill(foam_gradient.begin(), foam_gradient.end(), _pp_value); + } + } +} diff --git a/src/bcs/FoamFixedValuePosprocessorBC.C b/src/bcs/FoamFixedValuePosprocessorBC.C new file mode 100644 index 00000000..162a3bab --- /dev/null +++ b/src/bcs/FoamFixedValuePosprocessorBC.C @@ -0,0 +1,33 @@ +#include "FoamFixedValuePostprocessorBC.h" + +InputParameters +FoamFixedValuePostprocessorBC::validParams() +{ + return FoamPostprocessorBCBase::validParams(); +} + +FoamFixedValuePostprocessorBC::FoamFixedValuePostprocessorBC(const InputParameters & params) + : FoamPostprocessorBCBase(params) +{ +} + +void +FoamFixedValuePostprocessorBC::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); + for (auto subdomain : subdomains) + { + // Get underlying field from OpenFOAM boundary patch + auto & foam_var = const_cast &>( + foam_mesh.boundary()[subdomain].lookupPatchField( + _foam_variable)); + + assert(var_array.size() == static_cast(foam_var.size())); + + std::fill(foam_var.begin(), foam_var.end(), _pp_value); + } +} From 8d64df29238c2fad2f182fd35bbbe154790f4b3f Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Fri, 7 Nov 2025 13:44:38 +0000 Subject: [PATCH 25/52] Clean up code and register postprocessor BC objects --- include/bcs/FoamFixedValuePostprocessorBC.h | 1 - src/bcs/FoamFixedGradientPostprocessorBC.C | 8 ++++++++ src/bcs/FoamFixedValuePosprocessorBC.C | 3 +++ src/bcs/FoamMassFlowRateMappedInletBC.C | 3 +-- src/bcs/FoamScalarBulkMappedInletBC.C | 1 - 5 files changed, 12 insertions(+), 4 deletions(-) diff --git a/include/bcs/FoamFixedValuePostprocessorBC.h b/include/bcs/FoamFixedValuePostprocessorBC.h index c32041cf..026705c0 100644 --- a/include/bcs/FoamFixedValuePostprocessorBC.h +++ b/include/bcs/FoamFixedValuePostprocessorBC.h @@ -1,7 +1,6 @@ #pragma once #include "FoamPostprocessorBCBase.h" -#include "InputParameters.h" class FoamFixedValuePostprocessorBC : public FoamPostprocessorBCBase { diff --git a/src/bcs/FoamFixedGradientPostprocessorBC.C b/src/bcs/FoamFixedGradientPostprocessorBC.C index c0fba39f..32c896e4 100644 --- a/src/bcs/FoamFixedGradientPostprocessorBC.C +++ b/src/bcs/FoamFixedGradientPostprocessorBC.C @@ -1,8 +1,11 @@ #include "FoamFixedGradientPostprocessorBC.h" #include "PstreamReduceOps.H" +#include "Registry.h" #include "fixedGradientFvPatchFields.H" #include +registerMooseObject("hippoApp", FoamFixedGradientPostprocessorBC); + InputParameters FoamFixedGradientPostprocessorBC::validParams() { @@ -18,6 +21,11 @@ FoamFixedGradientPostprocessorBC::FoamFixedGradientPostprocessorBC(const InputPa : FoamPostprocessorBCBase(params), _diffusivity_coefficient(params.get("diffusivity_coefficient")) { + // check that the diffusivity coefficient is a OpenFOAM scalar field + if (!_diffusivity_coefficient.empty() && + !_mesh->fvMesh().foundObject(_diffusivity_coefficient)) + mooseError( + "Diffusivity coefficient '", _diffusivity_coefficient, "' not a Foam volScalarField"); } void diff --git a/src/bcs/FoamFixedValuePosprocessorBC.C b/src/bcs/FoamFixedValuePosprocessorBC.C index 162a3bab..d1c6afc5 100644 --- a/src/bcs/FoamFixedValuePosprocessorBC.C +++ b/src/bcs/FoamFixedValuePosprocessorBC.C @@ -1,4 +1,7 @@ #include "FoamFixedValuePostprocessorBC.h" +#include "Registry.h" + +registerMooseObject("hippoApp", FoamFixedValuePostprocessorBC); InputParameters FoamFixedValuePostprocessorBC::validParams() diff --git a/src/bcs/FoamMassFlowRateMappedInletBC.C b/src/bcs/FoamMassFlowRateMappedInletBC.C index 8aacad37..33751745 100644 --- a/src/bcs/FoamMassFlowRateMappedInletBC.C +++ b/src/bcs/FoamMassFlowRateMappedInletBC.C @@ -40,8 +40,7 @@ FoamMassFlowRateMappedInletBC::imposeBoundaryCondition() auto & rho = boundary_patch.lookupPatchField("rho"); auto & Sf = boundary_patch.Sf(); - auto m_dot = Foam::sum(g_map & -Sf); - Foam::reduce(m_dot, Foam::sumOp()); + auto m_dot = Foam::returnReduce(Foam::sum(g_map & -Sf), Foam::sumOp()); auto & U_var = const_cast &>( boundary_patch.lookupPatchField("U")); diff --git a/src/bcs/FoamScalarBulkMappedInletBC.C b/src/bcs/FoamScalarBulkMappedInletBC.C index f14b7518..5c01ed8e 100644 --- a/src/bcs/FoamScalarBulkMappedInletBC.C +++ b/src/bcs/FoamScalarBulkMappedInletBC.C @@ -1,6 +1,5 @@ #include "FoamScalarBulkMappedInletBC.h" #include "InputParameters.h" -#include "MooseError.h" #include "MooseTypes.h" #include "PstreamReduceOps.H" #include "Registry.h" From abe149d0a5531806d2785275d89fda187dceaa26 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Fri, 7 Nov 2025 13:45:07 +0000 Subject: [PATCH 26/52] Add tests for postprocessor BCs --- test/tests/bcs/fixed_gradient_pp/foam/0/T | 52 ++++++++++++ .../foam/constant/physicalProperties | 51 +++++++++++ .../foam/system/blockMeshDict | 85 +++++++++++++++++++ .../fixed_gradient_pp/foam/system/controlDict | 44 ++++++++++ .../fixed_gradient_pp/foam/system/fvSchemes | 46 ++++++++++ .../fixed_gradient_pp/foam/system/fvSolution | 49 +++++++++++ test/tests/bcs/fixed_gradient_pp/main.i | 56 ++++++++++++ test/tests/bcs/fixed_gradient_pp/test.py | 27 ++++++ test/tests/bcs/fixed_gradient_pp/tests | 39 +++++++++ test/tests/bcs/fixed_value_pp/foam/0/T | 56 ++++++++++++ .../foam/constant/physicalProperties | 51 +++++++++++ .../fixed_value_pp/foam/system/blockMeshDict | 85 +++++++++++++++++++ .../fixed_value_pp/foam/system/controlDict | 44 ++++++++++ .../bcs/fixed_value_pp/foam/system/fvSchemes | 46 ++++++++++ .../bcs/fixed_value_pp/foam/system/fvSolution | 61 +++++++++++++ test/tests/bcs/fixed_value_pp/main.i | 77 +++++++++++++++++ test/tests/bcs/fixed_value_pp/test.py | 28 ++++++ test/tests/bcs/fixed_value_pp/tests | 19 +++++ test/tests/bcs/laplace_fixed_gradient/tests | 12 +++ test/tests/bcs/receiver_pp/foam/0/T | 52 ++++++++++++ .../foam/constant/physicalProperties | 51 +++++++++++ .../bcs/receiver_pp/foam/system/blockMeshDict | 85 +++++++++++++++++++ .../bcs/receiver_pp/foam/system/controlDict | 44 ++++++++++ .../bcs/receiver_pp/foam/system/fvSchemes | 46 ++++++++++ .../bcs/receiver_pp/foam/system/fvSolution | 49 +++++++++++ test/tests/bcs/receiver_pp/main.i | 48 +++++++++++ test/tests/bcs/receiver_pp/test.py | 27 ++++++ test/tests/bcs/receiver_pp/tests | 39 +++++++++ 28 files changed, 1369 insertions(+) create mode 100644 test/tests/bcs/fixed_gradient_pp/foam/0/T create mode 100644 test/tests/bcs/fixed_gradient_pp/foam/constant/physicalProperties create mode 100644 test/tests/bcs/fixed_gradient_pp/foam/system/blockMeshDict create mode 100644 test/tests/bcs/fixed_gradient_pp/foam/system/controlDict create mode 100644 test/tests/bcs/fixed_gradient_pp/foam/system/fvSchemes create mode 100644 test/tests/bcs/fixed_gradient_pp/foam/system/fvSolution create mode 100644 test/tests/bcs/fixed_gradient_pp/main.i create mode 100644 test/tests/bcs/fixed_gradient_pp/test.py create mode 100644 test/tests/bcs/fixed_gradient_pp/tests create mode 100644 test/tests/bcs/fixed_value_pp/foam/0/T create mode 100644 test/tests/bcs/fixed_value_pp/foam/constant/physicalProperties create mode 100644 test/tests/bcs/fixed_value_pp/foam/system/blockMeshDict create mode 100644 test/tests/bcs/fixed_value_pp/foam/system/controlDict create mode 100644 test/tests/bcs/fixed_value_pp/foam/system/fvSchemes create mode 100644 test/tests/bcs/fixed_value_pp/foam/system/fvSolution create mode 100644 test/tests/bcs/fixed_value_pp/main.i create mode 100644 test/tests/bcs/fixed_value_pp/test.py create mode 100644 test/tests/bcs/fixed_value_pp/tests create mode 100644 test/tests/bcs/receiver_pp/foam/0/T create mode 100644 test/tests/bcs/receiver_pp/foam/constant/physicalProperties create mode 100644 test/tests/bcs/receiver_pp/foam/system/blockMeshDict create mode 100644 test/tests/bcs/receiver_pp/foam/system/controlDict create mode 100644 test/tests/bcs/receiver_pp/foam/system/fvSchemes create mode 100644 test/tests/bcs/receiver_pp/foam/system/fvSolution create mode 100644 test/tests/bcs/receiver_pp/main.i create mode 100644 test/tests/bcs/receiver_pp/test.py create mode 100644 test/tests/bcs/receiver_pp/tests diff --git a/test/tests/bcs/fixed_gradient_pp/foam/0/T b/test/tests/bcs/fixed_gradient_pp/foam/0/T new file mode 100644 index 00000000..6da637de --- /dev/null +++ b/test/tests/bcs/fixed_gradient_pp/foam/0/T @@ -0,0 +1,52 @@ +/*--------------------------------*- 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.; + +boundaryField +{ + left + { + type fixedValue; + value uniform 0.; + } + right + { + type fixedGradient; + gradient uniform 1.; + } + top + { + type zeroGradient; + } + front + { + type zeroGradient; + } + bottom + { + type zeroGradient; + } + back + { + type zeroGradient; + } +} + + +// ************************************************************************* // diff --git a/test/tests/bcs/fixed_gradient_pp/foam/constant/physicalProperties b/test/tests/bcs/fixed_gradient_pp/foam/constant/physicalProperties new file mode 100644 index 00000000..6dab7b1c --- /dev/null +++ b/test/tests/bcs/fixed_gradient_pp/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 2.; // Thermal conductivity [W/(m·K)] + } + equationOfState + { + rho 1; // Density [kg/m^3] + } +} + + +// ************************************************************************* // diff --git a/test/tests/bcs/fixed_gradient_pp/foam/system/blockMeshDict b/test/tests/bcs/fixed_gradient_pp/foam/system/blockMeshDict new file mode 100644 index 00000000..face9ea6 --- /dev/null +++ b/test/tests/bcs/fixed_gradient_pp/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/bcs/fixed_gradient_pp/foam/system/controlDict b/test/tests/bcs/fixed_gradient_pp/foam/system/controlDict new file mode 100644 index 00000000..89301ab0 --- /dev/null +++ b/test/tests/bcs/fixed_gradient_pp/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 32.; + +deltaT 1.; + +writeControl timeStep; + +writeInterval 1; + +writeFormat ascii; + +writePrecision 20; + +writeCompression off; + +timeFormat general; + +timePrecision 20; + +runTimeModifiable true; + +// ************************************************************************* // diff --git a/test/tests/bcs/fixed_gradient_pp/foam/system/fvSchemes b/test/tests/bcs/fixed_gradient_pp/foam/system/fvSchemes new file mode 100644 index 00000000..a24aaf80 --- /dev/null +++ b/test/tests/bcs/fixed_gradient_pp/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/bcs/fixed_gradient_pp/foam/system/fvSolution b/test/tests/bcs/fixed_gradient_pp/foam/system/fvSolution new file mode 100644 index 00000000..639b272d --- /dev/null +++ b/test/tests/bcs/fixed_gradient_pp/foam/system/fvSolution @@ -0,0 +1,49 @@ +/*--------------------------------*- 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-15; + relTol 1e-15; + } + + eFinal + { + $e; + tolerance 1e-15; + relTol 1e-15; + } +} + +PIMPLE +{ +} + +// ************************************************************************* // diff --git a/test/tests/bcs/fixed_gradient_pp/main.i b/test/tests/bcs/fixed_gradient_pp/main.i new file mode 100644 index 00000000..cce2ed4a --- /dev/null +++ b/test/tests/bcs/fixed_gradient_pp/main.i @@ -0,0 +1,56 @@ +[Mesh] + type = FoamMesh + case = 'foam' + foam_patch = 'left right' +[] + +[Variables] + [dummy] + family = MONOMIAL + order = CONSTANT + initial_condition = 999 + [] +[] + +[FoamBCs] + [T_value] + type=FoamFixedValuePostprocessorBC + foam_variable = T + default = 0. + boundary = 'left' + [] + [T_flux] + type=FoamFixedGradientPostprocessorBC + foam_variable = T + boundary = 'right' + diffusivity_coefficient = kappa + pp = T_flux + [] +[] + +[Postprocessors] + [T_flux] + type = ParsedPostprocessor + expression = '2*t' + use_t = true + execute_on = 'INITIAL TIMESTEP_BEGIN' + [] +[] + +[Problem] + type = FoamProblem +[] + +[Executioner] + type = Transient + end_time = 32 + [TimeSteppers] + [foam] + type = FoamControlledTimeStepper + [] + [] +[] + +[Outputs] + exodus = true +[] diff --git a/test/tests/bcs/fixed_gradient_pp/test.py b/test/tests/bcs/fixed_gradient_pp/test.py new file mode 100644 index 00000000..5c89a6fc --- /dev/null +++ b/test/tests/bcs/fixed_gradient_pp/test.py @@ -0,0 +1,27 @@ +"""Tests for imposing BCs in OpenFOAM using MOOSE input file syntax +""" + +import unittest +import fluidfoam as ff +import numpy as np + +from read_hippo_data import get_foam_times #pylint: disable=E0401 + +class TestFoamBCFixedGradient(unittest.TestCase): + """Test class for imposing fixed value BCs in Hippo.""" + def test_fixed_gradient_x(self): + """Test case for imposing fixed value.""" + case_dir = 'foam/' + times = get_foam_times(case_dir)[1:] + + for time in times: + coords = dict(zip(('x','y','z'),ff.readof.readmesh(case_dir))) + + temp = ff.readof.readscalar(case_dir, time, "T") + + temp_ref = coords['x']*np.float64(time) + + temp_diff_max = np.argmax(abs(temp-temp_ref)) + assert np.allclose(temp_ref, temp, rtol=1e-7, atol=1e-12),\ + (f"Max diff ({time}): {abs(temp-temp_ref).max()} " + f"{temp[temp_diff_max]} {temp_ref[temp_diff_max]}") diff --git a/test/tests/bcs/fixed_gradient_pp/tests b/test/tests/bcs/fixed_gradient_pp/tests new file mode 100644 index 00000000..ba30399b --- /dev/null +++ b/test/tests/bcs/fixed_gradient_pp/tests @@ -0,0 +1,39 @@ +[Tests] + [foam_bc_fixed_gradient_pp] + [setup] + type = RunCommand + command = 'bash -c "foamCleanCase -case foam && blockMesh -case foam"' + [] + [diffusivity_coeff_err] + type = RunException + input = main.i + prereq = foam_bc_fixed_gradient_pp/setup + expect_err = "Diffusivity coefficient 'kappa1' not a Foam volScalarField" + cli_args = 'FoamBCs/T_flux/diffusivity_coefficient=kappa1' + allow_warnings = true + [] + [run] + type = RunApp + input = main.i + prereq = foam_bc_fixed_gradient_pp/setup + allow_warnings = true + [] + [verify] + type = PythonUnitTest + input = test.py + prereq = foam_bc_fixed_gradient_pp/run + [] + [run_no_kappa] + type = RunApp + input = main.i + cli_args = "FoamBCs/T_flux/diffusivity_coefficient='' Postprocessors/T_flux/expression='t'" + prereq = foam_bc_fixed_gradient_pp/verify + allow_warnings = true + [] + [verify_no_kappa] + type = PythonUnitTest + input = test.py + prereq = foam_bc_fixed_gradient_pp/run_no_kappa + [] + [] +[] diff --git a/test/tests/bcs/fixed_value_pp/foam/0/T b/test/tests/bcs/fixed_value_pp/foam/0/T new file mode 100644 index 00000000..65a14be8 --- /dev/null +++ b/test/tests/bcs/fixed_value_pp/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/bcs/fixed_value_pp/foam/constant/physicalProperties b/test/tests/bcs/fixed_value_pp/foam/constant/physicalProperties new file mode 100644 index 00000000..96a14c15 --- /dev/null +++ b/test/tests/bcs/fixed_value_pp/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/bcs/fixed_value_pp/foam/system/blockMeshDict b/test/tests/bcs/fixed_value_pp/foam/system/blockMeshDict new file mode 100644 index 00000000..face9ea6 --- /dev/null +++ b/test/tests/bcs/fixed_value_pp/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/bcs/fixed_value_pp/foam/system/controlDict b/test/tests/bcs/fixed_value_pp/foam/system/controlDict new file mode 100644 index 00000000..cb155c26 --- /dev/null +++ b/test/tests/bcs/fixed_value_pp/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/bcs/fixed_value_pp/foam/system/fvSchemes b/test/tests/bcs/fixed_value_pp/foam/system/fvSchemes new file mode 100644 index 00000000..0e534821 --- /dev/null +++ b/test/tests/bcs/fixed_value_pp/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/bcs/fixed_value_pp/foam/system/fvSolution b/test/tests/bcs/fixed_value_pp/foam/system/fvSolution new file mode 100644 index 00000000..59db6a2a --- /dev/null +++ b/test/tests/bcs/fixed_value_pp/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/bcs/fixed_value_pp/main.i b/test/tests/bcs/fixed_value_pp/main.i new file mode 100644 index 00000000..c49df10a --- /dev/null +++ b/test/tests/bcs/fixed_value_pp/main.i @@ -0,0 +1,77 @@ +[Mesh] + type = FoamMesh + case = 'foam' + foam_patch = 'left right bottom top back front' +[] + +[Variables] + [dummy] + family = MONOMIAL + order = CONSTANT + initial_condition = 999 + [] +[] + +[FoamBCs] + [temp1] + type=FoamFixedValuePostprocessorBC + foam_variable = T + boundary = 'left right top' # test boundary restrictions + pp = T_bc1 + [] + [temp2] + type=FoamFixedValuePostprocessorBC + foam_variable = T + boundary = 'bottom front back' # test boundary restrictions + pp = T_bc2 + [] +[] + +[FoamVariables] + [T_shadow] + type = FoamVariableField + foam_variable = 'T' + [] + [e_shadow] + type = FoamVariableField + foam_variable = 'e' + [] + [whf_shadow] + type = FoamFunctionObject + foam_variable = 'wallHeatFlux' + [] +[] + +[Postprocessors] + [T_bc1] + type=ParsedPostprocessor + expression = '0.05 + t' + use_t = true + execute_on='TIMESTEP_BEGIN INITIAL' + [] + [T_bc2] + type=ParsedPostprocessor + expression = '0.05 + 2*t' + use_t = true + execute_on='TIMESTEP_BEGIN INITIAL' + [] +[] + +[Problem] + type = FoamProblem + # Take the boundary temperature from OpenFOAM and set it on the MOOSE mesh. +[] + +[Executioner] + type = Transient + end_time = 0.32 + [TimeSteppers] + [foam] + type = FoamControlledTimeStepper + [] + [] +[] + +[Outputs] + exodus = true +[] diff --git a/test/tests/bcs/fixed_value_pp/test.py b/test/tests/bcs/fixed_value_pp/test.py new file mode 100644 index 00000000..7a5fe9c7 --- /dev/null +++ b/test/tests/bcs/fixed_value_pp/test.py @@ -0,0 +1,28 @@ +"""Tests for imposing BCs in OpenFOAM using MOOSE input file syntax +""" + +import unittest +import fluidfoam as ff +import numpy as np + +from read_hippo_data import get_foam_times #pylint: disable=E0401 + +class TestFoamBCFixedValuePostprocessor(unittest.TestCase): + """Test class for imposing fixed value BCs in Hippo using postprocessors.""" + def test_fixed_value(self): + """Test case for imposing fixed value.""" + case_dir = 'foam/' + boundaries = ['top', 'bottom', 'front', 'back', 'left', 'right'] + times = get_foam_times(case_dir)[1:] + + for time in times: + for boundary in boundaries: + temp = ff.readof.readscalar(case_dir, time, "T", boundary=boundary) + + scale = 1. if boundary in ('left', 'right', 'top') else 2. + temp_ref = 0.05 + scale*np.float64(time) + + temp_diff_max = np.argmax(abs(temp-temp_ref)) + assert np.allclose(temp_ref, temp, rtol=1e-7, atol=1e-12),\ + (f"Max diff {boundary} ({time}): {abs(temp-temp_ref).max()} " + f"{temp[temp_diff_max]} {temp_ref[temp_diff_max]}") diff --git a/test/tests/bcs/fixed_value_pp/tests b/test/tests/bcs/fixed_value_pp/tests new file mode 100644 index 00000000..002cd453 --- /dev/null +++ b/test/tests/bcs/fixed_value_pp/tests @@ -0,0 +1,19 @@ +[Tests] + [foam_bc_action_test] + [setup] + type = RunCommand + command = 'bash -c "foamCleanCase -case foam && blockMesh -case foam"' + [] + [run] + type = RunApp + input = main.i + prereq = foam_bc_action_test/setup + allow_warnings = true + [] + [verify] + type = PythonUnitTest + input = test.py + prereq = foam_bc_action_test/run + [] + [] +[] diff --git a/test/tests/bcs/laplace_fixed_gradient/tests b/test/tests/bcs/laplace_fixed_gradient/tests index ab7bf175..5166c3b1 100644 --- a/test/tests/bcs/laplace_fixed_gradient/tests +++ b/test/tests/bcs/laplace_fixed_gradient/tests @@ -23,5 +23,17 @@ input = test.py prereq = foam_bc_fixed_gradient/run [] + [run_no_kappa] + type = RunApp + input = main.i + cli_args = "FoamBCs/T_flux/diffusivity_coefficient='' AuxKernels/T_flux/expression='t'" + prereq = foam_bc_fixed_gradient/verify + allow_warnings = true + [] + [verify_no_kappa] + type = PythonUnitTest + input = test.py + prereq = foam_bc_fixed_gradient/run_no_kappa + [] [] [] diff --git a/test/tests/bcs/receiver_pp/foam/0/T b/test/tests/bcs/receiver_pp/foam/0/T new file mode 100644 index 00000000..6da637de --- /dev/null +++ b/test/tests/bcs/receiver_pp/foam/0/T @@ -0,0 +1,52 @@ +/*--------------------------------*- 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.; + +boundaryField +{ + left + { + type fixedValue; + value uniform 0.; + } + right + { + type fixedGradient; + gradient uniform 1.; + } + top + { + type zeroGradient; + } + front + { + type zeroGradient; + } + bottom + { + type zeroGradient; + } + back + { + type zeroGradient; + } +} + + +// ************************************************************************* // diff --git a/test/tests/bcs/receiver_pp/foam/constant/physicalProperties b/test/tests/bcs/receiver_pp/foam/constant/physicalProperties new file mode 100644 index 00000000..6dab7b1c --- /dev/null +++ b/test/tests/bcs/receiver_pp/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 2.; // Thermal conductivity [W/(m·K)] + } + equationOfState + { + rho 1; // Density [kg/m^3] + } +} + + +// ************************************************************************* // diff --git a/test/tests/bcs/receiver_pp/foam/system/blockMeshDict b/test/tests/bcs/receiver_pp/foam/system/blockMeshDict new file mode 100644 index 00000000..face9ea6 --- /dev/null +++ b/test/tests/bcs/receiver_pp/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/bcs/receiver_pp/foam/system/controlDict b/test/tests/bcs/receiver_pp/foam/system/controlDict new file mode 100644 index 00000000..89301ab0 --- /dev/null +++ b/test/tests/bcs/receiver_pp/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 32.; + +deltaT 1.; + +writeControl timeStep; + +writeInterval 1; + +writeFormat ascii; + +writePrecision 20; + +writeCompression off; + +timeFormat general; + +timePrecision 20; + +runTimeModifiable true; + +// ************************************************************************* // diff --git a/test/tests/bcs/receiver_pp/foam/system/fvSchemes b/test/tests/bcs/receiver_pp/foam/system/fvSchemes new file mode 100644 index 00000000..a24aaf80 --- /dev/null +++ b/test/tests/bcs/receiver_pp/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/bcs/receiver_pp/foam/system/fvSolution b/test/tests/bcs/receiver_pp/foam/system/fvSolution new file mode 100644 index 00000000..639b272d --- /dev/null +++ b/test/tests/bcs/receiver_pp/foam/system/fvSolution @@ -0,0 +1,49 @@ +/*--------------------------------*- 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-15; + relTol 1e-15; + } + + eFinal + { + $e; + tolerance 1e-15; + relTol 1e-15; + } +} + +PIMPLE +{ +} + +// ************************************************************************* // diff --git a/test/tests/bcs/receiver_pp/main.i b/test/tests/bcs/receiver_pp/main.i new file mode 100644 index 00000000..cd1da1a7 --- /dev/null +++ b/test/tests/bcs/receiver_pp/main.i @@ -0,0 +1,48 @@ +[Mesh] + type = FoamMesh + case = 'foam' + foam_patch = 'left right' +[] + +[Variables] + [dummy] + family = MONOMIAL + order = CONSTANT + initial_condition = 999 + [] +[] + +[FoamBCs] + [T_value] + type=FoamFixedValuePostprocessorBC + foam_variable = T + default = 0. + boundary = 'left' + [] + [T_flux] + type=FoamFixedGradientPostprocessorBC + foam_variable = T + boundary = 'right' + diffusivity_coefficient = kappa + default=2 + [] +[] + + +[Problem] + type = FoamProblem +[] + +[Executioner] + type = Transient + end_time = 1 + [TimeSteppers] + [foam] + type = FoamControlledTimeStepper + [] + [] +[] + +[Outputs] + exodus = true +[] diff --git a/test/tests/bcs/receiver_pp/test.py b/test/tests/bcs/receiver_pp/test.py new file mode 100644 index 00000000..5c89a6fc --- /dev/null +++ b/test/tests/bcs/receiver_pp/test.py @@ -0,0 +1,27 @@ +"""Tests for imposing BCs in OpenFOAM using MOOSE input file syntax +""" + +import unittest +import fluidfoam as ff +import numpy as np + +from read_hippo_data import get_foam_times #pylint: disable=E0401 + +class TestFoamBCFixedGradient(unittest.TestCase): + """Test class for imposing fixed value BCs in Hippo.""" + def test_fixed_gradient_x(self): + """Test case for imposing fixed value.""" + case_dir = 'foam/' + times = get_foam_times(case_dir)[1:] + + for time in times: + coords = dict(zip(('x','y','z'),ff.readof.readmesh(case_dir))) + + temp = ff.readof.readscalar(case_dir, time, "T") + + temp_ref = coords['x']*np.float64(time) + + temp_diff_max = np.argmax(abs(temp-temp_ref)) + assert np.allclose(temp_ref, temp, rtol=1e-7, atol=1e-12),\ + (f"Max diff ({time}): {abs(temp-temp_ref).max()} " + f"{temp[temp_diff_max]} {temp_ref[temp_diff_max]}") diff --git a/test/tests/bcs/receiver_pp/tests b/test/tests/bcs/receiver_pp/tests new file mode 100644 index 00000000..01645088 --- /dev/null +++ b/test/tests/bcs/receiver_pp/tests @@ -0,0 +1,39 @@ +[Tests] + [receiver_pp] + [setup] + type = RunCommand + command = 'bash -c "foamCleanCase -case foam && blockMesh -case foam"' + [] + [diffusivity_coeff_err] + type = RunException + input = main.i + prereq = receiver_pp/setup + expect_err = "Diffusivity coefficient 'kappa1' not a Foam volScalarField" + cli_args = 'FoamBCs/T_flux/diffusivity_coefficient=kappa1' + allow_warnings = true + [] + [run] + type = RunApp + input = main.i + prereq = receiver_pp/setup + allow_warnings = true + [] + [verify] + type = PythonUnitTest + input = test.py + prereq = receiver_pp/run + [] + [run_no_kappa] + type = RunApp + input = main.i + cli_args = "FoamBCs/T_flux/diffusivity_coefficient='' FoamBCs/T_flux/default=1" + prereq = receiver_pp/verify + allow_warnings = true + [] + [verify_no_kappa] + type = PythonUnitTest + input = test.py + prereq = receiver_pp/run_no_kappa + [] + [] +[] From fc57ab20d12ae0bf621f40c68b54c766d398a1c4 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Sat, 8 Nov 2025 11:34:33 +0000 Subject: [PATCH 27/52] Improve mapped inlet tests, in particular the different bounding box conditions --- src/bcs/FoamMappedInletBCBase.C | 15 ++++ src/bcs/FoamScalarBulkMappedInletBC.C | 1 - test/tests/bcs/mapped_inlet/foam/0/T | 4 +- test/tests/bcs/mapped_inlet/main.i | 30 +++++++- test/tests/bcs/mapped_inlet/main_rotated.i | 50 ++++++++++++++ test/tests/bcs/mapped_inlet/test.py | 80 +++++++++++++--------- test/tests/bcs/mapped_inlet/tests | 40 ++++++++++- 7 files changed, 183 insertions(+), 37 deletions(-) create mode 100644 test/tests/bcs/mapped_inlet/main_rotated.i diff --git a/src/bcs/FoamMappedInletBCBase.C b/src/bcs/FoamMappedInletBCBase.C index 466c0c60..fc7e001c 100644 --- a/src/bcs/FoamMappedInletBCBase.C +++ b/src/bcs/FoamMappedInletBCBase.C @@ -213,6 +213,7 @@ FoamMappedInletBCBase::createPatchProcMap() if (isInletProc) { + std::set all_indices; for (auto & proc : map_procs) { int size; @@ -222,6 +223,20 @@ FoamMappedInletBCBase::createPatchProcMap() MPI_Recv(recv_indices.data(), size, MPI_INT, proc, 1, _mpi_comm, MPI_STATUS_IGNORE); for (auto index : recv_indices) _recv_map[proc].push_back(index); + + all_indices.insert(recv_indices.begin(), recv_indices.end()); + } + + for (int i = 0; i < face_centres.size(); ++i) + { + if (all_indices.count(i) == 0) + mooseError("Face centre at location (", + face_centres[i][0], + ",", + face_centres[i][1], + ",", + face_centres[i][2], + ") does not have a mapped plane location"); } } } diff --git a/src/bcs/FoamScalarBulkMappedInletBC.C b/src/bcs/FoamScalarBulkMappedInletBC.C index 5c01ed8e..59639f0d 100644 --- a/src/bcs/FoamScalarBulkMappedInletBC.C +++ b/src/bcs/FoamScalarBulkMappedInletBC.C @@ -56,7 +56,6 @@ FoamScalarBulkMappedInletBC::applyScaleMethod(T & var, const Real bulk_ref, cons { if (_scale_method == "SCALE") { - std::cout << bulk << " " << bulk_ref << std::endl; return (var * bulk_ref / bulk)(); } else if (_scale_method == "SUBTRACT") diff --git a/test/tests/bcs/mapped_inlet/foam/0/T b/test/tests/bcs/mapped_inlet/foam/0/T index 8bb7faf1..69c3f725 100644 --- a/test/tests/bcs/mapped_inlet/foam/0/T +++ b/test/tests/bcs/mapped_inlet/foam/0/T @@ -37,7 +37,7 @@ boundaryField } bottom { - type calculated; + type fixedValue; value uniform 0.; } back @@ -47,7 +47,7 @@ boundaryField } front { - type calculated; + type fixedValue; value uniform 0.; } } diff --git a/test/tests/bcs/mapped_inlet/main.i b/test/tests/bcs/mapped_inlet/main.i index 7641e38b..a8abf54c 100644 --- a/test/tests/bcs/mapped_inlet/main.i +++ b/test/tests/bcs/mapped_inlet/main.i @@ -5,19 +5,45 @@ [] [FoamBCs] - [mass_flow] + [mass_flowx] type=FoamMassFlowRateMappedInletBC boundary = 'left' default = 1 translation_vector = '0.5 0 0' [] - [temp] + [tempx] type=FoamScalarBulkMappedInletBC boundary = 'left' default = 1 translation_vector = '0.5 0 0' foam_variable = 'T' [] + [mass_flowy] + type=FoamMassFlowRateMappedInletBC + boundary = 'bottom' + default = 1 + translation_vector = '0 0.5 0' + [] + [tempy] + type=FoamScalarBulkMappedInletBC + boundary = 'bottom' + default = 1 + translation_vector = '0 0.5 0' + foam_variable = 'T' + [] + [mass_flowz] + type=FoamMassFlowRateMappedInletBC + boundary = 'front' + default = 1 + translation_vector = '0 0 0.5' + [] + [tempz] + type=FoamScalarBulkMappedInletBC + boundary = 'front' + default = 1 + translation_vector = '0 0 0.5' + foam_variable = 'T' + [] [] [Postprocessors] diff --git a/test/tests/bcs/mapped_inlet/main_rotated.i b/test/tests/bcs/mapped_inlet/main_rotated.i new file mode 100644 index 00000000..7810053d --- /dev/null +++ b/test/tests/bcs/mapped_inlet/main_rotated.i @@ -0,0 +1,50 @@ +[Mesh] + type = FoamMesh + case = 'foam' + foam_patch = 'left right bottom top back front' +[] + +[FoamBCs] + [mass_flowx] + type=FoamMassFlowRateMappedInletBC + boundary = 'left' + default = 1 + translation_vector = '${fparse sqrt(0.125)} ${fparse sqrt(0.125)} 0' + [] + [tempx] + type=FoamScalarBulkMappedInletBC + boundary = 'left' + default = 1 + translation_vector = '${fparse sqrt(0.125)} ${fparse sqrt(0.125)} 0' + foam_variable = 'T' + [] +[] + +[Postprocessors] + [pp] + type = ParsedPostprocessor + expression = '2' + execute_on = TIMESTEP_BEGIN + [] +[] + + +[Problem] + type = FoamProblem + # Take the boundary temperature from OpenFOAM and set it on the MOOSE mesh. +[] + +[Executioner] + type = Transient + end_time = 5 + [TimeSteppers] + [foam] + type = FoamControlledTimeStepper + [] + [] +[] + +[Outputs] + exodus = true + csv=true +[] diff --git a/test/tests/bcs/mapped_inlet/test.py b/test/tests/bcs/mapped_inlet/test.py index 22af5b04..e13ae72a 100644 --- a/test/tests/bcs/mapped_inlet/test.py +++ b/test/tests/bcs/mapped_inlet/test.py @@ -7,40 +7,58 @@ from read_hippo_data import get_foam_times +CASE_DIR = 'foam/' +TIMES = get_foam_times(CASE_DIR)[1:] + + class TestFoamBCMappedInlet(unittest.TestCase): """Test class for mapped inlet BCs in Hippo.""" def test_mapped_inlet(self): """Test case for mapped inlet.""" - case_dir = 'foam/' - times = get_foam_times(case_dir)[1:] + + for i in range(len(TIMES)): + self._check_u_temp_refs(i, 'left', [0.5, 0, 0]) + self._check_u_temp_refs(i, 'bottom', [0, 0.5, 0]) + self._check_u_temp_refs(i, 'front', [0, 0, 0.5]) + + def test_mapped_inlet_rotated(self): + """Test case for when inlet's are not aligned with the axis.""" + for i in range(len(TIMES)): + self._check_u_temp_refs(i, 'left', [np.sqrt(0.125), np.sqrt(0.125), 0]) + + def _check_u_temp_refs(self, idx, boundary, offset): rho = 0.5 - for i, time in enumerate(times): - u = ff.readof.readvector(case_dir, time, "U", boundary='left') - temp = ff.readof.readscalar(case_dir, time, "T", boundary='left') - - if time != times[0]: - x, y, z = ff.readof.readmesh(case_dir, boundary='left') - t = np.float64(times[i-1]) - x += 0.5 - u_ref = np.array([x + y + z + t, x - y + z + t, x + y - z + t,]) - temp_ref = np.sqrt(x*x + y*y + z*z) + t - else: - # first time step uses initialised value - u_ref = np.array([1, -0.5, 0.25])[:,None] - temp_ref = 2 - - rho = 0.5 - mdot = rho*np.mean(u_ref[0]) - mdot_pp = 1 - u_ref *= mdot_pp/mdot - - t_pp = 1 - t_bulk = np.mean(temp_ref) - temp_ref *= t_pp/t_bulk - - assert np.allclose(u_ref, u, rtol=1e-7, atol=1e-12),\ - f"Max diff (velocity) ({time}): {abs(u-u_ref).max()} " - - assert np.allclose(temp_ref, temp, rtol=1e-7, atol=1e-12),\ - f"Max diff (temperature) ({time}): {abs(temp-temp_ref).max()} {temp} {temp_ref}" + mdot_pp = 1 + t_pp = 1 + time = TIMES[idx] + + x, y, z = ff.readof.readmesh(CASE_DIR, boundary=boundary) + u = ff.readof.readvector(CASE_DIR, time, "U", boundary=boundary).T + temp = ff.readof.readscalar(CASE_DIR, time, "T", boundary=boundary) + + x += offset[0] + y += offset[1] + z += offset[2] + + if idx != 0: + t = np.float64(TIMES[idx-1]) + u_ref = np.array([x + y + z + t, x - y + z + t, x + y - z + t,]).T + temp_ref = np.sqrt(x*x + y*y + z*z) + t + else: + # first time step uses initialised value + u_ref = np.array([[1, -0.5, 0.25]]) + temp_ref = 2 + + normal = np.array(offset)/np.linalg.norm(offset) + mdot = rho*np.mean(np.vecdot(u_ref, normal)) + u_ref *= mdot_pp/mdot + + t_bulk = np.mean(temp_ref) + temp_ref *= t_pp/t_bulk + + assert np.allclose(u_ref, u, rtol=1e-7, atol=1e-12),\ + f"Max diff ({boundary}) (velocity) ({TIMES[idx]}): {abs(u-u_ref).max()} " + + assert np.allclose(temp_ref, temp, rtol=1e-7, atol=1e-12),\ + f"Max diff ({boundary}) (temperature) ({time}): {abs(temp-temp_ref).max()} {temp} {temp_ref}" diff --git a/test/tests/bcs/mapped_inlet/tests b/test/tests/bcs/mapped_inlet/tests index 9ec3256f..058753c4 100644 --- a/test/tests/bcs/mapped_inlet/tests +++ b/test/tests/bcs/mapped_inlet/tests @@ -4,6 +4,16 @@ type = RunCommand command = 'bash -c "foamCleanCase -case foam && blockMesh -case foam && decomposePar -case foam"' [] + [run_err] + type = RunException + input = main.i + prereq = mapped_mass_flow_receiver/setup + allow_warnings = true + min_parallel = 5 + max_parallel = 5 + cli_args = "FoamBCs/mass_flowx/translation_vector='-0.5 0 0'" + expect_err = "does not have a mapped plane location" + [] [run] type = RunApp input = main.i @@ -21,6 +31,7 @@ type = PythonUnitTest input = test.py prereq = mapped_mass_flow_receiver/reconstruct + test_case = 'TestFoamBCMappedInlet.test_mapped_inlet' [] [] [mapped_mass_flow] @@ -36,7 +47,7 @@ allow_warnings = true min_parallel = 5 max_parallel = 5 - cli_args = 'FoamBCs/mass_flow/pp=pp FoamBCs/temp/pp=pp Postprocessors/pp/expression=1' + cli_args = 'FoamBCs/mass_flowx/pp=pp FoamBCs/tempx/pp=pp FoamBCs/mass_flowy/pp=pp FoamBCs/tempy/pp=pp FoamBCs/mass_flowz/pp=pp FoamBCs/tempz/pp=pp Postprocessors/pp/expression=1' [] [reconstruct] type = RunCommand @@ -47,6 +58,33 @@ type = PythonUnitTest input = test.py prereq = mapped_mass_flow/reconstruct + test_case = 'TestFoamBCMappedInlet.test_mapped_inlet' + [] + [] + [mapped_rotated] + [setup] + type = RunCommand + command = 'bash -c "foamCleanCase -case foam && blockMesh -case foam && transformPoints -case foam "Rz=45" && decomposePar -case foam"' + prereq = mapped_mass_flow/reconstruct + [] + [run] + type = RunApp + input = main_rotated.i + prereq = mapped_rotated/setup + allow_warnings = true + min_parallel = 5 + max_parallel = 5 + [] + [reconstruct] + type = RunCommand + command = 'reconstructPar -case foam' + prereq = mapped_rotated/run + [] + [verify] + type = PythonUnitTest + input = test.py + prereq = mapped_rotated/reconstruct + test_case = 'TestFoamBCMappedInlet.test_mapped_inlet_rotated' [] [] [] From 336a5140aa24ac9a764f6a4aa7b795340eda99d0 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Sat, 8 Nov 2025 11:46:49 +0000 Subject: [PATCH 28/52] Add test for the mapped inlet subtract scaling method --- test/tests/bcs/mapped_inlet/test.py | 16 ++++++++++++++-- test/tests/bcs/mapped_inlet/tests | 26 ++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/test/tests/bcs/mapped_inlet/test.py b/test/tests/bcs/mapped_inlet/test.py index e13ae72a..26877d1d 100644 --- a/test/tests/bcs/mapped_inlet/test.py +++ b/test/tests/bcs/mapped_inlet/test.py @@ -22,12 +22,20 @@ def test_mapped_inlet(self): self._check_u_temp_refs(i, 'bottom', [0, 0.5, 0]) self._check_u_temp_refs(i, 'front', [0, 0, 0.5]) + def test_mapped_inlet_subtract(self): + """Test case for mapped inlet when temperature is scaled by subtracting the difference in bulk.""" + + for i in range(len(TIMES)): + self._check_u_temp_refs(i, 'left', [0.5, 0, 0], False) + self._check_u_temp_refs(i, 'bottom', [0, 0.5, 0], False) + self._check_u_temp_refs(i, 'front', [0, 0, 0.5], False) + def test_mapped_inlet_rotated(self): """Test case for when inlet's are not aligned with the axis.""" for i in range(len(TIMES)): self._check_u_temp_refs(i, 'left', [np.sqrt(0.125), np.sqrt(0.125), 0]) - def _check_u_temp_refs(self, idx, boundary, offset): + def _check_u_temp_refs(self, idx, boundary, offset, use_scale=True): rho = 0.5 mdot_pp = 1 t_pp = 1 @@ -55,7 +63,11 @@ def _check_u_temp_refs(self, idx, boundary, offset): u_ref *= mdot_pp/mdot t_bulk = np.mean(temp_ref) - temp_ref *= t_pp/t_bulk + if use_scale: + temp_ref *= t_pp/t_bulk + else: + temp_ref += (t_pp - t_bulk) + assert np.allclose(u_ref, u, rtol=1e-7, atol=1e-12),\ f"Max diff ({boundary}) (velocity) ({TIMES[idx]}): {abs(u-u_ref).max()} " diff --git a/test/tests/bcs/mapped_inlet/tests b/test/tests/bcs/mapped_inlet/tests index 058753c4..d6fed4a0 100644 --- a/test/tests/bcs/mapped_inlet/tests +++ b/test/tests/bcs/mapped_inlet/tests @@ -34,6 +34,32 @@ test_case = 'TestFoamBCMappedInlet.test_mapped_inlet' [] [] + [mapped_mass_flow_subtract] + [setup] + type = RunCommand + command = 'bash -c "foamCleanCase -case foam && blockMesh -case foam && decomposePar -case foam"' + [] + [run] + type = RunApp + input = main.i + prereq = mapped_mass_flow_receiver/setup + allow_warnings = true + min_parallel = 5 + max_parallel = 5 + cli_args = "FoamBCs/tempx/scale_method=subtract FoamBCs/tempy/scale_method=subtract FoamBCs/tempz/scale_method=subtract" + [] + [reconstruct] + type = RunCommand + command = 'reconstructPar -case foam' + prereq = mapped_mass_flow_receiver/run + [] + [verify] + type = PythonUnitTest + input = test.py + prereq = mapped_mass_flow_receiver/reconstruct + test_case = 'TestFoamBCMappedInlet.test_mapped_inlet_subtract' + [] + [] [mapped_mass_flow] [setup] type = RunCommand From 91d5a71eb2e38ff4afa395be9c9395b99ec46422 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Sat, 8 Nov 2025 18:02:41 +0000 Subject: [PATCH 29/52] Improve tests and code after review --- include/bcs/FoamBCBase.h | 1 + include/bcs/FoamFixedGradientPostprocessorBC.h | 1 + include/bcs/FoamFixedValuePostprocessorBC.h | 1 + include/bcs/FoamMappedInletBCBase.h | 4 ++++ src/actions/AddFoamBCAction.C | 1 + src/bcs/FoamFixedGradientPostprocessorBC.C | 1 + src/bcs/FoamMappedInletBCBase.C | 12 ++++++++---- src/bcs/FoamMassFlowRateMappedInletBC.C | 2 +- src/bcs/FoamPostprocessorBCBase.C | 2 +- src/bcs/FoamScalarBulkMappedInletBC.C | 2 +- .../bcs/mapped_inlet/foam/system/blockMeshDict | 14 +++++++------- test/tests/bcs/mapped_inlet/main.i | 12 ++++++------ test/tests/bcs/mapped_inlet/main_rotated.i | 4 ++-- test/tests/bcs/mapped_inlet/test.py | 18 +++++++++--------- 14 files changed, 44 insertions(+), 31 deletions(-) diff --git a/include/bcs/FoamBCBase.h b/include/bcs/FoamBCBase.h index 78c0d0b4..bce3c3d5 100644 --- a/include/bcs/FoamBCBase.h +++ b/include/bcs/FoamBCBase.h @@ -46,6 +46,7 @@ class FoamBCBase : public MooseObject, public Coupleable virtual void initialSetup() = 0; + // Add information about BC to table virtual void addInfoRow(BCInfoTable & table) = 0; protected: diff --git a/include/bcs/FoamFixedGradientPostprocessorBC.h b/include/bcs/FoamFixedGradientPostprocessorBC.h index 4e0199b8..5f35fd37 100644 --- a/include/bcs/FoamFixedGradientPostprocessorBC.h +++ b/include/bcs/FoamFixedGradientPostprocessorBC.h @@ -10,6 +10,7 @@ class FoamFixedGradientPostprocessorBC : public FoamPostprocessorBCBase FoamFixedGradientPostprocessorBC(const InputParameters & params); + // impose boundary condition virtual void imposeBoundaryCondition() override; protected: diff --git a/include/bcs/FoamFixedValuePostprocessorBC.h b/include/bcs/FoamFixedValuePostprocessorBC.h index 026705c0..57010a45 100644 --- a/include/bcs/FoamFixedValuePostprocessorBC.h +++ b/include/bcs/FoamFixedValuePostprocessorBC.h @@ -9,5 +9,6 @@ class FoamFixedValuePostprocessorBC : public FoamPostprocessorBCBase FoamFixedValuePostprocessorBC(const InputParameters & params); + // Impose boundary conditions (to be called from FoamProblem class) virtual void imposeBoundaryCondition() override; }; diff --git a/include/bcs/FoamMappedInletBCBase.h b/include/bcs/FoamMappedInletBCBase.h index 7b879c8e..6c250836 100644 --- a/include/bcs/FoamMappedInletBCBase.h +++ b/include/bcs/FoamMappedInletBCBase.h @@ -27,13 +27,17 @@ class FoamMappedInletBCBase : public FoamPostprocessorBCBase MPI_Comm _mpi_comm; + // create send and receive information for mapping void createPatchProcMap(); + // get array from mapped plane on the inlet processes template Foam::Field getMappedArray(const Foam::word & name); + // check if bounding box intersects with rank bool intersectMapPlane(const Foam::fvMesh & mesh, Real cart_bbox[6]); + // create/assign communicators for the transfers between map and inlet planes void createMapComm(const Foam::fvMesh & mesh, Foam::vectorField face_centres, std::vector & send_process, diff --git a/src/actions/AddFoamBCAction.C b/src/actions/AddFoamBCAction.C index 5ef83a81..3590ae9a 100644 --- a/src/actions/AddFoamBCAction.C +++ b/src/actions/AddFoamBCAction.C @@ -30,6 +30,7 @@ AddFoamBCAction::act() if (findParamKey(_moose_object_pars, "v") && !_moose_object_pars.isParamSetByUser("v")) createAuxVariable(); + // Create receiver if pp not provided and pp is an allowed parameter if (findParamKey(_moose_object_pars, "pp") && !_moose_object_pars.isParamSetByUser("pp")) createReceiver(*foam_problem); diff --git a/src/bcs/FoamFixedGradientPostprocessorBC.C b/src/bcs/FoamFixedGradientPostprocessorBC.C index 32c896e4..392311aa 100644 --- a/src/bcs/FoamFixedGradientPostprocessorBC.C +++ b/src/bcs/FoamFixedGradientPostprocessorBC.C @@ -56,6 +56,7 @@ FoamFixedGradientPostprocessorBC::imposeBoundaryCondition() auto & coeff = foam_mesh.boundary()[subdomain].lookupPatchField( _diffusivity_coefficient); + // Calculate the bulk value of the diffusivity coefficient auto area = boundary.magSf(); auto total_area = Foam::returnReduce(Foam::sum(area), Foam::sumOp()); auto coeff_bulk = diff --git a/src/bcs/FoamMappedInletBCBase.C b/src/bcs/FoamMappedInletBCBase.C index fc7e001c..397b2a01 100644 --- a/src/bcs/FoamMappedInletBCBase.C +++ b/src/bcs/FoamMappedInletBCBase.C @@ -12,6 +12,7 @@ namespace { +// Get the cartesian bounding box of the mapped inlet plane void getBBox(const Foam::vectorField points, Real bbox[6]) { @@ -58,6 +59,8 @@ FoamMappedInletBCBase::intersectMapPlane(const Foam::fvMesh & mesh, Real cart_bb } } + // The bbox could by narrower than the cell, check in each direction whether bbox is within the + // cell bbox Real cell_bbox[6] = {DBL_MAX, DBL_MIN, DBL_MAX, DBL_MIN, DBL_MAX, DBL_MIN}; for (auto point : points) { @@ -118,6 +121,7 @@ FoamMappedInletBCBase::createMapComm(const Foam::fvMesh & mesh, map_process.clear(); inlet_process.clear(); + // create list of processes in new communicator and whether they are in the inlet or mapped plane Foam::labelList processes; int j = 0; for (int i = 0; i < Foam::UPstream::nProcs(); ++i) @@ -154,7 +158,7 @@ FoamMappedInletBCBase::createPatchProcMap() std::vector map_procs, inlet_procs; createMapComm(foam_mesh, face_centres, map_procs, inlet_procs); - if (_mpi_comm == MPI_COMM_NULL) + if (_mpi_comm == MPI_COMM_NULL) // process not in mapped or inlet planes return; Foam::PstreamBuffers send_points( @@ -163,7 +167,7 @@ FoamMappedInletBCBase::createPatchProcMap() bool isMapProc = std::find(map_procs.begin(), map_procs.end(), rank) != map_procs.end(); bool isInletProc = std::find(inlet_procs.begin(), inlet_procs.end(), rank) != inlet_procs.end(); - if (isInletProc) + if (isInletProc) // send points from inlet process to all map processes { for (int proc : map_procs) { @@ -177,7 +181,7 @@ FoamMappedInletBCBase::createPatchProcMap() std::vector size_requests(inlet_procs.size()); std::vector data_requests(inlet_procs.size()); - if (isMapProc) + if (isMapProc) // check points from each process to see if they are local { for (int proc : inlet_procs) { @@ -211,7 +215,7 @@ FoamMappedInletBCBase::createPatchProcMap() } } - if (isInletProc) + if (isInletProc) // create map to determine where data from map processes should go { std::set all_indices; for (auto & proc : map_procs) diff --git a/src/bcs/FoamMassFlowRateMappedInletBC.C b/src/bcs/FoamMassFlowRateMappedInletBC.C index 33751745..d0b55d8e 100644 --- a/src/bcs/FoamMassFlowRateMappedInletBC.C +++ b/src/bcs/FoamMassFlowRateMappedInletBC.C @@ -32,7 +32,7 @@ FoamMassFlowRateMappedInletBC::imposeBoundaryCondition() auto & foam_mesh = _mesh->fvMesh(); auto & boundary_patch = foam_mesh.boundary()[_boundary[0]]; - // should we mapping rho U or just U? Fo now U but we can change it + // currently we map mass flux rather than velocity, maybe useful to have option auto && U_map = getMappedArray("U"); auto && rho_map = getMappedArray("rho"); auto g_map = rho_map * U_map; diff --git a/src/bcs/FoamPostprocessorBCBase.C b/src/bcs/FoamPostprocessorBCBase.C index f01508e0..b8323a3d 100644 --- a/src/bcs/FoamPostprocessorBCBase.C +++ b/src/bcs/FoamPostprocessorBCBase.C @@ -23,7 +23,7 @@ FoamPostprocessorBCBase::FoamPostprocessorBCBase(const InputParameters & params) _pp_value(getPostprocessorValueByName(_pp_name)) { if (params.isParamSetByUser("pp") && params.isParamSetByUser("default")) - mooseWarning("'pp' and 'default' should not be set. 'default' ignored."); + mooseWarning("'pp' and 'default' should not both be set. 'default' ignored."); } void diff --git a/src/bcs/FoamScalarBulkMappedInletBC.C b/src/bcs/FoamScalarBulkMappedInletBC.C index 59639f0d..5428e512 100644 --- a/src/bcs/FoamScalarBulkMappedInletBC.C +++ b/src/bcs/FoamScalarBulkMappedInletBC.C @@ -45,7 +45,7 @@ FoamScalarBulkMappedInletBC::imposeBoundaryCondition() Foam::reduce(var_bulk, Foam::sumOp()); auto & var = const_cast &>( - boundary_patch.lookupPatchField("T")); + boundary_patch.lookupPatchField(_foam_variable)); var == applyScaleMethod(var_map, _pp_value, var_bulk); } diff --git a/test/tests/bcs/mapped_inlet/foam/system/blockMeshDict b/test/tests/bcs/mapped_inlet/foam/system/blockMeshDict index c8d999e5..8221a4b1 100644 --- a/test/tests/bcs/mapped_inlet/foam/system/blockMeshDict +++ b/test/tests/bcs/mapped_inlet/foam/system/blockMeshDict @@ -9,14 +9,14 @@ FoamFile vertices ( ( 0.0 0.0 0.0 ) - ( 1.0 0.0 0.0 ) - ( 1.0 1.0 0.0 ) - ( 0.0 1.0 0.0 ) + ( 2.0 0.0 0.0 ) + ( 2.0 2.0 0.0 ) + ( 0.0 2.0 0.0 ) - ( 0.0 0.0 1.0) - ( 1.0 0.0 1.0) - ( 1.0 1.0 1.0) - ( 0.0 1.0 1.0) + ( 0.0 0.0 2.0) + ( 2.0 0.0 2.0) + ( 2.0 2.0 2.0) + ( 0.0 2.0 2.0) ); blocks diff --git a/test/tests/bcs/mapped_inlet/main.i b/test/tests/bcs/mapped_inlet/main.i index a8abf54c..50a34648 100644 --- a/test/tests/bcs/mapped_inlet/main.i +++ b/test/tests/bcs/mapped_inlet/main.i @@ -9,39 +9,39 @@ type=FoamMassFlowRateMappedInletBC boundary = 'left' default = 1 - translation_vector = '0.5 0 0' + translation_vector = '1. 0 0' [] [tempx] type=FoamScalarBulkMappedInletBC boundary = 'left' default = 1 - translation_vector = '0.5 0 0' + translation_vector = '1. 0 0' foam_variable = 'T' [] [mass_flowy] type=FoamMassFlowRateMappedInletBC boundary = 'bottom' default = 1 - translation_vector = '0 0.5 0' + translation_vector = '0 1. 0' [] [tempy] type=FoamScalarBulkMappedInletBC boundary = 'bottom' default = 1 - translation_vector = '0 0.5 0' + translation_vector = '0 1. 0' foam_variable = 'T' [] [mass_flowz] type=FoamMassFlowRateMappedInletBC boundary = 'front' default = 1 - translation_vector = '0 0 0.5' + translation_vector = '0 0 1.' [] [tempz] type=FoamScalarBulkMappedInletBC boundary = 'front' default = 1 - translation_vector = '0 0 0.5' + translation_vector = '0 0 1.' foam_variable = 'T' [] [] diff --git a/test/tests/bcs/mapped_inlet/main_rotated.i b/test/tests/bcs/mapped_inlet/main_rotated.i index 7810053d..553b6d3d 100644 --- a/test/tests/bcs/mapped_inlet/main_rotated.i +++ b/test/tests/bcs/mapped_inlet/main_rotated.i @@ -9,13 +9,13 @@ type=FoamMassFlowRateMappedInletBC boundary = 'left' default = 1 - translation_vector = '${fparse sqrt(0.125)} ${fparse sqrt(0.125)} 0' + translation_vector = '${fparse sqrt(0.5)} ${fparse sqrt(0.5)} 0' [] [tempx] type=FoamScalarBulkMappedInletBC boundary = 'left' default = 1 - translation_vector = '${fparse sqrt(0.125)} ${fparse sqrt(0.125)} 0' + translation_vector = '${fparse sqrt(0.5)} ${fparse sqrt(0.5)} 0' foam_variable = 'T' [] [] diff --git a/test/tests/bcs/mapped_inlet/test.py b/test/tests/bcs/mapped_inlet/test.py index 26877d1d..fa36db96 100644 --- a/test/tests/bcs/mapped_inlet/test.py +++ b/test/tests/bcs/mapped_inlet/test.py @@ -16,24 +16,23 @@ class TestFoamBCMappedInlet(unittest.TestCase): def test_mapped_inlet(self): """Test case for mapped inlet.""" - for i in range(len(TIMES)): - self._check_u_temp_refs(i, 'left', [0.5, 0, 0]) - self._check_u_temp_refs(i, 'bottom', [0, 0.5, 0]) - self._check_u_temp_refs(i, 'front', [0, 0, 0.5]) + self._check_u_temp_refs(i, 'left', [1., 0, 0]) + self._check_u_temp_refs(i, 'bottom', [0, 1., 0]) + self._check_u_temp_refs(i, 'front', [0, 0, 1.]) def test_mapped_inlet_subtract(self): """Test case for mapped inlet when temperature is scaled by subtracting the difference in bulk.""" for i in range(len(TIMES)): - self._check_u_temp_refs(i, 'left', [0.5, 0, 0], False) - self._check_u_temp_refs(i, 'bottom', [0, 0.5, 0], False) - self._check_u_temp_refs(i, 'front', [0, 0, 0.5], False) + self._check_u_temp_refs(i, 'left', [1., 0, 0], False) + self._check_u_temp_refs(i, 'bottom', [0, 1., 0], False) + self._check_u_temp_refs(i, 'front', [0, 0, 1.], False) def test_mapped_inlet_rotated(self): """Test case for when inlet's are not aligned with the axis.""" for i in range(len(TIMES)): - self._check_u_temp_refs(i, 'left', [np.sqrt(0.125), np.sqrt(0.125), 0]) + self._check_u_temp_refs(i, 'left', [np.sqrt(0.5), np.sqrt(0.5), 0]) def _check_u_temp_refs(self, idx, boundary, offset, use_scale=True): rho = 0.5 @@ -58,8 +57,9 @@ def _check_u_temp_refs(self, idx, boundary, offset, use_scale=True): u_ref = np.array([[1, -0.5, 0.25]]) temp_ref = 2 + area = 4. normal = np.array(offset)/np.linalg.norm(offset) - mdot = rho*np.mean(np.vecdot(u_ref, normal)) + mdot = rho*np.mean(np.vecdot(u_ref, normal))*area u_ref *= mdot_pp/mdot t_bulk = np.mean(temp_ref) From 6b7e9ae990e7e037200b682cd021e58b68e6cbff Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Mon, 10 Nov 2025 16:45:35 +0000 Subject: [PATCH 30/52] Implement initial fix to edge case where offset is on the cell face --- include/bcs/FoamMappedInletBCBase.h | 35 +++++++++++-- src/bcs/FoamFixedValuePosprocessorBC.C | 2 - src/bcs/FoamMappedInletBCBase.C | 69 ++++++++++++++++++++------ 3 files changed, 84 insertions(+), 22 deletions(-) diff --git a/include/bcs/FoamMappedInletBCBase.h b/include/bcs/FoamMappedInletBCBase.h index 6c250836..44427a06 100644 --- a/include/bcs/FoamMappedInletBCBase.h +++ b/include/bcs/FoamMappedInletBCBase.h @@ -10,11 +10,7 @@ class FoamMappedInletBCBase : public FoamPostprocessorBCBase FoamMappedInletBCBase(const InputParameters & params); - virtual ~FoamMappedInletBCBase() - { - if (Foam::UPstream::parRun()) - Foam::UPstream::freeCommunicator(_foam_comm); - } + virtual ~FoamMappedInletBCBase() { destroyCommunicator(_foam_comm); } protected: Foam::vector _offset; @@ -42,4 +38,33 @@ class FoamMappedInletBCBase : public FoamPostprocessorBCBase Foam::vectorField face_centres, std::vector & send_process, std::vector & recv_process); + + // find index of cell containing point or raise error if not found + int findIndex(const Foam::point & location, const MPI_Comm & comm); + + // handle creation of new communicators in parallel or serial + Foam::label + createCommunicator(const Foam::label parent_comm, std::vector procs, MPI_Comm & new_comm) + { + Foam::label foam_comm; + if (Foam::UPstream::parRun()) + { + Foam::labelList foam_procs(procs.begin(), procs.end()); + foam_comm = Foam::UPstream::allocateCommunicator(parent_comm, foam_procs, true); + new_comm = Foam::PstreamGlobals::MPICommunicators_[foam_comm]; + } + else + { + foam_comm = Foam::UPstream::worldComm; + new_comm = MPI_COMM_WORLD; + } + return foam_comm; + } + + // free communicators if parallel run + void destroyCommunicator(Foam::label comm) + { + if (Foam::UPstream::parRun()) + Foam::UPstream::freeCommunicator(comm); + } }; diff --git a/src/bcs/FoamFixedValuePosprocessorBC.C b/src/bcs/FoamFixedValuePosprocessorBC.C index d1c6afc5..5614196e 100644 --- a/src/bcs/FoamFixedValuePosprocessorBC.C +++ b/src/bcs/FoamFixedValuePosprocessorBC.C @@ -29,8 +29,6 @@ FoamFixedValuePostprocessorBC::imposeBoundaryCondition() foam_mesh.boundary()[subdomain].lookupPatchField( _foam_variable)); - assert(var_array.size() == static_cast(foam_var.size())); - std::fill(foam_var.begin(), foam_var.end(), _pp_value); } } diff --git a/src/bcs/FoamMappedInletBCBase.C b/src/bcs/FoamMappedInletBCBase.C index 397b2a01..70552fdb 100644 --- a/src/bcs/FoamMappedInletBCBase.C +++ b/src/bcs/FoamMappedInletBCBase.C @@ -2,13 +2,12 @@ #include "InputParameters.h" #include "MooseTypes.h" #include "Pstream.H" -#include "Pstream/mpi/PstreamGlobals.H" -#include "labelList.H" #include "mpi.h" #include "UPstream.H" #include "vectorField.H" #include "volFieldsFwd.H" +#include namespace { @@ -122,13 +121,13 @@ FoamMappedInletBCBase::createMapComm(const Foam::fvMesh & mesh, inlet_process.clear(); // create list of processes in new communicator and whether they are in the inlet or mapped plane - Foam::labelList processes; + std::vector processes; int j = 0; for (int i = 0; i < Foam::UPstream::nProcs(); ++i) { if (inlet_procs[i] || map_procs[i]) { - processes.append(i); + processes.push_back(i); if (inlet_procs[i]) inlet_process.push_back(j); if (map_procs[i]) @@ -136,16 +135,8 @@ FoamMappedInletBCBase::createMapComm(const Foam::fvMesh & mesh, ++j; } } - if (!Foam::Pstream::parRun()) - { - _foam_comm = Foam::UPstream::worldComm; - _mpi_comm = MPI_COMM_WORLD; - } - else - { - _foam_comm = Foam::UPstream::allocateCommunicator(Foam::UPstream::worldComm, processes, true); - _mpi_comm = Foam::PstreamGlobals::MPICommunicators_[_foam_comm]; - } + + _foam_comm = createCommunicator(Foam::UPstream::worldComm, processes, _mpi_comm); } void @@ -181,6 +172,9 @@ FoamMappedInletBCBase::createPatchProcMap() std::vector size_requests(inlet_procs.size()); std::vector data_requests(inlet_procs.size()); + MPI_Comm map_comm; + auto foam_map_comm = createCommunicator(_foam_comm, map_procs, map_comm); + if (isMapProc) // check points from each process to see if they are local { for (int proc : inlet_procs) @@ -192,7 +186,7 @@ FoamMappedInletBCBase::createPatchProcMap() std::vector recv_indices; for (int j = 0; j < field.size(); ++j) { - auto index = foam_mesh.findCell(field[j] + _offset, Foam::polyMesh::FACE_PLANES); + auto index = findIndex(field[j] + _offset, map_comm); if (index >= 0) { vec.push_back(index); // assign to send map required indices @@ -215,6 +209,8 @@ FoamMappedInletBCBase::createPatchProcMap() } } + destroyCommunicator(foam_map_comm); + if (isInletProc) // create map to determine where data from map processes should go { std::set all_indices; @@ -245,6 +241,49 @@ FoamMappedInletBCBase::createPatchProcMap() } } +int +FoamMappedInletBCBase::findIndex(const Foam::point & location, const MPI_Comm & comm) +{ + int index = _mesh->fvMesh().findCell(location, Foam::polyMesh::FACE_PLANES); + int gl_index; + MPI_Allreduce(&index, &gl_index, 1, MPI_INT, MPI_MAX, comm); + + // expand cell bounding box and repeat search + if (gl_index < 0) + { + Foam::label celli = _mesh->fvMesh().findNearestCell(location); + + bool in_cell = _mesh->fvMesh().pointInCellBB(location, celli, 0.1); + index = (in_cell) ? celli : -1; + MPI_Allreduce(&index, &gl_index, 1, MPI_INT, MPI_MAX, comm); + + int rank; + MPI_Comm_rank(comm, &rank); + if (gl_index < 0 && rank == 0) + { + mooseError("Face centre at location (", + location[0], + ",", + location[1], + ",", + location[2], + ") does not have a mapped plane location"); + } + } + + // handle if more than one cell found globally: use closest point + // to inlet point + Foam::scalar dist{DBL_MAX}, gl_dist; + if (index != -1) + dist = Foam::mag(_mesh->fvMesh().cellCentres()[index] - location); + + MPI_Allreduce(&dist, &gl_dist, 1, MPI_DOUBLE, MPI_MIN, comm); + if (dist != gl_dist) + index = -1; + + return index; +} + InputParameters FoamMappedInletBCBase::validParams() { From 80275f7053439b8ce4adfefc93d5e4c2790e6171 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Tue, 11 Nov 2025 14:56:36 +0000 Subject: [PATCH 31/52] Fix bugs causing seg faults --- src/bcs/FoamMappedInletBCBase.C | 82 ++++++++++++------ .../foam/system/blockMeshDict.face_edge | 85 +++++++++++++++++++ .../foam/system/blockMeshDict.orig | 85 +++++++++++++++++++ .../foam/system/decomposeParDict.face_edge | 42 +++++++++ .../foam/system/decomposeParDict.orig | 42 +++++++++ test/tests/bcs/mapped_inlet/test.py | 8 ++ test/tests/bcs/mapped_inlet/tests | 37 ++++++++ 7 files changed, 353 insertions(+), 28 deletions(-) create mode 100644 test/tests/bcs/mapped_inlet/foam/system/blockMeshDict.face_edge create mode 100644 test/tests/bcs/mapped_inlet/foam/system/blockMeshDict.orig create mode 100644 test/tests/bcs/mapped_inlet/foam/system/decomposeParDict.face_edge create mode 100644 test/tests/bcs/mapped_inlet/foam/system/decomposeParDict.orig diff --git a/src/bcs/FoamMappedInletBCBase.C b/src/bcs/FoamMappedInletBCBase.C index 70552fdb..655b16a8 100644 --- a/src/bcs/FoamMappedInletBCBase.C +++ b/src/bcs/FoamMappedInletBCBase.C @@ -1,12 +1,16 @@ #include "FoamMappedInletBCBase.h" #include "InputParameters.h" +#include "MooseError.h" #include "MooseTypes.h" #include "Pstream.H" #include "mpi.h" #include "UPstream.H" +#include "petsclog.h" #include "vectorField.H" #include "volFieldsFwd.H" +#include +#include #include namespace @@ -171,19 +175,19 @@ FoamMappedInletBCBase::createPatchProcMap() std::vector size_requests(inlet_procs.size()); std::vector data_requests(inlet_procs.size()); - + std::vector> recv_indices_procs(inlet_procs.size()); MPI_Comm map_comm; auto foam_map_comm = createCommunicator(_foam_comm, map_procs, map_comm); if (isMapProc) // check points from each process to see if they are local { - for (int proc : inlet_procs) + for (auto i = 0lu; i < inlet_procs.size(); ++i) { Foam::vectorField field; - Foam::UIPstream recieve(proc, send_points); + Foam::UIPstream recieve(inlet_procs[i], send_points); recieve >> field; - auto & vec = _send_map[proc]; - std::vector recv_indices; + auto & vec = _send_map[inlet_procs[i]]; + auto & recv_indices = recv_indices_procs[i]; for (int j = 0; j < field.size(); ++j) { auto index = findIndex(field[j] + _offset, map_comm); @@ -194,18 +198,18 @@ FoamMappedInletBCBase::createPatchProcMap() } } if (vec.size() == 0) - _send_map.erase(proc); + _send_map.erase(inlet_procs[i]); // Let original processes know which points will come from each rank - auto size = static_cast(vec.size()); - MPI_Isend(&size, 1, MPI_INT, proc, 0, _mpi_comm, &size_requests[proc]); + int size = recv_indices.size(); + MPI_Isend(&size, 1, MPI_INT, inlet_procs[i], 0, _mpi_comm, &size_requests.at(i)); MPI_Isend(recv_indices.data(), recv_indices.size(), MPI_INT, - proc, + inlet_procs[i], 1, _mpi_comm, - &data_requests[proc]); + &data_requests.at(i)); } } @@ -213,7 +217,6 @@ FoamMappedInletBCBase::createPatchProcMap() if (isInletProc) // create map to determine where data from map processes should go { - std::set all_indices; for (auto & proc : map_procs) { int size; @@ -221,29 +224,31 @@ FoamMappedInletBCBase::createPatchProcMap() std::vector recv_indices(size); MPI_Recv(recv_indices.data(), size, MPI_INT, proc, 1, _mpi_comm, MPI_STATUS_IGNORE); - for (auto index : recv_indices) + for (auto & index : recv_indices) + { + assert(index < face_centres.size()); _recv_map[proc].push_back(index); - - all_indices.insert(recv_indices.begin(), recv_indices.end()); - } - - for (int i = 0; i < face_centres.size(); ++i) - { - if (all_indices.count(i) == 0) - mooseError("Face centre at location (", - face_centres[i][0], - ",", - face_centres[i][1], - ",", - face_centres[i][2], - ") does not have a mapped plane location"); + } } } + MPI_Barrier(_mpi_comm); } int FoamMappedInletBCBase::findIndex(const Foam::point & location, const MPI_Comm & comm) { + /* + This function uses several ways of finding the mapped plane cell + 1. use findCell function + - Sometimes on cell boundaries it may not find the cell or two processes with both find it + 2. If none found, find the closest point and do an expanded bounding box search, raise error + if none still found. + 3. If multiple found, use the cell with cell centre closer to desired location + 4. If still multiple found, use the cell closer to the inlet. + - In the unlikely chance there are still multiple cells detected, raise a warning + Note that it is possible there is some non-deterministic behaviour in the function but this + shouldn't be a problem in practice. + */ int index = _mesh->fvMesh().findCell(location, Foam::polyMesh::FACE_PLANES); int gl_index; MPI_Allreduce(&index, &gl_index, 1, MPI_INT, MPI_MAX, comm); @@ -271,8 +276,7 @@ FoamMappedInletBCBase::findIndex(const Foam::point & location, const MPI_Comm & } } - // handle if more than one cell found globally: use closest point - // to inlet point + // use cell with cell centre closest to the location Foam::scalar dist{DBL_MAX}, gl_dist; if (index != -1) dist = Foam::mag(_mesh->fvMesh().cellCentres()[index] - location); @@ -281,6 +285,28 @@ FoamMappedInletBCBase::findIndex(const Foam::point & location, const MPI_Comm & if (dist != gl_dist) index = -1; + // 2. use cell centre closest to inlet point + int in_cell = index != -1; + MPI_Allreduce(MPI_IN_PLACE, &in_cell, 1, MPI_INT, MPI_SUM, comm); + if (in_cell > 1) + { + if (index != -1) + dist = Foam::mag(_mesh->fvMesh().cellCentres()[index] - (location - _offset)); + MPI_Allreduce(&dist, &gl_dist, 1, MPI_DOUBLE, MPI_MIN, comm); + if (dist != gl_dist) + index = -1; + } + in_cell = index != -1; + MPI_Allreduce(MPI_IN_PLACE, &in_cell, 1, MPI_INT, MPI_SUM, comm); + + if (in_cell > 1) + mooseWarning("More than 1 process found location (", + location[0], + ",", + location[1], + ",", + location[2], + ")"); return index; } diff --git a/test/tests/bcs/mapped_inlet/foam/system/blockMeshDict.face_edge b/test/tests/bcs/mapped_inlet/foam/system/blockMeshDict.face_edge new file mode 100644 index 00000000..4a877e58 --- /dev/null +++ b/test/tests/bcs/mapped_inlet/foam/system/blockMeshDict.face_edge @@ -0,0 +1,85 @@ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object blockMeshDict; +} + +vertices +( + ( 0.0 0.0 0.0 ) + ( 2.0 0.0 0.0 ) + ( 2.0 2.0 0.0 ) + ( 0.0 2.0 0.0 ) + + ( 0.0 0.0 2.0) + ( 2.0 0.0 2.0) + ( 2.0 2.0 2.0) + ( 0.0 2.0 2.0) +); + +blocks +( + hex (0 1 2 3 4 5 6 7) (8 8 8) simpleGrading (1 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/bcs/mapped_inlet/foam/system/blockMeshDict.orig b/test/tests/bcs/mapped_inlet/foam/system/blockMeshDict.orig new file mode 100644 index 00000000..8221a4b1 --- /dev/null +++ b/test/tests/bcs/mapped_inlet/foam/system/blockMeshDict.orig @@ -0,0 +1,85 @@ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object blockMeshDict; +} + +vertices +( + ( 0.0 0.0 0.0 ) + ( 2.0 0.0 0.0 ) + ( 2.0 2.0 0.0 ) + ( 0.0 2.0 0.0 ) + + ( 0.0 0.0 2.0) + ( 2.0 0.0 2.0) + ( 2.0 2.0 2.0) + ( 0.0 2.0 2.0) +); + +blocks +( + hex (0 1 2 3 4 5 6 7) (9 9 9) simpleGrading (1 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/bcs/mapped_inlet/foam/system/decomposeParDict.face_edge b/test/tests/bcs/mapped_inlet/foam/system/decomposeParDict.face_edge new file mode 100644 index 00000000..0204a6b9 --- /dev/null +++ b/test/tests/bcs/mapped_inlet/foam/system/decomposeParDict.face_edge @@ -0,0 +1,42 @@ +/*--------------------------------*- 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 2; + +method simple; + +simpleCoeffs +{ + n (2 1 1); +} + +hierarchicalCoeffs +{ + n (1 1 1); + order xyz; +} + +manualCoeffs +{ + dataFile ""; +} + +distributed no; + +roots ( ); + + +// ************************************************************************* // diff --git a/test/tests/bcs/mapped_inlet/foam/system/decomposeParDict.orig b/test/tests/bcs/mapped_inlet/foam/system/decomposeParDict.orig new file mode 100644 index 00000000..9df2378c --- /dev/null +++ b/test/tests/bcs/mapped_inlet/foam/system/decomposeParDict.orig @@ -0,0 +1,42 @@ +/*--------------------------------*- 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 5; + +method scotch; + +simpleCoeffs +{ + n (2 1 1); +} + +hierarchicalCoeffs +{ + n (1 1 1); + order xyz; +} + +manualCoeffs +{ + dataFile ""; +} + +distributed no; + +roots ( ); + + +// ************************************************************************* // diff --git a/test/tests/bcs/mapped_inlet/test.py b/test/tests/bcs/mapped_inlet/test.py index fa36db96..92d56290 100644 --- a/test/tests/bcs/mapped_inlet/test.py +++ b/test/tests/bcs/mapped_inlet/test.py @@ -34,6 +34,14 @@ def test_mapped_inlet_rotated(self): for i in range(len(TIMES)): self._check_u_temp_refs(i, 'left', [np.sqrt(0.5), np.sqrt(0.5), 0]) + def test_mapped_inlet_face_point(self): + """Test case for mapped inlet where the point is on the interface between boundaries.""" + + for i in range(len(TIMES)): + self._check_u_temp_refs(i, 'left', [7./8, 0, 0]) + self._check_u_temp_refs(i, 'bottom', [0, 7./8, 0]) + self._check_u_temp_refs(i, 'front', [0, 0, 7./8]) + def _check_u_temp_refs(self, idx, boundary, offset, use_scale=True): rho = 0.5 mdot_pp = 1 diff --git a/test/tests/bcs/mapped_inlet/tests b/test/tests/bcs/mapped_inlet/tests index d6fed4a0..cc19eb5a 100644 --- a/test/tests/bcs/mapped_inlet/tests +++ b/test/tests/bcs/mapped_inlet/tests @@ -113,4 +113,41 @@ test_case = 'TestFoamBCMappedInlet.test_mapped_inlet_rotated' [] [] + [face_edge_case] + [update_mesh] + type = RunCommand + command = 'bash -c "foamCleanCase -case foam && cp foam/system/blockMeshDict.face_edge foam/system/blockMeshDict && cp foam/system/decomposeParDict.face_edge foam/system/decomposeParDict"' + prereq = mapped_rotated/verify + [] + [setup] + type = RunCommand + command = 'bash -c "blockMesh -case foam && decomposePar -case foam"' + prereq = face_edge_case/update_mesh + [] + [run] + type = RunApp + input = main.i + prereq = face_edge_case/setup + allow_warnings = true + min_parallel = 2 + max_parallel = 2 + [] + [reconstruct] + type = RunCommand + command = 'reconstructPar -case foam' + prereq = face_edge_case/run + [] + [verify] + type = PythonUnitTest + input = test.py + prereq = face_edge_case/reconstruct + test_case = 'TestFoamBCMappedInlet.test_mapped_inlet_face_point' + [] + [reset_mesh] + type = RunCommand + command = 'bash -c "cp foam/system/blockMeshDict.orig foam/system/blockMeshDict && cp foam/system/decomposeParDict.orig foam/system/decomposeParDict"' + prereq = 'face_edge_case/update_mesh' + [] + [] + [] From e5ba3e67b0a937b1115e7b1b418d92772f45bf71 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Tue, 11 Nov 2025 16:23:22 +0000 Subject: [PATCH 32/52] Add option of not scaling the bulk when using mapped inlet --- include/bcs/FoamMappedInletBCBase.h | 2 +- include/bcs/FoamMassFlowRateMappedInletBC.h | 4 ++++ src/bcs/FoamMappedInletBCBase.C | 19 +++++++++--------- src/bcs/FoamMassFlowRateMappedInletBC.C | 22 +++++++++++++++------ src/bcs/FoamScalarBulkMappedInletBC.C | 9 +++++++-- 5 files changed, 37 insertions(+), 19 deletions(-) diff --git a/include/bcs/FoamMappedInletBCBase.h b/include/bcs/FoamMappedInletBCBase.h index 44427a06..29e31355 100644 --- a/include/bcs/FoamMappedInletBCBase.h +++ b/include/bcs/FoamMappedInletBCBase.h @@ -1,7 +1,7 @@ #pragma once #include "FoamPostprocessorBCBase.h" -#include "UPstream.H" +#include class FoamMappedInletBCBase : public FoamPostprocessorBCBase { diff --git a/include/bcs/FoamMassFlowRateMappedInletBC.h b/include/bcs/FoamMassFlowRateMappedInletBC.h index 0f7be797..fc3b6e35 100644 --- a/include/bcs/FoamMassFlowRateMappedInletBC.h +++ b/include/bcs/FoamMassFlowRateMappedInletBC.h @@ -1,5 +1,6 @@ #pragma once #include "FoamMappedInletBCBase.h" +#include "MooseEnum.h" class FoamMassFlowRateMappedInletBC : public FoamMappedInletBCBase { @@ -9,4 +10,7 @@ class FoamMassFlowRateMappedInletBC : public FoamMappedInletBCBase FoamMassFlowRateMappedInletBC(const InputParameters & params); virtual void imposeBoundaryCondition() override; + +protected: + MooseEnum _scale_method; }; diff --git a/src/bcs/FoamMappedInletBCBase.C b/src/bcs/FoamMappedInletBCBase.C index 655b16a8..9ca25de2 100644 --- a/src/bcs/FoamMappedInletBCBase.C +++ b/src/bcs/FoamMappedInletBCBase.C @@ -1,14 +1,13 @@ #include "FoamMappedInletBCBase.h" -#include "InputParameters.h" -#include "MooseError.h" -#include "MooseTypes.h" -#include "Pstream.H" - -#include "mpi.h" -#include "UPstream.H" -#include "petsclog.h" -#include "vectorField.H" -#include "volFieldsFwd.H" + +#include +#include +#include +#include +#include +#include +#include + #include #include #include diff --git a/src/bcs/FoamMassFlowRateMappedInletBC.C b/src/bcs/FoamMassFlowRateMappedInletBC.C index d0b55d8e..b306a8dd 100644 --- a/src/bcs/FoamMassFlowRateMappedInletBC.C +++ b/src/bcs/FoamMassFlowRateMappedInletBC.C @@ -14,6 +14,12 @@ InputParameters FoamMassFlowRateMappedInletBC::validParams() { auto params = FoamMappedInletBCBase::validParams(); + MooseEnum scaleEnum("SCALE NONE", "SCALE"); + params.addParam("scale_method", + scaleEnum, + "Method used to maintain inlet bulk variable. " + "SCALE means the variable is multiplied by a factor, " + "NONE means the variable is not scaled."); params.remove("foam_variable"); params.addPrivateParam("foam_variable", "U"); @@ -22,7 +28,7 @@ FoamMassFlowRateMappedInletBC::validParams() } FoamMassFlowRateMappedInletBC::FoamMassFlowRateMappedInletBC(const InputParameters & params) - : FoamMappedInletBCBase(params) + : FoamMappedInletBCBase(params), _scale_method(params.get("scale_method")) { } @@ -38,14 +44,18 @@ FoamMassFlowRateMappedInletBC::imposeBoundaryCondition() auto g_map = rho_map * U_map; auto & rho = boundary_patch.lookupPatchField("rho"); - auto & Sf = boundary_patch.Sf(); - - auto m_dot = Foam::returnReduce(Foam::sum(g_map & -Sf), Foam::sumOp()); - auto & U_var = const_cast &>( boundary_patch.lookupPatchField("U")); Foam::vectorField g_var(U_var.size()); - g_var = rho_map * U_map * _pp_value / m_dot; + g_var = rho_map * U_map; + if (_scale_method == "SCALE") + { + auto & Sf = boundary_patch.Sf(); + + auto m_dot = Foam::returnReduce(Foam::sum(g_map & -Sf), Foam::sumOp()); + g_var *= _pp_value / m_dot; + } + U_var == g_var / rho; } diff --git a/src/bcs/FoamScalarBulkMappedInletBC.C b/src/bcs/FoamScalarBulkMappedInletBC.C index 5428e512..f1cb83d9 100644 --- a/src/bcs/FoamScalarBulkMappedInletBC.C +++ b/src/bcs/FoamScalarBulkMappedInletBC.C @@ -13,12 +13,13 @@ InputParameters FoamScalarBulkMappedInletBC::validParams() { auto params = FoamMappedInletBCBase::validParams(); - MooseEnum scaleEnum("SCALE SUBTRACT", "SCALE"); + MooseEnum scaleEnum("SCALE SUBTRACT NONE", "SCALE"); params.addParam("scale_method", scaleEnum, "Method used to maintain inlet bulk variable. " "SCALE means the variable is multiplied by a factor, " - "SUBTRACT means the variable is reduced by constant."); + "SUBTRACT means the variable is reduced by constant," + "NONE means the variable is not scaled."); return params; } @@ -62,6 +63,10 @@ FoamScalarBulkMappedInletBC::applyScaleMethod(T & var, const Real bulk_ref, cons { return (var + bulk_ref - bulk)(); } + else if (_scale_method == "NONE") + { + return var; + } else { mooseError("Invalid scale method '", _scale_method, "'."); From ae8826297e87636d4cfd3bfcc0bdf1c3c937e807 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Sun, 16 Nov 2025 09:49:30 +0000 Subject: [PATCH 33/52] Add scale factor to mass flow rate BCs --- include/bcs/FoamMassFlowRateInletBC.h | 3 +++ include/bcs/FoamMassFlowRateMappedInletBC.h | 2 ++ src/bcs/FoamMassFlowRateInletBC.C | 5 +++-- src/bcs/FoamMassFlowRateMappedInletBC.C | 16 ++++++++++++++-- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/include/bcs/FoamMassFlowRateInletBC.h b/include/bcs/FoamMassFlowRateInletBC.h index 0167e169..741b2b6e 100644 --- a/include/bcs/FoamMassFlowRateInletBC.h +++ b/include/bcs/FoamMassFlowRateInletBC.h @@ -11,4 +11,7 @@ class FoamMassFlowRateInletBC : public FoamPostprocessorBCBase FoamMassFlowRateInletBC(const InputParameters & params); virtual void imposeBoundaryCondition() override; + +protected: + const Real _scale_factor; }; diff --git a/include/bcs/FoamMassFlowRateMappedInletBC.h b/include/bcs/FoamMassFlowRateMappedInletBC.h index fc3b6e35..39b8520f 100644 --- a/include/bcs/FoamMassFlowRateMappedInletBC.h +++ b/include/bcs/FoamMassFlowRateMappedInletBC.h @@ -13,4 +13,6 @@ class FoamMassFlowRateMappedInletBC : public FoamMappedInletBCBase protected: MooseEnum _scale_method; + + Real _scale_factor; }; diff --git a/src/bcs/FoamMassFlowRateInletBC.C b/src/bcs/FoamMassFlowRateInletBC.C index 322f4698..785061cf 100644 --- a/src/bcs/FoamMassFlowRateInletBC.C +++ b/src/bcs/FoamMassFlowRateInletBC.C @@ -11,6 +11,7 @@ FoamMassFlowRateInletBC::validParams() { auto params = FoamPostprocessorBCBase::validParams(); + params.addParam("scale_factor", 1., "Scale factor multiply mass flow rate pp by."); params.remove("foam_variable"); params.addPrivateParam("foam_variable", "U"); @@ -18,7 +19,7 @@ FoamMassFlowRateInletBC::validParams() } FoamMassFlowRateInletBC::FoamMassFlowRateInletBC(const InputParameters & params) - : FoamPostprocessorBCBase(params) + : FoamPostprocessorBCBase(params), _scale_factor(params.get("scale_factor")) { } @@ -38,6 +39,6 @@ FoamMassFlowRateInletBC::imposeBoundaryCondition() boundary_patch.lookupPatchField("U")); auto & rho = boundary_patch.lookupPatchField("rho"); Real area = Foam::returnReduce(Foam::sum(boundary_patch.magSf()), Foam::sumOp()); - U_var == -_pp_value * boundary_patch.nf() / (rho * area); + U_var == -_scale_factor * _pp_value * boundary_patch.nf() / (rho * area); } } diff --git a/src/bcs/FoamMassFlowRateMappedInletBC.C b/src/bcs/FoamMassFlowRateMappedInletBC.C index b306a8dd..88ba1f96 100644 --- a/src/bcs/FoamMassFlowRateMappedInletBC.C +++ b/src/bcs/FoamMassFlowRateMappedInletBC.C @@ -14,6 +14,8 @@ InputParameters FoamMassFlowRateMappedInletBC::validParams() { auto params = FoamMappedInletBCBase::validParams(); + + params.addParam("scale_factor", 1., "Scale factor multiply mass flow rate pp by."); MooseEnum scaleEnum("SCALE NONE", "SCALE"); params.addParam("scale_method", scaleEnum, @@ -28,7 +30,9 @@ FoamMassFlowRateMappedInletBC::validParams() } FoamMassFlowRateMappedInletBC::FoamMassFlowRateMappedInletBC(const InputParameters & params) - : FoamMappedInletBCBase(params), _scale_method(params.get("scale_method")) + : FoamMappedInletBCBase(params), + _scale_method(params.get("scale_method")), + _scale_factor(params.get("scale_factor")) { } @@ -54,7 +58,15 @@ FoamMassFlowRateMappedInletBC::imposeBoundaryCondition() auto & Sf = boundary_patch.Sf(); auto m_dot = Foam::returnReduce(Foam::sum(g_map & -Sf), Foam::sumOp()); - g_var *= _pp_value / m_dot; + if (fabs(m_dot) > 1e-8) + { + g_var *= _scale_factor * _pp_value / m_dot; + } + else + { + auto area = Foam::returnReduce(Foam::sum(boundary_patch.magSf()), Foam::sumOp()); + g_var -= _scale_factor * boundary_patch.nf() * _pp_value / area; + } } U_var == g_var / rho; From eab6a099bf8b789664d27d314de65f25774cef65 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Sun, 16 Nov 2025 12:04:46 +0000 Subject: [PATCH 34/52] Fix bugs after rebase --- include/actions/AddFoamBCAction.h | 4 +++- src/actions/AddFoamBCAction.C | 20 ++++++++++++++++++++ src/bcs/FoamBCBase.C | 3 ++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/include/actions/AddFoamBCAction.h b/include/actions/AddFoamBCAction.h index 33ec6c4e..84853b3d 100644 --- a/include/actions/AddFoamBCAction.h +++ b/include/actions/AddFoamBCAction.h @@ -1,7 +1,9 @@ #pragma once #include "InputParameters.h" -#include "MooseObjectAction.h" +#include "FoamProblem.h" + +#include class AddFoamBCAction : public MooseObjectAction { diff --git a/src/actions/AddFoamBCAction.C b/src/actions/AddFoamBCAction.C index 3590ae9a..84767518 100644 --- a/src/actions/AddFoamBCAction.C +++ b/src/actions/AddFoamBCAction.C @@ -7,6 +7,17 @@ registerMooseAction("hippoApp", AddFoamBCAction, "add_foam_bc"); +namespace +{ +inline bool +findParamKey(const InputParameters & params, const std::string & key) +{ + return std::find_if(params.begin(), + params.end(), + [&](const auto & param) { return param.first == key; }) != params.end(); +} +} + InputParameters AddFoamBCAction::validParams() { @@ -60,3 +71,12 @@ AddFoamBCAction::createAuxVariable() std::static_pointer_cast(_action_factory.create(class_name, name(), action_params)); _awh.addActionBlock(action); } + +void +AddFoamBCAction::createReceiver(FoamProblem & problem) +{ + auto params = _factory.getValidParams("Receiver"); + + Hippo::internal::copyParamFromParam(params, _moose_object_pars, "default"); + problem.addPostprocessor("Receiver", name(), params); +} diff --git a/src/bcs/FoamBCBase.C b/src/bcs/FoamBCBase.C index 742a00f5..bf637bf7 100644 --- a/src/bcs/FoamBCBase.C +++ b/src/bcs/FoamBCBase.C @@ -45,7 +45,8 @@ FoamBCBase::FoamBCBase(const InputParameters & params) _mesh = &problem->mesh(); // check that the foam variable exists - if (!_mesh->foamHasObject(_foam_variable)) + if (!params.isPrivate("foam_variable") && + !_mesh->foamHasObject(_foam_variable)) mooseError("There is no OpenFOAM field named '", _foam_variable, "'"); // check that the boundary is in the FoamMesh From 5d0377f421710393f7b03f5c359b925dd92315e6 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Thu, 18 Dec 2025 15:55:30 +0000 Subject: [PATCH 35/52] Add integrated value foam postprocessor --- include/postprocessors/FoamSideAverageValue.h | 2 +- src/postprocessors/FoamSidePostprocessor.C | 1 - test/tests/bcs/mass_flow_rate/main.i | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/include/postprocessors/FoamSideAverageValue.h b/include/postprocessors/FoamSideAverageValue.h index 12623583..70313bb2 100644 --- a/include/postprocessors/FoamSideAverageValue.h +++ b/include/postprocessors/FoamSideAverageValue.h @@ -5,7 +5,7 @@ class FoamSideAverageValue : public FoamSideIntegratedValue { public: - static InputParameters validParams(); + static InputParameters validParams() { return FoamSideIntegratedValue::validParams(); } FoamSideAverageValue(const InputParameters & params); diff --git a/src/postprocessors/FoamSidePostprocessor.C b/src/postprocessors/FoamSidePostprocessor.C index 5a579413..98bd6b98 100644 --- a/src/postprocessors/FoamSidePostprocessor.C +++ b/src/postprocessors/FoamSidePostprocessor.C @@ -1,7 +1,6 @@ #include "FoamSidePostprocessor.h" #include "InputParameters.h" #include "MooseTypes.h" -#include "FoamProblem.h" InputParameters FoamSidePostprocessor::validParams() diff --git a/test/tests/bcs/mass_flow_rate/main.i b/test/tests/bcs/mass_flow_rate/main.i index dbe15311..43fc5346 100644 --- a/test/tests/bcs/mass_flow_rate/main.i +++ b/test/tests/bcs/mass_flow_rate/main.i @@ -21,7 +21,7 @@ [] [m_dot] type = FoamSideAdvectiveFluxIntegral - block = left + boundary = left foam_scalar = rho [] [] From 66d9c346b51e7f8192218142d83421db57997bb1 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Sat, 7 Feb 2026 10:17:11 +0000 Subject: [PATCH 36/52] Fix errors associated with rebase --- include/postprocessors/FoamSideAverageValue.h | 2 +- test/tests/bcs/fixed_gradient_pp/test.py | 24 +++---- test/tests/bcs/fixed_value_pp/test.py | 26 ++++---- test/tests/bcs/mapped_inlet/test.py | 63 ++++++++++--------- test/tests/bcs/receiver_pp/test.py | 24 +++---- 5 files changed, 76 insertions(+), 63 deletions(-) diff --git a/include/postprocessors/FoamSideAverageValue.h b/include/postprocessors/FoamSideAverageValue.h index 70313bb2..12623583 100644 --- a/include/postprocessors/FoamSideAverageValue.h +++ b/include/postprocessors/FoamSideAverageValue.h @@ -5,7 +5,7 @@ class FoamSideAverageValue : public FoamSideIntegratedValue { public: - static InputParameters validParams() { return FoamSideIntegratedValue::validParams(); } + static InputParameters validParams(); FoamSideAverageValue(const InputParameters & params); diff --git a/test/tests/bcs/fixed_gradient_pp/test.py b/test/tests/bcs/fixed_gradient_pp/test.py index 5c89a6fc..98b48ce7 100644 --- a/test/tests/bcs/fixed_gradient_pp/test.py +++ b/test/tests/bcs/fixed_gradient_pp/test.py @@ -1,27 +1,29 @@ -"""Tests for imposing BCs in OpenFOAM using MOOSE input file syntax -""" +"""Tests for imposing BCs in OpenFOAM using MOOSE input file syntax""" import unittest import fluidfoam as ff import numpy as np -from read_hippo_data import get_foam_times #pylint: disable=E0401 +from read_hippo_data import get_foam_times # pylint: disable=E0401 + class TestFoamBCFixedGradient(unittest.TestCase): """Test class for imposing fixed value BCs in Hippo.""" + def test_fixed_gradient_x(self): """Test case for imposing fixed value.""" - case_dir = 'foam/' - times = get_foam_times(case_dir)[1:] + case_dir = "foam/" + times = get_foam_times(case_dir, string=True)[1:] for time in times: - coords = dict(zip(('x','y','z'),ff.readof.readmesh(case_dir))) + coords = dict(zip(("x", "y", "z"), ff.readof.readmesh(case_dir))) temp = ff.readof.readscalar(case_dir, time, "T") - temp_ref = coords['x']*np.float64(time) + temp_ref = coords["x"] * np.float64(time) - temp_diff_max = np.argmax(abs(temp-temp_ref)) - assert np.allclose(temp_ref, temp, rtol=1e-7, atol=1e-12),\ - (f"Max diff ({time}): {abs(temp-temp_ref).max()} " - f"{temp[temp_diff_max]} {temp_ref[temp_diff_max]}") + temp_diff_max = np.argmax(abs(temp - temp_ref)) + assert np.allclose(temp_ref, temp, rtol=1e-7, atol=1e-12), ( + f"Max diff ({time}): {abs(temp - temp_ref).max()} " + f"{temp[temp_diff_max]} {temp_ref[temp_diff_max]}" + ) diff --git a/test/tests/bcs/fixed_value_pp/test.py b/test/tests/bcs/fixed_value_pp/test.py index 7a5fe9c7..a42a0eed 100644 --- a/test/tests/bcs/fixed_value_pp/test.py +++ b/test/tests/bcs/fixed_value_pp/test.py @@ -1,28 +1,30 @@ -"""Tests for imposing BCs in OpenFOAM using MOOSE input file syntax -""" +"""Tests for imposing BCs in OpenFOAM using MOOSE input file syntax""" import unittest import fluidfoam as ff import numpy as np -from read_hippo_data import get_foam_times #pylint: disable=E0401 +from read_hippo_data import get_foam_times # pylint: disable=E0401 + class TestFoamBCFixedValuePostprocessor(unittest.TestCase): """Test class for imposing fixed value BCs in Hippo using postprocessors.""" + def test_fixed_value(self): """Test case for imposing fixed value.""" - case_dir = 'foam/' - boundaries = ['top', 'bottom', 'front', 'back', 'left', 'right'] - times = get_foam_times(case_dir)[1:] + case_dir = "foam/" + boundaries = ["top", "bottom", "front", "back", "left", "right"] + times = get_foam_times(case_dir, string=True)[1:] for time in times: for boundary in boundaries: temp = ff.readof.readscalar(case_dir, time, "T", boundary=boundary) - scale = 1. if boundary in ('left', 'right', 'top') else 2. - temp_ref = 0.05 + scale*np.float64(time) + scale = 1.0 if boundary in ("left", "right", "top") else 2.0 + temp_ref = 0.05 + scale * np.float64(time) - temp_diff_max = np.argmax(abs(temp-temp_ref)) - assert np.allclose(temp_ref, temp, rtol=1e-7, atol=1e-12),\ - (f"Max diff {boundary} ({time}): {abs(temp-temp_ref).max()} " - f"{temp[temp_diff_max]} {temp_ref[temp_diff_max]}") + temp_diff_max = np.argmax(abs(temp - temp_ref)) + assert np.allclose(temp_ref, temp, rtol=1e-7, atol=1e-12), ( + f"Max diff {boundary} ({time}): {abs(temp - temp_ref).max()} " + f"{temp[temp_diff_max]} {temp_ref[temp_diff_max]}" + ) diff --git a/test/tests/bcs/mapped_inlet/test.py b/test/tests/bcs/mapped_inlet/test.py index 92d56290..015437dc 100644 --- a/test/tests/bcs/mapped_inlet/test.py +++ b/test/tests/bcs/mapped_inlet/test.py @@ -1,5 +1,4 @@ -"""Tests for imposing BCs in OpenFOAM using MOOSE input file syntax -""" +"""Tests for imposing BCs in OpenFOAM using MOOSE input file syntax""" import unittest import fluidfoam as ff @@ -7,40 +6,41 @@ from read_hippo_data import get_foam_times -CASE_DIR = 'foam/' -TIMES = get_foam_times(CASE_DIR)[1:] +CASE_DIR = "foam/" +TIMES = get_foam_times(CASE_DIR, string=True)[1:] class TestFoamBCMappedInlet(unittest.TestCase): """Test class for mapped inlet BCs in Hippo.""" + def test_mapped_inlet(self): """Test case for mapped inlet.""" for i in range(len(TIMES)): - self._check_u_temp_refs(i, 'left', [1., 0, 0]) - self._check_u_temp_refs(i, 'bottom', [0, 1., 0]) - self._check_u_temp_refs(i, 'front', [0, 0, 1.]) + self._check_u_temp_refs(i, "left", [1.0, 0, 0]) + self._check_u_temp_refs(i, "bottom", [0, 1.0, 0]) + self._check_u_temp_refs(i, "front", [0, 0, 1.0]) def test_mapped_inlet_subtract(self): """Test case for mapped inlet when temperature is scaled by subtracting the difference in bulk.""" for i in range(len(TIMES)): - self._check_u_temp_refs(i, 'left', [1., 0, 0], False) - self._check_u_temp_refs(i, 'bottom', [0, 1., 0], False) - self._check_u_temp_refs(i, 'front', [0, 0, 1.], False) + self._check_u_temp_refs(i, "left", [1.0, 0, 0], False) + self._check_u_temp_refs(i, "bottom", [0, 1.0, 0], False) + self._check_u_temp_refs(i, "front", [0, 0, 1.0], False) def test_mapped_inlet_rotated(self): """Test case for when inlet's are not aligned with the axis.""" for i in range(len(TIMES)): - self._check_u_temp_refs(i, 'left', [np.sqrt(0.5), np.sqrt(0.5), 0]) + self._check_u_temp_refs(i, "left", [np.sqrt(0.5), np.sqrt(0.5), 0]) def test_mapped_inlet_face_point(self): """Test case for mapped inlet where the point is on the interface between boundaries.""" for i in range(len(TIMES)): - self._check_u_temp_refs(i, 'left', [7./8, 0, 0]) - self._check_u_temp_refs(i, 'bottom', [0, 7./8, 0]) - self._check_u_temp_refs(i, 'front', [0, 0, 7./8]) + self._check_u_temp_refs(i, "left", [7.0 / 8, 0, 0]) + self._check_u_temp_refs(i, "bottom", [0, 7.0 / 8, 0]) + self._check_u_temp_refs(i, "front", [0, 0, 7.0 / 8]) def _check_u_temp_refs(self, idx, boundary, offset, use_scale=True): rho = 0.5 @@ -57,28 +57,35 @@ def _check_u_temp_refs(self, idx, boundary, offset, use_scale=True): z += offset[2] if idx != 0: - t = np.float64(TIMES[idx-1]) - u_ref = np.array([x + y + z + t, x - y + z + t, x + y - z + t,]).T - temp_ref = np.sqrt(x*x + y*y + z*z) + t + t = np.float64(TIMES[idx - 1]) + u_ref = np.array( + [ + x + y + z + t, + x - y + z + t, + x + y - z + t, + ] + ).T + temp_ref = np.sqrt(x * x + y * y + z * z) + t else: # first time step uses initialised value u_ref = np.array([[1, -0.5, 0.25]]) temp_ref = 2 - area = 4. - normal = np.array(offset)/np.linalg.norm(offset) - mdot = rho*np.mean(np.vecdot(u_ref, normal))*area - u_ref *= mdot_pp/mdot + area = 4.0 + normal = np.array(offset) / np.linalg.norm(offset) + mdot = rho * np.mean(np.vecdot(u_ref, normal)) * area + u_ref *= mdot_pp / mdot t_bulk = np.mean(temp_ref) if use_scale: - temp_ref *= t_pp/t_bulk + temp_ref *= t_pp / t_bulk else: - temp_ref += (t_pp - t_bulk) - + temp_ref += t_pp - t_bulk - assert np.allclose(u_ref, u, rtol=1e-7, atol=1e-12),\ - f"Max diff ({boundary}) (velocity) ({TIMES[idx]}): {abs(u-u_ref).max()} " + assert np.allclose(u_ref, u, rtol=1e-7, atol=1e-12), ( + f"Max diff ({boundary}) (velocity) ({TIMES[idx]}): {abs(u - u_ref).max()} " + ) - assert np.allclose(temp_ref, temp, rtol=1e-7, atol=1e-12),\ - f"Max diff ({boundary}) (temperature) ({time}): {abs(temp-temp_ref).max()} {temp} {temp_ref}" + assert np.allclose(temp_ref, temp, rtol=1e-7, atol=1e-12), ( + f"Max diff ({boundary}) (temperature) ({time}): {abs(temp - temp_ref).max()} {temp} {temp_ref}" + ) diff --git a/test/tests/bcs/receiver_pp/test.py b/test/tests/bcs/receiver_pp/test.py index 5c89a6fc..98b48ce7 100644 --- a/test/tests/bcs/receiver_pp/test.py +++ b/test/tests/bcs/receiver_pp/test.py @@ -1,27 +1,29 @@ -"""Tests for imposing BCs in OpenFOAM using MOOSE input file syntax -""" +"""Tests for imposing BCs in OpenFOAM using MOOSE input file syntax""" import unittest import fluidfoam as ff import numpy as np -from read_hippo_data import get_foam_times #pylint: disable=E0401 +from read_hippo_data import get_foam_times # pylint: disable=E0401 + class TestFoamBCFixedGradient(unittest.TestCase): """Test class for imposing fixed value BCs in Hippo.""" + def test_fixed_gradient_x(self): """Test case for imposing fixed value.""" - case_dir = 'foam/' - times = get_foam_times(case_dir)[1:] + case_dir = "foam/" + times = get_foam_times(case_dir, string=True)[1:] for time in times: - coords = dict(zip(('x','y','z'),ff.readof.readmesh(case_dir))) + coords = dict(zip(("x", "y", "z"), ff.readof.readmesh(case_dir))) temp = ff.readof.readscalar(case_dir, time, "T") - temp_ref = coords['x']*np.float64(time) + temp_ref = coords["x"] * np.float64(time) - temp_diff_max = np.argmax(abs(temp-temp_ref)) - assert np.allclose(temp_ref, temp, rtol=1e-7, atol=1e-12),\ - (f"Max diff ({time}): {abs(temp-temp_ref).max()} " - f"{temp[temp_diff_max]} {temp_ref[temp_diff_max]}") + temp_diff_max = np.argmax(abs(temp - temp_ref)) + assert np.allclose(temp_ref, temp, rtol=1e-7, atol=1e-12), ( + f"Max diff ({time}): {abs(temp - temp_ref).max()} " + f"{temp[temp_diff_max]} {temp_ref[temp_diff_max]}" + ) From 1a6a30263736cf3ed337811dbac10915ecce5d52 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Sun, 8 Feb 2026 13:07:55 +0000 Subject: [PATCH 37/52] Remove mapped inlet classes to separate branch --- include/bcs/FoamMappedInletBCBase.h | 70 ---- include/bcs/FoamMassFlowRateMappedInletBC.h | 18 - include/bcs/FoamScalarBulkMappedInletBC.h | 19 - src/bcs/FoamMappedInletBCBase.C | 389 ------------------ src/bcs/FoamMassFlowRateMappedInletBC.C | 73 ---- src/bcs/FoamScalarBulkMappedInletBC.C | 74 ---- test/OpenFOAM/foam_modules.mk | 2 - .../modules/mappedInletTestSolver/Make/files | 3 - .../mappedInletTestSolver/Make/options | 20 - .../mappedInletTestSolver.C | 183 -------- .../mappedInletTestSolver.H | 152 ------- test/tests/bcs/mapped_inlet/foam/0/T | 56 --- test/tests/bcs/mapped_inlet/foam/0/U | 31 -- test/tests/bcs/mapped_inlet/foam/0/rho | 56 --- test/tests/bcs/mapped_inlet/foam/constant/g | 21 - .../foam/constant/momentumTransport | 18 - .../foam/constant/physicalProperties | 52 --- .../mapped_inlet/foam/system/blockMeshDict | 85 ---- .../foam/system/blockMeshDict.face_edge | 85 ---- .../foam/system/blockMeshDict.orig | 85 ---- .../bcs/mapped_inlet/foam/system/controlDict | 44 -- .../mapped_inlet/foam/system/decomposeParDict | 42 -- .../foam/system/decomposeParDict.face_edge | 42 -- .../foam/system/decomposeParDict.orig | 42 -- .../bcs/mapped_inlet/foam/system/fvSchemes | 51 --- .../bcs/mapped_inlet/foam/system/fvSolution | 61 --- test/tests/bcs/mapped_inlet/main.i | 76 ---- test/tests/bcs/mapped_inlet/main_rotated.i | 50 --- test/tests/bcs/mapped_inlet/test.py | 91 ---- test/tests/bcs/mapped_inlet/tests | 153 ------- 30 files changed, 2144 deletions(-) delete mode 100644 include/bcs/FoamMappedInletBCBase.h delete mode 100644 include/bcs/FoamMassFlowRateMappedInletBC.h delete mode 100644 include/bcs/FoamScalarBulkMappedInletBC.h delete mode 100644 src/bcs/FoamMappedInletBCBase.C delete mode 100644 src/bcs/FoamMassFlowRateMappedInletBC.C delete mode 100644 src/bcs/FoamScalarBulkMappedInletBC.C delete mode 100644 test/OpenFOAM/modules/mappedInletTestSolver/Make/files delete mode 100644 test/OpenFOAM/modules/mappedInletTestSolver/Make/options delete mode 100644 test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.C delete mode 100644 test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.H delete mode 100644 test/tests/bcs/mapped_inlet/foam/0/T delete mode 100644 test/tests/bcs/mapped_inlet/foam/0/U delete mode 100644 test/tests/bcs/mapped_inlet/foam/0/rho delete mode 100644 test/tests/bcs/mapped_inlet/foam/constant/g delete mode 100644 test/tests/bcs/mapped_inlet/foam/constant/momentumTransport delete mode 100644 test/tests/bcs/mapped_inlet/foam/constant/physicalProperties delete mode 100644 test/tests/bcs/mapped_inlet/foam/system/blockMeshDict delete mode 100644 test/tests/bcs/mapped_inlet/foam/system/blockMeshDict.face_edge delete mode 100644 test/tests/bcs/mapped_inlet/foam/system/blockMeshDict.orig delete mode 100644 test/tests/bcs/mapped_inlet/foam/system/controlDict delete mode 100644 test/tests/bcs/mapped_inlet/foam/system/decomposeParDict delete mode 100644 test/tests/bcs/mapped_inlet/foam/system/decomposeParDict.face_edge delete mode 100644 test/tests/bcs/mapped_inlet/foam/system/decomposeParDict.orig delete mode 100644 test/tests/bcs/mapped_inlet/foam/system/fvSchemes delete mode 100644 test/tests/bcs/mapped_inlet/foam/system/fvSolution delete mode 100644 test/tests/bcs/mapped_inlet/main.i delete mode 100644 test/tests/bcs/mapped_inlet/main_rotated.i delete mode 100644 test/tests/bcs/mapped_inlet/test.py delete mode 100644 test/tests/bcs/mapped_inlet/tests diff --git a/include/bcs/FoamMappedInletBCBase.h b/include/bcs/FoamMappedInletBCBase.h deleted file mode 100644 index 29e31355..00000000 --- a/include/bcs/FoamMappedInletBCBase.h +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once - -#include "FoamPostprocessorBCBase.h" -#include - -class FoamMappedInletBCBase : public FoamPostprocessorBCBase -{ -public: - static InputParameters validParams(); - - FoamMappedInletBCBase(const InputParameters & params); - - virtual ~FoamMappedInletBCBase() { destroyCommunicator(_foam_comm); } - -protected: - Foam::vector _offset; - - std::map> _send_map; - - std::map> _recv_map; - - Foam::label _foam_comm; - - MPI_Comm _mpi_comm; - - // create send and receive information for mapping - void createPatchProcMap(); - - // get array from mapped plane on the inlet processes - template - Foam::Field getMappedArray(const Foam::word & name); - - // check if bounding box intersects with rank - bool intersectMapPlane(const Foam::fvMesh & mesh, Real cart_bbox[6]); - - // create/assign communicators for the transfers between map and inlet planes - void createMapComm(const Foam::fvMesh & mesh, - Foam::vectorField face_centres, - std::vector & send_process, - std::vector & recv_process); - - // find index of cell containing point or raise error if not found - int findIndex(const Foam::point & location, const MPI_Comm & comm); - - // handle creation of new communicators in parallel or serial - Foam::label - createCommunicator(const Foam::label parent_comm, std::vector procs, MPI_Comm & new_comm) - { - Foam::label foam_comm; - if (Foam::UPstream::parRun()) - { - Foam::labelList foam_procs(procs.begin(), procs.end()); - foam_comm = Foam::UPstream::allocateCommunicator(parent_comm, foam_procs, true); - new_comm = Foam::PstreamGlobals::MPICommunicators_[foam_comm]; - } - else - { - foam_comm = Foam::UPstream::worldComm; - new_comm = MPI_COMM_WORLD; - } - return foam_comm; - } - - // free communicators if parallel run - void destroyCommunicator(Foam::label comm) - { - if (Foam::UPstream::parRun()) - Foam::UPstream::freeCommunicator(comm); - } -}; diff --git a/include/bcs/FoamMassFlowRateMappedInletBC.h b/include/bcs/FoamMassFlowRateMappedInletBC.h deleted file mode 100644 index 39b8520f..00000000 --- a/include/bcs/FoamMassFlowRateMappedInletBC.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once -#include "FoamMappedInletBCBase.h" -#include "MooseEnum.h" - -class FoamMassFlowRateMappedInletBC : public FoamMappedInletBCBase -{ -public: - static InputParameters validParams(); - - FoamMassFlowRateMappedInletBC(const InputParameters & params); - - virtual void imposeBoundaryCondition() override; - -protected: - MooseEnum _scale_method; - - Real _scale_factor; -}; diff --git a/include/bcs/FoamScalarBulkMappedInletBC.h b/include/bcs/FoamScalarBulkMappedInletBC.h deleted file mode 100644 index 2a68fd0c..00000000 --- a/include/bcs/FoamScalarBulkMappedInletBC.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once -#include "FoamMappedInletBCBase.h" -#include "MooseEnum.h" - -class FoamScalarBulkMappedInletBC : public FoamMappedInletBCBase -{ -public: - static InputParameters validParams(); - - FoamScalarBulkMappedInletBC(const InputParameters & params); - - virtual void imposeBoundaryCondition() override; - -protected: - MooseEnum _scale_method; - - template - T applyScaleMethod(T & var, const Real bulk_ref, const Real bulk); -}; diff --git a/src/bcs/FoamMappedInletBCBase.C b/src/bcs/FoamMappedInletBCBase.C deleted file mode 100644 index 9ca25de2..00000000 --- a/src/bcs/FoamMappedInletBCBase.C +++ /dev/null @@ -1,389 +0,0 @@ -#include "FoamMappedInletBCBase.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace -{ -// Get the cartesian bounding box of the mapped inlet plane -void -getBBox(const Foam::vectorField points, Real bbox[6]) -{ - bbox[0] = DBL_MAX; - bbox[1] = DBL_MIN; - bbox[2] = DBL_MAX; - bbox[3] = DBL_MIN; - bbox[4] = DBL_MAX; - bbox[5] = DBL_MIN; - for (auto p : points) - { - bbox[0] = std::min(bbox[0], p.x()); - bbox[1] = std::max(bbox[1], p.x()); - bbox[2] = std::min(bbox[2], p.y()); - bbox[3] = std::max(bbox[3], p.y()); - bbox[4] = std::min(bbox[4], p.z()); - bbox[5] = std::max(bbox[5], p.z()); - } - - MPI_Allreduce(MPI_IN_PLACE, &bbox[0], 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD); - MPI_Allreduce(MPI_IN_PLACE, &bbox[1], 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); - MPI_Allreduce(MPI_IN_PLACE, &bbox[2], 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD); - MPI_Allreduce(MPI_IN_PLACE, &bbox[3], 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); - MPI_Allreduce(MPI_IN_PLACE, &bbox[4], 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD); - MPI_Allreduce(MPI_IN_PLACE, &bbox[5], 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); -} -} - -bool -FoamMappedInletBCBase::intersectMapPlane(const Foam::fvMesh & mesh, Real cart_bbox[6]) -{ - auto & vertices = mesh.points(); - for (int i = 0; i < mesh.nCells(); ++i) - { - auto points = mesh.cellPoints(i); - for (auto pointI : points) - { - // check whether cell intersects bbox - const Foam::point & p = vertices[pointI]; - if (p.x() >= cart_bbox[0] && p.x() <= cart_bbox[1] && p.y() >= cart_bbox[2] && - p.y() <= cart_bbox[3] && p.z() >= cart_bbox[4] && p.z() <= cart_bbox[5]) - { - return true; - } - } - - // The bbox could by narrower than the cell, check in each direction whether bbox is within the - // cell bbox - Real cell_bbox[6] = {DBL_MAX, DBL_MIN, DBL_MAX, DBL_MIN, DBL_MAX, DBL_MIN}; - for (auto point : points) - { - const Foam::point & p = vertices[point]; - cell_bbox[0] = std::min(cell_bbox[0], p.x()); - cell_bbox[1] = std::max(cell_bbox[1], p.x()); - cell_bbox[2] = std::min(cell_bbox[2], p.y()); - cell_bbox[3] = std::max(cell_bbox[3], p.y()); - cell_bbox[4] = std::min(cell_bbox[4], p.z()); - cell_bbox[5] = std::max(cell_bbox[5], p.z()); - } - // check is cart bbox is narrower than cell bbox in x direction - if ((cart_bbox[0] >= cell_bbox[0] && cart_bbox[1] <= cell_bbox[1]) && - (cart_bbox[3] >= cell_bbox[2] || cart_bbox[2] <= cell_bbox[3]) && - (cart_bbox[5] >= cell_bbox[4] || cart_bbox[4] <= cell_bbox[5])) - { - return true; - } - - // check is cart bbox is narrower than cell bbox in y direction - if ((cart_bbox[2] >= cell_bbox[2] && cart_bbox[3] <= cell_bbox[3]) && - (cart_bbox[1] >= cell_bbox[0] || cart_bbox[0] <= cell_bbox[1]) && - (cart_bbox[5] >= cell_bbox[4] || cart_bbox[4] <= cell_bbox[5])) - { - return true; - } - // check is cart bbox is narrower than cell bbox in z direction - if ((cart_bbox[4] >= cell_bbox[4] && cart_bbox[5] <= cell_bbox[5]) && - (cart_bbox[1] >= cell_bbox[0] || cart_bbox[0] <= cell_bbox[1]) && - (cart_bbox[3] >= cell_bbox[2] || cart_bbox[2] <= cell_bbox[3])) - { - return true; - } - } - - return false; -} - -void -FoamMappedInletBCBase::createMapComm(const Foam::fvMesh & mesh, - const Foam::vectorField face_centres, - std::vector & map_process, - std::vector & inlet_process) -{ - Real cart_bbox[6]; - auto mapped_plane = face_centres + _offset; - getBBox(mapped_plane(), cart_bbox); - - int mappedPlaneProcess = intersectMapPlane(mesh, cart_bbox); - int inletPlaneProcess = face_centres.size() > 0; - - std::vector inlet_procs(Foam::UPstream::nProcs()); - std::vector map_procs(Foam::UPstream::nProcs()); - - MPI_Allgather(&mappedPlaneProcess, 1, MPI_INT, map_procs.data(), 1, MPI_INT, MPI_COMM_WORLD); - MPI_Allgather(&inletPlaneProcess, 1, MPI_INT, inlet_procs.data(), 1, MPI_INT, MPI_COMM_WORLD); - - map_process.clear(); - inlet_process.clear(); - - // create list of processes in new communicator and whether they are in the inlet or mapped plane - std::vector processes; - int j = 0; - for (int i = 0; i < Foam::UPstream::nProcs(); ++i) - { - if (inlet_procs[i] || map_procs[i]) - { - processes.push_back(i); - if (inlet_procs[i]) - inlet_process.push_back(j); - if (map_procs[i]) - map_process.push_back(j); - ++j; - } - } - - _foam_comm = createCommunicator(Foam::UPstream::worldComm, processes, _mpi_comm); -} - -void -FoamMappedInletBCBase::createPatchProcMap() -{ - auto & foam_mesh = _mesh->fvMesh(); - auto & boundary = foam_mesh.boundary()[_boundary[0]]; - auto face_centres = boundary.Cf(); - - std::vector map_procs, inlet_procs; - createMapComm(foam_mesh, face_centres, map_procs, inlet_procs); - - if (_mpi_comm == MPI_COMM_NULL) // process not in mapped or inlet planes - return; - - Foam::PstreamBuffers send_points( - Foam::UPstream::commsTypes::nonBlocking, Foam::UPstream::msgType(), _foam_comm); - int rank = Foam::UPstream::myProcNo(_foam_comm); - bool isMapProc = std::find(map_procs.begin(), map_procs.end(), rank) != map_procs.end(); - bool isInletProc = std::find(inlet_procs.begin(), inlet_procs.end(), rank) != inlet_procs.end(); - - if (isInletProc) // send points from inlet process to all map processes - { - for (int proc : map_procs) - { - Foam::UOPstream send(proc, send_points); - send << face_centres; - } - } - - send_points.finishedSends(true); - - std::vector size_requests(inlet_procs.size()); - std::vector data_requests(inlet_procs.size()); - std::vector> recv_indices_procs(inlet_procs.size()); - MPI_Comm map_comm; - auto foam_map_comm = createCommunicator(_foam_comm, map_procs, map_comm); - - if (isMapProc) // check points from each process to see if they are local - { - for (auto i = 0lu; i < inlet_procs.size(); ++i) - { - Foam::vectorField field; - Foam::UIPstream recieve(inlet_procs[i], send_points); - recieve >> field; - auto & vec = _send_map[inlet_procs[i]]; - auto & recv_indices = recv_indices_procs[i]; - for (int j = 0; j < field.size(); ++j) - { - auto index = findIndex(field[j] + _offset, map_comm); - if (index >= 0) - { - vec.push_back(index); // assign to send map required indices - recv_indices.push_back(j); - } - } - if (vec.size() == 0) - _send_map.erase(inlet_procs[i]); - - // Let original processes know which points will come from each rank - int size = recv_indices.size(); - MPI_Isend(&size, 1, MPI_INT, inlet_procs[i], 0, _mpi_comm, &size_requests.at(i)); - MPI_Isend(recv_indices.data(), - recv_indices.size(), - MPI_INT, - inlet_procs[i], - 1, - _mpi_comm, - &data_requests.at(i)); - } - } - - destroyCommunicator(foam_map_comm); - - if (isInletProc) // create map to determine where data from map processes should go - { - for (auto & proc : map_procs) - { - int size; - MPI_Recv(&size, 1, MPI_INT, proc, 0, _mpi_comm, MPI_STATUS_IGNORE); - - std::vector recv_indices(size); - MPI_Recv(recv_indices.data(), size, MPI_INT, proc, 1, _mpi_comm, MPI_STATUS_IGNORE); - for (auto & index : recv_indices) - { - assert(index < face_centres.size()); - _recv_map[proc].push_back(index); - } - } - } - MPI_Barrier(_mpi_comm); -} - -int -FoamMappedInletBCBase::findIndex(const Foam::point & location, const MPI_Comm & comm) -{ - /* - This function uses several ways of finding the mapped plane cell - 1. use findCell function - - Sometimes on cell boundaries it may not find the cell or two processes with both find it - 2. If none found, find the closest point and do an expanded bounding box search, raise error - if none still found. - 3. If multiple found, use the cell with cell centre closer to desired location - 4. If still multiple found, use the cell closer to the inlet. - - In the unlikely chance there are still multiple cells detected, raise a warning - Note that it is possible there is some non-deterministic behaviour in the function but this - shouldn't be a problem in practice. - */ - int index = _mesh->fvMesh().findCell(location, Foam::polyMesh::FACE_PLANES); - int gl_index; - MPI_Allreduce(&index, &gl_index, 1, MPI_INT, MPI_MAX, comm); - - // expand cell bounding box and repeat search - if (gl_index < 0) - { - Foam::label celli = _mesh->fvMesh().findNearestCell(location); - - bool in_cell = _mesh->fvMesh().pointInCellBB(location, celli, 0.1); - index = (in_cell) ? celli : -1; - MPI_Allreduce(&index, &gl_index, 1, MPI_INT, MPI_MAX, comm); - - int rank; - MPI_Comm_rank(comm, &rank); - if (gl_index < 0 && rank == 0) - { - mooseError("Face centre at location (", - location[0], - ",", - location[1], - ",", - location[2], - ") does not have a mapped plane location"); - } - } - - // use cell with cell centre closest to the location - Foam::scalar dist{DBL_MAX}, gl_dist; - if (index != -1) - dist = Foam::mag(_mesh->fvMesh().cellCentres()[index] - location); - - MPI_Allreduce(&dist, &gl_dist, 1, MPI_DOUBLE, MPI_MIN, comm); - if (dist != gl_dist) - index = -1; - - // 2. use cell centre closest to inlet point - int in_cell = index != -1; - MPI_Allreduce(MPI_IN_PLACE, &in_cell, 1, MPI_INT, MPI_SUM, comm); - if (in_cell > 1) - { - if (index != -1) - dist = Foam::mag(_mesh->fvMesh().cellCentres()[index] - (location - _offset)); - MPI_Allreduce(&dist, &gl_dist, 1, MPI_DOUBLE, MPI_MIN, comm); - if (dist != gl_dist) - index = -1; - } - in_cell = index != -1; - MPI_Allreduce(MPI_IN_PLACE, &in_cell, 1, MPI_INT, MPI_SUM, comm); - - if (in_cell > 1) - mooseWarning("More than 1 process found location (", - location[0], - ",", - location[1], - ",", - location[2], - ")"); - return index; -} - -InputParameters -FoamMappedInletBCBase::validParams() -{ - auto params = FoamPostprocessorBCBase::validParams(); - params.addRequiredParam>("translation_vector", - "A vector indicating the location of recycling plane"); - - return params; -} - -FoamMappedInletBCBase::FoamMappedInletBCBase(const InputParameters & params) - : FoamPostprocessorBCBase(params), - _offset(), - _send_map(), - _recv_map(), - _foam_comm(0), - _mpi_comm(MPI_COMM_NULL) -{ - if (_boundary.size() > 1) - mooseError("There can only be one boundary using this method"); - - auto param_offset = params.get>("translation_vector"); - assert(param_offset.size() == 3); - - _offset = {param_offset[0], param_offset[1], param_offset[2]}; - createPatchProcMap(); -} - -template -Foam::Field -FoamMappedInletBCBase::getMappedArray(const Foam::word & name) -{ - if (_mpi_comm == MPI_COMM_NULL) - return Foam::Field(); - - auto & foam_mesh = _mesh->fvMesh(); - auto & boundary_patch = foam_mesh.boundary()[_boundary[0]]; - - Foam::PstreamBuffers sendBuf( - Foam::UPstream::commsTypes::nonBlocking, Foam::UPstream::msgType(), _foam_comm); - if (_send_map.size() > 0) - { - auto & var = foam_mesh.lookupObject>(name); - for (auto & pair : _send_map) - { - auto & proc = pair.first; - auto & send_indices = pair.second; - - Foam::Field points(send_indices.size()); - for (auto j = 0lu; j < send_indices.size(); ++j) - points[j] = var[send_indices[j]]; - - Foam::UOPstream send(proc, sendBuf); - send << points; - } - } - sendBuf.finishedSends(true); - - Foam::Field boundaryData(boundary_patch.size()); - if (_recv_map.size() > 0) - { - for (auto & pair : _recv_map) - { - auto & proc = pair.first; - auto & recv_indices = pair.second; - - Foam::UIPstream recv(proc, sendBuf); - Foam::Field recvData; - recv >> recvData; - for (auto j = 0lu; j < recv_indices.size(); ++j) - { - boundaryData[recv_indices[j]] = recvData[j]; - } - } - } - - return boundaryData; -} diff --git a/src/bcs/FoamMassFlowRateMappedInletBC.C b/src/bcs/FoamMassFlowRateMappedInletBC.C deleted file mode 100644 index 88ba1f96..00000000 --- a/src/bcs/FoamMassFlowRateMappedInletBC.C +++ /dev/null @@ -1,73 +0,0 @@ -#include "FoamMassFlowRateMappedInletBC.h" -#include "InputParameters.h" -#include "MooseTypes.h" -#include "PstreamReduceOps.H" -#include "Registry.h" - -#include "ops.H" -#include "vectorField.H" -#include "volFieldsFwd.H" - -registerMooseObject("hippoApp", FoamMassFlowRateMappedInletBC); - -InputParameters -FoamMassFlowRateMappedInletBC::validParams() -{ - auto params = FoamMappedInletBCBase::validParams(); - - params.addParam("scale_factor", 1., "Scale factor multiply mass flow rate pp by."); - MooseEnum scaleEnum("SCALE NONE", "SCALE"); - params.addParam("scale_method", - scaleEnum, - "Method used to maintain inlet bulk variable. " - "SCALE means the variable is multiplied by a factor, " - "NONE means the variable is not scaled."); - - params.remove("foam_variable"); - params.addPrivateParam("foam_variable", "U"); - - return params; -} - -FoamMassFlowRateMappedInletBC::FoamMassFlowRateMappedInletBC(const InputParameters & params) - : FoamMappedInletBCBase(params), - _scale_method(params.get("scale_method")), - _scale_factor(params.get("scale_factor")) -{ -} - -void -FoamMassFlowRateMappedInletBC::imposeBoundaryCondition() -{ - auto & foam_mesh = _mesh->fvMesh(); - auto & boundary_patch = foam_mesh.boundary()[_boundary[0]]; - - // currently we map mass flux rather than velocity, maybe useful to have option - auto && U_map = getMappedArray("U"); - auto && rho_map = getMappedArray("rho"); - auto g_map = rho_map * U_map; - - auto & rho = boundary_patch.lookupPatchField("rho"); - auto & U_var = const_cast &>( - boundary_patch.lookupPatchField("U")); - - Foam::vectorField g_var(U_var.size()); - g_var = rho_map * U_map; - if (_scale_method == "SCALE") - { - auto & Sf = boundary_patch.Sf(); - - auto m_dot = Foam::returnReduce(Foam::sum(g_map & -Sf), Foam::sumOp()); - if (fabs(m_dot) > 1e-8) - { - g_var *= _scale_factor * _pp_value / m_dot; - } - else - { - auto area = Foam::returnReduce(Foam::sum(boundary_patch.magSf()), Foam::sumOp()); - g_var -= _scale_factor * boundary_patch.nf() * _pp_value / area; - } - } - - U_var == g_var / rho; -} diff --git a/src/bcs/FoamScalarBulkMappedInletBC.C b/src/bcs/FoamScalarBulkMappedInletBC.C deleted file mode 100644 index f1cb83d9..00000000 --- a/src/bcs/FoamScalarBulkMappedInletBC.C +++ /dev/null @@ -1,74 +0,0 @@ -#include "FoamScalarBulkMappedInletBC.h" -#include "InputParameters.h" -#include "MooseTypes.h" -#include "PstreamReduceOps.H" -#include "Registry.h" - -#include "ops.H" -#include "volFieldsFwd.H" - -registerMooseObject("hippoApp", FoamScalarBulkMappedInletBC); - -InputParameters -FoamScalarBulkMappedInletBC::validParams() -{ - auto params = FoamMappedInletBCBase::validParams(); - MooseEnum scaleEnum("SCALE SUBTRACT NONE", "SCALE"); - params.addParam("scale_method", - scaleEnum, - "Method used to maintain inlet bulk variable. " - "SCALE means the variable is multiplied by a factor, " - "SUBTRACT means the variable is reduced by constant," - "NONE means the variable is not scaled."); - - return params; -} - -FoamScalarBulkMappedInletBC::FoamScalarBulkMappedInletBC(const InputParameters & params) - : FoamMappedInletBCBase(params), _scale_method(params.get("scale_method")) -{ -} - -void -FoamScalarBulkMappedInletBC::imposeBoundaryCondition() -{ - auto & foam_mesh = _mesh->fvMesh(); - auto & boundary_patch = foam_mesh.boundary()[_boundary[0]]; - - auto && var_map = getMappedArray(_foam_variable); - auto & Sf = boundary_patch.magSf(); - - auto totalArea = Foam::sum(Sf); - Foam::reduce(totalArea, Foam::sumOp()); - - auto var_bulk = Foam::sum(var_map * Sf) / totalArea; - - Foam::reduce(var_bulk, Foam::sumOp()); - - auto & var = const_cast &>( - boundary_patch.lookupPatchField(_foam_variable)); - - var == applyScaleMethod(var_map, _pp_value, var_bulk); -} - -template -T -FoamScalarBulkMappedInletBC::applyScaleMethod(T & var, const Real bulk_ref, const Real bulk) -{ - if (_scale_method == "SCALE") - { - return (var * bulk_ref / bulk)(); - } - else if (_scale_method == "SUBTRACT") - { - return (var + bulk_ref - bulk)(); - } - else if (_scale_method == "NONE") - { - return var; - } - else - { - mooseError("Invalid scale method '", _scale_method, "'."); - } -} diff --git a/test/OpenFOAM/foam_modules.mk b/test/OpenFOAM/foam_modules.mk index 88d13625..80bf70a8 100644 --- a/test/OpenFOAM/foam_modules.mk +++ b/test/OpenFOAM/foam_modules.mk @@ -12,5 +12,3 @@ build_foam_tests: @$(MAKE) -s -j $(MOOSE_JOBS) test/OpenFOAM/modules/laplacianTestSolver/ @$(MAKE) -s -j $(MOOSE_JOBS) test/OpenFOAM/modules/odeTestSolver/ @$(MAKE) -s -j $(MOOSE_JOBS) test/OpenFOAM/modules/postprocessorTestSolver/ - @$(MAKE) -s -j $(MOOSE_JOBS) test/OpenFOAM/modules/mappedInletTestSolver/ - diff --git a/test/OpenFOAM/modules/mappedInletTestSolver/Make/files b/test/OpenFOAM/modules/mappedInletTestSolver/Make/files deleted file mode 100644 index 0f5991d4..00000000 --- a/test/OpenFOAM/modules/mappedInletTestSolver/Make/files +++ /dev/null @@ -1,3 +0,0 @@ -SOURCE += mappedInletTestSolver.C - -LIB = $(FOAM_USER_LIBBIN)/libmappedInletTestSolver diff --git a/test/OpenFOAM/modules/mappedInletTestSolver/Make/options b/test/OpenFOAM/modules/mappedInletTestSolver/Make/options deleted file mode 100644 index cc845ca8..00000000 --- a/test/OpenFOAM/modules/mappedInletTestSolver/Make/options +++ /dev/null @@ -1,20 +0,0 @@ -EXE_INC = \ - -I$(LIB_SRC)/physicalProperties/lnInclude \ - -I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \ - -I$(LIB_SRC)/thermophysicalModels/solidThermo/lnInclude \ - -I$(LIB_SRC)/ThermophysicalTransportModels/thermophysicalTransportModel/lnInclude \ - -I$(LIB_SRC)/ThermophysicalTransportModels/solid/lnInclude \ - -I$(LIB_SRC)/finiteVolume/lnInclude \ - -I$(LIB_SRC)/meshTools/lnInclude \ - -I$(LIB_SRC)/sampling/lnInclude - -LIB_LIBS = \ - -lsolidThermo \ - -lsolidThermophysicalTransportModels \ - -lcoupledThermophysicalTransportModels \ - -lspecie \ - -lfiniteVolume \ - -lmeshTools \ - -lsampling \ - -lfvModels \ - -lfvConstraints diff --git a/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.C b/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.C deleted file mode 100644 index 17f910c8..00000000 --- a/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.C +++ /dev/null @@ -1,183 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | Website: https://openfoam.org - \\ / A nd | Copyright (C) 2022-2024 OpenFOAM Foundation - \\/ M anipulation | -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see . - -\*---------------------------------------------------------------------------*/ - -#include "dimensionSets.H" -#include "dimensionedScalar.H" -#include "dimensionedVector.H" -#include "fvMesh.H" -#include "mappedInletTestSolver.H" -#include "fvMeshMover.H" -#include "addToRunTimeSelectionTable.H" -#include "fvConstraints.H" -#include "fvmLaplacian.H" - -// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // - -namespace Foam -{ -namespace solvers -{ -defineTypeNameAndDebug(mappedInletTestSolver, 0); -addToRunTimeSelectionTable(solver, mappedInletTestSolver, fvMesh); -} -} - -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // - -// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * // - -bool -Foam::solvers::mappedInletTestSolver::dependenciesModified() const -{ - return runTime.controlDict().modified(); -} - -bool -Foam::solvers::mappedInletTestSolver::read() -{ - solver::read(); - - maxDeltaT_ = runTime.controlDict().found("maxDeltaT") - ? runTime.controlDict().lookup("maxDeltaT", runTime.userUnits()) - : vGreat; - - return true; -} - -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -// Solver based on solid.C module -Foam::solvers::mappedInletTestSolver::mappedInletTestSolver(fvMesh & mesh, - autoPtr thermoPtr) - : solver(mesh), - - thermoPtr_(thermoPtr), - thermo_(thermoPtr_()), - - T_(IOobject("T", mesh.time().name(), mesh, IOobject::NO_READ, IOobject::AUTO_WRITE), mesh), - - U_(IOobject("U", mesh.time().name(), mesh, IOobject::NO_READ, IOobject::AUTO_WRITE), mesh), - - thermophysicalTransport(solidThermophysicalTransportModel::New(thermo_)), - thermo(thermo_), - T(T_), - U(U_) -{ - thermo.validate("solid", "h", "e"); -} - -Foam::solvers::mappedInletTestSolver::mappedInletTestSolver(fvMesh & mesh) - : mappedInletTestSolver(mesh, solidThermo::New(mesh)) -{ - // Read the controls - read(); -} - -// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // - -Foam::solvers::mappedInletTestSolver::~mappedInletTestSolver() {} - -// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // - -Foam::scalar -Foam::solvers::mappedInletTestSolver::maxDeltaT() const -{ - return min(fvModels().maxDeltaT(), maxDeltaT_); -} - -void -Foam::solvers::mappedInletTestSolver::preSolve() -{ - fvModels().preUpdateMesh(); - - // Update the mesh for topology change, mesh to mesh mapping - mesh_.update(); -} - -void -Foam::solvers::mappedInletTestSolver::moveMesh() -{ - if (pimple.firstIter() || pimple.moveMeshOuterCorrectors()) - { - if (!mesh_.mover().solidBody()) - { - FatalErrorInFunction << "Region " << name() << " of type " << type() - << " does not support non-solid body mesh motion" << exit(FatalError); - } - - mesh_.move(); - } -} - -void -Foam::solvers::mappedInletTestSolver::motionCorrector() -{ -} - -void -Foam::solvers::mappedInletTestSolver::prePredictor() -{ -} - -void -Foam::solvers::mappedInletTestSolver::momentumPredictor() -{ - auto & coords = mesh.C().primitiveField(); - auto & U_field = U_.primitiveFieldRef(); - auto time = mesh.time().userTimeValue(); - - auto x = coords.component(0)(); - auto y = coords.component(1)(); - auto z = coords.component(2)(); - - U_field.replace(0, x + y + z + time); - U_field.replace(1, x - y + z + time); - U_field.replace(2, x + y - z + time); -} - -void -Foam::solvers::mappedInletTestSolver::thermophysicalPredictor() -{ - volScalarField & e = thermo.he(); - auto & coords = mesh.C().primitiveField(); - e.primitiveFieldRef() = mag(coords) + mesh.time().userTimeValue(); - thermo_.correct(); -} - -void -Foam::solvers::mappedInletTestSolver::pressureCorrector() -{ -} - -void -Foam::solvers::mappedInletTestSolver::postCorrector() -{ -} - -void -Foam::solvers::mappedInletTestSolver::postSolve() -{ -} - -// ************************************************************************* // diff --git a/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.H b/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.H deleted file mode 100644 index 24705868..00000000 --- a/test/OpenFOAM/modules/mappedInletTestSolver/mappedInletTestSolver.H +++ /dev/null @@ -1,152 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | Website: https://openfoam.org - \\ / A nd | Copyright (C) 2022-2023 OpenFOAM Foundation - \\/ M anipulation | -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see . - -Class - Foam::solvers::mappedInletTestSolver - -Description - Solver module for to test mapped inlet implementation method - -SourceFiles - mappedInletTestSolver.C - -\*---------------------------------------------------------------------------*/ - -#pragma once - -#include "solver.H" -#include "solidThermophysicalTransportModel.H" -#include "volFieldsFwd.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ -namespace solvers -{ - -/*---------------------------------------------------------------------------*\ - Class mappedInletTestSolver Declaration -\*---------------------------------------------------------------------------*/ - -class mappedInletTestSolver : public solver -{ - -protected: - // Control parameters - scalar maxDeltaT_; - - // Thermophysical properties - autoPtr thermoPtr_; - - solidThermo & thermo_; - - volScalarField T_; - - volVectorField U_; - - autoPtr thermophysicalTransport; - - // Protected Member Functions - - //- Return true if the solver's dependencies have been modified - virtual bool dependenciesModified() const; - - //- Read controls - virtual bool read(); - -public: - // Public Data - // reference to thermophysical properties - solidThermo & thermo; - - //- Reference to the temperature field - const volScalarField & T; - - //- Reference velocity field - const volVectorField & U; - - //- Runtime type information - TypeName("mappedInletTestSolver"); - - // Constructors - - //- Construct from region mesh - mappedInletTestSolver(fvMesh & mesh, autoPtr thermoPtr); - - mappedInletTestSolver(fvMesh & mesh); - - //- Disallow default bitwise copy construction - mappedInletTestSolver(const mappedInletTestSolver &) = delete; - - //- Destructor - virtual ~mappedInletTestSolver(); - - // Member Functions - - //- Return the current maximum time-step for stable solution - virtual scalar maxDeltaT() const; - - //- Called at the start of the time-step, before the PIMPLE loop - virtual void preSolve(); - - //- Called at the start of the PIMPLE loop to move the mesh - virtual void moveMesh(); - - //- Corrections that follow mesh motion - virtual void motionCorrector(); - - //- Called at the beginning of the PIMPLE loop - virtual void prePredictor(); - - //- Construct and optionally solve the momentum equation - virtual void momentumPredictor(); - - //- Construct and solve the energy equation, - // convert to temperature - // and update thermophysical and transport properties - virtual void thermophysicalPredictor(); - - //- Construct and solve the pressure equation in the PISO loop - virtual void pressureCorrector(); - - //- Correct the thermophysical transport modelling - virtual void postCorrector(); - - //- Called after the PIMPLE loop at the end of the time-step - virtual void postSolve(); - - // Member Operators - - //- Disallow default bitwise assignment - void operator=(const mappedInletTestSolver &) = delete; -}; - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace solvers -} // End namespace Foam - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -// ************************************************************************* // diff --git a/test/tests/bcs/mapped_inlet/foam/0/T b/test/tests/bcs/mapped_inlet/foam/0/T deleted file mode 100644 index 69c3f725..00000000 --- a/test/tests/bcs/mapped_inlet/foam/0/T +++ /dev/null @@ -1,56 +0,0 @@ -/*--------------------------------*- 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 2.; - -boundaryField -{ - left - { - type fixedValue; - value uniform 0.; - } - right - { - type calculated; - value uniform 0.; - } - top - { - type calculated; - value uniform 0.; - } - bottom - { - type fixedValue; - value uniform 0.; - } - back - { - type calculated; - value uniform 0.; - } - front - { - type fixedValue; - value uniform 0.; - } -} - - -// ************************************************************************* // diff --git a/test/tests/bcs/mapped_inlet/foam/0/U b/test/tests/bcs/mapped_inlet/foam/0/U deleted file mode 100644 index 15b296fa..00000000 --- a/test/tests/bcs/mapped_inlet/foam/0/U +++ /dev/null @@ -1,31 +0,0 @@ -/*--------------------------------*- 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 volVectorField; - location "0"; - object U; -} -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -dimensions [ 0 1 -1 0 0 0 0 ]; - -internalField uniform (1 -0.5 0.25); - -boundaryField -{ - - ".*" - { - type fixedValue; - value $internalField; - } -} - -// ************************************************************************* // diff --git a/test/tests/bcs/mapped_inlet/foam/0/rho b/test/tests/bcs/mapped_inlet/foam/0/rho deleted file mode 100644 index d30a04dc..00000000 --- a/test/tests/bcs/mapped_inlet/foam/0/rho +++ /dev/null @@ -1,56 +0,0 @@ -/*--------------------------------*- 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 volScalarField; - location "0"; - object rho; -} -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -dimensions [1 -3 0 0 0 0 0]; - -internalField uniform 1; - -boundaryField -{ - left - { - type calculated; - value uniform 1; - } - right - { - type calculated; - value uniform 1; - } - top - { - type calculated; - value uniform 1; - } - front - { - type calculated; - value uniform 1; - } - bottom - { - type calculated; - value uniform 1; - } - back - { - type calculated; - value uniform 1; - } -} - - -// ************************************************************************* // diff --git a/test/tests/bcs/mapped_inlet/foam/constant/g b/test/tests/bcs/mapped_inlet/foam/constant/g deleted file mode 100644 index 8af96f3a..00000000 --- a/test/tests/bcs/mapped_inlet/foam/constant/g +++ /dev/null @@ -1,21 +0,0 @@ -/*--------------------------------*- 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 uniformDimensionedVectorField; - location "constant"; - object g; -} -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -dimensions [0 1 -2 0 0 0 0]; -value (0 0 0); - - -// ************************************************************************* // diff --git a/test/tests/bcs/mapped_inlet/foam/constant/momentumTransport b/test/tests/bcs/mapped_inlet/foam/constant/momentumTransport deleted file mode 100644 index 0416f1a9..00000000 --- a/test/tests/bcs/mapped_inlet/foam/constant/momentumTransport +++ /dev/null @@ -1,18 +0,0 @@ -/*--------------------------------*- 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 RASProperties; -} -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -simulationType laminar; - -// ************************************************************************* // diff --git a/test/tests/bcs/mapped_inlet/foam/constant/physicalProperties b/test/tests/bcs/mapped_inlet/foam/constant/physicalProperties deleted file mode 100644 index 4c5dac6a..00000000 --- a/test/tests/bcs/mapped_inlet/foam/constant/physicalProperties +++ /dev/null @@ -1,52 +0,0 @@ -/*--------------------------------*- 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)] - mu 1.; - } - equationOfState - { - rho 0.5; // Density [kg/m^3] - } -} - - -// ************************************************************************* // diff --git a/test/tests/bcs/mapped_inlet/foam/system/blockMeshDict b/test/tests/bcs/mapped_inlet/foam/system/blockMeshDict deleted file mode 100644 index 8221a4b1..00000000 --- a/test/tests/bcs/mapped_inlet/foam/system/blockMeshDict +++ /dev/null @@ -1,85 +0,0 @@ -FoamFile -{ - version 2.0; - format ascii; - class dictionary; - object blockMeshDict; -} - -vertices -( - ( 0.0 0.0 0.0 ) - ( 2.0 0.0 0.0 ) - ( 2.0 2.0 0.0 ) - ( 0.0 2.0 0.0 ) - - ( 0.0 0.0 2.0) - ( 2.0 0.0 2.0) - ( 2.0 2.0 2.0) - ( 0.0 2.0 2.0) -); - -blocks -( - hex (0 1 2 3 4 5 6 7) (9 9 9) simpleGrading (1 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/bcs/mapped_inlet/foam/system/blockMeshDict.face_edge b/test/tests/bcs/mapped_inlet/foam/system/blockMeshDict.face_edge deleted file mode 100644 index 4a877e58..00000000 --- a/test/tests/bcs/mapped_inlet/foam/system/blockMeshDict.face_edge +++ /dev/null @@ -1,85 +0,0 @@ -FoamFile -{ - version 2.0; - format ascii; - class dictionary; - object blockMeshDict; -} - -vertices -( - ( 0.0 0.0 0.0 ) - ( 2.0 0.0 0.0 ) - ( 2.0 2.0 0.0 ) - ( 0.0 2.0 0.0 ) - - ( 0.0 0.0 2.0) - ( 2.0 0.0 2.0) - ( 2.0 2.0 2.0) - ( 0.0 2.0 2.0) -); - -blocks -( - hex (0 1 2 3 4 5 6 7) (8 8 8) simpleGrading (1 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/bcs/mapped_inlet/foam/system/blockMeshDict.orig b/test/tests/bcs/mapped_inlet/foam/system/blockMeshDict.orig deleted file mode 100644 index 8221a4b1..00000000 --- a/test/tests/bcs/mapped_inlet/foam/system/blockMeshDict.orig +++ /dev/null @@ -1,85 +0,0 @@ -FoamFile -{ - version 2.0; - format ascii; - class dictionary; - object blockMeshDict; -} - -vertices -( - ( 0.0 0.0 0.0 ) - ( 2.0 0.0 0.0 ) - ( 2.0 2.0 0.0 ) - ( 0.0 2.0 0.0 ) - - ( 0.0 0.0 2.0) - ( 2.0 0.0 2.0) - ( 2.0 2.0 2.0) - ( 0.0 2.0 2.0) -); - -blocks -( - hex (0 1 2 3 4 5 6 7) (9 9 9) simpleGrading (1 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/bcs/mapped_inlet/foam/system/controlDict b/test/tests/bcs/mapped_inlet/foam/system/controlDict deleted file mode 100644 index 2bbe0e5f..00000000 --- a/test/tests/bcs/mapped_inlet/foam/system/controlDict +++ /dev/null @@ -1,44 +0,0 @@ -/*--------------------------------*- 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 mappedInletTestSolver; - -startFrom startTime; - -startTime 0; - -stopAt endTime; - -endTime 5.; - -deltaT 1.; - -writeControl timeStep; - -writeInterval 1; - -writeFormat ascii; - -writePrecision 20; - -writeCompression off; - -timeFormat general; - -timePrecision 20; - -runTimeModifiable true; - -// ************************************************************************* // diff --git a/test/tests/bcs/mapped_inlet/foam/system/decomposeParDict b/test/tests/bcs/mapped_inlet/foam/system/decomposeParDict deleted file mode 100644 index 9df2378c..00000000 --- a/test/tests/bcs/mapped_inlet/foam/system/decomposeParDict +++ /dev/null @@ -1,42 +0,0 @@ -/*--------------------------------*- 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 5; - -method scotch; - -simpleCoeffs -{ - n (2 1 1); -} - -hierarchicalCoeffs -{ - n (1 1 1); - order xyz; -} - -manualCoeffs -{ - dataFile ""; -} - -distributed no; - -roots ( ); - - -// ************************************************************************* // diff --git a/test/tests/bcs/mapped_inlet/foam/system/decomposeParDict.face_edge b/test/tests/bcs/mapped_inlet/foam/system/decomposeParDict.face_edge deleted file mode 100644 index 0204a6b9..00000000 --- a/test/tests/bcs/mapped_inlet/foam/system/decomposeParDict.face_edge +++ /dev/null @@ -1,42 +0,0 @@ -/*--------------------------------*- 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 2; - -method simple; - -simpleCoeffs -{ - n (2 1 1); -} - -hierarchicalCoeffs -{ - n (1 1 1); - order xyz; -} - -manualCoeffs -{ - dataFile ""; -} - -distributed no; - -roots ( ); - - -// ************************************************************************* // diff --git a/test/tests/bcs/mapped_inlet/foam/system/decomposeParDict.orig b/test/tests/bcs/mapped_inlet/foam/system/decomposeParDict.orig deleted file mode 100644 index 9df2378c..00000000 --- a/test/tests/bcs/mapped_inlet/foam/system/decomposeParDict.orig +++ /dev/null @@ -1,42 +0,0 @@ -/*--------------------------------*- 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 5; - -method scotch; - -simpleCoeffs -{ - n (2 1 1); -} - -hierarchicalCoeffs -{ - n (1 1 1); - order xyz; -} - -manualCoeffs -{ - dataFile ""; -} - -distributed no; - -roots ( ); - - -// ************************************************************************* // diff --git a/test/tests/bcs/mapped_inlet/foam/system/fvSchemes b/test/tests/bcs/mapped_inlet/foam/system/fvSchemes deleted file mode 100644 index 787f3b83..00000000 --- a/test/tests/bcs/mapped_inlet/foam/system/fvSchemes +++ /dev/null @@ -1,51 +0,0 @@ -/*--------------------------------*- 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 none; - - div(phi,U) Gauss linear; - div(phi,K) Gauss linear; - div(phi,h) Gauss linear; - div(((rho*nuEff)*dev2(T(grad(U))))) Gauss linear; -} - -laplacianSchemes -{ - default Gauss linear corrected; -} - -interpolationSchemes -{ - default linear; -} - -snGradSchemes -{ - default corrected; -} - -// ************************************************************************* // diff --git a/test/tests/bcs/mapped_inlet/foam/system/fvSolution b/test/tests/bcs/mapped_inlet/foam/system/fvSolution deleted file mode 100644 index 61143b21..00000000 --- a/test/tests/bcs/mapped_inlet/foam/system/fvSolution +++ /dev/null @@ -1,61 +0,0 @@ -/*--------------------------------*- 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; - } - - - "(U|h|p_rgh)" - { - solver PBiCGStab; - preconditioner DILU; - tolerance 1e-8; - relTol 1e-8; - } - - "(U|h|p_rgh)Final" - { - $U; - tolerance 1e-8; - relTol 1e-8; - } -} - -PIMPLE -{ - momentumPredictor yes; - pRefCell 0; - pRefValue 0; -} - -relaxationFactors -{ - equations - { - h 1; - U 1; - } -} - -// ************************************************************************* // diff --git a/test/tests/bcs/mapped_inlet/main.i b/test/tests/bcs/mapped_inlet/main.i deleted file mode 100644 index 50a34648..00000000 --- a/test/tests/bcs/mapped_inlet/main.i +++ /dev/null @@ -1,76 +0,0 @@ -[Mesh] - type = FoamMesh - case = 'foam' - foam_patch = 'left right bottom top back front' -[] - -[FoamBCs] - [mass_flowx] - type=FoamMassFlowRateMappedInletBC - boundary = 'left' - default = 1 - translation_vector = '1. 0 0' - [] - [tempx] - type=FoamScalarBulkMappedInletBC - boundary = 'left' - default = 1 - translation_vector = '1. 0 0' - foam_variable = 'T' - [] - [mass_flowy] - type=FoamMassFlowRateMappedInletBC - boundary = 'bottom' - default = 1 - translation_vector = '0 1. 0' - [] - [tempy] - type=FoamScalarBulkMappedInletBC - boundary = 'bottom' - default = 1 - translation_vector = '0 1. 0' - foam_variable = 'T' - [] - [mass_flowz] - type=FoamMassFlowRateMappedInletBC - boundary = 'front' - default = 1 - translation_vector = '0 0 1.' - [] - [tempz] - type=FoamScalarBulkMappedInletBC - boundary = 'front' - default = 1 - translation_vector = '0 0 1.' - foam_variable = 'T' - [] -[] - -[Postprocessors] - [pp] - type = ParsedPostprocessor - expression = '2' - execute_on = TIMESTEP_BEGIN - [] -[] - - -[Problem] - type = FoamProblem - # Take the boundary temperature from OpenFOAM and set it on the MOOSE mesh. -[] - -[Executioner] - type = Transient - end_time = 5 - [TimeSteppers] - [foam] - type = FoamControlledTimeStepper - [] - [] -[] - -[Outputs] - exodus = true - csv=true -[] diff --git a/test/tests/bcs/mapped_inlet/main_rotated.i b/test/tests/bcs/mapped_inlet/main_rotated.i deleted file mode 100644 index 553b6d3d..00000000 --- a/test/tests/bcs/mapped_inlet/main_rotated.i +++ /dev/null @@ -1,50 +0,0 @@ -[Mesh] - type = FoamMesh - case = 'foam' - foam_patch = 'left right bottom top back front' -[] - -[FoamBCs] - [mass_flowx] - type=FoamMassFlowRateMappedInletBC - boundary = 'left' - default = 1 - translation_vector = '${fparse sqrt(0.5)} ${fparse sqrt(0.5)} 0' - [] - [tempx] - type=FoamScalarBulkMappedInletBC - boundary = 'left' - default = 1 - translation_vector = '${fparse sqrt(0.5)} ${fparse sqrt(0.5)} 0' - foam_variable = 'T' - [] -[] - -[Postprocessors] - [pp] - type = ParsedPostprocessor - expression = '2' - execute_on = TIMESTEP_BEGIN - [] -[] - - -[Problem] - type = FoamProblem - # Take the boundary temperature from OpenFOAM and set it on the MOOSE mesh. -[] - -[Executioner] - type = Transient - end_time = 5 - [TimeSteppers] - [foam] - type = FoamControlledTimeStepper - [] - [] -[] - -[Outputs] - exodus = true - csv=true -[] diff --git a/test/tests/bcs/mapped_inlet/test.py b/test/tests/bcs/mapped_inlet/test.py deleted file mode 100644 index 015437dc..00000000 --- a/test/tests/bcs/mapped_inlet/test.py +++ /dev/null @@ -1,91 +0,0 @@ -"""Tests for imposing BCs in OpenFOAM using MOOSE input file syntax""" - -import unittest -import fluidfoam as ff -import numpy as np - -from read_hippo_data import get_foam_times - -CASE_DIR = "foam/" -TIMES = get_foam_times(CASE_DIR, string=True)[1:] - - -class TestFoamBCMappedInlet(unittest.TestCase): - """Test class for mapped inlet BCs in Hippo.""" - - def test_mapped_inlet(self): - """Test case for mapped inlet.""" - - for i in range(len(TIMES)): - self._check_u_temp_refs(i, "left", [1.0, 0, 0]) - self._check_u_temp_refs(i, "bottom", [0, 1.0, 0]) - self._check_u_temp_refs(i, "front", [0, 0, 1.0]) - - def test_mapped_inlet_subtract(self): - """Test case for mapped inlet when temperature is scaled by subtracting the difference in bulk.""" - - for i in range(len(TIMES)): - self._check_u_temp_refs(i, "left", [1.0, 0, 0], False) - self._check_u_temp_refs(i, "bottom", [0, 1.0, 0], False) - self._check_u_temp_refs(i, "front", [0, 0, 1.0], False) - - def test_mapped_inlet_rotated(self): - """Test case for when inlet's are not aligned with the axis.""" - for i in range(len(TIMES)): - self._check_u_temp_refs(i, "left", [np.sqrt(0.5), np.sqrt(0.5), 0]) - - def test_mapped_inlet_face_point(self): - """Test case for mapped inlet where the point is on the interface between boundaries.""" - - for i in range(len(TIMES)): - self._check_u_temp_refs(i, "left", [7.0 / 8, 0, 0]) - self._check_u_temp_refs(i, "bottom", [0, 7.0 / 8, 0]) - self._check_u_temp_refs(i, "front", [0, 0, 7.0 / 8]) - - def _check_u_temp_refs(self, idx, boundary, offset, use_scale=True): - rho = 0.5 - mdot_pp = 1 - t_pp = 1 - time = TIMES[idx] - - x, y, z = ff.readof.readmesh(CASE_DIR, boundary=boundary) - u = ff.readof.readvector(CASE_DIR, time, "U", boundary=boundary).T - temp = ff.readof.readscalar(CASE_DIR, time, "T", boundary=boundary) - - x += offset[0] - y += offset[1] - z += offset[2] - - if idx != 0: - t = np.float64(TIMES[idx - 1]) - u_ref = np.array( - [ - x + y + z + t, - x - y + z + t, - x + y - z + t, - ] - ).T - temp_ref = np.sqrt(x * x + y * y + z * z) + t - else: - # first time step uses initialised value - u_ref = np.array([[1, -0.5, 0.25]]) - temp_ref = 2 - - area = 4.0 - normal = np.array(offset) / np.linalg.norm(offset) - mdot = rho * np.mean(np.vecdot(u_ref, normal)) * area - u_ref *= mdot_pp / mdot - - t_bulk = np.mean(temp_ref) - if use_scale: - temp_ref *= t_pp / t_bulk - else: - temp_ref += t_pp - t_bulk - - assert np.allclose(u_ref, u, rtol=1e-7, atol=1e-12), ( - f"Max diff ({boundary}) (velocity) ({TIMES[idx]}): {abs(u - u_ref).max()} " - ) - - assert np.allclose(temp_ref, temp, rtol=1e-7, atol=1e-12), ( - f"Max diff ({boundary}) (temperature) ({time}): {abs(temp - temp_ref).max()} {temp} {temp_ref}" - ) diff --git a/test/tests/bcs/mapped_inlet/tests b/test/tests/bcs/mapped_inlet/tests deleted file mode 100644 index cc19eb5a..00000000 --- a/test/tests/bcs/mapped_inlet/tests +++ /dev/null @@ -1,153 +0,0 @@ -[Tests] - [mapped_mass_flow_receiver] - [setup] - type = RunCommand - command = 'bash -c "foamCleanCase -case foam && blockMesh -case foam && decomposePar -case foam"' - [] - [run_err] - type = RunException - input = main.i - prereq = mapped_mass_flow_receiver/setup - allow_warnings = true - min_parallel = 5 - max_parallel = 5 - cli_args = "FoamBCs/mass_flowx/translation_vector='-0.5 0 0'" - expect_err = "does not have a mapped plane location" - [] - [run] - type = RunApp - input = main.i - prereq = mapped_mass_flow_receiver/setup - allow_warnings = true - min_parallel = 5 - max_parallel = 5 - [] - [reconstruct] - type = RunCommand - command = 'reconstructPar -case foam' - prereq = mapped_mass_flow_receiver/run - [] - [verify] - type = PythonUnitTest - input = test.py - prereq = mapped_mass_flow_receiver/reconstruct - test_case = 'TestFoamBCMappedInlet.test_mapped_inlet' - [] - [] - [mapped_mass_flow_subtract] - [setup] - type = RunCommand - command = 'bash -c "foamCleanCase -case foam && blockMesh -case foam && decomposePar -case foam"' - [] - [run] - type = RunApp - input = main.i - prereq = mapped_mass_flow_receiver/setup - allow_warnings = true - min_parallel = 5 - max_parallel = 5 - cli_args = "FoamBCs/tempx/scale_method=subtract FoamBCs/tempy/scale_method=subtract FoamBCs/tempz/scale_method=subtract" - [] - [reconstruct] - type = RunCommand - command = 'reconstructPar -case foam' - prereq = mapped_mass_flow_receiver/run - [] - [verify] - type = PythonUnitTest - input = test.py - prereq = mapped_mass_flow_receiver/reconstruct - test_case = 'TestFoamBCMappedInlet.test_mapped_inlet_subtract' - [] - [] - [mapped_mass_flow] - [setup] - type = RunCommand - command = 'bash -c "foamCleanCase -case foam && blockMesh -case foam && decomposePar -case foam"' - prereq = mapped_mass_flow_receiver/reconstruct - [] - [run] - type = RunApp - input = main.i - prereq = mapped_mass_flow/setup - allow_warnings = true - min_parallel = 5 - max_parallel = 5 - cli_args = 'FoamBCs/mass_flowx/pp=pp FoamBCs/tempx/pp=pp FoamBCs/mass_flowy/pp=pp FoamBCs/tempy/pp=pp FoamBCs/mass_flowz/pp=pp FoamBCs/tempz/pp=pp Postprocessors/pp/expression=1' - [] - [reconstruct] - type = RunCommand - command = 'reconstructPar -case foam' - prereq = mapped_mass_flow/run - [] - [verify] - type = PythonUnitTest - input = test.py - prereq = mapped_mass_flow/reconstruct - test_case = 'TestFoamBCMappedInlet.test_mapped_inlet' - [] - [] - [mapped_rotated] - [setup] - type = RunCommand - command = 'bash -c "foamCleanCase -case foam && blockMesh -case foam && transformPoints -case foam "Rz=45" && decomposePar -case foam"' - prereq = mapped_mass_flow/reconstruct - [] - [run] - type = RunApp - input = main_rotated.i - prereq = mapped_rotated/setup - allow_warnings = true - min_parallel = 5 - max_parallel = 5 - [] - [reconstruct] - type = RunCommand - command = 'reconstructPar -case foam' - prereq = mapped_rotated/run - [] - [verify] - type = PythonUnitTest - input = test.py - prereq = mapped_rotated/reconstruct - test_case = 'TestFoamBCMappedInlet.test_mapped_inlet_rotated' - [] - [] - [face_edge_case] - [update_mesh] - type = RunCommand - command = 'bash -c "foamCleanCase -case foam && cp foam/system/blockMeshDict.face_edge foam/system/blockMeshDict && cp foam/system/decomposeParDict.face_edge foam/system/decomposeParDict"' - prereq = mapped_rotated/verify - [] - [setup] - type = RunCommand - command = 'bash -c "blockMesh -case foam && decomposePar -case foam"' - prereq = face_edge_case/update_mesh - [] - [run] - type = RunApp - input = main.i - prereq = face_edge_case/setup - allow_warnings = true - min_parallel = 2 - max_parallel = 2 - [] - [reconstruct] - type = RunCommand - command = 'reconstructPar -case foam' - prereq = face_edge_case/run - [] - [verify] - type = PythonUnitTest - input = test.py - prereq = face_edge_case/reconstruct - test_case = 'TestFoamBCMappedInlet.test_mapped_inlet_face_point' - [] - [reset_mesh] - type = RunCommand - command = 'bash -c "cp foam/system/blockMeshDict.orig foam/system/blockMeshDict && cp foam/system/decomposeParDict.orig foam/system/decomposeParDict"' - prereq = 'face_edge_case/update_mesh' - [] - [] - -[] From 700655a3505192c279aaddb01772f010222c665d Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Tue, 10 Feb 2026 10:46:08 +0000 Subject: [PATCH 38/52] Remove thermal hydraulics from modules --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ad5757dc..4c6713fb 100644 --- a/Makefile +++ b/Makefile @@ -46,7 +46,7 @@ RDG := no RICHARDS := no STOCHASTIC_TOOLS := no TENSOR_MECHANICS := no -THERMAL_HYDRAULICS := yes +THERMAL_HYDRAULICS := no XFEM := no include $(MOOSE_DIR)/modules/modules.mk From af9690f44b8311dd7779dc27678db99f79f7e778 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Tue, 10 Feb 2026 11:07:56 +0000 Subject: [PATCH 39/52] Remove unnecessary verify test from mass flow rate BC --- test/tests/bcs/mass_flow_rate/tests | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/tests/bcs/mass_flow_rate/tests b/test/tests/bcs/mass_flow_rate/tests index 91f63a7a..68cf4430 100644 --- a/test/tests/bcs/mass_flow_rate/tests +++ b/test/tests/bcs/mass_flow_rate/tests @@ -11,10 +11,5 @@ csvdiff = main_out.csv allow_warnings = true [] - [verify] - type = PythonUnitTest - input = test.py - prereq = mass_flow_rate/run - [] [] [] From 0b060678c1dc2109478290208bb9e8716faf2321 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Tue, 10 Feb 2026 15:38:37 +0000 Subject: [PATCH 40/52] Remove unnecessary parameters from BCs --- src/bcs/FoamBCBase.C | 1 - src/bcs/FoamMassFlowRateInletBC.C | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/bcs/FoamBCBase.C b/src/bcs/FoamBCBase.C index bf637bf7..5ab066a4 100644 --- a/src/bcs/FoamBCBase.C +++ b/src/bcs/FoamBCBase.C @@ -25,7 +25,6 @@ FoamBCBase::validParams() params.addRequiredParam("foam_variable", "Name of a Foam field. e.g. T (temperature) U (velocity)."); - params.addPrivateParam("_foam_var_settable", true); params.registerSystemAttributeName("FoamBC"); params.registerBase("FoamBC"); diff --git a/src/bcs/FoamMassFlowRateInletBC.C b/src/bcs/FoamMassFlowRateInletBC.C index 785061cf..925cd424 100644 --- a/src/bcs/FoamMassFlowRateInletBC.C +++ b/src/bcs/FoamMassFlowRateInletBC.C @@ -12,8 +12,8 @@ FoamMassFlowRateInletBC::validParams() auto params = FoamPostprocessorBCBase::validParams(); params.addParam("scale_factor", 1., "Scale factor multiply mass flow rate pp by."); - params.remove("foam_variable"); - params.addPrivateParam("foam_variable", "U"); + params.suppressParameter("foam_variable"); + params.set("foam_variable") = "U"; return params; } From 78a8abae75e70c3963aeb45130e2fd26f85ec454 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Tue, 10 Feb 2026 16:36:00 +0000 Subject: [PATCH 41/52] Minor refactor after review --- include/bcs/FoamVariableBCBase.h | 2 +- include/mesh/FoamMesh.h | 11 +++++++++-- src/bcs/FoamFixedGradientPostprocessorBC.C | 11 ++--------- src/bcs/FoamFixedValueBC.C | 8 ++------ src/bcs/FoamFixedValuePosprocessorBC.C | 7 +------ src/bcs/FoamVariableBCBase.C | 8 ++++---- 6 files changed, 19 insertions(+), 28 deletions(-) diff --git a/include/bcs/FoamVariableBCBase.h b/include/bcs/FoamVariableBCBase.h index 00300294..ccc2bce7 100644 --- a/include/bcs/FoamVariableBCBase.h +++ b/include/bcs/FoamVariableBCBase.h @@ -19,7 +19,7 @@ class FoamVariableBCBase : public FoamBCBase protected: // Get the value of the MOOSE variable at an element - Real variableValueAtElement(const libMesh::Elem * elem); + Real variableValueAtElement(const libMesh::Elem & elem); // Get the data vector of the MOOSE field on a subdomain std::vector getMooseVariableArray(int subdomainId); diff --git a/include/mesh/FoamMesh.h b/include/mesh/FoamMesh.h index 3643248d..b4cf892c 100644 --- a/include/mesh/FoamMesh.h +++ b/include/mesh/FoamMesh.h @@ -63,12 +63,19 @@ class FoamMesh : public MooseMesh return _foam_mesh.foundObject(name); } + // Returns the patch array for field and subdomain + template + Foam::fvPatchField & getBCField(SubdomainID subdomain, Foam::word const & field) + { + return const_cast &>( + _foam_mesh.boundary()[subdomain].lookupPatchField(field)); + } + // Returns the gradient BC array for field and subdomain template Foam::Field & getGradientBCField(SubdomainID subdomain, Foam::word const & field) { - auto & var = const_cast &>( - _foam_mesh.boundary()[subdomain].lookupPatchField(field)); + auto & var = getBCField(subdomain, field); return Foam::refCast>(var).gradient(); } diff --git a/src/bcs/FoamFixedGradientPostprocessorBC.C b/src/bcs/FoamFixedGradientPostprocessorBC.C index 392311aa..91b3dfaf 100644 --- a/src/bcs/FoamFixedGradientPostprocessorBC.C +++ b/src/bcs/FoamFixedGradientPostprocessorBC.C @@ -1,7 +1,6 @@ #include "FoamFixedGradientPostprocessorBC.h" #include "PstreamReduceOps.H" #include "Registry.h" -#include "fixedGradientFvPatchFields.H" #include registerMooseObject("hippoApp", FoamFixedGradientPostprocessorBC); @@ -34,19 +33,13 @@ FoamFixedGradientPostprocessorBC::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); for (auto subdomain : subdomains) { auto & boundary = foam_mesh.boundary()[subdomain]; // Get underlying field from OpenFOAM boundary patch. - // TODO: Change to function on rebase - auto & var = const_cast &>( - boundary.lookupPatchField(_foam_variable)); - - // Get the gradient associated with the field - Foam::scalarField & foam_gradient( - Foam::refCast(var).gradient()); + auto & foam_gradient = + _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 b072695b..29c7b0dc 100644 --- a/src/bcs/FoamFixedValueBC.C +++ b/src/bcs/FoamFixedValueBC.C @@ -1,6 +1,7 @@ #include "FoamFixedValueBC.h" #include "InputParameters.h" #include "MooseTypes.h" +#include registerMooseObject("hippoApp", FoamFixedValueBC); @@ -21,19 +22,14 @@ FoamFixedValueBC::FoamFixedValueBC(const InputParameters & parameters) void FoamFixedValueBC::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); for (auto subdomain : subdomains) { std::vector && var_array = getMooseVariableArray(subdomain); // Get underlying field from OpenFOAM boundary patch - auto & foam_var = const_cast &>( - foam_mesh.boundary()[subdomain].lookupPatchField( - _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 5614196e..03958d0d 100644 --- a/src/bcs/FoamFixedValuePosprocessorBC.C +++ b/src/bcs/FoamFixedValuePosprocessorBC.C @@ -17,17 +17,12 @@ FoamFixedValuePostprocessorBC::FoamFixedValuePostprocessorBC(const InputParamete void FoamFixedValuePostprocessorBC::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); for (auto subdomain : subdomains) { // Get underlying field from OpenFOAM boundary patch - auto & foam_var = const_cast &>( - foam_mesh.boundary()[subdomain].lookupPatchField( - _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/FoamVariableBCBase.C b/src/bcs/FoamVariableBCBase.C index 4caa83b6..4bf86889 100644 --- a/src/bcs/FoamVariableBCBase.C +++ b/src/bcs/FoamVariableBCBase.C @@ -55,10 +55,10 @@ FoamVariableBCBase::addInfoRow(BCInfoTable & table) } Real -FoamVariableBCBase::variableValueAtElement(const libMesh::Elem * elem) +FoamVariableBCBase::variableValueAtElement(const libMesh::Elem & elem) { auto & sys = _moose_var->sys(); - auto dof = elem->dof_number(sys.number(), _moose_var->number(), 0); + auto dof = elem.dof_number(sys.number(), _moose_var->number(), 0); return sys.solution()(dof); } @@ -72,9 +72,9 @@ FoamVariableBCBase::getMooseVariableArray(int subdomainId) for (size_t j = 0; j < patch_count; ++j) { auto elem = patch_offset + j; - 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); + var_array[j] = variableValueAtElement(*elem_ptr); } return var_array; From 734057c033026ee64d06fded789143e457a55556 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Tue, 10 Feb 2026 16:52:45 +0000 Subject: [PATCH 42/52] Move listFromVector to internals namespace --- include/bcs/FoamBCBase.h | 15 --------------- include/util/hippoUtils.h | 15 +++++++++++++++ src/bcs/FoamPostprocessorBCBase.C | 8 +++++++- src/bcs/FoamVariableBCBase.C | 8 ++++++-- src/problems/FoamProblem.C | 25 ++++++++++++------------- 5 files changed, 40 insertions(+), 31 deletions(-) diff --git a/include/bcs/FoamBCBase.h b/include/bcs/FoamBCBase.h index bce3c3d5..69fbfcb6 100644 --- a/include/bcs/FoamBCBase.h +++ b/include/bcs/FoamBCBase.h @@ -11,21 +11,6 @@ typedef VariadicTable BCInfoTable; -template -inline std::string -listFromVector(std::vector vec, StrType sep = ", ") -{ - if (vec.size() == 0) - return std::string(); - else if (vec.size() == 1) - return vec.at(0); - - std::string str; - auto binary_op = [&](const std::string & acc, const std::string & it) { return acc + sep + it; }; - std::accumulate(vec.begin(), vec.end(), str, binary_op); - return str; -} - class FoamBCBase : public MooseObject, public Coupleable { public: diff --git a/include/util/hippoUtils.h b/include/util/hippoUtils.h index de43b41d..fa13e0f7 100644 --- a/include/util/hippoUtils.h +++ b/include/util/hippoUtils.h @@ -13,5 +13,20 @@ copyParamFromParam(InputParameters & dst, const InputParameters & src, const std if (src.isParamValid(name_in)) dst.set(name_in) = src.get(name_in); } + +template +inline std::string +listFromVector(std::vector vec, StrType sep = ", ") +{ + if (vec.size() == 0) + return std::string(); + else if (vec.size() == 1) + return vec.at(0); + + std::string str; + auto binary_op = [&](const std::string & acc, const std::string & it) { return acc + sep + it; }; + std::accumulate(vec.begin(), vec.end(), str, binary_op); + return str; +} } } diff --git a/src/bcs/FoamPostprocessorBCBase.C b/src/bcs/FoamPostprocessorBCBase.C index b8323a3d..7deb88b2 100644 --- a/src/bcs/FoamPostprocessorBCBase.C +++ b/src/bcs/FoamPostprocessorBCBase.C @@ -1,5 +1,7 @@ #include "FoamBCBase.h" #include "FoamPostprocessorBCBase.h" +#include "hippoUtils.h" + #include "InputParameters.h" #include "MooseTypes.h" #include "PostprocessorInterface.h" @@ -29,5 +31,9 @@ FoamPostprocessorBCBase::FoamPostprocessorBCBase(const InputParameters & params) void FoamPostprocessorBCBase::addInfoRow(BCInfoTable & table) { - table.addRow(name(), type(), foamVariable(), moosePostprocessor(), listFromVector(boundary())); + table.addRow(name(), + type(), + foamVariable(), + moosePostprocessor(), + Hippo::internal::listFromVector(boundary())); } diff --git a/src/bcs/FoamVariableBCBase.C b/src/bcs/FoamVariableBCBase.C index 4bf86889..bd88208e 100644 --- a/src/bcs/FoamVariableBCBase.C +++ b/src/bcs/FoamVariableBCBase.C @@ -1,5 +1,8 @@ -#include "FEProblemBase.h" + #include "FoamVariableBCBase.h" +#include "hippoUtils.h" + +#include "FEProblemBase.h" namespace { @@ -51,7 +54,8 @@ void FoamVariableBCBase::addInfoRow(BCInfoTable & table) { // List info about BC - table.addRow(name(), type(), foamVariable(), mooseVariable(), listFromVector(boundary())); + table.addRow( + name(), type(), foamVariable(), mooseVariable(), Hippo::internal::listFromVector(boundary())); } Real diff --git a/src/problems/FoamProblem.C b/src/problems/FoamProblem.C index 7146148d..e15f2afb 100644 --- a/src/problems/FoamProblem.C +++ b/src/problems/FoamProblem.C @@ -1,27 +1,26 @@ -#include "Attributes.h" -#include "ExternalProblem.h" +#include "FoamVariableField.h" #include "FoamMesh.h" #include "FoamProblem.h" #include "FoamSolver.h" -#include "VariadicTable.h" -#include "word.H" +#include "hippoUtils.h" -#include -#include -#include -#include -#include -#include "FoamVariableField.h" +#include "Attributes.h" +#include "ExternalProblem.h" +#include "VariadicTable.h" +#include "MooseTypes.h" #include "InputParameters.h" #include "VariadicTable.h" + #include +#include #include #include #include - #include #include +#include + registerMooseObject("hippoApp", FoamProblem); InputParameters @@ -175,7 +174,7 @@ FoamProblem::verifyFoamBCs() unused_bcs.push_back(bc); } if (unused_bcs.size() > 0) - vt.addRow("", "UnusedBoundaries", "", "", listFromVector(unused_bcs)); + vt.addRow("", "UnusedBoundaries", "", "", Hippo::internal::listFromVector(unused_bcs)); } vt.print(_console); } @@ -200,7 +199,7 @@ FoamProblem::verifyFoamPostprocessors() if (fpp) { _foam_postprocessor.push_back(fpp); - vt.addRow(fpp->name(), fpp->type(), listFromVector(fpp->blocks())); + vt.addRow(fpp->name(), fpp->type(), Hippo::internal::listFromVector(fpp->blocks())); } } From d96ddafd0706e1090158d1a8da09cb6d53a90282 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Mon, 20 Apr 2026 13:35:52 +0100 Subject: [PATCH 43/52] Remove FoamControlledTimeStepper after rebase --- test/tests/bcs/fixed_gradient_pp/main.i | 2 +- test/tests/bcs/fixed_value_pp/main.i | 2 +- test/tests/bcs/mass_flow_rate/main.i | 2 +- test/tests/bcs/receiver_pp/main.i | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/tests/bcs/fixed_gradient_pp/main.i b/test/tests/bcs/fixed_gradient_pp/main.i index cce2ed4a..41bf0d73 100644 --- a/test/tests/bcs/fixed_gradient_pp/main.i +++ b/test/tests/bcs/fixed_gradient_pp/main.i @@ -46,7 +46,7 @@ end_time = 32 [TimeSteppers] [foam] - type = FoamControlledTimeStepper + type = FoamTimeStepper [] [] [] diff --git a/test/tests/bcs/fixed_value_pp/main.i b/test/tests/bcs/fixed_value_pp/main.i index c49df10a..0e4cdedf 100644 --- a/test/tests/bcs/fixed_value_pp/main.i +++ b/test/tests/bcs/fixed_value_pp/main.i @@ -67,7 +67,7 @@ end_time = 0.32 [TimeSteppers] [foam] - type = FoamControlledTimeStepper + type = FoamTimeStepper [] [] [] diff --git a/test/tests/bcs/mass_flow_rate/main.i b/test/tests/bcs/mass_flow_rate/main.i index 43fc5346..f5848106 100644 --- a/test/tests/bcs/mass_flow_rate/main.i +++ b/test/tests/bcs/mass_flow_rate/main.i @@ -37,7 +37,7 @@ end_time = 0.32 [TimeSteppers] [foam] - type = FoamControlledTimeStepper + type = FoamTimeStepper [] [] [] diff --git a/test/tests/bcs/receiver_pp/main.i b/test/tests/bcs/receiver_pp/main.i index cd1da1a7..740fb948 100644 --- a/test/tests/bcs/receiver_pp/main.i +++ b/test/tests/bcs/receiver_pp/main.i @@ -38,7 +38,7 @@ end_time = 1 [TimeSteppers] [foam] - type = FoamControlledTimeStepper + type = FoamTimeStepper [] [] [] From 8e327fbe213c263a3c0a46c36a863e1b29917453 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Fri, 22 May 2026 12:20:45 +0100 Subject: [PATCH 44/52] Update after code review --- include/bcs/FoamBCBase.h | 4 ++-- include/bcs/FoamPostprocessorBCBase.h | 8 ++++---- include/bcs/FoamVariableBCBase.h | 13 +++++++------ include/util/hippoUtils.h | 5 ++--- src/actions/AddFoamBCAction.C | 5 +++-- src/bcs/FoamMassFlowRateInletBC.C | 8 ++++---- src/bcs/FoamPostprocessorBCBase.C | 24 +++++++++++++----------- src/bcs/FoamVariableBCBase.C | 25 +++++++++++++------------ src/problems/FoamProblem.C | 3 ++- test/tests/bcs/fixed_gradient_pp/main.i | 2 +- test/tests/bcs/fixed_value_pp/main.i | 4 ++-- test/tests/bcs/mass_flow_rate/main.i | 2 +- 12 files changed, 54 insertions(+), 49 deletions(-) diff --git a/include/bcs/FoamBCBase.h b/include/bcs/FoamBCBase.h index 69fbfcb6..3f5d369a 100644 --- a/include/bcs/FoamBCBase.h +++ b/include/bcs/FoamBCBase.h @@ -9,7 +9,7 @@ #include #include "VariadicTable.h" -typedef VariadicTable BCInfoTable; +typedef std::tuple BCInfoTableRow; class FoamBCBase : public MooseObject, public Coupleable { @@ -32,7 +32,7 @@ class FoamBCBase : public MooseObject, public Coupleable virtual void initialSetup() = 0; // Add information about BC to table - virtual void addInfoRow(BCInfoTable & table) = 0; + virtual BCInfoTableRow addInfoRow() const = 0; protected: // OpenFOAM variable which this BC is to be imposed on diff --git a/include/bcs/FoamPostprocessorBCBase.h b/include/bcs/FoamPostprocessorBCBase.h index be37f63d..b7fb7eeb 100644 --- a/include/bcs/FoamPostprocessorBCBase.h +++ b/include/bcs/FoamPostprocessorBCBase.h @@ -12,16 +12,16 @@ class FoamPostprocessorBCBase : public FoamBCBase, public PostprocessorInterface explicit FoamPostprocessorBCBase(const InputParameters & params); - // returns the moose AuxVariable imposed on OpenFOAM + // returns the moose Postprocessor imposed on OpenFOAM VariableName moosePostprocessor() const { return _pp_name; } - virtual void initialSetup() {}; + virtual void initialSetup() override {}; - virtual void addInfoRow(BCInfoTable & table); + virtual BCInfoTableRow addInfoRow() const override; protected: const PostprocessorName _pp_name; - // Pointer to Moose variable used to impose BC + // Reference to Moose PostprocessorValue used to impose BC const PostprocessorValue & _pp_value; }; diff --git a/include/bcs/FoamVariableBCBase.h b/include/bcs/FoamVariableBCBase.h index ccc2bce7..08fa2489 100644 --- a/include/bcs/FoamVariableBCBase.h +++ b/include/bcs/FoamVariableBCBase.h @@ -2,6 +2,7 @@ #include "FoamBCBase.h" #include "InputParameters.h" +#include class FoamVariableBCBase : public FoamBCBase { @@ -11,19 +12,19 @@ class FoamVariableBCBase : public FoamBCBase explicit FoamVariableBCBase(const InputParameters & params); // returns the moose AuxVariable imposed on OpenFOAM - VariableName mooseVariable() const { return _moose_var->name(); } + VariableName mooseVariable() const { return _moose_var->get().name(); } - virtual void initialSetup(); + virtual void initialSetup() override; - virtual void addInfoRow(BCInfoTable & table); + virtual BCInfoTableRow addInfoRow() const override; protected: // Get the value of the MOOSE variable at an element - Real variableValueAtElement(const libMesh::Elem & elem); + Real variableValueAtElement(const libMesh::Elem & elem) const; // Get the data vector of the MOOSE field on a subdomain - std::vector getMooseVariableArray(int subdomainId); + std::vector getMooseVariableArray(int subdomainId) const; // Pointer to Moose variable used to impose BC - MooseVariableFieldBase * _moose_var; + std::optional> _moose_var; }; diff --git a/include/util/hippoUtils.h b/include/util/hippoUtils.h index fa13e0f7..d684bab6 100644 --- a/include/util/hippoUtils.h +++ b/include/util/hippoUtils.h @@ -23,10 +23,9 @@ listFromVector(std::vector vec, StrType sep = ", ") else if (vec.size() == 1) return vec.at(0); - std::string str; + std::string str{vec[0]}; auto binary_op = [&](const std::string & acc, const std::string & it) { return acc + sep + it; }; - std::accumulate(vec.begin(), vec.end(), str, binary_op); - return str; + return std::accumulate(vec.begin() + 1, vec.end(), str, binary_op); } } } diff --git a/src/actions/AddFoamBCAction.C b/src/actions/AddFoamBCAction.C index 84767518..f56ee815 100644 --- a/src/actions/AddFoamBCAction.C +++ b/src/actions/AddFoamBCAction.C @@ -41,8 +41,9 @@ AddFoamBCAction::act() if (findParamKey(_moose_object_pars, "v") && !_moose_object_pars.isParamSetByUser("v")) createAuxVariable(); - // Create receiver if pp not provided and pp is an allowed parameter - if (findParamKey(_moose_object_pars, "pp") && !_moose_object_pars.isParamSetByUser("pp")) + // 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); foam_problem->addObject(_type, _name, _moose_object_pars, false); diff --git a/src/bcs/FoamMassFlowRateInletBC.C b/src/bcs/FoamMassFlowRateInletBC.C index 925cd424..b458c6fa 100644 --- a/src/bcs/FoamMassFlowRateInletBC.C +++ b/src/bcs/FoamMassFlowRateInletBC.C @@ -11,7 +11,7 @@ FoamMassFlowRateInletBC::validParams() { auto params = FoamPostprocessorBCBase::validParams(); - params.addParam("scale_factor", 1., "Scale factor multiply mass flow rate pp by."); + params.addParam("scale_factor", 1., "Scale factor multiply mass flow rate pp_name by."); params.suppressParameter("foam_variable"); params.set("foam_variable") = "U"; @@ -33,12 +33,12 @@ FoamMassFlowRateInletBC::imposeBoundaryCondition() auto subdomains = _mesh->getSubdomainIDs(_boundary); for (auto subdomain : subdomains) { - auto & boundary_patch = foam_mesh.boundary()[subdomain]; + const auto & boundary_patch = foam_mesh.boundary()[subdomain]; auto & U_var = const_cast &>( boundary_patch.lookupPatchField("U")); - auto & rho = boundary_patch.lookupPatchField("rho"); - Real area = Foam::returnReduce(Foam::sum(boundary_patch.magSf()), Foam::sumOp()); + const auto & rho = boundary_patch.lookupPatchField("rho"); + const Real area = Foam::returnReduce(Foam::sum(boundary_patch.magSf()), Foam::sumOp()); U_var == -_scale_factor * _pp_value * boundary_patch.nf() / (rho * area); } } diff --git a/src/bcs/FoamPostprocessorBCBase.C b/src/bcs/FoamPostprocessorBCBase.C index 7deb88b2..e0c75bac 100644 --- a/src/bcs/FoamPostprocessorBCBase.C +++ b/src/bcs/FoamPostprocessorBCBase.C @@ -6,13 +6,14 @@ #include "MooseTypes.h" #include "PostprocessorInterface.h" #include "Receiver.h" +#include InputParameters FoamPostprocessorBCBase::validParams() { auto params = FoamBCBase::validParams(); - params.addParam("pp", "optional postprocessor to be used in BC"); + params.addParam("pp_name", "optional postprocessor to be used in BC"); params.transferParam(Receiver::validParams(), "default"); return params; @@ -21,19 +22,20 @@ FoamPostprocessorBCBase::validParams() FoamPostprocessorBCBase::FoamPostprocessorBCBase(const InputParameters & params) : FoamBCBase(params), PostprocessorInterface(this), - _pp_name((params.isParamSetByUser("pp")) ? params.get("pp") : _name), + _pp_name((params.isParamSetByUser("pp_name")) ? params.get("pp_name") + : _name), _pp_value(getPostprocessorValueByName(_pp_name)) { - if (params.isParamSetByUser("pp") && params.isParamSetByUser("default")) - mooseWarning("'pp' and 'default' should not both be set. 'default' ignored."); + if (params.isParamSetByUser("pp_name") && params.isParamSetByUser("default")) + mooseWarning("'pp_name' and 'default' should not both be set. 'default' ignored."); } -void -FoamPostprocessorBCBase::addInfoRow(BCInfoTable & table) +BCInfoTableRow +FoamPostprocessorBCBase::addInfoRow() const { - table.addRow(name(), - type(), - foamVariable(), - moosePostprocessor(), - Hippo::internal::listFromVector(boundary())); + return std::make_tuple(name(), + type(), + foamVariable(), + moosePostprocessor(), + Hippo::internal::listFromVector(boundary())); } diff --git a/src/bcs/FoamVariableBCBase.C b/src/bcs/FoamVariableBCBase.C index bd88208e..1287766d 100644 --- a/src/bcs/FoamVariableBCBase.C +++ b/src/bcs/FoamVariableBCBase.C @@ -1,4 +1,5 @@ +#include "FoamBCBase.h" #include "FoamVariableBCBase.h" #include "hippoUtils.h" @@ -21,8 +22,8 @@ FoamVariableBCBase::validParams() params.addParam( "v", - "Optional variable to use in BC. This allows existing AuxVariables to be" - " used rather than creating a new one under the hood."); + "Optional variable allowing existing AuxVariables to be used in the BC." + "If v is not provided, an AuxVariable with the name of this object is created."); // Get desired parameters from Variable objects params.transferParam>(MooseVariable::validParams(), "initial_condition"); @@ -30,7 +31,7 @@ FoamVariableBCBase::validParams() } FoamVariableBCBase::FoamVariableBCBase(const InputParameters & params) - : FoamBCBase(params), _moose_var(nullptr) + : FoamBCBase(params), _moose_var() { } @@ -43,31 +44,31 @@ FoamVariableBCBase::initialSetup() mooseError("Variable '", var_name, "' doesn't exist"); THREAD_ID tid = parameters().get("_tid"); - _moose_var = &_c_fe_problem.getVariable(tid, var_name); + _moose_var = _c_fe_problem.getVariable(tid, var_name); // Check variable is constant monomial in case it is provided. - if (!is_constant_monomial(*_moose_var)) + if (!is_constant_monomial(_moose_var->get())) mooseError("Variable '", var_name, "' must be a constant monomial."); } -void -FoamVariableBCBase::addInfoRow(BCInfoTable & table) +BCInfoTableRow +FoamVariableBCBase::addInfoRow() const { // List info about BC - table.addRow( + return std::make_tuple( name(), type(), foamVariable(), mooseVariable(), Hippo::internal::listFromVector(boundary())); } Real -FoamVariableBCBase::variableValueAtElement(const libMesh::Elem & elem) +FoamVariableBCBase::variableValueAtElement(const libMesh::Elem & elem) const { - auto & sys = _moose_var->sys(); - auto dof = elem.dof_number(sys.number(), _moose_var->number(), 0); + auto & sys = _moose_var->get().sys(); + auto dof = elem.dof_number(sys.number(), _moose_var->get().number(), 0); return sys.solution()(dof); } std::vector -FoamVariableBCBase::getMooseVariableArray(int subdomainId) +FoamVariableBCBase::getMooseVariableArray(int subdomainId) const { size_t patch_count = _mesh->getPatchCount(subdomainId); size_t patch_offset = _mesh->getPatchOffset(subdomainId); diff --git a/src/problems/FoamProblem.C b/src/problems/FoamProblem.C index e15f2afb..b91f4d89 100644 --- a/src/problems/FoamProblem.C +++ b/src/problems/FoamProblem.C @@ -152,7 +152,8 @@ FoamProblem::verifyFoamBCs() auto && boundary = bc->boundary(); used_bcs.insert(used_bcs.end(), boundary.begin(), boundary.end()); // List info about BC - bc->addInfoRow(vt); + auto [name, type, foam_var, moose_var, boundaries] = bc->addInfoRow(); + vt.addRow(name, type, foam_var, moose_var, boundaries); } } diff --git a/test/tests/bcs/fixed_gradient_pp/main.i b/test/tests/bcs/fixed_gradient_pp/main.i index 41bf0d73..3c8bedda 100644 --- a/test/tests/bcs/fixed_gradient_pp/main.i +++ b/test/tests/bcs/fixed_gradient_pp/main.i @@ -24,7 +24,7 @@ foam_variable = T boundary = 'right' diffusivity_coefficient = kappa - pp = T_flux + pp_name = T_flux [] [] diff --git a/test/tests/bcs/fixed_value_pp/main.i b/test/tests/bcs/fixed_value_pp/main.i index 0e4cdedf..b1ef805d 100644 --- a/test/tests/bcs/fixed_value_pp/main.i +++ b/test/tests/bcs/fixed_value_pp/main.i @@ -17,13 +17,13 @@ type=FoamFixedValuePostprocessorBC foam_variable = T boundary = 'left right top' # test boundary restrictions - pp = T_bc1 + pp_name = T_bc1 [] [temp2] type=FoamFixedValuePostprocessorBC foam_variable = T boundary = 'bottom front back' # test boundary restrictions - pp = T_bc2 + pp_name = T_bc2 [] [] diff --git a/test/tests/bcs/mass_flow_rate/main.i b/test/tests/bcs/mass_flow_rate/main.i index f5848106..6ae258c2 100644 --- a/test/tests/bcs/mass_flow_rate/main.i +++ b/test/tests/bcs/mass_flow_rate/main.i @@ -8,7 +8,7 @@ [temp1] type=FoamMassFlowRateInletBC boundary = 'left' # test boundary restrictions - pp = pp + pp_name = pp [] [] From 91e2450f1e912efd956b1bec54caaee90f863ee4 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Fri, 22 May 2026 13:33:18 +0100 Subject: [PATCH 45/52] Separate flux and neumann boundary conditions --- include/bcs/FoamDiffusionFluxBC.h | 17 ++++ include/bcs/FoamFixedGradientBC.h | 4 - src/bcs/FoamDiffusionFluxBC.C | 60 +++++++++++++ src/bcs/FoamFixedGradientBC.C | 33 +------ test/tests/bcs/laplace_fixed_gradient/main.i | 3 +- test/tests/bcs/laplace_fixed_gradient/tests | 20 ----- test/tests/bcs/laplace_flux_bc/foam/0/T | 52 ++++++++++++ .../foam/constant/physicalProperties | 51 +++++++++++ .../laplace_flux_bc/foam/system/blockMeshDict | 85 +++++++++++++++++++ .../laplace_flux_bc/foam/system/controlDict | 44 ++++++++++ .../bcs/laplace_flux_bc/foam/system/fvSchemes | 46 ++++++++++ .../laplace_flux_bc/foam/system/fvSolution | 49 +++++++++++ test/tests/bcs/laplace_flux_bc/main.i | 55 ++++++++++++ test/tests/bcs/laplace_flux_bc/test.py | 29 +++++++ test/tests/bcs/laplace_flux_bc/tests | 39 +++++++++ 15 files changed, 531 insertions(+), 56 deletions(-) create mode 100644 include/bcs/FoamDiffusionFluxBC.h create mode 100644 src/bcs/FoamDiffusionFluxBC.C create mode 100644 test/tests/bcs/laplace_flux_bc/foam/0/T create mode 100644 test/tests/bcs/laplace_flux_bc/foam/constant/physicalProperties create mode 100644 test/tests/bcs/laplace_flux_bc/foam/system/blockMeshDict create mode 100644 test/tests/bcs/laplace_flux_bc/foam/system/controlDict create mode 100644 test/tests/bcs/laplace_flux_bc/foam/system/fvSchemes create mode 100644 test/tests/bcs/laplace_flux_bc/foam/system/fvSolution create mode 100644 test/tests/bcs/laplace_flux_bc/main.i create mode 100644 test/tests/bcs/laplace_flux_bc/test.py create mode 100644 test/tests/bcs/laplace_flux_bc/tests diff --git a/include/bcs/FoamDiffusionFluxBC.h b/include/bcs/FoamDiffusionFluxBC.h new file mode 100644 index 00000000..d26f7e19 --- /dev/null +++ b/include/bcs/FoamDiffusionFluxBC.h @@ -0,0 +1,17 @@ +#pragma once + +#include "FoamVariableBCBase.h" + +class FoamDiffusionFluxBC : public FoamVariableBCBase +{ +public: + static InputParameters validParams(); + explicit FoamDiffusionFluxBC(const InputParameters & params); + + // Impose boundary conditions (to be called from FoamProblem class) + virtual void imposeBoundaryCondition() override; + +protected: + // diffusivity name for flux condition + const std::string _diffusivity; +}; diff --git a/include/bcs/FoamFixedGradientBC.h b/include/bcs/FoamFixedGradientBC.h index 0672b563..c4c3e5f8 100644 --- a/include/bcs/FoamFixedGradientBC.h +++ b/include/bcs/FoamFixedGradientBC.h @@ -14,8 +14,4 @@ class FoamFixedGradientBC : public FoamVariableBCBase // Impose boundary conditions (to be called from FoamProblem class) virtual void imposeBoundaryCondition() override; - -protected: - // name of diffusivity coefficient used to divide flux - std::string _diffusivity_coefficient; }; diff --git a/src/bcs/FoamDiffusionFluxBC.C b/src/bcs/FoamDiffusionFluxBC.C new file mode 100644 index 00000000..34de258f --- /dev/null +++ b/src/bcs/FoamDiffusionFluxBC.C @@ -0,0 +1,60 @@ + +#include "FoamDiffusionFluxBC.h" +#include "FoamVariableBCBase.h" +#include "MooseError.h" + +#include +#include +#include +#include + +registerMooseObject("hippoApp", FoamDiffusionFluxBC); + +InputParameters +FoamDiffusionFluxBC::validParams() +{ + auto params = FoamVariableBCBase::validParams(); + params.addParam( + "diffusivity", "kappa", "diffusivity for BC, defaults to kappa, the thermal conducitivity."); + params.addClassDescription("A FoamBC that imposes a fixed gradient boundary condition " + "on the OpenFOAM simulation"); + return params; +} + +FoamDiffusionFluxBC::FoamDiffusionFluxBC(const InputParameters & params) + : FoamVariableBCBase(params), _diffusivity(getParam("diffusivity")) +{ + if (!_mesh->fvMesh().foundObject(_diffusivity)) + { + mooseError("Diffusivity '", _diffusivity, "' not a Foam volScalarField."); + } +} + +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); + 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); + assert(grad_array.size() == static_cast(foam_gradient.size())); + + auto & coeff = foam_mesh.boundary()[subdomain].lookupPatchField( + _diffusivity); + + assert(foam_gradient.size() == coeff.size()); + // set gradient + for (auto i = 0; i < foam_gradient.size(); ++i) + { + foam_gradient[i] = grad_array[i] / coeff[i]; + } + } +} diff --git a/src/bcs/FoamFixedGradientBC.C b/src/bcs/FoamFixedGradientBC.C index 120bb6b7..7b4d9ed2 100644 --- a/src/bcs/FoamFixedGradientBC.C +++ b/src/bcs/FoamFixedGradientBC.C @@ -11,23 +11,14 @@ InputParameters FoamFixedGradientBC::validParams() { auto params = FoamVariableBCBase::validParams(); - params.addClassDescription("A FoamBC that imposes a fixed gradient dirichlet boundary condition " + params.addClassDescription("A FoamBC that imposes a fixed gradient boundary condition " "on the OpenFOAM simulation"); - params.addParam("diffusivity_coefficient", - "OpenFOAM scalar field name to be specified if 'v' is " - "a flux rather than a gradient"); return params; } FoamFixedGradientBC::FoamFixedGradientBC(const InputParameters & parameters) - : FoamVariableBCBase(parameters), - _diffusivity_coefficient(parameters.get("diffusivity_coefficient")) + : FoamVariableBCBase(parameters) { - // check that the diffusivity coefficient is a OpenFOAM scalar field - if (!_diffusivity_coefficient.empty() && - !_mesh->foamHasObject(_diffusivity_coefficient)) - mooseError( - "Diffusivity coefficient '", _diffusivity_coefficient, "' not a Foam volScalarField"); } void @@ -47,24 +38,6 @@ FoamFixedGradientBC::imposeBoundaryCondition() _mesh->getGradientBCField(subdomain, _foam_variable); assert(grad_array.size() == static_cast(foam_gradient.size())); - // If diffusivity_coefficient is specified grad array is a flux, so result - // must be divided by it - if (!_diffusivity_coefficient.empty()) - { - // Get the underlying diffusivity field - auto & coeff = foam_mesh.boundary()[subdomain].lookupPatchField( - _diffusivity_coefficient); - - assert(foam_gradient.size() == coeff.size()); - // set gradient - for (auto i = 0; i < foam_gradient.size(); ++i) - { - foam_gradient[i] = grad_array[i] / coeff[i]; - } - } - else // if no diffusivity coefficient grad_array is just the gradient so copy - { - std::copy(grad_array.begin(), grad_array.end(), foam_gradient.begin()); - } + std::copy(grad_array.begin(), grad_array.end(), foam_gradient.begin()); } } diff --git a/test/tests/bcs/laplace_fixed_gradient/main.i b/test/tests/bcs/laplace_fixed_gradient/main.i index 5adb3c53..f2fd450c 100644 --- a/test/tests/bcs/laplace_fixed_gradient/main.i +++ b/test/tests/bcs/laplace_fixed_gradient/main.i @@ -23,7 +23,6 @@ type=FoamFixedGradientBC foam_variable = T boundary = 'right' - diffusivity_coefficient = kappa [] [] @@ -31,7 +30,7 @@ [T_flux] type = ParsedAux variable = T_flux - expression = '2*t' + expression = 't' use_xyzt = true execute_on = 'INITIAL TIMESTEP_BEGIN' [] diff --git a/test/tests/bcs/laplace_fixed_gradient/tests b/test/tests/bcs/laplace_fixed_gradient/tests index 5166c3b1..6c60cad8 100644 --- a/test/tests/bcs/laplace_fixed_gradient/tests +++ b/test/tests/bcs/laplace_fixed_gradient/tests @@ -4,14 +4,6 @@ type = RunCommand command = 'bash -c "foamCleanCase -case foam && blockMesh -case foam"' [] - [diffusivity_coeff_err] - type = RunException - input = main.i - prereq = foam_bc_fixed_gradient/setup - expect_err = "Diffusivity coefficient 'kappa1' not a Foam volScalarField" - cli_args = 'FoamBCs/T_flux/diffusivity_coefficient=kappa1' - allow_warnings = true - [] [run] type = RunApp input = main.i @@ -23,17 +15,5 @@ input = test.py prereq = foam_bc_fixed_gradient/run [] - [run_no_kappa] - type = RunApp - input = main.i - cli_args = "FoamBCs/T_flux/diffusivity_coefficient='' AuxKernels/T_flux/expression='t'" - prereq = foam_bc_fixed_gradient/verify - allow_warnings = true - [] - [verify_no_kappa] - type = PythonUnitTest - input = test.py - prereq = foam_bc_fixed_gradient/run_no_kappa - [] [] [] diff --git a/test/tests/bcs/laplace_flux_bc/foam/0/T b/test/tests/bcs/laplace_flux_bc/foam/0/T new file mode 100644 index 00000000..6da637de --- /dev/null +++ b/test/tests/bcs/laplace_flux_bc/foam/0/T @@ -0,0 +1,52 @@ +/*--------------------------------*- 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.; + +boundaryField +{ + left + { + type fixedValue; + value uniform 0.; + } + right + { + type fixedGradient; + gradient uniform 1.; + } + top + { + type zeroGradient; + } + front + { + type zeroGradient; + } + bottom + { + type zeroGradient; + } + back + { + type zeroGradient; + } +} + + +// ************************************************************************* // diff --git a/test/tests/bcs/laplace_flux_bc/foam/constant/physicalProperties b/test/tests/bcs/laplace_flux_bc/foam/constant/physicalProperties new file mode 100644 index 00000000..6dab7b1c --- /dev/null +++ b/test/tests/bcs/laplace_flux_bc/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 2.; // Thermal conductivity [W/(m·K)] + } + equationOfState + { + rho 1; // Density [kg/m^3] + } +} + + +// ************************************************************************* // diff --git a/test/tests/bcs/laplace_flux_bc/foam/system/blockMeshDict b/test/tests/bcs/laplace_flux_bc/foam/system/blockMeshDict new file mode 100644 index 00000000..face9ea6 --- /dev/null +++ b/test/tests/bcs/laplace_flux_bc/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/bcs/laplace_flux_bc/foam/system/controlDict b/test/tests/bcs/laplace_flux_bc/foam/system/controlDict new file mode 100644 index 00000000..89301ab0 --- /dev/null +++ b/test/tests/bcs/laplace_flux_bc/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 32.; + +deltaT 1.; + +writeControl timeStep; + +writeInterval 1; + +writeFormat ascii; + +writePrecision 20; + +writeCompression off; + +timeFormat general; + +timePrecision 20; + +runTimeModifiable true; + +// ************************************************************************* // diff --git a/test/tests/bcs/laplace_flux_bc/foam/system/fvSchemes b/test/tests/bcs/laplace_flux_bc/foam/system/fvSchemes new file mode 100644 index 00000000..a24aaf80 --- /dev/null +++ b/test/tests/bcs/laplace_flux_bc/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/bcs/laplace_flux_bc/foam/system/fvSolution b/test/tests/bcs/laplace_flux_bc/foam/system/fvSolution new file mode 100644 index 00000000..639b272d --- /dev/null +++ b/test/tests/bcs/laplace_flux_bc/foam/system/fvSolution @@ -0,0 +1,49 @@ +/*--------------------------------*- 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-15; + relTol 1e-15; + } + + eFinal + { + $e; + tolerance 1e-15; + relTol 1e-15; + } +} + +PIMPLE +{ +} + +// ************************************************************************* // diff --git a/test/tests/bcs/laplace_flux_bc/main.i b/test/tests/bcs/laplace_flux_bc/main.i new file mode 100644 index 00000000..ed85d1d7 --- /dev/null +++ b/test/tests/bcs/laplace_flux_bc/main.i @@ -0,0 +1,55 @@ +[Mesh] + type = FoamMesh + case = 'foam' + foam_patch = 'left right' +[] + +[Variables] + [dummy] + family = MONOMIAL + order = CONSTANT + initial_condition = 999 + [] +[] + +[FoamBCs] + [T_value] + type=FoamFixedValueBC + foam_variable = T + initial_condition = 0. + boundary = 'left' + [] + [T_flux] + type=FoamDiffusionFluxBC + foam_variable = T + boundary = 'right' + [] +[] + +[AuxKernels] + [T_flux] + type = ParsedAux + variable = T_flux + expression = '2*t' + use_xyzt = true + execute_on = 'INITIAL TIMESTEP_BEGIN' + [] +[] + +[Problem] + type = FoamProblem +[] + +[Executioner] + type = Transient + end_time = 32 + [TimeSteppers] + [foam] + type = FoamTimeStepper + [] + [] +[] + +[Outputs] + exodus = true +[] diff --git a/test/tests/bcs/laplace_flux_bc/test.py b/test/tests/bcs/laplace_flux_bc/test.py new file mode 100644 index 00000000..98b48ce7 --- /dev/null +++ b/test/tests/bcs/laplace_flux_bc/test.py @@ -0,0 +1,29 @@ +"""Tests for imposing BCs in OpenFOAM using MOOSE input file syntax""" + +import unittest +import fluidfoam as ff +import numpy as np + +from read_hippo_data import get_foam_times # pylint: disable=E0401 + + +class TestFoamBCFixedGradient(unittest.TestCase): + """Test class for imposing fixed value BCs in Hippo.""" + + def test_fixed_gradient_x(self): + """Test case for imposing fixed value.""" + case_dir = "foam/" + times = get_foam_times(case_dir, string=True)[1:] + + for time in times: + coords = dict(zip(("x", "y", "z"), ff.readof.readmesh(case_dir))) + + temp = ff.readof.readscalar(case_dir, time, "T") + + temp_ref = coords["x"] * np.float64(time) + + temp_diff_max = np.argmax(abs(temp - temp_ref)) + assert np.allclose(temp_ref, temp, rtol=1e-7, atol=1e-12), ( + f"Max diff ({time}): {abs(temp - temp_ref).max()} " + f"{temp[temp_diff_max]} {temp_ref[temp_diff_max]}" + ) diff --git a/test/tests/bcs/laplace_flux_bc/tests b/test/tests/bcs/laplace_flux_bc/tests new file mode 100644 index 00000000..287a086b --- /dev/null +++ b/test/tests/bcs/laplace_flux_bc/tests @@ -0,0 +1,39 @@ +[Tests] + [foam_bc_diffusion_flux] + [setup] + type = RunCommand + command = 'bash -c "foamCleanCase -case foam && blockMesh -case foam"' + [] + [check_invalid_diffusivity] + type = RunException + input = main.i + prereq = foam_bc_diffusion_flux/setup + allow_warnings = true + cli_args ='FoamBCs/T_flux/diffusivity=kappa1' + expect_err = "Diffusivity 'kappa1' not a Foam volScalarField" + [] + [run] + type = RunApp + input = main.i + prereq = foam_bc_diffusion_flux/setup + allow_warnings = true + [] + [verify] + type = PythonUnitTest + input = test.py + prereq = foam_bc_diffusion_flux/run + [] + [run_diffusivity] + type = RunApp + input = main.i + prereq = foam_bc_diffusion_flux/setup + cli_args ='FoamBCs/T_flux/diffusivity=Cv AuxKernels/T_flux/expression=t' + allow_warnings = true + [] + [verify_diffusivity] + type = PythonUnitTest + input = test.py + prereq = foam_bc_diffusion_flux/run + [] + [] +[] From 6b6fe3dcdf2e32915b4577d5b46f16eb6f4546e6 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Fri, 22 May 2026 14:11:37 +0100 Subject: [PATCH 46/52] Add postprocessor diffusion flux BCs --- .../bcs/FoamDiffusionFluxPostprocessorBC.h | 19 +++++++ .../bcs/FoamFixedGradientPostprocessorBC.h | 4 -- src/bcs/FoamDiffusionFluxBC.C | 2 +- src/bcs/FoamDiffusionFluxPostprocessorBC.C | 54 +++++++++++++++++++ src/bcs/FoamFixedGradientPostprocessorBC.C | 32 +---------- 5 files changed, 76 insertions(+), 35 deletions(-) create mode 100644 include/bcs/FoamDiffusionFluxPostprocessorBC.h create mode 100644 src/bcs/FoamDiffusionFluxPostprocessorBC.C diff --git a/include/bcs/FoamDiffusionFluxPostprocessorBC.h b/include/bcs/FoamDiffusionFluxPostprocessorBC.h new file mode 100644 index 00000000..1a6d7d9b --- /dev/null +++ b/include/bcs/FoamDiffusionFluxPostprocessorBC.h @@ -0,0 +1,19 @@ +#pragma once + +#include "FoamPostprocessorBCBase.h" +#include "InputParameters.h" + +class FoamDiffusionFluxPostprocessorBC : public FoamPostprocessorBCBase +{ +public: + static InputParameters validParams(); + + FoamDiffusionFluxPostprocessorBC(const InputParameters & params); + + // impose boundary condition + virtual void imposeBoundaryCondition() override; + +protected: + // name of diffusivity coefficient used to divide flux + std::string _diffusivity; +}; diff --git a/include/bcs/FoamFixedGradientPostprocessorBC.h b/include/bcs/FoamFixedGradientPostprocessorBC.h index 5f35fd37..5eb7adf6 100644 --- a/include/bcs/FoamFixedGradientPostprocessorBC.h +++ b/include/bcs/FoamFixedGradientPostprocessorBC.h @@ -12,8 +12,4 @@ class FoamFixedGradientPostprocessorBC : public FoamPostprocessorBCBase // impose boundary condition virtual void imposeBoundaryCondition() override; - -protected: - // name of diffusivity coefficient used to divide flux - std::string _diffusivity_coefficient; }; diff --git a/src/bcs/FoamDiffusionFluxBC.C b/src/bcs/FoamDiffusionFluxBC.C index 34de258f..aea80990 100644 --- a/src/bcs/FoamDiffusionFluxBC.C +++ b/src/bcs/FoamDiffusionFluxBC.C @@ -15,7 +15,7 @@ FoamDiffusionFluxBC::validParams() { auto params = FoamVariableBCBase::validParams(); params.addParam( - "diffusivity", "kappa", "diffusivity for BC, defaults to kappa, the thermal conducitivity."); + "diffusivity", "kappa", "Diffusivity for BC, defaults to kappa, the thermal conducitivity."); params.addClassDescription("A FoamBC that imposes a fixed gradient boundary condition " "on the OpenFOAM simulation"); return params; diff --git a/src/bcs/FoamDiffusionFluxPostprocessorBC.C b/src/bcs/FoamDiffusionFluxPostprocessorBC.C new file mode 100644 index 00000000..f5fd1a57 --- /dev/null +++ b/src/bcs/FoamDiffusionFluxPostprocessorBC.C @@ -0,0 +1,54 @@ +#include "FoamDiffusionFluxPostprocessorBC.h" +#include "FoamPostprocessorBCBase.h" +#include "PstreamReduceOps.H" +#include "Registry.h" +#include + +registerMooseObject("hippoApp", FoamDiffusionFluxPostprocessorBC); + +InputParameters +FoamDiffusionFluxPostprocessorBC::validParams() +{ + auto params = FoamPostprocessorBCBase::validParams(); + params.addParam( + "diffusivity", "kappa", "Diffusivity for BC, defaults to kappa, the thermal conducitivity."); + return params; +} + +FoamDiffusionFluxPostprocessorBC::FoamDiffusionFluxPostprocessorBC(const InputParameters & params) + : FoamPostprocessorBCBase(params), _diffusivity(getParam("diffusivity")) +{ + if (!_mesh->fvMesh().foundObject(_diffusivity)) + { + mooseError("Diffusivity '", _diffusivity, "' not a Foam volScalarField."); + } +} + +void +FoamDiffusionFluxPostprocessorBC::imposeBoundaryCondition() +{ + auto & foam_mesh = _mesh->fvMesh(); + + // Get subdomains this FoamBC acts on + auto subdomains = _mesh->getSubdomainIDs(_boundary); + for (auto subdomain : subdomains) + { + auto & boundary = foam_mesh.boundary()[subdomain]; + // Get underlying field from OpenFOAM boundary patch. + auto & foam_gradient = + _mesh->getGradientBCField(subdomain, _foam_variable); + + // Get the underlying diffusivity field + auto & coeff = foam_mesh.boundary()[subdomain].lookupPatchField( + _diffusivity); + + // Calculate the bulk value of the diffusivity coefficient + auto area = boundary.magSf(); + auto total_area = Foam::returnReduce(Foam::sum(area), Foam::sumOp()); + auto coeff_bulk = + Foam::returnReduce(Foam::sum(coeff * area), Foam::sumOp()) / total_area; + + // set gradient + std::fill(foam_gradient.begin(), foam_gradient.end(), _pp_value / coeff_bulk); + } +} diff --git a/src/bcs/FoamFixedGradientPostprocessorBC.C b/src/bcs/FoamFixedGradientPostprocessorBC.C index 91b3dfaf..374c7228 100644 --- a/src/bcs/FoamFixedGradientPostprocessorBC.C +++ b/src/bcs/FoamFixedGradientPostprocessorBC.C @@ -9,22 +9,12 @@ InputParameters FoamFixedGradientPostprocessorBC::validParams() { auto params = FoamPostprocessorBCBase::validParams(); - params.addParam("diffusivity_coefficient", - "", - "OpenFOAM scalar field name to be specified if 'v' is " - "a flux rather than a gradient"); return params; } FoamFixedGradientPostprocessorBC::FoamFixedGradientPostprocessorBC(const InputParameters & params) - : FoamPostprocessorBCBase(params), - _diffusivity_coefficient(params.get("diffusivity_coefficient")) + : FoamPostprocessorBCBase(params) { - // check that the diffusivity coefficient is a OpenFOAM scalar field - if (!_diffusivity_coefficient.empty() && - !_mesh->fvMesh().foundObject(_diffusivity_coefficient)) - mooseError( - "Diffusivity coefficient '", _diffusivity_coefficient, "' not a Foam volScalarField"); } void @@ -43,24 +33,6 @@ FoamFixedGradientPostprocessorBC::imposeBoundaryCondition() // If diffusivity_coefficient is specified grad array is a flux, so result // must be divided by it - if (!_diffusivity_coefficient.empty()) - { - // Get the underlying diffusivity field - auto & coeff = foam_mesh.boundary()[subdomain].lookupPatchField( - _diffusivity_coefficient); - - // Calculate the bulk value of the diffusivity coefficient - auto area = boundary.magSf(); - auto total_area = Foam::returnReduce(Foam::sum(area), Foam::sumOp()); - auto coeff_bulk = - Foam::returnReduce(Foam::sum(coeff * area), Foam::sumOp()) / total_area; - - // set gradient - std::fill(foam_gradient.begin(), foam_gradient.end(), _pp_value / coeff_bulk); - } - else // if no diffusivity coefficient grad_array is just the gradient so fill - { - std::fill(foam_gradient.begin(), foam_gradient.end(), _pp_value); - } + std::fill(foam_gradient.begin(), foam_gradient.end(), _pp_value); } } From 3673b1f7ff74acd8ebdd7a4d0f824d79448c175f Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Fri, 22 May 2026 14:12:05 +0100 Subject: [PATCH 47/52] Add tests for diffusion flux --- test/tests/bcs/diffusion_flux_pp/foam/0/T | 52 ++++++++++++ .../foam/constant/physicalProperties | 51 +++++++++++ .../foam/system/blockMeshDict | 85 +++++++++++++++++++ .../diffusion_flux_pp/foam/system/controlDict | 44 ++++++++++ .../diffusion_flux_pp/foam/system/fvSchemes | 46 ++++++++++ .../diffusion_flux_pp/foam/system/fvSolution | 49 +++++++++++ test/tests/bcs/diffusion_flux_pp/main.i | 55 ++++++++++++ test/tests/bcs/diffusion_flux_pp/test.py | 29 +++++++ test/tests/bcs/diffusion_flux_pp/tests | 39 +++++++++ test/tests/bcs/fixed_gradient_pp/main.i | 3 +- test/tests/bcs/fixed_gradient_pp/tests | 20 ----- test/tests/bcs/receiver_pp/main.i | 3 +- test/tests/bcs/receiver_pp/tests | 12 +-- .../flow_over_heated_plate/fluid.i | 4 +- .../fixed-point/heated_plate_converge/fluid.i | 4 +- .../laplacian_fixed_gradient/fluid-openfoam.i | 4 +- .../fixed-point/restart_heated_plate/fluid.i | 4 +- .../restep_fixed_point/fluid-openfoam.i | 4 +- .../fluid-openfoam.i | 4 +- .../unsteady_hc_subcycling/fluid-openfoam.i | 3 +- .../unsteady_hc_variable_dt/fluid-openfoam.i | 4 +- .../unsteady_heat_conduction/fluid-openfoam.i | 3 +- test/tests/mesh/polygonal/fluid-openfoam.i | 3 +- .../tests/mesh/quadrilateral/fluid-openfoam.i | 3 +- test/tests/mesh/triangular/fluid-openfoam.i | 3 +- .../multiapps/flow_over_heated_plate/fluid.i | 3 +- .../simplified_heat_exchanger/fluid-bottom.i | 3 +- .../simplified_heat_exchanger/fluid-top.i | 3 +- .../fluid-openfoam.i | 3 +- 29 files changed, 481 insertions(+), 62 deletions(-) create mode 100644 test/tests/bcs/diffusion_flux_pp/foam/0/T create mode 100644 test/tests/bcs/diffusion_flux_pp/foam/constant/physicalProperties create mode 100644 test/tests/bcs/diffusion_flux_pp/foam/system/blockMeshDict create mode 100644 test/tests/bcs/diffusion_flux_pp/foam/system/controlDict create mode 100644 test/tests/bcs/diffusion_flux_pp/foam/system/fvSchemes create mode 100644 test/tests/bcs/diffusion_flux_pp/foam/system/fvSolution create mode 100644 test/tests/bcs/diffusion_flux_pp/main.i create mode 100644 test/tests/bcs/diffusion_flux_pp/test.py create mode 100644 test/tests/bcs/diffusion_flux_pp/tests diff --git a/test/tests/bcs/diffusion_flux_pp/foam/0/T b/test/tests/bcs/diffusion_flux_pp/foam/0/T new file mode 100644 index 00000000..6da637de --- /dev/null +++ b/test/tests/bcs/diffusion_flux_pp/foam/0/T @@ -0,0 +1,52 @@ +/*--------------------------------*- 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.; + +boundaryField +{ + left + { + type fixedValue; + value uniform 0.; + } + right + { + type fixedGradient; + gradient uniform 1.; + } + top + { + type zeroGradient; + } + front + { + type zeroGradient; + } + bottom + { + type zeroGradient; + } + back + { + type zeroGradient; + } +} + + +// ************************************************************************* // diff --git a/test/tests/bcs/diffusion_flux_pp/foam/constant/physicalProperties b/test/tests/bcs/diffusion_flux_pp/foam/constant/physicalProperties new file mode 100644 index 00000000..6dab7b1c --- /dev/null +++ b/test/tests/bcs/diffusion_flux_pp/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 2.; // Thermal conductivity [W/(m·K)] + } + equationOfState + { + rho 1; // Density [kg/m^3] + } +} + + +// ************************************************************************* // diff --git a/test/tests/bcs/diffusion_flux_pp/foam/system/blockMeshDict b/test/tests/bcs/diffusion_flux_pp/foam/system/blockMeshDict new file mode 100644 index 00000000..face9ea6 --- /dev/null +++ b/test/tests/bcs/diffusion_flux_pp/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/bcs/diffusion_flux_pp/foam/system/controlDict b/test/tests/bcs/diffusion_flux_pp/foam/system/controlDict new file mode 100644 index 00000000..89301ab0 --- /dev/null +++ b/test/tests/bcs/diffusion_flux_pp/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 32.; + +deltaT 1.; + +writeControl timeStep; + +writeInterval 1; + +writeFormat ascii; + +writePrecision 20; + +writeCompression off; + +timeFormat general; + +timePrecision 20; + +runTimeModifiable true; + +// ************************************************************************* // diff --git a/test/tests/bcs/diffusion_flux_pp/foam/system/fvSchemes b/test/tests/bcs/diffusion_flux_pp/foam/system/fvSchemes new file mode 100644 index 00000000..a24aaf80 --- /dev/null +++ b/test/tests/bcs/diffusion_flux_pp/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/bcs/diffusion_flux_pp/foam/system/fvSolution b/test/tests/bcs/diffusion_flux_pp/foam/system/fvSolution new file mode 100644 index 00000000..639b272d --- /dev/null +++ b/test/tests/bcs/diffusion_flux_pp/foam/system/fvSolution @@ -0,0 +1,49 @@ +/*--------------------------------*- 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-15; + relTol 1e-15; + } + + eFinal + { + $e; + tolerance 1e-15; + relTol 1e-15; + } +} + +PIMPLE +{ +} + +// ************************************************************************* // diff --git a/test/tests/bcs/diffusion_flux_pp/main.i b/test/tests/bcs/diffusion_flux_pp/main.i new file mode 100644 index 00000000..69d94b6e --- /dev/null +++ b/test/tests/bcs/diffusion_flux_pp/main.i @@ -0,0 +1,55 @@ +[Mesh] + type = FoamMesh + case = 'foam' + foam_patch = 'left right' +[] + +[Variables] + [dummy] + family = MONOMIAL + order = CONSTANT + initial_condition = 999 + [] +[] + +[FoamBCs] + [T_value] + type=FoamFixedValuePostprocessorBC + foam_variable = T + default = 0. + boundary = 'left' + [] + [T_flux] + type=FoamDiffusionFluxPostprocessorBC + foam_variable = T + boundary = 'right' + pp_name = T_flux + [] +[] + +[Postprocessors] + [T_flux] + type = ParsedPostprocessor + expression = '2*t' + use_t = true + execute_on = 'INITIAL TIMESTEP_BEGIN' + [] +[] + +[Problem] + type = FoamProblem +[] + +[Executioner] + type = Transient + end_time = 32 + [TimeSteppers] + [foam] + type = FoamTimeStepper + [] + [] +[] + +[Outputs] + exodus = true +[] diff --git a/test/tests/bcs/diffusion_flux_pp/test.py b/test/tests/bcs/diffusion_flux_pp/test.py new file mode 100644 index 00000000..98b48ce7 --- /dev/null +++ b/test/tests/bcs/diffusion_flux_pp/test.py @@ -0,0 +1,29 @@ +"""Tests for imposing BCs in OpenFOAM using MOOSE input file syntax""" + +import unittest +import fluidfoam as ff +import numpy as np + +from read_hippo_data import get_foam_times # pylint: disable=E0401 + + +class TestFoamBCFixedGradient(unittest.TestCase): + """Test class for imposing fixed value BCs in Hippo.""" + + def test_fixed_gradient_x(self): + """Test case for imposing fixed value.""" + case_dir = "foam/" + times = get_foam_times(case_dir, string=True)[1:] + + for time in times: + coords = dict(zip(("x", "y", "z"), ff.readof.readmesh(case_dir))) + + temp = ff.readof.readscalar(case_dir, time, "T") + + temp_ref = coords["x"] * np.float64(time) + + temp_diff_max = np.argmax(abs(temp - temp_ref)) + assert np.allclose(temp_ref, temp, rtol=1e-7, atol=1e-12), ( + f"Max diff ({time}): {abs(temp - temp_ref).max()} " + f"{temp[temp_diff_max]} {temp_ref[temp_diff_max]}" + ) diff --git a/test/tests/bcs/diffusion_flux_pp/tests b/test/tests/bcs/diffusion_flux_pp/tests new file mode 100644 index 00000000..02996f8c --- /dev/null +++ b/test/tests/bcs/diffusion_flux_pp/tests @@ -0,0 +1,39 @@ +[Tests] + [foam_bc_diffusion_flux_pp] + [setup] + type = RunCommand + command = 'bash -c "foamCleanCase -case foam && blockMesh -case foam"' + [] + [diffusivity_err] + type = RunException + input = main.i + prereq = foam_bc_diffusion_flux_pp/setup + expect_err = "Diffusivity 'kappa1' not a Foam volScalarField" + cli_args = 'FoamBCs/T_flux/diffusivity=kappa1' + allow_warnings = true + [] + [run] + type = RunApp + input = main.i + prereq = foam_bc_diffusion_flux_pp/setup + allow_warnings = true + [] + [verify] + type = PythonUnitTest + input = test.py + prereq = foam_bc_diffusion_flux_pp/run + [] + [run_diffusivity_cv] + type = RunApp + input = main.i + cli_args = "FoamBCs/T_flux/diffusivity='Cv' Postprocessors/T_flux/expression='t'" + prereq = foam_bc_diffusion_flux_pp/verify + allow_warnings = true + [] + [verify_diffusivity_cv] + type = PythonUnitTest + input = test.py + prereq = foam_bc_diffusion_flux_pp/run_diffusivity_cv + [] + [] +[] diff --git a/test/tests/bcs/fixed_gradient_pp/main.i b/test/tests/bcs/fixed_gradient_pp/main.i index 3c8bedda..7732c1a9 100644 --- a/test/tests/bcs/fixed_gradient_pp/main.i +++ b/test/tests/bcs/fixed_gradient_pp/main.i @@ -23,7 +23,6 @@ type=FoamFixedGradientPostprocessorBC foam_variable = T boundary = 'right' - diffusivity_coefficient = kappa pp_name = T_flux [] [] @@ -31,7 +30,7 @@ [Postprocessors] [T_flux] type = ParsedPostprocessor - expression = '2*t' + expression = 't' use_t = true execute_on = 'INITIAL TIMESTEP_BEGIN' [] diff --git a/test/tests/bcs/fixed_gradient_pp/tests b/test/tests/bcs/fixed_gradient_pp/tests index ba30399b..e0cdc47f 100644 --- a/test/tests/bcs/fixed_gradient_pp/tests +++ b/test/tests/bcs/fixed_gradient_pp/tests @@ -4,14 +4,6 @@ type = RunCommand command = 'bash -c "foamCleanCase -case foam && blockMesh -case foam"' [] - [diffusivity_coeff_err] - type = RunException - input = main.i - prereq = foam_bc_fixed_gradient_pp/setup - expect_err = "Diffusivity coefficient 'kappa1' not a Foam volScalarField" - cli_args = 'FoamBCs/T_flux/diffusivity_coefficient=kappa1' - allow_warnings = true - [] [run] type = RunApp input = main.i @@ -23,17 +15,5 @@ input = test.py prereq = foam_bc_fixed_gradient_pp/run [] - [run_no_kappa] - type = RunApp - input = main.i - cli_args = "FoamBCs/T_flux/diffusivity_coefficient='' Postprocessors/T_flux/expression='t'" - prereq = foam_bc_fixed_gradient_pp/verify - allow_warnings = true - [] - [verify_no_kappa] - type = PythonUnitTest - input = test.py - prereq = foam_bc_fixed_gradient_pp/run_no_kappa - [] [] [] diff --git a/test/tests/bcs/receiver_pp/main.i b/test/tests/bcs/receiver_pp/main.i index 740fb948..d1ccaf7c 100644 --- a/test/tests/bcs/receiver_pp/main.i +++ b/test/tests/bcs/receiver_pp/main.i @@ -20,10 +20,9 @@ boundary = 'left' [] [T_flux] - type=FoamFixedGradientPostprocessorBC + type=FoamDiffusionFluxPostprocessorBC foam_variable = T boundary = 'right' - diffusivity_coefficient = kappa default=2 [] [] diff --git a/test/tests/bcs/receiver_pp/tests b/test/tests/bcs/receiver_pp/tests index 01645088..371cbe3e 100644 --- a/test/tests/bcs/receiver_pp/tests +++ b/test/tests/bcs/receiver_pp/tests @@ -8,8 +8,8 @@ type = RunException input = main.i prereq = receiver_pp/setup - expect_err = "Diffusivity coefficient 'kappa1' not a Foam volScalarField" - cli_args = 'FoamBCs/T_flux/diffusivity_coefficient=kappa1' + expect_err = "Diffusivity 'kappa1' not a Foam volScalarField" + cli_args = 'FoamBCs/T_flux/diffusivity=kappa1' allow_warnings = true [] [run] @@ -23,17 +23,17 @@ input = test.py prereq = receiver_pp/run [] - [run_no_kappa] + [run_diffusivity_cv] type = RunApp input = main.i - cli_args = "FoamBCs/T_flux/diffusivity_coefficient='' FoamBCs/T_flux/default=1" + cli_args = "FoamBCs/T_flux/diffusivity='Cv' FoamBCs/T_flux/default=1" prereq = receiver_pp/verify allow_warnings = true [] - [verify_no_kappa] + [verify_diffusivity_cv] type = PythonUnitTest input = test.py - prereq = receiver_pp/run_no_kappa + prereq = receiver_pp/run_diffusivity_cv [] [] [] diff --git a/test/tests/fixed-point/flow_over_heated_plate/fluid.i b/test/tests/fixed-point/flow_over_heated_plate/fluid.i index dd4178ff..f937c25e 100644 --- a/test/tests/fixed-point/flow_over_heated_plate/fluid.i +++ b/test/tests/fixed-point/flow_over_heated_plate/fluid.i @@ -22,9 +22,9 @@ [FoamBCs] [solid_heat_flux] - type = FoamFixedGradientBC + type = FoamDiffusionFluxBC foam_variable = 'T' - diffusivity_coefficient = kappa + initial_condition = 0 [] [] diff --git a/test/tests/fixed-point/heated_plate_converge/fluid.i b/test/tests/fixed-point/heated_plate_converge/fluid.i index dd4178ff..f937c25e 100644 --- a/test/tests/fixed-point/heated_plate_converge/fluid.i +++ b/test/tests/fixed-point/heated_plate_converge/fluid.i @@ -22,9 +22,9 @@ [FoamBCs] [solid_heat_flux] - type = FoamFixedGradientBC + type = FoamDiffusionFluxBC foam_variable = 'T' - diffusivity_coefficient = kappa + initial_condition = 0 [] [] diff --git a/test/tests/fixed-point/laplacian_fixed_gradient/fluid-openfoam.i b/test/tests/fixed-point/laplacian_fixed_gradient/fluid-openfoam.i index 8108e3be..d73846ca 100644 --- a/test/tests/fixed-point/laplacian_fixed_gradient/fluid-openfoam.i +++ b/test/tests/fixed-point/laplacian_fixed_gradient/fluid-openfoam.i @@ -14,9 +14,9 @@ [FoamBCs] [fluid_heat_flux] - type = FoamFixedGradientBC + type = FoamDiffusionFluxBC foam_variable = 'T' - diffusivity_coefficient = kappa + initial_condition = 0.075 [] [] diff --git a/test/tests/fixed-point/restart_heated_plate/fluid.i b/test/tests/fixed-point/restart_heated_plate/fluid.i index dd4178ff..f937c25e 100644 --- a/test/tests/fixed-point/restart_heated_plate/fluid.i +++ b/test/tests/fixed-point/restart_heated_plate/fluid.i @@ -22,9 +22,9 @@ [FoamBCs] [solid_heat_flux] - type = FoamFixedGradientBC + type = FoamDiffusionFluxBC foam_variable = 'T' - diffusivity_coefficient = kappa + initial_condition = 0 [] [] diff --git a/test/tests/fixed-point/restep_fixed_point/fluid-openfoam.i b/test/tests/fixed-point/restep_fixed_point/fluid-openfoam.i index 34f01b1d..53d16a69 100644 --- a/test/tests/fixed-point/restep_fixed_point/fluid-openfoam.i +++ b/test/tests/fixed-point/restep_fixed_point/fluid-openfoam.i @@ -14,9 +14,9 @@ [FoamBCs] [solid_heat_flux] - type = FoamFixedGradientBC + type = FoamDiffusionFluxBC foam_variable = 'T' - diffusivity_coefficient = kappa + initial_condition = 0 [] [] diff --git a/test/tests/fixed-point/unsteady_fixed_point_converge/fluid-openfoam.i b/test/tests/fixed-point/unsteady_fixed_point_converge/fluid-openfoam.i index 34f01b1d..53d16a69 100644 --- a/test/tests/fixed-point/unsteady_fixed_point_converge/fluid-openfoam.i +++ b/test/tests/fixed-point/unsteady_fixed_point_converge/fluid-openfoam.i @@ -14,9 +14,9 @@ [FoamBCs] [solid_heat_flux] - type = FoamFixedGradientBC + type = FoamDiffusionFluxBC foam_variable = 'T' - diffusivity_coefficient = kappa + initial_condition = 0 [] [] diff --git a/test/tests/fixed-point/unsteady_hc_subcycling/fluid-openfoam.i b/test/tests/fixed-point/unsteady_hc_subcycling/fluid-openfoam.i index 72685c2c..7dd98811 100644 --- a/test/tests/fixed-point/unsteady_hc_subcycling/fluid-openfoam.i +++ b/test/tests/fixed-point/unsteady_hc_subcycling/fluid-openfoam.i @@ -23,9 +23,8 @@ [FoamBCs] [solid_heat_flux] - type = FoamFixedGradientBC + type = FoamDiffusionFluxBC foam_variable = 'T' - diffusivity_coefficient = kappa initial_condition = 0 [] [] diff --git a/test/tests/fixed-point/unsteady_hc_variable_dt/fluid-openfoam.i b/test/tests/fixed-point/unsteady_hc_variable_dt/fluid-openfoam.i index 72685c2c..78585653 100644 --- a/test/tests/fixed-point/unsteady_hc_variable_dt/fluid-openfoam.i +++ b/test/tests/fixed-point/unsteady_hc_variable_dt/fluid-openfoam.i @@ -23,9 +23,9 @@ [FoamBCs] [solid_heat_flux] - type = FoamFixedGradientBC + type = FoamDiffusionFluxBC foam_variable = 'T' - diffusivity_coefficient = kappa + initial_condition = 0 [] [] diff --git a/test/tests/fixed-point/unsteady_heat_conduction/fluid-openfoam.i b/test/tests/fixed-point/unsteady_heat_conduction/fluid-openfoam.i index 7367636a..f760d142 100644 --- a/test/tests/fixed-point/unsteady_heat_conduction/fluid-openfoam.i +++ b/test/tests/fixed-point/unsteady_heat_conduction/fluid-openfoam.i @@ -22,9 +22,8 @@ [FoamBCs] [solid_heat_flux] - type = FoamFixedGradientBC + type = FoamDiffusionFluxBC foam_variable = 'T' - diffusivity_coefficient = kappa initial_condition = 0 [] [] diff --git a/test/tests/mesh/polygonal/fluid-openfoam.i b/test/tests/mesh/polygonal/fluid-openfoam.i index df47e23e..c9b86e86 100644 --- a/test/tests/mesh/polygonal/fluid-openfoam.i +++ b/test/tests/mesh/polygonal/fluid-openfoam.i @@ -14,10 +14,9 @@ [FoamBCs] [solid_heat_flux] - type = FoamFixedGradientBC + type = FoamDiffusionFluxBC foam_variable = T initial_condition = 0 - diffusivity_coefficient = kappa [] [] diff --git a/test/tests/mesh/quadrilateral/fluid-openfoam.i b/test/tests/mesh/quadrilateral/fluid-openfoam.i index 30df6206..bb4b4853 100644 --- a/test/tests/mesh/quadrilateral/fluid-openfoam.i +++ b/test/tests/mesh/quadrilateral/fluid-openfoam.i @@ -15,10 +15,9 @@ [FoamBCs] [solid_heat_flux] - type = FoamFixedGradientBC + type = FoamDiffusionFluxBC foam_variable = T initial_condition = 0 - diffusivity_coefficient = kappa [] [] diff --git a/test/tests/mesh/triangular/fluid-openfoam.i b/test/tests/mesh/triangular/fluid-openfoam.i index 4af1f206..ac400577 100644 --- a/test/tests/mesh/triangular/fluid-openfoam.i +++ b/test/tests/mesh/triangular/fluid-openfoam.i @@ -14,10 +14,9 @@ [FoamBCs] [solid_heat_flux] - type = FoamFixedGradientBC + type = FoamDiffusionFluxBC foam_variable = T initial_condition = 0 - diffusivity_coefficient = kappa [] [] diff --git a/test/tests/multiapps/flow_over_heated_plate/fluid.i b/test/tests/multiapps/flow_over_heated_plate/fluid.i index 47ab7f00..873a95c0 100644 --- a/test/tests/multiapps/flow_over_heated_plate/fluid.i +++ b/test/tests/multiapps/flow_over_heated_plate/fluid.i @@ -14,10 +14,9 @@ [FoamBCs] [solid_heat_flux] - type = FoamFixedGradientBC + type = FoamDiffusionFluxBC foam_variable = T initial_condition = 0 - diffusivity_coefficient = kappa [] [] diff --git a/test/tests/multiapps/simplified_heat_exchanger/fluid-bottom.i b/test/tests/multiapps/simplified_heat_exchanger/fluid-bottom.i index 7efc43dd..f229905a 100644 --- a/test/tests/multiapps/simplified_heat_exchanger/fluid-bottom.i +++ b/test/tests/multiapps/simplified_heat_exchanger/fluid-bottom.i @@ -6,10 +6,9 @@ [FoamBCs] [solid_heat_flux] - type = FoamFixedGradientBC + type = FoamDiffusionFluxBC foam_variable = T initial_condition = 0 - diffusivity_coefficient = kappa [] [] diff --git a/test/tests/multiapps/simplified_heat_exchanger/fluid-top.i b/test/tests/multiapps/simplified_heat_exchanger/fluid-top.i index 110c369a..bb1cad5f 100644 --- a/test/tests/multiapps/simplified_heat_exchanger/fluid-top.i +++ b/test/tests/multiapps/simplified_heat_exchanger/fluid-top.i @@ -6,10 +6,9 @@ [FoamBCs] [solid_heat_flux] - type = FoamFixedGradientBC + type = FoamDiffusionFluxBC foam_variable = T initial_condition = 3 - diffusivity_coefficient = kappa [] [] diff --git a/test/tests/multiapps/unsteady_heat_conduction_in_infinite_system/fluid-openfoam.i b/test/tests/multiapps/unsteady_heat_conduction_in_infinite_system/fluid-openfoam.i index 4af1f206..ac400577 100644 --- a/test/tests/multiapps/unsteady_heat_conduction_in_infinite_system/fluid-openfoam.i +++ b/test/tests/multiapps/unsteady_heat_conduction_in_infinite_system/fluid-openfoam.i @@ -14,10 +14,9 @@ [FoamBCs] [solid_heat_flux] - type = FoamFixedGradientBC + type = FoamDiffusionFluxBC foam_variable = T initial_condition = 0 - diffusivity_coefficient = kappa [] [] From 3518bb22e24ed0bd62ea7b241d7f873901c0112e Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Fri, 22 May 2026 14:24:24 +0100 Subject: [PATCH 48/52] Update documentation changes with the boundary condition update --- doc/content/hit/step_by_step/fluid.i | 3 +-- doc/content/shell_tube_hx.md | 2 +- doc/content/step_by_step.md | 9 +++------ 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/doc/content/hit/step_by_step/fluid.i b/doc/content/hit/step_by_step/fluid.i index 1599dffb..bc3a2426 100644 --- a/doc/content/hit/step_by_step/fluid.i +++ b/doc/content/hit/step_by_step/fluid.i @@ -14,9 +14,8 @@ [FoamBCs] [solid_heat_flux] - type = FoamFixedGradientBC + type = FoamDiffusionFluxBC foam_variable = 'T' - diffusivity_coefficient = kappa initial_condition = 0 [] [] diff --git a/doc/content/shell_tube_hx.md b/doc/content/shell_tube_hx.md index 913d1207..e1bf449d 100644 --- a/doc/content/shell_tube_hx.md +++ b/doc/content/shell_tube_hx.md @@ -234,7 +234,7 @@ Both `inner.i` and `outer.i` are the same: ``` Note that this is a different type to the step-by-step example where a -`FoamFixedGradientBC` is used. +`FoamDiffusionFluxBC` is used. ## Imposing the fluid heat flux on the solid diff --git a/doc/content/step_by_step.md b/doc/content/step_by_step.md index 518e9af5..28d6e7d2 100644 --- a/doc/content/step_by_step.md +++ b/doc/content/step_by_step.md @@ -136,19 +136,16 @@ and so can be transferred between MOOSE apps. Hippo also implements the `FoamBC` system that allows you to impose boundary conditions on OpenFOAM from the Hippo input file. In this case, we wish to impose a heat flux BC -on the temperature field. This requires the `FoamFixedGradientBC`, which mirrors OpenFOAM's -`fixedGradient` BC type. As in this case, we provide a heat flux, we must also provide the -thermal conductivity, which is specified as the `diffusivity_coefficient`. -`kappa` is the name of the thermal conductivity variable in OpenFOAM. +on the temperature field, which can be donw using `FoamDiffusionFluxBC`. A diffusivity can be specified, +although the default is the thermal conductivity `kappa`, which is what we require here. ```toml # fluid.i [FoamBCs] [solid_heat_flux] - type = FoamFixedGradientBC + type = FoamDiffusionFluxBC foam_variable = T - diffusivity_coefficient = kappa [] [] ``` From 7d8fec569bc2aaa0768eee1dc317b5740f394ce3 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Thu, 4 Jun 2026 10:20:35 +0100 Subject: [PATCH 49/52] Update postprocessor-based BCs on code review --- include/bcs/FoamBCBase.h | 2 +- include/bcs/FoamPostprocessorBCBase.h | 2 +- include/bcs/FoamVariableBCBase.h | 2 +- src/bcs/FoamDiffusionFluxPostprocessorBC.C | 13 +++++++------ src/bcs/FoamPostprocessorBCBase.C | 2 +- src/bcs/FoamVariableBCBase.C | 2 +- src/problems/FoamProblem.C | 2 +- 7 files changed, 13 insertions(+), 12 deletions(-) diff --git a/include/bcs/FoamBCBase.h b/include/bcs/FoamBCBase.h index 3f5d369a..67cfaa5b 100644 --- a/include/bcs/FoamBCBase.h +++ b/include/bcs/FoamBCBase.h @@ -32,7 +32,7 @@ class FoamBCBase : public MooseObject, public Coupleable virtual void initialSetup() = 0; // Add information about BC to table - virtual BCInfoTableRow addInfoRow() const = 0; + virtual BCInfoTableRow getInfoRow() const = 0; protected: // OpenFOAM variable which this BC is to be imposed on diff --git a/include/bcs/FoamPostprocessorBCBase.h b/include/bcs/FoamPostprocessorBCBase.h index b7fb7eeb..7d14362f 100644 --- a/include/bcs/FoamPostprocessorBCBase.h +++ b/include/bcs/FoamPostprocessorBCBase.h @@ -17,7 +17,7 @@ class FoamPostprocessorBCBase : public FoamBCBase, public PostprocessorInterface virtual void initialSetup() override {}; - virtual BCInfoTableRow addInfoRow() const override; + virtual BCInfoTableRow getInfoRow() const override; protected: const PostprocessorName _pp_name; diff --git a/include/bcs/FoamVariableBCBase.h b/include/bcs/FoamVariableBCBase.h index 08fa2489..ac68f96a 100644 --- a/include/bcs/FoamVariableBCBase.h +++ b/include/bcs/FoamVariableBCBase.h @@ -16,7 +16,7 @@ class FoamVariableBCBase : public FoamBCBase virtual void initialSetup() override; - virtual BCInfoTableRow addInfoRow() const override; + virtual BCInfoTableRow getInfoRow() const override; protected: // Get the value of the MOOSE variable at an element diff --git a/src/bcs/FoamDiffusionFluxPostprocessorBC.C b/src/bcs/FoamDiffusionFluxPostprocessorBC.C index f5fd1a57..49a6fab1 100644 --- a/src/bcs/FoamDiffusionFluxPostprocessorBC.C +++ b/src/bcs/FoamDiffusionFluxPostprocessorBC.C @@ -33,19 +33,20 @@ FoamDiffusionFluxPostprocessorBC::imposeBoundaryCondition() auto subdomains = _mesh->getSubdomainIDs(_boundary); for (auto subdomain : subdomains) { - auto & boundary = foam_mesh.boundary()[subdomain]; + const auto & boundary = foam_mesh.boundary()[subdomain]; // Get underlying field from OpenFOAM boundary patch. auto & foam_gradient = _mesh->getGradientBCField(subdomain, _foam_variable); // Get the underlying diffusivity field - auto & coeff = foam_mesh.boundary()[subdomain].lookupPatchField( - _diffusivity); + const auto & coeff = + foam_mesh.boundary()[subdomain].lookupPatchField( + _diffusivity); // Calculate the bulk value of the diffusivity coefficient - auto area = boundary.magSf(); - auto total_area = Foam::returnReduce(Foam::sum(area), Foam::sumOp()); - auto coeff_bulk = + const auto area = boundary.magSf(); + const auto total_area = Foam::returnReduce(Foam::sum(area), Foam::sumOp()); + const auto coeff_bulk = Foam::returnReduce(Foam::sum(coeff * area), Foam::sumOp()) / total_area; // set gradient diff --git a/src/bcs/FoamPostprocessorBCBase.C b/src/bcs/FoamPostprocessorBCBase.C index e0c75bac..fb84f98e 100644 --- a/src/bcs/FoamPostprocessorBCBase.C +++ b/src/bcs/FoamPostprocessorBCBase.C @@ -31,7 +31,7 @@ FoamPostprocessorBCBase::FoamPostprocessorBCBase(const InputParameters & params) } BCInfoTableRow -FoamPostprocessorBCBase::addInfoRow() const +FoamPostprocessorBCBase::getInfoRow() const { return std::make_tuple(name(), type(), diff --git a/src/bcs/FoamVariableBCBase.C b/src/bcs/FoamVariableBCBase.C index 1287766d..f8896577 100644 --- a/src/bcs/FoamVariableBCBase.C +++ b/src/bcs/FoamVariableBCBase.C @@ -52,7 +52,7 @@ FoamVariableBCBase::initialSetup() } BCInfoTableRow -FoamVariableBCBase::addInfoRow() const +FoamVariableBCBase::getInfoRow() const { // List info about BC return std::make_tuple( diff --git a/src/problems/FoamProblem.C b/src/problems/FoamProblem.C index b91f4d89..9fadb6d5 100644 --- a/src/problems/FoamProblem.C +++ b/src/problems/FoamProblem.C @@ -152,7 +152,7 @@ FoamProblem::verifyFoamBCs() auto && boundary = bc->boundary(); used_bcs.insert(used_bcs.end(), boundary.begin(), boundary.end()); // List info about BC - auto [name, type, foam_var, moose_var, boundaries] = bc->addInfoRow(); + auto [name, type, foam_var, moose_var, boundaries] = bc->getInfoRow(); vt.addRow(name, type, foam_var, moose_var, boundaries); } } From 0e4f71dab62af871b8ea7ddb9e4cf7894e8a5f3c Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Thu, 4 Jun 2026 10:24:29 +0100 Subject: [PATCH 50/52] Remove whitespace from tests --- test/tests/fixed-point/heated_plate_converge/fluid.i | 1 - test/tests/fixed-point/laplacian_fixed_gradient/fluid-openfoam.i | 1 - test/tests/fixed-point/restart_heated_plate/fluid.i | 1 - test/tests/fixed-point/restep_fixed_point/fluid-openfoam.i | 1 - .../fixed-point/unsteady_fixed_point_converge/fluid-openfoam.i | 1 - test/tests/fixed-point/unsteady_hc_variable_dt/fluid-openfoam.i | 1 - 6 files changed, 6 deletions(-) diff --git a/test/tests/fixed-point/heated_plate_converge/fluid.i b/test/tests/fixed-point/heated_plate_converge/fluid.i index f937c25e..9c0817ca 100644 --- a/test/tests/fixed-point/heated_plate_converge/fluid.i +++ b/test/tests/fixed-point/heated_plate_converge/fluid.i @@ -24,7 +24,6 @@ [solid_heat_flux] type = FoamDiffusionFluxBC foam_variable = 'T' - initial_condition = 0 [] [] diff --git a/test/tests/fixed-point/laplacian_fixed_gradient/fluid-openfoam.i b/test/tests/fixed-point/laplacian_fixed_gradient/fluid-openfoam.i index d73846ca..e15c691a 100644 --- a/test/tests/fixed-point/laplacian_fixed_gradient/fluid-openfoam.i +++ b/test/tests/fixed-point/laplacian_fixed_gradient/fluid-openfoam.i @@ -16,7 +16,6 @@ [fluid_heat_flux] type = FoamDiffusionFluxBC foam_variable = 'T' - initial_condition = 0.075 [] [] diff --git a/test/tests/fixed-point/restart_heated_plate/fluid.i b/test/tests/fixed-point/restart_heated_plate/fluid.i index f937c25e..9c0817ca 100644 --- a/test/tests/fixed-point/restart_heated_plate/fluid.i +++ b/test/tests/fixed-point/restart_heated_plate/fluid.i @@ -24,7 +24,6 @@ [solid_heat_flux] type = FoamDiffusionFluxBC foam_variable = 'T' - initial_condition = 0 [] [] diff --git a/test/tests/fixed-point/restep_fixed_point/fluid-openfoam.i b/test/tests/fixed-point/restep_fixed_point/fluid-openfoam.i index 53d16a69..d1be5762 100644 --- a/test/tests/fixed-point/restep_fixed_point/fluid-openfoam.i +++ b/test/tests/fixed-point/restep_fixed_point/fluid-openfoam.i @@ -16,7 +16,6 @@ [solid_heat_flux] type = FoamDiffusionFluxBC foam_variable = 'T' - initial_condition = 0 [] [] diff --git a/test/tests/fixed-point/unsteady_fixed_point_converge/fluid-openfoam.i b/test/tests/fixed-point/unsteady_fixed_point_converge/fluid-openfoam.i index 53d16a69..d1be5762 100644 --- a/test/tests/fixed-point/unsteady_fixed_point_converge/fluid-openfoam.i +++ b/test/tests/fixed-point/unsteady_fixed_point_converge/fluid-openfoam.i @@ -16,7 +16,6 @@ [solid_heat_flux] type = FoamDiffusionFluxBC foam_variable = 'T' - initial_condition = 0 [] [] diff --git a/test/tests/fixed-point/unsteady_hc_variable_dt/fluid-openfoam.i b/test/tests/fixed-point/unsteady_hc_variable_dt/fluid-openfoam.i index 78585653..7dd98811 100644 --- a/test/tests/fixed-point/unsteady_hc_variable_dt/fluid-openfoam.i +++ b/test/tests/fixed-point/unsteady_hc_variable_dt/fluid-openfoam.i @@ -25,7 +25,6 @@ [solid_heat_flux] type = FoamDiffusionFluxBC foam_variable = 'T' - initial_condition = 0 [] [] From 96f06295391965b8d981a29a1835a4be1cf9c3ee Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Thu, 4 Jun 2026 10:48:42 +0100 Subject: [PATCH 51/52] Remove allow_warnings --- doc/content/step_by_step.md | 2 +- test/tests/actions/foam_bc/tests | 4 ---- test/tests/actions/foam_variable/tests | 2 -- test/tests/bcs/diffusion_flux_pp/tests | 3 --- test/tests/bcs/fixed_gradient_pp/tests | 1 - test/tests/bcs/fixed_value/tests | 2 -- test/tests/bcs/fixed_value_pp/tests | 1 - test/tests/bcs/laplace_fixed_gradient/tests | 1 - test/tests/bcs/laplace_flux_bc/tests | 3 --- test/tests/bcs/mass_flow_rate/tests | 1 - test/tests/bcs/receiver_pp/tests | 3 --- test/tests/fixed-point/flow_over_heated_plate/tests | 2 -- test/tests/fixed-point/function_test/tests | 2 -- test/tests/fixed-point/heated_plate_converge/tests | 1 - test/tests/fixed-point/laplacian_fixed_gradient/tests | 2 -- test/tests/fixed-point/laplacian_fixed_value/tests | 2 -- test/tests/fixed-point/ode_euler/tests | 2 -- test/tests/fixed-point/restart_heated_plate/tests | 1 - test/tests/fixed-point/restep_fixed_point/tests | 1 - test/tests/postprocessors/side_advective_flux_integral/tests | 4 ---- test/tests/postprocessors/side_average/tests | 2 -- test/tests/postprocessors/side_integrated_value/tests | 4 ---- test/tests/variables/foam_variable/tests | 2 -- 23 files changed, 1 insertion(+), 47 deletions(-) diff --git a/doc/content/step_by_step.md b/doc/content/step_by_step.md index 28d6e7d2..a3c09868 100644 --- a/doc/content/step_by_step.md +++ b/doc/content/step_by_step.md @@ -136,7 +136,7 @@ and so can be transferred between MOOSE apps. Hippo also implements the `FoamBC` system that allows you to impose boundary conditions on OpenFOAM from the Hippo input file. In this case, we wish to impose a heat flux BC -on the temperature field, which can be donw using `FoamDiffusionFluxBC`. A diffusivity can be specified, +on the temperature field, which can be done using `FoamDiffusionFluxBC`. A diffusivity can be specified, although the default is the thermal conductivity `kappa`, which is what we require here. ```toml diff --git a/test/tests/actions/foam_bc/tests b/test/tests/actions/foam_bc/tests index 3e5b200b..9ed2ded2 100644 --- a/test/tests/actions/foam_bc/tests +++ b/test/tests/actions/foam_bc/tests @@ -9,7 +9,6 @@ input = main.i prereq = foam_bc_action/setup allow_test_objects = true - allow_warnings = true [] [foam_var_error] type = RunException @@ -18,7 +17,6 @@ expect_err = "There is no OpenFOAM field named 'T1'" cli_args = 'FoamBCs/temp/foam_variable=T1' allow_test_objects = true - allow_warnings = true [] [foam_boundary_error] type = RunException @@ -27,7 +25,6 @@ expect_err = "Boundary 'left1' not found in FoamMesh" cli_args = 'FoamBCs/temp/boundary=left1' allow_test_objects = true - allow_warnings = true [] [foam_duplicated_boundary_error] type = RunException @@ -35,7 +32,6 @@ prereq = foam_bc_action/setup expect_err = "Imposed FoamBC has duplicated boundary 'left' for foam variable 'T'" cli_args = 'FoamBCs/temp_r/boundary=left' - allow_warnings = true allow_test_objects = true [] [] diff --git a/test/tests/actions/foam_variable/tests b/test/tests/actions/foam_variable/tests index c7e7fa3b..1fa573db 100644 --- a/test/tests/actions/foam_variable/tests +++ b/test/tests/actions/foam_variable/tests @@ -8,7 +8,6 @@ type = RunApp input = main.i prereq = transfer_test/setup - allow_warnings = true [] [err_problem] type = RunException @@ -16,7 +15,6 @@ prereq = transfer_test/setup expect_err = "can only be used with FoamProblem" cli_args = "Problem/type=FEProblem" - allow_warnings = true [] [] [] diff --git a/test/tests/bcs/diffusion_flux_pp/tests b/test/tests/bcs/diffusion_flux_pp/tests index 02996f8c..a7969cff 100644 --- a/test/tests/bcs/diffusion_flux_pp/tests +++ b/test/tests/bcs/diffusion_flux_pp/tests @@ -10,13 +10,11 @@ prereq = foam_bc_diffusion_flux_pp/setup expect_err = "Diffusivity 'kappa1' not a Foam volScalarField" cli_args = 'FoamBCs/T_flux/diffusivity=kappa1' - allow_warnings = true [] [run] type = RunApp input = main.i prereq = foam_bc_diffusion_flux_pp/setup - allow_warnings = true [] [verify] type = PythonUnitTest @@ -28,7 +26,6 @@ input = main.i cli_args = "FoamBCs/T_flux/diffusivity='Cv' Postprocessors/T_flux/expression='t'" prereq = foam_bc_diffusion_flux_pp/verify - allow_warnings = true [] [verify_diffusivity_cv] type = PythonUnitTest diff --git a/test/tests/bcs/fixed_gradient_pp/tests b/test/tests/bcs/fixed_gradient_pp/tests index e0cdc47f..885533fd 100644 --- a/test/tests/bcs/fixed_gradient_pp/tests +++ b/test/tests/bcs/fixed_gradient_pp/tests @@ -8,7 +8,6 @@ type = RunApp input = main.i prereq = foam_bc_fixed_gradient_pp/setup - allow_warnings = true [] [verify] type = PythonUnitTest diff --git a/test/tests/bcs/fixed_value/tests b/test/tests/bcs/fixed_value/tests index 948c7de2..6b0967ee 100644 --- a/test/tests/bcs/fixed_value/tests +++ b/test/tests/bcs/fixed_value/tests @@ -8,7 +8,6 @@ type = RunApp input = main.i prereq = foam_bc_action_test/setup - allow_warnings = true [] [verify] type = PythonUnitTest @@ -21,7 +20,6 @@ min_parallel=4 max_parallel=4 prereq = foam_bc_action_test/setup - allow_warnings = true [] [prep_verify] type = RunCommand diff --git a/test/tests/bcs/fixed_value_pp/tests b/test/tests/bcs/fixed_value_pp/tests index 002cd453..f33754ad 100644 --- a/test/tests/bcs/fixed_value_pp/tests +++ b/test/tests/bcs/fixed_value_pp/tests @@ -8,7 +8,6 @@ type = RunApp input = main.i prereq = foam_bc_action_test/setup - allow_warnings = true [] [verify] type = PythonUnitTest diff --git a/test/tests/bcs/laplace_fixed_gradient/tests b/test/tests/bcs/laplace_fixed_gradient/tests index 6c60cad8..879f5428 100644 --- a/test/tests/bcs/laplace_fixed_gradient/tests +++ b/test/tests/bcs/laplace_fixed_gradient/tests @@ -8,7 +8,6 @@ type = RunApp input = main.i prereq = foam_bc_fixed_gradient/setup - allow_warnings = true [] [verify] type = PythonUnitTest diff --git a/test/tests/bcs/laplace_flux_bc/tests b/test/tests/bcs/laplace_flux_bc/tests index 287a086b..4a84549c 100644 --- a/test/tests/bcs/laplace_flux_bc/tests +++ b/test/tests/bcs/laplace_flux_bc/tests @@ -8,7 +8,6 @@ type = RunException input = main.i prereq = foam_bc_diffusion_flux/setup - allow_warnings = true cli_args ='FoamBCs/T_flux/diffusivity=kappa1' expect_err = "Diffusivity 'kappa1' not a Foam volScalarField" [] @@ -16,7 +15,6 @@ type = RunApp input = main.i prereq = foam_bc_diffusion_flux/setup - allow_warnings = true [] [verify] type = PythonUnitTest @@ -28,7 +26,6 @@ input = main.i prereq = foam_bc_diffusion_flux/setup cli_args ='FoamBCs/T_flux/diffusivity=Cv AuxKernels/T_flux/expression=t' - allow_warnings = true [] [verify_diffusivity] type = PythonUnitTest diff --git a/test/tests/bcs/mass_flow_rate/tests b/test/tests/bcs/mass_flow_rate/tests index 68cf4430..2f51d581 100644 --- a/test/tests/bcs/mass_flow_rate/tests +++ b/test/tests/bcs/mass_flow_rate/tests @@ -9,7 +9,6 @@ input = main.i prereq = mass_flow_rate/setup csvdiff = main_out.csv - allow_warnings = true [] [] [] diff --git a/test/tests/bcs/receiver_pp/tests b/test/tests/bcs/receiver_pp/tests index 371cbe3e..7cc25f0b 100644 --- a/test/tests/bcs/receiver_pp/tests +++ b/test/tests/bcs/receiver_pp/tests @@ -10,13 +10,11 @@ prereq = receiver_pp/setup expect_err = "Diffusivity 'kappa1' not a Foam volScalarField" cli_args = 'FoamBCs/T_flux/diffusivity=kappa1' - allow_warnings = true [] [run] type = RunApp input = main.i prereq = receiver_pp/setup - allow_warnings = true [] [verify] type = PythonUnitTest @@ -28,7 +26,6 @@ input = main.i cli_args = "FoamBCs/T_flux/diffusivity='Cv' FoamBCs/T_flux/default=1" prereq = receiver_pp/verify - allow_warnings = true [] [verify_diffusivity_cv] type = PythonUnitTest diff --git a/test/tests/fixed-point/flow_over_heated_plate/tests b/test/tests/fixed-point/flow_over_heated_plate/tests index 567f657f..28dd8121 100644 --- a/test/tests/fixed-point/flow_over_heated_plate/tests +++ b/test/tests/fixed-point/flow_over_heated_plate/tests @@ -9,7 +9,6 @@ type = RunApp input = heated_plate-no-fixed.i prereq = 'flow_over_heated_plate_parallel/no_fixed_point/setup' - allow_warnings = true cli_args="Executioner/fixed_point_max_its=1" min_parallel=4 max_parallel=4 @@ -31,7 +30,6 @@ input = heated_plate.i prereq = 'flow_over_heated_plate_parallel/fixed_point/setup' exodiff = heated_plate_out.e - allow_warnings = true min_parallel=4 max_parallel=4 [] diff --git a/test/tests/fixed-point/function_test/tests b/test/tests/fixed-point/function_test/tests index 393c987a..78dd277a 100644 --- a/test/tests/fixed-point/function_test/tests +++ b/test/tests/fixed-point/function_test/tests @@ -9,7 +9,6 @@ input = main.i prereq = 'create_reference/setup' cli_args = 'Executioner/fixed_point_min_its=1 Executioner/fixed_point_max_its=1' - allow_warnings = true [] [copy] type = RunCommand @@ -27,7 +26,6 @@ type = RunApp input = main.i prereq = function_test/setup - allow_warnings = true [] [verify] type = PythonUnitTest diff --git a/test/tests/fixed-point/heated_plate_converge/tests b/test/tests/fixed-point/heated_plate_converge/tests index 6407419e..f79fa52d 100644 --- a/test/tests/fixed-point/heated_plate_converge/tests +++ b/test/tests/fixed-point/heated_plate_converge/tests @@ -9,7 +9,6 @@ input = heated_plate.i prereq = 'flow_over_heated_plate_regression/setup' exodiff = heated_plate_out.e - allow_warnings = true min_parallel=4 max_parallel=4 rel_err = 1e-4 diff --git a/test/tests/fixed-point/laplacian_fixed_gradient/tests b/test/tests/fixed-point/laplacian_fixed_gradient/tests index 715e0ad0..f27e79b4 100644 --- a/test/tests/fixed-point/laplacian_fixed_gradient/tests +++ b/test/tests/fixed-point/laplacian_fixed_gradient/tests @@ -9,7 +9,6 @@ input = main.i prereq = 'create_reference/setup' cli_args = 'Executioner/fixed_point_min_its=1 Executioner/fixed_point_max_its=1' - allow_warnings = true [] [copy] type = RunCommand @@ -27,7 +26,6 @@ type = RunApp input = main.i prereq = laplacian_fixed_gradient/setup - allow_warnings = true [] [verify] type = PythonUnitTest diff --git a/test/tests/fixed-point/laplacian_fixed_value/tests b/test/tests/fixed-point/laplacian_fixed_value/tests index 650015ee..bd06cf55 100644 --- a/test/tests/fixed-point/laplacian_fixed_value/tests +++ b/test/tests/fixed-point/laplacian_fixed_value/tests @@ -9,7 +9,6 @@ input = main.i prereq = 'create_reference/setup' cli_args = 'Executioner/fixed_point_min_its=1 Executioner/fixed_point_max_its=1' - allow_warnings = true [] [copy] type = RunCommand @@ -27,7 +26,6 @@ type = RunApp input = main.i prereq = laplacian_fixed_value/setup - allow_warnings = true [] [verify] type = PythonUnitTest diff --git a/test/tests/fixed-point/ode_euler/tests b/test/tests/fixed-point/ode_euler/tests index 2fbdef54..85d60ed7 100644 --- a/test/tests/fixed-point/ode_euler/tests +++ b/test/tests/fixed-point/ode_euler/tests @@ -9,7 +9,6 @@ input = main.i prereq = 'create_reference/setup' cli_args = 'Executioner/fixed_point_min_its=1 Executioner/fixed_point_max_its=1' - allow_warnings = true [] [copy] type = RunCommand @@ -27,7 +26,6 @@ type = RunApp input = main.i prereq = ode_euler/setup - allow_warnings = true [] [verify] type = PythonUnitTest diff --git a/test/tests/fixed-point/restart_heated_plate/tests b/test/tests/fixed-point/restart_heated_plate/tests index 80cc7921..93386941 100644 --- a/test/tests/fixed-point/restart_heated_plate/tests +++ b/test/tests/fixed-point/restart_heated_plate/tests @@ -20,7 +20,6 @@ delete_output_before_running = false exodiff = heated_plate_out.e gold_dir = '../heated_plate_converge' - allow_warnings = true min_parallel=4 max_parallel=4 [] diff --git a/test/tests/fixed-point/restep_fixed_point/tests b/test/tests/fixed-point/restep_fixed_point/tests index db3438ef..e4bee548 100644 --- a/test/tests/fixed-point/restep_fixed_point/tests +++ b/test/tests/fixed-point/restep_fixed_point/tests @@ -10,7 +10,6 @@ min_parallel=2 max_parallel=2 prereq = run_reference/setup - allow_warnings = true cli_args="Problem/type=FEProblem Executioner/TimeStepper/type=ConstantDT Executioner/TimeStepper/dt=0.0003125 -w" [] [copy] diff --git a/test/tests/postprocessors/side_advective_flux_integral/tests b/test/tests/postprocessors/side_advective_flux_integral/tests index d1258876..0c6a0e08 100644 --- a/test/tests/postprocessors/side_advective_flux_integral/tests +++ b/test/tests/postprocessors/side_advective_flux_integral/tests @@ -8,7 +8,6 @@ type = RunApp input = main.i prereq = postprocessor_test/setup - allow_warnings = true [] [verify_serial] type = PythonUnitTest @@ -19,7 +18,6 @@ type = RunApp input = main.i prereq = postprocessor_test/setup - allow_warnings = true min_parallel=2 max_parallel=2 [] @@ -32,7 +30,6 @@ type = RunException input = main.i prereq = postprocessor_test/setup - allow_warnings = true cli_args='Postprocessors/m_dot_x1/advective_velocity=U1' expect_err = "advective_velocity 'U1' not found." [] @@ -40,7 +37,6 @@ type = RunException input = main.i prereq = postprocessor_test/setup - allow_warnings = true cli_args='Postprocessors/m_dot_x1/foam_scalar=rho1' expect_err = "foam_scalar 'rho1' not found." [] diff --git a/test/tests/postprocessors/side_average/tests b/test/tests/postprocessors/side_average/tests index 9ab58d31..b5ca82e4 100644 --- a/test/tests/postprocessors/side_average/tests +++ b/test/tests/postprocessors/side_average/tests @@ -8,7 +8,6 @@ type = RunApp input = main.i prereq = postprocessor_test/setup - allow_warnings = true [] [verify_serial] type = PythonUnitTest @@ -19,7 +18,6 @@ type = RunApp input = main.i prereq = postprocessor_test/setup - allow_warnings = true min_parallel=2 max_parallel=2 [] diff --git a/test/tests/postprocessors/side_integrated_value/tests b/test/tests/postprocessors/side_integrated_value/tests index edd33817..7c5e4895 100644 --- a/test/tests/postprocessors/side_integrated_value/tests +++ b/test/tests/postprocessors/side_integrated_value/tests @@ -8,7 +8,6 @@ type = RunApp input = main.i prereq = postprocessor_test/setup - allow_warnings = true [] [verify_serial] type = PythonUnitTest @@ -19,7 +18,6 @@ type = RunApp input = main.i prereq = postprocessor_test/setup - allow_warnings = true min_parallel=2 max_parallel=2 [] @@ -32,7 +30,6 @@ type = RunException input = main.i prereq = postprocessor_test/setup - allow_warnings = true cli_args='Postprocessors/t_avg/boundary=top1' expect_err = "Boundary 'top1' not found in FoamMesh." [] @@ -40,7 +37,6 @@ type = RunException input = main.i prereq = postprocessor_test/setup - allow_warnings = true cli_args='Postprocessors/t_avg/foam_variable=T1' expect_err = "No Foam scalar or vector called 'T1'." [] diff --git a/test/tests/variables/foam_variable/tests b/test/tests/variables/foam_variable/tests index f511e12d..25ce77de 100644 --- a/test/tests/variables/foam_variable/tests +++ b/test/tests/variables/foam_variable/tests @@ -8,7 +8,6 @@ type = RunApp input = main.i prereq = transfer_test/setup - allow_warnings = true [] [verify] type = PythonUnitTest @@ -19,7 +18,6 @@ type = RunApp input = main.i prereq = transfer_test/setup - allow_warnings = true min_parallel=4 max_parallel=4 [] From 41d1689ee3a34ab9b8b13797890ce5361af45ce6 Mon Sep 17 00:00:00 2001 From: Matthew Falcone Date: Thu, 4 Jun 2026 13:27:34 +0100 Subject: [PATCH 52/52] Update tests using np.testing and adding clarifying comments --- test/tests/actions/foam_bc/test.py | 29 -------------- test/tests/bcs/diffusion_flux_pp/test.py | 25 ++++++++---- test/tests/bcs/fixed_gradient_pp/test.py | 25 ++++++++---- test/tests/bcs/fixed_value/test.py | 14 +++++-- test/tests/bcs/fixed_value_pp/test.py | 14 +++++-- test/tests/bcs/laplace_fixed_gradient/test.py | 23 ++++++++--- test/tests/bcs/laplace_flux_bc/test.py | 28 +++++++++---- test/tests/bcs/receiver_pp/test.py | 40 +++++++++++-------- test/tests/bcs/receiver_pp/tests | 1 + .../side_advective_flux_integral/test.py | 15 ++++--- .../tests/postprocessors/side_average/test.py | 30 ++++++++------ .../side_integrated_value/test.py | 30 ++++++++------ test/tests/variables/foam_variable/test.py | 28 +++++++++---- 13 files changed, 182 insertions(+), 120 deletions(-) delete mode 100644 test/tests/actions/foam_bc/test.py diff --git a/test/tests/actions/foam_bc/test.py b/test/tests/actions/foam_bc/test.py deleted file mode 100644 index d0ea36c3..00000000 --- a/test/tests/actions/foam_bc/test.py +++ /dev/null @@ -1,29 +0,0 @@ -"""Tests for imposing BCs in OpenFOAM using MOOSE input file syntax""" - -import unittest - -import fluidfoam as ff -import numpy as np -from read_hippo_data import get_foam_times - - -class TestFoamBCFixedGradient(unittest.TestCase): - """Test class for imposing fixed gradient BCs in Hippo.""" - - def test_fixed_gradient_x(self): - """Test case for imposing fixed gradient.""" - case_dir = "foam/" - times = get_foam_times(case_dir)[1:] - - for time in times: - coords = dict(zip(("x", "y", "z"), ff.readof.readmesh(case_dir))) - - temp = ff.readof.readscalar(case_dir, time, "T") - - temp_ref = coords["x"] * np.float64(time) - - temp_diff_max = np.argmax(abs(temp - temp_ref)) - assert np.allclose(temp_ref, temp, rtol=1e-7, atol=1e-12), ( - f"Max diff ({time}): {abs(temp - temp_ref).max()} " - f"{temp[temp_diff_max]} {temp_ref[temp_diff_max]}" - ) diff --git a/test/tests/bcs/diffusion_flux_pp/test.py b/test/tests/bcs/diffusion_flux_pp/test.py index 98b48ce7..a8dd55e7 100644 --- a/test/tests/bcs/diffusion_flux_pp/test.py +++ b/test/tests/bcs/diffusion_flux_pp/test.py @@ -1,17 +1,22 @@ """Tests for imposing BCs in OpenFOAM using MOOSE input file syntax""" import unittest + import fluidfoam as ff import numpy as np - from read_hippo_data import get_foam_times # pylint: disable=E0401 -class TestFoamBCFixedGradient(unittest.TestCase): - """Test class for imposing fixed value BCs in Hippo.""" +class TestFoamBCDiffusionFluxPP(unittest.TestCase): + """Test class for imposing fixed gradient BCs in Hippo.""" def test_fixed_gradient_x(self): - """Test case for imposing fixed value.""" + """ + Test case for imposing diffusion flux BC with postprocessor. + + Solves laplace equation at each time step with right BC being k\partial_x T = 2t + where k is 2. The analytical solution is t*x. + """ case_dir = "foam/" times = get_foam_times(case_dir, string=True)[1:] @@ -23,7 +28,13 @@ def test_fixed_gradient_x(self): temp_ref = coords["x"] * np.float64(time) temp_diff_max = np.argmax(abs(temp - temp_ref)) - assert np.allclose(temp_ref, temp, rtol=1e-7, atol=1e-12), ( - f"Max diff ({time}): {abs(temp - temp_ref).max()} " - f"{temp[temp_diff_max]} {temp_ref[temp_diff_max]}" + np.testing.assert_allclose( + temp_ref, + temp, + rtol=1e-7, + atol=1e-12, + err_msg=( + f"Max diff ({time}): {abs(temp - temp_ref).max()} " + f"{temp[temp_diff_max]} {temp_ref[temp_diff_max]}" + ), ) diff --git a/test/tests/bcs/fixed_gradient_pp/test.py b/test/tests/bcs/fixed_gradient_pp/test.py index 98b48ce7..1bb49201 100644 --- a/test/tests/bcs/fixed_gradient_pp/test.py +++ b/test/tests/bcs/fixed_gradient_pp/test.py @@ -1,17 +1,22 @@ """Tests for imposing BCs in OpenFOAM using MOOSE input file syntax""" import unittest + import fluidfoam as ff import numpy as np - from read_hippo_data import get_foam_times # pylint: disable=E0401 -class TestFoamBCFixedGradient(unittest.TestCase): +class TestFoamBCFixedGradientPP(unittest.TestCase): """Test class for imposing fixed value BCs in Hippo.""" - def test_fixed_gradient_x(self): - """Test case for imposing fixed value.""" + def test_diffusion_flux_x(self): + """ + Test case for imposing diffusion flux BC with postprocessor. + + Solves laplace equation at each time step with right BC being \partial_x T = t. + The analytical solution is t*x. + """ case_dir = "foam/" times = get_foam_times(case_dir, string=True)[1:] @@ -23,7 +28,13 @@ def test_fixed_gradient_x(self): temp_ref = coords["x"] * np.float64(time) temp_diff_max = np.argmax(abs(temp - temp_ref)) - assert np.allclose(temp_ref, temp, rtol=1e-7, atol=1e-12), ( - f"Max diff ({time}): {abs(temp - temp_ref).max()} " - f"{temp[temp_diff_max]} {temp_ref[temp_diff_max]}" + np.testing.assert_allclose( + temp_ref, + temp, + rtol=1e-7, + atol=1e-12, + err_msg=( + f"Max diff ({time}): {abs(temp - temp_ref).max()} " + f"{temp[temp_diff_max]} {temp_ref[temp_diff_max]}" + ), ) diff --git a/test/tests/bcs/fixed_value/test.py b/test/tests/bcs/fixed_value/test.py index c7961bac..93782320 100644 --- a/test/tests/bcs/fixed_value/test.py +++ b/test/tests/bcs/fixed_value/test.py @@ -1,9 +1,9 @@ """Tests for imposing BCs in OpenFOAM using MOOSE input file syntax""" import unittest + import fluidfoam as ff import numpy as np - from read_hippo_data import get_foam_times # pylint: disable=E0401 @@ -32,7 +32,13 @@ def test_fixed_value(self): ) * np.float64(time) temp_diff_max = np.argmax(abs(temp - temp_ref)) - assert np.allclose(temp_ref, temp, rtol=1e-7, atol=1e-12), ( - f"Max diff {boundary} ({time}): {abs(temp - temp_ref).max()} " - f"{temp[temp_diff_max]} {temp_ref[temp_diff_max]}" + np.testing.assert_allclose( + temp_ref, + temp, + rtol=1e-7, + atol=1e-12, + err_msg=( + f"Max diff ({time}): {abs(temp - temp_ref).max()} " + f"{temp[temp_diff_max]} {temp_ref[temp_diff_max]}" + ), ) diff --git a/test/tests/bcs/fixed_value_pp/test.py b/test/tests/bcs/fixed_value_pp/test.py index a42a0eed..3ab99c3f 100644 --- a/test/tests/bcs/fixed_value_pp/test.py +++ b/test/tests/bcs/fixed_value_pp/test.py @@ -1,9 +1,9 @@ """Tests for imposing BCs in OpenFOAM using MOOSE input file syntax""" import unittest + import fluidfoam as ff import numpy as np - from read_hippo_data import get_foam_times # pylint: disable=E0401 @@ -24,7 +24,13 @@ def test_fixed_value(self): temp_ref = 0.05 + scale * np.float64(time) temp_diff_max = np.argmax(abs(temp - temp_ref)) - assert np.allclose(temp_ref, temp, rtol=1e-7, atol=1e-12), ( - f"Max diff {boundary} ({time}): {abs(temp - temp_ref).max()} " - f"{temp[temp_diff_max]} {temp_ref[temp_diff_max]}" + np.testing.assert_allclose( + temp_ref, + temp, + rtol=1e-7, + atol=1e-12, + err_msg=( + f"Max diff ({time}): {abs(temp - temp_ref).max()} " + f"{temp[temp_diff_max]} {temp_ref}" + ), ) diff --git a/test/tests/bcs/laplace_fixed_gradient/test.py b/test/tests/bcs/laplace_fixed_gradient/test.py index 98b48ce7..34225a55 100644 --- a/test/tests/bcs/laplace_fixed_gradient/test.py +++ b/test/tests/bcs/laplace_fixed_gradient/test.py @@ -1,17 +1,22 @@ """Tests for imposing BCs in OpenFOAM using MOOSE input file syntax""" import unittest + import fluidfoam as ff import numpy as np - from read_hippo_data import get_foam_times # pylint: disable=E0401 class TestFoamBCFixedGradient(unittest.TestCase): - """Test class for imposing fixed value BCs in Hippo.""" + """Test class for imposing fixed gradient BCs in Hippo.""" def test_fixed_gradient_x(self): - """Test case for imposing fixed value.""" + """ + Test case for imposing fixed gradient BC. + + Solves laplace equation at each time step with right BC being \partial_x T = t. + The analytical solution is t*x. + """ case_dir = "foam/" times = get_foam_times(case_dir, string=True)[1:] @@ -23,7 +28,13 @@ def test_fixed_gradient_x(self): temp_ref = coords["x"] * np.float64(time) temp_diff_max = np.argmax(abs(temp - temp_ref)) - assert np.allclose(temp_ref, temp, rtol=1e-7, atol=1e-12), ( - f"Max diff ({time}): {abs(temp - temp_ref).max()} " - f"{temp[temp_diff_max]} {temp_ref[temp_diff_max]}" + np.testing.assert_allclose( + temp_ref, + temp, + rtol=1e-7, + atol=1e-12, + err_msg=( + f"Max diff ({time}): {abs(temp - temp_ref).max()} " + f"{temp[temp_diff_max]} {temp_ref[temp_diff_max]}" + ), ) diff --git a/test/tests/bcs/laplace_flux_bc/test.py b/test/tests/bcs/laplace_flux_bc/test.py index 98b48ce7..211943a7 100644 --- a/test/tests/bcs/laplace_flux_bc/test.py +++ b/test/tests/bcs/laplace_flux_bc/test.py @@ -1,17 +1,23 @@ """Tests for imposing BCs in OpenFOAM using MOOSE input file syntax""" import unittest + import fluidfoam as ff import numpy as np - from read_hippo_data import get_foam_times # pylint: disable=E0401 -class TestFoamBCFixedGradient(unittest.TestCase): - """Test class for imposing fixed value BCs in Hippo.""" +class TestFoamBCDiffusionFlux(unittest.TestCase): + """Test class for imposing flux BCs in Hippo.""" + + def test_diffusion_flux_x(self): + """ + Test case for imposing diffusion flux BCs. - def test_fixed_gradient_x(self): - """Test case for imposing fixed value.""" + Solves laplace equation at each time step with right BC being f\partial_x T = 2t + where k = 2. + The analytical solution is t*x. + """ case_dir = "foam/" times = get_foam_times(case_dir, string=True)[1:] @@ -23,7 +29,13 @@ def test_fixed_gradient_x(self): temp_ref = coords["x"] * np.float64(time) temp_diff_max = np.argmax(abs(temp - temp_ref)) - assert np.allclose(temp_ref, temp, rtol=1e-7, atol=1e-12), ( - f"Max diff ({time}): {abs(temp - temp_ref).max()} " - f"{temp[temp_diff_max]} {temp_ref[temp_diff_max]}" + np.testing.assert_allclose( + temp_ref, + temp, + rtol=1e-7, + atol=1e-12, + err_msg=( + f"Max diff ({time}): {abs(temp - temp_ref).max()} " + f"{temp[temp_diff_max]} {temp_ref[temp_diff_max]}" + ), ) diff --git a/test/tests/bcs/receiver_pp/test.py b/test/tests/bcs/receiver_pp/test.py index 98b48ce7..7761bfed 100644 --- a/test/tests/bcs/receiver_pp/test.py +++ b/test/tests/bcs/receiver_pp/test.py @@ -1,29 +1,37 @@ """Tests for imposing BCs in OpenFOAM using MOOSE input file syntax""" import unittest + import fluidfoam as ff import numpy as np -from read_hippo_data import get_foam_times # pylint: disable=E0401 - class TestFoamBCFixedGradient(unittest.TestCase): """Test class for imposing fixed value BCs in Hippo.""" - def test_fixed_gradient_x(self): - """Test case for imposing fixed value.""" - case_dir = "foam/" - times = get_foam_times(case_dir, string=True)[1:] - - for time in times: - coords = dict(zip(("x", "y", "z"), ff.readof.readmesh(case_dir))) + def test_diffusion_flux_x(self): + """ + Test case for imposing diffusion flux BCs using the default value of the + underlying reciever. - temp = ff.readof.readscalar(case_dir, time, "T") - - temp_ref = coords["x"] * np.float64(time) - - temp_diff_max = np.argmax(abs(temp - temp_ref)) - assert np.allclose(temp_ref, temp, rtol=1e-7, atol=1e-12), ( + Solves laplace equation with right BC being \partial_x T = 1. + The analytical solution is x. + """ + case_dir = "foam/" + time = "1" + coords = dict(zip(("x", "y", "z"), ff.readof.readmesh(case_dir))) + + temp = ff.readof.readscalar(case_dir, time, "T") + + temp_ref = coords["x"] + temp_diff_max = np.argmax(abs(temp - temp_ref)) + np.testing.assert_allclose( + temp_ref, + temp, + rtol=1e-7, + atol=1e-12, + err_msg=( f"Max diff ({time}): {abs(temp - temp_ref).max()} " f"{temp[temp_diff_max]} {temp_ref[temp_diff_max]}" - ) + ), + ) diff --git a/test/tests/bcs/receiver_pp/tests b/test/tests/bcs/receiver_pp/tests index 7cc25f0b..5ad5468b 100644 --- a/test/tests/bcs/receiver_pp/tests +++ b/test/tests/bcs/receiver_pp/tests @@ -1,5 +1,6 @@ [Tests] [receiver_pp] + requirement = "Tests the under-the-hood reciever in the Postprocessor BCs when using the default parameter" [setup] type = RunCommand command = 'bash -c "foamCleanCase -case foam && blockMesh -case foam"' diff --git a/test/tests/postprocessors/side_advective_flux_integral/test.py b/test/tests/postprocessors/side_advective_flux_integral/test.py index 097f99d4..51aa8f88 100644 --- a/test/tests/postprocessors/side_advective_flux_integral/test.py +++ b/test/tests/postprocessors/side_advective_flux_integral/test.py @@ -4,7 +4,6 @@ import numpy as np - U = [2, -1, 0] RHO = 0.5 AREAS = [1.0, 10.0, 10.0] @@ -21,13 +20,17 @@ def test_advective_flux_integral(self): for i in range(3): # n indicates the outward normal relative to the coordinate direction n = -1.0 - assert np.allclose( - data[i * 3], n * RHO * U[i] * AREAS[i], atol=1e-14, rtol=1e-12 - ), f"{data[i * 3]} vs {n * RHO * U[i] * AREAS[i]}" + np.testing.assert_allclose( + data[i * 3], + n * RHO * U[i] * AREAS[i], + atol=1e-14, + rtol=1e-12, + err_msg=f"{data[i * 3]} vs {n * RHO * U[i] * AREAS[i]}", + ) - assert np.allclose(data[i * 3 + 1], 0.0, atol=1e-14, rtol=1e-12) + np.testing.assert_allclose(data[i * 3 + 1], 0.0, atol=1e-14, rtol=1e-12) n = 1.0 - assert np.allclose( + np.testing.assert_allclose( data[i * 3 + 2], n * RHO * U[i] * AREAS[i], atol=1e-14, rtol=1e-12 ) diff --git a/test/tests/postprocessors/side_average/test.py b/test/tests/postprocessors/side_average/test.py index 3be266a2..ff5feef0 100644 --- a/test/tests/postprocessors/side_average/test.py +++ b/test/tests/postprocessors/side_average/test.py @@ -37,18 +37,22 @@ def test_side_average(self): tol_params = {"atol": 1e-14, "rtol": 1e-12} - assert np.allclose(data["t_avg"], T_AVG[1] * time, **tol_params) - assert np.allclose(data["t_avg_multiple"], T_AVG[1] * time, **tol_params) - assert np.allclose(data["U_avg_magnitude"], np.linalg.norm(U), **tol_params) - assert np.allclose( + np.testing.assert_allclose(data["t_avg"], T_AVG[1] * time, **tol_params) + np.testing.assert_allclose( + data["t_avg_multiple"], T_AVG[1] * time, **tol_params + ) + np.testing.assert_allclose( + data["U_avg_magnitude"], np.linalg.norm(U), **tol_params + ) + np.testing.assert_allclose( data["U_avg_magnitude_multiple"], np.linalg.norm(U), **tol_params ) - assert np.allclose(data["U_avg_normal"], U[0], **tol_params) - assert np.allclose(data["U_avg_normal_multiple"], 0.0, **tol_params) - assert np.allclose(data["U_avg_x"], U[0], **tol_params) - assert np.allclose(data["U_avg_x_multiple"], U[0], **tol_params) - assert np.allclose(data["U_avg_y"], U[1], **tol_params) - assert np.allclose(data["U_avg_y_multiple"], U[1], **tol_params) - assert np.allclose(data["U_avg_z"], U[2], **tol_params) - assert np.allclose(data["heat_flux"], time, **tol_params) - assert np.allclose(data["heat_flux_multiple"], 0.0, **tol_params) + np.testing.assert_allclose(data["U_avg_normal"], U[0], **tol_params) + np.testing.assert_allclose(data["U_avg_normal_multiple"], 0.0, **tol_params) + np.testing.assert_allclose(data["U_avg_x"], U[0], **tol_params) + np.testing.assert_allclose(data["U_avg_x_multiple"], U[0], **tol_params) + np.testing.assert_allclose(data["U_avg_y"], U[1], **tol_params) + np.testing.assert_allclose(data["U_avg_y_multiple"], U[1], **tol_params) + np.testing.assert_allclose(data["U_avg_z"], U[2], **tol_params) + np.testing.assert_allclose(data["heat_flux"], time, **tol_params) + np.testing.assert_allclose(data["heat_flux_multiple"], 0.0, **tol_params) diff --git a/test/tests/postprocessors/side_integrated_value/test.py b/test/tests/postprocessors/side_integrated_value/test.py index 2e9a9e58..fa2f22e1 100644 --- a/test/tests/postprocessors/side_integrated_value/test.py +++ b/test/tests/postprocessors/side_integrated_value/test.py @@ -37,29 +37,33 @@ def test_side_integrated_value(self): tol_params = {"atol": 1e-14, "rtol": 1e-12} - assert np.allclose(data["t_avg"], T_AVG[1] * time * AREAS[1], **tol_params) - assert np.allclose( + np.testing.assert_allclose( + data["t_avg"], T_AVG[1] * time * AREAS[1], **tol_params + ) + np.testing.assert_allclose( data["t_avg_multiple"], 2.0 * T_AVG[1] * time * AREAS[1], **tol_params ) - assert np.allclose( + np.testing.assert_allclose( data["U_avg_magnitude"], np.linalg.norm(U) * AREAS[2], **tol_params ) - assert np.allclose( + np.testing.assert_allclose( data["U_avg_magnitude_multiple"], 2.0 * np.linalg.norm(U) * AREAS[2], **tol_params, ) n = -1 # account for outward normal vector on the bottom - assert np.allclose(data["U_avg_normal"], n * U[1] * AREAS[1], **tol_params) - assert np.allclose(data["U_avg_normal_multiple"], 0.0, **tol_params) - assert np.allclose(data["U_avg_x"], U[0] * AREAS[2], **tol_params) - assert np.allclose( + np.testing.assert_allclose( + data["U_avg_normal"], n * U[1] * AREAS[1], **tol_params + ) + np.testing.assert_allclose(data["U_avg_normal_multiple"], 0.0, **tol_params) + np.testing.assert_allclose(data["U_avg_x"], U[0] * AREAS[2], **tol_params) + np.testing.assert_allclose( data["U_avg_x_multiple"], 2.0 * U[0] * AREAS[2], **tol_params ) - assert np.allclose(data["U_avg_y"], U[1] * AREAS[2], **tol_params) - assert np.allclose( + np.testing.assert_allclose(data["U_avg_y"], U[1] * AREAS[2], **tol_params) + np.testing.assert_allclose( data["U_avg_y_multiple"], 2.0 * U[1] * AREAS[1], **tol_params ) - assert np.allclose(data["U_avg_z"], U[2] * AREAS[2], **tol_params) - assert np.allclose(data["heat_flux"], time * AREAS[0], **tol_params) - assert np.allclose(data["heat_flux_multiple"], 0.0, **tol_params) + np.testing.assert_allclose(data["U_avg_z"], U[2] * AREAS[2], **tol_params) + np.testing.assert_allclose(data["heat_flux"], time * AREAS[0], **tol_params) + np.testing.assert_allclose(data["heat_flux_multiple"], 0.0, **tol_params) diff --git a/test/tests/variables/foam_variable/test.py b/test/tests/variables/foam_variable/test.py index 7bd7dbb7..0c2b89c7 100644 --- a/test/tests/variables/foam_variable/test.py +++ b/test/tests/variables/foam_variable/test.py @@ -3,8 +3,10 @@ import unittest import numpy as np - -from read_hippo_data import read_moose_exodus_data, get_exodus_times # pylint: disable=E0401 +from read_hippo_data import ( # pylint: disable=E0401 + get_exodus_times, + read_moose_exodus_data, +) class TestFoamVariableTransfer(unittest.TestCase): @@ -29,9 +31,15 @@ def test_variable_transfer(self): * time ) temp_diff_max = np.argmax(abs(temp - temp_ref)) - assert np.allclose(temp_ref, temp, rtol=1e-7, atol=1e-12), ( - f"Max diff ({time}): {abs(temp - temp_ref).max()} " - f"{temp[temp_diff_max]} {temp_ref[temp_diff_max]}" + np.testing.assert_allclose( + temp_ref, + temp, + rtol=1e-7, + atol=1e-12, + err_msg=( + f"Max diff ({time}): {abs(temp - temp_ref).max()} " + f"{temp[temp_diff_max]} {temp_ref[temp_diff_max]}" + ), ) def test_wall_heat_flux_transfer(self): @@ -61,6 +69,12 @@ def test_wall_heat_flux_transfer(self): assert sum_ == whf.size, f"{sum_} {whf.size}" whf_diff_max = np.argmax(abs(whf - whf_ref)) - assert np.allclose(whf_ref, whf, rtol=1e-7, atol=1e-12), ( - f"Max diff ({time}): {abs(whf - whf_ref)[whf_diff_max]} {whf[whf_diff_max]}" + np.testing.assert_allclose( + whf_ref, + whf, + rtol=1e-7, + atol=1e-12, + err_msg=( + f"Max diff ({time}): {abs(whf - whf_ref)[whf_diff_max]} {whf[whf_diff_max]}" + ), )