def _calc_directors(self, active_dim): """Calculate directors as the reciprocal lattice vectors. For orthorombic and triclinic simulation boxes the reciprocal lattice vectors are vectors perpendicular to each face of the simulation cell. Parameters ---------- active_dim : list of int Active dimensions each intereger must be either 0 for off or 1 for on. Returns ------- directors : numpy array(=<3,3) Directors along which to calculate the wave vector. """ # Get triclinic box vectors box_edge_vectors = mdamath.triclinic_vectors(self.universe.dimensions) # Calculate reciprocal lattice vectors recip_lat_vecs = self._calc_reciprocal_lattice_vectors( box_edge_vectors) # Remove inactive dimensions check_active_dim = [active_dim_i is 0 for active_dim_i in active_dim] del_idx_active_dim = [i for i, x in enumerate(check_active_dim) if x] directors = np.delete(recip_lat_vecs, del_idx_active_dim, axis=0) return directors
def initialize_bm(self, box): """ Store box information and define direct and reciprocal box matrices. Rows of the direct matrix are the components of the central cell vectors. Rows of the reciprocal matrix are the components of the normalized reciprocal lattice vectors. Each row of the reciprocal matrix represents the vector normal to the unit cell face associated to each axis. For instance, in an orthorhombic cell the YZ-plane is associated to the X-axis and its normal vector is (1, 0, 0). In a triclinic cell, the plane associated to vector ``\vec{a}`` is perpendicular to the normalized cross product of ``\vec{b}`` and ``\vec{c}``. Parameters ---------- box : array-like or ``None``, optional, default ``None`` Simulation cell dimensions in the form of :attr:`MDAnalysis.trajectory.base.Timestep.dimensions` when periodic boundary conditions should be taken into account for the calculation of contacts. """ box_type = _box_check(box) if box_type == 'ortho': a, b, c = box[:3] dm = np.array([[a, 0, 0], [0, b, 0], [0, 0, c]], dtype=np.float32) rm = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]], dtype=np.float32) elif box_type in 'tri_box tri_vecs tri_vecs_bad': if box_type == 'tri_box': dm = triclinic_vectors(box) elif box_type == 'tri_vecs': dm = box.copy('C') else: # case 'tri_vecs_bad' dm = triclinic_vectors(triclinic_box(box[0], box[1], box[2])) rm = np.zeros(9, dtype=np.float32).reshape(3, 3) rm[0] = np.cross(dm[1], dm[2]) rm[1] = np.cross(dm[2], dm[0]) rm[2] = np.cross(dm[0], dm[1]) for i in range(self.dim): rm[i] /= norm(rm[i]) # normalize else: raise ValueError('Failed to initialize direct/reciprocal matrices') self.box = box self._dm = dm self._rm = rm
def __init__(self, dims): assert len(dims) == 3 or len( dims) == 6, "Invalid number of box dimensions" if len(dims) == 3: dims = [*dims, 90., 90., 90] self.dims = np.array(dims) self.h = triclinic_vectors(dims) self.hinv = np.linalg.inv(self.h) boxtype, box = check_box(self.dimensions) self.boxtype = boxtype
def _write_dimensions(self, dimensions): """Convert dimensions to triclinic vectors, convert lengths to native units and then write the dimensions section """ if self.convert_units: triv = self.convert_pos_to_native(mdamath.triclinic_vectors( dimensions),inplace=False) self.f.write('\n') self.f.write('{:f} {:f} xlo xhi\n'.format(0., triv[0][0])) self.f.write('{:f} {:f} ylo yhi\n'.format(0., triv[1][1])) self.f.write('{:f} {:f} zlo zhi\n'.format(0., triv[2][2])) if any([triv[1][0], triv[2][0], triv[2][1]]): self.f.write('{xy:f} {xz:f} {yz:f} xy xz yz\n'.format( xy=triv[1][0], xz=triv[2][0], yz=triv[2][1])) self.f.write('\n')
def count_counterions(u, ion_group, counterion_group, pore_group, framestart, nframes_per_window): count = 0 for i, frame in enumerate(u.trajectory[framestart : framestart + nframes_per_window]): box_vectors = np.mat(triclinic_vectors(u.trajectory.dimensions)) box_inv = linalg.inv(box_vectors) reference_atom = pore_group[0].position z_start = reference_atom z_end = reference_atom z_start_atom = pore_group[0] z_end_atom = pore_group[0] for atom in pore_group[1:]: next_atom_minimum_disp = minimum_image_disp(box_vectors, reference_atom - atom.position, box_inv) next_atom_pos = reference_atom - next_atom_minimum_disp if next_atom_pos[2] < z_start[2]: z_start = next_atom_pos z_start_aotm = atom if next_atom_pos[2] > z_end[2]: z_end = next_atom_pos z_end_atom = atom z_center_of_pore = (z_start + z_end) / 2 # these two atoms' positions are in the same periodic image print_ion = False for cion in counterion_group: z_pos = reference_atom - minimum_image_disp(box_vectors, reference_atom - cion.position, box_inv) if z_pos[2] > z_start[2] and z_pos[2] < z_end[2]: count += 1 print_ion = True if print_ion: ion_minimum_image_disp = minimum_image_disp(box_vectors, ion_group[0].position - z_center_of_pore, box_inv) print(ion_minimum_image_disp[2]) return count
def test_set_triclinic_vectors(self): ref_vec = triclinic_vectors(self.newbox) self.ts.triclinic_dimensions = ref_vec assert_equal(self.ts.dimensions, self.newbox) assert_allclose(self.ts._unitcell, self.unitcell)
def test_triclinic_vectors(self): assert_allclose(self.ts.triclinic_dimensions, triclinic_vectors(self.ts.dimensions))
def test_set_triclinic_vectors(self, ts): ref_vec = triclinic_vectors(self.newbox) ts.triclinic_dimensions = ref_vec assert_equal(ts.dimensions, self.newbox) assert_equal(ts._unitcell, self.unitcell)
# Displacement vector subtraction with Periodic Boundary Conditions def vector(posA, posB, boxvec): vec = posA - posB for i in range(3): dot = np.dot(vec, boxvec[i]) / np.dot(boxvec[i], boxvec[i]) if dot > .5: vec -= boxvec[i] elif dot < -.5: vec += boxvec[i] return vec fout = open(folder + 'cationpi.dat', 'w') for ts in u.trajectory: sys.stdout.write('\rTime = %d' % u.trajectory.time) boxvec = mdamath.triclinic_vectors(u.dimensions) for ipi in range(npigroup): pigroup = pigroups[ipi] picenter = pigroup.centroid(pbc=True) for icat in range(ncat): cation = cations[icat] dist = distances.calc_bonds(coords1=cation.position, coords2=picenter, box=u.dimensions) if dist < 7.0: vec = vector(cation.position, picenter, boxvec) v1 = vector(pigroup.positions[0], pigroup.positions[5], boxvec) v2 = vector(pigroup.positions[1], pigroup.positions[4], boxvec) v3 = vector(pigroup.positions[2], pigroup.positions[3], boxvec) n1 = mdamath.normal(v1, v2) n2 = mdamath.normal(v3, v1)
import pytest import numpy as np from numpy.testing import assert_equal, assert_almost_equal from MDAnalysis.lib.pkdtree import PeriodicKDTree from MDAnalysis.lib.mdamath import triclinic_vectors, triclinic_box from MDAnalysis.lib.distances import (_box_check, transform_RtoS, transform_StoR, apply_PBC) # # Testing initialization with different boxes. # boxes_1 = (np.array([1, 2, 3, 90, 90, 90], dtype=np.float32), # ortho np.array([1, 2, 3, 30, 45, 60], dtype=np.float32), # tri_box triclinic_vectors( # tri_vecs np.array([1, 2, 3, 90, 90, 45], dtype=np.float32)), np.array([[0.5, 0.9, 1.9], # tri_vecs_bad [2.0, 0.4, 0.1], [0.0, 0.6, 0.5]], dtype=np.float32) ) rec_m = (np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]], dtype=np.float32), np.array([[0.67044002, -0.38707867, -0.6329931], [0, 0.54741204, -0.83686334], [0, 0, 1]], dtype=np.float32), np.array([[0.707106829, -0.707106829, 0], [0, 1, 0], [0, 0, 1]], dtype=np.float32), np.array([[0.42783618, -0.16049984, -0.88949198], [-0, 0.95654362, 0.29158944],