def do_thermodynamics(self): assert 'temp' in self.soundingdata, \ "Temperature needed for thermodynamics! Add TEMP" assert 'pres' in self.soundingdata, \ "Pressure needed for thermodynamics! Add PRES" assert 'dwpt' in self.soundingdata, \ "Moisture needed for thermodynamics! Add DWPT" # primary variables prespa = self.soundingdata['pres'] * 100. tempc = self.soundingdata['temp'] tempk = tempc + degCtoK dwptc = self.soundingdata['dwpt'] # secondary variables e = VaporPressure(dwptc) esat = VaporPressure(tempc) # assign/extract other variables if 'thta' not in self.soundingdata: self.soundingdata['thta'] = Theta(tempk, prespa) if 'thte' not in self.soundingdata: self.soundingdata['thte'] = ThetaE(tempk, prespa, e) if 'thtv' not in self.soundingdata: self.soundingdata['thtv'] = ThetaV(tempk, prespa, e) if 'relh' not in self.soundingdata: self.soundingdata['relh'] = 100. * e / esat return
def precipitable_water(self): """Calculate Total Precipitable Water (TPW) for sounding. TPW is defined as the total column-integrated water vapour. I calculate it from the dew point temperature because this is the fundamental moisture variable in this module (even though it is RH that is usually measured directly) """ tempk = self.soundingdata['temp'] + degCtoK prespa = self.soundingdata['pres'] * 100. hghtm = self.soundingdata['hght'] # Get Water Vapour Mixing Ratio, by calculation # from dew point temperature try: dwptc = self.soundingdata['dwpt'] except KeyError: print("Warning: No MIXR or DWPT for TPW calculation") return -999. vprespa = VaporPressure(dwptc) mixrkg = MixRatio(vprespa, prespa) # Calculate density of air (accounting for moisture) rho = DensHumid(tempk, prespa, vprespa) # Trapezoidal rule to approximate TPW (units kg/m^2==mm) tpw = trapz(mixrkg*rho, hghtm) return tpw
def mixed_layer_parcel(self, depth=100): """Returns parameters for a parcel initialised by: 1. Surface pressure (i.e. pressure of lowest level) 2. Surface temperature determined from mean(theta) of lowest <depth> mb 3. Dew point temperature representative of lowest <depth> mbar Inputs: depth (mbar): depth to average mixing ratio over """ pres = self.soundingdata["pres"] temp = self.soundingdata["temp"] dwpt = self.soundingdata["dwpt"] pres0, temp0, dwpt0, null = self.surface_parcel() # identify the layers for averaging layers = pres > (pres0-depth) # average theta over mixheight to give # parcel temperature thta_mix = Theta(temp[layers]+degCtoK, pres[layers]*100.).mean() temp_s = TempK(thta_mix, pres0*100) - degCtoK # average mixing ratio over mixheight vpres = VaporPressure(dwpt) mixr = MixRatio(vpres, pres*100) mixr_mix = mixr[layers].mean() vpres_s = MixR2VaporPress(mixr_mix, pres0*100) # surface dew point temp dwpt_s = DewPoint(vpres_s) # print "----- Mixed Layer Parcel Characteristics -----" # print "Mixed layer depth : %5d mb "%depth # print "Mean mixed layer potential temperature: %5.1f K"%thta_mix # print "Mean mixed layer mixing ratio : %5.2f g/kg"% # (mixr_mix*1e3) return pres0, temp_s, dwpt_s, 'ml' raise NotImplementedError
def dry_ascent(startp, startt, startdp, nsteps=101): from numpy import interp # ------------------------------------------------------------------- # Lift a parcel dry adiabatically from startp to LCL. # Init temp is startt in C, Init dew point is stwrtdp, # pressure levels are in hPa # ------------------------------------------------------------------- assert startdp <= startt if startdp == startt: return array([startp]), array([startt]), array([startdp]), # Pres=linspace(startp,600,nsteps) Pres = logspace(log10(startp), log10(600), nsteps) # Lift the dry parcel T_dry = (startt+degCtoK) * (Pres/startp)**(Rs_da/Cp_da) - degCtoK # Mixing ratio isopleth starte = VaporPressure(startdp) startw = MixRatio(starte, startp*100) e = Pres * startw / (.622+startw) T_iso = 243.5 / (17.67/log(e/6.112)-1) # Solve for the intersection of these lines (LCL). # interp requires the x argument (argument 2) # to be ascending in order! P_lcl = interp(0, T_iso-T_dry, Pres) T_lcl = interp(P_lcl, Pres[::-1], T_dry[::-1]) # presdry=linspace(startp,P_lcl) presdry = logspace(log10(startp), log10(P_lcl), nsteps) tempdry = interp(presdry, Pres[::-1], T_dry[::-1]) tempiso = interp(presdry, Pres[::-1], T_iso[::-1]) return presdry, tempdry, tempiso
rgrFreezingLevel[st, iTT] = 0 else: f = interp1d(rgrData_act[rgsSondVars.index('T'), :], rgrData_act[rgsSondVars.index('Z'), :]) rgrFreezingLevel[st, iTT] = f(0) if rgrData_act[rgsSondVars.index('T'), 0] <= 3: rgr3CLevel[st, iTT] = 0 else: f = interp1d(rgrData_act[rgsSondVars.index('T'), :], rgrData_act[rgsSondVars.index('Z'), :]) rgr3CLevel[st, iTT] = f(3) # calculate melting level height ESAT = esat(rgrData_act[rgsSondVars.index('T'), :] + 273.15) ee = VaporPressure( rgrData_act[rgsSondVars.index('T'), :] - rgrData_act[rgsSondVars.index('DPD'), :], phase="liquid") rgrMixRatio = MixRatio( ee, rgrData_act[rgsSondVars.index('P'), :]) VapPres = MixR2VaporPress( rgrMixRatio, rgrData_act[rgsSondVars.index('P'), :]) rgrRH = (VapPres / ESAT) * 100. rgrWBT = WetBulb(rgrData_act[rgsSondVars.index('T'), :], rgrRH) if rgrWBT[0] <= 0: rgrWBZ[st, iTT] = 0 else: f = interp1d(rgrWBT, rgrData_act[rgsSondVars.index('Z'), :]) rgrWBZ[st, iTT] = f(0) # rSolPrecProb=fnSolidPrecip(1,-5,0)