mo_coeff_f1 = _set_zero_to_coefficients( electronic_structure['basis'], electronic_structure['nato_coefficients_multi'][1], range_f2) # get symmetry classification electronic_structure['coefficients'] = mo_coeff_f1 electronic_structure['mo_energies'] = electronic_structure['nato_occupancies'] # save test fchk file with new coefficients open('test_f1.fchk', 'w').write(build_fchk(electronic_structure)) # get plane from coordinates coordinates_f1 = np.array( electronic_structure['structure'].get_coordinates())[range_f1] center_f1, normal_f1 = get_plane(coordinates_f1) mulliken = output['diabatization']['mulliken_analysis'][1] a = np.sum(np.array(mulliken['attach'])[range_f1]) print(a) print(electronic_structure['overlap']) print(mulliken) def orbital_localization(coefficients, overlap_matrix): for a_orbital, b_orbital in zip(coefficients['alpha'], coefficients['beta']): a_dot = np.dot(np.dot(a_orbital, overlap_matrix), a_orbital) b_dot = np.dot(np.dot(b_orbital, overlap_matrix), b_orbital)
basis='6-311(2+,2+)G**', ras_roots=10, ras_do_hole=False, ras_do_part=False) # get data from Q-Chem calculation output, electronic_structure = get_output_from_qchem(qc_input, processors=4, force_recalculation=False, read_fchk=True, parser=parser_rasci, store_full_output=True) # get plane from coordinates to determine orientation using the plane of the molecule coordinates_mat = np.array(electronic_structure['structure'].get_coordinates()) center, normal = get_plane(coordinates_mat) symmetry_measures = get_state_symmetry( electronic_structure, output['excited_states'], center=center, # if not provided use center of electronic charge orientation=normal, # if not provided auto-search best orientation group=point_group, extra_print=False) energies = [state['excitation_energy'] for state in output['excited_states']] print('Symmetry of RASCI excited states\n--------------------------------') for i, (energy, state) in enumerate(zip(energies, symmetry_measures)): print('{:2} {:6} {:5.3f}'.format(i + 1, state[0], state[1]) + ' {:5.3f} eV'.format(energy))
def get_symmetry_le(electronic_structure, data_rasci, fragment_atoms=(0), tol=0.1, group='D2h'): # This only works for singlets on close shell calculations types = classify_diabatic_states_of_fragment( data_rasci['diabatization']['diabatic_states'], fragment_atoms, tol=0.1) functions_range = get_basis_functions_ranges_by_atoms( electronic_structure['basis'], atoms_range=fragment_atoms) coordinates_frag = np.array( electronic_structure['structure'].get_coordinates())[fragment_atoms] labels_frag = electronic_structure['structure'].get_symbols( )[fragment_atoms] inertia_moments, inertia_axis = get_inertia( Structure(coordinates=coordinates_frag, symbols=labels_frag)) center_frag, normal_frag = get_plane(coordinates_frag) # print(np.array(inertia_axis)) # print(inertia_moments) # print(inertia_axis[0]) # print(inertia_axis[1]) # print(inertia_axis[2]) if 'LE' in types: indices = [i for i, x in enumerate(types) if x == "LE"] symmetry_labels = [] for index in indices: print('\nLE state found at diabat {}!'.format(index + 1)) coefficients = electronic_structure['nato_coefficients_multi'][ index + 1] occupation = electronic_structure['nato_occupancies_multi'][index + 1] overlap_matrix = np.array(electronic_structure['overlap']) functions_indices = _indices_from_ranges(functions_range) overlap_matrix = np.array([ ovm[functions_indices] for ovm in overlap_matrix[functions_indices] ]) c_alpha = np.array(coefficients['alpha']) oc_alpha = np.array(occupation['alpha']) orbitals = [] alpha = 0 beta = 0 coefficients_new = {'alpha': [], 'beta': []} for i, (va, o) in enumerate(zip(c_alpha, oc_alpha)): va_frag = va[functions_indices] frag_dot = np.dot(va_frag, np.dot(overlap_matrix, va_frag)) if np.abs(frag_dot - 0.5) > tol: if frag_dot > 0.5: orbitals.append((i, np.round(o))) orbital = np.zeros(len(c_alpha)) for j, val in zip(functions_indices, va_frag): orbital[j] = val / np.sqrt(frag_dot) if np.abs(o - 1) < tol and o < 2 - tol: if alpha == beta: alpha += 1 coefficients_new['alpha'].append(list(orbital)) else: beta += 1 coefficients_new['beta'].append(list(orbital)) else: pass if alpha == beta: multiplicity = 1 else: multiplicity = 3 n_electrons = alpha + beta try: # This only works for singlets molsym = get_wf_symmetry(electronic_structure['structure'], electronic_structure['basis'], coefficients_new, center=center_frag, orientation=inertia_axis[0], orientation2=inertia_axis[1], group=group) #molsym.print_alpha_mo_IRD() #molsym.print_beta_mo_IRD() molsym.print_wf_mo_IRD() symmetry_labels.append(molsym.IRLab[np.argmax(molsym.wf_IRd)]) except: pass return symmetry_labels return None
orientation=(1, 0, 0), orientation2=(0, 1, 0), ) # Analysis of diabatic states to use in diabatization print('\nSymmetry of the electronic states of the dimer') list_diabatic = [] for i, state in enumerate(parsed_data['excited_states']): sym_lab = symmetry_measures[i][0] energy = state['excitation_energy'] print('State {}: {:3}'.format(i+1, sym_lab)) range_frag = list(range(0, 6)) coordinates_frag = ee['structure'].get_coordinates(fragment=range_frag) center_frag, normal_frag = get_plane(coordinates_frag) electronic_structure_frag = crop_electronic_structure(ee, range_frag, renormalize=True) # save test fchk file with new coefficients write_to_fchk(electronic_structure_frag, filename='fragment.fchk') molsym = get_wf_symmetry(electronic_structure_frag['structure'], electronic_structure_frag['basis'], electronic_structure_frag['coefficients'], center=center_frag, orientation=(1, 0, 0), orientation2=(0, 1, 0), group='D2h') molsym.print_alpha_mo_IRD()