LCOV - code coverage report
Current view: top level - physics/waccmx - majorsp_diffusion.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 242 280 86.4 %
Date: 2025-03-14 01:26:08 Functions: 4 4 100.0 %

          Line data    Source code
       1             : module majorsp_diffusion
       2             : 
       3             : !--------------------------------------------------------------------------
       4             : ! This module computes the diffusion of major species (O2 and O) mass mixing
       5             : ! ratio. This routine computes both the molecular and eddy diffusivity. This
       6             : ! is adapted from the major species diffusion calculation of TIME-GCM.
       7             : !
       8             : ! Calling sequence:
       9             : !   initialization:
      10             : !      init
      11             : !         call mspd_init
      12             : !
      13             : !   interfacing:
      14             : !      tphysac
      15             : !         (after vertical_diffusion_tend)
      16             : !         call mspd_intr
      17             : !            call mspdiff
      18             : !
      19             : !---------------------------Code history--------------------------------
      20             : ! Adapted from TIME-GCM (comp.F): H.-L. Liu, Nov 2003
      21             : !--------------------------------------------------------------------------
      22             : 
      23             : 
      24             :   use shr_kind_mod, only: r8 => shr_kind_r8
      25             :   use ppgrid,       only: pcols, pver, pverp
      26             :   use constituents, only: pcnst, cnst_name, cnst_get_ind, cnst_mw
      27             :   use cam_history,  only: outfld
      28             : 
      29             :   implicit none
      30             : 
      31             :   private          ! Make default type private to the module
      32             :   save
      33             : !-----------------------
      34             : ! Public interfaces
      35             : !-----------------------
      36             :   public mspd_init   ! Initialization
      37             :   public mspd_intr   ! Full routine
      38             : !-----------------------
      39             : ! Private data
      40             : !-----------------------
      41             : 
      42             :   real(r8) :: rmass_o2, rmass_o1, rmass_n2               ! molecular weight kg/kmol
      43             :   real(r8) :: rmassinv_o2, rmassinv_o1, rmassinv_n2      ! 1/rmass_o2...
      44             :   real(r8) :: phi(2,3)                                   ! mutual diffusion constants of
      45             :                                                          ! major constituents
      46             :   real(r8) :: delta(2,2)                                 ! unit matrix
      47             : 
      48             :   real(r8), parameter :: t00=273._r8                     ! reference temperature
      49             :   real(r8), parameter :: ptref=5.e-5_r8                  ! thermosphere reference pressure (Pa)
      50             :   real(r8), parameter :: tau=1.86e3_r8                   ! diffusive time constant (sec).
      51             :   real(r8), parameter :: protonmass=1.6726e-27_r8        ! Proton mass (kg)
      52             :   real(r8), parameter :: mmrMin=1.e-20_r8                ! lower limit of o2 and o mixing ratio
      53             :   real(r8), parameter :: N2mmrMin=1.e-6_r8               ! lower limit of o2, o, and h mixing ratios
      54             : 
      55             :   integer :: indx_O2                                     ! cnst index for o2
      56             :   integer :: indx_O                                      ! cnst index for o
      57             :   integer :: indx_H                                      ! cnst index for h
      58             :   integer, parameter :: io2=1, io1=2                     ! local indices to o2 , o respectively
      59             :   logical :: fixed_ubc(2)                                ! flag for fixed upper boundary condition
      60             : 
      61             :   real(r8) :: o2mmr_ubc(pcols)                           ! MMR of O2 at top boundary (specified)
      62             :   real(r8) :: ommr_ubc(pcols)                            ! MMR of O at top boundary
      63             : 
      64             :   character(len=8), private :: mjdiffnam(2)              ! names of v-diff tendencies
      65             : 
      66             : contains
      67             : 
      68             : !===============================================================================
      69         768 :   subroutine mspd_init()
      70             : 
      71             :     !-------------------------------------------------------------------------------
      72             :     ! Define constants and coeficient matrices, phi and delta, in the initialization.
      73             :     !-------------------------------------------------------------------------------
      74             :     use constituents, only: cnst_mw, cnst_fixed_ubc
      75             :     use cam_history,  only: addfld, add_default
      76             :     use phys_control, only: phys_getopts
      77             : 
      78             :     !------------------------------Arguments--------------------------------
      79             : 
      80             :     !---------------------------Local storage-------------------------------
      81             :     logical :: history_waccmx
      82             : 
      83         768 :     call phys_getopts(history_waccmx_out=history_waccmx)
      84             : 
      85             :     !-----------------------------------------------------------
      86             :     ! Get required molecular weights
      87             :     !-----------------------------------------------------------
      88         768 :     call cnst_get_ind('O2', indx_O2, abort=.true.)
      89         768 :     call cnst_get_ind('O',  indx_O, abort=.true.)
      90         768 :     call cnst_get_ind('H',  indx_H, abort=.true.)
      91             : 
      92         768 :     rmass_o2 = cnst_mw(indx_O2)
      93         768 :     rmass_o1 = cnst_mw(indx_O)
      94         768 :     rmass_n2 = 28._r8
      95             : 
      96         768 :     rmassinv_o2 = 1._r8/rmass_o2
      97         768 :     rmassinv_o1 = 1._r8/rmass_o1
      98         768 :     rmassinv_n2 = 1._r8/rmass_n2
      99             : 
     100             :     !--------------------------------------------------------------------
     101             :     ! Get fixed upper boundary flags and set vertical range for diffusion
     102             :     !--------------------------------------------------------------------
     103         768 :     fixed_ubc(io2) = cnst_fixed_ubc(indx_O2)
     104         768 :     fixed_ubc(io1) = cnst_fixed_ubc(indx_O)
     105             : 
     106             :     !------------------------------------------------
     107             :     ! Set diffusion constants and setup matrix
     108             :     !------------------------------------------------
     109        2304 :     phi(:,1)=(/0._r8  ,0.673_r8/)
     110        2304 :     phi(:,2)=(/1.35_r8,0._r8   /)
     111        2304 :     phi(:,3)=(/1.11_r8,0.769_r8/)
     112        2304 :     delta(:,1)=(/1._r8,0._r8/)
     113        2304 :     delta(:,2)=(/0._r8,1._r8/)
     114             : 
     115             :    ! Set names of major diffusion tendencies and declare them as history variables
     116         768 :     mjdiffnam(1) = 'MD'//cnst_name(indx_O2)
     117        1536 :     call addfld (mjdiffnam(1),(/ 'lev' /), 'A','kg/kg/s','Major diffusion of '//cnst_name(indx_O2))
     118         768 :     mjdiffnam(2) = 'MD'//cnst_name(indx_O)
     119        1536 :     call addfld (mjdiffnam(2),(/ 'lev' /), 'A','kg/kg/s','Major diffusion of '//cnst_name(indx_O))
     120             : 
     121        1536 :     call addfld ('MBARV' , (/ 'lev' /),'I','g/mole','Variable Mean Mass')
     122             : 
     123         768 :     if (history_waccmx) then
     124         768 :        call add_default (mjdiffnam(1), 1, ' ')
     125         768 :        call add_default (mjdiffnam(2), 1, ' ')
     126         768 :        call add_default ('MBARV', 1, ' ')
     127             :     end if
     128             : 
     129         768 :   end subroutine mspd_init
     130             : 
     131             : !===============================================================================
     132       21888 :   subroutine mspd_intr(ztodt    ,state    ,ptend)
     133             : 
     134             : !-------------------------------------------------------------------------------
     135             : ! interface routine. output tendency.
     136             : !-------------------------------------------------------------------------------
     137         768 :     use physics_types,   only: physics_state, physics_ptend
     138             :     use upper_bc,        only: ubc_get_vals
     139             :     use air_composition, only: rairv, mbarv
     140             : 
     141             : !------------------------------Arguments--------------------------------
     142             :     real(r8), intent(in) :: ztodt                  ! 2 delta-t
     143             :     type(physics_state), intent(in)     :: state   ! Physics state variables
     144             :     type(physics_ptend), intent(inout)  :: ptend   ! indivdual parameterization tendencies
     145             : !---------------------------Local storage-------------------------------
     146             :     real(r8) :: rztodt                             ! 1/ztodt
     147             :     real(r8) :: tendo2o(pcols,pver,2)              ! temporary array for o2 and o tendency
     148             :     real(r8) :: ubc_mmr(pcols,pcnst)               ! upper bndy mixing ratios (kg/kg)
     149             :     real(r8) :: ubc_t(pcols)                       ! upper bndy temperature (K)
     150             :     integer :: lchnk                               ! chunk identifier
     151             :     integer :: ncol                                ! number of atmospheric columns
     152             :     integer :: i, k                                ! indexing integers
     153             : 
     154             :     !--------------------------------------------------------------------------------------------
     155             :     ! local constants
     156             :     !--------------------------------------------------------------------------------------------
     157       21888 :     rztodt = 1._r8/ztodt
     158       21888 :     lchnk = state%lchnk
     159       21888 :     ncol  = state%ncol
     160             : 
     161             :     !----------------------------------------------------------------------------------------------
     162             :     ! Store the o2 and o tendencies calculated from vertical_diffusion (due to eddy diffusion only)
     163             :     !----------------------------------------------------------------------------------------------
     164    37012608 :     tendo2o(:ncol,:,io2) = ptend%q(:ncol,:,indx_O2)
     165    37012608 :     tendo2o(:ncol,:,io1) = ptend%q(:ncol,:,indx_O)
     166             : 
     167             :     !----------------------------------------------------------------------
     168             :     ! Operate on copies of the input states, convert to tendencies at end.
     169             :     !----------------------------------------------------------------------
     170    37012608 :     ptend%q(:ncol,:,indx_O2) = state%q(:ncol,:,indx_O2)
     171    37012608 :     ptend%q(:ncol,:,indx_O) = state%q(:ncol,:,indx_O)
     172             : 
     173       21888 :     if (fixed_ubc(io2) .or. fixed_ubc(io1)) then
     174             :        !-------------------------------------------
     175             :        ! set upper boundary values of O2 and O MMR.
     176             :        !-------------------------------------------
     177           0 :        call ubc_get_vals( lchnk, ncol, state%pint, state%zi, ubc_t, ubc_mmr )
     178           0 :        o2mmr_ubc(:ncol) = ubc_mmr(:ncol,indx_O2)
     179           0 :        ommr_ubc(:ncol) = ubc_mmr(:ncol,indx_O)
     180             :     endif
     181             : 
     182             :     ! Since this is a combined tendency, retain the old name for output
     183             :     ! and debugging purposes.
     184       21888 :     ptend%name  = trim(ptend%name)//"+mspd"
     185       21888 :     ptend%lq(indx_O2) = .TRUE.
     186       21888 :     ptend%lq(indx_O) = .TRUE.
     187             :     !---------------------------------------------
     188             :     ! Call the major species diffusion subroutine.
     189             :     !---------------------------------------------
     190             :     call mspdiff (lchnk      ,ncol       ,                                     &
     191             :                   state%t    ,ptend%q    ,state%pmid ,state%pint ,             &
     192       21888 :                   state%pdel ,ztodt      ,rairv(:,:,lchnk),  mbarv(:,:,lchnk))
     193             : 
     194             :     !---------------------------------------------
     195             :     ! Update O2 and O tendencies and output
     196             :     !---------------------------------------------
     197     2867328 :     do k=1,pver
     198    37012608 :        do i=1,ncol
     199    34145280 :           ptend%q(i,k,indx_O2) = (ptend%q(i,k,indx_O2)-state%q(i,k,indx_O2))*rztodt  &
     200    68290560 :                                  +tendo2o(i,k,io2)
     201    34145280 :           ptend%q(i,k,indx_O) = (ptend%q(i,k,indx_O)-state%q(i,k,indx_O))*rztodt     &
     202    71136000 :                                  +tendo2o(i,k,io1)
     203             :        enddo
     204             :     enddo
     205             : 
     206       21888 :     call outfld(mjdiffnam(1),ptend%q(1,1,indx_O2),pcols,lchnk)
     207       21888 :     call outfld(mjdiffnam(2),ptend%q(1,1,indx_O),pcols,lchnk)
     208             : 
     209       21888 :   end subroutine mspd_intr
     210             : 
     211             : 
     212             : !===============================================================================
     213       21888 :   subroutine mspdiff (lchnk      ,ncol       ,                                     &
     214             :                       t          ,q          ,pmid       ,pint       ,             &
     215             :                       pdel       ,ztodt      ,rairv      ,mbarv)
     216             : !-----------------------------------------------------------------------
     217             : ! Driver routine to compute major species diffusion (O2 and O).
     218             : 
     219             : ! Turbulent diffusivities and boundary layer nonlocal transport terms are
     220             : ! obtained from the turbulence module.
     221             : !---------------------------Arguments------------------------------------
     222       21888 :     use ref_pres,     only: lev0 => nbot_molec
     223             :     use physconst,    only: gravit
     224             : 
     225             :     integer, intent(in) :: lchnk                   ! chunk identifier
     226             :     integer, intent(in) :: ncol                    ! number of atmospheric columns
     227             :     real(r8), intent(in) :: t(pcols,pver)          ! temperature input
     228             :     real(r8), intent(in) :: pmid(pcols,pver)       ! midpoint pressures
     229             :     real(r8), intent(in) :: pint(pcols,pverp)      ! interface pressures
     230             :     real(r8), intent(in) :: pdel(pcols,pver)       ! thickness between interfaces
     231             :     real(r8), intent(in) :: ztodt                  ! 2 delta-t
     232             :     real(r8), intent(in) :: rairv(pcols,pver)                  ! composition dependent gas "constant"
     233             :     real(r8), intent(in) :: mbarv(pcols,pver)                  ! composition dependent mean mass
     234             : 
     235             :     real(r8), intent(inout) :: q(pcols,pver,pcnst) ! constituents
     236             : 
     237             : !---------------------------Local storage-------------------------------
     238             :     real(r8) :: o2(pcols,pver), o1(pcols,pver)     ! o2, o1 mixing ratio (kg/kg moist air)
     239             :     real(r8) :: h_atom(pcols,pver)                 ! H mixing ratio
     240             :     real(r8) :: rztodt                             ! 1/ztodt
     241             :     real(r8) :: dz(pcols,pver)                     ! log-pressure interval between interfaces
     242             :     real(r8) :: rdz(pcols,pver)                    ! 1./dz, defined on midpoints
     243             :     real(r8) :: dzmid(pcols,pverp)                 ! log-pressure interval between midpoints
     244             :     real(r8) :: rdzmid(pcols,pverp)                ! 1./dzmid, defined on interfaces
     245             :     real(r8) :: ak(pcols,2,2,2)                    ! coefficient matrix "Alfa"
     246             :     real(r8) :: ep(pcols,2,2)                      ! coefficient matrix
     247             :     real(r8) :: difk(pcols,pverp)                  ! eddy diffusion normalized by scale height (1/sec)
     248             :     real(r8) :: expzm(pcols,pver)                  ! exp(-z)=pmid/ptref
     249             :     real(r8) :: expzi(pcols,pverp)                 ! exp(-z)=pint/ptref
     250             :     real(r8) :: wks1(pcols)
     251             :     real(r8) :: wks3(pcols),wks4(pcols)            ! temporary working arrays
     252             :     real(r8) :: psclht(pcols,pverp)                ! pressure scale height
     253             :     real(r8) :: p_ubc(pcols)                       ! extrapolated pressure at upper boundary level, pmid(1)^2=pmid(2)*p_ubc
     254             :     real(r8) :: rair_ubc(pcols)                    ! extrapolated rair at upper boundary level
     255             :     real(r8) :: mbar_ubc(pcols)                    ! extrapolated mbar at upper boundary level
     256             :     real(r8) :: flb(pcols,2)                       ! lower boundary condition for o2 and o, now
     257             :                                                    ! calculated locally.
     258             :     real(r8) :: fub(pcols,2)                       ! upper boundary condition for o2 and o, now
     259             :                                                    ! calculated locally.
     260             :     real(r8) :: fk(pcols,2)                        ! temporary working array for rhs
     261             :     real(r8) :: pk(pcols,2,2)                      ! temp array for coefficients on lower diagonal
     262             :     real(r8) :: rk(pcols,2,2)                      ! temp array for coefficients on upper diagonal
     263             :     real(r8) :: qk(pcols,2,2)                      ! temp array for coefficients on diagonal
     264             :     real(r8) :: apk(2,2,pcols,pver)                ! coefficients on lower diagonal
     265             :     real(r8) :: ark(2,2,pcols,pver)                ! coefficients on upper diagonal
     266             :     real(r8) :: aqk(2,2,pcols,pver)                ! coefficients on diagonal
     267             :     real(r8) :: rfk(2,pcols,pver)                  ! rhs of the array equation
     268             :     real(r8) :: betawk(2,2,pcols,pver)             ! working arrays for blktri solver.
     269             :     real(r8) :: gammawk(2,2,pcols,pver)            ! working arrays for blktri solver.
     270             :     real(r8) :: ywk(2,pcols,pver)                  ! working arrays for blktri solver.
     271             :     real(r8) :: xwk(2,pcols,pver)                  ! working arrays for blktri solver.
     272             :     integer  :: nlevs                              ! number of levels
     273             :     real(r8) :: t_ubc(pcols)                       ! Temperature at top boundary
     274             :     integer  :: i, k, km, kp, m, ktmp, isp, kk, kr
     275             : 
     276             :     !---------------------------------------------------
     277             :     ! Set vertical grid and get time step for diffusion
     278             :     !---------------------------------------------------
     279       21888 :     nlevs = lev0
     280       21888 :     rztodt = 1._r8/ztodt
     281             : 
     282             :     !------------------------------------------------------
     283             :     ! Get species to diffuse and set upper/lower boundaries
     284             :     !------------------------------------------------------
     285    37012608 :     o2(:ncol,:) = q(:ncol,:,indx_O2)
     286    37012608 :     o1(:ncol,:) = q(:ncol,:,indx_O)
     287    37012608 :     h_atom(:ncol,:) = q(:ncol,:,indx_H)
     288             : 
     289      284544 :     flb(:ncol,1) = o2(:ncol,lev0+1)      ! fixed lower boundary condition
     290      284544 :     flb(:ncol,2) = o1(:ncol,lev0+1)
     291       21888 :     if(fixed_ubc(io2).or.fixed_ubc(io1)) then
     292           0 :        fub(:ncol,1) = o2mmr_ubc(:ncol)      ! fixed upper boundary condition
     293           0 :        fub(:ncol,2) = ommr_ubc(:ncol)
     294             :     endif
     295             : 
     296             :     !------------------------------------------------------------------
     297             :     ! Get log-pressure intervals between midpoints and interface points
     298             :     !------------------------------------------------------------------
     299    37012608 :     dz(:ncol,:) = pdel(:ncol,:)/pmid(:ncol,:)
     300    37012608 :     rdz(:ncol,:) = 1._r8/dz(:ncol,:)
     301     2845440 :     do k=2,pver
     302    36728064 :        do i=1,ncol
     303    33882624 :           dzmid(i,k) = (pmid(i,k)-pmid(i,k-1))/pint(i,k)
     304    36706176 :           rdzmid(i,k) = 1._r8/dzmid(i,k)
     305             :        enddo
     306             :     enddo
     307      284544 :     do i=1,ncol
     308      262656 :        p_ubc(i) = pmid(i,1)*pmid(i,1)/pmid(i,2)
     309      262656 :        dzmid(i,1) = (pmid(i,1)-p_ubc(i))/pint(i,1)
     310      284544 :        rdzmid(i,1) = 1._r8/dzmid(i,1)
     311             :     enddo
     312      284544 :     do i=1,ncol
     313      262656 :        dzmid(i,pverp) = dzmid(i,pver)
     314      284544 :        rdzmid(i,pverp) = 1._r8/dzmid(i,pverp)
     315             :     enddo
     316             : 
     317             :     !------------------------------------------------------------------
     318             :     ! Get log-pressure intervals between midpoints and interface points
     319             :     !------------------------------------------------------------------
     320    37297152 :     expzi(:ncol,:) = pint(:ncol,:)/ptref
     321    37012608 :     expzm(:ncol,:) = pmid(:ncol,:)/ptref
     322             : 
     323             :     !------------------------------------------------------------------
     324             :     ! Get pressure scale height
     325             :     !------------------------------------------------------------------
     326     2845440 :     do k=2,pver
     327    36728064 :        do i=1,ncol
     328    36706176 :           psclht(i,k) = .5_r8*(rairv(i,k)*t(i,k)+rairv(i,k-1)*t(i,k-1))/gravit
     329             :        enddo
     330             :     enddo
     331      284544 :     do i=1,ncol
     332      262656 :        rair_ubc(i) = 1.5_r8*rairv(i,1)-.5_r8*rairv(i,2)
     333      262656 :        t_ubc(i) = 1.5_r8*t(i,1)-.5_r8*t(i,2)
     334      262656 :        psclht(i,1) = .5_r8*(rairv(i,1)*t(i,1)+rair_ubc(i)*t_ubc(i))/gravit
     335      284544 :        psclht(i,pverp) = psclht(i,pver)
     336             :     enddo
     337             : 
     338             :     !------------------------------------------------------------------
     339             :     ! Initialize scale height normalized eddy diffusion
     340             :     !------------------------------------------------------------------
     341     2889216 :     do k=1,pverp
     342    37297152 :        do i=1,ncol
     343    37275264 :           difk(i,k) = 0._r8          ! eddy diffusion already calculated in vertical_diffusion
     344             :        enddo
     345             :     enddo
     346             : 
     347       21888 :     call outfld ('MBARV', mbarv(:,:), pcols, lchnk)
     348             : 
     349             :     !------------------------------------------------------------------
     350             :     ! Set up mean mass working array
     351             :     !------------------------------------------------------------------
     352             :     ! ep, ak at the interface level immediately below midpoint level nbot_molec
     353             : 
     354             :     ! WKS4 = .5*(DMBAR/DZ)/MBAR
     355      284544 :     do i=1,ncol
     356      787968 :        wks4(i) = (mbarv(i,lev0)-mbarv(i,lev0+1))/                               &
     357     1072512 :                  (dzmid(i,lev0+1)*(mbarv(i,lev0+1)+mbarv(i,lev0)))
     358             :     enddo
     359             : 
     360             :     !-----------------------------------
     361             :     ! Calculate coefficient matrices
     362             :     !-----------------------------------
     363      284544 :     km = 1
     364      284544 :     kp = 2
     365      284544 :     do i=1, ncol
     366      787968 :        ep(i,io2,kp) = 1._r8-(2._r8/(mbarv(i,lev0+1)+mbarv(i,lev0)))*                  &
     367     1050624 :                    (rmass_o2+(mbarv(i,lev0)-mbarv(i,lev0+1))*rdzmid(i,lev0+1))
     368             :        ep(i,io1,kp) = 1._r8-(2._r8/(mbarv(i,lev0+1)+mbarv(i,lev0)))*                  &
     369      284544 :                    (rmass_o1+(mbarv(i,lev0)-mbarv(i,lev0+1))*rdzmid(i,lev0+1))
     370             :     enddo
     371             : 
     372             : 
     373       65664 :     do m=1,2
     374      590976 :       do i=1,ncol
     375     1050624 :          ak(i,io2,m,kp) =                                           &
     376             :             -delta(io2,m)*(phi(io1,3)+(phi(io1,io2)-phi(io1,3))*    &
     377     1050624 :             .5_r8*(o2(i,lev0+1)+o2(i,lev0)))-(1._r8-delta(io2,m))*        &
     378     2626560 :             (phi(io2,m)-phi(io2,3))*.5_r8*(o2(i,lev0+1)+o2(i,lev0))
     379             :          ak(i,io1,m,kp) =                                           &
     380             :             -delta(io1,m)*(phi(io2,3)+(phi(io2,io1)-phi(io2,3))*    &
     381             :             .5_r8*(o1(i,lev0+1)+o1(i,lev0)))-(1._r8-delta(io1,m))*        &
     382      569088 :             (phi(io1,m)-phi(io1,3))*.5_r8*(o1(i,lev0+1)+o1(i,lev0))
     383             :       enddo
     384             :     enddo
     385             : !
     386             : ! WKS1=MBAR/M3*(T00/(T0+T))*0.25/(TAU*DET(ak)) ak at the interface level
     387             : ! immediately below midpoint level nbot_molec.
     388      284544 :     do i=1,ncol
     389      787968 :       wks1(i) = 0.5_r8*(mbarv(i,lev0+1)+mbarv(i,lev0))*rmassinv_n2*       &
     390             :         (2._r8*t00/(t(i,lev0+1)+t(i,lev0)))**0.25_r8/                      &
     391     1072512 :         (tau*(ak(i,1,1,kp)*ak(i,2,2,kp)-ak(i,1,2,kp)*ak(i,2,1,kp)))
     392             :     enddo
     393             : !
     394             : ! Complete calculation of ak at the interface level immediately below midpoint
     395             : ! level nbot_molec.
     396       65664 :     do m=1,2
     397      590976 :       do i=1,ncol
     398      525312 :         ak(i,io2,m,kp) = ak(i,io2,m,kp)*wks1(i)
     399      569088 :         ak(i,io1,m,kp) = ak(i,io1,m,kp)*wks1(i)
     400             :       enddo
     401             :     enddo
     402             : 
     403       21888 :     km = 1
     404       21888 :     kp = 2
     405     1838592 :     do k=lev0,2,-1
     406    23617152 :        ktmp = km
     407    23617152 :        km = kp
     408    23617152 :        kp = ktmp
     409    23617152 :        do i=1,ncol
     410    87201792 :           ep(i,io2,kp) = 1._r8-(2._r8/(mbarv(i,k)+mbarv(i,k-1)))*(rmass_o2+      &
     411   109002240 :                          (mbarv(i,k-1)-mbarv(i,k))*rdzmid(i,k))
     412             :           ep(i,io1,kp) = 1._r8-(2._r8/(mbarv(i,k)+mbarv(i,k-1)))*(rmass_o1+      &
     413    23617152 :                          (mbarv(i,k-1)-mbarv(i,k))*rdzmid(i,k))
     414             :        enddo
     415             : 
     416     5450112 :        do m=1,2
     417    49051008 :           do i=1,ncol
     418   130802688 :              ak(i,io2,m,kp) =                                               &
     419             :                   -delta(io2,m)*(phi(io1,3)+(phi(io1,io2)-phi(io1,3))*      &
     420    87201792 :                   .5_r8*(o2(i,k)+o2(i,k-1)))-                                  &
     421    43600896 :                   (1._r8-delta(io2,m))*(phi(io2,m)-phi(io2,3))*                &
     422   218004480 :                   .5_r8*(o2(i,k)+o2(i,k-1))
     423             : 
     424             :              ak(i,io1,m,kp) =                                               &
     425             :                   -delta(io1,m)*(phi(io2,3)+(phi(io2,io1)-phi(io2,3))*      &
     426             :                   .5_r8*(o1(i,k)+o1(i,k-1)))-                                  &
     427             :                   (1._r8-delta(io1,m))*(phi(io1,m)-phi(io1,3))*                &
     428    47234304 :                   .5_r8*(o1(i,k)+o1(i,k-1))
     429             : 
     430             :           enddo
     431             :        enddo
     432             : 
     433             :     !---------------------------------------------
     434             :     ! Calculate coefficients for diagonals and rhs
     435             :     !---------------------------------------------
     436             : !
     437             : ! WKS1=MBAR/M3*(T00/(T0+T))**0.25/(TAU*DET(ALFA))
     438    23617152 :        do i=1,ncol
     439    65401344 :           wks1(i) = 0.5_r8*(mbarv(i,k)+mbarv(i,k-1))*rmassinv_n2*              &
     440             :                (2._r8*t00/(t(i,k)+t(i,k-1)))**0.25_r8/                          &
     441    87201792 :                (tau*(ak(i,1,1,kp)*ak(i,2,2,kp)-ak(i,1,2,kp)*ak(i,2,1,kp)))
     442    21800448 :           wks3(i) = wks4(i)
     443             :           wks4(i) = (mbarv(i,k-1)-mbarv(i,k))/                              &
     444    23617152 :                (dzmid(i,k)*(mbarv(i,k)+mbarv(i,k-1)))
     445             :        enddo
     446             : 
     447             : !
     448             : ! FINISH CALCULATING AK(K+1/2) AND GENERATE PK, QK, RK
     449     5450112 :        do m=1,2
     450    12716928 :           do isp=io2,io1
     451    98102016 :              do i=1,ncol
     452    87201792 :                 ak(i,isp,m,kp) = ak(i,isp,m,kp)*wks1(i)
     453             : 
     454   174403584 :                 pk(i,isp,m) = (ak(i,isp,m,km)*(rdzmid(i,k+1)+ep(i,m,km)/2._r8)-   &
     455             :                      expzi(i,k+1)*difk(i,k+1)*(rdzmid(i,k+1)-                  &
     456   261605376 :                      wks3(i))*delta(isp,m))*rdz(i,k)
     457             : 
     458    87201792 :                 rk(i,isp,m) = (ak(i,isp,m,kp)*(rdzmid(i,k)-ep(i,m,kp)/2._r8)-     &
     459             :                      expzi(i,k)*difk(i,k)*(rdzmid(i,k)+                        &
     460    87201792 :                      wks4(i))*delta(isp,m))*rdz(i,k)
     461             : 
     462             :                 qk(i,isp,m) = -(ak(i,isp,m,km)*(rdzmid(i,k+1)-ep(i,m,km)/2._r8)+  &
     463             :                      ak(i,isp,m,kp)*(rdzmid(i,k)+ep(i,m,kp)/2._r8))*rdz(i,k)+     &
     464             :                      ((expzi(i,k)*difk(i,k)*(rdzmid(i,k)-wks4(i))+             &
     465             :                      expzi(i,k+1)*difk(i,k+1)*(rdzmid(i,k+1)+wks3(i)))*        &
     466    94468608 :                      rdz(i,k)+expzm(i,k)*rztodt)*delta(isp,m)
     467             : 
     468             :              enddo
     469             :           enddo
     470             :        enddo
     471             : 
     472    23617152 :        do i=1,ncol
     473    21800448 :           fk(i,io2) = expzm(i,k)*o2(i,k)*rztodt
     474    23617152 :           fk(i,io1) = expzm(i,k)*o1(i,k)*rztodt
     475             :        enddo
     476             : 
     477             :        !----------------------------
     478             :        ! Lower boundary
     479             :        !----------------------------
     480     1816704 :        if (k==lev0) then
     481       65664 :           do m=1,2
     482      590976 :             do i=1,ncol
     483      525312 :               fk(i,io2) = fk(i,io2)-pk(i,io2,m)*flb(i,m)
     484      525312 :               fk(i,io1) = fk(i,io1)-pk(i,io1,m)*flb(i,m)
     485     1619712 :               pk(i,:,m) = 0._r8
     486             :             enddo
     487             :           enddo
     488             :        endif
     489             : 
     490     1816704 :        kr = lev0-k+1
     491             : 
     492    23617152 :        do i=1,ncol
     493    67218048 :           do m=1,2
     494   152603136 :              do kk=1,2
     495    87201792 :                 apk(kk,m,i,kr) = pk(i,kk,m)
     496    87201792 :                 aqk(kk,m,i,kr) = qk(i,kk,m)
     497   130802688 :                 ark(kk,m,i,kr) = rk(i,kk,m)
     498             :              enddo
     499             :           enddo
     500             :        enddo
     501             : 
     502    23639040 :        do i=1,ncol
     503    21800448 :           rfk(io2,i,kr) = fk(i,io2)
     504    23617152 :           rfk(io1,i,kr) = fk(i,io1)
     505             :        enddo
     506             : 
     507             :     enddo
     508             : 
     509             :     !----------------------------
     510             :     ! Upper boundary
     511             :     !----------------------------
     512       21888 :     k=1
     513       21888 :     ktmp = km
     514       21888 :     km = kp
     515       21888 :     kp = ktmp
     516       21888 :     if(fixed_ubc(io2).or.fixed_ubc(io1)) then
     517           0 :        do i=1,ncol
     518           0 :           mbar_ubc(i) = 1._r8/(o2mmr_ubc(i)*rmassinv_o2+ommr_ubc(i)*rmassinv_o1+ &
     519           0 :                (1._r8-o2mmr_ubc(i)-ommr_ubc(i))*rmassinv_n2)
     520           0 :           ep(i,io2,kp) = 1._r8-(2._r8/(mbarv(i,k)+mbar_ubc(i)))*(rmass_o2+      &
     521           0 :                (mbar_ubc(i)-mbarv(i,k))*rdzmid(i,k))
     522             :           ep(i,io1,kp) = 1._r8-(2._r8/(mbarv(i,k)+mbar_ubc(i)))*(rmass_o1+      &
     523           0 :                (mbar_ubc(i)-mbarv(i,k))*rdzmid(i,k))
     524             :        enddo
     525             : 
     526           0 :        do m=1,2
     527           0 :           do i=1,ncol
     528           0 :              ak(i,io2,m,kp) =                                               &
     529             :                   -delta(io2,m)*(phi(io1,3)+(phi(io1,io2)-phi(io1,3))*      &
     530             :                   .5_r8*(o2(i,k)+o2mmr_ubc(i)))-                                  &
     531           0 :                   (1._r8-delta(io2,m))*(phi(io2,m)-phi(io2,3))*                &
     532           0 :                   .5_r8*(o2(i,k)+o2mmr_ubc(i))
     533             : 
     534             :              ak(i,io1,m,kp) =                                               &
     535             :                   -delta(io1,m)*(phi(io2,3)+(phi(io2,io1)-phi(io2,3))*      &
     536             :                   .5_r8*(o1(i,k)+ommr_ubc(i)))-                                  &
     537             :                   (1._r8-delta(io1,m))*(phi(io1,m)-phi(io1,3))*                &
     538           0 :                   .5_r8*(o1(i,k)+ommr_ubc(i))
     539             : 
     540             :           enddo
     541             :        enddo
     542             : 
     543             : !
     544             : ! WKS1=MBAR/M3*(T00/(T0+T))**0.25/(TAU*DET(ALFA))
     545           0 :        do i=1,ncol
     546           0 :           wks1(i) = 0.5_r8*(mbarv(i,k)+mbar_ubc(i))*rmassinv_n2*              &
     547             :                (2._r8*t00/(t(i,k)+t_ubc(i)))**0.25_r8/                          &
     548           0 :                (tau*(ak(i,1,1,kp)*ak(i,2,2,kp)-ak(i,1,2,kp)*ak(i,2,1,kp)))
     549           0 :           wks3(i) = wks4(i)
     550             :           wks4(i) = (mbar_ubc(i)-mbarv(i,k))/                              &
     551           0 :                (dzmid(i,k)*(mbarv(i,k)+mbar_ubc(i)))
     552             :        enddo
     553             : 
     554             : !
     555             : ! FINISH CALCULATING AK(K+1/2) AND GENERATE PK, QK, RK
     556           0 :        do m=1,2
     557           0 :           do isp=io2,io1
     558           0 :              do i=1,ncol
     559           0 :                 ak(i,isp,m,kp) = ak(i,isp,m,kp)*wks1(i)
     560             : 
     561           0 :                 pk(i,isp,m) = (ak(i,isp,m,km)*(rdzmid(i,k+1)+ep(i,m,km)/2._r8)-   &
     562             :                      expzi(i,k+1)*difk(i,k+1)*(rdzmid(i,k+1)-                  &
     563           0 :                      wks3(i))*delta(isp,m))*rdz(i,k)
     564             : 
     565             :                 rk(i,isp,m) = (ak(i,isp,m,kp)*(rdzmid(i,k)-ep(i,m,kp)/2._r8)-     &
     566             :                      expzi(i,k)*difk(i,k)*(rdzmid(i,k)+                        &
     567           0 :                      wks4(i))*delta(isp,m))*rdz(i,k)
     568             : 
     569             :                 qk(i,isp,m) = -(ak(i,isp,m,km)*(rdzmid(i,k+1)-ep(i,m,km)/2._r8)+  &
     570             :                      ak(i,isp,m,kp)*(rdzmid(i,k)+ep(i,m,kp)/2._r8))*rdz(i,k)+     &
     571             :                      ((expzi(i,k)*difk(i,k)*(rdzmid(i,k)-wks4(i))+             &
     572             :                      expzi(i,k+1)*difk(i,k+1)*(rdzmid(i,k+1)+wks3(i)))*        &
     573           0 :                      rdz(i,k)+expzm(i,k)*rztodt)*delta(isp,m)
     574             : 
     575             :              enddo
     576             :           enddo
     577             :        enddo
     578             : 
     579           0 :        do i=1,ncol
     580           0 :           fk(i,io2) = expzm(i,k)*o2(i,k)*rztodt
     581           0 :           fk(i,io1) = expzm(i,k)*o1(i,k)*rztodt
     582             :        enddo
     583           0 :        do m=1,2
     584           0 :           do i=1,ncol
     585           0 :              fk(i,io2) = fk(i,io2)-rk(i,io2,m)*fub(i,m)
     586           0 :              fk(i,io1) = fk(i,io1)-rk(i,io1,m)*fub(i,m)
     587           0 :              rk(i,:,m) = 0._r8
     588             :           enddo
     589             :        enddo
     590             : 
     591             :     else
     592             : 
     593      284544 :        do i=1,ncol
     594      284544 :           wks3(i) = wks4(i)
     595             :        enddo
     596       65664 :        do m=1,2
     597      153216 :           do isp=io2,io1
     598     1181952 :              do i=1,ncol
     599     4202496 :                 pk(i,isp,m) = (ak(i,isp,m,km)*(rdzmid(i,k+1)+ep(i,m,km)/2._r8)-   &
     600             :                      expzi(i,k+1)*difk(i,k+1)*(rdzmid(i,k+1)-                  &
     601     4202496 :                      wks3(i))*delta(isp,m))*rdz(i,k)
     602             : 
     603             :                 qk(i,isp,m) = -(ak(i,isp,m,km)*(rdzmid(i,k+1)-ep(i,m,km)/2._r8))  &
     604             :                      *rdz(i,k)+     &
     605             :                      (expzi(i,k+1)*difk(i,k+1)*(rdzmid(i,k+1)+wks3(i))*        &
     606     1138176 :                      rdz(i,k)+expzm(i,k)*rztodt)*delta(isp,m)
     607             : 
     608             :              enddo
     609             :           enddo
     610             :        enddo
     611             : 
     612      284544 :        do i=1,ncol
     613      262656 :           fk(i,io2) = expzm(i,k)*o2(i,k)*rztodt
     614      284544 :           fk(i,io1) = expzm(i,k)*o1(i,k)*rztodt
     615             :        enddo
     616             : 
     617             :     endif
     618             : 
     619       21888 :     kr = lev0-k+1
     620             : 
     621      284544 :     do i=1,ncol
     622      809856 :        do m=1,2
     623     1838592 :           do kk=1,2
     624     1050624 :              apk(kk,m,i,kr) = pk(i,kk,m)
     625     1050624 :              aqk(kk,m,i,kr) = qk(i,kk,m)
     626     1575936 :              ark(kk,m,i,kr) = rk(i,kk,m)
     627             :           enddo
     628             :        enddo
     629             :     enddo
     630             : 
     631      284544 :     do i=1,ncol
     632      262656 :        rfk(io2,i,kr) = fk(i,io2)
     633      284544 :        rfk(io1,i,kr) = fk(i,io1)
     634             :     enddo
     635             : 
     636             :     !------------------------------------
     637             :     ! Call solver to get diffused species
     638             :     !------------------------------------
     639             :     call blktri(apk,aqk,ark,rfk,pcols,1,ncol,pver,1,nlevs,    &
     640       21888 :                 betawk, gammawk, ywk, xwk)
     641             : 
     642     1860480 :     do k=lev0,1,-1
     643     1838592 :        kr = lev0-k+1
     644    23923584 :        do i=1,ncol
     645    22063104 :           o2(i,k) = xwk(1,i,kr)
     646    23901696 :           o1(i,k) = xwk(2,i,kr)
     647             :        enddo
     648             :     enddo
     649             : 
     650             :     !---------------------------------------------------------------
     651             :     ! Ensure non-negative O2 and O and check for N2 greater than one
     652             :     !---------------------------------------------------------------
     653      284544 :     do i=1,ncol
     654    22347648 :        do k=1,lev0
     655             : 
     656    22063104 :           if (o2(i,k) < mmrMin) o2(i,k) = mmrMin
     657    22063104 :           if (o1(i,k) < mmrMin) o1(i,k) = mmrMin
     658             : 
     659    22325760 :           if(1._r8-mmrMin-o2(i,k)-o1(i,k)-h_atom(i,k) < 0._r8) then
     660        1728 :              o2(i,k) = o2(i,k)*((1._r8-N2mmrMin-h_atom(i,k))/(o2(i,k)+o1(i,k)))
     661        1728 :              o1(i,k) = o1(i,k)*((1._r8-N2mmrMin-h_atom(i,k))/(o2(i,k)+o1(i,k)))
     662             :           endif
     663             :        enddo
     664             :     enddo
     665             : 
     666    37012608 :     q(:ncol,:,indx_O2) = o2(:ncol,:)
     667    37012608 :     q(:ncol,:,indx_O)  = o1(:ncol,:)
     668             : 
     669       21888 :   end subroutine mspdiff
     670             : 
     671             : 
     672             : !===============================================================================
     673       21888 :       SUBROUTINE BLKTRI(A,B,C,F,IF,I1,I2,KF,K1,K2,BETA,GAMMA,Y,X)
     674             :       implicit none
     675             : !     ****
     676             : !     ****     This procedure solves (I2-I1+1) tridiagonal block matrix
     677             : !     ****     systems in which all blocks are 2 x 2 matrices.
     678             : !     ****
     679             : !     ****     Each system may be written:
     680             : !     ****
     681             : !     ****      A(K) * X(K-1) + B(K) * X(K) + Z(K) * X(K+1) = F(K)
     682             : !     ****
     683             : !     ****      where:
     684             : !     ****
     685             : !     ****       K = K1,K2,1
     686             : !     ****
     687             : !     ****       A(K), B(K), C(K) are given (2 x 2) matrices.
     688             : !     ****
     689             : !     ****       The F(k) are given two componente vectors.
     690             : !     ****
     691             : !     ****       The system is to be solved for the two component
     692             : !     ****       vectors, X(K).
     693             : !     ****
     694             : !     ****       A(K1) = C(K2) = 0.
     695             : !     ****
     696             : !     ****      BETA(K), GAMMA(K), (K = K1,K2,1), are work space for
     697             : !     ****      (2 x 2) matrices.
     698             : !     ****
     699             : !     ****      Y(K), (K = K1,K2,1), is work space for two component
     700             : !     ****      vectors.
     701             : !     ****
     702             : !     ****     Algorithm: (See Isaacson and Keller p55)
     703             : !     ****
     704             : !     ****      Forward sweep from K = K1 to K = K2:
     705             : !     ****
     706             : !     ****       BETA(K1) = B(K1)**(-1)
     707             : !     ****
     708             : !     ****       Y(K1) = BETA(K1)*F(K1)
     709             : !     ****
     710             : !     ****       GAMMA(K) = BETA(K)*C(K),        K = K1,(K2-1),1
     711             : !     ****
     712             : !     ****       BETA(K) = (B(K) - A(K)*GAMMA(K-1))**(-1),
     713             : !     ****                                       K = K1+1,K2,1
     714             : !     ****
     715             : !     ****       Y(K) = BETA(K)*(F(K) - A(K)*Y(K-1)),
     716             : !     ****                                       K = K1+1,K2,1
     717             : !     ****
     718             : !     ****      Backward sweep, K = K2,K1,-1
     719             : !     ****
     720             : !     ****       X(K2) = Y(K2)
     721             : !     ****
     722             : !     ****       X(K) = Y(K) - GAMMA(K)*X(K+1),  K = K2-1,K1,-1
     723             : !     ****
     724             : !     ****     Dimension statements:
     725             : !     ****
     726             : !     ****      Block matrices are dimensioned thus:
     727             : !     ****
     728             : !     ****       MATRIX(2,2,IF,KF)
     729             : !     ****
     730             : !     ****      Two component vectors are similarly treated:
     731             : !     ****
     732             : !     ****       VECTOR(2,IF,KF)
     733             : !     ****
     734             : !     ****     Our block matrix scheme spans the range, (K = K1,K2,1),
     735             : !     ****     where (1 .LE. K1 .LT. K2 .LE. KF)
     736             : !     ****
     737             : !     ****     Similarly, we are solving (I1-I2+1) systems
     738             : !     ****     simultaneously as the index, I, spans the range,
     739             : !     ****     (I = I1,I2,1), where (1 .LE. I1 .LT. I2 .LE. IF)
     740             : !     ****
     741             : !     ****
     742             : !     ****     Dimension statements:
     743             : !     SUBROUTINE BLKTRI(A,B,C,F,IF,I1,I2,KF,K1,K2,BETA,GAMMA,Y,X)
     744             : !     ****
     745             : ! Args:
     746             :       integer,intent(in)   :: if,i1,i2,kf,k1,k2
     747             :       real(r8),intent(in)  :: a(2,2,if,kf), b(2,2,if,kf), c(2,2,if,kf),      &
     748             :                               f(2,if,kf)
     749             :       real(r8),intent(out) :: beta(2,2,if,kf), gamma(2,2,if,kf),             &
     750             :                               y(2,if,kf), x(2,if,kf)
     751             : !
     752             : !     DIMENSION A(2,2,IF,KF), B(2,2,IF,KF), C(2,2,IF,KF), F(2,IF,KF),
     753             : !    1  BETA(2,2,IF,KF), GAMMA(2,2,IF,KF), Y(2,IF,KF), X(2,IF,KF)
     754             : !
     755             : ! Local:
     756             :       integer :: i,k
     757             : !     ****
     758             : !     ****     Lower boundary at K = K1
     759             : !     ****
     760      284544 :       DO I = I1,I2
     761             : !     ****
     762             : !     ****     Y(1,I,K1) = determinant(B(K1))
     763             : !     ****
     764      262656 :         Y(1,I,K1) = B(1,1,I,K1)*B(2,2,I,K1) - B(1,2,I,K1)*B(2,1,I,K1)
     765             : !     ****
     766             : !     ****     BETA(K1) = B(K1)**(-1)
     767             : !     ****
     768      262656 :         BETA(1,1,I,K1) = B(2,2,I,K1)/Y(1,I,K1)
     769      262656 :         BETA(1,2,I,K1) = -B(1,2,I,K1)/Y(1,I,K1)
     770      262656 :         BETA(2,1,I,K1) = -B(2,1,I,K1)/Y(1,I,K1)
     771      262656 :         BETA(2,2,I,K1) = B(1,1,I,K1)/Y(1,I,K1)
     772             : !     ****
     773             : !     ****     Y(K1) = BETA(K1)*F(K1)
     774             : !     ****
     775      262656 :         Y(1,I,K1) = BETA(1,1,I,K1)*F(1,I,K1) + BETA(1,2,I,K1)*F(2,I,K1)
     776      284544 :         Y(2,I,K1) = BETA(2,1,I,K1)*F(1,I,K1) + BETA(2,2,I,K1)*F(2,I,K1)
     777             :       ENDDO
     778             : !     ****
     779             : !     ****     Now deal with levels (K1+1),K2,1
     780             : !     ****
     781     1838592 :       DO K = K1+1,K2
     782    23639040 :         DO I = I1,I2
     783             : !         ****
     784             : !         ****     GAMMA(K-1) = BETA(K-1)*C(K-1)
     785             : !         ****
     786    43600896 :           GAMMA(1,1,I,K-1) = BETA(1,1,I,K-1)*C(1,1,I,K-1) +              &
     787    43600896 :             BETA(1,2,I,K-1)*C(2,1,I,K-1)
     788             :           GAMMA(1,2,I,K-1) = BETA(1,1,I,K-1)*C(1,2,I,K-1) +              &
     789    21800448 :             BETA(1,2,I,K-1)*C(2,2,I,K-1)
     790             :           GAMMA(2,1,I,K-1) = BETA(2,1,I,K-1)*C(1,1,I,K-1) +              &
     791    21800448 :             BETA(2,2,I,K-1)*C(2,1,I,K-1)
     792             :           GAMMA(2,2,I,K-1) = BETA(2,1,I,K-1)*C(1,2,I,K-1) +              &
     793    21800448 :             BETA(2,2,I,K-1)*C(2,2,I,K-1)
     794             : !         ****
     795             : !         ****     GAMMA(K) = B(K) - A(K)*GAMMA(K-1)
     796             : !         ****
     797    21800448 :           GAMMA(1,1,I,K) = B(1,1,I,K) - A(1,1,I,K)*GAMMA(1,1,I,K-1) -    &
     798    21800448 :             A(1,2,I,K)*GAMMA(2,1,I,K-1)
     799             :           GAMMA(1,2,I,K) = B(1,2,I,K) - A(1,1,I,K)*GAMMA(1,2,I,K-1) -    &
     800    21800448 :             A(1,2,I,K)*GAMMA(2,2,I,K-1)
     801             :           GAMMA(2,1,I,K) = B(2,1,I,K) - A(2,1,I,K)*GAMMA(1,1,I,K-1) -    &
     802    21800448 :             A(2,2,I,K)*GAMMA(2,1,I,K-1)
     803             :           GAMMA(2,2,I,K) = B(2,2,I,K) - A(2,1,I,K)*GAMMA(1,2,I,K-1) -    &
     804    21800448 :             A(2,2,I,K)*GAMMA(2,2,I,K-1)
     805             : !         ****
     806             : !         ****     Y(1,I,K) = determinant(GAMMA(K))
     807             : !         ****
     808             :           Y(1,I,K) = GAMMA(1,1,I,K)*GAMMA(2,2,I,K) -                     &
     809    21800448 :             GAMMA(1,2,I,K)*GAMMA(2,1,I,K)
     810             : !         ****
     811             : !         ****     BETA(K) = GAMMA(K)**(-1)
     812             : !         ****
     813    21800448 :           BETA(1,1,I,K) = GAMMA(2,2,I,K)/Y(1,I,K)
     814    21800448 :           BETA(1,2,I,K) = -GAMMA(1,2,I,K)/Y(1,I,K)
     815    21800448 :           BETA(2,1,I,K) = -GAMMA(2,1,I,K)/Y(1,I,K)
     816    21800448 :           BETA(2,2,I,K) = GAMMA(1,1,I,K)/Y(1,I,K)
     817             : !         ****
     818             : !         ****     X(K) = F(K) - A(K)*Y(K-1)
     819             : !         ****
     820             :           X(1,I,K) = F(1,I,K) - A(1,1,I,K)*Y(1,I,K-1) -                  &
     821    21800448 :             A(1,2,I,K)*Y(2,I,K-1)
     822             :           X(2,I,K) = F(2,I,K) - A(2,1,I,K)*Y(1,I,K-1) -                  &
     823    21800448 :             A(2,2,I,K)*Y(2,I,K-1)
     824             : !         ****
     825             : !         ****     Y(K) = BETA(K)*X(K)
     826             : !         ****
     827    21800448 :           Y(1,I,K) = BETA(1,1,I,K)*X(1,I,K) + BETA(1,2,I,K)*X(2,I,K)
     828    23617152 :           Y(2,I,K) = BETA(2,1,I,K)*X(1,I,K) + BETA(2,2,I,K)*X(2,I,K)
     829             :         ENDDO
     830             :       ENDDO
     831             : !     ****
     832             : !     ****     Backward sweep to determine final solution, X(K) for
     833             : !     ****     K = K2,K1,-1
     834             : !     ****
     835             : !     ****      X(K2) = Y(K2)
     836             : !     ****
     837      284544 :       DO I = I1,I2
     838      262656 :         X(1,I,K2) = Y(1,I,K2)
     839      284544 :         X(2,I,K2) = Y(2,I,K2)
     840             :       ENDDO
     841             : !     ****
     842             : !     ****      X(K) = Y(K) - GAMMA(K)*X(K+1)
     843             : !     ****
     844     1838592 :       DO K = K2-1,K1,-1
     845    23639040 :         DO I = I1,I2
     846    65401344 :           X(1,I,K) = Y(1,I,K) - GAMMA(1,1,I,K)*X(1,I,K+1) -             &
     847    65401344 :             GAMMA(1,2,I,K)*X(2,I,K+1)
     848             :           X(2,I,K) = Y(2,I,K) - GAMMA(2,1,I,K)*X(1,I,K+1) -             &
     849    23617152 :             GAMMA(2,2,I,K)*X(2,I,K+1)
     850             : 
     851             :         ENDDO
     852             :       ENDDO
     853       21888 :       RETURN
     854       21888 :       END SUBROUTINE BLKTRI
     855             : 
     856             : end module majorsp_diffusion

Generated by: LCOV version 1.14