|
[Sponsors] |
February 13, 2020, 08:17 |
Uprime2Mean and R (LES)
|
#1 |
Member
Conor Crickmore
Join Date: Jan 2020
Location: Leicestershire, United Kingdom
Posts: 36
Rep Power: 6 |
Hey everyone,
To repeat how 90% of posts here go, I'm relatively new to OpenFOAM, and I am having an issue processing the Reynolds Stress Tensor for my SA-based DES case. My understanding is that 'Uprime2Mean' provides the Reynolds Stress Tensor of the resolved flow, while 'R' provides the sub-grid (modelled) tensor. With these two values it should be possible to produce a field that displays the percentage of resolved TKE as a method of mesh validation. I'm seeking some guidance on how to either obtain an average of 'R' to use with 'Uprime2Mean' obtained through the fieldAverage function or an instantaneous value of 'Uprime2Mean' to use with 'R' obtained through the eponymous Post-Processing function. I half expect that this is a horribly inefficient method of obtaining the desired data, and any other suggestions would be equally welcome! Thanks,
__________________
Conor Crickmore PhD Researcher in Automotive Aerodynamics Aeronautical and Automotive Engineering Loughborough University LE11 3TU |
|
February 13, 2020, 12:13 |
|
#2 | |
Member
Conor Crickmore
Join Date: Jan 2020
Location: Leicestershire, United Kingdom
Posts: 36
Rep Power: 6 |
Quote:
I'm now hoping to produce the field: Code:
(1/2*tr(Uprime2Mean))/(1/2*tr(R + Uprime2Mean)) Any guidance would be appreciated,
__________________
Conor Crickmore PhD Researcher in Automotive Aerodynamics Aeronautical and Automotive Engineering Loughborough University LE11 3TU |
||
February 13, 2020, 17:36 |
|
#3 |
Senior Member
Herpes Free Engineer
Join Date: Sep 2019
Location: The Home Under The Ground with the Lost Boys
Posts: 931
Rep Power: 13 |
Might misunderstand you, but here we go: your understanding on these objects is correct.
You can obtain 'RMean' by the same FO 'fieldAverage', and use it with 'UPrime2Mean' at the end of a sim?
__________________
The OpenFOAM community is the biggest contributor to OpenFOAM: User guide/Wiki-1/Wiki-2/Code guide/Code Wiki/Journal Nilsson/Guerrero/Holzinger/Holzmann/Nagy/Santos/Nozaki/Jasak/Primer Governance Bugs/Features: OpenFOAM (ESI-OpenCFD-Trademark) Bugs/Features: FOAM-Extend (Wikki-FSB) Bugs: OpenFOAM.org How to create a MWE New: Forkable OpenFOAM mirror |
|
February 14, 2020, 05:59 |
|
#4 | |
Member
Conor Crickmore
Join Date: Jan 2020
Location: Leicestershire, United Kingdom
Posts: 36
Rep Power: 6 |
Quote:
Thanks for your reply! I actually made a bit of progress last night, but my post got caught by the new user moderator checks so didn't come through until after your response. If you read that post you'll see I am now trying to form a new field, produced from: Code:
(1/2*tr(Uprime2Mean))/(1/2*tr(RMean + Uprime2Mean))
__________________
Conor Crickmore PhD Researcher in Automotive Aerodynamics Aeronautical and Automotive Engineering Loughborough University LE11 3TU |
||
February 14, 2020, 16:22 |
|
#5 |
Senior Member
Herpes Free Engineer
Join Date: Sep 2019
Location: The Home Under The Ground with the Lost Boys
Posts: 931
Rep Power: 13 |
codedFunctionObjects can do it easily. Have a go for a review, and see by urself. I can provide an example after sitting in front of a PC unless you or other helpmates do earlier.
__________________
The OpenFOAM community is the biggest contributor to OpenFOAM: User guide/Wiki-1/Wiki-2/Code guide/Code Wiki/Journal Nilsson/Guerrero/Holzinger/Holzmann/Nagy/Santos/Nozaki/Jasak/Primer Governance Bugs/Features: OpenFOAM (ESI-OpenCFD-Trademark) Bugs/Features: FOAM-Extend (Wikki-FSB) Bugs: OpenFOAM.org How to create a MWE New: Forkable OpenFOAM mirror |
|
February 17, 2020, 06:03 |
|
#6 | |
Member
Conor Crickmore
Join Date: Jan 2020
Location: Leicestershire, United Kingdom
Posts: 36
Rep Power: 6 |
Quote:
Thanks once more for your help. I've had a look into codedFunctionObjects. I was able to get a basic function to work (simply reading and printing out a field value) but I'm hitting some errors when I try to include the functionality to calculate the ratio I need. Unfortunately, my current lack of experience with C++ means most of the errors are beyond my understanding. Code:
resolvedTKE { type coded; libs ("libutilityFunctionObjects.so"); name resolvedTKE; executeControl timeStep executeInterval 1; writeControl writeTime; // timeStart 0.5; // timeEnd 1; enabled false; codeOptions #{ -I$(LIB_SRC)/meshTools/lnInclude #}; codeExecute #{ const volSymmTensorField& RMean = mesh().lookupObject<volSymmTensorField>("RMean"); const volSymmTensorField& UPrime2Mean = mesh().lookupObject<volSymmTensorField>("UPrime2Mean"); Info << "Min RMean = " << min(RMean) << endl; Info << "Min UPrime2Mean = " << min(UPrime2Mean) << endl; // volScalarField resolvedTKE // ( // IOobject // ( // "resolvedTKE", // runTime.timeName(), // mesh, // IOobject::NO_READ, // IOobject::AUTO_WRITE // ), // mesh, // dimensionedScalar(dimless, 0) // ); // // resolvedTKE = ((1.0 / 2.0) * tr(UPrime2Mean)) / ((1.0 / 2.0) * tr(RMean + UPrime2Mean)); // resolvedTKE.write(); #}; } I'd again appreciate any advice you can provide!
__________________
Conor Crickmore PhD Researcher in Automotive Aerodynamics Aeronautical and Automotive Engineering Loughborough University LE11 3TU |
||
February 17, 2020, 09:38 |
|
#7 |
Member
Conor Crickmore
Join Date: Jan 2020
Location: Leicestershire, United Kingdom
Posts: 36
Rep Power: 6 |
The following code appears to mostly work:
Code:
resolvedTKE { type coded; libs ("libutilityFunctionObjects.so"); name resolvedTKE; writeControl runTime; writeInterval 0.005; // timeStart 0.5; // timeEnd 1; enabled true; codeExecute #{ const volSymmTensorField& RMean = mesh().lookupObject<volSymmTensorField>("RMean"); const volSymmTensorField& UPrime2Mean = mesh().lookupObject<volSymmTensorField>("UPrime2Mean"); volScalarField resolvedTKE ( IOobject ( "resolvedTKE", mesh().time().timeName(), mesh(), IOobject::NO_READ, IOobject::AUTO_WRITE ), mesh(), dimensionedScalar(dimless, 0) ); resolvedTKE = ((1.0 / 2.0) * tr(UPrime2Mean)) / ((1.0 / 2.0) * tr(RMean + UPrime2Mean)); resolvedTKE.write(); #}; } Due to this being a 'time' related problem, I'm assuming the issue is a result of one of (or a combination of) these lines: Code:
mesh().time().timeName(), IOobject::AUTO_WRITE resolvedTKE.write();
__________________
Conor Crickmore PhD Researcher in Automotive Aerodynamics Aeronautical and Automotive Engineering Loughborough University LE11 3TU |
|
February 17, 2020, 13:18 |
|
#8 |
Senior Member
Herpes Free Engineer
Join Date: Sep 2019
Location: The Home Under The Ground with the Lost Boys
Posts: 931
Rep Power: 13 |
I haven't compiled it below, because I don't have a test-case, might need to add a `codeOptions`.
Let me know if it would be any help. I'm not sure since I'm bloody getting old. :] Code:
resolvedTKE { functionObjectLibs (utilityFunctionObjects); type coded; name resolvedTKE; writeControl writeTime; codeExecute #{ static autoPtr<volScalarField> tkeRatio; if ( mesh().time().timeIndex() == 1 || mesh().time().startTimeIndex() == mesh().time().timeIndex() - 1 ) { Info<< " # First time-step or restart:" << nl; tkeRatio.set ( new volScalarField ( IOobject ( "tkeRatio", mesh().time().timeName(), mesh(), IOobject::NO_READ, IOobject::AUTO_WRITE ), mesh(), dimless ) ); } if (mesh().time().timeIndex() != 1) { const volSymmTensorField& RMean = mesh().lookupObjectRef<volSymmTensorField>("RMean"); const volSymmTensorField& UPrime2Mean = mesh().lookupObjectRef<volSymmTensorField>("UPrime2Mean"); volScalarField& tkeRatio = mesh().lookupObjectRef<volScalarField>("tkeRatio"); Info << "Min RMean = " << min(RMean) << endl; Info << "Min UPrime2Mean = " << min(UPrime2Mean) << endl; tkeRatio = (0.5*tr(UPrime2Mean))/(0.5*tr(RMean + UPrime2Mean) + SMALL); if (mesh().time().outputTime()) { Info<< " ### Writing out tkeRatio field" << nl << nl; tkeRatio.write(); } } #}; } FYI: You need to have `RMean` and `UPrime2Mean` beforehand this FO, e.g. by using `fieldAverage`.
__________________
The OpenFOAM community is the biggest contributor to OpenFOAM: User guide/Wiki-1/Wiki-2/Code guide/Code Wiki/Journal Nilsson/Guerrero/Holzinger/Holzmann/Nagy/Santos/Nozaki/Jasak/Primer Governance Bugs/Features: OpenFOAM (ESI-OpenCFD-Trademark) Bugs/Features: FOAM-Extend (Wikki-FSB) Bugs: OpenFOAM.org How to create a MWE New: Forkable OpenFOAM mirror |
|
February 18, 2020, 10:03 |
|
#9 |
Member
Conor Crickmore
Join Date: Jan 2020
Location: Leicestershire, United Kingdom
Posts: 36
Rep Power: 6 |
Hello again HPE,
Thanks again for your help! I've got the function mostly working now thanks to your input, and as a form of practice merged your code with my own as opposed to simply taking your code in its entirety. Hopefully these will be my last questions for you and then you can go onto more important things! Firstly, using: Code:
if ( mesh().time().timeIndex() == 1 || mesh().time().startTimeIndex() == mesh().time().timeIndex() - 1 ) ------------------- Secondly, in your code: Code:
tkeRatio = (0.5 * tr(UPrime2Mean)) / (0.5 * tr(RMean + UPrime2Mean) + SMALL); ------------------- Finally, I'd like the function to only write during a set time interval, such as can be done with the 'fieldAverage' function by denoting 'timeStart' and 'timeEnd' My best guess thus far has been: Code:
if ( mesh().time().writeTime() && mesh().time().value() >= $timeStart ) ------------------- Thanks again for your time, I really am grateful
__________________
Conor Crickmore PhD Researcher in Automotive Aerodynamics Aeronautical and Automotive Engineering Loughborough University LE11 3TU Last edited by cjc96; February 18, 2020 at 11:07. |
|
February 18, 2020, 14:27 |
|
#10 |
Senior Member
Herpes Free Engineer
Join Date: Sep 2019
Location: The Home Under The Ground with the Lost Boys
Posts: 931
Rep Power: 13 |
>> is there a method to have the field initialise in the 0 directory, as opposed to during the first time step? In this case it doesn't actually matter, but could be useful in the future.
OpenFOAM learned `setExprFields`, link, which you can use it to initialise fields like by using swak4Foam. >> I'm failing to see what the '+ SMALL' addition denotes, I'm guessing it is something left over from one of your own functions? Not sure throws error when compiled (because I haven't compiled it), but `SMALL` is an OpenFOAM object which is equal to the smallest floating-point, for my double-precision compilation SMALL=1e-15. SMALL is there in the denominator to avoid zero-division error, which might be annoying if you are not familiar with. >> Finally, I'd like the function to only write during a set time interval, such as can be done with the 'fieldAverage' function by denoting 'timeStart' and 'timeEnd' You can use these keywords in codedFOs as well. But they are not for writing, but execution. Outside of their interval, the FO will not be executed. >> however, the compiler states that 'timeStart' hasn't been properly declared, leading me to presume it is included in another function somewhere (to be added using #include) but I am unsure which one. `timeStart` is not known locally. If you want it, you need to construct it like `const scalar timeStart = 10;` Or you need to turn-on the generic `timeStart` keyword up there somewhere. Otherwise, compiler will not recognise it since C++ statically defined language (your object type must be known there). Hope it helps.
__________________
The OpenFOAM community is the biggest contributor to OpenFOAM: User guide/Wiki-1/Wiki-2/Code guide/Code Wiki/Journal Nilsson/Guerrero/Holzinger/Holzmann/Nagy/Santos/Nozaki/Jasak/Primer Governance Bugs/Features: OpenFOAM (ESI-OpenCFD-Trademark) Bugs/Features: FOAM-Extend (Wikki-FSB) Bugs: OpenFOAM.org How to create a MWE New: Forkable OpenFOAM mirror |
|
February 20, 2020, 06:11 |
|
#11 |
Senior Member
Andrea
Join Date: Feb 2012
Location: Leeds, UK
Posts: 179
Rep Power: 16 |
Hi Conor,
an alternative method could be to hardcode resolved TKE, epsilon and all the other variables you need in a modified version of the solver. I gave it a go here: pimpleTKEBudgetFoam, which also includes a LESResolutionIndex = k_res/(k_modelled + k_res) Andrea |
|
February 26, 2020, 07:08 |
|
#12 | |
Member
Conor Crickmore
Join Date: Jan 2020
Location: Leicestershire, United Kingdom
Posts: 36
Rep Power: 6 |
Quote:
Thanks for replying! Had a look through your repository and while I think I'll stick with the function for the time being, as I think it offers a bit more flexibility in what I am trying to do at the moment, it was very useful and I did pinch a few aspects of your code! One thing I did disagree with however, and this may in actuality just be poor understanding on my part, is your calculation of 'kRes' Code:
volVectorField UPrime = (U - db.lookupObject<volVectorField>("UMean")); volScalarField kRes = 0.5*(UPrime & UPrime); And that you are in fact calculating: Again, forgive me if I have totally misinterpreted either your code, or the underlying maths but I am eager to learn either way!
__________________
Conor Crickmore PhD Researcher in Automotive Aerodynamics Aeronautical and Automotive Engineering Loughborough University LE11 3TU |
||
February 26, 2020, 07:14 |
|
#13 |
Member
Conor Crickmore
Join Date: Jan 2020
Location: Leicestershire, United Kingdom
Posts: 36
Rep Power: 6 |
Also,
I just thought I'd include the function I settled on (for now) for reference, in case someone is working on a similar problem in the future: Code:
LESIndex { type coded; libs ("libutilityFunctionObjects.so"); name LESIndex; executeControl writeTime; writeControl writeTime; // timeStart 0; // timeEnd 0; enabled true; /*---------------------------------------------------------------------------*\ LES Quality Evaluation ** Requires fieldAverage Function to Obtain UPrime2Mean** ** Resolved Reynolds Stress Tensor ** Requires turbulenceFields Function to Obtain R** ** Subgrid Reynolds Stress Tensor \*---------------------------------------------------------------------------*/ codeExecute #{ static autoPtr<volScalarField> LESIndex; if ( mesh().foundObject<volSymmTensorField>("UPrime2Mean") && mesh().foundObject<volSymmTensorField>("R") && mesh().foundObject<volScalarField>("LESIndex") == 0 ) { Info << "LES Quality Index:" << endl; Info << " Initialising" << endl; Info << " Calculating" << nl << endl; LESIndex.set ( new volScalarField ( IOobject ( "LESIndex", mesh().time().timeName(), mesh(), IOobject::NO_READ, IOobject::AUTO_WRITE ), mesh(), dimensionedScalar ( "LESIndex", dimless, 0 ) ) ); const volSymmTensorField& R = mesh().lookupObjectRef<volSymmTensorField>("R"); const volSymmTensorField& UPrime2Mean = mesh().lookupObjectRef<volSymmTensorField>("UPrime2Mean"); volScalarField& LESIndex = mesh().lookupObjectRef<volScalarField>("LESIndex"); LESIndex = (0.5 * tr(UPrime2Mean)) / (0.5 * tr(R + UPrime2Mean)); LESIndex.write(); } else if ( mesh().foundObject<volSymmTensorField>("UPrime2Mean") && mesh().foundObject<volSymmTensorField>("R") && mesh().foundObject<volScalarField>("LESIndex") ) { Info << "LES Quality Index:" << endl; Info << " Calculating" << nl << endl; const volSymmTensorField& R = mesh().lookupObjectRef<volSymmTensorField>("R"); const volSymmTensorField& UPrime2Mean = mesh().lookupObjectRef<volSymmTensorField>("UPrime2Mean"); volScalarField& LESIndex = mesh().lookupObjectRef<volScalarField>("LESIndex"); LESIndex = (0.5 * tr(UPrime2Mean)) / (0.5 * tr(R + UPrime2Mean)); LESIndex.write(); } else { Info << "LES Quality Index:" << endl; Warning << endl << " Unable to Calculate LES Quality Index" << endl << " UPrime2Mean and/or R Unavailable" << endl << " Enable fieldAverage and turbulenceFields Functions" << nl << endl; } #}; }
__________________
Conor Crickmore PhD Researcher in Automotive Aerodynamics Aeronautical and Automotive Engineering Loughborough University LE11 3TU |
|
February 26, 2020, 07:21 |
|
#14 |
Senior Member
Andrea
Join Date: Feb 2012
Location: Leeds, UK
Posts: 179
Rep Power: 16 |
Hi Conor,
in a previous version of the code (see first commit) I had something like: Code:
RRes = symm((UPrime*UPrime)); //Instantaneous resolved Reynolds stress tensor kRes = 0.5*tr(RRes); Code:
volScalarField kRes = 0.5*(UPrime & UPrime); Hope this clarifies it Andrea |
|
February 26, 2020, 08:57 |
|
#15 |
Member
Conor Crickmore
Join Date: Jan 2020
Location: Leicestershire, United Kingdom
Posts: 36
Rep Power: 6 |
Hey Andrea,
Yes, I totally agree that we aren't interested in the entire Reynolds Stress Tensor so may as well simplify the calculation. However, unless I am misinterpreting your code, which as I said at the start of this thread, is entirely possible (I am very much new to this) you are calculating: as opposed to: Again, I do apologise if I am just being a massive idiot =D
__________________
Conor Crickmore PhD Researcher in Automotive Aerodynamics Aeronautical and Automotive Engineering Loughborough University LE11 3TU |
|
February 26, 2020, 09:08 |
|
#16 |
Senior Member
Andrea
Join Date: Feb 2012
Location: Leeds, UK
Posts: 179
Rep Power: 16 |
Lol no need to apologies, I am not 100% sure as well. Actually I believe I was wrong in my previous post to include the overbar in my definition of kRes.
It is true I am calculating the "instantaneous" value of kRes - I figured that I can then obtain the time-averaged kRes by just adding kRes (instantaneous) to the fieldAverage utility, which would output kResMean, i.e. including the overbar. I am not entirely sure if this is mathematically correct, it was leading to reasonable results in a test I did in a simple channel flow though. See snapshot below: https://imgur.com/yM6fNQx |
|
February 27, 2020, 11:03 |
|
#17 | |
New Member
Josh
Join Date: Jun 2013
Posts: 19
Rep Power: 13 |
Quote:
If you forget to do this at runtime, as long as you do have the mean U and nut fields, you can just change the name of UMean to U and nutMean to nut and run the R utility. |
||
April 17, 2020, 13:10 |
|
#18 | |
Senior Member
Arijit Saha
Join Date: Feb 2019
Location: Singapore
Posts: 132
Rep Power: 7 |
Quote:
|
||
April 17, 2020, 13:13 |
|
#19 | |
Member
Conor Crickmore
Join Date: Jan 2020
Location: Leicestershire, United Kingdom
Posts: 36
Rep Power: 6 |
Quote:
The symbol 'tr' denotes the trace of a matrix Hope that helps!
__________________
Conor Crickmore PhD Researcher in Automotive Aerodynamics Aeronautical and Automotive Engineering Loughborough University LE11 3TU |
||
August 25, 2020, 05:50 |
|
#20 | |
New Member
Ran Yi
Join Date: May 2019
Posts: 9
Rep Power: 7 |
Hello Conor,
Thanks for your share. I'm wandering if the "R" in your final coded function denotes the averaged value of R? Or just an instaneous tensor value? Quote:
|
||
Tags |
des les, les, reynolds stress tensor, turbulent kinetic energy |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
LES best practice: resolved and modelled turbulence kinetic energy | em17 | OpenFOAM Running, Solving & CFD | 22 | April 17, 2020 14:01 |
Relation between k and UPrime2Mean etc in LES | Tarak | OpenFOAM Running, Solving & CFD | 49 | August 10, 2018 14:10 |
Worse accuracy in LES models than in RANS models | dferrando | OpenFOAM Running, Solving & CFD | 0 | August 30, 2017 05:56 |
Resolved KE versus SGS KE - LES | smog | OpenFOAM | 0 | February 11, 2016 19:01 |
Bug in Dynamic 1Eq Eddy Viscosity LES Model Incompressible flow | harishg | OpenFOAM Bugs | 5 | December 2, 2008 19:18 |