From c0da2a5effadca4b4409a888ecf4b38ab798ded9 Mon Sep 17 00:00:00 2001 From: Will Bainbridge Date: Fri, 13 Oct 2023 12:37:01 +0100 Subject: [PATCH] waveModels: New irregular wave model This model builds up phase fraction and velocity fields from multiple first-order waves, sampled from a selectable wave spectrum. Usage: Property | Description | Required? | Default ----------+-------------------------------+-----------+------------- depth | The water depth [m] | no | great spectrum | The wave spectrum | yes | n | The number of times to sample | yes | | the spectrum | | span | The fractional range across | no | (0.01 0.99) | which to sample the spectrum | | setFormat | The format with which to plot | no | none | the spectrum | | Example specification in constant/waveProperties: waves ( irregular { spectrum PiersonMoskowitz; // or JONSWAP PiersonMoskowitzCoeffs { U19_5 15; } JONSWAPCoeffs { U10 10; F 200e3; } n 16; span (0.01 0.99); } ); --- src/waves/Make/files | 5 + src/waves/Make/options | 6 +- .../waveAlpha/waveAlphaFvPatchScalarField.H | 6 +- .../waveInletOutletFvPatchField.H | 8 +- .../waveVelocityFvPatchVectorField.H | 4 +- src/waves/waveModels/Airy/Airy.C | 115 ++----- src/waves/waveModels/Airy/Airy.H | 120 +++---- src/waves/waveModels/Airy/AiryCoeffs.C | 182 +++++++++++ src/waves/waveModels/Airy/AiryCoeffs.H | 172 ++++++++++ src/waves/waveModels/Airy/AiryI.H | 77 +++++ src/waves/waveModels/Stokes2/Stokes2.C | 54 ++-- src/waves/waveModels/Stokes2/Stokes2.H | 24 +- src/waves/waveModels/Stokes5/Stokes5.C | 65 ++-- src/waves/waveModels/Stokes5/Stokes5.H | 22 +- src/waves/waveModels/irregular/irregular.C | 301 ++++++++++++++++++ src/waves/waveModels/irregular/irregular.H | 199 ++++++++++++ .../irregular/waveSpectra/JONSWAP/JONSWAP.C | 109 +++++++ .../irregular/waveSpectra/JONSWAP/JONSWAP.H | 152 +++++++++ .../PiersonMoskowitz/PiersonMoskowitz.C | 122 +++++++ .../PiersonMoskowitz/PiersonMoskowitz.H | 166 ++++++++++ .../waveSpectra/waveSpectrum/waveSpectrum.C | 211 ++++++++++++ .../waveSpectra/waveSpectrum/waveSpectrum.H | 172 ++++++++++ src/waves/waveModels/solitary/solitary.H | 21 ++ src/waves/waveModels/waveModel/waveModel.C | 8 +- .../waveAtmBoundaryLayerSuperposition.H | 18 +- .../waveSuperposition/waveSuperposition.C | 2 +- .../waveSuperposition/waveSuperposition.H | 30 +- 27 files changed, 2094 insertions(+), 277 deletions(-) create mode 100644 src/waves/waveModels/Airy/AiryCoeffs.C create mode 100644 src/waves/waveModels/Airy/AiryCoeffs.H create mode 100644 src/waves/waveModels/Airy/AiryI.H create mode 100644 src/waves/waveModels/irregular/irregular.C create mode 100644 src/waves/waveModels/irregular/irregular.H create mode 100644 src/waves/waveModels/irregular/waveSpectra/JONSWAP/JONSWAP.C create mode 100644 src/waves/waveModels/irregular/waveSpectra/JONSWAP/JONSWAP.H create mode 100644 src/waves/waveModels/irregular/waveSpectra/PiersonMoskowitz/PiersonMoskowitz.C create mode 100644 src/waves/waveModels/irregular/waveSpectra/PiersonMoskowitz/PiersonMoskowitz.H create mode 100644 src/waves/waveModels/irregular/waveSpectra/waveSpectrum/waveSpectrum.C create mode 100644 src/waves/waveModels/irregular/waveSpectra/waveSpectrum/waveSpectrum.H diff --git a/src/waves/Make/files b/src/waves/Make/files index b999601919..9fd9b25367 100644 --- a/src/waves/Make/files +++ b/src/waves/Make/files @@ -1,9 +1,14 @@ waveModels/waveModel/waveModel.C waveModels/waveModel/waveModelNew.C +waveModels/Airy/AiryCoeffs.C waveModels/Airy/Airy.C waveModels/Stokes2/Stokes2.C waveModels/Stokes5/Stokes5.C waveModels/solitary/solitary.C +waveModels/irregular/waveSpectra/waveSpectrum/waveSpectrum.C +waveModels/irregular/waveSpectra/PiersonMoskowitz/PiersonMoskowitz.C +waveModels/irregular/waveSpectra/JONSWAP/JONSWAP.C +waveModels/irregular/irregular.C waveSuperpositions/waveSuperposition/waveSuperposition.C waveSuperpositions/waveSuperposition/waveSuperpositionNew.C diff --git a/src/waves/Make/options b/src/waves/Make/options index 4709d60eae..c39852a3bd 100644 --- a/src/waves/Make/options +++ b/src/waves/Make/options @@ -2,10 +2,12 @@ EXE_INC = \ -I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/dynamicMesh/lnInclude \ - -I$(LIB_SRC)/atmosphericModels/lnInclude + -I$(LIB_SRC)/atmosphericModels/lnInclude \ + -I$(LIB_SRC)/sampling/lnInclude LIB_LIBS = \ -lfiniteVolume \ -lmeshTools \ -ldynamicMesh \ - -latmosphericModels + -latmosphericModels \ + -lsampling diff --git a/src/waves/derivedFvPatchFields/waveAlpha/waveAlphaFvPatchScalarField.H b/src/waves/derivedFvPatchFields/waveAlpha/waveAlphaFvPatchScalarField.H index b2daff1949..a650cef434 100644 --- a/src/waves/derivedFvPatchFields/waveAlpha/waveAlphaFvPatchScalarField.H +++ b/src/waves/derivedFvPatchFields/waveAlpha/waveAlphaFvPatchScalarField.H @@ -32,9 +32,9 @@ Description Usage \table - Property | Description | Req'd? | Default - phi | Name of the flux field | no | phi - liquid | Is the alpha field that of the liquid? | no | true + Property | Description | Required? | Default + phi | Name of the flux field | no | phi + liquid | Is the alpha field that of the liquid? | no | true \endtable Example of the boundary condition specification: diff --git a/src/waves/derivedFvPatchFields/waveInletOutlet/waveInletOutletFvPatchField.H b/src/waves/derivedFvPatchFields/waveInletOutlet/waveInletOutletFvPatchField.H index c80421f9a9..8880da2f1b 100644 --- a/src/waves/derivedFvPatchFields/waveInletOutlet/waveInletOutletFvPatchField.H +++ b/src/waves/derivedFvPatchFields/waveInletOutlet/waveInletOutletFvPatchField.H @@ -32,10 +32,10 @@ Description Usage \table - Property | Description | Req'd? | Default - phi | Name of the flux field | no | phi - inletValueAbove | inlet value above the wave | no | None - inletValueBelow | inlet value below the wave | no | None + Property | Description | Required? | Default + phi | Name of the flux field | no | phi + inletValueAbove | inlet value above the wave | no | None + inletValueBelow | inlet value below the wave | no | None \endtable Example of the boundary condition specification: diff --git a/src/waves/derivedFvPatchFields/waveVelocity/waveVelocityFvPatchVectorField.H b/src/waves/derivedFvPatchFields/waveVelocity/waveVelocityFvPatchVectorField.H index 500d073221..60d4b1ebf1 100644 --- a/src/waves/derivedFvPatchFields/waveVelocity/waveVelocityFvPatchVectorField.H +++ b/src/waves/derivedFvPatchFields/waveVelocity/waveVelocityFvPatchVectorField.H @@ -32,8 +32,8 @@ Description Usage \table - Property | Description | Req'd? | Default - phi | Name of the flux field | no | phi + Property | Description | Required? | Default + phi | Name of the flux field | no | phi \endtable Example of the boundary condition specification: diff --git a/src/waves/waveModels/Airy/Airy.C b/src/waves/waveModels/Airy/Airy.C index c6f58ecef7..830c420d5b 100644 --- a/src/waves/waveModels/Airy/Airy.C +++ b/src/waves/waveModels/Airy/Airy.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org - \\ / A nd | Copyright (C) 2017-2021 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2017-2023 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -38,16 +38,15 @@ namespace waveModels } } - // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // -Foam::scalar Foam::waveModels::Airy::length +Foam::scalar Foam::waveModels::Airy::readLength ( const dictionary& dict, const scalar depth, const scalar amplitude, const scalar g, - scalar (*modelCelerity)(scalar, scalar, scalar, scalar) + scalar (*celerityPtr)(const AiryCoeffs&) ) { const bool haveLength = dict.found("length"); @@ -66,90 +65,24 @@ Foam::scalar Foam::waveModels::Airy::length } else { - const scalar period = dict.lookup("period"); - - scalar length0 = 0; - scalar length1 = 1.5*g*sqr(period)/(2*constant::mathematical::pi); - - // Bisect down to round off error to find the wave length - for (label i = 0; i < ceil(std::log2(1/small)); ++ i) - { - const scalar length = (length0 + length1)/2; - - const scalar t = length/modelCelerity(depth, amplitude, length, g); - - (t < period ? length0 : length1) = length; - } - - return (length0 + length1)/2; + return + AiryCoeffs + ( + depth, + amplitude, + dict.lookup("period"), + g, + celerityPtr + ).length; } } -// * * * * * * * * * * Static Protected Member Functions * * * * * * ** * * // - -Foam::scalar Foam::waveModels::Airy::k(const scalar length) -{ - return 2*Foam::constant::mathematical::pi/length; -} - - -bool Foam::waveModels::Airy::deep(const scalar depth, const scalar length) -{ - return depth*k(length) > log(great); -} - - -Foam::scalar Foam::waveModels::Airy::celerity -( - const scalar depth, - const scalar amplitude, - const scalar length, - const scalar g -) -{ - return sqrt(g/k(length)*tanh(k(length)*depth)); -} - - // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // -Foam::tmp Foam::waveModels::Airy::angle -( - const scalar t, - const scalarField& x -) const +Foam::scalar Foam::waveModels::Airy::celerity(const AiryCoeffs& coeffs) { - return phase_ + k()*(x - celerity()*t); -} - - -Foam::tmp Foam::waveModels::Airy::vi -( - const label i, - const scalar t, - const vector2DField& xz -) const -{ - const scalarField x(xz.component(0)); - const scalarField z(xz.component(1)); - - const scalarField phi(angle(t, x)); - - const scalar kzGreat = log(i*great); - const scalarField kz(min(max(k()*z, - kzGreat), kzGreat)); - - if (deep()) - { - return i*exp(kz)*zip(cos(i*phi), sin(i*phi)); - } - else - { - const scalar kd = k()*depth(); - const scalarField kdz(max(scalar(0), kd + kz)); - - return i*zip(cosh(i*kdz)*cos(i*phi), sinh(i*kdz)*sin(i*phi))/sinh(kd); - } + return coeffs.celerity(); } @@ -170,16 +103,16 @@ Foam::waveModels::Airy::Airy const dictionary& dict, const scalar g, const word& modelName, - scalar (*modelCelerity)(scalar, scalar, scalar, scalar) + scalar (*celerityPtr)(const AiryCoeffs&) ) : waveModel(dict, g), depth_(dict.lookupOrDefault("depth", great)), amplitude_(Function1::New("amplitude", dict)), - length_(length(dict, depth_, amplitude(), g, modelCelerity)), + length_(readLength(dict, depth_, amplitude(), g, celerityPtr)), phase_(dict.lookup("phase")) { - const scalar c = modelCelerity(depth(), amplitude(), length(), g); + const scalar c = celerityPtr(coeffs()); Info<< waveModel::typeName << ": " << modelName << ": period = " << length_/c @@ -195,13 +128,19 @@ Foam::waveModels::Airy::~Airy() // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // +Foam::scalar Foam::waveModels::Airy::celerity() const +{ + return celerity(coeffs()); +} + + Foam::tmp Foam::waveModels::Airy::elevation ( const scalar t, const scalarField& x ) const { - return amplitude(t)*cos(angle(t, x)); + return amplitude(t)*cos(coeffs().angle(phase_, t, x)); } @@ -211,9 +150,9 @@ Foam::tmp Foam::waveModels::Airy::velocity const vector2DField& xz ) const { - const scalar ka = k()*amplitude(t); + const scalar ka = coeffs().k()*amplitude(t); - return Airy::celerity()*ka*vi(1, t, xz); + return Airy::celerity()*ka*coeffs().vi(1, phase_, t, xz); } @@ -221,7 +160,7 @@ void Foam::waveModels::Airy::write(Ostream& os) const { waveModel::write(os); - if (!deep()) + if (!coeffs().deep()) { writeEntry(os, "depth", depth_); } diff --git a/src/waves/waveModels/Airy/Airy.H b/src/waves/waveModels/Airy/Airy.H index 322c15e239..0d3249003a 100644 --- a/src/waves/waveModels/Airy/Airy.H +++ b/src/waves/waveModels/Airy/Airy.H @@ -36,6 +36,29 @@ Description See the leading terms of equations 18 and 19. +Usage + \table + Property | Description | Required? | Default + depth | The water depth [m] | no | great + amplitude | The amplitude [m] | yes | + length | The wave length [m] | if period not set | + period | The wave period [s] | if length not set | + phase | The phase offset [rad] | yes | + \endtable + + Example specification in constant/waveProperties: + \verbatim + waves + ( + Airy + { + length 40; + amplitude 0.5; + phase 0; + } + ); + \endverbatim + SourceFiles Airy.C @@ -45,6 +68,7 @@ SourceFiles #define Airy_H #include "waveModel.H" +#include "AiryCoeffs.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -66,81 +90,43 @@ class Airy //- Depth [m] const scalar depth_; - //- Peak-to-peak mean amplitude [m] + //- Amplitude [m] autoPtr> amplitude_; - //- Peak-to-peak length [m] + //- Wavelength [m] const scalar length_; //- Phase offset [rad] const scalar phase_; -private: - // Private Member Functions //- Read and return the wave length from the dictionary. Either reads // the length directly, or reads the period and depth and calculates // the length. - static scalar length + static scalar readLength ( const dictionary& dict, const scalar depth, const scalar amplitude, const scalar g, - scalar (*celerityPtr)(scalar, scalar, scalar, scalar) + scalar (*celerityPtr)(const AiryCoeffs&) ); protected: - // Static Protected Member Functions - - //- The angular wavenumber [rad/m] - static scalar k(const scalar length); - - //- Return whether shallow and intermediate effects are to be omitted - static bool deep(const scalar length, const scalar depth); - - //- The wave celerity [m/s] - static scalar celerity - ( - const scalar depth, - const scalar amplitude, - const scalar length, - const scalar g - ); - - // Protected Member Functions - //- The angular wavenumber [rad/m] - scalar k() const - { - return k(length_); - } + //- Return the wave coefficients + AiryCoeffs coeffs(const scalar t) const; - //- Return whether shallow and intermediate effects are to be omitted - bool deep() const - { - return deep(depth(), length()); - } + //- Return the wave coefficients at steady state + AiryCoeffs coeffs() const; - //- Angle of the oscillation [rad] - tmp angle - ( - const scalar t, - const scalarField& x - ) const; - - //- Return the non-dimensionalised i-th harmonic of the velocity - tmp vi - ( - const label i, - const scalar t, - const vector2DField& xz - ) const; + //- The wave celerity [m/s] + static scalar celerity(const AiryCoeffs&); public: @@ -160,8 +146,7 @@ public: const dictionary& dict, const scalar g, const word& modelName = Airy::typeName, - scalar (*modelCelerity)(scalar, scalar, scalar, scalar) = - &Airy::celerity + scalar (*celerityPtr)(const AiryCoeffs&) = &AiryCoeffs::celerity ); //- Construct a clone @@ -180,40 +165,23 @@ public: // Access //- Get the depth - scalar depth() const - { - return depth_; - } + scalar depth() const; //- Get the amplitude - scalar amplitude(const scalar t) const - { - return amplitude_->value(t); - } + scalar amplitude(const scalar t) const; //- Get the amplitude at steady state - scalar amplitude() const - { - return amplitude_->value(great); - } + scalar amplitude() const; //- Get the length - scalar length() const - { - return length_; - } + scalar length() const; //- Get the phase - scalar phase() const - { - return phase_; - } + scalar phase() const; + //- The wave celerity [m/s] - virtual scalar celerity() const - { - return celerity(depth(), amplitude(), length(), g()); - } + virtual scalar celerity() const; //- Get the wave elevation at a given time and local coordinates. Local // x is aligned with the direction of propagation. @@ -244,6 +212,10 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +#include "AiryI.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + #endif // ************************************************************************* // diff --git a/src/waves/waveModels/Airy/AiryCoeffs.C b/src/waves/waveModels/Airy/AiryCoeffs.C new file mode 100644 index 0000000000..7630990739 --- /dev/null +++ b/src/waves/waveModels/Airy/AiryCoeffs.C @@ -0,0 +1,182 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | Website: https://openfoam.org + \\ / A nd | Copyright (C) 2017-2023 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 "AiryCoeffs.H" +#include "mathematicalConstants.H" + +// * * * * * * * * * * * Private Static Member Functions * * * * * * * * * * // + +Foam::scalar Foam::waveModels::AiryCoeffs::calcLength +( + const scalar depth, + const scalar amplitude, + const scalar period, + const scalar g, + scalar (*celerityPtr)(const AiryCoeffs&) +) +{ + scalar length0 = 0; + scalar length1 = 1.5*g*sqr(period)/(2*constant::mathematical::pi); + + // Bisect down to round off error to find the wave length + for (label i = 0; i < ceil(std::log2(1/small)); ++ i) + { + const scalar length = (length0 + length1)/2; + + const scalar t = + length/celerityPtr(AiryCoeffs(depth, amplitude, length, g)); + + (t < period ? length0 : length1) = length; + } + + return (length0 + length1)/2; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::waveModels::AiryCoeffs::AiryCoeffs +( + const scalar depth, + const scalar amplitude, + const scalar length, + const scalar g +) +: + depth(depth), + amplitude(amplitude), + length(length), + g(g) +{} + + +Foam::waveModels::AiryCoeffs::AiryCoeffs +( + const scalar depth, + const scalar amplitude, + const scalar period, + const scalar g, + scalar (*celerityPtr)(const AiryCoeffs&) +) +: + depth(depth), + amplitude(amplitude), + length(calcLength(depth, amplitude, period, g, celerityPtr)), + g(g) +{} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +Foam::scalar Foam::waveModels::AiryCoeffs::k() const +{ + return 2*Foam::constant::mathematical::pi/length; +} + + +bool Foam::waveModels::AiryCoeffs::deep() const +{ + return depth*k() > log(great); +} + + +Foam::scalar Foam::waveModels::AiryCoeffs::celerity(const AiryCoeffs& coeffs) +{ + return sqrt(coeffs.g/coeffs.k()*tanh(coeffs.k()*coeffs.depth)); +} + + +Foam::scalar Foam::waveModels::AiryCoeffs::celerity() const +{ + return celerity(*this); +} + + +Foam::tmp Foam::waveModels::AiryCoeffs::angle +( + const scalar phase, + const scalar t, + const scalarField& x +) const +{ + return phase + k()*(x - celerity()*t); +} + + +Foam::tmp Foam::waveModels::AiryCoeffs::elevation +( + const scalar phase, + const scalar t, + const scalarField& x +) const +{ + return amplitude*cos(angle(phase, t, x)); +} + + +Foam::tmp Foam::waveModels::AiryCoeffs::vi +( + const label i, + const scalar phase, + const scalar t, + const vector2DField& xz +) const +{ + const scalarField x(xz.component(0)); + const scalarField z(xz.component(1)); + + const scalarField phi(angle(phase, t, x)); + + const scalar kzGreat = log(i*great); + const scalarField kz(min(max(k()*z, - kzGreat), kzGreat)); + + if (deep()) + { + return i*exp(kz)*zip(cos(i*phi), sin(i*phi)); + } + else + { + const scalar kd = k()*depth; + const scalarField kdz(max(scalar(0), kd + kz)); + + return i*zip(cosh(i*kdz)*cos(i*phi), sinh(i*kdz)*sin(i*phi))/sinh(kd); + } +} + + +Foam::tmp Foam::waveModels::AiryCoeffs::velocity +( + const scalar phase, + const scalar t, + const vector2DField& xz +) const +{ + const scalar ka = k()*amplitude; + + return celerity()*ka*vi(1, phase, t, xz); +} + + +// ************************************************************************* // diff --git a/src/waves/waveModels/Airy/AiryCoeffs.H b/src/waves/waveModels/Airy/AiryCoeffs.H new file mode 100644 index 0000000000..dafdef6e5c --- /dev/null +++ b/src/waves/waveModels/Airy/AiryCoeffs.H @@ -0,0 +1,172 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | Website: https://openfoam.org + \\ / A nd | Copyright (C) 2017-2023 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::AiryCoeffs + +Description + Calculation engine for the Airy wave model and other models that are a + correction on top of the Airy model or a superposition of Airy models + +SourceFiles + AiryCoeffs.C + +\*---------------------------------------------------------------------------*/ + +#ifndef AiryCoeffs_H +#define AiryCoeffs_H + +#include "waveModel.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace waveModels +{ + +/*---------------------------------------------------------------------------*\ + Class AiryCoeffs Declaration +\*---------------------------------------------------------------------------*/ + +class AiryCoeffs +{ +private: + + // Private Static Member Functions + + //- Calculate the length from the depth, amplitude, period and g. + // Requires a function which returns celerity given the depth, + // amplitude, length and g. Iterates to solve this function for the + // specified period. + static scalar calcLength + ( + const scalar depth, + const scalar amplitude, + const scalar period, + const scalar g, + scalar (*celerityPtr)(const AiryCoeffs&) + ); + + +public: + + // Public Data + + //- Depth [m] + const scalar depth; + + //- Amplitude [m] + const scalar amplitude; + + //- Wavelength [m] + const scalar length; + + //- Gravitational acceleration [m/s^2] + const scalar g; + + + // Constructors + + //- Construct from components + AiryCoeffs + ( + const scalar depth, + const scalar amplitude, + const scalar length, + const scalar g + ); + + //- Construct from components but with period instead of length + AiryCoeffs + ( + const scalar depth, + const scalar amplitude, + const scalar period, + const scalar g, + scalar (*celerityPtr)(const AiryCoeffs&) + ); + + + // Member Functions + + //- The angular wavenumber [rad/m] + scalar k() const; + + //- Return whether shallow and intermediate effects are to be omitted + bool deep() const; + + //- The wave celerity [m/s] + static scalar celerity(const AiryCoeffs& coeffs); + + //- The wave celerity [m/s] + scalar celerity() const; + + //- Angle of the oscillation [rad] + tmp angle + ( + const scalar phase, + const scalar t, + const scalarField& x + ) const; + + //- Get the wave elevation at a given time and local coordinates. Local + // x is aligned with the direction of propagation. + tmp elevation + ( + const scalar phase, + const scalar t, + const scalarField& x + ) const; + + //- Return the non-dimensionalised i-th harmonic of the velocity + tmp vi + ( + const label i, + const scalar phase, + const scalar t, + const vector2DField& xz + ) const; + + //- Get the wave velocity at a given time and local coordinates. Local + // x is aligned with the direction of propagation, and z with negative + // gravity. + tmp velocity + ( + const scalar phase, + const scalar t, + const vector2DField& xz + ) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace waveModels +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/waves/waveModels/Airy/AiryI.H b/src/waves/waveModels/Airy/AiryI.H new file mode 100644 index 0000000000..aaef8d7831 --- /dev/null +++ b/src/waves/waveModels/Airy/AiryI.H @@ -0,0 +1,77 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | Website: https://openfoam.org + \\ / A nd | Copyright (C) 2017-2023 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" + +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +inline Foam::waveModels::AiryCoeffs Foam::waveModels::Airy::coeffs +( + const scalar t +) const +{ + return AiryCoeffs(depth_, amplitude_->value(t), length_, g()); +} + + +inline Foam::waveModels::AiryCoeffs Foam::waveModels::Airy::coeffs() const +{ + return AiryCoeffs(depth_, amplitude(), length_, g()); +} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +inline Foam::scalar Foam::waveModels::Airy::depth() const +{ + return depth_; +} + + +inline Foam::scalar Foam::waveModels::Airy::amplitude(const scalar t) const +{ + return amplitude_->value(t); +} + + +inline Foam::scalar Foam::waveModels::Airy::amplitude() const +{ + return amplitude_->value(great); +} + + +inline Foam::scalar Foam::waveModels::Airy::length() const +{ + return length_; +} + + +inline Foam::scalar Foam::waveModels::Airy::phase() const +{ + return phase_; +} + + +// ************************************************************************* // diff --git a/src/waves/waveModels/Stokes2/Stokes2.C b/src/waves/waveModels/Stokes2/Stokes2.C index 76721bfa1f..94407b74cf 100644 --- a/src/waves/waveModels/Stokes2/Stokes2.C +++ b/src/waves/waveModels/Stokes2/Stokes2.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org - \\ / A nd | Copyright (C) 2017-2021 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2017-2023 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -40,21 +40,15 @@ namespace waveModels // * * * * * * * * * * Static Protected Member Functions * * * * * * ** * * // -Foam::scalar Foam::waveModels::Stokes2::celerity -( - const scalar depth, - const scalar amplitude, - const scalar length, - const scalar g -) +Foam::scalar Foam::waveModels::Stokes2::celerity(const AiryCoeffs& coeffs) { static const scalar kdGreat = log(great); - const scalar kd = min(max(k(length)*depth, - kdGreat), kdGreat); - const scalar ka = k(length)*amplitude; + const scalar kd = min(max(coeffs.k()*coeffs.depth, - kdGreat), kdGreat); + const scalar ka = coeffs.k()*coeffs.amplitude; - const scalar S = deep(depth, length) ? 0 : 1/cosh(2*kd); + const scalar S = coeffs.deep() ? 0 : 1/cosh(2*kd); - const scalar C0 = Airy::celerity(depth, amplitude, length, g); + const scalar C0 = coeffs.celerity(); const scalar C2ByC0 = (2 + 7*sqr(S))/4/sqr(1 - S); if (debug) @@ -62,7 +56,7 @@ Foam::scalar Foam::waveModels::Stokes2::celerity Info<< "C2 = " << C2ByC0*C0 << endl; } - return Airy::celerity(depth, amplitude, length, g) + sqr(ka)*C2ByC0*C0; + return Airy::celerity(coeffs) + sqr(ka)*C2ByC0*C0; } @@ -73,10 +67,10 @@ Foam::waveModels::Stokes2::Stokes2 const dictionary& dict, const scalar g, const word& modelName, - scalar (*modelCelerity)(scalar, scalar, scalar, scalar) + scalar (*celerityPtr)(const AiryCoeffs&) ) : - Airy(dict, g, modelName, modelCelerity) + Airy(dict, g, modelName, celerityPtr) {} @@ -88,17 +82,25 @@ Foam::waveModels::Stokes2::~Stokes2() // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // +Foam::scalar Foam::waveModels::Stokes2::celerity() const +{ + return celerity(coeffs()); +} + + Foam::tmp Foam::waveModels::Stokes2::elevation ( const scalar t, const scalarField& x ) const { - static const scalar kdGreat = log(great); - const scalar kd = min(max(k()*depth(), - kdGreat), kdGreat); - const scalar ka = k()*amplitude(t); + const AiryCoeffs coeffs = this->coeffs(); - const scalar T = deep() ? 1 : tanh(kd); + static const scalar kdGreat = log(great); + const scalar kd = min(max(coeffs.k()*depth(), - kdGreat), kdGreat); + const scalar ka = coeffs.k()*amplitude(t); + + const scalar T = coeffs.deep() ? 1 : tanh(kd); const scalar B22 = (3/sqr(T) - 1)/T/4; @@ -109,7 +111,7 @@ Foam::tmp Foam::waveModels::Stokes2::elevation return Airy::elevation(t, x) - + (1/k())*sqr(ka)*B22*cos(2*angle(t, x)); + + (1/coeffs.k())*sqr(ka)*B22*cos(2*coeffs.angle(phase(), t, x)); } @@ -119,11 +121,13 @@ Foam::tmp Foam::waveModels::Stokes2::velocity const vector2DField& xz ) const { - static const scalar kdGreat = log(great); - const scalar kd = min(max(k()*depth(), - kdGreat), kdGreat); - const scalar ka = k()*amplitude(t); + const AiryCoeffs coeffs = this->coeffs(); - const scalar A22ByA11 = deep() ? 0 : 0.375/pow3(sinh(kd)); + static const scalar kdGreat = log(great); + const scalar kd = min(max(coeffs.k()*depth(), - kdGreat), kdGreat); + const scalar ka = coeffs.k()*amplitude(t); + + const scalar A22ByA11 = coeffs.deep() ? 0 : 0.375/pow3(sinh(kd)); if (debug) { @@ -133,7 +137,7 @@ Foam::tmp Foam::waveModels::Stokes2::velocity return Airy::velocity(t, xz) - + Airy::celerity()*sqr(ka)*A22ByA11*vi(2, t, xz); + + Airy::celerity()*sqr(ka)*A22ByA11*coeffs.vi(2, phase(), t, xz); } diff --git a/src/waves/waveModels/Stokes2/Stokes2.H b/src/waves/waveModels/Stokes2/Stokes2.H index 5dc31f7e74..58b5e87517 100644 --- a/src/waves/waveModels/Stokes2/Stokes2.H +++ b/src/waves/waveModels/Stokes2/Stokes2.H @@ -36,6 +36,12 @@ Description See equations 18 and 19. +Usage + The parameters of this model are identical to those used by the Airy model + +See also + Foam::waveModels::Airy + SourceFiles Stokes2.C @@ -66,18 +72,12 @@ protected: // Protected Member Functions //- The wave celerity [m/s] - static scalar celerity - ( - const scalar depth, - const scalar amplitude, - const scalar length, - const scalar g - ); + static scalar celerity(const AiryCoeffs&); public: - //- Runtime type information + //- Runtime type information TypeName("Stokes2"); @@ -89,8 +89,7 @@ public: const dictionary& dict, const scalar g, const word& modelName = Stokes2::typeName, - scalar (*modelCelerity)(scalar, scalar, scalar, scalar) = - &Stokes2::celerity + scalar (*celerityPtr)(const AiryCoeffs&) = &Stokes2::celerity ); //- Construct a clone @@ -107,10 +106,7 @@ public: // Member Functions //- The wave celerity [m/s] - virtual scalar celerity() const - { - return celerity(depth(), amplitude(), length(), g()); - } + virtual scalar celerity() const; //- Get the wave elevation at a given time and local coordinates. Local // x is aligned with the direction of propagation. diff --git a/src/waves/waveModels/Stokes5/Stokes5.C b/src/waves/waveModels/Stokes5/Stokes5.C index 6471bb085b..853b865a8e 100644 --- a/src/waves/waveModels/Stokes5/Stokes5.C +++ b/src/waves/waveModels/Stokes5/Stokes5.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org - \\ / A nd | Copyright (C) 2017-2021 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2017-2023 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -40,21 +40,15 @@ namespace waveModels // * * * * * * * * * * Static Protected Member Functions * * * * * * ** * * // -Foam::scalar Foam::waveModels::Stokes5::celerity -( - const scalar depth, - const scalar amplitude, - const scalar length, - const scalar g -) +Foam::scalar Foam::waveModels::Stokes5::celerity(const AiryCoeffs& coeffs) { static const scalar kdGreat = log(great); - const scalar kd = min(max(k(length)*depth, - kdGreat), kdGreat); - const scalar ka = k(length)*amplitude; + const scalar kd = min(max(coeffs.k()*coeffs.depth, - kdGreat), kdGreat); + const scalar ka = coeffs.k()*coeffs.amplitude; - const scalar S = deep(depth, length) ? 0 : 1/cosh(2*kd); + const scalar S = coeffs.deep() ? 0 : 1/cosh(2*kd); - const scalar C0 = Airy::celerity(depth, amplitude, length, g); + const scalar C0 = coeffs.celerity(); const scalar C4ByC0 = 1.0/32/pow5(1 - S) *(4 + 32*S - 116*sqr(S) - 400*pow3(S) - 71*pow4(S) + 146*pow5(S)); @@ -64,7 +58,7 @@ Foam::scalar Foam::waveModels::Stokes5::celerity Info<< "C4 = " << C4ByC0*C0 << endl; } - return Stokes2::celerity(depth, amplitude, length, g) + pow4(ka)*C4ByC0*C0; + return Stokes2::celerity(coeffs) + pow4(ka)*C4ByC0*C0; } @@ -75,10 +69,10 @@ Foam::waveModels::Stokes5::Stokes5 const dictionary& dict, const scalar g, const word& modelName, - scalar (*modelCelerity)(scalar, scalar, scalar, scalar) + scalar (*celerityPtr)(const AiryCoeffs&) ) : - Stokes2(dict, g, modelName, modelCelerity) + Stokes2(dict, g, modelName, celerityPtr) {} @@ -90,17 +84,26 @@ Foam::waveModels::Stokes5::~Stokes5() // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // +Foam::scalar Foam::waveModels::Stokes5::celerity() const +{ + return celerity(coeffs()); +} + + Foam::tmp Foam::waveModels::Stokes5::elevation ( const scalar t, const scalarField& x ) const { - static const scalar kdGreat = log(great); - const scalar kd = min(max(k()*depth(), - kdGreat), kdGreat); - const scalar ka = k()*amplitude(t); + const AiryCoeffs coeffs = this->coeffs(); - const scalar S = deep() ? 0 : 1/cosh(2*kd), T = deep() ? 1 : tanh(kd); + static const scalar kdGreat = log(great); + const scalar kd = min(max(coeffs.k()*depth(), - kdGreat), kdGreat); + const scalar ka = coeffs.k()*amplitude(t); + + const scalar S = coeffs.deep() ? 0 : 1/cosh(2*kd); + const scalar T = coeffs.deep() ? 1 : tanh(kd); const scalar B31 = - 3.0/8/pow3(1 - S) @@ -143,11 +146,11 @@ Foam::tmp Foam::waveModels::Stokes5::elevation << "B55 = " << B55 << endl; } - const scalarField phi(angle(t, x)); + const scalarField phi(coeffs.angle(phase(), t, x)); return Stokes2::elevation(t, x) - + (1/k()) + + (1/coeffs.k()) *( pow3(ka)*B31*(cos(phi) - cos(3*phi)) + pow4(ka)*(B42*cos(2*phi) + B44*cos(4*phi)) @@ -162,12 +165,14 @@ Foam::tmp Foam::waveModels::Stokes5::velocity const vector2DField& xz ) const { - static const scalar kdGreat = log(great); - const scalar kd = min(max(k()*depth(), - kdGreat), kdGreat); - const scalar ka = k()*amplitude(t); + const AiryCoeffs coeffs = this->coeffs(); - const scalar S = deep() ? 0 : 1/cosh(2*kd); - const scalar SByA11 = deep() ? 0 : S*sinh(kd); + static const scalar kdGreat = log(great); + const scalar kd = min(max(coeffs.k()*depth(), - kdGreat), kdGreat); + const scalar ka = coeffs.k()*amplitude(t); + + const scalar S = coeffs.deep() ? 0 : 1/cosh(2*kd); + const scalar SByA11 = coeffs.deep() ? 0 : S*sinh(kd); const scalar A31ByA11 = 1.0/8/pow3(1 - S) @@ -226,15 +231,17 @@ Foam::tmp Foam::waveModels::Stokes5::velocity << "A55 = " << A55ByA11*A11 << endl; } - const vector2DField v1(vi(1, t, xz)), v3(vi(3, t, xz)); + auto v = [&](const label i) { return coeffs.vi(i, phase(), t, xz); }; + + const vector2DField v1(v(1)), v3(v(3)); return Stokes2::velocity(t, xz) + Airy::celerity() *( pow3(ka)*(A31ByA11*v1 + A33ByA11*v3) - + pow4(ka)*(A42ByA11*vi(2, t, xz) + A44ByA11*vi(4, t, xz)) - + pow5(ka)*(A51ByA11*v1 + A53ByA11*v3 + A55ByA11*vi(5, t, xz)) + + pow4(ka)*(A42ByA11*v(2) + A44ByA11*v(4)) + + pow5(ka)*(A51ByA11*v1 + A53ByA11*v3 + A55ByA11*v(5)) ); } diff --git a/src/waves/waveModels/Stokes5/Stokes5.H b/src/waves/waveModels/Stokes5/Stokes5.H index d173b40881..125621d5d3 100644 --- a/src/waves/waveModels/Stokes5/Stokes5.H +++ b/src/waves/waveModels/Stokes5/Stokes5.H @@ -35,6 +35,12 @@ Description 216-234. \endverbatim +Usage + The parameters of this model are identical to those used by the Airy model + +See also: + Foam::waveModels::Airy + SourceFiles Stokes5.C @@ -65,13 +71,7 @@ protected: // Protected Member Functions //- The wave celerity [m/s] - static scalar celerity - ( - const scalar depth, - const scalar amplitude, - const scalar length, - const scalar g - ); + static scalar celerity(const AiryCoeffs&); public: @@ -88,8 +88,7 @@ public: const dictionary& dict, const scalar g, const word& modelName = Stokes5::typeName, - scalar (*modelCelerity)(scalar, scalar, scalar, scalar) = - &Stokes5::celerity + scalar (*celerityPtr)(const AiryCoeffs&) = &Stokes5::celerity ); //- Construct a clone @@ -106,10 +105,7 @@ public: // Member Functions //- The wave celerity [m/s] - virtual scalar celerity() const - { - return celerity(depth(), amplitude(), length(), g()); - } + virtual scalar celerity() const; //- Get the wave elevation at a given time and local coordinates. Local // x is aligned with the direction of propagation. diff --git a/src/waves/waveModels/irregular/irregular.C b/src/waves/waveModels/irregular/irregular.C new file mode 100644 index 0000000000..ee0a9fe6dc --- /dev/null +++ b/src/waves/waveModels/irregular/irregular.C @@ -0,0 +1,301 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | Website: https://openfoam.org + \\ / A nd | Copyright (C) 2023 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 "irregular.H" +#include "mathematicalConstants.H" +#include "OSspecific.H" +#include "Random.H" +#include "rawSetWriter.H" +#include "writeFile.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace waveModels +{ + defineTypeNameAndDebug(irregular, 0); + addToRunTimeSelectionTable(waveModel, irregular, dictionary); +} +} + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +Foam::waveModels::AiryCoeffs +Foam::waveModels::irregular::coeffs(const label i) const +{ + return AiryCoeffs(depth_, amplitudes_[i], lengths_[i], g()); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::waveModels::irregular::irregular(const irregular& wave) +: + waveModel(wave), + depth_(wave.depth_), + spectrum_(wave.spectrum_, false), + n_(wave.n_), + span_(wave.span_), + formatter_(wave.formatter_, false), + amplitudes_(wave.amplitudes_), + lengths_(wave.lengths_), + phases_(wave.phases_) +{} + + +Foam::waveModels::irregular::irregular +( + const dictionary& dict, + const scalar g, + const word& modelName +) +: + waveModel(dict, g), + depth_(dict.lookupOrDefault("depth", great)), + spectrum_(waveSpectrum::New(dict, g)), + n_(dict.lookup