Skip to content

Commit 723e62c

Browse files
authored
introducing @register_environment decorator to solve environment-reuse issue (#1373)
1 parent 55e0cce commit 723e62c

File tree

46 files changed

+4828
-192
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+4828
-192
lines changed

PySDM/builder.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@ def set_environment(self, environment):
4949
def _set_environment(self, environment):
5050
if self.particulator.environment is not None:
5151
raise AssertionError("environment has already been set")
52-
self.particulator.environment = environment
53-
self.particulator.environment.register(self)
52+
self.particulator.environment = environment.instantiate(builder=self)
5453

5554
def add_dynamic(self, dynamic):
5655
assert self.particulator.environment is not None

PySDM/environments/box.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
import numpy as np
66

77
from PySDM.impl.mesh import Mesh
8+
from PySDM.environments.impl import register_environment
89

910

11+
@register_environment()
1012
class Box:
1113
def __init__(self, dt, dv):
1214
self.dt = dt
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
""" common internals not intended to be imported from user code """
2+
3+
from PySDM.environments.impl.register_environment import register_environment
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
""" decorator for environment classes
2+
ensuring that their instances can be re-used with multiple builders """
3+
4+
from copy import deepcopy
5+
6+
7+
def _instantiate(self, *, builder):
8+
copy = deepcopy(self)
9+
copy.register(builder=builder)
10+
return copy
11+
12+
13+
def register_environment():
14+
def decorator(cls):
15+
if hasattr(cls, "instantiate"):
16+
if cls.instantiate is not _instantiate:
17+
raise AttributeError(
18+
"decorated class has a different instantiate method"
19+
)
20+
else:
21+
setattr(cls, "instantiate", _instantiate)
22+
return cls
23+
24+
return decorator

PySDM/environments/kinematic_1d.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77

88
from PySDM.environments.impl.moist import Moist
99

10-
from ..impl import arakawa_c
11-
from ..initialisation.equilibrate_wet_radii import equilibrate_wet_radii
10+
from PySDM.impl import arakawa_c
11+
from PySDM.initialisation.equilibrate_wet_radii import equilibrate_wet_radii
12+
from PySDM.environments.impl import register_environment
1213

1314

15+
@register_environment()
1416
class Kinematic1D(Moist):
1517
def __init__(self, *, dt, mesh, thd_of_z, rhod_of_z, z0=0):
1618
super().__init__(dt, mesh, [])

PySDM/environments/kinematic_2d.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@
1212
equilibrate_wet_radii,
1313
)
1414
from PySDM.initialisation.sampling.spectral_sampling import ConstantMultiplicity
15-
16-
from ..impl import arakawa_c
15+
from PySDM.impl import arakawa_c
16+
from PySDM.environments.impl import register_environment
1717

1818

19+
@register_environment()
1920
class Kinematic2D(Moist):
2021
def __init__(self, *, dt, grid, size, rhod_of, mixed_phase=False):
2122
super().__init__(dt, Mesh(grid, size), [], mixed_phase=mixed_phase)

PySDM/environments/parcel.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
default_rtol,
1313
equilibrate_wet_radii,
1414
)
15+
from PySDM.environments.impl import register_environment
1516

1617

18+
@register_environment()
1719
class Parcel(Moist): # pylint: disable=too-many-instance-attributes
1820
def __init__(
1921
self,

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ builder.add_dynamic(Condensation())
510510

511511
r_dry, specific_concentration = spectral_sampling.Logarithmic(spectrum).sample(n_sd)
512512
v_dry = formulae.trivia.volume(radius=r_dry)
513-
r_wet = equilibrate_wet_radii(r_dry=r_dry, environment=env, kappa_times_dry_volume=kappa * v_dry)
513+
r_wet = equilibrate_wet_radii(r_dry=r_dry, environment=builder.particulator.environment, kappa_times_dry_volume=kappa * v_dry)
514514

515515
attributes = Dict()
516516
attributes["multiplicity"] = discretise_multiplicities(specific_concentration * env.mass_of_dry_air)
@@ -595,7 +595,7 @@ v_dry = formulae.trivia.volume(pyargs('radius', r_dry));
595595
specific_concentration = tmp{2};
596596
r_wet = equilibrate_wet_radii(pyargs(...
597597
'r_dry', r_dry, ...
598-
'environment', env, ...
598+
'environment', builder.particulator.environment, ...
599599
'kappa_times_dry_volume', kappa * v_dry...
600600
));
601601
@@ -691,7 +691,7 @@ builder.add_dynamic(Condensation())
691691

692692
r_dry, specific_concentration = spectral_sampling.Logarithmic(spectrum).sample(n_sd)
693693
v_dry = formulae.trivia.volume(radius=r_dry)
694-
r_wet = equilibrate_wet_radii(r_dry=r_dry, environment=env, kappa_times_dry_volume=kappa * v_dry)
694+
r_wet = equilibrate_wet_radii(r_dry=r_dry, environment=builder.particulator.environment, kappa_times_dry_volume=kappa * v_dry)
695695

696696
attributes = {
697697
'multiplicity': discretise_multiplicities(specific_concentration * env.mass_of_dry_air),

examples/PySDM_examples/Abade_and_Albuquerque_2024/simulation.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,25 @@
1212

1313
class Simulation(BasicSimulation):
1414
def __init__(self, settings):
15-
parcel = Parcel(
16-
dt=settings.timestep,
17-
mass_of_dry_air=settings.mass_of_dry_air,
18-
p0=settings.initial_total_pressure,
19-
initial_water_vapour_mixing_ratio=settings.initial_water_vapour_mixing_ratio,
20-
T0=settings.initial_temperature,
21-
w=settings.updraft,
22-
)
2315
builder = Builder(
2416
backend=CPU(settings.formulae, override_jit_flags={"parallel": False}),
2517
n_sd=settings.n_sd,
26-
environment=parcel,
18+
environment=Parcel(
19+
dt=settings.timestep,
20+
mass_of_dry_air=settings.mass_of_dry_air,
21+
p0=settings.initial_total_pressure,
22+
initial_water_vapour_mixing_ratio=settings.initial_water_vapour_mixing_ratio,
23+
T0=settings.initial_temperature,
24+
w=settings.updraft,
25+
),
2726
)
2827
builder.add_dynamic(AmbientThermodynamics())
2928
builder.add_dynamic(Condensation())
3029

3130
r_dry, n_in_dv = ConstantMultiplicity(settings.soluble_aerosol).sample(
3231
n_sd=settings.n_sd
3332
)
34-
attributes = parcel.init_attributes(
33+
attributes = builder.particulator.environment.init_attributes(
3534
n_in_dv=n_in_dv, kappa=settings.kappa, r_dry=r_dry
3635
)
3736
self.products = (

examples/PySDM_examples/Abdul_Razzak_Ghan_2000/run_ARG_parcel.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ def run_parcel(
6565
v_dry = builder.formulae.trivia.volume(radius=r_dry)
6666
specific_concentration = concentration / builder.formulae.constants.rho_STP
6767
attributes["multiplicity"] = np.append(
68-
attributes["multiplicity"], specific_concentration * env.mass_of_dry_air
68+
attributes["multiplicity"],
69+
specific_concentration * builder.particulator.environment.mass_of_dry_air,
6970
)
7071
attributes["dry volume"] = np.append(attributes["dry volume"], v_dry)
7172
attributes["kappa times dry volume"] = np.append(
@@ -74,7 +75,7 @@ def run_parcel(
7475

7576
r_wet = equilibrate_wet_radii(
7677
r_dry=builder.formulae.trivia.radius(volume=attributes["dry volume"]),
77-
environment=env,
78+
environment=builder.particulator.environment,
7879
kappa_times_dry_volume=attributes["kappa times dry volume"],
7980
)
8081
attributes["volume"] = builder.formulae.trivia.volume(radius=r_wet)

0 commit comments

Comments
 (0)