/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2018 OpenCFD Ltd. \\/ M anipulation | Copyright (C) 2018 IH-Cantabria ------------------------------------------------------------------------------- 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 "waveMakerPointPatchVectorField.H" #include "mathematicalConstants.H" #include "pointPatchFields.H" #include "addToRunTimeSelectionTable.H" #include "Time.H" #include "gravityMeshObject.H" // * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * * // const Foam::Enum Foam::waveMakerPointPatchVectorField::motionTypeNames ({ { motionTypes::piston, "piston" }, { motionTypes::flap, "flap" } }); // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * // const Foam::vector& Foam::waveMakerPointPatchVectorField::g() { const meshObjects::gravity& gf = meshObjects::gravity::New(db().time()); if (mag(gf.value()) < SMALL) { FatalErrorInFunction << "Gravity vector is not set. Please update " << gf.uniformDimensionedVectorField::path() << exit(FatalError); } return gf.value(); } Foam::scalar Foam::waveMakerPointPatchVectorField::waveLength ( const scalar h, const scalar T ) { const scalar L0 = mag(g())*T*T/(constant::mathematical::twoPi); scalar L = L0; for (label i=1; i<=100; ++i) { L = L0*tanh(constant::mathematical::twoPi*h/L); } return L; } Foam::scalar Foam::waveMakerPointPatchVectorField::timeCoeff ( const scalar t ) const { return max(0, min(t/rampTime_, 1)); } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::waveMakerPointPatchVectorField::waveMakerPointPatchVectorField ( const pointPatch& p, const DimensionedField& iF ) : fixedValuePointPatchField(p, iF), motionType_(motionTypes::piston), n_(Zero), gHat_(Zero), initialDepth_(0), wavePeriod_(0), waveHeight_(0), wavePhase_(0), waveLength_(0), rampTime_(0), secondOrder_(false) {} Foam::waveMakerPointPatchVectorField::waveMakerPointPatchVectorField ( const pointPatch& p, const DimensionedField& iF, const dictionary& dict ) : fixedValuePointPatchField(p, iF, dict, false), motionType_(motionTypeNames.lookup("motionType", dict)), n_(dict.get("n")), gHat_(Zero), initialDepth_(dict.get("initialDepth")), wavePeriod_(dict.get("wavePeriod")), waveHeight_(dict.get("waveHeight")), wavePhase_(dict.get("wavePhase")), waveLength_(this->waveLength(initialDepth_, wavePeriod_)), rampTime_(dict.get("rampTime")), secondOrder_(dict.lookupOrDefault("secondOrder", false)) { // Create the co-ordinate system if (mag(n_) < SMALL) { FatalIOErrorInFunction(dict) << "Patch normal direction vector is not set. 'n' = " << n_ << exit(FatalIOError); } n_ /= mag(n_); gHat_ = (g() - n_*(n_&g())); gHat_ /= mag(gHat_); if (!dict.found("value")) { updateCoeffs(); } } Foam::waveMakerPointPatchVectorField::waveMakerPointPatchVectorField ( const waveMakerPointPatchVectorField& ptf, const pointPatch& p, const DimensionedField& iF, const pointPatchFieldMapper& mapper ) : fixedValuePointPatchField(ptf, p, iF, mapper), motionType_(ptf.motionType_), n_(ptf.n_), gHat_(ptf.gHat_), initialDepth_(ptf.initialDepth_), wavePeriod_(ptf.wavePeriod_), waveHeight_(ptf.waveHeight_), wavePhase_(ptf.wavePhase_), waveLength_(ptf.waveLength_), rampTime_(ptf.rampTime_), secondOrder_(ptf.secondOrder_) {} Foam::waveMakerPointPatchVectorField::waveMakerPointPatchVectorField ( const waveMakerPointPatchVectorField& ptf, const DimensionedField& iF ) : fixedValuePointPatchField(ptf, iF), motionType_(ptf.motionType_), n_(ptf.n_), gHat_(ptf.gHat_), initialDepth_(ptf.initialDepth_), wavePeriod_(ptf.wavePeriod_), waveHeight_(ptf.waveHeight_), wavePhase_(ptf.wavePhase_), waveLength_(ptf.waveLength_), rampTime_(ptf.rampTime_), secondOrder_(ptf.secondOrder_) {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void Foam::waveMakerPointPatchVectorField::updateCoeffs() { if (this->updated()) { return; } const scalar t = db().time().value(); const scalar waveK = constant::mathematical::twoPi/waveLength_; const scalar sigma = constant::mathematical::twoPi/wavePeriod_; const scalar kh = waveK*initialDepth_; switch (motionType_) { case motionTypes::flap: { const scalar m1 = 4*sinh(kh)/(sinh(2*kh) + 2*kh)*(sinh(kh) + (1 - cosh(kh))/kh); scalar motionX = 0.5*waveHeight_/m1*sin(sigma*t); if (secondOrder_) { motionX += sqr(waveHeight_)/(16*initialDepth_) *(3*cosh(kh)/pow3(sinh(kh)) - 2/m1) *sin(2*sigma*t); } const pointField& points = patch().localPoints(); const scalarField dz(-(points & gHat_) - initialDepth_); Field::operator= ( n_*timeCoeff(t)*motionX*(1 + dz/initialDepth_) ); break; } case motionTypes::piston: { const scalar m1 = 2*(cosh(2*kh) - 1)/(sinh(2*kh) + 2*kh); scalar motionX = 0.5*waveHeight_/m1*sin(sigma*t); if (secondOrder_) { motionX += sqr(waveHeight_) /(32*initialDepth_)*(3*cosh(kh) /pow3(sinh(kh)) - 2/m1); } Field::operator=(n_*timeCoeff(t)*motionX); break; } default: { FatalErrorInFunction << "Unhandled enumeration " << motionTypeNames[motionType_] << abort(FatalError); } } fixedValuePointPatchField::updateCoeffs(); } void Foam::waveMakerPointPatchVectorField::write(Ostream& os) const { pointPatchField::write(os); os.writeEntry("motionType", motionTypeNames[motionType_]); os.writeEntry("n", n_); os.writeEntry("initialDepth", initialDepth_); os.writeEntry("wavePeriod", wavePeriod_); os.writeEntry("waveHeight", waveHeight_); os.writeEntry("wavePhase", wavePhase_); os.writeEntry("rampTime", rampTime_); os.writeEntry("secondOrder", secondOrder_); writeEntry("value", os); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { makePointPatchTypeField ( pointPatchVectorField, waveMakerPointPatchVectorField ); } // ************************************************************************* //