def plotBoundOrbital(self): selected = self.orbitalSelection.selectedItems() assert len(selected) == 1 selected_orbital = self.orbital_dict[str(selected[0].text())] self.mo_bound = self.bound_orbs[:, selected_orbital] # shift geometry so that the expectation value of the dipole operator vanishes # dipole matrix dipole = np.tensordot(self.mo_bound, np.tensordot(self.tddftb.dftb2.D, self.mo_bound, axes=(1, 0)), axes=(0, 0)) print "expectation value of dipole: %s" % dipole # shift molecule R -> R - dipole self.atomlist = MolCo.transform_molecule( self.tddftb.dftb2.getGeometry(), (0, 0, 0), -dipole) # load bound basis functions self.bs_bound = AtomicBasisSet(self.atomlist) # plot selected orbital (xmin, xmax), (ymin, ymax), (zmin, zmax) = Cube.get_bbox(self.atomlist, dbuff=5.0) dx, dy, dz = xmax - xmin, ymax - ymin, zmax - zmin ppb = 3.0 # Points per bohr nx, ny, nz = int(dx * ppb), int(dy * ppb), int(dz * ppb) x, y, z = np.mgrid[xmin:xmax:nx * 1j, ymin:ymax:ny * 1j, zmin:zmax:nz * 1j] grid = (x, y, z) amplitude_bound = Cube.orbital_amplitude(grid, self.bs_bound.bfs, self.mo_bound, cache=False) bound_cube = CubeData() bound_cube.data = amplitude_bound.real bound_cube.grid = grid bound_cube.atomlist = self.atomlist self.boundOrbitalViewer.setCubes([bound_cube])
def build_water_cluster(atomlist_template, orbital_names, phases): """ build a cluster orbital as a linear combination of monomer orbitals with the correct orientation. The position and orientation of the water molecules is taken from the template. Parameters: =========== atomlist_template: molecular geometry for cluster with n water molecules orbital_names: list of orbital names ('1b1', '3a1', '1b2' or '2a1') for each of the n water molecules phases: list of +1 or -1's for each orbital Returns: ======== water_cluster: molecular geometry of the cluster orb_cluster: cluster orbital, that is a linear combination of the monomer orbitals. """ # water geometry in bohr water_std = [(1, (0.0, 0.8459947982381987, -1.4473477675908173)), (8, (0.0, -0.21392561795490195, 0.0 )), (1, (0.0, 0.8459947982381987, 1.4473477675908173))] valorbs, radial_val = load_pseudo_atoms(water_std) # Orbitals for H2O monomer in standard orientation: # molecular plane = yz-plane, oxygen lies on the negative y-axis, H-H bond is parallel to z-axis # H1-1s O-2s O-2py O-2pz O-2px H2-1s monomer_orbitals = { "1b1": np.array([ 0.0000, 0.0000, 0.0000, 0.0000, 1.0000, 0.0000]), "3a1": np.array([ 0.7816,-0.6842, 0.6989, 0.0000, 0.0000, 0.7816]), "1b2": np.array([-0.7264, 0.0000, 0.0000, 0.9429, 0.0000, 0.7264]), "2a1": np.array([ 0.1730, 0.8662, 0.0393, 0.0000, 0.0000, 0.1730]) } # First the individual water molecules in the template are identified and their positions # and orientations are extracted. fragments = MolecularGraph.disconnected_fragments(atomlist_template) assert len(fragments) == len(orbital_names) == len(phases), "For each water fragment in the cluster you need to specify one fragment orbital ('1b1', '3a1', '1b2' or '2a1') and its phase" orb_cluster = [] # list of MO coefficients water_cluster = [] # list of atoms for i,water in enumerate(fragments): # the Euler angles (a,b,g) specify the orientation of the i-th water molecule water_std_i, (a,b,g), cm = MolCo.molecular_frame_transformation(water) print "WATER STANDARD" for (Zi,posi) in water_std: print " %s %8.6f %8.6f %8.6f" % (Zi, posi[0], posi[1], posi[2]) print "WATER STANDARD %d" % i for (Zi,posi) in water_std_i: print " %s %8.6f %8.6f %8.6f" % (Zi, posi[0], posi[1], posi[2]) # The desired orbital is placed on the i-th water molecule and is # rotated to match the orientation of the molecule. orb_monomer = monomer_orbitals[orbital_names[i]] # rotate orbital orb_monomer_rot = OrbitalRotations.rotate_orbitals(water_std, valorbs, orb_monomer, (a,b,g)) # add orbital with desired phase to cluster MOs orb_cluster += list(phases[i] * orb_monomer_rot) # rotate geometry water_rot = MolCo.transform_molecule(water_std, (a,b,g), cm) XYZ.write_xyz("/tmp/water_std.xyz", [water_std, water_rot]) water_cluster += water_rot # Assuming that the overlap between orbitals on different water molecules is negligible, # we can normalize the cluster orbital by dividing through sqrt(number of water molecules) n = np.sum(abs(np.array(phases))) # a phase of 0 indicates no orbital orb_cluster /= np.sqrt(n) return water_cluster, orb_cluster