Esempio n. 1
0
def test_wet_vs_dry_spectrum(plot=False):
    # Arrange
    setup = Setup()

    # Act
    simulation = Simulation(setup)
    wet_volume = simulation.particles.state['volume']
    wet_volume = simulation.particles.backend.to_ndarray(wet_volume)
    r_wet = phys.radius(volume=wet_volume) / si.nanometre
    n = simulation.particles.backend.to_ndarray(
        simulation.particles.state['n'])

    dry_volume = simulation.particles.state['dry volume']
    dry_volume = simulation.particles.backend.to_ndarray(dry_volume)
    r_dry = phys.radius(volume=dry_volume) / si.nanometre

    # Plot
    if plot:
        plt.plot(r_wet, n)
        plt.plot(r_dry, n)
        plt.xscale('log')
        plt.yscale('log')
        plt.show()

    # Assert
    assert (r_dry < r_wet).all()
Esempio n. 2
0
def test_dry_spectrum_y(plot=False):
    setup = Setup()
    simulation = Simulation(setup)
    dry_volume = simulation.particles.state['dry volume']
    dry_volume = simulation.particles.backend.to_ndarray(dry_volume)
    rd = phys.radius(volume=dry_volume) / si.nanometre
    nd = simulation.particles.backend.to_ndarray(
        simulation.particles.state['n'])

    dr = (rd[1:] - rd[0:-1])
    env = simulation.particles.environment
    dn_dr = (nd[0:-1] / env.mass_of_dry_air * env["rhod"] / dr)
    dn_dr /= (1 / si.centimetre**3)

    if plot:
        plt.figure(figsize=(5, 5))
        plt.xscale('log')
        plt.yscale('log')
        plt.xlim(1e1, 1e3)
        plt.ylim(1e-9, 1e3)
        plt.yticks(10.**np.arange(-8, 3, step=2))
        plt.plot(rd[0:-1], dn_dr)
        plt.show()

    # from fig. 1b
    assert 1e-3 < dn_dr[0] < 1e-2
    assert 1e1 < max(dn_dr) < 1e2
    assert 0 < dn_dr[-1] < 1e-9
Esempio n. 3
0
 def impl(dy_dt, x, T, p, n, RH, kappa, rd, thd, dot_thd, dot_qv,
          m_d_mean, rhod_mean):
     for i in range(len(x)):
         dy_dt[idx_x + i] = dx_dt(
             x[i],
             phys.dr_dt_MM(phys.radius(volume(x[i])), T, p, RH, kappa,
                           rd[i]))
     dqv_dt = dot_qv - np.sum(
         n * volume(x) * dy_dt[idx_x:]) * rho_w / m_d_mean
     dy_dt[idx_thd] = dot_thd + phys.dthd_dt(rhod_mean, thd, T, dqv_dt)
Esempio n. 4
0
 def __init__(self, kappa, dry_volume: np.ndarray, n: np.ndarray,
              dthd_dt, dqv_dt, m_d_mean, rhod_mean, qt):
     self.kappa = kappa
     self.rd = phys.radius(volume=dry_volume)
     self.n = n
     self.dqv_dt = dqv_dt
     self.dthd_dt = dthd_dt
     self.rhod_mean = rhod_mean
     self.m_d_mean = m_d_mean
     self.qt = qt
Esempio n. 5
0
    def get(self):
        vals = np.empty([self.core.mesh.n_cell, len(self.v_bins) - 1])
        for i in range(len(self.v_bins) - 1):
            self.download_moment_to_buffer(
                attr=self.volume_attr, rank=0, filter_attr=self.volume_attr, filter_range=(self.v_bins[i], self.v_bins[i + 1])
            )
            vals[:, i] = self.buffer.ravel()

        if self.normalise_by_dv:
            vals[:] /= self.core.mesh.dv

        self.download_to_buffer(self.core.environment['rhod'])
        rhod = self.buffer.ravel()
        for i in range(len(self.v_bins) - 1):
            dr = phys.radius(volume=self.v_bins[i + 1]) - phys.radius(volume=self.v_bins[i])
            vals[:, i] /= rhod * dr

        const.convert_to(vals, const.si.micrometre**-1 * const.si.milligram**-1)

        return np.squeeze(vals.reshape(self.shape))
Esempio n. 6
0
def test_dry_spectrum_x():
    settings = Settings()
    simulation = Simulation(settings)
    dry_volume = simulation.core.particles['dry volume'].to_ndarray()
    rd = phys.radius(volume=dry_volume) / si.nanometre

    rd = rd[::-1]
    assert round(rd[1 - 1], 0) == 503
    assert round(rd[10 - 1], 0) == 355
    assert round(rd[50 - 1], 1) == 75.3
    assert round(rd[100 - 1], 1) == 10.8
Esempio n. 7
0
def test_dry_spectrum_x():
    setup = Setup()
    simulation = Simulation(setup)
    dry_volume = simulation.particles.state['dry volume']
    dry_volume = simulation.particles.backend.to_ndarray(dry_volume)
    rd = phys.radius(volume=dry_volume) / si.nanometre

    rd = rd[::-1]
    assert round(rd[1 - 1], 0) == 503
    assert round(rd[10 - 1], 0) == 355
    assert round(rd[50 - 1], 1) == 75.3
    assert round(rd[100 - 1], 1) == 10.8
Esempio n. 8
0
def test_wet_vs_dry_spectrum(plot=False):
    # Arrange
    settings = Settings()

    # Act
    simulation = Simulation(settings)
    wet_volume = simulation.core.particles['volume'].to_ndarray()
    r_wet = phys.radius(volume=wet_volume) / si.nanometre
    n = simulation.core.particles['n'].to_ndarray()

    dry_volume = simulation.core.particles['dry volume'].to_ndarray()
    r_dry = phys.radius(volume=dry_volume) / si.nanometre

    # Plot
    if plot:
        plt.plot(r_wet, n)
        plt.plot(r_dry, n)
        plt.xscale('log')
        plt.yscale('log')
        plt.show()

    # Assert
    assert (r_dry < r_wet).all()
Esempio n. 9
0
    def reinit(self, products):
        self.products = products
        self.product_select.options = [(f"{val.description} [{val.unit}]", key)
                                       for key, val in products.items()
                                       if len(val.shape) == 2]

        r_bins = phys.radius(volume=self.setup.v_bins)
        const.convert_to(r_bins, const.si.micrometres)
        self.spectrumOutput = Output()
        with self.spectrumOutput:
            self.spectrumPlot = _SpectrumPlot(r_bins)
            clear_output()

        self.plots = {}
        self.outputs = {}
        for key, product in products.items():
            if len(product.shape) == 2:
                self.outputs[key] = Output()
                with self.outputs[key]:
                    self.plots[key] = _ImagePlot(self.setup.grid,
                                                 self.setup.size, product)
                    clear_output()

        self.plot_box = Box()
        if len(products.keys()) > 0:
            layout_flex_end = Layout(display='flex',
                                     justify_content='flex-end')
            save_map = Button(icon='save')
            save_map.on_click(self.handle_save_map)
            save_spe = Button(icon='save')
            save_spe.on_click(self.handle_save_spe)
            self.plots_box.children = (HBox(children=(
                VBox(children=(
                    Box(layout=layout_flex_end, children=(save_map, )),
                    HBox((self.slider['Z'], self.plot_box)),
                    HBox((self.slider['X'], ), layout=layout_flex_end))),
                VBox(layout=Layout(), children=(save_spe,
                                                self.spectrumOutput)))), )

        for widget in (self.step_slider, self.play):
            widget.value = 0
            widget.max = len(self.setup.steps) - 1

        for j, xz in enumerate(('X', 'Z')):
            slider = self.slider[xz]
            mx = self.setup.grid[j]
            slider.max = mx
            slider.value = (0, mx)

        self.replot()
Esempio n. 10
0
 def save(self, output):
     cell_id = 0
     output["r_bins_values"].append(
         self.particles.products["Particles Wet Size Spectrum"].get())
     volume = self.particles.state['volume'].to_ndarray()
     output["r"].append(phys.radius(volume=volume))
     output["S"].append(self.particles.environment["RH"][cell_id] - 1)
     output["qv"].append(self.particles.environment["qv"][cell_id])
     output["T"].append(self.particles.environment["T"][cell_id])
     output["z"].append(self.particles.environment["z"][cell_id])
     output["t"].append(self.particles.environment["t"][cell_id])
     output["dt_cond_max"].append(
         self.particles.products["dt_cond"].get_max().copy())
     output["dt_cond_min"].append(
         self.particles.products["dt_cond"].get_min().copy())
     self.particles.products["dt_cond"].reset()
     output['ripening_rate'].append(
         self.particles.products['ripening_rate'].get()[cell_id].copy())
Esempio n. 11
0
def test_initialisation(plot=False):
    # TODO: seed as a part of setup?
    setup = Setup()
    setup.n_steps = -1
    setup.grid = (10, 5)
    setup.n_sd_per_gridbox = 2000

    simulation = Simulation(setup, None)

    n_bins = 32
    n_levels = setup.grid[1]
    n_cell = np.prod(np.array(setup.grid))
    n_moments = 1

    v_bins = np.logspace((np.log10(phys.volume(radius=setup.r_min))),
                         (np.log10(phys.volume(radius=10 * setup.r_max))),
                         num=n_bins,
                         endpoint=True)
    r_bins = phys.radius(volume=v_bins)

    histogram_dry = np.empty((len(r_bins) - 1, n_levels))
    histogram_wet = np.empty_like(histogram_dry)

    moment_0 = setup.backend.array(n_cell, dtype=int)
    moments = setup.backend.array((n_moments, n_cell), dtype=float)
    tmp = np.empty(n_cell)
    simulation.reinit()

    # Act (moments)
    simulation.run()
    particles = simulation.particles
    environment = simulation.particles.environment
    rhod = setup.backend.to_ndarray(environment["rhod"]).reshape(
        setup.grid).mean(axis=0)

    for i in range(len(histogram_dry)):
        particles.state.moments(moment_0,
                                moments,
                                specs={},
                                attr_name='dry volume',
                                attr_range=(v_bins[i], v_bins[i + 1]))
        particles.backend.download(moment_0, tmp)
        histogram_dry[i, :] = tmp.reshape(
            setup.grid).sum(axis=0) / (particles.mesh.dv * setup.grid[0])

        particles.state.moments(moment_0,
                                moments,
                                specs={},
                                attr_name='volume',
                                attr_range=(v_bins[i], v_bins[i + 1]))
        particles.backend.download(moment_0, tmp)
        histogram_wet[i, :] = tmp.reshape(
            setup.grid).sum(axis=0) / (particles.mesh.dv * setup.grid[0])

    # Plot
    if plot:
        for level in range(0, n_levels):
            color = str(.5 * (2 + (level / (n_levels - 1))))
            pyplot.step(r_bins[:-1] * si.metres / si.micrometres,
                        histogram_dry[:, level] / si.metre**3 *
                        si.centimetre**3,
                        where='post',
                        color=color,
                        label="level " + str(level))
            pyplot.step(r_bins[:-1] * si.metres / si.micrometres,
                        histogram_wet[:, level] / si.metre**3 *
                        si.centimetre**3,
                        where='post',
                        color=color,
                        linestyle='--')
        pyplot.grid()
        pyplot.xscale('log')
        pyplot.xlabel('particle radius [µm]')
        pyplot.ylabel('concentration per bin [cm^{-3}]')
        pyplot.legend()
        pyplot.show()

    # Assert - location of maximum
    for level in range(n_levels):
        real_max = setup.spectrum_per_mass_of_dry_air.distribution_params[2]
        idx_max_dry = np.argmax(histogram_dry[:, level])
        idx_max_wet = np.argmax(histogram_wet[:, level])
        assert r_bins[idx_max_dry] < real_max < r_bins[idx_max_dry + 1]
        assert idx_max_dry < idx_max_wet

    # Assert - total number
    for level in reversed(range(n_levels)):
        mass_conc_dry = np.sum(histogram_dry[:, level]) / rhod[level]
        mass_conc_wet = np.sum(histogram_wet[:, level]) / rhod[level]
        mass_conc_STP = setup.spectrum_per_mass_of_dry_air.norm_factor
        assert .5 * mass_conc_STP < mass_conc_dry < 1.5 * mass_conc_STP
        np.testing.assert_approx_equal(mass_conc_dry, mass_conc_wet)

    # Assert - decreasing number density
    total_above = 0
    for level in reversed(range(n_levels)):
        total_below = np.sum(histogram_dry[:, level])
        assert total_below > total_above
        total_above = total_below
Esempio n. 12
0
 def get(self, unit=const.si.micrometre):
     self.download_moment_to_buffer('volume', rank=1 / 3)
     self.buffer[:] *= phys.radius(volume=1)
     const.convert_to(self.buffer, unit)
     return self.buffer
Esempio n. 13
0
    def reinit(self, products):
        self.products = products
        self.product_select.options = [(f"{val.description} [{val.unit}]", key)
                                       for key, val in products.items()
                                       if len(val.shape) == 2]

        r_bins = phys.radius(volume=self.settings.v_bins)
        const.convert_to(r_bins, const.si.micrometres)
        self.spectrumOutput = Output()
        with self.spectrumOutput:
            self.spectrumPlot = _SpectrumPlot(r_bins)
            clear_output()

        self.timeseriesOutput = Output()
        with self.timeseriesOutput:
            default_figsize = rcParams["figure.figsize"]
            fig_kw = {
                'figsize': (2.25 * default_figsize[0], default_figsize[1] / 2)
            }
            fig, ax = pyplot.subplots(1, 1, **fig_kw)
            self.timeseriesPlot = _TimeseriesPlot(
                fig, ax, self.settings.steps * self.settings.dt)
            clear_output()

        self.plots = {}
        self.outputs = {}
        for key, product in products.items():
            if len(product.shape) == 2:
                self.outputs[key] = Output()
                with self.outputs[key]:
                    fig, ax = pyplot.subplots(1, 1)
                    self.plots[key] = _ImagePlot(fig,
                                                 ax,
                                                 self.settings.grid,
                                                 self.settings.size,
                                                 product,
                                                 show=True,
                                                 lines=True)
                    clear_output()

        self.plot_box = Box()
        if len(products.keys()) > 0:
            layout_flex_end = Layout(display='flex',
                                     justify_content='flex-end')
            save_map = Button(icon='save')
            save_map.on_click(self.handle_save_map)
            save_spe = Button(icon='save')
            save_spe.on_click(self.handle_save_spe)
            self.plots_box.children = (VBox(children=(HBox(children=(
                VBox(children=(
                    Box(layout=layout_flex_end, children=(save_map, )),
                    HBox((self.slider['Z'], self.plot_box)),
                    HBox((self.slider['X'], ), layout=layout_flex_end))),
                VBox(layout=Layout(), children=(save_spe, self.spectrumOutput))
            )), HBox((self.timeseriesOutput, )))), )

        for widget in (self.step_slider, self.play):
            widget.value = 0
            widget.max = len(self.settings.steps) - 1

        for j, xz in enumerate(('X', 'Z')):
            slider = self.slider[xz]
            mx = self.settings.grid[j]
            slider.max = mx
            slider.value = (0, mx)

        self.replot()