Source code for pysic.utility.geometry

#! /usr/bin/env python

from math import sqrt, pi, sin, cos, exp, fabs, floor
import numpy as np


[docs]class Cell: """Cell describing the simulation volume of a subvolume. This class can be used by the user for coordinate manipulation. Note however, that ASE does not use on this class, as it is part of Pysic. The class is merely a tool for examining the geometry. Parameters: vector1: list of doubles 3-vector specifying the first vector spanning the cell :math:`\mathbf{v}_1` vector2: list of doubles 3-vector specifying the second vector spanning the cell :math:`\mathbf{v}_2` vector3: list of doubles 3-vector specifying the third vector spanning the cell :math:`\mathbf{v}_3` pbc: list of logicals three logic switches for specifying periodic boundaries - True denotes periodicity """ def __init__(self,vector1,vector2,vector3,pbc): self.vector1 = np.array( vector1 ) self.vector2 = np.array( vector2 ) self.vector3 = np.array( vector3 ) self.matrix = np.array( [vector1,vector2,vector3] ).transpose() self.inverse = np.linalg.inv(self.matrix) self.pbc = pbc
[docs] def get_relative_coordinates(self,coordinates): """Returns the coordinates of the given atom in fractional coordinates. The absolute position of the atom is given by multiplying the cell vectors by the fractional coordinates. Parameters: coordinates: numpy double 3-vector the absolute coordinates """ return self.inverse.dot(coordinates)
[docs] def get_absolute_coordinates(self,fractional): """For the given fractional coordinates, returns the absolute coordinates. The absolute coordinates are the cell vectors multiplied by the fractional coordinates. Parameters: fractional: numpy double 3-vector the fractional coordinates """ return self.matrix.dot(fractional)
[docs] def get_wrapped_coordinates(self,coordinates): """Wraps the coordinates of the given atom inside the simulation cell. This method return the equivalent position (with respect to the periodic boundaries) of the atom inside the cell. For instance, if the cell is spanned by vectors of length 10.0 in directions of :math:`x`, :math:`y`, and :math:`z`, an the coordinates [-1.0, 12.0, 3.0] wrap to [9.0, 2.0, 3.0]. Parameters: coordinates: numpy double 3-vector the absolute coordinates """ rel_coord = self.get_relative_coordinates(coordinates) new_coord = np.array([0.0,0.0,0.0]) for ind in range(3): if self.pbc[ind]: new_coord[ind] = rel_coord[ind] % 1.0 else: new_coord[ind] = rel_coord[ind] return self.get_absolute_coordinates(new_coord)
[docs] def get_distance(self,atom1,atom2,offsets=None): """Calculates the distance between two atoms. Offsets are multipliers for the cell vectors to be added to the plain separation vector r1-r2 between the atoms. Parameters: atom1: ASE Atoms object first atom atom2: ASE Atoms object second atom offsets: Numpy integer 3-vector the periodic boundary offsets """ vec = self.get_separation(atom1,atom2,offsets) return sqrt(vec.dot(vec))
[docs] def get_separation(self, atom1, atom2, offsets=None): """Returns the separation vector between two atoms, r1-r2. Offsets are multipliers for the cell vectors to be added to the plain separation vector r1-r2 between the atoms. Parameters: atom1: ASE Atoms object first atom atom2: ASE Atoms object second atom offsets: Numpy integer 3-vector the periodic boundary offsets """ p1 = self.get_wrapped_coordinates(atom1.get_position()) p2 = self.get_wrapped_coordinates(atom2.get_position()) if offsets == None: return p1-p2 else: return p1-p2 - self.matrix.dot(offsets.transpose())