From 1d5687fc61b5313e67dfd55d3ed9704f7cbe35d2 Mon Sep 17 00:00:00 2001 From: gmatteo Date: Thu, 7 Sep 2023 13:53:53 +0200 Subject: [PATCH] Add get_oncvpsp_pseudos API --- abipy/dfpt/tests/test_msqdos.py | 2 +- abipy/flowtk/psrepos.py | 47 ++++-------- abipy/ml/aseml.py | 127 +++++++++++++++----------------- abipy/ml/ml_relax.py | 18 +---- abipy/scripts/abiml.py | 16 ++-- dev_scripts/mlrun.py | 10 ++- 6 files changed, 94 insertions(+), 126 deletions(-) diff --git a/abipy/dfpt/tests/test_msqdos.py b/abipy/dfpt/tests/test_msqdos.py index d4d1da79c..a2fe9373a 100644 --- a/abipy/dfpt/tests/test_msqdos.py +++ b/abipy/dfpt/tests/test_msqdos.py @@ -16,7 +16,7 @@ def test_from_ddb(self): filepath = os.path.join(abidata.dirpath, "refs", "mp-7000_DDB.bz2") with abilab.abiopen(filepath) as ddb: - phbst_file, phdos_file = ddb.anaget_phbst_and_phdos_files(nqsmall=2, ndivsm=1, mpi_procs=2) + phbst_file, phdos_file = ddb.anaget_phbst_and_phdos_files(nqsmall=2, ndivsm=1, mpi_procs=1) msqd_dos = phdos_file.msqd_dos # Read indsym from file and convert from F to C indsym = phdos_file.reader.read_value("indsym") diff --git a/abipy/flowtk/psrepos.py b/abipy/flowtk/psrepos.py index 92a76b14e..8ce6054ae 100644 --- a/abipy/flowtk/psrepos.py +++ b/abipy/flowtk/psrepos.py @@ -139,38 +139,20 @@ def get_repo_from_name(repo_name: str) -> PseudosRepo: raise KeyError(f"Couldn't find {repo_name} in the list of registered repos:\n{all_names}") -#def get_latest_pseudos(xc_name: str, ps_type: str = "NC", relativity_type: str = "SR", accuracy: str = "standard") -> PseudoTable: -# """ -# Args: -# xc_name: -# ps_type: -# relativity_type -# accuracy: -# """ -# if ps_type == "NC": -# version = "0.4" -# ps_generator, project_name = OncvpspRepo.ps_generator, OncvpspRepo.project_name -# repo_name = f"{ps_generator}-{xc_name}-{relativity_type}-{project_name}v{version}" -# #if relativity_type == "SR": -# # repo_name = { -# # "PBE": "ONCVPSP-PBE-SR-PDv0.4", -# # "PBEsol": "ONCVPSP-PBEsol-SR-PDv0.4", -# # "LDA": "ONCVPSP-LDA-SR-PDv0.4", -# # }[xc_name] -# #else -# # repo_name = { -# # "PBE": "ONCVPSP-PBE-FR-PDv0.4", -# # "PBEsol": "ONCVPSP-PBEsol-FR-PDv0.4", -# # "LDA": "ONCVPSP-LDA-FR-PDv0.4", -# # }[xc_name] -# -# elif ps_type == "PAW": -# raise NotImplementedError(f"Invalid {ps_type=}") -# -# else: -# raise ValueError(f"Invalid {ps_type=}") -# -# return get_repo_from_name(repo_name).get_pseudos(accuracy) +def get_oncvpsp_pseudos(xc_name: str, version: str, relativity_type: str = "SR", accuracy: str = "standard") -> PseudoTable: + """ + High-level API that returns a PseudoTable of ONCVPSP pseudos for a given xc functional and version. + + Args: + xc_name: Name of the XC functional. + version: Version string e.g. "0.4". + relativity_type: SR for scalar-relativistic, FR for fully-relativistic with SOC. + accuracy: "standard" or "stringent". + """ + ps_generator, project_name = OncvpspRepo.ps_generator, OncvpspRepo.project_name + repo_name = f"{ps_generator}-{xc_name}-{relativity_type}-{project_name}v{version}" + + return get_repo_from_name(repo_name).get_pseudos(accuracy) def get_installed_repos_and_root(dirpath: Optional[str] = None) -> tuple[list[PseudosRepo], str]: @@ -178,6 +160,7 @@ def get_installed_repos_and_root(dirpath: Optional[str] = None) -> tuple[list[Ps Return (all_repos, dirpath) """ dirpath = REPOS_ROOT if not dirpath else dirpath + if not os.path.exists(dirpath): os.makedirs(dirpath) dir_basenames = [name for name in os.listdir(dirpath) if os.path.isdir(os.path.join(dirpath, name))] dirname2repo = {repo.name: repo for repo in _ALL_REPOS} return [dirname2repo[dirname] for dirname in dir_basenames if dirname in dirname2repo], dirpath diff --git a/abipy/ml/aseml.py b/abipy/ml/aseml.py index eaef855fa..86547f947 100644 --- a/abipy/ml/aseml.py +++ b/abipy/ml/aseml.py @@ -1015,7 +1015,7 @@ def store_abi_forstr_atoms(self, abi_forces, abi_stress, atoms): Stores a copy of the ab-initio forces, stress tensor and atoms in the internal buffers. Also compute and store the corresponding ML values. """ - # Store copies. + # Store copies in internal buffers. abi_forces = np.asarray(abi_forces).copy() self.__abi_forces_list.append(abi_forces) abi_stress = np.asarray(abi_stress).copy() @@ -1047,25 +1047,15 @@ def fmt_vec6(vec6) -> str: print(f"abi_fcart_{iat=}:", fmt_vec3(abi_forces[iat])) print(f"ml_fcart_{iat=} :", fmt_vec3(ml_forces[iat])) - def get_abi_forces(self, pos=-1): - """Return the ab-initio forces or None if not available.""" - if self.__abi_forces_list: return self.__abi_forces_list[pos] - return None + def get_abi_ml_forces(self, pos=-1): + """Return the ab-initio and the ML forces or (None, None) if not available.""" + if not self.__abi_forces_list: return (None, None) + return self.__abi_forces_list[pos], self.__ml_forces_list[pos] - def get_ml_forces(self, pos=-1): - """Return the ML forces or None if not available.""" - if self.__ml_forces_list: return self.__ml_forces_list[pos] - return None - - def get_abi_stress(self, pos=-1): - """Return the ab-initio stress or None if not available.""" - if self.__abi_stress_list: return self.__abi_stress_list[pos] - return None - - def get_ml_stress(self, pos=-1): - """Return the ML stress or None if not available.""" - if self.__ml_stress_list: return self.__ml_stress_list[pos] - return None + def get_abi_ml_stress(self, pos=-1): + """Return the ab-initio and the ML stress or (None, None) if not available.""" + if not self.__abi_stress_list: return (None, None) + return self.__abi_stress_list[pos], self.__ml_stress_list[pos] def calculate( self, @@ -1087,39 +1077,37 @@ def calculate( super().calculate(atoms=atoms, properties=properties, system_changes=system_changes) if self.correct_forces_algo != CORRALGO.none: - # Apply ab-initio correction to the ml_forces. + if self.__verbose: print(f"Applying ab-initio correction to the ml_forces with {self.correct_forces_algo=}" forces = self.results["forces"] - abi_forces = self.get_abi_forces() - ml_forces = self.get_ml_forces() + abi_forces, ml_forces = self.get_abi_ml_forces() if abi_forces is not None: # Change forces only if have invoked store_abi_forstr_atoms if self.correct_forces_algo == CORRALGO.delta: - # Apply delta correction to forces. delta_forces = abi_forces - ml_forces + if self.__verbose > 1: print("Updating forces with delta_forces:\n", abi_forces) forces += delta_forces elif self.correct_forces_algo == CORRALGO.one_point: forces += abi_forces else: raise ValueError(f"Invalid {self.correct_forces_algo=}") - #print("Updating forces with abi_forces:\n", abi_forces) + self.results.update(forces=forces) if self.correct_stress_algo != CORRALGO.none: - # Apply ab-initio correction to the ml_stress. + if self.__verbose: print(f"Applying ab-initio correction to the ml_stress with {self.correct_stress_algo=}" stress = self.results["stress"] - abi_stress = self.get_abi_stress() - ml_stress = self.get_ml_stress() + abi_stress, ml_stress = self.get_abi_ml_stress() if abi_stress is not None: # Change stresses only if have invoked store_abi_forstr_atoms if self.correct_stress_algo == CORRALGO.delta: # Apply delta correction to stress. delta_stress = abi_stress - ml_stress + if self.__verbose > 1: print("Updating stress with delta_stress:\n", delta_stress) stress += delta_stress elif self.correct_stress_algo == CORRALGO.one_point: stress += abi_stress else: raise ValueError(f"Invalid {self.correct_stress_algo=}") - #print("Updating stress with abi_stress:\n", abi_stress) self.results.update(stress=stress) @@ -1183,10 +1171,10 @@ def reset(self) -> None: def get_calculator(self, reset=False) -> Calculator: """ - Return ASE calculator with ML potential. + Return an ASE calculator with ML potential. Args: - reset: True if internal cache should be reset. + reset: True if the internal cache should be reset. """ if reset: self.reset() @@ -1301,17 +1289,17 @@ def __str__(self): # Delegated to the subclass. return self.to_string() - @lazy_property - def calc_builder(self): - return CalcBuilder(self.nn_name) + #@lazy_property + #def calc_builder(self): + # return CalcBuilder(self.nn_name) - def get_calculator_name(self) -> tuple[Calculator, str]: - return self.get_calculator(), self.calc_builder.name + #def get_calculator_name(self) -> tuple[Calculator, str]: + # return self.get_calculator(), self.calc_builder.name - def get_calculator(self) -> Calculator: - """Return ASE calculator.""" - calc = self.calc_builder.get_calculator() - return calc + #def get_calculator(self) -> Calculator: + # """Return ASE calculator.""" + # calc = self.calc_builder.get_calculator() + # return calc def add_basename_info(self, basename: str, info: str) -> None: """ @@ -1604,7 +1592,7 @@ def run(self): """Run structural relaxation.""" #self.pickle_dump() workdir = self.workdir - self.atoms.calc = self.get_calculator() + self.atoms.calc = CalcBuilder(self.nn_name).get_calculator() # TODO: Here I should add the ab-initio forces/stress to the calculator to correct the ML ones print(f"Relaxing structure with relax mode: {self.relax_mode} ...") @@ -1676,7 +1664,7 @@ def to_string(self, verbose=0) -> str: steps = {self.steps} loginterval = {self.loginterval} ensemble = {self.ensemble} - calculator = {self.calc_builder} + nn_name = {self.nn_name} workdir = {self.workdir} verbose = {self.verbose} @@ -1690,7 +1678,7 @@ def run(self) -> None: """Run MD""" #self.pickle_dump() workdir = self.workdir - self.atoms.calc = self.get_calculator() + self.atoms.calc = CalcBuilder(self.nn_name).get_calculator() traj_file = self.get_path("md.traj", "ASE MD trajectory") logfile = self.get_path("md.log", "ASE MD log file") @@ -1785,6 +1773,7 @@ def read_neb_data(self) -> dict: return json.load(fh) + class MlGsList(_MlNebBase): """ Perform ground-state calculations for a list of atoms with ASE and ML-potential. @@ -1822,9 +1811,10 @@ def run(self) -> None: workdir = self.workdir results = [] + calc = CalcBuilder(self.nn_name).get_calculator() for ind, atoms in enumerate(self.atoms_list): write_vasp(self.workdir / f"IND_{ind}_POSCAR", atoms, label=None) - atoms.calc = self.get_calculator() + atoms.calc = calc results.append(AseResults.from_atoms(atoms)) write_vasp_xdatcar(self.workdir / "XDATCAR", self.atoms_list, @@ -1914,9 +1904,10 @@ def run(self) -> None: #self.pickle_dump() workdir = self.workdir initial_atoms, final_atoms = self.initial_atoms, self.final_atoms + calculator = CalcBuilder(self.nn_name).get_calculator() if self.relax_mode != RX_MODE.no: - relax_kws = dict(calculator=self.get_calculator(), + relax_kws = dict(calculator=calculator, optimizer=self.optimizer, relax_mode=self.relax_mode, fmax=self.fmax, @@ -1939,7 +1930,7 @@ def run(self) -> None: relax.summarize(tags=["final_unrelaxed", "final_relaxed"]) # Generate several instances of the calculator. It is probably fine to have just one, but just in case... - calculators = [self.get_calculator() for i in range(self.nimages)] + calculators = [CalcBuilder(self.nn_name).get_calculator()) for i in range(self.nimages)] neb = make_ase_neb(initial_atoms, final_atoms, self.nimages, calculators, self.neb_method, self.climb, method='linear', mic=False) @@ -2228,9 +2219,11 @@ def run(self) -> None: for group in groups: print(group[0]) + calculator = CalcBuilder(self.nn_name).get_calculator() + if self.relax_mode != RX_MODE.no: print(f"Relaxing structures with relax mode: {self.relax_mode}") - relax_kws = dict(calculator=self.get_calculator(), + relax_kws = dict(calculator=calculator, optimizer=self.optimizer, relax_mode=self.relax_mode, fmax=self.fmax, @@ -2264,6 +2257,7 @@ def run(self) -> None: # TODO: Post-process self._finalize() + class MlCompareWithAbinitio(_MlNebBase): """ Compare ab-initio energies, forces and stresses with ML results. @@ -2273,7 +2267,7 @@ def __init__(self, filepaths, nn_names, traj_range, verbose, workdir, prefix=Non """ Args: filepaths: List of file produced by the ab-initio code with energies, forces and stresses. - nn_names: String or list of strings defining the NN potential. + nn_names: String or list of strings defining the NN potential. See also CalcBuilder. traj_range: Trajectory range. None to include all steps. verbose: Verbosity level. workdir: Working directory. @@ -2441,7 +2435,6 @@ def main(): class MolecularDynamics: """ Molecular dynamics class - Based on https://github.com/materialsvirtuallab/m3gnet/blob/main/m3gnet/models/_dynamics.py """ @@ -2594,14 +2587,14 @@ class MlAsePhonons(_MlBase): Compute phonons with ASE and ML potential. """ - def __init__(self, atoms: Atoms, supercell, kpts, asr, nqpath, + def __init__(self, atoms: Atoms, supercell, qmesh, asr, nqpath, relax_mode, fmax, pressure, steps, optimizer, nn_name, verbose, workdir, prefix=None): """ Args: atoms: ASE atoms. supercell: tuple with supercell dimension. - kpts: K-mesh for phonon-DOS + qmesh: K-mesh for phonon-DOS asr: Enforce acoustic sum-rule. nqpath: Number of q-point along the q-path. relax_mode: "ions" to relax ions only, "cell" for ions + cell, "no" for no relaxation. @@ -2616,7 +2609,7 @@ def __init__(self, atoms: Atoms, supercell, kpts, asr, nqpath, super().__init__(workdir, prefix) self.atoms = get_atoms(atoms) self.supercell = supercell - self.kpts = kpts + self.qmesh = qmesh self.asr = asr self.nqpath = nqpath self.relax_mode = relax_mode @@ -2635,7 +2628,7 @@ def to_string(self, verbose=0): {self.__class__.__name__} parameters: supercell = {self.supercell} - kpts = {self.kpts} + qmesh = {self.qmesh} asr = {self.asr} nqpath = {self.nqpath} relax_mode = {self.relax_mode} @@ -2657,7 +2650,7 @@ def run(self) -> None: """Run AseMlPhonons.""" #self.pickle_dump() workdir = self.workdir - calculator = self.get_calculator() + calculator = CalcBuilder(self.nn_name).get_calculator() self.atoms.calc = calculator if self.relax != RX_MODE.no: @@ -2690,7 +2683,7 @@ def run(self) -> None: # Calculate phonon dispersion along a path in the Brillouin zone. path = self.atoms.cell.bandpath(npoints=self.nqpath) bs = ph.get_band_structure(path, born=False) - dos = ph.get_dos(kpts=self.kpts).sample_grid(npts=100, width=1e-3) + dos = ph.get_dos(kpts=self.qmesh).sample_grid(npts=100, width=1e-3) # Plot the band structure and DOS import matplotlib.pyplot as plt @@ -2716,17 +2709,17 @@ def run(self) -> None: class MlPhononsWithDDB(_MlBase): """ - Compute phonons with phonopy and ML potential starting from a DDB file. + Compute phonons with phonopy and a set of ML potentials starting from a DDB file. """ - def __init__(self, ddb_filepath: str, supercell, kpts, asr, nqpath, + def __init__(self, ddb_filepath: str, supercell, qmesh, asr, nqpath, relax_mode, fmax, pressure, steps, optimizer, nn_name, verbose, workdir, prefix=None): """ Args: ddb_filepath: DDB filename. supercell: tuple with supercell dimension. - kpts: K-mesh for phonon-DOS + qmesh: q-mesh for phonon-DOS asr: Enforce acoustic sum-rule. nqpath: Number of q-point along the q-path. relax_mode: "ions" to relax ions only, "cell" for ions + cell, "no" for no relaxation. @@ -2741,9 +2734,9 @@ def __init__(self, ddb_filepath: str, supercell, kpts, asr, nqpath, super().__init__(workdir, prefix) from abipy.dfpt.ddb import DdbFile self.ddb = DdbFile(ddb_file) - self.atoms = get_atoms(ddb.structure) + self.initial_atoms = get_atoms(ddb.structure) self.supercell = supercell - self.kpts = kpts + self.qmesh = qmesh self.asr = asr self.nqpath = nqpath self.relax_mode = relax_mode @@ -2763,7 +2756,7 @@ def to_string(self, verbose=0): ddb_path = {self.ddb.filepath} supercell = {self.supercell} - kpts = {self.kpts} + qmesh = {self.qmesh} asr = {self.asr} nqpath = {self.nqpath} relax_mode = {self.relax_mode} @@ -2771,21 +2764,23 @@ def to_string(self, verbose=0): steps = {self.steps} optimizer = {self.optimizer} pressure = {self.pressure} - nn_name = {self.nn_name} + nn_names = {self.nn_names} workdir = {self.workdir} verbose = {self.verbose} === ATOMS === -{self.atoms} +{self.initial_atoms} """ return s def run(self) -> None: """Run MlPhononsWithDDB.""" workdir = self.workdir - calculator = self.get_calculator() - self.atoms.calc = calculator + + atoms = self.initial_atoms.copy() + calculator = CalcBuilder(self.nn_name).get_calculator() + atoms.calc = calculator if self.relax != RX_MODE.no: print(f"Relaxing DDB atoms with relax mode: {self.relax_mode}.") @@ -2798,7 +2793,7 @@ def run(self) -> None: verbose=self.verbose, ) - relax = relax_atoms(self.atoms, **relax_kws) + relax = relax_atoms(atoms, **relax_kws) r0, r1 = AseResults.from_traj_inds(relax.traj, 0, -1) df = dataframe_from_results_list(["DDB_initial", "DDB_relaxed"], [r0, r1]) print(df, end=2*"\n") @@ -2806,7 +2801,7 @@ def run(self) -> None: # Call phonopy to compute phonons with finite difference and ML potential. # Include non-analytical term if dipoles are available in the DDB file. if self.dbb.has_lo_to_data: - print("Activating dipolar term in phonopy calculation using BECS and Zeff from DDB") + print("Activating dipolar term in phonopy calculation using BECS and Zeff taken from DDB.") # Call anaddb to compute ab-initio phonon frequencies from the DDB. #self.ddb.anaget_phmodes_at_qpoints( diff --git a/abipy/ml/ml_relax.py b/abipy/ml/ml_relax.py index 7593e13e7..01c184a9a 100644 --- a/abipy/ml/ml_relax.py +++ b/abipy/ml/ml_relax.py @@ -228,15 +228,14 @@ def run(self, workdir=None, prefix=None): # Run fully ab-initio relaxation with abinit. abi_relax = self.abi_relax_atoms(workdir / "abinit_relax") - # Run relaxation with ASE optimizer and Abinit forces. if False: + # Run relaxation with ASE optimizer and Abinit forces. abiase_opt = self.abi_relax_atoms_with_ase(workdir / f"abiase_relax") # Compare structures diff = StructDiff(["INITIAL", "ABINIT_RELAX", self.nn_name + "_RELAX"], [self.initial_atoms, abi_relax.atoms, ml_opt.atoms]) diff.tabulate() - #raise RuntimeError() # Run hybrid relaxation (ML + abinit) ml_calc = CalcBuilder(self.nn_name).get_calculator() @@ -261,7 +260,6 @@ def run(self, workdir=None, prefix=None): gs = self.abinit_run_gs_atoms(directory, atoms) abiml_nsteps += 1 print("Iteration:", count, "abi_fmax:", gs.fmax, ", fmax:", self.fmax) - #if self.relax_mode == RX_MODE.cell: print("abinit_stress_voigt", gs.stress_voigt) #print_atoms(atoms, cart_forces=gs.forces) @@ -320,19 +318,9 @@ def run(self, workdir=None, prefix=None): if __name__ == "__main__": - from abipy.flowtk.psrepos import get_repo_from_name + from abipy.flowtk.psrepos import get_oncvpsp_pseudos xc_name = "PBE" - # Get pseudos - repo_name = { - "PBE": "ONCVPSP-PBE-SR-PDv0.4", - "PBEsol": "ONCVPSP-PBEsol-SR-PDv0.4", - "LDA": "ONCVPSP-LDA-SR-PDv0.4", - }[xc_name] - print(f"Using {repo_name=}") - pseudos = get_repo_from_name(repo_name).get_pseudos("standard") - #pseudos = get_nc_pseudos(xc_name=PBE) - - + pseudos = get_oncvpsp_pseudos(xc_name=xc_name, version="0.4") from ase.build import bulk atoms = bulk('Si') atoms.rattle(stdev=0.1, seed=42) diff --git a/abipy/scripts/abiml.py b/abipy/scripts/abiml.py index 2e3bb9007..0d347f28d 100755 --- a/abipy/scripts/abiml.py +++ b/abipy/scripts/abiml.py @@ -321,16 +321,16 @@ def mneb(ctx, filepaths, nn_name, @click.argument("filepath", type=str) @add_nn_name_opt @click.option("--supercell", "-s", nargs=3, type=int, default=(4, 4, 4), show_default=True, help="Supercell") -@click.option("--kpts", "-k", nargs=3, type=int, default=(4, 4, 4), show_default=True, help="K-mesh for phonon-DOS") +@click.option("--qmesh", "-k", nargs=3, type=int, default=(4, 4, 4), show_default=True, help="q-mesh for phonon-DOS") @click.option('--asr/--no-asr', default=True, show_default=True, - help="Restore the acoustic sum rule on the force constants.") + help="Restore the acoustic sum rule on the interatomic force constants.") @click.option('--nqpath', default=100, type=int, show_default=True, help="Number of q-points along the q-path") @add_relax_opts @add_workdir_verbose_opts -def aseph(ctx, filepath, nn_name, supercell, kpts, asr, nqpath, +def aseph(ctx, filepath, nn_name, supercell, qmesh, asr, nqpath, relax_mode, fmax, pressure, steps, optimizer, workdir, verbose): """ - Use ASE finite-displacement method to compute phonon band structure and DOS with ML potential. + Use finite-displacement method to compute phonon band structure and DOS with ASE and ML potential. Based on: @@ -339,7 +339,7 @@ def aseph(ctx, filepath, nn_name, supercell, kpts, asr, nqpath, Usage example: \b - abiml.py.py aseph FILE --supercell 4 4 4 --kpts 8 8 8 --relax no + abiml.py.py aseph FILE --supercell 4 4 4 --qmesh 8 8 8 --relax no where `FILE` is any file supported by abipy/pymatgen e.g. netcdf files, Abinit input, POSCAR, xsf, etc. @@ -347,9 +347,9 @@ def aseph(ctx, filepath, nn_name, supercell, kpts, asr, nqpath, abiml.py.py aseph -nn m3gnet [...] """ - ml_aseph = aseml.MlAsePhonons(filepath, supercell, kpts, asr, nqpath, - relax_mode, fmax, pressure, steps, optimizer, nn_name, - verbose, workdir, prefix="_aseph_") + ml_aseph = aseml.MlAsePhonons(filepath, supercell, qmesh, asr, nqpath, + relax_mode, fmax, pressure, steps, optimizer, nn_name, + verbose, workdir, prefix="_aseph_") print(ml_aseph.to_string(verbose=verbose)) ml_aseph.run() return 0 diff --git a/dev_scripts/mlrun.py b/dev_scripts/mlrun.py index 4aab4b908..a058849fd 100755 --- a/dev_scripts/mlrun.py +++ b/dev_scripts/mlrun.py @@ -56,13 +56,13 @@ def add_workdir_verbose_opts(f): @click.option("--rattle", default=0.0, type=float, show_default=True, help="Displace atoms randomly with stdev.") @click.option("-sv", "--scale-volume", default=1.0, type=float, show_default=True, help="Scale input volume.") @click.option("-n","--mpi-nprocs", default=2, type=int, show_default=True, help="Number of MPI processes to run ABINIT") -@click.option("-xc", default="PBE", show_default=True, type=click.Choice(["PBE", "PBEsol", "LDA"]), +@click.option("-xc", "--xc-name", default="PBE", show_default=True, type=click.Choice(["PBE", "PBEsol", "LDA"]), help="XC functional.") @click.option("-m","--mpi-runner", default="mpirun", type=str, show_default=True, help="String used to invoke the MPI runner. ") @add_workdir_verbose_opts def main(filepath, nn_name, corr_algo_str, relax_mode, fmax, steps, optimizer, - kppa, rattle, scale_volume, mpi_nprocs, xc, mpi_runner, + kppa, rattle, scale_volume, mpi_nprocs, xc_name, mpi_runner, workdir, verbose, ): @@ -74,9 +74,11 @@ def main(filepath, nn_name, corr_algo_str, "PBE": "ONCVPSP-PBE-SR-PDv0.4", "PBEsol": "ONCVPSP-PBEsol-SR-PDv0.4", "LDA": "ONCVPSP-LDA-SR-PDv0.4", - }[xc] + }[xc_nane] print(f"Using {repo_name=}") pseudos = get_repo_from_name(repo_name).get_pseudos("standard") + #from abipy.flowtk.psrepos import get_repo_from_name get_oncvpsp_pseudos + #pseudos = get_oncvpsp_pseudos(xc_name=xc_name, version="0.4") # Get atoms if os.path.exists(filepath): @@ -97,7 +99,7 @@ def main(filepath, nn_name, corr_algo_str, print("Using corr_algo:", corr_algo_str) corr_algo = CORRALGO.from_string(corr_algo_str) - prof = RelaxationProfiler(atoms, pseudos, corr_algo, xc, kppa, relax_mode, fmax, mpi_nprocs, + prof = RelaxationProfiler(atoms, pseudos, corr_algo, xc_name, kppa, relax_mode, fmax, mpi_nprocs, steps=steps, verbose=verbose, optimizer=optimizer, nn_name=nn_name, mpi_runner=mpi_runner) prof.run(workdir=workdir) return 0