LCOV - code coverage report
Current view: top level - src - initialize.jl (source / functions) Hit Total Coverage
Test: on branch nothing Lines: 37 40 92.5 %
Date: 2025-02-26 15:13:49 Functions: 0 0 -

          Line data    Source code
       1             : """
       2             :     h = guessinitailstepsize(solver, dy)
       3             : 
       4             : Determine initial step size (evaluates `dy` once).
       5             : 
       6             : !!! warning "precondition"
       7             :     Attributes `y, dy, t, tfinal, tdir` are initialized.
       8             : 
       9             : Does one additional Euler step (one evaluation of `dy`), see
      10             : *Hairer. Solving Ordinary Differential Equations I. p. 169*.
      11             : 
      12             : Code adapted from
      13             : [JuliaDiffEq:ODE.jl](https://github.com/JuliaDiffEq/ODE.jl/blob/master/src/ODE.jl)
      14             : """
      15       12261 : function guessinitialstepsize(solver::Solver{N, T, S}, dy) where {N, T, S}
      16       12261 :     @massert issuccess(solver.state)
      17             : 
      18       12261 :     t, tfinal, tdir = solver.t, solver.tfinal, solver.tdir
      19             : 
      20       12400 :     normy = norm(solver.y)
      21       12261 :     τ = max.(solver.opts.rtol * normy, solver.opts.atol)
      22             :     # Note: This is not exactly scaled_norm() (Hairer: same norm).
      23             :     #       Should be good enough.
      24             : 
      25       12261 :     d0 = normy / τ
      26       12761 :     d1 = norm(solver.dy) / τ
      27             : 
      28             : 
      29       24383 :     h0 =
      30             :         if ((d0 < T(1e-5)) || (d1 < T(1e-5)))
      31         514 :             T(1e-6)
      32             :         else
      33       24008 :             h0 = (d0 / d1) * T(0.01)
      34             :         end
      35             : 
      36             :     # perform Euler step
      37             : 
      38       12261 :     fdy = guard(dy, solver)
      39             : 
      40       12261 :     y1 = solver.y + tdir * h0 * solver.dy
      41       24522 :     dy1 = fdy(t + tdir * h0, y1)
      42             : 
      43       12261 :     issuccess(fdy) || return tdir * h0 / 2 # leave to step size control
      44             : 
      45             :     # estimate second derivative
      46             : 
      47       12733 :     d2 = norm(dy1 - solver.dy) / (τ * h0)
      48             : 
      49       12261 :     h1 =
      50             :         if (max(d1, d2) <= T(1e-15))
      51         466 :             max(T(1e-6), T(1e-3) * h0)
      52             :         else
      53       24056 :             (T(0.01) / max(d1, d2)) ^ (1 / order1(solver.stepper))
      54             :         end
      55             : 
      56       12261 :     return tdir * min(min(100 * h0, h1), tdir * (tfinal - t))
      57             : end
      58             : 
      59       12261 : function initialize!(solver::Solver{N, T, S},
      60             :                      dy, t0::T,  t1::T, y0::SVector{N, T}) where {N, T, S}
      61       12261 :     solver.state = Ok
      62             : 
      63       12261 :     (t0 != t1) || @warn "initialized solver with t0=t1=$(t0)"
      64             : 
      65       12261 :     solver.t = t0
      66       12261 :     solver.tfinal = t1
      67       12261 :     solver.tdir = (t1 - t0) >= 0 ? +1 : -1
      68       12261 :     solver.y = y0
      69       12261 :     solver.nsteps = 0
      70       12261 :     solver.rejected = false
      71             : 
      72       12261 :     fdy = guard(dy, solver)
      73       24522 :     solver.dy = fdy(t0, y0)
      74             : 
      75       12261 :     if !issuccess(fdy)
      76           0 :         @warn "initialization failed: could not evaluate dy($(t0),$(y0))"
      77           0 :         return (solver.state = Failed)
      78             :     end
      79             : 
      80       12261 :     solver.ynew = solver.y
      81       12261 :     solver.dynew = solver.dy
      82       12261 :     solver.tnew = solver.t
      83             : 
      84       12261 :     hinit = solver.opts.h0
      85       24522 :     (hinit > 0) || (hinit = guessinitialstepsize(solver, dy))
      86             : 
      87       12261 :     solver.absh = abs(hinit)
      88           0 :     Ok
      89             : end

Generated by: LCOV version 1.16