|
[Sponsors] |
December 11, 2012, 11:25 |
Terminate simulation based on probe
|
#1 |
Senior Member
Bernhard
Join Date: Sep 2009
Location: Delft
Posts: 790
Rep Power: 22 |
I am running a specific a large set of parameter variations of a specific case (go pyFoam!). The case is using a transient solver, but will eventually result in a steady state simulation. I want to keep that this way.
Based on some probes, I can a posteriori conclude when the steady state was reached. Now, I want to terminate the simulation (with writing output), based on the probes during runTime. This will save me a lot of computational time. I am not sure how to proceed with this. I am thinking in the direction of some functionObject, but I wonder if anything in this respect has been done already. I am not afraid to implement things, so any hints or guidance in that direction is very welcome. Also other remarks, hints, tips, suggestions, comments, notes and answers are highly appreciated! |
|
December 11, 2012, 16:03 |
|
#2 |
Member
Ganesh Vijayakumar
Join Date: Jan 2010
Posts: 44
Rep Power: 16 |
Take a look at the panicDump functionObject
http://scicomp.stackexchange.com/que...-a-given-range http://openfoamwiki.net/index.php/Co...unctionObjects |
|
December 11, 2012, 16:41 |
|
#3 |
Senior Member
Bernhard
Join Date: Sep 2009
Location: Delft
Posts: 790
Rep Power: 22 |
Thanks, I will have a look into it. I think it is not completely what I need, but definitely a good starting point for further implementation.
|
|
December 12, 2012, 11:06 |
hi
|
#4 |
Member
Simon Arne
Join Date: May 2012
Posts: 42
Rep Power: 14 |
Hi,
I did something similiar using a bash script. Basically it reads out the lines of the probe alpha file, creates an average (out of the three probes i used) and terminates interFoam if a condition is met (in this case average=0.7). openFoam is started via a script called Allrun in background and every 5 second there is a check for the condition... Unluckily I cant publish the code as I created it for my employer Some hints: - set a killswitch variable that changes from 0 to 1 when a condition is met (in my case was the average of three probe alpha values >=0.7) - a basic structure initialising killswitch, condition etc start openfoam application in background, e.g. "sh Allrun &" while [condition is not met] while read inputline #useful function to grab values from probe file time="$(echo $inputline | cut -d' ' -f1)" alpha1="$(echo $inputline | cut -d' ' -f2)" alpha2="$(echo $inputline | cut -d' ' -f3)" alpha3="$(echo $inputline | cut -d' ' -f4)" some stuff about string/integer conversion if condition not met : killswitch stays 0 condition is met: killswitch to 1 killall "solvername" fi sleep 5 done < path/to/probe/file done A useful function for mathematics in bash is |bc e.g. final=$(echo "scale=4; ($a+$b+$c)/$nrOfProbes"|bc -l) the variable final is the average of variables a+b+c, divided by the nrOfProbes (another variable). Well sorry for not showing up with real code, but I can't. Anyway not sure if this is what you are looking for because i dont know about pyFoam. Good luck! Simon Something that came to my mind: This will leave you with the output from the last normally processed timestep... If you want the real last moment captured, I guess you have to do the following When the condition is met: - change writeInterval in controlDict to something super small, what will cause openFoam to write a folder with the timestep data immediately - terminate process than with killall (I know, its like opening a coke can with a chainsaw, but hey; after the solver termination the rest of your script will run through, e.g. yPlus calculation, foamToVTK or whatever is following after the solution) Another hint: - This also will create average values from the header lines of your probe file, for me was no problem as coordinates were super small (so it never met my cancel-condition), but depending on your probe's coordinates you have to find a solution for this (I created an emergency switch that put all read values >1 to 0, because I was processing the alpha field what made it fairly easy) |
|
December 12, 2012, 11:51 |
|
#5 |
Senior Member
Kent Wardle
Join Date: Mar 2009
Location: Illinois, USA
Posts: 219
Rep Power: 21 |
There is also the runTime.writeAndEnd() function which will immediately write the data fields and stop the simulation when called. This may be useful but you will have to trigger it in the solver based on your probe analysis somehow. If you can live with runTimeModifiable on (I cannot) then a flag in controlDict is an option. Just a few thoughts.
|
|
December 12, 2012, 12:16 |
|
#6 |
Senior Member
Bernhard
Join Date: Sep 2009
Location: Delft
Posts: 790
Rep Power: 22 |
Dear Simon, thanks for this extensive answer. I did not think about a solution like this, but I think it can work. Did you know about the writeNext or stopNow options for stopAt? That may simplify your scripts a bit.
But I am actually looking for a robust approach. With your approach, if I just rerun the solver, it will not check for this criteria again right? Also, if I have multiple instances of the same solver running, then I would kill them all, which is also undesired. |
|
December 12, 2012, 12:22 |
|
#7 | |
Senior Member
Bernhard
Join Date: Sep 2009
Location: Delft
Posts: 790
Rep Power: 22 |
Quote:
|
||
December 13, 2012, 11:27 |
|
#8 |
Senior Member
Bernhard
Join Date: Sep 2009
Location: Delft
Posts: 790
Rep Power: 22 |
For future reference, I was able to reproduce the panicDump behavior with codedFunctionObjects
Code:
codedTest { type coded; functionObjectLibs ( "libutilityFunctionObjects.so" ); redirectType probeFinishControl; outputControl timeStep; minP 0.04; code #{ const volScalarField& p = mesh().lookupObject<volScalarField>("p"); Info << mesh().time().value() << " " << average(p).value() << endl; if ( average(p).value() < $minP ) { bool result=const_cast<Time&>(mesh().time()).writeNow(); FatalErrorIn("Stopped") << "Bla" << endl << exit(FatalError); } #}; } Also, I would like to advertise this related topic: http://www.cfd-online.com/Forums/ope...ionobject.html |
|
December 13, 2012, 12:36 |
|
#9 |
Senior Member
Bernhard
Join Date: Sep 2009
Location: Delft
Posts: 790
Rep Power: 22 |
To continue my monologue. For the cavity-case and icoFoam I was able to get to the converged solution with the function I posted below.
Please note that this is only working for monotic increasing or decreasing convergence at a point, so it is far from a solid check, but, it is a starting point Code:
probeFinishControl { type coded; functionObjectLibs ( "libutilityFunctionObjects.so" ); redirectType probeFinishControl; outputControl timeStep; fieldName p; code #{ const volScalarField& p = mesh().lookupObject<volScalarField>("$fieldName"); scalar probe0(p.oldTime()[1]); scalar probe1(p[1]); scalar diff(probe0-probe1); Info << probe0 << endl << probe1 << endl; Info << fabs(diff) << endl; Info << mesh().time().timeIndex() << endl; if ( fabs(diff) < 1.e-7 && mesh().time().timeIndex() > 10 ) { const_cast<Time&>(mesh().time()).writeNow(); FatalErrorIn("probeFinishControl") << "Probe on testpoint for $fieldName not changing" << endl << exit(FatalError); } #}; } |
|
December 23, 2012, 07:11 |
|
#10 | |
Assistant Moderator
Bernhard Gschaider
Join Date: Mar 2009
Posts: 4,225
Rep Power: 51 |
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 |
||
December 23, 2012, 07:44 |
|
#11 |
Senior Member
Bernhard
Join Date: Sep 2009
Location: Delft
Posts: 790
Rep Power: 22 |
Thanks for your suggestions. Using a swak kind of probe would allow for a much nicer control of the probing location.
I have to test the static declaration, in the coded FO it will not work as far as I understand the C++. I see the possibilities when writing an own derived FO however. I should have thought of it. Thanks again. |
|
December 23, 2012, 08:49 |
|
#12 | |
Assistant Moderator
Bernhard Gschaider
Join Date: Mar 2009
Posts: 4,225
Rep Power: 51 |
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 8, 2014, 11:49 |
|
#13 |
New Member
Join Date: Jul 2013
Posts: 8
Rep Power: 13 |
Hallo,
I'd like to terminate my simulation based on temperature probes. For this purpose I create some probes with createSampledSet. I want to save these probes in a global variable with swakCoded and write a termination criterion. My problem is up to now, that I don't know how to get the probe values to the global variable. Is there an example? Thank's for your help in advance |
|
September 8, 2014, 15:11 |
|
#14 | |
Assistant Moderator
Bernhard Gschaider
Join Date: Mar 2009
Posts: 4,225
Rep Power: 51 |
Quote:
For your purposed you might not even need the variables. There is (in the simpleSwakFunctionObjects - or was it swakSimpleFunctionObjects. I keep forgetting) a FO called writeAndEndSwakExpression that gracefully ends the run if an expression is true (in your case "valueType set") For an explained example on global variables see my "Programming swak"-presentation from this years workshop in Zagreb (it is linked from the swak-Wiki-page)
__________________
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 9, 2014, 08:04 |
|
#15 |
New Member
Join Date: Jul 2013
Posts: 8
Rep Power: 13 |
Code:
stopIfNoChange { type writeAndEndSwakExpression; valueType set; logicalExpression "(diffT1 < threshold) || (diffT2 < threshold)"; logicalAccumulation and; setName probePoints; //my problems start here: how can I define the probes? set { type cloud; axis xyz; points ( (0.25 0.05 0.4) (0.25 0.225 0.4) ); variables ( "T1{set 'probePoints[1]}=sum(T);" //How can I access the probe values? "T1fter{set 'probePoints[1]}=sum(T);" "T2{set 'probePoints[2]}=sum(T);" "T2fter{set 'probePoints[2]}=sum(T);" "diffT1=mag(T1fter-T1);" "diffT2=mag(T2fter-T2);" "threshold=0.5;" ); delayedVariables ( { name T1fter; delay 2500; storeInterval 1; startupValue "1"; } { name T2fter; delay 2500; storeInterval 1; startupValue "1"; } ); verbose true; outputControlMode timestep; outputInterval 1; } thank's for your advise to use writeAndEndSwakExpression FO, but I still have some problems to implement and access the coordinates/values of my probes. I haven't found an example (,yet), how to use writeAndEndSwakExpression FO with valueType set;. Could you please give me a hint or an example? Thank's in advance |
|
September 9, 2014, 17:33 |
|
#16 | |
Assistant Moderator
Bernhard Gschaider
Join Date: Mar 2009
Posts: 4,225
Rep Power: 51 |
Quote:
As your value type is already "set" on probePoints you don't need the {set'probePoints} in the variables-section. The variables will then store the values in one array. It is not possible to to access the values separately but all the expressions are "vectorized". But this is not a problem for your application. The logical expression would be something like "TDiff<threshold" and the logicalAccumulation would be "or" (that would give the same semantics your current expression gives: if the difference on ANY point falls below 0.5 -> terminate run)
__________________
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 10, 2014, 12:43 |
|
#17 |
New Member
Join Date: Jul 2013
Posts: 8
Rep Power: 13 |
Code:
stopIfNoChange { type writeAndEndSwakExpression; valueType set; logicalExpression "(diffT1 < threshold)"; logicalAccumulation or; setName monitorpoints; set { type swakRegistryProxy; axis y; setName probePoints; } variables ( "T1=T;" "T1fter=T;" "diffT1=mag(T1fter-T1);" "threshold=0.5;" ); delayedVariables ( { name T1fter; delay 2500; storeInterval 1; startupValue "1"; } ); verbose true; outputControlMode timeStep; outputInterval 1; } createProbes { type createSampledSet; outputControl timeStep; outputInterval 1; setName probePoints; set { type cloud; axis y; points ( (0.25 0.05 0.4) (0.25 0.225 0.4) ); } } thank's for your help. I try to use the createSampledSet FO now (see code above), but unfortunately it still doesn't work. I get the following error message: probePoints not found in table. Valid entries: 0() Can you tell me, what I have to change? |
|
September 10, 2014, 13:21 |
|
#18 | |
Assistant Moderator
Bernhard Gschaider
Join Date: Mar 2009
Posts: 4,225
Rep Power: 51 |
Quote:
Because for people how do programming the Mantra is "usually things happen in the order in which they are written down". And the functions-entry in OpenFOAM is a bit like programming Move createProbes in front
__________________
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 11, 2014, 11:54 |
|
#19 |
New Member
Join Date: Jul 2013
Posts: 8
Rep Power: 13 |
Hallo Bernhard,
thank you very much for your help, it seems to work. |
|
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Strange residuals of the Density Based Solver | Pat84 | FLUENT | 0 | October 22, 2012 16:59 |
Compressible flow simulation at mach .7 | mbeals | FLUENT | 6 | April 18, 2009 11:49 |
About probe result of Wave simulation | shiw | FLOW-3D | 3 | March 13, 2009 10:15 |
strange simulation error | Ralf Schmidt | FLUENT | 2 | May 4, 2007 14:02 |
3-D Contaminant Dispersal Simulation | Apple L S Chan | Main CFD Forum | 1 | December 23, 1998 11:06 |