9 use mom_coms,
only : query_efp_overflow_error, reset_efp_overflow_error
15 implicit none ;
private 17 #include <MOM_memory.h> 19 public :: global_i_mean, global_j_mean
20 public :: global_area_mean, global_layer_mean
21 public :: global_area_integral
22 public :: global_volume_mean, global_mass_integral
23 public :: adjust_area_mean_to_zero
28 function global_area_mean(var, G, scale)
30 real,
dimension(SZI_(G), SZJ_(G)),
intent(in) :: var
31 real,
optional,
intent(in) :: scale
33 real,
dimension(SZI_(G), SZJ_(G)) :: tmpforsumming
34 real :: global_area_mean
37 integer :: i, j, is, ie, js, je
38 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
40 scalefac = g%US%L_to_m**2 ;
if (
present(scale)) scalefac = g%US%L_to_m**2*scale
42 tmpforsumming(:,:) = 0.
43 do j=js,je ;
do i=is,ie
44 tmpforsumming(i,j) = var(i,j) * (scalefac * g%areaT(i,j) * g%mask2dT(i,j))
48 end function global_area_mean
52 function global_area_integral(var, G, scale, area)
54 real,
dimension(SZI_(G),SZJ_(G)),
intent(in) :: var
55 real,
optional,
intent(in) :: scale
56 real,
dimension(SZI_(G),SZJ_(G)),
optional,
intent(in) :: area
58 real :: global_area_integral
61 real,
dimension(SZI_(G),SZJ_(G)) :: tmpforsumming
63 integer :: i, j, is, ie, js, je
64 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
66 scalefac = g%US%L_to_m**2 ;
if (
present(scale)) scalefac = g%US%L_to_m**2*scale
68 tmpforsumming(:,:) = 0.
69 if (
present(area))
then 70 do j=js,je ;
do i=is,ie
71 tmpforsumming(i,j) = var(i,j) * (scalefac * area(i,j))
74 do j=js,je ;
do i=is,ie
75 tmpforsumming(i,j) = var(i,j) * (scalefac * g%areaT(i,j) * g%mask2dT(i,j))
80 end function global_area_integral
83 function global_layer_mean(var, h, G, GV, scale)
86 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(in) :: var
87 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(in) :: h
88 real,
optional,
intent(in) :: scale
89 real,
dimension(SZK_(GV)) :: global_layer_mean
91 real,
dimension(G%isc:G%iec, G%jsc:G%jec, SZK_(GV)) :: tmpforsumming, weight
92 type(
efp_type),
dimension(2*SZK_(GV)) :: laysums
93 real,
dimension(SZK_(GV)) :: global_temp_scalar, global_weight_scalar
95 integer :: i, j, k, is, ie, js, je, nz
96 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = gv%ke
98 scalefac = 1.0 ;
if (
present(scale)) scalefac = scale
99 tmpforsumming(:,:,:) = 0. ; weight(:,:,:) = 0.
101 do k=1,nz ;
do j=js,je ;
do i=is,ie
102 weight(i,j,k) = (gv%H_to_m * h(i,j,k)) * (g%US%L_to_m**2*g%areaT(i,j) * g%mask2dT(i,j))
103 tmpforsumming(i,j,k) = scalefac * var(i,j,k) * weight(i,j,k)
104 enddo ;
enddo ;
enddo 106 global_temp_scalar =
reproducing_sum(tmpforsumming, efp_lay_sums=laysums(1:nz), only_on_pe=.true.)
107 global_weight_scalar =
reproducing_sum(weight, efp_lay_sums=laysums(nz+1:2*nz), only_on_pe=.true.)
111 global_layer_mean(k) = efp_to_real(laysums(k)) / efp_to_real(laysums(nz+k))
114 end function global_layer_mean
117 function global_volume_mean(var, h, G, GV, scale)
120 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
122 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
124 real,
optional,
intent(in) :: scale
125 real :: global_volume_mean
129 real,
dimension(SZI_(G), SZJ_(G)) :: tmpforsumming, sum_weight
130 integer :: i, j, k, is, ie, js, je, nz
131 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = gv%ke
133 scalefac = 1.0 ;
if (
present(scale)) scalefac = scale
134 tmpforsumming(:,:) = 0. ; sum_weight(:,:) = 0.
136 do k=1,nz ;
do j=js,je ;
do i=is,ie
137 weight_here = (gv%H_to_m * h(i,j,k)) * (g%US%L_to_m**2*g%areaT(i,j) * g%mask2dT(i,j))
138 tmpforsumming(i,j) = tmpforsumming(i,j) + scalefac * var(i,j,k) * weight_here
139 sum_weight(i,j) = sum_weight(i,j) + weight_here
140 enddo ;
enddo ;
enddo 144 end function global_volume_mean
148 function global_mass_integral(h, G, GV, var, on_PE_only, scale)
151 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
153 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
154 optional,
intent(in) :: var
155 logical,
optional,
intent(in) :: on_pe_only
157 real,
optional,
intent(in) :: scale
158 real :: global_mass_integral
161 real,
dimension(SZI_(G), SZJ_(G)) :: tmpforsumming
163 logical :: global_sum
164 integer :: i, j, k, is, ie, js, je, nz
165 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = gv%ke
167 scalefac = g%US%L_to_m**2 ;
if (
present(scale)) scalefac = g%US%L_to_m**2*scale
168 tmpforsumming(:,:) = 0.0
170 if (
present(var))
then 171 do k=1,nz ;
do j=js,je ;
do i=is,ie
172 tmpforsumming(i,j) = tmpforsumming(i,j) + var(i,j,k) * &
173 ((gv%H_to_kg_m2 * h(i,j,k)) * (scalefac*g%areaT(i,j) * g%mask2dT(i,j)))
174 enddo ;
enddo ;
enddo 176 do k=1,nz ;
do j=js,je ;
do i=is,ie
177 tmpforsumming(i,j) = tmpforsumming(i,j) + &
178 ((gv%H_to_kg_m2 * h(i,j,k)) * (scalefac*g%areaT(i,j) * g%mask2dT(i,j)))
179 enddo ;
enddo ;
enddo 181 global_sum = .true. ;
if (
present(on_pe_only)) global_sum = .not.on_pe_only
185 global_mass_integral = 0.0
186 do j=js,je ;
do i=is,ie
187 global_mass_integral = global_mass_integral + tmpforsumming(i,j)
191 end function global_mass_integral
196 subroutine global_i_mean(array, i_mean, G, mask, scale, tmp_scale)
198 real,
dimension(SZI_(G),SZJ_(G)),
intent(in) :: array
199 real,
dimension(SZJ_(G)),
intent(out) :: i_mean
200 real,
dimension(SZI_(G),SZJ_(G)), &
201 optional,
intent(in) :: mask
202 real,
optional,
intent(in) :: scale
203 real,
optional,
intent(in) :: tmp_scale
207 type(
efp_type),
allocatable,
dimension(:) :: asum, mask_sum
211 integer :: is, ie, js, je, idg_off, jdg_off
214 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
215 idg_off = g%idg_offset ; jdg_off = g%jdg_offset
217 scalefac = 1.0 ;
if (
present(scale)) scalefac = scale
219 if (
present(tmp_scale))
then ;
if (tmp_scale /= 0.0)
then 220 scalefac = scalefac * tmp_scale ; unscale = 1.0 / tmp_scale
222 call reset_efp_overflow_error()
224 allocate(asum(g%jsg:g%jeg))
225 if (
present(mask))
then 226 allocate(mask_sum(g%jsg:g%jeg))
229 asum(j) = real_to_efp(0.0) ; mask_sum(j) = real_to_efp(0.0)
232 do i=is,ie ;
do j=js,je
233 asum(j+jdg_off) = asum(j+jdg_off) + real_to_efp(scalefac*array(i,j)*mask(i,j))
234 mask_sum(j+jdg_off) = mask_sum(j+jdg_off) + real_to_efp(mask(i,j))
237 if (query_efp_overflow_error())
call mom_error(fatal, &
238 "global_i_mean overflow error occurred before sums across PEs.")
243 if (query_efp_overflow_error())
call mom_error(fatal, &
244 "global_i_mean overflow error occurred during sums across PEs.")
247 mask_sum_r = efp_to_real(mask_sum(j+jdg_off))
248 if (mask_sum_r == 0.0 )
then ; i_mean(j) = 0.0 ;
else 249 i_mean(j) = efp_to_real(asum(j+jdg_off)) / mask_sum_r
255 do j=g%jsg,g%jeg ; asum(j) = real_to_efp(0.0) ;
enddo 257 do i=is,ie ;
do j=js,je
258 asum(j+jdg_off) = asum(j+jdg_off) + real_to_efp(scalefac*array(i,j))
261 if (query_efp_overflow_error())
call mom_error(fatal, &
262 "global_i_mean overflow error occurred before sum across PEs.")
266 if (query_efp_overflow_error())
call mom_error(fatal, &
267 "global_i_mean overflow error occurred during sum across PEs.")
270 i_mean(j) = efp_to_real(asum(j+jdg_off)) /
real(g%ieg-g%isg+1)
274 if (unscale /= 1.0)
then ;
do j=js,je ; i_mean(j) = unscale*i_mean(j) ;
enddo ;
endif 278 end subroutine global_i_mean
282 subroutine global_j_mean(array, j_mean, G, mask, scale, tmp_scale)
284 real,
dimension(SZI_(G),SZJ_(G)),
intent(in) :: array
285 real,
dimension(SZI_(G)),
intent(out) :: j_mean
286 real,
dimension(SZI_(G),SZJ_(G)), &
287 optional,
intent(in) :: mask
288 real,
optional,
intent(in) :: scale
289 real,
optional,
intent(in) :: tmp_scale
293 type(
efp_type),
allocatable,
dimension(:) :: asum, mask_sum
297 integer :: is, ie, js, je, idg_off, jdg_off
300 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
301 idg_off = g%idg_offset ; jdg_off = g%jdg_offset
303 scalefac = 1.0 ;
if (
present(scale)) scalefac = scale
305 if (
present(tmp_scale))
then ;
if (tmp_scale /= 0.0)
then 306 scalefac = scalefac * tmp_scale ; unscale = 1.0 / tmp_scale
308 call reset_efp_overflow_error()
310 allocate(asum(g%isg:g%ieg))
311 if (
present(mask))
then 312 allocate (mask_sum(g%isg:g%ieg))
315 asum(i) = real_to_efp(0.0) ; mask_sum(i) = real_to_efp(0.0)
318 do i=is,ie ;
do j=js,je
319 asum(i+idg_off) = asum(i+idg_off) + real_to_efp(scalefac*array(i,j)*mask(i,j))
320 mask_sum(i+idg_off) = mask_sum(i+idg_off) + real_to_efp(mask(i,j))
323 if (query_efp_overflow_error())
call mom_error(fatal, &
324 "global_j_mean overflow error occurred before sums across PEs.")
329 if (query_efp_overflow_error())
call mom_error(fatal, &
330 "global_j_mean overflow error occurred during sums across PEs.")
333 mask_sum_r = efp_to_real(mask_sum(i+idg_off))
334 if (mask_sum_r == 0.0 )
then ; j_mean(i) = 0.0 ;
else 335 j_mean(i) = efp_to_real(asum(i+idg_off)) / mask_sum_r
341 do i=g%isg,g%ieg ; asum(i) = real_to_efp(0.0) ;
enddo 343 do i=is,ie ;
do j=js,je
344 asum(i+idg_off) = asum(i+idg_off) + real_to_efp(scalefac*array(i,j))
347 if (query_efp_overflow_error())
call mom_error(fatal, &
348 "global_j_mean overflow error occurred before sum across PEs.")
352 if (query_efp_overflow_error())
call mom_error(fatal, &
353 "global_j_mean overflow error occurred during sum across PEs.")
356 j_mean(i) = efp_to_real(asum(i+idg_off)) /
real(g%jeg-g%jsg+1)
360 if (unscale /= 1.0)
then ;
do i=is,ie ; j_mean(i) = unscale*j_mean(i) ;
enddo ;
endif 364 end subroutine global_j_mean
367 subroutine adjust_area_mean_to_zero(array, G, scaling, unit_scale)
369 real,
dimension(SZI_(G),SZJ_(G)),
intent(inout) :: array
370 real,
optional,
intent(out) :: scaling
371 real,
optional,
intent(in) :: unit_scale
373 real,
dimension(G%isc:G%iec, G%jsc:G%jec) :: posvals, negvals, areaxposvals, areaxnegvals
375 type(
efp_type),
dimension(2) :: areaint_efp
378 real :: areaintposvals, areaintnegvals, posscale, negscale
380 scalefac = 1.0 ;
if (
present(unit_scale)) scalefac = unit_scale
381 i_scalefac = 0.0 ;
if (scalefac /= 0.0) i_scalefac = 1.0 / scalefac
386 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
387 posvals(i,j) = max(0., scalefac*array(i,j))
388 areaxposvals(i,j) = g%US%L_to_m**2*g%areaT(i,j) * posvals(i,j)
389 negvals(i,j) = min(0., scalefac*array(i,j))
390 areaxnegvals(i,j) = g%US%L_to_m**2*g%areaT(i,j) * negvals(i,j)
397 areaintposvals = efp_to_real( areaint_efp(1) )
398 areaintnegvals = efp_to_real( areaint_efp(2) )
400 posscale = 0.0 ; negscale = 0.0
401 if ((areaintposvals>0.).and.(areaintnegvals<0.))
then 402 if (areaintposvals>-areaintnegvals)
then 403 posscale = - areaintnegvals / areaintposvals
404 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
405 array(i,j) = ((posscale * posvals(i,j)) + negvals(i,j)) * i_scalefac
407 elseif (areaintposvals<-areaintnegvals)
then 408 negscale = - areaintposvals / areaintnegvals
409 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
410 array(i,j) = (posvals(i,j) + (negscale * negvals(i,j))) * i_scalefac
414 if (
present(scaling)) scaling = posscale - negscale
416 end subroutine adjust_area_mean_to_zero
Functions and routines to take area, volume, mass-weighted, layerwise, zonal or meridional means...
Ocean grid type. See mom_grid for details.
Sum a value or 1-d array of values across processors, returning the sums in place.
A structure that can be parsed to read and document run-time parameters.
Provides the ocean grid type.
The MOM6 facility to parse input files for runtime parameters.
Interfaces to non-domain-oriented communication subroutines, including the MOM6 reproducing sums faci...
Routines for error handling and I/O management.
An overloaded interface to log version information about modules.
Describes the vertical ocean grid, including unit conversion factors.
Find an accurate and order-invariant sum of a distributed 2d or 3d field.
Find an accurate and order-invariant sum of a distributed 2d field, returning the result in the form ...
Provides a transparent vertical ocean grid type and supporting routines.
An overloaded interface to read and log the values of various types of parameters.
The Extended Fixed Point (EFP) type provides a public interface for doing sums and taking differences...