gandalfcode / gandalf

GANDALF (Graphical Astrophysics code for N-body Dynamics And Lagrangian Fluids)
GNU General Public License v2.0
46 stars 12 forks source link

Timestep limiter #91

Closed rbooth200 closed 7 years ago

rbooth200 commented 8 years ago

I'm beginning this pull request to spark discussion, rather than because it is ready to merge. It contains two methods to limit the timesteps:

The first one works by finding the largest dt such that r_ij * vsig_ij > dt for all pair in the simulation. This is done in an extra tree walk, which will need making MPI compatible later.

The second one just checks for particles that have too big timesteps compared to their neighbours and reduces their timestep at the next synchronization point. It is not exactly conservative since dQdt is used to predict dQ, but it seems to work fine for the sedov test.

In doing this work, I noticed that we don't enforce the levelneib heirachy properly at the moment. While the issue of reducing the time-step particles in the middle of their step conservatively is near impossible (although limiter 2 does is this in a non-conservative way). However, in addition we don't enforce the hierarchy at the start of the timestep either, which I think is a significant flaw. The reason that the heirachy is not enforced is that levelneib is computed before the new timesteps are evaluated, and after the new timesteps are calculated the levels shift, leading to some particles needing a smaller timestep than the one they are on because some of their neighbours are now on smaller timesteps.

I think that enforcing the hierarchy would improve the results when no extra timestep limiters are used or when the non-conservative limiters are used. This is because the fluxes are computed at the start of the timestep. Thus if we can predict that we are going to need a smaller timestep at the beginning of it we can reduce it immediately allowing a fully conservative update of these particles. With the global limiter switched on fewer particles tend to have level differences greater than requested, but some still do.

In SPH we enforce the hierarchy by iterating the whole timestep for particles on levels that are too big, but this is difficult to do correctly for the meshless because tracking the update of dQ is difficult. I have included an attemp at this by iterating on only the flux calculation but it doesn't work properly. I believe it would be much easier to iterate on the gradient calculation until the timesteps are set properly, but currently the gradients are done before the timestep calcution. Placing it after the timestep calculation has the issue that levelneib is not known in advance since we calculate it during the gradient calculation.

I would think that the most effective solution would be as follows: 1) Compute a gather based estimate of levelneib during the density calculation. 2) Compute the new timesteps. 3) Compute the full levelneib during the gradient calculation. To do this we would need to iterate on particles that had their timestep reduced to ensure it is propograted to all its neighbours. Step 3) could also be done in another tree walk to avoid recomputing the gradients.

The questions I have are as follows: How important do you think this is? Should we expend the extra cycles (probably only a few to 10 per cent) on making it more accurate? How should we implement it? I believe before the flux calculation is the only reasonable way.

dhubber commented 8 years ago

Okay, so first of all, I'm guessing this is implicitly about the meshless scheme since I assume 'conservative' is supposed to be in the context of a conservative FV scheme (and I'm not sure how that would relate to SPH). In that case, yes the Saitoh & Makino scheme is not conservative. I've been trying to think of ways to modify it to make it conservative but nothing satisfactory just yet.

Btw, I'm assuming this branch split off from timing since there seems to be plenty of the same code changes there? In fact, is there any different code since the above discussion talks about ideas and not about what has actually been done? Just wondering since I was thinking maybe I'm wasting time looking at this same code again :-) Actually, looking at the commit history there are a few commits more in this branch. Maybe we should (at some point soon?) accept the timing pull request and rebase this to master so we can see more clearly the code differences before delving too deep into this?

Some immediate questions/clarifications that come to mind

Assuming I understand it all correctly, my first impression is that it could work sure. I'll have to think about it some more and look at the ordering of the main loop but seems to make sense. I have just noticed that the UpdateAllProperties is called twice in the main loop (with self-gravity) but not sure if that makes much difference here.

rbooth200 commented 8 years ago

Hi David,

This is indeed currently only referring to the Meshless. To see the changes, just compare this with the timing branch. I'll rebase back onto it in a second to make it easer.

I'll try to clarify your questions. At the moment there are two working timestep limiters in this branch. For example try the sedov test with Nlevels=10 and with/without the two limiters. I agree that the Springel-type tree walk (conservative limiter) will need modifying with MPI. I'll discuss with Giovanni the best way to do this and report back... Obviously we need to get the MPI working with the meshless before we worry about this.

The main other point I was discussing is a bit seperate, and that is we don't enforce the timestep heirachy properly. I was describing what I think is the best way to do this in the meshless because, if we do it, we must do it at the start of the timestep to ensure conservation. At the moment we just accept that its wrong unless the Saitoh & Makino type limiter I added is used, in which case it is done at the end of the time-step once the 'error' in the levels has been detected.

After discussing it with Giovanni, we thought that we should probably just leave it as it is. With the new Springel-type limiter we don't really need to enforce the timestep hierarchy since the particles should be guaranteed to have small enough steps anyway. While the Saitoh & Makino timestep limiter would benefit from getting the time-step correct at the start of the step, even without with the energy error seems to be very small (1e-6) in test problems such as the sedov test.

giovanni-rosotti commented 7 years ago

I should now have implemented MPI with the conservative timestep limiter (note also that maxsound was not initiliased in the KDTree and OctTree, only for the BruteForceTree. I love you valgrind!), it appers to work correctly. The timestep limiter does a remarkable job I should say.

giovanni-rosotti commented 7 years ago

Done. In general, when we have so little modifications to suggest, we can do them directly.

Are we ready to merge this branch? I think so. David should do it as me and Richard committed code. Let's be quick because the to do list is long.

rbooth200 commented 7 years ago

I agree that this is ready to go...

dhubber commented 7 years ago

ok, having a look at this now.

dhubber commented 7 years ago

ok, I've had run a few tests with this, both with and without the timestep limiter (although not with MPI), and it seems to work fine without any problems on my machine. I also had a quick look at the changes to the code and there's nothing I'm overly worried about. The only extra thing I'd request before accepting is to add this new 'time_step_limiter' parameter to the userguide.tex file, with a small one sentence description of all options (in the same style as all other parameters). We probably need to go through and update the userguide at some point anyway but it's probably worth trying to keep new parameters updated whenever they are added. Then I think it's fine to be merged!

rbooth200 commented 7 years ago

I've now added the documentation