def config(self, step): '''Generates a config file containing flags and parameters for a particular experiment and step. This takes care of flags and parameters that *cannot* be set using command-line options. (We try to use command-line options whenever we can.) ''' filename = "MISMIP_conf_%s_A%s.nc" % (self.experiment, step) nc = NC(filename, 'w', format="NETCDF3_CLASSIC") var = nc.createVariable("pism_overrides", 'i') attrs = { "is_dry_simulation": "no", "include_bmr_in_continuity": "no", "compute_surf_grad_inward_ssa": "no", "ice_softness": MISMIP.A(self.experiment, step), "ice_density": MISMIP.rho_i(), "sea_water_density": MISMIP.rho_w(), "bootstrapping_geothermal_flux_value_no_var": 0.0, "Glen_exponent": MISMIP.n(), "standard_gravity": MISMIP.g(), "ocean_sub_shelf_heat_flux_into_ice": 0.0, "bed_smoother_range": 0.0, } for name, value in attrs.iteritems(): var.setncattr(name, value) nc.close() return filename
def plot_flux(in_file, out_file): print( "Reading %s to plot ice flux for model %s, experiment %s, grid mode %s, step %s" % (in_file, model, experiment, mode, step)) if out_file is None: out_file = os.path.splitext(in_file)[0] + "-flux.pdf" x = read(in_file, 'x') flux_mag = read(in_file, 'flux_mag') # plot positive xs only flux_mag = flux_mag[x >= 0] x = x[x >= 0] figure(2) hold(True) plot(x / 1e3, flux_mag, 'k.-', markersize=10, linewidth=2) plot(x / 1e3, x * MISMIP.a() * MISMIP.secpera(), 'r:', linewidth=1.5) title("MISMIP experiment %s, step %d" % (experiment, step)) xlabel("x ($\mathrm{km}$)", size=14) ylabel(r"flux ($\mathrm{m}^2\,\mathrm{a}^{-1}$)", size=14) print("Saving '%s'...\n" % out_file) savefig(out_file, dpi=300, facecolor='w', edgecolor='w')
def physics_options(self, input_file, step): "Options corresponding to modeling choices." config_filename = self.config(step) options = ["-energy none", # isothermal setup; allows selecting cold-mode flow laws "-ssa_flow_law isothermal_glen", # isothermal setup "-yield_stress constant", "-tauc %e" % MISMIP.C(self.experiment), "-pseudo_plastic", "-gradient eta", "-pseudo_plastic_q %e" % MISMIP.m(self.experiment), "-pseudo_plastic_uthreshold %e" % MISMIP.secpera(), "-calving ocean_kill", # calving at the present front "-ocean_kill_file %s" % input_file, "-config_override %s" % config_filename, "-ssa_method fd", "-cfbc", # calving front boundary conditions "-part_grid", # sub-grid front motion parameterization "-ssafd_ksp_rtol 1e-7", "-ys 0", "-ye %d" % MISMIP.run_length(self.experiment, step), "-options_left", ] if self.model == 1: options.extend(["-stress_balance ssa"]) else: options.extend(["-stress_balance ssa+sia", "-sia_flow_law isothermal_glen", # isothermal setup ]) return options
def plot_flux(in_file, out_file): print("Reading %s to plot ice flux for model %s, experiment %s, grid mode %s, step %s" % ( in_file, model, experiment, mode, step)) if out_file is None: out_file = os.path.splitext(in_file)[0] + "-flux.pdf" x = read(in_file, 'x') flux_mag = read(in_file, 'flux_mag') # plot positive xs only flux_mag = flux_mag[x >= 0] x = x[x >= 0] figure(2) hold(True) plot(x / 1e3, flux_mag, 'k.-', markersize=10, linewidth=2) plot(x / 1e3, x * MISMIP.a() * MISMIP.secpera(), 'r:', linewidth=1.5) title("MISMIP experiment %s, step %d" % (experiment, step)) xlabel("x ($\mathrm{km}$)", size=14) ylabel(r"flux ($\mathrm{m}^2\,\mathrm{a}^{-1}$)", size=14) print("Saving '%s'...\n" % out_file) savefig(out_file, dpi=300, facecolor='w', edgecolor='w')
def physics_options(self, input_file, step): "Options corresponding to modeling choices." config_filename = self.config(step) options = [ "-energy none", # isothermal setup; allows selecting cold-mode flow laws "-ssa_flow_law isothermal_glen", # isothermal setup "-yield_stress constant", "-tauc %e" % MISMIP.C(self.experiment), "-pseudo_plastic", "-gradient eta", "-pseudo_plastic_q %e" % MISMIP.m(self.experiment), "-pseudo_plastic_uthreshold %e" % MISMIP.secpera(), "-calving ocean_kill", # calving at the present front "-ocean_kill_file %s" % input_file, "-config_override %s" % config_filename, "-ssa_method fd", "-cfbc", # calving front boundary conditions "-part_grid", # sub-grid front motion parameterization "-ssafd_ksp_rtol 1e-7", "-ys 0", "-ye %d" % MISMIP.run_length(self.experiment, step), "-options_left", ] if self.model == 1: options.extend(["-stress_balance ssa"]) else: options.extend([ "-stress_balance ssa+sia", "-sia_flow_law isothermal_glen", # isothermal setup ]) return options
def config(self, step): '''Generates a config file containing flags and parameters for a particular experiment and step. This takes care of flags and parameters that *cannot* be set using command-line options. (We try to use command-line options whenever we can.) ''' filename = "MISMIP_conf_%s_A%s.nc" % (self.experiment, step) nc = NC(filename, 'w', format="NETCDF3_CLASSIC") var = nc.createVariable("pism_overrides", 'i') attrs = {"is_dry_simulation": "no", "include_bmr_in_continuity": "no", "compute_surf_grad_inward_ssa": "no", "ice_softness": MISMIP.A(self.experiment, step), "ice_density": MISMIP.rho_i(), "sea_water_density": MISMIP.rho_w(), "bootstrapping_geothermal_flux_value_no_var": 0.0, "Glen_exponent": MISMIP.n(), "standard_gravity": MISMIP.g(), "ocean_sub_shelf_heat_flux_into_ice": 0.0, } if self.model != 1: attrs["bed_smoother_range"] = 0.0 for name, value in attrs.iteritems(): var.setncattr(name, value) nc.close() return filename
def plot_profile(in_file, out_file): print( "Reading %s to plot geometry profile for model %s, experiment %s, grid mode %s, step %s" % (in_file, model, experiment, mode, step)) if out_file is None: out_file = os.path.splitext(in_file)[0] + "-profile.pdf" mask = read(in_file, 'mask') usurf = read(in_file, 'usurf') topg = read(in_file, 'topg') thk = read(in_file, 'thk') x = read(in_file, 'x') # theoretical grounding line position xg = MISMIP.x_g(experiment, step) # modeled grounding line position xg_PISM = find_grounding_line(x, topg, thk, mask) # mask out ice-free areas usurf = np.ma.array(usurf, mask=mask == 4) # compute the lower surface elevation lsrf = topg.copy() lsrf[mask == 3] = -MISMIP.rho_i() / MISMIP.rho_w() * thk[mask == 3] lsrf = np.ma.array(lsrf, mask=mask == 4) # convert x to kilometers x /= 1e3 figure(1) ax = subplot(111) hold(True) plot(x, np.zeros_like(x), ls='dotted', color='red') plot(x, topg, color='black') plot(x, usurf, 'o', color='blue', markersize=4) plot(x, lsrf, 'o', color='blue', markersize=4) xlabel('distance from the divide, km') ylabel('elevation, m') title("MISMIP experiment %s, step %d" % (experiment, step)) text(0.6, 0.9, "$x_g$ (model) = %4.0f km" % (xg_PISM / 1e3), color='r', transform=ax.transAxes) text(0.6, 0.85, "$x_g$ (theory) = %4.0f km" % (xg / 1e3), color='black', transform=ax.transAxes) _, _, ymin, ymax = axis(xmin=0, xmax=x.max()) vlines(xg / 1e3, ymin, ymax, linestyles='dashed', color='black') vlines(xg_PISM / 1e3, ymin, ymax, linestyles='dashed', color='red') print("Saving '%s'...\n" % out_file) savefig(out_file)
def plot_profile(in_file, out_file): print("Reading %s to plot geometry profile for model %s, experiment %s, grid mode %s, step %s" % ( in_file, model, experiment, mode, step)) if out_file is None: out_file = os.path.splitext(in_file)[0] + "-profile.pdf" mask = read(in_file, 'mask') usurf = read(in_file, 'usurf') topg = read(in_file, 'topg') thk = read(in_file, 'thk') x = read(in_file, 'x') # theoretical grounding line position xg = MISMIP.x_g(experiment, step) # modeled grounding line position xg_PISM = find_grounding_line(x, topg, thk, mask) # mask out ice-free areas usurf = np.ma.array(usurf, mask=mask == 4) # compute the lower surface elevation lsrf = topg.copy() lsrf[mask == 3] = -MISMIP.rho_i() / MISMIP.rho_w() * thk[mask == 3] lsrf = np.ma.array(lsrf, mask=mask == 4) # convert x to kilometers x /= 1e3 figure(1) ax = subplot(111) hold(True) plot(x, np.zeros_like(x), ls='dotted', color='red') plot(x, topg, color='black') plot(x, usurf, 'o', color='blue', markersize=4) plot(x, lsrf, 'o', color='blue', markersize=4) xlabel('distance from the divide, km') ylabel('elevation, m') title("MISMIP experiment %s, step %d" % (experiment, step)) text(0.6, 0.9, "$x_g$ (model) = %4.0f km" % (xg_PISM / 1e3), color='r', transform=ax.transAxes) text(0.6, 0.85, "$x_g$ (theory) = %4.0f km" % (xg / 1e3), color='black', transform=ax.transAxes) _, _, ymin, ymax = axis(xmin=0, xmax=x.max()) vlines(xg / 1e3, ymin, ymax, linestyles='dashed', color='black') vlines(xg_PISM / 1e3, ymin, ymax, linestyles='dashed', color='red') print("Saving '%s'...\n" % out_file) savefig(out_file)
def thickness(experiment, step, x, calving_front=1750e3, semianalytical_profile=True): # we expect x to have an odd number of grid points so that one of them is # at 0 if x.size % 2 != 1: raise ValueError("x has to have an odd number of points, got %d", x.size) x_nonnegative = x[x >= 0] if not semianalytical_profile: thk_nonnegative = np.zeros_like(x_nonnegative) + 10 else: thk_nonnegative = MISMIP.thickness(experiment, step, x_nonnegative) thk_nonnegative[x_nonnegative > calving_front] = 0 thk = np.zeros_like(x) thk[x >= 0] = thk_nonnegative thk[x < 0] = thk_nonnegative[:0:-1] return np.tile(thk, (3, 1))
def __init__(self, experiment, model=1, mode=1, Mx=None, Mz=15, semianalytic=True, initials="ABC", executable=None): self.model = model self.mode = mode self.experiment = experiment self.initials = initials self.semianalytic = semianalytic if executable: self.executable = executable if mode == 3: self.Mx = Mx else: self.Mx = 2 * MISMIP.N(self.mode) + 1 self.My = 3 if self.experiment == "2b": self.Lz = 7000 else: self.Lz = 6000
def config(self, step): '''Generates a config file containing flags and parameters for a particular experiment and step. This takes care of flags and parameters that *cannot* be set using command-line options. (We try to use command-line options whenever we can.) ''' filename = "MISMIP_conf_%s_A%s.nc" % (self.experiment, step) nc = NC(filename, 'w', format="NETCDF3_CLASSIC") var = nc.createVariable("pism_overrides", 'i') attrs = { "ocean.always_grounded": "no", "geometry.update.use_basal_melt_rate": "no", "stress_balance.ssa.compute_surface_gradient_inward": "no", "flow_law.isothermal_Glen.ice_softness": MISMIP.A(self.experiment, step), "constants.ice.density": MISMIP.rho_i(), "constants.sea_water.density": MISMIP.rho_w(), "bootstrapping.defaults.geothermal_flux": 0.0, "stress_balance.ssa.Glen_exponent": MISMIP.n(), "constants.standard_gravity": MISMIP.g(), "ocean.sub_shelf_heat_flux_into_ice": 0.0, } if self.model != 1: attrs["stress_balance.sia.bed_smoother.range"] = 0.0 for name, value in attrs.items(): var.setncattr(name, value) nc.close() return filename
def physics_options(self, step): "Options corresponding to modeling choices." config_filename = self.config(step) options = [ "-cold", # allow selecting cold-mode flow laws "-sia_flow_law isothermal_glen", # isothermal setup "-ssa_flow_law isothermal_glen", # isothermal setup "-no_energy", # isothermal setup "-ssa_sliding", # use SSA "-hold_tauc", "-tauc %e" % MISMIP.C(self.experiment), "-pseudo_plastic", "-gradient eta", "-pseudo_plastic_q %e" % MISMIP.m(self.experiment), "-pseudo_plastic_uthreshold %e" % MISMIP.secpera(), "-ocean_kill", # calving at the present front "-config_override %s" % config_filename, "-ssa_method fd", # use the FD solver that includes PIK improvements "-cfbc", # calving front boundary conditions "-part_grid", # sub-grid front motion parameterization "-ksp_rtol 1e-7", "-ys 0", "-ye %f" % MISMIP.run_length(self.experiment, step), "-options_left", ] if self.model == 1: options.extend(["-no_sia"]) else: options.extend(["-sia"]) if self.mode in (2, 3): options.extend(["-skip", "-skip_max 10"]) return options
def thickness(experiment, step, x, calving_front=1750e3, semianalytical_profile=True): # we expect x to have an odd number of grid points so that one of them is # at 0 if x.size % 2 != 1: raise ValueError("x has to have an odd number of points, got %d", x.size) x_nonnegative = x[x >= 0] if not semianalytical_profile: thk_nonnegative = np.zeros_like(x_nonnegative) + 10 else: thk_nonnegative = MISMIP.thickness(experiment, step, x_nonnegative) thk_nonnegative[x_nonnegative > calving_front] = 0 thk = np.zeros_like(x) thk[x >= 0] = thk_nonnegative thk[x < 0] = thk_nonnegative[:0:-1] return np.tile(thk, (3, 1))
def thickness(x, step, Q0, H0, calving_front=1750e3, perturbation='default'): # we expect x to have an odd number of grid points so that one of them is # at 0 if x.size % 2 != 1: raise ValueError("x has to have an odd number of points, got %d", x.size) dx = x[1] - x[0] A0 = MISMIP.A('1a', step) print(A0, A0**(-1.0 / 3.0)) B0 = A0**(-1.0 / MISMIP.n()) #C = (900.0*9.8/(4.0*B0)*(1.0-900.0/1000.0))**3.0 C = (MISMIP.rho_i() * MISMIP.g() / (4.0 * B0) * (1.0 - MISMIP.rho_i() / MISMIP.rho_w()))**MISMIP.n() thk = (4.0 * C * np.maximum(x - 100e3, eps) / Q0 + H0**(-4.0))**(-0.25) #thk = (x-100e3)*(-1e-4) + 800.0 thk[x < 100e3] = 800.0 thk[0] = 0.0 if perturbation == 'p1': #perturbation i thk[x > calving_front - 1 * dx] -= 50.0 elif perturbation == 'p2': #perutbation i-1 thk[x > calving_front - 2 * dx] -= 50.0 thk[x > calving_front - 1 * dx] += 50.0 elif perturbation == 'p3': #perutbation i-2 thk[x > calving_front - 3 * dx] -= 50.0 thk[x > calving_front - 2 * dx] += 50.0 #perutbation gli+1 #thk[ x > 100e3 + 0.5*dx ] -= 200.0 #thk[ x > 100e3+1.5*dx ] += 200.0 #perutbation gli+2 #thk[ x > 100e3 + 1.5*dx ] -= 200.0 #thk[ x > 100e3+2.5*dx ] += 200.0 thk[x > calving_front] = 0.0 return np.tile(thk, (3, 1))
def pism_bootstrap_file(filename, step, v0, H0, calving_front=1750e3, N=None, p="default"): import PISMNC xx = x(N) yy = y(xx) print("dx", xx[1] - xx[0]) v0 = v0 / MISMIP.secpera() #H0 = 800.0 Q0 = H0 * v0 topg = bed_topography(xx) thk = thickness(xx, step, Q0, H0, calving_front, p) smb = surface_mass_balance(xx) temp = ice_surface_temp(xx) vel = Q0 / np.maximum(thk, eps) * MISMIP.secpera() vel[thk == 0.0] = 0.0 #vel = np.nan_to_num(Q0/thk)*MISMIP.secpera() bcm = bcmask(xx) vel0 = np.zeros_like(vel) okill = ocean_kill(thk) nc = PISMNC.PISMDataset(filename, 'w', format="NETCDF3_CLASSIC") nc.create_dimensions(xx, yy) nc.define_2d_field('topg', attrs={ 'units': 'm', 'long_name': 'bedrock surface elevation', 'standard_name': 'bedrock_altitude' }) nc.write('topg', topg) nc.define_2d_field('thk', attrs={ 'units': 'm', 'long_name': 'ice thickness', 'standard_name': 'land_ice_thickness' }) nc.write('thk', thk) nc.define_2d_field( 'climatic_mass_balance', attrs={ 'units': 'kg m-2 / s', 'long_name': 'ice-equivalent surface mass balance (accumulation/ablation) rate', 'standard_name': 'land_ice_surface_specific_mass_balance_flux' }) nc.write('climatic_mass_balance', smb) nc.define_2d_field( 'ice_surface_temp', attrs={ 'units': 'Kelvin', 'long_name': 'annual average ice surface temperature, below firn processes' }) nc.write('ice_surface_temp', temp) nc.define_2d_field('land_ice_area_fraction_retreat', attrs={ 'units': '', 'long_name': 'mask where -ocean_kill cuts off ice' }) nc.write('land_ice_area_fraction_retreat', okill) nc.define_2d_field('u_ssa_bc', attrs={'units': 'm/yr'}) nc.write('u_ssa_bc', vel) nc.define_2d_field('v_ssa_bc', attrs={'units': 'm/yr'}) nc.write('v_ssa_bc', vel0) nc.define_2d_field('bc_mask', attrs={}) nc.write('bc_mask', bcm) nc.close()
def surface_mass_balance(x): """Computes the surface mass balance.""" return np.tile(np.zeros_like(x) + MISMIP.a(), (3, 1)) * MISMIP.rho_i()
def bed_topography(experiment, x): """Computes bed elevation as a function of x. experiment can be '1a', '1b', '2a', '2b', '3a', '3b'. """ return np.tile(-MISMIP.b(experiment, np.abs(x)), (3, 1))
def f(j): "See equation (7) in Pattyn et al, 'Role of transition zones in marine ice sheet dynamics', 2005." z_sl = 0 return (z_sl - topg[j]) * MISMIP.rho_w() / (MISMIP.rho_i() * thk[j])
def bed_topography(experiment, x): """Computes bed elevation as a function of x. experiment can be '1a', '1b', '2a', '2b', '3a', '3b'. """ return np.tile(-MISMIP.b(experiment, np.abs(x)), (3, 1))
def surface_mass_balance(x): """Computes the surface mass balance.""" return np.tile(np.zeros_like(x) + MISMIP.a(), (3, 1))
def x(mismip_mode, N=None): if mismip_mode in (1, 2): return np.linspace(-MISMIP.L(), MISMIP.L(), 2 * MISMIP.N(mismip_mode) + 1) return np.linspace(-MISMIP.L(), MISMIP.L(), N)
def f(j): "See equation (7) in Pattyn et al, 'Role of transition zones in marine ice sheet dynamics', 2005." z_sl = 0 return (z_sl - topg[j]) * MISMIP.rho_w() / (MISMIP.rho_i() * thk[j])
def x(N=None): return np.linspace(0, MISMIP.L(), N)