waveModel.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2015 IH-Cantabria
9  Copyright (C) 2016-2021 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "waveModel.H"
30 #include "fvMesh.H"
31 #include "polyPatch.H"
32 #include "gravityMeshObject.H"
33 #include "volFields.H"
34 #include "fvPatchFields.H"
35 
36 using namespace Foam::constant;
37 
38 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
39 
40 namespace Foam
41 {
42  defineTypeNameAndDebug(waveModel, 0);
44 }
45 
46 const Foam::word Foam::waveModel::dictName("waveProperties");
47 
48 
50 {
51  return dictName + '.' + patchName;
52 }
53 
54 
55 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
56 
58 {
59  // Determine local patch coordinate system given by:
60  // - X: streamwise: patch normal
61  // - Y: spanwise: Z^X
62  // - Z: up: (negative) gravity direction
63  vector x = normalised(-gAverage(patch_.faceAreas()));
64  vector z = -g_/mag(g_);
65  vector y = z^x;
66 
67  // Rotation from global<->local about global origin
68  Rlg_ = tensor(x, y, z);
69  Rgl_ = Rlg_.T();
70 
71  // Global patch extents
72  const vectorField& Cp = patch_.localPoints();
73  const vectorField CpLocal(Rgl_ & Cp);
74  boundBox bb(CpLocal, true);
75  const scalar xMin = bb.min().x();
76  const scalar xMax = bb.max().x();
77  const scalar yMin = bb.min().y();
78  const scalar yMax = bb.max().y();
79  zSpan_ = bb.max().z() - bb.min().z();
80 
81  // Global x, y positions of the paddle centres
82  xPaddle_.setSize(nPaddle_, 0);
83  yPaddle_.setSize(nPaddle_, 0);
84  const scalar xMid = xMin + 0.5*(xMax - xMin);
85  const scalar paddleDy = (yMax - yMin)/scalar(nPaddle_);
86  for (label paddlei = 0; paddlei < nPaddle_; ++paddlei)
87  {
88  xPaddle_[paddlei] = xMid;
89  yPaddle_[paddlei] = paddlei*paddleDy + yMin + 0.5*paddleDy;
90  }
91 
92  // Local face centres
93  const vectorField& Cf = patch_.faceCentres();
94  const vectorField CfLocal(Rgl_ & Cf);
95  z_ = CfLocal.component(2);
96 
97  // Local face extents in z-direction
98  zMin_.setSize(patch_.size());
99  zMax_.setSize(patch_.size());
100  const faceList& faces = patch_.localFaces();
101  forAll(faces, facei)
102  {
103  const face& f = faces[facei];
104  const label nPoint = f.size();
105  zMin_[facei] = CpLocal[f[0]].z();
106  zMax_[facei] = CpLocal[f[0]].z();
107 
108  for (label fpi = 1; fpi < nPoint; ++fpi)
109  {
110  const label pointi = f[fpi];
111  zMin_[facei] = min(zMin_[facei], CpLocal[pointi].z());
112  zMax_[facei] = max(zMax_[facei], CpLocal[pointi].z());
113  }
114  }
115 
116  // Set minimum z reference level
117  zMin0_ = gMin(zMin_);
118 
119  // Local paddle-to-face addressing
120  faceToPaddle_.setSize(patch_.size(), -1);
121  forAll(faceToPaddle_, facei)
122  {
123  faceToPaddle_[facei] = floor((CfLocal[facei].y() - yMin)/paddleDy);
124  }
125 }
126 
127 
129 {
130  // Note: initialising as initial depth
131  auto tlevel = tmp<scalarField>::New(nPaddle_, initialDepth_);
132  auto& level = tlevel.ref();
133 
134  const volScalarField& alpha =
135  mesh_.lookupObject<volScalarField>(alphaName_);
136  const fvPatchScalarField& alphap = alpha.boundaryField()[patch_.index()];
137  const scalarField alphac(alphap.patchInternalField());
138 
139  const scalarField& magSf = alphap.patch().magSf();
140  scalarList paddleMagSf(nPaddle_, Zero);
141  scalarList paddleWettedMagSf(nPaddle_, Zero);
142 
143  forAll(alphac, facei)
144  {
145  label paddlei = faceToPaddle_[facei];
146  paddleMagSf[paddlei] += magSf[facei];
147  paddleWettedMagSf[paddlei] += magSf[facei]*alphac[facei];
148  }
149 
150  forAll(paddleMagSf, paddlei)
151  {
152  reduce(paddleMagSf[paddlei], sumOp<scalar>());
153  reduce(paddleWettedMagSf[paddlei], sumOp<scalar>());
154  level[paddlei] +=
155  paddleWettedMagSf[paddlei]*zSpan_
156  /(paddleMagSf[paddlei] + ROOTVSMALL);
157  }
158 
159  return tlevel;
160 }
161 
162 
164 {
165  forAll(alpha_, facei)
166  {
167  const label paddlei = faceToPaddle_[facei];
168  const scalar paddleCalc = level[paddlei];
169 
170  const scalar zMin0 = zMin_[facei] - zMin0_;
171  const scalar zMax0 = zMax_[facei] - zMin0_;
172 
173  if (zMax0 < paddleCalc)
174  {
175  alpha_[facei] = 1.0;
176  }
177  else if (zMin0 > paddleCalc)
178  {
179  alpha_[facei] = 0.0;
180  }
181  else
182  {
183  scalar dz = paddleCalc - zMin0;
184  alpha_[facei] = dz/(zMax0 - zMin0);
185  }
186  }
187 }
188 
189 
191 (
192  const scalarField& level,
193  const label facei,
194  scalar& fraction,
195  scalar& z
196 ) const
197 {
198  const label paddlei = faceToPaddle_[facei];
199  const scalar paddleCalc = level[paddlei];
200  const scalar paddleHeight = min(paddleCalc, waterDepthRef_);
201  const scalar zMin = zMin_[facei] - zMin0_;
202  const scalar zMax = zMax_[facei] - zMin0_;
203 
204  fraction = 1;
205  z = 0;
206 
207  if (zMax < paddleHeight)
208  {
209  z = z_[facei] - zMin0_;
210  }
211  else if (zMin > paddleCalc)
212  {
213  fraction = -1;
214  }
215  else
216  {
217  if (paddleCalc < waterDepthRef_)
218  {
219  if ((zMax > paddleCalc) && (zMin < paddleCalc))
220  {
221  scalar dz = paddleCalc - zMin;
222  fraction = dz/(zMax - zMin);
223  z = z_[facei] - zMin0_;
224  }
225  }
226  else
227  {
228  if (zMax < paddleCalc)
229  {
230  z = waterDepthRef_;
231  }
232  else if ((zMax > paddleCalc) && (zMin < paddleCalc))
233  {
234  scalar dz = paddleCalc - zMin;
235  fraction = dz/(zMax - zMin);
236  z = waterDepthRef_;
237  }
238  }
239  }
240 }
241 
242 
243 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
244 
246 (
247  const dictionary& dict,
248  const fvMesh& mesh,
249  const polyPatch& patch,
250  const bool readFields
251 )
252 :
254  (
255  IOobject
256  (
257  modelName(patch.name()),
258  Time::timeName(mesh.time().startTime().value()),
259  "uniform",
260  mesh,
263  )
264  ),
265  mesh_(mesh),
266  patch_(patch),
267  g_(meshObjects::gravity::New(mesh.time()).value()),
268  UName_("U"),
269  alphaName_("alpha"),
270  Rgl_(tensor::I),
271  Rlg_(tensor::I),
272  nPaddle_(1),
273  xPaddle_(),
274  yPaddle_(),
275  z_(),
276  zSpan_(0),
277  zMin_(),
278  zMax_(),
279  waterDepthRef_(0),
280  initialDepth_(0),
281  currTimeIndex_(-1),
282  activeAbsorption_(false),
283  U_(patch.size(), Zero),
284  alpha_(patch.size(), Zero)
285 {
286  if (readFields)
287  {
288  readDict(dict);
289  }
290 }
291 
292 
293 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
294 
295 bool Foam::waveModel::readDict(const dictionary& overrideDict)
296 {
297  readOpt(IOobject::READ_IF_PRESENT);
298  if (headerOk())
299  {
301  }
302 
303  merge(overrideDict);
304 
305  readIfPresent("U", UName_);
306  readIfPresent("alpha", alphaName_);
307 
308  readEntry("nPaddle", nPaddle_);
309  if (nPaddle_ < 1)
310  {
312  << "Number of paddles must be greater than zero. Supplied"
313  << " value nPaddles = " << nPaddle_
314  << exit(FatalIOError);
315  }
316 
317  readIfPresent("initialDepth", initialDepth_);
318 
319  // Need to initialise the geometry before calling waterLevel()
320  initialiseGeometry();
321 
322  // Set the reference water depth
323  if (!readIfPresent("waterDepthRef", waterDepthRef_))
324  {
325  scalar waterDepth = 0;
326  if (readIfPresent("waterDepth", waterDepth))
327  {
328  waterDepthRef_ = waterDepth;
329  }
330  else
331  {
332  const scalarField level(waterLevel());
333  if (level.size())
334  {
335  waterDepthRef_ = level.first();
336  }
337  }
338 
339  // Avoid potential zero...
340  waterDepthRef_ += SMALL;
341 
342  // Insert the reference water depth into [this] to enable restart
343  add("waterDepthRef", waterDepthRef_);
344  }
345 
346  return true;
347 }
348 
349 
350 void Foam::waveModel::correct(const scalar t)
351 {
352  if (mesh_.time().timeIndex() != currTimeIndex_)
353  {
354  Info<< "Updating " << type() << " wave model for patch "
355  << patch_.name() << endl;
356 
357  // Time ramp weight
358  const scalar tCoeff = timeCoeff(t);
359 
360  // Reset the velocity and phase fraction fields
361  U_ = vector::zero;
362  alpha_ = 0;
363 
364  // Update the calculated water level field
365  scalarField calculatedLevel(nPaddle_, Zero);
366 
367  if (patch_.size())
368  {
369  // Set wave level
370  setLevel(t, tCoeff, calculatedLevel);
371 
372  // Update the velocity field
373  setVelocity(t, tCoeff, calculatedLevel);
374 
375  // Update the phase fraction field
376  setAlpha(calculatedLevel);
377  }
378 
379  if (activeAbsorption_)
380  {
381  const scalarField activeLevel(this->waterLevel());
382 
383  forAll(U_, facei)
384  {
385  const label paddlei = faceToPaddle_[facei];
386 
387  if (zMin_[facei] - zMin0_ < activeLevel[paddlei])
388  {
389  scalar UCorr =
390  (calculatedLevel[paddlei] - activeLevel[paddlei])
391  *sqrt(mag(g_)/activeLevel[paddlei]);
392 
393  U_[facei].x() += UCorr;
394  }
395  else
396  {
397  U_[facei].x() = 0;
398  }
399  }
400  }
401 
402  // Transform velocity into global coordinate system
403  U_ = Rlg_ & U_;
404 
405  currTimeIndex_ = mesh_.time().timeIndex();
406  }
407 }
408 
409 
411 {
412  return U_;
413 }
414 
415 
417 {
418  return alpha_;
419 }
420 
421 
423 {
424  os << "Wave model: patch " << patch_.name() << nl
425  << " Type : " << type() << nl
426  << " Velocity field name : " << UName_ << nl
427  << " Phase fraction field name : " << alphaName_ << nl
428  << " Transformation from local to global system : " << Rlg_ << nl
429  << " Number of paddles: " << nPaddle_ << nl
430  << " Reference water depth : " << waterDepthRef_ << nl
431  << " Active absorption: " << activeAbsorption_ << nl;
432 }
433 
434 
435 // ************************************************************************* //
Foam::fvPatchField< scalar >
waveModel.H
volFields.H
Foam::IOdictionary
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:54
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:169
Foam::Vector::x
const Cmpt & x() const
Access to the vector x component.
Definition: VectorI.H:73
Foam::IOobject::AUTO_WRITE
Definition: IOobject.H:194
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::Tensor::I
static const Tensor I
Definition: Tensor.H:85
Foam::waveModel::initialiseGeometry
virtual void initialiseGeometry()
Initialise.
Definition: waveModel.C:57
polyPatch.H
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::gAverage
Type gAverage(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:604
Foam::constant
Different types of constants.
Definition: atomicConstants.C:38
Foam::defineRunTimeSelectionTable
defineRunTimeSelectionTable(reactionRateFlameArea, dictionary)
Foam::constant::atomic::alpha
const dimensionedScalar alpha
Fine-structure constant: default SI units: [].
Definition: readThermalProperties.H:212
Foam::waveModel::alpha
virtual const scalarField & alpha() const
Return the latest wave indicator field prediction.
Definition: waveModel.C:416
dictName
const word dictName("faMeshDefinition")
gravityMeshObject.H
Foam::waveModel::waveModel
waveModel(const dictionary &dict, const fvMesh &mesh, const polyPatch &patch, const bool readFields=true)
Constructor.
Definition: waveModel.C:246
Foam::FatalIOError
IOerror FatalIOError
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::boundBox::max
const point & max() const
Maximum describing the bounding box.
Definition: boundBoxI.H:97
Foam::IOobject::info
InfoProxy< IOobject > info() const
Return info proxy.
Definition: IOobject.H:689
Foam::Vector::z
const Cmpt & z() const
Access to the vector z component.
Definition: VectorI.H:85
Foam::min
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
Foam::boundBox::min
const point & min() const
Minimum describing the bounding box.
Definition: boundBoxI.H:91
Foam::waveModel::waterLevel
virtual tmp< scalarField > waterLevel() const
Water level.
Definition: waveModel.C:128
Foam::sumOp
Definition: ops.H:213
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::waveModel::U
virtual const vectorField & U() const
Return the latest wave velocity prediction.
Definition: waveModel.C:410
Foam::blockMeshTools::read
void read(Istream &, label &val, const dictionary &)
In-place read with dictionary lookup.
Definition: blockMeshTools.C:57
Foam::Time::timeName
virtual word timeName() const
Return current time name.
Definition: Time.C:790
Foam::reduce
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamReduceOps.H:51
xMin
const scalar xMin
Definition: createFields.H:34
Foam::waveModel::setAlpha
virtual void setAlpha(const scalarField &level)
Set the alpha field based on the water level.
Definition: waveModel.C:163
Foam::Field< vector >
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::polyPatch
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:68
Foam::IOobject::READ_IF_PRESENT
Definition: IOobject.H:187
Foam::waveModel::modelName
static word modelName(const word &patchName)
Utility function to construct the model name.
Definition: waveModel.C:49
Foam::waveModel::setPaddlePropeties
virtual void setPaddlePropeties(const scalarField &level, const label facei, scalar &fraction, scalar &z) const
Set the paddle coverage fraction and reference height.
Definition: waveModel.C:191
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
Foam::add
void add(FieldField< Field1, typename typeOfSum< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
Definition: FieldFieldFunctions.C:939
os
OBJstream os(runTime.globalPath()/outputName)
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:85
fvMesh.H
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::Field::component
tmp< Field< cmptType > > component(const direction) const
Return a component field of the field.
Definition: Field.C:539
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::readFields
void readFields(const typename GeoFieldType::Mesh &mesh, const IOobjectList &objects, const wordHashSet &selectedFields, LIFOStack< regIOobject * > &storedObjects)
Read the selected GeometricFields of the templated type.
Definition: ReadFieldsTemplates.C:312
Foam::waveModel::readDict
virtual bool readDict(const dictionary &overrideDict)
Read from dictionary.
Definition: waveModel.C:295
Foam::normalised
VectorSpace< Form, Cmpt, Ncmpts > normalised(const VectorSpace< Form, Cmpt, Ncmpts > &vs)
Definition: VectorSpaceI.H:487
Foam::Vector::y
const Cmpt & y() const
Access to the vector y component.
Definition: VectorI.H:79
Foam::nl
constexpr char nl
Definition: Ostream.H:404
xMax
const scalar xMax
Definition: createFields.H:35
f
labelList f(nPoints)
Foam::foamVersion::patch
const std::string patch
OpenFOAM patch number as a std::string.
fvPatchFields.H
Foam::Vector< scalar >
Foam::List< face >
Foam::sqrt
dimensionedScalar sqrt(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:144
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::type
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: MSwindows.C:590
Foam::tmp::New
static tmp< T > New(Args &&... args)
Construct tmp of T with forwarding arguments.
Cp
const volScalarField & Cp
Definition: EEqn.H:7
x
x
Definition: LISASMDCalcMethod2.H:52
Foam::boundBox
A bounding box defined in terms of min/max extrema points.
Definition: boundBox.H:63
Foam::VectorSpace< Vector< scalar >, scalar, 3 >::zero
static const Vector< scalar > zero
Definition: VectorSpace.H:115
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:72
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::gMin
Type gMin(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:593
Foam::waveModel::correct
virtual void correct(const scalar t)
Correct the model for time, t[s].
Definition: waveModel.C:350
Foam::GeometricField< scalar, fvPatchField, volMesh >
Foam::IOobject::NO_READ
Definition: IOobject.H:188
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::tensor
Tensor< scalar > tensor
Tensor of scalars, i.e. Tensor<scalar>.
Definition: symmTensor.H:61
Foam::meshObjects::gravity::New
static const gravity & New(const Time &runTime)
Construct on Time.
Definition: gravityMeshObject.H:93
y
scalar y
Definition: LISASMDCalcMethod1.H:14
Foam::dictionary::dictName
word dictName() const
The local dictionary name (final part of scoped name)
Definition: dictionaryI.H:60