rkpar Subroutine

private subroutine rkpar(me, Ioptn, Numgr, Nparm, Icntyp, Mactrk, Iact, Actdif, Projct, Param, Fun, Ifun, Pttbl, Iptb, Indm, Vder, Pmat, Ncor, s, Itypm1, Itypm2, Unit, Tolcon, Rchin, Nstep, Error, Iphse, Iwork, Liwrk, Work, Lwrk, Confun, Vdern, Vders, Wvec, Parprj, Ifrkpr)

This subroutine computes a parameter vector parprj using fourth order runge kutta with h=-projct. h is negative since we want to approximate the parameters resulting from decreasing w by abs(h). if we do nstep steps then h=-projct/nstep.

Type Bound

conmax_solver

Arguments

Type IntentOptional Attributes Name
class(conmax_solver), intent(inout) :: me
integer :: Ioptn
integer, intent(in) :: Numgr
integer, intent(in) :: Nparm
integer :: Icntyp(Numgr)
integer :: Mactrk
integer :: Iact(Numgr)
real(kind=wp) :: Actdif(Numgr)
real(kind=wp) :: Projct
real(kind=wp) :: Param(Nparm)
real(kind=wp) :: Fun(Ifun)
integer, intent(in) :: Ifun
real(kind=wp) :: Pttbl(Iptb,Indm)
integer, intent(in) :: Iptb
integer, intent(in) :: Indm
real(kind=wp) :: Vder(Nparm)
real(kind=wp) :: Pmat(Nparm+1,Numgr)
integer :: Ncor
real(kind=wp) :: s
integer :: Itypm1
integer :: Itypm2
real(kind=wp) :: Unit
real(kind=wp) :: Tolcon
real(kind=wp) :: Rchin
integer :: Nstep
real(kind=wp) :: Error(Numgr+3)
integer :: Iphse
integer :: Iwork(Liwrk)
integer, intent(in) :: Liwrk
real(kind=wp) :: Work(Lwrk)
integer, intent(in) :: Lwrk
real(kind=wp) :: Confun(Numgr,Nparm+1)
real(kind=wp) :: Vdern(Nparm)
real(kind=wp) :: Vders(Nparm)
real(kind=wp) :: Wvec(Nparm)
real(kind=wp) :: Parprj(Nparm)
integer :: Ifrkpr

Calls

proc~~rkpar~~CallsGraph proc~rkpar conmax_solver%rkpar proc~corrct conmax_solver%corrct proc~rkpar->proc~corrct proc~iloc iloc proc~rkpar->proc~iloc proc~pmtst conmax_solver%pmtst proc~rkpar->proc~pmtst proc~wolfe wolfe proc~rkpar->proc~wolfe proc~corrct->proc~iloc proc~corrct->proc~wolfe proc~derst conmax_solver%derst proc~corrct->proc~derst proc~ercmp1 conmax_solver%ercmp1 proc~corrct->proc~ercmp1 proc~muller conmax_solver%muller proc~corrct->proc~muller proc~rchmod rchmod proc~corrct->proc~rchmod proc~searcr conmax_solver%searcr proc~corrct->proc~searcr proc~pmtst->proc~iloc proc~pmtst->proc~derst proc~wolfe->proc~iloc proc~conenr conenr proc~wolfe->proc~conenr proc~dotprd dotprd proc~wolfe->proc~dotprd proc~refwl refwl proc~wolfe->proc~refwl proc~conenr->proc~iloc proc~conenr->proc~dotprd proc~house house proc~conenr->proc~house fnset fnset proc~derst->fnset proc~ercmp1->proc~iloc proc~ercmp1->fnset proc~muller->proc~iloc proc~muller->proc~ercmp1 proc~searcr->proc~iloc proc~searcr->proc~ercmp1

Called by

proc~~rkpar~~CalledByGraph proc~rkpar conmax_solver%rkpar proc~rkcon conmax_solver%rkcon proc~rkcon->proc~rkpar proc~conmax conmax_solver%conmax proc~conmax->proc~rkcon

Source Code

    subroutine rkpar(me, Ioptn, Numgr, Nparm, Icntyp, Mactrk, Iact, Actdif, &
                     Projct, Param, Fun, Ifun, Pttbl, Iptb, Indm, Vder, Pmat, &
                     Ncor, s, Itypm1, Itypm2, Unit, Tolcon, Rchin, Nstep, &
                     Error, Iphse, Iwork, Liwrk, Work, Lwrk, Confun, Vdern, &
                     Vders, Wvec, Parprj, Ifrkpr)

        implicit none

        class(conmax_solver), intent(inout) :: me

        integer, intent(in)  :: Ifun
        integer, intent(in)  :: Indm
        integer, intent(in)  :: Iptb
        integer, intent(in)  :: Liwrk
        integer, intent(in) :: Lwrk
        integer, intent(in)  :: Nparm
        integer, intent(in)  :: Numgr
        integer  :: Ifrkpr
        integer  :: Ioptn
        integer  :: Iphse
        integer  :: Itypm1
        integer  :: Itypm2
        integer  :: Mactrk
        integer  :: Ncor
        integer  :: Nstep
        real(wp) :: Projct
        real(wp) :: Rchin
        real(wp) :: s
        real(wp) :: Tolcon
        real(wp) :: Unit
        real(wp) :: Actdif(Numgr)
        real(wp) :: Confun(Numgr, Nparm + 1)
        real(wp) :: Error(Numgr + 3)
        real(wp) :: Fun(Ifun)
        integer  :: Iact(Numgr)
        integer  :: Icntyp(Numgr)
        integer  :: Iwork(Liwrk)
        real(wp) :: Param(Nparm)
        real(wp) :: Parprj(Nparm)
        real(wp) :: Pmat(Nparm + 1, Numgr)
        real(wp) :: Pttbl(Iptb, Indm)
        real(wp) :: Vder(Nparm)
        real(wp) :: Vdern(Nparm)
        real(wp) :: Vders(Nparm)
        real(wp) :: Work(Lwrk)
        real(wp) :: Wvec(Nparm)

        real(wp) :: p6, wdist, proj1
        integer :: icorct, ilc06, ilc10, ilc11, ilc15, ilc21, ilc27, &
                   ilc30, ilc31, ilc33, ilc40, ilc48, j, jflag, nmaj, &
                   nmin, npar1, nstcnt

        ! SET MACHINE AND PRECISION DEPENDENT CONSTANTS FOR RKPAR.
        ilc06 = iloc(6, Nparm, Numgr)
        ilc10 = iloc(10, Nparm, Numgr)
        ilc11 = iloc(11, Nparm, Numgr)
        ilc15 = iloc(15, Nparm, Numgr)
        ilc21 = iloc(21, Nparm, Numgr)
        ilc27 = iloc(27, Nparm, Numgr)
        ilc30 = iloc(30, Nparm, Numgr)
        ilc31 = iloc(31, Nparm, Numgr)
        ilc33 = iloc(33, Nparm, Numgr)
        ilc40 = iloc(40, Nparm, Numgr)
        ilc48 = iloc(48, Nparm, Numgr)

        ! IFRKPR=0 IS A SIGNAL THAT THE SUBROUTINE OPERATED NORMALLY.
        Ifrkpr = 0
        proj1 = Projct/Nstep
        p6 = proj1/(two + two + two)
        npar1 = Nparm + 1
        nstcnt = 1
        ! PARPRJ WILL BE USED AS THE BASE POINT FOR THE NEXT RK STEP DURING THE
        ! OPERATION OF THIS SUBROUTINE.
        do j = 1, Nparm
            Parprj(j) = Param(j)
            Vdern(j) = Vder(j)
        end do

        main: block

            do
                ! NOTE THAT HERE H*VDERN IS THE K1 OF THE USUAL RUNGE-KUTTA FORMULAE.
                ! SET THE WORK VECTOR WVEC = PARPRJ-PROJ1*VDERN/2.0, THEN CALL PMTST
                ! AND WOLFE TO GET THE VECTOR (AGAIN CALLED VDERN) OF DERIVATIVE VALUES.
                ! THEN H*VDERN WILL BE THE K2 OF THE USUAL RUNGE-KUTTA FORMULAE.
                ! WE WILL ACCUMULATE K1/H + 2.0*K2/H + 2.0*K3/H IN VDERS, AND ADD IN
                ! K4/H AT THE END.
                do j = 1, Nparm
                    Vders(j) = Vdern(j)
                    Wvec(j) = Parprj(j) - proj1*Vdern(j)/two
                end do
                ! IF THERE ARE ANY STANDARD CONSTRAINTS, WE CORRECT BACK INTO THE
                ! FEASIBLE REGION IF POSSIBLE BEFORE CALLING PMTST.
                if (Itypm1 + Itypm2 > 0) then
                    call me%corrct(Ioptn, Nparm, Numgr, Fun, Ifun, Pttbl, Iptb, Indm, Icntyp, &
                                   Unit, Tolcon, Rchin, Error, Mactrk, Iact, Projct, Iphse, &
                                   Iwork, Liwrk, Work, Lwrk, Work(ilc27), Work(ilc11), &
                                   Work(ilc10), Pmat, Confun, Work(ilc48), Iwork(ilc21), &
                                   Wvec, icorct)
                    if (icorct > 0) exit main ! failure
                end if
                call me%pmtst(Ioptn, Numgr, Nparm, Wvec, Icntyp, Mactrk, Iact, Pttbl, Iptb, &
                              Indm, Actdif, Iphse, Iwork, Liwrk, Work, Lwrk, Confun, Pmat)
                call wolfe(Nparm, Mactrk, Pmat, 1, s, Ncor, Iwork(ilc15), Iwork, Liwrk, &
                           Work, Lwrk, Work(ilc33), Work(ilc06), Work(ilc31), &
                           Work(ilc30), Nparm, Numgr, Work(ilc40), Vdern, wdist, nmaj, &
                           nmin, jflag)
                ! IF WOLFE FAILED, SO WILL THIS SUBROUTINE.
                if (jflag <= 0) then
                    ! NOW VDERN REPRESENTS K2/H.  SET WVEC = PARPRJ-PROJ1*VDERN/2.0 AND
                    ! COMPUTE THE NEW VDERN, WHICH WILL REPRESENT K3/H.
                    do j = 1, Nparm
                        Vders(j) = Vders(j) + two*Vdern(j)
                        Wvec(j) = Parprj(j) - proj1*Vdern(j)/two
                    end do
                    ! IF THERE ARE ANY STANDARD CONSTRAINTS, WE CORRECT BACK INTO THE
                    ! FEASIBLE REGION IF POSSIBLE BEFORE CALLING PMTST.
                    if (Itypm1 + Itypm2 > 0) exit main ! failure
                    call me%corrct(Ioptn, Nparm, Numgr, Fun, Ifun, Pttbl, Iptb, Indm, Icntyp, &
                                   Unit, Tolcon, Rchin, Error, Mactrk, Iact, Projct, Iphse, &
                                   Iwork, Liwrk, Work, Lwrk, Work(ilc27), Work(ilc11), &
                                   Work(ilc10), Pmat, Confun, Work(ilc48), Iwork(ilc21), &
                                   Wvec, icorct)
                    if (icorct > 0) exit main ! failure
                end if

                call me%pmtst(Ioptn, Numgr, Nparm, Wvec, Icntyp, Mactrk, Iact, Pttbl, Iptb, &
                              Indm, Actdif, Iphse, Iwork, Liwrk, Work, Lwrk, Confun, Pmat)
                call wolfe(Nparm, Mactrk, Pmat, 1, s, Ncor, Iwork(ilc15), Iwork, Liwrk, &
                           Work, Lwrk, Work(ilc33), Work(ilc06), Work(ilc31), &
                           Work(ilc30), Nparm, Numgr, Work(ilc40), Vdern, wdist, nmaj, &
                           nmin, jflag)
                if (jflag > 0) exit main ! failure

                ! NOW VDERN REPRESENTS K3/H.  SET WVEC = PARPRJ-PROJ1*VDERN AND
                ! COMPUTE THE NEW VDERN, WHICH WILL REPRESENT K4/H.
                do j = 1, Nparm
                    Vders(j) = Vders(j) + two*Vdern(j)
                    Wvec(j) = Parprj(j) - proj1*Vdern(j)
                end do
                ! IF THERE ARE ANY STANDARD CONSTRAINTS, WE CORRECT BACK INTO THE
                ! FEASIBLE REGION IF POSSIBLE BEFORE CALLING PMTST.
                if (Itypm1 + Itypm2 > 0) then
                    call me%corrct(Ioptn, Nparm, Numgr, Fun, Ifun, Pttbl, Iptb, Indm, Icntyp, &
                                   Unit, Tolcon, Rchin, Error, Mactrk, Iact, Projct, Iphse, &
                                   Iwork, Liwrk, Work, Lwrk, Work(ilc27), Work(ilc11), &
                                   Work(ilc10), Pmat, Confun, Work(ilc48), Iwork(ilc21), &
                                   Wvec, icorct)
                    if (icorct > 0) exit main ! failure
                end if
                call me%pmtst(Ioptn, Numgr, Nparm, Wvec, Icntyp, Mactrk, Iact, Pttbl, Iptb, &
                              Indm, Actdif, Iphse, Iwork, Liwrk, Work, Lwrk, Confun, Pmat)
                call wolfe(Nparm, Mactrk, Pmat, 1, s, Ncor, Iwork(ilc15), Iwork, Liwrk, &
                           Work, Lwrk, Work(ilc33), Work(ilc06), Work(ilc31), &
                           Work(ilc30), Nparm, Numgr, Work(ilc40), Vdern, wdist, nmaj, &
                           nmin, jflag)
                if (jflag > 0) exit main ! failure

                ! NOW VDERN REPRESENTS K4/H, SO VDERS + VDERN WILL REPRESENT (K1 +
                ! 2.0*K2 + 2.0*K3 + K4)/H.  PUT THE NEW PARAMETER VECTOR IN PARPRJ.
                do j = 1, Nparm
                    Parprj(j) = Parprj(j) - p6*(Vders(j) + Vdern(j))
                end do
                if (nstcnt < Nstep) then
                    ! HERE NSTCNT < NSTEP AND WE SET UP FOR THE NEXT RK STEP.
                    ! AFTER WE HAVE DONE THIS STEP, VDERN WILL REPRESENT THE VDER1 FOR THE
                    ! NEXT STEP.  PARPRJ ALREADY IS THE BASE POINT FOR THE NEXT STEP.
                    nstcnt = nstcnt + 1
                    ! IF THERE ARE ANY STANDARD CONSTRAINTS, WE CORRECT BACK INTO THE
                    ! FEASIBLE REGION IF POSSIBLE BEFORE CALLING PMTST.
                    if (Itypm1 + Itypm2 > 0) then
                        call me%corrct(Ioptn, Nparm, Numgr, Fun, Ifun, Pttbl, Iptb, Indm, &
                                       Icntyp, Unit, Tolcon, Rchin, Error, Mactrk, Iact, &
                                       Projct, Iphse, Iwork, Liwrk, Work, Lwrk, Work(ilc27), &
                                       Work(ilc11), Work(ilc10), Pmat, Confun, Work(ilc48), &
                                       Iwork(ilc21), Parprj, icorct)
                        if (icorct > 0) exit main ! failure
                    end if
                    call me%pmtst(Ioptn, Numgr, Nparm, Parprj, Icntyp, Mactrk, Iact, Pttbl, &
                                  Iptb, Indm, Actdif, Iphse, Iwork, Liwrk, Work, Lwrk, Confun, &
                                  Pmat)
                    call wolfe(Nparm, Mactrk, Pmat, 1, s, Ncor, Iwork(ilc15), Iwork, Liwrk, &
                               Work, Lwrk, Work(ilc33), Work(ilc06), Work(ilc31), &
                               Work(ilc30), Nparm, Numgr, Work(ilc40), Vdern, wdist, &
                               nmaj, nmin, jflag)
                    if (jflag > 0) exit main ! failure
                else
                    exit ! done
                end if

            end do

            return ! success
        end block main

        ! failure
        Ifrkpr = 1
        ! WRITE(NWRIT,'(A)') '*****RKPAR HAS FAILED'

    end subroutine rkpar