def test_log(self): a = pybamm.InputParameter("a") fun = pybamm.log(a) self.assertEqual(fun.evaluate(inputs={"a": 3}), np.log(3)) h = 0.0000001 self.assertAlmostEqual( fun.diff(a).evaluate(inputs={"a": 3}), ( pybamm.log(pybamm.Scalar(3 + h)).evaluate() - fun.evaluate(inputs={"a": 3}) ) / h, places=5, ) # Base 10 fun = pybamm.log10(a) self.assertEqual(fun.evaluate(inputs={"a": 3}), np.log10(3)) h = 0.0000001 self.assertAlmostEqual( fun.diff(a).evaluate(inputs={"a": 3}), ( pybamm.log10(pybamm.Scalar(3 + h)).evaluate() - fun.evaluate(inputs={"a": 3}) ) / h, places=5, )
def _binary_jac(self, left_jac, right_jac): """ See :meth:`pybamm.BinaryOperator._binary_jac()`. """ # apply chain rule and power rule left, right = self.orphans if right.evaluates_to_constant_number(): return (right * left**(right - 1)) * left_jac elif left.evaluates_to_constant_number(): return (left**right * pybamm.log(left)) * right_jac else: return (left**(right - 1)) * (right * left_jac + left * pybamm.log(left) * right_jac)
def _jac(self, variable): """ See :meth:`pybamm.Symbol._jac()`. """ # apply chain rule and power rule base, exponent = self.orphans if base.evaluates_to_number() and exponent.evaluates_to_number(): return pybamm.Scalar(0) elif exponent.evaluates_to_number(): return (exponent * base**(exponent - 1)) * base.jac(variable) elif base.evaluates_to_number(): return (base**exponent * pybamm.log(base)) * exponent.jac(variable) else: return (base**(exponent - 1)) * ( exponent * base.jac(variable) + base * pybamm.log(base) * exponent.jac(variable))
def _diff(self, variable): """ See :meth:`pybamm.Symbol._diff()`. """ # apply chain rule and power rule base, exponent = self.orphans return base**(exponent - 1) * (exponent * base.diff(variable) + base * pybamm.log(base) * exponent.diff(variable))
def test_log(self): a = pybamm.Scalar(3) fun = pybamm.log(a) self.assertIsInstance(fun, pybamm.Log) self.assertEqual(fun.children[0].id, a.id) self.assertEqual(fun.evaluate(), np.log(3)) self.assertEqual(fun.diff(a).evaluate(), 1 / 3)
def test_unary_operator(self): a = pybamm.Symbol("a", domain=["test"]) un = pybamm.UnaryOperator("unary test", a) self.assertEqual(un.children[0].name, a.name) self.assertEqual(un.domain, a.domain) # with number log = pybamm.log(10) self.assertEqual(log.evaluate(), np.log(10))
def U_p_dimensional(self, sto, T): """Dimensional open-circuit potential in the positive electrode [V]""" inputs = {"Positive particle stoichiometry": sto} u_ref = pybamm.FunctionParameter("Positive electrode OCP [V]", inputs) # add a term to ensure that the OCP goes to infinity at 0 and -infinity at 1 # this will not affect the OCP for most values of sto # see #1435 u_ref -= 1e-6 * pybamm.log(sto / (1 - sto)) return u_ref + (T - self.T_ref) * self.dUdT_p_dimensional(sto)
def _diff(self, variable): """ See :meth:`pybamm.Symbol._diff()`. """ # apply chain rule and power rule base, exponent = self.orphans # derivative if variable is in the base diff = exponent * (base ** (exponent - 1)) * base.diff(variable) # derivative if variable is in the exponent (rare, check separately to avoid # unecessarily big tree) if any(variable.id == x.id for x in exponent.pre_order()): diff += (base ** exponent) * pybamm.log(base) * exponent.diff(variable) return diff
def RKn_fit(x, U0, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9): A = [a0, a1, a2, a3, a4, a5, a6, a7, a8, a9] R = 8.314 T = 298.15 F = 96485 term1 = R * T / F * pybamm.log((1 - x) / x) term2 = 0 for k in range(len(A)): a = (2 * x - 1)**(k + 1) b = 2 * x * k * (1 - x) c = (2 * x - 1)**(1 - k) term2 += (A[k] / F) * (a - b / c) return U0 + term1 + term2
def _higher_order_macinnes_function(self, x): "Function to differentiate between composite and first-order models" if self.higher_order_terms == "composite": return pybamm.log(x) elif self.higher_order_terms == "first-order": return x
def _higher_order_macinnes_function(self, x): "Use log for composite higher order terms" return pybamm.log(x)
def softplus(left, right, k): """ Softplus approximation to the maximum function. k is the smoothing parameter, set by `pybamm.settings.max_smoothing`. The recommended value is k=10. """ return pybamm.log(pybamm.exp(k * left) + pybamm.exp(k * right)) / k
def _higher_order_macinnes_function(self, x): return pybamm.log(x)