def penetrating_radiation(GRID, SWnet, dt, opt_dict=None): # Read and set options read_opt(opt_dict, globals()) penetrating_allowed = ['Bintanja95'] if penetrating_method == 'Bintanja95': subsurface_melt, Si = method_Bintanja(GRID, SWnet, dt) else: raise ValueError("Penetrating method = \"{:s}\" is not allowed, must be one of {:s}".format(penetrating_method, ", ".join(penetrating_allowed))) return subsurface_melt, Si
def evaluate(stake_names, stake_data, df_, opt_dict=None): """ This methods evaluates the simulation with the stake measurements stake_name :: """ # Read and set options read_opt(opt_dict, globals()) if eval_method == 'rmse': stat = rmse(stake_names, stake_data, df_) else: stat = None return stat
def updateRoughness(GRID, opt_dict=None): # Read and set options read_opt(opt_dict, globals()) roughness_allowed = ['Moelg12'] if roughness_method == 'Moelg12': sigma = method_Moelg(GRID) else: raise ValueError( "Roghness method = \"{:s}\" is not allowed, must be one of {:s}". format(roughness_method, ", ".join(roughness_allowed))) return sigma
def solveHeatEquation(GRID, dt, opt_dict=None): # Read and set options read_opt(opt_dict, globals()) heatEquation_method = 'default' heatEquation_allowed = ['default'] if heatEquation_method == 'default': heatEquation_default(GRID, dt) else: raise ValueError( "Heat equation = \"{:s}\" is not allowed, must be one of {:s}". format(heatEquation_method, ", ".join(heatEquation_allowed)))
def updateAlbedo(GRID, opt_dict): """ This methods updates the albedo """ # Read and set options read_opt(opt_dict, globals()) albedo_allowed = ['Oerlemans98'] if albedo_method == 'Oerlemans98': alphaMod = method_Oerlemans(GRID) else: raise ValueError( "Albedo method = \"{:s}\" is not allowed, must be one of {:s}". format(albedo_method, ", ".join(albedo_allowed))) return alphaMod
def refreezing(GRID, opt_dict=None): # Read and set options read_opt(opt_dict, globals()) refreezing_method = 'default' refreezing_allowed = ['default'] if refreezing_method == 'default': water_refreezed = refreezing_default(GRID) else: raise ValueError( "Refreezing method = \"{:s}\" is not allowed, must be one of {:s}". format(refreezing_method, ", ".join(refreezing_allowed))) return water_refreezed
def percolation(GRID, water, dt, opt_dict=None): # Read and set options read_opt(opt_dict, globals()) percolation_method = 'bucket' percolation_allowed = ['bucket'] if percolation_method == 'bucket': Q = bucket(GRID, water, dt) else: raise ValueError( "Percolation method = \"{:s}\" is not allowed, must be one of {:s}" .format(percolation_method, ", ".join(percolation_allowed))) return Q
def __init__(self, DATA=None, opt_dict=None): """ Init IO Class""" # Read and set options read_opt(opt_dict, globals()) # Read variable list from file config = configparser.ConfigParser() config.read('./cosipy/output') self.atm = config['vars']['atm'] self.internal = config['vars']['internal'] self.full = config['vars']['full'] # Initialize data self.DATA = DATA self.RESTART = None self.RESULT = None # If local IO class is initialized we need to get the dimensions of the dataset if DATA is not None: self.time = self.DATA.dims['time']
def densification(GRID, SLOPE, dt, opt_dict=None): """ Densification of the snowpack Args: GRID :: GRID-Structure dt :: integration time """ # Read and set options read_opt(opt_dict, globals()) densification_allowed = ['Boone', 'Vionnet', 'empirical', 'constant'] if densification_method == 'Boone': method_Boone(GRID, SLOPE, dt) elif densification_method == 'Vionnet': method_Vionnet(GRID, SLOPE, dt) elif densification_method == 'empirical': method_empirical(GRID, SLOPE, dt) elif densification_method == 'constant': pass else: raise ValueError( "Densification method = \"{:s}\" is not allowed, must be one of {:s}" .format(densification_method, ", ".join(densification_allowed)))
def update_surface_temperature(GRID, dt, z, z0, T2, rH2, p, SWnet, u2, RAIN, SLOPE, LWin=None, N=None, opt_dict=None): """ This methods updates the surface temperature and returns the surface fluxes Given: GRID :: Grid structure T0 :: Surface temperature [K] dt :: Integration time [s] -- can vary in WRF_X_CSPY alpha :: Albedo [-] z :: Measurement height [m] -- varies in WRF_X_CSPY z0 :: Roughness length [m] T2 :: Air temperature [K] rH2 :: Relative humidity [%] p :: Air pressure [hPa] G :: Incoming shortwave radiation [W m^-2] u2 :: Wind velocity [m S^-1] RAIN :: RAIN (mm) SLOPE :: Slope of the surface [degree] LWin :: Incoming longwave radiation [W m^-2] N :: Fractional cloud cover [-] Returns: Li :: Incoming longwave radiation [W m^-2] Lo :: Outgoing longwave radiation [W m^-2] H :: Sensible heat flux [W m^-2] L :: Latent heat flux [W m^-2] B :: Ground heat flux [W m^-2] Qrr :: Rain heat flux [W m^-2] SWnet :: Shortwave radiation budget [W m^-2] rho :: Air density [kg m^-3] Lv :: Latent heat of vaporization [J kg^-1] MOL :: Monin-Obukhov length Cs_t :: Stanton number [-] Cs_q :: Dalton number [-] q0 :: Mixing ratio at the surface [kg kg^-1] q2 :: Mixing ratio at measurement height [kg kg^-1] phi :: Stability correction term [-] """ # Read and set options read_opt(opt_dict, globals()) #Interpolate subsurface temperatures to selected subsurface depths for GHF computation B_Ts = interp_subT(GRID) #Update surface temperature lower_bnd_ts = 220. if sfc_temperature_method == 'L-BFGS-B' or sfc_temperature_method == 'SLSQP': # Get surface temperature by minimizing the energy balance function (SWnet+Li+Lo+H+L=0) res = minimize(eb_optim, GRID.get_node_temperature(0), method=sfc_temperature_method, bounds=((lower_bnd_ts, zero_temperature), ), tol=1e-2, args=(GRID, dt, z, z0, T2, rH2, p, SWnet, u2, RAIN, SLOPE, B_Ts, LWin, N)) elif sfc_temperature_method == 'Newton': try: res = newton(eb_optim, np.array([GRID.get_node_temperature(0)]), tol=1e-2, maxiter=50, args=(GRID, dt, z, z0, T2, rH2, p, SWnet, u2, RAIN, SLOPE, B_Ts, LWin, N)) if res < lower_bnd_ts: raise ValueError("TS Solution is out of bounds") res = SimpleNamespace(**{ 'x': min(np.array([zero_temperature]), res), 'fun': None }) except (RuntimeError, ValueError): #Workaround for non-convergence and unboundedness res = minimize(eb_optim, GRID.get_node_temperature(0), method='SLSQP', bounds=((lower_bnd_ts, zero_temperature), ), tol=1e-2, args=(GRID, dt, z, z0, T2, rH2, p, SWnet, u2, RAIN, SLOPE, B_Ts, LWin, N)) else: print('Invalid method for minimizing the residual') # Set surface temperature GRID.set_node_temperature(0, float(res.x)) (Li, Lo, H, L, B, Qrr, rho, Lv, MOL, Cs_t, Cs_q, q0, q2) = eb_fluxes( GRID, res.x, dt, z, z0, T2, rH2, p, u2, RAIN, SLOPE, B_Ts, LWin, N, ) # Consistency check if (float(res.x) > zero_temperature) or (float(res.x) < lower_bnd_ts): print('Surface temperature is outside bounds:', GRID.get_node_temperature(0)) # Return fluxes return res.fun, res.x, Li, Lo, H, L, B, Qrr, rho, Lv, MOL, Cs_t, Cs_q, q0, q2
def init_snowpack(DATA, opt_dict): ''' INITIALIZATION ''' # Read and set options read_opt(opt_dict, globals()) ##-------------------------------------- ## Check for WRF data ##-------------------------------------- if ('SNOWHEIGHT' in DATA): initial_snowheight = DATA.SNOWHEIGHT.values if np.isnan(initial_snowheight): initial_snowheight = 0.0 else: initial_snowheight = initial_snowheight_constant temperature_top = np.minimum(DATA.T2.values[0], 273.16) #-------------------------------------- # Do the vertical interpolation #-------------------------------------- layer_heights = [] layer_densities = [] layer_T = [] layer_liquid_water = [] if (initial_snowheight > 0.0): optimal_height = 0.1 # 10 cm nlayers = int(min(initial_snowheight / optimal_height, 5)) dT = (temperature_top - temperature_bottom) / (initial_snowheight + initial_glacier_height) if nlayers == 0: layer_heights = np.array([initial_snowheight]) layer_densities = np.array([initial_top_density_snowpack]) layer_T = np.array([temperature_top]) layer_liquid_water = np.array([0.0]) elif nlayers > 0: drho = (initial_top_density_snowpack - initial_bottom_density_snowpack) / initial_snowheight layer_heights = np.ones(nlayers) * (initial_snowheight / nlayers) layer_densities = np.array([ initial_top_density_snowpack - drho * (initial_snowheight / nlayers) * i for i in range(1, nlayers + 1) ]) layer_T = np.array([ temperature_top - dT * (initial_snowheight / nlayers) * i for i in range(1, nlayers + 1) ]) layer_liquid_water = np.zeros(nlayers) # add glacier nlayers = int(initial_glacier_height / initial_glacier_layer_heights) layer_heights = np.append( layer_heights, np.ones(nlayers) * initial_glacier_layer_heights) layer_densities = np.append(layer_densities, np.ones(nlayers) * ice_density) layer_T = np.append(layer_T, [ layer_T[-1] - dT * initial_glacier_layer_heights * i for i in range(1, nlayers + 1) ]) layer_liquid_water = np.append(layer_liquid_water, np.zeros(nlayers)) else: # only glacier nlayers = int(initial_glacier_height / initial_glacier_layer_heights) dT = (temperature_top - temperature_bottom) / initial_glacier_height layer_heights = np.ones(nlayers) * initial_glacier_layer_heights layer_densities = np.ones(nlayers) * ice_density layer_T = np.array([ temperature_top - dT * initial_glacier_layer_heights * i for i in range(1, nlayers + 1) ]) layer_liquid_water = np.zeros(nlayers) # Initialize grid, the grid class contains all relevant grid information GRID = Grid(np.array(layer_heights, dtype=np.float64), np.array(layer_densities, dtype=np.float64), np.array(layer_T, dtype=np.float64), np.array(layer_liquid_water, dtype=np.float64), None, None, None, None) return GRID
def cosipy_core(DATA, indY, indX, GRID_RESTART=None, stake_names=None, stake_data=None, opt_dict=None): """ Cosipy core function, which perform the calculations on one core. Params ====== DATA: xarray.Dataset xarray dataset which contain one grid point indY: indX: GRID_RESTART : boolean, optional If restart is given, no inital profile is created stake_name : boolean, optional stake names stake_data : boolean, optional stake data Returns ====== Returns all calculated variables of one grid point """ # Replace values from constants.py if coupled from constants import max_layers, dt, z #WTF python! if WRF_X_CSPY: dt = int(DATA.DT.values) max_layers = int(DATA.max_layers.values) z = float(DATA.ZLVL.values) # Replace imported variables with content of the opt_dict. If it's empty # nothing happens. read_opt(opt_dict, globals()) # Local variables nt = len(DATA.time.values) #accessing DATA is expensive _RRR = np.full(nt, np.nan) _RAIN = np.full(nt, np.nan) _SNOWFALL = np.full(nt, np.nan) _LWin = np.full(nt, np.nan) _LWout = np.full(nt, np.nan) _H = np.full(nt, np.nan) _LE = np.full(nt, np.nan) _B = np.full(nt, np.nan) _QRR = np.full(nt, np.nan) _MB = np.full(nt, np.nan) _surfMB = np.full(nt, np.nan) _MB = np.full(nt, np.nan) _Q = np.full(nt, np.nan) _SNOWHEIGHT = np.full(nt, np.nan) _TOTALHEIGHT = np.full(nt, np.nan) _TS = np.full(nt, np.nan) _ALBEDO = np.full(nt, np.nan) _ME = np.full(nt, np.nan) _intMB = np.full(nt, np.nan) _EVAPORATION = np.full(nt, np.nan) _SUBLIMATION = np.full(nt, np.nan) _CONDENSATION = np.full(nt, np.nan) _DEPOSITION = np.full(nt, np.nan) _REFREEZE = np.full(nt, np.nan) _NLAYERS = np.full(nt, np.nan) _subM = np.full(nt, np.nan) _Z0 = np.full(nt, np.nan) _surfM = np.full(nt, np.nan) _MOL = np.full(nt, np.nan) _LAYER_HEIGHT = np.full((nt,max_layers), np.nan) _LAYER_RHO = np.full((nt,max_layers), np.nan) _LAYER_T = np.full((nt,max_layers), np.nan) _LAYER_LWC = np.full((nt,max_layers), np.nan) _LAYER_CC = np.full((nt,max_layers), np.nan) _LAYER_POROSITY = np.full((nt,max_layers), np.nan) _LAYER_ICE_FRACTION = np.full((nt,max_layers), np.nan) _LAYER_IRREDUCIBLE_WATER = np.full((nt,max_layers), np.nan) _LAYER_REFREEZE = np.full((nt,max_layers), np.nan) #-------------------------------------------- # Initialize snowpack or load restart grid #-------------------------------------------- if GRID_RESTART is None: GRID = init_snowpack(DATA, opt_dict) else: GRID = load_snowpack(GRID_RESTART) # Create the local output datasets if not coupled RESTART = None if not WRF_X_CSPY: IO = IOClass(DATA, opt_dict) RESTART = IO.create_local_restart_dataset() # hours since the last snowfall (albedo module) hours_since_snowfall = 0 #-------------------------------------------- # Get data from file #-------------------------------------------- T2 = DATA.T2.values RH2 = DATA.RH2.values PRES = DATA.PRES.values G = DATA.G.values U2 = DATA.U2.values #-------------------------------------------- # Checks for optional input variables #-------------------------------------------- if ('SNOWFALL' in DATA) and ('RRR' in DATA): SNOWF = DATA.SNOWFALL.values * mult_factor_RRR RRR = DATA.RRR.values * mult_factor_RRR elif ('SNOWFALL' in DATA): SNOWF = DATA.SNOWFALL.values * mult_factor_RRR RRR = None RAIN = None else: SNOWF = None RRR = DATA.RRR.values * mult_factor_RRR # Use RRR rather than snowfall? if force_use_TP: SNOWF = None if ('LWin' in DATA) and ('N' in DATA): LWin = DATA.LWin.values N = DATA.N.values elif ('LWin' in DATA): LWin = DATA.LWin.values else: LWin = None N = DATA.N.values # Use N rather than LWin if force_use_N: LWin = None if ('SLOPE' in DATA): SLOPE = DATA.SLOPE.values else: SLOPE = 0.0 # Initial cumulative mass balance variable MB_cum = 0 if stake_evaluation: # Create pandas dataframe for stake evaluation _df = pd.DataFrame(index=stake_data.index, columns=['mb','snowheight'], dtype='float') #-------------------------------------------- # TIME LOOP #-------------------------------------------- for t in np.arange(nt): # Check grid GRID.grid_check() # get seconds since start timestamp = dt*t if WRF_X_CSPY: timestamp = np.float64(DATA.CURR_SECS.values) # Calc fresh snow density if (densification_method!='constant'): density_fresh_snow = np.maximum(109.0+6.0*(T2[t]-273.16)+26.0*np.sqrt(U2[t]), 50.0) else: density_fresh_snow = constant_density # Derive snowfall [m] and rain rates [m w.e.] if (SNOWF is not None) and (RRR is not None): SNOWFALL = SNOWF[t] RAIN = RRR[t]-SNOWFALL*(density_fresh_snow/ice_density) * 1000.0 elif (SNOWF is not None): SNOWFALL = SNOWF[t] else: # Else convert total precipitation [mm] to snowheight [m]; liquid/solid fraction SNOWFALL = (RRR[t]/1000.0)*(ice_density/density_fresh_snow)*(0.5*(-np.tanh(((T2[t]-zero_temperature) - center_snow_transfer_function) * spread_snow_transfer_function) + 1.0)) RAIN = RRR[t]-SNOWFALL*(density_fresh_snow/ice_density) * 1000.0 # if snowfall is smaller than the threshold if SNOWFALL<minimum_snowfall: SNOWFALL = 0.0 # if rainfall is smaller than the threshold if RAIN<(minimum_snowfall*(density_fresh_snow/ice_density)*1000.0): RAIN = 0.0 if SNOWFALL > 0.0: # Add a new snow node on top GRID.add_fresh_snow(SNOWFALL, density_fresh_snow, np.minimum(float(T2[t]),zero_temperature), 0.0) else: GRID.set_fresh_snow_props_update_time(dt) # Guarantee that solar radiation is greater equal zero if (G[t]<0.0): G[t] = 0.0 #-------------------------------------------- # Merge grid layers, if necessary #-------------------------------------------- GRID.update_grid() #-------------------------------------------- # Calculate albedo and roughness length changes if first layer is snow #-------------------------------------------- alpha = updateAlbedo(GRID, opt_dict) #-------------------------------------------- # Update roughness length #-------------------------------------------- z0 = updateRoughness(GRID, opt_dict) #-------------------------------------------- # Surface Energy Balance #-------------------------------------------- # Calculate net shortwave radiation SWnet = G[t] * (1 - alpha) # Penetrating SW radiation and subsurface melt if SWnet > 0.0: subsurface_melt, G_penetrating = penetrating_radiation(GRID, SWnet, dt, opt_dict) else: subsurface_melt = 0.0 G_penetrating = 0.0 # Calculate residual net shortwave radiation (penetrating part removed) sw_radiation_net = SWnet - G_penetrating if LWin is not None: # Find new surface temperature (LW is used from the input file) fun, surface_temperature, lw_radiation_in, lw_radiation_out, sensible_heat_flux, latent_heat_flux, \ ground_heat_flux, rain_heat_flux, rho, Lv, MOL, Cs_t, Cs_q, q0, q2 \ = update_surface_temperature(GRID, dt, z, z0, T2[t], RH2[t], PRES[t], sw_radiation_net, U2[t], RAIN, SLOPE, LWin=LWin[t], opt_dict=opt_dict) else: # Find new surface temperature (LW is parametrized using cloud fraction) fun, surface_temperature, lw_radiation_in, lw_radiation_out, sensible_heat_flux, latent_heat_flux, \ ground_heat_flux, rain_heat_flux, rho, Lv, MOL, Cs_t, Cs_q, q0, q2 \ = update_surface_temperature(GRID, dt, z, z0, T2[t], RH2[t], PRES[t], sw_radiation_net, U2[t], RAIN, SLOPE, N=N[t], opt_dict=opt_dict) #-------------------------------------------- # Surface mass fluxes [m w.e.q.] #-------------------------------------------- if surface_temperature < zero_temperature: sublimation = min(latent_heat_flux / (water_density * lat_heat_sublimation), 0) * dt deposition = max(latent_heat_flux / (water_density * lat_heat_sublimation), 0) * dt evaporation = 0 condensation = 0 else: sublimation = 0 deposition = 0 evaporation = min(latent_heat_flux / (water_density * lat_heat_vaporize), 0) * dt condensation = max(latent_heat_flux / (water_density * lat_heat_vaporize), 0) * dt #-------------------------------------------- # Melt process - mass changes of snowpack (melting, sublimation, deposition, evaporation, condensation) #-------------------------------------------- # Melt energy in [W m^-2 or J s^-1 m^-2] melt_energy = max(0, sw_radiation_net + lw_radiation_in + lw_radiation_out + ground_heat_flux + rain_heat_flux + sensible_heat_flux + latent_heat_flux) # Convert melt energy to m w.e.q. melt = melt_energy * dt / (1000 * lat_heat_melting) # Remove melt [m w.e.q.] lwc_from_melted_layers = GRID.remove_melt_weq(melt - sublimation - deposition) #-------------------------------------------- # Percolation #-------------------------------------------- Q = percolation(GRID, melt + condensation + RAIN/1000.0 + lwc_from_melted_layers, dt, opt_dict) #-------------------------------------------- # Refreezing #-------------------------------------------- water_refreezed = refreezing(GRID, opt_dict) #-------------------------------------------- # Solve the heat equation #-------------------------------------------- solveHeatEquation(GRID, dt, opt_dict) #-------------------------------------------- # Calculate new density to densification #-------------------------------------------- densification(GRID, SLOPE, dt, opt_dict) #-------------------------------------------- # Calculate mass balance #-------------------------------------------- surface_mass_balance = SNOWFALL * (density_fresh_snow / ice_density) - melt + sublimation + deposition + evaporation internal_mass_balance = water_refreezed - subsurface_melt mass_balance = surface_mass_balance + internal_mass_balance internal_mass_balance2 = melt-Q + subsurface_melt mass_balance_check = surface_mass_balance + internal_mass_balance2 # Cumulative mass balance for stake evaluation MB_cum = MB_cum + mass_balance # Store cumulative MB in pandas frame for validation if stake_names: if (DATA.isel(time=t).time.values in stake_data.index): _df['mb'].loc[DATA.isel(time=t).time.values] = MB_cum _df['snowheight'].loc[DATA.isel(time=t).time.values] = GRID.get_total_snowheight() # Save results _RAIN[t] = RAIN _SNOWFALL[t] = SNOWFALL * (density_fresh_snow/ice_density) _LWin[t] = lw_radiation_in _LWout[t] = lw_radiation_out _H[t] = sensible_heat_flux _LE[t] = latent_heat_flux _B[t] = ground_heat_flux _QRR[t] = rain_heat_flux _MB[t] = mass_balance _surfMB[t] = surface_mass_balance _Q[t] = Q _SNOWHEIGHT[t] = GRID.get_total_snowheight() _TOTALHEIGHT[t] = GRID.get_total_height() _TS[t] = surface_temperature _ALBEDO[t] = alpha _NLAYERS[t] = GRID.get_number_layers() _ME[t] = melt_energy _intMB[t] = internal_mass_balance _EVAPORATION[t] = evaporation _SUBLIMATION[t] = sublimation _CONDENSATION[t] = condensation _DEPOSITION[t] = deposition _REFREEZE[t] = water_refreezed _subM[t] = subsurface_melt _Z0[t] = z0 _surfM[t] = melt _MOL[t] = MOL if full_field: if GRID.get_number_layers()>max_layers: print('Maximum number of layers reached') else: _LAYER_HEIGHT[t, 0:GRID.get_number_layers()] = GRID.get_height() _LAYER_RHO[t, 0:GRID.get_number_layers()] = GRID.get_density() _LAYER_T[t, 0:GRID.get_number_layers()] = GRID.get_temperature() _LAYER_LWC[t, 0:GRID.get_number_layers()] = GRID.get_liquid_water_content() _LAYER_CC[t, 0:GRID.get_number_layers()] = GRID.get_cold_content() _LAYER_POROSITY[t, 0:GRID.get_number_layers()] = GRID.get_porosity() _LAYER_ICE_FRACTION[t, 0:GRID.get_number_layers()] = GRID.get_ice_fraction() _LAYER_IRREDUCIBLE_WATER[t, 0:GRID.get_number_layers()] = GRID.get_irreducible_water_content() _LAYER_REFREEZE[t, 0:GRID.get_number_layers()] = GRID.get_refreeze() else: _LAYER_HEIGHT = None _LAYER_RHO = None _LAYER_T = None _LAYER_LWC = None _LAYER_CC = None _LAYER_POROSITY = None _LAYER_ICE_FRACTION = None _LAYER_IRREDUCIBLE_WATER = None _LAYER_REFREEZE = None if stake_evaluation: # Evaluate stakes _stat = evaluate(stake_names, stake_data, _df) else: _stat = None _df = None # Restart if not WRF_X_CSPY: new_snow_height, new_snow_timestamp, old_snow_timestamp = GRID.get_fresh_snow_props() RESTART.NLAYERS.values[:] = GRID.get_number_layers() RESTART.NEWSNOWHEIGHT.values[:] = new_snow_height RESTART.NEWSNOWTIMESTAMP.values[:] = new_snow_timestamp RESTART.OLDSNOWTIMESTAMP.values[:] = old_snow_timestamp RESTART.LAYER_HEIGHT[0:GRID.get_number_layers()] = GRID.get_height() RESTART.LAYER_RHO[0:GRID.get_number_layers()] = GRID.get_density() RESTART.LAYER_T[0:GRID.get_number_layers()] = GRID.get_temperature() RESTART.LAYER_LWC[0:GRID.get_number_layers()] = GRID.get_liquid_water_content() RESTART.LAYER_IF[0:GRID.get_number_layers()] = GRID.get_ice_fraction() return (indY,indX,RESTART,_RAIN,_SNOWFALL,_LWin,_LWout,_H,_LE,_B, _QRR, \ _MB,_surfMB,_Q,_SNOWHEIGHT,_TOTALHEIGHT,_TS,_ALBEDO,_NLAYERS, \ _ME,_intMB,_EVAPORATION,_SUBLIMATION,_CONDENSATION,_DEPOSITION,_REFREEZE, \ _subM,_Z0,_surfM, _MOL, \ _LAYER_HEIGHT,_LAYER_RHO,_LAYER_T,_LAYER_LWC,_LAYER_CC,_LAYER_POROSITY,_LAYER_ICE_FRACTION, \ _LAYER_IRREDUCIBLE_WATER,_LAYER_REFREEZE,stake_names,_stat,_df)