Closed milankl closed 1 month ago
I hear you saying that you would use particle_advection = ParticleAdvection2D(spectral_grid, every_n_timesteps=1)
i.e. advection on everyt time step, the last commit makes sure that also in that case particle advection is never executed on the 1st step in first_timesteps!
(which is a half_step) to have 0, 0p, 1p, 2p, 3p, ...
(dynamics 0 0 1 2 3, particle advection p) not 0p, 0p, 1p, 2p, 3p, ...
which would cause an initial offset by dt/2.
Time stepping for particles is now
gridded!
at $t=n\Delta t$ (even though the clock time didn't step forward yet)So that (PA Particle advection, otherwise dynamics)
Note that the notion of time somewhat different
We may illustrate this as follows. Note two half steps in
first_timsteps!
to get from 0 to 0 (Euler forward, not counted) and from 0 to 1 (unfiltered leapfrog)Dynamics (step i):
| -- | -- | ------ | ------ | ------ | ------ | ------ | ------ | ------ |
0 0 1 2 3 4 5 6 7 8
Particle advection (step j, every 4th dynamics step)| -- | -- | ------ | ------ | ------ | ------ | ------ | ------ | ------ |
0->P1 C1->1->P2 C2->2
So that to get from particle step j=0 to j=1 it's the average betwee predictor step P1 which uses velocities at i=0 (stored during initialisation) and corrector step C1 which uses velocities at i=4; which is also directly used to interpolate and store velocities for predictor step P2 which is then averaged with corrector step C2 using velocities at i=8 to get from particle step j=1 to j=2 when the dynamics have reached i=8.