Skip to content

Commit 5857a3a

Browse files
committed
#1477 put back algebraic solver sens tests
1 parent 2cb99ad commit 5857a3a

File tree

1 file changed

+153
-0
lines changed

1 file changed

+153
-0
lines changed

tests/unit/test_solvers/test_casadi_algebraic_solver.py

+153
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import pybamm
66
import unittest
77
import numpy as np
8+
from scipy.optimize import least_squares
9+
import tests
810

911

1012
class TestCasadiAlgebraicSolver(unittest.TestCase):
@@ -172,6 +174,157 @@ def test_solve_with_input(self):
172174
np.testing.assert_array_equal(solution.y, -7)
173175

174176

177+
class TestCasadiAlgebraicSolverSensitivity(unittest.TestCase):
178+
def test_solve_with_symbolic_input(self):
179+
# Simple system: a single algebraic equation
180+
var = pybamm.Variable("var")
181+
model = pybamm.BaseModel()
182+
model.algebraic = {var: var + pybamm.InputParameter("param")}
183+
model.initial_conditions = {var: 2}
184+
model.variables = {"var": var}
185+
186+
# create discretisation
187+
disc = pybamm.Discretisation()
188+
disc.process_model(model)
189+
190+
# Solve
191+
solver = pybamm.CasadiAlgebraicSolver()
192+
solution = solver.solve(model, [0])
193+
np.testing.assert_array_equal(solution["var"].value({"param": 7}), -7)
194+
np.testing.assert_array_equal(solution["var"].value({"param": 3}), -3)
195+
np.testing.assert_array_equal(solution["var"].sensitivity({"param": 3}), -1)
196+
197+
def test_least_squares_fit(self):
198+
# Simple system: a single algebraic equation
199+
var = pybamm.Variable("var", domain="negative electrode")
200+
model = pybamm.BaseModel()
201+
p = pybamm.InputParameter("p")
202+
q = pybamm.InputParameter("q")
203+
model.algebraic = {var: (var - p)}
204+
model.initial_conditions = {var: 3}
205+
model.variables = {"objective": (var - q) ** 2 + (p - 3) ** 2}
206+
207+
# create discretisation
208+
disc = tests.get_discretisation_for_testing()
209+
disc.process_model(model)
210+
211+
# Solve
212+
solver = pybamm.CasadiAlgebraicSolver()
213+
solution = solver.solve(model, [0])
214+
sol_var = solution["objective"]
215+
216+
def objective(x):
217+
return sol_var.value({"p": x[0], "q": x[1]}).full().flatten()
218+
219+
# without jacobian
220+
lsq_sol = least_squares(objective, [2, 2], method="lm")
221+
np.testing.assert_array_almost_equal(lsq_sol.x, [3, 3], decimal=3)
222+
223+
def jac(x):
224+
return sol_var.sensitivity({"p": x[0], "q": x[1]})
225+
226+
# with jacobian
227+
lsq_sol = least_squares(objective, [2, 2], jac=jac, method="lm")
228+
np.testing.assert_array_almost_equal(lsq_sol.x, [3, 3], decimal=3)
229+
230+
def test_solve_with_symbolic_input_1D_scalar_input(self):
231+
var = pybamm.Variable("var", "negative electrode")
232+
model = pybamm.BaseModel()
233+
param = pybamm.InputParameter("param")
234+
model.algebraic = {var: var + param}
235+
model.initial_conditions = {var: 2}
236+
model.variables = {"var": var}
237+
238+
# create discretisation
239+
disc = tests.get_discretisation_for_testing()
240+
disc.process_model(model)
241+
242+
# Solve - scalar input
243+
solver = pybamm.CasadiAlgebraicSolver()
244+
solution = solver.solve(model, [0])
245+
np.testing.assert_array_equal(solution["var"].value({"param": 7}), -7)
246+
np.testing.assert_array_equal(solution["var"].value({"param": 3}), -3)
247+
np.testing.assert_array_equal(solution["var"].sensitivity({"param": 3}), -1)
248+
249+
def test_solve_with_symbolic_input_1D_vector_input(self):
250+
var = pybamm.Variable("var", "negative electrode")
251+
model = pybamm.BaseModel()
252+
param = pybamm.InputParameter("param", "negative electrode")
253+
model.algebraic = {var: var + param}
254+
model.initial_conditions = {var: 2}
255+
model.variables = {"var": var}
256+
257+
# create discretisation
258+
disc = tests.get_discretisation_for_testing()
259+
disc.process_model(model)
260+
261+
# Solve - scalar input
262+
solver = pybamm.CasadiAlgebraicSolver()
263+
solution = solver.solve(model, [0])
264+
n = disc.mesh["negative electrode"].npts
265+
266+
solver = pybamm.CasadiAlgebraicSolver()
267+
solution = solver.solve(model, [0])
268+
p = np.linspace(0, 1, n)[:, np.newaxis]
269+
np.testing.assert_array_almost_equal(
270+
solution["var"].value({"param": 3 * np.ones(n)}), -3
271+
)
272+
np.testing.assert_array_almost_equal(
273+
solution["var"].value({"param": 2 * p}), -2 * p
274+
)
275+
np.testing.assert_array_almost_equal(
276+
solution["var"].sensitivity({"param": 3 * np.ones(n)}), -np.eye(40)
277+
)
278+
np.testing.assert_array_almost_equal(
279+
solution["var"].sensitivity({"param": p}), -np.eye(40)
280+
)
281+
282+
def test_solve_with_symbolic_input_in_initial_conditions(self):
283+
# Simple system: a single algebraic equation
284+
var = pybamm.Variable("var")
285+
model = pybamm.BaseModel()
286+
model.algebraic = {var: var + 2}
287+
model.initial_conditions = {var: pybamm.InputParameter("param")}
288+
model.variables = {"var": var}
289+
290+
# create discretisation
291+
disc = pybamm.Discretisation()
292+
disc.process_model(model)
293+
294+
# Solve
295+
solver = pybamm.CasadiAlgebraicSolver()
296+
solution = solver.solve(model, [0])
297+
np.testing.assert_array_equal(solution["var"].value({"param": 7}), -2)
298+
np.testing.assert_array_equal(solution["var"].value({"param": 3}), -2)
299+
np.testing.assert_array_equal(solution["var"].sensitivity({"param": 3}), 0)
300+
301+
def test_least_squares_fit_input_in_initial_conditions(self):
302+
# Simple system: a single algebraic equation
303+
var = pybamm.Variable("var", domain="negative electrode")
304+
model = pybamm.BaseModel()
305+
p = pybamm.InputParameter("p")
306+
q = pybamm.InputParameter("q")
307+
model.algebraic = {var: (var - p)}
308+
model.initial_conditions = {var: p}
309+
model.variables = {"objective": (var - q) ** 2 + (p - 3) ** 2}
310+
311+
# create discretisation
312+
disc = tests.get_discretisation_for_testing()
313+
disc.process_model(model)
314+
315+
# Solve
316+
solver = pybamm.CasadiAlgebraicSolver()
317+
solution = solver.solve(model, [0])
318+
sol_var = solution["objective"]
319+
320+
def objective(x):
321+
return sol_var.value({"p": x[0], "q": x[1]}).full().flatten()
322+
323+
# without jacobian
324+
lsq_sol = least_squares(objective, [2, 2], method="lm")
325+
np.testing.assert_array_almost_equal(lsq_sol.x, [3, 3], decimal=3)
326+
327+
175328
if __name__ == "__main__":
176329
print("Add -v for more debug output")
177330
import sys

0 commit comments

Comments
 (0)