From 5db676551b3a6614cc4b9a5b9cd4011df04e760b Mon Sep 17 00:00:00 2001 From: Henry Weller <http://openfoam.org> Date: Mon, 17 Jul 2017 15:48:39 +0100 Subject: [PATCH] matchedFlowRateOutletVelocity: New flow-rate outlet BC Velocity outlet boundary condition which corrects the extrapolated velocity to match the flow rate of the specified corresponding inlet patch. --- ...FlowRateOutletVelocityFvPatchVectorField.C | 271 ++++++++++++++++++ ...FlowRateOutletVelocityFvPatchVectorField.H | 189 ++++++++++++ 2 files changed, 460 insertions(+) create mode 100644 src/finiteVolume/fields/fvPatchFields/derived/matchedFlowRateOutletVelocity/matchedFlowRateOutletVelocityFvPatchVectorField.C create mode 100644 src/finiteVolume/fields/fvPatchFields/derived/matchedFlowRateOutletVelocity/matchedFlowRateOutletVelocityFvPatchVectorField.H diff --git a/src/finiteVolume/fields/fvPatchFields/derived/matchedFlowRateOutletVelocity/matchedFlowRateOutletVelocityFvPatchVectorField.C b/src/finiteVolume/fields/fvPatchFields/derived/matchedFlowRateOutletVelocity/matchedFlowRateOutletVelocityFvPatchVectorField.C new file mode 100644 index 0000000000..4ea359ee5b --- /dev/null +++ b/src/finiteVolume/fields/fvPatchFields/derived/matchedFlowRateOutletVelocity/matchedFlowRateOutletVelocityFvPatchVectorField.C @@ -0,0 +1,271 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2017 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 "matchedFlowRateOutletVelocityFvPatchVectorField.H" +#include "volFields.H" +#include "one.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::matchedFlowRateOutletVelocityFvPatchVectorField:: +matchedFlowRateOutletVelocityFvPatchVectorField +( + const fvPatch& p, + const DimensionedField<vector, volMesh>& iF +) +: + fixedValueFvPatchField<vector>(p, iF), + inletPatchName_(), + volumetric_(false), + rhoName_("rho") +{} + + +Foam::matchedFlowRateOutletVelocityFvPatchVectorField:: +matchedFlowRateOutletVelocityFvPatchVectorField +( + const fvPatch& p, + const DimensionedField<vector, volMesh>& iF, + const dictionary& dict +) +: + fixedValueFvPatchField<vector>(p, iF, dict, false), + inletPatchName_(dict.lookup("inletPatch")), + volumetric_(dict.lookupOrDefault("volumetric", true)) +{ + if (volumetric_) + { + rhoName_ = "none"; + } + else + { + rhoName_ = word(dict.lookupOrDefault<word>("rho", "rho")); + } + + // Value field require if mass based + if (dict.found("value")) + { + fvPatchField<vector>::operator= + ( + vectorField("value", dict, p.size()) + ); + } + else + { + evaluate(Pstream::commsTypes::blocking); + } +} + + +Foam::matchedFlowRateOutletVelocityFvPatchVectorField:: +matchedFlowRateOutletVelocityFvPatchVectorField +( + const matchedFlowRateOutletVelocityFvPatchVectorField& ptf, + const fvPatch& p, + const DimensionedField<vector, volMesh>& iF, + const fvPatchFieldMapper& mapper +) +: + fixedValueFvPatchField<vector>(ptf, p, iF, mapper), + inletPatchName_(ptf.inletPatchName_), + volumetric_(ptf.volumetric_), + rhoName_(ptf.rhoName_) +{} + + +Foam::matchedFlowRateOutletVelocityFvPatchVectorField:: +matchedFlowRateOutletVelocityFvPatchVectorField +( + const matchedFlowRateOutletVelocityFvPatchVectorField& ptf +) +: + fixedValueFvPatchField<vector>(ptf), + inletPatchName_(ptf.inletPatchName_), + volumetric_(ptf.volumetric_), + rhoName_(ptf.rhoName_) +{} + + +Foam::matchedFlowRateOutletVelocityFvPatchVectorField:: +matchedFlowRateOutletVelocityFvPatchVectorField +( + const matchedFlowRateOutletVelocityFvPatchVectorField& ptf, + const DimensionedField<vector, volMesh>& iF +) +: + fixedValueFvPatchField<vector>(ptf, iF), + inletPatchName_(ptf.inletPatchName_), + volumetric_(ptf.volumetric_), + rhoName_(ptf.rhoName_) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template<class RhoType> +void Foam::matchedFlowRateOutletVelocityFvPatchVectorField::updateValues +( + const label inletPatchID, + const RhoType& rhoOutlet, + const RhoType& rhoInlet +) +{ + const fvPatch& p = patch(); + const fvPatch& inletPatch = p.boundaryMesh()[inletPatchID]; + + const vectorField n(p.nf()); + + // Extrapolate patch velocity + vectorField Up(patchInternalField()); + + // Patch normal extrapolated velocity + scalarField nUp(n & Up); + + // Remove the normal component of the extrapolate patch velocity + Up -= nUp*n; + + // Remove any reverse flow + nUp = max(nUp, scalar(0)); + + // Lookup non-const access to velocity field + volVectorField& U + ( + const_cast<volVectorField&> + ( + dynamic_cast<const volVectorField&>(internalField()) + ) + ); + + // Get the corresponding inlet velocity patch field + fvPatchVectorField& inletPatchU = U.boundaryFieldRef()[inletPatchID]; + + // Ensure that the corresponding inlet velocity patch field is up-to-date + inletPatchU.updateCoeffs(); + + // Calculate the inlet patch flow rate + const scalar flowRate = -gSum(rhoInlet*(inletPatch.Sf() & inletPatchU)); + + // Calculate the extrapolated outlet patch flow rate + const scalar estimatedFlowRate = gSum(rhoOutlet*(patch().magSf()*nUp)); + + if (estimatedFlowRate/flowRate > 0.5) + { + nUp *= (mag(flowRate)/mag(estimatedFlowRate)); + } + else + { + nUp += ((flowRate - estimatedFlowRate)/gSum(rhoOutlet*patch().magSf())); + } + + // Add the corrected normal component of velocity to the patch velocity + Up += nUp*n; + + // Correct the patch velocity + operator==(Up); +} + + +void Foam::matchedFlowRateOutletVelocityFvPatchVectorField::updateCoeffs() +{ + if (updated()) + { + return; + } + + // Find corresponding inlet patch + const label inletPatchID = + patch().patch().boundaryMesh().findPatchID(inletPatchName_); + + if (inletPatchID < 0) + { + FatalErrorInFunction + << "Unable to find inlet patch " << inletPatchName_ + << exit(FatalError); + } + + if (volumetric_) + { + updateValues(inletPatchID, one(), one()); + } + else + { + // Mass flow-rate + if (db().foundObject<volScalarField>(rhoName_)) + { + const volScalarField& rho = db().lookupObject<volScalarField> + ( + rhoName_ + ); + + updateValues + ( + inletPatchID, + rho.boundaryField()[patch().index()], + rho.boundaryField()[inletPatchID] + ); + } + else + { + FatalErrorInFunction + << "Cannot find density field " << rhoName_ << exit(FatalError); + } + } + + fixedValueFvPatchVectorField::updateCoeffs(); +} + + +void Foam::matchedFlowRateOutletVelocityFvPatchVectorField::write +( + Ostream& os +) const +{ + fvPatchField<vector>::write(os); + os.writeKeyword("inletPatch") + << inletPatchName_ << token::END_STATEMENT << nl; + if (!volumetric_) + { + os.writeKeyword("volumetric") + << volumetric_ << token::END_STATEMENT << nl; + writeEntryIfDifferent<word>(os, "rho", "rho", rhoName_); + } + writeEntry("value", os); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + makePatchTypeField + ( + fvPatchVectorField, + matchedFlowRateOutletVelocityFvPatchVectorField + ); +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fields/fvPatchFields/derived/matchedFlowRateOutletVelocity/matchedFlowRateOutletVelocityFvPatchVectorField.H b/src/finiteVolume/fields/fvPatchFields/derived/matchedFlowRateOutletVelocity/matchedFlowRateOutletVelocityFvPatchVectorField.H new file mode 100644 index 0000000000..2442e081f5 --- /dev/null +++ b/src/finiteVolume/fields/fvPatchFields/derived/matchedFlowRateOutletVelocity/matchedFlowRateOutletVelocityFvPatchVectorField.H @@ -0,0 +1,189 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2017 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::matchedFlowRateOutletVelocityFvPatchVectorField + +Group + grpOutletBoundaryConditions + +Description + Velocity outlet boundary condition which corrects the extrapolated velocity + to match the flow rate of the specified corresponding inlet patch. + +Usage + \table + Property | Description | Required | Default value + inletPatch | Corresponding inlet patch name | yes | + volumetric | Set volumetric or mass flow-rate | no | false + rho | density field name | no | rho + \endtable + + Example of the boundary condition specification for a volumetric flow rate: + \verbatim + <patchName> + { + type matchedFlowRateOutletVelocity; + inletPatch inlet; + value uniform (0 0 0); + } + \endverbatim + +See also + Foam::fixedValueFvPatchField + +SourceFiles + matchedFlowRateOutletVelocityFvPatchVectorField.C + +\*---------------------------------------------------------------------------*/ + +#ifndef matchedFlowRateOutletVelocityFvPatchVectorField_H +#define matchedFlowRateOutletVelocityFvPatchVectorField_H + +#include "fixedValueFvPatchFields.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class matchedFlowRateOutletVelocityFvPatchVectorField Declaration +\*---------------------------------------------------------------------------*/ + +class matchedFlowRateOutletVelocityFvPatchVectorField +: + public fixedValueFvPatchVectorField +{ + // Private data + + //- Inlet patch name from which the corresponding flow rate is obtained + word inletPatchName_; + + //- Is volumetric? + bool volumetric_; + + //- Name of the density field used to normalize the mass flux + word rhoName_; + + + // Private member functions + + //- Update the patch values given the appropriate density type and value + template<class RhoType> + void updateValues + ( + const label inletPatchID, + const RhoType& rhoOutlet, + const RhoType& rhoInlet + ); + + +public: + + //- Runtime type information + TypeName("matchedFlowRateOutletVelocity"); + + + // Constructors + + //- Construct from patch and internal field + matchedFlowRateOutletVelocityFvPatchVectorField + ( + const fvPatch&, + const DimensionedField<vector, volMesh>& + ); + + //- Construct from patch, internal field and dictionary + matchedFlowRateOutletVelocityFvPatchVectorField + ( + const fvPatch&, + const DimensionedField<vector, volMesh>&, + const dictionary& + ); + + //- Construct by mapping given + // matchedFlowRateOutletVelocityFvPatchVectorField + // onto a new patch + matchedFlowRateOutletVelocityFvPatchVectorField + ( + const matchedFlowRateOutletVelocityFvPatchVectorField&, + const fvPatch&, + const DimensionedField<vector, volMesh>&, + const fvPatchFieldMapper& + ); + + //- Construct as copy + matchedFlowRateOutletVelocityFvPatchVectorField + ( + const matchedFlowRateOutletVelocityFvPatchVectorField& + ); + + //- Construct and return a clone + virtual tmp<fvPatchVectorField> clone() const + { + return tmp<fvPatchVectorField> + ( + new matchedFlowRateOutletVelocityFvPatchVectorField(*this) + ); + } + + //- Construct as copy setting internal field reference + matchedFlowRateOutletVelocityFvPatchVectorField + ( + const matchedFlowRateOutletVelocityFvPatchVectorField&, + const DimensionedField<vector, volMesh>& + ); + + //- Construct and return a clone setting internal field reference + virtual tmp<fvPatchVectorField> clone + ( + const DimensionedField<vector, volMesh>& iF + ) const + { + return tmp<fvPatchVectorField> + ( + new matchedFlowRateOutletVelocityFvPatchVectorField(*this, iF) + ); + } + + + // Member functions + + //- Update the coefficients associated with the patch field + virtual void updateCoeffs(); + + //- Write + virtual void write(Ostream&) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // -- GitLab