def workflow_derivative_couplings(workflow_settings: Dict): """ Compute the derivative couplings from an MD trajectory. :param workflow_settings: Arguments to compute the oscillators see: `data/schemas/derivative_couplings.json :returns: None """ # Arguments to compute the orbitals and configure the workflow. see: # `data/schemas/general_settings.json config = workflow_settings['general_settings'] # Dictionary containing the general configuration config.update(initialize(**config)) # compute the molecular orbitals mo_paths_hdf5 = calculate_mos(**config) # Overlap matrix at two different times promised_overlaps = calculate_overlap( config['project_name'], config['path_hdf5'], config['dictCGFs'], config['geometries'], mo_paths_hdf5, config['hdf5_trans_mtx'], config['enumerate_from'], workflow_settings['overlaps_deph'], nHOMO=workflow_settings['nHOMO'], couplings_range=workflow_settings['couplings_range']) # Create a function that returns a proxime array of couplings schedule_couplings = schedule(lazy_couplings) # Calculate Non-Adiabatic Coupling promised_crossing_and_couplings = schedule_couplings( promised_overlaps, config['path_hdf5'], config['project_name'], config['enumerate_from'], workflow_settings['nHOMO'], workflow_settings['dt'], workflow_settings['tracking'], workflow_settings['write_overlaps'], algorithm=workflow_settings['algorithm']) # Write the results in PYXAID format work_dir = config['work_dir'] path_hamiltonians = join(work_dir, 'hamiltonians') if not os.path.exists(path_hamiltonians): os.makedirs(path_hamiltonians) # Inplace scheduling of write_hamiltonians function. # Equivalent to add @schedule on top of the function schedule_write_ham = schedule(write_hamiltonians) # Number of matrix computed nPoints = len(config['geometries']) - 2 # Write Hamilotians in PYXAID format promise_files = schedule_write_ham( config['path_hdf5'], mo_paths_hdf5, promised_crossing_and_couplings, nPoints, path_dir_results=path_hamiltonians, enumerate_from=config['enumerate_from'], nHOMO=workflow_settings['nHOMO'], couplings_range=workflow_settings['couplings_range']) run(promise_files, folder=work_dir) remove_folders(config['folders'])
def test_linear_ts(): """ compute a first approximation to the TS. """ # Read the Molecule from file cnc = Molecule('test/test_files/C-N-C.mol', 'mol') # User define Settings settings = Settings() settings.functional = "pbe" settings.basis = "SZ" settings.specific.dftb.dftb.scc constraint1 = Distance(1, 5) constraint2 = Distance(3, 4) # scan input pes = PES(cnc, constraints=[constraint1, constraint2], offset=[2.3, 2.3], get_current_values=False, nsteps=2, stepsize=[0.1, 0.1]) # returns a set of results object containing the output of # each point in the scan lt = pes.scan([dftb, adf], settings) # Gets the object presenting the molecule # with the maximum energy calculated from the scan apprTS = select_max(lt, "energy") # Run the TS optimization, using the default TS template ts = run(apprTS) expected_energy = -3.219708290363864 assert abs(ts.energy - expected_energy) < 0.02
def workflow_single_points(config: DictConfig) -> Result: """Perform single point calculations for a given trajectory. Parameters ---------- config Input to run the workflow. Returns ------- List with the node path to the molecular orbitals in the HDF5. """ # Dictionary containing the general configuration config.update(initialize(config)) logger.info("starting!") # compute the molecular orbitals # Unpack mo_paths_hdf5 = calculate_mos(config) # Pack results = run(mo_paths_hdf5, folder=config.workdir) return results
def main(file_xyz, cell, restart, basis, basis_folder): # Define which systems need to be calculated system = Molecule(file_xyz) # Set path for basis set basisCP2K = join(basis_folder, "BASIS_MOLOPT") potCP2K = join(basis_folder, "GTH_POTENTIALS") # Settings specifics s = templates.geometry s.basis = basis s.potential = "GTH-PBE" s.cell_parameters = cell s.specific.cp2k.force_eval.dft.basis_set_file_name = basisCP2K s.specific.cp2k.force_eval.dft.potential_file_name = potCP2K # s.specific.cp2k.force_eval.dft.uks = '' # s.specific.cp2k.force_eval.dft.charge = '1' # s.specific.cp2k.force_eval.dft.multiplicity = '2' s.specific.cp2k.force_eval.dft.wfn_restart_file_name = '{}'.format(restart) # ======================= # Compute OPT files with CP2k # ======================= result = run(cp2k(s, system)) # ====================== # Output the results # ====================== print(result.energy)
def workflow_stddft(config: dict) -> None: """ Compute the excited states using simplified TDDFT :param workflow_settings: Arguments to compute the oscillators see: `data/schemas/absorption_spectrum.json :returns: None """ # Dictionary containing the general configuration config.update(initialize(config)) # Single Point calculations settings using CP2K mo_paths_hdf5, energy_paths_hdf5 = unpack(calculate_mos(config), 2) # Read structures molecules_au = [ change_mol_units(parse_string_xyz(gs)) for i, gs in enumerate(config.geometries) if (i % config.stride) == 0 ] # Noodles promised call scheduleTDDFT = schedule(compute_excited_states_tddft) results = gather(*[ scheduleTDDFT(config, mo_paths_hdf5[i], DictConfig({ 'i': i * config.stride, 'mol': mol })) for i, mol in enumerate(molecules_au) ]) return run(gather(results, energy_paths_hdf5), folder=config['workdir'])
def workflow_stddft(config: dict) -> None: """ Compute the excited states using simplified TDDFT :param workflow_settings: Arguments to compute the oscillators see: `data/schemas/absorption_spectrum.json :returns: None """ # Dictionary containing the general configuration config.update(initialize(config)) # Single Point calculations settings using CP2K mo_paths_hdf5, energy_paths_hdf5 = unpack(calculate_mos(config), 2) # Read structures molecules_au = [change_mol_units(parse_string_xyz(gs)) for i, gs in enumerate(config.geometries) if (i % config.stride) == 0] # Noodles promised call scheduleTDDFT = schedule(compute_excited_states_tddft) results = gather( *[scheduleTDDFT(config, mo_paths_hdf5[i], DictConfig( {'i': i * config.stride, 'mol': mol})) for i, mol in enumerate(molecules_au)]) return run(gather(results, energy_paths_hdf5), folder=config['workdir'])
def fun_ethylene(scratch_path): """ Test Ethylene single """ geometry = Molecule('test/test_files/ethylene.xyz') job_settings = prepare_cp2k_settings(geometry, scratch_path) cp2k_result = run(cp2k(job_settings, geometry, work_dir=scratch_path)) # Path to the HDF5 file hdf5_file = 'quantum.hdf5' # Path to the molecular orbitals energies and coefficients path_es = 'ethylene/cp2k_job/cp2k/mo/eigenvalues' path_css = 'ethylene/cp2k_job/cp2k/mo/coefficients' with h5py.File(hdf5_file) as f5: dump_to_hdf5(cp2k_result.orbitals, 'cp2k', f5, project_name='ethylene', job_name=cp2k_result.job_name, property_to_dump='orbitals') energies = f5[path_es].value coefficients = f5[path_css].value print("Energy array shape: ", energies.shape) print("Coefficients array shape: ", coefficients.shape) assert (energies.shape == (40, )) and (coefficients.shape == (46, 40))
def main(file_xyz, cell, restart, basis, basis_folder): """Define which systems need to be calculated.""" system = Molecule(file_xyz) # Set path for basis set basisCP2K = join(basis_folder, "BASIS_MOLOPT") potCP2K = join(basis_folder, "GTH_POTENTIALS") # Settings specifics s = templates.geometry s.basis = basis s.potential = "GTH-PBE" s.cell_parameters = cell s.specific.cp2k.force_eval.dft.basis_set_file_name = basisCP2K s.specific.cp2k.force_eval.dft.potential_file_name = potCP2K s.specific.cp2k.force_eval.dft.uks = '' s.specific.cp2k.force_eval.dft.charge = '-1' s.specific.cp2k.force_eval.dft.multiplicity = '2' s.specific.cp2k.force_eval.dft.wfn_restart_file_name = f'{restart}' # ======================= # Compute OPT files with CP2k # ======================= result = run(cp2k(s, system)) # ====================== # Output the results # ====================== print(result.energy)
def test_c2pk_cell_opt() -> None: """Test CP2K cell optimization calculations with the :class:`CP2K_MM` class.""" mol = Molecule(PATH / 'cspbbr3_3d.xyz') s = Settings() s.specific.cp2k += cell_opt.specific.cp2k_mm.copy() s.specific.cp2k.motion.cell_opt.max_iter = 10 s.specific.cp2k.motion.print['forces low'].filename = '' s.gmax = [22, 22, 22] s.cell_parameters = [25.452, 35.995, 24.452] s.charge = { 'param': 'charge', 'Cs': 0.2, 'Pb': 0.4, 'Br': -0.2, } s.lennard_jones = { 'param': ('sigma', 'epsilon'), 'unit': ('nm', 'kjmol'), 'Cs Cs': (0.585, 1), 'Cs Pb': (0.510, 1), 'Br Se': (0.385, 1), 'Pb Pb': (0.598, 1), 'Br Pb': (0.290, 1), 'Br Br': (0.426, 1), } job = cp2k_mm(settings=s, mol=mol, job_name='cp2k_mm_cell_opt') result = run(job, path=PATH) assertion.eq(result.status, 'successful')
def test_freq(): """Do some constraint optimizations then launch a freq calc.""" mol = Molecule(PATH_MOLECULES / "ethene.xyz", "xyz") geo_opt = dftb(templates.geometry, mol) freq_calc = dftb(templates.freq, geo_opt.molecule, job_name="freq") r = run(freq_calc) assertion.eq(int(r.frequencies[0]), 831) assertion.len_eq(r.frequencies, 12)
def test_fail_dirac(): """ Dirac package should return ``None`` if it fails """ mol = Molecule("test/test_files/h2.xyz") s = Settings() job = dirac(s, mol, job_name="fail_dirac") result = run(job.energy) assert isNone(result)
def test_freq(): """ Do some constraint optimizations then launch a freq calc. """ mol = Molecule("test/test_files/ethene.xyz", "xyz") geo_opt = dftb(templates.geometry, mol) freq_calc = dftb(templates.freq, geo_opt.molecule, job_name="freq") r = run(freq_calc) assert int(r.frequencies[0]) == 831 assert len(r.frequencies) == 12
def test_fail_orca(): """ Orca package should returns ``None`` if the computation fails""" methanol = Molecule('test/test_files/methanol.xyz') s = Settings() s.specific.orca.main = "RKS The_Cow_Functional SVP Opt TightSCF SmallPrint" opt = orca(s, methanol, job_name='fail_orca') result = run(opt.molecule) assert isNone(result)
def test_fail_dirac(): """ Dirac package should return ``None`` if it fails """ folder = tempfile.mkdtemp(prefix="qmflows_") mol = Molecule("test/test_files/h2.xyz") s = Settings() job = dirac(s, mol, job_name="fail_dirac") try: result = run(job.energy, path=folder) assert isNone(result) finally: remove(folder)
def test_fail_orca(tmpdir): """Orca package should returns ``None`` if the computation fails.""" methanol = Molecule(PATH_MOLECULES / 'methanol.xyz') s = Settings() s.specific.orca.main = "RKS The_Cow_Functional SVP Opt TightSCF SmallPrint" opt = orca(s, methanol, job_name='fail_orca') result = run(opt.molecule, path=tmpdir) assertion.eq(result, None)
def test_singlepoint() -> None: """Test CP2K singlepoint calculations with the :class:`CP2K_MM` class.""" s = SETTINGS.copy() s.specific.cp2k += singlepoint.specific.cp2k_mm job = cp2k_mm(settings=s, mol=MOL, job_name='cp2k_mm_sp') result = run(job, path=PATH) assertion.eq(result.status, 'successful') # Compare energies ref = -15.4431781758 assertion.isclose(result.energy, ref, rel_tol=10**-4)
def test_run_packages(): """ Test the Workflow runner. """ folder = tempfile.mkdtemp(prefix="qmflows_") try: wf = g(3, f(5, 2)) result = run(wf, path=folder, folder=folder) assert result == 16 finally: if os.path.isdir(folder): shutil.rmtree(folder)
def example_FDE_fragments(): # For the purpose of the example, define xyz files here: xyz1 = io.StringIO('''3 O 0.00000000000000 -2.29819386240000 1.63037963360000 H -0.76925379540000 -2.28223123190000 2.22684542850000 H 0.76925379540000 -2.28223123190000 2.22684542850000''') xyz2 = io.StringIO('''3 O 0.00000000000000 2.29819386240000 1.63037963360000 H -0.76925379540000 2.28223123190000 2.22684542850000 H 0.76925379540000 2.28223123190000 2.22684542850000''') xyz3 = io.StringIO('''3 O 0.00000000000000 0.00000000000000 -0.26192472620000 H 0.00000000000000 0.77162768440000 0.34261631290000 H 0.00000000000000 -0.77162768440000 0.34261631290000''') # Read the Molecule from file m_h2o_1 = Molecule() m_h2o_1.readxyz(xyz1, 1) m_h2o_2 = Molecule() m_h2o_2.readxyz(xyz2, 1) m_mol = Molecule() m_mol.readxyz(xyz3, 1) settings = Settings() settings.basis = 'SZ' settings.specific.adf.nosymfit = '' # Prepare first water fragment r_h2o_1 = adf(templates.singlepoint.overlay(settings), m_h2o_1, job_name="h2o_1") # Prepare second water fragment r_h2o_2 = adf(templates.singlepoint.overlay(settings), m_h2o_2, job_name="h2o_2") frags = gather(schedule(Fragment)(r_h2o_1, m_h2o_1, isfrozen=True), schedule(Fragment)(r_h2o_2, m_h2o_2, isfrozen=True), Fragment(None, m_mol)) job_fde = adf_fragmentsjob(templates.singlepoint. overlay(settings), frags, job_name="test_fde_fragments") # Perform FDE job and get dipole # This gets the dipole moment of the active subsystem only dipole_fde = run(job_fde.dipole) print('FDE dipole:', dipole_fde) return dipole_fde
def select_orbitals_type(config: DictConfig, workflow: Callable[[DictConfig], Any]) -> Any: """Call a workflow using restriced or unrestricted orbitals.""" # Dictionary containing the general configuration config.update(initialize(config)) if config.orbitals_type != "both": logger.info("starting workflow calculation!") promises = workflow(config) return run(promises, folder=config.workdir, always_cache=False) else: config_alphas = DictConfig(config.copy()) config_betas = DictConfig(config.copy()) config_alphas.orbitals_type = "alphas" promises_alphas = workflow(config_alphas) config_betas.orbitals_type = "betas" promises_betas = workflow(config_betas) all_promises = gather(promises_alphas, promises_betas) alphas, betas = run(all_promises, folder=config.workdir, always_cache=False) return alphas, betas
def test_adf_props(): """ Get properties from ADF freq calc """ mol = molkit.from_smiles('F[H]') result = run(adf(templates.freq, mol, job_name='adf_FH')) expected_energy = -0.30 assert abs(result.energy - expected_energy) < 0.01 assert len(result.dipole) == 3 expected_frequency = 3480.90 assert abs(result.frequencies[1] - expected_frequency) < 0.1 assert len(result.charges) == 2 assert abs(result.charges[0] + result.charges[1]) < 1e-6
def test_dftb_props(): """ Get properties from DFTB freq calc """ mol = molkit.from_smiles('F[H]') result = run(dftb(templates.freq, mol, job_name='dftb_FH')) expected_energy = -4.76 assert abs(result.energy - expected_energy) < 0.01 assert len(result.dipole) == 3 expected_frequency = 3460.92 assert abs(result.frequencies - expected_frequency) < 0.1 assert len(result.charges) == 2 assert abs(result.charges[0] + result.charges[1]) < 1e-6
def compute_ldos(mol: Molecule, coord: NestedDict, name: str, workdir: str, path_results: str) -> None: """Compute the DOS projected on subsets of atoms given through lists. These lists are divided by atom type and coordination number. """ # Get cp2k settings s = create_cp2k_settings(mol) # Get the cp2k ldos setting containing the lists ldos = create_ldos_lists(coord) # Join settings and update with the single point template s.specific = s.specific + ldos sett_ldos = templates.singlepoint.overlay(s) # Create the cp2k job dos_job = cp2k(sett_ldos, mol, job_name="cp2k_ldos") # Run the cp2k job run(dos_job, path=workdir, folder=name) store_coordination(coord, name, path_results) logger.info(f"{name} LDOS has been printed with CP2K")
def test_numgrad(): """ Test Dirac numerical opt. """ # read geometry h2 = Molecule('test/test_files/h2.xyz') # create a dirac job job = create_job("h2_opt", h2) properties = [job.energy, job.molecule] rs = run(gather(*properties)) print("Energy:", rs[0]) print("Molecule: ", rs[1])
def test_md() -> None: """Test CP2K molecular dynamics calculations with the :class:`CP2K_MM` class.""" mol = Molecule( PATH_MOLECULES / 'Cd68Cl26Se55__26_acetate.freq.xyz') # Optimized coordinates s = SETTINGS.copy() s.specific.cp2k += md.specific.cp2k_mm s.specific.cp2k.motion.md.steps = 1000 job = cp2k_mm(settings=s, mol=mol, job_name='cp2k_mm_md') result = run(job, path=PATH) assertion.eq(result.status, 'successful') plams_results = result.results assertion.isfile(plams_results['cp2k-1_1000.restart'])
def test_fail_orca(): """ Orca package should returns ``None`` if the computation fails""" folder = tempfile.mkdtemp(prefix="qmflows_") methanol = Molecule('test/test_files/methanol.xyz') s = Settings() s.specific.orca.main = "RKS The_Cow_Functional SVP Opt TightSCF SmallPrint" opt = orca(s, methanol, job_name='fail_orca') try: result = run(opt.molecule, path=folder) assert isNone(result) finally: remove(folder)
def test_cp2k_opt(tmp_path: PathLike): """Run a simple molecular optimization.""" s = fill_cp2k_defaults(templates.geometry) # Do a single step s.specific.cp2k.motion.geo_opt.max_iter = 1 s.specific.cp2k.force_eval.dft.scf.eps_scf = 1e-1 water = Molecule(PATH_MOLECULES / "h2o.xyz", 'xyz', charge=0, multiplicity=1) job = cp2k(s, water) mol = run(job, folder=tmp_path) assertion.isinstance(mol.molecule, Molecule)
def test_fail_scm(): """ Test that both ADF and DFTB returns ``None`` if a computation fails""" # 5 membered ring from which ozone will dissociate mol = Molecule("test/test_files/ethylene.xyz") # Some dftb specific settings dftb_set = Settings() dftb_set.specific.dftb.dftb.scc # Calculate the DFTB hessian opt_dftb = dftb(templates.geometry.overlay(dftb_set), mol, job_name="failed_DFTB") fail_adf = adf(None, opt_dftb.molecule, job_name="fail_adf") result = run(fail_adf.molecule) print(result) assert isNone(result)
def compute_geo_opt(mol: Molecule, name: str, workdir: str, path_results: str) -> Molecule: """Perform the geometry optimization of **mol**.""" # Get cp2k settings s = create_cp2k_settings(mol) # Update the setting with the geometry optimization template sett_geo_opt = templates.geometry.overlay(s) # Create the cp2k job opt_job = cp2k(sett_geo_opt, mol, job_name="cp2k_opt") # Run the cp2k job optimized_geometry = run(opt_job.geometry, path=workdir, folder=name) store_optimized_molecule(optimized_geometry, name, path_results) logger.info(f"{name} has been optimized with CP2K") return optimized_geometry
def workflow_oscillator_strength(workflow_settings: Dict): """ Compute the oscillator strength. :param workflow_settings: Arguments to compute the oscillators see: `data/schemas/absorption_spectrum.json :returns: None """ # Arguments to compute the orbitals and configure the workflow. see: # `data/schemas/general_settings.json config = workflow_settings['general_settings'] # Dictionary containing the general configuration config.update(initialize(**config)) # Point calculations Using CP2K mo_paths_hdf5 = calculate_mos(**config) # geometries in atomic units molecules_au = [change_mol_units(parse_string_xyz(gs)) for gs in config['geometries']] # Construct initial and final states ranges transition_args = [workflow_settings[key] for key in ['initial_states', 'final_states', 'nHOMO']] initial_states, final_states = build_transitions(*transition_args) # Make a promise object the function the compute the Oscillator Strenghts scheduleOscillator = schedule(calc_oscillator_strenghts) oscillators = gather( *[scheduleOscillator( i, mol, mo_paths_hdf5, initial_states, final_states, config) for i, mol in enumerate(molecules_au) if i % workflow_settings['calculate_oscillator_every'] == 0]) energies, promised_cross_section = create_promised_cross_section( oscillators, workflow_settings['broadening'], workflow_settings['energy_range'], workflow_settings['convolution'], workflow_settings['calculate_oscillator_every']) cross_section, data = run( gather(promised_cross_section, oscillators), folder=config['work_dir']) return store_data(data, energies, cross_section)
def workflow_derivative_couplings(config: dict) -> list: """ Compute the derivative couplings from an MD trajectory. :param workflow_settings: Arguments to compute the oscillators see: `nac/workflows/schemas.py :returns: None """ # Dictionary containing the general configuration config.update(initialize(config)) logger.info("starting couplings calculation!") # compute the molecular orbitals mo_paths_hdf5, energy_paths_hdf5 = unpack(calculate_mos(config), 2) # mo_paths_hdf5 = run(calculate_mos(config), folder=config.workdir) # Overlap matrix at two different times promised_overlaps = calculate_overlap(config, mo_paths_hdf5) # Calculate Non-Adiabatic Coupling promised_crossing_and_couplings = lazy_couplings(config, promised_overlaps) # Write the results in PYXAID format config.path_hamiltonians = create_path_hamiltonians(config.workdir) # Inplace scheduling of write_hamiltonians function. # Equivalent to add @schedule on top of the function schedule_write_ham = schedule(write_hamiltonians) # Number of matrix computed config["nPoints"] = len(config.geometries) - 2 # Write Hamilotians in PYXAID format promise_files = schedule_write_ham( config, promised_crossing_and_couplings, mo_paths_hdf5) results = run( gather(promise_files, energy_paths_hdf5), folder=config.workdir, always_cache=False) remove_folders(config.folders) return results
def workflow_single_points(config: dict) -> list: """ Single point calculations for a given trajectory :param workflow_settings: Arguments to run the single points calculations see: `nac/workflows/schemas.py """ # Dictionary containing the general configuration config.update(initialize(config)) logger.info("starting!") # compute the molecular orbitals # Unpack mo_paths_hdf5 = calculate_mos(config) # Pack results = run(mo_paths_hdf5, folder=config.workdir) return results
def workflow_derivative_couplings(config: dict) -> list: """ Compute the derivative couplings from an MD trajectory. :param workflow_settings: Arguments to compute the oscillators see: `nac/workflows/schemas.py :returns: None """ # Dictionary containing the general configuration config.update(initialize(config)) logger.info("starting!") # compute the molecular orbitals mo_paths_hdf5, energy_paths_hdf5 = unpack(calculate_mos(config), 2) # mo_paths_hdf5 = run(calculate_mos(config), folder=config.workdir) # Overlap matrix at two different times promised_overlaps = calculate_overlap(config, mo_paths_hdf5) # Calculate Non-Adiabatic Coupling promised_crossing_and_couplings = lazy_couplings(config, promised_overlaps) # Write the results in PYXAID format config.path_hamiltonians = create_path_hamiltonians(config.workdir) # Inplace scheduling of write_hamiltonians function. # Equivalent to add @schedule on top of the function schedule_write_ham = schedule(write_hamiltonians) # Number of matrix computed config["nPoints"] = len(config.geometries) - 2 # Write Hamilotians in PYXAID format promise_files = schedule_write_ham( config, promised_crossing_and_couplings, mo_paths_hdf5) results = run(gather(promise_files, energy_paths_hdf5), folder=config.workdir) remove_folders(config.folders) return results
def example_partial_geometry_opt(): """ Performa partial optimization freezing the Hydrogen atoms """ methanol = molkit.from_smiles('CO') # optimize only H atoms s = Settings() s.freeze = [1, 2] geom_job1 = adf(templates.geometry.overlay(s), methanol, job_name='geom_job1').molecule # optimize only H atoms s = Settings() s.selected_atoms = ['H'] geom_job2 = adf(templates.geometry.overlay(s), methanol, job_name='geom_job2').molecule geom1, geom2 = run(gather(geom_job1, geom_job2), n_processes=1) return geom1, geom2
def example_generic_constraints(): """ This examples illustrates that, by using generic keywords, it is possible to call different packages interchangeably with the same Settings """ # build hydrogen fluoride molecule hydrogen_fluoride = molkit.from_smiles('F[H]') # loop over distances jobs = [] for distance in [1.0, 1.1, 1.2]: s = Settings() s.constraint['dist 1 2'] = distance # loop over packages for package in [dftb, adf, orca]: job_name = package.pkg_name + '_' + str(distance) constraint_opt = package(templates.geometry.overlay(s), hydrogen_fluoride, job_name) jobs.append(constraint_opt) # run the jobs results = run(gather(*jobs)) energies = [r.energy for r in results] names = [r.job_name for r in results] # put resulting energies into a dictionary table = {'dftb': {}, 'adf': {}, 'orca': {}} for r in results: package, distance = r.job_name.split('_') table[package][distance] = round(r.energy, 6) # print table hartree_to_kcalpermol = 627.094 for package in ['dftb', 'adf', 'orca']: row = [package] for distance in ['1.0', '1.1', '1.2']: val = table[package][distance] - table[package]['1.0'] row.append(round(val * hartree_to_kcalpermol, 2)) print('{:10s} {:10.2f} {:10.2f} {:10.2f}'.format(*row)) return names, energies
def run_plams(path_input): """ Call Plams to run a CP2K job """ # create settings dict_input = process_input(path_input, "derivative_couplings") sett = dict_input['cp2k_general_settings']['cp2k_settings_guess'] # adjust the cell parameters file_cell_parameters = dict_input['cp2k_general_settings'].get("file_cell_parameters") if file_cell_parameters is not None: array_cell_parameters = read_cell_parameters_as_array(file_cell_parameters)[1] sett.cell_parameters = array_cell_parameters[0, 2:11].reshape(3, 3).tolist() # Run the job job = cp2k(sett, plams.Molecule("test/test_files/C.xyz")) print("sett: ", sett) return run(job.energy)
def test_fail_scm(): """ Test that both ADF and DFTB returns ``None`` if a computation fails""" # 5 membered ring from which ozone will dissociate folder = tempfile.mkdtemp(prefix="qmflows_") mol = Molecule("test/test_files/ethylene.xyz") # Some dftb specific settings dftb_set = Settings() dftb_set.specific.dftb.dftb.scc # Calculate the DFTB hessian opt_dftb = dftb(templates.geometry.overlay(dftb_set), mol, job_name="failed_DFTB") fail_adf = adf(None, opt_dftb.molecule, job_name="fail_adf") try: result = run(fail_adf.molecule, path=folder) print(result) assert isNone(result) finally: remove(folder)
def example_freqs(): """ This examples illustrates the possibility to use different packages interchangeably. Analytical frequencies are not available for B3LYP in ADF This workflow captures the resulting error and submits the same job to ORCA. """ # Generate water molecule water = molkit.from_smiles('[OH2]', forcefield='mmff') # Pre-optimize the water molecule opt_water = dftb(templates.geometry, water, job_name="dftb_geometry") jobs = [] # Generate freq jobs for 3 functionals for functional in ['pbe', 'b3lyp', 'blyp']: s = Settings() s.basis = 'DZ' s.functional = functional # Try to perform the jobs with adf or orca, take result from first successful calculation freqjob = find_first_job(is_successful, [adf, orca], templates.freq.overlay(s), opt_water.molecule, job_name=functional) jobs.append(freqjob) # Run workflow results = run(gather(*jobs), n_processes=1) # extrac results freqs = [r.frequencies[-3:] for r in results] functionals = ['pbe', 'b3lyp', 'blyp'] # Print the result table = ["{:10s}{:10.3f}{:10.3f}{:10.3f}\n".format(fun, *fs) for fun, fs in zip(functionals, freqs)] print(table) return freqs
def test_fail_gamess(): """ Gamess should return ``None`` if a calculation fails. """ folder = tempfile.mkdtemp(prefix="qmflows_") symmetry = "Cpi" # Erroneous Keyowrkd methanol = Molecule('test/test_files/ion_methanol.xyz') methanol.properties['symmetry'] = symmetry s = Settings() s.specific.gamess.contrl.nzvar = 12 s.specific.gamess.pcm.solvnt = 'water' s.specific.gamess.basis.gbasis = 'sto' s.specific.gamess.basis.ngauss = 3 inp = templates.geometry.overlay(s) methanol_geometry = gamess(inp, methanol, job_name="fail_gamess", work_dir='/tmp') try: result = run(methanol_geometry.molecule, path=folder) assert isNone(result) finally: remove(folder)
def main(file_xyz, cell, restart, basis, basis_folder): """ Define which systems need to be calculated """ system = Molecule(file_xyz) # Set path for basis set basisCP2K = join(basis_folder, "BASIS_MOLOPT") potCP2K = join(basis_folder, "GTH_POTENTIALS") # Settings specifics s = templates.singlepoint del s.specific.cp2k.force_eval.dft.print.mo s.basis = basis s.potential = "GTH-PBE" s.cell_parameters = cell s.specific.cp2k.force_eval.dft.basis_set_file_name = basisCP2K s.specific.cp2k.force_eval.dft.potential_file_name = potCP2K s.specific.cp2k.force_eval.dft.print.pdos.nlumo = '1000' s.specific.cp2k.force_eval.dft.wfn_restart_file_name = '{}'.format(restart) s.specific.cp2k.force_eval.dft.scf.ot.minimizer = 'DIIS' s.specific.cp2k.force_eval.dft.scf.ot.n_diis = 7 s.specific.cp2k.force_eval.dft.scf.ot.preconditioner = 'FULL_SINGLE_INVERSE' s.specific.cp2k['global']['run_type'] = 'energy' # ======================= # Compute OPT files with CP2k # ======================= result = run(cp2k(s, system)) # ====================== # Output the results # ====================== print(result.energy)