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 | Intent | Optional | 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) |
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