Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ on:
paths-ignore: ['docs/**', '**.md']
pull_request:
branches: [ main ]
paths-ignore: ['docs/**', '**.md']
schedule:
- cron: '0 13 * * 4'

Expand Down
1 change: 1 addition & 0 deletions PySDM/attributes/impl/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@
from .maximum_attribute import MaximumAttribute
from .attribute_registry import register_attribute, get_attribute_class
from .intensive_attribute import IntensiveAttribute
from .temperature_variation_option_attribute import TemperatureVariationOptionAttribute
18 changes: 18 additions & 0 deletions PySDM/attributes/impl/temperature_variation_option_attribute.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"""common code for attributes offering an option to neglect temperature variation,
intended for use with Parcel environment only"""


class TemperatureVariationOptionAttribute: # pylint: disable=too-few-public-methods
"""base class"""

def __init__(self, builder, neglect_temperature_variations: bool):
if neglect_temperature_variations:
assert builder.particulator.environment.mesh.dimension == 0
self.neglect_temperature_variations = neglect_temperature_variations
self.initial_temperature = (
builder.particulator.Storage.from_ndarray(
builder.particulator.environment["T"].to_ndarray()
)
if neglect_temperature_variations
else None
)
4 changes: 2 additions & 2 deletions PySDM/attributes/physics/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
"""

from .area import Area
from .critical_supersaturation import CriticalSupersaturation
from .critical_saturation import CriticalSaturation
from .critical_volume import CriticalVolume, WetToCriticalVolumeRatio
from .dry_radius import DryRadius
from .dry_volume import DryVolume
from .equilibrium_supersaturation import EquilibriumSupersaturation
from .equilibrium_saturation import EquilibriumSaturation
from .heat import Heat
from .hygroscopicity import Kappa, KappaTimesDryVolume
from .water_mass import SignedWaterMass
Expand Down
54 changes: 54 additions & 0 deletions PySDM/attributes/physics/critical_saturation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"""
kappa-Koehler critical saturation calculated for either initial or actual environment temperature
"""

from PySDM.attributes.impl import (
DerivedAttribute,
register_attribute,
TemperatureVariationOptionAttribute,
)


@register_attribute()
class CriticalSaturation(DerivedAttribute, TemperatureVariationOptionAttribute):
def __init__(self, builder, neglect_temperature_variations=False):
assert builder.particulator.mesh.dimension == 0

self.v_crit = builder.get_attribute("critical 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")
TemperatureVariationOptionAttribute.__init__(
self, builder, neglect_temperature_variations
)
DerivedAttribute.__init__(
self,
builder=builder,
name="critical saturation",
dependencies=(self.v_crit, self.kappa, self.v_dry, self.f_org),
)

def recalculate(self):
temperature = (
self.initial_temperature
if self.neglect_temperature_variations
else self.particulator.environment["T"]
)
r_cr = self.formulae.trivia.radius(self.v_crit.data.data)
rd3 = self.v_dry.data.data / self.formulae.constants.PI_4_3
sgm = self.formulae.surface_tension.sigma(
temperature.data,
self.v_crit.data.data,
self.v_dry.data.data,
self.f_org.data.data,
)

self.data.data[:] = self.formulae.hygroscopicity.RH_eq(
r_cr, T=temperature.data, kp=self.kappa.data.data, rd3=rd3, sgm=sgm
)


@register_attribute()
class CriticalSaturationNeglectingTemperatureVariations(CriticalSaturation):
def __init__(self, builder):
super().__init__(builder, neglect_temperature_variations=True)
37 changes: 0 additions & 37 deletions PySDM/attributes/physics/critical_supersaturation.py

This file was deleted.

61 changes: 52 additions & 9 deletions PySDM/attributes/physics/critical_volume.py
Original file line number Diff line number Diff line change
@@ -1,45 +1,88 @@
"""
critical wet volume (kappa-Koehler, computed using actual temperature)
critical wet volume (kappa-Koehler, computed using actual or initial temperature)
"""

from PySDM.attributes.impl import DerivedAttribute, register_attribute
from PySDM.attributes.impl import (
DerivedAttribute,
register_attribute,
TemperatureVariationOptionAttribute,
)


@register_attribute()
class CriticalVolume(DerivedAttribute):
def __init__(self, builder):
class CriticalVolume(DerivedAttribute, TemperatureVariationOptionAttribute):
def __init__(self, builder, neglect_temperature_variations=False):
self.cell_id = builder.get_attribute("cell id")
self.v_dry = builder.get_attribute("dry volume")
self.v_wet = builder.get_attribute("volume")
self.kappa = builder.get_attribute("kappa")
self.f_org = builder.get_attribute("dry volume organic fraction")
self.environment = builder.particulator.environment
self.particles = builder.particulator

dependencies = [self.v_dry, self.v_wet, self.cell_id]
super().__init__(builder, name="critical volume", dependencies=dependencies)
TemperatureVariationOptionAttribute.__init__(
self, builder, neglect_temperature_variations
)
DerivedAttribute.__init__(
self, builder, name="critical volume", dependencies=dependencies
)

def recalculate(self):
temperature = (
self.initial_temperature
if self.neglect_temperature_variations
else self.environment["T"]
)
self.particulator.backend.critical_volume(
v_cr=self.data,
kappa=self.kappa.get(),
f_org=self.f_org.get(),
v_dry=self.v_dry.get(),
v_wet=self.v_wet.get(),
T=self.environment["T"],
T=temperature,
cell=self.cell_id.get(),
)


@register_attribute()
class WetToCriticalVolumeRatio(DerivedAttribute):
class CriticalVolumeNeglectingTemperatureVariations(CriticalVolume):
def __init__(self, builder):
self.critical_volume = builder.get_attribute("critical volume")
super().__init__(builder, neglect_temperature_variations=True)


@register_attribute()
class WetToCriticalVolumeRatio(DerivedAttribute):
def __init__(
self,
builder,
neglect_temperature_variations=False,
name="wet to critical volume ratio",
):
self.critical_volume = builder.get_attribute(
"critical volume"
+ (
" neglecting temperature variations"
if neglect_temperature_variations
else ""
)
)
self.volume = builder.get_attribute("volume")
super().__init__(
builder,
name="wet to critical volume ratio",
name=name,
dependencies=(self.critical_volume, self.volume),
)

def recalculate(self):
self.data.ratio(self.volume.get(), self.critical_volume.get())


@register_attribute()
class WetToCriticalVolumeRatioNeglectingTemperatureVariations(WetToCriticalVolumeRatio):
def __init__(self, builder):
super().__init__(
builder,
neglect_temperature_variations=True,
name="wet to critical volume ratio neglecting temperature variations",
)
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
"""
kappa-Koehler equilibrium supersaturation calculated for actual environment temperature
kappa-Koehler equilibrium saturation calculated for actual environment temperature
"""

from PySDM.attributes.impl import DerivedAttribute, register_attribute


@register_attribute()
class EquilibriumSupersaturation(DerivedAttribute):
class EquilibriumSaturation(DerivedAttribute):
def __init__(self, builder):
self.r_wet = builder.get_attribute("radius")
self.v_wet = builder.get_attribute("volume")
Expand All @@ -16,7 +16,7 @@ def __init__(self, builder):

super().__init__(
builder=builder,
name="equilibrium supersaturation",
name="equilibrium saturation",
dependencies=(self.kappa, self.v_dry, self.f_org, self.r_wet),
)

Expand Down
11 changes: 11 additions & 0 deletions PySDM/backends/impl_common/freezing_attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,14 @@ class TimeDependentAttributes(
"""groups attributes required in time-dependent regime"""

__slots__ = ()


class TimeDependentHomogeneousAttributes(
namedtuple(
typename="TimeDependentHomogeneousAttributes",
field_names=("volume", "signed_water_mass"),
)
):
"""groups attributes required in time-dependent regime for homogeneous freezing"""

__slots__ = ()
Loading
Loading