def getCentMass(self): """Gets the center of mass of the molecule.""" from BioNanoLEGO.DenseMatrix import zeros self.cent_of_mass = zeros((3), "d") total_mass = 0.0 for atom in self.atoms: atom_mass = atom.getAtomcMass() self.cent_of_mass += atom_mass * atom.getCoords() total_mass += atom_mass self.cent_of_mass /= total_mass return
def getInertiaTensor(self): """Gets the moment of inertia tensor.""" from BioNanoLEGO.DenseMatrix import zeros, asmatrix self.inertia_tensor = asmatrix(zeros((3, 3)), "d") for atom in self.atoms: atom_mass = atom.getAtomcMass() x, y, z = atom.getCoords() x2, y2, z2 = x * x, y * y, z * z self.inertia_tensor[0, 0] += atom_mass * (y2 + z2) self.inertia_tensor[1, 1] += atom_mass * (x2 + z2) self.inertia_tensor[2, 2] += atom_mass * (x2 + y2) self.inertia_tensor[0, 1] -= atom_mass * x * y self.inertia_tensor[1, 0] = self.inertia_tensor[0, 1] self.inertia_tensor[0, 2] -= atom_mass * x * z self.inertia_tensor[2, 0] = self.inertia_tensor[0, 2] self.inertia_tensor[1, 2] -= atom_mass * y * z self.inertia_tensor[2, 1] = self.inertia_tensor[1, 2] return
def __init__(self, name="molecule", atom_list=[], **options): """Creates a molecule. name: The name of the molecule. Default is 'molecule'. atom_list: A list of (atomic_symbol or atomic_number,(x,y,z)) of the molecule. Default is []. isotope_list: A list of isotope selection (atom_index,isotope), where the atom index starts from 0. Default is the most abundant isotope. unit: Length unit for the coordinates. Default is Bohr. charge: The charge of the molecule. Default is 0. multiplicity: The spin multiplicity of the molecule. Default is 1. inertial_coord: Transforms the molecule to inertial coordinates, i.e., translating to let the center of mass be zero origin, and rotating so that the moment of inertia tensor becomes a diagonal matrix. Default is making such transformation. """ from BioNanoLEGO.Element import get_atomic_symbol, get_atomic_number from BioNanoLEGO.DenseMatrix import asmatrix, zeros, eigh, diag self.name = name # Default is no pseudopotential self.pseudopotential = False unit = options.get("unit", "bohr") unit = unit.lower()[:4] if unit not in DEFINED_UNITS: raise ValueError("Unknown length unit '%s'!" % unit) self.charge = int(options.get("charge", 0)) self.multiplicity = int(options.get("multiplicity", 1)) inertial_coord = options.get("inertial_coord", True) # Gets the user specified isotope selections isotope_list = options.get("isotope_list", []) # Initializes atoms self.atoms = [] self.num_electrons = -int(self.charge) if atom_list: self.num_atoms = int(len(atom_list)) # Sets up the isotope selections isotopes = [None] * self.num_atoms for atom_idx, isotope in isotope_list: isotopes[atom_idx] = int(isotope) # Sets up the atoms atom_idx = int(0) for atomic_number, coords in atom_list: if unit == "angs": coords = angs_to_bhor(coords[0], coords[1], coords[2]) # The atomic symbol is given if type(atomic_number) == type(""): atom_name = atomic_number atomic_number = get_atomic_number(atom_name) # The atomic number is given elif type(atomic_number) == type(0): atom_name = get_atomic_symbol(atomic_number) else: raise TypeError("Atomic symbol or atomic number is expected for atom '%d'!" % atom_idx) new_atom = Atom(atom_idx, atom_name, atomic_number, isotopes[atom_idx], coords) self.atoms.append(new_atom) self.num_electrons += new_atom.getNumElectrons() atom_idx += 1 # Dumps coordinates print "Coordinates: " for atom in self.atoms: print atom.getCoords() # Gets the center of mass self.getCentMass() if inertial_coord: print "Translating to center of mass: ", self.cent_of_mass self.translate(-self.cent_of_mass) self.cent_of_mass = zeros((3), "d") # Gets the moment of inertia tensor self.getInertiaTensor() if inertial_coord: E, U = eigh(self.inertia_tensor) print "Rotation matrix: ", U self.rotate(U) self.inertia_tensor = asmatrix(diag(E)) print "New moment of inertia tensor: ", self.inertia_tensor print "New coordinates: " for atom in self.atoms: print atom.getCoords() else: self.num_atoms = int(0) return