@@ -372,36 +372,38 @@ end
372
372
373
373
function simulateSegment! (m:: SimulationModel{FloatType,TimeType} , algorithm= missing ; kwargs... ) where {FloatType,TimeType}
374
374
solution = nothing
375
+ options = m. options
375
376
376
377
sizesOfLinearEquationSystems = Int[length (leq. b) for leq in m. linearEquations]
377
378
378
379
# Define problem and callbacks based on algorithm and model type
379
- interval = m . options. interval
380
- if abs (m . options. stopTime - m . options. startTime) <= 0
380
+ interval = options. interval
381
+ if abs (options. stopTime - options. startTime) <= 0
381
382
interval = 1.0
382
- tspan2 = [m . options. startTime]
383
- elseif abs (m . options. interval) < abs (m . options. stopTime- m . options. startTime)
383
+ tspan2 = [options. startTime]
384
+ elseif abs (options. interval) < abs (options. stopTime- options. startTime)
384
385
if m. nsegments == 1
385
- tspan2 = m . options. startTime: interval: m . options. stopTime
386
+ tspan2 = options. startTime: interval: options. stopTime
386
387
else
387
- i = ceil ( (m . options. startTime - m . options. startTimeFirstSegment)/ interval )
388
- tnext = m . options. startTimeFirstSegment + i* interval
389
- tspan2 = tnext: interval: m . options. stopTime
390
- if tspan2[1 ] > m . options. startTime
391
- tspan2 = [m . options. startTime, tspan2... ]
388
+ i = ceil ( (options. startTime - options. startTimeFirstSegment)/ interval )
389
+ tnext = options. startTimeFirstSegment + i* interval
390
+ tspan2 = tnext: interval: options. stopTime
391
+ if tspan2[1 ] > options. startTime
392
+ tspan2 = [options. startTime, tspan2... ]
392
393
end
393
394
end
394
- if tspan2[end ] < m . options. stopTime
395
- tspan2 = [tspan2... , m . options. stopTime]
395
+ if tspan2[end ] < options. stopTime
396
+ tspan2 = [tspan2... , options. stopTime]
396
397
end
397
398
else
398
- tspan2 = [m . options. startTime, m . options. stopTime]
399
+ tspan2 = [options. startTime, options. stopTime]
399
400
end
400
- tspan = (m . options. startTime, m . options. stopTime)
401
+ tspan = (options. startTime, options. stopTime)
401
402
402
403
eh = m. eventHandler
403
- m. odeMode = true
404
- m. solve_leq = true
404
+ for leq in m. linearEquations
405
+ leq. odeMode = true
406
+ end
405
407
if typeof (algorithm) <: DifferentialEquations.DiffEqBase.AbstractDAEAlgorithm
406
408
# DAE integrator
407
409
m. odeIntegrator = false
@@ -411,27 +413,65 @@ function simulateSegment!(m::SimulationModel{FloatType,TimeType}, algorithm=miss
411
413
TimerOutputs. @timeit m. timer " DifferentialEquations.DAEProblem" problem = DifferentialEquations. DAEProblem {true} (DAEresidualsForODE!, m. der_x, m. x_init, tspan, m, differential_vars = differential_vars)
412
414
empty! (m. daeCopyInfo)
413
415
if length (sizesOfLinearEquationSystems) > 0 && maximum (sizesOfLinearEquationSystems) >= options. nlinearMinForDAE
414
- # Prepare data structure to efficiently perform copy operations for DAE integrator
416
+ # Prepare data structure to efficiently perform copy operations for DAE integrator
415
417
x_info = m. equationInfo. x_info
416
418
der_x_dict = m. equationInfo. der_x_dict
417
419
der_x_names = keys (der_x_dict)
420
+ daeMode = false
418
421
for (ileq,leq) in enumerate (m. linearEquations)
419
- if sizesOfLinearEquationSystems[ileq] >= options. nlinearMinForDAE &&
420
- length (intersect (leq. x_names,der_x_names)) == length (leq. x_names)
421
- # Linear equation shall be solved by DAE and all unknowns of the linear equation system are DAE derivatives
422
- leq. odeMode = false
423
- m. odeMode = false
424
- leq_copy = LinearEquationsCopyInfoForDAEMode (ileq)
425
- for ix in 1 : length (leq. x_names)
426
- x_name = leq. x_names[ix]
427
- x_length = leq. x_lengths[ix]
428
- x_info_i = x_info[ der_x_dict[x_name] ]
429
- @assert (x_length == x_info_i. length)
430
- startIndex = x_info_i. startIndex
431
- endIndex = startIndex + x_length - 1
432
- append! (leq_copy. index, startIndex: endIndex)
422
+ if sizesOfLinearEquationSystems[ileq] >= options. nlinearMinForDAE
423
+ answer = leq. x_names .∈ Ref (der_x_names)
424
+ daeMode = true
425
+ for (index, val) in enumerate (answer)
426
+ if ! val && leq. x_lengths[index] > 0
427
+ daeMode = false
428
+ break
429
+ end
430
+ end
431
+
432
+ if daeMode
433
+ # Linear equation shall be solved by DAE and all unknowns of the linear equation system are DAE derivatives
434
+ if eh. nz > 0
435
+ leq. odeMode = true
436
+ daeMode = false
437
+ if options. log
438
+ println (" No DAE mode for equation system $ileq because $(eh. nz) crossing function(s) defined (see issue #686 of DifferentialEquations.jl)" )
439
+ end
440
+
441
+ else
442
+ leq. odeMode = false
443
+ leq_copy = LinearEquationsCopyInfoForDAEMode (ileq)
444
+ for ix in 1 : length (leq. x_names)
445
+ x_length = leq. x_lengths[ix]
446
+ if x_length > 0
447
+ x_name = leq. x_names[ix]
448
+ x_info_i = x_info[ der_x_dict[x_name] ]
449
+ @assert (x_length == x_info_i. length)
450
+ startIndex = x_info_i. startIndex
451
+ endIndex = startIndex + x_length - 1
452
+ append! (leq_copy. index, startIndex: endIndex)
453
+ end
454
+ end
455
+ push! (m. daeCopyInfo, leq_copy)
456
+ end
457
+ else
458
+ if options. log
459
+ unknownsThatAreNoStateDerivatives = " "
460
+ first = true
461
+ for (index, val) in enumerate (answer)
462
+ if ! val && leq. x_lengths[index] > 0
463
+ if first
464
+ first = false
465
+ unknownsThatAreNoStateDerivatives = " \" " * leq. x_names[index] * " \" "
466
+ else
467
+ unknownsThatAreNoStateDerivatives *= " ,\" " * leq. x_names[index] * " \" "
468
+ end
469
+ end
470
+ end
471
+ println (" No DAE mode for equation system $ileq because the unknowns $unknownsThatAreNoStateDerivatives are no state derivatives!" )
472
+ end
473
+ leq. odeMode = true
433
474
end
434
- push! (m. daeCopyInfo, leq_copy)
435
475
else
436
476
leq. odeMode = true
437
477
end
@@ -442,6 +482,21 @@ function simulateSegment!(m::SimulationModel{FloatType,TimeType}, algorithm=miss
442
482
m. odeIntegrator = true
443
483
TimerOutputs. @timeit m. timer " DifferentialEquations.ODEProblem" problem = DifferentialEquations. ODEProblem {true} (derivatives!, m. x_init, tspan, m)
444
484
end
485
+
486
+ if length (m. linearEquations) == 0
487
+ m. odeMode = true
488
+ m. solve_leq = true
489
+ else
490
+ m. odeMode = false
491
+ m. solve_leq = false
492
+ for leq in m. linearEquations
493
+ if leq. odeMode
494
+ m. odeMode = true
495
+ m. solve_leq = true
496
+ break
497
+ end
498
+ end
499
+ end
445
500
446
501
callback2 = DifferentialEquations. DiscreteCallback (timeEventCondition!, affectTimeEvent!)
447
502
if eh. nz > 0
@@ -450,9 +505,9 @@ function simulateSegment!(m::SimulationModel{FloatType,TimeType}, algorithm=miss
450
505
# FunctionalCallingCallback(outputs!, ...) is not correctly called when zero crossings are present.
451
506
# The fix is to call outputs!(..) from the previous to the current event, when an event occurs.
452
507
# (alternativey: callback4 = DifferentialEquations.PresetTimeCallback(tspan2, affect_outputs!) )
453
- callback1 = DifferentialEquations. FunctionCallingCallback (outputs!, funcat= [m . options. startTime]) # call outputs!(..) at startTime
508
+ callback1 = DifferentialEquations. FunctionCallingCallback (outputs!, funcat= [options. startTime]) # call outputs!(..) at startTime
454
509
callback3 = DifferentialEquations. VectorContinuousCallback (zeroCrossings!,
455
- affectStateEvent!, eh. nz, interp_points= m . options. interp_points, rootfind= DifferentialEquations. SciMLBase. RightRootFind)
510
+ affectStateEvent!, eh. nz, interp_points= options. interp_points, rootfind= DifferentialEquations. SciMLBase. RightRootFind)
456
511
# callback4 = DifferentialEquations.PresetTimeCallback(tspan2, affect_outputs!)
457
512
callbacks = DifferentialEquations. CallbackSet (callback1, callback2, callback3) # , callback4)
458
513
else
@@ -463,24 +518,24 @@ function simulateSegment!(m::SimulationModel{FloatType,TimeType}, algorithm=miss
463
518
464
519
# Initial step size (the default of DifferentialEquations integrators is too large) + step-size of fixed-step algorithm
465
520
if ! m. sundials
466
- dt = m . options. adaptive ? m . options. interval/ 10 : m . options. interval # initial step-size
521
+ dt = options. adaptive ? options. interval/ 10 : options. interval # initial step-size
467
522
end
468
523
469
524
# Compute solution
470
- abstol = 0.1 * m . options. tolerance
525
+ abstol = 0.1 * options. tolerance
471
526
tstops = (m. eventHandler. nextEventTime,)
472
527
maxiters = Int (typemax (Int32)) # switch off maximum number of iterations (typemax(Int) gives an inexact error for Sundials)
473
528
if ismissing (algorithm)
474
- TimerOutputs. @timeit m. timer " DifferentialEquations.solve" solution = DifferentialEquations. solve (problem, reltol= m . options. tolerance, abstol= abstol, save_everystep= false ,
475
- callback= callbacks, adaptive= m . options. adaptive, saveat= tspan2, dt= dt, dtmax= m . options. dtmax, maxiters= maxiters, tstops = tstops,
529
+ TimerOutputs. @timeit m. timer " DifferentialEquations.solve" solution = DifferentialEquations. solve (problem, reltol= options. tolerance, abstol= abstol, save_everystep= false ,
530
+ callback= callbacks, adaptive= options. adaptive, saveat= tspan2, dt= dt, dtmax= options. dtmax, maxiters= maxiters, tstops = tstops,
476
531
initializealg = DifferentialEquations. NoInit ())
477
532
elseif m. sundials
478
- TimerOutputs. @timeit m. timer " DifferentialEquations.solve" solution = DifferentialEquations. solve (problem, algorithm, reltol= m . options. tolerance, abstol= abstol, save_everystep= false ,
479
- callback= callbacks, adaptive= m . options. adaptive, saveat= tspan2, dtmax= m . options. dtmax, maxiters= maxiters, tstops = tstops,
533
+ TimerOutputs. @timeit m. timer " DifferentialEquations.solve" solution = DifferentialEquations. solve (problem, algorithm, reltol= options. tolerance, abstol= abstol, save_everystep= false ,
534
+ callback= callbacks, adaptive= options. adaptive, saveat= tspan2, dtmax= options. dtmax, maxiters= maxiters, tstops = tstops,
480
535
initializealg = DifferentialEquations. NoInit ())
481
536
else
482
- TimerOutputs. @timeit m. timer " DifferentialEquations.solve" solution = DifferentialEquations. solve (problem, algorithm, reltol= m . options. tolerance, abstol= abstol, save_everystep= false ,
483
- callback= callbacks, adaptive= m . options. adaptive, saveat= tspan2, dt= dt, dtmax= m . options. dtmax, maxiters= maxiters, tstops = tstops,
537
+ TimerOutputs. @timeit m. timer " DifferentialEquations.solve" solution = DifferentialEquations. solve (problem, algorithm, reltol= options. tolerance, abstol= abstol, save_everystep= false ,
538
+ callback= callbacks, adaptive= options. adaptive, saveat= tspan2, dt= dt, dtmax= options. dtmax, maxiters= maxiters, tstops = tstops,
484
539
initializealg = DifferentialEquations. NoInit ())
485
540
end
486
541
0 commit comments