dintdy.inc Source File


Source Code

!----------------------------------------------------------------------------------------------------------------------------------!
!()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()!
!----------------------------------------------------------------------------------------------------------------------------------!
!>
!!
!!### DESCRIPTION
!!  DINTDY computes interpolated values of the K-th derivative of the
!!  dependent variable vector y, and stores it in DKY.  This routine
!!  is called within the package with K = 0 and T = TOUT, but may
!!  also be called by the user for any K up to the current order.
!!  (See detailed instructions in the usage documentation.)
!!
!!  The computed values in DKY are gotten by interpolation using the
!!  Nordsieck history array YH.  This array corresponds uniquely to a
!!  vector-valued polynomial of degree NQCUR or less, and DKY is set
!!  to the K-th derivative of this polynomial at T.
!!  The formula for DKY is:
!!```text
!!               q
!!   DKY(i)  =  sum  c(j,K) * (T - tn)**(j-K) * h**(-j) * YH(i,j+1)
!!              j=K
!!```
!!  where  c(j,K) = j*(j-1)*...*(j-K+1), q = NQCUR, tn = TCUR, h = HCUR.
!!
!!  The quantities  nq = NQCUR, l = nq+1, N = NEQ, tn, and h are
!!  communicated by COMMON.  The above sum is done in reverse order.
!!  IFLAG is returned negative if either K or T is out of bounds.
!!
! ### SUBSIDIARY
! ### PURPOSE  Interpolate solution derivatives.
! ### TYPE      DOUBLE PRECISION (SINTDY-S, DINTDY-D)
! ### AUTHOR  Hindmarsh, Alan C., (LLNL)
! ### SEE ALSO  DLSODE
! ### ROUTINES CALLED  XERRWD
! ### COMMON BLOCKS    DLS001
! ### REVISION HISTORY  (YYMMDD)
!     19791129  DATE WRITTEN
!     19890501  Modified prologue to SLATEC/LDOC format.  (FNF)
!     19890503  Minor cosmetic changes.  (FNF)
!     19930809  Renamed to allow single/double precision versions. (ACH)
!     20010418  Reduced size of Common block /DLS001/. (ACH)
!     20031105  Restored 'own' variables to Common block /DLS001/, to
!               enable interrupt/restart feature. (ACH)
!     20050427  Corrected roundoff decrement in TP. (ACH)
!-----------------------------------------------------------------------
subroutine dintdy(T,K,Yh,Nyh,Dky,Iflag)
!
real(kind=dp)               :: T
integer                     :: K
integer,intent(in)          :: Nyh
real(kind=dp),intent(in)    :: Yh(Nyh,*)
real(kind=dp),intent(inout) :: Dky(*)
integer,intent(out)         :: Iflag
!
real(kind=dp)     :: c , r , s , tp
integer           :: i , ic , j , jb , jb2 , jj , jj1 , jp1
character(len=80) :: msg
   !
   Iflag = 0
   if ( K<0 .or. K>dls1%nq ) then
      msg = 'DINTDY-  K (=I1) illegal      '
      call xerrwd(msg,30,51,0,1,K,0,0,0.0D0,0.0D0)
      Iflag = -1
      return
   endif
   tp = dls1%tn - dls1%hu - 100.0D0*dls1%uround*sign(abs(dls1%tn)+abs(dls1%hu),dls1%hu)
   if ( (T-tp)*(T-dls1%tn)>0.0D0 ) then
      msg = 'DINTDY-  T (=R1) illegal      '
      call xerrwd(msg,30,52,0,0,0,0,1,T,0.0D0)
      msg = '      T not in interval TCUR - HU (= R1) to TCUR (=R2)      '
      call xerrwd(msg,60,52,0,0,0,0,2,tp,dls1%tn)
      Iflag = -2
      return
   endif
   !
   s = (T-dls1%tn)/dls1%h
   ic = 1

   if ( K/=0 ) then
      jj1 = dls1%l - K
      do jj = jj1 , dls1%nq
         ic = ic*jj
      enddo
   endif

   c = ic

   do i = 1 , dls1%n
      Dky(i) = c*Yh(i,dls1%l)
   enddo

   if ( K/=dls1%nq ) then
      jb2 = dls1%nq - K
      do jb = 1 , jb2
         j = dls1%nq - jb
         jp1 = j + 1
         ic = 1
         if ( K/=0 ) then
            jj1 = jp1 - K
            do jj = jj1 , j
               ic = ic*jj
            enddo
         endif
         c = ic
         do i = 1 , dls1%n
            Dky(i) = c*Yh(i,jp1) + s*Dky(i)
         enddo
      enddo
      if ( K==0 ) return
   endif

   r = dls1%h**(-K)

   do i = 1 , dls1%n
      Dky(i) = r*Dky(i)
   enddo

end subroutine dintdy