-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Nonequilibrium in the parcel model #508
Merged
+246
−2
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
cc67902
adding nonequilibrium to the parcel
1be58a9
cleaning up unused code
b5e586b
Adding nonequilibrium parcel example with both liquid and ice
edfad12
debugging to get parcel to run with updated noneq script
ab7754d
getting rid of old non used arguments
05445ac
adding limiter
cfcfe0f
fixing initial conditions
f25a635
formatting
beb3733
Merge branch 'main' into oa/noneq_parcel_clean
736ae7d
changing Anna to simple
456b942
changing limiter
2600ff0
adding noneq figure and documentation
3f47d00
figure cleanup and main edits
2b963cf
Add r_eff overwirte based on ClimaParams
trontrytel 1df64ac
Small changes to liquid and ice structs
d46cf0a
cleaning
a0773ca
formatting
9e93473
Merge branch 'main' into oa/noneq_parcel_clean
oalcabes File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
import OrdinaryDiffEq as ODE | ||
import CairoMakie as MK | ||
import Thermodynamics as TD | ||
import CloudMicrophysics as CM | ||
import CloudMicrophysics.CloudDiagnostics as CD | ||
import CloudMicrophysics.Parameters as CMP | ||
import ClimaParams as CP | ||
|
||
FT = Float64 | ||
|
||
include(joinpath(pkgdir(CM), "parcel", "Parcel.jl")) | ||
|
||
|
||
# choosing a value for the ice relaxation timescale | ||
τ = FT(10) | ||
@info("using τ value ", τ) | ||
|
||
# Get free parameters | ||
tps = TD.Parameters.ThermodynamicsParameters(FT) | ||
wps = CMP.WaterProperties(FT) | ||
# Constants | ||
ρₗ = wps.ρw | ||
ρᵢ = wps.ρi | ||
R_v = TD.Parameters.R_v(tps) | ||
R_d = TD.Parameters.R_d(tps) | ||
|
||
# Initial conditions | ||
Nₐ = FT(0) | ||
Nₗ = FT(200 * 1e6) | ||
Nᵢ = FT(1e6) | ||
r₀ = FT(8e-6) | ||
p₀ = FT(800 * 1e2) | ||
T₀ = FT(243) | ||
ln_INPC = FT(0) | ||
e_sat = TD.saturation_vapor_pressure(tps, T₀, TD.Liquid()) | ||
Sₗ = FT(1) | ||
e = Sₗ * e_sat | ||
md_v = (p₀ - e) / R_d / T₀ | ||
mv_v = e / R_v / T₀ | ||
ml_v = Nₗ * 4 / 3 * FT(π) * ρₗ * r₀^3 | ||
mi_v = Nᵢ * 4 / 3 * FT(π) * ρᵢ * r₀^3 | ||
qᵥ = mv_v / (md_v + mv_v + ml_v + mi_v) | ||
qₗ = ml_v / (md_v + mv_v + ml_v + mi_v) | ||
qᵢ = mi_v / (md_v + mv_v + ml_v + mi_v) | ||
|
||
override_file = Dict( | ||
"condensation_evaporation_timescale" => | ||
Dict("value" => τ, "type" => "float"), | ||
) | ||
|
||
liquid_toml_dict = CP.create_toml_dict(FT; override_file) | ||
liquid = CMP.CloudLiquid(liquid_toml_dict) | ||
|
||
override_file = Dict( | ||
"sublimation_deposition_timescale" => | ||
Dict("value" => τ, "type" => "float"), | ||
) | ||
|
||
ice_toml_dict = CP.create_toml_dict(FT; override_file) | ||
|
||
ice = CMP.CloudIce(ice_toml_dict) | ||
@info("relaxations:", liquid.τ_relax, ice.τ_relax) | ||
|
||
IC = [Sₗ, p₀, T₀, qᵥ, qₗ, qᵢ, Nₐ, Nₗ, Nᵢ, ln_INPC] | ||
simple = false | ||
|
||
# Simulation parameters passed into ODE solver | ||
w = FT(1) # updraft speed | ||
const_dt = FT(0.001) # model timestep | ||
t_max = FT(20)#FT(const_dt*1) | ||
size_distribution_list = ["Monodisperse"] | ||
|
||
condensation_growth = "NonEq_Condensation" | ||
deposition_growth = "NonEq_Deposition" | ||
|
||
# Setup the plots | ||
fig = MK.Figure(size = (800, 600)) | ||
ax1 = MK.Axis(fig[1, 1], ylabel = "Liquid Supersaturation [%]") | ||
ax2 = MK.Axis(fig[2, 1], ylabel = "Temperature [K]") | ||
ax3 = MK.Axis(fig[3, 1], xlabel = "Time [s]", ylabel = "q_liq [g/kg]") | ||
ax4 = MK.Axis(fig[1, 2], ylabel = "Ice Supersaturation [%]") | ||
ax5 = MK.Axis(fig[2, 2], ylabel = "q_vap [g/kg]") | ||
ax6 = MK.Axis(fig[3, 2], xlabel = "Time [s]", ylabel = "q_ice [g/kg]") | ||
|
||
for DSD in size_distribution_list | ||
local params = parcel_params{FT}( | ||
liq_size_distribution = DSD, | ||
condensation_growth = condensation_growth, | ||
deposition_growth = deposition_growth, | ||
const_dt = const_dt, | ||
w = w, | ||
liquid = liquid, | ||
ice = ice, | ||
) | ||
|
||
# solve ODE | ||
local sol = run_parcel(IC, FT(0), t_max, params) | ||
|
||
# Plot results | ||
MK.lines!(ax1, sol.t, (sol[1, :] .- 1) * 100.0) | ||
MK.lines!(ax2, sol.t, sol[3, :]) | ||
MK.lines!(ax3, sol.t, sol[5, :] * 1e3) | ||
MK.lines!(ax4, sol.t, (S_i.(tps, sol[3, :], sol[1, :]) .- 1) * 100.0) | ||
MK.lines!(ax5, sol.t, sol[4, :] * 1e3) | ||
MK.lines!(ax6, sol.t, sol[6, :] * 1e3) | ||
|
||
|
||
sol_Nₗ = sol[8, :] | ||
sol_Nᵢ = sol[9, :] | ||
sol_T = sol[3, :] | ||
sol_p = sol[2, :] | ||
sol_qᵥ = sol[4, :] | ||
sol_qₗ = sol[5, :] | ||
sol_qᵢ = sol[6, :] | ||
|
||
q = TD.PhasePartition.(sol_qᵥ + sol_qₗ + sol_qᵢ, sol_qₗ, sol_qᵢ) | ||
|
||
local q = TD.PhasePartition.(sol_qᵥ + sol_qₗ + sol_qᵢ, sol_qₗ, sol_qᵢ) | ||
local ts = TD.PhaseNonEquil_pTq.(tps, sol_p, sol_T, q) | ||
local ρₐ = TD.air_density.(tps, ts) | ||
|
||
end | ||
|
||
MK.save("noneq_parcel.svg", fig) | ||
nothing |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,10 +2,16 @@ import Thermodynamics as TD | |
import CloudMicrophysics.Common as CMO | ||
import CloudMicrophysics.HetIceNucleation as CMI_het | ||
import CloudMicrophysics.HomIceNucleation as CMI_hom | ||
import CloudMicrophysics.MicrophysicsNonEq as MNE | ||
import CloudMicrophysics.Parameters as CMP | ||
import Distributions as DS | ||
import SpecialFunctions as SF | ||
|
||
# helper function to limit the tendency for noneq | ||
function limit(q, dt, n::Int) | ||
return q / dt / n | ||
end | ||
|
||
function aerosol_activation(::Empty, state) | ||
FT = eltype(state) | ||
return FT(0) | ||
|
@@ -223,6 +229,40 @@ function condensation(params::CondParams, PSD_liq, state, ρ_air) | |
return qₗ + dqₗ_dt * const_dt > 0 ? dqₗ_dt : -qₗ / const_dt | ||
end | ||
|
||
function condensation(params::NonEqCondParams_simple, PSD, state, ρ_air) | ||
|
||
FT = eltype(state) | ||
(; Sₗ, T, qₗ, qᵥ, qᵢ) = state | ||
(; tps, liquid) = params | ||
|
||
q_sat_liq = max(Sₗ * qᵥ - qᵥ, 0) | ||
q_sat = TD.PhasePartition(FT(0), q_sat_liq, FT(0)) | ||
|
||
q = TD.PhasePartition(qᵥ + qₗ + qᵢ, qₗ, qᵢ) | ||
|
||
new_q = MNE.conv_q_vap_to_q_liq_ice(liquid, q_sat, q) | ||
|
||
return new_q | ||
end | ||
|
||
function condensation(params::NonEqCondParams, PSD, state, ρ_air) | ||
FT = eltype(state) | ||
(; T, qₗ, qᵥ, qᵢ) = state | ||
|
||
(; tps, liquid, dt) = params | ||
|
||
q = TD.PhasePartition(qᵥ + qₗ + qᵢ, qₗ, qᵢ) | ||
|
||
cond_rate = MNE.conv_q_vap_to_q_liq_ice_MM2015(liquid, tps, q, ρ_air, T) | ||
|
||
# using same limiter as ClimaAtmos for now | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would be good to do some testing and see if we need the limiter. Maybe we don't? Or if we do, maybe we can limit just by dt? |
||
return ifelse( | ||
cond_rate > FT(0), | ||
min(cond_rate, limit(qᵥ, dt, 1)), | ||
-min(abs(cond_rate), limit(qₗ, dt, 1)), | ||
) | ||
end | ||
|
||
function deposition(::Empty, PSD_ice, state, ρ_air) | ||
FT = eltype(state) | ||
return FT(0) | ||
|
@@ -236,3 +276,39 @@ function deposition(params::DepParams, PSD_ice, state, ρ_air) | |
Gᵢ = CMO.G_func(aps, tps, T, TD.Ice()) | ||
return 4 * FT(π) / ρ_air * (Sᵢ - 1) * Gᵢ * PSD_ice.r * Nᵢ | ||
end | ||
|
||
function deposition(params::NonEqDepParams_simple, PSD, state, ρ_air) | ||
FT = eltype(state) | ||
(; T, Sₗ, qₗ, qᵥ, qᵢ) = state | ||
|
||
(; tps, ice) = params | ||
|
||
Sᵢ = S_i(tps, T, Sₗ) | ||
q_sat_ice = max(Sᵢ * qᵥ - qᵥ, 0) | ||
|
||
q_sat = TD.PhasePartition(FT(0), FT(0), q_sat_ice) | ||
|
||
q = TD.PhasePartition(qᵥ + qₗ + qᵢ, qₗ, qᵢ) | ||
|
||
new_q = MNE.conv_q_vap_to_q_liq_ice(ice, q_sat, q) | ||
|
||
return new_q | ||
end | ||
|
||
function deposition(params::NonEqDepParams, PSD, state, ρ_air) | ||
FT = eltype(state) | ||
(; T, qₗ, qᵥ, qᵢ) = state | ||
|
||
(; tps, ice, dt) = params | ||
|
||
q = TD.PhasePartition(qᵥ + qₗ + qᵢ, qₗ, qᵢ) | ||
|
||
dep_rate = MNE.conv_q_vap_to_q_liq_ice_MM2015(ice, tps, q, ρ_air, T) | ||
|
||
# using same limiter as ClimaAtmos for now | ||
return ifelse( | ||
dep_rate > FT(0), | ||
min(dep_rate, limit(qᵥ, dt, 1)), | ||
-min(abs(dep_rate), limit(qᵢ, dt, 1)), | ||
) | ||
end |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be neat to compare all two (or three depending on if you kick out the simple one) together. And it would be even neater to add a couple of words and the resulting plot to our docs, along with other parcel examples. This way at least your example will be run when we are building the docs during PRs.