Source code for sisl.shape.prism4

""" 
Implement a set of simple shapes that
"""

from numbers import Real
import numpy as np
import numpy.linalg as la

from .shape import Shape


__all__ = ['Cuboid', 'Cube']


[docs]class Cuboid(Shape): """ A cuboid/rectangular prism (P4) with equi-opposite faces """ def __init__(self, edge_length, center=None): super(Cuboid, self).__init__(center) if isinstance(edge_length, Real): # now this is really a Cube... edge_length = [edge_length] * 3 self._edge_length = np.copy(edge_length, np.float64) @property def displacement(self): """ Return the displacement vector of the Cuboid """ return self.edge_length @property def volume(self): """ Return the edge-length of the Cuboid """ return np.product(self.edge_length) @property def origo(self): """ Return the origin of the Cuboid (lower-left corner) """ return self.center - self.edge_length / 2
[docs] def set_center(self, center): """ Re-setting the center can sometimes be necessary """ self.__init__(self.edge_length, center)
@property def edge_length(self): """ Return the edge-length of the Cuboid """ return self._edge_length
[docs] def expand(self, length): """ Return a new shape with a larger corresponding to `length` """ return self(self.edge_length + length, center=self.center)
[docs] def within(self, other, return_sub=False): """ Return a `True/False` value of whether the `other` object is contained in this shape Parameters ---------- other : (`numpy.ndarray`, list, tuple) the object that is checked for containment """ if isinstance(other, (list, tuple)): other = np.asarray(other, np.float64) if isinstance(other, np.ndarray): # Figure out if th other.shape = (-1, 3) # Offset origo tmp = other[:, :] - self.origo[None, :] voxel = np.diagflat(self.edge_length) # First reject those that are definitely not inside land = np.logical_and ix = land(land(land(0 <= tmp[:, 0], tmp[:, 0] <= self.edge_length[0]), land(0 <= tmp[:, 1], tmp[:, 1] <= self.edge_length[1])), land(0 <= tmp[:, 2], tmp[:, 2] <= self.edge_length[2])) within = la.solve(voxel, tmp[ix, :].T).T # Reduce to check if they are within wtmp = land.reduce(land(0. <= within, within <=1), axis=1) ix[np.where(ix)[0]] = wtmp if return_sub: tmp = tmp[wtmp, :] + self.origo[None, :] if return_sub: return ix, tmp return ix raise NotImplementedError('within could not determine the extend of the `other` object')
[docs] def iwithin(self, other, return_sub=False): """ Return indices of the `other` object which are contained in the shape Parameters ---------- other : (`numpy.ndarray`, list, tuple) the object that is checked for containment """ if isinstance(other, (list, tuple)): other = np.asarray(other, np.float64) if not isinstance(other, np.ndarray): raise ValueError('Could not index the other list') other.shape = (-1, 3) # Offset origo tmp = other[:, :] - self.origo[None, :] voxel = np.diagflat(self.edge_length) # First reject those that are definitely not inside land = np.logical_and ix = np.where(land(land(land(0 <= tmp[:, 0], tmp[:, 0] <= self.edge_length[0]), land(0 <= tmp[:, 1], tmp[:, 1] <= self.edge_length[1])), land(0 <= tmp[:, 2], tmp[:, 2] <= self.edge_length[2])))[0] within = la.solve(voxel, tmp[ix, :].T).T # Reduce to check if they are within within = ix[land.reduce(land(0. <= within, within <=1), axis=1)] if return_sub: return within, other[within, :] return within
[docs]class Cube(Cuboid): """ A cuboid/rectangular prism (P4) with all-equi faces """ def __init__(self, edge_length, origo=None): super(Cube, self).__init__(edge_length, origo)