Ignore:
Timestamp:
Nov 17, 2020, 1:36:34 PM (4 years ago)
Author:
abierjon
Message:

Mars GCM:
Update utilities :
concat.F90

  • rewrite and simplify the handling of time and offset so that any file can be concatenated, including files from different years or stats file
  • use modulo to shift starting sols in concat.nc to values between 0 and 669
  • add a "adls" option in addition to "sol" or "ls" to add a Ls 1D variable

while keeping "sol" as the Time axis

  • add conservation of altitude attributes (long_name,units,positive)
  • enable absence of both hybrid (aps,bps) and sigma levels

solzenangle.F90

  • improve calculation for 1 sol file (stats) to use all local time data
  • read the starting sol in the file instead of asking it to the user (except for stats file) ; keep the possibility for user to change it
  • ask mean Ls value for stats file instead of sol number
  • fix crash when using "all variable" option (ticket #66)
  • fix bug on aps,bps by using GCM_layers dimension instead of altitude

localtime.F90

  • fix crash when using "all variable" option (ticket #66)
  • fix bug on aps,bps by using GCM_layers dimension instead of altitude

For all 3 utilities :

  • handle all ndim cases for the variables (ticket #52)
  • change "title" attribute into "long_name" by default (ticket #48)
  • extend size of long_name character string (ticket #57)
  • remove the use of #ifdef NC_DOUBLE (ticket #67)

AB

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/LMDZ.MARS/util/solzenangle.F90

    r2416 r2434  
    1515character (len=50)  file
    1616! file(): input file(s) names(s)
    17 character (len=30), dimension(15) :: notconcat
    18 ! notconcat(): names of the (15) variables that won't be concatenated
     17character (len=30), dimension(16) :: notprocessed
     18! notprocessed(): names of the (16) variables that won't be processed
    1919character (len=50), dimension(:), allocatable :: var
    20 ! var(): name(s) of variable(s) that will be concatenated
    21 character (len=50) :: tmpvar,title,units
     20! var(): name(s) of variable(s) that will be processed
     21character (len=100) :: tmpvar,long_name,units
    2222! tmpvar(): used to temporarily store a variable name
    23 ! title(): [netcdf] title attribute
     23! long_name(): [netcdf] long_name attribute
    2424! units(): [netcdf] units attribute
    2525character (len=100) :: filename,vartmp
     
    6262! ctldim: [netcdf] "controle" dim ID
    6363! timedim: [netcdf] "timedim" dim ID
     64integer :: gcmlayerdim ! NetCDF dimension ID for # of layers in GCM
    6465integer :: latvar,lonvar,altvar,ctlvar,timevar
    6566! latvar: [netcdf] ID of "latitude" variable
     
    7273! latlen: # of elements of lat() array
    7374! lonlen: # of elements of lon() array
    74 ! altvar: # of elements of alt() array
    75 ! ctlvar: # of elements of ctl() array
     75! altlen: # of elements of alt() array
     76! ctllen: # of elements of ctl() array
    7677! timelen: # of elements of time() array
    7778! timelen_tot:# =timelen or timelen+1 (if 1 more time to interpolate needed)
    7879integer :: nsol
    7980! nsol: # of sols in the input file AND # of elements of time() array in output
     81integer :: GCM_layers ! number of GCM atmospheric layers (may not be
     82! same as altlen if file is an output of zrecast)
    8083integer :: nout,latdimout,londimout,altdimout,timedimout,timevarout
    8184! nout: [netcdf] output file ID
     
    8588! timedimout: [netcdf] output time (dimension) ID
    8689! timevarout: [netcdf] ID of output "Time" variable
     90integer :: layerdimout ! NetCDF dimension ID for # of layers in GCM
    8791integer :: varidout
    8892! varidout: [netcdf] variable ID # (of a variable to write to the output file)
    89 integer :: Nnotconcat,var_ok
    90 ! Nnotconcat: # of (leading)variables that won't be concatenated
     93integer :: Nnotprocessed,var_ok
     94! Nnotprocessed: # of (leading)variables that won't be concatenated
    9195! var_ok: flag (0 or 1)
    9296integer, dimension(4) :: corner,edges,dim
     
    107111real :: sza ! solar zenith angle
    108112character (len=30) :: szastr ! to store the sza value in a string
    109 real :: starttimeoffset ! offset (in sols) of sol 0 in input file, wrt Ls=0
     113real :: startsol ! starting date (in sols) of sol 0 in input file, wrt Ls=0
    110114real :: tmpsol ! to temporarily store a sol value
    111115real :: tmpLs ! to temporarily store a Ls value
     
    121125! valid_range(2): [netcdf] interval in which a value is considered valid
    122126logical :: stats   ! stats=T when reading a "stats" kind of ile
     127real :: year_day_gcm = 669. ! number of sols in a year in GCM
     128
     129
    123130
    124131
     
    160167!==============================================================================
    161168
    162 notconcat(1)='Time'
    163 notconcat(2)='controle'
    164 notconcat(3)='rlonu'
    165 notconcat(4)='latitude'
    166 notconcat(5)='longitude'
    167 notconcat(6)='altitude'
    168 notconcat(7)='rlatv'
    169 notconcat(8)='aps'
    170 notconcat(9)='bps'
    171 notconcat(10)='ap'
    172 notconcat(11)='bp'
    173 notconcat(12)='cu'
    174 notconcat(13)='cv'
    175 notconcat(14)='aire'
    176 notconcat(15)='phisinit'
     169notprocessed(1)='Time'
     170notprocessed(2)='controle'
     171notprocessed(3)='rlonu'
     172notprocessed(4)='latitude'
     173notprocessed(5)='longitude'
     174notprocessed(6)='altitude'
     175notprocessed(7)='rlatv'
     176notprocessed(8)='aps'
     177notprocessed(9)='bps'
     178notprocessed(10)='ap'
     179notprocessed(11)='bp'
     180notprocessed(12)='soildepth'
     181notprocessed(13)='cu'
     182notprocessed(14)='cv'
     183notprocessed(15)='aire'
     184notprocessed(16)='phisinit'
    177185
    178186!==============================================================================
     
    180188!==============================================================================
    181189write(*,*)
    182    Nnotconcat=0
     190   Nnotprocessed=0
    183191do i=1,nbvarfile
    184192   ierr=NF_INQ_VARNAME(nid,i,vartmp)
    185193   ! vartmp now contains the "name" of variable of ID # i
    186194   var_ok=0
    187    do inter=1,15
    188       if (vartmp.eq.notconcat(inter)) then
     195   do inter=1,16
     196      if (vartmp.eq.notprocessed(inter)) then
    189197         var_ok=1
    190          Nnotconcat=Nnotconcat+1
     198         Nnotprocessed=Nnotprocessed+1
    191199      endif
    192200   enddo       
     
    194202enddo
    195203
    196 ! Nnotconcat: # of variables that won't be processed
     204! Nnotprocessed: # of variables that won't be processed
    197205! nbvarfile: total # of variables in file
    198 allocate(var(nbvarfile-Nnotconcat),stat=ierr)
     206allocate(var(nbvarfile-Nnotprocessed),stat=ierr)
    199207if (ierr.ne.0) then
    200   write(*,*) "Error: failed allocation of var(nbvarfile-Nnotconcat)"
     208  write(*,*) "Error: failed allocation of var(nbvarfile-Nnotprocessed)"
    201209  write(*,*) "  nbvarfile=",nbvarfile
    202   write(*,*) "  Nnotconcat=",Nnotconcat
     210  write(*,*) "  Nnotprocessed=",Nnotprocessed
    203211  stop
    204212endif
     
    218226
    219227if (tmpvar=="all") then
    220          nbvar=nbvarfile-Nnotconcat
    221          do j=Nnotconcat+1,nbvarfile
    222             ierr=nf_inq_varname(nid,j,var(j-Nnotconcat))
     228         nbvar=nbvarfile-Nnotprocessed
     229         do j=Nnotprocessed+1,nbvarfile
     230            ierr=nf_inq_varname(nid,j,var(j-Nnotprocessed))
    223231         enddo
    224232! Variables names from the file are stored in var()
    225    nbvar=nbvarfile-Nnotconcat
     233   nbvar=nbvarfile-Nnotprocessed
    226234   do i=1,nbvar
    227       ierr=nf_inq_varname(nid,i+Nnotconcat,var(i))
     235      ierr=nf_inq_varname(nid,i+Nnotprocessed,var(i))
    228236      write(*,'(a9,1x,i2,1x,a1,1x,a50)') "variable ",i,":",var(i)
    229237   enddo
     
    290298!  write(*,*) "altlen: ",altlen
    291299
     300! load size of aps() or sigma() (in case it is not altlen)
     301   ! default is that GCM_layers=altlen
     302   ! but for outputs of zrecast, it may be a different value
     303   ierr=NF_INQ_DIMID(nid,"GCM_layers",gcmlayerdim)
     304   if (ierr.ne.NF_NOERR) then
     305     ! didn't find a GCM_layers dimension; therefore we have:
     306     GCM_layers=altlen
     307   else
     308     ! load value of GCM_layers
     309     ierr=NF_INQ_DIMLEN(nid,gcmlayerdim,GCM_layers)
     310   endif
     311!   write(*,*) "GCM_layers=",GCM_layers
     312
    292313   ierr=NF_INQ_DIMID(nid,"index",ctldim)
    293314   if (ierr.NE.NF_NOERR) then
     
    304325      ierr=NF_INQ_DIMLEN(nid,ctldim,ctllen)
    305326   endif
    306 !  write(*,*) "controle: ",controle
     327
    307328
    308329!==============================================================================
     
    311332!==============================================================================
    312333
    313 ! First call; initialize/allocate
    314334   allocate(lat(latlen),stat=ierr)
    315335   if (ierr.ne.0) then
     
    333353   endif
    334354
    335 #ifdef NC_DOUBLE
    336    ierr = NF_GET_VAR_DOUBLE(nid,latvar,lat)
    337 #else
    338355   ierr = NF_GET_VAR_REAL(nid,latvar,lat)
    339 #endif
    340356   if (ierr.ne.0) then
    341357     write(*,*) "Error: failed to load latitude"
     
    344360   endif
    345361
    346 #ifdef NC_DOUBLE
    347    ierr = NF_GET_VAR_DOUBLE(nid,lonvar,lon)
    348 #else
    349362   ierr = NF_GET_VAR_REAL(nid,lonvar,lon)
    350 #endif
    351363   if (ierr.ne.0) then
    352364     write(*,*) "Error: failed to load longitude"
     
    355367   endif
    356368
    357 #ifdef NC_DOUBLE
    358    ierr = NF_GET_VAR_DOUBLE(nid,altvar,alt)
    359 #else
    360369   ierr = NF_GET_VAR_REAL(nid,altvar,alt)
    361 #endif
    362370   if (ierr.ne.0) then
    363371     write(*,*) "Error: failed to load altitude"
     
    367375! Get altitude attributes to handle files with any altitude type
    368376   ierr=nf_get_att_text(nid,altvar,'long_name',altlong_name)
     377   if (ierr.ne.nf_noerr) then
     378   ! if no attribute "long_name", try "title"
     379     ierr=nf_get_att_text(nid,altvar,"title",altlong_name)
     380   endif
    369381   ierr=nf_get_att_text(nid,altvar,'units',altunits)
    370382   ierr=nf_get_att_text(nid,altvar,'positive',altpositive)
    371383
    372384   if (ctllen .ne. 0) then
    373 #ifdef NC_DOUBLE
    374      ierr = NF_GET_VAR_DOUBLE(nid,ctlvar,ctl)
    375 #else
    376385     ierr = NF_GET_VAR_REAL(nid,ctlvar,ctl)
    377 #endif
    378386     if (ierr.ne.0) then
    379387       write(*,*) "Error: failed to load controle"
     
    403411!  write(*,*) "timelen: ",timelen
    404412
    405    ! Sanity Check: Does "Time" has a "title" attribute
     413   ! Sanity Check: Does "Time" has a "long_name" attribute
    406414   ! and is it "Solar longitude" ?
    407    ierr=nf_get_att_text(nid,timevar,"title",title)
    408    if ((ierr.EQ.NF_NOERR).and.(title.eq."Solar longitude")) then
     415   ierr=nf_get_att_text(nid,timevar,"long_name",long_name)
     416   if (ierr.ne.nf_noerr) then
     417   ! if no attribute "long_name", try "title"
     418     ierr=nf_get_att_text(nid,timevar,"title",long_name)
     419   endif
     420   if ((ierr.EQ.NF_NOERR).and.(long_name.eq."Solar longitude")) then
    409421     write(*,*) "ERROR: Time axis in input file is in Solar Longitude!"
    410422     write(*,*) "       localtime requires sols as time axis!"
     
    420432   endif
    421433
    422 #ifdef NC_DOUBLE
    423    ierr = NF_GET_VAR_DOUBLE(nid,timevar,time)
    424 #else
    425434   ierr = NF_GET_VAR_REAL(nid,timevar,time)
    426 #endif
    427435   if (ierr.NE.NF_NOERR) then
    428436     write(*,*) "Error , failed to load Time"
     
    434442! 2.4.1 Select local times to be saved "Time" in output file
    435443!==============================================================================
    436    write(*,*) "Planet side of the Solar Zenith Angle ?"
     444   write(*,*) "Planet side of the Solar Zenith Angle ? (morning or evening)"
    437445   read(*,*) planetside
    438446   if ((trim(planetside).ne."morning").and.(trim(planetside).ne."evening")) then
     
    448456     stop
    449457   endif
    450    write(*,*) "Beginning date of the simulation file "
    451    write(*,*) "(or median date of the simulation for a stats)?"
    452    write(*,*) "(i.e. number of sols since Ls=0 at the Time=0.0 in the input file)"
    453    read(*,*) starttimeoffset
     458
     459!  Sol and season: 
     460
     461   if (ctllen .ne. 0) then
     462      startsol = int(int(ctl(4))+int(time(1) + ctl(27)))
     463   else
     464      startsol = int(time(1))
     465   end if
    454466
    455467   if ((timelen.eq.12).and.(time(1).eq.2).and.(time(timelen).eq.24))then
     
    466478     nsol = int(time(timelen)) - int(time(1))
    467479   end if
    468 
    469480   allocate(intsol(nsol),stat=ierr)
    470481   if (ierr.ne.0) then
     
    477488     stop
    478489   endif
     490
     491   if (stats) then
     492         write(*,*) "What is the mean Ls of this stats file (degree) ?"
     493         read(*,*,iostat=ierr) tmpLs
     494         startsol=0.
     495   else
     496      write(*,*) "Beginning date (sol since Ls=0) of this file is :",startsol
     497      write(*,*) "If you do not want to change it,  just write 'n' (recommended)"
     498      write(*,*) "If you really wish to change it, write it now (not recommended!)"
     499      read(*,*,iostat=ierr) startsol
     500      if((ierr.eq.0).and.(ctllen.ne.0))  ctl(4)=startsol
     501      write(*,*) "Beginning date (sol since Ls=0) will be :",startsol
     502   end if
     503
    479504   do it=1,nsol
    480505     intsol(it)= int(time(1)) + it-1.
    481506     do ilon=1,lonlen
    482 !         For the computation of Ls, we try to take into account the rotation time
    483 !         of Mars it's supposed that the morning/evening
     507!         For the computation of Ls, we try to take into account the
     508!         rotation time of Mars. It is supposed that the morning/evening
    484509!         correspond to LT=6h/18h at the given longitude, which is
    485510!         then reported to a sol value at longitude 0
    486511       if (trim(planetside).eq."morning") then
    487          tmpsol = intsol(it) + (6.-lon(ilon)/15.)/24. + starttimeoffset
     512         tmpsol = intsol(it) + (6.-lon(ilon)/15.)/24. + startsol
    488513       else !if trim(planetside).eq."evening"
    489          tmpsol = intsol(it) + (18.-lon(ilon)/15.)/24. + starttimeoffset           
     514         tmpsol = intsol(it) + (18.-lon(ilon)/15.)/24. + startsol           
    490515       endif
    491        call sol2ls(tmpsol,tmpLs)
     516       if (.not.stats) call sol2ls(tmpsol,tmpLs)
    492517       do ilat=1,latlen
    493518!           Compute the Local Time of the solar zenith angle at a given longitude
     
    541566
    542567  ! Initialize output file's lat,lon,alt and time dimensions
    543    call initiate(filename,lat,lon,alt,ctl,latlen,lonlen,altlen,ctllen,&
     568   call initiate(filename,lat,lon,alt,ctl,latlen,lonlen,altlen,ctllen,GCM_layers,&
    544569         altlong_name,altunits,altpositive,&
    545          nout,latdimout,londimout,altdimout,timedimout,timevarout)
    546 
     570         nout,latdimout,londimout,altdimout,timedimout,&
     571         layerdimout,timevarout)
     572         
    547573  ! Initialize output file's aps,bps and phisinit variables
    548    call init2(nid,lonlen,latlen,altlen,altdim,&
    549               nout,londimout,latdimout,altdimout)
    550 
     574   call init2(nid,lonlen,latlen,altlen,GCM_layers,&
     575              nout,londimout,latdimout,altdimout,&
     576              layerdimout)
    551577
    552578!==============================================================================
     
    557583
    558584     do it=1,nsol
    559 #ifdef NC_DOUBLE
    560         ierr= NF_PUT_VARA_DOUBLE(nout,timevarout,it,1,intsol(it)*24.)
    561 #else
    562         ierr= NF_PUT_VARA_REAL(nout,timevarout,it,1,intsol(it)*24.)
    563 #endif
     585       ierr= NF_PUT_VARA_REAL(nout,timevarout,it,1,intsol(it)*24.)
    564586     enddo
    565587   else
    566588     do it=1,nsol
    567 #ifdef NC_DOUBLE
    568         ierr= NF_PUT_VARA_DOUBLE(nout,timevarout,it,1,intsol(it))
    569 #else
    570         ierr= NF_PUT_VARA_REAL(nout,timevarout,it,1,intsol(it))
    571 #endif
    572         if (ierr.NE.NF_NOERR) then
    573           write(*,*) "Error , failed to write Time"
    574           stop
    575         endif
     589       ierr= NF_PUT_VARA_REAL(nout,timevarout,it,1,intsol(it))
     590       if (ierr.NE.NF_NOERR) then
     591         write(*,*) "Error , failed to write Time"
     592         stop
     593       endif
    576594     enddo
    577595   end if
     
    584602
    585603!==============================================================================
    586 ! 2.5.1 Check that variable to be read existe in input file
     604! 2.5.1 Check that variable to be read exists in input file
    587605!==============================================================================
    588606
     
    595613      ierr=nf_inq_varndims(nid,varid,ndim)
    596614
     615      ! Check that it is a 3D or 4D variable
     616      if (ndim.lt.3) then
     617        write(*,*) "Error:",trim(var(j))," is nor a 3D neither a 4D variable"
     618        write(*,*) "We'll skip that variable..."
     619        CYCLE ! go directly to the next variable
     620      endif
     621     
    597622!==============================================================================
    598623! 2.5.2 Prepare things in order to read/write the variable
     
    642667
    643668      units=" "
    644       title=" "
    645       ierr=nf_get_att_text(nid,varid,"title",title)
     669      long_name=" "
     670      ierr=nf_get_att_text(nid,varid,"long_name",long_name)
     671      if (ierr.ne.nf_noerr) then
     672      ! if no attribute "long_name", try "title"
     673        ierr=nf_get_att_text(nid,varid,"title",long_name)
     674      endif
    646675      ierr=nf_get_att_text(nid,varid,"units",units)
    647       call def_var(nout,var(j),title,units,ndim,dim,varidout,ierr)
     676      call def_var(nout,var(j),long_name,units,ndim,dim,varidout,ierr)
    648677
    649678     
     
    653682!==============================================================================
    654683
    655 #ifdef NC_DOUBLE
    656       ierr = NF_GET_VAR_DOUBLE(nid,varid,var3d)
    657       miss=NF_GET_ATT_DOUBLE(nid,varid,"missing_value",missing)
    658       validr=NF_GET_ATT_DOUBLE(nid,varid,"valid_range",valid_range)
    659 #else
    660684      ierr = NF_GET_VAR_REAL(nid,varid,var3d)
    661685      miss=NF_GET_ATT_REAL(nid,varid,"missing_value",missing)
    662686      validr=NF_GET_ATT_REAL(nid,varid,"valid_range",valid_range)
    663 #endif
    664 
    665       ! If there is no missing value attribute in the input variable, create one
     687
     688     ! If there is no missing value attribute in the input variable, create one
    666689      if (miss.ne.NF_NOERR) then
    667690         missing = miss_lt
     
    673696!==============================================================================
    674697
    675       do ilon=1,lonlen
     698       do ilon=1,lonlen
    676699!        Recast GCM local time (sol decimal value) at each longitude :
    677700         do it=1,timelen  ! loop time input file
     
    688711               lt_outc(it)=intsol(it) + lt_out(ilon,ilat,it)/24.
    689712             endif
    690 !            If the computed local time exceeds the GCM input file time bounds,
    691 !            put a missing value in the local time variable
    692              if ((lt_outc(it).gt.lt_gcm(timelen_tot)).OR.(lt_outc(it).lt.lt_gcm(1))) then
    693                lt_out(ilon,ilat,it)=miss_lt
    694                lt_outc(it)=miss_lt
    695              endif
     713             if (nsol.eq.1) then
     714!              If 1 sol file (stats), use all data from that sol.
     715               if(lt_outc(it).gt.lt_gcm(timelen_tot)) lt_outc(it)=lt_outc(it)-1
     716               if(lt_outc(it).lt.lt_gcm(1)) lt_outc(it)=lt_outc(it)+1
     717             else
     718!              If the computed local time exceeds the GCM input file time bounds,
     719!              put a missing value in the local time variable
     720               if ((lt_outc(it).gt.lt_gcm(timelen_tot)).OR.(lt_outc(it).lt.lt_gcm(1))) then
     721                 lt_out(ilon,ilat,it)=miss_lt
     722                 lt_outc(it)=miss_lt
     723               endif
     724             end if
    696725           enddo ! local time
    697726
     
    710739             enddo ! local time
    711740
    712            else if  (ndim==4) then
     741           else if (ndim==4) then
    713742             do ialt=1,altlen
    714743               do it=1,timelen ! loop time input file
     
    725754               enddo ! local time   
    726755             enddo ! alt
    727            endif
     756           endif ! ndim
    728757
    729758         enddo ! lat
    730       end do ! lon
     759       end do ! lon
    731760
    732761
     
    735764!==============================================================================
    736765
    737 #ifdef NC_DOUBLE
    738       ierr= NF_PUT_VARA_DOUBLE(nout,varidout,corner,edges,var3d_lt)
    739 #else
    740       ierr= NF_PUT_VARA_REAL(nout,varidout,corner,edges,var3d_lt)
    741 #endif
    742 
    743       if (ierr.ne.NF_NOERR) then
     766       ierr= NF_PUT_VARA_REAL(nout,varidout,corner,edges,var3d_lt)
     767
     768       if (ierr.ne.NF_NOERR) then
    744769         write(*,*) 'PUT_VAR ERROR: ',NF_STRERROR(ierr)
    745770         stop ""
    746       endif
     771       endif
    747772
    748773      ! Write "missing_value" (and "valid_range" if there is one) attributes in output file
    749       call missing_value(nout,varidout,validr,miss,valid_range,missing)
     774       call missing_value(nout,varidout,validr,miss,valid_range,missing)
    750775
    751776      ! free var3d() array
    752       deallocate(var3d)
    753       deallocate(var3d_lt)
     777       deallocate(var3d)
     778       deallocate(var3d_lt)
    754779
    755780   enddo ! of do j=1,nbvar
     
    780805   write(szastr,*) sza
    781806   if (trim(planetside).eq."morning") then
    782      title="Morning-side LTST at sza="//trim(adjustl(szastr))//"deg"
     807     long_name="Morning-side LTST at sza="//trim(adjustl(szastr))//"deg"
    783808   else !if trim(planetside).eq."evening"
    784      title="Evening-side LTST at sza="//trim(adjustl(szastr))//"deg"           
    785    endif
    786    call def_var(nout,tmpvar,title,units,3,dim,varidout,ierr)
    787 
    788 #ifdef NC_DOUBLE
    789    ierr= NF_PUT_VARA_DOUBLE(nout,varidout,corner,edges,lt_out)
    790 #else
     809     long_name="Evening-side LTST at sza="//trim(adjustl(szastr))//"deg"           
     810   endif
     811   call def_var(nout,tmpvar,long_name,units,3,dim,varidout,ierr)
     812
    791813   ierr= NF_PUT_VARA_REAL(nout,varidout,corner,edges,lt_out)
    792 #endif
    793814   if (ierr.ne.NF_NOERR) then
    794815      write(*,*) 'PUT_VAR ERROR: ',NF_STRERROR(ierr)
     
    798819   validr=NF_NOERR+1
    799820   miss=NF_NOERR
    800    call missing_value(nout,varidout,validr,miss,(0,0),miss_lt)
     821   valid_range(:)=0.
     822   call missing_value(nout,varidout,validr,miss,valid_range,miss_lt)
    801823   write(*,*)"with missing value = ",miss_lt
    802824!==============================================================================
     
    837859!******************************************************************************
    838860
    839 subroutine initiate(filename,lat,lon,alt,ctl,latlen,lonlen,altlen,ctllen,&
     861subroutine initiate(filename,lat,lon,alt,ctl,latlen,lonlen,altlen,ctllen,GCM_layers,&
    840862                     altlong_name,altunits,altpositive,&
    841                      nout,latdimout,londimout,altdimout,timedimout,timevarout)
     863                     nout,latdimout,londimout,altdimout,timedimout,&
     864                     layerdimout,timevarout)
    842865!==============================================================================
    843866! Purpose:
     
    866889real, intent(in):: ctl(ctllen)
    867890! ctl(): controle
     891integer,intent(in) :: GCM_layers ! number of GCM layers
    868892character (len=*), intent(in) :: altlong_name
    869893! altlong_name(): [netcdf] altitude "long_name" attribute
     
    882906integer, intent(out):: timedimout
    883907! timedimout: [netcdf] "Time"  ID
     908integer,intent(out) :: layerdimout
     909! layerdimout: [netcdf] "GCM_layers" ID
    884910integer, intent(out):: timevarout
    885911! timevarout: [netcdf] "Time" (considered as a variable) ID
     
    943969endif
    944970
     971ierr = NF_DEF_DIM(nout, "GCM_layers", GCM_layers, layerdimout)
     972if (ierr.NE.NF_NOERR) then
     973   WRITE(*,*)'initiate: error failed to define dimension <GCM_layers>'
     974   write(*,*) NF_STRERROR(ierr)
     975   stop ""
     976endif
     977
    945978! End netcdf define mode
    946979ierr = NF_ENDDEF(nout)
     
    950983   stop ""
    951984endif
    952 
    953985!==============================================================================
    954986! 3. Write "Time" and its attributes
     
    960992ierr = NF_REDEF (nout)
    961993ierr = NF_PUT_ATT_TEXT(nout,timevarout,'comment',135,&
    962       "The true unit of the variable Time is the integer value of sol at lon=0deg. A false unit is put to enable reading from Grads or Ferret")
     994"The true unit of the variable Time is the integer value &
     995 of sol at lon=0deg. A false unit is put to enable reading from Grads or Ferret")
    963996! End netcdf define mode
    964997ierr = NF_ENDDEF(nout)
     
    9711004             (/latdimout/),nvarid,ierr)
    9721005
    973 #ifdef NC_DOUBLE
    974 ierr = NF_PUT_VAR_DOUBLE (nout,nvarid,lat)
    975 #else
    9761006ierr = NF_PUT_VAR_REAL (nout,nvarid,lat)
    977 #endif
    9781007if (ierr.NE.NF_NOERR) then
    9791008   WRITE(*,*)'initiate: error failed writing variable <latitude>'
     
    9891018             (/londimout/),nvarid,ierr)
    9901019
    991 #ifdef NC_DOUBLE
    992 ierr = NF_PUT_VAR_DOUBLE (nout,nvarid,lon)
    993 #else
    9941020ierr = NF_PUT_VAR_REAL (nout,nvarid,lon)
    995 #endif
    9961021if (ierr.NE.NF_NOERR) then
    9971022   WRITE(*,*)'initiate: error failed writing variable <longitude>'
     
    10071032ierr = NF_REDEF (nout)
    10081033
    1009 #ifdef NC_DOUBLE
    1010 ierr = NF_DEF_VAR (nout,"altitude",NF_DOUBLE,1,altdimout,nvarid)
    1011 #else
    10121034ierr = NF_DEF_VAR (nout,"altitude",NF_FLOAT,1,altdimout,nvarid)
    1013 #endif
    10141035
    10151036ierr = NF_PUT_ATT_TEXT (nout,nvarid,'long_name',len_trim(adjustl(altlong_name)),adjustl(altlong_name))
     
    10201041ierr = NF_ENDDEF(nout)
    10211042
    1022 #ifdef NC_DOUBLE
    1023 ierr = NF_PUT_VAR_DOUBLE (nout,nvarid,alt)
    1024 #else
    1025 ierr = NF_PUT_VAR_REAL (nout,nvarid,alt)
    1026 #endif
     1043ierr = NF_PUT_VAR_REAL (nout,nvarid,alt)
    10271044if (ierr.NE.NF_NOERR) then
    10281045   WRITE(*,*)'initiate: error failed writing variable <altitude>'
     
    10391056   ierr = NF_REDEF (nout)
    10401057
    1041 #ifdef NC_DOUBLE
    1042    ierr = NF_DEF_VAR (nout,"controle",NF_DOUBLE,1,ctldimout,nvarid)
    1043 #else
    10441058   ierr = NF_DEF_VAR (nout,"controle",NF_FLOAT,1,ctldimout,nvarid)
    1045 #endif
    1046 
    1047    ierr = NF_PUT_ATT_TEXT (nout,nvarid,"title",18,"Control parameters")
     1059
     1060   ierr = NF_PUT_ATT_TEXT (nout,nvarid,"long_name",18,"Control parameters")
    10481061
    10491062   ! End netcdf define mode
    10501063   ierr = NF_ENDDEF(nout)
    10511064
    1052 #ifdef NC_DOUBLE
    1053    ierr = NF_PUT_VAR_DOUBLE (nout,nvarid,ctl)
    1054 #else
    10551065   ierr = NF_PUT_VAR_REAL (nout,nvarid,ctl)
    1056 #endif
    10571066   if (ierr.NE.NF_NOERR) then
    10581067      WRITE(*,*)'initiate: error failed writing variable <controle>'
     
    10651074
    10661075!******************************************************************************
    1067 subroutine init2(infid,lonlen,latlen,altlen,altdimid, &
    1068                  outfid,londimout,latdimout,altdimout)
     1076subroutine init2(infid,lonlen,latlen,altlen,GCM_layers, &
     1077                 outfid,londimout,latdimout,altdimout, &
     1078                 layerdimout)
    10691079!==============================================================================
    10701080! Purpose:
     
    10861096integer, intent(in) :: latlen ! # of grid points along latitude
    10871097integer, intent(in) :: altlen ! # of grid points along altitude
    1088 integer, intent(in) :: altdimid ! ID of altitude dimension
     1098integer, intent(in) :: GCM_layers ! # of GCM atmospheric layers
    10891099integer, intent(in) :: outfid ! NetCDF output file ID
    10901100integer, intent(in) :: londimout ! longitude dimension ID
    10911101integer, intent(in) :: latdimout ! latitude dimension ID
    10921102integer, intent(in) :: altdimout ! altitude dimension ID
     1103integer, intent(in) :: layerdimout ! GCM_layers dimension ID
    10931104!==============================================================================
    10941105! Local variables:
     
    11001111integer :: tmpdimid ! temporary dimension ID
    11011112integer :: tmpvarid ! temporary variable ID
    1102 logical :: phis, aps_ok, bps_ok ! are "phisinit" "aps" "bps" available ?
     1113integer :: tmplen ! temporary variable length
     1114logical :: phis,hybrid ! are "phisinit" and "aps"/"bps" available ?
    11031115
    11041116
     
    11081120
    11091121! hybrid coordinate aps
    1110   allocate(aps(altlen),stat=ierr)
     1122!write(*,*) "aps: altlen=",altlen," GCM_layers=",GCM_layers
     1123allocate(aps(GCM_layers),stat=ierr)
     1124if (ierr.ne.0) then
     1125  write(*,*) "init2: failed to allocate aps!"
     1126  stop
     1127endif
     1128ierr=NF_INQ_VARID(infid,"aps",tmpvarid)
     1129if (ierr.ne.NF_NOERR) then
     1130  write(*,*) "Ooops. Failed to get aps ID. OK."
     1131  hybrid=.false.
     1132else
     1133  ierr=NF_GET_VAR_REAL(infid,tmpvarid,aps)
     1134  hybrid=.true.
     1135  if (ierr.ne.NF_NOERR) then
     1136    stop "init2 Error: Failed reading aps"
     1137  endif
     1138
     1139  ! hybrid coordinate bps
     1140!  write(*,*) "bps: altlen=",altlen," GCM_layers=",GCM_layers
     1141  allocate(bps(GCM_layers),stat=ierr)
    11111142  if (ierr.ne.0) then
    1112     write(*,*) "init2: failed to allocate aps(altlen)"
     1143    write(*,*) "init2: failed to allocate bps!"
    11131144    stop
    11141145  endif
    1115 
    1116 ierr=NF_INQ_VARID(infid,"aps",tmpvarid)
    1117 if (ierr.ne.NF_NOERR) then
    1118   write(*,*) "oops Failed to get aps ID. OK"
    1119   aps_ok=.false.
    1120 else
    1121   ! Check that aps() is the right size (it most likely won't be if
    1122   ! zrecast has be used to generate the input file)
    1123   ierr=NF_INQ_VARDIMID(infid,tmpvarid,tmpdimid)
    1124   if (tmpdimid.ne.altdimid) then
    1125     write(*,*) "init2: wrong dimension size for aps(), skipping it ..."
    1126     aps_ok=.false.
    1127   else
    1128     ierr=NF_GET_VAR_REAL(infid,tmpvarid,aps)
    1129     if (ierr.ne.NF_NOERR) then
    1130      stop "init2 error: Failed reading aps"
    1131     endif
    1132     aps_ok=.true.
    1133   endif
    1134 endif
    1135 
    1136 ! hybrid coordinate bps
    1137   allocate(bps(altlen),stat=ierr)
    1138   if (ierr.ne.0) then
    1139     write(*,*) "init2: failed to allocate bps(altlen)"
    1140     stop
    1141   endif
    1142 
    1143 ierr=NF_INQ_VARID(infid,"bps",tmpvarid)
    1144 if (ierr.ne.NF_NOERR) then
    1145   write(*,*) "oops: Failed to get bps ID. OK"
    1146   bps_ok=.false.
    1147 else
    1148   ! Check that bps() is the right size
    1149   ierr=NF_INQ_VARDIMID(infid,tmpvarid,tmpdimid)
    1150   if (tmpdimid.ne.altdimid) then
    1151     write(*,*) "init2: wrong dimension size for bps(), skipping it ..."
    1152     bps_ok=.false.
     1146  ierr=NF_INQ_VARID(infid,"bps",tmpvarid)
     1147  if (ierr.ne.NF_NOERR) then
     1148    write(*,*) "Ooops. Failed to get bps ID. OK."
     1149    hybrid=.false.
    11531150  else
    11541151    ierr=NF_GET_VAR_REAL(infid,tmpvarid,bps)
     
    11561153      stop "init2 Error: Failed reading bps"
    11571154    endif
    1158     bps_ok=.true.
    11591155  endif
    11601156endif
     
    11881184!==============================================================================
    11891185
    1190 IF (aps_ok) then
     1186IF (hybrid) then
    11911187  ! define aps
    11921188  call def_var(outfid,"aps","hybrid pressure at midlayers"," ",1,&
    1193                (/altdimout/),apsid,ierr)
     1189               (/layerdimout/),apsid,ierr)
    11941190  if (ierr.ne.NF_NOERR) then
    11951191    stop "Error: Failed to def_var aps"
     
    11971193
    11981194  ! write aps
    1199 #ifdef NC_DOUBLE
    1200   ierr=NF_PUT_VAR_DOUBLE(outfid,apsid,aps)
    1201 #else
    12021195  ierr=NF_PUT_VAR_REAL(outfid,apsid,aps)
    1203 #endif
    12041196  if (ierr.ne.NF_NOERR) then
    12051197    stop "Error: Failed to write aps"
    12061198  endif
    1207 ENDIF ! of IF (aps_ok)
    1208 
    1209 IF (bps_ok) then
     1199 
    12101200  ! define bps
    12111201  call def_var(outfid,"bps","hybrid sigma at midlayers"," ",1,&
    1212                (/altdimout/),bpsid,ierr)
     1202               (/layerdimout/),bpsid,ierr)
    12131203  if (ierr.ne.NF_NOERR) then
    12141204    stop "Error: Failed to def_var bps"
     
    12161206
    12171207  ! write bps
    1218 #ifdef NC_DOUBLE
    1219   ierr=NF_PUT_VAR_DOUBLE(outfid,bpsid,bps)
    1220 #else
    12211208  ierr=NF_PUT_VAR_REAL(outfid,bpsid,bps)
    1222 #endif
    12231209  if (ierr.ne.NF_NOERR) then
    12241210    stop "Error: Failed to write bps"
    12251211  endif
    1226 ENDIF ! of IF (bps_ok)
     1212 
     1213  deallocate(aps)
     1214  deallocate(bps)
     1215ENDIF ! of IF (hybrid)
    12271216
    12281217!==============================================================================
     
    12401229
    12411230  ! write phisinit
    1242 #ifdef NC_DOUBLE
    1243   ierr=NF_PUT_VAR_DOUBLE(outfid,phisinitid,phisinit)
    1244 #else
    12451231  ierr=NF_PUT_VAR_REAL(outfid,phisinitid,phisinit)
    1246 #endif
    12471232  if (ierr.ne.NF_NOERR) then
    12481233    stop "Error: Failed to write phisinit"
    12491234  endif
    12501235
     1236deallocate(phisinit)
    12511237ENDIF ! of IF (phis)
    12521238
    12531239
    1254 ! Cleanup
    1255 deallocate(aps)
    1256 deallocate(bps)
    1257 deallocate(phisinit)
    1258 
    12591240end subroutine init2
    12601241
    12611242!******************************************************************************
    1262 subroutine def_var(nid,name,title,units,nbdim,dim,nvarid,ierr)
     1243subroutine def_var(nid,name,long_name,units,nbdim,dim,nvarid,ierr)
    12631244!==============================================================================
    12641245! Purpose: Write a variable (i.e: add a variable to a dataset)
    1265 ! called "name"; along with its attributes "title", "units"...
     1246! called "name"; along with its attributes "long_name", "units"...
    12661247! to a file (following the NetCDF format)
    12671248!==============================================================================
     
    12811262character (len=*), intent(in) :: name
    12821263! name(): [netcdf] variable's name
    1283 character (len=*), intent(in) :: title
    1284 ! title(): [netcdf] variable's "title" attribute
     1264character (len=*), intent(in) :: long_name
     1265! long_name(): [netcdf] variable's "long_name" attribute
    12851266character (len=*), intent(in) :: units
    12861267! unit(): [netcdf] variable's "units" attribute
     
    12981279
    12991280! Insert the definition of the variable
    1300 #ifdef NC_DOUBLE
    1301 ierr=NF_DEF_VAR(nid,adjustl(name),NF_DOUBLE,nbdim,dim,nvarid)
    1302 #else
    13031281ierr=NF_DEF_VAR(nid,adjustl(name),NF_FLOAT,nbdim,dim,nvarid)
    1304 #endif
    13051282
    13061283! Write the attributes
    1307 ierr=NF_PUT_ATT_TEXT(nid,nvarid,"title",len_trim(adjustl(title)),adjustl(title))
     1284ierr=NF_PUT_ATT_TEXT(nid,nvarid,"long_name",len_trim(adjustl(long_name)),adjustl(long_name))
    13081285ierr=NF_PUT_ATT_TEXT(nid,nvarid,"units",len_trim(adjustl(units)),adjustl(units))
    13091286
     
    13631340! Write valid_range() attribute
    13641341if (validr.eq.NF_NOERR) then
    1365 #ifdef NC_DOUBLE
    1366   ierr=NF_PUT_ATT_DOUBLE(nout,nvarid,'valid_range',NF_DOUBLE,2,valid_range)
    1367 #else
    13681342  ierr=NF_PUT_ATT_REAL(nout,nvarid,'valid_range',NF_FLOAT,2,valid_range)
    1369 #endif
    13701343
    13711344  if (ierr.ne.NF_NOERR) then
     
    13801353! Write "missing_value" attribute
    13811354if (miss.eq.NF_NOERR) then
    1382 #ifdef NC_DOUBLE
    1383   ierr= NF_PUT_ATT_DOUBLE(nout,nvarid,'missing_value',NF_DOUBLE,1,missing)
    1384 #else
    13851355  ierr= NF_PUT_ATT_REAL(nout,nvarid,'missing_value',NF_FLOAT,1,missing)
    1386 #endif
    13871356
    13881357  if (ierr.NE.NF_NOERR) then
Note: See TracChangeset for help on using the changeset viewer.