FV3 Bundle
type_diag.F90
Go to the documentation of this file.
1 !----------------------------------------------------------------------
2 ! Module: type_diag
3 ! Purpose: diagnostic derived type
4 ! Author: Benjamin Menetrier
5 ! Licensing: this code is distributed under the CeCILL-C license
6 ! Copyright © 2015-... UCAR, CERFACS, METEO-FRANCE and IRIT
7 !----------------------------------------------------------------------
8 module type_diag
9 
10 use fckit_mpi_module, only: fckit_mpi_sum
11 use netcdf
12 use tools_const, only: reqkm,rad2deg,pi
13 use tools_fit, only: ver_smooth
15 use tools_kinds, only: kind_real
17 use tools_nc, only: ncfloat
18 use type_avg, only: avg_type
19 use type_bpar, only: bpar_type
21 use type_geom, only: geom_type
22 use type_io, only: io_type
23 use type_mpl, only: mpl_type
24 use type_nam, only: nam_type
25 use type_samp, only: samp_type
26 
27 implicit none
28 
29 real(kind_real),parameter :: bound = 5.0_kind_real ! Restriction bound applied on local diagnostics with respect to the global diagnostic
30 
31 ! Diagnostic derived type
33  character(len=1024) :: prefix ! Prefix
34  integer :: nc2a ! Number of local points
35  type(diag_blk_type),allocatable :: blk(:,:) ! Diagnostic blocks
36 contains
37  procedure :: alloc => diag_alloc
38  procedure :: fit_filter => diag_fit_filter
39  procedure :: write => diag_write
40  procedure :: covariance => diag_covariance
41  procedure :: correlation => diag_correlation
42  procedure :: localization => diag_localization
43  procedure :: hybridization => diag_hybridization
44  procedure :: dualens => diag_dualens
45 end type diag_type
46 
47 private
48 public :: diag_type
49 
50 contains
51 
52 !----------------------------------------------------------------------
53 ! Subroutine: diag_alloc
54 ! Purpose: allocation
55 !----------------------------------------------------------------------
56 subroutine diag_alloc(diag,nam,geom,bpar,samp,prefix,double_fit)
57 
58 implicit none
59 
60 ! Passed variables
61 class(diag_type),intent(inout) :: diag ! Diagnostic
62 type(nam_type),intent(in) :: nam ! Namelist
63 type(geom_type),intent(in) :: geom ! Geometry
64 type(bpar_type),intent(in) :: bpar ! Block parameters
65 type(samp_type),intent(in) :: samp ! Sampling
66 character(len=*),intent(in) :: prefix ! Block prefix
67 logical,intent(in) :: double_fit ! Double fit
68 
69 ! Local variables
70 integer :: ib,ic2a
71 
72 ! Number of local points
73 if (nam%var_diag.or.nam%local_diag) then
74  diag%nc2a = samp%nc2a
75 else
76  diag%nc2a = 0
77 end if
78 
79 ! Prefix
80 diag%prefix = trim(prefix)
81 
82 ! Allocation
83 allocate(diag%blk(0:diag%nc2a,bpar%nbe))
84 do ib=1,bpar%nbe
85  if (bpar%diag_block(ib)) then
86  do ic2a=0,diag%nc2a
87  call diag%blk(ic2a,ib)%alloc(nam,geom,bpar,samp,ic2a,ib,prefix,double_fit.and.nam%double_fit(bpar%b_to_v1(ib)))
88  end do
89  end if
90 end do
91 
92 end subroutine diag_alloc
93 
94 !----------------------------------------------------------------------
95 ! Subroutine: diag_fit_filter
96 ! Purpose: filter fit diagnostics
97 !----------------------------------------------------------------------
98 subroutine diag_fit_filter(diag,mpl,nam,geom,bpar,samp)
99 
100 implicit none
101 
102 ! Passed variables
103 class(diag_type),intent(inout) :: diag ! Diagnostic
104 type(mpl_type),intent(inout) :: mpl ! MPI data
105 type(nam_type),intent(in) :: nam ! Namelist
106 type(geom_type),intent(in) :: geom ! Geometry
107 type(bpar_type),intent(in) :: bpar ! Block parameters
108 type(samp_type),intent(in) :: samp ! Sampling
109 
110 ! Local variables
111 integer :: ib,il0,ic2a
112 real(kind_real) :: rmse,norm,rmse_tot,norm_tot
113 real(kind_real) :: rh_c2a(samp%nc2a,geom%nl0),rv_c2a(samp%nc2a,geom%nl0)
114 real(kind_real),allocatable :: rv_rfac_c2a(:,:),rv_coef_c2a(:,:)
115 
116 do ib=1,bpar%nbe
117  if (bpar%fit_block(ib)) then
118  if (nam%local_diag) then
119  ! Horizontal filtering
120 
121  ! Allocation
122  if (diag%blk(0,ib)%double_fit) then
123  allocate(rv_rfac_c2a(samp%nc2a,geom%nl0))
124  allocate(rv_coef_c2a(samp%nc2a,geom%nl0))
125  end if
126 
127  ! Initialization
128  call msr(rh_c2a)
129  call msr(rv_c2a)
130  if (diag%blk(0,ib)%double_fit) then
131  call msr(rv_rfac_c2a)
132  call msr(rv_coef_c2a)
133  end if
134 
135  do il0=1,geom%nl0
136  do ic2a=1,samp%nc2a
137  ! Copy data
138  rh_c2a(ic2a,il0) = diag%blk(ic2a,ib)%fit_rh(il0)
139  rv_c2a(ic2a,il0) = diag%blk(ic2a,ib)%fit_rv(il0)
140  if (diag%blk(0,ib)%double_fit) then
141  rv_rfac_c2a(ic2a,il0) = diag%blk(ic2a,ib)%fit_rv_rfac(il0)
142  rv_coef_c2a(ic2a,il0) = diag%blk(ic2a,ib)%fit_rv_coef(il0)
143  end if
144 
145  ! Apply bounds relatively to the global value
146  if (isnotmsr(rh_c2a(ic2a,il0)).and.isnotmsr(diag%blk(0,ib)%fit_rh(il0))) then
147  if ((rh_c2a(ic2a,il0)<diag%blk(0,ib)%fit_rh(il0)/bound) &
148  & .or.(rh_c2a(ic2a,il0)>diag%blk(0,ib)%fit_rh(il0)*bound)) call msr(rh_c2a(ic2a,il0))
149  end if
150  if (isnotmsr(rv_c2a(ic2a,il0)).and.isnotmsr(diag%blk(0,ib)%fit_rv(il0))) then
151  if ((rv_c2a(ic2a,il0)<diag%blk(0,ib)%fit_rv(il0)/bound) &
152  & .or.(rv_c2a(ic2a,il0)>diag%blk(0,ib)%fit_rv(il0)*bound)) call msr(rv_c2a(ic2a,il0))
153  end if
154  end do
155 
156  ! Median filter to remove extreme values
157  call samp%diag_filter(mpl,nam,geom,il0,'median',nam%diag_rhflt,rh_c2a(:,il0))
158  call samp%diag_filter(mpl,nam,geom,il0,'median',nam%diag_rhflt,rv_c2a(:,il0))
159  if (diag%blk(0,ib)%double_fit) then
160  call samp%diag_filter(mpl,nam,geom,il0,'median',nam%diag_rhflt,rv_rfac_c2a(:,il0))
161  call samp%diag_filter(mpl,nam,geom,il0,'median',nam%diag_rhflt,rv_coef_c2a(:,il0))
162  end if
163 
164  ! Average filter to smooth support radii
165  call samp%diag_filter(mpl,nam,geom,il0,'average',nam%diag_rhflt,rh_c2a(:,il0))
166  call samp%diag_filter(mpl,nam,geom,il0,'average',nam%diag_rhflt,rv_c2a(:,il0))
167  if (diag%blk(0,ib)%double_fit) then
168  call samp%diag_filter(mpl,nam,geom,il0,'average',nam%diag_rhflt,rv_rfac_c2a(:,il0))
169  call samp%diag_filter(mpl,nam,geom,il0,'average',nam%diag_rhflt,rv_coef_c2a(:,il0))
170  end if
171 
172  ! Fill missing values
173  call samp%diag_fill(mpl,nam,geom,il0,rh_c2a(:,il0))
174  call samp%diag_fill(mpl,nam,geom,il0,rv_c2a(:,il0))
175  if (diag%blk(0,ib)%double_fit) then
176  call samp%diag_fill(mpl,nam,geom,il0,rv_rfac_c2a(:,il0))
177  call samp%diag_fill(mpl,nam,geom,il0,rv_coef_c2a(:,il0))
178  end if
179 
180  ! Copy data
181  do ic2a=1,samp%nc2a
182  diag%blk(ic2a,ib)%fit_rh(il0) = rh_c2a(ic2a,il0)
183  diag%blk(ic2a,ib)%fit_rv(il0) = rv_c2a(ic2a,il0)
184  if (diag%blk(0,ib)%double_fit) then
185  diag%blk(ic2a,ib)%fit_rv_rfac(il0) = rv_rfac_c2a(ic2a,il0)
186  diag%blk(ic2a,ib)%fit_rv_coef(il0) = rv_coef_c2a(ic2a,il0)
187  end if
188  end do
189  end do
190 
191  ! Release memory
192  if (diag%blk(0,ib)%double_fit) then
193  deallocate(rv_rfac_c2a)
194  deallocate(rv_coef_c2a)
195  end if
196  end if
197 
198  ! Vertical filtering
199  do ic2a=0,diag%nc2a
200  call ver_smooth(mpl,geom%nl0,geom%vunitavg,nam%rvflt,diag%blk(ic2a,ib)%fit_rh)
201  call ver_smooth(mpl,geom%nl0,geom%vunitavg,nam%rvflt,diag%blk(ic2a,ib)%fit_rv)
202  if (diag%blk(0,ib)%double_fit) then
203  call ver_smooth(mpl,geom%nl0,geom%vunitavg,nam%rvflt,diag%blk(ic2a,ib)%fit_rv_rfac)
204  call ver_smooth(mpl,geom%nl0,geom%vunitavg,nam%rvflt,diag%blk(ic2a,ib)%fit_rv_coef)
205  end if
206  end do
207 
208  ! Rebuild fit
209  do ic2a=0,diag%nc2a
210  if (diag%blk(0,ib)%double_fit) then
211  call fit_diag_dble(mpl,nam%nc3,bpar%nl0r(ib),geom%nl0,bpar%l0rl0b_to_l0(:,:,ib),geom%disth,diag%blk(ic2a,ib)%distv, &
212  & diag%blk(ic2a,ib)%fit_rh,diag%blk(ic2a,ib)%fit_rv,diag%blk(ic2a,ib)%fit_rv_rfac,diag%blk(ic2a,ib)%fit_rv_coef, &
213  & diag%blk(ic2a,ib)%fit)
214  else
215  call fit_diag(mpl,nam%nc3,bpar%nl0r(ib),geom%nl0,bpar%l0rl0b_to_l0(:,:,ib),geom%disth,diag%blk(ic2a,ib)%distv, &
216  & diag%blk(ic2a,ib)%fit_rh,diag%blk(ic2a,ib)%fit_rv,diag%blk(ic2a,ib)%fit)
217  end if
218  end do
219 
220  ! Compute RMSE
221  rmse = 0.0
222  norm = 0.0
223  do ic2a=0,diag%nc2a
224  rmse = rmse+sum(abs(diag%blk(ic2a,ib)%fit-diag%blk(ic2a,ib)%raw),mask=isnotmsr(diag%blk(ic2a,ib)%raw))
225  norm = norm+real(count(isnotmsr(diag%blk(ic2a,ib)%raw)),kind_real)
226  end do
227  call mpl%f_comm%allreduce(rmse,rmse_tot,fckit_mpi_sum())
228  call mpl%f_comm%allreduce(norm,norm_tot,fckit_mpi_sum())
229  if (norm_tot>0.0) rmse_tot = sqrt(rmse_tot/norm_tot)
230  write(mpl%info,'(a10,a,a,a,e15.8,a,i8,a)') '','Fit RMSE for block ',trim(bpar%blockname(ib)),': ',rmse_tot, &
231  & ' for ',int(norm_tot),' diagnostic points'
232  end if
233 end do
234 
235 end subroutine diag_fit_filter
236 
237 !----------------------------------------------------------------------
238 ! Subroutine: diag_write
239 ! Purpose: write all diagnostics
240 !----------------------------------------------------------------------
241 subroutine diag_write(diag,mpl,nam,geom,bpar,io,samp)
243 implicit none
244 
245 ! Passed variables
246 class(diag_type),intent(inout) :: diag ! Diagnostic
247 type(mpl_type),intent(inout) :: mpl ! MPI data
248 type(nam_type),intent(in) :: nam ! Namelist
249 type(geom_type),intent(in) :: geom ! Geometry
250 type(bpar_type),intent(in) :: bpar ! Block parameters
251 type(io_type),intent(in) :: io ! I/O
252 type(samp_type),intent(in) :: samp ! Sampling
253 
254 ! Local variables
255 integer :: ib,i,ic2,il0,il0i,iproc,ic2a,ildw,n
256 real(kind_real) :: fld_c2a(samp%nc2a,geom%nl0),fld_c2b(samp%nc2b,geom%nl0),fld_c0a(geom%nc0a,geom%nl0)
257 character(len=7) :: lonchar,latchar
258 character(len=1024) :: filename
259 
260 if (mpl%main) then
261  filename = trim(nam%prefix)//'_diag.nc'
262  do ib=1,bpar%nbe
263  if (bpar%diag_block(ib)) then
264  call diag%blk(0,ib)%write(mpl,nam,geom,bpar,filename)
265  end if
266  end do
267 end if
268 
269 if ((trim(diag%prefix)/='cov').and.(nam%var_diag.or.nam%local_diag)) then
270  do ib=1,bpar%nbe
271  if (bpar%fit_block(ib)) then
272  filename = trim(nam%prefix)//'_local_diag_'//trim(diag%prefix)
273  n = 1
274  if (nam%local_diag) then
275  n = n+2
276  if (diag%blk(0,ib)%double_fit) n = n+2
277  end if
278  do i=1,n
279  ! Copy data
280  do ic2a=1,samp%nc2a
281  if (i==1) then
282  fld_c2a(ic2a,:) = diag%blk(ic2a,ib)%raw_coef_ens
283  elseif (i==2) then
284  fld_c2a(ic2a,:) = diag%blk(ic2a,ib)%fit_rh*reqkm
285  elseif (i==3) then
286  fld_c2a(ic2a,:) = diag%blk(ic2a,ib)%fit_rv
287  elseif (i==4) then
288  fld_c2a(ic2a,:) = diag%blk(ic2a,ib)%fit_rv_rfac
289  elseif (i==5) then
290  fld_c2a(ic2a,:) = diag%blk(ic2a,ib)%fit_rv_coef
291  end if
292  end do
293 
294  ! Interpolation
295  call samp%com_AB%ext(mpl,geom%nl0,fld_c2a,fld_c2b)
296  do il0=1,geom%nl0
297  il0i = min(il0,geom%nl0i)
298  call samp%h(il0i)%apply(mpl,fld_c2b(:,il0),fld_c0a(:,il0))
299  end do
300 
301  ! Write fields
302  if (i==1) then
303  call io%fld_write(mpl,nam,geom,filename,trim(bpar%blockname(ib))//'_raw_coef_ens',fld_c0a)
304  elseif (i==2) then
305  call io%fld_write(mpl,nam,geom,filename,trim(bpar%blockname(ib))//'_fit_rh',fld_c0a)
306  elseif (i==3) then
307  call io%fld_write(mpl,nam,geom,filename,trim(bpar%blockname(ib))//'_fit_rv',fld_c0a)
308  elseif (i==4) then
309  call io%fld_write(mpl,nam,geom,filename,trim(bpar%blockname(ib))//'_fit_rv_rfac',fld_c0a)
310  elseif (i==5) then
311  call io%fld_write(mpl,nam,geom,filename,trim(bpar%blockname(ib))//'_fit_rv_coef',fld_c0a)
312  end if
313  end do
314  end if
315  end do
316 end if
317 
318 do ildw=1,nam%nldwv
319  if (isnotmsi(samp%nn_ldwv_index(ildw))) then
320  ic2 = samp%nn_ldwv_index(ildw)
321  iproc = samp%c2_to_proc(ic2)
322  if (mpl%myproc==iproc) then
323  ! Build file name
324  write(lonchar,'(f7.2)') nam%lon_ldwv(ildw)*rad2deg
325  write(latchar,'(f7.2)') nam%lat_ldwv(ildw)*rad2deg
326  filename = trim(nam%prefix)//'_diag_'//trim(adjustl(lonchar))//'-'//trim(adjustl(latchar))//'.nc'
327 
328  ! Find diagnostic point task
329  ic2a = samp%c2_to_c2a(ic2)
330  do ib=1,bpar%nbe
331  if (bpar%diag_block(ib)) call diag%blk(ic2a,ib)%write(mpl,nam,geom,bpar,filename)
332  end do
333  end if
334  else
335  call mpl%warning('missing local profile')
336  end if
337 end do
338 
339 end subroutine diag_write
340 
341 !----------------------------------------------------------------------
342 ! Subroutine: diag_covariance
343 ! Purpose: compute covariance
344 !----------------------------------------------------------------------
345 subroutine diag_covariance(diag,mpl,nam,geom,bpar,io,samp,avg,prefix)
347 implicit none
348 
349 ! Passed variables
350 class(diag_type),intent(inout) :: diag ! Diagnostic
351 type(mpl_type),intent(inout) :: mpl ! MPI data
352 type(nam_type),intent(in) :: nam ! Namelist
353 type(geom_type),intent(in) :: geom ! Geometry
354 type(bpar_type),intent(in) :: bpar ! Block parameters
355 type(io_type),intent(in) :: io ! I/O
356 type(samp_type),intent(in) :: samp ! Sampling
357 type(avg_type),intent(in) :: avg ! Averaged statistics
358 character(len=*),intent(in) :: prefix ! Diagnostic prefix
359 
360 ! Local variables
361 integer :: ib,ic2a,ic2,il0
362 
363 ! Allocation
364 call diag%alloc(nam,geom,bpar,samp,prefix,.false.)
365 
366 do ib=1,bpar%nbe
367  if (bpar%diag_block(ib)) then
368  write(mpl%info,'(a10,a,a,a)') '','Block ',trim(bpar%blockname(ib))
369  call flush(mpl%info)
370 
371  do ic2a=0,diag%nc2a
372  ! Copy
373  if (ic2a>0) then
374  ic2 = samp%c2a_to_c2(ic2a)
375  else
376  ic2 = 0
377  end if
378  diag%blk(ic2a,ib)%raw = avg%blk(ic2,ib)%m11
379  end do
380 
381  ! Print results
382  do il0=1,geom%nl0
383  if (isnotmsr(diag%blk(0,ib)%raw(1,bpar%il0rz(il0,ib),il0))) then
384  write(mpl%info,'(a13,a,i3,a,a,e9.2,a)') '','Level: ',nam%levs(il0),' ~> cov. at class zero: ',trim(mpl%peach), &
385  & diag%blk(0,ib)%raw(1,bpar%il0rz(il0,ib),il0),trim(mpl%black)
386  call flush(mpl%info)
387  end if
388  end do
389  end if
390 end do
391 
392 ! Write
393 call diag%write(mpl,nam,geom,bpar,io,samp)
394 
395 end subroutine diag_covariance
396 
397 !----------------------------------------------------------------------
398 ! Subroutine: diag_correlation
399 ! Purpose: compute correlation
400 !----------------------------------------------------------------------
401 subroutine diag_correlation(diag,mpl,nam,geom,bpar,io,samp,avg,prefix)
403 implicit none
404 
405 ! Passed variables
406 class(diag_type),intent(inout) :: diag ! Diagnostic
407 type(mpl_type),intent(inout) :: mpl ! MPI data
408 type(nam_type),intent(in) :: nam ! Namelist
409 type(geom_type),intent(in) :: geom ! Geometry
410 type(bpar_type),intent(in) :: bpar ! Block parameters
411 type(io_type),intent(in) :: io ! I/O
412 type(samp_type),intent(in) :: samp ! Sampling
413 type(avg_type),intent(in) :: avg ! Averaged statistics
414 character(len=*),intent(in) :: prefix ! Diagnostic prefix
415 
416 ! Local variables
417 integer :: ib,ic2a,ic2,il0
418 type(diag_type) :: ndiag
419 
420 ! Allocation
421 call diag%alloc(nam,geom,bpar,samp,prefix,.true.)
422 call ndiag%alloc(nam,geom,bpar,samp,'n'//trim(prefix),.false.)
423 
424 do ib=1,bpar%nbe
425  if (bpar%diag_block(ib)) then
426  write(mpl%info,'(a10,a,a,a)',advance='no') '','Block ',trim(bpar%blockname(ib)),':'
427  call flush(mpl%info)
428 
429  ! Copy variance
430  do ic2a=0,diag%nc2a
431  if (nam%var_diag) then
432  ! Global index
433  if (ic2a>0) then
434  ic2 = samp%c2a_to_c2(ic2a)
435  else
436  ic2 = 0
437  end if
438 
439  ! Copy
440  if (nam%var_filter) then
441  diag%blk(ic2a,ib)%raw_coef_ens = avg%blk(ic2,ib)%m2flt
442  else
443  diag%blk(ic2a,ib)%raw_coef_ens = sum(avg%blk(ic2,ib)%m2,dim=2)/real(avg%nsub,kind_real)
444  end if
445  else
446  diag%blk(ic2a,ib)%raw_coef_ens = 1.0
447  end if
448  end do
449 
450  ! Initialization
451  call mpl%prog_init(diag%nc2a+1)
452 
453  do ic2a=0,diag%nc2a
454  ! Global index
455  if (ic2a>0) then
456  ic2 = samp%c2a_to_c2(ic2a)
457  else
458  ic2 = 0
459  end if
460 
461  ! Copy
462  diag%blk(ic2a,ib)%raw = avg%blk(ic2,ib)%cor
463 
464  ! Fitting
465  if (bpar%fit_block(ib)) call diag%blk(ic2a,ib)%fitting(mpl,nam,geom,bpar,samp)
466 
467  ! Update
468  call mpl%prog_print(ic2a+1)
469  end do
470  ndiag%blk(0,ib)%raw = avg%blk(0,ib)%nc1a_cor
471  write(mpl%info,'(a)') '100%'
472  call flush(mpl%info)
473 
474  ! Print results
475  do il0=1,geom%nl0
476  if (bpar%fit_block(ib)) then
477  if (isnotmsr(diag%blk(0,ib)%fit_rh(il0))) then
478  write(mpl%info,'(a13,a,i3,a4,a16,a,f10.2,a,f10.2,a)') '','Level: ',nam%levs(il0),' ~> ','cor. support radii: ', &
479  & trim(mpl%aqua),diag%blk(0,ib)%fit_rh(il0)*reqkm,trim(mpl%black)//' km / '//trim(mpl%aqua), &
480  & diag%blk(0,ib)%fit_rv(il0),trim(mpl%black)//' '//trim(mpl%vunitchar)
481  if (diag%blk(0,ib)%double_fit) then
482  write(mpl%info,'(a47,a,f10.2,a,f10.2,a)') 'cor. double fit: ',trim(mpl%aqua),diag%blk(0,ib)%fit_rv_rfac(il0), &
483  & trim(mpl%black)//' / '//trim(mpl%aqua),diag%blk(0,ib)%fit_rv_coef(il0),trim(mpl%black)//' '//trim(mpl%vunitchar)
484  end if
485  call flush(mpl%info)
486  end if
487  end if
488  end do
489  end if
490 end do
491 
492 ! Filtering
493 call diag%fit_filter(mpl,nam,geom,bpar,samp)
494 
495 ! Write
496 call diag%write(mpl,nam,geom,bpar,io,samp)
497 call ndiag%write(mpl,nam,geom,bpar,io,samp)
498 
499 end subroutine diag_correlation
500 
501 !----------------------------------------------------------------------
502 ! Subroutine: diag_localization
503 ! Purpose: compute diagnostic localization
504 !----------------------------------------------------------------------
505 subroutine diag_localization(diag,mpl,nam,geom,bpar,io,samp,avg,prefix)
507 implicit none
508 
509 ! Passed variables
510 class(diag_type),intent(inout) :: diag ! Diagnostic
511 type(mpl_type),intent(inout) :: mpl ! MPI data
512 type(nam_type),intent(in) :: nam ! Namelist
513 type(geom_type),intent(in) :: geom ! Geometry
514 type(bpar_type),intent(in) :: bpar ! Block parameters
515 type(io_type),intent(in) :: io ! I/O
516 type(samp_type),intent(in) :: samp ! Sampling
517 type(avg_type),intent(in) :: avg ! Averaged statistics
518 character(len=*),intent(in) :: prefix ! Block prefix
519 
520 ! Local variables
521 integer :: ib,ic2a,ic2,il0
522 
523 ! Allocation
524 call diag%alloc(nam,geom,bpar,samp,prefix,.false.)
525 
526 do ib=1,bpar%nbe
527  if (bpar%diag_block(ib)) then
528  write(mpl%info,'(a10,a,a,a)',advance='no') '','Block ',trim(bpar%blockname(ib)),':'
529  call flush(mpl%info)
530 
531  ! Initialization
532  call mpl%prog_init(diag%nc2a+1)
533 
534  do ic2a=0,diag%nc2a
535  ! Compute localization
536  if (ic2a>0) then
537  ic2 = samp%c2a_to_c2(ic2a)
538  else
539  ic2 = 0
540  end if
541  call diag%blk(ic2a,ib)%localization(geom,bpar,avg%blk(ic2,ib))
542 
543  ! Normalization
544  call diag%blk(ic2a,ib)%normalization(geom,bpar,.true.)
545  if (trim(nam%method)=='loc_norm') diag%blk(ic2a,ib)%raw_coef_ens = 1.0
546 
547  ! Fitting
548  if (bpar%fit_block(ib)) call diag%blk(ic2a,ib)%fitting(mpl,nam,geom,bpar,samp)
549 
550  ! Update
551  call mpl%prog_print(ic2a+1)
552  end do
553  write(mpl%info,'(a)') '100%'
554  call flush(mpl%info)
555 
556  ! Print results
557  do il0=1,geom%nl0
558  select case (trim(nam%method))
559  case ('loc','hyb-avg','hyb-rnd','dual-ens')
560  if (isnotmsr(diag%blk(0,ib)%raw_coef_ens(il0))) then
561  write(mpl%info,'(a13,a,i3,a4,a20,a,f10.2,a)') '','Level: ',nam%levs(il0),' ~> ','loc. at class zero: ', &
562  & trim(mpl%peach),diag%blk(0,ib)%raw_coef_ens(il0),trim(mpl%black)
563  call flush(mpl%info)
564  end if
565  end select
566  if (bpar%fit_block(ib)) then
567  if (isnotmsr(diag%blk(0,ib)%fit_rh(il0))) then
568  select case (trim(nam%method))
569  case ('loc','hyb-avg','hyb-rnd','dual-ens')
570  write(mpl%info,'(a47)',advance='no') 'loc. support radii: '
571  case ('loc_norm')
572  write(mpl%info,'(a13,a,i3,a4,a20)',advance='no') '','Level: ',nam%levs(il0),' ~> ','loc. support radii: '
573  end select
574  write(mpl%info,'(a,f10.2,a,f10.2,a)') trim(mpl%aqua),diag%blk(0,ib)%fit_rh(il0)*reqkm, &
575  & trim(mpl%black)//' km / '//trim(mpl%aqua),diag%blk(0,ib)%fit_rv(il0),trim(mpl%black)//' '//trim(mpl%vunitchar)
576  call flush(mpl%info)
577  end if
578  end if
579  end do
580  end if
581 end do
582 
583 ! Filtering
584 call diag%fit_filter(mpl,nam,geom,bpar,samp)
585 
586 ! Write
587 call diag%write(mpl,nam,geom,bpar,io,samp)
588 
589 end subroutine diag_localization
590 
591 !----------------------------------------------------------------------
592 ! Subroutine: diag_hybridization
593 ! Purpose: compute diagnostic hybridization
594 !----------------------------------------------------------------------
595 subroutine diag_hybridization(diag,mpl,nam,geom,bpar,io,samp,avg,avg_sta,prefix)
597 implicit none
598 
599 ! Passed variables
600 class(diag_type),intent(inout) :: diag ! Diagnostic (localization)
601 type(mpl_type),intent(inout) :: mpl ! MPI data
602 type(nam_type),intent(in) :: nam ! Namelist
603 type(geom_type),intent(in) :: geom ! Geometry
604 type(bpar_type),intent(in) :: bpar ! Block parameters
605 type(io_type),intent(in) :: io ! I/O
606 type(samp_type),intent(in) :: samp ! Sampling
607 type(avg_type),intent(in) :: avg ! Averaged statistics
608 type(avg_type),intent(in) :: avg_sta ! Static averaged statistics
609 character(len=*),intent(in) :: prefix ! Diagnostic prefix
610 
611 ! Local variables
612 integer :: ib,ic2a,ic2,il0
613 
614 ! Allocation
615 call diag%alloc(nam,geom,bpar,samp,prefix,.false.)
616 
617 do ib=1,bpar%nbe
618  if (bpar%diag_block(ib)) then
619  write(mpl%info,'(a10,a,a,a)',advance='no') '','Block ',trim(bpar%blockname(ib)),':'
620  call flush(mpl%info)
621 
622  ! Initialization
623  call mpl%prog_init(diag%nc2a+1)
624 
625  do ic2a=0,diag%nc2a
626  ! Compute hybridization
627  if (ic2a>0) then
628  ic2 = samp%c2a_to_c2(ic2a)
629  else
630  ic2 = 0
631  end if
632  call diag%blk(ic2a,ib)%hybridization(geom,bpar,avg%blk(ic2,ib),avg_sta%blk(ic2,ib))
633 
634  ! Normalization
635  call diag%blk(ic2a,ib)%normalization(geom,bpar,.true.)
636 
637  ! Fitting
638  if (bpar%fit_block(ib)) call diag%blk(ic2a,ib)%fitting(mpl,nam,geom,bpar,samp)
639 
640  ! Update
641  call mpl%prog_print(ic2a+1)
642  end do
643  write(mpl%info,'(a)') '100%'
644  call flush(mpl%info)
645 
646  ! Print results
647  do il0=1,geom%nl0
648  if (isnotmsr(diag%blk(0,ib)%raw_coef_ens(il0))) then
649  write(mpl%info,'(a13,a,i3,a4,a21,a,f10.2,a)') '','Level: ',nam%levs(il0),' ~> ','loc. at class zero: ', &
650  & trim(mpl%peach),diag%blk(0,ib)%raw_coef_ens(il0),trim(mpl%black)
651  call flush(mpl%info)
652  end if
653  if (bpar%fit_block(ib)) then
654  if (isnotmsr(diag%blk(0,ib)%fit_rh(il0))) then
655  write(mpl%info,'(a48,a,f10.2,a,f10.2,a)') 'loc. support radii: ',trim(mpl%aqua),diag%blk(0,ib)%fit_rh(il0)*reqkm, &
656  & trim(mpl%black)//' km / '//trim(mpl%aqua),diag%blk(0,ib)%fit_rv(il0),trim(mpl%black)//' '//trim(mpl%vunitchar)
657  call flush(mpl%info)
658  end if
659  end if
660  end do
661  write(mpl%info,'(a13,a,a,f10.2,a)') '','Raw static coeff.: ',trim(mpl%purple),diag%blk(0,ib)%raw_coef_sta,trim(mpl%black)
662  call flush(mpl%info)
663  end if
664 end do
665 
666 ! Filtering
667 call diag%fit_filter(mpl,nam,geom,bpar,samp)
668 
669 ! Write
670 call diag%write(mpl,nam,geom,bpar,io,samp)
671 
672 end subroutine diag_hybridization
673 
674 !----------------------------------------------------------------------
675 ! Subroutine: diag_dualens
676 ! Purpose: compute diagnostic dualens
677 !----------------------------------------------------------------------
678 subroutine diag_dualens(diag,mpl,nam,geom,bpar,io,samp,avg,avg_lr,diag_lr,prefix,prefix_lr)
680 implicit none
681 
682 ! Passed variables
683 class(diag_type),intent(inout) :: diag ! Diagnostic (localization)
684 type(mpl_type),intent(inout) :: mpl ! MPI data
685 type(nam_type),intent(in) :: nam ! Namelist
686 type(geom_type),intent(in) :: geom ! Geometry
687 type(bpar_type),intent(in) :: bpar ! Block parameters
688 type(io_type),intent(in) :: io ! I/O
689 type(samp_type),intent(in) :: samp ! Sampling
690 type(avg_type),intent(in) :: avg ! Averaged statistics
691 type(avg_type),intent(in) :: avg_lr ! LR averaged statistics
692 type(diag_type),intent(inout) :: diag_lr ! Diagnostic (LR localization)
693 character(len=*),intent(in) :: prefix ! Diagnostic prefix
694 character(len=*),intent(in) :: prefix_lr ! LR diagnostic prefix
695 
696 ! Local variables
697 integer :: ib,ic2a,ic2,il0
698 
699 ! Allocation
700 call diag%alloc(nam,geom,bpar,samp,prefix,.false.)
701 call diag_lr%alloc(nam,geom,bpar,samp,prefix_lr,.false.)
702 
703 do ib=1,bpar%nbe
704  if (bpar%diag_block(ib)) then
705  write(mpl%info,'(a10,a,a,a)',advance='no') '','Block ',trim(bpar%blockname(ib)),':'
706  call flush(mpl%info)
707 
708  ! Initialization
709  call mpl%prog_init(diag%nc2a+1)
710 
711  do ic2a=0,diag%nc2a
712  ! Compute dualens
713  if (ic2a>0) then
714  ic2 = samp%c2a_to_c2(ic2a)
715  else
716  ic2 = 0
717  end if
718  call diag%blk(ic2a,ib)%dualens(geom,bpar,avg%blk(ic2,ib),avg_lr%blk(ic2a,ib),diag_lr%blk(ic2a,ib))
719 
720  ! Normalization
721  call diag%blk(ic2a,ib)%normalization(geom,bpar,.true.)
722  call diag_lr%blk(ic2a,ib)%normalization(geom,bpar,.true.)
723 
724  ! Fitting
725  if (bpar%fit_block(ib)) then
726  call diag%blk(ic2a,ib)%fitting(mpl,nam,geom,bpar,samp)
727  call diag_lr%blk(ic2a,ib)%fitting(mpl,nam,geom,bpar,samp)
728  end if
729 
730  ! Update
731  call mpl%prog_print(ic2a+1)
732  end do
733  write(mpl%info,'(a)') '100%'
734  call flush(mpl%info)
735 
736  ! Print results
737  do il0=1,geom%nl0
738  if (isnotmsr(diag%blk(0,ib)%raw_coef_ens(il0))) then
739  write(mpl%info,'(a10,a,i3,a4,a21,a,f10.2,a)') '','Level: ',nam%levs(il0),' ~> ','loc. at class zero (HR): ', &
740  & trim(mpl%peach),diag%blk(0,ib)%raw_coef_ens(il0),trim(mpl%black)
741  call flush(mpl%info)
742  end if
743  if (isnotmsr(diag%blk(0,ib)%raw_coef_ens(il0))) then
744  write(mpl%info,'(a45,a,f10.2,a)') 'loc. at class zero (LR): ',trim(mpl%peach),diag_lr%blk(0,ib)%raw_coef_ens(il0), &
745  & trim(mpl%black)
746  call flush(mpl%info)
747  end if
748  if (bpar%fit_block(ib)) then
749  if (isnotmsr(diag%blk(0,ib)%fit_rh(il0))) then
750  write(mpl%info,'(a45,a,f10.2,a,f10.2,a)') 'loc. support radii (HR): ',trim(mpl%aqua), &
751  & diag%blk(0,ib)%fit_rh(il0)*reqkm,trim(mpl%black)//' km / '//trim(mpl%aqua),diag_lr%blk(0,ib)%fit_rv(il0), &
752  & trim(mpl%black)//' '//trim(mpl%vunitchar)
753  call flush(mpl%info)
754  end if
755  if (isnotmsr(diag_lr%blk(0,ib)%fit_rh(il0))) then
756  write(mpl%info,'(a45,a,f10.2,a,f10.2,a)') 'loc. support radii (LR): ',trim(mpl%aqua), &
757  & diag_lr%blk(0,ib)%fit_rh(il0)*reqkm,trim(mpl%black)//' km / '//trim(mpl%aqua),diag_lr%blk(0,ib)%fit_rv(il0), &
758  & trim(mpl%black)//' '//trim(mpl%vunitchar)
759  call flush(mpl%info)
760  end if
761  end if
762  end do
763  end if
764 end do
765 
766 ! Filtering
767 call diag%fit_filter(mpl,nam,geom,bpar,samp)
768 call diag_lr%fit_filter(mpl,nam,geom,bpar,samp)
769 
770 ! Write
771 call diag%write(mpl,nam,geom,bpar,io,samp)
772 call diag_lr%write(mpl,nam,geom,bpar,io,samp)
773 
774 end subroutine diag_dualens
775 
776 end module type_diag
subroutine diag_correlation(diag, mpl, nam, geom, bpar, io, samp, avg, prefix)
Definition: type_diag.F90:402
subroutine diag_dualens(diag, mpl, nam, geom, bpar, io, samp, avg, avg_lr, diag_lr, prefix, prefix_lr)
Definition: type_diag.F90:679
real(kind_real), parameter, public rad2deg
Definition: tools_const.F90:17
subroutine diag_covariance(diag, mpl, nam, geom, bpar, io, samp, avg, prefix)
Definition: type_diag.F90:346
subroutine, public fit_diag_dble(mpl, nc3, nl0r, nl0, l0rl0_to_l0, disth, distv, rh, rv, rv_rfac, rv_coef, fit)
Definition: tools_func.F90:369
subroutine, public ver_smooth(mpl, n, x, rv, profile)
Definition: tools_fit.F90:182
subroutine diag_write(diag, mpl, nam, geom, bpar, io, samp)
Definition: type_diag.F90:242
real(kind_real), parameter bound
Definition: type_diag.F90:29
subroutine diag_localization(diag, mpl, nam, geom, bpar, io, samp, avg, prefix)
Definition: type_diag.F90:506
integer, parameter, public kind_real
subroutine diag_fit_filter(diag, mpl, nam, geom, bpar, samp)
Definition: type_diag.F90:99
#define min(a, b)
Definition: mosaic_util.h:32
subroutine diag_hybridization(diag, mpl, nam, geom, bpar, io, samp, avg, avg_sta, prefix)
Definition: type_diag.F90:596
integer, parameter, public ncfloat
Definition: tools_nc.F90:27
subroutine diag_alloc(diag, nam, geom, bpar, samp, prefix, double_fit)
Definition: type_diag.F90:57
real(fp), parameter, public pi
subroutine, public fit_diag(mpl, nc3, nl0r, nl0, l0rl0_to_l0, disth, distv, rh, rv, fit)
Definition: tools_func.F90:235
real(kind_real), parameter, public reqkm
Definition: tools_const.F90:19