Changeset 4229 for dynamico_lmdz/simple_physics/phyparam
- Timestamp:
- Jan 16, 2020, 1:57:14 PM (5 years ago)
- Location:
- dynamico_lmdz/simple_physics/phyparam
- Files:
-
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
dynamico_lmdz/simple_physics/phyparam/Makefile
r4228 r4229 22 22 clean : 23 23 rm -f obj/* include/* lib/* xml/* 24 24 ../bash/beautify.sh physics/*.F90 25 25 %.so : $(OBJECTS) 26 26 $(F90) -shared $^ -o $@ -
dynamico_lmdz/simple_physics/phyparam/physics/astronomy.F90
r4228 r4229 1 1 MODULE astronomy 2 2 3 3 #include "use_logging.h" 4 4 … … 12 12 13 13 CONTAINS 14 14 15 15 SUBROUTINE solarlong(pday,psollong) 16 16 REAL, INTENT(IN) :: pday ! jour de l'annee (le jour 0 correspondant a l'equinoxe) … … 18 18 LOGICAL, PARAMETER :: lwrite=.TRUE. 19 19 20 ! Local:21 ! ------20 ! Local: 21 ! ------ 22 22 REAL zanom,xref,zx0,zdx,zteta,zz 23 23 INTEGER iter 24 24 25 !--------------------------------------------------------26 ! calcul de l'angle polaire et de la distance au soleil :27 ! -------------------------------------------------------25 !-------------------------------------------------------- 26 ! calcul de l'angle polaire et de la distance au soleil : 27 ! ------------------------------------------------------- 28 28 29 ! calcul de l'zanomalie moyenne29 ! calcul de l'zanomalie moyenne 30 30 31 31 zz=(pday-peri_day)/year_day … … 33 33 xref=abs(zanom) 34 34 35 ! resolution de l'equation horaire zx0 - e * sin (zx0) = xref36 ! methode de Newton37 35 ! resolution de l'equation horaire zx0 - e * sin (zx0) = xref 36 ! methode de Newton 37 38 38 zx0=xref+e_elips*sin(xref) 39 39 DO iter=1,10 … … 43 43 zx0=zx0+zdx 44 44 if(zanom.lt.0.) zx0=-zx0 45 45 46 46 ! zteta est la longitude solaire 47 47 48 48 zteta=2.*atan(sqrt((1.+e_elips)/(1.-e_elips))*tan(zx0/2.)) 49 49 50 50 psollong=zteta-timeperi 51 51 52 52 IF(psollong.LT.0.) psollong=psollong+2.*pi 53 53 IF(psollong.GT.2.*pi) psollong=psollong-2.*pi … … 55 55 ! sorties eventuelles: 56 56 ! --------------------- 57 57 58 58 IF (lwrite) THEN 59 59 WRITELOG(*,*) 'day of the year :',pday … … 61 61 LOG_DBG('solarlong') 62 62 ENDIF 63 63 64 64 END SUBROUTINE solarlong 65 65 66 66 SUBROUTINE iniorbit 67 67 !======================================================================= … … 92 92 ! 93 93 !======================================================================= 94 94 95 95 !----------------------------------------------------------------------- 96 96 97 97 ! Local: 98 98 ! ------ 99 99 REAL zxref,zanom,zz,zx0,zdx 100 100 INTEGER iter 101 101 102 102 !----------------------------------------------------------------------- 103 103 104 104 WRITELOG(*,*) 'Perihelie en Mkm ',periheli 105 WRITELOG(*,*) 'Aphelise en Mkm ',aphelie 105 WRITELOG(*,*) 'Aphelise en Mkm ',aphelie 106 106 WRITELOG(*,*) 'obliquite en degres :',obliquit 107 107 108 108 e_elips=(aphelie-periheli)/(periheli+aphelie) 109 109 p_elips=0.5*(periheli+aphelie)*(1-e_elips*e_elips)/unitastr 110 110 111 111 WRITELOG(*,*) 'e_elips',e_elips 112 112 WRITELOG(*,*) 'p_elips',p_elips … … 115 115 ! calcul de l'angle polaire et de la distance au soleil : 116 116 ! ------------------------------------------------------- 117 117 118 118 ! calcul de l'zanomalie moyenne 119 119 120 120 zz=(year_day-peri_day)/year_day 121 121 zanom=2.*pi*(zz-nint(zz)) 122 122 zxref=abs(zanom) 123 123 WRITELOG(*,*) 'zanom ',zanom 124 124 125 125 ! resolution de l'equation horaire zx0 - e * sin (zx0) = zxref 126 126 ! methode de Newton 127 127 128 128 zx0=zxref+e_elips*sin(zxref) 129 129 DO iter=1,100 130 130 zdx=-(zx0-e_elips*sin(zx0)-zxref)/(1.-e_elips*cos(zx0)) 131 ! if(abs(zdx).le.(1.e-12)) goto 120132 131 zx0=zx0+zdx 133 132 END DO 134 133 135 134 zx0=zx0+zdx 136 135 if(zanom.lt.0.) zx0=-zx0 137 136 WRITELOG(*,*) 'zx0 ',zx0 138 137 139 138 ! zteta est la longitude solaire 140 139 141 140 timeperi=2.*atan(sqrt((1.+e_elips)/(1.-e_elips))*tan(zx0/2.)) 142 141 WRITELOG(*,*) 'longitude solaire du perihelie timeperi = ',timeperi 143 142 144 143 LOG_INFO('iniorbit') 145 144 146 145 END SUBROUTINE iniorbit 147 146 … … 171 170 ! Declarations: 172 171 ! ------------- 173 172 174 173 ! arguments: 175 174 ! ---------- … … 177 176 REAL, INTENT(IN) :: pls 178 177 REAL, INTENT(OUT) :: pdist_sol,pdecli 179 178 180 179 !----------------------------------------------------------------------- 181 180 182 181 ! Distance Sun-Planet 183 182 184 183 pdist_sol=p_elips/(1.+e_elips*cos(pls+timeperi)) 185 184 186 185 ! Solar declination 187 186 188 187 pdecli= asin (sin(pls)*sin(obliquit*pi/180.)) 189 188 190 189 END SUBROUTINE orbite 191 190 192 191 END MODULE astronomy 193 -
dynamico_lmdz/simple_physics/phyparam/physics/callkeys.F90
r4223 r4229 2 2 IMPLICIT NONE 3 3 SAVE 4 4 5 5 LOGICAL callrad,calldifv,calladj,callcond,callsoil,season,diurnal,lverbose 6 6 INTEGER iradia -
dynamico_lmdz/simple_physics/phyparam/physics/comgeomfi.F90
r4217 r4229 5 5 REAL, ALLOCATABLE :: long(:), lati(:), sinlon(:), coslon(:), sinlat(:), coslat(:) 6 6 INTEGER :: ngridmax, nlayermx, nsoilmx 7 !$OMP THREADPRIVATE(long,lati,sinlon,coslon,sinlat,coslat,totarea)8 !$OMP THREADPRIVATE(ngridmax,nlayermx,nsoilmx)7 !$OMP THREADPRIVATE(long,lati,sinlon,coslon,sinlat,coslat,totarea) 8 !$OMP THREADPRIVATE(ngridmax,nlayermx,nsoilmx) 9 9 10 10 CONTAINS 11 11 12 12 SUBROUTINE init_comgeomfi(klon, klev, longitude, latitude) 13 13 INTEGER, INTENT(IN) :: klon, klev … … 29 29 coslon(:)=cos(long(:)) 30 30 END SUBROUTINE init_comgeomfi 31 31 32 32 END MODULE comgeomfi -
dynamico_lmdz/simple_physics/phyparam/physics/convection.F90
r4207 r4229 76 76 ! * momentum u,v is mixed with weight zalpha, i.e. u:=zalpha*mean(u)+(1-zalpha)*u 77 77 ! where zalpha = sum( abs(theta-mean(theta))*dsig) / mean(theta)*sum(dsig) 78 ! for large deviations of theta from its mean, this formula could in principe yield zalpha>1. 78 ! for large deviations of theta from its mean, this formula could in principe yield zalpha>1. 79 79 zalpha=0. 80 80 zum=0. … … 84 84 zh2(i, l) = zhm 85 85 ! we must use compute zum, zvm from zu2, zv2 to conserve momentum (see below) 86 zum=zum+dsig(l)*zu2(i,l) 86 zum=zum+dsig(l)*zu2(i,l) 87 87 zvm=zvm+dsig(l)*zv2(i,l) 88 88 END DO … … 101 101 zu2(i,l)=zu2(i,l)+zalpha*(zum-zu2(i,l)) 102 102 zv2(i,l)=zv2(i,l)+zalpha*(zvm-zv2(i,l)) 103 ENDDO 103 ENDDO 104 104 END IF 105 105 106 106 END DO 107 107 108 108 END SUBROUTINE adjust_onecolumn 109 109 … … 113 113 & pdufi,pdvfi,pdhfi, & 114 114 & pduadj,pdvadj,pdhadj) 115 115 116 116 !======================================================================= 117 117 ! … … 124 124 ! 125 125 !======================================================================= 126 126 127 127 INTEGER, INTENT(IN) :: ngrid,nlay 128 128 REAL, INTENT(IN) :: ptimestep … … 132 132 REAL, INTENT(OUT) :: pdhadj(ngrid,nlay), pduadj(ngrid,nlay), pdvadj(ngrid,nlay) 133 133 134 ! local: 134 ! local: 135 135 REAL sig(nlay+1),sdsig(nlay),dsig(nlay) 136 136 REAL zu(ngrid,nlay), zv(ngrid,nlay), zh(ngrid,nlay) 137 REAL zu2(ngrid,nlay), zv2(ngrid,nlay), zh2(ngrid,nlay) 137 REAL zu2(ngrid,nlay), zv2(ngrid,nlay), zh2(ngrid,nlay) 138 138 LOGICAL vtest(ngrid) 139 139 INTEGER jadrs(ngrid) 140 140 INTEGER jcnt, ig, l, jj 141 141 142 142 ! Add physics tendencies to u,v,h 143 143 DO l=1,nlay … … 151 151 zv2(:,:)=zv(:,:) 152 152 zh2(:,:)=zh(:,:) 153 153 154 154 !----------------------------------------------------------------------- 155 155 ! detection des profils a modifier: … … 160 160 ! sinon, il reste a sa valeur initiale (.FALSE.) 161 161 ! cette operation est vectorisable 162 162 163 163 vtest(:)=.FALSE. 164 164 DO l=2,nlay … … 186 186 END DO 187 187 END DO 188 188 189 189 END SUBROUTINE convadj 190 190 -
dynamico_lmdz/simple_physics/phyparam/physics/iniphyparam_mod.F90
r4228 r4229 9 9 10 10 CONTAINS 11 11 12 12 SUBROUTINE iniphyparam(ngrid,nlayer, & 13 13 & punjours, & … … 18 18 USE planet, ONLY : coefir, coefvis 19 19 USE astronomy 20 USE turbulence, ONLY : lmixmin, emin_turb 20 USE turbulence, ONLY : lmixmin, emin_turb 21 21 USE surface 22 22 USE read_param_mod … … 27 27 pdayref ! Day of reference for the simulation 28 28 REAL, INTENT(IN) :: ptimestep, prad, pg, pr, pcpp, punjours 29 29 30 30 CALL read_param('unjours', 86400., unjours,'unjours') 31 31 CALL read_param('planet_rad',prad,planet_rad,'planet_rad') … … 53 53 CALL read_param('coefvis',.99 ,coefvis,'coefvis') 54 54 CALL read_param('coefir',.08 ,coefir,'coefir') 55 55 56 56 CALL read_param('callrad',.true.,callrad,'appel rayonnemen') 57 57 CALL read_param('calldifv',.true.,calldifv,'appel difv') … … 63 63 CALL read_param('lverbose',.true.,lverbose,'appel soil') 64 64 CALL read_param('period_sort',1.,period_sort,'period sorties en jour') 65 65 66 66 CALL check_mismatch('unjours', punjours, unjours) 67 67 CALL check_mismatch('rad', prad, planet_rad) … … 69 69 CALL check_mismatch('R', pr, r) 70 70 CALL check_mismatch('cpp', pcpp, cpp) 71 71 72 72 WRITELOG(*,*) 'Activation de la physique:' 73 73 WRITELOG(*,*) ' R=',r -
dynamico_lmdz/simple_physics/phyparam/physics/logging.F90
r4227 r4229 16 16 END SUBROUTINE plugin 17 17 18 ! Plugin that writes into string 'line' information about the gridpoint of index 'index' 18 ! Plugin that writes into string 'line' information about the gridpoint of index 'index' 19 19 SUBROUTINE plugin_log_gridpoint(index, line) 20 20 INTEGER, INTENT(IN) :: index ! index of gridpoint … … 25 25 26 26 27 ! This module provides a default implementations of plugins but the top-level driver is welcome to override them. 27 ! This module provides a default implementations of plugins but the top-level driver is welcome to override them. 28 28 ! Note F2003/F2008: pgfortran (F2003) accepts to initialize pointers only to NULL() 29 29 ! => plugins are initialzed to NULL() and set to default values in flush_log and log_gridpoint … … 39 39 INTEGER :: logging_lineno=0 40 40 41 ! messages with a log level > max_log_level are not printed 41 ! messages with a log level > max_log_level are not printed 42 42 INTEGER, PARAMETER, PUBLIC :: log_level_fatal=1, log_level_error=2, log_level_warn=3, log_level_info=4, log_level_dbg=5 43 43 INTEGER, PUBLIC :: max_log_level = log_level_info … … 81 81 logging_lineno = logging_lineno+1 82 82 #ifndef XCODEML 83 IF(.NOT.ASSOCIATED(log_gridpoint_plugin)) log_gridpoint_plugin => default_log_gridpoint 83 IF(.NOT.ASSOCIATED(log_gridpoint_plugin)) log_gridpoint_plugin => default_log_gridpoint 84 84 CALL log_gridpoint_plugin(index, logging_buf(logging_lineno)) 85 85 #endif … … 87 87 88 88 SUBROUTINE default_log_gridpoint(index, line) 89 INTEGER, INTENT(IN) :: index ! index of gridpoint 89 INTEGER, INTENT(IN) :: index ! index of gridpoint 90 90 CHARACTER(*), INTENT(OUT) :: line 91 91 line='' -
dynamico_lmdz/simple_physics/phyparam/physics/mellor_yamada.F90
r4205 r4229 5 5 CONTAINS 6 6 7 PURE SUBROUTINE my_25(imax,kmax,dt,gp,zi,z,u,v,teta,cd,q2,long,km,kh) 8 9 !********************************************************************** 10 !****** FERMETURE MELLOR-YAMADA DE NIVEAU 2.5 (QUASI-EQUILIBRE) ******* 11 !* q2 au interfaces entre mailles. 12 !********************************************************************** 13 14 INTEGER, INTENT(IN) :: imax,kmax 7 PURE SUBROUTINE my_25(imax,kmax,dt,gp,zi,z,u,v,teta,cd,q2,long,km,kh) 8 9 !********************************************************************** 10 !****** FERMETURE MELLOR-YAMADA DE NIVEAU 2.5 (QUASI-EQUILIBRE) ******* 11 !* q2 au interfaces entre mailles. 12 !********************************************************************** 13 14 INTEGER, INTENT(IN) :: imax,kmax 15 15 REAL, INTENT(IN) :: dt, gp 16 16 REAL, INTENT(IN) :: z(imax,kmax), & 17 u(imax,kmax), v(imax,kmax), teta(imax,kmax), cd(imax) 17 u(imax,kmax), v(imax,kmax), teta(imax,kmax), cd(imax) 18 18 REAL, INTENT(INOUT) :: zi(imax,kmax+1), q2(imax,kmax+1) 19 19 REAL, INTENT(OUT) :: long(imax,kmax+1), km(imax,kmax+1), kh(imax,kmax+1) 20 20 21 !************* DECLARATIONS ******************************************* 22 23 INTEGER, PARAMETER :: impmax=5 21 !************* DECLARATIONS ******************************************* 22 23 INTEGER, PARAMETER :: impmax=5 24 24 REAL, PARAMETER :: kappa=0.4, & 25 25 a1=0.92, a2=0.74, b1=16.6, b2=10.1, c1=0.08, & 26 e1=1.8, e2=1.33, & 26 e1=1.8, e2=1.33, & 27 27 khmin=1.0e-5, kmmin=1.0e-5, kqmin=1.0e-5, & 28 q2min=0.001, q2lmin=0.001, & 29 ghmax=0.023, ghmin=-0.28 28 q2min=0.001, q2lmin=0.001, & 29 ghmax=0.023, ghmin=-0.28 30 30 31 31 REAL longc, au, ateta, az, adz, akq, acd, & … … 33 33 am, azi, bet, beta, dest, du, dv, gh, & 34 34 prod, q2c, sh, sm, sq, us, vt, vt1, vt2 35 36 REAL unsdz(imax,kmax),unsdzi(imax,kmax+1) 35 36 REAL unsdz(imax,kmax),unsdzi(imax,kmax+1) 37 37 REAL kq(imax,kmax), & 38 & m2(imax,kmax+1),n2(imax,kmax+1),ri(imax,kmax+1) 38 & m2(imax,kmax+1),n2(imax,kmax+1),ri(imax,kmax+1) 39 39 REAL a(imax,kmax),b(imax,kmax),c(imax,kmax),f(imax,kmax), & 40 & alph(imax,kmax) 41 REAL ksdz2inf,ksdz2sup 40 & alph(imax,kmax) 41 REAL ksdz2inf,ksdz2sup 42 42 43 43 INTEGER :: i,k 44 45 !************* INCREMENTS VERTICAUX *********************************** 46 47 DO i=1,imax 48 zi(i,kmax+1)=zi(i,kmax)+2.0*(z(i,kmax)-zi(i,kmax)) 49 END DO 50 DO k=1,kmax 51 DO i=1,imax 52 unsdz(i,k)=1.0/(zi(i,k+1)-zi(i,k)) 53 END DO 54 END DO 55 56 DO k=2,kmax 57 DO i=1,imax 58 unsdzi(i,k)=1.0/(z(i,k)-z(i,k-1)) 44 45 !************* INCREMENTS VERTICAUX *********************************** 46 47 DO i=1,imax 48 zi(i,kmax+1)=zi(i,kmax)+2.0*(z(i,kmax)-zi(i,kmax)) 49 END DO 50 DO k=1,kmax 51 DO i=1,imax 52 unsdz(i,k)=1.0/(zi(i,k+1)-zi(i,k)) 53 END DO 54 END DO 55 56 DO k=2,kmax 57 DO i=1,imax 58 unsdzi(i,k)=1.0/(z(i,k)-z(i,k-1)) 59 59 END do 60 60 END DO 61 61 62 DO i=1,imax 63 unsdzi(i,1)=0.5/(z(i,1)-zi(i,1)) 64 unsdzi(i,kmax+1)=0.5/(zi(i,kmax+1)-z(i,kmax)) 62 DO i=1,imax 63 unsdzi(i,1)=0.5/(z(i,1)-zi(i,1)) 64 unsdzi(i,kmax+1)=0.5/(zi(i,kmax+1)-z(i,kmax)) 65 65 END do 66 67 !********************************************************************** 68 69 70 !************* DIFFUSIVITES KH, KM et KQ ****************************** 71 ! Ci-dessous, une premiere estimation des diffusivites turbulentes km * 72 ! et kh est effectuee pour utilisation dans les taux de production * 73 ! et de destruction de q2 et q2l. On calcule aussi kq. * 74 75 DO k=2,kmax 76 DO i=1,imax 77 beta=2.0/(teta(i,k)+teta(i,k-1)) 78 n2(i,k)=beta*gp*unsdzi(i,k)*(teta(i,k)-teta(i,k-1)) 79 n2(i,k)=amax1(0.0,n2(i,k)) 80 du=unsdzi(i,k)*(u(i,k)-u(i,k-1)) 81 dv=unsdzi(i,k)*(v(i,k)-v(i,k-1)) 82 m2(i,k)=du*du+dv*dv 83 ri(i,k)=n2(i,k)/(m2(i,k)+1.0e-10) 84 ri(i,k)=amax1(-0.1,min(4.0,ri(i,k))) 85 END DO 86 END DO 87 88 DO k=2,kmax 89 DO i=1,imax 90 vt=kappa*(zi(i,k)-zi(i,1)) 91 long(i,k)=vt/(1.0+vt/160.0) 92 IF(n2(i,k).gt.0.0) THEN 93 long(i,k)=min(0.53*sqrt(q2(i,k))/sqrt(n2(i,k)),long(i,k)) 66 67 !********************************************************************** 68 69 70 !************* DIFFUSIVITES KH, KM et KQ ****************************** 71 ! Ci-dessous, une premiere estimation des diffusivites turbulentes km * 72 ! et kh est effectuee pour utilisation dans les taux de production * 73 ! et de destruction de q2 et q2l. On calcule aussi kq. * 74 75 DO k=2,kmax 76 DO i=1,imax 77 beta=2.0/(teta(i,k)+teta(i,k-1)) 78 n2(i,k)=beta*gp*unsdzi(i,k)*(teta(i,k)-teta(i,k-1)) 79 n2(i,k)=amax1(0.0,n2(i,k)) 80 du=unsdzi(i,k)*(u(i,k)-u(i,k-1)) 81 dv=unsdzi(i,k)*(v(i,k)-v(i,k-1)) 82 m2(i,k)=du*du+dv*dv 83 ri(i,k)=n2(i,k)/(m2(i,k)+1.0e-10) 84 ri(i,k)=amax1(-0.1,min(4.0,ri(i,k))) 85 END DO 86 END DO 87 88 DO k=2,kmax 89 DO i=1,imax 90 vt=kappa*(zi(i,k)-zi(i,1)) 91 long(i,k)=vt/(1.0+vt/160.0) 92 IF(n2(i,k).gt.0.0) THEN 93 long(i,k)=min(0.53*sqrt(q2(i,k))/sqrt(n2(i,k)),long(i,k)) 94 94 END IF 95 95 gh=amax1(ghmin, & 96 & min(ghmax,-long(i,k)*long(i,k)*n2(i,k)/q2(i,k))) 96 & min(ghmax,-long(i,k)*long(i,k)*n2(i,k)/q2(i,k))) 97 97 sm=a1*(1.0-3.0*c1-6.0*a1/b1-3.0*a2*gh* & 98 98 & ((b2-3.0*a2)*(1.0-6.0*a1/b1)-3.0*c1*(b2+6.0*a1)))/ & 99 & ((1.0-3.0*a2*gh*(6.0*a1+b2))*(1.0-9.0*a1*a2*gh)) 100 km(i,k)=amax1(kmmin,long(i,k)*sqrt(q2(i,k))*sm) 101 sh=a2*(1.0-6.0*a1/b1)/(1.0-3.0*a2*gh*(6.0*a1+b2)) 102 kh(i,k)=amax1(khmin,long(i,k)*sqrt(q2(i,k))*sh) 103 END DO 104 END DO 105 106 DO i=1,imax 107 us=sqrt(cd(i)*(u(i,1)*u(i,1)+v(i,1)*v(i,1))) 108 vt1=(b1**0.666667)*us*us 99 & ((1.0-3.0*a2*gh*(6.0*a1+b2))*(1.0-9.0*a1*a2*gh)) 100 km(i,k)=amax1(kmmin,long(i,k)*sqrt(q2(i,k))*sm) 101 sh=a2*(1.0-6.0*a1/b1)/(1.0-3.0*a2*gh*(6.0*a1+b2)) 102 kh(i,k)=amax1(khmin,long(i,k)*sqrt(q2(i,k))*sh) 103 END DO 104 END DO 105 106 DO i=1,imax 107 us=sqrt(cd(i)*(u(i,1)*u(i,1)+v(i,1)*v(i,1))) 108 vt1=(b1**0.666667)*us*us 109 109 vt2=(b1**0.6666667)*kappa*kappa* & 110 & m2(i,2)*(zi(i,2)-zi(i,1))*(zi(i,2)-zi(i,1)) 111 ! q2(i,1)=amax1(q2min,vt1,vt2) 112 q2(i,1)=amax1(q2min,vt1) 113 long(i,1)=0.0 114 long(i,kmax+1)=long(i,kmax) 115 sq=0.2 116 kq(i,1)=amax1(kqmin,kappa*(z(i,1)-zi(i,1))*us*sq) 117 END DO 118 119 DO k=2,kmax 120 DO i=1,imax 121 longc=0.5*(long(i,k)+long(i,k+1)) 122 q2c=0.5*(q2(i,k)+q2(i,k+1)) 123 sq=0.2 124 kq(i,k)=amax1(kqmin,longc*sqrt(q2c)*sq) 125 END DO 126 END DO 127 128 !********************************************************************** 129 130 131 !************* CALCUL DE Q2 ******************************************* 132 133 DO k=2,kmax 134 DO i=1,imax 135 prod=2.0*(km(i,k)*m2(i,k)+amax1(0.0,-kh(i,k)*n2(i,k))) 110 & m2(i,2)*(zi(i,2)-zi(i,1))*(zi(i,2)-zi(i,1)) 111 ! q2(i,1)=amax1(q2min,vt1,vt2) 112 q2(i,1)=amax1(q2min,vt1) 113 long(i,1)=0.0 114 long(i,kmax+1)=long(i,kmax) 115 sq=0.2 116 kq(i,1)=amax1(kqmin,kappa*(z(i,1)-zi(i,1))*us*sq) 117 END DO 118 119 DO k=2,kmax 120 DO i=1,imax 121 longc=0.5*(long(i,k)+long(i,k+1)) 122 q2c=0.5*(q2(i,k)+q2(i,k+1)) 123 sq=0.2 124 kq(i,k)=amax1(kqmin,longc*sqrt(q2c)*sq) 125 END DO 126 END DO 127 128 !********************************************************************** 129 130 131 !************* CALCUL DE Q2 ******************************************* 132 133 DO k=2,kmax 134 DO i=1,imax 135 prod=2.0*(km(i,k)*m2(i,k)+amax1(0.0,-kh(i,k)*n2(i,k))) 136 136 dest=2.0*(amax1(0.0,kh(i,k)*n2(i,k)) & 137 & +q2(i,k)*sqrt(q2(i,k))/(b1*long(i,k))) 138 IF(k.lt.kmax) THEN 139 ksdz2sup=unsdzi(i,k)*unsdz(i,k)*kq(i,k) 140 ELSE 141 ksdz2sup=0.0 137 & +q2(i,k)*sqrt(q2(i,k))/(b1*long(i,k))) 138 IF(k.lt.kmax) THEN 139 ksdz2sup=unsdzi(i,k)*unsdz(i,k)*kq(i,k) 140 ELSE 141 ksdz2sup=0.0 142 142 END IF 143 ksdz2inf=unsdzi(i,k)*unsdz(i,k-1)*kq(i,k-1) 144 b(i,k)=-ksdz2inf*dt 145 a(i,k)=1.0+dt*(dest/q2(i,k)+ksdz2inf+ksdz2sup) 146 c(i,k)=-ksdz2sup*dt 147 f(i,k)=q2(i,k)+dt*prod 148 END DO 149 END DO 150 DO i=1,imax 143 ksdz2inf=unsdzi(i,k)*unsdz(i,k-1)*kq(i,k-1) 144 b(i,k)=-ksdz2inf*dt 145 a(i,k)=1.0+dt*(dest/q2(i,k)+ksdz2inf+ksdz2sup) 146 c(i,k)=-ksdz2sup*dt 147 f(i,k)=q2(i,k)+dt*prod 148 END DO 149 END DO 150 DO i=1,imax 151 151 f(i,2)=f(i,2) & 152 & +dt*unsdzi(i,2)*unsdz(i,1)*kq(i,1)*q2(i,1) 153 END DO 154 155 DO i=1,imax 156 alph(i,2)=a(i,2) 157 END DO 158 159 DO k=3,kmax 160 DO i=1,imax 161 bet=b(i,k)/alph(i,k-1) 162 alph(i,k)=a(i,k)-bet*c(i,k-1) 163 f(i,k)=f(i,k)-bet*f(i,k-1) 164 END DO 165 END DO 166 167 DO i=1,imax 168 q2(i,kmax)=amax1(q2min,f(i,kmax)/alph(i,kmax)) 169 q2(i,kmax+1)=q2(i,kmax) 170 END DO 171 172 DO k=kmax-1,2,-1 173 DO i=1,imax 174 q2(i,k)=amax1(q2min,(f(i,k)-c(i,k)*q2(i,k+1))/alph(i,k)) 175 END DO 176 END DO 177 178 DO i=1,imax 179 q2(i,2)=amax1(q2(i,2),q2(i,1)) 180 END DO 181 182 !********************************************************************** 183 184 185 !************* EVALUATION FINALE DE KH ET KM ************************** 186 187 DO k=2,kmax 188 DO i=1,imax 189 IF(n2(i,k).gt.0.0) THEN 190 long(i,k)=min(0.53*sqrt(q2(i,k))/sqrt(n2(i,k)),long(i,k)) 152 & +dt*unsdzi(i,2)*unsdz(i,1)*kq(i,1)*q2(i,1) 153 END DO 154 155 DO i=1,imax 156 alph(i,2)=a(i,2) 157 END DO 158 159 DO k=3,kmax 160 DO i=1,imax 161 bet=b(i,k)/alph(i,k-1) 162 alph(i,k)=a(i,k)-bet*c(i,k-1) 163 f(i,k)=f(i,k)-bet*f(i,k-1) 164 END DO 165 END DO 166 167 DO i=1,imax 168 q2(i,kmax)=amax1(q2min,f(i,kmax)/alph(i,kmax)) 169 q2(i,kmax+1)=q2(i,kmax) 170 END DO 171 172 DO k=kmax-1,2,-1 173 DO i=1,imax 174 q2(i,k)=amax1(q2min,(f(i,k)-c(i,k)*q2(i,k+1))/alph(i,k)) 175 END DO 176 END DO 177 178 DO i=1,imax 179 q2(i,2)=amax1(q2(i,2),q2(i,1)) 180 END DO 181 182 !********************************************************************** 183 184 185 !************* EVALUATION FINALE DE KH ET KM ************************** 186 187 DO k=2,kmax 188 DO i=1,imax 189 IF(n2(i,k).gt.0.0) THEN 190 long(i,k)=min(0.53*sqrt(q2(i,k))/sqrt(n2(i,k)),long(i,k)) 191 191 END IF 192 192 gh=amax1(ghmin, & 193 & min(ghmax,-long(i,k)*long(i,k)*n2(i,k)/q2(i,k))) 193 & min(ghmax,-long(i,k)*long(i,k)*n2(i,k)/q2(i,k))) 194 194 sm=a1*(1.0-3.0*c1-6.0*a1/b1-3.0*a2*gh* & 195 195 & ((b2-3.0*a2)*(1.0-6.0*a1/b1)-3.0*c1*(b2+6.0*a1)))/ & 196 & ((1.0-3.0*a2*gh*(6.0*a1+b2))*(1.0-9.0*a1*a2*gh)) 197 km(i,k)=amax1(kmmin,long(i,k)*sqrt(q2(i,k))*sm) 198 sh=a2*(1.0-6.0*a1/b1)/(1.0-3.0*a2*gh*(6.0*a1+b2)) 199 kh(i,k)=amax1(khmin,long(i,k)*sqrt(q2(i,k))*sh) 200 END DO 201 END DO 202 203 DO i=1,imax 204 km(i,1)=kmmin 205 km(i,kmax+1)=km(i,kmax) 206 kh(i,1)=khmin 207 kh(i,kmax+1)=kh(i,kmax) 208 END DO 209 210 !********************************************************************** 211 212 am=1.0/float(imax) 213 DO k=kmax,1,-1 214 au=0.0 215 ateta=0.0 216 az=0.0 217 adz=0.0 218 akq=0.0 219 acd=0.0 220 DO i=1,imax 221 au=au+am*sqrt(u(i,k)*u(i,k)+v(i,k)*v(i,k)) 222 ateta=ateta+am*teta(i,k) 223 az=az+am*z(i,k) 224 adz=adz+am*(1.0/unsdz(i,k)) 225 akq=akq+am*kq(i,k) 226 acd=acd+am*cd(i) 227 END DO 228 END DO 229 230 DO k=kmax+1,1,-1 231 azi=0.0 232 adzi=0.0 233 aq2=0.0 234 al=0.0 235 akm=0.0 236 akh=0.0 237 am2=0.0 238 al0=0.0 239 DO i=1,imax 240 azi=azi+am*zi(i,k) 241 adzi=adzi+am*(1.0/unsdzi(i,k)) 242 aq2=aq2+am*q2(i,k) 243 al=al+am*long(i,k) 244 akm=akm+am*km(i,k) 245 akh=akh+am*kh(i,k) 246 am2=am2+am*m2(i,k) 247 ! al0=al0+am*long0d(i) 248 END DO 249 END DO 250 196 & ((1.0-3.0*a2*gh*(6.0*a1+b2))*(1.0-9.0*a1*a2*gh)) 197 km(i,k)=amax1(kmmin,long(i,k)*sqrt(q2(i,k))*sm) 198 sh=a2*(1.0-6.0*a1/b1)/(1.0-3.0*a2*gh*(6.0*a1+b2)) 199 kh(i,k)=amax1(khmin,long(i,k)*sqrt(q2(i,k))*sh) 200 END DO 201 END DO 202 203 DO i=1,imax 204 km(i,1)=kmmin 205 km(i,kmax+1)=km(i,kmax) 206 kh(i,1)=khmin 207 kh(i,kmax+1)=kh(i,kmax) 208 END DO 209 210 !********************************************************************** 211 212 am=1.0/float(imax) 213 DO k=kmax,1,-1 214 au=0.0 215 ateta=0.0 216 az=0.0 217 adz=0.0 218 akq=0.0 219 acd=0.0 220 DO i=1,imax 221 au=au+am*sqrt(u(i,k)*u(i,k)+v(i,k)*v(i,k)) 222 ateta=ateta+am*teta(i,k) 223 az=az+am*z(i,k) 224 adz=adz+am*(1.0/unsdz(i,k)) 225 akq=akq+am*kq(i,k) 226 acd=acd+am*cd(i) 227 END DO 228 END DO 229 230 DO k=kmax+1,1,-1 231 azi=0.0 232 adzi=0.0 233 aq2=0.0 234 al=0.0 235 akm=0.0 236 akh=0.0 237 am2=0.0 238 al0=0.0 239 DO i=1,imax 240 azi=azi+am*zi(i,k) 241 adzi=adzi+am*(1.0/unsdzi(i,k)) 242 aq2=aq2+am*q2(i,k) 243 al=al+am*long(i,k) 244 akm=akm+am*km(i,k) 245 akh=akh+am*kh(i,k) 246 am2=am2+am*m2(i,k) 247 ! al0=al0+am*long0d(i) 248 END DO 249 END DO 250 251 251 END SUBROUTINE my_25 252 252 253 253 END MODULE mellor_yamada -
dynamico_lmdz/simple_physics/phyparam/physics/phyparam_mod.F90
r4228 r4229 12 12 ps_rad=1.e5, height_scale=10000., ref_temp=285., & 13 13 capcal_nosoil=1e5, tsoil_init=300. 14 14 15 15 ! internal state, written to / read from disk at checkpoint / restart 16 16 REAL, ALLOCATABLE :: tsurf(:), tsoil(:,:), capcal(:), fluxgrd(:) … … 19 19 ! precomputed arrays 20 20 REAL, ALLOCATABLE :: rnatur(:), albedo(:),emissiv(:), z0(:), inertie(:) 21 !$OMP THREADPRIVATE( rnatur, albedo, emissiv, z0, inertie) 21 !$OMP THREADPRIVATE( rnatur, albedo, emissiv, z0, inertie) 22 22 23 23 INTEGER :: icount … … 42 42 43 43 !======================================================================= 44 ! Top routine of the physical parametrisations of the LMD 44 ! Top routine of the physical parametrisations of the LMD 45 45 ! 20 parameters GCM for planetary atmospheres. 46 46 ! It includes: … … 56 56 nlayer ! Number of vertical layers. 57 57 LOGICAL, INTENT(IN) :: & 58 firstcall, & ! True at the first call 58 firstcall, & ! True at the first call 59 59 lastcall ! True at the last call 60 60 REAL, INTENT(IN) :: & … … 73 73 pdt(ngrid,nlayer), & 74 74 pdpsrf(ngrid) 75 75 76 76 ! Local variables : 77 77 REAL, DIMENSION(ngrid) :: mu0 … … 90 90 REAL zdtlw(ngrid,nlayer),zdtsw(ngrid,nlayer) 91 91 REAL zfluxsw(ngrid),zfluxlw(ngrid), fluxrad(ngrid) 92 92 93 93 WRITELOG(*,*) 'latitude0', ngrid, lati(1:2), lati(ngrid-1:ngrid) 94 94 WRITELOG(*,*) 'nlayer',nlayer … … 104 104 105 105 nlevel=nlayer+1 106 igout=ngrid/2+1 106 igout=ngrid/2+1 107 107 zday=rjourvrai+gmtime 108 108 … … 110 110 ! 0. Allocate and initialize at first call 111 111 ! -------------------- 112 112 113 113 IF(firstcall) THEN 114 114 ! zday_last=rjourvrai … … 122 122 ! 1. Initialisations : 123 123 ! -------------------- 124 124 125 125 icount=icount+1 126 126 127 127 pdv(:,:) = 0. 128 128 pdu(:,:) = 0. … … 131 131 zflubid(:)= 0. 132 132 zdtsrf(:) = 0. 133 133 134 134 !----------------------------------------------------------------------- 135 135 ! calcul du geopotentiel aux niveaux intercouches 136 136 ! ponderation des altitudes au niveau des couches en dp/p 137 137 138 138 DO l=1,nlayer 139 139 DO ig=1,ngrid … … 151 151 ENDDO 152 152 ENDDO 153 153 154 154 !----------------------------------------------------------------------- 155 155 ! Transformation de la temperature en temperature potentielle … … 160 160 ENDDO 161 161 ENDDO 162 162 163 163 !----------------------------------------------------------------------- 164 164 ! 2. Compute radiative tendencies : 165 165 ! --------------------------------------- 166 166 167 167 IF(callrad) CALL radiative_tendencies(ngrid, igout, nlayer, & 168 169 168 gmtime, ptimestep*float(iradia), zday, pplev, pplay, pt, & 169 pdt, zdtlw, zfluxlw, zdtsw, zfluxsw, fluxrad, mu0) 170 170 171 171 !----------------------------------------------------------------------- … … 178 178 zflubid(ig)=fluxrad(ig)+fluxgrd(ig) 179 179 ENDDO 180 180 181 181 zdum1(:,:)=0. 182 182 zdum2(:,:)=0. 183 183 184 184 do l=1,nlayer 185 185 do ig=1,ngrid … … 187 187 enddo 188 188 enddo 189 189 190 190 CALL vdif(ngrid,nlayer,zday, & 191 & ptimestep,capcal,z0, &192 & pplay,pplev,zzlay,zzlev, &193 & pu,pv,zh,tsurf,emissiv, &194 & zdum1,zdum2,zdum3,zflubid, &195 & zdufr,zdvfr,zdhfr,zdtsrfr, &196 & lverbose)191 & ptimestep,capcal,z0, & 192 & pplay,pplev,zzlay,zzlev, & 193 & pu,pv,zh,tsurf,emissiv, & 194 & zdum1,zdum2,zdum3,zflubid, & 195 & zdufr,zdvfr,zdhfr,zdtsrfr, & 196 & lverbose) 197 197 198 198 DO l=1,nlayer … … 203 203 ENDDO 204 204 ENDDO 205 205 206 206 DO ig=1,ngrid 207 207 zdtsrf(ig)=zdtsrf(ig)+zdtsrfr(ig) 208 208 ENDDO 209 209 210 210 ELSE 211 211 DO ig=1,ngrid 212 212 zdtsrf(ig)=zdtsrf(ig)+ & 213 & (fluxrad(ig)+fluxgrd(ig))/capcal(ig)213 & (fluxrad(ig)+fluxgrd(ig))/capcal(ig) 214 214 ENDDO 215 215 ENDIF … … 218 218 ! 4. Dry convective adjustment: 219 219 ! ----------------------------- 220 220 221 221 IF(calladj) THEN 222 222 223 223 DO l=1,nlayer 224 224 DO ig=1,ngrid … … 226 226 ENDDO 227 227 ENDDO 228 228 229 229 zdufr(:,:)=0. 230 230 zdvfr(:,:)=0. 231 231 zdhfr(:,:)=0. 232 232 233 233 CALL convadj(ngrid,nlayer,ptimestep, & 234 & pplay,pplev,zpopsk, &235 & pu,pv,zh, &236 & pdu,pdv,zdum1, &237 & zdufr,zdvfr,zdhfr)238 234 & pplay,pplev,zpopsk, & 235 & pu,pv,zh, & 236 & pdu,pdv,zdum1, & 237 & zdufr,zdvfr,zdhfr) 238 239 239 DO l=1,nlayer 240 240 DO ig=1,ngrid … … 244 244 ENDDO 245 245 ENDDO 246 246 247 247 ENDIF 248 248 … … 250 250 ! On ajoute les tendances physiques a la temperature du sol: 251 251 ! --------------------------------------------------------------- 252 252 253 253 DO ig=1,ngrid 254 tsurf(ig)=tsurf(ig)+ptimestep*zdtsrf(ig) 255 ENDDO 256 254 tsurf(ig)=tsurf(ig)+ptimestep*zdtsrf(ig) 255 ENDDO 256 257 257 WRITE(55,'(2e15.5)') zday,tsurf(ngrid/2+1) 258 258 259 259 !----------------------------------------------------------------------- 260 260 ! soil temperatures: 261 261 ! -------------------- 262 262 263 263 IF (callsoil) THEN 264 264 CALL soil(ngrid,nsoilmx,.false.,inertie, & 265 & ptimestep,tsurf,tsoil,capcal,fluxgrd)265 & ptimestep,tsurf,tsoil,capcal,fluxgrd) 266 266 IF(lverbose) THEN 267 267 WRITELOG(*,*) 'Surface Heat capacity,conduction Flux, Ts, dTs, dt' … … 271 271 ENDIF 272 272 ENDIF 273 273 274 274 !----------------------------------------------------------------------- 275 275 ! sorties: … … 285 285 zday_last=zday 286 286 ! Ecriture/extension de la coordonnee temps 287 287 288 288 do ig=1,ngridmax 289 289 zpmer(ig)=pplev(ig,1)*exp(pphi(ig,1)/(r*ref_temp)) 290 290 enddo 291 291 292 292 call writefield('u','Vent zonal moy','m/s',pu) 293 293 call writefield('v','Vent meridien moy','m/s',pv) … … 295 295 call writefield('geop','Geopotential','m2/s2',pphi) 296 296 call writefield('plev','plev','Pa',pplev(:,1:nlayer)) 297 297 298 298 call writefield('du','du',' ',pdu) 299 299 call writefield('dv','du',' ',pdv) … … 301 301 call writefield('dtsw','dtsw',' ',zdtsw) 302 302 call writefield('dtlw','dtlw',' ',zdtlw) 303 303 304 304 call writefield('ts','Surface temper','K',tsurf) 305 305 call writefield('coslon','coslon',' ',coslon) … … 313 313 call writefield('swsurf','SW surf','Pa',zfluxsw) 314 314 call writefield('lwsurf','LW surf','Pa',zfluxlw) 315 315 316 316 endif 317 317 318 318 END SUBROUTINE phyparam 319 319 … … 338 338 & zfluxsw(ngrid), & ! short-wave flux at surface 339 339 & fluxrad(ngrid), & ! surface flux 340 340 mu0(ngrid) ! ?? 341 341 ! local variables 342 342 REAL :: fract(ngrid), dtrad(ngrid, nlayer) … … 347 347 ! 2.1 Insolation 348 348 ! -------------------------------------------------- 349 349 350 350 CALL solarlong(zday,zls) 351 351 CALL orbite(zls,dist_sol,declin) 352 352 353 353 IF(diurnal) THEN 354 354 IF ( .TRUE. ) then … … 362 362 CALL zenang(ngrid,zls,gmtime,zdtime,lati,long,mu0,fract) 363 363 ENDIF 364 364 365 365 IF(lverbose) THEN 366 366 WRITELOG(*,*) 'day, declin, sinlon,coslon,sinlat,coslat' … … 375 375 CALL mucorr(ngrid,declin,lati,mu0,fract,height_scale,planet_rad) 376 376 ENDIF 377 377 378 378 zinsol=solarcst/(dist_sol*dist_sol) 379 379 380 380 ! 2.2 Radiative tendencies and fluxes: 381 381 ! -------------------------------------------------- 382 382 383 383 CALL sw(ngrid,nlayer,diurnal,coefvis,albedo, & 384 384 & pplev,ps_rad, & … … 386 386 & zfluxsw,zdtsw, & 387 387 & lverbose) 388 388 389 389 CALL lw(ngrid,nlayer,coefir,emissiv, & 390 390 & pplev,ps_rad,tsurf,pt, & 391 391 & zfluxlw,zdtlw, & 392 392 & lverbose) 393 393 394 394 ! 2.4 surface fluxes 395 395 ! ------------------------------ 396 396 397 397 DO ig=1,ngrid 398 398 fluxrad(ig)=emissiv(ig)*zfluxlw(ig) & … … 402 402 fluxrad(ig)=fluxrad(ig)-zplanck(ig) 403 403 ENDDO 404 404 405 405 ! 2.5 Temperature tendencies 406 406 ! -------------------------- 407 407 408 408 DO l=1,nlayer 409 409 DO ig=1,ngrid … … 412 412 ENDDO 413 413 ENDDO 414 414 415 415 IF(lverbose) THEN 416 416 WRITELOG(*,*) 'Diagnostics for radiation' … … 428 428 LOG_DBG('radiative_tendencies') 429 429 ENDIF 430 430 431 431 END SUBROUTINE radiative_tendencies 432 432 -
dynamico_lmdz/simple_physics/phyparam/physics/phys_const.F90
r4215 r4229 1 1 MODULE phys_const 2 2 3 3 REAL planet_rad,g,r,cpp,rcp,dtphys,unjours,mugaz,omeg 4 4 -
dynamico_lmdz/simple_physics/phyparam/physics/planet.F90
r4190 r4229 4 4 5 5 REAL :: coefvis, coefir 6 6 7 7 END MODULE planet -
dynamico_lmdz/simple_physics/phyparam/physics/radiative_lw.F90
r4223 r4229 5 5 IMPLICIT NONE 6 6 SAVE 7 7 8 8 PRIVATE 9 9 10 10 PUBLIC :: lw 11 11 12 12 LOGICAL, PARAMETER :: lstrong=.TRUE. 13 13 REAL, PARAMETER :: stephan=5.67e-08 14 14 15 15 CONTAINS 16 16 17 17 SUBROUTINE lw(ngrid,nlayer,coefir,emissiv, & 18 18 pp,ps_rad,ptsurf,pt, & … … 45 45 ! 46 46 !======================================================================= 47 47 48 48 ! declarations: 49 49 ! ------------- 50 50 51 51 ! arguments: 52 52 ! ---------- 53 53 54 54 INTEGER, INTENT(IN) :: ngrid,nlayer 55 55 REAL, INTENT(IN) :: coefir,emissiv(ngrid),ps_rad … … 57 57 REAL, INTENT(OUT) :: pdtlw(ngrid,nlayer),pfluxir(ngrid) 58 58 LOGICAL, INTENT(IN) :: lwrite 59 59 60 60 ! variables locales: 61 61 ! ------------------ 62 62 63 63 INTEGER nlevel,ilev,ig,i,il 64 64 REAL zplanck(ngrid,nlayer+1),zcoef … … 72 72 ! initialisations: 73 73 ! ---------------- 74 74 75 75 nlevel=nlayer+1 76 76 77 77 !----------------------------------------------------------------------- 78 78 ! 2. calcul des quantites d'absorbants: 79 79 ! ------------------------------------- 80 80 81 81 ! absorption forte 82 82 IF(lstrong) THEN … … 93 93 ENDIF 94 94 zcoef=-log(coefir)/sqrt(ps_rad*ps_rad/(2.*g)) 95 95 96 96 ! absorption faible 97 97 ELSE … … 103 103 zcoef=-log(coefir)/ps_rad 104 104 ENDIF 105 106 105 106 107 107 !----------------------------------------------------------------------- 108 108 ! 2. calcul de la fonction de corps noir: 109 109 ! --------------------------------------- 110 110 111 111 DO ilev=1,nlayer 112 112 DO ig=1,ngrid … … 116 116 ENDDO 117 117 ENDDO 118 118 119 119 !----------------------------------------------------------------------- 120 120 ! 4. flux descendants: 121 121 ! -------------------- 122 122 123 123 DO ilev=1,nlayer 124 124 DO ig=1,ngrid … … 129 129 ENDDO 130 130 CALL lwtr(ngrid,zcoef,lstrong,zdup,zlwtr1) 131 131 132 132 DO il=nlayer,ilev,-1 133 133 zlwtr2(:)=zlwtr1(:) … … 142 142 ENDDO 143 143 ENDDO 144 144 145 145 DO ig=1,ngrid 146 146 zfluxdn(ig,nlevel)=0. 147 147 pfluxir(ig)=emissiv(ig)*zfluxdn(ig,1) 148 148 ENDDO 149 149 150 150 DO ig=1,ngrid 151 151 zfluxup(ig,1)=ptsurf(ig)*ptsurf(ig) … … 153 153 +(1.-emissiv(ig))*zfluxdn(ig,1) 154 154 ENDDO 155 155 156 156 !----------------------------------------------------------------------- 157 157 ! 3. flux montants: 158 158 ! ------------------ 159 159 160 160 DO ilev=1,nlayer 161 161 DO ig=1,ngrid … … 177 177 ENDDO 178 178 ENDDO 179 179 180 180 ENDDO 181 181 … … 183 183 ! 5. calcul des flux nets: 184 184 ! ------------------------ 185 185 186 186 DO ilev=1,nlevel 187 187 DO ig=1,ngrid … … 189 189 ENDDO 190 190 ENDDO 191 191 192 192 !----------------------------------------------------------------------- 193 193 ! 6. Calcul des taux de refroidissement: 194 194 ! -------------------------------------- 195 195 196 196 DO ilev=1,nlayer 197 197 DO ig=1,ngrid … … 200 200 ENDDO 201 201 ENDDO 202 202 203 203 !----------------------------------------------------------------------- 204 204 ! 10. sorties eventuelles: 205 205 ! ------------------------ 206 207 IF (lwrite) THEN 206 207 IF (lwrite) THEN 208 208 WRITELOG(*,*) 'Diagnostique rayonnement thermique' 209 209 WRITELOG(*,*) 'temperature ', & 210 'flux montant flux desc. taux de refroid.'210 'flux montant flux desc. taux de refroid.' 211 211 i=ngrid/2+1 212 212 WRITELOG(6,'(4e18.4)') ptsurf(i) … … 215 215 zfluxup(i,ilev),zfluxdn(i,ilev),pdtlw(i,ilev) 216 216 ENDDO 217 WRITELOG(6,'(4e18.4)') zfluxup(i,nlevel),zfluxdn(i,nlevel) 217 WRITELOG(6,'(4e18.4)') zfluxup(i,nlevel),zfluxdn(i,nlevel) 218 218 LOG_DBG(tag) 219 219 ENDIF 220 220 221 !-----------------------------------------------------------------------222 221 !----------------------------------------------------------------------- 222 223 223 END SUBROUTINE lw 224 224 … … 239 239 ENDDO 240 240 ENDIF 241 241 242 242 END SUBROUTINE lwtr 243 243 244 244 END MODULE radiative_lw -
dynamico_lmdz/simple_physics/phyparam/physics/radiative_sw.F90
r4228 r4229 5 5 IMPLICIT NONE 6 6 SAVE 7 7 8 8 PRIVATE 9 9 … … 11 11 12 12 CONTAINS 13 14 PURE SUBROUTINE monGATHER(n,a,b,index) 13 14 PURE SUBROUTINE monGATHER(n,a,b,index) 15 15 INTEGER, INTENT(IN) :: n,index(n) 16 16 REAL, INTENT(IN) :: b(n) … … 32 32 END DO 33 33 end subroutine monscatter 34 34 35 35 SUBROUTINE sw(ngrid,nlayer,ldiurn, & 36 36 coefvis,albedo, & … … 41 41 !======================================================================= 42 42 ! 43 ! Rayonnement solaire en atmosphere non diffusante avec un 43 ! Rayonnement solaire en atmosphere non diffusante avec un 44 44 ! coefficient d'absoprption gris. 45 45 ! … … 60 60 REAL, INTENT(IN) :: psolarf0 61 61 REAL, INTENT(OUT) :: fsrfvis(ngrid),dtsw(ngrid,nlayer) 62 62 63 63 REAL zalb(ngrid),zmu(ngrid),zfract(ngrid) 64 64 REAL zplev(ngrid,nlayer+1) 65 65 REAL zflux(ngrid),zdtsw(ngrid,nlayer) 66 66 67 67 INTEGER ig,l,nlevel,index(ngrid),ncount,igout 68 68 REAL ztrdir(ngrid,nlayer+1),ztrref(ngrid,nlayer+1) … … 71 71 REAL zu(ngrid,nlayer+1) 72 72 REAL tau0 73 73 74 74 !----------------------------------------------------------------------- 75 75 ! 1. initialisations: 76 76 ! ------------------- 77 77 78 78 nlevel=nlayer+1 79 79 … … 81 81 ! Definitions des tableaux locaux pour les points ensoleilles: 82 82 ! ------------------------------------------------------------ 83 83 84 84 IF (ldiurn) THEN 85 85 ncount=0 … … 106 106 zplev(:,:)=plevel(:,:) 107 107 ENDIF 108 108 109 109 !----------------------------------------------------------------------- 110 110 ! calcul des profondeurs optiques integres depuis p=0: 111 111 ! ---------------------------------------------------- 112 112 113 113 tau0=-.5*log(coefvis) 114 114 115 115 ! calcul de la partie homogene de l'opacite 116 116 tau0=tau0/ps_rad … … 120 120 ENDDO 121 121 ENDDO 122 122 123 123 !----------------------------------------------------------------------- 124 124 ! 2. calcul de la transmission depuis le sommet de l'atmosphere: 125 125 ! ----------------------------------------------------------- 126 126 127 127 DO l=1,nlevel 128 128 DO ig=1,ncount … … 130 130 ENDDO 131 131 ENDDO 132 132 133 133 IF (lwrite) THEN 134 134 igout=ncount/2+1 135 WRITELOG(*,*) 135 WRITELOG(*,*) 136 136 WRITELOG(*,*) 'Diagnostique des transmission dans le spectre solaire' 137 137 WRITELOG(*,*) 'zfract, zmu, zalb' … … 142 142 ENDDO 143 143 ENDIF 144 144 145 145 !----------------------------------------------------------------------- 146 146 ! 3. taux de chauffage, ray. solaire direct: 147 147 ! ------------------------------------------ 148 148 149 149 DO l=1,nlayer 150 150 DO ig=1,ncount … … 155 155 ENDDO 156 156 IF (lwrite) THEN 157 WRITELOG(*,*) 157 WRITELOG(*,*) 158 158 WRITELOG(*,*) 'Diagnostique des taux de chauffage solaires:' 159 159 WRITELOG(*,*) ' 1 taux de chauffage lie au ray. solaire direct' … … 162 162 ENDDO 163 163 ENDIF 164 165 164 165 166 166 !----------------------------------------------------------------------- 167 167 ! 4. calcul du flux solaire arrivant sur le sol: 168 168 ! ---------------------------------------------- 169 169 170 170 DO ig=1,ncount 171 171 z1(ig)=zfract(ig)*zmu(ig)*psolarf0*ztrdir(ig,1) … … 174 174 ENDDO 175 175 IF (lwrite) THEN 176 WRITELOG(*,*) 176 WRITELOG(*,*) 177 177 WRITELOG(*,*) 'Diagnostique des taux de chauffage solaires:' 178 178 WRITELOG(*,*) ' 2 flux solaire net incident sur le sol' 179 179 WRITELOG(*,*) zflux(igout) 180 180 ENDIF 181 182 181 182 183 183 !----------------------------------------------------------------------- 184 184 ! 5.calcul des traansmissions depuis le sol, cas diffus: 185 185 ! ------------------------------------------------------ 186 186 187 187 DO l=1,nlevel 188 188 DO ig=1,ncount … … 190 190 ENDDO 191 191 ENDDO 192 193 IF (lwrite) THEN 194 WRITELOG(*,*) 192 193 IF (lwrite) THEN 194 WRITELOG(*,*) 195 195 WRITELOG(*,*) 'Diagnostique des taux de chauffage solaires' 196 196 WRITELOG(*,*) ' 3 transmission avec les sol' … … 200 200 ENDDO 201 201 ENDIF 202 203 !----------------------------------------------------------------------- 204 ! 6.ajout a l'echauffement de la contribution du ray. sol. reflechit: 202 203 !----------------------------------------------------------------------- 204 ! 6.ajout a l'echauffement de la contribution du ray. sol. reflechit: 205 205 ! ------------------------------------------------------------------- 206 206 207 207 DO l=1,nlayer 208 208 DO ig=1,ncount … … 212 212 ENDDO 213 213 ENDDO 214 214 215 215 !----------------------------------------------------------------------- 216 216 ! 10. sorites eventuelles: 217 217 ! ------------------------ 218 219 IF (lwrite) THEN 220 WRITELOG(*,*) 218 219 IF (lwrite) THEN 220 WRITELOG(*,*) 221 221 WRITELOG(*,*) 'Diagnostique des taux de chauffage solaires:' 222 222 WRITELOG(*,*) ' 3 taux de chauffage total' … … 225 225 ENDDO 226 226 ENDIF 227 227 228 228 IF (ldiurn) THEN 229 229 fsrfvis(:)=0. … … 246 246 ! call dump2d(iim,jjm-1,ztrdir(2,1),'ztrdir ') 247 247 LOG_INFO('rad_sw') 248 248 249 249 END SUBROUTINE sw 250 250 251 251 END MODULE radiative_sw 252 -
dynamico_lmdz/simple_physics/phyparam/physics/read_param_mod.F90
r4227 r4229 5 5 SAVE 6 6 7 INTERFACE 7 INTERFACE 8 8 9 9 ! each of these plugins reads a parameter of a certain type and stores the value in 'val' … … 43 43 INTERFACE read_param 44 44 PROCEDURE read_paramr, read_parami, read_paramb 45 END INTERFACE read_param45 END INTERFACE 46 46 47 47 PUBLIC :: read_param … … 68 68 #endif 69 69 END SUBROUTINE read_parami 70 70 71 71 SUBROUTINE read_paramb(name, defval, val, comment) 72 72 CHARACTER(*), INTENT(IN) :: name, comment … … 78 78 #endif 79 79 END SUBROUTINE read_paramb 80 80 81 81 END MODULE read_param_mod -
dynamico_lmdz/simple_physics/phyparam/physics/solar.F90
r4210 r4229 6 6 PRIVATE 7 7 8 REAL, PARAMETER :: pi_local = 4.0 * ATAN(1.0), deux_pi_local = 2.0 * pi_local 8 REAL, PARAMETER :: pi_local = 4.0 * ATAN(1.0), deux_pi_local = 2.0 * pi_local 9 9 10 10 PUBLIC :: solang, zenang, mucorr … … 14 14 PURE SUBROUTINE solang ( kgrid,psilon,pcolon,psilat,pcolat, & 15 15 ptim1,ptim2,ptim3,pmu0,pfract ) 16 16 17 17 !----------------------------------------------------------------------- 18 18 ! CALCULATES THE SOLAR ANGLE FOR ALL THE POINTS OF THE GRID … … 93 93 ENDIF 94 94 ENDDO 95 95 96 96 END SUBROUTINE solang 97 97 98 98 SUBROUTINE zenang(klon,longi,gmtime,pdtrad,lat,long, & 99 & pmu0,frac) 100 USE astronomy 101 102 !============================================================= 103 ! Auteur : O. Boucher (LMD/CNRS) 104 ! d'apres les routines zenith et angle de Z.X. Li 105 ! Objet : calculer les valeurs moyennes du cos de l'angle zenithal 106 ! et l'ensoleillement moyen entre gmtime1 et gmtime2 107 ! connaissant la declinaison, la latitude et la longitude. 108 ! Rque : Different de la routine angle en ce sens que zenang 109 ! fournit des moyennes de pmu0 et non des valeurs 110 ! instantanees, du coup frac prend toutes les valeurs 111 ! entre 0 et 1. 112 ! Date : premiere version le 13 decembre 1994 113 ! revu pour GCM le 30 septembre 1996 114 !=============================================================== 115 ! longi----INPUT : la longitude vraie de la terre dans son plan 116 ! solaire a partir de l'equinoxe de printemps (degre) 117 ! gmtime---INPUT : temps universel en fraction de jour 118 ! pdtrad---INPUT : pas de temps du rayonnement (secondes) 119 ! lat------INPUT : latitude en degres 120 ! long-----INPUT : longitude en degres 121 ! pmu0-----OUTPUT: angle zenithal moyen entre gmtime et gmtime+pdtrad 122 ! frac-----OUTPUT: ensoleillement moyen entre gmtime et gmtime+pdtrad 123 !================================================================ 124 integer klon 125 !================================================================ 126 real longi, gmtime, pdtrad 127 real lat(klon), long(klon), pmu0(klon), frac(klon) 128 !================================================================ 129 integer i 130 real gmtime1, gmtime2 131 real incl 132 real omega1, omega2, omega 133 ! omega1, omega2 : temps 1 et 2 exprime en radian avec 0 a midi. 134 ! omega : heure en radian du coucher de soleil 135 ! -omega est donc l'heure en radian de lever du soleil 136 real omegadeb, omegafin 137 real zfrac1, zfrac2, z1_mu, z2_mu 138 ! declinaison en radian 139 real lat_sun 140 ! longitude solaire en radian 141 real lon_sun 142 ! latitude du pt de grille en radian 143 real latr 144 !================================================================ 145 ! 146 ! incl=R_incl * pi_local / 180. 99 & pmu0,frac) 100 USE astronomy 101 102 !============================================================= 103 ! Auteur : O. Boucher (LMD/CNRS) 104 ! d'apres les routines zenith et angle de Z.X. Li 105 ! Objet : calculer les valeurs moyennes du cos de l'angle zenithal 106 ! et l'ensoleillement moyen entre gmtime1 et gmtime2 107 ! connaissant la declinaison, la latitude et la longitude. 108 ! Rque : Different de la routine angle en ce sens que zenang 109 ! fournit des moyennes de pmu0 et non des valeurs 110 ! instantanees, du coup frac prend toutes les valeurs 111 ! entre 0 et 1. 112 ! Date : premiere version le 13 decembre 1994 113 ! revu pour GCM le 30 septembre 1996 114 !=============================================================== 115 ! longi----INPUT : la longitude vraie de la terre dans son plan 116 ! solaire a partir de l'equinoxe de printemps (degre) 117 ! gmtime---INPUT : temps universel en fraction de jour 118 ! pdtrad---INPUT : pas de temps du rayonnement (secondes) 119 ! lat------INPUT : latitude en degres 120 ! long-----INPUT : longitude en degres 121 ! pmu0-----OUTPUT: angle zenithal moyen entre gmtime et gmtime+pdtrad 122 ! frac-----OUTPUT: ensoleillement moyen entre gmtime et gmtime+pdtrad 123 !================================================================ 124 integer klon 125 !================================================================ 126 real longi, gmtime, pdtrad 127 real lat(klon), long(klon), pmu0(klon), frac(klon) 128 !================================================================ 129 integer i 130 real gmtime1, gmtime2 131 real incl 132 real omega1, omega2, omega 133 ! omega1, omega2 : temps 1 et 2 exprime en radian avec 0 a midi. 134 ! omega : heure en radian du coucher de soleil 135 ! -omega est donc l'heure en radian de lever du soleil 136 real omegadeb, omegafin 137 real zfrac1, zfrac2, z1_mu, z2_mu 138 ! declinaison en radian 139 real lat_sun 140 ! longitude solaire en radian 141 real lon_sun 142 ! latitude du pt de grille en radian 143 real latr 144 !================================================================ 145 ! 146 ! incl=R_incl * pi_local / 180. 147 147 WRITELOG(*,*) 'Obliquite =' ,obliquit 148 148 LOG_INFO('solar') 149 149 150 incl=obliquit * pi_local / 180. 151 ! 152 ! lon_sun = longi * pi_local / 180.0 153 lon_sun = longi 154 lat_sun = ASIN (SIN(lon_sun)*SIN(incl) ) 155 ! 156 gmtime1=gmtime*86400. 157 gmtime2=gmtime*86400.+pdtrad 158 ! 159 DO i = 1, klon 160 ! 161 ! latr = lat(i) * pi_local / 180. 162 latr = lat(i) 163 ! 164 !--pose probleme quand lat=+/-90 degres 165 ! 166 ! omega = -TAN(latr)*TAN(lat_sun) 167 ! omega = ACOS(omega) 168 ! IF (latr.GE.(pi_local/2.+lat_sun) 169 ! . .OR. latr.LE.(-pi_local/2.+lat_sun)) THEN 170 ! omega = 0.0 ! nuit polaire 171 ! ENDIF 172 ! IF (latr.GE.(pi_local/2.-lat_sun) 173 ! . .OR. latr.LE.(-pi_local/2.-lat_sun)) THEN 174 ! omega = pi_local ! journee polaire 175 ! ENDIF 176 ! 177 !--remplace par cela (le cas par defaut est different) 178 ! 179 !--nuit polaire 180 omega=0.0 150 incl=obliquit * pi_local / 180. 151 ! 152 ! lon_sun = longi * pi_local / 180.0 153 lon_sun = longi 154 lat_sun = ASIN (SIN(lon_sun)*SIN(incl) ) 155 ! 156 gmtime1=gmtime*86400. 157 gmtime2=gmtime*86400.+pdtrad 158 ! 159 DO i = 1, klon 160 ! 161 ! latr = lat(i) * pi_local / 180. 162 latr = lat(i) 163 ! 164 !--pose probleme quand lat=+/-90 degres 165 ! 166 ! omega = -TAN(latr)*TAN(lat_sun) 167 ! omega = ACOS(omega) 168 ! IF (latr.GE.(pi_local/2.+lat_sun) 169 ! . .OR. latr.LE.(-pi_local/2.+lat_sun)) THEN 170 ! omega = 0.0 ! nuit polaire 171 ! ENDIF 172 ! IF (latr.GE.(pi_local/2.-lat_sun) 173 ! . .OR. latr.LE.(-pi_local/2.-lat_sun)) THEN 174 ! omega = pi_local ! journee polaire 175 ! ENDIF 176 ! 177 !--remplace par cela (le cas par defaut est different) 178 ! 179 !--nuit polaire 180 omega=0.0 181 181 IF (latr.GE.(pi_local/2.-lat_sun) & 182 & .OR. latr.LE.(-pi_local/2.-lat_sun)) THEN 183 ! journee polaire 184 omega = pi_local 182 & .OR. latr.LE.(-pi_local/2.-lat_sun)) THEN 183 ! journee polaire 184 omega = pi_local 185 185 ENDIF 186 186 IF (latr.LT.(pi_local/2.+lat_sun).AND. & 187 187 & latr.GT.(-pi_local/2.+lat_sun).AND. & 188 188 & latr.LT.(pi_local/2.-lat_sun).AND. & 189 & latr.GT.(-pi_local/2.-lat_sun)) THEN 190 omega = -TAN(latr)*TAN(lat_sun) 191 omega = ACOS(omega) 192 ENDIF 193 ! 194 omega1 = gmtime1 + long(i)*86400.0/360.0 195 omega1 = omega1 / 86400.0*deux_pi_local 196 omega1 = MOD (omega1+deux_pi_local, deux_pi_local) 197 omega1 = omega1 - pi_local 198 ! 199 omega2 = gmtime2 + long(i)*86400.0/360.0 200 omega2 = omega2 / 86400.0*deux_pi_local 201 omega2 = MOD (omega2+deux_pi_local, deux_pi_local) 202 omega2 = omega2 - pi_local 203 ! 204 !--on est dans la meme journee locale 205 IF (omega1.LE.omega2) THEN 206 ! 189 & latr.GT.(-pi_local/2.-lat_sun)) THEN 190 omega = -TAN(latr)*TAN(lat_sun) 191 omega = ACOS(omega) 192 ENDIF 193 ! 194 omega1 = gmtime1 + long(i)*86400.0/360.0 195 omega1 = omega1 / 86400.0*deux_pi_local 196 omega1 = MOD (omega1+deux_pi_local, deux_pi_local) 197 omega1 = omega1 - pi_local 198 ! 199 omega2 = gmtime2 + long(i)*86400.0/360.0 200 omega2 = omega2 / 86400.0*deux_pi_local 201 omega2 = MOD (omega2+deux_pi_local, deux_pi_local) 202 omega2 = omega2 - pi_local 203 ! 204 !--on est dans la meme journee locale 205 IF (omega1.LE.omega2) THEN 206 ! 207 207 IF (omega2.LE.-omega .OR. omega1.GE.omega .OR. omega.LT.1e-5) & 208 THEN 209 !--nuit 210 frac(i)=0.0 211 pmu0(i)=0.0 208 THEN 209 !--nuit 210 frac(i)=0.0 211 pmu0(i)=0.0 212 212 !--jour+nuit/jou 213 ELSE 214 omegadeb=MAX(-omega,omega1) 215 omegafin=MIN(omega,omega2) 216 frac(i)=(omegafin-omegadeb)/(omega2-omega1) 213 ELSE 214 omegadeb=MAX(-omega,omega1) 215 omegafin=MIN(omega,omega2) 216 frac(i)=(omegafin-omegadeb)/(omega2-omega1) 217 217 pmu0(i)=SIN(latr)*SIN(lat_sun) + COS(latr)*COS(lat_sun)* & 218 (SIN(omegafin)-SIN(omegadeb))/ (omegafin-omegadeb) 218 (SIN(omegafin)-SIN(omegadeb))/ (omegafin-omegadeb) 219 219 ENDIF 220 ! 221 !---omega1 GT omega2 -- a cheval sur deux journees 222 ELSE 223 ! 224 !-------------------entre omega1 et pi 225 !--nuit 226 IF (omega1.GE.omega) THEN 227 zfrac1=0.0 228 z1_mu =0.0 229 !--jour+nuit 230 ELSE 231 omegadeb=MAX(-omega,omega1) 232 omegafin=omega 233 zfrac1=omegafin-omegadeb 220 ! 221 !---omega1 GT omega2 -- a cheval sur deux journees 222 ELSE 223 ! 224 !-------------------entre omega1 et pi 225 !--nuit 226 IF (omega1.GE.omega) THEN 227 zfrac1=0.0 228 z1_mu =0.0 229 !--jour+nuit 230 ELSE 231 omegadeb=MAX(-omega,omega1) 232 omegafin=omega 233 zfrac1=omegafin-omegadeb 234 234 z1_mu =SIN(latr)*SIN(lat_sun) + COS(latr)*COS(lat_sun)* & 235 (SIN(omegafin)-SIN(omegadeb))/ (omegafin-omegadeb) 235 (SIN(omegafin)-SIN(omegadeb))/ (omegafin-omegadeb) 236 236 ENDIF 237 !---------------------entre -pi et omega2 238 !--nuit 239 IF (omega2.LE.-omega) THEN 240 zfrac2=0.0 241 z2_mu =0.0 242 !--jour+nuit 243 ELSE 244 omegadeb=-omega 245 omegafin=MIN(omega,omega2) 246 zfrac2=omegafin-omegadeb 237 !---------------------entre -pi et omega2 238 !--nuit 239 IF (omega2.LE.-omega) THEN 240 zfrac2=0.0 241 z2_mu =0.0 242 !--jour+nuit 243 ELSE 244 omegadeb=-omega 245 omegafin=MIN(omega,omega2) 246 zfrac2=omegafin-omegadeb 247 247 z2_mu =SIN(latr)*SIN(lat_sun) + COS(latr)*COS(lat_sun)* & 248 (SIN(omegafin)-SIN(omegadeb))/ (omegafin-omegadeb) 249 ! 248 (SIN(omegafin)-SIN(omegadeb))/ (omegafin-omegadeb) 249 ! 250 250 ENDIF 251 !-----------------------moyenne 252 frac(i)=(zfrac1+zfrac2)/(omega2+deux_pi_local-omega1) 253 pmu0(i)=(zfrac1*z1_mu+zfrac2*z2_mu)/MAX(zfrac1+zfrac2,1.E-10) 254 ! 255 !---comparaison omega1 et omega2 256 ENDIF 257 ! 251 !-----------------------moyenne 252 frac(i)=(zfrac1+zfrac2)/(omega2+deux_pi_local-omega1) 253 pmu0(i)=(zfrac1*z1_mu+zfrac2*z2_mu)/MAX(zfrac1+zfrac2,1.E-10) 254 ! 255 !---comparaison omega1 et omega2 256 ENDIF 257 ! 258 258 ENDDO 259 ! 259 ! 260 260 END SUBROUTINE zenang 261 261 262 262 PURE SUBROUTINE mucorr(npts,pdeclin, plat, pmu, pfract,phaut,prad) 263 263 264 264 !======================================================================= 265 265 ! 266 ! Calcul of equivalent solar angle and and fraction of day whithout 266 ! Calcul of equivalent solar angle and and fraction of day whithout 267 267 ! diurnal cycle. 268 268 ! … … 284 284 ! 285 285 !======================================================================= 286 286 287 287 !----------------------------------------------------------------------- 288 288 ! 289 289 ! 0. Declarations : 290 290 ! ----------------- 291 291 292 292 ! Arguments : 293 293 ! ----------- … … 306 306 307 307 !----------------------------------------------------------------------- 308 308 309 309 z = pdeclin 310 310 cz = cos (z) 311 311 sz = sin (z) 312 312 313 313 DO j = 1, npts 314 314 315 315 phi = plat(j) 316 316 cphi = cos(phi) … … 322 322 a = 1.0 - t*t 323 323 ap = a 324 324 325 325 IF(t.eq.0.) then 326 326 t=0.5*pi … … 334 334 ENDIF 335 335 ENDIF 336 336 337 337 pmu(j) = (sphi*sz*t) / pi + b*sin(t)/pi 338 338 pfract(j) = t / pi … … 344 344 pmu(j) = pmu(j) / pfract(j) 345 345 IF (pmu(j).eq.0.) pfract(j) = 0. 346 346 347 347 END DO 348 348 349 349 !----------------------------------------------------------------------- 350 350 ! correction de rotondite: 351 351 ! ------------------------ 352 352 353 353 alph=phaut/prad 354 354 DO j=1,npts … … 357 357 ! $ (sqrt(alph*alph*pmu(j)*pmu(j)+2.*alph+1.)-alph*pmu(j)) 358 358 END DO 359 359 360 360 END SUBROUTINE mucorr 361 361 -
dynamico_lmdz/simple_physics/phyparam/physics/surface.F90
r4228 r4229 14 14 15 15 ! precomputed variables 16 REAL :: lambda 16 REAL :: lambda 17 17 REAL,ALLOCATABLE :: dz1(:),dz2(:) 18 18 !$OMP THREADPRIVATE(dz1,dz2,zc,lambda) 19 19 20 20 ! internal state variables needed for checkpoint/restart 21 REAL, ALLOCATABLE :: zc(:,:),zd(:,:) 21 REAL, ALLOCATABLE :: zc(:,:),zd(:,:) 22 22 !$OMP THREADPRIVATE(zc,zd) 23 23 … … 28 28 SUBROUTINE init_soil(ngrid,nsoil) 29 29 INTEGER, INTENT(IN) :: ngrid, nsoil 30 REAL min_period,dalph_soil 31 REAL fz,rk,fz1,rk1,rk2 30 REAL min_period,dalph_soil 31 REAL fz,rk,fz1,rk1,rk2 32 32 INTEGER :: jk 33 33 34 34 ! this is a function definition 35 fz(rk)=fz1*(dalph_soil**rk-1.)/(dalph_soil-1.) 36 37 !----------------------------------------------------------------------- 38 ! ground levels 39 ! grnd=z/l where l is the skin depth of the diurnal cycle: 40 ! -------------------------------------------------------- 41 35 fz(rk)=fz1*(dalph_soil**rk-1.)/(dalph_soil-1.) 36 37 !----------------------------------------------------------------------- 38 ! ground levels 39 ! grnd=z/l where l is the skin depth of the diurnal cycle: 40 ! -------------------------------------------------------- 41 42 42 WRITELOG(*,*) 'nsoil,ngrid,firstcall=',nsoil,ngrid, .TRUE. 43 43 44 ALLOCATE(dz1(nsoil),dz2(nsoil)) 45 46 min_period=20000. 47 dalph_soil=2. 48 49 ! la premiere couche represente un dixieme de cycle diurne 50 fz1=sqrt(min_period/pi) 51 52 DO jk=1,nsoil 53 rk1=jk 54 rk2=jk-1 55 dz2(jk)=fz(rk1)-fz(rk2) 56 ENDDO 57 DO jk=1,nsoil-1 58 rk1=jk+.5 59 rk2=jk-.5 60 dz1(jk)=1./(fz(rk1)-fz(rk2)) 61 ENDDO 62 lambda=fz(.5)*dz1(1) 63 64 WRITELOG(*,*) 'full layers, intermediate layers (secoonds)' 65 DO jk=1,nsoil 66 rk=jk 67 rk1=jk+.5 68 rk2=jk-.5 44 ALLOCATE(dz1(nsoil),dz2(nsoil)) 45 46 min_period=20000. 47 dalph_soil=2. 48 49 ! la premiere couche represente un dixieme de cycle diurne 50 fz1=sqrt(min_period/pi) 51 52 DO jk=1,nsoil 53 rk1=jk 54 rk2=jk-1 55 dz2(jk)=fz(rk1)-fz(rk2) 56 ENDDO 57 DO jk=1,nsoil-1 58 rk1=jk+.5 59 rk2=jk-.5 60 dz1(jk)=1./(fz(rk1)-fz(rk2)) 61 ENDDO 62 lambda=fz(.5)*dz1(1) 63 64 WRITELOG(*,*) 'full layers, intermediate layers (secoonds)' 65 DO jk=1,nsoil 66 rk=jk 67 rk1=jk+.5 68 rk2=jk-.5 69 69 WRITELOG(*,*) fz(rk1)*fz(rk2)*pi, & 70 & fz(rk)*fz(rk)*pi 70 & fz(rk)*fz(rk)*pi 71 71 ENDDO 72 72 LOG_INFO('init_soil') 73 73 74 74 END SUBROUTINE init_soil 75 75 76 76 SUBROUTINE soil(ngrid,nsoil,firstcall,ptherm_i, & 77 77 & ptimestep,ptsrf,ptsoil, & 78 & pcapcal,pfluxgrd) 79 78 & pcapcal,pfluxgrd) 79 80 80 !======================================================================= 81 ! 82 ! Auteur: Frederic Hourdin 30/01/92 83 ! ------- 84 ! 85 ! objet: computation of : the soil temperature evolution 86 ! ------ the surfacic heat capacity "Capcal" 87 ! the surface conduction flux pcapcal 88 ! 89 ! 90 ! Method: implicit time integration 91 ! ------- 92 ! Consecutive ground temperatures are related by: 93 ! T(k+1) = C(k) + D(k)*T(k) (1) 94 ! the coefficients C and D are computed at the t-dt time-step. 95 ! Routine structure: 96 ! 1)new temperatures are computed using (1) 97 ! 2)C and D coefficients are computed from the new temperature 98 ! profile for the t+dt time-step 99 ! 3)the coefficients A and B are computed where the diffusive 100 ! fluxes at the t+dt time-step is given by 101 ! Fdiff = A + B Ts(t+dt) 102 ! or Fdiff = F0 + Capcal (Ts(t+dt)-Ts(t))/dt 103 ! with F0 = A + B (Ts(t)) 104 ! Capcal = B*dt 105 ! 106 ! Interface: 107 ! ---------- 108 ! 109 ! Arguments: 110 ! ---------- 111 ! ngrid number of grid-points 112 ! ptimestep physical timestep (s) 113 ! pto(ngrid,nsoil) temperature at time-step t (K) 114 ! ptn(ngrid,nsoil) temperature at time step t+dt (K) 115 ! pcapcal(ngrid) specific heat (W*m-2*s*K-1) 116 ! pfluxgrd(ngrid) surface diffusive flux from ground (Wm-2) 117 ! 81 ! 82 ! Auteur: Frederic Hourdin 30/01/92 83 ! ------- 84 ! 85 ! objet: computation of : the soil temperature evolution 86 ! ------ the surfacic heat capacity "Capcal" 87 ! the surface conduction flux pcapcal 88 ! 89 ! 90 ! Method: implicit time integration 91 ! ------- 92 ! Consecutive ground temperatures are related by: 93 ! T(k+1) = C(k) + D(k)*T(k) (1) 94 ! the coefficients C and D are computed at the t-dt time-step. 95 ! Routine structure: 96 ! 1)new temperatures are computed using (1) 97 ! 2)C and D coefficients are computed from the new temperature 98 ! profile for the t+dt time-step 99 ! 3)the coefficients A and B are computed where the diffusive 100 ! fluxes at the t+dt time-step is given by 101 ! Fdiff = A + B Ts(t+dt) 102 ! or Fdiff = F0 + Capcal (Ts(t+dt)-Ts(t))/dt 103 ! with F0 = A + B (Ts(t)) 104 ! Capcal = B*dt 105 ! 106 ! Interface: 107 ! ---------- 108 ! 109 ! Arguments: 110 ! ---------- 111 ! ngrid number of grid-points 112 ! ptimestep physical timestep (s) 113 ! pto(ngrid,nsoil) temperature at time-step t (K) 114 ! ptn(ngrid,nsoil) temperature at time step t+dt (K) 115 ! pcapcal(ngrid) specific heat (W*m-2*s*K-1) 116 ! pfluxgrd(ngrid) surface diffusive flux from ground (Wm-2) 117 ! 118 118 !======================================================================= 119 ! declarations: 120 ! ------------- 121 122 123 !----------------------------------------------------------------------- 124 ! arguments 125 ! --------- 126 127 INTEGER ngrid,nsoil 128 REAL ptimestep 129 REAL ptsrf(ngrid),ptsoil(ngrid,nsoil),ptherm_i(ngrid) 130 REAL pcapcal(ngrid),pfluxgrd(ngrid) 131 LOGICAL firstcall 132 133 134 !----------------------------------------------------------------------- 135 ! local arrays 136 ! ------------ 137 138 INTEGER ig,jk 139 REAL zdz2(nsoil),z1(ngrid) 140 141 IF (firstcall) THEN 119 ! declarations: 120 ! ------------- 121 122 123 !----------------------------------------------------------------------- 124 ! arguments 125 ! --------- 126 127 INTEGER ngrid,nsoil 128 REAL ptimestep 129 REAL ptsrf(ngrid),ptsoil(ngrid,nsoil),ptherm_i(ngrid) 130 REAL pcapcal(ngrid),pfluxgrd(ngrid) 131 LOGICAL firstcall 132 133 134 !----------------------------------------------------------------------- 135 ! local arrays 136 ! ------------ 137 138 INTEGER ig,jk 139 REAL zdz2(nsoil),z1(ngrid) 140 141 IF (firstcall) THEN 142 142 CALL init_soil(ngrid, nsoil) 143 143 ELSE 144 144 !----------------------------------------------------------------------- 145 ! Computation of the soil temperatures using the Cgrd and Dgrd 146 ! coefficient computed at the previous time-step: 147 ! ----------------------------------------------- 148 149 ! surface temperature 150 DO ig=1,ngrid 145 ! Computation of the soil temperatures using the Cgrd and Dgrd 146 ! coefficient computed at the previous time-step: 147 ! ----------------------------------------------- 148 149 ! surface temperature 150 DO ig=1,ngrid 151 151 ptsoil(ig,1)=(lambda*zc(ig,1)+ptsrf(ig))/ & 152 & (lambda*(1.-zd(ig,1))+1.) 152 & (lambda*(1.-zd(ig,1))+1.) 153 153 ENDDO 154 155 ! other temperatures 156 DO jk=1,nsoil-1 157 DO ig=1,ngrid 154 155 ! other temperatures 156 DO jk=1,nsoil-1 157 DO ig=1,ngrid 158 158 ptsoil(ig,jk+1)=zc(ig,jk)+zd(ig,jk)*ptsoil(ig,jk) 159 159 ENDDO 160 160 ENDDO 161 161 162 162 ENDIF 163 163 164 164 !----------------------------------------------------------------------- 165 ! Computation of the Cgrd and Dgrd coefficient for the next step: 166 ! --------------------------------------------------------------- 167 168 DO jk=1,nsoil 169 zdz2(jk)=dz2(jk)/ptimestep 170 ENDDO 171 172 DO ig=1,ngrid 173 z1(ig)=zdz2(nsoil)+dz1(nsoil-1) 174 zc(ig,nsoil-1)=zdz2(nsoil)*ptsoil(ig,nsoil)/z1(ig) 175 zd(ig,nsoil-1)=dz1(nsoil-1)/z1(ig) 176 ENDDO 177 178 DO jk=nsoil-1,2,-1 179 DO ig=1,ngrid 180 z1(ig)=1./(zdz2(jk)+dz1(jk-1)+dz1(jk)*(1.-zd(ig,jk))) 165 ! Computation of the Cgrd and Dgrd coefficient for the next step: 166 ! --------------------------------------------------------------- 167 168 DO jk=1,nsoil 169 zdz2(jk)=dz2(jk)/ptimestep 170 ENDDO 171 172 DO ig=1,ngrid 173 z1(ig)=zdz2(nsoil)+dz1(nsoil-1) 174 zc(ig,nsoil-1)=zdz2(nsoil)*ptsoil(ig,nsoil)/z1(ig) 175 zd(ig,nsoil-1)=dz1(nsoil-1)/z1(ig) 176 ENDDO 177 178 DO jk=nsoil-1,2,-1 179 DO ig=1,ngrid 180 z1(ig)=1./(zdz2(jk)+dz1(jk-1)+dz1(jk)*(1.-zd(ig,jk))) 181 181 zc(ig,jk-1)= & 182 & (ptsoil(ig,jk)*zdz2(jk)+dz1(jk)*zc(ig,jk))*z1(ig) 183 zd(ig,jk-1)=dz1(jk-1)*z1(ig) 182 & (ptsoil(ig,jk)*zdz2(jk)+dz1(jk)*zc(ig,jk))*z1(ig) 183 zd(ig,jk-1)=dz1(jk-1)*z1(ig) 184 184 ENDDO 185 185 ENDDO 186 187 !----------------------------------------------------------------------- 188 ! computation of the surface diffusive flux from ground and 189 ! calorific capacity of the ground: 190 ! --------------------------------- 191 192 DO ig=1,ngrid 186 187 !----------------------------------------------------------------------- 188 ! computation of the surface diffusive flux from ground and 189 ! calorific capacity of the ground: 190 ! --------------------------------- 191 192 DO ig=1,ngrid 193 193 pfluxgrd(ig)=ptherm_i(ig)*dz1(1)* & 194 194 & (zc(ig,1)+(zd(ig,1)-1.)*ptsoil(ig,1)) … … 198 198 pfluxgrd(ig)=pfluxgrd(ig) & 199 199 & +pcapcal(ig)*(ptsoil(ig,1)*z1(ig)-lambda*zc(ig,1)-ptsrf(ig)) & 200 & /ptimestep 201 ENDDO 202 200 & /ptimestep 201 ENDDO 202 203 203 END SUBROUTINE soil 204 204 205 205 END MODULE surface -
dynamico_lmdz/simple_physics/phyparam/physics/turbulence.F90
r4228 r4229 1 1 MODULE turbulence 2 2 3 3 #include "use_logging.h" 4 4 … … 8 8 9 9 REAL, PARAMETER :: karman=0.4 10 REAL :: lmixmin=100., emin_turb=1e-8 10 REAL :: lmixmin=100., emin_turb=1e-8 11 11 12 12 PUBLIC :: vdif, lmixmin, emin_turb 13 13 14 14 CONTAINS 15 15 16 16 PURE SUBROUTINE vdif_cd( ngrid,pz0,pg,pz,pu,pv,pts,ph,pcdv,pcdh) 17 17 !======================================================================= … … 47 47 ! Declarations: 48 48 ! ------------- 49 49 50 50 ! Arguments: 51 51 ! ---------- 52 52 53 53 INTEGER, INTENT(IN) :: ngrid 54 54 REAL, INTENT(IN) :: pg, pz0(ngrid), pz(ngrid), & 55 55 pu(ngrid),pv(ngrid), pts(ngrid),ph(ngrid) 56 56 REAL, INTENT(OUT) :: pcdv(ngrid),pcdh(ngrid) 57 57 58 58 ! Local: 59 59 ! ------ 60 60 61 61 REAL, PARAMETER :: b=5., c=5., d=5., umin2=1e-12, & 62 62 c2b=2.*b, c3bc=3.*b*c, c3b=3.*b 63 63 INTEGER ig 64 REAL zu2,z1,zri,zcd0,zz 65 64 REAL zu2,z1,zri,zcd0,zz 65 66 66 !----------------------------------------------------------------------- 67 67 ! couche de surface: 68 68 ! ------------------ 69 69 70 70 ! DO ig=1,ngrid 71 71 ! zu2=pu(ig)*pu(ig)+pv(ig)*pv(ig)+umin2 … … 74 74 ! ENDDO 75 75 ! RETURN 76 77 76 77 78 78 !!!! WARNING, verifier la formule originale de Louis! 79 79 DO ig=1,ngrid … … 93 93 ENDIF 94 94 ENDDO 95 96 !----------------------------------------------------------------------- 97 95 96 !----------------------------------------------------------------------- 97 98 98 END SUBROUTINE vdif_cd 99 99 100 100 PURE SUBROUTINE vdif_k(ngrid,nlay, & 101 101 ptimestep,pg,pzlev,pzlay,pz0,pu,pv,ph,pkv,pkh) … … 106 106 pu(ngrid,nlay),pv(ngrid,nlay),ph(ngrid,nlay) 107 107 REAL, INTENT(OUT) :: pkv(ngrid,nlay+1),pkh(ngrid,nlay+1) 108 108 109 109 INTEGER ig,il 110 110 REAL zdu,zdv,zri,zdvodz2,zdz,z1,lmix 111 111 112 112 DO ig=1,ngrid 113 113 pkv(ig,1)=0. … … 116 116 pkh(ig,nlay+1)=0. 117 117 ENDDO 118 118 119 119 DO il=2,nlay 120 120 DO ig=1,ngrid … … 138 138 ENDDO 139 139 ENDDO 140 140 141 141 END SUBROUTINE vdif_k 142 142 143 143 144 144 SUBROUTINE multipl(n,x1,x2,y) 145 !=======================================================================146 ! multiplication de deux vecteurs147 !=======================================================================145 !======================================================================= 146 ! multiplication de deux vecteurs 147 !======================================================================= 148 148 INTEGER n,i 149 149 REAL x1(n),x2(n),y(n) … … 162 162 lwrite) 163 163 USE phys_const 164 165 !=======================================================================166 !167 ! Diffusion verticale168 ! Shema implicite169 ! On commence par rajouter au variables x la tendance physique170 ! et on resoult en fait:171 ! x(t+1) = x(t) + dt * (dx/dt)phys(t) + dt * (dx/dt)difv(t+1)172 !173 ! arguments:174 ! ----------175 !176 ! entree:177 ! -------178 !179 !180 !=======================================================================181 182 !183 ! arguments:184 ! ----------164 165 !======================================================================= 166 ! 167 ! Diffusion verticale 168 ! Shema implicite 169 ! On commence par rajouter au variables x la tendance physique 170 ! et on resoult en fait: 171 ! x(t+1) = x(t) + dt * (dx/dt)phys(t) + dt * (dx/dt)difv(t+1) 172 ! 173 ! arguments: 174 ! ---------- 175 ! 176 ! entree: 177 ! ------- 178 ! 179 ! 180 !======================================================================= 181 182 ! 183 ! arguments: 184 ! ---------- 185 185 186 186 INTEGER ngrid,nlay … … 198 198 ! local: 199 199 ! ------ 200 200 201 201 INTEGER ilev,ig,ilay,nlev 202 202 INTEGER unit,ierr,it1,it2 … … 213 213 REAL zc(ngrid,nlay),zd(ngrid,nlay) 214 214 REAL zcst1 215 215 216 216 ! 217 217 !----------------------------------------------------------------------- 218 218 ! initialisations: 219 219 ! ---------------- 220 220 221 221 nlev=nlay+1 222 222 223 223 ! computation of rho*dz and dt*rho/dz=dt*rho**2 g/dp: 224 224 ! with rho=p/RT=p/ (R Theta) (p/ps)**kappa 225 225 ! --------------------------------- 226 226 227 227 DO ilay=1,nlay 228 228 DO ig=1,ngrid … … 230 230 ENDDO 231 231 ENDDO 232 232 233 233 zcst1=4.*g*ptimestep/(r*r) 234 234 DO ilev=2,nlev-1 … … 258 258 LOG_DBG('vdif') 259 259 ENDIF 260 260 261 261 !----------------------------------------------------------------------- 262 262 ! 2. ajout des tendances physiques: 263 263 ! ------------------------------ 264 264 265 265 DO ilev=1,nlay 266 266 DO ig=1,ngrid … … 270 270 ENDDO 271 271 ENDDO 272 272 273 273 !----------------------------------------------------------------------- 274 274 ! 3. calcul de cd : … … 277 277 CALL vdif_cd( ngrid,pz0,g,pzlay,pu,pv,ptsrf,ph,zcdv,zcdh) 278 278 CALL vdif_k(ngrid,nlay,ptimestep,g,pzlev,pzlay,pz0,pu,pv,ph,zkv,zkh) 279 279 280 280 DO ig=1,ngrid 281 281 zu2=pu(ig,1)*pu(ig,1)+pv(ig,1)*pv(ig,1) … … 283 283 zcdh(ig)=zcdh(ig)*sqrt(zu2) 284 284 ENDDO 285 286 IF(lwrite) THEN 285 286 IF(lwrite) THEN 287 287 WRITELOG(*,*) 'Diagnostique diffusion verticale' 288 288 WRITELOG(*,*) 'LMIXMIN',lmixmin … … 295 295 LOG_DBG('vdif') 296 296 ENDIF 297 297 298 298 !----------------------------------------------------------------------- 299 299 ! integration verticale pour u: 300 300 ! ----------------------------- 301 301 302 302 CALL multipl((nlay-1)*ngrid,zkv(1,2),zb0(1,2),zb(1,2)) 303 303 CALL multipl(ngrid,zcdv,zb0,zb) … … 307 307 zd(ig,nlay)=zb(ig,nlay)*z1(ig) 308 308 ENDDO 309 309 310 310 DO ilay=nlay-1,1,-1 311 311 DO ig=1,ngrid … … 317 317 ENDDO 318 318 ENDDO 319 319 320 320 DO ig=1,ngrid 321 321 zu(ig,1)=zc(ig,1) … … 326 326 ENDDO 327 327 ENDDO 328 328 329 329 !----------------------------------------------------------------------- 330 330 ! integration verticale pour v: … … 336 336 zd(ig,nlay)=zb(ig,nlay)*z1(ig) 337 337 ENDDO 338 338 339 339 DO ilay=nlay-1,1,-1 340 340 DO ig=1,ngrid … … 346 346 ENDDO 347 347 ENDDO 348 348 349 349 DO ig=1,ngrid 350 350 zv(ig,1)=zc(ig,1) … … 355 355 ENDDO 356 356 ENDDO 357 357 358 358 !----------------------------------------------------------------------- 359 359 ! integration verticale pour h: … … 367 367 zd(ig,nlay)=zb(ig,nlay)*z1(ig) 368 368 ENDDO 369 369 370 370 DO ilay=nlay-1,1,-1 371 371 DO ig=1,ngrid … … 377 377 ENDDO 378 378 ENDDO 379 379 380 380 !----------------------------------------------------------------------- 381 381 ! rajout eventuel de planck dans le shema implicite: 382 382 ! -------------------------------------------------- 383 383 384 384 z4st=4.*5.67e-8*ptimestep 385 385 DO ig=1,ngrid 386 386 zdplanck(ig)=z4st*pemis(ig)*ptsrf(ig)*ptsrf(ig)*ptsrf(ig) 387 387 ENDDO 388 388 389 389 !----------------------------------------------------------------------- 390 390 ! calcul le l'evolution de la temperature du sol: 391 391 ! ----------------------------------------------- 392 392 393 393 DO ig=1,ngrid 394 394 z1(ig) = pcapcal(ig)*ptsrf(ig)+cpp*zb(ig,1)*zc(ig,1) & … … 399 399 pdtsrf(ig) = (ztsrf2(ig)-ptsrf(ig))/ptimestep 400 400 ENDDO 401 401 402 402 !----------------------------------------------------------------------- 403 403 ! integration verticale finale: 404 404 ! ----------------------------- 405 405 406 406 DO ilay=2,nlay 407 407 DO ig=1,ngrid … … 409 409 ENDDO 410 410 ENDDO 411 411 412 412 !----------------------------------------------------------------------- 413 413 ! calcul final des tendances de la diffusion verticale: 414 414 ! ----------------------------------------------------- 415 415 416 416 DO ilev = 1, nlay 417 417 DO ig=1,ngrid … … 424 424 ENDDO 425 425 ENDDO 426 426 427 427 IF(lwrite) THEN 428 WRITELOG(*,*) 428 WRITELOG(*,*) 429 429 WRITELOG(*,*) 'Diagnostique de la diffusion verticale' 430 430 WRITELOG(*,*) 'h avant et apres diffusion verticale' … … 437 437 438 438 END SUBROUTINE vdif 439 439 440 440 END MODULE turbulence -
dynamico_lmdz/simple_physics/phyparam/physics/use_logging.h
r4210 r4229 1 1 USE logging 2 2 #define WRITELOG(junk, fmt) logging_lineno = MIN(logging_bufsize, logging_lineno+1) ; WRITE(logging_buf(logging_lineno), fmt) 3 3 #define LOG_WARN(tag) CALL flush_log(log_level_warn, tag) -
dynamico_lmdz/simple_physics/phyparam/physics/writefield_mod.F90
r4227 r4229 24 24 INTERFACE writefield 25 25 PROCEDURE writefield1, writefield2 26 END INTERFACE writefield26 END INTERFACE 27 27 28 28 PUBLIC :: writefield … … 53 53 #endif 54 54 END SUBROUTINE writefield1 55 55 56 56 END MODULE writefield_mod
Note: See TracChangeset
for help on using the changeset viewer.