-
Notifications
You must be signed in to change notification settings - Fork 197
docs: add CALYPSO model deviation arginfo #1887
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -621,16 +621,190 @@ def model_devi_amber_args() -> list[Argument]: | |
| ] | ||
|
|
||
|
|
||
| def model_devi_calypso_args() -> list[Argument]: | ||
| """CALYPSO engine arguments.""" | ||
| doc_model_devi_jobs = ( | ||
| "Settings for CALYPSO structure generation and model deviation. " | ||
| "For native CALYPSO mode, each dict in the list specifies the " | ||
| "structure-generation settings for one or more iterations. In " | ||
| "calypso_input_path mode, this key is still required by the current " | ||
| "runtime but may be an empty list." | ||
| ) | ||
| doc_times = "List of iteration indices when this job should be executed." | ||
| doc_nameofatoms = "Element symbols of the different chemical species." | ||
| doc_numberofatoms = "Number of atoms for each chemical species in one formula unit." | ||
| doc_numberofformula = "Range of formula units per cell as [min, max]." | ||
| doc_volume = ( | ||
| "Volume per formula unit in angstrom^3. If omitted, CALYPSO " | ||
| "determines the volume automatically." | ||
| ) | ||
| doc_distanceofion = ( | ||
| "Minimal distances between atoms of each chemical species in " | ||
| "angstrom. The matrix shape should match the number of species." | ||
| ) | ||
| doc_psoratio = "Proportion of structures generated by the PSO algorithm (0.0-1.0)." | ||
| doc_popsize = "Population size for structure generation." | ||
| doc_maxstep = "Maximum number of CALYPSO optimization steps." | ||
| doc_icode = "Interface code for local optimization: 1=VASP, 2=SIESTA, 3=GULP." | ||
| doc_split = "Whether to split calculations. Use 'T' for true or 'F' for false." | ||
| doc_vsc = ( | ||
| "Variable Stoichiometry Control. Use 'T' to enable it or 'F' to disable it." | ||
| ) | ||
| doc_maxnumatom = "Maximum number of atoms in the unit cell when VSC is 'T'." | ||
| doc_ctrlrange = ( | ||
| "Variation range for each atom type when VSC is 'T'. The matrix shape " | ||
| "should match the number of species." | ||
| ) | ||
| doc_pstress = "Target pressure values in GPa." | ||
| doc_fmax = "Force convergence criterion for local optimization in eV/angstrom." | ||
| doc_calypso_input_path = ( | ||
| "Directory containing pre-existing CALYPSO input.dat files. When this " | ||
| "is set, DP-GEN copies the provided input files instead of generating " | ||
| "them from model_devi_jobs." | ||
| ) | ||
| doc_model_devi_max_iter = ( | ||
| "Maximum model-deviation iteration index when using calypso_input_path." | ||
| ) | ||
| doc_vsc_mode = "Enable variable stoichiometry mode for external input files." | ||
| doc_model_devi_dt = ( | ||
| "Timestep retained for compatibility with existing CALYPSO parameter files." | ||
| ) | ||
|
|
||
| scalar_or_singleton_float = [float, list[float]] | ||
| scalar_or_singleton_int = [int, list[int]] | ||
|
|
||
| calypso_args = [ | ||
| Argument( | ||
| "model_devi_jobs", | ||
| list, | ||
| optional=False, | ||
| repeat=True, | ||
| doc=doc_model_devi_jobs, | ||
| sub_fields=[ | ||
| Argument("times", list[int], optional=False, doc=doc_times), | ||
| Argument("NameOfAtoms", list[str], optional=False, doc=doc_nameofatoms), | ||
| Argument( | ||
| "NumberOfAtoms", | ||
| list[int], | ||
| optional=False, | ||
| doc=doc_numberofatoms, | ||
| ), | ||
| Argument( | ||
| "NumberOfFormula", | ||
| list[int], | ||
| optional=True, | ||
| default=[1, 1], | ||
| doc=doc_numberofformula, | ||
| ), | ||
| Argument( | ||
| "Volume", | ||
| scalar_or_singleton_float, | ||
| optional=True, | ||
| doc=doc_volume, | ||
| ), | ||
| Argument( | ||
| "DistanceOfIon", | ||
| list[list[float]], | ||
| optional=False, | ||
| doc=doc_distanceofion, | ||
| ), | ||
| Argument( | ||
| "PsoRatio", | ||
| scalar_or_singleton_float, | ||
| optional=True, | ||
| default=0.6, | ||
| doc=doc_psoratio, | ||
| ), | ||
| Argument( | ||
| "PopSize", | ||
| scalar_or_singleton_int, | ||
| optional=True, | ||
| default=30, | ||
| doc=doc_popsize, | ||
| ), | ||
| Argument( | ||
| "MaxStep", | ||
| scalar_or_singleton_int, | ||
| optional=True, | ||
| default=5, | ||
| doc=doc_maxstep, | ||
| ), | ||
| Argument( | ||
| "ICode", | ||
| scalar_or_singleton_int, | ||
| optional=True, | ||
| default=1, | ||
| doc=doc_icode, | ||
| ), | ||
| Argument("Split", str, optional=True, default="T", doc=doc_split), | ||
| Argument("VSC", str, optional=True, default="F", doc=doc_vsc), | ||
| Argument( | ||
| "MaxNumAtom", | ||
| scalar_or_singleton_int, | ||
| optional=True, | ||
| doc=doc_maxnumatom, | ||
| ), | ||
| Argument( | ||
| "CtrlRange", | ||
| list[list[int]], | ||
| optional=True, | ||
| doc=doc_ctrlrange, | ||
| ), | ||
| Argument( | ||
| "PSTRESS", | ||
| scalar_or_singleton_float, | ||
| optional=True, | ||
| default=[0.001], | ||
| doc=doc_pstress, | ||
| ), | ||
| Argument( | ||
| "fmax", | ||
| scalar_or_singleton_float, | ||
| optional=True, | ||
| default=0.01, | ||
| doc=doc_fmax, | ||
| ), | ||
| ], | ||
| ), | ||
| Argument("calypso_input_path", str, optional=True, doc=doc_calypso_input_path), | ||
| Argument( | ||
| "model_devi_max_iter", int, optional=True, doc=doc_model_devi_max_iter | ||
| ), | ||
| Argument("vsc", bool, optional=True, default=False, doc=doc_vsc_mode), | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Blocking] The CALYPSO variant ends here, but the labeling stage still unconditionally reads
njzjz-bot marked this conversation as resolved.
|
||
| Argument("model_devi_dt", float, optional=True, doc=doc_model_devi_dt), | ||
| ] | ||
| # CALYPSO uses the same downstream candidate-selection controls as LAMMPS. | ||
| common_names = { | ||
| "model_devi_skip", | ||
|
njzjz-bot marked this conversation as resolved.
|
||
| "model_devi_f_trust_lo", | ||
| "model_devi_f_trust_hi", | ||
| "model_devi_v_trust_lo", | ||
| "model_devi_v_trust_hi", | ||
| "model_devi_adapt_trust_lo", | ||
| "model_devi_numb_candi_f", | ||
| "model_devi_numb_candi_v", | ||
| "model_devi_perc_candi_f", | ||
| "model_devi_perc_candi_v", | ||
| "model_devi_clean_traj", | ||
| "shuffle_poscar", | ||
| } | ||
| common_args = [ | ||
| argument for argument in model_devi_lmp_args() if argument.name in common_names | ||
| ] | ||
| return [*calypso_args, *common_args] | ||
|
|
||
|
|
||
| def model_devi_args() -> list[Variant]: | ||
| doc_model_devi_engine = "Engine for the model deviation task." | ||
| doc_amber = "Amber DPRc engine. The command argument in the machine file should be path to sander." | ||
| doc_calypso = "CALYPSO structure-generation engine for crystal prediction." | ||
| return [ | ||
| Variant( | ||
| "model_devi_engine", | ||
| [ | ||
| Argument("lammps", dict, model_devi_lmp_args(), doc="LAMMPS"), | ||
| Argument("amber", dict, model_devi_amber_args(), doc=doc_amber), | ||
| Argument("calypso", dict, [], doc="TODO: add doc"), | ||
| Argument("calypso", dict, model_devi_calypso_args(), doc=doc_calypso), | ||
|
njzjz-bot marked this conversation as resolved.
|
||
| Argument("gromacs", dict, [], doc="TODO: add doc"), | ||
| ], | ||
| default_tag="lammps", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| import json | ||
| import unittest | ||
| from pathlib import Path | ||
|
|
||
| from dargs import Argument | ||
|
|
||
| from dpgen.generator.arginfo import model_devi_args | ||
|
|
||
|
|
||
| class TestCalypsoArginfo(unittest.TestCase): | ||
| def test_selection_arguments_are_accepted(self): | ||
| """CALYPSO exposes the controls consumed by downstream FP selection.""" | ||
| arginfo = Argument("model_devi", dict, sub_variants=model_devi_args()) | ||
| data = { | ||
| "model_devi_engine": "calypso", | ||
| "model_devi_jobs": [], | ||
| "calypso_input_path": "calypso-input", | ||
| "model_devi_skip": 0, | ||
| "model_devi_f_trust_lo": 0.05, | ||
| "model_devi_f_trust_hi": 0.15, | ||
| "model_devi_clean_traj": True, | ||
| "model_devi_numb_candi_f": 10, | ||
| "model_devi_numb_candi_v": 10, | ||
| "shuffle_poscar": False, | ||
| } | ||
|
|
||
| normalized = arginfo.normalize_value(data) | ||
| arginfo.check_value(normalized, strict=True) | ||
|
|
||
| def test_checked_in_example_is_schema_compatible(self): | ||
| """The maintained example's CALYPSO section passes strict validation.""" | ||
| param_file = ( | ||
| Path(__file__).parent.parent | ||
| / "examples" | ||
| / "run" | ||
| / "dp-calypso-vasp" | ||
| / "param.json" | ||
| ) | ||
| with open(param_file) as fp: | ||
| example = json.load(fp) | ||
|
|
||
| model_devi_keys = { | ||
| "model_devi_engine", | ||
| "model_devi_jobs", | ||
| "model_devi_dt", | ||
| "model_devi_skip", | ||
| "model_devi_f_trust_lo", | ||
| "model_devi_f_trust_hi", | ||
| "model_devi_clean_traj", | ||
| "shuffle_poscar", | ||
| "vsc", | ||
| } | ||
| data = {key: example[key] for key in model_devi_keys} | ||
| arginfo = Argument("model_devi", dict, sub_variants=model_devi_args()) | ||
| normalized = arginfo.normalize_value(data) | ||
| arginfo.check_value(normalized, strict=True) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| unittest.main() |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Blocking] The documentation says
model_devi_max_iteris required incalypso_input_pathmode, but this still allows it to be omitted. The runtime usesjdata.get("model_devi_max_iter"); a missing value does not trigger the existingexcept KeyErrorand instead fails atiter_index > NonewithTypeError. Add explicit conditional validation before iteration and a missing-value test. Making the field globally required would not be correct because native-job mode does not need it.