Ignore:
Timestamp:
Sep 7, 2021, 9:57:37 AM (3 years ago)
Author:
abierjon
Message:

Mars GCM:
simu_MCS.F90 : now computes the column-integrated dust optical depths of the MCS and GCM files
(between levels with no missing values in both files, which vary with space and time) and outputs
the ratio tau_GCM/tau_MCS to be used to normalize the GCM dust opacity profiles when comparing to MCSake simu_MCS.F90 compatible with DYNAMICO lon-lat output files, with a check on the latitude array order when doing the interpolation

AB

File:
1 edited

Legend:

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

    r2540 r2558  
    2828!                           # dso(/dsodust/qdust)+rho --->   ddust,ndust (dust opacity/km)
    2929!                           # h2o_ice+rho             --->   dwice,nwice (water ice opacity/km)
     30!
     31! For dust especially, if a dust opacity variable has been created in the output file, the program also
     32! computes the ratio of the Column-integrated Dust Optical Depths from the binned GCM file and the
     33! MCS file, that can then be used to normalize the dust opacity profiles when doing comparisons.
    3034!
    3135! Eventually, the program outputs a netcdf file, filled with the GCM binned data for dayside
     
    9195!    3.4 Write the data in the netcdf output file
    9296! ..var loop ends]
    93 !  4. END OF THE DAY/NIGHT LOOP
     97!  4. CDOD RATIO (tau_GCM/tau_MCS)
     98!    4.1 Preliminary checks
     99!    4.2 tau_ratio computation
     100!    4.3 Write tau_ratio in the netcdf output file
     101!  5. END OF THE DAY/NIGHT LOOP
    94102!..day/night loop ends]
    95 5. CLOSE THE FILES
     1036. CLOSE THE FILES
    96104!
    97105!  Subroutines
     
    159167integer :: nbdim                                       ! nb of dimensions of a variable
    160168real,dimension(:,:,:,:),allocatable :: GCM_var,OBS_var ! the 4D variable extracted from GCM & OBS files
    161 real,dimension(:,:,:,:),allocatable :: rho             ! atmospheric density for opacities' computation
     169real,dimension(:,:,:,:),allocatable :: GCM_rho         ! atmospheric density for opacities' computation
    162170character(len=64) :: long_name,units,comment           ! netcdf attributes of the variable
    163171
     
    199207integer :: m       ! sol binning loops iteration index
    200208integer :: v,vnot  ! variable loops indices
     209
     210!------------------------
     211! CDOD ratio (tau_GCM/tau_MCS)
     212logical :: tau_ratio_ok ! true if it is possible to compute the CDOD ratio
     213
     214character(len=64)::out_dztauname,OBS_dztauname,OBS_tempname ! input variable names in files
     215integer :: out_dztauid,OBS_dztauid,OBS_tempid               ! input variable ID in files
     216
     217real,dimension(:,:,:,:),allocatable :: out_dztau,OBS_dztau ! the 4D dust opacities from outfile and obsfile
     218real,dimension(:,:,:,:),allocatable :: OBS_temp            ! temperature from obsfile
     219
     220real,dimension(:),allocatable :: OBS_plev ! pressure levels encompassing each Observer pressure levels
     221
     222real :: OBS_rho              ! temporary OBS atm density computed from OBS temp and pressure
     223real,parameter :: r_atm=191. ! Mars atmosphere specific gas constant
     224real,parameter :: g=3.72     ! Mars gravity
     225real :: out_tau,OBS_tau      ! integrated dust columns from GCM (outfile) and OBS
     226
     227real,dimension(:,:,:),allocatable :: tau_ratio ! ratio out_tau/OBS_tau
    201228
    202229
     
    655682  else
    656683    ! Length allocation for each dimension of the 4D variable
    657     allocate(rho(GCMlonlen,GCMlatlen,GCMaltlen,GCMtimelen))
     684    allocate(GCM_rho(GCMlonlen,GCMlatlen,GCMaltlen,GCMtimelen))
    658685
    659686    ! Load datasets
    660687    if (.not.is_stats) then
    661       status=NF90_GET_VAR(gcmfid,GCMvarid,rho)
     688      status=NF90_GET_VAR(gcmfid,GCMvarid,GCM_rho)
    662689      error_text="Failed to load rho"
    663690      call status_check(status,error_text)
    664691    else
    665692      ! if it is a stats file, we load only the first sol, and then copy it to all the other sols
    666       status=NF90_GET_VAR(gcmfid,GCMvarid,rho(:,:,:,1:GCMstatstimelen))
     693      status=NF90_GET_VAR(gcmfid,GCMvarid,GCM_rho(:,:,:,1:GCMstatstimelen))
    667694      error_text="Failed to load rho"
    668695      call status_check(status,error_text)
     
    671698      do l=(GCMstatstimelen+1),GCMtimelen
    672699        if (modulo(l,GCMstatstimelen).ne.0) then
    673           rho(:,:,:,l) = rho(:,:,:,modulo(l,GCMstatstimelen))
     700          GCM_rho(:,:,:,l) = GCM_rho(:,:,:,modulo(l,GCMstatstimelen))
    674701        else ! if l is a multiple of GCMstatstimelen, since the index modulo(l,GCMstatstimelen)=0
    675702             ! doesn't exist, we make a special case
    676           rho(:,:,:,l) = rho(:,:,:,GCMstatstimelen)
     703          GCM_rho(:,:,:,l) = GCM_rho(:,:,:,GCMstatstimelen)
    677704        endif
    678705      enddo
     
    10241051    GCMvarname = gcm_vars(v)
    10251052   
    1026     ! Detect the dust and wice opacities special cases
     1053    ! Detect the dust and wice opacities special cases         
    10271054    if (trim(GCMvarname).eq."dust") then
     1055      ! Default : dso > dsodust > dustq
    10281056      if (dustok1) then ! "dso" is detected in gcmfile
    10291057        GCMvarname="dso"
     
    10381066      write(*,*) "Computing dust opacity..."
    10391067    endif
     1068   
    10401069    if (trim(GCMvarname).eq."wice") then ! "h2o_ice" detected in gcmfile
    10411070      GCMvarname="h2o_ice"
     
    11421171            if (GCM_var(i,j,k,l).ne.GCMmiss_val) then
    11431172              ! Multiply by rho to have opacity [1/km]
    1144               GCM_var(i,j,k,l) = GCM_var(i,j,k,l) * rho(i,j,k,l) *1000.
     1173              GCM_var(i,j,k,l) = GCM_var(i,j,k,l) * GCM_rho(i,j,k,l) *1000.
    11451174
    11461175              if (long_name(index(long_name,"(")+1:index(long_name,")")-1).eq."TES") then
     
    11681197              ! assuming a rho_dust=3000 kg/m3 and an effective radius reff=1.06 microns
    11691198              ! + the opacity is here in 1/km and the MMR in kg/kg
    1170               GCM_var(i,j,k,l) = GCM_var(i,j,k,l) * rho(i,j,k,l) / 0.012 * 1000
     1199              GCM_var(i,j,k,l) = GCM_var(i,j,k,l) * GCM_rho(i,j,k,l) / 0.012 * 1000
    11711200            endif
    11721201          enddo
     
    11971226             ! We assume a rho_wice=920 kg/m3, an effective radius reff=3um,
    11981227             ! an extinction coefficient Qext(wvl,reff)=1.54471
    1199              GCM_var(i,j,k,l) = 750*1.54471* GCM_var(i,j,k,l) * rho(i,j,k,l) / (920*3e-6)
     1228             GCM_var(i,j,k,l) = 750*1.54471* GCM_var(i,j,k,l) * GCM_rho(i,j,k,l) / (920*3e-6)
    12001229           endif
    12011230         enddo
     
    15121541    deallocate(outvar)
    15131542  ENDDO VAR ! end loop on variables
     1543
     1544
     1545!===================================================================================
     1546! 4. CDOD RATIO (tau_GCM/tau_MCS)
     1547!===================================================================================
     1548!=============================================================================== 
     1549! 4.1 Preliminary checks
     1550!===============================================================================
     1551  if (OBSalttype.eq.'p') then
     1552    tau_ratio_ok = .true.
     1553  else
     1554    tau_ratio_ok = .false.
     1555  endif
     1556 
     1557  IF (dayornight.EQ."dayside") THEN
     1558    out_dztauname = "d"
     1559    OBS_dztauname = "ddust"
     1560    OBS_tempname = "dtemp"
     1561  ELSE ! i.e. dayornight="nightside"
     1562    out_dztauname = "n"
     1563    OBS_dztauname = "ndust"
     1564    OBS_tempname = "ntemp"
     1565  ENDIF
     1566 
     1567  ! Check that the output file contains dust opacity
     1568  ! NB: a dust opacity in outfile requires the dust
     1569  ! opacity variable to be present in the obsfile,
     1570  ! so we don't have to check it out
     1571  if (tau_ratio_ok) then
     1572    out_dztauname = out_dztauname(1:1)//"dust"
     1573    status=nf90_inq_varid(outfid,trim(out_dztauname),out_dztauid)
     1574    if (status.ne.nf90_noerr) then
     1575      ! if no "d/ndust" in outfile, look for "d/nopadust"
     1576      out_dztauname = out_dztauname(1:1)//"opadust"
     1577      status=nf90_inq_varid(outfid,trim(out_dztauname),out_dztauid)
     1578      if (status.ne.nf90_noerr) then
     1579        tau_ratio_ok = .false.
     1580        write(*,*)"No dust opacity in the outfile, we'll pass the computation of the CDOD ratio"
     1581      endif
     1582    endif
     1583  endif
     1584 
     1585  ! Check that the obsfile contains temperature (for rho computation)
     1586  if (tau_ratio_ok) then
     1587    status=nf90_inq_varid(obsfid,trim(OBS_tempname),OBS_tempid)
     1588    if (status.ne.nf90_noerr) then
     1589      tau_ratio_ok = .false.
     1590      write(*,*)"No temperature in the outfile, we'll pass the computation of the CDOD ratio"
     1591    endif
     1592  endif
     1593
     1594
     1595!=============================================================================== 
     1596! 4.2 tau_ratio computation
     1597!===============================================================================
     1598  if (tau_ratio_ok) then
     1599    write(*,*)"Computing the Column Dust Optical Depths ratio (tau_ratio = tau_GCM/tau_MCS)..."
     1600    write(*,*)"(it is recommended to use it to normalize the GCM dust profiles when comparing with MCS dust profiles)"
     1601   
     1602    ! Creation of the OBS_plev table
     1603    IF (dayornight.EQ."dayside") THEN ! only do it once
     1604      allocate(OBS_plev(OBSaltlen+1))
     1605      DO k=2,OBSaltlen
     1606        ! mid-altitude pressure between 2 OBS pressure layers (OBSalt)
     1607        ! NB: OBS_plev(k) > OBSalt(k) > OBS_plev(k+1)
     1608        OBS_plev(k) = sqrt(OBSalt(k-1)*OBSalt(k))
     1609      ENDDO
     1610      OBS_plev(1)=2000.
     1611      OBS_plev(OBSaltlen+1)=0
     1612      write(*,*)"OBS_plev = ",OBS_plev
     1613    ENDIF
     1614   
     1615    ! Arrays allocation
     1616    allocate(out_dztau(OBSlonlen,OBSlatlen,OBSaltlen,OBSLslen))
     1617    allocate(OBS_dztau(OBSlonlen,OBSlatlen,OBSaltlen,OBSLslen))
     1618    allocate(OBS_temp(OBSlonlen,OBSlatlen,OBSaltlen,OBSLslen))
     1619   
     1620    allocate(tau_ratio(OBSlonlen,OBSlatlen,OBSLslen))
     1621    tau_ratio(:,:,:) = 0
     1622   
     1623    ! Load GCM opacity
     1624    status=NF90_GET_VAR(outfid,out_dztauid,out_dztau)
     1625    error_text="Failed to load outfile dust opacity"
     1626    call status_check(status,error_text)
     1627   
     1628    ! Load OBS opacity
     1629    status=nf90_inq_varid(obsfid,trim(OBS_dztauname),OBS_dztauid)
     1630    status=NF90_GET_VAR(OBSfid,OBS_dztauid,OBS_dztau)
     1631    error_text="Failed to load obsfile dust opacity"
     1632    call status_check(status,error_text)
     1633   
     1634    ! Load OBS temperature
     1635    status=NF90_GET_VAR(OBSfid,OBS_tempid,OBS_temp)
     1636    error_text="Failed to load obsfile temperature"
     1637    call status_check(status,error_text)
     1638   
     1639    do l=1,OBSLslen
     1640     do j=1,OBSlatlen
     1641      do i=1,OBSlonlen
     1642        ! initialize both columns to 0
     1643        out_tau = 0
     1644        OBS_tau = 0
     1645        do k=1,OBSlatlen
     1646          ! Compute optical depths where both GCM and OBS have non-missing values
     1647          ! (especially above the highest (in altitude) of the lowest (in altitude) valid values in the GCM and Observer profile)
     1648          IF ((out_dztau(i,j,k,l).ne.OBSmiss_val).and.(OBS_dztau(i,j,k,l).ne.OBSmiss_val).and.(OBS_temp(i,j,k,l).ne.OBSmiss_val)) then
     1649            OBS_rho = OBSalt(k) / (r_atm*OBS_temp(i,j,k,l))
     1650           
     1651            OBS_tau = OBS_tau + OBS_dztau(i,j,k,l)*1.e-3 / OBS_rho /g *(OBS_plev(k)-OBS_plev(k+1))
     1652           
     1653            out_tau = out_tau + out_dztau(i,j,k,l)*1.e-3 / OBS_rho /g *(OBS_plev(k)-OBS_plev(k+1))
     1654           
     1655          ENDIF
     1656        enddo !alt
     1657       
     1658        ! Compute the Column Dust Optical Depth ratio
     1659        if ((out_tau.eq.0).or.(OBS_tau.eq.0)) then
     1660          tau_ratio(i,j,l) = LTmiss_val
     1661        else
     1662          tau_ratio(i,j,l) = out_tau/OBS_tau
     1663        endif
     1664       
     1665      enddo !lon
     1666     enddo !lat
     1667    enddo !Ls
     1668
     1669
     1670!=============================================================================== 
     1671! 4.3 Write tau_ratio in the netcdf output file
     1672!===============================================================================
     1673    ! Switch to netcdf define mode
     1674    status=nf90_redef(outfid)
     1675    error_text="Error: could not switch to define mode in the outfile"
     1676    call status_check(status,error_text)
     1677
     1678    ! Definition of the variable
     1679    SELECT CASE (dayornight)
     1680    CASE ("dayside")
     1681      outvarname = "dtau_ratio"
     1682    CASE ("nightside")
     1683      outvarname = "ntau_ratio"
     1684    END SELECT
     1685    status=NF90_DEF_VAR(outfid,trim(outvarname),nf90_float,LTshape,outvarid)
     1686    error_text="Error: could not define the variable "//trim(outvarname)//" in the outfile"
     1687    call status_check(status,error_text)
     1688
     1689    ! Write the attributes
     1690    long_name = "Integrated optical depths ratio tau_GCM/tau_MCS"
     1691    SELECT CASE (dayornight)
     1692    CASE ("dayside")
     1693      long_name = trim(long_name)//" - day side"
     1694      status=nf90_put_att(outfid,outvarid,"long_name",long_name)
     1695    CASE ("nightside")
     1696      long_name = trim(long_name)//" - night side"
     1697      status=nf90_put_att(outfid,outvarid,"long_name",long_name)
     1698    END SELECT
     1699    status=nf90_put_att(outfid,outvarid,"units","/")
     1700    status=nf90_put_att(outfid,outvarid,"_FillValue",LTmiss_val)
     1701    comment = "Reference numbin: dust+temp"
     1702    status=nf90_put_att(outfid,outvarid,"comment",comment)
     1703
     1704    write(*,*)trim(outvarname)," has been created in the outfile"
     1705    write(*,'("  with missing_value attribute : ",1pe12.5)')LTmiss_val
     1706    write(*,*)""
     1707
     1708    ! End the netcdf define mode (and thus enter the "data writing" mode)
     1709    status=nf90_enddef(outfid)
     1710    error_text="Error: could not close the define mode of the outfile"
     1711    call status_check(status,error_text)
     1712
     1713    ! Write data
     1714    status = nf90_put_var(outfid, outvarid, tau_ratio)
     1715    error_text="Error: could not write "//trim(outvarname)//" data in the outfile"
     1716    call status_check(status,error_text)
     1717
     1718    ! Deallocations
     1719    deallocate(out_dztau)
     1720    deallocate(OBS_dztau)
     1721    deallocate(OBS_temp)
     1722    deallocate(tau_ratio)
     1723
     1724  endif !tau_ratio_ok
     1725 
    15141726 
    15151727!=================================================================================== 
    1516 ! 4. END OF THE DAY/NIGHT LOOP
     1728! 5. END OF THE DAY/NIGHT LOOP
    15171729!===================================================================================
    15181730  IF (dayornight.EQ."dayside") THEN
     
    15341746
    15351747!===================================================================================
    1536 ! 5. CLOSE THE FILES
     1748! 6. CLOSE THE FILES
    15371749!===================================================================================
    15381750status = nf90_close(gcmfid)
Note: See TracChangeset for help on using the changeset viewer.