- Timestamp:
- Sep 7, 2021, 9:57:37 AM (4 years ago)
- Location:
- trunk/LMDZ.MARS
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LMDZ.MARS/README
r2554 r2558 3438 3438 Make NO and O2 Nightglow emissions computations more flexible (reaction index 3439 3439 no longer hard coded in photochemistry.F90). 3440 3441 == 07/09/2021 == AB 3442 simu_MCS.F90 : now computes the column-integrated dust optical depths of the MCS and GCM files 3443 (between levels with no missing values in both files, which vary with space and time) and outputs 3444 the ratio tau_GCM/tau_MCS to be used to normalize the GCM dust opacity profiles when comparing to MCS -
trunk/LMDZ.MARS/util/simu_MCS.F90
r2540 r2558 28 28 ! # dso(/dsodust/qdust)+rho ---> ddust,ndust (dust opacity/km) 29 29 ! # 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. 30 34 ! 31 35 ! Eventually, the program outputs a netcdf file, filled with the GCM binned data for dayside … … 91 95 ! 3.4 Write the data in the netcdf output file 92 96 ! ..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 94 102 !..day/night loop ends] 95 ! 5. CLOSE THE FILES103 ! 6. CLOSE THE FILES 96 104 ! 97 105 ! Subroutines … … 159 167 integer :: nbdim ! nb of dimensions of a variable 160 168 real,dimension(:,:,:,:),allocatable :: GCM_var,OBS_var ! the 4D variable extracted from GCM & OBS files 161 real,dimension(:,:,:,:),allocatable :: rho! atmospheric density for opacities' computation169 real,dimension(:,:,:,:),allocatable :: GCM_rho ! atmospheric density for opacities' computation 162 170 character(len=64) :: long_name,units,comment ! netcdf attributes of the variable 163 171 … … 199 207 integer :: m ! sol binning loops iteration index 200 208 integer :: v,vnot ! variable loops indices 209 210 !------------------------ 211 ! CDOD ratio (tau_GCM/tau_MCS) 212 logical :: tau_ratio_ok ! true if it is possible to compute the CDOD ratio 213 214 character(len=64)::out_dztauname,OBS_dztauname,OBS_tempname ! input variable names in files 215 integer :: out_dztauid,OBS_dztauid,OBS_tempid ! input variable ID in files 216 217 real,dimension(:,:,:,:),allocatable :: out_dztau,OBS_dztau ! the 4D dust opacities from outfile and obsfile 218 real,dimension(:,:,:,:),allocatable :: OBS_temp ! temperature from obsfile 219 220 real,dimension(:),allocatable :: OBS_plev ! pressure levels encompassing each Observer pressure levels 221 222 real :: OBS_rho ! temporary OBS atm density computed from OBS temp and pressure 223 real,parameter :: r_atm=191. ! Mars atmosphere specific gas constant 224 real,parameter :: g=3.72 ! Mars gravity 225 real :: out_tau,OBS_tau ! integrated dust columns from GCM (outfile) and OBS 226 227 real,dimension(:,:,:),allocatable :: tau_ratio ! ratio out_tau/OBS_tau 201 228 202 229 … … 655 682 else 656 683 ! Length allocation for each dimension of the 4D variable 657 allocate( rho(GCMlonlen,GCMlatlen,GCMaltlen,GCMtimelen))684 allocate(GCM_rho(GCMlonlen,GCMlatlen,GCMaltlen,GCMtimelen)) 658 685 659 686 ! Load datasets 660 687 if (.not.is_stats) then 661 status=NF90_GET_VAR(gcmfid,GCMvarid, rho)688 status=NF90_GET_VAR(gcmfid,GCMvarid,GCM_rho) 662 689 error_text="Failed to load rho" 663 690 call status_check(status,error_text) 664 691 else 665 692 ! 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)) 667 694 error_text="Failed to load rho" 668 695 call status_check(status,error_text) … … 671 698 do l=(GCMstatstimelen+1),GCMtimelen 672 699 if (modulo(l,GCMstatstimelen).ne.0) then 673 rho(:,:,:,l) =rho(:,:,:,modulo(l,GCMstatstimelen))700 GCM_rho(:,:,:,l) = GCM_rho(:,:,:,modulo(l,GCMstatstimelen)) 674 701 else ! if l is a multiple of GCMstatstimelen, since the index modulo(l,GCMstatstimelen)=0 675 702 ! doesn't exist, we make a special case 676 rho(:,:,:,l) =rho(:,:,:,GCMstatstimelen)703 GCM_rho(:,:,:,l) = GCM_rho(:,:,:,GCMstatstimelen) 677 704 endif 678 705 enddo … … 1024 1051 GCMvarname = gcm_vars(v) 1025 1052 1026 ! Detect the dust and wice opacities special cases 1053 ! Detect the dust and wice opacities special cases 1027 1054 if (trim(GCMvarname).eq."dust") then 1055 ! Default : dso > dsodust > dustq 1028 1056 if (dustok1) then ! "dso" is detected in gcmfile 1029 1057 GCMvarname="dso" … … 1038 1066 write(*,*) "Computing dust opacity..." 1039 1067 endif 1068 1040 1069 if (trim(GCMvarname).eq."wice") then ! "h2o_ice" detected in gcmfile 1041 1070 GCMvarname="h2o_ice" … … 1142 1171 if (GCM_var(i,j,k,l).ne.GCMmiss_val) then 1143 1172 ! 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. 1145 1174 1146 1175 if (long_name(index(long_name,"(")+1:index(long_name,")")-1).eq."TES") then … … 1168 1197 ! assuming a rho_dust=3000 kg/m3 and an effective radius reff=1.06 microns 1169 1198 ! + 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 * 10001199 GCM_var(i,j,k,l) = GCM_var(i,j,k,l) * GCM_rho(i,j,k,l) / 0.012 * 1000 1171 1200 endif 1172 1201 enddo … … 1197 1226 ! We assume a rho_wice=920 kg/m3, an effective radius reff=3um, 1198 1227 ! 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) 1200 1229 endif 1201 1230 enddo … … 1512 1541 deallocate(outvar) 1513 1542 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 1514 1726 1515 1727 !=================================================================================== 1516 ! 4. END OF THE DAY/NIGHT LOOP1728 ! 5. END OF THE DAY/NIGHT LOOP 1517 1729 !=================================================================================== 1518 1730 IF (dayornight.EQ."dayside") THEN … … 1534 1746 1535 1747 !=================================================================================== 1536 ! 5. CLOSE THE FILES1748 ! 6. CLOSE THE FILES 1537 1749 !=================================================================================== 1538 1750 status = nf90_close(gcmfid)
Note: See TracChangeset
for help on using the changeset viewer.