Esempio n. 1
0
    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)
Esempio n. 2
0
    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)
Esempio n. 3
0
    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)
Esempio n. 4
0
    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)
Esempio n. 5
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)
Esempio n. 6
0
    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)
Esempio n. 7
0
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)
Esempio n. 8
0
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)
Esempio n. 9
0
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()
Esempio n. 10
0
    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)
Esempio n. 11
0
    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
Esempio n. 12
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)
Esempio n. 13
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)
Esempio n. 14
0
    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)
Esempio n. 15
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)
Esempio n. 16
0
    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)
Esempio n. 17
0
    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
Esempio n. 18
0
    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()
Esempio n. 19
0
    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()
Esempio n. 20
0
    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)
Esempio n. 21
0
    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()
Esempio n. 22
0
    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
Esempio n. 23
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()
Esempio n. 24
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)
Esempio n. 25
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()
Esempio n. 26
0
    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)
Esempio n. 27
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
Esempio n. 28
0
    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)
Esempio n. 29
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()
Esempio n. 30
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
Esempio n. 31
0
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
Esempio n. 32
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)