FV3 Bundle
type_mom.F90
Go to the documentation of this file.
1 !----------------------------------------------------------------------
2 ! Module: type_mom
3 ! Purpose: moments 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_mom
9 
10 !$ use omp_lib
11 use tools_kinds, only: kind_real
12 use tools_missing, only: msi,msr,isnotmsr
13 use type_bpar, only: bpar_type
14 use type_com, only: com_type
15 use type_ens, only: ens_type
16 use type_geom, only: geom_type
17 use type_linop, only: linop_type
18 use type_mom_blk, only: mom_blk_type
19 use type_mpl, only: mpl_type
20 use type_nam, only: nam_type
21 use type_samp, only: samp_type
22 
23 implicit none
24 
25 ! Moments derived type
27  integer :: ne
28  integer :: nsub
29  type(mom_blk_type),allocatable :: blk(:) ! Moments blocks
30 contains
31  procedure :: alloc => mom_alloc
32  procedure :: compute => mom_compute
33 end type mom_type
34 
35 private
36 public :: mom_type
37 
38 contains
39 
40 !----------------------------------------------------------------------
41 ! Subroutine: mom_alloc
42 ! Purpose: allocate moments
43 !----------------------------------------------------------------------
44 subroutine mom_alloc(mom,nam,geom,bpar,samp,ne,nsub)
45 
46 implicit none
47 
48 ! Passed variables
49 class(mom_type),intent(inout) :: mom ! Moments
50 type(nam_type),intent(in) :: nam ! Namelist
51 type(geom_type),intent(in) :: geom ! Geometry
52 type(bpar_type),intent(in) :: bpar ! Block parameters
53 type(samp_type),intent(in) :: samp ! Sampling
54 integer,intent(in) :: ne ! Ensemble size
55 integer,intent(in) :: nsub ! Number of sub-ensembles
56 
57 ! Local variables
58 integer :: ib
59 
60 ! Set attributes
61 mom%ne = ne
62 mom%nsub = nsub
63 
64 ! Allocation
65 allocate(mom%blk(bpar%nb))
66 
67 do ib=1,bpar%nb
68  if (bpar%diag_block(ib)) then
69  ! Allocation
70  mom%blk(ib)%ne = ne
71  mom%blk(ib)%nsub = nsub
72  allocate(mom%blk(ib)%m2_1(samp%nc1a,bpar%nc3(ib),geom%nl0,mom%blk(ib)%nsub))
73  allocate(mom%blk(ib)%m2_2(samp%nc1a,bpar%nc3(ib),geom%nl0,mom%blk(ib)%nsub))
74  allocate(mom%blk(ib)%m11(samp%nc1a,bpar%nc3(ib),bpar%nl0r(ib),geom%nl0,mom%blk(ib)%nsub))
75  if (.not.nam%gau_approx) allocate(mom%blk(ib)%m22(samp%nc1a,bpar%nc3(ib),bpar%nl0r(ib),geom%nl0,mom%blk(ib)%nsub))
76  if (nam%var_full) allocate(mom%blk(ib)%m2full(geom%nc0a,geom%nl0,mom%blk(ib)%nsub))
77 
78  ! Initialization
79  mom%blk(ib)%m2_1 = 0.0
80  mom%blk(ib)%m2_2 = 0.0
81  mom%blk(ib)%m11 = 0.0
82  if (.not.nam%gau_approx) mom%blk(ib)%m22 = 0.0
83  if (nam%var_full) mom%blk(ib)%m2full = 0.0
84  end if
85 end do
86 
87 end subroutine mom_alloc
88 
89 !----------------------------------------------------------------------
90 ! Subroutine: mom_compute
91 ! Purpose: compute centered moments (iterative formulae)
92 !----------------------------------------------------------------------
93 subroutine mom_compute(mom,mpl,nam,geom,bpar,samp,ens)
94 
95 implicit none
96 
97 ! Passed variables
98 class(mom_type),intent(inout) :: mom ! Moments
99 type(mpl_type),intent(in) :: mpl ! MPI data
100 type(nam_type),intent(in) :: nam ! Namelist
101 type(geom_type),intent(in) :: geom ! Geometry
102 type(bpar_type),intent(in) :: bpar ! Block parameters
103 type(samp_type),intent(in) :: samp ! Sampling
104 type(ens_type), intent(in) :: ens ! Ensemble
105 
106 ! Local variables
107 integer :: ie,ie_sub,jc0,ic0c,jc0c,ic0,jl0r,jl0,il0,isub,jc3,ic1,ic1a,ib,jv,iv,jts,its
108 real(kind_real),allocatable :: fld_ext(:,:,:,:),fld_1(:,:,:),fld_2(:,:,:)
109 logical,allocatable :: mask_unpack(:,:)
110 
111 ! Allocation
112 call mom%alloc(nam,geom,bpar,samp,ens%ne,ens%nsub)
113 
114 ! Loop on sub-ensembles
115 do isub=1,ens%nsub
116  if (ens%nsub==1) then
117  write(mpl%info,'(a10,a)',advance='no') '','Full ensemble, member:'
118  else
119  write(mpl%info,'(a10,a,i4,a)',advance='no') '','Sub-ensemble ',isub,', member:'
120  end if
121  call flush(mpl%info)
122 
123  ! Compute centered moments
124  do ie_sub=1,ens%ne/ens%nsub
125  write(mpl%info,'(i4)',advance='no') ie_sub
126  call flush(mpl%info)
127 
128  ! Full ensemble index
129  ie = ie_sub+(isub-1)*ens%ne/ens%nsub
130 
131  ! Allocation
132  allocate(fld_ext(samp%nc0c,geom%nl0,nam%nv,nam%nts))
133  allocate(mask_unpack(samp%nc0c,geom%nl0))
134  mask_unpack = .true.
135 
136  do ib=1,bpar%nb
137  ! Indices
138  iv = bpar%b_to_v1(ib)
139  jv = bpar%b_to_v2(ib)
140  its = bpar%b_to_ts1(ib)
141  jts = bpar%b_to_ts2(ib)
142 
143  ! Halo extension
144  if ((iv==jv).and.(its==jts)) call samp%com_AC%ext(mpl,geom%nl0,ens%fld(:,:,iv,its,ie),fld_ext(:,:,iv,its))
145  end do
146 
147  do ib=1,bpar%nb
148  if (bpar%diag_block(ib)) then
149  ! Allocation
150  allocate(fld_1(samp%nc1a,bpar%nc3(ib),geom%nl0))
151  allocate(fld_2(samp%nc1a,bpar%nc3(ib),geom%nl0))
152 
153  ! Initialization
154  iv = bpar%b_to_v1(ib)
155  jv = bpar%b_to_v2(ib)
156  its = bpar%b_to_ts1(ib)
157  jts = bpar%b_to_ts2(ib)
158 
159  ! Copy valid field points
160  call msr(fld_1)
161  call msr(fld_2)
162  if ((iv/=jv).and.(its/=jts).and.nam%displ_diag) then
163  ! Interpolate zero separation points
164  !$omp parallel do schedule(static) private(il0)
165  do il0=1,geom%nl0
166  call samp%d(il0,its)%apply(mpl,fld_ext(:,il0,iv,its),fld_1(:,1,il0))
167  call samp%d(il0,jts)%apply(mpl,fld_ext(:,il0,jv,jts),fld_2(:,1,il0))
168  end do
169  !$omp end parallel do
170  else
171  ! Copy all separations points
172  !$omp parallel do schedule(static) private(il0,jc3,ic1a,ic1,ic0,jc0,ic0c,jc0c)
173  do il0=1,geom%nl0
174  do jc3=1,bpar%nc3(ib)
175  do ic1a=1,samp%nc1a
176  ! Indices
177  ic1 = samp%c1a_to_c1(ic1a)
178 
179  if (samp%c1l0_log(ic1,il0).and.samp%c1c3l0_log(ic1,jc3,il0)) then
180  ! Indices
181  ic0 = samp%c1_to_c0(ic1)
182  jc0 = samp%c1c3_to_c0(ic1,jc3)
183  ic0c = samp%c0_to_c0c(ic0)
184  jc0c = samp%c0_to_c0c(jc0)
185 
186  ! Copy points
187  fld_1(ic1a,jc3,il0) = fld_ext(ic0c,il0,iv,its)
188  fld_2(ic1a,jc3,il0) = fld_ext(jc0c,il0,jv,jts)
189  end if
190  end do
191  end do
192  end do
193  !$omp end parallel do
194  end if
195 
196  !$omp parallel do schedule(static) private(il0,jl0r,jl0)
197  do il0=1,geom%nl0
198  do jl0r=1,bpar%nl0r(ib)
199  jl0 = bpar%l0rl0b_to_l0(jl0r,il0,ib)
200 
201  ! Fourth-order moment
202  if (.not.nam%gau_approx) mom%blk(ib)%m22(:,:,jl0r,il0,isub) = mom%blk(ib)%m22(:,:,jl0r,il0,isub) &
203  & +fld_1(:,:,il0)**2*fld_2(:,:,jl0)**2
204 
205  ! Covariance
206  mom%blk(ib)%m11(:,:,jl0r,il0,isub) = mom%blk(ib)%m11(:,:,jl0r,il0,isub)+fld_1(:,:,il0)*fld_2(:,:,jl0)
207  end do
208  end do
209  !$omp end parallel do
210 
211  ! Variances
212  mom%blk(ib)%m2_1(:,:,:,isub) = mom%blk(ib)%m2_1(:,:,:,isub)+fld_1**2
213  mom%blk(ib)%m2_2(:,:,:,isub) = mom%blk(ib)%m2_2(:,:,:,isub)+fld_2**2
214 
215  ! Full variance
216  if (nam%var_full) mom%blk(ib)%m2full(:,:,isub) = mom%blk(ib)%m2full(:,:,isub)+ens%fld(:,:,iv,its,ie)**2
217 
218  ! Release memory
219  deallocate(fld_1)
220  deallocate(fld_2)
221  end if
222  end do
223 
224  ! Release memory
225  deallocate(fld_ext)
226  deallocate(mask_unpack)
227  end do
228  write(mpl%info,'(a)') ''
229  call flush(mpl%info)
230 end do
231 
232 ! Normalize moments
233 do ib=1,bpar%nb
234  if (bpar%diag_block(ib)) then
235  mom%blk(ib)%m2_1 = mom%blk(ib)%m2_1/real(mom%ne/mom%nsub-1,kind_real)
236  mom%blk(ib)%m2_2 = mom%blk(ib)%m2_2/real(mom%ne/mom%nsub-1,kind_real)
237  mom%blk(ib)%m11 = mom%blk(ib)%m11/real(mom%ne/mom%nsub-1,kind_real)
238  if (.not.nam%gau_approx) mom%blk(ib)%m22 = mom%blk(ib)%m22/real(mom%ne/mom%nsub,kind_real)
239  if (nam%var_full) mom%blk(ib)%m2full = mom%blk(ib)%m2full/real(mom%ne/mom%nsub-1,kind_real)
240  end if
241 end do
242 
243 end subroutine mom_compute
244 
245 end module type_mom
subroutine mom_compute(mom, mpl, nam, geom, bpar, samp, ens)
Definition: type_mom.F90:94
integer, parameter, public kind_real
subroutine mom_alloc(mom, nam, geom, bpar, samp, ne, nsub)
Definition: type_mom.F90:45