Changeset 2289 for trunk/LMDZ.MARS/util


Ignore:
Timestamp:
Apr 16, 2020, 7:11:13 PM (5 years ago)
Author:
abierjon
Message:

Mars GCM:
Add the program solzenangle.F90 to the LMDZ.MARS/util/ directory, as well as a solzenangle.def
This program actually replaces and seals the dark fate of the former program terminator.F90
It can be used to interpolate GCM files at one given solar zenith angle
(on the morning-side or the evening-side) all around the globe (the terminator corresponding to sza = 90deg)
By Alwont Beebak

Location:
trunk/LMDZ.MARS/util
Files:
2 moved

Legend:

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

    r2288 r2289  
    1 program terminator
     1program solzenangle
    22
    33! ----------------------------------------------------------------------------
    44! Program to redistribute and interpolate the variables at the local time
    5 ! corresponding to one terminator (morning or evening) everywhere
     5! corresponding to one solar zenith angle (morning or evening) everywhere
     6! It can especially be used for the terminator (sza=90deg)
    67! input : diagfi.nc  / concat.nc / stats.nc kind of files
    78! authors: A.Bierjon,F.Forget,2020
     
    3334! altpositive(): [netcdf] altitude "positive" attribute
    3435
    35 character (len=8) :: sunterm
    36 ! sunterm(): type of terminator ("sunrise" for the morning, "sunset" for the evening)
     36character (len=7) :: planetside
     37! planetside(): planet side of the solar zenith angle ("morning" or "evening")
    3738
    3839integer :: nid,ierr,miss,validr
     
    103104real, dimension(:), allocatable :: intsol
    104105real, dimension(:,:,:), allocatable :: lt_out
     106real :: sza ! solar zenith angle
     107character (len=30) :: szastr ! to store the sza value in a string
    105108real :: starttimeoffset ! offset (in sols) of sol 0 in input file, wrt Ls=0
    106109real :: tmpsol ! to temporarily store a sol value
     
    113116real :: miss_lt
    114117PARAMETER(miss_lt=1E+20)
    115 ! miss_lt: [netcdf] missing value to write for the terminator Local Time in the output file
     118! miss_lt: [netcdf] missing value to write for the Local Time in the output file
    116119real, dimension(2) :: valid_range
    117120! valid_range(2): [netcdf] interval in which a value is considered valid
     
    122125! 1.1. Get input file name(s)
    123126!==============================================================================
     127write(*,*) "Welcome in the solar zenith angle interpolator program !"
    124128write(*,*)
    125129write(*,*) "which file do you want to use?  (diagfi... stats...  concat...)"
     
    430434! 2.4.1 Select local times to be saved "Time" in output file
    431435!==============================================================================
    432       write(*,*) 'Type of terminator?'
    433       read(*,*) sunterm
    434       if ((trim(sunterm).ne."sunrise").and.(trim(sunterm).ne."sunset")) then
    435         write(*,*) "sunterm = "//sunterm
    436         write(*,*) "Error: terminator type must be sunrise or sunset"
     436      write(*,*) "Planet side of the Solar Zenith Angle ?"
     437      read(*,*) planetside
     438      if ((trim(planetside).ne."morning").and.(trim(planetside).ne."evening")) then
     439        write(*,*) "planetside = "//planetside
     440        write(*,*) "Error: the planet side must be morning or evening"
     441        stop
     442      endif
     443      write(*,*) "Solar Zenith angle to interpolate ?"
     444      write(*,*) "(between 0 and 180 deg, 90deg for the terminator at the surface)"
     445      read(*,*) sza
     446      if ((sza.lt.0).or.(sza.ge.180)) then
     447        write(*,*) "ERROR: the solar zenith angle must lie within [0;180[ deg"
    437448        stop
    438449      endif
     
    470481        do ilon=1,lonlen
    471482!         For the computation of Ls, it's supposed that the morning/evening
    472 !         terminator happens at LT=6h/18h at the given longitude, which is
     483!         correspond to LT=6h/18h at the given longitude, which is
    473484!         then reported to a sol value at longitude 0
    474           if (trim(sunterm).eq."sunrise") then
     485          if (trim(planetside).eq."morning") then
    475486            tmpsol = intsol(it) + (6.-lon(ilon)/15.)/24. + starttimeoffset
    476           else !if trim(sunterm).eq."sunset"
     487          else !if trim(planetside).eq."evening"
    477488            tmpsol = intsol(it) + (18.-lon(ilon)/15.)/24. + starttimeoffset           
    478489          endif
    479490          call sol2ls(tmpsol,tmpLs)
    480491          do ilat=1,latlen
    481 !           Compute the Local Time of the terminator at a given longitude
    482             call LTterminator(lat(ilat),tmpLs,sunterm,miss_lt,tmpLT)
     492!           Compute the Local Time of the solar zenith angle at a given longitude
     493            call LTsolzenangle(lat(ilat),tmpLs,planetside,sza,miss_lt,tmpLT)
    483494!           Deduce the sol value at this longitude
    484495            if (tmpLT.eq.miss_lt) then
    485               ! if there is no terminator, put a missing value in lt_out
     496              ! if there is no LT corresponding to the sza, put a missing value in lt_out
    486497              lt_out(ilon,ilat,it)=miss_lt
    487498            else
     
    517528! 2.4.2. Get output file name
    518529!==============================================================================
    519     if (trim(sunterm).eq."sunrise") then
    520       filename=file(1:len_trim(file)-3)//"_TMO.nc"
    521     else ! if trim(sunterm).eq."sunset"
    522       filename=file(1:len_trim(file)-3)//"_TEV.nc"
     530    if (trim(planetside).eq."morning") then
     531      filename=file(1:len_trim(file)-3)//"_MO.nc"
     532    else ! if trim(planetside).eq."evening"
     533      filename=file(1:len_trim(file)-3)//"_EV.nc"
    523534    endif
    524535
     
    741752
    742753!==============================================================================
    743 ! 2.5.6 Write the terminator Local Time variable in output file
    744 !==============================================================================
    745    write(*,*) "variable LTterminator"
     754! 2.5.6 Write the solar zenith angle Local Time variable in output file
     755!==============================================================================
     756   write(*,*) "variable LTsolzenangle"
    746757   ! build dim(),corner() and edges() arrays
    747758   dim(1)=londimout
     
    761772   edges(4)=1
    762773
    763    tmpvar="LTterminator"
    764    units="hour(LTST)"
    765    if (trim(sunterm).eq."sunrise") then
    766      title="Morning Terminator Local Time"
    767    else !if trim(sunterm).eq."sunset"
    768      title="Evening Terminator Local Time"           
     774   tmpvar="LTsolzenangle"
     775   units="hours"
     776   write(szastr,*) sza
     777   if (trim(planetside).eq."morning") then
     778     title="Morning-side LTST at sza="//trim(adjustl(szastr))//"deg"
     779   else !if trim(planetside).eq."evening"
     780     title="Evening-side LTST at sza="//trim(adjustl(szastr))//"deg"           
    769781   endif
    770782   call def_var(nout,tmpvar,title,units,3,dim,varidout,ierr)
     
    802814write(*,*) "Program completed !"
    803815
    804 end program terminator
     816end program solzenangle
    805817
    806818
     
    14141426
    14151427!******************************************************************************
    1416 subroutine LTterminator(lat,ls,sunterm,missval,lt_term)
    1417 ! compute the terminator localtime by inversing
     1428subroutine LTsolzenangle(lat,ls,planetside,sza,missval,lt_sza)
     1429! compute the localtime by inversing
    14181430! the solar zenith angle equation :
    1419 ! mu0=sin(lat)*sin(declin)+
    1420 !     cos(lat)*cos(declin)*cos(2.*pi*(localtime/24.-.5))
    1421 ! for mu0=cos(sza)=0 (since sza=90deg at the terminator)
     1431! cos(sza)=sin(lat)*sin(declin)
     1432!         +cos(lat)*cos(declin)*cos(2.*pi*(localtime/24.-.5))
     1433
    14221434
    14231435implicit none
     
    14251437real,intent(in) :: lat ! latitude (deg)
    14261438real,intent(in) :: ls ! solar longitude (deg)
    1427 character (len=8), intent(in) :: sunterm ! terminator type : "sunrise" for morning,"sunset" for evening
    1428 real,intent(in) :: missval ! missing value for when there is no terminator (polar day/night)
    1429 real,intent(out) :: lt_term ! local true solar time (hours) of the terminator
     1439character (len=7), intent(in) :: planetside ! planet side : "morning" or "evening"
     1440real,intent(in) :: sza ! solar zenith angle (deg) (within [0;180[)
     1441real,intent(in) :: missval ! missing value for when there is no associated LT (polar day/night)
     1442real,intent(out) :: lt_sza ! local true solar time (hours) corresponding to the sza
    14301443
    14311444! local variables:
    14321445double precision :: declin ! declination of the Sun (rad)
     1446double precision :: tmpcos ! to temporarily store a cosine value
    14331447double precision,parameter :: obliquity=25.1919d0
    14341448double precision,parameter :: pi=3.14159265358979d0
     
    14391453declin=ASIN(sin(ls*degtorad)*sin(obliquity*degtorad))
    14401454
     1455! Small checks
     1456if ((cos(lat*degtorad).eq.0).or.(cos(declin).eq.0)) then
     1457  write(*,*) "ERROR in LTsolzenangle : lat and declin can't have their cosine equal to zero"
     1458  stop
     1459endif
     1460
    14411461! Compute Local Time
    1442 if (((-tan(lat*degtorad)*tan(declin)).gt.1.).or.(((-tan(lat*degtorad)*tan(declin)).lt.(-1.)))) then
     1462tmpcos = cos(sza*degtorad)/(cos(lat*degtorad)*cos(declin)) - tan(lat*degtorad)*tan(declin)
     1463
     1464if ((tmpcos.gt.1.).or.(tmpcos.lt.(-1.))) then
    14431465  ! Detect Polar Day and Polar Night (values out of the arccos definition domain)
    1444   lt_term = missval
     1466  lt_sza = missval
    14451467 
    14461468else
    14471469
    1448   if (trim(sunterm).eq."sunrise") then
    1449   ! Local Time of the Morning Terminator
    1450     lt_term = 24*(0.5 - ACOS(-tan(lat*degtorad)*tan(declin))/(2.*pi))
    1451   else ! if trim(sunterm).eq."sunset"
    1452   ! Local Time of the Evening Terminator
    1453     lt_term = 24*(0.5 + ACOS(-tan(lat*degtorad)*tan(declin))/(2.*pi))
     1470  if (trim(planetside).eq."morning") then
     1471  ! Local Time of the Morning-side Solar Zenith Angle
     1472    lt_sza = 24*(0.5 - ACOS(tmpcos)/(2.*pi))
     1473  else ! if trim(planetside).eq."evening"
     1474  ! Local Time of the Evening-side Solar Zenith Angle
     1475    lt_sza = 24*(0.5 + ACOS(tmpcos)/(2.*pi))
    14541476  endif
    14551477 
    14561478endif
    14571479
    1458 end subroutine LTterminator
     1480end subroutine LTsolzenangle
    14591481
    14601482!******************************************************************************
  • trunk/LMDZ.MARS/util/solzenangle.def

    r2288 r2289  
    44temp
    55
    6 sunrise
     6morning
     790
    780
    89
    910-----------------------------------------------------------------------
    10 ABOVE is the list of inputs to be fed to "terminator.e" if you don t want
     11ABOVE is the list of inputs to be fed to "solzenangle.e" if you don t want
    1112to reply directly to the program:
    1213
     
    14152) List of X variables to be kept (X lines) or 'all'
    15163) blank line at the end
    16 4) terminator type (sunrise or sunset)
    17 5) starttimeoffset :
     174) planet side wrt to noon (morning or evening)
     185) solar zenith angle (within [0;180[ deg)
     190deg = zenith ; 90deg = terminator at the surface ; >90deg = terminator in altitude
     206) starttimeoffset :
    1821    - for a diagfi/concat : sol value at the beginning of the run, wrt Ls=0
    1922    - for a stats : sol value at the middle of the run, wrt Ls=0
    2023
    2124USE :
    22 terminator.e < terminator.def
     25solzenangle.e < solzenangle.def
    2326
    2427
Note: See TracChangeset for help on using the changeset viewer.