|
1 | 1 | using ClimaArtifactsHelper |
| 2 | +using Interpolations |
| 3 | +using NCDatasets |
| 4 | +using DataStructures |
2 | 5 |
|
3 | 6 | const FILE_URL = "https://swift.dkrz.de/v1/dkrz_ab6243f85fe24767bb1508712d1eb504/SAPPHIRE/DYAMOND/ifs_oper_T1279_2016080100.nc" |
4 | 7 | const FILE_PATH = "ifs_oper_T1279_2016080100.nc" |
5 | 8 |
|
6 | 9 | artifact_name = "DYAMOND_summer_initial_conditions" |
7 | | - |
8 | 10 | create_artifact_guided_one_file(FILE_PATH; artifact_name = artifact_name, file_url = FILE_URL) |
| 11 | + |
| 12 | +const FT = Float32 |
| 13 | +const H_EARTH = FT(7000.0) |
| 14 | +const P0 = FT(1e5) |
| 15 | +const z_min, z_max = FT(0), FT(80E3) |
| 16 | + |
| 17 | +Plvl(z) = P0 * exp(-z / H_EARTH) |
| 18 | +Plvl_inv(P) = -H_EARTH * log(P / P0) |
| 19 | + |
| 20 | +compute_P(hyam, hybm, surfacepress) = hyam + hybm * surfacepress |
| 21 | + |
| 22 | +function interpz_3d(target_z, z3d, var3d) |
| 23 | + nx, ny, nz = size(z3d) |
| 24 | + target_var3d = similar(var3d, nx, ny, length(target_z)) |
| 25 | + @inbounds begin |
| 26 | + for yi in 1:ny, xi in 1:nx |
| 27 | + source_z = view(z3d, xi, yi, :) |
| 28 | + itp = extrapolate( |
| 29 | + interpolate( |
| 30 | + (source_z,), |
| 31 | + (view(var3d, xi, yi, :)), |
| 32 | + Gridded(Linear()), |
| 33 | + ), |
| 34 | + Flat(), |
| 35 | + ) |
| 36 | + target_var3d[xi, yi, :] .= itp.(target_z) |
| 37 | + end |
| 38 | + end |
| 39 | + return target_var3d |
| 40 | +end |
| 41 | + |
| 42 | +function create_initial_conditions(infile, outfile; skip = 1) |
| 43 | + ncin = NCDataset(infile, "r") |
| 44 | + ncout = NCDataset(outfile, "c", attrib = copy(ncin.attrib)) |
| 45 | + ncout.attrib["history"] *= "; Modified by CliMA (see atmos_dyamond_summer in ClimaArtifacts)" |
| 46 | + |
| 47 | + lonidx = 1:skip:ncin.dim["lon"] |
| 48 | + latidx = reverse(1:skip:ncin.dim["lat"]) |
| 49 | + # In this dataset vertical levels are ordered in the direction of |
| 50 | + # increasing pressure (decreasing elevation). This is being reordered |
| 51 | + # to stay consistent with our code which orders vertical levels in the |
| 52 | + # direction of increasing elevation |
| 53 | + zidx = ncin.dim["lev"]:-1:1 |
| 54 | + |
| 55 | + nlon = length(lonidx) |
| 56 | + nlat = length(latidx) |
| 57 | + source_nz = length(zidx) |
| 58 | + |
| 59 | + @inbounds begin |
| 60 | + # get source z |
| 61 | + sp = repeat(exp.(ncin["lnsp"][lonidx, latidx, 1, 1]), 1, 1, source_nz) # surface pressure |
| 62 | + hyam = repeat(reshape(ncin["hyam"][zidx], 1, 1, source_nz), nlon, nlat, 1) |
| 63 | + hybm = repeat(reshape(ncin["hybm"][zidx], 1, 1, source_nz), nlon, nlat, 1) |
| 64 | + |
| 65 | + P = FT.(compute_P.(hyam, hybm, sp)) |
| 66 | + source_z = Plvl_inv.(P) |
| 67 | + |
| 68 | + nz = source_nz #length(zidx) |
| 69 | + |
| 70 | + # create a target z grid with nz points |
| 71 | + target_z = FT.(Plvl_inv.(range(Plvl(z_min), Plvl(z_max), nz))) |
| 72 | + # defining dimensions |
| 73 | + defDim(ncout, "lon", nlon) |
| 74 | + defDim(ncout, "lat", nlat) |
| 75 | + defDim(ncout, "z", nz) |
| 76 | + # longitude |
| 77 | + lon = defVar(ncout, "lon", FT, ("lon",), attrib = ncin["lon"].attrib) |
| 78 | + lon[:] = Array{FT}(ncin["lon"][lonidx]) |
| 79 | + |
| 80 | + # latitude |
| 81 | + lat = defVar(ncout, "lat", FT, ("lat",), attrib = ncin["lat"].attrib) |
| 82 | + lat[:] = Array{FT}(ncin["lat"][latidx]) |
| 83 | + |
| 84 | + z = defVar(ncout, "z", FT, ( "z",), attrib = OrderedDict( |
| 85 | + "Datatype" => string(FT), |
| 86 | + "standard_name" => "altitude", |
| 87 | + "long_name" => "altitude", |
| 88 | + "units" => "m", |
| 89 | + ), |
| 90 | + ) |
| 91 | + z[:] = target_z |
| 92 | + |
| 93 | + # p (pressure) |
| 94 | + p = defVar(ncout, "p", FT, ("lon", "lat", "z",), attrib = OrderedDict( |
| 95 | + "Datatype" => string(FT), |
| 96 | + "standard_name" => "pressure", |
| 97 | + "long_name" => "pressure", |
| 98 | + "units" => "Pa", |
| 99 | + ), |
| 100 | + ) |
| 101 | + p[:, :, :] = P |
| 102 | + |
| 103 | + |
| 104 | + # u (eastward_wind) |
| 105 | + u = defVar(ncout, "u", FT, ("lon", "lat", "z",), attrib = ncin["u"].attrib) |
| 106 | + u[:, :, :] = interpz_3d(target_z, source_z, ncin["u"][lonidx, latidx, zidx, 1]) |
| 107 | + |
| 108 | + # v (northward_wind) |
| 109 | + v = defVar(ncout, "v", FT, ("lon", "lat", "z",), attrib = ncin["v"].attrib) |
| 110 | + v[:, :, :] = interpz_3d(target_z, source_z, ncin["v"][lonidx, latidx, zidx, 1]) |
| 111 | + |
| 112 | + # w (vertical velocity) |
| 113 | + w = defVar(ncout, "w", FT, ("lon", "lat", "z",), attrib = ncin["w"].attrib) |
| 114 | + w[:, :, :] = interpz_3d(target_z, source_z, ncin["w"][lonidx, latidx, zidx, 1]) |
| 115 | + |
| 116 | + # t (air_temperature) |
| 117 | + t = defVar(ncout, "t", FT, ("lon", "lat", "z",), attrib = ncin["t"].attrib) |
| 118 | + t[:, :, :] = interpz_3d(target_z, source_z, ncin["t"][lonidx, latidx, zidx, 1]) |
| 119 | + |
| 120 | + # q (specific_humidity) |
| 121 | + q = defVar(ncout, "q", FT, ("lon", "lat", "z",), attrib = ncin["q"].attrib) |
| 122 | + q[:, :, :] = max.(interpz_3d(target_z, source_z, ncin["q"][lonidx, latidx, zidx, 1]), FT(0)) |
| 123 | + |
| 124 | + # clwc (Specific cloud liquid water content) |
| 125 | + clwc = defVar(ncout, "clwc", FT, ("lon", "lat", "z",), attrib = ncin["clwc"].attrib) |
| 126 | + clwc[:, :, :] = max.(interpz_3d(target_z, source_z, ncin["clwc"][lonidx, latidx, zidx, 1]), FT(0)) |
| 127 | + |
| 128 | + # ciwc (Specific cloud ice water content) |
| 129 | + ciwc = defVar(ncout, "ciwc", FT, ("lon", "lat", "z",), attrib = ncin["ciwc"].attrib) |
| 130 | + ciwc[:, :, :] = max.(interpz_3d(target_z, source_z, ncin["ciwc"][lonidx, latidx, zidx, 1]), FT(0)) |
| 131 | + |
| 132 | + # crwc (Specific rain water content) |
| 133 | + crwc = defVar(ncout, "crwc", FT, ("lon", "lat", "z",), attrib = ncin["crwc"].attrib) |
| 134 | + crwc[:, :, :] = max.(interpz_3d(target_z, source_z, ncin["crwc"][lonidx, latidx, zidx, 1]), FT(0)) |
| 135 | + |
| 136 | + # cswc (Specific snow water content) |
| 137 | + cswc = defVar(ncout, "cswc", FT, ("lon", "lat", "z",), attrib = ncin["cswc"].attrib) |
| 138 | + cswc[:, :, :] = max.(interpz_3d(target_z, source_z, ncin["cswc"][lonidx, latidx, zidx, 1]), FT(0)) |
| 139 | + |
| 140 | + # tsn (temperature_in_surface_snow) |
| 141 | + tsn = defVar(ncout, "tsn", FT, ("lon", "lat",), attrib = ncin["tsn"].attrib) |
| 142 | + tsn[:, :] = ncin["tsn"][lonidx, latidx, 1] |
| 143 | + |
| 144 | + # skt (skin temperature) |
| 145 | + skt = defVar(ncout, "skt", FT, ("lon", "lat",), attrib = ncin["skt"].attrib) |
| 146 | + skt[:, :] = ncin["skt"][lonidx, latidx, 1] |
| 147 | + |
| 148 | + # sst (sea surface temperature) |
| 149 | + sst = defVar(ncout, "sst", FT, ("lon", "lat",), attrib = ncin["sst"].attrib) |
| 150 | + sst[:, :] = ncin["sst"][lonidx, latidx, 1] |
| 151 | + |
| 152 | + # stl1 (soil temperature level 1) |
| 153 | + stl1 = defVar(ncout, "stl1", FT, ("lon", "lat",), attrib = ncin["stl1"].attrib) |
| 154 | + stl1[:, :] = ncin["stl1"][lonidx, latidx, 1] |
| 155 | + |
| 156 | + # stl2 (soil temperature level 2) |
| 157 | + stl2 = defVar(ncout, "stl2", FT, ("lon", "lat",), attrib = ncin["stl2"].attrib) |
| 158 | + stl2[:, :] = ncin["stl2"][lonidx, latidx, 1] |
| 159 | + |
| 160 | + # stl3 (soil temperature level 3) |
| 161 | + stl3 = defVar(ncout, "stl3", FT, ("lon", "lat",), attrib = ncin["stl3"].attrib) |
| 162 | + stl3[:, :] = ncin["stl3"][lonidx, latidx, 1] |
| 163 | + |
| 164 | + # stl4 (soil temperature level 4) |
| 165 | + stl4 = defVar(ncout, "stl4", FT, ("lon", "lat",), attrib = ncin["stl4"].attrib) |
| 166 | + stl4[:, :] = ncin["stl4"][lonidx, latidx, 1] |
| 167 | + |
| 168 | + # sd (lwe_thickness_of_surface_snow_amount) |
| 169 | + sd = defVar(ncout, "sd", FT, ("lon", "lat",), attrib = ncin["sd"].attrib) |
| 170 | + sd[:, :] = ncin["sd"][lonidx, latidx, 1] |
| 171 | + |
| 172 | + # rsn (snow density) |
| 173 | + rsn = defVar(ncout, "rsn", FT, ("lon", "lat",), attrib = ncin["rsn"].attrib) |
| 174 | + rsn[:, :] = ncin["rsn"][lonidx, latidx, 1] |
| 175 | + |
| 176 | + # asn (snow albedo) |
| 177 | + asn = defVar(ncout, "asn", FT, ("lon", "lat",), attrib = ncin["asn"].attrib) |
| 178 | + asn[:, :] = ncin["asn"][lonidx, latidx, 1] |
| 179 | + |
| 180 | + # src (skin reservoir content) |
| 181 | + src = defVar(ncout, "src", FT, ("lon", "lat",), attrib = ncin["src"].attrib) |
| 182 | + src[:, :] = ncin["src"][lonidx, latidx, 1] |
| 183 | + |
| 184 | + # ci (Sec-ice cover) |
| 185 | + ci = defVar(ncout, "ci", FT, ("lon", "lat",), attrib = ncin["ci"].attrib) |
| 186 | + ci[:, :] = ncin["ci"][lonidx, latidx, 1] |
| 187 | + |
| 188 | + # swvl1 (volumetric soil water layer 1) |
| 189 | + swvl1 = defVar(ncout, "swvl1", FT, ("lon", "lat",), attrib = ncin["swvl1"].attrib) |
| 190 | + swvl1[:, :] = ncin["swvl1"][lonidx, latidx, 1] |
| 191 | + |
| 192 | + # swvl2 (volumetric soil water layer 2) |
| 193 | + swvl2 = defVar(ncout, "swvl2", FT, ("lon", "lat",), attrib = ncin["swvl2"].attrib) |
| 194 | + swvl2[:, :] = ncin["swvl2"][lonidx, latidx, 1] |
| 195 | + |
| 196 | + # swvl3 (volumetric soil water layer 3) |
| 197 | + swvl3 = defVar(ncout, "swvl3", FT, ("lon", "lat",), attrib = ncin["swvl3"].attrib) |
| 198 | + swvl3[:, :] = ncin["swvl3"][lonidx, latidx, 1] |
| 199 | + |
| 200 | + # swvl4 (volumetric soil water layer 4) |
| 201 | + swvl4 = defVar(ncout, "swvl4", FT, ("lon", "lat",), attrib = ncin["swvl4"].attrib) |
| 202 | + swvl4[:, :] = ncin["swvl4"][lonidx, latidx, 1] |
| 203 | + |
| 204 | + # slt (soil type) |
| 205 | + slt = defVar(ncout, "slt", FT, ("lon", "lat",), attrib = ncin["slt"].attrib) |
| 206 | + slt[:, :] = ncin["slt"][lonidx, latidx, 1] |
| 207 | + |
| 208 | + # lsm (land-sea mask) |
| 209 | + lsm = defVar(ncout, "lsm", FT, ("lon", "lat",), attrib = ncin["lsm"].attrib) |
| 210 | + lsm[:, :] = ncin["lsm"][lonidx, latidx, 1] |
| 211 | + |
| 212 | + # sr (surface roughness length) |
| 213 | + sr = defVar(ncout, "sr", FT, ("lon", "lat",), attrib = ncin["sr"].attrib) |
| 214 | + sr[:, :] = ncin["sr"][lonidx, latidx, 1] |
| 215 | + |
| 216 | + # cvl (low vegetation cover) |
| 217 | + cvl = defVar(ncout, "cvl", FT, ("lon", "lat",), attrib = ncin["cvl"].attrib) |
| 218 | + cvl[:, :] = ncin["cvl"][lonidx, latidx, 1] |
| 219 | + |
| 220 | + # cvh (high vegetation cover) |
| 221 | + cvh = defVar(ncout, "cvh", FT, ("lon", "lat",), attrib = ncin["cvh"].attrib) |
| 222 | + cvh[:, :] = ncin["cvh"][lonidx, latidx, 1] |
| 223 | + |
| 224 | + # sdor (standard deviation or orography) |
| 225 | + sdor = defVar(ncout, "sdor", FT, ("lon", "lat",), attrib = ncin["sdor"].attrib) |
| 226 | + sdor[:, :] = ncin["sdor"][lonidx, latidx, 1] |
| 227 | + |
| 228 | + # isor (anisotropy of sub-grid scale orography) |
| 229 | + isor = defVar(ncout, "isor", FT, ("lon", "lat",), attrib = ncin["isor"].attrib) |
| 230 | + isor[:, :] = ncin["isor"][lonidx, latidx, 1] |
| 231 | + |
| 232 | + # anor (angle of sub-grid scale orography) |
| 233 | + anor = defVar(ncout, "anor", FT, ("lon", "lat",), attrib = ncin["anor"].attrib) |
| 234 | + anor[:, :] = ncin["anor"][lonidx, latidx, 1] |
| 235 | + |
| 236 | + # slor (slope of sub-grid scale orography) |
| 237 | + slor = defVar(ncout, "slor", FT, ("lon", "lat",), attrib = ncin["slor"].attrib) |
| 238 | + slor[:, :] = ncin["slor"][lonidx, latidx, 1] |
| 239 | + end |
| 240 | + close(ncout) |
| 241 | + return nothing |
| 242 | +end |
| 243 | + |
| 244 | +println("creating initial conditions for 0.98⁰ resolution") |
| 245 | + |
| 246 | +artifact_dir_p98deg = artifact_name_p98deg = "DYAMOND_SUMMER_ICS_p98deg" |
| 247 | + |
| 248 | +if !isdir(artifact_dir_p98deg) |
| 249 | + mkdir(artifact_dir_p98deg) |
| 250 | +end |
| 251 | +file_path_p98deg = joinpath(@__DIR__, artifact_dir_p98deg, artifact_name_p98deg * ".nc") |
| 252 | + |
| 253 | +@time create_initial_conditions(FILE_PATH, file_path_p98deg, skip=7) |
| 254 | + |
| 255 | +create_artifact_guided(artifact_dir_p98deg, artifact_name = artifact_name_p98deg, append = true) |
0 commit comments