source: LMDZ6/trunk/libf/phylmd/surf_land_orchidee_noz0h_mod.F90 @ 5274

Last change on this file since 5274 was 5274, checked in by abarral, 31 hours ago

Replace yomcst.h by existing module

  • Property copyright set to
    Name of program: LMDZ
    Creation date: 1984
    Version: LMDZ5
    License: CeCILL version 2
    Holder: Laboratoire de m\'et\'eorologie dynamique, CNRS, UMR 8539
    See the license file in the root directory
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.1 KB
Line 
1!
2MODULE surf_land_orchidee_noz0h_mod
3#ifdef ORCHIDEE_NOZ0H
4!
5! This module controles the interface towards the model ORCHIDEE.
6!
7! Compatibility with ORCHIDIEE :
8! This module is compiled only if CPP key ORCHIDEE_NOZ0H is defined.
9! This version can be used with ORCHIDEE/trunk revision 2961-3525.
10! It is possible to use this interface with later versions of ORCHIDEE/trunk than 3525 but
11! in that case the option ROUGH_DYN=y in ORCHIDEE should not be set.
12! This interface can also be used with ORCHIDEE/trunk revision 1078-2960 if changing
13! coszang=yrmu0 into sinang=yrmu0 at 2 places later below in this module.
14!
15! Subroutines in this module : surf_land_orchidee
16!                              Init_orchidee_index
17!                              Get_orchidee_communicator
18!                              Init_neighbours
19
20  USE dimphy
21#ifdef CPP_VEGET
22  USE intersurf     ! module d'ORCHIDEE
23#endif
24  USE cpl_mod,      ONLY : cpl_send_land_fields
25  USE surface_data, ONLY : type_ocean
26  USE geometry_mod, ONLY : dx, dy
27  USE mod_grid_phy_lmdz
28  USE mod_phys_lmdz_para, mpi_root_rank=>mpi_master
29
30  IMPLICIT NONE
31
32  PRIVATE
33  PUBLIC  :: surf_land_orchidee
34
35CONTAINS
36!
37!****************************************************************************************
38
39  SUBROUTINE surf_land_orchidee(itime, dtime, date0, knon, &
40       knindex, rlon, rlat, yrmu0, pctsrf, &
41       debut, lafin, &
42       plev,  u1_lay, v1_lay, gustiness, temp_air, spechum, epot_air, ccanopy, &
43       tq_cdrag, petAcoef, peqAcoef, petBcoef, peqBcoef, &
44       precip_rain, precip_snow, lwdown, swnet, swdown, &
45       ps, q2m, t2m, &
46       evap, fluxsens, fluxlat, &             
47       tsol_rad, tsurf_new, alb1_new, alb2_new, &
48       emis_new, z0_new, z0h_new, qsurf, &
49       veget, lai, height)
50
51    USE mod_surf_para
52    USE mod_synchro_omp
53    USE carbon_cycle_mod, ONLY : carbon_cycle_cpl
54    USE indice_sol_mod
55    USE print_control_mod, ONLY: lunout
56    USE mod_grid_phy_lmdz, ONLY: nbp_lon, nbp_lat
57#ifdef CPP_VEGET
58    USE time_phylmdz_mod, ONLY: itau_phy
59#endif
60    USE yomcst_mod_h, ONLY: RPI, RCLUM, RHPLA, RKBOL, RNAVO                   &
61          , RDAY, REA, REPSM, RSIYEA, RSIDAY, ROMEGA                  &
62          , R_ecc, R_peri, R_incl                                      &
63          , RA, RG, R1SA                                         &
64          , RSIGMA                                                     &
65          , R, RMD, RMV, RD, RV, RCPD                    &
66          , RMO3, RMCO2, RMC, RMCH4, RMN2O, RMCFC11, RMCFC12        &
67          , RCPV, RCVD, RCVV, RKAPPA, RETV, eps_w                    &
68          , RCW, RCS                                                 &
69          , RLVTT, RLSTT, RLMLT, RTT, RATM                           &
70          , RESTT, RALPW, RBETW, RGAMW, RALPS, RBETS, RGAMS            &
71          , RALPD, RBETD, RGAMD
72!   
73! Cette routine sert d'interface entre le modele atmospherique et le
74! modele de sol continental. Appel a sechiba
75!
76! L. Fairhead 02/2000
77!
78! input:
79!   itime        numero du pas de temps
80!   dtime        pas de temps de la physique (en s)
81!   nisurf       index de la surface a traiter (1 = sol continental)
82!   knon         nombre de points de la surface a traiter
83!   knindex      index des points de la surface a traiter
84!   rlon         longitudes de la grille entiere
85!   rlat         latitudes de la grille entiere
86!   pctsrf       tableau des fractions de surface de chaque maille
87!   debut        logical: 1er appel a la physique (lire les restart)
88!   lafin        logical: dernier appel a la physique (ecrire les restart)
89!                     (si false calcul simplifie des fluxs sur les continents)
90!   plev         hauteur de la premiere couche (Pa)     
91!   u1_lay       vitesse u 1ere couche
92!   v1_lay       vitesse v 1ere couche
93!   temp_air     temperature de l'air 1ere couche
94!   spechum      humidite specifique 1ere couche
95!   epot_air     temp pot de l'air
96!   ccanopy      concentration CO2 canopee, correspond au co2_send de
97!                carbon_cycle_mod ou valeur constant co2_ppm
98!   tq_cdrag     cdrag
99!   petAcoef     coeff. A de la resolution de la CL pour t
100!   peqAcoef     coeff. A de la resolution de la CL pour q
101!   petBcoef     coeff. B de la resolution de la CL pour t
102!   peqBcoef     coeff. B de la resolution de la CL pour q
103!   precip_rain  precipitation liquide
104!   precip_snow  precipitation solide
105!   lwdown       flux IR descendant a la surface
106!   swnet        flux solaire net
107!   swdown       flux solaire entrant a la surface
108!   ps           pression au sol
109!   radsol       rayonnement net aus sol (LW + SW)
110!   
111!
112! output:
113!   evap         evaporation totale
114!   fluxsens     flux de chaleur sensible
115!   fluxlat      flux de chaleur latente
116!   tsol_rad     
117!   tsurf_new    temperature au sol
118!   alb1_new     albedo in visible SW interval
119!   alb2_new     albedo in near IR interval
120!   emis_new     emissivite
121!   z0_new       surface roughness
122!   z0h_new      surface roughness, it is a copy from z0_new
123!   qsurf        air moisture at surface
124!
125    INCLUDE "dimpft.h"
126    INCLUDE "compbl.h"
127!
128! Parametres d'entree
129!****************************************************************************************
130    INTEGER, INTENT(IN)                       :: itime
131    REAL, INTENT(IN)                          :: dtime
132    REAL, INTENT(IN)                          :: date0
133    INTEGER, INTENT(IN)                       :: knon
134    INTEGER, DIMENSION(klon), INTENT(IN)      :: knindex
135    LOGICAL, INTENT(IN)                       :: debut, lafin
136    REAL, DIMENSION(klon,nbsrf), INTENT(IN)   :: pctsrf
137    REAL, DIMENSION(klon), INTENT(IN)         :: rlon, rlat
138    REAL, DIMENSION(klon), INTENT(IN)         :: yrmu0 ! cosine of solar zenith angle
139    REAL, DIMENSION(klon), INTENT(IN)         :: plev
140    REAL, DIMENSION(klon), INTENT(IN)         :: u1_lay, v1_lay, gustiness
141    REAL, DIMENSION(klon), INTENT(IN)         :: temp_air, spechum
142    REAL, DIMENSION(klon), INTENT(IN)         :: epot_air, ccanopy
143    REAL, DIMENSION(klon), INTENT(IN)         :: tq_cdrag
144    REAL, DIMENSION(klon), INTENT(IN)         :: petAcoef, peqAcoef
145    REAL, DIMENSION(klon), INTENT(IN)         :: petBcoef, peqBcoef
146    REAL, DIMENSION(klon), INTENT(IN)         :: precip_rain, precip_snow
147    REAL, DIMENSION(klon), INTENT(IN)         :: lwdown, swnet, swdown, ps
148    REAL, DIMENSION(klon), INTENT(IN)         :: q2m, t2m
149
150! Parametres de sortie
151!****************************************************************************************
152    REAL, DIMENSION(klon), INTENT(OUT)        :: evap, fluxsens, fluxlat, qsurf
153    REAL, DIMENSION(klon), INTENT(OUT)        :: tsol_rad, tsurf_new
154    REAL, DIMENSION(klon), INTENT(OUT)        :: alb1_new, alb2_new
155    REAL, DIMENSION(klon), INTENT(OUT)        :: emis_new, z0_new, z0h_new
156    REAL, DIMENSION(klon,nvm_lmdz), INTENT(OUT) :: veget ! dummy variables
157    REAL, DIMENSION(klon,nvm_lmdz), INTENT(OUT) :: lai   ! dummy variables
158    REAL, DIMENSION(klon,nvm_lmdz), INTENT(OUT) :: height! dummy variables
159
160! Local
161!****************************************************************************************
162    INTEGER                                   :: ij, jj, igrid, ireal, index
163    INTEGER                                   :: error
164    REAL, DIMENSION(klon)                     :: swdown_vrai
165    CHARACTER (len = 20)                      :: modname = 'surf_land_orchidee'
166    CHARACTER (len = 80)                      :: abort_message
167    LOGICAL,SAVE                              :: check = .FALSE.
168    !$OMP THREADPRIVATE(check)
169
170! type de couplage dans sechiba
171!  character (len=10)   :: coupling = 'implicit'
172! drapeaux controlant les appels dans SECHIBA
173!  type(control_type), save   :: control_in
174! Preserved albedo
175    REAL, ALLOCATABLE, DIMENSION(:), SAVE     :: albedo_keep, zlev
176    !$OMP THREADPRIVATE(albedo_keep,zlev)
177! coordonnees geographiques
178    REAL, ALLOCATABLE, DIMENSION(:,:), SAVE   :: lalo
179    !$OMP THREADPRIVATE(lalo)
180! pts voisins
181    INTEGER,ALLOCATABLE, DIMENSION(:,:), SAVE :: neighbours
182    !$OMP THREADPRIVATE(neighbours)
183! fractions continents
184    REAL,ALLOCATABLE, DIMENSION(:), SAVE      :: contfrac
185    !$OMP THREADPRIVATE(contfrac)
186! resolution de la grille
187    REAL, ALLOCATABLE, DIMENSION (:,:), SAVE  :: resolution
188    !$OMP THREADPRIVATE(resolution)
189
190    REAL, ALLOCATABLE, DIMENSION (:,:), SAVE  :: lon_scat, lat_scat 
191    !$OMP THREADPRIVATE(lon_scat,lat_scat)
192
193    LOGICAL, SAVE                             :: lrestart_read = .TRUE.
194    !$OMP THREADPRIVATE(lrestart_read)
195    LOGICAL, SAVE                             :: lrestart_write = .FALSE.
196    !$OMP THREADPRIVATE(lrestart_write)
197
198    REAL, DIMENSION(knon,2)                   :: albedo_out
199
200! Pb de nomenclature
201    REAL, DIMENSION(klon)                     :: petA_orc, peqA_orc
202    REAL, DIMENSION(klon)                     :: petB_orc, peqB_orc
203! Pb de correspondances de grilles
204    INTEGER, DIMENSION(:), SAVE, ALLOCATABLE  :: ig, jg
205    !$OMP THREADPRIVATE(ig,jg)
206    INTEGER :: indi, indj
207    INTEGER, SAVE, ALLOCATABLE,DIMENSION(:)   :: ktindex
208    !$OMP THREADPRIVATE(ktindex)
209
210! Essai cdrag
211    REAL, DIMENSION(klon)                     :: cdrag
212    INTEGER,SAVE                              :: offset
213    !$OMP THREADPRIVATE(offset)
214
215    REAL, DIMENSION(klon_glo)                 :: rlon_g,rlat_g
216    INTEGER, SAVE                             :: orch_comm
217    !$OMP THREADPRIVATE(orch_comm)
218
219    REAL, ALLOCATABLE, DIMENSION(:), SAVE     :: coastalflow
220    !$OMP THREADPRIVATE(coastalflow)
221    REAL, ALLOCATABLE, DIMENSION(:), SAVE     :: riverflow
222    !$OMP THREADPRIVATE(riverflow)
223   
224    INTEGER :: orch_omp_rank
225    INTEGER :: orch_omp_size
226!
227! Fin definition
228!****************************************************************************************
229
230    IF (check) WRITE(lunout,*)'Entree ', modname
231
232    IF (ifl_pbltree == 1) THEN
233       abort_message='Pb de coherence: cette interface vers ORCHIDEE ne peut pas etre utilise avec ifl_pbltree'
234       CALL abort_physic(modname,abort_message,1)
235    END IF
236 
237! Initialisation
238 
239    IF (debut) THEN
240! Test of coherence between variable ok_veget and cpp key CPP_VEGET
241#ifndef CPP_VEGET
242       abort_message='Pb de coherence: ok_veget = .true. mais CPP_VEGET = .false.'
243       CALL abort_physic(modname,abort_message,1)
244#endif
245
246       CALL Init_surf_para(knon)
247       ALLOCATE(ktindex(knon))
248       IF ( .NOT. ALLOCATED(albedo_keep)) THEN
249!ym          ALLOCATE(albedo_keep(klon))
250!ym bizarre que non allou� en knon precedement
251          ALLOCATE(albedo_keep(knon))
252          ALLOCATE(zlev(knon))
253       ENDIF
254! Pb de correspondances de grilles
255       ALLOCATE(ig(klon))
256       ALLOCATE(jg(klon))
257       ig(1) = 1
258       jg(1) = 1
259       indi = 0
260       indj = 2
261       DO igrid = 2, klon - 1
262          indi = indi + 1
263          IF ( indi > nbp_lon) THEN
264             indi = 1
265             indj = indj + 1
266          ENDIF
267          ig(igrid) = indi
268          jg(igrid) = indj
269       ENDDO
270       ig(klon) = 1
271       jg(klon) = nbp_lat
272
273       IF ((.NOT. ALLOCATED(lalo))) THEN
274          ALLOCATE(lalo(knon,2), stat = error)
275          IF (error /= 0) THEN
276             abort_message='Pb allocation lalo'
277             CALL abort_physic(modname,abort_message,1)
278          ENDIF
279       ENDIF
280       IF ((.NOT. ALLOCATED(lon_scat))) THEN
281          ALLOCATE(lon_scat(nbp_lon,nbp_lat), stat = error)
282          IF (error /= 0) THEN
283             abort_message='Pb allocation lon_scat'
284             CALL abort_physic(modname,abort_message,1)
285          ENDIF
286       ENDIF
287       IF ((.NOT. ALLOCATED(lat_scat))) THEN
288          ALLOCATE(lat_scat(nbp_lon,nbp_lat), stat = error)
289          IF (error /= 0) THEN
290             abort_message='Pb allocation lat_scat'
291             CALL abort_physic(modname,abort_message,1)
292          ENDIF
293       ENDIF
294       lon_scat = 0.
295       lat_scat = 0.
296       DO igrid = 1, knon
297          index = knindex(igrid)
298          lalo(igrid,2) = rlon(index)
299          lalo(igrid,1) = rlat(index)
300       ENDDO
301
302       
303       
304       CALL Gather(rlon,rlon_g)
305       CALL Gather(rlat,rlat_g)
306
307       IF (is_mpi_root) THEN
308          index = 1
309          DO jj = 2, nbp_lat-1
310             DO ij = 1, nbp_lon
311                index = index + 1
312                lon_scat(ij,jj) = rlon_g(index)
313                lat_scat(ij,jj) = rlat_g(index)
314             ENDDO
315          ENDDO
316          lon_scat(:,1) = lon_scat(:,2)
317          lat_scat(:,1) = rlat_g(1)
318          lon_scat(:,nbp_lat) = lon_scat(:,2)
319          lat_scat(:,nbp_lat) = rlat_g(klon_glo)
320       ENDIF
321   
322       CALL bcast(lon_scat)
323       CALL bcast(lat_scat)
324!
325! Allouer et initialiser le tableau des voisins et des fraction de continents
326!
327       IF ( (.NOT.ALLOCATED(neighbours))) THEN
328          ALLOCATE(neighbours(knon,8), stat = error)
329          IF (error /= 0) THEN
330             abort_message='Pb allocation neighbours'
331             CALL abort_physic(modname,abort_message,1)
332          ENDIF
333       ENDIF
334       neighbours = -1.
335       IF (( .NOT. ALLOCATED(contfrac))) THEN
336          ALLOCATE(contfrac(knon), stat = error)
337          IF (error /= 0) THEN
338             abort_message='Pb allocation contfrac'
339             CALL abort_physic(modname,abort_message,1)
340          ENDIF
341       ENDIF
342
343       DO igrid = 1, knon
344          ireal = knindex(igrid)
345          contfrac(igrid) = pctsrf(ireal,is_ter)
346       ENDDO
347
348
349       CALL Init_neighbours(knon,neighbours,knindex,pctsrf(:,is_ter))
350
351!
352!  Allocation et calcul resolutions
353       IF ( (.NOT.ALLOCATED(resolution))) THEN
354          ALLOCATE(resolution(knon,2), stat = error)
355          IF (error /= 0) THEN
356             abort_message='Pb allocation resolution'
357             CALL abort_physic(modname,abort_message,1)
358          ENDIF
359       ENDIF
360       DO igrid = 1, knon
361          ij = knindex(igrid)
362          resolution(igrid,1) = dx(ij)
363          resolution(igrid,2) = dy(ij)
364       ENDDO
365     
366       ALLOCATE(coastalflow(klon), stat = error)
367       IF (error /= 0) THEN
368          abort_message='Pb allocation coastalflow'
369          CALL abort_physic(modname,abort_message,1)
370       ENDIF
371       
372       ALLOCATE(riverflow(klon), stat = error)
373       IF (error /= 0) THEN
374          abort_message='Pb allocation riverflow'
375          CALL abort_physic(modname,abort_message,1)
376       ENDIF
377!
378! carbon_cycle_cpl not possible with this interface and version of ORHCHIDEE
379!
380       IF (carbon_cycle_cpl) THEN
381          abort_message='carbon_cycle_cpl not yet possible with this interface of ORCHIDEE'
382          CALL abort_physic(modname,abort_message,1)
383       END IF
384       
385    ENDIF                          ! (fin debut)
386 
387
388!
389! Appel a la routine sols continentaux
390!
391    IF (lafin) lrestart_write = .TRUE.
392    IF (check) WRITE(lunout,*)'lafin ',lafin,lrestart_write
393     
394    petA_orc(1:knon) = petBcoef(1:knon) * dtime
395    petB_orc(1:knon) = petAcoef(1:knon)
396    peqA_orc(1:knon) = peqBcoef(1:knon) * dtime
397    peqB_orc(1:knon) = peqAcoef(1:knon)
398
399    cdrag = 0.
400    cdrag(1:knon) = tq_cdrag(1:knon)
401
402! zlev(1:knon) = (100.*plev(1:knon))/((ps(1:knon)/287.05*temp_air(1:knon))*9.80665)
403!    zlev(1:knon) = (100.*plev(1:knon))/((ps(1:knon)/RD*temp_air(1:knon))*RG)
404     zlev(1:knon) = plev(1:knon)*RD*temp_air(1:knon)/((ps(1:knon)*100.0)*RG)
405
406
407! PF et PASB
408!   where(cdrag > 0.01)
409!     cdrag = 0.01
410!   endwhere
411!  write(*,*)'Cdrag = ',minval(cdrag),maxval(cdrag)
412
413 
414    IF (debut) THEN
415       CALL Init_orchidee_index(knon,knindex,offset,ktindex)
416       CALL Get_orchidee_communicator(orch_comm,orch_omp_size,orch_omp_rank)
417       CALL Init_synchro_omp
418       
419       IF (knon > 0) THEN
420#ifdef CPP_VEGET
421         CALL Init_intersurf(nbp_lon,nbp_lat,knon,ktindex,offset,orch_omp_size,orch_omp_rank,orch_comm)
422#endif
423       ENDIF
424
425       
426       IF (knon > 0) THEN
427
428#ifdef CPP_VEGET
429          CALL intersurf_main (itime+itau_phy-1, nbp_lon, nbp_lat, knon, ktindex, dtime, &
430               lrestart_read, lrestart_write, lalo, &
431               contfrac, neighbours, resolution, date0, &
432               zlev,  u1_lay, v1_lay, spechum, temp_air, epot_air, ccanopy, &
433               cdrag, petA_orc, peqA_orc, petB_orc, peqB_orc, &
434               precip_rain, precip_snow, lwdown, swnet, swdown, ps, &
435               evap, fluxsens, fluxlat, coastalflow, riverflow, &
436               tsol_rad, tsurf_new, qsurf, albedo_out, emis_new, z0_new, &
437               lon_scat, lat_scat, q2m, t2m, coszang=yrmu0)
438#endif         
439       ENDIF
440
441       CALL Synchro_omp
442
443       albedo_keep(1:knon) = (albedo_out(1:knon,1)+albedo_out(1:knon,2))/2.
444
445    ENDIF
446
447   
448!  swdown_vrai(1:knon) = swnet(1:knon)/(1. - albedo_keep(1:knon))
449    swdown_vrai(1:knon) = swdown(1:knon)
450
451    IF (knon > 0) THEN
452#ifdef CPP_VEGET   
453
454       CALL intersurf_main (itime+itau_phy, nbp_lon, nbp_lat, knon, ktindex, dtime,  &
455            lrestart_read, lrestart_write, lalo, &
456            contfrac, neighbours, resolution, date0, &
457            zlev,  u1_lay(1:knon), v1_lay(1:knon), spechum(1:knon), temp_air(1:knon), epot_air(1:knon), ccanopy(1:knon), &
458            cdrag(1:knon), petA_orc(1:knon), peqA_orc(1:knon), petB_orc(1:knon), peqB_orc(1:knon), &
459            precip_rain(1:knon), precip_snow(1:knon), lwdown(1:knon), swnet(1:knon), swdown_vrai(1:knon), ps(1:knon), &
460            evap(1:knon), fluxsens(1:knon), fluxlat(1:knon), coastalflow(1:knon), riverflow(1:knon), &
461            tsol_rad(1:knon), tsurf_new(1:knon), qsurf(1:knon), albedo_out(1:knon,:), emis_new(1:knon), z0_new(1:knon), &
462            lon_scat, lat_scat, q2m(1:knon), t2m(1:knon), coszang=yrmu0(1:knon))
463#endif       
464    ENDIF
465    z0h_new(:)=z0_new(:)
466
467    CALL Synchro_omp
468   
469    albedo_keep(1:knon) = (albedo_out(1:knon,1)+albedo_out(1:knon,2))/2.
470
471!* Send to coupler
472!
473    IF (type_ocean=='couple') THEN
474       CALL cpl_send_land_fields(itime, knon, knindex, &
475            riverflow, coastalflow)
476    ENDIF
477
478    alb1_new(1:knon) = albedo_out(1:knon,1)
479    alb2_new(1:knon) = albedo_out(1:knon,2)
480
481! Convention orchidee: positif vers le haut
482    fluxsens(1:knon) = -1. * fluxsens(1:knon)
483    fluxlat(1:knon)  = -1. * fluxlat(1:knon)
484   
485!  evap     = -1. * evap
486
487    IF (debut) lrestart_read = .FALSE.
488   
489    IF (debut) CALL Finalize_surf_para
490
491   
492  END SUBROUTINE surf_land_orchidee
493!
494!****************************************************************************************
495!
496  SUBROUTINE Init_orchidee_index(knon,knindex,offset,ktindex)
497  USE mod_surf_para
498  USE mod_grid_phy_lmdz
499 
500    INTEGER,INTENT(IN)    :: knon
501    INTEGER,INTENT(IN)    :: knindex(klon)   
502    INTEGER,INTENT(OUT)   :: offset
503    INTEGER,INTENT(OUT)   :: ktindex(klon)
504   
505    INTEGER               :: ktindex_glo(knon_glo)
506    INTEGER               :: offset_para(0:omp_size*mpi_size-1)
507    INTEGER               :: LastPoint
508    INTEGER               :: task
509   
510    ktindex(1:knon)=knindex(1:knon)+(klon_mpi_begin-1)+(klon_omp_begin-1)+nbp_lon-1
511   
512    CALL gather_surf(ktindex(1:knon),ktindex_glo)
513   
514    IF (is_mpi_root .AND. is_omp_root) THEN
515      LastPoint=0
516      DO Task=0,mpi_size*omp_size-1
517        IF (knon_glo_para(Task)>0) THEN
518           offset_para(task)= LastPoint-MOD(LastPoint,nbp_lon)
519           LastPoint=ktindex_glo(knon_glo_end_para(task))
520        ENDIF
521      ENDDO
522    ENDIF
523   
524    CALL bcast(offset_para)
525   
526    offset=offset_para(omp_size*mpi_rank+omp_rank)
527   
528    ktindex(1:knon)=ktindex(1:knon)-offset
529
530  END SUBROUTINE Init_orchidee_index
531
532!
533!************************* ***************************************************************
534!
535
536  SUBROUTINE Get_orchidee_communicator(orch_comm,orch_omp_size,orch_omp_rank)
537  USE  mod_surf_para
538  USE lmdz_mpi
539     
540    INTEGER,INTENT(OUT) :: orch_comm
541    INTEGER,INTENT(OUT) :: orch_omp_size
542    INTEGER,INTENT(OUT) :: orch_omp_rank
543    INTEGER             :: color
544    INTEGER             :: i,ierr
545!
546! End definition
547!****************************************************************************************
548   
549   
550    IF (is_omp_root) THEN         
551     
552      IF (knon_mpi==0) THEN
553         color = 0
554      ELSE
555         color = 1
556      ENDIF
557   
558      IF (using_mpi) THEN
559        CALL MPI_COMM_SPLIT(COMM_LMDZ_PHY,color,mpi_rank,orch_comm,ierr)
560      ENDIF
561   
562    ENDIF
563    CALL bcast_omp(orch_comm)
564   
565    IF (knon_mpi /= 0) THEN
566      orch_omp_size=0
567      DO i=0,omp_size-1
568        IF (knon_omp_para(i) /=0) THEN
569          orch_omp_size=orch_omp_size+1
570          IF (i==omp_rank) orch_omp_rank=orch_omp_size-1
571        ENDIF
572      ENDDO
573    ENDIF
574   
575   
576  END SUBROUTINE Get_orchidee_communicator
577!
578!****************************************************************************************
579
580
581  SUBROUTINE Init_neighbours(knon,neighbours,knindex,pctsrf)
582    USE mod_grid_phy_lmdz
583    USE mod_surf_para   
584    USE indice_sol_mod
585    USE lmdz_mpi
586
587! Input arguments
588!****************************************************************************************
589    INTEGER, INTENT(IN)                     :: knon
590    INTEGER, DIMENSION(klon), INTENT(IN)    :: knindex
591    REAL, DIMENSION(klon), INTENT(IN)       :: pctsrf
592   
593! Output arguments
594!****************************************************************************************
595    INTEGER, DIMENSION(knon,8), INTENT(OUT) :: neighbours
596
597! Local variables
598!****************************************************************************************
599    INTEGER                              :: i, igrid, jj, ij, iglob
600    INTEGER                              :: ierr, ireal, index
601    INTEGER, DIMENSION(8,3)              :: off_ini
602    INTEGER, DIMENSION(8)                :: offset 
603    INTEGER, DIMENSION(nbp_lon,nbp_lat)  :: correspond
604    INTEGER, DIMENSION(knon_glo)         :: ktindex_glo
605    INTEGER, DIMENSION(knon_glo,8)       :: neighbours_glo
606    REAL, DIMENSION(klon_glo)            :: pctsrf_glo
607    INTEGER                              :: ktindex(klon)
608!
609! End definition
610!****************************************************************************************
611
612    ktindex(1:knon)=knindex(1:knon)+(klon_mpi_begin-1)+(klon_omp_begin-1)+nbp_lon-1
613   
614    CALL gather_surf(ktindex(1:knon),ktindex_glo)
615    CALL gather(pctsrf,pctsrf_glo)
616   
617    IF (is_mpi_root .AND. is_omp_root) THEN
618      neighbours_glo(:,:)=-1
619!  Initialisation des offset   
620!
621! offset bord ouest
622       off_ini(1,1) = - nbp_lon   ; off_ini(2,1) = - nbp_lon + 1     ; off_ini(3,1) = 1
623       off_ini(4,1) = nbp_lon + 1 ; off_ini(5,1) = nbp_lon           ; off_ini(6,1) = 2 * nbp_lon - 1
624       off_ini(7,1) = nbp_lon -1  ; off_ini(8,1) = - 1
625! offset point normal
626       off_ini(1,2) = - nbp_lon   ; off_ini(2,2) = - nbp_lon + 1     ; off_ini(3,2) = 1
627       off_ini(4,2) = nbp_lon + 1 ; off_ini(5,2) = nbp_lon           ; off_ini(6,2) = nbp_lon - 1
628       off_ini(7,2) = -1          ; off_ini(8,2) = - nbp_lon - 1
629! offset bord   est
630       off_ini(1,3) = - nbp_lon   ; off_ini(2,3) = - 2 * nbp_lon + 1 ; off_ini(3,3) = - nbp_lon + 1
631       off_ini(4,3) =  1          ; off_ini(5,3) = nbp_lon           ; off_ini(6,3) = nbp_lon - 1
632       off_ini(7,3) = -1          ; off_ini(8,3) = - nbp_lon - 1
633!
634!
635! Attention aux poles
636!
637       DO igrid = 1, knon_glo
638          index = ktindex_glo(igrid)
639          jj = INT((index - 1)/nbp_lon) + 1
640          ij = index - (jj - 1) * nbp_lon
641          correspond(ij,jj) = igrid
642       ENDDO
643!sonia : Les mailles des voisines doivent etre toutes egales (pour couplage orchidee)
644       IF (knon_glo == 1) THEN
645         igrid = 1
646         DO i = 1,8
647           neighbours_glo(igrid, i) = igrid
648         ENDDO
649       ELSE
650       print*,'sonia : knon_glo,ij,jj', knon_glo, ij,jj
651       
652       DO igrid = 1, knon_glo
653          iglob = ktindex_glo(igrid)
654         
655          IF (MOD(iglob, nbp_lon) == 1) THEN
656             offset = off_ini(:,1)
657          ELSE IF(MOD(iglob, nbp_lon) == 0) THEN
658             offset = off_ini(:,3)
659          ELSE
660             offset = off_ini(:,2)
661          ENDIF
662         
663          DO i = 1, 8
664             index = iglob + offset(i)
665             ireal = (MIN(MAX(1, index - nbp_lon + 1), klon_glo))
666             IF (pctsrf_glo(ireal) > EPSFRA) THEN
667                jj = INT((index - 1)/nbp_lon) + 1
668                ij = index - (jj - 1) * nbp_lon
669                neighbours_glo(igrid, i) = correspond(ij, jj)
670             ENDIF
671          ENDDO
672       ENDDO
673       ENDIF !fin knon_glo == 1
674
675    ENDIF
676   
677    DO i = 1, 8
678      CALL scatter_surf(neighbours_glo(:,i),neighbours(1:knon,i))
679    ENDDO
680  END SUBROUTINE Init_neighbours
681
682!
683!****************************************************************************************
684!
685#endif
686END MODULE surf_land_orchidee_noz0h_mod
Note: See TracBrowser for help on using the repository browser.