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

A question about PIMPLE algorithm

Register Blogs Members List Search Today's Posts Mark Forums Read

Like Tree2Likes
  • 1 Post By Tobermory
  • 1 Post By mostanad

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   March 18, 2025, 01:57
Default A question about PIMPLE algorithm
  #1
Senior Member
 
mohammad
Join Date: Sep 2015
Posts: 301
Rep Power: 12
mostanad is on a distinguished road
Dear FOAMERS,
I hope you are all doing well. I have a general question about PIMPLE algorithm thta might be a bit silly!
Supposing that we have a temporal term like \frac{d\rho}{dT}.
If I use PIMPLE and there would be nOuterCorrectors>1, \rho_{old} in the temporal disctritization by \frac{\rho-\rho_{old}}{\Delta T} is the previous timestep value, or the value of previous Outercorrector iteration? As I knwo, in the temporal discritization, we always consider this as rho.oldTime(). What does this oldTime() return in PIMPLE?
mostanad is offline   Reply With Quote

Old   March 18, 2025, 02:49
Default
  #2
Member
 
Eren
Join Date: Aug 2018
Posts: 92
Rep Power: 9
ErenC is on a distinguished road
Time marches after you reach the maximum number of outerIterations. You can see that in your log (or terminal).
ErenC is offline   Reply With Quote

Old   March 18, 2025, 03:05
Default
  #3
Senior Member
 
mohammad
Join Date: Sep 2015
Posts: 301
Rep Power: 12
mostanad is on a distinguished road
Quote:
Originally Posted by ErenC View Post
Time marches after you reach the maximum number of outerIterations. You can see that in your log (or terminal).
I dont have an actual case to see it now. About the theory, you mean time marching happens in the last outerIteration. And what about the iterations up to that? What value is used?
mostanad is offline   Reply With Quote

Old   March 22, 2025, 05:26
Default
  #4
Senior Member
 
Join Date: Apr 2020
Location: UK
Posts: 825
Rep Power: 16
Tobermory will become famous soon enough
This has been quite an interesting rabbit hole to dive down - the "simplest" questions in OF often are! TLDR: the oldTime() value in a pimple loop is the solution from the last full solver iteration, ie does not change during the pimple loops (which essentially is what Eren was saying above).

Want the proof? Here is my attempt. Using rhoPimpleFoam from OF8 as a solver (I assume you are using a compressible pimple solver, from your discussion of drho/dt), we can see the pimple looping part of the code as:
Code:
         while (pimple.loop())
         {
                 .... update rho, U*, E, p & U, turb
         }
and if you dive into pimpleControl::loop() you'll find:
Code:
bool Foam::pimpleControl::loop()
 {
     read();
     if (!pimpleLoop::loop(*this))
     {
         updateFinal();
         return false;
     }
     storePrevIterFields();
     updateFinal();
     return true;
 }
where read() reads the solver controls from fvSolution, pimpleLoop::loop() checks to see if we are converged yet and does some admin, and updateFinal() flags whether this is the final pimple iteration or not. Note however the call to storePrevIterFields() for all but the final pimple loop - as the name suggests, this stores the previous pimple iter solution for the new time level (but only if relaxation is being applied to the field ... otherwise why would you want to store it?):
Code:
 template<class Type>
 void Foam::singleRegionSolutionControl::storePrevIterTypeFields() const
 {
     typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
     HashTable<fieldType*>
         flds(mesh_.objectRegistry::lookupClass<fieldType>());
 
     forAllIter(typename HashTable<fieldType*>, flds, iter)
     {
         fieldType& fld = *iter();
         const word& fName = fld.name();
         size_t prevIterField = fName.find("PrevIter");
         if (prevIterField == word::npos && mesh_.relaxField(fName))
         {
             fld.storePrevIter();
         }
     }
 }
But what about the oldTime data? That is really tricky to find quickly, and in the end the following post threw some light on it for me: When does OpenFOAM execute "storeOldTime" ?. As is so common, OF does something really efficient and clever (and really difficult to parse initially!) and only stores oldTime when it needs to, i.e. when it is called. Essentially, a call to GeometricField:ldTime() returns the oldTime data, but first either creates an empty oldTime field if the field doesn't already exist (very first time step of a simulation?) or calls storeOldTimes():

Code:
 template<class Type, template<class> class PatchField, class GeoMesh>
 const Foam::GeometricField<Type, PatchField, GeoMesh>&
 Foam::GeometricField<Type, PatchField, GeoMesh>::oldTime() const
 {
     if (!field0Ptr_)
     {
         field0Ptr_ = new GeometricField<Type, PatchField, GeoMesh>
         (
             IOobject
             (
                 this->name() + "_0",
                 this->time().timeName(),
                 this->db(),
                 IOobject::NO_READ,
                 IOobject::NO_WRITE,
                 this->registerObject()
             ),
             *this
         );
     }
     else
     {
         storeOldTimes();
     }
 
     return *field0Ptr_;
 }
Now we are getting close. GeometricField::storeOldTimes() is:
Code:
 template<class Type, template<class> class PatchField, class GeoMesh>
 void Foam::GeometricField<Type, PatchField, GeoMesh>::storeOldTimes() const
 {
     if
     (
         field0Ptr_
      && timeIndex_ != this->time().timeIndex()
      && !(
             this->name().size() > 2
          && this->name()(this->name().size()-2, 2) == "_0"
          )
     )
     {
         storeOldTime();
     }
 
     // Correct time index
     timeIndex_ = this->time().timeIndex();
 }
and here we see that the call to storeOldTime() is only made if the timeIndex is not the same as the current solution time. In other words, for the interim pimple iterations, where the solver time is unchanging, the oldTime fields are not updated!

Time for a coffee ...
mostanad likes this.
Tobermory is offline   Reply With Quote

Old   March 23, 2025, 17:49
Default
  #5
Senior Member
 
mohammad
Join Date: Sep 2015
Posts: 301
Rep Power: 12
mostanad is on a distinguished road
Quote:
Originally Posted by Tobermory View Post
Want the proof?
.
.
.
.
Time for a coffee ...
Wow. Thanks Tobermory for your enlightening reply.
Tobermory likes this.
mostanad is offline   Reply With Quote

Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

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
PIMPLE – the value of the final under-relaxation factor Zbynek OpenFOAM 9 December 22, 2023 05:26
PIMPLE algorithm unstability ram_7 OpenFOAM Running, Solving & CFD 4 February 8, 2018 09:43
PIMPLE algorithm -- Energy equation gdeneyer OpenFOAM Running, Solving & CFD 2 May 2, 2012 08:32
Question regarding the F2F particle tracking algorithm implementation. andrewryan OpenFOAM 2 October 22, 2009 01:55
SIMPLER Algorithm question Erik Main CFD Forum 1 May 23, 2004 03:57


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