예제 #1
0
파일: Molecule.py 프로젝트: bingao/bnlego
    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
예제 #2
0
파일: Molecule.py 프로젝트: bingao/bnlego
    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
예제 #3
0
파일: Molecule.py 프로젝트: bingao/bnlego
    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