diff --git a/src/regionModels/regionModel/regionModel1D/regionModel1D.C b/src/regionModels/regionModel/regionModel1D/regionModel1D.C index 8997340266d4f3c425bfb9df4832fcde0ad95f74..19bf9f2ece549024f3c24a1e2d44a3e9cc42a68d 100644 --- a/src/regionModels/regionModel/regionModel1D/regionModel1D.C +++ b/src/regionModels/regionModel/regionModel1D/regionModel1D.C @@ -114,8 +114,6 @@ void Foam::regionModels::regionModel1D::initialise() boundaryFaceCells_[localPyrolysisFaceI].transfer(cellIDs); localPyrolysisFaceI++; - - nLayers_ = nCells; } } @@ -268,7 +266,6 @@ Foam::regionModels::regionModel1D::regionModel1D(const fvMesh& mesh) boundaryFaceFaces_(), boundaryFaceCells_(), boundaryFaceOppositeFace_(), - nLayers_(0), nMagSfPtr_(NULL), moveMesh_(false) {} @@ -286,7 +283,6 @@ Foam::regionModels::regionModel1D::regionModel1D boundaryFaceFaces_(regionMesh().nCells()), boundaryFaceCells_(regionMesh().nCells()), boundaryFaceOppositeFace_(regionMesh().nCells()), - nLayers_(0), nMagSfPtr_(NULL), moveMesh_(true) { diff --git a/src/regionModels/regionModel/regionModel1D/regionModel1D.H b/src/regionModels/regionModel/regionModel1D/regionModel1D.H index 35a6b75dfc8b70673e93b82c178fdb7d8dd8abd3..650dea510f008098bfe8d90e7f28fc1a0ebd306e 100644 --- a/src/regionModels/regionModel/regionModel1D/regionModel1D.H +++ b/src/regionModels/regionModel/regionModel1D/regionModel1D.H @@ -88,9 +88,6 @@ protected: //- Global boundary face IDs oppossite coupled patch labelList boundaryFaceOppositeFace_; - //- Number of layers in the region - label nLayers_; - // Geometry @@ -155,9 +152,6 @@ public: //- Return the global boundary face IDs oppossite coupled patch inline const labelList& boundaryFaceOppositeFace() const; - //- Return the number of layers in the region - inline label nLayers() const; - // Geometry diff --git a/src/regionModels/regionModel/regionModel1D/regionModel1DI.H b/src/regionModels/regionModel/regionModel1D/regionModel1DI.H index 7ab5cf08a5fcf6b64d3c0abbf9380267f6a05086..55e61d3eef0d7051c57d91c1f1531044a69d005e 100644 --- a/src/regionModels/regionModel/regionModel1D/regionModel1DI.H +++ b/src/regionModels/regionModel/regionModel1D/regionModel1DI.H @@ -49,12 +49,6 @@ Foam::regionModels::regionModel1D::boundaryFaceOppositeFace() const } -inline Foam::label Foam::regionModels::regionModel1D::nLayers() const -{ - return nLayers_; -} - - inline const Foam::surfaceScalarField& Foam::regionModels::regionModel1D::nMagSf() const { diff --git a/src/regionModels/regionModel/singleLayerRegion/singleLayerRegion.C b/src/regionModels/regionModel/singleLayerRegion/singleLayerRegion.C index adb3bf8a88dc7f4d0a60f33841c1fce424b0d981..91dbaba9ebd4e4037cad2731763c901ca77d3661 100644 --- a/src/regionModels/regionModel/singleLayerRegion/singleLayerRegion.C +++ b/src/regionModels/regionModel/singleLayerRegion/singleLayerRegion.C @@ -111,14 +111,12 @@ void Foam::regionModels::singleLayerRegion::initialise() if (nBoundaryFaces != regionMesh().nCells()) { - /* FatalErrorIn("singleLayerRegion::initialise()") << "Number of primary region coupled boundary faces not equal to " << "the number of cells in the local region" << nl << nl << "Number of cells = " << regionMesh().nCells() << nl << "Boundary faces = " << nBoundaryFaces << nl << abort(FatalError); - */ } scalarField passiveMagSf(magSf.size(), 0.0); @@ -178,12 +176,11 @@ Foam::regionModels::singleLayerRegion::singleLayerRegion bool readFields ) : - regionModel(mesh, regionType, modelName, readFields), + regionModel(mesh, regionType, modelName, false), nHatPtr_(NULL), magSfPtr_(NULL), passivePatchIDs_() { - Info << "singleLayerRegion" << endl; if (active_) { constructMeshObjects(); diff --git a/src/regionModels/surfaceFilmModels/Make/files b/src/regionModels/surfaceFilmModels/Make/files index e13af06b6eb0707c332a40a1ed6193b09101bb9a..a0e33184d6825d646d82263fa32d478500d183c9 100644 --- a/src/regionModels/surfaceFilmModels/Make/files +++ b/src/regionModels/surfaceFilmModels/Make/files @@ -12,9 +12,10 @@ submodels/subModelBase.C KINEMATICMODELS=submodels/kinematic $(KINEMATICMODELS)/injectionModel/injectionModel/injectionModel.C $(KINEMATICMODELS)/injectionModel/injectionModel/injectionModelNew.C -$(KINEMATICMODELS)/injectionModel/noInjection/noInjection.C -$(KINEMATICMODELS)/injectionModel/cloudInjection/cloudInjection.C +$(KINEMATICMODELS)/injectionModel/injectionModelList/injectionModelList.C +$(KINEMATICMODELS)/injectionModel/drippingInjection/drippingInjection.C $(KINEMATICMODELS)/injectionModel/removeInjection/removeInjection.C +$(KINEMATICMODELS)/injectionModel/curvatureSeparation/curvatureSeparation.C THERMOMODELS=submodels/thermo $(THERMOMODELS)/phaseChangeModel/phaseChangeModel/phaseChangeModel.C diff --git a/src/regionModels/surfaceFilmModels/derivedFvPatchFields/filmHeightInletVelocity/filmHeightInletVelocityFvPatchVectorField.C b/src/regionModels/surfaceFilmModels/derivedFvPatchFields/filmHeightInletVelocity/filmHeightInletVelocityFvPatchVectorField.C index 3ac7e917923c5bf47cec0a2e02ea0428f9752418..df4922f7acde4704ca21d22cc10c4829074e775e 100644 --- a/src/regionModels/surfaceFilmModels/derivedFvPatchFields/filmHeightInletVelocity/filmHeightInletVelocityFvPatchVectorField.C +++ b/src/regionModels/surfaceFilmModels/derivedFvPatchFields/filmHeightInletVelocity/filmHeightInletVelocityFvPatchVectorField.C @@ -123,10 +123,10 @@ void Foam::filmHeightInletVelocityFvPatchVectorField::updateCoeffs() const fvPatchField<scalar>& deltafp = patch().lookupPatchField<volScalarField, scalar>(deltafName_); - const vectorField& n = patch().nf(); + vectorField n(patch().nf()); const scalarField& magSf = patch().magSf(); - operator==(deltafp*n*phip/(rhop*magSf*sqr(deltafp) + ROOTVSMALL)); + operator==(n*phip/(rhop*magSf*deltafp + ROOTVSMALL)); fixedValueFvPatchVectorField::updateCoeffs(); } diff --git a/src/regionModels/surfaceFilmModels/derivedFvPatchFields/wallFunctions/alphatFilmWallFunction/alphatFilmWallFunctionFvPatchScalarField.C b/src/regionModels/surfaceFilmModels/derivedFvPatchFields/wallFunctions/alphatFilmWallFunction/alphatFilmWallFunctionFvPatchScalarField.C index 68fd285da8b7de28ef42f7a61feb1400420ef6ce..2dbbe9b4fb8d2115a76556ce953a3832431ee75c 100644 --- a/src/regionModels/surfaceFilmModels/derivedFvPatchFields/wallFunctions/alphatFilmWallFunction/alphatFilmWallFunctionFvPatchScalarField.C +++ b/src/regionModels/surfaceFilmModels/derivedFvPatchFields/wallFunctions/alphatFilmWallFunction/alphatFilmWallFunctionFvPatchScalarField.C @@ -156,9 +156,9 @@ void alphatFilmWallFunctionFvPatchScalarField::updateCoeffs() const mapDistribute& distMap = filmModel.mappedPatches()[filmPatchI].map(); - scalarField mDotFilm = - filmModel.massPhaseChangeForPrimary().boundaryField()[filmPatchI]; - distMap.distribute(mDotFilm); + tmp<volScalarField> mDotFilm(filmModel.primaryMassTrans()); + scalarField mDotFilmp = mDotFilm().boundaryField()[filmPatchI]; + distMap.distribute(mDotFilmp); // Retrieve RAS turbulence model const RASModel& rasModel = db().lookupObject<RASModel>("RASProperties"); @@ -185,7 +185,7 @@ void alphatFilmWallFunctionFvPatchScalarField::updateCoeffs() scalar Pr = muw[faceI]/alphaw[faceI]; scalar factor = 0.0; - scalar mStar = mDotFilm[faceI]/(y[faceI]*uTau); + scalar mStar = mDotFilmp[faceI]/(y[faceI]*uTau); if (yPlus > yPlusCrit_) { scalar expTerm = exp(min(50.0, yPlusCrit_*mStar*Pr)); @@ -209,6 +209,7 @@ void alphatFilmWallFunctionFvPatchScalarField::updateCoeffs() } + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void alphatFilmWallFunctionFvPatchScalarField::write(Ostream& os) const diff --git a/src/regionModels/surfaceFilmModels/derivedFvPatchFields/wallFunctions/mutkFilmWallFunction/mutkFilmWallFunctionFvPatchScalarField.C b/src/regionModels/surfaceFilmModels/derivedFvPatchFields/wallFunctions/mutkFilmWallFunction/mutkFilmWallFunctionFvPatchScalarField.C index 61bd0ddfb73cc763e890bb42e1f1dd08f7253f01..12c4426e9406c2b3efde908b95a530477442c876 100644 --- a/src/regionModels/surfaceFilmModels/derivedFvPatchFields/wallFunctions/mutkFilmWallFunction/mutkFilmWallFunctionFvPatchScalarField.C +++ b/src/regionModels/surfaceFilmModels/derivedFvPatchFields/wallFunctions/mutkFilmWallFunction/mutkFilmWallFunctionFvPatchScalarField.C @@ -72,9 +72,9 @@ tmp<scalarField> mutkFilmWallFunctionFvPatchScalarField::calcUTau const mapDistribute& distMap = filmModel.mappedPatches()[filmPatchI].map(); - scalarField mDotFilm = - filmModel.massPhaseChangeForPrimary().boundaryField()[filmPatchI]; - distMap.distribute(mDotFilm); + tmp<volScalarField> mDotFilm(filmModel.primaryMassTrans()); + scalarField mDotFilmp = mDotFilm().boundaryField()[filmPatchI]; + distMap.distribute(mDotFilmp); // Retrieve RAS turbulence model @@ -95,7 +95,7 @@ tmp<scalarField> mutkFilmWallFunctionFvPatchScalarField::calcUTau scalar yPlus = y[faceI]*ut/(muw[faceI]/rhow[faceI]); - scalar mStar = mDotFilm[faceI]/(y[faceI]*ut); + scalar mStar = mDotFilmp[faceI]/(y[faceI]*ut); scalar factor = 0.0; if (yPlus > yPlusCrit_) diff --git a/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayer.C b/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayer.C index c072c457896b0a2246b8e2af5edbff716cd8f13f..ccf431720a7ac5bbb4058fbfb8e0a7bd253e28dd 100644 --- a/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayer.C +++ b/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayer.C @@ -35,9 +35,6 @@ License #include "directMappedWallPolyPatch.H" #include "mapDistribute.H" -// Sub-models -#include "injectionModel.H" - // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam @@ -66,7 +63,6 @@ bool kinematicSingleLayer::read() solution.lookup("nNonOrthCorr") >> nNonOrthCorr_; coeffs_.lookup("Cf") >> Cf_; - coeffs_.lookup("deltaStable") >> deltaStable_; return true; } @@ -99,6 +95,11 @@ void kinematicSingleLayer::correctThermoFields() void kinematicSingleLayer::resetPrimaryRegionSourceTerms() { + if (debug) + { + Info<< "kinematicSingleLayer::resetPrimaryRegionSourceTerms()" << endl; + } + rhoSpPrimary_ == dimensionedScalar("zero", rhoSp_.dimensions(), 0.0); USpPrimary_ == dimensionedVector("zero", USp_.dimensions(), vector::zero); pSpPrimary_ == dimensionedScalar("zero", pSp_.dimensions(), 0.0); @@ -107,6 +108,11 @@ void kinematicSingleLayer::resetPrimaryRegionSourceTerms() void kinematicSingleLayer::transferPrimaryRegionThermoFields() { + if (debug) + { + Info<< "kinematicSingleLayer::" + << "transferPrimaryRegionThermoFields()" << endl; + } // Update fields from primary region via direct mapped // (coupled) boundary conditions UPrimary_.correctBoundaryConditions(); @@ -118,6 +124,12 @@ void kinematicSingleLayer::transferPrimaryRegionThermoFields() void kinematicSingleLayer::transferPrimaryRegionSourceFields() { + if (debug) + { + Info<< "kinematicSingleLayer::" + << "transferPrimaryRegionSourceFields()" << endl; + } + // Retrieve the source fields from the primary region via direct mapped // (coupled) boundary conditions // - fields require transfer of values for both patch AND to push the @@ -132,10 +144,6 @@ void kinematicSingleLayer::transferPrimaryRegionSourceFields() rhoSp_.field() /= magSf()*deltaT; USp_.field() /= magSf()*deltaT; pSp_.field() /= magSf()*deltaT; - - // reset transfer to primary fields - massForPrimary_ == dimensionedScalar("zero", dimMass, 0.0); - diametersForPrimary_ == dimensionedScalar("zero", dimLength, -1.0); } @@ -154,7 +162,7 @@ tmp<volScalarField> kinematicSingleLayer::pu() IOobject::NO_WRITE ), pPrimary_ // pressure (mapped from primary region) - + pSp_ // accumulated particle impingement + - pSp_ // accumulated particle impingement - fvc::laplacian(sigma_, delta_) // surface tension ) ); @@ -181,51 +189,25 @@ tmp<volScalarField> kinematicSingleLayer::pp() } -void kinematicSingleLayer::correctDetachedFilm() +void kinematicSingleLayer::updateSubmodels() { - tmp<volScalarField> tgNorm(this->gNorm()); - const scalarField& gNorm = tgNorm(); - const scalarField& magSf = this->magSf(); - - forAll(gNorm, i) + if (debug) { - if (gNorm[i] > SMALL) - { - const scalar ddelta = max(0.0, delta_[i] - deltaStable_.value()); - massForPrimary_[i] = - max - ( - 0.0, - ddelta*rho_[i]*magSf[i] - massPhaseChangeForPrimary_[i] - ); - } + Info<< "kinematicSingleLayer::updateSubmodels()" << endl; } -} - -void kinematicSingleLayer::updateSubmodels() -{ - correctDetachedFilm(); - - // Update injection model - mass returned is actual mass injected - injection_->correct(massForPrimary_, diametersForPrimary_); - - // Update cumulative detached mass counter - injectedMassTotal_ += sum(massForPrimary_.field()); - - // Push values to boundaries ready for transfer to the primary region - massForPrimary_.correctBoundaryConditions(); - diametersForPrimary_.correctBoundaryConditions(); + // Update injection model - mass returned is mass available for injection + injection_.correct(availableMass_, cloudMassTrans_, cloudDiameterTrans_); // Update source fields const dimensionedScalar deltaT = time().deltaT(); - rhoSp_ -= (massForPrimary_ + massPhaseChangeForPrimary_)/magSf()/deltaT; + rhoSp_ += cloudMassTrans_/magSf()/deltaT; } void kinematicSingleLayer::continuityCheck() { - const volScalarField deltaRho0 = deltaRho_; + const volScalarField deltaRho0(deltaRho_); solveContinuity(); @@ -241,7 +223,7 @@ void kinematicSingleLayer::continuityCheck() fvc::domainIntegrate(mag(mass - magSf()*deltaRho0))/totalMass ).value(); - const scalar globalContErr = + const scalar globalContErr = ( fvc::domainIntegrate(mass - magSf()*deltaRho0)/totalMass ).value(); @@ -268,7 +250,7 @@ void kinematicSingleLayer::solveContinuity() fvm::ddt(deltaRho_) + fvc::div(phi_) == - rhoSp_ + - rhoSp_ ); } @@ -305,8 +287,8 @@ tmp<fvVectorMatrix> kinematicSingleLayer::tau(volVectorField& U) const return ( - - fvm::Sp(Cs, U) + Cs*Us_ - - fvm::Sp(Cw, U) + Cw*Uw_ + - fvm::Sp(Cs, U) + Cs*Us_ // surface contribution + - fvm::Sp(Cw, U) + Cw*Uw_ // wall contribution ); } @@ -330,15 +312,10 @@ tmp<Foam::fvVectorMatrix> kinematicSingleLayer::solveMomentum fvm::ddt(deltaRho_, U_) + fvm::div(phi_, U_) == - USp_ + - USp_ + tau(U_) + fvc::grad(sigma_) - - fvm::Sp - ( - (massForPrimary_ + massPhaseChangeForPrimary_) - /magSf()/time().deltaT(), - U_ - ) + - fvm::SuSp(rhoSp_, U_) ); fvVectorMatrix& UEqn = tUEqn(); @@ -415,6 +392,7 @@ void kinematicSingleLayer::solveThickness surfaceScalarField ddrhorUAppf ( + "deltaCoeff", fvc::interpolate(delta_)*deltarUAf*rhof*fvc::interpolate(pp) ); // constrainFilmField(ddrhorUAppf, 0.0); @@ -428,7 +406,7 @@ void kinematicSingleLayer::solveThickness + fvm::div(phid, delta_) - fvm::laplacian(ddrhorUAppf, delta_) == - rhoSp_ + - rhoSp_ ); deltaEqn.solve(); @@ -475,15 +453,11 @@ kinematicSingleLayer::kinematicSingleLayer momentumPredictor_(solution().subDict("PISO").lookup("momentumPredictor")), nOuterCorr_(readLabel(solution().subDict("PISO").lookup("nOuterCorr"))), nCorr_(readLabel(solution().subDict("PISO").lookup("nCorr"))), - nNonOrthCorr_ - ( - readLabel(solution().subDict("PISO").lookup("nNonOrthCorr")) - ), + nNonOrthCorr_(readLabel(solution().subDict("PISO").lookup("nNonOrthCorr"))), cumulativeContErr_(0.0), Cf_(readScalar(coeffs().lookup("Cf"))), - deltaStable_(coeffs().lookup("deltaStable")), rho_ ( @@ -607,11 +581,11 @@ kinematicSingleLayer::kinematicSingleLayer dimLength*dimMass/dimTime ), - massForPrimary_ + primaryMassTrans_ ( IOobject ( - "massForPrimary", + "primaryMassTrans", time().timeName(), regionMesh(), IOobject::NO_READ, @@ -621,32 +595,32 @@ kinematicSingleLayer::kinematicSingleLayer dimensionedScalar("zero", dimMass, 0.0), zeroGradientFvPatchScalarField::typeName ), - diametersForPrimary_ + cloudMassTrans_ ( IOobject ( - "diametersForPrimary", + "cloudMassTrans", time().timeName(), regionMesh(), IOobject::NO_READ, IOobject::NO_WRITE ), regionMesh(), - dimensionedScalar("zero", dimLength, -1.0), + dimensionedScalar("zero", dimMass, 0.0), zeroGradientFvPatchScalarField::typeName ), - massPhaseChangeForPrimary_ + cloudDiameterTrans_ ( IOobject ( - "massPhaseChangeForPrimary", + "cloudDiameterTrans", time().timeName(), regionMesh(), IOobject::NO_READ, IOobject::NO_WRITE ), regionMesh(), - dimensionedScalar("zero", dimMass, 0), + dimensionedScalar("zero", dimLength, -1.0), zeroGradientFvPatchScalarField::typeName ), @@ -793,10 +767,11 @@ kinematicSingleLayer::kinematicSingleLayer this->mappedFieldAndInternalPatchTypes<scalar>() ), - injection_(injectionModel::New(*this, coeffs_)), + availableMass_(regionMesh().nCells(), 0.0), + + injection_(*this, coeffs_), - addedMassTotal_(0.0), - injectedMassTotal_(0.0) + addedMassTotal_(0.0) { if (readFields) { @@ -836,9 +811,9 @@ void kinematicSingleLayer::addSources << " pressure = " << pressureSource << endl; } - rhoSpPrimary_.boundaryField()[patchI][faceI] += massSource; - USpPrimary_.boundaryField()[patchI][faceI] += momentumSource; - pSpPrimary_.boundaryField()[patchI][faceI] += pressureSource; + rhoSpPrimary_.boundaryField()[patchI][faceI] -= massSource; + USpPrimary_.boundaryField()[patchI][faceI] -= momentumSource; + pSpPrimary_.boundaryField()[patchI][faceI] -= pressureSource; addedMassTotal_ += massSource; } @@ -846,22 +821,38 @@ void kinematicSingleLayer::addSources void kinematicSingleLayer::preEvolveRegion() { + if (debug) + { + Info<< "kinematicSingleLayer::preEvolveRegion()" << endl; + } + transferPrimaryRegionThermoFields(); correctThermoFields(); transferPrimaryRegionSourceFields(); + + // Reset transfer fields +// availableMass_ = mass(); + availableMass_ = netMass(); + cloudMassTrans_ == dimensionedScalar("zero", dimMass, 0.0); + cloudDiameterTrans_ == dimensionedScalar("zero", dimLength, -1.0); } void kinematicSingleLayer::evolveRegion() { + if (debug) + { + Info<< "kinematicSingleLayer::evolveRegion()" << endl; + } + updateSubmodels(); // Solve continuity for deltaRho_ solveContinuity(); - // Implicit pressure source coefficient + // Implicit pressure source coefficient - constant tmp<volScalarField> tpp(this->pp()); for (int oCorr=0; oCorr<nOuterCorr_; oCorr++) @@ -941,6 +932,12 @@ const volVectorField& kinematicSingleLayer::Uw() const } +const surfaceScalarField& kinematicSingleLayer::phi() const +{ + return phi_; +} + + const volScalarField& kinematicSingleLayer::rho() const { return rho_; @@ -1002,21 +999,37 @@ const volScalarField& kinematicSingleLayer::kappa() const } -const volScalarField& kinematicSingleLayer::massForPrimary() const +tmp<volScalarField> kinematicSingleLayer::primaryMassTrans() const { - return massForPrimary_; + return tmp<volScalarField> + ( + new volScalarField + ( + IOobject + ( + "kinematicSingleLayer::primaryMassTrans", + time().timeName(), + primaryMesh(), + IOobject::NO_READ, + IOobject::NO_WRITE, + false + ), + primaryMesh(), + dimensionedScalar("zero", dimMass/dimVolume/dimTime, 0.0) + ) + ); } -const volScalarField& kinematicSingleLayer::diametersForPrimary() const +const volScalarField& kinematicSingleLayer::cloudMassTrans() const { - return diametersForPrimary_; + return cloudMassTrans_; } -const volScalarField& kinematicSingleLayer::massPhaseChangeForPrimary() const +const volScalarField& kinematicSingleLayer::cloudDiameterTrans() const { - return massPhaseChangeForPrimary_; + return cloudDiameterTrans_; } @@ -1028,18 +1041,18 @@ void kinematicSingleLayer::info() const << returnReduce<scalar>(addedMassTotal_, sumOp<scalar>()) << nl << indent << "current mass = " << gSum((deltaRho_*magSf())()) << nl - << indent << "injected mass = " - << returnReduce<scalar>(injectedMassTotal_, sumOp<scalar>()) << nl << indent << "min/max(mag(U)) = " << min(mag(U_)).value() << ", " << max(mag(U_)).value() << nl << indent << "min/max(delta) = " << min(delta_).value() << ", " << max(delta_).value() << nl; + + injection_.info(Info); } -tmp<DimensionedField<scalar, volMesh> > kinematicSingleLayer::Srho() const +tmp<DimensionedField<scalar, volMesh> > kinematicSingleLayer::Srho() const { - tmp<DimensionedField<scalar, volMesh> > tSrho + return tmp<DimensionedField<scalar, volMesh> > ( new DimensionedField<scalar, volMesh> ( @@ -1056,37 +1069,12 @@ tmp<DimensionedField<scalar, volMesh> > kinematicSingleLayer::Srho() const dimensionedScalar("zero", dimMass/dimVolume/dimTime, 0.0) ) ); - - scalarField& Srho = tSrho(); - const scalarField& V = primaryMesh().V(); - const scalar dt = time_.deltaTValue(); - - forAll(intCoupledPatchIDs(), i) - { - const label filmPatchI = intCoupledPatchIDs()[i]; - const mapDistribute& distMap = mappedPatches_[filmPatchI].map(); - - scalarField patchMass = - massPhaseChangeForPrimary_.boundaryField()[filmPatchI]; - distMap.distribute(patchMass); - - const label primaryPatchI = primaryPatchIDs()[i]; - const unallocLabelList& cells = - primaryMesh().boundaryMesh()[primaryPatchI].faceCells(); - - forAll(patchMass, j) - { - Srho[cells[j]] = patchMass[j]/(V[cells[j]]*dt); - } - } - - return tSrho; } tmp<DimensionedField<scalar, volMesh> > kinematicSingleLayer::Srho ( - const label + const label i ) const { return tmp<DimensionedField<scalar, volMesh> > @@ -1095,7 +1083,7 @@ tmp<DimensionedField<scalar, volMesh> > kinematicSingleLayer::Srho ( IOobject ( - "kinematicSingleLayer::Srho(i)", + "kinematicSingleLayer::Srho(" + Foam::name(i) + ")", time().timeName(), primaryMesh(), IOobject::NO_READ, diff --git a/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayer.H b/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayer.H index 60d458727019eafc59ebd346b85a08644aa6c55e..361593ed0da9002d6c3d76140554c597464b29b0 100644 --- a/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayer.H +++ b/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayer.H @@ -42,6 +42,8 @@ SourceFiles #include "surfaceFields.H" #include "fvMatrices.H" +#include "injectionModelList.H" + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam @@ -51,9 +53,6 @@ namespace regionModels namespace surfaceFilmModels { -// Forward declaration of classes -class injectionModel; - /*---------------------------------------------------------------------------*\ Class kinematicSingleLayer Declaration \*---------------------------------------------------------------------------*/ @@ -100,9 +99,6 @@ protected: //- Skin frition coefficient for film/primary region interface scalar Cf_; - //- Stable film thickness - dimensionedScalar deltaStable_; - // Thermo properties @@ -139,16 +135,16 @@ protected: surfaceScalarField phi_; - // Transfer fields - to the primary region + // Transfer fields - //- Film mass available for transfer - volScalarField massForPrimary_; + //- Film mass available for transfer to the primary region + volScalarField primaryMassTrans_; - //- Parcel diameters originating from film - volScalarField diametersForPrimary_; + //- Film mass available for transfer to cloud + volScalarField cloudMassTrans_; - //- Film mass evolved via phase change - volScalarField massPhaseChangeForPrimary_; + //- Parcel diameters originating from film to cloud + volScalarField cloudDiameterTrans_; // Source term fields @@ -198,8 +194,11 @@ protected: // Sub-models - //- Injection - autoPtr<injectionModel> injection_; + //- Available mass for transfer via sub-models + scalarField availableMass_; + + //- Cloud injection + injectionModelList injection_; // Checks @@ -208,12 +207,6 @@ protected: scalar addedMassTotal_; - // Detached surface properties - - //- Cumulative mass detached [kg] - scalar injectedMassTotal_; - - // Protected member functions //- Read control parameters from dictionary @@ -231,9 +224,6 @@ protected: //- Transfer source fields from the primary region to the film region virtual void transferPrimaryRegionSourceFields(); - //- Correct the source terms for film that detaches from film region - virtual void correctDetachedFilm(); - // Explicit pressure source contribution virtual tmp<volScalarField> pu(); @@ -354,6 +344,9 @@ public: //- Return the film wall velocity [m/s] virtual const volVectorField& Uw() const; + //- Return the film flux [kg.m/s] + virtual const surfaceScalarField& phi() const; + //- Return the film density [kg/m3] virtual const volScalarField& rho() const; @@ -373,16 +366,16 @@ public: virtual const volScalarField& kappa() const; - // Transfer fields - to the primary region + // Transfer fields - to the primary region - //- Return the film mass available for transfer - virtual const volScalarField& massForPrimary() const; + //- Return mass transfer source - Eulerian phase only + virtual tmp<volScalarField> primaryMassTrans() const; - //- Return the parcel diameters originating from film - virtual const volScalarField& diametersForPrimary() const; + //- Return the film mass available for transfer to cloud + virtual const volScalarField& cloudMassTrans() const; - //- Return the film mass evolved via phase change - virtual const volScalarField& massPhaseChangeForPrimary() const; + //- Return the parcel diameters originating from film to cloud + virtual const volScalarField& cloudDiameterTrans() const; // External helper functions @@ -452,13 +445,16 @@ public: // Sub-models //- Injection - inline injectionModel& injection(); + inline injectionModelList& injection(); // Helper functions - //- Return the gravity tangential component contributions - inline tmp<volVectorField> gTan() const; + //- Return the current film mass + inline tmp<volScalarField> mass() const; + + //- Return the net film mass available over the next integration + inline tmp<volScalarField> netMass() const; //- Return the gravity normal-to-patch component contribution inline tmp<volScalarField> gNorm() const; @@ -467,6 +463,9 @@ public: // Clipped so that only non-zero if g & nHat_ < 0 inline tmp<volScalarField> gNormClipped() const; + //- Return the gravity tangential component contributions + inline tmp<volVectorField> gTan() const; + // Evolution @@ -494,7 +493,7 @@ public: virtual tmp<DimensionedField<scalar, volMesh> > Sh() const; - // I-O + // I-O //- Provide some feedback virtual void info() const; diff --git a/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayerI.H b/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayerI.H index 483742ca77d2ecdfafcf07b90be442a0e6f43d68..d3b6a54178900a176ec6e8ecc3a2ac1b566f0db9 100644 --- a/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayerI.H +++ b/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayerI.H @@ -24,7 +24,8 @@ License \*---------------------------------------------------------------------------*/ -#include "kinematicSingleLayer.H" +#include "surfaceInterpolate.H" +#include "fvcSurfaceIntegrate.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -163,9 +164,24 @@ inline const volScalarField& kinematicSingleLayer::muPrimary() const } -inline injectionModel& kinematicSingleLayer::injection() +inline injectionModelList& kinematicSingleLayer::injection() { - return injection_(); + return injection_; +} + + +inline tmp<volScalarField> kinematicSingleLayer::mass() const +{ + return rho_*delta_*magSf(); +} + + +inline tmp<volScalarField> kinematicSingleLayer::netMass() const +{ + dimensionedScalar d0("SMALL", dimLength, ROOTVSMALL); + return + fvc::surfaceSum(phi_/(fvc::interpolate(delta_) + d0))*time().deltaT() + + rho_*delta_*magSf(); } diff --git a/src/regionModels/surfaceFilmModels/noFilm/noFilm.C b/src/regionModels/surfaceFilmModels/noFilm/noFilm.C index d79814354c9d90a110dabe6c7e9a3ec587db13d4..e1bde38bf14b73f2e1ddf8939146c03ecdf5c5c6 100644 --- a/src/regionModels/surfaceFilmModels/noFilm/noFilm.C +++ b/src/regionModels/surfaceFilmModels/noFilm/noFilm.C @@ -103,6 +103,15 @@ const volScalarField& noFilm::delta() const } +const volScalarField& noFilm::sigma() const +{ + FatalErrorIn("const volScalarField& noFilm::sigma() const") + << "sigma field not available for " << type() << abort(FatalError); + + return volScalarField::null(); +} + + const volVectorField& noFilm::U() const { FatalErrorIn("const volVectorField& noFilm::U() const") @@ -184,32 +193,42 @@ const volScalarField& noFilm::kappa() const } -const volScalarField& noFilm::massForPrimary() const +tmp<volScalarField> noFilm::primaryMassTrans() const { - FatalErrorIn("const volScalarField& noFilm::massForPrimary() const") - << "massForPrimary field not available for " << type() - << abort(FatalError); - - return volScalarField::null(); + return tmp<volScalarField> + ( + new volScalarField + ( + IOobject + ( + "noFilm::primaryMassTrans", + time().timeName(), + primaryMesh(), + IOobject::NO_READ, + IOobject::NO_WRITE, + false + ), + primaryMesh(), + dimensionedScalar("zero", dimMass/dimVolume/dimTime, 0.0) + ) + ); } -const volScalarField& noFilm::diametersForPrimary() const +const volScalarField& noFilm::cloudMassTrans() const { - FatalErrorIn("const volScalarField& noFilm::diametersForPrimary() const") - << "diametersForPrimary field not available for " << type() + FatalErrorIn("const volScalarField& noFilm::cloudMassTrans() const") + << "cloudMassTrans field not available for " << type() << abort(FatalError); return volScalarField::null(); } -const volScalarField& noFilm::massPhaseChangeForPrimary() const +const volScalarField& noFilm::cloudDiameterTrans() const { - FatalErrorIn - ( - "const volScalarField& noFilm::massPhaseChangeForPrimary() const" - ) << "massPhaseChange field not available for " << type() + FatalErrorIn("const volScalarField& noFilm::cloudDiameterTrans() const") + << "cloudDiameterTrans field not available for " << type() << abort(FatalError); return volScalarField::null(); @@ -238,7 +257,7 @@ tmp<DimensionedField<scalar, volMesh> > noFilm::Srho() const } -tmp<DimensionedField<scalar, volMesh> > noFilm::Srho(const label) const +tmp<DimensionedField<scalar, volMesh> > noFilm::Srho(const label i) const { return tmp<DimensionedField<scalar, volMesh> > ( @@ -246,7 +265,7 @@ tmp<DimensionedField<scalar, volMesh> > noFilm::Srho(const label) const ( IOobject ( - "noFilm::Srho(i)", + "noFilm::Srho(" + Foam::name(i) + ")", time().timeName(), primaryMesh(), IOobject::NO_READ, diff --git a/src/regionModels/surfaceFilmModels/noFilm/noFilm.H b/src/regionModels/surfaceFilmModels/noFilm/noFilm.H index 0d6d398509d831c53070a8a9a2ec7011fbf42528..0c3627beb48a73f0e5c946331c44d7819e580f9b 100644 --- a/src/regionModels/surfaceFilmModels/noFilm/noFilm.H +++ b/src/regionModels/surfaceFilmModels/noFilm/noFilm.H @@ -111,49 +111,52 @@ public: ); - // Fields + // Fields - //- Return the film thickness [m] - virtual const volScalarField& delta() const; + //- Return the film thickness [m] + virtual const volScalarField& delta() const; - //- Return the film velocity [m/s] - virtual const volVectorField& U() const; + //- Return const access to the surface tension / [m/s2] + inline const volScalarField& sigma() const; - //- Return the film density [kg/m3] - virtual const volScalarField& rho() const; + //- Return the film velocity [m/s] + virtual const volVectorField& U() const; - //- Return the film surface velocity [m/s] - virtual const volVectorField& Us() const; + //- Return the film density [kg/m3] + virtual const volScalarField& rho() const; - //- Return the film wall velocity [m/s] - virtual const volVectorField& Uw() const; + //- Return the film surface velocity [m/s] + virtual const volVectorField& Us() const; - //- Return the film mean temperature [K] - virtual const volScalarField& T() const; + //- Return the film wall velocity [m/s] + virtual const volVectorField& Uw() const; - //- Return the film surface temperature [K] - virtual const volScalarField& Ts() const; + //- Return the film mean temperature [K] + virtual const volScalarField& T() const; - //- Return the film wall temperature [K] - virtual const volScalarField& Tw() const; + //- Return the film surface temperature [K] + virtual const volScalarField& Ts() const; - //- Return the film specific heat capacity [J/kg/K] - virtual const volScalarField& Cp() const; + //- Return the film wall temperature [K] + virtual const volScalarField& Tw() const; - //- Return the film thermal conductivity [W/m/K] - virtual const volScalarField& kappa() const; + //- Return the film specific heat capacity [J/kg/K] + virtual const volScalarField& Cp() const; + //- Return the film thermal conductivity [W/m/K] + virtual const volScalarField& kappa() const; - // Transfer fields - to the primary region - //- Return the film mass available for transfer - virtual const volScalarField& massForPrimary() const; + // Transfer fields - to the primary region - //- Return the parcel diameters originating from film - virtual const volScalarField& diametersForPrimary() const; + //- Return mass transfer source - Eulerian phase only + virtual tmp<volScalarField> primaryMassTrans() const; - //- Return the film mass evolved via phase change - virtual const volScalarField& massPhaseChangeForPrimary() const; + //- Return the film mass available for transfer + virtual const volScalarField& cloudMassTrans() const; + + //- Return the parcel diameters originating from film + virtual const volScalarField& cloudDiameterTrans() const; // Source fields diff --git a/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/curvatureSeparation/curvatureSeparation.C b/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/curvatureSeparation/curvatureSeparation.C new file mode 100644 index 0000000000000000000000000000000000000000..812f09bc330112d15e3bb62e5b2478e8aeba39b9 --- /dev/null +++ b/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/curvatureSeparation/curvatureSeparation.C @@ -0,0 +1,352 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2011 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "curvatureSeparation.H" +#include "addToRunTimeSelectionTable.H" +#include "fvMesh.H" +#include "Time.H" +#include "volFields.H" +#include "kinematicSingleLayer.H" +#include "surfaceInterpolate.H" +#include "fvcDiv.H" +#include "fvcGrad.H" +#include "stringListOps.H" +#include "cyclicPolyPatch.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace regionModels +{ +namespace surfaceFilmModels +{ + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +defineTypeNameAndDebug(curvatureSeparation, 0); +addToRunTimeSelectionTable +( + injectionModel, + curvatureSeparation, + dictionary +); + +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +tmp<volScalarField> curvatureSeparation::calcInvR1(const volVectorField& U) const +{ + // method 1 +/* + tmp<volScalarField> tinvR1 + ( + new volScalarField("invR1", fvc::div(owner().nHat())) + ); +*/ + + // method 2 + dimensionedScalar smallU("smallU", dimVelocity, ROOTVSMALL); + volVectorField UHat(U/(mag(U) + smallU)); + tmp<volScalarField> tinvR1 + ( + new volScalarField("invR1", UHat & (UHat & gradNHat_)) + ); + + + scalarField& invR1 = tinvR1().internalField(); + + // apply defined patch radii + const scalar rMin = 1e-6; + const fvMesh& mesh = owner().regionMesh(); + const polyBoundaryMesh& pbm = mesh.boundaryMesh(); + forAll(definedPatchRadii_, i) + { + label patchI = definedPatchRadii_[i].first(); + scalar definedInvR1 = 1.0/max(rMin, definedPatchRadii_[i].second()); + UIndirectList<scalar>(invR1, pbm[patchI].faceCells()) = definedInvR1; + } + + // filter out large radii + const scalar rMax = 1e6; + forAll(invR1, i) + { + if (mag(invR1[i]) < 1/rMax) + { + invR1[i] = -1.0; + } + } + + if (debug && mesh.time().outputTime()) + { + tinvR1().write(); + } + + return tinvR1; +} + + +tmp<scalarField> curvatureSeparation::calcCosAngle +( + const surfaceScalarField& phi +) const +{ + const fvMesh& mesh = owner().regionMesh(); + const vectorField nf(mesh.Sf()/mesh.magSf()); + const unallocLabelList& own = mesh.owner(); + const unallocLabelList& nbr = mesh.neighbour(); + + scalarField phiMax(mesh.nCells(), -GREAT); + scalarField cosAngle(mesh.nCells(), 0.0); + forAll(nbr, faceI) + { + label cellO = own[faceI]; + label cellN = nbr[faceI]; + + if (phi[faceI] > phiMax[cellO]) + { + phiMax[cellO] = phi[faceI]; + cosAngle[cellO] = -gHat_ & nf[faceI]; + } + if (-phi[faceI] > phiMax[cellN]) + { + phiMax[cellN] = -phi[faceI]; + cosAngle[cellN] = -gHat_ & -nf[faceI]; + } + } + + forAll(phi.boundaryField(), patchI) + { + const fvsPatchScalarField& phip = phi.boundaryField()[patchI]; + const fvPatch& pp = phip.patch(); + const labelList& faceCells = pp.faceCells(); + const vectorField nf(pp.nf()); + forAll(phip, i) + { + label cellI = faceCells[i]; + if (phip[i] > phiMax[cellI]) + { + phiMax[cellI] = phip[i]; + cosAngle[cellI] = -gHat_ & nf[i]; + } + } + } +/* + // correction for cyclics - use cyclic pairs' face normal instead of + // local face normal + const fvBoundaryMesh& pbm = mesh.boundary(); + forAll(phi.boundaryField(), patchI) + { + if (isA<cyclicPolyPatch>(pbm[patchI])) + { + const scalarField& phip = phi.boundaryField()[patchI]; + const vectorField nf(pbm[patchI].nf()); + const labelList& faceCells = pbm[patchI].faceCells(); + const label sizeBy2 = pbm[patchI].size()/2; + + for (label face0=0; face0<sizeBy2; face0++) + { + label face1 = face0 + sizeBy2; + label cell0 = faceCells[face0]; + label cell1 = faceCells[face1]; + + // flux leaving half 0, entering half 1 + if (phip[face0] > phiMax[cell0]) + { + phiMax[cell0] = phip[face0]; + cosAngle[cell0] = -gHat_ & -nf[face1]; + } + + // flux leaving half 1, entering half 0 + if (-phip[face1] > phiMax[cell1]) + { + phiMax[cell1] = -phip[face1]; + cosAngle[cell1] = -gHat_ & nf[face0]; + } + } + } + } +*/ + // checks + if (debug && mesh.time().outputTime()) + { + volScalarField volCosAngle + ( + IOobject + ( + "cosAngle", + mesh.time().timeName(), + mesh, + IOobject::NO_READ + ), + mesh, + dimensionedScalar("zero", dimless, 0.0), + zeroGradientFvPatchScalarField::typeName + ); + volCosAngle.internalField() = cosAngle; + volCosAngle.correctBoundaryConditions(); + volCosAngle.write(); + } + + return max(min(cosAngle, 1.0), -1.0); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +curvatureSeparation::curvatureSeparation +( + const surfaceFilmModel& owner, + const dictionary& dict +) +: + injectionModel(type(), owner, dict), + gradNHat_(fvc::grad(owner.nHat())), + deltaByR1Min_(coeffs().lookupOrDefault<scalar>("deltaByR1Min", 0.0)), + definedPatchRadii_(), + magG_(mag(owner.g().value())), + gHat_(owner.g().value()/magG_) +{ + List<Tuple2<word, scalar> > prIn(coeffs().lookup("definedPatchRadii")); + const wordList& allPatchNames = owner.regionMesh().boundaryMesh().names(); + + DynamicList<Tuple2<label, scalar> > prData(allPatchNames.size()); + + labelHashSet uniquePatchIDs; + + forAllReverse(prIn, i) + { + labelList patchIDs = findStrings(prIn[i].first(), allPatchNames); + forAll(patchIDs, j) + { + const label patchI = patchIDs[j]; + + if (!uniquePatchIDs.found(patchI)) + { + const scalar radius = prIn[i].second(); + prData.append(Tuple2<label, scalar>(patchI, radius)); + + uniquePatchIDs.insert(patchI); + } + } + } + + definedPatchRadii_.transfer(prData); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +curvatureSeparation::~curvatureSeparation() +{} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +void curvatureSeparation::correct +( + scalarField& availableMass, + scalarField& massToInject, + scalarField& diameterToInject +) +{ + const kinematicSingleLayer& film = + refCast<const kinematicSingleLayer>(this->owner()); + const fvMesh& mesh = film.regionMesh(); + + const volScalarField& delta = film.delta(); + const volVectorField& U = film.U(); + const surfaceScalarField& phi = film.phi(); + const volScalarField& rho = film.rho(); + const scalarField magSqrU(magSqr(film.U())); + const volScalarField& sigma = film.sigma(); + + const scalarField invR1(calcInvR1(U)); + const scalarField cosAngle(calcCosAngle(phi)); + + // calculate force balance + const scalar Fthreshold = 1e-10; + scalarField Fnet(mesh.nCells(), 0.0); + scalarField separated(mesh.nCells(), 0.0); + forAll(invR1, i) + { + if ((invR1[i] > 0) && (delta[i]*invR1[i] > deltaByR1Min_)) + { + scalar R1 = 1.0/(invR1[i] + ROOTVSMALL); + scalar R2 = R1 + delta[i]; + + // inertial force + scalar Fi = -delta[i]*rho[i]*magSqrU[i]*72.0/60.0*invR1[i]; + + // body force + scalar Fb = + - 0.5*rho[i]*magG_*invR1[i]*(sqr(R1) - sqr(R2))*cosAngle[i]; + + // surface force + scalar Fs = sigma[i]/R2; + + Fnet[i] = Fi + Fb + Fs; + + if (Fnet[i] + Fthreshold < 0) + { + separated[i] = 1.0; + } + } + } + + // inject all available mass + massToInject = separated*availableMass; + diameterToInject = separated*delta; + availableMass -= separated*availableMass; + + if (debug && mesh.time().outputTime()) + { + volScalarField volFnet + ( + IOobject + ( + "Fnet", + mesh.time().timeName(), + mesh, + IOobject::NO_READ + ), + mesh, + dimensionedScalar("zero", dimForce, 0.0), + zeroGradientFvPatchScalarField::typeName + ); + volFnet.internalField() = Fnet; + volFnet.correctBoundaryConditions(); + volFnet.write(); + } +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace surfaceFilmModels +} // End namespace regionModels +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/curvatureSeparation/curvatureSeparation.H b/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/curvatureSeparation/curvatureSeparation.H new file mode 100644 index 0000000000000000000000000000000000000000..02e7f7ccdd9b25bb2d3a1247681f653ca75842fe --- /dev/null +++ b/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/curvatureSeparation/curvatureSeparation.H @@ -0,0 +1,158 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2011 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::curvatureSeparation + +Description + Curvature film separation model + + Assesses film curvature via the mesh geometry and calculates a force + balance of the form: + + F_sum = F_inertial + F_body + F_surface + + If F_sum < 0, the film separates. Similarly, if F_sum > 0 the film will + remain attached. + + Based on description given by + Owen and D. J. Ryley. The flow of thin liquid films around corners. + International Journal of Multiphase Flow, 11(1):51-62, 1985. + + +SourceFiles + curvatureSeparation.C + +\*---------------------------------------------------------------------------*/ + +#ifndef curvatureSeparation_H +#define curvatureSeparation_H + +#include "injectionModel.H" +#include "surfaceFields.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace regionModels +{ +namespace surfaceFilmModels +{ + +/*---------------------------------------------------------------------------*\ + Class curvatureSeparation Declaration +\*---------------------------------------------------------------------------*/ + +class curvatureSeparation +: + public injectionModel +{ +private: + + // Private member functions + + //- Disallow default bitwise copy construct + curvatureSeparation(const curvatureSeparation&); + + //- Disallow default bitwise assignment + void operator=(const curvatureSeparation&); + + +protected: + + // Protected data + + //- Gradient of surface normals + volTensorField gradNHat_; + + //- Minimum gravity driven film thickness (non-dimensionalised delta/R1) + scalar deltaByR1Min_; + + //- List of radii for patches - if patch not defined, radius + // calculated based on mesh geometry + List<Tuple2<label, scalar> > definedPatchRadii_; + + //- Magnitude of gravity vector + scalar magG_; + + //- Direction of gravity vector + vector gHat_; + + + // Protected Member Functions + + //- Calculate local (inverse) radius of curvature + tmp<volScalarField> calcInvR1(const volVectorField& U) const; + + //- Calculate the cosine of the angle between gravity vector and + // cell out flow direction + tmp<scalarField> calcCosAngle(const surfaceScalarField& phi) const; + + +public: + + //- Runtime type information + TypeName("curvatureSeparation"); + + + // Constructors + + //- Construct from surface film model + curvatureSeparation + ( + const surfaceFilmModel& owner, + const dictionary& dict + ); + + + //- Destructor + virtual ~curvatureSeparation(); + + + // Member Functions + + // Evolution + + //- Correct + virtual void correct + ( + scalarField& availableMass, + scalarField& massToInject, + scalarField& diameterToInject + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace surfaceFilmModels +} // End namespace regionModels +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/cloudInjection/cloudInjection.C b/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/drippingInjection/drippingInjection.C similarity index 70% rename from src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/cloudInjection/cloudInjection.C rename to src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/drippingInjection/drippingInjection.C index d9d62b80866a13877d98ce8c543d94c1b2328efc..f904af56c6708679e6d45ba5e31244465a288509 100644 --- a/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/cloudInjection/cloudInjection.C +++ b/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/drippingInjection/drippingInjection.C @@ -24,13 +24,14 @@ License \*---------------------------------------------------------------------------*/ -#include "cloudInjection.H" +#include "drippingInjection.H" #include "addToRunTimeSelectionTable.H" #include "fvMesh.H" #include "Time.H" #include "mathematicalConstants.H" #include "Random.H" #include "volFields.H" +#include "kinematicSingleLayer.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -43,18 +44,19 @@ namespace surfaceFilmModels // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // -defineTypeNameAndDebug(cloudInjection, 0); -addToRunTimeSelectionTable(injectionModel, cloudInjection, dictionary); +defineTypeNameAndDebug(drippingInjection, 0); +addToRunTimeSelectionTable(injectionModel, drippingInjection, dictionary); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -cloudInjection::cloudInjection +drippingInjection::drippingInjection ( const surfaceFilmModel& owner, const dictionary& dict ) : injectionModel(type(), owner, dict), + deltaStable_(readScalar(coeffs_.lookup("deltaStable"))), particlesPerParcel_(readScalar(coeffs_.lookup("particlesPerParcel"))), rndGen_(label(0), -1), parcelDistribution_ @@ -76,31 +78,58 @@ cloudInjection::cloudInjection // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // -cloudInjection::~cloudInjection() +drippingInjection::~drippingInjection() {} // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // -void cloudInjection::correct +void drippingInjection::correct ( + scalarField& availableMass, scalarField& massToInject, scalarField& diameterToInject ) { + const kinematicSingleLayer& film = + refCast<const kinematicSingleLayer>(this->owner()); + const scalar pi = constant::mathematical::pi; - const scalarField& rhoFilm = owner().rho(); + + // calculate available dripping mass + tmp<volScalarField> tgNorm(film.gNorm()); + const scalarField& gNorm = tgNorm(); + const scalarField& magSf = film.magSf(); + + const scalarField& delta = film.delta(); + const scalarField& rho = film.rho(); + + scalarField massDrip(film.regionMesh().nCells(), 0.0); + + forAll(gNorm, i) + { + if (gNorm[i] > SMALL) + { + const scalar ddelta = max(0.0, delta[i] - deltaStable_); + massDrip[i] += min(availableMass[i], max(0.0, ddelta*rho[i]*magSf[i])); + } + } + // Collect the data to be transferred forAll(massToInject, cellI) { - scalar rho = rhoFilm[cellI]; + scalar rhoc = rho[cellI]; scalar diam = diameter_[cellI]; - scalar minMass = particlesPerParcel_*rho*pi/6*pow3(diam); + scalar minMass = particlesPerParcel_*rhoc*pi/6*pow3(diam); - if (massToInject[cellI] > minMass) + if (massDrip[cellI] > minMass) { - // All mass can be injected - set particle diameter + // All drip mass can be injected + massToInject[cellI] += massDrip[cellI]; + availableMass[cellI] -= massDrip[cellI]; + + // Set particle diameter diameterToInject[cellI] = diameter_[cellI]; // Retrieve new particle diameter sample diff --git a/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/cloudInjection/cloudInjection.H b/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/drippingInjection/drippingInjection.H similarity index 75% rename from src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/cloudInjection/cloudInjection.H rename to src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/drippingInjection/drippingInjection.H index 017af83d49ba92ce8738833b5e9a36641d4fd377..2181c121aa552269d361f1b50e8be7ff1a41c49c 100644 --- a/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/cloudInjection/cloudInjection.H +++ b/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/drippingInjection/drippingInjection.H @@ -23,18 +23,23 @@ License Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Class - Foam::cloudInjection + Foam::drippingInjection Description - Cloud injection model + Film Dripping mass transfer model. + + If the film mass exceeds that needed to generate a valid parcel, the + equivalent mass is removed from the film. + + New parcel diameters are sampled from a PDF. SourceFiles - cloudInjection.C + drippingInjection.C \*---------------------------------------------------------------------------*/ -#ifndef cloudInjection_H -#define cloudInjection_H +#ifndef drippingInjection_H +#define drippingInjection_H #include "injectionModel.H" #include "distributionModel.H" @@ -50,10 +55,10 @@ namespace surfaceFilmModels { /*---------------------------------------------------------------------------*\ - Class cloudInjection Declaration + Class drippingInjection Declaration \*---------------------------------------------------------------------------*/ -class cloudInjection +class drippingInjection : public injectionModel { @@ -62,16 +67,20 @@ private: // Private member functions //- Disallow default bitwise copy construct - cloudInjection(const cloudInjection&); + drippingInjection(const drippingInjection&); //- Disallow default bitwise assignment - void operator=(const cloudInjection&); + void operator=(const drippingInjection&); protected: // Protected data + //- Stable film thickness - drips only formed if thickness + // execeeds this threhold value + scalar deltaStable_; + //- Number of particles per parcel scalar particlesPerParcel_; @@ -82,24 +91,28 @@ protected: const autoPtr<distributionModels::distributionModel> parcelDistribution_; - //- Diameters of particles to inject into the cloud + //- Diameters of particles to inject into the dripping scalarList diameter_; public: //- Runtime type information - TypeName("cloudInjection"); + TypeName("drippingInjection"); // Constructors //- Construct from surface film model - cloudInjection(const surfaceFilmModel& owner, const dictionary& dict); + drippingInjection + ( + const surfaceFilmModel& owner, + const dictionary& dict + ); //- Destructor - virtual ~cloudInjection(); + virtual ~drippingInjection(); // Member Functions @@ -109,6 +122,7 @@ public: //- Correct virtual void correct ( + scalarField& availableMass, scalarField& massToInject, scalarField& diameterToInject ); diff --git a/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModel/injectionModel.C b/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModel/injectionModel.C index d167131d6e9fdab221f8375c5861af610a15b1d2..203c50f29c55164e15e3524b0bc7fd1a2e6a3f04 100644 --- a/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModel/injectionModel.C +++ b/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModel/injectionModel.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2009-2011 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2009-2010 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License diff --git a/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModel/injectionModel.H b/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModel/injectionModel.H index 02fed58af32f760ac339ec2a0dc94c928173493d..401a3dee0ffa8577c669d28442f404161748026c 100644 --- a/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModel/injectionModel.H +++ b/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModel/injectionModel.H @@ -26,12 +26,12 @@ Class Foam::injectionModel Description - Base class for film injection models + Base class for film injection models, handling mass transfer from the + film. SourceFiles injectionModel.C injectionModelNew.C - \*---------------------------------------------------------------------------*/ #ifndef injectionModel_H @@ -109,7 +109,8 @@ public: static autoPtr<injectionModel> New ( const surfaceFilmModel& owner, - const dictionary& dict + const dictionary& dict, + const word& mdoelType ); @@ -124,6 +125,7 @@ public: //- Correct virtual void correct ( + scalarField& availableMass, scalarField& massToInject, scalarField& diameterToInject ) = 0; diff --git a/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModel/injectionModelNew.C b/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModel/injectionModelNew.C index 51ef515f87aa6553f1758eea21c9b713b7571da9..79c908b3db193e00f969f90c38529ba087145ccd 100644 --- a/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModel/injectionModelNew.C +++ b/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModel/injectionModelNew.C @@ -40,12 +40,11 @@ namespace surfaceFilmModels autoPtr<injectionModel> injectionModel::New ( const surfaceFilmModel& model, - const dictionary& dict + const dictionary& dict, + const word& modelType ) { - word modelType(dict.lookup("injectionModel")); - - Info<< " Selecting injectionModel " << modelType << endl; + Info<< " " << modelType << endl; dictionaryConstructorTable::iterator cstrIter = dictionaryConstructorTablePtr_->find(modelType); diff --git a/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModelList/injectionModelList.C b/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModelList/injectionModelList.C new file mode 100644 index 0000000000000000000000000000000000000000..57f7ae0686c4e0ccb0c1c900b2f0d7e4ba76b062 --- /dev/null +++ b/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModelList/injectionModelList.C @@ -0,0 +1,135 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2011 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "injectionModelList.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace regionModels +{ +namespace surfaceFilmModels +{ + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +injectionModelList::injectionModelList(const surfaceFilmModel& owner) +: + PtrList<injectionModel>(), + owner_(owner), + dict_(dictionary::null), + injectedMassTotal_(0.0) +{} + + +injectionModelList::injectionModelList +( + const surfaceFilmModel& owner, + const dictionary& dict +) +: + PtrList<injectionModel>(), + owner_(owner), + dict_(dict), + injectedMassTotal_(0.0) +{ + const wordList activeModels(dict.lookup("injectionModels")); + + wordHashSet models; + forAll(activeModels, i) + { + models.insert(activeModels[i]); + } + + Info<< " Selecting film injection models" << endl; + if (models.size() > 0) + { + this->setSize(models.size()); + + label i = 0; + forAllConstIter(wordHashSet, models, iter) + { + const word& model = iter.key(); + set + ( + i, + injectionModel::New(owner, dict, model) + ); + i++; + } + } + else + { + Info<< " none" << endl; + } +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +injectionModelList::~injectionModelList() +{} + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void injectionModelList::correct +( + scalarField& availableMass, + volScalarField& massToInject, + volScalarField& diameterToInject +) +{ + // Correct models that accumulate mass and diameter transfers + forAll(*this, i) + { + injectionModel& im = operator[](i); + im.correct(availableMass, massToInject, diameterToInject); + } + + injectedMassTotal_ += sum(massToInject.internalField()); + + + // Push values to boundaries ready for transfer to the primary region + massToInject.correctBoundaryConditions(); + diameterToInject.correctBoundaryConditions(); +} + + +void injectionModelList::info(Ostream& os) const +{ + os << indent << "injected mass = " + << returnReduce<scalar>(injectedMassTotal_, sumOp<scalar>()) << nl; +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace surfaceFilmModels +} // End namespace regionModels +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/noInjection/noInjection.H b/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModelList/injectionModelList.H similarity index 62% rename from src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/noInjection/noInjection.H rename to src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModelList/injectionModelList.H index 2d26dff4fc1d7091f2ca7966ba3ff5411a928f51..3aaac5f28a7e6f19ff0b887f0148bed74d9d012e 100644 --- a/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/noInjection/noInjection.H +++ b/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModelList/injectionModelList.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2009-2011 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2011-2011 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -23,19 +23,20 @@ License Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Class - Foam::noInjection + Foam::injectionModelList Description - Dummy injection model for 'none' + List container for film injection models SourceFiles - noInjection.C + injectionModelList.C \*---------------------------------------------------------------------------*/ -#ifndef noInjection_H -#define noInjection_H +#ifndef injectionModelList_H +#define injectionModelList_H +#include "PtrList.H" #include "injectionModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -48,38 +49,53 @@ namespace surfaceFilmModels { /*---------------------------------------------------------------------------*\ - Class noInjection Declaration + Class injectionModelList Declaration \*---------------------------------------------------------------------------*/ -class noInjection +class injectionModelList : - public injectionModel + public PtrList<injectionModel> { private: - // Private member functions + // Private data + + //- Reference to the owner surface film model + const surfaceFilmModel& owner_; + + //- Dictionary + dictionary dict_; + + //- Cumulative mass injected total + scalar injectedMassTotal_; + + + // Private Member Functions //- Disallow default bitwise copy construct - noInjection(const noInjection&); + injectionModelList(const injectionModelList&); //- Disallow default bitwise assignment - void operator=(const noInjection&); + void operator=(const injectionModelList&); public: - //- Runtime type information - TypeName("none"); - - // Constructors - //- Construct from surface film model - noInjection(const surfaceFilmModel& owner, const dictionary& dict); + //- Construct null + injectionModelList(const surfaceFilmModel& owner); + + //- Construct from type name, dictionary and surface film model + injectionModelList + ( + const surfaceFilmModel& owner, + const dictionary& dict + ); //- Destructor - virtual ~noInjection(); + virtual ~injectionModelList(); // Member Functions @@ -89,9 +105,16 @@ public: //- Correct virtual void correct ( - scalarField& massToInject, - scalarField& diameterToInject + scalarField& availableMass, + volScalarField& massToInject, + volScalarField& diameterToInject ); + + + // I-O + + //- Provide some info + void info(Ostream& os) const; }; diff --git a/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/noInjection/noInjection.C b/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/noInjection/noInjection.C deleted file mode 100644 index 442e68ce9c52d9c6e1ffce8c0089b7cb571354aa..0000000000000000000000000000000000000000 --- a/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/noInjection/noInjection.C +++ /dev/null @@ -1,81 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2009-2011 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2 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, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -\*---------------------------------------------------------------------------*/ - -#include "noInjection.H" -#include "addToRunTimeSelectionTable.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ -namespace regionModels -{ -namespace surfaceFilmModels -{ - -// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // - -defineTypeNameAndDebug(noInjection, 0); -addToRunTimeSelectionTable(injectionModel, noInjection, dictionary); - -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -noInjection::noInjection -( - const surfaceFilmModel& owner, - const dictionary& -) -: - injectionModel(owner) -{} - - -// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // - -noInjection::~noInjection() -{} - - -// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // - -void noInjection::correct -( - scalarField& massToInject, - scalarField& diameterToInject -) -{ - // no mass injected - massToInject = 0.0; -} - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace surfaceFilmModels -} // End namespace regionModels -} // End namespace Foam - -// ************************************************************************* // diff --git a/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/removeInjection/removeInjection.C b/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/removeInjection/removeInjection.C index bffa600add7df59f5367d16f6f203a36b8d03827..e0d18d5077bd33853acc9a89ded39b8a95a2e32f 100644 --- a/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/removeInjection/removeInjection.C +++ b/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/removeInjection/removeInjection.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2010-2011 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -63,11 +63,13 @@ removeInjection::~removeInjection() void removeInjection::correct ( - scalarField&, + scalarField& availableMass, + scalarField& massToInject, scalarField& ) { - // do nothing - all mass available to be removed + massToInject = availableMass; + availableMass = 0.0; } diff --git a/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/removeInjection/removeInjection.H b/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/removeInjection/removeInjection.H index eae2c1da5f6933d9e35a18b50e9d0cb1fe9bec9c..ce189ac82e7b268159f41d25ed631da660bc92e5 100644 --- a/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/removeInjection/removeInjection.H +++ b/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/removeInjection/removeInjection.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2009-2011 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2009-2010 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -89,6 +89,7 @@ public: //- Correct virtual void correct ( + scalarField& availableMass, scalarField& massToInject, scalarField& diameterToInject ); diff --git a/src/regionModels/surfaceFilmModels/submodels/subModelBaseI.H b/src/regionModels/surfaceFilmModels/submodels/subModelBaseI.H index 3c5a1933eab8a822417fb6ef78a94e5d457c350c..67551e42f53e856e0271afa0759781c8bf89489c 100644 --- a/src/regionModels/surfaceFilmModels/submodels/subModelBaseI.H +++ b/src/regionModels/surfaceFilmModels/submodels/subModelBaseI.H @@ -24,8 +24,6 @@ License \*---------------------------------------------------------------------------*/ -#include "subModelBase.H" - // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam diff --git a/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/noPhaseChange/noPhaseChange.C b/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/noPhaseChange/noPhaseChange.C index be5ec46e154c6823211433db6c0d575573e886cd..b7736dec1d2063b8c1c69c4647f9f2b0ca24a56a 100644 --- a/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/noPhaseChange/noPhaseChange.C +++ b/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/noPhaseChange/noPhaseChange.C @@ -61,10 +61,11 @@ noPhaseChange::~noPhaseChange() // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // -void noPhaseChange::correct +void noPhaseChange::correctModel ( const scalar, scalarField&, + scalarField&, scalarField& ) { diff --git a/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/noPhaseChange/noPhaseChange.H b/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/noPhaseChange/noPhaseChange.H index 523955ee956770eaa2cbf78307ce00d43ba04af8..6108de35bbc8cda39f9f79289e836497e48bb244 100644 --- a/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/noPhaseChange/noPhaseChange.H +++ b/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/noPhaseChange/noPhaseChange.H @@ -87,9 +87,10 @@ public: // Evolution //- Correct - virtual void correct + virtual void correctModel ( const scalar dt, + scalarField& availableMass, scalarField& dMass, scalarField& dEnergy ); diff --git a/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/phaseChangeModel/phaseChangeModel.C b/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/phaseChangeModel/phaseChangeModel.C index 98b91c40fba774e4ec2b2f12034df9ae642cd01c..97365896cc5223072a1bc3c500286e2537f46fad 100644 --- a/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/phaseChangeModel/phaseChangeModel.C +++ b/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/phaseChangeModel/phaseChangeModel.C @@ -47,7 +47,9 @@ phaseChangeModel::phaseChangeModel const surfaceFilmModel& owner ) : - subModelBase(owner) + subModelBase(owner), + latestMassPC_(0.0), + totalMassPC_(0.0) {} @@ -58,7 +60,9 @@ phaseChangeModel::phaseChangeModel const dictionary& dict ) : - subModelBase(type, owner, dict) + subModelBase(type, owner, dict), + latestMassPC_(0.0), + totalMassPC_(0.0) {} @@ -68,6 +72,44 @@ phaseChangeModel::~phaseChangeModel() {} +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +void phaseChangeModel::correct +( + const scalar dt, + scalarField& availableMass, + volScalarField& dMass, + volScalarField& dEnergy +) +{ + correctModel + ( + dt, + availableMass, + dMass, + dEnergy + ); + + latestMassPC_ = sum(dMass.internalField()); + totalMassPC_ += latestMassPC_; + + availableMass -= dMass; + dMass.correctBoundaryConditions(); +} + + +void phaseChangeModel::info(Ostream& os) const +{ + const scalar massPCRate = + returnReduce(latestMassPC_, sumOp<scalar>()) + /owner_.time().deltaTValue(); + + os << indent << "mass phase change = " + << returnReduce(totalMassPC_, sumOp<scalar>()) << nl + << indent << "vapourisation rate = " << massPCRate << nl; +} + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // end namespace surfaceFilmModels diff --git a/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/phaseChangeModel/phaseChangeModel.H b/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/phaseChangeModel/phaseChangeModel.H index 909c71ec68010b92aba8daf4626f068700ff3b7c..b537cf59d7938619f4703f55b07a7ee8c5c9aeca 100644 --- a/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/phaseChangeModel/phaseChangeModel.H +++ b/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/phaseChangeModel/phaseChangeModel.H @@ -69,6 +69,17 @@ private: void operator=(const phaseChangeModel&); +protected: + + // Protected Member Functions + + //- Latest mass transfer due to phase change + scalar latestMassPC_; + + //- Total mass transfer due to phase change + scalar totalMassPC_; + + public: //- Runtime type information @@ -125,9 +136,25 @@ public: virtual void correct ( const scalar dt, + scalarField& availableMass, + volScalarField& dMass, + volScalarField& dEnergy + ); + + //- Correct + virtual void correctModel + ( + const scalar dt, + scalarField& availableMass, scalarField& dMass, scalarField& dEnergy ) = 0; + + + // I-O + + //- Provide some feedback + virtual void info(Ostream& os) const; }; diff --git a/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/standardPhaseChange/standardPhaseChange.C b/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/standardPhaseChange/standardPhaseChange.C index d5ebfa3a30a4bdffe1604e3c1f9a888fb690c8f9..1a3a67062ba1ee60b10bfbab20fb650a14c9d364 100644 --- a/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/standardPhaseChange/standardPhaseChange.C +++ b/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/standardPhaseChange/standardPhaseChange.C @@ -81,9 +81,7 @@ standardPhaseChange::standardPhaseChange Tb_(readScalar(coeffs_.lookup("Tb"))), deltaMin_(readScalar(coeffs_.lookup("deltaMin"))), L_(readScalar(coeffs_.lookup("L"))), - TbFactor_(coeffs_.lookupOrDefault<scalar>("TbFactor", 1.1)), - totalMass_(0.0), - vapourRate_(0.0) + TbFactor_(coeffs_.lookupOrDefault<scalar>("TbFactor", 1.1)) {} @@ -95,9 +93,10 @@ standardPhaseChange::~standardPhaseChange() // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // -void standardPhaseChange::correct +void standardPhaseChange::correctModel ( const scalar dt, + scalarField& availableMass, scalarField& dMass, scalarField& dEnergy ) @@ -124,8 +123,7 @@ void standardPhaseChange::correct const scalarField hInf(film.htcs().h()); const scalarField hFilm(film.htcw().h()); const vectorField dU(film.UPrimary() - film.Us()); - const scalarField availableMass((delta - deltaMin_)*rho*magSf); - + const scalarField limMass(max(0.0, availableMass - deltaMin_*rho*magSf)); forAll(dMass, cellI) { @@ -152,8 +150,7 @@ void standardPhaseChange::correct const scalar Cp = liq.Cp(pc, Tloc); const scalar Tcorr = max(0.0, T[cellI] - Tb_); - const scalar qCorr = availableMass[cellI]*Cp*(Tcorr); - + const scalar qCorr = limMass[cellI]*Cp*(Tcorr); dMass[cellI] = dt*magSf[cellI]/hVap*(qDotInf + qDotFilm) + qCorr/hVap; @@ -195,23 +192,10 @@ void standardPhaseChange::correct dt*magSf[cellI]*rhoInfc*hm*(Ys - YInf[cellI])/(1.0 - Ys); } - dMass[cellI] = min(availableMass[cellI], max(0.0, dMass[cellI])); + dMass[cellI] = min(limMass[cellI], max(0.0, dMass[cellI])); dEnergy[cellI] = dMass[cellI]*hVap; } } - - const scalar sumdMass = sum(dMass); - totalMass_ += sumdMass; - vapourRate_ = sumdMass/owner().time().deltaTValue(); -} - - -void standardPhaseChange::info() const -{ - Info<< indent << "mass phase change = " - << returnReduce(totalMass_, sumOp<scalar>()) << nl - << indent << "vapourisation rate = " - << returnReduce(vapourRate_, sumOp<scalar>()) << nl; } diff --git a/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/standardPhaseChange/standardPhaseChange.H b/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/standardPhaseChange/standardPhaseChange.H index 29227f296b1811a96779e4498e64c053473e91de..3d0c07a54871d7176fe3f6683fb26a574e154565 100644 --- a/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/standardPhaseChange/standardPhaseChange.H +++ b/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/standardPhaseChange/standardPhaseChange.H @@ -83,12 +83,6 @@ protected: // Used to set max limit on temperature to Tb*TbFactor const scalar TbFactor_; - //- Total mass evolved / [kg] - scalar totalMass_; - - //- Vapouristaion rate / kg/s - scalar vapourRate_; - // Protected member functions @@ -121,18 +115,13 @@ public: // Evolution //- Correct - virtual void correct + virtual void correctModel ( const scalar dt, + scalarField& availableMass, scalarField& dMass, scalarField& dEnergy ); - - - // Input/output - - //- Output model statistics - virtual void info() const; }; diff --git a/src/regionModels/surfaceFilmModels/surfaceFilmModel/surfaceFilmModel.H b/src/regionModels/surfaceFilmModels/surfaceFilmModel/surfaceFilmModel.H index ba4663a755c34e307b00ab1321b071d54ec54ac1..8a0f01b6b6dcab3321160f6cf11fa5950ce56722 100644 --- a/src/regionModels/surfaceFilmModels/surfaceFilmModel/surfaceFilmModel.H +++ b/src/regionModels/surfaceFilmModels/surfaceFilmModel/surfaceFilmModel.H @@ -161,6 +161,9 @@ public: // Access + //- Return the accleration due to gravity + inline const dimensionedVector& g() const; + //- Return the thermo type inline const thermoModelType& thermoModel() const; @@ -176,7 +179,7 @@ public: ) = 0; - // Solution parameters + // Solution parameters //- Courant number evaluation virtual scalar CourantNumber() const; @@ -184,48 +187,50 @@ public: // Fields - //- Return the film thickness [m] - virtual const volScalarField& delta() const = 0; + //- Return the film thickness [m] + virtual const volScalarField& delta() const = 0; - //- Return the film velocity [m/s] - virtual const volVectorField& U() const = 0; + //- Return the film velocity [m/s] + virtual const volVectorField& U() const = 0; - //- Return the film surface velocity [m/s] - virtual const volVectorField& Us() const = 0; + //- Return the film surface velocity [m/s] + virtual const volVectorField& Us() const = 0; - //- Return the film wall velocity [m/s] - virtual const volVectorField& Uw() const = 0; + //- Return the film wall velocity [m/s] + virtual const volVectorField& Uw() const = 0; - //- Return the film density [kg/m3] - virtual const volScalarField& rho() const = 0; + //- Return the film density [kg/m3] + virtual const volScalarField& rho() const = 0; - //- Return the film mean temperature [K] - virtual const volScalarField& T() const = 0; + //- Return the film mean temperature [K] + virtual const volScalarField& T() const = 0; - //- Return the film surface temperature [K] - virtual const volScalarField& Ts() const = 0; + //- Return the film surface temperature [K] + virtual const volScalarField& Ts() const = 0; - //- Return the film wall temperature [K] - virtual const volScalarField& Tw() const = 0; + //- Return the film wall temperature [K] + virtual const volScalarField& Tw() const = 0; //- Return the film specific heat capacity [J/kg/K] - virtual const volScalarField& Cp() const = 0; + virtual const volScalarField& Cp() const = 0; + + //- Return the film thermal conductivity [W/m/K] + virtual const volScalarField& kappa() const = 0; - //- Return the film thermal conductivity [W/m/K] - virtual const volScalarField& kappa() const = 0; + //- Return the film surface tension [N/m] + virtual const volScalarField& sigma() const = 0; - // Transfer fields - to the primary region + // Transfer fields - to the primary region - //- Return the film mass available for transfer - virtual const volScalarField& massForPrimary() const = 0; + //- Return mass transfer source - Eulerian phase only + virtual tmp<volScalarField> primaryMassTrans() const = 0; - //- Return the parcel diameters originating from film - virtual const volScalarField& diametersForPrimary() const = 0; + //- Return the film mass available for transfer + virtual const volScalarField& cloudMassTrans() const = 0; - //- Return the film mass evolved via phase change - virtual const volScalarField& massPhaseChangeForPrimary() - const = 0; + //- Return the parcel diameters originating from film + virtual const volScalarField& cloudDiameterTrans() const = 0; // Source fields diff --git a/src/regionModels/surfaceFilmModels/surfaceFilmModel/surfaceFilmModelI.H b/src/regionModels/surfaceFilmModels/surfaceFilmModel/surfaceFilmModelI.H index 2c8829284ea8996628094500c3b7f6880e108d95..3e5fdacdbee9c75c577fca120b951e691ea67278 100644 --- a/src/regionModels/surfaceFilmModels/surfaceFilmModel/surfaceFilmModelI.H +++ b/src/regionModels/surfaceFilmModels/surfaceFilmModel/surfaceFilmModelI.H @@ -37,6 +37,12 @@ namespace surfaceFilmModels // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +inline const Foam::dimensionedVector& surfaceFilmModel::g() const +{ + return g_; +} + + inline const surfaceFilmModel::thermoModelType& surfaceFilmModel::thermoModel() const { diff --git a/src/regionModels/surfaceFilmModels/thermoSingleLayer/thermoSingleLayer.C b/src/regionModels/surfaceFilmModels/thermoSingleLayer/thermoSingleLayer.C index 9aceadfc030fd4086de8ba39dba345c621691b0f..e6ce90d3af1e3c520a50c2e6c54160305c7125aa 100644 --- a/src/regionModels/surfaceFilmModels/thermoSingleLayer/thermoSingleLayer.C +++ b/src/regionModels/surfaceFilmModels/thermoSingleLayer/thermoSingleLayer.C @@ -81,6 +81,11 @@ bool thermoSingleLayer::read() void thermoSingleLayer::resetPrimaryRegionSourceTerms() { + if (debug) + { + Info<< "thermoSingleLayer::resetPrimaryRegionSourceTerms()" << endl; + } + kinematicSingleLayer::resetPrimaryRegionSourceTerms(); hsSpPrimary_ == dimensionedScalar("zero", hsSp_.dimensions(), 0.0); @@ -105,6 +110,7 @@ void thermoSingleLayer::correctThermoFields() { const liquidProperties& liq = thermo_.liquids().properties()[liquidId_]; + forAll(rho_, cellI) { const scalar T = T_[cellI]; @@ -173,6 +179,11 @@ void thermoSingleLayer::updateSurfaceTemperatures() void thermoSingleLayer::transferPrimaryRegionThermoFields() { + if (debug) + { + Info<< "thermoSingleLayer::transferPrimaryRegionThermoFields()" << endl; + } + kinematicSingleLayer::transferPrimaryRegionThermoFields(); // Update primary region fields on local region via direct mapped (coupled) @@ -187,6 +198,11 @@ void thermoSingleLayer::transferPrimaryRegionThermoFields() void thermoSingleLayer::transferPrimaryRegionSourceFields() { + if (debug) + { + Info<< "thermoSingleLayer::transferPrimaryRegionSourceFields()" << endl; + } + kinematicSingleLayer::transferPrimaryRegionSourceFields(); // Retrieve the source fields from the primary region via direct mapped @@ -199,27 +215,30 @@ void thermoSingleLayer::transferPrimaryRegionSourceFields() // Note: boundary values will still have original (neat) values const scalar deltaT = time_.deltaTValue(); hsSp_.field() /= magSf()*deltaT; + + // Apply enthalpy source as difference between incoming and actual states + hsSp_ -= rhoSp_*hs_; } void thermoSingleLayer::updateSubmodels() { + if (debug) + { + Info<< "thermoSingleLayer::updateSubmodels()" << endl; + } + // Update heat transfer coefficient sub-models htcs_->correct(); htcw_->correct(); - // Update phase change - massPhaseChangeForPrimary_.internalField() = 0.0; - energyPhaseChangeForPrimary_.internalField() = 0.0; - phaseChange_->correct ( time_.deltaTValue(), - massPhaseChangeForPrimary_, - energyPhaseChangeForPrimary_ + availableMass_, + primaryMassPCTrans_, + primaryEnergyPCTrans_ ); - massPhaseChangeForPrimary_.correctBoundaryConditions(); - totalMassPhaseChange_ += sum(massPhaseChangeForPrimary_).value(); // Update radiation radiation_->correct(); @@ -228,14 +247,12 @@ void thermoSingleLayer::updateSubmodels() kinematicSingleLayer::updateSubmodels(); // Update source fields - hsSp_ -= energyPhaseChangeForPrimary_/magSf()/time().deltaT(); + hsSp_ += primaryEnergyPCTrans_/magSf()/time().deltaT(); + rhoSp_ += primaryMassPCTrans_/magSf()/time().deltaT(); } -tmp<fvScalarMatrix> thermoSingleLayer::q -( - volScalarField& hs -) const +tmp<fvScalarMatrix> thermoSingleLayer::q(volScalarField& hs) const { dimensionedScalar Tstd("Tstd", dimTemperature, 298.15); @@ -263,10 +280,11 @@ void thermoSingleLayer::solveEnergy() fvm::ddt(deltaRho_, hs_) + fvm::div(phi_, hs_) == - fvm::Sp(hsSp_/(hs_ + hs0), hs_) +// - hsSp_ + - fvm::Sp(hsSp_/(hs_ + hs0), hs_) + q(hs_) + radiation_->Shs() - - fvm::Sp(massForPrimary_/magSf()/time().deltaT(), hs_) + - fvm::SuSp(rhoSp_, hs_) ); correctThermoFields(); @@ -370,10 +388,38 @@ thermoSingleLayer::thermoSingleLayer ), regionMesh(), dimensionedScalar("zero", dimEnergy/dimMass, 0.0), -// T_.boundaryField().types() hsBoundaryTypes() ), + primaryMassPCTrans_ + ( + IOobject + ( + "primaryMassPCTrans", + time().timeName(), + regionMesh(), + IOobject::NO_READ, + IOobject::NO_WRITE + ), + regionMesh(), + dimensionedScalar("zero", dimMass, 0), + zeroGradientFvPatchScalarField::typeName + ), + primaryEnergyPCTrans_ + ( + IOobject + ( + "primaryEnergyPCTrans", + time().timeName(), + regionMesh(), + IOobject::NO_READ, + IOobject::NO_WRITE + ), + regionMesh(), + dimensionedScalar("zero", dimEnergy, 0), + zeroGradientFvPatchScalarField::typeName + ), + hsSp_ ( IOobject @@ -429,22 +475,7 @@ thermoSingleLayer::thermoSingleLayer heatTransferModel::New(*this, coeffs().subDict("lowerSurfaceModels")) ), phaseChange_(phaseChangeModel::New(*this, coeffs())), - radiation_(filmRadiationModel::New(*this, coeffs())), - totalMassPhaseChange_(0.0), - energyPhaseChangeForPrimary_ - ( - IOobject - ( - "energyPhaseChangeForPrimary", - time().timeName(), - regionMesh(), - IOobject::NO_READ, - IOobject::NO_WRITE - ), - regionMesh(), - dimensionedScalar("zero", dimEnergy, 0), - zeroGradientFvPatchScalarField::typeName - ) + radiation_(filmRadiationModel::New(*this, coeffs())) { if (thermo_.hasMultiComponentCarrier()) { @@ -519,24 +550,34 @@ void thermoSingleLayer::addSources Info<< " energy = " << energySource << nl << endl; } - hsSpPrimary_.boundaryField()[patchI][faceI] += energySource; + hsSpPrimary_.boundaryField()[patchI][faceI] -= energySource; } void thermoSingleLayer::preEvolveRegion() { - transferPrimaryRegionThermoFields(); + if (debug) + { + Info<< "thermoSingleLayer::preEvolveRegion()" << endl; + } // correctHsForMappedT(); - correctThermoFields(); + kinematicSingleLayer::preEvolveRegion(); - transferPrimaryRegionSourceFields(); + // Update phase change + primaryMassPCTrans_ == dimensionedScalar("zero", dimMass, 0.0); + primaryEnergyPCTrans_ == dimensionedScalar("zero", dimEnergy, 0.0); } void thermoSingleLayer::evolveRegion() { + if (debug) + { + Info<< "thermoSingleLayer::evolveRegion()" << endl; + } + updateSubmodels(); // Solve continuity for deltaRho_ @@ -617,16 +658,67 @@ const volScalarField& thermoSingleLayer::hs() const } +tmp<volScalarField> thermoSingleLayer::primaryMassTrans() const +{ + return primaryMassPCTrans_; +} + + void thermoSingleLayer::info() const { kinematicSingleLayer::info(); Info<< indent << "min/max(T) = " << min(T_).value() << ", " - << max(T_).value() << nl - << indent << "mass phase change = " - << returnReduce(totalMassPhaseChange_, sumOp<scalar>()) << nl - << indent << "vapourisation rate = " - << sum(massPhaseChangeForPrimary_).value()/time_.deltaTValue() << nl; + << max(T_).value() << nl; + + phaseChange_->info(Info); +} + + +tmp<DimensionedField<scalar, volMesh> > thermoSingleLayer::Srho() const +{ + tmp<DimensionedField<scalar, volMesh> > tSrho + ( + new DimensionedField<scalar, volMesh> + ( + IOobject + ( + "thermoSingleLayer::Srho", + time().timeName(), + primaryMesh(), + IOobject::NO_READ, + IOobject::NO_WRITE, + false + ), + primaryMesh(), + dimensionedScalar("zero", dimMass/dimVolume/dimTime, 0.0) + ) + ); + + scalarField& Srho = tSrho(); + const scalarField& V = primaryMesh().V(); + const scalar dt = time_.deltaTValue(); + + forAll(intCoupledPatchIDs(), i) + { + const label filmPatchI = intCoupledPatchIDs()[i]; + const mapDistribute& distMap = mappedPatches_[filmPatchI].map(); + + scalarField patchMass = + primaryMassPCTrans_.boundaryField()[filmPatchI]; + distMap.distribute(patchMass); + + const label primaryPatchI = primaryPatchIDs()[i]; + const unallocLabelList& cells = + primaryMesh().boundaryMesh()[primaryPatchI].faceCells(); + + forAll(patchMass, j) + { + Srho[cells[j]] = patchMass[j]/(V[cells[j]]*dt); + } + } + + return tSrho; } @@ -644,7 +736,7 @@ tmp<DimensionedField<scalar, volMesh> > thermoSingleLayer::Srho ( IOobject ( - "thermoSingleLayer::Srho(i)", + "thermoSingleLayer::Srho(" + Foam::name(i) + ")", time_.timeName(), primaryMesh(), IOobject::NO_READ, @@ -668,7 +760,7 @@ tmp<DimensionedField<scalar, volMesh> > thermoSingleLayer::Srho const mapDistribute& distMap = mappedPatches_[filmPatchI].map(); scalarField patchMass = - massPhaseChangeForPrimary_.boundaryField()[filmPatchI]; + primaryMassPCTrans_.boundaryField()[filmPatchI]; distMap.distribute(patchMass); const label primaryPatchI = primaryPatchIDs()[i]; @@ -706,8 +798,10 @@ tmp<DimensionedField<scalar, volMesh> > thermoSingleLayer::Sh() const ) ); /* + phase change energy fed back into the film... + scalarField& Sh = tSh(); - const scalarField& V = mesh_.V(); + const scalarField& V = primaryMesh().V(); const scalar dt = time_.deltaTValue(); forAll(intCoupledPatchIDs_, i) @@ -716,14 +810,14 @@ tmp<DimensionedField<scalar, volMesh> > thermoSingleLayer::Sh() const const mapDistribute& distMap = mappedPatches_[filmPatchI].map(); scalarField patchEnergy = - energyPhaseChangeForPrimary_.boundaryField()[filmPatchI]; + primaryEnergyPCTrans_.boundaryField()[filmPatchI]; distMap.distribute(patchEnergy); const label primaryPatchI = primaryPatchIDs()[i]; const unallocLabelList& cells = primaryMesh().boundaryMesh()[primaryPatchI].faceCells(); - forAll(patchMass, j) + forAll(patchEnergy, j) { Sh[cells[j]] += patchEnergy[j]/(V[cells[j]]*dt); } diff --git a/src/regionModels/surfaceFilmModels/thermoSingleLayer/thermoSingleLayer.H b/src/regionModels/surfaceFilmModels/thermoSingleLayer/thermoSingleLayer.H index ddd53f2d11b536b78eb8157001485d4c94bba767..a2788f7128e5687466bfac3eaa31dae951bd33cb 100644 --- a/src/regionModels/surfaceFilmModels/thermoSingleLayer/thermoSingleLayer.H +++ b/src/regionModels/surfaceFilmModels/thermoSingleLayer/thermoSingleLayer.H @@ -115,6 +115,15 @@ protected: volScalarField hs_; + // Transfer fields - to the primary region + + //- Film mass evolved via phase change + volScalarField primaryMassPCTrans_; + + //- Film energy evolved via phase change + volScalarField primaryEnergyPCTrans_; + + // Source term fields // Film region - registered to the film region mesh @@ -157,11 +166,6 @@ protected: //- Radiation autoPtr<filmRadiationModel> radiation_; - //- Total mass transferred to primary region [kg] - scalar totalMassPhaseChange_; - - //- Film energy evolved via phase change - volScalarField energyPhaseChangeForPrimary_; // Protected member functions @@ -256,6 +260,13 @@ public: virtual const volScalarField& hs() const; + + // Transfer fields - to the primary region + + //- Return mass transfer source - Eulerian phase only + virtual tmp<volScalarField> primaryMassTrans() const; + + // Helper functions //- Return sensible enthalpy as a function of temperature @@ -345,6 +356,9 @@ public: // Mapped into primary region + //- Return total mass source - Eulerian phase only + virtual tmp<DimensionedField<scalar, volMesh> > Srho() const; + //- Return mass source for specie i - Eulerian phase only virtual tmp<DimensionedField<scalar, volMesh> > Srho (