View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0002722 | OpenFOAM | Feature | public | 2017-10-12 11:29 | 2017-11-29 11:16 |
Reporter | atulkjoy | Assigned To | henry | ||
Priority | normal | Severity | minor | Reproducibility | always |
Status | resolved | Resolution | fixed | ||
Platform | Centos | OS | Centos 7.0 | OS Version | Centos 7.0 |
Product Version | dev | ||||
Summary | 0002722: Wall Heat Flux function object | ||||
Description | /OpenFOAM-dev/src/functionObjects/field/wallHeatFlux/wallHeatFlux.C Total heat flux should be cumulative of convective heat flux and radiative heat flux at boundary. At wall boundary lower temperature then next adjacent cell due to gradient or snGrad convectibe heat flux will be negative. wallHeatFluxBf[patchi] = heatFluxBf[patchi]; // ln 78 Col 45 This results in substracation not addition wallHeatFluxBf[patchi] += radHeatFluxBf[patchi]; // Ln 90 col 61 | ||||
Steps To Reproduce | wallHeatFluxBf[patchi] = -heatFluxBf[patchi]; //sign has been changed to make it +ve due to which or better make it +ve always if it is negative to see the effect | ||||
Tags | functionObject | ||||
|
wallHeatFlux.C (9,839 bytes)
/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2016 OpenFOAM Foundation \\/ M anipulation | Copyright (C) 2016 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 "wallHeatFlux.H" #include "surfaceInterpolate.H" #include "fvcSnGrad.H" #include "wallPolyPatch.H" #include "turbulentFluidThermoModel.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // namespace Foam { namespace functionObjects { defineTypeNameAndDebug(wallHeatFlux, 0); addToRunTimeSelectionTable(functionObject, wallHeatFlux, dictionary); } ///////////////////////////////// START //////////////////////////////////////////////////////////// /////////////////////////////////// END ////////////////////////////////////////////////////////// } // * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * // void Foam::functionObjects::wallHeatFlux::writeFileHeader(Ostream& os) const { // Add headers to output data writeHeader(os, "Wall heat-flux"); writeCommented(os, "Time"); writeTabbed(os, "patch"); writeTabbed(os, "min"); writeTabbed(os, "max"); writeTabbed(os, "integral"); os << endl; } ///////////////////////////////// START /////////////////////////////////////////////////////////////// ///////////////////////////////// END //////////////////////////////////////////////////////////////// void Foam::functionObjects::wallHeatFlux::calcHeatFlux ( const volScalarField& alpha, const volScalarField& he, volScalarField& wallHeatFlux ) { surfaceScalarField heatFlux(fvc::interpolate(alpha)*fvc::snGrad(he)); volScalarField::Boundary& wallHeatFluxBf = wallHeatFlux.boundaryFieldRef(); const surfaceScalarField::Boundary& heatFluxBf = heatFlux.boundaryField(); forAll(wallHeatFluxBf, patchi) { wallHeatFluxBf[patchi] = -heatFluxBf[patchi]; ///Edited by atul from +ve to -ve // Info<<" wallHeatFlux "<<heatFluxBf[patchi]<<" for "<<mesh_.boundaryMesh()[patchi].name()<<endl; } if (foundObject<volScalarField>("Qr")) { Info<<" Yes Radiation Qr found ::"<<endl; const volScalarField& Qr = lookupObject<volScalarField>("Qr"); const volScalarField::Boundary& radHeatFluxBf = Qr.boundaryField(); forAll(wallHeatFluxBf, patchi) { wallHeatFluxBf[patchi] += radHeatFluxBf[patchi]; // Info<<" Radiation HeatFlux "<<radHeatFluxBf[patchi]<<" for "<<mesh_.boundaryMesh()[patchi].name()<<endl; } } } ///////////////////////////////////////////// START //////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////// END //////////////////////////////////////////////////////////////////////////////////// // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::functionObjects::wallHeatFlux::wallHeatFlux ( const word& name, const Time& runTime, const dictionary& dict ) : fvMeshFunctionObject(name, runTime, dict), writeFile(obr_, name, typeName, dict), patchSet_() { volScalarField* wallHeatFluxPtr ( new volScalarField ( IOobject ( type(), mesh_.time().timeName(), mesh_, IOobject::NO_READ, IOobject::NO_WRITE ), mesh_, dimensionedScalar("0", dimMass/pow3(dimTime), 0) ) ); mesh_.objectRegistry::store(wallHeatFluxPtr); read(dict); writeFileHeader(file()); } //////////////////////////////// START //////////////////////////////////////////////////// ////////////////////////////////////// END /////////////////////////////////////////////////// // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // Foam::functionObjects::wallHeatFlux::~wallHeatFlux() {} /////////////////////////////// START ///////////////////////////////////////////// ///////////////////////////////// END /////////////////////////////////////////// // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // bool Foam::functionObjects::wallHeatFlux::read(const dictionary& dict) { fvMeshFunctionObject::read(dict); writeFile::read(dict); const polyBoundaryMesh& pbm = mesh_.boundaryMesh(); patchSet_ = mesh_.boundaryMesh().patchSet ( wordReList(dict.lookupOrDefault("patches", wordReList())) ); Info<< type() << " " << name() << ":" << nl; if (patchSet_.empty()) { forAll(pbm, patchi) { if (isA<wallPolyPatch>(pbm[patchi])) { patchSet_.insert(patchi); } } Info<< " processing all wall patches" << nl << endl; } else { Info<< " processing wall patches: " << nl; labelHashSet filteredPatchSet; forAllConstIter(labelHashSet, patchSet_, iter) { label patchi = iter.key(); if (isA<wallPolyPatch>(pbm[patchi])) { filteredPatchSet.insert(patchi); Info<< " " << pbm[patchi].name() << endl; } else { WarningInFunction << "Requested wall heat-flux on non-wall boundary " << "type patch: " << pbm[patchi].name() << endl; } } Info<< endl; patchSet_ = filteredPatchSet; } return true; } ////////////////////////////////////////// START ////////////////////////////////////////////////////////////////// //////////////////////////////////////////////// END //////////////////////////////////////////////////////////////// bool Foam::functionObjects::wallHeatFlux::execute() { volScalarField& wallHeatFlux = const_cast<volScalarField&> ( lookupObject<volScalarField>(type()) ); if ( foundObject<compressible::turbulenceModel> ( turbulenceModel::propertiesName ) ) { const compressible::turbulenceModel& turbModel = lookupObject<compressible::turbulenceModel> ( turbulenceModel::propertiesName ); calcHeatFlux ( turbModel.alphaEff()(), turbModel.transport().he(), wallHeatFlux ); } else if (foundObject<fluidThermo>(fluidThermo::dictName)) { const fluidThermo& thermo = lookupObject<fluidThermo>(fluidThermo::dictName); calcHeatFlux ( thermo.alpha(), thermo.he(), wallHeatFlux ); } else { FatalErrorInFunction << "Unable to find compressible turbulence model in the " << "database" << exit(FatalError); } return true; } //////////////////////////////////////// START ////////////////////////////////////////////////////////////////////// ///////////////////////////////////////// END //////////////////////////////////////////////////////////////////////// bool Foam::functionObjects::wallHeatFlux::write() { const volScalarField& wallHeatFlux = lookupObject<volScalarField>(type()); Log << type() << " " << name() << " write:" << nl << " writing field " << wallHeatFlux.name() << endl; wallHeatFlux.write(); const fvPatchList& patches = mesh_.boundary(); const surfaceScalarField::Boundary& magSf = mesh_.magSf().boundaryField(); forAllConstIter(labelHashSet, patchSet_, iter) { label patchi = iter.key(); const fvPatch& pp = patches[patchi]; const scalarField& hfp = wallHeatFlux.boundaryField()[patchi]; const scalar minHfp = gMin(hfp); const scalar maxHfp = gMax(hfp); const scalar integralHfp = gSum(magSf[patchi]*hfp); if (Pstream::master()) { writeTime(file()); file() << token::TAB << pp.name() << token::TAB << minHfp << token::TAB << maxHfp << token::TAB << integralHfp << endl; } Log << " min/max(" << pp.name() << ") = " << minHfp << ", " << maxHfp << ", " << integralHfp << endl; } return true; } /////////////////////////////////////////////// START /////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // ************************************************************************* // |
|
Can you provide a simple case or is there a tutorial case which demonstrates the need for this change? |
|
I don't quite understand what you are getting at. The heat flux can be negative. This is not an error. The sign tells you if the heat is flowing into the domain or if it is leaving it. For CHT one side is always negative and the other positive. |
|
@atulkjoy: Please provide more details for this bug report, as requested on the rules page: https://bugs.openfoam.org/rules.php I know that you asked about this on this thread: https://www.cfd-online.com/Forums/openfoam-post-processing/192658-wall-heat-flux-utulity.html But in this report here, please also provide the evidences of what you initially discovered and how you reached the conclusion regarding what should be the correct sign. I know that you provided the plots and results on that thread, but it's not accessible to the public unless people log in there, so please post the images here as well. ---- @Henry and @StephanG: Just in case atulkjoy doesn't answer in the meantime, here is a partial quote of what I wrote regarding this topic on that thread: In OpenFOAM 4.x and older, the calculation is done as: convective_term - radiative_term While in OpenFOAM 5.x and newer, the calculation is done as: convective_term + radiative_term I haven't managed to figure out which one is correct, because I haven't managed to figure out what is the sign convention for Qr and for the convective heat flux. At a first glance, it seemed like Qr was always positive ("q = Boltzman * T^4 * Area"), which doesn't make much sense in this context, since it should be a subtraction of the two or more temperature[/radiation] sources, imposed on the wall. |
|
I have some more details on this topic, but I haven't had the time to sort through them yet and confirm what is correct. But here goes the information I've gathered so far: 1. The change in the sign for this calculation has already occurred in the past. Start reading from the following Juho's comment here: https://bugs.openfoam.org/view.php?id=1856#c5713 - in report #1856. - In a nutshell, see the bug fix in this commit: https://github.com/OpenFOAM/OpenFOAM-dev/commit/5749c95ed68e40c11ea586549fb667553d218f1f 2. A recent optimization that was implemented into this 'wallHeatFlux' function object - see Issue #2725: https://bugs.openfoam.org/view.php?id=2725 - has lead to not allowing the calculation of said wall heat flux on coupled patches, which is the test that was indications by Juho in the aforementioned issue #1856, and I quote: > Steps to reproduce: > 1. Run the chtMultiRegionSimpleFoam multiRegionHeaterRadiation tutorial to convergence > 2. Check the heat balance between the regions with the wallHeatFlux utility Therefore, once it's possible to run the function object with the tutorial case "chtMultiRegionSimpleFoam/multiRegionHeaterRadiation", it's possible to assess if the radiation term is meant to be added or subtracted. |
|
@wyldckat It is not clear to me how the changes for #2725 affect this, could you clarify? |
|
@Henry: I don't have an updated build of OpenFOAM-dev at hand right now, but when the tutorial case "chtMultiRegionSimpleFoam/multiRegionHeaterRadiation" is run with the function object 'wallHeatFlux', I get an error message about 'snGrad' not being implemented for coupled patches. Therefore, I was not able to do the same test that Juho did for the last fix in #1856, i.e. to verify which sign should be used when accounting the radiation term into the 'wallHeatFlux'. My apologies for not opening another report for the 'snGrad' issue sooner, but I was planning on opening it only when I had all of the pieces and patch... but a couple of weeks passed by since then, so it seemed best to at least provide what I already knew about this current report and associated information. |
|
@wyldckat: Thanks for the clarification, I will investigate. |
|
Just to comment, the sign convention of qr is such that it is the net amount of radiation absorbed by the wall -> positive qr indicates that energy is flowing into the wall and out of the domain. This means that qr behaves opposite to wallHeatFluxBf which is negative if the flux is out of the domain. This was the reason why the sign was changed previously. Easiest fix would be changing += to -= in line 91 in wallHeatFlux.C. |
|
@wyldckat: I am not able to reproduce the problem, I have added functions { #includeFunc wallHeatFlux(region=heater) } to the controlDict and the case runs fine and generates heat flux data for the patch. Could you provide more details for how to reproduce the problem? |
|
@Henry: If it's working fine for you, then please move onward. I will open a new bug report if I'm able to reproduce the issue I had with snGrad+coupled boundaries. In the meantime, tniemi's answer seems to clarify the need for the original bug report. |
|
Thanks Timo Resolved in OpenFOAM-5.x by commit a268af97208e55ed1d4f1ebff4d95a9faf64ef9c Resolved in OpenFOAM-dev by commit 396259f105b2542912c35b29c4d8b96df5d3a77c |
Date Modified | Username | Field | Change |
---|---|---|---|
2017-10-12 11:29 | atulkjoy | New Issue | |
2017-10-12 11:29 | atulkjoy | File Added: wallHeatFlux.C | |
2017-10-12 11:29 | atulkjoy | Tag Attached: functionObject | |
2017-10-12 15:45 | henry | Note Added: 0008863 | |
2017-10-13 09:21 | StephanG | Note Added: 0008864 | |
2017-10-15 10:22 | wyldckat | Note Added: 0008874 | |
2017-11-28 23:06 | wyldckat | Note Added: 0009093 | |
2017-11-28 23:38 | henry | Note Added: 0009095 | |
2017-11-29 08:54 | wyldckat | Note Added: 0009098 | |
2017-11-29 09:09 | henry | Note Added: 0009100 | |
2017-11-29 10:37 | tniemi | Note Added: 0009101 | |
2017-11-29 10:42 | henry | Note Added: 0009102 | |
2017-11-29 10:58 | wyldckat | Note Added: 0009103 | |
2017-11-29 11:16 | henry | Assigned To | => henry |
2017-11-29 11:16 | henry | Status | new => resolved |
2017-11-29 11:16 | henry | Resolution | open => fixed |
2017-11-29 11:16 | henry | Fixed in Version | => 5.x |
2017-11-29 11:16 | henry | Note Added: 0009104 |