SLIDE  3.0.0
A simulator for lithium-ion battery pack degradation
Loading...
Searching...
No Matches
free_functions.hpp
Go to the documentation of this file.
1/*
2 * free_functions.cpp
3 *
4 * Free functions to help to write everything shorter.
5 *
6 * Created on: 05 Apr 2022
7 * Author(s): Jorn Reniers, Volkan Kumtepeli
8 */
9
10#pragma once
11
12#include "../settings/settings.hpp"
13#include "../types/Status.hpp"
14
15#include <fstream>
16#include <string>
17#include <numeric>
18#include <vector>
19#include <fstream>
20#include <iostream>
21
22namespace slide::free {
23
24template <typename Tsu>
25inline Status setVoltage_iterative(Tsu *su, double Vset)
26{
27 // New redistributeCurrent without PI control:
29 constexpr int maxIteration = 50;
30 double Ia{ su->I() };
31
32 for (int iter{ 0 }; iter < maxIteration; iter++) {
33 const auto Va = su->V();
34 if (std::abs(Vset - Va) < 1e-6)
35 return Status::Success;
36
37 const auto Ib = (Vset > Va) ? Ia - 0.01 * su->Cap() : Ia + 0.01 * su->Cap();
38 su->setCurrent(Ib);
39 const auto Vb = su->V();
40
41 const double slope = (Ia - Ib) / (Va - Vb);
42 Ia = Ib - (Vb - Vset) * slope;
43 su->setCurrent(Ia);
44 }
45
46 return Status::RedistributeCurrent_failed; // #TODO change to setVoltage failed.
47}
48
49inline void write_data(std::ofstream &file, std::vector<double> &data, size_t N = 1)
50{
51 for (size_t i{}; i < data.size(); i++) {
52 if (i % N == 0) {
53 if (i != 0)
54 file << '\n';
55 } else
56 file << ',';
57
58 file << data[i];
59 }
60
61 data.clear();
62}
63
64template <typename T>
65size_t get_Ncells(T const &SU)
66{
67 /* return the number of cells connected to this module
68 * e.g. if this module has 3 child-modules, each with 2 cells.
69 * then getNSUs = 3 but getNcells = 6
70 */
71 return SU->getNcells();
72}
73
74template <typename T>
75auto get_V(T const &SU) { return SU.V(); }
76
77template <typename T>
78auto get_T(T const &SU) { return SU->T(); }
79
80
81template <typename T>
82auto get_Vmin(const T &SU) { return SU->Vmin(); }
83
84template <typename T>
85auto get_VMIN(const T &SU) { return SU->VMIN(); }
86
87template <typename T>
88auto get_Vmax(const T &SU) { return SU->Vmax(); }
89
90template <typename T>
91auto get_VMAX(const T &SU) { return SU->VMAX(); }
92
93template <typename T>
94auto get_Cap(const T &SU) { return SU->Cap(); }
95
96template <typename T>
97auto get_OCV(const T &SU) { return SU->getOCV(); }
98
99template <typename T>
100auto get_I(const T &SU) { return SU->I(); }
101
102
103template <bool Print = settings::printBool::printCrit>
104auto inline check_SOC(double SOCnew, double SOC_min = 0, double SOC_max = 1)
105{
106 if (SOCnew < SOC_min || SOCnew > SOC_max)
107 {
108 if constexpr (Print)
109 std::cerr << "ERROR in some Cell, illegal input value of SOC: "
110 << SOCnew << " while the minimum is " << SOC_min
111 << " and maximum is " << SOC_max << ".\n";
112 return false;
113 }
114 return true;
115}
116
117template <bool Print = settings::printBool::printCrit>
118auto inline check_Cell_states(auto &su, bool checkV)
119{
120 if (!su.validStates(Print))
121 {
122 if constexpr (Print)
123 std::cerr << "ERROR in " << su.getID() << "::setStates, illegal State.\n";
124
126 }
127
129 if (checkV) {
130 double v;
131 return su.checkVoltage(v, Print);
132 }
133
134 return Status::Success;
135}
136
137template <bool Print = true>
138auto inline check_voltage(double &v, auto &su)
139{
140 /*
141 * -2 V < VMIN discharging and outside safety range, cycling should be halted asap to avoid numerical errors
142 * -1 VMIN <= V < Vmin discharging and outside range of cell, but not yet safety limit
143 * 0 Vmin <= V <= Vmax valid range
144 * 1 Vmax < V <= VMAX charging and ...
145 * 2 VMAX < V charging and ...
146 *
147 * note: allow a small margin on Vmin and Vmax for when we are doing a CV phase
148 * then occasionally, V can be slightly above or below Vlimit
149 */
150
151 constexpr bool printCrit = (settings::printBool::printCrit) && Print;
152 constexpr bool printNonCrit = (settings::printBool::printNonCrit) && Print;
153
154 try {
155 v = su.V();
156 } catch (int) {
157 std::cout << "We could not calculate voltage!!!\n";
159 }
160
161 if (v <= 0) {
162 if (printCrit)
163 std::cout << "Error in Cell::setStates when getting the voltage, which is "
164 << v << " restoring the old states.\n";
165
167 }
168
170 if (v > (su.Vmin() - settings::MODULE_P_V_ABSTOL) && v < (su.Vmax() + settings::MODULE_P_V_ABSTOL)) {
171 return Status::Success;
172 } else if (v < su.VMIN() && su.isDischarging()) // #Check we dont actually look at the is discharging
173 {
174 if (printCrit)
175 std::cout << "The voltage of cell " << su.getFullID() << " is " << v
176 << "V which is below its safety limit of "
177 << su.VMIN() << ", cell temperature = " << K_to_Celsius(su.T())
178 << " centigrade and I = " << su.I() << '\n';
179
181 } else if (v > su.VMAX() && su.isCharging())
182 {
183 if (printCrit)
184 std::cout << "The voltage of cell " << su.getFullID() << " is " << v
185 << "V which is above its safety limit of "
186 << su.VMAX() << ", cell temperature = " << K_to_Celsius(su.T())
187 << " centigrade and I = " << su.I() << '\n';
188
190 } else if (v < (su.Vmin() - settings::MODULE_P_V_ABSTOL) && su.isDischarging()) {
191 if (printNonCrit)
192 std::cout << "The voltage of cell " << su.getFullID() << " is " << v
193 << "V which is below its minimum voltage of "
194 << su.Vmin() << ", cell temperature = " << K_to_Celsius(su.T())
195 << " centigrade and I = " << su.I() << '\n';
196
198 } else if (v > (su.Vmax() + settings::MODULE_P_V_ABSTOL) && su.isCharging())
199 {
200 if (printNonCrit)
201 std::cout << "The voltage of cell " << su.getFullID() << " is " << v
202 << "V which is above its maximum voltage of "
203 << su.Vmax() << ", cell temperature = " << K_to_Celsius(su.T())
204 << " centigrade and I = " << su.I() << '\n';
205
207 }
208
209 return Status::Success;
210}
211
212template <bool Print = settings::printBool::printCrit>
213auto inline check_safety(double vi, auto &cyc)
214{
215 const auto SafetyVmin = cyc.getSafetyVmin();
216 const auto SafetyVmax = cyc.getSafetyVmax();
217
218 if (vi < SafetyVmin)
219 {
220 if constexpr (Print)
221 std::cout << "Error in Cycler::??, the voltage of " << vi
222 << " V is smaller than the minimum safety voltage of the cycler of "
223 << SafetyVmin << " V." << '\n';
224
226 } else if (vi > SafetyVmax)
227 {
228 if constexpr (Print)
229 std::cout << "Error in Cycler::??, the voltage of " << vi
230 << " V is larger than the maximum safety voltage of the cycler of "
231 << SafetyVmax << " V." << '\n';
233 }
234
235 return Status::SafeVoltage;
236}
237
238template <bool Print = true>
239auto inline check_current(bool checkV, auto &su)
240{
241
243}
244
245inline std::ofstream openFile(auto &SU, const auto &folder, const std::string &prefix, const std::string &suffix)
246{
247 const auto name = PathVar::results / (prefix + "_" + SU.getFullID() + "_" + suffix);
248
249 // std::string name = getName(cell, prefix); //!< name of the file
250 std::ofstream file(name, std::ios_base::app); // #TODO app-> initially open then append.
251
252 if (!file.is_open()) {
253 std::cerr << "ERROR in Cell::writeData, could not open file "
254 << name << '\n';
255 throw 11;
256 }
257
258 return file;
259}
260
261} // namespace slide::free
Definition: free_functions.hpp:22
auto get_V(T const &SU)
Definition: free_functions.hpp:75
auto check_SOC(double SOCnew, double SOC_min=0, double SOC_max=1)
Definition: free_functions.hpp:104
auto get_VMAX(const T &SU)
Definition: free_functions.hpp:91
auto get_Cap(const T &SU)
Definition: free_functions.hpp:94
auto check_Cell_states(auto &su, bool checkV)
Definition: free_functions.hpp:118
auto get_Vmin(const T &SU)
Definition: free_functions.hpp:82
auto check_current(bool checkV, auto &su)
Definition: free_functions.hpp:239
void write_data(std::ofstream &file, std::vector< double > &data, size_t N=1)
Definition: free_functions.hpp:49
std::ofstream openFile(auto &SU, const auto &folder, const std::string &prefix, const std::string &suffix)
Definition: free_functions.hpp:245
auto check_voltage(double &v, auto &su)
Definition: free_functions.hpp:138
auto get_VMIN(const T &SU)
Definition: free_functions.hpp:85
auto get_T(T const &SU)
Definition: free_functions.hpp:78
size_t get_Ncells(T const &SU)
Definition: free_functions.hpp:65
Status setVoltage_iterative(Tsu *su, double Vset)
Definition: free_functions.hpp:25
auto get_OCV(const T &SU)
Definition: free_functions.hpp:97
auto get_Vmax(const T &SU)
Definition: free_functions.hpp:88
auto check_safety(double vi, auto &cyc)
Definition: free_functions.hpp:213
auto get_I(const T &SU)
Definition: free_functions.hpp:100
constexpr auto printCrit
threshold of verbose of when to print error messages for critical errors
Definition: derived_settings.hpp:30
constexpr auto printNonCrit
threshold of verbose of when to print error messages for noncritical errors
Definition: derived_settings.hpp:31
constexpr double MODULE_P_V_ABSTOL
Definition: tolerances.hpp:26
Status
Definition: Status.hpp:15
@ RedistributeCurrent_failed
@ SafeVoltage
Upper part is from cycler!
@ VMAXsafety_violation
1.01 VMAX
@ VMINsafety_violation
0.99 VMIN
constexpr double K_to_Celsius(auto Kelvin)
Definition: units.hpp:31