From af12c58626b6bd0463f34fb798210a60df81a306 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Wed, 15 Nov 2023 23:01:45 +0100 Subject: [PATCH 1/7] Nodes for the `atomistics` package Example: ``` from pyiron_workflow import Workflow from pyiron_workflow.atomistics_library.calculatornodes import get_emt, calc_with_calculator from pyiron_workflow.atomistics_library.tasknodes import get_evcurve_task_generator, analyse_structures, generate_structures, get_bulk wf = Workflow("evcurve") wf.get_structure = get_bulk(element="Al") wf.get_task_generator = get_evcurve_task_generator(structure=wf.get_structure) wf.generate_structures = generate_structures(instance=wf.get_task_generator) wf.get_calculator = get_emt() wf.calc_with_calculator = calc_with_calculator(task_dict=wf.generate_structures, calculator=wf.get_calculator) wf.fit = analyse_structures(instance=wf.get_task_generator, output_dict=wf.calc_with_calculator) wf.draw() wf.run() ``` As the workflows in the `atomistics` package all follow the same pattern of (0) initializing the generator, (1) generating atomic structures, (2) evaluate the atomic structures with a simulation code and (3) analyse the results, the integration was rather straight forward. --- .../atomistics_library/__init__.py | 0 .../atomistics_library/calculatornodes.py | 113 ++++++++++++++++++ .../atomistics_library/tasknodes.py | 80 +++++++++++++ 3 files changed, 193 insertions(+) create mode 100644 pyiron_workflow/atomistics_library/__init__.py create mode 100644 pyiron_workflow/atomistics_library/calculatornodes.py create mode 100644 pyiron_workflow/atomistics_library/tasknodes.py diff --git a/pyiron_workflow/atomistics_library/__init__.py b/pyiron_workflow/atomistics_library/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pyiron_workflow/atomistics_library/calculatornodes.py b/pyiron_workflow/atomistics_library/calculatornodes.py new file mode 100644 index 00000000..889d1bf7 --- /dev/null +++ b/pyiron_workflow/atomistics_library/calculatornodes.py @@ -0,0 +1,113 @@ +from ase.units import Ry + +from pyiron_workflow.function import single_value_node + + +@single_value_node(output_labels="calculator") +def get_emt(): + from ase.calculators.emt import EMT + return EMT() + + +@single_value_node(output_labels="calculator") +def get_abinit( + label='abinit_evcurve', + nbands=32, + ecut=10 * Ry, + kpts=(3, 3, 3), + toldfe=1.0e-2, + v8_legacy_format=False, +): + from ase.calculators.abinit import Abinit + return Abinit( + label=label, + nbands=nbands, + ecut=ecut, + kpts=kpts, + toldfe=toldfe, + v8_legacy_format=v8_legacy_format, + ) + + +@single_value_node(output_labels="calculator") +def get_gpaw( + xc="PBE", + encut=300, + kpts=(3, 3, 3) +): + from gpaw import GPAW, PW + return GPAW( + xc=xc, + mode=PW(encut), + kpts=kpts + ) + + +@single_value_node(output_labels="calculator") +def get_quantum_espresso( + pseudopotentials={"Al": "Al.pbe-n-kjpaw_psl.1.0.0.UPF"}, + tstress=True, + tprnfor=True, + kpts=(3, 3, 3), +): + from ase.calculators.espresso import Espresso + return Espresso( + pseudopotentials=pseudopotentials, + tstress=tstress, + tprnfor=tprnfor, + kpts=kpts, + ) + + +@single_value_node(output_labels="calculator") +def get_siesta( + label="siesta", + xc="PBE", + mesh_cutoff=200 * Ry, + energy_shift=0.01 * Ry, + basis_set="DZ", + kpts=(5, 5, 5), + fdf_arguments={"DM.MixingWeight": 0.1, "MaxSCFIterations": 100}, + pseudo_path="", + pseudo_qualifier="", +): + from ase.calculators.siesta import Siesta + return Siesta( + label=label, + xc=xc, + mesh_cutoff=mesh_cutoff, + energy_shift=energy_shift, + basis_set=basis_set, + kpts=kpts, + fdf_arguments=fdf_arguments, + pseudo_path=pseudo_path, + pseudo_qualifier=pseudo_qualifier, + ) + + +@single_value_node(output_labels="energy_dict") +def calc_with_calculator(task_dict, calculator): + from atomistics.calculators.ase import evaluate_with_ase + return evaluate_with_ase( + task_dict=task_dict, + ase_calculator=calculator + ) + + +@single_value_node(output_labels="lammps_potential_dataframe") +def get_lammps_potential(potential_name, structure, resource_path): + from atomistics.calculators.lammps import get_potential_dataframe + df_pot = get_potential_dataframe( + structure=structure, + resource_path=resource_path + ) + return df_pot[df_pot.Name == potential_name].iloc[0] + + +@single_value_node(output_labels="energy_dict") +def get_lammps(task_dict, potential_dataframe): + from atomistics.calculators.lammps import evaluate_with_lammps + return evaluate_with_lammps( + task_dict=task_dict, + potential_dataframe=potential_dataframe, + ) \ No newline at end of file diff --git a/pyiron_workflow/atomistics_library/tasknodes.py b/pyiron_workflow/atomistics_library/tasknodes.py new file mode 100644 index 00000000..3a9c6e7e --- /dev/null +++ b/pyiron_workflow/atomistics_library/tasknodes.py @@ -0,0 +1,80 @@ +from phonopy.units import VaspToTHz +from pyiron_workflow.function import single_value_node + + +@single_value_node(output_labels="task_generator") +def get_elastic_matrix_task_generator( + structure, + num_of_point=5, + eps_range=0.05, + sqrt_eta=True, + fit_order=2 +): + from atomistics.workflows.elastic.workflow import ElasticMatrixWorkflow + return ElasticMatrixWorkflow( + structure=structure, + num_of_point=num_of_point, + eps_range=eps_range, + sqrt_eta=sqrt_eta, + fit_order=fit_order, + ) + + +@single_value_node(output_labels="task_generator") +def get_evcurve_task_generator( + structure, + num_points=11, + fit_type='polynomial', + fit_order=3, + vol_range=0.05, + axes=['x', 'y', 'z'], + strains=None +): + from atomistics.workflows.evcurve.workflow import EnergyVolumeCurveWorkflow + return EnergyVolumeCurveWorkflow( + structure=structure, + num_points=num_points, + fit_type=fit_type, + fit_order=fit_order, + vol_range=vol_range, + axes=axes, + strains=strains, + ) + + +@single_value_node(output_labels="task_generator") +def get_phonons_task_generator( + structure, + interaction_range=10, + factor=VaspToTHz, + displacement=0.01, + dos_mesh=20, + primitive_matrix=None, + number_of_snapshots=None, +): + from atomistics.workflows.phonons.workflow import PhonopyWorkflow + return PhonopyWorkflow( + structure=structure, + interaction_range=interaction_range, + factor=factor, + displacement=displacement, + dos_mesh=dos_mesh, + primitive_matrix=primitive_matrix, + number_of_snapshots=number_of_snapshots, + ) + + +@single_value_node(output_labels="result_dict") +def analyse_structures(instance, output_dict): + return instance.analyse_structures(output_dict=output_dict) + + +@single_value_node(output_labels="task_dict") +def generate_structures(instance): + return instance.generate_structures() + + +@single_value_node(output_labels="structure") +def get_bulk(element): + from ase.build import bulk + return bulk(element, a=4.00, cubic=True) From 99511e70f4b391d9a276fcada0c0fa7b37bc4ad6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Thu, 16 Nov 2023 06:59:33 +0100 Subject: [PATCH 2/7] remove `output_labels` kwargs - switch to args --- .../atomistics_library/calculatornodes.py | 16 ++++++++-------- pyiron_workflow/atomistics_library/tasknodes.py | 12 ++++++------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/pyiron_workflow/atomistics_library/calculatornodes.py b/pyiron_workflow/atomistics_library/calculatornodes.py index 889d1bf7..3a5be22f 100644 --- a/pyiron_workflow/atomistics_library/calculatornodes.py +++ b/pyiron_workflow/atomistics_library/calculatornodes.py @@ -3,13 +3,13 @@ from pyiron_workflow.function import single_value_node -@single_value_node(output_labels="calculator") +@single_value_node("calculator") def get_emt(): from ase.calculators.emt import EMT return EMT() -@single_value_node(output_labels="calculator") +@single_value_node("calculator") def get_abinit( label='abinit_evcurve', nbands=32, @@ -29,7 +29,7 @@ def get_abinit( ) -@single_value_node(output_labels="calculator") +@single_value_node("calculator") def get_gpaw( xc="PBE", encut=300, @@ -43,7 +43,7 @@ def get_gpaw( ) -@single_value_node(output_labels="calculator") +@single_value_node("calculator") def get_quantum_espresso( pseudopotentials={"Al": "Al.pbe-n-kjpaw_psl.1.0.0.UPF"}, tstress=True, @@ -59,7 +59,7 @@ def get_quantum_espresso( ) -@single_value_node(output_labels="calculator") +@single_value_node("calculator") def get_siesta( label="siesta", xc="PBE", @@ -85,7 +85,7 @@ def get_siesta( ) -@single_value_node(output_labels="energy_dict") +@single_value_node("energy_dict") def calc_with_calculator(task_dict, calculator): from atomistics.calculators.ase import evaluate_with_ase return evaluate_with_ase( @@ -94,7 +94,7 @@ def calc_with_calculator(task_dict, calculator): ) -@single_value_node(output_labels="lammps_potential_dataframe") +@single_value_node("lammps_potential_dataframe") def get_lammps_potential(potential_name, structure, resource_path): from atomistics.calculators.lammps import get_potential_dataframe df_pot = get_potential_dataframe( @@ -104,7 +104,7 @@ def get_lammps_potential(potential_name, structure, resource_path): return df_pot[df_pot.Name == potential_name].iloc[0] -@single_value_node(output_labels="energy_dict") +@single_value_node("energy_dict") def get_lammps(task_dict, potential_dataframe): from atomistics.calculators.lammps import evaluate_with_lammps return evaluate_with_lammps( diff --git a/pyiron_workflow/atomistics_library/tasknodes.py b/pyiron_workflow/atomistics_library/tasknodes.py index 3a9c6e7e..379f75eb 100644 --- a/pyiron_workflow/atomistics_library/tasknodes.py +++ b/pyiron_workflow/atomistics_library/tasknodes.py @@ -2,7 +2,7 @@ from pyiron_workflow.function import single_value_node -@single_value_node(output_labels="task_generator") +@single_value_node("task_generator") def get_elastic_matrix_task_generator( structure, num_of_point=5, @@ -20,7 +20,7 @@ def get_elastic_matrix_task_generator( ) -@single_value_node(output_labels="task_generator") +@single_value_node("task_generator") def get_evcurve_task_generator( structure, num_points=11, @@ -42,7 +42,7 @@ def get_evcurve_task_generator( ) -@single_value_node(output_labels="task_generator") +@single_value_node("task_generator") def get_phonons_task_generator( structure, interaction_range=10, @@ -64,17 +64,17 @@ def get_phonons_task_generator( ) -@single_value_node(output_labels="result_dict") +@single_value_node("result_dict") def analyse_structures(instance, output_dict): return instance.analyse_structures(output_dict=output_dict) -@single_value_node(output_labels="task_dict") +@single_value_node("task_dict") def generate_structures(instance): return instance.generate_structures() -@single_value_node(output_labels="structure") +@single_value_node("structure") def get_bulk(element): from ase.build import bulk return bulk(element, a=4.00, cubic=True) From d28bd0bbdbe4e7466208366aa24b87124850dec5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Thu, 16 Nov 2023 07:21:03 +0100 Subject: [PATCH 3/7] Add Macro nodes These can be used like this: ``` wf = Workflow("evcurve") wf.get_structure = get_bulk() wf.get_calculator = get_emt() wf.evcurve = evcurve(structure=wf.get_structure, calculator=wf.get_calculator) wf.draw() wf.run() ``` --- .../atomistics_library/macronodes.py | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 pyiron_workflow/atomistics_library/macronodes.py diff --git a/pyiron_workflow/atomistics_library/macronodes.py b/pyiron_workflow/atomistics_library/macronodes.py new file mode 100644 index 00000000..452d754a --- /dev/null +++ b/pyiron_workflow/atomistics_library/macronodes.py @@ -0,0 +1,64 @@ +from pyiron_workflow.macro import Macro, macro_node +from pyiron_workflow.atomistics_library.calculatornodes import calc_with_calculator +from pyiron_workflow.atomistics_library.tasknodes import ( + get_elastic_matrix_task_generator, + get_evcurve_task_generator, + get_phonons_task_generator, + analyse_structures, + generate_structures +) + + +@macro_node() +def get_energy_volume_curve(wf: Macro) -> None: + wf.get_task_generator = get_evcurve_task_generator() + wf.generate_structures = generate_structures(instance=wf.get_task_generator) + wf.calc_with_calculator = calc_with_calculator(task_dict=wf.generate_structures) + wf.fit = analyse_structures(instance=wf.get_task_generator, output_dict=wf.calc_with_calculator) + wf.inputs_map = { + "get_task_generator__structure": "structure", + "get_task_generator__num_points": "num_points", + "get_task_generator__fit_type": "fit_type", + "get_task_generator__fit_order": "fit_order", + "get_task_generator__vol_range": "vol_range", + "get_task_generator__axes": "axes", + "get_task_generator__strains": "strains", + "calc_with_calculator__calculator": "calculator", + } + wf.outputs_map = {"fit__fit_dict": "fit_dict"} + + +@macro_node() +def get_elastic_matrix(wf: Macro) -> None: + wf.get_task_generator = get_elastic_matrix_task_generator() + wf.generate_structures = generate_structures(instance=wf.get_task_generator) + wf.calc_with_calculator = calc_with_calculator(task_dict=wf.generate_structures) + wf.fit = analyse_structures(instance=wf.get_task_generator, output_dict=wf.calc_with_calculator) + wf.inputs_map = { + "get_task_generator__structure": "structure", + "get_task_generator__num_of_point": "num_of_point", + "get_task_generator__eps_range": "eps_range", + "get_task_generator__sqrt_eta": "sqrt_eta", + "get_task_generator__fit_order": "fit_order", + "calc_with_calculator__calculator": "calculator", + } + wf.outputs_map = {"fit__fit_dict": "fit_dict"} + + +@macro_node() +def get_phonons(wf: Macro) -> None: + wf.get_task_generator = get_phonons_task_generator() + wf.generate_structures = generate_structures(instance=wf.get_task_generator) + wf.calc_with_calculator = calc_with_calculator(task_dict=wf.generate_structures) + wf.fit = analyse_structures(instance=wf.get_task_generator, output_dict=wf.calc_with_calculator) + wf.inputs_map = { + "get_task_generator__structure": "structure", + "get_task_generator__interaction_range": "interaction_range", + "get_task_generator__factor": "factor", + "get_task_generator__displacement": "displacement", + "get_task_generator__dos_mesh": "dos_mesh", + "get_task_generator__primitive_matrix": "primitive_matrix", + "get_task_generator__number_of_snapshots": "number_of_snapshots", + "calc_with_calculator__calculator": "calculator", + } + wf.outputs_map = {"fit__fit_dict": "fit_dict"} From 20d4658b090ea3c070d950b2e43039134f34d18c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Thu, 16 Nov 2023 07:43:34 +0100 Subject: [PATCH 4/7] Define an internal macro to reduce code duplication --- .../atomistics_library/macronodes.py | 43 ++++++++++++------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/pyiron_workflow/atomistics_library/macronodes.py b/pyiron_workflow/atomistics_library/macronodes.py index 452d754a..708c7eb0 100644 --- a/pyiron_workflow/atomistics_library/macronodes.py +++ b/pyiron_workflow/atomistics_library/macronodes.py @@ -1,4 +1,5 @@ from pyiron_workflow.macro import Macro, macro_node +from pyiron_workflow.function import single_value_node from pyiron_workflow.atomistics_library.calculatornodes import calc_with_calculator from pyiron_workflow.atomistics_library.tasknodes import ( get_elastic_matrix_task_generator, @@ -9,12 +10,28 @@ ) +@single_value_node("instance") +def get_instance(instance): + return instance + + +@macro_node() +def internal_macro(wf: Macro) -> None: + wf.get_instance = get_instance() + wf.generate_structures = generate_structures(instance=wf.get_instance) + wf.calc_with_calculator = calc_with_calculator(task_dict=wf.generate_structures) + wf.fit = analyse_structures(instance=wf.get_instance, output_dict=wf.calc_with_calculator) + wf.inputs_map = { + "get_instance__instance": "instance", + "calc_with_calculator__calculator": "calculator", + } + wf.outputs_map = {"fit__fit_dict": "fit_dict"} + + @macro_node() def get_energy_volume_curve(wf: Macro) -> None: wf.get_task_generator = get_evcurve_task_generator() - wf.generate_structures = generate_structures(instance=wf.get_task_generator) - wf.calc_with_calculator = calc_with_calculator(task_dict=wf.generate_structures) - wf.fit = analyse_structures(instance=wf.get_task_generator, output_dict=wf.calc_with_calculator) + wf.internal = internal_macro(instance=wf.get_task_generator) wf.inputs_map = { "get_task_generator__structure": "structure", "get_task_generator__num_points": "num_points", @@ -23,34 +40,30 @@ def get_energy_volume_curve(wf: Macro) -> None: "get_task_generator__vol_range": "vol_range", "get_task_generator__axes": "axes", "get_task_generator__strains": "strains", - "calc_with_calculator__calculator": "calculator", + "internal__calculator": "calculator", } - wf.outputs_map = {"fit__fit_dict": "fit_dict"} + wf.outputs_map = {"internal__fit_dict": "fit_dict"} @macro_node() def get_elastic_matrix(wf: Macro) -> None: wf.get_task_generator = get_elastic_matrix_task_generator() - wf.generate_structures = generate_structures(instance=wf.get_task_generator) - wf.calc_with_calculator = calc_with_calculator(task_dict=wf.generate_structures) - wf.fit = analyse_structures(instance=wf.get_task_generator, output_dict=wf.calc_with_calculator) + wf.internal = internal_macro(instance=wf.get_task_generator) wf.inputs_map = { "get_task_generator__structure": "structure", "get_task_generator__num_of_point": "num_of_point", "get_task_generator__eps_range": "eps_range", "get_task_generator__sqrt_eta": "sqrt_eta", "get_task_generator__fit_order": "fit_order", - "calc_with_calculator__calculator": "calculator", + "internal__calculator": "calculator", } - wf.outputs_map = {"fit__fit_dict": "fit_dict"} + wf.outputs_map = {"internal__fit_dict": "fit_dict"} @macro_node() def get_phonons(wf: Macro) -> None: wf.get_task_generator = get_phonons_task_generator() - wf.generate_structures = generate_structures(instance=wf.get_task_generator) - wf.calc_with_calculator = calc_with_calculator(task_dict=wf.generate_structures) - wf.fit = analyse_structures(instance=wf.get_task_generator, output_dict=wf.calc_with_calculator) + wf.internal = internal_macro(instance=wf.get_task_generator) wf.inputs_map = { "get_task_generator__structure": "structure", "get_task_generator__interaction_range": "interaction_range", @@ -59,6 +72,6 @@ def get_phonons(wf: Macro) -> None: "get_task_generator__dos_mesh": "dos_mesh", "get_task_generator__primitive_matrix": "primitive_matrix", "get_task_generator__number_of_snapshots": "number_of_snapshots", - "calc_with_calculator__calculator": "calculator", + "internal__calculator": "calculator", } - wf.outputs_map = {"fit__fit_dict": "fit_dict"} + wf.outputs_map = {"internal__fit_dict": "fit_dict"} From 27e35f1451582d2264b9d02245f97ce4729b2b22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Thu, 16 Nov 2023 07:49:56 +0100 Subject: [PATCH 5/7] black formatting --- .../atomistics_library/calculatornodes.py | 34 ++++++++----------- .../atomistics_library/macronodes.py | 6 ++-- .../atomistics_library/tasknodes.py | 16 ++++----- 3 files changed, 26 insertions(+), 30 deletions(-) diff --git a/pyiron_workflow/atomistics_library/calculatornodes.py b/pyiron_workflow/atomistics_library/calculatornodes.py index 3a5be22f..31175e24 100644 --- a/pyiron_workflow/atomistics_library/calculatornodes.py +++ b/pyiron_workflow/atomistics_library/calculatornodes.py @@ -6,12 +6,13 @@ @single_value_node("calculator") def get_emt(): from ase.calculators.emt import EMT + return EMT() @single_value_node("calculator") def get_abinit( - label='abinit_evcurve', + label="abinit_evcurve", nbands=32, ecut=10 * Ry, kpts=(3, 3, 3), @@ -19,6 +20,7 @@ def get_abinit( v8_legacy_format=False, ): from ase.calculators.abinit import Abinit + return Abinit( label=label, nbands=nbands, @@ -30,17 +32,10 @@ def get_abinit( @single_value_node("calculator") -def get_gpaw( - xc="PBE", - encut=300, - kpts=(3, 3, 3) -): +def get_gpaw(xc="PBE", encut=300, kpts=(3, 3, 3)): from gpaw import GPAW, PW - return GPAW( - xc=xc, - mode=PW(encut), - kpts=kpts - ) + + return GPAW(xc=xc, mode=PW(encut), kpts=kpts) @single_value_node("calculator") @@ -51,6 +46,7 @@ def get_quantum_espresso( kpts=(3, 3, 3), ): from ase.calculators.espresso import Espresso + return Espresso( pseudopotentials=pseudopotentials, tstress=tstress, @@ -72,6 +68,7 @@ def get_siesta( pseudo_qualifier="", ): from ase.calculators.siesta import Siesta + return Siesta( label=label, xc=xc, @@ -88,26 +85,23 @@ def get_siesta( @single_value_node("energy_dict") def calc_with_calculator(task_dict, calculator): from atomistics.calculators.ase import evaluate_with_ase - return evaluate_with_ase( - task_dict=task_dict, - ase_calculator=calculator - ) + + return evaluate_with_ase(task_dict=task_dict, ase_calculator=calculator) @single_value_node("lammps_potential_dataframe") def get_lammps_potential(potential_name, structure, resource_path): from atomistics.calculators.lammps import get_potential_dataframe - df_pot = get_potential_dataframe( - structure=structure, - resource_path=resource_path - ) + + df_pot = get_potential_dataframe(structure=structure, resource_path=resource_path) return df_pot[df_pot.Name == potential_name].iloc[0] @single_value_node("energy_dict") def get_lammps(task_dict, potential_dataframe): from atomistics.calculators.lammps import evaluate_with_lammps + return evaluate_with_lammps( task_dict=task_dict, potential_dataframe=potential_dataframe, - ) \ No newline at end of file + ) diff --git a/pyiron_workflow/atomistics_library/macronodes.py b/pyiron_workflow/atomistics_library/macronodes.py index 708c7eb0..1081f087 100644 --- a/pyiron_workflow/atomistics_library/macronodes.py +++ b/pyiron_workflow/atomistics_library/macronodes.py @@ -6,7 +6,7 @@ get_evcurve_task_generator, get_phonons_task_generator, analyse_structures, - generate_structures + generate_structures, ) @@ -20,7 +20,9 @@ def internal_macro(wf: Macro) -> None: wf.get_instance = get_instance() wf.generate_structures = generate_structures(instance=wf.get_instance) wf.calc_with_calculator = calc_with_calculator(task_dict=wf.generate_structures) - wf.fit = analyse_structures(instance=wf.get_instance, output_dict=wf.calc_with_calculator) + wf.fit = analyse_structures( + instance=wf.get_instance, output_dict=wf.calc_with_calculator + ) wf.inputs_map = { "get_instance__instance": "instance", "calc_with_calculator__calculator": "calculator", diff --git a/pyiron_workflow/atomistics_library/tasknodes.py b/pyiron_workflow/atomistics_library/tasknodes.py index 379f75eb..fbcadc4c 100644 --- a/pyiron_workflow/atomistics_library/tasknodes.py +++ b/pyiron_workflow/atomistics_library/tasknodes.py @@ -4,13 +4,10 @@ @single_value_node("task_generator") def get_elastic_matrix_task_generator( - structure, - num_of_point=5, - eps_range=0.05, - sqrt_eta=True, - fit_order=2 + structure, num_of_point=5, eps_range=0.05, sqrt_eta=True, fit_order=2 ): from atomistics.workflows.elastic.workflow import ElasticMatrixWorkflow + return ElasticMatrixWorkflow( structure=structure, num_of_point=num_of_point, @@ -24,13 +21,14 @@ def get_elastic_matrix_task_generator( def get_evcurve_task_generator( structure, num_points=11, - fit_type='polynomial', + fit_type="polynomial", fit_order=3, vol_range=0.05, - axes=['x', 'y', 'z'], - strains=None + axes=["x", "y", "z"], + strains=None, ): from atomistics.workflows.evcurve.workflow import EnergyVolumeCurveWorkflow + return EnergyVolumeCurveWorkflow( structure=structure, num_points=num_points, @@ -53,6 +51,7 @@ def get_phonons_task_generator( number_of_snapshots=None, ): from atomistics.workflows.phonons.workflow import PhonopyWorkflow + return PhonopyWorkflow( structure=structure, interaction_range=interaction_range, @@ -77,4 +76,5 @@ def generate_structures(instance): @single_value_node("structure") def get_bulk(element): from ase.build import bulk + return bulk(element, a=4.00, cubic=True) From c24815102711180a8cd9b4d5e25e7173870f7c70 Mon Sep 17 00:00:00 2001 From: liamhuber Date: Thu, 16 Nov 2023 11:54:04 -0800 Subject: [PATCH 6/7] Add `nodes: list[Node]` attribute to the node packages This is necessary for the creator to register the packages, and allows us to _not_ expose nodes which are only in the file for internal use. --- .../atomistics_library/calculatornodes.py | 12 ++++++++++++ pyiron_workflow/atomistics_library/macronodes.py | 6 ++++++ pyiron_workflow/atomistics_library/tasknodes.py | 10 ++++++++++ 3 files changed, 28 insertions(+) diff --git a/pyiron_workflow/atomistics_library/calculatornodes.py b/pyiron_workflow/atomistics_library/calculatornodes.py index 31175e24..0d56c37a 100644 --- a/pyiron_workflow/atomistics_library/calculatornodes.py +++ b/pyiron_workflow/atomistics_library/calculatornodes.py @@ -105,3 +105,15 @@ def get_lammps(task_dict, potential_dataframe): task_dict=task_dict, potential_dataframe=potential_dataframe, ) + + +nodes = [ + calc_with_calculator, + get_abinit, + get_emt, + get_gpaw, + get_lammps, + get_lammps_potential, + get_quantum_espresso, + get_siesta, +] diff --git a/pyiron_workflow/atomistics_library/macronodes.py b/pyiron_workflow/atomistics_library/macronodes.py index 1081f087..41affbad 100644 --- a/pyiron_workflow/atomistics_library/macronodes.py +++ b/pyiron_workflow/atomistics_library/macronodes.py @@ -77,3 +77,9 @@ def get_phonons(wf: Macro) -> None: "internal__calculator": "calculator", } wf.outputs_map = {"internal__fit_dict": "fit_dict"} + +nodes = [ + get_energy_volume_curve, + get_elastic_matrix, + get_phonons, +] diff --git a/pyiron_workflow/atomistics_library/tasknodes.py b/pyiron_workflow/atomistics_library/tasknodes.py index fbcadc4c..f07d0116 100644 --- a/pyiron_workflow/atomistics_library/tasknodes.py +++ b/pyiron_workflow/atomistics_library/tasknodes.py @@ -78,3 +78,13 @@ def get_bulk(element): from ase.build import bulk return bulk(element, a=4.00, cubic=True) + + +nodes = [ + analyse_structures, + generate_structures, + get_bulk, + get_elastic_matrix_task_generator, + get_evcurve_task_generator, + get_phonons_task_generator, +] From dab4659284c7ee9a8d1ae0a4cac37d617e658c5d Mon Sep 17 00:00:00 2001 From: pyiron-runner Date: Sun, 19 Nov 2023 16:38:38 +0000 Subject: [PATCH 7/7] Format black --- pyiron_workflow/atomistics_library/macronodes.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyiron_workflow/atomistics_library/macronodes.py b/pyiron_workflow/atomistics_library/macronodes.py index 41affbad..58698caa 100644 --- a/pyiron_workflow/atomistics_library/macronodes.py +++ b/pyiron_workflow/atomistics_library/macronodes.py @@ -78,6 +78,7 @@ def get_phonons(wf: Macro) -> None: } wf.outputs_map = {"internal__fit_dict": "fit_dict"} + nodes = [ get_energy_volume_curve, get_elastic_matrix,