Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
6 changes: 6 additions & 0 deletions .github/workflows/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ jobs:
- name: Test
shell: bash -l {0}
run: |
export ESPRESSO_PSEUDO=$(pwd)/espresso/pseudo
pip install --no-deps --no-build-isolation -e qe_xml_parser
verdi presto --profile-name pwd
echo -e 'from aiida import load_profile\nload_profile()\n\nfrom python_workflow_definition.aiida import load_workflow_json\n\n\nif __name__ == "__main__":\n workgraph = load_workflow_json(file_name="workflow.json")\n workgraph.run()' > test_with_aiida.py
python test_with_aiida.py
Expand All @@ -40,6 +42,8 @@ jobs:
- name: Test
shell: bash -l {0}
run: |
export ESPRESSO_PSEUDO=$(pwd)/espresso/pseudo
pip install --no-deps --no-build-isolation -e qe_xml_parser
echo -e 'from jobflow.managers.local import run_locally\nfrom python_workflow_definition.jobflow import load_workflow_json\n\n\nif __name__ == "__main__":\n flow = load_workflow_json(file_name="workflow.json")\n print(run_locally(flow))' > test_with_jobflow.py
python test_with_jobflow.py

Expand All @@ -58,5 +62,7 @@ jobs:
- name: Test
shell: bash -l {0}
run: |
export ESPRESSO_PSEUDO=$(pwd)/espresso/pseudo
pip install --no-deps --no-build-isolation -e qe_xml_parser
echo -e 'from python_workflow_definition.pyiron_base import load_workflow_json\n\n\nif __name__ == "__main__":\n delayed_object_lst = load_workflow_json(file_name="workflow.json")\n print(delayed_object_lst[-1].pull())' > test_with_pyiron.py
python test_with_pyiron.py
32 changes: 3 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,4 @@
# Arithmetic Example Workflow
[![Pipeline](https://github.com/pythonworkflow/example-workflow/actions/workflows/pipeline.yml/badge.svg)](https://github.com/pythonworkflow/example-workflow/actions/workflows/pipeline.yml)

Template repository for publishing an interoperable workflow based on the Python Workflow Definition.

## Content
The minimal workflow consists of three files:

| File | Explanation |
|-------------------|---------------------------------------------------------|
| `environment.yml` | Conda environment for software dependencies |
| `workflow.py` | Python functions representing the nodes of the workflow |
| `workflow.json` | Workflow graph consisting of nodes and edges |

Additional optional files for the publication of the workflow:

| File | Explanation |
|----------------------------------|------------------------------------------|
| `README.md` | Readme file to introduce the workflow |
| `.github/workflows/pipeline.yml` | Github Actions to test the workflow |

## Publish your workflow
You can publish your workflow in five simple steps:
* Fork the repository and clone your fork locally.
* Export your workflow to the Python Workflow Definition using the `python_workflow_definition` Python package, by calling the `write_workflow_json()` function.
* Replace the `environment.yml`, `workflow.py` and `workflow.json` in your local folder with the files for your workflow. In addition, you can add additional files if they are required and update the `README.md` to explain your workflow.
* Commit the files locally using `git add -A` and `git commit -m "add my workflow"`
* Push your workflow to Github `git push`

# Quantum Espresso Bulk Modulus Workflow
[![Pipeline](https://github.com/pythonworkflow/quantum-espresso-bulk-modulus-workflow/actions/workflows/pipeline.yml/badge.svg)](https://github.com/pythonworkflow/quantum-espresso-bulk-modulus-workflow/actions/workflows/pipeline.yml)

Workflow to calculate the equilibrium bulk modulus with the [quantum ESPRESSO](https://www.quantum-espresso.org) density functional theory simulation code. This repository demonstrates the use of the [python-workflow-definition](https://github.com/pythonworkflow/python-workflow-definition) Python package and the [example-workflow](https://github.com/pythonworkflow/example-workflow) repository template.
7 changes: 7 additions & 0 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,12 @@ channels:
- conda-forge
dependencies:
- python =3.12
- ase=3.24.0
- hatchling =1.27.0
- matplotlib=3.10.1
- xmlschema=3.4.3
- optimade=1.2.3
- qe=7.2
- qe-tools=2.0.0
- pip:
- python-workflow-definition==0.0.1
18,497 changes: 18,497 additions & 0 deletions espresso/pseudo/Al.pbe-n-kjpaw_psl.1.0.0.UPF

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions qe_xml_parser/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "qe_xml_parser"
version = "0.0.1"
description = "Quantum Espresso xml output parser"
authors = [
{ name = "Marnik Bercx", email = "marnik.bercx@psi.ch" },
]
license = { text = "MIT" }
dependencies = ["numpy", "xmlschema", "qe_tools", "ase"]
Empty file.
70 changes: 70 additions & 0 deletions qe_xml_parser/src/qe_xml_parser/parsers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import numpy

from xmlschema import XMLSchema
from qe_tools import CONSTANTS

from ase import Atoms
from importlib.resources import files

from . import schemas


def parse_pw(xml_file):
"""Parse a Quantum Espresso XML output file."""

xml_dict = XMLSchema(str(files(schemas) / "qes_230310.xsd")).to_dict(xml_file)

parsed_results = {}

try:
cell = (
numpy.array(
[v for v in xml_dict["output"]["atomic_structure"]["cell"].values()]
)
* CONSTANTS.bohr_to_ang
)
symbols = [
el["@name"]
for el in xml_dict["output"]["atomic_structure"]["atomic_positions"]["atom"]
]
positions = (
numpy.array(
[
el["$"]
for el in xml_dict["output"]["atomic_structure"][
"atomic_positions"
]["atom"]
]
)
* CONSTANTS.bohr_to_ang
)

parsed_results["ase_structure"] = Atoms(
cell=cell,
positions=positions,
symbols=symbols,
pbc=True,
)
except KeyError:
pass

try:
parsed_results["energy"] = (
xml_dict["output"]["total_energy"]["etot"] * CONSTANTS.ry_to_ev
)
except KeyError:
pass

try:
parsed_results["forces"] = (
numpy.array(xml_dict["output"]["forces"]["$"]).reshape(
xml_dict["output"]["forces"]["@dims"]
)
* 2
* CONSTANTS.ry_to_ev
/ CONSTANTS.bohr_to_ang
)
except KeyError:
pass

return parsed_results
Empty file.
Loading
Loading