├── P2D_identification.m ├── User Manual.pdf └── voltage_exp.txt /P2D_identification.m: -------------------------------------------------------------------------------- 1 | %% DEARLIBS 2021 (Doyle-Fuller-Newman Electrochemical Battery Models Implementation in Robust and Sleek MATLAB® Framework for Lithium-ion Batteries) 2 | % Developed by Dr. Seongbeom Lee (sblee3487@gmail.com) 3 | % Copyright @ 2020 Stanford Energy Control Group (PI: Prof. Simona Onori, Email:sonori@stanford.edu), Stanford University. All Rights Reserved. 4 | 5 | %% Battery Model: The DFN Model with Parabolic Profiles for Li-ion Batteries 6 | % Battery Chemistry: Cathode-NMC, Anode-Graphite, capacity=5000mAh (LG INR 21700) 7 | 8 | %% Academic Liscense 9 | % The single-step iteration-free initialization approach is protected under the U.S. Patent, US10769236B2, USA, 2020 10 | % The DEARLIBS is intended solely for academic and teaching purposes. 11 | % The DEARLIBS is under an academic use only license. 12 | % If the DEARLIBS is used for commercial purposes, it might infringe on the original patent of the single-step iteration-free initialization. 13 | 14 | %% Toolbox 15 | % The symbolic toolbox and gloabl optimal toolbox are required to execute DEARLIBS. 16 | % The parallel computing toolbox is optional and 'parfor' can be replaced with 'for' if users do not have the parallel computing toolbox. 'parfor' only accelerates the computational speed. 17 | % The signal toolbox is optional, and users can directly write down the root-mean-squre-error if they do not have the signal processing toolbox toolbox 18 | 19 | 20 | syms t kk 21 | 22 | global N M NM f MM y0 Numexp Totexp 23 | 24 | %% C-rate (Put your C-rate) 25 | Crate=-1; 26 | 27 | %% Experimental data (Users can input their experimental conditions) 28 | Numexp=63; % Number of experimental data 29 | Totexp=3100; % Experimental discharging time (or charging time) 30 | 31 | %% Number of parameters to be identified (Input the number of parameters to be identified) 32 | n_vars = 8; % Number of parameters to be identified 33 | kk = sym('kk',[1 n_vars]); % Arrays for parameters to be identified 34 | 35 | %% Node number (Change # of node- N: Cathode, M: Membrance, NM: Cathode) (Put your number of node points) 36 | N=2; 37 | M=2; 38 | NM=2; 39 | 40 | %% Design Parameters 41 | ep=0.335; % Porosity at positive 42 | es=0.47; % Porosity at membrane 43 | en=0.25; % Porosity at negative 44 | brugp=2.43; % Bruggeman coefficient at positive 45 | brugs=2.57; % Bruggeman coefficient at separator 46 | brugn=2.91; % Bruggeman coefficient at negative 47 | lp=75.6e-6; % Thickness at positive (unit:m) 48 | ls=12e-6; % Thickness at membrance (unit:m) 49 | ln1=85.2e-6; % Thickness at negative (unit:m) 50 | Rpp=5.22e-6; % Radius of solid particle at positive (unit:m) 51 | Rpn=5.86e-6; % Radius of solid particle at negative (unit:m) 52 | F=96487; % Faraday constant (unit: C/mol) 53 | R=8.3143; % Ideal gas constant (unit: J/(mol K)) 54 | t1=0.363; % Transference coefficient 55 | ap=(3/Rpp)*(1-ep); % Particle surface area to volume at positive (unit: m^2/m^3) 56 | an=(3/Rpn)*(1-en); % Particle surface area to volume at negative (unit: m^2/m^3) 57 | T=298.15; % Temperature (K) 58 | Acell=0.11; % Electrode area (m^2) 59 | Capa=5; % Nominal capacity (Ah) 60 | iapp=Capa*Crate/Acell; % Applied current density (A/m^2) 61 | 62 | %% Transport parameters 63 | c0=1000; % Electrolyte concentration (unit:mol/m3) 64 | D1=kk(1)*10^(-9); % Electrolyte diffusion coefficient (unit:m^2/s) 65 | Kappa=kk(2); % Conductivity (unit:S/m) 66 | ctp=51765; % Maximum solid phase concentration at positive (unit:mol/m^3) 67 | ctn=29583; % Maximum solid phase concentration at negative (unit:mol/m^3) 68 | Dbulk=D1; % Electrolyte diffusivity (unit:m^2/s) 69 | sigmap=kk(3); % Solid phase conductivity at positive (unit:S/m) 70 | sigman=kk(4); % Solid phase conductivity at negative (unit:S/m) 71 | Dsp=kk(5)*10^(-15); % Solid particle diffusivity at positive (unit:m^2/s) 72 | Dsn=kk(6)*10^(-14); % Solid particle diffusivity at negative (unit:m^2/s) 73 | 74 | Keffp=Kappa*(ep^brugp); % Liquid phase conductivity at positive (unit:S/m) 75 | Keffs=Kappa*(es^brugs); % Liquid phase conductivity at membrane (unit:S/m) 76 | Keffn=Kappa*(en^brugn); % Liquid phase conductivity at negative (unit:S/m) 77 | D2pos=(ep^brugp)*Dbulk; % Electrolyte diffusivity at positive (unit:m^2/s) 78 | D2sep=(es^brugs)*Dbulk; % Electrolyte diffusivity at membrane (unit:m^2/s) 79 | D2neg=(en^brugn)*Dbulk; % Electrolyte diffusivity at negative (unit:m^2/s) 80 | 81 | %% Kinetic parameters 82 | kp=kk(7)*10^(-11); % Reaction rate constant at positive (unit:m^2.5/(mol^0.5 s)) 83 | kn=kk(8)*10^(-12); % Reaction rate constant at negative (unit:m^2.5/(mol^0.5 s)) 84 | 85 | %% Step size 86 | h=lp/(N+1); % Step size at positive 87 | h2=ls/(M+1); % Step size at separator 88 | h3=ln1/(NM+1); % Step size at negative 89 | 90 | %% Variable declaration 91 | Nt=1+N+1+M+1+NM+1+N+NM+N+NM+N+2+NM+2+1+N+1+M+1+NM+1; 92 | X=cell(Nt,1); 93 | 94 | for ii=1:Nt 95 | X{ii}=symfun(str2sym(sprintf('X_%d(t)',ii)),t); 96 | end 97 | 98 | %% Variables 99 | varsX = [X{1:Nt}]; 100 | 101 | %% Positive 102 | % u1: electrolyte concentration 103 | % 'parfor' can be replaced with 'for' if users do not have the parallel computing toolbox 104 | u1=sym(zeros(1,1+N+1+M+1+NM+1)); 105 | parfor i=1:1+N+1+M+1+NM+1 106 | u1(i)=X{i}; 107 | end 108 | 109 | % u2: Surface concentration 110 | % 'parfor' can be replaced with 'for' if users do not have the parallel computing toolbox 111 | u2=sym(zeros(1,N+NM)); 112 | parfor i=1:N 113 | u2(i+1)=X{i+1+N+1+M+1+NM+1}; 114 | end 115 | 116 | for i=1:NM 117 | u2(i+1+N+1+M+1)=X{i+1+N+1+M+1+NM+1+N}; 118 | end 119 | 120 | % u3: Average concentration 121 | % 'parfor' can be replaced with 'for' if users do not have the parallel computing toolbox 122 | u3=sym(zeros(1,N+NM)); 123 | parfor i=1:N 124 | u3(i+1)=X{i+1+N+1+M+1+NM+1+N+NM}; 125 | end 126 | 127 | for i=1:NM 128 | u3(i+1+N+1+M+1)=X{i+1+N+1+M+1+NM+1+N+NM+N}; 129 | end 130 | 131 | % u4: Solid phase potential 132 | % 'parfor' can be replaced with 'for' if users do not have the parallel computing toolbox 133 | u4=sym(zeros(1,N+2+NM+2)); 134 | parfor i=1:N+2 135 | u4(i)=X{i+1+N+1+M+1+NM+1+N+NM+N+NM}; 136 | end 137 | 138 | for i=1:NM+2 139 | u4(i+1+N+1+M)=X{i+1+N+1+M+1+NM+1+N+NM+N+NM+N+2}; 140 | end 141 | 142 | % u5: Liquid potential (V) 143 | % 'parfor' can be replaced with 'for' if users do not have the parallel computing toolbox 144 | u5=sym(zeros(1,1+N+1+M+1+NM+1)); 145 | parfor i=1:1+N+1+M+1+NM+1 146 | u5(i)=X{i+1+N+1+M+1+NM+1+N+NM+N+NM+N+2+NM+2}; 147 | end 148 | 149 | %% Mole flux per area per second 150 | % Positive (jp) 151 | % 'parfor' can be replaced with 'for' if users do not have the parallel computing toolbox 152 | 153 | jp=sym(zeros(1,N+1)); 154 | parfor i=2:N+1 155 | 156 | theta=u2(i)*ctp/ctp; 157 | Up=-0.8090*theta+4.4875-0.0428*tanh(18.5138*(theta-0.5542))-17.7326*tanh(15.7890*(theta-0.3117))+17.5842*tanh(15.9308*(theta-0.3120)); 158 | 159 | jp(i)=2*kp*((u1(i)*c0)^0.5)*((ctp-u2(i)*ctp)^0.5)*((u2(i)*ctp)^0.5)*sinh(0.5*F/R/T*(u4(i)-u5(i)-Up)); 160 | 161 | end 162 | 163 | %% Negative (jn) 164 | % 'parfor' can be replaced with 'for' if users do not have the parallel computing toolbox 165 | 166 | jn=sym(zeros(1,1+N+1+M+1+NM)); 167 | parfor i=1+N+1+M+1+1:1+N+1+M+1+NM 168 | 169 | theta=u2(i)*ctn/ctn; 170 | Un=1.9793*exp(-39.3631*theta)+0.2482-0.0909*tanh(29.8538*(theta-0.1234))-0.04478*tanh(14.9159*(theta-0.2769))-0.0205*tanh(30.4444*(theta-0.6103)); 171 | 172 | jn(i)=2*kn*((u1(i)*c0)^0.5)*((ctn-u2(i)*ctn)^0.5)*((u2(i)*ctn)^0.5)*sinh(0.5*F/R/T*(u4(i)-u5(i)-Un)); 173 | 174 | end 175 | 176 | % u1: Electrolyte concentration (mol/m3) 177 | 178 | % Positive Electrode 179 | dudxf1=1/2/h*(-u1(3)-3*u1(1)+4*u1(2)); 180 | dudxb1=1/2/h*(u1(N)+3*u1(N+2)-4*u1(N+1)); 181 | dudxf1_2=1/2/h2*(-u1(N+4)-3*u1(N+2)+4*u1(N+3)); 182 | 183 | bc11=dudxf1; 184 | bc21=D2pos*dudxb1-D2sep*dudxf1_2; 185 | 186 | eq1=sym(zeros(1,1+N+1+M+1+NM+1)); 187 | 188 | eq1(1)=0==bc11; % Boundary equation 189 | 190 | % 'parfor' can be replaced with 'for' if users do not have the parallel computing toolbox 191 | parfor i=2:N+1 % Internal equation 192 | 193 | d2udx21=(1/(h^2))*(u1(i-1)-2*u1(i)+u1(i+1)); 194 | 195 | eq1(i)=diff(u1(i))==(D2pos*d2udx21+ap*(1-t1)*jp(i)/c0)/ep; 196 | 197 | end 198 | 199 | eq1(N+2)=0==bc21; % Boundary equation 200 | 201 | % Separator 202 | dudxb1_2=1/2/h2*(u1(N+2+M-1)+3*u1(N+2+M+1)-4*u1(N+2+M)); 203 | dudxf1_3=1/2/h3*(-u1(N+2+M+1+1+1)-3*u1(N+2+M+1)+4*u1(N+2+M+1+1)); 204 | 205 | bc31=D2sep*dudxb1_2-D2neg*dudxf1_3; 206 | 207 | % 'parfor' can be replaced with 'for' if users do not have the parallel computing toolbox 208 | parfor i=N+2+1:N+2+M % Internal equation 209 | 210 | d2udx21=(1/(h2^2))*(u1(i-1)-2*u1(i)+u1(i+1)); 211 | eq1(i)=diff(u1(i))==(D2sep*d2udx21)/es; 212 | 213 | end 214 | 215 | eq1(N+2+M+1)=0==bc31; % Boundary equation 216 | 217 | % Negative Electrode 218 | dudxb1_3=1/2/h3*(u1(1+N+1+M+1+NM-1)+3*u1(1+N+1+M+1+NM+1)-4*u1(1+N+1+M+1+NM)); 219 | 220 | bc41=dudxb1_3; 221 | 222 | % 'parfor' can be replaced with 'for' if users do not have the parallel computing toolbox 223 | parfor i=N+2+M+1+1:N+2+M+1+NM % Internal equation 224 | 225 | d2udx21=(1/(h3^2))*(u1(i-1)-2*u1(i)+u1(i+1)); 226 | eq1(i)=diff(u1(i))==(D2neg*d2udx21+an*(1-t1)*jn(i)/c0)/en; 227 | 228 | end 229 | 230 | eq1(1+N+1+M+1+NM+1)=0==bc41; % Boundary equation 231 | 232 | % u2: Surface concentration 233 | 234 | % Positive electrode 235 | 236 | eq2=sym(zeros(1,N+2+M+1+NM )); 237 | 238 | % 'parfor' can be replaced with 'for' if users do not have the parallel computing toolbox 239 | parfor i=2:N+1 % Internal equation 240 | 241 | eq2(i)=0==-u2(i)+u3(i)-jp(i)*Rpp/Dsp/5/ctp; 242 | 243 | end 244 | 245 | % Negative electrode 246 | 247 | % 'parfor' can be replaced with 'for' if users do not have the parallel computing toolbox 248 | parfor i=N+2+M+1+1:N+2+M+1+NM % Internal equation 249 | 250 | eq2(i)=0==-u2(i)+u3(i)-jn(i)*Rpn/Dsn/5/ctn; 251 | 252 | end 253 | 254 | % u3: Average concentration 255 | 256 | % Positive 257 | eq3=sym(zeros(1,1+N+1+M+1+NM)); 258 | 259 | % 'parfor' can be replaced with 'for' if users do not have the parallel computing toolbox 260 | parfor i=2:N+1 % Internal equation 261 | 262 | eq3(i)=diff(u3(i))==-3*jp(i)/Rpp/ctp; 263 | 264 | end 265 | 266 | % Negative electrode 267 | % 'parfor' can be replaced with 'for' if users do not have the parallel computing toolbox 268 | parfor i=1+N+1+M+1+1:1+N+1+M+1+NM % Internal equation 269 | 270 | eq3(i)=diff(u3(i))==-3*jn(i)/Rpn/ctn; 271 | 272 | end 273 | 274 | % u4: Solid Potential 275 | 276 | % positive 277 | dudxf4=1/2/h*(-u4(3)-3*u4(1)+4*u4(2)); 278 | dudxb4=1/2/h*(u4(N)+3*u4(N+2)-4*u4(N+1)); 279 | 280 | bc14=dudxf4+iapp/sigmap; 281 | bc24=dudxb4; 282 | 283 | eq4=sym(zeros(1,1+N+1+M+1+NM+1)); 284 | 285 | eq4(1)=0==bc14; % Boundary equation 286 | 287 | % 'parfor' can be replaced with 'for' if users do not have the parallel computing toolbox 288 | parfor i=2:N+1 % Internal equation 289 | 290 | d2udx24=(1/(h^2))*(u4(i-1)-2*u4(i)+u4(i+1)); 291 | 292 | eq4(i)=0==d2udx24-ap*F*jp(i)/sigmap; 293 | 294 | end 295 | 296 | eq4(N+2)=0==bc24; 297 | 298 | % Negative 299 | dudxf4_3=1/2/h3*(-u4(N+2+M+1+1+1)-3*u4(N+2+M+1)+4*u4(N+2+M+1+1)); 300 | dudxb4_3=1/2/h3*(u4(1+N+1+M+1+NM-1)+3*u4(1+N+1+M+1+NM+1)-4*u4(1+N+1+M+1+NM)); 301 | 302 | bc34=dudxf4_3; 303 | bc44=dudxb4_3+iapp/sigman; 304 | 305 | eq4(N+2+M+1)=0==bc34; % Boundary equation 306 | 307 | % 'parfor' can be replaced with 'for' if users do not have the parallel computing toolbox 308 | parfor i=N+2+M+1+1:N+2+M+1+NM % Internal equation 309 | 310 | d2udx24=(1/(h3^2))*(u4(i-1)-2*u4(i)+u4(i+1)); 311 | eq4(i)= 0==d2udx24-an*F*jn(i)/sigman; 312 | 313 | end 314 | 315 | eq4(1+N+1+M+1+NM+1)=0==bc44; % Boundary equation 316 | 317 | % u5: Liquid phase potential (V) 318 | 319 | % Positive Electrode 320 | dudxf5=1/2/h*(-u5(3)-3*u5(1)+4*u5(2)); 321 | dudxb5=1/2/h*(u5(N)+3*u5(N+2)-4*u5(N+1)); 322 | dudxf5_2=1/2/h2*(-u5(N+2+2)-3*u5(N+2)+4*u5(N+2+1)); 323 | 324 | bc15=dudxf5; 325 | bc25=Keffp*dudxb5-Keffs*dudxf5_2; 326 | 327 | eq5=sym(zeros(1,1+N+1+M+1+NM+1)); 328 | 329 | eq5(1)=0==bc15; % Boundary equation 330 | 331 | % 'parfor' can be replaced with 'for' if users do not have the parallel computing toolbox 332 | parfor i=2:N+1 % Internal equation 333 | 334 | dudx1=1/2/h*(u1(i+1)-u1(i-1)); 335 | dudx4=1/2/h*(u4(i+1)-u4(i-1)); 336 | dudx5=1/2/h*(u5(i+1)-u5(i-1)); 337 | 338 | eq5(i)=0==-sigmap*dudx4-Keffp*dudx5+(2*Keffp*R*T*(1-t1)*dudx1)/F/u1(i)-iapp; 339 | 340 | end 341 | 342 | eq5(N+2)=0==bc25; % Boundary equation 343 | 344 | % Separator 345 | % 'parfor' can be replaced with 'for' if users do not have the parallel computing toolbox 346 | parfor i=N+2+1:N+2+M % Internal equation 347 | 348 | dudx1=1/2/h2*(u1(i+1)-u1(i-1)); 349 | dudx5=1/2/h2*(u5(i+1)-u5(i-1)); 350 | 351 | eq5(i)=0==-Keffs*dudx5+(2*Keffs*R*T*(1-t1)*dudx1)/F/u1(i)-iapp; 352 | 353 | end 354 | 355 | dudxb5_2=1/2/h2*(u5(1+N+1+M-1)+3*u5(1+N+1+M+1)-4*u5(1+N+1+M)); 356 | dudxf5_3=1/2/h3*(-u5(1+N+1+M+1+1+1)-3*u5(1+N+1+M+1)+4*u5(1+N+1+M+1+1)); 357 | 358 | bc35=Keffs*dudxb5_2-Keffn*dudxf5_3; 359 | 360 | eq5(1+N+1+M+1)=0==bc35; % Boundary equation 361 | 362 | % Negative 363 | % 'parfor' can be replaced with 'for' if users do not have the parallel computing toolbox 364 | parfor i=1+N+1+M+1+1:1+N+1+M+1+NM % Internal equation 365 | 366 | dudx1=1/2/h3*(u1(i+1)-u1(i-1)); 367 | dudx4=1/2/h3*(u4(i+1)-u4(i-1)); 368 | dudx5=1/2/h3*(u5(i+1)-u5(i-1)); 369 | 370 | eq5(i)=0==-sigman*dudx4-Keffn*dudx5+(2*Keffn*R*T*(1-t1)*dudx1)/F/u1(i)-iapp; 371 | 372 | end 373 | 374 | bc45=u5(1+N+1+M+1+NM+1); 375 | 376 | eq5(1+N+1+M+1+NM+1)=0==bc45; % Boundary equation 377 | 378 | %% A single-step iteration-free initialization approach (Patented by Venkat Subramanian Group at UT Austin)- Allows for Only Acamedic purpose 379 | mu=10^(-3); 380 | q=1000; 381 | initime=200; 382 | ff=1/2*tanh(q*(t-initime))+1/2; 383 | 384 | eqn1=sym(zeros(1,1+N+1+M+1+NM+1)); 385 | 386 | eqn1(1)=-mu*(diff(rhs(eq1(1)))-diff(lhs(eq1(1))))-rhs(eq1(1))+lhs(eq1(1)); 387 | 388 | % 'parfor' can be replaced with 'for' if users do not have the parallel computing toolbox 389 | parfor ii=2:N+1 390 | eqn1(ii)=lhs(eq1(ii))-rhs(eq1(ii))*ff; 391 | end 392 | eqn1(N+2)=-mu*(diff(rhs(eq1(N+2)))-diff(lhs(eq1(N+2))))-rhs(eq1(N+2))+lhs(eq1(N+2)); 393 | parfor ii=N+2+1:N+2+M 394 | eqn1(ii)=lhs(eq1(ii))-rhs(eq1(ii))*ff; 395 | end 396 | eqn1(N+2+M+1)=-mu*(diff(rhs(eq1(N+2+M+1)))-diff(lhs(eq1(N+2+M+1))))-rhs(eq1(N+2+M+1))+lhs(eq1(N+2+M+1)); 397 | parfor ii=N+2+M+1+1:N+2+M+1+NM 398 | eqn1(ii)=lhs(eq1(ii))-rhs(eq1(ii))*ff; 399 | end 400 | eqn1(1+N+1+M+1+NM+1)=-mu*(diff(rhs(eq1(1+N+1+M+1+NM+1)))-diff(lhs(eq1(1+N+1+M+1+NM+1))))-rhs(eq1(1+N+1+M+1+NM+1))+lhs(eq1(1+N+1+M+1+NM+1)); 401 | 402 | eqn2=sym(zeros(1,N+2+M+1+NM)); 403 | % 'parfor' can be replaced with 'for' if users do not have the parallel computing toolbox 404 | parfor ii=2:N+1 405 | eqn2(ii)=-mu*(diff(rhs(eq2(ii)))-diff(lhs(eq2(ii))))-rhs(eq2(ii))+lhs(eq2(ii)); 406 | end 407 | parfor ii=N+2+M+1+1:N+2+M+1+NM 408 | eqn2(ii)=-mu*(diff(rhs(eq2(ii)))-diff(lhs(eq2(ii))))-rhs(eq2(ii))+lhs(eq2(ii)); 409 | end 410 | 411 | eqn3=sym(zeros(1,1+N+1+M+1+NM)); 412 | % 'parfor' can be replaced with 'for' if users do not have the parallel computing toolbox 413 | parfor ii=2:N+1 414 | eqn3(ii)=lhs(eq3(ii))-rhs(eq3(ii))*ff; 415 | end 416 | parfor ii=1+N+1+M+1+1:1+N+1+M+1+NM 417 | eqn3(ii)=lhs(eq3(ii))-rhs(eq3(ii))*ff; 418 | end 419 | 420 | eqn4=sym(zeros(1,1+N+1+M+1+NM+1)); 421 | eqn4(1)=-mu*(diff(rhs(eq4(1)))-diff(lhs(eq4(1))))-rhs(eq4(1))+lhs(eq4(1)); 422 | % 'parfor' can be replaced with 'for' if users do not have the parallel computing toolbox 423 | parfor ii=2:N+1 424 | eqn4(ii)=-mu*(diff(rhs(eq4(ii)))-diff(lhs(eq4(ii))))-rhs(eq4(ii))+lhs(eq4(ii)); 425 | end 426 | eqn4(N+2)=-mu*(diff(rhs(eq4(N+2)))-diff(lhs(eq4(N+2))))-rhs(eq4(N+2))+lhs(eq4(N+2)); 427 | eqn4(N+2+M+1)=-mu*(diff(rhs(eq4(N+2+M+1)))-diff(lhs(eq4(N+2+M+1))))-rhs(eq4(N+2+M+1))+lhs(eq4(N+2+M+1)); 428 | parfor ii=N+2+M+1+1:N+2+M+1+NM 429 | eqn4(ii)=-mu*(diff(rhs(eq4(ii)))-diff(lhs(eq4(ii))))-rhs(eq4(ii))+lhs(eq4(ii)); 430 | end 431 | eqn4(1+N+1+M+1+NM+1)=-mu*(diff(rhs(eq4(1+N+1+M+1+NM+1)))-diff(lhs(eq4(1+N+1+M+1+NM+1))))-rhs(eq4(1+N+1+M+1+NM+1))+lhs(eq4(1+N+1+M+1+NM+1)); 432 | 433 | eqn5=sym(zeros(1,1+N+1+M+1+NM+1)); 434 | eqn5(1)=-mu*(diff(rhs(eq5(1)))-diff(lhs(eq5(1))))-rhs(eq5(1))+lhs(eq5(1)); 435 | % 'parfor' can be replaced with 'for' if users do not have the parallel computing toolbox 436 | parfor ii=2:N+1 437 | eqn5(ii)=-mu*(diff(rhs(eq5(ii)))-diff(lhs(eq5(ii))))-rhs(eq5(ii))+lhs(eq5(ii)); 438 | end 439 | eqn5(N+2)=-mu*(diff(rhs(eq5(N+2)))-diff(lhs(eq5(N+2))))-rhs(eq5(N+2))+lhs(eq5(N+2)); 440 | parfor ii=N+2+1:N+2+M 441 | eqn5(ii)=-mu*(diff(rhs(eq5(ii)))-diff(lhs(eq5(ii))))-rhs(eq5(ii))+lhs(eq5(ii)); 442 | end 443 | eqn5(1+N+1+M+1)=-mu*(diff(rhs(eq5(1+N+1+M+1)))-diff(lhs(eq5(1+N+1+M+1))))-rhs(eq5(1+N+1+M+1))+lhs(eq5(1+N+1+M+1)); 444 | parfor ii=1+N+1+M+1+1:1+N+1+M+1+NM 445 | eqn5(ii)=-mu*(diff(rhs(eq5(ii)))-diff(lhs(eq5(ii))))-rhs(eq5(ii))+lhs(eq5(ii)); 446 | end 447 | eqn5(1+N+1+M+1+NM+1)=-mu*(diff(rhs(eq5(1+N+1+M+1+NM+1)))-diff(lhs(eq5(1+N+1+M+1+NM+1))))-rhs(eq5(1+N+1+M+1+NM+1))+lhs(eq5(1+N+1+M+1+NM+1)); 448 | 449 | %% Total equations 450 | eqs = [eqn1(1:1+N+1+M+1+NM+1),eqn2(1+1:N+1),eqn2(1+N+2+M+1:NM+N+2+M+1),eqn3(1+1:N+1),eqn3(1+N+2+M+1:NM+N+2+M+1),eqn4(1:N+2),eqn4(1+1+N+1+M:NM+2+1+N+1+M),eqn5(1:1+N+1+M+1+NM+1)]; 451 | vars = (varsX); 452 | 453 | [MM,f] = massMatrixForm(eqs, vars); 454 | 455 | MM = odeFunction(MM, vars,kk); 456 | f = odeFunction(f, vars,kk); 457 | 458 | %% Initial condition guess (Put your initial guess) 459 | U(1:1+N+1+M+1+NM+1)=1; % Electrolyte concentration 460 | U(1+1+N+1+M+1+NM+1:N+1+N+1+M+1+NM+1)=.27; % Surface con. at positive 461 | U(1+1+N+1+M+1+NM+1+N:NM+1+N+1+M+1+NM+1+N)=0.9014; % Surface con. at negative 462 | U(1+1+N+1+M+1+NM+1+N+NM:N+1+N+1+M+1+NM+1+N+NM)=.27; % Average con. at positive 463 | U(1+1+N+1+M+1+NM+1+N+NM+N:NM+1+N+1+M+1+NM+1+N+NM+N)=0.9014; % Average con. at negative 464 | U(1+1+N+1+M+1+NM+1+N+NM+N+NM:N+2+1+N+1+M+1+NM+1+N+NM+N+NM)=4.30430037; % Solid phase potential at positive 465 | U(1+1+N+1+M+1+NM+1+N+NM+N+NM+N+2:NM+2+1+N+1+M+1+NM+1+N+NM+N+NM+N+2)=.9202000152e-1; % Solid phase potential at negative 466 | U(1+1+N+1+M+1+NM+1+N+NM+N+NM+N+2+NM+2:1+N+1+M+1+NM+1+1+N+1+M+1+NM+1+N+NM+N+NM+N+2+NM+2)=0; % Liquid potential 467 | 468 | y0 = (U(1:1+N+1+M+1+NM+1+1+N+1+M+1+NM+1+N+NM+N+NM+N+2+NM+2)); 469 | 470 | x=importdata('voltage_exp.txt'); 471 | 472 | %% PSO identificaiton (Input your uppoer and lower bounds for parameters to be identified. Input your options for PSO) 473 | 474 | pp=0.3; % Deviation for upper and lower bounds (percentage) 475 | D10=1; % Electrolyte diffusion coefficient 476 | Kappa0=1.17; % Conductivity 477 | sigmap0=0.18; % Solid phase conductivity at positive 478 | sigman0=215; % Solid phase conductivity at negative 479 | Dsp0=4; % Solid particle diffusivity at positive 480 | Dsn0=3.3; % Solid particle diffusivity at negative 481 | kp0=0.7; % Reaction rate constant at positive 482 | kn0=0.7; % Reaction rate constant at negative 483 | 484 | Lower_bound = [D10-pp*D10 Kappa0-pp*Kappa0 sigmap0-pp*sigmap0 sigman0-pp*sigman0 Dsp0-pp*Dsp0 Dsn0-pp*Dsn0 kp0-pp*kp0 kn0-pp*kn0]; 485 | Upper_bound = [D10+pp*D10 Kappa0+pp*Kappa0 sigmap0+pp*sigmap0 sigman0+pp*sigman0 Dsp0+pp*Dsp0 Dsn0+pp*Dsn0 kp0+pp*kp0 kn0+pp*kn0]; 486 | 487 | options = optimoptions('particleswarm','SwarmSize',10,'Display','iter','MaxIterations',10); 488 | 489 | tic 490 | [kk,fval] = particleswarm(@(kk)P2Dobj(kk), n_vars, Lower_bound, Upper_bound, options); 491 | toc 492 | 493 | D1=kk(1)*10^(-9); % Electrolyte diffusion coefficient (unit:m2/s) 494 | Kappa=kk(2); % Conductivity (unit:S/m) 495 | sigmap=kk(3); % Solid phase conductivity at positive (unit:S/m) 496 | sigman=kk(4); % Solid phase conductivity at negative (unit:S/m) 497 | Dsp=kk(5)*10^(-15); % Solid particle diffusivity at positive (unit:m^2/s) 498 | Dsn=kk(6)*10^(-14); % Solid particle diffusivity at negative (unit:m^2/s) 499 | kp=kk(7)*10^(-11); % Reaction rate constant at positive (unit:m^2.5/(mol^0.5 s)) 500 | kn=kk(8)*10^(-12); % Reaction rate constant at negative (unit:m^2.5/(mol^0.5 s)) 501 | 502 | save('identified_params_kinetic','fval','D1','Kappa','sigmap','sigman','Dsp','Dsn','kp','kn'); 503 | 504 | %% Solver 505 | 506 | % Adapt solver functions for better conditioning 507 | M0 = MM(initime,y0(:),kk); 508 | vw = 1./max(abs(M0),[],2); 509 | mw = diag(vw); 510 | 511 | F = @(t,y) vw.*f(t,y(:),kk); 512 | M1 = @(t,y) mw*MM(t,y(:),kk); 513 | 514 | tsp=100000; 515 | opt = odeset('Mass', M1,'MStateDependence','weak','RelTol',1e-5,'AbsTol',1e-5,'InitialStep',1e-3,'MaxStep',5,'Events',@stopcondition); 516 | warning('off','all'); 517 | tic 518 | [T,Y] = ode15s(F,[0 tsp], y0, opt); 519 | toc 520 | 521 | % Plot 522 | figure(1) 523 | hold off 524 | 525 | p1=plot(T-initime,(Y(:,1+N+1+M+1+NM+1+N+NM+N+NM+1)-Y(:,1+N+1+M+1+NM+1+N+NM+N+NM+N+2+NM+2)),'Linewidth',2); 526 | hold on; 527 | 528 | %time1=linspace(0,3100,63); 529 | time1=linspace(0,Totexp,Numexp); 530 | p2=plot(time1,x(:,1),'o','MarkerSize',7,'color','red'); 531 | 532 | xlim([0 3200]); 533 | ylim([2.8 4]); 534 | set(gca,'FontSize',15); 535 | xlabel('Time(seconds)','FontSize',15); 536 | ylabel('Voltage(V)','FontSize',15); 537 | legend('P2D Model','Experiment'); 538 | legend('boxoff'); 539 | 540 | saveas(p1,'voltage_25C.bmp'); 541 | 542 | %% Objective function 543 | function obj=P2Dobj(kk) 544 | 545 | global y0 f MM N M NM initime Totexp Numexp 546 | 547 | try 548 | 549 | % Adapt solver functions for better conditioning 550 | M0 = MM(initime,y0(:),kk); 551 | vw = 1./max(abs(M0),[],2); 552 | mw = diag(vw); 553 | 554 | F = @(t,y) vw.*f(t,y(:),kk); 555 | M1 = @(t,y) mw*MM(t,y(:),kk); 556 | 557 | % In this code, 'Initime' is set up as 200 seconds. For 200s, consistent initial conditions are determined, and this should be excluded for actual simulations. 558 | 559 | % This is the reason the final time is 3100+200 seconds and the total data point is 63+4. 560 | 561 | time=linspace(0,Totexp+200,Numexp+3); 562 | opt = odeset('Mass', M1,'MStateDependence','weak','RelTol',1e-5,'AbsTol',1e-5,'InitialStep',1e-3,'MaxStep',5); 563 | warning('off','all'); 564 | [T,Y] = ode15s(F,time, y0, opt); 565 | 566 | x=importdata('voltage_exp.txt'); 567 | 568 | obj=rms(x(:,1)-(Y(4:Numexp+3,1+N+1+M+1+NM+1+N+NM+N+NM+1)-Y(4:Numexp+3,1+N+1+M+1+NM+1+N+NM+N+NM+N+2+NM+2))); 569 | 570 | catch 571 | obj=1000; 572 | end 573 | 574 | end 575 | 576 | %% Stop condition 577 | function [value,isterminal,direction] = stopcondition(~,Y) 578 | 579 | global N M NM 580 | 581 | value = (Y(1+N+1+M+1+NM+1+N+NM+N+NM+1)-Y(1+N+1+M+1+NM+1+N+NM+N+NM+N+2+NM+2))-2.7; % stop condition 4.2 V 582 | isterminal = 1; % stop the integration 583 | direction = 0; % negative direction 584 | 585 | end -------------------------------------------------------------------------------- /User Manual.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DEARLIBS/DFNcodes/e0cea12dee2025d0bb8f1ab5328b21f3769184fb/User Manual.pdf -------------------------------------------------------------------------------- /voltage_exp.txt: -------------------------------------------------------------------------------- 1 | 3.813591003 %25degreeC experimental data 2 | 3.745599508 3 | 3.716134071 4 | 3.697249413 5 | 3.683956146 6 | 3.673239231 7 | 3.663868427 8 | 3.654504776 9 | 3.644954443 10 | 3.634744167 11 | 3.623246908 12 | 3.610104799 13 | 3.595073938 14 | 3.578690767 15 | 3.561151505 16 | 3.543590546 17 | 3.52622056 18 | 3.509293079 19 | 3.493284941 20 | 3.478235006 21 | 3.463361263 22 | 3.449174166 23 | 3.435084105 24 | 3.420971632 25 | 3.406618595 26 | 3.39187336 27 | 3.376799107 28 | 3.361414194 29 | 3.345580578 30 | 3.329528093 31 | 3.313210726 32 | 3.297030687 33 | 3.280991316 34 | 3.265031815 35 | 3.24971962 36 | 3.235033512 37 | 3.221103191 38 | 3.207888126 39 | 3.19557929 40 | 3.183927536 41 | 3.172984838 42 | 3.162251472 43 | 3.151845217 44 | 3.141775846 45 | 3.131531715 46 | 3.121413708 47 | 3.111053467 48 | 3.100889444 49 | 3.090194225 50 | 3.079425097 51 | 3.067946911 52 | 3.055830002 53 | 3.042959452 54 | 3.029539585 55 | 3.014633656 56 | 2.998571873 57 | 2.981081009 58 | 2.961527109 59 | 2.939378977 60 | 2.913357735 61 | 2.881973267 62 | 2.844485998 63 | 2.80021286 --------------------------------------------------------------------------------