class MPDATA_1D: def __init__(self, nz, dt, advector_of_t, advectee_of_zZ_at_t0, g_factor_of_zZ, mpdata_settings): self.t = 0 self.dt = dt self.advector_of_t = advector_of_t grid = (nz, ) options = Options(n_iters=mpdata_settings['n_iters'], infinite_gauge=mpdata_settings['iga'], flux_corrected_transport=mpdata_settings['fct'], third_order_terms=mpdata_settings['tot']) stepper = Stepper(options=options, grid=grid, non_unit_g_factor=True) bcs = (ExtrapolatedBoundaryCondition(), ) g_factor = ScalarField(data=g_factor_of_zZ( arakawa_c.z_scalar_coord(grid)), halo=options.n_halo, boundary_conditions=bcs) advector = VectorField(data=(np.full(nz + 1, advector_of_t(0)), ), halo=options.n_halo, boundary_conditions=bcs) self.advectee = ScalarField(data=advectee_of_zZ_at_t0( arakawa_c.z_scalar_coord(grid)), halo=options.n_halo, boundary_conditions=bcs) self.solver = Solver(stepper=stepper, advectee=self.advectee, advector=advector, g_factor=g_factor) def __call__(self): self.t += .5 * self.dt self.solver.advector.get_component(0)[:] = self.advector_of_t(self.t) self.solver.advance(1) self.t += .5 * self.dt
def test_double_pass_donor_cell(n_iters): courant = .5 options = Options(n_iters=n_iters, DPDC=True, nonoscillatory=True) state = np.array([0, 1, 0], dtype=options.dtype) boundary_conditions = (Periodic(),) mpdata = Solver( stepper=Stepper(options=options, n_dims=state.ndim, non_unit_g_factor=False), advectee=ScalarField( state, halo=options.n_halo, boundary_conditions=boundary_conditions ), advector=VectorField( (np.full(state.shape[0] + 1, courant, dtype=options.dtype),), halo=options.n_halo, boundary_conditions=boundary_conditions ) ) steps = 1 conserved = np.sum(mpdata.advectee.get()) mpdata.advance(steps) assert np.sum(mpdata.advectee.get()) == conserved
def test_diffusion_only_2d(data0=np.array([[0, 0, 0], [0, 1., 0], [0, 0, 0]]), mu_coeff=(.1, .1), n_steps=1): # Arrange options = Options(non_zero_mu_coeff=True) boundary_conditions = tuple([Periodic()] * 2) advectee = ScalarField(data0, options.n_halo, boundary_conditions) 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=boundary_conditions) solver = Solver(stepper=Stepper(options=options, grid=data0.shape), advector=advector, advectee=advectee) # Act solver.advance(n_steps=n_steps, mu_coeff=mu_coeff) # 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 test_upwind(shape, ij0, out, courant_number): value = 44 scalar_field_init = np.zeros(shape) scalar_field_init[ij0] = value vector_field_init = ( np.full((shape[0] + 1, shape[1]), courant_number[0]), np.full((shape[0], shape[1] + 1), courant_number[1]) ) options = Options(n_iters=1) bcs = (Periodic(), Periodic()) advectee = ScalarField(scalar_field_init, halo=options.n_halo, boundary_conditions=bcs) advector = VectorField(vector_field_init, halo=options.n_halo, boundary_conditions=bcs) mpdata = Solver( stepper=Stepper(options=options, grid=shape, n_threads=1), advector=advector, advectee=advectee ) mpdata.advance(n_steps=1) np.testing.assert_array_equal( mpdata.advectee.get(), out )
class MPDATA_1D: def __init__( self, nz, dt, advector_of_t, advectee_of_zZ_at_t0, g_factor_of_zZ, mpdata_settings, ): self.__t = 0 self.dt = dt self.advector_of_t = advector_of_t grid = (nz, ) options = Options( n_iters=mpdata_settings["n_iters"], infinite_gauge=mpdata_settings["iga"], nonoscillatory=mpdata_settings["fct"], third_order_terms=mpdata_settings["tot"], ) stepper = Stepper(options=options, grid=grid, non_unit_g_factor=True) bcs = (Extrapolated(), ) zZ_scalar = arakawa_c.z_scalar_coord(grid) / nz g_factor = ScalarField( data=g_factor_of_zZ(zZ_scalar), halo=options.n_halo, boundary_conditions=bcs, ) advector = VectorField( data=(np.full(nz + 1, advector_of_t(0)), ), halo=options.n_halo, boundary_conditions=bcs, ) self.advectee = ScalarField( data=advectee_of_zZ_at_t0(zZ_scalar), halo=options.n_halo, boundary_conditions=bcs, ) self.solver = Solver( stepper=stepper, advectee=self.advectee, advector=advector, g_factor=g_factor, ) @property def advector(self): return self.solver.advector.get_component(0) def update_advector_field(self): self.__t += 0.5 * self.dt self.advector[:] = self.advector_of_t(self.__t) np.testing.assert_array_less(np.abs(self.advector), 1) self.__t += 0.5 * self.dt def __call__(self): self.solver.advance(1)
def test_shared_advector(): n_x = 100 arr = np.zeros(n_x) opt1 = Options(n_iters=2, DPDC=True) opt2 = Options(n_iters=2) b_c = (Periodic(),) halo = opt1.n_halo assert opt2.n_halo == halo advector = VectorField(data=(np.zeros(n_x + 1),), halo=halo, boundary_conditions=b_c) _ = Solver( stepper=Stepper(options=opt1, grid=(n_x,)), advectee=ScalarField(data=arr, halo=halo, boundary_conditions=b_c), advector=advector ) solver = Solver( stepper=Stepper(options=opt2, grid=(n_x,)), advectee=ScalarField(data=arr, halo=halo, boundary_conditions=b_c), advector=advector ) solver.advance(1)
def test_upwind_1d(): state = np.array([0, 1, 0]) courant = 1 options = Options(n_iters=1) mpdata = Solver( stepper=Stepper(options=options, n_dims=len(state.shape), non_unit_g_factor=False), advectee=ScalarField( state.astype(options.dtype), halo=options.n_halo, boundary_conditions=(Periodic(),) ), advector=VectorField( (np.full(state.shape[0] + 1, courant, dtype=options.dtype),), halo=options.n_halo, boundary_conditions=(Periodic(),) ) ) n_steps = 5 conserved = np.sum(mpdata.advectee.get()) mpdata.advance(n_steps) assert np.sum(mpdata.advectee.get()) == conserved