This repository has been archived by the owner on Mar 1, 2023. It is now read-only.
/
bc_moisture.jl
118 lines (107 loc) · 2.86 KB
/
bc_moisture.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
abstract type MoistureBC end
"""
Impermeable() :: MoistureBC
No moisture flux.
"""
struct Impermeable <: MoistureBC end
function atmos_moisture_boundary_state!(
nf,
bc_moisture::Impermeable,
atmos,
args...,
) end
function atmos_moisture_normal_boundary_flux_second_order!(
nf,
bc_moisture::Impermeable,
atmos,
args...,
) end
"""
PrescribedMoistureFlux(fn) :: MoistureBC
Prescribe the net inward moisture flux across the boundary by `fn`, a function
with signature `fn(state, aux, t)`, returning the flux (in kg/m^2).
"""
struct PrescribedMoistureFlux{FN} <: MoistureBC
fn::FN
end
function atmos_moisture_boundary_state!(
nf,
bc_moisture::PrescribedMoistureFlux,
atmos,
args...,
) end
function atmos_moisture_normal_boundary_flux_second_order!(
nf,
bc_moisture::PrescribedMoistureFlux,
atmos,
fluxᵀn,
n⁻,
state⁻,
diffusive⁻,
hyperdiffusive⁻,
aux⁻,
state⁺,
diffusive⁺,
hyperdiffusive⁺,
aux⁺,
bctype,
t,
args...,
)
nρd_q_tot = -bc_moisture.fn(state⁻, aux⁻, t)
fluxᵀn.ρ += nρd_q_tot
fluxᵀn.ρu += nρd_q_tot / state⁻.ρ .* state⁻.ρu
# assumes EquilMoist
fluxᵀn.moisture.ρq_tot += nρd_q_tot
end
"""
BulkFormulaMoisture(fn) :: MoistureBC
Calculate the net inward moisture flux across the boundary using
the bulk formula. The drag coefficient is `C_q = fn_C_q(state, aux,
t, normu_int_tan)`. The surface q_tot at the boundary is `q_tot =
fn_q_tot(state, aux, t)`.
Return the flux (in kg m^-2 s^-1).
"""
struct BulkFormulaMoisture{FNX, FNM} <: MoistureBC
fn_C_q::FNX
fn_q_tot::FNM
end
function atmos_moisture_boundary_state!(
nf,
bc_moisture::BulkFormulaMoisture,
atmos,
args...,
) end
function atmos_moisture_normal_boundary_flux_second_order!(
nf,
bc_moisture::BulkFormulaMoisture,
atmos,
fluxᵀn,
n⁻,
state⁻,
diffusive⁻,
hyperdiffusive⁻,
aux⁻,
state⁺,
diffusive⁺,
hyperdiffusive⁺,
aux⁺,
bctype,
t,
state_int⁻,
diffusive_int⁻,
aux_int⁻,
)
u_int⁻ = state_int⁻.ρu / state_int⁻.ρ
u_int⁻_tan = projection_tangential(atmos, aux_int⁻, u_int⁻)
normu_int⁻_tan = norm(u_int⁻_tan)
C_q = bc_moisture.fn_C_q(state⁻, aux⁻, t, normu_int⁻_tan)
q_tot = bc_moisture.fn_q_tot(state⁻, aux⁻, t)
q_tot_int = state_int⁻.moisture.ρq_tot / state_int⁻.ρ
# TODO: use the correct density at the surface
ρ_avg = average_density(state⁻.ρ, state_int⁻.ρ)
# NOTE: difference from design docs since normal points outwards
fluxᵀn.moisture.ρq_tot -= C_q * ρ_avg * normu_int⁻_tan * (q_tot - q_tot_int)
fluxᵀn.ρ -= C_q * ρ_avg * normu_int⁻_tan * (q_tot - q_tot_int)
fluxᵀn.ρu -= C_q * normu_int⁻_tan * (q_tot - q_tot_int) .* state_int⁻.ρu
end