CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   OpenFOAM Programming & Development (https://www.cfd-online.com/Forums/openfoam-programming-development/)
-   -   value of previous time step (https://www.cfd-online.com/Forums/openfoam-programming-development/92961-value-previous-time-step.html)

lulo September 30, 2011 04:21

value of previous time step
 
Hi
In OpenFoam is it possible to know the old time step value of any variable.
I need to store a vectorField and use it in the next time step.
I had a look in the forum and found the commands:

fieldName.storeOldTime(); // to store an old time field
fieldName.oldTime(); // to recover it

I tried to compile these and got the error:

#
error: 'class Foam::vectorField' has no member named 'storeOldTime'
error: 'class Foam::vectorField' has no member named 'storeOldTime'
#

My question is, how to handle with those?

Luca

nimasam September 30, 2011 06:42

did u try ?

fieldName.old();

benk September 30, 2011 09:07

Quote:

Originally Posted by lulo (Post 326198)
Hi
In OpenFoam is it possible to know the old time step value of any variable.
I need to store a vectorField and use it in the next time step.


Take a look at this post: http://www.cfd-online.com/Forums/ope...tml#post298878

If I remember correctly, the times are stored in an array and should be accessible through:
Code:

runTime.times()[indexNumber].value()

lulo September 30, 2011 09:14

I still get the same kind of error.
I probably use a wrong sintax.
If I wanted to store the vectorField a (for instance) for then using it in the next time step calculation, what should I write?

I tried these and all gave errors:

#
a.old();
a.oldTime();
a.StoreOldTime();
#

Bernhard September 30, 2011 09:18

Quote:

Originally Posted by benk (Post 326243)
Take a look at this post: http://www.cfd-online.com/Forums/ope...tml#post298878

If I remember correctly, the times are stored in an array and should be accessible through:
Code:

runTime.times()[indexNumber].value()

This will give you the fields of the previous output time, that is usually different from the previous time step.

marupio September 30, 2011 09:36

Use U.oldTime(). You don't need to tell it to store the old time... it figures that out on its own based on how many .oldTime() requests the GeometricField gets in a timestep. You can ask it how many old times it is storing: .nOldTimes() (I think). The first timestep, even if it is resuming in the middle of an old run, all the .oldTime() are the same.

lulo September 30, 2011 10:22

Thanks to all for replying

I tried U.oldTime() and it works but when I apply it to my vectorField 'myField' it gives:
error: 'class Foam::vectorField' has no member named 'oldTime()'

I am solving a system of equations by iteration and I want to give the current solution as first guess for the next time step.

marupio September 30, 2011 10:29

Oh, it's a vectorField, not a volVectorField? Yeah, vectorFields are just vectorLists with math. There's no fancy oldTime archiving. In that case, just create a vectorField like a temp variable.

Code:

// Initialize
vectorField oldVectors(myVectors.size());
// Save old vectors:
oldVectors = myVectors;
// etc..

You only need to create a "oldVectors" object if myVectors doesn't still have the previous iteration in it when starting the first iteration of the new timestep. When I put adaptive timestep control into mine, that's when I had to start keep old versions.

lulo October 3, 2011 04:19

Thanks for the help

I have tried the suggested:
Code:

// Initialize
vectorField oldVectors(myVectors.size());
// Save old vectors:
oldVectors = myVectors;
// etc..

I had no success.
I changed my vectorField to a volVectorField so that I could use fieldName.oldTime().
When I compile I do not know how to initialize my variable:

Code:

...
xn.oldTime();

for (int mm=0; mm < counter; mm++)    // iteration process
            {
            xn = ...    // in this loop the volVectorField xn is created by an iterative process
            }

xn.storeOldTime();
...

This gives me the error:
error: 'xn' was not declared in this scope

I want to use the results of the iteration as first guess for the next time step.

marupio October 4, 2011 08:12

> Had no success.
What was the error? Was it a compile error, or did it not hold the data. This is a simple vector field copy we're doing - it shouldn't be too hard.

The constructors for volVectorField are listed in GeometricField.H.

lulo October 5, 2011 04:49

Hi.
The solver compiles whitout problems.
What I can see is that every time step the volVectorField with the initial guesses is not updated.

Code:

volVectorField xn      //initialize the volVectorField with the initial guesses being 0,0,0
(
IOobject
(
"xn",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
dimensionedVector
(
"xn",
dimensionSet(0,0,0,0,0,0,0),
vector::zero
)
);

xn.oldTime();      // this should overwrite the xn with the results obtained in the previous step
                          // I THINK THIS IS NOT WORKING!!

for (int mm=0; mm < counter; mm++)    // iteration process
            {
            xn = ...    // in this loop the volVectorField xn is created by an iterative process
            }

xn.storeOldTime();          // This should store the xn results to be used as initial guesses
                                      // for the next time step
...

I am sure I am doing something wrong using this OldTime() and storeOldTime() function.
I just do not know how to use them properly.

Thanks in advance

marupio October 5, 2011 10:57

Yes, oldTime works much simpler than you think. It is all totally automatic in the background. You never need to call storeOldTime()... and the xn.oldTime() immediately gives you the value from the previous timestep. runTime is clever enough to count how many .oldTime()'s you use, and automatically stores that many in its database.

I think you are probably using a local object. I was always confused as to why xn wouldn't *already* have the previous timestep's value at the start of the next timestep. If you are using a local object, it is erased and reconstructed at every timestep. In this case, oldTime() won't work, and neither would a simpler vectorField copy we talked about either. Where are you constructing your xn object? Will the program encounter the constructor once and only once throughout multiple timestep iterations? If not, move the constructor above your while(runTime.loop())... possibly even into createFields.H. If this is the problem, that's probably why it didn't work when you were using a standard vectorField. I'd recommend returning to the vectorField framework if possible.

lulo October 6, 2011 17:03

Hi

Thanks a lot!!
I moved the volVectorField constructor in createFields.H and now the value at the next time step is overwritten correctly.

Why do you suggest to return to the vectorField? I could do that but it will take me time due to my poor programming knowledge.

How should the constructor for the vectorField in createFields.H?

Code:

vectorField xn = vector::zero.boundaryField()[bottom_patch];
I would like to create the vectorField 'xn' of the initial guesses being (0.05,0.001,0.001) and the number of vectors should be the same as the number of cells of my 'bottom_patch'.

I tried also with the volVectorField but without success:
Code:

volVectorField xn   
(
IOobject
(
"xn",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
dimensionedVector
(
"xn",
dimensionSet(0,0,0,0,0,0,0),
//vector::zero  // THIS WORKS BUT I DON'T WANT ZERO VECTORS
uniform (0.05,0.001,0.001) // THIS IS NOT COMPILING
)
);

Thanks

Luca

marupio October 6, 2011 18:23

I don't think you even need to use the .oldTime because the previous values will still be in the vectorField at the start of the next timestep. I suggest using a vectorField if you are not doing any math on the boundary because you are carrying a lot of unnecessary extra memory in the boundary field, as well as performing unnecessary operations there. It's your perogative.

As for the compile error, that's probably because it doesn't know what a uniform is. Try replacing the word 'uniform' with the word 'vector'.

lulo October 7, 2011 11:39

Thanks

I undersatand the memory issue. So I am trying to use a vectorField. I want to define the vectorField in createFields.H. I tried different ways:

Code:

                vectorField xn = vector::zero.boundaryField()[bottom_patch];

                vectorField xn
                (
                IOobject
                        (
                        "xn",
                        runTime.timeName(),
                        mesh,
                        IOobject::NO_READ,
                        IOobject::AUTO_WRITE
                        ),
                        mesh.boundaryMesh().findPatchID(bottom_patch),
                );

                vectorField xn
                (
                IOobject
                        (
                        "xn",
                        runTime.timeName(),
                        mesh,
                        IOobject::NO_READ,
                        IOobject::AUTO_WRITE
                        ),
                        mesh.boundaryMesh()[bottom_patch],
                );

I simply want to iniitialize a vectorField with the number of vectors being equal to the number of cells of my ´bottom_patch´.

Any idea??

marupio October 8, 2011 11:25

You could use this constructor:

Code:

vectorField nameOfVectorField(sizeOfVectorField);
 
// or
 
vectorField nameOfVectorField(sizeOfVectorField, initialValueForAllCells);

To know the size of the bottom patch, you could use: U.boundaryField()[patchNumber].size(). The tricky part is patchNumber, as you need to figure out what index number OpenFOAM assigned to the patch you want - "bottom_patch". Not sure how to do this. I think you need to loop through all the patches and compare .name() with "boundary_patch". You only need to initialize the values (second constructor above) if you are not assigning a value to them first off.

lulo October 14, 2011 11:49

I have been trying to use the vectorField without success. So I will keep my volVectorField.

Many thanks for your help!!

latvietis February 7, 2013 19:16

Greetings!

Sorry for bringing up such an old thread but the title is rather corresponding to my issue.

I have a dependent variable like g=g(a). But my solution has really bad convergence and to improve it there is an idea to use weighted combination of values from different time steps. It should look something like this where k is iteration step.

g(k+1)=g(a(k)+a(k-1))

How I can get these values in OF?

Is something like this correct? I mean is a.oldTime value 'more previous' than simply value of a?

Code:

g=g(a+a.oldTime())

kobelak May 21, 2013 12:08

Hi all!

I have to modify a solver and I'd like to do some calculations with values of U of all the previous time steps, not only the time step immediately earlier the current one. For instance, which is the way "to call" the value of U at (i-5) time step, if i is the current one (in run time)?

Any hints to do this?

Thanks in advance

Danilo

ThomasV November 5, 2013 04:47

Hi!

I tried the .oldTime() method but it didn't work for me - I always got the very same values for both my new volScalarField itself as well as for the fieldname.oldTime() expression...

I once saw a .prevIter() method in one of OpenFoam's solvers so I tried it that way. The compiler then asked me to do a field.storePrevIter() command too and this actually worked. So maybe someone should clarify if the oldTime method got deprecated in the meantime or not. What works is this:

Code:

fieldname.storePrevIter();

<< DO THE CALCULATIONS / UPDATES ON YOUR FIELD AFTERWARDS >>

fieldname.prevIter();


akidess November 8, 2013 09:47

oldTime and prevIter both are useful, nothing is deprecated. As stated by David, you can use oldTime to go back multiple time steps (not just one as prevIter), and it manages the storing automatically. That of course only works if you actually need values from a previous timestep, not from subcycle iterations. The latter case is where you would typically use prevIter/storePrevIter, but of course you can also use it to store data from a previous time step.

- Anton

ooo February 10, 2014 17:16

Does U.oldTime() gives us the value of previous time step, or last value of the field?
assume that we have this situation :

while (runTime.loop())
{
U = somevalue1 ;
.
.
U = somevalue2 ;

x = U.oldTime();
}

So x is somevalue1 or is the value of U at the previous time step ?

ahmmedshakil February 10, 2014 20:10

U.oldTime() will give the values of U at previous time step.

openfoammaofnepo March 7, 2015 15:35

Dear Marupio,

Your reply below is very helpful, but I have still the problems about

when "erased and reconstructed at every timestep" happens? At the beginning of each time step or at the end of the time step?

Thank you very much. OFFO


Quote:

Originally Posted by marupio (Post 326786)
Yes, oldTime works much simpler than you think. It is all totally automatic in the background. You never need to call storeOldTime()... and the xn.oldTime() immediately gives you the value from the previous timestep. runTime is clever enough to count how many .oldTime()'s you use, and automatically stores that many in its database.

I think you are probably using a local object. I was always confused as to why xn wouldn't *already* have the previous timestep's value at the start of the next timestep. If you are using a local object, it is erased and reconstructed at every timestep. In this case, oldTime() won't work, and neither would a simpler vectorField copy we talked about either. Where are you constructing your xn object? Will the program encounter the constructor once and only once throughout multiple timestep iterations? If not, move the constructor above your while(runTime.loop())... possibly even into createFields.H. If this is the problem, that's probably why it didn't work when you were using a standard vectorField. I'd recommend returning to the vectorField framework if possible.


GrpOne123 October 7, 2023 21:51

hello
 
Quote:

Originally Posted by ahmmedshakil (Post 474363)
U.oldTime() will give the values of U at previous time step.

I want to get the mesh.Cf() of a patch in oldTime , how can i do that?
I try mseh.Cf().oldTime().boundaryField()[patch], it is no works.


All times are GMT -4. The time now is 11:36.