- Timestamp:
- Nov 5, 2018, 3:24:59 PM (6 years ago)
- Location:
- LMDZ6/branches/DYNAMICO-conv
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
LMDZ6/branches/DYNAMICO-conv
- Property svn:mergeinfo changed
/LMDZ6/trunk removed
- Property svn:mergeinfo changed
-
LMDZ6/branches/DYNAMICO-conv/libf/phylmd/regr_pr_time_av_m.F90
r3356 r3411 5 5 USE mod_phys_lmdz_transfert_para, ONLY: bcast 6 6 USE mod_phys_lmdz_para, ONLY: mpi_rank, omp_rank 7 USE print_control_mod, ONLY: prt_level8 7 IMPLICIT NONE 9 8 … … 16 15 ! to the LMDZ vertical grid. 17 16 ! * the forcing fields are stretched if the following arguments are present: 18 ! - "lat_in": input file latitudes. 19 ! - "Ptrp_ou": target grid (LMDZ) tropopause pressure. 17 ! - "lat_in": input file latitudes. 18 ! - "pcen_in": input file cells center pressure levels. 19 ! - "ptrop_ou": target grid (LMDZ) tropopause pressure. 20 20 ! so that the tropopause is shifted to the position of the one of LMDZ. 21 21 ! Note that the ozone quantity conservation is not ensured. … … 34 34 ! except that the latitudes are in ascending order in the input file. 35 35 ! * We assume that all the input fields have the same coordinates. 36 ! * The target vertical LMDZ grid is the grid of layer centers. 37 ! * Regridding in pressure can be: 38 ! - Ploc=='I': pressures provided at Interfaces => conservative 2nd order 39 ! OK for ozone coefficients regridding in Cariolle routines. 40 ! - Ploc=='C': pressures provides at cells Centers => classical linear 41 ! OK for ozone vertical regridding, especially when torpopause 42 ! adjustment is activated, to avoid "strairs shape effect" on profiles. 36 ! * The target vertical LMDZ grid is the grid of layer boundaries. 37 ! * Regridding in pressure is conservative, second order. 43 38 ! * All the fields are regridded as a single multi-dimensional array, so it 44 39 ! saves CPU time to call this procedure once for several NetCDF variables … … 47 42 ! 1) read from the file if "tropopause_air_pressure" field is available. 48 43 ! 2) computed using "tro3" and "tro3_at_tropopause' (if available). 49 ! 3) computed using "tro3" and a fixed threshold otherwise, constant or50 ! determined usingan empirical three parameters law:44 ! 3) computed using "tro3" and a fixed threshold otherwise, determined using 45 ! an empirical three parameters law: 51 46 ! o3t(ppbV)=co1+co2*SIN(PI*(month-2)/6)*TANH(lat_deg/co3) 52 47 ! => co1 and co2 are in ppbV, and co3 in degrees. … … 56 51 ! * Fields with suffix "m"/"p" are at the closest records earlier/later than 57 52 ! the mid-julian day "julien", on the global "dynamics" horizontal grid. 58 ! * Fields(i,j,k,l) are at longitude-latitude -name "rlonv(i)-rlatu(j)-nam(l)",59 ! pressure level/interval (Ploc=="C"/"I") "pcen_in(k)"/"pcen_in(k:k+1)]".53 ! * Fields(i,j,k,l) are at longitude-latitude "rlonv(i)-rlatu(j)", pressure 54 ! interval "pint_in(k:k+1)]" and variable "nam(l)". 60 55 ! * In the 2D file case, the values are the same for all longitudes. 61 56 ! * The tropopause correction works like this: the input fields (file) are 62 57 ! interpolated on output (LMDZ) pressure field, which is streched using a power 63 ! law in a limited zone made of 2layers:64 ! 1) between lower bound (lower than lowest tropopause) and LMDZ tropopause65 ! 2) between LMDZ tropopause and upper bound (higher thzn highest tropopause)58 ! law in a limited zone made of 3 layers: 59 ! 1) between the two tropopauses (file and LMDZ) 60 ! 2) in an upper and a lower transitions layers 66 61 ! The stretching function has the following form: 67 ! Sigma_str = Sigma^(1+alpha*phi(Sigma)), where:68 ! * alpha=LOG(SigT_in/SigT_ou)/LOG(SigT_ou)69 ! This value shifts the file tropopause to the height of the one of LMDZ.70 ! * phi is quasi-linear (sections of 1/log function) in the adjacent intervals:71 ! - from 0 to 1 in [Sig_top,SigT_ou]72 ! - from 1 to 0 in [SigT_ou,Sig_bot]73 ! This quasi-triangular localization function ponderates alpha-law from one near74 ! the tropopause to zero each side apart.62 ! Sigma_str = Sigma^(1+alpha), with alpha=LOG(SigT_in/SigT_ou)/LOG(SigT_ou) 63 ! This value shifts the file tropopause to the height of the one of LMDZ. 64 ! The stretching is fully applied in the central zone only, and only partially 65 ! in the transitions zones, thick enough to guarantee a growing stretched 66 ! pressure field. The ponderation function for alpha to modulate the stretching 67 ! is constant equal to 1 in the central layer, and quasi-linear (from 1 to 0) 68 ! in the transition layers (from 1 to 0 ; in fact: sections of 1/log function), 69 ! making this localisation function quasi-trapezoidal. 75 70 ! 76 71 ! * The following fields are on the global "dynamics" grid, as read from files: 77 REAL, SAVE, ALLOCATABLE :: v1 (:,:,:,:) !--- Current time ozone fields 78 ! v1: Field read/interpol at time "julien" on the global "dynamics" horiz. grid. 79 REAL, SAVE, ALLOCATABLE :: v1m(:,:,:,:) !--- Previous time ozone fields 80 REAL, SAVE, ALLOCATABLE :: v1p(:,:,:,:) !--- Next time ozone fields 81 REAL, SAVE, ALLOCATABLE :: pgm(:,:), pgp(:,:) !--- Ground pressure 72 REAL, SAVE, ALLOCATABLE :: v1m(:,:,:,:) !--- Previous ozone fields 73 REAL, SAVE, ALLOCATABLE :: v1p(:,:,:,:) !--- Next ozone fields 74 REAL, SAVE, ALLOCATABLE :: psm(:,:), psp(:,:) !--- Surface pressure 82 75 REAL, SAVE, ALLOCATABLE :: ptm(:,:), ptp(:,:) !--- Tropopause pressure 83 76 REAL, SAVE, ALLOCATABLE :: otm(:,:), otp(:,:) !--- Tropopause o3 mix. ratio … … 88 81 ! * for monthly input files: julien is in [time_in(irec),time_in(irec+1)] 89 82 LOGICAL, SAVE :: linterp !--- Interpolation in time 90 LOGICAL, SAVE :: lPrS file!--- Surface pressure flag91 LOGICAL, SAVE :: lPrT file!--- Tropopause pressure flag92 LOGICAL, SAVE :: lO3T file!--- Tropopause ozone flag83 LOGICAL, SAVE :: lPrSurf !--- Surface pressure flag 84 LOGICAL, SAVE :: lPrTrop !--- Tropopause pressure flag 85 LOGICAL, SAVE :: lO3Trop !--- Tropopause ozone flag 93 86 LOGICAL, SAVE :: lfirst=.TRUE. !--- First call flag 94 87 !$OMP THREADPRIVATE(lfirst) 95 REAL, PARAMETER :: pTropUp=9.E+3 !--- Value < tropopause pressure (Pa) 96 REAL, PARAMETER :: gamm =0.4 !--- Max. stretched layer sigma ratio 97 REAL, PARAMETER :: rho =1.4 !--- Max tropopauses sigma ratio 98 REAL, PARAMETER :: o3t0 =1.E-7 !--- Nominal O3 vmr at tropopause 99 LOGICAL, PARAMETER :: lO3Tpara=.FALSE. !--- Parametrized O3 vmr at tropopause 100 LOGICAL, PARAMETER :: ldebug=.FALSE.!--- Force writefield_phy multiple outputs 101 REAL, PARAMETER :: ChemPTrMin=9.E+3 !--- Thresholds for minimum and maximum 102 REAL, PARAMETER :: ChemPTrMax=4.E+4 ! chemical tropopause pressure (Pa). 103 REAL, PARAMETER :: DynPTrMin =8.E+3 !--- Thresholds for minimum and maximum 104 REAL, PARAMETER :: DynPTrMax =4.E+4 ! dynamical tropopause pressure (Pa). 88 REAL, PARAMETER :: pTropUp=5.E+3 !--- Value < tropopause pressure (Pa) 89 REAL, PARAMETER :: gamm = 0.4 !--- Relative thickness of transitions 90 REAL, PARAMETER :: rho = 1.3 !--- Max tropopauses sigma ratio 91 REAL, PARAMETER :: o3t0 = 1.E-7 !--- Nominal O3 vmr at tropopause 92 LOGICAL, PARAMETER :: lo3tp=.FALSE. !--- Use parametrized O3 vmr at tropopause 105 93 106 94 CONTAINS … … 108 96 !------------------------------------------------------------------------------- 109 97 ! 110 SUBROUTINE regr_pr_time_av(fID, nam, julien, Ploc, Pre_in, Pre_ou, v3, Pgnd_ou,&111 time_in, lon_in, lat_in, Ptrp_ou)98 SUBROUTINE regr_pr_time_av(fID, nam, julien, pint_in, pint_ou, v3, & 99 time_in, lon_in, lat_in, pcen_in, ptrop_ou) 112 100 ! 113 101 !------------------------------------------------------------------------------- … … 124 112 USE slopes_m, ONLY: slopes 125 113 USE mod_phys_lmdz_mpi_data, ONLY: is_mpi_root 126 USE mod_grid_phy_lmdz, ONLY: nlon=>nbp_lon, nlat=>nbp_lat, nlev_ou=>nbp_lev114 USE mod_grid_phy_lmdz, ONLY: nbp_lon, nbp_lat, nbp_lev 127 115 USE mod_phys_lmdz_transfert_para, ONLY: scatter2d, scatter 128 116 USE phys_cal_mod, ONLY: calend, year_len, days_elapsed, jH_cur 129 117 !------------------------------------------------------------------------------- 130 118 ! Arguments: 131 INTEGER, INTENT(IN) :: fID!--- NetCDF file ID119 INTEGER, INTENT(IN) :: fID !--- NetCDF file ID 132 120 CHARACTER(LEN=13), INTENT(IN) :: nam(:) !--- NetCDF variables names 133 REAL, INTENT(IN) :: julien !--- Days since Jan 1st 134 CHARACTER(LEN=1), INTENT(IN) :: Ploc !--- Pressures locations 135 !--- File/LMDZ (resp. decreasing & increasing order) pressure, Pa 136 ! At cells centers or interfaces depending on "Ploc" keyword (C/I) 137 REAL, INTENT(IN) :: Pre_in(:) !--- in: file (nlev_in[+1]) 138 REAL, INTENT(IN) :: Pre_ou(:,:) !--- out: LMDZ (klon,nlev_ou[+1]) 139 REAL, INTENT(OUT) :: v3(:,:,:) !--- Regr. fld (klon,nlev_ou,n_var) 140 REAL, INTENT(IN), OPTIONAL :: Pgnd_ou(:) !--- LMDZ ground pressure (klon) 121 REAL, INTENT(IN) :: julien !--- Days since Jan 1st 122 REAL, INTENT(IN) :: pint_in(:) !--- Interfaces file Pres, Pa, ascending 123 REAL, INTENT(IN) :: pint_ou(:,:) !--- Interfaces LMDZ pressure, Pa (g,nbp_lev+1) 124 REAL, INTENT(OUT) :: v3(:,:,:) !--- Regridded field (klon,llm,SIZE(nam)) 141 125 REAL, INTENT(IN), OPTIONAL :: time_in(:) !--- Records times, in days 142 126 ! since Jan 1 of current year 143 REAL, INTENT(IN), OPTIONAL :: lon_in(:) !--- File longitudes vector (klon) 144 REAL, INTENT(IN), OPTIONAL :: lat_in(:) !--- File latitudes vector (klon) 145 REAL, INTENT(IN), OPTIONAL :: Ptrp_ou(:) !--- LMDZ tropopause pres (klon) 127 REAL, INTENT(IN), OPTIONAL :: lon_in(:) !--- Input/output longitudes vector 128 REAL, INTENT(IN), OPTIONAL :: lat_in(:) !--- Input/output latitudes vector 129 REAL, INTENT(IN), OPTIONAL :: pcen_in(:) !--- Mid-layers file pressure 130 REAL, INTENT(IN), OPTIONAL :: ptrop_ou(:)!--- Output tropopause pres (klon) 146 131 !------------------------------------------------------------------------------- 147 132 ! Local variables: … … 150 135 CHARACTER(LEN=80) :: sub 151 136 CHARACTER(LEN=320) :: str 152 INTEGER :: vID, ncerr, n_var, ibot, i out, nn153 INTEGER :: i, nlev_in, n_dim, itop, it rp, i0137 INTEGER :: vID, ncerr, n_var, ibot, ibo0, nn, itrp 138 INTEGER :: i, nlev_in, n_dim, itop, ito0, i0 154 139 LOGICAL :: lAdjTro !--- Need to adjust tropopause 155 140 REAL :: y_frac !--- Elapsed year fraction 156 141 REAL :: alpha, beta, al !--- For stretching/interpolation 157 142 REAL :: SigT_in, SigT_ou !--- Input and output tropopauses 158 REAL :: Sig_bot, Sig_top !--- Bounds of quasi-hat function 159 REAL :: Sig_bo0, Sig_to0 !--- Lower/upper tropopauses 160 REAL :: Sig_in (SIZE(Pre_in)) !--- Input field sigma levels 161 REAL :: Sig_ou (SIZE(Pre_ou,2)) !--- Output LMDZ sigma levels 162 REAL :: phi (SIZE(Pre_ou,2)) !--- Stretching exponent anomaly 163 REAL :: Pstr_ou(SIZE(Pre_ou,2)) !--- Stretched pressure levels 164 REAL :: Pres_ou(SIZE(Pre_ou,2)) !--- Pre_ou(i,:), reversed order 165 REAL, DIMENSION(nlon, nlat) :: pg1, pt1, ot1 166 REAL, DIMENSION(klon) :: Pgnd_in, Ptrp_in, Otrp_in 167 REAL, DIMENSION(klon) :: Ptrop_ou, Pgrnd_ou 168 ! * The following fields are scattered to the partial "physics" horizontal grid. 169 REAL, POINTER :: v2(:,:,:) !--- Current time ozone fields 143 REAL :: Sig_bot, Sig_top !--- Fully strained layer bounds 144 REAL :: Sig_bo0, Sig_to0 !--- Total strained layers bounds 145 REAL :: Sig_in(SIZE(pint_in)) !--- Input field sigma levels 146 REAL :: Sig_ou (nbp_lev+1) !--- Output LMDZ sigma levels 147 REAL :: phi (nbp_lev+1) !--- Stretching exponent anomaly 148 REAL :: pstr_ou(nbp_lev+1) !--- Stretched pressure levels 149 REAL :: pintou (nbp_lev+1) !--- pint_ou in reversed order 150 REAL :: v1(nbp_lon,nbp_lat,SIZE(pint_in)-1,SIZE(nam)) 151 REAL :: v2(klon, SIZE(pint_in)-1,SIZE(nam)) 152 ! v1: Field read/interpol at time "julien" on the global "dynamics" horiz. grid. 153 ! v2: Field scattered to the partial "physics" horizontal grid. 170 154 ! In the 2D file case, the values are the same for all longitudes. 171 ! "v2(i, k, l)" is at longitude-latitude "xlon(i)-xlat(i)" and name "nam(l)" 172 ! Both are: * if Ploc=='I' in pressure interval "press_in_edg(k:k+1)" 173 ! * if Ploc=='C' at pressure "press_in_cen(k)" 174 REAL, TARGET :: & 175 v2i(klon,SIZE(Pre_in)-1,SIZE(nam)), & !--- v2 in Ploc=='I' case 176 v2c(klon,SIZE(Pre_in) ,SIZE(nam)) !--- v2 in Ploc=='C' case 155 ! "v2(i, k, l)" is at longitude-latitude "xlon(i)-xlat(i)". 156 ! Both are for pressure interval "press_in_edg(k:k+1)]" and variable "nam(l)" 157 REAL, DIMENSION(nbp_lon, nbp_lat) :: ps1, pt1, ot1 158 REAL, DIMENSION(klon) :: ps2, pt2, ot2, ptropou 177 159 LOGICAL :: ll 178 !--- For debug179 REAL, DIMENSION(klon) :: Ptrop_in, Ptrop_ef180 REAL, DIMENSION(klon) :: dzStrain, dzStrain0181 REAL, DIMENSION(klon,SIZE(Pre_ou,2)) :: Pstrn_ou, phii182 160 !------------------------------------------------------------------------------- 183 161 sub="regr_pr_time_av" 184 nlev_in=SIZE(Pre_in); IF(Ploc=='I') nlev_in=nlev_in-1 185 IF(Ploc=='I') THEN; v2 => v2i; ELSE; v2 => v2c; END IF 186 CALL assert(SIZE(Pre_ou,1)==klon,TRIM(sub)//" Pre_ou klon") 187 CALL assert(SIZE(v3,1)==klon, TRIM(sub)//" v3 klon") 188 CALL assert(SIZE(v3,2)==nlev_ou, TRIM(sub)//" v3 nlev_ou") 189 IF(Ploc=='I') CALL assert(SIZE(Pre_ou,2)==nlev_ou+1,TRIM(sub)//" Pre_ou nlev_ou+1") 190 IF(Ploc=='C') CALL assert(SIZE(Pre_ou,2)==nlev_ou ,TRIM(sub)//" Pre_ou nlev_ou") 162 nlev_in=SIZE(pint_in)-1 163 CALL assert(SIZE(v3,1)==klon, TRIM(sub)//" v3 klon") 164 CALL assert(SIZE(v3,2)==nbp_lev, TRIM(sub)//" v3 nbp_lev") 191 165 n_var = assert_eq(SIZE(nam),SIZE(v3,3),TRIM(sub)//" v3 n_var") 192 IF(PRESENT(Pgnd_ou)) CALL assert(SIZE(Pgnd_ou)==klon,TRIM(sub)//" Pgnd_ou klon") 193 IF(PRESENT(lon_in)) CALL assert(SIZE(lon_in )==klon,TRIM(sub)//" lon_in klon") 194 IF(PRESENT(lat_in)) CALL assert(SIZE(lat_in )==klon,TRIM(sub)//" lat_in klon") 195 IF(PRESENT(Ptrp_ou)) CALL assert(SIZE(Ptrp_ou)==klon,TRIM(sub)//" Ptrp_ou klon") 196 lAdjTro=PRESENT(Ptrp_ou) 197 IF(lAdjTro) THEN 198 IF(.NOT.PRESENT(lat_in)) & 199 CALL abort_physic(sub, 'Missing lat_in (required if adjust_tropopause=T)', 1) 200 IF(.NOT.PRESENT(Pgnd_ou).AND.Ploc=='C') & 201 CALL abort_physic(sub, 'Missing ground Pr(required if adjust_tropopause=T)', 1) 202 IF(PRESENT(Pgnd_ou)) THEN; Pgrnd_ou=Pgnd_ou; ELSE; Pgrnd_ou=Pre_ou(:,1); END IF 203 END IF 166 CALL assert(SIZE(pint_ou,1)==klon ,TRIM(sub)//" pint_ou klon") 167 CALL assert(SIZE(pint_ou,2)==nbp_lev+1,TRIM(sub)//" pint_ou nbp_lev+1") 168 IF(PRESENT(lon_in)) CALL assert(SIZE(lon_in )==klon,TRIM(sub)//" lon_in klon") 169 IF(PRESENT(lat_in)) CALL assert(SIZE(lat_in )==klon,TRIM(sub)//" lat_in klon") 170 IF(PRESENT(ptrop_ou)) CALL assert(SIZE(ptrop_ou)==klon,TRIM(sub)//" ptrop_ou klon") 171 IF(PRESENT(pcen_in)) CALL assert(SIZE(pcen_in )==nlev_in,TRIM(sub)//" pcen_in") 172 lAdjTro=PRESENT(ptrop_ou) 173 IF(lAdjTro.AND.(.NOT.PRESENT(lat_in).OR..NOT.PRESENT(pcen_in))) & 174 CALL abort_physic(sub, 'Missing lat_in and/or pcen_in (adjust_tropopause=T)', 1) 204 175 205 176 !$OMP MASTER … … 208 179 !=== CHECK WHICH FIELDS ARE AVAILABLE IN THE INPUT FILE 209 180 IF(lfirst) THEN 210 lPrS file=lAdjTro.AND.NF90_INQ_VARID(fID,"ps" ,vID)==NF90_NOERR211 lPrT file=lAdjTro.AND.NF90_INQ_VARID(fID,"tropopause_air_pressure",vID)==NF90_NOERR212 lO3T file=lAdjTro.AND.NF90_INQ_VARID(fID,"tro3_at_tropopause" ,vID)==NF90_NOERR181 lPrSurf=NF90_INQ_VARID(fID,"ps" ,vID)==NF90_NOERR 182 lPrTrop=NF90_INQ_VARID(fID,"tropopause_air_pressure",vID)==NF90_NOERR 183 lO3Trop=NF90_INQ_VARID(fID,"tro3_at_tropopause" ,vID)==NF90_NOERR 213 184 CALL NF95_INQ_DIMID(fID,"time",vID) 214 185 CALL NF95_INQUIRE_DIMENSION(fID,vID,nclen=ntim_in) 215 186 linterp=PRESENT(time_in).AND.ntim_in==14 216 ALLOCATE(v1(nlon,nlat,nlev_in,n_var))217 187 IF(linterp) THEN 218 ALLOCATE(v1m(nlon,nlat,nlev_in,n_var),v1p(nlon,nlat,nlev_in,n_var)) 219 IF(lPrSfile) ALLOCATE(pgm(nlon,nlat),pgp(nlon,nlat)) 220 IF(lPrTfile) ALLOCATE(ptm(nlon,nlat),ptp(nlon,nlat)) 221 IF(lO3Tfile) ALLOCATE(otm(nlon,nlat),otp(nlon,nlat)) 188 ALLOCATE(v1m(nbp_lon,nbp_lat,nlev_in,n_var)) 189 ALLOCATE(v1p(nbp_lon,nbp_lat,nlev_in,n_var)) 190 ALLOCATE(psm(nbp_lon,nbp_lat),psp(nbp_lon,nbp_lat)) 191 ALLOCATE(ptm(nbp_lon,nbp_lat),ptp(nbp_lon,nbp_lat)) 192 IF(lO3Trop) ALLOCATE(otm(nbp_lon,nbp_lat),otp(nbp_lon,nbp_lat)) 222 193 END IF 223 194 !--- INITIAL INDEX: LOCATE A LAYER WELL ABOVE TROPOPAUSE (50hPa) 224 IF(lAdjTro) itrp0=locate(Pre_in,pTropUp) 225 CALL msg(linterp,'Monthly O3 files => ONLINE TIME INTERPOLATION.' ,sub) 226 CALL msg(lPrSfile,'Using GROUND PRESSURE from input O3 forcing file.',sub) 227 CALL msg(lAdjTro ,'o3 forcing file tropopause location uses:' ,sub) 228 IF(lPrTfile) THEN; str=' INPUT FILE PRESSURE' 229 ELSE IF(lO3Tfile) THEN; str=' INPUT FILE O3 CONCENTRATION' 230 ELSE IF(lO3Tpara) THEN; str=' PARAMETRIZED O3 concentration' 231 ELSE; str=' CONSTANT O3 concentration'; END IF 232 CALL msg(lAdjTro,TRIM(str)//' at tropopause') 195 IF(lAdjTro) itrp0=locate(pcen_in,pTropUp) 196 CALL msg(lPrSurf,'Using GROUND PRESSURE from input O3 forcing file.',sub) 197 CALL msg(linterp,'Monthly O3 files => ONLINE TIME INTERPOLATION.',sub) 198 CALL msg(lAdjTro,'o3 forcing file tropopause location uses:',sub) 199 IF(lPrTrop) THEN 200 CALL msg(lAdjTro,' PRESSURE AT TROPOPAUSE from file.') 201 ELSE IF(lO3Trop) THEN 202 CALL msg(lAdjTro,' O3 CONCENTRATION AT TROPOPAUSE from file.') 203 ELSE IF(lo3tp) THEN 204 CALL msg(lAdjTro,' PARAMETRIZED O3 concentration at tropopause.') 205 ELSE 206 CALL msg(lAdjTro,' CONSTANT O3 concentration at tropopause.') 207 END IF 233 208 END IF 234 209 … … 238 213 !=== TIME INTERPOLATION FOR MONTHLY INPUT FILES 239 214 IF(linterp) THEN 240 WRITE(str,'( a,f12.8,2(a,f5.1))')'Interpolating O3 at julian day ',julien,&241 ' fromfields at times ',time_in(irec),' and ', time_in(irec+1)215 WRITE(str,'(3(a,f12.8))')'Interpolating O3 at julian day ',julien,' from '& 216 &//'fields at times ',time_in(irec),' and ', time_in(irec+1) 242 217 CALL msg(.TRUE.,str,sub) 243 218 al=(time_in(irec+1)-julien)/(time_in(irec+1)-time_in(irec)) 244 219 v1=al*v1m+(1.-al)*v1p 245 IF(lPrS file) pg1=al*pgm+(1.-al)*pgp246 IF(lPrT file) pt1=al*ptm+(1.-al)*ptp247 IF(lO3T file) ot1=al*otm+(1.-al)*otp220 IF(lPrSurf) ps1=al*psm+(1.-al)*psp 221 IF(lPrTrop) pt1=al*ptm+(1.-al)*ptp 222 IF(lO3Trop) ot1=al*otm+(1.-al)*otp 248 223 END IF 249 224 END IF 250 225 !$OMP END MASTER 251 226 IF(lfirst) THEN 252 lfirst=.FALSE.; 253 IF(lAdjTro) 254 CALL bcast(lPr Sfile); CALL bcast(lPrTfile)255 CALL bcast(lO3T file); CALL bcast(linterp)227 lfirst=.FALSE.; CALL bcast(lfirst) 228 IF(lAdjTro) CALL bcast(itrp0) 229 CALL bcast(lPrTrop); CALL bcast(lPrSurf) 230 CALL bcast(lO3Trop); CALL bcast(linterp) 256 231 END IF 257 232 CALL scatter2d(v1,v2) 258 IF(lPrSfile) CALL scatter2d(pg1,Pgnd_in) 259 IF(lPrTfile) CALL scatter2d(pt1,Ptrp_in) 260 IF(lO3Tfile) CALL scatter2d(ot1,Otrp_in) 261 !--- No ground pressure in input file => choose it to be the one of LMDZ 262 IF(lAdjTro.AND..NOT.lPrSfile) Pgnd_in(:)=Pgrnd_ou(:) 263 264 !------------------------------------------------------------------------------- 265 IF(.NOT.lAdjTro) THEN !--- REGRID IN PRESSURE ; NO TROPOPAUSE ADJUSTMENT 266 !------------------------------------------------------------------------------- 233 !--- No "ps" in input file => assumed to be equal to current LMDZ ground press 234 IF(lPrSurf) THEN; CALL scatter2d(ps1,ps2); ELSE; ps2=pint_ou(:,1); END IF 235 IF(lPrTrop) CALL scatter2d(pt1,pt2) 236 IF(lO3Trop) CALL scatter2d(ot1,ot2) 237 238 !--- REGRID IN PRESSURE ; 3rd index inverted because "paprs" is decreasing 239 IF(.NOT.lAdjTro) THEN 267 240 DO i=1,klon 268 Pres_ou=Pre_ou(i,SIZE(Pre_ou,2):1:-1) !--- pplay & paprs are decreasing 269 IF(Ploc=='C') CALL regr_lint (1,v2(i,:,:), LOG(Pre_in(:)), & 270 LOG(Pres_ou(:)), v3(i,nlev_ou:1:-1,:)) 271 IF(Ploc=='I') CALL regr_conserv(1,v2(i,:,:), Pre_in(:) , & 272 Pres_ou(:) , v3(i,nlev_ou:1:-1,:), slopes(1,v2(i,:,:), Pre_in(:))) 241 pintou = pint_ou(i,nbp_lev+1:1:-1) 242 CALL regr_conserv(1,v2(i,:,:), pint_in(:), pintou(:), & 243 v3(i,nbp_lev:1:-1,:), slopes(1,v2(i,:,:), pint_in(:))) 273 244 END DO 274 !------------------------------------------------------------------------------- 275 ELSE !--- REGRID IN PRESSURE ; TROPOPAUSE ADJUSTMENT 276 !------------------------------------------------------------------------------- 245 ELSE 277 246 y_frac=(REAL(days_elapsed)+jH_cur)/year_len 278 247 … … 280 249 DO i=1,klon 281 250 282 !--- INPUT/OUTPUT (FILE/LMDZ) SIGMA LEVELS IN CURRENT COLUMN 283 Pres_ou = Pre_ou(i,SIZE(Pre_ou,2):1:-1)!--- pplay & paprs are decreasing 284 Sig_in(:) = Pre_in (:)/Pgnd_in(i) !--- increasing values 285 Sig_ou(:) = Pres_ou(:)/Pgnd_ou(i) !--- increasing values 286 287 !--- INPUT (FILE) SIGMA LEVEL AT TROPOPAUSE ; extreme values are filtered 288 ! to keep tropopause pressure realistic ; high values are usually due to 289 ! ozone hole fooling the crude chemical tropopause detection algorithm. 251 !--- LOCAL INPUT/OUTPUT (FILE/LMDZ) SIGMA LEVELS AT INTERFACES 252 pintou=pint_ou(i,nbp_lev+1:1:-1) !--- increasing values 253 Sig_in(:) = [pint_in(1:nlev_in+1)/ps2(i)] !--- increasing values 254 Sig_ou(:) = [pintou (1:nbp_lev)/ps2(i),1.0] !--- increasing values 255 256 !--- INPUT (FILE) AND OUTPUT (LMDZ) SIGMA LEVELS AT TROPOPAUSE 290 257 SigT_in = get_SigTrop(i,itrp) 291 SigT_in=MIN(SigT_in,ChemPTrMax/Pgnd_in(i)) !--- too low value filtered 292 SigT_in=MAX(SigT_in,ChemPTrMin/Pgnd_ou(i)) !--- too high value filtered 293 294 !--- OUTPUT (LMDZ) SIGMA LEVEL AT TROPOPAUSE ; too high variations of the 295 ! dynamical tropopause (especially in filaments) are conterbalanced with 296 ! a filter ensuring it stays within a certain distance around input (file) 297 ! tropopause, hence avoiding avoid a too thick stretched region ; a final 298 ! extra-safety filter keeps the tropopause pressure value realistic. 299 SigT_ou = Ptrp_ou(i)/Pgnd_ou(i) 300 IF(SigT_ou<SigT_in/rho) SigT_ou=SigT_in/rho !--- too low value w/r input 301 IF(SigT_ou>SigT_in*rho) SigT_ou=SigT_in*rho !--- too high value w/r input 302 SigT_ou=MIN(SigT_ou,DynPTrMax/Pgnd_ou(i)) !--- too low value filtered 303 SigT_ou=MAX(SigT_ou,DynPTrMin/Pgnd_ou(i)) !--- too high value filtered 304 Ptrop_ou(i)=SigT_ou*Pgnd_ou(i) 305 iout = locate(Sig_ou(:),SigT_ou) 306 307 !--- POWER LAW COEFFICIENT FOR TROPOPAUSES MATCHING 258 SigT_ou = ptrop_ou(i)/ps2(i) 259 260 !--- AVOID THE FILAMENTS WHICH WOULD NEED A VERY THICK STRETCHED REGION 261 IF(SigT_ou>SigT_in*rho) SigT_ou = SigT_in*rho 262 IF(SigT_ou<SigT_in/rho) SigT_ou = SigT_in/rho 263 ptropou(i)=SigT_ou*ps2(i) 264 265 !--- STRETCHING EXPONENT INCREMENT FOR SIMPLE POWER LAW 308 266 alpha = LOG(SigT_in/SigT_ou)/LOG(SigT_ou) 309 267 310 !--- DETERMINE STRETCHING DOMAIN UPPER AND LOWER BOUNDS311 Sig_bo 0 = MAX(SigT_in,SigT_ou) !--- lowest tropopause312 Sig_to 0 = MIN(SigT_in,SigT_ou) !--- highest tropopause313 beta = (Sig_bo0/Sig_to0)**gamm !--- stretching exponent 314 Sig_bot = MIN(Sig_bo0*beta,0.1*(9.+Sig_bo0)) !--- must be <1315 ibot = locate(Sig_ou(:),Sig_bot) !--- layer index316 IF(ibot-iout<2) THEN !--- at least one layer thick317 ibot=MIN(iout+2,nlev_ou); Sig_bot=Sig_ou(ibot)318 END IF 319 Sig_top = Sig_to0/beta !--- upper bound320 itop = locate(Sig_ou(:),Sig_top) !--- layer index321 IF(iout-itop<2) THEN !--- at least one layer thick322 itop=MAX(iout-2,1); Sig_top=Sig_ou(itop)323 END IF324 325 !--- STRETCHING POWER LAW LOCALIZATION FUNCTION: 326 ! 0 in [0,Sig_top] 0->1 in [Sig_top,SigT_ou]327 ! 0 in [Sig_bot,1] 1->0 in [SigT_ou, Sig_bot]268 !--- FULLY STRETCHED LAYER BOUNDS (FILE AND MODEL TROPOPAUSES) 269 Sig_bot = MAX(SigT_in,SigT_ou) ; ibot = locate(Sig_ou(:),Sig_bot) 270 Sig_top = MIN(SigT_in,SigT_ou) ; itop = locate(Sig_ou(:),Sig_top) 271 272 !--- PARTIALLY STRETCHED LAYER BOUNDS, ENSURING >0 DERIVATIVE 273 beta = LOG(Sig_top)/LOG(Sig_bot) 274 Sig_bo0 = Sig_bot ; IF(alpha<0.) Sig_bo0 = Sig_bot**(1/beta) 275 Sig_to0 = Sig_top ; IF(alpha>0.) Sig_to0 = Sig_top ** beta 276 277 !--- SOME ADDITIONAL MARGIN, PROPORTIONAL TO STRETCHED REGION THICKNESS 278 !--- gamma<log(Sig_bo0/|alpha|) to keep Sig_bo0<1 279 Sig_bo0 = MIN(Sig_bo0*EXP( gamm*ABS(alpha)), 0.95+(1.-0.95)*Sig_bo0) 280 Sig_to0 = Sig_to0*EXP(-gamm*ABS(alpha)) 281 ibo0 = locate(Sig_ou(:),Sig_bo0) 282 ito0 = locate(Sig_ou(:),Sig_to0) 283 284 !--- FUNCTION FOR STRETCHING LOCALISATION 285 ! 0 < Sig_to0 < Sig_top <= Sig_bo0 < Sig_bot < 1 328 286 phi(:)=0. 329 phi(itop+1:iout) = (1.-LOG(Sig_top)/LOG(Sig_ou(itop+1:iout)))& 330 *LOG(SigT_ou)/LOG(SigT_ou/Sig_top) 331 phi(iout+1:ibot) = (1.-LOG(Sig_bot)/LOG(Sig_ou(iout+1:ibot)))& 332 *LOG(SigT_ou)/LOG(SigT_ou/Sig_bot) 333 334 !--- LOCALY STRECHED OUTPUT (LMDZ) PRESSURE PROFILES (INCREASING ORDER) 335 Pstr_ou(:) = Pres_ou(:) * Sig_ou(:)**(alpha*phi(:)) 287 phi(itop+1:ibot) = 1. 288 phi(ito0+1:itop) = (1.-LOG(Sig_to0)/LOG(Sig_ou(ito0+1:itop)))& 289 *LOG(Sig_top)/LOG(Sig_top/Sig_to0) 290 phi(ibot+1:ibo0) = (1.-LOG(Sig_bo0)/LOG(Sig_ou(ibot+1:ibo0)))& 291 *LOG(Sig_bot)/LOG(Sig_bot/Sig_bo0) 292 293 !--- LOCAL STRAINED OUTPUT (LMDZ) PRESSURE PROFILES (INCREASING ORDER) 294 pstr_ou(:) = pintou(:) * Sig_ou(:)**(alpha*phi(:)) 336 295 337 296 !--- REGRID INPUT PROFILE ON STRAINED VERTICAL OUTPUT LEVELS 338 IF(Ploc=='C') CALL regr_lint (1, v2(i,:,:), LOG(Pre_in(:)), & 339 LOG(Pstr_ou(:)), v3(i,nlev_ou:1:-1,:)) 340 IF(Ploc=='I') CALL regr_conserv(1, v2(i,:,:), Pre_in(:) , & 341 Pstr_ou(:) , v3(i,nlev_ou:1:-1,:), slopes(1,v2(i,:,:), Pre_in(:))) 297 CALL regr_conserv(1, v2(i,:,:), pint_in(:), pstr_ou(:), & 298 v3(i,nbp_lev:1:-1,:), slopes(1,v2(i,:,:),pint_in(:))) 342 299 343 300 !--- CHECK CONCENTRATIONS. strato: 50ppbV-15ppmV ; tropo: 5ppbV-300ppbV. 344 i0=n lev_ou-locate(Pres_ou(:),Ptrop_ou(i))+1345 ll=check_ozone(v3(i, 1:i0 -1,1),lon_in(i),lat_in(i),1 ,'troposphere', &301 i0=nbp_lev-locate(pintou(:),ptropou(i))+1 302 ll=check_ozone(v3(i, 1:i0 ,1),lon_in(i),lat_in(i),1 ,'troposphere', & 346 303 5.E-9,3.0E-7) 347 304 ! IF(ll) CALL abort_physic(sub, 'Inconsistent O3 values in troposphere', 1) 348 ll=check_ozone(v3(i,i0:n lev_ou,1),lon_in(i),lat_in(i),i0,'stratosphere', &305 ll=check_ozone(v3(i,i0:nbp_lev,1),lon_in(i),lat_in(i),i0,'stratosphere', & 349 306 5.E-8,1.5E-5) 350 307 ! IF(ll) CALL abort_physic(sub, 'Inconsistent O3 values in stratosphere', 1) 351 308 352 IF(ldebug) THEN353 dzStrain0(i) = SIGN(7.*LOG(Sig_bo0/Sig_to0),SigT_in-SigT_ou)354 dzStrain (i) = SIGN(7.*LOG(Sig_bot/Sig_top),SigT_in-SigT_ou)355 Ptrop_in (i) = SigT_in*Pgnd_in(i)356 Pstrn_ou(i,:)= Pstr_ou357 phii(i,:) = phi(:)358 Ptrop_ef(i) = PTrop_chem(i, itrp, locate(Pres_ou(:),PTropUp), &359 Pres_ou(:), v3(:,nlev_ou:1:-1,1),o3trop=o3t0)360 END IF361 309 END DO 362 END IF363 IF(ldebug.AND.lAdjTro) THEN364 CALL writefield_phy('PreSt_ou' ,Pstrn_ou,SIZE(Pre_ou,2)) !--- Strained Pres365 CALL writefield_phy('dzStrain' ,dzStrain ,1) !--- Strained thickness366 CALL writefield_phy('dzStrain0',dzStrain0,1) !--- Tropopauses distance367 CALL writefield_phy('phi',phii,nlev_ou) !--- Localization function368 !--- Tropopauses pressures:369 CALL writefield_phy('PreTr_in',Ptrop_in,1) !--- Input and effective370 CALL writefield_phy('PreTr_ou',Ptrop_ou,1) !--- LMDz dyn tropopause371 CALL writefield_phy('PreTr_ef',Ptrop_ef,1) !--- Effective chem tropop372 END IF373 IF(ldebug) THEN374 CALL writefield_phy('Ozone_in',v2(:,:,1),nlev_in)!--- Raw input O3 field375 CALL writefield_phy('Ozone_ou',v3(:,:,1),nlev_ou)!--- Output ozone field376 CALL writefield_phy('Pres_ou' ,Pre_ou,SIZE(Pre_ou,2))!--- LMDZ Pressure377 310 END IF 378 311 … … 391 324 CALL get_3Dfields(v1) !--- Read ozone field(s) 392 325 IF(lAdjTro) THEN !--- Additional files for fields strain 393 IF(lPrS file) CALL get_2Dfield(pg1,"ps")394 IF(lPrT file) CALL get_2Dfield(pt1,"tropopause_air_pressure")395 IF(lO3T file) CALL get_2Dfield(ot1,"tro3_at_tropopause")326 IF(lPrSurf) CALL get_2Dfield(ps1,"ps") 327 IF(lPrTrop) CALL get_2Dfield(pt1,"tropopause_air_pressure") 328 IF(lO3Trop) CALL get_2Dfield(ot1,"tro3_at_tropopause") 396 329 END IF 397 330 ELSE !=== MONTHLY FILES: GET 2 NEAREST RECS … … 405 338 CALL get_3Dfields(v1m) !--- Read ozone field(s) 406 339 IF(lAdjTro) THEN !--- Additional files for fields strain 407 IF(lPrS file) CALL get_2Dfield(pgm,"ps")408 IF(lPrT file) CALL get_2Dfield(ptm,"tropopause_air_pressure")409 IF(lO3T file) CALL get_2Dfield(otm,"tro3_at_tropopause")340 IF(lPrSurf) CALL get_2Dfield(psm,"ps") 341 IF(lPrTrop) CALL get_2Dfield(ptm,"tropopause_air_pressure") 342 IF(lO3Trop) CALL get_2Dfield(otm,"tro3_at_tropopause") 410 343 END IF 411 344 ELSE !=== SHIFT FIELDS … … 416 349 v1m=v1p !--- Ozone fields 417 350 IF(lAdjTro) THEN !--- Additional files for fields strain 418 IF(lPrS file) pgm=pgp !--- Surface pressure419 IF(lPrT file) ptm=ptp !--- Tropopause pressure420 IF(lO3T file) otm=otp !--- Tropopause ozone351 IF(lPrSurf) psm=psp !--- Surface pressure 352 IF(lPrTrop) ptm=ptp !--- Tropopause pressure 353 IF(lO3Trop) otm=otp !--- Tropopause ozone 421 354 END IF 422 355 END IF … … 427 360 CALL get_3Dfields(v1p) !--- Read ozone field(s) 428 361 IF(lAdjTro) THEN !--- Additional files for fields strain 429 IF(lPrS file) CALL get_2Dfield(pgp,"ps")430 IF(lPrT file) CALL get_2Dfield(ptp,"tropopause_air_pressure")431 IF(lO3T file) CALL get_2Dfield(otp,"tro3_at_tropopause")362 IF(lPrSurf) CALL get_2Dfield(psp,"ps") 363 IF(lPrTrop) CALL get_2Dfield(ptp,"tropopause_air_pressure") 364 IF(lO3Trop) CALL get_2Dfield(otp,"tro3_at_tropopause") 432 365 END IF 433 366 irec=irec-1 … … 460 393 !--- Flip latitudes: ascending in input file, descending in "rlatu". 461 394 IF(n_dim==3) THEN 462 v(1,:) = v(1,n lat:1:-1)463 v(2:,:)= SPREAD(v(1,:),DIM=1,ncopies=n lon-1) !--- Duplication395 v(1,:) = v(1,nbp_lat:1:-1) 396 v(2:,:)= SPREAD(v(1,:),DIM=1,ncopies=nbp_lon-1) !--- Duplication 464 397 ELSE 465 v(:,:) = v(:,n lat:1:-1)398 v(:,:) = v(:,nbp_lat:1:-1) 466 399 END IF 467 400 … … 493 426 !--- Flip latitudes: ascending in input file, descending in "rlatu". 494 427 IF(n_dim==3) THEN 495 v(1,:,:,:) = v(1,n lat:1:-1,:,:)496 v(2:,:,:,:)= SPREAD(v(1,:,:,:),DIM=1,ncopies=n lon-1) !--- Duplication428 v(1,:,:,:) = v(1,nbp_lat:1:-1,:,:) 429 v(2:,:,:,:)= SPREAD(v(1,:,:,:),DIM=1,ncopies=nbp_lon-1) !--- Duplication 497 430 ELSE 498 v(:,:,:,:) = v(:,n lat:1:-1,:,:)431 v(:,:,:,:) = v(:,nbp_lat:1:-1,:,:) 499 432 END IF 500 433 … … 507 440 !------------------------------------------------------------------------------- 508 441 ! 509 FUNCTION get_SigTrop(ih,it) RESULT(out) 510 ! 511 !------------------------------------------------------------------------------- 512 ! Arguments: 513 REAL :: out 442 FUNCTION get_SigTrop(ih,it) 443 ! 444 !------------------------------------------------------------------------------- 445 ! Arguments: 514 446 INTEGER, INTENT(IN) :: ih 515 447 INTEGER, INTENT(OUT) :: it 516 !------------------------------------------------------------------------------- 517 !--- Pressure at tropopause read from the forcing file 518 IF(lPrTfile) THEN; out=Ptrp_in(ih)/Pgnd_in(ih); RETURN; END IF 519 520 !--- Chemical tropopause definition based on a particular threshold 521 IF(lO3Tfile) THEN; out=PTrop_chem(ih,it,itrp0,Pre_in,v2(:,:,1),Otrp_in(ih)) 522 ELSE IF(lO3Tpara) THEN; out=PTrop_chem(ih,it,itrp0,Pre_in,v2(:,:,1)) 523 ELSE ; out=PTrop_chem(ih,it,itrp0,Pre_in,v2(:,:,1),o3t0); END IF 524 out=out/Pgnd_in(ih) 448 REAL :: get_Sigtrop 449 !------------------------------------------------------------------------------- 450 !--- Pressure at tropopause is read in the forcing file 451 IF(lPrTrop) THEN !--- PrTrop KNOWN FROM FILE 452 get_SigTrop=pt2(ih)/ps2(ih); RETURN 453 END IF 454 !--- Chemical tropopause definition is used using a particular threshold 455 IF(lO3Trop) THEN !--- o3trop KNOWN FROM FILE 456 get_SigTrop=chem_tropopause(ih,it,itrp0,pint_in,v2(:,:,1),pcen_in,ot2(ih)) 457 ELSE IF(lo3tp) THEN !--- o3trop PARAMETRIZATION 458 get_SigTrop=chem_tropopause(ih,it,itrp0,pint_in,v2(:,:,1),pcen_in) 459 ELSE !--- o3trop CONSTANT 460 get_SigTrop=chem_tropopause(ih,it,itrp0,pint_in,v2(:,:,1),pcen_in,o3t0) 461 END IF 462 get_SigTrop=get_SigTrop/ps2(ih) 525 463 526 464 END FUNCTION get_SigTrop … … 531 469 !------------------------------------------------------------------------------- 532 470 ! 533 FUNCTION PTrop_chem(ih,it,it0,pres,o3,o3trop) RESULT(out)471 FUNCTION chem_tropopause(ih,it,it0,pint,o3,pcen,o3trop) 534 472 ! 535 473 !------------------------------------------------------------------------------- … … 546 484 !------------------------------------------------------------------------------- 547 485 ! Arguments: 548 REAL :: out!--- Pressure at tropopause486 REAL :: chem_tropopause !--- Pressure at tropopause 549 487 INTEGER, INTENT(IN) :: ih !--- Horizontal index 550 488 INTEGER, INTENT(OUT) :: it !--- Index of tropopause layer 551 489 INTEGER, INTENT(IN) :: it0 !--- Idx: higher than tropopause 552 REAL, INTENT(IN) :: p res(:) !--- Pressure profile, increasing490 REAL, INTENT(IN) :: pint(:) !--- Cells-interf Pr, increasing 553 491 REAL, INTENT(IN) :: o3(:,:) !--- Ozone field (pptV) 492 REAL, OPTIONAL, INTENT(IN) :: pcen(:) !--- Cells-center Pr, increasing 554 493 REAL, OPTIONAL, INTENT(IN) :: o3trop !--- Ozone at tropopause 555 494 !------------------------------------------------------------------------------- 556 495 ! Local variables: 557 REAL :: o3t!--- Ozone concent. at tropopause558 REAL :: al!--- Interpolation coefficient559 REAL :: coef!--- Coeff of latitude modulation496 REAL :: o3t !--- Ozone concent. at tropopause 497 REAL :: al !--- Interpolation coefficient 498 REAL :: coef !--- Coeff of latitude modulation 560 499 REAL, PARAMETER :: co3(3)=[91.,28.,20.] !--- Coeff for o3 at tropopause 561 500 !------------------------------------------------------------------------------- … … 572 511 it=it0; DO WHILE(o3(ih,it+1)>=o3t); it=it+1; END DO 573 512 al=(o3(ih,it)-o3t)/(o3(ih,it)-o3(ih,it+1)) 574 IF(Ploc=='C') out = pres(it)**(1.-al) * pres(it+1)**al 575 IF(Ploc=='I') out = SQRT(pres(it)**(1.-al) * pres(it+2)**al *pres(it+1)) 576 it = locate(pres(:), out) !--- pres(it)<Ptrop<pres(it+1) 577 578 END FUNCTION PTrop_chem 579 ! 580 !------------------------------------------------------------------------------- 581 582 583 !------------------------------------------------------------------------------- 584 ! 585 FUNCTION check_ozone(o3col, lon, lat, ilev0, layer, vmin, vmax) RESULT(out) 513 IF(PRESENT(pcen)) THEN 514 chem_tropopause = pcen(it)**(1.-al) * pcen(it+1)**al 515 ELSE 516 chem_tropopause = SQRT( pint(it)**(1.-al) * pint(it+2)**al * pint(it+1) ) 517 END IF 518 it = locate(pint(:), chem_tropopause) !--- pint(it)<ptrop<pint(it+1) 519 520 END FUNCTION chem_tropopause 521 ! 522 !------------------------------------------------------------------------------- 523 524 525 !------------------------------------------------------------------------------- 526 ! 527 FUNCTION check_ozone(o3col, lon, lat, ilev0, layer, vmin, vmax) 586 528 ! 587 529 !------------------------------------------------------------------------------- … … 589 531 !------------------------------------------------------------------------------- 590 532 ! Arguments: 591 LOGICAL :: out!--- .T. => some wrong values533 LOGICAL :: check_ozone !--- .T. => some wrong values 592 534 REAL, INTENT(IN) :: o3col(:), lon, lat 593 535 INTEGER, INTENT(IN) :: ilev0 … … 605 547 lmin=.FALSE.; IF(PRESENT(vmin)) lmin=COUNT(o3col<vmin)/=0 606 548 lmax=.FALSE.; IF(PRESENT(vmax)) lmax=COUNT(o3col>vmax)/=0 607 out=lmin.OR.lmax; IF(.NOT.out.OR.prt_level>100) RETURN549 check_ozone=lmin.OR.lmax; IF(.NOT.check_ozone) RETURN 608 550 609 551 !--- SOME TOO LOW VALUES FOUND
Note: See TracChangeset
for help on using the changeset viewer.