/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | foam-extend: Open Source CFD \\ / O peration | \\ / A nd | For copyright notice see file Copyright \\/ M anipulation | ------------------------------------------------------------------------------- License This file is part of foam-extend. foam-extend 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. foam-extend 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 foam-extend. If not, see . Author Henrik Rusche, Wikki GmbH. All rights reserved \*---------------------------------------------------------------------------*/ #include "chtRcThermalDiffusivityFvPatchScalarField.H" #include "chtRcThermalDiffusivitySlaveFvPatchScalarField.H" #include "chtRcTemperatureFvPatchScalarField.H" #include "addToRunTimeSelectionTable.H" #include "fvPatchFieldMapper.H" #include "volFields.H" #include "harmonic.H" #include "radiationConstants.H" #include "VectorN.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // chtRcThermalDiffusivityFvPatchScalarField::chtRcThermalDiffusivityFvPatchScalarField ( const fvPatch& p, const DimensionedField& iF ) : chtRegionCoupleBase(p, iF) {} chtRcThermalDiffusivityFvPatchScalarField::chtRcThermalDiffusivityFvPatchScalarField ( const fvPatch& p, const DimensionedField& iF, const dictionary& dict ) : chtRegionCoupleBase(p, iF, dict) {} chtRcThermalDiffusivityFvPatchScalarField::chtRcThermalDiffusivityFvPatchScalarField ( const chtRcThermalDiffusivityFvPatchScalarField& ptf, const fvPatch& p, const DimensionedField& iF, const fvPatchFieldMapper& mapper ) : chtRegionCoupleBase(ptf, p, iF, mapper) {} chtRcThermalDiffusivityFvPatchScalarField::chtRcThermalDiffusivityFvPatchScalarField ( const chtRcThermalDiffusivityFvPatchScalarField& ptf, const DimensionedField& iF ) : chtRegionCoupleBase(ptf, iF) {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void chtRcThermalDiffusivityFvPatchScalarField::evaluate ( const Pstream::commsTypes ) { fvPatchScalarField::evaluate(); } void chtRcThermalDiffusivityFvPatchScalarField::updateCoeffs() { if (updated()) { return; } calcThermalDiffusivity(*this, shadowPatchField()); } void chtRcThermalDiffusivityFvPatchScalarField::calcThermalDiffusivity ( chtRegionCoupleBase& owner, const chtRegionCoupleBase& neighbour ) const { if(debug) { Info << "In chtRcThermalDiffusivityFvPatchScalarField::calcThermalDiffusivity on " << this->dimensionedInternalField().name() << " in " << this->patch().boundaryMesh().mesh().name() << endl; } const fvPatch& p = owner.patch(); const fvMesh& mesh = p.boundaryMesh().mesh(); const magLongDelta& mld = magLongDelta::New(mesh); const chtRcTemperatureFvPatchScalarField& TwOwn = dynamic_cast ( p.lookupPatchField("T") ); scalarField& k = owner; const scalarField& fOwn = owner.originalPatchField(); const scalarField TcOwn = TwOwn.patchInternalField(); scalarField fNei(p.size()); scalarField TcNei(p.size()); scalarField Qr(p.size(), 0.0); scalarField fourQro(p.size(), 0.0); if (TwOwn.radiation()) { Qr += p.lookupPatchField("Qr"); fourQro += 4.0*radiation::sigmaSB.value()*pow4(TwOwn); } { Field > lData ( neighbour.size(), pTraits >::zero ); const scalarField& lfNei = neighbour.originalPatchField(); scalarField lTcNei = TwOwn.shadowPatchField().patchInternalField(); forAll(lData, facei) { lData[facei][0] = lTcNei[facei]; lData[facei][1] = lfNei[facei]; } if(TwOwn.shadowPatchField().radiation()) { const scalarField& lQrNei = owner.lookupShadowPatchField("Qr"); const scalarField& lTwNei = TwOwn.shadowPatchField(); forAll(lData, facei) { lData[facei][2] = lTwNei[facei]; lData[facei][3] = lQrNei[facei]; } } const Field > iData = owner.regionCouplePatch().interpolate(lData); forAll(iData, facei) { TcNei[facei] = iData[facei][0]; fNei[facei] = iData[facei][1]; } if(TwOwn.shadowPatchField().radiation()) { forAll(iData, facei) { Qr[facei] += iData[facei][3]; fourQro[facei] += 4.0*radiation::sigmaSB.value()*pow4(iData[facei][2]); } } } // Do interpolation harmonic interp(mesh); const scalarField weights = interp.weights(fOwn, fNei, p); const scalarField kHarm = weights*fOwn + (1.0 - weights)*fNei; const scalarField kOwn = fOwn/(1.0 - p.weights())/mld.magDelta(p.index()); const scalarField kNei = fNei/p.weights()/mld.magDelta(p.index()); //Info << "kOwn = " << kOwn << endl; //Info << "kNei = " << kNei << endl; //Info << "TcOwn = " << TcOwn << endl; //Info << "TcNei = " << TcNei << endl; //Info << "DeltaT = " << TcNei - TcOwn << endl; //Info << "Qr = " << Qr << endl; //Info << "kOwn + kNei = " << (kOwn + kNei) << endl; //Info << "k = " << k << endl; k = kOwn*(TwOwn*(kNei*(TcNei - TcOwn) + Qr + fourQro) - TcOwn*fourQro); k /= stabilise((fourQro + TwOwn*(kOwn + kNei))*(TcNei - TcOwn), SMALL); k /= p.deltaCoeffs(); //Info << "k = " << k << endl; forAll(k, facei) { k[facei] = max(min(k[facei], 100*kHarm[facei]), 0.01*kHarm[facei]); } //Info << "k = " << k << endl; owner.fvPatchScalarField::updateCoeffs(); } void chtRcThermalDiffusivityFvPatchScalarField::calcTemperature ( chtRcTemperatureFvPatchScalarField& TwOwn, const chtRcTemperatureFvPatchScalarField& neighbour, const chtRegionCoupleBase& ownerK ) const { if(debug) { Info << "In chtRcThermalDiffusivityFvPatchScalarField::calcTemperature on " << this->dimensionedInternalField().name() << " in " << this->patch().boundaryMesh().mesh().name() << endl; } const fvPatch& p = TwOwn.patch(); const fvMesh& mesh = p.boundaryMesh().mesh(); const magLongDelta& mld = magLongDelta::New(mesh); const scalarField& fOwn = ownerK.originalPatchField(); const scalarField TcOwn = TwOwn.patchInternalField(); scalarField fNei(p.size()); scalarField TcNei(p.size()); scalarField Qr(p.size(), 0.0); scalarField fourQro(p.size(), 0.0); if (TwOwn.radiation()) { Qr += p.lookupPatchField("Qr"); fourQro += 4.0*radiation::sigmaSB.value()*pow4(TwOwn); } { Field > lData ( neighbour.size(), pTraits >::zero ); const scalarField& lfNei = ownerK.shadowPatchField().originalPatchField(); scalarField lTcNei = TwOwn.shadowPatchField().patchInternalField(); forAll(lData, facei) { lData[facei][0] = lTcNei[facei]; lData[facei][1] = lfNei[facei]; } if(TwOwn.shadowPatchField().radiation()) { const scalarField& lTwNei = TwOwn.shadowPatchField(); const scalarField& lQrNei = TwOwn.lookupShadowPatchField("Qr"); forAll(lData, facei) { lData[facei][2] = lTwNei[facei]; lData[facei][3] = lQrNei[facei]; } } const Field > iData = TwOwn.regionCouplePatch().interpolate(lData); forAll(iData, facei) { TcNei[facei] = iData[facei][0]; fNei[facei] = iData[facei][1]; } if(TwOwn.shadowPatchField().radiation()) { forAll(iData, facei) { fourQro[facei] += 4.0*radiation::sigmaSB.value()*pow4(iData[facei][2]); Qr[facei] += iData[facei][3]; } } } const scalarField kOwn = fOwn/(1.0 - p.weights())/mld.magDelta(p.index()); const scalarField kNei = fNei/p.weights()/mld.magDelta(p.index()); //Info << "kOwn = " << kOwn << endl; //Info << "kNei = " << kNei << endl; //Info << "TcOwn = " << TcOwn << endl; //Info << "TcNei = " << TcNei << endl; //Info << "Qr = " << Qr << " Sum = " << sum(Qr*p.magSf()) << endl; TwOwn *= (fourQro + Qr + kOwn*TcOwn + kNei*TcNei) /(TwOwn*(kOwn + kNei) + fourQro); //Info << "TwOwn = " << TwOwn << endl; //scalarField q1 = (TwOwn - TcOwn)*kOwn; //Info << "q1 = " << q1 << " Sum = " << sum(q1*p.magSf()) << endl; //scalarField q2 = (TcNei - TcOwn)*ownerK*p.deltaCoeffs(); //Info << "q2 = " << q2 << " Sum = " << sum(q2*p.magSf()) << endl; TwOwn.fvPatchScalarField::updateCoeffs(); } void chtRcThermalDiffusivityFvPatchScalarField::write(Ostream& os) const { fvPatchScalarField::write(os); os.writeKeyword("remoteField") << remoteFieldName() << token::END_STATEMENT << nl; this->writeEntry("value", os); } //- Specify data associated with VectorN type is contiguous template<> inline bool contiguous >() {return true;} // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // makePatchTypeField ( fvPatchScalarField, chtRcThermalDiffusivityFvPatchScalarField ); } // End namespace Foam // ************************************************************************* //