source: trunk/LMDZ.COMMON/libf/dynphy_lonlat/inigeomphy_mod.F90 @ 1573

Last change on this file since 1573 was 1573, checked in by emillour, 8 years ago

All GCMS:
Cleanup concerning iniphysiq/inigeomphy initializations: initializations
related to routines in phy_common or dynphy_lonlat can be done in
inigeomphy, but any initialization for modules/routines in a physics
package (directory phy*) must be done in the related phy*/iniphysiq
routine.
EM

File size: 8.7 KB
Line 
1MODULE inigeomphy_mod
2
3CONTAINS
4
5SUBROUTINE inigeomphy(iim,jjm,nlayer, &
6                     nbp, communicator, &
7                     rlatu,rlatv,rlonu,rlonv,aire,cu,cv)
8  USE mod_grid_phy_lmdz, ONLY: klon_glo,  & ! number of atmospheric columns (on full grid)
9                               regular_lonlat, &  ! regular longitude-latitude grid type
10                               nbp_lon, nbp_lat, nbp_lev
11  USE mod_phys_lmdz_para, ONLY: klon_omp, & ! number of columns (on local omp grid)
12                                klon_omp_begin, & ! start index of local omp subgrid
13                                klon_omp_end, & ! end index of local omp subgrid
14                                klon_mpi_begin ! start indes of columns (on local mpi grid)
15  USE geometry_mod, ONLY : init_geometry
16  USE physics_distribution_mod, ONLY : init_physics_distribution
17  USE regular_lonlat_mod, ONLY : init_regular_lonlat, &
18                                 east, west, north, south, &
19                                 north_east, north_west, &
20                                 south_west, south_east
21  USE mod_interface_dyn_phys, ONLY :  init_interface_dyn_phys
22  USE nrtype, ONLY: pi
23  IMPLICIT NONE
24
25  ! =======================================================================
26  ! Initialisation of the physical constants and some positional and
27  ! geometrical arrays for the physics
28  ! =======================================================================
29
30  include "iniprint.h"
31
32  INTEGER, INTENT (IN) :: nlayer ! number of atmospheric layers
33  INTEGER, INTENT (IN) :: iim ! number of atmospheric columns along longitudes
34  INTEGER, INTENT (IN) :: jjm ! number of atompsheric columns along latitudes
35  INTEGER, INTENT(IN) :: nbp ! number of physics columns for this MPI process
36  INTEGER, INTENT(IN) :: communicator ! MPI communicator
37  REAL, INTENT (IN) :: rlatu(jjm+1) ! latitudes of the physics grid
38  REAL, INTENT (IN) :: rlatv(jjm) ! latitude boundaries of the physics grid
39  REAL, INTENT (IN) :: rlonv(iim+1) ! longitudes of the physics grid
40  REAL, INTENT (IN) :: rlonu(iim+1) ! longitude boundaries of the physics grid
41  REAL, INTENT (IN) :: aire(iim+1,jjm+1) ! area of the dynamics grid (m2)
42  REAL, INTENT (IN) :: cu((iim+1)*(jjm+1)) ! cu coeff. (u_covariant = cu * u)
43  REAL, INTENT (IN) :: cv((iim+1)*jjm) ! cv coeff. (v_covariant = cv * v)
44
45  INTEGER :: ibegin, iend, offset
46  INTEGER :: i,j,k
47  CHARACTER (LEN=20) :: modname = 'iniphysiq'
48  CHARACTER (LEN=80) :: abort_message
49  REAL :: total_area_phy, total_area_dyn
50
51  ! boundaries, on global grid
52  REAL,ALLOCATABLE :: boundslon_reg(:,:)
53  REAL,ALLOCATABLE :: boundslat_reg(:,:)
54
55  ! global array, on full physics grid:
56  REAL,ALLOCATABLE :: latfi_glo(:)
57  REAL,ALLOCATABLE :: lonfi_glo(:)
58  REAL,ALLOCATABLE :: cufi_glo(:)
59  REAL,ALLOCATABLE :: cvfi_glo(:)
60  REAL,ALLOCATABLE :: airefi_glo(:)
61  REAL,ALLOCATABLE :: boundslonfi_glo(:,:)
62  REAL,ALLOCATABLE :: boundslatfi_glo(:,:)
63
64  ! local arrays, on given MPI/OpenMP domain:
65  REAL,ALLOCATABLE,SAVE :: latfi(:)
66  REAL,ALLOCATABLE,SAVE :: lonfi(:)
67  REAL,ALLOCATABLE,SAVE :: cufi(:)
68  REAL,ALLOCATABLE,SAVE :: cvfi(:)
69  REAL,ALLOCATABLE,SAVE :: airefi(:)
70  REAL,ALLOCATABLE,SAVE :: boundslonfi(:,:)
71  REAL,ALLOCATABLE,SAVE :: boundslatfi(:,:)
72!$OMP THREADPRIVATE (latfi,lonfi,cufi,cvfi,airefi,boundslonfi,boundslatfi)
73
74  ! Initialize Physics distibution and parameters and interface with dynamics
75  IF (iim*jjm>1) THEN ! general 3D case
76    CALL init_physics_distribution(regular_lonlat,4, &
77                                 nbp,iim,jjm+1,nlayer,communicator)
78  ELSE ! For 1D model
79    CALL init_physics_distribution(regular_lonlat,4, &
80                                 1,1,1,nlayer,communicator)
81  ENDIF
82  CALL init_interface_dyn_phys
83 
84  ! init regular global longitude-latitude grid points and boundaries
85  ALLOCATE(boundslon_reg(iim,2))
86  ALLOCATE(boundslat_reg(jjm+1,2))
87 
88  DO i=1,iim
89   boundslon_reg(i,east)=rlonu(i)
90   boundslon_reg(i,west)=rlonu(i+1)
91  ENDDO
92
93  boundslat_reg(1,north)= PI/2
94  boundslat_reg(1,south)= rlatv(1)
95  DO j=2,jjm
96   boundslat_reg(j,north)=rlatv(j-1)
97   boundslat_reg(j,south)=rlatv(j)
98  ENDDO
99  boundslat_reg(jjm+1,north)= rlatv(jjm)
100  boundslat_reg(jjm+1,south)= -PI/2
101
102  ! Write values in module regular_lonlat_mod
103  CALL init_regular_lonlat(iim,jjm+1, rlonv(1:iim), rlatu, &
104                           boundslon_reg, boundslat_reg)
105
106  ! Generate global arrays on full physics grid
107  ALLOCATE(latfi_glo(klon_glo),lonfi_glo(klon_glo))
108  ALLOCATE(cufi_glo(klon_glo),cvfi_glo(klon_glo))
109  ALLOCATE(airefi_glo(klon_glo))
110  ALLOCATE(boundslonfi_glo(klon_glo,4))
111  ALLOCATE(boundslatfi_glo(klon_glo,4))
112
113  IF (klon_glo>1) THEN ! general case
114    ! North pole
115    latfi_glo(1)=rlatu(1)
116    lonfi_glo(1)=0.
117    cufi_glo(1) = cu(1)
118    cvfi_glo(1) = cv(1)
119    boundslonfi_glo(1,north_east)=0
120    boundslatfi_glo(1,north_east)=PI/2
121    boundslonfi_glo(1,north_west)=2*PI
122    boundslatfi_glo(1,north_west)=PI/2
123    boundslonfi_glo(1,south_west)=2*PI
124    boundslatfi_glo(1,south_west)=rlatv(1)
125    boundslonfi_glo(1,south_east)=0
126    boundslatfi_glo(1,south_east)=rlatv(1)
127    DO j=2,jjm
128      DO i=1,iim
129        k=(j-2)*iim+1+i
130        latfi_glo(k)= rlatu(j)
131        lonfi_glo(k)= rlonv(i)
132        cufi_glo(k) = cu((j-1)*(iim+1)+i)
133        cvfi_glo(k) = cv((j-1)*(iim+1)+i)
134        boundslonfi_glo(k,north_east)=rlonu(i)
135        boundslatfi_glo(k,north_east)=rlatv(j-1)
136        boundslonfi_glo(k,north_west)=rlonu(i+1)
137        boundslatfi_glo(k,north_west)=rlatv(j-1)
138        boundslonfi_glo(k,south_west)=rlonu(i+1)
139        boundslatfi_glo(k,south_west)=rlatv(j)
140        boundslonfi_glo(k,south_east)=rlonu(i)
141        boundslatfi_glo(k,south_east)=rlatv(j)
142      ENDDO
143    ENDDO
144    ! South pole
145    latfi_glo(klon_glo)= rlatu(jjm+1)
146    lonfi_glo(klon_glo)= 0.
147    cufi_glo(klon_glo) = cu((iim+1)*jjm+1)
148    cvfi_glo(klon_glo) = cv((iim+1)*jjm-iim)
149    boundslonfi_glo(klon_glo,north_east)= 0
150    boundslatfi_glo(klon_glo,north_east)= rlatv(jjm)
151    boundslonfi_glo(klon_glo,north_west)= 2*PI
152    boundslatfi_glo(klon_glo,north_west)= rlatv(jjm)
153    boundslonfi_glo(klon_glo,south_west)= 2*PI
154    boundslatfi_glo(klon_glo,south_west)= -PI/2
155    boundslonfi_glo(klon_glo,south_east)= 0
156    boundslatfi_glo(klon_glo,south_east)= -Pi/2
157
158    ! build airefi(), mesh area on physics grid
159    CALL gr_dyn_fi(1,iim+1,jjm+1,klon_glo,aire,airefi_glo)
160    ! Poles are single points on physics grid
161    airefi_glo(1)=sum(aire(1:iim,1))
162    airefi_glo(klon_glo)=sum(aire(1:iim,jjm+1))
163
164    ! Sanity check: do total planet area match between physics and dynamics?
165    total_area_dyn=sum(aire(1:iim,1:jjm+1))
166    total_area_phy=sum(airefi_glo(1:klon_glo))
167    IF (total_area_dyn/=total_area_phy) THEN
168      WRITE (lunout, *) 'iniphysiq: planet total surface discrepancy !!!'
169      WRITE (lunout, *) '     in the dynamics total_area_dyn=', total_area_dyn
170      WRITE (lunout, *) '  but in the physics total_area_phy=', total_area_phy
171      IF (abs(total_area_dyn-total_area_phy)>0.00001*total_area_dyn) THEN
172        ! stop here if the relative difference is more than 0.001%
173        abort_message = 'planet total surface discrepancy'
174        CALL abort_gcm(modname, abort_message, 1)
175      ENDIF
176    ENDIF
177  ELSE ! klon_glo==1, running the 1D model
178    ! just copy over input values
179    latfi_glo(1)=rlatu(1)
180    lonfi_glo(1)=rlonv(1)
181    cufi_glo(1)=cu(1)
182    cvfi_glo(1)=cv(1)
183    airefi_glo(1)=aire(1,1)
184    boundslonfi_glo(1,north_east)=rlonu(1)
185    boundslatfi_glo(1,north_east)=PI/2
186    boundslonfi_glo(1,north_west)=rlonu(2)
187    boundslatfi_glo(1,north_west)=PI/2
188    boundslonfi_glo(1,south_west)=rlonu(2)
189    boundslatfi_glo(1,south_west)=rlatv(1)
190    boundslonfi_glo(1,south_east)=rlonu(1)
191    boundslatfi_glo(1,south_east)=rlatv(1)
192  ENDIF ! of IF (klon_glo>1)
193
194!$OMP PARALLEL
195  ! Now generate local lon/lat/cu/cv/area/bounds arrays
196  ALLOCATE(latfi(klon_omp),lonfi(klon_omp),cufi(klon_omp),cvfi(klon_omp))
197  ALLOCATE(airefi(klon_omp))
198  ALLOCATE(boundslonfi(klon_omp,4))
199  ALLOCATE(boundslatfi(klon_omp,4))
200!  CALL initcomgeomphy
201
202  offset = klon_mpi_begin - 1
203  airefi(1:klon_omp) = airefi_glo(offset+klon_omp_begin:offset+klon_omp_end)
204  cufi(1:klon_omp) = cufi_glo(offset+klon_omp_begin:offset+klon_omp_end)
205  cvfi(1:klon_omp) = cvfi_glo(offset+klon_omp_begin:offset+klon_omp_end)
206  lonfi(1:klon_omp) = lonfi_glo(offset+klon_omp_begin:offset+klon_omp_end)
207  latfi(1:klon_omp) = latfi_glo(offset+klon_omp_begin:offset+klon_omp_end)
208  boundslonfi(1:klon_omp,:) = boundslonfi_glo(offset+klon_omp_begin:offset+klon_omp_end,:)
209  boundslatfi(1:klon_omp,:) = boundslatfi_glo(offset+klon_omp_begin:offset+klon_omp_end,:)
210
211  ! copy over local grid longitudes and latitudes
212  CALL init_geometry(klon_omp,lonfi,latfi,boundslonfi,boundslatfi, &
213                     airefi,cufi,cvfi)
214
215!$OMP END PARALLEL
216
217
218END SUBROUTINE inigeomphy
219
220END MODULE inigeomphy_mod
Note: See TracBrowser for help on using the repository browser.