export_dense_output Subroutine

private subroutine export_dense_output(me, t_stop, ok)

Report the dense output points (at the fixed dense_output_step interval) within the last accepted step, that are before t_stop.

t_stop is either the end of the step, or the final time (or event time) if this is the last step. Points at t_stop are not reported here: if this is not the last step, they are reported for the next step (where they are at the start of the step), otherwise, the final point is reported separately.

If the interpolation fails (which is not expected, since the points are within the step), the error is raised, and ok is returned false so that the integration is not continued.

Type Bound

rk_variable_step_class

Arguments

Type IntentOptional Attributes Name
class(rk_variable_step_class), intent(inout) :: me
real(kind=wp), intent(in) :: t_stop

report points up to (but not including) this time

logical, intent(out) :: ok

false if there was an error (the integration should not continue)


Calls

proc~~export_dense_output~~CallsGraph proc~export_dense_output rk_variable_step_class%export_dense_output proc~interpolate rk_class%interpolate proc~export_dense_output->proc~interpolate report report proc~export_dense_output->report proc~dense_extra_stages rk_class%dense_extra_stages proc~interpolate->proc~dense_extra_stages proc~raise_exception rk_class%raise_exception proc~interpolate->proc~raise_exception

Called by

proc~~export_dense_output~~CalledByGraph proc~export_dense_output rk_variable_step_class%export_dense_output proc~export_step rk_variable_step_class%export_step proc~export_step->proc~export_dense_output proc~integrate_to_event_variable_step rk_variable_step_class%integrate_to_event_variable_step proc~integrate_to_event_variable_step->proc~export_dense_output proc~integrate_to_event_variable_step->proc~export_step proc~integrate_variable_step rk_variable_step_class%integrate_variable_step proc~integrate_variable_step->proc~export_dense_output proc~integrate_variable_step->proc~export_step program~rklib_example rklib_example program~rklib_example->proc~integrate_variable_step

Source Code

    subroutine export_dense_output(me,t_stop,ok)
        class(rk_variable_step_class),intent(inout) :: me
        real(wp),intent(in) :: t_stop !! report points up to (but not including) this time
        logical,intent(out) :: ok !! false if there was an error (the integration should not continue)

        real(wp) :: t !! time of the next dense output point
        real(wp) :: direction !! direction of integration (+1 or -1)
        real(wp),dimension(me%n) :: x !! state at `t`
        integer :: istatus !! status of the interpolation

        ok = .true.
        if (.not. me%dense_reporting .or. .not. me%dense_available) return

        direction = sign(1.0_wp, me%dense_h)
        do
            ! compute from the index (rather than accumulating) to avoid roundoff growth:
            t = me%dense_output_t0 + direction * real(me%dense_output_k+1,wp) * me%dense_output_step
            ! [the tolerance is less than the one in interpolate, so that a point deferred to
            !  the next step is still within the range of its dense output]
            if (direction*(t_stop - t) <= 2*spacing(abs(t_stop))) exit
            ! [check the status of this call, not the overall status, which may be
            !  set by an unrelated earlier error, e.g., from the user calling interpolate]
            call me%interpolate(t,x,istatus)
            if (me%stopped) return
            if (istatus /= RKLIB_ERROR_NONE) then
                ok = .false.
                return
            end if
            me%dense_output_k = me%dense_output_k + 1
            call me%report(t,x)
            if (me%stopped) return
        end do

    end subroutine export_dense_output