Source code for pybop.costs.design_costs

import numpy as np

from pybop.costs.base_cost import BaseCost


[docs] class DesignCost(BaseCost): """ Overwrites and extends `BaseCost` class for design-related cost functions. Inherits all parameters and attributes from ``BaseCost``. Additional Attributes --------------------- problem : object The associated problem containing model and evaluation methods. """ def __init__(self, problem): """ Initialises the gravimetric energy density calculator with a problem. Parameters ---------- problem : object The problem instance containing the model and data. """ super().__init__(problem)
[docs] self.problem = problem
[docs] class GravimetricEnergyDensity(DesignCost): """ Represents the gravimetric energy density of a battery cell, calculated based on a normalised discharge from upper to lower voltage limits. The goal is to maximise the energy density, which is achieved by setting minimising = False in the optimiser settings. Inherits all parameters and attributes from ``DesignCost``. """ def __init__(self, problem): super().__init__(problem)
[docs] def compute( self, y: dict, dy: np.ndarray = None, calculate_grad: bool = False, ) -> float: """ Computes the cost function for the given predictions. Parameters ---------- y : dict The dictionary of predictions with keys designating the signals for fitting. dy : np.ndarray, optional The corresponding gradient with respect to the parameters for each signal. Note: not used in design optimisation classes. calculate_grad : bool, optional A bool condition designating whether to calculate the gradient. Returns ------- float The gravimetric energy density or -infinity in case of infeasible parameters. """ if not any(np.isfinite(y[signal][0]) for signal in self.signal): return -np.inf voltage, current = y["Voltage [V]"], y["Current [A]"] dt = y["Time [s]"][1] - y["Time [s]"][0] energy_density = np.trapz(voltage * current, dx=dt) / ( 3600 * self.problem.model.cell_mass() ) return energy_density
[docs] class VolumetricEnergyDensity(DesignCost): """ Represents the volumetric energy density of a battery cell, calculated based on a normalised discharge from upper to lower voltage limits. The goal is to maximise the energy density, which is achieved by setting minimising = False in the optimiser settings. Inherits all parameters and attributes from ``DesignCost``. """ def __init__(self, problem): super().__init__(problem)
[docs] def compute( self, y: dict, dy: np.ndarray = None, calculate_grad: bool = False, ) -> float: """ Computes the cost function for the given predictions. Parameters ---------- y : dict The dictionary of predictions with keys designating the signals for fitting. dy : np.ndarray, optional The corresponding gradient with respect to the parameters for each signal. Note: not used in design optimisation classes. calculate_grad : bool, optional A bool condition designating whether to calculate the gradient. Returns ------- float The volumetric energy density or -infinity in case of infeasible parameters. """ if not any(np.isfinite(y[signal][0]) for signal in self.signal): return -np.inf voltage, current = y["Voltage [V]"], y["Current [A]"] dt = y["Time [s]"][1] - y["Time [s]"][0] energy_density = np.trapz(voltage * current, dx=dt) / ( 3600 * self.problem.model.cell_volume() ) return energy_density