Skip to content

Commit

Permalink
#2376 update to new schema
Browse files Browse the repository at this point in the history
  • Loading branch information
rtimms committed Nov 22, 2022
1 parent da98f9a commit d149c7a
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 79 deletions.
133 changes: 75 additions & 58 deletions pybamm/parameters/bpx.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,15 @@ class Domain:


cell = Domain(name="cell", pre_name="", short_pre_name="")
anode = Domain(name="anode", pre_name="Negative electrode ", short_pre_name="Negative ")
cathode = Domain(
name="cathode", pre_name="Positive electrode ", short_pre_name="Positive "
negative_electrode = Domain(
name="negative electrode",
pre_name="Negative electrode ",
short_pre_name="Negative ",
)
positive_electrode = Domain(
name="positive electrode",
pre_name="Positive electrode ",
short_pre_name="Positive ",
)
electrolyte = Domain(name="electrolyte", pre_name="Electrolyte ", short_pre_name="")
separator = Domain(name="separator", pre_name="Separator ", short_pre_name="")
Expand All @@ -46,8 +52,12 @@ class Domain:
def bpx_to_param_dict(bpx: BPX) -> dict:
pybamm_dict = {}
pybamm_dict = _bpx_to_param_dict(bpx.parameterisation.cell, pybamm_dict, cell)
pybamm_dict = _bpx_to_param_dict(bpx.parameterisation.anode, pybamm_dict, anode)
pybamm_dict = _bpx_to_param_dict(bpx.parameterisation.cathode, pybamm_dict, cathode)
pybamm_dict = _bpx_to_param_dict(
bpx.parameterisation.negative_electrode, pybamm_dict, negative_electrode
)
pybamm_dict = _bpx_to_param_dict(
bpx.parameterisation.positive_electrode, pybamm_dict, positive_electrode
)
pybamm_dict = _bpx_to_param_dict(
bpx.parameterisation.electrolyte, pybamm_dict, electrolyte
)
Expand All @@ -58,73 +68,74 @@ def bpx_to_param_dict(bpx: BPX) -> dict:
bpx.parameterisation.separator, pybamm_dict, experiment
)

# set a default current function and typical current
# set a default current function and typical current based on the nominal capacity
# i.e. a default C-rate of 1
pybamm_dict["Current function [A]"] = pybamm_dict["Nominal cell capacity [A.h]"]
pybamm_dict["Typical current [A]"] = pybamm_dict["Nominal cell capacity [A.h]"]

# Ambient temp
pybamm_dict["Ambient temperature [K]"] = pybamm_dict["Initial temperature [K]"]

for domain in [anode, cathode]:
# number of electrons in reaction (1 for li-ion)
for domain in [negative_electrode, positive_electrode]:
pybamm_dict[domain.pre_name + "electrons in reaction"] = 1.0

# activity
pybamm_dict["1 + dlnf/dlnc"] = 1.0

# typical electrolyte concentration
pybamm_dict["Typical electrolyte concentration [mol.m-3]"] = pybamm_dict[
"Initial concentration in electrolyte [mol.m-3]"
]

for domain in [anode, cathode]:
pybamm_dict[domain.pre_name + "OCP entropic change [V.K-1]"] = 0.0

for domain in [anode, separator, cathode]:
# assume Bruggeman relation
for domain in [negative_electrode, separator, positive_electrode]:
pybamm_dict[domain.pre_name + "Bruggeman coefficient (electrolyte)"] = 1.5
pybamm_dict[domain.pre_name + "Bruggeman coefficient (electrode)"] = 1.5

# BPX is for single-cell in series, user can chnage this later
pybamm_dict["Number of cells connected in series to make a battery"] = 1
pybamm_dict[
"Number of electrodes connected in parallel to make a cell"
] = pybamm_dict["Number of electrode pairs connected in parallel to make a cell"]

# electrode area
equal_len_width = math.sqrt(pybamm_dict["Electrode area [m2]"])
pybamm_dict["Electrode width [m]"] = equal_len_width
pybamm_dict["Electrode height [m]"] = equal_len_width

# cell geometry
pybamm_dict["Cell volume [m3]"] = (
pybamm_dict["Cell width [m]"]
* pybamm_dict["Cell height [m]"]
* pybamm_dict["Cell thickness [m]"]
)
pybamm_dict["Cell cooling surface area [m2]"] = (
2 * pybamm_dict["Cell width [m]"] * pybamm_dict["Cell thickness [m]"]
+ 2 * pybamm_dict["Cell width [m]"] * pybamm_dict["Cell height [m]"]
+ 2 * pybamm_dict["Cell thickness [m]"] * pybamm_dict["Cell height [m]"]
)

pybamm_dict["1 + dlnf/dlnc"] = 1.0
# surface area
pybamm_dict["Cell cooling surface area [m2]"] = pybamm_dict[
"Cell external surface area [m2]"
]

# lumped parameters
for name in [
"Specific heat capacity [J.K-1.kg-1]",
"Density [kg.m-3]",
"Thermal conductivity [W.m-1.K-1]",
]:
for domain in [anode, cathode, separator]:
for domain in [negative_electrode, positive_electrode, separator]:
pybamm_name = domain.pre_name + name[:1].lower() + name[1:]
if name in pybamm_dict:
pybamm_dict[pybamm_name] = pybamm_dict[name]

# BET surface area
for domain in [anode, cathode]:
for domain in [negative_electrode, positive_electrode]:
pybamm_dict[domain.pre_name + "active material volume fraction"] = (
pybamm_dict[domain.pre_name + "surface area per unit volume"]
pybamm_dict[domain.pre_name + "surface area per unit volume [m-1]"]
* pybamm_dict[domain.short_pre_name + "particle radius [m]"]
) / 3.0

# transport efficiency
for domain in [anode, separator, cathode]:
for domain in [negative_electrode, separator, positive_electrode]:
pybamm_dict[domain.pre_name + "porosity"] = pybamm_dict[
domain.pre_name + "transport efficiency"
] ** (1.0 / 1.5)

# entropic change
for domain in [negative_electrode, positive_electrode]:
pybamm_dict[domain.pre_name + "OCP entropic change [V.K-1]"] = pybamm_dict[
domain.pre_name + "entropic change coefficient [V.K-1]"
]

# reaction rates in pybamm exchange current is defined j0 = k * sqrt(ce * cs *
# (cs-cs_max)) in BPX exchange current is defined j0 = F * k_norm * sqrt((ce/ce0) *
# (cs/cs_max) * (1-cs/cs_max))
Expand All @@ -134,17 +145,19 @@ def bpx_to_param_dict(bpx: BPX) -> dict:
T_ref = pybamm_dict["Reference temperature [K]"]
F = 96485

# anode
# negative electrode
c_n_max = pybamm_dict[
"Maximum concentration in " + anode.pre_name.lower() + "[mol.m-3]"
"Maximum concentration in " + negative_electrode.pre_name.lower() + "[mol.m-3]"
]
k_n_norm = pybamm_dict[
negative_electrode.pre_name + "reaction rate constant [mol.m-2.s-1]"
]
k_n_norm = pybamm_dict[anode.pre_name + "reaction rate [mol.m-2.s-1]"]
E_a_n = pybamm_dict.get(
anode.pre_name + "reaction rate activation energy [J.mol-1]", 0.0
negative_electrode.pre_name + "reaction rate activation energy [J.mol-1]", 0.0
)
k_n = k_n_norm * F / (c_n_max * c_e**0.5)

def anode_exchange_current_density(c_e, c_s_surf, c_s_max, T):
def negative_electrode_exchange_current_density(c_e, c_s_surf, c_s_max, T):
k_ref = k_n # (A/m2)(m3/mol)**1.5 - includes ref concentrations

arrhenius = exp(E_a_n / constants.R * (1 / T_ref - 1 / T))
Expand All @@ -156,21 +169,23 @@ def anode_exchange_current_density(c_e, c_s_surf, c_s_max, T):
* (c_s_max - c_s_surf) ** 0.5
)

pybamm_dict[anode.pre_name + "exchange-current density [A.m-2]"] = copy_func(
anode_exchange_current_density
)
pybamm_dict[
negative_electrode.pre_name + "exchange-current density [A.m-2]"
] = copy_func(negative_electrode_exchange_current_density)

# cathode
# positive electrode
c_p_max = pybamm_dict[
"Maximum concentration in " + cathode.pre_name.lower() + "[mol.m-3]"
"Maximum concentration in " + positive_electrode.pre_name.lower() + "[mol.m-3]"
]
k_p_norm = pybamm_dict[
positive_electrode.pre_name + "reaction rate constant [mol.m-2.s-1]"
]
k_p_norm = pybamm_dict[cathode.pre_name + "reaction rate [mol.m-2.s-1]"]
E_a_p = pybamm_dict.get(
cathode.pre_name + "reaction rate activation energy [J.mol-1]", 0.0
positive_electrode.pre_name + "reaction rate activation energy [J.mol-1]", 0.0
)
k_p = k_p_norm * F / (c_p_max * c_e**0.5)

def cathode_exchange_current_density(c_e, c_s_surf, c_s_max, T):
def positive_electrode_exchange_current_density(c_e, c_s_surf, c_s_max, T):
k_ref = k_p # (A/m2)(m3/mol)**1.5 - includes ref concentrations

arrhenius = exp(E_a_p / constants.R * (1 / T_ref - 1 / T))
Expand All @@ -183,54 +198,56 @@ def cathode_exchange_current_density(c_e, c_s_surf, c_s_max, T):
)

pybamm_dict[domain.pre_name + "exchange-current density [A.m-2]"] = copy_func(
cathode_exchange_current_density
positive_electrode_exchange_current_density
)

# diffusivity

# TODO: allow setting function parameters in a loop over domains
T_ref = pybamm_dict["Reference temperature [K]"]

# anode
# negative electrode
E_a = pybamm_dict.get(
anode.pre_name + "diffusivity activation energy [J.mol-1]", 0.0
negative_electrode.pre_name + "diffusivity activation energy [J.mol-1]", 0.0
)
D_n_ref = pybamm_dict[anode.pre_name + "diffusivity [m2.s-1]"]
D_n_ref = pybamm_dict[negative_electrode.pre_name + "diffusivity [m2.s-1]"]

if callable(D_n_ref):

def anode_diffusivity(sto, T):
def negative_electrode_diffusivity(sto, T):
arrhenius = exp(E_a / constants.R * (1 / T_ref - 1 / T))
return arrhenius * D_n_ref(sto)

else:

def anode_diffusivity(sto, T):
def negative_electrode_diffusivity(sto, T):
arrhenius = exp(E_a / constants.R * (1 / T_ref - 1 / T))
return arrhenius * D_n_ref

pybamm_dict[anode.pre_name + "diffusivity [m2.s-1]"] = copy_func(anode_diffusivity)
pybamm_dict[negative_electrode.pre_name + "diffusivity [m2.s-1]"] = copy_func(
negative_electrode_diffusivity
)

# cathode
# positive electrode
E_a = pybamm_dict.get(
cathode.pre_name + "diffusivity activation energy [J.mol-1]", 0.0
positive_electrode.pre_name + "diffusivity activation energy [J.mol-1]", 0.0
)
D_p_ref = pybamm_dict[cathode.pre_name + "diffusivity [m2.s-1]"]
D_p_ref = pybamm_dict[positive_electrode.pre_name + "diffusivity [m2.s-1]"]

if callable(D_p_ref):

def cathode_diffusivity(sto, T):
def positive_electrode_diffusivity(sto, T):
arrhenius = exp(E_a / constants.R * (1 / T_ref - 1 / T))
return arrhenius * D_p_ref(sto)

else:

def cathode_diffusivity(sto, T):
def positive_electrode_diffusivity(sto, T):
arrhenius = exp(E_a / constants.R * (1 / T_ref - 1 / T))
return arrhenius * D_p_ref

pybamm_dict[cathode.pre_name + "diffusivity [m2.s-1]"] = copy_func(
cathode_diffusivity
pybamm_dict[positive_electrode.pre_name + "diffusivity [m2.s-1]"] = copy_func(
positive_electrode_diffusivity
)

# electrolyte
Expand Down
45 changes: 24 additions & 21 deletions tests/unit/test_parameters/test_parameter_values.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@
import unittest
import inspect
import importlib
import json

import numpy as np
import pandas as pd

import pybamm
import tests
print(tests.__file__)
import tests.shared as shared
from pybamm.input.parameters.lithium_ion.Marquis2019 import (
lico2_ocp_Dualfoil1998,
Expand Down Expand Up @@ -1032,23 +1031,24 @@ def test_bpx(self):
"BPX": 1.0,
"Title": "Parametrisation example",
"Description": "NMC Pouch",
"Model": "Newman",
"Model": "DFN",
},
"Parameterisation": {
"Cell": {
"Ambient temperature [K]": 298.15,
"Initial temperature [K]": 298.15,
"Reference temperature [K]": 298.15,
"Nominal cell capacity [A.h]": 5.0,
"Lower voltage cut-off [V]": 2.8,
"Upper voltage cut-off [V]": 4.2,
"Nominal cell capacity [A.h]": 12.5,
"Specific heat capacity [J.K-1.kg-1]": 913,
"Thermal conductivity [W.m-1.K-1]": 2,
"Density [kg.m-3]": 1847,
"Electrode area [m2]": 0.016808,
"Number of electrodes connected in parallel to make a cell": 34,
"Cell height [m]": 191e-03,
"Cell width [m]": 88e-03,
"Number of electrode pairs connected "
"in parallel to make a cell": 34,
"Cell external surface area [m2]": 3.79e-2,
"Cell volume [m3]": 1.28e-4,
"Cell thickness [m]": 7.6e-03,
},
"Electrolyte": {
Expand All @@ -1059,12 +1059,13 @@ def test_bpx(self):
"- 2.51 * (x / 1000) ** 1.5 + 3.329 * (x / 1000)"
),
"Diffusivity [m2.s-1]": (
"8.794e-11 * (x / 1000) ** 2 " "- 3.972e-10 * (x / 1000) + 4.862e-10"
"8.794e-11 * (x / 1000) ** 2 "
"- 3.972e-10 * (x / 1000) + 4.862e-10"
),
"Conductivity activation energy [J.mol-1]": 34200,
"Diffusivity activation energy [J.mol-1]": 34200,
},
"Anode": {
"Negative electrode": {
"Particle radius [m]": 4.12e-06,
"Thickness [m]": 5.62e-05,
"Diffusivity [m2.s-1]": "8.6e-13 * exp(-13.5 * x) + 9.5e-15",
Expand All @@ -1075,17 +1076,18 @@ def test_bpx(self):
"9.41099327e02 * tanh(-6.91080049e-01 * (x + 2.49433043e00)) + "
"3.40646063e02 * tanh(7.27243978e-01 * (x + 1.64297574e00))"
),
"Entropic change coefficient [V.K-1]": 0,
"Conductivity [S.m-1]": 0.39,
"Surface area per unit volume": 487864,
"Surface area per unit volume [m-1]": 487864,
"Porosity": 0.33,
"Transport efficiency": 0.19,
"Reaction rate [mol.m-2.s-1]": 5.75e-06,
"Reaction rate constant [mol.m-2.s-1]": 5.75e-06,
"Initial concentration [mol.m-3]": 23370,
"Maximum concentration [mol.m-3]": 28500,
"Diffusivity activation energy [J.mol-1]": 108000,
"Reaction rate activation energy [J.mol-1]": 53400,
},
"Cathode": {
"Positive electrode": {
"Particle radius [m]": 4.6e-06,
"Thickness [m]": 5.23e-05,
"Diffusivity [m2.s-1]": (
Expand All @@ -1098,11 +1100,12 @@ def test_bpx(self):
"1.63480454 * tanh(82.26606342 * (x - 1.00945121)) - "
"10.70641562 * tanh(9.43939843 * (x - 0.79469384))"
),
"Entropic change coefficient [V.K-1]": 0,
"Conductivity [S.m-1]": 1.464,
"Surface area per unit volume": 404348,
"Surface area per unit volume [m-1]": 404348,
"Porosity": 0.385,
"Transport efficiency": 0.2389,
"Reaction rate [mol.m-2.s-1]": 2.5e-05,
"Reaction rate constant [mol.m-2.s-1]": 2.5e-05,
"Initial concentration [mol.m-3]": 26290,
"Maximum concentration [mol.m-3]": 56500,
"Diffusivity activation energy [J.mol-1]": 62400,
Expand All @@ -1116,11 +1119,9 @@ def test_bpx(self):
},
}

import json
import tempfile
filename = 'tmp.json'
filename = "tmp.json"
with tempfile.NamedTemporaryFile(
suffix=filename, delete=False, mode='w'
suffix=filename, delete=False, mode="w"
) as tmp:
# write to a tempory file so we can
# get the source later on using inspect.getsource
Expand All @@ -1131,9 +1132,11 @@ def test_bpx(self):
pv = pybamm.ParameterValues.create_from_bpx(tmp.name)

model = pybamm.lithium_ion.DFN()
experiment = pybamm.Experiment([
"Discharge at C/5 for 1 hour",
])
experiment = pybamm.Experiment(
[
"Discharge at C/5 for 1 hour",
]
)
sim = pybamm.Simulation(model, parameter_values=pv, experiment=experiment)
sim.solve()

Expand Down

0 comments on commit d149c7a

Please sign in to comment.