The mesh defines how each domain in the battery geometry is divided into discrete cells. PyBaMM provides several 1D submesh types with different node distributions, plus a 2D submesh for current-collector problems.
pybamm.Mesh
pybamm.Mesh(geometry, submesh_types, var_pts)
Geometry dictionary produced by e.g. pybamm.battery_geometry() after calling param.process_geometry(geometry).
Maps domain name → submesh class or MeshGenerator instance. Example:{
"negative electrode": pybamm.Uniform1DSubMesh,
"separator": pybamm.Uniform1DSubMesh,
"positive electrode": pybamm.Uniform1DSubMesh,
}
Maps spatial variable → number of cell-centre nodes. Can use variable objects or name strings as keys:{pybamm.standard_spatial_vars.x_n: 10,
pybamm.standard_spatial_vars.x_s: 5,
pybamm.standard_spatial_vars.x_p: 10,
pybamm.standard_spatial_vars.r_n: 10,
pybamm.standard_spatial_vars.r_p: 10}
import pybamm
model = pybamm.lithium_ion.SPM()
param = pybamm.ParameterValues("Chen2020")
geometry = model.default_geometry
param.process_geometry(geometry)
var_pts = {
pybamm.standard_spatial_vars.x_n: 10,
pybamm.standard_spatial_vars.x_s: 5,
pybamm.standard_spatial_vars.x_p: 10,
pybamm.standard_spatial_vars.r_n: 10,
pybamm.standard_spatial_vars.r_p: 10,
}
submesh_types = model.default_submesh_types
mesh = pybamm.Mesh(geometry, submesh_types, var_pts)
pybamm.MeshGenerator
A thin wrapper that pairs a submesh class with any extra keyword arguments needed at construction time.
pybamm.MeshGenerator(submesh_type, submesh_params=None)
# Exponential mesh, clustered symmetrically
generator = pybamm.MeshGenerator(
pybamm.Exponential1DSubMesh,
submesh_params={"side": "symmetric", "stretch": 1.5},
)
submesh_types = {
"negative electrode": generator,
"separator": pybamm.Uniform1DSubMesh,
"positive electrode": generator,
}
Submesh Types
Uniformly spaced nodes across the domain.
Best for homogeneous domains with no boundary layers.
Exponential1DSubMesh
Exponentially stretched nodes — concentrated near one or both boundaries.
pybamm.MeshGenerator(
pybamm.Exponential1DSubMesh,
submesh_params={"side": "symmetric", "stretch": 1.15},
)
side
str
default:"\"symmetric\""
Which boundary to cluster near: "left", "right", or "symmetric".
stretch
float
default:"1.15 (symmetric) / 2.3 (left or right)"
Stretching factor α. As node count → ∞, the ratio of largest to smallest cell → exp(α).
Chebyshev1DSubMesh
Nodes placed at Chebyshev collocation points on (a, b), clustered near both boundaries.
pybamm.Chebyshev1DSubMesh
Useful when you need polynomial interpolation properties or are solving with spectral methods.
UserSupplied1DSubMesh
Use your own array of edge locations.
import numpy as np
edges = np.array([0, 0.1, 0.3, 0.6, 1.0]) # custom edge positions
generator = pybamm.MeshGenerator(
pybamm.UserSupplied1DSubMesh,
submesh_params={"edges": edges},
)
Uniform 2D mesh for current-collector domains. Requires ScikitFiniteElement as the corresponding spatial method.
Controlling Resolution with var_pts
The var_pts dictionary is the primary knob for trading accuracy against speed:
# Coarse mesh — fast
var_pts_coarse = {
pybamm.standard_spatial_vars.x_n: 5,
pybamm.standard_spatial_vars.x_s: 3,
pybamm.standard_spatial_vars.x_p: 5,
pybamm.standard_spatial_vars.r_n: 5,
pybamm.standard_spatial_vars.r_p: 5,
}
# Fine mesh — accurate
var_pts_fine = {
pybamm.standard_spatial_vars.x_n: 30,
pybamm.standard_spatial_vars.x_s: 15,
pybamm.standard_spatial_vars.x_p: 30,
pybamm.standard_spatial_vars.r_n: 30,
pybamm.standard_spatial_vars.r_p: 30,
}
String keys are also accepted:
var_pts = {"x_n": 10, "x_s": 5, "x_p": 10, "r_n": 10, "r_p": 10}