openpnm.topotools.generate_base_points(num_points, domain_size, density_map=None, reflect=True)[source]

Generates a set of base points for passing into the Tessellation-based Network classes. The points can be distributed in spherical, cylindrical, or rectilinear patterns, as well as 2D and 3D (disks and squares).

  • num_points (scalar) – The number of base points that lie within the domain. Note that the actual number of points returned will be larger, with the extra points lying outside the domain.

  • domain_size (list or array) –

    Controls the size and shape of the domain, as follows:

    sphere : If a single value is received, its treated as the radius [r] of a sphere centered on [0, 0, 0].

    cylinder : If a two-element list is received it’s treated as the radius and height of a cylinder [r, z] positioned at [0, 0, 0] and extending in the positive z-direction. If the z dimension is 0, a disk of radius r is created.

    rectangle : If a three element list is received, it’s treated as the outer corner of rectangle [x, y, z] whose opposite corner lies at [0, 0, 0]. If the z dimension is 0, a rectangle of size X-by-Y is created.

  • density_map (array, optional) –

    A an array that contains fractional values (0 < i < 1) indicating the liklihood that a point in that region should be kept. The size of this array can be anything, but the shape must match the domain_size; that is for a 3D network the shape of the density_map can be [10, 10, 10] or [50, 50, 50], depending on how important the resolution of the density distribution is. For a 2D network the density_map should be [10, 10].

    When specifying a custom probabiliy map is it recommended to also set values outside the given domain to zero. If not, then the correct shape will still be returned, but with too few points in it.

  • reflect (bool) – If True, the the base points are generated as specified, the reflected about each face of the domain. This essentially tricks the tessellation functions into creating smoothfaces at the boundaries once these excess pores are trimmed.


The reflection approach tends to create larger pores near the surfaces, so it might be necessary to use the density_map argument to specify a slightly higher density of points near the surfaces.

The Voronoi, Delaunay, Gabriel, and DelunayVoronoiDual classes can techncially handle base points with spherical or cylindrical domains, but the reflection across round surfaces does not create perfect Voronoi cells so the surfaces will not be smooth.


The following generates a spherical array with higher values near the core. It uses a distance transform to create a sphere of radius 10, then a second distance transform to create larger values in the center away from the sphere surface. These distance values could be further skewed by applying a power, with values higher than 1 resulting in higher values in the core, and fractional values smoothinging them out a bit.

>>> import openpnm as op
>>> import scipy as sp
>>> import scipy.ndimage as spim
>>> im = np.ones([21, 21, 21], dtype=int)
>>> im[10, 10, 10] = 0
>>> im = spim.distance_transform_edt(im) <= 20  # Create sphere of 1's
>>> prob = spim.distance_transform_edt(im)
>>> prob = prob / np.amax(prob)  # Normalize between 0 and 1
>>> pts = op.topotools.generate_base_points(num_points=50,
...                                         domain_size=[1, 1, 1],
...                                         density_map=prob)
>>> net =, shape=[1, 1, 1])