6 use netcdf,
only : nf90_noerr, nf90_global, nf90_nowrite, &
7 nf90_inquire_attribute, nf90_open, nf90_strerror, &
8 nf90_inq_dimid, nf90_inquire_dimension, nf90_inq_varid, &
9 nf90_get_var, nf90_inquire, nf90_close, nf90_get_att
16 character(len=*),
parameter :: &
17 pressure_key =
"plev" , & !< NetCDF data plev key in McClatchey profile
41 integer,
parameter :: MAX_FILE_LEN=200
42 character(MAX_FILE_LEN) :: mcc_input_file
44 integer :: ncid, plev_dim, k
55 "Reading in McClatchey pressure and temperature from:"//trim(mcc_input_file) )
57 call check_mcc_status(nf90_open(path = trim(mcc_input_file), mode = nf90_nowrite, ncid = ncid))
62 if(.not.
allocated(temp_mcc_3d))
then
63 allocate(temp_mcc_3d(1,1,plev_dim))
67 allocate(mcc%t_level(plev_dim))
68 mcc%t_level(:)=temp_mcc_3d(1,1,:)
72 allocate(mcc%p_n(plev_dim))
74 mcc%p_n(k)=(0.5*(mcc%p_level(k-1)+(mcc%p_level(k))))
76 mcc%p_n(1)=mcc%p_level(1)+(0.5*(mcc%p_n(2)-mcc%p_level(1)))
78 allocate(mcc%t_n(plev_dim))
80 weight_upper = log(mcc%p_level(k))-log(mcc%p_n(k-1))
81 weight_lower = log(mcc%p_level(k))-log(mcc%p_level(k-1))
82 mcc%t_n(k) = (((weight_upper*mcc%t_level(k))) + &
83 (weight_lower*mcc%t_level(k-1)))/(weight_upper+weight_lower)
85 mcc%t_n(1)=mcc%t_level(1)+(0.5*(mcc%t_n(2)-mcc%t_level(1)))
92 "Reading in McClatchey vapour profile from:"//trim(mcc_input_file) )
94 call check_mcc_status(nf90_open(path = trim(mcc_input_file), mode = nf90_nowrite, ncid = ncid))
96 allocate(mcc%q_level(plev_dim))
97 mcc%q_level(:)=temp_mcc_3d(1,1,:)
102 allocate(mcc%q_n(plev_dim))
104 weight_upper = log(mcc%p_level(k))-log(mcc%p_n(k-1))
105 weight_lower = log(mcc%p_level(k))-log(mcc%p_level(k-1))
106 mcc%q_n(k) = (((weight_upper*log(mcc%q_level(k)))) + &
107 (weight_lower*log(mcc%q_level(k-1))))/(weight_upper+weight_lower)
108 mcc%q_n(k) = exp(mcc%q_n(k))
110 mcc%q_n(1)=mcc%q_level(1)+(0.5*((mcc%q_n(2)-mcc%q_level(1))))
117 "Reading in McClatchey ozone profile from:"//trim(mcc_input_file) )
119 call check_mcc_status(nf90_open(path = trim(mcc_input_file), mode = nf90_nowrite, ncid = ncid))
121 allocate(mcc%o3_level(plev_dim))
122 mcc%o3_level(:)=temp_mcc_3d(1,1,:)
127 allocate(mcc%o3_n(plev_dim))
129 weight_upper = log(mcc%p_level(k))-log(mcc%p_n(k-1))
130 weight_lower = log(mcc%p_level(k))-log(mcc%p_level(k-1))
131 mcc%o3_n(k) = (((weight_upper*log(mcc%o3_level(k)))) + &
132 (weight_lower*log(mcc%o3_level(k-1))))/(weight_upper+weight_lower)
133 mcc%o3_n(k) = exp(mcc%o3_n(k))
135 mcc%o3_n(1)=mcc%o3_level(1)+(0.5*(mcc%o3_n(2)-mcc%o3_level(1)))
137 deallocate(temp_mcc_3d)
145 integer,
intent(in) :: status
147 if (status /= nf90_noerr)
then
148 call log_log(
log_error,
"NetCDF returned error code of "//trim(nf90_strerror(status)))
159 integer,
intent(in) :: ncid
160 integer,
intent(out) :: plev_dim
161 integer :: plev_dimid
165 call check_mcc_status(nf90_inquire_dimension(ncid, plev_dimid, len=plev_dim))
172 character(*),
intent(in) :: filename
173 character(*),
intent(in) :: MCC_PROFILE_KEY
175 real(kind=
default_precision),
dimension(:),
allocatable,
intent(inout),
optional :: plev
176 real(kind=
default_precision),
dimension(:,:,:),
allocatable,
intent(inout) :: temp_mcc_3d
178 integer,
intent(in) :: ncid, plev_dim
179 integer :: status, variable_id
185 if (
present(plev))
then
187 if (status==nf90_noerr)
then
188 allocate(plev(plev_dim))
191 call log_log(
log_error,
"No recognized pressure variable found in"//trim(filename))
195 status=nf90_inq_varid(ncid, mcc_profile_key, variable_id)
196 if (status==nf90_noerr)
then
199 call log_log(
log_error,
"No recognized pressure variable found in"//trim(filename))
212 integer,
intent(in) :: ncid
213 character(len=*),
intent(in) :: key
215 real(kind=
default_precision),
dimension(:,:,:),
intent(inout),
optional :: data3d
217 integer :: variable_id
222 if (.not.
present(data1d) .and. .not.
present(data3d))
return
224 if (
present(data1d))
then
228 allocate(sdata(
size(data3d,1),
size(data3d,2),
size(data3d,3)))
230 data3d(:,:,:)=reshape(sdata(:,:,:),(/
size(data3d,1),
size(data3d,2),
size(data3d,3)/))
258 allocate(prefn_loc(current_state%local_grid%size(
z_index)))
260 prefn_loc(:) = current_state%global_grid%configuration%vertical%prefn(:)
262 pmindiff = min(max(fracdp* &
263 (prefn_loc(current_state%local_grid%size(
z_index)-1) - &
264 prefn_loc(current_state%local_grid%size(
z_index))), &
266 pcutoff = prefn_loc(current_state%local_grid%size(
z_index)) - pmindiff
270 if (mcc%p_n(k) .lt. pcutoff) mcc%cut = k
273 mcc%irad_levs = current_state%local_grid%size(
z_index) + mcc%cut
274 mcc%n_levels = mcc%irad_levs - 1
276 deallocate(prefn_loc)