def run_model(param, gdir, start_fls, t, i): fls = gdir.read_pickle('model_flowlines') fls1 = copy.deepcopy(fls) fls1[-1].surface_h = copy.deepcopy(y_start.fls[-1].surface_h) climate = copy.deepcopy(past_climate) #climate= RandomMassBalance(gdir) climate.temp_bias = param model = FluxBasedModel(fls1, mb_model=climate, glen_a=i * cfg.A, y0=1850) model.run_until(1850 + t) fls2 = copy.deepcopy(fls) fls2[-1].surface_h = model.fls[-1].surface_h real_model = FluxBasedModel(fls2, mb_model=past_climate, glen_a=cfg.A, y0=1850) real_model.run_until(2000) dif = real_model.fls[-1].surface_h - y_1900.fls[-1].surface_h s = np.sum(np.abs(dif)) #ax1.plot(x, model.fls[-1].surface_h, label='optimum') #ax2.plot(x, real_model.fls[-1].surface_h) #ax3.plot(x, dif) return [model, real_model]
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 run_model(param, gdir, y_t, random_climate2, t0, te): ''' :param param: temp bias, is changed by optimization :param gdir: oggm.GlacierDirectory :param y_t: oggm.Flowline for the observed state (2000) :param random_climate2: oggm.massbalance.RandomMassBalance :return: 2 oggm.flowline.FluxBasedModels (glacier candidate and predicted glacier model) ''' # run estimated glacier with random climate 2 until equilibrium # (glacier candidate) # estimated flowline = observed flowline estimated_fls = deepcopy(y_t) climate = deepcopy(random_climate2) # change temp_bias climate.temp_bias = param random_model = FluxBasedModel(estimated_fls, mb_model=climate, y0=t0) random_model.run_until_equilibrium() # run glacier candidate with past climate until 2000 candidate_fls = deepcopy(y_t) for i in range(len(y_t)): candidate_fls[i].surface_h = random_model.fls[i].surface_h past_climate = PastMassBalance(gdir) past_model = FluxBasedModel(candidate_fls, mb_model=past_climate, glen_a=cfg.A, y0=t0) past_model.run_until(te) return [random_model, past_model]
def get_first_guess_surface_h(data_logger): """TODO: Function to conduct spinup for first guess surface_h""" fl = data_logger.flowline_init if 'surface_h' in list(data_logger.spinup_options.keys()): mb_options = data_logger.spinup_options['surface_h']['mb_model'] if mb_options['type'] == 'constant': yr_start_run = mb_options['years'][0] yr_end_run = mb_options['years'][1] halfsize = (yr_end_run - yr_start_run) / 2 mb_spinup = MultipleFlowlineMassBalance( data_logger.gdir, fls=[fl], mb_model_class=ConstantMassBalance, filename='climate_historical', input_filesuffix='', y0=yr_start_run + halfsize, halfsize=halfsize) mb_spinup.temp_bias = mb_options['t_bias'] model = FluxBasedModel(copy.deepcopy([fl]), mb_spinup, y0=yr_start_run) model.run_until(yr_end_run) return model.fls[0].surface_h else: raise NotImplementedError( f'mb type {mb_options["type"]} not implemented!') else: raise NotImplementedError( 'The provided spinup option is not implemented!')
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 _run_parallel_experiment(gdir): # read flowlines from pre-processing fls = gdir.read_pickle('model_flowlines') try: # construct searched glacier # TODO: y0 in random mass balance? random_climate1 = RandomMassBalance(gdir, y0=1850, bias=0, seed=[1]) random_climate1.temp_bias = -0.75 commit_model = FluxBasedModel(fls, mb_model=random_climate1, glen_a=cfg.A, y0=1850) commit_model.run_until_equilibrium() y_t0 = deepcopy(commit_model) # try different seed of mass balance, if equilibrium could not be found except: # construct searched glacier random_climate1 = RandomMassBalance(gdir, y0=1850, bias=0,seed=[1]) commit_model = FluxBasedModel(fls, mb_model=random_climate1, glen_a=cfg.A, y0=1850) commit_model.run_until_equilibrium() y_t0 = deepcopy(commit_model) # construct observed glacier past_climate = PastMassBalance(gdir) commit_model2 = FluxBasedModel(commit_model.fls, mb_model=past_climate, glen_a=cfg.A, y0=1850) commit_model2.run_until(2000) y_t = deepcopy(commit_model2) # save output in gdir_dir experiment = {'y_t0': y_t0, 'y_t': y_t, 'climate': random_climate1} gdir.write_pickle(experiment, 'synthetic_experiment')
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_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_flux_gate_with_trib(self): mb = ScalarMassBalance() model = FluxBasedModel(dummy_width_bed_tributary(), 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) 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 init_model(init_flowline, mb_model, years, glen_a=None, fs=None): """This function initializes a new model, therefore it uses FluxBasedModel. The outline of the glacier is calculated for a chosen amount of years. Parameters ---------- init_flowline : oggm.core.flowline.RectangularBedFlowline the glacier flowline mb_model : oggm.core.massbalance.LinearMassBalance the glacier mass balance model years : int year until which glacier evolution is calculated glen_a : float, optional Glen's parameter, (default: 2.4e-24 s^-1 Pa^-3) fs : float, optional sliding parameter, (default: 0) Returns ------- model : oggm.core.flowline.FluxBasedModel the initialized model TODO: return also length and volume steps (they are calculated for every time step) """ if not glen_a: glen_a = cfg.PARAMS['glen_a'] if not fs: fs = 0 model = FluxBasedModel(init_flowline, mb_model=mb_model, y0=0., glen_a=glen_a, fs=fs) # Year 0 to 600 in 5 years step yrs = np.arange(0, years, 5) # Array to fill with data nsteps = len(yrs) length = np.zeros(nsteps) vol = np.zeros(nsteps) # Loop for i, yr in enumerate(yrs): model.run_until(yr) length[i] = model.length_m vol[i] = model.volume_km3 return model # , length, vol
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 _run_parallel_experiment(gdir, t0, te): ''' :param gdir: :param t0: :param te: :return: ''' # read flowlines from pre-processing fls = gdir.read_pickle('model_flowlines') try: # construct searched glacier random_climate1 = RandomMassBalance(gdir, y0=t0, halfsize=14) #set temp bias negative to force a glacier retreat later random_climate1.temp_bias = -0.75 commit_model = FluxBasedModel(fls, mb_model=random_climate1, glen_a=cfg.A, y0=t0) commit_model.run_until_equilibrium() y_t0 = deepcopy(commit_model) # try different seed of mass balance, if equilibrium could not be found except: # construct searched glacier random_climate1 = RandomMassBalance(gdir, y0=t0, halfsize=14) commit_model = FluxBasedModel(fls, mb_model=random_climate1, glen_a=cfg.A, y0=t0) commit_model.run_until_equilibrium() y_t0 = deepcopy(commit_model) # construct observed glacier past_climate = PastMassBalance(gdir) commit_model2 = FluxBasedModel(commit_model.fls, mb_model=past_climate, glen_a=cfg.A, y0=t0) commit_model2.run_until(te) y_t = deepcopy(commit_model2) # save output in gdir_dir experiment = {'y_t0': y_t0, 'y_t': y_t, 'climate': random_climate1} gdir.write_pickle(experiment, 'synthetic_experiment')
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 run_model(param,gdir,fls): fls1 = copy.deepcopy(fls) climate = random_climate2 climate.temp_bias = param model = FluxBasedModel(fls1, mb_model=climate, y0=1890) model.run_until_equilibrium() # fls2= copy.deepcopy(fls) fls2 = model.fls real_model = FluxBasedModel(fls2, mb_model=past_climate, glen_a=cfg.A, y0=1850) real_model.run_until(2000) return [model,real_model]
def spinup_run(t_bias): # with t_bias the glacier state after spinup is changed between iterations mb_spinup.temp_bias = t_bias # run the spinup model_spinup = FluxBasedModel(copy.deepcopy(fls_spinup), mb_spinup, y0=0) model_spinup.run_until_equilibrium(max_ite=1000) # Now conduct the actual model run to the rgi date model_historical = FluxBasedModel(model_spinup.fls, mb_historical, y0=yr_spinup) model_historical.run_until(yr_rgi) cost = (model_historical.length_m - length_m_ref) / length_m_ref * 100 return cost
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 run_model(param, gdir, fls, random_climate2): fls1 = copy.deepcopy(fls) climate = random_climate2 climate.temp_bias = param model = FluxBasedModel(fls1, mb_model=climate, y0=1890) model.run_until_equilibrium() fls2 = copy.deepcopy(fls) #fls2 = model.fls for i in range(len(fls)): fls2[i].surface_h = model.fls[i].surface_h real_model = FluxBasedModel(fls2, mb_model=past_climate, glen_a=cfg.A, y0=1850) real_model.run_until(2000) return [model, real_model]
def run_model(param, gdir): nx = y_1900.fls[-1].nx fls = gdir.read_pickle('model_flowlines') surface_h = rescale(param, nx) thick = surface_h - y_1900.fls[-1].bed_h # We define the length a bit differently: but more robust try: pok = np.where(thick < 10)[0] surface_h[int(pok[0]):] = y_1900.fls[-1].bed_h[int(pok[0]):] fls[-1].surface_h = surface_h real_model = FluxBasedModel(fls, mb_model=past_climate, glen_a=cfg.A, y0=1850) model = copy.deepcopy(real_model) real_model.run_until(1900) return [model, real_model] except: pass
def plot_objective_surface(gdir, plot_dir, i, best=True): #plot_dir = os.path.join(plot_dir, 'surface') if not os.path.exists(plot_dir): os.makedirs(plot_dir) reconstruction = gdir.read_pickle('reconstruction_output') experiment = gdir.read_pickle('synthetic_experiment') fls = gdir.read_pickle('model_flowlines') surface_t0 = pd.DataFrame() surface_t = pd.DataFrame() widths_t0 = pd.DataFrame() widths_t = pd.DataFrame() analysis = pd.DataFrame() plt.figure(figsize=(25, 15)) if gdir.name != "": plt.title(gdir.rgi_id + ': ' + gdir.name, fontsize=30) else: plt.title(gdir.rgi_id, fontsize=25) x = np.arange(experiment['y_t'].fls[i].nx) * \ experiment['y_t'].fls[i].dx * experiment['y_t'].fls[-1].map_dx plt.annotate(r'$t = 2000$', xy=(0.1, 0.95), xycoords='axes fraction', fontsize=30) for rec in reconstruction: if rec[0] != None: # surface surface_t0 = surface_t0.append([rec[0].fls[i].surface_h], ignore_index=True) surface_t = surface_t.append([rec[1].fls[i].surface_h], ignore_index=True) widths_t0 = widths_t0.append([rec[0].fls[i].widths], ignore_index=True) widths_t = widths_t.append([rec[1].fls[i].widths], ignore_index=True) plt.plot(x, rec[1].fls[i].surface_h - experiment['y_t'].fls[-1].surface_h, color='grey', alpha=0.3) if best: # calculate objective diff_s = surface_t.subtract(experiment['y_t'].fls[-1].surface_h, axis=1)**2 diff_w = widths_t.subtract(experiment['y_t'].fls[-1].widths, axis=1)**2 objective = diff_s.sum(axis=1) + diff_w.sum(axis=1) min_id = objective.argmin(axis=0) plt.plot(x, surface_t.iloc[min_id].values - experiment['y_t'].fls[-1].surface_h, 'r', linewidth=3, label='best objective') # plot median fls[-1].surface_h = surface_t0.median(axis=0).values past_climate = PastMassBalance(gdir) model = FluxBasedModel(fls, mb_model=past_climate, y0=1865) model.run_until(2000) plt.plot(x, model.fls[-1].surface_h - experiment['y_t'].fls[-1].surface_h, linewidth=3, label='median') ''' ax1.plot(x, surface_t0.median(axis=0), linewidth=2) ax1.fill_between(x, surface_t0.quantile(q=0.75, axis=0).values, surface_t0.quantile(q=0.25, axis=0).values, alpha=0.5,label='IQR'+r'$\left(\widehat{x}_t^j\right)$') ax1.fill_between(x, surface_t0.min(axis=0).values, surface_t0.max(axis=0).values, alpha=0.2, color='grey', label='range'+r'$\left(\widehat{x}_t^j\right)$') ax2.plot(x, surface_t.median(axis=0),linewidth=2) ax2.fill_between(x, surface_t.quantile(q=0.75, axis=0).values, surface_t.quantile(q=0.25, axis=0).values, alpha=0.5) ax2.fill_between(x, surface_t.min(axis=0).values, surface_t.max(axis=0).values, alpha=0.2,color='grey') ''' plt.legend(loc='center left', bbox_to_anchor=(1, 0.5), fontsize=15) plt.xlabel('Distance along the Flowline (m)', fontsize=30) plt.ylabel('Difference in Surface Elevation (m)', fontsize=30) plt.tick_params(axis='both', which='major', labelsize=25) plt.savefig(os.path.join(plot_dir, 'diff_s_HEF.png')) plt.show() #plt.close() return
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 find_initial_state(gdir): global past_climate global y_1900 global y_start fls = gdir.read_pickle('model_flowlines') past_climate = PastMassBalance(gdir) commit_model = FluxBasedModel(fls, mb_model=past_climate, glen_a=cfg.A, y0=1850) y_1850 = copy.deepcopy(commit_model) commit_model.run_until(1900) y_1900 = copy.deepcopy(commit_model) x = np.arange( y_1900.fls[-1].nx) * y_1900.fls[-1].dx * y_1900.fls[-1].map_dx plt.figure() ax1 = plt.subplot(311) ax1.set_title(gdir.rgi_id) plt.setp(ax1.get_xticklabels(), visible=False) plt.plot(x, y_1850.fls[-1].surface_h, 'k:', label='solution') plt.plot(x, y_1850.fls[-1].bed_h, 'k', label='bed') plt.legend(loc='best') ax2 = plt.subplot(312, sharex=ax1) plt.setp(ax2.get_xticklabels(), visible=False) ax2.plot(x, y_1900.fls[-1].surface_h, 'k:', label='solution') ax2.plot(x, y_1900.fls[-1].bed_h, 'k', label='bed') ax3 = plt.subplot(313, sharex=ax1) ax3.plot(x, np.zeros(len(x)), 'k--') growing_climate = LinearMassBalance(past_climate.get_ela(1850), 3) growing_model = FluxBasedModel(fls, mb_model=growing_climate, glen_a=cfg.A, y0=1850) #growing_model.fls[-1].surface_h=growing_model.fls[-1].bed_h succes = 0 y_start = copy.deepcopy(growing_model) y_start.run_until(1950) res = minimize(objfunc, 0.5, args=( gdir, past_climate.get_ela(1850), ), method='COBYLA', tol=1e-04, options={ 'maxiter': 500, 'rhobeg': 5 }) #print(res) result_model_1850, result_model_1900 = run_model( res.x, gdir, past_climate.get_ela(1850)) dif = result_model_1900.fls[-1].surface_h - y_1900.fls[-1].surface_h s = np.sum(np.abs(dif)) print(gdir.rgi_id, s) if s < 25: #print(gdir.rgi_id, i) succes += 1 ax1.plot(x, result_model_1850.fls[-1].surface_h, label='optimum') ax2.plot(x, result_model_1900.fls[-1].surface_h, label='optimum') ax3.plot(x, dif) ''' #ax[0].plot(x, y_start.fls[-1].surface_h, label=y_start.yr) ax[0].plot(x,result_model_1850.fls[-1].surface_h, label = 'optimum') ax[1].plot(x, result_model_1900.fls[-1].surface_h, label='optimum') ax[0].plot(x, y_1850.fls[-1].surface_h,':', label=y_1850.yr) ax[0].plot(x, y_1850.fls[-1].bed_h, 'k--') ax[0].legend(loc='best') ax[0].set_title(gdir.rgi_id) ax[1].plot(x,y_1900.fls[-1].surface_h,':',label = y_1900.yr) ax[1].plot(x, y_1900.fls[-1].bed_h, 'k--') ax[1].legend(loc='best') ''' ax1.legend(loc='best') if succes > 0: plot_dir = os.path.join(cfg.PATHS['working_dir'], 'plots', 'surface_h') if not os.path.exists(plot_dir): os.makedirs(plot_dir) plt.savefig(os.path.join(plot_dir, gdir.rgi_id + '.png')) plt.show() return True
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 response_time_vol(model, perturbed_mb): """Calculation of the volume response time after Oerlemans (1997). Parameters ---------- model : oggm.core.flowline.FluxBasedModel OGGM model class of the glacier in equilibrium perturbed_mb : oggm.core.massbalance.LinearMassBalance Perturbed mass balance model Returns ------- response_time : numpy.float64 the response time of the glacier pert_model : oggm.core.flowline.FluxBasedModel OGGM model class of the glacier in equilibrium adapted to the new ELA """ # to be sure that the model state is in equilibrium (maybe not necessary) count = 0 while True: try: model.run_until_equilibrium(rate=0.006) break except RuntimeError: count += 1 # if equilibrium not reached yet, add 1000 years. Then try again. model.run_until(models[0].yr + 1000) if count == 6: raise RuntimeError('Because the gradient is be very small, ' 'the equilibrium will be reached only ' 'after many years. Run this cell ' 'again, then it should work.') # set up new model, whith outlines of first model, but new mb_model pert_model = FluxBasedModel(model.fls[-1], mb_model=perturbed_mb, y0=0.) # run it until in reaches equilibrium state count = 0 while True: try: pert_model.run_until_equilibrium(rate=0.006) break except RuntimeError: count += 1 # if equilibrium not reached yet, add 1000 years. Then try again. pert_model.run_until(models[0].yr + 1000) if count == 6: raise RuntimeError('Because the gradient is be very small, ' 'the equilibrium will be reached only ' 'after many years. Run this cell ' 'again, then it should work.') # save outline of model in equilibrium state eq_pert_model = pert_model.fls[-1].surface_h # recalculate the perturbed model to be able to save intermediate steps yrs = np.arange(0, pert_model.yr, 5) nsteps = len(yrs) length_w = np.zeros(nsteps) vol_w = np.zeros(nsteps) year = np.zeros(nsteps) recalc_pert_model = FluxBasedModel(model.fls[-1], mb_model=perturbed_mb, y0=0.) for i, yer in enumerate(yrs): recalc_pert_model.run_until(yer) year[i] = recalc_pert_model.yr length_w[i] = recalc_pert_model.length_m vol_w[i] = recalc_pert_model.volume_km3 # to get response time: calculate volume difference between model and pert. # model in eq. state vol_dif = recalc_pert_model.volume_km3 vol_dif -= (recalc_pert_model.volume_km3 - model.volume_km3) / np.e # search for the appropriate time by determining the year with the closest # volume to vol_dif: # difference between volumes of different time steps and vol_dif all_dif_vol = abs(vol_w - vol_dif).tolist() # find index of smallest difference between index = all_dif_vol.index(min(all_dif_vol)) response_time = year[index] return response_time, pert_model
def find_initial_state(gdir): global past_climate global y_1900, y_1850 global y_start global x global ax1, ax2, ax3 fls = gdir.read_pickle('model_flowlines') past_climate = PastMassBalance(gdir) random_climate = RandomMassBalance(gdir) commit_model = FluxBasedModel(fls, mb_model=random_climate, glen_a=cfg.A, y0=1850) commit_model.run_until_equilibrium() y_1850 = copy.deepcopy(commit_model) commit_model = FluxBasedModel(commit_model.fls, mb_model=past_climate, glen_a=cfg.A, y0=1850) commit_model.run_until(2000) y_1900 = copy.deepcopy(commit_model) x = np.arange( y_1900.fls[-1].nx) * y_1900.fls[-1].dx * y_1900.fls[-1].map_dx plt.figure(figsize=(20, 10)) fig, ax1 = plt.subplots() ax2 = fig.add_axes([0.55, 0.66, 0.3, 0.2]) ax1.set_title(gdir.rgi_id) box = ax1.get_position() ax1.set_position([box.x0, box.y0, box.width * 0.95, box.height]) # Put a legend to the right of the current axis #plt.setp(ax1.get_xticklabels(), visible=False) #plt.plot(x, y_1850.fls[-1].surface_h, 'k:', label='solution') #plt.plot(x, y_1850.fls[-1].bed_h, 'k', label='bed') #plt.legend(loc='best') #ax2 = plt.subplot(412, sharex=ax1) #plt.setp(ax2.get_xticklabels(), visible=False) ''' ax3 = plt.subplot(413,sharex=ax1) ax3.plot(x, np.zeros(len(x)), 'k--') ax4 = plt.subplot(414, sharex=ax1) ax4.plot(x, np.zeros(len(x)), 'k--') ''' growing_model = FluxBasedModel(fls, mb_model=past_climate, glen_a=cfg.A, y0=1850) y_start = copy.deepcopy(growing_model) colors = [ pylab.cm.Blues(np.linspace(0.3, 1, 2)), pylab.cm.Reds(np.linspace(0.3, 1, 2)), pylab.cm.Greens(np.linspace(0.3, 1, 2)) ] #for i in [0,0.2,0.4,0.6,0.8,1,5,10,15,20,25,30,35,40,45,50]: j = 0 for i in [1]: k = 0 col = colors[j] j = j + 1 for t in [20, 40, 60, 80, 100, 120, 140, 150]: res = minimize(objfunc, [0], args=( gdir, y_1900.fls, t, i, ), method='COBYLA', tol=1e-04, options={ 'maxiter': 500, 'rhobeg': 2 }) try: result_model_1850, result_model_1900 = run_model( res.x, gdir, y_1900.fls, t, i) f = np.sum(abs(result_model_1900.fls[-1].surface_h-y_1900.fls[-1].surface_h) ** 2) + \ np.sum(abs(y_1900.fls[-1].widths - result_model_1900.fls[-1].widths) ** 2) dif_s = result_model_1900.fls[-1].surface_h - y_1900.fls[ -1].surface_h dif_w = result_model_1900.fls[-1].widths - y_1900.fls[-1].widths #if np.max(dif_s)<40 and np.max(dif_w)<15: ax1.plot(x, result_model_1850.fls[-1].surface_h, alpha=0.8, color=col[k], label='t=' + str(t)) ax2.plot(x, result_model_1900.fls[-1].surface_h, alpha=0.8, color=col[k]) except: pass k = k + 1 ax1.plot(x, y_1850.fls[-1].surface_h, 'k:') #, label='surface elevation (not known)') ax1.plot(x, y_1850.fls[-1].bed_h, 'k') #, label='bed topography') ax2.plot(x, y_1900.fls[-1].surface_h, 'k', label='surface elevation (observed)') ax2.plot(x, y_1900.fls[-1].bed_h, 'k', label='bed') #ax3.plot(x,np.zeros(len(x)),'k:') ax1.annotate('t = 1850', xy=(0.1, 0.95), xycoords='axes fraction', fontsize=13) ax2.annotate('t = 2000', xy=(0.1, 0.9), xycoords='axes fraction', fontsize=9) ax1.set_xlabel('Distance along the Flowline (m)') ax1.set_ylabel('Altitude (m)') ax2.set_xlabel('Distance along the Flowline (m)') ax2.set_ylabel('Altitude (m)') ax1.legend(loc='center left', bbox_to_anchor=(1, 0.5)) ax2.legend(loc='best') plot_dir = os.path.join(cfg.PATHS['working_dir'], 'plots') if not os.path.exists(plot_dir): os.makedirs(plot_dir) plt.savefig(os.path.join(plot_dir, gdir.rgi_id + '.png')) plt.show()
def find_initial_state(gdir): global past_climate global y_1900 global y_start f, ax = plt.subplots(2, sharex=True) fls = gdir.read_pickle('model_flowlines') past_climate = PastMassBalance(gdir) commit_model = FluxBasedModel(fls, mb_model=past_climate, glen_a=cfg.A, y0=1850) y_1850 = copy.deepcopy(commit_model) commit_model.run_until(1900) y_1900 = copy.deepcopy(commit_model) x = np.arange( y_1900.fls[-1].nx) * y_1900.fls[-1].dx * y_1900.fls[-1].map_dx surface_h = y_1900.fls[-1].bed_h x0 = surface_h[np.linspace(0, y_1900.fls[-1].nx - 1, 15).astype(int)] cons = ({ 'type': 'ineq', 'fun': con1, 'args': (gdir, ) }, { 'type': 'ineq', 'fun': con2, 'args': (gdir, ) }, { 'type': 'ineq', 'fun': con3, 'args': (gdir, ) }, { 'type': 'ineq', 'fun': con4, 'args': (gdir, ) }, { 'type': 'ineq', 'fun': con5, 'args': (gdir, ) }) results = [parallel(x, x0, cons, gdir) for x in range(75, 225, 25)] #output = [p.get() for p in results] output = results pickle.dump( output, open( '/home/juliaeis/PycharmProjects/find_inital_state/test_HEF/solution.pkl', 'wb')) for index, shape in enumerate(output): try: model, end_model = run_model(shape, gdir) ax[0].plot(x, model.fls[-1].surface_h, alpha=0.5) ax[1].plot(x, end_model.fls[-1].surface_h, alpha=0.5) except: pass ax[0].plot(x, y_1900.fls[-1].bed_h, 'k', label='bed') ax[0].plot(x, y_1850.fls[-1].surface_h, 'k:', label='solution') ax[0].set_ylabel('Altitude (m)') ax[0].set_xlabel('Distance along the flowline (m)') ax[0].set_title('1850') ax[0].legend(loc='best') ax[1].plot(x, y_1900.fls[-1].bed_h, 'k', label='bed') ax[1].plot(x, y_1900.fls[-1].surface_h, 'k:', label='solution') ax[1].legend(loc='best') ax[1].set_ylabel('Altitude (m)') ax[1].set_xlabel('Distance along the flowline (m)') ax[1].set_title('1900') plot_dir = os.path.join(cfg.PATHS['working_dir'], 'plots') if not os.path.isdir(plot_dir): os.makedirs(plot_dir) plt.savefig(os.path.join(plot_dir, gdir.rgi_id + '.png')) plt.show() print(gdir.rgi_id, 'finished')
def evolve_glacier_and_create_measurements(gdir, used_mb_models, yr_start_run, yr_spinup, yr_end_run): """TODO """ fls_spinup = gdir.read_pickle('model_flowlines', filesuffix='_spinup') yr_rgi = gdir.rgi_date # now start actual experiment run for the creation of measurements if used_mb_models == 'constant': halfsize_spinup = (yr_start_run - yr_spinup) / 2 mb_spinup = MultipleFlowlineMassBalance( gdir, fls=fls_spinup, mb_model_class=ConstantMassBalance, filename='climate_historical', input_filesuffix='', y0=yr_spinup + halfsize_spinup, halfsize=halfsize_spinup) halfsize_run = (yr_end_run - yr_start_run) / 2 mb_run = MultipleFlowlineMassBalance( gdir, fls=fls_spinup, mb_model_class=ConstantMassBalance, filename='climate_historical', input_filesuffix='', y0=yr_start_run + halfsize_run, halfsize=halfsize_run) # save used massbalance models for combine mb_models_combine = { 'MB1': { 'type': 'constant', 'years': np.array([yr_spinup, yr_start_run]) }, 'MB2': { 'type': 'constant', 'years': np.array([yr_start_run, yr_end_run]) } } gdir.write_pickle(mb_models_combine, 'inversion_input', filesuffix='_combine_mb_models') else: raise NotImplementedError(f'{used_mb_models}') # do spinup period before first measurement model = FluxBasedModel(copy.deepcopy(fls_spinup), mb_spinup, y0=yr_spinup) model.run_until_and_store(yr_start_run, diag_path=gdir.get_filepath( 'model_diagnostics', filesuffix='_combine_spinup')) # get measurements for dhdt dh_volume = [None, None] dh_area = [None, None] dh_volume[0] = model.volume_m3 dh_area[0] = model.area_m2 # switch to mb_run and run to rgi_date and save measurements and flowline model = FluxBasedModel(copy.deepcopy(model.fls), mb_run, y0=yr_start_run) model.run_until(yr_rgi) gdir.write_pickle(model.fls, 'model_flowlines', filesuffix='_combine_true_init') rgi_date_area_km2 = model.area_km2 rgi_date_volume_km3 = model.volume_km3 rgi_date_us_myr = model.u_stag[0] * model._surf_vel_fac * SEC_IN_YEAR # now run to the end for dhdt model.run_until_and_store(yr_end_run, diag_path=gdir.get_filepath( 'model_diagnostics', filesuffix='_combine_end')) gdir.write_pickle(model.fls, 'model_flowlines', filesuffix='_combine_true_end') dh_volume[1] = model.volume_m3 dh_area[1] = model.area_m2 # calculate dh dh_m = (dh_volume[1] - dh_volume[0]) / \ ((dh_area[1] + dh_area[0]) / 2.) # save measurements in gdir all_measurements = { 'dh:m': { '2000-2019': dh_m }, 'area:km2': { str(yr_rgi): rgi_date_area_km2 }, 'volume:km3': { str(yr_rgi): rgi_date_volume_km3 }, 'us:myr-1': { str(yr_rgi): rgi_date_us_myr }, } gdir.write_pickle(all_measurements, 'inversion_input', filesuffix='_combine_measurements')
def find_initial_state(gdir): global past_climate, random_climate2 global y_2000 global x global ax1, ax2, ax3 fls = gdir.read_pickle('model_flowlines') past_climate = PastMassBalance(gdir) random_climate1 = RandomMassBalance(gdir, y0=1865, halfsize=14) #construct searched glacier commit_model = FluxBasedModel(fls, mb_model=random_climate1, glen_a=cfg.A, y0=1850) commit_model.run_until_equilibrium() y_1880 = copy.deepcopy(commit_model) #construct observed glacier commit_model2 = FluxBasedModel(commit_model.fls, mb_model=past_climate, glen_a=cfg.A, y0=1880) commit_model2.run_until(2000) y_2000 = copy.deepcopy(commit_model2) results = pd.DataFrame(columns=['1880', '2000', 'length_1880']) pool = mp.Pool() result_list = pool.map(partial(run_parallel, gdir=gdir, y_2000=y_2000), range(300)) pool.close() pool.join() result_list = [x for x in result_list if x != [None, None]] # create plots for i in range(len(result_list[0][0].fls)): plt.figure(i, figsize=(20, 10)) #add subplot in the corner fig, ax1 = plt.subplots(figsize=(20, 10)) ax2 = fig.add_axes([0.55, 0.66, 0.3, 0.2]) ax1.set_title(gdir.rgi_id + ' flowline ' + str(i)) box = ax1.get_position() ax1.set_position([box.x0, box.y0, box.width * 0.95, box.height]) x = np.arange( y_2000.fls[i].nx) * y_2000.fls[i].dx * y_2000.fls[i].map_dx for j in range(len(result_list)): if result_list[j][0] != None: ax1.plot( x, result_list[j][0].fls[i].surface_h, alpha=0.8, ) ax2.plot( x, result_list[j][1].fls[i].surface_h, alpha=0.8, ) ax1.plot(x, y_1880.fls[i].surface_h, 'k:') ax2.plot(x, y_2000.fls[i].surface_h, 'k') ax1.plot(x, y_1880.fls[i].bed_h, 'k') ax2.plot(x, y_2000.fls[i].bed_h, 'k') plot_dir = os.path.join(cfg.PATHS['working_dir'], 'plots', 'Ben_idea_parallel_without_length') if not os.path.exists(plot_dir): os.makedirs(plot_dir) plt.savefig( os.path.join(plot_dir, gdir.rgi_id + '_fls' + str(i) + '.png')) pickle.dump(result_list, open(os.path.join(plot_dir, gdir.rgi_id + '.pkl'), 'wb')) solution = [y_1880, y_2000] pickle.dump( solution, open(os.path.join(plot_dir, gdir.rgi_id + '_solution.pkl'), 'wb'))
# get climate model random_climate = PastMassBalance(gdir_hef) pickle.dump(random_climate, open('random_climate_hef.pkl', 'wb')) #random_climate = pickle.load(open('random_climate_hef.pkl','rb')) hef_fls = pickle.load(open('hef_y1.pkl', 'rb')) commit_model = FluxBasedModel(hef_fls, mb_model=random_climate, glen_a=cfg.A, y0=1850) fls_y0 = copy.deepcopy(commit_model.fls) commit_model.run_until(1900) global fls_y1 y1 = copy.deepcopy(commit_model) # calculate x x = np.arange(y1.fls[-1].nx) * y1.fls[-1].dx * y1.fls[-1].map_dx surface_h = y1.fls[-1].bed_h # start array for optimization x0 = surface_h[np.linspace(0, hef_fls[-1].nx - 1, 15).astype(int)] #x0 = (y1.fls[-1].bed_h+y1.fls[-1].thick/4)[np.linspace(0,hef_fls[-1].nx-1,25).astype(int)] cons = ({ 'type': 'ineq', 'fun': con1 }, {
sh = model.fls[-1].surface_h[pg] ax.plot(sh, 'k') ax.plot(bh, 'C0', label='Real bed', linewidth=2) ax.plot(sh - thick1, 'C3', label='Computed bed') ax.set_xlabel('Grid [dx]') ax.set_ylabel('Elevation [m]') ax.text(tx, ty, 'c', transform=ax.transAxes, **letkm) # fls = dummy_constant_bed(map_dx=gdir.grid.dx) mb = LinearMassBalance(2600.) model = FluxBasedModel(fls, mb_model=mb, y0=0.) model.run_until_equilibrium() mb = LinearMassBalance(2800.) model = FluxBasedModel(model.fls, mb_model=mb, y0=0) model.run_until(60) 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]]) sh = fl.surface_h[pg] flo = Centerline(line, dx=fl.dx, surface_h=sh) 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) # expected errors
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 find_initial_state(gdir): global past_climate,random_climate2 global y_2000 global x global ax1,ax2,ax3 fls = gdir.read_pickle('model_flowlines') past_climate = PastMassBalance(gdir) random_climate1 = RandomMassBalance(gdir,y0=1865,halfsize=14) #construct searched glacier commit_model = FluxBasedModel(fls, mb_model=random_climate1, glen_a=cfg.A, y0=1850) commit_model.run_until_equilibrium() y_1880 = copy.deepcopy(commit_model) #construct observed glacier commit_model2 = FluxBasedModel(commit_model.fls, mb_model=past_climate, glen_a=cfg.A, y0=1880) commit_model2.run_until(2000) y_2000 = copy.deepcopy(commit_model2) results = pd.DataFrame(columns=['1880','2000','length_1880']) for i in range(4): random_climate2 = RandomMassBalance(gdir, y0=1875, halfsize=14) res = minimize(objfunc, [0], args=(gdir, y_2000.fls), method='COBYLA', tol=1e-04, options={'maxiter': 100, 'rhobeg': 1}) #try: result_model_1880, result_model_2000 = run_model(res.x, gdir, y_2000.fls) results = results.append({'1880':result_model_1880,'2000':result_model_2000,'length_1880':result_model_1880.length_m,'length_2000':result_model_2000.length_m}, ignore_index=True) #except: # pass # create plots for i in range(len(fls)): plt.figure(i,figsize=(20,10)) #add subplot in the corner fig, ax1 = plt.subplots(figsize=(20, 10)) ax2 = fig.add_axes([0.55, 0.66, 0.3, 0.2]) ax1.set_title(gdir.rgi_id+' flowline '+str(i)) box = ax1.get_position() ax1.set_position([box.x0, box.y0, box.width * 0.95, box.height]) x = np.arange(y_2000.fls[i].nx) * y_2000.fls[i].dx * y_2000.fls[i].map_dx for j in range(len(results)): ax1.plot(x, results.get_value(j, '1880').fls[i].surface_h, alpha=0.8, ) ax2.plot(x, results.get_value(j, '2000').fls[i].surface_h, alpha=0.8, ) ax1.plot(x,y_1880.fls[i].surface_h,'k:') ax2.plot(x, y_2000.fls[i].surface_h, 'k') ax1.plot(x, y_1880.fls[i].bed_h, 'k') ax2.plot(x, y_2000.fls[i].bed_h, 'k') plot_dir = os.path.join(cfg.PATHS['working_dir'], 'plots') plt.savefig(os.path.join(plot_dir, gdir.rgi_id +'_fls'+str(i)+ '.png')) #plt.show() results.to_csv(os.path.join(plot_dir,str(gdir.rgi_id)+'.csv')) '''