@@ -176,3 +176,83 @@ function _initialize_dae!(integrator, prob::Union{ODEProblem, DAEProblem},
176176 ReturnCode. InitialFailure)
177177 end
178178end
179+
180+ # # CheckInit
181+ struct CheckInitFailureError <: Exception
182+ normresid
183+ abstol
184+ end
185+
186+ function Base. showerror (io:: IO , e:: CheckInitFailureError )
187+ print (io, " CheckInit specified but initialization not satisifed. normresid = $(e. normresid) > abstol = $(e. abstol) " )
188+ end
189+
190+ function _initialize_dae! (integrator, prob:: ODEProblem , alg:: CheckInit ,
191+ isinplace:: Val{true} )
192+ @unpack p, t, f = integrator
193+ M = integrator. f. mass_matrix
194+ tmp = first (get_tmp_cache (integrator))
195+ u0 = integrator. u
196+
197+ algebraic_vars = [all (iszero, x) for x in eachcol (M)]
198+ algebraic_eqs = [all (iszero, x) for x in eachrow (M)]
199+ (iszero (algebraic_vars) || iszero (algebraic_eqs)) && return
200+ update_coefficients! (M, u0, p, t)
201+ f (tmp, u0, p, t)
202+ tmp .= ArrayInterface. restructure (tmp, algebraic_eqs .* _vec (tmp))
203+
204+ normresid = integrator. opts. internalnorm (tmp, t)
205+ if normresid > integrator. opts. abstol
206+ throw (CheckInitFailureError (normresid, integrator. opts. abstol))
207+ end
208+ end
209+
210+ function _initialize_dae! (integrator, prob:: ODEProblem , alg:: CheckInit ,
211+ isinplace:: Val{false} )
212+ @unpack p, t, f = integrator
213+ u0 = integrator. u
214+ M = integrator. f. mass_matrix
215+
216+ algebraic_vars = [all (iszero, x) for x in eachcol (M)]
217+ algebraic_eqs = [all (iszero, x) for x in eachrow (M)]
218+ (iszero (algebraic_vars) || iszero (algebraic_eqs)) && return
219+ update_coefficients! (M, u0, p, t)
220+ du = f (u0, p, t)
221+ resid = _vec (du)[algebraic_eqs]
222+
223+ normresid = integrator. opts. internalnorm (resid, t)
224+ if normresid > integrator. opts. abstol
225+ throw (CheckInitFailureError (normresid, integrator. opts. abstol))
226+ end
227+ end
228+
229+ function _initialize_dae! (integrator, prob:: DAEProblem ,
230+ alg:: CheckInit , isinplace:: Val{true} )
231+ @unpack p, t, f = integrator
232+ u0 = integrator. u
233+ resid = get_tmp_cache (integrator)[2 ]
234+
235+ f (resid, integrator. du, u0, p, t)
236+ normresid = integrator. opts. internalnorm (resid, t)
237+ if normresid > integrator. opts. abstol
238+ throw (CheckInitFailureError (normresid, integrator. opts. abstol))
239+ end
240+ end
241+
242+ function _initialize_dae! (integrator, prob:: DAEProblem ,
243+ alg:: CheckInit , isinplace:: Val{false} )
244+ @unpack p, t, f = integrator
245+ u0 = integrator. u
246+
247+ nlequation_oop = u -> begin
248+ f ((u - u0) / dt, u, p, t)
249+ end
250+
251+ nlequation = (u, _) -> nlequation_oop (u)
252+
253+ resid = f (integrator. du, u0, p, t)
254+ normresid = integrator. opts. internalnorm (resid, t)
255+ if normresid > integrator. opts. abstol
256+ throw (CheckInitFailureError (normresid, integrator. opts. abstol))
257+ end
258+ end
0 commit comments