source: LMDZ6/branches/Amaury_dev/libf/dynphy_lonlat/phylmd/etat0dyn_netcdf.F90 @ 5152

Last change on this file since 5152 was 5136, checked in by abarral, 4 months ago

Put comgeom.h, comgeom2.h into modules

File size: 22.6 KB
Line 
1MODULE etat0dyn
2
3  !*******************************************************************************
4  ! Purpose: Create dynamical initial state using atmospheric fields from a
5  !          database of atmospheric to initialize the model.
6  !-------------------------------------------------------------------------------
7  ! Comments:
8
9  !    *  This module is designed to work for Earth (and with ioipsl)
10
11  !    *  etat0dyn_netcdf routine can access to NetCDF data through the following
12  !  routine (to be called after restget):
13  !    CALL startget_dyn3d(varname, lon_in,  lat_in, pls, workvar,&
14  !                          champ, lon_in2, lat_in2)
15
16  !    *  Variables should have the following names in the NetCDF files:
17  !            'U'      : East ward wind              (in "ECDYN.nc")
18  !            'V'      : Northward wind              (in "ECDYN.nc")
19  !            'TEMP'   : Temperature                 (in "ECDYN.nc")
20  !            'R'      : Relative humidity           (in "ECDYN.nc")
21  !            'RELIEF' : High resolution orography   (in "Relief.nc")
22
23  !    * The land mask and corresponding weights can be:
24  !      1) already known (in particular if etat0dyn has been called before) ;
25  !         in this case, ANY(masque(:,:)/=-99999.) = .TRUE.
26  !      2) computed using the ocean mask from the ocean model (to ensure ocean
27  !         fractions are the same for atmosphere and ocean) for coupled runs.
28  !         File name: "o2a.nc"  ;  variable name: "OceMask"
29  !      3) computed from topography file "Relief.nc" for forced runs.
30
31  !   *   There is a big mess with the longitude size. Should it be iml or iml+1 ?
32  !  I have chosen to use the iml+1 as an argument to this routine and we declare
33  !  internaly smaller fields when needed. This needs to be cleared once and for
34  !  all in LMDZ. A convention is required.
35  !-------------------------------------------------------------------------------
36  USE ioipsl, ONLY: flininfo, flinopen, flinget, flinclo, histclo
37  USE lmdz_assert_eq, ONLY: assert_eq
38  USE comconst_mod, ONLY: pi, cpp, kappa
39  USE comvert_mod, ONLY: ap, bp, preff, pressure_exner
40  USE temps_mod, ONLY: annee_ref, day_ref, itau_dyn, itau_phy, start_time
41  USE lmdz_strings, ONLY: strLower
42  USE lmdz_iniprint, ONLY: lunout, prt_level
43  USE lmdz_comdissnew, ONLY: lstardis, nitergdiv, nitergrot, niterh, tetagdiv, &
44          tetagrot, tetatemp, coefdis, vert_prof_dissip
45  USE lmdz_comgeom2
46
47  IMPLICIT NONE
48
49  PRIVATE
50  PUBLIC :: etat0dyn_netcdf
51
52  INCLUDE "dimensions.h"
53  INCLUDE "paramet.h"
54  REAL, SAVE :: deg2rad
55  INTEGER, SAVE :: iml_dyn, jml_dyn, llm_dyn, ttm_dyn, fid_dyn
56  REAL, ALLOCATABLE, SAVE :: lon_dyn(:, :), lat_dyn(:, :), levdyn_ini(:)
57  CHARACTER(LEN = 120), PARAMETER :: dynfname = 'ECDYN.nc'
58
59CONTAINS
60
61  !-------------------------------------------------------------------------------
62
63  SUBROUTINE etat0dyn_netcdf(masque, phis)
64
65    !-------------------------------------------------------------------------------
66    ! Purpose: Create dynamical initial states.
67    !-------------------------------------------------------------------------------
68    ! Notes:  1) This routine is designed to work for Earth
69    !         2) If masque(:,:)/=-99999., masque and phis are already known.
70    !         Otherwise: compute it.
71    !-------------------------------------------------------------------------------
72    USE control_mod
73    USE regr_lat_time_coefoz_m, ONLY: regr_lat_time_coefoz
74    USE regr_pr_o3_m, ONLY: regr_pr_o3
75    USE press_coefoz_m, ONLY: press_coefoz
76    USE exner_hyb_m, ONLY: exner_hyb
77    USE exner_milieu_m, ONLY: exner_milieu
78    USE infotrac, ONLY: nqtot, tracers
79    USE lmdz_filtreg
80    USE lmdz_cppkeys_wrapper, ONLY: CPPKEY_INCA
81    USE lmdz_q_sat, ONLY: q_sat
82    IMPLICIT NONE
83    !-------------------------------------------------------------------------------
84    ! Arguments:
85    REAL, INTENT(INOUT) :: masque(iip1, jjp1)   !--- Land-ocean mask
86    REAL, INTENT(INOUT) :: phis  (iip1, jjp1)   !--- Ground geopotential
87    !-------------------------------------------------------------------------------
88    ! Local variables:
89    CHARACTER(LEN = 256) :: modname, fmt
90    INTEGER :: i, j, l, ji, itau, iday, iq
91    REAL :: xpn, xps, time, phystep
92    REAL, DIMENSION(iip1, jjp1) :: psol
93    REAL, DIMENSION(iip1, jjp1, llm + 1) :: p3d
94    REAL, DIMENSION(iip1, jjp1, llm) :: uvent, t3d, tpot, qsat, qd
95    REAL, DIMENSION(iip1, jjp1, llm) :: pk, pls, y, masse
96    REAL, DIMENSION(iip1, jjm, llm) :: vvent
97    REAL, DIMENSION(ip1jm, llm) :: pbarv
98    REAL, DIMENSION(ip1jmp1, llm) :: pbaru, phi, w
99    REAL, DIMENSION(ip1jmp1) :: pks
100    REAL, DIMENSION(iim) :: xppn, xpps
101    REAL, ALLOCATABLE :: q3d(:, :, :, :)
102    !-------------------------------------------------------------------------------
103    modname = 'etat0dyn_netcdf'
104
105    deg2rad = pi / 180.0
106    y(:, :, :) = 0  !ym warning unitialized variable
107
108    ! Compute psol AND tsol, knowing phis.
109    !*******************************************************************************
110    CALL start_init_dyn(rlonv, rlatu, rlonu, rlatv, phis, psol)
111
112    ! Mid-levels pressure computation
113    !*******************************************************************************
114    CALL pression(ip1jmp1, ap, bp, psol, p3d)             !--- Update p3d
115    IF(pressure_exner) THEN                               !--- Update pk, pks
116      CALL exner_hyb   (ip1jmp1, psol, p3d, pks, pk)
117    ELSE
118      CALL exner_milieu(ip1jmp1, psol, p3d, pks, pk)
119    END IF
120    pls(:, :, :) = preff * (pk(:, :, :) / cpp)**(1. / kappa)          !--- Update pls
121
122    ! Update uvent, vvent, t3d and tpot
123    !*******************************************************************************
124    uvent(:, :, :) = 0.0 ; vvent(:, :, :) = 0.0 ; t3d (:, :, :) = 0.0
125    CALL startget_dyn3d('u', rlonu, rlatu, pls, y, uvent, rlonv, rlatv)
126    CALL startget_dyn3d('v', rlonv, rlatv, pls(:, :jjm, :), y(:, :jjm, :), vvent, &
127            rlonu, rlatu(:jjm))
128    CALL startget_dyn3d('t', rlonv, rlatu, pls, y, t3d, rlonu, rlatv)
129    tpot(:, :, :) = t3d(:, :, :)
130    CALL startget_dyn3d('tpot', rlonv, rlatu, pls, pk, tpot, rlonu, rlatv)
131
132    WRITE(lunout, *) 'T3D min,max:', MINVAL(t3d(:, :, :)), MAXVAL(t3d(:, :, :))
133    WRITE(lunout, *) 'PLS min,max:', MINVAL(pls(:, :, :)), MAXVAL(pls(:, :, :))
134
135    ! Humidity at saturation computation
136    !*******************************************************************************
137    WRITE(lunout, *) 'avant q_sat'
138    CALL q_sat(llm * jjp1 * iip1, t3d, pls, qsat)
139    WRITE(lunout, *) 'apres q_sat'
140    WRITE(lunout, *) 'QSAT min,max:', MINVAL(qsat(:, :, :)), MAXVAL(qsat(:, :, :))
141    !  WRITE(lunout,*) 'QSAT :',qsat(10,20,:)
142    qd (:, :, :) = 0.0
143    CALL startget_dyn3d('q', rlonv, rlatu, pls, qsat, qd, rlonu, rlatv)
144    ALLOCATE(q3d(iip1, jjp1, llm, nqtot)); q3d(:, :, :, :) = 0.0 ; q3d(:, :, :, 1) = qd(:, :, :)
145    CALL flinclo(fid_dyn)
146
147    ! Parameterization of ozone chemistry:
148    !*******************************************************************************
149    ! Look for ozone tracer:
150    IF (CPPKEY_INCA) THEN
151      DO iq = 1, nqtot; IF(strLower(tracers(iq)%name)=="o3") EXIT;
152      END DO
153      IF(iq/=nqtot + 1) THEN
154        CALL regr_lat_time_coefoz
155        CALL press_coefoz
156        CALL regr_pr_o3(p3d, q3d(:, :, :, iq))
157        q3d(:, :, :, iq) = q3d(:, :, :, iq) * 48. / 29.                !--- Mole->mass fraction
158      END IF
159    END IF
160    q3d(iip1, :, :, :) = q3d(1, :, :, :)
161
162    ! Writing
163    !*******************************************************************************
164    CALL inidissip(lstardis, nitergdiv, nitergrot, niterh, tetagdiv, tetagrot, &
165            tetatemp, vert_prof_dissip)
166    WRITE(lunout, *)'sortie inidissip'
167    itau = 0
168    itau_dyn = 0
169    itau_phy = 0
170    iday = dayref + itau / day_step
171    time = FLOAT(itau - (iday - dayref) * day_step) / day_step
172    IF(time>1.) THEN
173      time = time - 1
174      iday = iday + 1
175    END IF
176    day_ref = dayref
177    annee_ref = anneeref
178    CALL geopot(ip1jmp1, tpot, pk, pks, phis, phi)
179    WRITE(lunout, *)'sortie geopot'
180    CALL caldyn0(itau, uvent, vvent, tpot, psol, masse, pk, phis, &
181            phi, w, pbaru, pbarv, time + iday - dayref)
182    WRITE(lunout, *)'sortie caldyn0'
183    start_time = 0.
184#ifdef CPP_PARA
185  CALL dynredem0_loc( "start.nc", dayref, phis)
186#else
187    CALL dynredem0("start.nc", dayref, phis)
188#endif
189    WRITE(lunout, *)'sortie dynredem0'
190#ifdef CPP_PARA
191  CALL dynredem1_loc( "start.nc", 0.0, vvent, uvent, tpot, q3d, masse, psol)
192#else
193    CALL dynredem1("start.nc", 0.0, vvent, uvent, tpot, q3d, masse, psol)
194#endif
195    WRITE(lunout, *)'sortie dynredem1'
196    CALL histclo()
197
198  END SUBROUTINE etat0dyn_netcdf
199
200  !-------------------------------------------------------------------------------
201
202
203  !-------------------------------------------------------------------------------
204
205  SUBROUTINE startget_dyn3d(var, lon_in, lat_in, pls, workvar, &
206          champ, lon_in2, lat_in2)
207
208
209    IMPLICIT NONE
210    !===============================================================================
211    ! Purpose: Compute some quantities (u,v,t,q,tpot) using variables U,V,TEMP and R
212    !     (3D fields) of file dynfname.
213    !-------------------------------------------------------------------------------
214    ! Note: An input auxilliary field "workvar" has to be specified in two cases:
215    !     * for "q":    the saturated humidity.
216    !     * for "tpot": the Exner function.
217    !===============================================================================
218    ! Arguments:
219    CHARACTER(LEN = *), INTENT(IN) :: var
220    REAL, INTENT(IN) :: lon_in(:)        ! dim (iml)
221    REAL, INTENT(IN) :: lat_in(:)        ! dim (jml)
222    REAL, INTENT(IN) :: pls    (:, :, :) ! dim (iml, jml, lml)
223    REAL, INTENT(IN) :: workvar(:, :, :) ! dim (iml, jml, lml)
224    REAL, INTENT(INOUT) :: champ  (:, :, :) ! dim (iml, jml, lml)
225    REAL, INTENT(IN) :: lon_in2(:)       ! dim (iml)
226    REAL, INTENT(IN) :: lat_in2(:)       ! dim (jml2)
227    !-------------------------------------------------------------------------------
228    ! Local variables:
229    CHARACTER(LEN = 10) :: vname
230    CHARACTER(LEN = 256) :: msg, modname = "startget_dyn3d"
231    INTEGER :: iml, jml, jml2, lml, il
232    REAL :: xppn, xpps
233    !-------------------------------------------------------------------------------
234    iml = assert_eq([SIZE(lon_in), SIZE(pls, 1), SIZE(workvar, 1), SIZE(champ, 1), &
235            SIZE(lon_in2)], TRIM(modname) // " iml")
236    jml = assert_eq(SIZE(lat_in), SIZE(pls, 2), SIZE(workvar, 2), SIZE(champ, 2), &
237            TRIM(modname) // " jml")
238    lml = assert_eq(SIZE(pls, 3), SIZE(workvar, 3), SIZE(champ, 3), &
239            TRIM(modname) // " lml")
240    jml2 = SIZE(lat_in2)
241
242    !--- CHECK IF THE FIELD IS KNOWN
243    SELECT CASE(var)
244    CASE('u');    vname = 'U'
245    CASE('v');    vname = 'V'
246    CASE('t');    vname = 'TEMP'
247    CASE('q');    vname = 'R';    msg = 'humidity as the saturated humidity'
248    CASE('tpot'); msg = 'potential temperature as the Exner function'
249    CASE DEFAULT; msg = 'No rule to extract variable ' // TRIM(var)
250    CALL abort_gcm(modname, TRIM(msg) // ' from any data set', 1)
251    END SELECT
252
253    !--- CHECK IF SOMETHING IS MISSING
254    IF((var=='tpot'.OR.var=='q').AND.MINVAL(workvar)==MAXVAL(workvar)) THEN
255      msg = 'Could not compute ' // TRIM(msg) // ' is missing or constant.'
256      CALL abort_gcm(modname, TRIM(msg), 1)
257    END IF
258
259    !--- INTERPOLATE 3D FIELD IF NEEDED
260    IF(var/='tpot') CALL start_inter_3d(TRIM(vname), lon_in, lat_in, lon_in2, &
261            lat_in2, pls, champ)
262
263    !--- COMPUTE THE REQUIRED FILED
264    SELECT CASE(var)
265    CASE('u'); DO il = 1, lml; champ(:, :, il) = champ(:, :, il) * cu(:, 1:jml);
266    END DO
267    champ(iml, :, :) = champ(1, :, :)                   !--- Eastward wind
268
269    CASE('v'); DO il = 1, lml; champ(:, :, il) = champ(:, :, il) * cv(:, 1:jml);
270    END DO
271    champ(iml, :, :) = champ(1, :, :)                   !--- Northward wind
272
273    CASE('tpot', 'q')
274      IF(var=='tpot') THEN; champ = champ * cpp / workvar !--- Potential temperature
275      ELSE;                 champ = champ * .01 * workvar !--- Relative humidity
276      WHERE(champ<0.) champ = 1.0E-10
277      END IF
278      DO il = 1, lml
279        xppn = SUM(aire(:, 1) * champ(:, 1, il)) / apoln
280        xpps = SUM(aire(:, jml) * champ(:, jml, il)) / apols
281        champ(:, 1, il) = xppn
282        champ(:, jml, il) = xpps
283      END DO
284    END SELECT
285
286  END SUBROUTINE startget_dyn3d
287
288  !-------------------------------------------------------------------------------
289
290
291  !-------------------------------------------------------------------------------
292
293  SUBROUTINE start_init_dyn(lon_in, lat_in, lon_in2, lat_in2, zs, psol)
294
295    !-------------------------------------------------------------------------------
296    IMPLICIT NONE
297    !===============================================================================
298    ! Purpose:   Compute psol, knowing phis.
299    !===============================================================================
300    ! Arguments:
301    REAL, INTENT(IN) :: lon_in (:), lat_in (:)    ! dim (iml) (jml)
302    REAL, INTENT(IN) :: lon_in2(:), lat_in2(:)    ! dim (iml) (jml2)
303    REAL, INTENT(IN) :: zs  (:, :)                  ! dim (iml,jml)
304    REAL, INTENT(OUT) :: psol(:, :)                  ! dim (iml,jml)
305    !-------------------------------------------------------------------------------
306    ! Local variables:
307    CHARACTER(LEN = 256) :: modname = 'start_init_dyn'
308    REAL :: date, dt
309    INTEGER :: iml, jml, jml2, itau(1)
310    REAL, ALLOCATABLE :: lon_rad(:), lon_ini(:), var_ana(:, :)
311    REAL, ALLOCATABLE :: lat_rad(:), lat_ini(:)
312    REAL, ALLOCATABLE :: z(:, :), ps(:, :), ts(:, :)
313    !-------------------------------------------------------------------------------
314    iml = assert_eq(SIZE(lon_in), SIZE(zs, 1), SIZE(psol, 1), SIZE(lon_in2), &
315            TRIM(modname) // " iml")
316    jml = assert_eq(SIZE(lat_in), SIZE(zs, 2), SIZE(psol, 2), TRIM(modname) // " jml")
317    jml2 = SIZE(lat_in2)
318
319    WRITE(lunout, *) 'Opening the surface analysis'
320    CALL flininfo(dynfname, iml_dyn, jml_dyn, llm_dyn, ttm_dyn, fid_dyn)
321    WRITE(lunout, *) 'Values read: ', iml_dyn, jml_dyn, llm_dyn, ttm_dyn
322
323    ALLOCATE(lon_dyn(iml_dyn, jml_dyn), lat_dyn(iml_dyn, jml_dyn))
324    ALLOCATE(levdyn_ini(llm_dyn))
325    CALL flinopen(dynfname, .FALSE., iml_dyn, jml_dyn, llm_dyn, &
326            lon_dyn, lat_dyn, levdyn_ini, ttm_dyn, itau, date, dt, fid_dyn)
327
328    !--- IF ANGLES ARE IN DEGREES, THEY ARE CONVERTED INTO RADIANS
329    ALLOCATE(lon_ini(iml_dyn), lat_ini(jml_dyn))
330    lon_ini(:) = lon_dyn(:, 1); IF(MAXVAL(lon_dyn)>pi) lon_ini = lon_ini * deg2rad
331    lat_ini(:) = lat_dyn(1, :); IF(MAXVAL(lat_dyn)>pi) lat_ini = lat_ini * deg2rad
332
333    ALLOCATE(var_ana(iml_dyn, jml_dyn), lon_rad(iml_dyn), lat_rad(jml_dyn))
334    CALL get_var_dyn('Z', z)                        !--- SURFACE GEOPOTENTIAL
335    CALL get_var_dyn('SP', ps)                      !--- SURFACE PRESSURE
336    CALL get_var_dyn('ST', ts)                      !--- SURFACE TEMPERATURE
337    !  CALL flinclo(fid_dyn)
338    DEALLOCATE(var_ana, lon_rad, lat_rad, lon_ini, lat_ini)
339
340    !--- PSOL IS COMPUTED IN PASCALS
341    psol(:iml - 1, :) = ps(:iml - 1, :) * (1.0 + (z(:iml - 1, :) - zs(:iml - 1, :)) / 287.0          &
342            / ts(:iml - 1, :))
343    psol(iml, :) = psol(1, :)
344    DEALLOCATE(z, ps, ts)
345    psol(:, 1) = SUM(aire(1:iml - 1, 1) * psol(1:iml - 1, 1)) / apoln  !--- NORTH POLE
346    psol(:, jml) = SUM(aire(1:iml - 1, jml) * psol(1:iml - 1, jml)) / apols  !--- SOUTH POLE
347
348  CONTAINS
349
350    !-------------------------------------------------------------------------------
351
352    SUBROUTINE get_var_dyn(title, field)
353
354      !-------------------------------------------------------------------------------
355      USE conf_dat_m, ONLY: conf_dat2d
356      IMPLICIT NONE
357      !-------------------------------------------------------------------------------
358      ! Arguments:
359      CHARACTER(LEN = *), INTENT(IN) :: title
360      REAL, ALLOCATABLE, INTENT(INOUT) :: field(:, :)
361      !-------------------------------------------------------------------------------
362      ! Local variables:
363      CHARACTER(LEN = 256) :: msg
364      INTEGER :: tllm
365      !-------------------------------------------------------------------------------
366      SELECT CASE(title)
367      CASE('Z');     tllm = 0;       msg = 'geopotential'
368      CASE('SP');    tllm = 0;       msg = 'surface pressure'
369      CASE('ST');    tllm = llm_dyn; msg = 'temperature'
370      END SELECT
371      IF(.NOT.ALLOCATED(field)) THEN
372        ALLOCATE(field(iml, jml))
373        CALL flinget(fid_dyn, title, iml_dyn, jml_dyn, tllm, ttm_dyn, 1, 1, var_ana)
374        CALL conf_dat2d(title, lon_ini, lat_ini, lon_rad, lat_rad, var_ana, .TRUE.)
375        CALL interp_startvar(title, .TRUE., lon_rad, lat_rad, var_ana, &
376                lon_in, lat_in, lon_in2, lat_in2, field)
377      ELSE IF(SIZE(field)/=SIZE(z)) THEN
378        msg = 'The ' // TRIM(msg) // ' field we have does not have the right size'
379        CALL abort_gcm(TRIM(modname), msg, 1)
380      END IF
381
382    END SUBROUTINE get_var_dyn
383
384    !-------------------------------------------------------------------------------
385
386  END SUBROUTINE start_init_dyn
387
388  !-------------------------------------------------------------------------------
389
390
391  !-------------------------------------------------------------------------------
392
393  SUBROUTINE start_inter_3d(var, lon_in, lat_in, lon_in2, lat_in2, pls_in, var3d)
394
395    !-------------------------------------------------------------------------------
396    USE conf_dat_m, ONLY: conf_dat3d
397    USE lmdz_libmath_pch, ONLY: pchsp_95, pchfe_95
398    USE lmdz_libmath, ONLY: minmax
399
400
401    IMPLICIT NONE
402    !-------------------------------------------------------------------------------
403    ! Arguments:
404    CHARACTER(LEN = *), INTENT(IN) :: var
405    REAL, INTENT(IN) :: lon_in(:), lat_in(:)   ! dim (iml) (jml)
406    REAL, INTENT(IN) :: lon_in2(:), lat_in2(:)  ! dim (iml) (jml2)
407    REAL, INTENT(IN) :: pls_in(:, :, :)           ! dim (iml,jml,lml)
408    REAL, INTENT(OUT) :: var3d (:, :, :)           ! dim (iml,jml,lml)
409    !-------------------------------------------------------------------------------
410    ! Local variables:
411    CHARACTER(LEN = 256) :: modname = 'start_inter_3d'
412    LOGICAL :: skip
413    REAL :: chmin, chmax
414    INTEGER :: iml, jml, lml, jml2, ii, ij, il, ierr
415    INTEGER :: n_extrap                             ! Extrapolated points number
416    REAL, ALLOCATABLE :: ax(:), lon_rad(:), lon_ini(:), lev_dyn(:), yder(:)
417    REAL, ALLOCATABLE :: ay(:), lat_rad(:), lat_ini(:), var_tmp3d(:, :, :)
418    REAL, ALLOCATABLE, SAVE :: var_ana3d(:, :, :)
419    !-------------------------------------------------------------------------------
420    iml = assert_eq(SIZE(lon_in), SIZE(lon_in2), SIZE(pls_in, 1), SIZE(var3d, 1), TRIM(modname) // " iml")
421    jml = assert_eq(SIZE(lat_in), SIZE(pls_in, 2), SIZE(var3d, 2), TRIM(modname) // " jml")
422    lml = assert_eq(SIZE(pls_in, 3), SIZE(var3d, 3), TRIM(modname) // " lml"); jml2 = SIZE(lat_in2)
423
424    WRITE(lunout, *)'Going into flinget to extract the 3D field.'
425    IF(.NOT.ALLOCATED(var_ana3d)) ALLOCATE(var_ana3d(iml_dyn, jml_dyn, llm_dyn))
426    CALL flinget(fid_dyn, var, iml_dyn, jml_dyn, llm_dyn, ttm_dyn, 1, 1, var_ana3d)
427
428    !--- ANGLES IN DEGREES ARE CONVERTED INTO RADIANS
429    ALLOCATE(lon_ini(iml_dyn), lat_ini(jml_dyn))
430    lon_ini(:) = lon_dyn(:, 1); IF(MAXVAL(lon_dyn)>pi) lon_ini = lon_ini * deg2rad
431    lat_ini(:) = lat_dyn(1, :); IF(MAXVAL(lat_dyn)>pi) lat_ini = lat_ini * deg2rad
432
433    !--- FIELDS ARE PROCESSED TO BE ON STANDARD ANGULAR DOMAINS
434    ALLOCATE(lon_rad(iml_dyn), lat_rad(jml_dyn), lev_dyn(llm_dyn))
435    CALL conf_dat3d(var, lon_ini, lat_ini, levdyn_ini, &
436            lon_rad, lat_rad, lev_dyn, var_ana3d, .TRUE.)
437    DEALLOCATE(lon_ini, lat_ini)
438
439    !--- COMPUTE THE REQUIRED FIELDS USING ROUTINE grid_noro
440    ALLOCATE(var_tmp3d(iml, jml, llm_dyn))
441    DO il = 1, llm_dyn
442      CALL interp_startvar(var, il==1, lon_rad, lat_rad, var_ana3d(:, :, il), &
443              lon_in, lat_in, lon_in2, lat_in2, var_tmp3d(:, :, il))
444    END DO
445    DEALLOCATE(lon_rad, lat_rad)
446
447    !--- VERTICAL INTERPOLATION FROM TOP OF ATMOSPHERE TO GROUND
448    ALLOCATE(ax(llm_dyn), ay(llm_dyn), yder(llm_dyn))
449    ax = lev_dyn(llm_dyn:1:-1)
450    skip = .FALSE.
451    n_extrap = 0
452    DO ij = 1, jml
453      DO ii = 1, iml - 1
454        ay = var_tmp3d(ii, ij, llm_dyn:1:-1)
455        yder = pchsp_95(ax, ay, ibeg = 2, iend = 2, vc_beg = 0., vc_end = 0.)
456        CALL pchfe_95(ax, ay, yder, skip, pls_in(ii, ij, lml:1:-1), &
457                var3d(ii, ij, lml:1:-1), ierr)
458        IF(ierr<0) CALL abort_gcm(TRIM(modname), 'error in pchfe_95', 1)
459        n_extrap = n_extrap + ierr
460      END DO
461    END DO
462    IF(n_extrap/=0) WRITE(lunout, *)TRIM(modname) // " pchfe_95: n_extrap=", n_extrap
463    var3d(iml, :, :) = var3d(1, :, :)
464
465  END SUBROUTINE start_inter_3d
466
467  !-------------------------------------------------------------------------------
468
469
470  !-------------------------------------------------------------------------------
471
472  SUBROUTINE interp_startvar(nam, ibeg, lon, lat, vari, lon1, lat1, lon2, lat2, varo)
473
474    !-------------------------------------------------------------------------------
475    USE inter_barxy_m, ONLY: inter_barxy
476    IMPLICIT NONE
477    !-------------------------------------------------------------------------------
478    ! Arguments:
479    CHARACTER(LEN = *), INTENT(IN) :: nam
480    LOGICAL, INTENT(IN) :: ibeg
481    REAL, INTENT(IN) :: lon(:), lat(:)   ! dim (ii) (jj)
482    REAL, INTENT(IN) :: vari(:, :)        ! dim (ii,jj)
483    REAL, INTENT(IN) :: lon1(:), lat1(:) ! dim (i1) (j1)
484    REAL, INTENT(IN) :: lon2(:), lat2(:) ! dim (i1) (j2)
485    REAL, INTENT(OUT) :: varo(:, :)        ! dim (i1) (j1)
486    !-------------------------------------------------------------------------------
487    ! Local variables:
488    CHARACTER(LEN = 256) :: modname = "interp_startvar"
489    INTEGER :: ii, jj, i1, j1, j2
490    REAL, ALLOCATABLE :: vtmp(:, :)
491    !-------------------------------------------------------------------------------
492    ii = assert_eq(SIZE(lon), SIZE(vari, 1), TRIM(modname) // " ii")
493    jj = assert_eq(SIZE(lat), SIZE(vari, 2), TRIM(modname) // " jj")
494    i1 = assert_eq(SIZE(lon1), SIZE(lon2), SIZE(varo, 1), TRIM(modname) // " i1")
495    j1 = assert_eq(SIZE(lat1), SIZE(varo, 2), TRIM(modname) // " j1")
496    j2 = SIZE(lat2)
497    ALLOCATE(vtmp(i1 - 1, j1))
498    IF(ibeg.AND.prt_level>1) THEN
499      WRITE(lunout, *)"---------------------------------------------------------"
500      WRITE(lunout, *)"$$$ Interpolation barycentrique pour " // TRIM(nam) // " $$$"
501      WRITE(lunout, *)"---------------------------------------------------------"
502    END IF
503    CALL inter_barxy(lon, lat(:jj - 1), vari, lon2(:i1 - 1), lat2, vtmp)
504    CALL gr_int_dyn(vtmp, varo, i1 - 1, j1)
505
506  END SUBROUTINE interp_startvar
507
508  !-------------------------------------------------------------------------------
509
510END MODULE etat0dyn
511
512!*******************************************************************************
Note: See TracBrowser for help on using the repository browser.