diff --git a/src/lagrangian/intermediate/parcels/include/makeParcelCloudFunctionObjects.H b/src/lagrangian/intermediate/parcels/include/makeParcelCloudFunctionObjects.H index f95d5d0ef0e4d2fbdefb6207af569765d973ab03..6b0d78ac3862050619037fbafb66739749f16548 100644 --- a/src/lagrangian/intermediate/parcels/include/makeParcelCloudFunctionObjects.H +++ b/src/lagrangian/intermediate/parcels/include/makeParcelCloudFunctionObjects.H @@ -45,6 +45,7 @@ License #include "RemoveParcels.H" #include "VoidFraction.H" #include "KinematicReynoldsNumber.H" +#include "ParticleDose.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -65,7 +66,8 @@ License makeCloudFunctionObjectType(PatchParticleHistogram, CloudType); \ makeCloudFunctionObjectType(RemoveParcels, CloudType); \ makeCloudFunctionObjectType(VoidFraction, CloudType); \ - makeCloudFunctionObjectType(KinematicReynoldsNumber, CloudType); + makeCloudFunctionObjectType(KinematicReynoldsNumber, CloudType); \ + makeCloudFunctionObjectType(ParticleDose, CloudType); // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/lagrangian/intermediate/parcels/include/makeReactingParcelCloudFunctionObjects.H b/src/lagrangian/intermediate/parcels/include/makeReactingParcelCloudFunctionObjects.H index 16258ff40c91d85ed91affd013a388154d73792a..e8bed51a3e23ec5e19e9d7a0af32adcdf91f8f1a 100644 --- a/src/lagrangian/intermediate/parcels/include/makeReactingParcelCloudFunctionObjects.H +++ b/src/lagrangian/intermediate/parcels/include/makeReactingParcelCloudFunctionObjects.H @@ -48,6 +48,7 @@ License #include "HeatTransferCoeff.H" #include "ThermoReynoldsNumber.H" #include "WeberNumberReacting.H" +#include "ParticleDose.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -71,7 +72,8 @@ License makeCloudFunctionObjectType(NusseltNumber, CloudType); \ makeCloudFunctionObjectType(HeatTransferCoeff, CloudType); \ makeCloudFunctionObjectType(ThermoReynoldsNumber, CloudType); \ - makeCloudFunctionObjectType(WeberNumberReacting, CloudType); + makeCloudFunctionObjectType(WeberNumberReacting, CloudType); \ + makeCloudFunctionObjectType(ParticleDose, CloudType); // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/lagrangian/intermediate/parcels/include/makeThermoParcelCloudFunctionObjects.H b/src/lagrangian/intermediate/parcels/include/makeThermoParcelCloudFunctionObjects.H index a703eb80407711c6cf4a94cb3d854e23522c5dbb..0e0a312b8f86b50d2cdce162bf24c11e2adbd282 100644 --- a/src/lagrangian/intermediate/parcels/include/makeThermoParcelCloudFunctionObjects.H +++ b/src/lagrangian/intermediate/parcels/include/makeThermoParcelCloudFunctionObjects.H @@ -46,6 +46,7 @@ License #include "NusseltNumber.H" #include "HeatTransferCoeff.H" #include "ThermoReynoldsNumber.H" +#include "ParticleDose.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -68,7 +69,8 @@ License makeCloudFunctionObjectType(VoidFraction, CloudType); \ makeCloudFunctionObjectType(NusseltNumber, CloudType); \ makeCloudFunctionObjectType(HeatTransferCoeff, CloudType); \ - makeCloudFunctionObjectType(ThermoReynoldsNumber, CloudType); + makeCloudFunctionObjectType(ThermoReynoldsNumber, CloudType); \ + makeCloudFunctionObjectType(ParticleDose, CloudType); // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/ParticleDose/ParticleDose.C b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/ParticleDose/ParticleDose.C new file mode 100644 index 0000000000000000000000000000000000000000..2868804093929fed8feed8f88c9a1a6170126a7a --- /dev/null +++ b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/ParticleDose/ParticleDose.C @@ -0,0 +1,108 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2022 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "ParticleDose.H" +#include "volFields.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template<class CloudType> +Foam::ParticleDose<CloudType>::ParticleDose +( + const dictionary& dict, + CloudType& owner, + const word& modelName +) +: + CloudFunctionObject<CloudType>(dict, owner, modelName, typeName), + GName_(this->coeffDict().getWord("GName")) +{} + + +template<class CloudType> +Foam::ParticleDose<CloudType>::ParticleDose +( + const ParticleDose<CloudType>& re +) +: + CloudFunctionObject<CloudType>(re), + GName_(re.GName_) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template<class CloudType> +void Foam::ParticleDose<CloudType>::postEvolve +( + const typename parcelType::trackingData& td +) +{ + auto& c = this->owner(); + + if (!c.template foundObject<IOField<scalar>>("D")) + { + auto* DPtr = + new IOField<scalar> + ( + IOobject + ( + "D", + c.time().timeName(), + c, + IOobject::NO_READ + ) + ); + + DPtr->store(); + } + + auto& D = c.template lookupObjectRef<IOField<scalar>>("D"); + + D.resize(c.size(), Zero); + + const fvMesh& mesh = this->owner().mesh(); + + const auto& G = mesh.lookupObject<volScalarField>(GName_); + + label parceli = 0; + forAllConstIters(c, parcelIter) + { + const parcelType& p = parcelIter(); + + D[parceli] += G[p.cell()]*mesh.time().deltaTValue(); + parceli++; + } + + if (c.size() && c.time().writeTime()) + { + D.write(); + } +} + + +// ************************************************************************* // diff --git a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/ParticleDose/ParticleDose.H b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/ParticleDose/ParticleDose.H new file mode 100644 index 0000000000000000000000000000000000000000..b4bdef6695ed2cbd077b6630a945c8d238d6fb28 --- /dev/null +++ b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/ParticleDose/ParticleDose.H @@ -0,0 +1,161 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2022 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::ParticleDose + +Group + grpLagrangianIntermediateFunctionObjects + +Description + Calculate the doses absorbed by a particle as the time integral + of the particle track along the radiation field G [w/m2]. + + Operands: + \table + Operand | Type | Location + input | - | - + output file | - | - + output field | scalarField | \<time\>/lagrangian/\<cloud\>/D + \endtable + +Usage + Minimal example by using \c constant/\<CloudProperties\>: + \verbatim + cloudFunctions + { + ParticleDose1 + { + // Mandatory entries + type ParticleDose; + GName G; + } + } + \endverbatim + + where the entries mean: + \table + Property | Description | Type | Reqd | Deflt + type | Type name: ParticleDose | word | yes | - + GName | Name of the radiation field | word | yes | - + \endtable + +SourceFiles + ParticleDose.C + +\*---------------------------------------------------------------------------*/ + +#ifndef Foam_ParticleDose_H +#define Foam_ParticleDose_H + +#include "CloudFunctionObject.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class ParticleDose Declaration +\*---------------------------------------------------------------------------*/ + +template<class CloudType> +class ParticleDose +: + public CloudFunctionObject<CloudType> +{ + // Private Data + + // Typedefs + + //- Convenience typedef for parcel type + typedef typename CloudType::parcelType parcelType; + + + //- Incident radiation field name + word GName_; + + +public: + + //- Runtime type information + TypeName("particleDose"); + + + // Generated Methods + + //- No copy assignment + void operator=(const ParticleDose<CloudType>&) = delete; + + + // Constructors + + //- Construct from dictionary + ParticleDose + ( + const dictionary& dict, + CloudType& owner, + const word& modelName + ); + + //- Copy construct + ParticleDose(const ParticleDose<CloudType>& vf); + + //- Construct and return a clone + virtual autoPtr<CloudFunctionObject<CloudType>> clone() const + { + return autoPtr<CloudFunctionObject<CloudType>> + ( + new ParticleDose<CloudType>(*this) + ); + } + + + //- Destructor + virtual ~ParticleDose() = default; + + + // Member Functions + + //- Post-evolve hook + virtual void postEvolve(const typename parcelType::trackingData& td); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository + #include "ParticleDose.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/thermophysicalModels/radiation/derivedFvPatchFields/greyDiffusiveRadiation/greyDiffusiveRadiationMixedFvPatchScalarField.C b/src/thermophysicalModels/radiation/derivedFvPatchFields/greyDiffusiveRadiation/greyDiffusiveRadiationMixedFvPatchScalarField.C index e658fd2fc4e97ac667535ced9dfa7f6032048abd..f0347d078ae7d4ce1aa52bcc5b626d8ad52e0357 100644 --- a/src/thermophysicalModels/radiation/derivedFvPatchFields/greyDiffusiveRadiation/greyDiffusiveRadiationMixedFvPatchScalarField.C +++ b/src/thermophysicalModels/radiation/derivedFvPatchFields/greyDiffusiveRadiation/greyDiffusiveRadiationMixedFvPatchScalarField.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2018 OpenFOAM Foundation - Copyright (C) 2016-2020 OpenCFD Ltd. + Copyright (C) 2016-2022 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -49,7 +49,9 @@ greyDiffusiveRadiationMixedFvPatchScalarField ) : mixedFvPatchScalarField(p, iF), - TName_("T") + TName_("T"), + qRadExt_(0), + qRadExtDir_(Zero) { refValue() = 0.0; refGrad() = 0.0; @@ -67,7 +69,9 @@ greyDiffusiveRadiationMixedFvPatchScalarField ) : mixedFvPatchScalarField(ptf, p, iF, mapper), - TName_(ptf.TName_) + TName_(ptf.TName_), + qRadExt_(ptf.qRadExt_), + qRadExtDir_(ptf.qRadExtDir_) {} @@ -80,7 +84,9 @@ greyDiffusiveRadiationMixedFvPatchScalarField ) : mixedFvPatchScalarField(p, iF), - TName_(dict.getOrDefault<word>("T", "T")) + TName_(dict.getOrDefault<word>("T", "T")), + qRadExt_(dict.getOrDefault<scalar>("qRadExt", 0)), + qRadExtDir_(dict.getOrDefault<vector>("qRadExtDir", Zero)) { if (dict.found("refValue")) { @@ -100,7 +106,6 @@ greyDiffusiveRadiationMixedFvPatchScalarField fvPatchScalarField::operator=(refValue()); } - } @@ -111,7 +116,9 @@ greyDiffusiveRadiationMixedFvPatchScalarField ) : mixedFvPatchScalarField(ptf), - TName_(ptf.TName_) + TName_(ptf.TName_), + qRadExt_(ptf.qRadExt_), + qRadExtDir_(ptf.qRadExtDir_) {} @@ -123,7 +130,9 @@ greyDiffusiveRadiationMixedFvPatchScalarField ) : mixedFvPatchScalarField(ptf, iF), - TName_(ptf.TName_) + TName_(ptf.TName_), + qRadExt_(ptf.qRadExt_), + qRadExtDir_(ptf.qRadExtDir_) {} @@ -264,6 +273,64 @@ updateCoeffs() } } + scalarField Isource(this->size(), 0.0); + + if (qRadExt_ > 0) + { + if (mag(qRadExtDir_) > 0) + { + label rayqoId = -1; + scalar maxRay = -GREAT; + + // Looking for the ray closest to the Sun direction + for (label rayI = 0; rayI < dom.nRay(); ++rayI) + { + const vector& iD = dom.IRay(rayI).d(); + const scalar dir = qRadExtDir_ & iD; + + if (dir > maxRay) + { + maxRay = dir; + rayqoId = rayI; + } + } + + if (rayId == rayqoId) + { + forAll(Isource, faceI) + { + Isource[faceI] += qRadExt_/mag(dom.IRay(rayId).dAve()); + } + } + } + else + { + forAll(Iw, faceI) + { + label rayqoId = -1; + scalar maxRay = -GREAT; + + // Looking for the ray closest to the Sun direction + for (label rayI = 0; rayI < dom.nRay(); ++rayI) + { + const vector& iD = dom.IRay(rayI).d(); + const scalar dir = -n[faceI] & iD; + + if (dir > maxRay) + { + maxRay = dir; + rayqoId = rayI; + } + } + + if (rayId == rayqoId) + { + Isource[faceI] += qRadExt_/mag(dom.IRay(rayId).dAve()); + } + } + } + } + forAll(Iw, faceI) { if ((-n[faceI] & myRayId) > 0.0) @@ -272,7 +339,8 @@ updateCoeffs() refGrad()[faceI] = 0.0; valueFraction()[faceI] = 1.0; refValue()[faceI] = - Iexternal[faceI]*transmissivity[faceI] + Isource[faceI] + + Iexternal[faceI]*transmissivity[faceI] + ( Ir[faceI]*(scalar(1) - emissivity[faceI]) + emissivity[faceI]*physicoChemical::sigma.value() @@ -308,6 +376,8 @@ void Foam::radiation::greyDiffusiveRadiationMixedFvPatchScalarField::write { mixedFvPatchScalarField::write(os); os.writeEntryIfDifferent<word>("T", "T", TName_); + os.writeEntryIfDifferent<scalar>("qRadExt", Zero, qRadExt_); + os.writeEntryIfDifferent<vector>("qRadExtDir", Zero, qRadExtDir_); } diff --git a/src/thermophysicalModels/radiation/derivedFvPatchFields/greyDiffusiveRadiation/greyDiffusiveRadiationMixedFvPatchScalarField.H b/src/thermophysicalModels/radiation/derivedFvPatchFields/greyDiffusiveRadiation/greyDiffusiveRadiationMixedFvPatchScalarField.H index fb3843227c96d44f86d6d16c4c5d8c76e6b90df6..bab87648027691463a47c5649e3b74d4d6257a7a 100644 --- a/src/thermophysicalModels/radiation/derivedFvPatchFields/greyDiffusiveRadiation/greyDiffusiveRadiationMixedFvPatchScalarField.H +++ b/src/thermophysicalModels/radiation/derivedFvPatchFields/greyDiffusiveRadiation/greyDiffusiveRadiationMixedFvPatchScalarField.H @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation + Copyright (C) 2016-2022 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -35,35 +36,53 @@ Description (fvDOM), in which the radiation temperature is retrieved from the temperature field boundary condition. -Usage - \table - Property | Description | Required | Default value - T | temperature field name | no | T - \endtable + An external radiative heat flux can be added using \c qRadExt. If + \c qRadExtDir is specified, this ray closest to this direction is used. + Otherwise, the face normal is used as direction to set \c qRadExt. +Usage Example of the boundary condition specification: \verbatim <patchName> { + // Mandatory entries type greyDiffusiveRadiation; + + // Optional entries T T; - value uniform 0; + qRadExt <scalar>; + qRadExtDir <vector>; + + // Inherited entries + ... } \endverbatim + where the entries mean: + \table + Property | Description | Type | Reqd | Deflt + type | Type name: greyDiffusiveRadiation | word | yes | - + T | Name of temperature field | word | no | T + qRadExt | Radiative external flux | scalar | no | Zero + qRadExtDir | Radiative external flux direction | vector | no | Zero + \endtable + + The inherited entries are elaborated in: + - \link mixedFvPatchFields.H \endlink + See also - Foam::radiation::radiationModel - Foam::radiation::fvDOM - Foam::radiationCoupledBase - Foam::mixedFvPatchField + - Foam::radiation::radiationModel + - Foam::radiation::fvDOM + - Foam::radiationCoupledBase + - Foam::mixedFvPatchField SourceFiles greyDiffusiveRadiationMixedFvPatchScalarField.C \*---------------------------------------------------------------------------*/ -#ifndef greyDiffusiveRadiationMixedFvPatchScalarField_H -#define greyDiffusiveRadiationMixedFvPatchScalarField_H +#ifndef radiation_greyDiffusiveRadiationMixedFvPatchScalarField_H +#define radiation_greyDiffusiveRadiationMixedFvPatchScalarField_H #include "mixedFvPatchFields.H" @@ -81,11 +100,18 @@ class greyDiffusiveRadiationMixedFvPatchScalarField : public mixedFvPatchScalarField { - // Private data + // Private Data //- Name of temperature field word TName_; + //- External radiative flux + scalar qRadExt_; + + //- External radiative flux direction + vector qRadExtDir_; + + public: //- Runtime type information @@ -110,7 +136,7 @@ public: ); //- Construct by mapping given a - // greyDiffusiveRadiationMixedFvPatchScalarField onto a new patch + //- greyDiffusiveRadiationMixedFvPatchScalarField onto a new patch greyDiffusiveRadiationMixedFvPatchScalarField ( const greyDiffusiveRadiationMixedFvPatchScalarField&, @@ -154,25 +180,25 @@ public: } - // Member functions + // Member Functions // Access //- Return the temperature field name - const word& TName() const + const word& TName() const noexcept { return TName_; } //- Return reference to the temperature field name to allow - // adjustment - word& TName() + //- adjustment + word& TName() noexcept { return TName_; } - // Evaluation functions + // Evaluation //- Update the coefficients associated with the patch field virtual void updateCoeffs(); diff --git a/tutorials/lagrangian/coalChemistryFoam/simplifiedSiwek/Allrun-parallel b/tutorials/lagrangian/coalChemistryFoam/simplifiedSiwek/Allrun-parallel index f5c23158ba456efc3e518154b3404102f1ed91e2..e7ef6d145fe60e561f3c1df037935ae484be5178 100755 --- a/tutorials/lagrangian/coalChemistryFoam/simplifiedSiwek/Allrun-parallel +++ b/tutorials/lagrangian/coalChemistryFoam/simplifiedSiwek/Allrun-parallel @@ -14,4 +14,6 @@ runApplication decomposePar runParallel $(getApplication) +runApplication reconstructPar -latestTime + #------------------------------------------------------------------------------ diff --git a/tutorials/lagrangian/coalChemistryFoam/simplifiedSiwek/constant/limestoneCloud1Properties b/tutorials/lagrangian/coalChemistryFoam/simplifiedSiwek/constant/limestoneCloud1Properties index 6108d91d09727918130c92c874058167ecc9e65b..b45f527d68fb24c385536b2c162132c094087703 100644 --- a/tutorials/lagrangian/coalChemistryFoam/simplifiedSiwek/constant/limestoneCloud1Properties +++ b/tutorials/lagrangian/coalChemistryFoam/simplifiedSiwek/constant/limestoneCloud1Properties @@ -121,7 +121,13 @@ subModels cloudFunctions -{} +{ + particleDose1 + { + type particleDose; + GName G; + } +} // ************************************************************************* //