Changeset 5202 for LMDZ6/branches/cirrus/libf
- Timestamp:
- Sep 20, 2024, 12:32:04 PM (4 months ago)
- Location:
- LMDZ6/branches/cirrus
- Files:
-
- 7 deleted
- 81 edited
- 18 copied
Legend:
- Unmodified
- Added
- Removed
-
LMDZ6/branches/cirrus
- Property svn:mergeinfo changed
-
LMDZ6/branches/cirrus/libf/dyn3d/check_isotopes.F90
r4399 r5202 23 23 iso_O17, iso_HTO 24 24 LOGICAL, SAVE :: first=.TRUE. 25 LOGICAL, PARAMETER :: tnat1=.TRUE. 25 26 26 27 modname='check_isotopes' … … 34 35 iso_O17 = strIdx(isoName,'H217O') 35 36 iso_HTO = strIdx(isoName,'HTO') 36 IF(getKey('tnat', tnat)) CALL abort_gcm(modname, 'missing isotopic parameter', 1) 37 if (tnat1) then 38 tnat(:)=1.0 39 else 40 IF(getKey('tnat', tnat)) CALL abort_gcm(modname, 'missing isotopic parameter', 1) 41 endif 37 42 first = .FALSE. 38 43 END IF -
LMDZ6/branches/cirrus/libf/dyn3d/conf_gcm.F90
r4519 r5202 18 18 USE logic_mod, ONLY: fxyhypb, iflag_phys, ok_etat0, ok_gradsfile, & 19 19 ok_guide, ok_limit, ok_strato, purmats, read_start, & 20 ysinus, read_orop 20 ysinus, read_orop, adv_qsat_liq 21 21 USE serre_mod, ONLY: clon,clat,grossismx,grossismy,dzoomx,dzoomy, & 22 22 alphax,alphay,taux,tauy … … 606 606 type_trac = 'lmdz' 607 607 CALL getin('type_trac',type_trac) 608 609 610 !Config Key = adv_qsat_liq 611 !Config Desc = option for qsat calculation in the dynamics 612 !Config Def = n 613 !Config Help = controls which phase is considered for qsat calculation 614 !Config 615 adv_qsat_liq = .FALSE. 616 CALL getin('adv_qsat_liq',adv_qsat_liq) 608 617 609 618 !Config Key = ok_dynzon … … 672 681 write(lunout,*)' ok_dyn_ins = ', ok_dyn_ins 673 682 write(lunout,*)' ok_dyn_ave = ', ok_dyn_ave 683 write(lunout,*)' adv_qsat_liq = ', adv_qsat_liq 674 684 ELSE 675 685 !Config Key = clon -
LMDZ6/branches/cirrus/libf/dyn3d/dynetat0.F90
r4492 r5202 43 43 REAL :: time, tnat, alpha_ideal, tab_cntrl(length) !--- RUN PARAMS TABLE 44 44 LOGICAL :: lSkip, ll 45 LOGICAL,PARAMETER :: tnat1=.TRUE. 45 46 !------------------------------------------------------------------------------- 46 47 modname="dynetat0" … … 155 156 iqParent = tracers(iq)%iqParent 156 157 IF(tracers(iq)%iso_iZone == 0) THEN 157 IF(getKey('tnat', tnat, isoName(iName)) .OR. getKey('alpha', alpha_ideal, isoName(iName))) & 158 if (tnat1) then 159 tnat=1.0 160 alpha_ideal=1.0 161 write(*,*) 'attention dans dynetat0: les alpha_ideal sont a 1' 162 else 163 IF(getKey('tnat', tnat, isoName(iName)) .OR. getKey('alpha', alpha_ideal, isoName(iName))) & 158 164 CALL abort_gcm(TRIM(modname), 'missing isotopic parameters', 1) 165 endif 159 166 CALL msg('Tracer <'//TRIM(var)//'> is missing => initialized with a simplified Rayleigh distillation law.', modname) 160 167 q(:,:,:,iq) = q(:,:,:,iqParent)*tnat*(q(:,:,:,iqParent)/30.e-3)**(alpha_ideal-1.) -
LMDZ6/branches/cirrus/libf/dyn3d/dynredem_mod.F90
r2299 r5202 4 4 PRIVATE 5 5 PUBLIC :: dynredem_write_u, dynredem_write_v, dynredem_read_u, err 6 PUBLIC :: cre_var, get_var1,put_var1, put_var2, fil, modname, msg6 PUBLIC :: cre_var, put_var1, put_var2, fil, modname, msg 7 7 include "dimensions.h" 8 8 include "paramet.h" -
LMDZ6/branches/cirrus/libf/dyn3d/iniacademic.F90
r4419 r5202 80 80 81 81 REAL zdtvr, tnat, alpha_ideal 82 LOGICAL,PARAMETER :: tnat1=.true. 82 83 83 84 character(len=*),parameter :: modname="iniacademic" … … 321 322 iqParent = tracers(iq)%iqParent 322 323 IF(tracers(iq)%iso_iZone == 0) THEN 323 IF(getKey('tnat', tnat, isoName(iName)) .OR. getKey('alpha', alpha_ideal, isoName(iName))) & 324 if (tnat1) then 325 tnat=1.0 326 alpha_ideal=1.0 327 write(*,*) 'Attention dans iniacademic: alpha_ideal=1' 328 else 329 IF(getKey('tnat', tnat, isoName(iName)) .OR. getKey('alpha', alpha_ideal, isoName(iName))) & 324 330 CALL abort_gcm(TRIM(modname), 'missing isotopic parameters', 1) 331 endif 325 332 q(:,:,iq) = q(:,:,iqParent)*tnat*(q(:,:,iqParent)/30.e-3)**(alpha_ideal-1.) 326 ELSE 327 q(:,:,iq) = q(:,:,iqIsoPha(iName,iPhase)) 328 END IF 333 ELSE !IF(tracers(iq)%iso_iZone == 0) THEN 334 IF(tracers(iq)%iso_iZone == 1) THEN 335 ! correction le 14 mai 2024 pour que tous les traceurs soient de la couleur 1. 336 ! Sinon, on va avoir des porblèmes de conservation de masse de traceurs. 337 q(:,:,iq) = q(:,:,iqIsoPha(iName,iPhase)) 338 else !IF(tracers(iq)%iso_iZone == 1) THEN 339 q(:,:,iq) = 0. 340 endif !IF(tracers(iq)%iso_iZone == 1) THEN 341 END IF !IF(tracers(iq)%iso_iZone == 0) THEN 329 342 enddo 330 343 else -
LMDZ6/branches/cirrus/libf/dyn3d/logic_mod.F90
r2665 r5202 30 30 LOGICAL hybrid ! vertical coordinate is hybrid if true (sigma otherwise) 31 31 ! (only used if disvert_type==2) 32 LOGICAL adv_qsat_liq ! true if qsat is calculated alwats wrt liquid for 33 ! adapted Van Leer advection scheme 32 34 INTEGER iflag_phys ! type of physics to call: 0 none, 1: phy*** package, 33 35 ! 2: Held & Suarez, 101-200: aquaplanets & terraplanets -
LMDZ6/branches/cirrus/libf/dyn3d/qminimum.F
r4143 r5202 28 28 c ................................................................. 29 29 c 30 cDC iq_val and iq_liq are usable for q only, NOT for q_follow 31 c and zx_defau_diag (crash if iq_val/liq==3) => vapor/liquid 32 c water at hardcoded indices 1/2 in these variables 30 33 INTEGER i, k, iq 31 34 REAL zx_defau, zx_abc, zx_pump(ip1jmp1), pompe … … 58 61 59 62 zx_defau_diag(:,:,:)=0.0 60 q_follow(:,:,1:2)=q(:,:,1:2) 61 DO 1000 k = 1, llm 62 DO 1040 i = 1, ip1jmp1 63 q_follow(:,:,1)=q(:,:,iq_vap) 64 q_follow(:,:,2)=q(:,:,iq_liq) 65 DO k = 1, llm 66 DO i = 1, ip1jmp1 63 67 if (seuil_liq - q(i,k,iq_liq) .gt. 0.d0 ) then 64 68 65 if (niso > 0) zx_defau_diag(i,k,iq_liq)=AMAX169 if (niso > 0) zx_defau_diag(i,k,2)=AMAX1 66 70 : ( seuil_liq - q(i,k,iq_liq), 0.0 ) 67 71 68 69 70 71 1040 CONTINUE72 1000 CONTINUE72 q(i,k,iq_vap) = q(i,k,iq_vap) + q(i,k,iq_liq) - seuil_liq 73 q(i,k,iq_liq) = seuil_liq 74 endif 75 ENDDO 76 ENDDO 73 77 c 74 78 c Quand l'eau vapeur est trop faible (ou negative), on complete 75 79 c le defaut en prennant de l'eau vapeur de la couche au-dessous. 76 80 c 77 iq = iq_vap78 c79 81 DO k = llm, 2, -1 80 82 ccc zx_abc = dpres(k) / dpres(k-1) 81 83 DO i = 1, ip1jmp1 82 if ( seuil_vap - q(i,k,iq ) .gt. 0.d0 ) then84 if ( seuil_vap - q(i,k,iq_vap) .gt. 0.d0 ) then 83 85 84 if (niso > 0) 85 & zx_defau_diag(i,k,iq)=AMAX1( seuil_vap - q(i,k,iq), 0.0 )86 if (niso > 0) zx_defau_diag(i,k,1) 87 & = AMAX1( seuil_vap - q(i,k,iq_vap), 0.0 ) 86 88 87 q(i,k-1,iq) = q(i,k-1,iq) - ( seuil_vap - q(i,k,iq) ) * 88 & deltap(i,k) / deltap(i,k-1) 89 q(i,k,iq) = seuil_vap 89 q(i,k-1,iq_vap) = q(i,k-1,iq_vap) - (seuil_vap 90 & -q(i,k,iq_vap)) * deltap(i,k)/deltap(i,k-1) 91 q(i,k,iq_vap) = seuil_vap 92 90 93 endif 91 94 ENDDO 92 95 ENDDO 96 93 97 c 94 98 c Quand il s'agit de la premiere couche au-dessus du sol, on … … 96 100 c 97 101 DO i = 1, ip1jmp1 98 zx_pump(i) = AMAX1( 0.0, seuil_vap - q(i,1,iq ) )99 q(i,1,iq ) = AMAX1( q(i,1,iq), seuil_vap )102 zx_pump(i) = AMAX1( 0.0, seuil_vap - q(i,1,iq_vap) ) 103 q(i,1,iq_vap) = AMAX1( q(i,1,iq_vap), seuil_vap ) 100 104 ENDDO 101 105 pompe = SSUM(ip1jmp1,zx_pump,1) … … 121 125 DO i = 1,ip1jmp1 122 126 if (zx_pump(i).gt.0.0) then 123 q_follow(i,1, iq_vap)=q_follow(i,1,iq_vap)+zx_pump(i)127 q_follow(i,1,1)=q_follow(i,1,1)+zx_pump(i) 124 128 endif !if (zx_pump(i).gt.0.0) then 125 129 enddo !DO i = 1,ip1jmp1 … … 129 133 do k=2,llm 130 134 DO i = 1,ip1jmp1 131 if (zx_defau_diag(i,k, iq_vap).gt.0.0) then135 if (zx_defau_diag(i,k,1).gt.0.0) then 132 136 ! on ajoute la vapeur en k 133 137 do ixt=1,ntiso 134 138 q(i,k,iqIsoPha(ixt,iq_vap))=q(i,k,iqIsoPha(ixt,iq_vap)) 135 : +zx_defau_diag(i,k, iq_vap)136 : *q(i,k-1,iqIsoPha(ixt,iq_vap))/q_follow(i,k-1, iq_vap)139 : +zx_defau_diag(i,k,1) 140 : *q(i,k-1,iqIsoPha(ixt,iq_vap))/q_follow(i,k-1,1) 137 141 138 142 ! et on la retranche en k-1 139 143 q(i,k-1,iqIsoPha(ixt,iq_vap))= 140 144 : q(i,k-1,iqIsoPha(ixt,iq_vap)) 141 : -zx_defau_diag(i,k, iq_vap)145 : -zx_defau_diag(i,k,1) 142 146 : *deltap(i,k)/deltap(i,k-1) 143 147 : *q(i,k-1,iqIsoPha(ixt,iq_vap)) 144 : /q_follow(i,k-1, iq_vap)148 : /q_follow(i,k-1,1) 145 149 146 150 enddo !do ixt=1,niso 147 q_follow(i,k, iq_vap)= q_follow(i,k,iq_vap)148 : +zx_defau_diag(i,k, iq_vap)149 q_follow(i,k-1, iq_vap)= q_follow(i,k-1,iq_vap)150 : -zx_defau_diag(i,k, iq_vap)151 q_follow(i,k,1)= q_follow(i,k,1) 152 : +zx_defau_diag(i,k,1) 153 q_follow(i,k-1,1)= q_follow(i,k-1,1) 154 : -zx_defau_diag(i,k,1) 151 155 : *deltap(i,k)/deltap(i,k-1) 152 endif !if (zx_defau_diag(i,k, iq_vap).gt.0.0) then156 endif !if (zx_defau_diag(i,k,1).gt.0.0) then 153 157 enddo !DO i = 1, ip1jmp1 154 158 enddo !do k=2,llm … … 161 165 do k=1,llm 162 166 DO i = 1,ip1jmp1 163 if (zx_defau_diag(i,k, iq_liq).gt.0.0) then167 if (zx_defau_diag(i,k,2).gt.0.0) then 164 168 165 169 ! on ajoute eau liquide en k en k 166 170 do ixt=1,ntiso 167 171 q(i,k,iqIsoPha(ixt,iq_liq))=q(i,k,iqIsoPha(ixt,iq_liq)) 168 : +zx_defau_diag(i,k, iq_liq)169 : *q(i,k,iqIsoPha(ixt,iq_vap))/q_follow(i,k, iq_vap)172 : +zx_defau_diag(i,k,2) 173 : *q(i,k,iqIsoPha(ixt,iq_vap))/q_follow(i,k,1) 170 174 ! et on la retranche à la vapeur en k 171 175 q(i,k,iqIsoPha(ixt,iq_vap))=q(i,k,iqIsoPha(ixt,iq_vap)) 172 : -zx_defau_diag(i,k, iq_liq)173 : *q(i,k,iqIsoPha(ixt,iq_vap))/q_follow(i,k, iq_vap)176 : -zx_defau_diag(i,k,2) 177 : *q(i,k,iqIsoPha(ixt,iq_vap))/q_follow(i,k,1) 174 178 enddo !do ixt=1,niso 175 q_follow(i,k, iq_liq)= q_follow(i,k,iq_liq)176 : +zx_defau_diag(i,k, iq_liq)177 q_follow(i,k, iq_vap)= q_follow(i,k,iq_vap)178 : -zx_defau_diag(i,k, iq_liq)179 endif !if (zx_defau_diag(i,k, iq_vap).gt.0.0) then179 q_follow(i,k,2)= q_follow(i,k,2) 180 : +zx_defau_diag(i,k,2) 181 q_follow(i,k,1)= q_follow(i,k,1) 182 : -zx_defau_diag(i,k,2) 183 endif !if (zx_defau_diag(i,k,1).gt.0.0) then 180 184 enddo !DO i = 1, ip1jmp1 181 185 enddo !do k=2,llm -
LMDZ6/branches/cirrus/libf/dyn3d/vlspltqs.F
r4470 r5202 25 25 26 26 USE comconst_mod, ONLY: cpp 27 27 USE logic_mod, ONLY: adv_qsat_liq 28 28 IMPLICIT NONE 29 29 c … … 92 92 ENDDO 93 93 DO ij = 1, ip1jmp1 94 zdelta = MAX( 0., SIGN(1., rtt - tempe(ij)) ) 94 IF (adv_qsat_liq) THEN 95 zdelta = 0. 96 ELSE 97 zdelta = MAX( 0., SIGN(1., rtt - tempe(ij)) ) 98 ENDIF 95 99 play = 0.5*(p(ij,l)+p(ij,l+1)) 96 100 qsat(ij,l) = MIN(0.5, r2es* FOEEW(tempe(ij),zdelta) / play ) -
LMDZ6/branches/cirrus/libf/dyn3d_common/infotrac.F90
r4638 r5202 5 5 USE strings_mod, ONLY: msg, fmsg, maxlen, cat, dispTable, int2str, bool2str, strStack, strParse 6 6 USE readTracFiles_mod, ONLY: trac_type, readTracersFiles, tracers, setGeneration, itZonIso, nzone, tran0, isoZone, & 7 delPhase, niso, getKey, isot_type, readIsotopesFile,isotope, maxTableWidth, iqIsoPha, nphas, ixIso, isoPhas, &8 addPhase, iH2O, addKey, isoSelect, testTracersFiles, isoKeys, indexUpdate, isoCheck, nbIso, ntiso, isoName7 delPhase, niso, getKey, isot_type, processIsotopes, isotope, maxTableWidth, iqIsoPha, nphas, ixIso, isoPhas, & 8 addPhase, iH2O, addKey, isoSelect, testTracersFiles, isoKeys, indexUpdate, iqWIsoPha, nbIso, ntiso, isoName, isoCheck 9 9 IMPLICIT NONE 10 10 … … 36 36 ! |--------------------+-----------------------+-----------------+---------------+----------------------------| 37 37 ! | water in different | water tagging | water isotopes | other tracers | additional tracers moments | 38 ! | phases: H2O_[gls b]| isotopes | | | for higher order schemes |38 ! | phases: H2O_[gls] | isotopes | | | for higher order schemes | 39 39 ! |--------------------+-----------------------+-----------------+---------------+----------------------------| 40 40 ! | | | | | | … … 65 65 ! | longName | Long name (with adv. scheme suffix) for outputs | ttext | | 66 66 ! | type | Type (so far: tracer or tag) | / | tracer,tag | 67 ! | phase | Phases list ("g"as / "l"iquid / "s"olid / "b"lowing) | / | [g][l][s][b]|67 ! | phase | Phases list ("g"as / "l"iquid / "s"olid) | / | [g][l][s] | 68 68 ! | component | Name(s) of the merged/cumulated section(s) | / | coma-separated names | 69 69 ! | iGeneration | Generation (>=1) | / | | … … 91 91 ! | trac | ntiso | Isotopes + tagging tracers list + number | / | ntraciso | | 92 92 ! | zone | nzone | Geographic tagging zones list + number | / | ntraceurs_zone | | 93 ! | phase | nphas | Phases list + number | | [g][l][s][b],1:4|93 ! | phase | nphas | Phases list + number | | [g][l][s], 1:3 | 94 94 ! | iqIsoPha | Index in "qx" = f(name(1:ntiso)),phas) | iqiso | 1:nqtot | 95 95 ! | itZonIso | Index in "trac(1:ntiso)"= f(zone, name(1:niso)) | index_trac | 1:ntiso | … … 156 156 INTEGER :: nqtrue !--- Tracers nb from tracer.def (no higher order moments) 157 157 INTEGER :: iad !--- Advection scheme number 158 INTEGER :: i c, iq, jq, it, nt, im, nm, iz, k!--- Indexes and temporary variables158 INTEGER :: iq, jq, nt, im, nm !--- Indexes and temporary variables 159 159 LOGICAL :: lerr, ll 160 CHARACTER(LEN=1) :: p161 160 TYPE(trac_type), ALLOCATABLE, TARGET :: ttr(:) 162 161 TYPE(trac_type), POINTER :: t1, t(:) 163 INTEGER :: ierr164 162 CHARACTER(LEN=maxlen), ALLOCATABLE :: types_trac(:) !--- Keyword for tracers type(s), parsed version 165 163 … … 225 223 ttp = type_trac; IF(fType /= 1) ttp = texp 226 224 227 IF(readTracersFiles(ttp, type_trac == 'repr'))CALL abort_gcm(modname, 'problem with tracers file(s)',1)225 IF(readTracersFiles(ttp, lRepr=type_trac=='repr')) CALL abort_gcm(modname, 'problem with tracers file(s)',1) 228 226 !--------------------------------------------------------------------------------------------------------------------------- 229 227 IF(fType == 0) CALL abort_gcm(modname, 'Missing tracers file: "traceur.def", "tracer.def" or "tracer_<keyword>.def file.',1) … … 236 234 nbtr = nqINCA + nqCO2 !--- Number of tracers passed to phytrac 237 235 nqtrue = nbtr + nqo !--- Total number of "true" tracers 238 IF(ALL([2,3 ,4,5] /= nqo)) CALL abort_gcm(modname, 'Only 2, 3, 4 , 5water phases allowed ; found nqo='//TRIM(int2str(nqo)), 1)236 IF(ALL([2,3] /= nqo)) CALL abort_gcm(modname, 'Only 2 or 3 water phases allowed ; found nqo='//TRIM(int2str(nqo)), 1) 239 237 ALLOCATE(hadv(nqtrue), hadv_inca(nqINCA), conv_flg_inca(nqINCA), solsym_inca(nqINCA)) 240 238 ALLOCATE(vadv(nqtrue), vadv_inca(nqINCA), pbl_flg_inca(nqINCA)) … … 245 243 ttr(1+nqo:nqCO2+nqo )%component = 'co2i' 246 244 ttr(1+nqo+nqCO2:nqtrue)%component = 'inca' 247 ttr(1+nqo :nqtrue)%name = [('CO2 ', k=1, nqCO2), solsym_inca]245 ttr(1+nqo :nqtrue)%name = [('CO2 ', iq=1, nqCO2), solsym_inca] 248 246 ttr(1+nqo+nqCO2:nqtrue)%parent = tran0 249 247 ttr(1+nqo+nqCO2:nqtrue)%phase = 'g' … … 348 346 IF(nm == 0) CYCLE !--- No higher moments 349 347 ttr(jq+1:jq+nm) = t1 350 ttr(jq+1:jq+nm)%name = [ (TRIM(t1%name) //'-'//TRIM(suff(im)), im=1, nm) ]351 ttr(jq+1:jq+nm)%parent = [ (TRIM(t1%parent) //'-'//TRIM(suff(im)), im=1, nm) ]352 ttr(jq+1:jq+nm)%longName = [ (TRIM(t1%longName)//'-'//TRIM(suff(im)), im=1, nm) ]353 ttr(jq+1:jq+nm)%iadv = [ (-iad, im=1, nm) ]354 ttr(jq+1:jq+nm)%isAdvected = [ (.FALSE., im=1, nm) ]348 ttr(jq+1:jq+nm)%name = [ (TRIM(t1%name) //'-'//TRIM(suff(im)), im=1, nm) ] 349 ttr(jq+1:jq+nm)%parent = [ (TRIM(t1%parent) //'-'//TRIM(suff(im)), im=1, nm) ] 350 ttr(jq+1:jq+nm)%longName = [ (TRIM(t1%longName)//'-'//TRIM(suff(im)), im=1, nm) ] 351 ttr(jq+1:jq+nm)%iadv = [ (-iad, im=1, nm) ] 352 ttr(jq+1:jq+nm)%isAdvected = [ (.FALSE., im=1, nm) ] 355 353 jq = jq + nm 356 354 END DO … … 359 357 360 358 !--- SET FIELDS %iqParent, %nqChildren, %iGeneration, %iqDescen, %nqDescen 361 CALL indexUpdate(tracers)359 IF(indexUpdate(tracers)) CALL abort_gcm(modname, 'problem with tracers indices update', 1) 362 360 363 361 !=== TEST ADVECTION SCHEME … … 384 382 !=== READ PHYSICAL PARAMETERS FOR ISOTOPES ; DONE HERE BECAUSE dynetat0 AND iniacademic NEED "tnat" AND "alpha_ideal" 385 383 niso = 0; nzone = 0; nphas = nqo; ntiso = 0; isoCheck = .FALSE. 386 IF( readIsotopesFile()) CALL abort_gcm(modname, 'Problem when reading isotopes parameters', 1)384 IF(processIsotopes()) CALL abort_gcm(modname, 'problem when processing isotopes parameters', 1) 387 385 388 386 !--- Convection / boundary layer activation for all tracers … … 393 391 nqtottr = nqtot - COUNT(delPhase(tracers%gen0Name) == 'H2O' .AND. tracers%component == 'lmdz') 394 392 IF(COUNT(tracers%iso_iName == 0) - COUNT(delPhase(tracers%name) == 'H2O' .AND. tracers%component == 'lmdz') /= nqtottr) & 395 CALL abort_gcm(modname, 'p b dans le calcul denqtottr', 1)393 CALL abort_gcm(modname, 'problem with the computation of nqtottr', 1) 396 394 397 395 !=== DISPLAY THE RESULTS … … 408 406 t => tracers 409 407 CALL msg('Information stored in infotrac :', modname) 410 IF(dispTable('isssssssssiiiiiiiii', & 411 ['iq ', 'name ', 'lName ', 'gen0N ', 'parent', 'type ', 'phase ', 'compon', 'isPhy ', 'isAdv ',&412 'iadv ', 'iGen ', 'iqPar ', 'nqDes ', 'nqChld', 'iGroup', 'iName ', 'iZone ', 'iPhase'],&408 409 IF(dispTable('isssssssssiiiiiiiii', ['iq ', 'name', 'lNam', 'g0Nm', 'prnt', 'type', 'phas', 'comp', & 410 'isPh', 'isAd', 'iadv', 'iGen', 'iqPr', 'nqDe', 'nqCh', 'iGrp', 'iNam', 'iZon', 'iPha'], & 413 411 cat(t%name, t%longName, t%gen0Name, t%parent, t%type, t%phase, t%component, bool2str(t%isInPhysics), & 414 412 bool2str(t%isAdvected)), & -
LMDZ6/branches/cirrus/libf/dyn3dmem/check_isotopes_loc.F90
r4399 r5202 24 24 iso_O17, iso_HTO 25 25 LOGICAL, SAVE :: first=.TRUE. 26 LOGICAL, PARAMETER :: tnat1=.TRUE. 26 27 !$OMP THREADPRIVATE(first) 27 28 … … 37 38 iso_O17 = strIdx(isoName,'H217O') 38 39 iso_HTO = strIdx(isoName,'HTO') 39 IF(getKey('tnat', tnat)) CALL abort_gcm(modname, 'missing isotopic parameter', 1) 40 if (tnat1) then 41 tnat(:)=1.0 42 else 43 IF(getKey('tnat', tnat)) CALL abort_gcm(modname, 'missing isotopic parameter', 1) 44 endif 40 45 !$OMP END MASTER 41 46 !$OMP BARRIER -
LMDZ6/branches/cirrus/libf/dyn3dmem/conf_gcm.F90
r4608 r5202 22 22 USE logic_mod, ONLY: fxyhypb, iflag_phys, ok_etat0, ok_gradsfile, & 23 23 ok_guide, ok_limit, ok_strato, purmats, read_start, & 24 ysinus, read_orop 24 ysinus, read_orop, adv_qsat_liq 25 25 USE serre_mod, ONLY: clon,clat,grossismx,grossismy,dzoomx,dzoomy, & 26 26 alphax,alphay,taux,tauy … … 660 660 type_trac = 'lmdz' 661 661 CALL getin('type_trac',type_trac) 662 663 664 !Config Key = adv_qsat_liq 665 !Config Desc = option for qsat calculation in the dynamics 666 !Config Def = n 667 !Config Help = controls which phase is considered for qsat calculation 668 !Config 669 adv_qsat_liq = .FALSE. 670 CALL getin('adv_qsat_liq',adv_qsat_liq) 662 671 663 672 !Config Key = ok_dynzon … … 736 745 write(lunout,*)' ok_dyn_ave = ', ok_dyn_ave 737 746 write(lunout,*)' ok_dyn_xios = ', ok_dyn_xios 747 write(lunout,*)' adv_qsat_liq = ', adv_qsat_liq 738 748 else 739 749 !Config Key = clon -
LMDZ6/branches/cirrus/libf/dyn3dmem/dynetat0_loc.F90
r4490 r5202 42 42 INTEGER, PARAMETER :: length=100 43 43 INTEGER :: iq, fID, vID, idecal, ierr, iqParent, iName, iZone, iPhase, ix 44 REAL :: time, tnat, alpha_ideal, tab_cntrl(length) !--- RUN PARAMS TABLE 44 REAL :: time,tab_cntrl(length) !--- RUN PARAMS TABLE 45 REAL :: tnat, alpha_ideal 45 46 REAL, ALLOCATABLE :: vcov_glo(:,:),masse_glo(:,:), ps_glo(:) 46 47 REAL, ALLOCATABLE :: ucov_glo(:,:), q_glo(:,:), phis_glo(:) 47 48 REAL, ALLOCATABLE :: teta_glo(:,:) 48 49 LOGICAL :: lSkip, ll 50 LOGICAL,PARAMETER :: tnat1=.TRUE. 49 51 !------------------------------------------------------------------------------- 50 52 modname="dynetat0_loc" … … 179 181 iqParent = tracers(iq)%iqParent 180 182 IF(tracers(iq)%iso_iZone == 0) THEN 181 IF(getKey('tnat', tnat, isoName(iName)) .OR. getKey('alpha', alpha_ideal, isoName(iName))) & 183 if (tnat1) then 184 tnat=1.0 185 alpha_ideal=1.0 186 write(*,*) 'attention dans dynetat0: les alpha_ideal sont a 1' 187 else 188 IF(getKey('tnat', tnat, isoName(iName)) .OR. getKey('alpha', alpha_ideal, isoName(iName))) & 182 189 CALL abort_gcm(TRIM(modname), 'missing isotopic parameters', 1) 190 endif 183 191 CALL msg('Tracer <'//TRIM(var)//'> is missing => initialized with a simplified Rayleigh distillation law.', modname) 184 192 q(ijb_u:ije_u,:,iq) = q(ijb_u:ije_u,:,iqParent)*tnat*(q(ijb_u:ije_u,:,iqParent)/30.e-3)**(alpha_ideal-1.) … … 193 201 ! remplacant 1 par izone_init dans la ligne qui suit. 194 202 IF(tracers(iq)%iso_iZone == 1) THEN 195 q(ijb_u:ije_u,:,iq) = q(ijb_u:ije_u,:,iqIsoPha(iName,iPhase))203 q(ijb_u:ije_u,:,iq) = q(ijb_u:ije_u,:,iqIsoPha(iName,iPhase)) 196 204 ELSE 197 205 q(ijb_u:ije_u,:,iq) = 0. -
LMDZ6/branches/cirrus/libf/dyn3dmem/dynredem_mod.F90
r2299 r5202 7 7 PRIVATE 8 8 PUBLIC :: dynredem_write_u, dynredem_write_v, dynredem_read_u, err 9 PUBLIC :: cre_var, get_var1,put_var, fil, modname, msg9 PUBLIC :: cre_var, put_var, fil, modname, msg 10 10 CHARACTER(LEN=256), SAVE :: fil, modname 11 11 INTEGER, SAVE :: nvarid -
LMDZ6/branches/cirrus/libf/dyn3dmem/gcm.F90
r4619 r5202 480 480 !$OMP COPYIN(saison,ecripar,fxyhypb,ysinus,read_start,ok_guide) & 481 481 !$OMP COPYIN(ok_strato,ok_gradsfile,ok_limit,ok_etat0) & 482 !$OMP COPYIN(iflag_phys,iflag_trac )482 !$OMP COPYIN(iflag_phys,iflag_trac,adv_qsat_liq) 483 483 CALL leapfrog_loc(ucov,vcov,teta,ps,masse,phis,q,time_0) 484 484 !$OMP END PARALLEL -
LMDZ6/branches/cirrus/libf/dyn3dmem/iniacademic_loc.F90
r4419 r5202 85 85 86 86 REAL zdtvr, tnat, alpha_ideal 87 LOGICAL,PARAMETER :: tnat1=.true. 87 88 88 89 character(len=*),parameter :: modname="iniacademic" … … 323 324 iqParent = tracers(iq)%iqParent 324 325 IF(tracers(iq)%iso_iZone == 0) THEN 325 IF(getKey('tnat', tnat, isoName(iName)) .OR. getKey('alpha', alpha_ideal, isoName(iName))) & 326 if (tnat1) then 327 tnat=1.0 328 alpha_ideal=1.0 329 write(*,*) 'Attention dans iniacademic: alpha_ideal=1' 330 else 331 IF(getKey('tnat', tnat, isoName(iName)) .OR. getKey('alpha', alpha_ideal, isoName(iName))) & 326 332 CALL abort_gcm(TRIM(modname), 'missing isotopic parameters', 1) 333 endif 327 334 q(ijb_u:ije_u,:,iq) = q(ijb_u:ije_u,:,iqParent)*tnat*(q(ijb_u:ije_u,:,iqParent)/30.e-3)**(alpha_ideal-1.) 328 ELSE 329 q(ijb_u:ije_u,:,iq) = q(ijb_u:ije_u,:,iqIsoPha(iName,iPhase)) 330 END IF 335 ELSE !IF(tracers(iq)%iso_iZone == 0) THEN 336 IF(tracers(iq)%iso_iZone == 1) THEN ! a verifier. 337 ! correction le 14 mai 2024 pour que tous les traceurs soient de la couleur 1. 338 ! Sinon, on va avoir des porblèmes de conservation de masse de traceurs. 339 q(ijb_u:ije_u,:,iq) = q(ijb_u:ije_u,:,iqIsoPha(iName,iPhase)) 340 else !IF(tracers(iq)%iso_iZone == 1) THEN 341 q(ijb_u:ije_u,:,iq) = 0.0 342 endif !IF(tracers(iq)%iso_iZone == 1) THEN 343 END IF !IF(tracers(iq)%iso_iZone == 0) THEN 331 344 enddo 332 345 else -
LMDZ6/branches/cirrus/libf/dyn3dmem/logic_mod.F90
r2665 r5202 30 30 LOGICAL hybrid ! vertical coordinate is hybrid if true (sigma otherwise) 31 31 ! (only used if disvert_type==2) 32 LOGICAL adv_qsat_liq ! true if qsat is calculated alwats wrt liquid for 33 ! adapted Van Leer advection scheme 32 34 INTEGER iflag_phys ! type of physics to call: 0 none, 1: phy*** package, 33 35 ! 2: Held & Suarez, 101-200: aquaplanets & terraplanets … … 37 39 !$OMP apdiss,apdelq,saison,ecripar,fxyhypb,ysinus, & 38 40 !$OMP read_start,ok_guide,ok_strato,ok_gradsfile, & 39 !$OMP ok_limit,ok_etat0,hybrid )41 !$OMP ok_limit,ok_etat0,hybrid, adv_qsat_liq) 40 42 !$OMP THREADPRIVATE(iflag_phys,iflag_trac) 41 43 -
LMDZ6/branches/cirrus/libf/dyn3dmem/qminimum_loc.F
r4469 r5202 31 31 c ................................................................. 32 32 c 33 cDC iq_val and iq_liq are usable for q only, NOT for q_follow 34 c and zx_defau_diag (crash if iq_val/liq==3) => vapor/liquid 35 c water at hardcoded indices 1/2 in these variables 33 36 INTEGER i, k, iq 34 37 REAL zx_defau, zx_abc, zx_pump(ijb_u:ije_u), pompe … … 49 52 INTEGER ixt 50 53 INTEGER iso_verif_noNaN_nostop 51 c52 c Quand l'eau liquide est trop petite (ou negative), on prend53 c l'eau vapeur de la meme couche et la convertit en eau liquide54 c (sans changer la temperature !)55 c56 54 57 55 c$OMP BARRIER … … 63 61 first = .FALSE. 64 62 END IF 63 c 64 c Quand l'eau liquide est trop petite (ou negative), on prend 65 c l'eau vapeur de la meme couche et la convertit en eau liquide 66 c (sans changer la temperature !) 67 c 68 65 69 call check_isotopes(q,ij_begin,ij_end,'qminimum 52') 66 70 … … 73 77 zx_defau_diag(i,k,1)=0.0 74 78 zx_defau_diag(i,k,2)=0.0 75 q_follow(i,k,1)=q(i,k, 1)76 q_follow(i,k,2)=q(i,k, 2)79 q_follow(i,k,1)=q(i,k,iq_vap) 80 q_follow(i,k,2)=q(i,k,iq_liq) 77 81 ENDDO 78 82 c$OMP END DO NOWAIT … … 80 84 81 85 !write(lunout,*) 'qminimum 57' 82 DO 1000k = 1, llm86 DO k = 1, llm 83 87 c$OMP DO SCHEDULE(STATIC) 84 DO 1040i = ijb, ije85 86 87 if (niso > 0) zx_defau_diag(i,k,iq_liq)=AMAX188 DO i = ijb, ije 89 if (seuil_liq - q(i,k,iq_liq) .gt. 0.d0 ) then 90 91 if (niso > 0) zx_defau_diag(i,k,2)=AMAX1 88 92 : ( seuil_liq - q(i,k,iq_liq), 0.0 ) 89 93 90 91 92 93 1040 CONTINUE94 c$OMP END DO NOWAIT 95 1000 CONTINUE94 q(i,k,iq_vap) = q(i,k,iq_vap) + q(i,k,iq_liq) - seuil_liq 95 q(i,k,iq_liq) = seuil_liq 96 endif 97 END DO 98 c$OMP END DO NOWAIT 99 END DO 96 100 97 101 c … … 100 104 c 101 105 !write(lunout,*) 'qminimum 81' 102 iq = iq_vap103 c104 106 DO k = llm, 2, -1 105 107 ccc zx_abc = dpres(k) / dpres(k-1) 106 108 c$OMP DO SCHEDULE(STATIC) 107 DO i = ijb, ije108 109 if ( seuil_vap - q(i,k,iq) .gt. 0.d0 ) then110 111 if (niso > 0) 112 & zx_defau_diag(i,k,iq)=AMAX1( seuil_vap - q(i,k,iq), 0.0 )113 114 q(i,k-1,iq ) = q(i,k-1,iq) - ( seuil_vap - q(i,k,iq) ) *115 & deltap(i,k) /deltap(i,k-1)116 q(i,k,iq ) = seuil_vap117 118 endif119 ENDDO109 DO i = ijb, ije 110 111 if ( seuil_vap - q(i,k,iq_vap) .gt. 0.d0 ) then 112 113 if (niso > 0) zx_defau_diag(i,k,1) 114 & = AMAX1( seuil_vap - q(i,k,iq_vap), 0.0 ) 115 116 q(i,k-1,iq_vap) = q(i,k-1,iq_vap) - (seuil_vap 117 & -q(i,k,iq_vap)) * deltap(i,k)/deltap(i,k-1) 118 q(i,k,iq_vap) = seuil_vap 119 120 endif 121 ENDDO 120 122 c$OMP END DO NOWAIT 121 123 ENDDO … … 129 131 c$OMP DO SCHEDULE(STATIC) 130 132 DO i = ijb, ije 131 zx_pump(i) = AMAX1( 0.0, seuil_vap - q(i,1,iq ) )132 q(i,1,iq ) = AMAX1( q(i,1,iq), seuil_vap )133 zx_pump(i) = AMAX1( 0.0, seuil_vap - q(i,1,iq_vap) ) 134 q(i,1,iq_vap) = AMAX1( q(i,1,iq_vap), seuil_vap ) 133 135 IF (zx_pump(i) > 0.0) THEN 134 136 nb_pump = nb_pump+1 … … 165 167 DO i = ijb, ije 166 168 if (zx_pump(i).gt.0.0) then 167 q_follow(i,1, iq_vap)=q_follow(i,1,iq_vap)+zx_pump(i)169 q_follow(i,1,1)=q_follow(i,1,1)+zx_pump(i) 168 170 endif !if (zx_pump(i).gt.0.0) then 169 171 enddo !DO i = ijb, ije … … 175 177 c$OMP DO SCHEDULE(STATIC) 176 178 DO i = ijb, ije 177 if (zx_defau_diag(i,k, iq_vap).gt.0.0) then179 if (zx_defau_diag(i,k,1).gt.0.0) then 178 180 ! on ajoute la vapeur en k 179 ! write(lunout,*) 'i,k,q_follow(i,k-1,i q_vap)=',180 ! : i,k,q_follow(i,k-1, iq_vap)181 if (q_follow(i,k-1, iq_vap).lt.min_qParent) then181 ! write(lunout,*) 'i,k,q_follow(i,k-1,ivap)=', 182 ! : i,k,q_follow(i,k-1,1) 183 if (q_follow(i,k-1,1).lt.min_qParent) then 182 184 write(lunout,*) 'tmp qmin: on stoppe' 183 185 write(lunout,*) 'zx_pump(i)=',zx_pump(i) 184 write(lunout,*) 'q_follow(i,:,i q_vap)=',185 : q_follow(i,:, iq_vap)186 write(lunout,*) 'q_follow(i,:,ivap)=', 187 : q_follow(i,:,1) 186 188 write(lunout,*) 'k=',k 187 189 call abort_gcm("qminimum","not enough vapor",1) … … 189 191 do ixt=1,ntiso 190 192 ! write(lunout,*) 'qmin 168: ixt=',ixt 191 ! write(lunout,*) 'q(i,k,iqIsoPha(ixt,iq_vap) =',193 ! write(lunout,*) 'q(i,k,iqIsoPha(ixt,iq_vap))=', 192 194 ! : q(i,k,iqIsoPha(ixt,iq_vap)) 193 ! write(lunout,*) 'zx_defau_diag(i,k,i q_vap)=',194 ! : zx_defau_diag(i,k, iq_vap)195 ! write(lunout,*) 'q(i,k-1,iqIsoPha(ixt,iq_vap) =',195 ! write(lunout,*) 'zx_defau_diag(i,k,ivap)=', 196 ! : zx_defau_diag(i,k,1) 197 ! write(lunout,*) 'q(i,k-1,iqIsoPha(ixt,iq_vap))=', 196 198 ! : q(i,k-1,iqIsoPha(ixt,iq_vap)) 197 199 198 200 q(i,k,iqIsoPha(ixt,iq_vap))=q(i,k,iqIsoPha(ixt,iq_vap)) 199 : +zx_defau_diag(i,k, iq_vap)200 : *q(i,k-1,iqIsoPha(ixt,iq_vap))/q_follow(i,k-1, iq_vap)201 : +zx_defau_diag(i,k,1) 202 : *q(i,k-1,iqIsoPha(ixt,iq_vap))/q_follow(i,k-1,1) 201 203 202 204 if (isoCheck) then … … 204 206 : 'qminimum 155').eq.1) then 205 207 write(*,*) 'i,k,ixt=',i,k,ixt 206 write(*,*) 'q_follow(i,k-1,i q_vap)=',207 : q_follow(i,k-1, iq_vap)208 write(*,*) 'q_follow(i,k-1,ivap)=', 209 : q_follow(i,k-1,1) 208 210 write(*,*) 'q(i,k,iqIsoPha(ixt,iq_vap))=', 209 211 : q(i,k,iqIsoPha(ixt,iq_vap)) 210 write(*,*) 'zx_defau_diag(i,k,i q_vap)=',211 : zx_defau_diag(i,k, iq_vap)212 write(*,*) 'zx_defau_diag(i,k,ivap)=', 213 : zx_defau_diag(i,k,1) 212 214 write(*,*) 'q(i,k-1,iqIsoPha(ixt,iq_vap))=', 213 215 : q(i,k-1,iqIsoPha(ixt,iq_vap)) … … 219 221 q(i,k-1,iqIsoPha(ixt,iq_vap)) = 220 222 : q(i,k-1,iqIsoPha(ixt,iq_vap)) 221 : -zx_defau_diag(i,k, iq_vap)223 : -zx_defau_diag(i,k,1) 222 224 : *deltap(i,k)/deltap(i,k-1) 223 225 : *q(i,k-1,iqIsoPha(ixt,iq_vap)) 224 : /q_follow(i,k-1, iq_vap)226 : /q_follow(i,k-1,1) 225 227 226 228 if (isoCheck) then … … 229 231 : 'qminimum 175').eq.1) then 230 232 write(*,*) 'k,i,ixt=',k,i,ixt 231 write(*,*) 'q_follow(i,k-1,i q_vap)=',232 : q_follow(i,k-1, iq_vap)233 write(*,*) 'q_follow(i,k-1,ivap)=', 234 : q_follow(i,k-1,1) 233 235 write(*,*) 'q(i,k,iqIsoPha(ixt,iq_vap))=', 234 236 : q(i,k,iqIsoPha(ixt,iq_vap)) 235 write(*,*) 'zx_defau_diag(i,k,i q_vap)=',236 : zx_defau_diag(i,k, iq_vap)237 write(*,*) 'zx_defau_diag(i,k,ivap)=', 238 : zx_defau_diag(i,k,1) 237 239 write(*,*) 'q(i,k-1,iqIsoPha(ixt,iq_vap))=', 238 240 : q(i,k-1,iqIsoPha(ixt,iq_vap)) … … 242 244 243 245 enddo !do ixt=1,niso 244 q_follow(i,k, iq_vap)= q_follow(i,k,iq_vap)245 : +zx_defau_diag(i,k, iq_vap)246 q_follow(i,k-1, iq_vap)= q_follow(i,k-1,iq_vap)247 : -zx_defau_diag(i,k, iq_vap)246 q_follow(i,k,1)= q_follow(i,k,1) 247 : +zx_defau_diag(i,k,1) 248 q_follow(i,k-1,1)= q_follow(i,k-1,1) 249 : -zx_defau_diag(i,k,1) 248 250 : *deltap(i,k)/deltap(i,k-1) 249 endif !if (zx_defau_diag(i,k, iq_vap).gt.0.0) then251 endif !if (zx_defau_diag(i,k,1).gt.0.0) then 250 252 enddo !DO i = 1, ip1jmp1 251 253 c$OMP END DO NOWAIT … … 260 262 c$OMP DO SCHEDULE(STATIC) 261 263 DO i = ijb, ije 262 if (zx_defau_diag(i,k, iq_liq).gt.0.0) then264 if (zx_defau_diag(i,k,2).gt.0.0) then 263 265 264 266 ! on ajoute eau liquide en k en k 265 267 do ixt=1,ntiso 266 268 q(i,k,iqIsoPha(ixt,iq_liq))=q(i,k,iqIsoPha(ixt,iq_liq)) 267 : +zx_defau_diag(i,k, iq_liq)268 : *q(i,k,iqIsoPha(ixt,iq_vap))/q_follow(i,k, iq_vap)269 : +zx_defau_diag(i,k,2) 270 : *q(i,k,iqIsoPha(ixt,iq_vap))/q_follow(i,k,1) 269 271 ! et on la retranche à la vapeur en k 270 272 q(i,k,iqIsoPha(ixt,iq_vap))=q(i,k,iqIsoPha(ixt,iq_vap)) 271 : -zx_defau_diag(i,k, iq_liq)272 : *q(i,k,iqIsoPha(ixt,iq_vap))/q_follow(i,k, iq_vap)273 : -zx_defau_diag(i,k,2) 274 : *q(i,k,iqIsoPha(ixt,iq_vap))/q_follow(i,k,1) 273 275 enddo !do ixt=1,niso 274 q_follow(i,k, iq_liq)= q_follow(i,k,iq_liq)275 : +zx_defau_diag(i,k, iq_liq)276 q_follow(i,k, iq_vap)= q_follow(i,k,iq_vap)277 : -zx_defau_diag(i,k, iq_liq)278 endif !if (zx_defau_diag(i,k, iq_vap).gt.0.0) then276 q_follow(i,k,2)= q_follow(i,k,2) 277 : +zx_defau_diag(i,k,2) 278 q_follow(i,k,1)= q_follow(i,k,1) 279 : -zx_defau_diag(i,k,2) 280 endif !if (zx_defau_diag(i,k,1).gt.0.0) then 279 281 enddo !DO i = ijb, ije 280 282 c$OMP END DO NOWAIT -
LMDZ6/branches/cirrus/libf/dyn3dmem/vlspltgen_loc.F
r4469 r5202 10 10 c 11 11 c ******************************************************************** 12 c S hema d'advection " pseudo amont " .12 c Schema d'advection " pseudo amont " . 13 13 c + test sur humidite specifique: Q advecte< Qsat aval 14 14 c (F. Codron, 10/99) … … 32 32 USE vlspltgen_mod 33 33 USE comconst_mod, ONLY: cpp 34 USE logic_mod, ONLY: adv_qsat_liq 34 35 IMPLICIT NONE 35 36 … … 108 109 ENDDO 109 110 DO ij = ijb, ije 110 zdelta = MAX( 0., SIGN(1., rtt - tempe(ij)) ) 111 IF (adv_qsat_liq) THEN 112 zdelta = 0. 113 ELSE 114 zdelta = MAX( 0., SIGN(1., rtt - tempe(ij)) ) 115 ENDIF 111 116 play = 0.5*(p(ij,l)+p(ij,l+1)) 112 117 qsat(ij,l) = MIN(0.5, r2es* FOEEW(tempe(ij),zdelta) / play ) -
LMDZ6/branches/cirrus/libf/dyn3dmem/vlspltqs_loc.F
r4469 r5202 806 806 IF (pole_sud) THEN 807 807 808 convps = -SSUM(iim,qbyv(ip1jm-iim,l,iq), iq,1)/apols808 convps = -SSUM(iim,qbyv(ip1jm-iim,l,iq),1)/apols 809 809 convmps = -SSUM(iim,masse_adv_v(ip1jm-iim,l),1)/apols 810 810 DO ij = ip1jm+1,ip1jmp1 -
LMDZ6/branches/cirrus/libf/misc/readTracFiles_mod.f90
r4951 r5202 1 1 MODULE readTracFiles_mod 2 2 3 USE strings_mod, ONLY: msg, find, get_in, str2int, dispTable, strHead, strReduce, strFind, strStack, strIdx, & 4 test, removeComment, cat, fmsg, maxlen, int2str, checkList, strParse, strReplace, strTail, strCount, reduceExpr 3 USE strings_mod, ONLY: msg, find, get_in, dispTable, strHead, strReduce, strFind, strStack, strIdx, & 4 removeComment, cat, fmsg, maxlen, checkList, strParse, strReplace, strTail, strCount, reduceExpr, & 5 int2str, str2int, real2str, str2real, bool2str, str2bool 5 6 6 7 IMPLICIT NONE … … 9 10 10 11 PUBLIC :: maxlen !--- PARAMETER FOR CASUAL STRING LENGTH 11 PUBLIC :: tracers !--- TRACERS DESCRIPTION DATABASE 12 PUBLIC :: trac_type, setGeneration, indexUpdate !--- TRACERS DESCRIPTION ASSOCIATED TOOLS 12 PUBLIC :: trac_type, tracers, setGeneration, indexUpdate !--- TRACERS DESCRIPTION DATABASE + ASSOCIATED TOOLS 13 13 PUBLIC :: testTracersFiles, readTracersFiles !--- TRACERS FILES READING ROUTINES 14 PUBLIC :: getKey , fGetKey, fGetKeys, addKey, setDirectKeys !--- TOOLS TO GET/SET KEYS FROM/TO tracers & isotopes15 PUBLIC :: getKeysDBase, setKeysDBase !--- TOOLS TO GET/SET THE DATABASE (tracers & isotopes)16 17 PUBLIC :: addPhase, getiPhase, old_phases, phases_sep, &!--- FUNCTIONS RELATED TO THE PHASES18 nphases, delPhase, getPhase, known_phases, phases_names!--- + ASSOCIATED VARIABLES14 PUBLIC :: getKeysDBase, setKeysDBase !--- TOOLS TO GET/SET THE DATABASE (tracers & isotopes) 15 PUBLIC :: addTracer, delTracer !--- ADD/REMOVE A TRACER FROM 16 PUBLIC :: addKey, delKey, getKey, keys_type !--- TOOLS TO SET/DEL/GET KEYS FROM/TO tracers & isotopes 17 PUBLIC :: addPhase, delPhase, getPhase, getiPhase, & !--- FUNCTIONS RELATED TO THE PHASES 18 nphases, old_phases, phases_sep, known_phases, phases_names !--- + ASSOCIATED VARIABLES 19 19 20 20 PUBLIC :: oldH2OIso, newH2OIso, old2newH2O, new2oldH2O !--- H2O ISOTOPES BACKWARD COMPATIBILITY (OLD traceur.def) 21 21 PUBLIC :: oldHNO3, newHNO3 !--- HNO3 REPRO BACKWARD COMPATIBILITY (OLD start.nc) 22 22 23 PUBLIC :: tran0 , idxAncestor, ancestor !--- GENERATION 0 TRACER + TOOLS FOR GENERATIONS23 PUBLIC :: tran0 !--- TRANSPORTING FLUID (USUALLY air) 24 24 25 25 !=== FOR ISOTOPES: GENERAL 26 PUBLIC :: isot_type, readIsotopesFile, isoSelect !--- ISOTOPES DESCRIPTION TYPE + READING ROUTINE 27 PUBLIC :: ixIso, nbIso !--- INDEX OF SELECTED ISOTOPES CLASS + NUMBER OF CLASSES 26 PUBLIC :: isot_type, processIsotopes, isoSelect, ixIso, nbIso !--- PROCESS [AND READ] & SELECT ISOTOPES + CLASS IDX & NUMBER 28 27 29 28 !=== FOR ISOTOPES: H2O FAMILY ONLY … … 36 35 PUBLIC :: itZonIso !--- Idx IN isoName(1:niso) = f(tagging idx, isotope idx) 37 36 PUBLIC :: iqIsoPha !--- Idx IN qx(1:nqtot) = f(isotope idx, phase idx) 37 PUBLIC :: iqWIsoPha !--- Idx IN qx(1:nqtot) = f(isotope idx, phase idx) but with normal water first 38 38 PUBLIC :: isoCheck !--- FLAG TO RUN ISOTOPES CHECKING ROUTINES 39 39 40 40 PUBLIC :: maxTableWidth 41 41 !------------------------------------------------------------------------------------------------------------------------------ 42 TYPE :: keys_type !=== TYPE FOR A SET OF KEYS ASSOCIATED TO AN ELEMENT43 CHARACTER(LEN=maxlen) :: name !--- Tracer name44 CHARACTER(LEN=maxlen), ALLOCATABLE :: key(:) !--- Keys string list45 CHARACTER(LEN=maxlen), ALLOCATABLE :: val(:) !--- Corresponding values string list42 TYPE :: keys_type !=== TYPE FOR A SET OF KEYS ASSOCIATED TO AN ELEMENT 43 CHARACTER(LEN=maxlen) :: name !--- Tracer name 44 CHARACTER(LEN=maxlen), ALLOCATABLE :: key(:) !--- Keys string list 45 CHARACTER(LEN=maxlen), ALLOCATABLE :: val(:) !--- Corresponding values string list 46 46 END TYPE keys_type 47 47 !------------------------------------------------------------------------------------------------------------------------------ 48 TYPE :: trac_type !=== TYPE FOR A SINGLE TRACER NAMED "name"49 CHARACTER(LEN=maxlen) :: name = '' !--- Name of the tracer50 CHARACTER(LEN=maxlen) :: gen0Name = '' !--- First generation ancestor name51 CHARACTER(LEN=maxlen) :: parent = '' !--- Parentname52 CHARACTER(LEN=maxlen) :: longName = '' !--- Long name (with advection scheme suffix)53 CHARACTER(LEN=maxlen) :: type = 'tracer' !--- Type (so far: 'tracer' / 'tag')54 CHARACTER(LEN=maxlen) :: phase = 'g' !--- Phase ('g'as / 'l'iquid / 's'olid)55 CHARACTER(LEN=maxlen) :: component = '' !--- Coma-separated list of components (Ex: lmdz,inca)56 INTEGER :: iGeneration = -1 !--- Generation number (>=0)57 INTEGER :: i qParent = 0 !--- Parent index58 INTEGER , ALLOCATABLE :: iqDescen(:) !--- Descendants index (in growing generation order)59 INTEGER :: nqDescen = 0 !--- Number of descendants (all generations)60 INTEGER :: nq Children = 0 !--- Number of children (first generation)61 TYPE(keys_type) :: keys !--- <key>=<val> pairs vector62 INTEGER :: iadv = 10 !--- Advection scheme used63 LOGICAL :: isAdvected = .FALSE. !--- "true" tracers: iadv > 0. COUNT(isAdvected )=nqtrue64 LOGICAL :: isInPhysics = .TRUE. !--- "true" tracers: in tr_seri. COUNT(isInPhysics)=nqtottr65 INTEGER :: iso_iGroup = 0 !--- Isotopes group index in isotopes(:)66 INTEGER :: iso_iName = 0 !--- Isotope name index in isotopes(iso_iGroup)%trac(:)67 INTEGER :: iso_iZone = 0 !--- Isotope zone index in isotopes(iso_iGroup)%zone(:)68 INTEGER :: iso_iPhase = 0 !--- Isotope phase index in isotopes(iso_iGroup)%phase48 TYPE :: trac_type !=== TYPE FOR A SINGLE TRACER NAMED "name" 49 CHARACTER(LEN=maxlen) :: name = '' !--- Name of the tracer 50 TYPE(keys_type) :: keys !--- <key>=<val> pairs vector 51 CHARACTER(LEN=maxlen) :: gen0Name = '' !--- First generation ancestor name 52 CHARACTER(LEN=maxlen) :: parent = '' !--- Parent name 53 CHARACTER(LEN=maxlen) :: longName = '' !--- Long name (with advection scheme suffix) 54 CHARACTER(LEN=maxlen) :: type = 'tracer' !--- Type (so far: 'tracer' / 'tag') 55 CHARACTER(LEN=maxlen) :: phase = 'g' !--- Phase ('g'as / 'l'iquid / 's'olid) 56 CHARACTER(LEN=maxlen) :: component = '' !--- Coma-separated list of components (Ex: lmdz,inca) 57 INTEGER :: iGeneration = -1 !--- Generation number (>=0) 58 INTEGER :: iqParent = 0 !--- Parent index 59 INTEGER, ALLOCATABLE :: iqDescen(:) !--- Descendants index (in growing generation order) 60 INTEGER :: nqDescen = 0 !--- Number of descendants (all generations) 61 INTEGER :: nqChildren = 0 !--- Number of children (first generation) 62 INTEGER :: iadv = 10 !--- Advection scheme used 63 LOGICAL :: isAdvected = .FALSE. !--- "true" tracers: iadv > 0. COUNT(isAdvected )=nqtrue 64 LOGICAL :: isInPhysics = .TRUE. !--- "true" tracers: in tr_seri. COUNT(isInPhysics)=nqtottr 65 INTEGER :: iso_iGroup = 0 !--- Isotopes group index in isotopes(:) 66 INTEGER :: iso_iName = 0 !--- Isotope name index in isotopes(iso_iGroup)%trac(:) 67 INTEGER :: iso_iZone = 0 !--- Isotope zone index in isotopes(iso_iGroup)%zone(:) 68 INTEGER :: iso_iPhase = 0 !--- Isotope phase index in isotopes(iso_iGroup)%phase 69 69 END TYPE trac_type 70 70 !------------------------------------------------------------------------------------------------------------------------------ 71 TYPE :: isot_type !=== TYPE FOR AN ISOTOPES FAMILY DESCENDING ON TRACER "parent"72 CHARACTER(LEN=maxlen) :: parent !--- Isotopes family name (parent tracer name ; ex: H2O)73 LOGICAL :: check=.FALSE. !--- Triggering of the checking routines74 TYPE(keys_type), ALLOCATABLE :: keys(:) !--- Isotopes keys/values pairs list (length: niso)75 CHARACTER(LEN=maxlen), ALLOCATABLE :: trac(:) !--- Isotopes + tagging tracers list (length: ntiso)76 CHARACTER(LEN=maxlen), ALLOCATABLE :: zone(:) !--- Geographic tagging zones names list (length: nzone)77 CHARACTER(LEN=maxlen) :: phase = 'g' !--- Phases list: [g][l][s] (length: nphas)78 INTEGER :: niso = 0 !--- Number of isotopes, excluding tagging tracers79 INTEGER :: n zone = 0 !--- Number of geographic tagging zones80 INTEGER :: n tiso = 0 !--- Number of isotopes, including tagging tracers81 INTEGER :: nphas = 0 !--- Numberphases82 INTEGER, ALLOCATABLE :: iqIsoPha(:,:) !--- Idx in "tracers(1:nqtot)" = f(name(1:ntiso)),phas)83 !--- "iqIsoPha"former name: "iqiso"84 INTEGER, ALLOCATABLE :: i tZonIso(:,:) !--- Idx in "trac(1:ntiso)" = f(zone, name(1:niso))85 !--- "itZonIso" former name: "index_trac"86 END TYPE isot_type 71 TYPE :: isot_type !=== TYPE FOR AN ISOTOPES FAMILY DESCENDING ON TRACER "parent" 72 CHARACTER(LEN=maxlen) :: parent !--- Isotopes family name (parent tracer name ; ex: H2O) 73 TYPE(keys_type), ALLOCATABLE :: keys(:) !--- Isotopes keys/values pairs list (length: niso) 74 LOGICAL :: check=.FALSE. !--- Flag for checking routines triggering 75 CHARACTER(LEN=maxlen), ALLOCATABLE :: trac(:) !--- Isotopes + tagging tracers list (length: ntiso) 76 CHARACTER(LEN=maxlen), ALLOCATABLE :: zone(:) !--- Geographic tagging zones names list (length: nzone) 77 CHARACTER(LEN=maxlen) :: phase = 'g' !--- Phases list: [g][l][s] (length: nphas) 78 INTEGER :: niso = 0 !--- Number of isotopes, excluding tagging tracers 79 INTEGER :: ntiso = 0 !--- Number of isotopes, including tagging tracers 80 INTEGER :: nzone = 0 !--- Number of geographic tagging zones 81 INTEGER :: nphas = 0 !--- Number of phases 82 INTEGER, ALLOCATABLE :: iqIsoPha(:,:) !--- Idx in "tracers(1:nqtot)" = f(name(1:ntiso),phas) 83 !--- (former name: "iqiso" 84 INTEGER, ALLOCATABLE :: iqWIsoPha(:,:) !--- Idx in "tracers(1:nqtot)" = f([H2O,name(1:ntiso)],phas) 85 INTEGER, ALLOCATABLE :: itZonIso(:,:) !--- Idx in "trac(1:ntiso)" = f(zone, name(1:niso)) 86 END TYPE isot_type !--- (former name: "index_trac") 87 87 !------------------------------------------------------------------------------------------------------------------------------ 88 88 TYPE :: dataBase_type !=== TYPE FOR TRACERS SECTION 89 CHARACTER(LEN=maxlen) :: name!--- Section name89 CHARACTER(LEN=maxlen) :: name !--- Section name 90 90 TYPE(trac_type), ALLOCATABLE :: trac(:) !--- Tracers descriptors 91 91 END TYPE dataBase_type 92 92 !------------------------------------------------------------------------------------------------------------------------------ 93 93 INTERFACE getKey 94 MODULE PROCEDURE getKeyByName_s1, getKeyByName_s1m, getKeyByName_sm, getKey_sm, & 95 getKeyByName_i1, getKeyByName_i1m, getKeyByName_im, getKey_im, & 96 getKeyByName_r1, getKeyByName_r1m, getKeyByName_rm, getKey_rm, & 97 getKeyByName_l1, getKeyByName_l1m, getKeyByName_lm, getKey_lm 94 MODULE PROCEDURE & 95 getKeyByIndex_s111, getKeyByIndex_sm11, getKeyByIndex_s1m1, getKeyByIndex_smm1, getKeyByIndex_s1mm, getKeyByIndex_smmm, & 96 getKeyByIndex_i111, getKeyByIndex_im11, getKeyByIndex_i1m1, getKeyByIndex_imm1, getKeyByIndex_i1mm, getKeyByIndex_immm, & 97 getKeyByIndex_r111, getKeyByIndex_rm11, getKeyByIndex_r1m1, getKeyByIndex_rmm1, getKeyByIndex_r1mm, getKeyByIndex_rmmm, & 98 getKeyByIndex_l111, getKeyByIndex_lm11, getKeyByIndex_l1m1, getKeyByIndex_lmm1, getKeyByIndex_l1mm, getKeyByIndex_lmmm, & 99 getKeyByName_s111, getKeyByName_sm11, getKeyByName_s1m1, getKeyByName_smm1, getKeyByName_s1mm, getKeyByName_smmm, & 100 getKeyByName_i111, getKeyByName_im11, getKeyByName_i1m1, getKeyByName_imm1, getKeyByName_i1mm, getKeyByName_immm, & 101 getKeyByName_r111, getKeyByName_rm11, getKeyByName_r1m1, getKeyByName_rmm1, getKeyByName_r1mm, getKeyByName_rmmm, & 102 getKeyByName_l111, getKeyByName_lm11, getKeyByName_l1m1, getKeyByName_lmm1, getKeyByName_l1mm, getKeyByName_lmmm 98 103 END INTERFACE getKey 99 104 !------------------------------------------------------------------------------------------------------------------------------ 100 INTERFACE isoSelect; MODULE PROCEDURE isoSelectByIndex, isoSelectByName; END INTERFACE isoSelect 101 INTERFACE old2newH2O; MODULE PROCEDURE old2newH2O_1, old2newH2O_m; END INTERFACE old2newH2O 102 INTERFACE new2oldH2O; MODULE PROCEDURE new2oldH2O_1, new2oldH2O_m; END INTERFACE new2oldH2O 103 INTERFACE fGetKey; MODULE PROCEDURE fgetKeyIdx_s1, fgetKeyNam_s1; END INTERFACE fGetKey 104 INTERFACE tracersSubset; MODULE PROCEDURE trSubset_Indx, trSubset_Name, trSubset_gen0Name; END INTERFACE tracersSubset 105 INTERFACE idxAncestor; MODULE PROCEDURE idxAncestor_1, idxAncestor_m, idxAncestor_mt; END INTERFACE idxAncestor 106 INTERFACE ancestor; MODULE PROCEDURE ancestor_1, ancestor_m, ancestor_mt; END INTERFACE ancestor 107 INTERFACE addKey; MODULE PROCEDURE addKey_1; END INTERFACE addKey!, addKey_m, addKey_mm; END INTERFACE addKey 108 INTERFACE addPhase; MODULE PROCEDURE addPhase_s1, addPhase_sm, addPhase_i1, addPhase_im; END INTERFACE addPhase 105 INTERFACE addKey 106 MODULE PROCEDURE addKey_s11, addKey_s1m, addKey_smm, addKey_i11, addKey_i1m, addKey_imm, & 107 addKey_r11, addKey_r1m, addKey_rmm, addKey_l11, addKey_l1m, addKey_lmm 108 END INTERFACE addKey 109 !------------------------------------------------------------------------------------------------------------------------------ 110 INTERFACE isoSelect; MODULE PROCEDURE isoSelectByIndex, isoSelectByName; END INTERFACE isoSelect 111 INTERFACE old2newH2O; MODULE PROCEDURE old2newH2O_1, old2newH2O_m; END INTERFACE old2newH2O 112 INTERFACE new2oldH2O; MODULE PROCEDURE new2oldH2O_1, new2oldH2O_m; END INTERFACE new2oldH2O 113 INTERFACE addTracer; MODULE PROCEDURE addTracer_1, addTracer_1def; END INTERFACE addTracer 114 INTERFACE delTracer; MODULE PROCEDURE delTracer_1, delTracer_1def; END INTERFACE delTracer 115 INTERFACE addPhase; MODULE PROCEDURE addPhase_s1, addPhase_sm, addPhase_i1, addPhase_im; END INTERFACE addPhase 116 INTERFACE tracersSubset; MODULE PROCEDURE trSubset_Indx, trSubset_Name, trSubset_gen0Name; END INTERFACE tracersSubset 109 117 !------------------------------------------------------------------------------------------------------------------------------ 110 118 … … 114 122 !--- SOME PARAMETERS THAT ARE NOT LIKELY TO CHANGE OFTEN 115 123 CHARACTER(LEN=maxlen), SAVE :: tran0 = 'air' !--- Default transporting fluid 116 CHARACTER(LEN=maxlen), PARAMETER :: old_phases = 'vli fbc'!--- Old phases for water (no separator)117 CHARACTER(LEN=maxlen), PARAMETER :: known_phases = 'gls fbc'!--- Known phases initials124 CHARACTER(LEN=maxlen), PARAMETER :: old_phases = 'vlirb' !--- Old phases for water (no separator) 125 CHARACTER(LEN=maxlen), PARAMETER :: known_phases = 'glsrb' !--- Known phases initials 118 126 INTEGER, PARAMETER :: nphases = LEN_TRIM(known_phases) !--- Number of phases 119 127 CHARACTER(LEN=maxlen), SAVE :: phases_names(nphases) & !--- Known phases names 120 = ['gaseous', 'liquid ', 'solid ', 'fracld ', 'blosnow', 'cldvapr'] 121 CHARACTER(LEN=1), SAVE :: phases_sep = '_' !--- Phase separator 122 LOGICAL, SAVE :: tracs_merge = .TRUE. !--- Merge/stack tracers lists 123 LOGICAL, SAVE :: lSortByGen = .TRUE. !--- Sort by growing generation 128 = ['gaseous ', 'liquid ', 'solid ', 'cloud ','blownSnow'] 129 CHARACTER(LEN=1), SAVE :: phases_sep = '_' !--- Phase separator 124 130 CHARACTER(LEN=maxlen), SAVE :: isoFile = 'isotopes_params.def'!--- Name of the isotopes parameters file 125 131 … … 128 134 CHARACTER(LEN=maxlen), SAVE :: newH2OIso(5) = ['H216O', 'HDO ', 'H218O', 'H217O', 'HTO '] 129 135 130 !--- CORRESPONDANCE BETWEEN OLD AND NEW HNO3 RELATED SPECIES NAMES 136 !--- CORRESPONDANCE BETWEEN OLD AND NEW HNO3 RELATED SPECIES NAMES (FOR REPROBUS) 131 137 CHARACTER(LEN=maxlen), SAVE :: oldHNO3(2) = ['HNO3_g ', 'HNO3 '] 132 138 CHARACTER(LEN=maxlen), SAVE :: newHNO3(2) = ['HNO3 ', 'HNO3tot'] … … 138 144 !=== ALIASES OF VARIABLES FROM SELECTED ISOTOPES FAMILY EMBEDDED IN "isotope" (isotopes(ixIso)) 139 145 TYPE(isot_type), SAVE, POINTER :: isotope !--- CURRENTLY SELECTED ISOTOPES FAMILY DESCRIPTOR 140 INTEGER, SAVE :: ixIso, iH2O 146 INTEGER, SAVE :: ixIso, iH2O=0 !--- Index of the selected isotopes family and H2O family 141 147 INTEGER, SAVE :: nbIso !--- Number of isotopes classes 142 148 LOGICAL, SAVE :: isoCheck !--- Flag to trigger the checking routines … … 148 154 nphas, ntiso !--- NUMBER OF PHASES AND ISOTOPES + ISOTOPIC TAGGING TRACERS 149 155 INTEGER, SAVE, POINTER ::itZonIso(:,:), & !--- INDEX IN "isoTrac" AS f(tagging zone idx, isotope idx) 150 iqIsoPha(:,:) !--- INDEX IN "qx" AS f(isotopic tracer idx, phase idx) 156 iqIsoPha(:,:), & !--- INDEX IN "qx" AS f(isotopic tracer idx, phase idx) 157 iqWIsoPha(:,:) !--- INDEX IN "qx" AS f(H2O + isotopic tracer idx, phase idx) 158 159 !=== PARAMETERS FOR DEFAULT BEHAVIOUR 160 LOGICAL, PARAMETER :: lTracsMerge = .FALSE. !--- Merge/stack tracers lists 161 LOGICAL, PARAMETER :: lSortByGen = .TRUE. !--- Sort by growing generation 151 162 152 163 INTEGER, PARAMETER :: maxTableWidth = 192 !--- Maximum width of a table displayed with "dispTable" … … 179 190 ! * If you need to convert a %key/%val pair into a direct-access key, add the corresponding line in "setDirectKeys". 180 191 !============================================================================================================================== 181 LOGICAL FUNCTION readTracersFiles(type_trac, lRepr) RESULT(lerr) 182 !------------------------------------------------------------------------------------------------------------------------------ 183 CHARACTER(LEN=*), INTENT(IN) :: type_trac !--- List of components used 184 LOGICAL, OPTIONAL, INTENT(IN) :: lRepr !--- Activate the HNNO3 exceptions for REPROBUS 192 LOGICAL FUNCTION readTracersFiles(type_trac, tracs, lRepr) RESULT(lerr) 193 !------------------------------------------------------------------------------------------------------------------------------ 194 CHARACTER(LEN=*), INTENT(IN) :: type_trac !--- List of components used 195 TYPE(trac_type), ALLOCATABLE, TARGET, OPTIONAL, INTENT(OUT) :: tracs(:) !--- Tracers descriptor for external storage 196 LOGICAL, OPTIONAL, INTENT(IN) :: lRepr !--- Activate the HNO3 exceptions for REPROBUS 185 197 CHARACTER(LEN=maxlen), ALLOCATABLE :: s(:), sections(:), trac_files(:) 186 198 CHARACTER(LEN=maxlen) :: str, fname, tname, pname, cname 187 199 INTEGER :: nsec, ierr, it, ntrac, ns, ip, ix, fType 200 INTEGER, ALLOCATABLE :: iGen(:) 188 201 LOGICAL :: lRep 189 202 TYPE(keys_type), POINTER :: k … … 195 208 196 209 !--- Required sections + corresponding files names (new style single section case) for tests 197 IF(test(testTracersFiles(modname, type_trac, fType, .FALSE., trac_files, sections), lerr)) RETURN210 lerr = testTracersFiles(modname, type_trac, fType, .FALSE., trac_files, sections); IF(lerr) RETURN 198 211 nsec = SIZE(sections) 199 212 200 213 !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 201 SELECT CASE(fType) !--- Set %name, %genOName, %parent, %type, %phase, %component, %iGeneration, %keys214 SELECT CASE(fType) !--- Set name, component, parent, phase, iGeneration, gen0Name, type 202 215 !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 203 216 CASE(1) !=== OLD FORMAT "traceur.def" 204 217 !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 205 218 !--- OPEN THE "traceur.def" FILE 206 OPEN(90, FILE="traceur.def", FORM='formatted', STATUS='old', IOSTAT=ierr)219 OPEN(90, FILE="traceur.def", FORM='formatted', STATUS='old', POSITION='REWIND', IOSTAT=ierr) 207 220 208 221 !--- GET THE TRACERS NUMBER 209 222 READ(90,'(i3)',IOSTAT=ierr)ntrac !--- Number of lines/tracers 210 IF(test(fmsg('Invalid format for "'//TRIM(fname)//'"', modname, ierr /= 0), lerr)) RETURN223 lerr = ierr/=0; IF(fmsg('Invalid format for "'//TRIM(fname)//'"', modname, lerr)) RETURN 211 224 212 225 !--- READ THE REMAINING LINES: <hadv> <vadv> <tracer> [<transporting fluid>] 213 IF(ALLOCATED(tracers)) DEALLOCATE(tracers)214 226 ALLOCATE(tracers(ntrac)) 215 DO it =1,ntrac!=== READ RAW DATA: loop on the line/tracer number227 DO it = 1, ntrac !=== READ RAW DATA: loop on the line/tracer number 216 228 READ(90,'(a)',IOSTAT=ierr) str 217 IF(test(fmsg('Invalid format for "' //TRIM(fname)//'"', modname, ierr>0), lerr)) RETURN218 IF(test(fmsg('Not enough lines in "'//TRIM(fname)//'"', modname, ierr<0), lerr)) RETURN229 lerr = ierr>0; IF(fmsg('Invalid format for "' //TRIM(fname)//'"', modname, lerr)) RETURN 230 lerr = ierr<0; IF(fmsg('Not enough lines in "'//TRIM(fname)//'"', modname, lerr)) RETURN 219 231 lerr = strParse(str, ' ', s, ns) 220 232 CALL msg('This file is for air tracers only', modname, ns == 3 .AND. it == 1) … … 226 238 ix = strIdx(oldHNO3, s(3)) 227 239 IF(ix /= 0 .AND. lRep) tname = newHNO3(ix) !--- Exception for HNO3 (REPROBUS ONLY) 228 tracers(it)%name = tname !--- Set %name229 CALL addKey _1('name', tname, k)!--- Set the name of the tracer240 tracers(it)%name = tname !--- Set the name of the tracer 241 CALL addKey('name', tname, k) !--- Set the name of the tracer 230 242 tracers(it)%keys%name = tname !--- Copy tracers names in keys components 231 243 … … 233 245 cname = type_trac !--- Name of the model component 234 246 IF(ANY([(addPhase('H2O', ip), ip = 1, nphases)] == tname)) cname = 'lmdz' 235 tracers(it)%component = cname !--- Set %component236 CALL addKey _1('component', cname, k)!--- Set the name of the model component247 tracers(it)%component = cname !--- Set component 248 CALL addKey('component', cname, k) !--- Set the name of the model component 237 249 238 250 !=== NAME OF THE PARENT … … 243 255 IF(ix /= 0 .AND. lRep) pname = newHNO3(ix) !--- Exception for HNO3 (REPROBUS ONLY) 244 256 END IF 245 tracers(it)%parent = pname !--- Set %parent246 CALL addKey _1('parent', pname, k)257 tracers(it)%parent = pname !--- Set the parent name 258 CALL addKey('parent', pname, k) 247 259 248 260 !=== PHASE AND ADVECTION SCHEMES NUMBERS 249 tracers(it)%phase = known_phases(ip:ip) !--- Set %phase: tracer phase(default: "g"azeous)250 CALL addKey _1('phase', known_phases(ip:ip), k) !--- Set the phaseof the tracer (default: "g"azeous)251 CALL addKey _1('hadv', s(1), k)!--- Set the horizontal advection schemes number252 CALL addKey _1('vadv', s(2), k)!--- Set the vertical advection schemes number261 tracers(it)%phase = known_phases(ip:ip) !--- Set the phase of the tracer (default: "g"azeous) 262 CALL addKey('phase', known_phases(ip:ip), k) !--- Set the phase of the tracer (default: "g"azeous) 263 CALL addKey('hadv', s(1), k) !--- Set the horizontal advection schemes number 264 CALL addKey('vadv', s(2), k) !--- Set the vertical advection schemes number 253 265 END DO 254 266 CLOSE(90) 255 IF(test(setGeneration(tracers), lerr)) RETURN !--- Set %iGeneration and %gen0Name 256 WHERE(tracers%iGeneration == 2) tracers(:)%type = 'tag' !--- Set %type: 'tracer' or 'tag' 257 DO it=1,ntrac 258 CALL addKey_1('type', tracers(it)%type, tracers(it)%keys) !--- Set the type of tracer 267 lerr = setGeneration(tracers); IF(lerr) RETURN !--- Set iGeneration and gen0Name 268 lerr = getKey('iGeneration', iGen, tracers(:)%keys) !--- Generation number 269 WHERE(iGen == 2) tracers(:)%type = 'tag' !--- Set type: 'tracer' or 'tag' 270 DO it = 1, ntrac 271 CALL addKey('type', tracers(it)%type, tracers(it)%keys) !--- Set the type of tracer 259 272 END DO 260 IF(test(checkTracers(tracers, fname, fname), lerr)) RETURN!--- Detect orphans and check phases261 IF(test(checkUnique (tracers, fname, fname), lerr)) RETURN!--- Detect repeated tracers262 CALL sortTracers (tracers)!--- Sort the tracers273 lerr = checkTracers(tracers, fname, fname); IF(lerr) RETURN !--- Detect orphans and check phases 274 lerr = checkUnique (tracers, fname, fname); IF(lerr) RETURN !--- Detect repeated tracers 275 CALL sortTracers (tracers) !--- Sort the tracers 263 276 !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 264 CASE(2); IF(test(feedDBase(["tracer.def"], [type_trac], modname), lerr)) RETURN!=== SINGLE FILE, MULTIPLE SECTIONS277 CASE(2); lerr=feedDBase(["tracer.def"], [type_trac], modname); IF(lerr) RETURN !=== SINGLE FILE, MULTIPLE SECTIONS 265 278 !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 266 CASE(3); IF(test(feedDBase( trac_files , sections, modname), lerr)) RETURN!=== MULTIPLE FILES, SINGLE SECTION279 CASE(3); lerr=feedDBase( trac_files , sections, modname); IF(lerr) RETURN !=== MULTIPLE FILES, SINGLE SECTION 267 280 !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 268 281 END SELECT 269 282 !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 270 283 IF(ALL([2,3] /= fType)) RETURN 271 272 IF(nsec == 1) THEN; 273 tracers = dBase(1)%trac 274 ELSE IF(tracs_merge) THEN 275 CALL msg('The multiple required sections will be MERGED.', modname) 276 IF(test(mergeTracers(dBase, tracers), lerr)) RETURN 277 ELSE 278 CALL msg('The multiple required sections will be CUMULATED.', modname) 279 IF(test(cumulTracers(dBase, tracers), lerr)) RETURN 284 IF(nsec == 1) tracers = dBase(1)%trac 285 IF(nsec /= 1) THEN 286 CALL msg('Multiple sections are MERGED', modname, lTracsMerge) 287 CALL msg('Multiple sections are CUMULATED', modname, .NOT.lTracsMerge) 288 IF( lTracsMerge) lerr = cumulTracers(dBase, tracers) 289 IF(.NOT.lTracsMerge) lerr = cumulTracers(dBase, tracers) 290 IF(lerr) RETURN 280 291 END IF 281 CALL setDirectKeys(tracers) !--- Set %iqParent, %iqDescen, %nqDescen, %nqChildren 292 lerr = indexUpdate(tracers); IF(lerr) RETURN !--- Set iqParent, iqDescen, nqDescen, nqChildren 293 IF(PRESENT(tracs)) CALL MOVE_ALLOC(FROM=tracers, TO=tracs) 282 294 END FUNCTION readTracersFiles 283 295 !============================================================================================================================== … … 299 311 !--- PARSE "type_trac" LIST AND DETERMINE THE TRACERS FILES NAMES (FOR CASE 3: MULTIPLE FILES, SINGLE SECTION PER FILE) 300 312 !--- If type_trac is a scalar (case 1), "sections" and "trac_files" are not usable, but are meaningless for case 1 anyway. 301 IF(test(strParse(type_trac, '|', sections, n=nsec), lerr)) RETURN !--- Parse "type_trac" list313 lerr = strParse(type_trac, '|', sections, n=nsec); IF(lerr) RETURN !--- Parse "type_trac" list 302 314 IF(PRESENT(sects)) sects = sections 303 315 ALLOCATE(trac_files(nsec), ll(nsec)) … … 313 325 IF(.NOT.lD) RETURN !--- NO CHECKING/DISPLAY NEEDED: JUST GET type_trac,fType 314 326 IF(ANY(ll) .AND. fType/=3) THEN !--- MISSING FILES 315 IF(test(checkList(trac_files, .NOT.ll, 'Failed reading tracers description', 'files', 'missing'), lerr)) RETURN327 lerr = checkList(trac_files, .NOT.ll, 'Failed reading tracers description', 'files', 'missing'); IF(lerr) RETURN 316 328 END IF 317 329 … … 344 356 ll = strCount(snames, '|', ndb) !--- Number of sections for each file 345 357 ALLOCATE(ixf(SUM(ndb))) 346 DO i=1, SIZE(fnames) !--- Set %name, %keys347 IF(test(readSections(fnames(i), snames(i), 'default'), lerr)) RETURN358 DO i=1, SIZE(fnames) !--- Set name, keys 359 lerr = readSections(fnames(i), snames(i), 'default'); IF(lerr) RETURN 348 360 ixf(1+SUM(ndb(1:i-1)):SUM(ndb(1:i))) = i !--- File index for each section of the expanded list 349 361 END DO … … 353 365 fnm = fnames(ixf(idb)); snm = dBase(idb)%name !--- FILE AND SECTION NAMES 354 366 lerr = ANY([(dispTraSection('RAW CONTENT OF SECTION "'//TRIM(snm)//'"', snm, modname), idb=1, SIZE(dBase))]) 355 IF(test(expandSection(dBase(idb)%trac, snm, fnm), lerr)) RETURN !--- EXPAND NAMES ; set %parent, %type, %component356 IF(test(setGeneration(dBase(idb)%trac), lerr)) RETURN !--- set %iGeneration, %genOName357 IF(test(checkTracers (dBase(idb)%trac, snm, fnm), lerr)) RETURN!--- CHECK ORPHANS AND PHASES358 IF(test(checkUnique (dBase(idb)%trac, snm, fnm), lerr)) RETURN!--- CHECK TRACERS UNIQUENESS359 CALL expandPhases (dBase(idb)%trac) !--- EXPAND PHASES ; set %phase360 CALL sortTracers (dBase(idb)%trac)!--- SORT TRACERS367 lerr = expandSection(dBase(idb)%trac, snm, fnm); IF(lerr) RETURN !--- EXPAND NAMES ; SET parent, type, component 368 lerr = setGeneration(dBase(idb)%trac); IF(lerr) RETURN !--- SET iGeneration, genOName 369 lerr = checkTracers (dBase(idb)%trac, snm, fnm); IF(lerr) RETURN !--- CHECK ORPHANS AND PHASES 370 lerr = checkUnique (dBase(idb)%trac, snm, fnm); IF(lerr) RETURN !--- CHECK TRACERS UNIQUENESS 371 lerr = expandPhases (dBase(idb)%trac); IF(lerr) RETURN !--- EXPAND PHASES ; set phase 372 CALL sortTracers (dBase(idb)%trac) !--- SORT TRACERS 361 373 lerr = ANY([(dispTraSection('EXPANDED CONTENT OF SECTION "'//TRIM(snm)//'"', snm, modname), idb=1, SIZE(dBase))]) 362 374 !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ … … 387 399 ll = strParse(snam, '|', keys = sec) !--- Requested sections names 388 400 ix = strIdx(dBase(:)%name, sec(:)) !--- Indexes of requested sections in database 389 IF(test(checkList(sec, ix == 0, 'In file "'//TRIM(fnam)//'"','section(s)', 'missing'), lerr)) RETURN401 lerr = checkList(sec, ix == 0, 'In file "'//TRIM(fnam)//'"','section(s)', 'missing'); IF(lerr) RETURN 390 402 tdb = dBase(:); dBase = [tdb(1:n0-1),tdb(PACK(ix, MASK=ix/=0))] !--- Keep requested sections only 391 403 … … 403 415 !------------------------------------------------------------------------------------------------------------------------------ 404 416 IF(.NOT.ALLOCATED(dBase)) ALLOCATE(dBase(0)) 405 OPEN(90, FILE=fnam, FORM='formatted', STATUS='old')417 OPEN(90, FILE=fnam, FORM='formatted', POSITION='REWIND', STATUS='old') 406 418 DO; str='' 407 419 DO … … 416 428 IF(str(1:1)=='#') CYCLE !--- Skip comments lines 417 429 CALL removeComment(str) !--- Skip comments at the end of a line 430 IF(LEN_TRIM(str) == 0) CYCLE !--- Empty line (probably end of file) 418 431 IF(str == '') CYCLE !--- Skip empty line (probably at the end of the file) 419 432 IF(str(1:1)=='&') THEN !=== SECTION HEADER LINE … … 431 444 ll = strParse(str,' ', s, n, v) !--- Parse <key>=<val> pairs 432 445 tt = dBase(ndb)%trac(:) 433 tmp%name = s(1); tmp%keys = keys_type(s(1), s(2:n), v(2:n)) !--- Set %name and %keys 446 v(1) = s(1); s(1) = 'name' !--- Convert "name" into a regular key 447 tmp%name = v(1); tmp%keys = keys_type(v(1), s(:), v(:)) !--- Set %name and %keys 434 448 dBase(ndb)%trac = [tt(:), tmp] 435 DEALLOCATE(tt) 436 ! dBase(ndb)%trac = [dBase(ndb)%trac(:), tra(name=s(1), keys=keys_type(s(1), s(2:n), v(2:n)))] 449 DEALLOCATE(tt, tmp%keys%key, tmp%keys%val) 437 450 END IF 438 451 END DO … … 460 473 ky => t(jd)%keys 461 474 DO k = 1, SIZE(ky%key) !--- Loop on the keys of the tracer named "defName" 462 ! CALL addKey _m(ky%key(k), ky%val(k), t(:)%keys, .FALSE.)!--- Add key to all the tracers (no overwriting)463 DO it = 1, SIZE(t); CALL addKey _1(ky%key(k), ky%val(k), t(it)%keys, .FALSE.); END DO475 ! CALL addKey(ky%key(k), ky%val(k), t(:)%keys, .FALSE.) !--- Add key to all the tracers (no overwriting) 476 DO it = 1, SIZE(t); CALL addKey(ky%key(k), ky%val(k), t(it)%keys, .FALSE.); END DO 464 477 END DO 465 478 tt = [t(1:jd-1),t(jd+1:SIZE(t))]; CALL MOVE_ALLOC(FROM=tt, TO=t) !--- Remove the virtual tracer named "defName" … … 506 519 !------------------------------------------------------------------------------------------------------------------------------ 507 520 TYPE(trac_type), ALLOCATABLE, INTENT(INOUT) :: tr(:) !--- Tracer derived type vector 508 CHARACTER(LEN=*), INTENT(IN) :: sname 509 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: fname 521 CHARACTER(LEN=*), INTENT(IN) :: sname !--- Current section name 522 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: fname !--- Tracers description file name 510 523 TYPE(trac_type), ALLOCATABLE :: ttr(:) 511 CHARACTER(LEN=maxlen), ALLOCATABLE :: ta(:), pa(:) 524 CHARACTER(LEN=maxlen), ALLOCATABLE :: ta(:), pa(:), tname(:), parent(:), dType(:) 512 525 CHARACTER(LEN=maxlen) :: msg1, modname 513 526 INTEGER :: it, nt, iq, nq, itr, ntr, ipr, npr … … 516 529 lerr = .FALSE. 517 530 nt = SIZE(tr) 531 lerr = getKey('name', tname, tr(:)%keys); IF(lerr) RETURN 532 lerr = getKey('parent', parent, tr(:)%keys, def = tran0); IF(lerr) RETURN 533 lerr = getKey('type', dType, tr(:)%keys, def = 'tracer'); IF(lerr) RETURN 518 534 nq = 0 519 535 !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ … … 521 537 !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 522 538 !--- Extract useful keys: parent name, type, component name 523 tr(it)%parent = fgetKey(it, 'parent', tr(:)%keys, tran0 )524 tr(it)%type = fgetKey(it, 'type' , tr(:)%keys, 'tracer')525 539 tr(it)%component = sname 526 ! CALL addKey_m('component', sname, tr(:)%keys) 527 DO iq=1,SIZE(tr); CALL addKey_1('component', sname, tr(iq)%keys); END DO 540 CALL addKey('component', sname, tr(it)%keys) 528 541 529 542 !--- Determine the number of tracers and parents ; coherence checking 530 ll = strCount( tr(it)%name,',', ntr)531 ll = strCount( tr(it)%parent, ',', npr)543 ll = strCount( tname(it), ',', ntr) 544 ll = strCount(parent(it), ',', npr) 532 545 533 546 !--- Tagging tracers only can have multiple parents 534 IF(test(npr/=1 .AND. TRIM(tr(it)%type)/='tag', lerr)) THEN 547 lerr = npr /=1 .AND. TRIM(dType(it)) /= 'tag' 548 IF(lerr) THEN 535 549 msg1 = 'Check section "'//TRIM(sname)//'"' 536 IF(PRESENT(fname)) msg1 =TRIM(msg1)//' in file "'//TRIM(fname)//'"'537 CALL msg(TRIM(msg1)//': "'//TRIM(t r(it)%name)//'" has several parents but is not a tag', modname); RETURN550 IF(PRESENT(fname)) msg1 = TRIM(msg1)//' in file "'//TRIM(fname)//'"' 551 CALL msg(TRIM(msg1)//': "'//TRIM(tname(it))//'" has several parents but is not a tag', modname); RETURN 538 552 END IF 539 553 nq = nq + ntr*npr … … 547 561 DO it = 1, nt !=== EXPAND TRACERS AND PARENTS NAMES LISTS 548 562 !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 549 ll = strParse(tr(it)%name, ',', ta, ntr) !--- Number of tracers 550 ll = strParse(tr(it)%parent, ',', pa, npr) !--- Number of parents 551 DO ipr=1,npr !--- Loop on parents list elts 552 DO itr=1,ntr !--- Loop on tracers list elts 563 ll = strParse( tname(it), ',', ta, ntr) !--- Number of tracers 564 ll = strParse(parent(it), ',', pa, npr) !--- Number of parents 565 DO ipr = 1, npr !--- Loop on parents list elts 566 DO itr = 1, ntr !--- Loop on tracers list elts 567 ttr(iq)%keys%name = TRIM(ta(itr)) 553 568 ttr(iq)%keys%key = tr(it)%keys%key 554 569 ttr(iq)%keys%val = tr(it)%keys%val 555 ttr(iq)%keys%name = ta(itr) 556 ttr(iq)%name = TRIM(ta(itr)); CALL addKey_1('name', ta(itr), ttr(iq)%keys) 557 ttr(iq)%parent = TRIM(pa(ipr)); CALL addKey_1('parent', pa(ipr), ttr(iq)%keys) 558 ttr(iq)%type = tr(it)%type; CALL addKey_1('type', tr(it)%type, ttr(iq)%keys) 559 ttr(iq)%component = tr(it)%component; CALL addKey_1('component', tr(it)%component, ttr(iq)%keys) 560 iq = iq+1 570 ttr(iq)%name = TRIM(ta(itr)) 571 ttr(iq)%parent = TRIM(pa(ipr)) 572 ttr(iq)%type = dType(it) 573 ttr(iq)%component = sname 574 CALL addKey('name', ta(itr), ttr(iq)%keys) 575 CALL addKey('parent', pa(ipr), ttr(iq)%keys) 576 CALL addKey('type', dType(it), ttr(iq)%keys) 577 CALL addKey('component', sname, ttr(iq)%keys) 578 iq = iq + 1 561 579 END DO 562 580 END DO … … 575 593 !------------------------------------------------------------------------------------------------------------------------------ 576 594 ! Purpose: Determine, for each tracer of "tr(:)": 577 ! * %iGeneration: the generation number578 ! * %gen0Name: the generation 0 ancestor name579 ! Check also for orphan tracers (tracers not descending on "tran0").595 ! * iGeneration: the generation number 596 ! * gen0Name: the generation 0 ancestor name 597 ! Check also for orphan tracers (tracers without parent). 580 598 !------------------------------------------------------------------------------------------------------------------------------ 581 599 TYPE(trac_type), INTENT(INOUT) :: tr(:) !--- Tracer derived type vector 582 600 INTEGER :: iq, jq, ig 583 CHARACTER(LEN=maxlen), ALLOCATABLE :: parent(:) 601 CHARACTER(LEN=maxlen), ALLOCATABLE :: parent(:), tname(:) 584 602 !------------------------------------------------------------------------------------------------------------------------------ 585 603 CHARACTER(LEN=maxlen) :: modname 586 604 modname = 'setGeneration' 587 IF(test(fmsg('missing "parent" attribute', modname, getKey('parent', parent, ky=tr(:)%keys)), lerr)) RETURN 605 lerr = getKey('name', tname, ky=tr(:)%keys); IF(lerr) RETURN 606 lerr = getKey('parent', parent, ky=tr(:)%keys); IF(lerr) RETURN 588 607 DO iq = 1, SIZE(tr) 589 608 jq = iq; ig = 0 590 609 DO WHILE(parent(jq) /= tran0) 591 jq = strIdx(tr(:)%name, parent(jq)) 592 IF(test(fmsg('Orphan tracer "'//TRIM(tr(iq)%name)//'"', modname, jq == 0), lerr)) RETURN 610 jq = strIdx(tname(:), parent(jq)) 611 lerr = jq == 0 612 IF(fmsg('Orphan tracer "'//TRIM(tname(iq))//'"', modname, lerr)) RETURN 593 613 ig = ig + 1 594 614 END DO 595 tr(iq)%gen0Name = tr(jq)%name; CALL addKey_1('gen0Name', tr(iq)%gen0Name, tr(iq)%keys) 596 tr(iq)%iGeneration = ig; CALL addKey_1('iGeneration', TRIM(int2str(ig)), tr(iq)%keys) 615 tr(iq)%gen0Name = tname(jq) 616 tr(iq)%iGeneration = ig 617 CALL addKey('iGeneration', ig, tr(iq)%keys) 618 CALL addKey('gen0Name', tname(jq), tr(iq)%keys) 597 619 END DO 598 620 END FUNCTION setGeneration … … 604 626 !------------------------------------------------------------------------------------------------------------------------------ 605 627 ! Purpose: 606 ! * check for orphan tracers (without knownparent)607 ! * check wether the phases are known or not ( "g"aseous, "l"iquid or "s"olid so far)628 ! * check for orphan tracers (without parent) 629 ! * check wether the phases are known or not (elements of "known_phases") 608 630 !------------------------------------------------------------------------------------------------------------------------------ 609 631 TYPE(trac_type), INTENT(IN) :: tr(:) !--- Tracer derived type vector 610 632 CHARACTER(LEN=*), INTENT(IN) :: sname !--- Section name 611 633 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: fname !--- File name 634 CHARACTER(LEN=1) :: p 612 635 CHARACTER(LEN=maxlen) :: mesg 613 636 CHARACTER(LEN=maxlen) :: bp(SIZE(tr, DIM=1)), pha !--- Bad phases list, phases of current tracer 614 CHARACTER(LEN=1) :: p 637 CHARACTER(LEN=maxlen), ALLOCATABLE :: tname(:) 638 INTEGER, ALLOCATABLE :: iGen(:) 615 639 INTEGER :: ip, np, iq, nq 616 640 !------------------------------------------------------------------------------------------------------------------------------ 641 CHARACTER(LEN=maxlen) :: modname 642 modname = 'checkTracers' 617 643 nq = SIZE(tr,DIM=1) !--- Number of tracers lines 618 644 mesg = 'Check section "'//TRIM(sname)//'"' 619 645 IF(PRESENT(fname)) mesg=TRIM(mesg)//' in file "'//TRIM(fname)//'"' 646 lerr = getKey('iGeneration', iGen, tr(:)%keys); IF(lerr) RETURN 647 lerr = getKey('name', tname, tr(:)%keys); IF(lerr) RETURN 620 648 621 649 !=== CHECK FOR ORPHAN TRACERS 622 IF(test(checkList(tr%name, tr%iGeneration==-1, mesg, 'tracers', 'orphan'), lerr)) RETURN650 lerr = checkList(tname, iGen==-1, mesg, 'tracers', 'orphan'); IF(lerr) RETURN 623 651 624 652 !=== CHECK PHASES 625 DO iq =1,nq; IF(tr(iq)%iGeneration/=0) CYCLE!--- Generation O only is checked626 pha = fgetKey(iq, 'phases', tr(:)%keys, 'g') !--- Phases653 DO iq = 1, nq; IF(iGen(iq) /= 0) CYCLE !--- Generation O only is checked 654 IF(getKey(['phases','phase '], pha, iq, tr(:)%keys, lDisp=.FALSE.)) pha = 'g' !--- Phase 627 655 np = LEN_TRIM(pha); bp(iq)=' ' 628 DO ip =1,np; p = pha(ip:ip); IF(INDEX(known_phases,p)==0) bp(iq) = TRIM(bp(iq))//p; END DO629 IF(TRIM(bp(iq)) /= '') bp(iq) = TRIM(t r(iq)%name)//': '//TRIM(bp(iq))656 DO ip = 1, np; p = pha(ip:ip); IF(INDEX(known_phases, p) == 0) bp(iq) = TRIM(bp(iq))//p; END DO 657 IF(TRIM(bp(iq)) /= '') bp(iq) = TRIM(tname(iq))//': '//TRIM(bp(iq)) 630 658 END DO 631 lerr = checkList(bp, tr%iGeneration==0 .AND. bp/='', mesg, 'tracers phases', 'unknown')659 lerr = checkList(bp, iGen == 0 .AND. bp /= '', mesg, 'tracers phases', 'unknown') 632 660 END FUNCTION checkTracers 633 661 !============================================================================================================================== … … 645 673 INTEGER :: ip, np, iq, nq, k 646 674 LOGICAL, ALLOCATABLE :: ll(:) 647 CHARACTER(LEN=maxlen) :: mesg, tnam, tdup(SIZE(tr,DIM=1)) 648 CHARACTER(LEN=1) :: p 649 !------------------------------------------------------------------------------------------------------------------------------ 675 CHARACTER(LEN=maxlen) :: mesg, phase, tdup(SIZE(tr,DIM=1)) 676 CHARACTER(LEN=maxlen), ALLOCATABLE :: tname(:), dType(:) 677 INTEGER, ALLOCATABLE :: iGen(:) 678 CHARACTER(LEN=1) :: p 679 !------------------------------------------------------------------------------------------------------------------------------ 680 CHARACTER(LEN=maxlen) :: modname 681 modname = 'checkUnique' 650 682 mesg = 'Check section "'//TRIM(sname)//'"' 651 683 IF(PRESENT(fname)) mesg=TRIM(mesg)//' in file "'//TRIM(fname)//'"' 652 684 nq=SIZE(tr,DIM=1); lerr=.FALSE. !--- Number of lines ; error flag 653 685 tdup(:) = '' 654 DO iq=1,nq; IF(tr(iq)%type == 'tag') CYCLE !--- Tags can be repeated 655 tnam = TRIM(tr(iq)%name) 656 ll = tr(:)%name==TRIM(tnam) !--- Mask for current tracer name 657 IF(COUNT(ll)==1 ) CYCLE !--- Tracer is not repeated 658 IF(tr(iq)%iGeneration>0) THEN 659 tdup(iq) = tnam !--- gen>0: MUST be unique 686 lerr = getKey('name', tname, tr%keys); IF(lerr) RETURN 687 lerr = getKey('type', dType, tr%keys); IF(lerr) RETURN 688 lerr = getKey('iGeneration', iGen, tr%keys); IF(lerr) RETURN 689 DO iq = 1, nq 690 IF(dType(iq) == 'tag') CYCLE !--- Tags can be repeated 691 ll = tname==TRIM(tname(iq)) !--- Mask for current tracer name 692 IF(COUNT(ll) == 1) CYCLE !--- Tracer is not repeated 693 IF(iGen(iq) > 0) THEN 694 tdup(iq) = tname(iq) !--- gen>0: MUST be unique 660 695 ELSE 661 DO ip=1,nphases; p=known_phases(ip:ip) !--- Loop on known phases 662 !--- Number of appearances of the current tracer with known phase "p" 663 np = COUNT( PACK( [(INDEX(fgetKey(k, 'phases', tr(:)%keys, 'g'),p), k=1, nq)] /=0 , MASK=ll ) ) 664 IF(np <=1) CYCLE 665 tdup(iq) = TRIM(tdup(iq))//TRIM(phases_names(ip)) 696 DO ip = 1, nphases; p = known_phases(ip:ip) !--- Loop on known phases 697 np = 0 698 DO k = 1, nq 699 IF(.NOT.ll(k)) CYCLE !--- Skip tracers different from current one 700 IF(getKey(['phases','phase '], phase, k, tr%keys, lDisp=.FALSE.)) phase='g'!--- Get current phases 701 IF(INDEX(phase, p) /= 0) np = np + 1 !--- One more appearance of current tracer with phase "p" 702 END DO 703 IF(np <= 1) CYCLE !--- Regular case: no or a single appearance 704 tdup(iq) = TRIM(tdup(iq))//TRIM(phases_names(ip)) !--- Repeated phase 666 705 IF(ANY(tdup(1:iq-1) == tdup(iq))) tdup(iq)='' !--- Avoid repeating same messages 667 706 END DO 668 707 END IF 669 IF(tdup(iq) /= '') tdup(iq)=TRIM(tnam )//' in '//TRIM(tdup(iq))//' phase(s)'708 IF(tdup(iq) /= '') tdup(iq)=TRIM(tname(iq))//' in '//TRIM(tdup(iq))//' phase(s)' 670 709 END DO 671 710 lerr = checkList(tdup, tdup/='', mesg, 'tracers', 'duplicated') … … 675 714 676 715 !============================================================================================================================== 677 SUBROUTINE expandPhases(tr)716 LOGICAL FUNCTION expandPhases(tr) RESULT(lerr) 678 717 !------------------------------------------------------------------------------------------------------------------------------ 679 718 ! Purpose: Expand the phases in the tracers descriptor "tr". Phases are not repeated for a tracer, thanks to "checkUnique". … … 681 720 TYPE(trac_type), ALLOCATABLE, INTENT(INOUT) :: tr(:) !--- Tracer derived type vector 682 721 !------------------------------------------------------------------------------------------------------------------------------ 683 TYPE(trac_type), ALLOCATABLE :: ttr(:) 684 INTEGER, ALLOCATABLE :: i0(:) 685 CHARACTER(LEN=maxlen) :: nam, pha, tname 722 TYPE(trac_type), ALLOCATABLE :: ttr(:) 723 INTEGER, ALLOCATABLE :: i0(:), iGen(:) 724 CHARACTER(LEN=maxlen), ALLOCATABLE :: tname(:), gen0N(:), phase(:), parents(:), dType(:) 725 CHARACTER(LEN=maxlen) :: nam, gen0Nm, pha, parent 686 726 CHARACTER(LEN=1) :: p 687 727 INTEGER :: ip, np, iq, jq, nq, it, nt, nc, i, n 688 728 LOGICAL :: lTag, lExt 689 729 !------------------------------------------------------------------------------------------------------------------------------ 730 CHARACTER(LEN=maxlen) :: modname 731 modname = 'expandPhases' 690 732 nq = SIZE(tr, DIM=1) 691 733 nt = 0 734 lerr = getKey('name', tname, tr%keys); IF(lerr) RETURN !--- Names of the tracers 735 lerr = getKey('gen0Name', gen0N, tr%keys); IF(lerr) RETURN !--- Names of the tracers of first generation 736 lerr = getKey('iGeneration', iGen, tr%keys); IF(lerr) RETURN !--- Generation number 737 lerr = getKey('phases', phase, tr%keys); IF(lerr) RETURN !--- Phases names 738 lerr = getKey('parent', parents, tr%keys); IF(lerr) RETURN !--- Parents names 739 lerr = getKey('type', dType, tr%keys); IF(lerr) RETURN !--- Tracers types ('tracer' or 'tag') 692 740 DO iq = 1, nq !--- GET THE NUMBER OF TRACERS 693 IF(tr(iq)%iGeneration /= 0) CYCLE !--- Only deal with generation 0 tracers 694 nc = COUNT(tr(:)%gen0Name==tr(iq)%name .AND. tr%iGeneration/=0) !--- Number of children of tr(iq) 695 tr(iq)%phase = fgetKey(iq, 'phases', tr(:)%keys) !--- Phases list of tr(iq) 696 np = LEN_TRIM(tr(iq)%phase) !--- Number of phases of tr(iq) 741 IF(iGen(iq) /= 0) CYCLE !--- Only deal with generation 0 tracers 742 nc = COUNT(gen0N == tname(iq) .AND. iGen /= 0) !--- Number of children of tr(iq) 743 np = LEN_TRIM(phase(iq)) !--- Number of phases of tr(iq) 697 744 nt = nt + (1+nc) * np !--- Number of tracers after expansion 698 745 END DO … … 700 747 it = 1 !--- Current "ttr(:)" index 701 748 DO iq = 1, nq !--- Loop on "tr(:)" indexes 702 lTag = tr(iq)%type=='tag'!--- Current tracer is a tag703 i0 = strFind(t r(:)%name, TRIM(tr(iq)%gen0Name), n)!--- Indexes of first generation ancestor copies704 np = SUM([( LEN_TRIM( tr(i0(i))%phase),i=1,n )], 1)!--- Number of phases for current tracer tr(iq)705 lExt = np >1!--- Phase suffix only required if phases number is > 1706 IF(lTag) lExt = lExt .AND. tr(iq)%iGeneration>0!--- No phase suffix for generation 0 tags707 DO i =1,n!=== LOOP ON GENERATION 0 ANCESTORS749 lTag = dType(iq)=='tag' !--- Current tracer is a tag 750 i0 = strFind(tname, TRIM(gen0N(iq)), n) !--- Indexes of first generation ancestor copies 751 np = SUM([( LEN_TRIM(phase(i0(i))), i = 1, n )], 1) !--- Number of phases for current tracer tr(iq) 752 lExt = np > 1 !--- Phase suffix only required if phases number is > 1 753 IF(lTag) lExt = lExt .AND. iGen(iq) > 0 !--- No phase suffix for generation 0 tags 754 DO i = 1, n !=== LOOP ON GENERATION 0 ANCESTORS 708 755 jq = i0(i) !--- tr(jq): ith tracer with same gen 0 ancestor as tr(iq) 709 IF( tr(iq)%iGeneration==0) jq=iq!--- Generation 0: count the current tracer phases only710 pha = tr(jq)%phase!--- Phases list for tr(jq)756 IF(iGen(iq) == 0) jq = iq !--- Generation 0: count the current tracer phases only 757 pha = phase(jq) !--- Phases list for tr(jq) 711 758 DO ip = 1, LEN_TRIM(pha) !=== LOOP ON PHASES LISTS 712 759 p = pha(ip:ip) 713 tname = TRIM(tr(iq)%name); nam = tname!--- Tracer name (regular case)714 IF(lTag) nam = TRIM( tr(iq)%parent)!--- Parent name (tagging case)760 nam = tname(iq) !--- Tracer name (regular case) 761 IF(lTag) nam = TRIM(parents(iq)) !--- Parent name (tagging case) 715 762 IF(lExt) nam = addPhase(nam, p ) !--- Phase extension needed 716 IF(lTag) nam = TRIM(nam)//'_'//TRIM(tname )!--- <parent>_<name> for tags763 IF(lTag) nam = TRIM(nam)//'_'//TRIM(tname(iq)) !--- <parent>_<name> for tags 717 764 ttr(it) = tr(iq) !--- Same <key>=<val> pairs 718 765 ttr(it)%name = TRIM(nam) !--- Name with possibly phase suffix 719 766 ttr(it)%keys%name = TRIM(nam) !--- Name inside the keys decriptor 720 767 ttr(it)%phase = p !--- Single phase entry 721 CALL addKey_1('name', nam, ttr(it)%keys) 722 CALL addKey_1('phase', p, ttr(it)%keys) 723 IF(lExt .AND. tr(iq)%iGeneration>0) THEN 724 ttr(it)%parent = addPhase(tr(iq)%parent, p) 725 ttr(it)%gen0Name = addPhase(tr(iq)%gen0Name, p) 726 CALL addKey_1('parent', ttr(it)%parent, ttr(it)%keys) 727 CALL addKey_1('gen0Name', ttr(it)%gen0Name, ttr(it)%keys) 768 CALL addKey('name', nam, ttr(it)%keys) 769 CALL addKey('phase', p, ttr(it)%keys) 770 IF(lExt) THEN 771 parent = parents(iq); IF(iGen(iq) > 0) parent = addPhase(parent, p) 772 gen0Nm = gen0N(iq); IF(iGen(iq) > 0) gen0Nm = addPhase(gen0Nm, p) 773 ttr(it)%parent = parent 774 ttr(it)%gen0Name = gen0Nm 775 CALL addKey('parent', parent, ttr(it)%keys) 776 CALL addKey('gen0Name', gen0Nm, ttr(it)%keys) 728 777 END IF 729 778 it = it+1 730 779 END DO 731 IF( tr(iq)%iGeneration==0) EXIT!--- Break phase loop for gen 0780 IF(iGen(iq) == 0) EXIT !--- Break phase loop for gen 0 732 781 END DO 733 782 END DO … … 735 784 CALL delKey(['phases'],tr) !--- Remove few keys entries 736 785 737 END SUBROUTINEexpandPhases786 END FUNCTION expandPhases 738 787 !============================================================================================================================== 739 788 … … 748 797 ! TO BE ADDED IF NECESSARY: HIGHER MOMENTS AT THE END 749 798 !------------------------------------------------------------------------------------------------------------------------------ 750 TYPE(trac_type), ALLOCATABLE, INTENT(INOUT) :: tr(:) !--- Tracer derived type vector 751 !------------------------------------------------------------------------------------------------------------------------------ 752 TYPE(trac_type), ALLOCATABLE :: tr2(:) 753 INTEGER, ALLOCATABLE :: iy(:), iz(:) 754 INTEGER :: ig, ng, iq, jq, ip, nq, n, ix(SIZE(tr)), k 799 TYPE(trac_type), INTENT(INOUT) :: tr(:) !--- Tracer derived type vector 800 !------------------------------------------------------------------------------------------------------------------------------ 801 TYPE(trac_type), ALLOCATABLE :: tr2(:) 802 INTEGER, ALLOCATABLE :: iy(:), iz(:) 803 INTEGER, ALLOCATABLE :: iGen(:) 804 CHARACTER(LEN=maxlen), ALLOCATABLE :: tname(:), gen0N(:) 805 INTEGER :: ig, ng, iq, jq, ip, nq, n, ix(SIZE(tr)), k 806 LOGICAL :: lerr 755 807 ! tr2 is introduced in order to cope with a bug in gfortran 4.8.5 compiler 756 808 !------------------------------------------------------------------------------------------------------------------------------ 809 lerr = getKey('iGeneration', iGen, tr%keys); IF(lerr) RETURN !--- Generation number 757 810 nq = SIZE(tr) 758 811 DO ip = nphases, 1, -1 759 iq = strIdx(tr(:)%name, addPhase('H2O', ip)) 812 lerr = getKey('name', tname, tr%keys); IF(lerr) RETURN !--- Names of the tracers of first generation 813 iq = strIdx(tname, addPhase('H2O', ip)) 760 814 IF(iq == 0) CYCLE 761 815 tr2 = tr(:) … … 764 818 IF(lSortByGen) THEN 765 819 iq = 1 766 ng = MAXVAL( tr(:)%iGeneration, MASK=.TRUE., DIM=1)!--- Number of generations820 ng = MAXVAL(iGen, MASK=.TRUE., DIM=1) !--- Number of generations 767 821 DO ig = 0, ng !--- Loop on generations 768 iy = PACK([(k, k=1, nq)], MASK= tr(:)%iGeneration==ig)!--- Generation ig tracers indexes822 iy = PACK([(k, k=1, nq)], MASK=iGen(:) == ig) !--- Generation ig tracers indexes 769 823 n = SIZE(iy) 770 824 ix(iq:iq+n-1) = iy !--- Stack growing generations idxs … … 772 826 END DO 773 827 ELSE 774 iq = 1828 lerr = getKey('gen0Name', gen0N, tr%keys); IF(lerr) RETURN !--- Names of the tracers iq = 1 775 829 DO jq = 1, nq !--- Loop on generation 0 tracers 776 IF( tr(jq)%iGeneration /= 0) CYCLE!--- Skip generations /= 0830 IF(iGen(jq) /= 0) CYCLE !--- Skip generations /= 0 777 831 ix(iq) = jq !--- Generation 0 ancestor index first 778 832 iq = iq + 1 !--- Next "iq" for next generations tracers 779 iy = strFind( tr(:)%gen0Name, TRIM(tr(jq)%name)) !--- Indexes of "tr(jq)" children in "tr(:)"780 ng = MAXVAL( tr(iy)%iGeneration, MASK=.TRUE., DIM=1)!--- Number of generations of the "tr(jq)" family833 iy = strFind(gen0N(:), TRIM(tname(jq))) !--- Indices of "tr(jq)" children in "tr(:)" 834 ng = MAXVAL(iGen(iy), MASK=.TRUE., DIM=1) !--- Number of generations of the "tr(jq)" family 781 835 DO ig = 1, ng !--- Loop on generations of the "tr(jq)" family 782 iz = find( tr(iy)%iGeneration, ig, n) !--- Indexes of the tracers "tr(iy(:))" of generation "ig"836 iz = find(iGen(iy), ig, n) !--- Indices of the tracers "tr(iy(:))" of generation "ig" 783 837 ix(iq:iq+n-1) = iy(iz) !--- Same indexes in "tr(:)" 784 838 iq = iq + n … … 796 850 TYPE(trac_type), ALLOCATABLE, INTENT(OUT) :: tr(:) 797 851 TYPE(trac_type), POINTER :: t1(:), t2(:) 852 TYPE(keys_type), POINTER :: k1(:), k2(:) 798 853 INTEGER, ALLOCATABLE :: ixct(:), ixck(:) 799 INTEGER :: is, k1,k2, nk2, i1, i2, nt2854 INTEGER :: is, ik, ik1, ik2, nk2, i1, i2, nt2 800 855 CHARACTER(LEN=maxlen) :: s1, v1, v2, tnam, knam, modname 856 CHARACTER(LEN=maxlen), ALLOCATABLE :: keys(:), n1(:), n2(:) 801 857 modname = 'mergeTracers' 802 858 lerr = .FALSE. 803 t1 => sections(1)%trac(:) !--- Alias: first tracers section 859 keys = ['parent ', 'type ', 'iGeneration'] !--- Mandatory keys 860 t1 => sections(1)%trac(:); k1 => t1(:)%keys !--- Alias: first tracers section, corresponding keys 861 lerr = getKey('name', n1, k1); IF(lerr) RETURN !--- Names of the tracers 804 862 tr = t1 805 863 !---------------------------------------------------------------------------------------------------------------------------- … … 807 865 !---------------------------------------------------------------------------------------------------------------------------- 808 866 t2 => sections(is)%trac(:) !--- Alias: current tracers section 867 k2 => t2(:)%keys 868 lerr = getKey('name', n2, k2); IF(lerr) RETURN !--- Names of the tracers 809 869 nt2 = SIZE(t2(:), DIM=1) !--- Number of tracers in section 810 ixct = strIdx( t1(:)%name, t2(:)%name)!--- Indexes of common tracers870 ixct = strIdx(n1(:), n2(:)) !--- Indexes of common tracers 811 871 tr = [tr, PACK(t2, MASK= ixct==0)] !--- Append with new tracers 812 872 IF( ALL(ixct == 0) ) CYCLE !--- No common tracers => done 813 873 CALL msg('Tracers defined in previous sections and duplicated in "'//TRIM(sections(is)%name)//'":', modname) 814 CALL msg( t1(PACK(ixct, MASK = ixct/=0))%name, modname, nmax=128)!--- Display duplicates (the 128 first at most)874 CALL msg(n1(PACK(ixct, MASK = ixct/=0)), modname, nmax=128) !--- Display duplicates (the 128 first at most) 815 875 !-------------------------------------------------------------------------------------------------------------------------- 816 876 DO i2=1,nt2; tnam = TRIM(t2(i2)%name) !=== LOOP ON COMMON TRACERS … … 820 880 !=== CHECK WETHER ESSENTIAL KEYS ARE IDENTICAL OR NOT 821 881 s1=' of "'//TRIM(tnam)//'" in "'//TRIM(sections(is)%name)//'" not matching previous value' 822 823 IF(test(fmsg('Parent name'//TRIM(s1), modname, t1(i1)%parent /= t2(i2)%parent), lerr)) RETURN824 IF(test(fmsg('Type' //TRIM(s1), modname, t1(i1)%type /= t2(i2)%type), lerr)) RETURN825 IF(test(fmsg('Generation' //TRIM(s1), modname, t1(i1)%iGeneration /= t2(i2)%iGeneration), lerr)) RETURN826 827 !=== APPEND <key>=<val> PAIRS NOT PREVIOULSLY DEFINED 828 nk2 = SIZE(t2(i2)%keys%key(:)) !--- Keys number in current section829 ixck = strIdx(t1(i1)%keys%key(:), t2(i2)%keys%key(:)) !--- Common keys indexes830 831 ! === APPEND NEW KEYS882 DO ik = 1, SIZE(keys) 883 lerr = getKey(keys(ik), v1, i1, k1) 884 lerr = getKey(keys(ik), v2, i2, k2) 885 lerr = v1 /= v2; IF(fmsg(TRIM(keys(ik))//TRIM(s1), modname, lerr)) RETURN 886 END DO 887 888 !=== GET THE INDICES IN tr(i2)%keys%key(:) OF THE KEYS ALSO PRESENT IN tr(i1)%keys%key(:) 889 nk2 = SIZE(k2(i2)%key(:)) !--- Keys number in current section 890 ixck = strIdx(k1(i1)%key(:), k2(i2)%key(:)) !--- Common keys indexes 891 !--- APPEND THE NEW KEYS PAIRS IN tr(i1)%keys%key(:) 832 892 tr(i1)%keys%key = [ tr(i1)%keys%key, PACK(tr(i2)%keys%key, MASK = ixck==0)] 833 893 tr(i1)%keys%val = [ tr(i1)%keys%val, PACK(tr(i2)%keys%val, MASK = ixck==0)] 834 894 835 !--- KEEP TRACK OF THE COMPONENTS NAMES 836 tr(i1)%component = TRIM(tr(i1)%component)//','//TRIM(tr(i2)%component) 837 838 !--- SELECT COMMON TRACERS WITH DIFFERING KEYS VALUES (PREVIOUS VALUE IS KEPT) 839 DO k2=1,nk2 840 k1 = ixck(k2); IF(k1 == 0) CYCLE 841 IF(t1(i1)%keys%val(k1) == t2(i2)%keys%val(k2)) ixck(k2)=0 895 !=== KEEP TRACK OF THE COMPONENTS NAMES: COMA-SEPARATED LIST 896 lerr = getKey('component', v1, i1, k1) 897 lerr = getKey('component', v2, i2, k2) 898 tr(i1)%component = TRIM(v1)//','//TRIM(v2) 899 CALL addKey('component', TRIM(v1)//','//TRIM(v2), tr(i1)%keys) 900 901 !=== FOR TRACERS COMMON TO PREVIOUS AND CURRENT SECTIONS: CHECK WETHER SOME KEYS HAVE DIFFERENT VALUES ; KEEP OLD ONE 902 DO ik2 = 1, nk2 !--- Collect the corresponding indices 903 ik1 = ixck(ik2); IF(ik1 == 0) CYCLE 904 IF(k1(i1)%val(ik1) == k2(i2)%val(ik2)) ixck(ik2)=0 842 905 END DO 843 IF(ALL(ixck==0)) CYCLE !--- No identical keys with /=values 844 845 !--- DISPLAY INFORMATION: OLD VALUES ARE KEPT FOR THE KEYS FOUND IN PREVIOUS AND CURRENT SECTIONS 846 CALL msg('Key(s)'//TRIM(s1), modname) 847 DO k2 = 1, nk2 !--- Loop on keys found in both t1(:) and t2(:) 848 knam = t2(i2)%keys%key(k2) !--- Name of the current key 849 k1 = ixck(k2) !--- Corresponding index in t1(:) 850 IF(k1 == 0) CYCLE !--- New keys are skipped 851 v1 = t1(i1)%keys%val(k1); v2 = t2(i2)%keys%val(k2) !--- Key values in t1(:) and t2(:) 906 IF(ALL(ixck==0)) CYCLE !--- No identical keys with /=values => nothing to display 907 CALL msg('Key(s)'//TRIM(s1), modname) !--- Display the keys with /=values (names list) 908 DO ik2 = 1, nk2 !--- Loop on keys found in both t1(:) and t2(:) 909 knam = k2(i2)%key(ik2) !--- Name of the current key 910 ik1 = ixck(ik2) !--- Corresponding index in t1(:) 911 IF(ik1 == 0) CYCLE !--- New keys are skipped 912 v1 = k1(i1)%val(ik1); v2 = k2(i2)%val(ik2) !--- Key values in t1(:) and t2(:) 852 913 CALL msg(' * '//TRIM(knam)//'='//TRIM(v2)//' ; previous value kept:'//TRIM(v1), modname) 853 914 END DO … … 862 923 863 924 !============================================================================================================================== 864 LOGICAL FUNCTION cumulTracers(sections, tr ) RESULT(lerr)925 LOGICAL FUNCTION cumulTracers(sections, tr, lRename) RESULT(lerr) 865 926 TYPE(dataBase_type), TARGET, INTENT(IN) :: sections(:) 866 927 TYPE(trac_type), ALLOCATABLE, INTENT(OUT) :: tr(:) 867 TYPE(trac_type), POINTER :: t(:) 868 INTEGER, ALLOCATABLE :: nt(:) 869 CHARACTER(LEN=maxlen) :: tnam, tnam_new 870 INTEGER :: iq, nq, is, ns, nsec 871 lerr = .FALSE. !--- Can't fail ; kept to match "mergeTracer" interface. 872 nsec = SIZE(sections) 873 tr = [( sections(is)%trac(:) , is=1, nsec )] !--- Concatenated tracers vector 874 nt = [( SIZE(sections(is)%trac(:)), is=1, nsec )] !--- Number of tracers in each section 928 LOGICAL, OPTIONAL, INTENT(IN) :: lRename !--- .TRUE.: add a section suffix to identical names 929 CHARACTER(LEN=maxlen) :: tnam_new, modname 930 CHARACTER(LEN=maxlen), ALLOCATABLE :: tname(:), parent(:), comp(:) 931 INTEGER :: iq, jq, is 932 modname = 'cumulTracers' 933 lerr = .FALSE. 934 tr = [( sections(is)%trac(:), is = 1, SIZE(sections) )] !--- Concatenated tracers vector 935 IF(PRESENT(lRename)) THEN; IF(lRename) RETURN; END IF !--- No renaming: finished 936 lerr = getKey('name', tname, tr%keys); IF(lerr) RETURN !--- Names 937 lerr = getKey('parent', parent, tr%keys); IF(lerr) RETURN !--- Parents 938 lerr = getKey('component', comp, tr%keys); IF(lerr) RETURN !--- Component name 875 939 !---------------------------------------------------------------------------------------------------------------------------- 876 DO i s=1, nsec !=== LOOP ON SECTIONS940 DO iq = 1, SIZE(tr); IF(COUNT(tname == tname(iq)) == 1) CYCLE !=== LOOP ON TRACERS 877 941 !---------------------------------------------------------------------------------------------------------------------------- 878 t => sections(is)%trac(:) 942 tnam_new = TRIM(tname(iq))//'_'//TRIM(comp(iq)) !--- Same with section extension 943 CALL addKey('name', tnam_new, tr(iq)%keys) !--- Modify tracer name 944 tr(iq)%name = TRIM(tnam_new) !--- Modify tracer name 879 945 !-------------------------------------------------------------------------------------------------------------------------- 880 DO iq=1, nt(is) !=== LOOP ON TRACERS946 DO jq = 1, SIZE(tr); IF(parent(jq) /= tname(iq)) CYCLE !=== LOOP ON TRACERS PARENTS 881 947 !-------------------------------------------------------------------------------------------------------------------------- 882 tnam = TRIM(t(iq)%name) !--- Original name 883 IF(COUNT(t%name == tnam) == 1) CYCLE !--- Current tracer is not duplicated: finished 884 tnam_new = TRIM(tnam)//'_'//TRIM(sections(is)%name) !--- Same with section extension 885 nq = SUM(nt(1:is-1)) !--- Number of tracers in previous sections 886 ns = nt(is) !--- Number of tracers in the current section 887 tr(iq + nq)%name = TRIM(tnam_new) !--- Modify tracer name 888 WHERE(tr(1+nq:ns+nq)%parent==tnam) tr(1+nq:ns+nq)%parent=tnam_new !--- Modify parent name 948 CALL addKey('parent', tnam_new, tr(jq)%keys) !--- Modify tracer name 949 tr(jq)%parent = TRIM(tnam_new) !--- Modify tracer name 889 950 !-------------------------------------------------------------------------------------------------------------------------- 890 951 END DO … … 896 957 !============================================================================================================================== 897 958 898 !============================================================================================================================== 899 SUBROUTINE setDirectKeys(tr) 959 960 !============================================================================================================================== 961 LOGICAL FUNCTION dispTraSection(message, sname, modname) RESULT(lerr) 962 CHARACTER(LEN=*), INTENT(IN) :: message, sname, modname 963 CHARACTER(LEN=maxlen), ALLOCATABLE :: s(:,:), n(:), tmp(:) 964 CHARACTER(LEN=maxlen) :: p 965 INTEGER :: idb, iq, nq 966 idb = strIdx(dBase(:)%name, sname); IF(idb == 0) RETURN 967 nq = SIZE(dBase(idb)%trac) 968 p = '' 969 CALL append(['iq'], .TRUE. ); IF(lerr) RETURN 970 CALL append(['name'], .TRUE. ); IF(lerr) RETURN 971 CALL append(['phases','phase '], .FALSE., 'pha'); IF(lerr) RETURN 972 CALL append(['hadv'], .TRUE. ); IF(lerr) RETURN 973 CALL append(['vadv'], .TRUE. ); IF(lerr) RETURN 974 CALL append(['parent'], .FALSE.); IF(lerr) RETURN 975 CALL append(['iGen'], .FALSE.); IF(lerr) RETURN 976 CALL msg(TRIM(message)//':', modname) 977 lerr = dispTable(p, n, s, nColMax=maxTableWidth, nHead=2, sub=modname); IF(lerr) RETURN 978 979 CONTAINS 980 981 SUBROUTINE append(nam, lMandatory, snam) 982 ! Test whether key named "nam(:)" is available. 983 ! * yes: - get its value for all species in "tmp(:)" and append table "s(:,:)" with it 984 ! - append titles list with "nam(1)" (or, if specified, "snam", usually a short name). 985 ! * no: return to calling routine with an error flag if the required key is mandatory 986 CHARACTER(LEN=*), INTENT(IN) :: nam(:) 987 LOGICAL, INTENT(IN) :: lMandatory 988 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: snam 989 INTEGER :: m 990 CHARACTER(LEN=maxlen), ALLOCATABLE :: n0(:) 991 CHARACTER(LEN=maxlen) :: nm 992 lerr = .FALSE. 993 IF(nam(1) == 'iq') THEN 994 tmp = int2str([(iq, iq=1, nq)]) 995 ELSE 996 lerr = getKey(nam, tmp, dBase(idb)%trac(:)%keys, lDisp=lMandatory) 997 END IF 998 IF(lerr) THEN; lerr = lMandatory; RETURN; END IF 999 nm = nam(1); IF(PRESENT(snam)) nm = snam 1000 p = TRIM(p)//'s' 1001 IF(ALLOCATED(s)) THEN; s = cat(s, tmp); ELSE; ALLOCATE(s(nq,1)); s(:,1) = tmp; END IF 1002 IF(ALLOCATED(n)) THEN; m = SIZE(n); ALLOCATE(n0(m+1)); n0(1:m)=n; n0(m+1)=nm; CALL MOVE_ALLOC(FROM=n0, TO=n) 1003 ELSE; n=nam(1:1); END IF 1004 END SUBROUTINE append 1005 1006 END FUNCTION dispTraSection 1007 !============================================================================================================================== 1008 1009 1010 !============================================================================================================================== 1011 !=== CREATE TRACER(S) ALIAS: SCALAR/VECTOR FROM NAME(S) OR INDICE(S) ========================================================== 1012 !============================================================================================================================== 1013 LOGICAL FUNCTION aliasTracer(tname, trac, alias) RESULT(lerr) !=== TRACER NAMED "tname" - SCALAR 1014 CHARACTER(LEN=*), INTENT(IN) :: tname 1015 TYPE(trac_type), TARGET, INTENT(IN) :: trac(:) 1016 TYPE(trac_type), POINTER, INTENT(OUT) :: alias 1017 INTEGER :: it 1018 CHARACTER(LEN=maxlen), ALLOCATABLE :: tnames(:) 1019 alias => NULL() 1020 lerr = getKey('name', tnames, trac(:)%keys) 1021 it = strIdx(tnames, tname) 1022 lerr = it /= 0; IF(.NOT.lerr) alias => trac(it) 1023 END FUNCTION aliasTracer 1024 !============================================================================================================================== 1025 LOGICAL FUNCTION trSubset_Indx(trac, idx, alias) RESULT(lerr) !=== TRACERS WITH INDICES "idx(:)" - VECTOR 1026 TYPE(trac_type), ALLOCATABLE, INTENT(IN) :: trac(:) 1027 INTEGER, INTENT(IN) :: idx(:) 1028 TYPE(trac_type), ALLOCATABLE, INTENT(OUT) :: alias(:) 1029 alias = trac(idx) 1030 lerr = indexUpdate(alias) 1031 END FUNCTION trSubset_Indx 1032 !------------------------------------------------------------------------------------------------------------------------------ 1033 LOGICAL FUNCTION trSubset_Name(trac, tname, alias) RESULT(lerr) !=== TRACERS NAMED "tname(:)" - VECTOR 1034 TYPE(trac_type), ALLOCATABLE, INTENT(IN) :: trac(:) 1035 CHARACTER(LEN=*), INTENT(IN) :: tname(:) 1036 TYPE(trac_type), ALLOCATABLE, INTENT(OUT) :: alias(:) 1037 CHARACTER(LEN=maxlen), ALLOCATABLE :: tnames(:) 1038 lerr = getKey('name', tnames, trac(:)%keys) 1039 alias = trac(strIdx(tnames, tname)) 1040 lerr = indexUpdate(alias) 1041 END FUNCTION trSubset_Name 1042 !============================================================================================================================== 1043 LOGICAL FUNCTION trSubset_gen0Name(trac, gen0Nm, alias) RESULT(lerr) !=== TRACERS OF COMMON 1st GENERATION ANCESTOR 1044 TYPE(trac_type), ALLOCATABLE, INTENT(IN) :: trac(:) 1045 CHARACTER(LEN=*), INTENT(IN) :: gen0Nm 1046 TYPE(trac_type), ALLOCATABLE, INTENT(OUT) :: alias(:) 1047 CHARACTER(LEN=maxlen), ALLOCATABLE :: gen0N(:) 1048 lerr = getKey('gen0Name', gen0N, trac(:)%keys) 1049 alias = trac(strFind(delPhase(gen0N), gen0Nm)) 1050 lerr = indexUpdate(alias) 1051 END FUNCTION trSubset_gen0Name 1052 !============================================================================================================================== 1053 1054 1055 !============================================================================================================================== 1056 !=== UPDATE THE INDEXES iqParent, iqDescend AND iGeneration IN THE TRACERS DESCRIPTOR LIST "tr" (USEFULL FOR SUBSETS) ========= 1057 !============================================================================================================================== 1058 LOGICAL FUNCTION indexUpdate(tr) RESULT(lerr) 900 1059 TYPE(trac_type), INTENT(INOUT) :: tr(:) 901 902 !--- Update %iqParent, %iqDescen, %nqDescen, %nqChildren 903 CALL indexUpdate(tr) 904 905 !--- Extract some direct-access keys 906 ! DO iq = 1, SIZE(tr) 907 ! tr(iq)%keys%<key> = getKey_prv(it, "<key>", tr%keys, <default_value> ) 908 ! END DO 909 END SUBROUTINE setDirectKeys 910 !============================================================================================================================== 911 912 !============================================================================================================================== 913 LOGICAL FUNCTION dispTraSection(message, sname, modname) RESULT(lerr) 914 CHARACTER(LEN=*), INTENT(IN) :: message, sname, modname 915 INTEGER :: idb, iq, nq 916 INTEGER, ALLOCATABLE :: hadv(:), vadv(:) 917 CHARACTER(LEN=maxlen), ALLOCATABLE :: phas(:), prnt(:) 918 TYPE(trac_type), POINTER :: tm(:) 919 lerr = .FALSE. 920 idb = strIdx(dBase(:)%name, sname); IF(idb == 0) RETURN 921 tm => dBase(idb)%trac 922 nq = SIZE(tm) 923 !--- BEWARE ! Can't use the "getKeyByName" functions yet. 924 ! Names must first include the phases for tracers defined on multiple lines. 925 hadv = str2int(fgetKeys('hadv', tm(:)%keys, '10')) 926 vadv = str2int(fgetKeys('vadv', tm(:)%keys, '10')) 927 prnt = fgetKeys('parent',tm(:)%keys, '' ) 928 IF(getKey('phases', phas, ky=tm(:)%keys)) phas = fGetKeys('phase', tm(:)%keys, 'g') 929 CALL msg(TRIM(message)//':', modname) 930 IF(ALL(prnt == 'air')) THEN 931 IF(test(dispTable('iiiss', ['iq ','hadv ','vadv ','name ','phase '], cat(tm%name, phas), & 932 cat([(iq, iq=1, nq)], hadv, vadv), nColMax=maxTableWidth, nHead=2, sub=modname), lerr)) RETURN 933 ELSE IF(ALL(tm%iGeneration == -1)) THEN 934 IF(test(dispTable('iiisss', ['iq ','hadv ','vadv ','name ','parent','phase '], cat(tm%name, prnt, phas), & 935 cat([(iq, iq=1, nq)], hadv, vadv), nColMax=maxTableWidth, nHead=2, sub=modname), lerr)) RETURN 936 ELSE 937 IF(test(dispTable('iiissis', ['iq ','hadv ','vadv ','name ','parent','igen ','phase '], cat(tm%name, prnt, phas), & 938 cat([(iq, iq=1, nq)], hadv, vadv, tm%iGeneration), nColMax=maxTableWidth, nHead=2, sub=modname), lerr)) RETURN 939 END IF 940 END FUNCTION dispTraSection 941 !============================================================================================================================== 942 943 944 !============================================================================================================================== 945 !== CREATE A SCALAR ALIAS OF THE COMPONENT OF THE TRACERS DESCRIPTOR "t" NAMED "tname" ======================================== 946 !============================================================================================================================== 947 FUNCTION aliasTracer(tname, t) RESULT(out) 948 TYPE(trac_type), POINTER :: out 949 CHARACTER(LEN=*), INTENT(IN) :: tname 950 TYPE(trac_type), TARGET, INTENT(IN) :: t(:) 951 INTEGER :: it 952 it = strIdx(t(:)%name, tname) 953 out => NULL(); IF(it /= 0) out => t(it) 954 END FUNCTION aliasTracer 955 !============================================================================================================================== 956 957 958 !============================================================================================================================== 959 !=== FROM A LIST OF INDEXES OR NAMES, CREATE A SUBSET OF THE TRACERS DESCRIPTORS LIST "trac" ================================== 960 !============================================================================================================================== 961 FUNCTION trSubset_Indx(trac,idx) RESULT(out) 962 TYPE(trac_type), ALLOCATABLE :: out(:) 963 TYPE(trac_type), ALLOCATABLE, INTENT(IN) :: trac(:) 964 INTEGER, INTENT(IN) :: idx(:) 965 out = trac(idx) 966 CALL indexUpdate(out) 967 END FUNCTION trSubset_Indx 968 !------------------------------------------------------------------------------------------------------------------------------ 969 FUNCTION trSubset_Name(trac,nam) RESULT(out) 970 TYPE(trac_type), ALLOCATABLE :: out(:) 971 TYPE(trac_type), ALLOCATABLE, INTENT(IN) :: trac(:) 972 CHARACTER(LEN=*), INTENT(IN) :: nam(:) 973 out = trac(strIdx(trac(:)%name, nam)) 974 CALL indexUpdate(out) 975 END FUNCTION trSubset_Name 976 !============================================================================================================================== 977 978 979 !============================================================================================================================== 980 !=== CREATE THE SUBSET OF THE TRACERS DESCRIPTORS LIST "trac" HAVING THE FIRST GENERATION ANCESTOR NAMED "nam" ================ 981 !============================================================================================================================== 982 FUNCTION trSubset_gen0Name(trac,nam) RESULT(out) 983 TYPE(trac_type), ALLOCATABLE :: out(:) 984 TYPE(trac_type), ALLOCATABLE, INTENT(IN) :: trac(:) 985 CHARACTER(LEN=*), INTENT(IN) :: nam 986 out = trac(strFind(delPhase(trac(:)%gen0Name), nam)) 987 CALL indexUpdate(out) 988 END FUNCTION trSubset_gen0Name 989 !============================================================================================================================== 990 991 992 !============================================================================================================================== 993 !=== UPDATE THE INDEXES iqParent, iqDescend AND iGeneration IN THE TRACERS DESCRIPTOR LIST "tr" (USEFULL FOR SUBSETS) ========= 994 !============================================================================================================================== 995 SUBROUTINE indexUpdate(tr) 996 TYPE(trac_type), INTENT(INOUT) :: tr(:) 997 INTEGER :: iq, ig, igen, ngen, ix(SIZE(tr)) 998 tr(:)%iqParent = strIdx( tr(:)%name, tr(:)%parent ) !--- Parent index 999 DO iq = 1, SIZE(tr); CALL addKey_1('iqParent', int2str(tr(iq)%iqParent), tr(iq)%keys); END DO 1000 ngen = MAXVAL(tr(:)%iGeneration, MASK=.TRUE.) 1001 DO iq = 1, SIZE(tr) 1002 ig = tr(iq)%iGeneration 1003 IF(ALLOCATED(tr(iq)%iqDescen)) DEALLOCATE(tr(iq)%iqDescen) 1004 ALLOCATE(tr(iq)%iqDescen(0)) 1005 CALL idxAncestor(tr, ix, ig) !--- Ancestor of generation "ng" for each tr 1006 DO igen = ig+1, ngen 1007 tr(iq)%iqDescen = [tr(iq)%iqDescen, find(ix==iq .AND. tr%iGeneration==igen)] 1008 tr(iq)%nqDescen = SIZE(tr(iq)%iqDescen) 1009 IF(igen == ig+1) THEN 1010 tr(iq)%nqChildren = tr(iq)%nqDescen 1011 CALL addKey_1('nqChildren', int2str(tr(iq)%nqChildren), tr(iq)%keys) 1012 END IF 1060 INTEGER :: iq, jq, nq, ig, nGen 1061 INTEGER, ALLOCATABLE :: iqDescen(:), ix(:), iy(:) 1062 CHARACTER(LEN=maxlen), ALLOCATABLE :: tnames(:), parent(:) 1063 INTEGER, DIMENSION(SIZE(tr)) :: iqParent, iGen 1064 lerr = getKey('name', tnames, tr%keys); IF(lerr) RETURN !--- Names 1065 lerr = getKey('parent', parent, tr%keys); IF(lerr) RETURN !--- Parents 1066 nq = SIZE(tr) 1067 1068 !=== iqParent, iGeneration 1069 DO iq = 1, nq; iGen(iq) = 0; jq = iq 1070 iqParent(iq) = strIdx(tnames, parent(iq)) 1071 DO; jq = strIdx(tnames, parent(jq)); IF(jq == 0) EXIT; iGen(iq) = iGen(iq) + 1; END DO 1072 CALL addKey('iqParent', parent(iq), tr(iq)%keys) 1073 CALL addKey('iqGeneration', iGen(iq), tr(iq)%keys) 1074 END DO 1075 1076 !=== nqChildren, iqDescen, nqDescen 1077 nGen = MAXVAL(iGen, MASK=.TRUE.) 1078 DO iq = 1, nq 1079 ix = [iq]; ALLOCATE(iqDescen(0)) 1080 DO ig = iGen(iq)+1, nGen 1081 iy = find(iqParent, ix); iqDescen = [iqDescen, iy]; ix = iy 1082 IF(ig /= iGen(iq)+1) CYCLE 1083 CALL addKey('nqChildren', SIZE(iqDescen), tr(iq)%keys) 1084 tr(iq)%nqChildren = SIZE(iqDescen) 1013 1085 END DO 1014 CALL addKey_1('iqDescen', strStack(int2str(tr(iq)%iqDescen)), tr(iq)%keys) 1015 CALL addKey_1('nqDescen', int2str(tr(iq)%nqDescen) , tr(iq)%keys) 1086 CALL addKey('iqDescen', strStack(int2str(iqDescen)), tr(iq)%keys) 1087 CALL addKey('nqDescen', SIZE(iqDescen), tr(iq)%keys) 1088 tr(iq)%iqDescen = iqDescen 1089 tr(iq)%nqDescen = SIZE(iqDescen) 1090 DEALLOCATE(iqDescen) 1016 1091 END DO 1017 END SUBROUTINEindexUpdate1092 END FUNCTION indexUpdate 1018 1093 !============================================================================================================================== 1019 1094 … … 1024 1099 !=== * For each isotopes class, the <key>=<val> vector of each tracer is moved into the isotopes descriptor "isot" ==== 1025 1100 !=== NOTES: ==== 1026 !=== * Most of the "isot" components have been defined in the calling routine ( readIsotopes):====1101 !=== * Most of the "isot" components have been defined in the calling routine (processIsotopes): ==== 1027 1102 !=== parent, nzone, zone(:), niso, keys(:)%name, ntiso, trac(:), nphas, phas, iqIsoPha(:,:), itZonPhi(:,:) ==== 1028 1103 !=== * Same syntax for isotopes file and "tracer.def": a tracers section contains one line for each of its isotopes ==== … … 1032 1107 !=== * The routine gives an error if a required isotope is not available in the database stored in "fnam" ==== 1033 1108 !============================================================================================================================== 1034 LOGICAL FUNCTION readIsotopesFile _prv(fnam, isot) RESULT(lerr)1109 LOGICAL FUNCTION readIsotopesFile(fnam, isot) RESULT(lerr) 1035 1110 CHARACTER(LEN=*), INTENT(IN) :: fnam !--- Input file name 1036 1111 TYPE(isot_type), TARGET, INTENT(INOUT) :: isot(:) !--- Isotopes descriptors (field %parent must be defined!) … … 1049 1124 !--- READ THE FILE SECTIONS, ONE EACH PARENT TRACER 1050 1125 nb0 = SIZE(dBase, DIM=1)+1 !--- Next database element index 1051 IF(test(readSections(fnam,strStack(isot(:)%parent,'|')),lerr)) RETURN !--- Read sections, one each parent tracer1126 lerr = readSections(fnam,strStack(isot(:)%parent,'|')); IF(lerr) RETURN !--- Read sections, one each parent tracer 1052 1127 ndb = SIZE(dBase, DIM=1) !--- Current database size 1053 1128 DO idb = nb0, ndb … … 1067 1142 is = strIdx(isot(iis)%keys(:)%name, t%name) !--- Index in "isot(iis)%keys(:)%name" of isotope "t%name" 1068 1143 IF(is == 0) CYCLE 1069 IF(test(ANY(reduceExpr(t%keys%val, vals)), lerr)) RETURN!--- Reduce expressions ; detect non-numerical elements1144 lerr = ANY(reduceExpr(t%keys%val, vals)); IF(lerr) RETURN !--- Reduce expressions ; detect non-numerical elements 1070 1145 isot(iis)%keys(is)%key = t%keys%key 1071 1146 isot(iis)%keys(is)%val = vals … … 1073 1148 1074 1149 !--- CHECK FOR MISSING ISOTOPES (NO KEYS ALLOCATED) 1075 IF(test(checkList(isot(iis)%keys(:)%name, .NOT.[( ALLOCATED(isot(iis)%keys(is)%key), is=1, SIZE(isot(iis)%keys) )], & 1076 'Check file "'//TRIM(fnam)//'" in section "'//TRIM(dBase(idb)%name)//'"', 'isotopes', 'missing'), lerr)) RETURN 1150 lerr = checkList(isot(iis)%keys(:)%name, .NOT.[( ALLOCATED(isot(iis)%keys(is)%key), is=1, SIZE(isot(iis)%keys) )], & 1151 'Check file "'//TRIM(fnam)//'" in section "'//TRIM(dBase(idb)%name)//'"', 'isotopes', 'missing') 1152 IF(lerr) RETURN 1077 1153 END DO 1078 1154 … … 1109 1185 END DO 1110 1186 END DO 1111 IF(test(fmsg('Problem with the table content', modname, dispTable(prf, ttl, val, &1112 cat([(it,it=1,nt)]), rFmt='(EN8.4)', nColMax=maxTableWidth, nHead=2, sub=modname)), lerr)) RETURN1187 lerr = dispTable(prf, ttl, val, cat([(it,it=1,nt)]), rFmt='(EN8.4)', nColMax=maxTableWidth, nHead=2, sub=modname) 1188 IF(fmsg('Problem with the table content', modname, lerr)) RETURN 1113 1189 DEALLOCATE(ttl, val) 1114 1190 END DO … … 1116 1192 !------------------------------------------------------------------------------------------------------------------------------ 1117 1193 1118 END FUNCTION readIsotopesFile _prv1194 END FUNCTION readIsotopesFile 1119 1195 !============================================================================================================================== 1120 1196 … … 1124 1200 !=== * COMPUTE MOST OF THE RELATED QUANTITIES ("isot" COMPONENTS). === 1125 1201 !=== * COMPUTE FEW ISOTOPES-DEDICATED "trac" COMPONENTS === 1126 !=== * CALL readIsotopesFile _prv TO GET PHYSICAL QUANTITIES (<key>=<val> PAIRS)===1202 !=== * CALL readIsotopesFile TO GET PHYSICAL QUANTITIES (<key>=<val> PAIRS) === 1127 1203 !=== NOTE: THIS IS DONE HERE (IN A ROUTINE CALLED BY THE DYNAMIC), BECAUSE THE DYNAMIC NEEDS FEW PHYSICAL PARAMETERS. === 1128 1204 !============================================================================================================================== 1129 LOGICAL FUNCTION readIsotopesFile(iNames) RESULT(lerr)1205 LOGICAL FUNCTION processIsotopes(iNames) RESULT(lerr) 1130 1206 CHARACTER(LEN=maxlen), TARGET, OPTIONAL, INTENT(IN) :: iNames(:) 1131 1207 CHARACTER(LEN=maxlen), ALLOCATABLE :: p(:), str(:) !--- Temporary storage 1208 CHARACTER(LEN=maxlen), ALLOCATABLE :: tname(:), parent(:), dType(:), phase(:), gen0N(:) 1132 1209 CHARACTER(LEN=maxlen) :: iName, modname 1133 1210 CHARACTER(LEN=1) :: ph !--- Phase 1211 INTEGER, ALLOCATABLE :: iGen(:) 1134 1212 INTEGER :: ic, ip, iq, it, iz 1135 1213 LOGICAL, ALLOCATABLE :: ll(:) !--- Mask 1136 1214 TYPE(trac_type), POINTER :: t(:), t1 1137 1215 TYPE(isot_type), POINTER :: i 1216 1138 1217 lerr = .FALSE. 1139 1218 modname = 'readIsotopesFile' … … 1141 1220 t => tracers 1142 1221 1222 lerr = getKey('name', tname, t%keys); IF(lerr) RETURN !--- Names 1223 lerr = getKey('parent', parent, t%keys); IF(lerr) RETURN !--- Parents 1224 lerr = getKey('type', dType, t%keys); IF(lerr) RETURN !--- Tracer type 1225 lerr = getKey('phase', phase, t%keys); IF(lerr) RETURN !--- Phase 1226 lerr = getKey('gen0Name', gen0N, t%keys); IF(lerr) RETURN !--- 1st generation ancestor name 1227 lerr = getKey('iGeneration', iGen, t%keys); IF(lerr) RETURN !--- Generation number 1228 1143 1229 !--- GET FROM "tracers" THE FULL LIST OF AVAILABLE ISOTOPES CLASSES 1144 p = PACK(delPhase( t%parent), MASK = t%type=='tracer' .AND. t%iGeneration==1)1230 p = PACK(delPhase(parent), MASK = dType=='tracer' .AND. iGen==1) 1145 1231 CALL strReduce(p, nbIso) 1146 1232 … … 1148 1234 IF(PRESENT(iNames)) THEN 1149 1235 DO it = 1, SIZE(iNames) 1150 IF(test(fmsg('No isotopes class "'//TRIM(iNames(it))//'" found among tracers', modname, ALL(p /= iNames(it))), lerr)) RETURN 1236 lerr = ALL(p /= iNames(it)) 1237 IF(fmsg('No isotopes class "'//TRIM(iNames(it))//'" found among tracers', modname, lerr)) RETURN 1151 1238 END DO 1152 1239 p = iNames; nbIso = SIZE(p) … … 1164 1251 1165 1252 !=== Isotopes children of tracer "iname": mask, names, number (same for each phase of "iname") 1166 ll = t(:)%type=='tracer' .AND. delPhase(t(:)%parent) == iname .AND. t(:)%phase == 'g'1167 str = PACK(delPhase(t (:)%name), MASK = ll)!--- Effectively found isotopes of "iname"1253 ll = dType=='tracer' .AND. delPhase(parent) == iname .AND. phase == 'g' 1254 str = PACK(delPhase(tname), MASK = ll) !--- Effectively found isotopes of "iname" 1168 1255 i%niso = SIZE(str) !--- Number of "effectively found isotopes of "iname" 1169 1256 ALLOCATE(i%keys(i%niso)) … … 1171 1258 1172 1259 !=== Geographic tagging tracers descending on tracer "iname": mask, names, number 1173 ll = t(:)%type=='tag' .AND. delPhase(t(:)%gen0Name) == iname .AND. t(:)%iGeneration == 21174 i%zone = PACK(strTail(t (:)%name,'_',.TRUE.), MASK = ll)!--- Tagging zones names for isotopes category "iname"1260 ll = dType=='tag' .AND. delPhase(gen0N) == iname .AND. iGen == 2 1261 i%zone = PACK(strTail(tname,'_',.TRUE.), MASK = ll) !--- Tagging zones names for isotopes category "iname" 1175 1262 CALL strReduce(i%zone) 1176 1263 i%nzone = SIZE(i%zone) !--- Tagging zones number for isotopes category "iname" … … 1178 1265 !=== Geographic tracers of the isotopes children of tracer "iname" (same for each phase of "iname") 1179 1266 ! NOTE: One might like to create a similar variable for 2nd generation tagging tracers (tagging the gen1 tracers) 1180 str = PACK(delPhase(t (:)%name), MASK=ll)1267 str = PACK(delPhase(tname), MASK=ll) 1181 1268 CALL strReduce(str) 1182 1269 i%ntiso = i%niso + SIZE(str) !--- Number of isotopes + their geographic tracers [ntiso] … … 1205 1292 i%iqIsoPha = RESHAPE( [( (strIdx(t%name, addPhase(i%trac(it),i%phase(ip:ip))), it=1, i%ntiso), ip=1, i%nphas)], & 1206 1293 [i%ntiso, i%nphas] ) 1294 !=== Table used to get iq (index in dyn array, size nqtot) from the water and isotope and phase indexes ; the full isotopes list 1295 ! (including tagging tracers) is sorted this way: iso1, iso2, ..., iso1_zone1, iso2_zone1, ..., iso1_zoneN, iso2_zoneN 1296 i%iqWIsoPha = RESHAPE( [( [strIdx(t%name, addPhase('H2O',i%phase(ip:ip))), i%iqIsoPha(:,ip)], ip=1,i%nphas)], & 1297 [1+i%ntiso, i%nphas] ) 1207 1298 !=== Table used to get ix (index in tagging tracers isotopes list, size ntiso) from the zone and isotope indexes 1208 1299 i%itZonIso = RESHAPE( [( (strIdx(i%trac(:), TRIM(i%trac(it))//'_'//TRIM(i%zone(iz))), iz=1, i%nzone), it=1, i%niso )], & … … 1211 1302 1212 1303 !=== READ PHYSICAL PARAMETERS FROM isoFile FILE 1213 IF(test(readIsotopesFile_prv(isoFile, isotopes), lerr)) RETURN 1304 ! lerr = readIsotopesFile(isoFile, isotopes); IF(lerr) RETURN! on commente pour ne pas chercher isotopes_params.def 1305 1306 !--- GET THE isoCheck ENTRY FROM THE *.DEF FILES (MIGHT BE CHANGED TO A CLASS-DEPENDANT KEYWORD) 1307 CALL get_in('ok_iso_verif', isoCheck, .TRUE.) 1214 1308 1215 1309 !=== CHECK CONSISTENCY 1216 IF(test(testIsotopes(), lerr)) RETURN1217 1218 !=== SELECT FIRST ISOTOPES CLASS OR, IF POSSIBLE, WATERCLASS1219 IF( .NOT.test(isoSelect(1, .TRUE.), lerr)) THEN; IF(isotope%parent == 'H2O') iH2O = ixIso; END IF1310 lerr = testIsotopes(); IF(lerr) RETURN 1311 1312 !=== SELECT WATER ISOTOPES CLASS OR, IF UNFOUND, THE FIRST ISOTOPES CLASS 1313 IF(isoSelect('H2O', .TRUE.)) THEN; iH2O = ixIso; ELSE; lerr = isoSelect(1, .TRUE.); END IF 1220 1314 1221 1315 CONTAINS … … 1224 1318 LOGICAL FUNCTION testIsotopes() RESULT(lerr) !--- MAKE SURE MEMBERS OF AN ISOTOPES FAMILY ARE PRESENT IN THE SAME PHASES 1225 1319 !------------------------------------------------------------------------------------------------------------------------------ 1226 INTEGER :: ix, it, ip, np, iz, nz 1320 INTEGER :: ix, it, ip, np, iz, nz, npha, nzon 1227 1321 TYPE(isot_type), POINTER :: i 1228 1322 DO ix = 1, nbIso 1229 1323 i => isotopes(ix) 1230 1324 !--- Check whether each isotope and tagging isotopic tracer is present in the same number of phases 1231 DO it = 1, i%ntiso 1232 np = SUM([(COUNT(tracers(:)%name == addPhase(i%trac(it), i%phase(ip:ip))), ip=1, i%nphas)]) 1233 IF(test(fmsg(TRIM(int2str(np))//' phases instead of '//TRIM(int2str(i%nphas))//' for '//TRIM(i%trac(it)), & 1234 modname, np /= i%nphas), lerr)) RETURN 1325 DO it = 1, i%ntiso; npha = i%nphas 1326 np = SUM([(COUNT(tracers(:)%name == addPhase(i%trac(it), i%phase(ip:ip))), ip=1, npha)]) 1327 lerr = np /= npha 1328 CALL msg(TRIM(int2str(np))//' phases instead of '//TRIM(int2str(npha))//' for '//TRIM(i%trac(it)), modname, lerr) 1329 IF(lerr) RETURN 1235 1330 END DO 1236 DO it = 1, i%niso 1237 nz = SUM([(COUNT(i%trac == TRIM(i%trac(it))//'_'//i%zone(iz)), iz=1, i%nzone)]) 1238 IF(test(fmsg(TRIM(int2str(nz))//' tagging zones instead of '//TRIM(int2str(i%nzone))//' for '//TRIM(i%trac(it)), & 1239 modname, nz /= i%nzone), lerr)) RETURN 1331 DO it = 1, i%niso; nzon = i%nzone 1332 nz = SUM([(COUNT(i%trac == TRIM(i%trac(it))//'_'//i%zone(iz)), iz=1, nzon)]) 1333 lerr = nz /= nzon 1334 CALL msg(TRIM(int2str(nz))//' tagging zones instead of '//TRIM(int2str(nzon))//' for '//TRIM(i%trac(it)), modname, lerr) 1335 IF(lerr) RETURN 1240 1336 END DO 1241 1337 END DO … … 1243 1339 !------------------------------------------------------------------------------------------------------------------------------ 1244 1340 1245 END FUNCTION readIsotopesFile1341 END FUNCTION processIsotopes 1246 1342 !============================================================================================================================== 1247 1343 … … 1259 1355 lV = .FALSE.; IF(PRESENT(lVerbose)) lV = lVerbose 1260 1356 iIso = strIdx(isotopes(:)%parent, iName) 1261 IF(test(iIso == 0, lerr)) THEN 1357 lerr = iIso == 0 1358 IF(lerr) THEN 1262 1359 niso = 0; ntiso = 0; nzone = 0; nphas = 0; isoCheck=.FALSE. 1263 1360 CALL msg('no isotope family named "'//TRIM(iName)//'"', ll=lV) … … 1287 1384 itZonIso => isotope%itZonIso; isoCheck = isotope%check 1288 1385 iqIsoPha => isotope%iqIsoPha 1386 iqWIsoPha => isotope%iqWIsoPha 1289 1387 END FUNCTION isoSelectByIndex 1290 1388 !============================================================================================================================== … … 1294 1392 !=== ADD THE <key>=<val> PAIR TO THE "ky[(:)]" KEY[S] DESCRIPTOR[S] OR THE <key>=<val(:)> PAIRS TO THE "ky(:)" KEYS DESCRIPTORS 1295 1393 !============================================================================================================================== 1296 SUBROUTINE addKey_ 1(key,val, ky, lOverWrite)1297 CHARACTER(LEN=*), INTENT(IN) :: key, val1394 SUBROUTINE addKey_s11(key, sval, ky, lOverWrite) 1395 CHARACTER(LEN=*), INTENT(IN) :: key, sval 1298 1396 TYPE(keys_type), INTENT(INOUT) :: ky 1299 1397 LOGICAL, OPTIONAL, INTENT(IN) :: lOverWrite … … 1305 1403 IF(.NOT.ALLOCATED(ky%key)) THEN 1306 1404 ALLOCATE(ky%key(1)); ky%key(1)=key 1307 ALLOCATE(ky%val(1)); ky%val(1)= val1405 ALLOCATE(ky%val(1)); ky%val(1)=sval 1308 1406 RETURN 1309 1407 END IF … … 1311 1409 IF(iky == 0) THEN 1312 1410 nky = SIZE(ky%key) 1313 ALLOCATE(k(nky+1)); k(1:nky) = ky%key; k(nky+1) = key; ky%key = k1314 ALLOCATE(v(nky+1)); v(1:nky) = ky%val; v(nky+1) = val; ky%val = v1411 ALLOCATE(k(nky+1)); k(1:nky) = ky%key; k(nky+1) = key; ky%key = k 1412 ALLOCATE(v(nky+1)); v(1:nky) = ky%val; v(nky+1) = sval; ky%val = v 1315 1413 ELSE IF(lo) THEN 1316 ky%key(iky) = key; ky%val(iky) = val1414 ky%key(iky) = key; ky%val(iky) = sval 1317 1415 END IF 1318 END SUBROUTINE addKey_1 1319 !============================================================================================================================== 1320 SUBROUTINE addKey_m(key, val, ky, lOverWrite) 1321 CHARACTER(LEN=*), INTENT(IN) :: key, val 1416 END SUBROUTINE addKey_s11 1417 !============================================================================================================================== 1418 SUBROUTINE addKey_i11(key, ival, ky, lOverWrite) 1419 CHARACTER(LEN=*), INTENT(IN) :: key 1420 INTEGER, INTENT(IN) :: ival 1421 TYPE(keys_type), INTENT(INOUT) :: ky 1422 LOGICAL, OPTIONAL, INTENT(IN) :: lOverWrite 1423 !------------------------------------------------------------------------------------------------------------------------------ 1424 CALL addKey_s11(key, int2str(ival), ky, lOverWrite) 1425 END SUBROUTINE addKey_i11 1426 !============================================================================================================================== 1427 SUBROUTINE addKey_r11(key, rval, ky, lOverWrite) 1428 CHARACTER(LEN=*), INTENT(IN) :: key 1429 REAL, INTENT(IN) :: rval 1430 TYPE(keys_type), INTENT(INOUT) :: ky 1431 LOGICAL, OPTIONAL, INTENT(IN) :: lOverWrite 1432 !------------------------------------------------------------------------------------------------------------------------------ 1433 CALL addKey_s11(key, real2str(rval), ky, lOverWrite) 1434 END SUBROUTINE addKey_r11 1435 !============================================================================================================================== 1436 SUBROUTINE addKey_l11(key, lval, ky, lOverWrite) 1437 CHARACTER(LEN=*), INTENT(IN) :: key 1438 LOGICAL, INTENT(IN) :: lval 1439 TYPE(keys_type), INTENT(INOUT) :: ky 1440 LOGICAL, OPTIONAL, INTENT(IN) :: lOverWrite 1441 !------------------------------------------------------------------------------------------------------------------------------ 1442 CALL addKey_s11(key, bool2str(lval), ky, lOverWrite) 1443 END SUBROUTINE addKey_l11 1444 !============================================================================================================================== 1445 !============================================================================================================================== 1446 SUBROUTINE addKey_s1m(key, sval, ky, lOverWrite) 1447 CHARACTER(LEN=*), INTENT(IN) :: key, sval 1322 1448 TYPE(keys_type), INTENT(INOUT) :: ky(:) 1323 1449 LOGICAL, OPTIONAL, INTENT(IN) :: lOverWrite 1324 1450 !------------------------------------------------------------------------------------------------------------------------------ 1325 1451 INTEGER :: itr 1326 DO itr = 1, SIZE(ky) 1327 CALL addKey_1(key, val, ky(itr), lOverWrite) 1328 END DO 1329 END SUBROUTINE addKey_m 1330 !============================================================================================================================== 1331 SUBROUTINE addKey_mm(key, val, ky, lOverWrite) 1332 CHARACTER(LEN=*), INTENT(IN) :: key, val(:) 1452 DO itr = 1, SIZE(ky); CALL addKey_s11(key, sval, ky(itr), lOverWrite); END DO 1453 END SUBROUTINE addKey_s1m 1454 !============================================================================================================================== 1455 SUBROUTINE addKey_i1m(key, ival, ky, lOverWrite) 1456 CHARACTER(LEN=*), INTENT(IN) :: key 1457 INTEGER, INTENT(IN) :: ival 1333 1458 TYPE(keys_type), INTENT(INOUT) :: ky(:) 1334 1459 LOGICAL, OPTIONAL, INTENT(IN) :: lOverWrite 1335 1460 !------------------------------------------------------------------------------------------------------------------------------ 1336 1461 INTEGER :: itr 1337 DO itr = 1, SIZE(ky); CALL addKey_1(key, val(itr), ky(itr), lOverWrite); END DO 1338 END SUBROUTINE addKey_mm 1462 DO itr = 1, SIZE(ky); CALL addKey_s11(key, int2str(ival), ky(itr), lOverWrite); END DO 1463 END SUBROUTINE addKey_i1m 1464 !============================================================================================================================== 1465 SUBROUTINE addKey_r1m(key, rval, ky, lOverWrite) 1466 CHARACTER(LEN=*), INTENT(IN) :: key 1467 REAL, INTENT(IN) :: rval 1468 TYPE(keys_type), INTENT(INOUT) :: ky(:) 1469 LOGICAL, OPTIONAL, INTENT(IN) :: lOverWrite 1470 !------------------------------------------------------------------------------------------------------------------------------ 1471 INTEGER :: itr 1472 DO itr = 1, SIZE(ky); CALL addKey_s11(key, real2str(rval), ky(itr), lOverWrite); END DO 1473 END SUBROUTINE addKey_r1m 1474 !============================================================================================================================== 1475 SUBROUTINE addKey_l1m(key, lval, ky, lOverWrite) 1476 CHARACTER(LEN=*), INTENT(IN) :: key 1477 LOGICAL, INTENT(IN) :: lval 1478 TYPE(keys_type), INTENT(INOUT) :: ky(:) 1479 LOGICAL, OPTIONAL, INTENT(IN) :: lOverWrite 1480 !------------------------------------------------------------------------------------------------------------------------------ 1481 INTEGER :: itr 1482 DO itr = 1, SIZE(ky); CALL addKey_s11(key, bool2str(lval), ky(itr), lOverWrite); END DO 1483 END SUBROUTINE addKey_l1m 1484 !============================================================================================================================== 1485 !============================================================================================================================== 1486 SUBROUTINE addKey_smm(key, sval, ky, lOverWrite) 1487 CHARACTER(LEN=*), INTENT(IN) :: key, sval(:) 1488 TYPE(keys_type), INTENT(INOUT) :: ky(:) 1489 LOGICAL, OPTIONAL, INTENT(IN) :: lOverWrite 1490 !------------------------------------------------------------------------------------------------------------------------------ 1491 INTEGER :: itr 1492 DO itr = 1, SIZE(ky); CALL addKey_s11(key, sval(itr), ky(itr), lOverWrite); END DO 1493 END SUBROUTINE addKey_smm 1494 !============================================================================================================================== 1495 SUBROUTINE addKey_imm(key, ival, ky, lOverWrite) 1496 CHARACTER(LEN=*), INTENT(IN) :: key 1497 INTEGER, INTENT(IN) :: ival(:) 1498 TYPE(keys_type), INTENT(INOUT) :: ky(:) 1499 LOGICAL, OPTIONAL, INTENT(IN) :: lOverWrite 1500 !------------------------------------------------------------------------------------------------------------------------------ 1501 INTEGER :: itr 1502 DO itr = 1, SIZE(ky); CALL addKey_s11(key, int2str(ival(itr)), ky(itr), lOverWrite); END DO 1503 END SUBROUTINE addKey_imm 1504 !============================================================================================================================== 1505 SUBROUTINE addKey_rmm(key, rval, ky, lOverWrite) 1506 CHARACTER(LEN=*), INTENT(IN) :: key 1507 REAL, INTENT(IN) :: rval(:) 1508 TYPE(keys_type), INTENT(INOUT) :: ky(:) 1509 LOGICAL, OPTIONAL, INTENT(IN) :: lOverWrite 1510 !------------------------------------------------------------------------------------------------------------------------------ 1511 INTEGER :: itr 1512 DO itr = 1, SIZE(ky); CALL addKey_s11(key, real2str(rval(itr)), ky(itr), lOverWrite); END DO 1513 END SUBROUTINE addKey_rmm 1514 !============================================================================================================================== 1515 SUBROUTINE addKey_lmm(key, lval, ky, lOverWrite) 1516 CHARACTER(LEN=*), INTENT(IN) :: key 1517 LOGICAL, INTENT(IN) :: lval(:) 1518 TYPE(keys_type), INTENT(INOUT) :: ky(:) 1519 LOGICAL, OPTIONAL, INTENT(IN) :: lOverWrite 1520 !------------------------------------------------------------------------------------------------------------------------------ 1521 INTEGER :: itr 1522 DO itr = 1, SIZE(ky); CALL addKey_s11(key, bool2str(lval(itr)), ky(itr), lOverWrite); END DO 1523 END SUBROUTINE addKey_lmm 1339 1524 !============================================================================================================================== 1340 1525 … … 1353 1538 DO ik = 1, SIZE(t(jd)%keys%key) 1354 1539 CALL get_in(t(jd)%keys%key(ik), val, '*none*') 1355 IF(val /= '*none*') CALL addKey _1(t(jd)%keys%key(ik), val, t(jd)%keys, .TRUE.)1540 IF(val /= '*none*') CALL addKey(t(jd)%keys%key(ik), val, t(jd)%keys, .TRUE.) 1356 1541 END DO 1357 1542 END SUBROUTINE addKeysFromDef … … 1387 1572 1388 1573 !============================================================================================================================== 1389 !================ GET THE VALUE OF A KEY FROM A "keys_type" DERIVED TYPE ; THE RESULT IS THE RETURNED VALUE =================== 1390 !============================================================================================================================== 1391 CHARACTER(LEN=maxlen) FUNCTION fgetKeyIdx_s1(itr, keyn, ky, def_val, lerr) RESULT(val) 1574 !=== INTERNAL FUNCTION: GET THE VALUE OF A KEY FOR "itr"th TRACER FROM A "keys_type" DERIVED TYPE AND RETURN THE RESULT === 1575 !=== IF keyn CONTAINS SEVERAL ELEMENTS, TRY WITH EACH ELEMENT ONE AFTER THE OTHER === 1576 !============================================================================================================================== 1577 CHARACTER(LEN=maxlen) FUNCTION fgetKeyIdx(itr, keyn, ky, lerr) RESULT(val) 1392 1578 INTEGER, INTENT(IN) :: itr 1393 CHARACTER(LEN=*), INTENT(IN) :: keyn 1579 CHARACTER(LEN=*), INTENT(IN) :: keyn(:) 1394 1580 TYPE(keys_type), INTENT(IN) :: ky(:) 1395 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: def_val1396 1581 LOGICAL, OPTIONAL, INTENT(OUT) :: lerr 1397 1582 !------------------------------------------------------------------------------------------------------------------------------ 1583 INTEGER :: ik 1584 LOGICAL :: ler 1585 ler = .TRUE. 1586 DO ik = 1, SIZE(keyn) 1587 CALL getKeyIdx(keyn(ik)); IF(.NOT.ler) EXIT 1588 END DO 1589 IF(PRESENT(lerr)) lerr = ler 1590 1591 CONTAINS 1592 1593 SUBROUTINE getKeyIdx(keyn) 1594 CHARACTER(LEN=*), INTENT(IN) :: keyn 1595 !------------------------------------------------------------------------------------------------------------------------------ 1398 1596 INTEGER :: iky 1399 LOGICAL :: ler1400 1597 iky = 0; val = '' 1401 IF(.NOT.test(itr <= 0 .OR. itr > SIZE(ky), ler)) iky = strIdx(ky(itr)%key(:), keyn) !--- Correct index 1402 IF(.NOT.test(iky == 0, ler)) val = ky(itr)%val(iky) !--- Found key 1403 IF(iky == 0) THEN 1404 IF(.NOT.test(.NOT.PRESENT(def_val), ler)) val = def_val !--- Default value 1405 END IF 1406 IF(PRESENT(lerr)) lerr = ler 1407 END FUNCTION fgetKeyIdx_s1 1408 !============================================================================================================================== 1409 CHARACTER(LEN=maxlen) FUNCTION fgetKeyNam_s1(tname, keyn, ky, def_val, lerr) RESULT(val) 1410 CHARACTER(LEN=*), INTENT(IN) :: tname, keyn 1411 TYPE(keys_type), INTENT(IN) :: ky(:) 1412 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: def_val 1413 LOGICAL, OPTIONAL, INTENT(OUT) :: lerr 1414 !------------------------------------------------------------------------------------------------------------------------------ 1415 val = fgetKeyIdx_s1(strIdx(ky(:)%name, tname), keyn, ky, def_val, lerr) 1416 END FUNCTION fgetKeyNam_s1 1417 !============================================================================================================================== 1418 FUNCTION fgetKeys(keyn, ky, def_val, lerr) RESULT(val) 1419 CHARACTER(LEN=maxlen), ALLOCATABLE :: val(:) 1420 CHARACTER(LEN=*), INTENT(IN) :: keyn 1421 TYPE(keys_type), INTENT(IN) :: ky(:) 1422 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: def_val 1423 LOGICAL, OPTIONAL, INTENT(OUT) :: lerr 1424 !------------------------------------------------------------------------------------------------------------------------------ 1425 LOGICAL :: ler(SIZE(ky)) 1426 INTEGER :: it 1427 val = [(fgetKeyIdx_s1(it, keyn, ky, def_val, ler(it)), it = 1, SIZE(ky))] 1428 IF(PRESENT(lerr)) lerr = ANY(ler) 1429 END FUNCTION fgetKeys 1430 !============================================================================================================================== 1431 1432 1433 !============================================================================================================================== 1434 !========== GET THE VALUE OF A KEY FROM A "keys_type" DERIVED TYPE ; THE RETURNED VALUE IS THE ERROR CODE ============== 1435 !========== The key "keyn" is searched in: 1) "ky(:)%name" (if given) ============== 1436 !========== 2) "tracers(:)%name" ============== 1437 !========== 3) "isotope%keys(:)%name" ============== 1438 !========== for the tracer[s] "tname[(:)]" (if given) or all the available tracers from the used set otherwise. ============== 1439 !========== The type of the returned value(s) can be string, integer or real, scalar or vector ============== 1440 !============================================================================================================================== 1441 LOGICAL FUNCTION getKeyByName_s1(keyn, val, tname, ky) RESULT(lerr) 1598 ler = itr <= 0 .OR. itr > SIZE(ky); IF(ler) RETURN 1599 iky = strIdx(ky(itr)%key(:), keyn) 1600 ler = iky == 0; IF(ler) RETURN 1601 val = ky(itr)%val(iky) 1602 END SUBROUTINE getKeyIdx 1603 1604 END FUNCTION fgetKeyIdx 1605 !============================================================================================================================== 1606 1607 1608 !============================================================================================================================== 1609 !=== GET KEYS VALUES FROM TRACERS INDICES === 1610 !============================================================================================================================== 1611 !=== TRY TO GET THE KEY NAMED "key" FOR THE "itr"th TRACER IN: === 1612 !=== * ARGUMENT "ky" DATABASE IF SPECIFIED ; OTHERWISE: === 1613 !=== * IN INTERNAL TRACERS DATABASE "tracers(:)%keys" (IF UNFOUND, IN INTERNAL ISOTOPES DATABASE "isotope%keys(:)") === 1614 !=== THE RETURNED VALUE (STRING, AN INTEGER, A REAL OR A LOGICAL) CAN BE EITHER: === 1615 !=== * A SCALAR === 1616 !=== * A VECTOR, WHICH IS THE FOUND VALUE PARSED WITH THE SEPARATOR "," === 1617 !=== === 1618 !=== SYNTAX: lerr = getKeyByIndex_{sirl}{1m}{1m}1(keyn[(:)], val[(:)], itr[, ky(:)] [, def][, lDisp]) === 1619 !============================================================================================================================== 1620 !=== IF "itr" IS NOT PRESENT, VALUES FOR ALL THE TRACERS OF THE SELECTED DATABASE ARE STORED IN THE VECTOR "val(:)" === 1621 !=== THE NAME OF THE TRACERS FOUND IN THE EFFECTIVELY USED DATABASE CAN BE RETURNED OPTIONALLY IN "nam(:)" === 1622 !=== SYNTAX lerr = getKeyByIndex_{sirl}{1m}mm (keyn[(:)], val (:) [, ky(:)][, nam(:)][, def][, lDisp]) === 1623 !============================================================================================================================== 1624 LOGICAL FUNCTION getKeyByIndex_s111(keyn, val, itr, ky, def, lDisp) RESULT(lerr) 1442 1625 CHARACTER(LEN=*), INTENT(IN) :: keyn 1443 1626 CHARACTER(LEN=maxlen), INTENT(OUT) :: val 1444 CHARACTER(LEN=*), INTENT(IN) :: tname1627 INTEGER, INTENT(IN) :: itr 1445 1628 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1446 !------------------------------------------------------------------------------------------------------------------------------ 1447 CHARACTER(LEN=maxlen) :: tnam 1448 tnam = strHead(delPhase(tname),'_',.TRUE.) !--- Remove phase and tag 1449 IF(PRESENT(ky)) THEN !=== KEY FROM "ky" 1450 val = fgetKeyNam_s1(tname, keyn, ky, lerr=lerr) !--- "ky" and "tname" 1451 IF( lerr ) val = fgetKeyNam_s1(tnam, keyn, ky, lerr=lerr) !--- "ky" and "tnam" 1452 ELSE 1453 IF( .NOT.test(.NOT.ALLOCATED(tracers ), lerr)) lerr = SIZE(tracers ) == 0 !=== KEY FROM "tracers" 1454 IF(.NOT.lerr) THEN 1455 val = fgetKeyNam_s1(tname, keyn, tracers%keys, lerr=lerr) !--- "ky" and "tname" 1456 IF(lerr) val = fgetKeyNam_s1(tnam, keyn, tracers%keys, lerr=lerr) !--- "ky" and "tnam" 1457 END IF 1458 IF(lerr.AND..NOT.test(.NOT.ALLOCATED(isotopes), lerr)) lerr = SIZE(isotopes) == 0 !=== KEY FROM "isotope" 1459 IF(.NOT.lerr) THEN 1460 val = fgetKeyNam_s1(tname, keyn, isotope%keys, lerr=lerr) !--- "ky" and "tname" 1461 IF(lerr) val = fgetKeyNam_s1(tnam, keyn, isotope%keys, lerr=lerr) !--- "ky" and "tnam" 1462 END IF 1629 CHARACTER(LEN=*),OPTIONAL, INTENT(IN) :: def 1630 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 1631 lerr = getKeyByIndex_sm11([keyn], val, itr, ky, def, lDisp) 1632 END FUNCTION getKeyByIndex_s111 1633 !============================================================================================================================== 1634 LOGICAL FUNCTION getKeyByIndex_i111(keyn, val, itr, ky, def, lDisp) RESULT(lerr) 1635 CHARACTER(LEN=*), INTENT(IN) :: keyn 1636 INTEGER, INTENT(OUT) :: val 1637 INTEGER, INTENT(IN) :: itr 1638 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1639 INTEGER, OPTIONAL, INTENT(IN) :: def 1640 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 1641 lerr = getKeyByIndex_im11([keyn], val, itr, ky, def, lDisp) 1642 END FUNCTION getKeyByIndex_i111 1643 !============================================================================================================================== 1644 LOGICAL FUNCTION getKeyByIndex_r111(keyn, val, itr, ky, def, lDisp) RESULT(lerr) 1645 CHARACTER(LEN=*), INTENT(IN) :: keyn 1646 REAL , INTENT(OUT) :: val 1647 INTEGER, INTENT(IN) :: itr 1648 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1649 REAL, OPTIONAL, INTENT(IN) :: def 1650 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 1651 lerr = getKeyByIndex_rm11([keyn], val, itr, ky, def, lDisp) 1652 END FUNCTION getKeyByIndex_r111 1653 !============================================================================================================================== 1654 LOGICAL FUNCTION getKeyByIndex_l111(keyn, val, itr, ky, def, lDisp) RESULT(lerr) 1655 CHARACTER(LEN=*), INTENT(IN) :: keyn 1656 LOGICAL, INTENT(OUT) :: val 1657 INTEGER, INTENT(IN) :: itr 1658 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1659 LOGICAL, OPTIONAL, INTENT(IN) :: def 1660 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 1661 lerr = getKeyByIndex_lm11([keyn], val, itr, ky, def, lDisp) 1662 END FUNCTION getKeyByIndex_l111 1663 !============================================================================================================================== 1664 !============================================================================================================================== 1665 LOGICAL FUNCTION getKeyByIndex_sm11(keyn, val, itr, ky, def, lDisp) RESULT(lerr) 1666 CHARACTER(LEN=*), INTENT(IN) :: keyn(:) 1667 CHARACTER(LEN=maxlen), INTENT(OUT) :: val 1668 INTEGER, INTENT(IN) :: itr 1669 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1670 CHARACTER(LEN=*),OPTIONAL, INTENT(IN) :: def 1671 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 1672 !------------------------------------------------------------------------------------------------------------------------------ 1673 CHARACTER(LEN=maxlen) :: s 1674 LOGICAL :: lD 1675 lD = .TRUE.; IF(PRESENT(lDisp)) lD = lDisp 1676 s = 'key "'//TRIM(strStack(keyn, '/'))//'" for tracer nr. '//TRIM(int2str(itr)) 1677 lerr = .TRUE. 1678 IF(lerr .AND. PRESENT(ky)) val = fgetKey(ky) !--- "ky" 1679 IF(lerr .AND. ALLOCATED (tracers)) val = fgetKey(tracers(:)%keys) !--- "tracers" 1680 IF(lerr .AND. ASSOCIATED(isotope)) val = fgetKey(isotope%keys(:)) !--- "isotope" 1681 IF(lerr .AND. PRESENT(def)) THEN 1682 val = def; lerr = .NOT.PRESENT(def) 1683 CALL msg('Using defaut value of '//TRIM(s)//': '//TRIM(def), modname, lD) 1463 1684 END IF 1464 END FUNCTION getKeyByName_s1 1465 !============================================================================================================================== 1466 LOGICAL FUNCTION getKeyByName_s1m(keyn, val, tname, ky) RESULT(lerr) 1685 CALL msg('No '//TRIM(s)//' or out of bounds index', modname, lD .AND. lerr) 1686 1687 CONTAINS 1688 1689 CHARACTER(LEN=maxlen) FUNCTION fgetKey(ky) RESULT(val) 1690 TYPE(keys_type), INTENT(IN) :: ky(:) 1691 lerr = SIZE(ky) == 0; IF(lerr) RETURN 1692 val = fgetKeyIdx(itr, keyn(:), ky, lerr) 1693 END FUNCTION fgetKey 1694 1695 END FUNCTION getKeyByIndex_sm11 1696 !============================================================================================================================== 1697 LOGICAL FUNCTION getKeyByIndex_im11(keyn, val, itr, ky, def, lDisp) RESULT(lerr) 1698 CHARACTER(LEN=*), INTENT(IN) :: keyn(:) 1699 INTEGER, INTENT(OUT) :: val 1700 INTEGER, INTENT(IN) :: itr 1701 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1702 INTEGER, OPTIONAL, INTENT(IN) :: def 1703 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 1704 !------------------------------------------------------------------------------------------------------------------------------ 1705 CHARACTER(LEN=maxlen) :: sval, s 1706 IF( PRESENT(def)) lerr = getKeyByIndex_sm11(keyn, sval, itr, ky, int2str(def), lDisp) 1707 IF(.NOT.PRESENT(def)) lerr = getKeyByIndex_sm11(keyn, sval, itr, ky, lDisp=lDisp) 1708 IF(lerr) RETURN 1709 val = str2int(sval) 1710 lerr = val == -HUGE(1) 1711 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of tracer nr. '//TRIM(int2str(itr))//' is not' 1712 CALL msg(TRIM(s)//' an integer: '//TRIM(sval), modname, lerr) 1713 END FUNCTION getKeyByIndex_im11 1714 !============================================================================================================================== 1715 LOGICAL FUNCTION getKeyByIndex_rm11(keyn, val, itr, ky, def, lDisp) RESULT(lerr) 1716 CHARACTER(LEN=*), INTENT(IN) :: keyn(:) 1717 REAL , INTENT(OUT) :: val 1718 INTEGER, INTENT(IN) :: itr 1719 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1720 REAL, OPTIONAL, INTENT(IN) :: def 1721 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 1722 !------------------------------------------------------------------------------------------------------------------------------ 1723 CHARACTER(LEN=maxlen) :: sval, s 1724 IF( PRESENT(def)) lerr = getKeyByIndex_sm11(keyn, sval, itr, ky, real2str(def), lDisp) 1725 IF(.NOT.PRESENT(def)) lerr = getKeyByIndex_sm11(keyn, sval, itr, ky, lDisp=lDisp) 1726 IF(lerr) RETURN 1727 val = str2real(sval) 1728 lerr = val == -HUGE(1.) 1729 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of tracer nr. '//TRIM(int2str(itr))//' is not' 1730 CALL msg(TRIM(s)//' a real: '//TRIM(sval), modname, lerr) 1731 END FUNCTION getKeyByIndex_rm11 1732 !============================================================================================================================== 1733 LOGICAL FUNCTION getKeyByIndex_lm11(keyn, val, itr, ky, def, lDisp) RESULT(lerr) 1734 CHARACTER(LEN=*), INTENT(IN) :: keyn(:) 1735 LOGICAL, INTENT(OUT) :: val 1736 INTEGER, INTENT(IN) :: itr 1737 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1738 LOGICAL, OPTIONAL, INTENT(IN) :: def 1739 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 1740 !------------------------------------------------------------------------------------------------------------------------------ 1741 CHARACTER(LEN=maxlen) :: sval, s 1742 INTEGER :: ival 1743 IF( PRESENT(def)) lerr = getKeyByIndex_sm11(keyn, sval, itr, ky, bool2str(def), lDisp) 1744 IF(.NOT.PRESENT(def)) lerr = getKeyByIndex_sm11(keyn, sval, itr, ky, lDisp=lDisp) 1745 IF(lerr) RETURN 1746 ival = str2bool(sval) 1747 lerr = ival == -1 1748 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of tracer nr. '//TRIM(int2str(itr))//' is not' 1749 CALL msg(TRIM(s)//' a boolean: '//TRIM(sval), modname, lerr) 1750 IF(.NOT.lerr) val = ival == 1 1751 END FUNCTION getKeyByIndex_lm11 1752 !============================================================================================================================== 1753 !============================================================================================================================== 1754 LOGICAL FUNCTION getKeyByIndex_s1m1(keyn, val, itr, ky, def, lDisp) RESULT(lerr) 1467 1755 CHARACTER(LEN=*), INTENT(IN) :: keyn 1468 1756 CHARACTER(LEN=maxlen), ALLOCATABLE, INTENT(OUT) :: val(:) 1469 CHARACTER(LEN=*), INTENT(IN) :: tname1757 INTEGER, INTENT(IN) :: itr 1470 1758 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1759 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: def 1760 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 1761 !------------------------------------------------------------------------------------------------------------------------------ 1762 CHARACTER(LEN=maxlen) :: sval 1763 lerr = getKeyByIndex_sm11([keyn], sval, itr, ky, def, lDisp); IF(lerr) RETURN 1764 lerr = strParse(sval, ',', val) 1765 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 1766 END FUNCTION getKeyByIndex_s1m1 1767 !============================================================================================================================== 1768 LOGICAL FUNCTION getKeyByIndex_i1m1(keyn, val, itr, ky, def, lDisp) RESULT(lerr) 1769 CHARACTER(LEN=*), INTENT(IN) :: keyn 1770 INTEGER, ALLOCATABLE, INTENT(OUT) :: val(:) 1771 INTEGER, INTENT(IN) :: itr 1772 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1773 INTEGER, OPTIONAL, INTENT(IN) :: def 1774 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 1775 !------------------------------------------------------------------------------------------------------------------------------ 1776 CHARACTER(LEN=maxlen) :: sval, s 1777 CHARACTER(LEN=maxlen), ALLOCATABLE :: svals(:) 1778 IF( PRESENT(def)) lerr = getKeyByIndex_sm11([keyn], sval, itr, ky, int2str(def), lDisp) 1779 IF(.NOT.PRESENT(def)) lerr = getKeyByIndex_sm11([keyn], sval, itr, ky, lDisp=lDisp) 1780 IF(lerr) RETURN 1781 lerr = strParse(sval, ',', svals) 1782 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 1783 val = str2int(svals) 1784 lerr = ANY(val == -HUGE(1)) 1785 s = 'key "'//TRIM(keyn)//'" of tracer nr. '//TRIM(int2str(itr))//' is not' 1786 CALL msg(TRIM(s)//' an integer: '//TRIM(sval), modname, lerr) 1787 END FUNCTION getKeyByIndex_i1m1 1788 !============================================================================================================================== 1789 LOGICAL FUNCTION getKeyByIndex_r1m1(keyn, val, itr, ky, def, lDisp) RESULT(lerr) 1790 CHARACTER(LEN=*), INTENT(IN) :: keyn 1791 REAL, ALLOCATABLE, INTENT(OUT) :: val(:) 1792 INTEGER, INTENT(IN) :: itr 1793 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1794 REAL, OPTIONAL, INTENT(IN) :: def 1795 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 1796 !------------------------------------------------------------------------------------------------------------------------------ 1797 CHARACTER(LEN=maxlen) :: sval, s 1798 CHARACTER(LEN=maxlen), ALLOCATABLE :: svals(:) 1799 IF( PRESENT(def)) lerr = getKeyByIndex_sm11([keyn], sval, itr, ky, real2str(def), lDisp) 1800 IF(.NOT.PRESENT(def)) lerr = getKeyByIndex_sm11([keyn], sval, itr, ky, lDisp=lDisp) 1801 lerr = strParse(sval, ',', svals) 1802 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 1803 val = str2real(svals) 1804 lerr = ANY(val == -HUGE(1.)) 1805 s = 'key "'//TRIM(keyn)//'" of tracer nr. '//TRIM(int2str(itr))//' is not' 1806 CALL msg(TRIM(s)//' a real: '//TRIM(sval), modname, lerr) 1807 END FUNCTION getKeyByIndex_r1m1 1808 !============================================================================================================================== 1809 LOGICAL FUNCTION getKeyByIndex_l1m1(keyn, val, itr, ky, def, lDisp) RESULT(lerr) 1810 CHARACTER(LEN=*), INTENT(IN) :: keyn 1811 LOGICAL, ALLOCATABLE, INTENT(OUT) :: val(:) 1812 INTEGER, INTENT(IN) :: itr 1813 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1814 LOGICAL, OPTIONAL, INTENT(IN) :: def 1815 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 1816 !------------------------------------------------------------------------------------------------------------------------------ 1817 CHARACTER(LEN=maxlen) :: sval, s 1818 CHARACTER(LEN=maxlen), ALLOCATABLE :: svals(:) 1819 INTEGER, ALLOCATABLE :: ivals(:) 1820 IF( PRESENT(def)) lerr = getKeyByIndex_sm11([keyn], sval, itr, ky, bool2str(def), lDisp) 1821 IF(.NOT.PRESENT(def)) lerr = getKeyByIndex_sm11([keyn], sval, itr, ky, lDisp=lDisp) 1822 lerr = strParse(sval, ',', svals) 1823 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 1824 ivals = str2bool(svals) 1825 lerr = ANY(ivals == -1) 1826 s = 'key "'//TRIM(keyn)//'" of tracer nr. '//TRIM(int2str(itr))//' is not' 1827 CALL msg(TRIM(s)//' a boolean: '//TRIM(sval), modname, lerr) 1828 IF(.NOT.lerr) val = ivals == 1 1829 END FUNCTION getKeyByIndex_l1m1 1830 !============================================================================================================================== 1831 !============================================================================================================================== 1832 LOGICAL FUNCTION getKeyByIndex_smm1(keyn, val, itr, ky, def, lDisp) RESULT(lerr) 1833 CHARACTER(LEN=*), INTENT(IN) :: keyn(:) 1834 CHARACTER(LEN=maxlen), ALLOCATABLE, INTENT(OUT) :: val(:) 1835 INTEGER, INTENT(IN) :: itr 1836 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1837 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: def 1838 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 1471 1839 !------------------------------------------------------------------------------------------------------------------------------ 1472 1840 CHARACTER(LEN=maxlen) :: sval 1473 lerr = getKeyByName_s1(keyn, sval, tname, ky) 1474 IF(test(fmsg('missing key "'//TRIM(keyn)//'" for tracer "'//TRIM(tname)//'"', modname, lerr), lerr)) RETURN 1841 lerr = getKeyByIndex_sm11(keyn, sval, itr, ky, def, lDisp); IF(lerr) RETURN 1475 1842 lerr = strParse(sval, ',', val) 1476 END FUNCTION getKeyByName_s1m 1477 !============================================================================================================================== 1478 LOGICAL FUNCTION getKeyByName_sm(keyn, val, tname, ky, nam) RESULT(lerr) 1843 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 1844 END FUNCTION getKeyByIndex_smm1 1845 !============================================================================================================================== 1846 LOGICAL FUNCTION getKeyByIndex_imm1(keyn, val, itr, ky, def, lDisp) RESULT(lerr) 1847 CHARACTER(LEN=*), INTENT(IN) :: keyn(:) 1848 INTEGER, ALLOCATABLE, INTENT(OUT) :: val(:) 1849 INTEGER, INTENT(IN) :: itr 1850 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1851 INTEGER, OPTIONAL, INTENT(IN) :: def 1852 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 1853 !------------------------------------------------------------------------------------------------------------------------------ 1854 CHARACTER(LEN=maxlen) :: sval, s 1855 CHARACTER(LEN=maxlen), ALLOCATABLE :: svals(:) 1856 IF( PRESENT(def)) lerr = getKeyByIndex_sm11(keyn, sval, itr, ky, int2str(def), lDisp) 1857 IF(.NOT.PRESENT(def)) lerr = getKeyByIndex_sm11(keyn, sval, itr, ky, lDisp=lDisp) 1858 IF(lerr) RETURN 1859 lerr = strParse(sval, ',', svals) 1860 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 1861 val = str2int(svals) 1862 lerr = ANY(val == -HUGE(1)) 1863 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of tracer nr. '//TRIM(int2str(itr))//' is not' 1864 CALL msg(TRIM(s)//' an integer: '//TRIM(sval), modname, lerr) 1865 END FUNCTION getKeyByIndex_imm1 1866 !============================================================================================================================== 1867 LOGICAL FUNCTION getKeyByIndex_rmm1(keyn, val, itr, ky, def, lDisp) RESULT(lerr) 1868 CHARACTER(LEN=*), INTENT(IN) :: keyn(:) 1869 REAL, ALLOCATABLE, INTENT(OUT) :: val(:) 1870 INTEGER, INTENT(IN) :: itr 1871 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1872 REAL, OPTIONAL, INTENT(IN) :: def 1873 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 1874 !------------------------------------------------------------------------------------------------------------------------------ 1875 CHARACTER(LEN=maxlen) :: sval, s 1876 CHARACTER(LEN=maxlen), ALLOCATABLE :: svals(:) 1877 IF( PRESENT(def)) lerr = getKeyByIndex_sm11(keyn, sval, itr, ky, real2str(def), lDisp) 1878 IF(.NOT.PRESENT(def)) lerr = getKeyByIndex_sm11(keyn, sval, itr, ky, lDisp=lDisp) 1879 IF(lerr) RETURN 1880 lerr = strParse(sval, ',', svals) 1881 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 1882 val = str2real(svals) 1883 lerr = ANY(val == -HUGE(1.)) 1884 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of tracer nr. '//TRIM(int2str(itr))//' is not' 1885 CALL msg(TRIM(s)//' a real: '//TRIM(sval), modname, lerr) 1886 END FUNCTION getKeyByIndex_rmm1 1887 !============================================================================================================================== 1888 LOGICAL FUNCTION getKeyByIndex_lmm1(keyn, val, itr, ky, def, lDisp) RESULT(lerr) 1889 CHARACTER(LEN=*), INTENT(IN) :: keyn(:) 1890 LOGICAL, ALLOCATABLE, INTENT(OUT) :: val(:) 1891 INTEGER, INTENT(IN) :: itr 1892 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1893 LOGICAL, OPTIONAL, INTENT(IN) :: def 1894 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 1895 !------------------------------------------------------------------------------------------------------------------------------ 1896 CHARACTER(LEN=maxlen) :: sval, s 1897 CHARACTER(LEN=maxlen), ALLOCATABLE :: svals(:) 1898 INTEGER, ALLOCATABLE :: ivals(:) 1899 IF( PRESENT(def)) lerr = getKeyByIndex_sm11(keyn, sval, itr, ky, bool2str(def), lDisp) 1900 IF(.NOT.PRESENT(def)) lerr = getKeyByIndex_sm11(keyn, sval, itr, ky, lDisp=lDisp) 1901 IF(lerr) RETURN 1902 lerr = strParse(sval, ',', svals) 1903 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 1904 ivals = str2bool(svals) 1905 lerr = ANY(ivals == -1) 1906 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of tracer nr. '//TRIM(int2str(itr))//' is not' 1907 CALL msg(TRIM(s)//' a boolean: '//TRIM(sval), modname, lerr) 1908 IF(.NOT.lerr) val = ivals == 1 1909 END FUNCTION getKeyByIndex_lmm1 1910 !============================================================================================================================== 1911 !============================================================================================================================== 1912 LOGICAL FUNCTION getKeyByIndex_s1mm(keyn, val, ky, nam, def, lDisp) RESULT(lerr) 1479 1913 CHARACTER(LEN=*), INTENT(IN) :: keyn 1480 1914 CHARACTER(LEN=maxlen), ALLOCATABLE, INTENT(OUT) :: val(:) 1481 CHARACTER(LEN=*), INTENT(IN) :: tname(:) 1482 TYPE(keys_type), OPTIONAL, TARGET, INTENT(IN) :: ky(:) 1915 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1483 1916 CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) :: nam(:) 1484 !------------------------------------------------------------------------------------------------------------------------------ 1485 TYPE(keys_type), POINTER :: keys(:) 1486 LOGICAL :: lk, lt, li 1487 INTEGER :: iq, nq 1488 1489 !--- DETERMINE THE DATABASE TO BE USED (ky, tracers or isotope) 1490 lk = PRESENT(ky) 1491 lt = .NOT.lk .AND. ALLOCATED(tracers); IF(lt) lt = SIZE(tracers) /= 0; IF(lt) lt = ANY(tracers(1)%keys%key(:) == keyn) 1492 li = .NOT.lt .AND. ALLOCATED(isotopes); IF(li) li = SIZE(isotopes) /= 0; IF(li) li = ANY(isotope%keys(1)%key(:) == keyn) 1493 1494 !--- LINK "keys" TO THE RIGHT DATABASE 1495 IF(test(.NOT.ANY([lk,lt,li]), lerr)) RETURN 1496 IF(lk) keys => ky(:) 1497 IF(lt) keys => tracers(:)%keys 1498 IF(li) keys => isotope%keys(:) 1499 1500 !--- GET THE DATA 1501 nq = SIZE(tname) 1502 ALLOCATE(val(nq)) 1503 lerr = ANY([(getKeyByName_s1(keyn, val(iq), tname(iq), keys(:)), iq=1, nq)]) 1504 IF(PRESENT(nam)) nam = tname(:) 1505 1506 END FUNCTION getKeyByName_sm 1507 !============================================================================================================================== 1508 LOGICAL FUNCTION getKey_sm(keyn, val, ky, nam) RESULT(lerr) 1917 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: def 1918 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 1919 lerr = getKeyByIndex_smmm([keyn], val, ky, nam, def, lDisp) 1920 END FUNCTION getKeyByIndex_s1mm 1921 !============================================================================================================================== 1922 LOGICAL FUNCTION getKeyByIndex_i1mm(keyn, val, ky, nam, def, lDisp) RESULT(lerr) 1509 1923 CHARACTER(LEN=*), INTENT(IN) :: keyn 1510 CHARACTER(LEN=maxlen),ALLOCATABLE, INTENT(OUT) :: val(:)1511 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:)1924 INTEGER, ALLOCATABLE, INTENT(OUT) :: val(:) 1925 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1512 1926 CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) :: nam(:) 1513 !------------------------------------------------------------------------------------------------------------------------------ 1514 ! Note: if names are repeated, getKeyByName_sm can't be used ; this routine, using indexes, must be used instead. 1515 IF(PRESENT(ky)) THEN !=== KEY FROM "ky" 1516 val = fgetKeys(keyn, ky, lerr=lerr) 1517 IF(PRESENT(nam)) nam = ky(:)%name 1518 ELSE 1519 IF( .NOT.test(.NOT.ALLOCATED(tracers ), lerr)) lerr = SIZE(tracers ) == 0 !=== KEY FROM "tracers" 1520 IF(.NOT.lerr) val = fgetKeys(keyn, tracers%keys, lerr=lerr) 1521 IF(.NOT.lerr.AND.PRESENT(nam)) nam = tracers(:)%keys%name 1522 IF(lerr.AND..NOT.test(.NOT.ALLOCATED(isotopes), lerr)) lerr = SIZE(isotopes) == 0 !=== KEY FROM "isotope" 1523 IF(.NOT.lerr) val = fgetKeys(keyn, isotope%keys, lerr=lerr) 1524 IF(.NOT.lerr.AND.PRESENT(nam)) nam = isotope%keys(:)%name 1927 INTEGER, OPTIONAL, INTENT(IN) :: def 1928 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 1929 lerr = getKeyByIndex_immm([keyn], val, ky, nam, def, lDisp) 1930 END FUNCTION getKeyByIndex_i1mm 1931 !============================================================================================================================== 1932 LOGICAL FUNCTION getKeyByIndex_r1mm(keyn, val, ky, nam, def, lDisp) RESULT(lerr) 1933 CHARACTER(LEN=*), INTENT(IN) :: keyn 1934 REAL, ALLOCATABLE, INTENT(OUT) :: val(:) 1935 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1936 CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) :: nam(:) 1937 REAL, OPTIONAL, INTENT(IN) :: def 1938 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 1939 lerr = getKeyByIndex_rmmm([keyn], val, ky, nam, def, lDisp) 1940 END FUNCTION getKeyByIndex_r1mm 1941 !============================================================================================================================== 1942 LOGICAL FUNCTION getKeyByIndex_l1mm(keyn, val, ky, nam, def, lDisp) RESULT(lerr) 1943 CHARACTER(LEN=*), INTENT(IN) :: keyn 1944 LOGICAL, ALLOCATABLE, INTENT(OUT) :: val(:) 1945 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1946 CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) :: nam(:) 1947 LOGICAL, OPTIONAL, INTENT(IN) :: def 1948 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 1949 lerr = getKeyByIndex_lmmm([keyn], val, ky, nam, def, lDisp) 1950 END FUNCTION getKeyByIndex_l1mm 1951 !============================================================================================================================== 1952 !============================================================================================================================== 1953 LOGICAL FUNCTION getKeyByIndex_smmm(keyn, val, ky, nam, def, lDisp) RESULT(lerr) 1954 CHARACTER(LEN=*), INTENT(IN) :: keyn(:) 1955 CHARACTER(LEN=maxlen), ALLOCATABLE, INTENT(OUT) :: val(:) 1956 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1957 CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) :: nam(:) 1958 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: def 1959 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 1960 !------------------------------------------------------------------------------------------------------------------------------ 1961 CHARACTER(LEN=maxlen) :: s 1962 CHARACTER(LEN=maxlen), ALLOCATABLE :: tname(:) 1963 INTEGER :: iq, nq(3), k 1964 LOGICAL :: lD, l(3) 1965 lD = .TRUE.; IF(PRESENT(lDisp)) lD = lDisp 1966 s = 'key "'//TRIM(strStack(keyn, '/'))//'"' 1967 lerr = .TRUE. 1968 IF(PRESENT(ky)) THEN; val = fgetKey(ky) !--- "ky" 1969 ELSE IF(ALLOCATED(tracers)) THEN; val = fgetKey(tracers(:)%keys) !--- "tracers" 1970 IF(lerr .AND. ASSOCIATED(isotope)) val = fgetKey(isotope%keys(:)) !--- "isotope" 1525 1971 END IF 1526 END FUNCTION getKey_sm 1527 !============================================================================================================================== 1528 LOGICAL FUNCTION getKeyByName_i1(keyn, val, tname, ky) RESULT(lerr) 1529 CHARACTER(LEN=*), INTENT(IN) :: keyn 1530 INTEGER, INTENT(OUT) :: val 1531 CHARACTER(LEN=*), INTENT(IN) :: tname 1532 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1533 !------------------------------------------------------------------------------------------------------------------------------ 1534 CHARACTER(LEN=maxlen) :: sval 1535 INTEGER :: ierr 1536 lerr = getKeyByName_s1(keyn, sval, tname, ky) 1537 IF(test(fmsg('key "'//TRIM(keyn)//'" or tracer "'//TRIM(tname)//'" is missing', modname, lerr), lerr)) RETURN 1538 READ(sval, *, IOSTAT=ierr) val 1539 IF(test(fmsg('key "'//TRIM(keyn)//'" of tracer "'//TRIM(tname)//'" is not an integer', modname, ierr/=0), lerr)) RETURN 1540 END FUNCTION getKeyByName_i1 1541 !============================================================================================================================== 1542 LOGICAL FUNCTION getKeyByName_i1m(keyn, val, tname, ky) RESULT(lerr) 1543 CHARACTER(LEN=*), INTENT(IN) :: keyn 1544 INTEGER, ALLOCATABLE, INTENT(OUT) :: val(:) 1545 CHARACTER(LEN=*), INTENT(IN) :: tname 1546 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1547 !------------------------------------------------------------------------------------------------------------------------------ 1548 CHARACTER(LEN=maxlen), ALLOCATABLE :: sval(:) 1549 INTEGER :: ierr, iq, nq 1550 IF(test(getKeyByName_s1m(keyn, sval, tname, ky), lerr)) RETURN 1551 nq = SIZE(sval); ALLOCATE(val(nq)) 1552 lerr = .FALSE.; DO iq=1, nq; READ(sval(iq), *, IOSTAT=ierr) val(iq); lerr = lerr .OR. ierr /= 0; END DO 1553 IF(test(fmsg('key "'//TRIM(keyn)//'" of tracer "'//TRIM(tname)//'" is not an integer', modname, lerr), lerr)) RETURN 1554 END FUNCTION getKeyByName_i1m 1555 !============================================================================================================================== 1556 LOGICAL FUNCTION getKeyByName_im(keyn, val, tname, ky, nam) RESULT(lerr) 1557 CHARACTER(LEN=*), INTENT(IN) :: keyn 1558 INTEGER, ALLOCATABLE, INTENT(OUT) :: val(:) 1559 CHARACTER(LEN=*), INTENT(IN) :: tname(:) 1560 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1561 CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) :: nam(:) 1562 !------------------------------------------------------------------------------------------------------------------------------ 1563 CHARACTER(LEN=maxlen), ALLOCATABLE :: sval(:), names(:) 1564 INTEGER :: ierr, iq, nq 1565 IF(test(getKeyByName_sm(keyn, sval, tname, ky, names), lerr)) RETURN 1566 nq = SIZE(sval); ALLOCATE(val(nq)) 1567 DO iq = 1, nq !--- CONVERT THE KEYS TO INTEGERS 1568 READ(sval(iq), *, IOSTAT=ierr) val(iq) 1569 IF(test(fmsg('key "'//TRIM(keyn)//'" of tracer "'//TRIM(names(iq))//'" is not an integer', modname, ierr/=0), lerr)) RETURN 1570 END DO 1571 IF(PRESENT(nam)) nam = names(:) 1572 END FUNCTION getKeyByName_im 1573 !============================================================================================================================== 1574 LOGICAL FUNCTION getKey_im(keyn, val, ky, nam) RESULT(lerr) 1575 CHARACTER(LEN=*), INTENT(IN) :: keyn 1972 IF(.NOT.lerr) THEN; IF(PRESENT(nam)) nam = tname; RETURN; END IF 1973 IF(.NOT.PRESENT(def)) THEN; CALL msg('No '//TRIM(s)//' found', modname, lD); RETURN; END IF 1974 1975 !--- DEFAULT VALUE 1976 l = [PRESENT(ky), ALLOCATED(tracers), ASSOCIATED(isotope)]; nq(:) = 0 1977 IF(l(1)) nq(1) = SIZE(ky) 1978 IF(l(2)) nq(2) = SIZE(tracers) 1979 IF(l(3)) nq(3) = SIZE(isotope%keys) 1980 DO k = 1, 3; IF(l(k) .AND. nq(k) /= 0) THEN; val = [(def, iq = 1, nq(k))]; EXIT; END IF; END DO 1981 lerr = k == 4 1982 CALL msg('Using defaut value for '//TRIM(s)//': '//TRIM(def), modname, lD .AND. .NOT.lerr) 1983 CALL msg('No '//TRIM(s), modname, lD .AND. lerr) 1984 1985 CONTAINS 1986 1987 FUNCTION fgetKey(ky) RESULT(val) 1988 CHARACTER(LEN=maxlen), ALLOCATABLE :: val(:) 1989 TYPE(keys_type), INTENT(IN) :: ky(:) 1990 LOGICAL :: ler(SIZE(ky)) 1991 INTEGER :: iq 1992 lerr = SIZE(ky) == 0; IF(lerr) RETURN 1993 tname = ky%name 1994 val = [(fgetKeyIdx(iq, keyn(:), ky, ler(iq)), iq = 1, SIZE(ky))] 1995 lerr = ANY(ler) 1996 END FUNCTION fgetKey 1997 1998 END FUNCTION getKeyByIndex_smmm 1999 !============================================================================================================================== 2000 LOGICAL FUNCTION getKeyByIndex_immm(keyn, val, ky, nam, def, lDisp) RESULT(lerr) 2001 CHARACTER(LEN=*), INTENT(IN) :: keyn(:) 1576 2002 INTEGER, ALLOCATABLE, INTENT(OUT) :: val(:) 1577 2003 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1578 2004 CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) :: nam(:) 1579 !------------------------------------------------------------------------------------------------------------------------------ 1580 CHARACTER(LEN=maxlen), ALLOCATABLE :: sval(:), names(:) 1581 INTEGER :: ierr, iq, nq 1582 IF(test(getKey_sm(keyn, sval, ky, names), lerr)) RETURN 1583 nq = SIZE(sval); ALLOCATE(val(nq)) 1584 DO iq = 1, nq 1585 READ(sval(iq), *, IOSTAT=ierr) val(iq) 1586 IF(test(fmsg('key "'//TRIM(keyn)//'" of tracer "'//TRIM(names(iq))//'" is not an integer', modname, ierr/=0), lerr)) RETURN 1587 END DO 1588 IF(PRESENT(nam)) nam = names 1589 END FUNCTION getKey_im 1590 !============================================================================================================================== 1591 LOGICAL FUNCTION getKeyByName_r1(keyn, val, tname, ky) RESULT(lerr) 1592 CHARACTER(LEN=*), INTENT(IN) :: keyn 1593 REAL, INTENT(OUT) :: val 1594 CHARACTER(LEN=*), INTENT(IN) :: tname 1595 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1596 !------------------------------------------------------------------------------------------------------------------------------ 1597 CHARACTER(LEN=maxlen) :: sval 1598 INTEGER :: ierr 1599 lerr = getKeyByName_s1(keyn, sval, tname, ky) 1600 IF(test(fmsg('key "'//TRIM(keyn)//'" or tracer "'//TRIM(tname)//'" is missing', modname, lerr), lerr)) RETURN 1601 READ(sval, *, IOSTAT=ierr) val 1602 IF(test(fmsg('key "'//TRIM(keyn)//'" of tracer "'//TRIM(tname)//'" is not a real', modname, ierr/=0), lerr)) RETURN 1603 END FUNCTION getKeyByName_r1 1604 !============================================================================================================================== 1605 LOGICAL FUNCTION getKeyByName_r1m(keyn, val, tname, ky) RESULT(lerr) 1606 CHARACTER(LEN=*), INTENT(IN) :: keyn 1607 REAL, ALLOCATABLE, INTENT(OUT) :: val(:) 1608 CHARACTER(LEN=*), INTENT(IN) :: tname 1609 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1610 !------------------------------------------------------------------------------------------------------------------------------ 1611 CHARACTER(LEN=maxlen), ALLOCATABLE :: sval(:) 1612 INTEGER :: ierr, iq, nq 1613 IF(test(getKeyByName_s1m(keyn, sval, tname, ky), lerr)) RETURN 1614 nq = SIZE(sval); ALLOCATE(val(nq)) 1615 lerr = .FALSE.; DO iq=1, nq; READ(sval(iq), *, IOSTAT=ierr) val(iq); lerr = lerr .OR. ierr /= 0; END DO 1616 IF(test(fmsg('key "'//TRIM(keyn)//'" of tracer "'//TRIM(tname)//'" is not a vector of reals', modname, lerr), lerr)) RETURN 1617 END FUNCTION getKeyByName_r1m 1618 !============================================================================================================================== 1619 LOGICAL FUNCTION getKeyByName_rm(keyn, val, tname, ky, nam) RESULT(lerr) 1620 CHARACTER(LEN=*), INTENT(IN) :: keyn 1621 REAL, ALLOCATABLE, INTENT(OUT) :: val(:) 1622 CHARACTER(LEN=*), INTENT(IN) :: tname(:) 1623 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1624 CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) :: nam(:) 1625 !------------------------------------------------------------------------------------------------------------------------------ 1626 CHARACTER(LEN=maxlen), ALLOCATABLE :: sval(:), names(:) 1627 INTEGER :: ierr, iq, nq 1628 IF(test(getKeyByName_sm(keyn, sval, tname, ky, names), lerr)) RETURN 1629 nq = SIZE(sval); ALLOCATE(val(nq)) 1630 DO iq = 1, nq !--- CONVERT THE KEYS TO INTEGERS 1631 READ(sval(iq), *, IOSTAT=ierr) val(iq) 1632 IF(test(fmsg('key "'//TRIM(keyn)//'" of tracer "'//TRIM(names(iq))//'" is not a real', modname, ierr/=0), lerr)) RETURN 1633 END DO 1634 IF(PRESENT(nam)) nam = names 1635 END FUNCTION getKeyByName_rm 1636 !============================================================================================================================== 1637 LOGICAL FUNCTION getKey_rm(keyn, val, ky, nam) RESULT(lerr) 1638 CHARACTER(LEN=*), INTENT(IN) :: keyn 2005 INTEGER, OPTIONAL, INTENT(IN) :: def 2006 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 2007 !------------------------------------------------------------------------------------------------------------------------------ 2008 CHARACTER(LEN=maxlen) :: s 2009 CHARACTER(LEN=maxlen), ALLOCATABLE :: svals(:), tname(:) 2010 LOGICAL, ALLOCATABLE :: ll(:) 2011 IF( PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, tname, int2str(def), lDisp) 2012 IF(.NOT.PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, tname, lDisp=lDisp) 2013 IF(lerr) RETURN 2014 val = str2int(svals) 2015 ll = val == -HUGE(1) 2016 lerr = ANY(ll); IF(.NOT.lerr) THEN; IF(PRESENT(nam)) nam = tname; RETURN; END IF 2017 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(strStack(PACK(tname, MASK=ll)))//' is not' 2018 CALL msg(TRIM(s)//' an integer: '//TRIM(strStack(svals, MASK=ll)), modname, lerr) 2019 IF(.NOT.lerr .AND. PRESENT(nam)) nam = tname 2020 END FUNCTION getKeyByIndex_immm 2021 !============================================================================================================================== 2022 LOGICAL FUNCTION getKeyByIndex_rmmm(keyn, val, ky, nam, def, lDisp) RESULT(lerr) 2023 CHARACTER(LEN=*), INTENT(IN) :: keyn(:) 1639 2024 REAL, ALLOCATABLE, INTENT(OUT) :: val(:) 1640 2025 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1641 2026 CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) :: nam(:) 1642 !------------------------------------------------------------------------------------------------------------------------------ 1643 CHARACTER(LEN=maxlen), ALLOCATABLE :: sval(:), names(:) 1644 INTEGER :: ierr, iq, nq 1645 IF(test(getKey_sm(keyn, sval, ky, names), lerr)) RETURN 1646 nq = SIZE(sval); ALLOCATE(val(nq)) 1647 DO iq = 1, nq !--- CONVERT THE KEYS TO INTEGERS 1648 READ(sval(iq), *, IOSTAT=ierr) val(iq) 1649 IF(test(fmsg('key "'//TRIM(keyn)//'" of tracer "'//TRIM(names(iq))//'" is not a real', modname, ierr/=0), lerr)) RETURN 1650 END DO 1651 IF(PRESENT(nam)) nam = names 1652 END FUNCTION getKey_rm 1653 !============================================================================================================================== 1654 LOGICAL FUNCTION getKeyByName_l1(keyn, val, tname, ky) RESULT(lerr) 1655 USE strings_mod, ONLY: str2bool 1656 CHARACTER(LEN=*), INTENT(IN) :: keyn 1657 LOGICAL, INTENT(OUT) :: val 1658 CHARACTER(LEN=*), INTENT(IN) :: tname 1659 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1660 !------------------------------------------------------------------------------------------------------------------------------ 1661 CHARACTER(LEN=maxlen) :: sval 1662 lerr = getKeyByName_s1(keyn, sval, tname, ky) 1663 IF(test(fmsg('key "'//TRIM(keyn)//'" or tracer "'//TRIM(tname)//'" is missing', modname, lerr), lerr)) RETURN 1664 val = str2bool(sval) 1665 END FUNCTION getKeyByName_l1 1666 !============================================================================================================================== 1667 LOGICAL FUNCTION getKeyByName_l1m(keyn, val, tname, ky) RESULT(lerr) 1668 USE strings_mod, ONLY: str2bool 1669 CHARACTER(LEN=*), INTENT(IN) :: keyn 1670 LOGICAL, ALLOCATABLE, INTENT(OUT) :: val(:) 1671 CHARACTER(LEN=*), INTENT(IN) :: tname 1672 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1673 !------------------------------------------------------------------------------------------------------------------------------ 1674 CHARACTER(LEN=maxlen), ALLOCATABLE :: sval(:) 1675 INTEGER :: iq, nq 1676 IF(test(getKeyByName_s1m(keyn, sval, tname, ky), lerr)) RETURN 1677 nq = SIZE(sval); ALLOCATE(val(nq)) 1678 lerr = .FALSE.; DO iq=1, nq; val(iq)=str2bool(sval(iq)); END DO 1679 END FUNCTION getKeyByName_l1m 1680 !============================================================================================================================== 1681 LOGICAL FUNCTION getKeyByName_lm(keyn, val, tname, ky, nam) RESULT(lerr) 1682 USE strings_mod, ONLY: str2bool 1683 CHARACTER(LEN=*), INTENT(IN) :: keyn 1684 LOGICAL, ALLOCATABLE, INTENT(OUT) :: val(:) 1685 CHARACTER(LEN=*), INTENT(IN) :: tname(:) 1686 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1687 CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) :: nam(:) 1688 !------------------------------------------------------------------------------------------------------------------------------ 1689 CHARACTER(LEN=maxlen), ALLOCATABLE :: sval(:) 1690 INTEGER :: iq, nq 1691 IF(test(getKeyByName_sm(keyn, sval, tname, ky, nam), lerr)) RETURN 1692 nq = SIZE(sval); ALLOCATE(val(nq)) 1693 lerr = .FALSE.; DO iq=1, nq; val(iq)=str2bool(sval(iq)); END DO 1694 END FUNCTION getKeyByName_lm 1695 !============================================================================================================================== 1696 LOGICAL FUNCTION getKey_lm(keyn, val, ky, nam) RESULT(lerr) 1697 USE strings_mod, ONLY: str2bool 1698 CHARACTER(LEN=*), INTENT(IN) :: keyn 2027 REAL, OPTIONAL, INTENT(IN) :: def 2028 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 2029 !------------------------------------------------------------------------------------------------------------------------------ 2030 CHARACTER(LEN=maxlen) :: s 2031 CHARACTER(LEN=maxlen), ALLOCATABLE :: svals(:), tname(:) 2032 LOGICAL, ALLOCATABLE :: ll(:) 2033 IF( PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, tname, real2str(def), lDisp) 2034 IF(.NOT.PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, tname, lDisp=lDisp) 2035 IF(lerr) RETURN 2036 val = str2real(svals) 2037 ll = val == -HUGE(1.) 2038 lerr = ANY(ll); IF(.NOT.lerr) THEN; IF(PRESENT(nam)) nam = tname; RETURN; END IF 2039 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(strStack(PACK(tname, MASK=ll)))//' is not a' 2040 CALL msg(TRIM(s)//' a real: '//TRIM(strStack(svals, MASK=ll)), modname) 2041 END FUNCTION getKeyByIndex_rmmm 2042 !============================================================================================================================== 2043 LOGICAL FUNCTION getKeyByIndex_lmmm(keyn, val, ky, nam, def, lDisp) RESULT(lerr) 2044 CHARACTER(LEN=*), INTENT(IN) :: keyn(:) 1699 2045 LOGICAL, ALLOCATABLE, INTENT(OUT) :: val(:) 1700 2046 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 1701 2047 CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) :: nam(:) 1702 !------------------------------------------------------------------------------------------------------------------------------ 1703 CHARACTER(LEN=maxlen), ALLOCATABLE :: sval(:) 2048 LOGICAL, OPTIONAL, INTENT(IN) :: def 2049 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 2050 !------------------------------------------------------------------------------------------------------------------------------ 2051 CHARACTER(LEN=maxlen) :: s 2052 CHARACTER(LEN=maxlen), ALLOCATABLE :: svals(:), tname(:) 2053 LOGICAL, ALLOCATABLE :: ll(:) 2054 INTEGER, ALLOCATABLE :: ivals(:) 2055 IF( PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, tname, bool2str(def), lDisp) 2056 IF(.NOT.PRESENT(def)) lerr = getKeyByIndex_smmm(keyn, svals, ky, tname, lDisp=lDisp) 2057 IF(lerr) RETURN 2058 ivals = str2bool(svals) 2059 ll = ivals == -1 2060 lerr = ANY(ll); IF(.NOT.lerr) THEN; val = ivals == 1; IF(PRESENT(nam)) nam = tname; RETURN; END IF 2061 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(strStack(tname, MASK=ll))//' is not' 2062 CALL msg(TRIM(s)//' a boolean: '//TRIM(strStack(svals, MASK=ll)), modname) 2063 END FUNCTION getKeyByIndex_lmmm 2064 !============================================================================================================================== 2065 2066 2067 2068 !============================================================================================================================== 2069 !=== GET KEYS VALUES FROM TRACERS NAMES === 2070 !============================================================================================================================== 2071 !=== TRY TO GET THE KEY NAMED "key" FOR THE TRACER NAMED "tname" IN: === 2072 !=== * ARGUMENT "ky" DATABASE IF SPECIFIED ; OTHERWISE: === 2073 !=== * IN INTERNAL TRACERS DATABASE "tracers(:)%keys" (IF UNFOUND, IN INTERNAL ISOTOPES DATABASE "isotope%keys(:)") === 2074 !=== THE RETURNED VALUE (STRING, AN INTEGER, A REAL OR A LOGICAL) CAN BE EITHER: === 2075 !=== * A SCALAR === 2076 !=== * A VECTOR, WHICH IS THE FOUND VALUE PARSED WITH THE SEPARATOR "," === 2077 !=== === 2078 !=== SYNTAX: lerr = getKeyByName_{sirl}{1m}{1m}1(keyn[(:)], val[(:)], tname [, ky(:)][, def][, lDisp]) === 2079 !============================================================================================================================== 2080 !=== IF "tname(:)" IS A VECTOR, THE RETURNED VALUES (ONE EACH "tname(:)" ELEMENT) ARE STORED IN THE VECTOR "val(:)" === 2081 !=== === 2082 !=== SYNTAX lerr = getKeyByName_{sirl}{1m}mm (keyn[(:)], val (:), tname(:)[, ky(:)][, def][, lDisp]) === 2083 !============================================================================================================================== 2084 LOGICAL FUNCTION getKeyByName_s111(keyn, val, tname, ky, def, lDisp) RESULT(lerr) 2085 CHARACTER(LEN=*), INTENT(IN) :: keyn, tname 2086 CHARACTER(LEN=maxlen), INTENT(OUT) :: val 2087 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 2088 CHARACTER(LEN=*),OPTIONAL, INTENT(IN) :: def 2089 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 2090 lerr = getKeyByName_sm11([keyn], val, tname, ky, def, lDisp) 2091 END FUNCTION getKeyByName_s111 2092 !============================================================================================================================== 2093 LOGICAL FUNCTION getKeyByName_i111(keyn, val, tname, ky, def, lDisp) RESULT(lerr) 2094 CHARACTER(LEN=*), INTENT(IN) :: keyn, tname 2095 INTEGER, INTENT(OUT) :: val 2096 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 2097 INTEGER, OPTIONAL, INTENT(IN) :: def 2098 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 2099 lerr = getKeyByName_im11([keyn], val, tname, ky, def, lDisp) 2100 END FUNCTION getKeyByName_i111 2101 !============================================================================================================================== 2102 LOGICAL FUNCTION getKeyByName_r111(keyn, val, tname, ky, def, lDisp) RESULT(lerr) 2103 CHARACTER(LEN=*), INTENT(IN) :: keyn, tname 2104 REAL , INTENT(OUT) :: val 2105 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 2106 REAL, OPTIONAL, INTENT(IN) :: def 2107 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 2108 lerr = getKeyByName_rm11([keyn], val, tname, ky, def, lDisp) 2109 END FUNCTION getKeyByName_r111 2110 !============================================================================================================================== 2111 LOGICAL FUNCTION getKeyByName_l111(keyn, val, tname, ky, def, lDisp) RESULT(lerr) 2112 CHARACTER(LEN=*), INTENT(IN) :: keyn, tname 2113 LOGICAL, INTENT(OUT) :: val 2114 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 2115 LOGICAL, OPTIONAL, INTENT(IN) :: def 2116 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 2117 lerr = getKeyByName_lm11([keyn], val, tname, ky, def, lDisp) 2118 END FUNCTION getKeyByName_l111 2119 !============================================================================================================================== 2120 !============================================================================================================================== 2121 LOGICAL FUNCTION getKeyByName_sm11(keyn, val, tname, ky, def, lDisp) RESULT(lerr) 2122 CHARACTER(LEN=*), INTENT(IN) :: keyn(:), tname 2123 CHARACTER(LEN=maxlen), INTENT(OUT) :: val 2124 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 2125 CHARACTER(LEN=*),OPTIONAL, INTENT(IN) :: def 2126 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 2127 !------------------------------------------------------------------------------------------------------------------------------ 2128 CHARACTER(LEN=maxlen) :: s, tnam 2129 LOGICAL :: lD 2130 lD = .TRUE.; IF(PRESENT(lDisp)) lD = lDisp 2131 s = 'key "'//TRIM(strStack(keyn, '/'))//'" for "'//TRIM(tname)//'"' 2132 lerr = .TRUE. 2133 tnam = strHead(delPhase(tname),'_',.TRUE.) !--- Remove phase and tag 2134 IF(lerr .AND. PRESENT(ky)) val = fgetKey(ky) !--- "ky" 2135 IF(lerr .AND. ALLOCATED (tracers)) val = fgetKey(tracers(:)%keys) !--- "tracers" 2136 IF(lerr .AND. ASSOCIATED(isotope)) val = fgetKey(isotope%keys(:)) !--- "isotope" 2137 IF(lerr .AND. PRESENT(def)) THEN 2138 val = def; lerr = .NOT.PRESENT(def) 2139 CALL msg('Using defaut value of '//TRIM(s)//': '//TRIM(def), modname, lD) 2140 END IF 2141 CALL msg('No '//TRIM(s)//' or out of bounds index', modname, lD .AND. lerr) 2142 2143 CONTAINS 2144 2145 CHARACTER(LEN=maxlen) FUNCTION fgetKey(ky) RESULT(val) 2146 TYPE(keys_type), INTENT(IN) :: ky(:) 2147 lerr = SIZE(ky) == 0 2148 IF(lerr) RETURN 2149 val = fgetKeyIdx(strIdx(ky%name, tname), [keyn], ky, lerr) 2150 IF(lerr) val = fgetKeyIdx(strIdx(ky%name, tnam ), [keyn], ky, lerr) 2151 2152 END FUNCTION fgetKey 2153 2154 END FUNCTION getKeyByName_sm11 2155 !============================================================================================================================== 2156 LOGICAL FUNCTION getKeyByName_im11(keyn, val, tname, ky, def, lDisp) RESULT(lerr) 2157 CHARACTER(LEN=*), INTENT(IN) :: keyn(:), tname 2158 INTEGER, INTENT(OUT) :: val 2159 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 2160 INTEGER, OPTIONAL, INTENT(IN) :: def 2161 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 2162 !------------------------------------------------------------------------------------------------------------------------------ 2163 CHARACTER(LEN=maxlen) :: sval, s 2164 IF( PRESENT(def)) lerr = getKeyByName_sm11(keyn, sval, tname, ky, int2str(def), lDisp) 2165 IF(.NOT.PRESENT(def)) lerr = getKeyByName_sm11(keyn, sval, tname, ky, lDisp=lDisp) 2166 IF(lerr) RETURN 2167 val = str2int(sval) 2168 lerr = val == -HUGE(1) 2169 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(tname)//' is not' 2170 CALL msg(TRIM(s)//' an integer: '//TRIM(sval), modname, lerr) 2171 END FUNCTION getKeyByName_im11 2172 !============================================================================================================================== 2173 LOGICAL FUNCTION getKeyByName_rm11(keyn, val, tname, ky, def, lDisp) RESULT(lerr) 2174 CHARACTER(LEN=*), INTENT(IN) :: keyn(:), tname 2175 REAL , INTENT(OUT) :: val 2176 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 2177 REAL, OPTIONAL, INTENT(IN) :: def 2178 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 2179 !------------------------------------------------------------------------------------------------------------------------------ 2180 CHARACTER(LEN=maxlen) :: sval, s 2181 IF( PRESENT(def)) lerr = getKeyByName_sm11(keyn, sval, tname, ky, real2str(def), lDisp) 2182 IF(.NOT.PRESENT(def)) lerr = getKeyByName_sm11(keyn, sval, tname, ky, lDisp=lDisp) 2183 IF(lerr) RETURN 2184 val = str2real(sval) 2185 lerr = val == -HUGE(1.) 2186 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(tname)//' is not' 2187 CALL msg(TRIM(s)//' a real: '//TRIM(sval), modname, lerr) 2188 END FUNCTION getKeyByName_rm11 2189 !============================================================================================================================== 2190 LOGICAL FUNCTION getKeyByName_lm11(keyn, val, tname, ky, def, lDisp) RESULT(lerr) 2191 CHARACTER(LEN=*), INTENT(IN) :: keyn(:), tname 2192 LOGICAL, INTENT(OUT) :: val 2193 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 2194 LOGICAL, OPTIONAL, INTENT(IN) :: def 2195 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 2196 !------------------------------------------------------------------------------------------------------------------------------ 2197 CHARACTER(LEN=maxlen) :: sval, s 2198 INTEGER :: ival 2199 IF( PRESENT(def)) lerr = getKeyByName_sm11(keyn, sval, tname, ky, bool2str(def), lDisp) 2200 IF(.NOT.PRESENT(def)) lerr = getKeyByName_sm11(keyn, sval, tname, ky, lDisp=lDisp) 2201 IF(lerr) RETURN 2202 ival = str2bool(sval) 2203 lerr = ival == -1 2204 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(tname)//' is not' 2205 CALL msg(TRIM(s)//' a boolean: '//TRIM(sval), modname, lerr) 2206 IF(.NOT.lerr) val = ival == 1 2207 END FUNCTION getKeyByName_lm11 2208 !============================================================================================================================== 2209 !============================================================================================================================== 2210 LOGICAL FUNCTION getKeyByName_s1m1(keyn, val, tname, ky, def, lDisp) RESULT(lerr) 2211 CHARACTER(LEN=*), INTENT(IN) :: keyn, tname 2212 CHARACTER(LEN=maxlen), ALLOCATABLE, INTENT(OUT) :: val(:) 2213 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 2214 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: def 2215 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 2216 !------------------------------------------------------------------------------------------------------------------------------ 2217 CHARACTER(LEN=maxlen) :: sval 2218 lerr = getKeyByName_sm11([keyn], sval, tname, ky, def, lDisp); IF(lerr) RETURN 2219 lerr = strParse(sval, ',', val) 2220 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 2221 END FUNCTION getKeyByName_s1m1 2222 !============================================================================================================================== 2223 LOGICAL FUNCTION getKeyByName_i1m1(keyn, val, tname, ky, def, lDisp) RESULT(lerr) 2224 CHARACTER(LEN=*), INTENT(IN) :: keyn, tname 2225 INTEGER, ALLOCATABLE, INTENT(OUT) :: val(:) 2226 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 2227 INTEGER, OPTIONAL, INTENT(IN) :: def 2228 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 2229 !------------------------------------------------------------------------------------------------------------------------------ 2230 CHARACTER(LEN=maxlen) :: sval, s 2231 CHARACTER(LEN=maxlen), ALLOCATABLE :: svals(:) 2232 IF( PRESENT(def)) lerr = getKeyByName_sm11([keyn], sval, tname, ky, int2str(def), lDisp) 2233 IF(.NOT.PRESENT(def)) lerr = getKeyByName_sm11([keyn], sval, tname, ky, lDisp=lDisp) 2234 IF(lerr) RETURN 2235 lerr = strParse(sval, ',', svals) 2236 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 2237 val = str2int(svals) 2238 lerr = ANY(val == -HUGE(1)) 2239 s = 'key "'//TRIM(keyn)//'" of '//TRIM(tname)//' is not' 2240 CALL msg(TRIM(s)//' an integer: '//TRIM(sval), modname, lerr) 2241 END FUNCTION getKeyByName_i1m1 2242 !============================================================================================================================== 2243 LOGICAL FUNCTION getKeyByName_r1m1(keyn, val, tname, ky, def, lDisp) RESULT(lerr) 2244 CHARACTER(LEN=*), INTENT(IN) :: keyn, tname 2245 REAL, ALLOCATABLE, INTENT(OUT) :: val(:) 2246 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 2247 REAL, OPTIONAL, INTENT(IN) :: def 2248 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 2249 !------------------------------------------------------------------------------------------------------------------------------ 2250 CHARACTER(LEN=maxlen) :: sval, s 2251 CHARACTER(LEN=maxlen), ALLOCATABLE :: svals(:) 2252 IF( PRESENT(def)) lerr = getKeyByName_sm11([keyn], sval, tname, ky, real2str(def), lDisp) 2253 IF(.NOT.PRESENT(def)) lerr = getKeyByName_sm11([keyn], sval, tname, ky, lDisp=lDisp) 2254 IF(lerr) RETURN 2255 lerr = strParse(sval, ',', svals) 2256 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 2257 val = str2real(svals) 2258 lerr = ANY(val == -HUGE(1.)) 2259 s = 'key "'//TRIM(keyn)//'" of '//TRIM(tname)//' is not' 2260 CALL msg(TRIM(s)//' a real: '//TRIM(sval), modname, lerr) 2261 END FUNCTION getKeyByName_r1m1 2262 !============================================================================================================================== 2263 LOGICAL FUNCTION getKeyByName_l1m1(keyn, val, tname, ky, def, lDisp) RESULT(lerr) 2264 CHARACTER(LEN=*), INTENT(IN) :: keyn, tname 2265 LOGICAL, ALLOCATABLE, INTENT(OUT) :: val(:) 2266 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 2267 LOGICAL, OPTIONAL, INTENT(IN) :: def 2268 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 2269 !------------------------------------------------------------------------------------------------------------------------------ 2270 CHARACTER(LEN=maxlen) :: sval, s 2271 CHARACTER(LEN=maxlen), ALLOCATABLE :: svals(:) 2272 INTEGER, ALLOCATABLE :: ivals(:) 2273 IF( PRESENT(def)) lerr = getKeyByName_sm11([keyn], sval, tname, ky, bool2str(def), lDisp) 2274 IF(.NOT.PRESENT(def)) lerr = getKeyByName_sm11([keyn], sval, tname, ky, lDisp=lDisp) 2275 IF(lerr) RETURN 2276 lerr = strParse(sval, ',', svals) 2277 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 2278 ivals = str2bool(svals) 2279 lerr = ANY(ivals == -1) 2280 s = 'key "'//TRIM(keyn)//'" of '//TRIM(tname)//' is not' 2281 CALL msg(TRIM(s)//' a boolean: '//TRIM(sval), modname, lerr) 2282 IF(.NOT.lerr) val = ivals == 1 2283 END FUNCTION getKeyByName_l1m1 2284 !============================================================================================================================== 2285 !============================================================================================================================== 2286 LOGICAL FUNCTION getKeyByName_smm1(keyn, val, tname, ky, def, lDisp) RESULT(lerr) 2287 CHARACTER(LEN=*), INTENT(IN) :: keyn(:), tname 2288 CHARACTER(LEN=maxlen), ALLOCATABLE, INTENT(OUT) :: val(:) 2289 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 2290 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: def 2291 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 2292 !------------------------------------------------------------------------------------------------------------------------------ 2293 CHARACTER(LEN=maxlen) :: sval 2294 lerr = getKeyByName_sm11(keyn, sval, tname, ky, def, lDisp); IF(lerr) RETURN 2295 lerr = strParse(sval, ',', val) 2296 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 2297 END FUNCTION getKeyByName_smm1 2298 !============================================================================================================================== 2299 LOGICAL FUNCTION getKeyByName_imm1(keyn, val, tname, ky, def, lDisp) RESULT(lerr) 2300 CHARACTER(LEN=*), INTENT(IN) :: keyn(:), tname 2301 INTEGER, ALLOCATABLE, INTENT(OUT) :: val(:) 2302 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 2303 INTEGER, OPTIONAL, INTENT(IN) :: def 2304 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 2305 !------------------------------------------------------------------------------------------------------------------------------ 2306 CHARACTER(LEN=maxlen) :: sval, s 2307 CHARACTER(LEN=maxlen), ALLOCATABLE :: svals(:) 2308 IF( PRESENT(def)) lerr = getKeyByName_sm11(keyn, sval, tname, ky, int2str(def), lDisp) 2309 IF(.NOT.PRESENT(def)) lerr = getKeyByName_sm11(keyn, sval, tname, ky, lDisp=lDisp) 2310 IF(lerr) RETURN 2311 lerr = strParse(sval, ',', svals) 2312 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 2313 val = str2int(svals) 2314 lerr = ANY(val == -HUGE(1)) 2315 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(tname)//' is not' 2316 CALL msg(TRIM(s)//' an integer: '//TRIM(sval), modname, lerr) 2317 END FUNCTION getKeyByName_imm1 2318 !============================================================================================================================== 2319 LOGICAL FUNCTION getKeyByName_rmm1(keyn, val, tname, ky, def, lDisp) RESULT(lerr) 2320 CHARACTER(LEN=*), INTENT(IN) :: keyn(:), tname 2321 REAL, ALLOCATABLE, INTENT(OUT) :: val(:) 2322 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 2323 REAL, OPTIONAL, INTENT(IN) :: def 2324 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 2325 !------------------------------------------------------------------------------------------------------------------------------ 2326 CHARACTER(LEN=maxlen) :: sval, s 2327 CHARACTER(LEN=maxlen), ALLOCATABLE :: svals(:) 2328 IF( PRESENT(def)) lerr = getKeyByName_sm11(keyn, sval, tname, ky, real2str(def), lDisp) 2329 IF(.NOT.PRESENT(def)) lerr = getKeyByName_sm11(keyn, sval, tname, ky, lDisp=lDisp) 2330 IF(lerr) RETURN 2331 lerr = strParse(sval, ',', svals) 2332 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 2333 val = str2real(svals) 2334 lerr = ANY(val == -HUGE(1.)) 2335 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(tname)//' is not' 2336 CALL msg(TRIM(s)//' a real: '//TRIM(sval), modname, lerr) 2337 END FUNCTION getKeyByName_rmm1 2338 !============================================================================================================================== 2339 LOGICAL FUNCTION getKeyByName_lmm1(keyn, val, tname, ky, def, lDisp) RESULT(lerr) 2340 CHARACTER(LEN=*), INTENT(IN) :: keyn(:), tname 2341 LOGICAL, ALLOCATABLE, INTENT(OUT) :: val(:) 2342 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 2343 LOGICAL, OPTIONAL, INTENT(IN) :: def 2344 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 2345 !------------------------------------------------------------------------------------------------------------------------------ 2346 CHARACTER(LEN=maxlen) :: sval, s 2347 CHARACTER(LEN=maxlen), ALLOCATABLE :: svals(:) 2348 INTEGER, ALLOCATABLE :: ivals(:) 2349 IF( PRESENT(def)) lerr = getKeyByName_sm11(keyn, sval, tname, ky, bool2str(def), lDisp) 2350 IF(.NOT.PRESENT(def)) lerr = getKeyByName_sm11(keyn, sval, tname, ky, lDisp=lDisp) 2351 IF(lerr) RETURN 2352 lerr = strParse(sval, ',', svals) 2353 IF(fmsg('can''t parse '//TRIM(sval), modname, lerr)) RETURN 2354 ivals = str2bool(svals) 2355 lerr = ANY(ivals == -1) 2356 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(tname)//' is not' 2357 CALL msg(TRIM(s)//' a boolean: '//TRIM(sval), modname, lerr) 2358 IF(.NOT.lerr) val = ivals == 1 2359 END FUNCTION getKeyByName_lmm1 2360 !============================================================================================================================== 2361 !============================================================================================================================== 2362 LOGICAL FUNCTION getKeyByName_s1mm(keyn, val, tname, ky, def, lDisp) RESULT(lerr) 2363 CHARACTER(LEN=*), INTENT(IN) :: keyn, tname(:) 2364 CHARACTER(LEN=maxlen), ALLOCATABLE, INTENT(OUT) :: val(:) 2365 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 2366 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: def 2367 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 2368 lerr = getKeyByName_smmm([keyn], val, tname, ky, def, lDisp) 2369 END FUNCTION getKeyByName_s1mm 2370 !============================================================================================================================== 2371 LOGICAL FUNCTION getKeyByName_i1mm(keyn, val, tname, ky, def, lDisp) RESULT(lerr) 2372 CHARACTER(LEN=*), INTENT(IN) :: keyn, tname(:) 2373 INTEGER, ALLOCATABLE, INTENT(OUT) :: val(:) 2374 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 2375 INTEGER, OPTIONAL, INTENT(IN) :: def 2376 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 2377 lerr = getKeyByName_immm([keyn], val, tname, ky, def, lDisp) 2378 END FUNCTION getKeyByName_i1mm 2379 !============================================================================================================================== 2380 LOGICAL FUNCTION getKeyByName_r1mm(keyn, val, tname, ky, def, lDisp) RESULT(lerr) 2381 CHARACTER(LEN=*), INTENT(IN) :: keyn, tname(:) 2382 REAL, ALLOCATABLE, INTENT(OUT) :: val(:) 2383 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 2384 REAL, OPTIONAL, INTENT(IN) :: def 2385 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 2386 lerr = getKeyByName_rmmm([keyn], val, tname, ky, def, lDisp) 2387 END FUNCTION getKeyByName_r1mm 2388 !============================================================================================================================== 2389 LOGICAL FUNCTION getKeyByName_l1mm(keyn, val, tname, ky, def, lDisp) RESULT(lerr) 2390 CHARACTER(LEN=*), INTENT(IN) :: keyn, tname(:) 2391 LOGICAL, ALLOCATABLE, INTENT(OUT) :: val(:) 2392 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 2393 LOGICAL, OPTIONAL, INTENT(IN) :: def 2394 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 2395 lerr = getKeyByName_lmmm([keyn], val, tname, ky, def, lDisp) 2396 END FUNCTION getKeyByName_l1mm 2397 !============================================================================================================================== 2398 !============================================================================================================================== 2399 LOGICAL FUNCTION getKeyByName_smmm(keyn, val, tname, ky, def, lDisp) RESULT(lerr) 2400 CHARACTER(LEN=*), INTENT(IN) :: keyn(:), tname(:) 2401 CHARACTER(LEN=maxlen), ALLOCATABLE, INTENT(OUT) :: val(:) 2402 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 2403 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: def 2404 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 2405 !------------------------------------------------------------------------------------------------------------------------------ 2406 CHARACTER(LEN=maxlen) :: s 1704 2407 INTEGER :: iq, nq 1705 IF(test(getKey_sm(keyn, sval, ky, nam), lerr)) RETURN 1706 nq = SIZE(sval); ALLOCATE(val(nq)) 1707 lerr = .FALSE.; DO iq=1, nq; val(iq)=str2bool(sval(iq)); END DO 1708 END FUNCTION getKey_lm 2408 LOGICAL :: lD 2409 nq = SIZE(tname); ALLOCATE(val(nq)) 2410 lD = .TRUE.; IF(PRESENT(lDisp)) lD = lDisp 2411 s = 'key "'//TRIM(strStack(keyn, '/'))//'"' 2412 lerr = .TRUE. 2413 IF(PRESENT(ky)) THEN; val = fgetKey(ky) !--- "ky" 2414 ELSE IF(ALLOCATED(tracers)) THEN; val = fgetKey(tracers(:)%keys) !--- "tracers" 2415 IF(lerr .AND. ASSOCIATED(isotope)) val = fgetKey(isotope%keys(:)) !--- "isotope" 2416 END IF 2417 IF(.NOT.PRESENT(def)) THEN; CALL msg('No '//TRIM(s)//' found', modname, lD); RETURN; END IF 2418 2419 !--- DEFAULT VALUE 2420 val = [(def, iq = 1, SIZE(tname))] 2421 CALL msg('Using defaut value for '//TRIM(s)//': '//TRIM(def), modname, lD) 2422 2423 CONTAINS 2424 2425 FUNCTION fgetKey(ky) RESULT(val) 2426 CHARACTER(LEN=maxlen), ALLOCATABLE :: val(:) 2427 TYPE(keys_type), INTENT(IN) :: ky(:) 2428 LOGICAL, ALLOCATABLE :: ler(:) 2429 lerr = SIZE(ky) == 0; IF(lerr) RETURN 2430 ALLOCATE(ler(SIZE(tname))) 2431 val = [(fgetKeyIdx(strIdx(ky(:)%name, tname(iq)), keyn, ky, ler(iq)), iq = 1, SIZE(tname))] 2432 lerr = ANY(ler) 2433 END FUNCTION fgetKey 2434 2435 END FUNCTION getKeyByName_smmm 2436 !============================================================================================================================== 2437 LOGICAL FUNCTION getKeyByName_immm(keyn, val, tname, ky, def, lDisp) RESULT(lerr) 2438 CHARACTER(LEN=*), INTENT(IN) :: keyn(:), tname(:) 2439 INTEGER, ALLOCATABLE, INTENT(OUT) :: val(:) 2440 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 2441 INTEGER, OPTIONAL, INTENT(IN) :: def 2442 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 2443 !------------------------------------------------------------------------------------------------------------------------------ 2444 CHARACTER(LEN=maxlen) :: s 2445 CHARACTER(LEN=maxlen), ALLOCATABLE :: svals(:) 2446 LOGICAL, ALLOCATABLE :: ll(:) 2447 IF( PRESENT(def)) lerr = getKeyByName_smmm(keyn, svals, tname, ky, int2str(def), lDisp) 2448 IF(.NOT.PRESENT(def)) lerr = getKeyByName_smmm(keyn, svals, tname, ky, lDisp=lDisp) 2449 IF(lerr) RETURN 2450 val = str2int(svals) 2451 ll = val == -HUGE(1) 2452 lerr = ANY(ll); IF(.NOT.lerr) RETURN 2453 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(strStack(tname, MASK=ll))//' is not' 2454 CALL msg(TRIM(s)//' an integer: '//TRIM(strStack(svals, MASK=ll)), modname) 2455 END FUNCTION getKeyByName_immm 2456 !============================================================================================================================== 2457 LOGICAL FUNCTION getKeyByName_rmmm(keyn, val, tname, ky, def, lDisp) RESULT(lerr) 2458 CHARACTER(LEN=*), INTENT(IN) :: keyn(:), tname(:) 2459 REAL, ALLOCATABLE, INTENT(OUT) :: val(:) 2460 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 2461 REAL, OPTIONAL, INTENT(IN) :: def 2462 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 2463 !------------------------------------------------------------------------------------------------------------------------------ 2464 CHARACTER(LEN=maxlen) :: s 2465 CHARACTER(LEN=maxlen), ALLOCATABLE :: svals(:) 2466 LOGICAL, ALLOCATABLE :: ll(:) 2467 IF( PRESENT(def)) lerr = getKeyByName_smmm(keyn, svals, tname, ky, real2str(def), lDisp) 2468 IF(.NOT.PRESENT(def)) lerr = getKeyByName_smmm(keyn, svals, tname, ky, lDisp=lDisp) 2469 IF(lerr) RETURN 2470 val = str2real(svals) 2471 ll = val == -HUGE(1.) 2472 lerr = ANY(ll); IF(.NOT.lerr) RETURN 2473 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(strStack(tname, MASK=ll))//' is not' 2474 CALL msg(TRIM(s)//' a real: '//TRIM(strStack(svals, MASK=ll)), modname) 2475 END FUNCTION getKeyByName_rmmm 2476 !============================================================================================================================== 2477 LOGICAL FUNCTION getKeyByName_lmmm(keyn, val, tname, ky, def, lDisp) RESULT(lerr) 2478 CHARACTER(LEN=*), INTENT(IN) :: keyn(:), tname(:) 2479 LOGICAL, ALLOCATABLE, INTENT(OUT) :: val(:) 2480 TYPE(keys_type), OPTIONAL, INTENT(IN) :: ky(:) 2481 LOGICAL, OPTIONAL, INTENT(IN) :: def 2482 LOGICAL, OPTIONAL, INTENT(IN) :: lDisp 2483 !------------------------------------------------------------------------------------------------------------------------------ 2484 CHARACTER(LEN=maxlen) :: s 2485 CHARACTER(LEN=maxlen), ALLOCATABLE :: svals(:) 2486 LOGICAL, ALLOCATABLE :: ll(:) 2487 INTEGER, ALLOCATABLE :: ivals(:) 2488 IF( PRESENT(def)) lerr = getKeyByName_smmm(keyn, svals, tname, ky, bool2str(def), lDisp) 2489 IF(.NOT.PRESENT(def)) lerr = getKeyByName_smmm(keyn, svals, tname, ky, lDisp=lDisp) 2490 IF(lerr) RETURN 2491 ivals = str2bool(svals) 2492 ll = ivals == -1 2493 lerr = ANY(ll); IF(.NOT.lerr) THEN; val = ivals == 1; RETURN; END IF 2494 s = 'key "'//TRIM(strStack(keyn, '/'))//'" of '//TRIM(strStack(tname, MASK=ll))//' is not' 2495 CALL msg(TRIM(s)//' a boolean: '//TRIM(strStack(svals, MASK=ll)), modname) 2496 END FUNCTION getKeyByName_lmmm 1709 2497 !============================================================================================================================== 1710 2498 … … 1808 2596 IF(.NOT.PRESENT(phases)) out = [( addPhase_i1(s(k), ipha, known_phases), k=1, SIZE(s) )] 1809 2597 END FUNCTION addPhase_im 2598 !============================================================================================================================== 2599 2600 2601 !============================================================================================================================== 2602 !=== APPEND TRACERS DATABASE "tracs" WITH TRACERS/KEYS "tname"/"keys" ; SAME FOR INTERNAL DATABASE "tracers" ================== 2603 !============================================================================================================================== 2604 LOGICAL FUNCTION addTracer_1(tname, keys, tracs) RESULT(lerr) 2605 CHARACTER(LEN=*), INTENT(IN) :: tname 2606 TYPE(keys_type), INTENT(IN) :: keys 2607 TYPE(trac_type), ALLOCATABLE, INTENT(INOUT) :: tracs(:) 2608 TYPE(trac_type), ALLOCATABLE :: tr(:) 2609 CHARACTER(LEN=maxlen), ALLOCATABLE :: tnames(:) 2610 INTEGER :: nt, ix 2611 IF(ALLOCATED(tracs)) THEN 2612 lerr = getKey('name', tnames, ky=tracs(:)%keys); IF(lerr) RETURN 2613 nt = SIZE(tracs) 2614 ix = strIdx(tnames, tname) 2615 CALL msg('Modifying existing tracer "'//TRIM(tname)//'"', modname, ix /= 0) 2616 CALL msg('Appending with tracer "' //TRIM(tname)//'"', modname, ix == 0) 2617 IF(ix == 0) THEN 2618 ix = nt+1; ALLOCATE(tr(nt+1)); tr(1:nt) = tracs(1:nt); CALL MOVE_ALLOC(FROM=tr, TO=tracs) 2619 END IF 2620 ELSE 2621 CALL msg('Creating a tracer descriptor with tracer "'//TRIM(tname)//'"', modname) 2622 ix = 1; ALLOCATE(tracs(1)) 2623 END IF 2624 CALL addKey('name', tname, tracs(ix)%keys) 2625 tracs(ix)%name = tname 2626 tracs(ix)%keys = keys 2627 2628 END FUNCTION addTracer_1 2629 !============================================================================================================================== 2630 LOGICAL FUNCTION addTracer_1def(tname, keys) RESULT(lerr) 2631 CHARACTER(LEN=*), INTENT(IN) :: tname 2632 TYPE(keys_type), INTENT(IN) :: keys 2633 lerr = addTracer_1(tname, keys, tracers) 2634 END FUNCTION addTracer_1def 2635 !============================================================================================================================== 2636 2637 2638 !============================================================================================================================== 2639 LOGICAL FUNCTION delTracer_1(tname, tracs) RESULT(lerr) 2640 CHARACTER(LEN=*), INTENT(IN) :: tname 2641 TYPE(trac_type), ALLOCATABLE, TARGET, INTENT(INOUT) :: tracs(:) 2642 TYPE(trac_type), ALLOCATABLE :: tr(:) 2643 CHARACTER(LEN=maxlen), ALLOCATABLE :: tnames(:) 2644 INTEGER :: nt, ix 2645 lerr = .NOT.ALLOCATED(tracs) 2646 IF(fmsg('Can''t remove tracer "'//TRIM(tname)//'" from an empty tracers descriptor', modname, lerr)) RETURN 2647 nt = SIZE(tracs) 2648 lerr = getKey('name', tnames, ky=tracs(:)%keys); IF(lerr) RETURN 2649 ix = strIdx(tnames, tname) 2650 CALL msg('Removing tracer "' //TRIM(tname)//'"', modname, ix /= 0) 2651 CALL msg('Can''t remove unknown tracer "'//TRIM(tname)//'"', modname, ix == 0) 2652 IF(ix /= 0) THEN 2653 ALLOCATE(tr(nt-1)); tr(1:ix-1) = tracs(1:ix-1); tr(ix:nt-1) = tracs(ix+1:nt); CALL MOVE_ALLOC(FROM=tr, TO=tracs) 2654 END IF 2655 END FUNCTION delTracer_1 2656 !============================================================================================================================== 2657 LOGICAL FUNCTION delTracer_1def(tname) RESULT(lerr) 2658 CHARACTER(LEN=*), INTENT(IN) :: tname 2659 lerr = delTracer(tname, tracers) 2660 END FUNCTION delTracer_1def 1810 2661 !============================================================================================================================== 1811 2662 … … 1908 2759 !============================================================================================================================== 1909 2760 1910 1911 !==============================================================================================================================1912 !=== GET THE NAME(S) OF THE ANCESTOR(S) OF TRACER(S) "tname" AT GENERATION "igen" IN THE TRACERS DESCRIPTORS LIST "tr" =======1913 !==============================================================================================================================1914 SUBROUTINE ancestor_1(t, out, tname, igen)1915 TYPE(trac_type), INTENT(IN) :: t(:)1916 CHARACTER(LEN=maxlen), INTENT(OUT) :: out1917 CHARACTER(LEN=*), INTENT(IN) :: tname1918 INTEGER, OPTIONAL, INTENT(IN) :: igen1919 !------------------------------------------------------------------------------------------------------------------------------1920 INTEGER :: ix1921 CALL idxAncestor_1(t, ix, tname, igen)1922 out = ''; IF(ix /= 0) out = t(ix)%name1923 END SUBROUTINE ancestor_11924 !==============================================================================================================================1925 SUBROUTINE ancestor_mt(t, out, tname, igen)1926 TYPE(trac_type), INTENT(IN) :: t(:)1927 CHARACTER(LEN=*), INTENT(IN) :: tname(:)1928 CHARACTER(LEN=maxlen), INTENT(OUT) :: out(SIZE(tname))1929 INTEGER, OPTIONAL, INTENT(IN) :: igen1930 !------------------------------------------------------------------------------------------------------------------------------1931 INTEGER :: ix(SIZE(tname))1932 CALL idxAncestor_mt(t, ix, tname, igen)1933 out(:) = ''; WHERE(ix /= 0) out = t(ix)%name1934 END SUBROUTINE ancestor_mt1935 !==============================================================================================================================1936 SUBROUTINE ancestor_m(t, out, igen)1937 TYPE(trac_type), INTENT(IN) :: t(:)1938 CHARACTER(LEN=maxlen), INTENT(OUT) :: out(SIZE(t))1939 INTEGER, OPTIONAL, INTENT(IN) :: igen1940 !------------------------------------------------------------------------------------------------------------------------------1941 INTEGER :: ix(SIZE(t))1942 CALL idxAncestor_m(t, ix, igen)1943 out(:) = ''; WHERE(ix /= 0) out = t(ix)%name1944 END SUBROUTINE ancestor_m1945 !==============================================================================================================================1946 1947 1948 !==============================================================================================================================1949 !=== GET THE INDEX(ES) OF THE GENERATION "igen" ANCESTOR(S) OF "tname" (t%name IF UNSPECIFIED) IN THE "t" LIST ================1950 !==============================================================================================================================1951 SUBROUTINE idxAncestor_1(t, idx, tname, igen)1952 TYPE(trac_type), INTENT(IN) :: t(:)1953 INTEGER, INTENT(OUT) :: idx1954 CHARACTER(LEN=*), INTENT(IN) :: tname1955 INTEGER, OPTIONAL, INTENT(IN) :: igen1956 INTEGER :: ig1957 ig = 0; IF(PRESENT(igen)) ig = igen1958 idx = strIdx(t(:)%name, tname)1959 IF(idx == 0) RETURN !--- Tracer not found1960 IF(t(idx)%iGeneration <= ig) RETURN !--- Tracer has a lower generation number than asked generation 'igen"1961 DO WHILE(t(idx)%iGeneration > ig); idx = strIdx(t(:)%name, t(idx)%parent); END DO1962 END SUBROUTINE idxAncestor_11963 !------------------------------------------------------------------------------------------------------------------------------1964 SUBROUTINE idxAncestor_mt(t, idx, tname, igen)1965 TYPE(trac_type), INTENT(IN) :: t(:)1966 CHARACTER(LEN=*), INTENT(IN) :: tname(:)1967 INTEGER, INTENT(OUT) :: idx(SIZE(tname))1968 INTEGER, OPTIONAL, INTENT(IN) :: igen1969 INTEGER :: ix1970 DO ix = 1, SIZE(tname); CALL idxAncestor_1(t, idx(ix), tname(ix), igen); END DO1971 END SUBROUTINE idxAncestor_mt1972 !------------------------------------------------------------------------------------------------------------------------------1973 SUBROUTINE idxAncestor_m(t, idx, igen)1974 TYPE(trac_type), INTENT(IN) :: t(:)1975 INTEGER, INTENT(OUT) :: idx(SIZE(t))1976 INTEGER, OPTIONAL, INTENT(IN) :: igen1977 INTEGER :: ix1978 DO ix = 1, SIZE(t); CALL idxAncestor_1(t, idx(ix), t(ix)%name, igen); END DO1979 END SUBROUTINE idxAncestor_m1980 !==============================================================================================================================1981 1982 1983 2761 END MODULE readTracFiles_mod -
LMDZ6/branches/cirrus/libf/misc/strings_mod.F90
r4454 r5202 10 10 PUBLIC :: is_numeric, bool2str, int2str, real2str, dble2str 11 11 PUBLIC :: reduceExpr, str2bool, str2int, str2real, str2dble 12 PUBLIC :: addQuotes, checkList, removeComment , test12 PUBLIC :: addQuotes, checkList, removeComment 13 13 14 14 INTERFACE get_in; MODULE PROCEDURE getin_s, getin_i, getin_r, getin_l; END INTERFACE get_in … … 22 22 INTERFACE strCount; MODULE PROCEDURE strCount_m1, strCount_11, strCount_1m; END INTERFACE strCount 23 23 INTERFACE strReplace; MODULE PROCEDURE strReplace_1, strReplace_m; END INTERFACE strReplace 24 INTERFACE cat; MODULE PROCEDURE horzcat_s1, horzcat_i1, horzcat_r1, & 25 ! horzcat_d1, horzcat_dm, 26 horzcat_sm, horzcat_im, horzcat_rm; END INTERFACE cat 27 INTERFACE find; MODULE PROCEDURE strFind, find_int, find_boo; END INTERFACE find 24 INTERFACE cat; MODULE PROCEDURE horzcat_s00, horzcat_i00, horzcat_r00, & !horzcat_d00, & 25 horzcat_s10, horzcat_i10, horzcat_r10, & !horzcat_d10, & 26 horzcat_s11, horzcat_i11, horzcat_r11, & !horzcat_d11, & 27 horzcat_s21, horzcat_i21, horzcat_r21; END INTERFACE cat !horzcat_d21 28 INTERFACE strFind; MODULE PROCEDURE strFind_1, strFind_m; END INTERFACE strFind 29 INTERFACE find; MODULE PROCEDURE strFind_1, strFind_m, intFind_1, intFind_m, booFind; END INTERFACE find 28 30 INTERFACE dispOutliers; MODULE PROCEDURE dispOutliers_1, dispOutliers_2; END INTERFACE dispOutliers 29 31 INTERFACE reduceExpr; MODULE PROCEDURE reduceExpr_1, reduceExpr_m; END INTERFACE reduceExpr … … 36 38 CONTAINS 37 39 38 !==============================================================================================================================39 LOGICAL FUNCTION test(lcond, lout) RESULT(lerr)40 LOGICAL, INTENT(IN) :: lcond41 LOGICAL, INTENT(OUT) :: lout42 lerr = lcond; lout = lcond43 END FUNCTION test44 !==============================================================================================================================45 46 40 47 41 !============================================================================================================================== 48 42 SUBROUTINE init_printout(lunout_, prt_level_) 43 IMPLICIT NONE 49 44 INTEGER, INTENT(IN) :: lunout_, prt_level_ 50 45 lunout = lunout_ … … 58 53 !============================================================================================================================== 59 54 SUBROUTINE getin_s(nam, val, def) 60 USE ioipsl_getincom, ONLY: getin 55 USE ioipsl_getincom, ONLY: getin 56 IMPLICIT NONE 61 57 CHARACTER(LEN=*), INTENT(IN) :: nam 62 58 CHARACTER(LEN=*), INTENT(INOUT) :: val … … 67 63 !============================================================================================================================== 68 64 SUBROUTINE getin_i(nam, val, def) 69 USE ioipsl_getincom, ONLY: getin 65 USE ioipsl_getincom, ONLY: getin 66 IMPLICIT NONE 70 67 CHARACTER(LEN=*), INTENT(IN) :: nam 71 68 INTEGER, INTENT(INOUT) :: val … … 76 73 !============================================================================================================================== 77 74 SUBROUTINE getin_r(nam, val, def) 78 USE ioipsl_getincom, ONLY: getin 75 USE ioipsl_getincom, ONLY: getin 76 IMPLICIT NONE 79 77 CHARACTER(LEN=*), INTENT(IN) :: nam 80 78 REAL, INTENT(INOUT) :: val … … 85 83 !============================================================================================================================== 86 84 SUBROUTINE getin_l(nam, val, def) 87 USE ioipsl_getincom, ONLY: getin 85 USE ioipsl_getincom, ONLY: getin 86 IMPLICIT NONE 88 87 CHARACTER(LEN=*), INTENT(IN) :: nam 89 88 LOGICAL, INTENT(INOUT) :: val … … 99 98 !============================================================================================================================== 100 99 SUBROUTINE msg_1(str, modname, ll, unit) 100 IMPLICIT NONE 101 101 !--- Display a simple message "str". Optional parameters: 102 102 ! * "modname": module name, displayed in front of the message (with ": " separator) if present. … … 118 118 !============================================================================================================================== 119 119 SUBROUTINE msg_m(str, modname, ll, unit, nmax) 120 IMPLICIT NONE 120 121 !--- Same as msg_1 with multiple strings that are stacked (separator: coma) on up to "nmax" full lines. 121 122 CHARACTER(LEN=*), INTENT(IN) :: str(:) … … 138 139 !============================================================================================================================== 139 140 LOGICAL FUNCTION fmsg_1(str, modname, ll, unit) RESULT(l) 141 IMPLICIT NONE 140 142 CHARACTER(LEN=*), INTENT(IN) :: str 141 143 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: modname … … 152 154 !============================================================================================================================== 153 155 LOGICAL FUNCTION fmsg_m(str, modname, ll, unit, nmax) RESULT(l) 156 IMPLICIT NONE 154 157 CHARACTER(LEN=*), INTENT(IN) :: str(:) 155 158 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: modname … … 173 176 !============================================================================================================================== 174 177 ELEMENTAL CHARACTER(LEN=maxlen) FUNCTION strLower(str) RESULT(out) 178 IMPLICIT NONE 175 179 CHARACTER(LEN=*), INTENT(IN) :: str 176 180 INTEGER :: k … … 182 186 !============================================================================================================================== 183 187 ELEMENTAL CHARACTER(LEN=maxlen) FUNCTION strUpper(str) RESULT(out) 188 IMPLICIT NONE 184 189 CHARACTER(LEN=*), INTENT(IN) :: str 185 190 INTEGER :: k … … 199 204 !============================================================================================================================== 200 205 CHARACTER(LEN=maxlen) FUNCTION strHead_1(str, sep, lBackward) RESULT(out) 206 IMPLICIT NONE 201 207 CHARACTER(LEN=*), INTENT(IN) :: str 202 208 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: sep … … 214 220 !============================================================================================================================== 215 221 FUNCTION strHead_m(str, sep, lBackward) RESULT(out) 222 IMPLICIT NONE 216 223 CHARACTER(LEN=maxlen), ALLOCATABLE :: out(:) 217 224 CHARACTER(LEN=*), INTENT(IN) :: str(:) … … 235 242 !============================================================================================================================== 236 243 CHARACTER(LEN=maxlen) FUNCTION strTail_1(str, sep, lBackWard) RESULT(out) 244 IMPLICIT NONE 237 245 CHARACTER(LEN=*), INTENT(IN) :: str 238 246 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: sep … … 250 258 !============================================================================================================================== 251 259 FUNCTION strTail_m(str, sep, lBackWard) RESULT(out) 260 IMPLICIT NONE 252 261 CHARACTER(LEN=maxlen), ALLOCATABLE :: out(:) 253 262 CHARACTER(LEN=*), INTENT(IN) :: str(:) … … 271 280 !============================================================================================================================== 272 281 FUNCTION strStack(str, sep, mask) RESULT(out) 282 IMPLICIT NONE 273 283 CHARACTER(LEN=:), ALLOCATABLE :: out 274 284 CHARACTER(LEN=*), INTENT(IN) :: str(:) … … 292 302 !============================================================================================================================== 293 303 FUNCTION strStackm(str, sep, nmax) RESULT(out) 304 IMPLICIT NONE 294 305 CHARACTER(LEN=maxlen), ALLOCATABLE :: out(:) 295 306 CHARACTER(LEN=*), INTENT(IN) :: str(:) … … 324 335 !============================================================================================================================== 325 336 SUBROUTINE strClean_1(str) 337 IMPLICIT NONE 326 338 CHARACTER(LEN=*), INTENT(INOUT) :: str 327 339 INTEGER :: k, n, m … … 337 349 !============================================================================================================================== 338 350 SUBROUTINE strClean_m(str) 351 IMPLICIT NONE 339 352 CHARACTER(LEN=*), INTENT(INOUT) :: str(:) 340 353 INTEGER :: k … … 349 362 !============================================================================================================================== 350 363 SUBROUTINE strReduce_1(str, nb) 364 IMPLICIT NONE 351 365 CHARACTER(LEN=*), ALLOCATABLE, INTENT(INOUT) :: str(:) 352 366 INTEGER, OPTIONAL, INTENT(OUT) :: nb … … 366 380 !============================================================================================================================== 367 381 SUBROUTINE strReduce_2(str1, str2) 382 IMPLICIT NONE 368 383 CHARACTER(LEN=*), ALLOCATABLE, INTENT(INOUT) :: str1(:) 369 384 CHARACTER(LEN=*), INTENT(IN) :: str2(:) … … 392 407 !============================================================================================================================== 393 408 INTEGER FUNCTION strIdx_1(str, s) RESULT(out) 409 IMPLICIT NONE 394 410 CHARACTER(LEN=*), INTENT(IN) :: str(:), s 395 411 DO out = 1, SIZE(str); IF(str(out) == s) EXIT; END DO … … 398 414 !============================================================================================================================== 399 415 FUNCTION strIdx_m(str, s, n) RESULT(out) 416 IMPLICIT NONE 400 417 CHARACTER(LEN=*), INTENT(IN) :: str(:), s(:) 401 418 INTEGER, OPTIONAL, INTENT(OUT) :: n … … 412 429 !=== GET THE INDEX LIST OF THE ELEMENTS OF "str(:)" EQUAL TO "s" AND OPTIONALY, ITS LENGTH "n" ================================ 413 430 !============================================================================================================================== 414 FUNCTION strFind(str, s, n) RESULT(out) 431 FUNCTION strFind_1(str, s, n) RESULT(out) 432 IMPLICIT NONE 415 433 CHARACTER(LEN=*), INTENT(IN) :: str(:), s 416 434 INTEGER, OPTIONAL, INTENT(OUT) :: n … … 420 438 out = PACK( [(k, k=1, SIZE(str(:), DIM=1))], MASK = str(:) == s ) 421 439 IF(PRESENT(n)) n = SIZE(out(:), DIM=1) 422 END FUNCTION strFind 423 !============================================================================================================================== 424 FUNCTION find_int(i,j,n) RESULT(out) 440 END FUNCTION strFind_1 441 !============================================================================================================================== 442 FUNCTION strFind_m(str, s, n) RESULT(out) 443 IMPLICIT NONE 444 CHARACTER(LEN=*), INTENT(IN) :: str(:), s(:) 445 INTEGER, OPTIONAL, INTENT(OUT) :: n 446 INTEGER, ALLOCATABLE :: out(:) 447 !------------------------------------------------------------------------------------------------------------------------------ 448 INTEGER :: k 449 out = [(strFind_1(str, s(k)), k=1, SIZE(s))] 450 IF(PRESENT(n)) n = SIZE(out(:), DIM=1) 451 END FUNCTION strFind_m 452 !============================================================================================================================== 453 FUNCTION intFind_1(i,j,n) RESULT(out) 454 IMPLICIT NONE 425 455 INTEGER, INTENT(IN) :: i(:), j 426 456 INTEGER, OPTIONAL, INTENT(OUT) :: n … … 430 460 out = PACK( [(k, k=1, SIZE(i(:), DIM=1))], MASK = i(:) == j ) 431 461 IF(PRESENT(n)) n = SIZE(out(:), DIM=1) 432 END FUNCTION find_int 433 !============================================================================================================================== 434 FUNCTION find_boo(l,n) RESULT(out) 435 LOGICAL, INTENT(IN) :: l(:) 462 END FUNCTION intFind_1 463 !============================================================================================================================== 464 FUNCTION intFind_m(i,j,n) RESULT(out) 465 IMPLICIT NONE 466 INTEGER, INTENT(IN) :: i(:), j(:) 467 INTEGER, OPTIONAL, INTENT(OUT) :: n 468 INTEGER, ALLOCATABLE :: out(:) 469 !------------------------------------------------------------------------------------------------------------------------------ 470 INTEGER :: k 471 out = [(intFind_1(i, j(k)), k=1, SIZE(j))] 472 IF(PRESENT(n)) n = SIZE(out(:), DIM=1) 473 END FUNCTION intFind_m 474 !============================================================================================================================== 475 FUNCTION booFind(l,n) RESULT(out) 476 IMPLICIT NONE 477 LOGICAL, INTENT(IN) :: l(:) 436 478 INTEGER, OPTIONAL, INTENT(OUT) :: n 437 479 INTEGER, ALLOCATABLE :: out(:) … … 440 482 out = PACK( [(k, k=1, SIZE(l(:), DIM=1))], MASK = l(:) ) 441 483 IF(PRESENT(n)) n = SIZE(out(:), DIM=1) 442 END FUNCTION find_boo484 END FUNCTION booFind 443 485 !============================================================================================================================== 444 486 … … 450 492 !============================================================================================================================== 451 493 LOGICAL FUNCTION strIdx_prv(rawList, del, ibeg, idx, idel, lSc) RESULT(lerr) 494 IMPLICIT NONE 452 495 CHARACTER(LEN=*), INTENT(IN) :: rawList !--- String in which delimiters have to be identified 453 496 CHARACTER(LEN=*), INTENT(IN) :: del(:) !--- List of delimiters … … 469 512 END IF 470 513 471 IF(test(idx == 1 .AND. INDEX('+-',del(idel)) /= 0, lerr)) RETURN!--- The front delimiter is different from +/-: error472 IF( idx /= 1 .AND. is_numeric(rawList(ibeg:idx-1))) RETURN!--- The input string head is a valid number514 lerr = idx == 1 .AND. INDEX('+-',del(idel)) /= 0; IF(lerr) RETURN !--- The front delimiter is different from +/-: error 515 IF( idx /= 1 .AND. is_numeric(rawList(ibeg:idx-1))) RETURN !--- The input string head is a valid number 473 516 474 517 !=== The string part in front of the 1st delimiter is not a valid number: search for next delimiter index "idx" … … 503 546 !============================================================================================================================== 504 547 LOGICAL FUNCTION strCount_11(rawList, delimiter, nb, lSc) RESULT(lerr) 548 IMPLICIT NONE 505 549 CHARACTER(LEN=*), INTENT(IN) :: rawList 506 550 CHARACTER(LEN=*), INTENT(IN) :: delimiter … … 514 558 !============================================================================================================================== 515 559 LOGICAL FUNCTION strCount_m1(rawList, delimiter, nb, lSc) RESULT(lerr) 560 IMPLICIT NONE 516 561 CHARACTER(LEN=*), INTENT(IN) :: rawList(:) 517 562 CHARACTER(LEN=*), INTENT(IN) :: delimiter … … 530 575 !============================================================================================================================== 531 576 LOGICAL FUNCTION strCount_1m(rawList, delimiter, nb, lSc) RESULT(lerr) 577 IMPLICIT NONE 532 578 CHARACTER(LEN=*), INTENT(IN) :: rawList 533 579 CHARACTER(LEN=*), INTENT(IN) :: delimiter(:) … … 560 606 !============================================================================================================================== 561 607 LOGICAL FUNCTION strParse(rawList, delimiter, keys, n, vals) RESULT(lerr) 608 IMPLICIT NONE 562 609 CHARACTER(LEN=*), INTENT(IN) :: rawList, delimiter 563 610 CHARACTER(LEN=maxlen), ALLOCATABLE, INTENT(OUT) :: keys(:) … … 570 617 r = TRIM(ADJUSTL(rawList)) 571 618 nr = LEN_TRIM(r); IF(nr == 0) THEN; keys = ['']; RETURN; END IF 572 CALL strParse_prv(nk) !--- COUNT THE ELEMENTS 573 ALLOCATE(keys(nk)) 574 IF(PRESENT(vals)) THEN 575 ALLOCATE(vals(nk)); CALL strParse_prv(nk, keys, vals) !--- PARSE THE KEYS 576 ELSE 577 CALL strParse_prv(nk, keys) !--- PARSE THE KEYS 578 END IF 579 IF(PRESENT(n)) n = nk 619 nk = countK() !--- COUNT THE ELEMENTS 620 CALL parseK(keys) !--- PARSE THE KEYS 621 IF(PRESENT(vals)) CALL parseV(vals) !--- PARSE <key>=<val> PAIRS 622 IF(PRESENT(n)) n = nk !--- RETURN THE NUMBER OF KEYS 580 623 581 624 CONTAINS 582 625 583 626 !------------------------------------------------------------------------------------------------------------------------------ 584 SUBROUTINE strParse_prv(nkeys, keys, vals) 585 !--- * Get the number of elements after parsing ("nkeys" only is present) 586 !--- * Parse the <key>=<val> pairs and store result in "keys" and "vals" (already allocated) 587 IMPLICIT NONE 588 INTEGER, INTENT(OUT) :: nkeys 589 CHARACTER(LEN=maxlen), OPTIONAL, INTENT(OUT) :: keys(:) 590 CHARACTER(LEN=maxlen), OPTIONAL, INTENT(OUT) :: vals(:) 591 !------------------------------------------------------------------------------------------------------------------------------ 592 INTEGER :: ib, ie 593 nkeys = 1; ib = 1 627 INTEGER FUNCTION countK() RESULT(nkeys) 628 !--- Get the number of elements after parsing. 629 IMPLICIT NONE 630 !------------------------------------------------------------------------------------------------------------------------------ 631 INTEGER :: ib, ie, nl 632 nkeys = 1; ib = 1; nl = LEN(delimiter) 594 633 DO 595 634 ie = INDEX(rawList(ib:nr), delimiter)+ib-1 !--- Determine the next separator start index 596 635 IF(ie == ib-1) EXIT 597 IF(PRESENT(keys)) keys(nkeys) = r(ib:ie-1) !--- Get the ikth key 598 IF(PRESENT(vals)) CALL parseKeys(keys(nkeys), vals(nkeys)) !--- Parse the ikth <key>=<val> pair 636 ib = ie + nl 637 DO WHILE(ANY([0, 9, 32] == IACHAR(r(ib:ib))) .AND. ib < nr) !--- Skip blanks (ascii): NULL (0), TAB (9), SPACE (32) 638 ib = ib + 1 639 END DO !--- Skip spaces before next chain 640 nkeys = nkeys+1 641 END DO 642 END FUNCTION countK 643 644 !------------------------------------------------------------------------------------------------------------------------------ 645 SUBROUTINE parseK(keys) 646 !--- Parse the string separated by "delimiter" from "rawList" into "keys(:)" 647 IMPLICIT NONE 648 CHARACTER(LEN=maxlen), ALLOCATABLE, INTENT(OUT) :: keys(:) 649 !------------------------------------------------------------------------------------------------------------------------------ 650 INTEGER :: ib, ie, ik 651 ALLOCATE(keys(nk)) 652 ib = 1 653 DO ik = 1, nk 654 ie = INDEX(rawList(ib:nr), delimiter)+ib-1 !--- Determine the next separator start index 655 IF(ie == ib-1) EXIT 656 keys(ik) = r(ib:ie-1) !--- Get the ikth key 599 657 ib = ie + LEN(delimiter) 600 658 DO WHILE(r(ib:ib) == ' ' .AND. ib < nr); ib = ib + 1; END DO !--- Skip spaces before next chain 601 nkeys = nkeys+1 602 END DO 603 IF(PRESENT(keys)) keys(nkeys) = r(ib:nr) !--- Get the last key 604 IF(PRESENT(vals)) CALL parseKeys(keys(nkeys), vals(nkeys)) !--- Parse the last <key>=<val> pair 605 END SUBROUTINE strParse_prv 606 607 !------------------------------------------------------------------------------------------------------------------------------ 608 SUBROUTINE parseKeys(key, val) 609 CHARACTER(LEN=*), INTENT(INOUT) :: key 610 CHARACTER(LEN=*), INTENT(OUT) :: val 611 !------------------------------------------------------------------------------------------------------------------------------ 612 INTEGER :: ix 613 ix = INDEX(key, '='); IF(ix == 0) RETURN !--- First "=" index in "key" 614 val = ADJUSTL(key(ix+1:LEN_TRIM(key))) 615 key = ADJUSTL(key(1:ix-1)) 616 END SUBROUTINE parseKeys 659 END DO 660 keys(ik) = r(ib:nr) !--- Get the last key 661 END SUBROUTINE parseK 662 663 !------------------------------------------------------------------------------------------------------------------------------ 664 SUBROUTINE parseV(vals) 665 !--- Parse the <key>=<val> pairs in "keys(:)" into "keys" and "vals" 666 IMPLICIT NONE 667 CHARACTER(LEN=maxlen), ALLOCATABLE, INTENT(OUT) :: vals(:) 668 !------------------------------------------------------------------------------------------------------------------------------ 669 CHARACTER(LEN=maxlen) :: key 670 INTEGER :: ik, ix 671 ALLOCATE(vals(nk)) 672 DO ik = 1, nk; key = keys(ik) 673 vals(ik) = '' 674 ix = INDEX(key, '='); IF(ix == 0) CYCLE !--- First "=" index in "key" 675 vals(ik) = ADJUSTL(key(ix+1:LEN_TRIM(key))) 676 keys(ik) = ADJUSTL(key(1:ix-1)) 677 END DO 678 END SUBROUTINE parseV 617 679 618 680 END FUNCTION strParse 619 681 !============================================================================================================================== 620 682 LOGICAL FUNCTION strParse_m(rawList, delimiter, keys, n, vals, lSc, id) RESULT(lerr) 683 IMPLICIT NONE 621 684 CHARACTER(LEN=*), INTENT(IN) :: rawList, delimiter(:) 622 685 CHARACTER(LEN=maxlen), ALLOCATABLE, INTENT(OUT) :: keys(:) !--- Parsed keys vector … … 630 693 LOGICAL :: ll 631 694 ll = .FALSE.; IF(PRESENT(lSc)) ll = lSc 632 IF(test(fmsg("Couldn't parse list: non-numerical strings were found", ll=strCount_1m(rawList, delimiter, nk, ll)),lerr)) RETURN 695 lerr = strCount_1m(rawList, delimiter, nk, ll) 696 CALL msg("Couldn't parse list: non-numerical strings were found", ll=lerr); IF(lerr) RETURN 633 697 634 698 !--- FEW ALLOCATIONS … … 643 707 ib = 1 644 708 DO ik = 1, nk-1 645 IF(test(fmsg('Non-numeric values found', ll=strIdx_prv(r, delimiter, ib, ie, jd, ll)),lerr)) RETURN 709 lerr = strIdx_prv(r, delimiter, ib, ie, jd, ll) 710 CALL msg('Non-numeric values found', ll=lerr); IF(lerr) RETURN 646 711 keys(ik) = r(ib:ie-1) 647 712 IF(PRESENT(vals)) CALL parseKeys(keys(ik), vals(ik)) !--- Parse a <key>=<val> pair … … 657 722 !------------------------------------------------------------------------------------------------------------------------------ 658 723 SUBROUTINE parseKeys(key, val) 724 IMPLICIT NONE 659 725 CHARACTER(LEN=*), INTENT(INOUT) :: key 660 726 CHARACTER(LEN=*), INTENT(OUT) :: val … … 674 740 !============================================================================================================================== 675 741 SUBROUTINE strReplace_1(str, key, val, lsurr) 742 IMPLICIT NONE 676 743 CHARACTER(LEN=*), INTENT(INOUT) :: str !--- Main string 677 744 CHARACTER(LEN=*), INTENT(IN) :: key, val !--- "key" will be replaced by "val" … … 700 767 !============================================================================================================================== 701 768 SUBROUTINE strReplace_m(str, key, val, lsurr) 769 IMPLICIT NONE 702 770 CHARACTER(LEN=*), INTENT(INOUT) :: str(:) !--- Main strings vector 703 771 CHARACTER(LEN=*), INTENT(IN) :: key, val !--- "key" will be replaced by "val" … … 714 782 !=== Contatenate horizontally scalars/vectors of strings/integers/reals into a vector/array =================================== 715 783 !============================================================================================================================== 716 FUNCTION horzcat_s1(s0, s1, s2, s3, s4, s5, s6, s7, s8, s9) RESULT(out) 717 CHARACTER(LEN=*), TARGET, INTENT(IN) :: s0 784 FUNCTION horzcat_s00(s0, s1, s2, s3, s4, s5, s6, s7, s8, s9) RESULT(out) 785 IMPLICIT NONE 786 CHARACTER(LEN=*), INTENT(IN) :: s0 718 787 CHARACTER(LEN=*), OPTIONAL, TARGET, INTENT(IN) :: s1, s2, s3, s4, s5, s6, s7, s8, s9 719 788 CHARACTER(LEN=maxlen), ALLOCATABLE :: out(:) 720 !------------------------------------------------------------------------------------------------------------------------------721 789 CHARACTER(LEN=maxlen), POINTER :: s 722 LOGICAL :: lv(10) 723 INTEGER :: iv 724 lv = [ .TRUE. , PRESENT(s1), PRESENT(s2), PRESENT(s3), PRESENT(s4) , & 725 PRESENT(s5), PRESENT(s6), PRESENT(s7), PRESENT(s8), PRESENT(s9) ] 726 ALLOCATE(out(COUNT(lv))) 727 DO iv=1, COUNT(lv) 728 SELECT CASE(iv) 729 CASE(1); s=> s0; CASE(2); s=> s1; CASE(3); s=> s2; CASE(4); s=> s3; CASE(5); s=> s4 730 CASE(6); s=> s5; CASE(7); s=> s6; CASE(8); s=> s7; CASE(9); s=> s8; CASE(10);s=> s9 790 INTEGER :: nrow, iv 791 LOGICAL :: pre(9) 792 !------------------------------------------------------------------------------------------------------------------------------ 793 pre(:) = [PRESENT(s1),PRESENT(s2),PRESENT(s3),PRESENT(s4),PRESENT(s5),PRESENT(s6),PRESENT(s7),PRESENT(s8),PRESENT(s9)] 794 nrow = 1+COUNT(pre) 795 ALLOCATE(out(nrow)) 796 out(1) = s0 797 DO iv = 2, nrow; IF(.NOT.pre(iv-1)) CYCLE 798 SELECT CASE(iv-1) 799 CASE(1); s=> s1; CASE(2); s=> s2; CASE(3); s=> s3; CASE(4); s=> s4; CASE(5); s=> s5 800 CASE(6); s=> s6; CASE(7); s=> s7; CASE(8); s=> s8; CASE(9); s=> s9 731 801 END SELECT 732 802 out(iv) = s 733 803 END DO 734 END FUNCTION horzcat_s1 735 !============================================================================================================================== 736 FUNCTION horzcat_sm(s0, s1, s2, s3, s4, s5, s6, s7, s8, s9) RESULT(out) 737 CHARACTER(LEN=*), TARGET, DIMENSION(:), INTENT(IN) :: s0 738 CHARACTER(LEN=*), OPTIONAL, TARGET, DIMENSION(:), INTENT(IN) :: s1, s2, s3, s4, s5, s6, s7, s8, s9 804 END FUNCTION horzcat_s00 805 !============================================================================================================================== 806 FUNCTION horzcat_s10(s0, s1, s2, s3, s4, s5, s6, s7, s8, s9) RESULT(out) 807 IMPLICIT NONE 808 CHARACTER(LEN=*), INTENT(IN) :: s0(:), s1 809 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: s2, s3, s4, s5, s6, s7, s8, s9 810 CHARACTER(LEN=maxlen), ALLOCATABLE :: out(:), tmp(:) 811 INTEGER :: nc 812 nc = SIZE(s0) 813 tmp = horzcat_s00(s0(nc), s1, s2, s3, s4, s5, s6, s7, s8, s9) 814 IF(nc == 1) out = tmp 815 IF(nc /= 1) out = [s0(1:nc-1), tmp] 816 END FUNCTION horzcat_s10 817 !============================================================================================================================== 818 FUNCTION horzcat_s11(s0, s1, s2, s3, s4, s5, s6, s7, s8, s9) RESULT(out) 819 IMPLICIT NONE 820 CHARACTER(LEN=*), INTENT(IN) :: s0(:) 821 CHARACTER(LEN=*), OPTIONAL, TARGET, INTENT(IN) :: s1(:), s2(:), s3(:), s4(:), s5(:), s6(:), s7(:), s8(:), s9(:) 739 822 CHARACTER(LEN=maxlen), ALLOCATABLE :: out(:,:) 740 !------------------------------------------------------------------------------------------------------------------------------741 823 CHARACTER(LEN=maxlen), POINTER :: s(:) 742 LOGICAL :: lv(10) 743 INTEGER :: nrow, ncol, iv, n 744 lv = [ .TRUE. , PRESENT(s1), PRESENT(s2), PRESENT(s3), PRESENT(s4) , & 745 PRESENT(s5), PRESENT(s6), PRESENT(s7), PRESENT(s8), PRESENT(s9) ] 746 nrow = SIZE(s0); ncol=COUNT(lv) 824 INTEGER :: nrow, ncol, iv, n 825 LOGICAL :: pre(9) 826 !------------------------------------------------------------------------------------------------------------------------------ 827 pre(:) = [PRESENT(s1),PRESENT(s2),PRESENT(s3),PRESENT(s4),PRESENT(s5),PRESENT(s6),PRESENT(s7),PRESENT(s8),PRESENT(s9)] 828 nrow = SIZE(s0) 829 ncol = 1+COUNT(pre) 747 830 ALLOCATE(out(nrow, ncol)) 748 DO iv=1, ncol 749 SELECT CASE(iv) 750 CASE(1); s=> s0; CASE(2); s=> s1; CASE(3); s=> s2; CASE(4); s=> s3; CASE(5); s=> s4 751 CASE(6); s=> s5; CASE(7); s=> s6; CASE(8); s=> s7; CASE(9); s=> s8; CASE(10);s=> s9 831 out(:,1) = s0 832 DO iv = 2, ncol; IF(.NOT.pre(iv-1)) CYCLE 833 SELECT CASE(iv-1) 834 CASE(1); s=> s1; CASE(2); s=> s2; CASE(3); s=> s3; CASE(4); s=> s4; CASE(5); s=> s5 835 CASE(6); s=> s6; CASE(7); s=> s7; CASE(8); s=> s8; CASE(9); s=> s9 752 836 END SELECT 753 837 n = SIZE(s, DIM=1) 754 IF(n /=nrow) THEN; CALL msg("Can't concatenate vectors of differing lengths"); STOP; END IF838 IF(n /= nrow) THEN; CALL msg("Can't concatenate vectors of differing lengths"); STOP; END IF 755 839 out(:,iv) = s(:) 756 840 END DO 757 END FUNCTION horzcat_sm 758 !============================================================================================================================== 759 FUNCTION horzcat_i1(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9) RESULT(out) 760 INTEGER, TARGET, INTENT(IN) :: i0 841 END FUNCTION horzcat_s11 842 !============================================================================================================================== 843 FUNCTION horzcat_s21(s0, s1, s2, s3, s4, s5, s6, s7, s8, s9) RESULT(out) 844 IMPLICIT NONE 845 CHARACTER(LEN=*), INTENT(IN) :: s0(:,:), s1(:) 846 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: s2(:), s3(:), s4(:), s5(:), s6(:), s7(:), s8(:), s9(:) 847 CHARACTER(LEN=maxlen), ALLOCATABLE :: out(:,:), tmp(:,:) 848 INTEGER :: nc 849 nc = SIZE(s0, 2) 850 tmp = horzcat_s11(s0(:,nc), s1, s2, s3, s4, s5, s6, s7, s8, s9) 851 IF(nc == 1) out = tmp 852 IF(nc /= 1) out = RESHAPE([PACK(s0(:,1:nc-1), .TRUE.), PACK(tmp, .TRUE.)], SHAPE=[SIZE(s0, 1), nc + SIZE(tmp, 2)-1]) 853 END FUNCTION horzcat_s21 854 !============================================================================================================================== 855 FUNCTION horzcat_i00(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9) RESULT(out) 856 IMPLICIT NONE 857 INTEGER, INTENT(IN) :: i0 761 858 INTEGER, OPTIONAL, TARGET, INTENT(IN) :: i1, i2, i3, i4, i5, i6, i7, i8, i9 762 859 INTEGER, ALLOCATABLE :: out(:) 763 !------------------------------------------------------------------------------------------------------------------------------764 860 INTEGER, POINTER :: i 765 LOGICAL :: lv(10) 766 INTEGER :: iv 767 lv = [ .TRUE. , PRESENT(i1), PRESENT(i2), PRESENT(i3), PRESENT(i4) , & 768 PRESENT(i5), PRESENT(i6), PRESENT(i7), PRESENT(i8), PRESENT(i9) ] 769 ALLOCATE(out(COUNT(lv))) 770 DO iv=1, COUNT(lv) 771 SELECT CASE(iv) 772 CASE(1); i=> i0; CASE(2); i=> i1; CASE(3); i=> i2; CASE(4); i=> i3; CASE(5); i=> i4 773 CASE(6); i=> i5; CASE(7); i=> i6; CASE(8); i=> i7; CASE(9); i=> i8; CASE(10);i=> i9 861 INTEGER :: ncol, iv 862 LOGICAL :: pre(9) 863 !------------------------------------------------------------------------------------------------------------------------------ 864 pre(:) = [PRESENT(i1),PRESENT(i2),PRESENT(i3),PRESENT(i4),PRESENT(i5),PRESENT(i6),PRESENT(i7),PRESENT(i8),PRESENT(i9)] 865 ncol = SIZE(pre) 866 ALLOCATE(out(ncol)) 867 out(1) = i0 868 DO iv = 2, ncol; IF(.NOT.pre(iv-1)) CYCLE 869 SELECT CASE(iv-1) 870 CASE(1); i=> i1; CASE(2); i=> i2; CASE(3); i=> i3; CASE(4); i=> i4; CASE(5); i=> i5 871 CASE(6); i=> i6; CASE(7); i=> i7; CASE(8); i=> i8; CASE(9); i=> i9 774 872 END SELECT 775 873 out(iv) = i 776 874 END DO 777 END FUNCTION horzcat_i1 778 !============================================================================================================================== 779 FUNCTION horzcat_im(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9) RESULT(out) 780 INTEGER, TARGET, DIMENSION(:), INTENT(IN) :: i0 781 INTEGER, OPTIONAL, TARGET, DIMENSION(:), INTENT(IN) :: i1, i2, i3, i4, i5, i6, i7, i8, i9 875 END FUNCTION horzcat_i00 876 !============================================================================================================================== 877 FUNCTION horzcat_i10(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9) RESULT(out) 878 IMPLICIT NONE 879 INTEGER, INTENT(IN) :: i0(:), i1 880 INTEGER, OPTIONAL, INTENT(IN) :: i2, i3, i4, i5, i6, i7, i8, i9 881 INTEGER, ALLOCATABLE :: out(:), tmp(:) 882 INTEGER :: nc 883 nc = SIZE(i0) 884 tmp = horzcat_i00(i0(nc), i1, i2, i3, i4, i5, i6, i7, i8, i9) 885 IF(nc == 1) out = tmp 886 IF(nc /= 1) out = [i0(1:nc-1), tmp] 887 END FUNCTION horzcat_i10 888 !============================================================================================================================== 889 FUNCTION horzcat_i11(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9) RESULT(out) 890 IMPLICIT NONE 891 INTEGER, INTENT(IN) :: i0(:) 892 INTEGER, OPTIONAL, TARGET, INTENT(IN) :: i1(:), i2(:), i3(:), i4(:), i5(:), i6(:), i7(:), i8(:), i9(:) 782 893 INTEGER, ALLOCATABLE :: out(:,:) 783 !------------------------------------------------------------------------------------------------------------------------------784 894 INTEGER, POINTER :: i(:) 785 LOGICAL :: lv(10) 786 INTEGER :: nrow, ncol, iv, n 787 lv = [ .TRUE. , PRESENT(i1), PRESENT(i2), PRESENT(i3), PRESENT(i4) , & 788 PRESENT(i5), PRESENT(i6), PRESENT(i7), PRESENT(i8), PRESENT(i9) ] 789 nrow = SIZE(i0); ncol=COUNT(lv) 895 INTEGER :: nrow, ncol, iv, n 896 LOGICAL :: pre(9) 897 !------------------------------------------------------------------------------------------------------------------------------ 898 pre(:) = [PRESENT(i1),PRESENT(i2),PRESENT(i3),PRESENT(i4),PRESENT(i5),PRESENT(i6),PRESENT(i7),PRESENT(i8),PRESENT(i9)] 899 nrow = SIZE(i0) 900 ncol = 1+COUNT(pre) 790 901 ALLOCATE(out(nrow, ncol)) 791 DO iv=1, ncol 792 SELECT CASE(iv) 793 CASE(1); i=> i0; CASE(2); i=> i1; CASE(3); i=> i2; CASE(4); i=> i3; CASE(5); i=> i4 794 CASE(6); i=> i5; CASE(7); i=> i6; CASE(8); i=> i7; CASE(9); i=> i8; CASE(10);i=> i9 902 out(:,1) = i0 903 DO iv = 2, ncol; IF(.NOT.pre(iv-1)) CYCLE 904 SELECT CASE(iv-1) 905 CASE(1); i=> i1; CASE(2); i=> i2; CASE(3); i=> i3; CASE(4); i=> i4; CASE(5); i=> i5 906 CASE(6); i=> i6; CASE(7); i=> i7; CASE(8); i=> i8; CASE(9); i=> i9 795 907 END SELECT 796 908 n = SIZE(i, DIM=1) 797 IF(n /=nrow) THEN; CALL msg("Can't concatenate vectors of differing lengths"); STOP; END IF909 IF(n /= nrow) THEN; CALL msg("Can't concatenate vectors of differing lengths"); STOP; END IF 798 910 out(:,iv) = i(:) 799 911 END DO 800 END FUNCTION horzcat_im 801 !============================================================================================================================== 802 FUNCTION horzcat_r1(r0, r1, r2, r3, r4, r5, r6, r7, r8, r9) RESULT(out) 803 REAL, TARGET, INTENT(IN) :: r0 912 END FUNCTION horzcat_i11 913 !============================================================================================================================== 914 FUNCTION horzcat_i21(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9) RESULT(out) 915 IMPLICIT NONE 916 INTEGER, INTENT(IN) :: i0(:,:), i1(:) 917 INTEGER, OPTIONAL, INTENT(IN) :: i2(:), i3(:), i4(:), i5(:), i6(:), i7(:), i8(:), i9(:) 918 INTEGER, ALLOCATABLE :: out(:,:), tmp(:,:) 919 INTEGER :: nc 920 nc = SIZE(i0, 2) 921 tmp = horzcat_i11(i0(:,nc), i1, i2, i3, i4, i5, i6, i7, i8, i9) 922 IF(nc == 1) out = tmp 923 IF(nc /= 1) out = RESHAPE([PACK(i0(:,1:nc-1), .TRUE.), PACK(tmp, .TRUE.)], SHAPE=[SIZE(i0, 1), nc + SIZE(tmp, 2)-1]) 924 END FUNCTION horzcat_i21 925 !============================================================================================================================== 926 FUNCTION horzcat_r00(r0, r1, r2, r3, r4, r5, r6, r7, r8, r9) RESULT(out) 927 IMPLICIT NONE 928 REAL, INTENT(IN) :: r0 804 929 REAL, OPTIONAL, TARGET, INTENT(IN) :: r1, r2, r3, r4, r5, r6, r7, r8, r9 805 930 REAL, ALLOCATABLE :: out(:) 806 !------------------------------------------------------------------------------------------------------------------------------807 931 REAL, POINTER :: r 808 LOGICAL :: lv(10) 809 INTEGER :: iv 810 lv = [ .TRUE. , PRESENT(r1), PRESENT(r2), PRESENT(r3), PRESENT(r4) , & 811 PRESENT(r5), PRESENT(r6), PRESENT(r7), PRESENT(r8), PRESENT(r9) ] 812 ALLOCATE(out(COUNT(lv))) 813 DO iv=1, COUNT(lv) 814 SELECT CASE(iv) 815 CASE(1); r=> r0; CASE(2); r=> r1; CASE(3); r=> r2; CASE(4); r=> r3; CASE(5); r=> r4 816 CASE(6); r=> r5; CASE(7); r=> r6; CASE(8); r=> r7; CASE(9); r=> r8; CASE(10);r=> r9 932 INTEGER :: ncol, iv 933 LOGICAL :: pre(9) 934 !------------------------------------------------------------------------------------------------------------------------------ 935 pre(:) = [PRESENT(r1),PRESENT(r2),PRESENT(r3),PRESENT(r4),PRESENT(r5),PRESENT(r6),PRESENT(r7),PRESENT(r8),PRESENT(r9)] 936 ncol = 1+COUNT(pre) 937 ALLOCATE(out(ncol)) 938 out(1) = r0 939 DO iv = 2, ncol; IF(.NOT.pre(iv-1)) CYCLE 940 SELECT CASE(iv-1) 941 CASE(1); r=> r1; CASE(2); r=> r2; CASE(3); r=> r3; CASE(4); r=> r4; CASE(5); r=> r5 942 CASE(6); r=> r6; CASE(7); r=> r7; CASE(8); r=> r8; CASE(9); r=> r9 817 943 END SELECT 818 944 out(iv) = r 819 945 END DO 820 END FUNCTION horzcat_r1 821 !============================================================================================================================== 822 FUNCTION horzcat_rm(r0, r1, r2, r3, r4, r5, r6, r7, r8, r9) RESULT(out) 823 REAL, TARGET, DIMENSION(:), INTENT(IN) :: r0 824 REAL, OPTIONAL, TARGET, DIMENSION(:), INTENT(IN) :: r1, r2, r3, r4, r5, r6, r7, r8, r9 946 END FUNCTION horzcat_r00 947 !============================================================================================================================== 948 FUNCTION horzcat_r10(r0, r1, r2, r3, r4, r5, r6, r7, r8, r9) RESULT(out) 949 IMPLICIT NONE 950 REAL, INTENT(IN) :: r0(:), r1 951 REAL, OPTIONAL, INTENT(IN) :: r2, r3, r4, r5, r6, r7, r8, r9 952 REAL, ALLOCATABLE :: out(:), tmp(:) 953 INTEGER :: nc 954 nc = SIZE(r0) 955 tmp = horzcat_r00(r0(nc), r1, r2, r3, r4, r5, r6, r7, r8, r9) 956 IF(nc == 1) out = tmp 957 IF(nc /= 1) out = [r0(1:nc-1), tmp] 958 END FUNCTION horzcat_r10 959 !============================================================================================================================== 960 FUNCTION horzcat_r11(r0, r1, r2, r3, r4, r5, r6, r7, r8, r9) RESULT(out) 961 IMPLICIT NONE 962 REAL, INTENT(IN) :: r0(:) 963 REAL, OPTIONAL, TARGET, INTENT(IN) :: r1(:), r2(:), r3(:), r4(:), r5(:), r6(:), r7(:), r8(:), r9(:) 825 964 REAL, ALLOCATABLE :: out(:,:) 826 !------------------------------------------------------------------------------------------------------------------------------827 965 REAL, POINTER :: r(:) 828 LOGICAL :: lv(10) 829 INTEGER :: nrow, ncol, iv, n 830 lv = [ .TRUE. , PRESENT(r1), PRESENT(r2), PRESENT(r3), PRESENT(r4) , & 831 PRESENT(r5), PRESENT(r6), PRESENT(r7), PRESENT(r8), PRESENT(r9) ] 832 nrow = SIZE(r0); ncol=COUNT(lv) 966 INTEGER :: nrow, ncol, iv, n 967 LOGICAL :: pre(9) 968 !------------------------------------------------------------------------------------------------------------------------------ 969 pre(:) = [PRESENT(r1),PRESENT(r2),PRESENT(r3),PRESENT(r4),PRESENT(r5),PRESENT(r6),PRESENT(r7),PRESENT(r8),PRESENT(r9)] 970 nrow = SIZE(r0) 971 ncol = 1+COUNT(pre) 833 972 ALLOCATE(out(nrow, ncol)) 834 DO iv=1, ncol 835 SELECT CASE(iv) 836 CASE(1); r=> r0; CASE(2); r=> r1; CASE(3); r=> r2; CASE(4); r=> r3; CASE(5); r=> r4 837 CASE(6); r=> r5; CASE(7); r=> r6; CASE(8); r=> r7; CASE(9); r=> r8; CASE(10);r=> r9 973 out(:,1) = r0 974 DO iv = 2, ncol; IF(.NOT.pre(iv-1)) CYCLE 975 SELECT CASE(iv-1) 976 CASE(1); r=> r1; CASE(2); r=> r2; CASE(3); r=> r3; CASE(4); r=> r4; CASE(5); r=> r5 977 CASE(6); r=> r5; CASE(7); r=> r7; CASE(8); r=> r8; CASE(9); r=> r9 838 978 END SELECT 839 979 n = SIZE(r, DIM=1) 840 IF(n /=nrow) THEN; CALL msg("Can't concatenate vectors of differing lengths"); STOP; END IF980 IF(n /= nrow) THEN; CALL msg("Can't concatenate vectors of differing lengths"); STOP; END IF 841 981 out(:,iv) = r(:) 842 982 END DO 843 END FUNCTION horzcat_rm 844 !============================================================================================================================== 845 FUNCTION horzcat_d1(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9) RESULT(out) 846 DOUBLE PRECISION, TARGET, INTENT(IN) :: d0 983 END FUNCTION horzcat_r11 984 !============================================================================================================================== 985 FUNCTION horzcat_r21(r0, r1, r2, r3, r4, r5, r6, r7, r8, r9) RESULT(out) 986 IMPLICIT NONE 987 REAL, INTENT(IN) :: r0(:,:), r1(:) 988 REAL, OPTIONAL, INTENT(IN) :: r2(:), r3(:), r4(:), r5(:), r6(:), r7(:), r8(:), r9(:) 989 REAL, ALLOCATABLE :: out(:,:), tmp(:,:) 990 INTEGER :: nc 991 nc = SIZE(r0, 2) 992 tmp = horzcat_r11(r0(:,nc), r1, r2, r3, r4, r5, r6, r7, r8, r9) 993 IF(nc == 1) out = tmp 994 IF(nc /= 1) out = RESHAPE([PACK(r0(:,1:nc-1), .TRUE.), PACK(tmp, .TRUE.)], SHAPE=[SIZE(r0, 1), nc + SIZE(tmp, 2)-1]) 995 END FUNCTION horzcat_r21 996 !============================================================================================================================== 997 FUNCTION horzcat_d00(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9) RESULT(out) 998 IMPLICIT NONE 999 DOUBLE PRECISION, INTENT(IN) :: d0 847 1000 DOUBLE PRECISION, OPTIONAL, TARGET, INTENT(IN) :: d1, d2, d3, d4, d5, d6, d7, d8, d9 848 1001 DOUBLE PRECISION, ALLOCATABLE :: out(:) 849 !------------------------------------------------------------------------------------------------------------------------------850 1002 DOUBLE PRECISION, POINTER :: d 851 LOGICAL :: lv(10) 852 INTEGER :: iv 853 lv = [ .TRUE. , PRESENT(d1), PRESENT(d2), PRESENT(d3), PRESENT(d4) , & 854 PRESENT(d5), PRESENT(d6), PRESENT(d7), PRESENT(d8), PRESENT(d9) ] 855 ALLOCATE(out(COUNT(lv))) 856 DO iv=1, COUNT(lv) 857 SELECT CASE(iv) 858 CASE(1); d=> d0; CASE(2); d=> d1; CASE(3); d=> d2; CASE(4); d=> d3; CASE(5); d=> d4 859 CASE(6); d=> d5; CASE(7); d=> d6; CASE(8); d=> d7; CASE(9); d=> d8; CASE(10);d=> d9 1003 INTEGER :: ncol, iv 1004 LOGICAL :: pre(9) 1005 !------------------------------------------------------------------------------------------------------------------------------ 1006 pre(:) = [PRESENT(d1),PRESENT(d2),PRESENT(d3),PRESENT(d4),PRESENT(d5),PRESENT(d6),PRESENT(d7),PRESENT(d8),PRESENT(d9)] 1007 ncol = 1+COUNT(pre) 1008 ALLOCATE(out(ncol)) 1009 out(1) = d0 1010 DO iv = 2, ncol; IF(.NOT.pre(iv-1)) CYCLE 1011 SELECT CASE(iv-1) 1012 CASE(1); d=> d1; CASE(2); d=> d2; CASE(3); d=> d3; CASE(4); d=> d4; CASE(5); d=> d5 1013 CASE(6); d=> d6; CASE(7); d=> d7; CASE(8); d=> d8; CASE(9); d=> d9 860 1014 END SELECT 861 1015 out(iv) = d 862 1016 END DO 863 END FUNCTION horzcat_d1 864 !============================================================================================================================== 865 FUNCTION horzcat_dm(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9) RESULT(out) 866 DOUBLE PRECISION, TARGET, DIMENSION(:), INTENT(IN) :: d0 867 DOUBLE PRECISION, OPTIONAL, TARGET, DIMENSION(:), INTENT(IN) :: d1, d2, d3, d4, d5, d6, d7, d8, d9 1017 END FUNCTION horzcat_d00 1018 !============================================================================================================================== 1019 FUNCTION horzcat_d10(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9) RESULT(out) 1020 IMPLICIT NONE 1021 DOUBLE PRECISION, INTENT(IN) :: d0(:), d1 1022 DOUBLE PRECISION, OPTIONAL, INTENT(IN) :: d2, d3, d4, d5, d6, d7, d8, d9 1023 DOUBLE PRECISION, ALLOCATABLE :: out(:), tmp(:) 1024 INTEGER :: nc 1025 nc = SIZE(d0) 1026 tmp = horzcat_d00(d0(nc), d1, d2, d3, d4, d5, d6, d7, d8, d9) 1027 IF(nc == 1) out = tmp 1028 IF(nc /= 1) out = [d0(1:nc-1), tmp] 1029 END FUNCTION horzcat_d10 1030 !============================================================================================================================== 1031 FUNCTION horzcat_d11(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9) RESULT(out) 1032 IMPLICIT NONE 1033 DOUBLE PRECISION, INTENT(IN) :: d0(:) 1034 DOUBLE PRECISION, OPTIONAL, TARGET, INTENT(IN) :: d1(:), d2(:), d3(:), d4(:), d5(:), d6(:), d7(:), d8(:), d9(:) 868 1035 DOUBLE PRECISION, ALLOCATABLE :: out(:,:) 869 !------------------------------------------------------------------------------------------------------------------------------870 1036 DOUBLE PRECISION, POINTER :: d(:) 871 LOGICAL :: lv(10) 872 INTEGER :: nrow, ncol, iv, n 873 lv = [ .TRUE. , PRESENT(d1), PRESENT(d2), PRESENT(d3), PRESENT(d4) , & 874 PRESENT(d5), PRESENT(d6), PRESENT(d7), PRESENT(d8), PRESENT(d9) ] 875 nrow = SIZE(d0); ncol=COUNT(lv) 1037 INTEGER :: nrow, ncol, iv, n 1038 LOGICAL :: pre(9) 1039 !------------------------------------------------------------------------------------------------------------------------------ 1040 nrow = SIZE(d0) 1041 pre(:) = [PRESENT(d1),PRESENT(d2),PRESENT(d3),PRESENT(d4),PRESENT(d5),PRESENT(d6),PRESENT(d7),PRESENT(d8),PRESENT(d9)] 1042 ncol = 1+COUNT(pre) 876 1043 ALLOCATE(out(nrow, ncol)) 877 DO iv =1, ncol878 SELECT CASE(iv )879 CASE(1); d=> d 0; CASE(2); d=> d1; CASE(3); d=> d2; CASE(4); d=> d3; CASE(5); d=> d4880 CASE(6); d=> d 5; CASE(7); d=> d6; CASE(8); d=> d7; CASE(9); d=> d8; CASE(10);d=> d91044 DO iv = 2, ncol; IF(.NOT.pre(iv-1)) CYCLE 1045 SELECT CASE(iv-1) 1046 CASE(1); d=> d1; CASE(2); d=> d2; CASE(3); d=> d3; CASE(4); d=> d4; CASE(5); d=> d5 1047 CASE(6); d=> d6; CASE(7); d=> d7; CASE(8); d=> d8; CASE(9); d=> d9 881 1048 END SELECT 882 1049 n = SIZE(d, DIM=1) 883 IF(n /=nrow) THEN; CALL msg("Can't concatenate vectors of differing lengths"); STOP; END IF1050 IF(n /= nrow) THEN; CALL msg("Can't concatenate vectors of differing lengths"); STOP; END IF 884 1051 out(:,iv) = d(:) 885 1052 END DO 886 END FUNCTION horzcat_dm 1053 END FUNCTION horzcat_d11 1054 !============================================================================================================================== 1055 FUNCTION horzcat_d21(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9) RESULT(out) 1056 IMPLICIT NONE 1057 DOUBLE PRECISION, INTENT(IN) :: d0(:,:), d1(:) 1058 DOUBLE PRECISION, OPTIONAL, INTENT(IN) :: d2(:), d3(:), d4(:), d5(:), d6(:), d7(:), d8(:), d9(:) 1059 DOUBLE PRECISION, ALLOCATABLE :: out(:,:), tmp(:,:) 1060 INTEGER :: nc 1061 nc = SIZE(d0, 2) 1062 tmp = horzcat_d11(d0(:,nc), d1, d2, d3, d4, d5, d6, d7, d8, d9) 1063 IF(nc == 1) out = tmp 1064 IF(nc /= 1) out = RESHAPE([PACK(d0(:,1:nc-1), .TRUE.), PACK(tmp, .TRUE.)], SHAPE=[SIZE(d0, 1), nc + SIZE(tmp, 2)-1]) 1065 END FUNCTION horzcat_d21 887 1066 !============================================================================================================================== 888 1067 … … 896 1075 !============================================================================================================================== 897 1076 LOGICAL FUNCTION dispTable(p, titles, s, i, r, rFmt, nRowMax, nColMax, nHead, unit, sub) RESULT(lerr) 1077 IMPLICIT NONE 898 1078 CHARACTER(LEN=*), INTENT(IN) :: p !--- DISPLAY MAP: s/i/r 899 1079 CHARACTER(LEN=*), INTENT(IN) :: titles(:) !--- TITLES (ONE EACH COLUMN) … … 1004 1184 !============================================================================================================================== 1005 1185 LOGICAL FUNCTION dispNamelist(unt, p, titles, s, i, r, rFmt, llast) RESULT(lerr) 1186 IMPLICIT NONE 1006 1187 INTEGER, INTENT(IN) :: unt !--- Output unit 1007 1188 CHARACTER(LEN=*), INTENT(IN) :: p !--- DISPLAY MAP: s/i/r … … 1086 1267 !============================================================================================================================== 1087 1268 LOGICAL FUNCTION dispOutliers_1(ll, a, n, err_msg, nam, subn, nRowmax, nColMax, nHead, unit) RESULT(lerr) 1269 IMPLICIT NONE 1088 1270 ! Display outliers list in tables 1089 1271 ! If "nam" is supplied, it means the last index is for tracers => one table each tracer for rank > 2. … … 1115 1297 1116 1298 rk = SIZE(n); nv = SIZE(vnm) 1117 IF(test(fmsg('SIZE(nam) /= 1 and /= last "n" element', sub, nv /= 1 .AND. nv /= n(rk), unt),lerr)) RETURN1118 IF(test(fmsg('ll" and "a" sizes mismatch', sub, SIZE(a) /= SIZE(ll), unt),lerr)) RETURN1119 IF(test(fmsg('profile "n" does not match "a" and "ll', sub, SIZE(a) /= PRODUCT(n), unt),lerr)) RETURN1299 lerr = nv/=1 .AND. nv/=n(rk); CALL msg('SIZE(nam) /= 1 and /= last "n" element', sub, lerr); IF(lerr) RETURN 1300 lerr = SIZE(a) /= SIZE(ll); CALL msg('ll" and "a" sizes mismatch', sub, lerr); IF(lerr) RETURN 1301 lerr = SIZE(a) /= PRODUCT(n); CALL msg('profile "n" does not match "a" and "ll', sub, lerr); IF(lerr) RETURN 1120 1302 CALL msg(mes, sub, unit=unt) 1121 1303 … … 1164 1346 !============================================================================================================================== 1165 1347 LOGICAL FUNCTION dispOutliers_2(ll, a, n, err_msg, nam, subn, nRowMax, nColMax, nHead, unit) RESULT(lerr) 1348 IMPLICIT NONE 1166 1349 ! Display outliers list in tables 1167 1350 ! If "nam" is supplied and, it means the last index is for tracers => one table each tracer for rank > 2. … … 1221 1404 !============================================================================================================================== 1222 1405 LOGICAL FUNCTION reduceExpr_1(str, val) RESULT(lerr) 1406 IMPLICIT NONE 1223 1407 CHARACTER(LEN=*), INTENT(IN) :: str 1224 1408 CHARACTER(LEN=maxlen), INTENT(OUT) :: val … … 1254 1438 DO WHILE(nl > 1) 1255 1439 i = 1; DO WHILE(ip(i) /= 1 .OR. ip(i+1) /= 2); i = i + 1; END DO !IF(i > SIZE(ip)+1) EXIT;END DO 1256 IF(test(reduceExpr_basic(vl(i+1), v), lerr)) RETURN1440 lerr = reduceExpr_basic(vl(i+1), v); IF(lerr) RETURN 1257 1441 v = TRIM(vl(i))//TRIM(v); IF(i+2<=nl) v=TRIM(v)//TRIM(vl(i+2)) 1258 1442 vv = v//REPEAT(' ',768) … … 1270 1454 !============================================================================================================================== 1271 1455 LOGICAL FUNCTION reduceExpr_basic(str, val) RESULT(lerr) 1456 IMPLICIT NONE 1272 1457 CHARACTER(LEN=*), INTENT(IN) :: str 1273 1458 CHARACTER(LEN=*), INTENT(OUT) :: val … … 1284 1469 op = ['^','/','*','+','-'] !--- List of recognized operations 1285 1470 s = str 1286 IF(test(strParse_m(s, op, ky, lSc=.TRUE., id = id), lerr)) RETURN !--- Parse the values 1471 lerr = strParse_m(s, op, ky, lSc=.TRUE., id = id) !--- Parse the values 1472 IF(lerr) RETURN !--- Problem with the parsing 1287 1473 vl = str2dble(ky) !--- Conversion to doubles 1288 1474 lerr = ANY(vl >= HUGE(1.d0)) 1289 IF(fmsg('Some values are non-numeric in: '//TRIM(s), ll=lerr)) RETURN !--- Non-numerical values found 1475 CALL msg('Some values are non-numeric in: '//TRIM(s), ll=lerr) 1476 IF(lerr) RETURN !--- Non-numerical values found 1290 1477 DO io = 1, SIZE(op) !--- Loop on known operators (order matters !) 1291 1478 DO i = SIZE(id), 1, -1 !--- Loop on found operators … … 1293 1480 IF(id(i) /= io) CYCLE !--- Current found operator is not op(io) 1294 1481 vm = vl(i); vp = vl(i+1) !--- Couple of values used for current operation 1295 SELECT CASE(op(io)) 1482 SELECT CASE(op(io)) !--- Perform operation on the two values 1296 1483 CASE('^'); v = vm**vp 1297 1484 CASE('/'); v = vm/vp … … 1311 1498 !============================================================================================================================== 1312 1499 FUNCTION reduceExpr_m(str, val) RESULT(lerr) 1500 IMPLICIT NONE 1313 1501 LOGICAL, ALLOCATABLE :: lerr(:) 1314 1502 CHARACTER(LEN=*), INTENT(IN) :: str(:) … … 1326 1514 !============================================================================================================================== 1327 1515 ELEMENTAL LOGICAL FUNCTION is_numeric(str) RESULT(out) 1516 IMPLICIT NONE 1328 1517 CHARACTER(LEN=*), INTENT(IN) :: str 1329 1518 REAL :: x … … 1341 1530 !=== Convert a string into a logical/integer integer or an integer/real into a string ========================================= 1342 1531 !============================================================================================================================== 1343 ELEMENTAL LOGICAL FUNCTION str2bool(str) RESULT(out) 1532 ELEMENTAL INTEGER FUNCTION str2bool(str) RESULT(out) !--- Result: 0/1 for .FALSE./.TRUE., -1 if not a valid boolean 1533 IMPLICIT NONE 1344 1534 CHARACTER(LEN=*), INTENT(IN) :: str 1345 1535 INTEGER :: ierr 1346 READ(str,*,IOSTAT=ierr) out 1347 IF(ierr==0) RETURN 1348 out = ANY(['t ','true ','.true.','y ','yes ']==strLower(str)) 1536 LOGICAL :: lout 1537 READ(str,*,IOSTAT=ierr) lout 1538 out = -HUGE(1) 1539 IF(ierr /= 0) THEN 1540 IF(ANY(['.false.', 'false ', 'no ', 'f ', 'n '] == strLower(str))) out = 0 1541 IF(ANY(['.true. ', 'true ', 'yes ', 't ', 'y '] == strLower(str))) out = 1 1542 ELSE 1543 out = 0; IF(lout) out = 1 1544 END IF 1349 1545 END FUNCTION str2bool 1350 1546 !============================================================================================================================== 1351 1547 ELEMENTAL INTEGER FUNCTION str2int(str) RESULT(out) 1548 IMPLICIT NONE 1352 1549 CHARACTER(LEN=*), INTENT(IN) :: str 1353 1550 INTEGER :: ierr … … 1357 1554 !============================================================================================================================== 1358 1555 ELEMENTAL REAL FUNCTION str2real(str) RESULT(out) 1556 IMPLICIT NONE 1359 1557 CHARACTER(LEN=*), INTENT(IN) :: str 1360 1558 INTEGER :: ierr … … 1364 1562 !============================================================================================================================== 1365 1563 ELEMENTAL DOUBLE PRECISION FUNCTION str2dble(str) RESULT(out) 1564 IMPLICIT NONE 1366 1565 CHARACTER(LEN=*), INTENT(IN) :: str 1367 1566 INTEGER :: ierr … … 1371 1570 !============================================================================================================================== 1372 1571 ELEMENTAL CHARACTER(LEN=maxlen) FUNCTION bool2str(b) RESULT(out) 1572 IMPLICIT NONE 1373 1573 LOGICAL, INTENT(IN) :: b 1374 1574 WRITE(out,*)b … … 1377 1577 !============================================================================================================================== 1378 1578 ELEMENTAL CHARACTER(LEN=maxlen) FUNCTION int2str(i, nDigits) RESULT(out) 1579 IMPLICIT NONE 1379 1580 INTEGER, INTENT(IN) :: i 1380 1581 INTEGER, OPTIONAL, INTENT(IN) :: nDigits … … 1387 1588 !============================================================================================================================== 1388 1589 ELEMENTAL CHARACTER(LEN=maxlen) FUNCTION real2str(r,fmt) RESULT(out) 1590 IMPLICIT NONE 1389 1591 REAL, INTENT(IN) :: r 1390 1592 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: fmt … … 1396 1598 !============================================================================================================================== 1397 1599 ELEMENTAL CHARACTER(LEN=maxlen) FUNCTION dble2str(d,fmt) RESULT(out) 1600 IMPLICIT NONE 1398 1601 DOUBLE PRECISION, INTENT(IN) :: d 1399 1602 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: fmt … … 1405 1608 !============================================================================================================================== 1406 1609 ELEMENTAL SUBROUTINE cleanZeros(s) 1610 IMPLICIT NONE 1407 1611 CHARACTER(LEN=*), INTENT(INOUT) :: s 1408 1612 INTEGER :: ls, ix, i … … 1422 1626 !============================================================================================================================== 1423 1627 FUNCTION addQuotes_1(s) RESULT(out) 1628 IMPLICIT NONE 1424 1629 CHARACTER(LEN=*), INTENT(IN) :: s 1425 1630 CHARACTER(LEN=:), ALLOCATABLE :: out … … 1428 1633 !============================================================================================================================== 1429 1634 FUNCTION addQuotes_m(s) RESULT(out) 1635 IMPLICIT NONE 1430 1636 CHARACTER(LEN=*), INTENT(IN) :: s(:) 1431 1637 CHARACTER(LEN=:), ALLOCATABLE :: out(:) … … 1440 1646 !============================================================================================================================== 1441 1647 ELEMENTAL LOGICAL FUNCTION needQuotes(s) RESULT(out) 1648 IMPLICIT NONE 1442 1649 CHARACTER(LEN=*), INTENT(IN) :: s 1443 1650 CHARACTER(LEN=1) :: b, e … … 1454 1661 !============================================================================================================================== 1455 1662 LOGICAL FUNCTION checkList(str, lerr, message, items, reason, nmax) RESULT(out) 1663 IMPLICIT NONE 1456 1664 ! Purpose: Messages in case a list contains wrong elements (indicated by lerr boolean vector). 1457 1665 ! Note: Return value "out" is .TRUE. if there are errors (ie at least one element of "lerr" is TRUE). … … 1476 1684 !============================================================================================================================== 1477 1685 SUBROUTINE removeComment(str) 1686 IMPLICIT NONE 1478 1687 CHARACTER(LEN=*), INTENT(INOUT) :: str 1479 1688 INTEGER :: ix -
LMDZ6/branches/cirrus/libf/phylmd/Dust/phys_output_write_spl_mod.F90
r4619 r5202 325 325 sissnow, runoff, albsol3_lic, evap_pot, & 326 326 t2m, fluxt, fluxlat, fsollw, fsolsw, & 327 wfbils, wfbilo,cdragm, cdragh, cldl, cldm, &327 wfbils, cdragm, cdragh, cldl, cldm, & 328 328 cldh, cldt, JrNt, & 329 329 ! cldljn, cldmjn, cldhjn, cldtjn & … … 353 353 toplwad_aero, toplwad0_aero, sollwad_aero, & 354 354 sollwad0_aero, toplwai_aero, sollwai_aero, & 355 scdnc, cldncl, reffclws, reffclwc, cldnvi, &356 lcc, lcc3d, lcc3dcon, lcc3dstra, reffclwtop, &355 !scdnc, cldncl, reffclws, reffclwc, cldnvi, & 356 !lcc, lcc3d, lcc3dcon, lcc3dstra, reffclwtop, & 357 357 ec550aer, flwc, fiwc, t_seri, theta, q_seri, & 358 358 !jyg< … … 377 377 USE phys_output_var_mod, ONLY: vars_defined, snow_o, zfra_o, bils_diss, & 378 378 bils_ec,bils_ech, bils_tke, bils_kinetic, bils_latent, bils_enthalp, & 379 itau_con, nfiles, clef_files, nid_files, zvstr_gwd_rando 379 itau_con, nfiles, clef_files, nid_files, zvstr_gwd_rando, & 380 scdnc, cldncl, reffclws, reffclwc, cldnvi, & 381 lcc, lcc3d, lcc3dcon, lcc3dstra, reffclwtop 380 382 USE ocean_slab_mod, ONLY: tslab, slab_bilg, tice, seaice 381 383 USE pbl_surface_mod, ONLY: snow … … 721 723 IF (vars_defined) zx_tmp_fi2d(1 : klon) = wfbils( 1 : klon, nsrf) 722 724 CALL histwrite_phy(o_wbils_srf(nsrf), zx_tmp_fi2d) 723 IF (vars_defined) zx_tmp_fi2d(1 : klon) = wfbilo( 1 : klon, nsrf)724 CALL histwrite_phy(o_wbilo_srf(nsrf), zx_tmp_fi2d)725 725 726 726 IF (iflag_pbl > 1) THEN -
LMDZ6/branches/cirrus/libf/phylmd/StratAer/aer_sedimnt.F90
r3677 r5202 17 17 !----------------------------------------------------------------------- 18 18 19 USE phys_local_var_mod, ONLY: mdw, budg_sed_part, DENSO4, f_r_wet, vsed_aer 19 USE phys_local_var_mod, ONLY: mdw, budg_sed_part, DENSO4, DENSO4B, f_r_wet, f_r_wetB, vsed_aer 20 USE strataer_local_var_mod, ONLY: flag_new_strat_compo 20 21 USE dimphy, ONLY : klon,klev 21 22 USE infotrac_phy … … 89 90 90 91 ! stokes-velocity with cunnigham slip- flow correction 91 ZVAER(JL,JK,nb) = 2./9.*(DENSO4(JL,JK)*1000.-ZRHO)*RG/zvis(JL,JK)*(f_r_wet(JL,JK)*mdw(nb)/2.)**2.* & 92 (1.+ 2.*zlair(JL,JK)/(f_r_wet(JL,JK)*mdw(nb))*(1.257+0.4*EXP(-0.55*f_r_wet(JL,JK)*mdw(nb)/zlair(JL,JK)))) 93 92 IF(flag_new_strat_compo) THEN 93 ! stokes-velocity with cunnigham slip- flow correction 94 ZVAER(JL,JK,nb) = 2./9.*(DENSO4B(JL,JK,nb)*1000.-ZRHO)*RG/zvis(JL,JK)*(f_r_wetB(JL,JK,nb)*mdw(nb)/2.)**2.* & 95 (1.+ 2.*zlair(JL,JK)/(f_r_wetB(JL,JK,nb)*mdw(nb))*(1.257+0.4*EXP(-0.55*f_r_wetB(JL,JK,nb)*mdw(nb)/zlair(JL,JK)))) 96 ELSE 97 ZVAER(JL,JK,nb) = 2./9.*(DENSO4(JL,JK)*1000.-ZRHO)*RG/zvis(JL,JK)*(f_r_wet(JL,JK)*mdw(nb)/2.)**2.* & 98 (1.+ 2.*zlair(JL,JK)/(f_r_wet(JL,JK)*mdw(nb))*(1.257+0.4*EXP(-0.55*f_r_wet(JL,JK)*mdw(nb)/zlair(JL,JK)))) 99 ENDIF 100 94 101 ZSEDFLX(JL,nb)=ZVAER(JL,JK,nb)*ZRHO 95 102 ZSOLAERB(nb)=ZSOLAERB(nb)+ZDTGDP*ZSEDFLX(JL,nb) -
LMDZ6/branches/cirrus/libf/phylmd/StratAer/aerophys.F90
r4601 r5202 5 5 IMPLICIT NONE 6 6 ! 7 REAL,PARAMETER :: ropx=1500.0 ! default aerosol particle mass density [kg/m3] 8 REAL,PARAMETER :: dens_aer_dry=1848.682308 ! dry aerosol particle mass density at T_0=293K[kg/m3] 9 REAL,PARAMETER :: dens_aer_ref=1483.905336 ! aerosol particle mass density with 75% H2SO4 at T_0=293K[kg/m3] 10 REAL,PARAMETER :: mdwmin=0.002e-6 ! dry diameter of smallest aerosol particles [m] 11 REAL,PARAMETER :: V_rat=2.0 ! volume ratio of neighboring size bins 12 REAL,PARAMETER :: mfrac_H2SO4=0.75 ! default mass fraction of H2SO4 in the aerosol 13 REAL, PARAMETER :: mAIRmol=28.949*1.66E-27 ! Average mass of an air molecule [kg] 14 REAL, PARAMETER :: mH2Omol=18.016*1.66E-27 ! Mass of an H2O molecule [kg] 15 REAL, PARAMETER :: mH2SO4mol=98.082*1.66E-27! Mass of an H2SO4 molecule [kg] 16 REAL, PARAMETER :: mSO2mol=64.06*1.66E-27 ! Mass of an SO2 molecule [kg] 17 REAL, PARAMETER :: mSatom=32.06*1.66E-27 ! Mass of a S atom [kg] 18 REAL, PARAMETER :: mOCSmol=60.07*1.66E-27 ! Mass of an OCS molecule [kg] 19 REAL, PARAMETER :: mClatom=35.45*1.66E-27 ! Mass of an Cl atom [kg] 20 REAL, PARAMETER :: mHClmol=36.46*1.66E-27 ! Mass of an HCl molecule [kg] 21 REAL, PARAMETER :: mBratom=79.90*1.66E-27 ! Mass of an Br atom [kg] 22 REAL, PARAMETER :: mHBrmol=80.92*1.66E-27 ! Mass of an HBr molecule [kg] 23 REAL, PARAMETER :: mNOmol=30.01*1.66E-27 ! Mass of an NO molecule [kg] 24 REAL, PARAMETER :: mNO2mol=46.01*1.66E-27 ! Mass of an NO2 molecule [kg] 25 REAL, PARAMETER :: mNatome=14.0067*1.66E-27 ! Mass of an N atome [kg] 7 REAL,PARAMETER :: ropx=1500.0 ! default aerosol particle mass density [kg/m3] 8 REAL,PARAMETER :: dens_aer_dry=1848.682308 ! dry aerosol particle mass density at T_0=293K[kg/m3] 9 REAL,PARAMETER :: dens_aer_ref=1483.905336 ! aerosol particle mass density with 75% H2SO4 at T_0=293K[kg/m3] 10 REAL,PARAMETER :: mdwmin=0.002e-6 ! dry diameter of smallest aerosol particles [m] 11 REAL,PARAMETER :: V_rat=2.0 ! volume ratio of neighboring size bins 12 REAL,PARAMETER :: mfrac_H2SO4=0.75 ! default mass fraction of H2SO4 in the aerosol 13 REAL, PARAMETER :: mAIRmol=28.949*1.66E-27 ! Average mass of an air molecule [kg] 14 REAL, PARAMETER :: mH2Omol=18.016*1.66E-27 ! Mass of an H2O molecule [kg] 15 REAL, PARAMETER :: mH2SO4mol=98.082*1.66E-27! Mass of an H2SO4 molecule [kg] 16 REAL, PARAMETER :: mSO2mol=64.06*1.66E-27 ! Mass of an SO2 molecule [kg] 17 REAL, PARAMETER :: mSatom=32.06*1.66E-27 ! Mass of a S atom [kg] 18 REAL, PARAMETER :: mOCSmol=60.07*1.66E-27 ! Mass of an OCS molecule [kg] 19 REAL, PARAMETER :: mClatom=35.45*1.66E-27 ! Mass of an Cl atom [kg] 20 REAL, PARAMETER :: mHClmol=36.46*1.66E-27 ! Mass of an HCl molecule [kg] 21 REAL, PARAMETER :: mBratom=79.90*1.66E-27 ! Mass of an Br atom [kg] 22 REAL, PARAMETER :: mHBrmol=80.92*1.66E-27 ! Mass of an HBr molecule [kg] 23 REAL, PARAMETER :: mNOmol=30.01*1.66E-27 ! Mass of an NO molecule [kg] 24 REAL, PARAMETER :: mNO2mol=46.01*1.66E-27 ! Mass of an NO2 molecule [kg] 25 REAL, PARAMETER :: mNatome=14.0067*1.66E-27 ! Mass of an N atome [kg] 26 REAL, PARAMETER :: rgas=8.3145 ! molar gas cste (J⋅K−1⋅mol−1=m3⋅Pa⋅K−1⋅mol−1=kg⋅m2⋅s−2⋅K−1⋅mol−1) 27 ! 28 REAL, PARAMETER :: MH2O =1000.*mH2Omol ! Mass of 1 molec [g] (18.016*1.66E-24) 29 REAL, PARAMETER :: MH2SO4=1000.*mH2SO4mol ! Mass of 1 molec [g] (98.082*1.66E-24) 30 REAL, PARAMETER :: BOLZ =1.381E-16 ! Boltzmann constant [dyn.cm/K] 26 31 ! 27 32 END MODULE aerophys -
LMDZ6/branches/cirrus/libf/phylmd/StratAer/coagulate.F90
r4762 r5202 26 26 USE aerophys 27 27 USE infotrac_phy 28 USE phys_local_var_mod, ONLY: DENSO4, f_r_wet 29 28 USE phys_local_var_mod, ONLY: DENSO4, DENSO4B, f_r_wet, f_r_wetB 29 USE strataer_local_var_mod, ONLY: flag_new_strat_compo 30 30 31 IMPLICIT NONE 31 32 … … 43 44 ! local variables in coagulation routine 44 45 INTEGER :: i,j,k,nb,ilon,ilev 45 REAL, DIMENSION(nbtr_bin) :: radius ! aerosol particle radius in each bin [m] 46 REAL, DIMENSION(nbtr_bin) :: radiusdry ! dry aerosol particle radius in each bin [m] 47 REAL, DIMENSION(nbtr_bin) :: radiuswet ! wet aerosol particle radius in each bin [m] 46 48 REAL, DIMENSION(klon,klev,nbtr_bin) :: tr_t ! Concentration Traceur at time t [U/KgA] 47 49 REAL, DIMENSION(klon,klev,nbtr_bin) :: tr_tp1 ! Concentration Traceur at time t+1 [U/KgA] 48 50 REAL, DIMENSION(nbtr_bin,nbtr_bin,nbtr_bin) :: ff ! Volume fraction of intermediate particles 49 REAL, DIMENSION(nbtr_bin) :: V ! Volume of bins 51 REAL, DIMENSION(nbtr_bin) :: Vdry ! Volume dry of bins 52 REAL, DIMENSION(nbtr_bin) :: Vwet ! Volume wet of bins 50 53 REAL, DIMENSION(nbtr_bin,nbtr_bin) :: Vij ! Volume sum of i and j 51 54 REAL :: eta ! Dynamic viscosity of air … … 82 85 include "YOMCST.h" 83 86 84 DO i=1, nbtr_bin 85 radius(i)=mdw(i)/2. 86 V(i)= radius(i)**3. !neglecting factor 4*RPI/3 87 ENDDO 88 89 DO j=1, nbtr_bin 90 DO i=1, nbtr_bin 91 Vij(i,j)= V(i)+V(j) 92 ENDDO 93 ENDDO 94 87 ! ff(i,j,k): Volume fraction of Vi,j that is partitioned to each model bin k 88 ! just need to be calculated in model initialization because mdw(:) size is fixed 89 ! no need to recalculate radius, Vdry, Vij, and ff every timestep because it is for 90 ! dry aerosols 91 DO i=1, nbtr_bin 92 radiusdry(i)=mdw(i)/2. 93 Vdry(i)=radiusdry(i)**3. !neglecting factor 4*RPI/3 94 Vwet(i)=0.0 95 ENDDO 96 97 DO j=1, nbtr_bin 98 DO i=1, nbtr_bin 99 Vij(i,j)= Vdry(i)+Vdry(j) 100 ENDDO 101 ENDDO 102 95 103 !--pre-compute the f(i,j,k) from Jacobson equation 13 96 104 ff=0.0 … … 100 108 IF (k.EQ.1) THEN 101 109 ff(i,j,k)= 0.0 102 ELSEIF (k.GT.1.AND.V (k-1).LT.Vij(i,j).AND.Vij(i,j).LT.V(k)) THEN110 ELSEIF (k.GT.1.AND.Vdry(k-1).LT.Vij(i,j).AND.Vij(i,j).LT.Vdry(k)) THEN 103 111 ff(i,j,k)= 1.-ff(i,j,k-1) 104 112 ELSEIF (k.EQ.nbtr_bin) THEN 105 IF (Vij(i,j).GE. v(k)) THEN113 IF (Vij(i,j).GE.Vdry(k)) THEN 106 114 ff(i,j,k)= 1. 107 115 ELSE 108 116 ff(i,j,k)= 0.0 109 117 ENDIF 110 ELSEIF (k.LE.(nbtr_bin-1).AND.V (k).LE.Vij(i,j).AND.Vij(i,j).LT.V(k+1)) THEN111 ff(i,j,k)= V (k)/Vij(i,j)*(V(k+1)-Vij(i,j))/(V(k+1)-V(k))118 ELSEIF (k.LE.(nbtr_bin-1).AND.Vdry(k).LE.Vij(i,j).AND.Vij(i,j).LT.Vdry(k+1)) THEN 119 ff(i,j,k)= Vdry(k)/Vij(i,j)*(Vdry(k+1)-Vij(i,j))/(Vdry(k+1)-Vdry(k)) 112 120 ENDIF 113 121 ENDDO 114 122 ENDDO 115 123 ENDDO 116 124 ! End of just need to be calculated at initialization because mdw(:) size is fixed 125 117 126 DO ilon=1, klon 118 127 DO ilev=1, klev … … 120 129 IF (is_strato(ilon,ilev)) THEN 121 130 !compute actual wet particle radius & volume for every grid box 122 DO i=1, nbtr_bin 123 radius(i)=f_r_wet(ilon,ilev)*mdw(i)/2. 124 V(i)= radius(i)**3. !neglecting factor 4*RPI/3 125 ENDDO 126 131 IF(flag_new_strat_compo) THEN 132 DO i=1, nbtr_bin 133 radiuswet(i)=f_r_wetB(ilon,ilev,i)*mdw(i)/2. 134 Vwet(i)= radiuswet(i)**3. !neglecting factor 4*RPI/3 135 !! Vwet(i)= Vdry(i)*(f_r_wetB(ilon,ilev,i)**3) 136 ENDDO 137 ELSE 138 DO i=1, nbtr_bin 139 radiuswet(i)=f_r_wet(ilon,ilev)*mdw(i)/2. 140 Vwet(i)= radiuswet(i)**3. !neglecting factor 4*RPI/3 141 !! Vwet(i)= Vdry(i)*(f_r_wet(ilon,ilev)**3) 142 ENDDO 143 ENDIF 144 127 145 !--Calculations for the coagulation kernel--------------------------------------------------------- 128 146 … … 150 168 Di=0.0 151 169 DO i=1, nbtr_bin 152 Kn(i)=mnfrpth/radius(i)153 Di(i)=RKBOL*t_seri(ilon,ilev)/(6.*RPI*radius(i)*eta)*(1.+Kn(i)*(1.249+0.42*exp(-0.87/Kn(i))))170 Kn(i)=mnfrpth/radiuswet(i) 171 Di(i)=RKBOL*t_seri(ilon,ilev)/(6.*RPI*radiuswet(i)*eta)*(1.+Kn(i)*(1.249+0.42*exp(-0.87/Kn(i)))) 154 172 ENDDO 155 173 156 174 !--pre-compute the thermal velocity of a particle thvelpar(i) from equation 20 157 175 thvelpar=0.0 158 DO i=1, nbtr_bin 159 m_par(i)=4./3.*RPI*radius(i)**3.*DENSO4(ilon,ilev)*1000. 160 thvelpar(i)=sqrt(8.*RKBOL*t_seri(ilon,ilev)/(RPI*m_par(i))) 161 ENDDO 176 IF(flag_new_strat_compo) THEN 177 DO i=1, nbtr_bin 178 m_par(i)=4./3.*RPI*radiuswet(i)**3.*DENSO4B(ilon,ilev,i)*1000. 179 thvelpar(i)=sqrt(8.*RKBOL*t_seri(ilon,ilev)/(RPI*m_par(i))) 180 ENDDO 181 ELSE 182 DO i=1, nbtr_bin 183 m_par(i)=4./3.*RPI*radiuswet(i)**3.*DENSO4(ilon,ilev)*1000. 184 thvelpar(i)=sqrt(8.*RKBOL*t_seri(ilon,ilev)/(RPI*m_par(i))) 185 ENDDO 186 ENDIF 162 187 163 188 !--pre-compute the particle mean free path mfppar(i) from equation 22 … … 171 196 delta=0.0 172 197 DO i=1, nbtr_bin 173 delta(i)=((2.*radius(i)+mfppar(i))**3.-(4.*radius(i)**2.+mfppar(i)**2.)**1.5)/ & 174 & (6.*radius(i)*mfppar(i))-2.*radius(i) 175 ENDDO 176 198 delta(i)=((2.*radiuswet(i)+mfppar(i))**3.-(4.*radiuswet(i)**2.+mfppar(i)**2.)**1.5)/ & 199 & (6.*radiuswet(i)*mfppar(i))-2.*radiuswet(i) 200 ENDDO 201 202 ! beta(i,j): coagulation kernel (rate coefficient) of 2 colliding particles i,j 177 203 !--pre-compute the beta(i,j) from equation 17 in Jacobson 178 204 num=0.0 … … 180 206 DO i=1, nbtr_bin 181 207 ! 182 num=4.*RPI*(radius(i)+radius(j))*(Di(i)+Di(j))183 denom=(radius(i)+radius(j))/(radius(i)+radius(j)+sqrt(delta(i)**2.+delta(j)**2.))+ &184 & 4.*(Di(i)+Di(j))/(sqrt(thvelpar(i)**2.+thvelpar(j)**2.)*(radius(i)+radius(j)))185 beta(i,j)=num/denom208 num=4.*RPI*(radiuswet(i)+radiuswet(j))*(Di(i)+Di(j)) 209 denom=(radiuswet(i)+radiuswet(j))/(radiuswet(i)+radiuswet(j)+sqrt(delta(i)**2.+delta(j)**2.))+ & 210 & 4.*(Di(i)+Di(j))/(sqrt(thvelpar(i)**2.+thvelpar(j)**2.)*(radiuswet(i)+radiuswet(j))) 211 beta(i,j)=num/denom 186 212 ! 187 213 !--compute enhancement factor due to van der Waals forces 188 214 IF (ok_vdw .EQ. 0) THEN !--no enhancement factor 189 Evdw=1.0215 Evdw=1.0 190 216 ELSEIF (ok_vdw .EQ. 1) THEN !--E(0) case 191 AvdWi = AvdW/(RKBOL*t_seri(ilon,ilev))*(4.*radius(i)*radius(j))/(radius(i)+radius(j))**2.192 xvdW = LOG(1.+AvdWi)193 EvdW = 1. + avdW1*xvdW + avdW3*xvdW**3217 AvdWi = AvdW/(RKBOL*t_seri(ilon,ilev))*(4.*radiuswet(i)*radiuswet(j))/(radiuswet(i)+radiuswet(j))**2. 218 xvdW = LOG(1.+AvdWi) 219 EvdW = 1. + avdW1*xvdW + avdW3*xvdW**3 194 220 ELSEIF (ok_vdw .EQ. 2) THEN !--E(infinity) case 195 AvdWi = AvdW/(RKBOL*t_seri(ilon,ilev))*(4.*radius(i)*radius(j))/(radius(i)+radius(j))**2.196 xvdW = LOG(1.+AvdWi)197 EvdW = 1. + SQRT(AvdWi/3.)/(1.+bvdW0*SQRT(AvdWi)) + bvdW1*xvdW + bvdW3*xvdW**3.221 AvdWi = AvdW/(RKBOL*t_seri(ilon,ilev))*(4.*radiuswet(i)*radiuswet(j))/(radiuswet(i)+radiuswet(j))**2. 222 xvdW = LOG(1.+AvdWi) 223 EvdW = 1. + SQRT(AvdWi/3.)/(1.+bvdW0*SQRT(AvdWi)) + bvdW1*xvdW + bvdW3*xvdW**3. 198 224 ENDIF 199 225 ! … … 209 235 denom=0.0 210 236 DO j=1, nbtr_bin 211 denom=denom+(1.-ff(k,j,k))*beta(k,j)*tr_t(ilon,ilev,j) 237 ! fraction of coagulation of k and j that is not giving k 238 denom=denom+(1.-ff(k,j,k))*beta(k,j)*tr_t(ilon,ilev,j) 212 239 ENDDO 213 240 … … 219 246 num=0.0 220 247 DO j=1, k 221 numi=0.0 222 DO i=1, k-1 223 numi=numi+ff(i,j,k)*beta(i,j)*V(i)*tr_tp1(ilon,ilev,i)*tr_t(ilon,ilev,j) 248 numi=0.0 249 DO i=1, k-1 250 ! 251 ! see Jacobson: " In order to conserve volume and volume concentration (which 252 ! coagulation physically does) while giving up some accuracy in number concentration" 253 ! 254 ! Coagulation of i and j giving k 255 ! with V(i) and then V(j) because it considers i,j and j,i with the double loop 256 ! 257 ! BUT WHY WET VOLUME V(i) in old STRATAER? tracers are already dry aerosols and coagulation 258 ! kernel beta(i,j) accounts for wet aerosols -> reply below 259 ! 260 ! numi=numi+ff(i,j,k)*beta(i,j)*V(i)*tr_tp1(ilon,ilev,i)*tr_t(ilon,ilev,j) 261 numi=numi+ff(i,j,k)*beta(i,j)*Vdry(i)*tr_tp1(ilon,ilev,i)*tr_t(ilon,ilev,j) 262 ENDDO 263 num=num+numi 224 264 ENDDO 225 num=num+numi226 ENDDO227 265 228 266 !--calculate new concentration of other bins 229 tr_tp1(ilon,ilev,k)=(V(k)*tr_t(ilon,ilev,k)+pdtcoag*num)/(1.+pdtcoag*denom)/V(k) 267 ! tr_tp1(ilon,ilev,k)=(V(k)*tr_t(ilon,ilev,k)+pdtcoag*num)/( (1.+pdtcoag*denom)*V(k) ) 268 tr_tp1(ilon,ilev,k)=(Vdry(k)*tr_t(ilon,ilev,k)+pdtcoag*num)/( (1.+pdtcoag*denom)*Vdry(k) ) 269 ! 270 ! In constant composition (no dependency on aerosol size because no kelvin effect) 271 ! V(l)= (f_r_wet(ilon,ilev)**3)*((mdw(l)/2.)**3) = (f_r_wet(ilon,ilev)**3)*Vdry(i) 272 ! so numi and num are proportional (f_r_wet(ilon,ilev)**3) 273 ! and so 274 ! tr_tp1(ilon,ilev,k)=(V(k)*tr_t(ilon,ilev,k)+pdtcoag*num)/( (1.+pdtcoag*denom)*V(k) ) 275 ! =(Vdry(k)*tr_t(ilon,ilev,k)+pdtcoag*num_dry)/( (1.+pdtcoag*denom)*Vdry(k) ) 276 ! with num_dry=...beta(i,j)*Vdry(i)*.... 277 ! so in old STRATAER (.not.flag_new_strat_compo), it was correct 230 278 ENDIF 231 279 … … 234 282 !--convert tracer concentration back from [number/m3] to [number/KgA] and write into tr_seri 235 283 DO i=1, nbtr_bin 236 tr_seri(ilon,ilev,i+nbtr_sulgas) = tr_tp1(ilon,ilev,i) / zrho284 tr_seri(ilon,ilev,i+nbtr_sulgas) = tr_tp1(ilon,ilev,i) / zrho 237 285 ENDDO 238 286 … … 240 288 ENDDO !--end of loop klev 241 289 ENDDO !--end of loop klon 290 ! ********************************************* 242 291 243 292 END SUBROUTINE COAGULATE -
LMDZ6/branches/cirrus/libf/phylmd/StratAer/cond_evap_tstep_mod.F90
r3677 r5202 9 9 CONTAINS 10 10 11 SUBROUTINE condens_evapor_rate_kelvin(R2SO4G,t_seri,pplay,R2SO4, & 12 & DENSO4,f_r_wet,R2SO4ik,DENSO4ik,f_r_wetik,FL,ASO4,DNDR) 13 ! 14 ! INPUT: 15 ! R2SO4G: number density of gaseous H2SO4 [molecules/cm3] 16 ! t_seri: temperature (K) 17 ! pplay: pressure (Pa) 18 ! R2SO4: aerosol H2SO4 weight fraction (percent) - flat surface (does not depend on aerosol size) 19 ! DENSO4: aerosol density (gr/cm3) 20 ! f_r_wet: factor for converting dry to wet radius 21 ! assuming 'flat surface' composition (does not depend on aerosol size) 22 ! variables that depends on aerosol size because of Kelvin effect 23 ! R2SO4Gik: number density of gaseous H2SO4 [molecules/cm3] - depends on aerosol size 24 ! DENSO4ik: aerosol density (gr/cm3) - depends on aerosol size 25 ! f_r_wetik: factor for converting dry to wet radius - depends on aerosol size 26 ! RRSI: radius [cm] 27 28 USE aerophys 29 USE infotrac_phy 30 USE YOMCST, ONLY : RPI 31 USE sulfate_aer_mod, ONLY : wph2so4, surftension, solh2so4, rpmvh2so4 32 USE strataer_local_var_mod, ONLY : ALPH2SO4, RRSI 33 34 IMPLICIT NONE 35 36 REAL, PARAMETER :: third=1./3. 37 38 ! input variables 39 REAL :: R2SO4G !H2SO4 number density [molecules/cm3] 40 REAL :: t_seri 41 REAL :: pplay 42 REAL :: R2SO4 43 REAL :: DENSO4 44 REAL :: f_r_wet 45 REAL :: R2SO4ik(nbtr_bin), DENSO4ik(nbtr_bin), f_r_wetik(nbtr_bin) 46 47 ! output variables 48 REAL :: FL(nbtr_bin) 49 REAL :: ASO4(nbtr_bin) 50 REAL :: DNDR(nbtr_bin) 51 52 ! local variables 53 INTEGER :: IK 54 REAL :: ALPHA,CST 55 REAL :: WH2(nbtr_bin) 56 REAL :: RP,VTK,AA,FL1,RKNUD 57 REAL :: DND 58 REAL :: ATOT,AH2O 59 REAL :: RRSI_wet(nbtr_bin) 60 REAL :: FPATH, WPP, XA, FKELVIN 61 REAL :: surtens, mvh2so4, temp 62 63 ! /// MOLEC CONDENSATION GROWTH (DUE TO CHANGES IN H2SO4 AND SO H2O) 64 ! ------------------------------------------------------------------ 65 ! EXCEPT CN 66 ! RK:H2SO4 WEIGHT PERCENT DOESN'T CHANGE 67 ! BE CAREFUL,H2SO4 WEIGHT PERCENTAGE 68 69 ! MOLECULAR ACCOMODATION OF H2SO4 70 ! H2SO4 accommodation coefficient [condensation/evaporation] 71 ALPHA = ALPH2SO4 72 ! FPLAIR=(2.281238E-5)*TAIR/PAIR 73 ! 1.E2 (m to cm), 74 CST=1.E2*2.281238E-5 75 ! same expression as in coagulate 76 ! in coagulate: mean free path of air (Pruppacher and Klett, 2010, p.417) [m] 77 ! mnfrpth=6.6E-8*(1.01325E+5/pplay(ilon,ilev))*(t_seri(ilon,ilev)/293.15) 78 ! mnfrpth=2.28E-5*t_seri/pplay 79 80 temp = min( max(t_seri, 190.), 300.) ! 190K <= temp <= 300K 81 82 RRSI_wet(:)=RRSI(:)*f_r_wetik(:) 83 84 ! Pruppa and Klett 85 FPATH=CST*t_seri/pplay 86 87 ! H2SO4 mass fraction in aerosol 88 WH2(:)=R2SO4ik(:)*1.0E-2 89 90 ! ACTIVITY COEFFICIENT(SEE GIAUQUE,1951) 91 ! AYERS ET AL (1980) 92 ! (MU-MU0) 93 ! RP=-10156.0/t_seri +16.259-(ACTSO4*4.184)/(8.31441*t_seri) 94 ! DROPLET H2SO4 PRESSURE IN DYN.CM-2 95 ! RP=EXP(RP)*1.01325E6/0.086 96 !! RP=EXP(RP)*1.01325E6 97 ! H2SO4 NUMBER DENSITY NEAR DROPLET 98 99 ! DND=RP*6.02E23/(8.31E7*t_seri) 100 101 ! KELVIN EFFECT FACTOR 102 !CK 20160613: bug fix, removed factor 250 (from original code by S. Bekki) 103 !! AA =2.0*MH2O*72.0/(DENSO4*BOLZ*t_seri*250.0) 104 ! AA =2.0*MH2O*72.0/(DENSO4*BOLZ*t_seri) 105 106 ! MEAN KINETIC VELOCITY 107 ! DYN*CM*K/(K*GR)=(CM/SEC2)*CM 108 ! IN CM/SEC 109 VTK=SQRT(8.0*BOLZ*t_seri/(RPI*MH2SO4)) 110 ! KELVIN EFFECT FACTOR 111 112 ! Loop on bin radius (RRSI in cm) 113 DO IK=1,nbtr_bin 114 115 IF(R2SO4ik(IK) > 0.0) THEN 116 117 ! h2so4 mass fraction (0<wpp<1) 118 wpp=R2SO4ik(IK)*1.e-2 119 xa=18.*wpp/(18.*wpp+98.*(1.-wpp)) 120 ! equilibrium h2so4 number density over H2SO4/H2O solution (molec/cm3) 121 DND=solh2so4(t_seri,xa) 122 ! KELVIN EFFECT: 123 ! surface tension (mN/m=1.e-3.kg/s2) = f(T,h2so4 mole fraction) 124 surtens=surftension(temp,xa) 125 ! partial molar volume of h2so4 (cm3.mol-1 =1.e-6.m3.mol-1) 126 mvh2so4= rpmvh2so4(temp,R2SO4ik(IK)) 127 ! Kelvin factor (MKS) 128 fkelvin=exp( 2.*1.e-3*surtens*1.e-6*mvh2so4/ (1.e-2*RRSI_wet(IK)*rgas*temp) ) 129 ! 130 DNDR(IK) =DND*fkelvin 131 132 FL1=RPI*ALPHA*VTK*(R2SO4G-DNDR(IK)) 133 134 ! TURCO(1979) FOR HNO3:ALH2SO4 CONDENSATION= ALH2SO4 EVAPORATION 135 ! RPI*R2*VTK IS EQUIVALENT TO DIFFUSION COEFFICIENT 136 ! EXTENSION OF THE RELATION FOR DIFFUSION KINETICS 137 ! KNUDSEN NUMBER FPATH/RRSI 138 ! NEW VERSION (SEE NOTES) 139 RKNUD=FPATH/RRSI_wet(IK) 140 ! SENFELD 141 FL(IK)=FL1*RRSI_wet(IK)**2*( 1.0 +RKNUD ) & 142 & /( 1.0 +ALPHA/(2.0*RKNUD) +RKNUD ) 143 ! TURCO 144 ! RL= (4.0/3.0 +0.71/RKNUD)/(1.0+1.0/RKNUD) 145 ! * +4.0*(1.0-ALPHA)/(3.0*ALPHA) 146 ! FL=FL1*RRSI(IK)*RRSI(IK) 147 ! * /( (3.0*ALPHA/4.0)*(1.0/RKNUD+RL*ALPHA) ) 148 149 ! INITIAL NUMBER OF H2SO4 MOLEC OF 1 DROPLET 150 ATOT=4.0*RPI*DENSO4ik(IK)*(RRSI_wet(IK)**3)/3.0 !attention: g and cm 151 ASO4(IK)=WH2(IK)*ATOT/MH2SO4 !attention: g 152 ! ATOT=4.0*RPI*dens_aer(I,J)/1000.*(RRSI(IK)**3)/3.0 153 ! ASO4=mfrac_H2SO4*ATOT/MH2SO4 154 ! INITIAL NUMBER OF H2O MOLEC OF 1 DROPLET 155 AH2O=(1.0-WH2(IK))*ATOT/MH2O !attention: g 156 157 ! CHANGE OF THE NUMBER OF H2SO4 MOLEC OF 1 DROPLET DURING DT 158 ! IT IS FOR KEM BUT THERE ARE OTHER WAYS 159 160 ENDIF 161 162 ENDDO !loop over bins 163 164 END SUBROUTINE condens_evapor_rate_kelvin 165 166 !******************************************************************** 11 167 SUBROUTINE condens_evapor_rate(R2SO4G,t_seri,pplay,ACTSO4,R2SO4, & 12 & DENSO4,f_r_wet, RRSI,Vbin,FL,ASO4,DNDR)168 & DENSO4,f_r_wet,FL,ASO4,DNDR) 13 169 ! 14 170 ! INPUT: … … 22 178 USE infotrac_phy 23 179 USE YOMCST, ONLY : RPI 180 USE strataer_local_var_mod, ONLY : ALPH2SO4, RRSI 24 181 25 182 IMPLICIT NONE … … 33 190 REAL DENSO4 34 191 REAL f_r_wet 35 REAL RRSI(nbtr_bin) 36 REAL Vbin(nbtr_bin) 37 192 38 193 ! output variables 39 194 REAL FL(nbtr_bin) … … 48 203 REAL ATOT,AH2O 49 204 REAL RRSI_wet(nbtr_bin) 50 REAL Vbin_wet(nbtr_bin) 51 REAL MH2SO4,MH2O,BOLZ,FPATH 205 REAL FPATH 52 206 53 207 ! /// MOLEC CONDENSATION GROWTH (DUE TO CHANGES IN H2SO4 AND SO H2O) … … 57 211 ! BE CAREFUL,H2SO4 WEIGHT PERCENTAGE 58 212 59 ! WEIGHT OF 1 MOLEC IN G60 MH2O =1000.*mH2Omol !18.016*1.66E-2461 MH2SO4=1000.*mH2SO4mol !98.082*1.66E-2462 ! BOLTZMANN CONSTANTE IN DYN.CM/K63 BOLZ =1.381E-1664 213 ! MOLECULAR ACCOMODATION OF H2SO4 65 ! raes and van dingen66 ALPHA = 0.1214 ! H2SO4 accommodation coefficient [condensation/evaporation] 215 ALPHA = ALPH2SO4 67 216 ! FPLAIR=(2.281238E-5)*TAIR/PAIR 68 217 ! 1.E2 (m to cm), 69 218 CST=1.E2*2.281238E-5 70 219 71 ! compute local wet particle radius and volume220 ! compute local wet particle radius [cm] 72 221 RRSI_wet(:)=RRSI(:)*f_r_wet 73 Vbin_wet(:)=Vbin(:)*f_r_wet**3 74 222 75 223 ! Pruppa and Klett 76 224 FPATH=CST*t_seri/pplay … … 138 286 139 287 !******************************************************************** 140 SUBROUTINE cond _evap_part(dt,FL,ASO4,f_r_wet,RRSI,Vbin,tr_seri)288 SUBROUTINE condens_evapor_part(dt,FL,ASO4,f_r_wet,tr_seri) 141 289 142 290 USE aerophys 143 291 USE infotrac_phy 144 292 USE YOMCST, ONLY : RPI 145 293 USE strataer_local_var_mod, ONLY : RRSI,Vbin 294 146 295 IMPLICIT NONE 147 296 … … 151 300 REAL ASO4(nbtr_bin) 152 301 REAL f_r_wet 153 REAL RRSI(nbtr_bin) 154 REAL Vbin(nbtr_bin) 155 302 156 303 ! output variables 157 304 REAL tr_seri(nbtr) 158 305 159 306 ! local variables 160 307 REAL tr_seri_new(nbtr) … … 211 358 tr_seri(:)=tr_seri_new(:) 212 359 213 END SUBROUTINE cond _evap_part360 END SUBROUTINE condens_evapor_part 214 361 215 362 END MODULE cond_evap_tstep_mod -
LMDZ6/branches/cirrus/libf/phylmd/StratAer/micphy_tstep.F90
r4601 r5202 8 8 USE aerophys 9 9 USE infotrac_phy, ONLY : nbtr_bin, nbtr_sulgas, nbtr, id_H2SO4_strat 10 USE phys_local_var_mod, ONLY: mdw, budg_3D_nucl, budg_3D_cond_evap, budg_h2so4_to_part, R2SO4, DENSO4, f_r_wet 10 USE phys_local_var_mod, ONLY: mdw, budg_3D_nucl, budg_3D_cond_evap, budg_h2so4_to_part, R2SO4, DENSO4, & 11 f_r_wet, R2SO4B, DENSO4B, f_r_wetB 11 12 USE nucleation_tstep_mod 12 13 USE cond_evap_tstep_mod … … 14 15 USE YOMCST, ONLY : RPI, RD, RG 15 16 USE print_control_mod, ONLY: lunout 16 USE strataer_local_var_mod 17 USE strataer_local_var_mod ! contains also RRSI and Vbin 17 18 18 19 IMPLICIT NONE … … 35 36 REAL :: ntot !total number of molecules in the critical cluster (ntot>4) 36 37 REAL :: x ! molefraction of H2SO4 in the critical cluster 37 REAL Vbin(nbtr_bin)38 38 REAL a_xm, b_xm, c_xm 39 39 REAL PDT, dt 40 40 REAL H2SO4_init 41 41 REAL ACTSO4(klon,klev) 42 REAL RRSI(nbtr_bin)43 42 REAL nucl_rate 44 43 REAL cond_evap_rate … … 48 47 REAL DNDR(nbtr_bin) 49 48 REAL H2SO4_sat 50 51 DO it=1,nbtr_bin 52 Vbin(it)=4.0*RPI*((mdw(it)/2.)**3)/3.0 53 ENDDO 54 49 REAL R2SO4ik(nbtr_bin), DENSO4ik(nbtr_bin), f_r_wetik(nbtr_bin) 50 55 51 !coefficients for H2SO4 density parametrization used for nucleation if ntot<4 56 52 a_xm = 0.7681724 + 1.*(2.1847140 + 1.*(7.1630022 + 1.*(-44.31447 + & … … 61 57 & 1.*(7.990811e-4 + 1.*(-7.458060e-4 + 1.*2.58139e-4 ))))) 62 58 63 ! STRAACT (R2SO4, t_seri -> H2SO4 activity coefficient (ACTSO4)) for cond/evap 64 CALL STRAACT(ACTSO4) 65 66 ! compute particle radius in cm RRSI from diameter in m 67 DO it=1,nbtr_bin 68 RRSI(it)=mdw(it)/2.*100. 69 ENDDO 70 59 IF(.not.flag_new_strat_compo) THEN 60 ! STRAACT (R2SO4, t_seri -> H2SO4 activity coefficient (ACTSO4)) for cond/evap 61 CALL STRAACT(ACTSO4) 62 ENDIF 63 71 64 DO ilon=1, klon 72 65 ! … … 104 97 ENDIF 105 98 ! compute cond/evap rate in kg(H2SO4)/kgA/s 106 CALL condens_evapor_rate(rhoa,t_seri(ilon,ilev),pplay(ilon,ilev), & 107 & ACTSO4(ilon,ilev),R2SO4(ilon,ilev),DENSO4(ilon,ilev),f_r_wet(ilon,ilev), & 108 & RRSI,Vbin,FL,ASO4,DNDR) 99 IF(flag_new_strat_compo) THEN 100 R2SO4ik(:) = R2SO4B(ilon,ilev,:) 101 DENSO4ik(:) = DENSO4B(ilon,ilev,:) 102 f_r_wetik(:) = f_r_wetB(ilon,ilev,:) 103 CALL condens_evapor_rate_kelvin(rhoa,t_seri(ilon,ilev),pplay(ilon,ilev), & 104 & R2SO4(ilon,ilev),DENSO4(ilon,ilev),f_r_wet(ilon,ilev), & 105 & R2SO4ik,DENSO4ik,f_r_wetik,FL,ASO4,DNDR) 106 ELSE 107 CALL condens_evapor_rate(rhoa,t_seri(ilon,ilev),pplay(ilon,ilev), & 108 & ACTSO4(ilon,ilev),R2SO4(ilon,ilev),DENSO4(ilon,ilev),f_r_wet(ilon,ilev), & 109 & FL,ASO4,DNDR) 110 ENDIF 109 111 ! Compute H2SO4 saturate vapor for big particules 110 112 H2SO4_sat = DNDR(nbtr_bin)/(pplay(ilon,ilev)/t_seri(ilon,ilev)/RD/1.E6/mH2SO4mol) … … 127 129 tr_seri(ilon,ilev,id_H2SO4_strat)=MAX(0.,tr_seri(ilon,ilev,id_H2SO4_strat)-(nucl_rate+cond_evap_rate)*dt) 128 130 ! apply cond to bins 129 CALL cond _evap_part(dt,FL,ASO4,f_r_wet(ilon,ilev),RRSI,Vbin,tr_seri(ilon,ilev,:))131 CALL condens_evapor_part(dt,FL,ASO4,f_r_wet(ilon,ilev),tr_seri(ilon,ilev,:)) 130 132 ! apply nucl. to bins 131 CALL nucleation_part(nucl_rate,ntot,x,dt, Vbin,tr_seri(ilon,ilev,:))133 CALL nucleation_part(nucl_rate,ntot,x,dt,tr_seri(ilon,ilev,:)) 132 134 ! compute fluxes as diagnostic in [kg(S)/m2/layer/s] (now - for evap and + for cond) 133 135 budg_3D_cond_evap(ilon,ilev)=budg_3D_cond_evap(ilon,ilev)+mSatom/mH2SO4mol & … … 142 144 & *pplay(ilon,ilev)/t_seri(ilon,ilev)/RD/1.E6/mH2SO4mol 143 145 ! compute cond/evap rate in kg(H2SO4)/kgA/s (now only evap for pdtphys) 144 CALL condens_evapor_rate(rhoa,t_seri(ilon,ilev),pplay(ilon,ilev), & 145 & ACTSO4(ilon,ilev),R2SO4(ilon,ilev),DENSO4(ilon,ilev),f_r_wet(ilon,ilev), & 146 & RRSI,Vbin,FL,ASO4,DNDR) 146 IF(flag_new_strat_compo) THEN 147 CALL condens_evapor_rate_kelvin(rhoa,t_seri(ilon,ilev),pplay(ilon,ilev), & 148 & R2SO4(ilon,ilev),DENSO4(ilon,ilev),f_r_wet(ilon,ilev), & 149 & R2SO4ik,DENSO4ik,f_r_wetik,FL,ASO4,DNDR) 150 ELSE 151 CALL condens_evapor_rate(rhoa,t_seri(ilon,ilev),pplay(ilon,ilev), & 152 & ACTSO4(ilon,ilev),R2SO4(ilon,ilev),DENSO4(ilon,ilev),f_r_wet(ilon,ilev), & 153 & FL,ASO4,DNDR) 154 ENDIF 147 155 ! limit evaporation (negative FL) over one physics time step to H2SO4 content of the droplet 148 156 DO it=1,nbtr_bin … … 159 167 tr_seri(ilon,ilev,id_H2SO4_strat)=MAX(0.,tr_seri(ilon,ilev,id_H2SO4_strat)-evap_rate*pdtphys) 160 168 ! apply evap to bins 161 CALL cond _evap_part(pdtphys,FL,ASO4,f_r_wet(ilon,ilev),RRSI,Vbin,tr_seri(ilon,ilev,:))169 CALL condens_evapor_part(pdtphys,FL,ASO4,f_r_wet(ilon,ilev),tr_seri(ilon,ilev,:)) 162 170 ! compute fluxes as diagnostic in [kg(S)/m2/layer/s] (now - for evap and + for cond) 163 171 budg_3D_cond_evap(ilon,ilev)=budg_3D_cond_evap(ilon,ilev)+mSatom/mH2SO4mol & -
LMDZ6/branches/cirrus/libf/phylmd/StratAer/miecalc_aer.F90
r3677 r5202 16 16 17 17 USE phys_local_var_mod, ONLY: tr_seri, mdw, alpha_bin, piz_bin, cg_bin 18 USE aerophys 18 USE aerophys, ONLY: dens_aer_dry, dens_aer_ref, V_rat 19 19 USE aero_mod 20 20 USE infotrac_phy, ONLY : nbtr, nbtr_bin, nbtr_sulgas, id_SO2_strat … … 226 226 40000.000, 0.2500, 1.48400, 1.0000E-08, & 227 227 50000.000, 0.2000, 1.49800, 1.0000E-08 /), (/nb_lambda_h2so4,4/), order=(/2,1/) ) 228 229 !--initialising dry diameters to geometrically spaced mass/volume (see Jacobson 1994) 230 mdw(1)=mdwmin 231 IF (V_rat.LT.1.62) THEN ! compensate for dip in second bin for lower volume ratio 232 mdw(2)=mdw(1)*2.**(1./3.) 233 DO it=3, nbtr_bin 234 mdw(it)=mdw(it-1)*V_rat**(1./3.) 235 ENDDO 236 ELSE 237 DO it=2, nbtr_bin 238 mdw(it)=mdw(it-1)*V_rat**(1./3.) 239 ENDDO 240 ENDIF 241 WRITE(lunout,*) 'init mdw=', mdw 242 228 243 229 !--compute particle radius for a composition of 75% H2SO4 / 25% H2O at T=293K 244 230 DO bin_number=1, nbtr_bin -
LMDZ6/branches/cirrus/libf/phylmd/StratAer/nucleation_tstep_mod.F90
r4912 r5202 70 70 !-------------------------------------------------------------------------------------------------- 71 71 72 SUBROUTINE nucleation_part(nucl_rate,ntot,x,dt, Vbin,tr_seri)72 SUBROUTINE nucleation_part(nucl_rate,ntot,x,dt,tr_seri) 73 73 74 74 USE aerophys 75 75 USE infotrac_phy 76 76 USE strataer_local_var_mod, ONLY : Vbin 77 77 78 IMPLICIT NONE 78 79 … … 82 83 REAL x ! mole raction of H2SO4 in the critical cluster 83 84 REAL dt 84 REAL Vbin(nbtr_bin) 85 85 86 86 ! output variable 87 87 REAL tr_seri(nbtr) -
LMDZ6/branches/cirrus/libf/phylmd/StratAer/strataer_local_var_mod.F90
r4767 r5202 51 51 52 52 !============= NUCLEATION VARS ============= 53 ! MOLECULAR ACCOMODATION OF H2SO4 (Raes and Van Dingen) 54 REAL,SAVE :: ALPH2SO4 ! H2SO4 accommodation coefficient [condensation/evaporation] 55 !$OMP THREADPRIVATE(ALPH2SO4) 56 53 57 ! flag to constraint nucleation rate in a lat/pres box 54 58 LOGICAL,SAVE :: flag_nuc_rate_box ! Nucleation rate limit or not to a lat/pres … … 64 68 INTEGER,SAVE :: flh2o ! ds stratemit : flh2o =0 (tr_seri), flh2o=1 (dq) 65 69 !$OMP THREADPRIVATE(flh2o) 66 ! REAL,ALLOCATABLE,SAVE :: d_q_emiss(:,:)67 ! !$OMP THREADPRIVATE(d_q_emiss)68 70 69 71 REAL,ALLOCATABLE,SAVE :: budg_emi(:,:) !DIMENSION(klon,n) … … 144 146 !$OMP THREADPRIVATE(day_emit_roc) 145 147 148 REAL,ALLOCATABLE,SAVE :: RRSI(:) ! radius [cm] for each aerosol size 149 REAL,ALLOCATABLE,SAVE :: Vbin(:) ! volume [m3] for each aerosol size 150 !$OMP THREADPRIVATE(RRSI, Vbin) 146 151 REAL,SAVE :: dlat, dlon ! delta latitude and d longitude of grid in degree 147 152 !$OMP THREADPRIVATE(dlat, dlon) … … 153 158 USE print_control_mod, ONLY : lunout 154 159 USE mod_phys_lmdz_para, ONLY : is_master 155 USE infotrac_phy, ONLY: id_OCS_strat,id_SO2_strat,id_H2SO4_strat,nbtr_sulgas 160 USE infotrac_phy, ONLY: id_OCS_strat,id_SO2_strat,id_H2SO4_strat,nbtr_sulgas,nbtr_bin 161 USE phys_local_var_mod, ONLY : mdw 162 USE aerophys, ONLY: mdwmin, V_rat 163 USE YOMCST , ONLY : RPI 164 165 INTEGER :: it 156 166 157 167 WRITE(lunout,*) 'IN STRATAER_LOCAL_VAR INIT WELCOME!' … … 185 195 186 196 ! nuc init 197 ALPH2SO4 = 0.1 187 198 flag_nuc_rate_box = .FALSE. 188 199 nuclat_min=0 ; nuclat_max=0 … … 238 249 ENDIF ! if master 239 250 251 !--initialising dry diameters to geometrically spaced mass/volume (see Jacobson 1994) 252 mdw(1)=mdwmin 253 IF (V_rat.LT.1.62) THEN ! compensate for dip in second bin for lower volume ratio 254 mdw(2)=mdw(1)*2.**(1./3.) 255 DO it=3, nbtr_bin 256 mdw(it)=mdw(it-1)*V_rat**(1./3.) 257 ENDDO 258 ELSE 259 DO it=2, nbtr_bin 260 mdw(it)=mdw(it-1)*V_rat**(1./3.) 261 ENDDO 262 ENDIF 263 IF (is_master) WRITE(lunout,*) 'init mdw=', mdw 264 265 ! compute particle radius RRSI [cm] and volume Vbin [m3] from diameter mdw [m] 266 ALLOCATE(RRSI(nbtr_bin), Vbin(nbtr_bin)) 267 268 DO it=1,nbtr_bin 269 ! [cm] 270 RRSI(it)=mdw(it)/2.*100. 271 ! [m3] 272 Vbin(it)=4.0*RPI*((mdw(it)/2.)**3)/3.0 273 ENDDO 274 275 IF (is_master) THEN 276 WRITE(lunout,*) 'init RRSI=', RRSI 277 WRITE(lunout,*) 'init Vbin=', Vbin 278 ENDIF 279 240 280 WRITE(lunout,*) 'IN STRATAER INIT END' 241 281 -
LMDZ6/branches/cirrus/libf/phylmd/StratAer/strataer_nuc_mod.F90
r4601 r5202 13 13 USE print_control_mod, ONLY : lunout 14 14 USE mod_phys_lmdz_para, ONLY : is_master 15 USE strataer_local_var_mod, ONLY: flag_nuc_rate_box,nuclat_min,nuclat_max,nucpres_min,nucpres_max 15 USE strataer_local_var_mod, ONLY: ALPH2SO4,flag_nuc_rate_box,nuclat_min,nuclat_max, & 16 nucpres_min,nucpres_max 16 17 17 18 !Config Key = flag_nuc_rate_box … … 30 31 CALL getin_p('nucpres_max',nucpres_max) 31 32 33 ! Read argument H2SO4 accommodation coefficient [condensation/evaporation] 34 CALL getin_p('alph2so4',ALPH2SO4) 35 32 36 !============= Print params ============= 33 37 IF (is_master) THEN 38 WRITE(lunout,*) 'IN STRATAER_NUC : ALPH2SO4 = ',alph2so4 34 39 WRITE(lunout,*) 'IN STRATAER_NUC : flag_nuc_rate_box = ',flag_nuc_rate_box 35 40 IF (flag_nuc_rate_box) THEN -
LMDZ6/branches/cirrus/libf/phylmd/StratAer/sulfate_aer_mod.F90
r4750 r5202 7 7 8 8 !******************************************************************* 9 SUBROUTINE STRACOMP_BIN(sh,t_seri,pplay) 10 ! 11 ! Aerosol H2SO4 weight fraction as a function of PH2O and temperature 12 ! INPUT: 13 ! sh: VMR of H2O 14 ! t_seri: temperature (K) 15 ! pplay: middle layer pression (Pa) 16 ! 17 ! OUTPUT: 18 ! R2SO4: aerosol H2SO4 weight fraction (percent) 9 SUBROUTINE STRACOMP_KELVIN(sh,t_seri,pplay) 10 ! 11 ! Aerosol H2SO4 weight fraction as a function of PH2O and temperature 12 ! INPUT: 13 ! sh: MMR of H2O 14 ! t_seri: temperature (K) 15 ! pplay: middle layer pression (Pa) 16 ! 17 ! Modified in modules: 18 ! R2SO4: aerosol H2SO4 weight fraction (percent) 19 ! R2SO4B: aerosol H2SO4 weight fraction (percent) for each aerosol bin 20 ! DENSO4: aerosol density (gr/cm3) 21 ! DENSO4B: aerosol density (gr/cm3)for each aerosol bin 22 ! f_r_wet: factor for converting dry to wet radius 23 ! assuming 'flat surface' composition (does not depend on aerosol size) 24 ! f_r_wetB: factor for converting dry to wet radius 25 ! assuming 'curved surface' composition (depends on aerosol size) 19 26 20 USE dimphy, ONLY : klon,klev ! nb of longitude and altitude bands 21 USE aerophys 22 USE phys_local_var_mod, ONLY: R2SO4 27 USE dimphy, ONLY : klon,klev ! nb of longitude and altitude bands 28 USE infotrac_phy, ONLY : nbtr_bin 29 USE aerophys 30 USE phys_local_var_mod, ONLY: R2SO4, R2SO4B, DENSO4, DENSO4B, f_r_wet, f_r_wetB 31 USE strataer_local_var_mod, ONLY: RRSI 32 ! WARNING: in phys_local_var_mod R2SO4B, DENSO4B, f_r_wetB (klon,klev,nbtr_bin) 33 ! and dens_aer_dry must be declared somewhere 23 34 24 IMPLICIT NONE35 IMPLICIT NONE 25 36 26 REAL,DIMENSION(klon,klev),INTENT(IN) :: t_seri ! Temperature 27 REAL,DIMENSION(klon,klev),INTENT(IN) :: pplay ! pression in the middle of each layer (Pa) 28 REAL,DIMENSION(klon,klev),INTENT(IN) :: sh ! specific humidity 37 REAL,DIMENSION(klon,klev),INTENT(IN) :: t_seri ! Temperature 38 REAL,DIMENSION(klon,klev),INTENT(IN) :: pplay ! pression in the middle of each layer (Pa) 39 REAL,DIMENSION(klon,klev),INTENT(IN) :: sh ! specific humidity (kg h2o/kg air) 40 41 ! local variables 42 integer :: ilon,ilev,ik 43 real, parameter :: rath2oair = mAIRmol/mH2Omol 44 real, parameter :: third = 1./3. 45 real :: pph2ogas(klon,klev) 46 real :: temp, wpp, xa, surtens, mvh2o, radwet, fkelvin, pph2okel, r2so4ik, denso4ik 47 !---------------------------------------- 48 49 ! gas-phase h2o partial pressure (Pa) 50 ! vmr=sh*rath2oair 51 pph2ogas(:,:) = pplay(:,:)*sh(:,:)*rath2oair 29 52 30 REAL ks(7) 31 REAL t,qh2o,ptot,pw 32 REAL a,b,c,det 33 REAL xsb,msb 53 DO ilon=1,klon 54 DO ilev=1,klev 55 56 temp = max(t_seri(ilon,ilev),190.) 57 temp = min(temp,300.) 58 59 ! *** H2SO4-H2O flat surface *** 60 !! equilibrium H2O pressure over pure flat liquid water (Pa) 61 !! pflath2o=psh2o(temp) 62 ! h2so4 weight percent(%) = f(P_h2o(Pa),T) 63 R2SO4(ilon,ilev)=wph2so4(pph2ogas(ilon,ilev),temp) 64 ! h2so4 mass fraction (0<wpp<1) 65 wpp=R2SO4(ilon,ilev)*1.e-2 66 ! mole fraction 67 xa=18.*wpp/(18.*wpp+98.*(1.-wpp)) 68 69 ! CHECK:compare h2so4 sat/ pressure (see Marti et al., 97 & reef. therein) 70 ! R2SO4(ilon,ilev)=70. temp=298.15 71 ! equilibrium h2so4 number density over H2SO4/H2O solution (molec/cm3) 72 ! include conversion from molec/cm3 to Pa 73 ! ph2so4=solh2so4(temp,xa)*(1.38065e-16*temp)/10. 74 ! print*,' ph2so4=',ph2so4,temp,R2SO4(ilon,ilev) 75 ! good match with Martin, et Ayers, not with Gmitro (the famous 0.086) 76 77 ! surface tension (mN/m=1.e-3.kg/s2) = f(T,h2so4 mole fraction) 78 surtens=surftension(temp,xa) 79 ! molar volume of pure h2o (cm3.mol-1 =1.e-6.m3.mol-1) 80 mvh2o= rmvh2o(temp) 81 ! aerosol density (gr/cm3) = f(T,h2so4 mass fraction) 82 DENSO4(ilon,ilev)=density(temp,wpp) 83 ! ->x1000., to have it in kg/m3 84 ! factor for converting dry to wet radius 85 f_r_wet(ilon,ilev) = (dens_aer_dry/(DENSO4(ilon,ilev)*1.e3)/ & 86 & (R2SO4(ilon,ilev)*1.e-2))**third 87 ! *** End of H2SO4-H2O flat surface *** 88 89 90 ! Loop on bin radius (RRSI in cm) 91 DO IK=1,nbtr_bin 92 93 ! *** H2SO4-H2O curved surface - Kelvin effect factor *** 94 ! wet radius (m) (RRSI(IK) in [cm]) 95 if (f_r_wetB(ilon,ilev,IK) .gt. 1.0) then 96 radwet = 1.e-2*RRSI(IK)*f_r_wetB(ilon,ilev,IK) 97 else 98 ! H2SO4-H2O flat surface, only on the first timestep 99 radwet = 1.e-2*RRSI(IK)*f_r_wet(ilon,ilev) 100 endif 101 ! Kelvin factor: 102 ! surface tension (mN/m=1.e-3.kg/s2) 103 ! molar volume of pure h2o (cm3.mol-1 =1.e-6.m3.mol-1) 104 fkelvin=exp( 2.*1.e-3*surtens*1.e-6*mvh2o/ (radwet*rgas*temp) ) 105 ! equilibrium: pph2o(gas) = pph2o(liq) = pph2o(liq_flat) * fkelvin 106 ! equilibrium: pph2o(liq_flat) = pph2o(gas) / fkelvin 107 ! h2o liquid partial pressure before Kelvin effect (Pa) 108 pph2okel = pph2ogas(ilon,ilev) / fkelvin 109 ! h2so4 weight percent(%) = f(P_h2o(Pa),temp) 110 r2so4ik=wph2so4(pph2okel,temp) 111 ! h2so4 mass fraction (0<wpp<1) 112 wpp=r2so4ik*1.e-2 113 ! mole fraction 114 xa=18.*wpp/(18.*wpp+98.*(1.-wpp)) 115 ! aerosol density (gr/cm3) = f(T,h2so4 mass fraction) 116 denso4ik=density(temp,wpp) 117 ! 118 ! recalculate Kelvin factor with surface tension and radwet 119 ! with new R2SO4B and DENSO4B 120 surtens=surftension(temp,xa) 121 ! wet radius (m) 122 radwet = 1.e-2*RRSI(IK)*(dens_aer_dry/(denso4ik*1.e3)/ & 123 & (r2so4ik*1.e-2))**third 124 fkelvin=exp( 2.*1.e-3*surtens*1.e-6*mvh2o / (radwet*rgas*temp) ) 125 pph2okel=pph2ogas(ilon,ilev) / fkelvin 126 ! h2so4 weight percent(%) = f(P_h2o(Pa),temp) 127 R2SO4B(ilon,ilev,IK)=wph2so4(pph2okel,temp) 128 ! h2so4 mass fraction (0<wpp<1) 129 wpp=R2SO4B(ilon,ilev,IK)*1.e-2 130 xa=18.*wpp/(18.*wpp+98.*(1.-wpp)) 131 ! aerosol density (gr/cm3) = f(T,h2so4 mass fraction) 132 DENSO4B(ilon,ilev,IK)=density(temp,wpp) 133 ! factor for converting dry to wet radius 134 f_r_wetB(ilon,ilev,IK) = (dens_aer_dry/(DENSO4B(ilon,ilev,IK)*1.e3)/ & 135 & (R2SO4B(ilon,ilev,IK)*1.e-2))**third 136 ! 137 ! print*,'R,Rwet(m),kelvin,h2so4(%),ro=',RRSI(ik),radwet,fkelvin, & 138 ! & R2SO4B(ilon,ilev,IK),DENSO4B(ilon,ilev,IK) 139 ! print*,' equil.h2so4(molec/cm3), & 140 ! & sigma',solh2so4(temp,xa),surftension(temp,xa) 141 142 ENDDO 143 144 ENDDO 145 ENDDO 146 147 RETURN 34 148 35 INTEGER ilon,ilev 36 DATA ks/-21.661,2724.2,51.81,-15732.0,47.004,-6969.0,-4.6183/ 37 38 !******************************************************************* 39 !*** liquid aerosols process 40 !******************************************************************* 41 ! BINARIES LIQUID AEROROLS: 42 43 DO ilon=1,klon 44 DO ilev=1,klev 45 46 t = max(t_seri(ilon,ilev),185.) 47 qh2o=sh(ilon,ilev)/18.*28.9 48 ptot=pplay(ilon,ilev)/100. 49 pw = qh2o*ptot/1013.0 50 pw = min(pw,2.e-3/1013.) 51 pw = max(pw,2.e-5/1013.) 52 53 !******************************************************************* 54 !*** binaries aerosols h2so4/h2o 55 !******************************************************************* 56 a = ks(3) + ks(4)/t 57 b = ks(1) + ks(2)/t 58 c = ks(5) + ks(6)/t + ks(7)*log(t) - log(pw) 59 60 det = b**2 - 4.*a*c 61 62 IF (det > 0.) THEN 63 xsb = (-b - sqrt(det))/(2.*a) 64 msb = 55.51*xsb/(1.0 - xsb) 65 ELSE 66 msb = 0. 67 ENDIF 68 R2SO4(ilon,ilev) = 100*msb*0.098076/(1.0 + msb*0.098076) 69 70 ! H2SO4 min dilution: 0.5% 71 R2SO4(ilon,ilev) = max( R2SO4(ilon,ilev), 0.005 ) 72 ENDDO 73 ENDDO 74 100 RETURN 75 76 END SUBROUTINE STRACOMP_BIN 77 149 END SUBROUTINE STRACOMP_KELVIN 78 150 !******************************************************************** 79 151 SUBROUTINE STRACOMP(sh,t_seri,pplay) … … 544 616 545 617 END SUBROUTINE 546 547 !****************************************************************548 SUBROUTINE DENH2SA_TABA(t_seri)549 550 ! AERSOL DENSITY AS A FUNCTION OF H2SO4 WEIGHT PERCENT AND T551 ! from Tabazadeh et al. (1994) abaques552 ! ---------------------------------------------553 554 !555 ! INPUT:556 ! R2SO4: aerosol H2SO4 weight fraction (percent)557 ! t_seri: temperature (K)558 ! klon: number of latitude bands in the model domain559 ! klev: number of altitude bands in the model domain560 ! for IFS: perhaps add another dimension for longitude561 !562 ! OUTPUT:563 ! DENSO4: aerosol mass density (gr/cm3 = aerosol mass/aerosol volume)564 !565 USE dimphy, ONLY : klon,klev566 USE phys_local_var_mod, ONLY: R2SO4, DENSO4567 568 IMPLICIT NONE569 570 REAL,DIMENSION(klon,klev),INTENT(IN) :: t_seri ! Temperature571 572 INTEGER i,j573 574 !----------------------------------------------------------------------575 ! ... Local variables576 !----------------------------------------------------------------------577 real, parameter :: a9 = -268.2616e4, a10 = 576.4288e3578 579 real :: a0, a1, a2, a3, a4, a5, a6, a7 ,a8580 real :: c1, c2, c3, c4, w581 582 583 ! Loop on model domain (2 dimension for UPMC model; 3 for IFS)584 DO i=1,klon585 DO j=1,klev586 !----------------------------------------------------------------------587 ! ... Temperature variables588 !----------------------------------------------------------------------589 c1 = t_seri(I,J)- 273.15590 c2 = c1**2591 c3 = c1*c2592 c4 = c1*c3593 !----------------------------------------------------------------------594 ! Polynomial Coefficients595 !----------------------------------------------------------------------596 a0 = 999.8426 + 334.5402e-4*c1 - 569.1304e-5*c2597 a1 = 547.2659 - 530.0445e-2*c1 + 118.7671e-4*c2 + 599.0008e-6*c3598 a2 = 526.295e1 + 372.0445e-1*c1 + 120.1909e-3*c2 - 414.8594e-5*c3 + 119.7973e-7*c4599 a3 = -621.3958e2 - 287.7670*c1 - 406.4638e-3*c2 + 111.9488e-4*c3 + 360.7768e-7*c4600 a4 = 409.0293e3 + 127.0854e1*c1 + 326.9710e-3*c2 - 137.7435e-4*c3 - 263.3585e-7*c4601 a5 = -159.6989e4 - 306.2836e1*c1 + 136.6499e-3*c2 + 637.3031e-5*c3602 a6 = 385.7411e4 + 408.3717e1*c1 - 192.7785e-3*c2603 a7 = -580.8064e4 - 284.4401e1*c1604 a8 = 530.1976e4 + 809.1053*c1605 !----------------------------------------------------------------------606 ! ... Summation607 !----------------------------------------------------------------------608 ! w : H2SO4 Weight fraction609 w=r2SO4(i,j)*0.01610 DENSO4(i,j) = 0.001*(a0 + w*(a1 + w*(a2 + w*(a3 + w*(a4 + &611 w*(a5 + w*(a6 + w*(a7 + w*(a8 + w*(a9 + w*a10))))))))))612 DENSO4(i,j) = max (0.0, DENSO4(i,j) )613 614 ENDDO615 ENDDO616 617 END SUBROUTINE DENH2SA_TABA618 618 619 619 !**************************************************************** … … 764 764 RETURN 765 765 END SUBROUTINE 766 766 !******************************************************************** 767 !----------------------------------------------------------------------- 768 real function psh2so4(T) result(psh2so4_out) 769 ! equilibrium H2SO4 pressure over pure H2SO4 solution (Pa) 770 ! 771 !---->Ayers et.al. (1980), GRL (7) pp 433-436 772 ! plus corrections for lower temperatures by Kulmala and Laaksonen (1990) 773 ! and Noppel et al. (1990) 774 775 implicit none 776 real, intent(in) :: T 777 real, parameter :: & 778 & b1=1.01325e5, & 779 & b2=11.5, & 780 & b3=1.0156e4, & 781 & b4=0.38/545., & 782 & tref=360.15 783 784 ! saturation vapor pressure ( N/m2 = Pa = kg/(m.s2) ) 785 psh2so4_out=b1*exp( -b2 +b3*( 1./tref-1./T & 786 & +b4*(1.+log(tref/T)-tref/T) ) ) 787 788 return 789 end function psh2so4 790 !----------------------------------------------------------------------- 791 real function ndsh2so4(T) result(ndsh2so4_out) 792 ! equilibrium H2SO4 number density over pure H2SO4 (molec/cm3) 793 794 implicit none 795 real, intent(in) :: T 796 real :: presat 797 798 ! Boltzmann constant ( 1.38065e-23 J/K = m2⋅kg/(s2⋅K) ) 799 ! akb idem in cm2⋅g/(s2⋅K) 800 real, parameter :: akb=1.38065e-16 801 802 ! pure h2so4 saturation vapor pressure (Pa) 803 presat=psh2so4(T) 804 ! saturation number density (1/cm3) - (molec/cm3) 805 ndsh2so4_out=presat*10./(akb*T) 806 807 return 808 end function ndsh2so4 809 !----------------------------------------------------------------------- 810 real function psh2o(T) result(psh2o_out) 811 ! equilibrium H2O pressure over pure liquid water (Pa) 812 ! 813 implicit none 814 real, intent(in) :: T 815 816 if(T.gt.229.) then 817 ! Preining et al., 1981 (from Kulmala et al., 1998) 818 ! saturation vapor pressure (N/m2 = 1 Pa = 1 kg/(m·s2)) 819 psh2o_out=exp( 77.34491296 -7235.424651/T & 820 & -8.2*log(T) + 5.7133e-3*T ) 821 else 822 ! Tabazadeh et al., 1997, parameterization for 185<T<260 823 ! saturation water vapor partial pressure (mb = hPa =1.E2 kg/(m·s2)) 824 ! or from Clegg and Brimblecombe , J. Chem. Eng., p43, 1995. 825 ; 826 psh2o_out=18.452406985 -3505.1578807/T & 827 & -330918.55082/(T*T) & 828 & +12725068.262/(T*T*T) 829 ! in Pa 830 psh2o_out=100.*exp(psh2o_out) 831 end if 832 ! print*,psh2o_out 833 834 return 835 end function psh2o 836 !----------------------------------------------------------------------- 837 real function density(T,so4mfrac) result(density_out) 838 ! calculation of particle density (gr/cm3) 839 840 ! requires Temperature (T) and acid mass fraction (so4mfrac) 841 !---->Vehkamaeki et al. (2002) 842 843 implicit none 844 real, intent(in) :: T, so4mfrac 845 real, parameter :: & 846 & a1= 0.7681724,& 847 & a2= 2.184714, & 848 & a3= 7.163002, & 849 & a4=-44.31447, & 850 & a5= 88.74606, & 851 & a6=-75.73729, & 852 & a7= 23.43228 853 real, parameter :: & 854 & b1= 1.808225e-3, & 855 & b2=-9.294656e-3, & 856 & b3=-3.742148e-2, & 857 & b4= 2.565321e-1, & 858 & b5=-5.362872e-1, & 859 & b6= 4.857736e-1, & 860 & b7=-1.629592e-1 861 real, parameter :: & 862 & c1=-3.478524e-6, & 863 & c2= 1.335867e-5, & 864 & c3= 5.195706e-5, & 865 & c4=-3.717636e-4, & 866 & c5= 7.990811e-4, & 867 & c6=-7.458060e-4, & 868 & c7= 2.581390e-4 869 real :: a,b,c,so4m2,so4m3,so4m4,so4m5,so4m6 870 871 so4m2=so4mfrac*so4mfrac 872 so4m3=so4mfrac*so4m2 873 so4m4=so4mfrac*so4m3 874 so4m5=so4mfrac*so4m4 875 so4m6=so4mfrac*so4m5 876 877 a=+a1+a2*so4mfrac+a3*so4m2+a4*so4m3 & 878 & +a5*so4m4+a6*so4m5+a7*so4m6 879 b=+b1+b2*so4mfrac+b3*so4m2+b4*so4m3 & 880 & +b5*so4m4+b6*so4m5+b7*so4m6 881 c=+c1+c2*so4mfrac+c3*so4m2+c4*so4m3 & 882 & +c5*so4m4+c6*so4m5+c7*so4m6 883 density_out=(a+b*T+c*T*T) ! units are gm/cm**3 884 885 return 886 end function density 887 !----------------------------------------------------------------------- 888 real function surftension(T,so4frac) result(surftension_out) 889 ! calculation of surface tension (mN/meter) 890 ! requires Temperature (T) and acid mole fraction (so4frac) 891 !---->Vehkamaeki et al. (2002) 892 893 implicit none 894 real,intent(in) :: T, so4frac 895 real :: a,b,so4mfrac,so4m2,so4m3,so4m4,so4m5,so4sig 896 real, parameter :: & 897 & a1= 0.11864, & 898 & a2=-0.11651, & 899 & a3= 0.76852, & 900 & a4=-2.40909, & 901 & a5= 2.95434, & 902 & a6=-1.25852 903 real, parameter :: & 904 & b1=-1.5709e-4, & 905 & b2= 4.0102e-4, & 906 & b3=-2.3995e-3, & 907 & b4= 7.611235e-3, & 908 & b5=-9.37386e-3, & 909 & b6= 3.89722e-3 910 real, parameter :: convfac=1.e3 ! convert from newton/m to dyne/cm 911 real, parameter :: Mw=18.01528, Ma=98.079 912 913 ! so4 mass fraction 914 so4mfrac=Ma*so4frac/( Ma*so4frac+Mw*(1.-so4frac) ) 915 so4m2=so4mfrac*so4mfrac 916 so4m3=so4mfrac*so4m2 917 so4m4=so4mfrac*so4m3 918 so4m5=so4mfrac*so4m4 919 920 a=+a1+a2*so4mfrac+a3*so4m2+a4*so4m3+a5*so4m4+a6*so4m5 921 b=+b1+b2*so4mfrac+b3*so4m2+b4*so4m3+b5*so4m4+b6*so4m5 922 so4sig=a+b*T 923 surftension_out=so4sig*convfac 924 925 return 926 end function surftension 927 !----------------------------------------------------------------------- 928 real function wph2so4(pph2o,T) result(wph2so4_out) 929 ! Calculates the equilibrium composition of h2so4 aerosols 930 ! as a function of temperature and H2O pressure, using 931 ! the parameterization of Tabazadeh et al., GRL, p1931, 1997. 932 ! 933 ! Parameters 934 ! 935 ! input: 936 ! T.....temperature (K) 937 ! pph2o..... amhbiant 2o pressure (Pa) 938 ! 939 ! output: 940 ! wph2so4......sulfuric acid composition (weight percent wt % h2so4) 941 ! = h2so4 mass fraction*100. 942 ! 943 implicit none 944 real, intent(in) :: pph2o, T 945 946 real :: aw, rh, y1, y2, sulfmolal 947 948 ! psh2o(T): equilibrium H2O pressure over pure liquid water (Pa) 949 ! relative humidity 950 rh=pph2o/psh2o(T) 951 ! water activity 952 ! aw=min( 0.999,max(1.e-3,rh) ) 953 aw=min( 0.999999999,max(1.e-8,rh) ) 954 955 ! composition 956 ! calculation of h2so4 molality 957 if(aw .le. 0.05 .and. aw .gt. 0.) then 958 y1=12.372089320*aw**(-0.16125516114) & 959 & -30.490657554*aw -2.1133114241 960 y2=13.455394705*aw**(-0.19213122550) & 961 & -34.285174607*aw -1.7620073078 962 else if(aw .le. 0.85 .and. aw .gt. 0.05) then 963 y1=11.820654354*aw**(-0.20786404244) & 964 & -4.8073063730*aw -5.1727540348 965 y2=12.891938068*aw**(-0.23233847708) & 966 & -6.4261237757*aw -4.9005471319 967 else 968 y1=-180.06541028*aw**(-0.38601102592) & 969 & -93.317846778*aw +273.88132245 970 y2=-176.95814097*aw**(-0.36257048154) & 971 & -90.469744201*aw +267.45509988 972 end if 973 ! h2so4 molality (m=moles of h2so4 (solute)/ kg of h2o(solvent)) 974 sulfmolal = y1+((T-190.)*(y2-y1)/70.) 975 976 ! for a solution containing mh2so4 and mh2o: 977 ! sulfmolal = (mh2so4(gr)/h2so4_molar_mass(gr/mole)) / (mh2o(gr)*1.e-3) 978 ! mh2o=1.e3*(mh2so4/Mh2so4)/sulfmolal=1.e3*mh2so4/(Mh2so4*sulfmolal) 979 ! h2so4_mass_fraction = mfh2so4 = mh2so4/(mh2o + mh2so4) 980 ! mh2o=mh2so4*(1-mfh2so4)/mfh2so4 981 ! combining the 2 equations 982 ! 1.e3*mh2so4/(Mh2so4*sulfmolal) = mh2so4*(1-mfh2so4)/mfh2so4 983 ! 1.e3/(Mh2so4*sulfmolal) = (1-mfh2so4)/mfh2so4 984 ! 1000*mfh2so4 = (1-mfh2so4)*Mh2so4*sulfmolal 985 ! mfh2so4*(1000.+Mh2so4*sulfmolal) = Mh2so4*sulfmolal 986 ! mfh2so4 = Mh2so4*sulfmolal / (1000.+Mh2so4*sulfmolal) 987 ! wph2so4 (% mass fraction)= 100.*Mh2so4*sulfmolal / (1000.+Mh2so4*sulfmolal) 988 ! recall activity of i = a_i = P_i/P_pure_i and 989 ! activity coefficient of i = gamma_i = a_i/X_i (X_i: mole fraction of i) 990 ! so P_i = gamma_i*X_i*P_pure_i 991 ! if ideal solution, gamma_i=1, P_i = X_i*P_pure_i 992 993 ! h2so4 weight precent 994 wph2so4_out = 9800.*sulfmolal/(98.*sulfmolal+1000.) 995 ! print*,rh,pph2o,psh2o(T),vpice(T) 996 ! print*,T,aw,sulfmolal,wph2so4_out 997 wph2so4_out = max(wph2so4_out,15.) 998 wph2so4_out = min(wph2so4_out,99.999) 999 1000 return 1001 end function wph2so4 1002 !----------------------------------------------------------------------- 1003 real function solh2so4(T,xa) result(solh2so4_out) 1004 ! equilibrium h2so4 number density over H2SO4/H2O solution (molec/cm3) 1005 1006 implicit none 1007 real, intent(in) :: T, xa ! T(K) xa(H2SO4 mass fraction) 1008 1009 real :: xw, a12,b12, cacta, presat 1010 1011 xw=1.0-xa 1012 1013 ! pure h2so4 saturation number density (molec/cm3) 1014 presat=ndsh2so4(T) 1015 ! compute activity of acid 1016 a12=5.672E3 -4.074E6/T +4.421E8/(T*T) 1017 b12=1./0.527 1018 cacta=10.**(a12*xw*xw/(xw+b12*xa)**2/T) 1019 ! h2so4 saturation number density over H2SO4/H2O solution (molec/cm3) 1020 solh2so4_out=cacta*xa*presat 1021 1022 return 1023 end function solh2so4 1024 !----------------------------------------------------------------------- 1025 real function rpmvh2so4(T,ws) result(rpmvh2so4_out) 1026 ! partial molar volume of h2so4 in h2so4/h2o solution (cm3/mole) 1027 1028 implicit none 1029 real, intent(in) :: T, ws 1030 real, dimension(22),parameter :: x=(/ & 1031 & 2.393284E-02,-4.359335E-05,7.961181E-08,0.0,-0.198716351, & 1032 & 1.39564574E-03,-2.020633E-06,0.51684706,-3.0539E-03,4.505475E-06, & 1033 & -0.30119511,1.840408E-03,-2.7221253742E-06,-0.11331674116, & 1034 & 8.47763E-04,-1.22336185E-06,0.3455282,-2.2111E-03,3.503768245E-06, & 1035 & -0.2315332,1.60074E-03,-2.5827835E-06/) 1036 1037 real :: w 1038 1039 w=ws*0.01 1040 rpmvh2so4_out=x(5)+x(6)*T+x(7)*T*T+(x(8)+x(9)*T+x(10)*T*T)*w & 1041 +(x(11)+x(12)*T+x(13)*T*T)*w*w 1042 ! h2so4 partial molar volume in h2so4/h2o solution (cm3/mole) 1043 rpmvh2so4_out=rpmvh2so4_out*1000. 1044 1045 return 1046 end function rpmvh2so4 1047 !----------------------------------------------------------------------- 1048 real function rmvh2o(T) result(rmvh2o_out) 1049 ! molar volume of pure h2o (cm3/mole) 1050 1051 implicit none 1052 real, intent(in) :: T 1053 real, parameter :: x1=2.393284E-02,x2=-4.359335E-05,x3=7.961181E-08 1054 1055 ! 1000: L/mole -> cm3/mole 1056 ! pure h2o molar volume (cm3/mole) 1057 rmvh2o_out=(x1+x2*T+x3*T*T)*1000. 1058 1059 return 1060 end function rmvh2o 1061 ! 767 1062 END MODULE sulfate_aer_mod -
LMDZ6/branches/cirrus/libf/phylmd/StratAer/traccoag_mod.F90
r4769 r5202 9 9 presnivs, xlat, xlon, pphis, pphi, & 10 10 t_seri, pplay, paprs, sh, rh, tr_seri) 11 11 12 12 USE phys_local_var_mod, ONLY: mdw, R2SO4, DENSO4, f_r_wet, surf_PM25_sulf, & 13 & budg_emi_ocs, budg_emi_so2, budg_emi_h2so4, budg_emi_part 14 13 & budg_emi_ocs, budg_emi_so2, budg_emi_h2so4, budg_emi_part, & 14 & R2SO4B, DENSO4B, f_r_wetB, sulfmmr, SAD_sulfate, sulfmmr_mode, nd_mode, reff_sulfate 15 15 16 USE dimphy 16 17 USE infotrac_phy, ONLY : nbtr_bin, nbtr_sulgas, nbtr, id_SO2_strat … … 56 57 REAL :: m_aer_emiss_vol_daily ! daily injection mass emission 57 58 REAL :: m_aer ! aerosol mass 58 INTEGER :: it, k, i, ilon, ilev, itime, i_int, ieru59 INTEGER :: it, k, i, j, ilon, ilev, itime, i_int, ieru 59 60 LOGICAL,DIMENSION(klon,klev) :: is_strato ! true = above tropopause, false = below 60 61 REAL,DIMENSION(klon,klev) :: m_air_gridbox ! mass of air in every grid box [kg] … … 82 83 INTEGER :: injdur_sai ! injection duration for SAI case [days] 83 84 INTEGER :: yr, is_bissext 85 REAL :: samoment2, samoment3! 2nd and 3rd order moments of size distribution 84 86 85 87 IF (is_mpi_root .AND. flag_verbose_strataer) THEN … … 88 90 ENDIF 89 91 92 ! radius [m] 90 93 DO it=1, nbtr_bin 91 94 r_bin(it)=mdw(it)/2. … … 117 120 118 121 IF(flag_new_strat_compo) THEN 119 IF(debutphy) WRITE(lunout,*) 'traccoag: USE STRAT COMPO from Tabazadeh 1994', flag_new_strat_compo 120 ! STRACOMP (H2O, P, t_seri -> aerosol composition (R2SO4)) : binary routine (from reprobus) 121 ! H2SO4 mass fraction in aerosol (%) from Tabazadeh et al. (1994). 122 CALL stracomp_bin(sh,t_seri,pplay) 123 124 ! aerosol density (gr/cm3) - from Tabazadeh 125 CALL denh2sa_taba(t_seri) 122 IF(debutphy) WRITE(lunout,*) 'traccoag: COMPO/DENSITY (Tabazadeh 97) + H2O kelvin effect', flag_new_strat_compo 123 ! STRACOMP (H2O, P, t_seri, R -> R2SO4 + Kelvin effect) : Taba97, Socol, etc... 124 CALL stracomp_kelvin(sh,t_seri,pplay) 126 125 ELSE 127 IF(debutphy) WRITE(lunout,*) 'traccoag: USE STRATCOMPO from Bekki 2D model', flag_new_strat_compo126 IF(debutphy) WRITE(lunout,*) 'traccoag: COMPO from Bekki 2D model', flag_new_strat_compo 128 127 ! STRACOMP (H2O, P, t_seri -> aerosol composition (R2SO4)) 129 128 ! H2SO4 mass fraction in aerosol (%) … … 132 131 ! aerosol density (gr/cm3) 133 132 CALL denh2sa(t_seri) 133 134 ! compute factor for converting dry to wet radius (for every grid box) 135 f_r_wet(:,:) = (dens_aer_dry/(DENSO4(:,:)*1000.)/(R2SO4(:,:)/100.))**(1./3.) 134 136 ENDIF 135 137 136 ! compute factor for converting dry to wet radius (for every grid box)137 f_r_wet(:,:) = (dens_aer_dry/(DENSO4(:,:)*1000.)/(R2SO4(:,:)/100.))**(1./3.)138 139 138 !--calculate mass of air in every grid box 140 139 DO ilon=1, klon … … 348 347 ENDDO 349 348 349 !--compute 350 ! sulfmmr: Sulfate aerosol concentration (dry mixing ratio) (condensed H2SO4 mmr) 351 ! SAD_sulfate: SAD all aerosols (cm2/cm3) (must be WET) 352 ! sulfmmr_mode: sulfate(=H2SO4 if dry) MMR in different modes (ambiguous but based on sulfmmr, it mus be DRY(?) mmr) 353 ! nd_mode: DRY(?) particle concentration in different modes (part/m3) 354 sulfmmr(:,:)=0.0 355 SAD_sulfate(:,:)=0.0 356 sulfmmr_mode(:,:,:)=0.0 357 nd_mode(:,:,:)=0.0 358 reff_sulfate(:,:)=0.0 359 360 DO i=1,klon 361 DO j=1,klev 362 samoment2=0.0 363 samoment3=0.0 364 DO it=1, nbtr_bin 365 !surf_PM25_sulf(i)=surf_PM25_sulf(i)+tr_seri(i,1,it+nbtr_sulgas)*m_part(i,1,it) & 366 !assume that particles consist of ammonium sulfate at the surface (132g/mol) 367 !and are dry at T = 20 deg. C and 50 perc. humidity 368 369 ! sulfmmr_mode: sulfate(=H2SO4 if dry) MMR in different modes (based on sulfmmr, it must be DRY mmr) 370 ! equivalent to condensed H2SO4 mmr= H2SO4 kg / kgA in bin it 371 sulfmmr_mode(i,j,it) = tr_seri(i,j,it+nbtr_sulgas) & ! [DRY part/kgA in bin it] 372 & *(4./3.)*RPI*(mdw(it)/2.)**3. & ! [mdw: dry diameter in m] 373 & *dens_aer_dry ! [dry aerosol mass density in kg/m3] 374 375 ! sulfmmr: Sulfate aerosol concentration (dry mass mixing ratio) 376 ! equivalent to total condensed H2SO4 mmr (H2SO4 kg / kgA 377 sulfmmr(i,j) = sulfmmr(i,j) + sulfmmr_mode(i,j,it) 378 379 ! nd_mode: particle concentration in different modes (DRY part/m3) 380 nd_mode(i,j,it) = tr_seri(i,j,it+nbtr_sulgas) & ! [DRY part/kgA in bin it] 381 & *pplay(i,j)/t_seri(i,j)/RD ! [air mass concentration in kg air /m3A] 382 383 IF(flag_new_strat_compo) THEN 384 ! SAD_sulfate: SAD WET sulfate aerosols (cm2/cm3) 385 SAD_sulfate(i,j) = SAD_sulfate(i,j) + nd_mode(i,j,it) & ! [DRY part/m3A (in bin it)] 386 & *4.*RPI*( mdw(it)*f_r_wetB(i,j,it)/2. )**2. & ! [WET SA of part it in m2] 387 & *1.e-2 ! conversion from m2/m3 to cm2/cm3A 388 ! samoment2 : 2nd order moment of WET sulfate aerosols (m2/m3) 389 samoment2 = samoment2 + nd_mode(i,j,it) & ! [DRY part/m3A (in bin it)] 390 & *( mdw(it)*f_r_wetB(i,j,it)/2. )**2. ! [WET SA of part it in m2] 391 ! samoment3 : 3nd order moment of WET sulfate aerosols (cm2/cm3) 392 samoment3 = samoment3 + nd_mode(i,j,it) & ! [DRY part/m3A (in bin it)] 393 & *( mdw(it)*f_r_wetB(i,j,it)/2. )**3. ! [WET SA of part it in m2] 394 ELSE 395 ! SAD_sulfate: SAD WET sulfate aerosols (cm2/cm3) 396 SAD_sulfate(i,j) = SAD_sulfate(i,j) + nd_mode(i,j,it) & ! [DRY part/m3A (in bin it)] 397 & *4.*RPI*( mdw(it)*f_r_wet(i,j)/2. )**2. & ! [WET SA of part it in m2] 398 & *1.e-2 ! conversion from m2/m3 to cm2/cm3A 399 ! samoment2 : 2nd order moment of WET sulfate aerosols (m2/m3) 400 samoment2 = samoment2 + nd_mode(i,j,it) & ! [DRY part/m3A (in bin it)] 401 & *( mdw(it)*f_r_wet(i,j)/2. )**2. ! [WET SA of part it in m2] 402 ! samoment3 : 3nd order moment of WET sulfate aerosols (cm2/cm3) 403 samoment3 = samoment3 + nd_mode(i,j,it) & ! [DRY part/m3A (in bin it)] 404 & *( mdw(it)*f_r_wet(i,j)/2. )**3. ! [WET SA of part it in m2] 405 ENDIF 406 ENDDO 407 ! reff_sulfate: effective radius of WET sulfate aerosols (cm) 408 reff_sulfate(i,j) = (samoment3 / samoment2) & 409 & *1.e2 ! conversion from m to cm 410 ENDDO 411 ENDDO 412 350 413 END SUBROUTINE traccoag 351 414 -
LMDZ6/branches/cirrus/libf/phylmd/add_phys_tend_mod.F90
r4738 r5202 774 774 bilh_bnd = (-(rcw-rcpd)*t_seri(1,1) + rlvtt) * rain_lsc(1) & 775 775 & + (-(rcs-rcpd)*t_seri(1,1) + rlstt) * snow_lsc(1) 776 CASE("bs ") param776 CASE("bsss") param 777 777 bilq_bnd = - bs_fall(1) 778 778 bilh_bnd = (-(rcs-rcpd)*t_seri(1,1) + rlstt) * bs_fall(1) -
LMDZ6/branches/cirrus/libf/phylmd/cdrag_mod.F90
r4777 r5202 23 23 24 24 USE dimphy 25 USE coare_cp_mod, ONLY: coare_cp 26 USE coare30_flux_cnrm_mod, ONLY: coare30_flux_cnrm 25 27 USE indice_sol_mod 26 28 USE print_control_mod, ONLY: lunout, prt_level … … 341 343 LPWG = .false. 342 344 call ini_csts 343 call coare30_flux_cnrm(z_0m,t1(i),tsurf(i), q1(i), & 344 sqrt(zdu2),zgeop1(i)/RG,zgeop1(i)/RG,psol(i),qsurf(i),PQSAT, & 345 PSFTH,PFSTQ,PUSTAR,PCD,PCDN,PCH,PCE,PRI, & 346 PRESA,prain,pat1(i),z_0h, LPRECIP, LPWG, coeffs) 345 block 346 real, dimension(1) :: z0m_1d, z_0h_1d, sqrt_zdu2_1d, zgeop1_rg_1d ! convert scalar to 1D for call 347 z0m_1d = z0m 348 z_0h_1d = z0h 349 sqrt_zdu2_1d = sqrt(zdu2) 350 zgeop1_rg_1d=zgeop1(i)/RG 351 call coare30_flux_cnrm(z0m_1d,t1(i),tsurf(i), q1(i), & 352 sqrt_zdu2_1d,zgeop1_rg_1d,zgeop1_rg_1d,psol(i),qsurf(i),PQSAT, & 353 PSFTH,PFSTQ,PUSTAR,PCD,PCDN,PCH,PCE,PRI, & 354 PRESA,prain,pat1(i),z_0h_1d, LPRECIP, LPWG, coeffs) 355 356 end block 347 357 cdmm(i) = coeffs(1) 348 358 cdhh(i) = coeffs(2) -
LMDZ6/branches/cirrus/libf/phylmd/clesphys.h
r4951 r5202 110 110 LOGICAL :: ok_3Deffect 111 111 112 !OB flag to activate water mass fixer in physiq 113 LOGICAL :: ok_water_mass_fixer 114 112 115 COMMON/clesphys/ & 113 116 ! REAL FIRST … … 161 164 & , iflag_phytrac, ok_new_lscp, ok_bs, ok_rad_bs & 162 165 & , iflag_thermals,nsplit_thermals, tau_thermals & 163 & , iflag_physiq, ok_3Deffect 166 & , iflag_physiq, ok_3Deffect, ok_water_mass_fixer 164 167 save /clesphys/ 165 168 !$OMP THREADPRIVATE(/clesphys/) -
LMDZ6/branches/cirrus/libf/phylmd/ecrad/lmdz/calcul_cloud_overlap_decorr_len.F90
r4911 r5202 146 146 ! ENDIF 147 147 ENDIF 148 CALL writefield_phy('latitude',latitude_deg,1)149 CALL writefield_phy('pressure_hl',pressure_hl,klev+1)150 CALL writefield_phy('Ldecorel',PDECORR_LEN_EDGES_M,klev)148 !CALL writefield_phy('latitude',latitude_deg,1) 149 !CALL writefield_phy('pressure_hl',pressure_hl,klev+1) 150 !CALL writefield_phy('Ldecorel',PDECORR_LEN_EDGES_M,klev) 151 151 ! ------------------------------------------------------------------- 152 152 -
LMDZ6/branches/cirrus/libf/phylmd/ecrad/lmdz/radiation_setup.F90
r4867 r5202 141 141 & -9, & 142 142 & 4 /) 143 ! rad_config%aerosol_optics_override_file_name = 'aerosol_optics_lmdz.nc'144 143 145 144 -
LMDZ6/branches/cirrus/libf/phylmd/ecrad/lmdz/readaerosol_optic_ecrad.F90
r4853 r5202 4 4 flag_aerosol, flag_bc_internal_mixture, itap, rjourvrai, & 5 5 pdtphys, pplay, paprs, t_seri, rhcl, presnivs, & 6 tr_seri, mass_solu_aero, mass_solu_aero_pi )6 tr_seri, mass_solu_aero, mass_solu_aero_pi, m_allaer) 7 7 ! tau_aero, piz_aero, cg_aero, & 8 8 ! tausum_aero, drytausum_aero, tau3d_aero ) … … 18 18 concso4,concno3,concoa,concbc,concss,concdust,loadso4,loadoa,loadbc,loadss,loaddust, & 19 19 loadno3,load_tmp1,load_tmp2,load_tmp3,load_tmp4,load_tmp5,load_tmp6,load_tmp7, & 20 load_tmp8,load_tmp9,load_tmp10 ,m_allaer20 load_tmp8,load_tmp9,load_tmp10 21 21 22 22 USE infotrac_phy, ONLY: tracers, nqtot, nbtr … … 49 49 REAL, DIMENSION(klon,klev), INTENT(OUT) :: mass_solu_aero ! Total mass for all soluble aerosols 50 50 REAL, DIMENSION(klon,klev), INTENT(OUT) :: mass_solu_aero_pi ! -"- preindustrial values 51 REAL, DIMENSION(klon,klev,naero_tot), INTENT(OUT) :: m_allaer 52 ! AI a passer par la suite en argument si besoin pour ecrad 53 !REAL, DIMENSION(klon,klev,naero_tot), INTENT(OUT) :: m_allaer_pi !RAF 54 51 55 ! REAL, DIMENSION(klon,klev,2,NSW), INTENT(OUT) :: tau_aero ! Aerosol optical thickness 52 56 ! REAL, DIMENSION(klon,klev,2,NSW), INTENT(OUT) :: piz_aero ! Single scattering albedo aerosol … … 86 90 REAL, DIMENSION(klon,klev) :: nitrinscoarse_pi 87 91 REAL, DIMENSION(klon,klev) :: pdel, zrho 88 ! REAL, DIMENSION(klon,klev,naero_tot) :: m_allaer 89 REAL, DIMENSION(klon,klev,naero_tot) :: m_allaer_pi !RAF 92 REAL, DIMENSION(klon,klev,naero_tot) :: m_allaer_pi 90 93 91 94 integer :: id_ASBCM, id_ASPOMM, id_ASSO4M, id_ASMSAM, id_CSSO4M, id_CSMSAM, id_SSSSM -
LMDZ6/branches/cirrus/libf/phylmd/ecrad/radiation/radiation_mcica_lw.F90
r4853 r5202 18 18 ! 2017-07-12 R. Hogan Call fast adding method if only clouds scatter 19 19 ! 2017-10-23 R. Hogan Renamed single-character variables 20 21 #include "ecrad_config.h"22 20 23 21 module radiation_mcica_lw … … 126 124 ! Identify clear-sky layers 127 125 logical :: is_clear_sky_layer(nlev) 128 129 ! Temporary storage for more efficient summation130 #ifdef DWD_REDUCTION_OPTIMIZATIONS131 real(jprb), dimension(nlev+1,2) :: sum_aux132 #else133 real(jprb) :: sum_up, sum_dn134 #endif135 126 136 127 ! Index of the highest cloudy layer … … 188 179 189 180 ! Sum over g-points to compute broadband fluxes 190 #ifdef DWD_REDUCTION_OPTIMIZATIONS 191 sum_aux(:,:) = 0.0_jprb 192 do jg = 1,ng 193 do jlev = 1,nlev+1 194 sum_aux(jlev,1) = sum_aux(jlev,1) + flux_up_clear(jg,jlev) 195 sum_aux(jlev,2) = sum_aux(jlev,2) + flux_dn_clear(jg,jlev) 196 end do 197 end do 198 flux%lw_up_clear(jcol,:) = sum_aux(:,1) 199 flux%lw_dn_clear(jcol,:) = sum_aux(:,2) 200 #else 201 do jlev = 1,nlev+1 202 sum_up = 0.0_jprb 203 sum_dn = 0.0_jprb 204 !$omp simd reduction(+:sum_up, sum_dn) 205 do jg = 1,ng 206 sum_up = sum_up + flux_up_clear(jg,jlev) 207 sum_dn = sum_dn + flux_dn_clear(jg,jlev) 208 end do 209 flux%lw_up_clear(jcol,jlev) = sum_up 210 flux%lw_dn_clear(jcol,jlev) = sum_dn 211 end do 212 #endif 213 181 flux%lw_up_clear(jcol,:) = sum(flux_up_clear,1) 182 flux%lw_dn_clear(jcol,:) = sum(flux_dn_clear,1) 214 183 ! Store surface spectral downwelling fluxes 215 184 flux%lw_dn_surf_clear_g(:,jcol) = flux_dn_clear(:,nlev+1) … … 310 279 else 311 280 ! Clear-sky layer: copy over clear-sky values 312 do jg = 1,ng 313 reflectance(jg,jlev) = ref_clear(jg,jlev) 314 transmittance(jg,jlev) = trans_clear(jg,jlev) 315 source_up(jg,jlev) = source_up_clear(jg,jlev) 316 source_dn(jg,jlev) = source_dn_clear(jg,jlev) 317 end do 281 reflectance(:,jlev) = ref_clear(:,jlev) 282 transmittance(:,jlev) = trans_clear(:,jlev) 283 source_up(:,jlev) = source_up_clear(:,jlev) 284 source_dn(:,jlev) = source_dn_clear(:,jlev) 318 285 end if 319 286 end do … … 340 307 341 308 ! Store overcast broadband fluxes 342 #ifdef DWD_REDUCTION_OPTIMIZATIONS 343 sum_aux(:,:) = 0._jprb 344 do jg = 1, ng 345 do jlev = 1, nlev+1 346 sum_aux(jlev,1) = sum_aux(jlev,1) + flux_up(jg,jlev) 347 sum_aux(jlev,2) = sum_aux(jlev,2) + flux_dn(jg,jlev) 348 end do 349 end do 350 flux%lw_up(jcol,:) = sum_aux(:,1) 351 flux%lw_dn(jcol,:) = sum_aux(:,2) 352 #else 353 do jlev = 1,nlev+1 354 sum_up = 0.0_jprb 355 sum_dn = 0.0_jprb 356 !$omp simd reduction(+:sum_up, sum_dn) 357 do jg = 1,ng 358 sum_up = sum_up + flux_up(jg,jlev) 359 sum_dn = sum_dn + flux_dn(jg,jlev) 360 end do 361 flux%lw_up(jcol,jlev) = sum_up 362 flux%lw_dn(jcol,jlev) = sum_dn 363 end do 364 #endif 309 flux%lw_up(jcol,:) = sum(flux_up,1) 310 flux%lw_dn(jcol,:) = sum(flux_dn,1) 365 311 366 312 ! Cloudy flux profiles currently assume completely overcast 367 313 ! skies; perform weighted average with clear-sky profile 368 do jlev = 1,nlev+1 369 flux%lw_up(jcol,jlev) = total_cloud_cover *flux%lw_up(jcol,jlev) & 370 & + (1.0_jprb - total_cloud_cover)*flux%lw_up_clear(jcol,jlev) 371 flux%lw_dn(jcol,jlev) = total_cloud_cover *flux%lw_dn(jcol,jlev) & 372 & + (1.0_jprb - total_cloud_cover)*flux%lw_dn_clear(jcol,jlev) 373 end do 314 flux%lw_up(jcol,:) = total_cloud_cover *flux%lw_up(jcol,:) & 315 & + (1.0_jprb - total_cloud_cover)*flux%lw_up_clear(jcol,:) 316 flux%lw_dn(jcol,:) = total_cloud_cover *flux%lw_dn(jcol,:) & 317 & + (1.0_jprb - total_cloud_cover)*flux%lw_dn_clear(jcol,:) 374 318 ! Store surface spectral downwelling fluxes 375 319 flux%lw_dn_surf_g(:,jcol) = total_cloud_cover*flux_dn(:,nlev+1) & … … 391 335 ! No cloud in profile and clear-sky fluxes already 392 336 ! calculated: copy them over 393 do jlev = 1,nlev+1 394 flux%lw_up(jcol,jlev) = flux%lw_up_clear(jcol,jlev) 395 flux%lw_dn(jcol,jlev) = flux%lw_dn_clear(jcol,jlev) 396 end do 337 flux%lw_up(jcol,:) = flux%lw_up_clear(jcol,:) 338 flux%lw_dn(jcol,:) = flux%lw_dn_clear(jcol,:) 397 339 flux%lw_dn_surf_g(:,jcol) = flux%lw_dn_surf_clear_g(:,jcol) 398 340 if (config%do_lw_derivatives) then -
LMDZ6/branches/cirrus/libf/phylmd/ecrad/radiation/radiation_mcica_sw.F90
r4853 r5202 17 17 ! 2017-04-22 R. Hogan Store surface fluxes at all g-points 18 18 ! 2017-10-23 R. Hogan Renamed single-character variables 19 20 #include "ecrad_config.h"21 19 22 20 module radiation_mcica_sw … … 121 119 ! Total cloud cover output from the cloud generator 122 120 real(jprb) :: total_cloud_cover 123 124 ! Temporary storage for more efficient summation125 #ifdef DWD_REDUCTION_OPTIMIZATIONS126 real(jprb), dimension(nlev+1,3) :: sum_aux127 #else128 real(jprb) :: sum_up, sum_dn_diff, sum_dn_dir129 #endif130 121 131 122 ! Number of g points … … 184 175 185 176 ! Sum over g-points to compute and save clear-sky broadband 186 ! fluxes. Note that the built-in "sum" function is very slow, 187 ! and before being replaced by the alternatives below 188 ! accounted for around 40% of the total cost of this routine. 189 #ifdef DWD_REDUCTION_OPTIMIZATIONS 190 ! Optimized summation for the NEC architecture 191 sum_aux(:,:) = 0.0_jprb 192 do jg = 1,ng 193 do jlev = 1,nlev+1 194 sum_aux(jlev,1) = sum_aux(jlev,1) + flux_up(jg,jlev) 195 sum_aux(jlev,2) = sum_aux(jlev,2) + flux_dn_direct(jg,jlev) 196 sum_aux(jlev,3) = sum_aux(jlev,3) + flux_dn_diffuse(jg,jlev) 197 end do 198 end do 199 flux%sw_up_clear(jcol,:) = sum_aux(:,1) 200 flux%sw_dn_clear(jcol,:) = sum_aux(:,2) + sum_aux(:,3) 177 ! fluxes 178 flux%sw_up_clear(jcol,:) = sum(flux_up,1) 201 179 if (allocated(flux%sw_dn_direct_clear)) then 202 flux%sw_dn_direct_clear(jcol,:) = sum_aux(:,2) 180 flux%sw_dn_direct_clear(jcol,:) & 181 & = sum(flux_dn_direct,1) 182 flux%sw_dn_clear(jcol,:) = sum(flux_dn_diffuse,1) & 183 & + flux%sw_dn_direct_clear(jcol,:) 184 else 185 flux%sw_dn_clear(jcol,:) = sum(flux_dn_diffuse,1) & 186 & + sum(flux_dn_direct,1) 203 187 end if 204 #else205 ! Optimized summation for the x86-64 architecture206 do jlev = 1,nlev+1207 sum_up = 0.0_jprb208 sum_dn_diff = 0.0_jprb209 sum_dn_dir = 0.0_jprb210 !$omp simd reduction(+:sum_up, sum_dn_diff, sum_dn_dir)211 do jg = 1,ng212 sum_up = sum_up + flux_up(jg,jlev)213 sum_dn_diff = sum_dn_diff + flux_dn_diffuse(jg,jlev)214 sum_dn_dir = sum_dn_dir + flux_dn_direct(jg,jlev)215 end do216 flux%sw_up_clear(jcol,jlev) = sum_up217 flux%sw_dn_clear(jcol,jlev) = sum_dn_diff + sum_dn_dir218 if (allocated(flux%sw_dn_direct_clear)) then219 flux%sw_dn_direct_clear(jcol,jlev) = sum_dn_dir220 end if221 end do222 #endif223 224 188 ! Store spectral downwelling fluxes at surface 225 do jg = 1,ng 226 flux%sw_dn_diffuse_surf_clear_g(jg,jcol) = flux_dn_diffuse(jg,nlev+1) 227 flux%sw_dn_direct_surf_clear_g(jg,jcol) = flux_dn_direct(jg,nlev+1) 228 end do 189 flux%sw_dn_diffuse_surf_clear_g(:,jcol) = flux_dn_diffuse(:,nlev+1) 190 flux%sw_dn_direct_surf_clear_g(:,jcol) = flux_dn_direct(:,nlev+1) 229 191 230 192 ! Do cloudy-sky calculation … … 287 249 else 288 250 ! Clear-sky layer: copy over clear-sky values 289 do jg = 1,ng 290 reflectance(jg,jlev) = ref_clear(jg,jlev) 291 transmittance(jg,jlev) = trans_clear(jg,jlev) 292 ref_dir(jg,jlev) = ref_dir_clear(jg,jlev) 293 trans_dir_diff(jg,jlev) = trans_dir_diff_clear(jg,jlev) 294 trans_dir_dir(jg,jlev) = trans_dir_dir_clear(jg,jlev) 295 end do 251 reflectance(:,jlev) = ref_clear(:,jlev) 252 transmittance(:,jlev) = trans_clear(:,jlev) 253 ref_dir(:,jlev) = ref_dir_clear(:,jlev) 254 trans_dir_diff(:,jlev) = trans_dir_diff_clear(:,jlev) 255 trans_dir_dir(:,jlev) = trans_dir_dir_clear(:,jlev) 296 256 end if 297 257 end do … … 304 264 305 265 ! Store overcast broadband fluxes 306 #ifdef DWD_REDUCTION_OPTIMIZATIONS 307 sum_aux(:,:) = 0.0_jprb 308 do jg = 1,ng 309 do jlev = 1,nlev+1 310 sum_aux(jlev,1) = sum_aux(jlev,1) + flux_up(jg,jlev) 311 sum_aux(jlev,2) = sum_aux(jlev,2) + flux_dn_direct(jg,jlev) 312 sum_aux(jlev,3) = sum_aux(jlev,3) + flux_dn_diffuse(jg,jlev) 313 end do 314 end do 315 flux%sw_up(jcol,:) = sum_aux(:,1) 316 flux%sw_dn(jcol,:) = sum_aux(:,2) + sum_aux(:,3) 266 flux%sw_up(jcol,:) = sum(flux_up,1) 317 267 if (allocated(flux%sw_dn_direct)) then 318 flux%sw_dn_direct(jcol,:) = sum_aux(:,2) 268 flux%sw_dn_direct(jcol,:) = sum(flux_dn_direct,1) 269 flux%sw_dn(jcol,:) = sum(flux_dn_diffuse,1) & 270 & + flux%sw_dn_direct(jcol,:) 271 else 272 flux%sw_dn(jcol,:) = sum(flux_dn_diffuse,1) & 273 & + sum(flux_dn_direct,1) 319 274 end if 320 #else 321 do jlev = 1,nlev+1 322 sum_up = 0.0_jprb 323 sum_dn_diff = 0.0_jprb 324 sum_dn_dir = 0.0_jprb 325 !$omp simd reduction(+:sum_up, sum_dn_diff, sum_dn_dir) 326 do jg = 1,ng 327 sum_up = sum_up + flux_up(jg,jlev) 328 sum_dn_diff = sum_dn_diff + flux_dn_diffuse(jg,jlev) 329 sum_dn_dir = sum_dn_dir + flux_dn_direct(jg,jlev) 330 end do 331 flux%sw_up(jcol,jlev) = sum_up 332 flux%sw_dn(jcol,jlev) = sum_dn_diff + sum_dn_dir 333 if (allocated(flux%sw_dn_direct)) then 334 flux%sw_dn_direct(jcol,jlev) = sum_dn_dir 335 end if 336 end do 337 #endif 338 275 339 276 ! Cloudy flux profiles currently assume completely overcast 340 277 ! skies; perform weighted average with clear-sky profile 341 do jlev = 1, nlev+1 342 flux%sw_up(jcol,jlev) = total_cloud_cover *flux%sw_up(jcol,jlev) & 343 & + (1.0_jprb - total_cloud_cover)*flux%sw_up_clear(jcol,jlev) 344 flux%sw_dn(jcol,jlev) = total_cloud_cover *flux%sw_dn(jcol,jlev) & 345 & + (1.0_jprb - total_cloud_cover)*flux%sw_dn_clear(jcol,jlev) 346 if (allocated(flux%sw_dn_direct)) then 347 flux%sw_dn_direct(jcol,jlev) = total_cloud_cover *flux%sw_dn_direct(jcol,jlev) & 348 & + (1.0_jprb - total_cloud_cover)*flux%sw_dn_direct_clear(jcol,jlev) 349 end if 350 end do 278 flux%sw_up(jcol,:) = total_cloud_cover *flux%sw_up(jcol,:) & 279 & + (1.0_jprb - total_cloud_cover)*flux%sw_up_clear(jcol,:) 280 flux%sw_dn(jcol,:) = total_cloud_cover *flux%sw_dn(jcol,:) & 281 & + (1.0_jprb - total_cloud_cover)*flux%sw_dn_clear(jcol,:) 282 if (allocated(flux%sw_dn_direct)) then 283 flux%sw_dn_direct(jcol,:) = total_cloud_cover *flux%sw_dn_direct(jcol,:) & 284 & + (1.0_jprb - total_cloud_cover)*flux%sw_dn_direct_clear(jcol,:) 285 end if 351 286 ! Likewise for surface spectral fluxes 352 do jg = 1,ng 353 flux%sw_dn_diffuse_surf_g(jg,jcol) = flux_dn_diffuse(jg,nlev+1) 354 flux%sw_dn_direct_surf_g(jg,jcol) = flux_dn_direct(jg,nlev+1) 355 flux%sw_dn_diffuse_surf_g(jg,jcol) = total_cloud_cover *flux%sw_dn_diffuse_surf_g(jg,jcol) & 356 & + (1.0_jprb - total_cloud_cover)*flux%sw_dn_diffuse_surf_clear_g(jg,jcol) 357 flux%sw_dn_direct_surf_g(jg,jcol) = total_cloud_cover *flux%sw_dn_direct_surf_g(jg,jcol) & 358 & + (1.0_jprb - total_cloud_cover)*flux%sw_dn_direct_surf_clear_g(jg,jcol) 359 end do 360 287 flux%sw_dn_diffuse_surf_g(:,jcol) = flux_dn_diffuse(:,nlev+1) 288 flux%sw_dn_direct_surf_g(:,jcol) = flux_dn_direct(:,nlev+1) 289 flux%sw_dn_diffuse_surf_g(:,jcol) = total_cloud_cover *flux%sw_dn_diffuse_surf_g(:,jcol) & 290 & + (1.0_jprb - total_cloud_cover)*flux%sw_dn_diffuse_surf_clear_g(:,jcol) 291 flux%sw_dn_direct_surf_g(:,jcol) = total_cloud_cover *flux%sw_dn_direct_surf_g(:,jcol) & 292 & + (1.0_jprb - total_cloud_cover)*flux%sw_dn_direct_surf_clear_g(:,jcol) 293 361 294 else 362 295 ! No cloud in profile and clear-sky fluxes already 363 296 ! calculated: copy them over 364 do jlev = 1, nlev+1 365 flux%sw_up(jcol,jlev) = flux%sw_up_clear(jcol,jlev) 366 flux%sw_dn(jcol,jlev) = flux%sw_dn_clear(jcol,jlev) 367 if (allocated(flux%sw_dn_direct)) then 368 flux%sw_dn_direct(jcol,jlev) = flux%sw_dn_direct_clear(jcol,jlev) 369 end if 370 end do 371 do jg = 1,ng 372 flux%sw_dn_diffuse_surf_g(jg,jcol) = flux%sw_dn_diffuse_surf_clear_g(jg,jcol) 373 flux%sw_dn_direct_surf_g(jg,jcol) = flux%sw_dn_direct_surf_clear_g(jg,jcol) 374 end do 297 flux%sw_up(jcol,:) = flux%sw_up_clear(jcol,:) 298 flux%sw_dn(jcol,:) = flux%sw_dn_clear(jcol,:) 299 if (allocated(flux%sw_dn_direct)) then 300 flux%sw_dn_direct(jcol,:) = flux%sw_dn_direct_clear(jcol,:) 301 end if 302 flux%sw_dn_diffuse_surf_g(:,jcol) = flux%sw_dn_diffuse_surf_clear_g(:,jcol) 303 flux%sw_dn_direct_surf_g(:,jcol) = flux%sw_dn_direct_surf_clear_g(:,jcol) 375 304 376 305 end if ! Cloud is present in profile … … 378 307 else 379 308 ! Set fluxes to zero if sun is below the horizon 380 do jlev = 1, nlev+1 381 flux%sw_up(jcol,jlev) = 0.0_jprb 382 flux%sw_dn(jcol,jlev) = 0.0_jprb 383 if (allocated(flux%sw_dn_direct)) then 384 flux%sw_dn_direct(jcol,jlev) = 0.0_jprb 385 end if 386 flux%sw_up_clear(jcol,jlev) = 0.0_jprb 387 flux%sw_dn_clear(jcol,jlev) = 0.0_jprb 388 if (allocated(flux%sw_dn_direct_clear)) then 389 flux%sw_dn_direct_clear(jcol,jlev) = 0.0_jprb 390 end if 391 end do 392 do jg = 1,ng 393 flux%sw_dn_diffuse_surf_g(jg,jcol) = 0.0_jprb 394 flux%sw_dn_direct_surf_g(jg,jcol) = 0.0_jprb 395 flux%sw_dn_diffuse_surf_clear_g(jg,jcol) = 0.0_jprb 396 flux%sw_dn_direct_surf_clear_g(jg,jcol) = 0.0_jprb 397 end do 309 flux%sw_up(jcol,:) = 0.0_jprb 310 flux%sw_dn(jcol,:) = 0.0_jprb 311 if (allocated(flux%sw_dn_direct)) then 312 flux%sw_dn_direct(jcol,:) = 0.0_jprb 313 end if 314 flux%sw_up_clear(jcol,:) = 0.0_jprb 315 flux%sw_dn_clear(jcol,:) = 0.0_jprb 316 if (allocated(flux%sw_dn_direct_clear)) then 317 flux%sw_dn_direct_clear(jcol,:) = 0.0_jprb 318 end if 319 flux%sw_dn_diffuse_surf_g(:,jcol) = 0.0_jprb 320 flux%sw_dn_direct_surf_g(:,jcol) = 0.0_jprb 321 flux%sw_dn_diffuse_surf_clear_g(:,jcol) = 0.0_jprb 322 flux%sw_dn_direct_surf_clear_g(:,jcol) = 0.0_jprb 398 323 end if ! Sun above horizon 399 324 -
LMDZ6/branches/cirrus/libf/phylmd/ecrad/radiation/radiation_tripleclouds_lw.F90
r4853 r5202 170 170 logical :: is_clear_sky_layer(0:nlev+1) 171 171 172 ! Temporaries to speed up summations173 real(jprb) :: sum_dn, sum_up174 175 172 ! Index of the highest cloudy layer 176 173 integer :: i_cloud_top … … 264 261 if (config%do_clear) then 265 262 ! Sum over g-points to compute broadband fluxes 266 do jlev = 1,nlev+1 267 sum_up = 0.0_jprb 268 sum_dn = 0.0_jprb 269 !$omp simd reduction(+:sum_up, sum_dn) 270 do jg = 1,ng 271 sum_up = sum_up + flux_up_clear(jg,jlev) 272 sum_dn = sum_dn + flux_dn_clear(jg,jlev) 273 end do 274 flux%lw_up_clear(jcol,jlev) = sum_up 275 flux%lw_dn_clear(jcol,jlev) = sum_dn 276 end do 277 263 flux%lw_up_clear(jcol,:) = sum(flux_up_clear,1) 264 flux%lw_dn_clear(jcol,:) = sum(flux_dn_clear,1) 278 265 ! Store surface spectral downwelling fluxes / TOA upwelling 279 do jg = 1,ng 280 flux%lw_dn_surf_clear_g(jg,jcol) = flux_dn_clear(jg,nlev+1) 281 flux%lw_up_toa_clear_g (jg,jcol) = flux_up_clear(jg,1) 282 end do 266 flux%lw_dn_surf_clear_g(:,jcol) = flux_dn_clear(:,nlev+1) 267 flux%lw_up_toa_clear_g (:,jcol) = flux_up_clear(:,1) 283 268 ! Save the spectral fluxes if required 284 269 if (config%do_save_spectral_flux) then … … 468 453 end if 469 454 else 470 sum_dn = 0.0_jprb 471 !$omp simd reduction(+:sum_dn) 472 do jg = 1,ng 473 sum_dn = sum_dn + flux_dn_clear(jg,jlev) 474 end do 475 flux%lw_dn(jcol,jlev) = sum_dn 455 flux%lw_dn(jcol,:) = sum(flux_dn_clear(:,jlev)) 476 456 if (config%do_save_spectral_flux) then 477 457 call indexed_sum(flux_dn_clear(:,jlev), & … … 490 470 & + total_albedo(:,1,i_cloud_top)*flux_dn_clear(:,i_cloud_top) 491 471 flux_up(:,2:) = 0.0_jprb 492 493 sum_up = 0.0_jprb 494 !$omp simd reduction(+:sum_up) 495 do jg = 1,ng 496 sum_up = sum_up + flux_up(jg,1) 497 end do 498 flux%lw_up(jcol,i_cloud_top) = sum_up 499 472 flux%lw_up(jcol,i_cloud_top) = sum(flux_up(:,1)) 500 473 if (config%do_save_spectral_flux) then 501 474 call indexed_sum(flux_up(:,1), & … … 505 478 do jlev = i_cloud_top-1,1,-1 506 479 flux_up(:,1) = trans_clear(:,jlev)*flux_up(:,1) + source_up_clear(:,jlev) 507 sum_up = 0.0_jprb 508 !$omp simd reduction(+:sum_up) 509 do jg = 1,ng 510 sum_up = sum_up + flux_up(jg,1) 511 end do 512 flux%lw_up(jcol,jlev) = sum_up 480 flux%lw_up(jcol,jlev) = sum(flux_up(:,1)) 513 481 if (config%do_save_spectral_flux) then 514 482 call indexed_sum(flux_up(:,1), & … … 560 528 561 529 ! Store the broadband fluxes 562 sum_up = 0.0_jprb 563 sum_dn = 0.0_jprb 564 do jreg = 1,nregions 565 !$omp simd reduction(+:sum_up, sum_dn) 566 do jg = 1,ng 567 sum_up = sum_up + flux_up(jg,jreg) 568 sum_dn = sum_dn + flux_dn(jg,jreg) 569 end do 570 end do 571 flux%lw_up(jcol,jlev+1) = sum_up 572 flux%lw_dn(jcol,jlev+1) = sum_dn 530 flux%lw_up(jcol,jlev+1) = sum(sum(flux_up,1)) 531 flux%lw_dn(jcol,jlev+1) = sum(sum(flux_dn,1)) 573 532 574 533 ! Save the spectral fluxes if required -
LMDZ6/branches/cirrus/libf/phylmd/ecrad/radiation/radiation_tripleclouds_lw.F90.or
r4773 r5202 170 170 logical :: is_clear_sky_layer(0:nlev+1) 171 171 172 ! Temporaries to speed up summations 173 real(jprb) :: sum_dn, sum_up 174 172 175 ! Index of the highest cloudy layer 173 176 integer :: i_cloud_top … … 249 252 call calc_ref_trans_lw(ng*nlev, & 250 253 & od(:,:,jcol), ssa(:,:,jcol), g(:,:,jcol), & 251 & planck_hl(:,1: jlev,jcol), planck_hl(:,2:jlev+1,jcol), &254 & planck_hl(:,1:nlev,jcol), planck_hl(:,2:nlev+1,jcol), & 252 255 & ref_clear, trans_clear, & 253 256 & source_up_clear, source_dn_clear) … … 261 264 if (config%do_clear) then 262 265 ! Sum over g-points to compute broadband fluxes 263 flux%lw_up_clear(jcol,:) = sum(flux_up_clear,1) 264 flux%lw_dn_clear(jcol,:) = sum(flux_dn_clear,1) 266 do jlev = 1,nlev+1 267 sum_up = 0.0_jprb 268 sum_dn = 0.0_jprb 269 !$omp simd reduction(+:sum_up, sum_dn) 270 do jg = 1,ng 271 sum_up = sum_up + flux_up_clear(jg,jlev) 272 sum_dn = sum_dn + flux_dn_clear(jg,jlev) 273 end do 274 flux%lw_up_clear(jcol,jlev) = sum_up 275 flux%lw_dn_clear(jcol,jlev) = sum_dn 276 end do 277 265 278 ! Store surface spectral downwelling fluxes / TOA upwelling 266 flux%lw_dn_surf_clear_g(:,jcol) = flux_dn_clear(:,nlev+1) 267 flux%lw_up_toa_clear_g (:,jcol) = flux_up_clear(:,1) 279 do jg = 1,ng 280 flux%lw_dn_surf_clear_g(jg,jcol) = flux_dn_clear(jg,nlev+1) 281 flux%lw_up_toa_clear_g (jg,jcol) = flux_up_clear(jg,1) 282 end do 268 283 ! Save the spectral fluxes if required 269 284 if (config%do_save_spectral_flux) then … … 453 468 end if 454 469 else 455 flux%lw_dn(jcol,:) = sum(flux_dn_clear(:,jlev)) 470 sum_dn = 0.0_jprb 471 !$omp simd reduction(+:sum_dn) 472 do jg = 1,ng 473 sum_dn = sum_dn + flux_dn_clear(jg,jlev) 474 end do 475 flux%lw_dn(jcol,jlev) = sum_dn 456 476 if (config%do_save_spectral_flux) then 457 477 call indexed_sum(flux_dn_clear(:,jlev), & … … 470 490 & + total_albedo(:,1,i_cloud_top)*flux_dn_clear(:,i_cloud_top) 471 491 flux_up(:,2:) = 0.0_jprb 472 flux%lw_up(jcol,i_cloud_top) = sum(flux_up(:,1)) 492 493 sum_up = 0.0_jprb 494 !$omp simd reduction(+:sum_up) 495 do jg = 1,ng 496 sum_up = sum_up + flux_up(jg,1) 497 end do 498 flux%lw_up(jcol,i_cloud_top) = sum_up 499 473 500 if (config%do_save_spectral_flux) then 474 501 call indexed_sum(flux_up(:,1), & … … 478 505 do jlev = i_cloud_top-1,1,-1 479 506 flux_up(:,1) = trans_clear(:,jlev)*flux_up(:,1) + source_up_clear(:,jlev) 480 flux%lw_up(jcol,jlev) = sum(flux_up(:,1)) 507 sum_up = 0.0_jprb 508 !$omp simd reduction(+:sum_up) 509 do jg = 1,ng 510 sum_up = sum_up + flux_up(jg,1) 511 end do 512 flux%lw_up(jcol,jlev) = sum_up 481 513 if (config%do_save_spectral_flux) then 482 514 call indexed_sum(flux_up(:,1), & … … 528 560 529 561 ! Store the broadband fluxes 530 flux%lw_up(jcol,jlev+1) = sum(sum(flux_up,1)) 531 flux%lw_dn(jcol,jlev+1) = sum(sum(flux_dn,1)) 562 sum_up = 0.0_jprb 563 sum_dn = 0.0_jprb 564 do jreg = 1,nregions 565 !$omp simd reduction(+:sum_up, sum_dn) 566 do jg = 1,ng 567 sum_up = sum_up + flux_up(jg,jreg) 568 sum_dn = sum_dn + flux_dn(jg,jreg) 569 end do 570 end do 571 flux%lw_up(jcol,jlev+1) = sum_up 572 flux%lw_dn(jcol,jlev+1) = sum_dn 532 573 533 574 ! Save the spectral fluxes if required -
LMDZ6/branches/cirrus/libf/phylmd/ecrad/radiation/radiation_tripleclouds_sw.F90
r4853 r5202 74 74 ! Gas and aerosol optical depth, single-scattering albedo and 75 75 ! asymmetry factor at each shortwave g-point 76 real(jprb), intent(in), dimension(config%n_g_sw,nlev,istartcol:iendcol) & 77 & :: od, ssa, g 76 ! real(jprb), intent(in), dimension(istartcol:iendcol,nlev,config%n_g_sw) :: & 77 real(jprb), intent(in), dimension(config%n_g_sw,nlev,istartcol:iendcol) :: & 78 & od, ssa, g 78 79 79 80 ! Cloud and precipitation optical depth, single-scattering albedo and 80 81 ! asymmetry factor in each shortwave band 81 real(jprb), intent(in), dimension(config%n_bands_sw,nlev,istartcol:iendcol) &82 & ::od_cloud, ssa_cloud, g_cloud82 real(jprb), intent(in), dimension(config%n_bands_sw,nlev,istartcol:iendcol) :: & 83 & od_cloud, ssa_cloud, g_cloud 83 84 84 85 ! Optical depth, single scattering albedo and asymmetry factor in … … 91 92 ! flux into a plane perpendicular to the incoming radiation at 92 93 ! top-of-atmosphere in each of the shortwave g points 93 real(jprb), intent(in), dimension(config%n_g_sw,istartcol:iendcol) &94 & ::albedo_direct, albedo_diffuse, incoming_sw94 real(jprb), intent(in), dimension(config%n_g_sw,istartcol:iendcol) :: & 95 & albedo_direct, albedo_diffuse, incoming_sw 95 96 96 97 ! Output … … 165 166 real(jprb) :: scat_od, scat_od_cloud 166 167 167 ! Temporaries to speed up summations168 real(jprb) :: sum_dn_diff, sum_dn_dir, sum_up169 170 ! Local cosine of solar zenith angle171 168 real(jprb) :: mu0 172 169 … … 447 444 end if 448 445 449 ! Store the TOA broadband fluxes, noting that there is no 450 ! diffuse downwelling at TOA. The intrinsic "sum" command has 451 ! been found to be very slow; better performance is found on 452 ! x86-64 architecture with explicit loops and the "omp simd 453 ! reduction" directive. 454 sum_up = 0.0_jprb 455 sum_dn_dir = 0.0_jprb 456 do jreg = 1,nregions 457 !$omp simd reduction(+:sum_up, sum_dn_dir) 458 do jg = 1,ng 459 sum_up = sum_up + flux_up(jg,jreg) 460 sum_dn_dir = sum_dn_dir + direct_dn(jg,jreg) 461 end do 462 end do 463 flux%sw_up(jcol,1) = sum_up 464 flux%sw_dn(jcol,1) = mu0 * sum_dn_dir 446 ! Store the TOA broadband fluxes 447 flux%sw_up(jcol,1) = sum(sum(flux_up,1)) 448 flux%sw_dn(jcol,1) = mu0 * sum(sum(direct_dn,1)) 465 449 if (allocated(flux%sw_dn_direct)) then 466 450 flux%sw_dn_direct(jcol,1) = flux%sw_dn(jcol,1) 467 451 end if 468 452 if (config%do_clear) then 469 sum_up = 0.0_jprb 470 sum_dn_dir = 0.0_jprb 471 !$omp simd reduction(+:sum_up, sum_dn_dir) 472 do jg = 1,ng 473 sum_up = sum_up + flux_up_clear(jg) 474 sum_dn_dir = sum_dn_dir + direct_dn_clear(jg) 475 end do 476 flux%sw_up_clear(jcol,1) = sum_up 477 flux%sw_dn_clear(jcol,1) = mu0 * sum_dn_dir 453 flux%sw_up_clear(jcol,1) = sum(flux_up_clear) 454 flux%sw_dn_clear(jcol,1) = mu0 * sum(direct_dn_clear) 478 455 if (allocated(flux%sw_dn_direct_clear)) then 479 456 flux%sw_dn_direct_clear(jcol,1) = flux%sw_dn_clear(jcol,1) … … 490 467 & config%i_spec_from_reordered_g_sw, & 491 468 & flux%sw_dn_band(:,jcol,1)) 492 flux%sw_dn_band(:,jcol,1) = mu0 * flux%sw_dn_band(:,jcol,1) 469 flux%sw_dn_band(:,jcol,1) = & 470 & mu0 * flux%sw_dn_band(:,jcol,1) 493 471 if (allocated(flux%sw_dn_direct_band)) then 494 472 flux%sw_dn_direct_band(:,jcol,1) = flux%sw_dn_band(:,jcol,1) … … 571 549 ! nothing to do 572 550 573 ! Store the broadband fluxes. The intrinsic "sum" command has 574 ! been found to be very slow; better performance is found on 575 ! x86-64 architecture with explicit loops and the "omp simd 576 ! reduction" directive. 577 sum_up = 0.0_jprb 578 sum_dn_dir = 0.0_jprb 579 sum_dn_diff = 0.0_jprb 580 do jreg = 1,nregions 581 !$omp simd reduction(+:sum_up, sum_dn_diff, sum_dn_dir) 582 do jg = 1,ng 583 sum_up = sum_up + flux_up(jg,jreg) 584 sum_dn_diff = sum_dn_diff + flux_dn(jg,jreg) 585 sum_dn_dir = sum_dn_dir + direct_dn(jg,jreg) 586 end do 587 end do 588 flux%sw_up(jcol,jlev+1) = sum_up 589 flux%sw_dn(jcol,jlev+1) = mu0 * sum_dn_dir + sum_dn_diff 551 ! Store the broadband fluxes 552 flux%sw_up(jcol,jlev+1) = sum(sum(flux_up,1)) 590 553 if (allocated(flux%sw_dn_direct)) then 591 flux%sw_dn_direct(jcol,jlev+1) = mu0 * sum_dn_dir 554 flux%sw_dn_direct(jcol,jlev+1) = mu0 * sum(sum(direct_dn,1)) 555 flux%sw_dn(jcol,jlev+1) & 556 & = flux%sw_dn_direct(jcol,jlev+1) + sum(sum(flux_dn,1)) 557 else 558 flux%sw_dn(jcol,jlev+1) = mu0 * sum(sum(direct_dn,1)) + sum(sum(flux_dn,1)) 592 559 end if 593 560 if (config%do_clear) then 594 sum_up = 0.0_jprb 595 sum_dn_dir = 0.0_jprb 596 sum_dn_diff = 0.0_jprb 597 !$omp simd reduction(+:sum_up, sum_dn_diff, sum_dn_dir) 598 do jg = 1,ng 599 sum_up = sum_up + flux_up_clear(jg) 600 sum_dn_diff = sum_dn_diff + flux_dn_clear(jg) 601 sum_dn_dir = sum_dn_dir + direct_dn_clear(jg) 602 end do 603 flux%sw_up_clear(jcol,jlev+1) = sum_up 604 flux%sw_dn_clear(jcol,jlev+1) = mu0 * sum_dn_dir + sum_dn_diff 561 flux%sw_up_clear(jcol,jlev+1) = sum(flux_up_clear) 605 562 if (allocated(flux%sw_dn_direct_clear)) then 606 flux%sw_dn_direct_clear(jcol,jlev+1) = mu0 * sum_dn_dir 563 flux%sw_dn_direct_clear(jcol,jlev+1) = mu0 * sum(direct_dn_clear) 564 flux%sw_dn_clear(jcol,jlev+1) & 565 & = flux%sw_dn_direct_clear(jcol,jlev+1) + sum(flux_dn_clear) 566 else 567 flux%sw_dn_clear(jcol,jlev+1) = mu0 * sum(direct_dn_clear) & 568 & + sum(flux_dn_clear) 607 569 end if 608 570 end if … … 643 605 end if 644 606 end if 607 645 608 end do ! Final loop over levels 646 609 -
LMDZ6/branches/cirrus/libf/phylmd/fonte_neige_mod.F90
r4523 r5202 36 36 REAL, ALLOCATABLE, DIMENSION(:) :: runofflic_global 37 37 !$OMP THREADPRIVATE(runofflic_global) 38 #ifdef ISO 39 REAL, ALLOCATABLE, DIMENSION(:,:), PRIVATE :: xtrun_off_ter 40 !$OMP THREADPRIVATE(xtrun_off_ter) 41 REAL, ALLOCATABLE, DIMENSION(:,:) :: xtrun_off_lic 42 !$OMP THREADPRIVATE(xtrun_off_lic) 43 REAL, ALLOCATABLE, DIMENSION(:,:), PRIVATE :: xtrun_off_lic_0 44 !$OMP THREADPRIVATE(xtrun_off_lic_0) 45 REAL, ALLOCATABLE, DIMENSION(:,:,:), PRIVATE:: fxtfonte_global 46 !$OMP THREADPRIVATE(fxtfonte_global) 47 REAL, ALLOCATABLE, DIMENSION(:,:,:), PRIVATE:: fxtcalving_global 48 !$OMP THREADPRIVATE(fxtcalving_global) 49 REAL, ALLOCATABLE, DIMENSION(:,:), PRIVATE :: xtrunofflic_global 50 !$OMP THREADPRIVATE(xtrunofflic_global) 51 #endif 38 52 39 53 CONTAINS … … 123 137 124 138 END SUBROUTINE fonte_neige_init 139 140 #ifdef ISO 141 SUBROUTINE fonte_neige_init_iso(xtrestart_runoff) 142 143 ! This subroutine allocates and initialize variables in the module. 144 ! The variable run_off_lic_0 is initialized to the field read from 145 ! restart file. The other variables are initialized to zero. 146 147 USE infotrac_phy, ONLY: niso 148 #ifdef ISOVERIF 149 USE isotopes_mod, ONLY: iso_eau,iso_HDO 150 USE isotopes_verif_mod 151 #endif 152 ! 153 !**************************************************************************************** 154 ! Input argument 155 REAL, DIMENSION(niso,klon), INTENT(IN) :: xtrestart_runoff 156 157 ! Local variables 158 INTEGER :: error 159 CHARACTER (len = 80) :: abort_message 160 CHARACTER (len = 20) :: modname = 'fonte_neige_init' 161 INTEGER :: i 162 163 164 !**************************************************************************************** 165 ! Allocate run-off at landice and initilize with field read from restart 166 ! 167 !**************************************************************************************** 168 169 ALLOCATE(xtrun_off_lic_0(niso,klon), stat = error) 170 IF (error /= 0) THEN 171 abort_message='Pb allocation run_off_lic' 172 CALL abort_gcm(modname,abort_message,1) 173 ENDIF 174 175 xtrun_off_lic_0(:,:) = xtrestart_runoff(:,:) 176 177 #ifdef ISOVERIF 178 IF (iso_eau > 0) THEN 179 CALL iso_verif_egalite_vect1D( & 180 & xtrun_off_lic_0,run_off_lic_0,'fonte_neige 100', & 181 & niso,klon) 182 ENDIF !IF (iso_eau > 0) THEN 183 #endif 184 185 !**************************************************************************************** 186 ! Allocate other variables and initilize to zero 187 ! 188 !**************************************************************************************** 189 190 ALLOCATE(xtrun_off_ter(niso,klon), stat = error) 191 IF (error /= 0) THEN 192 abort_message='Pb allocation xtrun_off_ter' 193 CALL abort_gcm(modname,abort_message,1) 194 ENDIF 195 xtrun_off_ter(:,:) = 0. 196 197 ALLOCATE(xtrun_off_lic(niso,klon), stat = error) 198 IF (error /= 0) THEN 199 abort_message='Pb allocation xtrun_off_lic' 200 CALL abort_gcm(modname,abort_message,1) 201 ENDIF 202 xtrun_off_lic(:,:) = 0. 203 204 ALLOCATE(fxtfonte_global(niso,klon,nbsrf)) 205 IF (error /= 0) THEN 206 abort_message='Pb allocation fxtfonte_global' 207 CALL abort_gcm(modname,abort_message,1) 208 ENDIF 209 fxtfonte_global(:,:,:) = 0.0 210 211 ALLOCATE(fxtcalving_global(niso,klon,nbsrf)) 212 IF (error /= 0) THEN 213 abort_message='Pb allocation fxtcalving_global' 214 CALL abort_gcm(modname,abort_message,1) 215 ENDIF 216 fxtcalving_global(:,:,:) = 0.0 217 218 ALLOCATE(xtrunofflic_global(niso,klon)) 219 IF (error /= 0) THEN 220 abort_message='Pb allocation xtrunofflic_global' 221 CALL abort_gcm(modname,abort_message,1) 222 ENDIF 223 xtrunofflic_global(:,:) = 0.0 224 225 END SUBROUTINE fonte_neige_init_iso 226 #endif 227 125 228 ! 126 229 !**************************************************************************************** … … 128 231 SUBROUTINE fonte_neige( knon, nisurf, knindex, dtime, & 129 232 tsurf, precip_rain, precip_snow, & 130 snow, qsol, tsurf_new, evap) 131 132 USE indice_sol_mod 233 snow, qsol, tsurf_new, evap & 234 #ifdef ISO 235 & ,fq_fonte_diag,fqfonte_diag,snow_evap_diag,fqcalving_diag & 236 & ,max_eau_sol_diag,runoff_diag,run_off_lic_diag,coeff_rel_diag & 237 #endif 238 & ) 239 240 USE indice_sol_mod 241 #ifdef ISO 242 USE infotrac_phy, ONLY: niso 243 !use isotopes_mod, ONLY: ridicule_snow,iso_eau,iso_HDO 244 #ifdef ISOVERIF 245 USE isotopes_verif_mod 246 #endif 247 #endif 133 248 134 249 ! Routine de traitement de la fonte de la neige dans le cas du traitement … … 172 287 REAL, DIMENSION(klon), INTENT(INOUT) :: tsurf_new 173 288 REAL, DIMENSION(klon), INTENT(INOUT) :: evap 289 290 #ifdef ISO 291 ! sortie de quelques diagnostiques 292 REAL, DIMENSION(klon), INTENT(OUT) :: fq_fonte_diag 293 REAL, DIMENSION(klon), INTENT(OUT) :: fqfonte_diag 294 REAL, DIMENSION(klon), INTENT(OUT) :: snow_evap_diag 295 REAL, DIMENSION(klon), INTENT(OUT) :: fqcalving_diag 296 REAL, INTENT(OUT) :: max_eau_sol_diag 297 REAL, DIMENSION(klon), INTENT(OUT) :: runoff_diag 298 REAL, DIMENSION(klon), INTENT(OUT) :: run_off_lic_diag 299 REAL, INTENT(OUT) :: coeff_rel_diag 300 #endif 174 301 175 302 ! Local variables … … 193 320 194 321 LOGICAL :: neige_fond 322 323 #ifdef ISO 324 max_eau_sol_diag=max_eau_sol 325 #endif 326 195 327 196 328 !**************************************************************************************** … … 231 363 232 364 bil_eau_s(:) = (precip_rain(:) * dtime) - (evap(:) - snow_evap(:)) * dtime 365 #ifdef ISO 366 snow_evap_diag(:) = snow_evap(:) 367 coeff_rel_diag = coeff_rel 368 #endif 369 233 370 234 371 … … 254 391 bil_eau_s(i) = bil_eau_s(i) + fq_fonte 255 392 tsurf_new(i) = tsurf_new(i) - fq_fonte * chasno 393 #ifdef ISO 394 fq_fonte_diag(i) = fq_fonte 395 #endif 396 256 397 257 398 !IM cf JLD OK … … 273 414 snow(i)=MIN(snow(i),snow_max) 274 415 ENDDO 416 #ifdef ISO 417 DO i = 1, knon 418 fqcalving_diag(i) = fqcalving(i) 419 fqfonte_diag(i) = fqfonte(i) 420 ENDDO !DO i = 1, knon 421 #endif 422 275 423 276 424 IF (nisurf == is_ter) THEN … … 278 426 qsol(i) = qsol(i) + bil_eau_s(i) 279 427 run_off_ter(i) = run_off_ter(i) + MAX(qsol(i) - max_eau_sol, 0.0) 428 #ifdef ISO 429 runoff_diag(i) = MAX(qsol(i) - max_eau_sol, 0.0) 430 #endif 280 431 qsol(i) = MIN(qsol(i), max_eau_sol) 281 432 ENDDO … … 290 441 ENDDO 291 442 ENDIF 443 444 #ifdef ISO 445 DO i = 1, klon 446 run_off_lic_diag(i) = run_off_lic(i) 447 ENDDO ! DO i = 1, knon 448 #endif 292 449 293 450 !**************************************************************************************** … … 312 469 !**************************************************************************************** 313 470 ! 314 SUBROUTINE fonte_neige_final(restart_runoff) 471 SUBROUTINE fonte_neige_final(restart_runoff & 472 #ifdef ISO 473 & ,xtrestart_runoff & 474 #endif 475 & ) 315 476 ! 316 477 ! This subroutine returns run_off_lic_0 for later writing to restart file. 317 478 ! 479 #ifdef ISO 480 USE infotrac_phy, ONLY: niso 481 #ifdef ISOVERIF 482 USE isotopes_mod, ONLY: iso_eau 483 USE isotopes_verif_mod 484 #endif 485 #endif 486 ! 318 487 !**************************************************************************************** 319 488 REAL, DIMENSION(klon), INTENT(OUT) :: restart_runoff 489 #ifdef ISO 490 REAL, DIMENSION(niso,klon), INTENT(OUT) :: xtrestart_runoff 491 #ifdef ISOVERIF 492 INTEGER :: i 493 #endif 494 #endif 495 496 320 497 321 498 !**************************************************************************************** 322 499 ! Set the output variables 323 500 restart_runoff(:) = run_off_lic_0(:) 501 #ifdef ISO 502 xtrestart_runoff(:,:) = xtrun_off_lic_0(:,:) 503 #ifdef ISOVERIF 504 IF (iso_eau > 0) THEN 505 DO i=1,klon 506 IF (iso_verif_egalite_nostop(run_off_lic_0(i) & 507 & ,xtrun_off_lic_0(iso_eau,i) & 508 & ,'fonte_neige 413') & 509 & == 1) then 510 WRITE(*,*) 'i=',i 511 STOP 512 ENDIF 513 ENDDO !DO i=1,klon 514 ENDIF !IF (iso_eau > 0) then 515 #endif 516 #endif 517 518 324 519 325 520 ! Deallocation of all varaibles in the module … … 334 529 IF (ALLOCATED(fqcalving_global)) DEALLOCATE(fqcalving_global) 335 530 IF (ALLOCATED(runofflic_global)) DEALLOCATE(runofflic_global) 531 #ifdef ISO 532 IF (ALLOCATED(xtrun_off_lic_0)) DEALLOCATE(xtrun_off_lic_0) 533 IF (ALLOCATED(xtrun_off_ter)) DEALLOCATE(xtrun_off_ter) 534 IF (ALLOCATED(xtrun_off_lic)) DEALLOCATE(xtrun_off_lic) 535 IF (ALLOCATED(fxtfonte_global)) DEALLOCATE(fxtfonte_global) 536 IF (ALLOCATED(fxtcalving_global)) DEALLOCATE(fxtcalving_global) 537 IF (ALLOCATED(xtrunofflic_global)) DEALLOCATE(xtrunofflic_global) 538 #endif 539 336 540 337 541 END SUBROUTINE fonte_neige_final … … 340 544 ! 341 545 SUBROUTINE fonte_neige_get_vars(pctsrf, fqcalving_out, & 342 fqfonte_out, ffonte_out, run_off_lic_out) 546 fqfonte_out, ffonte_out, run_off_lic_out & 547 #ifdef ISO 548 & ,fxtcalving_out, fxtfonte_out,xtrun_off_lic_out & 549 #endif 550 & ) 343 551 344 552 … … 349 557 !**************************************************************************************** 350 558 351 USE indice_sol_mod 559 USE indice_sol_mod 560 #ifdef ISO 561 USE infotrac_phy, ONLY: niso 562 #endif 352 563 353 564 REAL, DIMENSION(klon,nbsrf), INTENT(IN) :: pctsrf … … 358 569 REAL, DIMENSION(klon), INTENT(OUT) :: run_off_lic_out 359 570 571 #ifdef ISO 572 REAL, DIMENSION(niso,klon), INTENT(OUT) :: fxtcalving_out 573 REAL, DIMENSION(niso,klon), INTENT(OUT) :: fxtfonte_out 574 REAL, DIMENSION(niso,klon), INTENT(OUT) :: xtrun_off_lic_out 575 INTEGER :: i,ixt 576 #endif 577 360 578 INTEGER :: nisurf 361 579 !**************************************************************************************** … … 364 582 fqfonte_out(:) = 0.0 365 583 fqcalving_out(:) = 0.0 584 #ifdef ISO 585 fxtfonte_out(:,:) = 0.0 586 fxtcalving_out(:,:) = 0.0 587 #endif 366 588 367 589 DO nisurf = 1, nbsrf … … 373 595 run_off_lic_out(:)=runofflic_global(:) 374 596 597 #ifdef ISO 598 DO nisurf = 1, nbsrf 599 DO i=1,klon 600 DO ixt=1,niso 601 fxtfonte_out(ixt,i) = fxtfonte_out(ixt,i) + fxtfonte_global(ixt,i,nisurf)*pctsrf(i,nisurf) 602 fxtcalving_out(ixt,i) = fxtcalving_out(ixt,i) + fxtcalving_global(ixt,i,nisurf)*pctsrf(i,nisurf) 603 ENDDO !DO ixt=1,niso 604 ENDDO !DO i=1,klon 605 ENDDO !DO nisurf = 1, nbsrf 606 xtrun_off_lic_out(:,:) = xtrunofflic_global(:,:) 607 #endif 608 375 609 END SUBROUTINE fonte_neige_get_vars 376 610 ! 377 611 !**************************************************************************************** 378 612 ! 613 !#ifdef ISO 614 ! subroutine fonte_neige_export_xtrun_off_lic_0(knon,xtrun_off_lic_0_diag) 615 ! use infotrac_phy, ONLY: niso 616 ! 617 ! ! inputs 618 ! INTEGER, INTENT(IN) :: knon 619 ! real, INTENT(IN), DIMENSION(niso,klon) :: xtrun_off_lic_0_diag 620 ! 621 ! xtrun_off_lic_0(:,:)=xtrun_off_lic_0_diag(:,:) 622 ! 623 ! end subroutine fonte_neige_export_xtrun_off_lic_0 624 !#endif 625 626 #ifdef ISO 627 SUBROUTINE gestion_neige_besoin_varglob_fonte_neige(klon,knon, & 628 & xtprecip_snow,xtprecip_rain, & 629 & fxtfonte_neige,fxtcalving, & 630 & knindex,nisurf,run_off_lic_diag,coeff_rel_diag) 631 632 ! dans cette routine, on a besoin des variables globales de 633 ! fonte_neige_mod. Il faut donc la mettre dans fonte_neige_mod 634 ! le reste de gestion_neige est dans isotopes_routines_mod car sinon pb 635 ! de dépendance circulaire. 636 637 USE infotrac_phy, ONLY: ntiso,niso 638 USE isotopes_mod, ONLY: iso_eau 639 USE indice_sol_mod 640 #ifdef ISOVERIF 641 USE isotopes_verif_mod 642 #endif 643 IMPLICIT NONE 644 645 ! inputs 646 INTEGER, INTENT(IN) :: klon,knon 647 REAL, DIMENSION(ntiso,klon), INTENT(IN) :: xtprecip_snow, xtprecip_rain 648 REAL, DIMENSION(niso,klon), INTENT(IN) :: fxtfonte_neige,fxtcalving 649 INTEGER, INTENT(IN) :: nisurf 650 INTEGER, DIMENSION(klon), INTENT(IN) :: knindex 651 REAL, DIMENSION(klon), INTENT(IN) :: run_off_lic_diag 652 REAL, INTENT(IN) :: coeff_rel_diag 653 654 ! locals 655 INTEGER :: i,ixt,j 656 657 #ifdef ISOVERIF 658 IF (nisurf == is_lic) THEN 659 IF (iso_eau > 0) THEN 660 DO i = 1, knon 661 j = knindex(i) 662 CALL iso_verif_egalite(xtrun_off_lic_0(iso_eau,j), & 663 & run_off_lic_0(j),'gestion_neige_besoin_varglob_fonte_neige 625') 664 ENDDO 665 ENDIF 666 ENDIF 667 #endif 668 669 ! calcul de run_off_lic 670 671 IF (nisurf == is_lic) THEN 672 ! coeff_rel = dtime/(tau_calv * rday) 673 674 DO i = 1, knon 675 j = knindex(i) 676 DO ixt = 1, niso 677 xtrun_off_lic(ixt,i) = (coeff_rel_diag * fxtcalving(ixt,i)) & 678 & +(1. - coeff_rel_diag) * xtrun_off_lic_0(ixt,j) 679 xtrun_off_lic_0(ixt,j) = xtrun_off_lic(ixt,i) 680 xtrun_off_lic(ixt,i) = xtrun_off_lic(ixt,i) + fxtfonte_neige(ixt,i) + xtprecip_rain(ixt,i) 681 ENDDO !DO ixt=1,niso 682 #ifdef ISOVERIF 683 IF (iso_eau > 0) THEN 684 IF (iso_verif_egalite_choix_nostop(xtrun_off_lic(iso_eau,i), & 685 & run_off_lic_diag(i),'gestion_neige_besoin_varglob_fonte_neige 1201a', & 686 & errmax,errmaxrel) == 1) THEN 687 WRITE(*,*) 'i,j=',i,j 688 WRITE(*,*) 'coeff_rel_diag=',coeff_rel_diag 689 STOP 690 ENDIF 691 ENDIF 692 #endif 693 ENDDO 694 ENDIF !IF (nisurf == is_lic) THEN 695 696 ! Save ffonte, fqfonte and fqcalving in global arrays for each 697 ! sub-surface separately 698 DO i = 1, knon 699 DO ixt = 1, niso 700 fxtfonte_global(ixt,knindex(i),nisurf) = fxtfonte_neige(ixt,i) 701 fxtcalving_global(ixt,knindex(i),nisurf) = fxtcalving(ixt,i) 702 ENDDO !do ixt=1,niso 703 ENDDO 704 705 IF (nisurf == is_lic) THEN 706 DO i = 1, knon 707 DO ixt = 1, niso 708 xtrunofflic_global(ixt,knindex(i)) = xtrun_off_lic(ixt,i) 709 ENDDO ! DO ixt=1,niso 710 ENDDO 711 ENDIF 712 713 END SUBROUTINE gestion_neige_besoin_varglob_fonte_neige 714 #endif 715 716 379 717 END MODULE fonte_neige_mod -
LMDZ6/branches/cirrus/libf/phylmd/infotrac_phy.F90
r4638 r5202 5 5 USE strings_mod, ONLY: msg, fmsg, maxlen, cat, dispTable, int2str, bool2str, strStack, strParse, strIdx 6 6 USE readTracFiles_mod, ONLY: trac_type, readTracersFiles, tracers, setGeneration, itZonIso, nzone, tran0, isoZone, & 7 delPhase, niso, getKey, isot_type, readIsotopesFile,isotope, maxTableWidth, iqIsoPha, nphas, ixIso, isoPhas, &8 addPhase, iH2O, addKey, isoSelect, testTracersFiles, isoKeys, indexUpdate, isoCheck, nbIso, ntiso, isoName7 delPhase, niso, getKey, isot_type, processIsotopes, isotope, maxTableWidth, iqIsoPha, nphas, ixIso, isoPhas, & 8 addPhase, iH2O, addKey, isoSelect, testTracersFiles, isoKeys, indexUpdate, iqWIsoPha, nbIso, ntiso, isoName, isoCheck 9 9 IMPLICIT NONE 10 10 … … 20 20 PUBLIC :: id_OCS_strat, id_SO2_strat, id_H2SO4_strat, id_BIN01_strat, id_TEST_strat 21 21 #endif 22 #ifdef REPROBUS 23 PUBLIC :: nbtr_bin, nbtr_sulgas 24 PUBLIC :: id_OCS_strat, id_SO2_strat, id_H2SO4_strat, id_BIN01_strat, & 25 id_TEST_strat 26 #endif 27 22 23 !=== FOR WATER 24 PUBLIC :: ivap, iliq, isol 28 25 !=== FOR ISOTOPES: General 29 26 PUBLIC :: isot_type, nbIso !--- Derived type, full isotopes families database + nb of families … … 37 34 PUBLIC :: itZonIso !--- idx "it" (in "isoName(1:niso)") = function(tagging idx, isotope idx) 38 35 PUBLIC :: iqIsoPha !--- idx "iq" (in "qx") = function(isotope idx, phase idx) + aliases 36 PUBLIC :: iqWIsoPha !--- Same as iqIsoPha but with normal water phases 37 39 38 PUBLIC :: isoCheck !--- Run isotopes checking routines 40 39 !=== FOR BOTH TRACERS AND ISOTOPES … … 73 72 ! | longName | Long name (with adv. scheme suffix) for outputs | ttext | | 74 73 ! | type | Type (so far: tracer or tag) | / | tracer,tag | 75 ! | phase | Phases list ("g"as / "l"iquid / "s"olid / "b"lowing) | / | [g][l][s][b]|74 ! | phase | Phases list ("g"as / "l"iquid / "s"olid) | / | [g][l][s] | 76 75 ! | component | Name(s) of the merged/cumulated section(s) | / | coma-separated names | 77 76 ! | iGeneration | Generation (>=1) | / | | … … 98 97 ! | trac | ntiso | Isotopes + tagging tracers list + number | / | ntraciso | | 99 98 ! | zone | nzone | Geographic tagging zones list + number | / | ntraceurs_zone | | 100 ! | phase | nphas | Phases list + number | | [g][l][s][b] 1:4|99 ! | phase | nphas | Phases list + number | | [g][l][s], 1:3 | 101 100 ! | iqIsoPha | Index in "qx" = f(name(1:ntiso)),phas) | iqiso | 1:nqtot | 101 ! | iqWIsoPha | Index in "qx" = f(name(1:ntiso)),phas) | iqiso | 1:nqtot | 102 102 ! | itZonIso | Index in "trac(1:ntiso)"= f(zone, name(1:niso)) | index_trac | 1:ntiso | 103 103 ! +-----------------+--------------------------------------------------+--------------------+-----------------+ … … 112 112 !$OMP THREADPRIVATE(nqtot, nbtr, nqo, nqtottr, nqCO2, type_trac) 113 113 114 !=== INDICES OF WATER 115 INTEGER, SAVE :: ivap,iliq,isol ! Indices for vap, liq and ice 116 !$OMP THREADPRIVATE(ivap,iliq,isol) 117 114 118 !=== VARIABLES FOR INCA 115 119 INTEGER, SAVE, ALLOCATABLE :: conv_flg(:), & !--- Convection activation ; needed for INCA (nbtr) … … 123 127 INTEGER, SAVE :: id_OCS_strat, id_SO2_strat, id_H2SO4_strat, id_BIN01_strat, id_TEST_strat 124 128 !$OMP THREADPRIVATE(id_OCS_strat, id_SO2_strat, id_H2SO4_strat, id_BIN01_strat, id_TEST_strat) 125 #endif126 #ifdef REPROBUS127 INTEGER, SAVE :: nbtr_bin, nbtr_sulgas128 !$OMP THREADPRIVATE(nbtr_bin, nbtr_sulgas)129 INTEGER, SAVE :: id_OCS_strat, id_SO2_strat, id_H2SO4_strat, id_BIN01_strat,&130 id_TEST_strat131 !$OMP THREADPRIVATE(id_OCS_strat, id_SO2_strat, id_H2SO4_strat, id_BIN01_strat)132 !$OMP THREADPRIVATE(id_TEST_strat)133 129 #endif 134 130 … … 182 178 INTEGER :: nqtrue !--- Tracers nb from tracer.def (no higher order moments) 183 179 INTEGER :: iad !--- Advection scheme number 184 INTEGER :: ic, iq, jq, it, nt, im, nm, iz, k !--- Indexes and temporary variables 185 LOGICAL :: lerr, ll, lInit 186 CHARACTER(LEN=1) :: p 180 INTEGER :: iq, jq, nt, im, nm, k !--- Indexes and temporary variables 181 LOGICAL :: lerr, lInit 187 182 TYPE(trac_type), ALLOCATABLE, TARGET :: ttr(:) 188 183 TYPE(trac_type), POINTER :: t1, t(:) 189 INTEGER :: ierr190 184 CHARACTER(LEN=maxlen), ALLOCATABLE :: types_trac(:) !--- Keyword for tracers type(s), parsed version 191 185 … … 262 256 !############################################################################################################################## 263 257 IF(lInit) THEN 264 IF(readTracersFiles(ttp, type_trac =='repr')) CALL abort_physic(modname, 'problem with tracers file(s)',1)258 IF(readTracersFiles(ttp, lRepr=type_trac=='repr')) CALL abort_physic(modname, 'problem with tracers file(s)',1) 265 259 ELSE 266 260 CALL msg('No tracers description file(s) reading needed: already done in the dynamics', modname) … … 388 382 389 383 !--- SET FIELDS %iqParent, %nqChildren, %iGeneration, %iqDescen, %nqDescen 390 CALL indexUpdate(tracers)384 IF(indexUpdate(tracers)) CALL abort_gcm(modname, 'problem when processing isotopes parameters', 1) 391 385 392 386 !############################################################################################################################## … … 404 398 !=== READ PHYSICAL PARAMETERS FOR ISOTOPES 405 399 niso = 0; nzone = 0; nphas = nqo; ntiso = 0; isoCheck = .FALSE. 406 IF( readIsotopesFile()) CALL abort_physic(modname, 'Problem when reading isotopes parameters', 1)400 IF(processIsotopes()) CALL abort_physic(modname, 'Problem when processing isotopes parameters', 1) 407 401 408 402 !############################################################################################################################## … … 416 410 nqtottr = nqtot - COUNT(delPhase(tracers%gen0Name) == 'H2O' .AND. tracers%component == 'lmdz') 417 411 IF(COUNT(tracers%iso_iName == 0) - COUNT(delPhase(tracers%name) == 'H2O' .AND. tracers%component == 'lmdz') /= nqtottr) & 418 CALL abort_physic(modname, 'p b dans le calcul denqtottr', 1)412 CALL abort_physic(modname, 'problem with the computation of nqtottr', 1) 419 413 420 414 !=== DISPLAY THE RESULTS … … 431 425 t => tracers 432 426 CALL msg('Information stored in infotrac_phy :', modname) 433 IF(dispTable('issssssssiiiiiiii', & 434 ['iq ', 'name ', 'lName ', 'gen0N ', 'parent', 'type ', 'phase ', 'compon', 'isPhy ', & 435 'iGen ', 'iqPar ', 'nqDes ', 'nqChld', 'iGroup', 'iName ', 'iZone ', 'iPhase'], & 427 IF(dispTable('issssssssiiiiiiii', ['iq ', 'name', 'lNam', 'g0Nm', 'prnt', 'type', 'phas', 'comp', & 428 'isPh', 'iGen', 'iqPr', 'nqDe', 'nqCh', 'iGrp', 'iNam', 'iZon', 'iPha'], & 436 429 cat(t%name, t%longName, t%gen0Name, t%parent, t%type, t%phase, t%component, bool2str(t%isInPhysics)),& 437 430 cat([(iq, iq=1, nqtot)], t%iGeneration, t%iqParent, t%nqDescen, t%nqChildren, t%iso_iGroup, & -
LMDZ6/branches/cirrus/libf/phylmd/lmdz_atke_exchange_coeff.F90
r4884 r5202 7 7 subroutine atke_compute_km_kh(ngrid,nlay,dtime, & 8 8 wind_u,wind_v,temp,qvap,play,pinterf,cdrag_uv, & 9 tke,eps, Km_out,Kh_out)9 tke,eps,tke_shear,tke_buoy,tke_trans,Km_out,Kh_out) 10 10 11 11 !======================================================================== … … 79 79 80 80 REAL, DIMENSION(ngrid,nlay+1), INTENT(OUT) :: eps ! output: TKE dissipation rate at interface between layers (m2/s3) 81 REAL, DIMENSION(ngrid,nlay+1), INTENT(OUT) :: tke_shear! output: TKE shear production rate (m2/s3) 82 REAL, DIMENSION(ngrid,nlay+1), INTENT(OUT) :: tke_buoy ! output: TKE buoyancy production rate (m2/s3) 83 REAL, DIMENSION(ngrid,nlay+1), INTENT(OUT) :: tke_trans! output: TKE transport (diffusion) term (m2/s3) 81 84 REAL, DIMENSION(ngrid,nlay), INTENT(OUT) :: Km_out ! output: Exchange coefficient for momentum at interface between layers (m2/s) 82 85 REAL, DIMENSION(ngrid,nlay), INTENT(OUT) :: Kh_out ! output: Exchange coefficient for heat flux at interface between layers (m2/s) … … 261 264 shear2(igrid,ilay) * (1. - Ri(igrid,ilay) / Prandtl(igrid,ilay)) 262 265 eps(igrid,ilay) = (tke(igrid,ilay)**(3./2))/(cepsilon*l_exchange(igrid,ilay)) 266 tke_shear(igrid,ilay)=l_exchange(igrid,ilay)*Sm(igrid,ilay)*sqrt(tke(igrid,ilay))*shear2(igrid,ilay) 267 tke_buoy(igrid,ilay)=-l_exchange(igrid,ilay)*Sm(igrid,ilay)*sqrt(tke(igrid,ilay))*shear2(igrid,ilay) & 268 *(Ri(igrid,ilay) / Prandtl(igrid,ilay)) 263 269 ENDDO 264 270 ENDDO … … 278 284 qq=max(0.,qq) 279 285 tke(igrid,ilay)=0.5*(qq**2) 280 eps(igrid,ilay) = (tke(igrid,ilay)**(3./2))/(cepsilon*l_exchange(igrid,ilay)) 286 eps(igrid,ilay) = (tke(igrid,ilay)**(3./2))/(cepsilon*l_exchange(igrid,ilay)) 287 tke_shear(igrid,ilay)=l_exchange(igrid,ilay)*Sm(igrid,ilay)*sqrt(tke(igrid,ilay))*shear2(igrid,ilay) 288 tke_buoy(igrid,ilay)=-l_exchange(igrid,ilay)*Sm(igrid,ilay)*sqrt(tke(igrid,ilay))*shear2(igrid,ilay) & 289 *(Ri(igrid,ilay) / Prandtl(igrid,ilay)) 281 290 ENDDO 282 291 ENDDO … … 293 302 qq=(qq+l_exchange(igrid,ilay)*Sm(igrid,ilay)*dtime/sqrt(2.) & 294 303 *shear2(igrid,ilay)*(1.-Ri(igrid,ilay)/Prandtl(igrid,ilay))) & 295 /(1.+qq*dtime/(cepsilon*l_exchange(igrid,ilay)*2.*sqrt(2.))) 304 /(1.+qq*dtime/(cepsilon*l_exchange(igrid,ilay)*2.*sqrt(2.))) 305 tke_shear(igrid,ilay)=l_exchange(igrid,ilay)*Sm(igrid,ilay)*qq/sqrt(2.)*shear2(igrid,ilay) 306 tke_buoy(igrid,ilay)=-l_exchange(igrid,ilay)*Sm(igrid,ilay)*qq/sqrt(2.)*shear2(igrid,ilay) & 307 *(Ri(igrid,ilay) / Prandtl(igrid,ilay)) 296 308 tke(igrid,ilay)=0.5*(qq**2) 297 309 eps(igrid,ilay) = (tke(igrid,ilay)**(3./2))/(cepsilon*l_exchange(igrid,ilay)) … … 308 320 eps(igrid,ilay) = (tke(igrid,ilay)**(3./2))/(cepsilon*l_exchange(igrid,ilay)) 309 321 qq=max(sqrt(2.*tke(igrid,ilay)),1.e-10) 322 tke_shear(igrid,ilay)=l_exchange(igrid,ilay)*Sm(igrid,ilay)*qq/sqrt(2.)*shear2(igrid,ilay) 323 tke_buoy(igrid,ilay)=-l_exchange(igrid,ilay)*Sm(igrid,ilay)*qq/sqrt(2.)*shear2(igrid,ilay) & 324 *(Ri(igrid,ilay) / Prandtl(igrid,ilay)) 310 325 IF (Ri(igrid,ilay) .LT. 0.) THEN 311 326 netloss=qq/(2.*sqrt(2.)*cepsilon*l_exchange(igrid,ilay)) … … 327 342 DO igrid=1,ngrid 328 343 qq=max(sqrt(2.*tke(igrid,ilay)),1.e-10) 344 tke_shear(igrid,ilay)=l_exchange(igrid,ilay)*Sm(igrid,ilay)*qq/sqrt(2.)*shear2(igrid,ilay) 345 tke_buoy(igrid,ilay)=-l_exchange(igrid,ilay)*Sm(igrid,ilay)*qq/sqrt(2.)*shear2(igrid,ilay) & 346 *(Ri(igrid,ilay) / Prandtl(igrid,ilay)) 329 347 qq=(l_exchange(igrid,ilay)*Sm(igrid,ilay)/sqrt(2.)*shear2(igrid,ilay)*(1.-Ri(igrid,ilay)/Prandtl(igrid,ilay)) & 330 348 +qq*(1.+dtime*qq/(cepsilon*l_exchange(igrid,ilay)*2.*sqrt(2.)))) & … … 349 367 tke(igrid,nlay+1)=0. 350 368 eps(igrid,nlay+1)=0. 369 tke_shear(igrid,nlay+1)=0. 370 tke_buoy(igrid,nlay+1)=0. 351 371 END DO 352 372 … … 359 379 tke(igrid,1)=ctkes*(ustar**2) 360 380 eps(igrid,1)=0. ! arbitrary as TKE is not properly defined at the surface 381 tke_shear(igrid,1)=0. 382 tke_buoy(igrid,1)=0. 361 383 END DO 362 384 … … 364 386 ! vertical diffusion of TKE 365 387 !========================== 388 tke_trans(:,:)=0. 366 389 IF (atke_ok_vdiff) THEN 367 CALL atke_vdiff_tke(ngrid,nlay,dtime,z_lay,z_interf,temp,play,l_exchange,Sm,tke )390 CALL atke_vdiff_tke(ngrid,nlay,dtime,z_lay,z_interf,temp,play,l_exchange,Sm,tke,tke_trans) 368 391 ENDIF 369 392 … … 387 410 388 411 !=============================================================================================== 389 subroutine atke_vdiff_tke(ngrid,nlay,dtime,z_lay,z_interf,temp,play,l_exchange,Sm,tke )412 subroutine atke_vdiff_tke(ngrid,nlay,dtime,z_lay,z_interf,temp,play,l_exchange,Sm,tke,tke_trans) 390 413 391 414 ! routine that computes the vertical diffusion of TKE by the turbulence … … 408 431 409 432 REAL, DIMENSION(ngrid,nlay+1), INTENT(INOUT) :: tke ! turbulent kinetic energy at interface between layers 410 433 REAL, DIMENSION(ngrid,nlay+1), INTENT(INOUT) :: tke_trans ! turbulent kinetic energy transport term (m2/s3) 411 434 412 435 … … 480 503 ! update TKE 481 504 tke(:,:)=tke(:,:)+dtke(:,:) 505 tke_trans(:,:)=dtke(:,:)/dtime 482 506 483 507 -
LMDZ6/branches/cirrus/libf/phylmd/lmdz_atke_turbulence_ini.F90
r4804 r5202 50 50 !! 51 51 !! ** Purpose : Initialization of the atke module and choice of some constants 52 !! 52 !! Default values correspond to the 'best' configuration 53 !! from tuning on GABLS1 in Vignon et al. 2024, JAMES 53 54 !!---------------------------------------------------------------------- 54 55 … … 73 74 74 75 ! flag that controls options in atke_compute_km_kh 75 iflag_atke= 076 iflag_atke=1 76 77 CALL getin_p('iflag_atke',iflag_atke) 77 78 78 79 ! flag that controls the calculation of mixing length in atke 79 iflag_atke_lmix= 080 iflag_atke_lmix=3 80 81 CALL getin_p('iflag_atke_lmix',iflag_atke_lmix) 81 82 … … 86 87 87 88 ! activate vertical diffusion of TKE or not 88 atke_ok_vdiff=. false.89 atke_ok_vdiff=.true. 89 90 CALL getin_p('atke_ok_vdiff',atke_ok_vdiff) 90 91 … … 101 102 ! Sun et al 2011, JAMC 102 103 ! between 10 and 40 103 l0= 15.0104 l0=42.5279652116005 104 105 CALL getin_p('atke_l0',l0) 105 106 106 107 ! critical Richardson number 107 ric=0. 25108 ric=0.190537327781655 108 109 CALL getin_p('atke_ric',ric) 109 110 110 111 ! constant for tke dissipation calculation 111 cepsilon= 5.87 ! default value as in yamada4112 cepsilon=8.89273387537601 112 113 CALL getin_p('atke_cepsilon',cepsilon) 113 114 … … 131 132 132 133 ! slope of Pr=f(Ri) for stable conditions 133 pr_slope= 5.0 ! default value from Zilitinkevich et al. 2005134 pr_slope=4.67885738180385 134 135 CALL getin_p('atke_pr_slope',pr_slope) 135 136 if (pr_slope .le. 1) then … … 139 140 140 141 ! value of turbulent prandtl number in neutral conditions (Ri=0) 141 pr_neut=0.8 142 pr_neut=0.837372701768868 142 143 CALL getin_p('atke_pr_neut',pr_neut) 143 144 … … 151 152 152 153 ! coefficient for mixing length depending on local stratification 153 clmix=0. 5154 clmix=0.648055235325291 154 155 CALL getin_p('atke_clmix',clmix) 155 156 … … 160 161 ! minimum anisotropy coefficient (defined here as minsqrt(Ez/Ek)) at large Ri. 161 162 ! From Zilitinkevich et al. 2013, it equals sqrt(0.03)~0.17 162 smmin=0. 17163 smmin=0.0960838631869678 163 164 CALL getin_p('atke_smmin',smmin) 164 165 165 166 ! ratio between the eddy diffusivity coeff for tke wrt that for momentum 166 167 ! default value from Lenderink et al. 2004 167 cke=2. 168 cke=2.47069655134662 168 169 CALL getin_p('atke_cke',cke) 169 170 -
LMDZ6/branches/cirrus/libf/phylmd/lmdz_call_atke.F90
r4881 r5202 8 8 contains 9 9 10 subroutine call_atke(dtime,ngrid,nlay, cdrag_uv,cdrag_t,u_surf,v_surf,temp_surf, &10 subroutine call_atke(dtime,ngrid,nlay,nsrf,ni,cdrag_uv,cdrag_t,u_surf,v_surf,temp_surf, & 11 11 wind_u,wind_v,temp,qvap,play,pinterf, & 12 12 tke,eps,Km_out,Kh_out) … … 16 16 17 17 USE lmdz_atke_turbulence_ini, ONLY : iflag_num_atke, rg, rd 18 USE phys_local_var_mod, ONLY: tke_shear, tke_buoy, tke_trans 18 19 19 20 implicit none … … 26 27 INTEGER, INTENT(IN) :: ngrid ! number of horizontal index (flat grid) 27 28 INTEGER, INTENT(IN) :: nlay ! number of vertical index 29 INTEGER, INTENT(IN) :: nsrf ! surface tile index 30 INTEGER, DIMENSION(ngrid), INTENT(IN) :: ni ! array of indices to move from knon to klon arrays 28 31 29 32 … … 50 53 51 54 55 REAL, DIMENSION(ngrid,nlay+1) :: tke_shear_term,tke_buoy_term,tke_trans_term 52 56 REAL, DIMENSION(ngrid,nlay) :: wind_u_predict, wind_v_predict 53 57 REAL, DIMENSION(ngrid) :: wind1 54 INTEGER i 58 INTEGER i,j,k 55 59 56 60 57 61 call atke_compute_km_kh(ngrid,nlay,dtime,& 58 62 wind_u,wind_v,temp,qvap,play,pinterf,cdrag_uv,& 59 tke,eps, Km_out,Kh_out)63 tke,eps,tke_shear_term,tke_buoy_term,tke_trans_term,Km_out,Kh_out) 60 64 61 65 … … 76 80 call atke_compute_km_kh(ngrid,nlay,dtime,& 77 81 wind_u_predict,wind_v_predict,temp,qvap,play,pinterf,cdrag_uv, & 78 tke,eps, Km_out,Kh_out)82 tke,eps,tke_shear_term,tke_buoy_term,tke_trans_term,Km_out,Kh_out) 79 83 80 84 end if 81 85 82 86 87 ! Diagnostics of tke loss/source terms 83 88 89 DO k=1,nlay+1 90 DO i=1,ngrid 91 j=ni(i) 92 tke_shear(j,k,nsrf)=tke_shear_term(i,k) 93 tke_buoy(j,k,nsrf)=tke_buoy_term(i,k) 94 tke_trans(j,k,nsrf)=tke_trans_term(i,k) 95 ENDDO 96 ENDDO 84 97 85 98 -
LMDZ6/branches/cirrus/libf/phylmd/lmdz_lscp.F90
r5163 r5202 7 7 !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 8 8 SUBROUTINE lscp(klon,klev,dtime,missing_val, & 9 paprs,pplay,temp,qt, ptconv,ratqs,&9 paprs,pplay,temp,qt,qice_save,ptconv,ratqs, & 10 10 d_t, d_q, d_ql, d_qi, rneb, rneblsvol, & 11 pfraclr,pfracld, & 11 pfraclr, pfracld, & 12 cldfraliq, sigma2_icefracturb,mean_icefracturb, & 12 13 radocond, radicefrac, rain, snow, & 13 14 frac_impa, frac_nucl, beta, & 14 prfl, psfl, rhcl, qta, fraca, & 15 tv, pspsk, tla, thl, iflag_cld_th, & 16 iflag_ice_thermo, distcltop, temp_cltop, cell_area,& 17 cf_seri, rvc_seri, u_seri, v_seri, pbl_eps, & 15 prfl, psfl, rhcl, qta, fraca, & 16 tv, pspsk, tla, thl, iflag_cld_th, & 17 iflag_ice_thermo, distcltop, temp_cltop, & 18 tke, tke_dissip, & 19 cell_area, & 20 cf_seri, rvc_seri, u_seri, v_seri, & 18 21 qsub, qissr, qcld, subfra, issrfra, gamma_cond, & 19 22 ratio_qi_qtot, dcf_sub, dcf_con, dcf_mix, & … … 100 103 ! USE de modules contenant des fonctions. 101 104 USE lmdz_cloudth, ONLY : cloudth, cloudth_v3, cloudth_v6, cloudth_mpc 102 USE lmdz_lscp_tools, ONLY : calc_qsat_ecmwf, icefrac_lscp, calc_gammasat 105 USE lmdz_lscp_tools, ONLY : calc_qsat_ecmwf, calc_gammasat 106 USE lmdz_lscp_tools, ONLY : icefrac_lscp, icefrac_lscp_turb 103 107 USE lmdz_lscp_tools, ONLY : fallice_velocity, distance_to_cloud_top 104 108 USE lmdz_lscp_condensation, ONLY : condensation_lognormal, condensation_ice_supersat … … 115 119 USE lmdz_lscp_ini, ONLY : RCPD, RLSTT, RLVTT, RLMLT, RVTMP2, RTT, RD, RG 116 120 USE lmdz_lscp_ini, ONLY : ok_poprecip 117 USE lmdz_lscp_ini, ONLY : ok_external_lognormal, ok_ice_supersat, ok_unadjusted_clouds 121 USE lmdz_lscp_ini, ONLY : ok_external_lognormal, ok_ice_supersat, ok_unadjusted_clouds, iflag_icefrac 118 122 119 123 IMPLICIT NONE … … 134 138 REAL, DIMENSION(klon,klev), INTENT(IN) :: temp ! temperature (K) 135 139 REAL, DIMENSION(klon,klev), INTENT(IN) :: qt ! total specific humidity (in vapor phase in input) [kg/kg] 140 REAL, DIMENSION(klon,klev), INTENT(IN) :: qice_save ! ice specific from previous time step [kg/kg] 136 141 INTEGER, INTENT(IN) :: iflag_cld_th ! flag that determines the distribution of convective clouds 137 142 INTEGER, INTENT(IN) :: iflag_ice_thermo! flag to activate the ice thermodynamics … … 141 146 !Inputs associated with thermal plumes 142 147 143 REAL, DIMENSION(klon,klev), INTENT(IN) :: tv ! virtual potential temperature [K] 144 REAL, DIMENSION(klon,klev), INTENT(IN) :: qta ! specific humidity within thermals [kg/kg] 145 REAL, DIMENSION(klon,klev), INTENT(IN) :: fraca ! fraction of thermals within the mesh [-] 146 REAL, DIMENSION(klon,klev), INTENT(IN) :: pspsk ! exner potential (p/100000)**(R/cp) 147 REAL, DIMENSION(klon,klev), INTENT(IN) :: tla ! liquid temperature within thermals [K] 148 REAL, DIMENSION(klon,klev), INTENT(IN) :: tv ! virtual potential temperature [K] 149 REAL, DIMENSION(klon,klev), INTENT(IN) :: qta ! specific humidity within thermals [kg/kg] 150 REAL, DIMENSION(klon,klev), INTENT(IN) :: fraca ! fraction of thermals within the mesh [-] 151 REAL, DIMENSION(klon,klev), INTENT(IN) :: pspsk ! exner potential (p/100000)**(R/cp) 152 REAL, DIMENSION(klon,klev), INTENT(IN) :: tla ! liquid temperature within thermals [K] 153 REAL, DIMENSION(klon,klev+1), INTENT(IN) :: tke !--turbulent kinetic energy [m2/s2] 154 REAL, DIMENSION(klon,klev+1), INTENT(IN) :: tke_dissip !--TKE dissipation [m2/s3] 148 155 149 156 ! INPUT/OUTPUT variables 150 157 !------------------------ 151 158 152 REAL, DIMENSION(klon,klev), INTENT(INOUT) :: thl ! liquid potential temperature [K]153 REAL, DIMENSION(klon,klev), INTENT(INOUT) :: ratqs ! function of pressure that sets the large-scale159 REAL, DIMENSION(klon,klev), INTENT(INOUT) :: thl ! liquid potential temperature [K] 160 REAL, DIMENSION(klon,klev), INTENT(INOUT) :: ratqs ! function of pressure that sets the large-scale 154 161 155 162 ! INPUT/OUTPUT condensation and ice supersaturation … … 160 167 REAL, DIMENSION(klon,klev), INTENT(IN) :: u_seri ! eastward wind [m/s] 161 168 REAL, DIMENSION(klon,klev), INTENT(IN) :: v_seri ! northward wind [m/s] 162 REAL, DIMENSION(klon,klev+1), INTENT(IN) :: pbl_eps ! TKE dissipation [?]163 169 REAL, DIMENSION(klon), INTENT(IN) :: cell_area ! area of each cell [m2] 164 170 … … 179 185 REAL, DIMENSION(klon,klev), INTENT(OUT) :: pfraclr ! precip fraction clear-sky part [-] 180 186 REAL, DIMENSION(klon,klev), INTENT(OUT) :: pfracld ! precip fraction cloudy part [-] 187 REAL, DIMENSION(klon,klev), INTENT(OUT) :: cldfraliq ! liquid fraction of cloud [-] 188 REAL, DIMENSION(klon,klev), INTENT(OUT) :: sigma2_icefracturb ! Variance of the diagnostic supersaturation distribution (icefrac_turb) [-] 189 REAL, DIMENSION(klon,klev), INTENT(OUT) :: mean_icefracturb ! Mean of the diagnostic supersaturation distribution (icefrac_turb) [-] 181 190 REAL, DIMENSION(klon,klev), INTENT(OUT) :: radocond ! condensed water used in the radiation scheme [kg/kg] 182 191 REAL, DIMENSION(klon,klev), INTENT(OUT) :: radicefrac ! ice fraction of condensed water for radiation scheme … … 190 199 REAL, DIMENSION(klon,klev), INTENT(OUT) :: beta ! conversion rate of condensed water 191 200 192 ! fraction of aerosol scavenging through impaction and nucleation (for on-line)201 ! fraction of aerosol scavenging through impaction and nucleation (for on-line) 193 202 194 REAL, DIMENSION(klon,klev), INTENT(OUT) :: frac_impa ! scavenging fraction due tu impaction [-]195 REAL, DIMENSION(klon,klev), INTENT(OUT) :: frac_nucl ! scavenging fraction due tu nucleation [-]203 REAL, DIMENSION(klon,klev), INTENT(OUT) :: frac_impa ! scavenging fraction due tu impaction [-] 204 REAL, DIMENSION(klon,klev), INTENT(OUT) :: frac_nucl ! scavenging fraction due tu nucleation [-] 196 205 197 206 ! for condensation and ice supersaturation … … 255 264 ! LOCAL VARIABLES: 256 265 !---------------- 257 258 REAL,DIMENSION(klon) :: qsl, qsi 266 REAL,DIMENSION(klon) :: qsl, qsi ! saturation threshold at current vertical level 259 267 REAL :: zct, zcl,zexpo 260 268 REAL, DIMENSION(klon,klev) :: ctot … … 263 271 REAL :: zdelta, zcor, zcvm5 264 272 REAL, DIMENSION(klon) :: zdqsdT_raw 265 REAL, DIMENSION(klon) :: gammasat,dgammasatdt ! coefficient to make cold condensation at the correct RH and derivative wrt T266 REAL, DIMENSION(klon) :: Tbef,qlbef,DT 273 REAL, DIMENSION(klon) :: gammasat,dgammasatdt ! coefficient to make cold condensation at the correct RH and derivative wrt T 274 REAL, DIMENSION(klon) :: Tbef,qlbef,DT ! temperature, humidity and temp. variation during lognormal iteration 267 275 REAL :: num,denom 268 276 REAL :: cste 269 REAL, DIMENSION(klon) :: zpdf_sig,zpdf_k,zpdf_delta 270 REAL, DIMENSION(klon) :: Zpdf_a,zpdf_b,zpdf_e1,zpdf_e2 277 REAL, DIMENSION(klon) :: zpdf_sig,zpdf_k,zpdf_delta ! lognormal parameters 278 REAL, DIMENSION(klon) :: Zpdf_a,zpdf_b,zpdf_e1,zpdf_e2 ! lognormal intermediate variables 271 279 REAL :: erf 272 280 REAL, DIMENSION(klon) :: zfice_th … … 285 293 REAL :: zmelt,zrain,zsnow,zprecip 286 294 REAL, DIMENSION(klon) :: dzfice 295 REAL, DIMENSION(klon) :: zfice_turb, dzfice_turb 287 296 REAL :: zsolid 288 297 REAL, DIMENSION(klon) :: qtot, qzero … … 315 324 REAL, DIMENSION(klon,klev) :: radocondi, radocondl 316 325 REAL :: effective_zneb 317 REAL, DIMENSION(klon) :: distcltop1D, temp_cltop1D 326 REAL, DIMENSION(klon) :: zdistcltop, ztemp_cltop 327 REAL, DIMENSION(klon) :: zqliq, zqice, zqvapcl ! for icefrac_lscp_turb 318 328 319 329 ! for condensation and ice supersaturation … … 328 338 REAL :: min_qParent, min_ratio 329 339 330 331 340 INTEGER i, k, n, kk, iter 332 341 INTEGER, DIMENSION(klon) :: n_i … … 382 391 pfraclr(:,:)=0.0 383 392 pfracld(:,:)=0.0 393 cldfraliq(:,:)=0. 394 sigma2_icefracturb(:,:)=0. 395 mean_icefracturb(:,:)=0. 384 396 radocond(:,:) = 0.0 385 397 radicefrac(:,:) = 0.0 … … 391 403 zfice(:)=0.0 392 404 dzfice(:)=0.0 405 zfice_turb(:)=0.0 406 dzfice_turb(:)=0.0 393 407 zqprecl(:)=0.0 394 408 zqpreci(:)=0.0 … … 405 419 d_tot_zneb(:) = 0.0 406 420 qzero(:) = 0.0 407 distcltop1D(:)=0.0408 temp_cltop1D(:) = 0.0421 zdistcltop(:)=0.0 422 ztemp_cltop(:) = 0.0 409 423 ztupnew(:)=0.0 410 424 … … 459 473 460 474 461 462 475 !c_iso: variable initialisation for iso 463 476 … … 478 491 479 492 ! Initialisation temperature and specific humidity 493 ! temp(klon,klev) is not modified by the routine, instead all changes in temperature are made on zt 494 ! at the end of the klon loop, a temperature incremtent d_t due to all processes 495 ! (thermalization, evap/sub incoming precip, cloud formation, precipitation processes) is calculated 496 ! d_t = temperature tendency due to lscp 497 ! The temperature of the overlying layer is updated here because needed for thermalization 480 498 DO i = 1, klon 481 499 zt(i)=temp(i,k) … … 812 830 ELSEIF (iflag_cloudth_vert .EQ. 7) THEN 813 831 ! Updated version of Arnaud Jam (correction by E. Vignon) + adapted treatment 814 ! for boundary-layer mixed phase clouds following Vignon et al.832 ! for boundary-layer mixed phase clouds 815 833 CALL cloudth_mpc(klon,klev,k,mpc_bl_points,zt,zq,qta(:,k),fraca(:,k), & 816 834 pspsk(:,k),paprs(:,k+1),paprs(:,k),pplay(:,k), tla(:,k), & … … 834 852 835 853 ! lognormal 836 lognormale = .TRUE.854 lognormale(:) = .TRUE. 837 855 838 856 ELSEIF (iflag_cld_th .GE. 6) THEN 839 857 840 858 ! lognormal distribution when no thermals 841 lognormale = fraca(:,k) < min_frac_th_cld859 lognormale(:) = fraca(:,k) < min_frac_th_cld 842 860 843 861 ELSE 844 862 ! When iflag_cld_th=5, we always assume 845 863 ! bi-gaussian distribution 846 lognormale = .FALSE.864 lognormale(:) = .FALSE. 847 865 848 866 ENDIF … … 900 918 IF (iflag_t_glace.GE.4) THEN 901 919 ! For iflag_t_glace GE 4 the phase partition function dependends on temperature AND distance to cloud top 902 CALL distance_to_cloud_top(klon,klev,k,temp,pplay,paprs,rneb, distcltop1D,temp_cltop1D)920 CALL distance_to_cloud_top(klon,klev,k,temp,pplay,paprs,rneb,zdistcltop,ztemp_cltop) 903 921 ENDIF 904 CALL icefrac_lscp(klon, zt(:), iflag_ice_thermo, distcltop1D(:),temp_cltop1D(:),zfice(:),dzfice(:)) 905 922 923 CALL icefrac_lscp(klon, zt(:), iflag_ice_thermo, zdistcltop(:),ztemp_cltop(:),zfice(:),dzfice(:)) 906 924 907 925 !--AB Activates a condensation scheme that allows for … … 938 956 pplay(:,k), paprs(:,k), paprs(:,k+1), & 939 957 cf_seri(:,k), rvc_seri(:,k), ratio_qi_qtot(:,k), & 940 shear(:), pbl_eps(:,k), cell_area(:), &958 shear(:), tke_dissip(:,k), cell_area(:), & 941 959 Tbef(:), zq(:), zqs(:), gammasat(:), ratqs(:,k), keepgoing(:), & 942 960 rneb(:,k), zqn(:), qvc(:), issrfra(:,k), qissr(:,k), & … … 1017 1035 cste=RLSTT 1018 1036 ENDIF 1019 1037 1038 ! LEA_R : check formule 1020 1039 IF ( ok_unadjusted_clouds ) THEN 1021 1040 !--AB We relax the saturation adjustment assumption … … 1059 1078 ! For iflag_t_glace GE 4 the phase partition function dependends on temperature AND distance to cloud top 1060 1079 IF (iflag_t_glace.GE.4) THEN 1061 CALL distance_to_cloud_top(klon,klev,k,temp,pplay,paprs,rneb,distcltop1D,temp_cltop1D) 1062 distcltop(:,k)=distcltop1D(:) 1063 temp_cltop(:,k)=temp_cltop1D(:) 1064 ENDIF 1065 ! Partition function in stratiform clouds (will be overwritten in boundary-layer MPCs) 1066 CALL icefrac_lscp(klon,zt,iflag_ice_thermo,distcltop1D,temp_cltop1D,zfice,dzfice) 1067 1080 CALL distance_to_cloud_top(klon,klev,k,temp,pplay,paprs,rneb,zdistcltop,ztemp_cltop) 1081 distcltop(:,k)=zdistcltop(:) 1082 temp_cltop(:,k)=ztemp_cltop(:) 1083 ENDIF 1084 1085 ! Partition function depending on temperature 1086 CALL icefrac_lscp(klon, zt, iflag_ice_thermo, zdistcltop, ztemp_cltop, zfice, dzfice) 1087 1088 ! Partition function depending on tke for non shallow-convective clouds 1089 IF (iflag_icefrac .GE. 1) THEN 1090 1091 CALL icefrac_lscp_turb(klon, dtime, Tbef, pplay(:,k), paprs(:,k), paprs(:,k+1), qice_save(:,k), ziflcld, zqn, & 1092 rneb(:,k), tke(:,k), tke_dissip(:,k), zqliq, zqvapcl, zqice, zfice_turb, dzfice_turb, cldfraliq(:,k),sigma2_icefracturb(:,k), mean_icefracturb(:,k)) 1093 1094 ENDIF 1068 1095 1069 1096 ! Water vapor update, Phase determination and subsequent latent heat exchange 1070 1097 DO i=1, klon 1071 1098 ! Overwrite phase partitioning in boundary layer mixed phase clouds when the 1099 ! iflag_cloudth_vert=7 and specific param is activated 1072 1100 IF (mpc_bl_points(i,k) .GT. 0) THEN 1073 1074 1101 zcond(i) = MAX(0.0,qincloud_mpc(i))*rneb(i,k) 1075 1102 ! following line is very strange and probably wrong … … 1078 1105 zq(i) = zq(i) - zcond(i) 1079 1106 zfice(i)=zfice_th(i) 1080 1081 1107 ELSE 1082 1083 1108 ! Checks on rneb, rhcl and zqn 1084 1109 IF (rneb(i,k) .LE. 0.0) THEN … … 1108 1133 ! following line is very strange and probably wrong: 1109 1134 rhcl(i,k)=(zqs(i)+zq(i))/2./zqs(i) 1135 ! Overwrite partitioning for non shallow-convective clouds if iflag_icefrac>1 (icefrac turb param) 1136 IF (iflag_icefrac .GE. 1) THEN 1137 IF (lognormale(i)) THEN 1138 zcond(i) = zqliq(i) + zqice(i) 1139 zfice(i)=zfice_turb(i) 1140 rhcl(i,k) = zqvapcl(i) * rneb(i,k) + (zq(i) - zqn(i)) * (1.-rneb(i,k)) 1141 ENDIF 1142 ENDIF 1110 1143 ENDIF 1111 1144 … … 1493 1526 znebprecipcld(i)=0.0 1494 1527 ENDIF 1495 1528 !IF ( ((1-zfice(i))*zoliq(i) .GT. 0.) .AND. (zt(i) .LE. 233.15) ) THEN 1529 !print*,'WARNING LEA OLIQ A <-40°C ' 1530 !print*,'zt,Tbef,oliq,oice,cldfraliq,icefrac,rneb',zt(i),Tbef(i),(1-zfice(i))*zoliq(i),zfice(i)*zoliq(i),cldfraliq(i,k),zfice(i),rneb(i,k) 1531 !ENDIF 1496 1532 ENDDO 1497 1533 -
LMDZ6/branches/cirrus/libf/phylmd/lmdz_lscp_ini.F90
r5165 r5202 67 67 !$OMP THREADPRIVATE(iflag_t_glace) 68 68 69 INTEGER, SAVE, PROTECTED :: iflag_cloudth_vert=0 ! option for determining cloud fraction and content in convective boundary layers69 INTEGER, SAVE, PROTECTED :: iflag_cloudth_vert=0 ! option for determining cloud fraction and content in convective boundary layers 70 70 !$OMP THREADPRIVATE(iflag_cloudth_vert) 71 71 72 INTEGER, SAVE, PROTECTED :: iflag_gammasat=0 ! which threshold for homogeneous nucleation below -40oC72 INTEGER, SAVE, PROTECTED :: iflag_gammasat=0 ! which threshold for homogeneous nucleation below -40oC 73 73 !$OMP THREADPRIVATE(iflag_gammasat) 74 74 75 INTEGER, SAVE, PROTECTED :: iflag_rain_incloud_vol=0 ! use of volume cloud fraction for rain autoconversion75 INTEGER, SAVE, PROTECTED :: iflag_rain_incloud_vol=0 ! use of volume cloud fraction for rain autoconversion 76 76 !$OMP THREADPRIVATE(iflag_rain_incloud_vol) 77 77 78 INTEGER, SAVE, PROTECTED :: iflag_bergeron=0 ! bergeron effect for liquid precipitation treatment78 INTEGER, SAVE, PROTECTED :: iflag_bergeron=0 ! bergeron effect for liquid precipitation treatment 79 79 !$OMP THREADPRIVATE(iflag_bergeron) 80 80 81 INTEGER, SAVE, PROTECTED :: iflag_fisrtilp_qsat=0 ! qsat adjustment (iterative) during autoconversion81 INTEGER, SAVE, PROTECTED :: iflag_fisrtilp_qsat=0 ! qsat adjustment (iterative) during autoconversion 82 82 !$OMP THREADPRIVATE(iflag_fisrtilp_qsat) 83 83 84 INTEGER, SAVE, PROTECTED :: iflag_pdf=0 ! type of subgrid scale qtot pdf84 INTEGER, SAVE, PROTECTED :: iflag_pdf=0 ! type of subgrid scale qtot pdf 85 85 !$OMP THREADPRIVATE(iflag_pdf) 86 86 87 INTEGER, SAVE, PROTECTED :: iflag_autoconversion=0 ! autoconversion option 87 INTEGER, SAVE, PROTECTED :: iflag_icefrac=0 ! which phase partitioning function to use 88 !$OMP THREADPRIVATE(iflag_icefrac) 89 90 INTEGER, SAVE, PROTECTED :: iflag_autoconversion=0 ! autoconversion option 88 91 !$OMP THREADPRIVATE(iflag_autoconversion) 89 92 90 LOGICAL, SAVE, PROTECTED :: reevap_ice=.false. ! no liquid precip for T< threshold 93 94 LOGICAL, SAVE, PROTECTED :: reevap_ice=.false. ! no liquid precip for T< threshold 91 95 !$OMP THREADPRIVATE(reevap_ice) 92 96 93 REAL, SAVE, PROTECTED :: cld_lc_lsc=2.6e-4 ! liquid autoconversion coefficient, stratiform rain97 REAL, SAVE, PROTECTED :: cld_lc_lsc=2.6e-4 ! liquid autoconversion coefficient, stratiform rain 94 98 !$OMP THREADPRIVATE(cld_lc_lsc) 95 99 … … 118 122 !$OMP THREADPRIVATE(coef_eva) 119 123 120 REAL, SAVE, PROTECTED :: coef_sub ! tuning coefficient ice precip sublimation124 REAL, SAVE, PROTECTED :: coef_sub ! tuning coefficient ice precip sublimation 121 125 !$OMP THREADPRIVATE(coef_sub) 122 126 … … 124 128 !$OMP THREADPRIVATE(expo_eva) 125 129 126 REAL, SAVE, PROTECTED :: expo_sub ! tuning coefficient ice precip sublimation130 REAL, SAVE, PROTECTED :: expo_sub ! tuning coefficient ice precip sublimation 127 131 !$OMP THREADPRIVATE(expo_sub) 128 132 … … 226 230 !$OMP THREADPRIVATE(thresh_precip_frac) 227 231 232 REAL, SAVE, PROTECTED :: tau_mixenv=100000 ! Homogeneization time of mixed phase clouds [s] 233 !$OMP THREADPRIVATE(tau_mixenv) 234 235 REAL, SAVE, PROTECTED :: capa_crystal=1. ! Sursaturation of ice part in mixed phase clouds [-] 236 !$OMP THREADPRIVATE(capa_crystal) 237 238 REAL, SAVE, PROTECTED :: lmix_mpc=1000 ! Length of turbulent zones in Mixed Phase Clouds [m] 239 !$OMP THREADPRIVATE(lmix_mpc) 240 241 REAL, SAVE, PROTECTED :: naero5=0.5 ! Number concentration of aerosol larger than 0.5 microns [scm-3] 242 !$OMP THREADPRIVATE(naero5) 243 244 REAL, SAVE, PROTECTED :: gamma_snwretro = 0. ! Proportion of snow taken into account in ice retroaction in icefrac_turb [-] 245 !$OMP THREADPRIVATE(gamma_snwretro) 246 247 REAL, SAVE, PROTECTED :: gamma_taud = 1. ! Tuning coeff for tau_dissipturb [-] 248 !$OMP THREADPRIVATE(gamma_taud) 249 228 250 REAL, SAVE, PROTECTED :: gamma_col=1. ! A COMMENTER TODO [-] 229 251 !$OMP THREADPRIVATE(gamma_col) … … 235 257 !$OMP THREADPRIVATE(gamma_rim) 236 258 237 REAL, SAVE, PROTECTED :: rho_rain=1000. ! A COMMENTER TODO[kg/m3]259 REAL, SAVE, PROTECTED :: rho_rain=1000. ! Rain density [kg/m3] 238 260 !$OMP THREADPRIVATE(rho_rain) 239 261 240 REAL, SAVE, PROTECTED :: rho_ice=920. ! A COMMENTER TODO[kg/m3]262 REAL, SAVE, PROTECTED :: rho_ice=920. ! Ice density [kg/m3] 241 263 !$OMP THREADPRIVATE(rho_ice) 242 264 243 REAL, SAVE, PROTECTED :: r_rain=500.E-6 ! A COMMENTER TODO[m]265 REAL, SAVE, PROTECTED :: r_rain=500.E-6 ! Rain droplets radius for POPRECIP [m] 244 266 !$OMP THREADPRIVATE(r_rain) 245 267 246 REAL, SAVE, PROTECTED :: r_snow=1.E-3 ! A COMMENTER TODO[m]268 REAL, SAVE, PROTECTED :: r_snow=1.E-3 ! Ice crystals radius for POPRECIP [m] 247 269 !$OMP THREADPRIVATE(r_snow) 248 270 249 REAL, SAVE, PROTECTED :: tau_auto_snow_min=100. ! A COMMENTER TODO [s]271 REAL, SAVE, PROTECTED :: tau_auto_snow_min=100. ! A COMMENTER TODO [s] 250 272 !$OMP THREADPRIVATE(tau_auto_snow_min) 251 273 … … 256 278 !$OMP THREADPRIVATE(eps) 257 279 258 REAL, SAVE, PROTECTED :: gamma_melt=1. ! A COMMENTER TODO [-]280 REAL, SAVE, PROTECTED :: gamma_melt=1. ! A COMMENTER TODO [-] 259 281 !$OMP THREADPRIVATE(gamma_melt) 260 282 261 REAL, SAVE, PROTECTED :: alpha_freez=4. ! A COMMENTER TODO [-]283 REAL, SAVE, PROTECTED :: alpha_freez=4. ! A COMMENTER TODO [-] 262 284 !$OMP THREADPRIVATE(alpha_freez) 263 285 264 REAL, SAVE, PROTECTED :: beta_freez=0.1 ! A COMMENTER TODO [m-3.s-1]286 REAL, SAVE, PROTECTED :: beta_freez=0.1 ! A COMMENTER TODO [m-3.s-1] 265 287 !$OMP THREADPRIVATE(beta_freez) 266 288 267 REAL, SAVE, PROTECTED :: gamma_freez=1. ! A COMMENTER TODO [-]289 REAL, SAVE, PROTECTED :: gamma_freez=1. ! A COMMENTER TODO [-] 268 290 !$OMP THREADPRIVATE(gamma_freez) 269 291 270 REAL, SAVE, PROTECTED :: rain_fallspeed=4. ! A COMMENTER TODO [m/s]292 REAL, SAVE, PROTECTED :: rain_fallspeed=4. ! A COMMENTER TODO [m/s] 271 293 !$OMP THREADPRIVATE(rain_fallspeed) 272 294 273 REAL, SAVE, PROTECTED :: rain_fallspeed_clr ! A COMMENTER TODO [m/s]295 REAL, SAVE, PROTECTED :: rain_fallspeed_clr ! A COMMENTER TODO [m/s] 274 296 !$OMP THREADPRIVATE(rain_fallspeed_clr) 275 297 276 REAL, SAVE, PROTECTED :: rain_fallspeed_cld ! A COMMENTER TODO [m/s]298 REAL, SAVE, PROTECTED :: rain_fallspeed_cld ! A COMMENTER TODO [m/s] 277 299 !$OMP THREADPRIVATE(rain_fallspeed_cld) 278 300 279 REAL, SAVE, PROTECTED :: snow_fallspeed=1. ! A COMMENTER TODO [m/s]301 REAL, SAVE, PROTECTED :: snow_fallspeed=1. ! A COMMENTER TODO [m/s] 280 302 !$OMP THREADPRIVATE(snow_fallspeed) 281 303 282 REAL, SAVE, PROTECTED :: snow_fallspeed_clr ! A COMMENTER TODO [m/s]304 REAL, SAVE, PROTECTED :: snow_fallspeed_clr ! A COMMENTER TODO [m/s] 283 305 !$OMP THREADPRIVATE(snow_fallspeed_clr) 284 306 285 REAL, SAVE, PROTECTED :: snow_fallspeed_cld ! A COMMENTER TODO [m/s]307 REAL, SAVE, PROTECTED :: snow_fallspeed_cld ! A COMMENTER TODO [m/s] 286 308 !$OMP THREADPRIVATE(snow_fallspeed_cld) 287 309 !--End of the parameters for poprecip … … 325 347 RLMLT=RLMLT_in 326 348 RTT=RTT_in 327 R G=RG_in349 RV=RV_in 328 350 RVTMP2=RVTMP2_in 329 351 RPI=RPI_in … … 347 369 CALL getin_p('iflag_fisrtilp_qsat',iflag_fisrtilp_qsat) 348 370 CALL getin_p('iflag_pdf',iflag_pdf) 371 CALL getin_p('iflag_icefrac',iflag_icefrac) 349 372 CALL getin_p('reevap_ice',reevap_ice) 350 373 CALL getin_p('cld_lc_lsc',cld_lc_lsc) … … 368 391 CALL getin_p('dist_liq',dist_liq) 369 392 CALL getin_p('tresh_cl',tresh_cl) 393 CALL getin_p('tau_mixenv',tau_mixenv) 394 CALL getin_p('capa_crystal',capa_crystal) 395 CALL getin_p('lmix_mpc',lmix_mpc) 396 CALL getin_p('naero5',naero5) 397 CALL getin_p('gamma_snwretro',gamma_snwretro) 398 CALL getin_p('gamma_taud',gamma_taud) 370 399 CALL getin_p('iflag_oldbug_fisrtilp',iflag_oldbug_fisrtilp) 371 400 CALL getin_p('temp_nowater',temp_nowater) … … 430 459 WRITE(lunout,*) 'lscp_ini, iflag_fisrtilp_qsat:', iflag_fisrtilp_qsat 431 460 WRITE(lunout,*) 'lscp_ini, iflag_pdf', iflag_pdf 461 WRITE(lunout,*) 'lscp_ini, iflag_icefrac', iflag_icefrac 432 462 WRITE(lunout,*) 'lscp_ini, reevap_ice', reevap_ice 433 463 WRITE(lunout,*) 'lscp_ini, cld_lc_lsc', cld_lc_lsc … … 448 478 WRITE(lunout,*) 'lscp_ini, dist_liq', dist_liq 449 479 WRITE(lunout,*) 'lscp_ini, tresh_cl', tresh_cl 480 WRITE(lunout,*) 'lscp_ini, tau_mixenv', tau_mixenv 481 WRITE(lunout,*) 'lscp_ini, capa_crystal', capa_crystal 482 WRITE(lunout,*) 'lscp_ini, lmix_mpc', lmix_mpc 483 WRITE(lunout,*) 'lscp_ini, naero5', naero5 484 WRITE(lunout,*) 'lscp_ini, gamma_snwretro', gamma_snwretro 485 WRITE(lunout,*) 'lscp_ini, gamma_taud', gamma_taud 450 486 WRITE(lunout,*) 'lscp_ini, iflag_oldbug_fisrtilp', iflag_oldbug_fisrtilp 451 487 WRITE(lunout,*) 'lscp_ini, fl_cor_ebil', fl_cor_ebil -
LMDZ6/branches/cirrus/libf/phylmd/lmdz_lscp_poprecip.F90
r4974 r5202 559 559 560 560 !--Same as for aggregation 561 !--Eff_snow_liq formula: following Milbrandt and Yau 2005,561 !--Eff_snow_liq formula: 562 562 !--it s a product of a collection efficiency and a sticking efficiency 563 Eff_snow_ice = 0.05 * EXP( 0.1 * ( temp(i) - RTT ) ) 563 ! Milbrandt and Yau formula that gives very low values: 564 ! Eff_snow_ice = 0.05 * EXP( 0.1 * ( temp(i) - RTT ) ) 565 ! Lin 1983's formula 566 Eff_snow_ice = EXP( 0.025 * MIN( ( temp(i) - RTT ), 0.) ) 564 567 !--rho_snow formula follows Brandes et al. 2007 (JAMC) 565 568 rho_snow = 1.e3 * 0.178 * ( r_snow * 2. * 1000. )**(-0.922) … … 653 656 !--NB.: this process needs a temperature adjustment 654 657 655 !--Eff_snow_liq formula: following Seifert and Beheng 2006,656 !--assuming a cloud droplet diameter of 20 microns.657 Eff_snow_liq = 0.2658 !--Eff_snow_liq formula: following Ferrier 1994, 659 !--assuming 1 660 Eff_snow_liq = 1.0 658 661 !--rho_snow formula follows Brandes et al. 2007 (JAMC) 659 662 rho_snow = 1.e3 * 0.178 * ( r_snow * 2. * 1000. )**(-0.922) -
LMDZ6/branches/cirrus/libf/phylmd/lmdz_lscp_tools.F90
r5019 r5202 136 136 CHARACTER (len = 80) :: abort_message 137 137 138 IF ((iflag_t_glace.LT.2) 138 IF ((iflag_t_glace.LT.2)) THEN !.OR. (iflag_t_glace.GT.6)) THEN 139 139 abort_message = 'lscp cannot be used if iflag_t_glace<2 or >6' 140 140 CALL abort_physic(modname,abort_message,1) … … 194 194 195 195 ! with CMIP6 function of temperature at cloud top 196 IF ( iflag_t_glace .EQ. 5) THEN196 IF ((iflag_t_glace .EQ. 5) .OR. (iflag_t_glace .EQ. 7)) THEN 197 197 liqfrac_tmp = (temp(i)-t_glace_min) / (t_glace_max-t_glace_min) 198 198 liqfrac_tmp = MIN(MAX(liqfrac_tmp,0.0),1.0) … … 232 232 ENDIF 233 233 ENDIF 234 234 235 235 236 236 ENDDO ! klon 237 238 237 RETURN 239 238 … … 241 240 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 242 241 242 SUBROUTINE ICEFRAC_LSCP_TURB(klon, dtime, temp, pplay, paprsdn, paprsup, qice_ini, snowcld, qtot_incl, cldfra, tke, tke_dissip, qliq, qvap_cld, qice, icefrac, dicefracdT, cldfraliq, sigma2_icefracturb, mean_icefracturb) 243 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 244 ! Compute the liquid, ice and vapour content (+ice fraction) based 245 ! on turbulence (see Fields 2014, Furtado 2016, Raillard 2025) 246 ! L.Raillard (30/08/24) 247 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 248 249 250 USE lmdz_lscp_ini, ONLY : prt_level, lunout 251 USE lmdz_lscp_ini, ONLY : RCPD, RLSTT, RLVTT, RLMLT, RVTMP2, RTT, RD, RG, RV, RPI 252 USE lmdz_lscp_ini, ONLY : seuil_neb, temp_nowater 253 USE lmdz_lscp_ini, ONLY : tau_mixenv, lmix_mpc, naero5, gamma_snwretro, gamma_taud, capa_crystal 254 USE lmdz_lscp_ini, ONLY : eps 255 256 IMPLICIT NONE 257 258 INTEGER, INTENT(IN) :: klon !--number of horizontal grid points 259 REAL, INTENT(IN) :: dtime !--time step [s] 260 261 REAL, INTENT(IN), DIMENSION(klon) :: temp !--temperature 262 REAL, INTENT(IN), DIMENSION(klon) :: pplay !--pressure in the middle of the layer [Pa] 263 REAL, INTENT(IN), DIMENSION(klon) :: paprsdn !--pressure at the bottom interface of the layer [Pa] 264 REAL, INTENT(IN), DIMENSION(klon) :: paprsup !--pressure at the top interface of the layer [Pa] 265 REAL, INTENT(IN), DIMENSION(klon) :: qtot_incl !--specific total cloud water content, in-cloud content [kg/kg] 266 REAL, INTENT(IN), DIMENSION(klon) :: cldfra !--cloud fraction in gridbox [-] 267 REAL, INTENT(IN), DIMENSION(klon) :: tke !--turbulent kinetic energy [m2/s2] 268 REAL, INTENT(IN), DIMENSION(klon) :: tke_dissip !--TKE dissipation [m2/s3] 269 270 REAL, INTENT(IN), DIMENSION(klon) :: qice_ini !--initial specific ice content gridbox-mean [kg/kg] 271 REAL, INTENT(IN), DIMENSION(klon) :: snowcld 272 REAL, INTENT(OUT), DIMENSION(klon) :: qliq !--specific liquid content gridbox-mean [kg/kg] 273 REAL, INTENT(OUT), DIMENSION(klon) :: qvap_cld !--specific cloud vapor content, gridbox-mean [kg/kg] 274 REAL, INTENT(OUT), DIMENSION(klon) :: qice !--specific ice content gridbox-mean [kg/kg] 275 REAL, INTENT(OUT), DIMENSION(klon) :: icefrac !--fraction of ice in condensed water [-] 276 REAL, INTENT(OUT), DIMENSION(klon) :: dicefracdT 277 278 REAL, INTENT(OUT), DIMENSION(klon) :: cldfraliq !--fraction of cldfra which is liquid only 279 REAL, INTENT(OUT), DIMENSION(klon) :: sigma2_icefracturb !--Temporary 280 REAL, INTENT(OUT), DIMENSION(klon) :: mean_icefracturb !--Temporary 281 282 REAL, DIMENSION(klon) :: qzero, qsatl, dqsatl, qsati, dqsati !--specific humidity saturation values 283 INTEGER :: i 284 285 REAL :: qvap_incl, qice_incl, qliq_incl, qiceini_incl !--In-cloud specific quantities [kg/kg] 286 REAL :: qsnowcld_incl 287 !REAL :: capa_crystal !--Capacitance of ice crystals [-] 288 REAL :: water_vapor_diff !--Water-vapour diffusion coefficient in air [m2/s] (function of T&P) 289 REAL :: air_thermal_conduct !--Thermal conductivity of air [J/m/K/s] (function of T) 290 REAL :: C0 !--Lagrangian structure function [-] 291 REAL :: tau_mixingenv 292 REAL :: tau_dissipturb 293 REAL :: invtau_phaserelax 294 REAL :: sigma2_pdf, mean_pdf 295 REAL :: ai, bi, B0 296 REAL :: sursat_iceliq 297 REAL :: sursat_env 298 REAL :: liqfra_max 299 REAL :: sursat_iceext 300 REAL :: nb_crystals !--number concentration of ice crystals [#/m3] 301 REAL :: moment1_PSD !--1st moment of ice PSD 302 REAL :: N0_PSD, lambda_PSD !--parameters of the exponential PSD 303 304 REAL :: rho_ice !--ice density [kg/m3] 305 REAL :: cldfra1D 306 REAL :: deltaz, rho_air 307 REAL :: psati !--saturation vapor pressure wrt i [Pa] 308 309 C0 = 10. !--value assumed in Field2014 310 rho_ice = 950. 311 sursat_iceext = -0.1 312 !capa_crystal = 1. !r_ice 313 qzero(:) = 0. 314 cldfraliq(:) = 0. 315 icefrac(:) = 0. 316 dicefracdT(:) = 0. 317 318 sigma2_icefracturb(:) = 0. 319 mean_icefracturb(:) = 0. 320 321 !--wrt liquid water 322 CALL calc_qsat_ecmwf(klon,temp(:),qzero(:),pplay(:),RTT,1,.false.,qsatl(:),dqsatl(:)) 323 !--wrt ice 324 CALL calc_qsat_ecmwf(klon,temp(:),qzero(:),pplay(:),RTT,2,.false.,qsati(:),dqsati(:)) 325 326 327 DO i=1,klon 328 329 330 rho_air = pplay(i) / temp(i) / RD 331 !deltaz = ( paprsdn(i) - paprsup(i) ) / RG / rho_air(i) 332 ! because cldfra is intent in, but can be locally modified due to test 333 cldfra1D = cldfra(i) 334 IF (cldfra(i) .LE. 0.) THEN 335 qvap_cld(i) = 0. 336 qliq(i) = 0. 337 qice(i) = 0. 338 cldfraliq(i) = 0. 339 icefrac(i) = 0. 340 dicefracdT(i) = 0. 341 342 ! If there is a cloud 343 ELSE 344 IF (cldfra(i) .GE. 1.0) THEN 345 cldfra1D = 1.0 346 END IF 347 348 ! T>0°C, no ice allowed 349 IF ( temp(i) .GE. RTT ) THEN 350 qvap_cld(i) = qsatl(i) * cldfra1D 351 qliq(i) = MAX(0.0,qtot_incl(i)-qsatl(i)) * cldfra1D 352 qice(i) = 0. 353 cldfraliq(i) = 1. 354 icefrac(i) = 0. 355 dicefracdT(i) = 0. 356 357 ! T<-38°C, no liquid allowed 358 ELSE IF ( temp(i) .LE. temp_nowater) THEN 359 qvap_cld(i) = qsati(i) * cldfra1D 360 qliq(i) = 0. 361 qice(i) = MAX(0.0,qtot_incl(i)-qsati(i)) * cldfra1D 362 cldfraliq(i) = 0. 363 icefrac(i) = 1. 364 dicefracdT(i) = 0. 365 366 ! MPC temperature 367 ELSE 368 ! Not enough TKE 369 IF ( tke_dissip(i) .LE. eps ) THEN 370 qvap_cld(i) = qsati(i) * cldfra1D 371 qliq(i) = 0. 372 qice(i) = MAX(0.,qtot_incl(i)-qsati(i)) * cldfra1D 373 cldfraliq(i) = 0. 374 icefrac(i) = 1. 375 dicefracdT(i) = 0. 376 377 ! Enough TKE 378 ELSE 379 print*,"MOUCHOIRACTIVE" 380 !--------------------------------------------------------- 381 !-- ICE SUPERSATURATION PDF 382 !--------------------------------------------------------- 383 !--If -38°C< T <0°C and there is enough turbulence, 384 !--we compute the cloud liquid properties with a Gaussian PDF 385 !--of ice supersaturation F(Si) (Field2014, Furtado2016). 386 !--Parameters of the PDF are function of turbulence and 387 !--microphysics/existing ice. 388 389 sursat_iceliq = qsatl(i)/qsati(i) - 1. 390 psati = qsati(i) * pplay(i) / (RD/RV) 391 392 !-------------- MICROPHYSICAL TERMS -------------- 393 !--We assume an exponential ice PSD whose parameters 394 !--are computed following Morrison&Gettelman 2008 395 !--Ice number density is assumed equals to INP density 396 !--which is a function of temperature (DeMott 2010) 397 !--bi and B0 are microphysical function characterizing 398 !--vapor/ice interactions 399 !--tau_phase_relax is the typical time of vapor deposition 400 !--onto ice crystals 401 402 qiceini_incl = qice_ini(i) / cldfra1D 403 qsnowcld_incl = snowcld(i) * RG * dtime / ( paprsdn(i) - paprsup(i) ) / cldfra1D 404 sursat_env = max(0., (qtot_incl(i) - qiceini_incl)/qsati(i) - 1.) 405 IF ( qiceini_incl .GT. eps ) THEN 406 nb_crystals = 1.e3 * 5.94e-5 * ( RTT - temp(i) )**3.33 * naero5**(0.0264*(RTT-temp(i))+0.0033) 407 lambda_PSD = ( (RPI*rho_ice*nb_crystals) / (rho_air*(qiceini_incl + gamma_snwretro * qsnowcld_incl)) ) ** (1./3.) 408 N0_PSD = nb_crystals * lambda_PSD 409 moment1_PSD = N0_PSD/lambda_PSD**2 410 ELSE 411 moment1_PSD = 0. 412 ENDIF 413 414 !--Formulae for air thermal conductivity and water vapor diffusivity 415 !--comes respectively from Beard and Pruppacher (1971) 416 !--and Hall and Pruppacher (1976) 417 418 air_thermal_conduct = ( 5.69 + 0.017 * ( temp(i) - RTT ) ) * 1.e-3 * 4.184 419 water_vapor_diff = 2.11*1e-5 * ( temp(i) / RTT )**1.94 * ( 101325 / pplay(i) ) 420 421 bi = 1./((qsati(i)+qsatl(i))/2.) + RLSTT**2 / RCPD / RV / temp(i)**2 422 B0 = 4. * RPI * capa_crystal * 1. / ( RLSTT**2 / air_thermal_conduct / RV / temp(i)**2 & 423 + RV * temp(i) / psati / water_vapor_diff ) 424 425 invtau_phaserelax = (bi * B0 * moment1_PSD ) 426 427 ! Old way of estimating moment1 : spherical crystals + monodisperse PSD 428 ! nb_crystals = rho_air * qiceini_incl / ( 4. / 3. * RPI * r_ice**3. * rho_ice ) 429 ! moment1_PSD = nb_crystals * r_ice 430 431 !----------------- TURBULENT SOURCE/SINK TERMS ----------------- 432 !--Tau_mixingenv is the time needed to homogeneize the parcel 433 !--with its environment by turbulent diffusion over the parcel 434 !--length scale 435 !--if lmix_mpc <0, tau_mixigenv value is prescribed 436 !--else tau_mixigenv value is derived from tke_dissip and lmix_mpc 437 !--Tau_dissipturb is the time needed turbulence to decay due to 438 !--viscosity 439 440 ai = RG / RD / temp(i) * ( RD * RLSTT / RCPD / RV / temp(i) - 1. ) 441 IF ( lmix_mpc .GT. 0 ) THEN 442 tau_mixingenv = ( lmix_mpc**2. / tke_dissip(i) )**(1./3.) 443 ELSE 444 tau_mixingenv = tau_mixenv 445 ENDIF 446 447 tau_dissipturb = gamma_taud * 2. * 2./3. * tke(i) / tke_dissip(i) / C0 448 449 !--------------------- PDF COMPUTATIONS --------------------- 450 !--Formulae for sigma2_pdf (variance), mean of PDF in Furtado2016 451 !--cloud liquid fraction and in-cloud liquid content are given 452 !--by integrating resp. F(Si) and Si*F(Si) 453 !--Liquid is limited by the available water vapor trough a 454 !--maximal liquid fraction 455 456 liqfra_max = MAX(0., (MIN (1.,( qtot_incl(i) - qiceini_incl - qsati(i) * (1 + sursat_iceext ) ) / ( qsatl(i) - qsati(i) ) ) ) ) 457 sigma2_pdf = 1./2. * ( ai**2 ) * 2./3. * tke(i) * tau_dissipturb / ( invtau_phaserelax + 1./tau_mixingenv ) 458 mean_pdf = sursat_env * 1./tau_mixingenv / ( invtau_phaserelax + 1./tau_mixingenv ) 459 cldfraliq(i) = 0.5 * (1. - erf( ( sursat_iceliq - mean_pdf) / (SQRT(2.* sigma2_pdf) ) ) ) 460 IF (cldfraliq(i) .GT. liqfra_max) THEN 461 cldfraliq(i) = liqfra_max 462 ENDIF 463 464 qliq_incl = qsati(i) * SQRT(sigma2_pdf) / SQRT(2.*RPI) * EXP( -1.*(sursat_iceliq - mean_pdf)**2. / (2.*sigma2_pdf) ) & 465 - qsati(i) * cldfraliq(i) * (sursat_iceliq - mean_pdf ) 466 467 sigma2_icefracturb(i)= sigma2_pdf 468 mean_icefracturb(i) = mean_pdf 469 470 !------------ SPECIFIC VAPOR CONTENT AND WATER CONSERVATION ------------ 471 472 IF ( (qliq_incl .LE. eps) .OR. (cldfraliq(i) .LE. eps) ) THEN 473 qliq_incl = 0. 474 cldfraliq(i) = 0. 475 END IF 476 477 !--Specific humidity is the max between qsati and the weighted mean between 478 !--qv in MPC patches and qv in ice-only parts. We assume that MPC parts are 479 !--always at qsatl and ice-only parts slightly subsaturated (qsati*sursat_iceext+1) 480 !--The whole cloud can therefore be supersaturated but never subsaturated. 481 482 qvap_incl = MAX(qsati(i), ( 1. - cldfraliq(i) ) * (sursat_iceext + 1.) * qsati(i) + cldfraliq(i) * qsatl(i) ) 483 484 485 IF ( qvap_incl .GE. qtot_incl(i) ) THEN 486 qvap_incl = qsati(i) 487 qliq_incl = qtot_incl(i) - qvap_incl 488 qice_incl = 0. 489 490 ELSEIF ( (qvap_incl + qliq_incl) .GE. qtot_incl(i) ) THEN 491 qliq_incl = MAX(0.0,qtot_incl(i) - qvap_incl) 492 qice_incl = 0. 493 ELSE 494 qice_incl = qtot_incl(i) - qvap_incl - qliq_incl 495 END IF 496 497 qvap_cld(i) = qvap_incl * cldfra1D 498 qliq(i) = qliq_incl * cldfra1D 499 qice(i) = qice_incl * cldfra1D 500 icefrac(i) = qice(i) / ( qice(i) + qliq(i) ) 501 dicefracdT(i) = 0. 502 !print*,'MPC turb' 503 504 END IF ! Enough TKE 505 506 END IF ! ! MPC temperature 507 508 END IF ! cldfra 509 510 ENDDO ! klon 511 END SUBROUTINE ICEFRAC_LSCP_TURB 512 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 243 513 244 514 -
LMDZ6/branches/cirrus/libf/phylmd/lmdz_thermcell_plume_6A.F90
r4678 r5202 63 63 REAL,dimension(ngrid,nlay) :: zeps 64 64 65 REAL, dimension(ngrid) :: wmaxa (ngrid)65 REAL, dimension(ngrid) :: wmaxa 66 66 67 67 INTEGER ig,l,k,lt,it,lm -
LMDZ6/branches/cirrus/libf/phylmd/ocean_forced_mod.F90
r4523 r5202 22 22 radsol, snow, agesno, & 23 23 qsurf, evap, fluxsens, fluxlat, flux_u1, flux_v1, & 24 tsurf_new, dflux_s, dflux_l, sens_prec_liq, rhoa) 24 tsurf_new, dflux_s, dflux_l, sens_prec_liq, rhoa & 25 #ifdef ISO 26 ,xtprecip_rain, xtprecip_snow, xtspechum,Roce,rlat, & 27 xtsnow,xtevap,h1 & 28 #endif 29 ) 25 30 ! 26 31 ! This subroutine treats the "open ocean", all grid points that are not entierly covered … … 36 41 USE phys_output_var_mod, ONLY : sens_prec_liq_o, sens_prec_sol_o, lat_prec_liq_o, lat_prec_sol_o 37 42 use config_ocean_skin_m, only: activate_ocean_skin 43 #ifdef ISO 44 USE infotrac_phy, ONLY: ntiso,niso 45 USE isotopes_routines_mod, ONLY: calcul_iso_surf_oce_vectall, calcul_iso_surf_sic_vectall 46 #ifdef ISOVERIF 47 USE isotopes_mod, ONLY: iso_eau,ridicule 48 !USE isotopes_verif_mod, ONLY: errmax,errmaxrel,iso_verif_egalite_choix 49 USE isotopes_verif_mod 50 #endif 51 #endif 38 52 39 53 INCLUDE "YOMCST.h" … … 57 71 real, intent(in):: rhoa(:) ! (knon) density of moist air (kg / m3) 58 72 73 #ifdef ISO 74 REAL, DIMENSION(ntiso,klon), INTENT(IN) :: xtprecip_rain, xtprecip_snow 75 REAL, DIMENSION(ntiso,klon), INTENT(IN) :: xtspechum 76 REAL, DIMENSION(klon), INTENT(IN) :: rlat 77 #endif 78 59 79 ! In/Output arguments 60 80 !**************************************************************************************** … … 62 82 REAL, DIMENSION(klon), INTENT(INOUT) :: snow 63 83 REAL, DIMENSION(klon), INTENT(INOUT) :: agesno !? put to 0 in ocean 64 84 #ifdef ISO 85 REAL, DIMENSION(niso,klon), INTENT(IN) :: xtsnow 86 REAL, DIMENSION(niso,klon), INTENT(INOUT):: Roce 87 #endif 88 65 89 ! Output arguments 66 90 !**************************************************************************************** … … 72 96 REAL, intent(out):: sens_prec_liq(:) ! (knon) 73 97 98 #ifdef ISO 99 REAL, DIMENSION(ntiso,klon), INTENT(OUT) :: xtevap ! isotopes in evaporation flux 100 REAL, DIMENSION(klon), INTENT(OUT) :: h1 ! just a diagnostic, not useful for the simulation 101 #endif 102 74 103 ! Local variables 75 104 !**************************************************************************************** … … 80 109 REAL, DIMENSION(klon) :: u1_lay, v1_lay 81 110 LOGICAL :: check=.FALSE. 82 REAL sens_prec_sol(knon) 83 REAL, DIMENSION(klon) :: lat_prec_liq, lat_prec_sol 111 REAL, DIMENSION(knon) :: sens_prec_sol 112 REAL, DIMENSION(klon) :: lat_prec_liq, lat_prec_sol 113 #ifdef ISO 114 REAL, PARAMETER :: t_coup = 273.15 115 #endif 116 84 117 85 118 !**************************************************************************************** … … 87 120 !**************************************************************************************** 88 121 IF (check) WRITE(*,*)' Entering ocean_forced_noice' 89 122 123 #ifdef ISO 124 #ifdef ISOVERIF 125 DO i = 1, knon 126 IF (iso_eau > 0) THEN 127 CALL iso_verif_egalite_choix(xtspechum(iso_eau,i), & 128 & spechum(i),'ocean_forced_mod 111', & 129 & errmax,errmaxrel) 130 CALL iso_verif_egalite_choix(snow(i), & 131 & xtsnow(iso_eau,i),'ocean_forced_mod 117', & 132 & errmax,errmaxrel) 133 ENDIF !IF (iso_eau > 0) THEN 134 ENDDO !DO i=1,knon 135 #endif 136 #endif 137 90 138 !**************************************************************************************** 91 139 ! 1) … … 103 151 104 152 else ! GCM 105 CALL limit_read_sst(knon,knindex,tsurf_lim) 153 CALL limit_read_sst(knon,knindex,tsurf_lim & 154 #ifdef ISO 155 & ,Roce,rlat & 156 #endif 157 & ) 106 158 endif ! knon 107 159 !sb-- … … 161 213 flux_u1, flux_v1) 162 214 215 #ifdef ISO 216 CALL calcul_iso_surf_oce_vectall(klon, knon,t_coup, & 217 & ps,tsurf_new,spechum,u1_lay, v1_lay, xtspechum, & 218 & evap, Roce,xtevap,h1 & 219 #ifdef ISOTRAC 220 & ,knindex & 221 #endif 222 & ) 223 #endif 224 225 #ifdef ISO 226 #ifdef ISOVERIF 227 ! write(*,*) 'ocean_forced_mod 176: sortie de ocean_forced_noice' 228 IF (iso_eau > 0) THEN 229 DO i = 1, knon 230 CALL iso_verif_egalite_choix(snow(i), & 231 & xtsnow(iso_eau,i),'ocean_forced_mod 180', & 232 & errmax,errmaxrel) 233 ENDDO ! DO j=1,knon 234 ENDIF !IF (iso_eau > 0) THEN 235 #endif 236 #endif 237 163 238 END SUBROUTINE ocean_forced_noice 164 239 ! … … 173 248 radsol, snow, qsol, agesno, tsoil, & 174 249 qsurf, alb1_new, alb2_new, evap, fluxsens, fluxlat, flux_u1, flux_v1, & 175 tsurf_new, dflux_s, dflux_l, rhoa) 250 tsurf_new, dflux_s, dflux_l, rhoa & 251 #ifdef ISO 252 ,xtprecip_rain, xtprecip_snow, xtspechum,Roce, & 253 xtsnow, xtsol,xtevap,Rland_ice & 254 #endif 255 ) 176 256 ! 177 257 ! This subroutine treats the ocean where there is ice. … … 187 267 USE indice_sol_mod 188 268 USE phys_output_var_mod, ONLY : sens_prec_liq_o, sens_prec_sol_o, lat_prec_liq_o, lat_prec_sol_o 269 #ifdef ISO 270 USE infotrac_phy, ONLY: niso, ntiso 271 USE isotopes_routines_mod, ONLY: calcul_iso_surf_oce_vectall, calcul_iso_surf_sic_vectall 272 #ifdef ISOVERIF 273 USE isotopes_mod, ONLY: iso_eau,ridicule 274 !USE isotopes_verif_mod, ONLY: errmax,errmaxrel,iso_verif_egalite_choix 275 USE isotopes_verif_mod 276 #endif 277 #endif 189 278 190 279 ! INCLUDE "indicesol.h" … … 209 298 REAL, DIMENSION(klon), INTENT(IN) :: u1, v1, gustiness 210 299 real, intent(in):: rhoa(:) ! (knon) density of moist air (kg / m3) 300 #ifdef ISO 301 REAL, DIMENSION(ntiso,klon), INTENT(IN) :: xtprecip_rain, xtprecip_snow 302 REAL, DIMENSION(ntiso,klon), INTENT(IN) :: xtspechum 303 REAL, DIMENSION(niso,klon), INTENT(IN) :: Roce 304 REAL, DIMENSION(niso,klon), INTENT(IN) :: Rland_ice 305 #endif 211 306 212 307 ! In/Output arguments … … 216 311 REAL, DIMENSION(klon), INTENT(INOUT) :: agesno 217 312 REAL, DIMENSION(klon, nsoilmx), INTENT(INOUT) :: tsoil 313 #ifdef ISO 314 REAL, DIMENSION(niso,klon), INTENT(INOUT) :: xtsnow 315 REAL, DIMENSION(niso,klon), INTENT(IN) :: xtsol 316 #endif 218 317 219 318 ! Output arguments … … 226 325 REAL, DIMENSION(klon), INTENT(OUT) :: tsurf_new 227 326 REAL, DIMENSION(klon), INTENT(OUT) :: dflux_s, dflux_l 327 #ifdef ISO 328 REAL, DIMENSION(ntiso,klon), INTENT(OUT) :: xtevap 329 #endif 228 330 229 331 ! Local variables … … 238 340 REAL, DIMENSION(klon) :: u0, v0 239 341 REAL, DIMENSION(klon) :: u1_lay, v1_lay 240 REAL sens_prec_liq(knon), sens_prec_sol (knon)342 REAL, DIMENSION(knon) :: sens_prec_liq, sens_prec_sol 241 343 REAL, DIMENSION(klon) :: lat_prec_liq, lat_prec_sol 242 344 345 #ifdef ISO 346 REAL, PARAMETER :: t_coup = 273.15 347 REAL, DIMENSION(klon) :: fq_fonte_diag 348 REAL, DIMENSION(klon) :: fqfonte_diag 349 REAL, DIMENSION(klon) :: snow_evap_diag 350 REAL, DIMENSION(klon) :: fqcalving_diag 351 REAL, DIMENSION(klon) :: run_off_lic_diag 352 REAL :: coeff_rel_diag 353 REAL :: max_eau_sol_diag 354 REAL, DIMENSION(klon) :: runoff_diag 355 INTEGER IXT 356 REAL, DIMENSION(niso,klon) :: xtsnow_prec, xtsol_prec 357 REAL, DIMENSION(klon) :: snow_prec, qsol_prec 358 #endif 243 359 244 360 !**************************************************************************************** … … 307 423 ! 308 424 !**************************************************************************************** 425 #ifdef ISO 426 ! verif 427 #ifdef ISOVERIF 428 DO i = 1, knon 429 IF (iso_eau > 0) THEN 430 IF (snow(i) > ridicule) THEN 431 CALL iso_verif_egalite_choix(xtsnow(iso_eau,i),snow(i), & 432 & 'interfsurf 964',errmax,errmaxrel) 433 ENDIF !IF ((snow(i) > ridicule)) THEN 434 ENDIF !IF (iso_eau > 0) THEN 435 ENDDO !DO i=1,knon 436 #endif 437 ! end verif 438 439 DO i = 1, knon 440 snow_prec(i) = snow(i) 441 DO ixt = 1, niso 442 xtsnow_prec(ixt,i) = xtsnow(ixt,i) 443 ENDDO !DO ixt=1,niso 444 ! initialisation: 445 fq_fonte_diag(i) = 0.0 446 fqfonte_diag(i) = 0.0 447 snow_evap_diag(i)= 0.0 448 ENDDO !DO i=1,knon 449 #endif 450 451 309 452 CALL fonte_neige( knon, is_sic, knindex, dtime, & 310 453 tsurf_tmp, precip_rain, precip_snow, & 311 snow, qsol, tsurf_new, evap) 454 snow, qsol, tsurf_new, evap & 455 #ifdef ISO 456 & ,fq_fonte_diag,fqfonte_diag,snow_evap_diag,fqcalving_diag & 457 & ,max_eau_sol_diag,runoff_diag,run_off_lic_diag,coeff_rel_diag & 458 #endif 459 & ) 460 461 462 #ifdef ISO 463 ! isotopes: tout est externalisé 464 !#ifdef ISOVERIF 465 ! write(*,*) 'ocean_forced_mod 377: call calcul_iso_surf_sic_vectall' 466 ! write(*,*) 'klon,knon=',klon,knon 467 !#endif 468 CALL calcul_iso_surf_sic_vectall(klon,knon, & 469 & evap,snow_evap_diag,Tsurf_new,Roce,snow, & 470 & fq_fonte_diag,fqfonte_diag,dtime,t_coup, & 471 & precip_snow,xtprecip_snow,xtprecip_rain, snow_prec,xtsnow_prec, & 472 & xtspechum,spechum,ps, & 473 & xtevap,xtsnow,fqcalving_diag, & 474 & knindex,is_sic,run_off_lic_diag,coeff_rel_diag,Rland_ice & 475 & ) 476 #ifdef ISOVERIF 477 !write(*,*) 'ocean_forced_mod 391: sortie calcul_iso_surf_sic_vectall' 478 IF (iso_eau > 0) THEN 479 DO i = 1, knon 480 CALL iso_verif_egalite_choix(snow(i), & 481 & xtsnow(iso_eau,i),'ocean_forced_mod 396', & 482 & errmax,errmaxrel) 483 ENDDO ! DO j=1,knon 484 ENDIF !IF (iso_eau > 0) then 485 #endif 486 !#ifdef ISOVERIF 487 #endif 488 !#ifdef ISO 312 489 313 490 ! Calculation of albedo at snow (alb_neig) and update the age of snow (agesno) -
LMDZ6/branches/cirrus/libf/phylmd/pbl_surface_mod.F90
r4916 r5202 33 33 wx_pbl_check, wx_pbl_dts_check, wx_evappot 34 34 use config_ocean_skin_m, only: activate_ocean_skin 35 #ifdef ISO 36 USE infotrac_phy, ONLY: niso,ntraciso=>ntiso 37 #endif 35 38 36 39 IMPLICIT NONE … … 49 52 !$OMP THREADPRIVATE(ydTs0, ydqs0) 50 53 54 #ifdef ISO 55 REAL, ALLOCATABLE, DIMENSION(:,:,:), PRIVATE, SAVE :: xtsnow ! snow at surface 56 !$OMP THREADPRIVATE(xtsnow) 57 REAL, ALLOCATABLE, DIMENSION(:,:), PRIVATE, SAVE :: Rland_ice ! snow at surface 58 !$OMP THREADPRIVATE(Rland_ice) 59 REAL, ALLOCATABLE, DIMENSION(:,:), PRIVATE, SAVE :: Roce ! snow at surface 60 !$OMP THREADPRIVATE(Roce) 61 #endif 62 51 63 INTEGER, SAVE :: iflag_pbl_surface_t2m_bug 52 64 !$OMP THREADPRIVATE(iflag_pbl_surface_t2m_bug) 53 65 INTEGER, SAVE :: iflag_new_t2mq2m 54 66 !$OMP THREADPRIVATE(iflag_new_t2mq2m) 67 LOGICAL, SAVE :: ok_bug_zg_wk_pbl 68 !$OMP THREADPRIVATE(ok_bug_zg_wk_pbl) 55 69 56 70 !FC … … 176 190 177 191 END SUBROUTINE pbl_surface_init 192 193 #ifdef ISO 194 SUBROUTINE pbl_surface_init_iso(xtsnow_rst,Rland_ice_rst) 195 196 ! This routine should be called after the restart file has been read. 197 ! This routine initialize the restart variables and does some validation tests 198 ! for the index of the different surfaces and tests the choice of type of ocean. 199 200 USE indice_sol_mod 201 USE print_control_mod, ONLY: lunout 202 #ifdef ISOVERIF 203 USE isotopes_mod, ONLY: iso_eau,ridicule 204 USE isotopes_verif_mod 205 #endif 206 IMPLICIT NONE 207 208 INCLUDE "dimsoil.h" 209 210 ! Input variables 211 !**************************************************************************************** 212 REAL, DIMENSION(niso,klon, nbsrf), INTENT(IN) :: xtsnow_rst 213 REAL, DIMENSION(niso,klon), INTENT(IN) :: Rland_ice_rst 214 215 ! Local variables 216 !**************************************************************************************** 217 INTEGER :: ierr 218 CHARACTER(len=80) :: abort_message 219 CHARACTER(len = 20) :: modname = 'pbl_surface_init' 220 integer i,ixt 221 222 !**************************************************************************************** 223 ! Allocate and initialize module variables with fields read from restart file. 224 ! 225 !**************************************************************************************** 226 227 ALLOCATE(xtsnow(niso,klon,nbsrf), stat=ierr) 228 IF (ierr /= 0) CALL abort_gcm('pbl_surface_init', 'pb in allocation',1) 229 230 ALLOCATE(Rland_ice(niso,klon), stat=ierr) 231 IF (ierr /= 0) CALL abort_gcm('pbl_surface_init', 'pb in allocation',1) 232 233 ALLOCATE(Roce(niso,klon), stat=ierr) 234 IF (ierr /= 0) CALL abort_gcm('pbl_surface_init', 'pb in allocation',1) 235 236 xtsnow(:,:,:) = xtsnow_rst(:,:,:) 237 Rland_ice(:,:) = Rland_ice_rst(:,:) 238 Roce(:,:) = 0.0 239 240 #ifdef ISOVERIF 241 IF (iso_eau >= 0) THEN 242 CALL iso_verif_egalite_vect2D( & 243 & xtsnow,snow, & 244 & 'pbl_surface_mod 170',niso,klon,nbsrf) 245 DO i=1,klon 246 IF (iso_eau >= 0) THEN 247 CALL iso_verif_egalite(Rland_ice(iso_eau,i),1.0, & 248 & 'pbl_surf_mod 177') 249 ENDIF 250 ENDDO 251 ENDIF 252 #endif 253 254 END SUBROUTINE pbl_surface_init_iso 255 #endif 256 178 257 ! 179 258 !**************************************************************************************** … … 239 318 !FC 240 319 !!! 241 ) 320 #ifdef ISO 321 & ,xtrain_f, xtsnow_f,xt, & 322 & wake_dlxt,zxxtevap,xtevap, & 323 & d_xt,d_xt_w,d_xt_x, & 324 & xtsol,dflux_xt,zxxtsnow,zxfluxxt,flux_xt, & 325 & h1_diag,runoff_diag,xtrunoff_diag & 326 #endif 327 & ) 242 328 !**************************************************************************************** 243 329 ! Auteur(s) Z.X. Li (LMD/CNRS) date: 19930818 … … 314 400 USE mod_grid_phy_lmdz, ONLY : nbp_lon, nbp_lat, grid1dto2d_glo 315 401 USE print_control_mod, ONLY : prt_level,lunout 402 #ifdef ISO 403 USE isotopes_mod, ONLY: Rdefault,iso_eau 404 #ifdef ISOVERIF 405 USE isotopes_verif_mod 406 #endif 407 #ifdef ISOTRAC 408 USE isotrac_mod, only: index_iso 409 #endif 410 #endif 316 411 USE ioipsl_getin_p_mod, ONLY : getin_p 317 412 use phys_state_var_mod, only: ds_ns, dt_ns, delta_sst, delta_sal, dter, & … … 366 461 REAL, DIMENSION(klon), INTENT(IN) :: gustiness ! gustiness 367 462 368 REAL, DIMENSION(klon), INTENT(IN) :: cldt ! total cloud fraction 463 REAL, DIMENSION(klon), INTENT(IN) :: cldt ! total cloud 464 465 #ifdef ISO 466 REAL, DIMENSION(ntraciso,klon,klev), INTENT(IN) :: xt ! water vapour (kg/kg) 467 REAL, DIMENSION(ntraciso,klon), INTENT(IN) :: xtrain_f ! rain fall 468 REAL, DIMENSION(ntraciso,klon), INTENT(IN) :: xtsnow_f ! snow fall 469 #endif 369 470 370 471 !!! nrlmd+jyg le 02/05/2011 et le 20/02/2012 … … 379 480 REAL, DIMENSION(klon), INTENT(IN) :: wake_dens 380 481 !!! 381 482 #ifdef ISO 483 REAL, DIMENSION(ntraciso,klon,klev), INTENT(IN) :: wake_dlxt 484 #endif 382 485 ! Input/Output variables 383 486 !**************************************************************************************** … … 448 551 REAL, INTENT(OUT):: zcoefm(:, :, :) ! (klon, klev, nbsrf + 1) 449 552 ! coef for turbulent diffusion of U and V (?), mean for each grid point 553 #ifdef ISO 554 REAL, DIMENSION(ntraciso,klon), INTENT(OUT) :: zxxtevap ! water vapour flux at surface, positiv upwards 555 REAL, DIMENSION(ntraciso,klon, klev), INTENT(OUT) :: d_xt ! change in water vapour 556 REAL, DIMENSION(klon), INTENT(OUT) :: runoff_diag 557 REAL, DIMENSION(niso,klon), INTENT(OUT) :: xtrunoff_diag 558 REAL, DIMENSION(ntraciso,klon,klev), INTENT(OUT) :: d_xt_w 559 REAL, DIMENSION(ntraciso,klon,klev), INTENT(OUT) :: d_xt_x 560 #endif 561 562 450 563 451 564 !!! nrlmd+jyg le 02/05/2011 et le 20/02/2012 … … 511 624 REAL, DIMENSION(klon, klev, nbsrf), INTENT(OUT) :: flux_v ! v wind tension (kg m/s)/(m**2 s) or Pascal 512 625 !FC 513 REAL, DIMENSION(klon, klev, nbsrf), INTENT(INOUT) :: treedrg ! tree drag (m) 626 REAL, DIMENSION(klon, klev, nbsrf), INTENT(INOUT) :: treedrg ! tree drag (m) 627 #ifdef ISO 628 REAL, DIMENSION(niso,klon), INTENT(OUT) :: xtsol ! water height in the soil (mm) 629 REAL, DIMENSION(ntraciso,klon, nbsrf) :: xtevap ! evaporation at surface 630 REAL, DIMENSION(klon), INTENT(OUT) :: h1_diag ! just diagnostic, not useful 631 #endif 514 632 515 633 … … 525 643 REAL, DIMENSION(klon, klev, nbsrf), INTENT(OUT) :: flux_qbs ! blowind snow vertical flux (kg/m**2 526 644 645 #ifdef ISO 646 REAL, DIMENSION(ntraciso,klon), INTENT(OUT) :: dflux_xt ! change of water vapour flux 647 REAL, DIMENSION(niso,klon), INTENT(OUT) :: zxxtsnow ! snow at surface, mean for each grid point 648 REAL, DIMENSION(ntraciso,klon, klev), INTENT(OUT) :: zxfluxxt ! water vapour flux, mean for each grid point 649 REAL, DIMENSION(ntraciso,klon, klev, nbsrf), INTENT(OUT) :: flux_xt ! water vapour flux(latent flux) (kg/m**2/s) 650 #endif 527 651 528 652 ! Martin … … 573 697 REAL, DIMENSION(klon) :: ysnow, yqsurf, yagesno, yqsol 574 698 REAL, DIMENSION(klon) :: yrain_f, ysnow_f, ybs_f 699 #ifdef ISO 700 REAL, DIMENSION(ntraciso,klon) :: yxt1 701 REAL, DIMENSION(niso,klon) :: yxtsnow, yxtsol 702 REAL, DIMENSION(ntraciso,klon) :: yxtrain_f, yxtsnow_f 703 REAL, DIMENSION(klon) :: yrunoff_diag 704 REAL, DIMENSION(niso,klon) :: yxtrunoff_diag 705 REAL, DIMENSION(niso,klon) :: yRland_ice 706 #endif 575 707 REAL, DIMENSION(klon) :: ysolsw, ysollw 576 708 REAL, DIMENSION(klon) :: yfder … … 581 713 REAL, DIMENSION(klon) :: y_flux_t1, y_flux_q1 582 714 REAL, DIMENSION(klon) :: y_dflux_t, y_dflux_q 715 #ifdef ISO 716 REAL, DIMENSION(ntraciso,klon) :: y_flux_xt1 717 REAL, DIMENSION(ntraciso,klon) :: y_dflux_xt 718 #endif 583 719 REAL, DIMENSION(klon) :: y_flux_u1, y_flux_v1 584 720 REAL, DIMENSION(klon) :: y_flux_bs, y_flux0 … … 608 744 REAL, DIMENSION(klon) :: AcoefH_0, AcoefQ_0, BcoefH_0, BcoefQ_0 609 745 REAL, DIMENSION(klon) :: AcoefH, AcoefQ, BcoefH, BcoefQ 746 #ifdef ISO 747 REAL, DIMENSION(ntraciso,klon) :: AcoefXT, BcoefXT 748 #endif 610 749 REAL, DIMENSION(klon) :: AcoefU, AcoefV, BcoefU, BcoefV 611 750 REAL, DIMENSION(klon) :: AcoefQBS, BcoefQBS … … 626 765 REAL, DIMENSION(klon,klev) :: yu, yv 627 766 REAL, DIMENSION(klon,klev) :: yt, yq, yqbs 767 #ifdef ISO 768 REAL, DIMENSION(ntraciso,klon) :: yxtevap 769 REAL, DIMENSION(ntraciso,klon,klev) :: y_d_xt 770 REAL, DIMENSION(ntraciso,klon,klev) :: y_flux_xt 771 REAL, DIMENSION(ntraciso,klon,klev) :: yxt 772 #endif 628 773 REAL, DIMENSION(klon,klev) :: ypplay, ydelp 629 774 REAL, DIMENSION(klon,klev) :: delp … … 697 842 REAL, DIMENSION(klon,klev) :: Kcoef_hq_w, Kcoef_m_w, gama_h_w, gama_q_w 698 843 REAL, DIMENSION(klon) :: alf_1, alf_2, alf_1_x, alf_2_x, alf_1_w, alf_2_w 844 #ifdef ISO 845 REAL, DIMENSION(ntraciso,klon,klev) :: yxt_x, yxt_w 846 REAL, DIMENSION(ntraciso,klon) :: y_flux_xt1_x , y_flux_xt1_w 847 REAL, DIMENSION(ntraciso,klon,klev) :: y_flux_xt_x,y_d_xt_x,zxfluxxt_x 848 REAL, DIMENSION(ntraciso,klon,klev) :: y_flux_xt_w,y_d_xt_w,zxfluxxt_w 849 REAL, DIMENSION(ntraciso,klon,klev,nbsrf) :: flux_xt_x, flux_xt_w 850 REAL, DIMENSION(ntraciso,klon) :: AcoefXT_x, BcoefXT_x 851 REAL, DIMENSION(ntraciso,klon) :: AcoefXT_w, BcoefXT_w 852 REAL, DIMENSION(ntraciso,klon,klev) :: CcoefXT, DcoefXT 853 REAL, DIMENSION(ntraciso,klon,klev) :: CcoefXT_x, DcoefXT_x 854 REAL, DIMENSION(ntraciso,klon,klev) :: CcoefXT_w, DcoefXT_w 855 REAL, DIMENSION(ntraciso,klon,klev) :: gama_xt,gama_xt_x,gama_xt_w 856 #endif 699 857 !!! 700 858 !!!jyg le 08/02/2012 … … 889 1047 REAL, DIMENSION(klon) :: yrmu0 890 1048 ! Martin 891 REAL, DIMENSIO n(klon) :: yri01049 REAL, DIMENSION(klon) :: yri0 892 1050 893 1051 REAL, DIMENSION(klon):: ydelta_sst, ydelta_sal, yds_ns, ydt_ns, ydter, & … … 896 1054 ! dt_ds, tkt, tks, taur, sss on ocean points 897 1055 REAL :: missing_val 1056 #ifdef ISO 1057 REAL, DIMENSION(klon) :: h1 1058 INTEGER :: ixt 1059 !#ifdef ISOVERIF 1060 ! integer iso_verif_positif_nostop 1061 !#endif 1062 #endif 1063 898 1064 !**************************************************************************************** 899 1065 ! End of declarations … … 924 1090 iflag_split = iflag_split_ref 925 1091 1092 #ifdef ISO 1093 #ifdef ISOVERIF 1094 DO i=1,klon 1095 DO ixt=1,niso 1096 CALL iso_verif_noNaN(xtsol(ixt,i),'pbl_surface 608') 1097 ENDDO 1098 ENDDO 1099 #endif 1100 #ifdef ISOVERIF 1101 DO i=1,klon 1102 IF (iso_eau >= 0) THEN 1103 CALL iso_verif_egalite_choix(Rland_ice(iso_eau,i),1.0, & 1104 & 'pbl_surf_mod 585',errmax,errmaxrel) 1105 CALL iso_verif_egalite_choix(xtsnow_f(iso_eau,i),snow_f(i), & 1106 & 'pbl_surf_mod 594',errmax,errmaxrel) 1107 IF (iso_verif_egalite_choix_nostop(xtsol(iso_eau,i),qsol(i), & 1108 & 'pbl_surf_mod 596',errmax,errmaxrel) == 1) THEN 1109 WRITE(*,*) 'i=',i 1110 STOP 1111 ENDIF 1112 DO nsrf=1,nbsrf 1113 CALL iso_verif_egalite_choix(xtsnow(iso_eau,i,nsrf),snow(i,nsrf), & 1114 & 'pbl_surf_mod 598',errmax,errmaxrel) 1115 ENDDO 1116 ENDIF !IF (iso_eau >= 0) THEN 1117 ENDDO !DO i=1,knon 1118 DO k=1,klev 1119 DO i=1,klon 1120 IF (iso_eau >= 0) THEN 1121 CALL iso_verif_egalite_choix(xt(iso_eau,i,k),q(i,k), & 1122 & 'pbl_surf_mod 595',errmax,errmaxrel) 1123 ENDIF !IF (iso_eau >= 0) THEN 1124 ENDDO !DO i=1,knon 1125 ENDDO !DO k=1,klev 1126 #endif 1127 #endif 1128 1129 926 1130 !**************************************************************************************** 927 1131 ! 1) Initialisation and validation tests … … 935 1139 CALL getin_p('iflag_new_t2mq2m',iflag_new_t2mq2m) 936 1140 WRITE(lunout,*) 'pbl_iflag_new_t2mq2m=',iflag_new_t2mq2m 1141 1142 ok_bug_zg_wk_pbl=.TRUE. 1143 CALL getin_p('ok_bug_zg_wk_pbl',ok_bug_zg_wk_pbl) 1144 WRITE(lunout,*) 'ok_bug_zg_wk_pbl=',ok_bug_zg_wk_pbl 937 1145 938 1146 print*,'PBL SURFACE AVEC GUSTINESS' … … 984 1192 PRINT*,'WARNING : On impose qsol=',qsol0 985 1193 qsol(:)=qsol0 1194 #ifdef ISO 1195 DO ixt=1,niso 1196 xtsol(ixt,:)=qsol0*Rdefault(ixt) 1197 ENDDO 1198 #ifdef ISOTRAC 1199 DO ixt=1+niso,ntraciso 1200 xtsol(ixt,:)=qsol0*Rdefault(index_iso(ixt)) 1201 ENDDO 1202 #endif 1203 #endif 986 1204 ENDIF 987 1205 !**************************************************************************************** … … 1034 1252 qsnow(:)=0. ; snowhgt(:)=0. ; to_ice(:)=0. ; sissnow(:)=0. 1035 1253 runoff(:)=0. 1254 #ifdef ISO 1255 zxxtevap(:,:)=0. 1256 d_xt(:,:,:)=0. 1257 d_xt_x(:,:,:)=0. 1258 d_xt_w(:,:,:)=0. 1259 flux_xt(:,:,:,:)=0. 1260 ! xtsnow(:,:,:)=0.! attention, xtsnow est l'équivalent de snow et non de qsnow 1261 xtevap(:,:,:)=0. 1262 #endif 1036 1263 IF (iflag_pbl<20.or.iflag_pbl>=30) THEN 1037 1264 zcoefh(:,:,:) = 0.0 … … 1123 1350 !FC 1124 1351 1352 #ifdef ISO 1353 yxtrain_f = 0.0 ; yxtsnow_f = 0.0 1354 yxtsnow = 0.0 1355 yxt = 0.0 1356 yxtsol = 0.0 1357 flux_xt = 0.0 1358 yRland_ice = 0.0 1359 ! d_xt = 0.0 1360 y_dflux_xt = 0.0 1361 dflux_xt=0.0 1362 y_d_xt_x=0. ; y_d_xt_w=0. 1363 #endif 1364 1125 1365 ! >> PC 1126 1366 !the yfields_out variable is defined in (klon,nbcf_out) even if it is used on … … 1149 1389 fluxlat_x(:,:)=0. ; fluxlat_w(:,:)=0. 1150 1390 !>jyg 1391 #ifdef ISO 1392 flux_xt_x(:,:,:,:)=0. ; flux_xt_w(:,:,:,:)=0. 1393 #endif 1151 1394 ! 1152 1395 !jyg< … … 1448 1691 yfluxbs(j)=0.0 1449 1692 y_flux_bs(j) = 0.0 1693 !!! 1694 #ifdef ISO 1695 DO ixt=1,ntraciso 1696 yxtrain_f(ixt,j) = xtrain_f(ixt,i) 1697 yxtsnow_f(ixt,j) = xtsnow_f(ixt,i) 1698 ENDDO 1699 DO ixt=1,niso 1700 yxtsnow(ixt,j) = xtsnow(ixt,i,nsrf) 1701 ENDDO 1702 !IF (nsrf == is_lic) THEN 1703 DO ixt=1,niso 1704 yRland_ice(ixt,j)= Rland_ice(ixt,i) 1705 ENDDO 1706 !endif !IF (nsrf == is_lic) THEN 1707 #ifdef ISOVERIF 1708 IF (iso_eau >= 0) THEN 1709 call iso_verif_egalite_choix(ysnow_f(j), & 1710 & yxtsnow_f(iso_eau,j),'pbl_surf_mod 862', & 1711 & errmax,errmaxrel) 1712 call iso_verif_egalite_choix(ysnow(j), & 1713 & yxtsnow(iso_eau,j),'pbl_surf_mod 872', & 1714 & errmax,errmaxrel) 1715 ENDIF 1716 #endif 1717 #ifdef ISOVERIF 1718 DO ixt=1,ntraciso 1719 call iso_verif_noNaN(yxtsnow_f(ixt,j),'pbl_surf_mod 921') 1720 ENDDO 1721 #endif 1722 #endif 1450 1723 ENDDO 1451 1724 ! >> PC … … 1487 1760 yq(j,k) = q(i,k) 1488 1761 yqbs(j,k)=qbs(i,k) 1762 #ifdef ISO 1763 DO ixt=1,ntraciso 1764 yxt(ixt,j,k) = xt(ixt,i,k) 1765 ENDDO !DO ixt=1,ntraciso 1766 #endif 1489 1767 ENDDO 1490 1768 ENDDO … … 1504 1782 yq_w(j,k) = q(i,k)+(1.-wake_s(i))*wake_dlq(i,k) 1505 1783 !!! 1784 #ifdef ISO 1785 DO ixt=1,ntraciso 1786 yxt_x(ixt,j,k) = xt(ixt,i,k)-wake_s(i)*wake_dlxt(ixt,i,k) 1787 yxt_w(ixt,j,k) = xt(ixt,i,k)+(1.-wake_s(i))*wake_dlxt(ixt,i,k) 1788 ENDDO 1789 #endif 1506 1790 ENDDO 1507 1791 ENDDO … … 1559 1843 i = ni(j) 1560 1844 yqsol(j) = qsol(i) 1845 #ifdef ISO 1846 DO ixt=1,niso 1847 yxtsol(ixt,j) = xtsol(ixt,i) 1848 ENDDO 1849 #endif 1561 1850 ENDDO 1562 1851 ENDIF … … 1664 1953 ycdragm_w, ycdragh_w, zri1_w, pref_w, rain_f, zxtsol, ypplay(:,1) ) 1665 1954 ! 1666 !!!bug !! zgeo1(:) = wake_s(:)*zgeo1_w(:) + (1.-wake_s(:))*zgeo1_x(:) 1667 zgeo1(1:knon) = wake_s(1:knon)*zgeo1_w(1:knon) + (1.-wake_s(1:knon))*zgeo1_x(1:knon) 1955 IF(ok_bug_zg_wk_pbl) THEN 1956 zgeo1(1:knon) = wake_s(1:knon)*zgeo1_w(1:knon) + (1.-wake_s(1:knon))*zgeo1_x(1:knon) 1957 ELSE 1958 zgeo1(1:knon) = ywake_s(1:knon)*zgeo1_w(1:knon) + (1.-ywake_s(1:knon))*zgeo1_x(1:knon) 1959 ENDIF 1668 1960 1669 1961 ! --- special Dice. JYG+MPL 25112013 puis BOMEX … … 1704 1996 1705 1997 IF (iflag_pbl>=50) THEN 1706 CALL call_atke(dtime,knon,klev, ycdragm(1:knon), ycdragh(1:knon),yus0(1:knon),yvs0(1:knon),yts(1:knon), &1998 CALL call_atke(dtime,knon,klev,nsrf,ni,ycdragm(1:knon), ycdragh(1:knon),yus0(1:knon),yvs0(1:knon),yts(1:knon), & 1707 1999 yu(1:knon,:),yv(1:knon,:),yt(1:knon,:),yq(1:knon,:),ypplay(1:knon,:),ypaprs(1:knon,:), & 1708 2000 ytke(1:knon,:),yeps(1:knon,:), ycoefm(1:knon,:), ycoefh(1:knon,:)) … … 1749 2041 IF (iflag_pbl>=50) THEN 1750 2042 1751 CALL call_atke(dtime,knon,klev, ycdragm_x(1:knon),ycdragh_x(1:knon),yus0(1:knon),yvs0(1:knon),yts_x(1:knon), &2043 CALL call_atke(dtime,knon,klev,nsrf,ni,ycdragm_x(1:knon),ycdragh_x(1:knon),yus0(1:knon),yvs0(1:knon),yts_x(1:knon), & 1752 2044 yu_x(1:knon,:),yv_x(1:knon,:),yt_x(1:knon,:),yq_x(1:knon,:),ypplay(1:knon,:),ypaprs(1:knon,:), & 1753 2045 ytke_x(1:knon,:),yeps_x(1:knon,:),ycoefm_x(1:knon,:), ycoefh_x(1:knon,:)) … … 1789 2081 IF (iflag_pbl>=50) THEN 1790 2082 1791 CALL call_atke(dtime,knon,klev, ycdragm_w(1:knon),ycdragh_w(1:knon),yus0(1:knon),yvs0(1:knon),yts_w(1:knon), &2083 CALL call_atke(dtime,knon,klev,nsrf,ni,ycdragm_w(1:knon),ycdragh_w(1:knon),yus0(1:knon),yvs0(1:knon),yts_w(1:knon), & 1792 2084 yu_w(1:knon,:),yv_w(1:knon,:),yt_w(1:knon,:),yq_w(1:knon,:),ypplay(1:knon,:),ypaprs(1:knon,:), & 1793 2085 ytke_w(1:knon,:),yeps_w(1:knon,:),ycoefm_w(1:knon,:),ycoefh_w(1:knon,:)) … … 1850 2142 Kcoef_hq, gama_q, gama_h, & 1851 2143 !!! 1852 AcoefH, AcoefQ, BcoefH, BcoefQ) 2144 AcoefH, AcoefQ, BcoefH, BcoefQ & 2145 #ifdef ISO 2146 & ,yxt, CcoefXT, DcoefXT, gama_xt, AcoefXT, BcoefXT & 2147 #endif 2148 & ) 1853 2149 ELSE !(iflag_split .eq.0) 1854 2150 CALL climb_hq_down(knon, ycoefh_x, ypaprs, ypplay, & … … 1858 2154 Kcoef_hq_x, gama_q_x, gama_h_x, & 1859 2155 !!! 1860 AcoefH_x, AcoefQ_x, BcoefH_x, BcoefQ_x) 2156 AcoefH_x, AcoefQ_x, BcoefH_x, BcoefQ_x & 2157 #ifdef ISO 2158 & ,yxt_x, CcoefXT_x, DcoefXT_x, gama_xt_x, AcoefXT_x, BcoefXT_x & 2159 #endif 2160 & ) 1861 2161 !!! 1862 2162 IF (prt_level >=10) THEN … … 1873 2173 Kcoef_hq_w, gama_q_w, gama_h_w, & 1874 2174 !!! 1875 AcoefH_w, AcoefQ_w, BcoefH_w, BcoefQ_w) 2175 AcoefH_w, AcoefQ_w, BcoefH_w, BcoefQ_w & 2176 #ifdef ISO 2177 & ,yxt_w, CcoefXT_w, DcoefXT_w, gama_xt_w, AcoefXT_w, BcoefXT_w & 2178 #endif 2179 & ) 1876 2180 !!! 1877 2181 IF (prt_level >=10) THEN … … 1955 2259 yt1(:) = yt(:,1) 1956 2260 yq1(:) = yq(:,1) 2261 #ifdef ISO 2262 yxt1(:,:) = yxt(:,:,1) 2263 #endif 2264 1957 2265 ELSE IF (iflag_split .ge. 1) THEN 2266 #ifdef ISO 2267 call abort_gcm('pbl_surface_mod 2149','isos pas encore dans iflag_split=1',1) 2268 #endif 2269 1958 2270 ! 1959 2271 ! Cdragq computation … … 2117 2429 yqsurf, ytsurf_new, y_dflux_t, y_dflux_q, & 2118 2430 y_flux_u1, y_flux_v1, & 2119 yveget,ylai,yheight ) 2431 yveget,ylai,yheight & 2432 #ifdef ISO 2433 & ,yxtrain_f, yxtsnow_f,yxt1, & 2434 & yxtsnow,yxtsol,yxtevap,h1, & 2435 & yrunoff_diag,yxtrunoff_diag,yRland_ice & 2436 #endif 2437 & ) 2120 2438 2121 2439 !FC quid qd yveget ylai yheight ne sont pas definit … … 2147 2465 ENDDO 2148 2466 ENDIF 2149 2467 2468 #ifdef ISOVERIF 2469 DO j=1,knon 2470 DO ixt=1,ntraciso 2471 CALL iso_verif_noNaN(yxtevap(ixt,j), & 2472 & 'pbl_surface 1056a: apres surf_land') 2473 ENDDO 2474 DO ixt=1,niso 2475 CALL iso_verif_noNaN(yxtsol(ixt,j), & 2476 & 'pbl_surface 1056b: apres surf_land') 2477 ENDDO 2478 ENDDO 2479 #endif 2480 #ifdef ISOVERIF 2481 ! write(*,*) 'pbl_surface_mod 1038: sortie surf_land' 2482 DO j=1,knon 2483 IF (iso_eau >= 0) THEN 2484 CALL iso_verif_egalite(yxtsnow(iso_eau,j), & 2485 & ysnow(j),'pbl_surf_mod 1043') 2486 ENDIF !if (iso_eau.gt.0) then 2487 ENDDO !DO i=1,klon 2488 #endif 2489 2150 2490 CASE(is_lic) 2151 2491 ! Martin … … 2168 2508 ysnowhgt, yqsnow, ytoice, ysissnow, & 2169 2509 yalb3_new, yrunoff, & 2170 y_flux_u1, y_flux_v1) 2510 y_flux_u1, y_flux_v1 & 2511 #ifdef ISO 2512 & ,yxtrain_f, yxtsnow_f,yxt1,yRland_ice & 2513 & ,yxtsnow,yxtsol,yxtevap & 2514 #endif 2515 & ) 2171 2516 2172 2517 !jyg< … … 2190 2535 ENDDO 2191 2536 ENDIF 2192 2537 2538 #ifdef ISOVERIF 2539 DO j=1,knon 2540 DO ixt=1,ntraciso 2541 CALL iso_verif_noNaN(yxtevap(ixt,j), & 2542 & 'pbl_surface 1095a: apres surf_landice') 2543 ENDDO 2544 do ixt=1,niso 2545 call iso_verif_noNaN(yxtsol(ixt,j), & 2546 & 'pbl_surface 1095b: apres surf_landice') 2547 enddo 2548 enddo 2549 #endif 2550 #ifdef ISOVERIF 2551 !write(*,*) 'pbl_surface_mod 1060: sortie surf_landice' 2552 do j=1,knon 2553 IF (iso_eau >= 0) THEN 2554 CALL iso_verif_egalite(yxtsnow(iso_eau,j), & 2555 & ysnow(j),'pbl_surf_mod 1064') 2556 ENDIF !if (iso_eau >= 0) THEN 2557 ENDDO !DO i=1,klon 2558 #endif 2559 2193 2560 END IF 2194 2561 … … 2207 2574 y_flux_u1, y_flux_v1, ydelta_sst(:knon), ydelta_sal(:knon), & 2208 2575 yds_ns(:knon), ydt_ns(:knon), ydter(:knon), ydser(:knon), & 2209 ydt_ds(:knon), ytkt(:knon), ytks(:knon), ytaur(:knon), ysss) 2576 ydt_ds(:knon), ytkt(:knon), ytks(:knon), ytaur(:knon), ysss & 2577 #ifdef ISO 2578 & ,yxtrain_f, yxtsnow_f,yxt1,Roce, & 2579 & yxtsnow,yxtevap,h1 & 2580 #endif 2581 & ) 2210 2582 IF (prt_level >=10) THEN 2211 2583 print *,'arg de surf_ocean: ycdragh ',ycdragh(1:knon) … … 2248 2620 !albedo SB <<< 2249 2621 ytsurf_new, y_dflux_t, y_dflux_q, & 2250 y_flux_u1, y_flux_v1) 2622 y_flux_u1, y_flux_v1 & 2623 #ifdef ISO 2624 & ,yxtrain_f, yxtsnow_f,yxt1,Roce, & 2625 & yxtsnow,yxtsol,yxtevap,Rland_ice & 2626 #endif 2627 & ) 2251 2628 2252 2629 ! Special DICE MPL 05082013 puis BOMEX MPL 20150410 … … 2256 2633 y_flux_v1(j)=ycdragm(j)*(1.+sqrt(yu(j,1)*yu(j,1)+yv(j,1)*yv(j,1)))*yv(j,1)*ypplay(j,1)/RD/yt(j,1) 2257 2634 ENDDO 2258 ENDIF 2635 ENDIF 2636 2637 #ifdef ISOVERIF 2638 DO j=1,knon 2639 DO ixt=1,ntraciso 2640 CALL iso_verif_noNaN(yxtevap(ixt,j), & 2641 & 'pbl_surface 1165a: apres surf_seaice') 2642 ENDDO 2643 DO ixt=1,niso 2644 CALL iso_verif_noNaN(yxtsol(ixt,j), & 2645 & 'pbl_surface 1165b: apres surf_seaice') 2646 ENDDO 2647 ENDDO 2648 #endif 2649 #ifdef ISOVERIF 2650 !write(*,*) 'pbl_surface_mod 1077: sortie surf_seaice' 2651 DO j=1,knon 2652 IF (iso_eau >= 0) THEN 2653 CALL iso_verif_egalite(yxtsnow(iso_eau,j), & 2654 & ysnow(j),'pbl_surf_mod 1106') 2655 ENDIF !IF (iso_eau >= 0) THEN 2656 ENDDO !DO i=1,klon 2657 #endif 2259 2658 2260 2659 CASE DEFAULT … … 2316 2715 yt1_new=(1./RCPD)*(AcoefH(j)+BcoefH(j)*y_flux_t1(j)*dtime) 2317 2716 ytsurf_new(j)=yt1_new-y_flux_t1(j)/(Kech_h(j)*RCPD) 2717 ! for cases forced in flux and for which forcing in Ts is needed 2718 ! to prevent the latter to reach unrealistic value (even if not used, 2719 ! Ts is calculated and hgardfou can appear during the calculation 2720 ! of surface saturation humidity for example 2721 if (ok_forc_tsurf) ytsurf_new(j)=tg 2318 2722 ENDDO 2319 2723 … … 2326 2730 y_flux_t1(j) = yfluxsens(j) 2327 2731 y_flux_q1(j) = -yevap(j) 2732 #ifdef ISO 2733 y_flux_xt1(:,:) = -yxtevap(:,:) 2734 #endif 2328 2735 ENDDO 2329 2736 ENDIF ! (ok_flux_surf) … … 2341 2748 2342 2749 IF (iflag_split .GE. 1) THEN 2750 #ifdef ISO 2751 call abort_gcm('pbl_surface_mod 2607','isos pas encore dans iflag_split=1',1) 2752 #endif 2753 ! 2343 2754 ! 2344 2755 IF (nsrf .ne. is_oce) THEN … … 2558 2969 Kcoef_hq, gama_q, gama_h, & 2559 2970 !!! 2560 y_flux_q(:,:), y_flux_t(:,:), y_d_q(:,:), y_d_t(:,:)) 2971 y_flux_q(:,:), y_flux_t(:,:), y_d_q(:,:), y_d_t(:,:) & 2972 #ifdef ISO 2973 & ,yxt,y_flux_xt1 & 2974 & ,AcoefXT,BcoefXT,CcoefXT,DcoefXT,gama_xt & 2975 & ,y_flux_xt(:,:,:),y_d_xt(:,:,:) & 2976 #endif 2977 & ) 2561 2978 ELSE !(iflag_split .eq.0) 2562 2979 CALL climb_hq_up(knon, dtime, yt_x, yq_x, & … … 2567 2984 Kcoef_hq_x, gama_q_x, gama_h_x, & 2568 2985 !!! 2569 y_flux_q_x(:,:), y_flux_t_x(:,:), y_d_q_x(:,:), y_d_t_x(:,:)) 2986 y_flux_q_x(:,:), y_flux_t_x(:,:), y_d_q_x(:,:), y_d_t_x(:,:) & 2987 #ifdef ISO 2988 & ,yxt_x,y_flux_xt1_x & 2989 & ,AcoefXT_x,BcoefXT_x,CcoefXT_x,DcoefXT_x,gama_xt_x & 2990 & ,y_flux_xt_x(:,:,:),y_d_xt_x(:,:,:) & 2991 #endif 2992 & ) 2570 2993 ! 2571 2994 CALL climb_hq_up(knon, dtime, yt_w, yq_w, & … … 2576 2999 Kcoef_hq_w, gama_q_w, gama_h_w, & 2577 3000 !!! 2578 y_flux_q_w(:,:), y_flux_t_w(:,:), y_d_q_w(:,:), y_d_t_w(:,:)) 3001 y_flux_q_w(:,:), y_flux_t_w(:,:), y_d_q_w(:,:), y_d_t_w(:,:) & 3002 #ifdef ISO 3003 & ,yxt_w,y_flux_xt1_w & 3004 & ,AcoefXT_w,BcoefXT_w,CcoefXT_w,DcoefXT_w,gama_xt_w & 3005 & ,y_flux_xt_w(:,:,:),y_d_xt_w(:,:,:) & 3006 #endif 3007 & ) 2579 3008 !!! 2580 3009 ENDIF ! (iflag_split .eq.0) … … 2694 3123 flux_u(i,k,nsrf) = y_flux_u(j,k) 2695 3124 flux_v(i,k,nsrf) = y_flux_v(j,k) 3125 3126 #ifdef ISO 3127 DO ixt=1,ntraciso 3128 y_d_xt(ixt,j,k) = y_d_xt(ixt,j,k) * ypct(j) 3129 flux_xt(ixt,i,k,nsrf) = y_flux_xt(ixt,j,k) 3130 ENDDO ! DO ixt=1,ntraciso 3131 h1_diag(i)=h1(j) 3132 #endif 3133 2696 3134 ENDDO 2697 3135 ENDDO 3136 3137 #ifdef ISO 3138 #ifdef ISOVERIF 3139 if (iso_eau.gt.0) then 3140 call iso_verif_egalite_vect2D( & 3141 y_d_xt,y_d_q, & 3142 'pbl_surface_mod 2600',ntraciso,klon,klev) 3143 endif 3144 #endif 3145 #endif 2698 3146 2699 3147 ELSE !(iflag_split .eq.0) … … 2713 3161 flux_u_x(i,k,nsrf) = y_flux_u_x(j,k) 2714 3162 flux_v_x(i,k,nsrf) = y_flux_v_x(j,k) 3163 3164 #ifdef ISO 3165 DO ixt=1,ntraciso 3166 y_d_xt_x(ixt,j,k) = y_d_xt_x(ixt,j,k) * ypct(j) 3167 flux_xt_x(ixt,i,k,nsrf) = y_flux_xt_x(ixt,j,k) 3168 ENDDO ! DO ixt=1,ntraciso 3169 #endif 2715 3170 ENDDO 2716 3171 ENDDO … … 2730 3185 flux_u_w(i,k,nsrf) = y_flux_u_w(j,k) 2731 3186 flux_v_w(i,k,nsrf) = y_flux_v_w(j,k) 3187 3188 #ifdef ISO 3189 DO ixt=1,ntraciso 3190 y_d_xt_w(ixt,j,k) = y_d_xt_w(ixt,j,k) * ypct(j) 3191 flux_xt_w(ixt,i,k,nsrf) = y_flux_xt_w(ixt,j,k) 3192 ENDDO ! do ixt=1,ntraciso 3193 #endif 3194 2732 3195 ENDDO 2733 3196 ENDDO … … 2741 3204 flux_u(i,k,nsrf) = flux_u_x(i,k,nsrf)+ywake_s(j)*(flux_u_w(i,k,nsrf)-flux_u_x(i,k,nsrf)) 2742 3205 flux_v(i,k,nsrf) = flux_v_x(i,k,nsrf)+ywake_s(j)*(flux_v_w(i,k,nsrf)-flux_v_x(i,k,nsrf)) 3206 #ifdef ISO 3207 DO ixt=1,ntraciso 3208 flux_xt(ixt,i,k,nsrf) = flux_xt_x(ixt,i,k,nsrf)+ywake_s(j)*(flux_xt_w(ixt,i,k,nsrf)-flux_xt_x(ixt,i,k,nsrf)) 3209 ENDDO ! do ixt=1,ntraciso 3210 #endif 2743 3211 ENDDO 2744 3212 ENDDO … … 2798 3266 dflux_t(i) = dflux_t(i) + y_dflux_t(j)*ypct(j) 2799 3267 dflux_q(i) = dflux_q(i) + y_dflux_q(j)*ypct(j) 3268 #ifdef ISO 3269 DO ixt=1,niso 3270 xtsnow(ixt,i,nsrf) = yxtsnow(ixt,j) 3271 ENDDO 3272 DO ixt=1,ntraciso 3273 xtevap(ixt,i,nsrf) = - flux_xt(ixt,i,1,nsrf) 3274 dflux_xt(ixt,i) = dflux_xt(ixt,i) + y_dflux_xt(ixt,j)*ypct(j) 3275 ENDDO 3276 IF (nsrf == is_lic) THEN 3277 DO ixt=1,niso 3278 Rland_ice(ixt,i) = yRland_ice(ixt,j) 3279 ENDDO 3280 ENDIF !IF (nsrf == is_lic) THEN 3281 #ifdef ISOVERIF 3282 IF (iso_eau.gt.0) THEN 3283 call iso_verif_egalite_choix(Rland_ice(iso_eau,i),1.0, & 3284 & 'pbl_surf_mod 1230',errmax,errmaxrel) 3285 ENDIF !if (iso_eau.gt.0) then 3286 #endif 3287 #endif 2800 3288 ENDDO 2801 3289 … … 2902 3390 i = ni(j) 2903 3391 qsol(i) = yqsol(j) 3392 #ifdef ISO 3393 runoff_diag(i)=yrunoff_diag(j) 3394 DO ixt=1,niso 3395 xtsol(ixt,i) = yxtsol(ixt,j) 3396 xtrunoff_diag(ixt,i)=yxtrunoff_diag(ixt,j) 3397 ENDDO 3398 #endif 2904 3399 ENDDO 2905 3400 ENDIF … … 2914 3409 ENDDO 2915 3410 ENDDO 2916 3411 3412 #ifdef ISO 3413 #ifdef ISOVERIF 3414 !write(*,*) 'pbl_surface 2858' 3415 DO i = 1, klon 3416 DO ixt=1,niso 3417 call iso_verif_noNaN(xtsol(ixt,i),'pbl_surface 1405') 3418 ENDDO 3419 ENDDO 3420 #endif 3421 #ifdef ISOVERIF 3422 IF (iso_eau.gt.0) THEN 3423 call iso_verif_egalite_vect2D( & 3424 y_d_xt,y_d_q, & 3425 'pbl_surface_mod 1261',ntraciso,klon,klev) 3426 ENDIF !if (iso_eau.gt.0) then 3427 #endif 3428 #endif 2917 3429 !!! jyg le 07/02/2012 2918 3430 IF (iflag_split .ge.1) THEN … … 2933 3445 d_u_w(i,k) = d_u_w(i,k) + y_d_u_w(j,k) 2934 3446 d_v_w(i,k) = d_v_w(i,k) + y_d_v_w(j,k) 3447 #ifdef ISO 3448 DO ixt=1,ntraciso 3449 d_xt_x(ixt,i,k) = d_xt_x(ixt,i,k) + y_d_xt_x(ixt,j,k) 3450 d_xt_w(ixt,i,k) = d_xt_w(ixt,i,k) + y_d_xt_w(ixt,j,k) 3451 ENDDO ! DO ixt=1,ntraciso 3452 #endif 3453 2935 3454 ! 2936 3455 !! d_wake_dlt(i,k) = d_wake_dlt(i,k) + y_d_t_w(i,k)-y_d_t_x(i,k) … … 2948 3467 d_t(i,k) = d_t(i,k) + y_d_t(j,k) 2949 3468 d_q(i,k) = d_q(i,k) + y_d_q(j,k) 3469 #ifdef ISO 3470 DO ixt=1,ntraciso 3471 d_xt(ixt,i,k) = d_xt(ixt,i,k) + y_d_xt(ixt,j,k) 3472 ENDDO !DO ixt=1,ntraciso 3473 #endif 2950 3474 d_u(i,k) = d_u(i,k) + y_d_u(j,k) 2951 3475 d_v(i,k) = d_v(i,k) + y_d_v(j,k) … … 2962 3486 ENDDO 2963 3487 ENDIF 3488 3489 #ifdef ISO 3490 #ifdef ISOVERIF 3491 ! write(*,*) 'd_q,d_xt(iso_eau,554,19)=',d_q(554,19),d_xt(iso_eau,554,19) 3492 ! write(*,*) 'pbl_surface 2929: d_q,d_xt(iso_eau,2,1)=',d_q(2,1),d_xt(iso_eau,2,1) 3493 ! write(*,*) 'y_d_q,y_d_xt(iso_eau,2,1)=',y_d_q(2,1),y_d_xt(iso_eau,2,1) 3494 ! write(*,*) 'iso_eau.gt.0=',iso_eau.gt.0 3495 call iso_verif_noNaN_vect2D( & 3496 & d_xt, & 3497 & 'pbl_surface 1385',ntraciso,klon,klev) 3498 IF (iso_eau >= 0) THEN 3499 call iso_verif_egalite_vect2D( & 3500 y_d_xt,y_d_q, & 3501 'pbl_surface_mod 2945',ntraciso,klon,klev) 3502 call iso_verif_egalite_vect2D( & 3503 d_xt,d_q, & 3504 'pbl_surface_mod 1276',ntraciso,klon,klev) 3505 ENDIF !IF (iso_eau >= 0) THEN 3506 #endif 3507 #endif 2964 3508 2965 3509 ! print*,'Dans pbl OK4' … … 3349 3893 iflag_split=iflag_split_ref 3350 3894 3895 #ifdef ISO 3896 #ifdef ISOVERIF 3897 ! write(*,*) 'pbl_surface tmp 3249: d_q,d_xt(iso_eau,2,1)=',d_q(2,1),d_xt(iso_eau,2,1) 3898 IF (iso_eau >= 0) THEN 3899 call iso_verif_egalite_vect2D( & 3900 d_xt,d_q, & 3901 'pbl_surface_mod 1276',ntraciso,klon,klev) 3902 ENDIF !IF (iso_eau >= 0) THEN 3903 #endif 3904 #endif 3905 3351 3906 !**************************************************************************************** 3352 3907 ! 16) Calculate the mean value over all sub-surfaces for some variables … … 3370 3925 zxfluxt_w(:,:) = 0.0 ; zxfluxq_w(:,:) = 0.0 3371 3926 zxfluxu_w(:,:) = 0.0 ; zxfluxv_w(:,:) = 0.0 3927 #ifdef ISO 3928 zxfluxxt(:,:,:) = 0.0 3929 zxfluxxt_x(:,:,:) = 0.0 3930 zxfluxxt_w(:,:,:) = 0.0 3931 #endif 3932 3372 3933 3373 3934 !!! jyg le 07/02/2012 … … 3388 3949 zxfluxu_w(i,k) = zxfluxu_w(i,k) + flux_u_w(i,k,nsrf) * pctsrf(i,nsrf) 3389 3950 zxfluxv_w(i,k) = zxfluxv_w(i,k) + flux_v_w(i,k,nsrf) * pctsrf(i,nsrf) 3951 #ifdef ISO 3952 DO ixt=1,ntraciso 3953 zxfluxxt_x(ixt,i,k) = zxfluxxt_x(ixt,i,k) + flux_xt_x(ixt,i,k,nsrf) * pctsrf(i,nsrf) 3954 zxfluxxt_w(ixt,i,k) = zxfluxxt_w(ixt,i,k) + flux_xt_w(ixt,i,k,nsrf) * pctsrf(i,nsrf) 3955 ENDDO ! DO ixt=1,ntraciso 3956 #endif 3390 3957 ENDDO 3391 3958 ENDDO … … 3407 3974 zxfluxu(i,k) = zxfluxu(i,k) + flux_u(i,k,nsrf) * pctsrf(i,nsrf) 3408 3975 zxfluxv(i,k) = zxfluxv(i,k) + flux_v(i,k,nsrf) * pctsrf(i,nsrf) 3976 #ifdef ISO 3977 DO ixt=1,niso 3978 zxfluxxt(ixt,i,k) = zxfluxxt(ixt,i,k) + flux_xt(ixt,i,k,nsrf) * pctsrf(i,nsrf) 3979 ENDDO ! DO ixt=1,niso 3980 #endif 3409 3981 ENDDO 3410 3982 ENDDO … … 3431 4003 END DO 3432 4004 endif 4005 4006 #ifdef ISO 4007 DO i = 1, klon 4008 DO ixt=1,ntraciso 4009 zxxtevap(ixt,i) = - zxfluxxt(ixt,i,1) 4010 ENDDO 4011 ENDDO 4012 #endif 3433 4013 3434 4014 !!! … … 3606 4186 zxqsurf(:) = 0.0 3607 4187 zxsnow(:) = 0.0 4188 #ifdef ISO 4189 zxxtsnow(:,:) = 0.0 4190 #endif 4191 3608 4192 DO nsrf = 1, nbsrf 3609 4193 DO i = 1, klon 3610 4194 zxqsurf(i) = zxqsurf(i) + MAX(qsurf(i,nsrf),0.0) * pctsrf(i,nsrf) 3611 4195 zxsnow(i) = zxsnow(i) + snow(i,nsrf) * pctsrf(i,nsrf) 4196 #ifdef ISO 4197 DO ixt=1,niso 4198 zxxtsnow(ixt,i) = zxxtsnow(ixt,i) + xtsnow(ixt,i,nsrf) * pctsrf(i,nsrf) 4199 ENDDO ! DO ixt=1,niso 4200 #endif 3612 4201 ENDDO 3613 4202 ENDDO … … 3621 4210 !**************************************************************************************** 3622 4211 ! 3623 SUBROUTINE pbl_surface_final(fder_rst, snow_rst, qsurf_rst, ftsoil_rst) 4212 SUBROUTINE pbl_surface_final(fder_rst, snow_rst, qsurf_rst, ftsoil_rst & 4213 #ifdef ISO 4214 ,xtsnow_rst,Rland_ice_rst & 4215 #endif 4216 ) 3624 4217 3625 4218 USE indice_sol_mod 4219 #ifdef ISO 4220 #ifdef ISOVERIF 4221 USE isotopes_mod, ONLY: iso_eau,ridicule 4222 USE isotopes_verif_mod, ONLY: errmax,errmaxrel 4223 #endif 4224 #endif 3626 4225 3627 4226 INCLUDE "dimsoil.h" … … 3633 4232 REAL, DIMENSION(klon, nbsrf), INTENT(OUT) :: qsurf_rst 3634 4233 REAL, DIMENSION(klon, nsoilmx, nbsrf), INTENT(OUT) :: ftsoil_rst 4234 #ifdef ISO 4235 REAL, DIMENSION(niso,klon, nbsrf), INTENT(OUT) :: xtsnow_rst 4236 REAL, DIMENSION(niso,klon), INTENT(OUT) :: Rland_ice_rst 4237 #endif 3635 4238 3636 4239 … … 3643 4246 qsurf_rst(:,:) = qsurf(:,:) 3644 4247 ftsoil_rst(:,:,:) = ftsoil(:,:,:) 4248 #ifdef ISO 4249 xtsnow_rst(:,:,:) = xtsnow(:,:,:) 4250 Rland_ice_rst(:,:) = Rland_ice(:,:) 4251 #endif 3645 4252 3646 4253 !**************************************************************************************** … … 3655 4262 IF (ALLOCATED(ydTs0)) DEALLOCATE(ydTs0) 3656 4263 IF (ALLOCATED(ydqs0)) DEALLOCATE(ydqs0) 4264 #ifdef ISO 4265 IF (ALLOCATED(xtsnow)) DEALLOCATE(xtsnow) 4266 IF (ALLOCATED(Rland_ice)) DEALLOCATE(Rland_ice) 4267 IF (ALLOCATED(Roce)) DEALLOCATE(Roce) 4268 #endif 3657 4269 3658 4270 !jyg< … … 3673 4285 SUBROUTINE pbl_surface_newfrac(itime, pctsrf_new, pctsrf_old, & 3674 4286 evap, z0m, z0h, agesno, & 3675 tsurf,alb_dir,alb_dif, ustar, u10m, v10m, tke) 4287 tsurf,alb_dir,alb_dif, ustar, u10m, v10m, tke & 4288 #ifdef ISO 4289 ,xtevap & 4290 #endif 4291 & ) 3676 4292 !albedo SB <<< 3677 4293 ! Give default values where new fraction has appread … … 3702 4318 REAL, DIMENSION(klon,nbsrf+1), INTENT(INOUT) :: z0m,z0h 3703 4319 REAL, DIMENSION(klon,klev+1,nbsrf+1), INTENT(INOUT) :: tke 4320 #ifdef ISO 4321 REAL, DIMENSION(ntraciso,klon,nbsrf), INTENT(INOUT) :: xtevap 4322 #endif 3704 4323 3705 4324 ! Local variables … … 3709 4328 CHARACTER(len=20) :: modname = 'pbl_surface_newfrac' 3710 4329 INTEGER, DIMENSION(nbsrf) :: nfois=0, mfois=0, pfois=0 4330 #ifdef ISO 4331 INTEGER :: ixt 4332 #endif 3711 4333 ! 3712 4334 ! All at once !! … … 3754 4376 u10m(i,nsrf) = u10m(i,nsrf_comp1) 3755 4377 v10m(i,nsrf) = v10m(i,nsrf_comp1) 4378 #ifdef ISO 4379 DO ixt=1,ntraciso 4380 xtevap(ixt,i,nsrf) = xtevap(ixt,i,nsrf_comp1) 4381 ENDDO 4382 #endif 3756 4383 IF (iflag_pbl > 1) THEN 3757 4384 tke(i,:,nsrf) = tke(i,:,nsrf_comp1) … … 3809 4436 u10m(i,nsrf) = u10m(i,nsrf_comp2) *pctsrf_old(i,nsrf_comp2) + u10m(i,nsrf_comp3) *pctsrf_old(i,nsrf_comp3) 3810 4437 v10m(i,nsrf) = v10m(i,nsrf_comp2) *pctsrf_old(i,nsrf_comp2) + v10m(i,nsrf_comp3) *pctsrf_old(i,nsrf_comp3) 4438 #ifdef ISO 4439 DO ixt=1,ntraciso 4440 xtevap(ixt,i,nsrf) = xtevap(ixt,i,nsrf_comp2) *pctsrf_old(i,nsrf_comp2) & 4441 + xtevap(ixt,i,nsrf_comp3) *pctsrf_old(i,nsrf_comp3) 4442 ENDDO 4443 #endif 3811 4444 IF (iflag_pbl > 1) THEN 3812 4445 tke(i,:,nsrf) = tke(i,:,nsrf_comp2)*pctsrf_old(i,nsrf_comp2) + tke(i,:,nsrf_comp3)*pctsrf_old(i,nsrf_comp3) … … 3821 4454 agesno(i,nsrf) = 0. 3822 4455 ftsoil(i,:,nsrf) = tsurf(i,nsrf) 4456 #ifdef ISO 4457 xtsnow(:,i,nsrf) = 0. 4458 #endif 3823 4459 ELSE 3824 4460 pfois(nsrf) = pfois(nsrf)+ 1 -
LMDZ6/branches/cirrus/libf/phylmd/phys_local_var_mod.F90
r4951 r5202 14 14 REAL, SAVE, ALLOCATABLE :: ql_seri(:,:),qs_seri(:,:) 15 15 !$OMP THREADPRIVATE(ql_seri,qs_seri) 16 ! SN 15/07/2024 ISO 4D 17 REAL, SAVE, ALLOCATABLE :: qx_seri(:,:,:) 18 !$OMP THREADPRIVATE(qx_seri) 19 ! SN 16 20 REAL, SAVE, ALLOCATABLE :: qbs_seri(:,:) 17 21 !$OMP THREADPRIVATE(qbs_seri) … … 24 28 REAL, SAVE, ALLOCATABLE :: pbl_eps(:,:,:) 25 29 !$OMP THREADPRIVATE(pbl_eps) 30 REAL, SAVE, ALLOCATABLE :: tke_shear(:,:,:), tke_buoy(:,:,:), tke_trans(:,:,:) 31 !$OMP THREADPRIVATE(tke_shear,tke_buoy,tke_trans) 26 32 REAL, SAVE, ALLOCATABLE :: tr_seri(:,:,:) 27 33 !$OMP THREADPRIVATE(tr_seri) … … 64 70 REAL, SAVE, ALLOCATABLE :: d_t_eva(:,:),d_q_eva(:,:),d_ql_eva(:,:),d_qi_eva(:,:) 65 71 !$OMP THREADPRIVATE(d_t_eva,d_q_eva,d_ql_eva,d_qi_eva) 72 ! SN 15/07/2024 ISO 4D 73 REAL, SAVE, ALLOCATABLE :: d_qx_eva(:,:,:) 74 !$OMP THREADPRIVATE(d_qx_eva) 75 ! SN 66 76 REAL, SAVE, ALLOCATABLE :: d_t_lscst(:,:),d_q_lscst(:,:) 67 77 !$OMP THREADPRIVATE(d_t_lscst,d_q_lscst) … … 84 94 REAL, SAVE, ALLOCATABLE :: d_t_vdf_x(:,:), d_q_vdf_x(:,:) 85 95 !$OMP THREADPRIVATE( d_t_vdf_x, d_q_vdf_x) 86 REAL, SAVE, ALLOCATABLE :: d_t_bs (:,:), d_q_bs(:,:), d_qbs_bs(:,:)87 !$OMP THREADPRIVATE( d_t_bs ,d_q_bs, d_qbs_bs)96 REAL, SAVE, ALLOCATABLE :: d_t_bsss(:,:), d_q_bsss(:,:), d_qbs_bsss(:,:) 97 !$OMP THREADPRIVATE( d_t_bsss,d_q_bsss, d_qbs_bsss) 88 98 !>nrlmd+jyg 89 99 REAL, SAVE, ALLOCATABLE :: d_t_oro(:,:) … … 117 127 REAL, SAVE, ALLOCATABLE :: d_q_ch4(:,:) 118 128 !$OMP THREADPRIVATE(d_q_ch4) 129 #ifdef ISO 130 REAL, SAVE, ALLOCATABLE :: xt_seri(:,:,:) 131 !$OMP THREADPRIVATE( xt_seri) 132 REAL, SAVE, ALLOCATABLE :: xtl_seri(:,:,:) 133 !$OMP THREADPRIVATE( xtl_seri) 134 REAL, SAVE, ALLOCATABLE :: xts_seri(:,:,:) 135 !$OMP THREADPRIVATE( xts_seri) 136 REAL, SAVE, ALLOCATABLE :: xtbs_seri(:,:,:) 137 !$OMP THREADPRIVATE( xtbs_seri) 138 REAL, SAVE, ALLOCATABLE :: d_xt_eva(:,:,:) 139 !$OMP THREADPRIVATE( d_xt_eva) 140 REAL, SAVE, ALLOCATABLE :: d_xtl_eva(:,:,:) 141 !$OMP THREADPRIVATE( d_xtl_eva) 142 REAL, SAVE, ALLOCATABLE :: d_xti_eva(:,:,:) 143 !$OMP THREADPRIVATE( d_xti_eva) 144 REAL, SAVE, ALLOCATABLE :: d_xt_vdf(:,:,:) 145 !$OMP THREADPRIVATE( d_xt_vdf) 146 REAL, SAVE, ALLOCATABLE :: d_xt_dyn(:,:,:) 147 !$OMP THREADPRIVATE( d_xt_dyn) 148 REAL, SAVE, ALLOCATABLE :: d_xtl_dyn(:,:,:), d_xts_dyn(:,:,:), d_xtbs_dyn(:,:,:) 149 !$OMP THREADPRIVATE(d_xtl_dyn, d_xts_dyn, d_xtbs_dyn) 150 REAL, SAVE, ALLOCATABLE :: d_xt_con(:,:,:) 151 !$OMP THREADPRIVATE( d_xt_con) 152 REAL, SAVE, ALLOCATABLE :: d_xt_wake(:,:,:) 153 !$OMP THREADPRIVATE( d_xt_wake) 154 REAL, SAVE, ALLOCATABLE :: d_xt_lsc(:,:,:),d_xtl_lsc(:,:,:),d_xti_lsc(:,:,:) 155 !$OMP THREADPRIVATE( d_xt_lsc,d_xtl_lsc,d_xti_lsc) 156 REAL, SAVE, ALLOCATABLE :: d_xt_ajsb(:,:,:) 157 !$OMP THREADPRIVATE( d_xt_ajsb) 158 REAL, SAVE, ALLOCATABLE :: d_xt_ajs(:,:,:) 159 !$OMP THREADPRIVATE( d_xt_ajs) 160 REAL, SAVE, ALLOCATABLE :: d_xt_ajs_w(:,:,:), d_xt_ajs_x(:,:,:) 161 !$OMP THREADPRIVATE(d_xt_ajs_w, d_xt_ajs_x) 162 REAL, SAVE, ALLOCATABLE :: d_xt_vdf_w(:,:,:), d_xt_vdf_x(:,:,:) 163 !$OMP THREADPRIVATE(d_xt_vdf_w, d_xt_vdf_x) 164 REAL, SAVE, ALLOCATABLE :: d_xt_ch4(:,:,:) 165 !$OMP THREADPRIVATE( d_xt_ch4) 166 REAL, SAVE, ALLOCATABLE :: d_xt_prod_nucl(:,:,:) 167 !$OMP THREADPRIVATE( d_xt_prod_nucl) 168 REAL, SAVE, ALLOCATABLE :: d_xt_cosmo(:,:,:) 169 !$OMP THREADPRIVATE( d_xt_cosmo) 170 REAL, SAVE, ALLOCATABLE :: d_xt_decroiss(:,:,:) 171 !$OMP THREADPRIVATE( d_xt_decroiss) 172 #endif 119 173 120 174 ! tendance du a la conersion Ec -> E thermique … … 124 178 !$OMP THREADPRIVATE(d_ts, d_tr) 125 179 126 ! aerosols127 REAL, SAVE, ALLOCATABLE :: m_allaer (:,:,:)128 !$OMP THREADPRIVATE(m_allaer)129 180 ! diagnostique pour le rayonnement 130 181 REAL, SAVE, ALLOCATABLE :: topswad_aero(:), solswad_aero(:) ! diag … … 307 358 !!!OMP THREADPRIVATE(d_s_the, d_dens_the) 308 359 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:) :: d_deltat_ajs_cv, d_deltaq_ajs_cv 309 !$OMP THREADPRIVATE(d_deltat_ajs_cv, d_deltaq_ajs_cv) 360 !$OMP THREADPRIVATE(d_deltat_ajs_cv, d_deltaq_ajs_cv) 361 #ifdef ISO 362 REAL, SAVE, ALLOCATABLE,DIMENSION(:,:,:) :: d_deltaxt_wk 363 !$OMP THREADPRIVATE(d_deltaxt_wk) 364 REAL, SAVE, ALLOCATABLE,DIMENSION(:,:,:) :: d_deltaxt_wk_gw 365 !$OMP THREADPRIVATE(d_deltaxt_wk_gw) 366 REAL, SAVE, ALLOCATABLE,DIMENSION(:,:,:) :: d_deltaxt_the 367 !$OMP THREADPRIVATE(d_deltaxt_the) 368 REAL, SAVE, ALLOCATABLE,DIMENSION(:,:,:) :: d_deltaxt_vdf 369 !$OMP THREADPRIVATE(d_deltaxt_vdf) 370 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:,:) :: d_deltaxt_ajs_cv 371 !$OMP THREADPRIVATE(d_deltaxt_ajs_cv) 372 #endif 310 373 !! End of Wake variables 311 374 !! … … 343 406 REAL,ALLOCATABLE,SAVE,DIMENSION(:) :: zxfluxlat, zxtsol, snow_lsc, zxfqfonte 344 407 !$OMP THREADPRIVATE(zxfluxlat, zxtsol, snow_lsc, zxfqfonte) 345 REAL,ALLOCATABLE,SAVE,DIMENSION(:) :: zxrunofflic 346 !$OMP THREADPRIVATE(zxrunofflic) 408 !SN runoffdiag 409 REAL,ALLOCATABLE,SAVE,DIMENSION(:) :: zxrunofflic, runoff_diag 410 !$OMP THREADPRIVATE(zxrunofflic, runoff_diag) 347 411 REAL,ALLOCATABLE,SAVE,DIMENSION(:) :: zxqsurf, rain_lsc, rain_num 348 412 !$OMP THREADPRIVATE(zxqsurf, rain_lsc, rain_num) 413 #ifdef ISO 414 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:) :: xtevap,xtprw 415 !$OMP THREADPRIVATE(xtevap,xtprw) 416 REAL,ALLOCATABLE,SAVE,DIMENSION(:) :: h1_diag 417 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:) :: xtrunoff_diag 418 !$OMP THREADPRIVATE(h1_diagv,xtrunoff_diag) 419 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:) :: zxfxtcalving 420 !$OMP THREADPRIVATE(zxfxtcalving) 421 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:) :: xtsnow_lsc, zxfxtfonte 422 !$OMP THREADPRIVATE(xtsnow_lsc, zxfxtfonte) 423 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:) :: zxxtrunofflic 424 !$OMP THREADPRIVATE(zxxtrunofflic) 425 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:) :: xtrain_lsc 426 !$OMP THREADPRIVATE(xtrain_lsc) 427 #endif 349 428 ! 350 429 !jyg+nrlmd< … … 384 463 REAL,ALLOCATABLE,SAVE,DIMENSION(:) :: kh, kh_x, kh_w 385 464 !$OMP THREADPRIVATE(kh, kh_x, kh_w) 465 #ifdef ISO 466 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:,:) :: dxtvdf_x, dxtvdf_w 467 !$OMP THREADPRIVATE(dxtvdf_x, dxtvdf_w) 468 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:,:) :: xt_therm 469 !$OMP THREADPRIVATE(xt_therm) 470 #endif 386 471 !!! 387 472 !!!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc … … 446 531 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:,:):: sij 447 532 !$OMP THREADPRIVATE(sij) 533 #ifdef ISO 534 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:,:) :: xtwdtrainA 535 !$OMP THREADPRIVATE(xtwdtrainA) 536 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:,:) :: xtev 537 !$OMP THREADPRIVATE(xtev) 538 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:,:) :: xttaa 539 !$OMP THREADPRIVATE(xttaa) 540 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:,:) :: xtclw 541 !$OMP THREADPRIVATE(xtclw) 542 #ifdef DIAGISO 543 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:) :: qlp 544 !$OMP THREADPRIVATE(qlp) 545 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:) :: qvp 546 !$OMP THREADPRIVATE(qvp) 547 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:) :: fq_detrainement 548 !$OMP THREADPRIVATE(fq_detrainement) 549 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:) :: fq_ddft 550 !$OMP THREADPRIVATE(fq_ddft) 551 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:) :: fq_fluxmasse 552 !$OMP THREADPRIVATE(fq_fluxmasse) 553 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:) :: fq_evapprecip 554 !$OMP THREADPRIVATE(fq_evapprecip) 555 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:) :: f_detrainement 556 !$OMP THREADPRIVATE(f_detrainement) 557 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:) :: q_detrainement 558 !$OMP THREADPRIVATE(q_detrainement) 559 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:,:) :: xt_detrainement 560 !$OMP THREADPRIVATE(xt_detrainement) 561 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:,:) :: xtlp 562 !$OMP THREADPRIVATE(xtlp) 563 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:,:) :: xtvp 564 !$OMP THREADPRIVATE(xtvp) 565 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:) :: q_the 566 !$OMP THREADPRIVATE(q_the) 567 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:,:) :: xt_the 568 !$OMP THREADPRIVATE(xt_the) 569 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:,:) :: fxt_detrainement 570 !$OMP THREADPRIVATE(fxt_detrainement) 571 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:,:) :: fxt_ddft 572 !$OMP THREADPRIVATE(fxt_ddft) 573 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:,:) :: fxt_fluxmasse 574 !$OMP THREADPRIVATE(fxt_fluxmasse) 575 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:,:) :: fxt_evapprecip 576 !$OMP THREADPRIVATE(fxt_evapprecip) 577 #endif 578 #endif 448 579 ! 449 580 ! REAL,ALLOCATABLE,SAVE,DIMENSION(:,:) :: coefh, coefm, lambda_th … … 481 612 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:) :: pfraclr,pfracld 482 613 !$OMP THREADPRIVATE(pfraclr,pfracld) 614 REAL, SAVE, ALLOCATABLE :: cldfraliq(:,:) 615 !$OMP THREADPRIVATE(cldfraliq) 616 REAL, SAVE, ALLOCATABLE ::mean_icefracturb(:,:) 617 !$OMP THREADPRIVATE(mean_icefracturb) 618 REAL, SAVE, ALLOCATABLE :: sigma2_icefracturb(:,:) 619 !$OMP THREADPRIVATE(sigma2_icefracturb) 483 620 484 621 ! variables de sorties MM … … 487 624 !$OMP THREADPRIVATE(zxsnow,snowhgt,qsnow,to_ice) 488 625 !$OMP THREADPRIVATE(sissnow,runoff,albsol3_lic) 626 #ifdef ISO 627 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:) :: zxxtsnow 628 !$OMP THREADPRIVATE(zxxtsnow) 629 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:,:) :: xtVprecip,xtVprecipi 630 !$OMP THREADPRIVATE(xtVprecip,xtVprecipi) 631 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:,:) :: pxtrfl, pxtsfl 632 !$OMP THREADPRIVATE(pxtrfl, pxtsfl) 633 #endif 489 634 490 635 REAL, ALLOCATABLE, SAVE, DIMENSION(:) :: p_tropopause, z_tropopause, t_tropopause … … 567 712 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:) :: R2SO4 568 713 !$OMP THREADPRIVATE(R2SO4) 714 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: R2SO4B 715 !$OMP THREADPRIVATE(R2SO4B) 569 716 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:) :: DENSO4 570 717 !$OMP THREADPRIVATE(DENSO4) 718 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:, :) :: DENSO4B 719 !$OMP THREADPRIVATE(DENSO4B) 571 720 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:) :: f_r_wet 572 721 !$OMP THREADPRIVATE(f_r_wet) 722 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:, :) :: f_r_wetB 723 !$OMP THREADPRIVATE(f_r_wetB) 573 724 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:) :: decfluxaer 574 725 !$OMP THREADPRIVATE(decfluxaer) … … 599 750 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:) :: vsed_aer 600 751 !$OMP THREADPRIVATE(vsed_aer) 752 ! Sulfate aerosol concentration (dry mixing ratio) (condensed H2SO4 mmr) 753 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:) :: sulfmmr 754 !$OMP THREADPRIVATE(sulfmmr) 755 ! SAD all aerosols (cm2/cm3) 756 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:) :: SAD_sulfate 757 !$OMP THREADPRIVATE(SAD_sulfate) 758 ! Effective radius of wet surface aerosols (cm) 759 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:) :: reff_sulfate 760 !$OMP THREADPRIVATE(reff_sulfate) 761 ! sulfate MMR in different modes (based on sulfmmr, it must be dry mmr) 762 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: sulfmmr_mode 763 !$OMP THREADPRIVATE(sulfmmr_mode) 764 ! particle concentration in different modes (part/m3) 765 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: nd_mode 766 !$OMP THREADPRIVATE(nd_mode) 601 767 ! 602 768 !---3D budget variables … … 647 813 SUBROUTINE phys_local_var_init 648 814 USE dimphy 649 USE infotrac_phy, ONLY : nbtr 815 USE infotrac_phy, ONLY : nbtr,nqtot 816 #ifdef ISO 817 USE infotrac_phy, ONLY : ntraciso=>ntiso,niso 818 #endif 650 819 USE aero_mod 651 820 USE indice_sol_mod 652 821 USE phys_output_var_mod 653 822 USE phys_state_var_mod 823 #ifdef CPP_StratAer 824 USE infotrac_phy, ONLY : nbtr_bin 825 #endif 654 826 655 827 IMPLICIT NONE 656 828 ALLOCATE(t_seri(klon,klev),q_seri(klon,klev),ql_seri(klon,klev),qs_seri(klon,klev), qbs_seri(klon,klev)) 829 ! SN 4D ISO 830 ALLOCATE(qx_seri(klon,klev,nqtot)) 831 ! SN 657 832 ALLOCATE(u_seri(klon,klev),v_seri(klon,klev)) 658 833 ALLOCATE(cf_seri(klon,klev),rvc_seri(klon,klev)) 659 834 ALLOCATE(l_mixmin(klon,klev+1,nbsrf),l_mix(klon,klev+1,nbsrf),wprime(klon,klev+1,nbsrf)) 660 835 ALLOCATE(pbl_eps(klon,klev+1,nbsrf+1)) 836 ALLOCATE(tke_shear(klon,klev+1,nbsrf), tke_buoy(klon,klev+1,nbsrf), tke_trans(klon,klev+1,nbsrf)) 661 837 pbl_eps(:,:,:)=0. 838 tke_shear(:,:,:)=0.; tke_buoy(:,:,:)=0.; tke_trans(:,:,:)=0. 662 839 l_mix(:,:,:)=0.;l_mixmin(:,:,:)=0.;wprime(:,:,:)=0. ! doit etre initialse car pas toujours remplis 663 840 ALLOCATE(rhcl(klon,klev)) … … 684 861 ALLOCATE(d_u_ajs(klon,klev),d_v_ajs(klon,klev)) 685 862 ALLOCATE(d_t_eva(klon,klev),d_q_eva(klon,klev)) 863 ! SN 4D ISO 864 ALLOCATE(d_qx_eva(klon,klev,nqtot)) 865 ! SN 686 866 ALLOCATE(d_ql_eva(klon,klev),d_qi_eva(klon,klev)) 687 867 ALLOCATE(d_t_lscst(klon,klev),d_q_lscst(klon,klev)) … … 690 870 ALLOCATE(d_t_vdf(klon,klev),d_q_vdf(klon,klev),d_t_diss(klon,klev)) 691 871 ALLOCATE (d_qbs_vdf(klon,klev)) 692 ALLOCATE(d_t_bs (klon,klev),d_q_bs(klon,klev),d_qbs_bs(klon,klev))872 ALLOCATE(d_t_bsss(klon,klev),d_q_bsss(klon,klev),d_qbs_bsss(klon,klev)) 693 873 ALLOCATE(d_t_vdf_w(klon,klev),d_q_vdf_w(klon,klev)) 694 874 ALLOCATE(d_t_vdf_x(klon,klev),d_q_vdf_x(klon,klev)) 875 #ifdef ISO 876 allocate(xt_seri(ntraciso,klon,klev)) 877 allocate(xtl_seri(ntraciso,klon,klev)) 878 allocate(xts_seri(ntraciso,klon,klev)) 879 allocate(xtbs_seri(ntraciso,klon,klev)) 880 allocate(d_xt_dyn(ntraciso,klon,klev)) 881 allocate(d_xtl_dyn(ntraciso,klon,klev)) 882 allocate(d_xts_dyn(ntraciso,klon,klev)) 883 allocate(d_xtbs_dyn(ntraciso,klon,klev)) 884 allocate(d_xt_con(ntraciso,klon,klev)) 885 allocate(d_xt_wake(ntraciso,klon,klev)) 886 allocate(d_xt_lsc(ntraciso,klon,klev)) 887 allocate(d_xtl_lsc(ntraciso,klon,klev)) 888 allocate(d_xti_lsc(ntraciso,klon,klev)) 889 allocate(d_xt_ajsb(ntraciso,klon,klev)) 890 allocate(d_xt_ajs(ntraciso,klon,klev)) 891 allocate(d_xt_ajs_w(ntraciso,klon,klev)) 892 allocate(d_xt_ajs_x(ntraciso,klon,klev)) 893 allocate(d_xt_eva(ntraciso,klon,klev)) 894 allocate(d_xtl_eva(ntraciso,klon,klev)) 895 allocate(d_xti_eva(ntraciso,klon,klev)) 896 allocate(d_xt_vdf(ntraciso,klon,klev)) 897 allocate(d_xt_vdf_w(ntraciso,klon,klev)) 898 allocate(d_xt_vdf_x(ntraciso,klon,klev)) 899 allocate(d_xt_ch4(ntraciso,klon,klev)) 900 allocate(d_xt_prod_nucl(ntraciso,klon,klev)) 901 allocate(d_xt_cosmo(ntraciso,klon,klev)) 902 allocate(d_xt_decroiss(ntraciso,klon,klev)) 903 #endif 695 904 696 905 ALLOCATE(d_u_vdf(klon,klev),d_v_vdf(klon,klev)) … … 704 913 ALLOCATE(d_ts(klon,nbsrf), d_tr(klon,klev,nbtr)) 705 914 706 ! aerosols707 ALLOCATE(m_allaer(klon,klev,naero_tot))708 915 ! Special RRTM 709 916 ALLOCATE(ZLWFT0_i(klon,klev+1),ZSWFT0_i(klon,klev+1),ZFLDN0(klon,klev+1)) … … 813 1020 !! ALLOCATE( d_s_the(klon), d_dens_the(klon)) 814 1021 ALLOCATE(d_deltat_ajs_cv(klon, klev), d_deltaq_ajs_cv(klon, klev)) 1022 #ifdef ISO 1023 ALLOCATE(d_deltaxt_wk(ntraciso,klon, klev)) 1024 ALLOCATE(d_deltaxt_wk_gw(ntraciso,klon, klev)) 1025 ALLOCATE(d_deltaxt_the(ntraciso,klon, klev)) 1026 ALLOCATE(d_deltaxt_vdf(ntraciso,klon, klev)) 1027 ALLOCATE(d_deltaxt_ajs_cv(ntraciso,klon, klev)) 1028 #endif 815 1029 !! End of wake variables 816 1030 !! … … 834 1048 ALLOCATE(zxfqcalving(klon), zxfluxlat(klon)) 835 1049 ALLOCATE(zxtsol(klon), snow_lsc(klon), zxfqfonte(klon), zxqsurf(klon)) 836 ALLOCATE(zxrunofflic(klon)) 1050 ! SN add runoff_diag 1051 ALLOCATE(zxrunofflic(klon), runoff_diag(klon)) 1052 runoff_diag(:)=0. 837 1053 ALLOCATE(zxustartlic(klon), zxrhoslic(klon), zxqsaltlic(klon)) 838 1054 zxustartlic(:)=0. ; zxrhoslic(:)=0. ; zxqsaltlic(:)=0. … … 841 1057 ALLOCATE(qlth(klon,klev), qith(klon,klev), qsith(klon,klev), wiceth(klon,klev)) 842 1058 ! 1059 #ifdef ISO 1060 ALLOCATE(xtevap(ntraciso,klon)) 1061 ALLOCATE(xtprw(ntraciso,klon)) 1062 ALLOCATE(zxfxtcalving(niso,klon)) 1063 ALLOCATE(xtsnow_lsc(ntraciso,klon), zxfxtfonte(niso,klon)) 1064 ALLOCATE(zxxtrunofflic(niso,klon)) 1065 ALLOCATE(xtrain_lsc(ntraciso,klon)) 1066 ALLOCATE(xtrunoff_diag(niso,klon)) 1067 ALLOCATE(h1_diag(klon)) 1068 !SN 1069 xtrunoff_diag(:,:)=0. ! because variables are only given values on knon grid points 1070 #endif 1071 ! 843 1072 ALLOCATE(sens_x(klon), sens_w(klon)) 844 1073 ALLOCATE(zxfluxlat_x(klon), zxfluxlat_w(klon)) … … 857 1086 ALLOCATE(cdragm_x(klon), cdragm_w(klon)) 858 1087 ALLOCATE(kh(klon), kh_x(klon), kh_w(klon)) 1088 #ifdef ISO 1089 ALLOCATE(dxtvdf_x(ntraciso,klon,klev), dxtvdf_w(ntraciso,klon,klev)) 1090 ALLOCATE(xt_therm(ntraciso,klon,klev)) 1091 #endif 859 1092 ! 860 1093 ALLOCATE(ptconv(klon,klev)) … … 912 1145 ALLOCATE(epmlmMm(klon,klev,klev), eplaMm(klon,klev)) 913 1146 ALLOCATE(sij(klon,klev,klev)) 1147 #ifdef ISO 1148 ALLOCATE(xtwdtrainA(ntraciso,klon,klev)) 1149 ALLOCATE(xtev(ntraciso,klon,klev) ) 1150 ALLOCATE(xttaa(ntraciso,klon,klev) ) 1151 ALLOCATE(xtclw(ntraciso,klon,klev) ) 1152 #ifdef DIAGISO 1153 ALLOCATE(qlp(klon,klev)) 1154 ALLOCATE(qvp(klon,klev)) 1155 ALLOCATE(fq_detrainement(klon,klev)) 1156 ALLOCATE(fq_ddft(klon,klev)) 1157 ALLOCATE(fq_fluxmasse(klon,klev)) 1158 ALLOCATE(fq_evapprecip(klon,klev)) 1159 ALLOCATE(f_detrainement(klon,klev), q_detrainement(klon,klev)) 1160 ALLOCATE(xtlp(ntraciso,klon,klev)) 1161 ALLOCATE(xtvp(ntraciso,klon,klev)) 1162 ALLOCATE(q_the(klon,klev), xt_the(ntraciso,klon,klev)) 1163 ALLOCATE(fxt_detrainement(ntraciso,klon,klev)) 1164 ALLOCATE(fxt_ddft(ntraciso,klon,klev)) 1165 ALLOCATE(fxt_fluxmasse(ntraciso,klon,klev)) 1166 ALLOCATE(fxt_evapprecip(ntraciso,klon,klev)) 1167 ALLOCATE(xt_detrainement(ntraciso,klon,klev)) 1168 #endif 1169 #endif 914 1170 915 1171 ALLOCATE(prfl(klon, klev+1)) … … 931 1187 ALLOCATE(pfraclr(klon,klev),pfracld(klon,klev)) 932 1188 pfraclr(:,:)=0. ; pfracld(:,:)=0. ! because not always defined 1189 ALLOCATE(cldfraliq(klon,klev)) 1190 ALLOCATE(sigma2_icefracturb(klon,klev)) 1191 ALLOCATE(mean_icefracturb(klon,klev)) 933 1192 ALLOCATE(distcltop(klon,klev)) 934 1193 ALLOCATE(temp_cltop(klon,klev)) … … 937 1196 ALLOCATE (zxsnow(klon),snowhgt(klon),qsnow(klon),to_ice(klon)) 938 1197 ALLOCATE (sissnow(klon),runoff(klon),albsol3_lic(klon)) 1198 #ifdef ISO 1199 ALLOCATE (zxxtsnow(niso,klon)) 1200 ALLOCATE(xtVprecip(ntraciso,klon, klev+1),xtVprecipi(ntraciso,klon, klev+1)) 1201 ALLOCATE(pxtsfl(ntraciso,klon, klev+1),pxtrfl(ntraciso,klon, klev+1)) 1202 #endif 939 1203 940 1204 ALLOCATE (p_tropopause(klon)) … … 968 1232 ALLOCATE (d_q_emiss(klon,klev)) 969 1233 ALLOCATE (R2SO4(klon,klev)) 1234 ALLOCATE (R2SO4B(klon,klev,nbtr_bin)) 970 1235 ALLOCATE (DENSO4(klon,klev)) 1236 ALLOCATE (DENSO4B(klon,klev,nbtr_bin)) 971 1237 ALLOCATE (f_r_wet(klon,klev)) 1238 ALLOCATE (f_r_wetB(klon,klev,nbtr_bin)) 972 1239 ALLOCATE (decfluxaer(klon,nbtr)) 973 1240 ALLOCATE (mdw(nbtr)) … … 1006 1273 ALLOCATE (surf_PM25_sulf(klon)) 1007 1274 ALLOCATE (vsed_aer(klon,klev)) 1275 ALLOCATE (sulfmmr(klon,klev)) 1276 ALLOCATE (SAD_sulfate(klon,klev)) 1277 ALLOCATE (reff_sulfate(klon,klev)) 1278 ALLOCATE (sulfmmr_mode(klon,klev,nbtr_bin)) 1279 ALLOCATE (nd_mode(klon,klev,nbtr_bin)) 1008 1280 #endif 1009 1281 … … 1016 1288 IMPLICIT NONE 1017 1289 DEALLOCATE(t_seri,q_seri,ql_seri,qs_seri, qbs_seri) 1290 ! SN 4D ISO 1291 DEALLOCATE(qx_seri) 1292 ! SN 1018 1293 DEALLOCATE(u_seri,v_seri) 1019 1294 DEALLOCATE(cf_seri,rvc_seri) 1020 1295 DEALLOCATE(l_mixmin,l_mix,wprime) 1296 DEALLOCATE(tke_shear,tke_buoy,tke_trans) 1021 1297 DEALLOCATE(pbl_eps) 1022 1298 DEALLOCATE(rhcl) … … 1043 1319 DEALLOCATE(d_u_ajs,d_v_ajs) 1044 1320 DEALLOCATE(d_t_eva,d_q_eva) 1321 ! SN 4D ISO 1322 DEALLOCATE(d_qx_eva) 1323 ! SN 1045 1324 DEALLOCATE(d_ql_eva,d_qi_eva) 1046 1325 DEALLOCATE(d_t_lscst,d_q_lscst) … … 1049 1328 DEALLOCATE(d_t_vdf,d_q_vdf,d_t_diss) 1050 1329 DEALLOCATE(d_qbs_vdf) 1051 DEALLOCATE(d_t_bs,d_q_bs,d_qbs_bs) 1330 DEALLOCATE(d_t_bsss,d_q_bsss,d_qbs_bsss) 1331 #ifdef ISO 1332 deallocate(xt_seri,xtl_seri,xts_seri,xtbs_seri) 1333 DEALLOCATE(d_xtl_eva,d_xti_eva) 1334 deallocate(d_xt_dyn,d_xtl_dyn,d_xts_dyn,d_xtbs_dyn) 1335 deallocate(d_xt_con) 1336 deallocate(d_xt_wake) 1337 deallocate(d_xt_lsc) 1338 deallocate(d_xtl_lsc,d_xti_lsc) 1339 deallocate(d_xt_ajsb) 1340 deallocate(d_xt_ajs) 1341 deallocate(d_xt_ajs_w,d_xt_ajs_x) 1342 deallocate(d_xt_eva) 1343 deallocate(d_xtl_eva) 1344 deallocate(d_xti_eva) 1345 deallocate(d_xt_vdf) 1346 deallocate(d_xt_vdf_w,d_xt_vdf_x) 1347 deallocate(d_xt_ch4) 1348 deallocate(d_xt_prod_nucl) 1349 deallocate(d_xt_cosmo) 1350 deallocate(d_xt_decroiss) 1351 #endif 1352 1052 1353 DEALLOCATE(d_u_vdf,d_v_vdf) 1053 1354 DEALLOCATE(d_t_oli,d_t_oro) … … 1121 1422 DEALLOCATE(solsw_aerop, solsw0_aerop) 1122 1423 DEALLOCATE(topswcf_aerop, solswcf_aerop) 1123 !AI Aerosols1124 DEALLOCATE(m_allaer)1125 1424 !CK LW diagnostics 1126 1425 DEALLOCATE(toplwad_aerop, sollwad_aerop) … … 1155 1454 !! DEALLOCATE( d_s_the, d_dens_the) 1156 1455 DEALLOCATE(d_deltat_ajs_cv, d_deltaq_ajs_cv) 1456 #ifdef ISO 1457 DEALLOCATE(d_deltaxt_wk) 1458 DEALLOCATE(d_deltaxt_wk_gw) 1459 DEALLOCATE(d_deltaxt_ajs_cv) 1460 DEALLOCATE(d_deltaxt_vdf) 1461 #endif 1157 1462 ! 1158 1463 DEALLOCATE(bils) … … 1173 1478 DEALLOCATE(uwat, vwat) 1174 1479 DEALLOCATE(zxfqcalving, zxfluxlat) 1175 DEALLOCATE(zxrunofflic) 1480 ! SN runoff_diag 1481 DEALLOCATE(zxrunofflic, runoff_diag) 1176 1482 DEALLOCATE(zxustartlic, zxrhoslic, zxqsaltlic) 1177 1483 DEALLOCATE(zxtsol, snow_lsc, zxfqfonte, zxqsurf) … … 1194 1500 DEALLOCATE(cdragm_x, cdragm_w) 1195 1501 DEALLOCATE(kh, kh_x, kh_w) 1502 #ifdef ISO 1503 DEALLOCATE(xtevap,xtprw) 1504 DEALLOCATE(zxfxtcalving) 1505 DEALLOCATE(zxxtrunofflic) 1506 DEALLOCATE(xtsnow_lsc, zxfxtfonte) 1507 DEALLOCATE(xtrain_lsc) 1508 DEALLOCATE(dxtvdf_x, dxtvdf_w) 1509 DEALLOCATE(xt_therm) 1510 DEALLOCATE(h1_diag,xtrunoff_diag) 1511 #endif 1196 1512 ! 1197 1513 DEALLOCATE(ptconv) … … 1243 1559 DEALLOCATE(epmlmMm, eplaMm) 1244 1560 DEALLOCATE(sij) 1561 #ifdef ISO 1562 DEALLOCATE(xtwdtrainA) 1563 DEALLOCATE(xttaa ) 1564 DEALLOCATE(xtclw ) 1565 DEALLOCATE(xtev ) 1566 #ifdef DIAGISO 1567 DEALLOCATE(qlp) 1568 DEALLOCATE(qvp) 1569 DEALLOCATE(fq_detrainement) 1570 DEALLOCATE(fq_ddft) 1571 DEALLOCATE(fq_fluxmasse) 1572 DEALLOCATE(fq_evapprecip) 1573 DEALLOCATE(f_detrainement,q_detrainement) 1574 DEALLOCATE(xtlp) 1575 DEALLOCATE(xtvp) 1576 DEALLOCATE(q_the,xt_the) 1577 DEALLOCATE(fxt_detrainement) 1578 DEALLOCATE(fxt_ddft) 1579 DEALLOCATE(fxt_fluxmasse) 1580 DEALLOCATE(fxt_evapprecip) 1581 DEALLOCATE(xt_detrainement) 1582 #endif 1583 #endif 1245 1584 1246 1585 … … 1259 1598 DEALLOCATE(rneb) 1260 1599 DEALLOCATE(pfraclr,pfracld) 1600 DEALLOCATE(cldfraliq) 1601 DEALLOCATE(sigma2_icefracturb) 1602 DEALLOCATE(mean_icefracturb) 1261 1603 DEALLOCATE (zxsnow,snowhgt,qsnow,to_ice,sissnow,runoff,albsol3_lic) 1262 1604 DEALLOCATE(distcltop) 1263 1605 DEALLOCATE(temp_cltop) 1606 #ifdef ISO 1607 DEALLOCATE (zxxtsnow,xtVprecip,xtVprecipi,pxtrfl,pxtsfl) 1608 #endif 1609 1264 1610 DEALLOCATE (p_tropopause) 1265 1611 DEALLOCATE (z_tropopause) … … 1291 1637 ! variables for strat. aerosol CK 1292 1638 DEALLOCATE (d_q_emiss) 1293 DEALLOCATE (R2SO4 )1294 DEALLOCATE (DENSO4 )1295 DEALLOCATE (f_r_wet )1639 DEALLOCATE (R2SO4, R2SO4B) 1640 DEALLOCATE (DENSO4, DENSO4B) 1641 DEALLOCATE (f_r_wet, f_r_wetB) 1296 1642 DEALLOCATE (decfluxaer) 1297 1643 DEALLOCATE (mdw) … … 1308 1654 DEALLOCATE (surf_PM25_sulf) 1309 1655 DEALLOCATE (vsed_aer) 1656 DEALLOCATE (sulfmmr) 1657 DEALLOCATE (SAD_sulfate) 1658 DEALLOCATE (reff_sulfate) 1659 DEALLOCATE (sulfmmr_mode) 1660 DEALLOCATE (nd_mode) 1310 1661 DEALLOCATE (budg_3D_ocs_to_so2) 1311 1662 DEALLOCATE (budg_3D_so2_to_h2so4) -
LMDZ6/branches/cirrus/libf/phylmd/phys_output_ctrlout_mod.F90
r4951 r5202 1112 1112 TYPE(ctrl_out), SAVE :: o_tke = ctrl_out((/ 4, 10, 10, 10, 10, 10, 11, 11, 11, 11/), & 1113 1113 'tke ', 'TKE', 'm2/s2', (/ ('', i=1, 10) /)) 1114 TYPE(ctrl_out), SAVE :: o_tke_shear = ctrl_out((/ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11/), & 1115 'tke_shear ', 'TKE shear term', 'm2/s3', (/ ('', i=1, 10) /)) 1116 TYPE(ctrl_out), SAVE :: o_tke_buoy = ctrl_out((/ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11/), & 1117 'tke_buoy ', 'TKE buoyancy term', 'm2/s3', (/ ('', i=1, 10) /)) 1118 TYPE(ctrl_out), SAVE :: o_tke_trans = ctrl_out((/ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11/), & 1119 'tke_trans ', 'TKE transport term', 'm2/s3', (/ ('', i=1, 10) /)) 1114 1120 TYPE(ctrl_out), SAVE :: o_tke_dissip = ctrl_out((/ 10, 10, 10, 10, 10, 10, 11, 11, 11, 11/), & 1115 'tke_dissip ', 'TKE DISSIPATION', 'm2/s3', (/ ('', i=1, 10) /)) 1121 'tke_dissip ', 'TKE dissipation term', 'm2/s3', (/ ('', i=1, 10) /)) 1122 1116 1123 TYPE(ctrl_out), SAVE :: o_tke_max = ctrl_out((/ 4, 10, 10, 10, 10, 10, 11, 11, 11, 11/), & 1117 1124 'tke_max', 'TKE max', 'm2/s2', & … … 1442 1449 TYPE(ctrl_out), SAVE :: o_tau_strat_1020 = ctrl_out((/ 11, 11, 11, 11, 11, 11, 11, 11, 11, 1/), & 1443 1450 'OD1020_strat_only', 'Stratospheric Aerosol Optical depth at 1020 nm ', '1', (/ ('', i=1, 10) /)) 1451 TYPE(ctrl_out), SAVE :: o_SAD_sulfate = ctrl_out((/ 11, 11, 11, 11, 11, 11, 11, 11, 11, 1/), & 1452 'SAD_sulfate', 'SAD WET sulfate aerosols', 'cm2/cm3', (/ ('', i=1, 10) /)) 1453 TYPE(ctrl_out), SAVE :: o_reff_sulfate = ctrl_out((/ 11, 11, 11, 11, 11, 11, 11, 11, 11, 1/), & 1454 'reff_sulfate', 'Effective radius of WET sulfate aerosols', 'cm', (/ ('', i=1, 10) /)) 1455 TYPE(ctrl_out), SAVE :: o_sulfmmr = ctrl_out((/ 11, 11, 11, 11, 11, 11, 11, 11, 11, 1/), & 1456 'sulfMMR', 'Sulfate aerosol concentration (dry mass mixing ratio)', 'kg(H2SO4)/kg(air)', (/ ('', i=1, 10) /)) 1457 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_nd_mode(:) 1458 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_sulfmmr_mode(:) 1444 1459 !--chemistry 1445 1460 TYPE(ctrl_out), SAVE :: o_R2SO4 = ctrl_out((/ 11, 11, 11, 11, 11, 11, 11, 11, 11, 1/), & … … 1551 1566 TYPE(ctrl_out), SAVE :: o_rneb = ctrl_out((/ 2, 5, 10, 10, 10, 10, 11, 11, 11, 11/), & 1552 1567 'rneb', 'Cloud fraction', '-', (/ ('', i=1, 10) /)) 1568 TYPE(ctrl_out), SAVE :: o_cldfraliq = ctrl_out((/ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11/), & 1569 'cldfraliq', 'Liquid fraction of the cloud', '-', (/ ('', i=1, 10) /)) 1570 TYPE(ctrl_out), SAVE :: o_sigma2_icefracturb = ctrl_out((/ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11/), & 1571 'sigma2_icefracturb', 'Variance of the diagnostic supersaturation distribution (icefrac_turb) [-]', '-', (/ ('', i=1, 10) /)) 1572 TYPE(ctrl_out), SAVE :: o_mean_icefracturb = ctrl_out((/ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11/), & 1573 'mean_icefracturb', 'Mean of the diagnostic supersaturation distribution (icefrac_turb) [-]', '-', (/ ('', i=1, 10) /)) 1574 1553 1575 TYPE(ctrl_out), SAVE :: o_rnebjn = ctrl_out((/ 2, 5, 10, 10, 10, 10, 11, 11,11, 11/), & 1554 1576 'rnebjn', 'Cloud fraction in day', '-', (/ ('', i=1, 10) /)) … … 1981 2003 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_dtr_dry(:) 1982 2004 2005 #ifdef ISO 2006 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_xtprecip(:) 2007 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_xtevap(:) 2008 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_xtevap_srf(:,:) ! ajout Camille 8 mai 2023 2009 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_xtplul(:) 2010 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_xtpluc(:) 2011 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_xtovap(:) 2012 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_xtoliq(:) 2013 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_xtcond(:) 2014 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_xtrunoff_diag(:) 2015 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_dxtdyn(:) 2016 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_dxtldyn(:) 2017 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_dxtvdf(:) 2018 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_dxtcon(:) 2019 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_dxtlsc(:) 2020 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_dxteva(:) 2021 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_dxtajs(:) 2022 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_dxtthe(:) 2023 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_dxtch4(:) 2024 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_dxtprod_nucl(:) 2025 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_dxtcosmo(:) 2026 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_dxtdecroiss(:) 2027 #endif 2028 1983 2029 TYPE(ctrl_out), SAVE :: o_rsu = ctrl_out((/ 4, 10, 10, 10, 10, 10, 11, 11, 11, 11/), & 1984 2030 'rsu', 'SW upward radiation', 'W m-2', (/ ('', i=1, 10) /)) … … 2064 2110 TYPE(ctrl_out), SAVE :: o_runoff = ctrl_out((/ 1, 1, 10, 1, 10, 10, 11, 11, 11, 11/), & 2065 2111 'runoff', 'Run-off rate land ice', 'kg/m2/s', (/ ('', i=1, 10) /)) 2112 ! SN add runoff_diag 2113 !#ifdef ISO 2114 TYPE(ctrl_out), SAVE :: o_runoff_diag = ctrl_out((/ 1, 1, 10, 1, 10, 10, 11, 11, 11, 11/), & 2115 'runoffland', 'Run-off rate land for bucket', 'kg/m2/s', (/ ('', i=1, 10) /)) 2116 !#endif 2066 2117 TYPE(ctrl_out), SAVE :: o_albslw3 = ctrl_out((/ 1, 1, 1, 1, 10, 10, 11, 11, 11, 11/), & 2067 2118 'albslw3', 'Surface albedo LW3', '-', (/ ('', i=1, 10) /)) -
LMDZ6/branches/cirrus/libf/phylmd/phys_output_mod.F90
r4619 r5202 35 35 USE iophy 36 36 USE dimphy 37 USE infotrac_phy, ONLY: nqtot, tracers, niso 37 USE infotrac_phy, ONLY: nqtot, tracers, niso, ntraciso=>ntiso 38 38 USE strings_mod, ONLY: maxlen 39 39 USE ioipsl … … 49 49 ! ug Pour les sorties XIOS 50 50 USE wxios 51 #ifdef CPP_StratAer 52 USE infotrac_phy, ONLY: nbtr_bin 53 #endif 54 #ifdef ISO 55 USE isotopes_mod, ONLY: isoName,iso_HTO 56 #ifdef ISOTRAC 57 use isotrac_mod, only: index_zone,index_iso,strtrac 58 #endif 59 #endif 51 60 52 61 IMPLICIT NONE … … 93 102 CHARACTER(LEN=4), DIMENSION(nlevSTD) :: clevSTD 94 103 REAL, DIMENSION(nlevSTD) :: rlevSTD 95 INTEGER :: nsrf, k, iq, iff, i, j, ilev, itr, i xt, iiso, izone104 INTEGER :: nsrf, k, iq, iff, i, j, ilev, itr, itrb, ixt, iiso, izone 96 105 INTEGER :: naero 97 106 LOGICAL :: ok_veget … … 112 121 LOGICAL, DIMENSION(nfiles) :: phys_out_filestations 113 122 123 #ifdef ISO 124 CHARACTER(LEN=maxlen) :: outiso 125 CHARACTER(LEN=20) :: unit 126 #endif 114 127 CHARACTER(LEN=maxlen) :: tnam, lnam, dn 115 128 INTEGER :: flag(nfiles) … … 158 171 ALLOCATE(o_dtr_sscav(nqtot),o_dtr_sat(nqtot),o_dtr_uscav(nqtot)) 159 172 ALLOCATE(o_dtr_dry(nqtot),o_dtr_vdf(nqtot)) 173 #ifdef CPP_StratAer 174 ALLOCATE(o_nd_mode(nbtr_bin),o_sulfmmr_mode(nbtr_bin)) 175 #endif 176 #ifdef ISO 177 ALLOCATE(o_xtprecip(ntraciso)) 178 ALLOCATE(o_xtplul(ntraciso)) 179 ALLOCATE(o_xtpluc(ntraciso)) 180 ALLOCATE(o_xtevap(ntraciso)) 181 ALLOCATE(o_xtevap_srf(ntraciso,4)) 182 ALLOCATE(o_xtovap(ntraciso)) 183 ALLOCATE(o_xtoliq(ntraciso)) 184 ALLOCATE(o_xtcond(ntraciso)) 185 ALLOCATE(o_xtrunoff_diag(ntraciso)) 186 ALLOCATE(o_dxtdyn(ntraciso)) 187 ALLOCATE(o_dxtldyn(ntraciso)) 188 ALLOCATE(o_dxtcon(ntraciso)) 189 ALLOCATE(o_dxtlsc(ntraciso)) 190 ALLOCATE(o_dxteva(ntraciso)) 191 ALLOCATE(o_dxtajs(ntraciso)) 192 ALLOCATE(o_dxtvdf(ntraciso)) 193 ALLOCATE(o_dxtthe(ntraciso)) 194 ALLOCATE(o_dxtch4(ntraciso)) 195 if (iso_HTO.gt.0) then 196 ALLOCATE(o_dxtprod_nucl(ntraciso)) 197 ALLOCATE(o_dxtcosmo(ntraciso)) 198 ALLOCATE(o_dxtdecroiss(ntraciso)) 199 endif 200 #endif 160 201 161 202 levmax = [klev, klev, klev, klev, klev, klev, nlevSTD, nlevSTD, nlevSTD, klev] … … 467 508 ENDIF ! clef_files 468 509 469 itr = 0 510 itr = 0; itrb = 0 470 511 DO iq = 1, nqtot 471 512 IF(.NOT.(tracers(iq)%isAdvected .AND. tracers(iq)%isInPhysics)) CYCLE … … 503 544 lnam = 'Cumulated tracer '//TRIM(tracers(iq)%longName) 504 545 tnam = 'cum'//TRIM(tracers(iq)%name); o_trac_cum(itr) = ctrl_out(flag, tnam, lnam, "-", [('',i=1,nfiles)]) 505 ENDDO 546 547 #ifdef CPP_StratAer 548 if(tracers(iq)%name(1:3)=='BIN') then 549 itrb = itrb + 1 550 flag = [11, 11, 11, 11, 11, 11, 11, 11, 11, 1] 551 lnam = 'Dry particle concentration in '//TRIM(tracers(iq)%longName) 552 tnam = TRIM(tracers(iq)%name)//'_nd_mode'; o_nd_mode (itrb) = ctrl_out(flag, tnam, lnam, "part/m3", [('',i=1,nfiles)]) 553 lnam = 'Sulfate MMR in '//TRIM(tracers(iq)%longName) 554 tnam = TRIM(tracers(iq)%name)//'_sulfmmr_mode';o_sulfmmr_mode (itrb) = ctrl_out(flag, tnam, lnam, "kg(H2SO4)/kg(air)", [('',i=1,nfiles)]) 555 endif 556 #endif 557 ENDDO 506 558 507 559 ENDDO ! iff 508 560 509 ! Updated write frequencies due to phys_out_filetimesteps. 561 #ifdef ISO 562 write(*,*) 'phys_output_mid 589' 563 do ixt=1,ntraciso 564 outiso = TRIM(isoName(ixt)) 565 i = INDEX(outiso, '_', .TRUE.) 566 outiso = outiso(1:i-1)//outiso(i+1:LEN_TRIM(outiso)) 567 568 flag = [1, 1, 1, 10, 5, 10, 11, 11, 11, 11]; unit = 'kg/(s*m2)' 569 o_xtprecip(ixt)=ctrl_out(flag, 'precip'//TRIM(outiso), 'Precip Totale liq+sol', unit, [('',i=1,nfiles)]) 570 o_xtpluc (ixt)=ctrl_out(flag, 'pluc'//TRIM(outiso), 'Convective Precip.', unit, [('',i=1,nfiles)]) 571 572 flag = [1, 1, 1, 10, 10, 10, 11, 11, 11, 11] 573 o_xtplul (ixt)=ctrl_out(flag, 'plul'//TRIM(outiso), 'Large-scale Precip.', unit, [('',i=1,nfiles)]) 574 o_xtevap (ixt)=ctrl_out(flag, 'evap'//TRIM(outiso), 'Evaporat.', unit, [('',i=1,nfiles)]) 575 576 ! ajout Camille 8 mai 2023 577 flag = [1, 6, 10, 10, 10, 10, 11, 11, 11, 11] 578 o_xtevap_srf (ixt,1)=ctrl_out(flag, 'evap_ter'//TRIM(outiso), 'Evap sfc'//clnsurf(1), unit, [('',i=1,nfiles)]) 579 o_xtevap_srf (ixt,2)=ctrl_out(flag, 'evap_lic'//TRIM(outiso), 'Evap sfc'//clnsurf(2), unit, [('',i=1,nfiles)]) 580 o_xtevap_srf (ixt,3)=ctrl_out(flag, 'evap_oce'//TRIM(outiso), 'Evap sfc'//clnsurf(3), unit, [('',i=1,nfiles)]) 581 o_xtevap_srf (ixt,4)=ctrl_out(flag, 'evap_sic'//TRIM(outiso), 'Evap sfc'//clnsurf(4), unit, [('',i=1,nfiles)]) 582 583 flag = [2, 3, 4, 10, 10, 10, 11, 11, 11, 11]; unit = 'kg/kg' 584 o_xtovap (ixt)=ctrl_out(flag, 'ovap'//TRIM(outiso), 'Specific humidity', unit, [('',i=1,nfiles)]) 585 o_xtoliq (ixt)=ctrl_out(flag, 'oliq'//TRIM(outiso), 'Liquid water', unit, [('',i=1,nfiles)]) 586 o_xtcond (ixt)=ctrl_out(flag, 'ocond'//TRIM(outiso), 'Condensed water', unit, [('',i=1,nfiles)]) 587 588 flag = [1, 1, 1, 10, 5, 10, 11, 11, 11, 11]; unit = 'kg/m2/s' 589 o_xtrunoff_diag (ixt)=ctrl_out(flag, 'runoffland'//TRIM(outiso), 'Run-off rate land for bucket', unit, [('',i=1,nfiles)]) 590 591 flag = [4, 10, 10, 10, 10, 10, 11, 11, 11, 11]; unit = '(kg/kg)/s' 592 o_dxtdyn (ixt)=ctrl_out(flag, 'dqdyn'//TRIM(outiso), 'Dynamics dQ', unit, [('',i=1,nfiles)]) 593 o_dxtldyn (ixt)=ctrl_out(flag, 'dqldyn'//TRIM(outiso), 'Dynamics dQL', unit, [('',i=1,nfiles)]) 594 o_dxtcon (ixt)=ctrl_out(flag, 'dqcon'//TRIM(outiso), 'Convection dQ', unit, [('',i=1,nfiles)]) 595 o_dxteva (ixt)=ctrl_out(flag, 'dqeva'//TRIM(outiso), 'Reevaporation dQ', unit, [('',i=1,nfiles)]) 596 o_dxtlsc (ixt)=ctrl_out(flag, 'dqlsc'//TRIM(outiso), 'Condensation dQ', unit, [('',i=1,nfiles)]) 597 o_dxtajs (ixt)=ctrl_out(flag, 'dqajs'//TRIM(outiso), 'Dry adjust. dQ', unit, [('',i=1,nfiles)]) 598 o_dxtvdf (ixt)=ctrl_out(flag, 'dqvdf'//TRIM(outiso), 'Boundary-layer dQ', unit, [('',i=1,nfiles)]) 599 o_dxtthe (ixt)=ctrl_out(flag, 'dqthe'//TRIM(outiso), 'Thermal dQ', unit, [('',i=1,nfiles)]) 600 601 IF(ok_qch4) o_dxtch4(ixt)=ctrl_out(flag, 'dqch4'//TRIM(outiso), 'H2O due to CH4 oxidation & photolysis', & 602 unit, [('',i=1,nfiles)]) 603 IF(ixt == iso_HTO) THEN 604 o_dxtprod_nucl(ixt)=ctrl_out(flag, 'dqprodnucl'//TRIM(outiso), 'dHTO/dt due to nuclear production', & 605 unit, [('',i=1,nfiles)]) 606 o_dxtcosmo (ixt)=ctrl_out(flag, 'dqcosmo'//TRIM(outiso), 'dHTO/dt due to cosmogenic production', & 607 unit, [('',i=1,nfiles)]) 608 o_dxtdecroiss (ixt)=ctrl_out(flag, 'dqdecroiss'//TRIM(outiso), 'dHTO/dt due to radiative destruction', & 609 unit, [('',i=1,nfiles)]) 610 END IF 611 enddo !do ixt=1,niso 612 write(*,*) 'phys_output_mid 596' 613 #endif 614 615 ! Updated write frequencies due to phys_out_filetimesteps. 510 616 ! Write frequencies are now in seconds. 511 617 ecrit_mth = ecrit_files(1) -
LMDZ6/branches/cirrus/libf/phylmd/phys_output_write_mod.F90
r4951 r5202 65 65 o_fder, o_ffonte, o_fqcalving, o_fqfonte, o_mrroli, o_runofflic, & 66 66 o_taux, o_tauy, o_snowsrf, o_qsnow, & 67 o_snowhgt, o_toice, o_sissnow, o_runoff, & 67 ! SN runoff_diag 68 o_snowhgt, o_toice, o_sissnow, o_runoff, o_runoff_diag, & 68 69 o_albslw3, o_pourc_srf, o_fract_srf, & 69 70 o_taux_srf, o_tauy_srf, o_tsol_srf, & … … 141 142 o_zfull, o_zhalf, o_rneb, o_rnebjn, o_rnebcon, & 142 143 o_rnebls, o_rneblsvol, o_rhum, o_rhl, o_rhi, o_ozone, o_ozone_light, & 143 o_pfraclr, o_pfracld, &144 o_pfraclr, o_pfracld, o_cldfraliq, o_sigma2_icefracturb, o_mean_icefracturb, & 144 145 o_qrainlsc, o_qsnowlsc, o_dqreva, o_dqrauto, o_dqrcol, o_dqrmelt, o_dqrfreez, & 145 146 o_dqssub, o_dqsauto, o_dqsagg, o_dqsrim, o_dqsmelt, o_dqsfreez, & … … 147 148 o_dqsphy, o_dqsphy2d, o_dqbsphy, o_dqbsphy2d, o_albe_srf, o_z0m_srf, o_z0h_srf, & 148 149 o_ages_srf, o_snow_srf, o_alb1, o_alb2, o_tke, o_tke_dissip, & 149 o_tke_max, o_kz, o_kz_max, o_clwcon, &150 o_tke_max, o_kz, o_kz_max, o_clwcon, o_tke_shear, o_tke_buoy, o_tke_trans, & 150 151 o_dtdyn, o_dqdyn, o_dqdyn2d, o_dqldyn, o_dqldyn2d, & 151 152 o_dqsdyn, o_dqsdyn2d, o_dqbsdyn, o_dqbsdyn2d, o_dudyn, o_dvdyn, & … … 208 209 ! Isotopes 209 210 o_xtprecip,o_xtplul,o_xtpluc,o_xtovap,o_xtoliq,o_xtcond, & 211 o_xtrunoff_diag, & 210 212 o_xtevap,o_dxtdyn,o_dxtldyn,o_dxtcon,o_dxtlsc,o_dxteva, & 211 213 o_dxtajs,o_dxtvdf,o_dxtthe, o_dxtch4, & … … 248 250 249 251 #ifdef CPP_StratAer 252 USE infotrac_phy, ONLY: nbtr_bin 250 253 USE phys_output_ctrlout_mod, ONLY: & 251 254 o_budg_3D_nucl, o_budg_3D_cond_evap, o_budg_3D_ocs_to_so2, o_budg_3D_so2_to_h2so4, & … … 259 262 o_budg_ocs_to_so2, o_budg_so2_to_h2so4, o_budg_h2so4_to_part, & 260 263 o_surf_PM25_sulf, o_ext_strat_550, o_tau_strat_550, & 261 o_vsed_aer, o_tau_strat_1020, o_ext_strat_1020, o_f_r_wet 264 o_vsed_aer, o_tau_strat_1020, o_ext_strat_1020, o_f_r_wet, & 265 o_SAD_sulfate, o_reff_sulfate, o_sulfmmr, o_nd_mode, o_sulfmmr_mode 262 266 #endif 263 267 … … 314 318 zn2mout, t2m_min_mon, t2m_max_mon, evap, & 315 319 snowerosion, zxustartlic, zxrhoslic, zxqsaltlic, & 316 l_mixmin,l_mix, pbl_eps, &320 l_mixmin,l_mix, pbl_eps, tke_shear, tke_buoy, tke_trans, & 317 321 zu10m, zv10m, zq2m, zustar, zxqsurf, & 318 322 rain_lsc, rain_num, snow_lsc, bils, sens, fder, & 319 323 zxffonte, zxfqcalving, zxfqfonte, zxrunofflic, fluxu, & 320 324 fluxv, zxsnow, qsnow, snowhgt, to_ice, & 321 sissnow, runoff, albsol3_lic, evap_pot, & 325 ! SN runoff_diag 326 sissnow, runoff, runoff_diag, albsol3_lic, evap_pot, & 322 327 t2m, fluxt, fluxlat, fsollw, fsolsw, & 323 328 wfbils, wfevap, & … … 367 372 ql_seri, qs_seri, qbs_seri, tr_seri, qbs_seri,& 368 373 zphi, u_seri, v_seri, omega, cldfra, & 369 rneb, rnebjn, rneblsvol, zx_rh, zx_rhl, zx_rhi, & 370 pfraclr, pfracld, & 374 rneb, rnebjn, rneblsvol, & 375 zx_rh, zx_rhl, zx_rhi, & 376 pfraclr, pfracld, cldfraliq, sigma2_icefracturb, mean_icefracturb, & 371 377 qraindiag, qsnowdiag, dqreva, dqssub, & 372 378 dqrauto,dqrcol,dqrmelt,dqrfreez, & … … 382 388 d_t_lscst, d_q_lscth, d_q_lscst, plul_th, & 383 389 plul_st, d_t_vdf, d_t_diss, d_q_vdf, d_q_eva, & 384 d_t_bs , d_q_bs, d_qbs_bs, d_qbs_vdf, &390 d_t_bsss, d_q_bsss, d_qbs_bsss, d_qbs_vdf, & 385 391 zw2, fraca, zmax_th, d_q_ajsb, d_t_ec, d_u_vdf, & 386 392 d_v_vdf, d_u_oro, d_v_oro, d_t_oro, d_u_lif, & … … 395 401 d_xt_ajs, d_xt_ajsb, & 396 402 d_xt_prod_nucl,d_xt_cosmo,d_xt_decroiss, & 403 xtrunoff_diag, & 397 404 #endif 398 405 ep, epmax_diag, & ! epmax_cape … … 416 423 budg_ocs_to_so2, budg_so2_to_h2so4, budg_h2so4_to_part, & 417 424 surf_PM25_sulf, tau_strat_550, tausum_strat, & 418 vsed_aer, tau_strat_1020, f_r_wet 425 vsed_aer, tau_strat_1020, f_r_wet, & 426 SAD_sulfate, reff_sulfate, sulfmmr, nd_mode, sulfmmr_mode 419 427 #endif 420 428 … … 449 457 USE indice_sol_mod, ONLY: nbsrf 450 458 #ifdef ISO 451 USE isotopes_mod, ONLY: iso_HTO 459 USE isotopes_mod, ONLY: iso_HTO, isoName 452 460 #endif 453 461 USE geometry_mod, ONLY: cell_area, latitude_deg, longitude_deg … … 530 538 CHARACTER(LEN=maxlen) :: unt 531 539 #endif 540 541 #ifdef ISO 542 CHARACTER(LEN=maxlen) :: outiso 543 #endif 544 532 545 REAL,DIMENSION(klon,klev) :: z, dz 533 546 REAL,DIMENSION(klon) :: zrho, zt … … 1310 1323 1311 1324 ENDDO 1312 1313 1325 1326 1314 1327 IF (iflag_pbl > 1) THEN 1315 1328 zx_tmp_fi3d=0. … … 1323 1336 ENDIF 1324 1337 1325 CALL histwrite_phy(o_tke_dissip, zx_tmp_fi3d) 1338 CALL histwrite_phy(o_tke_dissip, zx_tmp_fi3d) 1339 1340 zx_tmp_fi3d=0. 1341 IF (vars_defined) THEN 1342 DO nsrf=1,nbsrf 1343 DO k=1,klev 1344 zx_tmp_fi3d(:,k)=zx_tmp_fi3d(:,k) & 1345 +pctsrf(:,nsrf)*tke_shear(:,k,nsrf) 1346 ENDDO 1347 ENDDO 1348 ENDIF 1349 1350 CALL histwrite_phy(o_tke_shear, zx_tmp_fi3d) 1351 1352 zx_tmp_fi3d=0. 1353 IF (vars_defined) THEN 1354 DO nsrf=1,nbsrf 1355 DO k=1,klev 1356 zx_tmp_fi3d(:,k)=zx_tmp_fi3d(:,k) & 1357 +pctsrf(:,nsrf)*tke_buoy(:,k,nsrf) 1358 ENDDO 1359 ENDDO 1360 ENDIF 1361 1362 CALL histwrite_phy(o_tke_buoy, zx_tmp_fi3d) 1363 1364 1365 zx_tmp_fi3d=0. 1366 IF (vars_defined) THEN 1367 DO nsrf=1,nbsrf 1368 DO k=1,klev 1369 zx_tmp_fi3d(:,k)=zx_tmp_fi3d(:,k) & 1370 +pctsrf(:,nsrf)*tke_trans(:,k,nsrf) 1371 ENDDO 1372 ENDDO 1373 ENDIF 1374 1375 CALL histwrite_phy(o_tke_trans, zx_tmp_fi3d) 1376 1326 1377 ENDIF 1327 1378 … … 1814 1865 CALL histwrite_phy(o_tau_strat_550, tausum_strat(:,1)) 1815 1866 CALL histwrite_phy(o_tau_strat_1020, tausum_strat(:,2)) 1867 CALL histwrite_phy(o_SAD_sulfate, SAD_sulfate) 1868 CALL histwrite_phy(o_reff_sulfate, reff_sulfate) 1869 CALL histwrite_phy(o_sulfmmr, sulfmmr) 1870 ! All BINs fields 1871 DO itr = 1, nbtr_bin 1872 CALL histwrite_phy(o_nd_mode(itr), nd_mode(:,:,itr)) 1873 CALL histwrite_phy(o_sulfmmr_mode(itr), sulfmmr_mode(:,:,itr)) 1874 ENDDO !--itr 1816 1875 ENDIF 1817 1876 #endif … … 2005 2064 CALL histwrite_phy(o_pfraclr, pfraclr) 2006 2065 CALL histwrite_phy(o_pfracld, pfracld) 2066 CALL histwrite_phy(o_cldfraliq, cldfraliq) 2067 CALL histwrite_phy(o_sigma2_icefracturb, sigma2_icefracturb) 2068 CALL histwrite_phy(o_mean_icefracturb, mean_icefracturb) 2007 2069 IF (ok_poprecip) THEN 2008 2070 CALL histwrite_phy(o_qrainlsc, qraindiag) … … 2306 2368 IF (vars_defined) zx_tmp_fi3d(1:klon,1:klev)=d_qbs_vdf(1:klon,1:klev)/pdtphys 2307 2369 CALL histwrite_phy(o_dqbsvdf, zx_tmp_fi3d) 2308 IF (vars_defined) zx_tmp_fi3d(1:klon,1:klev)=d_qbs_bs (1:klon,1:klev)/pdtphys2370 IF (vars_defined) zx_tmp_fi3d(1:klon,1:klev)=d_qbs_bsss(1:klon,1:klev)/pdtphys 2309 2371 CALL histwrite_phy(o_dqbsbs, zx_tmp_fi3d) 2310 IF (vars_defined) zx_tmp_fi3d(1:klon,1:klev)=d_q_bs (1:klon,1:klev)/pdtphys2372 IF (vars_defined) zx_tmp_fi3d(1:klon,1:klev)=d_q_bsss(1:klon,1:klev)/pdtphys 2311 2373 CALL histwrite_phy(o_dqbs, zx_tmp_fi3d) 2312 IF (vars_defined) zx_tmp_fi3d(1:klon,1:klev)=d_t_bs (1:klon,1:klev)/pdtphys2374 IF (vars_defined) zx_tmp_fi3d(1:klon,1:klev)=d_t_bsss(1:klon,1:klev)/pdtphys 2313 2375 CALL histwrite_phy(o_dtbs, zx_tmp_fi3d) 2314 2376 ENDIF … … 2810 2872 end if 2811 2873 2874 !! runoff land bucket - ajout S. Nguyen 23 07 2024 2875 CALL histwrite_phy(o_runoff_diag, runoff_diag) 2876 2812 2877 #ifdef ISO 2813 do ixt=1,ntiso 2814 ! write(*,*) 'ixt' 2878 !write(*,*) 'tmp phys_output_write: ntiso=',ntiso 2879 2880 DO ixt = 1, ntiso 2881 !write(*,*) 'ixt,o_xtovap(ixt)=',ixt,o_xtovap(ixt) 2815 2882 IF (vars_defined) zx_tmp_fi2d(:) = xtrain_fall(ixt,:) + xtsnow_fall(ixt,:) 2816 2883 CALL histwrite_phy(o_xtprecip(ixt), zx_tmp_fi2d) … … 2824 2891 CALL histwrite_phy(o_xtovap(ixt), xt_seri(ixt,:,:)) 2825 2892 CALL histwrite_phy(o_xtoliq(ixt), xtl_seri(ixt,:,:)) 2893 2894 !! runoff land bucket - ajout S. Nguyen 25 avril 2024 2895 CALL histwrite_phy(o_xtrunoff_diag(ixt), xtrunoff_diag(ixt,:)) 2896 2826 2897 2827 2898 DO nsrf = 1, nbsrf ! ajout Camille 8 mai 2023 … … 2884 2955 ENDDO ! iff 2885 2956 #endif 2957 2958 !SN activate water isotopes present in tracer.def 2959 #ifdef ISO 2960 DO ixt = 1, ntiso 2961 outiso = TRIM(isoName(ixt)) 2962 i = INDEX(outiso, '_', .TRUE.) 2963 outiso = outiso(1:i-1)//outiso(i+1:LEN_TRIM(outiso)) 2964 2965 CALL xios_set_fieldgroup_attr("iso2D_"//TRIM(outiso), enabled=.TRUE.) 2966 CALL xios_set_fieldgroup_attr("iso3D_"//TRIM(outiso), enabled=.TRUE.) 2967 2968 ENDDO 2969 #endif 2886 2970 !On finalise l'initialisation: 2887 2971 IF (using_xios) CALL wxios_closedef() -
LMDZ6/branches/cirrus/libf/phylmd/phys_state_var_mod.F90
r4951 r5202 87 87 !$OMP THREADPRIVATE(prw_ancien, prlw_ancien, prsw_ancien, prbsw_ancien) 88 88 #ifdef ISO 89 REAL, ALLOCATABLE, SAVE :: xt_ancien(:,:,:),xtl_ancien(:,:,:),xts_ancien(:,:,:) 90 !$OMP THREADPRIVATE(xt_ancien,xtl_ancien,xts_ancien) 89 REAL, ALLOCATABLE, SAVE :: xt_ancien(:,:,:),xtl_ancien(:,:,:),xts_ancien(:,:,:), & 90 xtbs_ancien(:,:,:) 91 !$OMP THREADPRIVATE(xt_ancien,xtl_ancien,xts_ancien,xtbs_ancien) 91 92 #endif 92 93 REAL, ALLOCATABLE, SAVE :: u_ancien(:,:), v_ancien(:,:) … … 760 761 ALLOCATE(xtl_ancien(ntraciso,klon,klev)) 761 762 ALLOCATE(xts_ancien(ntraciso,klon,klev)) 763 ALLOCATE(xtbs_ancien(ntraciso,klon,klev)) 762 764 ALLOCATE(xtrain_fall(ntraciso,klon)) 763 765 ALLOCATE(xtsnow_fall(ntraciso,klon)) … … 950 952 #ifdef ISO 951 953 DEALLOCATE(xtsol,fxtevap) 952 DEALLOCATE(xt_ancien,xtl_ancien,xts_ancien, fxtd, wake_deltaxt)954 DEALLOCATE(xt_ancien,xtl_ancien,xts_ancien,xtbs_ancien, fxtd, wake_deltaxt) 953 955 DEALLOCATE(xtrain_fall, xtsnow_fall, xtrain_con, xtsnow_con) 954 956 #ifdef ISOTRAC -
LMDZ6/branches/cirrus/libf/phylmd/physiq_mod.F90
r4951 r5202 1 ! 1 2 2 ! $Id$ 3 3 ! … … 184 184 d_ts, & 185 185 ! 186 d_t_bs ,d_q_bs,d_qbs_bs, &186 d_t_bsss,d_q_bsss,d_qbs_bsss, & 187 187 ! 188 188 ! d_t_oli,d_u_oli,d_v_oli, & … … 333 333 ! 334 334 rneblsvol, & 335 pfraclr, pfracld,&336 distcltop, temp_cltop,&335 pfraclr, pfracld, cldfraliq, sigma2_icefracturb, mean_icefracturb, & 336 distcltop, temp_cltop, & 337 337 !-- LSCP - condensation and ice supersaturation variables 338 338 qsub, qissr, qcld, subfra, issrfra, gamma_cond, ratio_qi_qtot, & … … 909 909 REAL zdtime, zdtime1, zdtime2, zlongi 910 910 ! 911 REAL qcheck912 911 REAL z_avant(klon), z_apres(klon), z_factor(klon) 913 912 LOGICAL zx_ajustq … … 1133 1132 REAL, DIMENSION(klon,klev) :: mass_solu_aero_pi 1134 1133 ! - " - (pre-industrial value) 1134 REAL, DIMENSION(klon,klev,naero_tot) :: m_allaer 1135 1135 1136 1136 ! Parameters … … 1271 1271 1272 1272 !--OB variables for mass fixer (hard coded for now) 1273 LOGICAL, PARAMETER :: mass_fixer=.FALSE.1274 1273 REAL qql1(klon),qql2(klon),corrqql 1275 1274 … … 1401 1400 IF (read_climoz>=1 .AND. create_etat0_limit .AND. grid_type==unstructured) & 1402 1401 CALL regr_horiz_time_climoz(read_climoz,ok_daily_climoz) 1403 1404 #ifdef REPROBUS1405 CALL strataer_init1406 CALL strataer_emiss_init1407 #endif1408 1409 #ifdef CPP_StratAer1410 CALL strataer_init1411 CALL strataer_nuc_init1412 CALL strataer_emiss_init1413 #endif1414 1402 1415 1403 print*, '=================================================' … … 1527 1515 iflag_phytrac = 1 ! by default we do want to call phytrac 1528 1516 CALL getin_p('iflag_phytrac',iflag_phytrac) 1517 1518 ok_water_mass_fixer=.FALSE. ! OB: by default we do not apply the mass fixer 1519 CALL getin_p('ok_water_mass_fixer',ok_water_mass_fixer) 1529 1520 #ifdef CPP_Dust 1530 1521 IF (iflag_phytrac.EQ.0) THEN … … 1551 1542 WRITE(lunout,*) 'fl_cor_ebil=', fl_cor_ebil 1552 1543 WRITE(lunout,*) 'iflag_phytrac=', iflag_phytrac 1544 WRITE(lunout,*) 'ok_water_mass_fixer=',ok_water_mass_fixer 1553 1545 WRITE(lunout,*) 'NVM=', nvm_lmdz 1554 1546 … … 1802 1794 IF (.NOT. create_etat0_limit) CALL init_readaerosolstrato(flag_aerosol_strat) !! initialise aero strato from file for XIOS interpolation (unstructured_grid) 1803 1795 1796 ! A.I : Initialisations pour le 1er passage a Cosp 1804 1797 if (ok_cosp) then 1798 1805 1799 #ifdef CPP_COSP 1806 ! A.I : Initialisations pour le 1er passage a Cosp1807 1800 CALL ini_COSP(ref_liq_cosp0,ref_ice_cosp0,pctsrf_cosp0,zu10m_cosp0,zv10m_cosp0, & 1808 1801 zxtsol_cosp0,zx_rh_cosp0,cldfra_cosp0,rnebcon_cosp0,flwc_cosp0, & … … 1824 1817 #endif 1825 1818 1826 #ifdef CPP_COSP 21827 CALL ini_COSP(ref_liq_cosp0,ref_ice_cosp0,pctsrf_cosp0,zu10m_cosp0,zv10m_cosp0, &1819 #ifdef CPP_COSPV2 1820 CALL ini_COSP(ref_liq_cosp0,ref_ice_cosp0,pctsrf_cosp0,zu10m_cosp0,zv10m_cosp0, & 1828 1821 zxtsol_cosp0,zx_rh_cosp0,cldfra_cosp0,rnebcon_cosp0,flwc_cosp0, & 1829 1822 fiwc_cosp0,prfl_cosp0,psfl_cosp0,pmflxr_cosp0,pmflxs_cosp0, & 1830 1823 mr_ozone_cosp0,cldtau_cosp0,cldemi_cosp0,JrNt_cosp0) 1831 1832 CALL phys_cosp2(itap,phys_tstep,freq_cosp, & 1833 ok_mensuelCOSP,ok_journeCOSP,ok_hfCOSP, & 1834 ecrit_mth,ecrit_day,ecrit_hf, ok_all_xml, missing_val, & 1835 klon,klev,longitude_deg,latitude_deg,presnivs,overlap, & 1836 JrNt,ref_liq,ref_ice, & 1837 pctsrf(:,is_ter)+pctsrf(:,is_lic), & 1838 zu10m,zv10m,pphis, & 1839 zphi,paprs(:,1:klev),pplay,zxtsol,t_seri, & 1840 qx(:,:,ivap),zx_rh,cldfra,rnebcon,flwc,fiwc, & 1841 prfl(:,1:klev),psfl(:,1:klev), & 1842 pmflxr(:,1:klev),pmflxs(:,1:klev), & 1843 mr_ozone,cldtau, cldemi) 1844 #endif 1845 1846 #ifdef CPP_COSPV2 1824 1847 1825 CALL lmdz_cosp_interface(itap,phys_tstep,freq_cosp, & 1848 1826 ok_mensuelCOSP,ok_journeCOSP,ok_hfCOSP, & 1849 1827 ecrit_mth,ecrit_day,ecrit_hf, ok_all_xml, missing_val, & 1850 1828 klon,klev,longitude_deg,latitude_deg,presnivs,overlap, & 1851 JrNt ,ref_liq,ref_ice, &1852 pctsrf (:,is_ter)+pctsrf(:,is_lic), &1853 zu10m ,zv10m,pphis, &1854 p hicosp,paprs(:,1:klev),pplay,zxtsol,t_seri, &1855 qx(:,:,ivap),zx_rh ,cldfra,rnebcon,flwc,fiwc, &1856 prfl (:,1:klev),psfl(:,1:klev), &1857 pmflxr (:,1:klev),pmflxs(:,1:klev), &1858 mr_ozone ,cldtau, cldemi)1829 JrNt_cosp0,ref_liq_cosp0,ref_ice_cosp0, & 1830 pctsrf_cosp0, & 1831 zu10m_cosp0,zv10m_cosp0,pphis, & 1832 pphi,paprs(:,1:klev),pplay,zxtsol_cosp0,t, & 1833 qx(:,:,ivap),zx_rh_cosp0,cldfra_cosp0,rnebcon_cosp0,flwc_cosp0,fiwc_cosp0, & 1834 prfl_cosp0(:,1:klev),psfl_cosp0(:,1:klev), & 1835 pmflxr_cosp0(:,1:klev),pmflxs_cosp0(:,1:klev), & 1836 mr_ozone_cosp0,cldtau_cosp0, cldemi_cosp0) 1859 1837 #endif 1860 ENDIF1838 endif ! ok_cosp 1861 1839 1862 1840 ! … … 1908 1886 ! 1909 1887 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 1888 #ifdef REPROBUS 1889 CALL strataer_init 1890 CALL strataer_emiss_init 1891 #endif 1892 1893 #ifdef CPP_StratAer 1894 CALL strataer_init 1895 CALL strataer_nuc_init 1896 CALL strataer_emiss_init 1897 #endif 1910 1898 1911 1899 #ifdef CPP_Dust … … 1948 1936 ELSE IF (klon_glo==1) THEN 1949 1937 pbl_tke(:,:,is_ave) = 0. 1938 pbl_eps(:,:,is_ave) = 0. 1950 1939 DO nsrf=1,nbsrf 1951 1940 DO k = 1,klev+1 1952 1941 pbl_tke(:,k,is_ave) = pbl_tke(:,k,is_ave) & 1953 1942 +pctsrf(:,nsrf)*pbl_tke(:,k,nsrf) 1943 pbl_eps(:,k,is_ave) = pbl_eps(:,k,is_ave) & 1944 +pctsrf(:,nsrf)*pbl_eps(:,k,nsrf) 1954 1945 ENDDO 1955 1946 ENDDO … … 1957 1948 pbl_tke(:,:,is_ave) = 0. !ym missing init : maybe must be initialized in the same way that for klon_glo==1 ?? 1958 1949 !>jyg 1950 pbl_eps(:,:,is_ave) = 0. 1959 1951 ENDIF 1960 1952 !IM begin … … 2470 2462 ENDDO 2471 2463 ! 2472 !--OB mass fixer2473 IF ( mass_fixer) THEN2464 !--OB water mass fixer 2465 IF (ok_water_mass_fixer) THEN 2474 2466 !--store initial water burden 2475 2467 qql1(:)=0.0 … … 3024 3016 ! Blowing snow sublimation and sedimentation 3025 3017 3026 d_t_bs (:,:)=0.3027 d_q_bs (:,:)=0.3028 d_qbs_bs (:,:)=0.3018 d_t_bsss(:,:)=0. 3019 d_q_bsss(:,:)=0. 3020 d_qbs_bsss(:,:)=0. 3029 3021 bsfl(:,:)=0. 3030 3022 bs_fall(:)=0. … … 3032 3024 3033 3025 CALL call_blowing_snow_sublim_sedim(klon,klev,phys_tstep,t_seri,q_seri,qbs_seri,pplay,paprs, & 3034 d_t_bs ,d_q_bs,d_qbs_bs,bsfl,bs_fall)3026 d_t_bsss,d_q_bsss,d_qbs_bsss,bsfl,bs_fall) 3035 3027 3036 3028 CALL add_phys_tend & 3037 (du0,dv0,d_t_bs ,d_q_bs,dql0,dqi0,d_qbs_bs,paprs,&3038 'bs ',abortphy,flag_inhib_tend,itap,0)3029 (du0,dv0,d_t_bsss,d_q_bsss,dql0,dqi0,d_qbs_bsss,paprs,& 3030 'bsss',abortphy,flag_inhib_tend,itap,0) 3039 3031 3040 3032 ENDIF … … 3079 3071 ENDDO 3080 3072 ENDDO 3081 IF (check) THEN3082 za = qcheck(klon,klev,paprs,q_seri,ql_seri,cell_area)3083 WRITE(lunout,*) "avantcon=", za3084 ENDIF3085 zx_ajustq = .FALSE.3086 IF (iflag_con.EQ.2) zx_ajustq=.TRUE.3087 IF (zx_ajustq) THEN3088 DO i = 1, klon3089 z_avant(i) = 0.03090 ENDDO3091 DO k = 1, klev3092 DO i = 1, klon3093 z_avant(i) = z_avant(i) + (q_seri(i,k)+ql_seri(i,k)) &3094 *(paprs(i,k)-paprs(i,k+1))/RG3095 ENDDO3096 ENDDO3097 ENDIF3098 3073 3099 3074 ! Calcule de vitesse verticale a partir de flux de masse verticale … … 3488 3463 CALL writefield_phy('q_seri',q_seri,nbp_lev) 3489 3464 ENDIF 3490 3491 IF (check) THEN3492 za = qcheck(klon,klev,paprs,q_seri,ql_seri,cell_area)3493 WRITE(lunout,*)"aprescon=", za3494 zx_t = 0.03495 za = 0.03496 DO i = 1, klon3497 za = za + cell_area(i)/REAL(klon)3498 zx_t = zx_t + (rain_con(i)+ &3499 snow_con(i))*cell_area(i)/REAL(klon)3500 ENDDO3501 zx_t = zx_t/za*phys_tstep3502 WRITE(lunout,*)"Precip=", zx_t3503 ENDIF3504 IF (zx_ajustq) THEN3505 DO i = 1, klon3506 z_apres(i) = 0.03507 ENDDO3508 DO k = 1, klev3509 DO i = 1, klon3510 z_apres(i) = z_apres(i) + (q_seri(i,k)+ql_seri(i,k)) &3511 *(paprs(i,k)-paprs(i,k+1))/RG3512 ENDDO3513 ENDDO3514 DO i = 1, klon3515 z_factor(i) = (z_avant(i)-(rain_con(i)+snow_con(i))*phys_tstep) &3516 /z_apres(i)3517 ENDDO3518 DO k = 1, klev3519 DO i = 1, klon3520 IF (z_factor(i).GT.(1.0+1.0E-08) .OR. &3521 z_factor(i).LT.(1.0-1.0E-08)) THEN3522 q_seri(i,k) = q_seri(i,k) * z_factor(i)3523 ENDIF3524 ENDDO3525 ENDDO3526 ENDIF3527 zx_ajustq=.FALSE.3528 3465 3529 3466 ! … … 3921 3858 3922 3859 CALL lscp(klon,klev,phys_tstep,missing_val,paprs,pplay, & 3923 t_seri, q_seri, ptconv,ratqs, &3860 t_seri, q_seri,qs_ancien,ptconv,ratqs, & 3924 3861 d_t_lsc, d_q_lsc, d_ql_lsc, d_qi_lsc, rneb, rneblsvol, & 3925 pfraclr, pfracld,&3862 pfraclr, pfracld, cldfraliq, sigma2_icefracturb, mean_icefracturb, & 3926 3863 radocond, picefra, rain_lsc, snow_lsc, & 3927 3864 frac_impa, frac_nucl, beta_prec_fisrt, & 3928 3865 prfl, psfl, rhcl, & 3929 3866 zqasc, fraca,ztv,zpspsk,ztla,zthl,iflag_cld_th, & 3930 iflag_ice_thermo, distcltop, temp_cltop, cell_area, & 3931 cf_seri, rvc_seri, u_seri, v_seri, pbl_eps(:,:,is_ave), & 3867 iflag_ice_thermo, distcltop, temp_cltop, & 3868 pbl_tke(:,:,is_ave), pbl_eps(:,:,is_ave), & 3869 cell_area, & 3870 cf_seri, rvc_seri, u_seri, v_seri, & 3932 3871 qsub, qissr, qcld, subfra, issrfra, gamma_cond, ratio_qi_qtot, & 3933 3872 dcf_sub, dcf_con, dcf_mix, dqi_adj, dqi_sub, dqi_con, dqi_mix, & … … 4021 3960 ENDIF 4022 3961 4023 ENDIF4024 4025 IF (check) THEN4026 za = qcheck(klon,klev,paprs,q_seri,ql_seri,cell_area)4027 WRITE(lunout,*)"apresilp=", za4028 zx_t = 0.04029 za = 0.04030 DO i = 1, klon4031 za = za + cell_area(i)/REAL(klon)4032 zx_t = zx_t + (rain_lsc(i) &4033 + snow_lsc(i))*cell_area(i)/REAL(klon)4034 ENDDO4035 zx_t = zx_t/za*phys_tstep4036 WRITE(lunout,*)"Precip=", zx_t4037 3962 ENDIF 4038 3963 … … 4405 4330 flag_aerosol, flag_bc_internal_mixture, itap, jD_cur-jD_ref, & 4406 4331 pdtphys, pplay, paprs, t_seri, rhcl, presnivs, & 4407 tr_seri, mass_solu_aero, mass_solu_aero_pi )4332 tr_seri, mass_solu_aero, mass_solu_aero_pi, m_allaer) 4408 4333 #else 4409 4334 abort_message='You should compile with -rad ecrad if running with iflag_rrtm=2' … … 4651 4576 ! Rajoute par OB pour RRTM 4652 4577 tau_aero_lw_rrtm, & 4653 cldtaupirad, &4578 cldtaupirad, m_allaer, & 4654 4579 ! zqsat, flwcrad, fiwcrad, & 4655 4580 zqsat, flwc, fiwc, & … … 4729 4654 ! Rajoute par OB pour RRTM 4730 4655 tau_aero_lw_rrtm, & 4731 cldtaupi, &4656 cldtaupi, m_allaer, & 4732 4657 ! zqsat, flwcrad, fiwcrad, & 4733 4658 zqsat, flwc, fiwc, & … … 4775 4700 tau_aero_sw_rrtm, piz_aero_sw_rrtm, cg_aero_sw_rrtm, & 4776 4701 tau_aero_lw_rrtm, & 4777 cldtaupi, &4702 cldtaupi, m_allaer, & 4778 4703 zqsat, flwc, fiwc, & 4779 4704 ref_liq, ref_ice, ref_liq_pi, ref_ice_pi, & … … 5508 5433 !--currently flag is turned off 5509 5434 !================================================================== 5510 IF ( mass_fixer) THEN5435 IF (ok_water_mass_fixer) THEN 5511 5436 qql2(:)=0.0 5512 5437 DO k = 1, klev -
LMDZ6/branches/cirrus/libf/phylmd/phystokenc_mod.F90
r2343 r5202 46 46 ! Objet: Ecriture des variables pour transport offline 47 47 ! 48 ! Note (A Cozic - July 2024): when coupled with inca, offline fields are no 49 ! longer calculated in this routine but directly in the physics code. 48 50 !====================================================================== 49 51 -
LMDZ6/branches/cirrus/libf/phylmd/radlwsw_m.F90
r4866 r5202 21 21 tau_aero_sw_rrtm, piz_aero_sw_rrtm, cg_aero_sw_rrtm,& ! rajoute par OB RRTM 22 22 tau_aero_lw_rrtm, & ! rajoute par C.Kleinschmitt pour RRTM 23 cldtaupi, &23 cldtaupi, m_allaer, & 24 24 qsat, flwc, fiwc, & 25 25 ref_liq, ref_ice, ref_liq_pi, ref_ice_pi, & … … 80 80 ! Besoin pour ECRAD de pctsrf, zmasq, longitude, altitude 81 81 #ifdef CPP_ECRAD 82 USE phys_local_var_mod, ONLY: rhcl, m_allaer83 82 USE geometry_mod, ONLY: latitude, longitude 84 83 USE phys_state_var_mod, ONLY: pctsrf … … 247 246 REAL, INTENT(in) :: ref_liq_pi(klon,klev) ! cloud droplet radius pre-industrial from newmicro 248 247 REAL, INTENT(in) :: ref_ice_pi(klon,klev) ! ice crystal radius pre-industrial from newmicro 248 REAL, INTENT(in) :: m_allaer(klon,klev,naero_tot) ! mass aero 249 249 250 250 CHARACTER(len=512), INTENT(in) :: namelist_ecrad_file … … 706 706 zsollw0(i)=0. 707 707 zsollwdown(i)=0. 708 ztoplwad0aero(i) = 0. 709 ztoplwadaero(i) = 0. 708 710 ENDDO 709 711 ! Old radiation scheme, used for AR4 runs -
LMDZ6/branches/cirrus/libf/phylmd/surf_land_bucket_mod.F90
r3974 r5202 16 16 snow, qsol, agesno, tsoil, & 17 17 qsurf, z0_new, alb1_new, alb2_new, evap, & 18 fluxsens, fluxlat, tsurf_new, dflux_s, dflux_l) 18 fluxsens, fluxlat, tsurf_new, dflux_s, dflux_l & 19 #ifdef ISO 20 ,xtprecip_rain, xtprecip_snow,xtspechum, & 21 xtsnow, xtsol,xtevap,h1, & 22 runoff_diag,xtrunoff_diag,Rland_ice & 23 #endif 24 ) 19 25 20 26 USE limit_read_mod … … 28 34 USE mod_phys_lmdz_para 29 35 USE indice_sol_mod 36 #ifdef ISO 37 use infotrac_phy, ONLY: ntiso,niso 38 USE isotopes_mod, ONLY: iso_eau, iso_HDO, iso_O18, iso_O17, & 39 ridicule_qsol 40 USE isotopes_routines_mod, ONLY: calcul_iso_surf_ter_vectall 41 #ifdef ISOVERIF 42 USE isotopes_verif_mod, ONLY: errmax,errmaxrel,iso_verif_noNaN, & 43 iso_verif_aberrant_o17,iso_verif_egalite_choix,iso_verif_egalite 44 #endif 45 #endif 30 46 !**************************************************************************************** 31 47 ! Bucket calculations for surface. … … 52 68 REAL, DIMENSION(klon), INTENT(IN) :: rugoro 53 69 REAL, DIMENSION(klon), INTENT(IN) :: swnet, lwnet 70 #ifdef ISO 71 REAL, DIMENSION(ntiso,klon), INTENT(IN) :: xtprecip_rain, xtprecip_snow 72 REAL, DIMENSION(ntiso,klon), INTENT(IN) :: xtspechum 73 #endif 54 74 55 75 ! In/Output variables … … 58 78 REAL, DIMENSION(klon), INTENT(INOUT) :: agesno 59 79 REAL, DIMENSION(klon, nsoilmx), INTENT(INOUT) :: tsoil 80 #ifdef ISO 81 REAL, DIMENSION(niso,klon), INTENT(INOUT) :: xtsnow,xtsol 82 #endif 60 83 61 84 ! Output variables … … 67 90 REAL, DIMENSION(klon), INTENT(OUT) :: tsurf_new 68 91 REAL, DIMENSION(klon), INTENT(OUT) :: dflux_s, dflux_l 92 #ifdef ISO 93 REAL, DIMENSION(ntiso,klon), INTENT(OUT) :: xtevap 94 REAL, DIMENSION(klon), INTENT(OUT) :: h1 95 REAL, DIMENSION(niso,klon), INTENT(OUT) :: xtrunoff_diag 96 REAL, DIMENSION(klon), INTENT(OUT) :: runoff_diag 97 REAL, DIMENSION(niso,klon), INTENT(IN) :: Rland_ice 98 #endif 69 99 70 100 ! Local variables … … 78 108 REAL, DIMENSION(klon) :: dummy_riverflow,dummy_coastalflow 79 109 INTEGER :: i 80 ! 81 !**************************************************************************************** 82 110 #ifdef ISO 111 INTEGER :: ixt 112 REAL, DIMENSION(niso,klon) :: xtsnow_prec,xtsol_prec 113 REAL, DIMENSION(klon) :: snow_prec,qsol_prec 114 REAL, PARAMETER :: t_coup = 273.15 115 REAL, DIMENSION(klon) :: fq_fonte_diag 116 REAL, DIMENSION(klon) :: fqfonte_diag 117 REAL, DIMENSION(klon) :: snow_evap_diag 118 REAL, DIMENSION(klon) :: fqcalving_diag 119 REAL :: max_eau_sol_diag 120 REAL, DIMENSION(klon) :: run_off_lic_diag 121 REAL :: coeff_rel_diag 122 #endif 123 ! 124 !**************************************************************************************** 125 126 #ifdef ISO 127 #ifdef ISOVERIF 128 !write(*,*) 'surf_land_bucket 152' 129 DO i=1,knon 130 IF (iso_eau > 0) THEN 131 CALL iso_verif_egalite_choix(precip_snow(i), & 132 & xtprecip_snow(iso_eau,i),'surf_land_bucket 131', & 133 & errmax,errmaxrel) 134 CALL iso_verif_egalite_choix(qsol(i), & 135 & xtsol(iso_eau,i),'surf_land_bucket 134', & 136 & errmax,errmaxrel) 137 ENDIF 138 ENDDO 139 #endif 140 #ifdef ISOVERIF 141 DO i=1,knon 142 DO ixt=1,niso 143 CALL iso_verif_noNaN(xtsol(ixt,i),'surf_land_mod_bucket 142') 144 ENDDO !do ixt=1,niso 145 ENDDO !do i=1,knon 146 !write(*,*) 'surf_land_bucket 152' 147 #endif 148 #endif 83 149 84 150 ! … … 131 197 tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l) 132 198 199 #ifdef ISO 200 ! verif 201 #ifdef ISOVERIF 202 !write(*,*) 'surf_land_bucket 211' 203 DO i=1,knon 204 IF (iso_eau > 0) THEN 205 CALL iso_verif_egalite_choix(xtsnow(iso_eau,i), & 206 & snow(i),'surf_land_bucket 522', & 207 & errmax,errmaxrel) 208 ENDIF !IF (iso_eau > 0) then 209 ENDDO !DO i=1,knon 210 #endif 211 ! end verif 212 #endif 213 #ifdef ISO 214 DO i=1,knon 215 snow_prec(i)=snow(i) 216 qsol_prec(i)=qsol(i) 217 DO ixt=1,niso 218 xtsnow_prec(ixt,i)=xtsnow(ixt,i) 219 xtsol_prec(ixt,i) =xtsol(ixt,i) 220 ENDDO !DO ixt=1,niso 221 ! initialisation: 222 fqfonte_diag(i) =0.0 223 fq_fonte_diag(i) =0.0 224 snow_evap_diag(i)=0.0 225 ENDDO !DO i=1,knon 226 #ifdef ISOVERIF 227 ! write(*,*) 'surf_land_bucket 235' 228 DO i=1,knon 229 IF (iso_eau > 0) THEN 230 CALL iso_verif_egalite(qsol_prec(i),xtsol_prec(iso_eau,i), & 231 & 'surf_land_bucket 141') 232 ENDIF 233 ENDDO !DO i=1,knon 234 #endif 235 #endif 133 236 ! 134 237 !* Calculate snow height, run_off, age of snow … … 136 239 CALL fonte_neige( knon, is_ter, knindex, dtime, & 137 240 tsurf, precip_rain, precip_snow, & 138 snow, qsol, tsurf_new, evap) 241 snow, qsol, tsurf_new, evap & 242 #ifdef ISO 243 & ,fq_fonte_diag,fqfonte_diag,snow_evap_diag,fqcalving_diag & 244 & ,max_eau_sol_diag,runoff_diag,run_off_lic_diag,coeff_rel_diag & 245 #endif 246 & ) 247 248 #ifdef ISO 249 #ifdef ISOVERIF 250 DO i=1,knon 251 DO ixt=1,niso 252 CALL iso_verif_noNaN(xtsol_prec(ixt,i),'surf_land_burcket 237') 253 ENDDO 254 ENDDO 255 #endif 256 #ifdef ISOVERIF 257 !write(*,*) 'surf_land_bucket 235' 258 DO i=1,knon 259 IF (iso_eau > 0) THEN 260 CALL iso_verif_egalite_choix(qsol_prec(i), & 261 & xtsol_prec(iso_eau,i),'surf_land_bucket 628', & 262 & errmax,errmaxrel) 263 CALL iso_verif_egalite_choix(precip_snow(i), & 264 & xtprecip_snow(iso_eau,i),'surf_land_bucket 227', & 265 & errmax,errmaxrel) 266 ! attention, dans fonte_neige, on modifie snow sans modifier 267 ! xtsnow 268 ! c'est fait plus tard dans gestion_neige 269 ! write(*,*) 'surf_land_bucket 287: i=',i 270 ! write(*,*) 'snow(i)=',snow(i) 271 CALL iso_verif_egalite_choix(xtsnow(iso_eau,i), & 272 & snow_prec(i),'surf_land_bucket 245', & 273 & errmax,errmaxrel) 274 ENDIF 275 IF ((iso_O17 > 0).AND.(iso_O18 > 0)) THEN 276 IF (qsol_prec(i) > ridicule_qsol) THEN 277 CALL iso_verif_aberrant_o17(xtsol_prec(iso_O17,i)/qsol_prec(i) & 278 & ,xtsol_prec(iso_O18,i)/qsol_prec(i) & 279 & ,'surf_land_bucket 642') 280 ENDIF !IF ((qsol_prec(i) > ridicule_qsol) & 281 ENDIF !IF ((iso_O17 > 0).AND.(iso_O18 > 0)) THEN 282 ENDDO !DO i=1,knon 283 !write(*,*) 'surf_land_mod 291' 284 !write(*,*) 'snow_evap_diag(1)=',snow_evap_diag(1) 285 #endif 286 CALL calcul_iso_surf_ter_vectall(klon,knon, & 287 & evap,snow_evap_diag,snow, & 288 & fq_fonte_diag,fqfonte_diag,dtime,precip_rain,xtprecip_rain, & 289 & precip_snow,xtprecip_snow, snow_prec,xtsnow_prec, & 290 & tsurf_new,xtspechum,pref,spechum,t_coup,u1_lay,v1_lay,p1lay, & 291 & qsol,xtsol,qsol_prec,xtsol_prec, & 292 & max_eau_sol_diag, & 293 & xtevap,xtsnow,h1,runoff_diag,xtrunoff_diag,fqcalving_diag, & 294 & knindex,is_ter,run_off_lic_diag,coeff_rel_diag,Rland_ice & 295 & ) 296 !#ifdef ISOVERIF 297 ! write(*,*) 'surf_land_bucket 303' 298 !#endif 299 #endif 300 139 301 ! 140 302 !* Calculate the age of snow -
LMDZ6/branches/cirrus/libf/phylmd/surf_land_mod.F90
r4526 r5202 20 20 qsurf, tsurf_new, dflux_s, dflux_l, & 21 21 flux_u1, flux_v1 , & 22 veget,lai,height) 22 veget,lai,height & 23 #ifdef ISO 24 ,xtprecip_rain, xtprecip_snow,xtspechum, & 25 xtsnow, xtsol,xtevap,h1, & 26 runoff_diag,xtrunoff_diag,Rland_ice & 27 #endif 28 ) 23 29 24 30 USE dimphy … … 59 65 USE calcul_fluxs_mod 60 66 USE indice_sol_mod 67 #ifdef ISO 68 use infotrac_phy, ONLY: ntiso,niso 69 use isotopes_mod, ONLY: nudge_qsol, iso_eau 70 #ifdef ISOVERIF 71 use isotopes_verif_mod 72 #endif 73 #endif 74 61 75 USE print_control_mod, ONLY: lunout 62 76 … … 92 106 ! corresponds to previous sollwdown 93 107 REAL, DIMENSION(klon), INTENT(IN) :: q2m, t2m 94 108 #ifdef ISO 109 REAL, DIMENSION(ntiso,klon), INTENT(IN) :: xtprecip_rain, xtprecip_snow 110 REAL, DIMENSION(ntiso,klon), INTENT(IN) :: xtspechum 111 #endif 95 112 ! In/Output variables 96 113 !**************************************************************************************** … … 98 115 REAL, DIMENSION(klon), INTENT(INOUT) :: agesno 99 116 REAL, DIMENSION(klon, nsoilmx), INTENT(INOUT) :: tsoil 117 #ifdef ISO 118 REAL, DIMENSION(niso,klon), INTENT(INOUT) :: xtsnow, xtsol 119 #endif 100 120 101 121 ! Output variables … … 116 136 REAL, DIMENSION(klon,nvm_lmdz), INTENT(OUT) :: veget,lai 117 137 REAL, DIMENSION(klon,nvm_lmdz), INTENT(OUT) :: height 138 #ifdef ISO 139 REAL, DIMENSION(ntiso,klon), INTENT(OUT) :: xtevap 140 REAL, DIMENSION(klon), INTENT(OUT) :: h1 141 REAL, DIMENSION(niso,klon), INTENT(OUT) :: xtrunoff_diag 142 REAL, DIMENSION(klon), INTENT(OUT) :: runoff_diag 143 REAL, DIMENSION(niso,klon), INTENT(IN) :: Rland_ice 144 #endif 118 145 119 146 ! Local variables … … 132 159 !albedo SB <<< 133 160 134 161 #ifdef ISO 162 real, parameter :: t_coup = 273.15 163 real, dimension(klon) :: fqfonte_diag 164 real, dimension(klon) :: snow_evap_diag 165 real, dimension(klon) :: fqcalving_diag 166 integer :: ixt 167 #endif 135 168 !**************************************************************************************** 136 169 !Total solid precip … … 142 175 ENDIF 143 176 !**************************************************************************************** 177 #ifdef ISO 178 #ifdef ISOVERIF 179 ! write(*,*) 'surf_land_mod 162' 180 do i=1,knon 181 if (iso_eau.gt.0) then 182 call iso_verif_egalite_choix(precip_snow(i), & 183 & xtprecip_snow(iso_eau,i),'surf_land_mod 129', & 184 & errmax,errmaxrel) 185 call iso_verif_egalite_choix(qsol(i), & 186 & xtsol(iso_eau,i),'surf_land_mod 139', & 187 & errmax,errmaxrel) 188 endif 189 enddo 190 #endif 191 #ifdef ISOVERIF 192 ! write(*,*) 'surf_land 169: ok_veget=',ok_veget 193 do i=1,knon 194 do ixt=1,ntiso 195 call iso_verif_noNaN(xtprecip_snow(ixt,i),'surf_land 146') 196 enddo 197 enddo 198 #endif 199 #endif 144 200 145 201 … … 172 228 END DO 173 229 230 #ifdef ISO 231 CALL abort_gcm('surf_land_mod 220','isos pas prevus dans orchidee',1) 232 #endif 174 233 ! temporary for keeping same results using lwdown_m instead of lwdown 175 234 CALL surf_land_orchidee(itime, dtime, date0, knon, & … … 183 242 tsol_rad, tsurf_new, alb1_new, alb2_new, & 184 243 emis_new, z0m, z0h, qsurf, & 185 veget, lai, height) 244 veget, lai, height & 245 !#ifdef ISO 246 ! , xtprecip_rain, xtprecip_snow, xtspechum, xtevap & 247 !#endif 248 ) 249 250 #ifdef ISO 251 #ifdef ISOVERIF 252 write(*,*) 'surf_land 193: apres surf_land_orchidee' 253 do i=1,knon 254 if (iso_eau.gt.0) then 255 call iso_verif_egalite_choix(xtevap(iso_eau,i),evap(i), & 256 & 'surf_land 197',errmax,errmaxrel) 257 endif !if (iso_eau.gt.0) then 258 enddo !do i=1,knon 259 #endif 260 #endif 186 261 ! 187 262 !* Add contribution of relief to surface roughness … … 196 271 ! 197 272 !**************************************************************************************** 273 #ifdef ISO 274 #ifdef ISOVERIF 275 ! write(*,*) 'surf_land 247' 276 call iso_verif_egalite_vect1D( & 277 & xtsnow,snow,'surf_land_mod 207',niso,klon) 278 #endif 279 #endif 280 281 #ifdef ISO 282 if (nudge_qsol.eq.1) then 283 call surf_land_nudge_qsol(knon,rlat,rlon,qsol,xtsol,knindex) 284 endif 285 !write(*,*) 'surf_land 258' 286 #endif 198 287 CALL surf_land_bucket(itime, jour, knon, knindex, debut, dtime,& 199 288 tsurf, p1lay, cdragh, precip_rain, precip_totsnow, temp_air, & … … 202 291 snow, qsol, agesno, tsoil, & 203 292 qsurf, z0m, alb1_new, alb2_new, evap, & 204 fluxsens, fluxlat, tsurf_new, dflux_s, dflux_l) 293 fluxsens, fluxlat, tsurf_new, dflux_s, dflux_l & 294 #ifdef ISO 295 ,xtprecip_rain, xtprecip_snow,xtspechum, & 296 xtsnow, xtsol,xtevap,h1, & 297 & runoff_diag, xtrunoff_diag,Rland_ice & 298 #endif 299 & ) 205 300 z0h(1:knon)=z0m(1:knon) ! En attendant mieux 206 301 … … 224 319 p1lay, temp_air, & 225 320 flux_u1, flux_v1) 321 322 #ifdef ISO 323 #ifdef ISOVERIF 324 ! write(*,*) 'surf_land 237: sortie' 325 DO i=1,knon 326 IF (iso_eau >= 0) THEN 327 call iso_verif_egalite_choix(xtsnow(iso_eau,i),snow(i), & 328 & 'surf_land 241',errmax,errmaxrel) 329 ENDIF !if (iso_eau.gt.0) then 330 ENDDO !do i=1,knon 331 #endif 332 #endif 226 333 227 334 !albedo SB >>> … … 248 355 249 356 END SUBROUTINE surf_land 357 358 359 #ifdef ISO 360 SUBROUTINE surf_land_nudge_qsol(knon,rlat,rlon,qsol,xtsol,knindex) 361 362 USE dimphy 363 USE infotrac_phy, ONLY: niso 364 USE isotopes_mod, ONLY: region_nudge_qsol 365 INTEGER, INTENT(IN) :: knon 366 REAL, DIMENSION(klon), INTENT(IN) :: rlon, rlat 367 REAL, DIMENSION(klon), INTENT(INOUT) :: qsol 368 INTEGER, DIMENSION(klon), INTENT(IN) :: knindex 369 REAL, DIMENSION(niso,klon), INTENT(INOUT) :: xtsol 370 REAL :: lat_min_nudge_qsol,lat_max_nudge_qsol 371 REAL :: lon_min_nudge_qsol,lon_max_nudge_qsol 372 INTEGER :: i,ixt 373 REAL :: qsol_new 374 375 IF (region_nudge_qsol == 1) THEN 376 ! Aamzonie du Sud 377 lat_min_nudge_qsol=-15.0 378 lat_max_nudge_qsol=-5.0 379 lon_min_nudge_qsol=-70.0 380 lon_max_nudge_qsol=-50.0 381 ELSE IF (region_nudge_qsol == 2) THEN 382 ! Aamzonie du Nord 383 lat_min_nudge_qsol=-5.0 384 lat_max_nudge_qsol=5.0 385 lon_min_nudge_qsol=-70.0 386 lon_max_nudge_qsol=-50.0 387 ELSE 388 WRITE(*,*) 'surf_land 298: cas pas prevu' 389 WRITE(*,*) 'region_nudge_qsol=',region_nudge_qsol 390 stop 391 ENDIF 392 393 ! write(*,*) 'surf_land 314: knon=',knon 394 ! write(*,*) 'rlat=',rlat 395 ! write(*,*) 'rlon=',rlon 396 ! write(*,*) 'region_nudge_qsol=',region_nudge_qsol 397 398 DO i=1,knon 399 IF ((rlat(knindex(i)) >= lat_min_nudge_qsol).and. & 400 & (rlat(knindex(i)) <= lat_max_nudge_qsol).and. & 401 & (rlon(knindex(i)) >= lon_min_nudge_qsol).and. & 402 & (rlon(knindex(i)) <= lon_max_nudge_qsol)) THEN 403 ! write(*,*) 'surf_land 324: bon domaine: rlat,rlon,qsol=', & 404 ! & rlat(knindex(i)),rlon(knindex(i)),qsol(knindex(i)) 405 qsol_new=qsol(i) 406 IF (region_nudge_qsol == 1) THEN 407 qsol_new=max(qsol(i),50.0) 408 ELSE IF (region_nudge_qsol == 2) THEN 409 qsol_new=max(qsol(i),120.0) 410 ELSE !if (region_nudge_qsol.eq.1) then 411 WRITE(*,*) 'surf_land 317: cas pas prevu' 412 WRITE(*,*) 'region_nudge_qsol=',region_nudge_qsol 413 STOP 414 ENDIF !if (region_nudge_qsol.eq.1) then 415 IF (qsol(i) > 0.0) THEN 416 DO ixt=1,niso 417 xtsol(ixt,i)=xtsol(ixt,i)*qsol_new/qsol(i) 418 ENDDO 419 ELSE !IF (qsol(i) > 0.0) THEN 420 DO ixt=1,niso 421 xtsol(ixt,i)=0.0 422 ENDDO 423 ENDIF !IF (qsol(i) > 0.0) THEN 424 qsol(i)=qsol_new 425 WRITE(*,*) 'surf_land 346: qsol_new=',qsol(i) 426 ENDIF ! if ((rlat(i).ge.lat_min_nudge_qsol).and. 427 ENDDO !DO i=1,knon 428 429 END SUBROUTINE surf_land_nudge_qsol 430 #endif 431 250 432 ! 251 433 !**************************************************************************************** -
LMDZ6/branches/cirrus/libf/phylmd/surf_landice_mod.F90
r4916 r5202 23 23 snowhgt, qsnow, to_ice, sissnow, & 24 24 alb3, runoff, & 25 flux_u1, flux_v1) 25 flux_u1, flux_v1 & 26 #ifdef ISO 27 & ,xtprecip_rain, xtprecip_snow,xtspechum,Rland_ice & 28 & ,xtsnow,xtsol,xtevap & 29 #endif 30 & ) 26 31 27 32 USE dimphy … … 33 38 USE phys_local_var_mod, ONLY : zxrhoslic, zxustartlic, zxqsaltlic 34 39 USE phys_output_var_mod, ONLY : snow_o,zfra_o 40 #ifdef ISO 41 USE fonte_neige_mod, ONLY : xtrun_off_lic 42 USE infotrac_phy, ONLY : ntiso,niso 43 USE isotopes_routines_mod, ONLY: calcul_iso_surf_lic_vectall 44 #ifdef ISOVERIF 45 USE isotopes_mod, ONLY: iso_eau,ridicule 46 USE isotopes_verif_mod 47 #endif 48 #endif 49 35 50 !FC 36 51 USE ioipsl_getin_p_mod, ONLY : getin_p … … 68 83 REAL, DIMENSION(klon), INTENT(IN) :: rugoro 69 84 REAL, DIMENSION(klon,nbsrf), INTENT(IN) :: pctsrf 85 #ifdef ISO 86 REAL, DIMENSION(ntiso,klon), INTENT(IN) :: xtprecip_rain, xtprecip_snow 87 REAL, DIMENSION(ntiso,klon), INTENT(IN) :: xtspechum 88 #endif 89 70 90 71 91 LOGICAL, INTENT(IN) :: debut !true if first step … … 85 105 REAL, DIMENSION(klon), INTENT(INOUT) :: agesno 86 106 REAL, DIMENSION(klon, nsoilmx), INTENT(INOUT) :: tsoil 107 #ifdef ISO 108 REAL, DIMENSION(niso,klon), INTENT(INOUT) :: xtsnow, xtsol 109 REAL, DIMENSION(niso,klon), INTENT(INOUT) :: Rland_ice 110 #endif 111 87 112 88 113 ! Output variables … … 108 133 REAL, DIMENSION(klon), INTENT(OUT) :: sissnow 109 134 REAL, DIMENSION(klon), INTENT(OUT) :: runoff !Land ice runoff 135 #ifdef ISO 136 REAL, DIMENSION(ntiso,klon), INTENT(OUT) :: xtevap 137 ! real, DIMENSION(niso,klon) :: xtrun_off_lic_0_diag ! est une variable globale de 138 ! fonte_neige 139 #endif 110 140 111 141 … … 120 150 REAL, DIMENSION(klon) :: fqfonte,ffonte 121 151 REAL, DIMENSION(klon) :: run_off_lic_frac 152 #ifdef ISO 153 REAL, PARAMETER :: t_coup = 273.15 154 REAL, DIMENSION(klon) :: fqfonte_diag 155 REAL, DIMENSION(klon) :: fq_fonte_diag 156 REAL, DIMENSION(klon) :: snow_evap_diag 157 REAL, DIMENSION(klon) :: fqcalving_diag 158 REAL max_eau_sol_diag 159 REAL, DIMENSION(klon) :: runoff_diag 160 REAL, DIMENSION(klon) :: run_off_lic_diag 161 REAL :: coeff_rel_diag 162 INTEGER :: ixt 163 REAL, DIMENSION(niso,klon) :: xtsnow_prec,xtsol_prec 164 REAL, DIMENSION(klon) :: snow_prec,qsol_prec 165 ! real, DIMENSION(klon) :: run_off_lic_0_diag 166 #endif 167 168 122 169 REAL, DIMENSION(klon) :: emis_new !Emissivity 123 170 REAL, DIMENSION(klon) :: swdown,lwdown … … 146 193 REAL, DIMENSION(klon) :: fluxbs_1, fluxbs_2, bsweight_fresh 147 194 LOGICAL, DIMENSION(klon) :: ok_remaining_freshsnow 195 REAL :: ta1, ta2, ta3, z01, z02, z03, coefa, coefb, coefc, coefd 196 148 197 149 198 ! End definition … … 161 210 !FC firtscall initializations 162 211 !****************************************************************************************** 212 #ifdef ISO 213 #ifdef ISOVERIF 214 ! write(*,*) 'surf_land_ice 1499' 215 DO i=1,knon 216 IF (iso_eau > 0) THEN 217 CALL iso_verif_egalite_choix(xtsnow(iso_eau,i),snow(i), & 218 & 'surf_land_ice 126',errmax,errmaxrel) 219 ENDIF !IF (iso_eau > 0) THEN 220 ENDDO !DO i=1,knon 221 #endif 222 #endif 223 163 224 IF (firstcall) THEN 164 225 alb_vis_sno_lic=0.77 … … 200 261 !**************************************************************************************** 201 262 #ifdef CPP_INLANDSIS 263 264 #ifdef ISO 265 CALL abort_gcm('surf_landice 235','isotopes pas dans INLANDSIS',1) 266 #endif 202 267 203 268 debut_is=debut … … 321 386 tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l) 322 387 388 #ifdef ISO 389 #ifdef ISOVERIF 390 !write(*,*) 'surf_land_ice 1499' 391 DO i=1,knon 392 IF (iso_eau > 0) THEN 393 IF (snow(i) > ridicule) THEN 394 CALL iso_verif_egalite_choix(xtsnow(iso_eau,i),snow(i), & 395 & 'surf_land_ice 1151',errmax,errmaxrel) 396 ENDIF !IF ((snow(i) > ridicule)) THEN 397 ENDIF !IF (iso_eau > 0) THEN 398 ENDDO !DO i=1,knon 399 #endif 400 401 DO i=1,knon 402 snow_prec(i)=snow(i) 403 DO ixt=1,niso 404 xtsnow_prec(ixt,i)=xtsnow(ixt,i) 405 ENDDO !DO ixt=1,niso 406 ! initialisation: 407 fq_fonte_diag(i)=0.0 408 fqfonte_diag(i)=0.0 409 snow_evap_diag(i)=0.0 410 ENDDO !DO i=1,knon 411 #endif 412 323 413 CALL calcul_flux_wind(knon, dtime, & 324 414 u0, v0, u1, v1, gustiness, cdragm, & … … 350 440 ! 351 441 !**************************************************************************************** 352 z0m = z0m_landice 353 z0h = z0h_landice 354 !z0m = SQRT(z0m**2+rugoro**2) 355 442 443 if (z0m_landice .GT. 0.) then 444 z0m(1:knon) = z0m_landice 445 z0h(1:knon) = z0h_landice 446 else 447 ! parameterization of z0=f(T) following measurements in Adelie Land by Amory et al 2018 448 coefa = 0.1658 !0.1862 !Ant 449 coefb = -50.3869 !-55.7718 !Ant 450 ta1 = 253.15 !255. Ant 451 ta2 = 273.15 452 ta3 = 273.15+3 453 z01 = exp(coefa*ta1 + coefb) !~0.2 ! ~0.25 mm 454 z02 = exp(coefa*ta2 + coefb) !~6 !~7 mm 455 z03 = z01 456 coefc = log(z03/z02)/(ta3-ta2) 457 coefd = log(z03)-coefc*ta3 458 do j=1,knon 459 if (temp_air(j) .lt. ta1) then 460 z0m(j) = z01 461 else if (temp_air(j).ge.ta1 .and. temp_air(j).lt.ta2) then 462 z0m(j) = exp(coefa*temp_air(j) + coefb) 463 else if (temp_air(j).ge.ta2 .and. temp_air(j).lt.ta3) then 464 ! if st > 0, melting induce smooth surface 465 z0m(j) = exp(coefc*temp_air(j) + coefd) 466 else 467 z0m(j) = z03 468 endif 469 z0h(j)=z0m(j) 470 enddo 471 472 endif 473 356 474 357 475 !**************************************************************************************** … … 366 484 if (ok_bs) then 367 485 fluxbs(:)=0. 368 do j=1,k lon486 do j=1,knon 369 487 ws1(j)=(u1(j)**2+v1(j)**2)**0.5 370 488 ustar(j)=(cdragm(j)*(u1(j)**2+v1(j)**2))**0.5 … … 493 611 494 612 CALL fonte_neige(knon, is_lic, knindex, dtime, & 495 tsurf, precip_rain, precip_totsnow, & 496 snow, qsol, tsurf_new, evap_totsnow) 613 tsurf, precip_rain, precip_totsnow, & 614 snow, qsol, tsurf_new, evap_totsnow & 615 #ifdef ISO 616 & ,fq_fonte_diag,fqfonte_diag,snow_evap_diag,fqcalving_diag & 617 & ,max_eau_sol_diag,runoff_diag,run_off_lic_diag,coeff_rel_diag & 618 #endif 619 & ) 620 621 622 #ifdef ISO 623 #ifdef ISOVERIF 624 DO i=1,knon 625 IF (iso_eau > 0) THEN 626 CALL iso_verif_egalite_choix(Rland_ice(iso_eau,i),1.0, & 627 & 'surf_landice_mod 217',errmax,errmaxrel) 628 ENDIF !IF (iso_eau > 0) THEN 629 ENDDO !DO i=1,knon 630 #endif 631 632 CALL calcul_iso_surf_lic_vectall(klon,knon, & 633 & evap,snow_evap_diag,Tsurf_new,snow, & 634 & fq_fonte_diag,fqfonte_diag,dtime,t_coup, & 635 & precip_snow,xtprecip_snow,precip_rain,xtprecip_rain, snow_prec,xtsnow_prec, & 636 & xtspechum,spechum,ps,Rland_ice, & 637 & xtevap,xtsnow,fqcalving_diag, & 638 & knindex,is_lic,run_off_lic_diag,coeff_rel_diag & 639 & ) 640 641 ! call fonte_neige_export_xtrun_off_lic_0(knon,xtrun_off_lic_0_diag) 642 643 #endif 497 644 498 499 645 WHERE (snow(1 : knon) .LT. 0.0001) agesno(1 : knon) = 0. 500 646 zfra(1:knon) = MAX(0.0,MIN(1.0,snow(1:knon)/(snow(1:knon)+10.0))) -
LMDZ6/branches/cirrus/libf/phylmd/surf_ocean_mod.F90
r4526 r5202 21 21 tsurf_new, dflux_s, dflux_l, lmt_bils, & 22 22 flux_u1, flux_v1, delta_sst, delta_sal, ds_ns, dt_ns, dter, dser, & 23 dt_ds, tkt, tks, taur, sss) 23 dt_ds, tkt, tks, taur, sss & 24 #ifdef ISO 25 & ,xtprecip_rain, xtprecip_snow,xtspechum,Roce, & 26 & xtsnow,xtevap,h1 & 27 #endif 28 & ) 24 29 25 30 use albedo, only: alboc, alboc_cd … … 31 36 USE ocean_cpl_mod, ONLY : ocean_cpl_noice 32 37 USE indice_sol_mod, ONLY : nbsrf, is_oce 38 #ifdef ISO 39 USE infotrac_phy, ONLY : ntraciso=>ntiso,niso 40 #ifdef ISOVERIF 41 USE isotopes_mod, ONLY: iso_eau,ridicule 42 USE isotopes_verif_mod 43 #endif 44 #endif 33 45 USE limit_read_mod 34 use config_ocean_skin_m, only: activate_ocean_skin46 USE config_ocean_skin_m, ONLY: activate_ocean_skin 35 47 ! 36 48 ! This subroutine will make a call to ocean_XXX_noice according to the ocean mode (force, … … 68 80 REAL, DIMENSION(klon), INTENT(IN) :: rugoro 69 81 REAL, DIMENSION(klon,nbsrf), INTENT(IN) :: pctsrf 82 #ifdef ISO 83 REAL, DIMENSION(ntraciso,klon), INTENT(IN) :: xtprecip_rain, xtprecip_snow 84 REAL, DIMENSION(ntraciso,klon), INTENT(IN) :: xtspechum 85 #endif 70 86 71 87 ! In/Output variables … … 75 91 REAL, DIMENSION(klon), INTENT(INOUT) :: agesno 76 92 REAL, DIMENSION(klon), INTENT(inOUT) :: z0h 93 #ifdef ISO 94 REAL, DIMENSION(niso,klon), INTENT(IN) :: xtsnow 95 REAL, DIMENSION(niso,klon), INTENT(INOUT):: Roce 96 #endif 77 97 78 98 REAL, intent(inout):: delta_sst(:) ! (knon) … … 136 156 ! size klon because of the coupling machinery.) 137 157 158 #ifdef ISO 159 REAL, DIMENSION(ntraciso,klon), INTENT(out) :: xtevap ! isotopes in surface evaporation flux 160 REAL, DIMENSION(klon), INTENT(out) :: h1 ! just a diagnostic, not useful for the simulation 161 #endif 162 138 163 ! Local variables 139 164 !************************************************************************* … … 146 171 REAL, DIMENSION(klon) :: precip_totsnow 147 172 CHARACTER(len=20),PARAMETER :: modname="surf_ocean" 148 realrhoa(knon) ! density of moist air (kg / m3)173 REAL rhoa(knon) ! density of moist air (kg / m3) 149 174 REAL sens_prec_liq(knon) 150 175 151 176 REAL t_int(knon) ! ocean-air interface temperature, in K 152 reals_int(knon) ! ocean-air interface salinity, in ppt177 REAL s_int(knon) ! ocean-air interface salinity, in ppt 153 178 154 179 !************************************************************************** 155 180 181 #ifdef ISO 182 #ifdef ISOVERIF 183 DO i = 1, knon 184 IF (iso_eau > 0) THEN 185 CALL iso_verif_egalite_choix(xtspechum(iso_eau,i), & 186 & spechum(i),'surf_ocean_mod 117', & 187 & errmax,errmaxrel) 188 CALL iso_verif_egalite_choix(xtsnow(iso_eau,i), & 189 & snow(i),'surf_ocean_mod 127', & 190 & errmax,errmaxrel) 191 ENDIF !IF (iso_eau > 0) then 192 ENDDO !DO i=1,klon 193 #endif 194 #endif 156 195 157 196 !****************************************************************************** … … 230 269 radsol, snow, agesno, & 231 270 qsurf, evap, fluxsens, fluxlat, flux_u1, flux_v1, & 232 tsurf_new, dflux_s, dflux_l, sens_prec_liq, rhoa) 271 tsurf_new, dflux_s, dflux_l, sens_prec_liq, rhoa & 272 #ifdef ISO 273 ,xtprecip_rain, xtprecip_snow, xtspechum,Roce,rlat, & 274 xtsnow,xtevap,h1 & 275 #endif 276 ) 233 277 END SELECT 234 278 -
LMDZ6/branches/cirrus/libf/phylmd/surf_seaice_mod.F90
r3815 r5202 21 21 z0m, z0h, SFRWL, alb_dir_new, alb_dif_new, evap, fluxsens, fluxlat, & 22 22 tsurf_new, dflux_s, dflux_l, & 23 flux_u1, flux_v1) 23 flux_u1, flux_v1 & 24 #ifdef ISO 25 & ,xtprecip_rain, xtprecip_snow,xtspechum,Roce, & 26 & xtsnow,xtsol,xtevap,Rland_ice & 27 #endif 28 & ) 24 29 25 30 USE dimphy … … 29 34 USE ocean_slab_mod, ONLY : ocean_slab_ice 30 35 USE indice_sol_mod 36 #ifdef ISO 37 USE infotrac_phy, ONLY : ntiso,niso 38 #endif 31 39 32 40 ! … … 62 70 REAL, DIMENSION(klon), INTENT(IN) :: u1, v1, gustiness 63 71 REAL, DIMENSION(klon,nbsrf), INTENT(IN) :: pctsrf 72 #ifdef ISO 73 REAL, DIMENSION(ntiso,klon), INTENT(IN) :: xtprecip_rain, xtprecip_snow 74 REAL, DIMENSION(klon), INTENT(IN) :: xtspechum 75 REAL, DIMENSION(niso,klon), INTENT(IN) :: Roce 76 REAL, DIMENSION(niso,klon), INTENT(IN) :: Rland_ice 77 #endif 64 78 65 79 ! In/Output arguments … … 68 82 REAL, DIMENSION(klon), INTENT(INOUT) :: agesno 69 83 REAL, DIMENSION(klon, nsoilmx), INTENT(INOUT) :: tsoil 84 #ifdef ISO 85 REAL, DIMENSION(niso,klon), INTENT(INOUT) :: xtsnow 86 REAL, DIMENSION(niso,klon), INTENT(IN) :: xtsol 87 #endif 70 88 71 89 ! Output arguments … … 82 100 REAL, DIMENSION(klon), INTENT(OUT) :: dflux_s, dflux_l 83 101 REAL, DIMENSION(klon), INTENT(OUT) :: flux_u1, flux_v1 102 #ifdef ISO 103 REAL, DIMENSION(ntiso,klon), INTENT(OUT) :: xtevap 104 #endif 84 105 85 106 ! Local arguments 86 107 !**************************************************************************************** 87 108 REAL, DIMENSION(klon) :: radsol 109 #ifdef ISO 110 #ifdef ISOVERIF 111 INTEGER :: j 112 #endif 113 #endif 88 114 89 115 !albedo SB >>> … … 145 171 radsol, snow, qsol, agesno, tsoil, & 146 172 qsurf, alb1_new, alb2_new, evap, fluxsens, fluxlat, flux_u1, flux_v1, & 147 tsurf_new, dflux_s, dflux_l, rhoa) 173 tsurf_new, dflux_s, dflux_l, rhoa & 174 #ifdef ISO 175 ,xtprecip_rain, xtprecip_snow, xtspechum,Roce, & 176 xtsnow, xtsol,xtevap,Rland_ice & 177 #endif 178 ) 148 179 149 180 END IF -
LMDZ6/branches/cirrus/libf/phylmdiso/add_phys_tend_mod.F90
r4523 r5202 957 957 bilh_bnd = (-(rcw-rcpd)*t_seri(1,1) + rlvtt) * rain_lsc(1) & 958 958 & + (-(rcs-rcpd)*t_seri(1,1) + rlstt) * snow_lsc(1) 959 CASE("bs ") param959 CASE("bsss") param 960 960 bilq_bnd = - bs_fall(1) 961 961 bilh_bnd = (-(rcs-rcpd)*t_seri(1,1) + rlstt) * bs_fall(1) -
LMDZ6/branches/cirrus/libf/phylmdiso/add_wake_tend.F90
r4143 r5202 1 SUBROUTINE add_wake_tend(zddeltat, zddeltaq, zds, zd densaw, zddensw, zoccur, text, abortphy &1 SUBROUTINE add_wake_tend(zddeltat, zddeltaq, zds, zdas, zddensw, zddensaw, zoccur, text, abortphy & 2 2 #ifdef ISO 3 3 , zddeltaxt & … … 13 13 14 14 USE dimphy, ONLY: klon, klev 15 USE phys_state_var_mod, ONLY: wake_deltat, wake_deltaq, wake_s, &16 awake_dens,wake_dens15 USE phys_state_var_mod, ONLY: wake_deltat, wake_deltaq, wake_s, awake_s, & 16 wake_dens, awake_dens 17 17 18 18 USE print_control_mod, ONLY: prt_level … … 26 26 !------------ 27 27 REAL, DIMENSION(klon, klev), INTENT (IN) :: zddeltat, zddeltaq 28 REAL, DIMENSION(klon), INTENT (IN) :: zds, zd densaw, zddensw28 REAL, DIMENSION(klon), INTENT (IN) :: zds, zdas, zddensw, zddensaw 29 29 INTEGER, DIMENSION(klon), INTENT (IN) :: zoccur 30 30 CHARACTER*(*), INTENT (IN) :: text … … 79 79 IF (zoccur(i) .GE. 1) THEN 80 80 wake_s(i) = wake_s(i) + zds(i) 81 awake_s(i) = awake_s(i) + zdas(i) 82 wake_dens(i) = wake_dens(i) + zddensw(i) 81 83 awake_dens(i) = awake_dens(i) + zddensaw(i) 82 wake_dens(i) = wake_dens(i) + zddensw(i)83 84 ELSE 84 85 wake_s(i) = 0. 86 awake_s(i) = 0. 87 wake_dens(i) = 0. 85 88 awake_dens(i) = 0. 86 wake_dens(i) = 0.87 89 ENDIF ! (zoccur(i) .GE. 1) 88 90 END DO -
LMDZ6/branches/cirrus/libf/phylmdiso/isotopes_mod.F90
r4491 r5202 20 20 21 21 !--- Variables not depending on isotopes 22 REAL, SAVE :: pxtmelt, pxtice, pxtmin, pxtmax 23 !$OMP THREADPRIVATE(pxtmelt, pxtice, pxtmin, pxtmax) 24 REAL, SAVE :: tdifexp, tv0cin, thumxt1 25 !$OMP THREADPRIVATE(tdifexp, tv0cin, thumxt1) 22 REAL, SAVE :: thumxt1 23 !$OMP THREADPRIVATE(thumxt1) 26 24 INTEGER, SAVE :: ntot 27 25 !$OMP THREADPRIVATE(ntot) … … 30 28 REAL, SAVE :: P_veg 31 29 !$OMP THREADPRIVATE(P_veg) 32 REAL, SAVE :: musi, lambda_sursat 33 !$OMP THREADPRIVATE(musi, lambda_sursat) 34 REAL, SAVE :: Kd 35 !$OMP THREADPRIVATE(Kd) 36 REAL, SAVE :: rh_cste_surf_cond, T_cste_surf_cond 37 !$OMP THREADPRIVATE(rh_cste_surf_cond, T_cste_surf_cond) 30 REAL, SAVE :: lambda_sursat 31 !$OMP THREADPRIVATE(lambda_sursat) 38 32 LOGICAL, SAVE :: bidouille_anti_divergence ! T: regularly, xteau <- q to avoid slow drifts 39 33 !$OMP THREADPRIVATE(bidouille_anti_divergence) … … 54 48 REAL, SAVE :: sstlatcrit, dsstlatcrit 55 49 !$OMP THREADPRIVATE(sstlatcrit, dsstlatcrit) 56 REAL, SAVE :: deltaO18_oce57 !$OMP THREADPRIVATE(deltaO18_oce)58 50 INTEGER, SAVE :: albedo_prescrit ! 0: default ; 1: constant albedo 59 51 !$OMP THREADPRIVATE(albedo_prescrit) … … 88 80 REAL, SAVE :: fac_modif_evaoce 89 81 !$OMP THREADPRIVATE(fac_modif_evaoce) 82 REAL, SAVE :: deltaO18_oce 83 !$OMP THREADPRIVATE(deltaO18_oce) 90 84 INTEGER, SAVE :: ok_bidouille_wake 91 85 !$OMP THREADPRIVATE(ok_bidouille_wake) … … 106 100 alpha_liq_sol, Rdefault, Rmethox 107 101 !$OMP THREADPRIVATE(alpha_liq_sol, Rdefault, Rmethox) 108 REAL, SAVE :: fac_coeff_eq17_liq, fac_coeff_eq17_ice 109 !$OMP THREADPRIVATE(fac_coeff_eq17_liq, fac_coeff_eq17_ice) 102 ! REAL, SAVE :: fac_coeff_eq17_liq, fac_coeff_eq17_ice 103 !!$OMP THREADPRIVATE(fac_coeff_eq17_liq, fac_coeff_eq17_ice) 104 105 !--- H2[18]O reference 106 REAL, PARAMETER :: fac_enrichoce18=0.0005 107 REAL, PARAMETER :: alpha_liq_sol_O18=1.00291 108 REAL, PARAMETER :: talph1_O18=1137. 109 REAL, PARAMETER :: talph2_O18=-0.4156 110 REAL, PARAMETER :: talph3_O18=-2.0667E-3 111 REAL, PARAMETER :: talps1_O18=11.839 112 REAL, PARAMETER :: talps2_O18=-0.028244 113 REAL, PARAMETER :: tdifrel_O18=1./0.9723 114 REAL, PARAMETER :: tkcin0_O18=0.006 115 REAL, PARAMETER :: tkcin1_O18=0.000285 116 REAL, PARAMETER :: tkcin2_O18=0.00082 117 REAL, PARAMETER :: fac_coeff_eq17_liq=0.529 118 REAL, PARAMETER :: fac_coeff_eq17_ice=0.529 119 120 !---- Parameters that do not depend on the nature of water isotopes: 121 REAL, PARAMETER :: pxtmelt = 273.15 ! temperature at which ice formation starts 122 REAL, PARAMETER :: pxtice = 273.15-10.0 ! -- temperature at which all condensate is ice: 123 REAL, PARAMETER :: pxtmin = 273.15 - 120.0 ! On ne calcule qu'au dessus de -120°C 124 REAL, PARAMETER :: pxtmax = 273.15 + 60.0 ! On ne calcule qu'au dessus de +60°C 125 REAL, PARAMETER :: tdifexp = 0.58 ! -- a constant for alpha_eff for equilibrium below cloud base: 126 REAL, PARAMETER :: tv0cin = 7.0 ! wind threshold (m/s) for smooth/rough regime (Merlivat and Jouzel 1979) 127 REAL, PARAMETER :: musi=1.0 ! facteurs lambda et mu dans Si=musi-lambda*T 128 REAL, PARAMETER :: Kd=2.5e-9 ! m2/s ! diffusion dans le sol 129 REAL, PARAMETER :: rh_cste_surf_cond = 0.6 ! cas où cste_surf_cond: on met rhs ou/et Ts cste pour voir 130 REAL, PARAMETER :: T_cste_surf_cond = 288.0 131 110 132 111 133 !--- Negligible lower thresholds: no need to check for absurd values under these lower limits … … 140 162 INTEGER :: ixt 141 163 142 !--- H2[18]O reference 143 REAL :: fac_enrichoce18, alpha_liq_sol_O18, & 144 talph1_O18, talph2_O18, talph3_O18, talps1_O18, talps2_O18, & 145 tkcin0_O18, tkcin1_O18, tkcin2_O18, tdifrel_O18 146 164 147 165 !--- For H2[17]O 148 166 REAL :: fac_kcin, pente_MWL … … 152 170 LOGICAL, PARAMETER :: ok_nocinsat = .FALSE. ! if T: no sursaturation effect for ice 153 171 LOGICAL, PARAMETER :: Rdefault_smow = .FALSE. ! if T: Rdefault=smow; if F: nul 172 LOGICAL, PARAMETER :: tnat1 = .TRUE. ! If T: all tnats are 1. 154 173 155 174 !--- For [3]H … … 157 176 158 177 CHARACTER(LEN=maxlen) :: modname, sxt 159 REAL, ALLOCATABLE :: tmp(:)160 178 161 179 modname = 'iso_init' … … 214 232 CALL get_in('lat_max_albedo', lat_max_albedo, 100.) 215 233 END IF 216 deltaO18_oce=0.0217 234 CALL get_in('deltaP_BL', deltaP_BL, 10.0) 218 235 CALL get_in('ruissellement_pluie', ruissellement_pluie, 0) … … 249 266 CALL get_in('ok_prod_nucl_tritium', ok_prod_nucl_tritium, .FALSE., .FALSE.) 250 267 251 !-------------------------------------------------------------- 252 ! Parameters that do not depend on the nature of water isotopes: 253 !-------------------------------------------------------------- 254 ! -- temperature at which ice condensate starts to form (valeur ECHAM?): 255 pxtmelt = 273.15 256 257 ! -- temperature at which all condensate is ice: 258 pxtice = 273.15-10.0 259 260 !- -- test PHASE 261 ! pxtmelt = 273.15 - 10.0 262 ! pxtice = 273.15 - 30.0 263 264 ! -- minimum temperature to calculate fractionation coeff 265 pxtmin = 273.15 - 120.0 ! On ne calcule qu'au dessus de -120°C 266 pxtmax = 273.15 + 60.0 ! On ne calcule qu'au dessus de +60°C 267 ! Remarque: les coeffs ont ete mesures seulement jusq'à -40! 268 269 ! -- a constant for alpha_eff for equilibrium below cloud base: 270 tdifexp = 0.58 271 tv0cin = 7.0 272 273 ! facteurs lambda et mu dans Si=musi-lambda*T 274 musi=1.0 275 if (ok_nocinsat) lambda_sursat = 0.0 ! no sursaturation effect 276 277 ! diffusion dans le sol 278 Kd=2.5e-9 ! m2/s 279 280 ! cas où cste_surf_cond: on met rhs ou/et Ts cste pour voir 281 rh_cste_surf_cond = 0.6 282 T_cste_surf_cond = 288.0 268 ! Ocean composition 269 CALL get_in('deltaO18_oce', deltaO18_oce, 0.0) 283 270 284 271 CALL msg('iso_O18, iso_HDO, iso_eau = '//TRIM(strStack(int2str([iso_O18, iso_HDO, iso_eau]))), modname) 285 272 286 273 !-------------------------------------------------------------- 287 ! Parameters that depend on the nature of water isotopes:274 ! Isotope fractionation factors and a few isotopic constants 288 275 !-------------------------------------------------------------- 289 IF(getKey('tnat', tnat, isoName)) CALL abort_physic(modname, 'can''t get tnat', 1) 290 IF(getKey('toce', toce, isoName)) CALL abort_physic(modname, 'can''t get toce', 1) 291 IF(getKey('tcorr', tcorr, isoName)) CALL abort_physic(modname, 'can''t get tcorr', 1) 292 IF(getKey('talph1', talph1, isoName)) CALL abort_physic(modname, 'can''t get talph1', 1) 293 IF(getKey('talph2', talph2, isoName)) CALL abort_physic(modname, 'can''t get talph2', 1) 294 IF(getKey('talph3', talph3, isoName)) CALL abort_physic(modname, 'can''t get talph3', 1) 295 IF(getKey('talps1', talps1, isoName)) CALL abort_physic(modname, 'can''t get talps1', 1) 296 IF(getKey('talps2', talps2, isoName)) CALL abort_physic(modname, 'can''t get talps2', 1) 297 IF(getKey('tkcin0', tkcin0, isoName)) CALL abort_physic(modname, 'can''t get tkcin0', 1) 298 IF(getKey('tkcin1', tkcin1, isoName)) CALL abort_physic(modname, 'can''t get tkcin1', 1) 299 IF(getKey('tkcin2', tkcin2, isoName)) CALL abort_physic(modname, 'can''t get tkcin2', 1) 300 IF(getKey('tdifrel', tdifrel, isoName)) CALL abort_physic(modname, 'can''t get tdifrel', 1) 301 IF(getKey('alpha_liq_sol', alpha_liq_sol, isoName)) CALL abort_physic(modname, 'can''t get alpha_liq_sol', 1) 302 IF(getKey('Rdefault',Rdefault,isoName)) CALL abort_physic(modname, 'can''t get Rdefault',1) 303 IF(getKey('Rmethox', Rmethox, isoName)) CALL abort_physic(modname, 'can''t get Rmethox', 1) 276 ALLOCATE(tkcin0(niso)) 277 ALLOCATE(tkcin1(niso)) 278 ALLOCATE(tkcin2(niso)) 279 ALLOCATE(tnat(niso)) 280 ALLOCATE(tdifrel(niso)) 281 ALLOCATE(toce(niso)) 282 ALLOCATE(tcorr(niso)) 283 ALLOCATE(talph1(niso)) 284 ALLOCATE(talph2(niso)) 285 ALLOCATE(talph3(niso)) 286 ALLOCATE(talps1(niso)) 287 ALLOCATE(talps2(niso)) 288 ALLOCATE(alpha_liq_sol(niso)) 289 ALLOCATE(Rdefault(niso)) 290 ALLOCATE(Rmethox(niso)) 291 292 do ixt=1,niso 293 if (ixt.eq.iso_HTO) then ! Tritium 294 tkcin0(ixt) = 0.01056 295 tkcin1(ixt) = 0.0005016 296 tkcin2(ixt) = 0.0014432 297 if (tnat1) then 298 tnat(ixt)=1 299 else 300 tnat(ixt)=0. 301 endif 302 toce(ixt)=4.0E-19 ! rapport T/H = 0.2 TU Dreisigacker and Roether 1978 303 tcorr(ixt)=1. 304 tdifrel(ixt)=1./0.968 305 talph1(ixt)=46480. 306 talph2(ixt)=-103.87 307 talph3(ixt)=0. 308 talps1(ixt)=46480. 309 talps2(ixt)=-103.87 310 alpha_liq_sol(ixt)=1. 311 Rmethox(ixt)=0.0 312 endif 313 if (ixt.eq.iso_O17) then ! O17 314 pente_MWL=0.528 315 tdifrel(ixt)=1./0.98555 ! valeur utilisée en 1D et dans modèle de LdG ! tdifrel(ixt)=1./0.985452 ! donné par Amaelle 316 fac_kcin= (tdifrel(ixt)-1.0)/(tdifrel_O18-1.0) ! fac_kcin=0.5145 ! donné par Amaelle 317 tkcin0(ixt) = tkcin0_O18*fac_kcin 318 tkcin1(ixt) = tkcin1_O18*fac_kcin 319 tkcin2(ixt) = tkcin2_O18*fac_kcin 320 if (tnat1) then 321 tnat(ixt)=1 322 else 323 tnat(ixt)=0.004/100. ! O17 représente 0.004% de l'oxygène 324 endif 325 toce(ixt)=tnat(ixt)*(1.0+deltaO18_oce/1000.0)**pente_MWL 326 tcorr(ixt)=1.0+fac_enrichoce18*pente_MWL ! donné par Amaelle 327 talph1(ixt)=talph1_O18 328 talph2(ixt)=talph2_O18 329 talph3(ixt)=talph3_O18 330 talps1(ixt)=talps1_O18 331 talps2(ixt)=talps2_O18 332 alpha_liq_sol(ixt)=(alpha_liq_sol_O18)**fac_coeff_eq17_liq 333 Rdefault(ixt)=tnat(ixt)*(-3.15/1000.0+1.0) 334 Rmethox(ixt)=(230./1000.+1.)*tnat(ixt) !Zahn et al 2006 335 endif 336 if (ixt.eq.iso_O18) then ! Oxygene18 337 tkcin0(ixt) = tkcin0_O18 338 tkcin1(ixt) = tkcin1_O18 339 tkcin2(ixt) = tkcin2_O18 340 if (tnat1) then 341 tnat(ixt)=1 342 else 343 tnat(ixt)=2005.2E-6 344 endif 345 toce(ixt)=tnat(ixt)*(1.0+deltaO18_oce/1000.0) 346 tcorr(ixt)=1.0+fac_enrichoce18 347 tdifrel(ixt)=tdifrel_O18 348 talph1(ixt)=talph1_O18 349 talph2(ixt)=talph2_O18 350 talph3(ixt)=talph3_O18 351 talps1(ixt)=talps1_O18 352 talps2(ixt)=talps2_O18 353 alpha_liq_sol(ixt)=alpha_liq_sol_O18 354 Rdefault(ixt)=tnat(ixt)*(-6.0/1000.0+1.0) 355 Rmethox(ixt)=(130./1000.+1.)*tnat(ixt) !Zahn et al 2006 356 endif 357 if (ixt.eq.iso_HDO) then ! Deuterium 358 pente_MWL=8.0 359 tdifrel(ixt)=1./0.9755 ! fac_kcin=0.88 360 fac_kcin= (tdifrel(ixt)-1)/(tdifrel_O18-1) 361 tkcin0(ixt) = tkcin0_O18*fac_kcin 362 tkcin1(ixt) = tkcin1_O18*fac_kcin 363 tkcin2(ixt) = tkcin2_O18*fac_kcin 364 if (tnat1) then 365 tnat(ixt)=1 366 else 367 tnat(ixt)=155.76E-6 368 endif 369 toce(ixt)=tnat(ixt)*(1.0+pente_MWL*deltaO18_oce/1000.0) 370 tcorr(ixt)=1.0+fac_enrichoce18*pente_MWL 371 talph1(ixt)=24844. 372 talph2(ixt)=-76.248 373 talph3(ixt)=52.612E-3 374 talps1(ixt)=16288. 375 talps2(ixt)=-0.0934 376 !ZXalpha_liq_sol=1.0192 ! Weston, Ralph, 1955 377 alpha_liq_sol(ixt)=1.0212 378 ! valeur de Lehmann & Siegenthaler, 1991, Journal of 379 ! Glaciology, vol 37, p 23 380 Rdefault(ixt)=tnat(ixt)*((-6.0*pente_MWL+10.0)/1000.0+1.0) 381 Rmethox(ixt)=tnat(ixt)*(-25.0/1000.+1.) ! Zahn et al 2006 382 endif 383 if (ixt.eq.iso_eau) then ! Oxygene16 384 tkcin0(ixt) = 0.0 385 tkcin1(ixt) = 0.0 386 tkcin2(ixt) = 0.0 387 tnat(ixt)=1. 388 toce(ixt)=tnat(ixt) 389 tcorr(ixt)=1.0 390 tdifrel(ixt)=1. 391 talph1(ixt)=0. 392 talph2(ixt)=0. 393 talph3(ixt)=0. 394 talps1(ixt)=0. 395 talph3(ixt)=0. 396 alpha_liq_sol(ixt)=1. 397 Rdefault(ixt)=tnat(ixt)*1.0 398 Rmethox(ixt)=1.0 399 endif 400 enddo ! ixt=1,niso 304 401 305 402 IF(.NOT.Rdefault_smow) then … … 308 405 ENDIF 309 406 write(*,*) 'Rdefault=',Rdefault 407 write(*,*) 'toce=',toce 310 408 311 409 !--- Sensitivity test: no kinetic effect in sfc evaporation -
LMDZ6/branches/cirrus/libf/phylmdiso/isotopes_routines_mod.F90
r4491 r5202 1525 1525 #endif 1526 1526 pxtfra=max(min(pxtfra,alpha_max),0.0) 1527 1528 1527 1529 1528 end subroutine fractcalk_liq … … 15922 15921 15923 15922 ! verif 15924 ! text="phyisoetat0 67"15925 ! write(*,*) 'snow(8,1)=',snow(8,1)15926 ! write(*,*) 'xtsnow(4,8,1)=',xtsnow(4,8,1)15927 15923 #ifdef ISOVERIF 15928 15924 do i=1,klon … … 15934 15930 enddo !do ixt=1,niso 15935 15931 enddo !do i=1,klon 15936 #endif15937 #ifdef ISOVERIF15938 15932 do i=1,klon 15939 15933 if (iso_eau.gt.0) then … … 16021 16015 endif 16022 16016 enddo !do i=1,klon 16023 16024 16017 #endif 16025 16018 !end verif … … 16128 16121 deltaD_run_off_lic_0(ixt)=deltaD_sol(ixt) 16129 16122 deltaD_land_ice(ixt)=deltaD_snow(ixt) 16130 call fractcalk_liq(ixt, 283.0, alpha(ixt)) 16123 call fractcalk_liq(ixt, 283.0, alpha(ixt)) 16131 16124 enddo !do ixt=1,niso 16132 16125 call calcul_kcin(2.0,kcin) … … 18830 18823 if ((iso_HDO.gt.0).and.(ixt.eq.iso_HDO)) then 18831 18824 if (q.gt.ridicule) then 18825 write(*,*) 'xt,q=',xt,q 18826 write(*,*) 'alpha=',alpha 18827 write(*,*) 'toce,kcin,h0=',toce,kcin,h0 18828 write(*,*) 'RMerlivat=',RMerlivat 18832 18829 call iso_verif_aberrant_encadre( xt/q, 'isotopes_routines_mod 18930b: iso_init_ideal') 18833 18830 endif … … 18902 18899 end subroutine appel_stewart_debug 18903 18900 18901 18902 subroutine dispatch(klon,klev,qx,q_seri,xt_seri,ql_seri,xtl_seri,qs_seri,xts_seri) 18903 18904 use infotrac_phy, ONLY: nqtot,nqo,ivap,iliq,isol,iqIsoPha,ntraciso=>ntiso 18905 implicit none 18906 18907 ! inputs 18908 integer, intent(in) :: klon,klev 18909 real,dimension(klon,klev,nqtot), intent(in) ::qx 18910 18911 ! outputs 18912 real,dimension(klon,klev), intent(out) ::q_seri,ql_seri,qs_seri 18913 real,dimension(ntraciso,klon,klev), intent(out) :: xt_seri,xtl_seri,xts_seri 18914 18915 ! locals 18916 integer :: i,k,ixt 18917 18918 do k=1,klev 18919 do i=1,klon 18920 q_seri(i,k) = qx(i,k,ivap) 18921 ql_seri(i,k) = qx(i,k,iliq) 18922 IF (nqo.EQ.2) THEN !--vapour and liquid only 18923 qs_seri(i,k) = 0. 18924 ELSE IF (nqo.ge.3) THEN !--vapour, liquid and ice 18925 qs_seri(i,k) = qx(i,k,isol) 18926 ENDIF 18927 do ixt=1,ntraciso 18928 xt_seri(ixt,i,k) = qx(i,k,iqIsoPha(ixt,ivap)) 18929 xtl_seri(ixt,i,k) = qx(i,k,iqIsoPha(ixt,iliq)) 18930 if (nqo.eq.2) then 18931 xts_seri(ixt,i,k) = 0. 18932 else if (nqo.eq.3) then 18933 xts_seri(ixt,i,k) = qx(i,k,iqIsoPha(ixt,isol)) 18934 endif 18935 enddo !do ixt=1,niso 18936 18937 enddo 18938 enddo 18939 18940 end subroutine dispatch 18941 18942 subroutine together(klon,klev,qx,q_seri,xt_seri,ql_seri,xtl_seri,qs_seri,xts_seri) 18943 18944 use infotrac_phy, ONLY: nqtot,nqo,ivap,iliq,isol,iqIsoPha,ntraciso=>ntiso 18945 implicit none 18946 18947 ! inputs 18948 integer, intent(in) :: klon,klev 18949 real,dimension(klon,klev), intent(in) ::q_seri,ql_seri,qs_seri 18950 real,dimension(ntraciso,klon,klev), intent(in) :: xt_seri,xtl_seri,xts_seri 18951 18952 ! inputs 18953 real,dimension(klon,klev,nqtot), intent(out) ::qx 18954 18955 ! locals 18956 integer :: i,k,ixt 18957 18958 do k=1,klev 18959 do i=1,klon 18960 qx(i,k,ivap) = q_seri(i,k) 18961 qx(i,k,iliq) = ql_seri(i,k) 18962 IF (nqo.ge.3) THEN !--vapour, liquid and ice 18963 qx(i,k,isol) = qs_seri(i,k) 18964 ENDIF 18965 do ixt=1,ntraciso 18966 qx(i,k,iqIsoPha(ixt,ivap)) = xt_seri(ixt,i,k) 18967 qx(i,k,iqIsoPha(ixt,iliq)) = xtl_seri(ixt,i,k) 18968 if (nqo.ge.3) then 18969 qx(i,k,iqIsoPha(ixt,isol)) = xts_seri(ixt,i,k) 18970 endif 18971 enddo !do ixt=1,niso 18972 18973 enddo 18974 enddo 18975 18976 end subroutine together 18977 18978 18904 18979 END MODULE isotopes_routines_mod 18905 18980 #endif -
LMDZ6/branches/cirrus/libf/phylmdiso/isotopes_verif_mod.F90
r4491 r5202 1042 1042 write(*,*) 'deltaD=',deltaD 1043 1043 write(*,*) 'Dexcess=',dexcess 1044 write(*,*) 'tnat=',tnat 1044 1045 ! stop 1045 1046 iso_verif_O18_aberrant_nostop=1 -
LMDZ6/branches/cirrus/libf/phylmdiso/isotrac_routines_mod.F90
r4491 r5202 681 681 Eqi_prime_cas(il)=Eqi_prime(cas(il)) & 682 682 & *(Pxtisup(ieau,cas(il))/Pqisup(cas(il))) 683 Eqi_cas(il)=Eqi( il) &683 Eqi_cas(il)=Eqi(cas(il)) & ! corr bug Camille 15 juin 2024 684 684 & *(Pxtisup(ieau,cas(il))/Pqisup(cas(il))) 685 685 else -
LMDZ6/branches/cirrus/libf/phylmdiso/phyetat0_mod.F90
r5055 r5202 30 30 solsw, solswfdiff, t_ancien, u_ancien, v_ancien, w01, wake_cstar, wake_deltaq, & 31 31 wake_deltat, wake_delta_pbl_TKE, delta_tsurf, beta_aridity, wake_fip, wake_pe, & 32 wake_s, wake_dens, awake_dens, cv_gen, zgam, zmax0, zmea, zpic, zsig, &32 wake_s, awake_s, wake_dens, awake_dens, cv_gen, zgam, zmax0, zmea, zpic, zsig, & 33 33 #ifdef ISO 34 34 fxtevap, xtsol, xt_ancien, xtl_ancien, xts_ancien, wake_deltaxt, & … … 49 49 USE time_phylmdz_mod, ONLY: init_iteration, pdtphys, itau_phy 50 50 USE wxios, ONLY: missing_val_xios => missing_val, using_xios 51 use netcdf, only: nf90_fill_real51 use netcdf, only: missing_val_netcdf => nf90_fill_real 52 52 use config_ocean_skin_m, only: activate_ocean_skin 53 53 #ifdef ISO … … 112 112 REAL Rland_ice(niso,klon) 113 113 #endif 114 115 IF (using_xios) THEN 116 missing_val=missing_val_xios 117 ELSE 118 missing_val=missing_val_netcdf 119 ENDIF 120 114 121 ! FH1D 115 122 ! real iolat(jjm+1) … … 117 124 118 125 ! Ouvrir le fichier contenant l'etat initial: 119 IF (using_xios) THEN120 missing_val = missing_val_xios121 ELSE122 missing_val = nf90_fill_real123 ENDIF124 126 125 127 CALL open_startphy(fichnom) … … 324 326 325 327 !=================================================================== 328 ! Lecture dans le cas iflag_pbl_surface =1 329 !=================================================================== 330 331 if ( iflag_physiq <= 1 ) then 332 !=================================================================== 326 333 ! Lecture des temperatures du sol profond: 327 334 !=================================================================== … … 351 358 found=phyetat0_get(snow_fall,"snow_f","snow fall",0.) 352 359 found=phyetat0_get(rain_fall,"rain_f","rain fall",0.) 353 354 360 IF (ok_bs) THEN 355 361 found=phyetat0_get(bs_fall,"bs_f","blowing snow fall",0.) … … 405 411 ENDIF 406 412 413 endif ! iflag_physiq <= 1 414 407 415 ! Lecture de l'age de la neige: 408 416 found=phyetat0_srf(agesno,"AGESNO","SNOW AGE",0.001) … … 498 506 found=phyetat0_get(wake_deltaq,"WAKE_DELTAQ","Delta hum. wake/env",0.) 499 507 found=phyetat0_get(wake_s,"WAKE_S","Wake frac. area",0.) 508 found=phyetat0_get(awake_s,"AWAKE_S","Active Wake frac. area",0.) 500 509 !jyg< 501 510 ! Set wake_dens to -1000. when there is no restart so that the actual … … 677 686 ! write(*,*) 'xtsnow(:,994,2)=',xtsnow(:,994,2) 678 687 !#endif 679 688 if ( iflag_physiq <= 1 ) then 680 689 CALL pbl_surface_init(fder, snow, qsurf, tsoil) 681 690 #ifdef ISO 682 691 CALL pbl_surface_init_iso(xtsnow,Rland_ice) 683 692 #endif 693 endif 684 694 685 695 ! Initialize module ocean_cpl_mod for the case of coupled ocean -
LMDZ6/branches/cirrus/libf/phylmdiso/phys_local_var_mod.F90
r5055 r5202 14 14 REAL, SAVE, ALLOCATABLE :: ql_seri(:,:),qs_seri(:,:) 15 15 !$OMP THREADPRIVATE(ql_seri,qs_seri) 16 ! SN 15/07/2024 ISO 4D 17 REAL, SAVE, ALLOCATABLE :: qx_seri(:,:,:) 18 !$OMP THREADPRIVATE(qx_seri) 19 ! SN 16 20 REAL, SAVE, ALLOCATABLE :: qbs_seri(:,:) 17 21 !$OMP THREADPRIVATE(qbs_seri) … … 24 28 REAL, SAVE, ALLOCATABLE :: pbl_eps(:,:,:) 25 29 !$OMP THREADPRIVATE(pbl_eps) 30 REAL, SAVE, ALLOCATABLE :: tke_shear(:,:,:), tke_buoy(:,:,:), tke_trans(:,:,:) 31 !$OMP THREADPRIVATE(tke_shear,tke_buoy,tke_trans) 26 32 REAL, SAVE, ALLOCATABLE :: tr_seri(:,:,:) 27 33 !$OMP THREADPRIVATE(tr_seri) … … 64 70 REAL, SAVE, ALLOCATABLE :: d_t_eva(:,:),d_q_eva(:,:),d_ql_eva(:,:),d_qi_eva(:,:) 65 71 !$OMP THREADPRIVATE(d_t_eva,d_q_eva,d_ql_eva,d_qi_eva) 72 ! SN 15/07/2024 ISO 4D 73 REAL, SAVE, ALLOCATABLE :: d_qx_eva(:,:,:) 74 !$OMP THREADPRIVATE(d_qx_eva) 75 ! SN 66 76 REAL, SAVE, ALLOCATABLE :: d_t_lscst(:,:),d_q_lscst(:,:) 67 77 !$OMP THREADPRIVATE(d_t_lscst,d_q_lscst) … … 84 94 REAL, SAVE, ALLOCATABLE :: d_t_vdf_x(:,:), d_q_vdf_x(:,:) 85 95 !$OMP THREADPRIVATE( d_t_vdf_x, d_q_vdf_x) 86 REAL, SAVE, ALLOCATABLE :: d_t_bs (:,:), d_q_bs(:,:), d_qbs_bs(:,:)87 !$OMP THREADPRIVATE( d_t_bs ,d_q_bs, d_qbs_bs)96 REAL, SAVE, ALLOCATABLE :: d_t_bsss(:,:), d_q_bsss(:,:), d_qbs_bsss(:,:) 97 !$OMP THREADPRIVATE( d_t_bsss,d_q_bsss, d_qbs_bsss) 88 98 !>nrlmd+jyg 89 99 REAL, SAVE, ALLOCATABLE :: d_t_oro(:,:) … … 124 134 REAL, SAVE, ALLOCATABLE :: xts_seri(:,:,:) 125 135 !$OMP THREADPRIVATE( xts_seri) 136 REAL, SAVE, ALLOCATABLE :: xtbs_seri(:,:,:) 137 !$OMP THREADPRIVATE( xtbs_seri) 126 138 REAL, SAVE, ALLOCATABLE :: d_xt_eva(:,:,:) 127 139 !$OMP THREADPRIVATE( d_xt_eva) … … 134 146 REAL, SAVE, ALLOCATABLE :: d_xt_dyn(:,:,:) 135 147 !$OMP THREADPRIVATE( d_xt_dyn) 136 REAL, SAVE, ALLOCATABLE :: d_xtl_dyn(:,:,:), d_xts_dyn(:,:,:) 137 !$OMP THREADPRIVATE(d_xtl_dyn, d_xts_dyn )148 REAL, SAVE, ALLOCATABLE :: d_xtl_dyn(:,:,:), d_xts_dyn(:,:,:), d_xtbs_dyn(:,:,:) 149 !$OMP THREADPRIVATE(d_xtl_dyn, d_xts_dyn, d_xtbs_dyn) 138 150 REAL, SAVE, ALLOCATABLE :: d_xt_con(:,:,:) 139 151 !$OMP THREADPRIVATE( d_xt_con) … … 166 178 !$OMP THREADPRIVATE(d_ts, d_tr) 167 179 168 ! aerosols169 REAL, SAVE, ALLOCATABLE :: m_allaer (:,:,:)170 !$OMP THREADPRIVATE(m_allaer)171 180 ! diagnostique pour le rayonnement 172 181 REAL, SAVE, ALLOCATABLE :: topswad_aero(:), solswad_aero(:) ! diag … … 292 301 !$OMP THREADPRIVATE(toplwad0_aerop, sollwad0_aerop) 293 302 303 !AI 08 2023 ajout pour Ecrad 304 REAL,ALLOCATABLE,SAVE :: topswad_aero_s2(:), solswad_aero_s2(:) 305 !$OMP THREADPRIVATE(topswad_aero_s2, solswad_aero_s2) 306 REAL,ALLOCATABLE,SAVE :: topswai_aero_s2(:), solswai_aero_s2(:) 307 !$OMP THREADPRIVATE(topswai_aero_s2, solswai_aero_s2) 308 REAL,ALLOCATABLE,SAVE :: topswad0_aero_s2(:), solswad0_aero_s2(:) 309 !$OMP THREADPRIVATE(topswad0_aero_s2, solswad0_aero_s2) 310 REAL,ALLOCATABLE,SAVE :: topsw_aero_s2(:,:), topsw0_aero_s2(:,:) 311 !$OMP THREADPRIVATE(topsw_aero_s2, topsw0_aero_s2) 312 REAL,ALLOCATABLE,SAVE :: solsw_aero_s2(:,:), solsw0_aero_s2(:,:) 313 !$OMP THREADPRIVATE(solsw_aero_s2, solsw0_aero_s2) 314 REAL,ALLOCATABLE,SAVE :: topswcf_aero_s2(:,:), solswcf_aero_s2(:,:) 315 !$OMP THREADPRIVATE(topswcf_aero_s2, solswcf_aero_s2) 316 ! additional LW variables CK 317 REAL,ALLOCATABLE,SAVE :: toplwad_aero_s2(:), sollwad_aero_s2(:) 318 !$OMP THREADPRIVATE(toplwad_aero_s2, sollwad_aero_s2) 319 REAL,ALLOCATABLE,SAVE :: toplwai_aero_s2(:), sollwai_aero_s2(:) 320 !$OMP THREADPRIVATE(toplwai_aero_s2, sollwai_aero_s2) 321 REAL,ALLOCATABLE,SAVE :: toplwad0_aero_s2(:), sollwad0_aero_s2(:) 322 !$OMP THREADPRIVATE(toplwad0_aero_s2, sollwad0_aero_s2) 323 294 324 !Ajout de celles n??cessaires au phys_output_write_mod 295 325 REAL, SAVE, ALLOCATABLE :: tal1(:), pal1(:), pab1(:), pab2(:) … … 300 330 !$OMP THREADPRIVATE(sens, flwp, fiwp) 301 331 !! 302 !FC 332 !FC 303 333 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:) :: zxfluxt, zxfluxq 304 334 !$OMP THREADPRIVATE(zxfluxt, zxfluxq) … … 315 345 REAL, SAVE, ALLOCATABLE,DIMENSION(:,:) :: d_deltat_wk, d_deltaq_wk 316 346 !$OMP THREADPRIVATE(d_deltat_wk, d_deltaq_wk) 317 REAL,ALLOCATABLE,SAVE,DIMENSION(:) :: d_s_wk, d_ dens_a_wk, d_dens_wk318 !$OMP THREADPRIVATE(d_s_wk, d_ dens_a_wk, d_dens_wk)347 REAL,ALLOCATABLE,SAVE,DIMENSION(:) :: d_s_wk, d_s_a_wk, d_dens_wk, d_dens_a_wk 348 !$OMP THREADPRIVATE(d_s_wk, d_s_a_wk, d_dens_wk, d_dens_a_wk) 319 349 REAL, SAVE, ALLOCATABLE,DIMENSION(:,:) :: d_deltat_wk_gw, d_deltaq_wk_gw 320 350 !$OMP THREADPRIVATE(d_deltat_wk_gw, d_deltaq_wk_gw) … … 328 358 !!!OMP THREADPRIVATE(d_s_the, d_dens_the) 329 359 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:) :: d_deltat_ajs_cv, d_deltaq_ajs_cv 330 !$OMP THREADPRIVATE(d_deltat_ajs_cv, d_deltaq_ajs_cv) 360 !$OMP THREADPRIVATE(d_deltat_ajs_cv, d_deltaq_ajs_cv) 331 361 #ifdef ISO 332 362 REAL, SAVE, ALLOCATABLE,DIMENSION(:,:,:) :: d_deltaxt_wk … … 376 406 REAL,ALLOCATABLE,SAVE,DIMENSION(:) :: zxfluxlat, zxtsol, snow_lsc, zxfqfonte 377 407 !$OMP THREADPRIVATE(zxfluxlat, zxtsol, snow_lsc, zxfqfonte) 378 REAL,ALLOCATABLE,SAVE,DIMENSION(:) :: zxrunofflic 379 !$OMP THREADPRIVATE(zxrunofflic) 408 !SN runoffdiag 409 REAL,ALLOCATABLE,SAVE,DIMENSION(:) :: zxrunofflic, runoff_diag 410 !$OMP THREADPRIVATE(zxrunofflic, runoff_diag) 380 411 REAL,ALLOCATABLE,SAVE,DIMENSION(:) :: zxqsurf, rain_lsc, rain_num 381 412 !$OMP THREADPRIVATE(zxqsurf, rain_lsc, rain_num) … … 383 414 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:) :: xtevap,xtprw 384 415 !$OMP THREADPRIVATE(xtevap,xtprw) 385 REAL,ALLOCATABLE,SAVE,DIMENSION(:) :: h1_diag ,runoff_diag416 REAL,ALLOCATABLE,SAVE,DIMENSION(:) :: h1_diag 386 417 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:) :: xtrunoff_diag 387 !$OMP THREADPRIVATE(h1_diag ,runoff_diag,xtrunoff_diag)418 !$OMP THREADPRIVATE(h1_diagv,xtrunoff_diag) 388 419 REAL,ALLOCATABLE,SAVE,DIMENSION(:,:) :: zxfxtcalving 389 420 !$OMP THREADPRIVATE(zxfxtcalving) … … 581 612 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:) :: pfraclr,pfracld 582 613 !$OMP THREADPRIVATE(pfraclr,pfracld) 614 REAL, SAVE, ALLOCATABLE :: cldfraliq(:,:) 615 !$OMP THREADPRIVATE(cldfraliq) 616 REAL, SAVE, ALLOCATABLE ::mean_icefracturb(:,:) 617 !$OMP THREADPRIVATE(mean_icefracturb) 618 REAL, SAVE, ALLOCATABLE :: sigma2_icefracturb(:,:) 619 !$OMP THREADPRIVATE(sigma2_icefracturb) 583 620 584 621 ! variables de sorties MM … … 671 708 ! 672 709 ! variables for stratospheric aerosol 710 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:) :: d_q_emiss 711 !$OMP THREADPRIVATE(d_q_emiss) 673 712 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:) :: R2SO4 674 713 !$OMP THREADPRIVATE(R2SO4) 714 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: R2SO4B 715 !$OMP THREADPRIVATE(R2SO4B) 675 716 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:) :: DENSO4 676 717 !$OMP THREADPRIVATE(DENSO4) 718 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:, :) :: DENSO4B 719 !$OMP THREADPRIVATE(DENSO4B) 677 720 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:) :: f_r_wet 678 721 !$OMP THREADPRIVATE(f_r_wet) 722 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:, :) :: f_r_wetB 723 !$OMP THREADPRIVATE(f_r_wetB) 679 724 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:) :: decfluxaer 680 725 !$OMP THREADPRIVATE(decfluxaer) … … 685 730 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:) :: SO2_lifetime 686 731 !$OMP THREADPRIVATE(SO2_lifetime) 732 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:) :: H2SO4_lifetime 733 !$OMP THREADPRIVATE(H2SO4_lifetime) 734 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:) :: O3_clim 735 !$OMP THREADPRIVATE(O3_clim) 687 736 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:) :: alpha_bin 688 737 !$OMP THREADPRIVATE(alpha_bin) … … 701 750 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:) :: vsed_aer 702 751 !$OMP THREADPRIVATE(vsed_aer) 752 ! Sulfate aerosol concentration (dry mixing ratio) (condensed H2SO4 mmr) 753 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:) :: sulfmmr 754 !$OMP THREADPRIVATE(sulfmmr) 755 ! SAD all aerosols (cm2/cm3) 756 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:) :: SAD_sulfate 757 !$OMP THREADPRIVATE(SAD_sulfate) 758 ! Effective radius of wet surface aerosols (cm) 759 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:) :: reff_sulfate 760 !$OMP THREADPRIVATE(reff_sulfate) 761 ! sulfate MMR in different modes (based on sulfmmr, it must be dry mmr) 762 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: sulfmmr_mode 763 !$OMP THREADPRIVATE(sulfmmr_mode) 764 ! particle concentration in different modes (part/m3) 765 REAL, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: nd_mode 766 !$OMP THREADPRIVATE(nd_mode) 703 767 ! 704 768 !---3D budget variables … … 749 813 SUBROUTINE phys_local_var_init 750 814 USE dimphy 751 USE infotrac_phy, ONLY : nbtr 815 USE infotrac_phy, ONLY : nbtr,nqtot 752 816 #ifdef ISO 753 817 USE infotrac_phy, ONLY : ntraciso=>ntiso,niso … … 757 821 USE phys_output_var_mod 758 822 USE phys_state_var_mod 823 #ifdef CPP_StratAer 824 USE infotrac_phy, ONLY : nbtr_bin 825 #endif 759 826 760 827 IMPLICIT NONE 761 828 ALLOCATE(t_seri(klon,klev),q_seri(klon,klev),ql_seri(klon,klev),qs_seri(klon,klev), qbs_seri(klon,klev)) 829 ! SN 4D ISO 830 ALLOCATE(qx_seri(klon,klev,nqtot)) 831 ! SN 762 832 ALLOCATE(u_seri(klon,klev),v_seri(klon,klev)) 763 833 ALLOCATE(cf_seri(klon,klev),rvc_seri(klon,klev)) 764 834 ALLOCATE(l_mixmin(klon,klev+1,nbsrf),l_mix(klon,klev+1,nbsrf),wprime(klon,klev+1,nbsrf)) 765 835 ALLOCATE(pbl_eps(klon,klev+1,nbsrf+1)) 836 ALLOCATE(tke_shear(klon,klev+1,nbsrf), tke_buoy(klon,klev+1,nbsrf), tke_trans(klon,klev+1,nbsrf)) 766 837 pbl_eps(:,:,:)=0. 838 tke_shear(:,:,:)=0.; tke_buoy(:,:,:)=0.; tke_trans(:,:,:)=0. 767 839 l_mix(:,:,:)=0.;l_mixmin(:,:,:)=0.;wprime(:,:,:)=0. ! doit etre initialse car pas toujours remplis 768 840 ALLOCATE(rhcl(klon,klev)) … … 789 861 ALLOCATE(d_u_ajs(klon,klev),d_v_ajs(klon,klev)) 790 862 ALLOCATE(d_t_eva(klon,klev),d_q_eva(klon,klev)) 863 ! SN 4D ISO 864 ALLOCATE(d_qx_eva(klon,klev,nqtot)) 865 ! SN 791 866 ALLOCATE(d_ql_eva(klon,klev),d_qi_eva(klon,klev)) 792 867 ALLOCATE(d_t_lscst(klon,klev),d_q_lscst(klon,klev)) … … 795 870 ALLOCATE(d_t_vdf(klon,klev),d_q_vdf(klon,klev),d_t_diss(klon,klev)) 796 871 ALLOCATE (d_qbs_vdf(klon,klev)) 797 ALLOCATE(d_t_bs (klon,klev),d_q_bs(klon,klev),d_qbs_bs(klon,klev))872 ALLOCATE(d_t_bsss(klon,klev),d_q_bsss(klon,klev),d_qbs_bsss(klon,klev)) 798 873 ALLOCATE(d_t_vdf_w(klon,klev),d_q_vdf_w(klon,klev)) 799 874 ALLOCATE(d_t_vdf_x(klon,klev),d_q_vdf_x(klon,klev)) … … 802 877 allocate(xtl_seri(ntraciso,klon,klev)) 803 878 allocate(xts_seri(ntraciso,klon,klev)) 879 allocate(xtbs_seri(ntraciso,klon,klev)) 804 880 allocate(d_xt_dyn(ntraciso,klon,klev)) 805 881 allocate(d_xtl_dyn(ntraciso,klon,klev)) 806 882 allocate(d_xts_dyn(ntraciso,klon,klev)) 883 allocate(d_xtbs_dyn(ntraciso,klon,klev)) 807 884 allocate(d_xt_con(ntraciso,klon,klev)) 808 885 allocate(d_xt_wake(ntraciso,klon,klev)) … … 835 912 ALLOCATE(d_u_lif(klon,klev),d_v_lif(klon,klev)) 836 913 ALLOCATE(d_ts(klon,nbsrf), d_tr(klon,klev,nbtr)) 914 837 915 ! Special RRTM 838 916 ALLOCATE(ZLWFT0_i(klon,klev+1),ZSWFT0_i(klon,klev+1),ZFLDN0(klon,klev+1)) … … 913 991 ALLOCATE(toplwad0_aerop(klon), sollwad0_aerop(klon)) 914 992 993 !AI Ajout Ecrad (3Deffect) 994 ALLOCATE(topswad_aero_s2(klon), solswad_aero_s2(klon)) 995 ALLOCATE(topswai_aero_s2(klon), solswai_aero_s2(klon)) 996 ALLOCATE(topswad0_aero_s2(klon), solswad0_aero_s2(klon)) 997 ALLOCATE(topsw_aero_s2(klon,naero_grp), topsw0_aero_s2(klon,naero_grp)) 998 ALLOCATE(solsw_aero_s2(klon,naero_grp), solsw0_aero_s2(klon,naero_grp)) 999 ALLOCATE(topswcf_aero_s2(klon,naero_grp), solswcf_aero_s2(klon,naero_grp)) 1000 ! additional LW variables CK 1001 ALLOCATE(toplwad_aero_s2(klon), sollwad_aero_s2(klon)) 1002 ALLOCATE(toplwai_aero_s2(klon), sollwai_aero_s2(klon)) 1003 ALLOCATE(toplwad0_aero_s2(klon), sollwad0_aero_s2(klon)) 1004 915 1005 ! FH Ajout de celles necessaires au phys_output_write_mod 916 1006 … … 923 1013 ALLOCATE(wake_omg(klon, klev)) 924 1014 ALLOCATE(d_deltat_wk(klon, klev), d_deltaq_wk(klon, klev)) 925 ALLOCATE(d_s_wk(klon), d_ dens_a_wk(klon), d_dens_wk(klon))1015 ALLOCATE(d_s_wk(klon), d_s_a_wk(klon), d_dens_wk(klon), d_dens_a_wk(klon)) 926 1016 ALLOCATE(d_deltat_wk_gw(klon, klev), d_deltaq_wk_gw(klon, klev)) 927 1017 ALLOCATE(d_deltat_vdf(klon, klev), d_deltaq_vdf(klon, klev)) … … 958 1048 ALLOCATE(zxfqcalving(klon), zxfluxlat(klon)) 959 1049 ALLOCATE(zxtsol(klon), snow_lsc(klon), zxfqfonte(klon), zxqsurf(klon)) 960 ALLOCATE(zxrunofflic(klon)) 1050 ! SN add runoff_diag 1051 ALLOCATE(zxrunofflic(klon), runoff_diag(klon)) 1052 runoff_diag(:)=0. 961 1053 ALLOCATE(zxustartlic(klon), zxrhoslic(klon), zxqsaltlic(klon)) 962 1054 zxustartlic(:)=0. ; zxrhoslic(:)=0. ; zxqsaltlic(:)=0. … … 973 1065 ALLOCATE(xtrain_lsc(ntraciso,klon)) 974 1066 ALLOCATE(xtrunoff_diag(niso,klon)) 975 ALLOCATE(h1_diag(klon),runoff_diag(klon)) 1067 ALLOCATE(h1_diag(klon)) 1068 !SN 1069 xtrunoff_diag(:,:)=0. ! because variables are only given values on knon grid points 976 1070 #endif 977 1071 ! … … 1032 1126 ALLOCATE(wfevap(klon, nbsrf)) 1033 1127 ALLOCATE(evap_pot(klon, nbsrf)) 1034 ! FC 1128 ! FC 1035 1129 ALLOCATE(zxfluxq(klon,klev),zxfluxt(klon,klev)) 1036 !1037 1130 ! 1038 1131 ! Deep convective variables used in phytrac 1039 1132 ALLOCATE(pmflxr(klon, klev+1), pmflxs(klon, klev+1)) 1040 1133 ALLOCATE(wdtrainA(klon,klev),wdtrainS(klon,klev),wdtrainM(klon,klev)) 1041 ALLOCATE(dnwd(klon, klev), upwd(klon, klev) 1134 ALLOCATE(dnwd(klon, klev), upwd(klon, klev)) 1042 1135 ALLOCATE(ep(klon,klev)) ! epmax_cape 1043 ALLOCATE(da(klon,klev), mp(klon,klev) 1044 ALLOCATE(phi(klon,klev,klev) 1045 ALLOCATE(wght_cvfd(klon,klev) 1046 ALLOCATE(phi2(klon,klev,klev) 1136 ALLOCATE(da(klon,klev), mp(klon,klev)) 1137 ALLOCATE(phi(klon,klev,klev)) 1138 ALLOCATE(wght_cvfd(klon,klev)) 1139 ALLOCATE(phi2(klon,klev,klev)) 1047 1140 ALLOCATE(d1a(klon,klev), dam(klon,klev)) 1048 ALLOCATE(ev(klon,klev) 1049 ALLOCATE(elij(klon,klev,klev) 1050 ALLOCATE(qtaa(klon,klev) 1051 ALLOCATE(clw(klon,klev) 1052 ALLOCATE(epmlmMm(klon,klev,klev), eplaMm(klon,klev) 1053 ALLOCATE(sij(klon,klev,klev) 1141 ALLOCATE(ev(klon,klev)) 1142 ALLOCATE(elij(klon,klev,klev)) 1143 ALLOCATE(qtaa(klon,klev)) 1144 ALLOCATE(clw(klon,klev)) 1145 ALLOCATE(epmlmMm(klon,klev,klev), eplaMm(klon,klev)) 1146 ALLOCATE(sij(klon,klev,klev)) 1054 1147 #ifdef ISO 1055 1148 ALLOCATE(xtwdtrainA(ntraciso,klon,klev)) … … 1094 1187 ALLOCATE(pfraclr(klon,klev),pfracld(klon,klev)) 1095 1188 pfraclr(:,:)=0. ; pfracld(:,:)=0. ! because not always defined 1189 ALLOCATE(cldfraliq(klon,klev)) 1190 ALLOCATE(sigma2_icefracturb(klon,klev)) 1191 ALLOCATE(mean_icefracturb(klon,klev)) 1096 1192 ALLOCATE(distcltop(klon,klev)) 1097 1193 ALLOCATE(temp_cltop(klon,klev)) … … 1134 1230 1135 1231 #ifdef CPP_StratAer 1232 ALLOCATE (d_q_emiss(klon,klev)) 1136 1233 ALLOCATE (R2SO4(klon,klev)) 1234 ALLOCATE (R2SO4B(klon,klev,nbtr_bin)) 1137 1235 ALLOCATE (DENSO4(klon,klev)) 1236 ALLOCATE (DENSO4B(klon,klev,nbtr_bin)) 1138 1237 ALLOCATE (f_r_wet(klon,klev)) 1238 ALLOCATE (f_r_wetB(klon,klev,nbtr_bin)) 1139 1239 ALLOCATE (decfluxaer(klon,nbtr)) 1140 1240 ALLOCATE (mdw(nbtr)) … … 1147 1247 ALLOCATE (OCS_lifetime(klon,klev)) 1148 1248 ALLOCATE (SO2_lifetime(klon,klev)) 1249 ALLOCATE (H2SO4_lifetime(klon,klev)) 1250 ALLOCATE (O3_clim(klon,klev)) 1149 1251 ALLOCATE (alpha_bin(nbands_sw_rrtm+nbands_lw_rrtm+nwave,nbtr)) 1150 1252 ALLOCATE (piz_bin(nbands_sw_rrtm+nbands_lw_rrtm+nwave,nbtr)) … … 1171 1273 ALLOCATE (surf_PM25_sulf(klon)) 1172 1274 ALLOCATE (vsed_aer(klon,klev)) 1275 ALLOCATE (sulfmmr(klon,klev)) 1276 ALLOCATE (SAD_sulfate(klon,klev)) 1277 ALLOCATE (reff_sulfate(klon,klev)) 1278 ALLOCATE (sulfmmr_mode(klon,klev,nbtr_bin)) 1279 ALLOCATE (nd_mode(klon,klev,nbtr_bin)) 1173 1280 #endif 1174 1281 … … 1181 1288 IMPLICIT NONE 1182 1289 DEALLOCATE(t_seri,q_seri,ql_seri,qs_seri, qbs_seri) 1290 ! SN 4D ISO 1291 DEALLOCATE(qx_seri) 1292 ! SN 1183 1293 DEALLOCATE(u_seri,v_seri) 1184 1294 DEALLOCATE(cf_seri,rvc_seri) 1185 1295 DEALLOCATE(l_mixmin,l_mix,wprime) 1296 DEALLOCATE(tke_shear,tke_buoy,tke_trans) 1186 1297 DEALLOCATE(pbl_eps) 1187 1298 DEALLOCATE(rhcl) … … 1208 1319 DEALLOCATE(d_u_ajs,d_v_ajs) 1209 1320 DEALLOCATE(d_t_eva,d_q_eva) 1321 ! SN 4D ISO 1322 DEALLOCATE(d_qx_eva) 1323 ! SN 1210 1324 DEALLOCATE(d_ql_eva,d_qi_eva) 1211 1325 DEALLOCATE(d_t_lscst,d_q_lscst) … … 1214 1328 DEALLOCATE(d_t_vdf,d_q_vdf,d_t_diss) 1215 1329 DEALLOCATE(d_qbs_vdf) 1216 DEALLOCATE(d_t_bs ,d_q_bs,d_qbs_bs)1217 #ifdef ISO 1218 deallocate(xt_seri,xtl_seri,xts_seri )1330 DEALLOCATE(d_t_bsss,d_q_bsss,d_qbs_bsss) 1331 #ifdef ISO 1332 deallocate(xt_seri,xtl_seri,xts_seri,xtbs_seri) 1219 1333 DEALLOCATE(d_xtl_eva,d_xti_eva) 1220 deallocate(d_xt_dyn,d_xtl_dyn,d_xts_dyn )1334 deallocate(d_xt_dyn,d_xtl_dyn,d_xts_dyn,d_xtbs_dyn) 1221 1335 deallocate(d_xt_con) 1222 1336 deallocate(d_xt_wake) … … 1308 1422 DEALLOCATE(solsw_aerop, solsw0_aerop) 1309 1423 DEALLOCATE(topswcf_aerop, solswcf_aerop) 1310 1311 1424 !CK LW diagnostics 1312 1425 DEALLOCATE(toplwad_aerop, sollwad_aerop) … … 1314 1427 DEALLOCATE(toplwad0_aerop, sollwad0_aerop) 1315 1428 1429 !AI Ajout pour Ecrad (3Deffect) 1430 DEALLOCATE(topswad_aero_s2, solswad_aero_s2) 1431 DEALLOCATE(topswai_aero_s2, solswai_aero_s2) 1432 DEALLOCATE(topswad0_aero_s2, solswad0_aero_s2) 1433 DEALLOCATE(topsw_aero_s2, topsw0_aero_s2) 1434 DEALLOCATE(solsw_aero_s2, solsw0_aero_s2) 1435 DEALLOCATE(topswcf_aero_s2, solswcf_aero_s2) 1436 !CK LW diagnostics 1437 DEALLOCATE(toplwad_aero_s2, sollwad_aero_s2) 1438 DEALLOCATE(toplwai_aero_s2, sollwai_aero_s2) 1439 DEALLOCATE(toplwad0_aero_s2, sollwad0_aero_s2) 1440 1316 1441 ! FH Ajout de celles necessaires au phys_output_write_mod 1317 1442 DEALLOCATE(tal1, pal1, pab1, pab2) … … 1322 1447 DEALLOCATE(wake_omg) 1323 1448 DEALLOCATE(d_deltat_wk, d_deltaq_wk) 1324 DEALLOCATE(d_s_wk, d_ dens_a_wk, d_dens_wk)1449 DEALLOCATE(d_s_wk, d_s_a_wk, d_dens_wk, d_dens_a_wk) 1325 1450 DEALLOCATE(d_deltat_wk_gw, d_deltaq_wk_gw) 1326 1451 DEALLOCATE(d_deltat_vdf, d_deltaq_vdf) … … 1353 1478 DEALLOCATE(uwat, vwat) 1354 1479 DEALLOCATE(zxfqcalving, zxfluxlat) 1355 DEALLOCATE(zxrunofflic) 1480 ! SN runoff_diag 1481 DEALLOCATE(zxrunofflic, runoff_diag) 1356 1482 DEALLOCATE(zxustartlic, zxrhoslic, zxqsaltlic) 1357 1483 DEALLOCATE(zxtsol, snow_lsc, zxfqfonte, zxqsurf) … … 1382 1508 DEALLOCATE(dxtvdf_x, dxtvdf_w) 1383 1509 DEALLOCATE(xt_therm) 1384 DEALLOCATE(h1_diag, runoff_diag,xtrunoff_diag)1510 DEALLOCATE(h1_diag,xtrunoff_diag) 1385 1511 #endif 1386 1512 ! … … 1422 1548 DEALLOCATE(upwd, dnwd) 1423 1549 DEALLOCATE(ep) 1424 DEALLOCATE(da, mp 1425 DEALLOCATE(phi 1426 DEALLOCATE(wght_cvfd 1427 DEALLOCATE(phi2 1550 DEALLOCATE(da, mp) 1551 DEALLOCATE(phi) 1552 DEALLOCATE(wght_cvfd) 1553 DEALLOCATE(phi2) 1428 1554 DEALLOCATE(d1a, dam) 1429 DEALLOCATE(ev 1430 DEALLOCATE(elij 1431 DEALLOCATE(qtaa 1432 DEALLOCATE(clw 1433 DEALLOCATE(epmlmMm, eplaMm 1434 DEALLOCATE(sij 1555 DEALLOCATE(ev) 1556 DEALLOCATE(elij) 1557 DEALLOCATE(qtaa) 1558 DEALLOCATE(clw) 1559 DEALLOCATE(epmlmMm, eplaMm) 1560 DEALLOCATE(sij) 1435 1561 #ifdef ISO 1436 1562 DEALLOCATE(xtwdtrainA) … … 1472 1598 DEALLOCATE(rneb) 1473 1599 DEALLOCATE(pfraclr,pfracld) 1600 DEALLOCATE(cldfraliq) 1601 DEALLOCATE(sigma2_icefracturb) 1602 DEALLOCATE(mean_icefracturb) 1603 DEALLOCATE (zxsnow,snowhgt,qsnow,to_ice,sissnow,runoff,albsol3_lic) 1474 1604 DEALLOCATE(distcltop) 1475 1605 DEALLOCATE(temp_cltop) 1476 DEALLOCATE (zxsnow,snowhgt,qsnow,to_ice,sissnow,runoff,albsol3_lic)1477 1606 #ifdef ISO 1478 1607 DEALLOCATE (zxxtsnow,xtVprecip,xtVprecipi,pxtrfl,pxtsfl) … … 1507 1636 #ifdef CPP_StratAer 1508 1637 ! variables for strat. aerosol CK 1509 DEALLOCATE (R2SO4) 1510 DEALLOCATE (DENSO4) 1511 DEALLOCATE (f_r_wet) 1638 DEALLOCATE (d_q_emiss) 1639 DEALLOCATE (R2SO4, R2SO4B) 1640 DEALLOCATE (DENSO4, DENSO4B) 1641 DEALLOCATE (f_r_wet, f_r_wetB) 1512 1642 DEALLOCATE (decfluxaer) 1513 1643 DEALLOCATE (mdw) 1514 1644 DEALLOCATE (SO2_lifetime) 1515 1645 DEALLOCATE (OCS_lifetime) 1646 DEALLOCATE (H2SO4_lifetime) 1647 DEALLOCATE (O3_clim) 1516 1648 DEALLOCATE (alpha_bin) 1517 1649 DEALLOCATE (piz_bin) … … 1522 1654 DEALLOCATE (surf_PM25_sulf) 1523 1655 DEALLOCATE (vsed_aer) 1656 DEALLOCATE (sulfmmr) 1657 DEALLOCATE (SAD_sulfate) 1658 DEALLOCATE (reff_sulfate) 1659 DEALLOCATE (sulfmmr_mode) 1660 DEALLOCATE (nd_mode) 1524 1661 DEALLOCATE (budg_3D_ocs_to_so2) 1525 1662 DEALLOCATE (budg_3D_so2_to_h2so4) -
LMDZ6/branches/cirrus/libf/phylmdiso/phys_output_ctrlout_mod.F90
r5055 r5202 1112 1112 TYPE(ctrl_out), SAVE :: o_tke = ctrl_out((/ 4, 10, 10, 10, 10, 10, 11, 11, 11, 11/), & 1113 1113 'tke ', 'TKE', 'm2/s2', (/ ('', i=1, 10) /)) 1114 TYPE(ctrl_out), SAVE :: o_tke_shear = ctrl_out((/ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11/), & 1115 'tke_shear ', 'TKE shear term', 'm2/s3', (/ ('', i=1, 10) /)) 1116 TYPE(ctrl_out), SAVE :: o_tke_buoy = ctrl_out((/ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11/), & 1117 'tke_buoy ', 'TKE buoyancy term', 'm2/s3', (/ ('', i=1, 10) /)) 1118 TYPE(ctrl_out), SAVE :: o_tke_trans = ctrl_out((/ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11/), & 1119 'tke_trans ', 'TKE transport term', 'm2/s3', (/ ('', i=1, 10) /)) 1114 1120 TYPE(ctrl_out), SAVE :: o_tke_dissip = ctrl_out((/ 10, 10, 10, 10, 10, 10, 11, 11, 11, 11/), & 1115 'tke_dissip ', 'TKE DISSIPATION', 'm2/s3', (/ ('', i=1, 10) /)) 1121 'tke_dissip ', 'TKE dissipation term', 'm2/s3', (/ ('', i=1, 10) /)) 1122 1116 1123 TYPE(ctrl_out), SAVE :: o_tke_max = ctrl_out((/ 4, 10, 10, 10, 10, 10, 11, 11, 11, 11/), & 1117 1124 'tke_max', 'TKE max', 'm2/s2', & … … 1442 1449 TYPE(ctrl_out), SAVE :: o_tau_strat_1020 = ctrl_out((/ 11, 11, 11, 11, 11, 11, 11, 11, 11, 1/), & 1443 1450 'OD1020_strat_only', 'Stratospheric Aerosol Optical depth at 1020 nm ', '1', (/ ('', i=1, 10) /)) 1451 TYPE(ctrl_out), SAVE :: o_SAD_sulfate = ctrl_out((/ 11, 11, 11, 11, 11, 11, 11, 11, 11, 1/), & 1452 'SAD_sulfate', 'SAD WET sulfate aerosols', 'cm2/cm3', (/ ('', i=1, 10) /)) 1453 TYPE(ctrl_out), SAVE :: o_reff_sulfate = ctrl_out((/ 11, 11, 11, 11, 11, 11, 11, 11, 11, 1/), & 1454 'reff_sulfate', 'Effective radius of WET sulfate aerosols', 'cm', (/ ('', i=1, 10) /)) 1455 TYPE(ctrl_out), SAVE :: o_sulfmmr = ctrl_out((/ 11, 11, 11, 11, 11, 11, 11, 11, 11, 1/), & 1456 'sulfMMR', 'Sulfate aerosol concentration (dry mass mixing ratio)', 'kg(H2SO4)/kg(air)', (/ ('', i=1, 10) /)) 1457 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_nd_mode(:) 1458 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_sulfmmr_mode(:) 1444 1459 !--chemistry 1445 1460 TYPE(ctrl_out), SAVE :: o_R2SO4 = ctrl_out((/ 11, 11, 11, 11, 11, 11, 11, 11, 11, 1/), & … … 1551 1566 TYPE(ctrl_out), SAVE :: o_rneb = ctrl_out((/ 2, 5, 10, 10, 10, 10, 11, 11, 11, 11/), & 1552 1567 'rneb', 'Cloud fraction', '-', (/ ('', i=1, 10) /)) 1568 TYPE(ctrl_out), SAVE :: o_cldfraliq = ctrl_out((/ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11/), & 1569 'cldfraliq', 'Liquid fraction of the cloud', '-', (/ ('', i=1, 10) /)) 1570 TYPE(ctrl_out), SAVE :: o_sigma2_icefracturb = ctrl_out((/ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11/), & 1571 'sigma2_icefracturb', 'Variance of the diagnostic supersaturation distribution (icefrac_turb) [-]', '-', (/ ('', i=1, 10) /)) 1572 TYPE(ctrl_out), SAVE :: o_mean_icefracturb = ctrl_out((/ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11/), & 1573 'mean_icefracturb', 'Mean of the diagnostic supersaturation distribution (icefrac_turb) [-]', '-', (/ ('', i=1, 10) /)) 1574 1553 1575 TYPE(ctrl_out), SAVE :: o_rnebjn = ctrl_out((/ 2, 5, 10, 10, 10, 10, 11, 11,11, 11/), & 1554 1576 'rnebjn', 'Cloud fraction in day', '-', (/ ('', i=1, 10) /)) … … 1981 2003 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_dtr_dry(:) 1982 2004 1983 1984 2005 #ifdef ISO 1985 2006 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_xtprecip(:) … … 1991 2012 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_xtoliq(:) 1992 2013 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_xtcond(:) 2014 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_xtrunoff_diag(:) 1993 2015 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_dxtdyn(:) 1994 2016 TYPE(ctrl_out), SAVE, ALLOCATABLE :: o_dxtldyn(:) … … 2088 2110 TYPE(ctrl_out), SAVE :: o_runoff = ctrl_out((/ 1, 1, 10, 1, 10, 10, 11, 11, 11, 11/), & 2089 2111 'runoff', 'Run-off rate land ice', 'kg/m2/s', (/ ('', i=1, 10) /)) 2112 ! SN add runoff_diag 2113 !#ifdef ISO 2114 TYPE(ctrl_out), SAVE :: o_runoff_diag = ctrl_out((/ 1, 1, 10, 1, 10, 10, 11, 11, 11, 11/), & 2115 'runoffland', 'Run-off rate land for bucket', 'kg/m2/s', (/ ('', i=1, 10) /)) 2116 !#endif 2090 2117 TYPE(ctrl_out), SAVE :: o_albslw3 = ctrl_out((/ 1, 1, 1, 1, 10, 10, 11, 11, 11, 11/), & 2091 2118 'albslw3', 'Surface albedo LW3', '-', (/ ('', i=1, 10) /)) -
LMDZ6/branches/cirrus/libf/phylmdiso/physiq_mod.F90
r5055 r5202 39 39 USE ioipsl_getin_p_mod, ONLY : getin_p 40 40 USE indice_sol_mod 41 USE infotrac_phy, ONLY: nqtot, nbtr, nqo, tracers, type_trac 41 USE infotrac_phy, ONLY: nqtot, nbtr, nqo, tracers, type_trac,ivap,iliq,isol 42 42 USE readTracFiles_mod, ONLY: addPhase 43 43 USE strings_mod, ONLY: strIdx … … 93 93 USE phys_output_var_mod, ONLY : cloud_cover_sw, cloud_cover_sw_s2 94 94 95 95 96 !USE cmp_seri_mod 96 97 ! USE add_phys_tend_mod, only : add_pbl_tend, add_phys_tend, diag_phys_tend, prt_enerbil, & … … 117 118 USE chem_rep, ONLY: Init_chem_rep_xjour, d_q_rep, d_ql_rep, d_qi_rep, & 118 119 ptrop, ttrop, ztrop, gravit, itroprep, Z1, Z2, fac, B 120 USE strataer_local_var_mod 121 USE strataer_emiss_mod, ONLY: strataer_emiss_init 119 122 #endif 120 123 #if defined INCA || defined REPROBUS … … 131 134 132 135 #ifdef CPP_StratAer 136 USE phys_local_var_mod, ONLY: d_q_emiss 133 137 USE strataer_local_var_mod 134 138 USE strataer_nuc_mod, ONLY: strataer_nuc_init 135 139 USE strataer_emiss_mod, ONLY: strataer_emiss_init 136 140 #endif 137 138 141 139 142 USE lmdz_xios, ONLY: xios_update_calendar, xios_context_finalize … … 153 156 & modif_ratqs,essai_convergence,iso_init,ridicule_rain,tnat, & 154 157 & ridicule,ridicule_snow 155 USE isotopes_routines_mod, ONLY: iso_tritium 158 USE isotopes_routines_mod, ONLY: iso_tritium,dispatch,together 156 159 #ifdef ISOVERIF 157 160 USE isotopes_verif_mod, ONLY: errmax,errmaxrel, & … … 188 191 !!!!!!!!!!!!!!!!!! END "USE" for CPP keys !!!!!!!!!!!!!!!!!!!!!! 189 192 193 USE physiqex_mod, ONLY : physiqex 190 194 USE phys_local_var_mod, ONLY: phys_local_var_init, phys_local_var_end, & 191 195 ! [Variables internes non sauvegardees de la physique] … … 193 197 t_seri,q_seri,ql_seri,qs_seri,qbs_seri, & 194 198 u_seri,v_seri,cf_seri,rvc_seri,tr_seri, & 199 rhcl, & 200 qx_seri, & ! CR 195 201 rhcl, & 196 202 ! Dynamic tendencies (diagnostics) … … 209 215 ! 210 216 d_t_eva,d_q_eva,d_ql_eva,d_qi_eva, & 217 d_qx_eva, & 211 218 d_t_lsc,d_q_lsc,d_ql_lsc,d_qi_lsc, & 212 219 d_t_lscst,d_q_lscst, & … … 219 226 d_ts, & 220 227 ! 221 d_t_bs ,d_q_bs,d_qbs_bs, &228 d_t_bsss,d_q_bsss,d_qbs_bsss, & 222 229 ! 223 230 ! d_t_oli,d_u_oli,d_v_oli, & … … 247 254 toplwai_aero,sollwai_aero, & 248 255 toplwad0_aero,sollwad0_aero, & 256 !pour Ecrad 257 topswad_aero_s2, solswad_aero_s2, & 258 topswai_aero_s2, solswai_aero_s2, & 259 topswad0_aero_s2, solswad0_aero_s2, & 260 topsw_aero_s2, topsw0_aero_s2, & 261 solsw_aero_s2, solsw0_aero_s2, & 262 topswcf_aero_s2, solswcf_aero_s2, & 263 !LW diagnostics 264 toplwad_aero_s2, sollwad_aero_s2, & 265 toplwai_aero_s2, sollwai_aero_s2, & 266 toplwad0_aero_s2, sollwad0_aero_s2, & 249 267 ! 250 268 topsw_aero,solsw_aero, & … … 265 283 toplwai_aerop, sollwai_aerop, & 266 284 toplwad0_aerop, sollwad0_aerop, & 285 !pour Ecrad 286 topswad_aero_s2, solswad_aero_s2, & 287 topswai_aero_s2, solswai_aero_s2, & 288 topswad0_aero_s2, solswad0_aero_s2, & 289 topsw_aero_s2, topsw0_aero_s2, & 290 solsw_aero_s2, solsw0_aero_s2, & 291 topswcf_aero_s2, solswcf_aero_s2, & 292 !LW diagnostics 293 toplwad_aero_s2, sollwad_aero_s2, & 294 toplwai_aero_s2, sollwai_aero_s2, & 295 toplwad0_aero_s2, sollwad0_aero_s2, & 267 296 ! 268 297 ptstar, pt0, slp, & … … 346 375 ! 347 376 rneblsvol, & 348 pfraclr, pfracld,&349 distcltop, temp_cltop,&377 pfraclr, pfracld, cldfraliq, sigma2_icefracturb, mean_icefracturb, & 378 distcltop, temp_cltop, & 350 379 !-- LSCP - condensation and ice supersaturation variables 351 380 qsub, qissr, qcld, subfra, issrfra, gamma_cond, ratio_qi_qtot, & … … 384 413 385 414 #ifdef ISO 386 USE phys_local_var_mod, ONLY: xt_seri,xtl_seri,xts_seri, &415 USE phys_local_var_mod, ONLY: xt_seri,xtl_seri,xts_seri,xtbs_seri, & 387 416 d_xt_eva,d_xtl_eva,d_xti_eva, & 388 d_xt_dyn,d_xtl_dyn,d_xts_dyn, 417 d_xt_dyn,d_xtl_dyn,d_xts_dyn,d_xtbs_dyn, & 389 418 d_xt_con, d_xt_wake, & 390 419 d_xt_ajsb, d_xt_ajs, & … … 412 441 USE phys_output_var_mod, ONLY: scdnc, cldncl, reffclwtop, lcc, reffclws, & 413 442 reffclwc, cldnvi, lcc3d, lcc3dcon, lcc3dstra, icc3dcon, icc3dstra 443 USE output_physiqex_mod, ONLY: output_physiqex 414 444 415 445 … … 556 586 ! 557 587 ! indices de traceurs eau vapeur, liquide, glace, fraction nuageuse LS (optional), blowing snow (optional) 558 INTEGER,SAVE :: ivap, iliq, isol, ibs, icf, irvc 559 !$OMP THREADPRIVATE(ivap, iliq, isol, ibs, icf, irvc) 560 ! 588 ! INTEGER,SAVE :: ivap, iliq, isol, irneb, ibs 589 !!$OMP THREADPRIVATE(ivap, iliq, isol, irneb, ibs) 590 ! Camille Risi 25 juillet 2023: ivap,iliq,isol deja definis dans infotrac_phy. 591 ! Et ils sont utiles ailleurs que dans physiq_mod (ex: 592 ! reevap -> je commente les 2 lignes au dessus et je laisse la definition 593 ! plutot dans infotrac_phy 594 INTEGER,SAVE :: irneb, ibs, icf,irvc 595 !$OMP THREADPRIVATE(irneb, ibs, icf,irvc) 596 ! 561 597 ! 562 598 ! Variables argument: … … 812 848 real therm_tke_max0(klon) ! TKE dans les thermiques au LCL 813 849 real env_tke_max0(klon) ! TKE dans l'environnement au LCL 850 INTEGER, SAVE :: iflag_thermcell_tke ! transtport TKE by thermals 851 !$OMP THREADPRIVATE(iflag_thermcell_tke) 814 852 815 853 !JLD !---D\'eclenchement stochastique … … 900 938 EXTERNAL ajsec ! ajustement sec 901 939 EXTERNAL conlmd ! convection (schema LMD) 902 !KE43903 940 EXTERNAL conema3 ! convect4.3 904 !AA905 ! JBM (3/14) fisrtilp_tr not loaded906 ! EXTERNAL fisrtilp_tr ! schema de condensation a grande echelle (pluie)907 ! ! stockage des coefficients necessaires au908 ! ! lessivage OFF-LINE et ON-LINE909 941 EXTERNAL hgardfou ! verifier les temperatures 910 942 EXTERNAL nuage ! calculer les proprietes radiatives … … 960 992 REAL conv_t(klon,klev) ! convergence de la temperature(K/s) 961 993 ! 962 #ifdef INCA963 REAL zxsnow_dummy(klon)964 #endif965 994 REAL zsav_tsol(klon) 966 995 ! … … 1068 1097 !$OMP THREADPRIVATE(ok_bug_split_th) 1069 1098 1099 ! Logical switch to a bug : modifying directly wake_deltat by adding 1100 ! the (w) dry adjustment tendency to wake_deltat 1101 LOGICAL, SAVE :: ok_bug_ajs_cv = .TRUE. 1102 !$OMP THREADPRIVATE(ok_bug_ajs_cv) 1070 1103 ! 1071 1104 !******************************************************** … … 1205 1238 REAL, DIMENSION(klon,klev) :: mass_solu_aero_pi 1206 1239 ! - " - (pre-industrial value) 1240 REAL, DIMENSION(klon,klev,naero_tot) :: m_allaer 1207 1241 1208 1242 ! Parameters … … 1271 1305 ! Declarations pour Simulateur COSP 1272 1306 !============================================================ 1307 ! AI 10-22 1308 #ifdef CPP_COSP 1309 include "ini_COSP.h" 1310 #endif 1311 #ifdef CPP_COSPV2 1312 include "ini_COSP.h" 1313 #endif 1273 1314 real :: mr_ozone(klon,klev), phicosp(klon,klev) 1274 1315 … … 1346 1387 1347 1388 REAL, dimension(klon,klev) :: t_env,q_env 1389 #ifdef ISO 1390 real, dimension(ntraciso,klon,klev) :: xt_env 1391 #endif 1348 1392 1349 1393 REAL, dimension(klon) :: pr_et … … 1356 1400 !AI namelist pour gerer le double appel de Ecrad 1357 1401 CHARACTER(len=512) :: namelist_ecrad_file 1402 1403 !======================================================================! 1404 ! Bifurcation vers un nouveau moniteur physique pour experimenter ! 1405 ! des solutions et préparer le couplage avec la physique de MesoNH ! 1406 ! 14 mai 2023 ! 1407 !======================================================================! 1408 if (debut) then ! 1409 iflag_physiq=0 1410 call getin_p('iflag_physiq', iflag_physiq) ! 1411 endif ! 1412 if ( iflag_physiq == 2 ) then 1413 #ifdef ISO 1414 abort_message='isotopes pas encore dans physiqex' 1415 CALL abort_physic(modname,abort_message,1) 1416 #endif 1417 call physiqex (nlon,nlev, & ! 1418 debut,lafin,pdtphys_, & ! 1419 paprs,pplay,pphi,pphis,presnivs, & ! 1420 u,v,rot,t,qx, & ! 1421 flxmass_w, & ! 1422 d_u, d_v, d_t, d_qx, d_ps) ! 1423 return ! 1424 endif ! 1425 !======================================================================! 1426 1358 1427 1359 1428 pi = 4. * ATAN(1.) … … 1372 1441 phys_tstep=NINT(pdtphys) 1373 1442 IF (.NOT. using_xios) missing_val=nf90_fill_real 1374 #ifdef CPP_XIOS 1375 ! switch to XIOS LMDZ physics context 1376 IF (.NOT. debut .AND. is_omp_master) THEN 1377 CALL wxios_set_context() 1378 CALL xios_update_calendar(itap+1) 1443 1444 IF (using_xios) THEN 1445 ! switch to XIOS LMDZ physics context 1446 IF (.NOT. debut .AND. is_omp_master) THEN 1447 CALL wxios_set_context() 1448 CALL xios_update_calendar(itap+1) 1449 ENDIF 1379 1450 ENDIF 1380 #endif1381 1451 1382 1452 !====================================================================== … … 1384 1454 ! Utilise notamment en 1D mais peut etre active egalement en 3D 1385 1455 ! en imposant la valeur de igout. 1386 !====================================================================== d1456 !====================================================================== 1387 1457 IF (prt_level.ge.1) THEN 1388 1458 igout=klon/2+1/klon … … 1441 1511 read_climoz, & 1442 1512 alp_offset) 1513 CALL init_etat0_limit_unstruct 1514 IF (.NOT. create_etat0_limit) CALL init_limit_read(days_elapsed) 1443 1515 CALL phys_state_var_init(read_climoz) 1444 1516 CALL phys_output_var_init 1445 1517 IF (read_climoz>=1 .AND. create_etat0_limit .AND. grid_type==unstructured) & 1446 1518 CALL regr_horiz_time_climoz(read_climoz,ok_daily_climoz) 1519 1520 #ifdef REPROBUS 1521 CALL strataer_init 1522 CALL strataer_emiss_init 1523 #endif 1447 1524 1448 1525 #ifdef CPP_StratAer … … 1488 1565 1489 1566 IF (ok_bs) THEN 1567 #ifdef ISO 1490 1568 abort_message='blowing snow cannot be activated with water isotopes yet' 1491 1569 CALL abort_physic(modname,abort_message, 1) … … 1497 1575 ENDIF 1498 1576 ENDIF 1577 1499 1578 Ncvpaseq1 = 0 1500 1579 dnwd0=0.0 … … 1538 1617 tau_gl=86400.*tau_gl 1539 1618 WRITE(lunout,*) 'debut physiq_mod tau_gl=',tau_gl 1619 iflag_thermcell_tke=0 1620 call getin_p('iflag_thermcell_tke', iflag_thermcell_tke) ! 1540 1621 1541 1622 CALL getin_p('iflag_alp_wk_cond', iflag_alp_wk_cond) … … 1560 1641 CALL getin_p('ok_bug_cv_trac',ok_bug_cv_trac) 1561 1642 CALL getin_p('ok_bug_split_th',ok_bug_split_th) 1643 CALL getin_p('ok_bug_ajs_cv',ok_bug_ajs_cv) 1562 1644 fl_ebil = 0 ! by default, conservation diagnostics are desactivated 1563 1645 CALL getin_p('fl_ebil',fl_ebil) … … 1596 1678 CALL infocfields_init 1597 1679 1680 !AI 08 2023 1598 1681 #ifdef CPP_ECRAD 1599 1682 ok_3Deffect=.false. … … 1875 1958 IF (.NOT. create_etat0_limit) CALL init_readaerosolstrato(flag_aerosol_strat) !! initialise aero strato from file for XIOS interpolation (unstructured_grid) 1876 1959 1960 ! A.I : Initialisations pour le 1er passage a Cosp 1961 if (ok_cosp) then 1962 1877 1963 #ifdef CPP_COSP 1878 IF (ok_cosp) THEN 1879 ! DO k = 1, klev 1880 ! DO i = 1, klon 1881 ! phicosp(i,k) = pphi(i,k) + pphis(i) 1882 ! ENDDO 1883 ! ENDDO 1964 CALL ini_COSP(ref_liq_cosp0,ref_ice_cosp0,pctsrf_cosp0,zu10m_cosp0,zv10m_cosp0, & 1965 zxtsol_cosp0,zx_rh_cosp0,cldfra_cosp0,rnebcon_cosp0,flwc_cosp0, & 1966 fiwc_cosp0,prfl_cosp0,psfl_cosp0,pmflxr_cosp0,pmflxs_cosp0, & 1967 mr_ozone_cosp0,cldtau_cosp0,cldemi_cosp0,JrNt_cosp0) 1968 1884 1969 CALL phys_cosp(itap,phys_tstep,freq_cosp, & 1885 1970 ok_mensuelCOSP,ok_journeCOSP,ok_hfCOSP, & 1886 1971 ecrit_mth,ecrit_day,ecrit_hf, ok_all_xml, missing_val, & 1887 1972 klon,klev,longitude_deg,latitude_deg,presnivs,overlap, & 1888 JrNt,ref_liq,ref_ice, & 1889 pctsrf(:,is_ter)+pctsrf(:,is_lic), & 1890 zu10m,zv10m,pphis, & 1891 zphi,paprs(:,1:klev),pplay,zxtsol,t_seri, & 1892 qx(:,:,ivap),zx_rh,cldfra,rnebcon,flwc,fiwc, & 1893 prfl(:,1:klev),psfl(:,1:klev), & 1894 pmflxr(:,1:klev),pmflxs(:,1:klev), & 1895 mr_ozone,cldtau, cldemi) 1896 ENDIF 1897 #endif 1898 1899 #ifdef CPP_COSP2 1900 IF (ok_cosp) THEN 1901 ! DO k = 1, klev 1902 ! DO i = 1, klon 1903 ! phicosp(i,k) = pphi(i,k) + pphis(i) 1904 ! ENDDO 1905 ! ENDDO 1906 CALL phys_cosp2(itap,phys_tstep,freq_cosp, & 1907 ok_mensuelCOSP,ok_journeCOSP,ok_hfCOSP, & 1908 ecrit_mth,ecrit_day,ecrit_hf, ok_all_xml, missing_val, & 1909 klon,klev,longitude_deg,latitude_deg,presnivs,overlap, & 1910 JrNt,ref_liq,ref_ice, & 1911 pctsrf(:,is_ter)+pctsrf(:,is_lic), & 1912 zu10m,zv10m,pphis, & 1913 zphi,paprs(:,1:klev),pplay,zxtsol,t_seri, & 1914 qx(:,:,ivap),zx_rh,cldfra,rnebcon,flwc,fiwc, & 1915 prfl(:,1:klev),psfl(:,1:klev), & 1916 pmflxr(:,1:klev),pmflxs(:,1:klev), & 1917 mr_ozone,cldtau, cldemi) 1918 ENDIF 1973 JrNt_cosp0,ref_liq_cosp0,ref_ice_cosp0, & 1974 pctsrf_cosp0, & 1975 zu10m_cosp0,zv10m_cosp0,pphis, & 1976 pphi,paprs(:,1:klev),pplay,zxtsol_cosp0,t, & 1977 qx(:,:,ivap),zx_rh_cosp0,cldfra_cosp0,rnebcon_cosp0,flwc_cosp0,fiwc_cosp0, & 1978 prfl_cosp0(:,1:klev),psfl_cosp0(:,1:klev), & 1979 pmflxr_cosp0(:,1:klev),pmflxs_cosp0(:,1:klev), & 1980 mr_ozone_cosp0,cldtau_cosp0, cldemi_cosp0) 1919 1981 #endif 1920 1982 1921 1983 #ifdef CPP_COSPV2 1922 IF (ok_cosp) THEN 1923 DO k = 1, klev 1924 DO i = 1, klon 1925 phicosp(i,k) = pphi(i,k) + pphis(i) 1926 ENDDO 1927 ENDDO 1984 CALL ini_COSP(ref_liq_cosp0,ref_ice_cosp0,pctsrf_cosp0,zu10m_cosp0,zv10m_cosp0, & 1985 zxtsol_cosp0,zx_rh_cosp0,cldfra_cosp0,rnebcon_cosp0,flwc_cosp0, & 1986 fiwc_cosp0,prfl_cosp0,psfl_cosp0,pmflxr_cosp0,pmflxs_cosp0, & 1987 mr_ozone_cosp0,cldtau_cosp0,cldemi_cosp0,JrNt_cosp0) 1988 1928 1989 CALL lmdz_cosp_interface(itap,phys_tstep,freq_cosp, & 1929 1990 ok_mensuelCOSP,ok_journeCOSP,ok_hfCOSP, & 1930 1991 ecrit_mth,ecrit_day,ecrit_hf, ok_all_xml, missing_val, & 1931 1992 klon,klev,longitude_deg,latitude_deg,presnivs,overlap, & 1932 JrNt,ref_liq,ref_ice, & 1933 pctsrf(:,is_ter)+pctsrf(:,is_lic), & 1934 zu10m,zv10m,pphis, & 1935 phicosp,paprs(:,1:klev),pplay,zxtsol,t_seri, & 1936 qx(:,:,ivap),zx_rh,cldfra,rnebcon,flwc,fiwc, & 1937 prfl(:,1:klev),psfl(:,1:klev), & 1938 pmflxr(:,1:klev),pmflxs(:,1:klev), & 1939 mr_ozone,cldtau, cldemi) 1940 ENDIF 1941 #endif 1993 JrNt_cosp0,ref_liq_cosp0,ref_ice_cosp0, & 1994 pctsrf_cosp0, & 1995 zu10m_cosp0,zv10m_cosp0,pphis, & 1996 pphi,paprs(:,1:klev),pplay,zxtsol_cosp0,t, & 1997 qx(:,:,ivap),zx_rh_cosp0,cldfra_cosp0,rnebcon_cosp0,flwc_cosp0,fiwc_cosp0, & 1998 prfl_cosp0(:,1:klev),psfl_cosp0(:,1:klev), & 1999 pmflxr_cosp0(:,1:klev),pmflxs_cosp0(:,1:klev), & 2000 mr_ozone_cosp0,cldtau_cosp0, cldemi_cosp0) 2001 #endif 2002 2003 endif !ok_cosp 1942 2004 1943 2005 ! … … 2014 2076 2015 2077 2016 #ifdef CPP_XIOS 2017 IF (is_omp_master) CALL xios_update_calendar(1) 2018 #endif 2078 IF (using_xios) THEN 2079 IF (is_omp_master) CALL xios_update_calendar(1) 2080 ENDIF 2081 2019 2082 IF(read_climoz>=1 .AND. create_etat0_limit) CALL regr_horiz_time_climoz(read_climoz,ok_daily_climoz) 2020 2083 CALL create_etat0_limit_unstruct … … 2213 2276 ENDIF 2214 2277 2215 IF (using_xios) THEN 2216 ! Need to put this initialisation after phyetat0 as in the coupled model the XIOS context is only 2217 ! initialised at that moment 2218 ! Get "missing_val" value from XML files (from temperature variable) 2219 IF (is_omp_master) CALL xios_get_field_attr("temp",default_value=missing_val) 2220 CALL bcast_omp(missing_val) 2221 2278 IF (using_xios) THEN 2279 ! Need to put this initialisation after phyetat0 as in the coupled model the XIOS context is only 2280 ! initialised at that moment 2281 ! Get "missing_val" value from XML files (from temperature variable) 2282 IF (is_omp_master) CALL xios_get_field_attr("temp",default_value=missing_val) 2283 CALL bcast_omp(missing_val) 2222 2284 ! 2223 2285 ! Now we activate some double radiation call flags only if some 2224 2286 ! diagnostics are requested, otherwise there is no point in doing this 2225 IF (is_master) THEN2226 !--setting up swaero_diag to TRUE in XIOS case2227 IF (xios_field_is_active("topswad").OR.xios_field_is_active("topswad0").OR. &2228 xios_field_is_active("solswad").OR.xios_field_is_active("solswad0").OR. &2229 xios_field_is_active("topswai").OR.xios_field_is_active("solswai").OR. &2230 (iflag_rrtm==1.AND.(xios_field_is_active("toplwad").OR.xios_field_is_active("toplwad0").OR. &2231 xios_field_is_active("sollwad").OR.xios_field_is_active("sollwad0")))) &2232 !!!--for now these fields are not in the XML files so they are omitted2233 !!! xios_field_is_active("toplwai").OR.xios_field_is_active("sollwai") !))) &2234 swaero_diag=.TRUE.2287 IF (is_master) THEN 2288 !--setting up swaero_diag to TRUE in XIOS case 2289 IF (xios_field_is_active("topswad").OR.xios_field_is_active("topswad0").OR. & 2290 xios_field_is_active("solswad").OR.xios_field_is_active("solswad0").OR. & 2291 xios_field_is_active("topswai").OR.xios_field_is_active("solswai").OR. & 2292 (iflag_rrtm==1.AND.(xios_field_is_active("toplwad").OR.xios_field_is_active("toplwad0").OR. & 2293 xios_field_is_active("sollwad").OR.xios_field_is_active("sollwad0")))) & 2294 !!!--for now these fields are not in the XML files so they are omitted 2295 !!! xios_field_is_active("toplwai").OR.xios_field_is_active("sollwai") !))) & 2296 swaero_diag=.TRUE. 2235 2297 2236 !--setting up swaerofree_diag to TRUE in XIOS case2237 IF (xios_field_is_active("SWdnSFCcleanclr").OR.xios_field_is_active("SWupSFCcleanclr").OR. &2238 xios_field_is_active("SWupTOAcleanclr").OR.xios_field_is_active("rsucsaf").OR. &2239 xios_field_is_active("rsdcsaf") .OR. xios_field_is_active("LWdnSFCcleanclr").OR. &2240 xios_field_is_active("LWupTOAcleanclr")) &2241 swaerofree_diag=.TRUE.2298 !--setting up swaerofree_diag to TRUE in XIOS case 2299 IF (xios_field_is_active("SWdnSFCcleanclr").OR.xios_field_is_active("SWupSFCcleanclr").OR. & 2300 xios_field_is_active("SWupTOAcleanclr").OR.xios_field_is_active("rsucsaf").OR. & 2301 xios_field_is_active("rsdcsaf") .OR. xios_field_is_active("LWdnSFCcleanclr").OR. & 2302 xios_field_is_active("LWupTOAcleanclr")) & 2303 swaerofree_diag=.TRUE. 2242 2304 2243 !--setting up dryaod_diag to TRUE in XIOS case 2244 DO naero = 1, naero_tot-1 2245 IF (xios_field_is_active("dryod550_"//name_aero_tau(naero))) dryaod_diag=.TRUE. 2246 ENDDO 2247 ! 2248 !--setting up ok_4xCO2atm to TRUE in XIOS case 2249 IF (xios_field_is_active("rsut4co2").OR.xios_field_is_active("rlut4co2").OR. & 2250 xios_field_is_active("rsutcs4co2").OR.xios_field_is_active("rlutcs4co2").OR. & 2251 xios_field_is_active("rsu4co2").OR.xios_field_is_active("rsucs4co2").OR. & 2252 xios_field_is_active("rsd4co2").OR.xios_field_is_active("rsdcs4co2").OR. & 2253 xios_field_is_active("rlu4co2").OR.xios_field_is_active("rlucs4co2").OR. & 2254 xios_field_is_active("rld4co2").OR.xios_field_is_active("rldcs4co2")) & 2255 ok_4xCO2atm=.TRUE. 2256 ENDIF 2257 !$OMP BARRIER 2258 CALL bcast(swaero_diag) 2259 CALL bcast(swaerofree_diag) 2260 CALL bcast(dryaod_diag) 2261 CALL bcast(ok_4xCO2atm) 2262 2263 ENDIF !using_xios 2264 2305 !--setting up dryaod_diag to TRUE in XIOS case 2306 DO naero = 1, naero_tot-1 2307 IF (xios_field_is_active("dryod550_"//name_aero_tau(naero))) dryaod_diag=.TRUE. 2308 ENDDO 2309 ! 2310 !--setting up ok_4xCO2atm to TRUE in XIOS case 2311 IF (xios_field_is_active("rsut4co2").OR.xios_field_is_active("rlut4co2").OR. & 2312 xios_field_is_active("rsutcs4co2").OR.xios_field_is_active("rlutcs4co2").OR. & 2313 xios_field_is_active("rsu4co2").OR.xios_field_is_active("rsucs4co2").OR. & 2314 xios_field_is_active("rsd4co2").OR.xios_field_is_active("rsdcs4co2").OR. & 2315 xios_field_is_active("rlu4co2").OR.xios_field_is_active("rlucs4co2").OR. & 2316 xios_field_is_active("rld4co2").OR.xios_field_is_active("rldcs4co2")) & 2317 ok_4xCO2atm=.TRUE. 2318 ENDIF 2319 !$OMP BARRIER 2320 CALL bcast(swaero_diag) 2321 CALL bcast(swaerofree_diag) 2322 CALL bcast(dryaod_diag) 2323 CALL bcast(ok_4xCO2atm) 2324 ENDIF !using_xios 2265 2325 ! 2266 2326 CALL printflag( tabcntr0,radpas,ok_journe, & … … 2549 2609 u_seri(i,k) = u(i,k) 2550 2610 v_seri(i,k) = v(i,k) 2611 qx_seri(i,k,:) = qx(i,k,:) 2551 2612 q_seri(i,k) = qx(i,k,ivap) 2552 2613 ql_seri(i,k) = qx(i,k,iliq) … … 2590 2651 DO k = 1, klev 2591 2652 DO i = 1, klon 2653 xtbs_seri(ixt,i,k) = 0. 2592 2654 xt_seri(ixt,i,k) = qx(i,k,iqIsoPha(ixt,ivap)) 2593 2655 xtl_seri(ixt,i,k) = qx(i,k,iqIsoPha(ixt,iliq)) … … 2610 2672 qql1(:)=0.0 2611 2673 DO k = 1, klev 2612 qql1(:)=qql1(:)+(q_seri(:,k)+ql_seri(:,k)+qs_seri(:,k)+qbs_seri(:,k))*zmasse(:,k) 2674 qql1(:)=qql1(:)+(q_seri(:,k)+ql_seri(:,k))*zmasse(:,k) 2675 IF (nqo >= 3) THEN 2676 qql1(:)=qql1(:)+qs_seri(:,k)*zmasse(:,k) 2677 ENDIF 2678 IF (ok_bs) THEN 2679 qql1(:)=qql1(:)+qbs_seri(:,k)*zmasse(:,k) 2680 ENDIF 2613 2681 ENDDO 2614 2682 #ifdef ISO 2615 #ifdef ISOVERIF 2616 write(*,*) 'physiq tmp 1913' 2617 #endif 2618 do ixt=1,ntraciso 2683 DO ixt=1,ntraciso 2619 2684 xtql1(ixt,:)=0.0 2620 2685 DO k = 1, klev 2621 xtql1(ixt,:)=xtql1(ixt,:)+(xt_seri(ixt,:,k)+xtl_seri(ixt,:,k)+xts_seri(ixt,:,k))*zmasse(:,k) 2622 ENDDO 2623 enddo !do ixt=1,ntraciso 2686 xtql1(ixt,:)=xtql1(ixt,:)+(xt_seri(ixt,:,k)+xtl_seri(ixt,:,k))*zmasse(:,k) 2687 IF (nqo >= 3) THEN 2688 xtql1(ixt,:)=xtql1(ixt,:)+xts_seri(ixt,:,k)*zmasse(:,k) 2689 ENDIF 2690 IF (ok_bs) THEN 2691 xtql1(ixt,:)=xtql1(ixt,:)+xtbs_seri(ixt,:,k)*zmasse(:,k) 2692 ENDIF 2693 ENDDO !DO k = 1, klev 2694 ENDDO !DO ixt=1,ntraciso 2624 2695 #endif 2625 2696 ENDIF … … 2633 2704 IF(.NOT.tracers(iq)%isInPhysics) CYCLE 2634 2705 itr = itr+1 2635 !#ifdef ISOVERIF 2636 ! write(*,*) 'physiq 1973: itr,iq=',itr,iq 2637 ! write(*,*) 'qx(1,1,iq)=',qx(1,1,iq) 2638 !#endif 2639 DO k = 1, klev 2706 DO k = 1, klev 2640 2707 DO i = 1, klon 2641 2708 tr_seri(i,k,itr) = qx(i,k,iq) … … 2752 2819 d_xts_dyn(ixt,i,k) = & 2753 2820 & (xts_seri(ixt,i,k)-xts_ancien(ixt,i,k))/phys_tstep 2821 d_xtbs_dyn(ixt,i,k) = & 2822 & (xtbs_seri(ixt,i,k)-xtbs_ancien(ixt,i,k))/phys_tstep 2754 2823 enddo ! do ixt=1,ntraciso 2755 2824 ENDDO … … 2765 2834 call iso_verif_noNaN(d_xtl_dyn(ixt,i,k),'physiq 2220d') 2766 2835 call iso_verif_noNaN(d_xts_dyn(ixt,i,k),'physiq 2220e') 2836 call iso_verif_noNaN(d_xtbs_dyn(ixt,i,k),'physiq 2220f') 2767 2837 enddo ! do ixt=1,ntraciso 2768 2838 enddo … … 2848 2918 ! !! RomP <<< 2849 2919 ancien_ok = .TRUE. 2920 #ifdef ISO 2921 d_xtbs_dyn(:,:,:)=0.0 2922 #endif 2850 2923 ENDIF 2851 2924 ! … … 2986 3059 ! Re-evaporer l'eau liquide nuageuse 2987 3060 ! 2988 CALL reevap (klon,klev,iflag_ice_thermo,t_seri,q_seri,ql_seri,qs_seri, & 2989 & d_t_eva,d_q_eva,d_ql_eva,d_qi_eva & 2990 #ifdef ISO 2991 ,xt_seri,xtl_seri,xts_seri,d_xt_eva,d_xtl_eva,d_xti_eva & 2992 #endif 2993 & ) 3061 CALL reevap (klon,klev,iflag_ice_thermo,t_seri,qx_seri, & 3062 & d_t_eva,d_qx_eva) 3063 3064 call dispatch(klon,klev,qx_seri,q_seri,xt_seri,ql_seri,xtl_seri,qs_seri,xts_seri) 3065 call dispatch(klon,klev,d_qx_eva,d_q_eva,d_xt_eva,d_ql_eva,d_xtl_eva,d_qi_eva,d_xti_eva) 3066 3067 3068 #ifdef ISO 3069 #ifdef ISOVERIF 3070 DO k = 1, klev 3071 DO i = 1, klon 3072 do ixt=1,ntraciso 3073 call iso_verif_noNaN(xt_seri(ixt,i,k), & 3074 & 'reevap 2417: apres evap tot') 3075 enddo 3076 if (iso_eau.gt.0) then 3077 call iso_verif_egalite_choix( & 3078 & xt_seri(iso_eau,i,k),q_seri(i,k), & 3079 & 'reevap 1891, après réévap totale',errmax,errmaxrel) 3080 call iso_verif_egalite_choix( & 3081 & xtl_seri(iso_eau,i,k),ql_seri(i,k), & 3082 & 'reevap 2209, après réévap totale',errmax,errmaxrel) 3083 call iso_verif_egalite_choix( & 3084 & xts_seri(iso_eau,i,k),qs_seri(i,k), & 3085 & 'reevap 2209b, après réévap totale',errmax,errmaxrel) 3086 endif !if (iso_eau.gt.0) then 3087 3088 if ((iso_HDO.gt.0).and.(iso_O18.gt.0)) then 3089 if (q_seri(i,k).gt.ridicule) then 3090 if (iso_verif_o18_aberrant_nostop( & 3091 & xt_seri(iso_HDO,i,k)/q_seri(i,k), & 3092 & xt_seri(iso_O18,i,k)/q_seri(i,k), & 3093 & 'reevap 2408: apres reevap totale').eq.1) then 3094 write(*,*) 'i,k,q_seri(i,k)=',i,k,q_seri(i,k) 3095 stop 3096 endif ! if (iso_verif_o18_aberrant_nostop 3097 endif !if (q_seri(i,k).gt.errmax) then 3098 endif !if ((iso_HDO.gt.0).and.(iso_O18.gt.0)) then 3099 #ifdef ISOTRAC 3100 call iso_verif_traceur(xt_seri(1,i,k), & 3101 & 'reevap 2165c') 3102 call iso_verif_traceur_pbidouille(xt_seri(1,i,k), & 3103 & 'reevap 2165d') 3104 #endif 3105 ENDDO 3106 ENDDO 3107 #endif 3108 #endif 3109 2994 3110 2995 3111 CALL add_phys_tend & … … 3123 3239 ! Calcul de l'humidite de saturation au niveau du sol 3124 3240 3241 ! Tests Fredho, instensibilite au pas de temps ------------------------------- 3242 ! A detruire en 2024 une fois les tests documentes et les choix faits ! 3243 ! Conservation des variables avant l'appel à l a diffusion pour les tehrmic ! 3244 if (iflag_thermals_tenv / 10 == 1 ) then ! 3245 do k=1,klev ! 3246 do i=1,klon ! 3247 t_env(i,k)=t_seri(i,k) ! 3248 q_env(i,k)=q_seri(i,k) 3249 #ifdef ISO 3250 do ixt=1,ntraciso 3251 xt_env(ixt,i,k)=xt_seri(ixt,i,k) 3252 enddo 3253 #endif 3254 enddo ! 3255 enddo ! 3256 else if (iflag_thermals_tenv / 10 == 2 ) then ! 3257 do k=1,klev ! 3258 do i=1,klon ! 3259 t_env(i,k)=t_seri(i,k) ! 3260 enddo ! 3261 enddo ! 3262 endif ! 3263 ! Tests Fredho, instensibilite au pas de temps ------------------------------- 3125 3264 3126 3265 … … 3311 3450 d_deltaq_vdf(:,:) = d_q_vdf_w(:,:)-d_q_vdf_x(:,:) 3312 3451 CALL add_wake_tend & 3313 (d_deltat_vdf, d_deltaq_vdf, dsig0, d dens0, ddens0, wkoccur1, 'vdf', abortphy &3452 (d_deltat_vdf, d_deltaq_vdf, dsig0, dsig0, ddens0, ddens0, wkoccur1, 'vdf', abortphy & 3314 3453 #ifdef ISO 3315 3454 ,d_deltaxt_vdf & … … 3344 3483 & ) 3345 3484 ENDIF 3346 #ifdef ISOVERIF3347 write(*,*) 'physiq tmp 2736'3348 #endif3349 3350 3485 CALL prt_enerbil('vdf',itap) 3486 3351 3487 !-------------------------------------------------------------------- 3352 3488 … … 3403 3539 ! Blowing snow sublimation and sedimentation 3404 3540 3405 d_t_bs (:,:)=0.3406 d_q_bs (:,:)=0.3407 d_qbs_bs (:,:)=0.3541 d_t_bsss(:,:)=0. 3542 d_q_bsss(:,:)=0. 3543 d_qbs_bsss(:,:)=0. 3408 3544 bsfl(:,:)=0. 3409 3545 bs_fall(:)=0. … … 3411 3547 3412 3548 CALL call_blowing_snow_sublim_sedim(klon,klev,phys_tstep,t_seri,q_seri,qbs_seri,pplay,paprs, & 3413 d_t_bs ,d_q_bs,d_qbs_bs,bsfl,bs_fall)3549 d_t_bsss,d_q_bsss,d_qbs_bsss,bsfl,bs_fall) 3414 3550 3415 3551 CALL add_phys_tend & 3416 (du0,dv0,d_t_bs ,d_q_bs,dql0,dqi0,d_qbs_bs,paprs,&3552 (du0,dv0,d_t_bsss,d_q_bsss,dql0,dqi0,d_qbs_bsss,paprs,& 3417 3553 'bs',abortphy,flag_inhib_tend,itap,0 & 3418 3554 #ifdef ISO … … 3713 3849 ENDDO 3714 3850 ENDDO 3715 IF (iflag_adjwk == 2 ) THEN3851 IF (iflag_adjwk == 2 .AND. OK_bug_ajs_cv) THEN 3716 3852 CALL add_wake_tend & 3717 (d_deltat_ajs_cv, d_deltaq_ajs_cv, dsig0, d dens0, ddens0, wkoccur1, 'ajs_cv', abortphy &3853 (d_deltat_ajs_cv, d_deltaq_ajs_cv, dsig0, dsig0, ddens0, ddens0, wkoccur1, 'ajs_cv', abortphy & 3718 3854 #ifdef ISO 3719 3855 ,d_deltaxt_ajs_cv & 3720 3856 #endif 3721 3857 ) 3722 ENDIF ! (iflag_adjwk == 2 )3858 ENDIF ! (iflag_adjwk == 2 .AND. OK_bug_ajs_cv) 3723 3859 ENDIF ! (iflag_adjwk >= 1) 3724 3860 ENDIF ! (iflag_wake>=1) … … 4424 4560 ! ==== 4425 4561 IF (prt_level>9) WRITE(lunout,*)'pas de convection seche' 4562 WRITE(lunout,*) 'WARNING : running without dry convection. Somme intermediate variables are not properly defined in physiq_mod.F90' 4563 ! Reprendre proprement les initialisation ci dessouds si on veut vraiment utiliser l'option (FH) 4564 fraca(:,:)=0. 4565 fm_therm(:,:)=0. 4566 ztv(:,:)=t_seri(:,:) 4567 zqasc(:,:)=q_seri(:,:) 4568 ztla(:,:)=0. 4569 zthl(:,:)=0. 4570 zpspsk(:,:)=(pplay(:,:)/100000.)**RKAPPA 4426 4571 4427 4572 … … 4515 4660 4516 4661 IF (iflag_thermals>=1) THEN 4662 4663 ! Tests Fredho, instensibilite au pas de temps ------------------------------- 4664 ! A detruire en 2024 une fois les tests documentes et les choix faits ! 4665 if (iflag_thermals_tenv /10 == 0 ) then ! 4666 do k=1,klev ! 4667 do i=1,klon ! 4668 t_env(i,k)=t_seri(i,k) ! 4669 q_env(i,k)=q_seri(i,k) ! 4670 #ifdef ISO 4671 do ixt=1,ntraciso 4672 xt_env(ixt,i,k)=xt_seri(ixt,i,k) 4673 enddo 4674 #endif 4675 enddo ! 4676 enddo ! 4677 else if (iflag_thermals_tenv / 10 == 2 ) then ! 4678 do k=1,klev ! 4679 do i=1,klon ! 4680 q_env(i,k)=q_seri(i,k) ! 4681 #ifdef ISO 4682 do ixt=1,ntraciso 4683 xt_env(ixt,i,k)=xt_seri(ixt,i,k) 4684 enddo 4685 #endif 4686 enddo ! 4687 enddo ! 4688 else if (iflag_thermals_tenv / 10 == 3 ) then ! 4689 do k=1,klev ! 4690 do i=1,klon ! 4691 t_env(i,k)=t(i,k) ! 4692 q_env(i,k)=qx(i,k,1) ! 4693 #ifdef ISO 4694 do ixt=1,ntraciso 4695 xt_env(ixt,i,k)=xt_seri(ixt,i,k) 4696 enddo 4697 #endif 4698 enddo ! 4699 enddo ! 4700 endif ! 4701 ! Tests Fredho, instensibilite au pas de temps ------------------------------ 4702 4517 4703 !jyg< 4518 4704 !! IF (mod(iflag_pbl_split/2,2) .EQ. 1) THEN … … 4523 4709 t_therm(i,k) = t_seri(i,k) - wake_s(i)*wake_deltat(i,k) 4524 4710 q_therm(i,k) = q_seri(i,k) - wake_s(i)*wake_deltaq(i,k) 4711 t_env(i,k) = t_env(i,k) - wake_s(i)*wake_deltat(i,k) 4712 q_env(i,k) = q_env(i,k) - wake_s(i)*wake_deltaq(i,k) 4525 4713 u_therm(i,k) = u_seri(i,k) 4526 4714 v_therm(i,k) = v_seri(i,k) … … 4528 4716 do ixt=1,ntraciso 4529 4717 xt_therm(ixt,i,k) = xt_seri(ixt,i,k) - wake_s(i)*wake_deltaxt(ixt,i,k) 4718 xt_env(ixt,i,k) = xt_env(ixt,i,k) - wake_s(i)*wake_deltaxt(ixt,i,k) 4530 4719 enddo !do ixt=1,ntraciso 4531 4720 #endif … … 4570 4759 ,pplay,paprs,pphi,weak_inversion & 4571 4760 ! ,u_seri,v_seri,t_seri,q_seri,zqsat,debut & !jyg 4572 ,u_therm,v_therm,t_therm,q_therm,t_ therm,q_therm,zqsat,debut & !jyg4761 ,u_therm,v_therm,t_therm,q_therm,t_env,q_env,zqsat,debut & !jyg 4573 4762 ,d_u_ajs,d_v_ajs,d_t_ajs,d_q_ajs & 4574 4763 ,fm_therm,entr_therm,detr_therm & … … 4589 4778 ,zqla,ztva & 4590 4779 #ifdef ISO 4591 & ,xt_ therm,d_xt_ajs &4780 & ,xt_env,d_xt_ajs & 4592 4781 #ifdef DIAGISO 4593 4782 & ,q_the,xt_the & … … 4624 4813 IF (ok_bug_split_th) THEN 4625 4814 CALL add_wake_tend & 4626 (d_deltat_the, d_deltaq_the, dsig0, d dens0, ddens0, wkoccur1, 'the', abortphy &4815 (d_deltat_the, d_deltaq_the, dsig0, dsig0, ddens0, ddens0, wkoccur1, 'the', abortphy & 4627 4816 #ifdef ISO 4628 4817 ,d_deltaxt_the & … … 4631 4820 ELSE 4632 4821 CALL add_wake_tend & 4633 (d_deltat_the, d_deltaq_the, dsig0, d dens0, ddens0, wake_k, 'the', abortphy &4822 (d_deltat_the, d_deltaq_the, dsig0, dsig0, ddens0, ddens0, wake_k, 'the', abortphy & 4634 4823 #ifdef ISO 4635 4824 ,d_deltaxt_the & … … 4660 4849 ! Transport de la TKE par les panaches thermiques. 4661 4850 ! FH : 2010/02/01 4662 ! if (iflag_pbl.eq.10) then 4663 ! call thermcell_dtke(klon,klev,nbsrf,pdtphys,fm_therm,entr_therm, 4664 ! s rg,paprs,pbl_tke) 4665 ! endif 4851 if (iflag_thermcell_tke==1) then 4852 call thermcell_dtke(klon,klev,nbsrf,pdtphys,fm_therm,entr_therm,rg,paprs,pbl_tke) 4853 endif 4666 4854 ! ------------------------------------------------------------------- 4667 4855 … … 4902 5090 4903 5091 CALL lscp(klon,klev,phys_tstep,missing_val,paprs,pplay, & 4904 t_seri, q_seri, ptconv,ratqs, &5092 t_seri, q_seri,qs_ancien,ptconv,ratqs, & 4905 5093 d_t_lsc, d_q_lsc, d_ql_lsc, d_qi_lsc, rneb, rneblsvol, & 4906 pfraclr, pfracld,&5094 pfraclr, pfracld, cldfraliq, sigma2_icefracturb, mean_icefracturb, & 4907 5095 radocond, picefra, rain_lsc, snow_lsc, & 4908 5096 frac_impa, frac_nucl, beta_prec_fisrt, & 4909 5097 prfl, psfl, rhcl, & 4910 5098 zqasc, fraca,ztv,zpspsk,ztla,zthl,iflag_cld_th, & 4911 iflag_ice_thermo, distcltop, temp_cltop, cell_area, & 4912 cf_seri, rvc_seri, u_seri, v_seri, pbl_eps(:,:,is_ave), & 5099 iflag_ice_thermo, distcltop, temp_cltop, 5100 pbl_tke(:,:,is_ave), pbl_eps(:,:,is_ave), & 5101 cell_area, & 5102 cf_seri, rvc_seri, u_seri, v_seri, & 4913 5103 qsub, qissr, qcld, subfra, issrfra, gamma_cond, ratio_qi_qtot, & 4914 5104 dcf_sub, dcf_con, dcf_mix, dqi_adj, dqi_sub, dqi_con, dqi_mix, & … … 4923 5113 ELSE 4924 5114 5115 ! Camille Risi mai 2024: on ne met pas à jour ici pour ne pas s'mbêter à modifier fisrtilp 4925 5116 CALL fisrtilp(phys_tstep,paprs,pplay, & 4926 5117 t_seri, q_seri,ptconv,ratqs, & … … 5522 5713 tausum_aero, tau3d_aero) 5523 5714 ENDIF 5524 ELSE 5715 ELSE IF (iflag_rrtm .EQ.1) THEN ! RRTM radiation 5525 5716 IF (aerosol_couple .AND. config_inca == 'aero' ) THEN 5526 5717 abort_message='config_inca=aero et rrtm=1 impossible' … … 5588 5779 ! 5589 5780 ENDIF 5781 ELSE IF (iflag_rrtm .EQ.2) THEN ! ecrad RADIATION 5782 #ifdef CPP_ECRAD 5783 !--climatologies or INCA aerosols 5784 CALL readaerosol_optic_ecrad( debut, aerosol_couple, ok_alw, ok_volcan, & 5785 flag_aerosol, flag_bc_internal_mixture, itap, jD_cur-jD_ref, & 5786 pdtphys, pplay, paprs, t_seri, rhcl, presnivs, & 5787 tr_seri, mass_solu_aero, mass_solu_aero_pi, m_allaer) 5788 #else 5789 abort_message='You should compile with -rad ecrad if running with iflag_rrtm=2' 5790 CALL abort_physic(modname,abort_message,1) 5791 #endif 5590 5792 ENDIF 5591 5793 ELSE !--flag_aerosol = 0 … … 5828 6030 ! Rajoute par OB pour RRTM 5829 6031 tau_aero_lw_rrtm, & 5830 cldtaupirad, &6032 cldtaupirad, m_allaer, & 5831 6033 ! zqsat, flwcrad, fiwcrad, & 5832 6034 zqsat, flwc, fiwc, & … … 5907 6109 ! Rajoute par OB pour RRTM 5908 6110 tau_aero_lw_rrtm, & 5909 cldtaupi, &6111 cldtaupi, m_allaer, & 5910 6112 ! zqsat, flwcrad, fiwcrad, & 5911 6113 zqsat, flwc, fiwc, & … … 5934 6136 cloud_cover_sw) 5935 6137 ENDIF !ok_4xCO2atm 6138 6139 ! A.I aout 2023 6140 ! Effet 3D des nuages Ecrad 6141 ! a passer : nom du ficher namelist et cles ok_3Deffect 6142 ! a declarer comme iflag_rrtm et a lire dans physiq.def 6143 #ifdef CPP_ECRAD 6144 IF (ok_3Deffect) then 6145 ! print*,'ok_3Deffect = ',ok_3Deffect 6146 namelist_ecrad_file='namelist_ecrad_s2' 6147 CALL radlwsw & 6148 (debut, dist, rmu0, fract, & 6149 paprs, pplay,zxtsol,SFRWL,albsol_dir, albsol_dif, & 6150 t_seri,q_seri,wo, & 6151 cldfrarad, cldemirad, cldtaurad, & 6152 ok_ade.OR.flag_aerosol_strat.GT.0, ok_aie, ok_volcan, flag_volc_surfstrat, & 6153 flag_aerosol, flag_aerosol_strat, flag_aer_feedback, & 6154 tau_aero, piz_aero, cg_aero, & 6155 tau_aero_sw_rrtm, piz_aero_sw_rrtm, cg_aero_sw_rrtm, & 6156 tau_aero_lw_rrtm, & 6157 cldtaupi, & 6158 zqsat, flwc, fiwc, & 6159 ref_liq, ref_ice, ref_liq_pi, ref_ice_pi, & 6160 namelist_ecrad_file, & 6161 ! A modifier 6162 heat_s2,heat0_s2,cool_s2,cool0_s2,albpla_s2, & 6163 heat_volc,cool_volc, & 6164 topsw_s2,toplw_s2,solsw_s2,solswfdiff_s2,sollw_s2, & 6165 sollwdown_s2, & 6166 topsw0_s2,toplw0_s2,solsw0_s2,sollw0_s2, & 6167 lwdnc0_s2, lwdn0_s2, lwdn_s2, lwupc0_s2, lwup0_s2, lwup_s2, & 6168 swdnc0_s2, swdn0_s2, swdn_s2, swupc0_s2, swup0_s2, swup_s2, & 6169 topswad_aero_s2, solswad_aero_s2, & 6170 topswai_aero_s2, solswai_aero_s2, & 6171 topswad0_aero_s2, solswad0_aero_s2, & 6172 topsw_aero_s2, topsw0_aero_s2, & 6173 solsw_aero_s2, solsw0_aero_s2, & 6174 topswcf_aero_s2, solswcf_aero_s2, & 6175 !-C. Kleinschmitt for LW diagnostics 6176 toplwad_aero_s2, sollwad_aero_s2,& 6177 toplwai_aero_s2, sollwai_aero_s2, & 6178 toplwad0_aero_s2, sollwad0_aero_s2,& 6179 !-end 6180 ZLWFT0_i, ZFLDN0, ZFLUP0, & 6181 ZSWFT0_i, ZFSDN0, ZFSUP0, & 6182 cloud_cover_sw_s2) 6183 ENDIF ! ok_3Deffect 6184 #endif 6185 5936 6186 ENDIF ! aerosol_couple 5937 6187 itaprad = 0 … … 6157 6407 d_t_hin(:, :)=0. 6158 6408 CALL add_phys_tend(du_gwd_hines, dv_gwd_hines, d_t_hin, dq0, dql0, & 6159 dqi0, dqbs0, paprs, 'hin', abortphy,flag_inhib_tend,itap,0 &6409 dqi0, dqbs0, paprs, 'hin', abortphy,flag_inhib_tend,itap,0 & 6160 6410 #ifdef ISO 6161 6411 & ,dxt0,dxtl0,dxti0 & … … 6280 6530 6281 6531 SELECT CASE(flag_emit) 6282 CASE(1) ! emission volc H2O dansLMDZ6532 CASE(1) ! emission volc H2O in LMDZ 6283 6533 DO ieru=1, nErupt 6284 6534 IF (year_cur==year_emit_vol(ieru).AND.& … … 6288 6538 6289 6539 IF(flag_verbose_strataer) print *,'IN physiq_mod: date=',year_cur,mth_cur,day_cur 6290 ! initialisation tendance qemission6540 ! initialisation of q tendency emission 6291 6541 d_q_emiss(:,:)=0. 6292 6542 ! daily injection mass emission - NL … … 6295 6545 ! 6296 6546 CALL STRATEMIT(pdtphys,pdtphys,latitude_deg,longitude_deg,t_seri,& 6297 pplay,paprs,tr_seri,& 6298 m_H2O_emiss_vol_daily,& 6299 xlat_min_vol(ieru),xlat_max_vol(ieru),& 6300 xlon_min_vol(ieru),xlon_max_vol(ieru),& 6301 altemiss_vol(ieru),& 6302 sigma_alt_vol(ieru),1,& 6303 1,nAerErupt+1,0) 6547 pplay,paprs,tr_seri,& 6548 m_H2O_emiss_vol_daily,& 6549 xlat_min_vol(ieru),xlat_max_vol(ieru),& 6550 xlon_min_vol(ieru),xlon_max_vol(ieru),& 6551 altemiss_vol(ieru),sigma_alt_vol(ieru),1,1.,& 6552 nAerErupt+1,0) 6304 6553 6305 6554 IF(flag_verbose_strataer) print *,'IN physiq_mod: min max d_q_emiss=',& … … 6315 6564 ENDIF 6316 6565 #endif 6317 6318 6566 6319 6567 !=============================================================== … … 6754 7002 t_seri(:,:)=t_seri(:,:)+d_t_ec(:,:) 6755 7003 6756 !======================================================================= 6757 ! SORTIES 6758 !======================================================================= 6759 ! 6760 !IM initialisation + calculs divers diag AMIP2 6761 ! 6762 include "calcul_divers.h" 6763 ! 6764 !IM Interpolation sur les niveaux de pression du NMC 6765 ! ------------------------------------------------- 6766 ! 6767 include "calcul_STDlev.h" 6768 ! 6769 ! slp sea level pressure derived from Arpege-IFS : CALL ctstar + CALL pppmer 6770 CALL diag_slp(klon,t_seri,paprs,pplay,pphis,ptstar,pt0,slp) 6771 ! 7004 !================================================================== 7005 !--OB water mass fixer for the physics 7006 !--water profiles are corrected to force mass conservation of water 7007 !--currently flag is turned off 7008 !================================================================== 7009 IF (mass_fixer) THEN 7010 #ifdef ISO 7011 CALL abort_gcm('physiq 6936','isos pas prevus dans le mass fixer',1) 7012 ! Camille Risi mai 2024: on attend d'avoir la 4e dimension qui rendra tout plus simple. 7013 #endif 7014 qql2(:)=0.0 7015 DO k = 1, klev 7016 qql2(:)=qql2(:)+(q_seri(:,k)+ql_seri(:,k))*zmasse(:,k) 7017 IF (nqo >= 3) THEN 7018 qql2(:)=qql2(:)+qs_seri(:,k)*zmasse(:,k) 7019 ENDIF 7020 IF (ok_bs) THEN 7021 qql2(:)=qql2(:)+qbs_seri(:,k)*zmasse(:,k) 7022 ENDIF 7023 ENDDO 7024 7025 #ifdef CPP_StratAer 7026 IF (ok_qemiss) THEN 7027 DO k = 1, klev 7028 qql1(:) = qql1(:)+d_q_emiss(:,k)*zmasse(:,k) 7029 ENDDO 7030 ENDIF 7031 #endif 7032 IF (ok_qch4) THEN 7033 DO k = 1, klev 7034 qql1(:) = qql1(:)+d_q_ch4_dtime(:,k)*zmasse(:,k) 7035 ENDDO 7036 ENDIF 7037 7038 DO i = 1, klon 7039 !--compute ratio of what q+ql should be with conservation to what it is 7040 IF (ok_bs) THEN 7041 corrqql=(qql1(i)+(evap(i)-rain_fall(i)-snow_fall(i)-bs_fall(i))*pdtphys)/qql2(i) 7042 ELSE 7043 corrqql=(qql1(i)+(evap(i)-rain_fall(i)-snow_fall(i))*pdtphys)/qql2(i) 7044 ENDIF 7045 DO k = 1, klev 7046 q_seri(i,k) =q_seri(i,k)*corrqql 7047 ql_seri(i,k)=ql_seri(i,k)*corrqql 7048 IF (nqo >= 3) THEN 7049 qs_seri(i,k)=qs_seri(i,k)*corrqql 7050 ENDIF 7051 IF (ok_bs) THEN 7052 qbs_seri(i,k)=qbs_seri(i,k)*corrqql 7053 ENDIF 7054 ENDDO 7055 ENDDO 7056 ENDIF 7057 !--fin mass fixer 7058 6772 7059 !cc prw = eau precipitable 6773 7060 ! prlw = colonne eau liquide 6774 7061 ! prlw = colonne eau solide 6775 7062 ! prbsw = colonne neige soufflee 7063 ! water_budget = non-conservation residual from the LMDZ physics 7064 ! (should be equal to machine precision if mass fixer is activated) 6776 7065 prw(:) = 0. 6777 7066 prlw(:) = 0. 6778 7067 prsw(:) = 0. 6779 7068 prbsw(:) = 0. 7069 water_budget(:) = 0.0 6780 7070 DO k = 1, klev 6781 7071 prw(:) = prw(:) + q_seri(:,k)*zmasse(:,k) 6782 7072 prlw(:) = prlw(:) + ql_seri(:,k)*zmasse(:,k) 6783 prsw(:) = prsw(:) + qs_seri(:,k)*zmasse(:,k) 6784 prbsw(:)= prbsw(:) + qbs_seri(:,k)*zmasse(:,k) 7073 water_budget(:) = water_budget(:) + (q_seri(:,k)-qx(:,k,ivap)+ql_seri(:,k)-qx(:,k,iliq))*zmasse(:,k) 7074 IF (nqo >= 3) THEN 7075 prsw(:) = prsw(:) + qs_seri(:,k)*zmasse(:,k) 7076 water_budget(:) = water_budget(:) + (qs_seri(:,k)-qx(:,k,isol))*zmasse(:,k) 7077 ENDIF 7078 IF (nqo >= 4 .AND. ok_bs) THEN 7079 prbsw(:)= prbsw(:) + qbs_seri(:,k)*zmasse(:,k) 7080 water_budget(:) = water_budget(:) + (qbs_seri(:,k)-qx(:,k,ibs))*zmasse(:,k) 7081 ENDIF 6785 7082 ENDDO 6786 6787 #ifdef ISO 6788 DO i = 1, klon 6789 do ixt=1,ntraciso 6790 xtprw(ixt,i) = 0. 6791 DO k = 1, klev 6792 xtprw(ixt,i) = xtprw(ixt,i) + & 6793 & xt_seri(ixt,i,k)*(paprs(i,k)-paprs(i,k+1))/RG 6794 ENDDO !DO k = 1, klev 6795 enddo !do ixt=1,ntraciso 6796 enddo !DO i = 1, klon 6797 #endif 7083 water_budget(:)=water_budget(:)+(rain_fall(:)+snow_fall(:)-evap(:))*pdtphys 7084 IF (ok_bs) THEN 7085 water_budget(:)=water_budget(:)+bs_fall(:)*pdtphys 7086 ENDIF 7087 ! Camille Risi mai 2024: pour les isotopes, on attend d'avoir la 4e dimension, ça rendra tout plus facile 7088 ! ces variables sont diagnostiques, donc pas indispensables 7089 7090 !======================================================================= 7091 ! SORTIES 7092 !======================================================================= 7093 ! 7094 !IM initialisation + calculs divers diag AMIP2 7095 ! 7096 include "calcul_divers.h" 7097 ! 7098 !IM Interpolation sur les niveaux de pression du NMC 7099 ! ------------------------------------------------- 7100 ! 7101 include "calcul_STDlev.h" 7102 ! 7103 ! slp sea level pressure derived from Arpege-IFS : CALL ctstar + CALL pppmer 7104 CALL diag_slp(klon,t_seri,paprs,pplay,pphis,ptstar,pt0,slp) 7105 ! 6798 7106 ! 6799 7107 IF (ANY(type_trac == ['inca','inco'])) THEN … … 6898 7206 !IM global posePB include "write_bilKP_ave.h" 6899 7207 ! 6900 6901 !--OB mass fixer6902 !--profile is corrected to force mass conservation of water6903 IF (mass_fixer) THEN6904 qql2(:)=0.06905 DO k = 1, klev6906 qql2(:)=qql2(:)+(q_seri(:,k)+ql_seri(:,k)+qs_seri(:,k))*zmasse(:,k)6907 ENDDO6908 6909 #ifdef CPP_StratAer6910 IF (ok_qemiss) THEN6911 DO k = 1, klev6912 qql1(:) = qql1(:)+d_q_emiss(:,k)*zmasse(:,k)6913 ENDDO6914 ENDIF6915 #endif6916 IF (ok_qch4) THEN6917 DO k = 1, klev6918 qql1(:) = qql1(:)+d_q_ch4_dtime(:,k)*zmasse(:,k)6919 ENDDO6920 ENDIF6921 6922 DO i = 1, klon6923 !--compute ratio of what q+ql should be with conservation to what it is6924 corrqql=(qql1(i)+(evap(i)-rain_fall(i)-snow_fall(i))*pdtphys)/qql2(i)6925 DO k = 1, klev6926 q_seri(i,k) =q_seri(i,k)*corrqql6927 ql_seri(i,k)=ql_seri(i,k)*corrqql6928 ENDDO6929 ENDDO6930 #ifdef ISO6931 do ixt=1,ntraciso6932 xtql2(ixt,:)=0.06933 DO k = 1, klev6934 xtql2(ixt,:)=xtql2(ixt,:)+(xt_seri(ixt,:,k)+xtl_seri(ixt,:,k)+xts_seri(ixt,:,k))*zmasse(:,k)6935 ENDDO6936 DO i = 1, klon6937 !--compute ratio of what q+ql should be with conservation to what it is6938 corrxtql(ixt)=(xtql1(ixt,i)+(xtevap(ixt,i)-xtrain_fall(ixt,i)-xtsnow_fall(ixt,i))*pdtphys)/xtql2(ixt,i)6939 DO k = 1, klev6940 xt_seri(ixt,i,k) =xt_seri(ixt,i,k)*corrxtql(ixt)6941 xtl_seri(ixt,i,k)=xtl_seri(ixt,i,k)*corrxtql(ixt)6942 ENDDO6943 ENDDO6944 enddo !do ixt=1,ntraciso6945 #endif6946 ENDIF6947 !--fin mass fixer6948 6949 7208 ! Sauvegarder les valeurs de t et q a la fin de la physique: 6950 7209 ! … … 6962 7221 xtl_ancien(:,:,:)=xtl_seri(:,:,:) 6963 7222 xts_ancien(:,:,:)=xts_seri(:,:,:) 7223 xtbs_ancien(:,:,:)=xtbs_seri(:,:,:) 6964 7224 #endif 6965 7225 CALL water_int(klon,klev,q_ancien,zmasse,prw_ancien) … … 7098 7358 ok_sync, ptconv, read_climoz, clevSTD, & 7099 7359 ptconvth, d_u, d_t, qx, d_qx, zmasse, & 7100 flag_aerosol, flag_aerosol_strat, ok_cdnc,t, u1,v1)7360 flag_aerosol, flag_aerosol_strat, ok_cdnc,t, u1, v1) 7101 7361 #endif 7102 7362 7103 7363 #ifndef CPP_XIOS 7104 CALL write_paramLMDZ_phy(itap,nid_ctesGCM,ok_sync) 7105 #endif 7106 7107 #endif 7108 7109 ! Pour XIOS : On remet des variables a .false. apres un premier appel 7110 IF (debut) THEN 7111 7112 IF (using_xios) THEN 7113 swaero_diag=.FALSE. 7114 swaerofree_diag=.FALSE. 7115 dryaod_diag=.FALSE. 7116 ok_4xCO2atm= .FALSE. 7117 ! write (lunout,*)'ok_4xCO2atm= ',swaero_diag, swaerofree_diag, dryaod_diag, ok_4xCO2atm 7118 7119 IF (is_master) THEN 7120 !--setting up swaero_diag to TRUE in XIOS case 7121 IF (xios_field_is_active("topswad").OR.xios_field_is_active("topswad0").OR. & 7122 xios_field_is_active("solswad").OR.xios_field_is_active("solswad0").OR. & 7123 xios_field_is_active("topswai").OR.xios_field_is_active("solswai").OR. & 7124 (iflag_rrtm==1.AND.(xios_field_is_active("toplwad").OR.xios_field_is_active("toplwad0").OR. & 7125 xios_field_is_active("sollwad").OR.xios_field_is_active("sollwad0")))) & 7126 !!!--for now these fields are not in the XML files so they are omitted 7127 !!! xios_field_is_active("toplwai").OR.xios_field_is_active("sollwai") !))) & 7128 swaero_diag=.TRUE. 7129 7130 !--setting up swaerofree_diag to TRUE in XIOS case 7131 IF (xios_field_is_active("SWdnSFCcleanclr").OR.xios_field_is_active("SWupSFCcleanclr").OR. & 7132 xios_field_is_active("SWupTOAcleanclr").OR.xios_field_is_active("rsucsaf").OR. & 7133 xios_field_is_active("rsdcsaf") .OR. xios_field_is_active("LWdnSFCcleanclr").OR. & 7134 xios_field_is_active("LWupTOAcleanclr")) & 7135 swaerofree_diag=.TRUE. 7136 7137 !--setting up dryaod_diag to TRUE in XIOS case 7138 DO naero = 1, naero_tot-1 7139 IF (xios_field_is_active("dryod550_"//name_aero_tau(naero))) dryaod_diag=.TRUE. 7140 ENDDO 7141 ! 7142 !--setting up ok_4xCO2atm to TRUE in XIOS case 7143 IF (xios_field_is_active("rsut4co2").OR.xios_field_is_active("rlut4co2").OR. & 7144 xios_field_is_active("rsutcs4co2").OR.xios_field_is_active("rlutcs4co2").OR. & 7145 xios_field_is_active("rsu4co2").OR.xios_field_is_active("rsucs4co2").OR. & 7146 xios_field_is_active("rsd4co2").OR.xios_field_is_active("rsdcs4co2").OR. & 7147 xios_field_is_active("rlu4co2").OR.xios_field_is_active("rlucs4co2").OR. & 7148 xios_field_is_active("rld4co2").OR.xios_field_is_active("rldcs4co2")) & 7149 ok_4xCO2atm=.TRUE. 7150 ENDIF 7151 !$OMP BARRIER 7152 CALL bcast(swaero_diag) 7153 CALL bcast(swaerofree_diag) 7154 CALL bcast(dryaod_diag) 7155 CALL bcast(ok_4xCO2atm) 7156 ! write (lunout,*)'ok_4xCO2atm= ',swaero_diag, swaerofree_diag, dryaod_diag, ok_4xCO2atm 7157 ENDIF !using_xios 7158 ENDIF 7364 CALL write_paramLMDZ_phy(itap,nid_ctesGCM,ok_sync) 7365 #endif 7366 7367 #endif 7368 ! Petit appelle de sorties pour accompagner le travail sur phyex 7369 if ( iflag_physiq == 1 ) then 7370 call output_physiqex(debut,jD_eq,pdtphys,presnivs,paprs,u,v,t,qx,cldfra,0.*t,0.*t,0.*t,pbl_tke,theta) 7371 endif 7159 7372 7160 7373 !==================================================================== … … 7200 7413 ! Disabling calls to the prt_alerte function 7201 7414 alert_first_call = .FALSE. 7415 7202 7416 7203 7417 IF (lafin) THEN … … 7212 7426 IF (read_climoz >= 1) THEN 7213 7427 IF (is_mpi_root) CALL nf95_close(ncid_climoz) 7214 DEALLOCATE(press_edg_climoz) ! pointer7215 DEALLOCATE(press_cen_climoz) ! pointer7428 DEALLOCATE(press_edg_climoz) 7429 DEALLOCATE(press_cen_climoz) 7216 7430 ENDIF 7217 7431 7218 7432 ENDIF 7433 7434 IF (using_xios) THEN 7435 7436 #ifdef INCA 7437 IF (type_trac == 'inca') THEN 7438 IF (is_omp_master .AND. grid_type==unstructured) THEN 7439 CALL finalize_inca 7440 ENDIF 7441 ENDIF 7442 #endif 7443 7444 IF (is_omp_master .and. grid_type==unstructured) CALL xios_context_finalize 7445 ENDIF 7446 7447 WRITE(lunout,*) ' physiq fin, nombre de steps ou cvpas = 1 : ', Ncvpaseq1 7219 7448 7220 IF (using_xios) THEN7221 IF (is_omp_master) CALL xios_context_finalize7222 7223 #ifdef INCA7224 if (type_trac == 'inca') then7225 IF (is_omp_master .and. grid_type==unstructured) THEN7226 CALL finalize_inca7227 ENDIF7228 endif7229 #endif7230 ENDIF !using_xios7231 WRITE(lunout,*) ' physiq fin, nombre de steps ou cvpas = 1 : ', Ncvpaseq17232 7449 ENDIF 7233 7450 -
LMDZ6/branches/cirrus/libf/phylmdiso/reevap.F90
r4491 r5202 1 SUBROUTINE reevap (klon,klev,iflag_ice_thermo,t_seri,q_seri,ql_seri,qs_seri, & 2 & d_t_eva,d_q_eva,d_ql_eva,d_qs_eva & 3 #ifdef ISO 4 ,xt_seri,xtl_seri,xts_seri,d_xt_eva,d_xtl_eva,d_xts_eva & 5 #endif 6 & ) 1 SUBROUTINE reevap (klon,klev,iflag_ice_thermo,t_seri,qx, & 2 & d_t_eva,d_qx_eva) 7 3 8 4 ! flag to include modifications to ensure energy conservation (if flag >0) 9 5 USE add_phys_tend_mod, only : fl_cor_ebil 10 6 #ifdef ISO 11 USE infotrac_phy, ONLY: ntiso 7 USE infotrac_phy, ONLY: ntiso,nqtot,ivap,iliq,isol,iqWIsoPha 12 8 #ifdef ISOVERIF 13 9 USE isotopes_verif_mod … … 23 19 24 20 INTEGER klon,klev,iflag_ice_thermo 25 REAL, DIMENSION(klon,klev), INTENT(in) :: t_seri,q_seri,ql_seri,qs_seri 26 REAL, DIMENSION(klon,klev), INTENT(out) :: d_t_eva,d_q_eva,d_ql_eva,d_qs_eva 21 REAL, DIMENSION(klon,klev), INTENT(in) :: t_seri 22 REAL, DIMENSION(klon,klev,nqtot), INTENT(in) :: qx 23 REAL, DIMENSION(klon,klev), INTENT(out) :: d_t_eva 24 REAL, DIMENSION(klon,klev,nqtot), INTENT(out) :: d_qx_eva 27 25 28 26 REAL za,zb,zdelta,zlvdcp,zlsdcp 29 INTEGER i,k 27 INTEGER i,k,ixt,ivapcur,iliqcur,isolcur 30 28 31 #ifdef ISO32 REAL, DIMENSION(ntiso,klon,klev), INTENT(in) :: xt_seri,xtl_seri,xts_seri33 REAL, DIMENSION(ntiso,klon,klev), INTENT(out) :: d_xt_eva,d_xtl_eva,d_xts_eva34 integer ixt35 #endif36 29 37 30 !--------Stochastic Boundary Layer Triggering: ALE_BL-------- … … 42 35 !IM 100106 BEG : pouvoir sortir les ctes de la physique 43 36 ! 37 DO ixt = 1, 1+ntiso 44 38 ! Re-evaporer l'eau liquide nuageuse 45 39 ! 40 iliqcur= iqWIsoPha(ixt,iliq) 41 ivapcur= iqWIsoPha(ixt,ivap) 42 isolcur= iqWIsoPha(ixt,isol) 46 43 !print *,'rrevap ; fl_cor_ebil:',fl_cor_ebil,' iflag_ice_thermo:',iflag_ice_thermo,' RVTMP2',RVTMP2 47 44 DO k = 1, klev ! re-evaporation de l'eau liquide nuageuse 48 DO i = 1, klon 49 if (fl_cor_ebil .GT. 0) then 50 zlvdcp=RLVTT/RCPD/(1.0+RVTMP2*(q_seri(i,k)+ql_seri(i,k)+qs_seri(i,k))) 51 zlsdcp=RLSTT/RCPD/(1.0+RVTMP2*(q_seri(i,k)+ql_seri(i,k)+qs_seri(i,k))) 52 else 53 zlvdcp=RLVTT/RCPD/(1.0+RVTMP2*q_seri(i,k)) 54 !jyg< 55 ! Attention : Arnaud a propose des formules completement differentes 56 ! A verifier !!! 57 zlsdcp=RLSTT/RCPD/(1.0+RVTMP2*q_seri(i,k)) 58 end if 59 IF (iflag_ice_thermo .EQ. 0) THEN 60 zlsdcp=zlvdcp 45 DO i = 1, klon 46 47 IF (ixt == 1) THEN ! water 48 IF (fl_cor_ebil > 0) THEN 49 !zlvdcp=RLVTT/RCPD/(1.0+RVTMP2*(q_seri(i,k)+ql_seri(i,k)+qs_seri(i,k))) 50 !zlsdcp=RLSTT/RCPD/(1.0+RVTMP2*(q_seri(i,k)+ql_seri(i,k)+qs_seri(i,k))) 51 zlvdcp=RLVTT/RCPD/(1.0+RVTMP2*(qx(i,k,ivapcur)+qx(i,k,iliqcur)+qx(i,k,isolcur))) 52 zlsdcp=RLSTT/RCPD/(1.0+RVTMP2*(qx(i,k,ivapcur)+qx(i,k,iliqcur)+qx(i,k,isolcur))) 53 ELSE 54 zlvdcp=RLVTT/RCPD/(1.0+RVTMP2*qx(i,k,ivapcur)) 55 !jyg< 56 ! Attention : Arnaud a propose des formules completement differentes 57 ! A verifier !!! 58 zlsdcp=RLSTT/RCPD/(1.0+RVTMP2*qx(i,k,ivapcur)) 59 ENDIF 60 IF (iflag_ice_thermo == 0) THEN 61 zlsdcp=zlvdcp 61 62 ENDIF 62 63 !>jyg 64 ENDIF 65 IF (iflag_ice_thermo == 0) THEN 66 !pas necessaire a priori 63 67 64 IF (iflag_ice_thermo.eq.0) THEN 65 !pas necessaire a priori 68 zdelta = MAX(0.,SIGN(1.,RTT-t_seri(i,k))) 69 zdelta = 0. 70 zb = MAX(0.0,qx(i,k,iliqcur)) 71 IF (ixt == 1) THEN 72 za = - MAX(0.0,qx(i,k,iliqcur)) & 73 * (zlvdcp*(1.-zdelta)+zlsdcp*zdelta) 74 d_t_eva(i,k) = za 75 ENDIF 76 d_qx_eva(i,k,ivapcur) = zb 77 d_qx_eva(i,k,iliqcur) = -qx(i,k,iliqcur) 78 d_qx_eva(i,k,isolcur) = 0. 66 79 67 zdelta = MAX(0.,SIGN(1.,RTT-t_seri(i,k))) 68 zdelta = 0. 69 zb = MAX(0.0,ql_seri(i,k)) 70 za = - MAX(0.0,ql_seri(i,k)) & 71 * (zlvdcp*(1.-zdelta)+zlsdcp*zdelta) 72 d_t_eva(i,k) = za 73 d_q_eva(i,k) = zb 74 d_ql_eva(i,k) = -ql_seri(i,k) 75 d_qs_eva(i,k) = 0. 76 77 #ifdef ISO 78 do ixt=1,ntiso 79 zb = MAX(0.0,xtl_seri(ixt,i,k)) 80 d_xt_eva(ixt,i,k) = zb 81 d_xtl_eva(ixt,i,k) = -xtl_seri(ixt,i,k) 82 d_xts_eva(ixt,i,k) = 0. 83 enddo 84 #ifdef ISOVERIF 85 do ixt=1,ntiso 86 call iso_verif_noNaN(xt_seri(ixt,i,k), & 87 & 'reevap 2417: apres evap tot') 88 enddo 89 if (iso_eau.gt.0) then 90 call iso_verif_egalite_choix( & 91 & xt_seri(iso_eau,i,k),q_seri(i,k), & 92 & 'reevap 1891+, après reevap totale',errmax,errmaxrel) 93 call iso_verif_egalite_choix( & 94 & xtl_seri(iso_eau,i,k),ql_seri(i,k), & 95 & 'reevap 2209+, après reevap totale',errmax,errmaxrel) 96 endif !if (iso_eau.gt.0) then 97 if ((iso_HDO.gt.0).and.(iso_O18.gt.0)) then 98 if (q_seri(i,k).gt.ridicule) then 99 if (iso_verif_o18_aberrant_nostop( & 100 & xt_seri(iso_HDO,i,k)/q_seri(i,k), & 101 & xt_seri(iso_O18,i,k)/q_seri(i,k), & 102 & 'reevap 2315: apres reevap totale').eq.1) then 103 write(*,*) 'i,k,q_seri(i,k)=',i,k,q_seri(i,k) 104 write(*,*) 'd_q_eva(i,k)=',d_q_eva(i,k) 105 write(*,*) 'deltaD(d_q_eva(i,k))=',deltaD(d_xt_eva(iso_HDO,i,k)/d_q_eva(i,k)) 106 write(*,*) 'deltaO18(d_q_eva(i,k))=',deltaO(d_xt_eva(iso_O18,i,k)/d_q_eva(i,k)) 107 stop 108 endif ! if (iso_verif_o18_aberrant_nostop 109 endif !if (q_seri(i,k).gt.errmax) then 110 endif !if ((iso_HDO.gt.0).and.(iso_O18.gt.0)) then 111 #ifdef ISOTRAC 112 call iso_verif_traceur(xt_seri(1,i,k), & 113 & 'reevap 2165a') 114 call iso_verif_traceur_pbidouille(xt_seri(1,i,k), & 115 & 'reevap 2165b') 116 #endif 117 118 #endif 119 #endif 120 121 ELSE 122 80 ELSE 81 123 82 !CR: on r\'e-\'evapore eau liquide et glace 124 83 … … 127 86 ! za = - MAX(0.0,ql_seri(i,k)) & 128 87 ! * (zlvdcp*(1.-zdelta)+zlsdcp*zdelta) 129 zb = MAX(0.0,ql_seri(i,k)+qs_seri(i,k)) 130 za = - MAX(0.0,ql_seri(i,k))*zlvdcp & 131 - MAX(0.0,qs_seri(i,k))*zlsdcp 132 d_t_eva(i,k) = za 133 d_q_eva(i,k) = zb 134 d_ql_eva(i,k) = -ql_seri(i,k) 135 d_qs_eva(i,k) = -qs_seri(i,k) 88 IF (ixt == 1) THEN 89 za = - MAX(0.0,qx(i,k,iliqcur))*zlvdcp & 90 - MAX(0.0,qx(i,k,iliqcur))*zlsdcp 91 d_t_eva(i,k) = za 92 ENDIF 93 !zb = MAX(0.0,ql_seri(i,k)+qs_seri(i,k)) 94 !d_q_eva(i,k) = zb 95 !d_ql_eva(i,k) = -ql_seri(i,k) 96 !d_qs_eva(i,k) = -qs_seri(i,k) 136 97 137 #ifdef ISO 138 do ixt=1,ntiso 139 zb = MAX(0.0,xtl_seri(ixt,i,k)+xts_seri(ixt,i,k)) 140 d_xt_eva(ixt,i,k) = zb 141 d_xtl_eva(ixt,i,k) = -xtl_seri(ixt,i,k) 142 d_xts_eva(ixt,i,k) = -xts_seri(ixt,i,k) 143 enddo 98 zb = MAX(0.0,qx(i,k,iliqcur)+qx(i,k,isolcur)) 99 d_qx_eva(i,k,ivapcur) = zb 100 d_qx_eva(i,k,iliqcur) = -qx(i,k,iliqcur) 101 d_qx_eva(i,k,isolcur) = -qx(i,k,isolcur) 102 ENDIF 144 103 145 #ifdef ISOVERIF146 do ixt=1,ntiso147 call iso_verif_noNaN(xt_seri(ixt,i,k), &148 & 'reevap 2417: apres evap tot')149 enddo150 if (iso_eau.gt.0) then151 call iso_verif_egalite_choix( &152 & xt_seri(iso_eau,i,k),q_seri(i,k), &153 & 'reevap 1891, après réévap totale',errmax,errmaxrel)154 call iso_verif_egalite_choix( &155 & xtl_seri(iso_eau,i,k),ql_seri(i,k), &156 & 'reevap 2209, après réévap totale',errmax,errmaxrel)157 call iso_verif_egalite_choix( &158 & xts_seri(iso_eau,i,k),qs_seri(i,k), &159 & 'reevap 2209b, après réévap totale',errmax,errmaxrel)160 endif !if (iso_eau.gt.0) then161 162 if ((iso_HDO.gt.0).and.(iso_O18.gt.0)) then163 if (q_seri(i,k).gt.ridicule) then164 if (iso_verif_o18_aberrant_nostop( &165 & xt_seri(iso_HDO,i,k)/q_seri(i,k), &166 & xt_seri(iso_O18,i,k)/q_seri(i,k), &167 & 'reevap 2408: apres reevap totale').eq.1) then168 write(*,*) 'i,k,q_seri(i,k)=',i,k,q_seri(i,k)169 stop170 endif ! if (iso_verif_o18_aberrant_nostop171 endif !if (q_seri(i,k).gt.errmax) then172 endif !if ((iso_HDO.gt.0).and.(iso_O18.gt.0)) then173 #ifdef ISOTRAC174 call iso_verif_traceur(xt_seri(1,i,k), &175 & 'reevap 2165c')176 call iso_verif_traceur_pbidouille(xt_seri(1,i,k), &177 & 'reevap 2165d')178 #endif179 #endif180 #endif181 104 182 ENDIF 105 ENDDO 106 ENDDO 183 107 184 ENDDO 185 ENDDO 108 ENDDO ! DO ixt = 1, 1+niso*(nzone +1) 186 109 187 110 RETURN
Note: See TracChangeset
for help on using the changeset viewer.