def MWtemphum(self): Theta = N.zeros_like(self.z, dtype=N.dtype('f8')) RH = N.zeros_like(Theta) P = N.zeros_like(Theta) # P = self.get_stdP(self.z) RV = N.zeros_like(Theta) T = N.zeros_like(Theta) # P[0] = 101325 P[0] = 100000 # P[0] = 99500 T[0] = self.th0 for idx, z in enumerate(self.z): if z <= self.zT: Theta[idx] = self.th0 + ((self.thT - self.th0) * ((z / self.zT)**1.25)) RH[idx] = 1 - (0.75 * ((z / self.zT)**1.25)) else: Theta[idx] = self.thT * N.exp( (mc.g / (mc.cp * self.tT)) * (z - self.zT)) RH[idx] = 0.25 for idx, z in enumerate(self.z): if idx > 0: dZ = self.z[idx] - self.z[idx - 1] # dZZ = self.z[idx] # dP = self.compute_P_at_z(P[idx-1],DryBulb[idx-1]-(6.5*dZ*10**-3),dZ) # dP = self.compute_P_at_z(P[idx-1],T[idx-1],dZ) # dP = self.compute_P_at_z(P[idx-1],T[idx-1]-(7*dZ*10**-3),dZ) mT = T[idx - 1] - (7 * 0.5 * dZ * 10**-3) # mT = T[idx-1] P[idx] = self.compute_P_at_z(P[idx - 1], mT, RH[idx], dZ) # P[idx] = P[idx-1] + (1.0*dP) T[idx] = self.compute_drybulb(Theta[idx], P[idx]) pass # pdb.set_trace() T = self.compute_drybulb(Theta, P) T_D = self.compute_Td(T, RH) # RV = self.compute_rv(P,T,RH) RV = self.compute_rv(P, Td=T_D) RV = RV * 0.85 # Set constant mixing ratio at surface # PBLidx = N.argmax(P<85000) PBLidx = N.argmax(RV < self.qv0) #-2 # RV_const = RV[PBLidx+1] RV_const = self.qv0 RV[0:PBLidx] = RV_const RH2 = self.RH_invert_RV(P, T, RV) # Fix constant theta-e in lowest layer # hLCL = ( 20 + ((T[0]-273.15)/5)) * (100-(100*RH2[0])) # pdb.set_trace() # LCLidx = N.argmax(self.z>hLCL)#-2 # thE = self.compute_thetaep(P[LCLidx],RV[LCLidx],T[LCLidx],RH[LCLidx]) # Theta[0:LCLidx] = self.compute_theta(thE,RV[0:LCLidx],T[LCLidx]) # pdb.set_trace() test_plot = False if test_plot: # Recalculate RH in PBL # ES = self.compute_es(T) # RVs = 0.622*(ES/(P-ES)) # RH2 = RV/RVs # T_D = self.compute_Td(T,RH2) # T = self.compute_drybulb(Theta,P) T_D = self.compute_Td(T, RH2) sT.plot_profile(P / 100, T - 273.15, T_D - 273.15, '/home/johnlawson') # pdb.set_trace() return Theta, RV
def MWtemphum(self): Theta = N.zeros_like(self.z,dtype=N.dtype('f8')) RH = N.zeros_like(Theta) P = N.zeros_like(Theta) # P = self.get_stdP(self.z) RV = N.zeros_like(Theta) T = N.zeros_like(Theta) # P[0] = 101325 P[0] = 100000 # P[0] = 99500 T[0] = self.th0 for idx,z in enumerate(self.z): if z <= self.zT: Theta[idx] = self.th0 + ((self.thT - self.th0)*( (z/self.zT)**1.25)) RH[idx] = 1 - (0.75*((z/self.zT)**1.25)) else: Theta[idx] = self.thT * N.exp( (mc.g/(mc.cp*self.tT))*(z-self.zT)) RH[idx] = 0.25 for idx,z in enumerate(self.z): if idx > 0: dZ = self.z[idx] - self.z[idx-1] # dZZ = self.z[idx] # dP = self.compute_P_at_z(P[idx-1],DryBulb[idx-1]-(6.5*dZ*10**-3),dZ) # dP = self.compute_P_at_z(P[idx-1],T[idx-1],dZ) # dP = self.compute_P_at_z(P[idx-1],T[idx-1]-(7*dZ*10**-3),dZ) mT = T[idx-1] - (7*0.5*dZ*10**-3) # mT = T[idx-1] P[idx] = self.compute_P_at_z(P[idx-1],mT,RH[idx],dZ) # P[idx] = P[idx-1] + (1.0*dP) T[idx] = self.compute_drybulb(Theta[idx],P[idx]) pass # pdb.set_trace() T = self.compute_drybulb(Theta,P) T_D = self.compute_Td(T,RH) # RV = self.compute_rv(P,T,RH) RV = self.compute_rv(P,Td=T_D) RV = RV*0.85 # Set constant mixing ratio at surface # PBLidx = N.argmax(P<85000) PBLidx = N.argmax(RV<self.qv0)#-2 # RV_const = RV[PBLidx+1] RV_const = self.qv0 RV[0:PBLidx] = RV_const RH2 = self.RH_invert_RV(P,T,RV) # Fix constant theta-e in lowest layer # hLCL = ( 20 + ((T[0]-273.15)/5)) * (100-(100*RH2[0])) # pdb.set_trace() # LCLidx = N.argmax(self.z>hLCL)#-2 # thE = self.compute_thetaep(P[LCLidx],RV[LCLidx],T[LCLidx],RH[LCLidx]) # Theta[0:LCLidx] = self.compute_theta(thE,RV[0:LCLidx],T[LCLidx]) # pdb.set_trace() test_plot = False if test_plot: # Recalculate RH in PBL # ES = self.compute_es(T) # RVs = 0.622*(ES/(P-ES)) # RH2 = RV/RVs # T_D = self.compute_Td(T,RH2) # T = self.compute_drybulb(Theta,P) T_D = self.compute_Td(T,RH2) sT.plot_profile(P/100,T-273.15,T_D-273.15,'/home/johnlawson') # pdb.set_trace() return Theta, RV
def buoyancy(self, ): """ Parcel buoyancy profile, or Eq. (A1) in MW01. Returns ------- b : array_like Atmospheric profile of buoyancy. qv : array_like Atmospheric profile of mixing ratio """ z = self.z E = self.E m = self.m zL = self.zL H = self.H zT = self.zT RH = self.RH # z' in Eq (1) dz = z - zL # Index of LCL, k2, and tropopause Lidx = N.where(z == zL)[0][0] k2idx = N.where(z == self.k2z)[0][0] Tidx = N.where(z == zT)[0][0] # Height above LCL of max buoyancy self.Zb = H / m # Buoyancy profile b = ((E * dz * m**2) / (H**2)) * N.exp((m / H) * -dz) # Set buoyancy to zero at and above tropopause # troposphere = N.where(z>=zT) # bT = copy.copy(b) # bT[troposphere] = 0 # Generating other arrays P = N.zeros_like(z, dtype=N.dtype('f8')) Theta = N.zeros_like(P) Rv = N.zeros_like(P) DryBulb = N.zeros_like(P) # Stats at k2 P[k2idx] = self.k2P Rv[k2idx] = self.compute_rv(self.k2P, Td=self.k2Td) self.k2RH = self.compute_RH(self.k2Td, self.k2T) Theta[k2idx] = self.compute_theta_2(self.k2P, self.k2T) DryBulb[k2idx] = self.k2T # Temperature at the LCL TLCL = self.compute_TLCL(self.k2Td, self.k2T) # self.k2the = self.compute_thetae_4(DryBulb[k2idx],P[k2idx], # Rv[k2idx],TLCL) self.k2the = self.compute_thetaep(P[k2idx], Rv[k2idx], self.k2T, self.k2RH) # self.k2the = self.compute_thetae_3(Theta[k2idx],self.k2P,self.k2Td, self.k2T,Rv[k2idx],TL=TLCL) # self.k2the = self.compute_thetae(self.k2T,self.k2rv,self.k2P,self.k2Td) # self.k2the = self.compute_thetae_2(self.k2th,self.k2rv,self.k2T)+4 # Get to next z level # dZ = zdiff[znext] # dP = self.compute_P_at_z(self.k2P,self.k2T,dZ) # P[znext] = self.k2P + dP # DryBulb[znext] = self.compute_T_with_LCL(P[znext],self.k2P,self.k2T) # DryBulb[znext] = self.compute_T_invert_thetae(self.k2the,P[znext],self.k2rv,self.k2T) # Rv[znext] = self.compute_rv(P[znext],T=DryBulb[znext],RH=self.RH) # Theta-e is conserved, and use T of LCL # Theta[znext] = self.compute_theta(self.k2the,Rv[znext],self.k2T) # Theta[znext] = self.compute_theta_2(P[znext],DryBulb[znext]) # Now iterate up sounding from k2 thru LCL to top of model for zidx in range(k2idx + 1, len(z)): zbot = zidx - 1 dZ = z[zidx] - z[zbot] dP = self.compute_P_at_z(P[zbot], DryBulb[zbot] - (6.5 * dZ * 10**-3), dZ) # dP = self.compute_P_at_z(P[zbot],DryBulb[zbot],dZ) P[zidx] = P[zbot] + dP if zidx < Lidx: Rv[zidx] = Rv[k2idx] # DryBulb[zidx] = self.compute_T_with_LCL(P[zidx],self.k2P,self.k2T) Theta[zidx] = self.compute_theta(self.k2the, Rv[k2idx], TLCL) DryBulb[zidx] = self.compute_drybulb(Theta[zidx], P[zidx]) elif zidx == Lidx: # Using LCL RH = 0.9. Could try 1? DryBulb[zidx] = TLCL Theta[zidx] = self.compute_theta_2(P[zidx], TLCL) Rv[zidx] = self.compute_rv(P[zidx], T=DryBulb[zidx], RH=self.RH) TdLCL = self.compute_Td(DryBulb[zidx], self.RH) # theLCL = self.compute_thetae_4(DryBulb[zidx],P[zidx], # Rv[zidx],TLCL) theLCL = self.compute_thetaep(P[zidx], Rv[zidx], DryBulb[zidx], self.RH) # theLCL = self.compute_thetae_3(Theta[zidx],P[zidx],TdLCL,TLCL,Rv[zidx]) elif zidx > Lidx: T2 = self.compute_T_with_LCL(P[zidx], P[Lidx], TLCL) Th2 = self.compute_theta_2(P[zidx], T2) Rv2 = self.compute_rv(P[zidx], T=T2, RH=self.RH) # Th1 = self.compute_theta(theLCL,Rv[zbot],TLCL) # T1 = self.compute_drybulb(Th1,P[zidx]) # T3 = self.compute_T_invert_thetae(theLCL,P[zidx],Rv[zbot],TLCL) # Th3 = self.compute_theta_2(P[zidx],T3) Theta[zidx] = Th2 DryBulb[zidx] = T2 Rv[zidx] = Rv2 # pdb.set_trace() pdb.set_trace() # Now iterate down from LCL to surface for zidx in range(0, Lidx + 1)[::-1]: ztop = zidx + 1 dZ = z[zidx] - z[ztop] dP = self.compute_P_at_z(P[ztop], DryBulb[ztop] + (6.5 * dZ * 10**-3), dZ) # pdb.set_trace() P[zidx] = P[ztop] + dP # DryBulb[zidx] = self.compute_T_invert_thetae(self.k2the,P[zidx],Rv[zbot],self.k2T) DryBulb[zidx] = self.compute_T_with_LCL(P[zidx], self.k2P, self.k2T) # Rv[zidx] = self.compute_rv(P[zidx],T=DryBulb[zidx],RH=self.RH) Rv[zidx] = Rv[Lidx] Theta[zidx] = self.compute_theta(self.k2the, Rv[zidx], self.k2T) # MIGHT NEED RICHARDSON CONSTRAINT # Create isothermal layer above tropopause isotherm = DryBulb[Tidx] # for zidx in range(Tidx+1,len(z)): # Theta = isothermC * (100000/P)**(mc.R/mc.cp) TRO = slice(Tidx + 1, len(z)) Theta[TRO] = self.compute_theta_2(P[TRO], isotherm) DryBulb[TRO] = self.compute_drybulb(Theta[TRO], P[TRO]) # ttt = Theta/( (100000/P)**(mc.R/mc.cp)) # Enforce 90% again # Rv[zidx] = self.compute_rv(p=P[zidx],T=ttt, RH=self.RH) Rv[TRO] = self.compute_rv(p=P[TRO], T=DryBulb[TRO], RH=self.RH) # Integrate CAPE between LCL and model top after isothermal calc Et = integrate.trapz(b[Lidx:], x=z[Lidx:]) # Multiply buoyancy profile by CAPE ratio B = b * (E / Et) # Calc virtual temp perturbations from buoyancy # Tpert = (B*Theta)/mc.g Tpert = self.compute_thetapert(B, DryBulb, Rv) # Change theta, sfc/LCL to tropopause, to create CAPE==E in sounding THETA = Theta.copy() modify_bLCL = False if not modify_bLCL: # Only change LCL upward THETA[Lidx:Tidx] = Theta[Lidx:Tidx] - Tpert[Lidx:Tidx] else: # Change near surface too THETA[:Tidx] = Theta[:Tidx] - Tpert[:Tidx] # Enforce RH = 90% for new theta values DRYBULB = self.compute_drybulb(THETA, P) SL = slice(Lidx, Tidx) RV = self.compute_rv(P, T=DRYBULB, RH=self.RH) # RV[SL] = self.compute_rv(P[SL],T=DRYBULB[SL],RH=self.RH) # Change PW # Substract ~8C from theta and dewpoint # T in C; RH in 0-100 % # Td = utils.dewpoint(T,RH) # Modified RH # Extra fields for plotting skew-T ES = self.compute_es(DRYBULB) RVs = 0.622 * (ES / (P - ES)) RHs = RV / RVs T_D = self.compute_Td(DRYBULB, RHs) sT.plot_profile(P / 100, DRYBULB - 273.15, T_D - 273.15, self.fdir) # sT.plot_profile(pres,oldtemps,dewpoints,self.fdir,fname='skewT_oldtemps.png') pdb.set_trace() return THETA, RV
def buoyancy(self,): """ Parcel buoyancy profile, or Eq. (A1) in MW01. Returns ------- b : array_like Atmospheric profile of buoyancy. qv : array_like Atmospheric profile of mixing ratio """ z = self.z E = self.E m = self.m zL = self.zL H = self.H zT = self.zT RH = self.RH # z' in Eq (1) dz = z-zL # Index of LCL, k2, and tropopause Lidx = N.where(z==zL)[0][0] k2idx = N.where(z==self.k2z)[0][0] Tidx = N.where(z==zT)[0][0] # Height above LCL of max buoyancy self.Zb = H/m # Buoyancy profile b = ((E*dz*m**2)/(H**2))*N.exp((m/H)*-dz) # Set buoyancy to zero at and above tropopause # troposphere = N.where(z>=zT) # bT = copy.copy(b) # bT[troposphere] = 0 # Generating other arrays P = N.zeros_like(z,dtype=N.dtype('f8')) Theta = N.zeros_like(P) Rv = N.zeros_like(P) DryBulb = N.zeros_like(P) # Stats at k2 P[k2idx] = self.k2P Rv[k2idx] = self.compute_rv(self.k2P,Td=self.k2Td) self.k2RH = self.compute_RH(self.k2Td,self.k2T) Theta[k2idx] = self.compute_theta_2(self.k2P,self.k2T) DryBulb[k2idx] = self.k2T # Temperature at the LCL TLCL = self.compute_TLCL(self.k2Td,self.k2T) # self.k2the = self.compute_thetae_4(DryBulb[k2idx],P[k2idx], # Rv[k2idx],TLCL) self.k2the = self.compute_thetaep(P[k2idx],Rv[k2idx],self.k2T,self.k2RH) # self.k2the = self.compute_thetae_3(Theta[k2idx],self.k2P,self.k2Td, self.k2T,Rv[k2idx],TL=TLCL) # self.k2the = self.compute_thetae(self.k2T,self.k2rv,self.k2P,self.k2Td) # self.k2the = self.compute_thetae_2(self.k2th,self.k2rv,self.k2T)+4 # Get to next z level # dZ = zdiff[znext] # dP = self.compute_P_at_z(self.k2P,self.k2T,dZ) # P[znext] = self.k2P + dP # DryBulb[znext] = self.compute_T_with_LCL(P[znext],self.k2P,self.k2T) # DryBulb[znext] = self.compute_T_invert_thetae(self.k2the,P[znext],self.k2rv,self.k2T) # Rv[znext] = self.compute_rv(P[znext],T=DryBulb[znext],RH=self.RH) # Theta-e is conserved, and use T of LCL # Theta[znext] = self.compute_theta(self.k2the,Rv[znext],self.k2T) # Theta[znext] = self.compute_theta_2(P[znext],DryBulb[znext]) # Now iterate up sounding from k2 thru LCL to top of model for zidx in range(k2idx+1,len(z)): zbot = zidx-1 dZ = z[zidx]-z[zbot] dP = self.compute_P_at_z(P[zbot],DryBulb[zbot]-(6.5*dZ*10**-3),dZ) # dP = self.compute_P_at_z(P[zbot],DryBulb[zbot],dZ) P[zidx] = P[zbot] + dP if zidx < Lidx: Rv[zidx] = Rv[k2idx] # DryBulb[zidx] = self.compute_T_with_LCL(P[zidx],self.k2P,self.k2T) Theta[zidx] = self.compute_theta(self.k2the,Rv[k2idx],TLCL) DryBulb[zidx] = self.compute_drybulb(Theta[zidx],P[zidx]) elif zidx == Lidx: # Using LCL RH = 0.9. Could try 1? DryBulb[zidx] = TLCL Theta[zidx] = self.compute_theta_2(P[zidx],TLCL) Rv[zidx] = self.compute_rv(P[zidx],T=DryBulb[zidx],RH=self.RH) TdLCL = self.compute_Td(DryBulb[zidx],self.RH) # theLCL = self.compute_thetae_4(DryBulb[zidx],P[zidx], # Rv[zidx],TLCL) theLCL = self.compute_thetaep(P[zidx],Rv[zidx],DryBulb[zidx],self.RH) # theLCL = self.compute_thetae_3(Theta[zidx],P[zidx],TdLCL,TLCL,Rv[zidx]) elif zidx > Lidx: T2 = self.compute_T_with_LCL(P[zidx],P[Lidx],TLCL) Th2 = self.compute_theta_2(P[zidx],T2) Rv2 = self.compute_rv(P[zidx],T=T2,RH=self.RH) # Th1 = self.compute_theta(theLCL,Rv[zbot],TLCL) # T1 = self.compute_drybulb(Th1,P[zidx]) # T3 = self.compute_T_invert_thetae(theLCL,P[zidx],Rv[zbot],TLCL) # Th3 = self.compute_theta_2(P[zidx],T3) Theta[zidx] = Th2 DryBulb[zidx] = T2 Rv[zidx] = Rv2 # pdb.set_trace() pdb.set_trace() # Now iterate down from LCL to surface for zidx in range(0,Lidx+1)[::-1]: ztop = zidx+1 dZ = z[zidx]-z[ztop] dP = self.compute_P_at_z(P[ztop],DryBulb[ztop]+(6.5*dZ*10**-3),dZ) # pdb.set_trace() P[zidx] = P[ztop] + dP # DryBulb[zidx] = self.compute_T_invert_thetae(self.k2the,P[zidx],Rv[zbot],self.k2T) DryBulb[zidx] = self.compute_T_with_LCL(P[zidx],self.k2P,self.k2T) # Rv[zidx] = self.compute_rv(P[zidx],T=DryBulb[zidx],RH=self.RH) Rv[zidx] = Rv[Lidx] Theta[zidx] = self.compute_theta(self.k2the,Rv[zidx],self.k2T) # MIGHT NEED RICHARDSON CONSTRAINT # Create isothermal layer above tropopause isotherm = DryBulb[Tidx] # for zidx in range(Tidx+1,len(z)): # Theta = isothermC * (100000/P)**(mc.R/mc.cp) TRO = slice(Tidx+1,len(z)) Theta[TRO] = self.compute_theta_2(P[TRO],isotherm) DryBulb[TRO] = self.compute_drybulb(Theta[TRO],P[TRO]) # ttt = Theta/( (100000/P)**(mc.R/mc.cp)) # Enforce 90% again # Rv[zidx] = self.compute_rv(p=P[zidx],T=ttt, RH=self.RH) Rv[TRO] = self.compute_rv(p=P[TRO],T=DryBulb[TRO], RH=self.RH) # Integrate CAPE between LCL and model top after isothermal calc Et = integrate.trapz(b[Lidx:],x=z[Lidx:]) # Multiply buoyancy profile by CAPE ratio B = b * (E/Et) # Calc virtual temp perturbations from buoyancy # Tpert = (B*Theta)/mc.g Tpert = self.compute_thetapert(B,DryBulb,Rv) # Change theta, sfc/LCL to tropopause, to create CAPE==E in sounding THETA = Theta.copy() modify_bLCL = False if not modify_bLCL: # Only change LCL upward THETA[Lidx:Tidx] = Theta[Lidx:Tidx]-Tpert[Lidx:Tidx] else: # Change near surface too THETA[:Tidx] = Theta[:Tidx]-Tpert[:Tidx] # Enforce RH = 90% for new theta values DRYBULB = self.compute_drybulb(THETA,P) SL = slice(Lidx,Tidx) RV = self.compute_rv(P,T=DRYBULB,RH=self.RH) # RV[SL] = self.compute_rv(P[SL],T=DRYBULB[SL],RH=self.RH) # Change PW # Substract ~8C from theta and dewpoint # T in C; RH in 0-100 % # Td = utils.dewpoint(T,RH) # Modified RH # Extra fields for plotting skew-T ES = self.compute_es(DRYBULB) RVs = 0.622*(ES/(P-ES)) RHs = RV/RVs T_D = self.compute_Td(DRYBULB,RHs) sT.plot_profile(P/100,DRYBULB-273.15,T_D-273.15,self.fdir) # sT.plot_profile(pres,oldtemps,dewpoints,self.fdir,fname='skewT_oldtemps.png') pdb.set_trace() return THETA, RV