Unidata / MetPy

MetPy is a collection of tools in Python for reading, visualizing and performing calculations with weather data.
https://unidata.github.io/MetPy/
BSD 3-Clause "New" or "Revised" License
1.25k stars 414 forks source link

Add parcel path options #461

Open jrleeman opened 7 years ago

jrleeman commented 7 years ago

In trying to implement a robust CAPE/CIN calculation, we've discovered that the complication really should lie in the parcel path calculation. Currently the parcel path calculation function call looks like this:

def parcel_profile(pressure, temperature, dewpt)

Only the starting temperature and dew point are needed and the pressures at which the path is wanted. Ideally we need to implement the following options:

Virtual Temperature

Moist Adiabats

The virtual temperature should be implemented now. A hook for adiabats can be put in, but only have the option of pseudoadiabats for now.

Here's a simple sketch of what a path assumptions object could look like:

class parcelPathAssumptions(object):
    """
    Holds assumptions made about the parcel path during calculations.
    """
    __slots__ = ('use_virtual_temperature')
    def __init__(self):
        self.use_virtual_temperature = True
        self.moist_adiabat = 'pseudoadiabatic'

The function would then use the default options from __init__.

def parcel_profile(pressure, temperature, dewpt, assumptions=parcelPathAssumptions()):

The biggest complication I see here is that for the virtual temperature correction (assuming I understand it correctly) we'll be needing the full dew point profile from the sounding. Then parcel_profile could be modified something like:

# Do virtual temperature correction
    if assumptions.use_virtual_temperature:
        Rv = mpcalc.mixing_ratio(mpcalc.saturation_vapor_pressure(dewpt_prof), pressure)
        t1 = mpcalc.virtual_temperature(t1, Rv)

        Rv = mpcalc.mixing_ratio(mpcalc.saturation_vapor_pressure(t2), pressure)
        t2 =  mpcalc.virtual_temperature(t2, Rv)

Discussion on how to tweak the API on this would be useful. I don't like the idea of dewpt_prof being a kwarg really, but it doesn't belong in the assumptions object either.

sgdecker commented 6 years ago

Constructing the parcel profile with the virtual temperature correction does not require the full dew point profile. (Only computing the virtual temperature of the environment requires the full profile.) For the parcel profile, you can determine the dewpoint, and hence the virtual temperature, from: a) The starting mixing ratio (if below the LCL) b) The saturation mixing ratio (if above the LCL)

dopplershift commented 6 years ago

Isn't really that the starting mixing ratio in both cases? Just that in the second case it starts as saturated.

sgdecker commented 6 years ago

Well, as the parcel ascends above the LCL the saturation mixing ratio will decrease as water condenses out, but I figure you know that so I might be missing something.

To put it another way, in that example code above, the line Rv = mpcalc.mixing_ratio(mpcalc.saturation_vapor_pressure(dewpt_prof), pressure) could be modified to set Rv to the starting mixing ratio for points below the LCL, and to mpcalc.mixing_ratio(mpcalc.saturation_vapor_pressure(t1), pressure) at or above the LCL, since the temperature and dewpoint of the parcel are the same at that point.

dopplershift commented 6 years ago

You're not missing anything, I was thinking too much as a software engineer and not enough as a meteorologist.

dopplershift commented 1 year ago

Re-opening since we haven't added options, we only just forced the use of virtual temperature within cape_cin.

wx4stg commented 1 year ago

I've started playing with this a little bit as I'm highly interested in getting it implemented. I forked metpy yesterday to add a "return_virt" kwarg for the parcel profile functions. I was about to PR that when I came across this issue with the class idea which I agree is better and if I end up PR'ing I'll use that...

Constructing the parcel profile with the virtual temperature correction does not require the full dew point profile. (Only computing the virtual temperature of the environment requires the full profile.) For the parcel profile, you can determine the dewpoint, and hence the virtual temperature, from: a) The starting mixing ratio (if below the LCL) b) The saturation mixing ratio (if above the LCL)

I ended up doing basically this for my implementation:

https://github.com/wx4stg/MetPy/blob/6e5f1aa11316986b064e053d66f4290a6210056a/src/metpy/calc/thermo.py#L1234-L1238

However I ran into something that bothers me a little bit. Below I have attached an observed profile with the parcel paths plotted using return_virt=False and return_virt=True. the moist lapse component of the virtual temperature trace is not parallel to the moist adiabatic lapse rate lines. Not sure what to think about that.

soundingwithprofiles

LL_zoom

wx4stg commented 1 year ago

code and data used to generate those figures:

virt_example.py.txt KCLL_1835Z_20221104_RAOB_SHARPPY.txt

sgdecker commented 1 year ago

This is to be expected @wx4stg . The moist adiabatic lapse rate represents a temperature change, not a virtual temperature change. As the parcel ascends, it loses water vapor, so the virtual temperature converges to the actual temperature eventually.

wx4stg commented 1 year ago

gotcha. It's been a while since I took thermodynamics and I couldn't remember if that was factored in to the moist adiabatic lapse rate or not. thanks for clarifying @sgdecker