45 { motionTypes::piston,
"piston" },
46 { motionTypes::flap,
"flap" },
47 { motionTypes::solitary,
"solitary" }
57 if (
mag(gf.value()) < SMALL)
60 <<
"Gravity vector is not set. Please update " 61 << gf.uniformDimensionedVectorField::path()
78 for (label i=1; i<=100; ++i)
92 return max(0,
min(t/rampTime_, 1));
103 const scalar
xMin = bb.min().x();
104 const scalar
xMax = bb.max().x();
105 const scalar yMin = bb.min().y();
106 const scalar yMax = bb.max().y();
107 zSpan_ = bb.max().z() - bb.min().z();
109 zMinGb_ = bb.min().z();
113 xPaddle_.setSize(nPaddle_, 0);
114 yPaddle_.setSize(nPaddle_, 0);
116 const scalar paddleDy = (yMax - yMin)/scalar(nPaddle_);
118 for (label paddlei = 0; paddlei < nPaddle_; ++paddlei)
120 xPaddle_[paddlei] = xMid;
121 yPaddle_[paddlei] = paddlei*paddleDy + yMin + 0.5*paddleDy;
125 x_ = this->
patch().localPoints().component(0);
126 y_ = this->
patch().localPoints().component(1);
127 z_ = this->
patch().localPoints().component(2);
130 pointToPaddle_.setSize(this->
patch().size(), -1);
132 forAll(pointToPaddle_, ppi)
134 pointToPaddle_[ppi] = floor((y_[ppi] - yMin)/(paddleDy+0.01*paddleDy));
143 const DimensionedField<vector, pointMesh>& iF
146 fixedValuePointPatchField<
vector>(
p, iF),
147 motionType_(motionTypes::piston),
170 motionType_(motionTypeNames.
get(
"motionType",
dict)),
173 initialDepth_(
dict.
get<scalar>(
"initialDepth")),
174 wavePeriod_(
dict.
get<scalar>(
"wavePeriod")),
175 waveHeight_(
dict.
get<scalar>(
"waveHeight")),
176 wavePhase_(
dict.
get<scalar>(
"wavePhase")),
177 waveAngle_(
dict.getOrDefault<scalar>(
"waveAngle", 0)),
180 dict.getOrDefault<scalar>
186 rampTime_(
dict.
get<scalar>(
"rampTime")),
187 secondOrder_(
dict.getOrDefault<bool>(
"secondOrder", false)),
188 nPaddle_(
dict.getOrDefault<label>(
"nPaddle", 1))
194 <<
"Patch normal direction vector is not set. 'n' = " <<
n_ 203 <<
"Patch normal and gravity directions must not be aligned. " 204 <<
"'n' = " <<
n_ <<
" 'g' = " <<
g()
215 if (!
dict.found(
"value"))
224 const waveMakerPointPatchVectorField& ptf,
226 const DimensionedField<vector, pointMesh>& iF,
227 const pointPatchFieldMapper& mapper
230 fixedValuePointPatchField<
vector>(ptf,
p, iF, mapper),
231 motionType_(ptf.motionType_),
234 initialDepth_(ptf.initialDepth_),
235 wavePeriod_(ptf.wavePeriod_),
236 waveHeight_(ptf.waveHeight_),
237 wavePhase_(ptf.wavePhase_),
238 waveAngle_(ptf.waveAngle_),
239 startTime_(ptf.startTime_),
240 rampTime_(ptf.rampTime_),
241 secondOrder_(ptf.secondOrder_),
242 nPaddle_(ptf.nPaddle_)
253 motionType_(ptf.motionType_),
256 initialDepth_(ptf.initialDepth_),
257 wavePeriod_(ptf.wavePeriod_),
258 waveHeight_(ptf.waveHeight_),
259 wavePhase_(ptf.wavePhase_),
260 waveAngle_(ptf.waveAngle_),
261 startTime_(ptf.startTime_),
262 rampTime_(ptf.rampTime_),
263 secondOrder_(ptf.secondOrder_),
264 nPaddle_(ptf.nPaddle_)
280 if (initialDepth_ != 0 )
282 forAll(waterDepthRef_, paddlei)
284 waterDepthRef_[paddlei] = initialDepth_;
290 <<
"initialDepth is not set. Please update " 295 Info<<
" WaterDepth at the wavepaddles = " << waterDepthRef_ <<
endl;
299 const scalar t = db().time().value() - startTime_;
309 waveLength_[padddlei] =
310 waveLength(waterDepthRef_[padddlei], wavePeriod_);
313 waveKx[padddlei] = waveK[padddlei]*
cos(waveAngle_);
314 waveKy[padddlei] = waveK[padddlei]*
sin(waveAngle_);
320 case motionTypes::flap:
327 const label paddlei = pointToPaddle_[pointi];
329 const scalar phaseTot =
330 waveKx[paddlei]*xPaddle_[paddlei]
331 + waveKy[paddlei]*yPaddle_[paddlei];
333 const scalar depthRef = waterDepthRef_[paddlei];
334 const scalar kh = waveK[paddlei]*depthRef;
341 const scalar boardStroke = waveHeight_/m1;
343 motionX[pointi] = 0.5*boardStroke*
sin(phaseTot -
sigma*t);
348 sqr(waveHeight_)/(16*depthRef)
354 motionX[pointi] *= 1.0 + (pz - zMinGb_ - depthRef)/depthRef;
362 case motionTypes::piston:
369 const label paddlei = pointToPaddle_[pointi];
371 const scalar phaseTot =
372 waveKx[paddlei]*xPaddle_[paddlei]
373 + waveKy[paddlei]*yPaddle_[paddlei];
375 const scalar depthRef = waterDepthRef_[paddlei];
376 const scalar kh = waveK[paddlei]*depthRef;
377 const scalar m1 = 2*(
cosh(2*kh) - 1.0)/(
sinh(2*kh) + 2*kh);
378 const scalar boardStroke = waveHeight_/m1;
380 motionX[pointi] = 0.5*boardStroke*
sin(phaseTot -
sigma*t);
395 case motionTypes::solitary:
399 const scalar magG =
mag(
g());
403 const label paddlei = pointToPaddle_[pointi];
404 const scalar depthRef = waterDepthRef_[paddlei];
407 const scalar celerity =
sqrt(magG*(depthRef + waveHeight_));
408 const scalar stroke =
sqrt(16*waveHeight_*depthRef/3.0);
409 const scalar
hr = waveHeight_/depthRef;
410 wavePeriod_ = 2.0/(
kappa*celerity)*(3.8 +
hr);
411 const scalar tSolitary = -0.5*wavePeriod_ + t;
417 const scalar error = 0.001;
422 - (theta1 -
kappa*celerity*tSolitary +
hr*
tanh(theta1))
423 /(1.0 +
hr*(1.0/
cosh(theta1))*(1.0/
cosh(theta1)));
425 er =
mag(theta1 - theta2);
430 waveHeight_/(
kappa*depthRef)*
tanh(theta1) + 0.5*stroke;
440 <<
"Unhandled enumeration " << motionTypeNames[motionType_]
452 os.
writeEntry(
"motionType", motionTypeNames[motionType_]);
463 writeEntry(
"value",
os);
474 waveMakerPointPatchVectorField
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
List of values generated by applying the access operation to each list item.
dimensionedScalar tanh(const dimensionedScalar &ds)
errorManipArg< error, int > exit(error &err, const int errNo=1)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
const vector L(dict.get< vector >("L"))
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
virtual void write(Ostream &) const
Write.
A FixedValue boundary condition for pointField.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
dimensionedScalar sqrt(const dimensionedScalar &ds)
label nPaddle_
Number of wave paddles.
Ostream & endl(Ostream &os)
Add newline and flush stream.
virtual void updateCoeffs()
Update the coefficients associated with the patch field.
scalar waveAngle_
Wave angle.
A bounding box defined in terms of min/max extrema points.
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
virtual void updateCoeffs()
Update the coefficients associated with the patch field.
virtual scalar timeCoeff(const scalar t) const
Return the time scaling coefficient.
const dimensionedScalar kappa
Coulomb constant: default SI units: [N.m2/C2].
dimensionedScalar sigma("sigma", dimMass/sqr(dimTime), transportProperties)
const dimensionedScalar hr
Reduced Planck constant: default SI units: [J/s].
Macros for easy insertion into run-time selection tables.
vector n_
Patch normal direction.
#define forAll(list, i)
Loop across all elements in list.
const vector & g()
Return the gravitational acceleration.
virtual void initialiseGeometry()
Initialise.
static const Enum< motionTypes > motionTypeNames
Names for motion types.
vectorField pointField
pointField is a vectorField.
void setSize(const label n)
Alias for resize()
dimensionedScalar cos(const dimensionedScalar &ds)
constexpr scalar twoPi(2 *M_PI)
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Point motion boundary condition to generate waves based on either piston or flap motions.
static const gravity & New(const Time &runTime)
Return cached object or construct on Time.
constexpr scalar pi(M_PI)
const objectRegistry & db() const
The associated objectRegistry.
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
errorManip< error > abort(error &err)
tmp< Field< cmptType > > component(const direction) const
Return a component field of the field.
const uniformDimensionedVectorField & g
dimensionedScalar sin(const dimensionedScalar &ds)
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
const volScalarField & Cp
waveMakerPointPatchVectorField(const pointPatch &, const DimensionedField< vector, pointMesh > &)
Construct from patch and internal field.
OBJstream os(runTime.globalPath()/outputName)
void operator=(const Field< Type > &)
Copy assignment.
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
pointPatchField< vector > pointPatchVectorField
vector gHat_
Vertical direction.
const dimensionedScalar h
Planck constant.
scalarField waterDepthRef_
Calculated water depth at the patch.
virtual void write(Ostream &) const
Write.
dimensionedScalar pow3(const dimensionedScalar &ds)
virtual scalar waveLength(const scalar h, const scalar T)
Dispersion equation.
dimensionedScalar sinh(const dimensionedScalar &ds)
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Basic pointPatch represents a set of points from the mesh.
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
const std::string patch
OpenFOAM patch number as a std::string.
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
Reduce inplace (cf. MPI Allreduce) using specified communication schedule.
messageStream Info
Information stream (stdout output on master, null elsewhere)
makePointPatchTypeField(pointPatchVectorField, solidBodyMotionDisplacementPointPatchVectorField)
dimensionedScalar cosh(const dimensionedScalar &ds)
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
static constexpr const zero Zero
Global zero (0)