def test_fake_numba():
        # Arrange
        sut = DimensionalAnalysis()

        # Act & Assert
        assert hasattr(Formulae().saturation_vapour_pressure.pvs_Celsius,
                       "py_func")
        with sut:
            assert not hasattr(
                Formulae().saturation_vapour_pressure.pvs_Celsius, "py_func")
        assert hasattr(Formulae().saturation_vapour_pressure.pvs_Celsius,
                       "py_func")
Example #2
0
    def __init__(self,
                 w_avg: float,
                 N_STP: float,
                 r_dry: float,
                 mass_of_dry_air: float,
                 coord: str = 'VolumeLogarithm'):
        self.formulae = Formulae(
            saturation_vapour_pressure='AugustRocheMagnus',
            condensation_coordinate=coord)

        self.p0 = 1000 * si.hectopascals
        self.RH0 = .98
        self.kappa = .2  # TODO #441
        self.T0 = 300 * si.kelvin
        self.z_half = 150 * si.metres

        pvs = self.formulae.saturation_vapour_pressure.pvs_Celsius(self.T0 -
                                                                   const.T0)
        self.q0 = const.eps / (self.p0 / self.RH0 / pvs - 1)
        self.w_avg = w_avg
        self.r_dry = r_dry
        self.N_STP = N_STP
        self.n_in_dv = N_STP / const.rho_STP * mass_of_dry_air
        self.mass_of_dry_air = mass_of_dry_air
        self.n_output = 500

        self.rtol_x = condensation.default_rtol_x
        self.rtol_thd = condensation.default_rtol_thd
        self.coord = 'volume logarithm'
        self.dt_cond_range = condensation.default_cond_range
Example #3
0
    def test___str__():
        # Arrange
        sut = Formulae()

        # Act
        result = str(sut)

        # Assert
        assert len(result) > 0
Example #4
0
 def __init__(self, backend, n_sd=0, formulae=None):
     if formulae is None:
         formulae = Formulae()
     Core.__init__(self, n_sd, backend(formulae))
     self.core = self
     self.environment = DummyEnvironment()
     self.environment.register(self)
     self.req_attr = {'n': Multiplicities(self), 'cell id': CellID(self)}
     self.particles = None
Example #5
0
 def __init__(self, n_sd, backend, formulae=Formulae()):
     assert inspect.isclass(backend)
     self.formulae = formulae
     self.core = Core(n_sd, backend(formulae))
     self.req_attr = {
         'n': Multiplicities(self),
         'volume': Volume(self),
         'cell id': CellID(self)
     }
     self.aerosol_radius_threshold = 0
     self.condensation_params = None
Example #6
0
    def test_pvs():
        with DimensionalAnalysis():
            # Arrange
            formulae = Formulae()
            si = constants.si
            sut = formulae.saturation_vapour_pressure.pvs_Celsius
            T = 300 * si.kelvins

            # Act
            pvs = sut(T)

            # Assert
            assert pvs.units == si.hectopascals
Example #7
0
    def test_analytic_solution_underflow(x):
        # Arrange
        formulae = Formulae()
        b = 1.5e3
        x_0 = formulae.trivia.volume(radius=30.531e-6)
        N_0 = 2 ** 23
        sut = Golovin(b)

        # Act
        value = sut.analytic_solution(x=x, t=1200, x_0=x_0, N_0=N_0)

        # Assert
        assert np.all(np.isfinite(value))
Example #8
0
    def test_lv():
        with DimensionalAnalysis():
            # Arrange
            si = constants.si
            T = 300 * si.kelvins

            formulae = Formulae()
            sut = formulae.latent_heat.lv

            # Act
            latent_heat = sut(T)

            # Assert
            assert latent_heat.check('[energy]/[mass]')
Example #9
0
    def test_r_cr():
        with DimensionalAnalysis():
            # Arrange
            si = constants.si
            formulae = Formulae()
            sut = formulae.hygroscopicity.r_cr

            kp = .5
            rd = .1 * si.micrometre
            T = 300 * si.kelvins
            sgm = constants.sgm

            # Act
            r_cr = sut(kp, rd**3, T, sgm)

            # Assert
            assert r_cr.to_base_units().units == si.metres
Example #10
0
    def __init__(self, settings, backend=CPU):
        dt_output = settings.total_time / settings.n_steps  # TODO #334 overwritten in jupyter example
        self.n_substeps = 1  # TODO #334 use condensation substeps
        while (dt_output / self.n_substeps >= settings.dt_max):
            self.n_substeps += 1
        self.formulae = Formulae(condensation_coordinate=settings.coord, saturation_vapour_pressure='AugustRocheMagnus')
        self.bins_edges = self.formulae.trivia.volume(settings.r_bins_edges)
        builder = Builder(backend=backend, n_sd=settings.n_sd, formulae=self.formulae)
        builder.set_environment(Parcel(
            dt=dt_output / self.n_substeps,
            mass_of_dry_air=settings.mass_of_dry_air,
            p0=settings.p0,
            q0=settings.q0,
            T0=settings.T0,
            w=settings.w,
            z0=settings.z0
        ))

        environment = builder.core.environment
        builder.add_dynamic(AmbientThermodynamics())
        condensation = Condensation(
            kappa=settings.kappa,
            adaptive=settings.adaptive,
            rtol_x=settings.rtol_x,
            rtol_thd=settings.rtol_thd,
            dt_cond_range=settings.dt_cond_range
        )
        builder.add_dynamic(condensation)

        products = [
            PySDM_products.ParticlesWetSizeSpectrum(v_bins=self.formulae.trivia.volume(settings.r_bins_edges)),
            PySDM_products.CondensationTimestepMin(),
            PySDM_products.CondensationTimestepMax(),
            PySDM_products.RipeningRate()
        ]

        attributes = environment.init_attributes(
            n_in_dv=settings.n,
            kappa=settings.kappa,
            r_dry=settings.r_dry
        )

        self.core = builder.build(attributes, products)

        self.n_steps = settings.n_steps
Example #11
0
def test_toms748(fun):
    sut = toms748_solve if 'NUMBA_DISABLE_JIT' in os.environ else toms748_solve.py_func

    a = -.5
    b = .5
    rtol = 1e-6
    wt = Formulae().trivia.within_tolerance
    actual, iters = sut(f2, (),
                        ax=a,
                        bx=b,
                        fax=f2(a),
                        fbx=f2(b),
                        max_iter=10,
                        rtol=rtol,
                        within_tolerance=wt)
    expected = toms748(f2, a, b)

    np.testing.assert_almost_equal(actual, expected)
Example #12
0
def test_coalescence(backend, croupier, adaptive):
    if backend == ThrustRTC and croupier == 'local':  # TODO #358
        return
    if backend == ThrustRTC and adaptive and croupier == 'global':  # TODO #329
        return
    # Arrange
    formulae = Formulae(seed=256)
    n_sd = 2**14
    steps = [0, 100, 200]
    X0 = formulae.trivia.volume(radius=30.531e-6)
    n_part = 2**23 / si.metre**3
    dv = 1e6 * si.metres**3
    dt = 1 * si.seconds
    norm_factor = n_part * dv
    rho = 1000 * si.kilogram / si.metre**3

    kernel = Golovin(b=1.5e3)  # [s-1]
    spectrum = Exponential(norm_factor=norm_factor, scale=X0)
    builder = Builder(n_sd=n_sd, backend=backend(formulae=formulae))
    builder.set_environment(Box(dt=dt, dv=dv))
    attributes = {}
    attributes['volume'], attributes['n'] = ConstantMultiplicity(
        spectrum).sample(n_sd)
    builder.add_dynamic(
        Coalescence(kernel, croupier=croupier, adaptive=adaptive))
    particulator = builder.build(attributes)

    volumes = {}

    # Act
    for step in steps:
        particulator.run(step - particulator.n_steps)
        check(n_part, dv, n_sd, rho, particulator.attributes, step)
        volumes[particulator.
                n_steps] = particulator.attributes['volume'].to_ndarray()

    # Assert
    x_max = 0
    for volume in volumes.values():
        assert x_max < np.amax(volume)
        x_max = np.amax(volume)
Example #13
0
    def test_equilibrate_pH_non_trivial(init_conc, env_T):

        equilibria = {
            'water':
            Equilibrium.from_string(f"H2O = H+ + OH-; {K_H2O / M / M}"),
            'ammonia':
            Equilibrium.from_string(
                f"NH3 + H2O = NH4+ + OH-; {EQUILIBRIUM_CONST['K_NH3'].at(env_T) / M}"
            ),
            'sulfonic_first':
            Equilibrium.from_string(
                f"H2SO3(aq) = H+ + HSO3-; {EQUILIBRIUM_CONST['K_SO2'].at(env_T) / M}"
            ),
            'sulfonic_second':
            Equilibrium.from_string(
                f"HSO3- = H+ + SO3-2; {EQUILIBRIUM_CONST['K_HSO3'].at(env_T) / M}"
            ),
            'carbonic_first':
            Equilibrium.from_string(
                f"H2CO3(aq) = H+ + HCO3-; {EQUILIBRIUM_CONST['K_CO2'].at(env_T) / M}"
            ),
            'carbonic_second':
            Equilibrium.from_string(
                f"HCO3- = H+ + CO3-2; {EQUILIBRIUM_CONST['K_HCO3'].at(env_T) / M}"
            )
        }
        substances = [
            Species.from_formula(f) for f in
            'H2O OH- H+ NH3 NH4+ H2CO3(aq) HCO3- CO3-2 H2SO3(aq) HSO3- SO3-2'.
            split()
        ]
        eqsys = EqSystem(equilibria.values(), substances)

        x, sol, sane = eqsys.root(init_conc)
        assert sol['success'] and sane

        H_idx = 2
        assert substances[H_idx].name == 'H+'
        expected_pH = -np.log10(x[H_idx])

        eqs = {}
        for key in EQUILIBRIUM_CONST.keys():
            eqs[key] = np.full(1, EQUILIBRIUM_CONST[key].at(env_T))

        actual_pH = np.empty(1)
        formulae = Formulae()
        ChemistryMethods.equilibrate_H_body(
            within_tolerance=formulae.trivia.within_tolerance,
            pH2H=formulae.trivia.pH2H,
            H2pH=formulae.trivia.H2pH,
            N_mIII=np.full(1, init_conc['NH3'] * 1e3),
            N_V=np.full(1, init_conc['HNO3(aq)'] * 1e3),
            C_IV=np.full(1, init_conc['H2CO3(aq)'] * 1e3),
            S_IV=np.full(1, init_conc['H2SO3(aq)'] * 1e3),
            S_VI=np.full(1, init_conc['HSO4-'] * 1e3),
            K_HNO3=eqs['K_HNO3'].data,
            K_HCO3=eqs['K_HCO3'].data,
            K_HSO3=eqs['K_HSO3'].data,
            K_HSO4=eqs['K_HSO4'].data,
            K_CO2=eqs['K_CO2'].data,
            K_NH3=eqs['K_NH3'].data,
            K_SO2=eqs['K_SO2'].data,
            cell_id=np.zeros(1, dtype=int),
            # output
            do_chemistry_flag=np.empty(1),
            pH=actual_pH,
            # params
            H_min=formulae.trivia.pH2H(aqueous_chemistry.default_pH_max),
            H_max=formulae.trivia.pH2H(aqueous_chemistry.default_pH_min),
            ionic_strength_threshold=aqueous_chemistry.
            default_ionic_strength_threshold,
            rtol=aqueous_chemistry.default_pH_rtol)

        np.testing.assert_allclose(actual_pH[0], expected_pH, rtol=1e-5)
Example #14
0
from PySDM.physics.aqueous_chemistry.support import M, EquilibriumConsts
from PySDM.physics.constants import ROOM_TEMP, K_H2O
from PySDM.physics.formulae import Formulae
from PySDM.backends.numba.impl._chemistry_methods import ChemistryMethods
from PySDM.dynamics import aqueous_chemistry
from chempy import Equilibrium
from chempy.equilibria import EqSystem
from chempy.chemistry import Species

import numpy as np
import pytest
from collections import defaultdict

formulae = Formulae()
EQUILIBRIUM_CONST = EquilibriumConsts(formulae).EQUILIBRIUM_CONST


class Test_pH:
    @staticmethod
    def test_equilibrate_pH_pure_water():
        # Arrange
        eqs = {}
        for key in EQUILIBRIUM_CONST.keys():
            eqs[key] = np.full(1, EQUILIBRIUM_CONST[key].at(ROOM_TEMP))

        # Act
        result = np.empty(1)
        ChemistryMethods.equilibrate_H_body(
            within_tolerance=formulae.trivia.within_tolerance,
            pH2H=formulae.trivia.pH2H,
            H2pH=formulae.trivia.H2pH,