Repository navigation
Fix changing dt in kernel #3019
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
base: main
Are you sure you want to change the base?
Changes from all commits
1d72831
c81e442
f3d6902
865cd02
0cd6a8c
3557709
3233f66
8c3c18c
07c0bf1
e28a80f
6f49df5
1d0bbe2
3e806dc
9341967
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,7 +5,9 @@ | |
| FieldSet, | ||
| KernelWarning, | ||
| Particle, | ||
| ParticleFile, | ||
| ParticleSet, | ||
| StatusCode, | ||
| Variable, | ||
| ) | ||
| from parcels._core.kernel import Kernel | ||
|
|
@@ -166,8 +168,47 @@ def SampleP(particles, fieldset): # pragma: no cover | |
| assert np.allclose(lons[0], 0.2) | ||
|
|
||
|
|
||
| @pytest.mark.xfail(reason="Modifying dt in a kernel doesn't work GH2765") | ||
| def test_dt_modify_in_kernel(fieldset): | ||
| @pytest.mark.parametrize(("with_output", "expected_num_kernel_loops"), [(True, 7), (False, 5)]) | ||
| def test_dt_modify_in_kernel(fieldset, tmp_parquet, with_output, expected_num_kernel_loops): | ||
| npart = 10 | ||
| TestParticle = Particle.add_variable(Variable("num_kernel_loops", dtype=np.float32, initial=0)) | ||
| pset = ParticleSet(fieldset, pclass=TestParticle, x=np.linspace(0, 1, npart), y=[0] * npart) | ||
|
|
||
| def ModifyDt(particles, fieldset): # pragma: no cover | ||
| particles.num_kernel_loops += 1 | ||
| particles.dt = 4 | ||
| particles[particles.x > 0.8].state = StatusCode.Delete | ||
|
|
||
| runtime = 17 | ||
| output = ParticleFile(tmp_parquet, outputdt=5.0) if with_output else None | ||
| pset.execute(ModifyDt, runtime=runtime, dt=1.0, output_file=output, verbose_progress=False) | ||
|
|
||
| np.testing.assert_allclose(pset.t, runtime) | ||
| np.testing.assert_allclose(pset.num_kernel_loops, expected_num_kernel_loops) | ||
|
|
||
|
|
||
| def test_dt_modify_in_kernel_vector(fieldset): | ||
| TestParticle = Particle.add_variable(Variable("num_kernel_loops", dtype=np.float32, initial=0)) | ||
| pset = ParticleSet(fieldset, pclass=TestParticle, x=[0.5], y=[0]) | ||
|
|
||
| dt_in_kernel = np.array([1, 4, 3, 4, 5, 5, 10, 2, 2]) | ||
| fieldset.add_context("dt_in_kernel", dt_in_kernel) | ||
|
|
||
| def ModifyDt_FromArray(particles, fieldset): # pragma: no cover | ||
| i = np.asarray(particles.num_kernel_loops).astype(int) | ||
| particles.dt = fieldset.dt_in_kernel[i] | ||
| assert particles.t == np.cumsum(np.r_[0, fieldset.dt_in_kernel])[i] | ||
| particles.num_kernel_loops += 1 | ||
|
|
||
| runtime = sum(dt_in_kernel) | ||
| expected_num_kernel_loops = len(dt_in_kernel) | ||
| pset.execute(ModifyDt_FromArray, runtime=runtime, dt=1.0) | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should the test in #2765 be added too? As far as I can tell these tests don't actually verify that the (fyi I get the same behavior for this test on this branch as is documented in the original issue) def test_dt_modify_in_kernel(fieldset):
TestParticle = Particle.add_variable(Variable("age", dtype=np.float32, initial=0))
pset = ParticleSet(fieldset, pclass=TestParticle, x=[0.5], y=[0])
def ModifyDt(particles, fieldset): # pragma: no cover
particles.age += particles.dt
particles.dt = 2
runtime = 10
expected_age = 1 + 2 * (runtime - 2) # 1 for the first step; 2 for the remaining steps (except last)
pset.execute(ModifyDt, runtime=runtime, dt=1.0)
np.testing.assert_allclose(pset.t[0], runtime)
np.testing.assert_allclose(pset.age[0], expected_age)
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good call, @wyatt-fluidnumerics, I had forgotten about the original test. While working on that test, I have found a cleaner solution, now implemented in 9341967. This may also fix your other questions/comments? (Note ny the way, that the |
||
| np.testing.assert_allclose(pset.t[0], runtime) | ||
| np.testing.assert_allclose(pset.num_kernel_loops[0], expected_num_kernel_loops) | ||
|
|
||
|
|
||
| def test_dt_modify_age_in_kernel(fieldset): | ||
| TestParticle = Particle.add_variable(Variable("age", dtype=np.float32, initial=0)) | ||
| pset = ParticleSet(fieldset, pclass=TestParticle, x=[0.5], y=[0]) | ||
|
|
||
|
|
@@ -176,7 +217,7 @@ def ModifyDt(particles, fieldset): # pragma: no cover | |
| particles.dt = 2 | ||
|
|
||
| runtime = 10 | ||
| expected_age = 1 + 2 * (runtime - 2) # 1 for the first step; 2 for the remaining steps (except last) | ||
| expected_age = 1 + 2 * (runtime / 2 - 1) # 1 for the first step; 2 for the remaining steps (except last) | ||
| pset.execute(ModifyDt, runtime=runtime, dt=1.0) | ||
| np.testing.assert_allclose(pset.t[0], runtime) | ||
| np.testing.assert_allclose(pset.age[0], expected_age) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that this TODO is not relevant now that we have https://docs.parcels-code.org/en/latest/user_guide/examples/tutorial_write_in_kernel.html#writing-on-particle-deletion, so can be ignored