source: LMDZ6/trunk/libf/phylmd/surf_land_orchidee_nolic_mod.F90 @ 4608

Last change on this file since 4608 was 4600, checked in by yann meurdesoif, 18 months ago

Suppress CPP_MPI key usage in source code. MPI wrappers is used to supress missing symbol if the mpi library is not linked

YM

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