![]() |
SLIDE
3.0.0
A simulator for lithium-ion battery pack degradation
|
Functions | |
bool | Cell_Bucket_test () |
bool | getStates_test () |
bool | getV_test () |
bool | getParent_test () |
bool | setCurrent_test () |
bool | setT_test () |
bool | setSOC_test () |
bool | setStates_test () |
bool | timeStep_CC_test () |
bool | data_test () |
bool | Copy_test () |
int | test_all_Cell_Bucket () |
bool | test_constructor_ECM () |
bool | test_getStates_ECM () |
bool | test_getV_ECM () |
bool | test_setStates_ECM () |
bool | test_validStates_ECM () |
bool | test_timeStep_CC_ECM () |
int | test_all_Cell_ECM () |
bool | test_constructor_SPM () |
bool | test_getStates_SPM () |
bool | test_getV_SPM () |
bool | test_setStates_SPM () |
bool | test_timeStep_CC_SPM () |
int | test_all_Cell_SPM () |
bool | testLosses () |
int | test_all_Converter () |
bool | test_CyclerSU (StorageUnit *su, bool testCV) |
template<typename Cell_t > | |
bool | test_CyclerCell () |
bool | test_CyclerVariations (double Rc) |
bool | test_Cycler_writeData (int control) |
bool | test_Cycler_CoolSystem () |
int | test_all_Cycler () |
bool | test_Constructor_p () |
bool | test_BasicGetters_p () |
bool | test_setI_p () |
bool | test_validStates_p () |
bool | test_timeStep_CC_p () |
template<typename Cell_t > | |
bool | test_Modules_p () |
bool | test_contactR () |
bool | test_Hierarchichal_p () |
bool | test_Hierarchical_cross_p () |
bool | test_copy_p () |
bool | test_equaliseV_timing (Deep_ptr< Module_p > &mp, Deep_ptr< StorageUnit > c[], int nin) |
bool | test_equaliseV () |
int | test_all_Module_p () |
bool | test_BasicGetters () |
< ********************************************************** test functions from Module_base ******************************************************************* More... | |
bool | test_getCellV () |
bool | test_getStates () |
bool | test_getCells () |
bool | test_setT () |
bool | test_setStates () |
bool | test_setCells () |
********************************************************* test functions from Module_base_s ******************************************************************* More... | |
bool | test_Constructor () |
bool | test_BasicGetters_s () |
bool | test_setI () |
bool | test_validStates () |
bool | test_validCells () |
bool | test_timeStep_CC () |
template<typename Cell_t > | |
bool | test_Modules_s () |
bool | test_Hierarchichal () |
bool | test_Hierarchical_Cross () |
bool | test_copy_s () |
bool | test_CoolSystem_s () |
***************************************************************** test all functions ************************************************************************* More... | |
int | test_all_Module_s () |
bool | test_Procedure_cycleAge (double Rc, bool spread, int cool) |
bool | test_Procedure_CoolSystem () |
bool | test_Procedure_cycleAge_stress () |
bool | test_degradationModel (bool capsread, bool Rspread, bool degspread, DEG_ID deg, int cool) |
bool | test_allDegradationModels (int cool) |
int | test_all_Procedure () |
bool slide::tests::unit::Cell_Bucket_test | ( | ) |
< test the constructors
bool slide::tests::unit::Copy_test | ( | ) |
< dynamic cast c2 back to a cell
< Dynamic cast from smart pointer of StorageUnit to regular pointer of Cell
< now try with a changed SOC
< dynamic cast c2 back to a cell
< Dynamic cast from StorageUnit to Cell
< now change c22 and double check c1 hasn't changed
bool slide::tests::unit::data_test | ( | ) |
< slowly charge while storing data
< double tol = 0.002;
< store a data point every time step
< c1.writeData(pref);
bool slide::tests::unit::getParent_test | ( | ) |
bool slide::tests::unit::getStates_test | ( | ) |
< soc
< T
< current
bool slide::tests::unit::getV_test | ( | ) |
< normal cell, should give no errors
< cell with SOC out of range
< make a cell with soC equal to 1
< charge further for one hour, now the SOC should be close to 2
bool slide::tests::unit::setCurrent_test | ( | ) |
< set I without checking the voltage is valid
< setCurrent with a valid voltage
< without optional arguments
bool slide::tests::unit::setSOC_test | ( | ) |
< set I without checking the voltage is valid
< setCurrent with a valid voltage
< without optional arguments
bool slide::tests::unit::setStates_test | ( | ) |
< set valid new states
< soc
< T
< current
< set invalid states
< set states which violate voltage
bool slide::tests::unit::setT_test | ( | ) |
int slide::tests::unit::test_all_Cell_Bucket | ( | ) |
int slide::tests::unit::test_all_Cell_ECM | ( | ) |
< if we test the errors, suppress error messages
int slide::tests::unit::test_all_Cell_SPM | ( | ) |
< calls all test-functions
int slide::tests::unit::test_all_Converter | ( | ) |
int slide::tests::unit::test_all_Cycler | ( | ) |
int slide::tests::unit::test_all_Module_p | ( | ) |
< parallel from ECM cells
< parallel from SPM cells
< parallel from parallel
< parallel from series
int slide::tests::unit::test_all_Module_s | ( | ) |
< if we test the errors, suppress error messages
< includes setState
< (includes validCells)
< Combinations
< series of series
< series of parallel
< coolsystem (includes hierarchical modules and uses SPM cells)
int slide::tests::unit::test_all_Procedure | ( | ) |
< Test normal procedures, with and without contact resistance and CV phases
< test with two different values for contact resistance
< no contact resistance, no cell-to-cell variation
< 0.2 mOhm contact resistance, with cell-to-cell variation
< test with large variation of cells in P module
< Test the cooling system
< Test various degradation models
< test them all
< test a specific model
< kinetic SEI and porosity, with Dai/Laresgoiti LAM
bool slide::tests::unit::test_allDegradationModels | ( | int | cool | ) |
< kinetic SEI
< kinetic SEI from paper
< kinetic SEI + porosity
< kinetic SEI from paper + porosity
< reset SEI
< DAI + Laresgoiti LAM
< Delacourt LAM [linear with Ah]
< Kindermann LAM
< Kindermann LAM + SEI
< Kindermann LAM + SEI + porosity
< SEI + Ekstrom cracks
< SEI + Laresgoiti cracks (pure laresgoiti, i.e. with the simplified stress model)
bool slide::tests::unit::test_BasicGetters | ( | ) |
< ********************************************************** test functions from Module_base *******************************************************************
bool slide::tests::unit::test_BasicGetters_p | ( | ) |
< has no parent yet
bool slide::tests::unit::test_BasicGetters_s | ( | ) |
bool slide::tests::unit::test_Constructor | ( | ) |
< Module_base_s::Module_base_s() Module_base_s::Module_base_s(int ncellsi, Cell_Bucket ci[], double Ti, bool checkCells, bool print)
< has no parent yet
< note: you have to make a new module, else the getParent() fails I made an m before, so &m points to the first module_s made
bool slide::tests::unit::test_constructor_ECM | ( | ) |
bool slide::tests::unit::test_Constructor_p | ( | ) |
< has no parent yet
bool slide::tests::unit::test_constructor_SPM | ( | ) |
bool slide::tests::unit::test_contactR | ( | ) |
< total resistance: -Rp+-Rp-+-Rp-| | | | Rs Rs Rs where Rp = contact resistance (value Rc) and Rs = cell resistance = 0.01;
< resistance of last two branches
< setCurrent check voltages at each node from the branch going 'down' and the branch going 'right' R1*I1 = Rp2*(I2 + I3) + R2*I2 R2*I2 = (Rp3 + R3)*I3 where Ri = resistance of cell i Rpi = contact resistance in parallel at cell i since all cells have the same OCV
< assert the currents of cells further from the terminal are smaller
< Check the voltage at every node
< all cell resistances are the same
< voltage at the node connecting the first cell, going down [ignoring OCV]
< voltage at the node connecting the first cell, going right
< double V13 = Rcs[1] * (I2 + I3) + Rcs[2]*I3 + Rcell*I3;
< voltage at node of 2nd cell going down
< voltage at node of 2nc cell going right
< check the total voltage
< set charging current
< all cell resistances are the same
< voltage at the node connecting the first cell, going down [ignoring OCV]
< voltage at the node connecting the first cell, going right
< voltage at node of 2nd cell going down
< voltage at node of 2nc cell going right
bool slide::tests::unit::test_CoolSystem_s | ( | ) |
***************************************************************** test all functions *************************************************************************
< Parameters from Cell_SPM which are needed to calculate the heat balance
< thickness of one layer
< width of the pouch
< height of the pouch
< number of layers in the pouch
< geometric surface area of the pouch
< total 'unrolled' surface area of the electrodes
< General settings
< number of steps per charge / discharge / rest
< Loop for each setting of the cool controller
< **************************************************************************************************************************************************** Make a simple module with one SPM cell cout<<"module_s_test start coolsystem test with a single cell for cool control setting "<<coolControl<<endl;
< do a few 1C cycles (note just some time steps since we don't have the Cycler
< charge
< rest
< discharge
< rest
< total heat generated by cells
< total heat extracted by the coolsystem from the cells
< total energy in heating up the cells
< cout<<"\t Total heat balance of coolsystem single cell "<<coolControl<<" is "<<Qgen<<", "<<Qheat<<", "<<Qcool<<" and error "<
< ********************************************************************************************************************************************************** Make a simple module with SPM cells cout<<"module_s_test start coolsystem test with a simple module for cool control setting "<<coolControl<<endl;
< do a few 1C cycles (note just some time steps since we don't have the Cycler
< charge
< rest
< discharge
< rest
< total heat generated by cells
< total heat extracted by the coolsystem from the cells
< total energy in heating up the cells
< cout<<"\t Total heat balance of coolsystem simple module "<<coolControl<<" is "<<Qgen2<<", "<<Qheat2<<", "<<Qcool2<<" and error "<
< ****************************************************************************************************************************************************** make the hierarchical module cout<<"Module_s_test start coolsystem test with a complex module for cool control setting "<<coolControl<<endl;
< middle level modules are pass through
< pass through cool system
< do a few 1C cycles (note just some time steps since we don't have the Cycler
< charge
< rest
< discharge
< rest
< check balance of module mp11
< total heat generated by cells
< total heat extracted by the coolsystem from the cells
< total energy in heating up the cells
< check balance of module mp22
< total heat generated by cells
< total heat extracted by the coolsystem from the cells
< total energy in heating up the cells
< check balance of module mp33
< total heat generated by cells
< total heat extracted by the coolsystem from the cells
< total energy in heating up the cells
< check balance of the top level module
< check balance of total system
< cout<<"\t Total heat balance of coolsystem complex module "<<coolControl<<" is "<<Qgen3<<", "<<Qheat3<<", "<<Qcool3<<" and error "<
< Comparison of cool system performance in the different control strategies: print out the following statement cout<<"Total heat balance of coolsystem complex module "<<coolControl<<" is "<<Qgen3<<", "<<Qheat3<<", "<<Qcool3<<" and error "<
bool slide::tests::unit::test_copy_p | ( | ) |
< /*
< make module #TODO copy functions are commented out.
< copy this one and check they are identical
< Dynamic cast from StorageUnit to Cell
< change the copied version, and ensure the old one is still the same
< discharge
bool slide::tests::unit::test_copy_s | ( | ) |
< /*
< //!< make module
auto cp1 = make<Cell_Bucket>(); auto cp2 = make<Cell_Bucket>(); Deep_ptr<StorageUnit> cs[] = {cp1, cp2}; std::string n = "na"; double v1 = cp1->V(); double T = settings::T_ENV; bool checkCells = false; auto mp = make<Module_s>(n, T, true, false, std::size(cs), 1, 1); mp->setSUs(cs, checkCells, true);
< //!< copy this one and check they are identical Deep_ptr<StorageUnit> cn = mp->copy(); Module_s *c22 = dynamic_cast<Module_s *>(cn.get()); //!< Dynamic cast from StorageUnit to Cell_Bucket assert(mp->V() == c22->V()); Deep_ptr<StorageUnit> corig[], cnew[];
mp->getSUs(corig); c22->getSUs(cnew); for (int i = 0; i < mp->getNSUs(); i++) assert(corig[i]->V() == cnew[i]->V());
< //!< change the copied version, and ensure the old one is still the same c22->setCurrent(1 * std::size(cs), false, false); //!< discharge for (int t = 0; t < 10; t++) c22->timeStep_CC(2); mp->getSUs(corig); c22->getSUs(cnew); for (int i = 0; i < mp->getNSUs(); i++) { assert(corig[i]->V() == v1); assert(cnew[i]->V() < v1); }
bool slide::tests::unit::test_Cycler_CoolSystem | ( | ) |
< Parameters from Cell_SPM which are needed to calculate the heat balance
< thickness of one layer
< width of the pouch
< height of the pouch
< number of layers in the pouch
< geometric surface area of the pouch
< total 'unrolled' surface area of the electrodes
< General settings
< Loop for each setting of the cool controller
< **************************************************************************************************************************************************** Make a simple module with one SPM cell
< do a few 1C cycles
< charge
< CC discharge
< check the energy balance of the outer module
< total heat generated by cells
< total heat extracted by the coolsystem from the cells
< total energy in heating up the cells
< cout<<"Total heat balance of coolsystem single cell "<<coolControl<<" is "<<Qgen<<", "<<Qheat<<", "<<Qcool<<" and error "<
< do a few 1C cycles (note just some time steps since we don't have the Cycler
< charge
< CC discharge
< check the energy balance of the outer module
< total heat generated by cells
< total heat extracted by the coolsystem from the cells
< total energy in heating up the cells
< cout<<"Total heat balance of coolsystem simle module "<<coolControl<<" is "<<Qgen2<<", "<<Qheat2<<", "<<Qcool2<<" and error "<
< do a few 1C cycles (note just some time steps since we don't have the Cycler
< charge
< CC discharge
< check balance of module mp11
< total heat generated by cells
< total heat extracted by the coolsystem from the cells
< total energy in heating up the cells
< cout<<"Total heat balance of coolsystem complex module 1 "<<coolControl<<" is "<<Qgen3<<", "<<Qheat3<<", "<<Qcool3<<" and error "<
< check balance of module mp22
< total heat generated by cells
< total heat extracted by the coolsystem from the cells
< total energy in heating up the cells
< cout<<"Total heat balance of coolsystem complex module 2 "<<coolControl<<" is "<<Qgen3<<", "<<Qheat3<<", "<<Qcool3<<" and error "<
< check balance of module mp33
< total heat generated by cells
< total heat extracted by the coolsystem from the cells
< total energy in heating up the cells
< cout<<"Total heat balance of coolsystem complex module 3 "<<coolControl<<" is "<<Qgen3<<", "<<Qheat3<<", "<<Qcool3<<" and error "<
< check balance of the top level module
< cout<<"Total heat balance of coolsystem complex module top "<<coolControl<<" is "<<Qgen3<<", "<<Qheat3<<", "<<Qcool3<<" and error "<
< check balance of total system
< Comparison of cool system performance in the different control strategies: print out the following statement cout<<"Total heat balance of coolsystem complex module entire "<<coolControl<<" is "<<Qgen3<<", "<<Qheat3<<", "<<Qcool3<<" and error "<
bool slide::tests::unit::test_Cycler_writeData | ( | int | control | ) |
< complex modules have larger under- and overshoot due to the larger numbers involved
< ******************************************************* test a single cell doing a single CCCV cycle *********************************************
< store data every 2 seconds (or every dt)
< CCCV charge
< CCCV discharge
< write the data
< ******************************************************* test three cells in a module doing lots of cycles *********************************************
< chirstensen SEI growth
< don't decrease the porosity (set to 1 if you do want to decrease the porosity)
< no surface cracks
< don't decrease the diffusion coefficient (set to 1 if you do want to decrease the diffusion)
< no LAM
< no litihium plating
< check that the middle cell heats up more
< do 100 cycles
< CCCV charge
< CCCV discharge
bool slide::tests::unit::test_CyclerCell | ( | ) |
< Cells can't do a CV phase since they have no diffusion the resistive effect is much to quick for the PI controller in Cycler
< test cell cout<<"Test cycler made of one Cell"<<endl;
< test series of cell cout<<"Test cycler made of a series module of Cells"<<endl;
< test parallel of cells cout<<"Test cycler made of a parallel module of Cells"<<endl;
< test complex module cout<<"Cycler test complex module of Cells"<<endl;
< three module_p in series
< note the capacity of this module will be larger than the parallel module getCapacity (dis)charges to the voltage limit of the total module (so in this case 3*cell voltage) The 2 modules with 2 cells will reach their voltage limit after 2*cell capacity but the 3rd module has three cells, so it will not have reached its voltage limit yet so the overall module won't have reached its voltage limit and you keep (dis)charging and then the overall module reaches its voltage limit after > 2 * cell capacity, the first two will be over(dis)charged so the capacity check with and without diagnostic will give a different result
bool slide::tests::unit::test_CyclerSU | ( | StorageUnit * | su, |
bool | testCV | ||
) |
< complex modules have larger under- and overshoot due to the larger numbers involved
< use a 1C rate
< CC charge cout<<"\t CC charge"<<endl<<flush;
< CC charge must do a slight overshoot
< rest for 1h to relax cout<<"\t resting 1h after CC charge for SU "<<su->getFullID()<<endl;
< rest for 10h and check the voltage does not change cout<<"\t resting 10h after CC charge for SU "<<su->getFullID()<<endl;
< CC discharge cout<<"\t CC discharge"<<endl<<flush;
< CC discharge must do a slight overshoot
< rest for 1h to relax cout<<"\t resting 1h after CC discharge for SU "<<su->getFullID()<<endl;
< rest for 10h and check the voltage does not change cout<<"\t resting 10h after CC discharge for SU "<<su->getFullID()<<endl;
< CC cycle for a specified time
< note: this brings the complex module from SPM cells close to their minimum voltage (because not all sub-modules take the same current the charge-discharge is not symmetric) so if cells are cooled below 20 degrees, this test fails since we reach the minimum voltage just before the time limit
< CCCV charge cout<<"\t CCCV charge"<<endl<<flush;
< cout<<"\t \t starting CC phase"<<endl<<flush;
< CC charge must do a slight overshoot
< cout<<"\t \t terminating CC phase"<<endl<<flush;
< cout<<"\t \t starting CV phase"<<endl<<flush;
< CV charge must do a slight overshoot
< cout<<"\t \t terminating CV phase with "<<succ<<"\t"<<su->V()<<"\t"<<su->I()<<endl<<flush;
< rest for 1h to relax cout<<"\t resting 1h after CCCV charge for SU "<<su->getFullID()<<endl;
< rest for 10h and check the voltage does not change cout<<"\t resting 10h after CCCV charge for SU "<<su->getFullID()<<endl;
< CCCV discharge cout<<"\t CCCV discharge"<<endl<<flush;
< CC charge must do a slight overshoot
< CV discharge must do a slight overshoot
< cout<<"\t \t terminating CV phase with "<<succ<<"\t"<<su->V()<<"\t"<<su->I()<<" and voltage error "<<abs(su->V()-vlim) <<endl<<flush;
< rest for 1h to relax cout<<"\t resting 1h after CCCV discharge for SU "<<su->getFullID()<<endl;
< rest for 10h and check the voltage does not change cout<<"\t resting 10h after CCCV discharge for SU "<<su->getFullID()<<endl;
< getCapacity cout<<"\t getCapacity 1"<<endl<<flush;
< check we are close to the nominal capacity, i.e. error < 15%
< get the capacity while ignoring degradation
< charge to get in the valid voltage region
< cout<<"\t capacity measurements: "<<cap<<"\t"<<cap2<<"\t"<<cap3<<"\t for nominal capacity "<<su->Cap()<<endl; // assert(std::abs(cap-cap3) < tol); //!< get the capacity while stopping when one cell reached the voltage limit this should fail for a complex hierarchial module (see testCyclerSPM)
bool slide::tests::unit::test_CyclerVariations | ( | double | Rc | ) |
< cout<<"start test with cell-to-cell variations with contact resistance "<<Rc<<endl;
< cell-to-cell variations
< normal distribution with mean 1 and std 0.4% for cell capacity
< normal distribution with mean 1 and std 2.5% for cell resistance
< normal distribution with mean 1 and std 2.5% for cell degradation rate
< degradation
< chirstensen SEI growth
< don't decrease the porosity (set to 1 if you do want to decrease the porosity)
< no surface cracks
< don't decrease the diffusion coefficient (set to 1 if you do want to decrease the diffusion)
< no LAM
< no litihium plating
< Make a parallel module with 9 cells, and contact resistance Rc
< no multithreading, nt_Vcheck time steps between checking SU voltage
< call the test function
< don't do CV phases
bool slide::tests::unit::test_degradationModel | ( | bool | capsread, |
bool | Rspread, | ||
bool | degspread, | ||
DEG_ID | deg, | ||
int | cool | ||
) |
< name of files
< Settings
< Control printing
< if true, less stuff is printed
< normal distribution with mean 1 and std 0.4% for cell capacity
< normal distribution with mean 1 and std 2.5% for cell resistance
< normal distribution with mean 1 and std 2.5% for cell degradation rate
< Make the procedure with standard settings
< 1 CC cycle takes about 0.5 min
< do a checkup ever 100 cycles
< balance every 10 cycles
< test with series module
< no multithreading
< test with parallel module
< no multithreading, nt_Vcheck time steps between checking SU voltage
bool slide::tests::unit::test_equaliseV | ( | ) |
< test timing with 5 identical cells 5 cells with minor differences 5 widely different cells 4 similar and one aged cell
< chirstensen SEI growth
< don't decrease the porosity (set to 1 if you do want to decrease the porosity)
< no surface cracks
< don't decrease the diffusion coefficient (set to 1 if you do want to decrease the diffusion)
< no LAM
< no litihium plating
< 5 identical cells
< no multithreading, nt_Vcheck time steps between checking SU voltage
< 5 cells with small distribution
< normal distribution with mean 1 and std 0.4% for cell capacity
< normal distribution with mean 1 and std 2.5% for cell resistance
< normal distribution with mean 1 and std 2.5% for cell degradation rate
< no multithreading, nt_Vcheck time steps between checking SU voltage
< 5 cells with large distribution
< normal distribution with mean 1 and std 0.4% for cell capacity
< normal distribution with mean 1 and std 2.5% for cell resistance
< normal distribution with mean 1 and std 2.5% for cell degradation rate
< no multithreading, nt_Vcheck time steps between checking SU voltage
< 4 similar and one very different
< one with half the capacity and double the resistance
< no multithreading, nt_Vcheck time steps between checking SU voltage
bool slide::tests::unit::test_equaliseV_timing | ( | Deep_ptr< Module_p > & | mp, |
Deep_ptr< StorageUnit > | c[], | ||
int | nin | ||
) |
< test timing IN mp parallel module SUs array with smart pointers to the children of mp
< ignore thermal and degradation during this function (we mess with individual cells time time keeping for thermal gives errors)
< set a 1C current to the individual cells, then redistribute
< current per cell
< take 10 time steps, then redistribute again
< go to low SOC (lowest cell voltage is 3V
< take 10 time steps, then redistribute again
< Use a Cycler to do a full CC cycle with redistributeCurrent every time step
< CC charge
< CC discharge
bool slide::tests::unit::test_getCells | ( | ) |
< original states
< states of returned cells
< change cell 2 to verify the order is correct
< returns storage units, not cells. So getStates is the implementation from SU not Cell_Bucket
< this is SU::getStates, not Cell_Bucket::getStates
< validate cell states
< Set the current, ensure it has changed in the cells
< charge
bool slide::tests::unit::test_getCellV | ( | ) |
< Module_base::getCellVotages
< change cell 2 to verify the order is correct
bool slide::tests::unit::test_getStates | ( | ) |
< bool Module_base::getStates(double s[], int nin, int& nout)
< change cell 2 to verify the order is correct
bool slide::tests::unit::test_getStates_ECM | ( | ) |
< soc
< Ir
< T
< current
< #TODO this must throw an error
bool slide::tests::unit::test_getStates_SPM | ( | ) |
< bool getStates(double s[], int nin, int&nout);
< 0 to nch = zp nch to 2*nch = zn
< allow slightly larger error since we approximated all elements of the initial array and matrix
< concentration ~ 10,000 so 0.1 is still a relative error of e-5
bool slide::tests::unit::test_getV_ECM | ( | ) |
< double V(bool print = true); //!< crit is an optional argument
< normal cell, should give no errors
< set to charging and check the voltage has increased
< set to discharge
bool slide::tests::unit::test_getV_SPM | ( | ) |
< normal cell, should give no errors
< set to charging and check the voltage has increased
< set to discharge
bool slide::tests::unit::test_Hierarchical_Cross | ( | ) |
< test series-modules made out of parallel-modules
< make the hierarichical series-module
< pass through cool systems
< set a CC current
< no longer exact since it involves parallel modules
< 2nd module has 2 cells, so current should split in 2
< 3rd module has 3 cells, so current should split in 3
< time a CC time step
< the SOC must have increased (check just 1 cell out of all 7)
bool slide::tests::unit::test_Hierarchical_cross_p | ( | ) |
< test parallel module made out of series modules note: series modules must have same number of cells to get the same voltage
< pass through cool systems
< make the hierarichical module
< one module has 2 cells so voltage should split in 2
< set a CC current
< should give about 2A per cell
< m1 has two cells
< m3 has two cells
< check voltage is equal
< time a CC time step
< submodules must have same voltage note: there is no check on sub-modules with different SOC but I assume that works since it works with sub-cells of different SOC
bool slide::tests::unit::test_Hierarchichal | ( | ) |
< test series modules made out of other series modules
< middle level modules are pass through
< pass through cool systems
< make the hierarichical module
< set a CC current
< time a CC time step
< the SOC must have increased (check just 1 cell out of all 7)
bool slide::tests::unit::test_Hierarchichal_p | ( | ) |
< test parallel modules made out of other parallel modules
< pass through cool systems
< make the hierarichical module
< set a CC current
< should give about 2A per cell
< time a CC time step
< the SOC must have increased (check just 1 cell out of all 7)
< submodules must have same voltage
bool slide::tests::unit::test_Modules_p | ( | ) |
< test parallel modules with ECM cells
< setCurrent
< discharge
< voltage must decrease
< do not check individual cells, that is done in getCells charge
< voltage must increase
< rest with different SOC values -> must be different lithium fractions since SOC does not affect the concentration too complicated so skip this test here
< validCells
< valid cells with the current cells
< CC timestep
< time step with 0 current
< discharge
< note: this is not going to be exact because we solve a nonlinear equation to obain I
< check individual cells
< we know the current has to split equally between both cells
< Dynamic cast from StorageUnit to Cell
< we know the current has to split equally between both cells
< Dynamic cast from StorageUnit to Cell
bool slide::tests::unit::test_Modules_s | ( | ) |
< test series modules make out of ECM cells this just repeats the other tests but with a different Cell_Bucket type
< getStates - setStates
< change cell 2 to verify the order is correct
< change SOC of a cell
< change T
< mp->setStates invoked cp2->setStates, so also c2 should have changed
< reset the tenperature, else the thermal model in timeStep will freak out
< getCells - setCells
< timeStep_CC
< time step with 0 current
< discharge
< check individual cells
< Dynamic cast from StorageUnit to Cell_Bucket
< Dynamic cast from StorageUnit to Cell_Bucket
bool slide::tests::unit::test_Procedure_CoolSystem | ( | ) |
< Parameters from Cell_SPM which are needed to calculate the heat balance
< thickness of one layer
< width of the pouch
< height of the pouch
< number of layers in the pouch
< geometric surface area of the pouch
< total 'unrolled' surface area of the electrodes
< settings of the cycle age
< General settings
< controls printing for cycle age, should be true unless for debugging
< Loop for each setting of the cool controller
< **************************************************************************************************************************************************** Make a simple module with one SPM cell
< Use procedure age to cycle it cout<<"Procedure_test start coolsystem test with a single cell for cool control setting "<<coolControl<<endl;
< include CV phase
< check the energy balance of the outer module
< total heat generated by cells
< total heat extracted by the coolsystem from the cells
< total energy in heating up the cells
< ********************************************************************************************************************************************************** Make a simple module with SPM cells
< Use procedure age to cycle it cout<<"Procedure_test start coolsystem test with a simple module for cool control setting "<<coolControl<<endl;
< exclude CV phase, CC only
< check the energy balance of the outer module
< total heat generated by cells
< total heat extracted by the coolsystem from the cells
< total energy in heating up the cells
< ****************************************************************************************************************************************************** make the hierarchical module
< constexpr size_t ncel33 = 3; -> gives problems with voltage limits in cycleAge so skip for now. this unit test focuses on thermal model which does not depend on different sized modules
< Use procedure age to cycle it cout<<"Procedure_test start coolsystem test with a complex module for cool control setting "<<coolControl<<endl;
< exclude CV phase, CC only
< check balance of module mp11
< total heat generated by cells
< total heat extracted by the coolsystem from the cells
< total energy in heating up the cells
< check balance of module mp22
< total heat generated by cells
< total heat extracted by the coolsystem from the cells
< total energy in heating up the cells
< check balance of module mp33 Qgen3 = cp55->thermal_getTotalHeat() + cp66->thermal_getTotalHeat() + cp77->thermal_getTotalHeat(); //!< total heat generated by cells
< total heat generated by cells
< total heat extracted by the coolsystem from the cells
< Qheat3 = -((Tini22[4] - cp55->T()) * (rho*Cp*L*elec_surf) + (Tini22[5] - cp66->T()) * (rho*Cp*L*elec_surf)+ (Tini22[6] - cp77->T()) * (rho*Cp*L*elec_surf)); //!< total energy in heating up the cells
< total energy in heating up the cells
< check balance of the top level module
< check balance of total system
< Qgen3 += cp55->thermal_getTotalHeat() + cp66->thermal_getTotalHeat() + cp77->thermal_getTotalHeat();
< Qheat3 += -((Tini22[4] - cp55->T()) * (rho*Cp*L*elec_surf) + (Tini22[5] - cp66->T()) * (rho*Cp*L*elec_surf)+ (Tini22[6] - cp77->T()) * (rho*Cp*L*elec_surf));
< Comparison of cool system performance in the different control strategies: print out the following statement cout<<"Total heat balance of coolsystem complex module entire "<<coolControl<<" is Qgen = "<<Qgen3<<", Qheat = "<<Qheat3<<", Qcool = "<<Qcool3<<" and error "<
bool slide::tests::unit::test_Procedure_cycleAge | ( | double | Rc, |
bool | spread, | ||
int | cool | ||
) |
< Settings
< normal distribution with mean 1 and std 0.4% for cell capacity
< normal distribution with mean 1 and std 2.5% for cell resistance
< normal distribution with mean 1 and std 2.5% for cell degradation rate
< Make the procedure with standard settings
< test with SPM cell
< WITH CV -> 1C CCCV cycling
< just check this runs without producing an error warning
< test with series module
< no multithreading
< this should write a file called s_module_capacities.csv check that all cells age more or less the same the capacity of the string should be the capacity of the smallest cell
< test with Battery from parallel module
< no multithreading, nt_Vcheck time steps between checking SU voltage
< this should write a file called p_module_capacities.csv
< check the document with the capacities if contact resistance is not zero, then cells with higher numbers (right columns) should have more remaining capacities than cells with low numbers (left columns) if Rc == 0, all cells should have more or less the same capacity
bool slide::tests::unit::test_Procedure_cycleAge_stress | ( | ) |
< 5 widely different cells 4 similar and one aged cell
< 5 cells with large distribution
< normal distribution with mean 1 and std 0.4% for cell capacity
< normal distribution with mean 1 and std 2.5% for cell resistance
< normal distribution with mean 1 and std 2.5% for cell degradation rate
< no multithreading, nt_Vcheck time steps between checking SU voltage
< 4 similar and one very different
< normal distribution with mean 1 and std 0.4% for cell capacity
< normal distribution with mean 1 and std 2.5% for cell resistance
< normal distribution with mean 1 and std 2.5% for cell degradation rate
< one with half the capacity and double the resistance and 10% more degradation
< no multithreading, nt_Vcheck time steps between checking SU voltage
< this should write a file called s_module_capacities.csv
bool slide::tests::unit::test_setCells | ( | ) |
********************************************************* test functions from Module_base_s *******************************************************************
< set cell with new SOC
< check using getCells
< Dynamic cast from smart ptr of StorageUnit to regular pointer of Cell_Bucket
< the new soc should be 0.1
< try updating the number of cells
< check using getCells
< Dynamic cast from StorageUnit to Cell_Bucket
bool slide::tests::unit::test_setI | ( | ) |
< voltage must decrease
< do not check individual cells, that is done in getCells
< voltage must increase
< test things which should break
< very large current, should give too low voltage
< should fail because the current equation cannot be solved
< very large current, should give too low voltage
< should fail because the current equation cannot be solved
bool slide::tests::unit::test_setI_p | ( | ) |
< double Module_base_s::setCurrent(double Inew, bool checkV, bool print)
< has no parent yet
< discharge
< voltage must decrease
< do not check individual cells, that is done in getCells
< charge
< voltage must increase
< rest with different SOC values
< c2 has lower OCV -> should charge
< the large change in OCV causes a large voltage change, which cannot be fixed by setCurrent
< cell voltages are equal
< cell currents are opposite
< test things which should break
< very large current, should give too low voltage
< should fail because the current equation cannot be solved
< very large current, should give too low voltage
< should fail because the current equation cannot be solved
bool slide::tests::unit::test_setStates | ( | ) |
< Make a new State vector from cells 1 and 3, where 3 has a different SOC
< change SOC of a cell
< change T
< this changes the states of m, and should therefore change the states of cell 2 too
< Check cell 2 and the states have changed
< mp->setStates invoked cp2->setStates, so also c2 should have changed
bool slide::tests::unit::test_setStates_ECM | ( | ) |
< set valid new states
< soc
< Ir
< T
< current
bool slide::tests::unit::test_setStates_SPM | ( | ) |
< set valid new states
< this checks states are valid
bool slide::tests::unit::test_setT | ( | ) |
bool slide::tests::unit::test_timeStep_CC | ( | ) |
< bool Module_base_s::timeStep_CC(double dt)
< time step with 0 current
< discharge
< check individual cells
< Dynamic cast from StorageUnit to Cell_Bucket
< Dynamic cast from StorageUnit to Cell_Bucket
bool slide::tests::unit::test_timeStep_CC_ECM | ( | ) |
< bool timeStep_CC(double dt);
< soc initial = 0.5 and capacity = 10 so SOC_end = 0.5 + 1*5/3600 = 0.5014
bool slide::tests::unit::test_timeStep_CC_p | ( | ) |
< bool Module_base_s::timeStep_CC(double dt)
< time step with 0 current
< discharge
< note: this is not going to be exact because we solve a nonlinear equation to obain I
< check individual cells
< we know the current has to split equally between both cells
< Dynamic cast from StorageUnit to Cell
< we know the current has to split equally between both cells
< Dynamic cast from StorageUnit to Cell
bool slide::tests::unit::test_timeStep_CC_SPM | ( | ) |
< bool timeStep_CC(double dt);
< set to charging and check the voltage has increased
< set to discharge
bool slide::tests::unit::test_validCells | ( | ) |
< bool Module_base_s::validCells(Cell_Bucket c[], int nin, bool print)
bool slide::tests::unit::test_validStates | ( | ) |
< valid states (current states)
< valid states (new T)
bool slide::tests::unit::test_validStates_ECM | ( | ) |
< bool validStates(double s[], int nin);
< set valid new states
< set invalid states
bool slide::tests::unit::test_validStates_p | ( | ) |
< bool Module_base_s::validStates(double s[], int nin, bool print)
< has no parent yet
< valid states (current states)
bool slide::tests::unit::testLosses | ( | ) |
< print the efficiency for a 1C charge for a small cell
< print the efficiency for a 1C charge for a large battery (for 9p, 15s 20s)
< check the losses are between 0 and 15 %
< cout<<"V = "<<v/(15.0*20.0)<<", I = "<<I<<", loss = "<<loss<<" W or "<<relloss*100<<" %"<<endl;
bool slide::tests::unit::timeStep_CC_test | ( | ) |
< soc initial = 0.5 and capacity = 10 so SOC_end = 0.5 + 1*5/3600/capacity =