dusol.inc Source File


Source Code

!----------------------------------------------------------------------------------------------------------------------------------!
!()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()!
!----------------------------------------------------------------------------------------------------------------------------------!
!>
!! This routine solves the linear system A * x = b using only a call
!! to the user-supplied routine PSOL (no Krylov iteration).
!! If the norm of the right-hand side vector b is smaller than DELTA,
!! the vector X returned is X = b (if MNEWT = 0) or X = 0 otherwise.
!! PSOL is called with an LR argument of 0.
!!
!!### On entry
!!
!! NEQ
!!
!! : problem size, passed to F and PSOL (NEQ(1) = N).
!!
!! TN
!!
!! : current value of t.
!!
!! Y
!!
!! : array containing current dependent variable vector.
!!
!! SAVF
!!
!! : array containing current value of f(t,y).
!!
!! B
!!
!! : the right hand side of the system A*x = b.
!!
!! WGHT
!!
!! : the vector of length N containing the nonzero
!! elements of the diagonal scaling matrix.
!!
!! N
!!
!! : the order of the matrix A, and the lengths
!! of the vectors WGHT, B and X.
!!
!! DELTA
!!
!! : tolerance on residuals b - A*x in weighted RMS-norm.
!!
!! HL0
!!
!! : current value of (step size h) * (coefficient l0).
!!
!! MNEWT
!!
!! : Newton iteration counter (.ge. 0).
!!
!! WK
!!
!! : real work array used by PSOL.
!!
!! WP
!!
!! : real work array used by preconditioner PSOL.
!!
!! IWP
!!
!! : integer work array used by preconditioner PSOL.
!!
!!### On return
!!
!! X
!!
!! : the final computed approximation to the solution
!! of the system A*x = b.
!!
!! NPSL
!!
!! : the number of calls to PSOL.
!!
!! IFLAG
!!
!! : integer error flag:
!!
!!                0 means no trouble occurred.
!!                3 means there was a recoverable error in PSOL
!!                  caused by the preconditioner being out of date.
!!               -1 means there was a nonrecoverable error in PSOL.
!!
!-----------------------------------------------------------------------
subroutine dusol(Neq,Tn,Y,Savf,B,Wght,N,Delta,Hl0,Mnewt,psol,Npsl,X,Wp,Iwp,Wk,Iflag)
!
integer , dimension(*) :: Neq
real(kind=dp) :: Tn
real(kind=dp) , dimension(*) :: Y
real(kind=dp) , dimension(*) :: Savf
real(kind=dp) , dimension(*) :: B
real(kind=dp) , dimension(*) :: Wght
integer :: N
real(kind=dp) , intent(in) :: Delta
real(kind=dp) :: Hl0
integer , intent(in) :: Mnewt
external :: psol
!
real(kind=dp) :: bnrm
integer :: i , ier
integer , intent(out) :: Iflag , Npsl
integer , dimension(*) :: Iwp
real(kind=dp) , dimension(*) :: Wk , Wp , X
   !
   Iflag = 0
   Npsl = 0
   !-----------------------------------------------------------------------
   !  Test for an immediate return with X = 0 or X = b.
   !-----------------------------------------------------------------------
   bnrm = dvnorm(N,B,Wght)
   if ( bnrm>Delta ) then
   !  Make call to PSOL and copy result from B to X. -----------------------
      ier = 0
      call psol(Neq,Tn,Y,Savf,Wk,Hl0,Wp,Iwp,B,0,ier)
      Npsl = 1
      if ( ier/=0 ) then
   !-----------------------------------------------------------------------
   !  This block handles error returns forced by routine PSOL.
   !-----------------------------------------------------------------------
         if ( ier<0 ) Iflag = -1
         if ( ier>0 ) Iflag = 3
         return
      endif
   elseif ( Mnewt>0 ) then
      do i = 1 , N
         X(i) = 0.0D0
      enddo
      return
   else
      !X!call dcopy(N,B,1,X,1)
      X(1:N) = B(1:N)!X!
      return
   endif
   !X!call dcopy(N,B,1,X,1)
   X(1:N) = B(1:N)!X!
end subroutine dusol