Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 1082 casadi #1089

Merged
merged 9 commits into from
Jun 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Features

- Reformatted Getting Starte notebooks ([#1083](https://github.com/pybamm-team/PyBaMM/pull/1083))
- Reformatted Getting Started notebooks ([#1083](https://github.com/pybamm-team/PyBaMM/pull/1083))
- Reformatted Landesfeind electrolytes ([#1064](https://github.com/pybamm-team/PyBaMM/pull/1064))
- Adapted examples to be run in Google Colab ([#1061](https://github.com/pybamm-team/PyBaMM/pull/1061))
- Added some new solvers for algebraic models ([#1059](https://github.com/pybamm-team/PyBaMM/pull/1059))
Expand All @@ -12,6 +12,8 @@

## Optimizations

- Reformatted CasADi "safe" mode to deal with events better ([#1089](https://github.com/pybamm-team/PyBaMM/pull/1089))

## Bug fixes

- 2D processed variables can now be evaluated at the domain boundaries ([#1088](https://github.com/pybamm-team/PyBaMM/pull/1088))
Expand Down
2 changes: 1 addition & 1 deletion examples/scripts/compare_lithium_ion.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#
import pybamm

# pybamm.set_logging_level("INFO")
pybamm.set_logging_level("INFO")

# load models
models = [
Expand Down
36 changes: 23 additions & 13 deletions pybamm/solvers/casadi_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ def _integrate(self, model, t_eval, inputs=None):
# Non-dimensionalise provided dt_max
dt_max = self.dt_max / model.timescale_eval
else:
dt_max = 0.01
# t_f is the dimensionless final time (scaled with the timescale)
dt_max = 0.1 * min(1, t_f)
dt_eval_max = np.max(np.diff(t_eval)) * 1.01
dt_max = np.max([dt_max, dt_eval_max])
while t < t_f:
Expand Down Expand Up @@ -186,11 +187,11 @@ def _integrate(self, model, t_eval, inputs=None):
count += 1
if count >= self.max_step_decrease_count:
raise pybamm.SolverError(
"""
Maximum number of decreased steps occurred at t={}. Try
solving the model up to this time only or reducing dt_max.
""".format(
t
"Maximum number of decreased steps occurred at t={}. Try "
"solving the model up to this time only or reducing dt_max "
"(currently, dt_max={})."
"".format(
t * model.timescale_eval, dt_max * model.timescale_eval
)
)
# Check most recent y to see if any events have been crossed
Expand Down Expand Up @@ -246,18 +247,27 @@ def event_fun(t):
t_event = np.nanmin(t_events)
y_event = y_sol(t_event)

# return truncated solution
t_truncated = current_step_sol.t[current_step_sol.t < t_event]
y_trunctaed = current_step_sol.y[:, 0 : len(t_truncated)]
truncated_step_sol = pybamm.Solution(t_truncated, y_trunctaed)
# solve again until the event time
# See comments above on creating t_window
t_window = np.concatenate(
([t], t_eval[(t_eval > t) & (t_eval < t_event)])
)
if len(t_window) == 1:
t_window = np.array([t, t_event])

integrator = self.get_integrator(model, t_window, inputs)
current_step_sol = self._run_integrator(
integrator, model, y0, inputs, t_window
)

# assign temporary solve time
truncated_step_sol.solve_time = np.nan
current_step_sol.solve_time = np.nan
# append solution from the current step to solution
solution.append(truncated_step_sol)

solution.append(current_step_sol)
solution.termination = "event"
solution.t_event = t_event
solution.y_event = y_event

break
else:
# assign temporary solve time
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def get_output_times(self):

# Assign common time
solution0 = self.solutions[0]
max_index = np.where(solution0.t == max_t)[0][0]
max_index = np.where(solution0.t >= max_t)[0][0]
t_common = solution0.t[:max_index]

# Check times
Expand Down
12 changes: 7 additions & 5 deletions tests/unit/test_solvers/test_casadi_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def test_model_solver_events(self):
t_eval = np.linspace(0, 5, 100)
solution = solver.solve(model, t_eval)
np.testing.assert_array_less(solution.y[0], 1.5)
np.testing.assert_array_less(solution.y[-1], 2.5)
np.testing.assert_array_less(solution.y[-1], 2.5 + 1e-10)
np.testing.assert_array_almost_equal(
solution.y[0], np.exp(0.1 * solution.t), decimal=5
)
Expand All @@ -133,7 +133,9 @@ def test_model_solver_events(self):
t_eval = np.linspace(0, 5, 100)
solution = solver.solve(model, t_eval)
np.testing.assert_array_less(solution.y[0], 1.5)
np.testing.assert_array_less(solution.y[-1], 2.5)
np.testing.assert_array_less(solution.y[-1], 2.5 + 1e-10)
# test the last entry is exactly 2.5
np.testing.assert_array_almost_equal(solution.y[-1, -1], 2.5, decimal=2)
np.testing.assert_array_almost_equal(
solution.y[0], np.exp(0.1 * solution.t), decimal=5
)
Expand Down Expand Up @@ -168,7 +170,8 @@ def test_model_solver_events(self):
disc.process_model(model)
solver = pybamm.CasadiSolver(rtol=1e-8, atol=1e-8)
solution = solver.solve(model, t_eval)
np.testing.assert_array_less(solution.y[0], 1.02)
np.testing.assert_array_less(solution.y[0], 1.02 + 1e-10)
np.testing.assert_array_almost_equal(solution.y[0, -1], 1.02, decimal=2)

def test_model_step(self):
# Create model
Expand Down Expand Up @@ -299,8 +302,7 @@ def test_model_solver_with_inputs(self):
t_eval = np.linspace(0, 10, 100)
solution = solver.solve(model, t_eval, inputs={"rate": 0.1})
self.assertLess(len(solution.t), len(t_eval))
np.testing.assert_array_equal(solution.t, t_eval[: len(solution.t)])
np.testing.assert_allclose(solution.y[0], np.exp(-0.1 * solution.t), rtol=1e-06)
np.testing.assert_allclose(solution.y[0], np.exp(-0.1 * solution.t), rtol=1e-04)

def test_model_solver_dae_inputs_in_initial_conditions(self):
# Create model
Expand Down