source: LMDZ4/branches/LMDZ4-dev-20091210/libf/phylmd/regr_pr_av_m.F90 @ 4104

Last change on this file since 4104 was 1263, checked in by lguez, 15 years ago

1) Reactivated ability to read ozone (that was deactivated because of
dependency on version of IOIPSL). Added ability to read a pressure
coordinate in Pa in "regr_lat_time_climoz".

2) Added the ability to read a second ozone climatology, corresponding to
daylight ozone:

-- "read_climoz" is now an integer variable, instead of a logical
variable.

-- Added argument "read_climoz" to "phys_state_var_init",
"phys_output_open" and "regr_lat_time_climoz".

-- Created new variable "ozone_daylight" for "hist*.nc" output files.

-- Added a third dimension to variable "wo" in module
"phys_state_var_mod" and variable "POZON" in "radlwsw": index 1 for
average day-night ozone, index 2 for daylight ozone.

-- Added a fourth dimension to variables "o3_in", "o3_regr_lat" and
"o3_out" in "regr_lat_time_climoz": index 1 for average day-night
ozone, index 2 for daylight ozone.

-- In "physiq", moved call to "conf_phys" before call to
"phys_state_var_init". Thus, "conf_phys" is now inside the block "if
(first)" instead of "IF (debut)". There were definitions of "bl95_b0"
and "bl95_b1" that were useless because the variables were overwritten
by "conf_phys". Removed those definitions.

-- In "radlwsw", we pass the average day-night ozone to "LW_LMDAR4"
and the daylight ozone, if we have it, to "SW_LMDAR4" or
"SW_AEROAR4". If we do not have a specific field for daylight ozone
then "SW_LMDAR4" or "SW_AEROAR4" just get the average day-night ozone.

-- "regr_lat_time_climoz" now manages latitudes where the input ozone
field is missing at all levels (polar night).

-- Encapsulated "radlwsw" in a module.

3) Modifications to make sequential and parallel versions of
"create_etat0_limit" almost identical:

-- In "dyn3dpar/create_etat0_limit.F". No need to call
"phys_state_var_init", removed "use phys_state_var_mod" statement. No
need for "clesphys.h", removed "include" statement.

-- In "dyn3dpar/etat0_netcdf.F". Added argument "tau_ratqs" in call to
"conf_phys" (this bug was already corrected in "dyn3d"). Moved call to
"inifilr" after call to "infotrac_init" (as in "dyn3d").

4) Other peripheral modifications:

-- Added procedures "nf95_get_att" and "nf95_def_var_scalar" in
NetCDF95 interface. Overloaded "nf95_put_var" with three more
procedures: "nf95_put_var_FourByteReal", "nf95_put_var_FourByteInt",
"nf95_put_var_1D_FourByteInt".

-- Overloaded "regr1_step_av" with one more procedure:
"regr14_step_av". Overloaded "regr3_lint" with one more procedure:
"regr34_lint".

-- Corrected call to "Init_Phys_lmdz" in "dyn3d/create_etat0_limit.F":
the last argument should be an array, not a scalar.

-- Encapsulated "conf_phys" in a module.

-- Splitted module "regr_pr" into "regr_pr_av_m" and "regr_pr_int_m".

5) Tests:

This revision was compared to revision 1259, with optimization options
"debug" and "dev", parallelization options "none", "mpi", "omp" and
"mpi_omp", 1 and 2 MPI processes, 1 and 2 OpenMP threads, with the
compiler "FORTRAN90/SX Version 2.0 for SX-8". Both programs
"create_etat0_limit" and "gcm" were tested. In all cases,
parallelization does not change the results. With "read_climoz = 0" in
the ".def" files, the results of revision 1259 and of this revision
are the same.

File size: 4.4 KB
Line 
1! $Id$
2module regr_pr_av_m
3
4  ! Author: Lionel GUEZ
5
6  implicit none
7
8contains
9
10  subroutine regr_pr_av(ncid, name, julien, press_in_edg, paprs, v3)
11
12    ! "regr_pr_av" stands for "regrid pressure averaging".
13    ! In this procedure:
14    ! -- the root process reads 2D latitude-pressure fields from a
15    !    NetCDF file, at a given day.
16    ! -- the fields are packed to the LMDZ horizontal "physics"
17    !    grid and scattered to all threads of all processes;
18    ! -- in all the threads of all the processes, the fields are regridded in
19    !    pressure to the LMDZ vertical grid.
20    ! We assume that, in the input file, the fields have 3 dimensions:
21    ! latitude, pressure, julian day.
22    ! We assume that the input fields are already on the "rlatu"
23    ! latitudes, excepth that latitudes are in ascending order in the input
24    ! file.
25    ! We assume that the inputs fields have the same pressure coordinate.
26
27    ! The target vertical LMDZ grid is the grid of layer boundaries.
28    ! Regridding in pressure is done by averaging a step function of pressure.
29
30    ! All the fields are regridded as a single multi-dimensional array
31    ! so it saves CPU time to call this procedure once for several NetCDF
32    ! variables rather than several times, each time for a single
33    ! NetCDF variable.
34
35    use dimphy, only: klon
36    use netcdf95, only: nf95_inq_varid, handle_err
37    use netcdf, only: nf90_get_var
38    use assert_m, only: assert
39    use assert_eq_m, only: assert_eq
40    use regr1_step_av_m, only: regr1_step_av
41    use mod_phys_lmdz_mpi_data, only: is_mpi_root
42
43    use mod_phys_lmdz_transfert_para, only: scatter2d
44    ! (pack to the LMDZ horizontal "physics" grid and scatter)
45
46    integer, intent(in):: ncid ! NetCDF ID of the file
47    character(len=*), intent(in):: name(:) ! of the NetCDF variables
48    integer, intent(in):: julien ! jour julien, 1 <= julien <= 360
49
50    real, intent(in):: press_in_edg(:)
51    ! edges of pressure intervals for input data, in Pa, in strictly
52    ! ascending order
53
54    real, intent(in):: paprs(:, :) ! (klon, llm + 1)
55    ! (pression pour chaque inter-couche, en Pa)
56
57    real, intent(out):: v3(:, :, :) ! (klon, llm, size(name))
58    ! regridded fields on the partial "physics" grid
59    ! "v3(i, k, l)" is at longitude "xlon(i)", latitude
60    ! "xlat(i)", in pressure interval "[paprs(i, k+1), paprs(i, k)]",
61    ! for NetCDF variable "name(l)".
62
63    ! Variables local to the procedure:
64
65    include "dimensions.h"
66    integer varid, ncerr ! for NetCDF
67
68    real  v1(iim, jjm + 1, size(press_in_edg) - 1, size(name))
69    ! input fields at day "julien", on the global "dynamics" horizontal grid
70    ! First dimension is for longitude.
71    ! The values are the same for all longitudes.
72    ! "v1(:, j, k, l)" is at latitude "rlatu(j)", for
73    ! pressure interval "[press_in_edg(k), press_in_edg(k+1)]" and
74    ! NetCDF variable "name(l)".
75
76    real v2(klon, size(press_in_edg) - 1, size(name))
77    ! fields scattered to the partial "physics" horizontal grid
78    ! "v2(i, k, l)" is at longitude "xlon(i)", latitude "xlat(i)",
79    ! for pressure interval "[press_in_edg(k), press_in_edg(k+1)]" and
80    ! NetCDF variable "name(l)".
81
82    integer i, n_var
83
84    !--------------------------------------------
85
86    call assert(size(v3, 1) == klon, size(v3, 2) == llm, "regr_pr_av v3 klon")
87    n_var = assert_eq(size(name), size(v3, 3), "regr_pr_av v3 n_var")
88    call assert(shape(paprs) == (/klon, llm+1/), "regr_pr_av paprs")
89
90    !$omp master
91    if (is_mpi_root) then
92       do i = 1, n_var
93          call nf95_inq_varid(ncid, name(i), varid)
94         
95          ! Get data at the right day from the input file:
96          ncerr = nf90_get_var(ncid, varid, v1(1, :, :, i), &
97               start=(/1, 1, julien/))
98          call handle_err("regr_pr_av nf90_get_var " // name(i), ncerr, ncid)
99       end do
100       
101       ! Latitudes are in ascending order in the input file while
102       ! "rlatu" is in descending order so we need to invert order:
103       v1(1, :, :, :) = v1(1, jjm+1:1:-1, :, :)
104
105       ! Duplicate on all longitudes:
106       v1(2:, :, :, :) = spread(v1(1, :, :, :), dim=1, ncopies=iim-1)
107    end if
108    !$omp end master
109
110    call scatter2d(v1, v2)
111
112    ! Regrid in pressure at each horizontal position:
113    do i = 1, klon
114       v3(i, llm:1:-1, :) = regr1_step_av(v2(i, :, :), press_in_edg, &
115            paprs(i, llm+1:1:-1))
116       ! (invert order of indices because "paprs" is in descending order)
117    end do
118
119  end subroutine regr_pr_av
120
121end module regr_pr_av_m
Note: See TracBrowser for help on using the repository browser.