# Actual Courant Numbers much greater than maxCo in interFoam with Local Time Stepping

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

July 31, 2020, 01:01
Actual Courant Numbers much greater than maxCo in interFoam with Local Time Stepping
#1
Senior Member

Claudio Boezio
Join Date: May 2020
Location: Europe
Posts: 137
Rep Power: 7
I'm a bit confused about the meaning of the maxCo parameter of the PIMPLE algorithm. The case is a ship hull resistance calculation in calm water, similar to the DTCHull tutorial case. The simulation works fine, however I've noticed that the Courant Numbers reported by the functionObject CourantNo greatly exceed the Courant Number specified by maxCo in the PIMPLE dictionary. The case is solved by interFoam with ddtSchemes set to defeult localEuler (Local Time Stepping). I've checked the forum for relevant threads and read through the documentation about localEulerDdtScheme and Courant Number, but I couldn't learn how Local Time Stepping actually works and how it relates to the Courant Number. I've found out that the Courant Number appears to be tied to rDeltaT.

When looking at the CourantNo field in ParaView, the portion of the domain with the finest mesh and close to the hull is the one with the high Courant Numbers greater than specified, see picture below.

In the case, I've set maxCo to 5 and get reported Courant Numbers of greater than 1000. Changing the value of maxCo affects the solution time and its stability, so it still has an influence. My question is, how can I estimate an adequate value for maxCo when LTS is used, without having to run the simulation several times with different values? What relationship exists between the specified maxCo and the actual Courant Numbers?

I would be grateful for any hints, thanks!

PIMPLE Dictionary used:

Code:
```PIMPLE
{
momentumPredictor   yes;

nOuterCorrectors    2;
nCorrectors         3;
nNonOrthogonalCorrectors 1;

maxCo               5;
maxAlphaCo          2;

rDeltaTSmoothingCoeff 0.05;
rDeltaTDampingCoeff 0.5;
nAlphaSweepIter     0;
maxDeltaT           1;
}```
Output of last time step of simulation:

Code:
```functionObjects::CourantNo CourantNumber writing field: CourantNo
fieldMinMax MinMaxDomain write:
...
min(CourantNo) = 0.409736 in cell 543810 at location (6.02834 -0.0494664 0.329774) on processor 1
max(CourantNo) = 1220.72 in cell 376934 at location (5.98567 -0.360553 0.0190734) on processor 1```
Attached Images
 DTCHull-Fr0174 maxCo greater than 5.jpg (27.7 KB, 78 views)

 September 30, 2020, 14:15 #2 New Member     Serge Join Date: Nov 2019 Posts: 22 Rep Power: 6 Hello, Claudio! Seems I have a similar problems with maxCo number.... Did you anything known about "relationship exists between the specified maxCo and the actual Courant Numbers"? Respectfully, Serge lourencosm likes this.

 October 1, 2020, 02:43 #3 Senior Member   Gerhard Holzinger Join Date: Feb 2012 Location: Austria Posts: 339 Rep Power: 28 Are you sure the PIMPLE dictionary is the right place for maxCo? IIRC it used to go into the controlDict: see the User Guide Ship Designer likes this.

 October 1, 2020, 04:07 #4 Senior Member   Carlo_P Join Date: May 2019 Location: Italy Posts: 176 Rep Power: 8 As I kwon, the max courant number for transient simulation has to go in the controlDIct, for LTS should go in fvSolution. The docu for LTS is very poor.... lourencosm likes this.

October 1, 2020, 20:49
#5
Senior Member

Claudio Boezio
Join Date: May 2020
Location: Europe
Posts: 137
Rep Power: 7
Hello Kil,

I was able to obtain only a small insight after my post.

Generally in the cases I calculate, the higher maxCo, the more correctors PIMPLE needs to maintain stability. The former reduces the time steps needed to get a certain result (wave pattern) but it also tends to destabilize the solution. The latter can maintain stability but adds to the solution time. In the end, a balance between the two needs to be found. Thus my interest in understanding how it works, without having to start and abort several calculations with different maxCo values.

By filtering the maxCo in ParaView, I've noticed that it correlates with the refinement levels of the mesh, but only up to a certain point. It makes sense, since the Courant No. is dependent on flow velocity in a cell and its size. Now, I've always assumed that to calculate the critical Courant No. in a case, one should take the highest flow velocity of the smallest cell. It appears that Local Time Stepping or PIMPLE, not sure which, takes the largest cell(s) instead to calculate the time step so that maxCo is observed with the given velocity.

When I look at the cells of the 1st refinement level, Co is double that of maxCo. At the 2nd level it is 4 times that much and at every additional refinement level, the Co doubles. This is the case up to refinement level 4-5, where this conclusion is not consistent anymore and even higher Co values are shown or for cells far away from that level of refinement. The cells with the highest Co values are not consistent with the highest refinement level of the mesh but tend instead to disperse randomly near the geometry.

Quote:
 Are you sure the PIMPLE dictionary is the right place for maxCo? IIRC it used to go into the controlDict: see the User Guide
No, I'm not sure. The PIMPLE documentation page is not finished yet, so there's no list available with all its settings and what they do: https://www.openfoam.com/documentati...rs-pimple.html
Is there a detailed code guide for OpenFOAM Foundation edition?

However, to support that it might be the proper place to put it, there's the following:
1. The code snippet of fvSolution is taken from the DTCHull tutorial, with some modifications. The maxCo setting was already there. I trust that tutorials contain correct code.
2. This other tutorial by Wolfdynamics also has that setting, including some useful comments, in fvSolution. http://www.wolfdynamics.com/tutorials.html?id=149 These guys are professionals and I trust their code to be correct too. Btw, that tutorial case solves like a charm and I warmly recommend it to everyone that wants to learn how to solve hull resistance cases.
3. Finally, if I change the value of maxCo within fvSolution, the solution changes as well in terms of solution stability and wave pattern development related to time step. This suggests that maxCo in there is read and interpreted in some way.
Happy to hear your thoughts! Fair winds, Claudio

October 2, 2020, 03:04
#6
Senior Member

Carlo_P
Join Date: May 2019
Location: Italy
Posts: 176
Rep Power: 8
Quote:
 Originally Posted by Ship Designer Hello Kil, Now, I've always assumed that to calculate the critical Courant No. in a case, one should take the highest flow velocity of the smallest cell. It appears that Local Time Stepping or PIMPLE, not sure which, takes the largest cell(s) instead to calculate the time step so that maxCo is observed with the given velocity. When I look at the cells of the 1st refinement level, Co is double that of maxCo. At the 2nd level it is 4 times that much and at every additional refinement level, the Co doubles. This is the case up to refinement level 4-5, where this conclusion is not consistent anymore and even higher Co values are shown or for cells far away from that level of refinement. The cells with the highest Co values are not consistent with the highest refinement level of the mesh but tend instead to disperse randomly near the geometry.

Probably, but I'm not sure, the LTS will calculate a "standard" maxCo with the first refinement.

I also notice that the Co is very higher than the maxCo writeen in fvSolution.

Quote:
 Originally Posted by Ship Designer No, I'm not sure. The PIMPLE documentation page is not finished yet, so there's no list available with all its settings and what they do: https://www.openfoam.com/documentati...rs-pimple.html Is there a detailed code guide for OpenFOAM Foundation edition? However, to support that it might be the proper place to put it, there's the following: The code snippet of fvSolution is taken from the DTCHull tutorial, with some modifications. The maxCo setting was already there. I trust that tutorials contain correct code. This other tutorial by Wolfdynamics also has that setting, including some useful comments, in fvSolution. http://www.wolfdynamics.com/tutorials.html?id=149 These guys are professionals and I trust their code to be correct too. Btw, that tutorial case solves like a charm and I warmly recommend it to everyone that wants to learn how to solve hull resistance cases. Finally, if I change the value of maxCo within fvSolution, the solution changes as well in terms of solution stability and wave pattern development related to time step. This suggests that maxCo in there is read and interpreted in some way. Happy to hear your thoughts! Fair winds, Claudio

For this point, I'm very sure the that maxCo should go in the fvSolution.

 October 10, 2020, 13:09 #7 New Member     Serge Join Date: Nov 2019 Posts: 22 Rep Power: 6 Thank you so much for your response! It's a pity that I couldn't figure out how it works. And what's the range for the maxCo calculation should be considered acceptable? I've heard that it depends on the type of solver (explicit or implicit solvers), but I haven't seen any specific recommendations. P.S. Claudio, what utility do you use to determine the height of the first cell?

 October 12, 2020, 06:26 #8 Senior Member   Carlo_P Join Date: May 2019 Location: Italy Posts: 176 Rep Power: 8 For explicity solver (but there is no one in openfoam, as I know), the maxCo should be 1. For implicit, there is no theoretical limit, but 10-50 is the maximum value recommended quite always

October 13, 2020, 17:03
#9
Senior Member

Claudio Boezio
Join Date: May 2020
Location: Europe
Posts: 137
Rep Power: 7
Quote:
 And what's the range for the maxCo calculation should be considered acceptable? […] P.S. Claudio, what utility do you use to determine the height of the first cell?
Hi Serge, in my case I can determine the best maxCo by trial and error or judging by experience. So far I've used blockMesh and thus I know from its coordinates and subdivisions what the dimensions of the largest cells are, if this is what you mean.

Quote:
 For explicity solver (but there is no one in openfoam, as I know), the maxCo should be 1. For implicit, there is no theoretical limit, but 10-50 is the maximum value recommended quite always
Hello Carlo_P, this makes me wonder then, why the lid-driven cavity tutorial at section "2.1.1.4 Control" suggests using a timestep such to fulfil Co < 1. See https://www.openfoam.com/documentati...utorialse2.php

Best wishes, Claudio

 October 14, 2020, 04:05 #10 Senior Member   Carlo_P Join Date: May 2019 Location: Italy Posts: 176 Rep Power: 8 Hey Claudio, sorry, I was not clear. For the explicit you must use a Co< 1. For implicit, it is up to you. It is depend on the accuracy and the complex of the simulations. If you use a number of subiterations = 1, it is good practise to use a Co<=1. If you use a number of subiterations > 1, it is good practise to have a Co around 10-50. But I run also simulations with C0=100 and 5-10 subiterations. It was stable and accuate too.

 October 14, 2020, 04:40 #11 Senior Member     Jan Join Date: Jul 2009 Location: Hamburg Posts: 137 Rep Power: 19 Hi All, correct, for LTS the maxCo is defined in fvSolution, whereas for "normal" time schemes the maxCo is defined in the controlDict. As far as I know, for LTS you can not use the functionObject to monitor the Courant number, as the timeStep defined in the controlDict does not have any relation to the timeStep used in the simulation. You have an individual timeStep in each cell, and due to the definition of LTS the maxCo in each cell is always guaranteed. Hope this helps, Jan lourencosm and Carlo_P like this.

October 25, 2020, 12:56
#12
New Member

Serge
Join Date: Nov 2019
Posts: 22
Rep Power: 6
Quote:
 Originally Posted by Ship Designer Hi Serge, in my case I can determine the best maxCo by trial and error or judging by experience. So far I've used blockMesh and thus I know from its coordinates and subdivisions what the dimensions of the largest cells are, if this is what you mean.
I will describe my problem in more detail.

I'm interesting in ship's hull resistance simulation in full scale (nature size). I'm use blockMesh to create a domain mesh (zero level or basic mesh). After that, I'm have started snappyHexMesh and in this step I have some problems...

I need to simulate the boundary layer with the addLayersControls function. I know the required thickness of the boundary layer, the first cell height and and the number of calculated points in the boundary layer, but I can't understand how to make a settings of the addLayersControls function to make it correctly.

In my case:

first cell height yh= 0.00356 m
height of the boundary layer delta=0.01523 m
number of calculated points = 15

I've tried to use different setting but the results were wrong....
I need to understand how to properly configure the following settings:
-relativeSizes
-finalLayerThickness / firstLayerThikness / thikness
-minThickness
-nGrow

I will be glad if you can help with something.

Respectfully,
Serge

October 25, 2020, 13:01
#13
New Member

Serge
Join Date: Nov 2019
Posts: 22
Rep Power: 6
Quote:
 Originally Posted by Carlo_P For explicity solver (but there is no one in openfoam, as I know), the maxCo should be 1. For implicit, there is no theoretical limit, but 10-50 is the maximum value recommended quite always

Many thanks, Carlo!

October 25, 2020, 13:20
#14
New Member

Serge
Join Date: Nov 2019
Posts: 22
Rep Power: 6
Quote:
 Originally Posted by JNSN Hi All, As far as I know, for LTS you can not use the functionObject to monitor the Courant number
Yes, I've tried to use this function for the CFL controls but it's doesn't works.

Quote:
 Originally Posted by JNSN , as the timeStep defined in the controlDict does not have any relation to the timeStep used in the simulation.
but if I change the timeStep in the controlDict it changes and the total time spent on calculations increases/decreases and it happens that the simulation crashes or doesn't start. What does it mean? Why then need the timeStep in the controlDict?

Quote:
 Originally Posted by JNSN You have an individual timeStep in each cell, and due to the definition of LTS the maxCo in each cell is always guaranteed.
Does this mean that we only need to adjust the maxCo parameter without timeStep?

Respectfully,
Serge

October 28, 2020, 04:26
#15
Senior Member

Carlo_P
Join Date: May 2019
Location: Italy
Posts: 176
Rep Power: 8
Quote:
 Originally Posted by Kil I will describe my problem in more detail. I'm interesting in ship's hull resistance simulation in full scale (nature size). I'm use blockMesh to create a domain mesh (zero level or basic mesh). After that, I'm have started snappyHexMesh and in this step I have some problems... I need to simulate the boundary layer with the addLayersControls function. I know the required thickness of the boundary layer, the first cell height and and the number of calculated points in the boundary layer, but I can't understand how to make a settings of the addLayersControls function to make it correctly. In my case: first cell height yh= 0.00356 m height of the boundary layer delta=0.01523 m number of calculated points = 15 I've tried to use different setting but the results were wrong.... I need to understand how to properly configure the following settings: -relativeSizes -finalLayerThickness / firstLayerThikness / thikness -minThickness -nGrow I will be glad if you can help with something. Respectfully, Serge

For this problem, you can use this simple calculator:
https://cfdfeaservice.it/index.php/2...snappyhexmesh/

November 9, 2020, 13:33
#16
New Member

Serge
Join Date: Nov 2019
Posts: 22
Rep Power: 6
Quote:
 Originally Posted by Carlo_P For this problem, you can use this simple calculator: https://cfdfeaservice.it/index.php/2...snappyhexmesh/
Thank you very much for your help!!!

 August 5, 2022, 11:08 #17 New Member   wangjikang Join Date: Apr 2022 Posts: 4 Rep Power: 4 i am curious about the ratio of local Co to MaxCo changing with the mesh . as you say is in another way presented blow: MaxCo :choose the box with Maxium U magnitude among the smallest cell Volume，then calculate the Δt; acctual MaxCo：choose the box with Maxium U magnitude among the bigest cell volume 。then calculate local step MaxCo(acctual Maxco) by using the Δt calculated by MaxCo . to assume mesh size is changed to 1/k ,then smallest δx will be 1/k than before。because the inteporlate principle ，the max U magnitude among the smallest cell will not change，so Maxco=1 with the condition that δx is 1/k of before and max U do not change make the Δt be 1/k of before。 Then wo talk about the acctual Maxco,when the mesh is 1/k of before,the max U also do not change ,so acctual Maxco keep its former value (1.i have the assumation that when 1/k sizing the mesh normally,each new cell is 1/k then before 2.sizing the mesh with 1/k(k＞1) factor，the sum of all the mesh with smallest cell is equal to before in the view of acctual computional space，so U maxium do not change because of interporlate；however ，when sizing with k （k＞1）factor，the sum of all the mesh with bigest cell is k times of before in the view of acctual computional space，which must lead to U maxium change to much bigger result )

 Tags courant number, interfoam, local time stepping, maxco