Moist Brunt-Vaisala frequency #2878
Replies: 2 comments 10 replies
-
We would be interested in serving a calculation such as the moist Brunt-Vaisala frequency and would welcome working with you to develop the appropriate code to go along with that. First it would help to know which version of the equation you wish to implement. A quick search yielded a paper by Durran and Klemp (1982; https://doi.org/10.1175/1520-0469(1982)039%3C2152:OTEOMO%3E2.0.CO;2) and they appear to support their equation 5. Once we know which equation we want to implement, then we can open an issue and help you begin the process of using various MetPy functions and other pieces to bring it all together. In a quick inspection of the equation, it appears that this will have to be a function that works for only 1D data due to a dependence on the moist adiabatic lapse rate. So as long as you are not want to calculate this on a gridded field, you should be able to pull all of the pieces together. |
Beta Was this translation helpful? Give feedback.
-
Okay, so I think there are some things going on with multiplying values (e.g., constants) against a DataArray that was cause some unit issues. I have a full working example with GFS data... from datetime import datetime
import metpy.constants as mpconst
import xarray as xr
def compute_N_m_squared(P, T, RH, GEOPOT):
import metpy.calc as mpcalc
import metpy.constants as mpconst
from metpy.units import units
# Computes N_m_squared from the ERA5 reanalysis dataset
Lv = mpconst.Lv
R = mpconst.Rd
eps = mpconst.epsilon
cp = mpconst.Cp_d
g = mpconst.g
# Compute actual height from geopotential
height = mpcalc.geopotential_to_height(GEOPOT)
qs = mpcalc.saturation_mixing_ratio(total_press=P.data[:, None, None] * units(P.units), temperature=T)
qw = mpcalc.mixing_ratio_from_relative_humidity(pressure = P.data[:, None, None] * units(P.units),
temperature = T, relative_humidity=RH)
theta = mpcalc.potential_temperature(P.data[:, None, None] * units(P.units), T)
# Term one
numerator = 1 + ( (Lv * qs) / (R * T) )
denominator = 1 + ( (eps * (Lv ** 2) * qs) / (cp * R * (T ** 2)) )
term_1 = numerator / denominator
# Term two
# Term 2_a
term_2_a = mpcalc.first_derivative(theta, x = height) / theta
# Term 2_b_1
term_2_b1 = Lv / (cp * T)
# Term 2_b_2
term_2_b2 = mpcalc.first_derivative(qs, x = height)
term_2 = term_2_a + (term_2_b1 * term_2_b2)
# Term 3
term_3 = mpcalc.first_derivative(qw, x = height)
N_m_squared = g * (term_1 * term_2 - term_3 )
return N_m_squared
date = datetime(2023, 1, 15, 12)
# Get GFS data for contouring
ds = xr.open_dataset('https://thredds.ucar.edu/thredds/dodsC/grib/NCEP/GFS/'
f'Global_onedeg_ana/GFS_Global_onedeg_ana_{date:%Y%m%d_%H%M}.grib2')
# Subset data to be just over the CONUS
ds = ds.metpy.sel(time=date)
# Temperature, RH, and Geopotential Height as Unit Arrays
temperature = ds.Temperature_isobaric.metpy.quantify()
relative_humidity = ds.Relative_humidity_isobaric.metpy.quantify()
geopotential = ds.Geopotential_height_isobaric.metpy.quantify() * mpconst.g
# Pressure as a DataArray
pressure = ds.Temperature_isobaric.metpy.vertical
compute_N_m_squared(pressure, temperature, relative_humidity, geopotential)*1e4 Try to modify with ERA5 variable names and/or see if this gives sensible values from the GFS output. |
Beta Was this translation helpful? Give feedback.
-
There is an excellent function to calculate the Brunt-Vaisala frequency in Metpy:
https://unidata.github.io/MetPy/latest/api/generated/metpy.calc.brunt_vaisala_frequency.html
I've been searching for code to compute the moist Brunt-Vaisala frequency (a challenging calculation), and I haven't been able to find anything. Will this calculation be implemented in future versions of Metpy. Any recommendations for making this calculation myself?
Beta Was this translation helpful? Give feedback.
All reactions