Ejemplo n.º 1
0
    def __init__(self, particles_builder: ParticlesBuilder, scheme='FTBS', sedimentation=False):
        particles_builder.request_attribute('terminal velocity')
        self.particles = particles_builder.particles
        courant_field = self.particles.environment.get_courant_field_data()

        # CFL # TODO: this should be done by MPyDATA
        for d in range(len(courant_field)):
            assert np.amax(abs(courant_field[d])) <= 1

        # TODO: replace with make_calculate_displacement
        if scheme == 'FTFS':
            method = self.particles.backend.explicit_in_space
        elif scheme == 'FTBS':
            method = self.particles.backend.implicit_in_space
        else:
            raise NotImplementedError()

        self.scheme = method
        self.enable_sedimentation = sedimentation

        self.dimension = len(courant_field)
        self.grid = self.particles.backend.from_ndarray(np.array([courant_field[1].shape[0], courant_field[0].shape[1]], dtype=np.int64))

        self.courant = [self.particles.backend.from_ndarray(courant_field[i]) for i in range(self.dimension)]

        self.displacement = self.particles.backend.from_ndarray(np.zeros((self.dimension, self.particles.n_sd)))
        self.temp = self.particles.backend.from_ndarray(np.zeros((self.dimension, self.particles.n_sd), dtype=np.int64))
Ejemplo n.º 2
0
def run(setup):
    particles_building = ParticlesBuilder(n_sd=setup.n_sd,
                                          backend=setup.backend)
    particles_building.set_environment(Box, {'dv': setup.dv, 'dt': setup.dt})
    v, n = constant_multiplicity(setup.n_sd, setup.spectrum,
                                 (setup.init_x_min, setup.init_x_max))
    attributes = {'n': n, 'volume': v}
    particles_building.register_dynamic(Coalescence, {"kernel": setup.kernel})

    particles = particles_building.get_particles(attributes)

    states = {}
    for step in setup.steps:
        particles.run(step - particles.n_steps)

    return states, particles.stats
Ejemplo n.º 3
0
def run(setup):
    particles_builder = ParticlesBuilder(n_sd=setup.n_sd, backend=setup.backend)
    particles_builder.set_environment(Box, {"dv": setup.dv, "dt": setup.dt})
    attributes = {}
    attributes['volume'], attributes['n'] = constant_multiplicity(setup.n_sd, setup.spectrum,
                                                                  (setup.init_x_min, setup.init_x_max))
    particles_builder.register_dynamic(Coalescence, {"kernel": setup.kernel})
    products = {ParticlesVolumeSpectrum: {}}
    particles = particles_builder.get_particles(attributes, products)

    vals = {}
    for step in setup.steps:
        particles.run(step - particles.n_steps)
        vals[step] = particles.products['dv/dlnr'].get(setup.radius_bins_edges)
        vals[step][:] *= setup.rho

    return vals, particles.stats
Ejemplo n.º 4
0
    def __init__(self, setup):

        dt_output = setup.total_time / setup.n_steps  # TODO: overwritten in jupyter example
        self.n_substeps = 1  # TODO:
        while (dt_output / self.n_substeps >= setup.dt_max):
            self.n_substeps += 1
        self.bins_edges = phys.volume(setup.r_bins_edges)
        particles_builder = ParticlesBuilder(backend=setup.backend,
                                             n_sd=setup.n_sd)
        particles_builder.set_environment(
            MoistLagrangianParcelAdiabatic, {
                "dt": dt_output / self.n_substeps,
                "mass_of_dry_air": setup.mass_of_dry_air,
                "p0": setup.p0,
                "q0": setup.q0,
                "T0": setup.T0,
                "w": setup.w,
                "z0": setup.z0
            })

        environment = particles_builder.particles.environment
        r_wet = r_wet_init(setup.r_dry, environment, np.zeros_like(setup.n),
                           setup.kappa)
        particles_builder.register_dynamic(
            Condensation, {
                "kappa": setup.kappa,
                "coord": setup.coord,
                "adaptive": setup.adaptive,
                "rtol_x": setup.rtol_x,
                "rtol_thd": setup.rtol_thd,
            })
        attributes = {
            'n': setup.n,
            'dry volume': phys.volume(radius=setup.r_dry),
            'volume': phys.volume(radius=r_wet)
        }
        products = {
            ParticlesSizeSpectrum: {
                'v_bins': phys.volume(setup.r_bins_edges)
            },
            CondensationTimestep: {},
            RipeningRate: {}
        }
        self.particles = particles_builder.get_particles(attributes, products)

        self.n_steps = setup.n_steps
Ejemplo n.º 5
0
def test_coalescence(croupier):
    # Arrange
    v_min = 4.186e-15
    v_max = 4.186e-12
    n_sd = 2**13
    steps = [0, 30, 60]
    X0 = 4 / 3 * np.pi * 30.531e-6**3
    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)
    particles_builder = ParticlesBuilder(n_sd=n_sd, backend=backend)
    particles_builder.set_environment(Box, {"dt": dt, "dv": dv})
    attributes = {}
    attributes['volume'], attributes['n'] = constant_multiplicity(
        n_sd, spectrum, (v_min, v_max))
    particles_builder.register_dynamic(Coalescence, {"kernel": kernel})
    particles = particles_builder.get_particles(attributes)
    particles.croupier = croupier

    class Seed:
        seed = 0

        def __call__(self):
            Seed.seed += 1
            return Seed.seed

    particles.dynamics[str(Coalescence)].seed = Seed()

    states = {}

    # Act
    for step in steps:
        particles.run(step - particles.n_steps)
        check(n_part, dv, n_sd, rho, particles.state, step)
        states[particles.n_steps] = copy.deepcopy(particles.state)

    # Assert
    x_max = 0
    for state in states.values():
        assert x_max < np.amax(backend.to_ndarray(state['volume']))
        x_max = np.amax(backend.to_ndarray(state['volume']))
Ejemplo n.º 6
0
    def __init__(self, setup):
        t_half = setup.z_half / setup.w_avg

        dt_output = (2 * t_half) / setup.n_output
        self.n_substeps = 1
        while dt_output / self.n_substeps >= setup.dt_max:  # TODO dt_max
            self.n_substeps += 1

        particles_builder = ParticlesBuilder(backend=setup.backend, n_sd=1)
        particles_builder.set_environment(
            MoistLagrangianParcelAdiabatic, {
                "dt": dt_output / self.n_substeps,
                "mass_of_dry_air": setup.mass_of_dry_air,
                "p0": setup.p0,
                "q0": setup.q0,
                "T0": setup.T0,
                "w": setup.w
            })

        particles_builder.register_dynamic(
            Condensation, {
                "kappa": setup.kappa,
                "rtol_x": setup.rtol_x,
                "rtol_thd": setup.rtol_thd,
            })
        attributes = {}
        r_dry = np.array([setup.r_dry])
        attributes['dry volume'] = phys.volume(radius=r_dry)
        attributes['n'] = np.array([setup.n_in_dv], dtype=np.int64)
        environment = particles_builder.particles.environment
        r_wet = r_wet_init(r_dry, environment, np.zeros_like(attributes['n']),
                           setup.kappa)
        attributes['volume'] = phys.volume(radius=r_wet)
        products = {ParticleMeanRadius: {}}

        self.particles = particles_builder.get_particles(attributes, products)

        self.n_output = setup.n_output
Ejemplo n.º 7
0
    def reinit(self):

        particles_builder = ParticlesBuilder(n_sd=self.setup.n_sd,
                                             backend=self.setup.backend)
        particles_builder.set_environment(
            MoistEulerian2DKinematic, {
                "dt": self.setup.dt,
                "grid": self.setup.grid,
                "size": self.setup.size,
                "stream_function": self.setup.stream_function,
                "field_values": self.setup.field_values,
                "rhod_of": self.setup.rhod,
                "mpdata_iga": self.setup.mpdata_iga,
                "mpdata_tot": self.setup.mpdata_tot,
                "mpdata_fct": self.setup.mpdata_fct,
                "mpdata_iters": self.setup.mpdata_iters
            })

        particles_builder.register_dynamic(
            Condensation,
            {
                "kappa": self.setup.kappa,
                "rtol_x": self.setup.condensation_rtol_x,
                "rtol_thd": self.setup.condensation_rtol_thd,
                "coord": self.setup.condensation_coord,
                "adaptive": self.setup.adaptive,
                "do_advection": self.setup.
                processes["fluid advection"],  # TODO req. EulerianAdvection
                "do_condensation":
                self.setup.processes["condensation"]  # do somthing with that
            })
        particles_builder.register_dynamic(EulerianAdvection, {})

        if self.setup.processes["particle advection"]:
            particles_builder.register_dynamic(
                Displacement, {
                    "scheme": 'FTBS',
                    "sedimentation": self.setup.processes["sedimentation"]
                })
        if self.setup.processes["coalescence"]:
            particles_builder.register_dynamic(Coalescence,
                                               {"kernel": self.setup.kernel})
        # TODO
        # if self.setup.processes["relaxation"]:
        #     raise NotImplementedError()

        attributes = {}
        moist_environment_init(
            attributes,
            particles_builder.particles.environment,
            spatial_discretisation=spatial_sampling.pseudorandom,
            spectral_discretisation=spectral_sampling.
            constant_multiplicity,  # TODO: random
            spectrum_per_mass_of_dry_air=self.setup.
            spectrum_per_mass_of_dry_air,
            r_range=(self.setup.r_min, self.setup.r_max),
            kappa=self.setup.kappa)
        products = {
            ParticlesSizeSpectrum: {
                'v_bins': self.setup.v_bins
            },
            TotalParticleConcentration: {},
            TotalParticleSpecificConcentration: {},
            AerosolConcentration: {
                'radius_threshold': self.setup.aerosol_radius_threshold
            },
            AerosolSpecificConcentration: {
                'radius_threshold': self.setup.aerosol_radius_threshold
            },
            ParticleMeanRadius: {},
            SuperDropletCount: {},
            RelativeHumidity: {},
            WaterVapourMixingRatio: {},
            DryAirDensity: {},
            DryAirPotentialTemperature: {},
            CondensationTimestep: {},
            RipeningRate: {}
        }
        self.particles = particles_builder.get_particles(attributes, products)
        SpinUp(self.particles, self.setup.n_spin_up)
        # TODO
        if self.storage is not None:
            self.storage.init(self.setup)