get_sparsity_pattern Subroutine

public subroutine get_sparsity_pattern(me, irow, icol, linear_irow, linear_icol, linear_vals, maxgrp, ngrp)

Returns the sparsity pattern for the "forward-backward" Halo problem.

Type Bound

mission_type

Arguments

Type IntentOptional Attributes Name
class(mission_type), intent(inout) :: me
integer, intent(out), dimension(:), allocatable :: irow

sparsity pattern nonzero elements row indices

integer, intent(out), dimension(:), allocatable :: icol

sparsity pattern nonzero elements column indices

integer, intent(out), optional, dimension(:), allocatable :: linear_irow

linear sparsity pattern nonzero elements row indices

integer, intent(out), optional, dimension(:), allocatable :: linear_icol

linear sparsity pattern nonzero elements column indices

real(kind=wp), intent(out), optional, dimension(:), allocatable :: linear_vals

linear sparsity values (constant elements of the Jacobian)

integer, intent(out), optional :: maxgrp

DSM sparsity partition

integer, intent(out), optional, dimension(:), allocatable :: ngrp

DSM sparsity partition


Calls

proc~~get_sparsity_pattern~~CallsGraph proc~get_sparsity_pattern mission_type%get_sparsity_pattern proc~define_problem_size mission_type%define_problem_size proc~get_sparsity_pattern->proc~define_problem_size

Called by

proc~~get_sparsity_pattern~~CalledByGraph proc~get_sparsity_pattern mission_type%get_sparsity_pattern proc~initialize_the_mission mission_type%initialize_the_mission proc~initialize_the_mission->proc~get_sparsity_pattern proc~initialize_the_solver my_solver_type%initialize_the_solver proc~initialize_the_solver->proc~get_sparsity_pattern proc~initialize_the_solver->proc~initialize_the_mission proc~halo_solver_main halo_solver_main proc~halo_solver_main->proc~initialize_the_solver

Source Code

    subroutine get_sparsity_pattern(me,irow,icol,&
                                    linear_irow,linear_icol,linear_vals,&
                                    maxgrp,ngrp)

    implicit none

    class(mission_type),intent(inout) :: me
    integer,dimension(:),allocatable,intent(out)  :: irow  !! sparsity pattern nonzero elements row indices
    integer,dimension(:),allocatable,intent(out)  :: icol  !! sparsity pattern nonzero elements column indices
    integer,dimension(:),allocatable,intent(out),optional  :: linear_irow !! linear sparsity pattern
                                                                          !! nonzero elements row indices
    integer,dimension(:),allocatable,intent(out),optional  :: linear_icol !! linear sparsity pattern nonzero
                                                                          !! elements column indices
    real(wp),dimension(:),allocatable,intent(out),optional :: linear_vals !! linear sparsity values (constant
                                                                          !! elements of the Jacobian)
    integer,intent(out),optional                           :: maxgrp      !! DSM sparsity partition
    integer,dimension(:),allocatable,intent(out),optional  :: ngrp        !! DSM sparsity partition

    integer :: k,ii,jj,icol_start,irow_start
    integer :: n_nonzero  !! number of nonzero elements in the jacobian
    integer :: n  !! number of optimization variables
    integer :: m  !! number of functions
    integer :: iblock
    integer,dimension(:),allocatable :: cols_to_remove !! the columns from the full pattern to remove
    logical,dimension(:),allocatable :: mask
    integer,dimension(:),allocatable :: icol_tmp

    ! get the size of the full problem, we will first construct the full pattern:
    call me%define_problem_size(n=n, m=m, n_nonzero=n_nonzero, full_problem=.true.)

    !-------------------------------------
    ! test... dense pattern
    !-------------------------------------
    ! allocate(irow(n*m))
    ! allocate(icol(n*m))
    ! k = 0
    ! do ii = 1, n
    !     do jj = 1, m
    !         k = k + 1
    !         icol(k) = ii
    !         irow(k) = jj
    !     end do
    ! end do
    ! return
    !-------------------------------------

    allocate(irow(n_nonzero))
    allocate(icol(n_nonzero))

    k = 0
    do iblock = 1, me%n_revs*4 ! block loop

        ! see Figure 22b in Modern Fortran paper
        icol_start = (iblock-1)*7 + 1  ! [1-14, 8-21, 15-29, ...]
        irow_start = (iblock-1)*6 + 1  ! [1-6,  7-12, 13-18, ...]

        do ii = icol_start,icol_start+13
            do jj = irow_start,irow_start+5
                k = k + 1
                irow(k) = jj
                icol(k) = ii
            end do
        end do

    end do

    ! the full pattern was generated above.
    ! Here we just remove the columns (optimization variables) we don't need.

    allocate(cols_to_remove(0))
    if (me%fix_initial_time) &
        cols_to_remove = [cols_to_remove, 1]
    if (me%fix_initial_r) &
        cols_to_remove = [cols_to_remove, [2,3,4]]

    if (me%fix_ry_at_end_of_rev > 0) then
        ! remove Ry at end of specified rev
        ! e.g. rev 1 : SEG8 Ry (km) : column 31
        !
        ! patch point: [t rx ry rz vx vy vz]
        !                    ^^
        cols_to_remove = [cols_to_remove, me%fix_ry_at_end_of_rev*7*5 - 4]
    end if

    if (me%fix_final_ry_and_vx) &
        cols_to_remove = [cols_to_remove, [n-4,n-2]] ! last segment Ry & Vx

    if (size(cols_to_remove) > 0) then

        allocate(mask(size(icol)))
        mask = .true. ! keep these
        do k = 1, size(cols_to_remove)
            where(icol == cols_to_remove(k)) mask = .false. ! remove these
        end do

        ! remove the cols:
        irow = pack(irow, mask)
        icol = pack(icol, mask)

        ! decrement ones > the ones removed
        icol_tmp = icol ! so we have the original indices
        do k = 1, size(cols_to_remove)
            where (icol_tmp > cols_to_remove(k)) icol = icol - 1
        end do

        call me%define_problem_size(n_nonzero=n_nonzero)

    end if

    end subroutine get_sparsity_pattern