-
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.
new example based on Grabowski & Pawlowska 2023 (GRL) (#1093)
Co-authored-by: Sylwester Arabas <[email protected]> Co-authored-by: Sylwester Arabas <[email protected]>
- Loading branch information
1 parent
ed50cb2
commit 42f8485
Showing
29 changed files
with
4,618 additions
and
58 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
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,39 @@ | ||
""" | ||
kappa-Koehler equilibrium supersaturation calculated for actual environment temperature | ||
""" | ||
from PySDM.attributes.impl.derived_attribute import DerivedAttribute | ||
|
||
|
||
class EquilibriumSupersaturation(DerivedAttribute): | ||
def __init__(self, builder): | ||
self.r_wet = builder.get_attribute("radius") | ||
self.v_wet = builder.get_attribute("volume") | ||
self.v_dry = builder.get_attribute("dry volume") | ||
self.kappa = builder.get_attribute("kappa") | ||
self.f_org = builder.get_attribute("dry volume organic fraction") | ||
|
||
super().__init__( | ||
builder=builder, | ||
name="equilibrium supersaturation", | ||
dependencies=(self.kappa, self.v_dry, self.f_org, self.r_wet), | ||
) | ||
|
||
def recalculate(self): | ||
if len(self.particulator.environment["T"]) != 1: | ||
raise NotImplementedError() | ||
temperature = self.particulator.environment["T"][0] | ||
rd3 = self.v_dry.data.data / self.formulae.constants.PI_4_3 | ||
sgm = self.formulae.surface_tension.sigma( | ||
temperature, | ||
self.v_wet.data.data, | ||
self.v_dry.data.data, | ||
self.f_org.data.data, | ||
) | ||
|
||
self.data.data[:] = self.formulae.hygroscopicity.RH_eq( | ||
self.r_wet.data.data, | ||
T=temperature, | ||
kp=self.kappa.data.data, | ||
rd3=rd3, | ||
sgm=sgm, | ||
) |
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,30 @@ | ||
""" | ||
common base class for products filtering droplets based on their activation state | ||
""" | ||
import numpy as np | ||
|
||
|
||
class _ActivationFilteredProduct: | ||
def __init__( | ||
self, | ||
*, | ||
count_unactivated: bool, | ||
count_activated: bool, | ||
): | ||
self.__filter_attr = "wet to critical volume ratio" | ||
self.__filter_range = [0, np.inf] | ||
if not count_activated: | ||
self.__filter_range[1] = 1 | ||
if not count_unactivated: | ||
self.__filter_range[0] = 1 | ||
|
||
def impl(self, *, attr, rank): | ||
getattr(self, "_download_moment_to_buffer")( | ||
attr=attr, | ||
rank=rank, | ||
filter_attr=self.__filter_attr, | ||
filter_range=self.__filter_range, | ||
) | ||
|
||
def register(self, builder): | ||
builder.request_attribute(self.__filter_attr) |
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 |
---|---|---|
@@ -1,14 +1,29 @@ | ||
""" | ||
mean radius of particles within a grid cell (optionally restricted to a given size range) | ||
""" | ||
import numpy as np | ||
|
||
from PySDM.products.impl.moment_product import MomentProduct | ||
|
||
|
||
class MeanRadius(MomentProduct): | ||
def __init__(self, name=None, unit="m"): | ||
def __init__( | ||
self, | ||
name=None, | ||
unit="m", | ||
radius_range=(0, np.inf), | ||
): | ||
self.radius_range = radius_range | ||
super().__init__(name=name, unit=unit) | ||
|
||
def _impl(self, **kwargs): | ||
self._download_moment_to_buffer(attr="volume", rank=1 / 3) | ||
self._download_moment_to_buffer( | ||
attr="volume", | ||
rank=1 / 3, | ||
filter_range=( | ||
self.formulae.trivia.volume(self.radius_range[0]), | ||
self.formulae.trivia.volume(self.radius_range[1]), | ||
), | ||
) | ||
self.buffer[:] /= self.formulae.constants.PI_4_3 ** (1 / 3) | ||
return self.buffer |
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,24 @@ | ||
""" | ||
mean radius of particles within a grid cell, for activated, unactivated or both | ||
""" | ||
from PySDM.products.impl.activation_filtered_product import _ActivationFilteredProduct | ||
from PySDM.products.impl.moment_product import MomentProduct | ||
|
||
|
||
class ActivatedMeanRadius(MomentProduct, _ActivationFilteredProduct): | ||
def __init__( | ||
self, count_unactivated: bool, count_activated: bool, name=None, unit="m" | ||
): | ||
MomentProduct.__init__(self, name=name, unit=unit) | ||
_ActivationFilteredProduct.__init__( | ||
self, count_activated=count_activated, count_unactivated=count_unactivated | ||
) | ||
|
||
def register(self, builder): | ||
for base_class in (_ActivationFilteredProduct, MomentProduct): | ||
base_class.register(self, builder) | ||
|
||
def _impl(self, **kwargs): | ||
_ActivationFilteredProduct.impl(self, attr="volume", rank=1 / 3) | ||
self.buffer[:] /= self.formulae.constants.PI_4_3 ** (1 / 3) | ||
return self.buffer |
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,24 @@ | ||
""" | ||
mean volume radius of particles within a grid cell, for activated, unactivated or both | ||
""" | ||
|
||
from PySDM.products.impl.activation_filtered_product import _ActivationFilteredProduct | ||
from PySDM.products.impl.moment_product import MomentProduct | ||
|
||
|
||
class MeanVolumeRadius(MomentProduct, _ActivationFilteredProduct): | ||
def __init__( | ||
self, count_unactivated: bool, count_activated: bool, name=None, unit="m" | ||
): | ||
MomentProduct.__init__(self, name=name, unit=unit) | ||
_ActivationFilteredProduct.__init__( | ||
self, count_activated=count_activated, count_unactivated=count_unactivated | ||
) | ||
|
||
def register(self, builder): | ||
for base_class in (_ActivationFilteredProduct, MomentProduct): | ||
base_class.register(self, builder) | ||
|
||
def _impl(self, **kwargs): | ||
_ActivationFilteredProduct.impl(self, attr="volume", rank=1) | ||
return self.formulae.trivia.radius(self.buffer[:]) |
46 changes: 46 additions & 0 deletions
46
PySDM/products/size_spectral/particle_concentration_activated.py
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,46 @@ | ||
""" | ||
concentration of particles within a grid cell (either per-volume of per-mass-of-dry air), | ||
activated, unactivated or both | ||
""" | ||
|
||
from PySDM.products.impl.activation_filtered_product import _ActivationFilteredProduct | ||
from PySDM.products.impl.concentration_product import ConcentrationProduct | ||
|
||
|
||
class ActivatedParticleConcentration(ConcentrationProduct, _ActivationFilteredProduct): | ||
# pylint: disable=too-many-arguments | ||
def __init__( | ||
self, | ||
*, | ||
count_unactivated: bool, | ||
count_activated: bool, | ||
specific=False, | ||
stp=False, | ||
name=None, | ||
unit="m^-3", | ||
): | ||
ConcentrationProduct.__init__( | ||
self, name=name, unit=unit, specific=specific, stp=stp | ||
) | ||
_ActivationFilteredProduct.__init__( | ||
self, count_activated=count_activated, count_unactivated=count_unactivated | ||
) | ||
|
||
def register(self, builder): | ||
for base_class in (_ActivationFilteredProduct, ConcentrationProduct): | ||
base_class.register(self, builder) | ||
|
||
def _impl(self, **kwargs): | ||
_ActivationFilteredProduct.impl(self, attr="volume", rank=0) | ||
return ConcentrationProduct._impl(self, **kwargs) | ||
|
||
|
||
class ActivatedParticleSpecificConcentration(ActivatedParticleConcentration): | ||
def __init__(self, count_unactivated, count_activated, name=None, unit="kg^-1"): | ||
super().__init__( | ||
count_unactivated=count_unactivated, | ||
count_activated=count_activated, | ||
specific=True, | ||
name=name, | ||
unit=unit, | ||
) |
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 @@ | ||
""" | ||
standard deviation of radius/area/volume of particles within a grid cell, | ||
for activated, unactivated or both | ||
""" | ||
import numpy as np | ||
|
||
from PySDM.products.impl.activation_filtered_product import _ActivationFilteredProduct | ||
from PySDM.products.impl.moment_product import MomentProduct | ||
|
||
|
||
class _SizeStandardDeviation(MomentProduct, _ActivationFilteredProduct): | ||
# pylint: disable=too-many-arguments | ||
def __init__( | ||
self, | ||
count_unactivated: bool, | ||
count_activated: bool, | ||
name=None, | ||
unit="m", | ||
attr="radius", | ||
): | ||
self.attr = attr | ||
MomentProduct.__init__(self, name=name, unit=unit) | ||
_ActivationFilteredProduct.__init__( | ||
self, count_activated=count_activated, count_unactivated=count_unactivated | ||
) | ||
|
||
def register(self, builder): | ||
builder.request_attribute(self.attr) | ||
for base_class in (_ActivationFilteredProduct, MomentProduct): | ||
base_class.register(self, builder) | ||
|
||
def _impl(self, **kwargs): | ||
_ActivationFilteredProduct.impl(self, attr=self.attr, rank=1) | ||
tmp = np.empty_like(self.buffer) | ||
tmp[:] = -self.buffer**2 | ||
_ActivationFilteredProduct.impl(self, attr=self.attr, rank=2) | ||
tmp[:] += self.buffer | ||
tmp[:] = np.sqrt(tmp) | ||
return tmp | ||
|
||
|
||
RadiusStandardDeviation = _SizeStandardDeviation | ||
|
||
|
||
class AreaStandardDeviation(_SizeStandardDeviation): | ||
def __init__( | ||
self, *, name=None, unit="m^2", count_activated: bool, count_unactivated: bool | ||
): | ||
super().__init__( | ||
name=name, | ||
unit=unit, | ||
count_activated=count_activated, | ||
count_unactivated=count_unactivated, | ||
attr="area", | ||
) | ||
|
||
|
||
class VolumeStandardDeviation(_SizeStandardDeviation): | ||
def __init__( | ||
self, *, name=None, unit="m^3", count_activated: bool, count_unactivated: bool | ||
): | ||
super().__init__( | ||
name=name, | ||
unit=unit, | ||
count_activated=count_activated, | ||
count_unactivated=count_unactivated, | ||
attr="volume", | ||
) |
3 changes: 3 additions & 0 deletions
3
examples/PySDM_examples/Grabowski_and_Pawlowska_2023/__init__.py
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,3 @@ | ||
# pylint: disable=invalid-name | ||
from .settings import Settings | ||
from .simulation import Simulation |
Oops, something went wrong.