Exemplo n.º 1
0
def get_norm_cgto(ang_number,exponents,coefs_shell):
    """Gets the norms of contracted GTOs in a shell."""
    from math import sqrt,pow
    from BioNanoLEGO.DenseMatrix import asmatrix,empty
    # Threshold of the norms
    NORM_THRESHOLD = 1e-17
    # Gets the number of contractions
    num_contrs = len(coefs_shell)
    # Gets the number of primitives
    num_prims = len(exponents)
    # Initializes the norms of contracted GTOs
    norm_cgto = [0]*num_contrs
    # Sets the power
    expnt_power = float(ang_number)+1.5
    # Sets up the matrix of radical overlap between two primitive GTOs
    rad_overlap = asmatrix(empty((num_prims,num_prims)))
    for iprim in xrange(num_prims):
        for jprim in xrange(num_prims):
            rad_overlap[iprim,jprim] = \
                pow(2*sqrt(exponents[iprim]*exponents[jprim])/ \
                    (exponents[iprim]+exponents[jprim]),expnt_power)
    # Gets the norms of contracted GTOs
    for icontr in xrange(num_contrs):
        coeff_matrix = asmatrix(coefs_shell[icontr])
        norm_cgto[icontr] = sqrt((coeff_matrix*rad_overlap*coeff_matrix.transpose())[0,0])
        if norm_cgto[icontr] < NORM_THRESHOLD:
            raise ZeroDivisionError("Norm '%f' of CGTO '%d' is smaller than the threshold '%f'!" \
                                    % (norm_cgto[icontr],icontr,NORM_THRESHOLD))
    return norm_cgto
Exemplo n.º 2
0
    def getOneInt(self,other,operator,**options):
        """Calculates the integral of an one-electron operator.

        other: Basis sets of ket.

        molecule: Molecule class defined in Molecule.py.

        operator: One-electron operator, function object, see Gen1Int.py for example.
        """
        from BioNanoLEGO.DenseMatrix import empty,asmatrix
        # Parallelize here, using dynamic parallelization
        #     MASTER sends first initial jobs to all SLAVES, SLAVES do the job,
        #     and send the results back, MASTER receives the result from one SLAVE,
        #     does some computations (like reduce the number of working nodes),
        #     and sends new job to it with job_tag and increases the number of
        #     working nodes, or sends terminator_tag.
        # Sets up the integral matrix, using row-major order
        one_int = asmatrix(empty((self.num_basis_functions,other.num_basis_functions)))
        #from Parallel import mpi
        for idx_bra in xrange(self.num_shells):
            # Indices of basis functions in bra-shell
            strt_row = self.idx_shell[idx_bra]+1
            end_row = self.idx_shell[idx_bra+1]
            for idx_ket in xrange(other.num_shells):
                # Indices of basis functions in ket-shell
                strt_col = other.idx_shell[idx_ket]+1
                end_col = other.idx_shell[idx_ket+1]
Exemplo n.º 3
0
    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
Exemplo n.º 4
0
    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