diff --git a/.github/workflows/mpet-code-style.yml b/.github/workflows/mpet-code-style.yml index c63a21ed..e8ead7be 100644 --- a/.github/workflows/mpet-code-style.yml +++ b/.github/workflows/mpet-code-style.yml @@ -9,13 +9,13 @@ jobs: steps: - name: Set up python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: 3.9 architecture: x64 - name: Checkout MPET - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 1 path: mpet diff --git a/.github/workflows/mpet-regression-test.yml b/.github/workflows/mpet-regression-test.yml index d748789a..5f8a1212 100644 --- a/.github/workflows/mpet-regression-test.yml +++ b/.github/workflows/mpet-regression-test.yml @@ -9,35 +9,27 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.7","3.8","3.9","3.10"] + python-version: ["3.8","3.9","3.10","3.11"] defaults: run: shell: bash -l {0} steps: - - uses: actions/checkout@v1 - with: - fetch-depth: 1 - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 1 path: mpet - - uses: actions/checkout@v2 - with: - fetch-depth: 1 - path: base-mpet - ref: ${{ github.base_ref }} - uses: conda-incubator/setup-miniconda@v2 with: - auto-update-conda: true python-version: ${{ matrix.python-version }} + mamba-version: "*" + channels: conda-forge,defaults activate-environment: mpet-env - - name: Install daetools via conda + - name: Install daetools via mamba run: | - conda activate mpet-env - conda install -c conda-forge daetools python=${{ matrix.python-version }} pip + mamba install daetools - name: Install additional dependencies using mpet's setup.py run: | @@ -57,7 +49,6 @@ jobs: - name: run tests for modified branch and get coverage run: | - conda activate mpet-env cd mpet/bin/workdir coverage run --source=../../mpet/ run_tests.py --test_dir ./tests --output_dir ../../bin/workdir/modified > /dev/null diff --git a/CHANGELOG.md b/CHANGELOG.md index fbdefb8f..797a6002 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.1.9] - 2023-01-27 +### Added +- Regression tests for Python 3.10 and 3.11. +- Additional badges added to README. + +### Fixed +- Code clean up and maintenance updates. + + ## [0.1.8] - 2022-02-14 ### Added - Online documentation with updated installation instructions: [https://mpet.readthedocs.io/en/latest/](https://mpet.readthedocs.io/en/latest/) diff --git a/README.md b/README.md index fd5e6de6..cab4ad97 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ -Development: [![Coverage Status](https://coveralls.io/repos/github/TRI-AMDD/mpet/badge.svg?branch=development)](https://coveralls.io/github/TRI-AMDD/mpet?branch=development) -Master: [![Coverage Status](https://coveralls.io/repos/github/TRI-AMDD/mpet/badge.svg?branch=master)](https://coveralls.io/github/TRI-AMDD/mpet?branch=master) +[![Build](https://img.shields.io/github/actions/workflow/status/TRI-AMDD/mpet/mpet-regression-test.yml?branch=development)](https://github.com/TRI-AMDD/mpet/actions/workflows/mpet-regression-test.yml) +[![Coverage Status](https://coveralls.io/repos/github/TRI-AMDD/mpet/badge.svg?branch=development)](https://coveralls.io/github/TRI-AMDD/mpet?branch=development) +[![readthedocs](https://readthedocs.org/projects/mpet/badge/?version=latest)](https://mpet.readthedocs.io) +[![release](https://img.shields.io/github/v/release/TRI-AMDD/mpet)](https://github.com/TRI-AMDD/mpet/releases) + # MPET -- Multiphase Porous Electrode Theory This software is designed to run simulations of batteries with porous electrodes using porous electrode theory, which is a volume-averaged, multiscale approach to capture the coupled behavior of electrolyte and active material within electrodes. As a result, with physical parameter inputs and run protocols (specified current or voltage profiles), it makes predictions about the internal dynamics within a battery (electrolyte concentration and potential, solid phase concentrations, reaction rates, etc.) and also macroscopic, easily measurable electrochemical quantities such as total current and voltage. In this way, it is similar to the [`dualfoil`](http://www.cchem.berkeley.edu/jsngrp/fortran.html) code released by Newman and coworkers from Berkeley. This software has much of the functionality contained in `dualfoil` (it is currently missing, e.g., temperature dependence). However, beyond the standard porous electrode theory simulations, this software can also simulate electrodes in which the active materials phase separate using non-equilibrium thermodynamics within a phase field modeling framework. Such behavior is common in widely used electrode materials, including graphite and LiFePO4. diff --git a/configs/params_NMC532_Colclasure20.cfg b/configs/params_NMC532_Colclasure20.cfg new file mode 100644 index 00000000..886e9fb2 --- /dev/null +++ b/configs/params_NMC532_Colclasure20.cfg @@ -0,0 +1,23 @@ +#Cathode parameters from A. Colclasure et al., J. Electrochim. Acta 337, 135854 (2020). +# See params_electrodes.cfg for parameter explanations. + +[Particles] +type = diffn +discretization = 9.e-8 +shape = sphere +thickness = 10e-6 + +[Material] +muRfunc = NMC532_Colclasure20 +noise = false +noise_prefac = 1e-6 +numnoise = 200 +rho_s = 2.9869e28 +D = 1 +Dfunc = NMC532_Colclasure20 + +[Reactions] +rxnType = BV_Colclasure20 +k0 = 10 +alpha = 0.5 +Rfilm = 0e-0 diff --git a/configs/params_graphite_Colclasure20.cfg b/configs/params_graphite_Colclasure20.cfg new file mode 100644 index 00000000..417e69e9 --- /dev/null +++ b/configs/params_graphite_Colclasure20.cfg @@ -0,0 +1,23 @@ +#Cathode parameters from A. Colclasure et al., J. Electrochim. Acta 337, 135854 (2020). +# See params_electrodes.cfg for parameter explanations. + +[Particles] +type = diffn +discretization = 2.e-7 +shape = sphere +thickness = 20e-9 + +[Material] +muRfunc = LiC6_Colclasure_1506T +noise = false +noise_prefac = 1e-6 +numnoise = 200 +rho_s = 1.6862e28 +D = 3.0e-14 +Dfunc = constant + +[Reactions] +rxnType = BV_mod01 +k0 = 11 +alpha = 0.5 +Rfilm = 0.e-0 diff --git a/configs/params_system_Colclasure20.cfg b/configs/params_system_Colclasure20.cfg new file mode 100644 index 00000000..62330bbf --- /dev/null +++ b/configs/params_system_Colclasure20.cfg @@ -0,0 +1,114 @@ +#Parameters for the low loading cell (1.5 mAh/cm^2) from A. Colclasure et al., J. Electrochim. Acta 337, 135854 (2020). +# See params_system.cfg for parameter explanations. + +[Sim Params] +# Constant voltage or current or segments of one of them +# Options: CV, CC, CCsegments, CVsegments +profileType = CC +# Battery (dis)charge c-rate (only used for CC), number of capacities / hr +# (positive for discharge, negative for charge) +Crate=-2 +#Optional nominal 1C current density for the cell, A/m^2 +1C_current_density = 13.475 +# Voltage cutoffs, V +Vmax = 4.1 +Vmin = 0 +# Continuation directory. +# Options: false, absolute directory path +prevDir = false +# Final time (only used for CV), [s] +tend = 1.2e4 +# Number disc. in time +tsteps = 200 +# Numerical Tolerances +relTol = 1e-6 +absTol = 1e-6 +# Temperature, K +T = 303.15 +# Random seed. Set to true to give a random seed in the simulation +randomSeed = false +# Value of the random seed, must be an integer +seed = 0 +# Series resistance, [Ohm m^2] +Rser = 0. +# Cathode, anode, and separator numer disc. in x direction (volumes in electrodes) +Nvol_c = 20 +Nvol_s = 10 +Nvol_a = 20 +# Number of particles per volume for cathode and anode +Npart_c = 1 +Npart_a = 1 + +[Electrodes] +cathode = params_NMC532_Colclasure20.cfg +anode = params_graphite_Colclasure20.cfg +# Rate constant of the Li foil electrode, A/m^2 +# Used only if Nvol_a = 0 +k0_foil = 1e0 +# Film resistance on the Li foil, Ohm m^2 +Rfilm_foil = 0e-0 + +[Particles] +# electrode particle size distribution info, m +mean_c = 1.8e-6 +stddev_c = 0e-9 +mean_a = 4.0e-6 +stddev_a = 0e-9 +# Initial electrode filling fractions +cs0_c = 0.91 +cs0_a = 0.05 + +[Conductivity] +# Simulate bulk cathode conductivity (Ohm's Law)? +simBulkCond_c = false +simBulkCond_a = false +# Dimensional conductivity (used if simBulkCond = true), S/m +sigma_s_c = 1e-1 +sigma_s_a = 1e-1 +# Simulate particle connectivity losses (Ohm's Law)? +# Options: true, false +simPartCond_c = false +simPartCond_a = false +# Conductance between particles, S = 1/Ohm +G_mean_c = 1e-14 +G_stddev_c = 0 +G_mean_a = 1e-14 +G_stddev_a = 0 + +[Geometry] +# Thicknesses, m +L_c = 42e-6 +L_a = 47e-6 +L_s = 20e-6 +# Volume loading percents of active material (volume fraction of solid +# that is active material) +P_L_c = 0.7803 +P_L_a = 0.9026 +# Porosities (liquid volume fraction in each region) +poros_c = 0.33 +poros_a = 0.37 +poros_s = 0.39 +# Bruggeman exponent (tortuosity = porosity^bruggExp) +BruggExp_c = -1.0 +BruggExp_a = -1.2 +BruggExp_s = -1.3 + +[Electrolyte] +# Initial electrolyte conc., mol/m^3 +c0 = 1200 +# Cation/anion charge number (e.g. 2, -1 for CaCl_2) +zp = 1 +zm = -1 +# Cation/anion dissociation number (e.g. 1, 2 for CaCl_2) +nup = 1 +num = 1 +# Electrolyte model, +# Options: dilute, SM +elyteModelType = SM +# Stefan-Maxwell property set, see props_elyte.py file +SMset = Colclasure20 +# Reference electrode (defining the electrolyte potential) information: +# number of electrons transfered in the reaction, 1 for Li/Li+ +n = 1 +# Stoichiometric coefficient of cation, -1 for Li/Li+ +sp = -1 diff --git a/dockerfiles/Dockerfile-daetools b/dockerfiles/Dockerfile-daetools-1.9.0 similarity index 100% rename from dockerfiles/Dockerfile-daetools rename to dockerfiles/Dockerfile-daetools-1.9.0 diff --git a/dockerfiles/Dockerfile-daetools-2.0.0 b/dockerfiles/Dockerfile-daetools-2.0.0 new file mode 100644 index 00000000..5f7c5e38 --- /dev/null +++ b/dockerfiles/Dockerfile-daetools-2.0.0 @@ -0,0 +1,11 @@ +FROM python:3.10-bullseye + +#Install necessary packages for daetools +RUN apt-get update && \ + apt-get install --yes libgl1-mesa-glx libgfortran5 + +#Download and install daetools +RUN wget https://sourceforge.net/projects/daetools/files/daetools/2.0.0/daetools-2.0.0-gnu_linux-x86_64.zip && \ + unzip daetools-2.0.0-gnu_linux-x86_64.zip && \ + pip install ./daetools-2.0.0-gnu_linux-x86_64 && \ + rm -r ./daetools* diff --git a/dockerfiles/Dockerfile-mpet-deps b/dockerfiles/Dockerfile-mpet-deps deleted file mode 100644 index 632aa813..00000000 --- a/dockerfiles/Dockerfile-mpet-deps +++ /dev/null @@ -1,6 +0,0 @@ -FROM vikko00/daetools:1.9.0 - -#Install mpet dependencies - -RUN pip install numpy scipy matplotlib pyQt5 h5py -RUN pip install coverage coveralls pytest diff --git a/mpet/config/configuration.py b/mpet/config/configuration.py index 9ef9f37b..e1c6a70e 100644 --- a/mpet/config/configuration.py +++ b/mpet/config/configuration.py @@ -140,10 +140,6 @@ def _init_from_cfg(self, paramfile): if self.D_s['Nvol_a'] > 0: trodes.append('a') self['trodes'] = trodes - # to check for separator, directly access underlying dict of system config; - # self['Nvol']['s'] would not work because that requires have_separator to - # be defined already - self['have_separator'] = self.D_s['Nvol_s'] > 0 # load electrode parameter file(s) self.paramfiles = {} @@ -506,7 +502,7 @@ def _scale_electrode_parameters(self): self[trode, param] = value / kT # scalings on separator - if self['have_separator']: + if self['Nvol']['s']: self['L']['s'] /= self['L_ref'] def _scale_macroscopic_parameters(self, Vref): @@ -761,7 +757,7 @@ def _distr_part(self): # For homogeneous particles (only one 'volume' per particle) elif solidType in ['homog', 'homog_sdn', 'homog2', 'homog2_sdn']: # Each particle is only one volume - psd_num = np.ones(raw.shape, dtype=np.int) + psd_num = np.ones(raw.shape, dtype=int) # The lengths are given by the original length distr. psd_len = raw else: diff --git a/mpet/config/parameterset.py b/mpet/config/parameterset.py index 7d2460ee..b306c0d2 100644 --- a/mpet/config/parameterset.py +++ b/mpet/config/parameterset.py @@ -87,7 +87,7 @@ def __getitem__(self, item): d = {} # some parameters are also defined for the separator trodes = self['trodes'][:] # make a copy here to avoid adding values to the original - if item in PARAMS_SEPARATOR and self['have_separator']: + if item in PARAMS_SEPARATOR: trodes.append('s') for trode in trodes: # get the value for this electrode/separator and store it diff --git a/mpet/electrode/diffusion/NMC532_Colclasure20.py b/mpet/electrode/diffusion/NMC532_Colclasure20.py new file mode 100644 index 00000000..3d8c6ef8 --- /dev/null +++ b/mpet/electrode/diffusion/NMC532_Colclasure20.py @@ -0,0 +1,4 @@ +def NMC532_Colclasure20(y): + cm2_s = 20000.*10**(-2319.*y**10 + 6642.*y**9 - 5269.*y**8 - 3319.*y**7 + 10038.*y**6 + - 9806.*y**5 + 5817.*y**4 - 2286.*y**3 + 575.3*y**2 - 83.16*y-9.292) + return cm2_s/1e4 diff --git a/mpet/electrode/materials/LiC6_Colclasure_1506T.py b/mpet/electrode/materials/LiC6_Colclasure_1506T.py new file mode 100644 index 00000000..4e8a0c5d --- /dev/null +++ b/mpet/electrode/materials/LiC6_Colclasure_1506T.py @@ -0,0 +1,29 @@ +import numpy as np + + +def LiC6_Colclasure_1506T(self, y, ybar, muR_ref, ISfuncs=None): + """Taken from Colclasure 2020, but only for lithiating. The range of\ + confidence is 0.01 to 0.97 for voltages of ~0.6V and \ + 0.0435V. Don’t calculate U2 for intercalation fractions below 0.8, \ + it will cause numeric issues just use U1.""" + x = y + U1 = \ + - 1.059423355572770E-02*np.tanh((x - 1.453708425609560E-02) / 9.089868397988610E-05) \ + + 2.443615203087110E-02*np.tanh((x - 5.464261369950400E-01) / 6.270508166379020E-01) \ + - 1.637520788053810E-02*np.tanh((x - 5.639025014475490E-01) / 7.053886409518520E-02) \ + - 6.542365622896410E-02*np.tanh((x - 5.960370524233590E-01) / 1.409966536648620E+00) \ + - 4.173226059293490E-02*np.tanh((x - 1.787670587868640E-01) / 7.693844911793470E-02) \ + - 4.792178163846890E-01*np.tanh((x + 3.845707852011820E-03) / 4.112633446959460E-02) \ + + 6.594735004847470E-01 \ + - 4.364293924074990E-02*np.tanh((x - 9.449231893318330E-02) / -2.046776012570780E-02) \ + - 8.241166396760410E-02*np.tanh((x - 7.746685789572230E-02) / 3.593817905677970E-02) + U2 = \ + -1.731504647676420E+02*np.power(x, 8.0) + 8.252008712749000E+01*np.power(x, 7.0) \ + + 1.233160814852810E+02*np.power(x, 6.0) + 5.913206621637760E+01*np.power(x, 5.0) \ + + 3.322960033709470E+01*np.power(x, 4.0) + 3.437968012320620E+00*np.power(x, 3.0) \ + - 6.906367679257650E+01*np.power(x, 2.0) - \ + 1.228217254296760E+01*x - 5.037944982759270E+01 + U = U1 + (U2 - U1) / (1.0 + np.exp(-1.0e2*(x - 1.02956203215198))) + muR = self.get_muR_from_OCV(U, muR_ref) + actR = None + return muR, actR diff --git a/mpet/electrode/materials/NMC532_Colclasure20.py b/mpet/electrode/materials/NMC532_Colclasure20.py new file mode 100644 index 00000000..52da0c5a --- /dev/null +++ b/mpet/electrode/materials/NMC532_Colclasure20.py @@ -0,0 +1,18 @@ +import numpy as np + + +def NMC532_Colclasure20(self, y, ybar, muR_ref, ISfuncs=None): + x = y + OCV = (5.314735633000300E+00 + + -3.640117692001490E+03*x**14.0 + 1.317657544484270E+04*x**13.0 + - 1.455742062291360E+04*x**12.0 - 1.571094264365090E+03*x**11.0 + + 1.265630978512400E+04*x**10.0 - 2.057808873526350E+03*x**9.0 + - 1.074374333186190E+04*x**8.0 + 8.698112755348720E+03*x**7.0 + - 8.297904604107030E+02*x**6.0 - 2.073765547574810E+03*x**5.0 + + 1.190223421193310E+03*x**4.0 - 2.724851668445780E+02*x**3.0 + + 2.723409218042130E+01*x**2.0 - 4.158276603609060E+00*x + + -5.573191762723310E-04*np.exp(6.560240842659690E+00*x**4.148209275061330E+01) + ) + muR = self.get_muR_from_OCV(OCV, muR_ref) + actR = None + return muR, actR diff --git a/mpet/electrode/reactions/BV_Colclasure20.py b/mpet/electrode/reactions/BV_Colclasure20.py new file mode 100644 index 00000000..b38f2d02 --- /dev/null +++ b/mpet/electrode/reactions/BV_Colclasure20.py @@ -0,0 +1,11 @@ +import numpy as np + + +def BV_Colclasure20(eta, c_sld, c_lyte, k0, E_A, T, act_R=None, + act_lyte=None, lmbda=None, alpha=None): + """Implemented for the Finegan 2020/Colclasure 2020 model comparison + for the NMC electrode""" + ecd = k0 * (165*c_sld**5 - 752.4*c_sld**4 + 1241*c_sld**3 + - 941.7*c_sld**2 + 325*c_sld - 35.85) * (c_lyte/1.2)**0.5 + Rate = ecd * (np.exp(-alpha*eta/T) - np.exp((1-alpha)*eta/T)) + return Rate diff --git a/mpet/electrolyte/Colclasure20.py b/mpet/electrolyte/Colclasure20.py new file mode 100644 index 00000000..5c9c3314 --- /dev/null +++ b/mpet/electrolyte/Colclasure20.py @@ -0,0 +1,54 @@ +import numpy as np +from mpet.config import constants + + +def Colclasure20(): + def tp0(Ce, T): + T = T*constants.T_ref # T has units in this model + Acoeff_Trfn = -0.0000002876102*T**2 + 0.0002077407*T - 0.03881203 + Bcoeff_Trfn = 0.000001161463*T**2 - 0.00086825*T + 0.1777266 + Ccoeff_Trfn = -0.0000006766258*T**2 + 0.0006389189*T + 0.3091761 + + return (Acoeff_Trfn*Ce**2 + Bcoeff_Trfn*Ce + + Ccoeff_Trfn) + + def D(Ce, T): + T = T*constants.T_ref # T has units in this model + D_00 = -0.5688226 + D_01 = -1607.003 + D_10 = -0.8108721 + D_11 = 475.291 + D_20 = -0.005192312 + D_21 = -33.43827 + T_g0 = -24.83763 + T_g1 = 64.07366 + return (10**(D_00 + D_01 / (T - (T_g0 + T_g1 * Ce)) + + (D_10 + D_11 / (T - (T_g0 + T_g1 * Ce)))*Ce + + (D_20 + D_21 / (T - (T_g0 + T_g1 * Ce)))*Ce**2)*0.0001) + + def therm_fac(c, T): + T = T*constants.T_ref # T has units in this model + return 1 + 0.341*np.exp(261/T)-0.00225*np.exp(1360/T)*c + 0.54*np.exp(329/T)*c**2 + + def sigma(Ce, T): + T = T*constants.T_ref # T has units in this model + Acoeff_Kappa = 0.0001909446*T**2 - 0.08038545*T + 9.00341 + Bcoeff_Kappa = -0.00000002887587*T**4 + 0.00003483638*T**3 - 0.01583677*T**2 \ + + 3.195295*T - 241.4638 + Ccoeff_Kappa = 0.00000001653786*T**4 - 0.0000199876*T**3 + 0.009071155*T**2 \ + - 1.828064*T + 138.0976 + Dcoeff_Kappa = -0.000000002791965*T**4 + 0.000003377143 * \ + T**3 - 0.001532707*T**2 + 0.3090003*T - 23.35671 + + return (Ce * (Acoeff_Kappa + Bcoeff_Kappa * Ce + + Ccoeff_Kappa * Ce**2 + Dcoeff_Kappa * Ce**3)) + + Dref = D(constants.c_ref/1000, 1) + + def D_ndim(c, T): + return D(c, T) / Dref + + def sigma_ndim(c, T): + return sigma(c, T) * ( + constants.k*constants.T_ref/(constants.e**2*Dref*constants.N_A*constants.c_ref)) + return D_ndim, sigma_ndim, therm_fac, tp0, Dref diff --git a/mpet/mod_cell.py b/mpet/mod_cell.py index 635f1fbd..798921b5 100644 --- a/mpet/mod_cell.py +++ b/mpet/mod_cell.py @@ -41,7 +41,7 @@ def __init__(self, config, Name, Parent=None, Description=""): # Domains where variables are distributed self.DmnCell = {} # domains over full cell dimensions self.DmnPart = {} # domains over particles in each cell volume - if config['have_separator']: # If we have a separator + if config['Nvol']['s']: # If we have a separator self.DmnCell["s"] = dae.daeDomain( "DmnCell_s", self, dae.unit(), "Simulated volumes in the separator") @@ -86,7 +86,7 @@ def __init__(self, config, Name, Parent=None, Description=""): self.ffrac[trode] = dae.daeVariable( "ffrac_{trode}".format(trode=trode), mole_frac_t, self, "Overall filling fraction of solids in electrodes") - if config['have_separator']: # If we have a separator + if config['Nvol']['s']: # If we have a separator self.c_lyte["s"] = dae.daeVariable( "c_lyte_s", conc_t, self, "Concentration in the electrolyte in the separator", @@ -98,7 +98,7 @@ def __init__(self, config, Name, Parent=None, Description=""): # Note if we're doing a single electrode volume simulation # It will be in a perfect bath of electrolyte at the applied # potential. - if ('a' not in config['trodes']) and (not config['have_separator']) and Nvol["c"] == 1: + if ('a' not in config['trodes']) and (not config['Nvol']['s']) and Nvol["c"] == 1: self.SVsim = True else: self.SVsim = False @@ -322,16 +322,11 @@ def DeclareEquations(self): ecd = config["k0_foil"]*cWall**0.5 # note negative current because positive current is # oxidation here - BVfunc = -self.current() / ecd - eta_eff = 2*np.arcsinh(-BVfunc/2.) - eta = eta_eff + self.current()*config["Rfilm_foil"] - # eta = mu_R - mu_O = -mu_O (evaluated at interface) - # mu_O = [T*ln(c) +] phiWall - phi_cell = -eta - # phiWall = -eta + phi_cell [- T*ln(c)] - phiWall = -eta + self.phi_cell() + eta = self.phi_cell() - self.current()*config["Rfilm_foil"] \ + - .5*(phitmp[0] + phitmp[1]) if config["elyteModelType"] == "dilute": - phiWall -= config["T"]*np.log(cWall) - eqP.Residual = phiWall - .5*(phitmp[0] + phitmp[1]) + eta -= config["T"]*np.log(cWall) + eqP.Residual = self.current() - ecd*2*np.sinh(eta/2) # We have a porous anode -- no flux of charge or anions through current collector else: diff --git a/mpet/plot/plot_data.py b/mpet/plot/plot_data.py index 17796bc6..1fa5f164 100644 --- a/mpet/plot/plot_data.py +++ b/mpet/plot/plot_data.py @@ -72,7 +72,7 @@ def show_data(indir, plot_type, print_flag, save_flag, data_only, vOut=None, pOu dxvec = np.array(Nvol["c"] * [dxc]) porosvec = np.array(Nvol["c"] * [config["poros"]["c"]]) cellsvec = dxc*np.arange(Nvol["c"]) + dxc/2. - if config["have_separator"]: + if config["Nvol"]["s"]: dxs = config["L"]["s"]/Nvol["s"] dxvec_s = np.array(Nvol["s"] * [dxs]) dxvec = np.hstack((dxvec_s, dxvec)) @@ -116,7 +116,7 @@ def show_data(indir, plot_type, print_flag, save_flag, data_only, vOut=None, pOu # print "Actual psd_stddev [nm]:", np.std(psd_len[l]) print("Cell structure:") print(("porous anode | " if "a" in config["trodes"] else "flat anode | ") - + ("sep | " if config["have_separator"] else "") + "porous cathode") + + ("sep | " if config["Nvol"]["s"] else "") + "porous cathode") if "a" in config["trodes"]: print("capacity ratio cathode:anode, 'z':", config["z"]) for trode in trodes: @@ -139,7 +139,7 @@ def show_data(indir, plot_type, print_flag, save_flag, data_only, vOut=None, pOu print("Specified psd_stddev, c [{unit}]:".format(unit=Lunit), np.array(config['stddev']["c"])*Lfac) print("ndim B_c:", config["c", "B"]) - if config["have_separator"]: + if config["Nvol"]["s"]: print("Nvol_s:", Nvol["s"]) print("Nvol_c:", Nvol["c"]) if 'a' in config["trodes"]: @@ -330,7 +330,7 @@ def show_data(indir, plot_type, print_flag, save_flag, data_only, vOut=None, pOu datay_p = utils.get_dict_key(data, p_cath, squeeze=False) L_c = config['L']["c"] * config['L_ref'] * Lfac Ltot = L_c - if config["have_separator"]: + if config["Nvol"]["s"]: datay_s_c = utils.get_dict_key(data, c_sep, squeeze=False) datay_s_p = utils.get_dict_key(data, p_sep, squeeze=False) datay_c = np.hstack((datay_s_c, datay_c)) diff --git a/mpet/sim.py b/mpet/sim.py index 3d46c769..77fe2356 100644 --- a/mpet/sim.py +++ b/mpet/sim.py @@ -46,7 +46,7 @@ def __init__(self, config, tScale=None): def SetUpParametersAndDomains(self): # Domains config = self.config - if config["have_separator"]: + if config["Nvol"]["s"]: self.m.DmnCell["s"].CreateArray(config["Nvol"]["s"]) for tr in config["trodes"]: self.m.DmnCell[tr].CreateArray(config["Nvol"][tr]) @@ -118,7 +118,7 @@ def SetUpVariables(self): self.m.phi_lyteGP_L.SetInitialGuess(0) # Separator electrolyte initialization - if config["have_separator"]: + if config["Nvol"]["s"]: for i in range(Nvol["s"]): self.m.c_lyte["s"].SetInitialCondition(i, config['c0']) self.m.phi_lyte["s"].SetInitialGuess(i, 0) @@ -186,7 +186,7 @@ def SetUpVariables(self): k, data[partStr + "c1"][-1,k]) part.c2.SetInitialCondition( k, data[partStr + "c2"][-1,k]) - if config["have_separator"]: + if config["Nvol"]["s"]: for i in range(Nvol["s"]): self.m.c_lyte["s"].SetInitialCondition( i, data["c_lyte_s"][-1,i]) diff --git a/mpet/utils.py b/mpet/utils.py index 2dbd862a..e5a15385 100644 --- a/mpet/utils.py +++ b/mpet/utils.py @@ -88,7 +88,7 @@ def get_dxvec(L, Nvol): dxa = Nvol["a"] * [L["a"]/Nvol["a"]] else: dxa = [] - if "s" in Nvol: + if Nvol["s"]: dxs = Nvol["s"] * [L["s"]/Nvol["s"]] else: dxs = [] diff --git a/mpet/version.py b/mpet/version.py index c3bb2961..1c98a23a 100644 --- a/mpet/version.py +++ b/mpet/version.py @@ -1 +1 @@ -__version__ = '0.1.8' +__version__ = '0.1.9'