Source code for sisl.shape.prism4

from numbers import Real
import numpy as np

from .base 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 def __repr__(self): v = np.append(self.origo, self.edge_length) return self.__class__.__name__ + ' O({} {} {}) L({} {} {})'.format(*v)
[docs] def set_center(self, center): """ Re-setting the center can sometimes be necessary """ self.__init__(self.edge_length, center)
[docs] def set_origo(self, origo): """ Re-setting the origo can sometimes be necessary """ self.__init__(self.edge_length, origo + self.edge_length * .5)
@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 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 """ # Retrieve indices idx = self.iwithin(other) if isinstance(other, (list, tuple)): other = np.asarray(other, np.float64) if isinstance(other, np.ndarray): other.shape = (-1, 3) full = np.empty(len(other), dtype='bool') full[:] = False full[idx] = True return full raise NotImplementedError('within could not determine the extend of the `other` object')
[docs] def iwithin(self, other): """ 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, :] el = self.edge_length[:] # First reject those that are definitely not inside land = np.logical_and ix = land(land(land(0 <= tmp[:, 0], tmp[:, 0] <= el[0]), land(0 <= tmp[:, 1], tmp[:, 1] <= el[1])), land(0 <= tmp[:, 2], tmp[:, 2] <= el[2])).nonzero()[0] return ix
## This below is for a skewed box #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)] #return within
[docs]class Cube(Cuboid): """ A cuboid/rectangular prism (P4) with all-equi faces """ def __init__(self, edge_length, center=None): super(Cube, self).__init__(edge_length, center)