diff --git a/src/fvOptions/Make/files b/src/fvOptions/Make/files
index 534e9cd2d7..7ede376606 100644
--- a/src/fvOptions/Make/files
+++ b/src/fvOptions/Make/files
@@ -36,6 +36,7 @@ $(derivedSources)/tabulatedAccelerationSource/tabulatedAccelerationSource.C
$(derivedSources)/tabulatedAccelerationSource/tabulated6DoFAcceleration/tabulated6DoFAcceleration.C
$(derivedSources)/viscousDissipation/viscousDissipation.C
$(derivedSources)/buoyancyTurbSource/buoyancyTurbSource.C
+$(derivedSources)/patchCellsSource/patchCellsSource.C
interRegion = sources/interRegion
$(interRegion)/interRegionHeatTransfer/interRegionHeatTransferModel/interRegionHeatTransferModel.C
diff --git a/src/fvOptions/Make/options b/src/fvOptions/Make/options
index 5da3ef931d..1e51ded765 100644
--- a/src/fvOptions/Make/options
+++ b/src/fvOptions/Make/options
@@ -8,6 +8,7 @@ EXE_INC = \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/specie/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/solidThermo/lnInclude \
+ -I$(LIB_SRC)/thermophysicalModels/reactionThermo/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude
@@ -20,4 +21,5 @@ LIB_LIBS = \
-lsolidThermo \
-lturbulenceModels \
-lincompressibleTurbulenceModels \
- -lcompressibleTurbulenceModels
+ -lcompressibleTurbulenceModels \
+ -lreactionThermophysicalModels
diff --git a/src/fvOptions/sources/derived/patchCellsSource/patchCellsSource.C b/src/fvOptions/sources/derived/patchCellsSource/patchCellsSource.C
new file mode 100644
index 0000000000..7d5b74f643
--- /dev/null
+++ b/src/fvOptions/sources/derived/patchCellsSource/patchCellsSource.C
@@ -0,0 +1,195 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2022 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+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 "patchCellsSource.H"
+#include "fvMatrices.H"
+#include "addToRunTimeSelectionTable.H"
+#include "boundarySourcePatch.H"
+
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace fv
+{
+ defineTypeNameAndDebug(patchCellsSource, 0);
+ addToRunTimeSelectionTable(option, patchCellsSource, dictionary);
+}
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+Foam::fv::patchCellsSource::patchCellsSource
+(
+ const word& sourceName,
+ const word& modelType,
+ const dictionary& dict,
+ const fvMesh& mesh
+)
+:
+ fv::option(sourceName, modelType, dict, mesh),
+ curTimeIndex_(-1),
+ UName_(coeffs_.getOrDefault("U", "none")),
+ hName_(coeffs_.getOrDefault("he", "none")),
+ speciesName_(coeffs_.getOrDefault("species", "none"))
+{
+ label nFields = 0;
+ if (UName_ != "none")
+ {
+ nFields++;
+ }
+ if (hName_ != "none")
+ {
+ nFields++;
+ }
+ if (speciesName_ != "none")
+ {
+ nFields++;
+ }
+
+ if (nFields > 1)
+ {
+ FatalErrorInFunction
+ << "patchCellsSource : "
+ << " cannot be used for more than one field."
+ << exit(FatalError);
+ }
+
+ fieldNames_.resize(1);
+ if (speciesName_ != "none")
+ {
+ fieldNames_[0] = speciesName_;
+ }
+
+ if (UName_ != "none")
+ {
+ fieldNames_[0] = UName_;
+ }
+
+ if (hName_ != "none")
+ {
+ fieldNames_[0] = hName_;
+ }
+
+ fv::option::resetApplied();
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+void Foam::fv::patchCellsSource::addSup
+(
+ const volScalarField& rho,
+ fvMatrix& eqn,
+ const label fieldi
+)
+{
+ if (debug)
+ {
+ Info<< type() << ": applying source to " << eqn.psi().name() << endl;
+ }
+
+ if (curTimeIndex_ == mesh_.time().timeIndex())
+ {
+ return;
+ }
+
+ volScalarField* psiPtr;
+
+ // If source applied to he, we need to loop over T for BC's
+ if (hName_ != "none")
+ {
+ psiPtr = mesh_.getObjectPtr("T");
+ }
+ else
+ {
+ auto* psi =
+ mesh_.getObjectPtr(eqn.psi().name());
+
+ psiPtr = psi;
+ }
+
+ const volScalarField::Boundary& psib = psiPtr->boundaryField();
+
+ volScalarField mDot
+ (
+ IOobject
+ (
+ "mDot",
+ mesh_.time().timeName(),
+ mesh_,
+ IOobject::NO_READ,
+ IOobject::NO_WRITE
+ ),
+ mesh_,
+ dimensionedScalar(eqn.dimensions()/dimVolume, Zero)
+ );
+
+ forAll(psib, patchi)
+ {
+ if (isA(psib[patchi]))
+ {
+ const boundarySourcePatch& pp =
+ refCast(psib[patchi]);
+
+ const labelUList& fc = mesh_.boundary()[patchi].faceCells();
+
+ tmp tsb = pp.patchSource();
+ const scalarField& sb = tsb.cref();
+
+ forAll(fc, facei)
+ {
+ const label celli = fc[facei];
+ mDot[celli] += sb[facei];
+ }
+ }
+ }
+ eqn += mDot;
+
+ curTimeIndex_ = mesh_.time().timeIndex();
+
+ if (debug)
+ {
+ Info<< " Field source rate min/max : "
+ << gMin(mDot) << " / " << gMax(mDot) << endl;
+ }
+}
+
+
+bool Foam::fv::patchCellsSource::read(const dictionary& dict)
+{
+ if (!fv::option::read(dict))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+
+// ************************************************************************* //
diff --git a/src/fvOptions/sources/derived/patchCellsSource/patchCellsSource.H b/src/fvOptions/sources/derived/patchCellsSource/patchCellsSource.H
new file mode 100644
index 0000000000..6c39b97012
--- /dev/null
+++ b/src/fvOptions/sources/derived/patchCellsSource/patchCellsSource.H
@@ -0,0 +1,162 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2022 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+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::fv::patchCellsSource
+
+Group
+ grpFvOptionsSources
+
+Description
+ Source defined by a boundary condition applied to cells next to patches.
+ This fvOption needs to be used with a \c boundarySourcePatch type of
+ boundary condition (e.g. \c speciesSorption and \c enthalpySorption.)
+
+Usage
+ Minimal example by using \c constant/fvOptions:
+ \verbatim
+
+ {
+ // Mandatory entries
+ type patchCellsSource;
+
+ // Optional entries
+ U ;
+ he ;
+ species ;
+
+ // Inherited entries
+ ...
+ }
+ \endverbatim
+
+ where the entries mean:
+ \table
+ Property | Description | Type | Reqd | Deflt
+ type | Type name: patchCellsSource | word | yes | -
+ U | Name of operand velocity field | word | no | none
+ he | Name of operand energy field | word | no | none
+ species | Name of operand species field | word | no | none
+ \endtable
+
+ The inherited entries are elaborated in:
+ - \link cellSetOption.H \endlink
+
+SourceFiles
+ patchCellsSource.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef Foam_fv_patchCellsSource_H
+#define Foam_fv_patchCellsSource_H
+
+#include "fvMesh.H"
+#include "volFields.H"
+#include "cellSetOption.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace fv
+{
+
+/*---------------------------------------------------------------------------*\
+ Class patchCellsSource Declaration
+\*---------------------------------------------------------------------------*/
+
+class patchCellsSource
+:
+ public fv::option
+{
+ // Private Data
+
+ //- Current time index (used for updating)
+ label curTimeIndex_;
+
+ //- Name of operand velocity field
+ word UName_;
+
+ //- Name of operand energy field
+ word hName_;
+
+ //- Name of operand species field
+ word speciesName_;
+
+
+public:
+
+ //- Runtime type information
+ TypeName("patchCellsSource");
+
+
+ // Constructors
+
+ //- Construct from explicit source name and mesh
+ patchCellsSource
+ (
+ const word& sourceName,
+ const word& modelType,
+ const dictionary& dict,
+ const fvMesh& mesh
+ );
+
+ //- No copy construct
+ patchCellsSource(const patchCellsSource&) = delete;
+
+ //- No copy assignment
+ void operator=(const patchCellsSource&) = delete;
+
+
+ //- Destructor
+ virtual ~patchCellsSource() = default;
+
+
+ // Member Functions
+
+ //- Add explicit contribution to compressible enthalpy equation
+ virtual void addSup
+ (
+ const volScalarField& rho,
+ fvMatrix& eqn,
+ const label fieldi
+ );
+
+ //- Read source dictionary
+ virtual bool read(const dictionary& dict);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace fv
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/thermophysicalModels/reactionThermo/Make/files b/src/thermophysicalModels/reactionThermo/Make/files
index e31e2076ff..1778902590 100644
--- a/src/thermophysicalModels/reactionThermo/Make/files
+++ b/src/thermophysicalModels/reactionThermo/Make/files
@@ -18,6 +18,9 @@ rhoReactionThermo/rhoReactionThermos.C
derivedFvPatchFields/fixedUnburntEnthalpy/fixedUnburntEnthalpyFvPatchScalarField.C
derivedFvPatchFields/gradientUnburntEnthalpy/gradientUnburntEnthalpyFvPatchScalarField.C
derivedFvPatchFields/mixedUnburntEnthalpy/mixedUnburntEnthalpyFvPatchScalarField.C
+derivedFvPatchFields/speciesSorption/speciesSorptionFvPatchScalarField.C
+derivedFvPatchFields/enthalpySorption/enthalpySorptionFvPatchScalarField.C
+derivedFvPatchFields/boundarySourcePatch/boundarySourcePatch.C
functionObjects/moleFractions/moleFractionsFunctionObjects.C
diff --git a/src/thermophysicalModels/reactionThermo/Make/options b/src/thermophysicalModels/reactionThermo/Make/options
index 9b2471488b..8982d92338 100644
--- a/src/thermophysicalModels/reactionThermo/Make/options
+++ b/src/thermophysicalModels/reactionThermo/Make/options
@@ -1,5 +1,6 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
+ -I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/transportModels/compressible/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/specie/lnInclude \
@@ -9,6 +10,7 @@ EXE_INC = \
LIB_LIBS = \
-lfiniteVolume \
+ -lmeshTools \
-lcompressibleTransportModels \
-lfluidThermophysicalModels \
-lspecie \
diff --git a/src/thermophysicalModels/reactionThermo/derivedFvPatchFields/boundarySourcePatch/boundarySourcePatch.C b/src/thermophysicalModels/reactionThermo/derivedFvPatchFields/boundarySourcePatch/boundarySourcePatch.C
new file mode 100644
index 0000000000..4188677dd4
--- /dev/null
+++ b/src/thermophysicalModels/reactionThermo/derivedFvPatchFields/boundarySourcePatch/boundarySourcePatch.C
@@ -0,0 +1,38 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2022 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+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 "boundarySourcePatch.H"
+
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
+
+namespace Foam
+{
+ defineTypeNameAndDebug(boundarySourcePatch, 0);
+}
+
+
+// ************************************************************************* //
diff --git a/src/thermophysicalModels/reactionThermo/derivedFvPatchFields/boundarySourcePatch/boundarySourcePatch.H b/src/thermophysicalModels/reactionThermo/derivedFvPatchFields/boundarySourcePatch/boundarySourcePatch.H
new file mode 100644
index 0000000000..79bf4d3837
--- /dev/null
+++ b/src/thermophysicalModels/reactionThermo/derivedFvPatchFields/boundarySourcePatch/boundarySourcePatch.H
@@ -0,0 +1,78 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2022 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+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::boundarySourcePatch
+
+Description
+ Pure virtual class for sources on cells next to patches.
+
+SourceFiles
+ boundarySourcePatch.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef Foam_boundarySourcePatch_H
+#define Foam_boundarySourcePatch_H
+
+#include "scalarField.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+ Class boundarySourcePatch Declaration
+\*---------------------------------------------------------------------------*/
+
+class boundarySourcePatch
+{
+public:
+
+ //- Runtime type information
+ TypeName("boundarySourcePatch");
+
+
+ //- Destructor
+ virtual ~boundarySourcePatch() = default;
+
+
+ // Member Functions
+
+ //- Source applied on cells of the patch
+ virtual tmp patchSource() const = 0;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/thermophysicalModels/reactionThermo/derivedFvPatchFields/enthalpySorption/enthalpySorptionFvPatchScalarField.C b/src/thermophysicalModels/reactionThermo/derivedFvPatchFields/enthalpySorption/enthalpySorptionFvPatchScalarField.C
new file mode 100644
index 0000000000..694dc96d98
--- /dev/null
+++ b/src/thermophysicalModels/reactionThermo/derivedFvPatchFields/enthalpySorption/enthalpySorptionFvPatchScalarField.C
@@ -0,0 +1,350 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2022 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+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 "enthalpySorptionFvPatchScalarField.H"
+#include "addToRunTimeSelectionTable.H"
+#include "fvPatchFieldMapper.H"
+#include "volFields.H"
+#include "rhoReactionThermo.H"
+#include "speciesSorptionFvPatchScalarField.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+const Foam::Enum
+<
+ Foam::enthalpySorptionFvPatchScalarField::enthalpyModelType
+>
+Foam::enthalpySorptionFvPatchScalarField::enthalpyModelTypeNames
+({
+ { enthalpyModelType::estimated, "estimated" },
+ { enthalpyModelType::calculated, "calculated" }
+});
+
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+Foam::enthalpySorptionFvPatchScalarField::enthalpySorptionFvPatchScalarField
+(
+ const fvPatch& p,
+ const DimensionedField& iF
+)
+:
+ zeroGradientFvPatchScalarField(p, iF),
+ enthalpyModel_(enthalpyModelType::estimated),
+ includeHs_(false),
+ enthalpyMassLoadPtr_(nullptr),
+ C_(0),
+ Hvap_(0),
+ speciesName_("none"),
+ pName_("p"),
+ TName_("T"),
+ dhdt_(p.size(), 0)
+{}
+
+
+Foam::enthalpySorptionFvPatchScalarField::enthalpySorptionFvPatchScalarField
+(
+ const fvPatch& p,
+ const DimensionedField& iF,
+ const dictionary& dict
+)
+:
+ zeroGradientFvPatchScalarField(p, iF, dict),
+ enthalpyModel_(enthalpyModelTypeNames.get("enthalpyModel", dict)),
+ includeHs_(dict.getOrDefault("includeHs", true)),
+ enthalpyMassLoadPtr_(nullptr),
+ C_(dict.getCheckOrDefault("C", 0, scalarMinMax::ge(0))),
+ Hvap_(dict.getCheckOrDefault("Hvap", 0, scalarMinMax::ge(0))),
+ speciesName_(dict.get("species")),
+ pName_(dict.getOrDefault("p", "p")),
+ TName_(dict.getOrDefault("T", "T")),
+ dhdt_
+ (
+ dict.found("dhdt")
+ ? scalarField("dhdt", dict, p.size())
+ : scalarField(p.size(), 0)
+ )
+{
+ switch (enthalpyModel_)
+ {
+ case enthalpyModelType::calculated:
+ {
+ enthalpyMassLoadPtr_ =
+ Function1::New("enthalpyTable", dict);
+ break;
+ }
+ case enthalpyModelType::estimated:
+ {
+ break;
+ }
+ }
+
+ if (dict.found("value"))
+ {
+ fvPatchScalarField::operator=
+ (
+ scalarField("value", dict, p.size())
+ );
+ }
+ else
+ {
+ fvPatchField::operator=(Zero);
+ }
+}
+
+
+Foam::enthalpySorptionFvPatchScalarField::enthalpySorptionFvPatchScalarField
+(
+ const enthalpySorptionFvPatchScalarField& ptf,
+ const fvPatch& p,
+ const DimensionedField& iF,
+ const fvPatchFieldMapper& mapper
+)
+:
+ zeroGradientFvPatchScalarField(ptf, p, iF, mapper),
+ enthalpyModel_(ptf.enthalpyModel_),
+ includeHs_(ptf.includeHs_),
+ enthalpyMassLoadPtr_(ptf.enthalpyMassLoadPtr_.clone()),
+ C_(ptf.C_),
+ Hvap_(ptf.Hvap_),
+ speciesName_(ptf.speciesName_),
+ pName_(ptf.pName_),
+ TName_(ptf.TName_),
+ dhdt_(ptf.dhdt_, mapper)
+{}
+
+
+Foam::enthalpySorptionFvPatchScalarField::enthalpySorptionFvPatchScalarField
+(
+ const enthalpySorptionFvPatchScalarField& ptf
+)
+:
+ zeroGradientFvPatchScalarField(ptf),
+ enthalpyModel_(ptf.enthalpyModel_),
+ includeHs_(ptf.includeHs_),
+ enthalpyMassLoadPtr_(ptf.enthalpyMassLoadPtr_.clone()),
+ C_(ptf.C_),
+ Hvap_(ptf.Hvap_),
+ speciesName_(ptf.speciesName_),
+ pName_(ptf.pName_),
+ TName_(ptf.TName_),
+ dhdt_(ptf.dhdt_)
+{}
+
+
+Foam::enthalpySorptionFvPatchScalarField::enthalpySorptionFvPatchScalarField
+(
+ const enthalpySorptionFvPatchScalarField& ptf,
+ const DimensionedField& iF
+)
+:
+ zeroGradientFvPatchScalarField(ptf, iF),
+ enthalpyModel_(ptf.enthalpyModel_),
+ includeHs_(ptf.includeHs_),
+ enthalpyMassLoadPtr_(ptf.enthalpyMassLoadPtr_.clone()),
+ C_(ptf.C_),
+ Hvap_(ptf.Hvap_),
+ speciesName_(ptf.speciesName_),
+ pName_(ptf.pName_),
+ TName_(ptf.TName_),
+ dhdt_(ptf.dhdt_)
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+void Foam::enthalpySorptionFvPatchScalarField::autoMap
+(
+ const fvPatchFieldMapper& m
+)
+{
+ zeroGradientFvPatchScalarField::autoMap(m);
+
+ dhdt_.autoMap(m);
+}
+
+
+void Foam::enthalpySorptionFvPatchScalarField::rmap
+(
+ const fvPatchScalarField& ptf,
+ const labelList& addr
+)
+{
+ zeroGradientFvPatchScalarField::rmap(ptf, addr);
+
+ const auto& tiptf = refCast(ptf);
+
+ dhdt_.rmap(tiptf.dhdt_, addr);
+}
+
+
+Foam::tmp Foam::enthalpySorptionFvPatchScalarField::
+patchSource() const
+{
+ const auto& Yp =
+ refCast
+ (
+ patch().lookupPatchField
+ (
+ speciesName_
+ )
+ );
+
+ // mass rate [kg/sec/m3]
+ tmp tmassb = Yp.patchSource();
+ const scalarField& massb = tmassb();
+
+ // The moles absorbed by the solid
+ // dhdt[J/kg] * kg/sec/m3 = [J/m3/s]
+ scalarField dhdt(dhdt_*massb);
+
+ if (includeHs_)
+ {
+ const fvPatchField& pp =
+ patch().lookupPatchField(pName_);
+
+ const fvPatchField& Tp =
+ patch().lookupPatchField(TName_);
+
+ const auto& thermo = db().lookupObject
+ (
+ basicThermo::dictName
+ );
+
+ const basicSpecieMixture& composition = thermo.composition();
+
+ const label speicesId =
+ thermo.composition().species()[speciesName_];
+
+ scalarField hsp(this->patch().size(), 0);
+
+ forAll(pp, facei)
+ {
+ hsp[facei] = composition.Hs(speicesId, pp[facei], Tp[facei]);
+ }
+
+ dhdt += hsp*massb;
+ }
+
+ if (debug)
+ {
+ Info<< " Patch enthalpy rate min/max [J/m3/sec]: "
+ << gMin(dhdt) << " - " << gMax(dhdt) << endl;
+ }
+
+ return tmp::New(dhdt);
+}
+
+
+void Foam::enthalpySorptionFvPatchScalarField::updateCoeffs()
+{
+ if (updated())
+ {
+ return;
+ }
+
+ const auto& Yp =
+ refCast
+ (
+ patch().lookupPatchField
+ (
+ speciesName_
+ )
+ );
+
+ switch (enthalpyModel_)
+ {
+ case enthalpyModelType::estimated:
+ {
+ dhdt_ = -C_*Hvap_;
+ break;
+ }
+ case enthalpyModelType::calculated:
+ {
+ // mass [mol/kg]
+ tmp tmassb = Yp.mass();
+ const scalarField& massb = tmassb.ref();
+
+ forAll(massb, facei)
+ {
+ const scalar mfacei = massb[facei];
+
+ dhdt_[facei] = enthalpyMassLoadPtr_->value(mfacei);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (debug)
+ {
+ Info<< " Enthalpy change min/max [J/kg]: "
+ << gMin(dhdt_) << " - " << gMax(dhdt_) << endl;
+ }
+
+ zeroGradientFvPatchScalarField::updateCoeffs();
+}
+
+
+void Foam::enthalpySorptionFvPatchScalarField::write(Ostream& os) const
+{
+ fvPatchScalarField::write(os);
+
+ os.writeEntry("enthalpyModel", enthalpyModelTypeNames[enthalpyModel_]);
+
+ if (enthalpyMassLoadPtr_)
+ {
+ enthalpyMassLoadPtr_->writeData(os);
+ }
+
+ os.writeEntry("species", speciesName_);
+
+ os.writeEntryIfDifferent("includeHs", true, includeHs_);
+ os.writeEntryIfDifferent("C", scalar(0), C_);
+ os.writeEntryIfDifferent("Hvap", scalar(0), Hvap_);
+ os.writeEntryIfDifferent("p", "p", pName_);
+ os.writeEntryIfDifferent("T", "T", TName_);
+
+ dhdt_.writeEntry("dhdt", os);
+
+ writeEntry("value", os);
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+ makePatchTypeField
+ (
+ fvPatchScalarField,
+ enthalpySorptionFvPatchScalarField
+ );
+}
+
+// ************************************************************************* //
diff --git a/src/thermophysicalModels/reactionThermo/derivedFvPatchFields/enthalpySorption/enthalpySorptionFvPatchScalarField.H b/src/thermophysicalModels/reactionThermo/derivedFvPatchFields/enthalpySorption/enthalpySorptionFvPatchScalarField.H
new file mode 100644
index 0000000000..f232c79c71
--- /dev/null
+++ b/src/thermophysicalModels/reactionThermo/derivedFvPatchFields/enthalpySorption/enthalpySorptionFvPatchScalarField.H
@@ -0,0 +1,284 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2022 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+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::enthalpySorptionFvPatchScalarField
+
+Group
+ grpGenericBoundaryConditions
+
+Description
+ This is a temperature boundary condition which works
+ in conjunction with the \c speciesSorption condition for species.
+
+ This boundary condition substracts or adds enthalpy associated with the
+ adsorption provided by the \c speciesSorption condition.
+
+ It can handle two enthalpy models:
+
+ 1) Estimate
+ 2) Calculated
+
+ On top of this, the enthalpy associated with the sensible enthalpy
+ corresponding with the species transport can be added using \c includeHs.
+
+Usage
+ Example of the boundary condition specification:
+ \verbatim
+
+ {
+ // Mandatory entries
+ type enthalpySorption;
+ enthalpyModel ;
+ species ;
+
+ // Conditional mandatory entries
+
+ // when enthalpyModel == calculated
+ enthalpyTable >
+
+ // enthalpyTable
+ // {
+ // type table;
+ // values ((0 0)(1 50));
+ // }
+
+ // Optional entries
+ includeHs ;
+ C ;
+ Hvap ;
+ dhdt ;
+ p ;
+ T ;
+ }
+ \endverbatim
+
+ where the entries mean:
+ \table
+ Property | Description | Type | Reqd | Deflt
+ type | Type name: enthalpySorption | word | yes | -
+ enthalpyModel | Adsorption enthalpy model | word | yes | -
+ species | Name of associated species | word | yes | -
+ enthalpyTable | Calculated enthalpy model table | Function1\ | no | -
+ includeHs | Include sensible enthalpy | bool | no | true
+ C | Estimate enthalpy model constant | scalar | no | 0
+ Hvap | Evaporation heat for species | scalar | no | 0
+ p | Name of operand pressure field | word | no | p
+ T | Name of operand temperature field | word | no | T
+ dhdt | Enthalpy change on cells next to patch [J/kg] | scalarField | no | Zero
+ \endtable
+
+ Options for the \c enthalpyModel entry:
+ \verbatim
+ estimated | Enthalpy is estimated
+ calculated | Enthalpy is calculated based on enthalpyTable
+ \endverbatim
+
+ The inherited entries are elaborated in:
+ - \link zeroGradientFvPatchFields.H \endlink
+ - \link Function1.H \endlink
+
+SourceFiles
+ enthalpySorptionFvPatchScalarField.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef Foam_enthalpySorptionFvPatchScalarField_H
+#define Foam_enthalpySorptionFvPatchScalarField_H
+
+#include "boundarySourcePatch.H"
+#include "zeroGradientFvPatchFields.H"
+#include "Function1.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+ Class enthalpySorptionFvPatchScalarField Declaration
+\*---------------------------------------------------------------------------*/
+
+class enthalpySorptionFvPatchScalarField
+:
+ public zeroGradientFvPatchField,
+ public boundarySourcePatch
+{
+ // Private Enumeration
+
+ //- Options for the enthalpy model
+ enum enthalpyModelType : char
+ {
+ estimated,
+ calculated
+ };
+
+ //- Names for enthalpyModelType
+ static const Enum enthalpyModelTypeNames;
+
+
+ // Private Data
+
+ //- Enthalpy model
+ enum enthalpyModelType enthalpyModel_;
+
+ //- Include sensible enthalpy of the species
+ bool includeHs_;
+
+ //- Load enthalpy table for calculated model
+ autoPtr> enthalpyMassLoadPtr_;
+
+ //- Estimated enthalpy model constant
+ scalar C_;
+
+ //- Heat of evaporation of species
+ scalar Hvap_;
+
+ //- Name of operand species field
+ word speciesName_;
+
+ //- Name of operand pressure field
+ word pName_;
+
+ //- Name of operand temperature field
+ word TName_;
+
+ //- Enthalpy change on cells next to patch [J/kg]
+ scalarField dhdt_;
+
+
+public:
+
+ //- Runtime type information
+ TypeName("enthalpySorption");
+
+
+ // Constructors
+
+ //- Construct from patch and internal field
+ enthalpySorptionFvPatchScalarField
+ (
+ const fvPatch&,
+ const DimensionedField&
+ );
+
+ //- Construct from patch, internal field and dictionary
+ enthalpySorptionFvPatchScalarField
+ (
+ const fvPatch&,
+ const DimensionedField&,
+ const dictionary&
+ );
+
+ //- Construct by mapping given
+ //- enthalpySorptionFvPatchScalarField onto a new patch
+ enthalpySorptionFvPatchScalarField
+ (
+ const enthalpySorptionFvPatchScalarField&,
+ const fvPatch&,
+ const DimensionedField&,
+ const fvPatchFieldMapper&
+ );
+
+ //- Construct as copy
+ enthalpySorptionFvPatchScalarField
+ (
+ const enthalpySorptionFvPatchScalarField&
+ );
+
+ //- Construct and return a clone
+ virtual tmp clone() const
+ {
+ return tmp
+ (
+ new enthalpySorptionFvPatchScalarField(*this)
+ );
+ }
+
+ //- Construct as copy setting internal field reference
+ enthalpySorptionFvPatchScalarField
+ (
+ const enthalpySorptionFvPatchScalarField&,
+ const DimensionedField&
+ );
+
+ //- Construct and return a clone setting internal field reference
+ virtual tmp clone
+ (
+ const DimensionedField& iF
+ ) const
+ {
+ return tmp
+ (
+ new enthalpySorptionFvPatchScalarField(*this, iF)
+ );
+ }
+
+
+ // Member Functions
+
+ // Mapping
+
+ //- Map (and resize as needed) from self given a mapping object
+ virtual void autoMap
+ (
+ const fvPatchFieldMapper&
+ );
+
+ //- Reverse map the given fvPatchField onto this fvPatchField
+ virtual void rmap
+ (
+ const fvPatchScalarField&,
+ const labelList&
+ );
+
+
+ // Evaluation
+
+ //- Source of cells next to the patch
+ virtual tmp patchSource() const;
+
+ //- Update the coefficients associated with the patch field
+ virtual void updateCoeffs();
+
+
+ // I-O
+
+ //- Write
+ virtual void write(Ostream&) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/thermophysicalModels/reactionThermo/derivedFvPatchFields/speciesSorption/speciesSorptionFvPatchScalarField.C b/src/thermophysicalModels/reactionThermo/derivedFvPatchFields/speciesSorption/speciesSorptionFvPatchScalarField.C
new file mode 100644
index 0000000000..b64b3f2052
--- /dev/null
+++ b/src/thermophysicalModels/reactionThermo/derivedFvPatchFields/speciesSorption/speciesSorptionFvPatchScalarField.C
@@ -0,0 +1,459 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2022 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+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 "speciesSorptionFvPatchScalarField.H"
+#include "addToRunTimeSelectionTable.H"
+#include "fvPatchFieldMapper.H"
+#include "volFields.H"
+#include "rhoReactionThermo.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+const Foam::Enum
+<
+ Foam::speciesSorptionFvPatchScalarField::equilibriumModelType
+>
+Foam::speciesSorptionFvPatchScalarField::equilibriumModelTypeNames
+({
+ { equilibriumModelType::LANGMUIR, "Langmuir" }
+});
+
+
+const Foam::Enum
+<
+ Foam::speciesSorptionFvPatchScalarField::kineticModelType
+>
+Foam::speciesSorptionFvPatchScalarField::kinematicModelTypeNames
+({
+ { kineticModelType::PseudoFirstOrder, "PseudoFirstOrder" }
+});
+
+
+// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
+
+Foam::tmp
+Foam::speciesSorptionFvPatchScalarField::calcMoleFractions() const
+{
+ auto tMole = tmp::New(patch().size(), 0);
+ scalarField& Mole = tMole.ref();
+
+ if (db().foundObject(basicThermo::dictName))
+ {
+ const auto& thermo = db().lookupObject
+ (
+ basicThermo::dictName
+ );
+
+ const PtrList& Y = thermo.composition().Y();
+
+ const volScalarField W(thermo.W());
+
+ const labelUList& faceCells = patch().faceCells();
+
+ const label speicesId =
+ thermo.composition().species()[this->internalField().name()];
+
+ const dimensionedScalar Wi
+ (
+ dimMass/dimMoles,
+ thermo.composition().W(speicesId)
+ );
+
+ const volScalarField X(W*Y[speicesId]/Wi);
+
+ forAll(faceCells, i)
+ {
+ const label cellId = faceCells[i];
+ Mole[i] = X[cellId];
+ }
+ }
+ else
+ {
+ FatalErrorInFunction
+ << "Thermo type is not 'rhoReactionThermo'. " << nl
+ << "This BC is designed to operate with a rho based thermo."
+ << exit(FatalError);
+ }
+
+ return tMole;
+}
+
+
+Foam::volScalarField&
+Foam::speciesSorptionFvPatchScalarField::field
+(
+ const word& fieldName,
+ const dimensionSet& dim
+) const
+{
+ const fvMesh& mesh = this->internalField().mesh();
+ auto* ptr = mesh.getObjectPtr(fieldName);
+
+ if (!ptr)
+ {
+ ptr = new volScalarField
+ (
+ IOobject
+ (
+ fieldName,
+ mesh.time().timeName(),
+ mesh,
+ IOobject::NO_READ,
+ IOobject::AUTO_WRITE
+ ),
+ mesh,
+ dimensionedScalar(dim, Zero)
+ );
+
+ ptr->store();
+ }
+
+ return *ptr;
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+Foam::speciesSorptionFvPatchScalarField::speciesSorptionFvPatchScalarField
+(
+ const fvPatch& p,
+ const DimensionedField& iF
+)
+:
+ zeroGradientFvPatchScalarField(p, iF),
+ equilibriumModel_(equilibriumModelType::LANGMUIR),
+ kinematicModel_(kineticModelType::PseudoFirstOrder),
+ thicknessPtr_(nullptr),
+ kabs_(1),
+ kl_(0),
+ max_(1),
+ rhoS_(0),
+ pName_("p"),
+ dfldp_(p.size(), 0),
+ mass_(p.size(), 0)
+{}
+
+
+Foam::speciesSorptionFvPatchScalarField::speciesSorptionFvPatchScalarField
+(
+ const fvPatch& p,
+ const DimensionedField& iF,
+ const dictionary& dict
+)
+:
+ zeroGradientFvPatchScalarField(p, iF, dict),
+ equilibriumModel_(equilibriumModelTypeNames.get("equilibriumModel", dict)),
+ kinematicModel_(kinematicModelTypeNames.get("kinematicModel", dict)),
+ thicknessPtr_(PatchFunction1::New(p.patch(), "thickness", dict)),
+ kabs_(dict.getCheck("kabs", scalarMinMax::ge(0))),
+ kl_(dict.getCheck("kl", scalarMinMax::ge(0))),
+ max_(dict.getCheck("max", scalarMinMax::ge(0))),
+ rhoS_(dict.get("rhoS")),
+ pName_(dict.getOrDefault("p", "p")),
+ dfldp_
+ (
+ dict.found("dfldp")
+ ? scalarField("dfldp", dict, p.size())
+ : scalarField(p.size(), 0)
+ ),
+ mass_
+ (
+ dict.found("mass")
+ ? scalarField("mass", dict, p.size())
+ : scalarField(p.size(), 0)
+ )
+{
+ if (dict.found("value"))
+ {
+ fvPatchScalarField::operator=
+ (
+ scalarField("value", dict, p.size())
+ );
+ }
+ else
+ {
+ fvPatchField::operator=(Zero);
+ }
+}
+
+
+Foam::speciesSorptionFvPatchScalarField::speciesSorptionFvPatchScalarField
+(
+ const speciesSorptionFvPatchScalarField& ptf,
+ const fvPatch& p,
+ const DimensionedField& iF,
+ const fvPatchFieldMapper& mapper
+)
+:
+ zeroGradientFvPatchScalarField(ptf, p, iF, mapper),
+ equilibriumModel_(ptf.equilibriumModel_),
+ kinematicModel_(ptf.kinematicModel_),
+ thicknessPtr_(ptf.thicknessPtr_.clone(patch().patch())),
+ kabs_(ptf.kabs_),
+ kl_(ptf.kl_),
+ max_(ptf.max_),
+ rhoS_(ptf.rhoS_),
+ pName_(ptf.pName_),
+ dfldp_(ptf.dfldp_, mapper),
+ mass_(ptf.mass_, mapper)
+{}
+
+
+Foam::speciesSorptionFvPatchScalarField::speciesSorptionFvPatchScalarField
+(
+ const speciesSorptionFvPatchScalarField& ptf
+)
+:
+ zeroGradientFvPatchScalarField(ptf),
+ equilibriumModel_(ptf.equilibriumModel_),
+ kinematicModel_(ptf.kinematicModel_),
+ thicknessPtr_(ptf.thicknessPtr_.clone(patch().patch())),
+ kabs_(ptf.kabs_),
+ kl_(ptf.kl_),
+ max_(ptf.max_),
+ rhoS_(ptf.rhoS_),
+ pName_(ptf.pName_),
+ dfldp_(ptf.dfldp_),
+ mass_(ptf.mass_)
+{}
+
+
+Foam::speciesSorptionFvPatchScalarField::speciesSorptionFvPatchScalarField
+(
+ const speciesSorptionFvPatchScalarField& ptf,
+ const DimensionedField& iF
+)
+:
+ zeroGradientFvPatchScalarField(ptf, iF),
+ equilibriumModel_(ptf.equilibriumModel_),
+ kinematicModel_(ptf.kinematicModel_),
+ thicknessPtr_(ptf.thicknessPtr_.clone(patch().patch())),
+ kabs_(ptf.kabs_),
+ kl_(ptf.kl_),
+ max_(ptf.max_),
+ rhoS_(ptf.rhoS_),
+ pName_(ptf.pName_),
+ dfldp_(ptf.dfldp_),
+ mass_(ptf.mass_)
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+void Foam::speciesSorptionFvPatchScalarField::autoMap
+(
+ const fvPatchFieldMapper& m
+)
+{
+ zeroGradientFvPatchScalarField::autoMap(m);
+
+ dfldp_.autoMap(m);
+ mass_.autoMap(m);
+
+ if (thicknessPtr_)
+ {
+ thicknessPtr_->autoMap(m);
+ }
+}
+
+
+void Foam::speciesSorptionFvPatchScalarField::rmap
+(
+ const fvPatchScalarField& ptf,
+ const labelList& addr
+)
+{
+ zeroGradientFvPatchScalarField::rmap(ptf, addr);
+
+ const auto& tiptf = refCast(ptf);
+
+ dfldp_.rmap(tiptf.dfldp_, addr);
+ mass_.rmap(tiptf.mass_, addr);
+
+ if (thicknessPtr_)
+ {
+ thicknessPtr_->rmap(tiptf.thicknessPtr_(), addr);
+ }
+}
+
+
+Foam::tmp Foam::speciesSorptionFvPatchScalarField::
+patchSource() const
+{
+ const auto& thermo = db().lookupObject
+ (
+ basicThermo::dictName
+ );
+
+ const label speicesId =
+ thermo.composition().species()[this->internalField().name()];
+
+ const scalar Wi(thermo.composition().W(speicesId));
+
+ const scalar t = db().time().timeOutputValue();
+
+ const scalarField h(thicknessPtr_->value(t));
+
+ const scalarField AbyV(this->patch().magSf());
+
+ // Solid mass [kg]
+ const scalarField mass(h*AbyV*rhoS_);
+
+ scalarField Vol(this->patch().size());
+
+ forAll(AbyV, facei)
+ {
+ const label faceCelli = this->patch().faceCells()[facei];
+ Vol[facei] = this->internalField().mesh().V()[faceCelli];
+ }
+
+ // The moles absorbed by the solid
+ // dfldp[mol/kg/sec]* mass[kg]* Wi[kg/mol] / Vol[m3]= [kg/sec/m3]
+ const scalarField dfldp(-dfldp_*mass*Wi*1e-3/Vol);
+
+ if (debug)
+ {
+ Info<< " Patch mass rate min/max [kg/m3/sec]: "
+ << gMin(dfldp) << " - " << gMax(dfldp) << endl;
+ }
+
+ return tmp::New(dfldp);
+}
+
+
+Foam::tmp Foam::speciesSorptionFvPatchScalarField::
+mass() const
+{
+ return tmp::New(mass_);
+}
+
+
+void Foam::speciesSorptionFvPatchScalarField::updateCoeffs()
+{
+ if (updated())
+ {
+ return;
+ }
+
+ // equilibrium in mol/kg
+ scalarField cEq(patch().size(), 0);
+
+ switch (equilibriumModel_)
+ {
+ case equilibriumModelType::LANGMUIR:
+ {
+ // mole fraction
+ tmp tco = calcMoleFractions();
+
+ const fvPatchField& pp =
+ patch().lookupPatchField(pName_);
+
+ cEq = max_*(kl_*tco()*pp/(1 + kl_*tco()*pp));
+ break;
+ }
+ default:
+ break;
+ }
+
+ // source [mol/kg/sec]
+ dfldp_ = Zero;
+
+ switch (kinematicModel_)
+ {
+ case kineticModelType::PseudoFirstOrder:
+ {
+ dfldp_ = kabs_*(cEq - mass_);
+ }
+ default:
+ break;
+ }
+
+ // mass [mol/kg]
+ const scalar dt = db().time().deltaTValue();
+ mass_ += dfldp_*dt;
+ mass_ = max(mass_, scalar(0));
+
+ scalarField& pMass =
+ field
+ (
+ "absorbedMass" + this->internalField().name(),
+ dimensionSet(dimMoles/dimMass)
+ ).boundaryFieldRef()[patch().index()];
+
+ pMass = mass_;
+
+ if (debug)
+ {
+ Info<< " Absorption rate min/max [mol/kg/sec]: "
+ << gMin(dfldp_) << " - " << gMax(dfldp_) << endl;
+ }
+
+ zeroGradientFvPatchScalarField::updateCoeffs();
+}
+
+
+void Foam::speciesSorptionFvPatchScalarField::write(Ostream& os) const
+{
+ fvPatchScalarField::write(os);
+
+ os.writeEntry
+ (
+ "equilibriumModel", equilibriumModelTypeNames[equilibriumModel_]
+ );
+ os.writeEntry
+ (
+ "kinematicModel", kinematicModelTypeNames[kinematicModel_]
+ );
+ if (thicknessPtr_)
+ {
+ thicknessPtr_->writeData(os);
+ }
+ os.writeEntry("kabs", kabs_);
+ os.writeEntry("kl", kl_);
+ os.writeEntry("max", max_);
+ os.writeEntry("rhoS", rhoS_);
+
+ dfldp_.writeEntry("dfldp", os);
+ mass_.writeEntry("mass", os);
+ os.writeEntryIfDifferent("p", "p", pName_);
+
+ writeEntry("value", os);
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+ makePatchTypeField
+ (
+ fvPatchScalarField,
+ speciesSorptionFvPatchScalarField
+ );
+}
+
+// ************************************************************************* //
diff --git a/src/thermophysicalModels/reactionThermo/derivedFvPatchFields/speciesSorption/speciesSorptionFvPatchScalarField.H b/src/thermophysicalModels/reactionThermo/derivedFvPatchFields/speciesSorption/speciesSorptionFvPatchScalarField.H
new file mode 100644
index 0000000000..140492c752
--- /dev/null
+++ b/src/thermophysicalModels/reactionThermo/derivedFvPatchFields/speciesSorption/speciesSorptionFvPatchScalarField.H
@@ -0,0 +1,322 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2022 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+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::speciesSorptionFvPatchScalarField
+
+Group
+ grpGenericBoundaryConditions
+
+Description
+ This boundary condition provides a first-order zero-gradient
+ condition for a given scalar field to model time-dependent
+ adsorption-desorption processes.
+
+ \f[
+ \frac{d c}{d t} = k_{ads} (c_{eq} - c_{abs})
+ \f]
+
+ where
+ \vartable
+ c_{eq} | Equilibrium concentration
+ c_{abs} | Absorbed at wall
+ k_{ads} | Adsorption rate constant [1/s]
+ \endvartable
+
+ \f[
+ c_{eq} = c_{max} \frac{k_l \, c_{int}}{1 + k_l \, c_{int}}
+ \f]
+
+ where
+ \vartable
+ c_{max} | Maximum concentration
+ k_l | Langmuir constant
+ c_{int} | Local cell value concentration
+ \endvartable
+
+Usage
+ Example of the boundary condition specification:
+ \verbatim
+
+ {
+ // Mandatory entries
+ type speciesSorption;
+ equilibriumModel ;
+ kinematicModel ;
+ kabs ;
+ kl ;
+ max ;
+ thickness >;
+ rhoS ;
+
+ // Optional entries
+ dfldp ;
+ mass ;
+ pName ;
+
+ // Inherited entries
+ ...
+ }
+ \endverbatim
+
+ where the entries mean:
+ \table
+ Property | Description | Type | Reqd | Deflt
+ type | Type name: speciesSorption | word | yes | -
+ equilibriumModel | Equilibrium model | word | yes | -
+ kinematicModel | Kinematic model | word | yes | -
+ kabs | Adsorption rate constant [1/s] | scalar | yes | -
+ kl | Langmuir constant [1/Pa] | scalar | yes | -
+ max | Maximum concentation at wall [mol/kg] | scalar | yes | -
+ thickness| Solid thickness along the patch | PatchFunction1\ | yes | -
+ rhoS | Solid density | scalar | yes | -
+ dfldp | Source on cells next to patch | scalarField | no | Zero
+ mass | Absorbed mass per kg of absorbent [mol/kg] | scalarField | no | Zero
+ pName | Name of operand pressure field | word | no | p
+ \endtable
+
+ Options for the \c equilibriumModel entry:
+ \verbatim
+ Langmuir | Langmuir model
+ \endverbatim
+
+ Options for the \c kinematicModel entry:
+ \verbatim
+ PseudoFirstOrder | Pseudo first-order model
+ \endverbatim
+
+ The inherited entries are elaborated in:
+ - \link zeroGradientFvPatchFields.H \endlink
+ - \link PatchFunction1.H \endlink
+
+SourceFiles
+ speciesSorptionFvPatchScalarField.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef Foam_speciesSorptionFvPatchScalarField_H
+#define Foam_speciesSorptionFvPatchScalarField_H
+
+#include "boundarySourcePatch.H"
+#include "zeroGradientFvPatchFields.H"
+#include "PatchFunction1.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+ Class speciesSorptionFvPatchScalarField Declaration
+\*---------------------------------------------------------------------------*/
+
+class speciesSorptionFvPatchScalarField
+:
+ public zeroGradientFvPatchField,
+ public boundarySourcePatch
+{
+public:
+
+ // Public Enumeration
+
+ //- Options for the equilibrum model
+ enum equilibriumModelType : char
+ {
+ LANGMUIR = 0
+ };
+
+ //- Options for the kinematic model
+ enum kineticModelType : char
+ {
+ PseudoFirstOrder = 0
+ };
+
+ //- Names for equilibriumModelType
+ static const Enum equilibriumModelTypeNames;
+
+ //- Names for kineticModelType
+ static const Enum kinematicModelTypeNames;
+
+
+private:
+
+ // Private Data
+
+ //- Equilibrium model
+ enum equilibriumModelType equilibriumModel_;
+
+ //- Kinematic model
+ enum kineticModelType kinematicModel_;
+
+ //- Solid thickness along the patch
+ autoPtr> thicknessPtr_;
+
+ //- Adsorption rate constant [1/sec]
+ scalar kabs_;
+
+ //- Langmuir adsorption constant [1/Pa]
+ scalar kl_;
+
+ //- Maximum density on patch [mol/kg]
+ scalar max_;
+
+ //- Solid density
+ scalar rhoS_;
+
+ //- Name of operand pressure field
+ word pName_;
+
+ //- Source on cells next to patch [mol/kg/sec]
+ scalarField dfldp_;
+
+ //- Absorbed mass per kg of absorbent [mol/kg]
+ scalarField mass_;
+
+
+ // Private Member Functions
+
+ //- Calculate the mole fraction fields
+ tmp calcMoleFractions() const;
+
+ //- Lookup (or create) field for output
+ volScalarField& field(const word&, const dimensionSet&) const;
+
+
+public:
+
+ //- Runtime type information
+ TypeName("speciesSorption");
+
+
+ // Constructors
+
+ //- Construct from patch and internal field
+ speciesSorptionFvPatchScalarField
+ (
+ const fvPatch&,
+ const DimensionedField&
+ );
+
+ //- Construct from patch, internal field and dictionary
+ speciesSorptionFvPatchScalarField
+ (
+ const fvPatch&,
+ const DimensionedField&,
+ const dictionary&
+ );
+
+ //- Construct by mapping given
+ //- speciesSorptionFvPatchScalarField onto a new patch
+ speciesSorptionFvPatchScalarField
+ (
+ const speciesSorptionFvPatchScalarField&,
+ const fvPatch&,
+ const DimensionedField&,
+ const fvPatchFieldMapper&
+ );
+
+ //- Construct as copy
+ speciesSorptionFvPatchScalarField
+ (
+ const speciesSorptionFvPatchScalarField&
+ );
+
+ //- Construct and return a clone
+ virtual tmp clone() const
+ {
+ return tmp
+ (
+ new speciesSorptionFvPatchScalarField(*this)
+ );
+ }
+
+ //- Construct as copy setting internal field reference
+ speciesSorptionFvPatchScalarField
+ (
+ const speciesSorptionFvPatchScalarField&,
+ const DimensionedField&
+ );
+
+ //- Construct and return a clone setting internal field reference
+ virtual tmp clone
+ (
+ const DimensionedField& iF
+ ) const
+ {
+ return tmp
+ (
+ new speciesSorptionFvPatchScalarField(*this, iF)
+ );
+ }
+
+
+ // Member Functions
+
+ // Mapping
+
+ //- Map (and resize as needed) from self given a mapping object
+ virtual void autoMap
+ (
+ const fvPatchFieldMapper&
+ );
+
+ //- Reverse map the given fvPatchField onto this fvPatchField
+ virtual void rmap
+ (
+ const fvPatchScalarField&,
+ const labelList&
+ );
+
+
+ // Evaluation
+
+ //- Source of cells next to the patch
+ virtual tmp patchSource() const;
+
+ //- Access to mass
+ tmp mass() const;
+
+ //- Update the coefficients associated with the patch field
+ virtual void updateCoeffs();
+
+
+ // I-O
+
+ //- Write
+ virtual void write(Ostream&) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/CH4 b/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/CH4
new file mode 100644
index 0000000000..5b70d8312c
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/CH4
@@ -0,0 +1,51 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| ========= | |
+| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
+| \\ / O peration | Version: v2106 |
+| \\ / A nd | Website: www.openfoam.com |
+| \\/ M anipulation | |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+ version 2.0;
+ format ascii;
+ class volScalarField;
+ object CH4;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions [0 0 0 0 0 0 0];
+
+internalField uniform 0;
+
+boundaryField
+{
+ "(outlet|sides)"
+ {
+ type inletOutlet;
+ inletValue $internalField;
+ value $internalField;
+ }
+
+ base
+ {
+ type speciesSorption;
+ equilibriumModel Langmuir;
+ kinematicModel PseudoFirstOrder;
+ kabs 10; // [1/sec]
+ kl 0.01; //[1/mol]
+ max 0.1; // [mol/Kg]
+ thickness uniform 1e-3;
+ rhoS 2000;
+ value $internalField;
+ }
+
+ inlet
+ {
+ type fixedValue;
+ value uniform 1.0;
+ }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/N2 b/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/N2
new file mode 100644
index 0000000000..a504cfaaca
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/N2
@@ -0,0 +1,43 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| ========= | |
+| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
+| \\ / O peration | Version: v2106 |
+| \\ / A nd | Website: www.openfoam.com |
+| \\/ M anipulation | |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+ version 2.0;
+ format ascii;
+ class volScalarField;
+ object N2;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions [0 0 0 0 0 0 0];
+
+internalField uniform 0.76699;
+
+boundaryField
+{
+ "(outlet|sides)"
+ {
+ type calculated;
+ value $internalField;
+ }
+
+ base
+ {
+ type calculated;
+ value $internalField;
+ }
+
+ inlet
+ {
+ type calculated;
+ value uniform 0;
+ }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/O2 b/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/O2
new file mode 100644
index 0000000000..1d71259408
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/O2
@@ -0,0 +1,43 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| ========= | |
+| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
+| \\ / O peration | Version: v2106 |
+| \\ / A nd | Website: www.openfoam.com |
+| \\/ M anipulation | |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+ version 2.0;
+ format ascii;
+ class volScalarField;
+ object O2;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions [0 0 0 0 0 0 0];
+
+internalField uniform 0.23301;
+
+boundaryField
+{
+ "(outlet|sides)"
+ {
+ type inletOutlet;
+ inletValue $internalField;
+ value $internalField;
+ }
+
+ base
+ {
+ type zeroGradient;
+ }
+
+ inlet
+ {
+ type fixedValue;
+ value uniform 0;
+ }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/T b/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/T
new file mode 100644
index 0000000000..b7291aa2f5
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/T
@@ -0,0 +1,60 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| ========= | |
+| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
+| \\ / O peration | Version: v2106 |
+| \\ / A nd | Website: www.openfoam.com |
+| \\/ M anipulation | |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+ version 2.0;
+ format ascii;
+ class volScalarField;
+ object T;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions [0 0 0 1 0 0 0];
+
+internalField uniform 300;
+
+boundaryField
+{
+ "(outlet|sides)"
+ {
+ type inletOutlet;
+ inletValue $internalField;
+ value $internalField;
+ }
+
+ base
+ {
+// type zeroGradient;
+
+ type enthalpySorption;
+ enthalpyModel calculated;
+ enthalpyTable
+ {
+ type table;
+ values
+ (
+ (0 0)
+ (1e-2 1e4)
+ (4e-2 2e4)
+ );
+ }
+ species CH4;
+ includeHs true;
+ Hvap 1e6;
+ value $internalField;
+ }
+
+ inlet
+ {
+ type fixedValue;
+ value uniform 300;
+ }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/U b/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/U
new file mode 100644
index 0000000000..e30eae8ffb
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/U
@@ -0,0 +1,43 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| ========= | |
+| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
+| \\ / O peration | Version: v2106 |
+| \\ / A nd | Website: www.openfoam.com |
+| \\/ M anipulation | |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+ version 2.0;
+ format ascii;
+ class volVectorField;
+ object U;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions [0 1 -1 0 0 0 0];
+
+internalField uniform (0 0 0);
+
+boundaryField
+{
+ "(outlet|sides)"
+ {
+ type pressureInletOutletVelocity;
+ value uniform (0 0 0);
+ }
+
+ base
+ {
+ type fixedValue;
+ value uniform (0 0.01 0);
+ }
+
+ inlet
+ {
+ type fixedValue;
+ value uniform (0 0.01 0);
+ }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/Ydefault b/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/Ydefault
new file mode 100644
index 0000000000..78820becc3
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/Ydefault
@@ -0,0 +1,43 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| ========= | |
+| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
+| \\ / O peration | Version: v2106 |
+| \\ / A nd | Website: www.openfoam.com |
+| \\/ M anipulation | |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+ version 2.0;
+ format ascii;
+ class volScalarField;
+ object Ydefault;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions [0 0 0 0 0 0 0];
+
+internalField uniform 0;
+
+boundaryField
+{
+ "(outlet|sides)"
+ {
+ type inletOutlet;
+ inletValue $internalField;
+ value $internalField;
+ }
+
+ base
+ {
+ type zeroGradient;
+ }
+
+ inlet
+ {
+ type fixedValue;
+ value uniform 0;
+ }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/alphat b/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/alphat
new file mode 100644
index 0000000000..78c5dc00fd
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/alphat
@@ -0,0 +1,40 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| ========= | |
+| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
+| \\ / O peration | Version: v2106 |
+| \\ / A nd | Website: www.openfoam.com |
+| \\/ M anipulation | |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+ version 2.0;
+ format ascii;
+ class volScalarField;
+ object alphat;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions [1 -1 -1 0 0 0 0];
+
+internalField uniform 0;
+
+boundaryField
+{
+ "(outlet|sides)"
+ {
+ type zeroGradient;
+ }
+
+ base
+ {
+ type zeroGradient;
+ }
+
+ inlet
+ {
+ type zeroGradient;
+ }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/k b/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/k
new file mode 100644
index 0000000000..aa8b891e24
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/k
@@ -0,0 +1,43 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| ========= | |
+| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
+| \\ / O peration | Version: v2106 |
+| \\ / A nd | Website: www.openfoam.com |
+| \\/ M anipulation | |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+ version 2.0;
+ format ascii;
+ class volScalarField;
+ object k;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions [0 2 -2 0 0 0 0];
+
+internalField uniform 1e-4;
+
+boundaryField
+{
+ "(outlet|sides)"
+ {
+ type inletOutlet;
+ inletValue $internalField;
+ value $internalField;
+ }
+
+ base
+ {
+ type zeroGradient;
+ }
+
+ inlet
+ {
+ type fixedValue;
+ value $internalField;
+ }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/nut b/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/nut
new file mode 100644
index 0000000000..30cf622e62
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/nut
@@ -0,0 +1,40 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| ========= | |
+| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
+| \\ / O peration | Version: v2106 |
+| \\ / A nd | Website: www.openfoam.com |
+| \\/ M anipulation | |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+ version 2.0;
+ format ascii;
+ class volScalarField;
+ object nut;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions [0 2 -1 0 0 0 0];
+
+internalField uniform 0;
+
+boundaryField
+{
+ "(outlet|sides)"
+ {
+ type zeroGradient;
+ }
+
+ base
+ {
+ type zeroGradient;
+ }
+
+ inlet
+ {
+ type zeroGradient;
+ }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/p b/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/p
new file mode 100644
index 0000000000..803c58ab46
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/p
@@ -0,0 +1,44 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| ========= | |
+| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
+| \\ / O peration | Version: v2106 |
+| \\ / A nd | Website: www.openfoam.com |
+| \\/ M anipulation | |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+ version 2.0;
+ format ascii;
+ class volScalarField;
+ object p;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions [1 -1 -2 0 0 0 0];
+
+internalField uniform 101325;
+
+boundaryField
+{
+ "(outlet|sides)"
+ {
+ type totalPressure;
+ p0 $internalField;
+ value $internalField;
+ }
+
+ base
+ {
+ type fixedFluxPressure;
+ value $internalField;
+ }
+
+ inlet
+ {
+ type fixedFluxPressure;
+ value $internalField;
+ }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/p_rgh b/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/p_rgh
new file mode 100644
index 0000000000..d9eff58f7b
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/0.orig/p_rgh
@@ -0,0 +1,45 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| ========= | |
+| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
+| \\ / O peration | Version: v2106 |
+| \\ / A nd | Website: www.openfoam.com |
+| \\/ M anipulation | |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+ version 2.0;
+ format ascii;
+ class volScalarField;
+ object p_rgh;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions [1 -1 -2 0 0 0 0];
+
+internalField uniform 0;
+
+boundaryField
+{
+ "(outlet|sides)"
+ {
+ type prghTotalHydrostaticPressure;
+ p0 $internalField;
+ gamma 1;
+ value $internalField;
+ }
+
+ base
+ {
+ type fixedFluxPressure;
+ value $internalField;
+ }
+
+ inlet
+ {
+ type fixedFluxPressure;
+ value $internalField;
+ }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/Allclean b/tutorials/combustion/rhoReactingFoam/groundAbsorption/Allclean
new file mode 100755
index 0000000000..95f16ccfd2
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/Allclean
@@ -0,0 +1,10 @@
+#!/bin/sh
+cd "${0%/*}" || exit # Run from this directory
+. ${WM_PROJECT_DIR:?}/bin/tools/CleanFunctions # Tutorial clean functions
+#------------------------------------------------------------------------------
+
+cleanCase0
+
+rm -Rf oldProcessors
+
+#------------------------------------------------------------------------------
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/Allrun b/tutorials/combustion/rhoReactingFoam/groundAbsorption/Allrun
new file mode 100755
index 0000000000..14976575b2
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/Allrun
@@ -0,0 +1,35 @@
+#!/bin/sh
+cd "${0%/*}" || exit # Run from this directory
+. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions # Tutorial run functions
+#------------------------------------------------------------------------------
+
+restore0Dir
+
+runApplication blockMesh
+
+runApplication topoSet
+
+runApplication createPatch -overwrite
+
+runApplication decomposePar -force
+
+runParallel $(getApplication)
+
+runApplication reconstructPar
+
+
+latestTime=$(foamListTimes -latestTime)
+
+mv -f "$latestTime" "$latestTime".bak
+
+mkdir oldProcessors
+
+mv -f processor* oldProcessors
+
+runParallel -s "decompose" redistributePar -decompose -latestTime
+
+runParallel -s "restart" $(getApplication)
+
+runParallel -s "reconstruct" redistributePar -reconstruct -latestTime
+
+#------------------------------------------------------------------------------
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/constant/chemistryProperties b/tutorials/combustion/rhoReactingFoam/groundAbsorption/constant/chemistryProperties
new file mode 100644
index 0000000000..b56ed38d71
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/constant/chemistryProperties
@@ -0,0 +1,27 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| ========= | |
+| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
+| \\ / O peration | Version: v2106 |
+| \\ / A nd | Website: www.openfoam.com |
+| \\/ M anipulation | |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+ version 2.0;
+ format ascii;
+ class dictionary;
+ object chemistryProperties;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+chemistryType
+{
+ solver noChemistrySolver;
+}
+
+chemistry off;
+
+initialChemicalTimeStep 1e-07;
+
+
+// ************************************************************************* //
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/constant/combustionProperties b/tutorials/combustion/rhoReactingFoam/groundAbsorption/constant/combustionProperties
new file mode 100644
index 0000000000..e901e39609
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/constant/combustionProperties
@@ -0,0 +1,29 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| ========= | |
+| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
+| \\ / O peration | Version: v2106 |
+| \\ / A nd | Website: www.openfoam.com |
+| \\/ M anipulation | |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+ version 2.0;
+ format ascii;
+ class dictionary;
+ object combustionProperties;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+combustionModel laminar;
+
+EDMCoeffs
+{
+ semiImplicit no;
+ Cd 1;
+ CEDC 1;
+}
+
+active off;
+
+
+// ************************************************************************* //
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/constant/fvOptions b/tutorials/combustion/rhoReactingFoam/groundAbsorption/constant/fvOptions
new file mode 100644
index 0000000000..ee5e0378b0
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/constant/fvOptions
@@ -0,0 +1,32 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| ========= | |
+| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
+| \\ / O peration | Version: v2106 |
+| \\ / A nd | Website: www.openfoam.com |
+| \\/ M anipulation | |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+ version 2.0;
+ format ascii;
+ class dictionary;
+ object fvOptions;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+patchCellsMassSource
+{
+ type patchCellsSource;
+ species CH4;
+ active true;
+}
+
+patchCellsEnthalpySource
+{
+ type patchCellsSource;
+ he h;
+ active true;
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/constant/g b/tutorials/combustion/rhoReactingFoam/groundAbsorption/constant/g
new file mode 100644
index 0000000000..c08dfd97b4
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/constant/g
@@ -0,0 +1,21 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| ========= | |
+| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
+| \\ / O peration | Version: v2106 |
+| \\ / A nd | Website: www.openfoam.com |
+| \\/ M anipulation | |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+ version 2.0;
+ format ascii;
+ class uniformDimensionedVectorField;
+ object g;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions [0 1 -2 0 0 0 0];
+value (0 -9.8 0);
+
+
+// ************************************************************************* //
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/constant/reactions b/tutorials/combustion/rhoReactingFoam/groundAbsorption/constant/reactions
new file mode 100644
index 0000000000..ec91b149f2
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/constant/reactions
@@ -0,0 +1,12 @@
+species
+(
+ O2
+ H2O
+ CH4
+ CO2
+ N2
+);
+
+reactions
+{
+}
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/constant/surfaceFilmProperties b/tutorials/combustion/rhoReactingFoam/groundAbsorption/constant/surfaceFilmProperties
new file mode 100644
index 0000000000..322a327a2f
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/constant/surfaceFilmProperties
@@ -0,0 +1,24 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| ========= | |
+| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
+| \\ / O peration | Version: v2106 |
+| \\ / A nd | Website: www.openfoam.com |
+| \\/ M anipulation | |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+ version 2.0;
+ format ascii;
+ class dictionary;
+ object surfaceFilmProperties;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+surfaceFilmModel none;
+
+region none;
+
+active false;
+
+
+// ************************************************************************* //
\ No newline at end of file
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/constant/thermo.compressibleGas b/tutorials/combustion/rhoReactingFoam/groundAbsorption/constant/thermo.compressibleGas
new file mode 100644
index 0000000000..3da131e5c2
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/constant/thermo.compressibleGas
@@ -0,0 +1,144 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| ========= | |
+| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
+| \\ / O peration | Version: v2106 |
+| \\ / A nd | Website: www.openfoam.com |
+| \\/ M anipulation | |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+ version 2.0;
+ format ascii;
+ class dictionary;
+ object thermo.compressibleGas;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+O2
+{
+ specie
+ {
+ molWeight 31.9988;
+ }
+ thermodynamics
+ {
+ Tlow 200;
+ Thigh 5000;
+ Tcommon 1000;
+ highCpCoeffs ( 3.69758 0.00061352 -1.25884e-07 1.77528e-11 -1.13644e-15 -1233.93 3.18917 );
+ lowCpCoeffs ( 3.21294 0.00112749 -5.75615e-07 1.31388e-09 -8.76855e-13 -1005.25 6.03474 );
+ }
+ transport
+ {
+ As 1.67212e-06;
+ Ts 170.672;
+ }
+}
+
+H2O
+{
+ specie
+ {
+ molWeight 18.0153;
+ }
+ thermodynamics
+ {
+ Tlow 200;
+ Thigh 5000;
+ Tcommon 1000;
+ highCpCoeffs ( 2.67215 0.00305629 -8.73026e-07 1.201e-10 -6.39162e-15 -29899.2 6.86282 );
+ lowCpCoeffs ( 3.38684 0.00347498 -6.3547e-06 6.96858e-09 -2.50659e-12 -30208.1 2.59023 );
+ }
+ transport
+ {
+ As 1.67212e-06;
+ Ts 170.672;
+ }
+}
+
+CH4
+{
+ specie
+ {
+ molWeight 16.0428;
+ }
+ thermodynamics
+ {
+ Tlow 200;
+ Thigh 6000;
+ Tcommon 1000;
+ highCpCoeffs ( 1.63543 0.0100844 -3.36924e-06 5.34973e-10 -3.15528e-14 -10005.6 9.9937 );
+ lowCpCoeffs ( 5.14988 -0.013671 4.91801e-05 -4.84744e-08 1.66694e-11 -10246.6 -4.64132 );
+ }
+ transport
+ {
+ As 1.67212e-06;
+ Ts 170.672;
+ }
+}
+
+CO2
+{
+ specie
+ {
+ molWeight 44.01;
+ }
+ thermodynamics
+ {
+ Tlow 200;
+ Thigh 5000;
+ Tcommon 1000;
+ highCpCoeffs ( 4.45362 0.00314017 -1.27841e-06 2.394e-10 -1.66903e-14 -48967 -0.955396 );
+ lowCpCoeffs ( 2.27572 0.00992207 -1.04091e-05 6.86669e-09 -2.11728e-12 -48373.1 10.1885 );
+ }
+ transport
+ {
+ As 1.67212e-06;
+ Ts 170.672;
+ }
+}
+
+N2
+{
+ specie
+ {
+ molWeight 28.0134;
+ }
+ thermodynamics
+ {
+ Tlow 200;
+ Thigh 5000;
+ Tcommon 1000;
+ highCpCoeffs ( 2.92664 0.00148798 -5.68476e-07 1.0097e-10 -6.75335e-15 -922.798 5.98053 );
+ lowCpCoeffs ( 3.29868 0.00140824 -3.96322e-06 5.64152e-09 -2.44486e-12 -1020.9 3.95037 );
+ }
+ transport
+ {
+ As 1.67212e-06;
+ Ts 170.672;
+ }
+}
+
+CO
+{
+ specie
+ {
+ molWeight 28.0106;
+ }
+ thermodynamics
+ {
+ Tlow 200;
+ Thigh 6000;
+ Tcommon 1000;
+ highCpCoeffs ( 3.04849 0.00135173 -4.85794e-07 7.88536e-11 -4.69807e-15 -14266.1 6.0171 );
+ lowCpCoeffs ( 3.57953 -0.000610354 1.01681e-06 9.07006e-10 -9.04424e-13 -14344.1 3.50841 );
+ }
+ transport
+ {
+ As 1.67212e-06;
+ Ts 170.672;
+ }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/constant/thermophysicalProperties b/tutorials/combustion/rhoReactingFoam/groundAbsorption/constant/thermophysicalProperties
new file mode 100644
index 0000000000..52bb717df9
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/constant/thermophysicalProperties
@@ -0,0 +1,39 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| ========= | |
+| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
+| \\ / O peration | Version: v2106 |
+| \\ / A nd | Website: www.openfoam.com |
+| \\/ M anipulation | |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+ version 2.0;
+ format ascii;
+ class dictionary;
+ object thermophysicalProperties;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+thermoType
+{
+ type heRhoThermo;
+ mixture reactingMixture;
+ transport sutherland;
+ thermo janaf;
+ energy sensibleEnthalpy;
+ equationOfState perfectGas;
+ specie specie;
+}
+
+inertSpecie N2;
+
+fuel CH4;
+
+chemistryReader foamChemistryReader;
+
+foamChemistryFile "/reactions";
+
+foamChemistryThermoFile "/thermo.compressibleGas";
+
+
+// ************************************************************************* //
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/constant/turbulenceProperties b/tutorials/combustion/rhoReactingFoam/groundAbsorption/constant/turbulenceProperties
new file mode 100644
index 0000000000..15113f55f9
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/constant/turbulenceProperties
@@ -0,0 +1,20 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| ========= | |
+| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
+| \\ / O peration | Version: v2106 |
+| \\ / A nd | Website: www.openfoam.com |
+| \\/ M anipulation | |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+ version 2.0;
+ format ascii;
+ class dictionary;
+ object turbulenceProperties;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+simulationType laminar;
+
+
+// ************************************************************************* //
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/system/blockMeshDict b/tutorials/combustion/rhoReactingFoam/groundAbsorption/system/blockMeshDict
new file mode 100644
index 0000000000..e1b9fbef60
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/system/blockMeshDict
@@ -0,0 +1,73 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| ========= | |
+| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
+| \\ / O peration | Version: v2106 |
+| \\ / A nd | Website: www.openfoam.com |
+| \\/ M anipulation | |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+ version 2.0;
+ format ascii;
+ class dictionary;
+ object blockMeshDict;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+scale 1;
+
+vertices
+(
+ (-0.5 0 -0.5)
+ ( 0.5 0 -0.5)
+ ( 0.5 1.0 -0.5)
+ (-0.5 1.0 -0.5)
+ (-0.5 0 0.5)
+ ( 0.5 0 0.5)
+ ( 0.5 1.0 0.5)
+ (-0.5 1.0 0.5)
+
+);
+
+blocks
+(
+ hex (0 1 2 3 4 5 6 7) (60 60 60) simpleGrading (1 1 1)
+);
+
+edges
+(
+);
+
+boundary
+(
+ base
+ {
+ type patch;
+ faces
+ (
+ (0 1 5 4)
+ );
+ }
+ outlet
+ {
+ type patch;
+ faces
+ (
+ (3 2 6 7)
+ );
+ }
+ sides
+ {
+ type patch;
+ faces
+ (
+ (0 4 7 3)
+ (0 1 2 3)
+ (1 5 6 2)
+ (4 5 6 7)
+ );
+ }
+);
+
+
+// ************************************************************************* //
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/system/controlDict b/tutorials/combustion/rhoReactingFoam/groundAbsorption/system/controlDict
new file mode 100644
index 0000000000..ee1d14fde8
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/system/controlDict
@@ -0,0 +1,56 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| ========= | |
+| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
+| \\ / O peration | Version: v2106 |
+| \\ / A nd | Website: www.openfoam.com |
+| \\/ M anipulation | |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+ version 2.0;
+ format ascii;
+ class dictionary;
+ object controlDict;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+application rhoReactingFoam;
+
+startFrom latestTime;
+
+startTime 0.0;
+
+stopAt endTime;
+
+endTime 2.0;
+
+deltaT 0.001;
+
+writeControl adjustable;
+
+writeInterval 0.1;
+
+purgeWrite 0;
+
+writeFormat ascii;
+
+writePrecision 6;
+
+writeCompression off;
+
+timeFormat general;
+
+timePrecision 6;
+
+graphFormat raw;
+
+runTimeModifiable yes;
+
+adjustTimeStep yes;
+
+maxCo 0.6;
+
+maxDeltaT 0.1;
+
+
+// ************************************************************************* //
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/system/createPatchDict b/tutorials/combustion/rhoReactingFoam/groundAbsorption/system/createPatchDict
new file mode 100644
index 0000000000..a0056784a9
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/system/createPatchDict
@@ -0,0 +1,43 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| ========= | |
+| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
+| \\ / O peration | Version: v2106 |
+| \\ / A nd | Website: www.openfoam.com |
+| \\/ M anipulation | |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+ version 2.0;
+ format ascii;
+ class dictionary;
+ object createPatchDict;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+pointSync false;
+
+patches
+(
+ {
+ // Name of new patch
+ name inlet;
+
+ // Type of new patch
+ patchInfo
+ {
+ type patch;
+ }
+
+ // How to construct: either from 'patches' or 'set'
+ constructFrom set;
+
+ // If constructFrom = patches : names of patches. Wildcards allowed.
+ patches ("periodic.*");
+
+ // If constructFrom = set : name of faceSet
+ set f0;
+ }
+);
+
+
+// ************************************************************************* //
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/system/decomposeParDict b/tutorials/combustion/rhoReactingFoam/groundAbsorption/system/decomposeParDict
new file mode 100644
index 0000000000..cbbbabb8fe
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/system/decomposeParDict
@@ -0,0 +1,27 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| ========= | |
+| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
+| \\ / O peration | Version: v2106 |
+| \\ / A nd | Website: www.openfoam.com |
+| \\/ M anipulation | |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+ version 2.0;
+ format ascii;
+ class dictionary;
+ object decomposeParDict;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+numberOfSubdomains 4;
+
+method hierarchical;
+
+coeffs
+{
+ n (1 2 2);
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/system/fvSchemes b/tutorials/combustion/rhoReactingFoam/groundAbsorption/system/fvSchemes
new file mode 100644
index 0000000000..5986b01c85
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/system/fvSchemes
@@ -0,0 +1,64 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| ========= | |
+| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
+| \\ / O peration | Version: v2106 |
+| \\ / A nd | Website: www.openfoam.com |
+| \\/ M anipulation | |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+ version 2.0;
+ format ascii;
+ class dictionary;
+ object fvSchemes;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ddtSchemes
+{
+ default Euler;
+}
+
+gradSchemes
+{
+ default Gauss linear;
+}
+
+divSchemes
+{
+ default none;
+
+ div(phi,U) Gauss LUST grad(U);
+
+ div(phi,K) Gauss linear;
+ div(phi,k) Gauss limitedLinear 1;
+ div(phi,Yi_h) Gauss multivariateSelection
+ {
+ O2 limitedLinear01 1;
+ CH4 limitedLinear01 1;
+ N2 limitedLinear01 1;
+ H2O limitedLinear01 1;
+ CO2 limitedLinear01 1;
+ h limitedLinear 1;
+ };
+ div(((rho*nuEff)*dev2(T(grad(U))))) Gauss linear;
+ div(Ji,Ii_h) Gauss upwind;
+}
+
+laplacianSchemes
+{
+ default Gauss linear corrected;
+}
+
+interpolationSchemes
+{
+ default linear;
+}
+
+snGradSchemes
+{
+ default corrected;
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/system/fvSolution b/tutorials/combustion/rhoReactingFoam/groundAbsorption/system/fvSolution
new file mode 100644
index 0000000000..a5071c1ac1
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/system/fvSolution
@@ -0,0 +1,75 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| ========= | |
+| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
+| \\ / O peration | Version: v2106 |
+| \\ / A nd | Website: www.openfoam.com |
+| \\/ M anipulation | |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+ version 2.0;
+ format ascii;
+ class dictionary;
+ object fvSolution;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+solvers
+{
+ "(rho|rhoFinal)"
+ {
+ solver diagonal;
+ };
+
+ p
+ {
+ solver GAMG;
+ tolerance 1e-6;
+ relTol 0.1;
+ smoother GaussSeidel;
+ };
+
+ pFinal
+ {
+ $p;
+ tolerance 1e-6;
+ relTol 0;
+ maxIter 100;
+ };
+
+ "(U|Yi|k|h)"
+ {
+ solver PBiCGStab;
+ preconditioner DILU;
+ tolerance 1e-6;
+ relTol 0.1;
+ nSweeps 1;
+ };
+
+ "(U|Yi|k|h)Final"
+ {
+ $U;
+ tolerance 1e-6;
+ relTol 0;
+ };
+}
+
+PIMPLE
+{
+ momentumPredictor yes;
+ nOuterCorrectors 1;
+ nCorrectors 2;
+ nNonOrthogonalCorrectors 0;
+}
+
+relaxationFactors
+{
+ equations
+ {
+ "(U|k).*" 1;
+ "(CH4|O2|H2O|CO2|h).*" 1;
+ }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/combustion/rhoReactingFoam/groundAbsorption/system/topoSetDict b/tutorials/combustion/rhoReactingFoam/groundAbsorption/system/topoSetDict
new file mode 100644
index 0000000000..9951a32cac
--- /dev/null
+++ b/tutorials/combustion/rhoReactingFoam/groundAbsorption/system/topoSetDict
@@ -0,0 +1,29 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| ========= | |
+| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
+| \\ / O peration | Version: v2106 |
+| \\ / A nd | Website: www.openfoam.com |
+| \\/ M anipulation | |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+ version 2.0;
+ format ascii;
+ class dictionary;
+ object topoSetDict;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+actions
+(
+ {
+ name f0;
+ type faceSet;
+ action new;
+ source boxToFace;
+ box (-0.1 -0.001 -0.1)(0.1 0.005 0.1);
+ }
+);
+
+
+// ************************************************************************* //