Source code for openpnm.network._cubic

import logging
import numpy as np
from openpnm.network import Network
from openpnm.utils import Docorator
from openpnm import topotools
from openpnm import _skgraph as skgr
skgr.settings.node_prefix = 'pore'
skgr.settings.edge_prefix = 'throat'

docstr = Docorator()
logger = logging.getLogger(__name__)
__all__ = ['Cubic']


[docs] @docstr.dedent class Cubic(Network): r""" Simple cubic lattice with connectivity from 6 to 26 Though simple, the Cubic network offers many advantages such as easy visualization and accurate determination of domain area and length in transport calculations. Parameters ---------- shape : array_like The [Nx, Ny, Nz] size of the network in terms of the number of pores in each direction. For a 2D network spacing : array_like, optional The spacing between pore centers in each direction. If not given, then [1, 1, 1] is assumed. connectivity : int, optional The number of connections to neighboring pores. Connections are made symmetrically to any combination of face, edge, or corners neighbors. The default is 6 to create a simple cubic structure, but options are: =========== ===================================================== Value Result =========== ===================================================== 6 Faces only 14 Faces and Corners 18 Faces and Edges 20 Edges and Corners 26 Faces, Edges and Corners =========== ===================================================== For a more random distribution of connectivity, use a high ``connectivity`` (i.e. 26) and then delete a fraction of the throats using ``openpnm.topotools.reduce_coordination``. Also note that corners-only and edges-only are not permitted since they create disconnected networks. If you require one of these topologies you can specify 14 or 18, then use ``openpnm.topotools.trim`` to remove the face-to-face connections, which can be identified by looking for throats with a length equal to the network spacing. %(Network.parameters)s """ def __init__(self, shape, spacing=[1, 1, 1], connectivity=6, **kwargs): super().__init__(**kwargs) net = skgr.generators.cubic(shape=shape, spacing=spacing, connectivity=connectivity, node_prefix='pore', edge_prefix='throat') self.update(net) self._post_init() self["pore.surface"] = skgr.tools.find_surface_nodes_cubic(self) Ps = self["pore.surface"] self["throat.surface"] = np.all(Ps[self["throat.conns"]], axis=1) self.update(skgr.generators.tools.label_faces_cubic(self))
[docs] def add_boundary_pores(self, labels=["top", "bottom", "front", "back", "left", "right"], spacing=None): r""" Add pores to the faces of the network for use as boundary pores. Pores are offset from the faces by 1/2 a lattice spacing such that they lie directly on the boundaries. Parameters ---------- labels : str or list[str] The labels indicating the pores defining each face where boundary pores are to be added (e.g. 'left' or ['left', 'right']) spacing : scalar or array_like The spacing of the network (e.g. [1, 1, 1]). This should be given since it can be quite difficult to infer from the network, for instance if boundary pores have already added to other faces. """ if isinstance(labels, str): labels = [labels] x, y, z = self["pore.coords"].T if spacing is None: spacing = skgr.tools.get_cubic_spacing(self) else: spacing = np.array(spacing) if spacing.size == 1: spacing = np.ones(3) * spacing Lcx, Lcy, Lcz = spacing offset = {} shape = skgr.tools.get_cubic_shape(self) offset["front"] = offset["left"] = offset["bottom"] = [0, 0, 0] offset["right"] = [Lcx * shape[0], 0, 0] offset["back"] = [0, Lcy * shape[1], 0] offset["top"] = [0, 0, Lcz * shape[2]] scale = {} scale["left"] = scale["right"] = [0, 1, 1] scale["front"] = scale["back"] = [1, 0, 1] scale["bottom"] = scale["top"] = [1, 1, 0] for label in labels: try: Ps = self.pores(label) topotools.clone_pores(network=self, pores=Ps, labels=f"{label}_boundary", mode='parents') # Translate cloned pores ind = self.pores(label + "_boundary") coords = self["pore.coords"][ind] coords = coords * scale[label] + offset[label] self["pore.coords"][ind] = coords except KeyError: msg = f"No pores labelled {label} found, skipping boundary addition" logger.warning(msg)