LCOV - code coverage report
Current view: top level - ionosphere/waccmx - edyn_solve.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 411 423 97.2 %
Date: 2025-03-14 01:26:08 Functions: 12 12 100.0 %

          Line data    Source code
       1             : module edyn_solve
       2             : !
       3             : ! Prepare stencils and call mudpack PDE solver. This is executed
       4             : ! by the root task only, following the gather_edyn call in edynamo.F90.
       5             : !
       6             :   use shr_kind_mod ,only: r8 => shr_kind_r8 ! 8-byte reals
       7             :   use cam_logfile  ,only: iulog
       8             :   use edyn_params  ,only: finit
       9             :   use edyn_maggrid ,only: nmlon,nmlonp1,nmlat,nmlath
      10             :   use edyn_maggrid ,only: res_nlev, res_ngrid
      11             :   use spmd_utils,   only: masterproc
      12             :   use edyn_solver_coefs, only: nc, cee, cofum
      13             : 
      14             :   implicit none
      15             :   private
      16             : 
      17             :   public :: edyn_solve_init
      18             :   public :: solve_edyn
      19             : 
      20             : !
      21             : ! Global 2d fields for root task to complete serial part of dynamo.
      22             : ! The zigmxxx, rhs and rims are gathered from subdomains by in sub
      23             : ! gather_edyn (edynamo.F90).
      24             : !
      25             :   real(r8),allocatable, dimension(:,:), public :: &
      26             :     zigm11_glb  ,&
      27             :     zigm22_glb  ,&
      28             :     zigmc_glb   ,&
      29             :     zigm2_glb   ,&
      30             :     rhs_glb
      31             :   real(r8),allocatable, dimension(:,:,:), public :: &
      32             :     rim_glb    ! pde solver output
      33             :   real(r8),allocatable, dimension(:,:) :: &
      34             :     phisolv
      35             : !
      36             : ! Dimensions of the grid resolutions for the multi-grid PDE:
      37             :   integer, public, protected :: &
      38             :     nmlon0, &
      39             :     nmlat0, &
      40             :     nmlon1, &
      41             :     nmlat1, &
      42             :     nmlon2, &
      43             :     nmlat2, &
      44             :     nmlon3, &
      45             :     nmlat3, &
      46             :     nmlon4, &
      47             :     nmlat4, &
      48             :     nmlon5, &
      49             :     nmlat5, &
      50             :     nmlon6, &
      51             :     nmlat6, &
      52             :     nmlon7, &
      53             :     nmlat7
      54             : !
      55             : ! Space needed for descretized coefficients of of dynamo pde at all levels:
      56             : !
      57             :   integer :: ncee
      58             : !
      59             : ! The following parameters nc0,nc1,... are pointers to the beginning of
      60             : !   the coefficients for each level of resolution.
      61             : !
      62             :   integer :: &
      63             :     nc0, &
      64             :     nc1, &
      65             :     nc2, &
      66             :     nc3, &
      67             :     nc4, &
      68             :     nc5, &
      69             :     nc6, &
      70             :     nc7
      71             : 
      72             :   real(r8), private, pointer :: &
      73             :     c0(:),  &
      74             :     c1(:),  &
      75             :     c2(:),  &
      76             :     c3(:),  &
      77             :     c4(:),  &
      78             :     c5(:),  &
      79             :     c6(:),  &
      80             :     c7(:)
      81             : 
      82             : ! phihm is high-latitude potential, set by the high-latitude potential model (e.g. Heelis)
      83             : ! or is prescribed (e.g. AMIE)
      84             : !
      85             :   real(r8), allocatable, public :: phihm(:,:) ! high-latitude potential
      86             :   real(r8), allocatable, public :: pfrac(:,:) ! NH fraction of potential
      87             : 
      88             :   contains
      89             : 
      90             : !-----------------------------------------------------------------------
      91         768 :   subroutine edyn_solve_init
      92             :     use infnan, only: nan, assignment(=)
      93             : 
      94        3072 :     allocate(zigm11_glb(nmlonp1,nmlat))
      95        2304 :     allocate(zigm22_glb(nmlonp1,nmlat))
      96        2304 :     allocate(zigmc_glb(nmlonp1,nmlat))
      97        2304 :     allocate(zigm2_glb(nmlonp1,nmlat))
      98        2304 :     allocate(rhs_glb(nmlonp1,nmlat))
      99        3840 :     allocate(rim_glb(nmlonp1,nmlat,2))
     100        3072 :     allocate(phisolv(0:nmlonp1,0:nmlat+1))
     101             : 
     102     6311424 :     phisolv(:,:) = 0._r8
     103             :     
     104         768 :     nmlon0=nmlon+1
     105         768 :     nmlat0=(nmlat +1)/2
     106         768 :     nmlon1=(nmlon0+1)/2
     107         768 :     nmlat1=(nmlat0+1)/2
     108         768 :     nmlon2=(nmlon1+1)/2
     109         768 :     nmlat2=(nmlat1+1)/2
     110         768 :     nmlon3=(nmlon2+1)/2
     111         768 :     nmlat3=(nmlat2+1)/2
     112         768 :     nmlon4=(nmlon3+1)/2
     113         768 :     nmlat4=(nmlat3+1)/2
     114         768 :     nmlon5=(nmlon4+1)/2
     115         768 :     nmlat5=(nmlat4+1)/2
     116         768 :     nmlon6=(nmlon5+1)/2
     117         768 :     nmlat6=(nmlat5+1)/2
     118         768 :     nmlon7=(nmlon6+1)/2
     119         768 :     nmlat7=(nmlat6+1)/2
     120             : 
     121        3840 :     allocate(cofum(nmlon0,nmlat0,9))
     122             : 
     123             :     ncee=10*nmlon0*nmlat0+9*(nmlon1*nmlat1+nmlon2*nmlat2+nmlon3* &
     124         768 :          nmlat3+nmlon4*nmlat4+nmlon5*nmlat5+nmlon6*nmlat6+nmlon7*nmlat7)
     125             : 
     126        2304 :     allocate(cee(ncee))
     127             : 
     128         768 :     nc0=1
     129         768 :     nc1=nc0+10*nmlon0*nmlat0
     130         768 :     nc2=nc1+9 *nmlon1*nmlat1
     131         768 :     nc3=nc2+9 *nmlon2*nmlat2
     132         768 :     nc4=nc3+9 *nmlon3*nmlat3
     133         768 :     nc5=nc4+9 *nmlon4*nmlat4
     134         768 :     nc6=nc5+9 *nmlon5*nmlat5
     135         768 :     nc7=nc6+9 *nmlon6*nmlat6
     136             : 
     137         768 :     c0 => cee
     138         768 :     c1 => cee(nc1:)
     139         768 :     c2 => cee(nc2:)
     140         768 :     c3 => cee(nc3:)
     141         768 :     c4 => cee(nc4:)
     142         768 :     c5 => cee(nc5:)
     143         768 :     c6 => cee(nc6:)
     144         768 :     c7 => cee(nc7:)
     145             : 
     146        2304 :     allocate(phihm(nmlonp1,nmlat))
     147        3072 :     allocate(pfrac(nmlonp1,nmlat0))
     148             : 
     149         768 :     phihm = nan
     150         768 :     pfrac = nan
     151             : 
     152         768 :   end subroutine edyn_solve_init
     153             : 
     154             : !-----------------------------------------------------------------------
     155          19 :   subroutine solve_edyn
     156             : !
     157             : ! Set up stencils for solver:
     158             : !
     159          19 :     call stencils
     160             : !
     161             : ! Call mudpack PDE solver:
     162             : !
     163          19 :     call solver(cofum,c0)
     164             : 
     165          19 :   end subroutine solve_edyn
     166             : !-----------------------------------------------------------------------
     167          19 :   subroutine stencils
     168             :   use edyn_params ,only: pi_dyn
     169             :   use edyn_maggrid,only: dlatm,dlonm
     170             : !
     171             : ! Locals:
     172             :     integer :: i,j,jj,jjj,j0,n,ncc,nmaglon,nmaglat, ndx1,ndx2
     173             :     real(r8) :: sym
     174          38 :     real(r8) :: cs(nmlat0)
     175             : 
     176             : !
     177             : ! Set index array nc and magnetic latitude cosine array:
     178             : ! nc pointes to the start of the coefficient array for each level
     179          19 :     nc(1) = nc0
     180          19 :     nc(2) = nc1
     181          19 :     nc(3) = nc2
     182          19 :     nc(4) = nc3
     183          19 :     nc(5) = nc4
     184          19 :     nc(6) = nc5
     185          19 :     nc(7) = nc6
     186          19 :     nc(8) = nc7
     187          19 :     nc(9) = ncee
     188             : 
     189         950 :     do j=1,nmlat0
     190         950 :       cs(j) = cos(pi_dyn/2._r8-(nmlat0-j)*dlatm)
     191             :     enddo ! j=1,nmlat0
     192             : !
     193             : ! Set up difference coefficients. Replace zigm11 by A, zigm22 by B,
     194             : ! zigmc by C, and zigm2 by D.
     195             : !
     196          19 :     j0 = nmlat0-nmlath
     197         950 :     do j=1,nmlath       !  1,49 (assuming nmlat=97)
     198         931 :       jj = nmlath+j-1   ! 49,97
     199         931 :       jjj = nmlath-j+1  ! 49,1
     200             : !
     201             : ! factor 4 from 5-point diff. stencil
     202             : ! Sigma_(phi lam)/( 4*Delta lam* Delta lon )
     203             : ! Sigma_(phi lam)/( 4*Delta lam* Delta lon )
     204             : ! Sigma_(lam lam)*cos(lam_m)*DT0DTS/(Delta lam)^2
     205             : ! -zigmc_north = southern hemis. 49,1 equator-pole
     206             : ! -zigm2_north = southern hemis. 49,1 equator-pole
     207             : !  zigm22 = southern hemis. 49,1 equator-pole
     208             : !
     209       76342 :       do i=1,nmlonp1
     210           0 :         zigmc_glb(i,jj) = (zigmc_glb(i,jj)+zigm2_glb(i,jj))/ &
     211       75411 :           (4._r8*dlatm*dlonm)
     212           0 :         zigm2_glb(i,jj) = zigmc_glb(i,jj)-2._r8*zigm2_glb(i,jj)/ &
     213       75411 :           (4._r8*dlatm*dlonm)
     214       75411 :         zigm22_glb(i,jj)  = zigm22_glb(i,jj)*cs(j0+j)/dlatm**2
     215       75411 :         zigmc_glb(i,jjj)  = -zigmc_glb(i,jj)
     216       75411 :         zigm2_glb(i,jjj)  = -zigm2_glb(i,jj)
     217       76342 :         zigm22_glb(i,jjj) = zigm22_glb(i,jj)
     218             :       enddo ! i=1,nmlonp1
     219         950 :       if (j /= nmlath) then
     220             : !
     221             : ! Sigma_(phi phi)/( cos(lam_m)*DT0DTS*(Delta lon)^2 )
     222             : ! zigm11 = southern hemis. 49,1 equator-pole
     223             : !
     224       74784 :         do i = 1,nmlonp1
     225       73872 :           zigm11_glb(i,jj)  = zigm11_glb(i,jj)/(cs(j0+j)*dlonm**2)
     226       74784 :           zigm11_glb(i,jjj) = zigm11_glb(i,jj)
     227             :         enddo
     228             :       endif
     229             :     enddo ! j=1,nmlath
     230             : !
     231             : ! Set zigm11 to zero at megnetic poles to avoid floating exception
     232             : ! (values at poles are not used):
     233             : !
     234        1558 :     do i = 1,nmlonp1
     235        1539 :       zigm11_glb(i,1) = 0.0_r8
     236        1558 :       zigm11_glb(i,nmlat) = 0.0_r8
     237             :     enddo
     238             : 
     239             : ! Clear array for difference stencils at all levels:
     240          19 :     call clearcee(cee,nmlon0,nmlat0)
     241             : !
     242             : ! Init cofum coefficients:
     243      687268 :     cofum(:,:,:) = finit
     244             : !
     245             : ! Calculate contribution to stencils from each PDE coefficient
     246             : !
     247             : ! Sigma_(phi phi)/( cos(lam_m)*dt0dts*(Delta lon)^2 )
     248          19 :     sym = 1._r8
     249          19 :     call stencmd(zigm11_glb,nmlon0,nmlat0,sym,cee,1)
     250             : !
     251             : ! Sigma_(lam lam)*cos(lam_m)*dt0dts/(Delta lam)^2
     252          19 :     sym = 1._r8
     253          19 :     call stencmd(zigm22_glb,nmlon0,nmlat0,sym,cee,4)
     254             : !
     255             : ! Sigma_(phi lam)/( 4*Delta lam* Delta lon )
     256          19 :     sym = -1._r8
     257          19 :     call stencmd(zigmc_glb,nmlon0,nmlat0,sym,cee,2)
     258             : !
     259             : ! Sigma_(lam phi)/( 4*Delta lam* Delta lon )
     260          19 :     sym = -1._r8
     261          19 :     call stencmd(zigm2_glb,nmlon0,nmlat0,sym,cee,3)
     262             : !
     263             : ! Insert RHS in finest stencil:
     264         950 :     do j = 1,nmlat0
     265         931 :       jj = nmlath-nmlat0+j
     266       76361 :       do i = 1,nmlon0
     267       75411 :         ndx1 = 9*nmlat0*nmlon0 + (j-1)*nmlon0 + i
     268       76342 :         c0(ndx1) = rhs_glb(i,jj)
     269             :       enddo ! i = 1,nmlon0
     270             :     enddo ! j = 1,nmlat0
     271          19 :     ndx1 = 9*nmlat0*nmlon0 + nmlonp1
     272          19 :     ndx2 = 9*nmlat0*nmlon0 + 1
     273          19 :     c0(ndx1) = c0(ndx2)
     274             : !
     275             : ! Set boundary condition at the pole:
     276          19 :     call edges(c0,nmlon0,nmlat0)
     277          19 :     call edges(c1,nmlon1,nmlat1)
     278          19 :     call edges(c2,nmlon2,nmlat2)
     279          19 :     call edges(c3,nmlon3,nmlat3)
     280          19 :     call edges(c4,nmlon4,nmlat4)
     281          19 :     if ( res_nlev > 5 ) then
     282           0 :        call edges(c5,nmlon5,nmlat5)
     283             :     endif
     284          19 :     if ( res_nlev > 6 ) then
     285           0 :        call edges(c6,nmlon6,nmlat6)
     286             :     endif
     287          19 :     if ( res_nlev > 7 ) then
     288           0 :        call edges(c7,nmlon7,nmlat7)
     289             :     endif
     290          19 :     call edges(cofum,nmlon0,nmlat0)
     291             : !
     292             : ! Divide stencils by cos(lam_0) (not rhs):
     293          19 :     call divide(c0,nmlon0,nmlat0,nmlon0,cs,1)
     294          19 :     call divide(c1,nmlon1,nmlat1,nmlon0,cs,1)
     295          19 :     call divide(c2,nmlon2,nmlat2,nmlon0,cs,1)
     296          19 :     call divide(c3,nmlon3,nmlat3,nmlon0,cs,1)
     297          19 :     call divide(c4,nmlon4,nmlat4,nmlon0,cs,1)
     298          19 :     if ( res_nlev > 5 ) then
     299           0 :        call divide(c5,nmlon5,nmlat5,nmlon0,cs,1)
     300             :     endif
     301          19 :     if ( res_nlev > 6 ) then
     302           0 :        call divide(c6,nmlon6,nmlat6,nmlon0,cs,1)
     303             :     endif
     304          19 :     if ( res_nlev > 7 ) then
     305           0 :        call divide(c7,nmlon7,nmlat7,nmlon0,cs,1)
     306             :     endif
     307          19 :     call divide(cofum,nmlon0,nmlat0,nmlon0,cs,0)
     308             : !
     309             : ! Set value of solution to 1. at pole:
     310        1558 :     do i=1,nmlon0
     311        1539 :       ndx1 = 9*nmlat0*nmlon0 + (nmlat0-1)*nmlon0 + i
     312        1558 :       c0(ndx1) = 1._r8
     313             :     enddo
     314             : !
     315             : ! Modify stencils and RHS so that the NH high lat potential is inserted at
     316             : !  high latitude.  The SH high lat potential will be added back later.
     317             : !  pfrac = fraction of dynamo in solution in the NH. = 1 low lat, = 0 hi lat
     318             : !    cons_module: crit(1)=15, crit(2)=30 deg colats, or hi-lat > 75 deg,
     319             : !      dynamo < 60 deg, and combination between 60-75 mag lat.
     320             : ! The dynamo is symmetric about the magnetic equator, but the high latitude
     321             : !  is anti-symmetric in both hemispheres.  However, since Mudpack uses the
     322             : !  NH potential pattern, then the SH potential pattern must be added
     323             : !  back into the 2-D phim before the call threed, and before it is
     324             : !  transformed to geographic coordinates.
     325             : !
     326          19 :     ncc = 1
     327          19 :     nmaglon = nmlon0
     328          19 :     nmaglat = nmlat0
     329         114 :     do n=1,res_nlev ! resolution levels
     330          95 :       call stenmd(nmaglon,nmaglat,cee(ncc),phihm(1,nmlat0),pfrac)
     331          95 :       ncc = ncc+9*nmaglon*nmaglat
     332          95 :       if (n==1) ncc = ncc+nmaglon*nmaglat ! rhs is in 10th slot
     333          95 :       nmaglon = (nmaglon+1)/2
     334         209 :       nmaglat = (nmaglat+1)/2
     335             :     enddo
     336             : 
     337          19 :   end subroutine stencils
     338             : !-----------------------------------------------------------------------
     339          19 :   subroutine clearcee(cee,nlon0,nlat0)
     340             : !
     341             : ! Zero C arrays for stencil coefficients.
     342             : ! Cee will contain:
     343             : !   c0(nmlon0,nmlat0,10), c1(nmlon1,nmlat1,9), c2(nmlon2,nmlat2,9),
     344             : !   c3(nmlon3,nmlat3,9),  c4(nmlon4,nmlat4,9)
     345             : !
     346             : ! Args:
     347             :     integer,intent(in) :: nlon0,nlat0
     348             :     real(r8),intent(out) :: cee(*)
     349             : !
     350             : ! Local:
     351             :     integer :: nlon,nlat,n,m,i
     352             : !
     353             : ! Compute total size of cee
     354          19 :     nlon = nlon0
     355          19 :     nlat = nlat0
     356          19 :     n = 0
     357         114 :     do m=1,res_nlev ! resolution levels
     358          95 :       n = n+nlon*nlat
     359          95 :       nlon = (nlon+1)/2
     360         114 :       nlat = (nlat+1)/2
     361             :     enddo
     362          19 :     n = 9*n+nlon0*nlat0
     363             : !
     364             : ! Clear cee:
     365      993358 :     do i=1,n
     366      993358 :       cee(i) = 0._r8
     367             :     enddo
     368          19 :   end subroutine clearcee
     369             : !-----------------------------------------------------------------------
     370          76 :   subroutine stencmd(zigm,nlon0,nlat0,sym,cee,ncoef)
     371             : !
     372             : ! Calculate contribution fo 3 by 3 stencil from coefficient zigm
     373             : ! at each grid point and level.
     374             : !
     375             : ! Args:
     376             :     integer,intent(in) ::  &
     377             :       nlon0,               & ! longitude dimension of finest grid level
     378             :       nlat0,               & ! latitude dimension of finest grid level
     379             :       ncoef                  ! integer identifier of coefficient
     380             :     real(r8),intent(in) :: &
     381             :       zigm(nlon0,nlat0),   & ! coefficients (nlon0+1/2,(nlat0+1)/2)
     382             :       sym                    !  1. if zigm symmetric w.r.t. equator, -1 otherwise
     383             :     real(r8),intent(inout) ::  & ! output stencil array consisting of c0,c1,c2,c3,c4
     384             :       cee(*)
     385             : !
     386             : ! Local:
     387             :     integer :: nc,nlon,nlat,n
     388         152 :     real(r8) :: wkarray(-res_ngrid+1:nmlon0+res_ngrid,nmlat0)
     389             : !
     390             : ! Perform half-way interpolation and extend zigm in wkarray:
     391             : !
     392          76 :     call htrpex(zigm,nlon0,nlat0,sym,wkarray)
     393             : !
     394             : ! Calculate contribution to stencil for each grid point and level:
     395             : !
     396          76 :     nc = 1
     397          76 :     nlon = nlon0
     398          76 :     nlat = nlat0
     399             : !
     400             : ! Calculate modified and unmodified stencil on finest grid
     401             : !
     402          76 :     call cnmmod(nlon0,nlon,nlat,cee(nc),ncoef,wkarray,cofum)
     403             : !
     404             : ! Stencils on other grid levels remain the same.
     405          76 :     nc = nc+10*nlon*nlat
     406          76 :     nlon = (nlon+1)/2
     407          76 :     nlat = (nlat+1)/2
     408             : !
     409         380 :     do n=2,res_nlev
     410         304 :       call cnm(nlon0,nlon,nlat,cee(nc),ncoef,wkarray)
     411         304 :       nc = nc+9*nlon*nlat
     412         304 :       if (n==1) nc = nc+nlon*nlat
     413         304 :       nlon = (nlon+1)/2
     414         684 :       nlat = (nlat+1)/2
     415             :     enddo ! n=1,5
     416          76 :   end subroutine stencmd
     417             : !-----------------------------------------------------------------------
     418          76 :   subroutine htrpex(coeff,nmlon0,nmlat0,sym,wkarray)
     419             : !
     420             : ! Perform half-way interpolation on array coeff and extend over 16 grid
     421             : ! points. Result returned in wkarray.
     422             : !
     423             : ! Args:
     424             :     integer,intent(in)   :: nmlon0,nmlat0
     425             :     real(r8),intent(in)  :: coeff(nmlon0,nmlat0),sym
     426             :     real(r8),intent(out) :: wkarray(-res_ngrid+1:nmlon0+res_ngrid,nmlat0)
     427             : !
     428             : ! Local:
     429             :     integer :: i,j,jj
     430             : !
     431             : ! Copy coeff into positions in wkarray:
     432        3800 :     do j=1,nmlat0
     433        3724 :       jj = nmlat0-j+1
     434      305444 :       do i=1,nmlon0
     435      305368 :         wkarray(i,j) = sym*coeff(i,jj)
     436             :       enddo ! i=1,nmlon0
     437             :     enddo ! j=1,nmlat0
     438             : !
     439             : ! Extend over 2*res_ngrid grid spaces to allow for a total of res_nlev grid levels:
     440        1292 :     do i=1,res_ngrid
     441       60876 :       do j=1,nmlat0
     442       59584 :         wkarray(1-i,j) = wkarray(nmlon0-i,j)
     443       60800 :         wkarray(nmlon0+i,j) = wkarray(1+i,j)
     444             :       enddo ! j=1,nmlat0
     445             :     enddo ! i=1,res_ngrid
     446          76 :   end subroutine htrpex
     447             : !-----------------------------------------------------------------------
     448         304 :   subroutine cnm(nlon0,nlon,nlat,c,ncoef,wkarray)
     449             : !
     450             : ! Compute contribution to stencil from zigm(ncoef) on grid nlon by nlat,
     451             : ! Finest grid is nlon0.
     452             : !
     453             : ! Args:
     454             :     integer,intent(in) :: &
     455             :       nlon0,              & ! finest grid dimensions
     456             :       nlon,nlat             ! output grid dimensions
     457             :     real(r8),intent(in) :: wkarray(-res_ngrid+1:nmlon0+res_ngrid,nmlat0)
     458             : !
     459             : ! ncoef: integer id of coefficient:
     460             : ! ncoef = 1 for zigm11
     461             : ! ncoef = 2 for zigm12 (=zigmc+zigm2)
     462             : ! ncoef = 3 for zigm21 (=zigmc-zigm2)
     463             : ! ncoef = 4 for zigm22
     464             : !
     465             :     integer,intent(in) :: ncoef
     466             :     real(r8),intent(inout) :: &
     467             :       c(nlon,nlat,*) ! output array for grid point stencils at resolution nlon x nlat
     468             : !
     469             : ! Local:
     470             :     integer :: i,j,nint,i0,j0
     471             : ! For now, retain this pi to insure bit compatability w/ old code
     472             :     real(r8),parameter :: pi=3.141592654_r8
     473         608 :     real(r8) :: wk(nlon0,3)
     474             : !
     475             : ! Compute separation of grid points of resolution nlon x nlat within
     476             : ! grid of resolution nlon0. Evaluate dlon and dlat, grid spacing
     477             : ! of nlon x nlat.
     478             : !
     479         304 :     nint = (nlon0-1)/(nlon-1)
     480             : !
     481             : ! Scan wkarray nlon x nlat calculating and adding contributions to stencil
     482             : ! from zigm(ncoef)
     483         304 :     i0 = 1-nint
     484         304 :     j0 = 1-nint
     485             : !
     486             : ! zigm11:
     487             : ! am 2001-6-27 include boundary condition at equator
     488         304 :     if (ncoef==1) then
     489         931 :       do j = 1,nlat-1
     490       26011 :         do i = 1,nlon
     491      100320 :           c(i,j,1) = c(i,j,1)+0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     492      125400 :             wkarray(i0+(i+1)*nint,j0+j*nint))
     493             :           c(i,j,5) = c(i,j,5)+0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     494       25080 :             wkarray(i0+(i-1)*nint,j0+j*nint))
     495             :           c(i,j,9) = c(i,j,9)-0.5_r8*(wkarray(i0+(i+1)*nint,j0+j*nint)+ &
     496       25935 :             2._r8*wkarray(i0+i*nint,j0+j*nint)+wkarray(i0+(i-1)*nint,j0+j*nint))
     497             :         enddo ! i = 1,nlon
     498             :       enddo ! j = 2,nlat-1
     499             : !
     500             : ! zigm12 (=zigmc+zigm2)
     501         228 :     elseif (ncoef==2) then
     502         855 :       do j = 2,nlat-1
     503       24434 :         do i = 1,nlon
     504       94316 :           c(i,j,2) = c(i,j,2)+0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     505      117895 :             wkarray(i0+(i+1)*nint,j0+j*nint))
     506             :           c(i,j,4) = c(i,j,4)-0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     507       23579 :             wkarray(i0+(i-1)*nint,j0+j*nint))
     508             :           c(i,j,6) = c(i,j,6)+0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     509       23579 :             wkarray(i0+(i-1)*nint,j0+j*nint))
     510             :           c(i,j,8) = c(i,j,8)-0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     511       23579 :             wkarray(i0+(i+1)*nint,j0+j*nint))
     512       23579 :           wk(i,1) = 0.5_r8*(wkarray(i0+(i+1)*nint,j0+j*nint)- &
     513       23579 :             wkarray(i0+(i-1)*nint,j0+j*nint))
     514       23579 :           wk(i,2) = (c(i,j,3)+wk(i,1))*(c(i,j,7)-wk(i,1))
     515       23579 :           wk(i,3) = sign(wk(i,1),c(i,j,3)+c(i,j,7))
     516       23579 :           if (wk(i,2) >= 0._r8) wk(i,3) = 0._r8
     517       23579 :           c(i,j,3) = c(i,j,3)+wk(i,1)+wk(i,3)
     518       23579 :           c(i,j,7) = c(i,j,7)-wk(i,1)+wk(i,3)
     519       24358 :           c(i,j,9) = c(i,j,9)-2._r8*wk(i,3)
     520             :         enddo ! i = 1,nlon
     521             :       enddo ! j = 2,nlat-1
     522             : !
     523             : ! zigm21 (=zigmc-zigm2)
     524         152 :     elseif (ncoef==3) then
     525         855 :       do j = 2,nlat-1
     526       24434 :         do i = 1,nlon
     527       94316 :           c(i,j,2) = c(i,j,2)+0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     528      117895 :             wkarray(i0+i*nint,j0+(j+1)*nint))
     529             :           c(i,j,4) = c(i,j,4)-0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     530       23579 :             wkarray(i0+i*nint,j0+(j+1)*nint))
     531             :           c(i,j,6) = c(i,j,6)+0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     532       23579 :             wkarray(i0+i*nint,j0+(j-1)*nint))
     533             :           c(i,j,8) = c(i,j,8)-0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     534       23579 :             wkarray(i0+i*nint,j0+(j-1)*nint))
     535       23579 :           wk(i,1) = 0.5_r8*(wkarray(i0+i*nint,j0+(j+1)*nint)- &
     536       23579 :             wkarray(i0+i*nint,j0+(j-1)*nint))
     537       23579 :           wk(i,2) = (c(i,j,1)+wk(i,1))*(c(i,j,5)-wk(i,1))
     538       23579 :           wk(i,3) = sign(wk(i,1),c(i,j,1)+c(i,j,5))
     539       23579 :           if (wk(i,2) >= 0._r8) wk(i,3) = 0._r8
     540       23579 :           c(i,j,1) = c(i,j,1)+wk(i,1)+wk(i,3)
     541       23579 :           c(i,j,5) = c(i,j,5)-wk(i,1)+wk(i,3)
     542       24358 :           c(i,j,9) = c(i,j,9)-2._r8*wk(i,3)
     543             :         enddo ! i = 1,nlon
     544             :       enddo ! j = 2,nlat-1
     545             : !
     546             : ! Low latitude boundary condition:
     547        1577 :       j = 1
     548        1577 :       do i=1,nlon
     549        4503 :         c(i,j,2) = c(i,j,2)+0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     550        4503 :           wkarray(i0+i*nint,j0+(j+1)*nint))
     551             :         c(i,j,4) = c(i,j,4)-0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     552        1501 :           wkarray(i0+i*nint,j0+(j+1)*nint))
     553        1501 :         wk(i,1) = 0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     554        1501 :           wkarray(i0+i*nint,j0+(j+1)*nint))
     555        1501 :         wk(i,2) = (c(i,j,1)+wk(i,1))*(c(i,j,5)-wk(i,1))
     556        1501 :         wk(i,3) = sign(wk(i,1),c(i,j,1)+c(i,j,5))
     557        1501 :         if (wk(i,2) >= 0._r8) wk(i,3) = 0._r8
     558        1501 :         c(i,j,1) = c(i,j,1)+wk(i,1)+wk(i,3)
     559        1501 :         c(i,j,5) = c(i,j,5)-wk(i,1)+wk(i,3)
     560        1577 :         c(i,j,9) = c(i,j,9)-2._r8*wk(i,3)
     561             :       enddo ! i=1,nlon
     562             : !
     563             : ! zigm22:
     564          76 :     elseif (ncoef==4) then
     565         855 :       do j = 2,nlat-1
     566       24434 :         do i = 1,nlon
     567       94316 :           c(i,j,3) = c(i,j,3)+0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     568      117895 :             wkarray(i0+i*nint,j0+(j+1)*nint))
     569             :           c(i,j,7) = c(i,j,7)+0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     570       23579 :             wkarray(i0+i*nint,j0+(j-1)*nint))
     571             :           c(i,j,9) = c(i,j,9)-0.5_r8*(wkarray(i0+i*nint,j0+(j-1)*nint)+ &
     572             :             2._r8*wkarray(i0+i*nint,j0+j*nint)+ &
     573       24358 :             wkarray(i0+i*nint,j0+(j+1)*nint))
     574             :         enddo ! i = 1,nlon
     575             :       enddo ! j = 2,nlat-1
     576             : !
     577             : ! Low latitude boundary condition:
     578        1577 :       j = 1
     579        1577 :       do i=1,nlon
     580        4503 :         c(i,j,3) = c(i,j,3)+0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     581        4503 :           wkarray(i0+i*nint,j0+(j+1)*nint))
     582             :         c(i,j,9) = c(i,j,9)-0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     583        1577 :                                 wkarray(i0+i*nint,j0+(j+1)*nint))
     584             :       enddo ! i=1,nlon
     585             :     endif ! ncoef
     586         304 :   end subroutine cnm
     587             : !-----------------------------------------------------------------------
     588          76 :   subroutine cnmmod(nlon0,nlon,nlat,c,ncoef,wkarray,cofum)
     589             : !
     590             : ! Compute contribution to stencil from zigm(ncoef) on grid nlon by nlat,
     591             : ! Finest grid is nlon0.
     592             : !
     593             : ! Args:
     594             :     integer,intent(in) :: &
     595             :       nlon0,              & ! finest grid dimensions
     596             :       nlon,nlat             ! output grid dimensions
     597             :     real(r8),intent(in) :: wkarray(-res_ngrid+1:nmlon0+res_ngrid,nmlat0)
     598             :     real(r8),dimension(nmlon0,nmlat0,9),intent(inout) :: cofum
     599             : !
     600             : ! ncoef: integer id of coefficient:
     601             : ! ncoef = 1 for zigm11
     602             : ! ncoef = 2 for zigm12 (=zigmc+zigm2)
     603             : ! ncoef = 3 for zigm21 (=zigmc-zigm2)
     604             : ! ncoef = 4 for zigm22
     605             : !
     606             :     integer,intent(in) :: ncoef
     607             :     real(r8),intent(inout) :: &
     608             :       c(nlon,nlat,*)  ! output array for grid point stencils at resolution nlon x nlat
     609             : !
     610             : ! Local:
     611             :     integer :: i,j,nint,i0,j0
     612             : ! For now, retain this pi to insure bit compatability w/ old code
     613             :     real(r8),parameter :: pi=3.141592654_r8
     614         152 :     real(r8) :: wk(nlon0,3)
     615             : !
     616             : ! Compute separation of grid points of resolution nlon x nlat within
     617             : ! grid of resolution nlon0. Evaluate dlon and dlat, grid spacing
     618             : ! of nlon x nlat.
     619             : !
     620          76 :     nint = (nlon0-1)/(nlon-1)
     621             : !
     622             : ! Scan wkarray nlon x nlat calculating and adding contributions to stencil
     623             : ! from zigm(ncoef)
     624          76 :     i0 = 1-nint
     625          76 :     j0 = 1-nint
     626             : !
     627             : ! zigm11:
     628             : ! am 2001-6-27 include boundary condition at equator
     629          76 :     if (ncoef==1) then
     630         931 :       do j = 1,nlat-1
     631       74803 :         do i = 1,nlon
     632      295488 :           c(i,j,1) = c(i,j,1)+0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     633      369360 :             wkarray(i0+(i+1)*nint,j0+j*nint))
     634             :           c(i,j,5) = c(i,j,5)+0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     635       73872 :             wkarray(i0+(i-1)*nint,j0+j*nint))
     636             :           c(i,j,9) = c(i,j,9)-0.5_r8*(wkarray(i0+(i+1)*nint,j0+j*nint)+ &
     637             :             2._r8*wkarray(i0+i*nint,j0+j*nint)+ &
     638       73872 :             wkarray(i0+(i-1)*nint,j0+j*nint))
     639             : !
     640             : ! Unmodified:
     641       73872 :           cofum(i,j,1) = cofum(i,j,1)+0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     642       73872 :             wkarray(i0+(i+1)*nint,j0+j*nint))
     643             :           cofum(i,j,5) = cofum(i,j,5)+0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     644       73872 :             wkarray(i0+(i-1)*nint,j0+j*nint))
     645             :           cofum(i,j,9) = cofum(i,j,9)-0.5_r8*(wkarray(i0+(i+1)*nint,j0+j*nint)+ &
     646       74784 :             2._r8*wkarray(i0+i*nint,j0+j*nint)+wkarray(i0+(i-1)*nint,j0+j*nint))
     647             :         enddo ! i = 1,nlon
     648             :       enddo ! j = 2,nlat-1
     649             : !
     650             : ! zigm12 (=zigmc+zigm2)
     651          57 :     elseif (ncoef==2) then
     652         912 :       do j = 2,nlat-1
     653       73245 :         do i = 1,nlon
     654      289332 :           c(i,j,2) = c(i,j,2)+0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     655      361665 :             wkarray(i0+(i+1)*nint,j0+j*nint))
     656             :           c(i,j,4) = c(i,j,4)-0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     657       72333 :             wkarray(i0+(i-1)*nint,j0+j*nint))
     658             :           c(i,j,6) = c(i,j,6)+0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     659       72333 :             wkarray(i0+(i-1)*nint,j0+j*nint))
     660             :           c(i,j,8) = c(i,j,8)-0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     661       72333 :             wkarray(i0+(i+1)*nint,j0+j*nint))
     662       72333 :           wk(i,1) = 0.5_r8*(wkarray(i0+(i+1)*nint,j0+j*nint)- &
     663       72333 :             wkarray(i0+(i-1)*nint,j0+j*nint))
     664             : !
     665             : ! Unmodified:
     666       72333 :           cofum(i,j,2) = c(i,j,2)
     667       72333 :           cofum(i,j,4) = c(i,j,4)
     668       72333 :           cofum(i,j,6) = c(i,j,6)
     669       72333 :           cofum(i,j,8) = c(i,j,8)
     670       72333 :           cofum(i,j,3) = cofum(i,j,3)+wk(i,1)
     671       72333 :           cofum(i,j,7) = cofum(i,j,7)-wk(i,1)
     672             : !
     673       72333 :           wk(i,2) = (c(i,j,3)+wk(i,1))*(c(i,j,7)-wk(i,1))
     674       72333 :           wk(i,3) = sign(wk(i,1),c(i,j,3)+c(i,j,7))
     675       72333 :           if (wk(i,2) >= 0._r8) wk(i,3) = 0._r8
     676       72333 :           c(i,j,3) = c(i,j,3)+wk(i,1)+wk(i,3)
     677       72333 :           c(i,j,7) = c(i,j,7)-wk(i,1)+wk(i,3)
     678       73226 :           c(i,j,9) = c(i,j,9)-2._r8*wk(i,3)
     679             :         enddo ! i = 1,nlon
     680             :       enddo ! j = 2,nlat-1
     681             : !
     682             : ! zigm21 (=zigmc-zigm2)
     683          38 :     elseif (ncoef==3) then
     684         912 :       do j = 2,nlat-1
     685       73245 :         do i = 1,nlon
     686      289332 :           c(i,j,2) = c(i,j,2)+0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     687      361665 :             wkarray(i0+i*nint,j0+(j+1)*nint))
     688             :           c(i,j,4) = c(i,j,4)-0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     689       72333 :             wkarray(i0+i*nint,j0+(j+1)*nint))
     690             :           c(i,j,6) = c(i,j,6)+0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     691       72333 :             wkarray(i0+i*nint,j0+(j-1)*nint))
     692             :           c(i,j,8) = c(i,j,8)-0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     693       72333 :             wkarray(i0+i*nint,j0+(j-1)*nint))
     694       72333 :           wk(i,1) = 0.5_r8*(wkarray(i0+i*nint,j0+(j+1)*nint)- &
     695       72333 :             wkarray(i0+i*nint,j0+(j-1)*nint))
     696             : !
     697             : ! Unmodified:
     698       72333 :           cofum(i,j,2) = c(i,j,2)
     699       72333 :           cofum(i,j,4) = c(i,j,4)
     700       72333 :           cofum(i,j,6) = c(i,j,6)
     701       72333 :           cofum(i,j,8) = c(i,j,8)
     702       72333 :           cofum(i,j,1) = cofum(i,j,1)+wk(i,1)
     703       72333 :           cofum(i,j,5) = cofum(i,j,5)-wk(i,1)
     704             : !
     705       72333 :           wk(i,2) = (c(i,j,1)+wk(i,1))*(c(i,j,5)-wk(i,1))
     706       72333 :           wk(i,3) = sign(wk(i,1),c(i,j,1)+c(i,j,5))
     707       72333 :           if (wk(i,2) >= 0._r8) wk(i,3) = 0._r8
     708       72333 :           c(i,j,1) = c(i,j,1)+wk(i,1)+wk(i,3)
     709       72333 :           c(i,j,5) = c(i,j,5)-wk(i,1)+wk(i,3)
     710       73226 :           c(i,j,9) = c(i,j,9)-2._r8*wk(i,3)
     711             :         enddo ! i = 1,nlon
     712             :       enddo ! j = 2,nlat-1
     713             : !
     714             : ! Low latitude boundary condition:
     715        1558 :       j = 1
     716        1558 :       do i=1,nlon
     717        4617 :         c(i,j,2) = c(i,j,2)+.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     718        4617 :           wkarray(i0+i*nint,j0+(j+1)*nint))
     719             :         c(i,j,4) = c(i,j,4)-.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     720        1539 :           wkarray(i0+i*nint,j0+(j+1)*nint))
     721        1539 :         wk(i,1) = .5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     722        1539 :           wkarray(i0+i*nint,j0+(j+1)*nint))
     723             : 
     724        1539 :         cofum(i,j,2) = c(i,j,2)
     725        1539 :         cofum(i,j,4) = c(i,j,4)
     726        1539 :         cofum(i,j,1) = cofum(i,j,1)+wk(i,1)
     727        1539 :         cofum(i,j,5) = cofum(i,j,5)-wk(i,1)
     728             : 
     729        1539 :         wk(i,2) = (c(i,j,1)+wk(i,1))*(c(i,j,5)-wk(i,1))
     730        1539 :         wk(i,3) = sign(wk(i,1),c(i,j,1)+c(i,j,5))
     731        1539 :         if (wk(i,2) >= 0._r8) wk(i,3) = 0._r8
     732        1539 :         c(i,j,1) = c(i,j,1)+wk(i,1)+wk(i,3)
     733        1539 :         c(i,j,5) = c(i,j,5)-wk(i,1)+wk(i,3)
     734        1558 :         c(i,j,9) = c(i,j,9)-2._r8*wk(i,3)
     735             :       enddo ! i=1,nlon
     736             : !
     737             : ! zigm22:
     738          19 :     elseif (ncoef==4) then
     739         912 :       do j = 2,nlat-1
     740       73245 :         do i = 1,nlon
     741      289332 :           c(i,j,3) = c(i,j,3)+0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     742      361665 :             wkarray(i0+i*nint,j0+(j+1)*nint))
     743             :           c(i,j,7) = c(i,j,7)+0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     744       72333 :             wkarray(i0+i*nint,j0+(j-1)*nint))
     745             :           c(i,j,9) = c(i,j,9)-0.5_r8*(wkarray(i0+i*nint,j0+(j-1)*nint)+ &
     746       72333 :             2._r8*wkarray(i0+i*nint,j0+j*nint)+wkarray(i0+i*nint,j0+(j+1)*nint))
     747             : !
     748             : ! Unmodified:
     749       72333 :           cofum(i,j,3) = cofum(i,j,3)+0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     750       72333 :             wkarray(i0+i*nint,j0+(j+1)*nint))
     751             :           cofum(i,j,7) = cofum(i,j,7)+0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     752       72333 :             wkarray(i0+i*nint,j0+(j-1)*nint))
     753             :           cofum(i,j,9) = cofum(i,j,9)-0.5_r8*(wkarray(i0+i*nint,j0+(j-1)*nint)+ &
     754       73226 :             2._r8*wkarray(i0+i*nint,j0+j*nint)+wkarray(i0+i*nint,j0+(j+1)*nint))
     755             :         enddo ! i = 1,nlon
     756             :       enddo ! j = 2,nlat-1
     757             : !
     758             : ! Low latitude boundary condition:
     759        1558 :       j = 1
     760        1558 :       do i=1,nlon
     761        4617 :         c(i,j,3) = c(i,j,3)+0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     762        4617 :           wkarray(i0+i*nint,j0+(j+1)*nint))
     763             :         c(i,j,9) = c(i,j,9)-0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     764        1539 :                                 wkarray(i0+i*nint,j0+(j+1)*nint))
     765        1539 :         cofum(i,j,3) = cofum(i,j,3)+0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     766        1539 :                                 wkarray(i0+i*nint,j0+(j+1)*nint))
     767             :         cofum(i,j,9) = cofum(i,j,9)-0.5_r8*(wkarray(i0+i*nint,j0+j*nint)+ &
     768        1558 :                                 wkarray(i0+i*nint,j0+(j+1)*nint))
     769             :       enddo ! i=1,nlon
     770             :     endif ! ncoef
     771          76 :   end subroutine cnmmod
     772             : !--------------------------------------------------------------------
     773         114 :   subroutine edges(c,nlon,nlat)
     774             : !
     775             : ! Insert equatorial and polar boundary conditions in stencil c(nlon,nlat,9)
     776             : !
     777             : ! Args:
     778             :     integer,intent(in) :: nlon,nlat
     779             :     real(r8),intent(out) :: c(*)
     780             : !
     781             : ! Local:
     782             :     integer :: n,i, ndx
     783             : 
     784        1026 :     do n=1,8
     785       37658 :        do i=1,nlon
     786       36632 :         ndx = (n-1)*nlat*nlon + (nlat-1)*nlon + i
     787       37544 :         c(ndx) = 0._r8
     788             :       enddo
     789             :     enddo
     790        4693 :     do i=1,nlon
     791        4579 :       ndx = 8*nlat*nlon + (nlat-1)*nlon + i
     792        4693 :       c(ndx) = 1._r8
     793             :     enddo
     794         114 :   end subroutine edges
     795             : !--------------------------------------------------------------------
     796         114 :   subroutine divide(c,nlon,nlat,nlon0,cs,igrid)
     797             : !
     798             : ! Divide stencil C by cos(theta(i,j))
     799             : !
     800             : ! Args:
     801             :     integer,intent(in) :: nlon,nlat,nlon0,igrid
     802             :     real(r8),intent(in) :: cs(:)
     803             :     real(r8),intent(out) :: c(*)
     804             : !
     805             : ! Local:
     806             :     integer :: nint,j0,n,j,i, ndx
     807             : !
     808         114 :     nint = (nlon0-1)/(nlon-1)
     809         114 :     j0 = 1-nint
     810        1140 :     do n = 1,9
     811       25251 :       do j = 1,nlat-1
     812     1580553 :         do i = 1,nlon
     813     1555416 :           ndx = (n-1)*nlat*nlon + (j-1)*nlon + i
     814     1579527 :           c(ndx) = c(ndx)/(cs(j0+j*nint)*nint**2)
     815             :         enddo ! i = 1,nlon
     816             :       enddo ! j = 1,nlat-1
     817             :     enddo ! n = 1,9
     818             : !
     819         114 :     if (nint==1.and.igrid > 0) then
     820        1558 :       do i = 1,nlon
     821        1539 :         ndx = 9*nlat*nlon + i
     822        1558 :         c(ndx) = c(ndx)/cs(1)
     823             :       enddo ! i = 1,nlon
     824             :     endif
     825         114 :   end subroutine divide
     826             : !--------------------------------------------------------------------
     827          95 :   subroutine stenmd(inlon,inlat,c,phihm,pfrac)
     828             :   use edyn_params ,only: dtr
     829             :   use edyn_maggrid,only: dlatm
     830             : !
     831             : ! Modify stencil to set potential to heelis value within auroral circle.
     832             : !
     833             : ! Args:
     834             :     integer,intent(in) :: inlon,inlat
     835             :     real(r8),intent(inout) :: c(inlon,inlat,*)
     836             :     real(r8),dimension(nmlon0,nmlat0),intent(in) :: &
     837             :       phihm,  & ! heelis potential (from subs potm, flwv32)
     838             :       pfrac     ! fractional presence of dynamo (from sub colath)
     839             : !
     840             : ! Local:
     841             :     integer :: nint,i0,j0,i,j,n,jj
     842             :     real(r8) :: real8
     843             : !
     844             : ! Compute separation of grid points for this resolution:
     845          95 :     nint = (nmlon0-1)/(inlon-1)
     846          95 :     i0 = 1-nint
     847          95 :     j0 = 1-nint
     848             : !
     849             : ! If nint==1, then we are at the highest resolution.
     850             : ! Correct RHS, which is in c(10)
     851             : !
     852          95 :     if (nint==1) then
     853         950 :       do j=1,inlat
     854       76361 :         do i=1,inlon
     855      150822 :           c(i,j,10) = pfrac(i,j)*c(i,j,10)+(1._r8-pfrac(i,j))*c(i,j,9)* &
     856      227164 :             (dlatm/(10._r8*dtr))**2*phihm(i,j)
     857             :         enddo ! i=1,inlon
     858             :       enddo ! j=1,inlat
     859             :     endif
     860             : !
     861             : ! Modify stencil, c(i,j,n),n=1,9:
     862             : !
     863          95 :     real8 = dble(nint)
     864             :     if (nint==1) then
     865         950 :       do j=1,inlat
     866         931 :         jj = j0+j*nint
     867        8379 :         do n = 1,8
     868      611667 :           do i = 1,inlon
     869      603288 :             c(i,j,n) = c(i,j,n)*pfrac(i0+i*nint,jj)
     870      610736 :             cofum(i,j,n) = cofum(i,j,n)*pfrac(i0+i*nint,jj)
     871             :           enddo ! i = 1,inlon
     872             :         enddo ! n = 1,8
     873       76361 :         do i = 1,inlon
     874      301644 :           c(i,j,9) = c(i,j,9)*pfrac(i0+i*nint,jj)+ &
     875             :             (1._r8-pfrac(i0+i*nint,jj))*c(i,j,9)* &
     876      301644 :             (dlatm*real8/(10._r8*dtr))**2
     877           0 :           cofum(i,j,9) =cofum(i,j,9)*pfrac(i0+i*nint,jj)+ &
     878             :             (1._r8-pfrac(i0+i*nint,jj))*cofum(i,j,9)* &
     879       76342 :             (dlatm*real8/(10._r8*dtr))**2
     880             :         enddo ! i = 1,inlon
     881             :       enddo ! j=1,inlat
     882             :     else ! nint /= 1
     883        1007 :       do j=1,inlat
     884         931 :         jj = j0+j*nint
     885        8379 :         do n = 1,8
     886      221027 :           do i = 1,inlon
     887      220096 :             c(i,j,n) = c(i,j,n)*pfrac(i0+i*nint,jj)
     888             :           enddo ! i = 1,inlon
     889             :         enddo ! n = 1,8
     890       27588 :         do i = 1,inlon
     891      106324 :           c(i,j,9) = c(i,j,9)*pfrac(i0+i*nint,jj)+ &
     892             :             (1._r8-pfrac(i0+i*nint,jj))*c(i,j,9)* &
     893      133836 :             (dlatm*real8/(10._r8*dtr))**2
     894             :         enddo ! i = 1,inlon
     895             :       enddo ! j=1,inlat
     896             :     endif ! nint
     897          95 :   end subroutine stenmd
     898             : !--------------------------------------------------------------------
     899          19 :   subroutine solver(cofum,c0)
     900             :    use edyn_mudmod, only: mudmod
     901             :    use edyn_muh2cr, only: muh
     902             : !
     903             : ! Call mudpack to solve PDE. Solution is returned in rim:
     904             : !     real,dimension(nmlonp1,nmlat,2) :: rim
     905             : ! Mudpack solvers:
     906             : !   isolve = 0  org. mud v5.      (modified stencils neq direct solution)
     907             : !   isolve = 1  muh hybrid solver (no convergence => only as direct solver)
     908             : !   isolve = 2  modified mud      (residual calculated with unmodified stencils
     909             : !                                  same solution as with direct solver, if same
     910             : !                                  coefficient matrix is used)
     911             : ! Only isolve==2 is supported in edynamo.
     912             : !
     913             : ! Args:
     914             :     real(r8),dimension(nmlon0,nmlat0,9),intent(in) :: cofum
     915             :     real(r8),intent(in) :: c0(nmlon0,nmlat0,10)
     916             : !
     917             : ! Local:
     918             :     integer :: i,j,jntl,ier,isolve
     919             :     real(r8) :: l2norm
     920          38 :     real(r8),dimension(nmlon0,nmlat0)   :: ressolv
     921          38 :     real(r8),dimension(nmlon0,nmlat0,9) :: cofum_solv
     922             : 
     923             : ! Module data:
     924             : ! real,dimension(nmlonp1,nmlat,2) :: rim_glb ! pde solver output
     925             : 
     926          19 :     jntl = 0
     927          19 :     ier = 0
     928          19 :     isolve = 2
     929          19 :     call mudmod(rim_glb,phisolv,jntl,isolve,res_nlev,ier)
     930          19 :     if (ier < 0 ) then       ! not converged
     931           0 :       if (masterproc) write(iulog,*) 'solver: use muh direct solver'
     932           0 :       call muh(rim_glb,nmlon,nmlat,res_nlev,jntl)
     933             :     endif
     934             : 
     935          19 :     l2norm=0._r8
     936       76361 :     ressolv = 0.0_r8
     937         950 :     do j = 1,nmlat0
     938       75430 :       do i = 1,nmlon0-1
     939      744800 :         cofum_solv(i,j,:) = cofum(i,j,:)
     940             : !
     941             : ! fields: phisolv(0:nmlonp1,0:nmlat+1)       ! 2d solution/ electric potential
     942             : !
     943             :         ressolv(i,j) = (                    &
     944           0 :              cofum_solv(i,j,1)*phisolv(i+1,j)+   &
     945       74480 :              cofum_solv(i,j,2)*phisolv(i+1,j+1)+ &
     946       74480 :              cofum_solv(i,j,3)*phisolv(i,j+1)+   &
     947       74480 :              cofum_solv(i,j,4)*phisolv(i-1,j+1)+ &
     948             :              cofum_solv(i,j,5)*phisolv(i-1,j)+   &
     949       74480 :              cofum_solv(i,j,6)*phisolv(i-1,j-1)+ &
     950             :              cofum_solv(i,j,7)*phisolv(i,j-1)+   &
     951             :              cofum_solv(i,j,8)*phisolv(i+1,j-1)+ &
     952      223440 :              cofum_solv(i,j,9)*phisolv(i,j))
     953             : 
     954       74480 :         ressolv(i,j) = c0(i,j,10)-ressolv(i,j)
     955       75411 :         l2norm = l2norm + ressolv(i,j)*ressolv(i,j)
     956             :       enddo
     957             :     enddo
     958             : !   write(iulog,*) 'L2norm (global root task) = ',l2norm
     959             : 
     960          19 :   end subroutine solver
     961             : !--------------------------------------------------------------------
     962             : end module edyn_solve

Generated by: LCOV version 1.14