def find_derivs(var_vec, the_time, cloud_tup): """ calcuate derivatives of var_vec Parameters ---------- var_vec: vector(float) vector of values to be integrated the_time: float timestep cloud_tup: namedtuple tuple of necessary coefficients Returns ------- deriv_vec: vector(float) derivatives of each of var_vec """ # print('inside: ',var_vec) temp, press, height = var_vec[-3:] numrads = len(var_vec) - 3 dry_radius = cloud_tup.dry_radius rho = press / (c.Rd * temp) # # find the evironmental S by water balance # S = Scalc(var_vec, cloud_tup) deriv_vec = np.zeros_like(var_vec) # dropgrow notes equaton 18 (W&H p. 170) for i in range(numrads): m = cloud_tup.masses[i] if var_vec[i] < dry_radius[i]: var_vec[i] = dry_radius[i] Seq = cloud_tup.koehler_fun(var_vec[i], m) rhovr = (Seq * find_esat(temp)) / (c.Rv * temp) rhovinf = S * find_esat(temp) / (c.Rv * temp) # day 25 drop_grow.pdf eqn. 18 deriv_vec[i] = (c.D / (var_vec[i] * c.rhol)) * (rhovinf - rhovr) # # moist adiabat day 25 equation 21a # deriv_vec[-3] = find_lv(temp) / c.cpd * wlderiv(var_vec, deriv_vec, cloud_tup) - c.g0 / c.cpd * cloud_tup.wvel # # hydrostatic balance dp/dt = -rho g dz/dt # deriv_vec[-2] = -1.0 * rho * c.g0 * cloud_tup.wvel # # how far up have we traveled? # deriv_vec[-1] = cloud_tup.wvel return deriv_vec
def Scalc(var_vec, cloud_tup): """ calculate the environmental saturation using conservation of total water mixing ratio cloud_top.wt and the current value of the liquid water mixing ratio wl Parameters ---------- var_vec: vector(float) vector of values to be integrated cloud_top: namedtuple tuple of necessary coefficients Returns ------- Sout: float environmental saturation """ temp, press, height = var_vec[-3:] wl = wlcalc(var_vec, cloud_tup) wv = cloud_tup.wt - wl e = wv * press / (c.eps + wv) Sout = e / find_esat(temp) return Sout
def find_rsat(temp,press): """ input: temp (K) press (hPa) output: rsat (kg/kg) """ esat = find_esat(temp)*0.01 rsat=c.eps*esat/(press - esat) return rsat
def therm_calc(the_row): rT = cloud_vars['wt'] S = the_row[-1] temp, press,height = the_row[-4:-1] esat = find_esat(temp) e = S*esat rv = c.eps*e/(press - e) #Thompkins eqn 2.20 Td = find_Td(rv,press) thetae = find_thetaet(Td,rT,temp,press) hm = c.cpd*temp + find_lv(temp)*rv + c.g0*height return (thetae, hm)
def zero_rs(temp,rsat,press): """ find the saturation temperature for a given rsat,press, by rootfinding this zero input: temp (guess) (K) rsat (kg/kg) press (hPa) output: residual see thompkins 2.20 """ esat=find_esat(temp)*0.01 #convert to hPa residual=rsat - c.eps*esat/(press - esat) return residual
def parse_data(data_text): all_lines=data_text.strip().split('\n') count=0 theLine=all_lines[count] try: while theLine.find('PRES HGHT TEMP DWPT') < 0: count += 1 theLine = all_lines[count] header_names=all_lines[count].lower().split() except IndexError: print("no column header line found in sounding") sys.exit(1) count += 1 #go to unit names unit_names=all_lines[count].split() count+=2 #skip a row of ------ data_list=[] while True: try: the_line=all_lines[count] dataFields = the_line.split() if len(dataFields) == 11: try: dataFields = [float(number) for number in dataFields] es = find_esat(dataFields[3] + 273.15)*0.01 #get vapor pressure from dewpoint in hPa dataFields[5] = (con.eps*es/(dataFields[0] - es))*1.e3 #g/kg except VauleError: print('trouble converting dataFields to float') print(dataFields) sys.exit(1) data_list.append(dataFields) # # get the next line # count += 1 theLine = all_lines[count] except IndexError: break df_out=pd.DataFrame.from_records(data_list,columns=header_names) return df_out,unit_names
numrads = len(initial_radius) var_vec = np.empty(numrads + 3) for i in range(numrads): var_vec[i] = initial_radius[i] # # temp, press and height go at the end of the vector # var_vec[-3] = parcel.Tinit var_vec[-2] = parcel.Pinit var_vec[-1] = parcel.Zinit cloud_tup = make_tuple(cloud_vars) #calculate the total water (kg/kg) wl=wlcalc(var_vec,cloud_tup); e=parcel.Sinit*find_esat(parcel.Tinit); wv=c.eps*e/(parcel.Pinit - e) #save total water cloud_vars['wt'] = wv + wl cloud_vars['wvel'] = parcel.wvel cloud_vars['wvel'] = 1.5 # # pass this to the find_derivs function # cloud_tup= make_tuple(cloud_vars) # ### use odeint to integrate the variable in var_vec from tinit to tfin with outputs every dt seconds # In[43]:
# In[11]: from a405thermo.thermlib import find_rsat, find_esat from a405thermo.constants import constants as c x,y,z,temp = get_var(the_file,'TABS') x,y,z,press = get_var(the_file,'p') vert_cross_sec = temp[:,row_number,:end_col] plt.close('all') fig,ax = plt.subplots(1,1,figsize=(10,10)) image=ax.pcolormesh(x[:end_col],z,vert_cross_sec[:,:end_col]) cax = plt.colorbar(image,ax=ax) cax.set_label('temperature (K)') ax.set_title('vertical temp cross section along y=2 km') esat = find_esat(temp) esat.shape # # add dimensions to the 1D pressure vectory so # that it can be used in the denominator # press = press[:,np.newaxis,np.newaxis]*100. #convert to Pa rsat = c.eps*esat/(press - esat)*1.e3 #convert to g/kg rh = qv/rsat fig,ax = plt.subplots(1,1,figsize=(10,10)) vert_cross_sec = rh[:,row_number,:end_col] image=ax.pcolormesh(x[:end_col],z,vert_cross_sec[:,:end_col]) cax = plt.colorbar(image,ax=ax) cax.set_label('relative humidity') ax.set_title('relative humidity cross section along y=2 km')
def parse_data(data_text): """ Read a single sounding into a dataframe Parameters ---------- data_text : str sounding text Returns ------- df_out : dataframe 11 column data frame with sounding values unit_name : list list of strings with name of units of each column """ """ read lines with 11 numbers and convert to dataframe data_text looks like: ----------------------------------------------------------------------------- PRES HGHT TEMP DWPT RELH MIXR DRCT SKNT THTA THTE THTV hPa m C C % g/kg deg knot K K K ----------------------------------------------------------------------------- 1000.0 100 979.0 288 24.0 23.0 94 18.45 0 0 299.0 353.0 302.2 974.0 333 25.2 21.1 78 16.46 348 0 300.6 349.1 303.6 932.0 719 24.0 16.0 61 12.42 243 3 303.2 340.3 305.4 925.0 785 23.4 15.4 61 12.03 225 3 303.2 339.2 305.4 """ all_lines=data_text.strip().split('\n') count=0 theLine=all_lines[count] try: while theLine.find('PRES HGHT TEMP DWPT') < 0: count += 1 theLine = all_lines[count] header_names=all_lines[count].lower().split() except IndexError: print("no column header line found in sounding") sys.exit(1) count += 1 #go to unit names unit_names=all_lines[count].split() count+=2 #skip a row of ------ data_list=[] while True: try: the_line=all_lines[count] dataFields = the_line.split() if len(dataFields) == 11: try: dataFields = [float(number) for number in dataFields] es = find_esat(dataFields[3] + 273.15)*0.01 #get vapor pressure from dewpoint in hPa dataFields[5] = (con.eps*es/(dataFields[0] - es))*1.e3 #g/kg except ValueError: print('trouble converting dataFields to float') print(dataFields) sys.exit(1) data_list.append(dataFields) # # get the next line # count += 1 theLine = all_lines[count] except IndexError: break df_out=pd.DataFrame.from_records(data_list,columns=header_names) return df_out,unit_names
rv: {rv:6.3g} kg/kg rl: {rl:6.3g} kg/kg rt: {rt:6.3g} kg/kg enthalpy: {enthalpy: 8.3g} J/kg """ return the_string.format_map(the_tup._asdict()) get_ipython().magic('matplotlib inline') pa2hPa = 1.e-2 A_press = 1.e5 #Pa B_press = 4.e4 #Pa A_temp = 300 #K RH = 0.8 e = find_esat(A_temp)*RH A_rv = c.eps*e/(A_press - e) A_Td = find_Td(A_rv,A_press) print('tropical surface dewpoint: {} K'.format(A_Td)) A_thetae=find_thetaet(A_Td,A_rv,A_temp,A_press) print('tropical surface thetae: {} K'.format(A_thetae)) A_temp,A_rv,A_rl = tinvert_thetae(A_thetae,A_rv,A_press) fields=['id','temp','rv','rl','press'] A_dict = dict(zip(fields,('A',A_temp,A_rv,A_rl,A_press))) A_tup = calc_enthalpy(A_dict) print(format_tup(A_tup)) # ### B. Lift to 400 hPa and remove 80% of the liquied water # In[201]: