LCOV - code coverage report
Current view: top level - num/test/src - test_vdpol.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 51.4 % 107 55
Test Date: 2025-05-08 18:23:42 Functions: 42.9 % 7 3

            Line data    Source code
       1              : module test_vdpol
       2              :    use num_def
       3              :    use num_lib
       4              :    use mtx_lib
       5              :    use mtx_def
       6              :    use test_int_support, only: i_nfcn, i_njac
       7              :    use utils_lib, only: mesa_error
       8              :    use bari_vdpol, only: vdpol_feval, vdpol_jeval, vdpol_init, vdpol_solut
       9              : 
      10              :    implicit none
      11              : 
      12              :    logical, parameter :: dbg = .false.
      13              : 
      14              :    integer :: cnt = 0
      15              : 
      16              : contains
      17              : 
      18           14 :    subroutine vdpol_fcn_blk_dble(n, caller_id, nvar, nz, x, h, y, f, lrpar, rpar, lipar, ipar, ierr)
      19              :       use const_def, only: dp
      20              :       integer, intent(in) :: n, caller_id, nvar, nz, lrpar, lipar
      21              :       real(dp), intent(in) :: x, h
      22              :       real(dp), intent(inout), pointer :: y(:)  ! (n)
      23              :       real(dp), intent(inout), pointer :: f(:)  ! (n) ! dy/dx
      24              :       integer, intent(inout), pointer :: ipar(:)  ! (lipar)
      25              :       real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
      26              :       integer, intent(out) :: ierr
      27              :       include 'formats'
      28            0 :       call vdpol_derivs(n, x, h, y, f, lrpar, rpar, lipar, ipar, ierr)
      29              :       !write(*,2) 'vdpol_fcn_blk_dble', ipar(i_nfcn), x
      30            0 :    end subroutine vdpol_fcn_blk_dble
      31              : 
      32        59826 :    subroutine vdpol_derivs(n, x, h, vars, dvars_dx, lrpar, rpar, lipar, ipar, ierr)
      33              :       integer, intent(in) :: n, lrpar, lipar
      34              :       real(dp), intent(in) :: x, h
      35              :       real(dp), intent(inout) :: vars(:)  ! (n)
      36              :       real(dp), intent(inout) :: dvars_dx(:)  ! (n)
      37              :       integer, intent(inout), pointer :: ipar(:)  ! (lipar)
      38              :       real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
      39       179478 :       real(dp) :: yprime(n)
      40              :       integer, intent(out) :: ierr
      41        59826 :       ierr = 0
      42        59826 :       ipar(i_nfcn) = ipar(i_nfcn) + 1
      43        59826 :       call vdpol_feval(n, x, vars, yprime, dvars_dx, ierr, rpar, ipar)
      44              : 
      45              :       if (dbg) then
      46              :          cnt = cnt + 1
      47              :          write (*, *) 'func cnt', cnt
      48              :          write (*, *) 'func n', n
      49              :          write (*, *) 'func x', x
      50              :          write (*, *) 'func y(1)', vars(1)
      51              :          write (*, *) 'func y(2)', vars(2)
      52              :          write (*, *) 'func f(1)', dvars_dx(1)
      53              :          write (*, *) 'func f(2)', dvars_dx(2)
      54              :          write (*, *)
      55              :          if (cnt == 5) stop 'vdpol_derivs'
      56              :       end if
      57              : 
      58        59826 :    end subroutine vdpol_derivs
      59              : 
      60            0 :    subroutine vdpol_jac_blk_dble(n, caller_id, nvar, nz, x, h, y, f, lblk1, dblk1, ublk1, lrpar, rpar, lipar, ipar, ierr)
      61              :       use const_def, only: dp
      62              :       integer, intent(in) :: n, caller_id, nvar, nz, lrpar, lipar
      63              :       real(dp), intent(in) :: x, h
      64              :       real(dp), intent(inout), pointer :: y(:)  ! (n)
      65              :       real(dp), intent(inout), pointer :: f(:)  ! (n) ! dy/dx
      66              :       real(dp), dimension(:), pointer, intent(inout) :: lblk1, dblk1, ublk1  ! =(nvar,nvar,nz)
      67              :       integer, intent(inout), pointer :: ipar(:)  ! (lipar)
      68              :       real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
      69              :       integer, intent(out) :: ierr
      70              : 
      71            0 :       real(dp), dimension(:, :, :), pointer :: lblk, dblk, ublk  ! =(nvar,nvar,nz)
      72              :       integer, parameter :: ld_dfdy = 2  ! for vdpol
      73            0 :       real(dp), target :: dfdy1(ld_dfdy*n)
      74              :       real(dp), pointer :: dfdy(:, :)
      75              :       include 'formats'
      76            0 :       ierr = 0
      77            0 :       dfdy(1:ld_dfdy, 1:n) => dfdy1(1:ld_dfdy*n)
      78            0 :       call vdpol_jacob(n, x, h, y, f, dfdy, ld_dfdy, lrpar, rpar, lipar, ipar, ierr)
      79              :       !write(*,2) 'vdpol_jac_blk_dble', ipar(i_nfcn), x
      80            0 :       if (ierr /= 0) return
      81            0 :       lblk(1:nvar, 1:nvar, 1:nz) => lblk1(1:nvar*nvar*nz)
      82            0 :       dblk(1:nvar, 1:nvar, 1:nz) => dblk1(1:nvar*nvar*nz)
      83            0 :       ublk(1:nvar, 1:nvar, 1:nz) => ublk1(1:nvar*nvar*nz)
      84              :       ! convert from square to block tridiagonal
      85            0 :       dblk(:, :, 1) = dfdy(:, :)
      86            0 :       ublk(:, :, 1) = 0
      87            0 :       lblk(:, :, 1) = 0
      88            0 :    end subroutine vdpol_jac_blk_dble
      89              : 
      90         8221 :    subroutine vdpol_jacob(n, x, h, y, f, dfdy, ld_dfdy, lrpar, rpar, lipar, ipar, ierr)
      91              :       integer, intent(in) :: n, ld_dfdy, lrpar, lipar
      92              :       real(dp), intent(in) :: x, h
      93              :       real(dp), intent(inout) :: y(:)
      94              :       real(dp), intent(inout) :: f(:), dfdy(:, :)
      95              :       integer, intent(inout), pointer :: ipar(:)  ! (lipar)
      96              :       real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
      97        24663 :       real(dp) :: yprime(n)
      98              :       integer, intent(out) :: ierr
      99         8221 :       ierr = 0
     100         8221 :       ipar(i_njac) = ipar(i_njac) + 1
     101         8221 :       call vdpol_jeval(ld_dfdy, n, x, y, yprime, dfdy, ierr, rpar, ipar)
     102         8221 :       if (ierr == 0) call vdpol_derivs(n, x, h, y, f, lrpar, rpar, lipar, ipar, ierr)
     103              : 
     104              :       if (.false.) then
     105              :          write (*, *) 'jac_fcn y(1)', y(1)
     106              :          write (*, *) 'jac_fcn y(2)', y(2)
     107              :          write (*, *) 'jac_fcn dfdy(1,1)', dfdy(1, 1)
     108              :          write (*, *) 'jac_fcn dfdy(1,2)', dfdy(1, 2)
     109              :          write (*, *) 'jac_fcn dfdy(2,1)', dfdy(2, 1)
     110              :          write (*, *) 'jac_fcn dfdy(2,2)', dfdy(2, 2)
     111              :          write (*, *)
     112              :       end if
     113              : 
     114         8221 :    end subroutine vdpol_jacob
     115              : 
     116            0 :    subroutine vdpol_sjac(n, x, h, y, f, nzmax, ia, ja, values, lrpar, rpar, lipar, ipar, ierr)
     117              :       ! sparse jacobian. format either compressed row or compressed column.
     118              :       use mtx_lib, only: dense_to_row_sparse_with_diag, dense_to_col_sparse_with_diag
     119              :       use test_int_support, only: ipar_sparse_format
     120              :       integer, intent(in) :: n, nzmax, lrpar, lipar
     121              :       real(dp), intent(in) :: x, h
     122              :       real(dp), intent(inout) :: y(:)  ! (n)
     123              :       real(dp), intent(inout) :: f(:)  ! (n) ! dy/dx
     124              :       integer, intent(inout) :: ia(:)  ! (n+1)
     125              :       integer, intent(inout) :: ja(:)  ! (nzmax)
     126              :       real(dp), intent(inout) :: values(:)  ! (nzmax)
     127              :       integer, intent(inout), pointer :: ipar(:)  ! (lipar)
     128              :       real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
     129              :       integer, intent(out) :: ierr  ! nonzero means terminate integration
     130            0 :       real(dp) :: dfdy(n, n)
     131              :       integer :: ld_dfdy, nz
     132            0 :       ld_dfdy = n
     133              :       ierr = 0
     134            0 :       call vdpol_jacob(n, x, h, y, f, dfdy, ld_dfdy, lrpar, rpar, lipar, ipar, ierr)
     135            0 :       if (ierr /= 0) return
     136            0 :       if (ipar(ipar_sparse_format) == 0) then
     137            0 :          call dense_to_row_sparse_with_diag(n, n, dfdy, nzmax, nz, ia, ja, values, ierr)
     138              :       else
     139            0 :          call dense_to_col_sparse_with_diag(n, n, dfdy, nzmax, nz, ia, ja, values, ierr)
     140              :       end if
     141            0 :    end subroutine vdpol_sjac
     142              : 
     143            0 :    subroutine vdpol_solout(nr, xold, x, n, y, rwork, iwork, interp_y, lrpar, rpar, lipar, ipar, irtrn)
     144              :       ! nr is the step number.
     145              :       ! x is the current x value; xold is the previous x value.
     146              :       ! y is the current y value.
     147              :       ! irtrn negative means terminate integration.
     148              :       ! rwork and iwork hold info for
     149              :       integer, intent(in) :: nr, n, lrpar, lipar
     150              :       real(dp), intent(in) :: xold, x
     151              :       real(dp), intent(inout) :: y(:)  ! (n)
     152              :       real(dp), intent(inout), target :: rwork(*)
     153              :       integer, intent(inout), target :: iwork(*)
     154              :       integer, intent(inout), pointer :: ipar(:)  ! (lipar)
     155              :       real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
     156              :       interface
     157              :          ! this subroutine can be called from your solout routine.
     158              :          ! it computes interpolated values for y components during the just completed step.
     159              :          real(dp) function interp_y(i, s, rwork, iwork, ierr)
     160              :             use const_def, only: dp
     161              :             implicit none
     162              :             integer, intent(in) :: i  ! result is interpolated approximation of y(i) at x=s.
     163              :             real(dp), intent(in) :: s  ! interpolation x value (between xold and x).
     164              :             real(dp), intent(inout), target :: rwork(*)
     165              :             integer, intent(inout), target :: iwork(*)
     166              :             integer, intent(out) :: ierr
     167              :          end function interp_y
     168              :       end interface
     169              :       integer, intent(out) :: irtrn
     170            0 :       real(dp) :: xout, y1, y2
     171              :       integer :: ierr
     172              : 
     173              :       if (dbg .and. nr > 450) stop
     174              : 
     175            0 :       ierr = 0
     176            0 :       irtrn = 0
     177            0 :       xout = rpar(1)
     178            0 :       if (nr == 1) then
     179            0 :          write (6, 99) x, y(1), y(2), nr - 1
     180            0 :          xout = 0.2d0
     181              :       else
     182            0 :          do
     183            0 :             if (x >= xout) then
     184            0 :                y1 = interp_y(1, xout, rwork, iwork, ierr)
     185            0 :                if (ierr /= 0) exit
     186            0 :                y2 = interp_y(2, xout, rwork, iwork, ierr)
     187            0 :                write (6, 99) xout, y1, y2, nr - 1
     188            0 :                if (ierr /= 0) exit
     189            0 :                xout = xout + 0.2d0
     190              :                cycle
     191              :             end if
     192            0 :             exit
     193              :          end do
     194              :       end if
     195            0 :       if (ierr /= 0) then
     196            0 :          write (*, *) 'problem with interp_y in vdpol_solout'
     197            0 :          irtrn = -1
     198              :       end if
     199            0 :       rpar(1) = xout
     200              : 99    format(1x, 'x =', f5.2, '    y =', 2e18.10, '    nstep =', i8)
     201            0 :    end subroutine vdpol_solout
     202              : 
     203           14 :    subroutine do_test_vdpol(which_solver, which_decsol, numerical_jacobian, show_all, quiet)
     204              :       use test_support, only: show_results, show_statistics, check_results
     205              :       use test_int_support, only: do_test_stiff_int
     206              :       integer, intent(in) :: which_solver, which_decsol
     207              :       logical, intent(in) :: numerical_jacobian, show_all, quiet
     208              : 
     209              :       integer, parameter :: nvar = 2, nz = 1
     210              :       integer, parameter :: n = nvar*nz  ! the number of variables in the "vdpol" system of ODEs
     211           98 :       real(dp), target :: y_ary(n), yprime(n), yexact(n)
     212              :       real(dp), pointer :: y(:)
     213              :       integer, parameter :: lrpar = 1, lipar = 3
     214              :       logical :: consis
     215              :       integer, parameter :: ndisc = 0
     216           84 :       real(dp) :: h0, t(0:ndisc + 1), atol(1), rtol(1)
     217              :       integer :: mujac, mljac, matrix_type_spec, ierr, imas, mlmas, mumas, m1, m2, itol, iout, nstep
     218           28 :       real(dp), target :: rpar_ary(lrpar)
     219              :       integer, target :: ipar_ary(lipar)
     220              :       real(dp), pointer :: rpar(:)
     221              :       integer, pointer :: ipar(:)
     222              :       integer :: caller_id, nvar_blk_dble, nz_blk_dble
     223           14 :       real(dp), dimension(:), pointer :: lblk, dblk, ublk  ! =(nvar,nvar,nz)
     224           14 :       real(dp), dimension(:), pointer :: uf_lblk, uf_dblk, uf_ublk  ! =(nvar,nvar,nz)
     225              : 
     226           14 :       rpar => rpar_ary
     227           14 :       ipar => ipar_ary
     228           14 :       y => y_ary
     229              : 
     230           14 :       if (.not. quiet) write (*, *) 'vdpol'
     231              : 
     232           14 :       nullify (lblk, dblk, ublk, uf_lblk, uf_dblk, uf_ublk)
     233           14 :       caller_id = 0
     234           14 :       nvar_blk_dble = 0
     235           14 :       nz_blk_dble = 0
     236              : 
     237           14 :       t(0) = 0
     238           14 :       t(1) = 2d0
     239              : 
     240           14 :       itol = 0  ! scalar tolerances
     241              :       rtol(1) = 1d-8
     242              :       atol(1) = 1d-8
     243              :       h0 = 1d-10  ! initial step size
     244              : 
     245              :       rtol(1) = 1d-6
     246              :       atol(1) = 1d-6
     247              :       h0 = 1d-8  ! initial step size
     248              : 
     249           14 :       rtol(1) = 1d-4
     250           14 :       atol(1) = 1d-4
     251           14 :       h0 = 1d-4  ! initial step size
     252              : 
     253           14 :       mljac = n  ! square matrix
     254           14 :       mujac = n
     255           14 :       matrix_type_spec = square_matrix_type
     256              : 
     257           14 :       imas = 0
     258           14 :       mlmas = 0
     259           14 :       mumas = 0
     260              : 
     261           14 :       m1 = 0
     262           14 :       m2 = 0
     263              : 
     264           14 :       if (show_all) then
     265            0 :          iout = 1
     266              :       else
     267           14 :          iout = 0
     268              :       end if
     269              : 
     270           56 :       ipar = 0
     271              : 
     272           14 :       call vdpol_init(n, y, yprime, consis)
     273           14 :       nstep = 0
     274              : 
     275              :       if (nvar_blk_dble == 0) then
     276              :          call do_test_stiff_int(which_solver, which_decsol, numerical_jacobian, &
     277              :                                 vdpol_derivs, vdpol_jacob, vdpol_sjac, vdpol_solout, iout, &
     278              :                                 null_fcn_blk_dble, null_jac_blk_dble, &
     279              :                                 caller_id, nvar_blk_dble, nz_blk_dble, lblk, dblk, ublk, uf_lblk, uf_dblk, uf_ublk, &
     280              :                                 n, ndisc, mljac, mujac, matrix_type_spec, null_mas, imas, mlmas, mumas, m1, m2, &
     281           14 :                                 t, rtol, atol, itol, h0, y, nstep, lrpar, rpar, lipar, ipar, quiet, ierr)
     282              :       else
     283              :          call do_test_stiff_int(which_solver, which_decsol, numerical_jacobian, &
     284              :                                 null_fcn, null_jac, null_sjac, vdpol_solout, iout, &
     285              :                                 vdpol_fcn_blk_dble, vdpol_jac_blk_dble, &
     286              :                                 caller_id, nvar_blk_dble, nz_blk_dble, lblk, dblk, ublk, uf_lblk, uf_dblk, uf_ublk, &
     287              :                                 n, ndisc, mljac, mujac, matrix_type_spec, null_mas, imas, mlmas, mumas, m1, m2, &
     288              :                                 t, rtol, atol, itol, h0, y, nstep, lrpar, rpar, lipar, ipar, quiet, ierr)
     289              :       end if
     290           14 :       if (ierr /= 0) then
     291            0 :          write (*, *) 'test_vdpol ierr', ierr
     292            0 :          call mesa_error(__FILE__, __LINE__)
     293              :       end if
     294              : 
     295           14 :       call vdpol_solut(n, 0d0, yexact)
     296              :       !call check_results(n,y,yexact,rtol(1)*2,ierr)
     297           14 :       if (ierr /= 0) then
     298            0 :          write (*, *) 'check results ierr', ierr
     299            0 :          call mesa_error(__FILE__, __LINE__)  ! do_test_vdpol
     300              :       end if
     301              : 
     302           14 :       if (quiet) return
     303              : 
     304           14 :       call show_results(n, y, yexact, show_all)
     305           14 :       call show_statistics(ipar(i_nfcn), ipar(i_njac), nstep, show_all)
     306              : 
     307           28 :    end subroutine do_test_vdpol
     308              : 
     309              : end module test_vdpol
        

Generated by: LCOV version 2.0-1