|
[Sponsors] |
Create registered object at runtime using a functionObject |
|
LinkBack | Thread Tools | Search this Thread | Display Modes |
March 28, 2012, 10:40 |
Create registered object at runtime using a functionObject
|
#1 |
Member
Cedric Van Holsbeke
Join Date: Dec 2009
Location: Belgium
Posts: 81
Rep Power: 16 |
A functionObject can only perform calculations on fields that are calculated by the solver. If I want to calculate the fieldMinMax of the total pressure (ptot) at runtime, the createFields.H file of the solver has to be changed so that ptot is a known volScalarField.
However, it would be nice to generate this value without modifying the solver to preserve compatibility when upgrading OpenFOAM. I can calculate ptot for an incompressible solver using this functionObject: Code:
compute_ptot { functionObjectLibs ( "libutilityFunctionObjects.so" ); type coded; enabled true; redirectType ptot; outputControl timeStep; outputInterval 1; code #{ const volScalarField& p = mesh().lookupObject<volScalarField>("p"); const volVectorField& U = mesh().lookupObject<volVectorField>("U"); volScalarField ptot ( IOobject ( "ptot", mesh().time().timeName(), p.mesh(), IOobject::NO_READ, IOobject::AUTO_WRITE ), p ); ptot = p + 0.5*magSqr(U); #}; } Code:
fieldMinMax { type fieldMinMax; functionObjectLibs ("libfieldFunctionObjects.so"); log true; valueOutput false; outputControl timeStep; outputInterval 1; mode magnitude; fields ( ptot ); } I can make a workaround by adding ptot.write() to the first functionObject and than reading it back in using readFields. However, this generates extra files and directories and is not a clean solution. Is there a possibility to keep the calculated ptot in memory (as it does with p and U) in order to be able to use functionObjects on this value? |
|
March 28, 2012, 17:32 |
|
#2 | |
Assistant Moderator
Bernhard Gschaider
Join Date: Mar 2009
Posts: 4,225
Rep Power: 51 |
Quote:
But what I usually do in that situation is write something like Code:
compute_ptot { type expressionField; outputControl timeStep; outputInterval 1; fieldName ptot; expression "p + 0.5*magSqr(U)"; autowrite false; } The coded-functionObject can be very useful and enables you to go to places that swak can't go, but I don't like to program C++ if it is not necessary (especially if the only thing that changed between applications is the one line of code that does the actual calculation) PS: another way to solve this would be to write a subclass of codedFunctionObject that has a volScalarField as a member |
||
April 3, 2012, 12:07 |
|
#3 |
Member
Cedric Van Holsbeke
Join Date: Dec 2009
Location: Belgium
Posts: 81
Rep Power: 16 |
Thank you very much!
I did not manage in C++ but with swak4foam it works perfectly! However, swak4foam does not recognise the magSqr() function. If other people would have the same problem, the correct code is: Code:
compute_ptot { type expressionField; outputControl timeStep; outputInterval 1; fieldName ptot; expression "p + 0.5*sqrt(mag(U))"; autowrite false; } |
|
April 3, 2012, 14:48 |
|
#4 | |
Assistant Moderator
Bernhard Gschaider
Join Date: Mar 2009
Posts: 4,225
Rep Power: 51 |
Quote:
If a bug-report appears on the of-extend-Mantis the magSqr-function might appear in swak4Foam in the next release |
||
September 21, 2012, 06:03 |
|
#5 |
Senior Member
Eelco van Vliet
Join Date: Mar 2009
Location: The Netherlands
Posts: 124
Rep Power: 19 |
Hi Bernard,
I was reading your instruction to add an object to the registry from the code snipped. Actually, I would like to do something like this. For instance, I would like to calculated the averaged vorticity magnitude using the field average libs without modifying the code. For that I want to use the code snipped to calculate the mag voritcity. I tried your tip, it compiles but it does not work The question is: how do I add the field to the object registry ? Do you have a hint for me ? Here is what I have so far. I am trying to use checkin. Is that correct ? Thanks! Eelco Code:
magUIntegral { functionObjectLibs ("libutilityFunctionObjects.so"); type coded; redirectType integral; outputControl timeStep; code #{ const volVectorField& U = mesh().lookupObject<volVectorField>("U"); if (!(IOobject("magVorticity", mesh().time().timeName(), U.mesh()).headerOk())) { Info << "creating magVorticity" << nl; volScalarField magVorticity ( IOobject ( "magVorticity", mesh().time().timeName(), U.mesh(), IOobject::NO_READ, IOobject::NO_WRITE ), mag(fvc::curl(U)) ); Info << "Add it to the registry" << nl; magVorticity.checkIn(); } Info << "now getting magVoritity" << nl; const volScalarField& magVorticity = mesh().lookupObject<volScalarField>("magVorticity"); //magVorticity=mag(fvc::curl(U)); #}; } |
|
September 21, 2012, 13:18 |
|
#6 | ||
Assistant Moderator
Bernhard Gschaider
Join Date: Mar 2009
Posts: 4,225
Rep Power: 51 |
Quote:
I'm afraid the object is destroyed when it goes out of scope and the during that the destructor calls checkOut (its got no other choice as C++ will insist on giving back the memory). So I guess you'll have to create a volScalarField with new, check that in and forget about the pointer. But to see how to do that correctly without openig a HUGE memory leak and be sure that it is given back correctly at the end of the run I'd have to go through the sources. and frankly I don't care: If I want such a field I use an expressionField-function object with the expression "mag(curl(U))" give it a name and happily use it from then on (and I do that regularly). For me programming is solving a problem once, do it right and then forget how I did it. That's what swak is there for. Writing boilerplate-snipplets like the one below every time I need it (and I use that often) would be a good memory exercise (not my strong foot) but in the long run rather boring. Don't get me wrong: if you want to learn how to program OpenFOAM then this is a nice exercise, but you'll learn more by reading the regIOobject and the objectRegistry-class and experimenting. If you just want to get your work done then take the 15 minutes it will take you to compile swak4Foam (most of the time will be spent drinking coffee) and use an expressionField. Or if you're lucky somebody will take this arrogant rant (hope it doesn't come across as that) as an incentive to show you (and me) how it can be done elegantly in C++ Quote:
__________________
Note: I don't use "Friend"-feature on this forum out of principle. Ah. And by the way: I'm not on Facebook either. So don't be offended if I don't accept your invitation/friend request |
|||
September 25, 2012, 08:04 |
|
#7 |
Senior Member
Eelco van Vliet
Join Date: Mar 2009
Location: The Netherlands
Posts: 124
Rep Power: 19 |
Hi Bernard,
Indeed my example didn't work for the reason you gave. Your remark about using swak4foam: yes, I totally agree, I use it at least quite a lot for funkySetFields and groovyBC, I didn't no this expression field yet. But to be honest, the reason I wanted to do something complicated via C++ is that I want to keep an summation of the velocity of lagrangian particles (their values and their sum) per grid cell so I can calculate the mean conditional particle velocity over the field at the end of the run .This requires I think some C++ coding as I guessed swak4foam could not deal with lagrangian particles. I though if I got the simpler case wit mag(curl(U)) running I can do the particle averaging as well (without modifying the source code of the application) So per grid cell I would like to keep durign the run sumN=Sum_particlesincell(i) sumU=Sumparticlesincell(U_i) in order to get the <Upart>=sumU/sumN at the end of the run. I thought I need coded snipped for this, but if there is a way to do it with swak4foam: please let me know! |
|
September 25, 2012, 12:44 |
|
#8 | ||
Assistant Moderator
Bernhard Gschaider
Join Date: Mar 2009
Posts: 4,225
Rep Power: 51 |
Quote:
Quote:
- functionObjects that allow to add particle clouds to solvers that don't usually do particles - function-plugins (a new feature of that development version) that query existing clouds (of the intermediate-variety) for information that they voluntarily give (volume/mass fraction of the particles, momentum and other sources ...) but the information you're interested in (particle properties mapped to the volume) it can not do. Writing such a function is not that hard ... for a specific cloud-type. The problem starts if it should be more general So I'm afraid swak won't do this for you. About your problem with the field being destroyed if the variable goes out of scope. The problem is basically that the coded-function object doesn't allow you to add member variables. But maybe this might help you: Code:
static autoPtr<volScalarField> pField; if(!pField.valid()) { pField.set(new volScalarField(....)); } volScalarField &field=pField(); ... do your thing What I'd do if I had that problem (but admittedly I'm a bit extreme here) would be to write a library with plugin-functions that encapsulate the querying of the particles in a special function that I can then call in swak-expressions (something like "cellVelocitySum(myCloudName)") if the library is loaded. That's what I did the functionPlugins for: adding application specific functionality to swak. But there is currently no docu for this, so this wouldn't be easy
__________________
Note: I don't use "Friend"-feature on this forum out of principle. Ah. And by the way: I'm not on Facebook either. So don't be offended if I don't accept your invitation/friend request |
|||
October 1, 2012, 03:06 |
|
#9 |
Senior Member
Eelco van Vliet
Join Date: Mar 2009
Location: The Netherlands
Posts: 124
Rep Power: 19 |
Hi Bernard,
Well, thanks for the answer to my problem, your suggestion seems to work. For the record, here what I did: Code:
magvorticityIntegral { functionObjectLibs ("libutilityFunctionObjects.so"); type coded; redirectType integral; outputControl timeStep; code #{ const volVectorField& U = mesh().lookupObject<volVectorField>("U"); static autoPtr<volScalarField> pField; if(!pField.valid()) { Info << "Creating magVorticity" << nl; pField.set ( new volScalarField ( IOobject ( "magVorticity", mesh().time().timeName(), U.mesh(), IOobject::NO_READ, IOobject::AUTO_WRITE ), mag(fvc::curl(U)) ) ); } volScalarField &magVorticity = pField(); magVorticity.checkIn(); magVorticity += mag(fvc::curl(U)); Info << " max Vorticity " << max(magVorticity) << nl; #}; } ~ Well, one small issue, perhaps you have the solution for it as well. Although this code works, the registration of the magVorticity field is done only at the end of the first iteration. In case you would like to use the fieldAverage functionobject, this is too late. Althought I make sure that the dynamic code is added before the fieldAverages, the magVorticity does not exist yet when the fieldaverage field are created and therefore fieldaverage complains if you add magVorticity to its list. Do you have any trick to get away with this? For example to force to run the dynamic code directly at loading time? Or to postpone the allocation of the field average dict after the end of the iteration ? Well, if it is not easy to solve, never mind. With this I at least get my particles statistics running. but if I could use fieldAverage for it it would be even better of coarse:-) Thanks! Regards Eelco |
|
October 1, 2012, 08:41 |
|
#10 | |
Assistant Moderator
Bernhard Gschaider
Join Date: Mar 2009
Posts: 4,225
Rep Power: 51 |
Quote:
Well. I have a workaround. But don't be surprised: it involves swak. There is a functionObject executeIfSwakExpression (there is a number of similar FOs) that encapsulates a list of functionObjects and only executes them if a condition is true. Also there is an option readDuringConstruction. If set to false the construction of the FOs will be deferred until the expression (for instance "time>0.001") is true for the first time. So what might work is this sequence - your FO - executeIfSwakExpression with -- expression "true" -- readDuringConstruction "false" -- fieldAverage as the only FO in the sequence might help you But there is always the possibility to write a new FO by copy/pasting fieldAverage or inheriting and "rewiring" the execution
__________________
Note: I don't use "Friend"-feature on this forum out of principle. Ah. And by the way: I'm not on Facebook either. So don't be offended if I don't accept your invitation/friend request |
||
October 4, 2012, 03:00 |
|
#11 |
Senior Member
Eelco van Vliet
Join Date: Mar 2009
Location: The Netherlands
Posts: 124
Rep Power: 19 |
Bernard,
Thanks a lot, I just had a look at those swak function objects and I have the impression that this is going to help me. For now I actually solved it by writing a cloudfunction function object in the LPT library (copied VoidFraction Cloudfunctionobject and modified it to get the mean particle velocity field). This works and allows me to keep the statistical analyses separare from the solver as well. I will have a look at the swak function objects as soon as I have some time. It seems to me that this replaces almost all the other functionobjects (averaging, sample lines and planes, volume averaging, monitoring points) with a greater flexibility, so it is worth to see if I can use it. Thanks for the hint! Regards Eelco |
|
October 19, 2012, 04:12 |
averaging of field made with coded function objects
|
#12 |
Senior Member
Eelco van Vliet
Join Date: Mar 2009
Location: The Netherlands
Posts: 124
Rep Power: 19 |
Hi Bernard,
Just had some time to play around with swak4foam to see if I got your suggestion running. And yes, swak4foam gives the solution again! For those interested: In case you want to generate some field (like for instance the vorticity) on the fly (not in the solver) and also be able to average it with the functionobject, the following works Put in your controlDict Code:
libs ( "libsimpleSwakFunctionObjects.so" "libswakFunctionObjects.so" ); functions ( #include "dynamicCodeVolumeAverageDict" #include "fieldAverageDict" ); system/dynamicCodeVolumeAverageDict Code:
magvorticityIntegral { functionObjectLibs ("libutilityFunctionObjects.so"); type coded; redirectType integral; outputControl timeStep; code #{ const volVectorField& U = mesh().lookupObject<volVectorField>("U"); static autoPtr<volScalarField> pField; if(!pField.valid()) { Info << "Creating magVorticity" << nl; pField.set ( new volScalarField ( IOobject ( "magVorticity", mesh().time().timeName(), U.mesh(), IOobject::NO_READ, IOobject::AUTO_WRITE ), mag(fvc::curl(U)) ) ); } volScalarField &magVorticity = pField(); magVorticity.checkIn(); magVorticity += mag(fvc::curl(U)); Info << " max Vorticity " << max(magVorticity) << nl; #}; } system/fieldAverageDict Code:
fieldAverageEnc { type executeIfSwakExpression; logicalExpression "(time()>0.001)"; logicalAccumulation "and"; readDuringConstruction false; valueType internalField; functions { fieldAverage { type fieldAverage; functionObjectLibs ("libfieldFunctionObjects.so"); enabled true; timeStart 0; resetFields 1; // timeEnd 250; outputControl outputTime; fields ( U { mean on; prime2Mean on; base time; } magVorticity { mean on; prime2Mean off; base time; } ); } // END fieldAverage } } Bernard, thanks again for the very useful hints! (and for writing those swak4foam functionobjects in the first place of course). Regards Eelco |
|
October 19, 2012, 04:14 |
|
#13 |
Senior Member
Eelco van Vliet
Join Date: Mar 2009
Location: The Netherlands
Posts: 124
Rep Power: 19 |
Oops, the += in the code function object should be =, the former was of a testing phase.
|
|
October 19, 2012, 05:58 |
|
#14 | |
Assistant Moderator
Bernhard Gschaider
Join Date: Mar 2009
Posts: 4,225
Rep Power: 51 |
Quote:
Code:
magvorticityIntegral { type expressionField; outputControl timeStep; outputInterval 1; fieldName magVorticity; expression "mag(curl(U))"; autowrite false; }
__________________
Note: I don't use "Friend"-feature on this forum out of principle. Ah. And by the way: I'm not on Facebook either. So don't be offended if I don't accept your invitation/friend request |
||
October 19, 2012, 09:08 |
|
#15 |
Senior Member
Eelco van Vliet
Join Date: Mar 2009
Location: The Netherlands
Posts: 124
Rep Power: 19 |
It's always nice to know that there are several ways to Rome :-)
|
|
November 26, 2012, 09:15 |
startTime reference
|
#16 |
Senior Member
Eelco van Vliet
Join Date: Mar 2009
Location: The Netherlands
Posts: 124
Rep Power: 19 |
Dear Bernhard,
I took the trick you showed me with the executeIfSwakExpression in my standard repetoir. One little question I now use the expression: { type executeIfSwakExpression; logicalExpression "(time()>0.001)"; logicalAccumulation "and"; readDuringConstruction false; valueType internalField; functions { } } However, if I make a restart I have to change the 0.001 into something with 10.0001 orso. Is there a way to refer to the startTime of the current run, something like logicalExpression "(time()>startTime()+0.001)"; I tried a few options, but none did work. Otherwise: is there a way just to check if a field excists ? and the execute the function only if it is true ? That would help too. Well, thanks for any hints. Regards Eelco |
|
November 26, 2012, 15:01 |
|
#17 | ||
Assistant Moderator
Bernhard Gschaider
Join Date: Mar 2009
Posts: 4,225
Rep Power: 51 |
Quote:
Adding a global variable with the addGlobalVariable-functionObject has the same problem ... I think (I could look at the source but I'm too busy). Then there is the possibility to use the pythonIntegration-functionObject: define a code snipplet for the initialization time that sets some variable to the current time (which is the initialization time). Don't modify it in the other snipplets and export the variable to a global namespace from which the functionObject in question can import it. If you bit the bullet and used the pythonIntegration then you might be able to do it with the executeIfPython-function object and the python code: Code:
if not "startTime" in dir(): startTime=runTime return runTime>(startTime+0.001) Quote:
For examples on the usage of this something like "grep -r executeIfPython Examples/*" will help you
__________________
Note: I don't use "Friend"-feature on this forum out of principle. Ah. And by the way: I'm not on Facebook either. So don't be offended if I don't accept your invitation/friend request |
|||
November 27, 2012, 02:38 |
|
#18 |
Senior Member
Eelco van Vliet
Join Date: Mar 2009
Location: The Netherlands
Posts: 124
Rep Power: 19 |
Thanks for the hints Bernhard!
I will give the python option a try. If I find I solution I will report it back to you. Eelco (alias Captain beefheard |
|
November 27, 2012, 03:04 |
executeIfObjectExists
|
#19 |
Senior Member
Eelco van Vliet
Join Date: Mar 2009
Location: The Netherlands
Posts: 124
Rep Power: 19 |
For those interested. Using the captain braveheard trick I found the executeIfObjectExists function object. I need this because first I use a swakExpression to calculate the magnitude of the vorticity:
Code:
magVorticity { type expressionField; outputControl timeStep; outputInterval 1; fieldName magVorticity; expression "mag(curl(U))"; autowrite true; } You can do the following Code:
PlanesVTKEnc { type executeIfObjectExists; readDuringConstruction false; objectName magVorticity; checkType true; objectType volScalarField; objectShouldExist true; valueType internalField; functions { PlanesVTK { enabled true; type surfaces; setFormat raw; surfaceFormat vtk; writeFormat binary; timePrecision 0; interpolationScheme cellPointFace; functionObjectLibs ("libsampling.so"); outputControl timeStep; outputInterval 1; fields ( U nuSgs magVorticity ); surfaces ( pxy_z0p0 { type plane; // always triangulated // make plane relative to the coordinateSystem (Cartesian) coordinateSystem { origin (0.0 0.0 0.0); } basePoint (0 0 0); normalVector (0 0 1); interpolate true; } ); } } } Bernhard, thanks again for the useful hints. swak4foam is truly fantastic! |
|
November 27, 2012, 10:11 |
|
#20 | |
Assistant Moderator
Bernhard Gschaider
Join Date: Mar 2009
Posts: 4,225
Rep Power: 51 |
Quote:
Damn. I thought I had tricked you to come to the dark side of the force (=Python)
__________________
Note: I don't use "Friend"-feature on this forum out of principle. Ah. And by the way: I'm not on Facebook either. So don't be offended if I don't accept your invitation/friend request |
||
Thread Tools | Search this Thread |
Display Modes | |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Meshing a Sphere | Ajay | FLUENT | 10 | September 3, 2016 14:18 |
Actuator disk model | audrich | FLUENT | 0 | September 21, 2009 07:06 |
Where's the singularity/mesh flaw? | audrich | FLUENT | 3 | August 4, 2009 01:07 |
[blockMesh] BlockMeshmergePatchPairs | hjasak | OpenFOAM Meshing & Mesh Conversion | 11 | August 15, 2008 07:36 |
fluent add additional zones for the mesh file | SSL | FLUENT | 2 | January 26, 2008 11:55 |