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 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 time_1d_flux_simple_bed_adaptive_dt(): fls = dummy_constant_bed() mb = massbalance.LinearMassBalance(2600.) model = flowline.FluxBasedModel(fls, mb_model=mb, y0=0.) model.run_until(800)
def test_flux_gate(): # This is to check that we are conserving mass on a slab # There are more tests in OGGM proper, this is just to play around fls = dummy_constant_bed() mb_mod = ScalarMassBalance() model = ChakraModel(fls, mb_model=mb_mod, flux_gate_thickness=150, check_for_boundaries=False) model.run_until(3000) df = model.get_diagnostics() df['ice_flux'] *= cfg.SEC_IN_YEAR assert_allclose(df['ice_thick'], 150, atol=1) assert_allclose(df['ice_flux'], df['ice_flux'].iloc[0], atol=0.2) if do_plot: fl = model.fls[-1] x = fl.dis_on_line * fl.dx_meter plt.figure() plt.plot(x, fl.bed_h, 'k') plt.plot(x, fl.surface_h, 'C3') plt.xlabel('[m]') plt.ylabel('Elevation [m]') plt.show()
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 time_1d_flux_simple_bed_fixed_dt(): fls = dummy_constant_bed() mb = massbalance.LinearMassBalance(2600.) model = flowline.FluxBasedModel(fls, mb_model=mb, y0=0., fixed_dt=10 * cfg.SEC_IN_DAY) model.run_until(800)
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_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_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_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) 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_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 test_flux_gate_with_calving(self): mb = ScalarMassBalance() model = FluxBasedModel(dummy_constant_bed(), mb_model=mb, flux_gate_thickness=150, flux_gate_build_up=50, water_level=2000, is_tidewater=True) model.run_until(2000) assert_allclose(model.volume_m3 + model.calving_m3_since_y0, model.flux_gate_m3_since_y0) if do_plot: # pragma: no cover plt.plot(model.fls[-1].bed_h, 'k') plt.plot(model.fls[-1].surface_h, 'b') plt.show()
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 test_simple_flux_gate(self): mb = ScalarMassBalance() model = FluxBasedModel(dummy_constant_bed(), mb_model=mb, flux_gate_thickness=150, flux_gate_build_up=50) model.run_until(1000) assert_allclose(model.volume_m3, model.flux_gate_m3_since_y0) model = FluxBasedModel(dummy_mixed_bed(), mb_model=mb, flux_gate_thickness=150, flux_gate_build_up=50) model.run_until(1000) assert_allclose(model.volume_m3, model.flux_gate_m3_since_y0) # Make sure that we cover the types of beds beds = np.unique(model.fls[0].shape_str[model.fls[0].thick > 0]) assert len(beds) == 2 if do_plot: # pragma: no cover plt.plot(model.fls[-1].bed_h, 'k') plt.plot(model.fls[-1].surface_h, '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_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): 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_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
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_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_numerics(): # We test that our model produces similar results than Jarosh et al 2013. models = [MUSCLSuperBeeModel, ChakraModel] lens = [] surface_h = [] volume = [] yrs = np.arange(1, 700, 2) for model_class in models: mb = LinearMassBalance(2600.) model = model_class(dummy_constant_bed(), mb_model=mb) length = yrs * 0. vol = yrs * 0. for i, y in enumerate(yrs): model.run_until(y) assert model.yr == y length[i] = model.fls[-1].length_m vol[i] = model.fls[-1].volume_km3 lens.append(length) volume.append(vol) surface_h.append(model.fls[-1].surface_h.copy()) # We are almost at equilibrium. Spec MB should be close to 0 assert_allclose(mb.get_specific_mb(fls=model.fls), 0, atol=10) if do_plot: plt.figure() plt.plot(yrs, lens[0]) plt.plot(yrs, lens[1]) plt.title('Compare Length') plt.xlabel('years') plt.ylabel('[m]') plt.legend(['MUSCL-SuperBee', 'Chakra'], loc=2) plt.figure() plt.plot(yrs, volume[0]) plt.plot(yrs, volume[1]) plt.title('Compare Volume') plt.xlabel('years') plt.ylabel('[km^3]') plt.legend(['MUSCL-SuperBee', 'Chakra'], loc=2) plt.figure() plt.plot(model.fls[-1].bed_h, 'k') plt.plot(surface_h[0]) plt.plot(surface_h[1]) plt.title('Compare Shape') plt.xlabel('[m]') plt.ylabel('Elevation [m]') plt.legend(['Bed', 'MUSCL-SuperBee', 'Chakra'], 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=1e-3) assert utils.rmsd(lens[0], lens[1]) < 50. assert utils.rmsd(volume[0], volume[1]) < 2e-3 assert utils.rmsd(surface_h[0], surface_h[1]) < 1.0
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)