source: LMDZ5/trunk/libf/dyn3dpar/limit_netcdf.F90 @ 1508

Last change on this file since 1508 was 1508, checked in by jghattas, 13 years ago
  • Add specific treatement for file histmth_sst.nc and histmth_sic.nc : these files have the same format as histmth.nc files written during a previous LMDZ run. The files contains 12 monthly values of SST and sea-ice cover.
  • Remove specific treatement for file amipbc_sst_1x1_clim.nc and amipbc_sic_1x1_clim.nc : use option amipbc_sst_1x1.nc and amipbc_sic_1x1.nc.
  • Removed logical fracterre and the part where fracterre=F. The code doesn't change behavior.
  • All text output are under control prt_level.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 26.4 KB
RevLine 
[1000]1!
[1279]2! $Id: limit_netcdf.F90 1508 2011-04-15 13:05:34Z jghattas $
[1319]3!-------------------------------------------------------------------------------
[1000]4!
[1319]5SUBROUTINE limit_netcdf(interbar, extrap, oldice, masque)
6!
7!-------------------------------------------------------------------------------
8! Author : L. Fairhead, 27/01/94
9!-------------------------------------------------------------------------------
10! Purpose: Boundary conditions files building for new model using climatologies.
11!          Both grids have to be regular.
12!-------------------------------------------------------------------------------
13! Note: This routine is designed to work for Earth
14!-------------------------------------------------------------------------------
15! Modification history:
16!  * 23/03/1994: Z. X. Li
17!  *    09/1999: L. Fairhead (netcdf reading in LMDZ.3.3)
18!  *    07/2001: P. Le Van
19!  *    11/2009: L. Guez     (ozone day & night climatos, see etat0_netcdf.F90)
20!  *    12/2009: D. Cugnet   (f77->f90, calendars, files from coupled runs)
21!-------------------------------------------------------------------------------
[1425]22  USE control_mod
[1279]23#ifdef CPP_EARTH
[1319]24  USE dimphy
25  USE ioipsl,             ONLY : ioget_year_len
26  USE phys_state_var_mod, ONLY : pctsrf
27  USE netcdf,             ONLY : NF90_OPEN,    NF90_CREATE,  NF90_CLOSE,       &
28                   NF90_DEF_DIM, NF90_DEF_VAR, NF90_PUT_VAR, NF90_PUT_ATT,     &
29                   NF90_NOERR,   NF90_NOWRITE, NF90_DOUBLE,  NF90_GLOBAL,      &
[1425]30                   NF90_CLOBBER, NF90_ENDDEF,  NF90_UNLIMITED, NF90_FLOAT
[1323]31  USE inter_barxy_m, only: inter_barxy
[1319]32#endif
33  IMPLICIT NONE
34!-------------------------------------------------------------------------------
35! Arguments:
[1000]36#include "dimensions.h"
37#include "paramet.h"
[1319]38#include "iniprint.h"
39  LOGICAL,                    INTENT(IN) :: interbar ! barycentric interpolation
40  LOGICAL,                    INTENT(IN) :: extrap   ! SST extrapolation flag
41  LOGICAL,                    INTENT(IN) :: oldice   ! old way ice computation
42  REAL, DIMENSION(iip1,jjp1), INTENT(IN) :: masque   ! land mask
43#ifndef CPP_EARTH
[1508]44  CALL abort_gcm('limit_netcdf','Earth-specific routine, needs Earth physics',1)
[1319]45#else
46!-------------------------------------------------------------------------------
47! Local variables:
[1000]48#include "logic.h"
49#include "comvert.h"
50#include "comgeom2.h"
51#include "comconst.h"
52#include "indicesol.h"
53
[1319]54!--- INPUT NETCDF FILES NAMES --------------------------------------------------
55  CHARACTER(LEN=25) :: icefile, sstfile, dumstr
56  CHARACTER(LEN=25), PARAMETER :: famipsst='amipbc_sst_1x1.nc        ',        &
57                                  famipsic='amipbc_sic_1x1.nc        ',        &
58                                  fcpldsst='cpl_atm_sst.nc           ',        &
59                                  fcpldsic='cpl_atm_sic.nc           ',        &
[1508]60                                  fhistsst='histmth_sst.nc           ',        &
61                                  fhistsic='histmth_sic.nc           ',        &
[1319]62                                  frugo   ='Rugos.nc                 ',        &
63                                  falbe   ='Albedo.nc                '
[1508]64  CHARACTER(LEN=10) :: varname
[1319]65!--- OUTPUT VARIABLES FOR NETCDF FILE ------------------------------------------
66  REAL,   DIMENSION(klon)                :: fi_ice, verif
67  REAL,   DIMENSION(:,:),   POINTER      :: phy_rug=>NULL(), phy_ice=>NULL()
68  REAL,   DIMENSION(:,:),   POINTER      :: phy_sst=>NULL(), phy_alb=>NULL()
69  REAL,   DIMENSION(:,:),   ALLOCATABLE  :: phy_bil
70  REAL,   DIMENSION(:,:,:), ALLOCATABLE  :: pctsrf_t
71  INTEGER                                :: nbad
[1000]72
[1319]73!--- VARIABLES FOR OUTPUT FILE WRITING -----------------------------------------
74  INTEGER :: ierr, nid, ndim, ntim, k
75  INTEGER, DIMENSION(2) :: dims
76  INTEGER :: id_tim,  id_SST,  id_BILS, id_RUG, id_ALB
77  INTEGER :: id_FOCE, id_FSIC, id_FTER, id_FLIC
78  INTEGER :: NF90_FORMAT
[1328]79  INTEGER :: ndays                   !--- Depending on the output calendar
[1000]80
[1319]81!--- INITIALIZATIONS -----------------------------------------------------------
82#ifdef NC_DOUBLE
83  NF90_FORMAT=NF90_DOUBLE
84#else
85  NF90_FORMAT=NF90_FLOAT
86#endif
[1000]87
[1319]88  pi    = 4.*ATAN(1.)
89  rad   = 6371229.
90  daysec= 86400.
91  omeg  = 2.*pi/daysec
92  g     = 9.8
93  kappa = 0.2857143
94  cpp   = 1004.70885
[1454]95  dtvr  = daysec/REAL(day_step)
[1319]96  CALL inigeom
[1000]97
[1319]98!--- Beware: anneeref (from gcm.def) is used to determine output time sampling
99  ndays=ioget_year_len(anneeref)
[1000]100
[1319]101!--- RUGOSITY TREATMENT --------------------------------------------------------
[1508]102  IF (prt_level>1) WRITE(lunout,*) 'Traitement de la rugosite'
103  varname='RUGOS'
104  CALL get_2Dfield(frugo,varname,'RUG',interbar,ndays,phy_rug,mask=masque(1:iim,:))
[1000]105
[1319]106!--- OCEAN TREATMENT -----------------------------------------------------------
[1508]107  IF (prt_level>1) WRITE(lunout,*) 'Traitement de la glace oceanique'
[1000]108
[1319]109! Input SIC file selection
[1508]110! Open file only to test if available
111  IF ( NF90_OPEN(TRIM(famipsic),NF90_NOWRITE,nid)==NF90_NOERR ) THEN
112     icefile=TRIM(famipsic)
113     varname='sicbcs'
114  ELSE IF( NF90_OPEN(TRIM(fcpldsic),NF90_NOWRITE,nid)==NF90_NOERR ) THEN
115     icefile=TRIM(fcpldsic)
116     varname='SIICECOV'
117  ELSE IF ( NF90_OPEN(TRIM(fhistsic),NF90_NOWRITE,nid)==NF90_NOERR ) THEN
118     icefile=TRIM(fhistsic)
119     varname='pourc_sic'
120  ELSE
121     WRITE(lunout,*) 'ERROR! No sea-ice input file was found.'
122     WRITE(lunout,*) 'One of following files must be availible : ',trim(famipsic),', ',trim(fcpldsic),', ',trim(fhistsic)
123     CALL abort_gcm('limit_netcdf','No sea-ice file was found',1)
124  END IF
[1319]125  ierr=NF90_CLOSE(nid)
[1508]126  IF (prt_level>=0) WRITE(lunout,*)'Pour la glace de mer a ete choisi le fichier '//TRIM(icefile)
[1000]127
[1508]128  CALL get_2Dfield(icefile,varname, 'SIC',interbar,ndays,phy_ice,flag=oldice)
[1000]129
[1319]130  ALLOCATE(pctsrf_t(klon,nbsrf,ndays))
131  DO k=1,ndays
[1508]132     fi_ice=phy_ice(:,k)
133     WHERE(fi_ice>=1.0  ) fi_ice=1.0
134     WHERE(fi_ice<EPSFRA) fi_ice=0.0
135     pctsrf_t(:,is_ter,k)=pctsrf(:,is_ter)       ! land soil
136     pctsrf_t(:,is_lic,k)=pctsrf(:,is_lic)       ! land ice
137     IF (icefile==trim(fcpldsic)) THEN           ! SIC=pICE*(1-LIC-TER)
138        pctsrf_t(:,is_sic,k)=fi_ice(:)*(1.-pctsrf(:,is_lic)-pctsrf(:,is_ter))
139     ELSE IF (icefile==trim(fhistsic)) THEN      ! SIC=pICE
140        pctsrf_t(:,is_sic,k)=fi_ice(:)
141     ELSE ! icefile==famipsic                    ! SIC=pICE-LIC
[1319]142        pctsrf_t(:,is_sic,k)=fi_ice-pctsrf_t(:,is_lic,k)
[1508]143     END IF
144     WHERE(pctsrf_t(:,is_sic,k)<=0) pctsrf_t(:,is_sic,k)=0.
145     WHERE(1.0-zmasq<EPSFRA)
[1319]146        pctsrf_t(:,is_sic,k)=0.0
147        pctsrf_t(:,is_oce,k)=0.0
[1508]148     ELSEWHERE
[1319]149        WHERE(pctsrf_t(:,is_sic,k)>=1.0-zmasq)
[1508]150           pctsrf_t(:,is_sic,k)=1.0-zmasq
151           pctsrf_t(:,is_oce,k)=0.0
[1319]152        ELSEWHERE
[1508]153           pctsrf_t(:,is_oce,k)=1.0-zmasq-pctsrf_t(:,is_sic,k)
154           WHERE(pctsrf_t(:,is_oce,k)<EPSFRA)
155              pctsrf_t(:,is_oce,k)=0.0
156              pctsrf_t(:,is_sic,k)=1.0-zmasq
157           END WHERE
[1319]158        END WHERE
[1508]159     END WHERE
160     nbad=COUNT(pctsrf_t(:,is_oce,k)<0.0)
161     IF(nbad>0) WRITE(lunout,*) 'pb sous maille pour nb point = ',nbad
162     nbad=COUNT(abs(sum(pctsrf_t(:,:,k),dim=2)-1.0)>EPSFRA)
163     IF(nbad>0) WRITE(lunout,*) 'pb sous surface pour nb points = ',nbad
[1319]164  END DO
165  DEALLOCATE(phy_ice)
[1000]166
[1319]167!--- SST TREATMENT -------------------------------------------------------------
[1508]168  IF (prt_level>1) WRITE(lunout,*) 'Traitement de la sst'
[1000]169
[1319]170! Input SST file selection
[1508]171! Open file only to test if available
172  IF ( NF90_OPEN(TRIM(famipsst),NF90_NOWRITE,nid)==NF90_NOERR ) THEN
173     sstfile=TRIM(famipsst)
174     varname='tosbcs'
175  ELSE IF ( NF90_OPEN(TRIM(fcpldsst),NF90_NOWRITE,nid)==NF90_NOERR ) THEN
176     sstfile=TRIM(fcpldsst)
177     varname='SISUTESW'
178  ELSE IF ( NF90_OPEN(TRIM(fhistsst),NF90_NOWRITE,nid)==NF90_NOERR ) THEN
179     sstfile=TRIM(fhistsst)
180     varname='tsol_oce'
181  ELSE
182     WRITE(lunout,*) 'ERROR! No sst input file was found.'
183     WRITE(lunout,*) 'One of following files must be availible : ',trim(famipsst),trim(fcpldsst),trim(fhistsst)
184     CALL abort_gcm('limit_netcdf','No sst file was found',1)
185  END IF
[1319]186  ierr=NF90_CLOSE(nid)
[1508]187  IF (prt_level>=0) WRITE(lunout,*)'Pour la temperature de mer a ete choisi un fichier '//TRIM(sstfile)
[1000]188
[1508]189  CALL get_2Dfield(sstfile,varname,'SST',interbar,ndays,phy_sst,flag=extrap)
[1000]190
[1319]191!--- ALBEDO TREATMENT ----------------------------------------------------------
[1508]192  IF (prt_level>1) WRITE(lunout,*) 'Traitement de l albedo'
193  varname='ALBEDO'
194  CALL get_2Dfield(falbe,varname,'ALB',interbar,ndays,phy_alb)
[1000]195
[1319]196!--- REFERENCE GROUND HEAT FLUX TREATMENT --------------------------------------
197  ALLOCATE(phy_bil(klon,ndays)); phy_bil=0.0
[1000]198
[1319]199!--- OUTPUT FILE WRITING -------------------------------------------------------
[1508]200  IF (prt_level>5) WRITE(lunout,*) 'Ecriture du fichier limit : debut'
[1000]201
[1319]202  !--- File creation
203  ierr=NF90_CREATE("limit.nc",NF90_CLOBBER,nid)
204  ierr=NF90_PUT_ATT(nid,NF90_GLOBAL,"title","Fichier conditions aux limites")
[1000]205
[1319]206  !--- Dimensions creation
207  ierr=NF90_DEF_DIM(nid,"points_physiques",klon,ndim)
208  ierr=NF90_DEF_DIM(nid,"time",NF90_UNLIMITED,ntim)
[1000]209
[1319]210  dims=(/ndim,ntim/)
[1000]211
[1319]212  !--- Variables creation
[1328]213  ierr=NF90_DEF_VAR(nid,"TEMPS",NF90_FORMAT,(/ntim/),id_tim)
[1319]214  ierr=NF90_DEF_VAR(nid,"FOCE", NF90_FORMAT,dims,id_FOCE)
215  ierr=NF90_DEF_VAR(nid,"FSIC", NF90_FORMAT,dims,id_FSIC)
216  ierr=NF90_DEF_VAR(nid,"FTER", NF90_FORMAT,dims,id_FTER)
217  ierr=NF90_DEF_VAR(nid,"FLIC", NF90_FORMAT,dims,id_FLIC)
218  ierr=NF90_DEF_VAR(nid,"SST",  NF90_FORMAT,dims,id_SST)
219  ierr=NF90_DEF_VAR(nid,"BILS", NF90_FORMAT,dims,id_BILS)
220  ierr=NF90_DEF_VAR(nid,"ALB",  NF90_FORMAT,dims,id_ALB)
221  ierr=NF90_DEF_VAR(nid,"RUG",  NF90_FORMAT,dims,id_RUG)
[1000]222
[1319]223  !--- Attributes creation
224  ierr=NF90_PUT_ATT(nid,id_tim, "title","Jour dans l annee")
225  ierr=NF90_PUT_ATT(nid,id_FOCE,"title","Fraction ocean")
226  ierr=NF90_PUT_ATT(nid,id_FSIC,"title","Fraction glace de mer")
227  ierr=NF90_PUT_ATT(nid,id_FTER,"title","Fraction terre")
228  ierr=NF90_PUT_ATT(nid,id_FLIC,"title","Fraction land ice")
229  ierr=NF90_PUT_ATT(nid,id_SST ,"title","Temperature superficielle de la mer")
230  ierr=NF90_PUT_ATT(nid,id_BILS,"title","Reference flux de chaleur au sol")
231  ierr=NF90_PUT_ATT(nid,id_ALB, "title","Albedo a la surface")
232  ierr=NF90_PUT_ATT(nid,id_RUG, "title","Rugosite")
[1000]233
[1319]234  ierr=NF90_ENDDEF(nid)
235
236  !--- Variables saving
[1328]237  ierr=NF90_PUT_VAR(nid,id_tim,(/(REAL(k),k=1,ndays)/))
[1319]238  ierr=NF90_PUT_VAR(nid,id_FOCE,pctsrf_t(:,is_oce,:),(/1,1/),(/klon,ndays/))
239  ierr=NF90_PUT_VAR(nid,id_FSIC,pctsrf_t(:,is_sic,:),(/1,1/),(/klon,ndays/))
240  ierr=NF90_PUT_VAR(nid,id_FTER,pctsrf_t(:,is_ter,:),(/1,1/),(/klon,ndays/))
241  ierr=NF90_PUT_VAR(nid,id_FLIC,pctsrf_t(:,is_lic,:),(/1,1/),(/klon,ndays/))
242  ierr=NF90_PUT_VAR(nid,id_SST ,phy_sst(:,:),(/1,1/),(/klon,ndays/))
243  ierr=NF90_PUT_VAR(nid,id_BILS,phy_bil(:,:),(/1,1/),(/klon,ndays/))
244  ierr=NF90_PUT_VAR(nid,id_ALB ,phy_alb(:,:),(/1,1/),(/klon,ndays/))
245  ierr=NF90_PUT_VAR(nid,id_RUG ,phy_rug(:,:),(/1,1/),(/klon,ndays/))
246
247  ierr=NF90_CLOSE(nid)
248
[1508]249  IF (prt_level>5) WRITE(lunout,*) 'Ecriture du fichier limit : fin'
250
[1319]251  DEALLOCATE(pctsrf_t,phy_sst,phy_bil,phy_alb,phy_rug)
[1000]252
253
[1319]254!===============================================================================
255!
256  CONTAINS
257!
258!===============================================================================
[1000]259
260
[1319]261!-------------------------------------------------------------------------------
262!
[1508]263SUBROUTINE get_2Dfield(fnam, varname, mode, ibar, ndays, champo, flag, mask)
[1319]264!
[1425]265!-----------------------------------------------------------------------------
[1319]266! Comments:
267!   There are two assumptions concerning the NetCDF files, that are satisfied
268!   with files that are conforming NC convention:
269!     1) The last dimension of the variables used is the time record.
270!     2) Dimensional variables have the same names as corresponding dimensions.
[1425]271!-----------------------------------------------------------------------------
272  USE netcdf, ONLY: NF90_OPEN, NF90_INQ_VARID, NF90_INQUIRE_VARIABLE, &
273       NF90_CLOSE, NF90_INQ_DIMID, NF90_INQUIRE_DIMENSION, NF90_GET_VAR, &
274       NF90_GET_ATT
[1319]275  USE dimphy, ONLY : klon
276  USE phys_state_var_mod, ONLY : pctsrf
[1403]277  USE control_mod
[1425]278  use pchsp_95_m, only: pchsp_95
279  use pchfe_95_m, only: pchfe_95
280  use arth_m, only: arth
281
[1319]282  IMPLICIT NONE
283#include "dimensions.h"
284#include "paramet.h"
285#include "comgeom2.h"
286#include "indicesol.h"
287#include "iniprint.h"
[1425]288!-----------------------------------------------------------------------------
[1319]289! Arguments:
290  CHARACTER(LEN=*),  INTENT(IN)     :: fnam     ! NetCDF file name
[1508]291  CHARACTER(LEN=10), INTENT(IN)     :: varname  ! NetCDF variable name
[1319]292  CHARACTER(LEN=3),  INTENT(IN)     :: mode     ! RUG, SIC, SST or ALB
293  LOGICAL,           INTENT(IN)     :: ibar     ! interp on pressure levels
294  INTEGER,           INTENT(IN)     :: ndays    ! current year number of days
[1508]295  REAL,    POINTER,  DIMENSION(:, :) :: champo  ! output field = f(t)
[1425]296  LOGICAL, OPTIONAL, INTENT(IN)     :: flag     ! extrapol. (SST) old ice (SIC)
297  REAL,    OPTIONAL, DIMENSION(iim, jjp1), INTENT(IN) :: mask
298!------------------------------------------------------------------------------
[1319]299! Local variables:
300!--- NetCDF
[1425]301  INTEGER :: ncid, varid                  ! NetCDF identifiers
[1319]302  CHARACTER(LEN=30)               :: dnam       ! dimension name
303!--- dimensions
304  INTEGER,           DIMENSION(4) :: dids       ! NetCDF dimensions identifiers
305  REAL, ALLOCATABLE, DIMENSION(:) :: dlon_ini   ! initial longitudes vector
306  REAL, ALLOCATABLE, DIMENSION(:) :: dlat_ini   ! initial latitudes  vector
307  REAL, POINTER,     DIMENSION(:) :: dlon, dlat ! reordered lon/lat  vectors
308!--- fields
309  INTEGER :: imdep, jmdep, lmdep                ! dimensions of 'champ'
[1425]310  REAL, ALLOCATABLE, DIMENSION(:, :) :: champ   ! wanted field on initial grid
[1319]311  REAL, ALLOCATABLE, DIMENSION(:) :: yder, timeyear
[1425]312  REAL,              DIMENSION(iim, jjp1) :: champint   ! interpolated field
313  REAL, ALLOCATABLE, DIMENSION(:, :, :)    :: champtime
314  REAL, ALLOCATABLE, DIMENSION(:, :, :)    :: champan
[1319]315!--- input files
316  CHARACTER(LEN=20)                 :: cal_in   ! calendar
[1508]317  CHARACTER(LEN=20)                 :: unit_sic ! attribute unit in sea-ice file
[1319]318  INTEGER                           :: ndays_in ! number of days
319!--- misc
320  INTEGER :: i, j, k, l                         ! loop counters
[1425]321  REAL, ALLOCATABLE, DIMENSION(:, :) :: work     ! used for extrapolation
[1319]322  CHARACTER(LEN=25)                 :: title    ! for messages
323  LOGICAL                           :: extrp    ! flag for extrapolation
[1508]324  LOGICAL                           :: oldice   ! flag for old way ice computation
[1319]325  REAL                              :: chmin, chmax
[1425]326  INTEGER ierr
327  integer n_extrap ! number of extrapolated points
328  logical skip
[1508]329
[1425]330!------------------------------------------------------------------------------
331!---Variables depending on keyword 'mode' -------------------------------------
[1319]332  NULLIFY(champo)
[1508]333
[1319]334  SELECT CASE(mode)
[1508]335  CASE('RUG'); title='Rugosite'
336  CASE('SIC'); title='Sea-ice'
337  CASE('SST'); title='SST'
338  CASE('ALB'); title='Albedo'
[1319]339  END SELECT
[1508]340 
341
[1425]342  extrp=.FALSE.
[1508]343  oldice=.FALSE.
[1425]344  IF ( PRESENT(flag) ) THEN
345    IF ( flag .AND. mode=='SST' ) extrp=.TRUE.
[1508]346    IF ( flag .AND. mode=='SIC' ) oldice=.TRUE.
[1425]347  END IF
[1000]348
[1425]349!--- GETTING SOME DIMENSIONAL VARIABLES FROM FILE -----------------------------
[1508]350  IF (prt_level>5) WRITE(lunout,*) ' Now reading file : ',fnam
[1425]351  ierr=NF90_OPEN(fnam, NF90_NOWRITE, ncid);             CALL ncerr(ierr, fnam)
[1508]352  ierr=NF90_INQ_VARID(ncid, trim(varname), varid);            CALL ncerr(ierr, fnam)
[1425]353  ierr=NF90_INQUIRE_VARIABLE(ncid, varid, dimids=dids); CALL ncerr(ierr, fnam)
[1404]354
[1508]355!--- Read unit for sea-ice variable only
356  IF (mode=='SIC') THEN
357     ierr=NF90_GET_ATT(ncid, varid, 'units', unit_sic)
358     IF(ierr/=NF90_NOERR) THEN
359        IF (prt_level>5) WRITE(lunout,*) 'No unit was given in sea-ice file. Take percentage as default value'
360        unit_sic='X'
361     ELSE
362        IF (prt_level>5) WRITE(lunout,*) ' Sea-ice cover has unit=',unit_sic
363     END IF
364  END IF
365
[1319]366!--- Longitude
[1425]367  ierr=NF90_INQUIRE_DIMENSION(ncid, dids(1), name=dnam, len=imdep)
368  CALL ncerr(ierr, fnam); ALLOCATE(dlon_ini(imdep), dlon(imdep))
369  ierr=NF90_INQ_VARID(ncid, dnam, varid);                CALL ncerr(ierr, fnam)
370  ierr=NF90_GET_VAR(ncid, varid, dlon_ini);              CALL ncerr(ierr, fnam)
[1508]371  IF (prt_level>5) WRITE(lunout, *) 'variable ', dnam, 'dimension ', imdep
[1000]372
[1319]373!--- Latitude
[1425]374  ierr=NF90_INQUIRE_DIMENSION(ncid, dids(2), name=dnam, len=jmdep)
375  CALL ncerr(ierr, fnam); ALLOCATE(dlat_ini(jmdep), dlat(jmdep))
376  ierr=NF90_INQ_VARID(ncid, dnam, varid);                CALL ncerr(ierr, fnam)
377  ierr=NF90_GET_VAR(ncid, varid, dlat_ini);              CALL ncerr(ierr, fnam)
[1508]378  IF (prt_level>5) WRITE(lunout, *) 'variable ', dnam, 'dimension ', jmdep
[1000]379
[1319]380!--- Time (variable is not needed - it is rebuilt - but calendar is)
[1425]381  ierr=NF90_INQUIRE_DIMENSION(ncid, dids(3), name=dnam, len=lmdep)
382  CALL ncerr(ierr, fnam); ALLOCATE(timeyear(lmdep))
383  ierr=NF90_INQ_VARID(ncid, dnam, varid);                CALL ncerr(ierr, fnam)
[1319]384  cal_in=' '
[1425]385  ierr=NF90_GET_ATT(ncid, varid, 'calendar', cal_in)
[1319]386  IF(ierr/=NF90_NOERR) THEN
387    SELECT CASE(mode)
[1425]388      CASE('RUG', 'ALB'); cal_in='360d'
389      CASE('SIC', 'SST'); cal_in='gregorian'
[1319]390    END SELECT
[1508]391    IF (prt_level>5) WRITE(lunout, *)'ATTENTION: variable "time" sans attribut "calendrier" ' &
[1425]392         // 'dans '//TRIM(fnam)//'. On choisit la valeur par defaut.'
[1319]393  END IF
[1508]394  IF (prt_level>5) WRITE(lunout, *) 'variable ', dnam, 'dimension ', lmdep, 'calendrier ', &
[1425]395       cal_in
[1000]396
[1508]397 
[1425]398!--- CONSTRUCTING THE INPUT TIME VECTOR FOR INTERPOLATION --------------------
[1319]399  !--- Determining input file number of days, depending on calendar
[1425]400  ndays_in=year_len(anneeref, cal_in)
[1000]401
[1319]402!--- Time vector reconstruction (time vector from file is not trusted)
403!--- If input records are not monthly, time sampling has to be constant !
[1425]404  timeyear=mid_months(anneeref, cal_in, lmdep)
[1508]405  IF (lmdep /= 12) WRITE(lunout,*) 'Note : les fichiers de ', TRIM(mode), &
406       ' ne comportent pas 12, mais ', lmdep, ' enregistrements.'
[1000]407
[1425]408!--- GETTING THE FIELD AND INTERPOLATING IT ----------------------------------
409  ALLOCATE(champ(imdep, jmdep), champtime(iim, jjp1, lmdep))
410  IF(extrp) ALLOCATE(work(imdep, jmdep))
[1000]411
[1508]412  IF (prt_level>5) WRITE(lunout, *)
413  IF (prt_level>5) WRITE(lunout,*)'LECTURE ET INTERPOLATION HORIZ. DE ', lmdep, ' CHAMPS.'
[1425]414  ierr=NF90_INQ_VARID(ncid, varname, varid);             CALL ncerr(ierr, fnam)
415  DO l=1, lmdep
416    ierr=NF90_GET_VAR(ncid, varid, champ, (/1, 1, l/), (/imdep, jmdep, 1/))
417    CALL ncerr(ierr, fnam)
418    CALL conf_dat2d(title, imdep, jmdep, dlon_ini, dlat_ini, dlon, dlat, &
419         champ, ibar)
[1000]420
[1425]421    IF (extrp) CALL extrapol(champ, imdep, jmdep, 999999., .TRUE., .TRUE., 2, &
422         work)
[1000]423
[1508]424    IF(ibar .AND. .NOT.oldice) THEN
425      IF(l==1 .AND. prt_level>5) THEN
426        WRITE(lunout, *) '-------------------------------------------------------------------------'
427        WRITE(lunout, *) 'Utilisation de l''interpolation barycentrique pour ',TRIM(title),' $$$'
428        WRITE(lunout, *) '-------------------------------------------------------------------------'
[1319]429      END IF
430      IF(mode=='RUG') champ=LOG(champ)
[1323]431      CALL inter_barxy(dlon, dlat(:jmdep-1), champ, rlonu(:iim),     &
432                         rlatv, champint)
[1319]433      IF(mode=='RUG') THEN
434        champint=EXP(champint)
435        WHERE(NINT(mask)/=1) champint=0.001
436      END IF
437    ELSE
438      SELECT CASE(mode)
[1323]439        CASE('RUG');       CALL rugosite(imdep, jmdep, dlon, dlat, champ,    &
[1319]440                                    iim, jjp1, rlonv, rlatu, champint, mask)
[1323]441        CASE('SIC');       CALL sea_ice (imdep, jmdep, dlon, dlat, champ,    &
[1319]442                                    iim, jjp1, rlonv, rlatu, champint)
[1425]443        CASE('SST', 'ALB'); CALL grille_m(imdep, jmdep, dlon, dlat, champ,    &
[1319]444                                    iim, jjp1, rlonv, rlatu, champint)
445      END SELECT
446    END IF
[1425]447    champtime(:, :, l)=champint
[1319]448  END DO
[1425]449  ierr=NF90_CLOSE(ncid);                                 CALL ncerr(ierr, fnam)
[1000]450
[1425]451  DEALLOCATE(dlon_ini, dlat_ini, dlon, dlat, champ)
[1319]452  IF(extrp) DEALLOCATE(work)
[1000]453
[1425]454!--- TIME INTERPOLATION ------------------------------------------------------
[1508]455  IF (prt_level>5) THEN
456     WRITE(lunout, *)
457     WRITE(lunout, *)'INTERPOLATION TEMPORELLE.'
458     WRITE(lunout, *)' Vecteur temps en entree: ', timeyear
459     WRITE(lunout, *)' Vecteur temps en sortie de 0 a ', ndays
460  END IF
461
[1425]462  ALLOCATE(yder(lmdep), champan(iip1, jjp1, ndays))
463  skip = .false.
464  n_extrap = 0
465  DO j=1, jjp1
466    DO i=1, iim
467      yder = pchsp_95(timeyear, champtime(i, j, :), ibeg=2, iend=2, &
468           vc_beg=0., vc_end=0.)
469      CALL pchfe_95(timeyear, champtime(i, j, :), yder, skip, &
470           arth(0., real(ndays_in) / ndays, ndays), champan(i, j, :), ierr)
471      if (ierr < 0) stop 1
472      n_extrap = n_extrap + ierr
[1319]473    END DO
474  END DO
[1425]475  if (n_extrap /= 0) then
[1508]476     WRITE(lunout,*) "get_2Dfield pchfe_95: n_extrap = ", n_extrap
[1425]477  end if
478  champan(iip1, :, :)=champan(1, :, :)
479  DEALLOCATE(yder, champtime, timeyear)
[1000]480
[1319]481!--- Checking the result
[1425]482  DO j=1, jjp1
483    CALL minmax(iip1, champan(1, j, 10), chmin, chmax)
[1508]484    IF (prt_level>5) WRITE(lunout, *)' ',TRIM(title),' au temps 10 ', chmin, chmax, j
[1319]485  END DO
[1000]486
[1425]487!--- SPECIAL FILTER FOR SST: SST>271.38 --------------------------------------
[1319]488  IF(mode=='SST') THEN
[1508]489    IF (prt_level>5) WRITE(lunout, *) 'Filtrage de la SST: SST >= 271.38'
[1319]490    WHERE(champan<271.38) champan=271.38
491  END IF
[1000]492
[1425]493!--- SPECIAL FILTER FOR SIC: 0.0<SIC<1.0 -------------------------------------
[1319]494  IF(mode=='SIC') THEN
[1508]495    IF (prt_level>5) WRITE(lunout, *) 'Filtrage de la SIC: 0.0 < Sea-ice < 1.0'
496
497    IF (unit_sic=='1') THEN
498       ! Nothing to be done for sea-ice field is already in fraction of 1
499       ! This is the case for sea-ice in file cpl_atm_sic.nc
500       IF (prt_level>5) WRITE(lunout,*) 'Sea-ice field already in fraction of 1'
501    ELSE
502       ! Convert sea ice from percentage to fraction of 1
503       IF (prt_level>5) WRITE(lunout,*) 'Transformt sea-ice field from percentage to fraction of 1.'
504       champan(:, :, :)=champan(:, :, :)/100.
505    END IF
506
[1425]507    champan(iip1, :, :)=champan(1, :, :)
[1319]508    WHERE(champan>1.0) champan=1.0
509    WHERE(champan<0.0) champan=0.0
[1508]510 END IF
[1000]511
[1425]512!--- DYNAMICAL TO PHYSICAL GRID ----------------------------------------------
513  ALLOCATE(champo(klon, ndays))
514  DO k=1, ndays
515    CALL gr_dyn_fi(1, iip1, jjp1, klon, champan(1, 1, k), champo(1, k))
[1319]516  END DO
517  DEALLOCATE(champan)
[1328]518
[1319]519END SUBROUTINE get_2Dfield
520!
521!-------------------------------------------------------------------------------
[1000]522
523
524
[1319]525!-------------------------------------------------------------------------------
526!
527FUNCTION year_len(y,cal_in)
528!
529!-------------------------------------------------------------------------------
530  USE ioipsl, ONLY : ioget_calendar,ioconf_calendar,lock_calendar,ioget_year_len
531  IMPLICIT NONE
532!-------------------------------------------------------------------------------
533! Arguments:
534  INTEGER                       :: year_len
535  INTEGER,           INTENT(IN) :: y
536  CHARACTER(LEN=*),  INTENT(IN) :: cal_in
537!-------------------------------------------------------------------------------
538! Local variables:
539  CHARACTER(LEN=20)             :: cal_out              ! calendar (for outputs)
540!-------------------------------------------------------------------------------
541!--- Getting the input calendar to reset at the end of the function
542  CALL ioget_calendar(cal_out)
[1000]543
[1319]544!--- Unlocking calendar and setting it to wanted one
545  CALL lock_calendar(.FALSE.); CALL ioconf_calendar(TRIM(cal_in))
[1000]546
[1319]547!--- Getting the number of days in this year
548  year_len=ioget_year_len(y)
[1000]549
[1319]550!--- Back to original calendar
551  CALL lock_calendar(.FALSE.); CALL ioconf_calendar(TRIM(cal_out))
[1000]552
[1319]553END FUNCTION year_len
554!
555!-------------------------------------------------------------------------------
[1000]556
557
[1319]558!-------------------------------------------------------------------------------
559!
560FUNCTION mid_months(y,cal_in,nm)
561!
562!-------------------------------------------------------------------------------
563  USE ioipsl, ONLY : ioget_calendar,ioconf_calendar,lock_calendar,ioget_mon_len
564  IMPLICIT NONE
565!-------------------------------------------------------------------------------
566! Arguments:
567  INTEGER,                INTENT(IN) :: y               ! year
568  CHARACTER(LEN=*),       INTENT(IN) :: cal_in          ! calendar
569  INTEGER,                INTENT(IN) :: nm              ! months/year number
570  REAL,    DIMENSION(nm)             :: mid_months      ! mid-month times
571!-------------------------------------------------------------------------------
572! Local variables:
573  CHARACTER(LEN=99)                  :: mess            ! error message
574  CHARACTER(LEN=20)                  :: cal_out         ! calendar (for outputs)
575  INTEGER, DIMENSION(nm)             :: mnth            ! months lengths (days)
576  INTEGER                            :: m               ! months counter
577  INTEGER                            :: nd              ! number of days
578!-------------------------------------------------------------------------------
579  nd=year_len(y,cal_in)
[1000]580
[1319]581  IF(nm==12) THEN
[1000]582
[1319]583  !--- Getting the input calendar to reset at the end of the function
584    CALL ioget_calendar(cal_out)
[1000]585
[1319]586  !--- Unlocking calendar and setting it to wanted one
587    CALL lock_calendar(.FALSE.); CALL ioconf_calendar(TRIM(cal_in))
[1000]588
[1319]589  !--- Getting the length of each month
590    DO m=1,nm; mnth(m)=ioget_mon_len(y,m); END DO
[1000]591
[1319]592  !--- Back to original calendar
593    CALL lock_calendar(.FALSE.); CALL ioconf_calendar(TRIM(cal_out))
[1000]594
[1319]595  ELSE IF(MODULO(nd,nm)/=0) THEN
596    WRITE(mess,'(a,i3,a,i3,a)')'Unconsistent calendar: ',nd,' days/year, but ',&
597      nm,' months/year. Months number should divide days number.'
598    CALL abort_gcm('mid_months',TRIM(mess),1)
[1000]599
[1319]600  ELSE
601    mnth=(/(m,m=1,nm,nd/nm)/)
602  END IF
[1000]603
[1319]604!--- Mid-months times
[1454]605  mid_months(1)=0.5*REAL(mnth(1))
[1319]606  DO k=2,nm
[1454]607    mid_months(k)=mid_months(k-1)+0.5*REAL(mnth(k-1)+mnth(k))
[1319]608  END DO
[1000]609
[1319]610END FUNCTION mid_months
611!
612!-------------------------------------------------------------------------------
[1000]613
614
[1319]615!-------------------------------------------------------------------------------
616!
617SUBROUTINE ncerr(ncres,fnam)
618!
619!-------------------------------------------------------------------------------
620! Purpose: NetCDF errors handling.
621!-------------------------------------------------------------------------------
622  USE netcdf, ONLY : NF90_NOERR, NF90_STRERROR
623  IMPLICIT NONE
624!-------------------------------------------------------------------------------
625! Arguments:
626  INTEGER,          INTENT(IN) :: ncres
627  CHARACTER(LEN=*), INTENT(IN) :: fnam
628!-------------------------------------------------------------------------------
629#include "iniprint.h"
630  IF(ncres/=NF90_NOERR) THEN
631    WRITE(lunout,*)'Problem with file '//TRIM(fnam)//' in routine limit_netcdf.'
632    CALL abort_gcm('limit_netcdf',NF90_STRERROR(ncres),1)
633  END IF
[1000]634
[1319]635END SUBROUTINE ncerr
636!
637!-------------------------------------------------------------------------------
638
[1454]639#endif
640! of #ifdef CPP_EARTH
[1319]641
642END SUBROUTINE limit_netcdf
Note: See TracBrowser for help on using the repository browser.