def compute(self, grid, Mz, coarsening_factor): tauc = PISM.IceModelVec2S(grid, "tauc", PISM.WITHOUT_GHOSTS) tauc.set(0.0) enthalpy = PISM.IceModelVec3(grid, "enthalpy", PISM.WITHOUT_GHOSTS, grid.z()) enthalpy.set(0.0) model = PISM.BlatterTestHalfar(grid, Mz, coarsening_factor) geometry = PISM.Geometry(grid) with PISM.vec.Access(geometry.ice_thickness): for (i, j) in grid.points(): geometry.ice_thickness[i, j] = model.H_exact(grid.x(i)) geometry.bed_elevation.set(0.0) geometry.sea_level_elevation.set(0) geometry.ensure_consistency(0.0) model.init() inputs = PISM.StressBalanceInputs() inputs.geometry = geometry inputs.basal_yield_stress = tauc inputs.enthalpy = enthalpy model.update(inputs, True) return model
def run_model(grid): geometry = PISM.Geometry(grid) bed_model = PISM.LingleClark(grid) bed_uplift = PISM.IceModelVec2S(grid, "uplift", PISM.WITHOUT_GHOSTS) # start with a flat bed, no ice, and no uplift geometry.bed_elevation.set(0.0) geometry.ice_thickness.set(0.0) geometry.sea_level_elevation.set(-1000.0) # everything is grounded geometry.ensure_consistency(0.0) bed_uplift.set(0.0) bed_model.bootstrap(geometry.bed_elevation, bed_uplift, geometry.ice_thickness, geometry.sea_level_elevation) Mx2 = int(grid.Mx()) // 2 My2 = int(grid.My()) // 2 # add the load with PISM.vec.Access(nocomm=geometry.ice_thickness): for (i, j) in grid.points(): # if i == Mx2 and j == My2: if abs(i - Mx2) < 2 and abs(j - My2) < 2: geometry.ice_thickness[i, j] = 1000.0 # dt of zero disables the viscous part of the model, so all we get is the elastic # response bed_model.step(geometry.ice_thickness, geometry.sea_level_elevation, 0) return (geometry.ice_thickness.numpy(), bed_model.total_displacement().numpy(), bed_model.elastic_load_response_matrix().numpy())
def setUp(self): self.filename = tmp_name("atmosphere_yearly_cycle") self.grid = shallow_grid() self.geometry = PISM.Geometry(self.grid) self.T_mean = 250.0 self.T_summer = 270.0 self.P = 15.0 output = PISM.util.prepare_output(self.filename) precipitation(self.grid, self.P).write(output) T_mean = PISM.IceModelVec2S(self.grid, "air_temp_mean_annual", PISM.WITHOUT_GHOSTS) T_mean.set_attrs("climate", "mean annual near-surface air temperature", "K", "K", "", 0) T_mean.set(self.T_mean) T_mean.write(output) T_summer = PISM.IceModelVec2S(self.grid, "air_temp_mean_summer", PISM.WITHOUT_GHOSTS) T_summer.set_attrs("climate", "mean summer near-surface air temperature", "K", "K", "", 0) T_summer.set(self.T_summer) T_summer.write(output) config.set_string("atmosphere.yearly_cycle.file", self.filename)
def synthetic_geometry(grid): geometry = PISM.Geometry(grid) bed = geometry.bed_elevation thickness = geometry.ice_thickness with PISM.vec.Access([bed, thickness]): for i, j in grid.points(): xi = grid.x(i) b = flowline.bump(xi, x0=32e3, zmax=1625, zmin_l=-300, zmin_r=-650, sigma_l=7.5e3, sigma_r=20e3) s = flowline.bump(xi, x0=32e3, zmax=2000, zmin_l=-200, zmin_r=30, sigma_l=10e3, sigma_r=30e3) bed[i, j] = b thickness[i, j] = max(s - b, 0) geometry.sea_level_elevation.set(0) geometry.ensure_consistency(0) return geometry
def pik_test(): "Model PIK" grid = shallow_grid() geometry = PISM.Geometry(grid) ice_thickness = 1000.0 # meters # compute pressure melting temperature ice_density = config.get_number("constants.ice.density") T0 = config.get_number("constants.fresh_water.melting_point_temperature") beta_CC = config.get_number("constants.ice.beta_Clausius_Clapeyron") g = config.get_number("constants.standard_gravity") pressure = ice_density * g * ice_thickness T_melting = T0 - beta_CC * pressure average_water_column_pressure = water_column_pressure(ice_thickness) mass_flux = 5.36591610659e-06 # stored mass flux value returned by the model # create the model geometry.ice_thickness.set(ice_thickness) geometry.bed_elevation.set(-2 * ice_thickness) geometry.ensure_consistency(0.0) model = PISM.OceanPIK(grid) model.init(geometry) model.update(geometry, 0, 1) check_model(model, T_melting, mass_flux, average_water_column_pressure) assert model.max_timestep(0).infinite() == True
def setUp(self): depth = 1000.0 salinity = 35.0 potential_temperature = 270.0 self.melange_back_pressure = 0.0 self.temperature = 270.17909999999995 self.mass_flux = -6.489250000000001e-05 self.grid = shallow_grid() self.geometry = PISM.Geometry(self.grid) self.geometry.ice_thickness.set(depth) filename = "ocean_given_th_input.nc" self.filename = filename PISM.util.prepare_output(filename) Th = PISM.IceModelVec2S(self.grid, "theta_ocean", PISM.WITHOUT_GHOSTS) Th.set_attrs("climate", "potential temperature", "Kelvin", "Kelvin", "", 0) Th.set(potential_temperature) Th.write(filename) S = PISM.IceModelVec2S(self.grid, "salinity_ocean", PISM.WITHOUT_GHOSTS) S.set_attrs("climate", "ocean salinity", "g/kg", "g/kg", "", 0) S.set(salinity) S.write(filename) config.set_string("ocean.th.file", self.filename)
def _allocStdSSACoefficients(self): """Helper method that allocates the standard :cpp:class:`IceModelVec` variables used to solve the SSA and stores them in :attr:`modeldata```.vecs``: * ``surface`` * ``thickness`` * ``bed`` * ``tauc`` * ``enthalpy`` * ``mask`` * ``age`` if -age is given Intended to be called from custom implementations of :meth:`_initSSACoefficients` if desired.""" vecs = self.modeldata.vecs grid = self.grid self.geometry = PISM.Geometry(grid) geometry = self.geometry vecs.add(geometry.ice_surface_elevation) vecs.add(geometry.ice_thickness) vecs.add(geometry.bed_elevation) vecs.add(geometry.sea_level_elevation) vecs.add(geometry.cell_type) vecs.add(model.createYieldStressVec(grid), 'tauc') vecs.add(model.createEnthalpyVec(grid), 'enthalpy') # The SIA model might need the "age" field if grid.ctx().config().get_boolean("age.enabled"): vecs.add(model.createAgeVec(grid), "age")
def bed_def_iso(ice_thickness_change): "Use the pointwise isostasy model to compute plate deflection." # grid size and domain size are irrelevant M = 3 L = 1000e3 grid = PISM.IceGrid.Shallow(ctx, L, L, 0, 0, M, M, PISM.CELL_CORNER, PISM.NOT_PERIODIC) geometry = PISM.Geometry(grid) geometry.bed_elevation.set(0.0) geometry.sea_level_elevation.set(0.0) geometry.ice_thickness.set(0.0) geometry.ice_area_specific_volume.set(0.0) geometry.ensure_consistency(0.0) # uplift is required (but not used) bed_uplift = PISM.IceModelVec2S(grid, "uplift", PISM.WITHOUT_GHOSTS) bed_uplift.set(0.0) bed_model = PISM.PointwiseIsostasy(grid) bed_model.bootstrap(geometry.bed_elevation, bed_uplift, geometry.ice_thickness, geometry.sea_level_elevation) geometry.ice_thickness.set(ice_thickness_change) # time step duration is irrelevant bed_model.update(geometry.ice_thickness, geometry.sea_level_elevation, 0, 1) return bed_model.bed_elevation().numpy()[0,0]
def bed_def_given_test(self): "Test -bed_def given" model = PISM.GivenTopography(self.grid) geometry = PISM.Geometry(self.grid) geometry.ice_thickness.set(0.0) geometry.sea_level_elevation.set(0.0) opts = PISM.process_input_options(ctx.com, ctx.config) model.init(opts, geometry.ice_thickness, geometry.sea_level_elevation) # use dt == 0 to sample topg_delta at a predictable time dt = 0.0 model.update(geometry.ice_thickness, geometry.sea_level_elevation, 1, dt) topg_0 = model.bed_elevation().numpy()[0, 0] model.update(geometry.ice_thickness, geometry.sea_level_elevation, 2, dt) topg_1 = model.bed_elevation().numpy()[0, 0] # -4 - 2 == -6 (see the create_forcing() call above) np.testing.assert_almost_equal(topg_1 - topg_0, -6)
def run_model(grid, orography): "Run the PISM implementation of the model to compare to the Python version." model = PISM.AtmosphereOrographicPrecipitation( grid, PISM.AtmosphereUniform(grid)) geometry = PISM.Geometry(grid) with PISM.vec.Access(nocomm=geometry.ice_thickness): for i, j in grid.points(): geometry.ice_thickness[i, j] = orography[j, i] geometry.bed_elevation.set(0.0) geometry.sea_level_elevation.set(0.0) geometry.ice_area_specific_volume.set(0.0) # compute surface elevation from ice thickness and bed elevation geometry.ensure_consistency(0) model.init(geometry) model.update(geometry, 0, 1) config = PISM.Context().config water_density = config.get_number("constants.fresh_water.density") # convert from kg / (m^2 s) to mm/s return model.mean_precipitation().numpy() / (1e-3 * water_density)
def run(L, test): """Calls PISM's code to compute grounded cell fraction. Parameters ---------- L : controls the thickness in the interior of the icy patch test : chooses the shape of the patch ("box" or "cross") """ Lx, Ly = 1e5, 1e5 Mx, My = 7, 7 x0, y0 = 0.0, 0.0 grid = PISM.IceGrid.Shallow(ctx.ctx, Lx, Ly, x0, y0, Mx, My, PISM.CELL_CORNER, PISM.NOT_PERIODIC) sea_level = 500.0 geometry = PISM.Geometry(grid) ice_density = ctx.config.get_number("constants.ice.density") ocean_density = ctx.config.get_number("constants.sea_water.density") init(ice_density / ocean_density, L, sea_level, geometry.ice_thickness, test) geometry.bed_elevation.set(0.0) geometry.sea_level_elevation.set(sea_level) # this call computes the grounded fraction of each cell geometry.ensure_consistency(0.0) return geometry
def constant_test(): "Model Constant" depth = 1000.0 # meters # compute mass flux melt_rate = config.get_number("ocean.constant.melt_rate", "m second-1") ice_density = config.get_number("constants.ice.density") mass_flux = melt_rate * ice_density # compute pressure melting temperature T0 = config.get_number("constants.fresh_water.melting_point_temperature") beta_CC = config.get_number("constants.ice.beta_Clausius_Clapeyron") g = config.get_number("constants.standard_gravity") pressure = ice_density * g * depth T_melting = T0 - beta_CC * pressure melange_back_pressure = 0.0 grid = shallow_grid() geometry = PISM.Geometry(grid) geometry.ice_thickness.set(depth) model = PISM.OceanConstant(grid) model.init(geometry) model.update(geometry, 0, 1) check_model(model, T_melting, mass_flux, melange_back_pressure) assert model.max_timestep(0).infinite() == True
def constant_test(): "Model Constant" ice_thickness = 1000.0 # meters # compute mass flux melt_rate = config.get_number("ocean.constant.melt_rate", "m second-1") ice_density = config.get_number("constants.ice.density") mass_flux = melt_rate * ice_density # compute pressure melting temperature T0 = config.get_number("constants.fresh_water.melting_point_temperature") beta_CC = config.get_number("constants.ice.beta_Clausius_Clapeyron") g = config.get_number("constants.standard_gravity") pressure = ice_density * g * ice_thickness T_melting = T0 - beta_CC * pressure average_water_column_pressure = water_column_pressure(ice_thickness) grid = shallow_grid() geometry = PISM.Geometry(grid) geometry.ice_thickness.set(ice_thickness) geometry.bed_elevation.set(-2 * ice_thickness) geometry.ensure_consistency(0.0) model = PISM.OceanConstant(grid) model.init(geometry) model.update(geometry, 0, 1) check_model(model, T_melting, mass_flux, average_water_column_pressure) assert model.max_timestep(0).infinite() == True
def setUp(self): self.filename = tmp_name("ocean_frac_MBP_input") self.grid = shallow_grid() self.geometry = PISM.Geometry(self.grid) self.model = PISM.OceanConstant(self.grid) self.Lambda = 0.5 self.H = 1000.0 g = config.get_number("constants.standard_gravity") rho_w = config.get_number("constants.sea_water.density") rho_i = config.get_number("constants.ice.density") def P(depth, density, g): return 0.5 * density * g * depth P_water = water_column_pressure(self.H) P_ice = 0.5 * rho_i * g * self.H self.dP = self.Lambda * (P_ice - P_water) self.geometry.ice_thickness.set(self.H) self.geometry.bed_elevation.set(-2 * self.H) self.geometry.ensure_consistency(0.0) create_scalar_forcing(self.filename, "frac_MBP", "1", [self.Lambda], [0], time_bounds=[0, 1])
def setUp(self): self.filename = tmp_name("atmosphere_one_station") self.grid = shallow_grid() self.geometry = PISM.Geometry(self.grid) self.T = 263.15 self.P = 10.0 time_name = config.get_string("time.dimension_name") output = PISM.util.prepare_output(self.filename, append_time=True) output.redef() output.define_dimension("nv", 2) output.define_variable("time_bounds", PISM.PISM_DOUBLE, [time_name, "nv"]) output.write_attribute(time_name, "bounds", "time_bounds") output.define_variable("precipitation", PISM.PISM_DOUBLE, [time_name]) output.write_attribute("precipitation", "units", "kg m-2 s-1") output.define_variable("air_temp", PISM.PISM_DOUBLE, [time_name]) output.write_attribute("air_temp", "units", "Kelvin") output.write_variable("precipitation", [0], [1], [self.P]) output.write_variable("air_temp", [0], [1], [self.T]) output.write_variable("time_bounds", [0, 0], [1, 2], [0, 1]) output.close() config.set_string("atmosphere.one_station.file", self.filename)
def setUp(self): self.filename = tmp_name("atmosphere_anomaly_input") self.grid = shallow_grid() self.geometry = PISM.Geometry(self.grid) self.geometry.ice_thickness.set(1000.0) self.model = PISM.AtmosphereUniform(self.grid) self.dT = -5.0 self.dP = 20.0 dT = PISM.IceModelVec2S(self.grid, "air_temp_anomaly", PISM.WITHOUT_GHOSTS) dT.set_attrs("climate", "air temperature anomaly", "Kelvin", "Kelvin", "", 0) dT.set(self.dT) dP = PISM.IceModelVec2S(self.grid, "precipitation_anomaly", PISM.WITHOUT_GHOSTS) dP.set_attrs("climate", "precipitation anomaly", "kg m-2 s-1", "kg m-2 s-1", "", 0) dP.set(self.dP) output = PISM.util.prepare_output(self.filename) dT.write(output) dP.write(output) config.set_string("atmosphere.anomaly.file", self.filename)
def real_geometry(grid): def load(filename, prefix="data/"): data = np.genfromtxt(prefix + filename, delimiter=",", skip_header=1, usecols=(1, 3)) return data[:, 0], data[:, 1] x, b = load("bed.csv") _, H = load("thickness.csv") X = np.array(grid.x()) b = np.interp(X, x, b) H = np.interp(X, x, H) geometry = PISM.Geometry(grid) bed = geometry.bed_elevation thickness = geometry.ice_thickness with PISM.vec.Access([bed, thickness]): for i, j in grid.points(): bed[i, j] = b[i] thickness[i, j] = H[i] geometry.sea_level_elevation.set(0) geometry.ensure_consistency(0) return geometry
def setUp(self): self.filename = "surface_anomaly_input.nc" self.output_filename = "surface_anomaly_output.nc" self.grid = shallow_grid() self.geometry = PISM.Geometry(self.grid) self.model = surface_simple(self.grid) self.dSMB = -(config.get_number("atmosphere.uniform.precipitation", "kg m-2 s-1") + 5.0) self.dT = 2.0 PISM.util.prepare_output(self.filename) delta_SMB = PISM.IceModelVec2S(self.grid, "climatic_mass_balance_anomaly", PISM.WITHOUT_GHOSTS) delta_SMB.set_attrs("climate_forcing", "2D surface mass flux anomaly", "kg m-2 s-1", "kg m-2 s-1", "", 0) delta_SMB.set(self.dSMB) delta_SMB.write(self.filename) delta_T = PISM.IceModelVec2S(self.grid, "ice_surface_temp_anomaly", PISM.WITHOUT_GHOSTS) delta_T.set_attrs("climate_forcing", "2D surface temperature anomaly", "Kelvin", "Kelvin", "", 0) delta_T.set(self.dT) delta_T.write(self.filename)
def setUp(self): self.grid = shallow_grid() self.geometry = PISM.Geometry(self.grid) self.model = surface_simple(self.grid) self.filename = "surface_force_to_thickness_input.nc" self.output_filename = "surface_force_to_thickness_output.nc" self.H = 1000.0 self.dH = 1000.0 self.geometry.ice_thickness.set(self.H) # save ice thickness to a file to use as the target thickness PISM.util.prepare_output(self.filename) self.geometry.ice_thickness.write(self.filename) ftt_mask = PISM.IceModelVec2S(self.grid, "ftt_mask", PISM.WITHOUT_GHOSTS) ftt_mask.set(1.0) ftt_mask.write(self.filename) alpha = 10.0 ice_density = config.get_number("constants.ice.density") self.dSMB = -ice_density * alpha * self.dH config.set_string("surface.force_to_thickness_file", self.filename) config.set_number("surface.force_to_thickness.alpha", convert(alpha, "1/s", "1/year"))
def setUp(self): self.air_temp = config.get_number("atmosphere.uniform.temperature") self.precip = config.get_number("atmosphere.uniform.precipitation") self.grid = shallow_grid() self.geometry = PISM.Geometry(self.grid) # make sure that there's ice to melt self.geometry.ice_thickness.set(1000.0) T_above_zero = 1 dt_days = 5 self.T = 273.15 + T_above_zero self.dt = dt_days * 86400 ice_density = config.get_number("constants.ice.density") beta_ice = config.get_number("surface.pdd.factor_ice") refreeze_fraction = config.get_number("surface.pdd.refreeze") PDD = dt_days * T_above_zero ice_melted = PDD * beta_ice refreeze = ice_melted * refreeze_fraction self.SMB = -(ice_melted - refreeze) * ice_density / self.dt config.set_number("atmosphere.uniform.temperature", self.T) # disable daily variability so that we can compute the number of PDDs exactly config.set_number("surface.pdd.std_dev", 0.0) # no precipitation config.set_number("atmosphere.uniform.precipitation", 0)
def setUp(self): ice_thickness = 1000.0 salinity = 35.0 potential_temperature = 270.0 self.average_water_column_pressure = water_column_pressure( ice_thickness) self.temperature = 270.17909999999995 self.mass_flux = -6.489250000000001e-05 self.grid = shallow_grid() self.geometry = PISM.Geometry(self.grid) self.geometry.ice_thickness.set(ice_thickness) self.geometry.bed_elevation.set(-2 * ice_thickness) self.geometry.ensure_consistency(0.0) self.filename = tmp_name("ocean_given_th_input") filename = self.filename PISM.util.prepare_output(filename) Th = PISM.IceModelVec2S(self.grid, "theta_ocean", PISM.WITHOUT_GHOSTS) Th.set_attrs("climate", "potential temperature", "Kelvin", "Kelvin", "", 0) Th.set(potential_temperature) Th.write(filename) S = PISM.IceModelVec2S(self.grid, "salinity_ocean", PISM.WITHOUT_GHOSTS) S.set_attrs("climate", "ocean salinity", "g/kg", "g/kg", "", 0) S.set(salinity) S.write(filename) config.set_string("ocean.th.file", self.filename)
def setUp(self): self.filename = tmp_name("atmosphere_reference_surface") self.grid = shallow_grid() self.dTdz = 1.0 # Kelvin per km self.dPdz = 1000.0 # (kg/m^2)/year per km self.dz = 1000.0 # m self.dT = -self.dTdz * self.dz / 1000.0 self.dP = -PISM.util.convert(self.dPdz * self.dz / 1000.0, "kg m-2 year-1", "kg m-2 s-1") self.precip_dTdz = 2.0 # Kelvin per km self.geometry = PISM.Geometry(self.grid) # save current surface elevation to use it as a "reference" surface elevation self.geometry.ice_surface_elevation.dump(self.filename) config.set_string("atmosphere.elevation_change.file", self.filename) config.set_number( "atmosphere.elevation_change.precipitation.lapse_rate", self.dPdz) config.set_number( "atmosphere.elevation_change.precipitation.temp_lapse_rate", self.precip_dTdz) config.set_number("atmosphere.elevation_change.temperature_lapse_rate", self.dTdz)
def setUp(self): self.filename = "ocean_delta_SL_input.nc" self.grid = shallow_grid() self.geometry = PISM.Geometry(self.grid) self.model = PISM.SeaLevel(self.grid) self.dSL = -5.0 create_scalar_forcing(self.filename, "delta_SL", "meters", [self.dSL], [0])
def setUp(self): self.grid = shallow_grid() self.geometry = PISM.Geometry(self.grid) self.output_filename = "surface_elevation_output.nc" # change geometry just to make this a bit more interesting self.geometry.ice_thickness.set(1000.0) self.geometry.ensure_consistency(0.0)
def setUp(self): self.filename = "ocean_frac_SMB_input.nc" self.grid = shallow_grid() self.geometry = PISM.Geometry(self.grid) self.model = PISM.OceanConstant(self.grid) self.dSMB = 0.5 create_scalar_forcing(self.filename, "frac_mass_flux", "1", [self.dSMB], [0])
def setUp(self): self.grid = shallow_grid() self.geometry = PISM.Geometry(self.grid) self.P = 5.0 self.T = 250.0 config.set_number("atmosphere.uniform.temperature", self.T) config.set_number("atmosphere.uniform.precipitation", self.P)
def setUp(self): self.filename = "ocean_delta_SMB_input.nc" self.grid = shallow_grid() self.geometry = PISM.Geometry(self.grid) self.model = PISM.OceanConstant(self.grid) self.dSMB = -5.0 create_scalar_forcing(self.filename, "delta_mass_flux", "kg m-2 s-1", [self.dSMB], [0])
def setUp(self): self.filename = "ocean_delta_T_input.nc" self.grid = shallow_grid() self.geometry = PISM.Geometry(self.grid) self.geometry.ice_thickness.set(1000.0) self.model = PISM.OceanConstant(self.grid) self.dT = -5.0 PISM.testing.create_scalar_forcing(self.filename, "delta_T", "Kelvin", [self.dT], [0])
def setUp(self): self.filename = "ocean_frac_MBP_input.nc" self.grid = shallow_grid() self.geometry = PISM.Geometry(self.grid) self.model = PISM.OceanConstant(self.grid) self.dMBP = 0.5 create_scalar_forcing(self.filename, "frac_MBP", "1", [self.dMBP], [0]) config.set_number("ocean.melange_back_pressure_fraction", 1.0)
def computeSIASurfaceVelocities(modeldata, siasolver=PISM.SIAFD): """Generates surface horizontal velocities corresponding to solving the SIA with zero basal sliding. :param `modeldata`: :class:`PISM.model.ModelData` containing variables and model physics :param `siasolver`: specific class used for solving the SIA """ md = modeldata grid = md.grid sia = siasolver(grid) sia.init() geometry = PISM.Geometry(grid) geometry.ice_thickness.copy_from(md.vecs.thk) geometry.bed_elevation.copy_from(md.vecs.topg) geometry.sea_level_elevation.set(0.0) geometry.ice_area_specific_volume.set(0.0) geometry.ensure_consistency( md.config.get_number("geometry.ice_free_thickness_standard")) inputs = PISM.StressBalanceInputs() inputs.geometry = geometry inputs.basal_melt_rate = None inputs.melange_back_pressure = None inputs.basal_yield_stress = None inputs.enthalpy = md.vecs.enthalpy inputs.age = None sliding_velocity = PISM.IceModelVec2V(grid, 'sliding_velocity', PISM.WITHOUT_GHOSTS) sliding_velocity.set(0.0) sia.update(sliding_velocity, inputs, True) u = sia.velocity_u() v = sia.velocity_v() vel_sia = PISM.model.create2dVelocityVec(grid, name="_sia", stencil_width=1) u_sia = PISM.IceModelVec2S(grid, 'u_sia', PISM.WITHOUT_GHOSTS) v_sia = PISM.IceModelVec2S(grid, 'v_sia', PISM.WITHOUT_GHOSTS) PISM.extract_surface(u, md.vecs.thk, u_sia) PISM.extract_surface(v, md.vecs.thk, v_sia) with PISM.vec.Access([vel_sia, u_sia, v_sia]): for (i, j) in grid.points(): vel_sia[i, j].u = u_sia[i, j] vel_sia[i, j].v = v_sia[i, j] return vel_sia