this subroutine adjusts the yh
array on reduction of order,
and also when the order is increased for the stiff option (meth = 2).
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(dvode_t), | intent(inout) | :: | me | |||
real(kind=wp), | intent(inout) | :: | yh(ldyh,*) | |||
integer, | intent(in) | :: | ldyh |
leading dimension of |
||
integer, | intent(in) | :: | iord |
an integer flag used when meth = 2 to indicate an order increase (iord = +1) or an order decrease (iord = -1). |
subroutine dvjust(me,yh,ldyh,iord) class(dvode_t),intent(inout) :: me integer,intent(in) :: ldyh !! leading dimension of `yh` integer,intent(in) :: iord !! an integer flag used when meth = 2 to indicate an order !! increase (iord = +1) or an order decrease (iord = -1). real(wp),intent(inout) :: yh(ldyh,*) real(wp) :: alph0 , alph1 , hsum , prod , t1 , xi , xiold integer :: i , iback , j , jp1 , lp1 , nqm1 , nqm2 , nqp1 real(wp),parameter :: one = 1.0_wp if ( (me%dat%nq==2) .and. (iord/=1) ) return nqm1 = me%dat%nq - 1 nqm2 = me%dat%nq - 2 if ( me%dat%meth==2 ) then !----------------------------------------------------------------------- ! stiff option... ! check to see if the order is being increased or decreased. !----------------------------------------------------------------------- if ( iord==1 ) then ! order increase. ------------------------------------------------------ do j = 1 , me%dat%lmax me%dat%el(j) = zero enddo me%dat%el(3) = one alph0 = -one alph1 = one prod = one xiold = one hsum = me%dat%hscal if ( me%dat%nq/=1 ) then do j = 1 , nqm1 ! construct coefficients of x*x*(x+xi(1))*...*(x+xi(j)). --------------- jp1 = j + 1 hsum = hsum + me%dat%tau(jp1) xi = hsum/me%dat%hscal prod = prod*xi alph0 = alph0 - one/real(jp1,wp) alph1 = alph1 + one/xi do iback = 1 , jp1 i = (j+4) - iback me%dat%el(i) = me%dat%el(i)*xiold + me%dat%el(i-1) enddo xiold = xi enddo endif t1 = (-alph0-alph1)/prod ! load column l + 1 in yh array. --------------------------------------- lp1 = me%dat%l + 1 do i = 1 , me%dat%n yh(i,lp1) = t1*yh(i,me%dat%lmax) enddo ! add correction terms to yh array. ------------------------------------ nqp1 = me%dat%nq + 1 do j = 3 , nqp1 call daxpy(me%dat%n,me%dat%el(j),yh(1,lp1),1,yh(1,j),1) enddo else ! order decrease. ------------------------------------------------------ do j = 1 , me%dat%lmax me%dat%el(j) = zero enddo me%dat%el(3) = one hsum = zero do j = 1 , nqm2 ! construct coefficients of x*x*(x+xi(1))*...*(x+xi(j)). --------------- hsum = hsum + me%dat%tau(j) xi = hsum/me%dat%hscal jp1 = j + 1 do iback = 1 , jp1 i = (j+4) - iback me%dat%el(i) = me%dat%el(i)*xi + me%dat%el(i-1) enddo enddo ! subtract correction terms from yh array. ----------------------------- do j = 3 , me%dat%nq do i = 1 , me%dat%n yh(i,j) = yh(i,j) - yh(i,me%dat%l)*me%dat%el(j) enddo enddo return endif !----------------------------------------------------------------------- ! nonstiff option... ! check to see if the order is being increased or decreased. !----------------------------------------------------------------------- else if ( iord==1 ) then ! order increase. ------------------------------------------------------ ! zero out next column in yh array. ------------------------------------ lp1 = me%dat%l + 1 do i = 1 , me%dat%n yh(i,lp1) = zero enddo return else ! order decrease. ------------------------------------------------------ do j = 1 , me%dat%lmax me%dat%el(j) = zero enddo me%dat%el(2) = one hsum = zero do j = 1 , nqm2 ! construct coefficients of x*(x+xi(1))*...*(x+xi(j)). ----------------- hsum = hsum + me%dat%tau(j) xi = hsum/me%dat%hscal jp1 = j + 1 do iback = 1 , jp1 i = (j+3) - iback me%dat%el(i) = me%dat%el(i)*xi + me%dat%el(i-1) enddo enddo ! construct coefficients of integrated polynomial. --------------------- do j = 2 , nqm1 me%dat%el(j+1) = real(me%dat%nq,wp)*me%dat%el(j)/real(j,wp) enddo ! subtract correction terms from yh array. ----------------------------- do j = 3 , me%dat%nq do i = 1 , me%dat%n yh(i,j) = yh(i,j) - yh(i,me%dat%l)*me%dat%el(j) enddo enddo return endif end subroutine dvjust