Coder Social home page Coder Social logo

pyiron / structuretoolkit Goto Github PK

View Code? Open in Web Editor NEW
5.0 5.0 0.0 47.37 MB

build, analyse and visualise atomistic structures for materials science

License: BSD 3-Clause "New" or "Revised" License

Python 100.00%
ase atomistic materials-science pyiron

structuretoolkit's Introduction

structuretoolkit

Unittests Coverage Status

Originally developed as part of the pyiron_atomistics module the structuretoolkit was release as standalone library for analysing, building and visualising atomistic structures. Internally it uses the ase.atoms.Atoms class to represent atomistic structures in python. The structuretoolkit is integrated inside pyiron_atomistics.

Disclaimer

The structuretoolkit is currently under development.

Example

import structuretoolkit as stk
from ase.build import bulk

structure = bulk("Al", cubic=True)
stk.analyse.get_adaptive_cna_descriptors(structure)
stk.plot3d(structure)

Features

Analysis

  • stk.analyse.get_neighbors()
  • stk.analyse.get_neighborhood()
  • stk.analyse.get_equivalent_atoms()
  • stk.analyse.get_steinhardt_parameters()
  • stk.analyse.get_centro_symmetry_descriptors()
  • stk.analyse.get_diamond_structure_descriptors()
  • stk.analyse.get_adaptive_cna_descriptors()
  • stk.analyse.get_voronoi_volumes()
  • stk.analyse.find_solids()
  • stk.analyse.get_mean_positions()
  • stk.analyse.get_average_of_unique_labels()
  • stk.analyse.get_interstitials()
  • stk.analyse.get_layers()
  • stk.analyse.get_voronoi_vertices()
  • stk.analyse.get_voronoi_neighbors()
  • stk.analyse.get_delaunay_neighbors()
  • stk.analyse.get_cluster_positions()
  • stk.analyse.get_strain()

Build

  • stk.build.get_grainboundary_info()
  • stk.build.grainboundary()
  • stk.build.high_index_surface()
  • stk.build.get_high_index_surface_info()
  • stk.build.sqs_structures()
  • stk.build.pyxtal()
  • stk.build.B2()
  • stk.build.C14()
  • stk.build.C15()
  • stk.build.C36()
  • stk.build.D03()

Visualize

  • stk.visualize.plot3d()

Common

  • stk.common.ase_to_pymatgen()
  • stk.common.pymatgen_to_ase()
  • stk.common.pymatgen_read_from_file()
  • stk.common.ase_to_pyscal()
  • stk.common.apply_strain()
  • stk.common.center_coordinates_in_unit_cell()
  • stk.common.get_extended_positions()
  • stk.common.get_vertical_length()
  • stk.common.get_wrapped_coordinates()
  • stk.common.select_index()

structuretoolkit's People

Contributors

ahmed-aslam avatar ahmedabdelkawy avatar alaukiksaxena avatar ashtonmv avatar caglayanoaras avatar codacy-badger avatar dependabot-preview[bot] avatar dependabot[bot] avatar feloch avatar freyso avatar github-actions[bot] avatar ibrsam avatar jan-janssen 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 zendegani avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

structuretoolkit's Issues

`plot3d` - go beyond NGLview

Currently we have to rely on NGLview for most of the functionalities, especially if we want to have different colours for a continuous value, or vectors. It's not only extremely slow, but it also doesn't give us the possibility to

  • Combine it with continuum plotting
  • Save the figure
  • Run on machines that do not have NGLview installed

So the functionalities should be extended with plotly

Documentation needed in`common.helper`

I think common.helper.get_species_indices_dict is not behaving as intended, but it's hard to tell with neither docstring nor test. Note that this dictionary only couples species and their index of first appearance.

EDIT:

Ok, common.helper.get_species_indices_dict is doing what it is supposed to by returning the index of the first occurrence of each species. The source of my confusion was that this usage of indices as a numeric formulation of the species information in Atoms.get_chemical_symbols rather than the integer range $[0, N_\mathrm{atoms}-1]$.

The ase Atoms docs consistently use indices to mean exactly this 0..N-1 range, while the use of indices here is a holdover from pyiron-specific terminology.

I don't think it's the end of the world to introduce or re-define terms compared to ASE. However, if and when we do that, it does become important to have documentation regarding the differences. (I mean, we need documentation anyhow, but it becomes especially important in such cases.)

Right now the four indices-related methods in common.helper (get_species_indices_dict, get_structure_indices, select_index, set_indices) are sorely in need of documentation.

At the same time, we could consider alternative nomenclature that doesn't conflict with the ASE meaning for indices -- but if we can't think of anything, then documenting the difference is sufficient.

Test generate warning for stoichiometry Mg1

Currently the pyxtal tests raise the following warning:

/home/runner/work/structuretoolkit/structuretoolkit/structuretoolkit/build/random.py:104: UserWarning: Groups [193, 194] could not be generated with stoichiometry Mg1!
  warnings.warn(

It would be great to adjust the test to not raise a warning anymore.

Warning about missing neighborhood atoms

During the tests we get the error message:

/home/runner/work/structuretoolkit/structuretoolkit/structuretoolkit/analyse/neighbors.py:350: UserWarning: Taking a larger search area after initialization has the risk of missing neighborhood atoms
  warnings.warn(

It would be great to adjust the tests to not run into this warning.

Address warning about neighbour list limit

Currently in the tests we get the following warning:

/home/runner/work/structuretoolkit/structuretoolkit/structuretoolkit/analyse/neighbors.py:270: UserWarning: Number of neighbors found within the cutoff_radius is equal to (estimated) num_neighbors. Increase num_neighbors (or set it to None) or width_buffer to find all neighbors within cutoff_radius.

It is not yet clear to me which tests cause these warnings, but we should take a look to see if we can fix them.

Address FutureWarning from sklearn

/usr/share/miniconda3/envs/my-env/lib/python3.11/site-packages/sklearn/cluster/_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning

plot3d is not working with the latest kernel

Plot3d() - nglview mode - has not been working for a while now.

output:
Error displaying widget: model not found

code to reproduce:

pr = Project('plot3d')
al_struc = pr.create.structure.bulk('Al', cubic=True)
al_struc.plot3d()

directly from nglview

import nglview
from structuretoolkit.visualize import _plot3d, _ngl_write_structure
pr = Project('plot3d')
al_struc = pr.create.structure.bulk('Al', cubic=True)
structure = al_struc.copy()
elements = structure.get_chemical_symbols()
atomic_numbers = structure.get_atomic_numbers()
positions = structure.positions
struct = nglview.TextStructure(_ngl_write_structure(elements, positions, structure.cell))
view = nglview.NGLWidget(struct)
view

Things I tried and did not work:
1.using latest structuretoolkit (0.0.21) and atomistics (0.4.14) and the ones currently on the cluster structuretoolkit (0.0.18) and atomistics (0.4.9).
2.downgrading nglview

Things I tried and worked:
changing the kernel from pyiron/latest to python 3

`get_neighborhood` does not work when `cutoff_radius` is specified

It's actually a very rare case, but the following code does not work:

from pyiron_atomistics import Project
a_0 = 3.4812
structure = Project(".").create.structure.bulk('Fe', cubic=True, crystalstructure='fcc', a=a_0).repeat(5)
neigh = structure.get_neighbors(num_neighbors=12)
narrow_paths = structure.positions[:, None, :] + neigh.vecs * 0.5
narrow_paths = narrow_paths[neigh.indices > neigh.atom_numbers]
structure.get_neighborhood(narrow_paths, num_neighbors=None, cutoff_radius=5).distances.max()

Output : inf (while it should be some finite number since different points do not have different neighborhood)

The reason is get_extended_positions from structuretoolkit.common.helper does not correctly calculate the distance of external points to the nearest point in the box. I always knew that this could be a problem but I guess I should come up with a decent algorithm.

pyxtal triples the dependencies

@pmrv there seems to be something off with the dependencies of pyxtal:

  Summary:

  Install: 357 packages

  Total download: 708MB

Before it was:

  Summary:

  Install: 164 packages

  Total download: 208MB

In addition there are a couple of mysterious crashes in pyiron_atomistics when trying to include pyxtal in the environment:
pyiron/pyiron_atomistics#1119

Originally we planned to include it in structuretoolkit=0.0.6 but the conda package dependencies were not update, those were only updated in structuretoolkit=0.0.7.

Workflow stack

In other repos where the CI is already migrated (e.g. ironflow, pyiron_module_template and pyiron_contrib), there are some more workflows:

  • daily.yml
  • dependabot-pr.yml
  • pr-labeled.yml
  • pr-target-opened.yml
  • weekly.yml

I've added them for structuretoolkit, too. Is it intended that all our repos shall have more or less the same CI stack?

Maybe this issue should be placed in pyiron/actions, so feel free to move it there.

plot3d with select_atoms does not work anymore

If you try to plot3d() from a generated structure with select_atoms showing subset of atoms:

from pyiron import Project
pr = Project('test')
struc = pr.create.structure.bulk('Fe', cubic=True)
struc.plot3d(select_atoms=[0])

you will end up with the error:

File /u/system/SLES12/soft/pyiron/dev/anaconda3/lib/python3.10/site-packages/structuretoolkit/visualize.py:310, in _plot3d(structure, show_cell, show_axes, camera, spacefill, particle_size, select_atoms, background, color_scheme, colors, scalar_field, scalar_start, scalar_end, scalar_cmap, vector_field, vector_color, magnetic_moments, view_plane, distance_from_camera)
    308 if select_atoms is not None:
    309     select_atoms = np.array(select_atoms, dtype=int)
--> 310     elements = elements[select_atoms]
    311     atomic_numbers = atomic_numbers[select_atoms]
    312     positions = positions[select_atoms]

TypeError: only integer scalar arrays can be converted to a scalar index

The current structure.plot3d() currently works as follows:

  1. plot3d() Inside pyiron_atomistics/atomistics/structure/atoms.py calls and passes pyiron_to_ase(self): self=structure to
  2. plot3d() inside /structuretoolkit/visualize.py
  3. Which passes the element list as a list and not numpy array
  4. However plot3d() inside visualize.py explicitly changes the select_atoms into a numpy: select_atoms = np.array(select_atoms, dtype=int)
  5. You end up trying to index a list with a numpy array which does not work:
s = ['A', 'B', 'C', 'D']
ind = np.array([1])
s[ind]

If you try to use plot3d() directly from visual.py and pass the structure to it, it works because elements is an array no pyiron_to_ase was imposed.

from structuretoolkit.visualize import _plot3d
_plot3d(struc, select_atoms=[0])

Proposed solutions:

  1. remove pyiron_to_ase(self) and just pass (self) in plot3d() in atoms.py
  2. explicitly change elements list to numpy similar to select_atoms in plot3d() in visual.py: elements= np.array(elements)

Both are tested and work locally. However, I am not sure if they affect other functionalities.

get_neighbors crashes with out of memory for certain structures

I've found that for certain structures with weird aspect ratios or low density, get_neighbors will try to extend the structure so much that the python process gets killed because of extreme memory consumption. I'm guessing this is because the width_buffer is calculated incorrectly. This happens also with get_neigbhors_by_distance or when setting width_buffer=0. I'm not sure whether it will always be possible to do sensible things for such weird structures, but at least the code should check how much it's going to extend the structure and raise an error if that's inappropriately large.

Here's an example structure, to reproduce the error just call get_neighbors on it.

Purpose of workflow `mini.yml`

I'm migrating the repository's CI to use our centralized actions/workflows (see branch migrate_ci). This was mostly straight forward, I guess. With one workflow I did not really now what to do:
.github/workflows/mini.yml runs tests in a minimal conda environment on pushes and PRs to main. I tried to reconstruct this workflow with our centralized actions. What is actually the purpose of this workflow? On the same events, all those tests are run anyways (via push-pull-main.yml) using a slightly larger environment.

Documentation

While setting up the CI, I also created the doc/ dir, with empty files conf.py and index.rst. I did not know right away, what to do further with them. Do we have some documentation of structuretoolkit anywhere?

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.