@@ -61,6 +61,9 @@ def _integrate(self, model, t_eval, inputs_dict=None):
61
61
"""
62
62
# Record whether there are any symbolic inputs
63
63
inputs_dict = inputs_dict or {}
64
+ has_symbolic_inputs = any (
65
+ isinstance (v , casadi .MX ) for v in inputs_dict .values ()
66
+ )
64
67
symbolic_inputs = casadi .vertcat (
65
68
* [v for v in inputs_dict .values () if isinstance (v , casadi .MX )]
66
69
)
@@ -70,22 +73,29 @@ def _integrate(self, model, t_eval, inputs_dict=None):
70
73
71
74
y0 = model .y0
72
75
76
+ # If y0 already satisfies the tolerance for all t then keep it
77
+ if has_symbolic_inputs is False and all (
78
+ np .all (abs (model .casadi_algebraic (t , y0 , inputs ).full ()) < self .tol )
79
+ for t in t_eval
80
+ ):
81
+ pybamm .logger .debug ("Keeping same solution at all times" )
82
+ return pybamm .Solution (
83
+ t_eval , y0 , model , inputs_dict , termination = "success"
84
+ )
85
+
73
86
# The casadi algebraic solver can read rhs equations, but leaves them unchanged
74
87
# i.e. the part of the solution vector that corresponds to the differential
75
88
# equations will be equal to the initial condition provided. This allows this
76
89
# solver to be used for initialising the DAE solvers
77
90
if model .rhs == {}:
78
- print ('no rhs' )
79
91
len_rhs = 0
80
92
y0_diff = casadi .DM ()
81
93
y0_alg = y0
82
94
else :
83
95
# Check y0 to see if it includes sensitivities
84
96
if model .len_rhs_and_alg == y0 .shape [0 ]:
85
- print ('doesnt include sens' )
86
97
len_rhs = model .len_rhs
87
98
else :
88
- print ('includes sens' , inputs .shape [0 ])
89
99
len_rhs = model .len_rhs * (inputs .shape [0 ] + 1 )
90
100
y0_diff = y0 [:len_rhs ]
91
101
y0_alg = y0 [len_rhs :]
@@ -159,7 +169,8 @@ def _integrate(self, model, t_eval, inputs_dict=None):
159
169
for idx , t in enumerate (t_eval ):
160
170
# Evaluate algebraic with new t and previous y0, if it's already close
161
171
# enough then keep it
162
- if np .all (
172
+ # We can't do this if there are symbolic inputs
173
+ if has_symbolic_inputs is False and np .all (
163
174
abs (model .casadi_algebraic (t , y0 , inputs ).full ()) < self .tol
164
175
):
165
176
pybamm .logger .debug (
@@ -171,7 +182,7 @@ def _integrate(self, model, t_eval, inputs_dict=None):
171
182
y_alg = casadi .horzcat (y_alg , y0_alg )
172
183
# Otherwise calculate new y_sol
173
184
else :
174
- t_y0_diff_inputs = casadi .vertcat (t , y0_diff , inputs )
185
+ t_y0_diff_inputs = casadi .vertcat (t , y0_diff , symbolic_inputs )
175
186
# Solve
176
187
try :
177
188
timer .reset ()
@@ -187,9 +198,11 @@ def _integrate(self, model, t_eval, inputs_dict=None):
187
198
message = err .args [0 ]
188
199
fun = None
189
200
190
- # check the function is below the tol
201
+ # If there are no symbolic inputs, check the function is below the tol
202
+ # Skip this check if there are symbolic inputs
191
203
if success and (
192
- not any (np .isnan (fun )) and np .all (casadi .fabs (fun ) < self .tol )
204
+ has_symbolic_inputs is True
205
+ or (not any (np .isnan (fun )) and np .all (casadi .fabs (fun ) < self .tol ))
193
206
):
194
207
# update initial guess for the next iteration
195
208
y0_alg = y_alg_sol
0 commit comments