test_krdem2 Program

Uses

  • program~~test_krdem2~~UsesGraph program~test_krdem2 test_krdem2 iso_fortran_env iso_fortran_env program~test_krdem2->iso_fortran_env module~daskr_kinds daskr_kinds program~test_krdem2->module~daskr_kinds module~krdem2_m krdem2_m program~test_krdem2->module~krdem2_m module~daskr_kinds->iso_fortran_env module~krdem2_m->module~daskr_kinds

Test program for DASKR: intermittently stiff problem.

The initial value problem is:

with initial conditions:

The root function is:

The analytical solution is not known, but the zeros of are known to 15 figures.

If the errors are too large, or other difficulty occurs, a warning message is printed. To run the demonstration problem with full printing, set kprint = 3.


Calls

program~~test_krdem2~~CallsGraph program~test_krdem2 test_krdem2 daskr daskr program~test_krdem2->daskr

Variables

Type Attributes Name Initial
integer, parameter :: lrw = 100
integer, parameter :: liw = 100
integer :: idid
integer :: iout
integer :: ipar
integer :: jtype
integer :: kprint
integer :: lout
integer :: nerr
integer :: nre
integer :: nrea
integer :: nrte
integer :: nje
integer :: nst
integer :: kroot
integer :: info(20)
integer :: iwork(liw)
integer :: jroot(nrt)
real(kind=rk) :: errt
real(kind=rk) :: psdum
real(kind=rk) :: rpar
real(kind=rk) :: t
real(kind=rk) :: tout
real(kind=rk) :: tzero
real(kind=rk) :: atol(neq)
real(kind=rk) :: rtol(neq)
real(kind=rk) :: rwork(lrw)
real(kind=rk) :: y(neq)
real(kind=rk) :: yprime(neq)

Source Code

program test_krdem2
!! Test program for [[daskr]]: intermittently stiff problem.
!!
!! The initial value problem is:
!!
!! $$\begin{aligned}
!! y_1'(t) &= y_2 \\
!! y_2'(t) &= 100(1 - y_1^2)y_2 - y_1
!! \end{aligned}$$
!! 
!! with initial conditions:
!!      
!! $$\begin{aligned}
!! y_1(0)  &= 2, \quad y_2(0)  = 0, \quad 0 \le t \le 200 \\
!! y_1'(0) &= 0, \quad y_2'(0) = -2
!! \end{aligned}$$
!!
!! The root function is:
!!
!! $$ r_1(t, y, y') = y_1 $$
!!
!! The analytical solution is not known, but the zeros of \(y_1\) are known to 15 figures.
!!
!! If the errors are too large, or other difficulty occurs, a warning message is printed.
!! To run the demonstration problem with full printing, set `kprint = 3`.

   use iso_fortran_env, only: stdout => output_unit
   use daskr_kinds, only: rk, zero, one, two
   use krdem2_m, only: res, rt, jac, neq, nrt
   implicit none

   integer, parameter :: lrw = 100, liw = 100 ! @note: to be replaced by formula or alloc
   integer :: idid, iout, ipar, jtype, kprint, lout, nerr, nre, nrea, nrte, nje, nst, kroot
   integer :: info(20), iwork(liw), jroot(nrt)
   real(rk) :: errt, psdum, rpar, t, tout, tzero
   real(rk) :: atol(neq), rtol(neq), rwork(lrw), y(neq), yprime(neq)

   ! Set report options
   lout = stdout
   kprint = 3

   ! Initialize variables and set tolerance parameters.
   ! Note that INFO(2) is set to 1, indicating that RTOL and ATOL are arrays. Each entry of
   ! RTOL and ATOL must then be defined.
   nerr = 0
   idid = 0
   info = 0
   info(2) = 1
   rtol(:) = 1e-6_rk
   atol(1) = 1e-6_rk
   atol(2) = 1e-4_rk

   if (kprint >= 2) then
      write (lout, '(/, a, /)') 'DKRDEM-2: Test Program for DASKR'
      write (lout, '(a)') 'Van Der Pol oscillator'
      write (lout, '(a)') 'Problem is dY1/dT = Y2,  dY2/dT = 100*(1-Y1**2)*Y2 - Y1'
      write (lout, '(a)') '            Y1(0) = 2,    Y2(0) = 0'
      write (lout, '(a)') 'Root function is  R(T,Y,YP) = Y1'
      write (lout, '(a, e10.1, a, 2(e10.1))') 'RTOL =', rtol(1), ' ATOL =', atol(1:2)
   end if

   ! Note: JTYPE indicates the Jacobian type:
   ! JTYPE = 1 ==> Jacobian is dense and user-supplied
   ! JTYPE = 2 ==> Jacobian is dense and computed internally

   ! Loop over JTYPE = 1, 2.  Set remaining parameters and print JTYPE.
   do jtype = 1, 2

      ! Set INFO(1) = 0 to indicate start of a new problem
      ! Set INFO(5) = 2 - JTYPE to tell DDASKR the Jacobian type.
      info(1) = 0
      info(1) = 0
      info(5) = 2 - jtype
      t = zero
      y(1) = two
      y(2) = zero
      yprime(1) = zero
      yprime(2) = -two
      tout = 20.0_rk

      if (kprint > 2) then
         write (lout, '(/, 70("."), /, a, i2, /)') 'Solution with JTYPE =', jtype
      end if

      ! Call DDASKR in loop over TOUT values = 20, 40, ..., 200.
      do iout = 1, 10

         do
            call daskr(res, neq, t, y, yprime, tout, info, rtol, atol, idid, &
                       rwork, lrw, iwork, liw, rpar, ipar, jac, psdum, rt, nrt, jroot)

            ! Print Y1 and Y2.
            if (kprint > 2) then
               write (lout, '(a, e15.7, 5x, a, e15.7, 5x, a, e15.7)') &
                  'At t =', t, 'y1 =', y(1), 'y2 =', y(2)
            end if

            if (idid < 0) exit

            ! If no root found, increment TOUT and loop back.
            ! If a root was found, write results and check root location.
            ! Then return to DDASKR to continue the integration.
            if (idid /= 5) then
               tout = tout + 20.0_rk
               exit
            else

               if (kprint > 2) then
                  write (lout, '(/, a, e15.7, 2x, a, i3)') &
                     'Root found at t =', t, 'JROOT =', jroot(1)
               end if

               kroot = int(t/81.2_rk + 0.5_rk)
               tzero = 81.17237787055_rk + (kroot - 1)*81.41853556212_rk
               errt = t - tzero
               if (kprint > 2) then
                  write (lout, '(a, e12.4, /)') 'Error in t location of root is', errt
               end if

               if (errt >= one) then
                  nerr = nerr + 1
                  if (kprint >= 2) then
                     write (lout, '(/, a, /)') 'WARNING: Root error exceeds 1.0'
                  end if
               end if

            end if

         end do

         if (idid < 0) exit

      end do

      ! Problem complete. Print final statistics.
      if (idid < 0) nerr = nerr + 1
      nst = iwork(11)
      nre = iwork(12)
      nje = iwork(13)
      nrte = iwork(36)
      nrea = nre
      if (jtype == 2) nre = nre + neq*nje

      if (kprint >= 2) then
         write (lout, '(/, a)') 'Final statistics for this run:'
         write (lout, '(a, i5)') 'number of steps =', nst
         write (lout, '(a, i5)') 'number of Gs    =', nre
         write (lout, '(a, i5)') '(excluding Js)  =', nrea
         write (lout, '(a, i5)') 'number of Js    =', nje
         write (lout, '(a, i5)') 'number of Rs    =', nrte
      end if

   end do

   if (kprint >= 1) then
      write (lout, '(/, a, i3)') 'Number of errors encountered =', nerr
   end if

   if (nerr == 0) then
      stop '>>> Test passed. <<<'
   else
      error stop '>>> Test failed. <<<'
   end if

end program test_krdem2