Skip to content
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

Moist thermal sw #390

Closed
wants to merge 50 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
ce80f06
start of reversible physics class
nhartney Feb 15, 2023
2120701
ReversibleAdjustment working just for the constant in time saturation…
nhartney Feb 17, 2023
d961cea
moist Williamson 2 with reversible condensation/evaporation process
nhartney Feb 17, 2023
a03580d
adding other saturation field option and trying to figure out why clo…
nhartney Feb 20, 2023
b635125
include factor of 1/tau in reversible process
nhartney Feb 20, 2023
3b55169
trying forced advection equation instead of shallow water equations
nhartney Mar 6, 2023
e061de8
started again, building up from no tracer - this has negative moist t…
nhartney Mar 6, 2023
4aa9e13
following the example of SaturationAdjustment physics class to stop n…
nhartney Mar 6, 2023
8ce3726
Merge branch 'main' into reversible_moist_physics
nhartney Mar 6, 2023
312c5bb
Merge branch 'main' into reversible_moist_physics
nhartney Mar 6, 2023
11e0db6
condense/evaporate all available species rather than a fraction of th…
nhartney Mar 7, 2023
aa46c2b
add tracer transport to ForcedAdvectionEquation class
nhartney Mar 7, 2023
5bf9445
trying to add diagnostics and total moisture (not working)
nhartney Mar 9, 2023
bd5515b
use compatible spaces and set up total moisture as a diagnostic
nhartney Mar 9, 2023
c216cb7
total moisture is now tracked using the Sum diagnostic field
nhartney Mar 9, 2023
56240e8
fix lint
nhartney Mar 9, 2023
5f7a526
Merge branch 'main' into reversible_moist_physics
nhartney May 17, 2023
8eac25a
Incorporating changes from the saturation curve fix into the Reversib…
nhartney May 17, 2023
9d2a786
updating moist Williamson1 example after changes to the ReversiblePhy…
nhartney May 17, 2023
d94caac
Adding the option for feedback to the buoyancy equation from moisture…
nhartney May 18, 2023
48f3f74
moist thermal Williamson 2 test from Zerroukat and Allen
nhartney May 18, 2023
6e97223
Replace gamma with beta1 for clarity
nhartney May 18, 2023
c97965b
Make the thermal feedback proportionality time-varying so that only a…
nhartney May 24, 2023
52d7c78
Proportionality of thermal feedback can be time-varying, to avoid osc…
nhartney May 24, 2023
f56f1e1
Start with non-negative theta
nhartney May 24, 2023
4fee8cd
allow for fractions of moist species to be converted (avoids two-time…
nhartney May 25, 2023
ba875c5
convert a fraction of the moist species
nhartney May 25, 2023
0c4b4d2
sign change in the theta initial condiiton
nhartney Jun 2, 2023
75cf541
change sign in theta initial condition
nhartney Jun 2, 2023
d285557
moist thermal Williamson 5 as in ZA
nhartney Jun 5, 2023
8e89709
checking initial theta condition to see why the intial vapour is so d…
nhartney Jun 5, 2023
bdf4e76
including factor of g in expressions involving topography, and writin…
nhartney Jun 13, 2023
6138bec
try xi=0 to see if we get the correct cloud, change q0 to give max v …
nhartney Jun 16, 2023
5b13c04
Add factors to list for convective feedback and thermal feedback, L i…
nhartney Jun 16, 2023
c73e348
Add L, correct beta2, try bigger q0, change bracket in initial condit…
nhartney Jun 16, 2023
5b059f3
add steady state error output for vapour and cloud for doing converge…
nhartney Jun 24, 2023
c3e79fb
Williamson 2 in moist convective thermal shallow water model
nhartney Jun 24, 2023
c88daa2
rename ReversibleAdjustment to SW_SaturationAdjustment
nhartney Jul 24, 2023
6489006
L is None unless thermal feedback is specified
nhartney Jul 25, 2023
eff5855
start of test for SWSaturationAdjustment
nhartney Jul 26, 2023
73b6548
getting SWSaturationAdjustment test working with lots of print statem…
nhartney Jul 27, 2023
db42049
remove print statements and lint fixes
nhartney Jul 27, 2023
60499a2
remove unnecessary examples
nhartney Jul 27, 2023
0922840
rename SWSaturationAdjustment class
nhartney Jul 27, 2023
61b6baf
working towards the SWSaturationAdjustment test
nhartney Jul 27, 2023
5b287d0
finish SWSaturationAdjustment test
nhartney Jul 27, 2023
dddee7e
moist thermal Williamson 5 example
nhartney Jul 28, 2023
db7dd7b
replace L with L_v
nhartney Jul 28, 2023
ac7f2d6
remame both saturation adjustment tests
nhartney Jul 28, 2023
bb02241
Merge branch 'main' into moist_thermal_sw
tommbendall Jul 28, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 145 additions & 0 deletions examples/shallow_water/moist_thermal_williamson5.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
"""
Moist flow over a mountain test case from Zerroukat and Allen (2015). Similar
to the Williamson et al test 5 but with additional thermodynamic equations.
"""
from gusto import *
from firedrake import (IcosahedralSphereMesh, SpatialCoordinate,
as_vector, pi, sqrt, min_value, exp, cos)
import sys

# ----------------------------------------------------------------- #
# Test case parameters
# ----------------------------------------------------------------- #

dt = 300
R = 6371220.
H = 5960.
u_max = 20.
# moist shallow water parameters
epsilon = 1/300
SP = -40*epsilon
EQ = 30*epsilon
NP = -20*epsilon
mu1 = 0.05
mu2 = 0.98
L_v = 10
q0 = 135 # chosen to give an initial max vapour of approx 0.02
beta2 = 1
qprecip = 10e-4
gamma_r = 10e-3
# topography parameters
R0 = pi/9.
R0sq = R0**2
lamda_c = -pi/2.
phi_c = pi/6.

if '--running-tests' in sys.argv:
tmax = dt
dumpfreq = 1
else:
day = 24*60*60
tmax = 50*day
ndumps = 50
dumpfreq = int(tmax / (ndumps*dt))

# ----------------------------------------------------------------- #
# Set up model objects
# ----------------------------------------------------------------- #

# Domain
mesh = IcosahedralSphereMesh(radius=R,
refinement_level=4, degree=1)
degree = 1
domain = Domain(mesh, dt, "BDM", degree)
x = SpatialCoordinate(mesh)

# Equation
parameters = ShallowWaterParameters(H=H)
Omega = parameters.Omega
fexpr = 2*Omega*x[2]/R

# Topography
phi, lamda = latlon_coords(mesh)
lsq = (lamda - lamda_c)**2
thsq = (phi - phi_c)**2
rsq = min_value(R0sq, lsq+thsq)
r = sqrt(rsq)
tpexpr = 2000 * (1 - r/R0)

tracers = [WaterVapour(space='DG'), CloudWater(space='DG'), Rain(space='DG')]
eqns = ShallowWaterEquations(domain, parameters, fexpr=fexpr, bexpr=tpexpr,
thermal=True,
active_tracers=tracers)

# I/O
dirname = "moist_thermal_williamson5"
output = OutputParameters(dirname=dirname,
dumplist_latlon=['D'],
dumpfreq=dumpfreq,
log_level='INFO')
diagnostic_fields = [Sum('D', 'topography'), CourantNumber()]
io = IO(domain, output, diagnostic_fields=diagnostic_fields)


# Saturation function
def sat_func(x_in):
h = x_in.split()[1]
b = x_in.split()[2]
return (q0/(g*h + g*tpexpr)) * exp(20*(1 - b/g))


# Feedback proportionality is dependent on h and b
def gamma_v(x_in):
h = x_in.split()[1]
b = x_in.split()[2]
return (1 + L_v*(20*q0/(g*h + g*tpexpr) * exp(20*(1 - b/g))))**(-1)


SWSaturationAdjustment(eqns, sat_func, L_v, time_varying_saturation=True,
parameters=parameters, thermal_feedback=True,
beta2=beta2, gamma_v=gamma_v,
time_varying_gamma_v=True)

InstantRain(eqns, qprecip, vapour_name="cloud_water", rain_name="rain",
gamma_r=gamma_r)

# Timestepper
stepper = Timestepper(eqns, RK4(domain), io)

# ----------------------------------------------------------------- #
# Initial conditions
# ----------------------------------------------------------------- #

u0 = stepper.fields("u")
D0 = stepper.fields("D")
b0 = stepper.fields("b")
v0 = stepper.fields("water_vapour")
c0 = stepper.fields("cloud_water")
r0 = stepper.fields("rain")

uexpr = as_vector([-u_max*x[1]/R, u_max*x[0]/R, 0.0])

g = parameters.g
Rsq = R**2
Dexpr = H - ((R * Omega * u_max + 0.5*u_max**2)*x[2]**2/Rsq)/g - tpexpr

# Expression for initial buoyancy - note the bracket around 1-mu
F = (2/(pi**2))*(phi*(phi-pi/2)*SP - 2*(phi+pi/2)*(phi-pi/2)*(1-mu1)*EQ + phi*(phi+pi/2)*NP)
theta_expr = F + mu1*EQ*cos(phi)*sin(lamda)
bexpr = g * (1 - theta_expr)

# Expression for initial vapour depends on initial saturation
initial_msat = q0/(g*D0 + g*tpexpr) * exp(20*theta_expr)
vexpr = mu2 * initial_msat

# Initialise (cloud and rain initially zero)
u0.project(uexpr)
D0.interpolate(Dexpr)
b0.interpolate(bexpr)
v0.interpolate(vexpr)

# ----------------------------------------------------------------- #
# Run
# ----------------------------------------------------------------- #

stepper.run(t=0, tmax=tmax)
7 changes: 4 additions & 3 deletions examples/shallow_water/thermal_williamson2.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@
ShallowWaterKineticEnergy(),
ShallowWaterPotentialEnergy(params),
ShallowWaterPotentialEnstrophy(),
SteadyStateError('u'), SteadyStateError('D')]
SteadyStateError('u'), SteadyStateError('D'),
MeridionalComponent('u'), ZonalComponent('u')]
io = IO(domain, output, diagnostic_fields=diagnostic_fields)
transport_methods = [DGUpwind(eqns, "u"),
DGUpwind(eqns, "D"),
Expand All @@ -74,11 +75,11 @@
uexpr = sphere_to_cartesian(mesh, u_max*cos(phi), 0)
g = params.g
w = Omega*R*u_max + (u_max**2)/2
sigma = 0
sigma = w/10

Dexpr = H - (1/g)*(w + sigma)*((sin(phi))**2)

numerator = theta_0 - sigma*((cos(phi))**2) * ((w + sigma)*(cos(phi))**2 + 2*(phi_0 - w - sigma))
numerator = theta_0 + sigma*((cos(phi))**2) * ((w + sigma)*(cos(phi))**2 + 2*(phi_0 - w - sigma))

denominator = phi_0**2 + (w + sigma)**2*(sin(phi))**4 - 2*phi_0*(w + sigma)*(sin(phi))**2

Expand Down
Loading
Loading