Giter Club home page Giter Club logo

pyiron_atomistics's Introduction

pyiron

Coverage Status

Codacy Badge

Release_Date

Build Status

Downloads

Documentation Status

Screenshot of pyiron running inside jupyterlab.

pyiron - an integrated development environment (IDE) for computational materials science. It combines several tools in a common platform:

  • Atomic structure objects – compatible to the Atomic Simulation Environment (ASE).
  • Atomistic simulation codes – like LAMMPS and VASP.
  • Feedback Loops – to construct dynamic simulation life cycles.
  • Hierarchical data management – interfacing with storage resources like SQL and HDF5.
  • Integrated visualization – based on NGLview.
  • Interactive simulation protocols - based on Jupyter notebooks.
  • Object oriented job management – for scaling complex simulation protocols from single jobs to high-throughput simulations.

pyiron (called pyron) is developed in the Computational Materials Design department of Joerg Neugebauer at the Max Planck Institut für Eisenforschung (Max Planck Institute for iron research). While its original focus was to provide a framework to develop and run complex simulation protocols as needed for ab initio thermodynamics it quickly evolved into a versatile tool to manage a wide variety of simulation tasks. In 2016 the Interdisciplinary Centre for Advanced Materials Simulation (ICAMS) joined the development of the framework with a specific focus on high throughput applications. In 2018 pyiron was released as open-source project. See the Documentation page for more details.

Note

pyiron: This is the documentation page for the pyiron meta package, that combines the other packages in a common interface. The API documentation for pyiron_base and pyiron_atomistics are available as separate pages.

Installation

You can test pyiron on Mybinder.org (beta). For a local installation we recommend to install pyiron inside an anaconda environment:

conda install -c conda-forge pyiron

After the installation of pyiron you need to configure pyiron. The default configuration can be generated automatically. Start a new Python session and import pyiron:

> import pyiron
> pyiron.install()
>>> It appears that pyiron is not yet configured, do you want to create a default start configuration (recommended: yes). [yes/no]:
> yes
> exit()

See the Documentation-Installation page for more details.

Example

After the successful configuration you can start your first pyiron calculation. Navigate to the the projects directory and start a jupyter notebook or jupyter lab session correspondingly:

cd ~/pyiron/projects
jupyter notebook

Open a new jupyter notebook and inside the notebook you can now validate your pyiron calculation by creating a test project, setting up an initial structure of bcc Fe and visualize it using NGLview:

from pyiron import Project
pr = Project('test')
structure = pr.create_structure('Fe', 'bcc', 2.78)
structure.plot3d()

Finally a first lammps calculation can be executed by:

job = pr.create_job(job_type=pr.job_type.Lammps, job_name='lammpstestjob')
job.structure = structure
job.potential = job.list_potentials()[0]
job.run()

Getting started:

Test pyiron with mybinder:

mybinder

License and Acknowledgments

pyiron is licensed under the BSD license.

If you use pyiron in your scientific work, please consider citing :

@article{pyiron-paper,
  title = {pyiron: An integrated development environment for computational materials science},
  journal = {Computational Materials Science},
  volume = {163},
  pages = {24 - 36},
  year = {2019},
  issn = {0927-0256},
  doi = {https://doi.org/10.1016/j.commatsci.2018.07.043},
  url = {http://www.sciencedirect.com/science/article/pii/S0927025618304786},
  author = {Jan Janssen and Sudarsan Surendralal and Yury Lysogorskiy and Mira Todorova and Tilmann Hickel and Ralf Drautz and Jörg Neugebauer},
  keywords = {Modelling workflow, Integrated development environment, Complex simulation protocols},
}

pyiron_atomistics's People

Contributors

ahmed-aslam avatar ahmedabdelkawy avatar alaukiksaxena avatar codacy-badger avatar dependabot-preview[bot] avatar dependabot[bot] avatar dgehringer avatar feloch avatar freyso avatar github-actions[bot] avatar jan-janssen avatar kuhnmn avatar leimeroth avatar liamhuber avatar ligerzero-ai avatar max-hassani avatar niklassiemer avatar pmrv avatar prince-mathews avatar pyiron-runner avatar pyironlandingpage avatar raynol-dsouza avatar samwaseda avatar sanderborgmans avatar skatnagallu avatar srmnitc avatar sudarsan-surendralal avatar t-brink avatar usaikia avatar zendegani avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyiron_atomistics's Issues

changing input parameter in sphinx

Summary

as initial parameter in sphinx for field evaporation calculation but I can not do it see below

pyiron Version and Platform

I used latest version of pyiron in cloud
Expected Behavior

I try to do field evaporation calculation and want to set to initial parameter as input (charge and z) same as

  • [ https://github.com/pyiron/pyiron/pull/592]
    job.input.sphinx.initialGuess.rho.charged={"charge": charge, "z": bottom}

I was expecting to this dictionary put charge and z coordinate in initial input

Actual Behavior

however I think it is work in literal way i.e. it is adding what I wrote in dictionary. as actual error that I got in log file is
"""Illegal character '{' in ./input.sx:256."""
and when I look at in input file I have

charged = {'charge': 1.1242386117856127, 'z': 10.000000000000004};

I also try below line
job.input.sphinx.initialGuess.rho.set_group("charged",{"charge":charge ,"z":bottom})
but still I have same error massage

Steps to Reproduce

Further Information, Files, and Links

Difference between _key_from_property and _lst_from_property?

Does anyone with interactive experience know what the difference between these two functions is?

def _lst_from_property(self, key, prop=None):

def _key_from_property(self, key, prop):

They seem do to the same to me, so if I don't hear from you I'll throw one of them under the bus.

Atomic spins could be an attribute

Right now we need structure.set_initial_magnetic_moment(*args, **kwargs) to add spins to our atomic structures. But spin is just a per-atom property like position -- can we just set these as an attribute, e.g.

structure = pr.create.structure.ase_bulk('Fe', cubic=True)
print(structure.spins)
>>> None

structure.spins = [0.1, 0.5]
# Runs a regular magnetic calculation

structure.spins = np.array([
    [0., 0., 0.1],
    [0.1, 0., 0.]
])
# Runs non-collinear magnetism

Moving yaff and quickff to pyiron_gpl

@SanderBorgmans Based on the strict interpretation of the GPL license it is not allowed to include a GPL library in an BSD licensed project. This is solved by the LGPL. So my suggestion would be to migrate yaff and quickff to pyiron_gpl. From the user side nothing changes as long as you import pyiron, because both pyiron_atomistics and pyiron_gpl are loaded in the background when they are installed. But when the user only loads pyiron_atomistics they have to separately import pyiron_gpl.

unwrapped_positions

I have a question rather than an issue. For an 128 atom BCC Ti, If I plot the positions of atoms, I get the figure below:
wrapped

If I plot the 'unwrapped_positions' I get this figure:

unwrapped

Wrapped positions should be within the cell and as a result I find these plots strange. I am suspicious that
'output/generic/positions' gives the unwrapped positions and
'output/generic/unwrapped_positions' gives the wrapped positions Which should be the opposite

Any comment is much appreciated.

Calling list_potentials() multiple times gives longer list every time

Summary

Calling list_potentials on a lammps job increases the list of available potentials every time it is called.

pyiron Version and Platform

POTENTIALS workshop environment.

Steps to Reproduce

Create a lammps job and call list_potentials a few times

j = pr.create.job.Lammps("a")
print(len(j.list_potentials()))
print(len(j.list_potentials()))
print(len(j.list_potentials()))
print(len(j.list_potentials()))

Number of atoms not allowed to change?

I realized that the following lines don't work, because the number of atoms changes:

lmp = pr.create_job('Lammps', 'lmp')
lmp.structure = pr.create_structure('Al', 'fcc', 4.)
lmp.potential = lmp.list_potentials()[0]
lmp.calc_static()
lmp.interactive_open()
lmp.run()
del lmp.structure[1]
lmp.run()

Is it supposed to be like this?

Changing the number of atoms in a structure

Updating the number of atoms in a structure no longer works - presumably since we switched to ASE structures, but it is required for example for interactive jobs running monte carlo simulation:
https://github.com/pyiron/pyiron_atomistics/blob/master/pyiron_atomistics/atomistics/job/interactive.py#L271

Here is an example code that worked previously:

struct = pr.create_ase_bulk("Al")
struct.indices = np.array([0, 0])
struct.positions = np.array([[0, 0, 0], [1, 1, 1]])

Now the last line fails with:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-8-66e6ff27ba8e> in <module>
----> 1 struct.positions = np.array([[0, 0, 0], [1, 1, 1]])

/srv/conda/envs/notebook/lib/python3.7/site-packages/ase/atoms.py in _set_positions(self, pos)
   1932     def _set_positions(self, pos):
   1933         """Set positions directly, bypassing constraints."""
-> 1934         self.arrays['positions'][:] = pos
   1935 
   1936     positions = property(_get_positions, _set_positions,

ValueError: could not broadcast input array from shape (2,3) into shape (1,3)

This function is required for fitting a lennard Jones potential with scipy which we have currently planned for the up coming workshop.

Lammps error when using openkim potentials

Summary

Lammps jobs abort when using openkim potentials

pyiron Version and Platform
conda to install dependencies, pyiron in recent git version

Expected Behavior
jobs with kim potentials run like jobs with other potentials

Actual Behavior
Lammps throws an error like this one:

2021-01-20 10:57:54,629 - pyiron_log - WARNING - Job aborted
2021-01-20 10:57:54,630 - pyiron_log - WARNING - LAMMPS (24 Dec 2020)
Reading data file ...
  orthogonal box = (0.0000000 0.0000000 0.0000000) to (3.6000000 3.6000000 3.6000000)
  1 by 1 by 1 MPI processor grid
  reading atoms ...
  4 atoms
  read_data CPU = 0.000 seconds
ERROR: Must use 'kim_init' command before simulation box is defined (src/KIM/kim_init.cpp:87)
Last command: kim_init SNAP_ZuoChenLi_2019_Cu__MO_931672895580_000 metal

2021-01-20 10:57:54,790 - pyiron_log - WARNING - Job aborted
2021-01-20 10:57:54,791 - pyiron_log - WARNING - LAMMPS (24 Dec 2020)
Reading data file ...
  orthogonal box = (0.0000000 0.0000000 0.0000000) to (3.6000000 3.6000000 3.6000000)
  1 by 1 by 1 MPI processor grid
  reading atoms ...
  4 atoms
  read_data CPU = 0.000 seconds
ERROR: Must use 'kim_init' command before simulation box is defined (src/KIM/kim_init.cpp:87)
Last command: kim_init SNAP_ZuoChenLi_2019quadratic_Cu__MO_265210066873_000 metal

Steps to Reproduce
Try to run a lammps job with a potential that states kim_init in config

Further Information, Files, and Links

Maybe openkim potentials have to be used in another way, if thats the case it would help to improve the error message.

Also I am not sure if this should be here (pyiron_atomistics) or in the pyiron issues?

"create_ase_bulk" does not work with Mn bcc

Summary

The creation of the structure using "create_ase_bulk" for Vasp works well for many bcc elements (Fe, Cr, etc.) but fails for Mn.

The error could be reproduced by this way:

from pyiron import Project
pr = Project("Mn_fix")

# Works well
job = pr.create_job(pr.job_type.Vasp, "Fe_test")
job.structure = pr.create_ase_bulk(name="Fe", a=3.02, crystalstructure="bcc")

# Error
job = pr.create_job(pr.job_type.Vasp, "Mn_test")
job.structure = pr.create_ase_bulk(name="Mn", a=3.02, crystalstructure="bcc")

The error log

<ipython-input-33-55709a86525c> in <module>
     10 
     11 job = pr.create_job(pr.job_type.Vasp, "Mn_test")
---> 12 job.structure = pr.create_ase_bulk(name="Mn", a=3.02, crystalstructure="bcc")

/u/system/SLES12/soft/pyiron/dev/anaconda3/lib/python3.7/site-packages/pyiron_atomistics/project.py in create_ase_bulk(self, name, crystalstructure, a, c, covera, u, orthorhombic, cubic)
    443         # )
    444         return self.create.structure.ase.bulk(name=name, crystalstructure=crystalstructure, a=a, c=c,
--> 445                                               covera=covera, u=u, orthorhombic=orthorhombic, cubic=cubic)
    446 
    447     def create_structure(self, element, bravais_basis, lattice_constant):

/u/system/SLES12/soft/pyiron/dev/anaconda3/lib/python3.7/site-packages/pyiron_atomistics/atomistics/structure/factories/ase.py in wrapper(*args, **kwargs)
     42         def wrapper(*args, **kwargs):
     43             s.publication_add(publication_ase())
---> 44             return func(*args, **kwargs)
     45         wrapper.__doc__ = _ase_header(ase_func) + wrapper.__doc__
     46         return wrapper

/u/system/SLES12/soft/pyiron/dev/anaconda3/lib/python3.7/site-packages/pyiron_atomistics/atomistics/structure/factories/ase.py in bulk(self, *args, **kwargs)
     51     @_ase_wraps(ase_bulk)
     52     def bulk(self, *args, **kwargs):
---> 53         return ase_to_pyiron(ase_bulk(*args, **kwargs))
     54 
     55     @_ase_wraps(ase_cut)

/u/system/SLES12/soft/pyiron/dev/anaconda3/lib/python3.7/site-packages/ase/build/bulk.py in bulk(name, crystalstructure, a, b, c, alpha, covera, u, orthorhombic, cubic, basis)
     79             # then. We used to just return the cubic one but that must
     80             # have been wrong somehow.  --askhl
---> 81             raise RuntimeError('Only simple cubic ("sc") supported')
     82 
     83     # Mapping of name to number of atoms in primitive cell.

RuntimeError: Only simple cubic ("sc") supported

I will appreciate any help with this.

Warning when expected memory potentially too large

It occurred to me several times that I submit a LAMMPS job for a relatively large structure with a relatively large number of steps and I surpass the memory limit. In the case of MPIE cluster, this forces all simulations to stop since there wouldn't be any update to the output anymore. This problem is mostly avoided in the traditional LAMMPS calculations, because there we have to specify the frequency of output, which in pyiron we don't have to. I think it makes sense to issue a warning if the number of data points to collect times the number of atoms becomes larger than a certain value. What do you guys think?

Automatic triclinic boxes in LAMMPS?

When I run a LAMMPS simulation with a barostat and I also apply a barostat to shear components, the simulation can fail when the input simulation cell is orthogonal:

job2 = pr.create_job(pr.job_type.Lammps, "test2")
job2.structure = <something orthogonal>
job2.potential = ...
job2.calc_md(
    temperature=1000.0,
    temperature_damping_timescale=100.0,
    pressure=[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
    pressure_damping_timescale=500.0,
    time_step=1.0,
    n_ionic_steps=100000,
)

The reason is that LAMMPS needs to be told if shear of a box is allowed. The command is change_box all triclinic. Shouldn't this command be added automatically when applying a barostat with shear components?

Can I submit an interactive job?

I have a few thousand structures that I want to put through Lammps. I could use a StructureListMaster, but I thought it's more convenient to use an interactive job and keep changing the structure (since I have the same number of atoms/alloying atoms).

I used the following snippet, but the job ends up running on the login node.

j = pr.create.job.Lammps('gb_110_n4', delete_existing_job=True)
j.potential = pr.data.potential

j.server.queue = 'cm'
j.server.cores = 4
j.server.run_time = 60 * 60 * 2

j.interactive_open()

from itertools import combinations

n = 4
for I in combinations(np.where(find_sites(gbr)!=-1)[0], n):
    if not ( (gbr.cell[1, 1] * 1/4 < gbr.positions[I, 1]) & (gbr.positions[I, 1] < gbr.cell[1, 1] * 3/4) ).all(): continue
    j.structure = gbr.copy()

    for i in I:
        j.structure[i] = 'Al'
    j.calc_minimize(pressure=0)
    j.input.control.energy_pot_per_atom()
    j.run()

j.interactive_close()

How to cite papers in docstrings

I know that pyiron has the feature to show all papers involved, but I'd like to talk about more practical cases, namely when the user wants to see the original paper quickly. I just wanted to raise this point briefly in order to share the common base with everyone.

The specific example below is related to set_mixing_parameter in VASP and SPHInX, where we use either the linear (aka Kerker) mixer or the Pulay mixer. The docstring for the Pulay mixer will look like "The Pulay mixer scheme is given by the equation blablabla - for more info, cf. XXX". And for XXX, I'm wondering which one to put:

I was going for the first one. What do you think?

vasp import gives warnings

For some VASP results imported, it gives the following error when reading it:

pr['job_9']
/Users/xxx/opt/anaconda3/lib/python3.7/site-packages/h5io/_h5io.py:610: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray
return np.array(array_restore)
{'groups': ['input', 'output'], 'nodes': ['HDF_VERSION', 'NAME', 'TYPE', 'VERSION', 'server', 'status']}

plot3d vector field broken with triclinic unit cells

Summary

Arrows are drawn incorrectly when plotting a structure + vector field with a triclinic cells.

Not sure if this our bug or NGLView's, skimming the plot3d I at least didn't see anything suspicious. Anyone more familiar with that?

pyiron Version and Platform

d9145e6 @ garching

Expected Behavior

Arrows should be rooted at atomic coordinates

Actual Behavior

Arrows roots seem to be inverted, so screens below.

Steps to Reproduce

Create a non-cubic structure with ase and plot any vector field.
vector
vector2

"import pyiron.atomistics" does not work

Summary

A simple cell containing "import pyiron.atomistics" does not work, providing the following error:
ImportError: cannot import name 'gaussian' from 'pyiron_atomistics' (/u/system/SLES12/soft/pyiron/dev/anaconda3/lib/python3.7/site-packages/pyiron_atomistics/init.py)

pyiron_atomistics.file:
'/u/system/SLES12/soft/pyiron/dev/anaconda3/lib/python3.7/site-packages/pyiron_atomistics/init.py'

Please can I have some help?

ase_to_pyiron is slow

I'm currently importing a large number of ase structures into a structure container and have noticed it is exceedingly slow. Importing 1000 structures takes ~40s, 10000 ~4min or longer. After some profiling I identified ase_to_pyiron and this line

el_object_list = [self.convert_element(el) for el in element_list]

as the culprits. It seems for the element conversion mendelev consults some kind of SQL database (???) that takes a lot of time. Can I skip this conversion somehow?

Regular Lammps output ends up in error.out of master jobs

Summary

I'm running a parallel master job, that spawns a few lammps jobs. The lammps jobs finish correctly, but when I check the error.out of the master (for an unrelated error), somehow the normal lammps output of the children is in there, which makes it harder to find the actual error. Curiously the error.out of the children are empty.

pyiron Version and Platform

'0.3.20.post.dev20', still pre-atomistic split-off, but I'll assume this is not something recently touched.

Expected behavior

The error.out file should only keep error logs.

I don't know how lammps works, but is it possible that it writes its log to stderr?

-partition possible?

On this page, there's an example for Parallel Replica Dynamics with LAMMPS. Here, I see the command:

mpirun -np 4 lmp_g++ -partition 4x1 -in in.prd

I wonder whether -partition is available in pyiron. This should be analogous to NEB. If not, is there a good way to incorporate it?

lammps job with other executable crashes

Summary
Dear all,

I have a problem running my own lammps executable on the hpc with pyiron. I was not sure where to post it, hopefully it is fine here. I try to adapt one of the sh files in the bin folder to run pyiron jobs with my own executable (I need this because I included a new fix). When I try to run the job it crashes immediately. I use the same submission command for lammps jobs without pyiron and there it works.
(I also tried to submit it with mpiexec but it is still crashing, if necessary I can post the backtrace)

Maybe someone can confirm this or tell me what is going wrong?

Thanks in advance!

pyiron Version and Platform

pyiron - 0.4.3

Expected Behavior
It works.

Actual Behavior
The job fails.

Steps to Reproduce
I copied one of the sh files inside the bin folder, loaded the module and adapted the submission command:

#!/bin/bash
module load pyiron/dev
module load lammps/3Mar20
srun -n $1 lmp_serial.cmfe -in control.inp

When the jobs starts, it crashes immediately and the error.msg says:

srun: error: Invalid numeric value "lmp_serial.cmfe" for --ntasks.

and I find in the error.out:

Traceback (most recent call last):
  File "/u/system/SLES12/soft/pyiron/dev/anaconda3/lib/python3.7/site-packages/pyiron_base/job/generic.py", line 724, in run_static
    universal_newlines=True,
  File "/u/system/SLES12/soft/pyiron/dev/anaconda3/lib/python3.7/subprocess.py", line 411, in check_output
    **kwargs).stdout
  File "/u/system/SLES12/soft/pyiron/dev/anaconda3/lib/python3.7/subprocess.py", line 512, in run
    output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command '/u/deissei/pyiron-resources-cmmc/lammps/bin/run_lammps_2021_flo.sh' returned non-zero exit status 1.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/u/system/SLES12/soft/pyiron/dev/anaconda3/lib/python3.7/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/u/system/SLES12/soft/pyiron/dev/anaconda3/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/u/system/SLES12/soft/pyiron/dev/anaconda3/lib/python3.7/site-packages/pyiron_base/cli/__main__.py", line 2, in <module>
    main()
  File "/u/system/SLES12/soft/pyiron/dev/anaconda3/lib/python3.7/site-packages/pyiron_base/cli/__init__.py", line 61, in main
    args.cli(args)
  File "/u/system/SLES12/soft/pyiron/dev/anaconda3/lib/python3.7/site-packages/pyiron_base/cli/wrapper.py", line 39, in main
    submit_on_remote=args.submit
  File "/u/system/SLES12/soft/pyiron/dev/anaconda3/lib/python3.7/site-packages/pyiron_base/job/wrapper.py", line 149, in job_wrapper_function
    job.run()
  File "/u/system/SLES12/soft/pyiron/dev/anaconda3/lib/python3.7/site-packages/pyiron_base/job/wrapper.py", line 115, in run
    self.job.run_static()
  File "/u/system/SLES12/soft/pyiron/dev/anaconda3/lib/python3.7/site-packages/pyiron_base/job/generic.py", line 757, in run_static
    raise RuntimeError("Job aborted")
RuntimeError: Job aborted

I checked if this could be a problem of the run_queue.sh but ntasks equals one as it should.

Further Information, Files, and Links

Child jobs of ParallelMaster

Original Issue
As discussed in #197 ParallelMaster jobs don't know about their child jobs when submitting them to a remote queue. I decided to open another issue for this since it is completely unrelated to the problem with ElasticTensor jobs.
I thought there must have been some change to the Class since it used to work before, but maybe I was wrong with that.
After revisiting some old notebooks I noticed that child jobs are created and submitted individually when a queue is assigned to the ref job, but not to the master job, which is probably what I always did. If a queue is specified for the master job it get's submitted and child jobs are created on the remote cluster, so their IDs are lost when fetching them back to the local system.

As suggested by @liamhuber I had a look at the _run_if_master_modal_child_non_modal function, but as far as I can tell all the Master run functions are called after the job is transferred to the cluster so any change in them won't have an effect in the local database, so I am somewhat lost where this can be fixed without messing up the installation of everyone running a different setup.

Update
pyiron/pyiron_base#329 fixes the problem when the master job finishes. The issue persists if the master job itself fails. It is unclear yet what happens if a child job fails.

Quasi Harmonic Job difficult to use

I recently talked about the doc string of the quasi harmonic job, but I think there are still following points that I would like to raise (you have to have run a QHA job, otherwise it's probably difficult to follow what I say below):

  • Most of the people want a quick insight into the temperature dependence and are not badly concerned about small details (meaning I don't think people want to change more than what can be done in the input)
  • Creation of phonopy between QHA and MS is not quite intuitive
  • It requires an independent Murnaghan job, even though hardly any input parameter is allowed to be independent (number of points, volume range etc.)
  • Not clear why the temperature range has to be given beforehand in the input (and indeed I usually change it afterwards) -> This step might force the user to do an unnecessary interpolation of the free energy interpolation.
  • Retrieving the output quantities as well as the temperatures not very intuitively clear.

Ideally for me it should look like this:

pr = Project('QHA')
lmp = pr.create_job('Lammps', 'lmp')
lmp.structure = structure_of_your_choice
lmp.potential = potential_of_your_choice
qha = lmp.create_job('QuasiHarmonicJob', 'qha')
qha.run()

output = qha.get_output(temperature=temperatures_of_my_choice)

and output is a dictionary containing all the quantities. QHA in this case should then create both Murnaghan and Phonopy, in which it is guaranteed that all the input parameters are compatible.

Of course I could have done all this without opening an issue, but since the workflow above is already different from what's in place and the input structure would also change, there'll be no backward compatibility. So I would like to ask you for suggestions.

How to run Sphinx with Murnaghan on the Queue?

I'm trying to run some simple Murnaghan with sphinx on the cluster, but something with writing the input is broken. The following snippet runs fine on the login node, but not when submitted

j = pr.create.job.Sphinx("ref")
j.structure = pr.create.structure.bulk('Mg')

j.input.EnCut = ...

m = j.create_job(j.job_type.Murnaghan, "murn_default", delete_existing_job=True)
m.input

m.server.queue = 'cm'
m.server.cores = 4
m.server.run_time = 60

m.run()

The output from sphinx is

+-----------------------------------------------------------------------------
| Abnormal program stop in file /u/cfrey/devel/sphinx/sxaccelerate/src/io/SxSymbolTable.cpp at line 1728.
+-----------------------------------------------------------------------------
srun: error: cmti005: task 0: Exited with exit code 1
srun: Terminating job step 2170288.5
tail: cannot open 'eps*' for reading: No such file or directory
tail: cannot open 'eps*' for reading: No such file or directory

    file ./input.sx at line 27
    Validation error in group 'basis'!
>>> Missing item 'eCut'.

+-----------------------------------------------------------------------------
| Abnormal program stop in file /u/cfrey/devel/sphinx/sxaccelerate/src/io/SxSymbolTable.cpp at line 1728.
+-----------------------------------------------------------------------------
mv: cannot stat 'tdos.dat': No such file or directory

Anyone run into this before?

EDIT: The exact same setup works with VASP, so I think it's something we should fix.

substituting atoms in pyiron

Hi all,

I am trying to substitute a Mg atom with an Al atom.

I tried the following

bulk_structure = pr.create_ase_bulk(metal_name, crystalstructure='hcp', a=a_calc, c=c_calc)
print ('Initial symbols are', bulk_structure.symbols)
bulk_structure.symbols[0] = 'Al'
print ('Updated symbols are', bulk_structure.symbols)
print (bulk_structure[0])
bulk_structure.plot3d()
Initial symbols are Mg2
Updated symbols are AlMg
element: [None, AtomicNumber                      12
AtomicRadius                     145
AtomicMass                    24.305
Color                         Silver
CovalentRadius                  1.41
CrystalStructure     SimpleHexagonal
Density                         1738
DiscoveryYear                   1755
ElectronAffinity                   0
Electronegativity               1.31
Group                              2
Name                       magnesium
Period                             3
Phase                          Solid
StandardName               Magnesium
VanDerWaalsRadius                173
MeltingPoint                     923
Abbreviation                      Mg
tags                              {}
Name: Mg, dtype: object]

Capture

Clearly, only the symbols list is getting updated and not the actual atoms as can be seen from both the pic and the printed array. I checked the POSCAR as well, both atoms have not changed from Mg.

So, I tried the ase way

from ase.build import bulk
bulk_structure = bulk(metal_name, crystalstructure='hcp', a=a_calc, c=c_calc) # bulk function from ase
print ('Initial symbols are', bulk_structure.symbols)
bulk_structure.symbols[0] = 'Al'
print ('Updated symbols are', bulk_structure.symbols)
bulk_structure = ase_to_pyiron(bulk_structure)
print (bulk_structure[0])
bulk_structure.write('POSCAR_ase_way')
bulk_structure.plot3d()
Initial symbols are Mg2
Updated symbols are AlMg
element: [None, AtomicNumber                       13
AtomicRadius                      118
AtomicMass                    26.9815
Color                          Silver
CovalentRadius                   1.21
CrystalStructure     FaceCenteredCubi
Density                          2700
DiscoveryYear                    1825
ElectronAffinity                 42.5
Electronegativity                1.61
Group                              13
Name                         aluminum
Period                              3
Phase                           Solid
StandardName                 Aluminum
VanDerWaalsRadius                   0
MeltingPoint                  933.473
Abbreviation                       Al
tags                               {}
Name: Al, dtype: object]

Capture_2

So, it can be seen that the atom at the 0th index is updated to Al from the printed array and the pic. I checked the POSCAR as well, the atom at the 0th index has changed from Mg to Al. It appears that the ase method is working for substituting the atoms.
So, am I better off just using ase to generate structures and converting them using "ase_to_pyiron", as the functions associated with pyiron structures lack functionality?
Thanks.

Structure methods could treat PBC better

Summary

There are many methods of Atoms that rely on periodic boundary conditions, but when these are set partially or completely to False, they misbehave silently. That they behave differently than intended is expected is totally fair, but it let's make the results more transparent.

Example

Here, we play with wrap and see that without PBC it simply silently does nothing

struct = pr.create.structure.ase_bulk('Al', cubic=True)
struct.positions[0] += struct.cell[0, 0]
struct.wrap()
print(struct.positions[0, 0])
>>> 2.364662249426745e-16
struct.pbc = [False, False, False]
struct.positions[0] += struct.cell[0, 0]
struct.wrap()
print(struct.positions[0, 0])
>>> 4.05

Proposed solution

I think it would be nice to have a @needs_pbc decorator which we can thrown on any method that needs PBC to function. This decorator could check the structure's PBC and if it doesn't match the requirement (all True by default, but maybe the decorator can take an optional argument to allow other combos). If the PBC match, the decorator returns the method result as normal. If they don't match, the decorator returns None and throws a warning stating what PBC are required and what are present.

Anyone want to implement this? 😸

Elastic tensor and child jobs when submitting

Also see updates 1 and 2 below, issues seems to be the storage of pressure in vasp jobs
Summary

ElasticTensor jobs fail for me when I submit them to our remote cluster.
I am not really sure but I think this could be related to some other weird behavior which I noticed that affects all AtomisticParallel jobs. When I submitted Murnaghan jobs with old pyiron versions (not sure which ones) each child job was given an id and stored in the local database, then each job was submitted to the cluster. Now only the master job is stored in the local database and submitted to the cluster. This has the side effect that the child_ids attribute is an empty list, maybe this causes the issue?
Murnaghan jobs still work, even if there child_ids is empty, so maybe something else causes the problem.

pyiron Version and Platform

Newest pyiron versions from git.

Steps to Reproduce

Submit a ElasticTensor job to a remote cluster.

Error message

  File "/home/nl77pupy/miniconda3/lib/python3.8/runpy.py", line 194, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/home/nl77pupy/miniconda3/lib/python3.8/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/home/nl77pupy/git_projects/pyiron_base/pyiron_base/cli/__main__.py", line 2, in <module>
    main()
  File "/home/nl77pupy/git_projects/pyiron_base/pyiron_base/cli/__init__.py", line 61, in main
    args.cli(args)
  File "/home/nl77pupy/git_projects/pyiron_base/pyiron_base/cli/wrapper.py", line 34, in main
    job_wrapper_function(
  File "/home/nl77pupy/git_projects/pyiron_base/pyiron_base/job/wrapper.py", line 149, in job_wrapper_function
    job.run()
  File "/home/nl77pupy/git_projects/pyiron_base/pyiron_base/job/wrapper.py", line 115, in run
    self.job.run_static()
  File "/home/nl77pupy/git_projects/pyiron_base/pyiron_base/master/parallel.py", line 678, in run_static
    self._run_if_master_modal_child_non_modal(job=job)
  File "/home/nl77pupy/git_projects/pyiron_base/pyiron_base/master/parallel.py", line 657, in _run_if_master_modal_child_non_modal
    self.run()  # self.run_if_collect()
  File "/home/nl77pupy/git_projects/pyiron_base/pyiron_base/generic/util.py", line 213, in decorated
    return function(*args, **kwargs)
  File "/home/nl77pupy/git_projects/pyiron_base/pyiron_base/job/generic.py", line 670, in run
    self._run_if_collect()
  File "/home/nl77pupy/git_projects/pyiron_base/pyiron_base/master/parallel.py", line 488, in _run_if_collect
    self.collect_output()
  File "/home/nl77pupy/git_projects/pyiron_atomistics/pyiron_atomistics/atomistics/master/elastic.py", line 525, in collect_output
    elastic_tensor, score = calc_elastic_tensor(
  File "/home/nl77pupy/git_projects/pyiron_atomistics/pyiron_atomistics/atomistics/master/elastic.py", line 274, in calc_elastic_tensor
    coeff, score = _fit_coeffs_with_stress(
  File "/home/nl77pupy/git_projects/pyiron_atomistics/pyiron_atomistics/atomistics/master/elastic.py", line 106, in _fit_coeffs_with_stress
    stress = _convert_to_voigt(stress, rotations=rotations, strain=False)
  File "/home/nl77pupy/git_projects/pyiron_atomistics/pyiron_atomistics/atomistics/master/elastic.py", line 79, in _convert_to_voigt
    s_tmp = np.einsum('nik,mkl,njl->nmij',
  File "<__array_function__ internals>", line 5, in einsum
  File "/home/nl77pupy/miniconda3/lib/python3.8/site-packages/numpy/core/einsumfunc.py", line 1361, in einsum
    return c_einsum(*operands, **kwargs)
ValueError: einstein sum subscripts string contains too many subscripts for operand 1

Trouble importing aborted vasp jobs into pyiron

Hello,

I am having trouble importing aborted jobs into pyiron.

# importing job
path_to_import = temp_job_files_pr.path
temp_update_pr.import_from_path(path=path_to_import, recursive=True, copy_raw_files=True)
temp_update_pr.job_table()
	id	status	chemicalformula	job	subjob	projectpath	project	timestart	timestop	totalcputime	computer	hamilton	hamversion	parentid	masterid
2	14770767	aborted	Ca2Mg22Ne4	Mg_Ca_0_5_0	/Mg_Ca_0_5_0	/cmmc/u/	skanchar/pyiron/projects/research/Mg_surfaces_solid_solns/Ca_solid_solns/Ca_in_Mg_0001_surface/Ne_electrode/2_by_2/Ca_in_Mg_0001_with_Ne/asym_slabs_without_tags_and_damped_algo/surface_level_1/sur...	2021-05-21 17:55:03.966883	None	None	skanchar@cmti001#1	Vasp	5.4.4	None	None
3	14770768	aborted	Mg24Ne4	Mg_Ca_0_0_0	/Mg_Ca_0_0_0	/cmmc/u/	skanchar/pyiron/projects/research/Mg_surfaces_solid_solns/Ca_solid_solns/Ca_in_Mg_0001_surface/Ne_electrode/2_by_2/Ca_in_Mg_0001_with_Ne/asym_slabs_without_tags_and_damped_algo/surface_level_1/sur...	2021-05-21 17:55:05.217042	None	None	skanchar@cmti001#1	Vasp	5.4.4	None	None
4	14770769	finished	CaMg23Ne4	Mg_Ca_0_25_0	/Mg_Ca_0_25_0	/cmmc/u/	skanchar/pyiron/projects/research/Mg_surfaces_solid_solns/Ca_solid_solns/Ca_in_Mg_0001_surface/Ne_electrode/2_by_2/Ca_in_Mg_0001_with_Ne/asym_slabs_without_tags_and_damped_algo/surface_level_1/sur...	2021-05-21 17:55:06.715210	None	None	skanchar@cmti001#1	Vasp	5.4.4	None	None
0	14770770	finished	Ca3Mg21Ne4	Mg_Ca_0_75_0	/Mg_Ca_0_75_0	/cmmc/u/	skanchar/pyiron/projects/research/Mg_surfaces_solid_solns/Ca_solid_solns/Ca_in_Mg_0001_surface/Ne_electrode/2_by_2/Ca_in_Mg_0001_with_Ne/asym_slabs_without_tags_and_damped_algo/surface_level_1/sur...	2021-05-21 17:55:10.613522	None	None	skanchar@cmti001#1	Vasp	5.4.4	None	None
1	14770771	finished	Ca4Mg20Ne4	Mg_Ca_1_0_0	/Mg_Ca_1_0_0	/cmmc/u/	skanchar/pyiron/projects/research/Mg_surfaces_solid_solns/Ca_solid_solns/Ca_in_Mg_0001_surface/Ne_electrode/2_by_2/Ca_in_Mg_0001_with_Ne/asym_slabs_without_tags_and_damped_algo/surface_level_1/sur...	2021-05-21 17:55:13.798992	None	None	skanchar@cmti001#1	Vasp	5.4.4	None	None
junk_job = temp_update_pr.load('Mg_Ca_0_5_0')
DEBUG:pyiron_log:sql_query: {'job': 'Mg_Ca_0_5_0', 'project': 'skanchar/pyiron/projects/research/Mg_surfaces_solid_solns/Ca_solid_solns/Ca_in_Mg_0001_surface/Ne_electrode/2_by_2/Ca_in_Mg_0001_with_Ne/asym_slabs_without_tags_and_damped_algo/surface_level_1/surface/'}
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-57-fa2c9a28a217> in <module>
----> 1 junk_job = temp_update_pr.load('Mg_Ca_0_5_0')

/u/system/SLES12/soft/pyiron/dev/anaconda3/lib/python3.7/site-packages/pyiron_base/project/generic.py in load(self, job_specifier, convert_to_object)
    756             return None
    757         return self.load_from_jobpath(
--> 758             job_id=job_id, convert_to_object=convert_to_object
    759         )
    760 

/u/system/SLES12/soft/pyiron/dev/anaconda3/lib/python3.7/site-packages/pyiron_atomistics/project.py in load_from_jobpath(self, job_id, db_entry, convert_to_object)
    208         """
    209         job = super(Project, self).load_from_jobpath(
--> 210             job_id=job_id, db_entry=db_entry, convert_to_object=convert_to_object
    211         )
    212         job.project_hdf5._project = self.__class__(path=job.project_hdf5.file_path)

/u/system/SLES12/soft/pyiron/dev/anaconda3/lib/python3.7/site-packages/pyiron_base/project/generic.py in load_from_jobpath(self, job_id, db_entry, convert_to_object)
    777             job = jobpath(db=self.db, job_id=job_id, user=self.user)
    778             job = job.load_object(
--> 779                 convert_to_object=convert_to_object, project=job.project_hdf5.copy()
    780             )
    781             job._job_id = job_id

/u/system/SLES12/soft/pyiron/dev/anaconda3/lib/python3.7/site-packages/pyiron_base/job/core.py in load_object(self, convert_to_object, project)
    546             with project.open("..") as job_dir:
    547                 job_dir._mode = "a"
--> 548                 return self.to_object(project=job_dir, job_name=self._name)
    549         return self
    550 

/u/system/SLES12/soft/pyiron/dev/anaconda3/lib/python3.7/site-packages/pyiron_base/job/core.py in to_object(self, object_type, **qwargs)
    479                 "The HDF5 file of this job with the job_name: \""
    480                 + self.job_name
--> 481                 + "\" is empty, so it can not be loaded."
    482             )
    483         return self.project_hdf5.to_object(object_type, **qwargs)

ValueError: The HDF5 file of this job with the job_name: "Mg_Ca_0_5_0" is empty, so it can not be loaded.

Structure conversion functions to methods

Summary

We currently have functions in pyiron.atomistics.structure.atoms to convert our Atoms class to pymatgen and ASE formats. Let's modernize the interface to these and make them accessible without explicit deep imports.

Current

from pyiron.atomistics.structure.atoms  import pyiron_to_pymatgen, pymatgen_to_pyiron

pyiron_struct = pymatgen_to_pyiron(some_pymatgen_struct)
pymatgen_struct = pyiron_to_pymatgen(pyiron_struct)

Suggested

pyiron_struct = pr.create.structure.from_pymatgen(some_pymatgen_struct)
pymatget_struct = pyiron_struct.to_pymatgen()

And similarly for ASE.

Anyone want to implement this? 😸 I suggest the following steps:

  • Take the current conversion implementations and copy them over to be methods of Atoms and StructureFactory
    • changing signatures as needed
  • Make the current implementations simply exploit these methods
  • Deprecate the current methods with Marvin's new deprecator object
  • Add tests, or move and redirect existing tests as needed so they use the right part of the code instead of the old deprecated methods

Read the docs broken

Since the atomistics split the normal readthedocs page doesn't have any API docs anymore.

Take orientation as argument in structure creation

In the ADIS workshop, I realised several times that it is not quite straightforward to put the orientation in pyiron. It would be really nice to be able to do something like this:

structure = pr.create_ase_bulk('Al', directions=[[1,1,1], [1,-2,1], [1,0,-1]])

This essentially follows the same convention as in ASE (I guess it was BodyCenteredCubic in ase.lattice.cubic).

Elements can not be used as dictionary keys

But we still use this functionality in:
https://github.com/pyiron/pyiron_atomistics/blob/master/pyiron_atomistics/lammps/interactive.py#L423

The output of the following lines is true as expected:

s1 = pr_test.create_ase_bulk("Al")
s2 = pr_test.create_ase_bulk("Al")
s1.species[0] == s2.species[0]

But the following fails:

{s1.species[0]: "test"}[s2.species[0]]

With:

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-8-af2754853027> in <module>
----> 1 {s1.species[0]: "test"}[s2.species[0]]

KeyError: <pyiron_atomistics.atomistics.structure.periodic_table.ChemicalElement object at 0x7fd89e0de810>

Again the issue is related to the potential fitting workshop as the functionality is used to fit interatomic potentials with LAMMPS directly.

Request for function for doing bader charge analysis

Summary

Hello everyone,
I am looking for a function in pyiron to do Bader charge analysis.

Detailed Description

Usually, it can be done with an executable developed by Prof. Henkelman. (http://theory.cm.utexas.edu/henkelman/code/bader/)

This executable generates a file (ACF.dat) with the charges of the atoms.
It would be nice to have a function that can run this executable, generate the ACF.dat file and read the charges of the individual atoms from this file.

The best-case scenario would be when the user can access the Bader charges as an attribute of the job.

Further Information, Files, and Links
(http://theory.cm.utexas.edu/henkelman/code/bader/)

How to specify pseudopotential for different pseudohydrogens in VASP calculation

I'd like to specify a different pseudopotential (POTCAR) for a different type of hydrogens in VASP calculations
Let me give an example with ZnO slab

O Zn
1.00000000000000
3.2882546529036105 0.0000000000000000 0.0000000000000000
-1.6441273264518053 2.8477120634625819 0.0000000000000000
0.0000000000000000 0.0000000000000000 31.2636316299999990
H O Zn H
1 5 5 1
Selective dynamics
Direct
0.3333333429999996 0.6666666870000029 0.0307854723785965 F F F
0.3333333429999996 0.6666666870000029 0.0643456190559277 F F F
0.6666666269999979 0.3333333129999971 0.1491958436697587 F F F
0.3333333429999996 0.6666666870000029 0.2342682119439904 T T T
0.6666666269999979 0.3333333129999971 0.3194919934872525 T T T
0.3333333429999996 0.6666666870000029 0.4059699954341262 T T T
0.6666666269999979 0.3333333129999971 0.0848502297048483 F F F
0.3333333429999996 0.6666666870000029 0.1697004594096896 F F F
0.6666666269999979 0.3333333129999971 0.2544607979050794 T T T
0.3333333429999996 0.6666666870000029 0.3391798251091048 T T T
0.6666666269999979 0.3333333129999971 0.4223078948387798 T T T
0.6666666269999979 0.3333333129999971 0.4523078948387798 T T T

Here I have a pseudohydrogen with 0.5 valence on the bottom (denoted psH0.50) and real hydrogen on the top.

According to pyiron/pyiron#908 and pyiron/pyiron#660, I can set the first H as psH0.50 by

psh_pot = pr.create_element(new_element_name="psH05", parent_element="H", potential_file="/u/system/SLES12/soft/pyiron/dev/pyiron-resources-cmmc/vasp/potentials/potpaw_PBE/H.5/POTCAR") job.structure[0] = psh_pot

and then I tried to specify the corresponding POTCARs for elements by

job.potential.Zn = "/u/system/SLES12/soft/pyiron/dev/pyiron-resources-cmmc/vasp/potentials/potpaw_PBE/Zn/POTCAR" job.potential.O = "/u/system/SLES12/soft/pyiron/dev/pyiron-resources-cmmc/vasp/potentials/potpaw_PBE/O/POTCAR" job.potential.psH05 = "/u/system/SLES12/soft/pyiron/dev/pyiron-resources-cmmc/vasp/potentials/potpaw_PBE/H.5/POTCAR" job.potential.H = "/u/system/SLES12/soft/pyiron/dev/pyiron-resources-cmmc/vasp/potentials/potpaw_PBE/H/POTCAR"

This gives me an error

/cmmc/u/suhyun/prgm/pyiron/pyiron/vasp/potential.py in setattr(self, key, value)
246 self._potential_dict[key] = value
247 else:
--> 248 raise AttributeError
249
250 def to_dict(self):

AttributeError:

Just wondering I am missing some other functions to do it?

selective_dynamics doesn't appear in the list of tab completion

From what I know even after setting:

structure.add_tag(selective_dynamics=[True, True, True])

selective_dynamics does not appear in the tab completion list, even though it can (or maybe even should?) still be accessed via structure.selective_dynamics. I wouldn't call it a bug but it would be really nice to have it tab-completable.

get_structure() is slow

I did some brief profiling that identified two problems:

  1. the connection to the database can take a significant amount of time, a few seconds per call and it seems to get triggered a few times.
  2. conversions of numpy arrays from/to python lists when reading the positions and indices.

To load the final structure of ~1000 atoms from a 20000 steps trajectory takes around 30s, around 1/3 of that in the database connection and 2/3 in the numpy conversions. I'll look into these conversions and cut out as much as I can, but I will need some help on the database part, since I'm not familiar with its setup.

I put a notebook and an exported project containing this job on the cluster world-readable at
/u/zora/get_structure_profile.tar.gz
/u/zora/GetStructureProfile.ipynb

Below some example traces. tottime is the total internal time, i.e. how long the function takes minus how long its callees take.

        40013 function calls (39849 primitive calls) in 38.418 seconds

   Ordered by: internal time
   List reduced from 1010 to 10 due to restriction <10>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        7   14.327    2.047   14.327    2.047 {built-in method psycopg2._psycopg._connect}
      108   12.191    0.113   12.744    0.118 {built-in method numpy.array}
        3   10.082    3.361   10.082    3.361 {method 'tolist' of 'numpy.ndarray' objects}
        1    1.048    1.048   24.091   24.091 /u/zora/software/pyiron_atomistics/pyiron_atomistics/atomistics/job/interactive.py:491(positions)
        4    0.553    0.138    0.553    0.138 /u/system/SLES12/soft/pyiron/dev/anaconda3/lib/python3.7/site-packages/h5py/_hl/dataset.py:947(read_direct)
        7    0.052    0.007    0.052    0.007 {method 'execute' of 'psycopg2.extensions.cursor' objects}
        1    0.033    0.033    3.043    3.043 /u/zora/software/pyiron_atomistics/pyiron_atomistics/atomistics/job/interactive.py:467(indices)
        7    0.028    0.004    0.028    0.004 {method 'rollback' of 'psycopg2.extensions.connection' objects}
       11    0.027    0.002    0.027    0.002 {method '_g_list_group' of 'tables.hdf5extension.Group' objects}
       62    0.009    0.000    0.011    0.000 {method '_g_new' of 'tables.hdf5extension.File' objects}
         40013 function calls (39849 primitive calls) in 33.868 seconds

   Ordered by: internal time
   List reduced from 1010 to 10 due to restriction <10>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      108   11.489    0.106   12.178    0.113 {built-in method numpy.array}
        7   10.645    1.521   10.645    1.521 {built-in method psycopg2._psycopg._connect}
        3    9.605    3.202    9.605    3.202 {method 'tolist' of 'numpy.ndarray' objects}
        1    1.086    1.086   22.085   22.085 /u/zora/software/pyiron_atomistics/pyiron_atomistics/atomistics/job/interactive.py:491(positions)
        4    0.689    0.172    0.689    0.172 /u/system/SLES12/soft/pyiron/dev/anaconda3/lib/python3.7/site-packages/h5py/_hl/dataset.py:947(read_direct)
       11    0.070    0.006    0.070    0.006 {method '_g_list_group' of 'tables.hdf5extension.Group' objects}
       62    0.063    0.001    0.065    0.001 {method '_g_new' of 'tables.hdf5extension.File' objects}
        7    0.058    0.008    0.058    0.008 {method 'execute' of 'psycopg2.extensions.cursor' objects}
        1    0.033    0.033    9.343    9.343 /u/zora/software/pyiron_atomistics/pyiron_atomistics/atomistics/job/interactive.py:467(indices)
        7    0.025    0.004    0.025    0.004 {method 'rollback' of 'psycopg2.extensions.connection' objects}

Packaging more input into `input`

Summary

As discussed in the last couple of meetings, we'd like to get more and more of the input for a job into job.input, thus making it more amenable to saving, copying, etc. -- functions which sometimes fail at present (e.g. copying a vasp job loses all changes to the pseudopotential).

In principle this applies to all jobs, but those in the atomistic module are the most widely used and the most urgent offenders, so let's start here.

Detailed Description

Some pseudocode to kick-start the conversation:

Lammps

job = pr.create.job.Lammps('lammps')
job.input.structure = pr.create.structure.ase_bulk('Al', cubic=True)
job.input.potential = 'YuriMishinRulez'
# In the long run it would be nice to separate out calculators, but in the meantime
job.calc_md(temperature=300, n_ionic_steps=10)
# Should update some features in the input
print(job.input.md.temperature)
> 300
print(job.input.calc_mode)
> 'calc_md'

Vasp

job = pr.create.job.Vasp('vasp')
job.input.structure = pr.create.structure.ase_bulk('Cr', cubic=True)
job.input.structure[0] = Al
job.input.potcar.Al  # Has default value
job.input.potcar.Cr = pr.vasp.version_52.potcars.Cr.sv  # Use non-standard
# Alternatively attach to VaspJob: job.input.potcar = job.potcars.version_52.Cr.sv
job.input.kpoints.set_mesh_spacing(3)

Implementation

Under the hood, one thing that might be nice is (a) having all jobs consistently use InputList to handle their input, and (b) having each job subclass off this base to have its own custom input with relevant fields pre-defined (e.g. even just as None) to make them tab completable. E.g.

class AtomisticInput(InputList):
    def __init__(init=None, table_name=None):
        super().__init__(init=init, table_name=table_name)
        self.structure = None
        self.md = MDInput()  # Only until the atomistic jobs are split into interpreters and calculators
class LammpsInput(AtomisticInput):
    def __init__(init=None, table_name='input'):
        super().__init__(init=init, table_name=table_name)
        self.potential = None
class VaspInput(AtomisticInput):
    def __init__(init=None, table_name='input'):
        super().__init__(init=init, table_name=table_name)
        self._potcar = SomePotcarClass()
        self._kpoints = SomeKpointsClass()
        self.energy_cutoff = None  # Or however we handle the default

    @property 
    def potcar(self):
        # getter only so the cool class can't get overwritten
        return self._potcar

    @property 
    def kpoints(self):
        return self_kpoints
class MDInput(InputList):
    def __init__(init=None, table_name='md'):
        super().__init__(init=init, table_name=table_name)
        self.n_ionic_steps = None
        self._temperature = None 
        self._pressure = None
        # etc

    @property 
    def temperature(self):
        return self._temperature 

    @temperature.setter
    def temperature(self, T):
        # I'm not sure we want to write all these checks, but I'm open to it
        # especially if we can leverage them hard be re-using the code for many classes
        # Maybe there is also ontology stuff we can loop in here?
        if T < 0:
            raise ValueError('Cannot set temperature < 0 but got {}'.format(T))
        self._temperature = T

    @property 
    def pressure(self):
        return self._pressure 

    @pressure.setter 
    def pressure(self, p):
        p = whatever_filtering_code_we_need_for_float_tensor_list_etc(p)
        self._pressure = p

Note that none of these classes are exhaustive/complete, this is just an example of some key features.

Related issues

That we don't need to resolve here, but should bear in mind when dealing with this topic

  • Creating and deleting files on the fly
    • e.g. store a soft link to the potential file, write it, delete it
    • Store all the potential files as database objects and link to that? Maybe easier for exporting projects
  • The job-level tab completion lists are hella messy right now
  • Separating interpreters (Vasp, Lammps, ...) from calculators (MD, Static, VCSGC, Minimise, ...)

How to create the pseudohydrogen potential with modified valency (ZVAL)

Summary
I'd like to create a pseudohydrogen potential with the modified valency (ZVAL)
e.g. potpaw_PBE/H.5/POTCAR with ZVAL = 0.48

But I faced at two errors and it would be great if there's way to solve it.

  1. an error reading the element name "H.5"
  2. Permission problem when writing potential file

pyiron Version and Platform
location of pyiron I'm using: /u/system/SLES12/soft/pyiron/dev/anaconda3/lib/python3.7/site-packages/pyiron/
pyiron version: 0.4.0
python version: 3.7.9

Expected Behavior

POTCAR file should be created by using the potpaw_PBE/H.5/POTCAR file with modifying a value (0.5) of the ZVAL flag to 0.480

Actual Behavior

According to pyiron/pyiron#1295, the new potential file with modified valency can be created by using
from pyiron_mpie.electrochemistry.potential_ramp import potential_file_creator
Ne_new= potential_file_creator(element="Ne", charge=0.01)

My first issue is that I faced at the permission issue when I use exactly same code in my notebook

PermissionError: [Errno 13] Permission denied: '/u/system/SLES12/soft/pyiron/dev/pyiron-resources-cmmc/vasp/potentials/potpaw_PBE/Ne_p_0_010'

It is obvious permission error to write the potcar file in the system folder.
With this issue, how can I deal with writing POTCAR?

The second issue is that if I try to specify pseudohydrogen potcar by using
new = potential_file_creator(element="H.5", charge=0.02)
KeyError: 'H.5' is printed out.
I guess "H.5" is not passed as the element name.
It would be great if there's a way to create H.5 POTCAR with modified ZVAL?

Steps to Reproduce

1st error
from pyiron_mpie.electrochemistry.potential_ramp import potential_file_creator
Ne_new= potential_file_creator(element="Ne", charge=0.01)

2nd error
from pyiron_mpie.electrochemistry.potential_ramp import potential_file_creator
new = potential_file_creator(element="H.5", charge=0.02)

ASE removed rotate_euler

Now the unit tests fail with:

======================================================================
1871
ERROR: test_rotate_euler (atomistics.structure.test_atoms.TestAtoms)
1872
----------------------------------------------------------------------
1873
Traceback (most recent call last):
1874
  File "/home/runner/work/pyiron_atomistics/pyiron_atomistics/tests/atomistics/structure/test_atoms.py", line 453, in test_rotate_euler
1875
    basis.rotate_euler(phi=0.1 * np.pi)
1876
  File "/home/runner/work/pyiron_atomistics/pyiron_atomistics/pyiron_atomistics/atomistics/structure/atoms.py", line 2172, in __getattr__
1877
    return object.__getattribute__(self, item)
1878
AttributeError: 'Atoms' object has no attribute 'rotate_euler'
1879

1880
----------------------------------------------------------------------
1881
Ran 388 tests in 221.502s

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.