def run(self, geom, multiplicity=1): self.E = [] self.grada = [] coordinates3 = Coordinates3.WithExtent(len(geom)) xyz = manage_xyz.xyz_to_np(geom) for (i, (x, y, z)) in enumerate(xyz): coordinates3[i, 0] = x coordinates3[i, 1] = y coordinates3[i, 2] = z self.system.coordinates3 = coordinates3 energy = self.system.Energy(doGradients=True) # KJ energy *= units.KJ_MOL_TO_AU * units.KCAL_MOL_PER_AU # KCAL/MOL self.E.append((multiplicity, energy)) print(energy) gradient = [] for i in range(len(geom)): for j in range(3): gradient.append(self.system.scratch.gradients3[i, j] * units.KJ_MOL_TO_AU / units.ANGSTROM_TO_AU) # Ha/Bohr gradient = np.asarray(gradient) # print(gradient) self.grada.append((multiplicity, gradient))
def run(self, geom, mult, ad_idx, runtype='gradient'): coords = manage_xyz.xyz_to_np(geom) # Update coordinates of simulation (shallow-copied object) xyz_nm = 0.1 * coords # coords are in angstrom self.simulation.context.setPositions(xyz_nm) # actually compute (only applicable to ground-states,singlet mult) if mult != 1 or ad_idx > 1: raise RuntimeError('MM cant do excited states') s = self.simulation.context.getState( getEnergy=True, getForces=True, ) tmp = s.getPotentialEnergy() E = tmp.value_in_unit(openmm_units.kilocalories / openmm_units.moles) self._Energies[(mult, ad_idx)] = self.Energy(E, 'kcal/mol') F = s.getForces() G = -1.0 * np.asarray( F.value_in_unit(openmm_units.kilocalories / openmm_units.moles / openmm_units.angstroms)) self._Gradients[(mult, ad_idx)] = self.Gradient(G, 'kcal/mol/Angstrom') self.hasRanForCurrentCoords = True return
def eckart_frame( geom, masses, ): """ Moves the molecule to the Eckart frame Params: geom ((natoms,4) np.ndarray) - Contains atom symbol and xyz coordinates masses ((natoms) np.ndarray) - Atom masses Returns: COM ((3), np.ndarray) - Molecule center of mess L ((3), np.ndarray) - Principal moments O ((3,3), np.ndarray)- Principle axes of inertial tensor geom2 ((natoms,4 np.ndarray) - Contains new geometry (atom symbol and xyz coordinates) """ # Center of mass COM = np.sum(manage_xyz.xyz_to_np(geom) * np.outer(masses, [1.0] * 3), 0) / np.sum(masses) # Inertial tensor I = np.zeros((3, 3)) for atom, mass in zip(geom, masses): I[0, 0] += mass * (atom[1] - COM[0]) * (atom[1] - COM[0]) I[0, 1] += mass * (atom[1] - COM[0]) * (atom[2] - COM[1]) I[0, 2] += mass * (atom[1] - COM[0]) * (atom[3] - COM[2]) I[1, 0] += mass * (atom[2] - COM[1]) * (atom[1] - COM[0]) I[1, 1] += mass * (atom[2] - COM[1]) * (atom[2] - COM[1]) I[1, 2] += mass * (atom[2] - COM[1]) * (atom[3] - COM[2]) I[2, 0] += mass * (atom[3] - COM[2]) * (atom[1] - COM[0]) I[2, 1] += mass * (atom[3] - COM[2]) * (atom[2] - COM[1]) I[2, 2] += mass * (atom[3] - COM[2]) * (atom[3] - COM[2]) I /= np.sum(masses) # Principal moments/Principle axes of inertial tensor L, O = np.linalg.eigh(I) # Eckart geometry geom2 = manage_xyz.np_to_xyz( geom, np.dot((manage_xyz.xyz_to_np(geom) - np.outer(np.ones( (len(masses), )), COM)), O)) return COM, L, O, geom2
def pick_best_orb_from_lots(self, lots): ''' The idea is that this would take a list of lots and pick the best one for a node Untested! ''' rmsds = [] xyz1 = manage_xyz.xyz_to_np(self.geom) for lot in lots: rmsds.append(lot.rmsd(xyz1, lot.self.currentCoords)) minnode = rmsds.index(min(rmsds)) self.lot = self.lot.copy(lots[minnode]) return
def parse_grad( self, state, tempfileout=None, ): if tempfileout is None: tempfileout = 'scratch/{:03}/{}/output.dat'.format( self.ID, self.node_id) # GET GRADIENT FOR QMMMM -- REGULAR GRADIENT IS PARSED THROUGH grad.xyz # QMMM is done differently :( if "prmtop" in self.file_options.ActiveOptions: tmpgrad = [] with open(tempfileout, "r") as f: for line in f: if line.startswith("dE/dX", 8): for i in range(self.QM_atoms): findline = next(f, '').strip() mobj = re.match(r'(\S+)\s+(\S+)\s+(\S+)\s*$', findline) tmpgrad.append([ float(mobj.group(1)), float(mobj.group(2)), float(mobj.group(3)), ]) for i in range(self.link_atoms): next(f) # read two lines seperating the QM and MM regions next(f) next(f) for i in range(self.MM_atoms): findline = next(f, '').strip() mobj = re.match(r'(\S+)\s+(\S+)\s+(\S+)\s*$', findline) tmpgrad.append([ float(mobj.group(1)), float(mobj.group(2)), float(mobj.group(3)), ]) tmpgrad = np.asarray(tmpgrad) grad = np.zeros_like(tmpgrad) grad[self.qmindices] = tmpgrad[:len(self.qmindices)] grad[self.mm_indices] = tmpgrad[len(self.qmindices):] else: # getting gradient of non-prmtop job gradfile = 'scratch/{:03}/{}/grad_{}_{}.xyz'.format( self.ID, self.node_id, state[0], state[1]) grad = manage_xyz.read_xyz(gradfile, scale=1.0) grad = manage_xyz.xyz_to_np(grad) self._Gradients[state] = self.Gradient(grad, "Hartree/Bohr")
def parse_coup(self): tempfileout = 'scratch/{:03}/{}/output.dat'.format( self.ID, self.node_id) if "prmtop" in self.file_options.ActiveOptions: tmpcoup = [] with open(tempfileout, "r") as f: for line in f: if line.startswith("dE/dX", 8): # will work for SA-MC and RSPT2 HF for i in range(self.QM_atoms): findline = next(f, '').strip() mobj = re.match(r'(\S+)\s+(\S+)\s+(\S+)\s*$', findline) tmpcoup.append([ float(mobj.group(1)), float(mobj.group(2)), float(mobj.group(3)), ]) # read link atoms for i in range(self.link_atoms): next(f) next(f) next( f ) # read two lines seperating the QM and MM regions for i in range(self.MM_atoms): findline = next(f, '').strip() mobj = re.match(r'(\S+)\s+(\S+)\s+(\S+)\s*$', findline) tmpcoup.append([ float(mobj.group(1)), float(mobj.group(2)), float(mobj.group(3)), ]) tmpcoup = np.asarray(tmpcoup) coup = np.zeros_like(tmpcoup) coup[self.qmindices] = tmpcoup[:len(self.qmindices)] coup[self.mm_indices] = tmpcoup[len(self.qmindices):] else: coupfile = 'scratch/{:03}/{}/coup_{}_{}.xyz'.format( self.ID, self.node_id, self.coupling_states[0], self.coupling_states[1]) coup = manage_xyz.read_xyz(coupfile, scale=1.0) coup = manage_xyz.xyz_to_np(coup) self.Couplings[self.coupling_states] = self.Coupling( coup, 'Hartree/Bohr')
def vibrational_basis( geom, masses, ): """ Compute the vibrational basis in mass-weighted Cartesian coordinates. This is the null-space of the translations and rotations in the Eckart frame. Params: geom (geometry struct) - minimimum geometry structure masses (list of float) - masses for the geometry Returns: B ((3*natom, 3*natom-6) np.ndarray) - orthonormal basis for vibrations. Mass-weighted cartesians in rows, mass-weighted vibrations in columns. """ # Compute Eckart frame geometry # L,O are the Principle moments/Principle axes of the intertial tensor COM, L, O, geom2 = eckart_frame(geom, masses) G = manage_xyz.xyz_to_np(geom2) # Known basis functions for translations TR = np.zeros((3 * len(geom), 6)) # Translations TR[0::3, 0] = np.sqrt(masses) # +X TR[1::3, 1] = np.sqrt(masses) # +Y TR[2::3, 2] = np.sqrt(masses) # +Z # Rotations in the Eckart frame for A, mass in enumerate(masses): mass_12 = np.sqrt(mass) for j in range(3): TR[3 * A + j, 3] = +mass_12 * ( G[A, 1] * O[j, 2] - G[A, 2] * O[j, 1]) # + Gy Oz - Gz Oy TR[3 * A + j, 4] = -mass_12 * ( G[A, 0] * O[j, 2] - G[A, 2] * O[j, 0]) # - Gx Oz + Gz Ox TR[3 * A + j, 5] = +mass_12 * ( G[A, 0] * O[j, 1] - G[A, 1] * O[j, 0]) # + Gx Oy - Gy Ox # Single Value Decomposition (review) U, s, V = np.linalg.svd(TR, full_matrices=True) # The null-space of TR B = U[:, 6:] return B
def copy_from_options(MoleculeA, xyz=None, fnm=None, new_node_id=1, copy_wavefunction=True): """Create a copy of MoleculeA""" print(" Copying from MoleculA {}".format(MoleculeA.node_id)) PES = type(MoleculeA.PES).create_pes_from( PES=MoleculeA.PES, options={'node_id': new_node_id}) if xyz is not None: new_geom = manage_xyz.np_to_xyz(MoleculeA.geometry, xyz) coord_obj = type(MoleculeA.coord_obj)( MoleculeA.coord_obj.options.copy().set_values({"xyz": xyz})) elif fnm is not None: new_geom = manage_xyz.read_xyz(fnm, scale=1.) xyz = manage_xyz.xyz_to_np(new_geom) coord_obj = type(MoleculeA.coord_obj)( MoleculeA.coord_obj.options.copy().set_values({"xyz": xyz})) else: new_geom = MoleculeA.geometry coord_obj = type(MoleculeA.coord_obj)( MoleculeA.coord_obj.options.copy()) return Molecule(MoleculeA.Data.copy().set_values({ 'PES': PES, 'coord_obj': coord_obj, 'geom': new_geom, 'node_id': new_node_id, 'copy_wavefunction': copy_wavefunction, }))
raise RuntimeError self.hasRanForCurrentCoords = True return if __name__ == "__main__": # ,units.ANGSTROM_TO_AU) geom = manage_xyz.read_xyz('../../data/ethylene.xyz') B = BAGEL.from_options(states=[(1, 0), (1, 1)], gradient_states=[(1, 0), (1, 1)], coupling_states=(0, 1), geom=geom, lot_inp_file='bagel.txt', node_id=0) coords = manage_xyz.xyz_to_np(geom) E0 = B.get_energy(coords, 1, 0) E1 = B.get_energy(coords, 1, 1) g0 = B.get_gradient(coords, 1, 0) g1 = B.get_gradient(coords, 1, 1) c = B.get_coupling(coords, 1, 0, 1) print(E0, E1) print(g0.T) print(g1.T) print(c.T) # for line in B.file_options.record(): # print(line) # for key,value in B.file_options.ActiveOptions.items(): # print(key,value)
def add_restraints(self, system): # Bond Restraints if self.restrain_bondfile is not None: nifty.printcool(" Adding bonding restraints!") # Harmonic constraint flat_bottom_force = openmm.CustomBondForce( 'step(r-r0) * (k/2) * (r-r0)^2') flat_bottom_force.addPerBondParameter('r0') flat_bottom_force.addPerBondParameter('k') system.addForce(flat_bottom_force) with open(self.restrain_bondfile, 'r') as input_file: for line in input_file: print(line) columns = line.split() atom_index_i = int(columns[0]) atom_index_j = int(columns[1]) r0 = float(columns[2]) k = float(columns[3]) flat_bottom_force.addBond(atom_index_i, atom_index_j, [r0, k]) # Torsion restraint if self.restrain_torfile is not None: nifty.printcool(" Adding torsional restraints!") # Harmonic constraint tforce = openmm.CustomTorsionForce( "0.5*k*min(dtheta, 2*pi-dtheta)^2; dtheta = abs(theta-theta0); pi = 3.1415926535" ) tforce.addPerTorsionParameter("k") tforce.addPerTorsionParameter("theta0") system.addForce(tforce) xyz = manage_xyz.xyz_to_np(self.geom) with open(self.restrain_torfile, 'r') as input_file: for line in input_file: columns = line.split() a = int(columns[0]) b = int(columns[1]) c = int(columns[2]) d = int(columns[3]) k = float(columns[4]) dih = Dihedral(a, b, c, d) theta0 = dih.value(xyz) tforce.addTorsion(a, b, c, d, [k, theta0]) # Translation restraint if self.restrain_tranfile is not None: nifty.printcool(" Adding translational restraints!") trforce = openmm.CustomExternalForce( "k*periodicdistance(x, y, z, x0, y0, z0)^2") trforce.addPerParticleParameter("k") trforce.addPerParticleParameter("x0") trforce.addPerParticleParameter("y0") trforce.addPerParticleParameter("z0") system.addForce(trforce) xyz = manage_xyz.xyz_to_np(self.geom) with open(self.restrain_tranfile, 'r') as input_file: for line in input_file: columns = line.split() a = int(columns[0]) k = float(columns[1]) x0 = xyz[a, 0] * 0.1 # Units are in nm y0 = xyz[a, 1] * 0.1 # Units are in nm z0 = xyz[a, 2] * 0.1 # Units are in nm trforce.addParticle(a, [k, x0, y0, z0])
def __init__( self, options, ): """ Constructor """ self.options = options # properties self.Energy = namedtuple('Energy', 'value unit') self.Gradient = namedtuple('Gradient', 'value unit') self.Coupling = namedtuple('Coupling', 'value unit') self._Energies = {} self._Gradients = {} self._Couplings = {} # count number of states singlets = self.search_tuple(self.states, 1) doublets = self.search_tuple(self.states, 2) triplets = self.search_tuple(self.states, 3) quartets = self.search_tuple(self.states, 4) quintets = self.search_tuple(self.states, 5) #TODO do this for all states, since it catches if states are put in lazy e.g [(1,1)] if singlets: len_singlets = max(singlets, key=lambda x: x[1])[1] + 1 else: len_singlets = 0 len_doublets = len(doublets) len_triplets = len(triplets) len_quartets = len(quartets) len_quintets = len(quintets) # DO this before fixing states if put in lazy if self.options['gradient_states'] == None and self.calc_grad: print(" Assuming gradient states are ", self.states) self.options['gradient_states'] = self.options['states'] if len( self.states ) < len_singlets + len_doublets + len_triplets + len_quartets + len_quintets: print('fixing states to be proper length') tmp = [] # TODO put in rest of fixed states for i in range(len_singlets): tmp.append((1, i)) for i in range(len_triplets): tmp.append((3, i)) self.states = tmp print(' New states ', self.states) self.geom = self.options['geom'] if self.geom is not None: print(" initializing LOT from geom") elif self.options['fnm'] is not None: print(" initializing LOT from file") if not os.path.exists(self.options['fnm']): logger.error( 'Tried to create LOT object from a file that does not exist: %s\n' % self.options['fnm']) raise IOError self.geom = manage_xyz.read_xyz(self.options['fnm'], scale=1.) else: raise RuntimeError("Need to initialize LOT object") # Cache some useful atributes - other useful attributes are properties self.currentCoords = manage_xyz.xyz_to_np(self.geom) self.atoms = manage_xyz.get_atoms(self.geom) self.ID = self.options['ID'] self.nproc = self.options['nproc'] self.charge = self.options['charge'] self.node_id = self.options['node_id'] self.lot_inp_file = self.options['lot_inp_file'] # Bools for running self.hasRanForCurrentCoords = False self.has_nelectrons = False # Read file options if they exist and not already set if self.file_options is None: self.file_options = File_Options(self.lot_inp_file) #package specific implementation #TODO MOVE to specific package !!! # tc cloud self.options['job_data']['orbfile'] = self.options['job_data'].get( 'orbfile', '') # pytc? TODO self.options['job_data']['lot'] = self.options['job_data'].get( 'lot', None) print(" making folder scratch/{:03}/{}".format(self.ID, self.node_id)) os.system('mkdir -p scratch/{:03}/{}'.format(self.ID, self.node_id))
def eckart_align(geom1,geom2,masses,rfrac,max_iter=200): COMreact = np.sum(manage_xyz.xyz_to_np(geom1) * np.outer(masses, [1.0]*3), 0) / np.sum(masses) COMproduct = np.sum(manage_xyz.xyz_to_np(geom2) * np.outer(masses, [1.0]*3), 0) / np.sum(masses) xyzreact = manage_xyz.xyz_to_np(geom1) xyzproduct = manage_xyz.xyz_to_np(geom2) # Convert to MW coordinates mwcreact = xyzreact*units.ANGSTROM_TO_AU*np.outer(np.sqrt(masses),[1.0]*3) mwcproduct = xyzproduct*units.ANGSTROM_TO_AU*np.outer(np.sqrt(masses),[1.0]*3) thetas = np.zeros(3) total_thetas = np.zeros(3) rot_mat = np.zeros((3,3)) if rfrac < 1.: max_iter=1 for i in range(maxiter): # get gradmag grad = np.zeros(3) for atom1,atom2 in zip(mwcreact,mwcproduct): grad[0] += 2*(atom1[1]*atom2[2]-atom1[2]*atom2[1]) grad[1] += 2*(atom1[2]*atom2[0]-atom1[0]*atom2[2]) grad[2] += 2*(atom1[0]*atom2[1]-atom1[1]*atom2[0]) gradmag = np.linalg(grad) print(" the gradient of the Eckart distance is %5.4f" % gradmag) # get hessian dot = np.dot(mwcreact.flatten(),mwcproduct.flatten()) xd = np.zeros((3,3)) for atom1,atom2 in zip(mwcreact,mwcproduct): xd[0,0] += atom1[0]*atom2[0] xd[1,1] += atom1[1]*atom2[1] xd[2,2] += atom1[2]*atom2[2] xd[1,0] += atom1[1]*atom2[0] xd[2,0] += atom1[2]*atom2[0] xd[2,1] += atom1[2]*atom2[1] xd[0,1] = xd[1,0] xd[0,2] = xd[2,0] xd[1,2] = xd[2,1] hess = np.zeros((3,3)) hess[0,0] = 2*(dot-xd[0,0]) hess[1,1] = 2*(dot-xd[1,1]) hess[2,2] = 2*(dot-xd[2,2]) hess[1,0] = -2*xd[1,0] hess[2,0] = -2*xd[2,0] hess[2,1] = -2*xd[2,1] hess[0,1] = hess[1,0] hess[0,2] = hess[2,0] hess[1,2] = hess[2,1] hess_evals,hess_evecs = np.linalg.eigh(hess) mag_thetas = np.linalg.norm(thetas) if gradmag<tol and all(hess_evals>0.): break temp=0. vec_index=0 for j in range(3): if hess_evals[j]<temp and abs(hess_evals[j])>0.01: temp = hess_evals[j] vec_index=j if vec_index!=0: # Rotate around structure RotMat = np.zeros((3,3)) vec = hess_evecs[vec_index] RotMat[0,0] = 2*vec[0]*vec[0] -1 RotMat[1,1] = 2*vec[1]*vec[1] -1 RotMat[2,2] = 2*vec[2]*vec[2] -1 RotMat[1,0] = 2*vec[0]*vec[1] RotMat[2,0] = 2*vec[2]*vec[0] RotMat[2,1] = 2*vec[2]*vec[1] RotMat[0,1] = RotMat[1,0] RotMat[0,2] = RotMat[2,0] RotMat[1,2] = RotMat[2,1] # rotate product mwcprod = np.dot(mwcprod,RotMat) hess_inverse = np.linalg.inv(hess) thetas = np.dot(hess_inverse,grad) thetas -= np.ones(3)*rfrac total_thetas += thetas x = thetas[0] y= thetas[1] z = thetas[2] rot_mat[0,0] = np.cos(y)*np.cos(z) rot_mat[0,1] = -np.cos(y)*np.sin(z) rot_mat[0,2] = np.sin(y) rot_mat[1,0] = np.sin(x)*np.sin(y)*np.cos(z) + np.cos(x)*np.sin(z) rot_mat[1,1] = -np.sin(x)*np.sin(y)*np.sin(z) + np.cos(x)*np.cos(z) rot_mat[1,2] = -np.sin(x)*np.cos(y) rot_mat[2,0] = -np.cos(x)*np.sin(y)*np.cos(z) + np.sin(x)*np.sin(z) rot_mat[2,1] = np.cos(x)*np.sin(y)*np.sin(z) + np.sin(x)*np.cos(z) rot_mat[2,2] = np.cos(x)*np.cos(y)
tmpcoup.append([ float(mobj.group(2)), float(mobj.group(3)), float(mobj.group(4)), ]) self.Couplings[self.coupling_states] = self.Coupling(np.asarray(tmpcoup), "Hartree/Bohr") for state, grad in zip(self.states, tmpgrada): self._Gradients[state] = self.Gradient(np.asarray(grad), "Hartree/Bohr") @classmethod def copy(cls, lot, options, copy_wavefunction=True): """ create a copy of this lot object""" # print(" creating copy, new node id =",node_id) # print(" old node id = ",self.node_id) node_id = options.get('node_id', 1) if node_id != lot.node_id and copy_wavefunction: cmd = "cp scratch/mp_{:04d}_{:04d} scratch/mp_{:04d}_{:04d}".format(lot.ID, lot.node_id, lot.ID, node_id) print(cmd) os.system(cmd) return cls(lot.options.copy().set_values(options)) if __name__ == '__main__': filepath = "../../data/ethylene.xyz" molpro = Molpro.from_options(states=[(1, 0), (1, 1)], fnm=filepath, lot_inp_file='../../data/ethylene_molpro.com', coupling_states=(0, 1)) geom = manage_xyz.read_xyz(filepath) xyz = manage_xyz.xyz_to_np(geom) print(molpro.get_energy(xyz, 1, 0)) print(molpro.get_gradient(xyz, 1, 0)) print(molpro.get_coupling(xyz, 1, 0, 1))
def __init__(self, options, **kwargs): self.Data = options # => Read in the coordinates <= # # important first try to read in geom t0 = time() if self.Data['geom'] is not None: print(" getting cartesian coordinates from geom") atoms = manage_xyz.get_atoms(self.Data['geom']) xyz = manage_xyz.xyz_to_np(self.Data['geom']) elif self.Data['fnm'] is not None: print(" reading cartesian coordinates from file") if self.Data['ftype'] is None: self.Data['ftype'] = os.path.splitext(self.Data['fnm'])[1][1:] if not os.path.exists(self.Data['fnm']): #logger.error('Tried to create Molecule object from a file that does not exist: %s\n' % self.Data['fnm']) raise IOError geom = manage_xyz.read_xyz(self.Data['fnm'], scale=1.) xyz = manage_xyz.xyz_to_np(geom) atoms = manage_xyz.get_atoms(geom) else: raise RuntimeError t1 = time() print(" Time to get coords= %.3f" % (t1 - t0)) #resid=[] #for a in ob.OBMolAtomIter(mol.OBMol): # res = a.GetResidue() # resid.append(res.GetName()) #self.resid = resid # Perform all the sanity checks and cache some useful attributes # TODO make PES property self.PES = type(self.Data['PES']).create_pes_from( PES=self.Data['PES'], options={'node_id': self.Data['node_id']}, copy_wavefunction=self.Data['copy_wavefunction']) if not hasattr(atoms, "__getitem__"): raise TypeError("atoms must be a sequence of atomic symbols") for a in atoms: if not isinstance(a, str): raise TypeError("atom symbols must be strings") if type(xyz) is not np.ndarray: raise TypeError("xyz must be a numpy ndarray") if xyz.shape != (len(atoms), 3): raise ValueError("xyz must have shape natoms x 3") self.Data['xyz'] = xyz.copy() # create a dictionary from atoms # atoms contain info you need to know about the atoms self.atoms = [ELEMENT_TABLE.from_symbol(atom) for atom in atoms] tx = time() print(" Time to create PES,elements %.3f" % (tx - t1)) t1 = tx if not isinstance(self.Data['comment'], str): raise TypeError("comment for a Molecule must be a string") # Create the coordinate system if self.Data['coord_obj'] is not None: print(" getting coord_object from options") self.coord_obj = self.Data['coord_obj'] else: print( " Disabling this feature, Molecule cannot create coordinate system" ) raise NotImplementedError #elif self.Data['coordinate_type'] == "Cartesian": # self.coord_obj = CartesianCoordinates.from_options(xyz=self.xyz,atoms=self.atoms) #elif self.Data['coordinate_type'] == "DLC": # print(" building coordinate object") # self.coord_obj = DelocalizedInternalCoordinates.from_options(xyz=self.xyz,atoms=self.atoms,connect=True,extra_kwargs =self.Data['top_settings']) #elif self.Data['coordinate_type'] == "HDLC": # self.coord_obj = DelocalizedInternalCoordinates.from_options(xyz=self.xyz,atoms=self.atoms,addcart=True,extra_kwargs =self.Data['top_settings']) #elif self.Data['coordinate_type'] == "TRIC": # self.coord_obj = DelocalizedInternalCoordinates.from_options(xyz=self.xyz,atoms=self.atoms,addtr=True,extra_kwargs =self.Data['top_settings']) self.Data['coord_obj'] = self.coord_obj t2 = time() print(" Time to build coordinate system= %.3f" % (t2 - t1)) #TODO self.gradrms = 0. self.isTSnode = False self.bdist = 0. self.newHess = 5 if self.Data['Hessian'] is None and self.Data['Form_Hessian']: if self.Data['Primitive_Hessian'] is None and type( self.coord_obj) is not CartesianCoordinates: self.form_Primitive_Hessian() t3 = time() print(" Time to build Prim Hessian %.3f" % (t3 - t2)) if self.Data['Primitive_Hessian'] is not None: print(" forming Hessian in basis") self.form_Hessian_in_basis() else: self.form_Hessian() #logger.info("Molecule %s constructed.", repr(self)) #logger.debug("Molecule %s constructed.", repr(self)) print(" molecule constructed")
if __name__ == '__main__': from level_of_theories.dummy_lot import Dummy from potential_energy_surfaces.pes import PES from coordinate_systems.delocalized_coordinates import DelocalizedInternalCoordinates, PrimitiveInternalCoordinates, Topology from optimizers import eigenvector_follow geoms = manage_xyz.read_molden_geoms( '../growing_string_methods/opt_converged_000.xyz') lot = Dummy.from_options(geom=geoms[0]) pes = PES.from_options(lot=lot, ad_idx=0, multiplicity=1) atom_symbols = manage_xyz.get_atoms(geoms[0]) ELEMENT_TABLE = elements.ElementData() atoms = [ELEMENT_TABLE.from_symbol(atom) for atom in atom_symbols] xyz1 = manage_xyz.xyz_to_np(geoms[0]) xyz2 = manage_xyz.xyz_to_np(geoms[-1]) top1 = Topology.build_topology( xyz1, atoms, ) # find union bonds xyz2 = manage_xyz.xyz_to_np(geoms[-1]) top2 = Topology.build_topology( xyz2, atoms, ) # Add bonds to top1 that are present in top2
return AtomIterator, drij if __name__ == '__main__' and __package__ is None: from os import sys, path sys.path.append(path.dirname(path.dirname(path.abspath(__file__)))) #filepath='../../data/butadiene_ethene.xyz' #filepath='crystal.xyz' filepath1 = 'multi1.xyz' filepath2 = 'multi2.xyz' geom1 = manage_xyz.read_xyz(filepath1) geom2 = manage_xyz.read_xyz(filepath2) atom_symbols = manage_xyz.get_atoms(geom1) xyz1 = manage_xyz.xyz_to_np(geom1) xyz2 = manage_xyz.xyz_to_np(geom2) ELEMENT_TABLE = elements.ElementData() atoms = [ELEMENT_TABLE.from_symbol(atom) for atom in atom_symbols] #print(atoms) #hybrid_indices = list(range(0,10)) + list(range(21,26)) hybrid_indices = list(range(16, 26)) G1 = Topology.build_topology(xyz1, atoms, hybrid_indices=hybrid_indices) G2 = Topology.build_topology(xyz2, atoms, hybrid_indices=hybrid_indices) for bond in G2.edges(): if bond in G1.edges: pass