def run_job(settings, mol, job_name='gamess_job', work_dir=None): """ Call the Cp2K binary using plams interface. :param settings: Job Settings. :type settings: :class:`~qmflows.Settings` :param mol: molecular Geometry :type mol: plams Molecule :param input_file_name: Optional name for the input. :type input_file_name: String :param out_file_name: Optional name for the output. :type out_file_name: String :return: Package.Result """ gamess_settings = Settings() gamess_settings.input = settings.specific.gamess job = plams.interfaces.gamess.GamessJob(molecule=mol, name=job_name, settings=gamess_settings) r = job.run() # Relative job path relative_plams_path = '/'.join(r.job.path.split('/')[-2:]) result = Gamess_Result(gamess_settings, mol, r.job.name, plams_dir=relative_plams_path, work_dir=work_dir, status=job.status) return result
def process_input(input_file: str, workflow_name: str) -> Dict: """ Read the `input_file` in YAML format, validate it against the corresponding `workflow_name` schema and return a nested dictionary with the input. :param str input_file: path to the input :return: Input as dictionary :raise SchemaError: If the input is not valid """ schema = schema_workflows[workflow_name] with open(input_file, 'r') as f: dict_input = yaml.load(f.read()) try: d = schema.validate(dict_input) # Convert cp2k definitions to settings d['general_settings']['settings_main'] = Settings( d['general_settings']['settings_main']) d['general_settings']['settings_guess'] = Settings( d['general_settings']['settings_guess']) return d except SchemaError as e: msg = "There was an error in the input provided:\n{}".format(e) raise RuntimeError(msg)
def get_constraint_settings(self, step): s = Settings() if isinstance(self.constraints, list): for c in range(len(self.constraints)): s.constraint.update( self.constraints[c].get_settings(self.start[c] + self.stepsize[c] * step)) else: s.constraint = self.constraints.get_settings(self.start + self.stepsize * step) return s
def run_job(settings, mol, job_name="dirac_job"): dirac_settings = Settings() dirac_settings.input = settings.specific.dirac dirac_settings.ignore_molecule job = plams.interfaces.thirdparty.dirac.DiracJob( name=job_name, settings=dirac_settings, molecule=mol) result = job.run() # Relative job path relative_plams_path = '/'.join(result.job.path.split('/')[-2:]) return DIRAC_Result(dirac_settings, mol, result.job.name, plams_dir=relative_plams_path, status=job.status)
def run_job(settings, mol, job_name='cp2k_job', work_dir=None, **kwargs): """ Call the Cp2K binary using plams interface. :param settings: Job Settings. :type settings: :class:`~qmflows.Settings` :param mol: molecular Geometry :type mol: plams Molecule :param hdf5_file: Path to the HDF5 file that contains the numerical results. :type hdf5_file: String :param input_file_name: Optional name for the input. :type input_file_name: String :param out_file_name: Optional name for the output. :type out_file_name: String :param store_in_hdf5: wether to store the output arrays in HDF5 format. :type store_in_hdf5: Bool """ # Yet another work directory # Input modifications cp2k_settings = Settings() cp2k_settings.input = settings.specific.cp2k # Add molecular coordinates m = format_coord_xyz(mol) + '{:>8}'.format('&END') cp2k_settings.input.force_eval.subsys['&COORD'] = m # Create a Plams job job = plams.interfaces.thirdparty.cp2k.Cp2kJob(name=job_name, settings=cp2k_settings, molecule=mol) r = job.run() work_dir = work_dir if work_dir is not None else job.path warnings = parse_output_warnings(job_name, r.job.path, parse_cp2k_warnings, cp2k_warnings) result = CP2K_Result(cp2k_settings, mol, job_name, r.job.path, work_dir, status=job.status, warnings=warnings) return result
def freeze(): if not isinstance(value, list): msg = 'selected_atoms ' + str(value) + ' is not a list' raise RuntimeError(msg) sel_coords = [] if isinstance(value[0], int): for v in value: a = v - 1 sel_coords += [str(i) for i in range(a * 3 + 1, a * 3 + 4)] else: for a in range(len(mol)): if mol[a + 1].symbol in value: sel_coords += [ str(i) for i in range(a * 3 + 1, a * 3 + 4) ] ifreez = Settings() ifreez.statpt = "IFREEZ(1)=" + ",".join(sel_coords) settings.specific.gamess.update(ifreez)
def run_job(settings, mol, job_name='DFTBjob', nproc=None): """ Execute an DFTB job with the *ADF* quantum package. :param settings: user input settings. :type settings: |Settings| :param mol: Molecule to run the simulation :type mol: Plams Molecule :parameter input_file_name: The user can provide a name for the job input. :type input_file_name: String :parameter out_file_name: The user can provide a name for the job output. :type out_file_name: String :returns: :class:`~qmflows.packages.SCM.DFTB_Result` """ dftb_settings = Settings() if nproc: dftb_settings.runscript.nproc = nproc dftb_settings.input = settings.specific.dftb job = plams.DFTBJob(name=job_name, molecule=mol, settings=dftb_settings) # Check RKF status try: result = job.run() name = result.job.name path = result.job.path except struct.error: job.status = 'failed' name = job_name path = None msg = "job:{} has failed.\nRKF is corrupted" print(msg.format(job_name)) if job.status in ['failed', 'crashed']: builtins.config.jm.remove_job(job) return DFTB_Result(dftb_settings, mol, name, plams_dir=path, status=job.status)
def create_settings(d: Dict) -> Dict: """ Transform the input dict into Cp2K settings. :param d: input dict :return: dictionary with Settings to call Cp2k """ # Convert cp2k definitions to settings general = d['cp2k_general_settings'] general['cp2k_settings_main'] = Settings(general['cp2k_settings_main']) general['cp2k_settings_guess'] = Settings(general['cp2k_settings_guess']) apply_templates(general, d['path_traj_xyz']) input_parameters = add_missing_keywords(d) print_final_input(input_parameters) return input_parameters
def generate_kinds(elements: Iterable[str], basis: str, potential: str) -> Settings: """Generate the kind section for cp2k basis.""" s = Settings() subsys = s.cp2k.force_eval.subsys for e in elements: q = valence_electrons['-'.join((e, basis))] subsys.kind[e]['basis_set'] = [f"{basis}-q{q}"] subsys.kind[e]['potential'] = f"{potential}-q{q}" return s
def get_settings(self, value=None, mol=None): s = Settings() if value is None: if mol is None: msg = 'Distance constraint settings requires a value or molecule' raise RuntimeError(msg) else: value = self.get_current_value(mol) s["dist {:d} {:d}".format(self.atom1, self.atom2)] = value return s
def run_job(settings, mol, job_name="ORCAjob", work_dir=None, **kwargs): orca_settings = Settings() orca_settings.input = settings.specific.orca # Running Orca with Plams job = plams.interfaces.orca.ORCAJob(molecule=mol, settings=orca_settings, name=job_name) result = job.run() # Relative job path relative_plams_path = '/'.join(result.job.path.split('/')[-2:]) return ORCA_Result(orca_settings, mol, result.job.name, plams_dir=relative_plams_path, status=job.status)
def generic2specific(self, settings, mol=None): """ Traverse all the key, value pairs of the ``settings``, translating the generic keys into package specific keys as defined in the specific dictionary. If one key is not in the specific dictionary an error is raised. These new specific settings take preference over existing specific settings. :parameter settings: Settings provided by the user. :type settings: Settings :parameter mol: Molecule to run the calculation. :type mol: plams Molecule """ generic_dict = self.get_generic_dict() specific_from_generic_settings = Settings() for k, v in settings.items(): if k != "specific": key = generic_dict.get(k) if key: if isinstance(key, list): if isinstance(key[1], dict): value = key[1][v] else: value = {key[1]: v} if value: v = value key = key[0] if v: if isinstance(v, dict): v = Settings(v) specific_from_generic_settings \ .specific[self.pkg_name][key] = v else: specific_from_generic_settings \ .specific[self.pkg_name][key] else: self.handle_special_keywords( specific_from_generic_settings, k, v, mol) return settings.overlay(specific_from_generic_settings)
def get_settings(self, value=None, mol=None): s = Settings() if value is None: if mol is None: msg = 'Dihedral constraint settings requires a value or molecule' raise RuntimeError(msg) else: value = self.get_current_value(mol) key = "dihed {:d} {:d} {:d} {:d}".format(self.atom1, self.atom2, self.atom3, self.atom4) s[key] = value return s
def get_settings(self, value=None, mol=None): s = Settings() if value is None and mol is None: msg = 'coordinate constraint settings requires a value or molecule' raise RuntimeError(msg) elif value is None: value = self.get_current_value(mol) # create settings entry data = self.fmt.format(*self.atoms) s[data] = value return s
def dict2Setting(d): """ Transform recursively a dict into a Settings object. """ r = Settings() for k, v in d.items(): if isinstance(v, dict): r[k] = dict2Setting(v) else: r[k] = v return r
def run_job(settings, mol, job_name='ADFjob', nproc=None): """ Execute ADF job. :param settings: user input settings. :type settings: |Settings| :param mol: Molecule to run the simulation :type mol: Plams Molecule :parameter input_file_name: The user can provide a name for the job input. :type input_file_name: String :parameter out_file_name: The user can provide a name for the job output. :type out_file_name: String :returns: :class:`~qmflows.packages.SCM.ADF_Result` """ adf_settings = Settings() if nproc: adf_settings.runscript.nproc = nproc adf_settings.input = settings.specific.adf job = plams.ADFJob(name=job_name, molecule=mol, settings=adf_settings) result = job.run() # Path to the tape 21 file path_t21 = result._kf.path # Relative path to the CWD relative_path_t21 = '/'.join(path_t21.split('/')[-3:]) # Relative job path relative_plams_path = '/'.join(result.job.path.split('/')[-2:]) adf_result = ADF_Result(adf_settings, mol, result.job.name, relative_path_t21, plams_dir=relative_plams_path, status=job.status) return adf_result
def create_settings_from_template( general: Dict[str, Any], template_name: str, path_traj_xyz: PathLike) -> Settings: """Create a job Settings using the name provided by the user.""" setts = templates_dict[template_name] elements = read_unique_atomic_labels(path_traj_xyz) kinds = generate_kinds(elements, general['basis'], general['potential']) if 'pbe0' in template_name: s = Settings() return generate_auxiliar_basis(setts + s + kinds, general['basis'], general['aux_fit']) elif 'hse06' in template_name: return generate_auxiliar_basis(setts + kinds, general['basis'], general['aux_fit']) else: return setts + kinds
def constraint(): if isinstance(value, Settings): s = Settings() if len(mol) == 2: degr = 1 # s['izmat(1)'] = '1,1,2' else: degr = 3 * len(mol) - 6 s.auto = ".TRUE." s.dlc = ".TRUE." settings.specific.gamess.contrl.nzvar = degr i = 1 for k, v in value.items(): ks = k.split() # print('--->', ks, type(ks[2]), type(value), v) if ks[0] == 'dist' and len(ks) == 3: n = 'ifzmat({:d})'.format(i) s[n] = "1,{},{}".format(int(ks[1]), int(ks[2])) n = 'fvalue({:d})'.format(i) s[n] = v elif ks[0] == 'angle' and len(ks) == 4: n = 'ifzmat({:d})'.format(i) s[n] = "2,{},{},{}".format(int(ks[1]), int(ks[2]), int(ks[3])) n = 'fvalue({:d})'.format(i) s[n] = v elif ks[0] == 'dihed' and len(ks) == 5: n = 'ifzmat({:d})'.format(i) s[n] = "3,{},{},{},{}".format(int(ks[1]), int(ks[2]), int(ks[3]), int(ks[4])) n = 'fvalue({:d})'.format(i) s[n] = v else: warn('Invalid constraint key: ' + k) i += 1 settings.specific.gamess.zmat = s
def extract_properties_rkf(path_rkf, key=None, subkey=None): """ Read result from a DFTB computation using the job_name.rkf file. """ kf = plams.tools.kftools.KFFile(path_rkf).read props = Settings() for i in range(kf('Properties', 'nEntries')): typ = kf('Properties', 'Type(' + str(i + 1) + ')').strip() subtype = kf('Properties', 'Subtype(' + str(i + 1) + ')').strip() value = kf('Properties', 'Value(' + str(i + 1) + ')') props[typ][subtype] = value ret = props[key][subkey] if isinstance(ret, list): ret = np.array(ret) return ret
def create_settings_from_template(general: dict, template_name: str, path_traj_xyz: str) -> Settings: """ Create a job Settings using the name provided by the user """ setts = templates_dict[template_name] elements = read_unique_atomic_labels(path_traj_xyz) kinds = generate_kinds(elements, general['basis'], general['potential']) if 'pbe0' in template_name: s = Settings() s.cp2k.force_eval.dft.xc.hf.interaction_potential.t_c_g_data = os.path.abspath( join(general['path_basis'], "t_c_g.dat")) return generate_auxiliar_basis(setts + s + kinds, general['basis'], general['aux_fit']) elif 'hse06' in template_name: return generate_auxiliar_basis(setts + kinds, general['basis'], general['aux_fit']) else: return setts + kinds
def adf_fragmentsjob(settings, frags, caps=None, fragment_settings=None, job_name='fde'): mol_tot = Molecule() frag_settings = Settings() cap_ids = {} if caps: for i, cap in enumerate(caps): cap_id = 'cap' + str(i + 1) for a in cap.mol: cap_ids[a.coords] = cap_id path = cap.result.kf.path key = cap_id + ' ' + path + ' type=FDEsubstract &' frag_settings.specific.adf.fragments[key] = fragment_settings for i, frag in enumerate(frags): frag_id = 'frag' + str(i + 1) if frag.result: for a in frag.mol: a.properties.adf.fragment = frag_id if a.coords in cap_ids: a.properties.adf.fragment += ' fs=' + cap_ids[a.coords] path = frag.result.kf.path key = frag_id + ' ' + path + ' subfrag=active' if frag.isfrozen: key += ' type=FDE' if fragment_settings: key += ' &' frag_settings.specific.adf.fragments[ key] = fragment_settings else: frag_settings.specific.adf.fragments[key] = "" else: frag_settings.specific.adf.fragments[key] = "" mol_tot += frag.mol frag_settings.specific.adf.fde.PW91k = "" return adf(settings.overlay(frag_settings), mol_tot, job_name=job_name)
def decode(self, cls, data): return Settings(data)
singlepoint = Settings( yaml.load(""" specific: adf: basis: type: SZ xc: __block_replace: true lda: "" numericalquality: normal scf: converge: 1e-6 iterations: 100 ams: ams: Task: SinglePoint dftb: dftb: resourcesdir: "DFTB.org/3ob-3-1" task: runtype: SP cp2k: force_eval: dft: mgrid: cutoff: 400 ngrids: 4 print: mo: add_last: numeric each: qs_scf: 0 eigenvalues: "" eigenvectors: "" filename: "./mo.data" ndigits: 36 occupation_numbers: "" qs: method: gpw scf: eps_scf: 1e-06 max_scf: 200 scf_guess: restart subsys: cell: periodic: xyz global: print_level: low project: cp2k run_type: energy dirac: DIRAC: WAVEFUNCTION HAMILTONIAN: "LEVY-LEBLOND" WAVE FUNCTION: SCF gamess: basis: gbasis: sto ngauss: 3 contrl: scftyp: rhf dfttyp: pbe orca: method: method: dft functional: lda basis: basis: sto_sz """, Loader=yaml.FullLoader))
cfit = aux_fit[atom][index] kind[atom]["BASIS_SET"] = "AUX_FIT " + f"CFIT{cfit}" return sett cp2k_pbe_guess = Settings( yaml.load(""" cp2k: force_eval: subsys: cell: periodic: "None" dft: xc: xc_functional pbe: {} scf: eps_scf: 1e-6 added_mos: 0 scf_guess: "restart" ot: minimizer: "DIIS" n_diis: 7 preconditioner: "FULL_SINGLE_INVERSE" """, Loader=yaml.FullLoader)) cp2k_pbe_main = Settings( yaml.load(""" cp2k: force_eval: subsys:
def create_settings(self) -> None: """Transform the CP2K input dict into :class:`QMFLows.Settings`.""" self.general['cp2k_settings_main'] = Settings( self.general['cp2k_settings_main']) self.general['cp2k_settings_guess'] = Settings( self.general['cp2k_settings_guess'])