-
Notifications
You must be signed in to change notification settings - Fork 0
/
WRF.jl
162 lines (114 loc) · 3.83 KB
/
WRF.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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
module WRF
#
# Module for reading in WRF outputs and re-packaging selected variables
# for use with the moisture simulation/data assimilation code.
#
#
using Calendar
import Calendar.CalendarTime
using NetCDF
type WRFData
# source file path
file_path :: String
# the variable fields
fields :: Dict{String,Array{Float64}}
# the times of recording history
tm :: Array{CalendarTime}
end
WRFData(file_path) = WRFData(file_path, Dict{String,Array{Float64}}(), Array(CalendarTime,0))
function load_wrf_data(file_path::String, var_list::Array{ASCIIString})
w = WRFData(file_path)
nc = NetCDF.open(file_path)
vl = Array(ASCIIString, 0)
def_var_list = ["T2", "Q2", "PSFC", "RAINC", "RAINNC"]
if var_list != nothing
append!(vl, var_list)
end
append!(vl, def_var_list)
for v in vl
fld = NetCDF.readvar(nc, v, [1, 1, 1], [-1, -1, -1])
w.fields[v] = fld
end
tm = NetCDF.readvar(nc, "Times", [1, 1], [-1, -1])'
for i in 1:size(tm,1)
push!(w.tm, Calendar.parse("yyyy-MM-dd_HH:mm:ss", ascii(squeeze(tm[i,:], 1)), "GMT"))
end
# read in grid dimensions
w.fields["lon"] = squeeze(NetCDF.readvar(nc, "XLONG", [1, 1, 1], [-1, -1, -1])[:,:,1], 3)
w.fields["lat"] = squeeze(NetCDF.readvar(nc, "XLAT", [1, 1, 1], [-1, -1, -1])[:,:,1], 3)
# compute derived variables
compute_rainfall_per_hour(w)
compute_equilibrium_moisture(w)
NetCDF.close(nc)
return w
end
function lat(w::WRFData)
return w.fields["lat"]
end
function lon(w::WRFData)
return w.fields["lon"]
end
function times(w::WRFData)
return w.tm
end
function field(w::WRFData, fname)
return w.fields[fname]
end
function interpolated_field(w::WRFData, fname)
F = field(w, fname)
IF = zeros(Float64, size(F))
N = size(F,3)
IF[:,:,2:N] = 0.5 * (F[:,:,1:N-1] + F[:,:,2:N])
return IF
end
function compute_rainfall_per_hour(w::WRFData)
rainnc = field(w, "RAINNC")
rainc = field(w, "RAINC")
rain = zeros(Float64, size(rainnc))
rain_old = zeros(Float64, size(rain[:,:,1]))
for i in 2:length(w.tm)
dt = (w.tm[i] - w.tm[i-1]).millis / 1000
rain[:,:,i] = ((rainc[:,:,i] + rainnc[:,:,i]) - rain_old) * 3600.0 / dt
rain_old[:,:,:] = rainc[:,:,i]
rain_old += rainnc[:,:,i]
end
w.fields["RAIN"] = rain
delete!(w.fields, "RAINC")
delete!(w.fields, "RAINNC")
end
function domain_extent(w::WRFData)
lon = field(w, "LON")
lat = field(w, "LAT")
return (min(lon), min(lat), max(lon), max(lat))
end
function compute_equilibrium_moisture(w::WRFData)
# pull out required fields from WRF
P, Q, T = field(w, "PSFC"), field(w, "Q2"), field(w, "T2")
N = size(P,3)
# Xi stands for X interpolated
Pi = 0.5 * (P[:,:,1:N-1] + P[:,:,2:N])
Qi = 0.5 * (Q[:,:,1:N-1] + Q[:,:,2:N])
Ti = 0.5 * (T[:,:,1:N-1] + T[:,:,2:N])
# compute saturated vapor pressure
Pws = exp(54.842763 - 6763.22/Ti - 4.210 * log(Ti) + 0.000367*Ti
+ tanh(0.0415*(Ti - 218.8)) .*
(53.878 - 1331.22/Ti - 9.44523 * log(Ti) + 0.014025*Ti))
# compute current water vapor pressure
Pw = Pi .* Qi ./ (0.622 + (1 - 0.622) * Qi)
# compute relative humidity in percent
RH = 100 * Pw ./ Pws
# drying/wetting fuel equilibrium moisture contents
Ed = zeros(Float64, size(P))
Ew = zeros(Float64, size(P))
Ed[:,:,2:] = 0.924*RH.^0.679 + 0.000499*exp(0.1*RH) + 0.18*(21.1 + 273.15 - Ti).*(1 - exp(-0.115*RH))
Ew[:,:,2:] = 0.618*RH.^0.753 + 0.000454*exp(0.1*RH) + 0.18*(21.1 + 273.15 - Ti).*(1 - exp(-0.115*RH))
Ed *= 0.01
Ew *= 0.01
w.fields["Ed"] = Ed
w.fields["Ew"] = Ew
end
function slice_field(w::WRFData, fn::String)
# remove the time dimension from a static field and save a lot of storage
w.fields[fn] = squeeze(w.fields[fn][:,:,1], 3)
end
end