Source code for idaes.apps.matopt.materials.lattices.lattice

#################################################################################
# The Institute for the Design of Advanced Energy Systems Integrated Platform
# Framework (IDAES IP) was produced under the DOE Institute for the
# Design of Advanced Energy Systems (IDAES).
#
# Copyright (c) 2018-2023 by the software owners: The Regents of the
# University of California, through Lawrence Berkeley National Laboratory,
# National Technology & Engineering Solutions of Sandia, LLC, Carnegie Mellon
# University, West Virginia University Research Corporation, et al.
# All rights reserved.  Please see the files COPYRIGHT.md and LICENSE.md
# for full copyright and license information.
#################################################################################
from abc import abstractmethod
from copy import deepcopy
import numpy as np

from ..transform_func import (
    TransformFunc,
    ShiftFunc,
    ScaleFunc,
    RotateFunc,
    ReflectFunc,
)


[docs]class Lattice(object): """A class used to represent crystal lattice locations. The class encodes methods for determining which Cartesian coordinates to consider as sites on an infinite crystal lattice. A ``Lattice`` can be constructed from a point on the lattice (i.e., a shift from the origin), an alignment (i.e., rotation from a nominal orientation), and appropriate scaling factors. With these attributes, we generally support the translation, rotation, and rescaling of lattices. Additionally, ``Lattice`` objects include a method for determining which sites should be considered neighbors. """ # === DEFAULT CONSTRUCTOR def __init__(self): self._TransformFuncs = [] # === MANIPULATION METHODS def applyTransF(self, TransF): if isinstance(TransF, TransformFunc): self._TransformFuncs.append(TransF) else: raise TypeError def shift(self, Shift): if type(Shift) is ShiftFunc: self.applyTransF(Shift) elif type(Shift) is np.ndarray: self.applyTransF(ShiftFunc(Shift)) else: raise TypeError def scale(self, Scale, OriginOfScale=None): if type(Scale) is ScaleFunc: self.applyTransF(Scale) elif type(Scale) is np.ndarray: self.applyTransF(ScaleFunc(Scale, OriginOfScale)) else: raise TypeError def rotate(self, Rotation, OriginOfRotation=None): if type(Rotation) is RotateFunc: self.applyTransF(Rotation) elif type(Rotation) is np.ndarray: self.applyTransF(RotateFunc(Rotation, OriginOfRotation)) else: raise TypeError def reflect(self, Reflection): if type(Reflection) is ReflectFunc: self.applyTransF(Reflection) else: raise TypeError # === PROPERTY EVALUATION METHODS @abstractmethod def isOnLattice(self, P): raise NotImplementedError @abstractmethod def areNeighbors(self, P1, P2): raise NotImplementedError @abstractmethod def getNeighbors(self, P, layer): raise NotImplementedError def _convertFromReference(self, P): for TransF in self._TransformFuncs: TransF.transform(P) def _convertToReference(self, P): for TransF in reversed(self._TransformFuncs): TransF.undo(P) def _getConvertFromReference(self, P): result = deepcopy(P) self._convertFromReference(result) return result def _getConvertToReference(self, P): result = deepcopy(P) self._convertToReference(result) return result