@@ -401,8 +401,9 @@ function simulateSegment!(m::SimulationModel{FloatType,TimeType}, algorithm=miss
401401 tspan = (options. startTime, options. stopTime)
402402
403403 eh = m. eventHandler
404- m. odeMode = true
405- m. solve_leq = true
404+ for leq in m. linearEquations
405+ leq. odeMode = true
406+ end
406407 if typeof (algorithm) <: DifferentialEquations.DiffEqBase.AbstractDAEAlgorithm
407408 # DAE integrator
408409 m. odeIntegrator = false
@@ -412,27 +413,65 @@ function simulateSegment!(m::SimulationModel{FloatType,TimeType}, algorithm=miss
412413 TimerOutputs. @timeit m. timer " DifferentialEquations.DAEProblem" problem = DifferentialEquations. DAEProblem {true} (DAEresidualsForODE!, m. der_x, m. x_init, tspan, m, differential_vars = differential_vars)
413414 empty! (m. daeCopyInfo)
414415 if length (sizesOfLinearEquationSystems) > 0 && maximum (sizesOfLinearEquationSystems) >= options. nlinearMinForDAE
415- # Prepare data structure to efficiently perform copy operations for DAE integrator
416+ # Prepare data structure to efficiently perform copy operations for DAE integrator
416417 x_info = m. equationInfo. x_info
417418 der_x_dict = m. equationInfo. der_x_dict
418419 der_x_names = keys (der_x_dict)
420+ daeMode = false
419421 for (ileq,leq) in enumerate (m. linearEquations)
420- if sizesOfLinearEquationSystems[ileq] >= options. nlinearMinForDAE &&
421- length (intersect (leq. x_names,der_x_names)) == length (leq. x_names)
422- # Linear equation shall be solved by DAE and all unknowns of the linear equation system are DAE derivatives
423- leq. odeMode = false
424- m. odeMode = false
425- leq_copy = LinearEquationsCopyInfoForDAEMode (ileq)
426- for ix in 1 : length (leq. x_names)
427- x_name = leq. x_names[ix]
428- x_length = leq. x_lengths[ix]
429- x_info_i = x_info[ der_x_dict[x_name] ]
430- @assert (x_length == x_info_i. length)
431- startIndex = x_info_i. startIndex
432- endIndex = startIndex + x_length - 1
433- 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
434474 end
435- push! (m. daeCopyInfo, leq_copy)
436475 else
437476 leq. odeMode = true
438477 end
@@ -443,6 +482,21 @@ function simulateSegment!(m::SimulationModel{FloatType,TimeType}, algorithm=miss
443482 m. odeIntegrator = true
444483 TimerOutputs. @timeit m. timer " DifferentialEquations.ODEProblem" problem = DifferentialEquations. ODEProblem {true} (derivatives!, m. x_init, tspan, m)
445484 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
446500
447501 callback2 = DifferentialEquations. DiscreteCallback (timeEventCondition!, affectTimeEvent!)
448502 if eh. nz > 0
0 commit comments