Skip to content

Commit c5ebea2

Browse files
committed
Export from pyiron_base to jobflow
1 parent cafaed0 commit c5ebea2

File tree

3 files changed

+294
-2
lines changed

3 files changed

+294
-2
lines changed

.github/workflows/pyiron.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,5 @@ jobs:
2525
pip install -e python_workflow_definition
2626
conda install -c conda-forge jupyter papermill
2727
export ESPRESSO_PSEUDO=$(pwd)/espresso/pseudo
28-
papermill universal_qe_to_pyiron_base.ipynb universal_qe_to_pyiron_base_out.ipynb -k "python3"
28+
papermill universal_qe_to_pyiron_base.ipynb universal_qe_to_pyiron_base_out.ipynb -k "python3"
29+
papermill pyiron_base_to_jobflow.ipynb pyiron_base_to_jobflow_out.ipynb -k "python3"

pyiron_base_to_jobflow.ipynb

Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"id": "28d69730-d8cb-4174-ae3f-aa70da8a8108",
7+
"metadata": {},
8+
"outputs": [],
9+
"source": [
10+
"import numpy as np"
11+
]
12+
},
13+
{
14+
"cell_type": "code",
15+
"execution_count": null,
16+
"id": "cacaa0a8-27c8-44de-9e37-69cd3d13408b",
17+
"metadata": {},
18+
"outputs": [],
19+
"source": [
20+
"from jobflow.managers.local import run_locally"
21+
]
22+
},
23+
{
24+
"cell_type": "code",
25+
"execution_count": null,
26+
"id": "78ca455d-d0b8-4814-81fa-6039f6adb4c4",
27+
"metadata": {},
28+
"outputs": [],
29+
"source": [
30+
"from python_workflow_definition.jobflow import load_workflow_json"
31+
]
32+
},
33+
{
34+
"cell_type": "code",
35+
"execution_count": null,
36+
"id": "14d87342-706e-4120-99e6-b5363f724601",
37+
"metadata": {},
38+
"outputs": [],
39+
"source": [
40+
"from pyiron_base import Project, job"
41+
]
42+
},
43+
{
44+
"cell_type": "code",
45+
"execution_count": null,
46+
"id": "a2ed2608-9e1b-4a81-81cb-5079573ea2d1",
47+
"metadata": {},
48+
"outputs": [],
49+
"source": [
50+
"from python_workflow_definition.pyiron_base import write_workflow_json"
51+
]
52+
},
53+
{
54+
"cell_type": "code",
55+
"execution_count": null,
56+
"id": "444347b0-d5ba-4903-b8d4-a9d7fc35d268",
57+
"metadata": {},
58+
"outputs": [],
59+
"source": [
60+
"from python_workflow_definition.jobflow import load_workflow_json"
61+
]
62+
},
63+
{
64+
"cell_type": "code",
65+
"execution_count": null,
66+
"id": "b75c2530-9b89-4185-838f-a17e517fa68f",
67+
"metadata": {},
68+
"outputs": [],
69+
"source": [
70+
"from quantum_espresso_workflow import (\n",
71+
" calculate_qe as _calculate_qe, \n",
72+
" generate_structures as _generate_structures, \n",
73+
" get_bulk_structure as _get_bulk_structure, \n",
74+
" plot_energy_volume_curve as _plot_energy_volume_curve,\n",
75+
")"
76+
]
77+
},
78+
{
79+
"cell_type": "code",
80+
"execution_count": null,
81+
"id": "208ddfb8-dfda-4227-aa1f-3dc29e34ea82",
82+
"metadata": {},
83+
"outputs": [],
84+
"source": [
85+
"calculate_qe = job(_calculate_qe, output_key_lst=[\"energy\", \"volume\", \"structure\"])\n",
86+
"generate_structures = job(_generate_structures)\n",
87+
"plot_energy_volume_curve = job(_plot_energy_volume_curve)\n",
88+
"get_bulk_structure = job(_get_bulk_structure)"
89+
]
90+
},
91+
{
92+
"cell_type": "code",
93+
"execution_count": null,
94+
"id": "5071d3a0-7c1f-44c5-85e0-dede1566c10c",
95+
"metadata": {},
96+
"outputs": [],
97+
"source": [
98+
"pseudopotentials = {\"Al\": \"Al.pbe-n-kjpaw_psl.1.0.0.UPF\"}"
99+
]
100+
},
101+
{
102+
"cell_type": "code",
103+
"execution_count": null,
104+
"id": "13debfcd-362d-4fd0-a91f-5ab33632fceb",
105+
"metadata": {},
106+
"outputs": [],
107+
"source": [
108+
"pr = Project(\"test\")\n",
109+
"pr.remove_jobs(recursive=True, silently=True)"
110+
]
111+
},
112+
{
113+
"cell_type": "code",
114+
"execution_count": null,
115+
"id": "1f1cb12f-4001-478d-8ea0-b369f4f2981a",
116+
"metadata": {},
117+
"outputs": [],
118+
"source": [
119+
"structure = get_bulk_structure(\n",
120+
" name=\"Al\",\n",
121+
" a=4.05,\n",
122+
" cubic=True,\n",
123+
" pyiron_project=pr,\n",
124+
")"
125+
]
126+
},
127+
{
128+
"cell_type": "code",
129+
"execution_count": null,
130+
"id": "4140f07b-af54-41ef-be22-df6b5b53bf95",
131+
"metadata": {},
132+
"outputs": [],
133+
"source": [
134+
"calc_mini = calculate_qe(\n",
135+
" working_directory=\"mini\",\n",
136+
" input_dict={\n",
137+
" \"structure\": structure,\n",
138+
" \"pseudopotentials\": pseudopotentials,\n",
139+
" \"kpts\": (3, 3, 3),\n",
140+
" \"calculation\": \"vc-relax\",\n",
141+
" \"smearing\": 0.02,\n",
142+
" },\n",
143+
" pyiron_project=pr,\n",
144+
")"
145+
]
146+
},
147+
{
148+
"cell_type": "code",
149+
"execution_count": null,
150+
"id": "3c4dae11-8750-42d5-807c-cd19f2b65706",
151+
"metadata": {},
152+
"outputs": [],
153+
"source": [
154+
"number_of_strains = 5\n",
155+
"structure_lst = generate_structures( # the generate_structures() function is not available in the workflow graph\n",
156+
" structure=calc_mini.output.structure,\n",
157+
" strain_lst=np.linspace(0.9, 1.1, number_of_strains),\n",
158+
" pyiron_project=pr,\n",
159+
" list_length=number_of_strains,\n",
160+
")"
161+
]
162+
},
163+
{
164+
"cell_type": "code",
165+
"execution_count": null,
166+
"id": "fdf3b62d-6cce-4312-8a5b-057224e36aca",
167+
"metadata": {},
168+
"outputs": [],
169+
"source": [
170+
"job_strain_lst = []\n",
171+
"for i, structure_strain in enumerate(structure_lst):\n",
172+
" calc_strain = calculate_qe(\n",
173+
" working_directory=\"strain_\" + str(i),\n",
174+
" input_dict={\n",
175+
" \"structure\": structure_strain,\n",
176+
" \"pseudopotentials\": pseudopotentials,\n",
177+
" \"kpts\": (3, 3, 3),\n",
178+
" \"calculation\": \"scf\",\n",
179+
" \"smearing\": 0.02,\n",
180+
" },\n",
181+
" pyiron_project=pr,\n",
182+
" )\n",
183+
" job_strain_lst.append(calc_strain)"
184+
]
185+
},
186+
{
187+
"cell_type": "code",
188+
"execution_count": null,
189+
"id": "b2823306-0a8a-4ae6-bb1f-104e90e2fe41",
190+
"metadata": {},
191+
"outputs": [],
192+
"source": [
193+
"plot = plot_energy_volume_curve(\n",
194+
" volume_lst=[job.output.volume for job in job_strain_lst],\n",
195+
" energy_lst=[job.output.energy for job in job_strain_lst],\n",
196+
" pyiron_project=pr,\n",
197+
")"
198+
]
199+
},
200+
{
201+
"cell_type": "code",
202+
"execution_count": null,
203+
"id": "52646121-335f-48e6-bd5e-a1d69d00e8bc",
204+
"metadata": {},
205+
"outputs": [],
206+
"source": [
207+
"write_workflow_json(delayed_object=plot, file_name=\"workflow_pyiron.json\")"
208+
]
209+
},
210+
{
211+
"cell_type": "code",
212+
"execution_count": null,
213+
"id": "72c8e6e6-8e60-4a4f-81f3-968b4b5f36ee",
214+
"metadata": {},
215+
"outputs": [],
216+
"source": [
217+
"!cat workflow_pyiron.json"
218+
]
219+
},
220+
{
221+
"cell_type": "code",
222+
"execution_count": null,
223+
"id": "32fcd4b2-4f0a-442d-b098-827672823796",
224+
"metadata": {},
225+
"outputs": [],
226+
"source": [
227+
"flow = load_workflow_json(file_name=\"workflow_pyiron.json\")"
228+
]
229+
},
230+
{
231+
"cell_type": "code",
232+
"execution_count": null,
233+
"id": "a80b59bd-fe30-49c6-92ca-35ef2d77a6fb",
234+
"metadata": {},
235+
"outputs": [],
236+
"source": [
237+
"result = run_locally(flow)\n",
238+
"result"
239+
]
240+
},
241+
{
242+
"cell_type": "code",
243+
"execution_count": null,
244+
"id": "6a8d1a17-3698-4873-8937-616e9e7dc7ca",
245+
"metadata": {},
246+
"outputs": [],
247+
"source": []
248+
}
249+
],
250+
"metadata": {
251+
"kernelspec": {
252+
"display_name": "Python 3 (ipykernel)",
253+
"language": "python",
254+
"name": "python3"
255+
},
256+
"language_info": {
257+
"codemirror_mode": {
258+
"name": "ipython",
259+
"version": 3
260+
},
261+
"file_extension": ".py",
262+
"mimetype": "text/x-python",
263+
"name": "python",
264+
"nbconvert_exporter": "python",
265+
"pygments_lexer": "ipython3",
266+
"version": "3.12.5"
267+
}
268+
},
269+
"nbformat": 4,
270+
"nbformat_minor": 5
271+
}

python_workflow_definition/src/python_workflow_definition/pyiron_base.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import json
21
from importlib import import_module
2+
from inspect import isfunction
3+
import json
34

45
from pyiron_base import job
56
from pyiron_base.project.delayed import DelayedObject
@@ -216,3 +217,22 @@ def load_workflow_json(project, file_name):
216217
pyiron_project=project,
217218
)
218219
return delayed_object_dict[list(delayed_object_dict.keys())[-1]]
220+
221+
222+
def write_workflow_json(delayed_object, file_name="workflow.json"):
223+
nodes_dict, edges_lst = delayed_object.get_graph()
224+
nodes_dict, edges_lst = remove_server_obj(nodes_dict=nodes_dict, edges_lst=edges_lst)
225+
delayed_object_updated_dict, match_dict = get_unique_objects(nodes_dict=nodes_dict, edges_lst=edges_lst)
226+
connection_dict, lookup_dict = get_connection_dict(delayed_object_updated_dict=delayed_object_updated_dict, match_dict=match_dict)
227+
nodes_new_dict = get_nodes(connection_dict=connection_dict, delayed_object_updated_dict=delayed_object_updated_dict)
228+
edges_new_lst = get_edges_dict(edges_lst=edges_lst, nodes_dict=nodes_dict, connection_dict=connection_dict, lookup_dict=lookup_dict)
229+
230+
nodes_store_dict = {}
231+
for k, v in nodes_new_dict.items():
232+
if isfunction(v):
233+
nodes_store_dict[k] = v.__module__ + "." + v.__name__
234+
else:
235+
nodes_store_dict[k] = v
236+
237+
with open(file_name, "w") as f:
238+
json.dump({"nodes": nodes_store_dict, "edges": edges_new_lst}, f)

0 commit comments

Comments
 (0)