Skip to content

Commit

Permalink
The configuration in convergence workflow can be set dynamically in C…
Browse files Browse the repository at this point in the history
…LI (#195)
  • Loading branch information
unkcpz authored May 15, 2023
1 parent 7b66fc9 commit d59ce04
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 107 deletions.
98 changes: 26 additions & 72 deletions aiida_sssp_workflow/cli/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
UpfData = DataFactory("pseudo.upf")
VerificationWorkChain = WorkflowFactory("sssp_workflow.verification")

SSSP_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "_sssp")

# Trigger the launch by running:
# aiida-sssp-workflow launch --property accuracy.delta --pw-code pw-7.0@localhost --ph-code ph-7.0@localhost --protocol test --cutoff-control test --criteria efficiency --withmpi True -- examples/_static/Si_ONCV_PBE-1.2.upf

Expand Down Expand Up @@ -52,6 +50,11 @@
@click.option(
"criteria", "--criteria", default="efficiency", help="Criteria of convergence."
)
@click.option(
"configuration",
"--configuration",
help="(convergence only) Configuration of structure, can be: SC, FCC, BCC, Diamond, XO, XO2, XO3, X2O, X2O3, X2O5, TYPICAL.",
)
@click.option("withmpi", "--withmpi", default=True, help="Run with mpi.")
@click.option("npool", "--npool", default=1, help="Number of pool.")
@click.option("walltime", "--walltime", default=3600, help="Walltime.")
Expand All @@ -74,6 +77,7 @@ def launch(
protocol,
cutoff_control,
criteria,
configuration,
withmpi,
npool,
walltime,
Expand Down Expand Up @@ -106,12 +110,21 @@ def launch(
with open(pseudo, "rb") as stream:
pseudo = UpfData(stream)

_basic_inputs = {
inputs = {
"accuracy": {
"protocol": orm.Str(protocol),
"cutoff_control": orm.Str(cutoff_control),
},
"convergence": {
"protocol": orm.Str(protocol),
"cutoff_control": orm.Str(cutoff_control),
"criteria": orm.Str(criteria),
},
"pw_code": pw_code,
"ph_code": ph_code,
"protocol": orm.Str(protocol),
"cutoff_control": orm.Str(cutoff_control),
"criteria": orm.Str(criteria),
"pseudo": pseudo,
"label": label,
"properties_list": orm.List(properties_list),
"options": orm.Dict(
dict={
"resources": {
Expand All @@ -122,81 +135,22 @@ def launch(
"withmpi": withmpi,
}
),
"parallization": orm.Dict(dict={"npool": npool}),
"properties_list": orm.List(list=properties_list),
}

_pseudo_inputs = {
"pseudo": pseudo,
"label": label,
"extra_desc": extra_desc,
}

node = run_verification(
**_basic_inputs,
**_pseudo_inputs,
clean_workchain=clean_workchain,
on_daemon=daemon,
)

click.echo(node)
click.echo(f"calculated on property: {'/'.join(properties_list)}")


def run_verification(
pseudo,
pw_code,
ph_code,
protocol,
cutoff_control,
criteria,
options,
parallization,
properties_list,
label,
extra_desc,
clean_workchain,
on_daemon,
):
"""
pw_code: code for pw.x calculation
ph_code: code for ph.x calculation
upf: upf file to verify
properties_list: propertios to verified
label: if None, label will parsed from filename
mode:
test to run on localhost with test protocol
precheck: precheck control protocol on convergence verification
standard: running a production on eiger
"""
inputs = {
"accuracy": {
"protocol": protocol,
"cutoff_control": cutoff_control,
},
"convergence": {
"protocol": protocol,
"cutoff_control": cutoff_control,
"criteria": criteria,
},
"pw_code": pw_code,
"ph_code": ph_code,
"pseudo": pseudo,
"label": label,
"properties_list": properties_list,
"options": options,
"parallelization": parallization,
"parallelization": orm.Dict(dict={"npool": npool}),
"clean_workchain": orm.Bool(clean_workchain),
}

if on_daemon:
if configuration is not None:
inputs["convergence"]["configuration"] = orm.Str(configuration)

if daemon:
node = submit(VerificationWorkChain, **inputs)
else:
_, node = run_get_node(VerificationWorkChain, **inputs)

node.description = f"{label.value} ({extra_desc})"

return node
click.echo(node)
click.echo(f"calculated on property: {'/'.join(properties_list)}")


if __name__ == "__main__":
Expand Down
66 changes: 33 additions & 33 deletions aiida_sssp_workflow/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,40 +143,36 @@ def get_standard_structure(
from ase import io

# If for delta measure workflow
base_cif_module = "aiida_sssp_workflow.statics.structures"
if prop == "delta":
if configuration == "RE":
assert element in RARE_EARTH_ELEMENTS
base_structure_module = "aiida_sssp_workflow.statics.structures"

# use RE-nitrides of Wenzovich paper
# from typical cif folder
res_path = importlib.resources.path(
f"{base_cif_module}.typical", f"{element}N.cif"
)
primitive_cell = True
if configuration == "RE":
assert element in RARE_EARTH_ELEMENTS

if configuration == "TYPICAL":
res_path = importlib.resources.path(
f"{base_cif_module}.typical", f"{element}.cif"
)
primitive_cell = True
# use RE-nitrides of Wenzovich paper
# from typical cif folder
res_path = importlib.resources.path(
f"{base_structure_module}.typical", f"{element}N.cif"
)

# For elements that are verified in ACWF paper, use the XSF files.
# https://github.com/aiidateam/acwf-verification-scripts/tree/main/0-preliminary-do-not-run
if configuration in OXIDE_CONFIGURATIONS:
res_path = importlib.resources.path(
f"{base_cif_module}.oxides", f"{element}-{configuration}.xsf"
)
primitive_cell = False
if configuration == "TYPICAL":
res_path = importlib.resources.path(
f"{base_structure_module}.typical", f"{element}.cif"
)

if configuration in UNARIE_CONFIGURATIONS:
res_path = importlib.resources.path(
f"{base_cif_module}.unaries", f"{element}-{configuration}.xsf"
)
primitive_cell = False
# For elements that are verified in ACWF paper, use the XSF files.
# https://github.com/aiidateam/acwf-verification-scripts/tree/main/0-preliminary-do-not-run
if configuration in OXIDE_CONFIGURATIONS:
res_path = importlib.resources.path(
f"{base_structure_module}.oxides", f"{element}-{configuration}.xsf"
)

else:
# If for bands measure or convergence workflow
if configuration in UNARIE_CONFIGURATIONS:
res_path = importlib.resources.path(
f"{base_structure_module}.unaries", f"{element}-{configuration}.xsf"
)

if configuration is None:
# If configuration is not specified, use the one from mapping.json as default
# after some back-forward, most elements only use typical structure
# for bands and for convergence. But with the primitived structure.
# But for future maintainance, I keep the mapping.json for configuration
Expand All @@ -189,17 +185,21 @@ def get_standard_structure(
mapping = json.load(handle)

dir, fn = mapping[element][prop].split("/")
res_path = importlib.resources.path(f"{base_cif_module}.{dir}", fn)
primitive_cell = (
True # Since we want the convergence test run fast, use primitive cell.
)
res_path = importlib.resources.path(f"{base_structure_module}.{dir}", fn)

# For magnetic elements, use the conventional cell
if element in MAGNETIC_ELEMENTS:
primitive_cell = False
else:
primitive_cell = True

if prop == "delta":
primitive_cell = False
else:
# bands and convergence test.
# Since we want the convergence test run fast, use primitive cell.
primitive_cell = True

with res_path as path:
if Path(path).suffix == ".cif":
structure = orm.CifData.get_or_create(str(path), use_first=True)[
Expand Down
8 changes: 7 additions & 1 deletion aiida_sssp_workflow/workflows/convergence/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ def define(cls, spec):
help='The cutoff control list to use for the workchain.')
spec.input('criteria', valid_type=orm.Str, required=True,
help='Criteria for convergence measurement to give recommend cutoff pair.')
spec.input('configuration', valid_type=orm.Str, required=False)
spec.input('preset_ecutwfc', valid_type=orm.Int, required=False,
help='Preset wavefunction cutoff will be used and skip wavefunction test.')
spec.input('options', valid_type=orm.Dict, required=False,
Expand Down Expand Up @@ -230,7 +231,12 @@ def init_setup(self):

# Please check README for what and why we use configuration set 'convergence'
# for convergence verification.
self.ctx.structure = get_standard_structure(self.ctx.element, prop='convergence')
if "configuration" in self.inputs:
configuration = self.inputs.configuration.value
else:
# will use the default configuration set in the protocol (mapping.json)
configuration = None
self.ctx.structure = get_standard_structure(self.ctx.element, prop='convergence', configuration=configuration)

# For configuration that contains O, which is the configuration from ACWF set, we need to add O pseudo
if "O" in self.ctx.structure.get_kind_names():
Expand Down
2 changes: 1 addition & 1 deletion aiida_sssp_workflow/workflows/verifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def define(cls, spec):
spec.input('pseudo', valid_type=UpfData, required=True,
help='Pseudopotential to be verified')
spec.input('label', valid_type=orm.Str, required=False,
help='label store for display as extra attribut.')
help='label store for display as extra attributes.')
spec.input('properties_list', valid_type=orm.List,
default=lambda: orm.List(list=DEFAULT_PROPERTIES_LIST),
help='The preperties will be calculated, passed as a list.')
Expand Down

0 comments on commit d59ce04

Please sign in to comment.