Added ramping functionality for multiphase simulations

The outletPhaseMeanVelocity and waveVelocity boundary conditions now
support a "ramp" keyword, for which a function can be supplied to
gradually increase the input velocity. The following is an example
specification for an outlet patch:

    outlet
    {
        type            outletPhaseMeanVelocity;
        Umean           2;
        ramp
        {
            type            quarterSineRamp;
            start           0;
            duration        5;
        }
        alpha           alpha.water;
    }

There is also a new velocityRamping function object, which provides a
matching force within the volume of the domain, so that the entire flow
is smoothly accelerated up to the operating condition. An example
specification is as follows:

    velocityRamping
    {
        type        velocityRamping;
        active      on;
        selectionMode all;
        U           U;
        velocity    (-2 0 0);
        ramp
        {
            type        quarterSineRamp;
            start       0;
            duration    5;
        }
    }

These additions have been designed to facilitate a smoother startup of
ship simulations by avoiding the slamming transients associated with
initialising a uniform velocity field.

This work was supported by Jan Kaufmann and Jan Oberhagemann at DNV GL.
This commit is contained in:
Will Bainbridge
2018-01-08 08:50:07 +00:00
parent 9a35ce69a3
commit a80da1a489
10 changed files with 408 additions and 42 deletions

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2017 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2017-2018 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -72,6 +72,7 @@ int main(int argc, char *argv[])
forAll(timeDirs, timeI)
{
runTime.setTime(timeDirs[timeI], timeI);
const scalar t = runTime.value();
Info<< "Time = " << runTime.timeName() << nl << endl;
@ -188,17 +189,16 @@ int main(int argc, char *argv[])
}
liquid = liquidp;
const scalar t = runTime.value();
const pointField& ccs = mesh.cellCentres();
const pointField& pts = mesh.points();
// Internal field superposition
h.primitiveFieldRef() += waves.height(t, ccs);
hp.primitiveFieldRef() += waves.height(t, pts);
uGas.primitiveFieldRef() += waves.UGas(t, ccs) - waves.UMean();
uGasp.primitiveFieldRef() += waves.UGas(t, pts) - waves.UMean();
uLiq.primitiveFieldRef() += waves.ULiquid(t, ccs) - waves.UMean();
uLiqp.primitiveFieldRef() += waves.ULiquid(t, pts) - waves.UMean();
uGas.primitiveFieldRef() += waves.UGas(t, ccs) - waves.UMean(t);
uGasp.primitiveFieldRef() += waves.UGas(t, pts) - waves.UMean(t);
uLiq.primitiveFieldRef() += waves.ULiquid(t, ccs) - waves.UMean(t);
uLiqp.primitiveFieldRef() += waves.ULiquid(t, pts) - waves.UMean(t);
// Boundary field superposition
forAll(mesh.boundary(), patchj)
@ -206,9 +206,9 @@ int main(int argc, char *argv[])
const pointField& fcs = mesh.boundary()[patchj].Cf();
h.boundaryFieldRef()[patchj] += waves.height(t, fcs);
uGas.boundaryFieldRef()[patchj] +=
waves.UGas(t, fcs) - waves.UMean();
waves.UGas(t, fcs) - waves.UMean(t);
uLiq.boundaryFieldRef()[patchj] +=
waves.ULiquid(t, fcs) - waves.UMean();
waves.ULiquid(t, fcs) - waves.UMean(t);
}
++ nWaves;
@ -246,7 +246,8 @@ int main(int argc, char *argv[])
const waveSuperposition& waves =
refCast<const waveVelocityFvPatchVectorField>(Up).waves();
UMean == dimensionedVector("UMean", dimVelocity, waves.UMean());
UMean ==
dimensionedVector("UMean", dimVelocity, waves.UMean(t));
}
}
else if (nWaves > 1)
@ -290,7 +291,7 @@ int main(int argc, char *argv[])
weight += w;
weightUMean +=
w*dimensionedVector("wUMean", dimVelocity, waves.UMean());
w*dimensionedVector("wUMean", dimVelocity, waves.UMean(t));
}
// Complete the average for the mean velocity

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013-2016 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2013-2018 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -40,6 +40,7 @@ Foam::outletPhaseMeanVelocityFvPatchVectorField
:
mixedFvPatchField<vector>(p, iF),
Umean_(0),
ramp_(),
alphaName_("none")
{
refValue() = Zero;
@ -59,6 +60,7 @@ Foam::outletPhaseMeanVelocityFvPatchVectorField
:
mixedFvPatchField<vector>(ptf, p, iF, mapper),
Umean_(ptf.Umean_),
ramp_(ptf.ramp_, false),
alphaName_(ptf.alphaName_)
{}
@ -73,6 +75,12 @@ Foam::outletPhaseMeanVelocityFvPatchVectorField
:
mixedFvPatchField<vector>(p, iF),
Umean_(readScalar(dict.lookup("Umean"))),
ramp_
(
dict.found("ramp")
? Function1<scalar>::New("ramp", dict)
: autoPtr<Function1<scalar>>()
),
alphaName_(dict.lookup("alpha"))
{
refValue() = Zero;
@ -101,6 +109,7 @@ Foam::outletPhaseMeanVelocityFvPatchVectorField
:
mixedFvPatchField<vector>(ptf),
Umean_(ptf.Umean_),
ramp_(ptf.ramp_, false),
alphaName_(ptf.alphaName_)
{}
@ -114,6 +123,7 @@ Foam::outletPhaseMeanVelocityFvPatchVectorField
:
mixedFvPatchField<vector>(ptf, iF),
Umean_(ptf.Umean_),
ramp_(ptf.ramp_, false),
alphaName_(ptf.alphaName_)
{}
@ -127,6 +137,8 @@ void Foam::outletPhaseMeanVelocityFvPatchVectorField::updateCoeffs()
return;
}
const scalar t = this->db().time().timeOutputValue();
scalarField alphap =
patch().lookupPatchField<volScalarField, scalar>(alphaName_);
@ -143,15 +155,16 @@ void Foam::outletPhaseMeanVelocityFvPatchVectorField::updateCoeffs()
// Set the refValue and valueFraction to adjust the boundary field
// such that the phase mean is Umean_
if (Uzgmean >= Umean_)
const scalar Umean = (ramp_.valid() ? ramp_->value(t) : 1)*Umean_;
if (Uzgmean >= Umean)
{
refValue() = Zero;
valueFraction() = 1.0 - Umean_/Uzgmean;
valueFraction() = 1.0 - Umean/Uzgmean;
}
else
{
refValue() = (Umean_ + Uzgmean)*patch().nf();
valueFraction() = 1.0 - Uzgmean/Umean_;
refValue() = (Umean + Uzgmean)*patch().nf();
valueFraction() = 1.0 - Uzgmean/Umean;
}
mixedFvPatchField<vector>::updateCoeffs();
@ -165,10 +178,12 @@ void Foam::outletPhaseMeanVelocityFvPatchVectorField::write
{
fvPatchField<vector>::write(os);
os.writeKeyword("Umean") << Umean_
<< token::END_STATEMENT << nl;
os.writeKeyword("alpha") << alphaName_
<< token::END_STATEMENT << nl;
os.writeKeyword("Umean") << Umean_ << token::END_STATEMENT << nl;
if (ramp_.valid())
{
ramp_->writeData(os);
}
os.writeKeyword("alpha") << alphaName_ << token::END_STATEMENT << nl;
writeEntry("value", os);
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013-2016 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2013-2018 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -39,6 +39,7 @@ Usage
\table
Property | Description | Required | Default value
Umean | mean velocity normal to the boundary [m/s] | yes |
ramp | ramping function for the mean flow speed | no | None
alpha | phase-fraction field | yes |
\endtable
@ -66,6 +67,7 @@ SourceFiles
#define outletPhaseMeanVelocityFvPatchVectorField_H
#include "mixedFvPatchFields.H"
#include "Function1.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -84,6 +86,9 @@ class outletPhaseMeanVelocityFvPatchVectorField
//- Inlet integral flow rate
scalar Umean_;
//- Ramp for the mean flow rate
autoPtr<Function1<scalar>> ramp_;
//- Name of the phase-fraction field
word alphaName_;
@ -163,21 +168,6 @@ public:
// Member functions
// Access
//- Return the flux
scalar Umean() const
{
return Umean_;
}
//- Return reference to the flux to allow adjustment
scalar& Umean()
{
return Umean_;
}
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();

View File

@ -39,6 +39,7 @@ $(derivedSources)/buoyancyEnergy/buoyancyEnergy.C
$(derivedSources)/buoyancyEnergy/buoyancyEnergyIO.C
$(derivedSources)/verticalDamping/verticalDamping.C
$(derivedSources)/phaseLimitStabilization/phaseLimitStabilization.C
$(derivedSources)/velocityRamping/velocityRamping.C
interRegion = sources/interRegion
$(interRegion)/interRegionHeatTransfer/interRegionHeatTransferModel/interRegionHeatTransferModel.C

View File

@ -0,0 +1,118 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 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 "fvMesh.H"
#include "fvMatrix.H"
#include "geometricOneField.H"
#include "velocityRamping.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace fv
{
defineTypeNameAndDebug(velocityRamping, 0);
addToRunTimeSelectionTable(option, velocityRamping, dictionary);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fv::velocityRamping::velocityRamping
(
const word& name,
const word& modelType,
const dictionary& dict,
const fvMesh& mesh
)
:
cellSetOption(name, modelType, dict, mesh),
velocity_(vector::zero),
ramp_(nullptr)
{
read(dict);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::fv::velocityRamping::addSup
(
fvMatrix<vector>& eqn,
const label fieldi
)
{
add(geometricOneField(), eqn, fieldi);
}
void Foam::fv::velocityRamping::addSup
(
const volScalarField& rho,
fvMatrix<vector>& eqn,
const label fieldi
)
{
add(rho, eqn, fieldi);
}
void Foam::fv::velocityRamping::addSup
(
const volScalarField& alpha,
const volScalarField& rho,
fvMatrix<vector>& eqn,
const label fieldi
)
{
add((alpha*rho)(), eqn, fieldi);
}
bool Foam::fv::velocityRamping::read(const dictionary& dict)
{
if (cellSetOption::read(dict))
{
fieldNames_ = wordList(1, coeffs_.lookupOrDefault<word>("U", "U"));
applied_.setSize(1, false);
velocity_ = dict.lookupType<vector>("velocity");
ramp_ = Function1<scalar>::New("ramp", dict);
return true;
}
else
{
return false;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,173 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 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::fv::velocityRamping
Description
This fvOption applies an explicit acceleration force to components of the
velocity field.
Usage
Example usage:
\verbatim
velocityRamping
{
type velocityRamping;
active on;
selectionMode all;
U U;
velocity (-2.572 0 0);
ramp
{
type quarterSineRamp;
start 0;
duration 10;
}
}
\endverbatim
SourceFiles
velocityRamping.C
\*---------------------------------------------------------------------------*/
#ifndef velocityRamping_H
#define velocityRamping_H
#include "cellSetOption.H"
#include "Function1.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace fv
{
/*---------------------------------------------------------------------------*\
Class velocityRamping Declaration
\*---------------------------------------------------------------------------*/
class velocityRamping
:
public cellSetOption
{
private:
// Private data
//- Velocity at the end of the ramp
vector velocity_;
//- Ramp function
autoPtr<Function1<scalar>> ramp_;
// Private Member Functions
//- Source term to momentum equation
template<class AlphaRhoFieldType>
void add
(
const AlphaRhoFieldType& rho,
fvMatrix<vector>& eqn,
const label fieldi
);
public:
//- Runtime type information
TypeName("velocityRamping");
// Constructors
//- Construct from components
velocityRamping
(
const word& name,
const word& modelType,
const dictionary& dict,
const fvMesh& mesh
);
//- Destructor
virtual ~velocityRamping()
{}
// Member Functions
// Add explicit and implicit contributions
//- Source term to momentum equation
virtual void addSup
(
fvMatrix<vector>& eqn,
const label fieldi
);
//- Source term to compressible momentum equation
virtual void addSup
(
const volScalarField& rho,
fvMatrix<vector>& eqn,
const label fieldi
);
//- Source term to phase momentum equation
virtual void addSup
(
const volScalarField& alpha,
const volScalarField& rho,
fvMatrix<vector>& eqn,
const label fieldi
);
// IO
//- Read dictionary
virtual bool read(const dictionary& dict);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fv
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "velocityRampingTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,51 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 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/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class AlphaRhoFieldType>
void Foam::fv::velocityRamping::add
(
const AlphaRhoFieldType& alphaRho,
fvMatrix<vector>& eqn,
const label fieldi
)
{
const DimensionedField<scalar, volMesh>& V = mesh_.V();
const scalar t = mesh_.time().value();
const scalar dt = mesh_.time().deltaTValue();
const vector dU = velocity_*(ramp_->value(t) - ramp_->value(t - dt));
const vector a = dU/mesh_.time().deltaTValue();
forAll(cells_, i)
{
const label c = cells_[i];
eqn.source()[c] -= V[c]*alphaRho[c]*a;
}
}
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2017 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2017-2018 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -60,6 +60,7 @@ Usage
direction | direction of the mean flow | yes |
speed | speed of the mean flow | yes |
waves | list of wave models to superimpose | yes |
ramp | ramping function for the mean flow speed | no | None
scale | scale factor along the mean flow direction | no | None
crossScale | scale factor across the mean flow direction | no | None
phi | Name of the flux field | no | phi
@ -91,6 +92,7 @@ Usage
angle 0;
}
);
ramp constant 1;
scale table ((100 1) (200 0));
crossScale constant 1;
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2017 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2017-2018 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -180,6 +180,7 @@ Foam::waveSuperposition::waveSuperposition(const objectRegistry& db)
speed_(0),
waveModels_(),
waveAngles_(),
ramp_(),
scale_(),
crossScale_()
{}
@ -193,6 +194,7 @@ Foam::waveSuperposition::waveSuperposition(const waveSuperposition& waves)
speed_(waves.speed_),
waveModels_(waves.waveModels_),
waveAngles_(waves.waveAngles_),
ramp_(waves.ramp_, false),
scale_(waves.scale_, false),
crossScale_(waves.crossScale_, false)
{}
@ -210,6 +212,12 @@ Foam::waveSuperposition::waveSuperposition
speed_(readScalar(dict.lookup("speed"))),
waveModels_(),
waveAngles_(),
ramp_
(
dict.found("ramp")
? Function1<scalar>::New("ramp", dict)
: autoPtr<Function1<scalar>>()
),
scale_
(
dict.found("scale")
@ -277,7 +285,7 @@ Foam::tmp<Foam::vectorField> Foam::waveSuperposition::ULiquid
vectorField xyz(p.size());
transformation(p, axes, u, xyz);
return UMean() + (velocity(t, xyz) & axes);
return UMean(t) + (velocity(t, xyz) & axes);
}
@ -294,7 +302,7 @@ Foam::tmp<Foam::vectorField> Foam::waveSuperposition::UGas
axes = tensor(- axes.x(), - axes.y(), axes.z());
return UMean() + (velocity(t, xyz) & axes);
return UMean(t) + (velocity(t, xyz) & axes);
}
@ -338,6 +346,10 @@ void Foam::waveSuperposition::write(Ostream& os) const
<< nl << decrIndent << indent << token::END_BLOCK << nl;
}
os << decrIndent << token::END_LIST << token::END_STATEMENT << nl;
if (ramp_.valid())
{
ramp_->writeData(os);
}
if (scale_.valid())
{
scale_->writeData(os);

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2017 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2017-2018 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -69,6 +69,9 @@ class waveSuperposition
//- The angle relative to the mean velocity at which the waves propagate
scalarList waveAngles_;
//- Ramp for the mean flow speed
const autoPtr<Function1<scalar>> ramp_;
//- Scaling in the flow direction
const autoPtr<Function1<scalar>> scale_;
@ -147,9 +150,9 @@ public:
tmp<scalarField> pGas(const scalar t, const vectorField& p) const;
//- Get the mean flow velocity
inline vector UMean() const
inline vector UMean(const scalar t) const
{
return direction_*speed_;
return (ramp_.valid() ? ramp_->value(t) : 1)*direction_*speed_;
}
//- Write