From f3d4e512424153ed631129adc552d192514423b3 Mon Sep 17 00:00:00 2001
From: Henry Weller <http://cfd.direct>
Date: Wed, 14 Oct 2015 13:15:17 +0100
Subject: [PATCH] prghTotalPressureFvPatchScalarField: Total pressure BC for
 p_rgh Resolves some stability issues with the outlet of multiphase problems.

---
 src/finiteVolume/Make/files                   |   1 +
 .../prghTotalPressureFvPatchScalarField.C     | 213 +++++++++++++++
 .../prghTotalPressureFvPatchScalarField.H     | 243 ++++++++++++++++++
 .../laminar/bubbleColumn/0/p_rgh              |  17 +-
 4 files changed, 467 insertions(+), 7 deletions(-)
 create mode 100644 src/finiteVolume/fields/fvPatchFields/derived/prghTotalPressure/prghTotalPressureFvPatchScalarField.C
 create mode 100644 src/finiteVolume/fields/fvPatchFields/derived/prghTotalPressure/prghTotalPressureFvPatchScalarField.H

diff --git a/src/finiteVolume/Make/files b/src/finiteVolume/Make/files
index c7100518ab6..1b9c242765d 100644
--- a/src/finiteVolume/Make/files
+++ b/src/finiteVolume/Make/files
@@ -199,6 +199,7 @@ $(derivedFvPatchFields)/waveTransmissive/waveTransmissiveFvPatchFields.C
 $(derivedFvPatchFields)/waveSurfacePressure/waveSurfacePressureFvPatchScalarField.C
 $(derivedFvPatchFields)/interstitialInletVelocity/interstitialInletVelocityFvPatchVectorField.C
 $(derivedFvPatchFields)/prghPressure/prghPressureFvPatchScalarField.C
+$(derivedFvPatchFields)/prghTotalPressure/prghTotalPressureFvPatchScalarField.C
 
 fvsPatchFields = fields/fvsPatchFields
 $(fvsPatchFields)/fvsPatchField/fvsPatchFields.C
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/prghTotalPressure/prghTotalPressureFvPatchScalarField.C b/src/finiteVolume/fields/fvPatchFields/derived/prghTotalPressure/prghTotalPressureFvPatchScalarField.C
new file mode 100644
index 00000000000..7b8789df448
--- /dev/null
+++ b/src/finiteVolume/fields/fvPatchFields/derived/prghTotalPressure/prghTotalPressureFvPatchScalarField.C
@@ -0,0 +1,213 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 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 <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "prghTotalPressureFvPatchScalarField.H"
+#include "addToRunTimeSelectionTable.H"
+#include "fvPatchFieldMapper.H"
+#include "volFields.H"
+#include "surfaceFields.H"
+#include "uniformDimensionedFields.H"
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::prghTotalPressureFvPatchScalarField::
+prghTotalPressureFvPatchScalarField
+(
+    const fvPatch& p,
+    const DimensionedField<scalar, volMesh>& iF
+)
+:
+    fixedValueFvPatchScalarField(p, iF),
+    UName_("U"),
+    phiName_("phi"),
+    rhoName_("rho"),
+    p0_(p.size(), 0.0)
+{}
+
+
+Foam::prghTotalPressureFvPatchScalarField::
+prghTotalPressureFvPatchScalarField
+(
+    const fvPatch& p,
+    const DimensionedField<scalar, volMesh>& iF,
+    const dictionary& dict
+)
+:
+    fixedValueFvPatchScalarField(p, iF),
+    UName_(dict.lookupOrDefault<word>("U", "U")),
+    phiName_(dict.lookupOrDefault<word>("phi", "phi")),
+    rhoName_(dict.lookupOrDefault<word>("rhoName", "rho")),
+    p0_("p0", dict, p.size())
+{
+    if (dict.found("value"))
+    {
+        fvPatchScalarField::operator=
+        (
+            scalarField("value", dict, p.size())
+        );
+    }
+    else
+    {
+        fvPatchField<scalar>::operator=(p0_);
+    }
+}
+
+
+Foam::prghTotalPressureFvPatchScalarField::
+prghTotalPressureFvPatchScalarField
+(
+    const prghTotalPressureFvPatchScalarField& ptf,
+    const fvPatch& p,
+    const DimensionedField<scalar, volMesh>& iF,
+    const fvPatchFieldMapper& mapper
+)
+:
+    fixedValueFvPatchScalarField(ptf, p, iF, mapper),
+    UName_(ptf.UName_),
+    phiName_(ptf.phiName_),
+    rhoName_(ptf.rhoName_),
+    p0_(ptf.p0_, mapper)
+{}
+
+
+Foam::prghTotalPressureFvPatchScalarField::
+prghTotalPressureFvPatchScalarField
+(
+    const prghTotalPressureFvPatchScalarField& ptf
+)
+:
+    fixedValueFvPatchScalarField(ptf),
+    UName_(ptf.UName_),
+    phiName_(ptf.phiName_),
+    rhoName_(ptf.rhoName_),
+    p0_(ptf.p0_)
+{}
+
+
+Foam::prghTotalPressureFvPatchScalarField::
+prghTotalPressureFvPatchScalarField
+(
+    const prghTotalPressureFvPatchScalarField& ptf,
+    const DimensionedField<scalar, volMesh>& iF
+)
+:
+    fixedValueFvPatchScalarField(ptf, iF),
+    UName_(ptf.UName_),
+    phiName_(ptf.phiName_),
+    rhoName_(ptf.rhoName_),
+    p0_(ptf.p0_)
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::prghTotalPressureFvPatchScalarField::autoMap
+(
+    const fvPatchFieldMapper& m
+)
+{
+    fixedValueFvPatchScalarField::autoMap(m);
+    p0_.autoMap(m);
+}
+
+
+void Foam::prghTotalPressureFvPatchScalarField::rmap
+(
+    const fvPatchScalarField& ptf,
+    const labelList& addr
+)
+{
+    fixedValueFvPatchScalarField::rmap(ptf, addr);
+
+    const prghTotalPressureFvPatchScalarField& tiptf =
+        refCast<const prghTotalPressureFvPatchScalarField>(ptf);
+
+    p0_.rmap(tiptf.p0_, addr);
+}
+
+
+void Foam::prghTotalPressureFvPatchScalarField::updateCoeffs()
+{
+    if (updated())
+    {
+        return;
+    }
+
+    const scalarField& rhop =
+        patch().lookupPatchField<volScalarField, scalar>(rhoName_);
+
+    const scalarField& phip =
+        patch().lookupPatchField<surfaceScalarField, scalar>(phiName_);
+
+    const vectorField& Up =
+        patch().lookupPatchField<volVectorField, vector>(UName_);
+
+    const uniformDimensionedVectorField& g =
+        db().lookupObject<uniformDimensionedVectorField>("g");
+
+    const uniformDimensionedScalarField& hRef =
+        db().lookupObject<uniformDimensionedScalarField>("hRef");
+
+    dimensionedScalar ghRef
+    (
+        mag(g.value()) > SMALL
+      ? g & (cmptMag(g.value())/mag(g.value()))*hRef
+      : dimensionedScalar("ghRef", g.dimensions()*dimLength, 0)
+    );
+
+    operator==
+    (
+        p0_
+      - 0.5*rhop*(1.0 - pos(phip))*magSqr(Up)
+      - rhop*((g.value() & patch().Cf()) - ghRef.value())
+    );
+
+    fixedValueFvPatchScalarField::updateCoeffs();
+}
+
+
+void Foam::prghTotalPressureFvPatchScalarField::write(Ostream& os) const
+{
+    fvPatchScalarField::write(os);
+    writeEntryIfDifferent<word>(os, "U", "U", UName_);
+    writeEntryIfDifferent<word>(os, "phi", "phi", phiName_);
+    writeEntryIfDifferent<word>(os, "rho", "rho", rhoName_);
+    p0_.writeEntry("p0", os);
+    writeEntry("value", os);
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    makePatchTypeField
+    (
+        fvPatchScalarField,
+        prghTotalPressureFvPatchScalarField
+    );
+}
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/prghTotalPressure/prghTotalPressureFvPatchScalarField.H b/src/finiteVolume/fields/fvPatchFields/derived/prghTotalPressure/prghTotalPressureFvPatchScalarField.H
new file mode 100644
index 00000000000..f809029261b
--- /dev/null
+++ b/src/finiteVolume/fields/fvPatchFields/derived/prghTotalPressure/prghTotalPressureFvPatchScalarField.H
@@ -0,0 +1,243 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 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 <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::prghTotalPressureFvPatchScalarField
+
+Group
+    grpGenericBoundaryConditions
+
+Description
+    This boundary condition provides static pressure condition for p_rgh,
+    calculated as:
+
+        \f[
+            p_rgh = p - \rho g (h - hRef)
+        \f]
+
+    where
+    \vartable
+        p_rgh   | Pseudo hydrostatic pressure [Pa]
+        p       | Static pressure [Pa]
+        h       | Height in the opposite direction to gravity
+        hRef    | Reference height in the opposite direction to gravity
+        \rho    | density
+        g       | acceleration due to gravity [m/s^2]
+    \endtable
+
+    \heading Patch usage
+
+    \table
+        Property     | Description             | Required    | Default value
+        rhoName      | rho field name          | no          | rho
+        p            | static pressure         | yes         |
+    \endtable
+
+    Example of the boundary condition specification:
+    \verbatim
+    myPatch
+    {
+        type            prghTotalPressure;
+        rhoName         rho;
+        p               uniform 0;
+        value           uniform 0; // optional initial value
+    }
+    \endverbatim
+
+SeeAlso
+    Foam::fixedValueFvPatchScalarField
+
+SourceFiles
+    prghTotalPressureFvPatchScalarField.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef prghTotalPressureFvPatchScalarField_H
+#define prghTotalPressureFvPatchScalarField_H
+
+#include "fixedValueFvPatchFields.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+         Class prghTotalPressureFvPatchScalarField Declaration
+\*---------------------------------------------------------------------------*/
+
+class prghTotalPressureFvPatchScalarField
+:
+    public fixedValueFvPatchScalarField
+{
+
+protected:
+
+    // Protected data
+
+        //- Name of the velocity field
+        word UName_;
+
+        //- Name of the flux transporting the field
+        word phiName_;
+
+        //- Name of phase-fraction field
+        word rhoName_;
+
+        //- Total pressure
+        scalarField p0_;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("prghTotalPressure");
+
+
+    // Constructors
+
+        //- Construct from patch and internal field
+        prghTotalPressureFvPatchScalarField
+        (
+            const fvPatch&,
+            const DimensionedField<scalar, volMesh>&
+        );
+
+        //- Construct from patch, internal field and dictionary
+        prghTotalPressureFvPatchScalarField
+        (
+            const fvPatch&,
+            const DimensionedField<scalar, volMesh>&,
+            const dictionary&
+        );
+
+        //- Construct by mapping given
+        //  prghTotalPressureFvPatchScalarField onto a new patch
+        prghTotalPressureFvPatchScalarField
+        (
+            const prghTotalPressureFvPatchScalarField&,
+            const fvPatch&,
+            const DimensionedField<scalar, volMesh>&,
+            const fvPatchFieldMapper&
+        );
+
+        //- Construct as copy
+        prghTotalPressureFvPatchScalarField
+        (
+            const prghTotalPressureFvPatchScalarField&
+        );
+
+        //- Construct and return a clone
+        virtual tmp<fvPatchScalarField> clone() const
+        {
+            return tmp<fvPatchScalarField >
+            (
+                new prghTotalPressureFvPatchScalarField(*this)
+            );
+        }
+
+        //- Construct as copy setting internal field reference
+        prghTotalPressureFvPatchScalarField
+        (
+            const prghTotalPressureFvPatchScalarField&,
+            const DimensionedField<scalar, volMesh>&
+        );
+
+        //- Construct and return a clone setting internal field reference
+        virtual tmp<fvPatchScalarField> clone
+        (
+            const DimensionedField<scalar, volMesh>& iF
+        ) const
+        {
+            return tmp<fvPatchScalarField>
+            (
+                new prghTotalPressureFvPatchScalarField(*this, iF)
+            );
+        }
+
+
+    // Member functions
+
+        // Access
+
+            //- Return the rhoName
+            const word& rhoName() const
+            {
+                return rhoName_;
+            }
+
+            //- Return reference to the rhoName to allow adjustment
+            word& rhoName()
+            {
+                return rhoName_;
+            }
+
+            //- Return the total pressure
+            const scalarField& p0() const
+            {
+                return p0_;
+            }
+
+            //- Return reference to the total pressure to allow adjustment
+            scalarField& p0()
+            {
+                return p0_;
+            }
+
+
+        // Mapping functions
+
+            //- 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 functions
+
+            //- Update the coefficients associated with the patch field
+            virtual void updateCoeffs();
+
+
+        //- Write
+        virtual void write(Ostream&) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/tutorials/multiphase/reactingMultiphaseEulerFoam/laminar/bubbleColumn/0/p_rgh b/tutorials/multiphase/reactingMultiphaseEulerFoam/laminar/bubbleColumn/0/p_rgh
index de5ac9e4379..d78578a4408 100644
--- a/tutorials/multiphase/reactingMultiphaseEulerFoam/laminar/bubbleColumn/0/p_rgh
+++ b/tutorials/multiphase/reactingMultiphaseEulerFoam/laminar/bubbleColumn/0/p_rgh
@@ -22,19 +22,22 @@ boundaryField
 {
     inlet
     {
-        type               fixedFluxPressure;
-        value              $internalField;
+        type            fixedFluxPressure;
+        value           $internalField;
     }
     outlet
     {
-        type               prghPressure;
-        p                  $internalField;
-        value              $internalField;
+        type            prghTotalPressure;
+        p0              $internalField;
+        U               U.air;
+        phi             phi.air;
+        rho             rho.air;
+        value           $internalField;
     }
     walls
     {
-        type               fixedFluxPressure;
-        value              $internalField;
+        type            fixedFluxPressure;
+        value           $internalField;
     }
 }
 
-- 
GitLab