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

Repeat last timestep with a smaller deltaT for guaranteed accuracy

Register Blogs Community New Posts Updated Threads Search

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   September 30, 2014, 11:36
Default Repeat last timestep with a smaller deltaT for guaranteed accuracy
  #1
New Member
 
Join Date: Feb 2014
Posts: 24
Rep Power: 12
hajott is on a distinguished road
Hello,
what is the recommended way to repeat a time step in time dependent solvers, when a given accuracy criterion is not met at the end of the actual time step?

The existing solvers, which can work with "adjustableTimeStep yes;" in controlDict, set the FUTURE time step based on the courant number or other criteria and don't care if the courant number is too large AFTER the time step has been solved.

But what if my solver decides that the actual step has been calculated with a too large deltaT, and I have to dismiss the latest solution, and start over with a smaller deltaT? My idea is to implement something like this:

Code:
while(runTime.run()){
  runTime++;
  solve();
  while (!isAccurate()){
    undoSolve();
    runTime.setDeltaT(0.5*runTime.deltaTValue();
    solve();
  }
}
But how do I implement "undoSolve()"? All fields, their values stored from previous timesteps and all other conditions must be reset as if the last "solve()" didn't happen. Does OpenFOAM offer an easy solution for this, or do I have to backup and possibly restore all fields?

Regards
hajott is offline   Reply With Quote

Old   September 30, 2014, 16:07
Default
  #2
Senior Member
 
Alexey Matveichev
Join Date: Aug 2011
Location: Nancy, France
Posts: 1,930
Rep Power: 38
alexeym has a spectacular aura aboutalexeym has a spectacular aura about
Send a message via Skype™ to alexeym
Hi,

you can try doing something like:

Code:
while(runTime.run()){
  for (;;){
    solve();
    if (!isAccurate())
    {
      runTime.setDeltaT(0.5*runTime.deltaTValue();
      // Restoring old value of fields
        // Scalar fields
        {
            HashTable<volScalarField*> flds =
                lookupClass<volScalarField>();

            forAllIter(HashTable<volScalarField*>, flds, iter)
            {
                if (iter()->nOldTimes() < 1)
                {
                        continue;
                }

                iter()->internalField() = iter()->oldTime();
            }
        }

        // Vector fields
        {
            HashTable<volScalarField*> flds =
                lookupClass<volScalarField>();

            forAllIter(HashTable<volScalarField*>, flds, iter)
            {
                if (iter()->nOldTimes() < 1)
                {
                        continue;
                }

                iter()->internalField() = iter()->oldTime();
            }
        }
     }
     else
     {
        break;
     }
  }
  runTime++;
}
see http://foam.sourceforge.net/docs/cpp...c7d231aa6b5f3f for more thoughts.
alexeym is offline   Reply With Quote

Old   October 1, 2014, 03:46
Default
  #3
New Member
 
Join Date: Feb 2014
Posts: 24
Rep Power: 12
hajott is on a distinguished road
Thank you, your suggestion looks very promising. I didn't know about lookupClass<T>, which is very helpful, because with this method I cannot forget to backup and restore those fields that I add to the solver during the development process.

One more question about GeometricField.oldTime(): I have a partial understanding about this method from reading the implementation. At which point within the runTime loop is the oldest (for example t(n-3)) history discarded if my solver needs the actual and too previous timesteps (t(n),t(n-1),t(n-2))?

I wonder if t(n-2) would be restored by your code at "iter()->internalField() = iter()->oldTime();" or if it has been discarded already at that point.

Finally, your example only resets the internalField to the old values. I suppose I have to reset the boundaryField, too, using iter()->correctBoundaryConditions(), don't I?
hajott is offline   Reply With Quote

Old   October 1, 2014, 08:31
Default
  #4
Senior Member
 
Alexey Matveichev
Join Date: Aug 2011
Location: Nancy, France
Posts: 1,930
Rep Power: 38
alexeym has a spectacular aura aboutalexeym has a spectacular aura about
Send a message via Skype™ to alexeym
The idea of lookupClass<T> was taken from src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.C:305.

Quote:
I wonder if t(n-2) would be restored by your code at "iter()->internalField() = iter()->oldTime();" or if it has been discarded already at that point.
Don't know, guess you have to use experimental verification.

Quote:
Finally, your example only resets the internalField to the old values. I suppose I have to reset the boundaryField, too, using iter()->correctBoundaryConditions(), don't I?
Well, yes. Thought, partly it depends on what you are doing in solve method.
alexeym is offline   Reply With Quote

Reply


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
Unexpected deltaT decrease in pimpleFoam simulation robyTKD OpenFOAM Running, Solving & CFD 9 June 27, 2014 06:52
Modifying sonicFoam to run with variable timestep - strange results dalaron OpenFOAM Programming & Development 1 September 2, 2013 07:21
Smaller time step results in less accuracy!! farshadn12 Main CFD Forum 10 May 3, 2013 15:09
smaller timestep leads not to converge vovogoal CFX 5 October 17, 2011 09:10
IcoFsiFoam simulation crashes when using a smaller timestep mathieu OpenFOAM Running, Solving & CFD 1 May 17, 2009 03:54


All times are GMT -4. The time now is 16:24.