def add_ghost_meshes(self): """ Create meshes for potential ghost nodes on either side of each submesh, using self.submeshclass This will be useful for calculating the gradient with Dirichlet BCs. """ # Get all submeshes relating to space (i.e. exclude time) submeshes = [ (domain, submesh_list) for domain, submesh_list in self.items() if not isinstance(submesh_list[0], (pybamm.SubMesh0D, pybamm.ScikitSubMesh2D)) ] for domain, submesh_list in submeshes: self[domain + "_left ghost cell"] = [None] * len(submesh_list) self[domain + "_right ghost cell"] = [None] * len(submesh_list) for i, submesh in enumerate(submesh_list): edges = submesh.edges # left ghost cell: two edges, one node, to the left of existing submesh lgs_edges = np.array([2 * edges[0] - edges[1], edges[0]]) self[domain + "_left ghost cell"][i] = pybamm.SubMesh1D( lgs_edges, submesh.coord_sys) # right ghost cell: two edges, one node, to the right of # existing submesh rgs_edges = np.array([edges[-1], 2 * edges[-1] - edges[-2]]) self[domain + "_right ghost cell"][i] = pybamm.SubMesh1D( rgs_edges, submesh.coord_sys)
def combine_submeshes(self, *submeshnames): """Combine submeshes into a new submesh, using self.submeshclass Raises pybamm.DomainError if submeshes to be combined do not match up (edges are not aligned). Parameters ---------- submeshnames: list of str The names of the submeshes to be combined Returns ------- submesh: :class:`self.submeshclass` A new submesh with the class defined by self.submeshclass """ # Check that the final edge of each submesh is the same as the first edge of the # next submesh for i in range(len(submeshnames) - 1): for j in range(len(self[submeshnames[i]])): if (self[submeshnames[i]][j].edges[-1] != self[submeshnames[i + 1]][j].edges[0]): raise pybamm.DomainError("submesh edges are not aligned") coord_sys = self[submeshnames[i]][0].coord_sys coord_sys_r = self[submeshnames[i + 1]][0].coord_sys if coord_sys != coord_sys_r: raise pybamm.DomainError( "trying to combine two meshes in different coordinate systems" ) submeshes = [None] * len(self[submeshnames[0]]) # Hack for the special case of current collector if submeshnames == ("current collector", ) and isinstance( self[submeshnames[0]][0].edges, dict): return self[submeshnames[0]] for i in range(len(self[submeshnames[0]])): combined_submesh_edges = np.concatenate( [self[submeshnames[0]][i].edges] + [ self[submeshname][i].edges[1:] for submeshname in submeshnames[1:] ]) coord_sys = self[submeshnames[0]][i].coord_sys submeshes[i] = pybamm.SubMesh1D(combined_submesh_edges, coord_sys) # add in internal boundaries submeshes[i].internal_boundaries = [ self[submeshname][i].edges[0] for submeshname in submeshnames[1:] ] return submeshes
def combine_submeshes(self, *submeshnames): """Combine submeshes into a new submesh, using self.submeshclass Raises pybamm.DomainError if submeshes to be combined do not match up (edges are not aligned). Parameters ---------- submeshnames: list of str The names of the submeshes to be combined Returns ------- submesh: :class:`self.submeshclass` A new submesh with the class defined by self.submeshclass """ if submeshnames == (): raise ValueError("Submesh domains being combined cannot be empty") # If there is just a single submesh, we can return it directly if len(submeshnames) == 1: return self[submeshnames[0]] # Check that the final edge of each submesh is the same as the first edge of the # next submesh for i in range(len(submeshnames) - 1): if self[submeshnames[i]].edges[-1] != self[submeshnames[i + 1]].edges[0]: raise pybamm.DomainError("submesh edges are not aligned") coord_sys = self[submeshnames[i]].coord_sys coord_sys_r = self[submeshnames[i + 1]].coord_sys if coord_sys != coord_sys_r: raise pybamm.DomainError( "trying to combine two meshes in different coordinate systems" ) combined_submesh_edges = np.concatenate( [self[submeshnames[0]].edges] + [self[submeshname].edges[1:] for submeshname in submeshnames[1:]] ) coord_sys = self[submeshnames[0]].coord_sys submesh = pybamm.SubMesh1D(combined_submesh_edges, coord_sys) # add in internal boundaries submesh.internal_boundaries = [ self[submeshname].edges[0] for submeshname in submeshnames[1:] ] return submesh
def test_tabs(self): edges = np.linspace(0, 1, 10) tabs = {"negative": {"z_centre": 0}, "positive": {"z_centre": 1}} mesh = pybamm.SubMesh1D(edges, None, tabs=tabs) self.assertEqual(mesh.tabs["negative tab"], "left") self.assertEqual(mesh.tabs["positive tab"], "right")
def test_exceptions(self): edges = np.linspace(0, 1, 10) tabs = {"negative": {"z_centre": 0.2}, "positive": {"z_centre": 1}} with self.assertRaises(pybamm.GeometryError): pybamm.SubMesh1D(edges, None, tabs=tabs)