CFD Online Discussion Forums

CFD Online Discussion Forums (http://www.cfd-online.com/Forums/)
-   OpenFOAM Programming & Development (http://www.cfd-online.com/Forums/openfoam-programming-development/)
-   -   Starting field averaging using libFunctionObject after certain time (http://www.cfd-online.com/Forums/openfoam-programming-development/92306-starting-field-averaging-using-libfunctionobject-after-certain-time.html)

eelcovv September 9, 2011 09:47

Starting field averaging using libFunctionObject after certain time
 
Hi Foamers,

I am quite often using simpleFunctionObjects (http://openfoamwiki.net/index.php/Co...unctionObjects), in order to do for instance averaging of data field. In this tread I want to find out how to start the averaging after a certain time such that first the flow can first develop.

For data averging over time I put in the controlDict

Code:

functions
(
    #include "fieldAverageDict"
);

and to add a file in the system directory called fieldAverageDict with the content

Code:

  fieldAverage1
    {
        type            fieldAverage;
        functionObjectLibs ("libfieldFunctionObjects.so" );
        enabled        true;
        outputControl  outputTime;
        fields
        (
            U
            {
                mean        on;
                prime2Mean  off;
                base        time;
            }
        );
    }

This works very well. As I said: quite often I want to start the averaging only after a certain time such that the flow can first fully develop. Of course I could stop my simulation, reset the field averaging and switch the enabled flag from false to true, and start again, however, this is not very convinient, especially if there is long waiting time in a queing system: if you stop you calculation, you have to go back into the queue again. Also, I could by hand modify fieldAverageDict, then controlDict, and that works too. However, I want to have it automatically.

The question is: how can I automatically start the averaging during a run after a certain time with the function objects?

According to the simpleFunctionobject manual there is an entry to the functionobject called 'after' which should define the time after which the function is read, however, this does not work. If I add after 100; (for instance), nothing happens, it just starts averaging right from the start.

So I have thought another trick: using the timeActivatedFileUpdate lib: http://foam.sourceforge.net/docs/cpp/a02055.html

With this dict, I add a file to the system directory called fileUpdate with the content
Code:

fileUpdate1
{
    type            timeActivatedFileUpdate;
    functionObjectLibs ("libutilityFunctionObjects.so");
    outputControl  timeStep;
    outputInterval  1;
    fileToUpdate    "$FOAM_CASE/system/fieldAverageDict";
    timeVsFile
    (
        (-1    "$FOAM_CASE/system/fieldAverageDict_0")
        (20    "$FOAM_CASE/system/fieldAverageDict_1")
    );

And I included this in the controlDict with an include statement

Code:

   
fucntions
(
  #include "fieldAverageDict"
  #include "fileUpdate"
);

In fieldAverageDict_0, enabled=false, in fieldAverageDict_1, enabled=true.

This works, however, although the file fieldAverageDict got modified, it does not get reread during the run.

Next trick: also use trackDictionary from simpleSwakFunctionObjects.so, in which aparently you can specify all the files which are read during the run and reread if modified. So I add to the functions the include line
Code:

  #include "trackDictionary"
and to the file trackDictionary
Code:

trackDictionaryContent
{
    type trackDictionary;

    // Where to load it from (if not already in solver)
    functionObjectLibs ("simpleSwakFunctionObjects.so");

    // Names of dictionaries to track.
    dictionaryNameList
    (
        "system/controlDict"
        "system/fvSchemes"
        "system/fvSolution"
        "constant/transportProperties"
        "system/fieldAverage"
    );
  echoControlDictDebugSwitches        false;
  echoControlDictInfoSwitches        true;
  echoControlDictOptimisationSwitches true;
  echoControlDictTolerances          true;
  echoControlDictDimensionedConstants true;
  sectionStartSeparator "############ Start of: _sectionIdToken_ ############";
    sectionEndSeparator  "############ End of: _sectionIdToken_ ############";
}

Now fieldAverage is read as a dictionary, so it should contrain a header. I therefore define a file fieldAverage in the system directory
Code:

/*--------------------------------*- C++ -*----------------------------------*\
| =========                |                                                |
| \\      /  F ield        | OpenFOAM: The Open Source CFD Toolbox          |
|  \\    /  O peration    | Version:  2.0.0                                |
|  \\  /    A nd          | Web:      www.OpenFOAM.com                      |
|    \\/    M anipulation  |                                                |
\*---------------------------------------------------------------------------*/
FoamFile
{
    version    2.0;
    format      ascii;
    class      dictionary;
    location    "system";
    object      fieldAverage;
    type        fieldAverage;
    enabled        true;
    outputControl  outputTime;
    functionObjectLibs ("libfieldFunctionObjects.so" );
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
type        fieldAverage;
enabled        true;
functionObjectLibs ("libfieldFunctionObjects.so" );
outputControl  outputTime;
fields
(
    U
    {
        mean        on;
        prime2Mean  off;
        base        time;
    }
);

At the start of the run I see that this file is read indeed (just as controlDict, fvScheme, fvSolutions). However, averaging does not start. In my idea, if this would be the case the whole set up should work:
the fileUpdate is used to update the fieldAverage dictionary file to enable field averaging at a certain time, and then the trackdictionary should ensured it got reread during the code. Unfortrunately: it does not work

Anybody see where is goes wrong ? Why is trackDictionary not rereading my fieldAverage file after it has been updated? If I change something in the other files in the list (controlDict, etc), they do get reread. I am sure that the file fieldAverage does get updated with the enable flag set to true. It is only not read again, even it is defined in trackDictionary.

To conclude: I have found a way around, and that is to not use trackDictionary, but to hard-code the fieldAverageDict include file in the controlDict it self. I then defined two controlDict: controlDict_0 and controlDict_1, which are idendentical except the enabling of the field averaging. I then use the fileUpdate library to update the controldict:
Code:

fileUpdate2
{
    type            timeActivatedFileUpdate;
    functionObjectLibs ("libutilityFunctionObjects.so");
    outputControl  timeStep;
    outputInterval  1;
    fileToUpdate    "$FOAM_CASE/system/controlDict";

    timeVsFile
    (
        (20    "$FOAM_CASE/system/controlDict_1")
    );
}

It works, but I dont like it because you have to always maintain two controlDicts which should be identical exept for one line. This is quite prone for errors: if you make a change in you controlDict, you have to consistently do it to the other.

Hopefully anybody sees what goes wrong with the trackDictionary/fileUpdate procedure. Any hints appreciated!

Regards

Eelco

stevenvanharen September 9, 2011 10:19

1 Attachment(s)
Hi Eelco,

We had the same problem, we added a keyword 'after' to the fieldAverage function. This will delay averaging untill the specified time is reached (this is specified in controlDict).

You can unzip this folder and compile it (wmake libso), in the controlDict which is in the folder you can see how to use it.

I hope this solves your problem, please let me know if you have any more questions.

Regards,

Steven

eelcovv September 9, 2011 10:47

field average after certain time works!
 
Hi Steven,

Many thanks! I compiled you piece of code and it works like a charm!
This is much more convenient than all the struggling with trackDict etc., so thanks again

Regards,
Eelco

gschaider September 10, 2011 17:39

Quote:

Originally Posted by eelcovv (Post 323547)
Hi Foamers,

I am quite often using simpleFunctionObjects (http://openfoamwiki.net/index.php/Co...unctionObjects), in order to do for instance averaging of data field. In this tread I want to find out how to start the averaging after a certain time such that first the flow can first develop.

For data averging over time I put in the controlDict

Code:

functions
(
    #include "fieldAverageDict"
);

and to add a file in the system directory called fieldAverageDict with the content

Code:

  fieldAverage1
    {
        type            fieldAverage;
        functionObjectLibs ("libfieldFunctionObjects.so" );
        enabled        true;
        outputControl  outputTime;
        fields
        (
            U
            {
                mean        on;
                prime2Mean  off;
                base        time;
            }
        );
    }

This works very well. As I said: quite often I want to start the averaging only after a certain time such that the flow can first fully develop. Of course I could stop my simulation, reset the field averaging and switch the enabled flag from false to true, and start again, however, this is not very convinient, especially if there is long waiting time in a queing system: if you stop you calculation, you have to go back into the queue again. Also, I could by hand modify fieldAverageDict, then controlDict, and that works too. However, I want to have it automatically.

The question is: how can I automatically start the averaging during a run after a certain time with the function objects?

According to the simpleFunctionobject manual there is an entry to the functionobject called 'after' which should define the time after which the function is read, however, this does not work. If I add after 100; (for instance), nothing happens, it just starts averaging right from the start.

The thing is that you mixed two things:

The function object fieldAverage (which averages a field during time) is part of the regular OF distribution (you used the right library in your example). There is a functionObject volumeAverage in the simpleFunctionObjects which does something different: it averages the field at a time and prints this single value.

The Information in the SFO-documentation about the after-parameter therefor applies only to volumeAverage but not fieldAverage

eelcovv September 12, 2011 05:11

fieldAverage vs volumeAverage
 
Hi Bernard,

You are right, the after option is found in the volumeAverage and not in the fieldAverage manual. I erroneously assumed that it would be available for the fieldAverage too. The modified library posted by Steven adds the after option to the fieldAverage. Perhaps the 'after' option can be added to the official release of fieldAverage as well?

About the trackDictionary: can you see why the reloading of the file fieldAverage does not work ? With this trick I tried to turn on averaging during a run (by modifying the file fieldAverage using fileUpdate), but some how is does not get reread by the solver, although it is defined in the trackDirctionary (and it is loaded at the start of the run, so it is seen correctly). Although with the modified fieldAverage library containing the 'after' option I don't use this trick anymore, I still think this combination of trackDictionary and fileUpdate can be quite powerful, so I would like it get it working. Any suggestion ?

Regards

Eelco

gschaider September 13, 2011 06:52

Quote:

Originally Posted by eelcovv (Post 323744)
Hi Bernard,

You are right, the after option is found in the volumeAverage and not in the fieldAverage manual. I erroneously assumed that it would be available for the fieldAverage too. The modified library posted by Steven adds the after option to the fieldAverage. Perhaps the 'after' option can be added to the official release of fieldAverage as well?

You're right. It makes even more sense for fieldAverage than for volumeAverage. But that is not my "jurisdiction". Write a bug-report at the OpenCFD-Mantis and suggest it as a feature

Quote:

Originally Posted by eelcovv (Post 323744)
About the trackDictionary: can you see why the reloading of the file fieldAverage does not work ? With this trick I tried to turn on averaging during a run (by modifying the file fieldAverage using fileUpdate), but some how is does not get reread by the solver, although it is defined in the trackDirctionary (and it is loaded at the start of the run, so it is seen correctly). Although with the modified fieldAverage library containing the 'after' option I don't use this trick anymore, I still think this combination of trackDictionary and fileUpdate can be quite powerful, so I would like it get it working. Any suggestion ?

Would have to look at the source of trackDictionary (that one I didn't implement). Just one question: you didn't show the whole controlDict. I assume that you set runTimeModifiable to "yes" (otherwise this won't work).

I'll ask Martin Beaudoin (the original author) about his opinion

eelcovv September 13, 2011 08:59

Hi Bernard

I have switched on runTimeModifiable to "yes" indeed. It looks as if this not taken into account though, since the dictionary is read correctly the first time, but not update when the file is updated. Well, it is a minor problem, may be I overlook something trivial.

Anyway, I have added the request for the -after option to the mantis opencfd bug report, so hopefully it will be updated soon.

Kind regards,

Eelco

gschaider September 14, 2011 04:54

Quote:

Originally Posted by eelcovv (Post 323941)
Hi Bernard

I have switched on runTimeModifiable to "yes" indeed. It looks as if this not taken into account though, since the dictionary is read correctly the first time, but not update when the file is updated. Well, it is a minor problem, may be I overlook something trivial.

One question: does the included file you modify trigger a reread of the functionObjects. I'm asking because I'm not quite sure how well the runTimeModifiable-business plays with included files

Quote:

Originally Posted by eelcovv (Post 323941)
Anyway, I have added the request for the -after option to the mantis opencfd bug report, so hopefully it will be updated soon.

Saw that. Although I'm not 100% sure whether they know the volumeAverage-FO you're talking about ;)

eelcovv September 15, 2011 08:22

1 Attachment(s)
I was aware of include files not being reread if they get updated. If you have an include file and changes something manually during the run, it does not get updated, so what I do is I touch touch the controlDict, and then also the include file gets reread.

My first attempt was therefore to touch the controlDict during the run if I want to have to reread the include file automatically, but I could not figure out how to do that.

However, with the trackDictionary trick, the file containing the fieldAveraging is never included in the controlDict anymore, because now it is defined in the trackDictionary list, i.e. it is read automatically. That is the reason why I have added a header to the include file, because trackDict expects that.

I have added a sample in which I show my construction with fileUpdate and trackDict. If you run, you can see that at time t=20 the fieldAverage file indeed gets updated, but it is not reread by trackDictionary. The first time steps it does get read.

Well, again, the trick is not required anymore with the custum fieldAverage lib (and hopefully later the newly updated fieldAverage including the -after option), however, it could be a quite powerful l construction. By the way, if controlDict (or one of the other files which are default in the reread list) is updated by fileUpdate, it is indeed read again. It only does not work for the user added file which are defined in trackDict.

Well, just run my sample and you will see what happens.

Regards,
Eelco

gschaider September 15, 2011 10:59

Quote:

Originally Posted by eelcovv (Post 324238)
I was aware of include files not being reread if they get updated. If you have an include file and changes something manually during the run, it does not get updated, so what I do is I touch touch the controlDict, and then also the include file gets reread.

My first attempt was therefore to touch the controlDict during the run if I want to have to reread the include file automatically, but I could not figure out how to do that.

However, with the trackDictionary trick, the file containing the fieldAveraging is never included in the controlDict anymore, because now it is defined in the trackDictionary list, i.e. it is read automatically. That is the reason why I have added a header to the include file, because trackDict expects that.

I have added a sample in which I show my construction with fileUpdate and trackDict. If you run, you can see that at time t=20 the fieldAverage file indeed gets updated, but it is not reread by trackDictionary. The first time steps it does get read.

Well, again, the trick is not required anymore with the custum fieldAverage lib (and hopefully later the newly updated fieldAverage including the -after option), however, it could be a quite powerful l construction. By the way, if controlDict (or one of the other files which are default in the reread list) is updated by fileUpdate, it is indeed read again. It only does not work for the user added file which are defined in trackDict.

Well, just run my sample and you will see what happens.

Regards,
Eelco

I tried it and it works under 1.7 but no under 2.0 on my machine.
Added
Code:

   
wait {
        type systemCall;
        outputControl timeStep;
        outputInterval 1;
        writeCalls (
            "sleep 1"
        );
    }

to functions to make it wait 1 second after each timestep and tried "touch system/*" in another terminal. On 2.0 trackDict never picks it up. On 1.7 its strange as it varies which files are picked up and which aren't. Could you post a bug-report at http://sourceforge.net/apps/mantisbt...l_bug_page.php (include that test-case) and I'll ask Martin to have a look at it

Bernhard

eelcovv September 19, 2011 05:11

Bug in trackDictionary is reported now.

I saw that the -after option has been added to the new fieldAveraging functionobject now. Thanks for the quick feature fix!

Regards

Eelco

BigPapi34 May 24, 2012 10:33

Starting field averaging using libFunctionObject after certain time
 
Hi there,

This would be ideal for me if a similar method could be used to obtain the average for expressions created using swak4Foam.

Does anyone know if this is possible?

gschaider May 24, 2012 10:58

Quote:

Originally Posted by BigPapi34 (Post 362922)
Hi there,

This would be ideal for me if a similar method could be used to obtain the average for expressions created using swak4Foam.

Does anyone know if this is possible?

With "average" you mean "time-average"? Yep.

Or do you mean this "after" thing (it is not obvious what you're referring to): all swak-functionObjects based on the simpleFunctionObjects have a "hidden" after-parameter that starts them after a certain time. For FOs that are not based on that there is also a solution but that is a bit more challenging.

@time-average: if you want to time-average a whole field the solution would be to create a field foo with expressionField and then tell the regular fieldAverage-FO to average foo. For values on patches things are a bit more complicated but possible too (keywords: storedVariables and readAndUpdateFields)

But if you tell me what you're trying to achieve then I can probably assist you ... if you promise to do a little write-up on the solution on the Wiki (doesn't have to be long)

BigPapi34 May 25, 2012 04:30

Starting field averaging using libFunctionObject after certain time
 
Thanks for responding so quickly!

Sorry, I should have been clearer about my question. I mean time-averaged, yes.

Basically I have a simple setup with inlet and outlet patches and I currently use swak4Foam (patchExpression) in order to find the pressure difference as well as using some other custom expressions which I log and then plot via gnuplot.

My goal is to be able to log (and potentially plot) time-averaged values (such as pressure difference) from the patchExpression outputs taking, for example, the last 25% of the iterations during the run.

What would you suggest would be the best way forward?

gschaider May 25, 2012 05:39

Quote:

Originally Posted by BigPapi34 (Post 363048)
Thanks for responding so quickly!

Sorry, I should have been clearer about my question. I mean time-averaged, yes.

Basically I have a simple setup with inlet and outlet patches and I currently use swak4Foam (patchExpression) in order to find the pressure difference as well as using some other custom expressions which I log and then plot via gnuplot.

My goal is to be able to log (and potentially plot) time-averaged values (such as pressure difference) from the patchExpression outputs taking, for example, the last 25% of the iterations during the run.

What would you suggest would be the best way forward?

The pragmatic says: "Read the written timeseries into Excel/R/Matlab/Mathematica and calculate the timeseries there". The fanatic says "My stuff can do that". If we assume a constant timestep something like (note that I'm directly typing this here so there might by syntax-errors)
Code:

timeAverageP {
  type patchExpression;
  verbose true;
  expression "averageP";
  variables (
    "relax=0.9;"
    "averageP=relax*averageP+(1-relax)*p;"
  );
  storedVariables (
      {
        name averageP;
        initialValue "p";.
      }
  );
  accumulations (
      min
      max
      average // this is not area weighted!!! Results are only correct if all patch faces are the same size
  );
}

would generate a floating average where the influence of old timesteps vanishes exponentially. A fixed time-window where timesteps suddently "drop out" is not possible (I think swak would need arrays for that and that is can of worms I don't want to open).

This should work with any swak4Foam-version from the last year.

The nice thing is that the approach preserves the individual values until the accumulation. With the "readAndUpdateFields"-functionObject added to the development version you can generate a postprocessing field where a similar groovyBC is defined (so you can have a look at the spatial distribution in paraview .... or for instance record the pressure maxima to see "what is the maximum pressure where on the patch")

If the above approach works for you it would be nice if you add it as a paragraph to the swak-Wiki-page

BigPapi34 May 25, 2012 07:00

Starting field averaging using libFunctionObject after certain time
 
I suppose you're right regarding reading the information in excel although it would be easier (well, nicer) to do everything in OF if possible like you say.

I've just added the code you supplied me with to the controlDict and from what I can see it works well in terms of the pressures at the inlet/outlet, looks to be a good workaround there!

I am wondering if you could assist one final time by confirming how a custom expression can be introduced to the time-averaged code so that the expression itself can be time-averaged? Probably very simple and I may have been silly by asking this! I have a generic piece of code here:

PRESSURE_DIFF
{
type patchExpression;
variables ( "pOut{patch'outlet}=sum(p*area())/sum(area());");
accumulations (
average
);
patches (
inlet
);
expression "pOut-p";
verbose true;
}

Again, I am probably being silly but I would appreciate any help - new Foamer and exploring its capabilities (impressed so far!).

gschaider May 25, 2012 07:37

Quote:

Originally Posted by BigPapi34 (Post 363086)
I suppose you're right regarding reading the information in excel although it would be easier (well, nicer) to do everything in OF if possible like you say.

I've just added the code you supplied me with to the controlDict and from what I can see it works well in terms of the pressures at the inlet/outlet, looks to be a good workaround there!

Yeah. But it's good to know when to go to the experts (== use another program)

Quote:

Originally Posted by BigPapi34 (Post 363086)
I am wondering if you could assist one final time by confirming how a custom expression can be introduced to the time-averaged code so that the expression itself can be time-averaged? Probably very simple and I may have been silly by asking this! I have a generic piece of code here:

PRESSURE_DIFF
{
type patchExpression;
variables ( "pOut{patch'outlet}=sum(p*area())/sum(area());");
accumulations (
average
);
patches (
inlet
);
expression "pOut-p";
verbose true;
}

Again, I am probably being silly but I would appreciate any help - new Foamer and exploring its capabilities (impressed so far!).

That's easy: Add a variable "pDiff=factor*(pOut-p)*(1-factor)*pDiff;", make it a stored variable with initial value "0" and finally make the expression "pDiff" ....

aka August 7, 2012 11:48

Quote:

Originally Posted by eelcovv (Post 324634)
Bug in trackDictionary is reported now.

I saw that the -after option has been added to the new fieldAveraging functionobject now. Thanks for the quick feature fix!

Regards

Eelco

The field-average tool works by calculating the mean and turbulent quantities from the time when "Mean" and "prime2Mean" are on. I think the turbulent quantities should be calculated after the mean is calculated for some time or when it becomes nearly constant. For example, the mean for the first few time steps can be affected by the instantaneous velocity which can significantly affect the mean turbulence quantities. To get a roughly constant UMean field, I first make off the "prime2Mean" and keep "Mean" on for some time. Later, I put "prime2Mean" on and make my simulation run for a desired period time. However, I found that the field-average tool reads the "fieldAverageProperties file" from "uniform folder" in the current time step and takes either the total iteration or time count and these values are used for the calculation of both "Mean" and "prime2Mean" quantities for the next time steps. This brings underestimation of the turbulence quantities. I believe it is mainly due to the "Dt" count which is taken from the previously started "Mean", not separately for "prime2Mean". I really appreciate if someone has a suggestion or solution for this problem. I put the code for fieldaverage from fieldAverageTemplates.C file below.

scalar dt = obr_.time().deltaTValue();


forAll(faItems_, i)
{
if
(
faItems_[i].prime2Mean()
&& meanFieldList[i].size()
&& prime2MeanFieldList[i].size()
)
{
const word& fieldName = faItems_[i].fieldName();
const fieldType1& baseField =
obr_.lookupObject<fieldType1>(fieldName);
const fieldType1& meanField =
obr_.lookupObject<fieldType1>(meanFieldList[i]);
fieldType2& prime2MeanField = const_cast<fieldType2&>
(
obr_.lookupObject<fieldType2>(prime2MeanFieldList[i])
);


scalar Dt = totalTime_[i];
if (faItems_[i].iterBase())
{
dt = 1.0;
Dt = scalar(totalIter_[i]);
}


scalar alpha = (Dt - dt)/Dt;
scalar beta = dt/Dt;
if (faItems_[i].window() > 0)
{
const scalar w = faItems_[i].window();


if (Dt - dt >= w)
{
alpha = (w - dt)/w;
beta = dt/w;
}
}


prime2MeanField =
alpha*prime2MeanField
+ beta*sqr(baseField)
- sqr(meanField);
}
}
}

eelcovv August 9, 2012 05:05

I just replied to you private message.

Again: good back ground on this topic can be found here

http://www.cfd-online.com/Forums/ope...ome-grids.html

Regards
Eelco

aka August 10, 2012 02:22

Thanks a lot, I read the link and it is so helpful. I understand most of the mathematical derivations however, I am not still convinced in using the current mean value instead of the final mean. Gregor used in his mathematical derivation and sentence the following and it is not still clear for me. "The point is you want to have a variance every time step but your final mean value is unknown, therefore you take the current mean value. But once you use the current mean value the old mean values has to be taken out."


All times are GMT -4. The time now is 20:45.