LCOV - code coverage report
Current view: top level - mtx/private - pre_conditioners.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 34 0
Test Date: 2025-05-08 18:23:42 Functions: 0.0 % 3 0

            Line data    Source code
       1              : module pre_conditioners
       2              : 
       3              :       use const_def, only: dp
       4              : 
       5              :       implicit none
       6              : 
       7              :       private
       8              :       public :: compute_block_preconditioner, compute_band_preconditioner, compute_block_left_preconditioner
       9              : 
      10              :       contains
      11              : 
      12              :       !> Computes a pre-conditioning array for rows of a block triadiagonal matrix.
      13              :       !! Each row in the matrix can then be divided by the corresponding element in this array
      14              :       !! to form a usually better-conditioned matrix.
      15              :       !! This element is chosen to be the absolute value of the element in that row with the greatest magnitude.
      16              :       !!
      17              :       !! @params ublk The upper blocks. Shape is (nvars, nvars, nblocks-1).
      18              :       !! @params lblk The lower blocks. Shape is (nvars, nvars, nblocks-1).
      19              :       !! @params dblk The diagonal blocks. Shape is (nvars, nvars, nblocks).
      20              :       !! @params nblocks The number of blocks on the diagonal.
      21              :       !! @params nvars The width and height of each block (e.g. each block is nvars by nvars).
      22              :       !! @params pre_conditioner Pre-conditioning vector. Computed in this routine.
      23            0 :       subroutine compute_block_preconditioner(ublk, lblk, dblk, nblocks, nvar, pre_conditioner)
      24              :          real(dp), dimension(:,:,:), intent(in) :: ublk, lblk, dblk
      25              :          integer, intent(in) :: nblocks, nvar
      26              : 
      27              :          integer :: j, k
      28              : 
      29              :          real(dp), dimension(:,:), intent(out) :: pre_conditioner
      30              : 
      31            0 :          pre_conditioner = 0d0
      32            0 :          do j=1,nblocks
      33            0 :             do k=1,nvar
      34            0 :                pre_conditioner(k,j) = pre_conditioner(k,j) + sum(abs(dblk(k,:,j)))
      35              : 
      36            0 :                if (j < nblocks) then
      37            0 :                   pre_conditioner(k,j) = pre_conditioner(k,j) + sum(abs(ublk(k,:,j)))
      38              :                end if
      39              : 
      40            0 :                if (j > 1) then
      41            0 :                   pre_conditioner(k,j) = pre_conditioner(k,j) + sum(abs(lblk(k,:,j-1)))
      42              :                end if
      43              :             end do
      44              :          end do
      45              : 
      46            0 :       end subroutine compute_block_preconditioner
      47              : 
      48              :       !> Computes a pre-conditioning array for columns of a block triadiagonal matrix.
      49              :       !! Each column in the matrix can then be divided by the corresponding element in this array
      50              :       !! to form a usually better-conditioned matrix.
      51              :       !! This element is chosen to be the absolute value of the element in that column with the greatest magnitude.
      52              :       !! Note that the final answer to the linear solve must be divided element-wise by this pre-conditioner.
      53              :       !!
      54              :       !! @params ublk The upper blocks. Shape is (nvars, nvars, nblocks-1).
      55              :       !! @params lblk The lower blocks. Shape is (nvars, nvars, nblocks-1).
      56              :       !! @params dblk The diagonal blocks. Shape is (nvars, nvars, nblocks).
      57              :       !! @params nblocks The number of blocks on the diagonal.
      58              :       !! @params nvars The width and height of each block (e.g. each block is nvars by nvars).
      59              :       !! @params pre_conditioner Pre-conditioning vector. Computed in this routine.
      60            0 :       subroutine compute_block_left_preconditioner(ublk, lblk, dblk, nblocks, nvar, &
      61            0 :                                                    right_pre_conditioner, pre_conditioner)
      62              :          real(dp), dimension(:,:,:), intent(in) :: ublk, lblk, dblk
      63              :          real(dp), dimension(:,:), intent(in) :: right_pre_conditioner
      64              :          integer, intent(in) :: nblocks, nvar
      65              : 
      66              :          integer :: j, k, k2
      67              : 
      68              :          real(dp), dimension(:,:), intent(out) :: pre_conditioner
      69              : 
      70            0 :          pre_conditioner = 0d0
      71            0 :          do j=1,nblocks
      72            0 :             do k=1,nvar
      73            0 :                do k2=1,nvar
      74            0 :                   pre_conditioner(k,j) = pre_conditioner(k,j) + abs(dblk(k2,k,j) / right_pre_conditioner(k2,j))
      75              : 
      76            0 :                   if (j < nblocks) then
      77            0 :                      pre_conditioner(k,j) = pre_conditioner(k,j) + abs(lblk(k2,k,j) / right_pre_conditioner(k2,j+1))
      78              :                   end if
      79              : 
      80            0 :                   if (j > 1) then
      81            0 :                      pre_conditioner(k,j) = pre_conditioner(k,j) + abs(ublk(k2,k,j-1) / right_pre_conditioner(k2,j-1))
      82              :                   end if
      83              :                end do
      84              :             end do
      85              :          end do
      86              : 
      87            0 :       end subroutine compute_block_left_preconditioner
      88              : 
      89              :       !> Computes a pre-conditioning array for rows of a banded matrix.
      90              :       !! Each row in the matrix can then be divided by the corresponding element in this array
      91              :       !! to form a usually better-conditioned matrix.
      92              :       !! This element is chosen to be the absolute value of the element in that row with the greatest magnitude.
      93              :       !!
      94              :       !! @params n_upper_bands The number of bands above the diagonal.
      95              :       !! @params n_lower_bands The number of bands below the diagonal.
      96              :       !! @params bands Array of shape (n_upper_bands + n_lower_bands + 1, matrix_size). Stores the bands going from upper-most to lower-most, aligned so the first entry in each band has index 1.
      97              :       !! @params pre_conditioner Pre-conditioning vector. Computed in this routine.
      98            0 :       subroutine compute_band_preconditioner(matrix_size, n_upper_bands, n_lower_bands, bands, pre_conditioner)
      99              :          ! Inputs
     100              :          real(dp), dimension(:,:), intent(in) :: bands
     101              :          integer, intent(in) :: matrix_size, n_upper_bands, n_lower_bands
     102              : 
     103              :          ! Intermediates
     104              :          integer :: i, j, n_bands
     105              : 
     106              :          ! Outputs
     107              :          real(dp), dimension(:), intent(out) :: pre_conditioner
     108              : 
     109            0 :          n_bands = n_upper_bands + n_lower_bands + 1
     110              : 
     111            0 :          pre_conditioner = 0d0
     112              : 
     113              :          ! Upper bands
     114            0 :          do j=1,n_upper_bands
     115              :              ! The first upper band has index 1 in bands and runs 1...matrix_size-n_upper_bands.
     116            0 :             do i=1,matrix_size + j - n_upper_bands - 1
     117            0 :                pre_conditioner(i) = max(pre_conditioner(i), abs(bands(j,i)))
     118              :             end do
     119              :          end do
     120              : 
     121              :          ! Diagonal band
     122            0 :          do i=1,matrix_size
     123            0 :             pre_conditioner(i) = max(pre_conditioner(i), abs(bands(n_upper_bands + 1, i)))
     124              :          end do
     125              : 
     126              :          ! Lower bands
     127            0 :          do j=1,n_lower_bands
     128              :             ! The first lower band has index n_upper_bands+2 in bands and runs 1...matrix_size-1
     129            0 :             do i=j+1,matrix_size
     130            0 :                pre_conditioner(i) = max(pre_conditioner(i), abs(bands(j + n_upper_bands + 1, i-j)))
     131              :             end do
     132              :          end do
     133              : 
     134            0 :       end subroutine compute_band_preconditioner
     135              : 
     136              : end module pre_conditioners
        

Generated by: LCOV version 2.0-1