FV3 Bundle
type_avg_blk.F90
Go to the documentation of this file.
1 !----------------------------------------------------------------------
2 ! Module: type_avg_blk
3 ! Purpose: averaged statistics block 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 !----------------------------------------------------------------------
9 
10 use tools_kinds, only: kind_real
12 use tools_repro, only: sup,inf
13 use type_bpar, only: bpar_type
14 use type_geom, only: geom_type
15 use type_mom_blk, only: mom_blk_type
16 use type_mpl, only: mpl_type
17 use type_nam, only: nam_type
18 use type_samp, only: samp_type
19 
20 implicit none
21 
22 real(kind_real),parameter :: var_min = 1.0e-24_kind_real ! Minimum variance for correlation computation
23 real(kind_real),parameter :: nc1a_cor_th = 0.1 ! Threshold on the effective sampling size for asymptotic statistics
24 
25 ! Averaged statistics block derived type
27  integer :: ic2 ! Global index
28  integer :: ib ! Block index
29  integer :: ne ! Ensemble size
30  integer :: nsub ! Sub-ensembles number
31  real(kind_real),allocatable :: m2(:,:) ! Variance
32  real(kind_real),allocatable :: m4(:,:) ! Fourth-order centered moment
33  real(kind_real),allocatable :: m2flt(:) ! Filtered variance
34  real(kind_real),allocatable :: nc1a(:,:,:) ! Number of points in subset Sc1 on halo A
35  real(kind_real),allocatable :: m11(:,:,:) ! Covariance average
36  real(kind_real),allocatable :: m11m11(:,:,:,:,:) ! Product of covariances average
37  real(kind_real),allocatable :: m2m2(:,:,:,:,:) ! Product of variances average
38  real(kind_real),allocatable :: m22(:,:,:,:) ! Fourth-order centered moment average
39  real(kind_real),allocatable :: nc1a_cor(:,:,:) ! Number of points in subset Sc1 on halo A with valid correlations
40  real(kind_real),allocatable :: cor(:,:,:) ! Correlation average
41  real(kind_real),allocatable :: m11asysq(:,:,:) ! Squared asymptotic covariance average
42  real(kind_real),allocatable :: m2m2asy(:,:,:) ! Product of asymptotic variances average
43  real(kind_real),allocatable :: m22asy(:,:,:) ! Asymptotic fourth-order centered moment average
44  real(kind_real),allocatable :: m11sq(:,:,:) ! Squared covariance average for several ensemble sizes
45  real(kind_real),allocatable :: m11sta(:,:,:) ! Ensemble covariance/static covariance product
46  real(kind_real),allocatable :: stasq(:,:,:) ! Squared static covariance
47  real(kind_real),allocatable :: m11lrm11sub(:,:,:,:,:) ! LR covariance/HR covariance product average
48  real(kind_real),allocatable :: m11lrm11(:,:,:) ! LR covariance/HR covariance product average, averaged over sub-ensembles
49  real(kind_real),allocatable :: m11lrm11asy(:,:,:) ! LR covariance/HR asymptotic covariance product average
50 contains
51  procedure :: alloc => avg_blk_alloc
52  procedure :: dealloc => avg_blk_dealloc
53  procedure :: copy => avg_blk_copy
54  procedure :: compute => avg_blk_compute
55  procedure :: compute_asy => avg_blk_compute_asy
56  procedure :: compute_lr => avg_blk_compute_lr
57  procedure :: compute_asy_lr => avg_blk_compute_asy_lr
58 end type avg_blk_type
59 
60 private
61 public :: avg_blk_type
62 
63 contains
64 
65 !----------------------------------------------------------------------
66 ! Subroutine: avg_blk_alloc
67 ! Purpose: averaged statistics block data allocation
68 !----------------------------------------------------------------------
69 subroutine avg_blk_alloc(avg_blk,nam,geom,bpar,ic2,ib,ne,nsub)
70 
71 implicit none
72 
73 ! Passed variables
74 class(avg_blk_type),intent(inout) :: avg_blk ! Averaged statistics block
75 type(nam_type),intent(in) :: nam ! Namelist
76 type(geom_type),intent(in) :: geom ! Geometry
77 type(bpar_type),intent(in) :: bpar ! Block parameters
78 integer,intent(in) :: ne ! Ensemble size
79 integer,intent(in) :: nsub ! Sub-ensembles number
80 integer,intent(in) :: ic2 ! Global index
81 integer,intent(in) :: ib ! Block index
82 
83 ! Set attributes
84 avg_blk%ic2 = ic2
85 avg_blk%ib = ib
86 avg_blk%ne = ne
87 avg_blk%nsub = nsub
88 
89 ! Allocation
90 if (.not.allocated(avg_blk%nc1a)) then
91  if ((ic2==0).or.(nam%var_diag)) then
92  allocate(avg_blk%m2(geom%nl0,avg_blk%nsub))
93  if (nam%var_filter) then
94  if (.not.nam%gau_approx) allocate(avg_blk%m4(geom%nl0,avg_blk%nsub))
95  allocate(avg_blk%m2flt(geom%nl0))
96  end if
97  end if
98  if ((ic2==0).or.(nam%local_diag)) then
99  allocate(avg_blk%nc1a(bpar%nc3(ib),bpar%nl0r(ib),geom%nl0))
100  allocate(avg_blk%m11(bpar%nc3(ib),bpar%nl0r(ib),geom%nl0))
101  allocate(avg_blk%m11m11(bpar%nc3(ib),bpar%nl0r(ib),geom%nl0,avg_blk%nsub,avg_blk%nsub))
102  allocate(avg_blk%m2m2(bpar%nc3(ib),bpar%nl0r(ib),geom%nl0,avg_blk%nsub,avg_blk%nsub))
103  if (.not.nam%gau_approx) allocate(avg_blk%m22(bpar%nc3(ib),bpar%nl0r(ib),geom%nl0,avg_blk%nsub))
104  allocate(avg_blk%nc1a_cor(bpar%nc3(ib),bpar%nl0r(ib),geom%nl0))
105  allocate(avg_blk%cor(bpar%nc3(ib),bpar%nl0r(ib),geom%nl0))
106  allocate(avg_blk%m11asysq(bpar%nc3(ib),bpar%nl0r(ib),geom%nl0))
107  allocate(avg_blk%m2m2asy(bpar%nc3(ib),bpar%nl0r(ib),geom%nl0))
108  if (.not.nam%gau_approx) allocate(avg_blk%m22asy(bpar%nc3(ib),bpar%nl0r(ib),geom%nl0))
109  allocate(avg_blk%m11sq(bpar%nc3(ib),bpar%nl0r(ib),geom%nl0))
110  select case (trim(nam%method))
111  case ('hyb-avg','hyb-rnd')
112  allocate(avg_blk%m11sta(bpar%nc3(ib),bpar%nl0r(ib),geom%nl0))
113  allocate(avg_blk%stasq(bpar%nc3(ib),bpar%nl0r(ib),geom%nl0))
114  case ('dual-ens')
115  allocate(avg_blk%m11lrm11sub(bpar%nc3(ib),bpar%nl0r(ib),geom%nl0,avg_blk%nsub,avg_blk%nsub))
116  allocate(avg_blk%m11lrm11(bpar%nc3(ib),bpar%nl0r(ib),geom%nl0))
117  allocate(avg_blk%m11lrm11asy(bpar%nc3(ib),bpar%nl0r(ib),geom%nl0))
118  end select
119  end if
120 end if
121 
122 ! Initialization
123 if ((ic2==0).or.(nam%var_diag)) then
124  call msr(avg_blk%m2)
125  if (nam%var_filter) then
126  if (.not.nam%gau_approx) call msr(avg_blk%m4)
127  call msr(avg_blk%m2flt)
128  end if
129 end if
130 if ((ic2==0).or.(nam%local_diag)) then
131  call msr(avg_blk%nc1a)
132  call msr(avg_blk%m11)
133  call msr(avg_blk%m11m11)
134  call msr(avg_blk%m2m2)
135  if (.not.nam%gau_approx) call msr(avg_blk%m22)
136  call msr(avg_blk%nc1a_cor)
137  call msr(avg_blk%cor)
138  call msr(avg_blk%m11asysq)
139  call msr(avg_blk%m2m2asy)
140  if (.not.nam%gau_approx) call msr(avg_blk%m22asy)
141  call msr(avg_blk%m11sq)
142  select case (trim(nam%method))
143  case ('hyb-avg_blk','hyb-rnd')
144  call msr(avg_blk%m11sta)
145  call msr(avg_blk%stasq)
146  case ('dual-ens')
147  call msr(avg_blk%m11lrm11sub)
148  call msr(avg_blk%m11lrm11)
149  call msr(avg_blk%m11lrm11asy)
150  end select
151 end if
152 
153 end subroutine avg_blk_alloc
154 
155 !----------------------------------------------------------------------
156 ! Subroutine: avg_blk_dealloc
157 ! Purpose: averaged statistics block data deallocation
158 !----------------------------------------------------------------------
159 subroutine avg_blk_dealloc(avg_blk)
161 implicit none
162 
163 ! Passed variables
164 class(avg_blk_type),intent(inout) :: avg_blk ! Averaged statistics block
165 
166 ! Allocation
167 if (allocated(avg_blk%m2)) deallocate(avg_blk%m2)
168 if (allocated(avg_blk%m4)) deallocate(avg_blk%m4)
169 if (allocated(avg_blk%m2flt)) deallocate(avg_blk%m2flt)
170 if (allocated(avg_blk%nc1a)) deallocate(avg_blk%nc1a)
171 if (allocated(avg_blk%m11)) deallocate(avg_blk%m11)
172 if (allocated(avg_blk%m11m11)) deallocate(avg_blk%m11m11)
173 if (allocated(avg_blk%m2m2)) deallocate(avg_blk%m2m2)
174 if (allocated(avg_blk%nc1a_cor)) deallocate(avg_blk%nc1a_cor)
175 if (allocated(avg_blk%cor)) deallocate(avg_blk%cor)
176 if (allocated(avg_blk%m11asysq)) deallocate(avg_blk%m11asysq)
177 if (allocated(avg_blk%m2m2asy)) deallocate(avg_blk%m2m2asy)
178 if (allocated(avg_blk%m11sq)) deallocate(avg_blk%m11sq)
179 if (allocated(avg_blk%m11sta)) deallocate(avg_blk%m11sta)
180 if (allocated(avg_blk%stasq)) deallocate(avg_blk%stasq)
181 if (allocated(avg_blk%m11lrm11sub)) deallocate(avg_blk%m11lrm11sub)
182 if (allocated(avg_blk%m11lrm11)) deallocate(avg_blk%m11lrm11)
183 if (allocated(avg_blk%m11lrm11asy)) deallocate(avg_blk%m11lrm11asy)
184 
185 end subroutine avg_blk_dealloc
186 
187 !----------------------------------------------------------------------
188 ! Function: avg_blk_copy
189 ! Purpose: averaged statistics block copy
190 !----------------------------------------------------------------------
191 type(avg_blk_type) function avg_blk_copy(avg_blk,nam,geom,bpar)
193 implicit none
194 
195 ! Passed variables
196 class(avg_blk_type),intent(in) :: avg_blk ! Averaged statistics block
197 type(nam_type),intent(in) :: nam ! Namelist
198 type(geom_type),intent(in) :: geom ! Geometry
199 type(bpar_type),intent(in) :: bpar ! Block parameters
200 
201 ! Deallocation
202 call avg_blk_copy%dealloc
203 
204 ! Allocation
205 call avg_blk_copy%alloc(nam,geom,bpar,avg_blk%ic2,avg_blk%ib,avg_blk%ne,avg_blk%nsub)
206 
207 ! Copy data
208 if ((avg_blk%ic2==0).or.(nam%var_diag)) then
209  avg_blk_copy%m2 = avg_blk%m2
210  if (nam%var_filter) then
211  if (.not.nam%gau_approx) avg_blk_copy%m4 = avg_blk%m4
212  avg_blk_copy%m2flt = avg_blk%m2flt
213  end if
214 end if
215 if ((avg_blk%ic2==0).or.(nam%local_diag)) then
216  avg_blk_copy%nc1a = avg_blk%nc1a
217  avg_blk_copy%m11 = avg_blk%m11
218  avg_blk_copy%m11m11 = avg_blk%m11m11
219  avg_blk_copy%m2m2 = avg_blk%m2m2
220  if (.not.nam%gau_approx) avg_blk_copy%m22 = avg_blk%m22
221  avg_blk_copy%nc1a_cor = avg_blk%nc1a_cor
222  avg_blk_copy%cor = avg_blk%cor
223  avg_blk_copy%m11asysq = avg_blk%m11asysq
224  avg_blk_copy%m2m2asy = avg_blk%m2m2asy
225  if (.not.nam%gau_approx) avg_blk_copy%m22asy = avg_blk%m22asy
226  avg_blk_copy%m11sq = avg_blk%m11sq
227  select case (trim(nam%method))
228  case ('hyb-avg_blk','hyb-rnd')
229  avg_blk_copy%m11sta = avg_blk%m11sta
230  avg_blk_copy%stasq = avg_blk%stasq
231  case ('dual-ens')
232  avg_blk_copy%m11lrm11sub = avg_blk%m11lrm11sub
233  avg_blk_copy%m11lrm11sub = avg_blk%m11lrm11sub
234  avg_blk_copy%m11lrm11asy = avg_blk%m11lrm11asy
235  end select
236 end if
237 
238 end function avg_blk_copy
239 
240 !----------------------------------------------------------------------
241 ! Subroutine: avg_blk_compute
242 ! Purpose: compute averaged statistics via spatial-angular erogodicity assumption
243 !----------------------------------------------------------------------
244 subroutine avg_blk_compute(avg_blk,nam,geom,bpar,samp,mom_blk)
246 implicit none
247 
248 ! Passed variables
249 class(avg_blk_type),intent(inout) :: avg_blk ! Averaged statistics block
250 type(nam_type),intent(in) :: nam ! Namelist
251 type(geom_type),intent(in) :: geom ! Geometry
252 type(bpar_type),intent(in) :: bpar ! Block parameters
253 type(samp_type),intent(in) :: samp ! Sampling
254 type(mom_blk_type),intent(in) :: mom_blk ! Moments
255 
256 ! Local variables
257 integer :: il0,jl0,jl0r,jc3,isub,jsub,ic1a,ic1,nc1amax,nc1a
258 real(kind_real) :: m2_1,m2_2
259 real(kind_real),allocatable :: list_m11(:),list_m11m11(:,:,:),list_m2m2(:,:,:),list_m22(:,:),list_cor(:)
260 logical :: involved,valid
261 
262 ! Associate
263 associate(ic2=>avg_blk%ic2,ib=>avg_blk%ib)
264 
265 if ((ic2==0).or.(nam%var_diag)) then
266  ! Copy variance
267  if (ic2==0) then
268  do isub=1,avg_blk%nsub
269  do il0=1,geom%nl0
270  jl0r = bpar%il0rz(il0,ib)
271  avg_blk%m2(il0,isub) = sum(mom_blk%m2_1(:,1,il0,isub))/real(nam%nc1,kind_real)
272  if (nam%var_filter.and.(.not.nam%gau_approx)) avg_blk%m4(il0,isub) = sum(mom_blk%m22(:,1,jl0r,il0,isub)) &
273  & /real(nam%nc1,kind_real)
274  end do
275  end do
276  else
277  avg_blk%m2 = 0.0
278  if (nam%var_filter.and.(.not.nam%gau_approx)) avg_blk%m4 = 0.0
279  do ic1a=1,samp%nc1a
280  ic1 = samp%c1a_to_c1(ic1a)
281  if (ic1==samp%c2_to_c1(ic2)) then
282  do isub=1,avg_blk%nsub
283  do il0=1,geom%nl0
284  jl0r = bpar%il0rz(il0,ib)
285  avg_blk%m2(il0,isub) = mom_blk%m2_1(ic1a,1,il0,isub)
286  if (nam%var_filter.and.(.not.nam%gau_approx)) avg_blk%m4(il0,isub) = mom_blk%m22(ic1a,1,jl0r,il0,isub)
287  end do
288  end do
289  end if
290  end do
291  end if
292 end if
293 
294 if ((ic2==0).or.(nam%local_diag)) then
295  ! Check whether this task is involved
296  if (ic2>0) then
297  involved = any(samp%local_mask(samp%c1a_to_c1,ic2))
298  else
299  involved = .true.
300  end if
301 
302  if (involved) then
303  ! Average
304  !$omp parallel do schedule(static) private(il0,jl0r,jl0,nc1amax,jc3,nc1a,ic1a,ic1,valid,m2_1,m2_2,isub,jsub), &
305  !$omp& firstprivate(list_m11,list_m11m11,list_m2m2,list_m22,list_cor)
306  do il0=1,geom%nl0
307  do jl0r=1,bpar%nl0r(ib)
308  jl0 = bpar%l0rl0b_to_l0(jl0r,il0,ib)
309 
310  ! Allocation
311  if (ic2>0) then
312  nc1amax = count(samp%local_mask(samp%c1a_to_c1,ic2))
313  else
314  nc1amax = samp%nc1a
315  end if
316  allocate(list_m11(nc1amax))
317  allocate(list_m11m11(nc1amax,avg_blk%nsub,avg_blk%nsub))
318  allocate(list_m2m2(nc1amax,avg_blk%nsub,avg_blk%nsub))
319  allocate(list_m22(nc1amax,avg_blk%nsub))
320  allocate(list_cor(nc1amax))
321 
322  do jc3=1,bpar%nc3(ib)
323  ! Fill lists
324  nc1a = 0
325  do ic1a=1,samp%nc1a
326  ! Index
327  ic1 = samp%c1a_to_c1(ic1a)
328 
329  ! Check validity
330  valid = samp%c1l0_log(ic1,il0).and.samp%c1c3l0_log(ic1,jc3,jl0)
331  if (ic2>0) valid = valid.and.samp%local_mask(ic1,ic2)
332 
333  if (valid) then
334  ! Update
335  nc1a = nc1a+1
336 
337  ! Averages for diagnostics
338  list_m11(nc1a) = sum(mom_blk%m11(ic1a,jc3,jl0r,il0,:))/real(avg_blk%nsub,kind_real)
339  do isub=1,avg_blk%nsub
340  do jsub=1,avg_blk%nsub
341  list_m11m11(nc1a,jsub,isub) = mom_blk%m11(ic1a,jc3,jl0r,il0,isub)*mom_blk%m11(ic1a,jc3,jl0r,il0,jsub)
342  list_m2m2(nc1a,jsub,isub) = mom_blk%m2_1(ic1a,jc3,il0,isub)*mom_blk%m2_2(ic1a,jc3,jl0,jsub)
343  end do
344  if (.not.nam%gau_approx) list_m22(nc1a,isub) = mom_blk%m22(ic1a,jc3,jl0r,il0,isub)
345  end do
346 
347  ! Correlation
348  m2_1 = sum(mom_blk%m2_1(ic1a,jc3,il0,:))/real(avg_blk%nsub,kind_real)
349  m2_2 = sum(mom_blk%m2_2(ic1a,jc3,jl0,:))/real(avg_blk%nsub,kind_real)
350  if (sup(m2_1,var_min).and.sup(m2_2,var_min)) then
351  list_cor(nc1a) = list_m11(nc1a)/sqrt(m2_1*m2_2)
352  if (sup(abs(list_cor(nc1a)),1.0_kind_real)) call msr(list_cor(nc1a))
353  else
354  call msr(list_cor(nc1a))
355  end if
356  end if
357  end do
358 
359  ! Average
360  avg_blk%nc1a(jc3,jl0r,il0) = real(nc1a,kind_real)
361  if (nc1a>0) then
362  avg_blk%m11(jc3,jl0r,il0) = sum(list_m11(1:nc1a))
363  do isub=1,avg_blk%nsub
364  do jsub=1,avg_blk%nsub
365  avg_blk%m11m11(jc3,jl0r,il0,jsub,isub) = sum(list_m11m11(1:nc1a,jsub,isub))
366  avg_blk%m2m2(jc3,jl0r,il0,jsub,isub) = sum(list_m2m2(1:nc1a,jsub,isub))
367  end do
368  if (.not.nam%gau_approx) avg_blk%m22(jc3,jl0r,il0,isub) = sum(list_m22(1:nc1a,isub))
369  end do
370  avg_blk%nc1a_cor(jc3,jl0r,il0) = real(count(isnotmsr(list_cor(1:nc1a))),kind_real)
371  if (avg_blk%nc1a_cor(jc3,jl0r,il0)>0.0) then
372  avg_blk%cor(jc3,jl0r,il0) = sum(list_cor(1:nc1a),mask=isnotmsr(list_cor(1:nc1a)))
373  else
374  call msr(avg_blk%cor(jc3,jl0r,il0))
375  end if
376  else
377  avg_blk%m11(jc3,jl0r,il0) = 0.0
378  do isub=1,avg_blk%nsub
379  do jsub=1,avg_blk%nsub
380  avg_blk%m11m11(jc3,jl0r,il0,jsub,isub) = 0.0
381  avg_blk%m2m2(jc3,jl0r,il0,jsub,isub) = 0.0
382  end do
383  if (.not.nam%gau_approx) avg_blk%m22(jc3,jl0r,il0,isub) = 0.0
384  end do
385  avg_blk%nc1a_cor(jc3,jl0r,il0) = 0.0
386  avg_blk%cor(jc3,jl0r,il0) = 0.0
387  end if
388  end do
389 
390  ! Release memory
391  deallocate(list_m11)
392  deallocate(list_m11m11)
393  deallocate(list_m2m2)
394  deallocate(list_m22)
395  deallocate(list_cor)
396  end do
397  end do
398  !$omp end parallel do
399  else
400  ! Set to zero
401  avg_blk%nc1a = 0
402  avg_blk%m11 = 0.0
403  avg_blk%m11m11 = 0.0
404  avg_blk%m2m2 = 0.0
405  if (.not.nam%gau_approx) avg_blk%m22 = 0.0
406  avg_blk%nc1a_cor = 0.0
407  avg_blk%cor = 0.0
408  end if
409 end if
410 
411 ! End associate
412 end associate
413 
414 end subroutine avg_blk_compute
415 
416 !----------------------------------------------------------------------
417 ! Subroutine: avg_blk_compute_asy
418 ! Purpose: compute asymptotic statistics
419 !----------------------------------------------------------------------
420 subroutine avg_blk_compute_asy(avg_blk,nam,geom,bpar,ne)
422 implicit none
423 
424 ! Passed variables
425 class(avg_blk_type),intent(inout) :: avg_blk ! Averaged statistics block
426 type(nam_type),intent(in) :: nam ! Namelist
427 type(geom_type),intent(in) :: geom ! Geometry
428 type(bpar_type),intent(in) :: bpar ! Block parameters
429 integer,intent(in) :: ne ! Ensemble size
430 
431 ! Local variables
432 integer :: il0,jl0r,jc3,isub,jsub,n
433 real(kind_real) :: P1,P3,P4,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17
434 real(kind_real),allocatable :: m11asysq(:,:),m2m2asy(:,:),m22asy(:)
435 
436 ! Associate
437 associate(ic2=>avg_blk%ic2,ib=>avg_blk%ib)
438 
439 if ((ic2==0).or.(nam%local_diag)) then
440  ! Ensemble size-dependent coefficients
441  n = ne
442  p1 = 1.0/real(n,kind_real)
443  p3 = 1.0/real(n*(n-1),kind_real)
444  p4 = 1.0/real(n-1,kind_real)
445  p14 = real(n**2-2*n+2,kind_real)/real(n*(n-1),kind_real)
446  p16 = real(n,kind_real)/real(n-1,kind_real)
447 
448  ! Ensemble/sub-ensemble size-dependent coefficients
449  n = avg_blk%ne/avg_blk%nsub
450  p7 = real((n-1)*(n**2-3*n+1),kind_real)/real(n*(n-2)*(n-3),kind_real)
451  p8 = real(n-1,kind_real)/real(n*(n-2)*(n-3),kind_real)
452  p9 = -real(n,kind_real)/real((n-2)*(n-3),kind_real)
453  p10 = -real((n-1)*(2*n-3),kind_real)/real(n*(n-2)*(n-3),kind_real)
454  p11 = real(n*(n**2-2*n+3),kind_real)/real((n-1)*(n-2)*(n-3),kind_real)
455  p12 = real(n*(n-1),kind_real)/real((n-2)*(n+1),kind_real)
456  p13 = -real(n-1,kind_real)/real((n-2)*(n+1),kind_real)
457  p15 = real((n-1)**2,kind_real)/real(n*(n-3),kind_real)
458  p17 = real((n-1)**2,kind_real)/real((n-2)*(n+1),kind_real)
459 
460  ! Asymptotic statistics
461  !$omp parallel do schedule(static) private(il0,jl0r,jc3,isub,jsub) firstprivate(m11asysq,m2m2asy,m22asy)
462  do il0=1,geom%nl0
463  do jl0r=1,bpar%nl0r(ib)
464  do jc3=1,bpar%nc3(ib)
465  if (avg_blk%nc1a_cor(jc3,jl0r,il0)>nc1a_cor_th*avg_blk%nc1a(jc3,jl0r,il0)) then
466  ! Allocation
467  allocate(m11asysq(avg_blk%nsub,avg_blk%nsub))
468  allocate(m2m2asy(avg_blk%nsub,avg_blk%nsub))
469  allocate(m22asy(avg_blk%nsub))
470 
471  ! Asymptotic statistics
472  do isub=1,avg_blk%nsub
473  do jsub=1,avg_blk%nsub
474  if (isub==jsub) then
475  ! Diagonal terms
476  if (nam%gau_approx) then
477  ! Gaussian approximation
478  m11asysq(jsub,isub) = p17*avg_blk%m11m11(jc3,jl0r,il0,jsub,isub) &
479  & +p13*avg_blk%m2m2(jc3,jl0r,il0,jsub,isub)
480  m2m2asy(jsub,isub) = 2.0*p13*avg_blk%m11m11(jc3,jl0r,il0,jsub,isub) &
481  & +p12*avg_blk%m2m2(jc3,jl0r,il0,jsub,isub)
482  else
483  ! General case
484  m11asysq(jsub,isub) = p15*avg_blk%m11m11(jc3,jl0r,il0,jsub,isub) &
485  & +p8*avg_blk%m2m2(jc3,jl0r,il0,jsub,isub)+p9*avg_blk%m22(jc3,jl0r,il0,jsub)
486  m2m2asy(jsub,isub) = 2.0*p8*avg_blk%m11m11(jc3,jl0r,il0,jsub,isub) &
487  & +p7*avg_blk%m2m2(jc3,jl0r,il0,jsub,isub)+p9*avg_blk%m22(jc3,jl0r,il0,jsub)
488  m22asy(jsub) = p10*(2.0*avg_blk%m11m11(jc3,jl0r,il0,jsub,isub)+avg_blk%m2m2(jc3,jl0r,il0,jsub,isub)) &
489  & +p11*avg_blk%m22(jc3,jl0r,il0,jsub)
490  end if
491  else
492  ! Off-diagonal terms
493  m11asysq(jsub,isub) = avg_blk%m11m11(jc3,jl0r,il0,jsub,isub)
494  m2m2asy(jsub,isub) = avg_blk%m2m2(jc3,jl0r,il0,jsub,isub)
495  end if
496  end do
497  end do
498 
499  ! Sum
500  avg_blk%m11asysq(jc3,jl0r,il0) = sum(m11asysq)/real(avg_blk%nsub**2,kind_real)
501  avg_blk%m2m2asy(jc3,jl0r,il0) = sum(m2m2asy)/real(avg_blk%nsub**2,kind_real)
502  if (.not.nam%gau_approx) avg_blk%m22asy(jc3,jl0r,il0) = sum(m22asy)/real(avg_blk%nsub,kind_real)
503 
504  ! Check positivity
505  if (avg_blk%m11asysq(jc3,jl0r,il0)<0.0) call msr(avg_blk%m11asysq(jc3,jl0r,il0))
506  if (avg_blk%m2m2asy(jc3,jl0r,il0)<0.0) call msr(avg_blk%m2m2asy(jc3,jl0r,il0))
507  if (.not.nam%gau_approx) then
508  if (avg_blk%m22asy(jc3,jl0r,il0)<0.0) call msr(avg_blk%m22asy(jc3,jl0r,il0))
509  end if
510 
511  ! Squared covariance average
512  if (nam%gau_approx) then
513  ! Gaussian approximation
514  if (isnotmsr(avg_blk%m11asysq(jc3,jl0r,il0)).and.isnotmsr(avg_blk%m2m2asy(jc3,jl0r,il0))) &
515  & avg_blk%m11sq(jc3,jl0r,il0) = p16*avg_blk%m11asysq(jc3,jl0r,il0)+p4*avg_blk%m2m2asy(jc3,jl0r,il0)
516  else
517  ! General case
518  if (isnotmsr(avg_blk%m22asy(jc3,jl0r,il0)).and.isnotmsr(avg_blk%m11asysq(jc3,jl0r,il0)) &
519  & .and.isnotmsr(avg_blk%m2m2asy(jc3,jl0r,il0))) &
520  & avg_blk%m11sq(jc3,jl0r,il0) = p1*avg_blk%m22asy(jc3,jl0r,il0)+p14*avg_blk%m11asysq(jc3,jl0r,il0) &
521  & +p3*avg_blk%m2m2asy(jc3,jl0r,il0)
522  end if
523 
524  ! Check value
525  if (ismsr(avg_blk%m11sq(jc3,jl0r,il0))) then
526  if (inf(avg_blk%m11sq(jc3,jl0r,il0),avg_blk%m11asysq(jc3,jl0r,il0))) call msr(avg_blk%m11sq(jc3,jl0r,il0))
527  if (inf(avg_blk%m11sq(jc3,jl0r,il0),avg_blk%m11(jc3,jl0r,il0)**2)) call msr(avg_blk%m11sq(jc3,jl0r,il0))
528  end if
529 
530  ! Allocation
531  deallocate(m11asysq)
532  deallocate(m2m2asy)
533  deallocate(m22asy)
534  end if
535  end do
536  end do
537  end do
538  !$omp end parallel do
539 end if
540 
541 ! End associate
542 end associate
543 
544 end subroutine avg_blk_compute_asy
545 
546 !----------------------------------------------------------------------
547 ! Subroutine: avg_blk_compute_lr
548 ! Purpose: compute averaged statistics via spatial-angular erogodicity assumption, for LR covariance/HR covariance and LR covariance/HR asymptotic covariance products
549 !----------------------------------------------------------------------
550 subroutine avg_blk_compute_lr(avg_blk_lr,mpl,nam,geom,bpar,samp,mom_blk,mom_lr_blk)
552 implicit none
553 
554 ! Passed variables
555 class(avg_blk_type),intent(inout) :: avg_blk_lr ! Low-resolution averaged statistics block
556 type(mpl_type),intent(in) :: mpl ! MPI data
557 type(nam_type),intent(in) :: nam ! Namelist
558 type(geom_type),intent(in) :: geom ! Geometry
559 type(bpar_type),intent(in) :: bpar ! Block parameters
560 type(samp_type),intent(in) :: samp ! Sampling
561 type(mom_blk_type),intent(in) :: mom_blk ! Moments block
562 type(mom_blk_type),intent(in) :: mom_lr_blk ! Low-resolution moments block
563 
564 ! Local variables
565 integer :: il0,jl0,jl0r,jc3,isub,jsub,ic1a,ic1,nc1amax,nc1a
566 real(kind_real),allocatable :: list_m11lrm11(:,:,:)
567 logical :: valid
568 
569 ! Associate
570 associate(ic2=>avg_blk_lr%ic2,ib=>avg_blk_lr%ib)
571 
572 if ((ic2==0).or.(nam%local_diag)) then
573  ! Check number of sub-ensembles
574  if (avg_blk_lr%nsub/=avg_blk_lr%nsub) call mpl%abort('different number of sub-ensembles')
575 
576  ! Average
577  !$omp parallel do schedule(static) private(il0,jl0r,jl0,nc1amax,list_m11lrm11,jc3,nc1a,ic1a,ic1,valid,isub,jsub)
578  do il0=1,geom%nl0
579  do jl0r=1,bpar%nl0r(ib)
580  jl0 = bpar%l0rl0b_to_l0(jl0r,il0,ib)
581 
582  ! Allocation
583  if (ic2>0) then
584  nc1amax = count(samp%local_mask(samp%c1a_to_c1,ic2))
585  else
586  nc1amax = samp%nc1a
587  end if
588  allocate(list_m11lrm11(nc1amax,avg_blk_lr%nsub,avg_blk_lr%nsub))
589 
590  do jc3=1,bpar%nc3(ib)
591  ! Fill lists
592  nc1a = 0
593  do ic1a=1,samp%nc1a
594  ! Index
595  ic1 = samp%c1a_to_c1(ic1a)
596 
597  ! Check validity
598  valid = samp%c1l0_log(ic1,il0).and.samp%c1c3l0_log(ic1,jc3,jl0)
599  if (ic2>0) valid = valid.and.samp%local_mask(ic1,ic2)
600 
601  if (valid) then
602  ! Update
603  nc1a = nc1a+1
604 
605  ! Averages for diagnostics
606  do isub=1,avg_blk_lr%nsub
607  do jsub=1,avg_blk_lr%nsub
608  list_m11lrm11(nc1a,jsub,isub) = mom_blk%m11(ic1a,jc3,jl0r,il0,isub)*mom_lr_blk%m11(ic1a,jc3,jl0r,il0,jsub)
609  end do
610  end do
611  end if
612  end do
613 
614  ! Average
615  avg_blk_lr%nc1a(jc3,jl0r,il0) = real(nc1a,kind_real)
616  do isub=1,avg_blk_lr%nsub
617  do jsub=1,avg_blk_lr%nsub
618  avg_blk_lr%m11lrm11sub(jc3,jl0r,il0,jsub,isub) = sum(list_m11lrm11(1:nc1a,jsub,isub))
619  end do
620  end do
621  end do
622 
623  ! Release memory
624  deallocate(list_m11lrm11)
625  end do
626  end do
627  !$omp end parallel do
628 end if
629 
630 ! End associate
631 end associate
632 
633 end subroutine avg_blk_compute_lr
634 
635 !----------------------------------------------------------------------
636 ! Subroutine: avg_blk_compute_asy_lr
637 ! Purpose: compute LR covariance/HR asymptotic covariance products
638 !----------------------------------------------------------------------
639 subroutine avg_blk_compute_asy_lr(avg_blk_lr,nam,geom,bpar)
641 implicit none
642 
643 ! Passed variables
644 class(avg_blk_type),intent(inout) :: avg_blk_lr ! Low-resolution averaged statistics block
645 type(nam_type),intent(in) :: nam ! Namelist
646 type(geom_type),intent(in) :: geom ! Geometry
647 type(bpar_type),intent(in) :: bpar ! Block parameters
648 
649 ! Local variables
650 integer :: il0,jl0r,jc3,isub,jsub
651 
652 ! Associate
653 associate(ic2=>avg_blk_lr%ic2,ib=>avg_blk_lr%ib)
654 
655 if ((ic2==0).or.(nam%local_diag)) then
656  ! Normalize
657  !$omp parallel do schedule(static) private(il0,jl0r,jc3,isub,jsub)
658  do il0=1,geom%nl0
659  do jl0r=1,bpar%nl0r(ib)
660  do jc3=1,bpar%nc3(ib)
661  if (avg_blk_lr%nc1a(jc3,jl0r,il0)>0.0) then
662  do isub=1,avg_blk_lr%nsub
663  do jsub=1,avg_blk_lr%nsub
664  avg_blk_lr%m11lrm11sub(jc3,jl0r,il0,jsub,isub) = avg_blk_lr%m11lrm11sub(jc3,jl0r,il0,jsub,isub) &
665  & /avg_blk_lr%nc1a(jc3,jl0r,il0)
666  end do
667  end do
668  end if
669  end do
670  end do
671  end do
672  !$omp end parallel do
673 
674  ! Average over sub-ensembles
675  !$omp parallel do schedule(static) private(il0,jl0r,jc3)
676  do il0=1,geom%nl0
677  do jl0r=1,bpar%nl0r(ib)
678  do jc3=1,bpar%nc3(ib)
679  if (isanynotmsr(avg_blk_lr%m11lrm11sub(jc3,jl0r,il0,:,:))) then
680  avg_blk_lr%m11lrm11(jc3,jl0r,il0) = sum(avg_blk_lr%m11lrm11sub(jc3,jl0r,il0,:,:), &
681  & mask=isnotmsr(avg_blk_lr%m11lrm11sub(jc3,jl0r,il0,:,:))) &
682  & /real(count(isnotmsr(avg_blk_lr%m11lrm11sub(jc3,jl0r,il0,:,:))),kind_real)
683  end if
684  end do
685  end do
686  end do
687  !$omp end parallel do
688 
689  ! Define asymptotic covariance
690  avg_blk_lr%m11lrm11asy = avg_blk_lr%m11lrm11
691 end if
692 
693 ! End associate
694 end associate
695 
696 end subroutine avg_blk_compute_asy_lr
697 
698 end module type_avg_blk
logical function, public sup(x, y)
Definition: tools_repro.F90:85
subroutine avg_blk_compute(avg_blk, nam, geom, bpar, samp, mom_blk)
subroutine avg_blk_compute_asy(avg_blk, nam, geom, bpar, ne)
type(avg_blk_type) function avg_blk_copy(avg_blk, nam, geom, bpar)
subroutine, public copy(self, rhs)
Definition: qg_fields.F90:225
subroutine avg_blk_compute_asy_lr(avg_blk_lr, nam, geom, bpar)
subroutine avg_blk_compute_lr(avg_blk_lr, mpl, nam, geom, bpar, samp, mom_blk, mom_lr_blk)
real(kind_real), parameter var_min
real(kind_real), parameter nc1a_cor_th
subroutine avg_blk_alloc(avg_blk, nam, geom, bpar, ic2, ib, ne, nsub)
subroutine avg_blk_dealloc(avg_blk)
integer, parameter, public kind_real
logical function, public inf(x, y)
Definition: tools_repro.F90:47