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 create_cp2k_settings(mol: Molecule) -> Settings: """Create CP2K general settings.""" # Set path for basis set path_basis = pkg_resources.resource_filename("nanoqm", "basis/BASIS_MOLOPT") path_potential = pkg_resources.resource_filename("nanoqm", "basis/GTH_POTENTIALS") # Settings specifics s = Settings() s.basis = "DZVP-MOLOPT-SR-GTH" s.potential = "GTH-PBE" s.cell_parameters = 25 s.specific.cp2k.force_eval.subsys.cell.periodic = 'none' s.specific.cp2k.force_eval.dft.basis_set_file_name = path_basis s.specific.cp2k.force_eval.dft.potential_file_name = path_potential # functional s.specific.cp2k.force_eval.dft.xc["xc_functional pbe"] = {} # Generate kinds for the atom types elements = [x.symbol for x in mol.atoms] kinds = generate_kinds(elements, s.basis, s.potential) # Update the setting with the kinds s.specific = s.specific + kinds return s
def test_opt_orca(): """ Test Orca input generation and run functions. """ h2o = Molecule('test/test_files/h2o.xyz', 'xyz', charge=0, multiplicity=1) h2o_geometry = dftb(templates.geometry, h2o) s = Settings() # generic keyword "basis" must be present in the generic dictionary s.basis = "sto_dzp" # "specific" allows the user to apply specific keywords for a # package that are not in a generic dictionary # s.specific.adf.basis.core = "large" r = templates.singlepoint.overlay(s) h2o_singlepoint = orca(r, h2o_geometry.molecule) dipole = h2o_singlepoint.dipole final_result = run(dipole, n_processes=1) expected_dipole = [0.82409, 0.1933, -0.08316] diff = sqrt(sum((x - y) ** 2 for x, y in zip(final_result, expected_dipole))) print("Expected dipole computed with Orca 3.0.3 is:", expected_dipole) print("Actual dipole is:", final_result) assert diff < 1e-2
def test_opt_orca(): """Test Orca input generation and run functions.""" h2o = Molecule(PATH_MOLECULES / "h2o.xyz", 'xyz', charge=0, multiplicity=1) h2o_geometry = dftb(templates.geometry, h2o) s = Settings() # generic keyword "basis" must be present in the generic dictionary s.basis = "sto_dzp" # s.specific.adf.basis.core = "large" r = templates.singlepoint.overlay(s) h2o_singlepoint = orca(r, h2o_geometry.molecule) dipole = h2o_singlepoint.dipole final_result = run(dipole, n_processes=1) expected_dipole = [0.82409, 0.1933, -0.08316] diff = sqrt(sum((x - y)**2 for x, y in zip(final_result, expected_dipole))) logger.info( f"Expected dipole computed with Orca 3.0.3 is: {expected_dipole}") logger.info(f"Actual dipole is: {final_result}") assertion.lt(diff, 1e-2)
def test_opt_orca(): """ Test Orca input generation and run functions. """ h2o = Molecule('test/test_files/h2o.xyz', 'xyz', charge=0, multiplicity=1) h2o_geometry = dftb(templates.geometry, h2o) s = Settings() # generic keyword "basis" must be present in the generic dictionary s.basis = "sto_dzp" # "specific" allows the user to apply specific keywords for a # package that are not in a generic dictionary # s.specific.adf.basis.core = "large" r = templates.singlepoint.overlay(s) h2o_singlepoint = orca(r, h2o_geometry.molecule) dipole = h2o_singlepoint.dipole final_result = run(dipole, n_processes=1) expected_dipole = [0.82409, 0.1933, -0.08316] diff = sqrt(sum((x - y)**2 for x, y in zip(final_result, expected_dipole))) print("Expected dipole computed with Orca 3.0.3 is:", expected_dipole) print("Actual dipole is:", final_result) assert diff < 1e-2
def prepare_cp2k_settings(geometry, work_dir): """ Fills in the parameters for running a single job in CP2K. :param geometry: Molecular geometry stored as String :type geometry: plams.Molecule :param files: Tuple containing the IO files to run the calculations :type files: nameTuple :parameter settings: Dictionary contaning the data to fill in the template :type settings: ~qmflows.Settings :parameter work_dir: Name of the Working folder :type work_dir: String :param wfn_restart_job: Path to *.wfn cp2k file use as restart file. :type wfn_restart_job: String :param cp2k_config: Parameters required by cp2k. :type cp2k_config: Dict :returns: ~qmflows.Settings """ # Input/Output Files file_MO = join(work_dir, 'mo_coeffs.out') # create Settings for the Cp2K Jobs cp2k_args = Settings() cp2k_args.basis = "DZVP-MOLOPT-SR-GTH" cp2k_args.potential = "GTH-PBE" cp2k_args.cell_parameters = [12.74] * 3 dft = cp2k_args.specific.cp2k.force_eval.dft dft.scf.added_mos = 20 dft.scf.eps_scf = 1e-3 dft["print"]["mo"]["mo_index_range"] = "7 46" dft.scf.diagonalization.jacobi_threshold = 1e-5 # Atom basis cp2k_args.specific.cp2k.force_eval.subsys.kind["C"]["BASIS_SET"] = "DZVP-MOLOPT-SR-GTH-q4" cp2k_args.specific.cp2k.force_eval.subsys.kind["C"]["POTENTIAL"] = "GTH-PBE-q4" cp2k_args.specific.cp2k.force_eval.subsys.kind["H"]["BASIS_SET"] = "DZVP-MOLOPT-SR-GTH-q1" cp2k_args.specific.cp2k.force_eval.subsys.kind["H"]["POTENTIAL"] = "GTH-PBE-q1" # Functional # cp2k_args.specific.cp2k.force_eval.dft.xc["xc_functional"]["pbe"]["scale_x"] = 0.75 # cp2k_args.specific.cp2k.force_eval.dft.xc["xc_functional"]["pbe"]["scale_c"] = 1.0 # copy the basis and potential to a tmp file for f in ['BASIS_MOLOPT', 'GTH_POTENTIALS', 'BASIS_ADMM_MOLOPT']: shutil.copy(join('test/test_files', f), work_dir) # Cp2k configuration files force = cp2k_args.specific.cp2k.force_eval force.dft.basis_set_file_name = join(work_dir, 'BASIS_MOLOPT') force.dft.Basis_set_file_name = join(work_dir, 'BASIS_ADMM_MOLOPT') force.dft.potential_file_name = join(work_dir, 'GTH_POTENTIALS') force.dft['print']['mo']['filename'] = file_MO cp2k_args.specific.cp2k['global']['project'] = 'ethylene' return templates.singlepoint.overlay(cp2k_args)
def main(): # Current Work Directory cwd = os.getcwd() # ========== Fill in the following variables # Varaible to define the Path ehere the Cp2K jobs will be computed scratch = "/path/to/scratch" project_name = 'My_awesome_project' # name use to create folders # Path to the basis set used by Cp2k basisCP2K = "/Path/to/CP2K/BASIS_MOLOPT" potCP2K = "/Path/to/CP2K/GTH_POTENTIALS" path_to_trajectory = 'Path/to/trajectory/in/XYZ' # Number of MO used to compute the coupling nHOMO = None couplings_range = None # Basis basis = "DZVP-MOLOPT-SR-GTH" # Algorithm to compute the NAC algorithm = 'levine' # Integation step used for the dynamics (femtoseconds) dt = 1 # ============== End of User definitions =================================== cp2k_args = Settings() cp2k_args.basis = basis # Results folder results_dir = join(cwd, 'total_results') if not os.path.exists(results_dir): os.mkdir(results_dir) # Merge all the HDF5 files file_hdf5 = merge_hdf5(scratch, project_name, cwd, results_dir) # compute missing couplings script_name = "merge_data.py" write_python_script(scratch, 'total_results', path_to_trajectory, project_name, basisCP2K, potCP2K, cp2k_args, Settings(), 0, script_name, file_hdf5, nHOMO, couplings_range, algorithm, dt) # Script using SLURM write_slurm_script(scratch, results_dir, script_name)
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 cp2k_input( range_orbitals, cell_parameters, cell_angles, added_mos, basis="DZVP-MOLOPT-SR-GTH", potential="GTH-PBE"): """ # create ``Settings`` for the Cp2K Jobs. """ # Main Cp2k Jobs cp2k_args = Settings() cp2k_args.basis = fun_format(basis) cp2k_args.potential = fun_format(potential) cp2k_args.cell_parameters = cell_parameters cp2k_args.cell_angles = cell_angles main_dft = cp2k_args.specific.cp2k.force_eval.dft main_dft.scf.added_mos = added_mos main_dft.scf.max_scf = 40 main_dft.scf.eps_scf = 5e-4 main_dft['print']['mo']['mo_index_range'] = '"{} {}"'.format(*range_orbitals) cp2k_args.specific.cp2k.force_eval.subsys.cell.periodic = fun_format('None') # Setting to calculate the wave function used as guess cp2k_OT = Settings() cp2k_OT.basis = fun_format(basis) cp2k_OT.potential = fun_format(potential) cp2k_OT.cell_parameters = cell_parameters cp2k_OT.cell_angles = cell_angles ot_dft = cp2k_OT.specific.cp2k.force_eval.dft ot_dft.scf.scf_guess = fun_format('atomic') ot_dft.scf.ot.minimizer = fun_format('DIIS') ot_dft.scf.ot.n_diis = 7 ot_dft.scf.ot.preconditioner = fun_format('FULL_SINGLE_INVERSE') ot_dft.scf.added_mos = 0 ot_dft.scf.eps_scf = 1e-06 ot_dft.scf.scf_guess = fun_format('restart') cp2k_OT.specific.cp2k.force_eval.subsys.cell.periodic = fun_format('None') return cp2k_args, cp2k_OT
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 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
'methylthiophene': 'CC1=C(C=CS1)C#C' } # transform the string into a format understandable by Qmflows molecules = {name: from_smiles(smile) for name, smile in smiles.items()} # Used DFTB to optimize the geometries dftb_jobs = { name: dftb(templates.geometry, mol, job_name='dftb_{}'.format(name)) for name, mol in molecules.items() } optimized_mols = {name: job.molecule for name, job in dftb_jobs.items()} # Settings for ADF SAOP single point calculation s = Settings() s.basis = 'DZP' s.specific.adf.basis.core = None s.specific.adf.xc.model = 'saop' s.specific.adf.scf.converge = 1e-6 s.specific.adf.symmetry = 'nosym' # single point calculations using the SAOP functional singlepoints = [ adf(s, mol, job_name='adf_{}'.format(name)) for name, mol in optimized_mols.items() ] # Filter results with H**O-LUMO gap lower than 3 eV candidates = filter_homo_lumo_lower_than(gather(*singlepoints), 3) # Optimize the selected candidates
def bond_distance(r1, r2): return sqrt(sum((x - y)**2 for x, y in zip(r1, r2))) # ========== ============= plams.init() # Read the Molecule from file cnc = Molecule('C-N-C.mol', 'mol') # User define Settings settings = Settings() settings.functional = "pbe" settings.basis = "TZ2P" settings.specific.dftb.dftb.scc constraint1 = "dist 1 5" constraint2 = "dist 3 4" # scan input scan = { 'constraint': [constraint1, constraint2], 'surface': { 'nsteps': 6, 'start': [2.3, 2.3], 'stepsize': [0.1, 0.1] } }
# ========== ============= def bond_distance(r1, r2): return sqrt(sum((x - y)**2 for x, y in zip(r1, r2))) # ========== ============= # Read the Molecule from file cnc = Molecule('C-N-C.mol', 'mol') # User define Settings settings = Settings() settings.functional = "pbe" settings.basis = "SZ" settings.specific.dftb.dftb.scc constraint1 = Distance(0, 4) constraint2 = Distance(2, 3) # 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