def test_moment_0d(backend): # Arrange n_part = 100000 v_mean = 2e-6 d = 1.2 n_sd = 32 spectrum = Lognormal(n_part, v_mean, d) v, n = Linear(spectrum).sample(n_sd) T = np.full_like(v, 300.) n = discretise_n(n) particles = DummyCore(backend, n_sd) attribute = {'n': n, 'volume': v, 'temperature': T, 'heat': T * v} particles.build(attribute) state = particles.particles true_mean, true_var = spectrum.stats(moments='mv') # TODO #217 : add a moments_0 wrapper moment_0 = particles.backend.Storage.empty((1, ), dtype=float) moments = particles.backend.Storage.empty((1, 1), dtype=float) # Act state.moments(moment_0, moments, specs={'volume': (0, )}) discr_zero = moments[0, slice(0, 1)].to_ndarray() state.moments(moment_0, moments, specs={'volume': (1, )}) discr_mean = moments[0, slice(0, 1)].to_ndarray() state.moments(moment_0, moments, specs={'volume': (2, )}) discr_mean_radius_squared = moments[0, slice(0, 1)].to_ndarray() state.moments(moment_0, moments, specs={'temperature': (0, )}) discr_zero_T = moments[0, slice(0, 1)].to_ndarray() state.moments(moment_0, moments, specs={'temperature': (1, )}) discr_mean_T = moments[0, slice(0, 1)].to_ndarray() state.moments(moment_0, moments, specs={'temperature': (2, )}) discr_mean_T_squared = moments[0, slice(0, 1)].to_ndarray() # Assert assert abs(discr_zero - 1) / 1 < 1e-3 assert abs(discr_mean - true_mean) / true_mean < .01e-1 true_mrsq = true_var + true_mean**2 assert abs(discr_mean_radius_squared - true_mrsq) / true_mrsq < .05e-1 assert discr_zero_T == discr_zero assert discr_mean_T == 300. np.testing.assert_approx_equal(discr_mean_T_squared, 300.**2, significant=6)
def test_size_distribution_n_part(): # Arrange s = 1.5 n_part = 256 sut = Lognormal(n_part, .5e-5, s) # Act m, dm = np.linspace(.1e-6, 100e-6, 100, retstep=True) sd = sut.size_distribution(m) # Assert assert_approx_equal(np.sum(sd) * dm, n_part, 4)
def test_size_distribution_r_mode(): # Arrange s = 1.001 r_mode = 1e-6 sut = Lognormal(1, r_mode, s) # Act m, dm = np.linspace(.01e-6, 100e-6, 10000, retstep=True) sd = sut.size_distribution(m) # Assert assert_approx_equal(m[sd == np.amax(sd)], r_mode, 2)
def test_final_state(croupier, backend): from PySDM.backends import ThrustRTC if backend is ThrustRTC: return # TODO #330 # Arrange n_part = 100000 v_mean = 2e-6 d = 1.2 n_sd = 32 x = 4 y = 4 attributes = {} spectrum = Lognormal(n_part, v_mean, d) attributes['volume'], attributes['n'] = Linear(spectrum).sample(n_sd) particulator = DummyParticulator(backend, n_sd) particulator.environment = DummyEnvironment(grid=(x, y)) particulator.croupier = croupier attributes['cell id'] = np.array((n_sd,), dtype=int) cell_origin_np = np.concatenate([np.random.randint(0, x, n_sd), np.random.randint(0, y, n_sd)]).reshape((2, -1)) attributes['cell origin'] = cell_origin_np position_in_cell_np = np.concatenate([np.random.rand(n_sd), np.random.rand(n_sd)]).reshape((2, -1)) attributes['position in cell'] = position_in_cell_np particulator.build(attributes) # Act u01 = backend.Storage.from_ndarray(np.random.random(n_sd)) particulator.attributes.permutation(u01, local=particulator.croupier == 'local') _ = particulator.attributes.cell_start # Assert assert (np.diff(particulator.attributes['cell id'][particulator.attributes._Particles__idx]) >= 0).all()
def test_spectrum_moment_0d(backend): # Arrange n_part = 100000 v_mean = 2e-6 d = 1.2 n_sd = 32 spectrum = Lognormal(n_part, v_mean, d) v, n = Linear(spectrum).sample(n_sd) T = np.full_like(v, 300.) n = discretise_n(n) particles = DummyCore(backend, n_sd) attribute = {'n': n, 'volume': v, 'temperature': T, 'heat': T * v} particles.build(attribute) state = particles.particles v_bins = np.linspace(0, 5e-6, num=5, endpoint=True) true_mean, true_var = spectrum.stats(moments='mv') # TODO #217 : add a moments_0 wrapper spectrum_moment_0 = particles.backend.Storage.empty( (len(v_bins) - 1, 1), dtype=float) spectrum_moments = particles.backend.Storage.empty( (len(v_bins) - 1, 1), dtype=float) moment_0 = particles.backend.Storage.empty((1, ), dtype=float) moments = particles.backend.Storage.empty((1, 1), dtype=float) v_bins_edges = particles.backend.Storage.from_ndarray(v_bins) # Act state.spectrum_moments(spectrum_moment_0, spectrum_moments, attr='volume', rank=1, attr_bins=v_bins_edges) actual = spectrum_moments.to_ndarray() expected = np.empty((len(v_bins) - 1, 1), dtype=float) for i in range(len(v_bins) - 1): state.moments(moment_0, moments, specs={'volume': (1, )}, attr_range=(v_bins[i], v_bins[i + 1])) expected[i, 0] = moments[0, 0] # Assert np.testing.assert_array_almost_equal(actual, expected)
def test_spectral_discretisation(discretisation): # Arrange n_sd = 100 m_mode = .5e-5 n_part = 256*16 s_geom = 1.5 spectrum = Lognormal(n_part, m_mode, s_geom) m_range = (.1e-6, 100e-6) # Act m, n = discretisation(spectrum, m_range).sample(n_sd) # Assert assert m.shape == n.shape assert n.shape == (n_sd,) assert np.min(m) >= m_range[0] assert np.max(m) <= m_range[1] actual = np.sum(n) desired = spectrum.cumulative(m_range[1]) - spectrum.cumulative(m_range[0]) quotient = actual / desired np.testing.assert_almost_equal(actual=quotient, desired=1.0, decimal=2)
class TestSum: scale = 1 n_part = 256 exponential = Exponential(n_part, scale) s = 1.001 r_mode = 1e-6 lognormal = Lognormal(1, r_mode, s) @staticmethod def test_size_distribution(): # Arrange sut = Sum((TestSum.exponential, )) # Act x = np.linspace(0, 1) sut_sd = sut.size_distribution(x) exp_sd = TestSum.exponential.size_distribution(x) # Assert np.testing.assert_array_equal(sut_sd, exp_sd) @staticmethod def test_cumulative(): # Arrange sut = Sum((TestSum.exponential, )) # Act x = np.linspace(0, 1) sut_c = sut.cumulative(x) exp_c = TestSum.exponential.cumulative(x) # Assert np.testing.assert_array_equal(sut_c, exp_c) @staticmethod @pytest.mark.parametrize("distributions", [ pytest.param((exponential, ), id="single exponential"), pytest.param((lognormal, ), id="single lognormal"), pytest.param((exponential, exponential), id="2 exponentials") ]) def test_percentiles(distributions): # Arrange sut = Sum(distributions) # Act cdf_values = default_interpolation_grid sut_p = sut.percentiles(cdf_values) exp_p = distributions[0].percentiles(cdf_values) # Assert np.testing.assert_array_almost_equal(sut_p, exp_p, decimal=3)
from PySDM.initialisation import spectral_sampling, spectro_glacial from PySDM.physics.spectra import Lognormal from PySDM.physics import Formulae, constants as const from PySDM.physics.freezing_temperature_spectrum import niemand_et_al_2012 import numpy as np import pytest niemand_et_al_2012.a = -0.517 niemand_et_al_2012.b = 8.934 m_mode = .5e-5 n_part = 256 * 16 s_geom = 1.5 spectrum = Lognormal(n_part, m_mode, s_geom) m_range = (.1e-6, 100e-6) formulae = Formulae(freezing_temperature_spectrum='Niemand_et_al_2012', seed=const.default_random_seed) @pytest.mark.parametrize( "discretisation", [ pytest.param(spectral_sampling.Linear(spectrum, m_range)), pytest.param(spectral_sampling.Logarithmic(spectrum, m_range)), pytest.param(spectral_sampling.ConstantMultiplicity(spectrum, m_range)), pytest.param(spectral_sampling.UniformRandom(spectrum, m_range)), # TODO #599 ]) def test_spectral_discretisation(discretisation): # Arrange