LCOV - code coverage report
Current view: top level - mtx/test/src - test_block_tridiagonal.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 80.8 % 120 97
Test Date: 2025-06-06 17:08:43 Functions: 100.0 % 8 8

            Line data    Source code
       1              : ! ***********************************************************************
       2              : !
       3              : !   Copyright (C) 2011  Bill Paxton & The MESA Team
       4              : !
       5              : !   This program is free software: you can redistribute it and/or modify
       6              : !   it under the terms of the GNU Lesser General Public License
       7              : !   as published by the Free Software Foundation,
       8              : !   either version 3 of the License, or (at your option) any later version.
       9              : !
      10              : !   This program is distributed in the hope that it will be useful,
      11              : !   but WITHOUT ANY WARRANTY; without even the implied warranty of
      12              : !   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
      13              : !   See the GNU Lesser General Public License for more details.
      14              : !
      15              : !   You should have received a copy of the GNU Lesser General Public License
      16              : !   along with this program. If not, see <https://www.gnu.org/licenses/>.
      17              : !
      18              : ! ***********************************************************************
      19              : 
      20              : module test_block_tri_dble
      21              : 
      22              :    use mtx_lib
      23              :    use mtx_def
      24              :    use const_def, only: dp
      25              :    use utils_lib, only: is_bad, mesa_error
      26              : 
      27              :    implicit none
      28              : 
      29              :    integer, parameter :: fltp = dp
      30              :    integer, parameter :: caller_id = 0
      31              : 
      32              : contains
      33              : 
      34            1 :    subroutine do_test_block_tri_dble
      35            1 :       call test_block(bcyclic_dble, .true.)
      36            1 :       call test_block(block_thomas_dble, .true.)
      37            1 :    end subroutine do_test_block_tri_dble
      38              : 
      39            2 :    subroutine test_block(which_decsol_option, for_release)
      40              : 
      41              :       integer, intent(in) :: which_decsol_option
      42              :       logical, intent(in) :: for_release
      43              : 
      44            2 :       real(fltp), pointer :: lblk1(:), dblk1(:), ublk1(:)  ! (nvar,nvar,nz)
      45            2 :       real(fltp), pointer :: lblk(:, :, :), dblk(:, :, :), ublk(:, :, :)  ! (nvar,nvar,nz)
      46            2 :       real(fltp), pointer :: x(:, :), xcorrect(:, :), brhs(:, :), work(:, :)  ! (nvar,nz)
      47            2 :       real(fltp), pointer :: x1(:)  ! =(nvar,nz)
      48            2 :       integer, pointer :: ipiv1(:)  ! =(nvar,nz)
      49            2 :       integer, pointer :: ipiv(:, :)  ! (nvar,nz)
      50              : 
      51            2 :       real(dp), pointer :: rpar_decsol(:)  ! (lrd)
      52            2 :       integer, pointer :: ipar_decsol(:)  ! (lid)
      53            2 :       real(fltp) :: time_factor, time_solve, time_refine, time_dealloc
      54              : 
      55              :       integer :: ierr, lid, lrd, nvar, nz
      56              :       character(len=255) :: fname, which_decsol_str
      57              : 
      58              :       include 'formats'
      59              : 
      60            2 :       ierr = 0
      61              : 
      62            2 :       call decsol_option_str(which_decsol_option, which_decsol_str, ierr)
      63            2 :       if (ierr /= 0) return
      64              : 
      65            1 :       if (for_release) then
      66            1 :          fname = 'block_tri.data'
      67              :       else
      68            0 :          fname = 'block_tri_12.data'
      69              :       end if
      70              : 
      71            1 :       time_factor = 0; time_solve = 0; time_refine = 0; time_dealloc = 0
      72              : 
      73            1 :       call read_testfile(fname)
      74              : 
      75            1 :       if (which_decsol_option == bcyclic_dble) then
      76            1 :          write (*, *) 'bcyclic_dble'
      77            1 :          call bcyclic_dble_work_sizes(nvar, nz, lrd, lid)
      78              :       else
      79            0 :          write (*, *) 'bad value for which_decsol_option in test_block'
      80            0 :          call mesa_error(__FILE__, __LINE__)
      81              :       end if
      82              : 
      83              :       allocate ( &
      84              :          rpar_decsol(lrd), ipar_decsol(lid), x1(nvar*nz), xcorrect(nvar, nz), &
      85            1 :          brhs(nvar, nz), ipiv1(nvar*nz), work(nvar, nz), stat=ierr)
      86            1 :       if (ierr /= 0) then
      87            0 :          write (*, *) 'failed in alloc'
      88            0 :          call mesa_error(__FILE__, __LINE__)
      89              :       end if
      90            1 :       ipiv(1:nvar, 1:nz) => ipiv1(1:nvar*nz)
      91            1 :       x(1:nvar, 1:nz) => x1(1:nvar*nz)
      92              : 
      93            1 :       call set_xcorrect
      94            1 :       call set_brhs(lblk, dblk, ublk)
      95              : 
      96            1 :       if (which_decsol_option == bcyclic_dble) then
      97            1 :          call solve_blocks(bcyclic_dble_decsolblk)
      98              :       else
      99            0 :          write (*, *) 'missing case for which_decsol_option', which_decsol_option
     100            0 :          call mesa_error(__FILE__, __LINE__)
     101              :       end if
     102              : 
     103            1 :       call check_x
     104              : 
     105            1 :       if (which_decsol_option == bcyclic_dble) then
     106            1 :          write (*, *) 'done bcyclic_dble'
     107            0 :       else if (which_decsol_option == block_thomas_dble) then
     108            0 :          write (*, *) 'done block_thomas_dble'
     109              :       end if
     110              : 
     111            1 :       write (*, *)
     112              : 
     113            0 :       deallocate (rpar_decsol, ipar_decsol, x1, xcorrect, work, &
     114            3 :                   brhs, ipiv1, lblk1, dblk1, ublk1)
     115              : 
     116              :    contains
     117              : 
     118            1 :       subroutine solve_blocks(decsolblk)
     119              :          interface
     120              :             include 'mtx_decsolblk_dble.dek'
     121              :          end interface
     122              : 
     123              :          integer :: iop, rep
     124              :          integer :: j, k
     125              : 
     126              :          include 'formats'
     127              : 
     128            1 :          iop = 0  ! factor A
     129              :          call decsolblk( &
     130            1 :             iop, caller_id, nvar, nz, lblk1, dblk1, ublk1, x1, ipiv1, lrd, rpar_decsol, lid, ipar_decsol, ierr)
     131            1 :          if (ierr /= 0) then
     132            0 :             write (*, *) 'decsolblk failed for factor'
     133            0 :             call mesa_error(__FILE__, __LINE__)
     134              :          end if
     135              : 
     136            2 :          do rep = 1, 1
     137              : 
     138            1 :             iop = 1  ! solve A*x = b
     139              : 
     140           21 :             do k = 1, nz
     141          521 :                do j = 1, nvar
     142          520 :                   x(j, k) = brhs(j, k)
     143              :                end do
     144              :             end do
     145              :             call decsolblk( &
     146            1 :                iop, caller_id, nvar, nz, lblk1, dblk1, ublk1, x1, ipiv1, lrd, rpar_decsol, lid, ipar_decsol, ierr)
     147            2 :             if (ierr /= 0) then
     148            0 :                write (*, *) 'decsolblk failed for solve'
     149            0 :                call mesa_error(__FILE__, __LINE__)
     150              :             end if
     151              : 
     152              :          end do
     153              : 
     154            1 :          iop = 2  ! deallocate
     155              :          call decsolblk( &
     156            1 :             iop, caller_id, nvar, nz, lblk1, dblk1, ublk1, x1, ipiv1, lrd, rpar_decsol, lid, ipar_decsol, ierr)
     157            1 :          if (ierr /= 0) then
     158            0 :             write (*, *) 'decsolblk failed for deallocate'
     159            0 :             call mesa_error(__FILE__, __LINE__)
     160              :          end if
     161              : 
     162            1 :       end subroutine solve_blocks
     163              : 
     164            2 :       subroutine read_testfile(fname)
     165              :          character(len=*), intent(in) :: fname
     166              :          integer :: iounit, ierr
     167              :          !write(*,*) 'reading ' // trim(fname)
     168            1 :          iounit = 33; ierr = 0
     169            1 :          open (unit=iounit, file=trim(fname), status='old', action='read', iostat=ierr)
     170            1 :          if (ierr /= 0) then
     171            0 :             write (*, *) 'failed to open '//trim(fname)
     172            0 :             call mesa_error(__FILE__, __LINE__)
     173              :          end if
     174              : 
     175            1 :          call mtx_read_block_tridiagonal(iounit, nvar, nz, lblk1, dblk1, ublk1, ierr)
     176              : 
     177            1 :          if (ierr /= 0) then
     178            0 :             write (*, *) 'failed to read '//trim(fname)
     179            0 :             call mesa_error(__FILE__, __LINE__)
     180              :          end if
     181            1 :          close (iounit)
     182              : 
     183            1 :          lblk(1:nvar, 1:nvar, 1:nz) => lblk1(1:nvar*nvar*nz)
     184            1 :          dblk(1:nvar, 1:nvar, 1:nz) => dblk1(1:nvar*nvar*nz)
     185            1 :          ublk(1:nvar, 1:nvar, 1:nz) => ublk1(1:nvar*nvar*nz)
     186              : 
     187              :          !return
     188            1 :          nz = 20
     189            1 :          write (*, *) 'testing with nvar,nz', nvar, nz
     190              : 
     191            1 :       end subroutine read_testfile
     192              : 
     193            1 :       subroutine set_brhs(lblk, dblk, ublk)
     194              :          real(fltp), pointer, dimension(:, :, :) :: lblk, dblk, ublk
     195              :          integer :: k, j
     196              :          include 'formats'
     197              :          ! set brhs = A*xcorrect
     198              : 
     199            1 :          call block_dble_mv(nvar, nz, lblk, dblk, ublk, xcorrect, brhs)
     200              : 
     201            1 :          return
     202              :          do k = 1, 2  !nz
     203              :             do j = 1, nvar
     204              :                if (brhs(j, k) /= 0) write (*, 3) 'brhs xcorrect', j, k, brhs(j, k), xcorrect(j, k)
     205              :             end do
     206              :          end do
     207              :          write (*, *) 'end set_brhs'
     208              :          stop
     209              :       end subroutine set_brhs
     210              : 
     211            1 :       subroutine check_x
     212            1 :          real(fltp) :: max_err, atol, rtol, avg_err
     213              :          integer :: i_max, j_max, i, j
     214              :          include 'formats'
     215            1 :          atol = 1d-4
     216            1 :          rtol = 1d-4
     217            1 :          call check1_x(avg_err, max_err, atol, rtol, i_max, j_max)
     218            1 :          i = i_max; j = j_max
     219            1 :          if (max_err > 1) then
     220            0 :             write (*, 3) 'BAD: err, x, xcorrect', i, j, max_err, x(i, j), xcorrect(i, j)
     221              :             !write(*,3) 'BAD: avg err, max err, x, xcorrect', i, j, avg_err, max_err, x(i,j), xcorrect(i,j)
     222              :          end if
     223            1 :       end subroutine check_x
     224              : 
     225            1 :       subroutine check1_x(avg_err, max_err, atol, rtol, i_max, j_max)
     226              :          real(fltp), intent(out) :: avg_err, max_err
     227              :          real(fltp), intent(in) ::  atol, rtol
     228              :          integer, intent(out) :: i_max, j_max
     229              :          integer :: i, j
     230            1 :          real(fltp) :: err_sum
     231            1 :          real(fltp) :: err
     232              :          include 'formats'
     233            1 :          max_err = 0; i_max = 0; j_max = 0; err_sum = 0
     234           21 :          do j = 1, nz
     235          521 :             do i = 1, nvar
     236          500 :                if (is_bad(x(i, j))) then
     237            0 :                   write (*, 3) 'x xcorrect', i, j, x(i, j), xcorrect(i, j)
     238            0 :                   stop 'check1_x'
     239              :                end if
     240          500 :                err = abs(x(i, j) - xcorrect(i, j))/(atol + rtol*max(abs(x(i, j)), abs(xcorrect(i, j))))
     241          500 :                err_sum = err_sum + err
     242          520 :                if (err > max_err) then
     243            4 :                   max_err = err; i_max = i; j_max = j
     244              :                end if
     245              :             end do
     246              :          end do
     247            1 :          avg_err = err_sum/(nz*nvar)
     248              :          !write(*,1) 'avg_err', avg_err
     249            1 :       end subroutine check1_x
     250              : 
     251            1 :       subroutine set_xcorrect
     252            1 :          real(fltp) :: cnt
     253              :          integer :: k, j
     254            1 :          cnt = 1d0
     255           21 :          do k = 1, nz
     256          521 :             do j = 1, nvar
     257          500 :                cnt = cnt + 1d-3
     258          520 :                xcorrect(j, k) = cnt
     259              :             end do
     260              :          end do
     261            1 :       end subroutine set_xcorrect
     262              : 
     263              :    end subroutine test_block
     264              : end module test_block_tri_dble
        

Generated by: LCOV version 2.0-1