Comments (6)
I submitted a pull request. I listed @liamhuber as an author in the notebook since most of the EMTJob code is from the discussion above/
from pyiron.
Hi @jkitchin, welcome to pyiron!
First: I had never thought of just slapping an ASE calculator onto a structure and making it a job -- that's absolutely brilliant. Pyiron team, I think we can make a whole family of jobs very quickly with this!
What you're trying to do is absolutely feasible and your example is not too far off. Murnhaghan is expecting some things your job doesn't have, and our "run" cycle is poorly documented and a bit more complex than overriding run
. Below is a working example that (I believe) accomplishes what you want, and I've tried to explain why I make each of the changes relative to your example code. It's also the case that Murn is not up-to-date with our latest storage practices, so I show a bit how I'd like to do it, as well as how it actually needs to be done right now.
from pyiron_base import PythonTemplateJob
from pyiron_atomistics import Project, Atoms
# Our Atoms inherit from ASE.Atoms, so you can use it directly
from ase.calculators.emt import EMT
class EMTJob(PythonTemplateJob):
def __init__(self, project, job_name):
super(EMTJob, self).__init__(project, job_name)
# The template job comes with `input` and `output` attributes that will
# handle all the (de)serialization for you
self.input.atoms = pr.atomistics.structure.bulk('Cu') # Or whatever default
# self.output.energy = None # Let's just populate the field for now
@property
def structure(self):
"""
'structure' is the canonical name for an `Atoms` object in pyiron.
The Murnhaghan job is expecting(?) a `structure` attribute on its input jobs.
"""
return self.input.atoms
@structure.setter
def structure(self, structure: Atoms):
if isinstance(structure, Atoms):
self.input.atoms = structure
else:
raise TypeError(f"Expected an Atoms object but got {type(structure)}")
def run_static(self):
"""
`run` is actually already a method higher up the job inheritence tree,
it does things like let the project know the job exists -- this is why you
weren't seeing the job in `job_table`.
What we actually want to define is `run_static`.
...This definitely needs to be better documented!!! (Actually, the whole
run paradigm needs some work to make it simpler and clearer, but documentation
would be a good enough start!)
"""
print("RUNNING")
self.structure.set_calculator(EMT())
self.output.energy = self.structure.get_potential_energy()
# With the output attribute, all we need to do is tell the job to
# write itself:
self.to_hdf()
# Buuuuut, the Murnhaghan job doesn't know about this functionality,
# so we still need to use the old-school way of writing directly to a
# particular place in the HDF. Note that Murnhaghan looks at "energy_pot"
# not just "energy". It also expects that value to be a list of energies.
# Murn is also expecting a (list of) volume(s) stored in a particular place,
# so we'll write that too
with self.project_hdf5.open("output/generic") as h5out:
h5out["energy_pot"] = [self.output.energy]
h5out["volume"] = [self.structure.get_volume()]
# Ok, now we're really done
self.status.finished = True
pr = Project('emt')
pr.remove_jobs(silently=True, recursive=True)
job = pr.create_job(job_type=EMTJob, job_name="Al_1")
job.structure = pr.atomistics.structure.bulk("Al")
job.run()
print(job.output.energy)
loaded = pr.load("Al_1")
print(loaded.output.energy)
# The job shows up in the job table, and can be loaded later
pr.remove_jobs(silently=True, recursive=True)
job = pr.create_job(job_type=EMTJob, job_name="Cu_1")
job.structure = pr.atomistics.structure.bulk("Cu")
murn = pr.atomistics.job.Murnaghan("murn")
murn.ref_job = job
murn.input["num_points"] = 5 # I just want it faster
murn.run()
murn.plot() # Looks right for me!
# Lastly I'll wipe everything from storage because this is just
# an example
pr.remove_jobs(silently=True, recursive=True)
pr.remove(enable=True)
from pyiron.
First: I had never thought of just slapping an ASE calculator onto a structure and making it a job -- that's absolutely brilliant. Pyiron team, I think we can make a whole family of jobs very quickly with this!
Did not we do this already? For example the GPAW
wrapper is implemented in this way.
https://github.com/pyiron/pyiron_atomistics/blob/main/pyiron_atomistics/gpaw/gpaw.py
class Gpaw(AseJob, GenericDFTJob):
@import_alarm
def __init__(self, project, job_name):
super(Gpaw, self).__init__(project, job_name)
self.input = GpawInput()
@property
def plane_wave_cutoff(self):
return self.input["encut"]
@plane_wave_cutoff.setter
def plane_wave_cutoff(self, val):
self.input["encut"] = val
def get_kpoints(self):
return self.input["kpoints"]
def _set_kpoints(
self,
mesh=None,
scheme="MP",
center_shift=None,
symmetry_reduction=True,
manual_kpoints=None,
weights=None,
reciprocal=True,
n_path=None,
path_name=None,
):
if scheme != "MP":
raise ValueError("Currently only MP is supported in the pyiron wrapper.")
if center_shift is not None:
raise ValueError("centershift is not implemented in the pyiron wrapper.")
if not symmetry_reduction:
raise ValueError(
"symmetry_reduction is not implemented in the pyiron wrapper."
)
if manual_kpoints is not None:
raise ValueError(
"manual_kpoints are not implemented in the pyiron wrapper."
)
if weights is not None:
raise ValueError("weights are not implemented in the pyiron wrapper.")
if not reciprocal:
raise ValueError("reciprocal is not implemented in the pyiron wrapper.")
if n_path is not None:
raise ValueError("n_path is not implemented in the pyiron wrapper.")
if path_name is not None:
raise ValueError("path_name is not implemented in the pyiron wrapper.")
self.input["kpoints"] = mesh
def set_calculator(self):
kpoints = self.input["kpoints"]
if isinstance(kpoints, str):
kpoints = self.input["kpoints"].replace("[", "").replace("]", "").split()
self._create_working_directory()
calc = GPAWcode(
mode=PW(float(self.input["encut"])),
xc=self.input["potential"],
occupations=MethfesselPaxton(width=float(self.input["sigma"])),
kpts=kpoints,
txt=self.working_directory + "/" + self.job_name + ".txt",
)
self.structure.calc = calc
def to_hdf(self, hdf=None, group_name=None):
"""
Store the ExampleJob object in the HDF5 File
Args:
hdf (ProjectHDFio): HDF5 group object - optional
group_name (str): HDF5 subgroup name - optional
"""
super(Gpaw, self).to_hdf(hdf=hdf, group_name=group_name)
with self.project_hdf5.open("input") as hdf5_input:
self.input.to_hdf(hdf5_input)
def from_hdf(self, hdf=None, group_name=None):
"""
Restore the ExampleJob object in the HDF5 File
Args:
hdf (ProjectHDFio): HDF5 group object - optional
group_name (str): HDF5 subgroup name - optional
"""
super(Gpaw, self).from_hdf(hdf=hdf, group_name=group_name)
with self.project_hdf5.open("input") as hdf5_input:
self.input.from_hdf(hdf5_input)
@jkitchin There are some functions which we try to unify for all DFT codes, like _set_kpoints()
but the important part happens in set_calculator()
where we set the parameter saved in the input class to the corresponding ASE calculator. In this example the separate to_hdf()
and from_hdf()
functions are still necessary to tell pyiron which information to store in the HDF5 file, but we are working on removing the need to define them explicitly, as illustrated by the example @liamhuber posted.
from pyiron.
Did not we do this already? For example the GPAW wrapper is implemented in this way.
Ah nice! I had never looked at the GPAW implementation. Seems like some low hanging fruit for adding a bunch of functionality. Might be well suited to an MPIE hackathon where they get new devs to learn by doing.
from pyiron.
Thanks for the pointers. Would you be interested in adding a notebook example on this in https://github.com/pyiron/pyiron/tree/main/notebooks?
from pyiron.
Thanks for the pointers. Would you be interested in adding a notebook example on this in https://github.com/pyiron/pyiron/tree/main/notebooks?
Yeah, I think that would be a nice addition 👍
from pyiron.
Related Issues (20)
- Restructure pyiron HOT 1
- How to modify "run_thermointdfteam_0.01_mpi.sh" in pyiron HOT 12
- outdated informations in the CONTRIBUTING.rst
- pyiron in binder - jupyter and jupyterlab extensions throw an error HOT 5
- submitted jobs disappeared in the queue list HOT 11
- pyiron inside pycharm: ValueError: Was not able to locate a periodic table HOT 5
- working in view_mode HOT 5
- Mailing list or chat room? HOT 1
- docker command is not correct HOT 1
- Documentation or Feature for Environment Use on Remote HOT 3
- Reporting a vulnerability HOT 1
- import pyiron error HOT 3
- Installation is confusing HOT 4
- Intrecting Potential is missing for Potassium Niobate(KNbO3) HOT 14
- Documentation is broken HOT 2
- Outdated (pr.create) commands in tutorials
- [Bug] The module index is currently broken
- Bug: .h5 file of remote job is transferred twice, but it is deleted after the first time HOT 12
- Lost kernels after creating a new conda environment
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pyiron.