diff --git a/setup.cfg b/setup.cfg
index d9e6a107d..2a1909ac9 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -58,6 +58,7 @@ aiidalab_qe.properties =
xps = aiidalab_qe.plugins.xps:xps
electronic_structure = aiidalab_qe.plugins.electronic_structure:electronic_structure
xas = aiidalab_qe.plugins.xas:xas
+ hp = aiidalab_qe.plugins.hp:hp
[aiidalab]
title = Quantum ESPRESSO
diff --git a/src/aiidalab_qe/common/setup_codes.py b/src/aiidalab_qe/common/setup_codes.py
index bfa95a8f3..6092c6bac 100644
--- a/src/aiidalab_qe/common/setup_codes.py
+++ b/src/aiidalab_qe/common/setup_codes.py
@@ -41,6 +41,7 @@
"pw2wannier90",
"q2r",
"xspectra",
+ "hp",
)
diff --git a/src/aiidalab_qe/plugins/hp/__init__.py b/src/aiidalab_qe/plugins/hp/__init__.py
new file mode 100644
index 000000000..15f015864
--- /dev/null
+++ b/src/aiidalab_qe/plugins/hp/__init__.py
@@ -0,0 +1,24 @@
+from aiidalab_qe.common.panel import OutlinePanel
+from aiidalab_widgets_base import ComputationalResourcesWidget
+
+from .result import Result
+from .workchain import workchain_and_builder
+
+
+class HpOutline(OutlinePanel):
+ title = "HP calculation"
+ help = """"""
+
+
+hp_code = ComputationalResourcesWidget(
+ description="hp.x",
+ default_calc_job_plugin="quantumespresso.hp",
+)
+
+
+hp = {
+ "outline": HpOutline,
+ "code": {"hp": hp_code},
+ "result": Result,
+ "workchain": workchain_and_builder,
+}
diff --git a/src/aiidalab_qe/plugins/hp/result.py b/src/aiidalab_qe/plugins/hp/result.py
new file mode 100644
index 000000000..fdf79342f
--- /dev/null
+++ b/src/aiidalab_qe/plugins/hp/result.py
@@ -0,0 +1,67 @@
+import ipywidgets as ipw
+from aiidalab_qe.common.panel import ResultPanel
+
+
+class Result(ResultPanel):
+ title = "Bader Charge"
+ workchain_labels = ["bader"]
+
+ def __init__(self, node=None, **kwargs):
+ super().__init__(node=node, **kwargs)
+ self.summary_view = ipw.HTML()
+
+ def _update_view(self):
+ structure = self.node.inputs.bader.structure
+ bader_charge = self.outputs.bader.bader.bader_charge.get_array("charge")
+ self._generate_table(structure, bader_charge)
+ self.children = [
+ ipw.HBox(
+ children=[self.summary_view],
+ layout=ipw.Layout(justify_content="space-between", margin="10px"),
+ ),
+ ]
+
+ def _generate_table(self, structure, bader_charge):
+ # get index and element form AiiDA StructureData
+ site_index = [site.kind_name for site in structure.sites]
+
+ # Start of the HTML string for the table
+ html_str = """
+
Bader Charge Table
+
+
+
+ Site Index |
+ Element |
+ Bader Charge |
+
"""
+
+ # Add rows to the table based on the bader_charge
+ for i in range(len(site_index)):
+ html_str += f"""
+
+ {i} |
+ {site_index[i]} |
+ {bader_charge[i]:1.3f} |
+
"""
+
+ # Close the table and div tags
+ html_str += """
+
+
"""
+ self.summary_view = ipw.HTML(html_str)
diff --git a/src/aiidalab_qe/plugins/hp/workchain.py b/src/aiidalab_qe/plugins/hp/workchain.py
new file mode 100644
index 000000000..5fc1f494e
--- /dev/null
+++ b/src/aiidalab_qe/plugins/hp/workchain.py
@@ -0,0 +1,68 @@
+from aiida_quantumespresso_hp.workflows.hp.main import HpWorkChain
+
+
+def check_codes(pw_code, hp_code):
+ """Check that the codes are installed on the same computer."""
+ if (
+ not any(
+ [
+ pw_code is None,
+ hp_code is None,
+ ]
+ )
+ and len(
+ set(
+ (
+ pw_code.computer.pk,
+ hp_code.computer.pk,
+ )
+ )
+ )
+ != 1
+ ):
+ raise ValueError(
+ "All selected codes must be installed on the same computer. This is because the "
+ "HP calculations rely on large files that are not retrieved by AiiDA."
+ )
+
+
+def get_builder(codes, structure, parameters, **kwargs):
+ pw_code = codes.get("pw")
+ hp_code = codes.get("hp")
+ check_codes(pw_code, hp_code)
+ protocol = parameters["workchain"]["protocol"]
+
+ overrides = {
+ "parallelize_atoms": True,
+ "parallelize_qpoints": True,
+ "hp": {
+ "hubbard_structure": structure,
+ "metadata": {
+ "options": {
+ "resources": {
+ "num_machines": 1,
+ "num_mpiprocs_per_machine": 2,
+ },
+ }
+ },
+ },
+ "qpoints_distance": 1000, # to get few q points
+ }
+ if hp_code is not None:
+ builder = HpWorkChain.get_builder_from_protocol(
+ code=hp_code,
+ protocol=protocol,
+ overrides=overrides,
+ **kwargs,
+ )
+ else:
+ raise ValueError("The hp_code and bader_code are required.")
+ return builder
+
+
+workchain_and_builder = {
+ "workchain": HpWorkChain,
+ "exclude": ("clean_workdir", "structure", "relax"),
+ "get_builder": get_builder,
+ "input_from_ctx": {"hp.parent_folder": "scf_folder"},
+}
diff --git a/src/aiidalab_qe/workflows/__init__.py b/src/aiidalab_qe/workflows/__init__.py
index ac292cb4a..aa6f32f25 100644
--- a/src/aiidalab_qe/workflows/__init__.py
+++ b/src/aiidalab_qe/workflows/__init__.py
@@ -204,7 +204,8 @@ def inspect_relax(self):
f"PwRelaxWorkChain failed with exit status {workchain.exit_status}"
)
return self.exit_codes.ERROR_SUB_PROCESS_FAILED_RELAX
-
+ # save the remote folder so that the next workchain can use it
+ self.ctx.scf_folder = workchain.outputs.remote_folder
if "output_structure" in workchain.outputs:
self.ctx.current_structure = workchain.outputs.output_structure
self.ctx.current_number_of_bands = (
@@ -228,6 +229,9 @@ def run_plugin(self):
)
inputs.metadata.call_link_label = name
inputs.structure = self.ctx.current_structure
+ # set the scf parent folder and other inputs from the context
+ for key, value in entry_point.get("input_from_ctx", {}).items():
+ setattr(inputs, key, self.ctx[value])
inputs = prepare_process_inputs(plugin_workchain, inputs)
running = self.submit(plugin_workchain, **inputs)
self.report(f"launching plugin {name} <{running.pk}>")