![]() |
SLIDE
3.0.0
A simulator for lithium-ion battery pack degradation
|
#include <Cycler.hpp>
Public Member Functions | |
Cycler ()=default | |
Cycler (StorageUnit *sui) | |
Cycler (StorageUnit *sui, const std::string &IDi) | |
Cycler (Deep_ptr< StorageUnit > &sui, const std::string &IDi) | |
Cycler & | initialise (StorageUnit *sui, const std::string &IDi) |
Cycler & | initialise (Deep_ptr< StorageUnit > &sui, const std::string &IDi) |
Cycler & | setDiagnostic (bool newDia) |
double | getSafetyVmin () |
#TODO probably causing many calculations. More... | |
double | getSafetyVmax () |
Status | rest (double tlim, double dt, int ndt_data, ThroughputData &th) |
Rest the storage unit for a given amount of time, ignoring voltage limits. More... | |
Status | CC (double I, double vlim, double tlim, double dt, int ndt_data, ThroughputData &th) |
Apply a constant current to the connected storage unit until either a voltage or time limit is reached. More... | |
Status | CV (double Vset, double Ilim, double tlim, double dt, int ndt_data, ThroughputData &th) |
Status | CCCV (double I, double Vset, double Ilim, double dt, int ndt_data, ThroughputData &th) |
Status | CCCV_with_tlim (double I, double Vset, double Ilim, double tlim, double dt, int ndt_data, ThroughputData &th) |
Status | Profile (std::span< double > I_vec, double vlim, double tlim, double dt, int ndt_data, double &Ah, double &Wh) |
int | storeData () |
int | writeData () |
double | testCapacity (double &Ah, double &ttot) |
double | testCapacity () |
StorageUnit * | getSU () |
|
default |
|
inline |
|
inline |
|
inline |
Status slide::Cycler::CC | ( | double | I, |
double | vlim, | ||
double | tlim, | ||
double | dt, | ||
int | ndt_data, | ||
ThroughputData & | th | ||
) |
Apply a constant current to the connected storage unit until either a voltage or time limit is reached.
I[in] | Current [A] to be applied (negative for charging, positive for discharging) |
vlim[in] | Voltage to which the cell should be (dis)charged (no check is done to ensure compatibility with the current) |
tlim[in] | Time [s] for which the current should be applied |
dt[in] | Time step [s] to be used for time integration |
ndt_data[in] | Integer indicating after how many time steps a data point should be stored (if <= 0, no data is stored) |
th[out] | ThroughputData object to store the charge and energy throughput |
100 | if time integration was stopped without the time or voltage limit reached |
< stop if we could not successfully set the current
< Variables
< length of time step i
< total time done
< consecutive number of time steps done without storing data
< number of time steps we take at once, will change dynamically
< increase nOnce if the voltage headroom is bigger than sfactor*dV (dV = change in this iteration)
< allow maximum this number of steps to be taken at once
< if we store data, never take more than the interval at which you want to store the voltage
< boolean indicating if vlim has been reached
< voltage in the previous/this iteration
< do we allow nOnce to increase?
< check the voltage limit
< charging -> exceeded if Vnew > vlim
< apply current
< change length of the time step in the last iteration to get exactly tlim seconds
< we are close to the total time -> set nOnce to 1
< the last time step, ensure we end up exactly at the right time
< take a number of time steps
< in diagnostic mode and the voltage of one of the cells was violated
< previously -4
< Increase the throughput
< Store a data point if needed
< charging -> exceeded if Vnew > vlim
< indicate the voltage limit was reached
< adapt the number of time steps we take at once
< if charging, voltage is increasing -> increase if dV < Vlim-V
< still far of, increase nOnce
< very close, immediately reset to 1 to avoid overshoot
< fairly close, reduce nOnce
< check the highest cell voltage, if it is close, reduce nOnce aggressively
< on discharge be careful with steep OCV change at low SoC
< add the *2 to reduce faster on discharge
< reduce by 2 to reduce faster
< check the lowest cell voltage, and if it is on the steep part, reduce nOnce aggressively
< this gets directly to the cell level, so we know for sure the value which matters is 3.1
< reduce nOnce
< block nOnce from increasing
< #TODO this are for cells? What about modules?
< this gets directly to the cell level, so we know for sure the value which matters is 3
< respect min and max
< update the voltage from the previous time step
< check why we stopped the time integration
Status slide::Cycler::CCCV | ( | double | I, |
double | Vset, | ||
double | Ilim, | ||
double | dt, | ||
int | ndt_data, | ||
ThroughputData & | th | ||
) |
< #TODO check all input parameters are sensible
Status slide::Cycler::CCCV_with_tlim | ( | double | I, |
double | Vset, | ||
double | Ilim, | ||
double | tlim, | ||
double | dt, | ||
int | ndt_data, | ||
ThroughputData & | th | ||
) |
< check all input parameters are sensible
< #TODO su Vmax and Vmin require lots of computation
< OCV larger than Vset so we need to discharge
< do the CC phase
Status slide::Cycler::CV | ( | double | Vset, |
double | Ilim, | ||
double | tlim, | ||
double | dt, | ||
int | ndt_data, | ||
ThroughputData & | th | ||
) |
< #TODO normally sign is very sensitive function
< *************************************************************** INITIALISE ************************************************************************* store data point
< check if we are already at the limit
< voltage and current in the previous and present time step
< ******************************************************* apply voltage ****************************************************************************
< number of time steps
< length of time step i
< total time done
< boolean indicating if Ilim has been reached
< boolean indicating if the voltage tolerance was reached
< change in current we will apply to keep the voltage constant
< change length of the time step in the last iteration to get exactly tlim seconds
< take a time step
< Store a data point if needed
< check the current limit
< indicate the current limit was reached
< indicate the current limit was reached
< but without reaching the voltage tolerance
< *********************************************************** TERMINATE ****************************************************************************** check why we stopped the time integration
< time limit
< #TODO why a bool named Itot? It looks like double.
< current limit
< #TODO is this ever possible? current became way too small, but voltage limit still not reached
|
inline |
|
inline |
#TODO probably causing many calculations.
|
inline |
|
inline |
Cycler & slide::Cycler::initialise | ( | StorageUnit * | sui, |
const std::string & | IDi | ||
) |
Status slide::Cycler::Profile | ( | std::span< double > | I_vec, |
double | vlim, | ||
double | tlim, | ||
double | dt, | ||
int | ndt_data, | ||
double & | Ah, | ||
double & | Wh | ||
) |
Status slide::Cycler::rest | ( | double | tlim, |
double | dt, | ||
int | ndt_data, | ||
ThroughputData & | th | ||
) |
Rest the storage unit for a given amount of time, ignoring voltage limits.
This function allows the storage unit to rest for a specified time duration, tlim. Voltage limits are not considered during this period. Data points are stored according to the specified ndt_data parameter.
[in] | tlim | Time (in seconds) for which the storage unit should rest. |
[in] | dt | Time step (in seconds) to be used for time integration. |
[in] | ndt_data | Integer indicating after how many time steps a data point should be stored. If <= 0, no data is stored. Otherwise, a data point is guaranteed at the beginning and end of this function, and between those, a data point is added every ndt_data*dt seconds. |
[out] | th | throughput data. |
100 | Time integration was stopped without the time or voltage limit being reached. |
< store data point
< Variables
< length of time step i
< total time done
< consecutive number of time steps done without storing data
< number of time steps we take at once, will change dynamically
< allow maximum this number of steps to be taken at once careful with thermal stability. Thermal model only calculated every nOnce*dt so that can be in the unstable region for large batteries with cooling systems so don't have nOnceMax above 10 (even though once everything is in equilibrium, you could take much larger steps)
< can nonce increase this iteration?
< if we store data, never take more than the interval at which you want to store the voltage
< apply current
< set current. It makes the code more stable to do this every iteration. parallel module::setCurrent will reset all currents to 0 and only allow minor variations to equalise the voltage if you don't cell setCurrent, then timeStep will call redistributeCurrent, which can incrementally increase cell currents causing them to diverge. (e.g. I1 = 3A and I2 = -3A)
< do not check voltagel limits, but print error warnings std::cout << getStatusMessage(succ) << '
';
< we are close to the total time -> set nOnce to 1
< the last time step, ensure we end up exactly at the right time
< take a number of time steps
< Store a data point if needed
< getting close to the end
< increase every other iteration, else thermal model might freak out
< e.g. rest after cycle -> cell needs to cool down before you can take very long time steps
< #TODO Increasing nOnce will cause not saving data regularly. We are probably not saving data every ndata_step
< respect min and maximum
< check why we stopped the time integration
< there is no throughput during resting
Cycler & slide::Cycler::setDiagnostic | ( | bool | newDia | ) |
int slide::Cycler::storeData | ( | ) |
|
inline |
double slide::Cycler::testCapacity | ( | double & | Ah, |
double & | ttot | ||
) |
< use a 2 second time step for accuracy (probably 5 would be fine as well)
< #TODO if it is avoidable.
< #TODO once we introduce a different temperature, set T to Tref
< *********************************************************** 2 full charge / discharge cycle ***********************************************************************
< fully charge and discharge the cell
< fully charge battery to its specified maximum voltage )
< restore the original states
< restore the original states
int slide::Cycler::writeData | ( | ) |
< reset the index.