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=(ExtrapolatedBoundaryCondition(),) ) self.solvers[2] = Factories.advection_diffusion_1d( advectee=setup.payoff(self.S), advector=self.C, options=Options(**OPTIONS), boundary_conditions=(ExtrapolatedBoundaryCondition(),) )
def test_make_upwind(self): # Arrange psi_data = np.array((0, 1, 0)) flux_data = np.array((0, 0, 1, 0)) options = Options() halo = options.n_halo traversals = Traversals(grid=psi_data.shape, halo=halo, jit_flags={}, n_threads=1) upwind = make_upwind(options=options, non_unit_g_factor=False, traversals=traversals) bc = [PeriodicBoundaryCondition()] psi = ScalarField(psi_data, halo, bc) psi_impl = psi.impl flux_impl = VectorField((flux_data, ), halo, bc).impl null_impl = ScalarField.make_null(len(psi_data.shape)).impl # Act upwind(psi_impl[0], *flux_impl, *null_impl) # Assert np.testing.assert_array_equal(psi.get(), np.roll(psi_data, 1))
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": [], "wall_time": [] } last_step = 0 for n_steps in simulation.out_steps: steps = n_steps - last_step wall_time = simulation.step(steps) if steps > 0 else 0 last_step += steps result['n'].append(simulation.n_of_r.copy()) result['wall_time'].append(wall_time) 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, dt=simulation.dt)
def test_diffusion_only_2d( data0=np.array([[0, 0, 0], [0, 1., 0], [0, 0, 0]]), mu=(.1, .1), nt=1): # Arrange options = Options(non_zero_mu_coeff=True) bc = [PeriodicBoundaryCondition()] * 2 advectee = ScalarField(data0, options.n_halo, bc) advector = VectorField(data=(np.zeros( (data0.shape[0] + 1, data0.shape[1])), np.zeros( (data0.shape[0], data0.shape[1] + 1))), halo=options.n_halo, boundary_conditions=bc) solver = Solver(stepper=Stepper(options=options, grid=data0.shape), advector=advector, advectee=advectee) # Act solver.advance(nt=nt, mu_coeff=mu) # Assert data1 = solver.advectee.get() np.testing.assert_almost_equal(actual=np.sum(data1), desired=np.sum(data0)) assert np.amax(data0) > np.amax(data1) assert np.amin(data1) >= 0 assert np.count_nonzero(data1) == 5
def make_data(setup, grid, opts): options = Options(**opts) simulation = Simulation(setup=setup, grid_layout=grid, psi_coord=x_id(), opts=options, GC_max=default_GC_max) result = {"wall_time": []} last_step = 0 for n_steps in simulation.out_steps: steps = n_steps - last_step wall_time_per_timestep = simulation.step(steps) last_step += steps result['wall_time'].append(wall_time_per_timestep) return result
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 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
from MPyDATA.arakawa_c.traversals import Traversals from MPyDATA.arakawa_c.meta import meta_halo_valid from MPyDATA import Options, ScalarField, VectorField, ConstantBoundaryCondition from MPyDATA.arakawa_c.indexers import indexers import pytest import numba import numpy as np jit_flags = Options().jit_flags @numba.njit(**jit_flags) def cell_id(i, j): if i == -1: return j return 100 * i + j @numba.njit(**jit_flags) def _cell_id_scalar(value, arg_1_vec, arg_2_scl, arg_3_scl, arg_4_scl): focus = arg_1_vec[0] if focus != arg_2_scl[0]: raise Exception() if focus != arg_3_scl[0]: raise Exception() if focus != arg_4_scl[0]: raise Exception() return value + cell_id(*focus) @numba.njit(**jit_flags)
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 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