LCOV - code coverage report
Current view: | top level - chemistry/mozart - tracer_cnst.F90 (source / functions) |  |  | Hit | Total | Coverage
Test: | coverage.info |  | Lines: | 101 | 116 | 87.1 %
Date: | 2024-12-17 22:39:59 |  | Functions: | 9 | 9 | 100.0 %

              Line data    Source code
           1             : !-------------------------------------------------------------------
           2             : ! manages reading and interpolation of offline tracer fields
           3             : ! Created by: Francis Vitt -- 2 May 2006
           4             : !-------------------------------------------------------------------
           5             : module tracer_cnst
           6             :
           7             :   use shr_kind_mod,     only : r8 => shr_kind_r8
           8             :   use cam_abortutils,   only : endrun
           9             :   use spmd_utils,       only : masterproc
          10             :   use tracer_data,      only : trfld,trfile,MAXTRCRS
          11             :   use cam_logfile,      only : iulog
          12             :
          13             :   implicit none
          14             :
          15             :   private  ! all unless made public
          16             :   save
          17             :
          18             :   public :: tracer_cnst_init
          19             :   public :: num_tracer_cnst
          20             :   public :: tracer_cnst_flds
          21             :   public :: tracer_cnst_adv
          22             :   public :: get_cnst_data
          23             :   public :: get_cnst_data_ptr
          24             :   public :: write_tracer_cnst_restart
          25             :   public :: read_tracer_cnst_restart
          26             :   public :: tracer_cnst_defaultopts
          27             :   public :: tracer_cnst_setopts
          28             :   public :: init_tracer_cnst_restart
          29             :
          30             :   type(trfld), pointer :: fields(:) => null()
          31             :   type(trfile) :: file
          32             :
          33             :   integer :: num_tracer_cnst
          34             :   character(len=16), pointer :: tracer_cnst_flds(:) => null()
          35             :   real(r8), allocatable, target, dimension(:,:,:,:) :: data_q  ! constituent mass mixing ratios
          36             :
          37             :   character(len=64)  :: specifier(MAXTRCRS) = ''
          38             :   character(len=256) :: filename = 'tracer_cnst_file'
          39             :   character(len=256) :: filelist = ''
          40             :   character(len=256) :: datapath = ''
          41             :   character(len=32)  :: data_type = 'SERIAL'
          42             :   logical            :: rmv_file = .false.
          43             :   integer            :: cycle_yr  = 0
          44             :   integer            :: fixed_ymd = 0
          45             :   integer            :: fixed_tod = 0
          46             :
          47             : contains
          48             :
          49             : !-------------------------------------------------------------------
          50             : !-------------------------------------------------------------------
          51        2304 :   subroutine tracer_cnst_init()
          52             :
          53             :     use mo_chem_utls,only : get_inv_ndx
          54             :     use tracer_data, only : trcdata_init
          55             :     use cam_history, only : addfld
          56             :     use error_messages, only: handle_err
          57             :     use ppgrid,         only: pcols, pver, begchunk, endchunk
          58             :     use physics_buffer, only : physics_buffer_desc
          59             :
          60             :     implicit none
          61             :
          62             :     integer :: i ,ndx, istat
          63             :
          64        1536 :     allocate(file%in_pbuf(size(specifier)))
          65      155136 :     file%in_pbuf(:) = .false.
          66             :     call trcdata_init( specifier, filename, filelist, datapath, fields, file, &
          67        1536 :                        rmv_file, cycle_yr, fixed_ymd, fixed_tod, data_type)
          68             :
          69        1536 :     num_tracer_cnst = 0
          70        1536 :     if (associated(fields)) num_tracer_cnst = size( fields )
          71             :
          72        1536 :     if( num_tracer_cnst < 1 ) then
          73           0 :        if ( masterproc ) then
          74           0 :           write(iulog,*) 'There are no offline invariant species'
          75           0 :           write(iulog,*) ' '
          76             :        endif
          77             :        return
          78             :     end if
          79             :
          80        4608 :     allocate( tracer_cnst_flds(num_tracer_cnst), stat=istat)
          81        1536 :     call handle_err(istat, 'tracer_cnst_init: ERROR allocating tracer_cnst_flds')
          82             :
          83             :
          84        9216 :     do i = 1, num_tracer_cnst
          85             :
          86        7680 :        ndx = get_inv_ndx( fields(i)%fldnam )
          87             :
          88        7680 :        if (ndx < 1) then
          89           0 :           write(iulog,*) fields(i)%fldnam//' is not an invariant'
          90           0 :           call endrun('tracer_cnst_init')
          91             :        endif
          92             :
          93        7680 :        tracer_cnst_flds(i) = fields(i)%fldnam
          94             :
          95           0 :        call addfld(trim(fields(i)%fldnam), (/ 'lev' /), &
          96       16896 :                    'I','mol/mol', 'prescribed tracer constituent' )
          97             :     enddo
          98             :
          99        6144 :     allocate(data_q(pcols,pver,num_tracer_cnst,begchunk:endchunk), stat=istat)
         100        1536 :     call handle_err(istat, 'tracer_cnst_init: ERROR allocating data_q')
         101             :
         102        1536 :   end subroutine tracer_cnst_init
         103             :
         104             : !-------------------------------------------------------------------
         105             : !-------------------------------------------------------------------
         106        1536 :   subroutine tracer_cnst_setopts(       &
         107             :        tracer_cnst_file_in,      &
         108             :        tracer_cnst_filelist_in,  &
         109             :        tracer_cnst_datapath_in,  &
         110             :        tracer_cnst_type_in,      &
         111        1536 :        tracer_cnst_specifier_in, &
         112             :        tracer_cnst_rmfile_in,    &
         113             :        tracer_cnst_cycle_yr_in,  &
         114             :        tracer_cnst_fixed_ymd_in, &
         115             :        tracer_cnst_fixed_tod_in  &
         116             :        )
         117             :
         118             :     implicit none
         119             :
         120             :     character(len=*), intent(in), optional :: tracer_cnst_file_in
         121             :     character(len=*), intent(in), optional :: tracer_cnst_filelist_in
         122             :     character(len=*), intent(in), optional :: tracer_cnst_datapath_in
         123             :     character(len=*), intent(in), optional :: tracer_cnst_type_in
         124             :     character(len=*), intent(in), optional :: tracer_cnst_specifier_in(:)
         125             :     logical,          intent(in), optional :: tracer_cnst_rmfile_in
         126             :     integer,          intent(in), optional :: tracer_cnst_cycle_yr_in
         127             :     integer,          intent(in), optional :: tracer_cnst_fixed_ymd_in
         128             :     integer,          intent(in), optional :: tracer_cnst_fixed_tod_in
         129             :
         130        1536 :     if ( present(tracer_cnst_file_in) ) then
         131        1536 :        filename = tracer_cnst_file_in
         132             :     endif
         133        1536 :     if ( present(tracer_cnst_filelist_in) ) then
         134        1536 :        filelist = tracer_cnst_filelist_in
         135             :     endif
         136        1536 :     if ( present(tracer_cnst_datapath_in) ) then
         137        1536 :        datapath = tracer_cnst_datapath_in
         138             :     endif
         139        1536 :     if ( present(tracer_cnst_type_in) ) then
         140        1536 :        data_type = tracer_cnst_type_in
         141             :     endif
         142        1536 :     if ( present(tracer_cnst_specifier_in) ) then
         143      156672 :        specifier = tracer_cnst_specifier_in
         144             :     endif
         145        1536 :     if ( present(tracer_cnst_rmfile_in) ) then
         146        1536 :        rmv_file = tracer_cnst_rmfile_in
         147             :     endif
         148        1536 :     if ( present(tracer_cnst_cycle_yr_in) ) then
         149        1536 :        cycle_yr = tracer_cnst_cycle_yr_in
         150             :     endif
         151        1536 :     if ( present(tracer_cnst_fixed_ymd_in) ) then
         152        1536 :        fixed_ymd = tracer_cnst_fixed_ymd_in
         153             :     endif
         154        1536 :     if ( present(tracer_cnst_fixed_tod_in) ) then
         155        1536 :        fixed_tod = tracer_cnst_fixed_tod_in
         156             :     endif
         157             :
         158        3072 :   endsubroutine tracer_cnst_setopts
         159             :
         160             : !-------------------------------------------------------------------
         161             : !-------------------------------------------------------------------
         162        1536 :   subroutine tracer_cnst_defaultopts(   &
         163             :        tracer_cnst_file_out,     &
         164             :        tracer_cnst_filelist_out, &
         165             :        tracer_cnst_datapath_out, &
         166             :        tracer_cnst_type_out,     &
         167        1536 :        tracer_cnst_specifier_out,&
         168             :        tracer_cnst_rmfile_out,   &
         169             :        tracer_cnst_cycle_yr_out, &
         170             :        tracer_cnst_fixed_ymd_out,&
         171             :        tracer_cnst_fixed_tod_out &
         172             :        )
         173             :
         174             :     implicit none
         175             :
         176             :     character(len=*), intent(out), optional :: tracer_cnst_file_out
         177             :     character(len=*), intent(out), optional :: tracer_cnst_filelist_out
         178             :     character(len=*), intent(out), optional :: tracer_cnst_datapath_out
         179             :     character(len=*), intent(out), optional :: tracer_cnst_type_out
         180             :     character(len=*), intent(out), optional :: tracer_cnst_specifier_out(:)
         181             :     logical,          intent(out), optional :: tracer_cnst_rmfile_out
         182             :     integer,          intent(out), optional :: tracer_cnst_cycle_yr_out
         183             :     integer,          intent(out), optional :: tracer_cnst_fixed_ymd_out
         184             :     integer,          intent(out), optional :: tracer_cnst_fixed_tod_out
         185             :
         186        1536 :     if ( present(tracer_cnst_file_out) ) then
         187        1536 :        tracer_cnst_file_out = filename
         188             :     endif
         189        1536 :     if ( present(tracer_cnst_filelist_out) ) then
         190        1536 :        tracer_cnst_filelist_out = filelist
         191             :     endif
         192        1536 :     if ( present(tracer_cnst_datapath_out) ) then
         193        1536 :        tracer_cnst_datapath_out = datapath
         194             :     endif
         195        1536 :     if ( present(tracer_cnst_type_out) ) then
         196        1536 :        tracer_cnst_type_out = data_type
         197             :     endif
         198        1536 :     if ( present(tracer_cnst_specifier_out) ) then
         199      156672 :        tracer_cnst_specifier_out = specifier
         200             :     endif
         201        1536 :     if ( present(tracer_cnst_rmfile_out) ) then
         202        1536 :        tracer_cnst_rmfile_out = rmv_file
         203             :     endif
         204        1536 :     if ( present(tracer_cnst_cycle_yr_out) ) then
         205        1536 :        tracer_cnst_cycle_yr_out = cycle_yr
         206             :     endif
         207        1536 :     if ( present(tracer_cnst_fixed_ymd_out) ) then
         208        1536 :        tracer_cnst_fixed_ymd_out = fixed_ymd
         209             :     endif
         210        1536 :     if ( present(tracer_cnst_fixed_tod_out) ) then
         211        1536 :        tracer_cnst_fixed_tod_out = fixed_tod
         212             :     endif
         213             :
         214        1536 :   endsubroutine tracer_cnst_defaultopts
         215             :
         216             : !-------------------------------------------------------------------
         217             : !-------------------------------------------------------------------
         218      741888 :   subroutine tracer_cnst_adv( pbuf2d, state )
         219             :
         220             :     use physics_buffer, only : physics_buffer_desc
         221             :     use tracer_data,  only : advance_trcdata
         222             :     use physics_types,only : physics_state
         223             :     use ppgrid,       only : begchunk, endchunk
         224             :     use ppgrid,       only : pcols, pver
         225             :     use string_utils, only : to_lower, GLC
         226             :     use chem_mods,    only : fix_mass
         227             :     use mo_chem_utls, only : get_inv_ndx
         228             :     use cam_history,  only : outfld
         229             :     use physconst,    only: mwdry   ! molecular weight dry air ~ kg/kmole
         230             :     use physconst,    only: boltz
         231             :
         232             :     implicit none
         233             :
         234             :     type(physics_state), intent(in):: state(begchunk:endchunk)
         235             :     type(physics_buffer_desc), pointer :: pbuf2d(:,:)
         236             :
         237             :     integer :: i,ind,c,ncol
         238             :     real(r8) :: to_vmr(pcols,pver)
         239             :
         240      370944 :     if( num_tracer_cnst < 1 ) return
         241             :
         242      370944 :     call advance_trcdata( fields, file, state, pbuf2d )
         243             :
         244             :     ! copy prescribed tracer fields into state variable with the correct units
         245             :
         246     2225664 :     do i = 1,num_tracer_cnst
         247     1854720 :        ind = get_inv_ndx( tracer_cnst_flds(i) )
         248     9702504 :        do c = begchunk,endchunk
         249     7476840 :           ncol = state(c)%ncol
         250             :
         251    14953680 :           select case ( to_lower(trim(fields(i)%units(:GLC(fields(i)%units)))) )
         252             :           case ("molec/cm3","/cm3","molecules/cm3","cm^-3","cm**-3")
         253           0 :              to_vmr(:ncol,:) = (1.e6_r8*boltz*state(c)%t(:ncol,:))/(state(c)%pmiddry(:ncol,:))
         254             :           case ('kg/kg','mmr')
         255           0 :              to_vmr(:ncol,:) = mwdry/fix_mass(ind)
         256             :           case ('mol/mol','mole/mole','vmr')
         257 11618139960 :              to_vmr(:ncol,:) = 1._r8
         258             :           case default
         259           0 :              write(iulog,*) 'tracer_cnst_adv: units = ',trim(fields(i)%units) ,' are not recognized'
         260    14953680 :              call endrun('tracer_cnst_adv: units are not recognized')
         261             :           end select
         262             :
         263 11618139960 :           fields(i)%data(:ncol,:,c) = to_vmr(:ncol,:) * fields(i)%data(:ncol,:,c)      ! vmr
         264     9331560 :           call outfld( trim(tracer_cnst_flds(i)), fields(i)%data(:ncol,:,c), ncol, state(c)%lchnk )
         265             :
         266             :        enddo
         267             :     enddo
         268             :
         269      370944 :   end subroutine tracer_cnst_adv
         270             :
         271             : !-------------------------------------------------------------------
         272             : !-------------------------------------------------------------------
         273     7445880 :   subroutine get_cnst_data( field_name, data, ncol, lchnk, pbuf  )
         274             :
         275      370944 :     use tracer_data, only : get_fld_data
         276             :     use physics_buffer, only : physics_buffer_desc
         277             :
         278             :     implicit none
         279             :
         280             :     character(len=*), intent(in) :: field_name
         281             :     real(r8), intent(out) :: data(:,:)
         282             :     integer, intent(in) :: lchnk
         283             :     integer, intent(in) :: ncol
         284             :     type(physics_buffer_desc), pointer :: pbuf(:)
         285             :
         286     7445880 :     if( num_tracer_cnst < 1 ) return
         287             :
         288     7445880 :     call get_fld_data( fields, field_name, data, ncol, lchnk, pbuf  )
         289             :
         290     7445880 :   end subroutine get_cnst_data
         291             :
         292             : !-------------------------------------------------------------------
         293             : !-------------------------------------------------------------------
         294     1495368 :   subroutine get_cnst_data_ptr(name, state, q, pbuf)
         295             :
         296     7445880 :     use tracer_data,   only : get_fld_data, get_fld_ndx
         297             :     use physconst,     only : mwdry            ! molecular weight dry air ~ kg/kmole
         298             :     use chem_mods,     only : fix_mass
         299             :     use mo_chem_utls,  only : get_inv_ndx
         300             :     use physics_types, only : physics_state
         301             :     use ppgrid,        only : pcols, pver
         302             :     use physics_buffer, only : physics_buffer_desc
         303             :
         304             :     implicit none
         305             :
         306             :     character(len=*),    intent(in) :: name
         307             :     type(physics_state), intent(in) :: state
         308             :     real(r8), pointer, dimension(:,:) :: q     ! constituent mass mixing ratio
         309             :     type(physics_buffer_desc), pointer :: pbuf(:)
         310             :
         311             :     integer :: lchnk
         312             :     integer :: ncol
         313             :     integer :: inv_id, idx
         314             :     character(len=80) :: error_str
         315             :
         316     1495368 :     lchnk = state%lchnk
         317     1495368 :     ncol  = state%ncol
         318             :
         319             :     ! make sure the requested constituent can be provided
         320     1495368 :     inv_id = get_inv_ndx(name)
         321     1495368 :     if (.not. inv_id > 0) then
         322           0 :        if (masterproc) then
         323           0 :           write(iulog,*) 'get_cnst_data_ptr: '//name//' is not a prescribed tracer constituent'
         324             :        endif
         325             :        return
         326             :     endif
         327             :
         328             :
         329     1495368 :     call get_fld_ndx( fields, name, idx  )
         330     1495368 :     if (idx<1) then
         331           0 :        write(error_str,*) 'get_cnst_data_ptr: ',trim(name),' not found ... idx : ',idx
         332           0 :        if (masterproc) then
         333           0 :           write(iulog,*) error_str
         334             :        end if
         335           0 :        call endrun(error_str)
         336             :     end if
         337     1495368 :     call get_fld_data( fields, name, data_q(:,:,idx,lchnk), ncol, lchnk, pbuf  )
         338             :
         339  2323627992 :     data_q(:ncol,:,idx,lchnk) = data_q(:ncol,:,idx,lchnk)*fix_mass(inv_id)/mwdry   ! vmr->mmr
         340     1495368 :     q => data_q(:,:,idx,lchnk)
         341             :
         342     1495368 :   end subroutine get_cnst_data_ptr
         343             :
         344             : !-------------------------------------------------------------------
         345             :
         346        1536 :   subroutine init_tracer_cnst_restart( piofile )
         347     1495368 :     use pio, only : file_desc_t
         348             :     use tracer_data, only : init_trc_restart
         349             :     implicit none
         350             :     type(file_desc_t),intent(inout) :: pioFile     ! pio File pointer
         351             :
         352        1536 :     call init_trc_restart( 'tracer_cnst', piofile, file )
         353             :
         354        1536 :   end subroutine init_tracer_cnst_restart
         355             : !-------------------------------------------------------------------
         356        1536 :   subroutine write_tracer_cnst_restart( piofile )
         357        1536 :     use tracer_data, only : write_trc_restart
         358             :     use pio, only : file_desc_t
         359             :     implicit none
         360             :
         361             :     type(file_desc_t) :: piofile
         362             :
         363        1536 :     call write_trc_restart( piofile, file )
         364             :
         365        1536 :   end subroutine write_tracer_cnst_restart
         366             :
         367             : !-------------------------------------------------------------------
         368         768 :   subroutine read_tracer_cnst_restart( pioFile )
         369        1536 :     use tracer_data, only : read_trc_restart
         370             :     use pio, only : file_desc_t
         371             :     implicit none
         372             :
         373             :     type(file_desc_t) :: piofile
         374             :
         375         768 :     call read_trc_restart( 'tracer_cnst', piofile, file )
         376             :
         377         768 :   end subroutine read_tracer_cnst_restart
         378             :
         379             : end module tracer_cnst

Generated by: LCOV version 1.14