def init_caete_dyn(self, input_fpath, stime_i, co2, pls_table): """ input_fpath: Files with climate and soil data co2: (list) a alist (association list) with yearly cCO2 ATM data pls_table: np.ndarray with functional traits of a set of PLant life strategies name: str a name for the gridcell group""" assert self.filled == False, "already done" self.input_fpath = Path(os.path.join(input_fpath, self.input_fname)) assert self.input_fpath.exists() with bz2.BZ2File(self.input_fpath, mode='r') as fh: self.data = pkl.load(fh) os.makedirs(self.out_dir, exist_ok=True) self.flush_data = 0 self.pr = self.data['pr'] self.ps = self.data['ps'] self.rsds = self.data['rsds'] self.tas = self.data['tas'] self.rhs = self.data['hurs'] # SOIL AND NUTRIENTS self.input_nut = [] self.nutlist = ['tn', 'tp', 'ap', 'ip', 'op'] for nut in self.nutlist: self.input_nut.append(self.data[nut]) self.soil_dict = dict(zip(self.nutlist, self.input_nut)) self.data = None # TIME self.stime = copy.deepcopy(stime_i) self.calendar = self.stime['calendar'] self.time_index = self.stime['time_index'] self.time_unit = self.stime['units'] self.ssize = self.time_index.size self.sind = int(self.time_index[0]) self.eind = int(self.time_index[-1]) self.start_date = cftime.num2date(self.time_index[0], self.time_unit, calendar=self.calendar) self.end_date = cftime.num2date(self.time_index[-1], self.time_unit, calendar=self.calendar) # OTHER INPUTS self.pls_table = pls_table.copy() self.neighbours = neighbours_index(self.pos, mask) self.soil_temp = st.soil_temp_sub(self.tas[:1095] - 273.15) # Prepare co2 inputs (we have annually means) self.co2_data = copy.deepcopy(co2) # STATE self.wfim = None self.gfim = None self.sfim = None self.wp_water = 0.01 self.wp_ice = 0.0 self.wp_snow = 0.0 self.tsoil = [] self.emaxm = [] # start biomass self.vp_cleaf, self.vp_croot, self.vp_cwood = m.spinup2( 1.0, self.pls_table) a, b, c, d = m.pft_area_frac(self.vp_cleaf, self.vp_croot, self.vp_cwood, self.pls_table[6, :]) self.vp_lsid = np.where(a > 0.0)[0] del a, b, c, d self.vp_csap = np.zeros(shape=(npls, ), order='F') self.vp_cheart = np.zeros(shape=(npls, ), order='F') self.vp_dcl = np.zeros(shape=(npls, ), order='F') self.vp_dca = np.zeros(shape=(npls, ), order='F') self.vp_dcf = np.zeros(shape=(npls, ), order='F') self.vp_ocp = np.zeros(shape=(npls, ), order='F') self.vp_sto = np.zeros(shape=(3, npls), order='F') # # # SOIL START self.sp_csoil = np.zeros(shape=(4, ), order='F') + 1.0 self.sp_snc = np.zeros(shape=(8, ), order='F') self.sp_available_p = self.soil_dict['ap'] self.sp_available_n = 0.2 * self.soil_dict['tn'] self.sp_in_n = 0.5 * self.soil_dict['tn'] self.sp_so_n = 0.3 * self.soil_dict['tn'] self.sp_so_p = self.soil_dict['tp'] - sum(self.input_nut[2:]) self.sp_in_p = self.soil_dict['ip'] self.sp_uptk_costs = np.zeros(npls, order='F') self.sp_organic_n = 0.01 self.sp_sorganic_n = 0.01 self.sp_organic_p = 0.01 self.sp_sorganic_p = 0.01 self.outputs = dict() self.filled = True return None
def init_caete_dyn(self, input_fpath, stime_i, co2, pls_table, tsoil, ssoil): """ PREPARE A GRIDCELL TO RUN TODO adapt to change climatic data/ maybe another method input_fpath:(str or pathlib.Path) path to Files with climate and soil data co2: (list) a alist (association list) with yearly cCO2 ATM data(yyyy\t[CO2]\n) pls_table: np.ndarray with functional traits of a set of PLant life strategies """ assert self.filled == False, "already done" self.input_fpath = Path(os.path.join(input_fpath, self.input_fname)) assert self.input_fpath.exists() with bz2.BZ2File(self.input_fpath, mode='r') as fh: self.data = pkl.load(fh) os.makedirs(self.out_dir, exist_ok=True) self.flush_data = 0 self.pr = self.data['pr'] self.ps = self.data['ps'] self.rsds = self.data['rsds'] self.tas = self.data['tas'] self.rhs = self.data['hurs'] # SOIL AND NUTRIENTS self.input_nut = [] self.nutlist = ['tn', 'tp', 'ap', 'ip', 'op'] for nut in self.nutlist: self.input_nut.append(self.data[nut]) self.soil_dict = dict(zip(self.nutlist, self.input_nut)) self.data = None # TIME self.stime = copy.deepcopy(stime_i) self.calendar = self.stime['calendar'] self.time_index = self.stime['time_index'] self.time_unit = self.stime['units'] self.ssize = self.time_index.size self.sind = int(self.time_index[0]) self.eind = int(self.time_index[-1]) self.start_date = cftime.num2date(self.time_index[0], self.time_unit, calendar=self.calendar) self.end_date = cftime.num2date(self.time_index[-1], self.time_unit, calendar=self.calendar) # OTHER INPUTS self.pls_table = pls_table.copy() self.neighbours = neighbours_index(self.pos, mask) self.soil_temp = st.soil_temp_sub(self.tas[:1095] - 273.15) # Prepare co2 inputs (we have annually means) self.co2_data = copy.deepcopy(co2) self.tsoil = [] self.emaxm = [] # STATE self.wp_water_upper = np.float64(0.1) # vol/vol self.wp_water_lower = np.float64(0.1) # vol/vol self.wp_water_upper_mm = self.wp_water_upper * 300.0 self.wp_water_lower_mm = self.wp_water_lower * 700.0 self.wp_sat_water_upper_ratio = tsoil[0][self.y, self.x].copy() self.wp_field_capacity_upper = tsoil[1][self.y, self.x].copy() self.wp_wilting_point_upper = tsoil[2][self.y, self.x].copy() self.wp_sat_water_lower_ratio = ssoil[0][self.y, self.x].copy() self.wp_field_capacity_lower = ssoil[1][self.y, self.x].copy() self.wp_wilting_point_lower = ssoil[2][self.y, self.x].copy() self.wp_sat_water_upper_mm = self.wp_sat_water_upper_ratio * 300.0 self.wp_sat_water_lower_mm = self.wp_sat_water_lower_ratio * 700.0 self.wmax_mm = np.float64(self.wp_sat_water_upper_mm + self.wp_sat_water_lower_mm) # start biomass self.vp_cleaf, self.vp_croot, self.vp_cwood = m.spinup2( 1.0, self.pls_table) a, b, c, d = m.pft_area_frac(self.vp_cleaf, self.vp_croot, self.vp_cwood, self.pls_table[6, :]) self.vp_lsid = np.where(a > 0.0)[0] del a, b, c, d self.vp_dcl = np.zeros(shape=(npls, ), order='F') self.vp_dca = np.zeros(shape=(npls, ), order='F') self.vp_dcf = np.zeros(shape=(npls, ), order='F') self.vp_ocp = np.zeros(shape=(npls, ), order='F') self.vp_sto = np.zeros(shape=(3, npls), order='F') # # # SOIL START self.sp_csoil = np.zeros(shape=(4, ), order='F') + 1.0 self.sp_snc = np.zeros(shape=(8, ), order='F') self.sp_available_p = self.soil_dict['ap'] self.sp_available_n = 0.2 * self.soil_dict['tn'] self.sp_in_n = 0.5 * self.soil_dict['tn'] self.sp_so_n = 0.3 * self.soil_dict['tn'] self.sp_so_p = self.soil_dict['tp'] - sum(self.input_nut[2:]) self.sp_in_p = self.soil_dict['ip'] self.sp_uptk_costs = np.zeros(npls, order='F') self.sp_organic_n = 0.01 self.sp_sorganic_n = 0.01 self.sp_organic_p = 0.01 self.sp_sorganic_p = 0.01 self.outputs = dict() self.filled = True return None
def run_dyn(grd, at=np.copy(d_at)): """apply CAETÊ in dynamical mode in gridcell grd for nt1 days""" # starting variables # execute the model according to grd time variables RUN = 0 w0 = np.zeros(shape=npls,) + 0.01 g0 = np.zeros(shape=npls,) s0 = np.zeros(shape=npls,) dcl = np.zeros(npls,) dca = np.zeros(npls,) dcf = np.zeros(npls,) if grd.run_id == 'spinup': grd.clin, grd.cfin, grd.cwin = model_funcs.spinup2(0.5, at) # ndays,x,y,run,dt,w0,g0,s0,dcl,dca,dcf,prec,temp,p0,par,rhs& # &,cleaf_ini,cawood_ini,cfroot_ini outputs = model.caete_dyn(grd.x, grd.y, RUN, at, w0, g0, s0, dcl, dca, dcf, grd.pr, grd.tas, grd.ps, grd.rsds, grd.rhs, grd.clin, grd.cwin, grd.cfin) # TODO # atualizar attributos de tempo de grd # Cut off no_data tails # Include the cut of the time variables # def cut_tail(in_array): # return in_array[0:ndays-1] grd.emaxm = outputs[0] grd.tsoil = outputs[1] grd.photo = outputs[2] grd.aresp = outputs[3] grd.npp = outputs[4] grd.lai = outputs[5] grd.c**t = outputs[6] # 2D grd.csoil = outputs[7] # 3D grd.hresp = outputs[8] grd.rcm = outputs[9] grd.f5 = outputs[10] grd.runom = outputs[11] grd.evapm = outputs[12] grd.wsoil = outputs[13] grd.rm = outputs[14] grd.rg = outputs[15] grd.cleaf = outputs[16] grd.cawood = outputs[17] grd.cfroot = outputs[18] grd.area = outputs[19] grd.wue = outputs[20] grd.cue = outputs[21] grd.cdef = outputs[22] grd.wfim = outputs[23] grd.gfim = outputs[24] grd.sfim = outputs[25] grd.dl_final = outputs[26] grd.dw_final = outputs[27] grd.dr_final = outputs[28] grd.clf = outputs[29] grd.caf = outputs[30] grd.cff = outputs[31] grd.nitro_min = outputs[32] grd.phop_lab = outputs[33] grd.vcmax = outputs[34] grd.specific_la = outputs[35] grd.nupt = outputs[36] grd.pupt = outputs[37] grd.litter_l = outputs[38] grd.cwd = outputs[39] grd.litter_fr = outputs[40] grd.lnr = outputs[41] grd.storage_pool = outputs[42] def spin(grd1, r_number): """ Continuation Runs """ outputs = model.caete_dyn(grd.x, grd.y, r_number, at, grd1.wfim, grd1.gfim, grd1.sfim, grd1.dl_final, grd1.dw_final, grd1.dr_final, grd1.pr, grd1.tas, grd1.ps, grd1.rsds, grd1.rhs, grd1.clf, grd1.caf, grd1.cff) grd1.emaxm = np.hstack((grd1.emaxm, outputs[0])) grd1.tsoil = np.hstack((grd1.tsoil, outputs[1])) grd1.photo = np.hstack((grd1.photo, outputs[2])) grd1.aresp = np.hstack((grd1.aresp, outputs[3])) grd1.npp = np.hstack((grd1.npp, outputs[4])) grd1.lai = np.hstack((grd1.lai, outputs[5])) grd1.c**t = np.hstack((grd1.c**t, outputs[6])) grd1.csoil = np.hstack((grd1.csoil, outputs[7])) grd1.hresp = np.hstack((grd1.hresp, outputs[8])) grd1.rcm = np.hstack((grd1.rcm, outputs[9])) grd1.f5 = np.hstack((grd1.f5, outputs[10])) grd1.runom = np.hstack((grd1.runom, outputs[11])) grd1.evapm = np.hstack((grd1.evapm, outputs[12])) grd1.wsoil = np.hstack((grd1.wsoil, outputs[13])) grd1.rm = np.hstack((grd1.rm, outputs[14])) grd1.rg = np.hstack((grd1.rg, outputs[15])) grd1.cleaf = np.hstack((grd1.cleaf, outputs[16])) grd1.cawood = np.hstack((grd1.cawood, outputs[17])) grd1.cfroot = np.hstack((grd1.cfroot, outputs[18])) grd1.area = np.vstack((grd1.area, outputs[19])) grd1.wue = np.hstack((grd1.wue, outputs[20])) grd1.cue = np.hstack((grd1.cue, outputs[21])) grd1.cdef = np.hstack((grd1.cdef, outputs[22])) grd1.wfim = outputs[23] grd1.gfim = outputs[24] grd1.sfim = outputs[25] grd1.dl_final = outputs[26] grd1.dw_final = outputs[27] grd1.dr_final = outputs[28] grd1.clf = outputs[29] grd1.caf = outputs[30] grd1.cff = outputs[31] grd1.nitro_min = np.hstack((grd1.nitro_min, outputs[32])) grd1.phop_lab = np.hstack((grd1.phop_lab, outputs[33])) grd1.vcmax = np.hstack((grd1.vcmax, outputs[34])) grd1.specific_la = np.hstack((grd1.specific_la, outputs[35])) grd1.nupt = np.hstack((grd1.nupt, outputs[36])) grd1.pupt = np.hstack((grd1.pupt, outputs[37])) grd1.litter_l = np.hstack((grd1.litter_l, outputs[38])) grd1.cwd = np.hstack((grd1.cwd, outputs[39])) grd1.litter_fr = np.hstack((grd1.litter_fr, outputs[40])) grd1.lnr = np.hstack((grd1.lnr, outputs[41])) grd1.storage_pool = np.hstack((grd1.storage_pool, outputs[42])) # # GAMBIARRA NERVOSA print('\n--run 1\n') RUN += int(gp.nt1) spin(grd, RUN) print('\n--run 2\n') RUN += int(gp.nt1) spin(grd, RUN) print('\n--run 3\n') RUN += int(gp.nt1) spin(grd, RUN) print('\n--run 4\n') RUN += int(gp.nt1) spin(grd, RUN) print('\n--run 5\n') RUN += int(gp.nt1) spin(grd, RUN)