Skip to content

Commit

Permalink
pybamm-team#983 added Modulo operator
Browse files Browse the repository at this point in the history
  • Loading branch information
brosaplanella committed Jul 27, 2020
1 parent 12f049e commit de9c69d
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 2 deletions.
15 changes: 15 additions & 0 deletions pybamm/expression_tree/binary_operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,21 @@ def _binary_evaluate(self, left, right):
return left < right


class Modulo(BinaryOperator):
"Calculates the remainder of an integer division"

def __init__(self, left, right):
super().__init__("%", left, right)

def __str__(self):
""" See :meth:`pybamm.Symbol.__str__()`. """
return "{!s} mod {!s}".format(self.left, self.right)

def _binary_evaluate(self, left, right):
""" See :meth:`pybamm.BinaryOperator._binary_evaluate()`. """
return left % right


class Minimum(BinaryOperator):
" Returns the smaller of two objects "

Expand Down
2 changes: 2 additions & 0 deletions pybamm/expression_tree/operations/convert_to_casadi.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ def _convert(self, symbol, t, y, y_dot, inputs):
converted_left = self.convert(left, t, y, y_dot, inputs)
converted_right = self.convert(right, t, y, y_dot, inputs)

if isinstance(symbol, pybamm.Modulo):
return casadi.fmod(converted_left, converted_right)
if isinstance(symbol, pybamm.Minimum):
return casadi.fmin(converted_left, converted_right)
if isinstance(symbol, pybamm.Maximum):
Expand Down
6 changes: 6 additions & 0 deletions pybamm/expression_tree/symbol.py
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,12 @@ def __abs__(self):
return pybamm.simplify_if_constant(
pybamm.AbsoluteValue(self), keep_domains=True
)

def __mod__(self, other):
"""return an :class:`Modulo` object"""
return pybamm.simplify_if_constant(
pybamm.Modulo(self, other), keep_domains=True
)

def diff(self, variable):
"""
Expand Down
30 changes: 28 additions & 2 deletions pybamm/solvers/base_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,8 @@ def report(string):
jac_call = None
return func, func_call, jac_call

# Check for heaviside functions in rhs and algebraic and add discontinuity
# events if these exist.
# Check for heaviside and modulo functions in rhs and algebraic and add
# discontinuity events if these exist.
# Note: only checks for the case of t < X, t <= X, X < t, or X <= t, but also
# accounts for the fact that t might be dimensional
# Only do this for DAE models as ODE models can deal with discontinuities fine
Expand Down Expand Up @@ -315,6 +315,32 @@ def report(string):
pybamm.EventType.DISCONTINUITY,
)
)
elif isinstance(symbol, pybamm.Modulo):
found_t = False
# Dimensionless
if symbol.right.id == pybamm.t.id:
expr = symbol.left
found_t = True
elif symbol.left.id == pybamm.t.id:
expr = symbol.right
found_t = True
# Dimensional
elif symbol.right.id == (pybamm.t * model.timescale).id:
expr = symbol.left.new_copy() / symbol.right.right.new_copy()
found_t = True
elif symbol.left.id == (pybamm.t * model.timescale).id:
expr = symbol.right.new_copy() / symbol.left.right.new_copy()
found_t = True

# Update the events if the heaviside function depended on t
if found_t:
model.events.append(
pybamm.Event(
str(symbol),
expr.new_copy(),
pybamm.EventType.DISCONTINUITY,
)
)

# Process initial conditions
initial_conditions = process(
Expand Down

0 comments on commit de9c69d

Please sign in to comment.