def setUp(self): # store current configuration parameters self.config = PISM.DefaultConfig(ctx.com, "pism_config", "-config", ctx.unit_system) self.config.init_with_default(ctx.log) self.config.import_from(ctx.config) self.filename = filename("forcing-options-input") PISM.util.prepare_output(self.filename)
def ssa_trivial_test(): "Test the SSA solver using a trivial setup." context = PISM.Context() L = 50.e3 # // 50km half-width H0 = 500 # // m dhdx = 0.005 # // pure number, slope of surface & bed nu0 = PISM.util.convert(30.0, "MPa year", "Pa s") tauc0 = 1.e4 # // 1kPa class TrivialSSARun(PISM.ssa.SSAExactTestCase): def _initGrid(self): self.grid = PISM.IceGrid.Shallow(context.ctx, L, L, 0, 0, self.Mx, self.My, PISM.CELL_CORNER, PISM.NOT_PERIODIC) def _initPhysics(self): self.modeldata.setPhysics(context.enthalpy_converter) def _initSSACoefficients(self): self._allocStdSSACoefficients() self._allocateBCs() vecs = self.modeldata.vecs vecs.land_ice_thickness.set(H0) vecs.surface_altitude.set(H0) vecs.bedrock_altitude.set(0.0) vecs.tauc.set(tauc0) # zero Dirichler B.C. everywhere vecs.vel_bc.set(0.0) vecs.vel_bc_mask.set(1.0) def _initSSA(self): # The following ensure that the strength extension is used everywhere se = self.ssa.strength_extension se.set_notional_strength(nu0 * H0) se.set_min_thickness(4000 * 10) # For the benefit of SSAFD on a non-periodic grid self.config.set_flag("ssa.compute_surface_gradient_inward", True) def exactSolution(self, i, j, x, y): return [0, 0] output_file = filename("ssa_trivial") try: Mx = 11 My = 11 test_case = TrivialSSARun(Mx, My) test_case.run(output_file) finally: os.remove(output_file)
def logging_test(): "Test the PISM.logging module" grid = create_dummy_grid() import PISM.logging as L log_filename = filename("log") try: PISM.File(grid.com, log_filename, PISM.PISM_NETCDF3, PISM.PISM_READWRITE_MOVE) c = L.CaptureLogger(log_filename) L.clear_loggers() L.add_logger(L.print_logger) L.add_logger(c) L.log("log message\n", L.kError) L.logError("error message\n") L.logWarning("warning message\n") L.logMessage("log message (again)\n") L.logDebug("debug message\n") L.logPrattle("prattle message\n") c.write() # default arguments c.readOldLog() finally: os.remove(log_filename) log_filename = filename("other_log") try: PISM.File(grid.com, log_filename, PISM.PISM_NETCDF3, PISM.PISM_READWRITE_MOVE) c.write(log_filename, "other_log") # non-default arguments finally: os.remove(log_filename)
def grid_from_file_test_2(): "Intiialize a grid from a file (test 2)" grid = create_dummy_grid() enthalpy = PISM.model.createEnthalpyVec(grid) enthalpy.set(80e3) file_name = filename("grid_from_file") try: pio = PISM.util.prepare_output(file_name) enthalpy.write(pio) grid2 = PISM.IceGrid.FromFile(ctx.ctx, file_name, ["enthalpy"], PISM.CELL_CORNER) finally: os.remove(file_name)
def regridding_test(): "Test 2D regridding: same input and target grids." import numpy as np ctx = PISM.Context() params = PISM.GridParameters(ctx.config) params.Mx = 3 params.My = 3 params.ownership_ranges_from_options(1) grid = PISM.IceGrid(ctx.ctx, params) thk1 = PISM.model.createIceThicknessVec(grid) thk2 = PISM.model.createIceThicknessVec(grid) x = grid.x() x_min = np.min(x) x_max = np.max(x) y = grid.y() y_min = np.min(y) y_max = np.max(y) with PISM.vec.Access(nocomm=[thk1]): for (i, j) in grid.points(): F_x = (x[i] - x_min) / (x_max - x_min) F_y = (y[j] - y_min) / (y_max - y_min) thk1[i, j] = (F_x + F_y) / 2.0 file_name = filename("thickness") try: thk1.dump(file_name) thk2.regrid(file_name, critical=True) with PISM.vec.Access(nocomm=[thk1, thk2]): for (i, j) in grid.points(): v1 = thk1[i, j] v2 = thk2[i, j] if np.abs(v1 - v2) > 1e-12: raise AssertionError("mismatch at {},{}: {} != {}".format( i, j, v1, v2)) finally: os.remove(file_name)
def grid_from_file_test(): "Intiialize a grid from a file (test 1)" grid = create_dummy_grid() enthalpy = PISM.model.createEnthalpyVec(grid) enthalpy.set(80e3) file_name = filename("grid_from_file") try: pio = PISM.util.prepare_output(file_name) enthalpy.write(pio) pio = PISM.File(grid.com, file_name, PISM.PISM_NETCDF3, PISM.PISM_READONLY) grid2 = PISM.IceGrid.FromFile(ctx.ctx, pio, "enthalpy", PISM.CELL_CORNER) finally: os.remove(file_name)
def util_test(): "Test the PISM.util module" grid = create_dummy_grid() output_file = filename("test_pism_util") try: pio = PISM.File(grid.com, output_file, PISM.PISM_NETCDF3, PISM.PISM_READWRITE_MOVE) pio.close() PISM.util.writeProvenance(output_file) PISM.util.writeProvenance(output_file, message="history string") PISM.util.fileHasVariable(output_file, "data") finally: os.remove(output_file) # Test PISM.util.Bunch b = PISM.util.Bunch(a=1, b="string") b.update(c=3.0) print(b.a, b["b"], "b" in b, b)
def setUp(self): "Prepare an input file with an interesting time-dependent field." suffix = filename("") self.filename = "input_" + suffix self.empty = "empty_" + suffix self.one_record = "one_record_" + suffix self.no_time = "no_time_" + suffix self.no_bounds = "no_time_bounds_" + suffix self.time_order = "time_order_" + suffix self.interp_linear = "interp_linear_" + suffix M = 3 self.grid = PISM.IceGrid.Shallow(ctx.ctx, 1, 1, 0, 0, M, M, PISM.CELL_CORNER, PISM.NOT_PERIODIC) v = PISM.IceModelVec2S(self.grid, "v", PISM.WITHOUT_GHOSTS) units = "30 days since 1-1-1" N = 12 self.t = numpy.arange(N, dtype=float) + 0.5 self.tb = numpy.arange(N + 1, dtype=float) self.f = 2 * (self.t > 6) - 1 def write_data(filename, use_bounds=True, forward=True): bounds = PISM.VariableMetadata("time_bounds", ctx.unit_system) bounds.set_string("units", units) output = PISM.util.prepare_output(filename, append_time=False) output.write_attribute("time", "units", units) if use_bounds: PISM.define_time_bounds(bounds, "time", "nv", output, PISM.PISM_DOUBLE) output.write_attribute("time", "bounds", "time_bounds") if forward: order = range(N) else: order = range(N - 1, -1, -1) for k in order: PISM.append_time(output, "time", self.t[k]) if use_bounds: PISM.write_time_bounds(output, bounds, k, (self.tb[k], self.tb[k + 1])) v.set(float(self.f[k])) v.write(output) # regular forcing file write_data(self.filename, use_bounds=True) # file without time bounds write_data(self.no_bounds, use_bounds=False) # file with invalid time order write_data(self.time_order, forward=False) # empty file PISM.util.prepare_output(self.empty) # file with one record output = PISM.util.prepare_output(self.one_record) v.set(float(self.f[-1])) v.write(output) # file without a time dimension v.set(float(self.f[-1])) v.set_time_independent(True) v.dump(self.no_time) self.times_linear = [1, 2, 3] self.values_linear = [2, -4, 3] self.bounds_linear = [0.5, 1.5, 2.5, 3.5] PISM.testing.create_forcing(self.grid, self.interp_linear, "v", "", values=self.values_linear, times=self.times_linear, time_bounds=self.bounds_linear)
def vertical_extrapolation_during_regridding_test(): "Test extrapolation in the vertical direction" # create a grid with 11 levels, 1000m thick ctx = PISM.Context() params = PISM.GridParameters(ctx.config) params.Lx = 1e5 params.Ly = 1e5 params.Mx = 3 params.My = 3 params.Mz = 11 params.Lz = 1000 params.registration = PISM.CELL_CORNER params.periodicity = PISM.NOT_PERIODIC params.ownership_ranges_from_options(ctx.size) z = np.linspace(0, params.Lz, params.Mz) params.z[:] = z grid = PISM.IceGrid(ctx.ctx, params) # create an IceModelVec that uses this grid v = PISM.IceModelVec3(grid, "test", PISM.WITHOUT_GHOSTS, grid.z()) v.set(0.0) # set a column with PISM.vec.Access(nocomm=[v]): v.set_column(1, 1, z) # save to a file file_name = filename("regridding") try: v.dump(file_name) # create a taller grid (to 2000m): params.Lz = 2000 params.Mz = 41 z_tall = np.linspace(0, params.Lz, params.Mz) params.z[:] = z_tall tall_grid = PISM.IceGrid(ctx.ctx, params) # create an IceModelVec that uses this grid v_tall = PISM.IceModelVec3(tall_grid, "test", PISM.WITHOUT_GHOSTS, tall_grid.z()) # Try regridding without extrapolation. This should fail. try: ctx.ctx.log().disable() v_tall.regrid(file_name, PISM.CRITICAL) ctx.ctx.log().enable() raise AssertionError( "Should not be able to regrid without extrapolation") except RuntimeError as e: pass # allow extrapolation during regridding ctx.config.set_flag("grid.allow_extrapolation", True) # regrid from test.nc ctx.ctx.log().disable() v_tall.regrid(file_name, PISM.CRITICAL) ctx.ctx.log().enable() # get a column with PISM.vec.Access(nocomm=[v_tall]): column = np.array(v_tall.get_column(1, 1)) # compute the desired result desired = np.r_[np.linspace(0, 1000, 21), np.zeros(20) + 1000] # compare np.testing.assert_almost_equal(column, desired) finally: os.remove(file_name)
def modelvecs_test(): "Test the ModelVecs class" grid = create_dummy_grid() mask = PISM.model.createIceMaskVec(grid) mask.set(PISM.MASK_GROUNDED) modeldata = PISM.model.ModelData(grid) vecs = modeldata.vecs vecs.add(mask, "ice_mask", writing=True) # use the default name, no writing vecs.add(PISM.model.createIceThicknessVec(grid)) try: vecs.add(mask, "ice_mask") return False except RuntimeError: # should fail: mask was added already pass # get a field: print("get() method: ice mask: ", vecs.get("ice_mask").metadata().get_string("long_name")) print("dot notation: ice mask: ", vecs.ice_mask.metadata().get_string("long_name")) try: vecs.invalid return False except AttributeError: # should fail pass try: vecs.get("invalid") return False except RuntimeError: # should fail pass # test __repr__ print(vecs) # test has() print("Has thickness?", vecs.has("thickness")) # test markForWriting vecs.markForWriting("ice_mask") vecs.markForWriting(mask) vecs.markForWriting("thk") # test write() output_file = filename("test_ModelVecs") try: pio = PISM.util.prepare_output(output_file) pio.close() vecs.write(output_file) # test writeall() vecs.writeall(output_file) finally: os.remove(output_file)
def setUp(self): suffix = filename("-scalar-forcing-") self.filename = "input" + suffix self.filename_decreasing = "decreasing" + suffix self.filename_wrong_bounds = "wrong-bounds" + suffix self.filename_2d = "2d" + suffix self.filename_1 = "one-value" + suffix self.filename_no_bounds = "no-bounds" + suffix def f(x): return np.sin(2 * np.pi / 12 * x) dt = 1.0 self.times = (0.5 + np.arange(12)) * dt self.values = f(self.times) self.times_long = (0.5 + np.arange(24)) * dt self.values_long = f(self.times_long) self.ts = np.linspace(0 + dt, 24 - dt, 1001) time_bounds = np.vstack( (self.times - 0.5 * dt, self.times + 0.5 * dt)).T.flatten() ctx.time.set_start(0) ctx.time.set_end(4) # good input PISM.testing.create_scalar_forcing(self.filename, "delta_T", "Kelvin", self.values, self.times, time_bounds) # non-increasing times PISM.testing.create_scalar_forcing(self.filename_decreasing, "delta_T", "Kelvin", [0, 1], [1, 0], time_bounds=[1, 2, 0, 1]) # wrong time bounds PISM.testing.create_scalar_forcing(self.filename_wrong_bounds, "delta_T", "Kelvin", [0, 1], [0, 1], time_bounds=[0, 2, 2, 3]) # invalid number of dimensions grid = create_dummy_grid() PISM.testing.create_forcing(grid, self.filename_2d, "delta_T", "Kelvin", [0, 1], "seconds since 1-1-1", times=[0, 1]) # only one value PISM.testing.create_scalar_forcing(self.filename_1, "delta_T", "Kelvin", [1], [0], time_bounds=[0, 4]) # no time bounds PISM.testing.create_scalar_forcing(self.filename_no_bounds, "delta_T", "Kelvin", [1], [0], time_bounds=None)
def setUp(self): self.output_file = filename("age") self.grid = self.create_dummy_grid()