diff --git a/applications/utilities/preProcessing/setWaves/Make/files b/applications/utilities/preProcessing/setWaves/Make/files new file mode 100644 index 0000000000..272ca7022b --- /dev/null +++ b/applications/utilities/preProcessing/setWaves/Make/files @@ -0,0 +1,3 @@ +setWaves.C + +EXE = $(FOAM_APPBIN)/setWaves diff --git a/applications/utilities/preProcessing/setWaves/Make/options b/applications/utilities/preProcessing/setWaves/Make/options new file mode 100644 index 0000000000..688c6306cd --- /dev/null +++ b/applications/utilities/preProcessing/setWaves/Make/options @@ -0,0 +1,9 @@ +EXE_INC = \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude \ + -I$(LIB_SRC)/waves/lnInclude + +EXE_LIBS = \ + -lfiniteVolume \ + -lmeshTools \ + -lwaves diff --git a/applications/utilities/preProcessing/setWaves/setWaves.C b/applications/utilities/preProcessing/setWaves/setWaves.C new file mode 100644 index 0000000000..895b3a9906 --- /dev/null +++ b/applications/utilities/preProcessing/setWaves/setWaves.C @@ -0,0 +1,252 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +Application + setWaves + +Description + +\*---------------------------------------------------------------------------*/ + +#include "fvCFD.H" +#include "levelSet.H" +#include "timeSelector.H" +#include "waveAlphaFvPatchScalarField.H" +#include "waveVelocityFvPatchVectorField.H" +#include "waveSuperposition.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +void addWaves +( + const waveSuperposition& waves, + const bool liquid, + volScalarField& alpha, + volVectorField& U +) +{ + const scalar t = alpha.time().value();; + const fvMesh& mesh = alpha.mesh(); + const pointMesh& pMesh = pointMesh::New(mesh); + + // Height fields + const scalarField heightC(waves.height(t, mesh.cellCentres())); + const scalarField heightP(waves.height(t, mesh.points())); + + // Velocity fields + const DimensionedField + UGasC + ( + IOobject("UGasC", mesh.time().timeName(), mesh), + mesh, + dimVelocity, + waves.UGas(t, mesh.cellCentres()) + ); + const DimensionedField + UGasP + ( + IOobject("UGasP", mesh.time().timeName(), mesh), + pMesh, + dimVelocity, + waves.UGas(t, mesh.points()) + ); + const DimensionedField + ULiquidC + ( + IOobject("ULiquidC", mesh.time().timeName(), mesh), + mesh, + dimVelocity, + waves.ULiquid(t, mesh.cellCentres()) + ); + const DimensionedField + ULiquidP + ( + IOobject("ULiquidP", mesh.time().timeName(), mesh), + pMesh, + dimVelocity, + waves.ULiquid(t, mesh.points()) + ); + + // Convert from the level set to volume-averaged fields and sum up + alpha.ref() += levelSetFraction(mesh, heightC, heightP, !liquid); + U.ref() += + levelSetAverage + ( + mesh, + heightC, + heightP, + UGasC, + UGasP, + ULiquidC, + ULiquidP + ); + + // Now set the boundary fields + forAll(alpha.boundaryField(), patchi) + { + fvPatchScalarField& alphap = alpha.boundaryFieldRef()[patchi]; + fvPatchVectorField& Up = U.boundaryFieldRef()[patchi]; + + const fvPatch& patch = alphap.patch(); + + // Height fields + const scalarField heightF(waves.height(t, patch.Cf())); + const scalarField heightP(waves.height(t, patch.patch().localPoints())); + + // Velocity fields + const vectorField UGasC(waves.UGas(t, mesh.cellCentres())); + const vectorField UGasP(waves.UGas(t, mesh.points())); + const vectorField ULiquidC(waves.ULiquid(t, mesh.cellCentres())); + const vectorField ULiquidP(waves.ULiquid(t, mesh.points())); + + alphap == alphap + levelSetFraction(patch, heightF, heightP, !liquid); + Up == Up + + levelSetAverage + ( + patch, + heightC, + heightP, + UGasC, + UGasP, + ULiquidC, + ULiquidP + ); + } +} + + +int main(int argc, char *argv[]) +{ + timeSelector::addOptions(false, false); + + Foam::argList::addOption + ( + "U", + "name", + "name of the velocity field, default is \"U\"" + ); + + Foam::argList::addOption + ( + "alpha", + "name", + "name of the volume fraction field, default is \"alpha\"" + ); + + #include "setRootCase.H" + #include "createTime.H" + + instantList timeDirs = timeSelector::selectIfPresent(runTime, args); + + #include "createMesh.H" + #include "readGravitationalAcceleration.H" + + forAll(timeDirs, timeI) + { + runTime.setTime(timeDirs[timeI], timeI); + + Info<< "Time = " << runTime.timeName() << nl << endl; + + mesh.readUpdate(); + + // Read the phase fraction and velocity fields + volScalarField alpha + ( + IOobject + ( + args.optionFound("alpha") ? args["alpha"] : "alpha", + runTime.timeName(), + mesh, + IOobject::MUST_READ + ), + mesh + ); + volVectorField U + ( + IOobject + ( + args.optionFound("U") ? args["U"] : "U", + runTime.timeName(), + mesh, + IOobject::MUST_READ + ), + mesh + ); + + // Zero the fields + alpha = dimensionedScalar("0", alpha.dimensions(), 0); + U = dimensionedVector("0", U.dimensions(), vector::zero); + forAll(alpha.boundaryField(), patchi) + { + alpha.boundaryFieldRef()[patchi] == 0; + U.boundaryFieldRef()[patchi] == vector::zero; + } + + // Loop the patches, looking for wave conditions + forAll(alpha.boundaryField(), patchi) + { + const fvPatchScalarField& alphap = alpha.boundaryField()[patchi]; + const fvPatchVectorField& Up = U.boundaryField()[patchi]; + + const bool isWave = isA(alphap); + + if (isA(Up) != isWave) + { + FatalErrorInFunction + << "The alpha condition on patch " << Up.patch().name() + << " is " << alphap.type() << " and the velocity condition" + << " is " << Up.type() << ". Wave boundary conditions must" + << " be set in pairs. If the alpha condition is " + << waveAlphaFvPatchScalarField::typeName + << " then the velocity condition must be " + << waveVelocityFvPatchVectorField::typeName + << " and vice-versa." << exit(FatalError); + } + + if (isWave) + { + Info<< "Adding waves from patch " << Up.patch().name() << endl; + addWaves + ( + refCast(Up).waves(), + refCast(alphap).liquid(), + alpha, + U + ); + } + } + + // Output + Info<< "Writing " << alpha.name() << nl; + alpha.write(); + Info<< "Writing " << U.name() << nl << endl; + U.write(); + } + + Info<< "End\n" << endl; + + return 0; +} + + +// ************************************************************************* // diff --git a/src/Allwmake b/src/Allwmake index 0e0ef5692a..e7fb45896c 100755 --- a/src/Allwmake +++ b/src/Allwmake @@ -78,6 +78,7 @@ functionObjects/Allwmake $targetType $* wmake $targetType sixDoFRigidBodyMotion wmake $targetType rigidBodyDynamics wmake $targetType rigidBodyMeshMotion +wmake $targetType waves #------------------------------------------------------------------------------ diff --git a/src/finiteVolume/cfdTools/general/levelSet/levelSet.C b/src/finiteVolume/cfdTools/general/levelSet/levelSet.C index 34f3c99d2c..dd1b262817 100644 --- a/src/finiteVolume/cfdTools/general/levelSet/levelSet.C +++ b/src/finiteVolume/cfdTools/general/levelSet/levelSet.C @@ -39,23 +39,29 @@ Foam::levelSetFraction const bool above ) { - DimensionedField sum + tmp> tResult ( - IOobject + new DimensionedField ( - "levelSetIntegral", - mesh.time().timeName(), - mesh - ), - mesh, - dimensionedScalar("0", dimVolume, 0) + IOobject + ( + "levelSetFraction", + mesh.time().timeName(), + mesh + ), + mesh, + dimensionedScalar("0", dimless, 0) + ) ); + DimensionedField& result = tResult.ref(); - forAll(sum, cI) + forAll(result, cI) { const List cellTetIs = polyMeshTetDecomposition::cellTetIndices(mesh, cI); + scalar v = 0, r = 0; + forAll(cellTetIs, cellTetI) { const tetIndices& tetIs = cellTetIs[cellTetI]; @@ -82,18 +88,22 @@ Foam::levelSetFraction levelP[pIB] }; + v += cut::volumeOp()(tet); + if (above) { - sum[cI] += tetCut(tet, level, cut::volumeOp(), cut::noOp()); + r += tetCut(tet, level, cut::volumeOp(), cut::noOp()); } else { - sum[cI] += tetCut(tet, level, cut::noOp(), cut::volumeOp()); + r += tetCut(tet, level, cut::noOp(), cut::volumeOp()); } } + + result[cI] = r/v; } - return sum/mesh.V(); + return tResult; } @@ -105,12 +115,15 @@ Foam::tmp Foam::levelSetFraction const bool above ) { - vectorField sum(patch.size(), vector::zero); + tmp tResult(new scalarField(patch.size(), 0)); + scalarField& result = tResult.ref(); - forAll(sum, fI) + forAll(result, fI) { const face& f = patch.patch().localFaces()[fI]; + vector a = vector::zero, r = vector::zero; + for(label eI = 0; eI < f.size(); ++ eI) { const edge e = f.faceEdge(eI); @@ -130,18 +143,22 @@ Foam::tmp Foam::levelSetFraction levelP[e[1]] }; + a += cut::areaOp()(tri); + if (above) { - sum[fI] += triCut(tri, level, cut::areaOp(), cut::noOp()); + r += triCut(tri, level, cut::areaOp(), cut::noOp()); } else { - sum[fI] += triCut(tri, level, cut::noOp(), cut::areaOp()); + r += triCut(tri, level, cut::noOp(), cut::areaOp()); } } + + result[fI] = a/magSqr(a) & r; } - return sum & patch.Sf()/sqr(patch.magSf()); + return tResult; } // ************************************************************************* // diff --git a/src/finiteVolume/cfdTools/general/levelSet/levelSetTemplates.C b/src/finiteVolume/cfdTools/general/levelSet/levelSetTemplates.C index 86d7d837a6..718506d056 100644 --- a/src/finiteVolume/cfdTools/general/levelSet/levelSetTemplates.C +++ b/src/finiteVolume/cfdTools/general/levelSet/levelSetTemplates.C @@ -42,28 +42,30 @@ Foam::tmp> Foam::levelSetAverage const DimensionedField& negativeP ) { - DimensionedField sum + tmp> tResult ( - IOobject + new DimensionedField ( - "levelSetIntegral", - mesh.time().timeName(), - mesh - ), - mesh, - dimensioned - ( - "0", - positiveC.dimensions()*dimVolume, - pTraits::zero + IOobject + ( + positiveC.name() + ":levelSetAverage", + mesh.time().timeName(), + mesh + ), + mesh, + dimensioned("0", positiveC.dimensions(), Zero) ) ); + DimensionedField& result = tResult.ref(); - forAll(sum, cI) + forAll(result, cI) { const List cellTetIs = polyMeshTetDecomposition::cellTetIndices(mesh, cI); + scalar v = 0; + Type r = Zero; + forAll(cellTetIs, cellTetI) { const tetIndices& tetIs = cellTetIs[cellTetI]; @@ -106,11 +108,15 @@ Foam::tmp> Foam::levelSetAverage negativeP[pIB] }); - sum[cI] += tetCut(tet, level, positive, negative); + v += cut::volumeOp()(tet); + + r += tetCut(tet, level, positive, negative); } + + result[cI] = r/v; } - return sum/mesh.V(); + return tResult; } @@ -128,12 +134,16 @@ Foam::tmp> Foam::levelSetAverage { typedef typename outerProduct::type sumType; - Field sum(patch.size(), pTraits::zero); + tmp> tResult(new Field(patch.size(), Zero)); + Field& result = tResult.ref(); - forAll(sum, fI) + forAll(result, fI) { const face& f = patch.patch().localFaces()[fI]; + vector a = vector::zero; + sumType r = Zero; + for(label eI = 0; eI < f.size(); ++ eI) { const edge e = f.faceEdge(eI); @@ -167,11 +177,15 @@ Foam::tmp> Foam::levelSetAverage negativeP[e[1]] }); - sum[fI] += triCut(tri, level, positive, negative); + a += cut::areaOp()(tri); + + r += triCut(tri, level, positive, negative); } + + result[fI] = a/magSqr(a) & r; } - return patch.Sf()/sqr(patch.magSf()) & sum; + return tResult; } diff --git a/src/waves/Make/files b/src/waves/Make/files new file mode 100644 index 0000000000..985d87616b --- /dev/null +++ b/src/waves/Make/files @@ -0,0 +1,11 @@ +waveModels/waveModel/waveModel.C +waveModels/waveModel/newWaveModel.C +waveModels/Airy/Airy.C +waveModels/Stokes2/Stokes2.C + +waveSuperposition/waveSuperposition.C + +derivedFvPatchFields/waveAlpha/waveAlphaFvPatchScalarField.C +derivedFvPatchFields/waveVelocity/waveVelocityFvPatchVectorField.C + +LIB = $(FOAM_LIBBIN)/libwaves diff --git a/src/waves/Make/options b/src/waves/Make/options new file mode 100644 index 0000000000..a3ae8da833 --- /dev/null +++ b/src/waves/Make/options @@ -0,0 +1,7 @@ +EXE_INC = \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude + +LIB_LIBS = \ + -lfiniteVolume \ + -lmeshTools diff --git a/src/waves/derivedFvPatchFields/waveAlpha/waveAlphaFvPatchScalarField.C b/src/waves/derivedFvPatchFields/waveAlpha/waveAlphaFvPatchScalarField.C new file mode 100644 index 0000000000..de3ea9fc78 --- /dev/null +++ b/src/waves/derivedFvPatchFields/waveAlpha/waveAlphaFvPatchScalarField.C @@ -0,0 +1,187 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +\*---------------------------------------------------------------------------*/ + +#include "waveAlphaFvPatchScalarField.H" +#include "waveVelocityFvPatchVectorField.H" +#include "addToRunTimeSelectionTable.H" +#include "levelSet.H" +#include "surfaceFields.H" +#include "volFields.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +Foam::tmp Foam::waveAlphaFvPatchScalarField::alpha() const +{ + const scalar t = db().time().timeOutputValue(); + + const waveVelocityFvPatchVectorField& Up = + refCast + ( + patch().lookupPatchField(UName_) + ); + const waveSuperposition& waves = Up.waves(); + + return + levelSetFraction + ( + patch(), + waves.height(t, patch().Cf()), + waves.height(t, patch().patch().localPoints()), + !liquid_ + ); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::waveAlphaFvPatchScalarField::waveAlphaFvPatchScalarField +( + const fvPatch& p, + const DimensionedField& iF +) +: + mixedFvPatchScalarField(p, iF), + UName_("U"), + liquid_(true), + inletOutlet_(true) +{ + refValue() = Zero; + refGrad() = Zero; + valueFraction() = 0; +} + + +Foam::waveAlphaFvPatchScalarField::waveAlphaFvPatchScalarField +( + const fvPatch& p, + const DimensionedField& iF, + const dictionary& dict +) +: + mixedFvPatchScalarField(p, iF), + UName_(dict.lookupOrDefault("U", "U")), + liquid_(dict.lookupOrDefault("liquid", true)), + inletOutlet_(dict.lookupOrDefault("inletOutlet", true)) +{ + if (dict.found("value")) + { + fvPatchScalarField::operator=(scalarField("value", dict, p.size())); + } + else + { + fvPatchScalarField::operator=(patchInternalField()); + } + + refValue() = *this; + refGrad() = Zero; + valueFraction() = 0; +} + + +Foam::waveAlphaFvPatchScalarField::waveAlphaFvPatchScalarField +( + const waveAlphaFvPatchScalarField& ptf, + const fvPatch& p, + const DimensionedField& iF, + const fvPatchFieldMapper& mapper +) +: + mixedFvPatchScalarField(ptf, p, iF, mapper), + UName_(ptf.UName_), + liquid_(ptf.liquid_), + inletOutlet_(ptf.inletOutlet_) +{} + + +Foam::waveAlphaFvPatchScalarField::waveAlphaFvPatchScalarField +( + const waveAlphaFvPatchScalarField& ptf +) +: + mixedFvPatchScalarField(ptf), + UName_(ptf.UName_), + liquid_(ptf.liquid_), + inletOutlet_(ptf.inletOutlet_) +{} + +Foam::waveAlphaFvPatchScalarField::waveAlphaFvPatchScalarField +( + const waveAlphaFvPatchScalarField& ptf, + const DimensionedField& iF +) +: + mixedFvPatchScalarField(ptf, iF), + UName_(ptf.UName_), + liquid_(ptf.liquid_), + inletOutlet_(ptf.inletOutlet_) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::waveAlphaFvPatchScalarField::updateCoeffs() +{ + if (updated()) + { + return; + } + + refValue() = alpha(); + + if (inletOutlet_) + { + const scalarField& phip = + patch().lookupPatchField("phi"); + + valueFraction() = 1 - pos(phip); + } + else + { + valueFraction() = 1; + } + + mixedFvPatchScalarField::updateCoeffs(); +} + + +void Foam::waveAlphaFvPatchScalarField::write +( + Ostream& os +) const +{ + mixedFvPatchScalarField::write(os); + writeEntryIfDifferent(os, "U", "U", UName_); + writeEntryIfDifferent(os, "inletOutlet", true, inletOutlet_); +} + + +// * * * * * * * * * * * * * * Build Macro Function * * * * * * * * * * * * // + +namespace Foam +{ + makePatchTypeField(fvPatchScalarField, waveAlphaFvPatchScalarField); +} + +// ************************************************************************* // diff --git a/src/waves/derivedFvPatchFields/waveAlpha/waveAlphaFvPatchScalarField.H b/src/waves/derivedFvPatchFields/waveAlpha/waveAlphaFvPatchScalarField.H new file mode 100644 index 0000000000..a224992706 --- /dev/null +++ b/src/waves/derivedFvPatchFields/waveAlpha/waveAlphaFvPatchScalarField.H @@ -0,0 +1,196 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +Class + Foam::waveAlphaFvPatchScalarField + +Group + grpGenericBoundaryConditions + +Description + This boundary condition provides a waveAlpha condition. This sets the phase + fraction to that specified by a superposition of wave models. All the + parameters are looked up from the corresponding velocity condition. + +Usage + \table + Property | Description | Req'd? | Default + U | name of the velocity field | no | U + liquid | is the alpha field that of the liquid | no | true + inletOutlet | does the condition behave like inletOutlet | no | true + \endtable + + Example of the boundary condition specification: + \verbatim + + { + type waveAlpha; + U U; + inletOutlet true; + } + \endverbatim + +SourceFiles + waveAlphaFvPatchScalarField.C + +\*---------------------------------------------------------------------------*/ + +#ifndef waveAlphaFvPatchScalarField_H +#define waveAlphaFvPatchScalarField_H + +#include "mixedFvPatchFields.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class waveAlphaFvPatchScalarField Declaration +\*---------------------------------------------------------------------------*/ + +class waveAlphaFvPatchScalarField +: + public mixedFvPatchScalarField +{ + // Private data + + //- Name of the velocity field + word UName_; + + //- Is this alpha field that of the liquid under the wave? + const bool liquid_; + + //- Act as an inlet/outlet patch? If false, the alpha field will be set + // by the wave model even during outflow. This may apply the wave model + // more accurately, but it might also be unstable. If true, the alpha + // boundary condition will be zero gradient when the flow reverses, as + // is usual. + const bool inletOutlet_; + + + // Private Member Functions + + //- Return the current modelled phase fraction field + tmp alpha() const; + + +public: + + //- Runtime type information + TypeName("waveAlpha"); + + + // Constructors + + //- Construct from patch and internal field + waveAlphaFvPatchScalarField + ( + const fvPatch&, + const DimensionedField& + ); + + //- Construct from patch, internal field and dictionary + waveAlphaFvPatchScalarField + ( + const fvPatch&, + const DimensionedField&, + const dictionary& + ); + + //- Construct by mapping given mixedTypeFvPatchField onto a new patch + waveAlphaFvPatchScalarField + ( + const waveAlphaFvPatchScalarField&, + const fvPatch&, + const DimensionedField&, + const fvPatchFieldMapper& + ); + + //- Construct as copy + waveAlphaFvPatchScalarField + ( + const waveAlphaFvPatchScalarField& + ); + + //- Construct and return a clone + virtual tmp clone() const + { + return tmp + ( + new waveAlphaFvPatchScalarField(*this) + ); + } + + //- Construct as copy setting internal field reference + waveAlphaFvPatchScalarField + ( + const waveAlphaFvPatchScalarField&, + const DimensionedField& + ); + + //- Construct and return a clone setting internal field reference + virtual tmp clone + ( + const DimensionedField& iF + ) const + { + return tmp + ( + new waveAlphaFvPatchScalarField(*this, iF) + ); + } + + + // Member functions + + // Access + + //- Access the liquid flag + bool liquid() const + { + return liquid_; + } + + + // 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/src/waves/derivedFvPatchFields/waveVelocity/waveVelocityFvPatchVectorField.C b/src/waves/derivedFvPatchFields/waveVelocity/waveVelocityFvPatchVectorField.C new file mode 100644 index 0000000000..22da4097b2 --- /dev/null +++ b/src/waves/derivedFvPatchFields/waveVelocity/waveVelocityFvPatchVectorField.C @@ -0,0 +1,173 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +\*---------------------------------------------------------------------------*/ + +#include "waveVelocityFvPatchVectorField.H" +#include "addToRunTimeSelectionTable.H" +#include "levelSet.H" +#include "surfaceFields.H" +#include "volFields.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +Foam::tmp Foam::waveVelocityFvPatchVectorField::U() const +{ + const scalar t = db().time().timeOutputValue(); + + return + levelSetAverage + ( + patch(), + waves_.height(t, patch().Cf()), + waves_.height(t, patch().patch().localPoints()), + waves_.UGas(t, patch().Cf())(), + waves_.UGas(t, patch().patch().localPoints())(), + waves_.ULiquid(t, patch().Cf())(), + waves_.ULiquid(t, patch().patch().localPoints())() + ); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::waveVelocityFvPatchVectorField::waveVelocityFvPatchVectorField +( + const fvPatch& p, + const DimensionedField& iF +) +: + directionMixedFvPatchVectorField(p, iF), + waves_(db()) +{ + refValue() = Zero; + refGrad() = Zero; + valueFraction() = Zero; +} + + +Foam::waveVelocityFvPatchVectorField::waveVelocityFvPatchVectorField +( + const fvPatch& p, + const DimensionedField& iF, + const dictionary& dict +) +: + directionMixedFvPatchVectorField(p, iF), + waves_(db(), dict) +{ + if (dict.found("value")) + { + fvPatchVectorField::operator=(vectorField("value", dict, p.size())); + } + else + { + fvPatchVectorField::operator=(patchInternalField()); + } + + refValue() = *this; + refGrad() = Zero; + valueFraction() = Zero; +} + + +Foam::waveVelocityFvPatchVectorField::waveVelocityFvPatchVectorField +( + const waveVelocityFvPatchVectorField& ptf, + const fvPatch& p, + const DimensionedField& iF, + const fvPatchFieldMapper& mapper +) +: + directionMixedFvPatchVectorField(ptf, p, iF, mapper), + waves_(ptf.waves_) +{} + + +Foam::waveVelocityFvPatchVectorField::waveVelocityFvPatchVectorField +( + const waveVelocityFvPatchVectorField& ptf +) +: + directionMixedFvPatchVectorField(ptf), + waves_(ptf.waves_) +{} + + +Foam::waveVelocityFvPatchVectorField::waveVelocityFvPatchVectorField +( + const waveVelocityFvPatchVectorField& ptf, + const DimensionedField& iF +) +: + directionMixedFvPatchVectorField(ptf, iF), + waves_(ptf.waves_) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::waveVelocityFvPatchVectorField::updateCoeffs() +{ + if (updated()) + { + return; + } + + refValue() = U(); + + const scalarField& phip = + patch().lookupPatchField("phi"); + + const symmTensorField nnp(sqr(patch().nf())); + + // Fix all components if inflow, just normal if outflow + valueFraction() = (1 - pos(phip))*I + pos(phip)*nnp; + + directionMixedFvPatchVectorField::updateCoeffs(); + directionMixedFvPatchVectorField::evaluate(); +} + + +void Foam::waveVelocityFvPatchVectorField::write +( + Ostream& os +) const +{ + directionMixedFvPatchVectorField::write(os); + waves_.write(os); +} + + +// * * * * * * * * * * * * * * Build Macro Function * * * * * * * * * * * * // + +namespace Foam +{ + makePatchTypeField + ( + fvPatchVectorField, + waveVelocityFvPatchVectorField + ); +} + +// ************************************************************************* // diff --git a/src/waves/derivedFvPatchFields/waveVelocity/waveVelocityFvPatchVectorField.H b/src/waves/derivedFvPatchFields/waveVelocity/waveVelocityFvPatchVectorField.H new file mode 100644 index 0000000000..2d259703ed --- /dev/null +++ b/src/waves/derivedFvPatchFields/waveVelocity/waveVelocityFvPatchVectorField.H @@ -0,0 +1,211 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +Class + Foam::waveVelocityFvPatchVectorField + +Group + grpGenericBoundaryConditions + +Description + This boundary condition provides a waveVelocity condition. This sets the + velocity to that specified by a superposition of wave models. The + corresponding phase fraction condition looks this condition up and re-uses + the wave modelling. + +Usage + \table + Property | Description | Req'd? | Default + origin | origin of the wave coordinate system | yes | + direction | direction of the mean flow | yes | + speed | speed of the mean flow | yes | + waves | list of wave models to superimpose | yes | + scale | scale factor along the mean flow direction | no | None + crossScale | scale factor across the mean flow direction | no | None + \endtable + + Example of the boundary condition specification: + \verbatim + + { + type waveVelocity; + origin (0 25 0); + direction (1 0 0); + speed 2; + waves + ( + Airy + { + length 40; + amplitude 0.5; + phase 0; + angle 0; + } + Airy + { + length 20; + amplitude 0.25; + phase 1.5708; + angle 0; + } + ); + scale table ((100 1) (200 0)); + crossScale constant 1; + } + \endverbatim + +SourceFiles + waveVelocityFvPatchVectorField.C + +\*---------------------------------------------------------------------------*/ + +#ifndef waveVelocityFvPatchVectorField_H +#define waveVelocityFvPatchVectorField_H + +#include "directionMixedFvPatchFields.H" +#include "waveSuperposition.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class waveVelocityFvPatchVectorField Declaration +\*---------------------------------------------------------------------------*/ + +class waveVelocityFvPatchVectorField +: + public directionMixedFvPatchVectorField +{ + // Private data + + //- Wave superposition + const waveSuperposition waves_; + + + // Private Member Functions + + //- Return the current modelled velocity field + tmp U() const; + + +public: + + //- Runtime type information + TypeName("waveVelocity"); + + + // Constructors + + //- Construct from patch and internal field + waveVelocityFvPatchVectorField + ( + const fvPatch&, + const DimensionedField& + ); + + //- Construct from patch, internal field and dictionary + waveVelocityFvPatchVectorField + ( + const fvPatch&, + const DimensionedField&, + const dictionary& + ); + + //- Construct by mapping given mixedTypeFvPatchField onto a new patch + waveVelocityFvPatchVectorField + ( + const waveVelocityFvPatchVectorField&, + const fvPatch&, + const DimensionedField&, + const fvPatchFieldMapper& + ); + + //- Construct as copy + waveVelocityFvPatchVectorField + ( + const waveVelocityFvPatchVectorField& + ); + + //- Construct and return a clone + virtual tmp clone() const + { + return tmp + ( + new waveVelocityFvPatchVectorField(*this) + ); + } + + //- Construct as copy setting internal field reference + waveVelocityFvPatchVectorField + ( + const waveVelocityFvPatchVectorField&, + const DimensionedField& + ); + + //- Construct and return a clone setting internal field reference + virtual tmp clone + ( + const DimensionedField& iF + ) const + { + return tmp + ( + new waveVelocityFvPatchVectorField(*this, iF) + ); + } + + + // Member functions + + // Access + + //- Access the wave models + const waveSuperposition& waves() const + { + return waves_; + } + + + // 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/src/waves/waveModels/Airy/Airy.C b/src/waves/waveModels/Airy/Airy.C new file mode 100644 index 0000000000..ff94fe3d28 --- /dev/null +++ b/src/waves/waveModels/Airy/Airy.C @@ -0,0 +1,99 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +\*---------------------------------------------------------------------------*/ + +#include "Airy.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace waveModels +{ + defineTypeNameAndDebug(Airy, 0); + addToRunTimeSelectionTable(waveModel, Airy, objectRegistry); +} +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::waveModels::Airy::Airy +( + const objectRegistry& db, + const dictionary& dict +) +: + waveModel(db, dict) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::waveModels::Airy::~Airy() +{} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +Foam::tmp Foam::waveModels::Airy::elevation +( + const scalar t, + const scalar u, + const scalarField& x +) const +{ + return amplitude(t)*cos(angle(t, u, x)); +} + + +Foam::tmp Foam::waveModels::Airy::velocity +( + const scalar t, + const scalar u, + const vector2DField& xz +) const +{ + const scalarField x(xz.component(0)); + const scalarField z(xz.component(1)); + + const scalarField phi(angle(t, u, x)); + const scalarField kz(- k()*mag(z - elevation(t, u, x))); + const scalar wa = omega(u)*amplitude(t); + + if (shallow()) + { + const scalar kh = k()*depth(); + const scalarField khz((kh + kz)*pos(kh + kz)); + return wa*zip(cosh(khz)*cos(phi), sinh(khz)*sin(phi))/sinh(kh); + } + else + { + return wa*exp(kz)*zip(cos(phi), sin(phi)); + } +} + + +// ************************************************************************* // diff --git a/src/waves/waveModels/Airy/Airy.H b/src/waves/waveModels/Airy/Airy.H new file mode 100644 index 0000000000..7616145468 --- /dev/null +++ b/src/waves/waveModels/Airy/Airy.H @@ -0,0 +1,117 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +Class + Foam::waveModels::Airy + +Description + First-order wave model. + + Reference: + \verbatim + "On the Theory of Oscillatory Waves" + G G Stokes + Transactions of the Cambridge Philosophical Society (1847), Volume 8, + Pages 441-455, Equations 18 and 19 (leading terms only) + \endverbatim + +SourceFiles + Airy.C + +\*---------------------------------------------------------------------------*/ + +#ifndef Airy_H +#define Airy_H + +#include "waveModel.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace waveModels +{ + +/*---------------------------------------------------------------------------*\ + Class Airy Declaration +\*---------------------------------------------------------------------------*/ + +class Airy +: + public waveModel +{ +public: + + //- Runtime type information + TypeName("Airy"); + + + // Constructors + + //- Construct from a database and a dictionary + Airy(const objectRegistry& db, const dictionary& dict); + + //- Construct a clone + virtual autoPtr clone() const + { + return autoPtr(new Airy(*this)); + } + + + //- Destructor + virtual ~Airy(); + + + // Member Functions + + //- Get the wave elevation at a given time, mean velocity and local + // coordinates. Local x is aligned with the mean velocity. + virtual tmp elevation + ( + const scalar t, + const scalar u, + const scalarField& x + ) const; + + //- Get the wave velocity at a given time, mean velocity and local + // coordinates. Local x is aligned with the mean velocity, and z with + // negative gravity. + virtual tmp velocity + ( + const scalar t, + const scalar u, + const vector2DField& xz + ) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace waveModels +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/waves/waveModels/Stokes2/Stokes2.C b/src/waves/waveModels/Stokes2/Stokes2.C new file mode 100644 index 0000000000..9b6d7d50fe --- /dev/null +++ b/src/waves/waveModels/Stokes2/Stokes2.C @@ -0,0 +1,116 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +\*---------------------------------------------------------------------------*/ + +#include "Stokes2.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace waveModels +{ + defineTypeNameAndDebug(Stokes2, 0); + addToRunTimeSelectionTable(waveModel, Stokes2, objectRegistry); +} +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::waveModels::Stokes2::Stokes2 +( + const objectRegistry& db, + const dictionary& dict +) +: + Airy(db, dict) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::waveModels::Stokes2::~Stokes2() +{} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +Foam::tmp Foam::waveModels::Stokes2::elevation +( + const scalar t, + const scalar u, + const scalarField& x +) const +{ + const scalar kh = k()*depth(); + const scalarField correction(k()*sqr(amplitude(t))*cos(2*angle(t, u, x))/2); + + if (shallow()) + { + const scalar factor((3/sqr(tanh(kh)) - 1)/tanh(kh)/2); + return Airy::elevation(t, u, x) + factor*correction; + } + else + { + return Airy::elevation(t, u, x) + correction; + } +} + + +Foam::tmp Foam::waveModels::Stokes2::velocity +( + const scalar t, + const scalar u, + const vector2DField& xz +) const +{ + if (shallow()) + { + const scalarField x(xz.component(0)); + const scalarField z(xz.component(1)); + + const scalarField phi(angle(t, u, x)); + const scalarField kz(- k()*mag(z - elevation(t, u, x))); + const scalar kh = k()*depth(); + const scalarField khz((kh + kz)*pos(kh + kz)); + const scalar kwaa = k()*omega(u)*sqr(amplitude(t)); + + return + Airy::velocity(t, u, xz) + + 6*kwaa*zip + ( + cosh(2*khz)*cos(2*phi), + sinh(2*khz)*sin(2*phi) + )/pow4(sinh(kh)); + } + else + { + return Airy::velocity(t, u, xz); + } +} + + +// ************************************************************************* // diff --git a/src/waves/waveModels/Stokes2/Stokes2.H b/src/waves/waveModels/Stokes2/Stokes2.H new file mode 100644 index 0000000000..f36c53632c --- /dev/null +++ b/src/waves/waveModels/Stokes2/Stokes2.H @@ -0,0 +1,117 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +Class + Foam::waveModels::Stokes2 + +Description + Second-order wave model. + + Reference: + \verbatim + "On the Theory of Oscillatory Waves" + G G Stokes + Transactions of the Cambridge Philosophical Society (1847), Volume 8, + Pages 441-455, Equations 18 and 19 + \endverbatim + +SourceFiles + Stokes2.C + +\*---------------------------------------------------------------------------*/ + +#ifndef Stokes2_H +#define Stokes2_H + +#include "Airy.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace waveModels +{ + +/*---------------------------------------------------------------------------*\ + Class Stokes2 Declaration +\*---------------------------------------------------------------------------*/ + +class Stokes2 +: + public Airy +{ +public: + + //- Runtime type information + TypeName("Stokes2"); + + + // Constructors + + //- Construct from a database and a dictionary + Stokes2(const objectRegistry& db, const dictionary& dict); + + //- Construct a clone + virtual autoPtr clone() const + { + return autoPtr(new Stokes2(*this)); + } + + + //- Destructor + virtual ~Stokes2(); + + + // Member Functions + + //- Get the wave elevation at a given time, mean velocity and local + // coordinates. Local x is aligned with the mean velocity. + virtual tmp elevation + ( + const scalar t, + const scalar u, + const scalarField& x + ) const; + + //- Get the wave velocity at a given time, mean velocity and local + // coordinates. Local x is aligned with the mean velocity, and z with + // negative gravity. + virtual tmp velocity + ( + const scalar t, + const scalar u, + const vector2DField& xz + ) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam +} // End namespace waveModels + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/waves/waveModels/waveModel/newWaveModel.C b/src/waves/waveModels/waveModel/newWaveModel.C new file mode 100644 index 0000000000..f176a63e20 --- /dev/null +++ b/src/waves/waveModels/waveModel/newWaveModel.C @@ -0,0 +1,68 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +\*---------------------------------------------------------------------------*/ + +#include "waveModel.H" + +// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * // + +Foam::autoPtr Foam::waveModel::New +( + const objectRegistry& db, + const dictionary& dict +) +{ + return waveModel::New(dict.lookup("type"), db, dict); +} + + +Foam::autoPtr Foam::waveModel::New +( + const word& type, + const objectRegistry& db, + const dictionary& dict +) +{ + if (debug) + { + Info<< "Selecting " << waveModel::typeName << " " << type << endl; + } + + objectRegistryConstructorTable::iterator cstrIter = + objectRegistryConstructorTablePtr_->find(type); + + if (cstrIter == objectRegistryConstructorTablePtr_->end()) + { + FatalErrorInFunction + << "Unknown " << waveModel::typeName << " " << type << nl << nl + << "Valid model types are:" << nl + << objectRegistryConstructorTablePtr_->sortedToc() + << exit(FatalError); + } + + return cstrIter()(db, dict); +} + + +// ************************************************************************* // diff --git a/src/waves/waveModels/waveModel/waveModel.C b/src/waves/waveModels/waveModel/waveModel.C new file mode 100644 index 0000000000..a461d13e79 --- /dev/null +++ b/src/waves/waveModels/waveModel/waveModel.C @@ -0,0 +1,119 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +\*---------------------------------------------------------------------------*/ + +#include "waveModel.H" +#include "mathematicalConstants.H" +#include "Time.H" +#include "uniformDimensionedFields.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(waveModel, 0); + defineRunTimeSelectionTable(waveModel, objectRegistry); +} + + +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +Foam::scalar Foam::waveModel::k() const +{ + return 2*Foam::constant::mathematical::pi/length_; +} + + +Foam::scalar Foam::waveModel::sigma() const +{ + const uniformDimensionedVectorField& g = + db_.lookupObject("g"); + + return sqrt(mag(g.value())*k()*tanh(k()*depth())); +} + + +Foam::scalar Foam::waveModel::omega(const scalar u) const +{ + return sigma() + k()*u; +} + + +Foam::tmp Foam::waveModel::angle +( + const scalar t, + const scalar u, + const scalarField& x +) const +{ + return k()*x - omega(u)*t; +} + + +bool Foam::waveModel::shallow() const +{ + return k()*depth() < log(GREAT); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::waveModel::waveModel(const waveModel& wave) +: + db_(wave.db_), + length_(wave.length_), + amplitude_(wave.amplitude_, false), + phase_(wave.phase_), + depth_(wave.depth_) +{} + + +Foam::waveModel::waveModel(const objectRegistry& db, const dictionary& dict) +: + db_(db), + length_(readScalar(dict.lookup("length"))), + amplitude_(Function1::New("amplitude", dict)), + phase_(readScalar(dict.lookup("phase"))), + depth_(dict.lookupOrDefault("depth", GREAT)) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::waveModel::~waveModel() +{} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +void Foam::waveModel::write(Ostream& os) const +{ + os.writeKeyword("length") << length_ << token::END_STATEMENT << nl; + amplitude_->writeData(os); + os.writeKeyword("phase") << phase_ << token::END_STATEMENT << nl; + os.writeKeyword("depth") << depth_ << token::END_STATEMENT << nl; +} + + +// ************************************************************************* // diff --git a/src/waves/waveModels/waveModel/waveModel.H b/src/waves/waveModels/waveModel/waveModel.H new file mode 100644 index 0000000000..e972464c02 --- /dev/null +++ b/src/waves/waveModels/waveModel/waveModel.H @@ -0,0 +1,212 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +Class + Foam::waveModel + +Description + Generic base class for waves. Derived classes must implement field + functions which return the elevation above the wave surface and the + velocity field, both as a function of position. + +SourceFiles + waveModel.C + +\*---------------------------------------------------------------------------*/ + +#ifndef waveModel_H +#define waveModel_H + +#include "objectRegistry.H" +#include "dictionary.H" +#include "Function1.H" +#include "runTimeSelectionTables.H" +#include "vectorField.H" +#include "vector2DField.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class waveModel Declaration +\*---------------------------------------------------------------------------*/ + +class waveModel +{ + // Private data + + //- Reference to the database + const objectRegistry& db_; + + //- Peak-to-peak length [m] + const scalar length_; + + //- Peak-to-mean amplitude [m] + autoPtr> amplitude_; + + //- Phase offset [rad] + const scalar phase_; + + //- Depth [m] + const scalar depth_; + + +protected: + + // Protected Member Functions + + //- The angular wavenumber [rad/m] + scalar k() const; + + //- The intrinsic angular frequency [rad/s] + scalar sigma() const; + + //- The observed angular frequency [rad/s] + scalar omega(const scalar u) const; + + //- Angle of the oscillation [rad] + tmp angle + ( + const scalar t, + const scalar u, + const scalarField& x + ) const; + + //- Return whether shallow effects are to be included + bool shallow() const; + + +public: + + //- Runtime type information + TypeName("waveModel"); + + + // Declare runtime construction + declareRunTimeSelectionTable + ( + autoPtr, + waveModel, + objectRegistry, + (const objectRegistry& db, const dictionary& dict), + (db, dict) + ); + + + // Constructors + + //- Construct a copy + waveModel(const waveModel& wave); + + //- Construct from a database and a dictionary + waveModel(const objectRegistry& db, const dictionary& dict); + + //- Construct a clone + virtual autoPtr clone() const = 0; + + + // Selectors + + //- Select + static autoPtr New + ( + const objectRegistry& db, + const dictionary& dict + ); + + //- Select + static autoPtr New + ( + const word& type, + const objectRegistry& db, + const dictionary& dict + ); + + + //- Destructor + virtual ~waveModel(); + + + // Member Functions + + // Access + + //- Get the length + scalar length() const + { + return length_; + } + + //- Get the amplitude + scalar amplitude(const scalar t) const + { + return amplitude_->value(t); + } + + //- Get the phase + scalar phase() const + { + return phase_; + } + + //- Get the depth + scalar depth() const + { + return depth_; + } + + //- Get the wave elevation at a given time, mean velocity and local + // coordinates. Local x is aligned with the mean velocity. + virtual tmp elevation + ( + const scalar t, + const scalar u, + const scalarField& x + ) const = 0; + + //- Get the wave velocity at a given time, mean velocity and local + // coordinates. Local x is aligned with the mean velocity, and z with + // negative gravity. + virtual tmp velocity + ( + const scalar t, + const scalar u, + const vector2DField& xz + ) const = 0; + + //- Write + virtual void write(Ostream& os) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/waves/waveSuperposition/waveSuperposition.C b/src/waves/waveSuperposition/waveSuperposition.C new file mode 100644 index 0000000000..ca762e68cb --- /dev/null +++ b/src/waves/waveSuperposition/waveSuperposition.C @@ -0,0 +1,295 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +\*---------------------------------------------------------------------------*/ + +#include "waveSuperposition.H" +#include "uniformDimensionedFields.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::waveSuperposition::transformation +( + const vectorField& p, + tensor& axes, + scalar& u, + vectorField& xyz +) const +{ + const uniformDimensionedVectorField& g = + db_.lookupObject("g"); + const scalar magG = mag(g.value()); + const vector gHat = g.value()/magG; + + const vector dSurf = direction_ - gHat*(gHat & direction_); + const scalar magDSurf = mag(dSurf); + const vector dSurfHat = direction_/magDSurf; + + axes = tensor(dSurfHat, - gHat ^ dSurfHat, - gHat); + + u = speed_*magDSurf; + + xyz = axes & (p - origin_); +} + + +Foam::tmp Foam::waveSuperposition::elevation +( + const scalar t, + const vector2DField& xy +) const +{ + scalarField result(xy.size(), 0); + + forAll(waveModels_, wavei) + { + const vector2D d(cos(waveAngles_[wavei]), sin(waveAngles_[wavei])); + result += waveModels_[wavei].elevation(t, d.x()*speed_, d & xy); + } + + return scale(xy)*result; +} + + +Foam::tmp Foam::waveSuperposition::velocity +( + const scalar t, + const vectorField& xyz +) const +{ + vectorField result(xyz.size(), vector::zero); + + forAll(waveModels_, wavei) + { + const vector2D d(cos(waveAngles_[wavei]), sin(waveAngles_[wavei])); + const vector2DField xz + ( + zip + ( + d & zip(xyz.component(0), xyz.component(1)), + tmp(xyz.component(2)) + ) + ); + const vector2DField uw + ( + waveModels_[wavei].velocity(t, d.x()*speed_, xz) + ); + result += zip + ( + d.x()*uw.component(0), + d.y()*uw.component(0), + uw.component(1) + ); + } + + tmp s = scale(zip(xyz.component(0), xyz.component(1))); + + return s*result; +} + + +Foam::tmp Foam::waveSuperposition::scale +( + const vector2DField& xy +) const +{ + tmp tResult(new scalarField(xy.size(), 1)); + scalarField& result = tResult.ref(); + + if (scale_.valid()) + { + const scalarField x(xy.component(0)); + forAll(result, i) + { + result[i] *= scale_->value(x[i]); + } + } + + if (crossScale_.valid()) + { + const scalarField y(xy.component(1)); + forAll(result, i) + { + result[i] *= crossScale_->value(y[i]); + } + } + + return tResult; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::waveSuperposition::waveSuperposition(const objectRegistry& db) +: + db_(db), + origin_(vector::zero), + direction_(vector(1, 0, 0)), + speed_(0), + waveModels_(), + waveAngles_(), + scale_(), + crossScale_() +{} + + +Foam::waveSuperposition::waveSuperposition(const waveSuperposition& waves) +: + db_(waves.db_), + origin_(waves.origin_), + direction_(waves.direction_), + speed_(waves.speed_), + waveModels_(waves.waveModels_), + waveAngles_(waves.waveAngles_), + scale_(waves.scale_, false), + crossScale_(waves.crossScale_, false) +{} + + +Foam::waveSuperposition::waveSuperposition +( + const objectRegistry& db, + const dictionary& dict +) +: + db_(db), + origin_(dict.lookup("origin")), + direction_(dict.lookup("direction")), + speed_(readScalar(dict.lookup("speed"))), + waveModels_(), + waveAngles_(), + scale_ + ( + dict.found("scale") + ? Function1::New("scale", dict) + : autoPtr>() + ), + crossScale_ + ( + dict.found("crossScale") + ? Function1::New("crossScale", dict) + : autoPtr>() + ) +{ + const PtrList waveEntries(dict.lookup("waves")); + + waveModels_.setSize(waveEntries.size()); + waveAngles_.setSize(waveEntries.size()); + + forAll(waveEntries, wavei) + { + const dictionary waveDict = waveEntries[wavei].dict(); + waveModels_.set + ( + wavei, + waveModel::New(waveDict.dictName(), db, waveDict) + ); + waveAngles_[wavei] = readScalar(waveDict.lookup("angle")); + } +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::waveSuperposition::~waveSuperposition() +{} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +Foam::tmp Foam::waveSuperposition::height +( + const scalar t, + const vectorField& p +) const +{ + tensor axes; + scalar u; + vectorField xyz(p.size()); + transformation(p, axes, u, xyz); + + return + xyz.component(2) + - elevation(t, zip(xyz.component(0), xyz.component(1))); +} + + +Foam::tmp Foam::waveSuperposition::ULiquid +( + const scalar t, + const vectorField& p +) const +{ + tensor axes; + scalar u; + vectorField xyz(p.size()); + transformation(p, axes, u, xyz); + + return direction_*speed_ + (velocity(t, xyz) & axes); +} + + +Foam::tmp Foam::waveSuperposition::UGas +( + const scalar t, + const vectorField& p +) const +{ + tensor axes; + scalar u; + vectorField xyz(p.size()); + transformation(p, axes, u, xyz); + + axes = tensor(- axes.x(), - axes.y(), axes.z()); + + return direction_*speed_ + (velocity(t, xyz) & axes); +} + + +void Foam::waveSuperposition::write(Ostream& os) const +{ + os.writeKeyword("origin") << origin_ << token::END_STATEMENT << nl; + os.writeKeyword("direction") << direction_ << token::END_STATEMENT << nl; + os.writeKeyword("speed") << speed_ << token::END_STATEMENT << nl; + os.writeKeyword("waves") << nl << token::BEGIN_LIST << nl << incrIndent; + forAll(waveModels_, wavei) + { + os.writeKeyword(waveModels_[wavei].type()) << nl << indent + << token::BEGIN_BLOCK << nl << incrIndent; + waveModels_[wavei].write(os); + os.writeKeyword("angle") << waveAngles_[wavei] << token::END_STATEMENT + << nl << decrIndent << indent << token::END_BLOCK << nl; + } + os << decrIndent << token::END_LIST << token::END_STATEMENT << nl; + if (scale_.valid()) + { + scale_->writeData(os); + } + if (crossScale_.valid()) + { + crossScale_->writeData(os); + } +} + + +// ************************************************************************* // diff --git a/src/waves/waveSuperposition/waveSuperposition.H b/src/waves/waveSuperposition/waveSuperposition.H new file mode 100644 index 0000000000..099a657dfb --- /dev/null +++ b/src/waves/waveSuperposition/waveSuperposition.H @@ -0,0 +1,155 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +Class + Foam::waveSuperposition + +Description + A wrapper around a list of wave models. Superimposes the modelled values + of elevation and velocity. + +SourceFiles + waveSuperposition.C + +\*---------------------------------------------------------------------------*/ + +#ifndef waveSuperposition_H +#define waveSuperposition_H + +#include "waveModel.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class waveSuperposition Declaration +\*---------------------------------------------------------------------------*/ + +class waveSuperposition +{ + // Private data + + //- Reference to the database + const objectRegistry& db_; + + //- The origin of the wave coordinate system + const vector origin_; + + //- The mean flow direction + const vector direction_; + + //- The mean flow speed + const scalar speed_; + + //- Wave models to superimpose + PtrList waveModels_; + + //- The angle relative to the mean velocity at which the waves propagate + scalarList waveAngles_; + + //- Scaling in the flow direction + const autoPtr> scale_; + + //- Scaling perpendicular to the flow direction + const autoPtr> crossScale_; + + + // Private Member Functions + + //- Get the transformation to actual coordinates + void transformation + ( + const vectorField& p, + tensor& axes, + scalar& u, + vectorField& xyz + ) const; + + //- Get the wave elevation relative to the mean at a given time, mean + // velocity and local coordinates. Local x is aligned with the mean + // velocity, and y is perpendicular to both x and gravity. + tmp elevation + ( + const scalar t, + const vector2DField& xy + ) const; + + //- Get the wave velocity at a given time, mean velocity and local + // coordinates. Local x is aligned with the mean velocity, z with + // negative gravity, and y is perpendicular to both. + tmp velocity + ( + const scalar t, + const vectorField& xyz + ) const; + + //- Get the scaling factor, calculated from the optional scaling + // functions. X and y are the same as for the elevation method. + tmp scale(const vector2DField& xy) const; + + +public: + + // Constructors + + //- Construct from a database + waveSuperposition(const objectRegistry& db); + + //- Construct a copy + waveSuperposition(const waveSuperposition& waves); + + //- Construct from a database and gravity + waveSuperposition(const objectRegistry& db, const dictionary& dict); + + + //- Destructor + ~waveSuperposition(); + + + // Member Functions + + //- Get the height above the waves at a given time and global positions + tmp height(const scalar t, const vectorField& p) const; + + //- Get the liquid velocity at a given time and global positions + tmp ULiquid(const scalar t, const vectorField& p) const; + + //- Get the gas velocity at a given time and global positions + tmp UGas(const scalar t, const vectorField& p) const; + + //- Write + void write(Ostream&) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* //