example_web Program

Uses

  • program~~example_web~~UsesGraph program~example_web example_web module~daskr_kinds daskr_kinds program~example_web->module~daskr_kinds module~web_m web_m program~example_web->module~web_m module~web_par web_par program~example_web->module~web_par iso_fortran_env iso_fortran_env module~daskr_kinds->iso_fortran_env module~web_m->module~daskr_kinds module~web_par->module~daskr_kinds

Example program for DASKR: DAE system derived from -species interaction PDE in 2 dimensions.

This program solves a DAE system that arises from a system of partial differential equations. The PDE system is a food web population model, with predator-prey interaction and diffusion on the unit square in two dimensions. The dependent variable vector is

and the PDEs are as follows:

where the rate of formation of species is given by:

The number of species is , with the first being prey and the last being predators. The coefficients , , are:

The various scalar parameters are set in subroutine setpar.

The boundary conditions are of Neumann type (zero normal derivative) everywhere. A polynomial in and is used to set the initial conditions. The PDEs are discretized by central differencing on a mesh.

The root function is:

The DAE system is solved by DASKR with three different method options:

  1. Direct band method for the linear systems (internal Jacobian),
  2. Preconditioned Krylov method for the linear systems, without block-grouping in the reaction-based factor, and
  3. Preconditioned Krylov method for the linear systems, with block-grouping in the reaction-based factor.

In the Krylov cases, the preconditioner is the product of two factors:

  • The spatial factor uses a fixed number of Gauss-Seidel iterations based on the diffusion terms only.
  • The reaction-based factor is a block-diagonal matrix based on the partial derivatives of the interaction terms R only.

With block-grouping, only a subset of the blocks are computed. An integer flag, jpre, is set in the main program to specify whether the preconditioner is to use only one of the two factors or both, and in which order.

The reaction-based preconditioner factor is set up and solved in seven subroutines:

These routines are provided separately for general use on problems arising from reaction-transport systems.

Two output files are written: one with the problem description and performance statistics on and one with solution profiles at selected output times. The solution file is written only in the case of the direct method.

References:

  • Peter N. Brown and Alan C. Hindmarsh, "Reduced Storage Matrix Methods in Stiff ODE Systems", J. Appl. Math. & Comp., 31 (1989), pp. 40-91.
  • Peter N. Brown, Alan C. Hindmarsh, and Linda R. Petzold, "Using Krylov Methods in the Solution of Large-Scale Differential-Algebraic Systems", SIAM J. Sci. Comput., 15 (1994), pp. 1467-1488.
  • Peter N. Brown, Alan C. Hindmarsh, and Linda R. Petzold, "Consistent Initial Condition Calculation for Differential-Algebraic Systems", LLNL Report UCRL-JC-122175, August 1995; SIAM J. Sci. Comput., 19 (1998), pp. 1495 - 1512.

Calls

program~~example_web~~CallsGraph program~example_web example_web daskr daskr program~example_web->daskr dgset2 dgset2 program~example_web->dgset2 dmset2 dmset2 program~example_web->dmset2 proc~c1_average c1_average program~example_web->proc~c1_average proc~cinit cinit program~example_web->proc~cinit proc~out out program~example_web->proc~out proc~setid setid program~example_web->proc~setid proc~setpar setpar program~example_web->proc~setpar proc~f~2 f proc~cinit->proc~f~2 proc~to_string to_string proc~out->proc~to_string proc~rates rates proc~f~2->proc~rates

Variables

Type Attributes Name Initial
integer, parameter :: neq = ns*mx*my
integer, parameter :: maxm = max(mx, my)
integer, parameter :: lrw = 63+(3*ns*maxm+11)*neq+maxm
integer, parameter :: liw = 40+2*neq
integer :: idid
integer :: info(20)
integer :: iout
integer :: ipar(2)
integer :: iwork(liw)
integer :: jbg
integer :: jpre
integer :: jroot
integer :: leniw
integer :: lenrw
integer :: ldout
integer :: lcout
integer :: meth
integer :: ncfl
integer :: ncfn
integer :: ng
integer :: nli
integer :: nlidif
integer :: nni
integer :: nnidif
integer :: nout
integer :: npe
integer :: nps
integer :: nqu
integer :: nre
integer :: nrt
integer :: nrte
integer :: nst
integer :: nxg
integer :: nyg
real(kind=rk) :: atol
real(kind=rk) :: avlin
real(kind=rk) :: c1ave
real(kind=rk) :: cc(neq)
real(kind=rk) :: ccprime(neq)
real(kind=rk) :: hu
real(kind=rk) :: pred_ic
real(kind=rk) :: rpar(neq)
real(kind=rk) :: rtol
real(kind=rk) :: rwork(lrw)
real(kind=rk) :: t
real(kind=rk) :: tout

Source Code

program example_web
!! Example program for [[daskr]]:
!! DAE system derived from \(s\)-species interaction PDE in 2 dimensions.
!!
!! This program solves a DAE system that arises from a system of partial differential equations.
!! The PDE system is a food web population model, with predator-prey interaction and diffusion
!! on the unit square in two dimensions. The dependent variable vector is
!!
!! $$ c = [c_1, c_2 , ..., c_s] $$
!!
!! and the PDEs are as follows:
!!
!! $$\begin{aligned}
!! \frac{\partial c_i}{\partial t} &= d_i \left( \frac{\partial^2 c_i}{\partial x^2}
!!           + \frac{\partial^2 c_i}{\partial y^2} \right) + v_i \quad i=1,...,s/2 \\
!!                               0 &= d_i \left( \frac{\partial^2 c_i}{\partial x^2}
!!           + \frac{\partial^2 c_i}{\partial y^2} \right) + v_i \quad i=s/2+1,...,s
!! \end{aligned}$$
!!
!! where the rate of formation of species \(i\) is given by:
!!
!! $$ v_i(x,y,c) = c_i \left( b_i + \sum_{j=1}^s a_{ij} c_j \right) $$
!!
!! The number of species is \(s = 2 p\), with the first \(p\) being prey and the last \(p\)
!! being predators. The coefficients \(a_{ij}\), \(b_i\), \(d_i\) are:
!!
!! $$\begin{aligned}
!!   a_{ii} &= -a  \quad (\mathrm{all}\; i) \\
!!   a_{ij} &= -g  \quad (i \le p,\; j > p) \\
!!   a_{ij} &=  e  \quad (i > p,\; j \le p)
!! \end{aligned}$$
!!
!! $$\begin{aligned}
!!   b_i    &=  b (1 + \alpha x y + \beta \sin(4 \pi x) \sin(4 \pi y)) \quad (i \le p) \\
!!   b_i    &= -b (1 + \alpha x y + \beta \sin(4 \pi x) \sin(4 \pi y)) \quad (i > p)
!! \end{aligned}$$
!!
!! $$\begin{aligned}
!!   d_i    &= d_{prey} \quad (i \le p) \\
!!   d_i    &= d_{pred} \quad (i > p)
!! \end{aligned}$$
!!
!! The various scalar parameters are set in subroutine [[setpar]].
!!
!! The boundary conditions are of Neumann type (zero normal derivative) everywhere. A polynomial
!! in \(x\) and \(y\) is used to set the initial conditions. The PDEs are discretized by central
!! differencing on a \( M_x \times M_y\) mesh.
!!
!! The root function is:
!!
!! $$ r(t,c,c') = \iint c_1 dx dy - 20 $$
!!
!! The DAE system is solved by [[daskr]] with three different method options:
!!
!! 1. Direct band method for the linear systems (internal Jacobian),
!! 2. Preconditioned Krylov method for the linear systems, without block-grouping in the
!!    reaction-based factor, and
!! 3. Preconditioned Krylov method for the linear systems, with block-grouping in the
!!    reaction-based factor.
!!
!! In the Krylov cases, the preconditioner is the product of two factors:
!!
!! * The spatial factor uses a fixed number of Gauss-Seidel iterations based on the diffusion
!!   terms only.
!! * The reaction-based factor is a block-diagonal matrix based on the partial derivatives of
!!   the interaction terms `R` only.
!!
!! With block-grouping, only a subset of the \((s \times s)\) blocks are computed. An integer
!! flag, `jpre`, is set in the main program to specify whether the preconditioner is to use only
!! one of the two factors or both, and in which order.
!!
!! The reaction-based preconditioner factor is set up and solved in seven subroutines:
!!
!! * [[DMSET2]], [[DRBDJA]], [[DRBDPS]] in the case of no block-grouping, and
!! * [[DGSET2]], [[GSET1]], [[DRBGJA]], [[DRBGPS]]  in the case of block-grouping.
!!
!! These routines are provided separately for general use on problems arising from
!! reaction-transport systems.
!!
!! Two output files are written: one with the problem description and performance statistics on
!! and one with solution profiles at selected output times. The solution file is written only
!! in the case of the direct method.
!!
!! References:
!!
!! * Peter N. Brown and Alan C. Hindmarsh, "Reduced Storage Matrix Methods in Stiff ODE
!!   Systems", J. Appl. Math. & Comp., 31 (1989), pp. 40-91.
!! * Peter N. Brown, Alan C. Hindmarsh, and Linda R. Petzold, "Using Krylov Methods in the
!!   Solution of Large-Scale Differential-Algebraic Systems", SIAM J. Sci. Comput., 15 (1994),
!!   pp. 1467-1488.
!! * Peter N. Brown, Alan C. Hindmarsh, and Linda R. Petzold, "Consistent Initial Condition
!!   Calculation for Differential-Algebraic Systems", LLNL Report UCRL-JC-122175, August 1995;
!!   SIAM J. Sci. Comput., 19 (1998), pp. 1495 - 1512.

   use daskr_kinds, only: rk, zero, one
   use web_par, only: aa, alpha, bb, beta, dpred, dprey, ee, gg, mx, my, mxns, np, ns, setpar
   use web_m
   implicit none

   integer, parameter :: neq = ns*mx*my, maxm = max(mx, my)
   integer, parameter :: lrw = 63 + (3*ns*maxm + 11)*neq + maxm, liw = 40 + 2*neq
   integer :: idid, info(20), iout, ipar(2), iwork(liw), jbg, jpre, jroot, leniw, &
              lenrw, ldout, lcout, meth, ncfl, ncfn, ng, nli, nlidif, nni, nnidif, nout, &
              npe, nps, nqu, nre, nrt, nrte, nst, nxg, nyg
   real(rk) :: atol, avlin, c1ave, cc(neq), ccprime(neq), hu, pred_ic, rpar(neq), rtol, &
               rwork(lrw), t, tout

   ! Dimension solution arrays and work arrays.
   !
   ! When INFO(12) = 0, with INFO(5) = 0, INFO(6) = 1:
   !       The length required for RWORK is
   !       60 + 3*NRT + (2*ML+MU+11)*NEQ + 2*(NEQ/(ML+MU+1) + 1) .
   !       For MX = MY = (even number) and ML = MU = NS*MX, this length is
   !       60 + 3*NRT + (3*NS*MX + 11)*NEQ + MY .
   !       The length required for IWORK is  40 + 2*NEQ .
   !
   ! When INFO(12) = 1:
   !       The length required for RWORK is
   !       101 + 3*NRT + 19*NEQ + LENWP = 104 + 19*NEQ + NS*NS*NGRP .
   !       The length required for IWORK is
   !       40 + NEQ + LENIWP = 40 + NEQ + NS*NGRP .
   !
   ! The dimensions for the various arrays are set using parameters
   !       MAXN    which must be >= NEQ = NS*MX*MY,
   !       MAXM    which must be >= MAX(MX,MY).

   ! Open output files.
   open (newunit=ldout, file='./example/example_web_d.out', action="write", position="rewind")
   open (newunit=lcout, file='./example/example_web_c.out', action="write", position="rewind")

   ! Call SETPAR to set basic problem parameters.
   call setpar

   ! Set NRT = number of root functions.
   nrt = 1

   write (ldout, '(a, /)') 'DWEB: Example program for DASKR package'
   write (ldout, '(a, i4)') 'Food web problem with NS species, NS =', ns
   write (ldout, '(a, /)') 'Predator-prey interaction and diffusion on a 2-D square'
   write (ldout, '(a, e12.4, a, e12.4, a, e12.4)') &
      'Matrix parameters..  a =', aa, '  e =', ee, '  g =', gg
   write (ldout, '(21x, a, e12.4)') &
      'b =', bb
   write (ldout, '(a, e12.4, a, e12.4)') &
      'Diffusion coefficients: dprey =', dprey, '  dpred =', dpred
   write (ldout, '(a, e12.4, a, e12.4)') &
      'Rate parameters alphaa =', alpha, ' and beta =', beta
   write (ldout, '(a, 2i4, 5x, a, i7)') &
      'Mesh dimensions (MX,MY) =', mx, my, ' Total system size is NEQ =', neq
   write (ldout, '(a)') 'Root function is R(Y) = average(c1) - 20'

   ! Set the flat initial guess for the predators.
   pred_ic = 1e5_rk

   ! Set remaining method parameters for DDASKR.
   ! These include the INFO array and tolerances.
   info = 0

   ! Set INFO(11) = 1, indicating I.C. calculation requested.
   info(11) = 1

   ! Set INFO(14) = 1 to get the computed initial values.
   info(14) = 1

   ! Set INFO(15) = 1 to signal that a preconditioner setup routine is to be called in the
   ! Krylov case.
   info(15) = 1

   ! Set INFO(16) = 1 to get alternative error test (on the differential variables only).
   info(16) = 1

   ! Set the tolerances.
   rtol = 1e-5_rk
   atol = rtol

   write (ldout, '(/, a, e10.2, a, e10.2)') &
      'Tolerance parameters: RTOL =', rtol, '  ATOL =', atol
   write (ldout, '(a, i2, a)') &
      'Internal I.C. calculation flag INFO(11) =', info(11), '  (0 = off, 1 = on)'
   write (ldout, '(a, e10.2)') &
      'Predator I.C. guess =', pred_ic
   write (ldout, '(a, i2, a)') &
      'Alternate error test flag INFO(16) =', info(16), '  (0 = off, 1 = on)'

   ! Set NOUT = number of output times.
   nout = 18

   ! Loop over method options:
   ! METH = 0 means use INFO(12) = 0 (direct)
   ! METH = 1 means use INFO(12) = 1 (Krylov) without block-grouping in the reaction-based
   !          factor in the preconditioner.
   ! METH = 2 means use INFO(12) = 1 (Krylov) with block-grouping in the reaction-based factor
   !          in the preconditioner.
   ! A block-grouping flag JBG, communicated through IPAR, is set to 0 (no block-grouping) or
   ! 1 (use block-grouping) with METH = 1 or 2.
   ! Reset INFO(1) = 0 and INFO(11) = 1.

   do meth = 0, 2

      info(12) = min(meth, 1)
      info(1) = 0
      info(11) = 1
      jbg = meth - 1
      ipar(2) = jbg

      write (ldout, '(/, 80("."), //, a, i2, a)') &
         'Linear solver method flag INFO(12) =', info(12), '  (0 = direct, 1 = Krylov)'

      ! In the case of the direct method, set INFO(6) = 1 to signal a banded Jacobian, set
      ! IWORK(1) = IWORK(2) = MX*NS, the half-bandwidth, and call SETID to set the IWORK
      ! segment containing the block ID indicating the differential and algebraic components.
      if (info(12) == 0) then
         info(6) = 1
         iwork(1) = mxns
         iwork(2) = mxns
         call setid(mx, my, ns, np, 40, iwork)
         write (ldout, '(a, i4)') 'Difference-quotient banded Jacobian, half-bandwidths =', mxns
      end if

      ! In the case of the Krylov method, set and print various preconditioner parameters.
      if (info(12) == 1) then

         ! First set the preconditioner choice JPRE.
         !  JPRE = 1 means reaction-only (block-diagonal) factor A_R
         !  JPRE = 2 means spatial factor (Gauss-Seidel) A_S
         !  JPRE = 3 means A_S * A_R
         !  JPRE = 4 means A_R * A_S
         ! Use IPAR to communicate JPRE to the preconditioner solve routine.
         jpre = 3
         ipar(1) = jpre
         write (ldout, '(a, i3)') 'Preconditioner flag is JPRE =', jpre
         write (ldout, '(a)') &
            '(1 = reaction factor A_R, 2 = spatial factor A_S, 3 = A_S*A_R, 4 = A_R*A_S)'

         ! Call DMSET2 if JBG = 0, or DGSET2 if JBG = 1, to set the 2D mesh parameters and 
         ! block-grouping data, and the IWORK segment ID indicating the differential and 
         ! algebraic components.
         if (jbg == 0) then
            call dmset2(mx, my, ns, np, 40, iwork)
            write (ldout, '(a)') 'No block-grouping in reaction factor'
         end if
         if (jbg == 1) then
            nxg = 5
            nyg = 5
            ng = nxg*nyg
            call dgset2(mx, my, ns, np, nxg, nyg, 40, iwork)
            write (ldout, '(a)') 'Block-grouping in reaction factor'
            write (ldout, '(a, i5, a, i3, a, i3, a)') &
               'Number of groups =', ng, ' (NGX by NGY, NGX =', nxg, ',  NGY =', nyg, ')'
         end if
      end if

      ! Set the initial T and TOUT, and call CINIT to set initial values.
      t = zero
      tout = 1.0e-8_rk
      call cinit(cc, ccprime, pred_ic, rpar)

      nli = 0
      nni = 0

      ! Header for "ldout"
      write (ldout, '(/10x, a)') &
         't      <c1>  NSTEP   NRE   NNI   NLI   NPE    NQ          H    AVLIN'

      ! Loop over output times and call DASKR. At each output time, print average c1 value and
      ! performance data.
      ! The first call, with IOUT = 0, is to calculate initial values only.
      ! After the first call, reset INFO(11) = 0 and the initial TOUT.
      ! If a root was found, we flag this, and return to the DASKR call.
      do iout = 0, nout

         do
            call daskr(res, neq, t, cc, ccprime, tout, info, rtol, atol, &
                       idid, rwork, lrw, iwork, liw, rpar, ipar, jacrs, psolrs, &
                       rt, nrt, jroot)

            nst = iwork(11)
            nre = iwork(12)
            npe = iwork(13)
            nnidif = iwork(19) - nni
            nni = iwork(19)
            nlidif = iwork(20) - nli
            nli = iwork(20)
            nqu = iwork(8)
            hu = rwork(7)
            avlin = zero
            if (nnidif > 0) avlin = one*nlidif/nnidif

            if (meth == 0) then
               call out(t, cc, ns, mx, my, lcout)
            end if

            call c1_average(cc, c1ave)
            write (ldout, '(e11.5, f10.5, i7, i6, i6, i6, i6, i6, e11.2, f9.4)') &
               t, c1ave, nst, nre, nni, nli, npe, nqu, hu, avlin

            if (idid == 5) then
               write (ldout, '(15x, a, i3)') '*****   Root found, JROOT =', jroot
            else
               exit
            end if

         end do

         if (idid < 0) then
            write (ldout, '(//a, e12.4//)') 'Final time reached =', t
            exit
         end if

         if (tout > 0.9_rk) then
            tout = tout + one
         else
            tout = 10*tout
         end if

         if (iout == 0) then
            info(11) = 0
            tout = 1.0e-8_rk
            nli = 0
            nni = 0
         end if

      end do

      lenrw = iwork(18)
      leniw = iwork(17)
      nst = iwork(11)
      nre = iwork(12)
      npe = iwork(13)
      nni = iwork(19)
      nli = iwork(20)
      nps = iwork(21)
      if (nni > 0) avlin = real(nli)/real(nni)
      ncfn = iwork(15)
      ncfl = iwork(16)
      nrte = iwork(36)

      write (ldout, '(//a)') 'Final statistics for this run..'
      write (ldout, '(a, i8, a, i6)') 'RWORK size =', lenrw, '  IWORK size =', leniw
      write (ldout, '(a, i5)') 'Number of time steps              =', nst
      write (ldout, '(a, i5)') 'Number of residual evaluations    =', nre
      write (ldout, '(a, i5)') 'Number of root fn. evaluations    =', nrte
      write (ldout, '(a, i5)') 'Number of Jac. or prec. evals.    =', npe
      write (ldout, '(a, i5)') 'Number of preconditioner solves   =', nps
      write (ldout, '(a, i5)') 'Number of nonlinear iterations    =', nni
      write (ldout, '(a, i5)') 'Number of linear iterations       =', nli
      write (ldout, '(a, f8.4)') 'Average Krylov subspace dimension =', avlin
      write (ldout, '(i3, a, i5, a)') ncfn, ' nonlinear conv. failures,', ncfl, ' linear conv. failures'

   end do

   close (unit=ldout)
   close (unit=lcout)

end program example_web