-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Seeding dynamic and associated initialisation logic (super-droplet in…
…jection during simulation) (#1367) Co-authored-by: claresinger <[email protected]> Co-authored-by: jtbuch <[email protected]>
- Loading branch information
1 parent
ec1f515
commit f1e1df9
Showing
26 changed files
with
1,449 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
""" CPU implementation of backend methods for particle injections """ | ||
|
||
from functools import cached_property | ||
|
||
import numba | ||
|
||
from PySDM.backends.impl_common.backend_methods import BackendMethods | ||
|
||
|
||
class SeedingMethods(BackendMethods): # pylint: disable=too-few-public-methods | ||
@cached_property | ||
def _seeding(self): | ||
@numba.njit(**{**self.default_jit_flags, "parallel": False}) | ||
def body( # pylint: disable=too-many-arguments | ||
idx, | ||
multiplicity, | ||
extensive_attributes, | ||
seeded_particle_index, | ||
seeded_particle_multiplicity, | ||
seeded_particle_extensive_attributes, | ||
number_of_super_particles_to_inject: int, | ||
): | ||
number_of_super_particles_already_injected = 0 | ||
# TODO #1387 start enumerating from the end of valid particle set | ||
for i, mult in enumerate(multiplicity): | ||
if ( | ||
number_of_super_particles_to_inject | ||
== number_of_super_particles_already_injected | ||
): | ||
break | ||
if mult == 0: | ||
idx[i] = -1 | ||
s = seeded_particle_index[ | ||
number_of_super_particles_already_injected | ||
] | ||
number_of_super_particles_already_injected += 1 | ||
multiplicity[i] = seeded_particle_multiplicity[s] | ||
for a in range(len(extensive_attributes)): | ||
extensive_attributes[a, i] = ( | ||
seeded_particle_extensive_attributes[a, s] | ||
) | ||
assert ( | ||
number_of_super_particles_to_inject | ||
== number_of_super_particles_already_injected | ||
) | ||
|
||
return body | ||
|
||
def seeding( | ||
self, | ||
*, | ||
idx, | ||
multiplicity, | ||
extensive_attributes, | ||
seeded_particle_index, | ||
seeded_particle_multiplicity, | ||
seeded_particle_extensive_attributes, | ||
number_of_super_particles_to_inject: int, | ||
): | ||
self._seeding( | ||
idx=idx.data, | ||
multiplicity=multiplicity.data, | ||
extensive_attributes=extensive_attributes.data, | ||
seeded_particle_index=seeded_particle_index.data, | ||
seeded_particle_multiplicity=seeded_particle_multiplicity.data, | ||
seeded_particle_extensive_attributes=seeded_particle_extensive_attributes.data, | ||
number_of_super_particles_to_inject=number_of_super_particles_to_inject, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
""" particle injection handling, requires initalising a simulation with | ||
enough particles flagged with NaN multiplicity (translated to zeros | ||
at multiplicity discretisation """ | ||
|
||
from collections.abc import Sized | ||
|
||
import numpy as np | ||
|
||
from PySDM.dynamics.impl import register_dynamic | ||
from PySDM.initialisation import discretise_multiplicities | ||
|
||
|
||
@register_dynamic() | ||
class Seeding: | ||
def __init__( | ||
self, | ||
*, | ||
super_droplet_injection_rate: callable, | ||
seeded_particle_extensive_attributes: dict, | ||
seeded_particle_multiplicity: Sized, | ||
): | ||
for attr in seeded_particle_extensive_attributes.values(): | ||
assert len(seeded_particle_multiplicity) == len(attr) | ||
self.particulator = None | ||
self.super_droplet_injection_rate = super_droplet_injection_rate | ||
self.seeded_particle_extensive_attributes = seeded_particle_extensive_attributes | ||
self.seeded_particle_multiplicity = seeded_particle_multiplicity | ||
self.rnd = None | ||
self.u01 = None | ||
self.index = None | ||
|
||
def register(self, builder): | ||
self.particulator = builder.particulator | ||
|
||
def post_register_setup_when_attributes_are_known(self): | ||
if tuple(self.particulator.attributes.get_extensive_attribute_keys()) != tuple( | ||
self.seeded_particle_extensive_attributes.keys() | ||
): | ||
raise ValueError( | ||
f"extensive attributes ({self.seeded_particle_extensive_attributes.keys()})" | ||
" do not match those used in particulator" | ||
f" ({self.particulator.attributes.get_extensive_attribute_keys()})" | ||
) | ||
|
||
self.index = self.particulator.Index.identity_index( | ||
len(self.seeded_particle_multiplicity) | ||
) | ||
if len(self.seeded_particle_multiplicity) > 1: | ||
self.rnd = self.particulator.Random( | ||
len(self.seeded_particle_multiplicity), self.particulator.formulae.seed | ||
) | ||
self.u01 = self.particulator.Storage.empty( | ||
len(self.seeded_particle_multiplicity), dtype=float | ||
) | ||
self.seeded_particle_multiplicity = ( | ||
self.particulator.IndexedStorage.from_ndarray( | ||
self.index, | ||
discretise_multiplicities( | ||
np.asarray(self.seeded_particle_multiplicity) | ||
), | ||
) | ||
) | ||
self.seeded_particle_extensive_attributes = ( | ||
self.particulator.IndexedStorage.from_ndarray( | ||
self.index, | ||
np.asarray(list(self.seeded_particle_extensive_attributes.values())), | ||
) | ||
) | ||
|
||
def __call__(self): | ||
if self.particulator.n_steps == 0: | ||
self.post_register_setup_when_attributes_are_known() | ||
|
||
time = self.particulator.n_steps * self.particulator.dt | ||
number_of_super_particles_to_inject = self.super_droplet_injection_rate(time) | ||
|
||
if number_of_super_particles_to_inject > 0: | ||
assert number_of_super_particles_to_inject <= len( | ||
self.seeded_particle_multiplicity | ||
) | ||
|
||
if self.rnd is not None: | ||
self.u01.urand(self.rnd) | ||
# TODO #1387 make shuffle smarter | ||
# e.g. don't need to shuffle if only one type of seed particle | ||
# or if the number of super particles to inject | ||
# is equal to the number of possible seeds | ||
self.index.shuffle(self.u01) | ||
self.particulator.seeding( | ||
seeded_particle_index=self.index, | ||
number_of_super_particles_to_inject=number_of_super_particles_to_inject, | ||
seeded_particle_multiplicity=self.seeded_particle_multiplicity, | ||
seeded_particle_extensive_attributes=self.seeded_particle_extensive_attributes, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
from .settings import Settings | ||
from .simulation import Simulation |
Oops, something went wrong.