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
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]
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