Running experiments#
An experiment is a sequence of steps that operate a battery through its controls, the inlet
temperature and the mass flow rate. Each step either holds both controls
(Inlet) or holds the power by adjusting one of them (Power). Steps end
after a duration or when a termination condition is met, and they can be grouped into
cycles. The result is an ordinary pybamm.Solution.
Power is positive on discharge (heat delivered by the battery), so a charge at constant power uses a negative power.
Tutorial 6 introduces experiments.
import numpy as np
import pybamm
import pytes
from pytes.experiments import Experiment, run_experiment
from pytes.experiments import step as s
model = pytes.SharpFrontModel()
mdot = 0.02 # the default mass flow rate [kg.s-1]
T_cold, T_hot = 273.15 + 10, 273.15 + 75
The battery starts uniform at 70 °C. A cycle discharges it at 1 kW with water at 10 °C, adjusting the flow rate, until the flow would exceed twice the nominal one; rests for half an hour with no flow; and charges it at 1 kW at the nominal flow, adjusting the inlet temperature, until the inlet would exceed 75 °C or the outlet reaches 65 °C. The cycle runs twice.
discharge = s.Power(
1e3,
inlet_temperature=T_cold,
termination=s.mass_flow_rate_above(2 * mdot),
description="Discharge at 1 kW",
)
rest = s.Rest(duration=1800, description="Rest for 30 min")
charge = s.Power(
-1e3,
mass_flow_rate=mdot,
termination=[
s.inlet_temperature_above(T_hot),
s.outlet_temperature_above(T_hot - 10),
],
description="Charge at 1 kW",
)
experiment = Experiment([(discharge, rest, charge)] * 2)
solution = run_experiment(model, experiment)
# As in PyBaMM, solution.cycles[i].steps[j] is the solution of experiment.cycles[i][j]
for i, (cycle, cycle_solution) in enumerate(
zip(experiment.cycles, solution.cycles, strict=True)
):
for step, step_solution in zip(cycle, cycle_solution.steps, strict=True):
duration = (step_solution.t[-1] - step_solution.t[0]) / 60
print(f"cycle {i + 1}: {step.description:20s} {duration:5.1f} min")
cycle 1: Discharge at 1 kW 139.4 min
cycle 1: Rest for 30 min 30.0 min
cycle 1: Charge at 1 kW 98.3 min
cycle 2: Discharge at 1 kW 99.0 min
cycle 2: Rest for 30 min 30.0 min
cycle 2: Charge at 1 kW 99.0 min
Power holds the power by adjusting the control that is not given: the flow rate
in the discharge, the inlet temperature in the charge.
pybamm.dynamic_plot(
solution,
[
["Inlet temperature [degC]", "Outlet temperature [degC]"],
"Mass flow rate [kg.s-1]",
"Power [kW]",
"Discharged energy [kWh]",
],
time_unit="hours",
)
<pybamm.plotting.quick_plot.QuickPlot at 0x7cdfb3a6af90>
The throughputs count the energy delivered while discharging and the energy put in while charging. The models have no heat losses yet, so the two differ only by the change in stored energy: the first cycle starts full and its charge stops before the battery is full again, so it delivers more than it takes back; the second starts and ends in nearly the same state, so its ratio, the round-trip efficiency, is about 1. The pumped volume is the water used, as a flow meter would total it.
for i, cycle in enumerate(solution.cycles, start=1):
out = cycle["Discharged throughput [kWh]"].entries
put_in = cycle["Charged throughput [kWh]"].entries
pumped = cycle["Pumped volume [l]"].entries
energy_out, energy_in = out[-1] - out[0], put_in[-1] - put_in[0]
print(
f"cycle {i}: {energy_out:.2f} kWh out, {energy_in:.2f} kWh in "
f"(ratio {energy_out / energy_in:.2f}), {pumped[-1] - pumped[0]:.0f} l pumped"
)
cycle 1: 2.32 kWh out, 1.64 kWh in (ratio 1.42), 162 l pumped
cycle 2: 1.65 kWh out, 1.65 kWh in (ratio 1.00), 152 l pumped
Step values can also be time series (a 2-column array of time since the start of the step and value) or functions of the time since the start of the step, for example a slowly rising inlet temperature.
ramp = s.Inlet(lambda t: T_cold + 20 * t / 3600, mdot, duration=3600)
ramped = run_experiment(model, Experiment([ramp]))
print(
"inlet temperature at 0, 30 and 60 min [degC]:",
ramped["Inlet temperature [degC]"](np.array([0, 1800, 3600])),
)
inlet temperature at 0, 30 and 60 min [degC]: [10. 20. 30.]