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/concatnc.F90

    r2395 r2434  
    3434character (len=50), dimension(:), allocatable :: var
    3535! var(): name(s) of variable(s) that will be concatenated
    36 character (len=50) :: tmpvar,tmpfile,title,units
     36character (len=100) :: tmpvar,tmpfile,long_name,units
    3737! tmpvar(): used to temporarily store a variable name
    3838! tmpfile(): used to temporarily store a file name
    39 ! title(): [netcdf] title attribute
     39! long_name(): [netcdf] long_name attribute
    4040! units(): [netcdf] units attribute
    4141character (len=100) :: filename,vartmp
    4242! filename(): output file name
    4343! vartmp(): temporary variable name (read from netcdf input file)
    44 !character (len=1) :: ccopy
    45 ! ccpy: 'y' or 'n' answer
     44character (len=50) :: altlong_name,altunits,altpositive
     45! altlong_name(): [netcdf] altitude "long_name" attribute
     46! altunits(): [netcdf] altitude "units" attribute
     47! altpositive(): [netcdf] altitude "positive" attribute
    4648character (len=4) :: axis
    47 ! axis: "ls" or "sol"
     49! axis:  "sol" or "ls" or "adls"
    4850integer :: nid,ierr,miss
    4951! nid: [netcdf] file ID #
     
    115117real :: ctlsol
    116118! ctlsol: starting sol value of the file, stored in the variable ctl()
    117 real :: memotime
    118 ! memotime: (cumulative) time value, in martian days (sols)
     119real :: previous_last_output_time, output_time
     120! previous_last_output_time: last time stored in concat.nc after treating a file
     121logical :: firstsol
     122! firstsol:  true if the first file's starting day must be used in the output
     123real :: startsol
     124! startsol: sol of the firstday as requested by the users (used if firstsol="y")
    119125real :: starttimeoffset
    120 ! starttimeoffset: offset given by the user for the output time axis
    121 character (len=1) :: firstsol
    122 ! firstsol: =[y/n], to know whether the user offset or the first file's starting day must be used in the output
     126! starttimeoffset: offset given by the user for the output time axis (0 if ! firstsol="n")
    123127real :: missing
    124128!PARAMETER(missing=1E+20)
     
    126130real, dimension(2) :: valid_range
    127131! valid_range(2): [netcdf] interval in which a value is considered valid
     132real :: year_day = 669.
    128133
    129134!==============================================================================
     
    154159!==============================================================================
    155160
    156 write(*,*)
    157 write(*,*) "Starting day to be stored in the output file time axis?"
    158 write(*,*) "(e.g.: 100 if you want the output file to start at time=100 sols)"
    159 write(*,*) "Your answer will bypass any starting day value stored in the 1st"
    160 write(*,*) "input file. Conversely, just type return if you want this 1st file's"
    161 write(*,*) "value to be kept for the output file starting day."
    162 read(*,*,iostat=ierr) starttimeoffset
    163 if (ierr.ne.0) then
     161 write(*,*) "Starting time in the concat file ?"
     162 write(*,*) "   If you really wish to change it, write it now (not recommanded!)"
     163 write(*,*) "   If you do not want to change it,  just write 'n' (recommanded)"
     164
     165read(*,*,iostat=ierr) startsol
     166
     167firstsol= (ierr.eq.0)
     168if (firstsol) then
    164169   ! if nothing or a character that is not a float is read
    165170   write(*,*) "1st input file's starting day will serve as starting day for the outfile."
    166    firstsol='n'
    167171else ! if the user gave a number
    168172   write(*,*) "Your input day will serve as starting day for the outfile."
    169    firstsol='y'
    170173endif
    171174
     
    190193
    191194write(*,*)
    192 write(*,*) "Warning: to read the result with grads, choose sol"
    193 write(*,*) "Warning: use ferret to read the non linear scale ls"
    194 write(*,*) "Which time axis should be given in the output? (sol/ls)"
     195write(*,*) "Which time axis should be given in the output? (sol/ls/adls)"
     196write(*,*) "        (Warning: to read the result with grads, choose sol)"
     197write(*,*) "  To keep sol as the time axis, and just add Ls as a variable, type adls  "
    195198read(*,*) axis
    196199! loop as long as axis is neither "sol" nor "ls"
    197 do while ((axis/="sol").AND.(axis/="ls"))
     200do while ((axis/="sol").AND.(axis/="ls").AND.(axis/="adls"))
    198201   read(*,*) axis
    199202enddo
     
    255258if (tmpvar=="all") then
    256259   if (axis=="ls") then
    257 !      write(*,*) "Do you want to keep the original file? (y/n)"
    258 !      read(*,*) ccopy
    259 !      if ((ccopy=="n").or.(ccopy=="N")) then
    260 !         do i=1,nbfile
    261 !            ierr=NF_CLOSE(nid)
    262 !            ierr = NF_OPEN(file(1),NF_WRITE,nid)
    263 !            call change_time_axis(nid,ierr)
    264 !            ierr=NF_CLOSE(nid)
    265 !            STOP ""
    266 !         enddo
    267 !      else
    268260         nbvar=nbvarfile-Nnotconcat
    269261         do j=Nnotconcat+1,nbvarfile
    270262            ierr=nf_inq_varname(nid,j,var(j-Nnotconcat))
    271263         enddo
    272 !      endif ! of if ((ccopy=="n").or.(ccopy=="N"))
    273264   endif ! of if (axis=="ls")
    274265! Variables names from the file are catched
     
    394385      endif
    395386   endif
    396 !  write(*,*) "controle: ",controle
    397387
    398388   if (ctllen .ne. 0) then ! variable controle
    399389      allocate(ctl(ctllen))
    400 #ifdef NC_DOUBLE
    401       ierr = NF_GET_VAR_DOUBLE(nid,ctlvar,ctl)
    402 #else
    403390      ierr = NF_GET_VAR_REAL(nid,ctlvar,ctl)
    404 #endif
    405391      ctlsol = ctl(4)
    406392   endif
     
    425411   allocate(time(timelen))
    426412
    427 #ifdef NC_DOUBLE
    428    ierr = NF_GET_VAR_DOUBLE(nid,timevar,time)
    429 #else
    430413   ierr = NF_GET_VAR_REAL(nid,timevar,time)
    431 #endif
    432 
    433414
    434415!==============================================================================
     
    437418!==============================================================================
    438419
    439    if (i==1) then ! First call; initialize/allocate
     420   if (i==1) then ! First File ; initialize/allocate
    440421      memolatlen=latlen
    441422      memolonlen=lonlen
     
    445426      allocate(lon(lonlen))
    446427      allocate(alt(altlen))
    447 #ifdef NC_DOUBLE
    448       ierr = NF_GET_VAR_DOUBLE(nid,latvar,lat)
    449       ierr = NF_GET_VAR_DOUBLE(nid,lonvar,lon)
    450       ierr = NF_GET_VAR_DOUBLE(nid,altvar,alt)
    451 #else
    452428      ierr = NF_GET_VAR_REAL(nid,latvar,lat)
    453429      ierr = NF_GET_VAR_REAL(nid,lonvar,lon)
    454430      ierr = NF_GET_VAR_REAL(nid,altvar,alt)
    455 #endif
     431!   Get altitude attributes to handle files with any altitude type
     432      ierr=nf_get_att_text(nid,altvar,'long_name',altlong_name)
     433      if (ierr.ne.nf_noerr) then
     434      ! if no attribute "long_name", try "title"
     435        ierr=nf_get_att_text(nid,altvar,"title",altlong_name)
     436      endif
     437      ierr=nf_get_att_text(nid,altvar,'units',altunits)
     438      ierr=nf_get_att_text(nid,altvar,'positive',altpositive)
    456439      write(*,*)
     440     
    457441      if (ctllen .ne. 0) then
    458          if (int(starttimeoffset) .ne. (int(ctlsol)+int(time(1))) ) then
    459            write(*,*) "WARNING: Starting day of the first file is not ",&
    460                        int(starttimeoffset)," but ",int(ctlsol)+int(time(1)),"!"
     442       
     443         if (firstsol) then
     444           starttimeoffset = float(int(ctlsol)+int(time(1) + ctl(27))) - startsol
     445         else ! if firstsol.eq..false.
     446!          if there is no user chosen first sol, nevertheless use
     447!          starttimeoffset to lower the sol number (same exact season)
     448           startsol = modulo(int(int(ctlsol)+int(time(1) + ctl(27))),int(year_day))
     449           starttimeoffset = float(int(ctlsol)+int(time(1) + ctl(27))) - startsol
    461450         endif
    462        
    463          if (firstsol.eq.'y') then
    464            starttimeoffset = float(int(ctlsol)+int(time(1))) + ctl(27) - starttimeoffset
    465          else ! if firstsol.eq.'n'
    466            starttimeoffset = 0
    467          endif
    468 
    469          memotime=float(int(ctlsol)+int(time(1))) + ctl(27)
     451
     452!        artificially estimating "previous_last_output_time" for first file read:
     453         previous_last_output_time= startsol
     454
    470455         ctl(4) = 0.  ! values written in the output
    471456         ctl(27) = 0. ! file controle variable (resp. day_ini and hour_ini)
    472457         
    473458      else ! if no variable "controle"
    474          if (int(starttimeoffset) .ne. (int(time(1))) ) then
    475            write(*,*) "WARNING: Starting day of the first file is not ",&
    476                        int(starttimeoffset)," but ",int(time(1)),"!"
    477          endif
    478 
    479          if (firstsol.eq.'y') then
    480            starttimeoffset = int(time(1)) - starttimeoffset
    481          else ! if firstsol.eq.'n'
     459         if (firstsol) then
     460           starttimeoffset = int(time(1)) - startsol
     461         else ! if firstsol.eq.false
    482462           starttimeoffset = 0
    483463         endif
    484464
    485          memotime=float(int(time(1)))
     465!        artificially estimating "previous_last_output_time" for first file read:
     466         previous_last_output_time=time(1) -(time(2) - time(1)) - starttimeoffset
    486467      endif
     468      write(*,*) "Original starting day of 1st input file", previous_last_output_time + starttimeoffset
     469      write(*,*) "Starting day of the concat file : ", previous_last_output_time
     470
    487471       
    488472   ! Initialize output file's lat,lon,alt and time dimensions
    489473      write(*,*)
    490       call initiate(filename,lat,lon,alt,ctl,GCM_layers,nout,&
    491        latdimout,londimout,altdimout,timedimout,&
     474      call initiate(filename,lat,lon,alt,ctl,GCM_layers,&
     475       altlong_name,altunits,altpositive,&
     476       nout,latdimout,londimout,altdimout,timedimout,&
    492477       layerdimout,interlayerdimout,timevarout,axis)
    493478   ! Initialize output file's aps,bps,ap,bp and phisinit variables
    494      call init2(nid,lonlen,latlen,altlen,GCM_layers,&
     479      call init2(nid,lonlen,latlen,altlen,GCM_layers,&
    495480                nout,londimout,latdimout,altdimout,&
    496481                layerdimout,interlayerdimout)
    497482   
    498    else ! Not a first call,
     483   else ! Not first file to concatenate
    499484   ! Check that latitude,longitude and altitude of current input file
    500485   ! are identical to those of the output file
     
    521506
    522507   rep=0
    523    write(*,*)
    524    write(*,'(a3,1x,f6.1)') "Sol",memotime-starttimeoffset
    525 !   if (ctllen.ne.0) write(*,'(a30,1x,f6.1)') "In the current file's ctl: Sol",ctlsol
    526 
    527    ! Add (memotime)/(ctlsol) offset and write "concatenated" time values to output file
    528    if (ctllen.ne.0) then
    529      do k=reptime+1,reptime+timelen
     508
     509   do k=reptime+1,reptime+timelen
    530510       rep=rep+1
    531        if ((time(rep)+ctlsol).le.memotime) then
    532          write(*,*) "ERROR : the time intervals of the files are not dissociated"
    533          stop ""
    534        endif
    535 #ifdef NC_DOUBLE
    536        ierr= NF_PUT_VARA_DOUBLE(nout,timevarout,k,1,ctlsol+time(rep)-starttimeoffset)
    537 #else
    538        ierr= NF_PUT_VARA_REAL(nout,timevarout,k,1,ctlsol+time(rep)-starttimeoffset)
    539 #endif
    540        !
    541      enddo
    542 
    543    ! Compute new time offset (for further concatenations)
    544    memotime=ctlsol+time(timelen) ! the actual last day of the current file
    545                                  ! becomes the reference time for next file
    546                                  ! leaving potential "time holes" in the output time axis
    547                                  ! at the junction of two files' time axes
    548    
    549    else ! if no variable "controle"
    550    
    551      do k=reptime+1,reptime+timelen
    552         rep=rep+1
    553 #ifdef NC_DOUBLE
    554         ierr= NF_PUT_VARA_DOUBLE(nout,timevarout,k,1,memotime+time(rep)-int(time(1))-starttimeoffset)
    555 #else
    556         ierr= NF_PUT_VARA_REAL(nout,timevarout,k,1,memotime+time(rep)-int(time(1))-starttimeoffset)
    557 #endif
    558      enddo
    559      
    560    ! Compute new time offset (for further concatenations)
    561    memotime=memotime+time(timelen)-time(1) ! files are concatenated one after another
    562                                            ! even if their time axes normally don't
    563                                            ! directly follow each other
    564    endif ! if ctllen.ne.0
     511       if (ctllen.ne.0) then
     512          output_time=time(rep)+ctlsol-starttimeoffset
     513!         correction if the file to concatenate seems "before" previous file
     514!         (for instance to concatenate diagfi from the previous year at the enf of a year)
     515          do while (output_time.lt.previous_last_output_time) 
     516                   output_time = output_time + year_day
     517          end do
     518       else ! if no control, just add timestep after timestep
     519          output_time= previous_last_output_time + (time(2)-time(1)) &
     520         + (time(rep)-time(1))
     521       end if
     522       if (rep.eq.1) write(*,*) "Sol", int(output_time) 
     523
     524       ierr= NF_PUT_VARA_REAL(nout,timevarout,k,1,output_time)
     525   end do
     526!  use the last output_time value to update memotime   
     527   previous_last_output_time = output_time
     528
    565529
    566530!==============================================================================
     
    577541      ierr=nf_inq_varid(nid,var(j),varid)
    578542      if (ierr.NE.NF_NOERR) then
    579          write(*,*) 'ERROR: Field <',var(j),'> not found in file'//file(i)
     543         write(*,*) 'ERROR: Field <',var(j),'> not found in file '//file(i)
    580544         stop ""
    581545      endif
    582546      ierr=nf_inq_varndims(nid,varid,ndim)
    583547
     548      ! Check that it is a 1D, 3D or 4D variable
     549      if ((ndim.ne.1).and.(ndim.ne.3).and.(ndim.ne.4)) then
     550        write(*,*) "Error:",trim(var(j))," is not a time-dependent variable,"
     551        write(*,*) "so it can't be concatenated."
     552        write(*,*) "We'll skip that variable..."
     553        CYCLE ! go directly to the next variable
     554      endif
     555     
    584556!==============================================================================
    585557! 2.5.2 Prepare things in order to read/write the variable
     
    644616      if (i==1) then ! First call: write some definitions to output file
    645617         units="                                                    "
    646          title="                                                    "
    647          ierr=nf_get_att_text(nid,varid,"title",title)
     618         long_name="                                                    "
     619         ierr=nf_get_att_text(nid,varid,"long_name",long_name)
     620         if (ierr.ne.nf_noerr) then
     621         ! if no attribute "long_name", try "title"
     622           ierr=nf_get_att_text(nid,varid,"title",long_name)
     623         endif
    648624         ierr=nf_get_att_text(nid,varid,"units",units)
    649          call def_var(nout,var(j),title,units,ndim,dim,varidout,ierr)
     625         call def_var(nout,var(j),long_name,units,ndim,dim,varidout,ierr)
    650626      else
    651627         ierr=NF_INQ_VARID(nout,var(j),varidout)
     
    656632!==============================================================================
    657633
    658 #ifdef NC_DOUBLE
    659       ierr = NF_GET_VAR_DOUBLE(nid,varid,var3d)
    660       ierr= NF_PUT_VARA_DOUBLE(nout,varidout,corner,edges,var3d)
    661       miss=NF_GET_ATT_DOUBLE(nid,varid,"missing_value",missing)
    662       miss=NF_GET_ATT_DOUBLE(nid,varid,"valid_range",valid_range)
    663 #else
    664634      ierr = NF_GET_VAR_REAL(nid,varid,var3d)
    665635      ierr= NF_PUT_VARA_REAL(nout,varidout,corner,edges,var3d)
    666636      miss=NF_GET_ATT_REAL(nid,varid,"missing_value",missing)
    667637      miss=NF_GET_ATT_REAL(nid,varid,"valid_range",valid_range)
    668 #endif
    669638
    670639      if (ierr.ne.NF_NOERR) then
     
    700669!==============================================================================
    701670
    702 if (axis=="ls") then
    703    write(*,*);write(*,*) "Converting the time axis from sol to Ls..."
    704    call change_time_axis(nout,ierr)
     671if ((axis=="ls").or.(axis=="adls")) then
     672   call change_time_axis(nout,ierr,axis)
    705673endif
    706674
     
    712680
    713681!******************************************************************************
    714 subroutine initiate (filename,lat,lon,alt,ctl,GCM_layers,nout,&
    715          latdimout,londimout,altdimout,timedimout,&
    716          layerdimout,interlayerdimout,timevarout,axis)
     682subroutine initiate (filename,lat,lon,alt,ctl,GCM_layers,&
     683                     altlong_name,altunits,altpositive,&
     684                     nout,latdimout,londimout,altdimout,timedimout,&
     685                     layerdimout,interlayerdimout,timevarout,axis)
    717686!==============================================================================
    718687! Purpose:
     
    741710! ctl(): controle
    742711integer,intent(in) :: GCM_layers ! number of GCM layers
     712character (len=*), intent(in) :: altlong_name
     713! altlong_name(): [netcdf] altitude "long_name" attribute
     714character (len=*), intent(in) :: altunits
     715! altunits(): [netcdf] altitude "units" attribute
     716character (len=*), intent(in) :: altpositive
     717! altpositive(): [netcdf] altitude "positive" attribute
    743718integer, intent(out):: nout
    744719! nout: [netcdf] file ID
     
    787762ierr = NF_DEF_DIM(nout, "longitude", size(lon), londimout)
    788763ierr = NF_DEF_DIM(nout, "altitude", size(alt), altdimout)
    789 if (size(ctl).ne.0) ierr = NF_DEF_DIM(nout, "index", size(ctl), ctldimout)
     764if (ctllen.ne.0) ierr = NF_DEF_DIM(nout, "index", size(ctl), ctldimout)
    790765ierr = NF_DEF_DIM(nout, "Time", NF_UNLIMITED, timedimout)
    791766ierr = NF_DEF_DIM(nout, "GCM_layers", GCM_layers, layerdimout)
     
    798773! 3. Write "Time" and its attributes
    799774!==============================================================================
    800 if (axis=="sol") then
     775if (axis=="ls") then
     776  call def_var(nout,"Time","Solar longitude","degree",1,&
     777             (/timedimout/),timevarout,ierr)
     778else
    801779  call def_var(nout,"Time","Time","days since 0000-00-0 00:00:00",1,&
    802780             (/timedimout/),timevarout,ierr)
    803 else ! Ls
    804   call def_var(nout,"Time","Solar longitude","days since 0000-00-0 00:00:00",1,&
    805              (/timedimout/),timevarout,ierr)
    806781endif
    807782!==============================================================================
     
    812787             (/latdimout/),nvarid,ierr)
    813788
    814 #ifdef NC_DOUBLE
    815 ierr = NF_PUT_VAR_DOUBLE (nout,nvarid,lat)
    816 #else
    817789ierr = NF_PUT_VAR_REAL (nout,nvarid,lat)
    818 #endif
    819790
    820791!==============================================================================
     
    825796             (/londimout/),nvarid,ierr)
    826797
    827 #ifdef NC_DOUBLE
    828 ierr = NF_PUT_VAR_DOUBLE (nout,nvarid,lon)
    829 #else
    830798ierr = NF_PUT_VAR_REAL (nout,nvarid,lon)
    831 #endif
    832799
    833800!==============================================================================
     
    838805ierr = NF_REDEF (nout)
    839806
    840 #ifdef NC_DOUBLE
    841 ierr = NF_DEF_VAR (nout,"altitude",NF_DOUBLE,1,altdimout,nvarid)
    842 #else
    843807ierr = NF_DEF_VAR (nout,"altitude",NF_FLOAT,1,altdimout,nvarid)
    844 #endif
    845 
    846 ierr = NF_PUT_ATT_TEXT (nout,nvarid,"long_name",8,"altitude")
    847 ierr = NF_PUT_ATT_TEXT (nout,nvarid,'units',2,"km")
    848 ierr = NF_PUT_ATT_TEXT (nout,nvarid,'positive',2,"up")
     808
     809ierr = NF_PUT_ATT_TEXT (nout,nvarid,'long_name',len_trim(adjustl(altlong_name)),adjustl(altlong_name))
     810ierr = NF_PUT_ATT_TEXT (nout,nvarid,'units',len_trim(adjustl(altunits)),adjustl(altunits))
     811ierr = NF_PUT_ATT_TEXT (nout,nvarid,'positive',len_trim(adjustl(altpositive)),adjustl(altpositive))
    849812
    850813! End netcdf define mode
    851814ierr = NF_ENDDEF(nout)
    852815
    853 #ifdef NC_DOUBLE
    854 ierr = NF_PUT_VAR_DOUBLE (nout,nvarid,alt)
    855 #else
    856816ierr = NF_PUT_VAR_REAL (nout,nvarid,alt)
    857 #endif
    858817
    859818!==============================================================================
     
    861820!==============================================================================
    862821
    863 if (size(ctl).ne.0) then
     822if (ctllen.ne.0) then
    864823   ! Switch to netcdf define mode
    865824   ierr = NF_REDEF (nout)
    866825
    867 #ifdef NC_DOUBLE
    868    ierr = NF_DEF_VAR (nout,"controle",NF_DOUBLE,1,ctldimout,nvarid)
    869 #else
    870826   ierr = NF_DEF_VAR (nout,"controle",NF_FLOAT,1,ctldimout,nvarid)
    871 #endif
    872 
    873    ierr = NF_PUT_ATT_TEXT (nout,nvarid,"title",18,"Control parameters")
     827
     828   ierr = NF_PUT_ATT_TEXT (nout,nvarid,"long_name",18,"Control parameters")
    874829
    875830   ! End netcdf define mode
    876831   ierr = NF_ENDDEF(nout)
    877832
    878 #ifdef NC_DOUBLE
    879    ierr = NF_PUT_VAR_DOUBLE (nout,nvarid,ctl)
    880 #else
    881833   ierr = NF_PUT_VAR_REAL (nout,nvarid,ctl)
    882 #endif
    883834endif
    884835
     
    890841!==============================================================================
    891842! Purpose:
    892 ! Copy ap() , bp(), aps(), bps(), aire() and phisinit()
    893 ! from input file to outpout file
     843! Copy ap(), bp(), aps(), bps(), aire() and phisinit()
     844! from input file to output file
    894845!==============================================================================
    895846! Remarks:
     
    907858integer, intent(in) :: lonlen ! # of grid points along longitude
    908859integer, intent(in) :: latlen ! # of grid points along latitude
    909 integer, intent(in) :: altlen ! # of grid points along latitude
     860integer, intent(in) :: altlen ! # of grid points along altitude
    910861integer, intent(in) :: GCM_layers ! # of GCM atmospheric layers
    911862integer, intent(in) :: outfid ! NetCDF output file ID
     
    931882logical :: hybrid ! are "aps" and "bps" available ?
    932883logical :: apbp ! are "ap" and "bp" available ?
     884logical :: sig ! is "sigma" available ?
    933885
    934886!==============================================================================
     
    976928  write(*,*) "init2: failed to allocate ap!"
    977929  stop
     930endif
     931ierr=NF_INQ_VARID(infid,"ap",tmpvarid)
     932if (ierr.ne.NF_NOERR) then
     933  write(*,*) "Ooops. Failed to get ap ID. OK."
     934  apbp=.false.
    978935else
    979   ierr=NF_INQ_VARID(infid,"ap",tmpvarid)
    980   if (ierr.ne.NF_NOERR) then
    981     write(*,*) "Ooops. Failed to get ap ID. OK."
    982     apbp=.false.
    983   else
    984     ierr=NF_GET_VAR_REAL(infid,tmpvarid,ap)
    985     apbp=.true.
    986     if (ierr.ne.NF_NOERR) then
    987       stop "Error: Failed reading ap"
    988     endif
     936  ierr=NF_GET_VAR_REAL(infid,tmpvarid,ap)
     937  apbp=.true.
     938  if (ierr.ne.NF_NOERR) then
     939    stop "Error: Failed reading ap"
    989940  endif
    990941endif
     
    995946  write(*,*) "init2: failed to allocate bp!"
    996947  stop
     948endif
     949ierr=NF_INQ_VARID(infid,"bp",tmpvarid)
     950if (ierr.ne.NF_NOERR) then
     951  write(*,*) "Ooops. Failed to get bp ID. OK."
     952  apbp=.false.
    997953else
    998   ierr=NF_INQ_VARID(infid,"bp",tmpvarid)
    999   if (ierr.ne.NF_NOERR) then
    1000     write(*,*) "Ooops. Failed to get bp ID. OK."
    1001     apbp=.false.
    1002   else
    1003     ierr=NF_GET_VAR_REAL(infid,tmpvarid,bp)
    1004     apbp=.true.
    1005     if (ierr.ne.NF_NOERR) then
    1006       stop "Error: Failed reading bp"
    1007     endif
     954  ierr=NF_GET_VAR_REAL(infid,tmpvarid,bp)
     955  apbp=.true.
     956  if (ierr.ne.NF_NOERR) then
     957    stop "Error: Failed reading bp"
    1008958  endif
    1009959endif
     
    1017967  endif
    1018968  ierr=NF_INQ_VARID(infid,"sigma",tmpvarid)
    1019   ierr=NF_GET_VAR_REAL(infid,tmpvarid,sigma)
    1020   if (ierr.ne.NF_NOERR) then
    1021     stop "init2 Error: Failed reading sigma"
     969  if (ierr.ne.NF_NOERR) then
     970    write(*,*) "Ooops. Failed to get sigma ID. OK."
     971    sig=.false.
     972  else
     973    ierr=NF_GET_VAR_REAL(infid,tmpvarid,sigma)
     974    sig=.true.
     975    if (ierr.ne.NF_NOERR) then
     976      stop "init2 Error: Failed reading sigma"
     977    endif
    1022978  endif
    1023979endif ! of if (.not.hybrid)
     
    10751031
    10761032! write aps
    1077 #ifdef NC_DOUBLE
    1078   ierr=NF_PUT_VAR_DOUBLE(outfid,apsid,aps)
    1079 #else
    10801033  ierr=NF_PUT_VAR_REAL(outfid,apsid,aps)
    1081 #endif
    10821034  if (ierr.ne.NF_NOERR) then
    10831035    stop "init2 Error: Failed to write aps"
     
    10921044
    10931045! write bps
    1094 #ifdef NC_DOUBLE
    1095   ierr=NF_PUT_VAR_DOUBLE(outfid,bpsid,bps)
    1096 #else
    10971046  ierr=NF_PUT_VAR_REAL(outfid,bpsid,bps)
    1098 #endif
    10991047  if (ierr.ne.NF_NOERR) then
    11001048    stop "init2 Error: Failed to write bps"
     
    11101058
    11111059! write ap
    1112 #ifdef NC_DOUBLE
    1113     ierr=NF_PUT_VAR_DOUBLE(outfid,apid,ap)
    1114 #else
    11151060    ierr=NF_PUT_VAR_REAL(outfid,apid,ap)
    1116 #endif
    11171061    if (ierr.ne.NF_NOERR) then
    11181062      stop "Error: Failed to write ap"
     
    11271071
    11281072!   write bp
    1129 #ifdef NC_DOUBLE
    1130     ierr=NF_PUT_VAR_DOUBLE(outfid,bpid,bp)
    1131 #else
    11321073    ierr=NF_PUT_VAR_REAL(outfid,bpid,bp)
    1133 #endif
    11341074    if (ierr.ne.NF_NOERR) then
    11351075      stop "Error: Failed to write bp"
     
    11371077  endif ! of if (apbp)
    11381078
    1139 else
     1079else if (sig) then
    11401080! define sigma
    11411081  call def_var(nout,"sigma","sigma at midlayers"," ",1,&
     
    11451085  endif
    11461086! write sigma
    1147 #ifdef NC_DOUBLE
    1148   ierr=NF_PUT_VAR_DOUBLE(outfid,sigmaid,sigma)
    1149 #else
    11501087  ierr=NF_PUT_VAR_REAL(outfid,sigmaid,sigma)
    1151 #endif
    11521088  if (ierr.ne.NF_NOERR) then
    11531089    stop "init2 Error: Failed to write sigma"
     
    11681104 
    11691105  ! write aire
    1170 #ifdef NC_DOUBLE
    1171   ierr=NF_PUT_VAR_DOUBLE(outfid,tmpvarid,aire)
    1172 #else
    11731106  ierr=NF_PUT_VAR_REAL(outfid,tmpvarid,aire)
    1174 #endif
    11751107  if (ierr.ne.NF_NOERR) then
    11761108    stop "init2 Error: Failed to write aire"
     
    11881120
    11891121  ! write phisinit
    1190 #ifdef NC_DOUBLE
    1191   ierr=NF_PUT_VAR_DOUBLE(outfid,phisinitid,phisinit)
    1192 #else
    11931122  ierr=NF_PUT_VAR_REAL(outfid,phisinitid,phisinit)
    1194 #endif
    11951123  if (ierr.ne.NF_NOERR) then
    11961124    stop "init2 Error: Failed to write phisinit"
     
    12111139end subroutine init2
    12121140!******************************************************************************
    1213 subroutine def_var(nid,name,title,units,nbdim,dim,nvarid,ierr)
     1141subroutine def_var(nid,name,long_name,units,nbdim,dim,nvarid,ierr)
    12141142!==============================================================================
    12151143! Purpose: Write a variable (i.e: add a variable to a dataset)
    1216 ! called "name"; along with its attributes "title", "units"...
     1144! called "name"; along with its attributes "long_name", "units"...
    12171145! to a file (following the NetCDF format)
    12181146!==============================================================================
     
    12321160character (len=*), intent(in) :: name
    12331161! name(): [netcdf] variable's name
    1234 character (len=*), intent(in) :: title
    1235 ! title(): [netcdf] variable's "title" attribute
     1162character (len=*), intent(in) :: long_name
     1163! long_name(): [netcdf] variable's "long_name" attribute
    12361164character (len=*), intent(in) :: units
    12371165! unit(): [netcdf] variable's "units" attribute
     
    12491177
    12501178! Insert the definition of the variable
    1251 #ifdef NC_DOUBLE
    1252 ierr=NF_DEF_VAR(nid,adjustl(name),NF_DOUBLE,nbdim,dim,nvarid)
    1253 #else
    12541179ierr=NF_DEF_VAR(nid,adjustl(name),NF_FLOAT,nbdim,dim,nvarid)
    1255 #endif
    12561180
    12571181! Write the attributes
    1258 ierr=NF_PUT_ATT_TEXT(nid,nvarid,"title",len_trim(adjustl(title)),adjustl(title))
     1182ierr=NF_PUT_ATT_TEXT(nid,nvarid,"long_name",len_trim(adjustl(long_name)),adjustl(long_name))
    12591183ierr=NF_PUT_ATT_TEXT(nid,nvarid,"units",len_trim(adjustl(units)),adjustl(units))
    12601184
     
    12641188end subroutine def_var
    12651189!******************************************************************************
    1266 subroutine change_time_axis(nid,ierr)
     1190subroutine change_time_axis(nid,ierr,axis)
    12671191!==============================================================================
    12681192! Purpose:
     
    12851209integer, intent(out) :: ierr
    12861210! ierr: [netcdf]  return error code
     1211character (len=4),intent(in) :: axis
     1212! axis: "ls" or "sol"
    12871213
    12881214!==============================================================================
     
    13151241ierr=NF_INQ_DIMLEN(nid,timedim,timelen)
    13161242allocate(time(timelen),ls(timelen))
    1317 #ifdef NC_DOUBLE
    1318 ierr = NF_GET_VAR_DOUBLE(nid,nvarid,time)
    1319 #else
    13201243ierr = NF_GET_VAR_REAL(nid,nvarid,time)
    1321 #endif
    13221244if (ierr.ne.NF_NOERR) then
    13231245  write(*,*) "ERROR in change_time_axis: Failed to load Time"
     
    13531275!==============================================================================
    13541276
    1355 #ifdef NC_DOUBLE
    1356 ierr = NF_PUT_VAR_DOUBLE(nid,nvarid,ls)
    1357 #else
     1277if (axis.eq."ls") then
     1278   write(*,*) "Converting the time axis from sol to Ls..."
     1279else ! if (axis.eq."adls")
     1280   write(*,*) "Adding Ls as a 1D time variable"
     1281   call def_var(nout,"Ls","Solar Longitude","degree",1, (/timedimout/),nvarid,ierr)
     1282end if
     1283
    13581284ierr = NF_PUT_VAR_REAL(nid,nvarid,ls)
    1359 #endif
    13601285if (ierr.ne.NF_NOERR) then
    1361   write(*,*) "ERROR in change_time_axis: Failed to write Ls"
    1362   stop
     1286   write(*,*) "ERROR in change_time_axis: Failed to write Ls"
     1287   stop
    13631288endif
    13641289
     
    15021427
    15031428! Write valid_range() attribute
    1504 #ifdef NC_DOUBLE
    1505 ierr=NF_PUT_ATT_DOUBLE(nout,nvarid,'valid_range',NF_DOUBLE,2,valid_range)
    1506 #else
    15071429ierr=NF_PUT_ATT_REAL(nout,nvarid,'valid_range',NF_FLOAT,2,valid_range)
    1508 #endif
    15091430
    15101431if (ierr.ne.NF_NOERR) then
     
    15171438
    15181439! Write "missing_value" attribute
    1519 #ifdef NC_DOUBLE
    1520 ierr= NF_PUT_ATT_DOUBLE(nout,nvarid,'missing_value',NF_DOUBLE,1,missing)
    1521 #else
    15221440ierr= NF_PUT_ATT_REAL(nout,nvarid,'missing_value',NF_FLOAT,1,missing)
    1523 #endif
    15241441
    15251442if (ierr.NE.NF_NOERR) then
Note: See TracChangeset for help on using the changeset viewer.