dsolss.inc Source File


Source Code

!----------------------------------------------------------------------------------------------------------------------------------!
!()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()!
!----------------------------------------------------------------------------------------------------------------------------------!
!>
!! This routine manages the solution of the linear system arising from
!! a chord iteration.  It is called if MITER .ne. 0.
!!
!! If MITER is 1 or 2, it calls CDRV to accomplish this.
!!
!! If MITER = 3 it updates the coefficient H*EL0 in the diagonal
!! matrix, and then computes the solution.
!! communication with DSOLSS uses the following variables:
!!
!! WK
!!
!! : real work space containing the inverse diagonal matrix if
!! MITER = 3 and the LU decomposition of the matrix otherwise.
!! Storage of matrix elements starts at WK(3).
!! WK also contains the following matrix-related data:
!!
!!         WK(1) = SQRT(UROUND) (not used here),
!!         WK(2) = HL0, the previous value of H*EL0, used if MITER = 3.
!!
!! IWK
!!
!! : integer work space for matrix-related data, assumed to
!! be equivalenced to WK.  In addition, WK(IPRSP) and IWK(IPISP)
!! are assumed to have identical locations.
!!
!! X
!!
!! : the right-hand side vector on input, and the solution vector
!! on output, of length N.
!!
!! TEM
!!
!! : vector of work space of length N, not used in this version.
!!
!! IERSL
!!
!! : output flag (in Common).
!!
!!            IERSL = 0  if no trouble occurred.
!!            IERSL = -1 if CDRV returned an error flag (MITER = 1 or 2).
!!                       This should never occur and is considered fatal.
!!            IERSL = 1  if a singular matrix arose with MITER = 3.
!!
!-----------------------------------------------------------------------
! This routine also uses other variables in global structures
!-----------------------------------------------------------------------
subroutine dsolss(Wk,Iwk,X,Tem)
!
real(kind=dp),intent(inout) :: Wk(*)
integer                     :: Iwk(*)
real(kind=dp),intent(inout) :: X(*)
real(kind=dp)               :: Tem(*)
!
real(kind=dp) :: di, hl0, phl0, r
integer :: i
   !
   dls1%iersl = 0
   select case (dls1%miter)
   case (3)
   !
      phl0 = Wk(2)
      hl0 = dls1%h*dls1%el0
      Wk(2) = hl0
      if ( hl0/=phl0 ) then
         r = hl0/phl0
         do i = 1, dls1%n
            di = 1.0D0 - r*(1.0D0-1.0D0/Wk(i+2))
            if ( abs(di)==0.0D0 ) then
               dls1%iersl = 1
               return
            else
               Wk(i+2) = 1.0D0/di
            endif
         enddo
      endif
   case default
      call cdrv(dls1%n,Iwk(dlss%ipr),Iwk(dlss%ipc),Iwk(dlss%ipic),Iwk(dlss%ipian),Iwk(dlss%ipjan),Wk(dlss%ipa),X,X,dlss%nsp,&
       & Iwk(dlss%ipisp),Wk(dlss%iprsp),dlss%iesp,4,dls1%iersl)
      if ( dls1%iersl/=0 ) dls1%iersl = -1
      return
   endselect

   do i = 1, dls1%n
      X(i) = Wk(i+2)*X(i)
   enddo

end subroutine dsolss