def test_equilibrium(self): models = [KarthausModel, FluxBasedModel] vols = [] for model in models: fls = dummy_constant_bed() mb = LinearMassBalance(2600.) model = model(fls, mb_model=mb, glen_a=self.glen_a, fixed_dt=10 * SEC_IN_DAY) model.run_until_equilibrium() vols.append(model.volume_km3) ref_vols = [] for model in models: fls = dummy_constant_bed() mb = LinearMassBalance(2600.) model = model(fls, mb_model=mb, glen_a=self.glen_a, fixed_dt=10 * SEC_IN_DAY) model.run_until(600) ref_vols.append(model.volume_km3) np.testing.assert_allclose(ref_vols, vols, atol=0.01)
def test_mass_conservation(self): mb = LinearMassBalance(2600.) fls = dummy_constant_bed() model = MassConservationChecker(fls, mb_model=mb, y0=0., glen_a=self.glen_a) model.run_until(200) assert_allclose(model.total_mass, model.volume_m3, rtol=1e-3) fls = dummy_noisy_bed() model = MassConservationChecker(fls, mb_model=mb, y0=0., glen_a=self.glen_a) model.run_until(200) assert_allclose(model.total_mass, model.volume_m3, rtol=1e-3) fls = dummy_width_bed_tributary() model = MassConservationChecker(fls, mb_model=mb, y0=0., glen_a=self.glen_a) model.run_until(200) assert_allclose(model.total_mass, model.volume_m3, rtol=1e-3) # Calving! fls = dummy_constant_bed(hmax=1000., hmin=0., nx=100) mb = LinearMassBalance(450.) model = MassConservationChecker(fls, mb_model=mb, y0=0., glen_a=self.glen_a, is_tidewater=True) model.run_until(500) tot_vol = model.volume_m3 + model.calving_m3_since_y0 assert_allclose(model.total_mass, tot_vol, rtol=2e-2)
def apparent_mb_from_linear_mb(gdir, mb_gradient=3.): """Compute apparent mb from a linear mass-balance assumption (for testing). This is for testing currently, but could be used as alternative method for the inversion quite easily. Parameters ---------- gdir : oggm.GlacierDirectory """ # Do we have a calving glacier? cmb = calving_mb(gdir) # Get the height and widths along the fls h, w = gdir.get_inversion_flowline_hw() # Now find the ELA till the integrated mb is zero from oggm.core.massbalance import LinearMassBalance def to_minimize(ela_h): mbmod = LinearMassBalance(ela_h[0], grad=mb_gradient) smb = mbmod.get_specific_mb(h, w) return (smb - cmb)**2 ela_h = optimization.minimize(to_minimize, [0.], bounds=((0, 10000), )) ela_h = ela_h['x'][0] mbmod = LinearMassBalance(ela_h, grad=mb_gradient) # For each flowline compute the apparent MB fls = gdir.read_pickle('inversion_flowlines') # Reset flux for fl in fls: fl.flux = np.zeros(len(fl.surface_h)) # Flowlines in order to be sure rho = cfg.PARAMS['ice_density'] for fl in fls: mbz = mbmod.get_annual_mb(fl.surface_h) * cfg.SEC_IN_YEAR * rho fl.set_apparent_mb(mbz) # Check and write aflux = fls[-1].flux[-1] * 1e-9 / rho * gdir.grid.dx**2 # If not marine and a bit far from zero, warning if cmb == 0 and not np.allclose(fls[-1].flux[-1], 0., atol=0.01): log.warning('(%s) flux should be zero, but is: ' '%.4f km3 ice yr-1', gdir.rgi_id, aflux) # If not marine and quite far from zero, error if cmb == 0 and not np.allclose(fls[-1].flux[-1], 0., atol=1): msg = ('({}) flux should be zero, but is: {:.4f} km3 ice yr-1'.format( gdir.rgi_id, aflux)) raise RuntimeError(msg) gdir.write_pickle(fls, 'inversion_flowlines') gdir.write_pickle({ 'ela_h': ela_h, 'grad': mb_gradient }, 'linear_mb_params')
def test_constant_bed(self): models = [FluxBasedModel, MUSCLSuperBeeModel] lens = [] surface_h = [] volume = [] yrs = np.arange(1, 300, 2) for model in models: fls = dummy_constant_bed() mb = LinearMassBalance(2600.) model = model(fls, mb_model=mb, y0=0., glen_a=self.glen_a, fs=self.fs, fixed_dt=10 * SEC_IN_DAY) length = yrs * 0. vol = yrs * 0. for i, y in enumerate(yrs): model.run_until(y) assert model.yr == y length[i] = fls[-1].length_m vol[i] = fls[-1].volume_km3 lens.append(length) volume.append(vol) surface_h.append(fls[-1].surface_h.copy()) assert_allclose(lens[0][-1], lens[1][-1], atol=101) assert_allclose(volume[0][-1], volume[1][-1], atol=3e-3) assert rmsd(lens[0], lens[1]) < 50. assert rmsd(volume[0], volume[1]) < 2e-3 assert rmsd(surface_h[0], surface_h[1]) < 1.0
def test_adaptive_ts(self): models = [KarthausModel, FluxBasedModel, MUSCLSuperBeeModel] steps = [31 * SEC_IN_DAY, None, None] lens = [] surface_h = [] volume = [] yrs = np.arange(1, 500, 2) for model, step in zip(models, steps): fls = dummy_constant_bed() mb = LinearMassBalance(2600.) model = model(fls, mb_model=mb, glen_a=self.glen_a, fixed_dt=step) length = yrs * 0. vol = yrs * 0. for i, y in enumerate(yrs): model.run_until(y) length[i] = fls[-1].length_m vol[i] = fls[-1].volume_km3 lens.append(length) volume.append(vol) surface_h.append(fls[-1].surface_h.copy()) np.testing.assert_almost_equal(lens[0][-1], lens[1][-1]) np.testing.assert_allclose(volume[0][-1], volume[1][-1], atol=1e-2) np.testing.assert_allclose(volume[0][-1], volume[2][-1], atol=1e-2) self.assertTrue(utils.rmsd(lens[0], lens[1]) < 50.) self.assertTrue(utils.rmsd(volume[2], volume[1]) < 1e-3) self.assertTrue(utils.rmsd(surface_h[0], surface_h[1]) < 5) self.assertTrue(utils.rmsd(surface_h[1], surface_h[2]) < 5)
def test_timestepping(self): steps = ['ambitious', 'default', 'conservative', 'ultra-conservative'][::-1] lens = [] surface_h = [] volume = [] yrs = np.arange(1, 400, 2) for step in steps: fls = dummy_constant_bed() mb = LinearMassBalance(2600.) model = FluxBasedModel(fls, mb_model=mb, glen_a=self.glen_a, time_stepping=step) length = yrs * 0. vol = yrs * 0. for i, y in enumerate(yrs): model.run_until(y) length[i] = fls[-1].length_m vol[i] = fls[-1].volume_km3 lens.append(length) volume.append(vol) surface_h.append(fls[-1].surface_h.copy()) np.testing.assert_allclose(volume[0][-1], volume[1][-1], atol=1e-2) np.testing.assert_allclose(volume[0][-1], volume[2][-1], atol=1e-2) np.testing.assert_allclose(volume[0][-1], volume[3][-1], atol=1e-2)
def objfunc(surface_h): # glacier bed # This is the bed rock, linearily decreasing from 3000m altitude to 1000m, in 200 steps nx = 200 bed_h = np.linspace(3400, 1400, nx) # At the begining, there is no glacier so our glacier surface is at the bed altitude # Let's set the model grid spacing to 100m (needed later) map_dx = 100 # The units of widths is in "grid points", i.e. 3 grid points = 300 m in our case widths = np.zeros(nx) + 3. # Define our bed init_flowline = RectangularBedFlowline(surface_h=rescale(surface_h, nx), bed_h=bed_h, widths=widths, map_dx=map_dx) # ELA at 3000m a.s.l., gradient 4 mm m-1 mb_model = LinearMassBalance(3000, grad=4) #annual_mb = mb_model.get_mb(surface_h) * SEC_IN_YEAR # The model requires the initial glacier bed, a mass-balance model, and an initial time (the year y0) model = FlowlineModel(init_flowline, mb_model=mb_model, y0=150) model.run_until(300) measured = pickle.load( open('/home/juliaeis/PycharmProjects/find_inital_state/fls_300.pkl', 'rb')) f = abs(model.fls[-1].surface_h - measured.fls[-1].surface_h)+\ abs(min_length_m(model.fls)-measured.length_m)+\ abs(model.area_km2-measured.area_km2)+\ abs(model.volume_km3-measured.volume_km3) print(sum(f)) return sum(f)
def test_staggered_diagnostics(self): mb = LinearMassBalance(2600.) fls = dummy_constant_bed() model = FluxBasedModel(fls, mb_model=mb, y0=0.) model.run_until(700) assert_allclose(mb.get_specific_mb(fls=fls), 0, atol=10) # Check the flux just for fun fl = model.flux_stag[0] assert fl[0] == 0 # Now check the diags df = model.get_diagnostics() fl = model.fls[0] df['my_flux'] = np.cumsum(mb.get_annual_mb(fl.surface_h) * fl.widths_m * fl.dx_meter * cfg.SEC_IN_YEAR).clip(0) df = df.loc[df['ice_thick'] > 0] # Also convert ours df['ice_flux'] *= cfg.SEC_IN_YEAR df['ice_velocity'] *= cfg.SEC_IN_YEAR df['tributary_flux'] *= cfg.SEC_IN_YEAR assert_allclose(np.abs(df['ice_flux'] - df['my_flux']), 0, atol=35e3) assert df['ice_velocity'].max() > 25 assert df['tributary_flux'].max() == 0 fls = dummy_width_bed_tributary() model = FluxBasedModel(fls, mb_model=mb, y0=0.) model.run_until(500) df = model.get_diagnostics() df['ice_velocity'] *= cfg.SEC_IN_YEAR df['tributary_flux'] *= cfg.SEC_IN_YEAR df = df.loc[df['ice_thick'] > 0] assert df['ice_velocity'].max() > 50 assert df['tributary_flux'].max() > 30e4 df = model.get_diagnostics(fl_id=0) df = df.loc[df['ice_thick'] > 0] df['ice_velocity'] *= cfg.SEC_IN_YEAR df['tributary_flux'] *= cfg.SEC_IN_YEAR assert df['ice_velocity'].max() > 10 assert df['tributary_flux'].max() == 0
def run_model(param, gdir, ela): climate = LinearMassBalance(ela_h=ela) climate.temp_bias = param fls = gdir.read_pickle('model_flowlines') fls1 = copy.deepcopy(fls) fls1[-1].surface_h = y_start.fls[-1].surface_h model = FluxBasedModel(fls1, mb_model=climate, glen_a=cfg.A, y0=0) model.run_until(50) fls2 = copy.deepcopy(fls) fls2[-1].surface_h = copy.deepcopy(model.fls[-1].surface_h) real_model = FluxBasedModel(fls2, mb_model=past_climate, glen_a=cfg.A, y0=1850) real_model.run_until(1900) return [model, real_model]
def test_boundaries(self): fls = dummy_constant_bed() mb = LinearMassBalance(2000.) model = FluxBasedModel(fls, mb_model=mb, y0=0., glen_a=self.glen_a, fs=self.fs) with pytest.raises(RuntimeError) as excinfo: model.run_until(300) assert 'exceeds domain boundaries' in str(excinfo.value)
def test_mixed_bed(self): models = [KarthausModel, FluxBasedModel] flss = [dummy_constant_bed(), dummy_mixed_bed()] lens = [] surface_h = [] volume = [] widths = [] yrs = np.arange(1, 700, 2) # yrs = np.arange(1, 100, 2) for model, fls in zip(models, flss): mb = LinearMassBalance(2800.) model = model(fls, mb_model=mb, fs=self.fs_old, glen_a=self.aglen_old, fixed_dt=14 * SEC_IN_DAY) length = yrs * 0. vol = yrs * 0. for i, y in enumerate(yrs): model.run_until(y) assert model.yr == y length[i] = fls[-1].length_m vol[i] = fls[-1].volume_km3 lens.append(length) volume.append(vol) widths.append(fls[-1].widths_m.copy()) surface_h.append(fls[-1].surface_h.copy()) np.testing.assert_allclose(volume[0][-1], volume[1][-1], atol=2e-2) if do_plot: # pragma: no cover plt.plot(lens[0], 'r', label='normal') plt.plot(lens[1], 'b', label='mixed') plt.legend() plt.show() plt.plot(volume[0], 'r', label='normal') plt.plot(volume[1], 'b', label='mixed') plt.legend() plt.show() plt.plot(fls[-1].bed_h, 'k') plt.plot(surface_h[0], 'r', label='normal') plt.plot(surface_h[1], 'b', label='mixed') plt.legend() plt.show() plt.plot(widths[0], 'r', label='normal') plt.plot(widths[1], 'b', label='mixed') plt.legend() plt.show()
def test_run_until_and_store(self): fls = dummy_constant_bed() mb = LinearMassBalance(2600.) model = FluxBasedModel(fls, mb_model=mb) ds_f, ds_d = model.run_until_and_store(150) assert ds_d['length_m'][-1] > 1e3 df = model.get_diagnostics() assert (df['ice_velocity'].max() * cfg.SEC_IN_YEAR) > 10
def test_tributary(self): models = [KarthausModel, FluxBasedModel] steps = [15 * SEC_IN_DAY, None] flss = [dummy_width_bed(), dummy_width_bed_tributary()] lens = [] surface_h = [] volume = [] yrs = np.arange(1, 500, 2) for model, step, fls in zip(models, steps, flss): mb = LinearMassBalance(2600.) model = model(fls, mb_model=mb, fs=self.fs_old, glen_a=self.aglen_old, fixed_dt=step) length = yrs * 0. vol = yrs * 0. for i, y in enumerate(yrs): model.run_until(y) assert model.yr == y length[i] = fls[-1].length_m vol[i] = np.sum([f.volume_km3 for f in fls]) lens.append(length) volume.append(vol) surface_h.append(fls[-1].surface_h.copy()) np.testing.assert_allclose(lens[0][-1], lens[1][-1], atol=101) np.testing.assert_allclose(volume[0][-1], volume[1][-1], atol=2e-2) np.testing.assert_allclose(utils.rmsd(lens[0], lens[1]), 0., atol=70) np.testing.assert_allclose(utils.rmsd(volume[0], volume[1]), 0., atol=6e-3) np.testing.assert_allclose(utils.rmsd(surface_h[0], surface_h[1]), 0., atol=5) if do_plot: # pragma: no cover plt.plot(lens[0], 'r') plt.plot(lens[1], 'b') plt.show() plt.plot(volume[0], 'r') plt.plot(volume[1], 'b') plt.show() plt.plot(fls[-1].bed_h, 'k') plt.plot(surface_h[0], 'r') plt.plot(surface_h[1], 'b') plt.show()
def test_parabolic_bed(self): models = [flowline.KarthausModel, flowline.FluxBasedModel] flss = [dummy_constant_bed(), dummy_parabolic_bed()] lens = [] surface_h = [] volume = [] widths = [] yrs = np.arange(1, 700, 2) for model, fls in zip(models, flss): mb = LinearMassBalance(2800.) model = model(fls, mb_model=mb, glen_a=self.glen_a, fixed_dt=10 * SEC_IN_DAY) length = yrs * 0. vol = yrs * 0. for i, y in enumerate(yrs): model.run_until(y) length[i] = fls[-1].length_m vol[i] = fls[-1].volume_km3 lens.append(length) volume.append(vol) widths.append(fls[-1].widths_m.copy()) surface_h.append(fls[-1].surface_h.copy()) np.testing.assert_allclose(lens[0][-1], lens[1][-1], atol=1300) np.testing.assert_allclose(volume[0][-1], volume[1][-1], atol=1e-2) if do_plot: # pragma: no cover plt.plot(lens[0], 'r') plt.plot(lens[1], 'b') plt.show() plt.plot(volume[0], 'r') plt.plot(volume[1], 'b') plt.show() plt.plot(fls[-1].bed_h, 'k') plt.plot(surface_h[0], 'r') plt.plot(surface_h[1], 'b') plt.show() plt.plot(widths[0], 'r') plt.plot(widths[1], 'b') plt.show()
def test_find_flux_from_thickness(self): mb = LinearMassBalance(2600.) model = FluxBasedModel(dummy_constant_bed(), mb_model=mb) model.run_until(700) # Pick a flux and slope somewhere in the glacier for i in [1, 10, 20, 50]: flux = model.flux_stag[0][i] slope = model.slope_stag[0][i] thick = model.thick_stag[0][i] width = model.fls[0].widths_m[i] out = find_sia_flux_from_thickness(slope, width, thick) assert_allclose(out, flux, atol=1e-7)
def run_model(surface_h): nx = 200 bed_h = np.linspace(3400, 1400, nx) # At the begining, there is no glacier so our glacier surface is at the bed altitude # Let's set the model grid spacing to 100m (needed later) map_dx = 100 # The units of widths is in "grid points", i.e. 3 grid points = 300 m in our case widths = np.zeros(nx) + 3. # Define our bed init_flowline = RectangularBedFlowline(surface_h=rescale(surface_h, nx), bed_h=bed_h, widths=widths, map_dx=map_dx) # ELA at 3000m a.s.l., gradient 4 mm m-1 mb_model = LinearMassBalance(3000, grad=4) # annual_mb = mb_model.get_mb(surface_h) * SEC_IN_YEAR # The model requires the initial glacier bed, a mass-balance model, and an initial time (the year y0) model = FlowlineModel(init_flowline, mb_model=mb_model, y0=150) return model
def test_water_massbalance(): mb_mod = LinearMassBalance(ela_h=100, grad=1) to_test = mb_mod.get_annual_mb([200, 100, 0, -1, -100]) # Convert units to_test *= cfg.SEC_IN_YEAR * cfg.PARAMS['ice_density'] # Test assert_allclose(to_test, [100, 0, -100, -101, -200]) mb_mod = WaterMassBalance(ela_h=100, grad=1) to_test = mb_mod.get_annual_mb([200, 100, 0, -1, -100]) # Convert units to_test *= cfg.SEC_IN_YEAR * cfg.PARAMS['ice_density'] # Test assert_allclose(to_test, [100, 0, -100, 0, 0]) mb_mod = WaterMassBalance(ela_h=100, grad=1, underwater_melt=-1000) to_test = mb_mod.get_annual_mb([200, 100, 0, -1, -100]) # Convert units to_test *= cfg.SEC_IN_YEAR * cfg.PARAMS['ice_density'] # Test assert_allclose(to_test, [100, 0, -100, -1000, -1000])
def to_minimize(ela_h): mbmod = LinearMassBalance(ela_h[0], grad=mb_gradient) smb = mbmod.get_specific_mb(h, w) return (smb - cmb)**2
def test_random(self): # Fake Reset (all these tests are horribly coded) if not os.path.exists(TEST_DIR): os.makedirs(TEST_DIR) with open(CLI_LOGF, 'wb') as f: pickle.dump('none', f) gdirs = up_to_inversion(reset=False) # First tests df = utils.compile_glacier_statistics(gdirs) df['volume_before_calving_km3'] = df['volume_before_calving'] * 1e-9 assert np.sum(~df.volume_before_calving.isnull()) == 2 dfs = df.iloc[:2] assert np.all(dfs['volume_before_calving_km3'] < dfs['inv_volume_km3']) assert_allclose(df['inv_flowline_glacier_area'] * 1e-6, df['rgi_area_km2']) workflow.execute_entity_task(flowline.init_present_time_glacier, gdirs) # Check init_present_time_glacier not messing around too much for gd in gdirs: from oggm.core.massbalance import LinearMassBalance from oggm.core.flowline import FluxBasedModel mb_mod = LinearMassBalance(ela_h=2500) fls = gd.read_pickle('model_flowlines') model = FluxBasedModel(fls, mb_model=mb_mod) df.loc[gd.rgi_id, 'start_area_km2'] = model.area_km2 df.loc[gd.rgi_id, 'start_volume_km3'] = model.volume_km3 df.loc[gd.rgi_id, 'start_length'] = model.length_m assert_allclose(df['rgi_area_km2'], df['start_area_km2'], rtol=0.01) assert_allclose(df['rgi_area_km2'].sum(), df['start_area_km2'].sum(), rtol=0.005) assert_allclose(df['inv_volume_km3'], df['start_volume_km3']) assert_allclose(df['inv_volume_km3'].sum(), df['start_volume_km3'].sum()) assert_allclose(df['main_flowline_length'], df['start_length']) workflow.execute_entity_task(flowline.run_random_climate, gdirs, nyears=100, seed=0, store_monthly_step=True, output_filesuffix='_test') for gd in gdirs: path = gd.get_filepath('model_run', filesuffix='_test') # See that we are running ok with flowline.FileModel(path) as model: vol = model.volume_km3_ts() area = model.area_km2_ts() length = model.length_m_ts() self.assertTrue(np.all(np.isfinite(vol) & vol != 0.)) self.assertTrue(np.all(np.isfinite(area) & area != 0.)) self.assertTrue(np.all(np.isfinite(length) & length != 0.)) ds_diag = gd.get_filepath('model_diagnostics', filesuffix='_test') ds_diag = xr.open_dataset(ds_diag) df = vol.to_frame('RUN') df['DIAG'] = ds_diag.volume_m3.to_series() * 1e-9 assert_allclose(df.RUN, df.DIAG) df = area.to_frame('RUN') df['DIAG'] = ds_diag.area_m2.to_series() * 1e-6 assert_allclose(df.RUN, df.DIAG) df = length.to_frame('RUN') df['DIAG'] = ds_diag.length_m.to_series() assert_allclose(df.RUN, df.DIAG) # Test output ds = utils.compile_run_output(gdirs, input_filesuffix='_test') assert_allclose(ds_diag.volume_m3, ds.volume.sel(rgi_id=gd.rgi_id)) assert_allclose(ds_diag.area_m2, ds.area.sel(rgi_id=gd.rgi_id)) assert_allclose(ds_diag.length_m, ds.length.sel(rgi_id=gd.rgi_id)) df = ds.volume.sel(rgi_id=gd.rgi_id).to_series().to_frame('OUT') df['RUN'] = ds_diag.volume_m3.to_series() assert_allclose(df.RUN, df.OUT) # Compare to statistics df = utils.compile_glacier_statistics(gdirs) df['y0_vol'] = ds.volume.sel(rgi_id=df.index, time=0) * 1e-9 df['y0_area'] = ds.area.sel(rgi_id=df.index, time=0) * 1e-6 df['y0_len'] = ds.length.sel(rgi_id=df.index, time=0) assert_allclose(df['rgi_area_km2'], df['y0_area'], 0.06) assert_allclose(df['inv_volume_km3'], df['y0_vol'], 0.04) assert_allclose(df['main_flowline_length'], df['y0_len']) # Calving stuff assert ds.isel(rgi_id=0).calving[-1] > 0 assert ds.isel(rgi_id=0).calving_rate[-1] > 0 assert ds.isel(rgi_id=0).volume_bsl[-1] == 0 assert ds.isel(rgi_id=0).volume_bwl[-1] > 0 assert ds.isel(rgi_id=1).calving[-1] > 0 assert ds.isel(rgi_id=1).calving_rate[-1] > 0 assert not np.isfinite(ds.isel(rgi_id=1).volume_bsl[-1])
def test_trapezoidal_bed(self): tb = dummy_trapezoidal_bed()[0] np.testing.assert_almost_equal(tb._w0_m, tb.widths_m) np.testing.assert_almost_equal(tb.section, tb.widths_m * 0) np.testing.assert_almost_equal(tb.area_km2, 0) tb.section = tb.section np.testing.assert_almost_equal(tb._w0_m, tb.widths_m) np.testing.assert_almost_equal(tb.section, tb.widths_m * 0) np.testing.assert_almost_equal(tb.area_km2, 0) h = 50. sec = (2 * tb._w0_m + tb._lambdas * h) * h / 2 tb.section = sec np.testing.assert_almost_equal(sec, tb.section) np.testing.assert_almost_equal(sec * 0 + h, tb.thick) np.testing.assert_almost_equal(tb._w0_m + tb._lambdas * h, tb.widths_m) akm = (tb._w0_m + tb._lambdas * h) * len(sec) * 100 np.testing.assert_almost_equal(tb.area_m2, akm) models = [KarthausModel, FluxBasedModel] flss = [dummy_constant_bed(), dummy_trapezoidal_bed()] lens = [] surface_h = [] volume = [] widths = [] yrs = np.arange(1, 700, 2) for model, fls in zip(models, flss): mb = LinearMassBalance(2800.) model = model(fls, mb_model=mb, fs=self.fs_old, glen_a=self.aglen_old, fixed_dt=14 * SEC_IN_DAY) length = yrs * 0. vol = yrs * 0. for i, y in enumerate(yrs): model.run_until(y) length[i] = fls[-1].length_m vol[i] = fls[-1].volume_km3 lens.append(length) volume.append(vol) widths.append(fls[-1].widths_m.copy()) surface_h.append(fls[-1].surface_h.copy()) np.testing.assert_allclose(volume[0][-1], volume[1][-1], atol=1e-2) if do_plot: # pragma: no cover plt.plot(lens[0], 'r') plt.plot(lens[1], 'b') plt.show() plt.plot(volume[0], 'r') plt.plot(volume[1], 'b') plt.show() plt.plot(fls[-1].bed_h, 'k') plt.plot(surface_h[0], 'r') plt.plot(surface_h[1], 'b') plt.show() plt.plot(widths[0], 'r') plt.plot(widths[1], 'b') plt.show()
def test_constant_bed(self): map_dx = 100. yrs = np.arange(1, 400, 5) lens = [] volume = [] areas = [] surface_h = [] # Flowline case fls = dummy_constant_bed(hmax=3000., hmin=1000., nx=200, map_dx=map_dx, widths=1.) mb = LinearMassBalance(2600.) flmodel = FluxBasedModel(fls, mb_model=mb, y0=0.) length = yrs * 0. vol = yrs * 0. area = yrs * 0 for i, y in enumerate(yrs): flmodel.run_until(y) length[i] = fls[-1].length_m vol[i] = fls[-1].volume_km3 area[i] = fls[-1].area_km2 lens.append(length) volume.append(vol) areas.append(area) surface_h.append(fls[-1].surface_h.copy()) # Make a 2D bed out of the 1D bed_2d = np.repeat(fls[-1].bed_h, 3).reshape((fls[-1].nx, 3)) sdmodel = Upstream2D(bed_2d, dx=map_dx, mb_model=mb, y0=0., ice_thick_filter=None) length = yrs * 0. vol = yrs * 0. area = yrs * 0 for i, y in enumerate(yrs): sdmodel.run_until(y) surf_1d = sdmodel.ice_thick[:, 1] length[i] = np.sum(surf_1d > 0) * sdmodel.dx vol[i] = sdmodel.volume_km3 / 3 area[i] = sdmodel.area_km2 / 3 lens.append(length) volume.append(vol) areas.append(area) surface_h.append(sdmodel.surface_h[:, 1]) if do_plot: plt.figure() plt.plot(yrs, lens[0], 'r') plt.plot(yrs, lens[1], 'b') plt.title('Compare Length') plt.xlabel('years') plt.ylabel('[m]') plt.legend(['Flowline', '2D'], loc=2) plt.figure() plt.plot(yrs, volume[0], 'r') plt.plot(yrs, volume[1], 'b') plt.title('Compare Volume') plt.xlabel('years') plt.ylabel('[km^3]') plt.legend(['Flowline', '2D'], loc=2) plt.figure() plt.plot(fls[-1].bed_h, 'k') plt.plot(surface_h[0], 'r') plt.plot(surface_h[1], 'b') plt.title('Compare Shape') plt.xlabel('[m]') plt.ylabel('Elevation [m]') plt.legend(['Bed', 'Flowline', '2D'], loc=2) plt.show() np.testing.assert_almost_equal(lens[0][-1], lens[1][-1]) np.testing.assert_allclose(volume[0][-1], volume[1][-1], atol=3e-3) self.assertTrue(utils.rmsd(lens[0], lens[1]) < 50.) self.assertTrue(utils.rmsd(volume[0], volume[1]) < 2e-3) self.assertTrue(utils.rmsd(areas[0], areas[1]) < 2e-3) self.assertTrue(utils.rmsd(surface_h[0], surface_h[1]) < 1.0) # Equilibrium sdmodel.run_until_equilibrium() flmodel.run_until_equilibrium() assert_allclose(sdmodel.volume_km3 / 3, flmodel.volume_km3, atol=2e-3) assert_allclose(sdmodel.area_km2 / 3, flmodel.area_km2, atol=2e-3) # Store run_ds = sdmodel.run_until_and_store(sdmodel.yr + 50) ts = run_ds['ice_thickness'].mean(dim=['y', 'x']) assert_allclose(ts, ts.values[0], atol=1) # Other direction bed_2d = np.repeat(fls[-1].bed_h, 3).reshape((fls[-1].nx, 3)).T sdmodel = Upstream2D(bed_2d, dx=map_dx, mb_model=mb, y0=0., ice_thick_filter=None) length = yrs * 0. vol = yrs * 0. area = yrs * 0 for i, y in enumerate(yrs): sdmodel.run_until(y) surf_1d = sdmodel.ice_thick[1, :] length[i] = np.sum(surf_1d > 0) * sdmodel.dx vol[i] = sdmodel.volume_km3 / 3 area[i] = sdmodel.area_km2 / 3 lens.append(length) volume.append(vol) areas.append(area) surface_h.append(sdmodel.surface_h[:, 1]) np.testing.assert_almost_equal(lens[0][-1], lens[1][-1]) np.testing.assert_allclose(volume[0][-1], volume[1][-1], atol=3e-3) self.assertTrue(utils.rmsd(lens[0], lens[1]) < 50.) self.assertTrue(utils.rmsd(volume[0], volume[1]) < 2e-3) self.assertTrue(utils.rmsd(areas[0], areas[1]) < 2e-3) self.assertTrue(utils.rmsd(surface_h[0], surface_h[1]) < 1.0) # Equilibrium sdmodel.run_until_equilibrium() assert_allclose(sdmodel.volume_km3 / 3, flmodel.volume_km3, atol=2e-3) assert_allclose(sdmodel.area_km2 / 3, flmodel.area_km2, atol=2e-3)
def test_varying_width(self): """This test is for a flowline glacier of variying width, i.e with an accumulation area twice as wide as the tongue.""" # TODO: @alexjarosch here we should have a look at MUSCLSuperBeeModel # set do_plot = True to see the plots models = [KarthausModel, FluxBasedModel, MUSCLSuperBeeModel] steps = [15 * SEC_IN_DAY, None, None] lens = [] surface_h = [] volume = [] yrs = np.arange(1, 500, 2) for model, step in zip(models, steps): fls = dummy_width_bed() mb = LinearMassBalance(2600.) model = model(fls, mb_model=mb, glen_a=self.glen_a, fixed_dt=step) length = yrs * 0. vol = yrs * 0. for i, y in enumerate(yrs): model.run_until(y) length[i] = fls[-1].length_m vol[i] = fls[-1].volume_km3 lens.append(length) volume.append(vol) surface_h.append(fls[-1].surface_h.copy()) if do_plot: # pragma: no cover plt.figure() plt.plot(yrs, lens[0], 'r') plt.plot(yrs, lens[1], 'b') plt.plot(yrs, lens[2], 'g') plt.title('Compare Length') plt.xlabel('years') plt.ylabel('[m]') plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2) plt.figure() plt.plot(yrs, volume[0], 'r') plt.plot(yrs, volume[1], 'b') plt.plot(yrs, volume[2], 'g') plt.title('Compare Volume') plt.xlabel('years') plt.ylabel('[km^3]') plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2) plt.figure() plt.plot(fls[-1].bed_h, 'k') plt.plot(surface_h[0], 'r') plt.plot(surface_h[1], 'b') plt.plot(surface_h[2], 'g') plt.title('Compare Shape') plt.xlabel('[m]') plt.ylabel('Elevation [m]') plt.legend(['Bed', 'Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=3) plt.show() np.testing.assert_almost_equal(lens[0][-1], lens[1][-1]) np.testing.assert_allclose(volume[0][-1], volume[1][-1], atol=2e-2) np.testing.assert_allclose(utils.rmsd(lens[0], lens[1]), 0., atol=70) np.testing.assert_allclose(utils.rmsd(volume[0], volume[1]), 0., atol=1e-2) np.testing.assert_allclose(utils.rmsd(surface_h[0], surface_h[1]), 0., atol=5)
def test_constant_bed(self): models = [KarthausModel, FluxBasedModel, MUSCLSuperBeeModel] lens = [] surface_h = [] volume = [] yrs = np.arange(1, 700, 2) for model in models: fls = dummy_constant_bed() mb = LinearMassBalance(2600.) model = model(fls, mb_model=mb, y0=0., glen_a=self.glen_a, fs=self.fs, fixed_dt=10 * SEC_IN_DAY) length = yrs * 0. vol = yrs * 0. for i, y in enumerate(yrs): model.run_until(y) length[i] = fls[-1].length_m vol[i] = fls[-1].volume_km3 lens.append(length) volume.append(vol) surface_h.append(fls[-1].surface_h.copy()) if do_plot: plt.figure() plt.plot(yrs, lens[0], 'r') plt.plot(yrs, lens[1], 'b') plt.plot(yrs, lens[2], 'g') plt.title('Compare Length') plt.xlabel('years') plt.ylabel('[m]') plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2) plt.figure() plt.plot(yrs, volume[0], 'r') plt.plot(yrs, volume[1], 'b') plt.plot(yrs, volume[2], 'g') plt.title('Compare Volume') plt.xlabel('years') plt.ylabel('[km^3]') plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2) plt.figure() plt.plot(fls[-1].bed_h, 'k') plt.plot(surface_h[0], 'r') plt.plot(surface_h[1], 'b') plt.plot(surface_h[2], 'g') plt.title('Compare Shape') plt.xlabel('[m]') plt.ylabel('Elevation [m]') plt.legend(['Bed', 'Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=3) plt.show() np.testing.assert_almost_equal(lens[0][-1], lens[1][-1]) np.testing.assert_allclose(volume[0][-1], volume[2][-1], atol=3e-3) np.testing.assert_allclose(volume[1][-1], volume[2][-1], atol=3e-3) self.assertTrue(utils.rmsd(lens[0], lens[2]) < 50.) self.assertTrue(utils.rmsd(lens[1], lens[2]) < 50.) self.assertTrue(utils.rmsd(volume[0], volume[2]) < 2e-3) self.assertTrue(utils.rmsd(volume[1], volume[2]) < 2e-3) self.assertTrue(utils.rmsd(surface_h[0], surface_h[2]) < 1.0) self.assertTrue(utils.rmsd(surface_h[1], surface_h[2]) < 1.0)
def test_run_until(self): # Just check that exotic times are guaranteed to be met yrs = np.array([10.2, 10.2, 10.200001, 10.3, 99.999, 150.]) models = [KarthausModel, FluxBasedModel, MUSCLSuperBeeModel] steps = [31 * SEC_IN_DAY, None, None] # Annual update lens = [] surface_h = [] volume = [] for model, step in zip(models, steps): fls = dummy_constant_bed() mb = LinearMassBalance(2600.) model = model(fls, mb_model=mb, glen_a=self.glen_a, fixed_dt=step) # Codecov with pytest.raises(InvalidParamsError): model.step(0.) length = yrs * 0. vol = yrs * 0. for i, y in enumerate(yrs): model.run_until(y) assert model.yr == y length[i] = fls[-1].length_m vol[i] = fls[-1].volume_km3 lens.append(length) volume.append(vol) surface_h.append(fls[-1].surface_h.copy()) np.testing.assert_almost_equal(lens[0][-1], lens[1][-1]) np.testing.assert_allclose(volume[0][-1], volume[1][-1], atol=1e-2) np.testing.assert_allclose(volume[0][-1], volume[2][-1], atol=1e-2) assert utils.rmsd(lens[0], lens[1]) < 50. assert utils.rmsd(volume[2], volume[1]) < 1e-3 assert utils.rmsd(surface_h[0], surface_h[1]) < 5 assert utils.rmsd(surface_h[1], surface_h[2]) < 5 # Always update lens = [] surface_h = [] volume = [] for model, step in zip(models, steps): fls = dummy_constant_bed() mb = LinearMassBalance(2600.) model = model(fls, mb_model=mb, glen_a=self.glen_a, fixed_dt=step, mb_elev_feedback='always') length = yrs * 0. vol = yrs * 0. for i, y in enumerate(yrs): model.run_until(y) assert model.yr == y length[i] = fls[-1].length_m vol[i] = fls[-1].volume_km3 lens.append(length) volume.append(vol) surface_h.append(fls[-1].surface_h.copy()) np.testing.assert_almost_equal(lens[0][-1], lens[1][-1]) np.testing.assert_allclose(volume[0][-1], volume[1][-1], atol=1e-2) np.testing.assert_allclose(volume[0][-1], volume[2][-1], atol=1e-2) assert utils.rmsd(lens[0], lens[1]) < 50. assert utils.rmsd(volume[2], volume[1]) < 1e-3 assert utils.rmsd(surface_h[0], surface_h[1]) < 5 assert utils.rmsd(surface_h[1], surface_h[2]) < 5
def test_noisy_bed(self): models = [KarthausModel, FluxBasedModel, MUSCLSuperBeeModel] steps = [15 * SEC_IN_DAY, None, None] lens = [] surface_h = [] volume = [] yrs = np.arange(1, 500, 2) fls_orig = dummy_noisy_bed() for model, step in zip(models, steps): fls = copy.deepcopy(fls_orig) mb = LinearMassBalance(2600.) model = model(fls, mb_model=mb, glen_a=self.glen_a, fixed_dt=step) length = yrs * 0. vol = yrs * 0. for i, y in enumerate(yrs): model.run_until(y) length[i] = fls[-1].length_m vol[i] = fls[-1].volume_km3 lens.append(length) volume.append(vol) surface_h.append(fls[-1].surface_h.copy()) if do_plot: # pragma: no cover plt.figure() plt.plot(yrs, lens[0], 'r') plt.plot(yrs, lens[1], 'b') plt.plot(yrs, lens[2], 'g') plt.title('Compare Length') plt.xlabel('years') plt.ylabel('[m]') plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2) plt.figure() plt.plot(yrs, volume[0], 'r') plt.plot(yrs, volume[1], 'b') plt.plot(yrs, volume[2], 'g') plt.title('Compare Volume') plt.xlabel('years') plt.ylabel('[km^3]') plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2) plt.figure() plt.plot(fls[-1].bed_h, 'k') plt.plot(surface_h[0], 'r') plt.plot(surface_h[1], 'b') plt.plot(surface_h[2], 'g') plt.title('Compare Shape') plt.xlabel('[m]') plt.ylabel('Elevation [m]') plt.legend(['Bed', 'Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=3) plt.show() np.testing.assert_allclose(lens[0][-1], lens[1][-1], atol=101) np.testing.assert_allclose(volume[0][-1], volume[1][-1], atol=1e-2) np.testing.assert_allclose(volume[0][-1], volume[2][-1], atol=1e-2) self.assertTrue(utils.rmsd(lens[0], lens[1]) < 100.) self.assertTrue(utils.rmsd(volume[0], volume[1]) < 1e-1) self.assertTrue(utils.rmsd(volume[0], volume[2]) < 1e-1) self.assertTrue(utils.rmsd(surface_h[0], surface_h[1]) < 10) self.assertTrue(utils.rmsd(surface_h[0], surface_h[2]) < 10)
dummy_constant_bed_cliff) # Figure f = 0.7 f, axs = plt.subplots(2, 2, figsize=(10 * f, 7 * f), sharey=True, sharex=True) axs = np.asarray(axs).flatten() tx, ty = .98, .97 letkm = dict(color='black', ha='right', va='top', fontsize=12, bbox=dict(facecolor='white', edgecolor='black')) fls = dummy_constant_bed(map_dx=gdir.grid.dx) mb = LinearMassBalance(2600.) model = FluxBasedModel(fls, mb_model=mb, y0=0.) model.run_until_equilibrium() fls = [] for fl in model.fls: pg = np.where(fl.thick > 0) line = shpg.LineString([fl.line.coords[int(p)] for p in pg[0]]) flo = Centerline(line, dx=fl.dx, surface_h=fl.surface_h[pg]) flo.widths = fl.widths[pg] flo.is_rectangular = np.ones(flo.nx).astype(np.bool) fls.append(flo) gdir.write_pickle(fls, 'inversion_flowlines') tasks.apparent_mb_from_linear_mb(gdir) tasks.prepare_for_inversion(gdir) v, _ = mass_conservation_inversion(gdir)
def linear_mb_equilibrium(bed, surface, accw, elaw, nz, mb_grad, nx, map_dx, idx=None, advance=None, retreat=None, plot=True): """Runs the OGGM FluxBasedModel with a linear mass balance gradient until the glacier reaches equilibrium. Parameters ---------- bed : ndarray the glacier bed surface : ndarray the initial glacier surface accw : int the width of the glacier at the top of the accumulation area elaw : int the width of the glacier at the equilibrium line altitude nz : float fraction of vertical grid points occupied by accumulation area mb_grad : int, float the mass balance altitude gradient in mm w.e. m^-1 yr^-1 nx : int number of grid points map_dx : int grid point spacing idx : int, optional number of vertical grid points to shift ELA down/upglacier advance : bool, optional move the ELA downglacier by idx grid points to simulate a glacier advance retreat : bool, optional move the ELA upglacier by idx grid points to simulate a glacier retreat plot : bool, optional show a pseudo-3d plot of the glacier (default: True) Returns ------- model : oggm.core.flowline.FluxBasedModel OGGM model class of the glacier in equilibrium """ # accumulation area occupies a fraction NZ of the total glacier extent acc_width = np.linspace(accw, elaw, int(nx * nz)) # ablation area occupies a fraction 1 - NZ of the total glacier extent abl_width = np.tile(elaw, nx - len(acc_width)) # glacier widths profile widths = np.hstack([acc_width, abl_width]) # model widths mwidths = np.zeros(nx) + widths / map_dx # define the glacier bed init_flowline = RectangularBedFlowline(surface_h=surface, bed_h=bed, widths=mwidths, map_dx=map_dx) # equilibrium line altitude # in case of an advance scenario, move the ELA downglacier by a number of # vertical grid points idx if advance and idx: ela = bed[np.where(widths == elaw)[0][idx]] # in case of a retreat scenario, move the ELA upglacier by a number of # vertical grid points idx elif retreat and idx: ela = bed[np.where(widths == acc_width[-idx])[0][0]] # in case of no scenario, the ela is the height where the width of the ela # is first reached else: ela = bed[np.where(widths == elaw)[0][0]] # linear mass balance model mb_model = LinearMassBalance(ela, grad=mb_grad) # flowline model model = FluxBasedModel(init_flowline, mb_model=mb_model, y0=0., min_dt=0, cfl_number=0.01) # run until the glacier reaches an equilibrium model.run_until_equilibrium() # show a pseudo-3d plot of the glacier geometry if plot: dis = distance_along_glacier(nx, map_dx) plot_glacier_3d(dis, bed, widths, nx) return model
def test_cliff(self): """ a test case for mass conservation in the flowline models the idea is to introduce a cliff in the sloping bed and see what the models do when the cliff height is changed """ models = [KarthausModel, FluxBasedModel, MUSCLSuperBeeModel] lens = [] surface_h = [] volume = [] yrs = np.arange(1, 500, 2) for model in models: fls = dummy_constant_bed_cliff() mb = LinearMassBalance(2600.) model = model(fls, mb_model=mb, y0=0., glen_a=self.glen_a, fs=self.fs, fixed_dt=2 * SEC_IN_DAY) length = yrs * 0. vol = yrs * 0. for i, y in enumerate(yrs): model.run_until(y) length[i] = fls[-1].length_m vol[i] = fls[-1].volume_km3 lens.append(length) volume.append(vol) surface_h.append(fls[-1].surface_h.copy()) if False: # pragma: no cover plt.figure() plt.plot(yrs, lens[0], 'r') plt.plot(yrs, lens[1], 'b') plt.plot(yrs, lens[2], 'g') plt.title('Compare Length') plt.xlabel('years') plt.ylabel('[m]') plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2) plt.figure() plt.plot(yrs, volume[0], 'r') plt.plot(yrs, volume[1], 'b') plt.plot(yrs, volume[2], 'g') plt.title('Compare Volume') plt.xlabel('years') plt.ylabel('[km^3]') plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2) plt.figure() plt.plot(fls[-1].bed_h, 'k') plt.plot(surface_h[0], 'r') plt.plot(surface_h[1], 'b') plt.plot(surface_h[2], 'g') plt.title('Compare Shape') plt.xlabel('[m]') plt.ylabel('Elevation [m]') plt.legend(['Bed', 'Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=3) plt.show() # OK, so basically, Alex's tests below show that the other models # are wrong and produce too much mass. There is also another more # more trivial issue with the computation of the length, I added a # "to do" in the code. # Unit-testing perspective: # "verify" that indeed the models are wrong of more than 50% self.assertTrue(volume[1][-1] > volume[2][-1] * 1.5) # Karthaus is even worse self.assertTrue(volume[0][-1] > volume[1][-1]) if False: # TODO: this will always fail so ignore it for now np.testing.assert_almost_equal(lens[0][-1], lens[1][-1]) np.testing.assert_allclose(volume[0][-1], volume[2][-1], atol=2e-3) np.testing.assert_allclose(volume[1][-1], volume[2][-1], atol=2e-3) self.assertTrue(utils.rmsd(lens[0], lens[2]) < 50.) self.assertTrue(utils.rmsd(lens[1], lens[2]) < 50.) self.assertTrue(utils.rmsd(volume[0], volume[2]) < 1e-3) self.assertTrue(utils.rmsd(volume[1], volume[2]) < 1e-3) self.assertTrue(utils.rmsd(surface_h[0], surface_h[2]) < 1.0) self.assertTrue(utils.rmsd(surface_h[1], surface_h[2]) < 1.0)
def test_min_slope(self): """ Check what is the min slope a flowline model can produce """ models = [KarthausModel, FluxBasedModel, MUSCLSuperBeeModel] kwargs = [{'fixed_dt': 3 * SEC_IN_DAY}, {}, {}] lens = [] surface_h = [] volume = [] min_slope = [] yrs = np.arange(1, 700, 2) for model, kw in zip(models, kwargs): fls = dummy_constant_bed_obstacle() mb = LinearMassBalance(2600.) model = model(fls, mb_model=mb, y0=0., glen_a=self.glen_a, **kw) length = yrs * 0. vol = yrs * 0. slope = yrs * 0. for i, y in enumerate(yrs): model.run_until(y) fl = fls[-1] length[i] = fl.length_m vol[i] = fl.volume_km3 hgt = np.where(fl.thick > 0, fl.surface_h, np.NaN) sl = np.arctan(-np.gradient(hgt, fl.dx_meter)) slope[i] = np.rad2deg(np.nanmin(sl)) lens.append(length) volume.append(vol) min_slope.append(slope) surface_h.append(fls[-1].surface_h.copy()) np.testing.assert_allclose(lens[0][-1], lens[1][-1], atol=101) np.testing.assert_allclose(volume[0][-1], volume[2][-1], atol=2e-3) np.testing.assert_allclose(volume[1][-1], volume[2][-1], atol=5e-3) self.assertTrue(utils.rmsd(volume[0], volume[2]) < 1e-2) self.assertTrue(utils.rmsd(volume[1], volume[2]) < 1e-2) if do_plot: # pragma: no cover plt.figure() plt.plot(yrs, lens[0], 'r') plt.plot(yrs, lens[1], 'b') plt.plot(yrs, lens[2], 'g') plt.title('Compare Length') plt.xlabel('years') plt.ylabel('[m]') plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2) plt.figure() plt.plot(yrs, volume[0], 'r') plt.plot(yrs, volume[1], 'b') plt.plot(yrs, volume[2], 'g') plt.title('Compare Volume') plt.xlabel('years') plt.ylabel('[km^3]') plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2) plt.figure() plt.plot(yrs, min_slope[0], 'r') plt.plot(yrs, min_slope[1], 'b') plt.plot(yrs, min_slope[2], 'g') plt.title('Compare min slope') plt.xlabel('years') plt.ylabel('[degrees]') plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2) plt.figure() plt.plot(fls[-1].bed_h, 'k') plt.plot(surface_h[0], 'r') plt.plot(surface_h[1], 'b') plt.plot(surface_h[2], 'g') plt.title('Compare Shape') plt.xlabel('[m]') plt.ylabel('Elevation [m]') plt.legend(['Bed', 'Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=3) plt.show()
def test_constant_bed(self): map_dx = 100. yrs = np.arange(1, 200, 5) lens = [] volume = [] areas = [] surface_h = [] # Flowline case fls = dummy_constant_bed(hmax=3000., hmin=1000., nx=200, map_dx=map_dx, widths=1.) mb = LinearMassBalance(2600.) flmodel = FluxBasedModel(fls, mb_model=mb, y0=0.) length = yrs * 0. vol = yrs * 0. area = yrs * 0 for i, y in enumerate(yrs): flmodel.run_until(y) assert flmodel.yr == y length[i] = fls[-1].length_m vol[i] = fls[-1].volume_km3 area[i] = fls[-1].area_km2 lens.append(length) volume.append(vol) areas.append(area) surface_h.append(fls[-1].surface_h.copy()) # Make a 2D bed out of the 1D bed_2d = np.repeat(fls[-1].bed_h, 3).reshape((fls[-1].nx, 3)) sdmodel = Upstream2D(bed_2d, dx=map_dx, mb_model=mb, y0=0., ice_thick_filter=None) length = yrs * 0. vol = yrs * 0. area = yrs * 0 for i, y in enumerate(yrs): sdmodel.run_until(y) assert sdmodel.yr == y surf_1d = sdmodel.ice_thick[:, 1] length[i] = np.sum(surf_1d > 0) * sdmodel.dx vol[i] = sdmodel.volume_km3 / 3 area[i] = sdmodel.area_km2 / 3 lens.append(length) volume.append(vol) areas.append(area) surface_h.append(sdmodel.surface_h[:, 1]) assert_allclose(lens[0][-1], lens[1][-1], atol=101) assert_allclose(volume[0][-1], volume[1][-1], atol=3e-3) assert rmsd(lens[0], lens[1]) < 50. assert rmsd(volume[0], volume[1]) < 2e-3 assert rmsd(areas[0], areas[1]) < 2e-3 assert rmsd(surface_h[0], surface_h[1]) < 1.0 # Store run_ds = sdmodel.run_until_and_store(sdmodel.yr+50) assert 'ice_thickness' in run_ds # Other direction bed_2d = np.repeat(fls[-1].bed_h, 3).reshape((fls[-1].nx, 3)).T sdmodel = Upstream2D(bed_2d, dx=map_dx, mb_model=mb, y0=0., ice_thick_filter=None) length = yrs * 0. vol = yrs * 0. area = yrs * 0 for i, y in enumerate(yrs): sdmodel.run_until(y) assert sdmodel.yr == y surf_1d = sdmodel.ice_thick[1, :] length[i] = np.sum(surf_1d > 0) * sdmodel.dx vol[i] = sdmodel.volume_km3 / 3 area[i] = sdmodel.area_km2 / 3 lens.append(length) volume.append(vol) areas.append(area) surface_h.append(sdmodel.surface_h[:, 1]) assert_allclose(lens[0][-1], lens[1][-1], atol=101) assert_allclose(volume[0][-1], volume[1][-1], atol=3e-3) assert rmsd(lens[0], lens[1]) < 50. assert rmsd(volume[0], volume[1]) < 2e-3 assert rmsd(areas[0], areas[1]) < 2e-3 assert rmsd(surface_h[0], surface_h[1]) < 1.0