def __init__(self, setup): self.setup = setup sigma2 = pow(setup.sigma, 2) dx_opt = abs(setup.C_opt / (.5 * sigma2 - setup.r) * setup.l2_opt * sigma2) dt_opt = pow(dx_opt, 2) / sigma2 / setup.l2_opt # adjusting dt so that nt is integer self.dt = setup.T self.nt = 0 while self.dt > dt_opt: self.nt += 1 self.dt = setup.T / self.nt # adjusting dx to match requested l^2 dx = np.sqrt(setup.l2_opt * self.dt) * setup.sigma # calculating actual u number and lambda self.C = -(.5 * sigma2 - setup.r) * (-self.dt) / dx self.l2 = dx * dx / sigma2 / self.dt # adjusting nx and setting S_beg, S_end S_beg = setup.S_match self.nx = 1 while S_beg > setup.S_min: self.nx += 1 S_beg = np.exp(np.log(setup.S_match) - self.nx * dx) self.ix_match = self.nx S_end = setup.S_match while S_end < setup.S_max: self.nx += 1 S_end = np.exp(np.log(S_beg) + (self.nx - 1) * dx) # asset price self.S = np.exp(np.log(S_beg) + np.arange(self.nx) * dx) self.mu_coeff = 0.5 / self.l2 self.solvers = {} self.solvers[1] = Factories.advection_diffusion_1d( advectee=setup.payoff(self.S), advector=self.C, options=Options(n_iters=1, non_zero_mu_coeff=True), boundary_conditions=Extrapolated()) self.solvers[2] = Factories.advection_diffusion_1d( advectee=setup.payoff(self.S), advector=self.C, options=Options(**OPTIONS), boundary_conditions=Extrapolated())
def __init__(self, dt, grid, size, stream_function, field_values, rhod_of, mpdata_iters, mpdata_iga, mpdata_fct, mpdata_tot): super().__init__(dt, Mesh(grid, size), []) self.__rhod_of = rhod_of grid = self.mesh.grid self.rhod = np.repeat( rhod_of( (np.arange(grid[1]) + 1 / 2) / grid[1] ).reshape((1, grid[1])), grid[0], axis=0 ) self.__GC, self.__mpdatas = Factories.stream_function_2d( grid=self.mesh.grid, size=self.mesh.size, dt=self.dt, stream_function=stream_function, field_values=dict((key, np.full(grid, value)) for key, value in field_values.items()), g_factor=self.rhod, options=Options( n_iters=mpdata_iters, infinite_gauge=mpdata_iga, flux_corrected_transport=mpdata_fct, third_order_terms=mpdata_tot ) ) self.asynchronous = False self.thread: (Thread, None) = None
class TestMPDATA2D: def test_Arabas_et_al_2014_sanity(self, case): case = { "nx": case[0], "ny": case[1], "Cx": case[2], "Cy": case[3], "nt": case[4], "ni": case[5], "input": case[6], "output": case[7] } # Arrange sut = Factories.constant_2d(case["input"].reshape( (case["nx"], case["ny"])), [case["Cx"], case["Cy"]], options=Options(n_iters=case["ni"])) # Act sut.advance(nt=case["nt"]) # Assert np.testing.assert_almost_equal(sut.advectee.get(), case["output"].reshape( case["nx"], case["ny"]), decimal=4)
def __init__(self, particles_builder: ParticlesBuilder, dt, grid, size, stream_function, field_values, rhod_of, mpdata_iters, mpdata_iga, mpdata_fct, mpdata_tot): super().__init__(particles_builder, dt, Mesh(grid, size), []) self.__rhod_of = rhod_of grid = self.mesh.grid rhod = np.repeat(rhod_of( (np.arange(grid[1]) + 1 / 2) / grid[1]).reshape((1, grid[1])), grid[0], axis=0) self.__GC, self.__mpdatas = Factories.stream_function_2d( grid=self.mesh.grid, size=self.mesh.size, dt=self.dt, stream_function=stream_function, field_values=dict((key, np.full(grid, value)) for key, value in field_values.items()), g_factor=rhod, options=Options(n_iters=mpdata_iters, infinite_gauge=mpdata_iga, flux_corrected_transport=mpdata_fct, third_order_terms=mpdata_tot)) rhod = particles_builder.particles.backend.from_ndarray(rhod.ravel()) self._values["current"]["rhod"] = rhod self._tmp["rhod"] = rhod self.asynchronous = False self.thread: Thread = None super().sync() self.notify()
def test_upwind(shape, ij0, out, C): value = 44 scalar_field_init = np.zeros(shape) scalar_field_init[ij0] = value vector_field_init = (np.full((shape[0] + 1, shape[1]), C[0]), np.full((shape[0], shape[1] + 1), C[1])) options = Options(n_iters=1) advectee = ScalarField(scalar_field_init, halo=options.n_halo, boundary_conditions=(PeriodicBoundaryCondition(), PeriodicBoundaryCondition())) advector = VectorField(vector_field_init, halo=options.n_halo, boundary_conditions=(PeriodicBoundaryCondition(), PeriodicBoundaryCondition())) mpdata = Solver(stepper=Stepper(options=options, grid=shape), advector=advector, advectee=advectee) mpdata.advance(1) np.testing.assert_array_equal(mpdata.advectee.get(), out)
def __init__(self, advector, advectee, shape): self.options = Options(n_iters=2, infinite_gauge=True, flux_corrected_transport=True) # self.stepper = Stepper(options=options, grid=(ny, nx)) self.stepper = Stepper(options=self.options, grid=shape) self.solver = Solver(stepper=self.stepper, advectee=advectee, advector=advector)
def test_upwind_1d(): state = np.array([0, 1, 0]) C = 1 mpdata = Factories.constant_1d(state, C, Options(n_iters=1)) nt = 5 conserved = np.sum(mpdata.advectee.get()) mpdata.advance(nt) assert np.sum(mpdata.advectee.get()) == conserved
def test_fig10(dtype: np.floating): # Arrange simulation = Simulation(Setup("cosine"), Options(infinite_gauge=True, n_iters=2, dtype=dtype)) # Act simulation.run() psiT = simulation.state # Assert assert psiT.dtype == dtype assert -.1 < np.amin(psiT) < 0 assert 1.75 < np.amax(psiT) < 1.9
def test_fig10(): # Arrange simulation = Simulation(Setup("cosine"), Options(infinite_gauge=True, n_iters=2)) # Act simulation.run() psiT = simulation.state # Assert assert -.1 < np.amin(psiT) < 0 assert 1.75 < np.amax(psiT) < 1.9
def test_fig11(dtype: np.floating): # Arrange simulation = Simulation(Setup("rect"), Options(infinite_gauge=True, n_iters=2, dtype=dtype)) # Act simulation.run() psiT = simulation.state # Assert assert psiT.dtype == dtype assert -1.9 < np.amin(psiT) < 2 assert 4 < np.amax(psiT) < 4.2
def test_fig11(): # Arrange simulation = Simulation(Setup("rect"), Options(infinite_gauge=True, n_iters=2)) # Act simulation.run() psiT = simulation.state # Assert assert -1.9 < np.amin(psiT) < 2 assert 4 < np.amax(psiT) < 4.2
def test_fig12(dtype: np.floating): # Arrange simulation = Simulation(Setup("rect"), Options(n_iters=2, infinite_gauge=True, flux_corrected_transport=True, dtype=dtype)) # Act simulation.run() psiT = simulation.state # Assert assert psiT.dtype == dtype assert np.amin(psiT) >= 2 assert np.amax(psiT) <= 4 assert np.amax(psiT) > 3
def test_fig3(): # Arrange simulation = Simulation(Setup("cosine"), Options(n_iters=1)) psi0 = simulation.state # Act simulation.run() psiT = simulation.state # Assert epsilon = 1e-20 assert np.amin(psi0) == 0 assert np.amax(psi0) == 2 assert 0 < np.amin(psiT) < epsilon assert .45 < np.amax(psiT) < .5
def test_fig4(dtype: np.floating): # Arrange simulation = Simulation(Setup("cosine"), Options(n_iters=2, dtype=dtype)) psi0 = simulation.state # Act simulation.run() psiT = simulation.state # Assert epsilon = 1e-20 assert psiT.dtype == dtype assert np.amin(psi0) == 0 assert np.amax(psi0) == 2 assert 0 < np.amin(psiT) < epsilon assert 1.3 < np.amax(psiT) < 1.4
def test_init(grid_layout, psi_coord, flux_corrected_transport): # Arrange opts = Options(flux_corrected_transport=flux_corrected_transport) setup = Setup() # Act simulation = Simulation(setup, grid_layout=grid_layout, GC_max=default_GC_max, psi_coord=psi_coord, opts=opts) simulation.step(1) # Asserts for array shapes assert simulation.n.shape[0] == setup.nr # Asserts for Jacobian G_with_halo = simulation.solver.g_factor.data assert np.isfinite(G_with_halo).all() if type(psi_coord) == type(grid_layout): np.testing.assert_array_almost_equal(np.diff(G_with_halo), 0) else: assert (np.diff(G_with_halo) >= 0).all() or (np.diff(G_with_halo) <= 0).all()
def analysis(setup, grid_layout, psi_coord, options_dict, GC_max): options_str = str(options_dict) options = Options(**options_dict) simulation = Simulation(setup, grid_layout, psi_coord, options, GC_max) result = {"n": [], "n_analytical": [], "error_norm_L2": []} last_step = 0 for n_steps in simulation.out_steps: steps = n_steps - last_step simulation.step(steps) last_step += steps result['n'].append(simulation.n.copy()) result['r'] = simulation.r.copy() result['rh'] = simulation.rh.copy() result['dx'] = simulation.dx return Result( grid_layout_str=grid_layout.__class__.__name__, option_str=options_str, result=result, out_steps=simulation. out_steps, # TODO? deepcopy? check if running tests multiple times crashes simulation dt=simulation.dt)
def __init__(self, particles, stream_function, field_values, rhod_of, mpdata_iters, mpdata_iga, mpdata_fct, mpdata_tot): super().__init__(particles, []) self.__rhod_of = rhod_of self.mpdata_iters = mpdata_iters grid = particles.mesh.grid rhod = np.repeat(rhod_of( (np.arange(grid[1]) + 1 / 2) / grid[1]).reshape((1, grid[1])), grid[0], axis=0) self.__GC, self.__eulerian_fields = MPDATAFactory.kinematic_2d( grid=self.particles.mesh.grid, size=self.particles.mesh.size, dt=particles.dt, stream_function=stream_function, field_values=dict((key, np.full(grid, value)) for key, value in field_values.items()), g_factor=rhod, opts=Options(nug=True, iga=mpdata_iga, fct=mpdata_fct, tot=mpdata_tot)) rhod = particles.backend.from_ndarray(rhod.ravel()) self._values["current"]["rhod"] = rhod self._tmp["rhod"] = rhod self.products = [ DryAirDensity(self), RelativeHumidity(self), DryAirPotentialTemperature(self), WaterVapourMixingRatio(self) ] self.thread: Thread = None super().sync() self.post_step()
from joblib import Parallel, delayed from MPyDATA_examples.Molenkamp_test_as_in_Jaruga_et_al_2015_Fig_12.simulation import Simulation from MPyDATA_examples.Molenkamp_test_as_in_Jaruga_et_al_2015_Fig_12.setup import Setup from MPyDATA.options import Options options = { 'upwind': Options(n_iters=-1), '2+fct': Options(n_iters=2, flux_corrected_transport=True), '3+fct+tot': Options(n_iters=3, flux_corrected_transport=True, third_order_terms=True), '2+fct+iga': Options(n_iters=2, flux_corrected_transport=True, infinite_gauge=True) } def compute_panel(panel): setup = Setup(n_rotations=6) simulation = Simulation(setup, options[panel]) if panel == 'upwind': return simulation.state simulation.run() return simulation.state def fig_12_data(): data = Parallel(n_jobs=-2)( delayed(compute_panel)(panel) for panel in ['upwind', '2+fct', '3+fct+tot', '2+fct+iga'] ) return data
def from_pdf_2d(pdf, xrange, yrange, gridsize): z = np.empty(gridsize) dx, dy = (xrange[1] - xrange[0]) / gridsize[0], (yrange[1] - yrange[0]) / gridsize[1] for i in range(gridsize[0]): for j in range(gridsize[1]): z[i, j] = pdf( xrange[0] + dx * (i + .5), yrange[0] + dy * (j + .5) ) x = np.linspace(xrange[0] + dx / 2, xrange[1] - dx / 2, gridsize[0]) y = np.linspace(yrange[0] + dy / 2, yrange[1] - dy / 2, gridsize[1]) return x, y, z @pytest.mark.parametrize("options", [ Options(n_iters=1), Options(n_iters=2), Options(n_iters=3), Options(n_iters=4), # Options(n_iters=2, infinite_gauge=True, flux_corrected_transport=True), # TODO! Options(n_iters=3, infinite_gauge=True), Options(n_iters=2, flux_corrected_transport=True), Options(n_iters=2, divergent_flow=True) ]) @pytest.mark.parametrize("dtype", (np.float64,)) def test_timing_2d(benchmark, options, dtype): setup = Setup(n_rotations=6) _, __, z = from_pdf_2d(setup.pdf, xrange=setup.xrange, yrange=setup.yrange, gridsize=setup.grid) mpdata = Factories.constant_2d(data=z, C=(-.5, .25), options=options) def set_z():
from MPyDATA.factories import Factories from MPyDATA.options import Options import numpy as np import pytest # TODO: work in progress @pytest.mark.parametrize( "options", [ # TODO # Options(n_iters=1), # Options(n_iters=2), # Options(n_iters=2, flux_corrected_transport=True), # Options(n_iters=3, flux_corrected_transport=True), Options(n_iters=2, flux_corrected_transport=True, infinite_gauge=True), # Options(nug=True, fct=True, iga=True, tot=True), # Options(nug=True, fct=False, iga=True), # Options(nug=True, fct=False, tot=True), # Options(nug=True, fct=False, iga=True, tot=True) ] ) def test_single_timestep(options): # Arrange grid = (75, 75) size = (1500, 1500) dt = 1 w_max = .6 def stream_function(xX, zZ): X = size[0] return - w_max * X / np.pi * np.sin(np.pi * zZ) * np.cos(2 * np.pi * xX)