source: LMDZ6/branches/DYNAMICO-conv/libf/phylmd/surf_land_orchidee_mod.F90 @ 3863

Last change on this file since 3863 was 3413, checked in by Laurent Fairhead, 6 years ago

Inclusion of Yann's latest (summer/fall 2018) modifications for
convergence of DYNAMICO/LMDZ physics
YM/LF

  • 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:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 28.4 KB
Line 
1!
2MODULE surf_land_orchidee_mod
3#ifndef ORCHIDEE_NOOPENMP
4#ifndef ORCHIDEE_NOZ0H
5#ifndef ORCHIDEE_NOFREIN
6#ifndef ORCHIDEE_NOUNSTRUCT
7!
8! This module controles the interface towards the model ORCHIDEE.
9!
10! Compatibility with ORCHIDIEE :
11! The current version can be used with ORCHIDEE/trunk from revision 4465.
12! This interface is used if none of the cpp keys ORCHIDEE_NOOPENMP,
13! ORCHIDEE_NOZ0H or ORCHIDEE_NOFREIN is set.
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, boundslon, boundslat,longitude, latitude, cell_area,  ind_cell_glo
27  USE mod_grid_phy_lmdz
28  USE mod_phys_lmdz_para, mpi_root_rank=>mpi_master
29  USE nrtype, ONLY : PI
30 
31  IMPLICIT NONE
32
33  PRIVATE
34  PUBLIC  :: surf_land_orchidee
35
36CONTAINS
37!
38!****************************************************************************************
39
40  SUBROUTINE surf_land_orchidee(itime, dtime, date0, knon, &
41       knindex, rlon, rlat, yrmu0, pctsrf, &
42       debut, lafin, &
43       plev,  u1_lay, v1_lay, gustiness, temp_air, spechum, epot_air, ccanopy, &
44       tq_cdrag, petAcoef, peqAcoef, petBcoef, peqBcoef, &
45       precip_rain, precip_snow, lwdown, swnet, swdown, &
46       ps, q2m, t2m, &
47       evap, fluxsens, fluxlat, &             
48       tsol_rad, tsurf_new, alb1_new, alb2_new, &
49       emis_new, z0m_new, z0h_new, qsurf, &
50       veget, lai, height )
51
52
53    USE mod_surf_para
54    USE mod_synchro_omp
55    USE carbon_cycle_mod, ONLY : carbon_cycle_cpl
56    USE indice_sol_mod
57    USE print_control_mod, ONLY: lunout
58    USE mod_grid_phy_lmdz, ONLY: nbp_lon, nbp_lat
59#ifdef CPP_VEGET
60    USE time_phylmdz_mod, ONLY: itau_phy
61#endif
62!   
63! Cette routine sert d'interface entre le modele atmospherique et le
64! modele de sol continental. Appel a sechiba
65!
66! L. Fairhead 02/2000
67!
68! input:
69!   itime        numero du pas de temps
70!   dtime        pas de temps de la physique (en s)
71!   nisurf       index de la surface a traiter (1 = sol continental)
72!   knon         nombre de points de la surface a traiter
73!   knindex      index des points de la surface a traiter
74!   rlon         longitudes de la grille entiere
75!   rlat         latitudes de la grille entiere
76!   pctsrf       tableau des fractions de surface de chaque maille
77!   debut        logical: 1er appel a la physique (lire les restart)
78!   lafin        logical: dernier appel a la physique (ecrire les restart)
79!                     (si false calcul simplifie des fluxs sur les continents)
80!   plev         hauteur de la premiere couche (Pa)     
81!   u1_lay       vitesse u 1ere couche
82!   v1_lay       vitesse v 1ere couche
83!   temp_air     temperature de l'air 1ere couche
84!   spechum      humidite specifique 1ere couche
85!   epot_air     temp pot de l'air
86!   ccanopy      concentration CO2 canopee, correspond au co2_send de
87!                carbon_cycle_mod ou valeur constant co2_ppm
88!   tq_cdrag     cdrag
89!   petAcoef     coeff. A de la resolution de la CL pour t
90!   peqAcoef     coeff. A de la resolution de la CL pour q
91!   petBcoef     coeff. B de la resolution de la CL pour t
92!   peqBcoef     coeff. B de la resolution de la CL pour q
93!   precip_rain  precipitation liquide
94!   precip_snow  precipitation solide
95!   lwdown       flux IR descendant a la surface
96!   swnet        flux solaire net
97!   swdown       flux solaire entrant a la surface
98!   ps           pression au sol
99!   radsol       rayonnement net aus sol (LW + SW)
100!   
101!
102! output:
103!   evap         evaporation totale
104!   fluxsens     flux de chaleur sensible
105!   fluxlat      flux de chaleur latente
106!   tsol_rad     
107!   tsurf_new    temperature au sol
108!   alb1_new     albedo in visible SW interval
109!   alb2_new     albedo in near IR interval
110!   emis_new     emissivite
111!   z0m_new      surface roughness for momentum
112!   z0h_new      surface roughness for heat
113!   qsurf        air moisture at surface
114!
115    INCLUDE "YOMCST.h"
116    INCLUDE "dimpft.h"
117
118
119 
120!
121! Parametres d'entree
122!****************************************************************************************
123    INTEGER, INTENT(IN)                       :: itime
124    REAL, INTENT(IN)                          :: dtime
125    REAL, INTENT(IN)                          :: date0
126    INTEGER, INTENT(IN)                       :: knon
127    INTEGER, DIMENSION(klon), INTENT(IN)      :: knindex
128    LOGICAL, INTENT(IN)                       :: debut, lafin
129    REAL, DIMENSION(klon,nbsrf), INTENT(IN)   :: pctsrf
130    REAL, DIMENSION(klon), INTENT(IN)         :: rlon, rlat
131    REAL, DIMENSION(klon), INTENT(IN)         :: yrmu0 ! cosine of solar zenith angle
132    REAL, DIMENSION(klon), INTENT(IN)         :: plev
133    REAL, DIMENSION(klon), INTENT(IN)         :: u1_lay, v1_lay, gustiness
134    REAL, DIMENSION(klon), INTENT(IN)         :: temp_air, spechum
135    REAL, DIMENSION(klon), INTENT(IN)         :: epot_air, ccanopy
136    REAL, DIMENSION(klon), INTENT(IN)         :: tq_cdrag
137    REAL, DIMENSION(klon), INTENT(IN)         :: petAcoef, peqAcoef
138    REAL, DIMENSION(klon), INTENT(IN)         :: petBcoef, peqBcoef
139    REAL, DIMENSION(klon), INTENT(IN)         :: precip_rain, precip_snow
140    REAL, DIMENSION(klon), INTENT(IN)         :: lwdown, swnet, swdown, ps
141    REAL, DIMENSION(klon), INTENT(IN)         :: q2m, t2m
142
143! Parametres de sortie
144!****************************************************************************************
145    REAL, DIMENSION(klon), INTENT(OUT)        :: evap, fluxsens, fluxlat, qsurf
146    REAL, DIMENSION(klon), INTENT(OUT)        :: tsol_rad, tsurf_new
147    REAL, DIMENSION(klon), INTENT(OUT)        :: alb1_new, alb2_new
148    REAL, DIMENSION(klon), INTENT(OUT)        :: emis_new, z0m_new, z0h_new
149    REAL, DIMENSION(klon,nvm_lmdz), INTENT(OUT) :: veget
150    REAL, DIMENSION(klon,nvm_lmdz), INTENT(OUT) :: lai
151    REAL, DIMENSION(klon,nvm_lmdz), INTENT(OUT) :: height
152
153
154! Local
155!****************************************************************************************
156    INTEGER                                   :: ij, jj, igrid, ireal, index
157    INTEGER                                   :: error
158    REAL, DIMENSION(klon)                     :: swdown_vrai
159    CHARACTER (len = 20)                      :: modname = 'surf_land_orchidee'
160    CHARACTER (len = 80)                      :: abort_message
161    LOGICAL,SAVE                              :: check = .FALSE.
162    !$OMP THREADPRIVATE(check)
163
164! type de couplage dans sechiba
165!  character (len=10)   :: coupling = 'implicit'
166! drapeaux controlant les appels dans SECHIBA
167!  type(control_type), save   :: control_in
168! Preserved albedo
169    REAL, ALLOCATABLE, DIMENSION(:), SAVE     :: albedo_keep, zlev
170    !$OMP THREADPRIVATE(albedo_keep,zlev)
171! coordonnees geographiques
172    REAL, ALLOCATABLE, DIMENSION(:,:), SAVE   :: lalo
173    !$OMP THREADPRIVATE(lalo)
174! boundaries of cells
175    REAL, ALLOCATABLE, DIMENSION(:,:,:), SAVE   :: bounds_lalo
176    !$OMP THREADPRIVATE(bounds_lalo)
177! pts voisins
178    INTEGER,ALLOCATABLE, DIMENSION(:,:), SAVE :: neighbours
179    !$OMP THREADPRIVATE(neighbours)
180! fractions continents
181    REAL,ALLOCATABLE, DIMENSION(:), SAVE      :: contfrac
182    !$OMP THREADPRIVATE(contfrac)
183! resolution de la grille
184    REAL, ALLOCATABLE, DIMENSION (:,:), SAVE  :: resolution
185    !$OMP THREADPRIVATE(resolution)
186
187    REAL, ALLOCATABLE, DIMENSION (:,:), SAVE  :: lon_scat, lat_scat 
188    !$OMP THREADPRIVATE(lon_scat,lat_scat)
189
190! area of cells
191    REAL, ALLOCATABLE, DIMENSION (:), SAVE  :: area 
192    !$OMP THREADPRIVATE(area)
193
194    LOGICAL, SAVE                             :: lrestart_read = .TRUE.
195    !$OMP THREADPRIVATE(lrestart_read)
196    LOGICAL, SAVE                             :: lrestart_write = .FALSE.
197    !$OMP THREADPRIVATE(lrestart_write)
198
199    REAL, DIMENSION(knon,2)                   :: albedo_out
200
201! Pb de nomenclature
202    REAL, DIMENSION(klon)                     :: petA_orc, peqA_orc
203    REAL, DIMENSION(klon)                     :: petB_orc, peqB_orc
204! Pb de correspondances de grilles
205    INTEGER, DIMENSION(:), SAVE, ALLOCATABLE  :: ig, jg
206    !$OMP THREADPRIVATE(ig,jg)
207    INTEGER :: indi, indj
208    INTEGER, SAVE, ALLOCATABLE,DIMENSION(:)   :: ktindex
209    !$OMP THREADPRIVATE(ktindex)
210
211! Essai cdrag
212    REAL, DIMENSION(klon)                     :: cdrag
213    INTEGER,SAVE                              :: offset
214    !$OMP THREADPRIVATE(offset)
215
216    REAL, DIMENSION(klon_glo)                 :: rlon_g,rlat_g
217    INTEGER, SAVE                             :: orch_comm
218    !$OMP THREADPRIVATE(orch_comm)
219
220    REAL, ALLOCATABLE, DIMENSION(:), SAVE     :: coastalflow
221    !$OMP THREADPRIVATE(coastalflow)
222    REAL, ALLOCATABLE, DIMENSION(:), SAVE     :: riverflow
223    !$OMP THREADPRIVATE(riverflow)
224   
225    INTEGER :: orch_mpi_rank
226    INTEGER :: orch_mpi_size
227    INTEGER :: orch_omp_rank
228    INTEGER :: orch_omp_size
229
230    REAL, ALLOCATABLE, DIMENSION(:)         :: longitude_glo
231    REAL, ALLOCATABLE, DIMENSION(:)         :: latitude_glo
232    REAL, ALLOCATABLE, DIMENSION(:,:)       :: boundslon_glo
233    REAL, ALLOCATABLE, DIMENSION(:,:)       :: boundslat_glo
234    INTEGER, ALLOCATABLE, DIMENSION(:)      :: ind_cell_glo_glo
235    INTEGER, ALLOCATABLE, SAVE,DIMENSION(:) :: ind_cell
236    !$OMP THREADPRIVATE(ind_cell)
237    INTEGER :: begin, end
238!
239! Fin definition
240!****************************************************************************************
241
242    IF (check) WRITE(lunout,*)'Entree ', modname
243 
244! Initialisation
245 
246    IF (debut) THEN
247! Test of coherence between variable ok_veget and cpp key CPP_VEGET
248#ifndef CPP_VEGET
249       abort_message='Pb de coherence: ok_veget = .true. mais CPP_VEGET = .false.'
250       CALL abort_physic(modname,abort_message,1)
251#endif
252
253       CALL Init_surf_para(knon)
254       ALLOCATE(ktindex(knon))
255       IF ( .NOT. ALLOCATED(albedo_keep)) THEN
256!ym          ALLOCATE(albedo_keep(klon))
257!ym bizarre que non alloué en knon precedement
258          ALLOCATE(albedo_keep(knon))
259          ALLOCATE(zlev(knon))
260       ENDIF
261! Pb de correspondances de grilles
262       ALLOCATE(ig(klon))
263       ALLOCATE(jg(klon))
264       ig(1) = 1
265       jg(1) = 1
266       indi = 0
267       indj = 2
268       DO igrid = 2, klon - 1
269          indi = indi + 1
270          IF ( indi > nbp_lon) THEN
271             indi = 1
272             indj = indj + 1
273          ENDIF
274          ig(igrid) = indi
275          jg(igrid) = indj
276       ENDDO
277       ig(klon) = 1
278       jg(klon) = nbp_lat
279
280       IF ((.NOT. ALLOCATED(area))) THEN
281          ALLOCATE(area(knon), stat = error)
282          IF (error /= 0) THEN
283             abort_message='Pb allocation area'
284             CALL abort_physic(modname,abort_message,1)
285          ENDIF
286       ENDIF
287       DO igrid = 1, knon
288          area(igrid) = cell_area(knindex(igrid))
289       ENDDO
290       
291       IF (grid_type==unstructured) THEN
292
293
294         IF ((.NOT. ALLOCATED(lon_scat))) THEN
295            ALLOCATE(lon_scat(nbp_lon,nbp_lat), stat = error)
296            IF (error /= 0) THEN
297               abort_message='Pb allocation lon_scat'
298               CALL abort_physic(modname,abort_message,1)
299            ENDIF
300         ENDIF
301 
302         IF ((.NOT. ALLOCATED(lat_scat))) THEN
303            ALLOCATE(lat_scat(nbp_lon,nbp_lat), stat = error)
304            IF (error /= 0) THEN
305               abort_message='Pb allocation lat_scat'
306               CALL abort_physic(modname,abort_message,1)
307            ENDIF
308         ENDIF
309         CALL Gather(rlon,rlon_g)
310         CALL Gather(rlat,rlat_g)
311
312         IF (is_mpi_root) THEN
313            index = 1
314            DO jj = 2, nbp_lat-1
315               DO ij = 1, nbp_lon
316                  index = index + 1
317                  lon_scat(ij,jj) = rlon_g(index)
318                  lat_scat(ij,jj) = rlat_g(index)
319               ENDDO
320            ENDDO
321            lon_scat(:,1) = lon_scat(:,2)
322            lat_scat(:,1) = rlat_g(1)
323            lon_scat(:,nbp_lat) = lon_scat(:,2)
324            lat_scat(:,nbp_lat) = rlat_g(klon_glo)
325         ENDIF
326     
327         CALL bcast(lon_scat)
328         CALL bcast(lat_scat)
329               
330       ELSE IF (grid_type==regular_lonlat) THEN
331
332         IF ((.NOT. ALLOCATED(lalo))) THEN
333            ALLOCATE(lalo(knon,2), stat = error)
334            IF (error /= 0) THEN
335               abort_message='Pb allocation lalo'
336               CALL abort_physic(modname,abort_message,1)
337            ENDIF
338         ENDIF
339       
340         IF ((.NOT. ALLOCATED(bounds_lalo))) THEN
341           ALLOCATE(bounds_lalo(knon,nvertex,2), stat = error)
342           IF (error /= 0) THEN
343             abort_message='Pb allocation lalo'
344             CALL abort_physic(modname,abort_message,1)
345           ENDIF
346         ENDIF
347       
348         IF ((.NOT. ALLOCATED(lon_scat))) THEN
349            ALLOCATE(lon_scat(nbp_lon,nbp_lat), stat = error)
350            IF (error /= 0) THEN
351               abort_message='Pb allocation lon_scat'
352               CALL abort_physic(modname,abort_message,1)
353            ENDIF
354         ENDIF
355         IF ((.NOT. ALLOCATED(lat_scat))) THEN
356            ALLOCATE(lat_scat(nbp_lon,nbp_lat), stat = error)
357            IF (error /= 0) THEN
358               abort_message='Pb allocation lat_scat'
359               CALL abort_physic(modname,abort_message,1)
360            ENDIF
361         ENDIF
362         lon_scat = 0.
363         lat_scat = 0.
364         DO igrid = 1, knon
365            index = knindex(igrid)
366            lalo(igrid,2) = rlon(index)
367            lalo(igrid,1) = rlat(index)
368            bounds_lalo(igrid,:,2)=boundslon(index,:)*180./PI
369            bounds_lalo(igrid,:,1)=boundslat(index,:)*180./PI
370         ENDDO
371
372       
373       
374         CALL Gather(rlon,rlon_g)
375         CALL Gather(rlat,rlat_g)
376
377         IF (is_mpi_root) THEN
378            index = 1
379            DO jj = 2, nbp_lat-1
380               DO ij = 1, nbp_lon
381                  index = index + 1
382                  lon_scat(ij,jj) = rlon_g(index)
383                  lat_scat(ij,jj) = rlat_g(index)
384               ENDDO
385            ENDDO
386            lon_scat(:,1) = lon_scat(:,2)
387            lat_scat(:,1) = rlat_g(1)
388            lon_scat(:,nbp_lat) = lon_scat(:,2)
389            lat_scat(:,nbp_lat) = rlat_g(klon_glo)
390         ENDIF
391   
392         CALL bcast(lon_scat)
393         CALL bcast(lat_scat)
394       
395       ENDIF
396!
397! Allouer et initialiser le tableau des voisins et des fraction de continents
398!
399       IF (( .NOT. ALLOCATED(contfrac))) THEN
400          ALLOCATE(contfrac(knon), stat = error)
401          IF (error /= 0) THEN
402             abort_message='Pb allocation contfrac'
403             CALL abort_physic(modname,abort_message,1)
404          ENDIF
405       ENDIF
406
407       DO igrid = 1, knon
408          ireal = knindex(igrid)
409          contfrac(igrid) = pctsrf(ireal,is_ter)
410       ENDDO
411
412
413       IF (grid_type==regular_lonlat) THEN
414 
415         IF ( (.NOT.ALLOCATED(neighbours))) THEN
416          ALLOCATE(neighbours(knon,8), stat = error)
417          IF (error /= 0) THEN
418             abort_message='Pb allocation neighbours'
419             CALL abort_physic(modname,abort_message,1)
420          ENDIF
421         ENDIF
422         neighbours = -1.
423         CALL Init_neighbours(knon,neighbours,knindex,pctsrf(:,is_ter))
424
425       ELSE IF (grid_type==unstructured) THEN
426 
427         IF ( (.NOT.ALLOCATED(neighbours))) THEN
428          ALLOCATE(neighbours(knon,12), stat = error)
429          IF (error /= 0) THEN
430             abort_message='Pb allocation neighbours'
431             CALL abort_physic(modname,abort_message,1)
432          ENDIF
433         ENDIF
434         neighbours = -1.
435 
436       ENDIF
437         
438
439!
440!  Allocation et calcul resolutions
441       IF ( (.NOT.ALLOCATED(resolution))) THEN
442          ALLOCATE(resolution(knon,2), stat = error)
443          IF (error /= 0) THEN
444             abort_message='Pb allocation resolution'
445             CALL abort_physic(modname,abort_message,1)
446          ENDIF
447       ENDIF
448       
449       IF (grid_type==regular_lonlat) THEN
450         DO igrid = 1, knon
451            ij = knindex(igrid)
452            resolution(igrid,1) = dx(ij)
453           resolution(igrid,2) = dy(ij)
454         ENDDO
455       ENDIF
456       
457       ALLOCATE(coastalflow(klon), stat = error)
458       IF (error /= 0) THEN
459          abort_message='Pb allocation coastalflow'
460          CALL abort_physic(modname,abort_message,1)
461       ENDIF
462       
463       ALLOCATE(riverflow(klon), stat = error)
464       IF (error /= 0) THEN
465          abort_message='Pb allocation riverflow'
466          CALL abort_physic(modname,abort_message,1)
467       ENDIF
468!
469! carbon_cycle_cpl not possible with this interface and version of ORHCHIDEE
470!
471       IF (carbon_cycle_cpl) THEN
472          abort_message='carbon_cycle_cpl not yet possible with this interface of ORCHIDEE'
473          CALL abort_physic(modname,abort_message,1)
474       END IF
475       
476    ENDIF                          ! (fin debut)
477 
478
479!
480! Appel a la routine sols continentaux
481!
482    IF (lafin) lrestart_write = .TRUE.
483    IF (check) WRITE(lunout,*)'lafin ',lafin,lrestart_write
484     
485    petA_orc(1:knon) = petBcoef(1:knon) * dtime
486    petB_orc(1:knon) = petAcoef(1:knon)
487    peqA_orc(1:knon) = peqBcoef(1:knon) * dtime
488    peqB_orc(1:knon) = peqAcoef(1:knon)
489
490    cdrag = 0.
491    cdrag(1:knon) = tq_cdrag(1:knon)
492
493! zlev(1:knon) = (100.*plev(1:knon))/((ps(1:knon)/287.05*temp_air(1:knon))*9.80665)
494!    zlev(1:knon) = (100.*plev(1:knon))/((ps(1:knon)/RD*temp_air(1:knon))*RG)
495     zlev(1:knon) = plev(1:knon)*RD*temp_air(1:knon)/((ps(1:knon)*100.0)*RG)
496
497
498! PF et PASB
499!   where(cdrag > 0.01)
500!     cdrag = 0.01
501!   endwhere
502!  write(*,*)'Cdrag = ',minval(cdrag),maxval(cdrag)
503
504 
505    IF (debut) THEN
506       CALL Init_orchidee_index(knon,knindex,offset,ktindex)
507       CALL Get_orchidee_communicator(orch_comm,orch_mpi_size,orch_mpi_rank, orch_omp_size,orch_omp_rank)
508
509       IF (grid_type==unstructured) THEN
510         IF (knon==0) THEN
511           begin=1
512           end=0
513         ELSE
514           begin=offset+1
515           end=offset+ktindex(knon)
516         ENDIF
517       
518         IF (orch_mpi_rank==orch_mpi_size-1 .AND. orch_omp_rank==orch_omp_size-1) end=nbp_lon*nbp_lat
519         
520         ALLOCATE(lalo(end-begin+1,2))
521         ALLOCATE(bounds_lalo(end-begin+1,nvertex,2))
522         ALLOCATE(ind_cell(end-begin+1))
523         
524         ALLOCATE(longitude_glo(klon_glo))
525         CALL gather(longitude,longitude_glo)
526         CALL bcast(longitude_glo)
527         lalo(:,2)=longitude_glo(begin:end)*180./PI
528 
529         ALLOCATE(latitude_glo(klon_glo))
530         CALL gather(latitude,latitude_glo)
531         CALL bcast(latitude_glo)
532         lalo(:,1)=latitude_glo(begin:end)*180./PI
533
534         ALLOCATE(boundslon_glo(klon_glo,nvertex))
535         CALL gather(boundslon,boundslon_glo)
536         CALL bcast(boundslon_glo)
537         bounds_lalo(:,:,2)=boundslon_glo(begin:end,:)*180./PI
538 
539         ALLOCATE(boundslat_glo(klon_glo,nvertex))
540         CALL gather(boundslat,boundslat_glo)
541         CALL bcast(boundslat_glo)
542         bounds_lalo(:,:,1)=boundslat_glo(begin:end,:)*180./PI
543         
544         ALLOCATE(ind_cell_glo_glo(klon_glo))
545         CALL gather(ind_cell_glo,ind_cell_glo_glo)
546         CALL bcast(ind_cell_glo_glo)
547         ind_cell(:)=ind_cell_glo_glo(begin:end)
548         
549       ENDIF
550       CALL Init_synchro_omp
551       
552       IF (knon > 0) THEN
553#ifdef CPP_VEGET
554         CALL Init_intersurf(nbp_lon,nbp_lat,knon,ktindex,offset,orch_omp_size,orch_omp_rank,orch_comm,grid=grid_type)
555#endif
556       ENDIF
557
558       
559       IF (knon > 0) THEN
560
561#ifdef CPP_VEGET
562
563         CALL intersurf_initialize_gathered (itime+itau_phy-1, nbp_lon, nbp_lat, knon, ktindex, dtime, &
564               lrestart_read, lrestart_write, lalo, contfrac, neighbours, resolution, date0, &
565               zlev,  u1_lay, v1_lay, spechum, temp_air, epot_air, &
566               cdrag, petA_orc, peqA_orc, petB_orc, peqB_orc, &
567               precip_rain, precip_snow, lwdown, swnet, swdown, ps, &
568               evap, fluxsens, fluxlat, coastalflow, riverflow, &
569               tsol_rad, tsurf_new, qsurf, albedo_out, emis_new, z0m_new, &   
570               lon_scat, lat_scat, q2m(1:knon), t2m(1:knon), z0h_new(1:knon), nvm_orch, &
571               grid=grid_type, bounds_latlon=bounds_lalo, cell_area=area, ind_cell_glo=ind_cell)
572#endif         
573       ENDIF
574
575       CALL Synchro_omp
576
577       albedo_keep(1:knon) = (albedo_out(1:knon,1)+albedo_out(1:knon,2))/2.
578
579    ENDIF
580
581   
582!  swdown_vrai(1:knon) = swnet(1:knon)/(1. - albedo_keep(1:knon))
583    swdown_vrai(1:knon) = swdown(1:knon)
584
585    IF (knon > 0) THEN
586#ifdef CPP_VEGET   
587       IF (nvm_orch .NE. nvm_lmdz ) THEN
588          abort_message='Pb de dimensiosn PFT: nvm_orch et nvm_lmdz differents.'
589          CALL abort_physic(modname,abort_message,1)
590       ENDIF
591
592       CALL intersurf_main_gathered (itime+itau_phy, nbp_lon, nbp_lat, knon, ktindex, dtime,  &
593            lrestart_read, lrestart_write, lalo, &
594            contfrac, neighbours, resolution, date0, &
595            zlev,  u1_lay(1:knon), v1_lay(1:knon), spechum(1:knon), temp_air(1:knon), epot_air(1:knon), ccanopy(1:knon), &
596            cdrag(1:knon), petA_orc(1:knon), peqA_orc(1:knon), petB_orc(1:knon), peqB_orc(1:knon), &
597            precip_rain(1:knon), precip_snow(1:knon), lwdown(1:knon), swnet(1:knon), swdown_vrai(1:knon), ps(1:knon), &
598            evap(1:knon), fluxsens(1:knon), fluxlat(1:knon), coastalflow(1:knon), riverflow(1:knon), &
599            tsol_rad(1:knon), tsurf_new(1:knon), qsurf(1:knon), albedo_out(1:knon,:), emis_new(1:knon), z0m_new(1:knon), &
600            lon_scat, lat_scat, q2m(1:knon), t2m(1:knon), z0h_new(1:knon),&
601            veget(1:knon,:),lai(1:knon,:),height(1:knon,:),&
602            coszang=yrmu0(1:knon))
603#endif       
604    ENDIF
605
606    CALL Synchro_omp
607   
608    albedo_keep(1:knon) = (albedo_out(1:knon,1)+albedo_out(1:knon,2))/2.
609
610!* Send to coupler
611!
612    IF (type_ocean=='couple') THEN
613       CALL cpl_send_land_fields(itime, knon, knindex, &
614            riverflow, coastalflow)
615    ENDIF
616
617    alb1_new(1:knon) = albedo_out(1:knon,1)
618    alb2_new(1:knon) = albedo_out(1:knon,2)
619
620! Convention orchidee: positif vers le haut
621    fluxsens(1:knon) = -1. * fluxsens(1:knon)
622    fluxlat(1:knon)  = -1. * fluxlat(1:knon)
623   
624!  evap     = -1. * evap
625
626    IF (debut) lrestart_read = .FALSE.
627   
628    IF (debut) CALL Finalize_surf_para
629
630   
631  END SUBROUTINE surf_land_orchidee
632!
633!****************************************************************************************
634!
635  SUBROUTINE Init_orchidee_index(knon,knindex,offset,ktindex)
636  USE mod_surf_para
637  USE mod_grid_phy_lmdz
638 
639    INTEGER,INTENT(IN)    :: knon
640    INTEGER,INTENT(IN)    :: knindex(klon)   
641    INTEGER,INTENT(OUT)   :: offset
642    INTEGER,INTENT(OUT)   :: ktindex(klon)
643   
644    INTEGER               :: ktindex_glo(knon_glo)
645    INTEGER               :: offset_para(0:omp_size*mpi_size-1)
646    INTEGER               :: LastPoint
647    INTEGER               :: task
648   
649    ktindex(1:knon)=knindex(1:knon)+(klon_mpi_begin-1)+(klon_omp_begin-1)+nbp_lon-1
650   
651    CALL gather_surf(ktindex(1:knon),ktindex_glo)
652   
653    IF (is_mpi_root .AND. is_omp_root) THEN
654      LastPoint=0
655      DO Task=0,mpi_size*omp_size-1
656        IF (knon_glo_para(Task)>0) THEN
657           offset_para(task)= LastPoint-MOD(LastPoint,nbp_lon)
658           LastPoint=ktindex_glo(knon_glo_end_para(task))
659        ENDIF
660      ENDDO
661    ENDIF
662   
663    CALL bcast(offset_para)
664   
665    offset=offset_para(omp_size*mpi_rank+omp_rank)
666   
667    ktindex(1:knon)=ktindex(1:knon)-offset
668
669  END SUBROUTINE Init_orchidee_index
670
671!
672!************************* ***************************************************************
673!
674
675  SUBROUTINE Get_orchidee_communicator(orch_comm, orch_mpi_size, orch_mpi_rank, orch_omp_size,orch_omp_rank)
676  USE  mod_surf_para
677     
678#ifdef CPP_MPI
679    INCLUDE 'mpif.h'
680#endif   
681
682    INTEGER,INTENT(OUT) :: orch_comm
683    INTEGER,INTENT(OUT) :: orch_mpi_size
684    INTEGER,INTENT(OUT) :: orch_mpi_rank
685    INTEGER,INTENT(OUT) :: orch_omp_size
686    INTEGER,INTENT(OUT) :: orch_omp_rank
687    INTEGER             :: color
688    INTEGER             :: i,ierr
689!
690! End definition
691!****************************************************************************************
692   
693   
694    IF (is_omp_root) THEN         
695     
696      IF (knon_mpi==0) THEN
697         color = 0
698      ELSE
699         color = 1
700      ENDIF
701   
702#ifdef CPP_MPI   
703      CALL MPI_COMM_SPLIT(COMM_LMDZ_PHY,color,mpi_rank,orch_comm,ierr)
704      CALL MPI_COMM_SIZE(orch_comm,orch_mpi_size,ierr)
705      CALL MPI_COMM_RANK(orch_comm,orch_mpi_rank,ierr)
706#endif
707   
708    ENDIF
709    CALL bcast_omp(orch_comm)
710   
711    IF (knon_mpi /= 0) THEN
712      orch_omp_size=0
713      DO i=0,omp_size-1
714        IF (knon_omp_para(i) /=0) THEN
715          orch_omp_size=orch_omp_size+1
716          IF (i==omp_rank) orch_omp_rank=orch_omp_size-1
717        ENDIF
718      ENDDO
719    ENDIF
720   
721   
722  END SUBROUTINE Get_orchidee_communicator
723!
724!****************************************************************************************
725
726
727  SUBROUTINE Init_neighbours(knon,neighbours,knindex,pctsrf)
728    USE mod_grid_phy_lmdz
729    USE mod_surf_para   
730    USE indice_sol_mod
731
732#ifdef CPP_MPI
733    INCLUDE 'mpif.h'
734#endif   
735
736! Input arguments
737!****************************************************************************************
738    INTEGER, INTENT(IN)                     :: knon
739    INTEGER, DIMENSION(klon), INTENT(IN)    :: knindex
740    REAL, DIMENSION(klon), INTENT(IN)       :: pctsrf
741   
742! Output arguments
743!****************************************************************************************
744    INTEGER, DIMENSION(knon,8), INTENT(OUT) :: neighbours
745
746! Local variables
747!****************************************************************************************
748    INTEGER                              :: i, igrid, jj, ij, iglob
749    INTEGER                              :: ierr, ireal, index
750    INTEGER, DIMENSION(8,3)              :: off_ini
751    INTEGER, DIMENSION(8)                :: offset 
752    INTEGER, DIMENSION(nbp_lon,nbp_lat)  :: correspond
753    INTEGER, DIMENSION(knon_glo)         :: ktindex_glo
754    INTEGER, DIMENSION(knon_glo,8)       :: neighbours_glo
755    REAL, DIMENSION(klon_glo)            :: pctsrf_glo
756    INTEGER                              :: ktindex(klon)
757!
758! End definition
759!****************************************************************************************
760
761    ktindex(1:knon)=knindex(1:knon)+(klon_mpi_begin-1)+(klon_omp_begin-1)+nbp_lon-1
762   
763    CALL gather_surf(ktindex(1:knon),ktindex_glo)
764    CALL gather(pctsrf,pctsrf_glo)
765   
766    IF (is_mpi_root .AND. is_omp_root) THEN
767      neighbours_glo(:,:)=-1
768!  Initialisation des offset   
769!
770! offset bord ouest
771       off_ini(1,1) = - nbp_lon   ; off_ini(2,1) = - nbp_lon + 1     ; off_ini(3,1) = 1
772       off_ini(4,1) = nbp_lon + 1 ; off_ini(5,1) = nbp_lon           ; off_ini(6,1) = 2 * nbp_lon - 1
773       off_ini(7,1) = nbp_lon -1  ; off_ini(8,1) = - 1
774! offset point normal
775       off_ini(1,2) = - nbp_lon   ; off_ini(2,2) = - nbp_lon + 1     ; off_ini(3,2) = 1
776       off_ini(4,2) = nbp_lon + 1 ; off_ini(5,2) = nbp_lon           ; off_ini(6,2) = nbp_lon - 1
777       off_ini(7,2) = -1          ; off_ini(8,2) = - nbp_lon - 1
778! offset bord   est
779       off_ini(1,3) = - nbp_lon   ; off_ini(2,3) = - 2 * nbp_lon + 1 ; off_ini(3,3) = - nbp_lon + 1
780       off_ini(4,3) =  1          ; off_ini(5,3) = nbp_lon           ; off_ini(6,3) = nbp_lon - 1
781       off_ini(7,3) = -1          ; off_ini(8,3) = - nbp_lon - 1
782!
783!
784! Attention aux poles
785!
786       DO igrid = 1, knon_glo
787          index = ktindex_glo(igrid)
788          jj = INT((index - 1)/nbp_lon) + 1
789          ij = index - (jj - 1) * nbp_lon
790          correspond(ij,jj) = igrid
791       ENDDO
792!sonia : Les mailles des voisines doivent etre toutes egales (pour couplage orchidee)
793       IF (knon_glo == 1) THEN
794         igrid = 1
795         DO i = 1,8
796           neighbours_glo(igrid, i) = igrid
797         ENDDO
798       ELSE
799       print*,'sonia : knon_glo,ij,jj', knon_glo, ij,jj
800       
801       DO igrid = 1, knon_glo
802          iglob = ktindex_glo(igrid)
803         
804          IF (MOD(iglob, nbp_lon) == 1) THEN
805             offset = off_ini(:,1)
806          ELSE IF(MOD(iglob, nbp_lon) == 0) THEN
807             offset = off_ini(:,3)
808          ELSE
809             offset = off_ini(:,2)
810          ENDIF
811         
812          DO i = 1, 8
813             index = iglob + offset(i)
814             ireal = (MIN(MAX(1, index - nbp_lon + 1), klon_glo))
815             IF (pctsrf_glo(ireal) > EPSFRA) THEN
816                jj = INT((index - 1)/nbp_lon) + 1
817                ij = index - (jj - 1) * nbp_lon
818                neighbours_glo(igrid, i) = correspond(ij, jj)
819             ENDIF
820          ENDDO
821       ENDDO
822       ENDIF !fin knon_glo == 1
823
824    ENDIF
825   
826    DO i = 1, 8
827      CALL scatter_surf(neighbours_glo(:,i),neighbours(1:knon,i))
828    ENDDO
829  END SUBROUTINE Init_neighbours
830
831!
832!****************************************************************************************
833!
834#endif
835#endif
836#endif
837#endif
838END MODULE surf_land_orchidee_mod
Note: See TracBrowser for help on using the repository browser.