Experiments#
Experiments: steps that operate a model through its controls, and the runner.
- class pytes.experiments.Experiment(operating_conditions)[source]#
Bases:
objectA sequence of steps.
- Parameters:
operating_conditions (
list) – Steps, or tuples (or lists) of steps that form a cycle. As in PyBaMM, a list can be repeated, e.g.[(charge, discharge)] * 5.- Variables:
- Raises:
TypeError – If an item is not a
pytes.experiments.stepstep (for example, a PyBaMM step string).
- property unique_steps#
One step per model branch, in order of first appearance
- pytes.experiments.build_experiment_model(model, experiment, parameter_values)[source]#
Build the experiment version of a model: its controls become solver unknowns, fixed by the active step’s control residuals.
- Parameters:
model (
pytes.BaseModel) – The model, which is copied (not modified).experiment (
Experiment) – The experiment.parameter_values (
pybamm.ParameterValues) – The parameter values, which are copied (not modified).
- Returns:
model,parameter_values,branch_index,input_names– The new model and parameter values, the branch (1-based) of each step’sbranch_key, and the names of all the solver inputs the model needs.- Raises:
ValueError – If a step drives controls the model does not declare.
- pytes.experiments.run_experiment(model, experiment, parameter_values=None, var_pts=None, solver=None)[source]#
Run an experiment on a heat battery model.
- Parameters:
model (
pytes.BaseModel) – The model. It is not modified.experiment (
Experiment) – The steps to run.parameter_values (
pybamm.ParameterValues, optional) – Defaults to the model’s default parameter values. The controls in it are replaced by the steps.var_pts (
dict, optional) – Mesh points, as forpybamm.Simulation.solver (
pybamm.BaseSolver, optional) – Defaults to the model’s default solver (it must handle algebraic equations).
- Returns:
pybamm.Solution– The solution of the whole experiment. As for PyBaMM experiments,solution.cycles[i]holds the solution ofexperiment.cycles[i], andsolution.cycles[i].steps[j]that of its stepexperiment.cycles[i][j], with itstermination(the duration, or the termination condition that ended it). Steps whose termination condition already holds when they start are skipped, with a warning, and their place is held by apybamm.EmptySolution, as is that of a cycle whose steps are all skipped. If the solver fails during a step, the experiment stops there with a warning, and the solution up to the end of the previous step is returned (as for PyBaMM experiments).
Steps#
Steps of a heat battery experiment, run with pytes.experiments.run_experiment().
A model declares its controls (DESIGN D9); today they are the inlet temperature and the mass flow rate. Each step declares the controls it drives. In an experiment the controls are solver unknowns, and each step fixes them with one equation each (its control residuals): either by holding them at given values, or by adjusting one of them to hold the power. This follows the “unified” experiment mode of PyBaMM, so that the steps can move to PyBaMM’s own experiment framework once it supports models other than batteries.
The values a step holds can be constants, measured time series (a 2-column array of time since the start of the step [s] and value) or functions of the time since the start of the step [s]. Constant values are passed to the solver as inputs, so steps that only differ in their constant values share the same compiled model branch.
The steps are named after what they hold, as PyBaMM’s (pybamm.step.Current,
Power, Rest): Inlet holds the inlet conditions, Power the power
and Rest no flow. The power is positive when the battery delivers heat
(discharge), so a charge uses a negative power.
- pytes.experiments.step.START_TIME = InputParameter(-0x6f52209aa5404979, Step start time [s], children=[], domains={})#
Input parameter holding the time [s] at which the current step started
- pytes.experiments.step.DEFAULT_DURATION = 86400#
Default step duration [s] when neither a duration nor a time series sets it
- pytes.experiments.step.DEFAULT_PERIOD = 60#
Default time between output points [s]
- pytes.experiments.step.PREVIOUS_INLET_TEMPERATURE = InputParameter(-0x45d4629c0ed4e8f6, Inlet temperature at the end of the previous step [K], children=[], domains={})#
Input parameter holding the inlet temperature [K] at the end of the previous step, which a
Restholds by default
- class pytes.experiments.step.Termination(name, function)[source]#
Bases:
objectA condition that ends a step, used in addition to its duration.
- Parameters:
name (
str) – Name of the condition, used to report why a step ended.function (
callable) – Function of the model variables (a dict of symbols) returning an expression that is positive while the step should continue, and crosses zero when it should end.
- expression(variables)[source]#
The condition as an expression.
- Parameters:
variables (
dict) – Model variables.- Returns:
pybamm.Symbol– Positive while the step should continue; the step ends when it crosses zero.
- property key#
Identity of the condition, used to decide which steps share a model branch
- pytes.experiments.step.outlet_temperature_below(T)[source]#
End the step when the outlet temperature [K] falls below T
- pytes.experiments.step.outlet_temperature_above(T)[source]#
End the step when the outlet temperature [K] rises above T
- pytes.experiments.step.inlet_temperature_below(T)[source]#
End the step when the inlet temperature [K] falls below T
- pytes.experiments.step.inlet_temperature_above(T)[source]#
End the step when the inlet temperature [K] rises above T
- pytes.experiments.step.mass_flow_rate_above(mdot)[source]#
End the step when the mass flow rate [kg.s-1] rises above mdot
- pytes.experiments.step.average_liquid_fraction_below(phi)[source]#
End the step when the average liquid fraction falls below phi
- pytes.experiments.step.average_liquid_fraction_above(phi)[source]#
End the step when the average liquid fraction rises above phi
- class pytes.experiments.step.Target(name, value)[source]#
Bases:
objectA value held by a step: a constant, a 2-column time series (time since the start of the step [s], value) or a function of the time since the start of the step [s].
A time series is interpolated linearly, and its last value is held if the step lasts longer than the series (unlike PyBaMM drive cycles, which are repeated).
- Parameters:
name (
str) – Name of the quantity, e.g. “Inlet temperature [K]”.value (
float,numpy.ndarrayorcallable) – A constant, a 2-column array of time since the start of the step [s] (starting at 0) and value, or a function of the time since the start of the step [s] (apybamm.Symbol) returning a symbol.
- Raises:
ValueError – If a time series is not a 2-column array starting at time 0.
TypeError – If the value is none of the above.
- property input_name#
Name of the input parameter holding a constant value
- property key#
Identity, used to decide which steps share a model branch
- property initial_value#
Value at the start of the step, as a number
- property end_time#
Last time of a time series, or None
- class pytes.experiments.step.BaseStep(targets, duration=None, termination=None, period=None, description=None)[source]#
Bases:
objectBase class for experiment steps.
Subclasses declare the controls they drive (
controls), pass their targets to this constructor and implementcontrol_residuals().- Parameters:
duration (
float, optional) – Maximum duration of the step [s]. Defaults to the length of the step’s time series if it has one, otherwise one day.termination (
Terminationorlistofthem, optional) – Conditions that end the step before its duration.period (
float, optional) – Time between output points [s] (default 60 s).description (
str, optional) – Description of the step, used when reporting results.
- controls = ('Inlet temperature [K]', 'Mass flow rate [kg.s-1]')#
Names of the controls the step drives
- control_residuals(variables, targets, power)[source]#
Equations fixing the controls.
- Parameters:
variables (
dict) – Model variables, including the controls and “Power [W]”.targets (
dict) – The step’s target values as symbols, keyed by name.power (
callable) – The model’s power [W] with some controls replaced:power(controls), withcontrolsa dict of symbols keyed by control name (seepytes.BaseModel.power()).
- Returns:
dict– One residual per control incontrols, keyed by control name.
- termination_expression(variables)[source]#
Combined termination: positive while the step should continue
- property branch_key#
the same type, the same kind of targets (constant inputs, or the same time series) and the same terminations.
- Type:
Steps with the same key share a model branch
- class pytes.experiments.step.Inlet(inlet_temperature, mass_flow_rate, **kwargs)[source]#
Bases:
BaseStepHold the inlet conditions: the inlet temperature [K] and the mass flow rate [kg.s-1]. Each can be a constant, a time series or a function of time (see
Target).- Parameters:
inlet_temperature (
float,numpy.ndarrayorcallable) – Inlet temperature [K].mass_flow_rate (
float,numpy.ndarrayorcallable) – Mass flow rate through the whole device [kg.s-1]. For no flow, useRest.**kwargs –
duration,termination,periodanddescription, seeBaseStep.
- class pytes.experiments.step.Rest(inlet_temperature=None, **kwargs)[source]#
Bases:
BaseStepStop the flow: hold the mass flow rate at 0. The inlet temperature has no effect without flow, but the model still needs a value: by default the step holds it where the previous step left it (the initial temperature for a first step), so that the inlet temperature does not jump.
- Parameters:
inlet_temperature (
float,numpy.ndarrayorcallable, optional) – Inlet temperature [K] to hold instead (seeTarget).**kwargs –
duration,termination,periodanddescription, seeBaseStep.
- property holds_previous_inlet_temperature#
Whether the step holds the inlet temperature of the previous step
- class pytes.experiments.step.Power(power, *, inlet_temperature=None, mass_flow_rate=None, **kwargs)[source]#
Bases:
BaseStepHold the power [W] (positive for discharge) by adjusting the one control that is not given (DESIGN D10). Give exactly one of:
mass_flow_rate: the inlet temperature is adjusted. Useinlet_temperature_below()andinlet_temperature_above()to limit it.inlet_temperature: the mass flow rate is adjusted. Usemass_flow_rate_above()to limit it: the flow needed grows without bound as the outlet temperature approaches the inlet temperature. The step also ends if the mass flow rate would become negative.
- Parameters:
power (
float,numpy.ndarrayorcallable) – Power of the whole battery [W], positive for discharge and negative for charge.inlet_temperature (
float,numpy.ndarrayorcallable, optional) – Inlet temperature [K], held.mass_flow_rate (
float,numpy.ndarrayorcallable, optional) – Mass flow rate through the whole device [kg.s-1], held. Must not be 0: no power can be exchanged without flow.**kwargs –
duration,termination,periodanddescription, seeBaseStep.
- Variables:
adjusted (
str) – Name of the control the step adjusts.- Raises:
ValueError – If both controls or neither are given.