SURFEX v8.1
General documentation of Surfex
conserv_global_mass.F90
Go to the documentation of this file.
1 !SFX_LIC Copyright 1994-2014 CNRS, Meteo-France and Universite Paul Sabatier
2 !SFX_LIC This is part of the SURFEX software governed by the CeCILL-C licence
3 !SFX_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
4 !SFX_LIC for details. version 1.
5  SUBROUTINE conserv_global_mass (DTCO, U, NP, NPE, PMESH_SIZE, KPATCH, &
6  ILUOUT, PZDG, PZDG_OLD, HNAME, PFIELD_OLD)
7 !!
8 !!**** *CONSERV_GLOBAL_MASS* - routine to conserve global 3D mass (LAND USE case)
9 !!
10 !! PURPOSE
11 !! -------
12 !!
13 !! METHOD
14 !! ------
15 !!
16 !! EXTERNAL
17 !! --------
18 !!
19 !! IMPLICIT ARGUMENTS
20 !! ------------------
21 !!
22 !! REFERENCE
23 !! ---------
24 !!
25 !! AUTHOR
26 !! ------
27 !!
28 !! R. Alkama Meteo-France
29 !!
30 !! MODIFICATION
31 !! ------------
32 !! Original 07/2011
33 !!
34 !!
35 !!* 0. DECLARATION
36 ! -----------
37 !
38 !
39 !
41 USE modd_sfx_grid_n, ONLY : grid_t
43 USE modd_surf_atm_n, ONLY : surf_atm_t
44 !
45 USE modd_surf_par, ONLY : xundef
46 !
48 USE modi_get_surf_mask_n
49 !
50 USE modd_surfex_mpi, ONLY : nproc, nrank, npio, ncomm
52 !
53 USE yomhook ,ONLY : lhook, dr_hook
54 USE parkind1 ,ONLY : jprb
55 !
56 IMPLICIT NONE
57 !
58 #ifdef SFX_MPI
59 include "mpif.h"
60 #endif
61 !
62 !* 0.1 Declaration of arguments
63 ! ------------------------
64 !
65 !
66 TYPE(data_cover_t), INTENT(INOUT) :: DTCO
67 TYPE(surf_atm_t), INTENT(INOUT) :: U
68 TYPE(isba_np_t), INTENT(INOUT) :: NP
69 TYPE(isba_npe_t), INTENT(INOUT) :: NPE
70 REAL, DIMENSION(:), INTENT(IN) :: PMESH_SIZE
71 INTEGER, INTENT(IN) :: KPATCH
72 !
73 INTEGER, INTENT(IN ) :: ILUOUT
74 REAL, DIMENSION(:,:,:), INTENT(IN ) :: PFIELD_OLD,PZDG,PZDG_OLD
75  CHARACTER(LEN=3), INTENT(IN) :: HNAME
76 !
77 !* 0.2 Declaration of local variables
78 ! ------------------------------
79 !
80 TYPE(isba_p_t), POINTER :: PK
81 !
82 REAL, DIMENSION(U%NSIZE_NATURE,SIZE(NPE%AL(1)%XWG,2),KPATCH) :: ZFIELD0
83 REAL, DIMENSION(U%NSIZE_NATURE) :: ZFIELD,ZFIELD_OLD, ZFRAC_NAT
84 INTEGER, DIMENSION(SIZE(U%XNATURE)) :: IMASK ! mask for packing from complete field to nature field
85 INTEGER :: INI, IPATCH, IFULL, ILEV
86 INTEGER :: JLEV, JP, JJ ! loop counter
87 REAL :: ZRATIO_TOT, ZWORK1,ZWORK2
88 !
89 REAL, DIMENSION(:), ALLOCATABLE :: ZFIELD_TOT, ZFIELD_OLD_TOT, ZFRAC_NAT_TOT
90 INTEGER :: INFOMPI
91 !
92 REAL(KIND=JPRB) :: ZHOOK_HANDLE
93 !
94 !-------------------------------------------------------------------------------
95 !
96 IF (lhook) CALL dr_hook('CONSERV_GLOBAL_MASS',0,zhook_handle)
97 !
98 IF (trim(hname)=="WG") THEN
99  DO jp = 1,kpatch
100  zfield0(:,:,jp) = npe%AL(jp)%XWG(:,:)
101  ENDDO
102 ELSEIF (trim(hname)=="WGI") THEN
103  DO jp = 1,kpatch
104  zfield0(:,:,jp) = npe%AL(jp)%XWGI(:,:)
105  ENDDO
106 ENDIF
107 !
108 ini = SIZE(pzdg,1)
109 ilev = SIZE(pzdg,2)
110 ifull = SIZE(u%XNATURE )
111 !
112 zfrac_nat = 1.
113  CALL get_surf_mask_n(dtco, u, 'NATURE',ifull,imask,u%NSIZE_FULL,iluout)
114  CALL pack_same_rank(imask,u%XNATURE,zfrac_nat)
115 zfrac_nat(:)=zfrac_nat(:)*pmesh_size(:)
116 !
117 zfield(:) =0.0
118 zfield_old(:)=0.0
119 DO jp=1,kpatch
120  pk => np%AL(jp)
121  DO jlev=1,ilev
122  DO jj=1,pk%NSIZE_P
123  imask = pk%NR_P(jj)
124  !
125  zfield(imask) = zfield(imask) + zfield0(jj,jlev,jp)*pzdg(jj,jlev,jp)*pk%XPATCH(jj)
126  zfield_old(imask)= zfield_old(imask) + pfield_old(jj,jlev,jp)*pzdg_old(jj,jlev,jp)*pk%XPATCH_OLD(jj)
127  !
128  ENDDO
129  ENDDO
130 ENDDO
131 !
132 zwork1=0.0
133 zwork2=0.0
134 zratio_tot = 1.0
135 !
136 IF (nproc==1) THEN
137  DO jj=1,ini
138  zwork1=zwork1+zfield(jj)*zfrac_nat(jj)
139  zwork2=zwork2+zfield_old(jj)*zfrac_nat(jj)
140  ENDDO
141 ELSE
142  IF (nrank==npio) THEN
143  ALLOCATE(zfield_tot(u%NDIM_FULL),zfield_old_tot(u%NDIM_FULL),zfrac_nat_tot(u%NDIM_FULL))
144  ELSE
145  ALLOCATE(zfield_tot(0),zfield_old_tot(0),zfrac_nat_tot(0))
146  ENDIF
147  CALL gather_and_write_mpi(zfield,zfield_tot,u%NR_NATURE)
148  CALL gather_and_write_mpi(zfield_old,zfield_old_tot,u%NR_NATURE)
149  CALL gather_and_write_mpi(zfrac_nat,zfrac_nat_tot,u%NR_NATURE)
150  IF (nrank==npio) THEN
151  DO jj=1,u%NDIM_FULL
152  IF (zfield_tot(jj)/=xundef) THEN
153  zwork1=zwork1+zfield_tot(jj)*zfrac_nat_tot(jj)
154  zwork2=zwork2+zfield_old_tot(jj)*zfrac_nat_tot(jj)
155  ENDIF
156  ENDDO
157  ENDIF
158 #ifdef SFX_MPI
159  CALL mpi_bcast(zwork1,kind(zwork1)/4,mpi_real,npio,ncomm,infompi)
160  CALL mpi_bcast(zwork2,kind(zwork2)/4,mpi_real,npio,ncomm,infompi)
161 #endif
162  DEALLOCATE(zfield_tot,zfield_old_tot,zfrac_nat_tot)
163 ENDIF
164 !
165 IF(zwork2/= 0.)THEN
166  zratio_tot = zwork1/zwork2
167 ENDIF
168 !
169 WHERE(zfield0(:,:,:)/=xundef) zfield0(:,:,:)= zfield0(:,:,:) * zratio_tot
170 !
171 IF (trim(hname)=="WG") THEN
172  DO jp = 1,kpatch
173  npe%AL(jp)%XWG(:,:) = zfield0(:,:,jp)
174  ENDDO
175 ELSEIF (trim(hname)=="WGI") THEN
176  DO jp = 1,kpatch
177  npe%AL(jp)%XWGI(:,:) = zfield0(:,:,jp)
178  ENDDO
179 ENDIF
180 !
181 !-------------------------------------------------------------------------------
182 !
183 IF (lhook) CALL dr_hook('CONSERV_GLOBAL_MASS',1,zhook_handle)
184 !
185 !-------------------------------------------------------------------------------
186 !
187 END SUBROUTINE conserv_global_mass
real, parameter xundef
subroutine get_surf_mask_n(DTCO, U, HTYPE, KDIM, KMASK, KLU, KLUOUT)
integer, parameter jprb
Definition: parkind1.F90:32
subroutine conserv_global_mass(DTCO, U, NP, NPE, PMESH_SIZE, KPAT
logical lhook
Definition: yomhook.F90:15