From efd3f59295df2d531e4bb749fdec30620ad86424 Mon Sep 17 00:00:00 2001 From: sergio Date: Tue, 13 Jul 2021 12:11:01 +0100 Subject: [PATCH] ENH: finiteArea: new models for shallow film modelling - new model framework: liquidFilm - new film turbulence models: filmTurbulenceModel with friction models - new velocity boundary condition: velocityFilmShell to handle/evolve regionFa film - new function object: setTimeStep to control the simulation time-step based on regionFa Courant number - add support for the absorption of Lagrangian particles into films --- src/lagrangian/coalCombustion/Make/options | 9 +- src/lagrangian/intermediate/Make/options | 9 +- .../SurfaceFilmModel/SurfaceFilmModel.C | 185 ++++-- .../SurfaceFilmModel/SurfaceFilmModel.H | 34 +- .../ThermoSurfaceFilm/ThermoSurfaceFilm.C | 191 +++++- .../ThermoSurfaceFilm/ThermoSurfaceFilm.H | 55 +- src/lagrangian/spray/Make/options | 9 +- src/lagrangian/turbulence/Make/options | 9 +- src/regionFaModels/Make/files | 11 + src/regionFaModels/Make/options | 7 +- .../velocityFilmShellFvPatchVectorField.C | 200 +++++++ .../velocityFilmShellFvPatchVectorField.H | 226 +++++++ .../setTimeStepFaRegionsFunctionObject.C | 163 +++++ .../setTimeStepFaRegionsFunctionObject.H | 156 +++++ .../kinematicThinFilm/kinematicThinFilm.C | 190 ++++++ .../kinematicThinFilm/kinematicThinFilm.H | 116 ++++ .../liquidFilm/liquidFilmBase.C | 566 ++++++++++++++++++ .../liquidFilm/liquidFilmBase.H | 302 ++++++++++ .../liquidFilm/liquidFilmBaseNew.C | 71 +++ .../liquidFilmModel/liquidFilmModel.C | 245 ++++++++ .../liquidFilmModel/liquidFilmModel.H | 203 +++++++ .../filmTurbulenceModel/filmTurbulenceModel.C | 170 ++++++ .../filmTurbulenceModel/filmTurbulenceModel.H | 183 ++++++ .../filmTurbulenceModelNew.C | 74 +++ .../filmTurbulenceModel/laminar/laminar.C | 117 ++++ .../filmTurbulenceModel/laminar/laminar.H | 116 ++++ 26 files changed, 3514 insertions(+), 103 deletions(-) create mode 100644 src/regionFaModels/derivedFvPatchFields/filmShell/velocityFilmShellFvPatchVectorField.C create mode 100644 src/regionFaModels/derivedFvPatchFields/filmShell/velocityFilmShellFvPatchVectorField.H create mode 100644 src/regionFaModels/functionObjects/setTimeStep/setTimeStepFaRegionsFunctionObject.C create mode 100644 src/regionFaModels/functionObjects/setTimeStep/setTimeStepFaRegionsFunctionObject.H create mode 100644 src/regionFaModels/liquidFilm/kinematicThinFilm/kinematicThinFilm.C create mode 100644 src/regionFaModels/liquidFilm/kinematicThinFilm/kinematicThinFilm.H create mode 100644 src/regionFaModels/liquidFilm/liquidFilmBase.C create mode 100644 src/regionFaModels/liquidFilm/liquidFilmBase.H create mode 100644 src/regionFaModels/liquidFilm/liquidFilmBaseNew.C create mode 100644 src/regionFaModels/liquidFilm/liquidFilmModel/liquidFilmModel.C create mode 100644 src/regionFaModels/liquidFilm/liquidFilmModel/liquidFilmModel.H create mode 100644 src/regionFaModels/liquidFilm/subModels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModel.C create mode 100644 src/regionFaModels/liquidFilm/subModels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModel.H create mode 100644 src/regionFaModels/liquidFilm/subModels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModelNew.C create mode 100644 src/regionFaModels/liquidFilm/subModels/kinematic/filmTurbulenceModel/laminar/laminar.C create mode 100644 src/regionFaModels/liquidFilm/subModels/kinematic/filmTurbulenceModel/laminar/laminar.H diff --git a/src/lagrangian/coalCombustion/Make/options b/src/lagrangian/coalCombustion/Make/options index 25ee31bf7d..5947708176 100644 --- a/src/lagrangian/coalCombustion/Make/options +++ b/src/lagrangian/coalCombustion/Make/options @@ -18,7 +18,10 @@ EXE_INC = \ -I$(LIB_SRC)/regionModels/regionModel/lnInclude \ -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \ -I$(LIB_SRC)/dynamicMesh/lnInclude \ - -I$(LIB_SRC)/dynamicFvMesh/lnInclude + -I$(LIB_SRC)/dynamicFvMesh/lnInclude \ + -I$(LIB_SRC)/regionFaModels/lnInclude \ + -I$(LIB_SRC)/finiteArea/lnInclude \ + -I$(LIB_SRC)/faOptions/lnInclude LIB_LIBS = \ -lfiniteVolume \ @@ -41,4 +44,6 @@ LIB_LIBS = \ -lregionModels \ -lsurfaceFilmModels \ -ldynamicMesh \ - -ldynamicFvMesh + -ldynamicFvMesh \ + -lregionFaModels \ + -lfiniteArea diff --git a/src/lagrangian/intermediate/Make/options b/src/lagrangian/intermediate/Make/options index d972d5b034..74eb95ca4c 100644 --- a/src/lagrangian/intermediate/Make/options +++ b/src/lagrangian/intermediate/Make/options @@ -16,7 +16,10 @@ EXE_INC = \ -I$(LIB_SRC)/regionModels/regionModel/lnInclude \ -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \ -I$(LIB_SRC)/dynamicMesh/lnInclude \ - -I$(LIB_SRC)/dynamicFvMesh/lnInclude + -I$(LIB_SRC)/dynamicFvMesh/lnInclude \ + -I$(LIB_SRC)/regionFaModels/lnInclude \ + -I$(LIB_SRC)/finiteArea/lnInclude \ + -I$(LIB_SRC)/faOptions/lnInclude LIB_LIBS = \ -lfiniteVolume \ @@ -36,4 +39,6 @@ LIB_LIBS = \ -lregionModels \ -lsurfaceFilmModels \ -ldynamicMesh \ - -ldynamicFvMesh + -ldynamicFvMesh \ + -lregionFaModels \ + -lfiniteArea diff --git a/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.C b/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.C index 5ef693076d..4696ac7021 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.C @@ -27,8 +27,9 @@ License \*---------------------------------------------------------------------------*/ #include "SurfaceFilmModel.H" -#include "surfaceFilmRegionModel.H" #include "mathematicalConstants.H" +#include "surfaceFilmRegionModel.H" +#include "liquidFilmBase.H" using namespace Foam::constant; @@ -102,6 +103,64 @@ Foam::SurfaceFilmModel::~SurfaceFilmModel() // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +template +template +void Foam::SurfaceFilmModel::injectParticles +( + const label primaryPatchi, + const labelList& injectorCellsPatch, + CloudTrackType& cloud +) +{ + const fvMesh& mesh = this->owner().mesh(); + const vectorField& Cf = mesh.C().boundaryField()[primaryPatchi]; + const vectorField& Sf = mesh.Sf().boundaryField()[primaryPatchi]; + const scalarField& magSf = + mesh.magSf().boundaryField()[primaryPatchi]; + + forAll(injectorCellsPatch, j) + { + if (diameterParcelPatch_[j] > 0) + { + const label celli = injectorCellsPatch[j]; + + const scalar offset = + max + ( + diameterParcelPatch_[j], + deltaFilmPatch_[primaryPatchi][j] + ); + const point pos = Cf[j] - 1.1*offset*Sf[j]/magSf[j]; + + // Create a new parcel + parcelType* pPtr = + new parcelType(this->owner().pMesh(), pos, celli); + + // Check/set new parcel thermo properties + cloud.setParcelThermoProperties(*pPtr, 0.0); + + setParcelProperties(*pPtr, j); + + if (pPtr->nParticle() > 0.001) + { + // Check new parcel properties +// cloud.checkParcelProperties(*pPtr, 0.0, true); + cloud.checkParcelProperties(*pPtr, 0.0, false); + + // Add the new parcel to the cloud + cloud.addParticle(pPtr); + + nParcelsInjected_++; + } + else + { + // TODO: cache mass and re-distribute? + delete pPtr; + } + } + } +} + template template void Foam::SurfaceFilmModel::inject(TrackCloudType& cloud) @@ -111,78 +170,63 @@ void Foam::SurfaceFilmModel::inject(TrackCloudType& cloud) return; } + const fvMesh& mesh = this->owner().mesh(); + const polyBoundaryMesh& pbm = mesh.boundaryMesh(); + // Retrieve the film model from the owner database - const regionModels::surfaceFilmModels::surfaceFilmRegionModel& filmModel = - this->owner().mesh().time().objectRegistry::template lookupObject + const regionModels::surfaceFilmModels::surfaceFilmRegionModel* filmModel = + mesh.time().objectRegistry::template findObject ( "surfaceFilmProperties" ); - if (!filmModel.active()) + // Check the singleLayer type of films + if (filmModel && filmModel->active()) { - return; + + const labelList& filmPatches = filmModel->intCoupledPatchIDs(); + const labelList& primaryPatches = filmModel->primaryPatchIDs(); + + forAll(filmPatches, i) + { + const label filmPatchi = filmPatches[i]; + const label primaryPatchi = primaryPatches[i]; + + const labelList& injectorCellsPatch = pbm[primaryPatchi].faceCells(); + + cacheFilmFields(filmPatchi, primaryPatchi, *filmModel); + + injectParticles(primaryPatchi, injectorCellsPatch, cloud); + } } - const labelList& filmPatches = filmModel.intCoupledPatchIDs(); - const labelList& primaryPatches = filmModel.primaryPatchIDs(); + // Check finite area films + wordList names = + mesh.time().objectRegistry::template + sortedNames(); - const fvMesh& mesh = this->owner().mesh(); - const polyBoundaryMesh& pbm = mesh.boundaryMesh(); - - forAll(filmPatches, i) + forAll (names, i) { - const label filmPatchi = filmPatches[i]; - const label primaryPatchi = primaryPatches[i]; + const regionModels::regionFaModel* regionFa = + mesh.time().objectRegistry::template cfindObject + < + regionModels::regionFaModel + >(names[i]); - const labelList& injectorCellsPatch = pbm[primaryPatchi].faceCells(); - - cacheFilmFields(filmPatchi, primaryPatchi, filmModel); - - const vectorField& Cf = mesh.C().boundaryField()[primaryPatchi]; - const vectorField& Sf = mesh.Sf().boundaryField()[primaryPatchi]; - const scalarField& magSf = mesh.magSf().boundaryField()[primaryPatchi]; - - forAll(injectorCellsPatch, j) + // Check that it is a type areaFilm + if (regionFa && isA(*regionFa)) { - if (diameterParcelPatch_[j] > 0) - { - const label celli = injectorCellsPatch[j]; + areaFilm& film = + const_cast(refCast(*regionFa)); - const scalar offset = - max - ( - diameterParcelPatch_[j], - deltaFilmPatch_[primaryPatchi][j] - ); - const point pos = Cf[j] - 1.1*offset*Sf[j]/magSf[j]; + const label patchId = regionFa->patchID(); - // Create a new parcel - parcelType* pPtr = - new parcelType(this->owner().pMesh(), pos, celli); + const labelList& injectorCellsPatch = pbm[patchId].faceCells(); - // Check/set new parcel thermo properties - cloud.setParcelThermoProperties(*pPtr, 0.0); + cacheFilmFields(patchId, film); - setParcelProperties(*pPtr, j); - - if (pPtr->nParticle() > 0.001) - { - // Check new parcel properties - // cloud.checkParcelProperties(*pPtr, 0.0, true); - cloud.checkParcelProperties(*pPtr, 0.0, false); - - // Add the new parcel to the cloud - cloud.addParticle(pPtr); - - nParcelsInjected_++; - } - else - { - // TODO: cache mass and re-distribute? - delete pPtr; - } - } + injectParticles(patchId, injectorCellsPatch, cloud); } } } @@ -215,6 +259,35 @@ void Foam::SurfaceFilmModel::cacheFilmFields } +template +void Foam::SurfaceFilmModel::cacheFilmFields +( + const label filmPatchi, + const regionModels::areaSurfaceFilmModels::liquidFilmBase& filmModel +) +{ + // WIP: the finite area film does not support splashing so far + //massParcelPatch_ = filmModel.cloudMassTrans().boundaryField()[filmPatchi]; + //filmModel.toPrimary(filmPatchi, massParcelPatch_); + massParcelPatch_.setSize(filmModel.Uf().size(), Zero); + diameterParcelPatch_.setSize(filmModel.Uf().size(), Zero); + // filmModel.cloudDiameterTrans().boundaryField()[filmPatchi]; + //filmModel.toPrimary(filmPatchi, diameterParcelPatch_, maxEqOp()); + const volSurfaceMapping& map = filmModel.region().vsm(); + + UFilmPatch_.setSize(filmModel.Uf().size(), Zero); + map.mapToField(filmModel.Uf(), UFilmPatch_); + //filmModel.toPrimary(filmPatchi, UFilmPatch_); + + rhoFilmPatch_.setSize(UFilmPatch_.size(), Zero); + map.mapToField(filmModel.rho(), rhoFilmPatch_); + //filmModel.toPrimary(filmPatchi, rhoFilmPatch_); + + deltaFilmPatch_[filmPatchi].setSize(UFilmPatch_.size(), Zero); + map.mapToField(filmModel.h(), deltaFilmPatch_[filmPatchi]); +} + + template void Foam::SurfaceFilmModel::setParcelProperties ( diff --git a/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.H b/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.H index ed23299906..0e5a7a4cef 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.H +++ b/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.H @@ -60,6 +60,15 @@ namespace regionModels } } +namespace regionModels +{ + namespace areaSurfaceFilmModels + { + class liquidFilmBase; + } +} + + /*---------------------------------------------------------------------------*\ Class SurfaceFilmModel Declaration \*---------------------------------------------------------------------------*/ @@ -76,6 +85,9 @@ protected: //- Convenience typedef to the cloud's parcel type typedef typename CloudType::parcelType parcelType; + typedef typename + regionModels::areaSurfaceFilmModels::liquidFilmBase areaFilm; + //- Gravitational acceleration constant const dimensionedVector& g_; @@ -94,13 +106,13 @@ protected: scalarList diameterParcelPatch_; //- Film velocity / patch face - List UFilmPatch_; + Field UFilmPatch_; //- Film density / patch face - scalarList rhoFilmPatch_; + scalarField rhoFilmPatch_; //- Film height of all film patches / patch face - scalarListList deltaFilmPatch_; + Field deltaFilmPatch_; // Counters @@ -122,6 +134,22 @@ protected: const regionModels::surfaceFilmModels::surfaceFilmRegionModel& ); + //- Cache the finite area film fields in preparation for injection + virtual void cacheFilmFields + ( + const label primaryPatchi, + const regionModels::areaSurfaceFilmModels::liquidFilmBase& + ); + + //- Inject particles in cloud + template + void injectParticles + ( + const label primaryPatchi, + const labelList& injectorCellsPatch, + TrackCloudType& cloud + ); + //- Set the individual parcel properties virtual void setParcelProperties ( diff --git a/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.C b/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.C index d45be7e042..70594de693 100644 --- a/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.C +++ b/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.C @@ -27,6 +27,8 @@ License \*---------------------------------------------------------------------------*/ #include "ThermoSurfaceFilm.H" +#include "surfaceFilmRegionModel.H" +#include "liquidFilmBase.H" #include "addToRunTimeSelectionTable.H" #include "unitConversion.H" #include "Pstream.H" @@ -131,7 +133,6 @@ Foam::vector Foam::ThermoSurfaceFilm::splashDirection template void Foam::ThermoSurfaceFilm::absorbInteraction ( - regionModels::surfaceFilmModels::surfaceFilmRegionModel& filmModel, const parcelType& p, const polyPatch& pp, const label facei, @@ -159,6 +160,56 @@ void Foam::ThermoSurfaceFilm::absorbInteraction // Parcel tangential velocity const vector Ut = Urel - Un; + if (filmModel_) + { + filmModel_->addSources + ( + pp.index(), + facei, + mass, // mass + mass*Ut, // tangential momentum + mass*mag(Un), // impingement pressure + mass*p.hs() // energy + ); + + this->nParcelsTransferred()++; + + keepParticle = false; + } +} + +template +void Foam::ThermoSurfaceFilm::absorbInteraction +( + areaFilm& filmModel, + const parcelType& p, + const polyPatch& pp, + const label facei, + const scalar mass, + bool& keepParticle +) +{ + + if (debug) + { + Info<< "Parcel " << p.origId() << " absorbInteraction" << endl; + } + + // Patch face normal + const vector& nf = pp.faceNormals()[facei]; + + // Patch velocity + const vector& Up = this->owner().U().boundaryField()[pp.index()][facei]; + + // Relative parcel velocity + const vector Urel = p.U() - Up; + + // Parcel normal velocity + const vector Un = nf*(Urel & nf); + + // Parcel tangential velocity + const vector Ut = Urel - Un; +DebugVar(mass) filmModel.addSources ( pp.index(), @@ -172,6 +223,7 @@ void Foam::ThermoSurfaceFilm::absorbInteraction this->nParcelsTransferred()++; keepParticle = false; + } @@ -208,7 +260,7 @@ void Foam::ThermoSurfaceFilm::bounceInteraction template void Foam::ThermoSurfaceFilm::drySplashInteraction ( - regionModels::surfaceFilmModels::surfaceFilmRegionModel& filmModel, + //regionModels::surfaceFilmModels::surfaceFilmRegionModel& filmModel, const parcelType& p, const polyPatch& pp, const label facei, @@ -249,14 +301,14 @@ void Foam::ThermoSurfaceFilm::drySplashInteraction if (We < Wec) // Adhesion - assume absorb { - absorbInteraction(filmModel, p, pp, facei, m, keepParticle); + absorbInteraction(p, pp, facei, m, keepParticle); } else // Splash { // Ratio of incident mass to splashing mass const scalar mRatio = 0.2 + 0.6*rndGen_.sample01(); splashInteraction - (filmModel, p, pp, facei, mRatio, We, Wec, sigma, keepParticle); + (p, pp, facei, mRatio, We, Wec, sigma, keepParticle); } } @@ -264,7 +316,7 @@ void Foam::ThermoSurfaceFilm::drySplashInteraction template void Foam::ThermoSurfaceFilm::wetSplashInteraction ( - regionModels::surfaceFilmModels::surfaceFilmRegionModel& filmModel, + //regionModels::surfaceFilmModels::surfaceFilmRegionModel& filmModel, parcelType& p, const polyPatch& pp, const label facei, @@ -307,7 +359,7 @@ void Foam::ThermoSurfaceFilm::wetSplashInteraction if (We < 2) // Adhesion - assume absorb { - absorbInteraction(filmModel, p, pp, facei, m, keepParticle); + absorbInteraction(p, pp, facei, m, keepParticle); } else if ((We >= 2) && (We < 20)) // Bounce { @@ -325,7 +377,7 @@ void Foam::ThermoSurfaceFilm::wetSplashInteraction } else if ((We >= 20) && (We < Wec)) // Spread - assume absorb { - absorbInteraction(filmModel, p, pp, facei, m, keepParticle); + absorbInteraction(p, pp, facei, m, keepParticle); } else // Splash { @@ -333,7 +385,7 @@ void Foam::ThermoSurfaceFilm::wetSplashInteraction // splash mass can be > incident mass due to film entrainment const scalar mRatio = 0.2 + 0.9*rndGen_.sample01(); splashInteraction - (filmModel, p, pp, facei, mRatio, We, Wec, sigma, keepParticle); + (p, pp, facei, mRatio, We, Wec, sigma, keepParticle); } } @@ -341,7 +393,7 @@ void Foam::ThermoSurfaceFilm::wetSplashInteraction template void Foam::ThermoSurfaceFilm::splashInteraction ( - regionModels::surfaceFilmModels::surfaceFilmRegionModel& filmModel, + //regionModels::surfaceFilmModels::surfaceFilmRegionModel& filmModel, const parcelType& p, const polyPatch& pp, const label facei, @@ -414,7 +466,7 @@ void Foam::ThermoSurfaceFilm::splashInteraction // Switch to absorb if insufficient energy for splash if (EKs <= 0) { - absorbInteraction(filmModel, p, pp, facei, m, keepParticle); + absorbInteraction(p, pp, facei, m, keepParticle); return; } @@ -469,7 +521,7 @@ void Foam::ThermoSurfaceFilm::splashInteraction // Transfer remaining part of parcel to film 0 - splashMass can be -ve // if entraining from the film const scalar mDash = m - mSplash; - absorbInteraction(filmModel, p, pp, facei, mDash, keepParticle); + absorbInteraction(p, pp, facei, mDash, keepParticle); } @@ -488,6 +540,7 @@ Foam::ThermoSurfaceFilm::ThermoSurfaceFilm ( owner.db().objectRegistry::template lookupObject("SLGThermo") ), + filmModel_(nullptr), TFilmPatch_(0), CpFilmPatch_(0), interactionType_ @@ -516,6 +569,18 @@ Foam::ThermoSurfaceFilm::ThermoSurfaceFilm this->coeffDict().readEntry("Awet", Awet_); this->coeffDict().readEntry("Cf", Cf_); } + + filmModel_ = + const_cast + ( + this->owner().mesh().time().objectRegistry::template findObject + < + regionModels::surfaceFilmModels::surfaceFilmRegionModel + > + ( + "surfaceFilmProperties" + ) + ); } @@ -528,6 +593,7 @@ Foam::ThermoSurfaceFilm::ThermoSurfaceFilm SurfaceFilmModel(sfm), rndGen_(sfm.rndGen_), thermo_(sfm.thermo_), + filmModel_(nullptr), TFilmPatch_(sfm.TFilmPatch_), CpFilmPatch_(sfm.CpFilmPatch_), interactionType_(sfm.interactionType_), @@ -538,7 +604,19 @@ Foam::ThermoSurfaceFilm::ThermoSurfaceFilm Awet_(sfm.Awet_), Cf_(sfm.Cf_), nParcelsSplashed_(sfm.nParcelsSplashed_) -{} +{ + filmModel_ = + const_cast + ( + this->owner().mesh().time().objectRegistry::template findObject + < + regionModels::surfaceFilmModels::surfaceFilmRegionModel + > + ( + "surfaceFilmProperties" + ) + ); +} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // @@ -558,21 +636,12 @@ bool Foam::ThermoSurfaceFilm::transferParcel bool& keepParticle ) { - // Retrieve the film model from the owner database - regionModels::surfaceFilmModels::surfaceFilmRegionModel& filmModel = - const_cast - ( - this->owner().db().time().objectRegistry::template - lookupObject - - ( - "surfaceFilmProperties" - ) - ); + const fvMesh& mesh = this->owner().mesh(); const label patchi = pp.index(); - if (filmModel.isRegionPatch(patchi)) + // Check the singleLayer film models + if (filmModel_ && filmModel_->isRegionPatch(patchi)) { const label facei = pp.whichFace(p.face()); @@ -587,7 +656,7 @@ bool Foam::ThermoSurfaceFilm::transferParcel case itAbsorb: { const scalar m = p.nParticle()*p.mass(); - absorbInteraction(filmModel, p, pp, facei, m, keepParticle); + absorbInteraction(p, pp, facei, m, keepParticle); break; } @@ -597,11 +666,11 @@ bool Foam::ThermoSurfaceFilm::transferParcel if (dry) { - drySplashInteraction(filmModel, p, pp, facei, keepParticle); + drySplashInteraction(p, pp, facei, keepParticle); } else { - wetSplashInteraction(filmModel, p, pp, facei, keepParticle); + wetSplashInteraction( p, pp, facei, keepParticle); } break; @@ -617,6 +686,54 @@ bool Foam::ThermoSurfaceFilm::transferParcel // Transfer parcel/parcel interactions complete return true; } + else + { + + // Check the finite area films + wordList names = + mesh.time().objectRegistry::template + sortedNames(); + + forAll(names, i) + { + const regionModels::regionFaModel* regionFa = + mesh.time().objectRegistry::template findObject + < + regionModels::regionFaModel + >(names[i]); + + // Check that regionFa is a areaFilm + if (regionFa && isA(*regionFa)) + { + areaFilm& film = + const_cast(refCast(*regionFa)); + + const label facei = pp.whichFace(p.face()); + + switch (interactionType_) + { + // It only supports absorp model + case itAbsorb: + { + const scalar m = p.nParticle()*p.mass(); + absorbInteraction + ( + film, p, pp, facei, m, keepParticle + ); + break; + } + default: + { + FatalErrorInFunction + << "Unknown interaction type enumeration" + << abort(FatalError); + } + } + // Transfer parcel/parcel interactions complete + return true; + } + } + } // Parcel not interacting with film return false; @@ -646,6 +763,26 @@ void Foam::ThermoSurfaceFilm::cacheFilmFields } +template +void Foam::ThermoSurfaceFilm::cacheFilmFields +( + const label filmPatchi, + const areaFilm& filmModel +) +{ + SurfaceFilmModel::cacheFilmFields + ( + filmPatchi, + filmModel + ); + const volSurfaceMapping& map = filmModel.region().vsm(); + + TFilmPatch_.setSize(filmModel.Tf().size(), Zero); + map.mapToField(filmModel.Tf(), TFilmPatch_); + //map.mapToField(filmModel.Cp(), CpFilmPatch_); +} + + template void Foam::ThermoSurfaceFilm::setParcelProperties ( diff --git a/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.H b/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.H index 186e951dbb..b1b821a294 100644 --- a/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.H +++ b/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.H @@ -61,6 +61,22 @@ SourceFiles namespace Foam { +//Forward declaration of classes +namespace regionModels +{ + namespace surfaceFilmModels + { + class surfaceFilmRegionModel; + } +} +namespace regionModels +{ + namespace areaSurfaceFilmModels + { + class liquidFilmBase; + } +} + /*---------------------------------------------------------------------------*\ Class ThermoSurfaceFilm Declaration \*---------------------------------------------------------------------------*/ @@ -102,20 +118,26 @@ protected: //- Convenience typedef to the cloud's parcel type typedef typename CloudType::parcelType parcelType; + typedef typename + regionModels::areaSurfaceFilmModels::liquidFilmBase areaFilm; + //- Reference to the cloud random number generator Random& rndGen_; //- Reference to the cloud thermo package const SLGThermo& thermo_; + //- Pointer to filmModel + regionModels::surfaceFilmModels::surfaceFilmRegionModel* filmModel_; + // Cached injector fields per film patch //- Film temperature / patch face - scalarList TFilmPatch_; + scalarField TFilmPatch_; //- Film specific heat capacity / patch face - scalarList CpFilmPatch_; + scalarField CpFilmPatch_; // Interaction model data @@ -173,7 +195,18 @@ protected: //- Absorb parcel into film void absorbInteraction ( - regionModels::surfaceFilmModels::surfaceFilmRegionModel&, + //regionModels::surfaceFilmModels::surfaceFilmRegionModel&, + const parcelType& p, + const polyPatch& pp, + const label facei, + const scalar mass, + bool& keepParticle + ); + + //- Absorb parcel into area film + void absorbInteraction + ( + areaFilm&, const parcelType& p, const polyPatch& pp, const label facei, @@ -193,7 +226,7 @@ protected: //- Parcel interaction with dry surface void drySplashInteraction ( - regionModels::surfaceFilmModels::surfaceFilmRegionModel&, + //regionModels::surfaceFilmModels::surfaceFilmRegionModel&, const parcelType& p, const polyPatch& pp, const label facei, @@ -203,7 +236,7 @@ protected: //- Parcel interaction with wetted surface void wetSplashInteraction ( - regionModels::surfaceFilmModels::surfaceFilmRegionModel&, + //regionModels::surfaceFilmModels::surfaceFilmRegionModel&, parcelType& p, const polyPatch& pp, const label facei, @@ -213,7 +246,7 @@ protected: //- Bai parcel splash interaction model void splashInteraction ( - regionModels::surfaceFilmModels::surfaceFilmRegionModel&, + //regionModels::surfaceFilmModels::surfaceFilmRegionModel&, const parcelType& p, const polyPatch& pp, const label facei, @@ -224,18 +257,24 @@ protected: bool& keepParticle ); + virtual void cacheFilmFields + ( + const label primaryPatchi, + const areaFilm& + ); // Injection from sheet (ejection) helper functions - //- Cache the film fields in preparation for injection + //- Cache the film fields in preparation for injection virtual void cacheFilmFields ( const label filmPatchi, const label primaryPatchi, const regionModels::surfaceFilmModels::surfaceFilmRegionModel& - filmModel ); + + //- Set the individual parcel properties virtual void setParcelProperties ( diff --git a/src/lagrangian/spray/Make/options b/src/lagrangian/spray/Make/options index d595ada329..443d427398 100644 --- a/src/lagrangian/spray/Make/options +++ b/src/lagrangian/spray/Make/options @@ -20,7 +20,10 @@ EXE_INC = \ -I$(LIB_SRC)/regionModels/regionModel/lnInclude \ -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \ -I$(LIB_SRC)/dynamicMesh/lnInclude \ - -I$(LIB_SRC)/dynamicFvMesh/lnInclude + -I$(LIB_SRC)/dynamicFvMesh/lnInclude \ + -I$(LIB_SRC)/regionFaModels/lnInclude \ + -I$(LIB_SRC)/finiteArea/lnInclude \ + -I$(LIB_SRC)/faOptions/lnInclude LIB_LIBS = \ -lfiniteVolume \ @@ -44,4 +47,6 @@ LIB_LIBS = \ -lregionModels \ -lsurfaceFilmModels \ -ldynamicMesh \ - -ldynamicFvMesh + -ldynamicFvMesh \ + -lregionFaModels \ + -lfiniteArea diff --git a/src/lagrangian/turbulence/Make/options b/src/lagrangian/turbulence/Make/options index 7be9fe24ee..e2fc84c325 100644 --- a/src/lagrangian/turbulence/Make/options +++ b/src/lagrangian/turbulence/Make/options @@ -18,7 +18,10 @@ EXE_INC = \ -I$(LIB_SRC)/transportModels \ -I$(LIB_SRC)/regionModels/regionModel/lnInclude \ -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \ - -I$(LIB_SRC)/dynamicFvMesh/lnInclude + -I$(LIB_SRC)/dynamicFvMesh/lnInclude \ + -I$(LIB_SRC)/regionFaModels/lnInclude \ + -I$(LIB_SRC)/finiteArea/lnInclude \ + -I$(LIB_SRC)/faOptions/lnInclude LIB_LIBS = \ -lfiniteVolume \ @@ -40,4 +43,6 @@ LIB_LIBS = \ -lincompressibleTransportModels \ -lregionModels \ -lsurfaceFilmModels \ - -ldynamicFvMesh + -ldynamicFvMesh \ + -lregionFaModels \ + -lfiniteArea diff --git a/src/regionFaModels/Make/files b/src/regionFaModels/Make/files index 3a3b9a4add..70521f391a 100644 --- a/src/regionFaModels/Make/files +++ b/src/regionFaModels/Make/files @@ -13,4 +13,15 @@ KirchhoffShell/KirchhoffShell.C derivedFvPatchFields/thermalShell/thermalShellFvPatchScalarField.C derivedFvPatchFields/vibrationShell/vibrationShellFvPatchScalarField.C +liquidFilm/liquidFilmBase.C +liquidFilm/liquidFilmBaseNew.C +liquidFilm/subModels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModel.C +liquidFilm/subModels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModelNew.C +liquidFilm/subModels/kinematic/filmTurbulenceModel/laminar/laminar.C +liquidFilm/liquidFilmModel/liquidFilmModel.C +liquidFilm/kinematicThinFilm/kinematicThinFilm.C +derivedFvPatchFields/filmShell/velocityFilmShellFvPatchVectorField.C + +functionObjects/setTimeStep/setTimeStepFaRegionsFunctionObject.C + LIB = $(FOAM_LIBBIN)/libregionFaModels diff --git a/src/regionFaModels/Make/options b/src/regionFaModels/Make/options index cd4795b38d..2af18fc4d1 100644 --- a/src/regionFaModels/Make/options +++ b/src/regionFaModels/Make/options @@ -5,7 +5,12 @@ EXE_INC = \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/thermophysicalModels/thermophysicalProperties/lnInclude \ -I$(LIB_SRC)/thermophysicalModels/specie/lnInclude \ - -I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude + -I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \ + -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \ + -I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \ + -I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \ + -I$(LIB_SRC)/transportModels/compressible/lnInclude \ + -I$(LIB_SRC)/transportModels LIB_LIBS = \ -lfiniteVolume \ diff --git a/src/regionFaModels/derivedFvPatchFields/filmShell/velocityFilmShellFvPatchVectorField.C b/src/regionFaModels/derivedFvPatchFields/filmShell/velocityFilmShellFvPatchVectorField.C new file mode 100644 index 0000000000..e2fe02f80f --- /dev/null +++ b/src/regionFaModels/derivedFvPatchFields/filmShell/velocityFilmShellFvPatchVectorField.C @@ -0,0 +1,200 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 "velocityFilmShellFvPatchVectorField.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +velocityFilmShellFvPatchVectorField::velocityFilmShellFvPatchVectorField +( + const fvPatch& p, + const DimensionedField& iF +) +: + mixedFvPatchField(p, iF), + baffle_(), + dict_(dictionary::null), + curTimeIndex_(-1), + zeroWallVelocity_(true) +{ + refValue() = 0; + refGrad() = 0; + valueFraction() = 1; +} + + +velocityFilmShellFvPatchVectorField::velocityFilmShellFvPatchVectorField +( + const velocityFilmShellFvPatchVectorField& ptf, + const fvPatch& p, + const DimensionedField& iF, + const fvPatchFieldMapper& mapper +) +: + mixedFvPatchField + ( + ptf, + p, + iF, + mapper + ), + baffle_(), + dict_(ptf.dict_), + curTimeIndex_(-1), + zeroWallVelocity_(true) +{} + + +velocityFilmShellFvPatchVectorField::velocityFilmShellFvPatchVectorField +( + const fvPatch& p, + const DimensionedField& iF, + const dictionary& dict +) +: + mixedFvPatchField(p, iF), + baffle_(nullptr), + dict_(dict), + curTimeIndex_(-1), + zeroWallVelocity_(dict.getOrDefault("zeroWallVelocity", true)) +{ + fvPatchVectorField::operator=(vectorField("value", dict, p.size())); + + typedef regionModels::areaSurfaceFilmModels::liquidFilmBase baffle; + + if (dict.found("refValue")) + { + // Full restart + refValue() = vectorField("refValue", dict, p.size()); + refGrad() = vectorField("refGradient", dict, p.size()); + valueFraction() = scalarField("valueFraction", dict, p.size()); + } + else + { + // Start from user entered data. Assume fixedValue. + refValue() = *this; + refGrad() = vector::zero; + valueFraction() = 1; + } + + if (!baffle_) + { + baffle_.reset(baffle::New(p, dict).ptr()); + } +} + + +velocityFilmShellFvPatchVectorField::velocityFilmShellFvPatchVectorField +( + const velocityFilmShellFvPatchVectorField& ptf, + const DimensionedField& iF +) +: + mixedFvPatchField(ptf, iF), + baffle_(), + dict_(ptf.dict_), + curTimeIndex_(-1), + zeroWallVelocity_(true) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + + +void velocityFilmShellFvPatchVectorField::updateCoeffs() +{ + if (this->updated()) + { + return; + } + + // Execute the change to the openFraction only once per time-step + if (curTimeIndex_ != this->db().time().timeIndex()) + { + baffle_->evolve(); + + volVectorField::Boundary& vfb = + db().lookupObjectRef + ( + this->internalField().name() + ).boundaryFieldRef(); + + baffle_->vsm().mapToVolume(baffle_->Us(), vfb); + + refGrad() = Zero; + valueFraction() = 1; + + if (zeroWallVelocity_) + { + refValue() = Zero; + } + else + { + refValue() = vfb[patch().index()]; + } + curTimeIndex_ = this->db().time().timeIndex(); + } + + mixedFvPatchField::updateCoeffs(); +} + + +void velocityFilmShellFvPatchVectorField::write(Ostream& os) const +{ + mixedFvPatchField::write(os); + + // Remove value and type already written by mixedFvPatchField + dict_.remove("value"); + dict_.remove("type"); + dict_.remove("refValue"); + dict_.remove("refGradient"); + dict_.remove("valueFraction"); + dict_.write(os, false); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +makePatchTypeField +( + fvPatchVectorField, + velocityFilmShellFvPatchVectorField +); + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + + +// ************************************************************************* // diff --git a/src/regionFaModels/derivedFvPatchFields/filmShell/velocityFilmShellFvPatchVectorField.H b/src/regionFaModels/derivedFvPatchFields/filmShell/velocityFilmShellFvPatchVectorField.H new file mode 100644 index 0000000000..66ba8205ee --- /dev/null +++ b/src/regionFaModels/derivedFvPatchFields/filmShell/velocityFilmShellFvPatchVectorField.H @@ -0,0 +1,226 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 OpenCFD Ltd. +------------------------------------------------------------------------------- +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::compressible::velocityFilmShellFvPatchVectorField + +Group + grpLiquidFilmBoundaryConditions + +Description + +Usage + Example of the boundary condition specification: + \verbatim + + { + type velocityFilmShell; + + active true; + infoOutput true; + + U U; + pRef 1e5; + T0 300; + + deltaWet 1e-4; + h0 1e-8; + + zeroWallVelocity true; + + thermo + { + H2O; + } + + turbulence laminar; + + laminarCoeffs + { + friction ManningStrickler; // Wall friction model + n 0.005; // Manning number + Cf 0.9; // Gas friction + } + + injectionModels + ( + curvatureSeparation + ); + + forces (); + + curvatureSeparationCoeffs + { + definedPatchRadii 0; + } + + region film; + liquidFilmModel kinematicThinFilm; + + value uniform (0 0 0); + } + \endverbatim + + where the entries mean: + \table + Property | Description | Type | Reqd | Deflt + type | Type name: velocityFilmShell | word | yes | - + U | Name of the primary U | word | yes | - + pRef | Reference pressure for thermo | scalar | yes | - + T0 | Film initial temperature | scalar | no | READ + thermo | Flow thermo | wordRes | yes | - + zeroWallVelocity | Flag to fix zero U for primary flow | bool | no | true + turbulence | Type of film turbulence model | word | yes | - + injectionModels | Lagrangian injection | | no | - + forces | Film force models | wordRes | no | - + deltaWet | Wet film thickness | scalar | no | 1e-4 + h0 | Numerical minimum thickness | scalar | no | 1e-7 + region | Name of the 2D region | word | yes | - + liquidFilmModel | Film model | word | yes | - + \endtable + +SourceFiles + velocityFilmShellFvPatchVectorField.C + +\*---------------------------------------------------------------------------*/ + +#ifndef velocityFilmShellFvPatchVectorField_H +#define velocityFilmShellFvPatchVectorField_H + +#include "autoPtr.H" +#include "liquidFilmBase.H" +#include "mixedFvPatchFields.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class velocityFilmShellFvPatchVectorField Declaration +\*---------------------------------------------------------------------------*/ + +class velocityFilmShellFvPatchVectorField +: + public mixedFvPatchField +{ + // Private Data + + //- Thermal baffle + autoPtr baffle_; + + //- Dictionary + mutable dictionary dict_; + + //- Time index to evolve the film + label curTimeIndex_; + + //- Zero wall velocity. Fix U to zero or to film U + bool zeroWallVelocity_; + + +public: + + //- Runtime type information + TypeName("velocityFilmShell"); + + + // Constructors + + //- Construct from patch and internal field + velocityFilmShellFvPatchVectorField + ( + const fvPatch&, + const DimensionedField& + ); + + //- Construct from patch, internal field and dictionary + velocityFilmShellFvPatchVectorField + ( + const fvPatch&, + const DimensionedField&, + const dictionary& + ); + + //- Construct by mapping given + //- velocityFilmShellFvPatchVectorField onto a new patch + velocityFilmShellFvPatchVectorField + ( + const velocityFilmShellFvPatchVectorField&, + const fvPatch&, + const DimensionedField&, + const fvPatchFieldMapper& + ); + + //- Construct and return a clone + virtual tmp clone() const + { + return tmp + ( + new velocityFilmShellFvPatchVectorField(*this) + ); + } + + //- Construct as copy setting internal field reference + velocityFilmShellFvPatchVectorField + ( + const velocityFilmShellFvPatchVectorField&, + const DimensionedField& + ); + + //- Construct and return a clone setting internal field reference + virtual tmp clone + ( + const DimensionedField& iF + ) const + { + return tmp + ( + new velocityFilmShellFvPatchVectorField(*this, iF) + ); + } + + + // Member Functions + + //- Update the coefficients associated with the patch field + virtual void updateCoeffs(); + + //- Write + virtual void write(Ostream&) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + +#endif + +// ************************************************************************* // diff --git a/src/regionFaModels/functionObjects/setTimeStep/setTimeStepFaRegionsFunctionObject.C b/src/regionFaModels/functionObjects/setTimeStep/setTimeStepFaRegionsFunctionObject.C new file mode 100644 index 0000000000..3b5e95ffd1 --- /dev/null +++ b/src/regionFaModels/functionObjects/setTimeStep/setTimeStepFaRegionsFunctionObject.C @@ -0,0 +1,163 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 "setTimeStepFaRegionsFunctionObject.H" +#include "addToRunTimeSelectionTable.H" + + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace functionObjects +{ + defineTypeNameAndDebug(setTimeStepFaRegionsFunctionObject, 0); + addToRunTimeSelectionTable + ( + functionObject, + setTimeStepFaRegionsFunctionObject, + dictionary + ); +} +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::functionObjects:: +setTimeStepFaRegionsFunctionObject:: +setTimeStepFaRegionsFunctionObject +( + const word& name, + const Time& runTime, + const dictionary& dict +) +: + timeFunctionObject(name, runTime) +{ + read(dict); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::functionObjects::setTimeStepFaRegionsFunctionObject::adjustTimeStep() +{ + // Wanted timestep + scalar newDeltaT = regionDeltaT(); + + static label index = -1; + + if ((time_.timeIndex() != index) && (newDeltaT < time_.deltaTValue())) + { + // Store current time so we don't get infinite recursion (since + // setDeltaT calls adjustTimeStep() again) + index = time_.timeIndex(); + + // Set time, allow deltaT to be adjusted for writeInterval purposes + const_cast(time_).setDeltaT(newDeltaT, false); + + return true; + } + + return false; +} + + +bool Foam::functionObjects::setTimeStepFaRegionsFunctionObject::read +( + const dictionary& dict +) +{ + if (timeFunctionObject::read(dict)) + { + // Ensure that adjustTimeStep is active + if (!time_.controlDict().lookupOrDefault("adjustTimeStep", false)) + { + FatalIOErrorInFunction(dict) + << "Need to set 'adjustTimeStep' true to allow timestep control" + << nl + << exit(FatalIOError); + } + + return true; + } + + return false; +} + + +Foam::scalar Foam::functionObjects::setTimeStepFaRegionsFunctionObject:: +regionDeltaT() const +{ + const wordList names(time_.sortedNames()); + + scalar Co = 0.0; + + forAll (names, i) + { + const auto* regionFa = time_.cfindObject(names[i]); + + if (regionFa) + { + const scalar regionCo = regionFa->CourantNumber(); + if (regionCo > Co) + { + Co = regionCo; + } + } + } + + if (names.size() > 0) + { + const scalar regionFaMaxCo = + time_.controlDict().get("regionFaMaxCo"); + + const scalar maxDeltaTFact = regionFaMaxCo/(Co + SMALL); + const scalar deltaTFact = + min(min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2); + + return deltaTFact*time_.deltaTValue(); + } + + return time_.deltaTValue(); +} + + +bool Foam::functionObjects::setTimeStepFaRegionsFunctionObject::execute() +{ + return true; +} + + +bool Foam::functionObjects::setTimeStepFaRegionsFunctionObject::write() +{ + return true; +} + + +// ************************************************************************* // diff --git a/src/regionFaModels/functionObjects/setTimeStep/setTimeStepFaRegionsFunctionObject.H b/src/regionFaModels/functionObjects/setTimeStep/setTimeStepFaRegionsFunctionObject.H new file mode 100644 index 0000000000..6c61535720 --- /dev/null +++ b/src/regionFaModels/functionObjects/setTimeStep/setTimeStepFaRegionsFunctionObject.H @@ -0,0 +1,156 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 OpenCFD Ltd. +------------------------------------------------------------------------------- +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::functionObjects::setTimeStepFaRegionsFunctionObject + +Group + grpUtilitiesFunctionObjects + +Description + This function object controls the time step for classes of the type + \c regionFaModel. It reads \c regionFaMaxCo entry from \c controlDict + and evaluate the time step based on the finite area Courant Number. + + Can only be used with solvers using \c adjustTimeStep control (e.g. + \c pimpleFoam). It makes no attempt to co-operate with other time step + 'controllers', e.g. \c maxCo, other functionObjects. Supports \c enabled + flag but none of the other options \c timeStart, \c timeEnd, \c writeControl + etc. + +Usage + Example of function object specification to manipulate the time step: + \verbatim + setTimeStep1 + { + // Mandatory entries + type setTimeStepFaRegion; + + // Inherited entries + ... + } + \endverbatim + + where the entries mean: + \table + Property | Description | Type | Reqd | Deflt + type | Type name: setTimeStepFaRegion | word | yes | - + enabled | On/off switch | bool | no | yes + \endtable + + The inherited entries are elaborated in: + - \link timeFunctionObject.H \endlink + - \link regionFaModel.H \endlink + +SourceFiles + setTimeStepFaRegionsFunctionObject.C + +\*---------------------------------------------------------------------------*/ + +#ifndef functionObjects_setTimeStepFaRegionsFunctionObject_H +#define functionObjects_setTimeStepFaRegionsFunctionObject_H + +#include "timeFunctionObject.H" +#include "regionFaModel.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +using namespace Foam::regionModels; + +namespace Foam +{ +namespace functionObjects +{ + +/*---------------------------------------------------------------------------*\ + Class setTimeStepFaRegionsFunctionObject Declaration +\*---------------------------------------------------------------------------*/ + +class setTimeStepFaRegionsFunctionObject +: + public functionObjects::timeFunctionObject +{ + // Private Member Functions + + //- No copy construct + setTimeStepFaRegionsFunctionObject + ( + const setTimeStepFaRegionsFunctionObject& + ) = delete; + + //- No copy assignment + void operator=(const setTimeStepFaRegionsFunctionObject&) = delete; + + //- Return minimum deltaT from fa regions + scalar regionDeltaT() const; + + +public: + + //- Runtime type information + TypeName("setTimeStepFaRegion"); + + + // Constructors + + //- Construct from components + setTimeStepFaRegionsFunctionObject + ( + const word& name, + const Time& runTime, + const dictionary& dict + ); + + + // Destructor + virtual ~setTimeStepFaRegionsFunctionObject() = default; + + + // Member Functions + + //- Called at the end of Time::adjustDeltaT() if adjustTime is true + virtual bool adjustTimeStep(); + + //- Read and set the function object if its data have changed + virtual bool read(const dictionary& dict); + + //- Execute does nothing + virtual bool execute(); + + //- Write does nothing + virtual bool write(); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace functionObjects +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/regionFaModels/liquidFilm/kinematicThinFilm/kinematicThinFilm.C b/src/regionFaModels/liquidFilm/kinematicThinFilm/kinematicThinFilm.C new file mode 100644 index 0000000000..1fc4b873ab --- /dev/null +++ b/src/regionFaModels/liquidFilm/kinematicThinFilm/kinematicThinFilm.C @@ -0,0 +1,190 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 "kinematicThinFilm.H" +#include "addToRunTimeSelectionTable.H" +#include "uniformDimensionedFields.H" +#include "volFields.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace regionModels +{ +namespace areaSurfaceFilmModels +{ + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +defineTypeNameAndDebug(kinematicThinFilm, 0); +addToRunTimeSelectionTable(liquidFilmBase, kinematicThinFilm, dictionary); + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +kinematicThinFilm::kinematicThinFilm +( + const word& modelType, + const fvPatch& patch, + const dictionary& dict +) +: + liquidFilmModel(modelType, patch, dict) +{} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +void kinematicThinFilm::preEvolveRegion() +{ + rhoSp_.storePrevIter(); + USp_.storePrevIter(); + pnSp_.storePrevIter(); + + // Update mass exchange sources + liquidFilmModel::preEvolveRegion(); + + // gas pressure map from primary region + ppf_ = pg(); +} + + +void kinematicThinFilm::evolveRegion() +{ + if (debug) + { + InfoInFunction << endl; + } + + const areaVectorField& ns = regionMesh().faceAreaNormals(); + + const areaVectorField gs(g_ - ns*(ns & g_)); + + phi2s_ = fac::interpolate(h_)*phif_; + + for (int oCorr=1; oCorr<=nOuterCorr_; oCorr++) + { + pf_.storePrevIter(); + + faVectorMatrix UsEqn + ( + fam::ddt(h_, Uf_) + + fam::div(phi2s_, Uf_) + == + gs*h_ + + turbulence_->Su(Uf_) + + faOptions()(h_, Uf_, sqr(dimVelocity)) + + forces_.correct(Uf_) + + USp_ + ); + + UsEqn.relax(); + + faOptions().constrain(UsEqn); + + if (momentumPredictor_) + { + solve(UsEqn == - fac::grad(pf_*h_)/rho_ + pf_*fac::grad(h_)/rho_); + } + + for (int corr=1; corr<=nCorr_; corr++) + { + areaScalarField UsA(UsEqn.A()); + + Uf_ = UsEqn.H()/UsA; + Uf_.correctBoundaryConditions(); + faOptions().correct(Uf_); + + phif_ = + (fac::interpolate(Uf_) & regionMesh().Le()) + - fac::interpolate(1.0/(rho_*UsA)) + * fac::lnGrad(pf_*h_)*regionMesh().magLe() + + fac::interpolate(pf_/(rho_*UsA)) + * fac::lnGrad(h_)*regionMesh().magLe(); + + for (int nFilm=1; nFilm<=nFilmCorr_; nFilm++) + { + faScalarMatrix hEqn + ( + fam::ddt(h_) + + fam::div(phif_, h_) + == + faOptions()(rho_, h_, dimVelocity) + + rhoSp_ + ); + + hEqn.relax(); + faOptions().constrain(hEqn); + hEqn.solve(); + faOptions().correct(h_); + + if (nFilm == nFilmCorr_) + { + phi2s_ = hEqn.flux(); + } + } + + // Bound h_ + h_ = max(h_, h0_); + + pf_ = rho_*gn_*h_ - sigma_*fac::laplacian(h_) + pnSp_ + ppf_; + pf_.correctBoundaryConditions(); + pf_.relax(); + + Uf_ -= (1.0/(rho_*UsA))*fac::grad(pf_*h_) + - (pf_/(rho_*UsA))*fac::grad(h_); + Uf_.correctBoundaryConditions(); + faOptions().correct(Uf_); + } + } + + Info<< "Film h min/max = " << min(h_).value() << ", " + << max(h_).value() << endl; + + Info<< "Film U min/max = " << max(mag(Uf_)).value() << endl; +} + + +void kinematicThinFilm::postEvolveRegion() +{ + // Reset sources + liquidFilmModel::postEvolveRegion(); + + // Correct thermo + correctThermoFields(); + + // Correct turbulence + turbulence_->correct(); +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace areaSurfaceFilmModels +} // End namespace regionModels +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/regionFaModels/liquidFilm/kinematicThinFilm/kinematicThinFilm.H b/src/regionFaModels/liquidFilm/kinematicThinFilm/kinematicThinFilm.H new file mode 100644 index 0000000000..bad60d4954 --- /dev/null +++ b/src/regionFaModels/liquidFilm/kinematicThinFilm/kinematicThinFilm.H @@ -0,0 +1,116 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 OpenCFD Ltd. +------------------------------------------------------------------------------- +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::regionFaModels::kinematicThinFilm + +Description + Thin film model. + +SourceFiles + kinematicThinFilm.C + kinematicThinFilmI.H + +\*---------------------------------------------------------------------------*/ + +#ifndef kinematicThinFilm_H +#define kinematicThinFilm_H + +#include "volFieldsFwd.H" +#include "liquidFilmModel.H" +#include "faMesh.H" +#include "filmTurbulenceModel.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace regionModels +{ +namespace areaSurfaceFilmModels +{ + +/*---------------------------------------------------------------------------*\ + Class kinematicThinFilm Declaration +\*---------------------------------------------------------------------------*/ + +class kinematicThinFilm +: + public liquidFilmModel +{ +public: + + //- Runtime type information + TypeName("kinematicThinFilm"); + + + // Constructors + + //- Construct from components and dict + kinematicThinFilm + ( + const word& modelType, + const fvPatch& patch, + const dictionary& dict + ); + + //- No copy construct + kinematicThinFilm(const kinematicThinFilm&) = delete; + + //- No copy assignment + void operator=(const kinematicThinFilm&) = delete; + + + //- Destructor + virtual ~kinematicThinFilm() = default; + + + // Member Functions + + // Evolution + + //- Pre-evolve film + virtual void preEvolveRegion(); + + //- Evolve the film + virtual void evolveRegion(); + + //- Post-evolve film + virtual void postEvolveRegion(); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace areaSurfaceFilmModels +} // End namespace regionModels +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + +#endif + +// ************************************************************************* // diff --git a/src/regionFaModels/liquidFilm/liquidFilmBase.C b/src/regionFaModels/liquidFilm/liquidFilmBase.C new file mode 100644 index 0000000000..540bbe9da9 --- /dev/null +++ b/src/regionFaModels/liquidFilm/liquidFilmBase.C @@ -0,0 +1,566 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 "liquidFilmBase.H" +#include "faMesh.H" +#include "faCFD.H" +#include "uniformDimensionedFields.H" +#include "gravityMeshObject.H" +#include "movingWallVelocityFvPatchVectorField.H" +#include "turbulentFluidThermoModel.H" +#include "turbulentTransportModel.H" +#include "calculatedFvPatchFields.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace regionModels +{ +namespace areaSurfaceFilmModels +{ + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +defineTypeNameAndDebug(liquidFilmBase, 0); + +defineRunTimeSelectionTable(liquidFilmBase, dictionary); + +const Foam::word liquidFilmName("liquidFilm"); + +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + + +bool liquidFilmBase::read(const dictionary& dict) +{ + regionFaModel::read(dict); + if (active_) + { + const dictionary& solution = this->solution().subDict("PISO"); + solution.readEntry("momentumPredictor", momentumPredictor_); + solution.readIfPresent("nOuterCorr", nOuterCorr_); + solution.readEntry("nCorr", nCorr_); + solution.readEntry("nNonOrthCorr", nNonOrthCorr_); + } + return true; +} + + +scalar liquidFilmBase::CourantNumber() const +{ + scalar CoNum = 0.0; + scalar meanCoNum = 0.0; + scalar velMag = 0.0; + + if (regionMesh().nInternalEdges()) + { + edgeScalarField SfUfbyDelta + ( + regionMesh().edgeInterpolation::deltaCoeffs()*mag(phif_) + ); + + CoNum = max(SfUfbyDelta/regionMesh().magLe()) + .value()*time().deltaT().value(); + + meanCoNum = (sum(SfUfbyDelta)/sum(regionMesh().magLe())) + .value()*time().deltaT().value(); + + velMag = max(mag(phif_)/regionMesh().magLe()).value(); + } + + Info<< "Film Courant Number mean: " << meanCoNum + << " max: " << CoNum + << " Film velocity magnitude: " << velMag << endl; + + return CoNum; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + + +liquidFilmBase::liquidFilmBase +( + const word& modelType, + const fvPatch& p, + const dictionary& dict +) +: + regionFaModel(p, liquidFilmName, modelType, dict, true), + + momentumPredictor_ + ( + this->solution().subDict("PISO").lookup("momentumPredictor") + ), + nOuterCorr_ + ( + this->solution().subDict("PISO").lookupOrDefault("nOuterCorr", 1) + ), + nCorr_(this->solution().subDict("PISO").get