Changeset 2788 for LMDZ5/trunk/libf/phylmd
- Timestamp:
- Feb 2, 2017, 7:01:50 PM (8 years ago)
- Location:
- LMDZ5/trunk/libf/phylmd
- Files:
-
- 3 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
LMDZ5/trunk/libf/phylmd/clesphys.h
r2730 r2788 87 87 LOGICAL :: ok_qch4 88 88 LOGICAL :: ok_conserv_q 89 LOGICAL :: adjust_tropopause 90 LOGICAL :: ok_daily_climoz 89 91 90 92 COMMON/clesphys/ & … … 130 132 & , iflag_rrtm, ok_strato,ok_hines, ok_qch4 & 131 133 & , iflag_ice_thermo, ok_gwd_rando, NSW, iflag_albedo & 132 & , ok_chlorophyll,ok_conserv_q, ok_all_xml 134 & , ok_chlorophyll,ok_conserv_q, adjust_tropopause & 135 & , ok_daily_climoz, ok_all_xml 133 136 134 137 save /clesphys/ -
LMDZ5/trunk/libf/phylmd/conf_phys_m.F90
r2785 r2788 222 222 LOGICAL,SAVE :: carbon_cycle_tr_omp 223 223 LOGICAL,SAVE :: carbon_cycle_cpl_omp 224 LOGICAL,SAVE :: adjust_tropopause_omp 225 LOGICAL,SAVE :: ok_daily_climoz_omp 224 226 225 227 INTEGER, INTENT(OUT):: read_climoz ! read ozone climatology, OpenMP shared … … 2035 2037 !Config Help = ... 2036 2038 ! 2039 ! 2040 adjust_tropopause = .FALSE. 2041 CALL getin('adjust_tropopause', adjust_tropopause_omp) 2042 ! 2043 !Config Key = adjust_tropopause 2044 !Config Desc = Adjust the ozone field from the climoz file by stretching its 2045 ! tropopause so that it matches the one of LMDZ. 2046 !Config Def = .FALSE. 2047 !Config Help = Ensure tropospheric ozone column conservation. 2048 ! 2049 ! 2050 ok_daily_climoz = .TRUE. 2051 CALL getin('ok_daily_climoz', ok_daily_climoz_omp) 2052 ! 2053 !Config Key = ok_daily_climoz 2054 !Config Desc = Interpolate in time the ozone forcings within ce0l. 2055 ! .TRUE. if backward compatibility is needed. 2056 !Config Def = .TRUE. 2057 !Config Help = .FALSE. ensure much fewer (no calendar dependency) 2058 ! and lighter monthly climoz files, inetrpolated in time at gcm run time. 2037 2059 ! 2038 2060 ecrit_LES_omp = 1./8. … … 2291 2313 callstats = callstats_omp 2292 2314 ecrit_LES = ecrit_LES_omp 2315 adjust_tropopause = adjust_tropopause_omp 2316 ok_daily_climoz = ok_daily_climoz_omp 2293 2317 carbon_cycle_tr = carbon_cycle_tr_omp 2294 2318 carbon_cycle_cpl = carbon_cycle_cpl_omp … … 2485 2509 write(lunout,*)' aerosol_couple = ', aerosol_couple 2486 2510 write(lunout,*)' flag_aerosol = ', flag_aerosol 2487 write(lunout,*)' flag_aerosol_strat 2511 write(lunout,*)' flag_aerosol_strat= ', flag_aerosol_strat 2488 2512 write(lunout,*)' new_aod = ', new_aod 2489 2513 write(lunout,*)' aer_type = ',aer_type … … 2568 2592 write(lunout,*) 'SSO gkwake=',gkwake 2569 2593 write(lunout,*) 'SSO gklift=',gklift 2594 write(lunout,*) 'adjust_tropopause = ', adjust_tropopause 2595 write(lunout,*) 'ok_daily_climoz = ',ok_daily_climoz 2570 2596 write(lunout,*) 'read_climoz = ', read_climoz 2571 2597 write(lunout,*) 'carbon_cycle_tr = ', carbon_cycle_tr -
LMDZ5/trunk/libf/phylmd/limit_read_mod.F90
r2770 r2788 223 223 ierr=NF90_INQUIRE(nid, UnlimitedDimID=ndimid) 224 224 ierr=NF90_INQUIRE_DIMENSION(nid, ndimid, len=nn) 225 WRITE(abort_message,'(a,2(i 0,a))')'limit.nc records number (',nn,') does no'//&225 WRITE(abort_message,'(a,2(i3,a))')'limit.nc records number (',nn,') does no'//& 226 226 't match year length (',year_len,')' 227 227 IF(nn/=year_len) CALL abort_physic(modname,abort_message,1) -
LMDZ5/trunk/libf/phylmd/open_climoz_m.F90
r1907 r2788 6 6 contains 7 7 8 subroutine open_climoz(ncid, press_in_ edg)8 subroutine open_climoz(ncid, press_in_cen, press_in_edg, time_in) 9 9 10 10 ! This procedure should be called once per "gcm" run, by a single 11 11 ! thread of each MPI process. 12 12 ! The root MPI process opens "climoz_LMDZ.nc", reads the pressure 13 ! levels and broadcasts them to the other processes.13 ! levels and the times and broadcasts them to the other processes. 14 14 15 15 ! We assume that, in "climoz_LMDZ.nc", the pressure levels are in hPa … … 21 21 use mod_phys_lmdz_mpi_data, only: is_mpi_root 22 22 use mod_phys_lmdz_mpi_transfert, only: bcast_mpi ! broadcast 23 USE phys_cal_mod, ONLY: calend, year_len, year_cur 23 24 25 ! OpenMP shares arguments: 24 26 integer, intent(out):: ncid ! of "climoz_LMDZ.nc", OpenMP shared 25 27 26 real, pointer:: press_in_edg(:) 27 ! edges of pressure intervals for ozone climatology, in Pa, in strictly 28 ! ascending order, OpenMP shared 28 ! pressure levels for ozone climatology, in Pa, strictly ascending order 29 real, pointer:: press_in_cen(:) !--- at cells centers 30 real, pointer:: press_in_edg(:) !--- at the interfaces (pressure intervals) 31 32 real, pointer:: time_in(:) 33 ! times of ozone climatology records, in days since Jan. 1st 0h 29 34 30 35 ! Variables local to the procedure: 31 36 32 real, pointer:: plev(:)33 ! (pressure levels for ozone climatology, converted to Pa, in strictly34 ! ascending order)35 36 37 integer varid ! for NetCDF 37 38 integer n_plev ! number of pressure levels in the input data 39 integer n_time ! number of time records in the input field 38 40 integer k 41 CHARACTER(LEN=80) :: modname 42 CHARACTER(LEN=320) :: msg 39 43 40 44 !--------------------------------------- 41 45 42 print *, "Call sequence information: open_climoz" 46 modname="open_climoz" 47 print *, "Call sequence information: "//TRIM(modname) 43 48 44 49 if (is_mpi_root) then … … 46 51 47 52 call nf95_inq_varid(ncid, "plev", varid) 48 call nf95_gw_var(ncid, varid, p lev)53 call nf95_gw_var(ncid, varid, press_in_cen) 49 54 ! Convert from hPa to Pa because "paprs" and "pplay" are in Pa: 50 plev = plev * 100. 51 n_plev = size(plev) 55 press_in_cen = press_in_cen * 100. 56 n_plev = size(press_in_cen) 57 CALL NF95_INQ_VARID(ncID, "time", varID) 58 CALL NF95_GW_VAR(ncid, varid, time_in) 59 n_time = SIZE(time_in) 60 IF(ALL([year_len,14]/=n_time)) THEN !--- Check records number 61 WRITE(msg,'(a,3(i4,a))')TRIM(modname)//': expected input file could be& 62 & monthly or daily (14 or ',year_len,' records for year ',year_cur,' a& 63 &nd calendar "'//TRIM(calend)//'"), but ',n_time,' records were found' 64 CALL abort_physic(modname, msg, 1) 65 END IF 66 52 67 end if 53 68 54 69 call bcast_mpi(n_plev) 55 if (.not. is_mpi_root) allocate(plev(n_plev)) 56 call bcast_mpi(plev) 57 70 if (.not. is_mpi_root) allocate(press_in_cen(n_plev)) 71 call bcast_mpi(press_in_cen) 72 call bcast_mpi(n_time) 73 if (.not. is_mpi_root) allocate(time_in(n_time)) 74 call bcast_mpi(time_in) 75 58 76 ! Compute edges of pressure intervals: 59 77 allocate(press_in_edg(n_plev + 1)) … … 61 79 press_in_edg(1) = 0. 62 80 ! We choose edges halfway in logarithm: 63 forall (k = 2:n_plev) press_in_edg(k) = sqrt(p lev(k - 1) * plev(k))81 forall (k = 2:n_plev) press_in_edg(k) = sqrt(press_in_cen(k - 1) * press_in_cen(k)) 64 82 press_in_edg(n_plev + 1) = huge(0.) 65 83 ! (infinity, but any value guaranteed to be greater than the … … 67 85 end if 68 86 call bcast_mpi(press_in_edg) 69 deallocate(plev) ! pointer87 ! deallocate(press_in_cen) ! pointer 70 88 71 89 end subroutine open_climoz -
LMDZ5/trunk/libf/phylmd/phys_local_var_mod.F90
r2752 r2788 487 487 !$OMP THREADPRIVATE(budg_sed_part) 488 488 #endif 489 REAL, ALLOCATABLE, SAVE, DIMENSION(:) :: pr_tropopause 490 !$OMP THREADPRIVATE(pr_tropopause) 489 491 490 492 CONTAINS … … 764 766 ALLOCATE (vsed_aer(klon,klev)) 765 767 #endif 768 ALLOCATE (pr_tropopause(klon)) 766 769 767 770 END SUBROUTINE phys_local_var_init … … 1018 1021 DEALLOCATE (budg_sed_part) 1019 1022 #endif 1023 DEALLOCATE (pr_tropopause) 1020 1024 1021 1025 END SUBROUTINE phys_local_var_end -
LMDZ5/trunk/libf/phylmd/physiq_mod.F90
r2784 r2788 35 35 USE change_srf_frac_mod 36 36 USE surface_data, ONLY : type_ocean, ok_veget, ok_snow 37 USE tropopause_m, ONLY: dyn_tropopause 37 38 #ifdef CPP_Dust 38 39 USE phytracr_spl_mod, ONLY: phytracr_spl … … 191 192 beta_prec, & 192 193 rneb, & 193 zxsnow,snowhgt,qsnow,to_ice,sissnow,runoff,albsol3_lic 194 zxsnow,snowhgt,qsnow,to_ice,sissnow,runoff,albsol3_lic, & 195 pr_tropopause 194 196 ! 195 197 USE phys_state_var_mod ! Variables sauvegardees de la physique … … 205 207 USE phys_output_ctrlout_mod 206 208 use open_climoz_m, only: open_climoz ! ozone climatology from a file 207 use regr_pr_ av_m, only: regr_pr_av209 use regr_pr_time_av_m, only: regr_pr_time_av 208 210 use netcdf95, only: nf95_close 209 211 !IM for NMC files … … 1006 1008 !$OMP THREADPRIVATE(first) 1007 1009 1008 integer, save:: read_climoz ! read ozone climatology 1010 ! VARIABLES RELATED TO OZONE CLIMATOLOGIES ; all are OpenMP shared 1011 ! Note that pressure vectors are in Pa and in stricly ascending order 1012 INTEGER,SAVE :: read_climoz ! Read ozone climatology 1009 1013 ! (let it keep the default OpenMP shared attribute) 1010 1014 ! Allowed values are 0, 1 and 2 … … 1013 1017 ! 2: read two ozone climatologies, the average day and night 1014 1018 ! climatology and the daylight climatology 1015 1016 integer, save:: ncid_climoz ! NetCDF file containing ozone climatologies 1017 ! (let it keep the default OpenMP shared attribute) 1018 1019 real, pointer, save:: press_climoz(:) 1020 ! (let it keep the default OpenMP shared attribute) 1021 ! edges of pressure intervals for ozone climatologies, in Pa, in strictly 1022 ! ascending order 1023 1024 integer ro3i 1025 ! required time index in NetCDF file for the ozone fields, between 1 1026 ! and 360 1019 INTEGER,SAVE :: ncid_climoz ! NetCDF file identifier 1020 REAL, POINTER, SAVE :: press_cen_climoz(:) ! Pressure levels 1021 REAL, POINTER, SAVE :: press_edg_climoz(:) ! Edges of pressure intervals 1022 REAL, POINTER, SAVE :: time_climoz(:) ! Time vector 1023 CHARACTER(LEN=13), PARAMETER :: vars_climoz(2) & 1024 = ["tro3 ","tro3_daylight"] 1025 ! vars_climoz(1:read_climoz): variables names in climoz file. 1027 1026 1028 1027 INTEGER ierr … … 1671 1670 1672 1671 !$omp single 1673 IF (read_climoz >= 1) THEN 1674 CALL open_climoz(ncid_climoz, press_climoz) 1675 ENDIF 1672 IF (read_climoz >= 1) CALL open_climoz(ncid_climoz, press_cen_climoz, & 1673 press_edg_climoz, time_climoz) 1676 1674 !$omp end single 1677 1675 ! … … 1978 1976 wo(:,:,1)=ozonecm(latitude_deg, paprs,read_climoz,rjour=zzz) 1979 1977 ELSE 1980 ro3i = int((days_elapsed + jh_cur - jh_1jan) / year_len * 360.) + 1 1981 1982 IF (ro3i == 361) ro3i = 360 1983 ! (This should never occur, except perhaps because of roundup 1984 ! error. See documentation.) 1985 1986 IF (read_climoz == 1) THEN 1987 CALL regr_pr_av(ncid_climoz, (/"tro3"/), julien=ro3i, & 1988 press_in_edg=press_climoz, paprs=paprs, v3=wo) 1978 IF(adjust_tropopause) THEN 1979 WRITE(*,*)' >> Adjusting O3 field to match gcm tropopause.' 1980 CALL dyn_tropopause(t_seri, ztsol, paprs, pplay, presnivs, rot, & 1981 pr_tropopause) 1982 CALL regr_pr_time_av(ncid_climoz, vars_climoz(1:read_climoz), & 1983 days_elapsed+jh_cur-jh_1jan, press_edg_climoz, paprs, wo, & 1984 time_climoz, latitude_deg, press_cen_climoz, pr_tropopause) 1989 1985 ELSE 1990 ! read_climoz == 21991 CALL regr_pr_av(ncid_climoz, (/"tro3 ",&1992 "tro3_daylight"/), julien=ro3i, press_in_edg=press_climoz,&1993 paprs=paprs, v3=wo)1994 END IF1986 WRITE(*,*)' >> Interpolating O3 field directly on gcm levels.' 1987 CALL regr_pr_time_av(ncid_climoz, vars_climoz(1:read_climoz), & 1988 days_elapsed+jh_cur-jh_1jan, press_edg_climoz, paprs, wo, & 1989 time_climoz) 1990 END IF 1995 1991 ! Convert from mole fraction of ozone to column density of ozone in a 1996 1992 ! cell, in kDU: 1997 1993 FORALL (l = 1: read_climoz) wo(:, :, l) = wo(:, :, l) * rmo3 / rmd & 1998 1994 * zmasse / dobson_u / 1e3 1999 ! (By regridding ozone values for LMDZ only once perday, we1995 ! (By regridding ozone values for LMDZ only once a day, we 2000 1996 ! have already neglected the variation of pressure in one 2001 1997 ! day. So do not recompute "wo" at each time step even if … … 4465 4461 CALL nf95_close(ncid_climoz) 4466 4462 ENDIF 4467 DEALLOCATE(press_climoz) ! pointer 4463 DEALLOCATE(press_edg_climoz) ! pointer 4464 DEALLOCATE(press_cen_climoz) ! pointer 4468 4465 ENDIF 4469 4466 !$OMP END MASTER -
LMDZ5/trunk/libf/phylmd/regr_lat_time_coefoz_m.F90
r2440 r2788 41 41 42 42 use mod_grid_phy_lmdz, ONLY : nbp_lat 43 use regr 1_conserv_m, only: regr1_conserv44 use regr 3_lint_m, only: regr3_lint43 use regr_conserv_m, only: regr_conserv 44 use regr_lint_m, only: regr_lint 45 45 use netcdf95, only: nf95_open, nf95_close, nf95_inq_varid, handle_err, & 46 46 nf95_put_var, nf95_gw_var … … 84 84 ! Last dimension is month number.) 85 85 86 real, allocatable:: o3_par_out(:, :, :) ! (jjm + 1, n_plev, 360)86 real, allocatable:: o3_par_out(:, :, :) ! (jjm + 1, n_plev, ndays) 87 87 ! (regridded ozone parameter) 88 88 ! ("o3_par_out(j, l, day)" is at latitude "rlatu(j)", pressure … … 162 162 latitude = latitude / 180. * pi 163 163 n_lat = size(latitude) 164 ! We need to supply the latitudes to "regr 1_conserv" in164 ! We need to supply the latitudes to "regr_conserv" in 165 165 ! ascending order, so invert order if necessary: 166 166 desc_lat = latitude(1) > latitude(n_lat) … … 209 209 ! We average with respect to sine of latitude, which is 210 210 ! equivalent to weighting by cosine of latitude: 211 call regr 1_conserv(o3_par_in, xs = sin(lat_in_edg), &211 call regr_conserv(1, o3_par_in, xs = sin(lat_in_edg), & 212 212 xt = (/-1., sin((/boundslat_reg(nbp_lat-1:1:-1,south)/)), 1./), & 213 213 vt = v_regr_lat(nbp_lat:1:-1, :, 1:12)) … … 221 221 222 222 ! Regrid in time by linear interpolation: 223 o3_par_out = regr3_lint(v_regr_lat, tmidmonth, tmidday)223 call regr_lint(3, v_regr_lat, tmidmonth, tmidday, o3_par_out) 224 224 225 225 ! Write to file: -
LMDZ5/trunk/libf/phylmd/regr_pr_comb_coefoz_m.F90
r2346 r2788 76 76 use dimphy, only: klon 77 77 use mod_phys_lmdz_mpi_data, only: is_mpi_root 78 use regr_pr_ av_m, only: regr_pr_av78 use regr_pr_time_av_m, only: regr_pr_time_av 79 79 use regr_pr_int_m, only: regr_pr_int 80 80 use press_coefoz_m, only: press_in_edg, plev … … 128 128 !$omp end master 129 129 130 call regr_pr_ av(ncid, (/"a2 ", "a4 ", "a6 ", &131 "P_net_Mob", "r_Mob ", "temp_Mob ", "R_Het "/), julien, &130 call regr_pr_time_av(ncid, (/"a2 ", "a4 ", "a6 ", & 131 "P_net_Mob", "r_Mob ", "temp_Mob ", "R_Het "/), REAL(julien-1), & 132 132 press_in_edg, paprs, coefoz) 133 133 a2 = coefoz(:, :, 1) -
LMDZ5/trunk/libf/phylmd/regr_pr_int_m.F90
r2346 r2788 28 28 use netcdf, only: nf90_get_var 29 29 use assert_m, only: assert 30 use regr 1_lint_m, only: regr1_lint30 use regr_lint_m, only: regr_lint 31 31 use mod_phys_lmdz_mpi_data, only: is_mpi_root 32 32 use mod_grid_phy_lmdz, only: nbp_lon, nbp_lat, nbp_lev … … 97 97 ! Regrid in pressure at each horizontal position: 98 98 do i = 1, klon 99 v3(i, nbp_lev:1:-1) = regr1_lint(v2(i, :), (/0., plev/), pplay(i, nbp_lev:1:-1)) 99 call regr_lint(1, v2(i, :), (/0., plev/), pplay(i, nbp_lev:1:-1), & 100 v3(i, nbp_lev:1:-1)) 100 101 ! (invert order of indices because "pplay" is in descending order) 101 102 end do -
LMDZ5/trunk/libf/phylmd/regr_pr_o3_m.F90
r2440 r2788 28 28 use netcdf, only: nf90_nowrite, nf90_get_var 29 29 use assert_m, only: assert 30 use regr 1_conserv_m, only: regr1_conserv30 use regr_conserv_m, only: regr_conserv 31 31 use press_coefoz_m, only: press_in_edg 32 32 use time_phylmdz_mod, only: day_ref … … 75 75 ! Poles: 76 76 do j = 1, nbp_lat, nbp_lat-1 77 call regr 1_conserv(r_mob(j, :), press_in_edg, &77 call regr_conserv(1, r_mob(j, :), press_in_edg, & 78 78 p3d(1, j, nbp_lev + 1:1:-1), o3_mob_regr(1, j, nbp_lev:1:-1)) 79 79 ! (invert order of indices because "p3d" is in descending order) … … 83 83 do j = 2, nbp_lat-1 84 84 do i = 1, nbp_lon 85 call regr 1_conserv(r_mob(j, :), press_in_edg, &85 call regr_conserv(1, r_mob(j, :), press_in_edg, & 86 86 p3d(i, j, nbp_lev + 1:1:-1), o3_mob_regr(i, j, nbp_lev:1:-1)) 87 87 ! (invert order of indices because "p3d" is in descending order)
Note: See TracChangeset
for help on using the changeset viewer.