70 use netcdf95, only: handle_err, nf95_close, nf95_get_att, nf95_gw_var, &
73 use netcdf
, only: nf90_get_att, nf90_get_var, nf90_noerr, nf90_nowrite
76 integer,
intent(in):: read_climoz
84 include
"dimensions.h"
97 real,
pointer:: latitude(:)
100 real,
allocatable:: lat_in_edg(:)
104 real,
pointer:: plev(:)
111 real,
allocatable:: o3_in(:, :, :, :)
122 real,
allocatable:: o3_regr_lat(:, :, :, :)
139 real,
allocatable:: o3_out(:, :, :, :)
151 integer ncid_in, ncid_out
152 integer varid_plev, varid_time, varid, ncerr, dimid
153 character(len=80) press_unit
155 integer varid_in(read_climoz), varid_out(read_climoz)
159 real,
parameter:: tmidmonth(0:13) = (/(-15. + 30. *
l,
l = 0, 13)/)
165 real,
parameter:: tmidday(360) = (/(
l + 0.5,
l = 0, 359)/)
171 print *,
"Call sequence information: regr_lat_time_climoz"
172 call
assert(read_climoz == 1 .or. read_climoz == 2,
"regr_lat_time_climoz")
174 call
nf95_open(
"climoz.nc", nf90_nowrite, ncid_in)
179 call nf95_gw_var(ncid_in, varid, latitude)
181 latitude = latitude / 180. *
pi
182 n_lat =
size(latitude)
185 desc_lat = latitude(1) > latitude(n_lat)
186 if (desc_lat) latitude = latitude(n_lat:1:-1)
189 allocate(lat_in_edg(n_lat + 1))
190 lat_in_edg(1) = -
pi / 2
191 forall (
j = 2:n_lat) lat_in_edg(
j) = (latitude(
j - 1) + latitude(
j)) / 2
192 lat_in_edg(n_lat + 1) =
pi / 2
196 call nf95_gw_var(ncid_in, varid, plev)
202 desc_plev = plev(1) > plev(n_plev)
203 if (desc_plev) plev = plev(n_plev:1:-1)
204 call nf95_get_att(ncid_in, varid,
"units", press_unit)
205 if (press_unit ==
"Pa")
then
208 elseif (press_unit /=
"hPa")
then
209 print *,
"regr_lat_time_climoz: the only recognized units are Pa " &
215 call
prepare_out(ncid_in, n_plev, ncid_out, varid_out, varid_plev, &
219 call nf95_put_var(ncid_out, varid_plev, plev)
220 call nf95_put_var(ncid_out, varid_time, tmidday)
228 allocate(o3_in(n_lat, n_plev, n_month, read_climoz))
231 ncerr = nf90_get_var(ncid_in, varid_in(1), o3_in(:, :, :, 1))
232 call
handle_err(
"regr_lat_time_climoz nf90_get_var tro3", ncerr, ncid_in)
234 if (read_climoz == 2)
then
236 ncerr = nf90_get_var(ncid_in, varid_in(2), o3_in(:, :, :, 2))
237 call
handle_err(
"regr_lat_time_climoz nf90_get_var tro3_daylight", &
238 ncerr, ncid_in, varid_in(2))
241 if (desc_lat) o3_in = o3_in(n_lat:1:-1, :, :, :)
242 if (desc_plev) o3_in = o3_in(:, n_plev:1:-1, :, :)
244 do m = 1, read_climoz
245 ncerr = nf90_get_att(ncid_in, varid_in(
m),
"missing_value", &
247 if (ncerr == nf90_noerr)
then
253 do while (o3_in(
j, 1,
l,
m) == missing_value)
256 if (
j > 1) o3_in(:
j-1, :,
l,
m) = &
257 spread(o3_in(
j, :,
l,
m), dim=1, ncopies=
j-1)
261 do while (o3_in(
j, 1,
l,
m) == missing_value)
264 if (
j < n_lat) o3_in(
j+1:, :,
l,
m) = &
265 spread(o3_in(
j, :,
l,
m), dim=1, ncopies=n_lat-
j)
274 do while (o3_in(
j,
k,
l,
m) /= missing_value .and.
k < n_plev)
279 if (o3_in(
j,
k,
l,
m) == missing_value) &
280 o3_in(
j,
k:n_plev,
l,
m) = o3_in(
j,
k-1,
l,
m)
284 print *,
"regr_lat_time_climoz: field ",
m, &
285 ", no missing value attribute"
291 allocate(o3_regr_lat(jjm + 1, n_plev, 0:13, read_climoz))
292 allocate(o3_out(jjm + 1, n_plev, 360, read_climoz))
297 if (n_month == 12)
then
299 "Found 12 months in ozone climatologies, assuming periodicity..."
301 xs=sin(lat_in_edg), xt=sin((/-
pi / 2,
rlatv(jjm:1:-1),
pi / 2/)))
307 o3_regr_lat(:, :, 0, :) = o3_regr_lat(:, :, 12, :)
308 o3_regr_lat(:, :, 13, :) = o3_regr_lat(:, :, 1, :)
310 print *,
"Using 14 months in ozone climatologies..."
312 xs=sin(lat_in_edg), xt=sin((/-
pi / 2,
rlatv(jjm:1:-1),
pi / 2/)))
318 o3_out =
regr3_lint(o3_regr_lat, tmidmonth, tmidday)
321 do m = 1, read_climoz
322 call nf95_put_var(ncid_out, varid_out(
m), o3_out(jjm+1:1:-1, :, :,
m))
332 subroutine prepare_out(ncid_in, n_plev, ncid_out, varid_out, varid_plev, &
338 use netcdf95, only: nf95_create, nf95_def_dim, nf95_def_var, &
340 use netcdf
, only: nf90_clobber, nf90_float, nf90_global
342 integer,
intent(in):: ncid_in, n_plev
343 integer,
intent(out):: ncid_out, varid_plev, varid_time
345 integer,
intent(out):: varid_out(:)
351 include
"dimensions.h"
361 integer dimid_rlatu, dimid_plev, dimid_time
366 print *,
"Call sequence information: prepare_out"
368 call
nf95_create(
"climoz_LMDZ.nc", nf90_clobber, ncid_out)
373 call
nf95_def_dim(ncid_out,
"rlatu", jjm + 1, dimid_rlatu)
377 call nf95_def_var(ncid_out,
"time", nf90_float, dimid_time, varid_time)
378 call nf95_put_att(ncid_out, varid_time,
"units",
"days since 2000-1-1")
379 call nf95_put_att(ncid_out, varid_time,
"calendar",
"360_day")
380 call nf95_put_att(ncid_out, varid_time,
"standard_name",
"time")
382 call nf95_def_var(ncid_out,
"plev", nf90_float, dimid_plev, varid_plev)
383 call nf95_put_att(ncid_out, varid_plev,
"units",
"millibar")
384 call nf95_put_att(ncid_out, varid_plev,
"standard_name",
"air_pressure")
385 call nf95_put_att(ncid_out, varid_plev,
"long_name",
"air pressure")
387 call nf95_def_var(ncid_out,
"rlatu", nf90_float, dimid_rlatu, varid_rlatu)
388 call nf95_put_att(ncid_out, varid_rlatu,
"units",
"degrees_north")
389 call nf95_put_att(ncid_out, varid_rlatu,
"standard_name",
"latitude")
393 call nf95_def_var(ncid_out,
"tro3", nf90_float, &
394 (/dimid_rlatu, dimid_plev, dimid_time/), varid_out(1))
395 call nf95_put_att(ncid_out, varid_out(1),
"long_name", &
396 "ozone mole fraction")
397 call nf95_put_att(ncid_out, varid_out(1),
"standard_name", &
398 "mole_fraction_of_ozone_in_air")
400 if (
size(varid_out) == 2)
then
401 call nf95_def_var(ncid_out,
"tro3_daylight", nf90_float, &
402 (/dimid_rlatu, dimid_plev, dimid_time/), varid_out(2))
403 call nf95_put_att(ncid_out, varid_out(2),
"long_name", &
404 "ozone mole fraction in daylight")
413 call
nf95_copy_att(ncid_in, nf90_global,
"Conventions", ncid_out, &
417 call
nf95_copy_att(ncid_in, nf90_global,
"title", ncid_out, nf90_global, &
421 call
nf95_copy_att(ncid_in, nf90_global,
"institution", ncid_out, &
425 call
nf95_copy_att(ncid_in, nf90_global,
"source", ncid_out, nf90_global, &
429 call nf95_put_att(ncid_out, nf90_global,
"comment",
"Regridded for LMDZ")
434 call nf95_put_var(ncid_out, varid_rlatu,
rlatu(jjm+1:1:-1) /
pi * 180.)
441 use netcdf
, only: nf90_noerr, nf90_strerror
443 character(len=*),
intent(in):: att_name
447 if (ncerr /= nf90_noerr)
then
448 print *,
"regr_lat_time_climoz_m prepare_out nf95_copy_att " &
449 // att_name //
" -- " // trim(nf90_strerror(ncerr))