def find_guess(mb_data): nx = 200 bed_h = np.linspace(3400, 1400, nx) map_dx = 100 widths = np.zeros(nx) + 3. init_flowline = VerticalWallFlowline(surface_h=measured.fls[-1].surface_h, bed_h=bed_h, widths=widths, map_dx=map_dx) # with random ELA mb_model = LinearMassBalanceModel(mb_data[0], grad=4) # The model requires the initial glacier bed, a mass-balance model, and an initial time (the year y0) model = FlowlineModel(init_flowline, mb_model=mb_model, y0=150) model.run_until(300) mb_model_orig = LinearMassBalanceModel(3000, grad=4) end_model = FlowlineModel(model.fls, mb_model=mb_model_orig, y0=150) end_model.run_until(300) f = abs(end_model.fls[-1].surface_h - measured.fls[-1].surface_h)+\ abs(end_model.length_m-measured.length_m)+\ abs(end_model.area_km2-measured.area_km2)+\ abs(end_model.volume_km3-measured.volume_km3) print(sum(f)) return f
def objfunc(surface_h): nx = 200 bed_h = np.linspace(3400, 1400, nx) # At the begining, there is no glacier so our glacier surface is at the bed altitude # Let's set the model grid spacing to 100m (needed later) map_dx = 100 # The units of widths is in "grid points", i.e. 3 grid points = 300 m in our case widths = np.zeros(nx) + 3. # Define our bed init_flowline = VerticalWallFlowline(surface_h=surface_h, bed_h=bed_h, widths=widths, map_dx=map_dx) mb_model = LinearMassBalanceModel(3000, grad=4) model = FlowlineModel(init_flowline, mb_model=mb_model, y0=150) model.run_until(300) f = abs(model.fls[-1].surface_h - measured.fls[-1].surface_h)+\ abs(model.length_m-measured.length_m)+\ abs(model.area_km2-measured.area_km2)+\ abs(model.volume_km3-measured.volume_km3) print(sum(f)) return f
def objfunc(x): nx = 200 # set the model grid spacing to 100m map_dx = 100 # The units of widths is in "grid points", i.e. 3 grid points = 300 m in our case widths = np.zeros(nx) + 3. surface_h = make_surface_h(x) flowline = VerticalWallFlowline(surface_h=surface_h, bed_h=bed_h, widths=widths, map_dx=map_dx) #plt.plot(flowline.surface_h) #plt.plot(np.linspace(0,x[0],10),x[1::],'o') #plt.plot(bed_h) #plt.show() # ELA at 3000m a.s.l., gradient 4 mm m-1 mb_model = LinearMassBalanceModel(3000, grad=4) # The model requires the initial glacier bed, a mass-balance model, and an initial time (the year y0) model = FlowlineModel(flowline, mb_model=mb_model, y0=150) model.run_until(300) #plt.plot(model.fls[-1].surface_h) measured = pickle.load( open('/home/juliaeis/PycharmProjects/find_inital_state/fls_300.pkl', 'rb')) #plt.plot(measured.fls[-1].surface_h) #plt.show() f = abs(model.fls[-1].surface_h - measured.fls[-1].surface_h)+\ abs(model.length_m-measured.length_m)+\ abs(model.area_km2-measured.area_km2)+\ abs(model.volume_km3-measured.volume_km3) print('objective:',sum(f)) return f
def target(ela,time): mb_model = LinearMassBalanceModel(ela, grad=4) bed_h = np.linspace(3400, 1400, 200) # model = FlowlineModel(final_flowline.fls[-1], mb_model=mb_model, y0=0) model = FlowlineModel(VerticalWallFlowline(surface_h=bed_h, bed_h=bed_h, widths=np.zeros(200) + 3., map_dx=100), mb_model=mb_model, y0=0) model.run_until(time) flowline = model.fls[-1] new_mb_model = LinearMassBalanceModel(3000, grad=4) new_model = FlowlineModel(flowline, mb_model=new_mb_model, y0=0) new_model.run_until(150) return -sum( abs(final_flowline.fls[-1].surface_h - new_model.fls[-1].surface_h))
def objfunc(mb_data): mb_model = LinearMassBalanceModel(mb_data[0], grad=4) bed_h = np.linspace(3400, 1400, 200) model = FlowlineModel(VerticalWallFlowline( surface_h=final_flowline.fls[-1].surface_h, bed_h=bed_h, widths=np.zeros(200) + 3., map_dx=100), mb_model=mb_model, y0=0) #model = FlowlineModel(VerticalWallFlowline(surface_h=bed_h, bed_h=bed_h, widths=np.zeros(200) + 3., map_dx=100),mb_model=mb_model,y0=0) model.run_until(mb_data[1]) flowline = model.fls[-1] new_mb_model = LinearMassBalanceModel(3000, grad=4) new_model = FlowlineModel(flowline, mb_model=new_mb_model, y0=0) new_model.run_until(150) #print(mb_data,sum(abs(final_flowline.fls[-1].surface_h-new_model.fls[-1].surface_h))) return sum( abs(final_flowline.fls[-1].surface_h - new_model.fls[-1].surface_h)) + sum(abs(final_flowline.volume_m3))
def run_model(surface_h): nx = 200 bed_h = np.linspace(3400, 1400, nx) # At the begining, there is no glacier so our glacier surface is at the bed altitude # Let's set the model grid spacing to 100m (needed later) map_dx = 100 # The units of widths is in "grid points", i.e. 3 grid points = 300 m in our case widths = np.zeros(nx) + 3. # Define our bed init_flowline = VerticalWallFlowline(surface_h=rescale(surface_h, nx), bed_h=bed_h, widths=widths, map_dx=map_dx) # ELA at 3000m a.s.l., gradient 4 mm m-1 mb_model = LinearMassBalanceModel(3000, grad=4) annual_mb = mb_model.get_mb(surface_h) * SEC_IN_YEAR # The model requires the initial glacier bed, a mass-balance model, and an initial time (the year y0) model = FlowlineModel(init_flowline, mb_model=mb_model, y0=150) return model
constraints=cons, options={ 'maxiter': 5000, 'rhobeg': 400 }) nx = 200 bed_h = np.linspace(3400, 1400, nx) # At the begining, there is no glacier so our glacier surface is at the bed altitude # Let's set the model grid spacing to 100m (needed later) map_dx = 100 # The units of widths is in "grid points", i.e. 3 grid points = 300 m in our case widths = np.zeros(nx) + 3. mb_model = LinearMassBalanceModel(res.x, grad=4) init_flowline = VerticalWallFlowline(surface_h=measured.fls[-1].surface_h, bed_h=bed_h, widths=widths, map_dx=map_dx) # The model requires the initial glacier bed, a mass-balance model, and an initial time (the year y0) model = FlowlineModel(init_flowline, mb_model=mb_model, y0=150) model.run_until(300) start_guess = model.fls[-1].surface_h print('####### beginn optimization######') #------------------------------optimization--------------------------------- def objfunc(surface_h): nx = 200
#glacier bed # This is the bed rock, linearily decreasing from 3000m altitude to 1000m, in 200 steps nx = 200 bed_h = np.linspace(3400, 1400, nx) # At the begining, there is no glacier so our glacier surface is at the bed altitude surface_h = bed_h # Let's set the model grid spacing to 100m (needed later) map_dx = 100 # The units of widths is in "grid points", i.e. 3 grid points = 300 m in our case widths = np.zeros(nx) + 3. # Define our bed init_flowline = VerticalWallFlowline(surface_h=surface_h, bed_h=bed_h, widths=widths, map_dx=map_dx) # ELA at 3000m a.s.l., gradient 4 mm m-1 mb_model = LinearMassBalanceModel(3000, grad=4) annual_mb = mb_model.get_mb(surface_h) * SEC_IN_YEAR # The model requires the initial glacier bed, a mass-balance model, and an initial time (the year y0) model = FlowlineModel(init_flowline, mb_model=mb_model, y0=0) model.run_until(150) print(model.length_m, model.area_km2, model.volume_km3) d= model.fls[-1].to_dataset() pickle.dump(model,open('/home/juliaeis/PycharmProjects/find_inital_state/fls_150.pkl','wb')) model.run_until(300) print(model.length_m, model.area_km2, model.volume_km3) pickle.dump(model,open('/home/juliaeis/PycharmProjects/find_inital_state/fls_300.pkl','wb'))
cons = ({'type': 'ineq', 'fun': con1}, {'type': 'ineq', 'fun': con2}) res = minimize(objfunc, x0, method='COBYLA', tol=1e-10, constraints=cons, options={ 'maxiter': 5000, 'rhobeg': 100 }) bed_h = np.linspace(3400, 1400, 200) model = FlowlineModel(VerticalWallFlowline(surface_h=bed_h, bed_h=bed_h, widths=np.zeros(200) + 3., map_dx=100), mb_model=LinearMassBalanceModel(res.x[0], grad=4), y0=0) model.run_until(res.x[1]) #inital flowline plt.figure(0) plt.plot(initial_flowline.fls[-1].bed_h, color='k', label='Bedrock') plt.plot(initial_flowline.fls[-1].surface_h, label='Initial flowline') plt.plot(model.fls[-1].surface_h, label='optimized intial flowline ') plt.xlabel('Grid points') plt.ylabel('Altitude (m)') plt.legend(loc='best') orig_mb = LinearMassBalanceModel(3000, grad=4) res_model = FlowlineModel(model.fls[-1], orig_mb, y0=0) res_model.run_until(150)
result = ([ 3556.82325655, 3323.4899938, 3048.91883072, 2733.36490086, 2511.11111111, 2288.88888889, 2066.66666667, 1844.44444444, 1622.22222222, 1400. ]) interp = rescale(result, 200) initial_flowline = pickle.load( open('/home/juliaeis/PycharmProjects/find_inital_state/fls_150.pkl', 'rb')) final_flowline = pickle.load( open('/home/juliaeis/PycharmProjects/find_inital_state/fls_300.pkl', 'rb')) model = FlowlineModel(VerticalWallFlowline(surface_h=interp, bed_h=bed_h, widths=np.zeros(nx) + 3., map_dx=100), mb_model=LinearMassBalanceModel(3000, grad=4), y0=0) model.run_until(0) init = copy.deepcopy(model) model.run_until(150) #inital flowline plt.figure(1) plt.plot(initial_flowline.fls[-1].bed_h, color='k', label='Bedrock') plt.plot(initial_flowline.fls[-1].surface_h, '--', color='teal', label='"initial" glacier - result (normally unknown) -') plt.plot(final_flowline.fls[-1].surface_h, color='teal', label='glacier after 300 yrs') plt.plot(init.fls[-1].surface_h,
def to_minimize(ela_h): mbmod = LinearMassBalanceModel(ela_h[0], grad=grad) smb = mbmod.get_specific_mb(h, w) return smb**2
def apparent_mb_from_linear_mb(gdir, div_id=None): """Compute apparent mb from a linear mass-balance assumption (for testing). This is for testing currently, but could be used as alternative method for the inversion quite easily. Parameters ---------- gdir : oggm.GlacierDirectory """ # Do we have a calving glacier? cmb = calving_mb(gdir) # Get the height and widths along the fls if div_id == 0: h, w = gdir.get_inversion_flowline_hw() else: h, w = gdir.get_inversion_flowline_hw(div_id=div_id) # Now find the ELA till the integrated mb is zero from oggm.core.models.massbalance import LinearMassBalanceModel grad = 3. # mm w.e def to_minimize(ela_h): mbmod = LinearMassBalanceModel(ela_h[0], grad=grad) smb = mbmod.get_specific_mb(h, w) return smb**2 ela_h = optimization.minimize(to_minimize, [0.], bounds=((0, 10000), )) ela_h = ela_h['x'][0] mbmod = LinearMassBalanceModel(ela_h) # For each flowline compute the apparent MB # For div 0 it is kind of artificial but this is for validation fls = [] if div_id == 0: for i in gdir.divide_ids: fls.extend(gdir.read_pickle('inversion_flowlines', div_id=i)) else: fls = gdir.read_pickle('inversion_flowlines', div_id=div_id) # Reset flux for fl in fls: fl.flux = np.zeros(len(fl.surface_h)) # Flowlines in order to be sure for fl in fls: mbz = mbmod.get_annual_mb(fl.surface_h) * cfg.SEC_IN_YEAR * cfg.RHO fl.set_apparent_mb(mbz) # Check and write if div_id > 0: aflux = fls[-1].flux[-1] * 1e-9 / cfg.RHO * gdir.grid.dx**2 if not np.allclose(fls[-1].flux[-1], 0., atol=0.01): log.warning( '%s: flux should be zero, but is: ' '%.4f km3 ice yr-1', gdir.rgi_id, aflux) # If not marine and quite far from zero, error if cmb == 0 and not np.allclose(fls[-1].flux[-1], 0., atol=1): msg = '{}: flux should be zero, but is: %.4f km3 ice yr-1' \ .format(gdir.rgi_id, aflux) raise RuntimeError(msg) gdir.write_pickle(fls, 'inversion_flowlines', div_id=div_id) gdir.write_pickle({ 'ela_h': ela_h, 'grad': grad }, 'linear_mb_params', div_id=div_id)
def to_minimize(ela_h): mbmod = LinearMassBalanceModel(ela_h[0], grad=grad) smb = mbmod.get_specific_mb(h, w) return smb**2
def apparent_mb_from_linear_mb(gdir, div_id=None): """Compute apparent mb from a linear mass-balance assumption (for testing). This is for testing currently, but could be used as alternative method for the inversion quite easily. Parameters ---------- gdir : oggm.GlacierDirectory """ # Do we have a calving glacier? cmb = calving_mb(gdir) # Get the height and widths along the fls if div_id == 0: h, w = gdir.get_inversion_flowline_hw() else: h, w = gdir.get_inversion_flowline_hw(div_id=div_id) # Now find the ELA till the integrated mb is zero from oggm.core.models.massbalance import LinearMassBalanceModel grad = 3. # mm w.e def to_minimize(ela_h): mbmod = LinearMassBalanceModel(ela_h[0], grad=grad) smb = mbmod.get_specific_mb(h, w) return smb**2 ela_h = optimization.minimize(to_minimize, [0.], bounds=((0, 10000), )) ela_h = ela_h['x'][0] mbmod = LinearMassBalanceModel(ela_h) # For each flowline compute the apparent MB # For div 0 it is kind of artificial but this is for validation fls = [] if div_id == 0: for i in gdir.divide_ids: fls.extend(gdir.read_pickle('inversion_flowlines', div_id=i)) else: fls = gdir.read_pickle('inversion_flowlines', div_id=div_id) # Reset flux for fl in fls: fl.flux = np.zeros(len(fl.surface_h)) # Flowlines in order to be sure for fl in fls: mbz = mbmod.get_annual_mb(fl.surface_h) * cfg.SEC_IN_YEAR * cfg.RHO fl.set_apparent_mb(mbz) # Check and write if div_id > 0: aflux = fls[-1].flux[-1] * 1e-9 / cfg.RHO * gdir.grid.dx**2 if not np.allclose(fls[-1].flux[-1], 0., atol=0.01): log.warning('%s: flux should be zero, but is: ' '%.4f km3 ice yr-1', gdir.rgi_id, aflux) # If not marine and quite far from zero, error if cmb == 0 and not np.allclose(fls[-1].flux[-1], 0., atol=1): msg = '{}: flux should be zero, but is: %.4f km3 ice yr-1' \ .format(gdir.rgi_id, aflux) raise RuntimeError(msg) gdir.write_pickle(fls, 'inversion_flowlines', div_id=div_id) gdir.write_pickle({'ela_h': ela_h, 'grad': grad}, 'linear_mb_params', div_id=div_id)