LCOV - code coverage report
Current view: top level - dynamics/se - test_fvm_mapping.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 12 12 100.0 %
Date: 2025-01-13 21:54:50 Functions: 5 5 100.0 %

          Line data    Source code
       1             : module test_fvm_mapping
       2             :   use shr_kind_mod,           only: r8=>shr_kind_r8
       3             :   use fvm_control_volume_mod, only: fvm_struct
       4             :   use cam_history,            only: outfld
       5             :   use physconst,              only: pi
       6             :   use dimensions_mod,         only: np, nelemd, nlev, npsq, ntrac, use_cslam
       7             :   use element_mod,            only: element_t
       8             :   implicit none
       9             :   private
      10             : 
      11             :   real(r8), parameter, private :: deg2rad = pi/180.0_r8
      12             :   real(r8), parameter, private :: psurf_moist = 100000.0_r8 !moist surface pressure
      13             :   integer,  parameter, private :: cl_idx  = 12
      14             :   integer,  parameter, private :: cl2_idx = 13
      15             :   real(r8), parameter, private :: cly_constant = 4.e-6_r8
      16             :   integer,  parameter, private :: num_fnc = 26
      17             :   integer,  parameter, private :: offset = 15
      18             : 
      19             :   public :: test_mapping_overwrite_tendencies, test_mapping_addfld
      20             :   public :: test_mapping_output_mapped_tendencies, test_mapping_overwrite_dyn_state
      21             :   public :: test_mapping_output_phys_state
      22             : contains
      23             : 
      24      372480 :   subroutine test_mapping_addfld
      25             : #ifdef debug_coupling
      26             :     use cam_history,        only: addfld, add_default, horiz_only, register_vector_field
      27             :     use constituents,       only: cnst_get_ind,cnst_name
      28             :     character(LEN=128) :: name
      29             :     integer :: nq,m_cnst
      30             : 
      31             :     name = 'd2p_u_gll'
      32             :     call addfld(trim(name),   (/ 'lev' /),  'I','m/2','Exact zonal wind on GLL grid',gridname='GLL')
      33             :     !call add_default (trim(name), 1, ' ')
      34             : 
      35             :     name = 'd2p_v_gll'
      36             :     call addfld(trim(name),   (/ 'lev' /),  'I','m/2','Exact meridional wind on GLL grid',gridname='GLL')
      37             :     !call add_default (trim(name), 1, ' ')
      38             : 
      39             :     name = 'd2p_scalar_gll'
      40             :     call addfld(trim(name),   (/ 'lev' /),  'I','','Exact scalar on GLL grid',gridname='GLL')
      41             :     !call add_default (trim(name), 1, ' ')
      42             : 
      43             :     name = 'd2p_u'
      44             :     call addfld(trim(name),   (/ 'lev' /),  'I','m/2','Zonal wind mapped to physics grid')
      45             :     !call add_default (trim(name), 1, ' ')
      46             : 
      47             :     name = 'd2p_u_err'
      48             :     call addfld(trim(name),   (/ 'lev' /),  'I','m/2','Error in zonal wind mapped to physics grid')
      49             :     !call add_default (trim(name), 1, ' ')
      50             : 
      51             :     name = 'd2p_v_err'
      52             :     call addfld(trim(name),   (/ 'lev' /),  'I','m/2','Error in meridional wind mapped to physics grid')
      53             :     !call add_default (trim(name), 1, ' ')
      54             : 
      55             :     name = 'd2p_v'
      56             :     call addfld(trim(name),   (/ 'lev' /),  'I','m/s','Meridional wind mapped to physics grid')
      57             :     !call add_default (trim(name), 1, ' ')
      58             : 
      59             :     name = 'd2p_scalar'
      60             :     call addfld(trim(name),   (/ 'lev' /),  'I','','Scalar mapped to physics grid')
      61             :     call add_default (trim(name), 1, ' ')
      62             : 
      63             :     name = 'd2p_scalar_err'
      64             :     call addfld(trim(name),   (/ 'lev' /),  'I','','Error in scalar mapped to physics grid')
      65             :     call add_default (trim(name), 1, ' ')
      66             : 
      67             :     do nq=ntrac,ntrac
      68             :       m_cnst = nq
      69             :       name = 'f2p_'//trim(cnst_name(m_cnst))//'_fvm'
      70             :       call addfld(trim(name),   (/ 'lev' /),  'I','','Exact water tracer on fvm grid',gridname='FVM')
      71             :       call add_default (trim(name), 1, ' ')
      72             :       name = 'f2p_'//trim(cnst_name(m_cnst))//'_err'
      73             :       call addfld(trim(name),   (/ 'lev' /),  'I','','Error in water tracer on physics grid (mapped from fvm grid)')
      74             :       call add_default (trim(name), 1, ' ')
      75             :       name = 'f2p_'//trim(cnst_name(m_cnst))//''
      76             :       call addfld(trim(name),   (/ 'lev' /),  'I','','Water tracer on physics grid (mapped from fvm grid')
      77             :       call add_default (trim(name), 1, ' ')
      78             :       !
      79             :       ! physgrid to gll (condensate loading tracers)
      80             :       !
      81             :       name = 'p2d_'//trim(cnst_name(m_cnst))//''
      82             :       call addfld(trim(name),   (/ 'lev' /),  'I','','Water tracer on physics grid')
      83             :       !call add_default (trim(name), 1, ' ')
      84             :       name = 'p2d_'//trim(cnst_name(m_cnst))//'_gll'
      85             :       call addfld(trim(name),   (/ 'lev' /),  'I','','Water tracer on GLL grid',gridname='GLL')
      86             :       !call add_default (trim(name), 1, ' ')
      87             :       name = 'p2d_'//trim(cnst_name(m_cnst))//'_err_gll'
      88             :       call addfld(trim(name),   (/ 'lev' /),  'I','','Error in water tracer mapped to GLL grid',gridname='GLL')
      89             :       !call add_default (trim(name), 1, ' ')
      90             :       !
      91             :       ! physgrid to fvm (condensate loading tracers)
      92             :       !
      93             :       name = 'p2f_'//trim(cnst_name(m_cnst))//''
      94             :       call addfld(trim(name),   (/ 'lev' /),  'I','','Water tracer on physics grid')
      95             :       call add_default (trim(name), 1, ' ')
      96             :       name = 'p2f_'//trim(cnst_name(m_cnst))//'_fvm'
      97             :       call addfld(trim(name),   (/ 'lev' /),  'I','','Water tracer on FVM grid',gridname='FVM')
      98             :       call add_default (trim(name), 1, ' ')
      99             :       name = 'p2f_'//trim(cnst_name(m_cnst))//'_err_fvm'
     100             :       call addfld(trim(name),   (/ 'lev' /),  'I','','Error in water tracer mapped to FVM grid',gridname='FVM')
     101             :       call add_default (trim(name), 1, ' ')
     102             :     end do
     103             :     !
     104             :     ! temperature tendency
     105             :     !
     106             :     name = 'p2d_ptend'
     107             :     call addfld(trim(name),   (/ 'lev' /),  'I','','T tendency on physics grid')
     108             :     !call add_default (trim(name), 1, ' ')
     109             :     name = 'p2d_ptend_gll'
     110             :     call addfld(trim(name),   (/ 'lev' /),  'I','','T tendency on GLL grid',gridname='GLL')
     111             :     !call add_default (trim(name), 1, ' ')
     112             :     name = 'p2d_ptend_err_gll'
     113             :     call addfld(trim(name),   (/ 'lev' /),  'I','','Error in T tendency mapped to GLL grid',gridname='GLL')
     114             :     !call add_default (trim(name), 1, ' ')
     115             : 
     116             :     call addfld('p2d_u',   (/ 'lev' /),  'I','m/2','Zonal wind on physics grid')
     117             :     !call add_default ('p2d_u', 1, ' ')
     118             :     call addfld('p2d_v',   (/ 'lev' /),  'I','m/2','Meridional wind on physics grid')
     119             :     !call add_default ('p2d_v', 1, ' ')
     120             :     call addfld('p2d_u_gll',   (/ 'lev' /),  'I','m/2','Zonal wind on physics grid',gridname='GLL')
     121             :     !call add_default ('p2d_u_gll', 1, ' ')
     122             :     call addfld('p2d_v_gll',   (/ 'lev' /),  'I','m/2','Meridional wind on physics grid',gridname='GLL')
     123             :     !call add_default ('p2d_v_gll', 1, ' ')
     124             :     call addfld('p2d_u_gll_err',   (/ 'lev' /),  'I','m/2','Error in zonal wind interpolation to GLL grid',gridname='GLL')
     125             :     !call add_default ('p2d_u_gll_err', 1, ' ')
     126             :     call addfld('p2d_v_gll_err',   (/ 'lev' /),  'I','m/2','Error in meridional wind interpolation to GLL grid',&
     127             :          gridname='GLL')
     128             :     !call add_default ('p2d_v_gll_err', 1, ' ')
     129             : 
     130             : !      name = 'phys2dyn_'//trim(cnst_name(m_cnst))//'_physgrid'
     131             : !      call outfld(trim(name),phys_state%q(:ncols,:,m_cnst),ncols,lchnk)
     132             : #endif
     133        1536 :   end subroutine test_mapping_addfld
     134             : 
     135    23376600 :   subroutine test_mapping_overwrite_tendencies(phys_state,phys_tend,ncols,lchnk,q_prev,fvm)
     136             :     use dimensions_mod,         only: fv_nphys
     137             :     use constituents,           only: cnst_get_ind,pcnst,cnst_name
     138             :     use physics_types,  only: physics_state, physics_tend
     139             :     type(physics_state), intent(inout) :: phys_state
     140             :     type(physics_tend),  intent(inout) :: phys_tend
     141             :     real(r8), dimension(:,:,:), intent(inout) :: q_prev
     142             :     type(fvm_struct), intent(inout):: fvm(:)
     143             :     integer,          intent(in)   :: ncols,lchnk
     144             : #ifdef debug_coupling
     145             :     integer :: icol,k
     146             :     character(LEN=128) :: name
     147             :     integer :: m_cnst, nq, ie
     148             : 
     149             :     q_prev(:,:,ntrac) = 0.0_r8
     150             :     phys_state%pdel(1:ncols,:) = phys_state%pdeldry(1:ncols,:) !make sure there is no conversion from wet to dry
     151             :     do nq=ntrac,ntrac
     152             :       m_cnst = nq
     153             :       do icol=1,ncols
     154             :         do k=1,num_fnc
     155             :           phys_state%q(icol,k,m_cnst)   = test_func(phys_state%lat(icol), phys_state%lon(icol), k, k)
     156             :         end do
     157             :       enddo
     158             :       name = 'p2f_'//trim(cnst_name(m_cnst))//''
     159             :       call outfld(trim(name),phys_state%q(:ncols,:,m_cnst),ncols,lchnk)
     160             :       name = 'p2d_'//trim(cnst_name(m_cnst))//''
     161             :       call outfld(trim(name),phys_state%q(:ncols,:,m_cnst),ncols,lchnk)
     162             :     end do
     163             : 
     164             :     do icol=1,ncols
     165             :       do k=ntrac,ntrac
     166             :         phys_tend%dudt(icol,k) = test_func(phys_state%lat(icol), phys_state%lon(icol), k, k)
     167             :         phys_tend%dvdt(icol,k) = test_func(phys_state%lat(icol), phys_state%lon(icol), k, k)
     168             :         phys_tend%dtdt(icol,k) = test_func(phys_state%lat(icol), phys_state%lon(icol), k, k)
     169             :       end do
     170             :     enddo
     171             :     name = 'p2d_u'
     172             :     call outfld(trim(name),phys_tend%dudt(:ncols,:),ncols,lchnk)
     173             :     name = 'p2d_v'
     174             :     call outfld(trim(name),phys_tend%dvdt(:ncols,:),ncols,lchnk)
     175             :     name = 'p2d_ptend'
     176             :     call outfld(trim(name),phys_tend%dtdt(:ncols,:),ncols,lchnk)
     177             : 
     178             : 
     179             :     do icol=1,ncols
     180             :       do k=1,nlev
     181             : !        phys_tend%dudt(icol,k) = 0.0_r8
     182             : !        phys_tend%dvdt(icol,k) = 0.0_r8
     183             : !        phys_tend%dtdt(icol,k) = 0.0_r8
     184             :       end do
     185             :     enddo
     186             : #endif
     187    23376600 :   end subroutine test_mapping_overwrite_tendencies
     188             : 
     189      369408 :   subroutine test_mapping_output_mapped_tendencies(fvm,elem,nets,nete,tl_f,tl_qdp)
     190    23376600 :     use dimensions_mod,         only: fv_nphys,nlev,nc
     191             :     use constituents,           only: cnst_get_ind,cnst_name
     192             :     integer,          intent(in)   :: nets,nete,tl_f,tl_qdp
     193             :     type(fvm_struct), intent(inout):: fvm(nets:nete)
     194             :     type(element_t),  intent(inout):: elem(nets:nete)             ! pointer to dyn_out element array
     195             : #ifdef debug_coupling
     196             :     integer :: ie,i,j,k
     197             :     character(LEN=128) :: name
     198             :     integer :: nq,m_cnst
     199             :     real(r8) :: diff(nc,nc,nlev,ntrac)
     200             :     diff = 0.0_r8
     201             :     do ie = nets,nete
     202             :       call outfld('p2d_u_gll', RESHAPE(elem(ie)%derived%fm(:,:,1,:),(/npsq,nlev/)), npsq, ie)
     203             :       call outfld('p2d_v_gll', RESHAPE(elem(ie)%derived%fm(:,:,2,:),(/npsq,nlev/)), npsq, ie)
     204             :       call outfld('p2d_ptend_gll', RESHAPE(elem(ie)%derived%ft(:,:,:),(/npsq,nlev/)), npsq, ie)
     205             :       do k=ntrac,ntrac
     206             :         do j=1,np
     207             :           do i=1,np
     208             :             elem(ie)%derived%fm(i,j,1,k)   = elem(ie)%derived%fm(i,j,1,k) -&
     209             :                  test_func(elem(ie)%spherep(i,j)%lat, elem(ie)%spherep(i,j)%lon, k,k)
     210             :             elem(ie)%derived%fm(i,j,2,k)   = elem(ie)%derived%fm(i,j,2,k) - &
     211             :                  test_func(elem(ie)%spherep(i,j)%lat, elem(ie)%spherep(i,j)%lon, k,k)
     212             :             elem(ie)%derived%ft(i,j,k)   = elem(ie)%derived%ft(i,j,k) - &
     213             :                  test_func(elem(ie)%spherep(i,j)%lat, elem(ie)%spherep(i,j)%lon, k,k)
     214             :           end do
     215             :         end do
     216             :       end do
     217             :       call outfld('p2d_u_gll_err'    , RESHAPE(elem(ie)%derived%fm(:,:,1,:),(/npsq,nlev/)), npsq, ie)
     218             :       call outfld('p2d_v_gll_err'    , RESHAPE(elem(ie)%derived%fm(:,:,2,:),(/npsq,nlev/)), npsq, ie)
     219             :       call outfld('p2d_ptend_err_gll', RESHAPE(elem(ie)%derived%ft(:,:,:),(/npsq,nlev/)), npsq, ie)
     220             :       elem(ie)%derived%ft(:,:,:)   = 0.0_r8
     221             :     end do
     222             : 
     223             :     do ie = nets,nete
     224             :       do nq=ntrac,ntrac
     225             :         m_cnst = nq
     226             :         name = 'p2d_'//trim(cnst_name(m_cnst))//'_gll'
     227             :         call outfld(TRIM(name), RESHAPE(elem(ie)%derived%fq(:,:,:,nq),(/npsq,nlev/)), npsq, ie)
     228             :         !        call outfld(trim(name),&
     229             :         !             RESHAPE(fvm(ie)%fc(1:nc,1:nc,:,m_cnst),&
     230             :         !             (/nc*nc,nlev/)),nc*nc,ie)
     231             :         do k=1,num_fnc
     232             :           do j=1,np
     233             :             do i=1,np
     234             :               elem(ie)%derived%fq(i,j,k,nq) = elem(ie)%derived%fq(i,j,k,nq)-&
     235             :                    test_func(elem(ie)%spherep(i,j)%lat, elem(ie)%spherep(i,j)%lon, k, k)
     236             :             end do
     237             :           end do
     238             :         end do
     239             :         name = 'p2d_'//trim(cnst_name(m_cnst))//'_err_gll'
     240             :         call outfld(TRIM(name), RESHAPE(elem(ie)%derived%fq(:,:,:,nq),(/npsq,nlev/)), npsq, ie)
     241             :       end do
     242             :       if (use_cslam) then
     243             :         do nq=ntrac,ntrac
     244             :           m_cnst = nq
     245             :           name = 'p2f_'//trim(cnst_name(m_cnst))//'_fvm'
     246             :           !
     247             :           ! cly
     248             :           !
     249             : !          k=num_tracer+1
     250             : !          fvm(ie)%fc(1:nc,1:nc,k,:) = fvm(ie)%fc(1:nc,1:nc,cl_idx,:)+&
     251             : !                                    2.0_r8*fvm(ie)%fc(1:nc,1:nc,cl2_idx,:)
     252             :           call outfld(trim(name),&
     253             :                RESHAPE(fvm(ie)%fc(1:nc,1:nc,:,m_cnst)/fvm(ie)%dp_fvm(1:nc,1:nc,:),&
     254             :                (/nc*nc,nlev/)),nc*nc,ie)
     255             :           do k=1,num_fnc
     256             :             do j=1,nc
     257             :               do i=1,nc
     258             :                 diff(i,j,k,m_cnst) = fvm(ie)%fc(i,j,k,m_cnst)/fvm(ie)%dp_fvm(i,j,k)-&
     259             :                      test_func(fvm(ie)%center_cart(i,j)%lat,fvm(ie)%center_cart(i,j)%lon, k, k)
     260             :               end do
     261             :             end do
     262             :           end do
     263             :           name = 'p2f_'//trim(cnst_name(m_cnst))//'_err_fvm'
     264             :           call outfld(TRIM(name), RESHAPE(diff(:,:,:,m_cnst),(/nc*nc,nlev/)), nc*nc, ie)
     265             : 
     266             :         end do
     267             :       endif
     268             :     end do
     269             : #endif
     270      369408 :   end subroutine test_mapping_output_mapped_tendencies
     271             : 
     272      370944 :   subroutine test_mapping_overwrite_dyn_state(elem,fvm)
     273             :     use fvm_control_volume_mod, only: fvm_struct
     274             :     use constituents,           only: cnst_name
     275             :     use dimensions_mod,         only: nc,nhc
     276             :     use hybrid_mod,             only: get_loop_ranges, hybrid_t,config_thread_region
     277             :     use control_mod,            only: north, south, east, west, neast, nwest, seast, swest    
     278             :     !    use fvm_mod,                only: fill_halo_fvm_noprealloc
     279             :     use fvm_mod,                only: fill_halo_fvm,ghostBufQnhc_h    
     280             :     use parallel_mod,           only: par
     281             :     type (fvm_struct), intent(inout)    :: fvm(:)
     282             :     type(element_t), intent(inout) :: elem(:)             ! pointer to dyn_out element array
     283             : #ifdef debug_coupling
     284             :     integer            :: i,j,k,ie,nq,m_cnst
     285             :     character(LEN=128) :: name
     286             :     integer            :: nets,nete
     287             :     type(hybrid_t)                                                   :: hybrid
     288             : 
     289             :     hybrid = config_thread_region(par,'serial')
     290             :     call get_loop_ranges(hybrid,ibeg=nets,iend=nete)
     291             :     do ie=nets,nete
     292             :       do nq=ntrac,ntrac
     293             :         m_cnst = nq
     294             :         name = 'f2p_'//trim(cnst_name(m_cnst))//'_fvm'
     295             :         do k=1,num_fnc
     296             :           do j=1,nc
     297             :             do i=1,nc
     298             :               fvm(ie)%c(i,j,k,m_cnst) = test_func(fvm(ie)%center_cart(i,j)%lat,fvm(ie)%center_cart(i,j)%lon, k, k)
     299             :             end do
     300             :           end do
     301             :         end do
     302             :         !
     303             :         ! cly
     304             :         !
     305             : !        k=num_tracer+1
     306             : !        do j=1,nc
     307             : !          do i=1,nc
     308             : !            fvm(ie)%c(i,j,k,m_cnst) = test_func(fvm(ie)%center_cart(i,j)%lat,fvm(ie)%center_cart(i,j)%lon, k,cl_idx)+&
     309             : !                                 2.0_r8*test_func(fvm(ie)%center_cart(i,j)%lat,fvm(ie)%center_cart(i,j)%lon, k,cl2_idx)
     310             : !          end do
     311             : !        end do
     312             :         call outfld(TRIM(name), RESHAPE(fvm(ie)%c(1:nc,1:nc,:,m_cnst),(/nc*nc,nlev/)), nc*nc, ie)
     313             :       end do
     314             :       
     315             :       elem(ie)%state%Qdp(:,:,:,:,:)   = 0.0_r8 !for testing the p2d map
     316             :       do k=1,num_fnc
     317             :         do j=1,np
     318             :           do i=1,np
     319             :             elem(ie)%state%v(i,j,1,k,:)   = test_func(elem(ie)%spherep(i,j)%lat, elem(ie)%spherep(i,j)%lon, k, k )
     320             :             elem(ie)%state%v(i,j,2,k,:)   = test_func(elem(ie)%spherep(i,j)%lat, elem(ie)%spherep(i,j)%lon, k, k)
     321             :           end do
     322             :         end do
     323             :       end do
     324             :       do k=1,num_fnc
     325             :         do j=1,np
     326             :           do i=1,np
     327             :             elem(ie)%derived%omega(i,j,k) = test_func(elem(ie)%spherep(i,j)%lat, elem(ie)%spherep(i,j)%lon, k, k)
     328             :           end do
     329             :         end do
     330             :       end do
     331             :       call outfld('d2p_scalar_gll', RESHAPE(elem(ie)%derived%omega(:,:,:)  ,(/npsq,nlev/)), npsq, ie)
     332             :       call outfld('d2p_u_gll', RESHAPE(elem(ie)%state%v(:,:,1,:,1),(/npsq,nlev/)), npsq, ie)
     333             :       call outfld('d2p_v_gll', RESHAPE(elem(ie)%state%v(:,:,2,:,1),(/npsq,nlev/)), npsq, ie)
     334             :     end do
     335             :     !
     336             :     ! do boundary exchange (this call should be indentical to call in prim_driver)
     337             :     !
     338             :     call fill_halo_fvm(ghostBufQnhc_h,elem,fvm,hybrid,nets,nete,nhc,1,nlev,nlev)
     339             :     do ie=nets,nete
     340             :       if (fvm(ie)%cubeboundary>4) then
     341             :         do k=ntrac,ntrac
     342             :           select case(fvm(ie)%cubeboundary)
     343             :           case (nwest)
     344             :             fvm(ie)%c(0,nc+1,:,k) = fvm(ie)%c(1,nc+1,:,k)
     345             :           case (swest)
     346             :             fvm(ie)%c(0,0,:,k) = fvm(ie)%c(0,1,:,k)
     347             :           case (seast)
     348             :             fvm(ie)%c(nc+1,0,:,k) = fvm(ie)%c(0,nc,:,k)            
     349             :           case (neast)
     350             :             fvm(ie)%c(nc+1,nc+1,:,k) = fvm(ie)%c(nc,nc+1,:,k)                        
     351             :           end select
     352             :         end do
     353             :       end if
     354             :     end do
     355             : #endif
     356      370944 :   end subroutine test_mapping_overwrite_dyn_state
     357             : 
     358      370944 :   subroutine test_mapping_output_phys_state(phys_state,fvm)
     359      370944 :     use physics_types, only: physics_state
     360             :     use ppgrid,        only: begchunk, endchunk, pver, pcols
     361             :     use constituents,  only: cnst_get_ind,cnst_name
     362             :     type(physics_state), intent(inout) :: phys_state(begchunk:endchunk)
     363             :     type(fvm_struct), pointer:: fvm(:)
     364             : #ifdef debug_coupling
     365             :     integer            :: lchnk, ncol,k,icol,m_cnst,nq,ie
     366             :     character(LEN=128) :: name
     367             : 
     368             :     do lchnk = begchunk, endchunk
     369             :       call outfld('d2p_scalar', phys_state(lchnk)%omega(1:pcols,1:pver), pcols, lchnk)
     370             :       call outfld('d2p_u', phys_state(lchnk)%U(1:pcols,1:pver), pcols, lchnk)
     371             :       call outfld('d2p_v', phys_state(lchnk)%V(1:pcols,1:pver), pcols, lchnk)
     372             :       if (use_cslam) then
     373             :         do nq=ntrac,ntrac
     374             :           m_cnst = nq
     375             :           name = 'f2p_'//trim(cnst_name(m_cnst))
     376             :           !
     377             :           ! cly
     378             :           !
     379             :           !phys_state(lchnk)%q(1:pcols,num_tracer+1,m_cnst)=phys_state(lchnk)%q(1:pcols,cl_idx,m_cnst)+&
     380             :           !      2.0_r8*phys_state(lchnk)%q(1:pcols,12,m_cnst)
     381             :           call outfld(TRIM(name), phys_state(lchnk)%q(1:pcols,1:pver,m_cnst), pcols, lchnk)
     382             : !          k=num_tracer+1
     383             : !          do icol=1,phys_state(lchnk)%ncol
     384             : !            phys_state(lchnk)%q(icol,k,m_cnst) = phys_state(lchnk)%q(icol,cl_idx,m_cnst)+&
     385             : !                                          2.0_r8*phys_state(lchnk)%q(icol,cl2_idx,m_cnst)-&
     386             : !                                                 cly_constant
     387             : !          end do
     388             :           do k=1,num_fnc
     389             :             do icol=1,phys_state(lchnk)%ncol
     390             :               phys_state(lchnk)%q(icol,k,m_cnst) = phys_state(lchnk)%q(icol,k,m_cnst)&
     391             :                    -test_func(phys_state(lchnk)%lat(icol), phys_state(lchnk)%lon(icol), k,k)
     392             :             end do
     393             :           enddo
     394             :           name = 'f2p_'//trim(cnst_name(m_cnst))//'_err'
     395             :           call outfld(TRIM(name), phys_state(lchnk)%q(1:pcols,1:pver,m_cnst), pcols, lchnk)
     396             :           phys_state(lchnk)%q(1:pcols,1:pver,m_cnst) = 0.0_r8
     397             :         end do
     398             :       end if
     399             :     end do
     400             : 
     401             : 
     402             :     do lchnk = begchunk, endchunk
     403             :       do k=1,nlev
     404             :         do icol=1,phys_state(lchnk)%ncol
     405             :           phys_state(lchnk)%U(icol,k) = phys_state(lchnk)%U(icol,k)&
     406             :                -test_func(phys_state(lchnk)%lat(icol), phys_state(lchnk)%lon(icol), k, 9)
     407             :           phys_state(lchnk)%V(icol,k) = phys_state(lchnk)%V(icol,k)&
     408             :                -test_func(phys_state(lchnk)%lat(icol), phys_state(lchnk)%lon(icol), k,10)
     409             :         end do
     410             :       enddo
     411             :       name = 'd2p_u_err'
     412             :       call outfld(trim(name),phys_state(lchnk)%U(:pcols,:),pcols,lchnk)
     413             :       name = 'd2p_v_err'
     414             :       call outfld(trim(name),phys_state(lchnk)%V(:pcols,:),pcols,lchnk)
     415             :       do k=1,num_fnc
     416             :         do icol=1,phys_state(lchnk)%ncol
     417             :           phys_state(lchnk)%omega(icol,k) = phys_state(lchnk)%omega(icol,k)&
     418             :                -test_func(phys_state(lchnk)%lat(icol), phys_state(lchnk)%lon(icol), k,k)
     419             :         end do
     420             :       end do
     421             :       name = 'd2p_scalar_err'
     422             :       call outfld(trim(name),phys_state(lchnk)%omega(:pcols,:),pcols,lchnk)
     423             :     end do
     424             : #endif
     425      370944 :   end subroutine test_mapping_output_phys_state
     426             : 
     427             : !  subroutine test_mapping_overwrite_state(phys_tend,nets,nete)
     428             : !#ifdef debug_coupling
     429             : !    phys_tend(lchnk)%dtdt(icol,ilyr)   = 0!test_func(phys_state(lchnk)%lat(icol),phys_state(lchnk)%lon(icol),ilyr,9)
     430             : !    phys_tend(lchnk)%dudt(icol,ilyr)   = 0!test_func(phys_state(lchnk)%lat(icol),phys_state(lchnk)%lon(icol),ilyr,12)
     431             : !    phys_tend(lchnk)%dvdt(icol,ilyr)   = 0!test_func(phys_state(lchnk)%lat(icol),phys_state(lchnk)%lon(icol),ilyr,13)
     432             : !    q_prev(icol, ilyr, 2:pcnst, lchnk) = 0.0D0
     433             : !    do m=2,pcnst
     434             : !      phys_state(lchnk)%Q(icol,ilyr,m)=0!test_func(phys_state(lchnk)%lat(icol),phys_state(lchnk)%lon(icol),ilyr,m)
     435             : !    end do
     436             : !#endif
     437             : !  end subroutine test_mapping_overwrite_state
     438             : 
     439             : #ifdef debug_coupling
     440             :   function test_func(lat_in, lon_in, k, funcnum) result(fout)
     441             :     use hycoef,        only: hyai, hybi, hyam, hybm, ps0
     442             :     use shr_sys_mod,   only: shr_sys_flush
     443             :     use cam_abortutils, only: endrun
     444             :     real(r8), intent(in) :: lon_in
     445             :     real(r8), intent(in) :: lat_in
     446             :     integer,  intent(in) :: k
     447             :     integer,  intent(in) :: funcnum
     448             :     real(r8)             :: fout
     449             :     real(r8)             :: lon1,lat1,R0,Rg1,Rg2,lon2,lat2,cl,cl2
     450             :     real(r8)             :: eta_c
     451             : 
     452             :     real(r8)             :: radius      = 10.0_r8 ! radius of the perturbation
     453             :     real(r8)             :: perturb_lon = 20.0_r8 ! longitudinal position, 20E
     454             :     real(r8)             :: perturb_lat = 40.0_r8 ! latitudinal position, 40N
     455             :     real(r8)             :: cos_tmp, sin_tmp, eta
     456             :     real(r8)             :: u_wind, v_wind, lat, lon, u_tmp, v_tmp
     457             :     real(r8)             :: rotation_angle
     458             :     real(r8)             :: det,r,k1,k2
     459             :     real(r8), parameter :: pi = 3.1415926535897932384626433832795028841971693993751058209749445923078164_r8
     460             :     real(r8), parameter :: half_pi = pi*0.5_r8
     461             :     real(r8), parameter :: degrees_to_radians = pi/180.0_r8
     462             :     real(r8), parameter :: k1_lat_center =   20.d0*degrees_to_radians
     463             :     real(r8), parameter :: k1_lon_center =  300.d0*degrees_to_radians
     464             : 
     465             :     lon = lon_in
     466             :     lat = lat_in
     467             : 
     468             : 
     469             :     select case(MOD(funcnum,8)+1)
     470             :     case(1)
     471             :       !
     472             :       !   Non-smooth scalar field (slotted cylinder)
     473             :       !
     474             :       R0 = 0.5_r8
     475             :       lon1 = 5.0_r8 * PI / 6.0_r8
     476             :       lat1 = 0.0_r8
     477             :       Rg1 = acos(sin(lat1)*sin(lat)+cos(lat1)*cos(lat)*cos(lon-lon1))
     478             :       lon2 = 7.0_r8 * PI / 6.0_r8
     479             :       lat2 = 0.0_r8
     480             :       Rg2 = acos(sin(lat2)*sin(lat)+cos(lat2)*cos(lat)*cos(lon-lon2))
     481             : 
     482             :       if ((Rg1 <= R0) .AND. (abs(lon-lon1) >= R0/6)) then
     483             :         fout = 2.0_r8
     484             :       elseif ((Rg2 <= R0) .AND. (abs(lon-lon2) >= R0/6)) then
     485             :         fout = 2.0_r8
     486             :       elseif ((Rg1 <= R0) .AND. (abs(lon-lon1) < R0/6) &
     487             :            .AND. (lat-lat1 < -5.0_r8*R0/12.0_r8)) then
     488             :         fout = 2.0_r8
     489             :       elseif ((Rg2 <= R0) .AND. (abs(lon-lon2) < R0/6) &
     490             :            .AND. (lat-lat2 > 5.0_r8*R0/12.0_r8)) then
     491             :         fout = 2.0_r8
     492             :       else
     493             :         fout = 1.0_r8
     494             :       endif
     495             :     case(2)
     496             :       !
     497             :       ! Smooth Gaussian "ball"
     498             :       !
     499             :       R0    = 10.0_r8           ! radius of the perturbation
     500             :       lon1  = 20.0_r8*deg2rad   ! longitudinal position, 20E
     501             :       lat1  = 40.0_r8 *deg2rad  ! latitudinal position, 40N
     502             :       eta_c = 0.6_r8
     503             :       sin_tmp = SIN(lat1)*SIN(lat)
     504             :       cos_tmp = COS(lat1)*COS(lat)
     505             :       Rg1 = ACOS( sin_tmp + cos_tmp*COS(lon-lon1) )    ! great circle distance
     506             :       eta =  (hyam(k)*ps0 + hybm(k)*psurf_moist)/psurf_moist
     507             :       fout = EXP(- ((Rg1*R0)**2 + ((eta-eta_c)/0.1_r8)**2))
     508             :       if (ABS(fout) < 1.0E-8_r8) then
     509             :         fout = 0.0_r8
     510             :       end IF
     511             :     case(3)
     512             :       !
     513             :       !
     514             :       !
     515             :       fout = 0.5_r8 * ( tanh( 3.0_r8*abs(lat)-pi ) + 1.0_r8)
     516             :     case(4)
     517             :       fout = 2.0_r8+cos(5.0_r8+40*lon)!1.0e-8_r8
     518             :       fout = -0.5_r8-0.5_r8*(cos(16*lon)*(sin(2_r8*lat)**16))            
     519             :     case(5)
     520             :       !
     521             :       ! approximately Y^2_2 spherical harmonic
     522             :       !
     523             :       fout = sin(lon)*cos(40*lat)!1.0e-8_r8
     524             :       fout = 0.5_r8*(cos(16*lon)*(sin(2_r8*lat)**16))      
     525             :     case(6)
     526             :       !
     527             :       ! approximately Y32_16 spherical harmonic
     528             :       !
     529             :       fout = 0.5_r8 + 0.5_r8*(cos(16*lon)*(sin(2_r8*lat)**16))
     530             :     case(7)
     531             :       fout = 2.0_r8 + lat
     532             :     case(8)
     533             :       fout = 2.0_r8 + cos(lon)
     534             :     case(9)
     535             :       rotation_angle = 45.0_r8*pi/180.0_r8
     536             :       CALL regrot(lon_in,lat_in,lon,lat,0.0_r8,-0.5_r8*pi+rotation_angle,1)
     537             :       call Rossby_Haurwitz (lon, lat,u_wind, v_wind)
     538             :       CALL turnwi(u_wind,v_wind,u_tmp,v_tmp,lon_in,lat_in,lon,lat,0.0_r8,-0.5_r8*pi+rotation_angle,-1)
     539             :       fout = u_tmp
     540             :     case(10)
     541             :       rotation_angle = 45.0_r8*pi/180.0_r8
     542             :       CALL regrot(lon_in,lat_in,lon,lat,0.0_r8,-0.5_r8*pi+rotation_angle,1)
     543             :       call Rossby_Haurwitz (lon, lat,u_wind, v_wind)
     544             :       CALL turnwi(u_wind,v_wind,u_tmp,v_tmp,lon_in,lat_in,lon,lat,0.0_r8,-0.5_r8*pi+rotation_angle,-1)
     545             :       fout = v_tmp
     546             :     case(11)
     547             :       fout = 1.0E-8_r8
     548             :     case(12)
     549             :       !
     550             :       ! Terminator chemistry initial condition
     551             :       !
     552             :       k1 = 1.0_r8*max(0.d0,sin(lat)*sin(k1_lat_center) + cos(lat)*cos(k1_lat_center)*cos(lon-k1_lon_center))
     553             :       k2 = 1._r8
     554             : 
     555             :       r = k1 / (4._r8*k2)
     556             :       det = sqrt(r*r + 2._r8*cly_constant*r)
     557             : 
     558             :       fout  = (det-r)
     559             : !      fout = cly_constant/2._r8 - (det-r)/2._r8
     560             :     case(13)
     561             :       !
     562             :       ! Terminator chemistry initial condition
     563             :       !
     564             :       k1 = 1.0_r8*max(0.d0,sin(lat)*sin(k1_lat_center) + cos(lat)*cos(k1_lat_center)*cos(lon-k1_lon_center))
     565             :       k2 = 1._r8
     566             : 
     567             :       r = k1 / (4._r8*k2)
     568             :       det = sqrt(r*r + 2._r8*cly_constant*r)
     569             : 
     570             : !      fout  = (det-r)
     571             :       fout = cly_constant/2._r8 - (det-r)/2._r8
     572             :     case default
     573             : !      call endrun("Illegal funcnum_arg in test_func")
     574             :       fout = 1.0_r8
     575             :     end select
     576             :   end function test_func
     577             : 
     578             :   function test_wind(lat, lon, iwind) result(fout)
     579             :    use cam_abortutils, only: endrun
     580             :     real(r8), intent(in) :: lon
     581             :     real(r8), intent(in) :: lat
     582             :     integer,  intent(in) :: iwind
     583             : 
     584             :     real(r8)             :: fout
     585             : 
     586             : 
     587             :     fout = 0
     588             :   end function test_wind
     589             : 
     590             : 
     591             :   SUBROUTINE regrot(pxreg,pyreg,pxrot,pyrot,pxcen,pycen,kcall)
     592             :     use physconst, only: pi
     593             : !
     594             : !----------------------------------------------------------------------
     595             : !
     596             : !*    conversion between regular and rotated spherical coordinates.
     597             : !*
     598             : !*    pxreg     longitudes of the regular coordinates
     599             : !*    pyreg     latitudes of the regular coordinates
     600             : !*    pxrot     longitudes of the rotated coordinates
     601             : !*    pyrot     latitudes of the rotated coordinates
     602             : !*              all coordinates given in degrees n (negative for s)
     603             : !*              and degrees e (negative values for w)
     604             : !*    pxcen     regular longitude of the south pole of the rotated grid
     605             : !*    pycen     regular latitude of the south pole of the rotated grid
     606             : !*
     607             : !*    kcall=-1: find regular as functions of rotated coordinates.
     608             : !*    kcall= 1: find rotated as functions of regular coordinates.
     609             : !
     610             : !-----------------------------------------------------------------------
     611             : !
     612             :       integer kxdim,kydim,kx,ky,kcall
     613             :       real(r8) :: pxreg,pyreg,&
     614             :                   pxrot,pyrot,&
     615             :                   pxcen,pycen
     616             : !
     617             : !-----------------------------------------------------------------------
     618             : !
     619             :       real(r8) zsycen,zcycen,zxmxc,zsxmxc,zcxmxc,zsyreg,zcyreg, &
     620             :                zsyrot,zcyrot,zcxrot,zsxrot,zpi,zpih
     621             :       integer jy,jx
     622             : 
     623             :       zpih = pi*0.5_r8
     624             : !
     625             :       !----------------------------------------------------------------------
     626             : !
     627             :       zsycen = SIN((pycen+zpih))
     628             :       zcycen = COS((pycen+zpih))
     629             : !
     630             :       IF (kcall.eq.1) then
     631             : !
     632             :          zxmxc  = pxreg - pxcen
     633             :          zsxmxc = SIN(zxmxc)
     634             :          zcxmxc = COS(zxmxc)
     635             :          zsyreg = SIN(pyreg)
     636             :          zcyreg = COS(pyreg)
     637             :          zsyrot = zcycen*zsyreg - zsycen*zcyreg*zcxmxc
     638             :          zsyrot = max(zsyrot,-1.0_r8)
     639             :          zsyrot = min(zsyrot,+1.0_r8)
     640             :          !
     641             :          pyrot = ASIN(zsyrot)
     642             :          !
     643             :          zcyrot = COS(pyrot)
     644             :          zcxrot = (zcycen*zcyreg*zcxmxc +zsycen*zsyreg)/zcyrot
     645             :          zcxrot = max(zcxrot,-1.0_r8)
     646             :          zcxrot = min(zcxrot,+1.0_r8)
     647             :          zsxrot = zcyreg*zsxmxc/zcyrot
     648             :          !
     649             :          pxrot = ACOS(zcxrot)
     650             :          !
     651             :          IF (zsxrot < 0.0_r8) then
     652             :            pxrot = -pxrot
     653             :          end IF
     654             :                !
     655             :       ELSEIF (kcall.eq.-1) then
     656             :          !
     657             :          zsxrot = SIN(pxrot)
     658             :          zcxrot = COS(pxrot)
     659             :          zsyrot = SIN(pyrot)
     660             :          zcyrot = COS(pyrot)
     661             :          zsyreg = zcycen*zsyrot + zsycen*zcyrot*zcxrot
     662             :          zsyreg = max(zsyreg,-1.0_r8)
     663             :          zsyreg = min(zsyreg,+1.0_r8)
     664             :          !
     665             :          pyreg = ASIN(zsyreg)
     666             :          !
     667             :          zcyreg = COS(pyreg)
     668             :          zcxmxc = (zcycen*zcyrot*zcxrot -&
     669             :               zsycen*zsyrot)/zcyreg
     670             :          zcxmxc = max(zcxmxc,-1.0_r8)
     671             :          zcxmxc = min(zcxmxc,+1.0_r8)
     672             :          zsxmxc = zcyrot*zsxrot/zcyreg
     673             :          zxmxc  = ACOS(zcxmxc)
     674             :          IF (zsxmxc < 0.0_r8) then
     675             :            zxmxc = -zxmxc
     676             :          end IF
     677             :          !
     678             :          pxreg = zxmxc + pxcen
     679             :          !
     680             :       ELSE
     681             :          WRITE(6,'(1x,''invalid kcall in regrot'')')
     682             :          STOP
     683             :       ENDIF
     684             :     END SUBROUTINE regrot
     685             : 
     686             :   SUBROUTINE turnwi(puarg,pvarg,pures,pvres,pxreg,pyreg,pxrot,pyrot,pxcen,pycen,kcall)
     687             :     use physconst, only: pi
     688             :     !
     689             :     !-----------------------------------------------------------------------
     690             :     !
     691             :     !*    turn horizontal velocity components between regular and
     692             :     !*    rotated spherical coordinates.
     693             :     !
     694             :     !*    puarg : input u components
     695             :     !*    pvarg : input v components
     696             :     !*    pures : output u components
     697             :     !*    pvres : output v components
     698             :     !*    pa    : transformation coefficients
     699             :     !*    pb    :    -"-
     700             :     !*    pc    :    -"-
     701             :     !*    pd    :    -"-
     702             :     !*    pxreg : regular longitudes
     703             :     !*    pyreg : regular latitudes
     704             :     !*    pxrot : rotated longitudes
     705             :     !*    pyrot : rotated latitudes
     706             :     !*    kxdim              : dimension in the x (longitude) direction
     707             :     !*    kydim              : dimension in the y (latitude) direction
     708             :     !*    kx                 : number of gridpoints in the x direction
     709             :     !*    ky                 : number of gridpoints in the y direction
     710             :     !*    pxcen              : regular longitude of the south pole of the
     711             :     !*                         transformed grid
     712             :     !*    pycen              : regular latitude of the south pole of the
     713             :     !*                         transformed grid
     714             :     !*
     715             :     !*    kcall < 0          : find wind components in regular coordinates
     716             :     !*                         from wind components in rotated coordinates
     717             :     !*    kcall > 0          : find wind components in rotated coordinates
     718             :     !*                         from wind components in regular coordinates
     719             :     !*    note that all coordinates are given in degrees n and degrees e.
     720             :     !*       (negative values for s and w)
     721             :     !
     722             :     !-----------------------------------------------------------------------
     723             : 
     724             :     integer kxdim,kydim,kx,ky,kcall
     725             :     real(r8) puarg,pvarg,    &
     726             :          pures,pvres,    &
     727             :          pa,   pb,       &
     728             :          pc,   pd,       &
     729             :          pxreg,pyreg,    &
     730             :          pxrot,pyrot
     731             :       real(r8) pxcen,pycen
     732             :       !
     733             :       !-----------------------------------------------------------------------
     734             :       !
     735             :       integer jy,jx
     736             :       real(r8) zpih,zsyc,zcyc,zsxreg,zcxreg,zsyreg,zcyreg,zxmxc,&
     737             :            zsxmxc,zcxmxc,zsxrot,zcxrot,zsyrot,zcyrot
     738             :       !
     739             :       !-----------------------------------------------------------------------
     740             :       !
     741             :       IF (kcall.eq.1) then
     742             :         zpih = pi*0.5_r8
     743             :         zsyc = SIN(pycen+zpih)
     744             :         zcyc = COS(pycen+zpih)
     745             :         !
     746             :         zsxreg = SIN(pxreg)
     747             :         zcxreg = COS(pxreg)
     748             :         zsyreg = SIN(pyreg)
     749             :         zcyreg = COS(pyreg)
     750             :         !
     751             :         zxmxc  = pxreg - pxcen
     752             :         zsxmxc = SIN(zxmxc)
     753             :         zcxmxc = COS(zxmxc)
     754             :         !
     755             :         zsxrot = SIN(pxrot)
     756             :         zcxrot = COS(pxrot)
     757             :         zsyrot = SIN(pyrot)
     758             :         zcyrot = COS(pyrot)
     759             :         !
     760             :         pa = zcyc*zsxmxc*zsxrot + zcxmxc*zcxrot
     761             :         pb = zcyc*zcxmxc*zsyreg*zsxrot - zsyc*zcyreg*zsxrot - &
     762             :              zsxmxc*zsyreg*zcxrot
     763             :         pc = zsyc*zsxmxc/zcyrot
     764             :         pd = (zsyc*zcxmxc*zsyreg + zcyc*zcyreg)/zcyrot
     765             :         !
     766             :         pures = pa*puarg + pb*pvarg
     767             :         pvres = pc*puarg + pd*pvarg
     768             :       ELSEIF (kcall.eq.-1) then
     769             :         zpih = pi*0.5_r8
     770             :         zsyc = SIN(pycen+zpih)
     771             :         zcyc = COS(pycen+zpih)
     772             :         !
     773             :         zsxreg = SIN(pxreg)
     774             :         zcxreg = COS(pxreg)
     775             :         zsyreg = SIN(pyreg)
     776             :         zcyreg = COS(pyreg)
     777             :         !
     778             :         zxmxc  = pxreg - pxcen
     779             :         zsxmxc = SIN(zxmxc)
     780             :         zcxmxc = COS(zxmxc)
     781             :         !
     782             :         zsxrot = SIN(pxrot)
     783             :         zcxrot = COS(pxrot)
     784             :         zsyrot = SIN(pyrot)
     785             :         zcyrot = COS(pyrot)
     786             :         !
     787             :         pa = zcxmxc*zcxrot + zcyc*zsxmxc*zsxrot
     788             :         pb = zcyc*zsxmxc*zcxrot*zsyrot + zsyc*zsxmxc*zcyrot -&
     789             :              zcxmxc*zsxrot*zsyrot
     790             :         pc =-zsyc*zsxrot/zcyreg
     791             :         pd = (zcyc*zcyrot - zsyc*zcxrot*zsyrot)/zcyreg
     792             :         !
     793             :         pures = pa*puarg + pb*pvarg
     794             :         pvres = pc*puarg + pd*pvarg
     795             :       ELSE
     796             :         write(6,'(1x,''invalid kcall in turnwi'')')
     797             :         STOP
     798             :       ENDIF
     799             :     END SUBROUTINE turnwi
     800             : 
     801             :   SUBROUTINE Rossby_Haurwitz (lon, lat,u_wind, v_wind)
     802             :     use physconst, only: rearth
     803             : !-----------------------------------------------------------------------
     804             : !     input parameters
     805             : !-----------------------------------------------------------------------
     806             :       real(r8), intent(in)  :: lon,                                     & ! longitude in radians
     807             :                                lat                                        ! latitude in radians
     808             :                                                                           ! both coefficients 'a' and 'b' are needed at the full model level
     809             : !-----------------------------------------------------------------------
     810             : !     input parameters
     811             : !-----------------------------------------------------------------------
     812             :       real(r8), intent(out) :: u_wind,                                  & ! zonal wind in m/s
     813             :                                v_wind                                     ! meridional wind in m/s
     814             : 
     815             : !-----------------------------------------------------------------------
     816             : !     test case parameters
     817             : !-----------------------------------------------------------------------
     818             :       real(r8),parameter :: u0      = 50._r8,                          &   ! reference wind
     819             :                             n       = 4._r8                                ! wavenumber
     820             : 
     821             : !-----------------------------------------------------------------------
     822             : !     local
     823             : !-----------------------------------------------------------------------
     824             :       real(r8) :: tmp1, tmp2, tmp3, KK, MM
     825             :       real(r8) :: sin_lat, cos_lat, sin_slat, cos_slat
     826             : 
     827             : !-----------------------------------------------------------------------
     828             : !     initialize the wind components
     829             : !-----------------------------------------------------------------------
     830             :       MM      = u0/(n*rearth)   ! parameter M
     831             :       KK      = u0/(n*rearth)   ! parameter K
     832             : 
     833             : 
     834             :       cos_lat = cos(lat)
     835             :       sin_lat = sin(lat)
     836             :       tmp1 = rearth * MM * cos_lat
     837             :       tmp2 = rearth * KK * cos_lat**(n-1._r8)*(n*sin_lat**2 - cos_lat**2)
     838             :       tmp3 = -rearth * KK * n * cos_lat**(n-1._r8) * sin_lat
     839             :       u_wind = tmp1 + tmp2 * cos(n*lon)
     840             :       v_wind = tmp3 * sin(n*lon)
     841             :   end subroutine Rossby_Haurwitz
     842             : 
     843             : #endif
     844             : end module test_fvm_mapping

Generated by: LCOV version 1.14