3 #ifndef ORCHIDEE_NOOPENMP
16 USE cpl_mod, ONLY : cpl_send_land_fields
27 LOGICAL,
ALLOCATABLE,
SAVE :: flag_omp(:)
35 plev, u1_lay, v1_lay, temp_air, spechum, epot_air, ccanopy, &
36 tq_cdrag, petacoef, peqacoef, petbcoef, peqbcoef, &
37 precip_rain, precip_snow, lwdown, swnet, swdown, &
39 evap, fluxsens, fluxlat, &
40 tsol_rad, tsurf_new, alb1_new, alb2_new, &
41 emis_new, z0_new,
qsurf)
103 include
"dimensions.h"
108 INTEGER,
INTENT(IN) ::
itime
109 REAL,
INTENT(IN) ::
dtime
110 REAL,
INTENT(IN) :: date0
111 INTEGER,
INTENT(IN) :: knon
112 INTEGER,
DIMENSION(klon),
INTENT(IN) :: knindex
113 LOGICAL,
INTENT(IN) :: debut, lafin
114 REAL,
DIMENSION(klon,nbsrf),
INTENT(IN) :: pctsrf
115 REAL,
DIMENSION(klon),
INTENT(IN) ::
rlon,
rlat
116 REAL,
DIMENSION(klon),
INTENT(IN) :: plev
117 REAL,
DIMENSION(klon),
INTENT(IN) :: u1_lay, v1_lay
118 REAL,
DIMENSION(klon),
INTENT(IN) :: temp_air, spechum
119 REAL,
DIMENSION(klon),
INTENT(IN) :: epot_air, ccanopy
120 REAL,
DIMENSION(klon),
INTENT(IN) :: tq_cdrag
121 REAL,
DIMENSION(klon),
INTENT(IN) :: petacoef, peqacoef
122 REAL,
DIMENSION(klon),
INTENT(IN) :: petbcoef, peqbcoef
123 REAL,
DIMENSION(klon),
INTENT(IN) :: precip_rain, precip_snow
124 REAL,
DIMENSION(klon),
INTENT(IN) :: lwdown, swnet, swdown, ps
125 REAL,
DIMENSION(klon),
INTENT(IN) :: q2m, t2m
129 REAL,
DIMENSION(klon),
INTENT(OUT) :: evap, fluxsens, fluxlat,
qsurf
130 REAL,
DIMENSION(klon),
INTENT(OUT) :: tsol_rad, tsurf_new
131 REAL,
DIMENSION(klon),
INTENT(OUT) :: alb1_new, alb2_new
132 REAL,
DIMENSION(klon),
INTENT(OUT) :: emis_new, z0_new
136 INTEGER ::
ij, jj, igrid, ireal, index
138 REAL,
DIMENSION(klon) :: swdown_vrai
139 CHARACTER (len = 20) :: modname =
'surf_land_orchidee'
140 CHARACTER (len = 80) :: abort_message
141 LOGICAL,
SAVE :: check = .false.
149 REAL,
ALLOCATABLE,
DIMENSION(:),
SAVE :: albedo_keep, zlev
152 REAL,
ALLOCATABLE,
DIMENSION(:,:),
SAVE :: lalo
155 INTEGER,
ALLOCATABLE,
DIMENSION(:,:),
SAVE :: neighbours
158 REAL,
ALLOCATABLE,
DIMENSION(:),
SAVE :: contfrac
161 REAL,
ALLOCATABLE,
DIMENSION (:,:),
SAVE :: resolution
164 REAL,
ALLOCATABLE,
DIMENSION (:,:),
SAVE :: lon_scat, lat_scat
167 LOGICAL,
SAVE :: lrestart_read = .true.
169 LOGICAL,
SAVE :: lrestart_write = .false.
172 REAL,
DIMENSION(knon,2) :: albedo_out
175 REAL,
DIMENSION(klon) :: peta_orc, peqa_orc
176 REAL,
DIMENSION(klon) :: petb_orc, peqb_orc
178 INTEGER,
DIMENSION(:),
SAVE,
ALLOCATABLE :: ig, jg
180 INTEGER :: indi, indj
181 INTEGER,
SAVE,
ALLOCATABLE,
DIMENSION(:) :: ktindex
185 REAL,
DIMENSION(klon) :: cdrag
186 INTEGER,
SAVE :: offset
189 REAL,
DIMENSION(klon_glo) :: rlon_g,rlat_g
190 INTEGER,
SAVE :: orch_comm
193 REAL,
ALLOCATABLE,
DIMENSION(:),
SAVE :: coastalflow
195 REAL,
ALLOCATABLE,
DIMENSION(:),
SAVE :: riverflow
198 INTEGER :: orch_omp_rank
199 INTEGER :: orch_omp_size
204 IF (check)
WRITE(
lunout,*)
'Entree ', modname
211 abort_message=
'Pb de coherence: ok_veget = .true. mais CPP_VEGET = .false.'
216 ALLOCATE(ktindex(knon))
217 IF ( .NOT.
ALLOCATED(albedo_keep))
THEN
220 ALLOCATE(albedo_keep(knon))
230 DO igrid = 2, klon - 1
232 IF ( indi >
iim)
THEN
242 IF ((.NOT.
ALLOCATED(lalo)))
THEN
243 ALLOCATE(lalo(knon,2), stat = error)
245 abort_message=
'Pb allocation lalo'
249 IF ((.NOT.
ALLOCATED(lon_scat)))
THEN
250 ALLOCATE(lon_scat(
iim,jjm+1), stat = error)
252 abort_message=
'Pb allocation lon_scat'
256 IF ((.NOT.
ALLOCATED(lat_scat)))
THEN
257 ALLOCATE(lat_scat(
iim,jjm+1), stat = error)
259 abort_message=
'Pb allocation lat_scat'
266 index = knindex(igrid)
267 lalo(igrid,2) =
rlon(index)
268 lalo(igrid,1) =
rlat(index)
276 IF (is_mpi_root)
THEN
281 lon_scat(
ij,jj) = rlon_g(index)
282 lat_scat(
ij,jj) = rlat_g(index)
285 lon_scat(:,1) = lon_scat(:,2)
286 lat_scat(:,1) = rlat_g(1)
287 lon_scat(:,jjm+1) = lon_scat(:,2)
288 lat_scat(:,jjm+1) = rlat_g(klon_glo)
296 IF ( (.NOT.
ALLOCATED(neighbours)))
THEN
297 ALLOCATE(neighbours(knon,8), stat = error)
299 abort_message=
'Pb allocation neighbours'
304 IF (( .NOT.
ALLOCATED(contfrac)))
THEN
305 ALLOCATE(contfrac(knon), stat = error)
307 abort_message=
'Pb allocation contfrac'
313 ireal = knindex(igrid)
314 contfrac(igrid) = pctsrf(ireal,is_ter)
322 IF ( (.NOT.
ALLOCATED(resolution)))
THEN
323 ALLOCATE(resolution(knon,2), stat = error)
325 abort_message=
'Pb allocation resolution'
331 resolution(igrid,1) =
cuphy(
ij)
332 resolution(igrid,2) =
cvphy(
ij)
335 ALLOCATE(coastalflow(klon), stat = error)
337 abort_message=
'Pb allocation coastalflow'
341 ALLOCATE(riverflow(klon), stat = error)
343 abort_message=
'Pb allocation riverflow'
349 IF (carbon_cycle_cpl)
THEN
350 abort_message=
'carbon_cycle_cpl not yet possible with this interface of ORCHIDEE'
360 IF (lafin) lrestart_write = .true.
361 IF (check)
WRITE(
lunout,*)
'lafin ',lafin,lrestart_write
363 peta_orc(1:knon) = petbcoef(1:knon) *
dtime
364 petb_orc(1:knon) = petacoef(1:knon)
365 peqa_orc(1:knon) = peqbcoef(1:knon) *
dtime
366 peqb_orc(1:knon) = peqacoef(1:knon)
369 cdrag(1:knon) = tq_cdrag(1:knon)
372 zlev(1:knon) = (100.*plev(1:knon))/((ps(1:knon)/rd*temp_air(1:knon))*rg)
389 CALL init_intersurf(nbp_lon,nbp_lat,knon,ktindex,offset,orch_omp_size,orch_omp_rank,orch_comm)
398 lrestart_read, lrestart_write, lalo, &
399 contfrac, neighbours, resolution, date0, &
400 zlev, u1_lay, v1_lay, spechum, temp_air, epot_air, ccanopy, &
401 cdrag, peta_orc, peqa_orc, petb_orc, peqb_orc, &
402 precip_rain, precip_snow, lwdown, swnet, swdown, ps, &
403 evap, fluxsens, fluxlat, coastalflow, riverflow, &
404 tsol_rad, tsurf_new,
qsurf, albedo_out, emis_new, z0_new, &
405 lon_scat, lat_scat, q2m, t2m)
411 albedo_keep(1:knon) = (albedo_out(1:knon,1)+albedo_out(1:knon,2))/2.
417 swdown_vrai(1:knon) = swdown(1:knon)
422 lrestart_read, lrestart_write, lalo, &
423 contfrac, neighbours, resolution, date0, &
424 zlev, u1_lay(1:knon), v1_lay(1:knon), spechum(1:knon), temp_air(1:knon), epot_air(1:knon), ccanopy(1:knon), &
425 cdrag(1:knon), peta_orc(1:knon), peqa_orc(1:knon), petb_orc(1:knon), peqb_orc(1:knon), &
426 precip_rain(1:knon), precip_snow(1:knon), lwdown(1:knon), swnet(1:knon), swdown_vrai(1:knon), ps(1:knon), &
427 evap(1:knon), fluxsens(1:knon), fluxlat(1:knon), coastalflow(1:knon), riverflow(1:knon), &
428 tsol_rad(1:knon), tsurf_new(1:knon),
qsurf(1:knon), albedo_out(1:knon,:), emis_new(1:knon), z0_new(1:knon), &
429 lon_scat, lat_scat, q2m, t2m)
435 albedo_keep(1:knon) = (albedo_out(1:knon,1)+albedo_out(1:knon,2))/2.
439 IF (type_ocean==
'couple')
THEN
441 riverflow, coastalflow)
444 alb1_new(1:knon) = albedo_out(1:knon,1)
445 alb2_new(1:knon) = albedo_out(1:knon,2)
448 fluxsens(1:knon) = -1. * fluxsens(1:knon)
449 fluxlat(1:knon) = -1. * fluxlat(1:knon)
453 IF (debut) lrestart_read = .false.
466 INTEGER,
INTENT(IN) :: knon
467 INTEGER,
INTENT(IN) :: knindex(klon)
468 INTEGER,
INTENT(OUT) :: offset
469 INTEGER,
INTENT(OUT) :: ktindex(klon)
471 INTEGER :: ktindex_glo(knon_glo)
472 INTEGER :: offset_para(0:omp_size*mpi_size-1)
476 ktindex(1:knon)=knindex(1:knon)+(klon_mpi_begin-1)+(klon_omp_begin-1)+nbp_lon-1
480 IF (is_mpi_root .AND. is_omp_root)
THEN
482 DO task=0,mpi_size*omp_size-1
483 IF (knon_glo_para(task)>0)
THEN
484 offset_para(task)= lastpoint-mod(lastpoint,nbp_lon)
485 lastpoint=ktindex_glo(knon_glo_end_para(task))
490 CALL
bcast(offset_para)
492 offset=offset_para(omp_size*mpi_rank+omp_rank)
494 ktindex(1:knon)=ktindex(1:knon)-offset
509 INTEGER,
INTENT(OUT) :: orch_comm
510 INTEGER,
INTENT(OUT) :: orch_omp_size
511 INTEGER,
INTENT(OUT) :: orch_omp_rank
519 IF (is_omp_root)
THEN
521 IF (knon_mpi==0)
THEN
528 CALL mpi_comm_split(comm_lmdz_phy,color,mpi_rank,orch_comm,ierr)
532 CALL bcast_omp(orch_comm)
534 IF (knon_mpi /= 0)
THEN
537 IF (knon_omp_para(
i) /=0)
THEN
538 orch_omp_size=orch_omp_size+1
539 IF (
i==omp_rank) orch_omp_rank=orch_omp_size-1
553 include
"indicesol.h"
561 INTEGER,
INTENT(IN) :: knon
562 INTEGER,
DIMENSION(klon),
INTENT(IN) :: knindex
563 REAL,
DIMENSION(klon),
INTENT(IN) :: pctsrf
567 INTEGER,
DIMENSION(knon,8),
INTENT(OUT) :: neighbours
571 INTEGER ::
i, igrid, jj,
ij, iglob
572 INTEGER :: ierr, ireal, index
573 INTEGER,
DIMENSION(8,3) :: off_ini
574 INTEGER,
DIMENSION(8) :: offset
575 INTEGER,
DIMENSION(nbp_lon,nbp_lat) :: correspond
576 INTEGER,
DIMENSION(knon_glo) :: ktindex_glo
577 INTEGER,
DIMENSION(knon_glo,8) :: neighbours_glo
578 REAL,
DIMENSION(klon_glo) :: pctsrf_glo
579 INTEGER :: ktindex(klon)
584 ktindex(1:knon)=knindex(1:knon)+(klon_mpi_begin-1)+(klon_omp_begin-1)+nbp_lon-1
587 CALL
gather(pctsrf,pctsrf_glo)
589 IF (is_mpi_root .AND. is_omp_root)
THEN
590 neighbours_glo(:,:)=-1
594 off_ini(1,1) = - nbp_lon ; off_ini(2,1) = - nbp_lon + 1 ; off_ini(3,1) = 1
595 off_ini(4,1) = nbp_lon + 1 ; off_ini(5,1) = nbp_lon ; off_ini(6,1) = 2 * nbp_lon - 1
596 off_ini(7,1) = nbp_lon -1 ; off_ini(8,1) = - 1
598 off_ini(1,2) = - nbp_lon ; off_ini(2,2) = - nbp_lon + 1 ; off_ini(3,2) = 1
599 off_ini(4,2) = nbp_lon + 1 ; off_ini(5,2) = nbp_lon ; off_ini(6,2) = nbp_lon - 1
600 off_ini(7,2) = -1 ; off_ini(8,2) = - nbp_lon - 1
602 off_ini(1,3) = - nbp_lon ; off_ini(2,3) = - 2 * nbp_lon + 1 ; off_ini(3,3) = - nbp_lon + 1
603 off_ini(4,3) = 1 ; off_ini(5,3) = nbp_lon ; off_ini(6,3) = nbp_lon - 1
604 off_ini(7,3) = -1 ; off_ini(8,3) = - nbp_lon - 1
609 DO igrid = 1, knon_glo
610 index = ktindex_glo(igrid)
611 jj = int((index - 1)/nbp_lon) + 1
612 ij = index - (jj - 1) * nbp_lon
613 correspond(
ij,jj) = igrid
616 DO igrid = 1, knon_glo
617 iglob = ktindex_glo(igrid)
619 IF (mod(iglob, nbp_lon) == 1)
THEN
620 offset = off_ini(:,1)
621 ELSE IF(mod(iglob, nbp_lon) == 0)
THEN
622 offset = off_ini(:,3)
624 offset = off_ini(:,2)
628 index = iglob + offset(
i)
629 ireal = (min(max(1, index - nbp_lon + 1), klon_glo))
630 IF (pctsrf_glo(ireal) > epsfra)
THEN
631 jj = int((index - 1)/nbp_lon) + 1
632 ij = index - (jj - 1) * nbp_lon
633 neighbours_glo(igrid,
i) = correspond(
ij, jj)