CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > Software User Forums > OpenFOAM > OpenFOAM Programming & Development

Mixing #codeStream with coded-function-object

Register Blogs Community New Posts Updated Threads Search

Like Tree1Likes
  • 1 Post By Zeppo

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   December 31, 2015, 14:20
Default Mixing #codeStream with coded-function-object
  #1
Senior Member
 
Zeppo's Avatar
 
Sergei
Join Date: Dec 2009
Posts: 261
Rep Power: 21
Zeppo will become famous soon enough
While performing a multi-region heat transfer simulation with “chtMultiRegionSimpleFoam” I want to track the solution progress. To be more specific I need to watch maximum temperatures in every region while a simulation is running. The utility “pyFoamRunner” can easily generate a live plot (through gnuplot) of any user-defined values (the format should be specified in the “customRegexp” file). The values are periodically picked up by pyFoamRunner from the solver’s standard output and then added to the plot throughout a simulation.
My customRegexp is as follows:
“customRegexp”
Code:
T_max
{
    type dynamic;
    idNr 1;
    expr "T__max__(.+): (%f%)";
    titles ("");
}
Now I only have to find a way to print something like
“T__max__region__01: 523”,
“T__max__region__02: 311”,

and so on, one line for one region, at every iteration to the standard output. Here, “region__01”, “region__02” are regions’ names; 523, 311 are the actual solution-dependent values to be plotted.
As we all know, function objects are executed at every iteration. I want to construct as many function objects as there are regions in the case. Each function region is going to be responsible for printing a maximum value of a specific region’s temperature to the solver’s standard output.
Please, take a look at the excerpt from my controlDict:
Code:
   
//”system/controlDict”
//- This doesn't work at all. #{ #} causes all the problems
#codeStream
{
	codeInclude
	#{
		#include <cstdio>
		#include "OSspecific.H"     // getEnv();
		#include "IFstream.H"
		#include "error.h"
	#};
	code
	#{
		string casePath = Foam::getEnv("FOAM_CASE");
		string userDictPath = casePath + "/system/include/userInput";
		IFstream ifs (userDictPath);
		dictionary userDict (ifs);
		long n = userDict.lookupOrDefault("numberOfRegions", -1);
		if(n<1)
		{
			error error("!ERROR! number of regions is less than 1");
			error.abort();
		}
		for(long i=0; i<n; ++i)
		{
			char iStr[100];
			std::sprintf(iStr,"%02ld", (i+1));
			string region = string("region__") + iStr;
			string str =
			string("T__max__") + region + string("{\n")+
			string("region             ") + region + string(";\n")+
			string("redirectType       ") + region + string(";\n")+
			string("enabled            true;\n")+
			string("type               coded;\n")+
			string("functionObjectLibs (\"libutilityFunctionObjects.so\");\n")+
			string("outputControl      timeStep;\n")+
			string("outputInterval     1;\n")+
			string("log                false;\n")+
			string("codeInclude #{ #};\n")+
			string("code #{\n")+
			string("const volScalarField& T = mesh().lookupObject<volScalarField>("T");\n")+
			string("Info << "T_max__01: " << max(T).value() << "\n" << endl;\n")+
			string("#};\n")+
			string("}\n");
			os << word(str) << endl;
		}
	#};
}
#codeStream's role is to iterate through the regions (the loop from 0 to n) and construct a coded function object for each region. For example, for a region “region__01” a function object is constructed this way:
Code:
T__max__region__01
{
	enabled            true;
	type               coded;
	functionObjectLibs ("libutilityFunctionObjects.so");
	region             region__01;
	redirectType       T__max__region__01;
	outputControl      timeStep;
	outputInterval     1;
	log                false;
	codeInclude
	#{
	#};
	code
	#{
		const volScalarField& T = mesh().lookupObject<volScalarField>("T");
		Info << string("T__max__")+region+string(": ") << max(T).value() << "\n" << endl;
	#};
}
And this is the point where my entire plan fails. OpenFoam #codeStream mechanism just doesn’t know what to do with a group of special-meaning tokens “#{” and “#}” enclosed in each other. It can’t figure out if “#{” and “#}” are only for function object definition or they are merely a part of #codeStream definition.
Is it possible to resolve the problem? Can anyone suggest any workaround? Might I be better off developing my own function object?
Zeppo is offline   Reply With Quote

Old   January 1, 2016, 08:59
Lightbulb Solution
  #2
Senior Member
 
Zeppo's Avatar
 
Sergei
Join Date: Dec 2009
Posts: 261
Rep Power: 21
Zeppo will become famous soon enough
I’ve found a solution! The code should be:
Code:
#codeStream
{
	codeInclude
	#{
		#include "OSspecific.H"     // getEnv();
		#include "IFstream.H"
	#};
	code
	#{
		string casePath = Foam::getEnv("FOAM_CASE");
		string userDictPath = casePath + "/system/include/userInput";
		IFstream ifs (userDictPath);
		dictionary userDict (ifs);
		long n = userDict.lookupOrDefault("numberOfRegions", -1);
		if(n<1)
		{
			error error("!ERROR! number of regions is less than 1");
			error.abort();
		}
		for(long i=0; i<n; ++i)
		{
			char iStr[100];
			std::sprintf(iStr,"%02ld", (i+1));
			string region = string("region__") + iStr;
			string str =
			string("T_max_[") + region + string("]{\n")+
			string("enabled            true;\n")+
			string("type               cellSource;\n")+
			string("functionObjectLibs (\"libfieldFunctionObjects.so\");\n")+
			string("region             ") + region + string(";\n")+
			string("source             cellZone;\n")+
			string("sourceName         ") + region + string(";\n")+
			string("operation          max;\n")+
			string("fields             (T);\n")+
			string("outputControl      timeStep;\n")+
			string("outputInterval     1;\n")+
			string("log                true;\n")+
			string("valueOutput        false;\n")+
			string("surfaceFormat      null;\n")+
			string("}\n");
			os << word(str) << endl;
		}
	#};
}
The line that make a difference is “string("log true;\n")+”. Now function objects print the following to the output:
Code:
cellSource T_max_[region__01] output:
max(region__01) of T = 310.3328

cellSource T_max_[region__02] output:
max(region__02) of T = 320.5656
and so on.
My customRegexp was altered to be:
Code:
"customRegexp"
T_max
{
    type dynamic;
    idNr 1;
    expr "max(.+) of T = (%f%)";
    titles ("");
}
And a plot looks like:

Unfortunately the plot legend items are displayed in an unsorted order.
Jamill1283 likes this.
Zeppo is offline   Reply With Quote

Reply

Tags
#codestream, c++, coded function object


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
codeInclude in coded function in controlDict, and yPlus LuisAlberto OpenFOAM Programming & Development 4 August 18, 2015 12:48
Compile problem ivanyao OpenFOAM Running, Solving & CFD 1 October 12, 2012 09:31
Compilation errors in ThirdPartymallochoard feng_w OpenFOAM Installation 1 January 25, 2009 06:59
Problem with compile the setParabolicInlet ivanyao OpenFOAM Running, Solving & CFD 6 September 5, 2008 20:50
[blockMesh] BlockMeshmergePatchPairs hjasak OpenFOAM Meshing & Mesh Conversion 11 August 15, 2008 07:36


All times are GMT -4. The time now is 15:38.