Skip to content
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

Set relax type none and no properites to run SCF only #274

Merged
merged 5 commits into from
Nov 16, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions aiidalab_qe/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,23 +82,31 @@ def find_work_chains(cls):
)

for process in projected[1:]:
pk = process[0]
formula = load_node(pk).inputs.structure.get_formula()
if "relax" in load_node(pk).inputs:
relax_info = "structure is relaxed"
else:
relax_info = "structure is not relaxed"
workchain = load_node(process[0])
formula = workchain.inputs.structure.get_formula()

properties = []
if "pdos" in load_node(pk).inputs:
if "pdos" in workchain.inputs:
properties.append("pdos")
if "bands" in load_node(pk).inputs:
if "bands" in workchain.inputs:
properties.append("bands")

if "relax" in workchain.inputs:
builder_parameters = workchain.get_extra("builder_parameters", {})
relax_type = builder_parameters.get("relax_type")

if relax_type != "none":
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is "none", not None or "None". Please make sure "none" is correct.

If it is correct, we need to change it to a more standard way, e.g. None

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

relax_type is a parameter read from widget.

        # RelaxType: degrees of freedom in geometry optimization
        self.relax_type = ipw.ToggleButtons(
            options=[
                ("Structure as is", "none"),
                ("Atomic positions", "positions"),
                ("Full geometry", "positions_cell"),
            ],
            value="positions_cell",
        )

The string type is used to distinguish the None in purpose.

relax_info = "structure is not relaxed"
unkcpz marked this conversation as resolved.
Show resolved Hide resolved
else:
relax_info = "static SCF calculation on structure"
else:
relax_info = "structure is not relaxed"

if not properties:
properties_info = ""
else:
properties_info = f"properties on {', '.join(properties)}"

yield cls.WorkChainData(
formula=formula,
relax_info=relax_info,
Expand Down
37 changes: 19 additions & 18 deletions aiidalab_qe/report.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from aiida.common.exceptions import NotExistentAttributeError
from aiida.plugins import WorkflowFactory

PwBaseWorkChain = WorkflowFactory("quantumespresso.pw.base")
Expand Down Expand Up @@ -98,27 +99,27 @@ def _generate_report_dict(qeapp_wc):
# read default from protocol
smearing = default_params["smearing"]

if run_relax:
try:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this try ... except is not used, because it will always run a relax (scf or real relax) calculation.

pw_parameters = qeapp_wc.inputs.relax.base.pw.parameters.get_dict()
if scf_kpoints_distance is None:
scf_kpoints_distance = qeapp_wc.inputs.relax.base.kpoints_distance.value
if run_bands:
pw_parameters = qeapp_wc.inputs.bands.scf.pw.parameters.get_dict()
if scf_kpoints_distance is None:
scf_kpoints_distance = qeapp_wc.inputs.bands.scf.kpoints_distance.value
bands_kpoints_distance = qeapp_wc.inputs.bands.bands_kpoints_distance.value
if run_pdos:
scf_kpoints_distance = (
scf_kpoints_distance or qeapp_wc.inputs.pdos.scf.kpoints_distance.value
)
pw_parameters = (
pw_parameters or qeapp_wc.inputs.pdos.scf.pw.parameters.get_dict()
)
nscf_kpoints_distance = qeapp_wc.inputs.pdos.nscf.kpoints_distance.value

if pw_parameters:
energy_cutoff_wfc = round(pw_parameters["SYSTEM"]["ecutwfc"])
energy_cutoff_rho = round(pw_parameters["SYSTEM"]["ecutrho"])
except NotExistentAttributeError:
if run_bands:
pw_parameters = qeapp_wc.inputs.bands.scf.pw.parameters.get_dict()
if scf_kpoints_distance is None:
scf_kpoints_distance = qeapp_wc.inputs.bands.scf.kpoints_distance.value
bands_kpoints_distance = qeapp_wc.inputs.bands.bands_kpoints_distance.value
if run_pdos:
scf_kpoints_distance = (
scf_kpoints_distance or qeapp_wc.inputs.pdos.scf.kpoints_distance.value
)
pw_parameters = (
pw_parameters or qeapp_wc.inputs.pdos.scf.pw.parameters.get_dict()
)
nscf_kpoints_distance = qeapp_wc.inputs.pdos.nscf.kpoints_distance.value

energy_cutoff_wfc = round(pw_parameters["SYSTEM"]["ecutwfc"])
energy_cutoff_rho = round(pw_parameters["SYSTEM"]["ecutrho"])

yield "energy_cutoff_wfc", energy_cutoff_wfc
yield "energy_cutoff_rho", energy_cutoff_rho
Expand Down
23 changes: 8 additions & 15 deletions aiidalab_qe/steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -425,21 +425,8 @@ def set_input_parameters(self, parameters):
def _update_state(self, _=None):
if self.previous_step_state == self.State.SUCCESS:
self.confirm_button.disabled = False
if not (
self.workchain_settings.relax_type.value != "none"
or self.workchain_settings.bands_run.value
or self.workchain_settings.pdos_run.value
):
self.confirm_button.disabled = True
self.state = self.State.READY
self._submission_blocker_messages.value = """
<div class="alert alert-info">
The configured work chain would not actually compute anything.
Select either a structure relaxation method or at least one of the
the bands or the PDOS calculations or both.</div>"""
else:
self._submission_blocker_messages.value = ""
self.state = self.State.CONFIGURED
self._submission_blocker_messages.value = ""
self.state = self.State.CONFIGURED
elif self.previous_step_state == self.State.FAIL:
self.state = self.State.FAIL
else:
Expand Down Expand Up @@ -878,6 +865,12 @@ def update_builder(buildy, resources, npools):
if "smearing_override" in parameters:
builder.smearing_override = Str(parameters["smearing_override"])

# skip relax sub-worflow only when RelaxType is NONE and has property calculated.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain the difference between relax (only scf) and relax sub-workflow? I am not very clear about this, thanks.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unkcpz marked this conversation as resolved.
Show resolved Hide resolved
if RelaxType(parameters["relax_type"]) is RelaxType.NONE and (
parameters["run_bands"] or parameters["run_pdos"]
):
builder.pop("relax")

if not parameters.get("run_bands", False):
builder.pop("bands")

Expand Down
44 changes: 21 additions & 23 deletions src/aiidalab_qe_workchain/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,25 +108,22 @@ def get_builder_from_protocol(
builder = cls.get_builder()
builder.structure = structure

if relax_type is not RelaxType.NONE:
relax_overrides = overrides.get("relax", {})
if pseudo_family is not None:
relax_overrides.setdefault("base", {})["pseudo_family"] = pseudo_family
relax_overrides = overrides.get("relax", {})
if pseudo_family is not None:
relax_overrides.setdefault("base", {})["pseudo_family"] = pseudo_family

relax = PwRelaxWorkChain.get_builder_from_protocol(
code=pw_code,
structure=structure,
protocol=protocol,
overrides=relax_overrides,
relax_type=relax_type,
**kwargs,
)
relax.pop("structure", None)
relax.pop("clean_workdir", None)
relax.pop("base_final_scf", None)
builder.relax = relax
else:
builder.pop("relax", None)
relax = PwRelaxWorkChain.get_builder_from_protocol(
code=pw_code,
structure=structure,
protocol=protocol,
overrides=relax_overrides,
relax_type=relax_type,
**kwargs,
)
relax.pop("structure", None)
relax.pop("clean_workdir", None)
relax.pop("base_final_scf", None)
builder.relax = relax

bands_overrides = overrides.get("bands", {})
if pseudo_family is not None:
Expand Down Expand Up @@ -236,11 +233,12 @@ def inspect_relax(self):
)
return self.exit_codes.ERROR_SUB_PROCESS_FAILED_RELAX

self.ctx.current_structure = workchain.outputs.output_structure
self.ctx.current_number_of_bands = (
workchain.outputs.output_parameters.get_attribute("number_of_bands")
)
self.out("structure", self.ctx.current_structure)
if "output_structure" in workchain.outputs:
self.ctx.current_structure = workchain.outputs.output_structure
self.ctx.current_number_of_bands = (
workchain.outputs.output_parameters.get_attribute("number_of_bands")
)
self.out("structure", self.ctx.current_structure)

def should_run_bands(self):
"""Check if the band structure should be calculated."""
Expand Down