def setUp(self): self.assertDictEqual.__self__.maxDiff = None # generate molecule molecule = Structure(coordinates=[[0.0, 1.0, 0.0], [0.0, 0.0, 1.0], [0.0, 0.0, -1.0]], symbols=['O', 'H', 'H'], charge=0, multiplicity=1) # optimization txt_input = create_qchem_input(molecule, jobtype='opt', exchange='hf', basis='sto-3g', geom_opt_tol_gradient=300, geom_opt_tol_energy=100, geom_opt_coords=-1, geom_opt_tol_displacement=1200) parsed_data = get_output_from_qchem(txt_input, processors=4, parser=basic_optimization, force_recalculation=recalculate, store_full_output=True) self.molecule = parsed_data['optimized_molecule']
def read_structure_from_xyz(filename, read_multiple=False): """ Read a XYZ file a return a Structure :param file_name: file name :param read_multiple: read multiple molecules :return: Structure or list of Structure """ with open(filename, mode='r') as lines: file_lines = lines.readlines() i_start = 0 structures = [] while True: n_atoms = int(file_lines[i_start].split()[0]) name = file_lines[i_start + 1] body_txt = file_lines[i_start + 2:i_start + n_atoms + 2] structures.append( Structure(coordinates=np.array( [c.split()[1:4] for c in body_txt], dtype=float).tolist(), symbols=[c.split()[0] for c in body_txt], name=name)) if not read_multiple: return structures[0] i_start += len(body_txt) + 2 if len(file_lines) - i_start < 3: break return structures
def setUp(self): self.assertDictEqual.__self__.maxDiff = None # generate molecule self.molecule = Structure(coordinates=[[0.0, 0.0, 0.0], [0.0, 0.0, 1.5]], symbols=['H', 'H'], charge=0, multiplicity=1)
def dimer_mix(distance, slide_y, slide_z): monomer1 = [[ 0.6660120, 0.0000000, 0.0000000, ], [ -0.6660120, 0.0000000, 0.0000000, ], [ 1.2279200, 0.9228100, 0.0000000, ], [ 1.2279200, -0.9228100, 0.0000000, ], [ -1.2279200, -0.9228100, 0.0000000, ], [ -1.2279200, 0.9228100, 0.0000000, ]] symbols1 = ['C', 'C', 'H', 'H', 'H', 'H'] monomer2 = [[0.6624670117, 0.0000000000, 0.0000000000], [-0.6624670117, 0.0000000000, 0.0000000000], [1.3834661472, 1.0993897934, 0.0000000000], [1.3834661472, -1.0993897934, 0.0000000000], [-1.3834661472, -1.0993897934, 0.0000000000], [-1.3834661472, 1.0993897934, 0.0000000000]] symbols2 = ['C', 'C', 'F', 'F', 'F', 'F'] monomer2 = np.array(monomer2) monomer2[:, 2] = monomer2[:, 2] + distance monomer2[:, 1] = monomer2[:, 1] + slide_y monomer2[:, 0] = monomer2[:, 0] + slide_z coordinates = np.vstack([monomer1, monomer2]) symbols = symbols1 + symbols2 molecule = Structure(coordinates=coordinates, symbols=symbols, charge=0) return molecule, {'state_threshold': 0.4, 'n_mon': len(monomer1)}
def get_geometry_from_pubchem(entry, type='name'): """ Get structure form PubChem database :param entry: entry data :param type: data type: 'name', 'cid' :return: Structure """ base = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/" input_1 = 'compound/{}/'.format(type) output_format = "JSON" additional = "record_type=3d" apiurl = base + input_1 + output_format + '?' + additional postdata = '{}={}'.format(type, entry).encode() from urllib.error import HTTPError try: response = urlopen(apiurl, postdata) except HTTPError as e: string = e.read().decode("utf-8") json_data = json.loads(string) fault = json_data['Fault'] if 'Details' in fault: raise Exception(fault['Details'][0]) else: raise Exception(fault['Message']) string = response.read().decode("utf-8") json_data = json.loads(string) conformers = json_data['PC_Compounds'][0]['coords'][0]['conformers'][0] atoms = json_data['PC_Compounds'][0]['atoms'] positions = np.array([conformers['x'], conformers['y'], conformers['z']]).T atomic_numbers = atoms['element'] if 'charge' in atoms: charge = np.add.reduce([c_atom['value'] for c_atom in atoms['charge']]) else: charge = 0 return Structure(coordinates=positions, atomic_numbers=atomic_numbers, charge=charge)
def setUp(self): self.assertDictEqual.__self__.maxDiff = None # generate molecule self.molecule = Structure(coordinates=[ [0.865000, 0.200000, 0.800000], [-0.665000, -0.300000, 0.500000], [-1.130407, 0.715473, 0.220000], [-1.430407, -0.915473, 0.300000], [1.230407, 0.815473, -0.4], [1.000407,-0.888888, 0.45]], symbols=['C', 'C', 'H', 'H', 'H', 'H'], charge=0, multiplicity=1) self.rem = {'jobtype': 'sp', 'exchange': 'hf', 'basis': '6-31G(d,p)', 'thresh': 14, 'scf_convergence': 8, 'max_scf_cycles': 150, 'max_cis_cycles': 150, 'unrestricted': False, # RASCI 'correlation': 'rasci', 'ras_act': 2, 'ras_elec': 2, 'ras_occ': 7, 'ras_spin_mult': 0, 'ras_roots': 7, 'ras_do_hole': True, 'ras_do_part': True, 'ras_sts_tm': True, 'ras_natorb': True, # rasci sr-dft # 'ras_srdft': False, # 'ras_omega': 400, # 'ras_srdft_cor': 'srpw92', # 'ras_srdft_exc': 'srpbe', # 'ras_srdft_damp': 0.5, # rasci print level 'ras_print': 2, # Frozen 'n_frozen_core': 0, 'n_frozen_virt': 0, 'set_iter': 60}
def dimer_ethene(distance, slide_y, slide_z): coordinates = [[0.0000000, 0.0000000, 0.6660120], [0.0000000, 0.0000000, -0.6660120], [0.0000000, 0.9228100, 1.2279200], [0.0000000, -0.9228100, 1.2279200], [0.0000000, -0.9228100, -1.2279200], [0.0000000, 0.9228100, -1.2279200], [distance, 0.0000000, 0.6660120], [distance, 0.0000000, -0.6660120], [distance, 0.9228100, 1.2279200], [distance, -0.9228100, 1.2279200], [distance, -0.9228100, -1.2279200], [distance, 0.9228100, -1.2279200]] coordinates = np.array(coordinates) coordinates[6:, 1] = coordinates[6:, 1] + slide_y coordinates[6:, 2] = coordinates[6:, 2] + slide_z symbols = ['C', 'C', 'H', 'H', 'H', 'H', 'C', 'C', 'H', 'H', 'H', 'H'] molecule = Structure(coordinates=coordinates, symbols=symbols, charge=0) return molecule, {'state_threshold': 0.2, 'n_mon': 6}
def dimer_tetrafluoroethene(distance, slide_y, slide_z): monomer = [[0.6624670117, 0.0000000000, 0.0000000000], [-0.6624670117, 0.0000000000, 0.0000000000], [1.3834661472, 1.0993897934, 0.0000000000], [1.3834661472, -1.0993897934, 0.0000000000], [-1.3834661472, -1.0993897934, 0.0000000000], [-1.3834661472, 1.0993897934, 0.0000000000]] symbols = ['C', 'C', 'F', 'F', 'F', 'F'] monomer2 = np.array(monomer) #monomer2 = np.dot(monomer, rotation_matrix([0, 1, 0], np.pi / 2)) monomer2[:, 2] = monomer2[:, 2] + distance monomer2[:, 1] = monomer2[:, 1] + slide_y monomer2[:, 0] = monomer2[:, 0] + slide_z coordinates = np.vstack([monomer, monomer2]) molecule = Structure(coordinates=coordinates, symbols=symbols * 2, charge=0) return molecule, {'state_threshold': 0.2, 'n_mon': len(monomer)}
def parser_fchk(output): def convert_to_type(item_type, item): item_types = {'I': int, 'R': float} if type(item) is list: return [item_types[item_type](e) for e in item] else: return item_types[item_type](item) key_list = [ 'Charge', 'Multiplicity', 'Number of alpha electrons', 'Number of beta electrons', 'Atomic numbers', 'Current cartesian coordinates', 'Shell types', 'Number of primitives per shell', 'Shell to atom map', 'Primitive exponents', 'Contraction coefficients', 'P(S=P) Contraction coefficients', 'Alpha MO coefficients', 'Beta MO coefficients', 'Coordinates of each shell', 'Overlap Matrix', 'Core Hamiltonian Matrix', 'Alpha Orbital Energies', 'Beta Orbital Energies', 'Total SCF Density', 'Alpha NATO coefficients', 'Beta NATO coefficients', 'Alpha Natural Orbital occupancies', 'Beta Natural Orbital occupancies', 'Natural Transition Orbital occupancies', 'Natural Transition Orbital U coefficients', 'Natural Transition Orbital V coefficients' ] basis_set = output.split('\n')[1].split()[-1] words_output = output.replace('\n', ' ').split() data = {} nw = len(words_output) for key in key_list: wc = len(key.split()) for i in range(nw): word = ' '.join(words_output[i:i + wc]) if word == key: item_type = words_output[i + wc] if words_output[i + wc + 1] == 'N=': n_elements = int(words_output[i + wc + 2]) data[word] = convert_to_type( item_type, words_output[i + wc + 3:i + wc + n_elements + 3]) else: data[word] = convert_to_type(item_type, words_output[i + wc + 1]) break bohr_to_angstrom = 0.529177249 coordinates = np.array(data['Current cartesian coordinates']).reshape( -1, 3) * bohr_to_angstrom structure = Structure(coordinates=coordinates, atomic_numbers=data['Atomic numbers'], multiplicity=data['Multiplicity'], charge=data['Charge']) if not 'P(S=P) Contraction coefficients' in data: data['P(S=P) Contraction coefficients'] = np.zeros_like( data['Contraction coefficients']).tolist() basis = basis_format( basis_set_name=basis_set, atomic_numbers=structure.get_atomic_numbers(), atomic_symbols=structure.get_symbols(), shell_type=data['Shell types'], n_primitives=data['Number of primitives per shell'], atom_map=data['Shell to atom map'], p_exponents=data['Primitive exponents'], c_coefficients=data['Contraction coefficients'], p_c_coefficients=data['P(S=P) Contraction coefficients']) nbas = int(np.sqrt(len(data['Alpha MO coefficients']))) mo_coeff = { 'alpha': np.array(data['Alpha MO coefficients']).reshape(nbas, nbas).tolist() } mo_energy = {'alpha': data['Alpha Orbital Energies']} if 'Beta MO coefficients' in data: mo_coeff['beta'] = np.array(data['Beta MO coefficients']).reshape( nbas, nbas).tolist() mo_energy['beta'] = data['Beta Orbital Energies'] final_dict = { 'structure': structure, 'basis': basis, 'coefficients': mo_coeff, 'mo_energies': mo_energy, 'number_of_electrons': { 'alpha': data['Number of alpha electrons'], 'beta': data['Number of beta electrons'] } } if 'Overlap Matrix' in data: final_dict['overlap'] = vect_to_mat(data['Overlap Matrix']).tolist() if 'Alpha NATO coefficients' in data: final_dict['nato_coefficients'] = { 'alpha': np.array(data['Alpha NATO coefficients']).reshape(nbas, nbas).tolist() } final_dict['nato_occupancies'] = { 'alpha': data['Alpha Natural Orbital occupancies'] } if 'Beta NATO coefficients' in data: final_dict['nato_coefficients'].update({ 'beta': np.array(data['Beta NATO coefficients']).reshape(nbas, nbas).tolist() }) final_dict['nato_occupancies'].update( {'beta': data['Beta Natural Orbital occupancies']}) # check multiple NATO (may be improved) if 'Alpha NATO coefficients' in data: nato_coefficients_list, nato_occupancies_list = _get_all_nato(output) if len(nato_occupancies_list) > 1: final_dict['nato_coefficients_multi'] = nato_coefficients_list final_dict['nato_occupancies_multi'] = nato_occupancies_list if 'Natural Transition Orbital occupancies' in data: nat_coefficients_list, nat_occupancies_list = _get_all_nto(output) if len(nat_occupancies_list) > 1: final_dict['nto_coefficients_multi'] = nat_coefficients_list final_dict['nto_occupancies_multi'] = nat_occupancies_list return final_dict
from pyqchem.qc_input import QchemInput from pyqchem.parsers.parser_rasci import parser_rasci from pyqchem.structure import Structure import numpy as np import matplotlib.pyplot as plt # define distances distances = np.arange(0.1, 3.5, 0.1) energies = [] for dist in distances: # generate molecule molecule = Structure(coordinates=[[0.0, 0.0, 0.0], [0.0, 0.0, dist]], symbols=['H', 'H'], charge=0, multiplicity=1) # create qchem input qc_input = QchemInput(molecule, jobtype='sp', exchange='hf', correlation='rasci', basis='sto-3g', ras_act=2, ras_elec=2, ras_spin_mult=0, ras_roots=2, ras_do_part=False, ras_do_hole=False)
'look_for_keys': False, 'precommand': ['module load qchem/qchem_group' ], # commands (if) needed to load qchem in remote computer 'remote_scratch': '/home/user/' } # scratch directory in remote computer # molecule ethene = [[0.0, 0.0000, 0.65750], [0.0, 0.0000, -0.65750], [0.0, 0.92281, 1.22792], [0.0, -0.92281, 1.22792], [0.0, -0.92281, -1.22792], [0.0, 0.92281, -1.22792]] symbols = ['C', 'C', 'H', 'H', 'H', 'H'] # create molecule molecule = Structure(coordinates=ethene, symbols=symbols, charge=0, multiplicity=1) # create Q-Chem input qc_input = QchemInput(molecule, jobtype='sp', exchange='hf', basis='sto-3g') print(qc_input.get_txt()) # get data from Q-Chem calculation output = get_output_from_qchem(qc_input, processors=1, force_recalculation=True, remote=remote_data_pc, scratch='/Users/abel/Scratch/export/', parser=basic_parser_qchem)
def basic_irc(output, print_data=False): branch_mark = True data_dict = {} # Molecule n = output.find('$molecule') n2 = output[n:].find('$end') molecule_region = output[n:n + n2 - 1].replace('\t', ' ').split('\n')[1:] charge, multiplicity = [int(num) for num in molecule_region[0].split()] coordinates = np.array([ np.array(line.split()[1:4], dtype=float) for line in molecule_region[1:] ]) symbols = [line.split()[0].capitalize() for line in molecule_region[1:]] n_atoms = len(coordinates) forward_steps = [] backward_steps = [] list_iterations = [ l.end() for l in re.finditer('Reaction path following', output) ] for ini, fin in zip(list_iterations, list_iterations[1:] + [len(output)]): step_section = output[ini:fin] enum = step_section.find('Standard Nuclear Orientation') atoms_list = step_section[enum:].split('\n')[3:n_atoms + 3] coordinates_step = np.array([atom.split()[2:] for atom in atoms_list], dtype=float).tolist() step_energy = None for l in re.finditer('Total energy in the final basis set', step_section): step_energy = float(step_section[l.end():l.end() + 50].split()[1]) step_molecule = Structure(coordinates=coordinates_step, symbols=symbols, charge=charge, multiplicity=multiplicity) if (step_section.find('IRC -- maximum number of cycles reached') > 0 or step_section.find('IRC -- convergence criterion reached') > 0): if branch_mark: #forward_steps = forward_steps[::-1] branch_mark = False else: break if branch_mark: forward_steps.append({ 'molecule': step_molecule, 'energy': step_energy, }) else: backward_steps.append({ 'molecule': step_molecule, 'energy': step_energy, }) data_dict['irc_forward'] = forward_steps data_dict['irc_backward'] = forward_steps return data_dict
def createMolecule(coordinate_list, symbols_list, charge=0, multiplicity=1): molecule = Structure(coordinate_list, symbols_list, charge, multiplicity) return molecule
' '.join(['{:7.3f}'.format(s) for s in line])) print('occupations') print('alpha', np.array(nato_occup['alpha'])[orbitals]) print('beta ', np.array(nato_occup['beta'])[orbitals]) ethene = [[0.0, 0.0000, 0.65750], [0.0, 0.0000, -0.65750], [0.0, 0.92281, 1.22792], [0.0, -0.92281, 1.22792], [0.0, -0.92281, -1.22792], [0.0, 0.92281, -1.22792]] symbols = ['C', 'C', 'H', 'H', 'H', 'H'] # create molecule molecule = Structure(coordinates=ethene, symbols=symbols, charge=0, multiplicity=1) print('Optimized monomer structure') print(molecule) # Build dimer from monomer coor_monomer2 = np.array(ethene) from kimonet.utils.rotation import rotate_vector coor_monomer2 = np.array( [rotate_vector(coor, [0.0, 0.0, 0.0]) for coor in coor_monomer2]) coor_monomer2[:, 0] += 4.0 # monomers separation coor_monomer2[:, 1] += 0.0 # monomers separation coor_monomer2[:, 2] += 0.0 # monomers separation
def parser_rasci(output): """ Parser for RAS-CI calculations Include: - Diabatization scheme data - Structure - Adiabatic states - SOC :param output: :return: """ data_dict = {} # Molecule n = output.find('$molecule') n2 = output[n:].find('$end') molecule_region = output[n:n + n2 - 1].replace('\t', ' ').split('\n')[1:] charge, multiplicity = [int(num) for num in molecule_region[0].split()] coordinates = [[float(l) for l in line.split()[1:4]] for line in molecule_region[1:]] symbols = [line.split()[0].capitalize() for line in molecule_region[1:]] n_atoms = len(symbols) # structure structure_input = Structure(coordinates=coordinates, symbols=symbols, charge=charge, multiplicity=multiplicity) enum = output.find('Standard Nuclear Orientation') section_structure = output[enum:enum + 200 * structure_input.get_number_of_atoms()].split( '\n') section_structure = section_structure[3:structure_input. get_number_of_atoms() + 3] coordinates = [[float(num) for num in s.split()[2:]] for s in section_structure] data_dict['structure'] = Structure(coordinates=coordinates, symbols=symbols, charge=charge, multiplicity=multiplicity) # basic info enum = output.find('Nuclear Repulsion Energy') basic_data = read_basic_info(output[enum:enum + 5000]) # scf_energy enum = output.find('SCF energy in the final basis set') scf_energy = float(output[enum:enum + 100].split()[8]) data_dict['scf_energy'] = scf_energy # total energy # enum = output.find('Total energy in the final basis set') # total_energy = float(output[enum:enum+100].split()[8]) # RASCI dimensions ini_section = output.find('RAS-CI Dimensions') end_section = search_bars(output, from_position=enum, bar_type='\*\*\*')[1] dimension_section = output[ini_section:end_section] enum = dimension_section.find('Doubly Occ') doubly_occ = int(dimension_section[enum:enum + 50].split()[3]) enum = dimension_section.find('Doubly Vir') doubly_vir = int(dimension_section[enum:enum + 50].split()[2]) enum = dimension_section.find('Frozen Occ') frozen_occ = int(dimension_section[enum:enum + 50].split()[3]) enum = dimension_section.find('Frozen Vir') frozen_vir = int(dimension_section[enum:enum + 50].split()[2]) enum = dimension_section.find('Total CI configurations') total_conf = int(dimension_section[enum:enum + 50].split()[3]) enum = dimension_section.find('Active configurations') active_conf = int(dimension_section[enum:enum + 50].split()[2]) enum = dimension_section.find('Hole configurations') hole_conf = int(dimension_section[enum:enum + 50].split()[2]) enum = dimension_section.find('Particle configurations') particle_conf = int(dimension_section[enum:enum + 50].split()[2]) rasci_dimensions = { 'doubly_occupied': doubly_occ, 'doubly_virtual': doubly_vir, 'frozen_occupied': frozen_occ, 'frozen_virtual': frozen_vir, 'total_configurations': total_conf, 'active_configurations': active_conf, 'hole_configurations': hole_conf, 'particle_configurations': particle_conf } data_dict.update({'rasci_dimensions': rasci_dimensions}) # Diabatization scheme done_diabat = bool(output.find('RASCI DIABATIZATION') + 1) if done_diabat: rot_matrix = _read_simple_matrix( 'showmatrix final adiabatic -> diabatic', output)[-1] adiabatic_matrix = _read_simple_matrix( 'showing H in adiabatic representation: NO coupling elements', output)[-1] diabatic_matrix = _read_simple_matrix( 'showing H in diabatic representation: WITH coupling elements', output)[-1] mulliken_adiabatic = [] enum = output.find('Mulliken analysis of Adiabatic State') for m in re.finditer('Mulliken analysis of Adiabatic State', output[enum:]): section_mulliken = output[m.end() + enum:m.end() + 10000 + enum] # 10000: assumed to max of section section_mulliken = section_mulliken[:section_mulliken.find( 'Natural Orbitals stored in FCHK')] section_attachment = section_mulliken.split('\n')[9 + n_atoms:9 + n_atoms * 2] mulliken_adiabatic.append({ 'attach': [float(l.split()[1]) for l in section_attachment], 'detach': [float(l.split()[2]) for l in section_attachment], 'total': [float(l.split()[3]) for l in section_attachment] }) mulliken_diabatic = [] enum = output.find('showing H in diabatic representation') for m in re.finditer('Mulliken Analysis of Diabatic State', output[enum:]): section_mulliken = output[m.end() + enum:m.end() + 10000 + enum] # 10000: assumed to max of section section_mulliken = section_mulliken[:section_mulliken.find( 'Natural Orbitals stored in FCHK')] section_attachment = section_mulliken.split('\n')[9 + n_atoms:9 + n_atoms * 2] mulliken_diabatic.append({ 'attach': [float(l.split()[1]) for l in section_attachment], 'detach': [float(l.split()[2]) for l in section_attachment], 'total': [float(l.split()[3]) for l in section_attachment] }) enum = output.find('Transition dipole moment - diabatic states') tdm_section = output[enum:enum + 70 * len(rot_matrix)] diabatic_tdm = [] for m in re.finditer('TDM', tdm_section): diabatic_tdm.append([ float(n) for n in tdm_section[m.end():m.end() + 70][14:].split()[:3] ]) diabatic_states = [] for i, tdm in enumerate(diabatic_tdm): diabatic_states.append({ 'excitation_energy': diabatic_matrix[i][i], 'excitation_energy_units': 'eV', 'transition_moment': tdm, 'dipole_moment_units': 'ua', 'mulliken': mulliken_diabatic[i] }) data_dict['diabatization'] = { 'rot_matrix': rot_matrix, 'adiabatic_matrix': adiabatic_matrix, 'diabatic_matrix': diabatic_matrix, 'diabatic_states': diabatic_states, 'mulliken_adiabatic': mulliken_adiabatic } # excited states data excited_states = [] for m in re.finditer('RAS-CI total energy for state', output): # print('ll found', m.start(), m.end()) section_state = output[m.end():m.end() + 10000] # 10000: assumed to max of section section_state = section_state[:section_state.find('********')] enum = section_state.find('RAS-CI total energy for state') section_state = section_state[:enum] # energies tot_energy = float(section_state.split()[1]) exc_energy_units = section_state.split()[4][1:-1] exc_energy = float(section_state.split()[6]) state_multiplicity = section_state.split( )[8] if section_state.split()[8] != ':' else section_state.split()[9] # dipole moment enum = section_state.find('Dipole Moment') dipole_mom = [ float(section_state[enum:].split()[2]) + 0.0, float(section_state[enum:].split()[4]) + 0.0, float(section_state[enum:].split()[6]) + 0.0 ] # Transition moment enum = section_state.find('Trans. Moment') if enum > -1: trans_mom = [ float(section_state[enum:].split()[2]) + 0.0, float(section_state[enum:].split()[4]) + 0.0, float(section_state[enum:].split()[6]) + 0.0 ] trans_mom = standardize_vector(trans_mom) strength = float(section_state[enum:].split()[10]) else: trans_mom = None strength = None # configurations table enum = section_state.find('AMPLITUDE') enum2 = section_state.find('Contributions') section_table = section_state[enum:enum2].split('\n')[2:-2] # ' HOLE | ALPHA | BETA | PART | AMPLITUDE' table = [] for row in section_table: table.append({ 'hole': row.split('|')[1].strip(), 'alpha': row.split('|')[2].strip(), 'beta': row.split('|')[3].strip(), 'part': row.split('|')[4].strip(), 'amplitude': float(row.split('|')[5]) + 0.0 }) table[-1]['occupations'] = get_rasci_occupations_list( table[-1], data_dict['structure'], basic_data['n_basis_functions']) table = sorted(table, key=operator.itemgetter('hole', 'alpha', 'beta', 'part')) # Contributions RASCI wfn contributions_section = section_state[enum2:] contributions = { 'active': float(contributions_section.split()[4]), 'hole': float(contributions_section.split()[6]), 'part': float(contributions_section.split()[8]) } # complete dictionary tot_energy_units = 'au' excited_states.append({ 'total_energy': tot_energy, 'total_energy_units': tot_energy_units, 'excitation_energy': exc_energy, 'excitation_energy_units': exc_energy_units, 'multiplicity': state_multiplicity, 'dipole_moment': dipole_mom, 'transition_moment': trans_mom, 'dipole_moment_units': 'ua', 'oscillator_strength': strength, 'configurations': table, 'contributions_fwn': contributions }) data_dict.update({'excited_states': excited_states}) # Interstate transition properties done_interstate = bool(output.find('Interstate Transition Properties') + 1) if done_interstate: ini_section = output.find('Interstate Transition Properties') end_section = search_bars(output, from_position=ini_section)[1] interstate_section = output[ini_section:end_section] interstate_dict = {} for m in re.finditer('State A: Root', interstate_section): section_pair = interstate_section[m.start():m.start() + 10000] section_pair = section_pair[:section_pair.find('********')] lines = section_pair.split('\n') state_a = int(lines[0].split()[-1]) state_b = int(lines[1].split()[-1]) pair_dict = {'state_a': state_a, 'state_b': state_b} s_a = s_b = 0 for i, line in enumerate(lines): # RAS-CI SOC section if 'Angular momentum components' in line: pair_dict['angular_momentum'] = [ complex(lines[i + 1 + k].split()[-1].replace('i', 'j')) for k in range(3) ] if '||gamma^AB||_total' in line: pair_dict['gamma_total'] = float(lines[i + 0].split()[-1]) pair_dict['gamma_sym'] = float(lines[i + 1].split()[-1]) pair_dict['gamma_anti_sym'] = float(lines[i + 2].split()[-1]) if "KET: S',Sz'" in line: s_a = float(lines[i].split('=')[1].split()[0]) s_b = float(lines[i + 1].split('=')[1].split()[0]) na = int(2 * s_a + 1) nb = int(2 * s_b + 1) if 'Spin Matrices' in line: spinmat_x = _read_soc_matrix(lines[i + 2:], [nb, na]) spinmat_y = _read_soc_matrix(lines[i + 4 + nb:], [nb, na]) spinmat_z = _read_soc_matrix(lines[i + 6 + 2 * nb:], [nb, na]) pair_dict['spin_matrices'] = [ spinmat_x, spinmat_y, spinmat_z ] if 'Spin matrices Sx, Sy and Sz for states' in line: pair_dict['spin_matrices'] = [np.zeros( (nb, na)).tolist()] * 3 if '1-elec SOC matrix (cm-1)' in line: pair_dict['1e_soc_mat'] = _read_soc_matrix( lines[i + 1:], [nb, na]) pair_dict['1e_socc'] = float(lines[i + 2 + nb].split()[-2:][0]) if '2e-SOMF Reduced matrix elements (cm-1)' in line: r, c = lines[i + 1].split()[-2:] pair_dict['hso_l-'] = float(r) + float(c) * 1j r, c = lines[i + 2].split()[-2:] pair_dict['hso_l0'] = float(r) + float(c) * 1j r, c = lines[i + 3].split()[-2:] pair_dict['hso_l+'] = float(r) + float(c) * 1j if '2-elec mean-field SOC matrix (cm-1)' in line: pair_dict['2e_soc_mat'] = _read_soc_matrix( lines[i + 1:], [nb, na]) if 'Total mean-field SOC matrix (cm-1)' in line: pair_dict['total_soc_mat'] = _read_soc_matrix( lines[i + 1:], [nb, na]) if 'Mean-Field SOCC' in line: pair_dict['mf_socc'] = float(line.split()[-2]) pair_dict['units'] = line.split()[-1] interstate_dict[(state_a, state_b)] = pair_dict data_dict.update({'interstate_properties': interstate_dict}) return data_dict
from pyqchem.qchem_core import get_output_from_qchem, redefine_calculation_data_filename from pyqchem.qc_input import QchemInput from pyqchem.structure import Structure from pyqchem.parsers.parser_rasci import parser_rasci as parser_rasci from pyqchem.basis import get_basis_from_ccRepo, trucate_basis, basis_to_txt import numpy as np from pyqchem.errors import OutputError redefine_calculation_data_filename('test_soc.pkl') # create molecules mol_oh = Structure(coordinates=[[0.0, 0.0, 0.0000], [0.0, 0.0, 0.9697]], symbols=['O', 'H'], charge=-1, multiplicity=1, name='OH') as_oh = [[3, 2, 3], [5, 3, 2], [7, 4, 1], [9, 5, 0]] mol_sh = Structure(coordinates=[[0.0, 0.0, 0.0000], [0.0, 0.0, 1.3409]], symbols=['S', 'H'], charge=-1, multiplicity=1, name='SH') as_sh = [[3, 2, 7], [5, 3, 6], [7, 4, 5], [13, 7, 2], [17, 9, 0]] mol_seh = Structure(coordinates=[[0.0, 0.0, 0.0000], [0.0, 0.0, 1.5811]],
from pyqchem.parsers.parser_optimization import basic_optimization from pyqchem.parsers.parser_rasci import parser_rasci from pyqchem.structure import Structure import numpy as np import matplotlib.pyplot as plt # define monomer coor_monomer = [[0.6695, 0.0000, 0.0000], [-0.6695, 0.0000, 0.0000], [1.2321, 0.9289, 0.0000], [1.2321, -0.9289, 0.0000], [-1.2321, 0.9289, 0.0000], [-1.2321, -0.9289, 0.0000]] symbols_monomer = ['C', 'C', 'H', 'H', 'H', 'H'] monomer = Structure(coordinates=coor_monomer, symbols=symbols_monomer, charge=0, multiplicity=1) # optimization qchem input qc_input = QchemInput(monomer, jobtype='opt', exchange='hf', basis='sto-3g', geom_opt_tol_gradient=300, geom_opt_tol_energy=100, geom_opt_coords=-1, geom_opt_tol_displacement=1200) parsed_data = get_output_from_qchem(qc_input, processors=4, parser=basic_optimization)
from pyqchem.qc_input import QchemInput from pyqchem.structure import Structure from pyqchem.parsers.parser_rasci import parser_rasci as parser_rasci from pyqchem.basis import get_basis_from_ccRepo, trucate_basis, basis_to_txt from pyqchem.errors import OutputError import numpy as np # import pyqchem.qchem_core # pyqchem.qchem_core.__calculation_data_filename__ = 'test.pkl' redefine_calculation_data_filename('test_soc2.pkl') # create molecule as_clo = [[3, 2, 11], [5, 3, 10], [11, 6, 7], [13, 7, 6], [19, 10, 3]] mol_clo = Structure(coordinates=[[0.0, 0.0, 0.0000], [0.0, 0.0, 1.5696]], symbols=['Cl', 'O'], charge=-1, multiplicity=1, name='ClO') as_bro = [[3, 2, 20], [9, 5, 17], [13, 7, 15], [23, 12, 10]] mol_bro = Structure(coordinates=[[0.0, 0.0, 0.0000], [0.0, 0.0, 1.7172]], symbols=['Br', 'O'], charge=-1, multiplicity=1, name='BrO') as_ncs = [[3, 2, 13], [7, 4, 11], [11, 6, 9], [15, 8, 7]] mol_ncs = Structure(coordinates=[[0.0, 0.0, 1.159], [0.0, 0.0, 0.000], [0.0, 0.0, -1.631]], symbols=['N', 'C', 'S'], charge=-1,
energies = [] for dist in distances: # generate molecule coordinates = [[ 0.6695, 0.0000, 0.0000], [-0.6695, 0.0000, 0.0000], [ 1.2321, 0.9289, 0.0000], [ 1.2321, -0.9289, 0.0000], [-1.2321, 0.9289, 0.0000], [-1.2321, -0.9289, 0.0000]] coordinates = rotate_coordinates(coordinates, angle=dist, axis=[1, 0, 0], atoms_list=[4, 5]) ethene = Structure(coordinates=coordinates, symbols=['C', 'C', 'H', 'H', 'H', 'H'], charge=0, multiplicity=1) # create qchem input qc_input = QchemInput(ethene, jobtype='sp', exchange='hf', correlation='rasci', basis='6-31G', ras_act=4, ras_elec=2, ras_spin_mult=0, ras_roots=2, ras_do_part=False, ras_do_hole=False, # ras_srdft_spinpol=True,
def basic_cis(output): """ Parser for CIS/TD-DFT calculations :param output: :return: """ data_dict = {} # Molecule n = output.find('$molecule') n2 = output[n:].find('$end') molecule_region = output[n:n + n2 - 1].replace('\t', ' ').split('\n')[1:] charge, multiplicity = [int(num) for num in molecule_region[0].split()] coordinates = [[float(l) for l in line.split()[1:4]] for line in molecule_region[1:]] symbols = [line.split()[0].capitalize() for line in molecule_region[1:]] n_atoms = len(symbols) # structure structure_input = Structure(coordinates=coordinates, symbols=symbols, charge=charge, multiplicity=multiplicity) enum = output.find('Standard Nuclear Orientation') section_structure = output[enum:enum + 200 * structure_input.get_number_of_atoms()].split( '\n') section_structure = section_structure[3:structure_input. get_number_of_atoms() + 3] coordinates = [[float(num) for num in s.split()[2:]] for s in section_structure] data_dict['structure'] = Structure(coordinates=coordinates, symbols=symbols, charge=charge, multiplicity=multiplicity) # scf_energy enum = output.find('Total energy in the final basis set') try: data_dict['scf_energy'] = float(output[enum:enum + 100].split()[8]) except IndexError: pass enum = output.find('Molecular Point Group') if enum > 0: symmetry_data = read_symmetry_info(output[enum:enum + 1000]) enum = output.find('Nuclear Repulsion Energy') basic_data = read_basic_info(output[enum:enum + 5000]) # CIS excited states # enum = output.find('CIS Excitation Energies') try: enum = list(re.finditer('CIS Excitation Energies', output))[-1].end() except IndexError: enum = list(re.finditer('TDDFT/TDA Excitation Energies', output))[-1].end() excited_states = [] if enum > 0: bars = search_bars(output, from_position=enum) output_cis = output[bars[0]:bars[1]] for m in re.finditer('Excited state ', output_cis): state_cis_section = output_cis[m.end():] state_cis_lines = state_cis_section.split('\n') exc_energy = float(state_cis_lines[0].split()[5]) exc_energy_units = state_cis_lines[0].split()[3][1:-1] tot_energy = float(state_cis_lines[1].split()[5]) try: tot_energy_units = state_cis_lines[1].split()[6] mul = state_cis_lines[2].split()[-1] trans_mom = [ float(mom) for mom in [ state_cis_lines[3].split()[2], state_cis_lines[3]. split()[4], state_cis_lines[3].split()[6] ] ] strength = float(state_cis_lines[4].split()[2]) except ValueError: # old version of qchem (< 5.01) state_cis_words = output_cis[m.end():].split() tot_energy_units = 'au' mul = state_cis_words[13] trans_mom = [ float(mom) for mom in [ state_cis_words[16], state_cis_words[18], state_cis_words[20] ] ] strength = float(state_cis_words[24]) transitions = [] for line in state_cis_lines[5:]: if line.find('-->') > 0: origin = int( line.split('>')[0].split('(')[1].split(')')[0]) target = int( line.split('>')[1].split('(')[1].split(')')[0]) amplitude = float(line.split('=')[1].split()[0]) alpha_transitions = [] beta_transitions = [] try: spin = line[21:].split()[3] if spin == 'alpha': alpha_transitions.append({ 'origin': origin, 'target': target + basic_data['n_alpha'] }) elif spin == 'beta': beta_transitions.append({ 'origin': origin, 'target': target + basic_data['n_beta'] }) else: raise ParserError('basic_cis', 'Error reading configurations') transitions.append({ 'origin': origin, 'target': target, 'amplitude': amplitude, 'occupations': get_cis_occupations_list( basic_data['n_basis_functions'], basic_data['n_alpha'], basic_data['n_beta'], alpha_transitions=alpha_transitions, beta_transitions=beta_transitions) }) except (IndexError, ParserError): # This supposes single electron transition alpha_transitions.append({ 'origin': origin, 'target': target + basic_data['n_alpha'] }) transitions.append({ 'origin': origin, 'target': target, 'amplitude': amplitude / np.sqrt(2), 'occupations': get_cis_occupations_list( basic_data['n_basis_functions'], basic_data['n_alpha'], basic_data['n_beta'], alpha_transitions=alpha_transitions, beta_transitions=beta_transitions) }) transitions.append({ 'origin': origin, 'target': target, 'amplitude': amplitude / np.sqrt(2) if mul == 'Singlet' else -amplitude / np.sqrt(2), 'occupations': get_cis_occupations_list( basic_data['n_basis_functions'], basic_data['n_alpha'], basic_data['n_beta'], alpha_transitions=beta_transitions, beta_transitions=alpha_transitions) }) if len(line) < 5: break excited_states.append({ 'total_energy': tot_energy, 'total_energy_units': tot_energy_units, 'excitation_energy': exc_energy, 'excitation_energy_units': exc_energy_units, 'multiplicity': mul, 'transition_moment': standardize_vector(trans_mom), 'strength': strength, 'configurations': transitions }) data_dict['excited_states'] = excited_states # Spin-Orbit coupling initial = output.find( '*********SPIN-ORBIT COUPLING JOB BEGINS HERE*********') final = output.find('*********SOC CODE ENDS HERE*********') data_interstate = {} if initial > 0: soc_section = output[initial:final] def label_states(excited_states): labels = [] ns = 1 nt = 1 for state in excited_states: if state['multiplicity'].lower() == 'singlet': labels.append('S{}'.format(ns)) ns += 1 elif state['multiplicity'].lower() == 'triplet': labels.append('T{}'.format(nt)) nt += 1 else: try: m = float(state['multiplicity']) if abs(m - 1) < 0.1: labels.append('S{}'.format(ns)) ns += 1 if abs(m - 3) < 0.1: labels.append('T{}'.format(nt)) nt += 1 state['multiplicity'] = m except ValueError: raise ParserError('basic_cis', 'State multiplicity error') return labels, nt - 1, ns - 1 labels, n_triplet, n_singlet = label_states(excited_states) for i, label in enumerate(labels): data_interstate[(i + 1, 0)] = { '1e_soc_mat': [0j, 0j, 0j], 'soc_units': 'cm-1' } data_interstate[(0, i + 1)] = { '1e_soc_mat': [0j, 0j, 0j], 'soc_units': 'cm-1' } for j, label2 in enumerate(labels): if (label[0] == 'S' or label2[0] == 'S') and (label[0] != label2[0]): data_interstate[(i + 1, j + 1)] = { '1e_soc_mat': [[0j, 0j, 0j]], 'soc_units': 'cm-1' } elif label[0] == 'T' and label2[0] == 'T': data_interstate[(i + 1, j + 1)] = { '1e_soc_mat': [[0j, 0j, 0j], [0j, 0j, 0j], [0j, 0j, 0j]], 'soc_units': 'cm-1' } elif label[0] == 'S' and label2[0] == 'S': data_interstate[(i + 1, j + 1)] = { '1e_soc_mat': [[0j]], 'soc_units': 'cm-1' } else: raise ParserError('basic_cis', 'State multiplicity error') for i, label in enumerate(labels): for k2, ms2 in enumerate([-1, 0, 1]): for j, label2 in enumerate(labels): if label[0] == 'T': for k, ms in enumerate([-1, 0, 1]): enum = soc_section.find( 'SOC between the {} (ms={}) state and excited triplet states (ms={})' .format(label, ms2, ms)) for line in soc_section[enum:enum + 80 * (n_triplet + 1)].split( '\n'): if len(line.split()) == 0: break if line.split()[0] == '{}(ms={})'.format( label2, ms): data_interstate[( i + 1, j + 1 )]['1e_soc_mat'][k2][k] = _list_to_complex( line.split()[1:4]) data_interstate[( i + 1, j + 1 )]['1e_soc_mat'][k][k2] = _list_to_complex( line.split()[1:4]) data_interstate[( j + 1, i + 1 )]['1e_soc_mat'][k2][k] = _list_to_complex( line.split()[1:4]) data_interstate[( j + 1, i + 1 )]['1e_soc_mat'][k][k2] = _list_to_complex( line.split()[1:4]) break elif label[0] == 'S': for k, ms in enumerate([-1, 0, 1]): enum = soc_section.find( 'SOC between the {} state and excited triplet states (ms={})' .format(label, ms)) for line in soc_section[enum:enum + 80 * (n_triplet + 1)].split( '\n'): if len(line.split()) == 0: break if line.split()[0] == '{}(ms={})'.format( label2, ms): data_interstate[( i + 1, j + 1 )]['1e_soc_mat'][0][k] = _list_to_complex( line.split()[1:4]) data_interstate[( j + 1, i + 1 )]['1e_soc_mat'][0][k] = _list_to_complex( line.split()[1:4]) break else: raise ParserError('basic_cis', 'SOC reading error') enum = soc_section.find( 'SOC between the singlet ground state and excited triplet states (ms={})' .format(ms2)) for line in soc_section[enum:enum + 80 * (n_triplet + 1)].split('\n'): if len(line.split()) == 0: break if line.split()[0] == '{}(ms={})'.format(label, ms2): data_interstate[( i + 1, 0)]['1e_soc_mat'][k2] = _list_to_complex( line.split()[1:4]) data_interstate[( 0, i + 1)]['1e_soc_mat'][k2] = _list_to_complex( line.split()[1:4]) break data_dict['interstate_properties'] = data_interstate # diabatization initial = output.find('Localization Code for CIS excited states') if initial > 0: bars = search_bars(output, from_position=initial) diabat_section = output[initial:bars[0]] def read_diabatization_matrix(label): matrix = [] for m in re.finditer(label, diabat_section): line = diabat_section[m.end():m.end() + 50].split('\n')[0] matrix.append(float(line.split('=')[1])) diabat_dim = int(np.sqrt(len(matrix))) return np.array(matrix).reshape(diabat_dim, diabat_dim).T r_matrix = read_diabatization_matrix('showmatrix adiabatic R-Matrix') rot_matrix = read_diabatization_matrix( 'showmatrix final adiabatic -> diabatic RotMatrix') diabatic_matrix = read_diabatization_matrix( 'showmatrix diabatH') * AU_TO_EV if len(rot_matrix) == 0: # Boys diabatization rot_matrix = read_diabatization_matrix( 'showmatrix Boys adiabatic->diabatic RotMatrix') diabatic_matrix = read_diabatization_matrix( 'showmatrix Boys diabatH') * AU_TO_EV adiabatic_matrix = read_diabatization_matrix( 'showmatrix adiabatH') * AU_TO_EV diabat_data = { 'rot_matrix': rot_matrix, 'adiabatic_matrix': adiabatic_matrix.tolist(), 'diabatic_matrix': diabatic_matrix.tolist() } if diabat_section.find('showmatrix Total_Decomposed_H_diabatic'): tot_decomp_matrix = read_diabatization_matrix( 'showmatrix Total_Decomposed_H_diabatic') * AU_TO_EV decomp_one_matrix = read_diabatization_matrix( 'showmatrix Decomposed_One_diabatic') * AU_TO_EV decomp_j_matrix = read_diabatization_matrix( 'showmatrix Decomposed_J_diabatic') * AU_TO_EV decomp_k_matrix = read_diabatization_matrix( 'showmatrix Decomposed_K_diabatic') * AU_TO_EV diabat_data.update({ 'tot_decomp_matrix': tot_decomp_matrix, 'decomp_one_matrix': decomp_one_matrix.tolist(), 'decomp_j_matrix': decomp_j_matrix.tolist(), 'decomp_k_matrix': decomp_k_matrix.tolist() }) mulliken_diabatic = [] enum = output.find('Mulliken & Loewdin analysis of') for m in re.finditer('Mulliken analysis of TDA State', output[enum:]): section_mulliken = output[m.end() + enum:m.end() + 10000 + enum] # 10000: assumed to max of section section_mulliken = section_mulliken[:section_mulliken.find( 'Natural Orbitals stored in FCHK')] section_attachment = section_mulliken.split('\n')[10 + n_atoms:10 + n_atoms * 2] mulliken_diabatic.append({ 'attach': [float(l.split()[1]) for l in section_attachment], 'detach': [float(l.split()[2]) for l in section_attachment], 'total': [float(l.split()[3]) for l in section_attachment] }) diabatic_states = [] for i in range(len(rot_matrix)): diabat_states_data = { 'excitation_energy': diabatic_matrix[i][i], 'excitation_energy_units': 'eV', 'transition_moment': [], 'dipole_moment_units': 'ua' } if len(mulliken_diabatic) > 0: diabat_states_data['mulliken'] = mulliken_diabatic[i] diabatic_states.append(diabat_states_data) diabat_data['diabatic_states'] = diabatic_states data_dict['diabatization'] = diabat_data return data_dict
[0.0000000, 0.9228100, -1.2279200], [distance, 0.0000000, 0.6660120], [distance, 0.0000000, -0.6660120], [distance, 0.9228100, 1.2279200], [distance, -0.9228100, 1.2279200], [distance, -0.9228100, -1.2279200], [distance, 0.9228100, -1.2279200]] coordinates = np.array(coordinates) coordinates[6:, 1] = coordinates[6:, 1] + slide_y coordinates[6:, 2] = coordinates[6:, 2] + slide_z molecule = Structure(coordinates=coordinates, symbols=[ 'C', 'C', 'H', 'H', 'H', 'H', 'C', 'C', 'H', 'H', 'H', 'H' ], charge=0) txt_input = create_qchem_input(molecule, **parameters) # print(txt_input) data = get_output_from_qchem(txt_input, processors=4, force_recalculation=False, parser=basic_parser_qchem) # if closed shell ocup_orb = (np.sum(molecule.get_atomic_numbers()) - molecule.charge) // 2 n_states = 2
# Spin-orbit coupling calculation using TD-DFT and RASCI from pyqchem.qchem_core import get_output_from_qchem from pyqchem.qc_input import QchemInput from pyqchem.structure import Structure from pyqchem.parsers.parser_rasci import parser_rasci from pyqchem.parsers.parser_cis import basic_cis as parser_cis import numpy as np # Carbon atom defintion atom_c = Structure(coordinates=[[0.0, 0.0, 0.0]], symbols=['C'], charge=-2, multiplicity=1, name='C') basis_name = '6-31G**' # RAS_CI calculation qc_input_rasci = QchemInput(atom_c, jobtype='sp', exchange='hf', correlation='rasci', unrestricted=True, thresh=14, scf_convergence=8, max_cis_cycles=150, max_scf_cycles=100, basis=basis_name, ras_elec_alpha=3, ras_elec_beta=1, ras_act=4, ras_occ=1,
from pyqchem.qchem_core import get_output_from_qchem, redefine_calculation_data_filename from pyqchem.qc_input import QchemInput from pyqchem.structure import Structure from pyqchem.parsers.parser_rasci import parser_rasci as parser_rasci from pyqchem.basis import get_basis_from_ccRepo, trucate_basis, basis_to_txt import numpy as np from pyqchem.errors import OutputError redefine_calculation_data_filename('test_soc3s.pkl') as_c_triplet = [[3, 1], 4, 1] as_c_singlet = [[2, 2], 4, 1] atom_c = Structure(coordinates=[[0.0, 0.0, 0.0]], symbols=['C'], charge=-1, multiplicity=4, name='C') as_o_triplet = [[4, 2], 4, 1] as_o_singlet = [[3, 3], 4, 1] atom_o = Structure(coordinates=[[0.0, 0.0, 0.0]], symbols=['O'], charge=-2, multiplicity=1, name='O') as_si_triplet = [[7, 5], 8, 1] as_si_singlet = [[6, 6], 8, 1] atom_si = Structure(coordinates=[[0.0, 0.0, 0.0]], symbols=['Si'], charge=-1,
energies = [] energies_es = [] atoms = ['C', 'O', 'Si'] omegas = [pow(10, i) for i in np.arange(1, 2, 0.25)] atom_data = {} for atom in atoms: data_omega = [] for omega in omegas: try: molecule = Structure(coordinates=[[0.0, 0.0, 0.0]], symbols=[atom], charge=0) parameters.update({'ras_omega': int(omega)}) gap_list = [] for ispin in [True, False]: print(ispin) parameters.update({'ras_srdft_spinpol': ispin}) # singlet parameters.update({'ras_spin_mult': 1}) txt_input = create_qchem_input(molecule, **parameters) data_singlet = get_output_from_qchem(txt_input, processors=4, parser=basic_parser_qchem)
from pyqchem.qc_input import QchemInput from pyqchem.structure import Structure from pyqchem.parsers.parser_rasci import parser_rasci from pyqchem.parsers.parser_cis import basic_cis from pyqchem.symmetry import get_state_symmetry import numpy as np ethene = [[0.0, 0.0000, 0.65750], [0.0, 0.0000, -0.65750], [0.0, 0.92281, 1.22792], [0.0, -0.92281, 1.22792], [0.0, -0.92281, -1.22792], [0.0, 0.92281, -1.22792]] symbols = ['C', 'C', 'H', 'H', 'H', 'H'] # create molecule molecule = Structure(coordinates=ethene, symbols=symbols, charge=0, multiplicity=1) point_group = molecule.get_point_symmetry() print('Point group: {}\n'.format(point_group)) # create Q-Chem input qc_input = QchemInput(molecule, jobtype='sp', exchange='hf', correlation='rasci', ras_act=6, ras_elec=6, basis='6-311(2+,2+)G**', ras_roots=10, ras_do_hole=False,
def basic_optimization(output, print_data=False): data_dict = {} # Molecule n = output.find('$molecule') n2 = output[n:].find('$end') molecule_region = output[n:n + n2 - 1].replace('\t', ' ').split('\n')[1:] charge, multiplicity = [int(num) for num in molecule_region[0].split()] coordinates = np.array([ np.array(line.split()[1:4], dtype=float) for line in molecule_region[1:] ]) symbols = [line.split()[0].capitalize() for line in molecule_region[1:]] n_atoms = len(coordinates) step_s2 = None # Optimization steps optimization_steps = [] list_iterations = [ l.end() for l in re.finditer('Optimization Cycle', output) ] for ini, fin in zip(list_iterations, list_iterations[1:] + [len(output)]): step_section = output[ini:fin] enum = step_section.find('Coordinates (Angstroms)') atoms_list = step_section[enum:].split('\n')[2:n_atoms + 2] coordinates_step = np.array([atom.split()[2:] for atom in atoms_list], dtype=float).tolist() step_molecule = Structure(coordinates=coordinates_step, symbols=symbols, charge=charge, multiplicity=multiplicity) enum = step_section.find('Energy is') step_energy = float(step_section[enum:enum + 50].split()[2]) enum = step_section.find(' Gradient') step_gradient = float(step_section[enum:enum + 50].split()[1]) enum = step_section.find(' Displacement') step_displacement = float(step_section[enum:enum + 50].split()[1]) enum = step_section.find('<S^2>') if enum > 0: step_s2 = float(step_section[enum:enum + 50].split()[2]) optimization_steps.append({ 'molecule': step_molecule, 'energy': step_energy, 'gradient': step_gradient, 'displacement': step_displacement }) data_dict['optimization_steps'] = optimization_steps # Optimization Convergence enum = output.find('** OPTIMIZATION CONVERGED **') if enum > 0: ne = output[enum - 200:enum].find('Final energy') final_energy = float(output[ne + enum - 200:enum].split()[3]) optimization_section = output[enum:] coordinates_section = optimization_section.split('\n') coordinates_final = [ line.split()[2:5] for line in coordinates_section[5:5 + n_atoms] ] optimized_molecule = Structure(coordinates=np.array( coordinates_final, dtype=float).tolist(), symbols=symbols, charge=charge, multiplicity=multiplicity) data_dict['optimized_molecule'] = optimized_molecule data_dict['energy'] = final_energy data_dict['s2'] = step_s2 return data_dict
[0.8867106, -2.6006386, -3.199612], [0.8941856, -2.5562337, 2.9920521], [-0.8941856, -2.5562337, 2.9920521], [0., -4.0461503, 2.5809354], [-0.8867106, 2.6006386, -3.199612], [0., 4.0761113, -2.7556685], [0.8867106, 2.6006386, -3.199612], [0., 4.0461503, 2.5809354], [-0.8941856, 2.5562337, 2.9920521], [0.8941856, 2.5562337, 2.9920521]] symbols = [ 'C', 'C', 'N', 'C', 'C', 'B', 'N', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'F', 'F', 'H', 'H', 'H', 'H', 'H', 'H', 'H', 'H', 'H', 'H', 'H', 'H', 'H', 'H', 'H' ] molecule = Structure(coordinates=coordinates, symbols=symbols, charge=0, multiplicity=1) molecule.get_coordinates() print('optimize molecule') txt_input = create_qchem_input(molecule, jobtype='opt', method='b3lyp', basis='cc-pVDZ', geom_opt_tol_gradient=50, geom_opt_coords=-1, geom_opt_tol_displacement=800) parsed_data = get_output_from_qchem(txt_input,
[-1.21479, 0.70136, 0.00000], [-2.15666, 1.24515, 0.00000], [-1.21479, -0.70136, 0.00000], [-2.15666, -1.24515, 0.00000], [0.00000, -1.40272, 0.00000], [0.00000, -2.49029, 0.00000], [1.21479, -0.70136, 0.00000], [2.15666, -1.24515, 0.00000], [1.21479, 0.70136, 0.00000], [2.15666, 1.24515, 0.00000]] symbols = ['C', 'H', 'C', 'H', 'C', 'H', 'C', 'H', 'C', 'H', 'C', 'H'] # create molecule molecule = Structure(coordinates=benzene_coordinates, symbols=symbols, charge=0, multiplicity=1) # define Q-Chem parameters parameters = {'jobtype': 'sp', 'exchange': 'hf', 'basis': '6-31G'} # create Q-Chem input qc_input = create_qchem_input(molecule, **parameters) # get data from Q-Chem calculation output, parsed_fchk = get_output_from_qchem(qc_input, processors=4, force_recalculation=False, read_fchk=True, fchk_only=True)
del atom['shells'][i] return basis_trunc if __name__ == '__main__': citation, description, basis = get_basis_element_from_ccRepo( 'C', program='Gaussian', basis='cc-pVTZ') print(citation) print(description) print('-----------------------') for line in basis: print(line) basis = _txt_to_basis_dict(basis) print(basis) from pyqchem.structure import Structure # create molecule molecule = Structure(coordinates=[[0.0, 0.0, 0.0000], [0.0, 0.0, 1.5811]], symbols=['Se', 'H'], charge=-1, multiplicity=1) basis = get_basis_from_ccRepo(molecule, basis='cc-pVTZ', full=False) print(basis_to_txt(basis))
from pyqchem.qchem_core import get_output_from_qchem, redefine_calculation_data_filename from pyqchem.qc_input import QchemInput from pyqchem.structure import Structure from pyqchem.parsers.parser_rasci import parser_rasci as parser_rasci from pyqchem.basis import get_basis_from_ccRepo, trucate_basis, basis_to_txt import numpy as np from pyqchem.errors import OutputError redefine_calculation_data_filename('test_soc3s_b.pkl') as_f_doblet = [[4, 3], 4, 1] atom_f = Structure(coordinates=[[0.0, 0.0, 0.0]], symbols=['F'], charge=-1, multiplicity=1, name='F') as_cl_doblet = [[8, 7], 8, 1] atom_cl = Structure(coordinates=[[0.0, 0.0, 0.0]], symbols=['Cl'], charge=-1, multiplicity=1, name='Cl') experimental = {'F': [0, 0], 'Cl': [0,0]} use_experimental = False