Skip to content
Permalink
Browse files

waves: Split mean flow from wave perturbation modelling

In order to increase the flexibility of the wave library, the mean flow
handling has been removed from the waveSuperposition class. This makes
waveSuperposition work purely in terms of perturbations to a mean
background flow.

The input has also been split, with waves now defined as region-wide
settings in constant/waveProperties. The mean flow parameters are sill
defined by the boundary conditions.

The new format of the velocity boundary is much simpler. Only a mean
flow velocity is required.

    In 0/U:

        boundaryField
        {
            inlet
            {
                type            waveVelocity;
                UMean           (2 0 0);
            }
            // etc ...
        }

Other wave boundary conditions have not changed.

The constant/waveProperties file contains the wave model selections and
the settings to define the associated coordinate system and scaling
functions:

    In constant/waveProperties:

        origin          (0 0 0);
        direction       (1 0 0);
        waves
        (
            Airy
            {
                length      300;
                amplitude   2.5;
                phase       0;
                angle       0;
            }
        );
        scale           table ((1200 1) (1800 0));
        crossScale      constant 1;

setWaves has been changed to use a system/setWavesDict file rather than
relying on command-line arguments. It also now requires a mean velocity
to be specified in order to prevent ambiguities associated with multiple
inlet patches. An example is shown below:

    In system/setWavesDict:

        alpha   alpha.water;
        U       U;
        liquid  true;
        UMean   (1 0 0);
  • Loading branch information...
Will Bainbridge
Will Bainbridge committed Dec 6, 2018
1 parent bd2f275 commit 967edc9425152f068a9614598c6aedf0254b9d0a
Showing with 489 additions and 472 deletions.
  1. +66 −165 applications/utilities/preProcessing/setWaves/setWaves.C
  2. +31 −0 etc/caseDicts/annotated/setWavesDict
  3. +7 −8 src/waves/derivedFvPatchFields/waveAlpha/waveAlphaFvPatchScalarField.C
  4. +6 −1 src/waves/derivedFvPatchFields/waveAlpha/waveAlphaFvPatchScalarField.H
  5. +16 −16 src/waves/derivedFvPatchFields/wavePressure/wavePressureFvPatchScalarField.C
  6. +4 −1 src/waves/derivedFvPatchFields/wavePressure/wavePressureFvPatchScalarField.H
  7. +24 −20 src/waves/derivedFvPatchFields/waveVelocity/waveVelocityFvPatchVectorField.C
  8. +25 −40 src/waves/derivedFvPatchFields/waveVelocity/waveVelocityFvPatchVectorField.H
  9. +5 −10 src/waves/waveModels/Airy/Airy.C
  10. +8 −13 src/waves/waveModels/Airy/Airy.H
  11. +4 −6 src/waves/waveModels/Stokes2/Stokes2.C
  12. +5 −7 src/waves/waveModels/Stokes2/Stokes2.H
  13. +6 −8 src/waves/waveModels/Stokes5/Stokes5.C
  14. +5 −7 src/waves/waveModels/Stokes5/Stokes5.H
  15. +5 −10 src/waves/waveModels/solitary/solitary.C
  16. +8 −13 src/waves/waveModels/solitary/solitary.H
  17. +8 −11 src/waves/waveModels/waveModel/waveModel.H
  18. +56 −75 src/waves/waveSuperposition/waveSuperposition.C
  19. +74 −31 src/waves/waveSuperposition/waveSuperposition.H
  20. +1 −14 tutorials/multiphase/interFoam/RAS/DTCHullWave/0/U.orig
  21. +36 −0 tutorials/multiphase/interFoam/RAS/DTCHullWave/constant/waveProperties
  22. +27 −0 tutorials/multiphase/interFoam/RAS/DTCHullWave/system/setWavesDict
  23. +2 −16 tutorials/multiphase/interFoam/laminar/wave/0/U.orig
  24. +38 −0 tutorials/multiphase/interFoam/laminar/wave/constant/waveProperties
  25. +22 −0 tutorials/multiphase/interFoam/laminar/wave/system/setWavesDict
@@ -30,45 +30,77 @@ Description
\*---------------------------------------------------------------------------*/

#include "fvCFD.H"
#include "argList.H"
#include "levelSet.H"
#include "pointFields.H"
#include "timeSelector.H"
#include "uniformDimensionedFields.H"
#include "volFields.H"
#include "wallDist.H"
#include "waveAlphaFvPatchScalarField.H"
#include "waveVelocityFvPatchVectorField.H"
#include "waveSuperposition.H"

using namespace Foam;

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

int main(int argc, char *argv[])
{
timeSelector::addOptions(false, false);

Foam::argList::addOption
#include "addDictOption.H"
#include "addRegionOption.H"

argList::addOption
(
"alpha",
"name",
"name of the volume fraction field, default is \"alpha\""
);

argList::addOption
(
"U",
"name",
"name of the velocity field, default is \"U\""
);

Foam::argList::addOption
argList::addBoolOption
(
"alpha",
"name",
"name of the volume fraction field, default is \"alpha\""
"gas",
"the volume fraction field is that that of the gas above the wave"
);

#include "setRootCase.H"
#include "createTime.H"

instantList timeDirs = timeSelector::selectIfPresent(runTime, args);

#include "createMesh.H"
#include "createNamedMesh.H"

const word dictName("setWavesDict");
#include "setSystemMeshDictionaryIO.H"
Info<< "Reading " << dictName << "\n" << endl;
IOdictionary setWavesDict(dictIO);

#include "readGravitationalAcceleration.H"

const pointMesh& pMesh = pointMesh::New(mesh);

// Parse options
const word alphaName = setWavesDict.lookupOrDefault<word>("alpha", "alpha");
const word UName = setWavesDict.lookupOrDefault<word>("U", "U");
const bool liquid = setWavesDict.lookupOrDefault<bool>("liquid", true);
const dimensionedVector UMean
(
"UMean",
dimVelocity,
setWavesDict.lookup("UMean")
);

// Get the wave models
const waveSuperposition& waves = waveSuperposition::New(mesh);

forAll(timeDirs, timeI)
{
runTime.setTime(timeDirs[timeI], timeI);
@@ -83,7 +115,7 @@ int main(int argc, char *argv[])
(
IOobject
(
args.optionFound("alpha") ? args["alpha"] : "alpha",
alphaName,
runTime.timeName(),
mesh,
IOobject::MUST_READ
@@ -94,7 +126,7 @@ int main(int argc, char *argv[])
(
IOobject
(
args.optionFound("U") ? args["U"] : "U",
UName,
runTime.timeName(),
mesh,
IOobject::MUST_READ
@@ -125,7 +157,7 @@ int main(int argc, char *argv[])
(
IOobject("uGasp", runTime.timeName(), mesh),
pMesh,
dimensionedVector("0", dimLength, vector::zero)
dimensionedVector("0", dimVelocity, vector::zero)
);
volVectorField uLiq
(
@@ -137,165 +169,31 @@ int main(int argc, char *argv[])
(
IOobject("uLiqp", runTime.timeName(), mesh),
pMesh,
dimensionedVector("0", dimLength, vector::zero)
);

// The number of wave patches
label nWaves = 0;

// Whether the alpha conditions refer to the liquid phase
bool liquid = false;

// Loop the patches, averaging and superimposing wave model data
forAll(mesh.boundary(), patchi)
{
fvPatchScalarField& alphap = alpha.boundaryFieldRef()[patchi];
fvPatchVectorField& Up = U.boundaryFieldRef()[patchi];

const bool isWave = isA<waveAlphaFvPatchScalarField>(alphap);

if (isA<waveVelocityFvPatchVectorField>(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)
{
continue;
}

Info<< "Adding waves from patch " << Up.patch().name() << endl;

const waveSuperposition& waves =
refCast<waveVelocityFvPatchVectorField>(Up).waves();

const bool liquidp =
refCast<waveAlphaFvPatchScalarField>(alphap).liquid();
if (nWaves > 0 && liquidp != liquid)
{
FatalErrorInFunction
<< "All " << waveAlphaFvPatchScalarField::typeName
<< "patch fields must be configured for the same phase,"
<< " i.e., the liquid switch must have the same value."
<< exit(FatalError);
}
liquid = liquidp;

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(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)
{
const pointField& fcs = mesh.boundary()[patchj].Cf();
h.boundaryFieldRef()[patchj] += waves.height(t, fcs);
uGas.boundaryFieldRef()[patchj] +=
waves.UGas(t, fcs) - waves.UMean(t);
uLiq.boundaryFieldRef()[patchj] +=
waves.ULiquid(t, fcs) - waves.UMean(t);
}

++ nWaves;
}

// Create the mean velocity field
volVectorField UMean
(
IOobject("UMean", runTime.timeName(), mesh),
mesh,
dimensionedVector("UMean", dimVelocity, Zero)
dimensionedVector("0", dimVelocity, vector::zero)
);

if (nWaves == 0)
{
// Warn and skip to the next time if there are no wave patches
WarningInFunction
<< "No " << waveAlphaFvPatchScalarField::typeName << " or "
<< waveVelocityFvPatchVectorField::typeName << " patch fields "
<< "were found. No waves have been set." << endl;
// Offset
const vector offset = UMean.value()*t;

continue;
}
else if (nWaves == 1)
{
// Set a mean velocity equal to that on the only wave patch
forAll(mesh.boundary(), patchi)
{
const fvPatchVectorField& Up = U.boundaryField()[patchi];
if (!isA<waveVelocityFvPatchVectorField>(Up))
{
continue;
}
// Cell centres and points
const pointField& ccs = mesh.cellCentres();
const pointField& pts = mesh.points();

const waveSuperposition& waves =
refCast<const waveVelocityFvPatchVectorField>(Up).waves();
// Internal field
h.primitiveFieldRef() = waves.height(t, ccs + offset);
hp.primitiveFieldRef() = waves.height(t, pts + offset);
uGas.primitiveFieldRef() = waves.UGas(t, ccs + offset);
uGasp.primitiveFieldRef() = waves.UGas(t, pts + offset);
uLiq.primitiveFieldRef() = waves.ULiquid(t, ccs + offset);
uLiqp.primitiveFieldRef() = waves.ULiquid(t, pts + offset);

UMean ==
dimensionedVector("UMean", dimVelocity, waves.UMean(t));
}
}
else if (nWaves > 1)
// Boundary fields
forAll(mesh.boundary(), patchj)
{
// Set the mean velocity by distance weighting from the wave patches

// Create weighted average fields for the mean velocity
volScalarField weight
(
IOobject("weight", runTime.timeName(), mesh),
mesh,
dimensionedScalar("0", dimless/dimLength, 0)
);
volVectorField weightUMean
(
IOobject("weightUMean", runTime.timeName(), mesh),
mesh,
dimensionedVector("0", dimVelocity/dimLength, vector::zero)
);

// Loop the patches, inverse-distance weighting the mean velocities
forAll(mesh.boundary(), patchi)
{
const fvPatchVectorField& Up = U.boundaryField()[patchi];
if (!isA<waveVelocityFvPatchVectorField>(Up))
{
continue;
}

const waveSuperposition& waves =
refCast<const waveVelocityFvPatchVectorField>(Up).waves();

const volScalarField w
(
1
/(
wallDist(mesh, labelList(1, patchi)).y()
+ dimensionedScalar("ySmall", dimLength, small)
)
);

weight += w;
weightUMean +=
w*dimensionedVector("wUMean", dimVelocity, waves.UMean(t));
}

// Complete the average for the mean velocity
UMean = weightUMean/weight;
const pointField& fcs = mesh.boundary()[patchj].Cf();
h.boundaryFieldRef()[patchj] = waves.height(t, fcs + offset);
uGas.boundaryFieldRef()[patchj] = waves.UGas(t, fcs + offset);
uLiq.boundaryFieldRef()[patchj] = waves.ULiquid(t, fcs + offset);
}

// Set the fields
@@ -306,10 +204,13 @@ int main(int argc, char *argv[])
forAll(mesh.boundary(), patchi)
{
fvPatchScalarField& alphap = alpha.boundaryFieldRef()[patchi];
fvPatchVectorField& Up = U.boundaryFieldRef()[patchi];
if (isA<waveAlphaFvPatchScalarField>(alphap))
{
alphap == refCast<waveAlphaFvPatchScalarField>(alphap).alpha();
}
fvPatchVectorField& Up = U.boundaryFieldRef()[patchi];
if (isA<waveVelocityFvPatchVectorField>(Up))
{
Up == refCast<waveVelocityFvPatchVectorField>(Up).U();
}
}
@@ -0,0 +1,31 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: dev
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object setWavesDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

// Optional name of the volume fraction field
alpha alpha.water;

// Optional name of the velocity field
U U;

// Optional flag which indicates whether the alpha field is that of the liquid
// under the waves (true) or the gas over the waves (false)
liquid true;

// The mean flow velocity over which to superimpose waves
UMean (1 0 0);


// ************************************************************************* //
@@ -122,35 +122,34 @@ Foam::waveAlphaFvPatchScalarField::waveAlphaFvPatchScalarField
Foam::tmp<Foam::scalarField> Foam::waveAlphaFvPatchScalarField::alpha() const
{
const scalar t = db().time().timeOutputValue();

const waveSuperposition& waves = waveSuperposition::New(db());
const waveVelocityFvPatchVectorField& Up =
refCast<const waveVelocityFvPatchVectorField>
(
patch().lookupPatchField<volVectorField, scalar>(UName_)
);
const waveSuperposition& waves = Up.waves();

return
levelSetFraction
(
patch(),
waves.height(t, patch().Cf()),
waves.height(t, patch().patch().localPoints()),
waves.height(t, patch().Cf() + Up.offset()),
waves.height(t, patch().patch().localPoints() + Up.offset()),
!liquid_
);
}


Foam::tmp<Foam::scalarField> Foam::waveAlphaFvPatchScalarField::alphan() const
{
const scalar t = db().time().timeOutputValue();
const waveSuperposition& waves = waveSuperposition::New(db());
const waveVelocityFvPatchVectorField& Up =
refCast<const waveVelocityFvPatchVectorField>
(
patch().lookupPatchField<volVectorField, scalar>(UName_)
);

const scalar t = db().time().timeOutputValue();

const fvMeshSubset& subset = Up.faceCellSubset();
const fvMesh& meshs = subset.subMesh();
const label patchis = findIndex(subset.patchMap(), patch().index());
@@ -160,8 +159,8 @@ Foam::tmp<Foam::scalarField> Foam::waveAlphaFvPatchScalarField::alphan() const
levelSetFraction
(
meshs,
Up.waves().height(t, meshs.cellCentres())(),
Up.waves().height(t, meshs.points())(),
waves.height(t, meshs.cellCentres() + Up.offset())(),
waves.height(t, meshs.points() + Up.offset())(),
!liquid_
)
);

0 comments on commit 967edc9

Please sign in to comment.
You can’t perform that action at this time.