9 #ifdef ORCHIDEE_NOOPENMP
30 PUBLIC :: surf_land_orchidee
36 SUBROUTINE surf_land_orchidee(itime, dtime, date0, knon, &
39 plev, u1_lay, v1_lay, temp_air, spechum, epot_air, ccanopy, &
40 tq_cdrag, petacoef, peqacoef, petbcoef, peqbcoef, &
41 precip_rain, precip_snow, lwdown, swnet, swdown, &
43 evap, fluxsens, fluxlat, &
44 tsol_rad, tsurf_new, alb1_new, alb2_new, &
45 emis_new, z0_new, qsurf)
112 INTEGER,
INTENT(IN) ::
itime
113 REAL,
INTENT(IN) :: dtime
114 REAL,
INTENT(IN) :: date0
115 INTEGER,
INTENT(IN) :: knon
116 INTEGER,
DIMENSION(klon),
INTENT(IN) :: knindex
117 LOGICAL,
INTENT(IN) :: debut, lafin
118 REAL,
DIMENSION(klon,nbsrf),
INTENT(IN) :: pctsrf
119 REAL,
DIMENSION(klon),
INTENT(IN) ::
rlon,
rlat
120 REAL,
DIMENSION(klon),
INTENT(IN) :: plev
121 REAL,
DIMENSION(klon),
INTENT(IN) :: u1_lay, v1_lay
122 REAL,
DIMENSION(klon),
INTENT(IN) :: temp_air, spechum
123 REAL,
DIMENSION(klon),
INTENT(IN) :: epot_air, ccanopy
124 REAL,
DIMENSION(klon),
INTENT(IN) :: tq_cdrag
125 REAL,
DIMENSION(klon),
INTENT(IN) :: petacoef, peqacoef
126 REAL,
DIMENSION(klon),
INTENT(IN) :: petbcoef, peqbcoef
127 REAL,
DIMENSION(klon),
INTENT(IN) :: precip_rain, precip_snow
128 REAL,
DIMENSION(klon),
INTENT(IN) :: lwdown, swnet, swdown, ps
129 REAL,
DIMENSION(klon),
INTENT(IN) :: q2m, t2m
133 REAL,
DIMENSION(klon),
INTENT(OUT) :: evap, fluxsens, fluxlat, qsurf
134 REAL,
DIMENSION(klon),
INTENT(OUT) :: tsol_rad, tsurf_new
135 REAL,
DIMENSION(klon),
INTENT(OUT) :: alb1_new, alb2_new
136 REAL,
DIMENSION(klon),
INTENT(OUT) :: emis_new, z0_new
140 INTEGER ::
ij, jj, igrid, ireal, index
142 INTEGER,
SAVE :: nb_fields_cpl
143 REAL,
SAVE,
ALLOCATABLE,
DIMENSION(:,:) :: fields_cpl
144 REAL,
DIMENSION(klon) :: swdown_vrai
145 CHARACTER (len = 20) :: modname =
'surf_land_orchidee'
146 CHARACTER (len = 80) :: abort_message
147 LOGICAL,
SAVE :: check = .
false.
155 REAL,
ALLOCATABLE,
DIMENSION(:),
SAVE :: albedo_keep, zlev
158 REAL,
ALLOCATABLE,
DIMENSION(:,:),
SAVE :: lalo
161 INTEGER,
ALLOCATABLE,
DIMENSION(:,:),
SAVE :: neighbours
164 REAL,
ALLOCATABLE,
DIMENSION(:),
SAVE :: contfrac
167 REAL,
ALLOCATABLE,
DIMENSION (:,:),
SAVE :: resolution
170 REAL,
ALLOCATABLE,
DIMENSION (:,:),
SAVE :: lon_scat, lat_scat
173 LOGICAL,
SAVE :: lrestart_read = .
true.
175 LOGICAL,
SAVE :: lrestart_write = .
false.
178 REAL,
DIMENSION(knon,2) :: albedo_out
182 REAL,
DIMENSION(klon) :: peta_orc, peqa_orc
183 REAL,
DIMENSION(klon) :: petb_orc, peqb_orc
185 INTEGER,
DIMENSION(:),
SAVE,
ALLOCATABLE :: ig, jg
187 INTEGER :: indi, indj
188 INTEGER,
SAVE,
ALLOCATABLE,
DIMENSION(:) :: ktindex
192 REAL,
DIMENSION(klon) ::
cdrag
193 INTEGER,
SAVE :: offset
196 REAL,
DIMENSION(klon_glo) :: rlon_g,rlat_g
197 INTEGER,
SAVE :: orch_comm
200 REAL,
ALLOCATABLE,
DIMENSION(:),
SAVE :: coastalflow
202 REAL,
ALLOCATABLE,
DIMENSION(:),
SAVE :: riverflow
209 IF (check)
WRITE(
lunout,*)
'Entree ', modname
218 abort_message=
'You must define preprossing key ORCH_NEW when running carbon_cycle_cpl=y'
222 ALLOCATE(ktindex(knon))
223 IF ( .NOT.
ALLOCATED(albedo_keep))
THEN
224 ALLOCATE(albedo_keep(
klon))
234 DO igrid = 2,
klon - 1
246 IF ((.NOT.
ALLOCATED(lalo)))
THEN
247 ALLOCATE(lalo(knon,2), stat = error)
249 abort_message=
'Pb allocation lalo'
253 IF ((.NOT.
ALLOCATED(lon_scat)))
THEN
256 abort_message=
'Pb allocation lon_scat'
260 IF ((.NOT.
ALLOCATED(lat_scat)))
THEN
263 abort_message=
'Pb allocation lat_scat'
270 index = knindex(igrid)
271 lalo(igrid,2) =
rlon(index)
272 lalo(igrid,1) =
rlat(index)
280 IF (is_mpi_root)
THEN
285 lon_scat(
ij,jj) = rlon_g(index)
286 lat_scat(
ij,jj) = rlat_g(index)
289 lon_scat(:,1) = lon_scat(:,2)
290 lat_scat(:,1) = rlat_g(1)
291 lon_scat(:,
nbp_lat) = lon_scat(:,2)
292 lat_scat(:,
nbp_lat) = rlat_g(klon_glo)
301 IF ( (.NOT.
ALLOCATED(neighbours)))
THEN
302 ALLOCATE(neighbours(knon,8), stat = error)
304 abort_message=
'Pb allocation neighbours'
309 IF (( .NOT.
ALLOCATED(contfrac)))
THEN
310 ALLOCATE(contfrac(knon), stat = error)
312 abort_message=
'Pb allocation contfrac'
318 ireal = knindex(igrid)
319 contfrac(igrid) = pctsrf(ireal,
is_ter)
323 CALL init_neighbours(knon,neighbours,knindex,pctsrf(:,
is_ter))
327 IF ( (.NOT.
ALLOCATED(resolution)))
THEN
328 ALLOCATE(resolution(knon,2), stat = error)
330 abort_message=
'Pb allocation resolution'
336 resolution(igrid,1) =
dx(
ij)
337 resolution(igrid,2) =
dy(
ij)
340 ALLOCATE(coastalflow(
klon), stat = error)
342 abort_message=
'Pb allocation coastalflow'
346 ALLOCATE(riverflow(
klon), stat = error)
348 abort_message=
'Pb allocation riverflow'
363 IF (error /= 0)
CALL abort_physic(modname,
'Pb in allocation fco2_land_inst',1)
366 IF(error /=0)
CALL abort_physic(modname,
'Pb in allocation fco2_lu_inst',1)
369 ALLOCATE(fields_cpl(
klon,nb_fields_cpl), stat = error)
370 IF (error /= 0)
CALL abort_physic(modname,
'Pb in allocation fields_cpl',1)
377 IF (lafin) lrestart_write = .
true.
378 IF (check)
WRITE(
lunout,*)
'lafin ',lafin,lrestart_write
380 peta_orc(1:knon) = petbcoef(1:knon) * dtime
381 petb_orc(1:knon) = petacoef(1:knon)
382 peqa_orc(1:knon) = peqbcoef(1:knon) * dtime
383 peqb_orc(1:knon) = peqacoef(1:knon)
386 cdrag(1:knon) = tq_cdrag(1:knon)
389 zlev(1:knon) = (100.*plev(1:knon))/((ps(1:knon)/rd*temp_air(1:knon))*
rg)
411 CALL get_orchidee_communicator(knon,orch_comm)
413 CALL init_orchidee_index(knon,orch_comm,knindex,offset,ktindex)
418 lrestart_read, lrestart_write, lalo, &
419 contfrac, neighbours, resolution, date0, &
420 zlev, u1_lay, v1_lay, spechum, temp_air, epot_air, ccanopy, &
421 cdrag, peta_orc, peqa_orc, petb_orc, peqb_orc, &
422 precip_rain, precip_snow, lwdown, swnet, swdown, ps, &
423 evap, fluxsens, fluxlat, coastalflow, riverflow, &
424 tsol_rad, tsurf_new, qsurf, albedo_out, emis_new, z0_new, &
425 lon_scat, lat_scat, q2m, t2m &
427 , nb_fields_cpl, fields_cpl)
435 orch_comm, dtime, lrestart_read, lrestart_write, lalo, &
436 contfrac, neighbours, resolution, date0, &
437 zlev, u1_lay(1:knon), v1_lay(1:knon), spechum(1:knon), temp_air(1:knon), epot_air(1:knon), ccanopy(1:knon), &
438 cdrag(1:knon), peta_orc(1:knon), peqa_orc(1:knon), petb_orc(1:knon), peqb_orc(1:knon), &
439 precip_rain(1:knon), precip_snow(1:knon), lwdown(1:knon), swnet(1:knon), swdown(1:knon), ps(1:knon), &
440 evap(1:knon), fluxsens(1:knon), fluxlat(1:knon), coastalflow(1:knon), riverflow(1:knon), &
441 tsol_rad(1:knon), tsurf_new(1:knon), qsurf(1:knon), albedo_out(1:knon,:), emis_new(1:knon), z0_new(1:knon), &
442 lon_scat, lat_scat, q2m, t2m &
444 , nb_fields_cpl, fields_cpl(1:knon,:))
452 albedo_keep(1:knon) = (albedo_out(1:knon,1)+albedo_out(1:knon,2))/2.
457 swdown_vrai(1:knon) = swdown(1:knon)
463 lrestart_read, lrestart_write, lalo, &
464 contfrac, neighbours, resolution, date0, &
465 zlev, u1_lay, v1_lay, spechum, temp_air, epot_air, ccanopy, &
466 cdrag, peta_orc, peqa_orc, petb_orc, peqb_orc, &
467 precip_rain, precip_snow, lwdown, swnet, swdown_vrai, ps, &
468 evap, fluxsens, fluxlat, coastalflow, riverflow, &
469 tsol_rad, tsurf_new, qsurf, albedo_out, emis_new, z0_new, &
470 lon_scat, lat_scat, q2m, t2m &
472 , nb_fields_cpl, fields_cpl)
479 orch_comm,dtime, lrestart_read, lrestart_write, lalo, &
480 contfrac, neighbours, resolution, date0, &
481 zlev, u1_lay(1:knon), v1_lay(1:knon), spechum(1:knon), temp_air(1:knon), epot_air(1:knon), ccanopy(1:knon), &
482 cdrag(1:knon), peta_orc(1:knon), peqa_orc(1:knon), petb_orc(1:knon), peqb_orc(1:knon), &
483 precip_rain(1:knon), precip_snow(1:knon), lwdown(1:knon), swnet(1:knon), swdown_vrai(1:knon), ps(1:knon), &
484 evap(1:knon), fluxsens(1:knon), fluxlat(1:knon), coastalflow(1:knon), riverflow(1:knon), &
485 tsol_rad(1:knon), tsurf_new(1:knon), qsurf(1:knon), albedo_out(1:knon,:), emis_new(1:knon), z0_new(1:knon), &
486 lon_scat, lat_scat, q2m, t2m &
488 , nb_fields_cpl, fields_cpl(1:knon,:))
495 albedo_keep(1:knon) = (albedo_out(1:knon,1)+albedo_out(1:knon,2))/2.
501 riverflow, coastalflow)
504 alb1_new(1:knon) = albedo_out(1:knon,1)
505 alb2_new(1:knon) = albedo_out(1:knon,2)
508 fluxsens(1:knon) = -1. * fluxsens(1:knon)
509 fluxlat(1:knon) = -1. * fluxlat(1:knon)
513 IF (debut) lrestart_read = .
false.
521 ireal = knindex(igrid)
528 END SUBROUTINE surf_land_orchidee
532 SUBROUTINE init_orchidee_index(knon,orch_comm,knindex,offset,ktindex)
543 INTEGER,
INTENT(IN) :: knon
544 INTEGER,
INTENT(IN) :: orch_comm
545 INTEGER,
DIMENSION(klon),
INTENT(IN) :: knindex
549 INTEGER,
INTENT(OUT) :: offset
550 INTEGER,
DIMENSION(knon),
INTENT(OUT) :: ktindex
555 INTEGER,
DIMENSION(MPI_STATUS_SIZE) :: status
558 INTEGER :: mylastpoint
560 INTEGER :: mpi_rank_orch
561 INTEGER :: mpi_size_orch
567 mylastpoint=klon_mpi_begin-1+knindex(knon)+
nbp_lon-1
571 CALL mpi_comm_size(orch_comm,mpi_size_orch,ierr)
572 CALL mpi_comm_rank(orch_comm,mpi_rank_orch,ierr)
580 IF (mpi_rank_orch /= 0)
THEN
582 CALL mpi_recv(lastpoint,1,mpi_integer,mpi_rank_orch-1,1234,orch_comm,status,ierr)
586 IF (mpi_rank_orch /= mpi_size_orch-1)
THEN
588 CALL mpi_send(mylastpoint,1,mpi_integer,mpi_rank_orch+1,1234,orch_comm,ierr)
593 IF (mpi_rank_orch == 0)
THEN
596 offset=lastpoint-mod(lastpoint,
nbp_lon)
599 ktindex(1:knon)=knindex(1:knon)+(klon_mpi_begin+
nbp_lon-1)-offset-1
602 END SUBROUTINE init_orchidee_index
606 SUBROUTINE get_orchidee_communicator(knon,orch_comm)
613 INTEGER,
INTENT(IN) :: knon
614 INTEGER,
INTENT(OUT) :: orch_comm
629 CALL mpi_comm_split(comm_lmdz_phy,color,mpi_rank,orch_comm,ierr)
632 END SUBROUTINE get_orchidee_communicator
636 SUBROUTINE init_neighbours(knon,neighbours,ktindex,pctsrf)
647 INTEGER,
INTENT(IN) :: knon
648 INTEGER,
DIMENSION(klon),
INTENT(IN) :: ktindex
649 REAL,
DIMENSION(klon),
INTENT(IN) :: pctsrf
653 INTEGER,
DIMENSION(knon,8),
INTENT(OUT) :: neighbours
658 INTEGER :: i, igrid, jj,
ij, iglob
659 INTEGER :: ierr, ireal, index
661 INTEGER,
DIMENSION(0:mpi_size-1) :: knon_nb
662 INTEGER,
DIMENSION(0:mpi_size-1) :: displs
663 INTEGER,
DIMENSION(8,3) :: off_ini
664 INTEGER,
DIMENSION(8) :: offset
665 INTEGER,
DIMENSION(knon) :: ktindex_p
666 INTEGER,
DIMENSION(nbp_lon,nbp_lat) :: correspond
667 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ktindex_g
668 INTEGER,
ALLOCATABLE,
DIMENSION(:,:) :: neighbours_g
669 REAL,
DIMENSION(klon_glo) :: pctsrf_g
680 CALL mpi_gather(knon,1,mpi_integer,knon_nb,1,mpi_integer,0,comm_lmdz_phy,ierr)
685 IF (is_mpi_root)
THEN
686 knon_g=sum(knon_nb(:))
687 ALLOCATE(ktindex_g(knon_g))
688 ALLOCATE(neighbours_g(knon_g,8))
692 displs(i)=displs(i-1)+knon_nb(i-1)
695 ALLOCATE(ktindex_g(1))
696 ALLOCATE(neighbours_g(1,8))
699 ktindex_p(1:knon)=ktindex(1:knon)+klon_mpi_begin-1+
nbp_lon-1
702 ktindex_g(:)=ktindex_p(:)
706 CALL mpi_gatherv(ktindex_p,knon,mpi_integer,ktindex_g,knon_nb,&
707 displs,mpi_integer,0,comm_lmdz_phy,ierr)
712 CALL gather(pctsrf,pctsrf_g)
714 IF (is_mpi_root)
THEN
718 off_ini(1,1) = -
nbp_lon ; off_ini(2,1) = -
nbp_lon + 1; off_ini(3,1) = 1
720 off_ini(7,1) =
nbp_lon -1 ; off_ini(8,1) = - 1
722 off_ini(1,2) = -
nbp_lon ; off_ini(2,2) = -
nbp_lon + 1; off_ini(3,2) = 1
724 off_ini(7,2) = -1 ; off_ini(8,2) = -
nbp_lon - 1
727 off_ini(4,3) = 1 ; off_ini(5,3) =
nbp_lon ; off_ini(6,3) =
nbp_lon - 1
728 off_ini(7,3) = -1 ; off_ini(8,3) = -
nbp_lon - 1
734 index = ktindex_g(igrid)
735 jj = int((index - 1)/
nbp_lon) + 1
737 correspond(
ij,jj) = igrid
741 iglob = ktindex_g(igrid)
742 IF (mod(iglob,
nbp_lon) == 1)
THEN
743 offset = off_ini(:,1)
744 ELSE IF(mod(iglob,
nbp_lon) == 0)
THEN
745 offset = off_ini(:,3)
747 offset = off_ini(:,2)
750 index = iglob + offset(i)
751 ireal = (min(max(1, index -
nbp_lon + 1), klon_glo))
752 IF (pctsrf_g(ireal) >
epsfra)
THEN
753 jj = int((index - 1)/
nbp_lon) + 1
755 neighbours_g(igrid, i) = correspond(
ij, jj)
764 neighbours(:,i)=neighbours_g(:,i)
769 CALL mpi_scatterv(neighbours_g(:,i),knon_nb,displs,mpi_integer,neighbours(:,i),knon,mpi_integer,0,comm_lmdz_phy,ierr)
772 CALL mpi_scatterv(neighbours_g(:,i),knon_nb,displs,mpi_integer,var_tmp,knon,mpi_integer,0,comm_lmdz_phy,ierr)
778 END SUBROUTINE init_neighbours
!IM Implemente en modes sequentiel et parallele CALL rlon_glo CALL bcast(rlon_glo)!$OMP MASTER if(is_mpi_root) then!zstophy
integer, parameter is_ter
real, dimension(:), allocatable, save dx
real, dimension(:), allocatable, public fco2_land_inst
real, dimension(:), allocatable, public fco2_lu_inst
!$Id itapm1 ENDIF!IM on interpole les champs sur les niveaux STD de pression!IM a chaque pas de temps de la physique c!positionnement de l argument logique a false c!pour ne pas recalculer deux fois la meme chose!c!a cet effet un appel a plevel_new a ete deplace c!a la fin de la serie d appels c!la boucle DO nlevSTD a ete internalisee c!dans d ou la creation de cette routine c c!CALL false
!$Id klon klev DO klon!IM klev DO klon klon nbp_lat DO nbp_lon ij
!IM Implemente en modes sequentiel et parallele CALL gather(rlat, rlat_glo) CALL bcast(rlat_glo) CALL gather(rlon
real, dimension(:), allocatable, save dy
!$Id itapm1 ENDIF!IM on interpole les champs sur les niveaux STD de pression!IM a chaque pas de temps de la physique c!positionnement de l argument logique a false c!pour ne pas recalculer deux fois la meme chose!c!a cet effet un appel a plevel_new a ete deplace c!a la fin de la serie d appels c!la boucle DO nlevSTD a ete internalisee c!dans d ou la creation de cette routine c c!CALL ulevSTD CALL &zphi philevSTD CALL &zx_rh rhlevSTD!DO klev DO klon klev DO klon klev DO klon klev DO klon klev DO klon klev DO klon klev DO klon klev DO klon klev DO klon klev DO klon du jour ou toutes les read_climoz CALL true
c c $Id c nbregdyn DO klon c rlat(i) c ENDIF!lon c ENDIF!lat ENDIF!pctsrf ENDDO!klon ENDDO!nbregdyn cIM 190504 ENDIF!ok_regdyn cIM somme de toutes les nhistoW BEG IF(debut) THEN DO nreg
character(len=6), save type_ocean
subroutine cdrag(knon, nsrf, speed, t1, q1, zgeop1, psol, tsurf, qsurf, z0m, z0h, pcfm, pcfh, zri, pref)
logical, save is_parallel
subroutine, public cpl_send_land_fields(itime, knon, knindex, rriv_in, rcoa_in)
!$Header!integer nvarmx s s itime
subroutine abort_physic(modname, message, ierr)
logical, public carbon_cycle_cpl
logical, save is_sequential
c c $Id c nbregdyn DO klon c rlon(i)
!$Header!gestion des impressions de sorties et de débogage la sortie standard prt_level COMMON comprint lunout