LMDZ
regr_pr_av_m.F90
Go to the documentation of this file.
1 ! $Id$
3 
4  ! Author: Lionel GUEZ
5 
6  implicit none
7 
8 contains
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, except that latitudes are in ascending order in the input
24  ! file.
25  ! We assume that all the inputs fields have the same coordinates.
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
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  integer varid, ncerr ! for NetCDF
66 
67  real v1(nbp_lon, nbp_lat, size(press_in_edg) - 1, size(name))
68  ! input fields at day "julien", on the global "dynamics" horizontal grid
69  ! First dimension is for longitude.
70  ! The values are the same for all longitudes.
71  ! "v1(:, j, k, l)" is at latitude "rlatu(j)", for
72  ! pressure interval "[press_in_edg(k), press_in_edg(k+1)]" and
73  ! NetCDF variable "name(l)".
74 
75  real v2(klon, size(press_in_edg) - 1, size(name))
76  ! fields scattered to the partial "physics" horizontal grid
77  ! "v2(i, k, l)" is at longitude "xlon(i)", latitude "xlat(i)",
78  ! for pressure interval "[press_in_edg(k), press_in_edg(k+1)]" and
79  ! NetCDF variable "name(l)".
80 
81  integer i, n_var
82 
83  !--------------------------------------------
84 
85  call assert(size(v3, 1) == klon, size(v3, 2) == nbp_lev, "regr_pr_av v3 klon")
86  n_var = assert_eq(size(name), size(v3, 3), "regr_pr_av v3 n_var")
87  call assert(shape(paprs) == (/klon, nbp_lev+1/), "regr_pr_av paprs")
88 
89  !$omp master
90  if (is_mpi_root) then
91  do i = 1, n_var
92  call nf95_inq_varid(ncid, trim(name(i)), varid)
93 
94  ! Get data at the right day from the input file:
95  ncerr = nf90_get_var(ncid, varid, v1(1, :, :, i), &
96  start=(/1, 1, julien/))
97  call handle_err("regr_pr_av nf90_get_var " // trim(name(i)), ncerr, &
98  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, nbp_lat:1:-1, :, :)
104 
105  ! Duplicate on all longitudes:
106  v1(2:, :, :, :) = spread(v1(1, :, :, :), dim=1, ncopies=nbp_lon-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, nbp_lev:1:-1, :) = regr1_step_av(v2(i, :, :), press_in_edg, &
115  paprs(i, nbp_lev+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 
121 end module regr_pr_av_m
subroutine handle_err(status)
subroutine regr_pr_av(ncid, name, julien, press_in_edg, paprs, v3)
integer, save klon
Definition: dimphy.F90:3
Definition: dimphy.F90:1