|
[Sponsors] |
May 31, 2020, 10:24 |
integrate multiplication of fields
|
#1 |
New Member
Nikita
Join Date: Oct 2019
Posts: 20
Rep Power: 7 |
Hi foamers,
I'm doing a multhiphase task with 3 phases using multiphaseInterFoam and i want to get volume integral of the some variables and of their multiplication, for example, mass of one phase. in the controlDict file, I want to use a function to calculate the integral for the quantity ( rho*alpha.water) during the whole calculation. I has found this topic - integrate several fields , but in last version OpenFOAM some functions of swak4foam was included in the OpenFOAM. I want use smth like this (code from link above) Code:
functions { makeMagU { type expressionField; functionObjectLibs ( "libswakFunctionObjects.so" ); autowrite false; fieldName magU; expression "mag(U)"; } temp_average { type volumeAverage; functionObjectLibs ( "libsimpleFunctionObjects.so" ); verbose true; fields (magU); } } |
|
June 1, 2020, 13:12 |
Try coded functionObject
|
#2 |
Senior Member
Carlos Rubio Abujas
Join Date: Jan 2018
Location: Spain
Posts: 127
Rep Power: 11 |
Possibly there are other options, but you can try with coded functionObjects. Just define the following on your controlDict:
Code:
waterDensity { functionObjectLibs ("libutilityFunctionObjects.so"); type coded; name waterDensity; codeWrite #{ volScalarField rhoWater ( IOobject ( "rho.water", mesh().time().timeName(), mesh(), IOobject::NO_READ, IOobject::AUTO_WRITE ), mesh().lookupObject<volScalarField>("alpha.water") * mesh().lookupObject<volScalarField>("rho") ); rhoWater.write(); #}; } |
|
June 1, 2020, 15:04 |
|
#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 |
Hi,
Just a quick heads up: crubio.abujas' good example will create a new field every execution step, which may hamper the speed of the simulation, or would not allow you to use this function object output for the subsequent function objects, for example fieldAverage of the multiplied field. I had had provided an example of coded function objects in which a field was created once in one of my threads - for someone from Loughborough Uni. - I have searched for it, but couldn't find in a short period of time. If fancy, please do search for that thread. Good luck.
__________________
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 |
|
June 1, 2020, 15:45 |
|
#4 | |
New Member
Nikita
Join Date: Oct 2019
Posts: 20
Rep Power: 7 |
Quote:
Thank you crubio.abujas, but as HPE specified, it would not allow me to use this function object output for volIntegrate, code Code:
volumeIntegrate type volFieldValue; libs ("libfieldFunctionObjects.so"); log true; writeControl timeStep; writeFields false; regionType all;. operation volIntegrate; fields ( rho.water ............ ); }. HPE, thank you, I will definitely look for this topic because I have run into the problem you described. |
||
June 1, 2020, 15:54 |
|
#5 | |
New Member
Nikita
Join Date: Oct 2019
Posts: 20
Rep Power: 7 |
Quote:
Dou you think that using this code I can use volIntegrate for my field? Thank you! |
||
June 1, 2020, 16:06 |
|
#6 | |
Senior Member
Carlos Rubio Abujas
Join Date: Jan 2018
Location: Spain
Posts: 127
Rep Power: 11 |
Quote:
Concerning the first issue, it is true that the code as stated in the previous post will do it on every execution step. But I think that can be controller adding writeControl/writeInverval properties inside the definition of the function, so it behaves as any other functionObject. Concerning the second issue: I think that,as the declaration of the rhoAir object is made on the fly, other functionObjects are not aware of their existence. I've to match the writeIntervals to check if the second functionObject will try to read the file, but I guess that the dbregister drops the field as soon as it leave the scope of the first one, so it cannot be located for other ones. |
||
June 1, 2020, 16:27 |
|
#7 |
Senior Member
Carlos Rubio Abujas
Join Date: Jan 2018
Location: Spain
Posts: 127
Rep Power: 11 |
I've been trying to figure out a way, but right now I have nothing... There has to be a better way for sure, but maybe you can integrate the field using paraview, or you can try to calculate the volIntegral inside the coded functionObject. Not specially satisfying options, but It's all I have in mind right now.
|
|
June 1, 2020, 16:29 |
|
#8 | |
New Member
Nikita
Join Date: Oct 2019
Posts: 20
Rep Power: 7 |
Quote:
|
||
June 1, 2020, 16:35 |
It was just lacking static...
|
#9 | |
Senior Member
Carlos Rubio Abujas
Join Date: Jan 2018
Location: Spain
Posts: 127
Rep Power: 11 |
Quote:
Code:
waterDensity { functionObjectLibs ("libutilityFunctionObjects.so"); type coded; name waterDensity; writeControl adjustableRunTime; writeInterval 0.125; codeWrite #{ Info << "Writing rhoWater field" << endl; if (!mesh().foundObject<volScalarField>("rho.water")) { static autoPtr<volScalarField> rhoWater; rhoWater.set ( new volScalarField ( IOobject ( "rho.water", mesh().time().timeName(), mesh(), IOobject::NO_READ, IOobject::AUTO_WRITE ), mesh(), mesh().lookupObject<volScalarField>("rho").dimensions() ) ); } if(mesh().time().timeIndex() != 1) { volScalarField& rhoWater = mesh().lookupObjectRef<volScalarField>("rho.water"); rhoWater = mesh().lookupObject<volScalarField>("alpha.water") * mesh().lookupObject<volScalarField>("rho"); if (mesh().time().outputTime()) { rhoWater.write(); } } #}; } EDIT: The code I've posted ran with errors, but never updates the field. I've studied with more calm the HPE code and adapted for the current case. Now it just create a single volScalarField in the register the first time is called, and update it of the subsequent calls. Last edited by crubio.abujas; June 1, 2020 at 17:58. Reason: Correcting the code |
||
June 2, 2020, 07:08 |
|
#10 |
New Member
Nikita
Join Date: Oct 2019
Posts: 20
Rep Power: 7 |
crubio.abujas, thank you so much!!! it works.
Another little question, I need integral : rho*Uz * dV, where Uz - vertical velocity component. How can I access this vertical component of velocity in your code? |
|
June 2, 2020, 08:25 |
|
#11 | |
Senior Member
Carlos Rubio Abujas
Join Date: Jan 2018
Location: Spain
Posts: 127
Rep Power: 11 |
Quote:
Hi again Chikiton, For accessing the component of a vector you can try this code: Code:
zMomentum { functionObjectLibs ("libutilityFunctionObjects.so"); type coded; name zMomentum; writeControl adjustableRunTime; writeInterval 0.125; codeWrite #{ if (!mesh().foundObject<volScalarField>("zMom")) { static autoPtr<volScalarField> zMom; zMom.set ( new volScalarField ( IOobject ( "zMom", mesh().time().timeName(), mesh(), IOobject::NO_READ, IOobject::AUTO_WRITE ), mesh(), dimMass/dimVolume*dimLength/dimTime ) ); } volScalarField& zMom = mesh().lookupObjectRef<volScalarField>("zMom"); zMom = mesh().lookupObject<volScalarField>("rho") * mesh().lookupObject<volVectorField>("U").component(2); zMom.write(); #}; } Referring the volume multiplication. I tried to multiply straightforward, but it fails. The reason is that volume is not defined in the boundaries, so to have a magnitude of the mass could be a little bit more complicated inside the coded function objects. Maybe you can do that afterwards with another functionObject? Hopes it works! |
||
June 2, 2020, 10:20 |
|
#12 | |
New Member
Nikita
Join Date: Oct 2019
Posts: 20
Rep Power: 7 |
Quote:
|
||
June 2, 2020, 14:59 |
|
#13 | |
Senior Member
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,715
Rep Power: 40 |
Quote:
Code:
if (!mesh().foundObject<volScalarField>("zMom")) { volScalarField* pzmon = new volScalarField ( IOobject ( "zMom", mesh().time().timeName(), mesh(), IOobject::NO_READ, IOobject::AUTO_WRITE ), mesh(), dimMass/dimVolume*dimLength/dimTime ); pzmon->store(); } volScalarField& zMom = mesh().lookupObjectRef<volScalarField>("zMom"); zMom = mesh().lookupObject<volScalarField>("rho") * mesh().lookupObject<volVectorField>("U").component(2); zMom.write(); #}; } Code:
auto* pzmon = mesh().getObjectPtr("zMom"); if (!pzMon) { pzmon = new volScalarField ( IOobject ( "zMom", mesh().time().timeName(), mesh(), IOobject::NO_READ, IOobject::AUTO_WRITE ), mesh(), dimMass/dimVolume*dimLength/dimTime ); pzmon->store(); } auto& zMom = *pzmon; zMom = mesh().lookupObject<volScalarField>("rho") * mesh().lookupObject<volVectorField>("U").component(2); zMom.write(); |
||
June 3, 2020, 04:16 |
|
#14 | |
Senior Member
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,715
Rep Power: 40 |
Quote:
https://develop.openfoam.com/Develop...erivedFields.CIt illustrates much the same approach as previously outlined, but also includes handling of incompressible/compressible without much additional coding and remains IMO fairly readable in the process. For clarification, the getObjectPtr method is very much like the findObject method. They both return a pointer that can be tested (as a bool) or de-referenced. The getObjectPtr version just includes an additional const_cast since this is a frequently used idiom and it makes sense not to have all these operations cluttering things up. |
||
April 12, 2022, 03:43 |
|
#15 | |||
New Member
Shengjie Lu
Join Date: Sep 2020
Location: Nanjing,China
Posts: 12
Rep Power: 6 |
Hi, crubio.abujas, thanks for your contribution!
I tried to adapt your code to my case to calculate the time-averaged flux:<Us>, in which the U and s denotes velocity and scalar field repectively. The simulation successfully generated the field Us. However, this variable could not be used by fieldAverage. That is no say, there is no UsMean output. Here's the code adapted from your code(the flux_1 is the variable in place of Us): Quote:
Quote:
Quote:
|
||||
April 13, 2022, 05:22 |
|
#16 |
Senior Member
Carlos Rubio Abujas
Join Date: Jan 2018
Location: Spain
Posts: 127
Rep Power: 11 |
Hi Shengjie Lu,
I’ve made some tests in OF7 and fieldAverage works fine with custom fields. The code should try to reconstruct the fields defined on each time folder, so if flux exist it should process it properly. In my trials I have been unable to replicate the error you mentioned. Could you detail what commands did you execute and the detailed output? Did you execute “postprocess” or “pimpleFoam -postProcess”? Which version of OpenFOAM did you use? |
|
April 15, 2022, 03:48 |
|
#17 | |
New Member
Shengjie Lu
Join Date: Sep 2020
Location: Nanjing,China
Posts: 12
Rep Power: 6 |
Hi crubio.abujas,
I use OF7.0 in clusters, here's the commands in script: Quote:
Could you share the controlDict file of your test case if possible. Thanks again for your quick reply! |
||
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
surface and volume fields multiplication | Zato_Ichi | OpenFOAM Programming & Development | 9 | May 27, 2022 03:48 |
integrate several fields | sixwp | OpenFOAM Post-Processing | 26 | July 21, 2017 17:10 |
a reconstructPar issue | immortality | OpenFOAM Post-Processing | 8 | June 16, 2013 12:25 |
an odd(at least for me!) reconstructPar error on a field | immortality | OpenFOAM Running, Solving & CFD | 3 | June 3, 2013 23:36 |
PostChannel | maka | OpenFOAM Post-Processing | 5 | July 22, 2009 10:15 |