openfoam/src/waveModels/derivedPointPatchFields/waveMaker/waveMakerPointPatchVectorField.C

291 lines
7.9 KiB
C

/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation | Copyright (C) 2018 IH-Cantabria
-------------------------------------------------------------------------------
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 "waveMakerPointPatchVectorField.H"
#include "mathematicalConstants.H"
#include "pointPatchFields.H"
#include "addToRunTimeSelectionTable.H"
#include "Time.H"
#include "gravityMeshObject.H"
// * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * * //
const Foam::Enum<Foam::waveMakerPointPatchVectorField::motionTypes>
Foam::waveMakerPointPatchVectorField::motionTypeNames
({
{ motionTypes::piston, "piston" },
{ motionTypes::flap, "flap" }
});
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
const Foam::vector& Foam::waveMakerPointPatchVectorField::g()
{
const meshObjects::gravity& gf = meshObjects::gravity::New(db().time());
if (mag(gf.value()) < SMALL)
{
FatalErrorInFunction
<< "Gravity vector is not set. Please update "
<< gf.uniformDimensionedVectorField::path()
<< exit(FatalError);
}
return gf.value();
}
Foam::scalar Foam::waveMakerPointPatchVectorField::waveLength
(
const scalar h,
const scalar T
)
{
const scalar L0 = mag(g())*T*T/(constant::mathematical::twoPi);
scalar L = L0;
for (label i=1; i<=100; ++i)
{
L = L0*tanh(constant::mathematical::twoPi*h/L);
}
return L;
}
Foam::scalar Foam::waveMakerPointPatchVectorField::timeCoeff
(
const scalar t
) const
{
return max(0, min(t/rampTime_, 1));
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::waveMakerPointPatchVectorField::waveMakerPointPatchVectorField
(
const pointPatch& p,
const DimensionedField<vector, pointMesh>& iF
)
:
fixedValuePointPatchField<vector>(p, iF),
motionType_(motionTypes::piston),
n_(Zero),
gHat_(Zero),
initialDepth_(0),
wavePeriod_(0),
waveHeight_(0),
wavePhase_(0),
waveLength_(0),
rampTime_(0),
secondOrder_(false)
{}
Foam::waveMakerPointPatchVectorField::waveMakerPointPatchVectorField
(
const pointPatch& p,
const DimensionedField<vector, pointMesh>& iF,
const dictionary& dict
)
:
fixedValuePointPatchField<vector>(p, iF, dict, false),
motionType_(motionTypeNames.lookup("motionType", dict)),
n_(dict.get<vector>("n")),
gHat_(Zero),
initialDepth_(dict.get<scalar>("initialDepth")),
wavePeriod_(dict.get<scalar>("wavePeriod")),
waveHeight_(dict.get<scalar>("waveHeight")),
wavePhase_(dict.get<scalar>("wavePhase")),
waveLength_(this->waveLength(initialDepth_, wavePeriod_)),
rampTime_(dict.get<scalar>("rampTime")),
secondOrder_(dict.lookupOrDefault<bool>("secondOrder", false))
{
// Create the co-ordinate system
if (mag(n_) < SMALL)
{
FatalIOErrorInFunction(dict)
<< "Patch normal direction vector is not set. 'n' = " << n_
<< exit(FatalIOError);
}
n_ /= mag(n_);
gHat_ = (g() - n_*(n_&g()));
gHat_ /= mag(gHat_);
if (!dict.found("value"))
{
updateCoeffs();
}
}
Foam::waveMakerPointPatchVectorField::waveMakerPointPatchVectorField
(
const waveMakerPointPatchVectorField& ptf,
const pointPatch& p,
const DimensionedField<vector, pointMesh>& iF,
const pointPatchFieldMapper& mapper
)
:
fixedValuePointPatchField<vector>(ptf, p, iF, mapper),
motionType_(ptf.motionType_),
n_(ptf.n_),
gHat_(ptf.gHat_),
initialDepth_(ptf.initialDepth_),
wavePeriod_(ptf.wavePeriod_),
waveHeight_(ptf.waveHeight_),
wavePhase_(ptf.wavePhase_),
waveLength_(ptf.waveLength_),
rampTime_(ptf.rampTime_),
secondOrder_(ptf.secondOrder_)
{}
Foam::waveMakerPointPatchVectorField::waveMakerPointPatchVectorField
(
const waveMakerPointPatchVectorField& ptf,
const DimensionedField<vector, pointMesh>& iF
)
:
fixedValuePointPatchField<vector>(ptf, iF),
motionType_(ptf.motionType_),
n_(ptf.n_),
gHat_(ptf.gHat_),
initialDepth_(ptf.initialDepth_),
wavePeriod_(ptf.wavePeriod_),
waveHeight_(ptf.waveHeight_),
wavePhase_(ptf.wavePhase_),
waveLength_(ptf.waveLength_),
rampTime_(ptf.rampTime_),
secondOrder_(ptf.secondOrder_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::waveMakerPointPatchVectorField::updateCoeffs()
{
if (this->updated())
{
return;
}
const scalar t = db().time().value();
const scalar waveK = constant::mathematical::twoPi/waveLength_;
const scalar sigma = constant::mathematical::twoPi/wavePeriod_;
const scalar kh = waveK*initialDepth_;
switch (motionType_)
{
case motionTypes::flap:
{
const scalar m1 =
4*sinh(kh)/(sinh(2*kh) + 2*kh)*(sinh(kh) + (1 - cosh(kh))/kh);
scalar motionX = 0.5*waveHeight_/m1*sin(sigma*t);
if (secondOrder_)
{
motionX +=
sqr(waveHeight_)/(16*initialDepth_)
*(3*cosh(kh)/pow3(sinh(kh)) - 2/m1)
*sin(2*sigma*t);
}
const pointField& points = patch().localPoints();
const scalarField dz(-(points & gHat_) - initialDepth_);
Field<vector>::operator=
(
n_*timeCoeff(t)*motionX*(1 + dz/initialDepth_)
);
break;
}
case motionTypes::piston:
{
const scalar m1 = 2*(cosh(2*kh) - 1)/(sinh(2*kh) + 2*kh);
scalar motionX = 0.5*waveHeight_/m1*sin(sigma*t);
if (secondOrder_)
{
motionX +=
sqr(waveHeight_)
/(32*initialDepth_)*(3*cosh(kh)
/pow3(sinh(kh)) - 2/m1);
}
Field<vector>::operator=(n_*timeCoeff(t)*motionX);
break;
}
default:
{
FatalErrorInFunction
<< "Unhandled enumeration " << motionTypeNames[motionType_]
<< abort(FatalError);
}
}
fixedValuePointPatchField<vector>::updateCoeffs();
}
void Foam::waveMakerPointPatchVectorField::write(Ostream& os) const
{
pointPatchField<vector>::write(os);
os.writeEntry("motionType", motionTypeNames[motionType_]);
os.writeEntry("n", n_);
os.writeEntry("initialDepth", initialDepth_);
os.writeEntry("wavePeriod", wavePeriod_);
os.writeEntry("waveHeight", waveHeight_);
os.writeEntry("wavePhase", wavePhase_);
os.writeEntry("rampTime", rampTime_);
os.writeEntry("secondOrder", secondOrder_);
writeEntry("value", os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
makePointPatchTypeField
(
pointPatchVectorField,
waveMakerPointPatchVectorField
);
}
// ************************************************************************* //