-
Notifications
You must be signed in to change notification settings - Fork 133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[OUTDATED; DO NOT MERGE] Vectorial summing of particle displacement at end of kernel loop #1388
[OUTDATED; DO NOT MERGE] Vectorial summing of particle displacement at end of kernel loop #1388
Conversation
As calling functions is not possible anymore with new implementation
Having to remove 'once' because this does not work in parquet's column-based format
And fixing flake8 error because of merge with plotting-removal PR
I've done some exploration of how best to update the kernels. See this gist that explores this on a very minimal example ('nanoparcels') Bottom line is that the cleanest working implementation (cell 6 in the gist) is something like (only for def concatenated_kernels(particle, fieldset, time):
# set dlon to zero at beginning of loop
dlon = 0
# sample fields at (time, location), and add to dlon when particle moves
particle.p = fieldset.P(particle.time, particle.lon)
dlon += fieldset.U(particle.time, particle.lon) * particle.dt
# write the particle if needed (depending on outputdt)
particle.write()
# update the particle time and particle location
particle.time += particle.dt
particle.lon += dlon So this requires a |
Also cleaning path creation for Parquet file
I've been playing around with his a bit today. The obvious major change is that custom kernels will need to compute displacements, rather than positions. That's easy enough (just subtract the current position particle.lon or particle.lat). One minor issue is that an unbeaching kernel is still not commutable. You must first perform advection and custom kernels, and only then identify the updated position of the particle (particle.lon + particle_dlon for e.g.) and apply an unbeaching kernel. For custom kernels that set custom variables (e.g. a variable to track if a particle goes below 500m), I think this would be even more prominent. Should you check an 'if statement' before any movement, and set the custom variable at the current timestep (based on the previous timestep position), or check the 'if statement' after all displacements and set at the current timestep? Any thoughts? |
…rning In recent version of numpy, we see a "RuntimeWarning: invalid value encountered in cast". This commit fixes that
As it was not advertised/used, and with the new lazy loading schemes is not needed. It does complicate the code significantly
Thanks @michaeldenes, for your feedback on this Draft PR. You're right that actions like unteaching will still not be commutable; kernels where the action depends on position will generally have that problem. The point is that with this PR some can commute. It also means we might be able to get rid of the SummedFields (which was essentially an implementation of vectorial summing for Advection only). I think/hope that actions like unteaching could be treated in Error/RecoveryKernels, which need a major upgrade anyways. We still use the RecoveryKernel code from v0.9 essentially unchanged, and it is very slow. That's point e. in the list at the top of this page. But I'm first focussing on point a, since that's a sine qua non... |
…at_end_of_kernel_list
for more information, see https://pre-commit.ci
So they are available in the kernel
for more information, see https://pre-commit.ci
Keeping field_outputdt for writing Fields (only in Scipy mode)
Moving stmt to main loop; proper closing of files, and support for outputdt in JIT
Via an extra table metadata with one row
for more information, see https://pre-commit.ci
… of https://github.com/OceanParcels/parcels into vectorial_summing_particle_moves_at_end_of_kernel_list
for more information, see https://pre-commit.ci
Only works in scipy mode for now; probably because memory is not shared between C and python
This significantly speeds up writing in sql
for more information, see https://pre-commit.ci
Closing this PR as #1402 is now the working implementation of this idea |
(note: the PR is now superseded by #1402, which was reset to caf7418 (before the merging of #1399), because Parquet and sqlite writing had in practice far worse performance to zarr)
Until now, the way that
Kernel
-concatenation worked in Parcels meant that the execution of multipleKernels
was generally not commutable: for example first advection a particle and then letting it sink would lead to a different result than first sinking and then advecting. That is because particle positions were updated within each kernel, instead of the vectorial summing of displacements that would be more appropriate (and would ensure commutability).More problematically, while the particle positions would be updated within a kernel, the time was generally only updated at the end. This meant that
Field
-sampling could give unexpected results (e.g. when sampling was done at the new location but the old time).To solve these issues, in this PR I propose that individual Kernels compute displacements (
particle_dlon
,particle_dlat
andparticle_ddepth
) and that these displacements are only added to the particle locations when all kernels have been executed for a timestep dt.This means that the workflow for each particle
p
and each timet
becomesparticle_dlon = particle_dlat = particle_ddepth = 0
Kernels
, including samplingKernels
, and let theKernels
updateparticle_dlon
,particle_dlat
andparticle_ddepth
when requiredp
at timet
(if needed)t += dt
and particle locations toparticle.lon += particle_dlon
etcNote that this workflow means that particles will be written at
t=0
(and there is no need anymore for a separate initial values sampling step!), but not anymore att=runtime
(the last tilmestep), unless we also change that the particle loop is executed one time more at the end (tbd).Issues/questions that need to be explored or implemented:
t=runtime
(see comment above)particles_backups
are stil needed now that particles are not moved in a KernelSince this is a major overhaul that can change results, I suggest to make this PR (when merged) part of v2.5.0