├── .bumpversion.cfg
├── .ci_support
└── environment.yml
├── .coverage
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
└── workflows
│ ├── deploy.yml
│ └── testing.yml
├── .gitignore
├── .readthedocs.yml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.rst
├── LICENSE
├── MANIFEST.in
├── README.md
├── Welcome.md
├── _config.yml
├── _toc.yml
├── binder
├── apt.txt
├── environment.yml
├── jupyterlab-workspace.json
├── postBuild
└── start
├── docs
├── .nojekyll
├── _static
│ ├── img_time_memory.png
│ ├── img_time_neighbor.png
│ ├── pyscal_logo1.png
│ └── pyscal_logo2.png
├── _templates
│ ├── download.html
│ └── sidebarhelp.html
├── epilogue.md
├── examples.md
├── gettingstarted.md
├── index.rst
├── intro.md
├── license.md
├── methods
│ ├── 01_neighbors.md
│ ├── 02_steinhardt.md
│ ├── 03_solidliquid.md
│ ├── 04_disorder.md
│ ├── 05_angular.md
│ ├── 06_voronoi.md
│ ├── 07_centrosymmetry.md
│ └── 08_entropy.md
├── methods_landing.md
├── methodsandexamples.rst
├── methodsindex.rst
├── modules.rst
├── prologue
│ ├── acknowledgements.md
│ ├── api.md
│ ├── citing.md
│ ├── download.md
│ ├── extending.md
│ ├── gettingstarted.md
│ ├── helpandsupport.md
│ ├── license.md
│ ├── news.md
│ ├── projects.md
│ └── publications.md
├── pubsandprojects.rst
├── pyscal.rst
└── requirements.txt
├── environment-docs.yml
├── examples
├── 01_getting_started.ipynb
├── 02_creating_structures.ipynb
├── 03_atoms_in_more_detail.ipynb
├── 04_creating_grain_boundaries.ipynb
├── 05_finding_neighbors.ipynb
├── 06_steinhardt_parameters.ipynb
├── 07_disorder_parameters.ipynb
├── 08_angular_parameters.ipynb
├── 09_distinguishing_solid_liquid.ipynb
├── 10_voronoi_tessellation.ipynb
├── 11_chi_params.ipynb
├── 12_centrosymmetry_parameter.ipynb
├── 13_short_range_order.ipynb
├── 14_common_neighbor_analysis.ipynb
├── 15_trajectory_module.ipynb
├── 16_entropy_parameter.ipynb
├── Al.eam.fs
├── Mo.set
├── cluster.dump
├── conf.bcc
├── conf.bcc.dump
├── conf.dump
├── conf.fcc
├── conf.fcc.Al.dump
├── conf.fcc.dump
├── conf.hcp
├── conf.hcp.dump
├── conf.lqd
├── conf.lqd.Al.dump
├── conf0.bcc
├── conf0.fcc
├── conf0.hcp
├── conf8k.dump
├── prototype_files.ipynb
├── system1.png
├── system2.png
├── system3.png
├── system4.png
└── traj.light
├── lib
└── voro++
│ ├── Doxyfile
│ ├── Makefile
│ ├── Makefile.dep
│ ├── README
│ ├── c_loops.cc
│ ├── c_loops.hh
│ ├── cell.cc
│ ├── cell.hh
│ ├── cmd_line.cc
│ ├── common.cc
│ ├── common.hh
│ ├── config.hh
│ ├── container.cc
│ ├── container.hh
│ ├── container_prd.cc
│ ├── container_prd.hh
│ ├── pre_container.cc
│ ├── pre_container.hh
│ ├── rad_option.hh
│ ├── test.cpp
│ ├── unitcell.cc
│ ├── unitcell.hh
│ ├── v_base.cc
│ ├── v_base.hh
│ ├── v_base_wl.cc
│ ├── v_compute.cc
│ ├── v_compute.hh
│ ├── voro++.cc
│ ├── voro++.hh
│ ├── wall.cc
│ ├── wall.hh
│ ├── worklist.hh
│ └── worklist_gen.pl
├── more_atom_manipulation.ipynb
├── neighbor_data.ipynb
├── new_features.ipynb
├── pyproject.toml
├── requirements.txt
├── requirements_dev.txt
├── setup.py
├── src
└── pyscal3
│ ├── __init__.py
│ ├── ase.py
│ ├── atoms.py
│ ├── attributes.py
│ ├── centrosymmetry.cpp
│ ├── cna.cpp
│ ├── core.py
│ ├── csl.py
│ ├── data
│ ├── annotations.yaml
│ ├── element_data.yaml
│ └── structure_data.yaml
│ ├── entropy.cpp
│ ├── formats
│ ├── __init__.py
│ ├── ase.py
│ ├── lammps.py
│ ├── mdtraj.py
│ └── vasp.py
│ ├── grain_boundary.py
│ ├── misc.py
│ ├── neighbor.cpp
│ ├── operations
│ ├── __init__.py
│ ├── calculations.py
│ ├── centrosymmetry.py
│ ├── chemical.py
│ ├── cna.py
│ ├── entropy.py
│ ├── identify.py
│ ├── input.py
│ ├── neighbor.py
│ ├── operations.py
│ ├── serialize.py
│ ├── symmetry.py
│ ├── visualize.py
│ └── voronoi.py
│ ├── routines.py
│ ├── sh.cpp
│ ├── solids.cpp
│ ├── structure_creator.py
│ ├── system.h
│ ├── system_binding.cpp
│ ├── traj_process.py
│ ├── trajectory.py
│ ├── visualization.py
│ └── voronoi.cpp
├── test.ipynb
├── tests
├── files
│ ├── POSCAR
│ ├── cluster.dump
│ ├── conf.bcc.scaled.dump
│ ├── conf.dump
│ ├── conf.dump.gz
│ ├── conf.fcc.Al.dump
│ ├── conf.fcc.dump
│ └── conf.lqd.dump
├── test_angular.py
├── test_ase.py
├── test_centro.py
├── test_chiparams.py
├── test_cna.py
├── test_crystal_structures.py
├── test_delete.py
├── test_disorder.py
├── test_entropy.py
├── test_masking.py
├── test_neighbors.py
├── test_nucsize.py
├── test_q12.py
├── test_q3.py
├── test_q_system.py
├── test_rdf.py
├── test_read_file.py
├── test_sro.py
├── test_symmetry.py
├── test_system.py
├── test_traj_process.py
├── test_trajectory.py
└── test_voronoi.py
└── update_xtals.ipynb
/.bumpversion.cfg:
--------------------------------------------------------------------------------
1 | [bumpversion]
2 | current_version = 3.3.0
3 | commit = True
4 | tag = True
5 |
6 | [bumpversion:file:setup.py]
7 |
--------------------------------------------------------------------------------
/.ci_support/environment.yml:
--------------------------------------------------------------------------------
1 | name: pyscal-test
2 | channels:
3 | - conda-forge
4 | dependencies:
5 | - numpy
6 | - matplotlib
7 | - ase
8 | - plotly
9 | - ipywidgets
10 | - pytest
11 | - pytest-cov
12 | - pybind11
13 | - scipy
14 | - spglib
15 | - pyyaml
16 |
--------------------------------------------------------------------------------
/.coverage:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pyscal/pyscal3/ae76867ab0a315c39151666a5fda1121f0c4a899/.coverage
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/workflows/deploy.yml:
--------------------------------------------------------------------------------
1 | name: Build and upload to PyPI
2 |
3 | # Build on every branch push, tag push, and pull request change:
4 | #on: [push, pull_request]
5 | # Alternatively, to publish when a (published) GitHub Release is created, use the following:
6 | on:
7 | release:
8 | types:
9 | - published
10 |
11 | jobs:
12 | build_wheels:
13 | name: Build wheels on ${{ matrix.os }}
14 | runs-on: ${{ matrix.os }}
15 | strategy:
16 | matrix:
17 | os: [ubuntu-latest, macos-13]
18 | python-version: ['3.10', '3.11']
19 |
20 | steps:
21 | - uses: actions/checkout@v3
22 | - name: Install dependencies
23 | run: >-
24 | python -m pip install --user --upgrade setuptools wheel pybind11
25 | - name: Build wheels
26 | uses: pypa/cibuildwheel@v2.12.3
27 |
28 | - uses: actions/upload-artifact@v3
29 | with:
30 | path: ./wheelhouse/*.whl
31 |
32 | build_sdist:
33 | name: Build source distribution
34 | runs-on: ubuntu-latest
35 | steps:
36 | - uses: actions/checkout@v3
37 | - name: Install dependencies
38 | run: >-
39 | python -m pip install --user --upgrade setuptools wheel pybind11
40 | - name: Build sdist
41 | run: |
42 | pip install pybind11
43 | python setup.py sdist
44 |
45 | - uses: actions/upload-artifact@v3
46 | with:
47 | path: dist/*.tar.gz
48 |
49 | upload_pypi:
50 | needs: [build_wheels, build_sdist]
51 | runs-on: ubuntu-latest
52 | # upload to PyPI on every tag starting with 'v'
53 | #if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
54 | # alternatively, to publish when a GitHub Release is created, use the following rule:
55 | #if: github.event_name == 'release' && github.event.action == 'published'
56 | steps:
57 | - uses: actions/download-artifact@v4
58 | with:
59 | # unpacks default artifact into dist/
60 | # if `name: artifact` is omitted, the action will create extra parent dir
61 | name: artifact
62 | path: dist
63 |
64 | - uses: pypa/gh-action-pypi-publish@v1.5.0
65 | with:
66 | user: __token__
67 | password: ${{ secrets.PYPI_API_TOKEN }}
68 | #repository_url: https://test.pypi.org/legacy/
69 |
--------------------------------------------------------------------------------
/.github/workflows/testing.yml:
--------------------------------------------------------------------------------
1 | name: pyscal-testing
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | pull_request:
7 | branches: [ main ]
8 |
9 | jobs:
10 | build:
11 | strategy:
12 | matrix:
13 | os: [ubuntu-latest, macos-13, windows-latest]
14 | python-version: ['3.10', '3.11']
15 |
16 | runs-on: ${{ matrix.os }}
17 | steps:
18 | - uses: actions/checkout@v4
19 | - name: Setup Mambaforge
20 | uses: conda-incubator/setup-miniconda@v3
21 | with:
22 | python-version: ${{ matrix.python-version }}
23 | miniforge-version: latest
24 | channels: conda-forge
25 | environment-file: .ci_support/environment.yml
26 | - name: run tests
27 | shell: bash -l {0}
28 | run: |
29 | pip install --no-deps --no-build-isolation -e .
30 | pytest --cov-report=xml --cov=pyscal tests/
31 |
32 | - name: Upload coverage to Codecov
33 | uses: codecov/codecov-action@v1
34 | with:
35 | file: coverage.xml
36 | name: codecov-umbrella
37 | fail_ci_if_error: false
38 |
39 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | *~
3 | *#
4 | *.nfs*
5 | __pycache__/
6 | build/
7 | dist/
8 | *.egg*
9 | .cache
10 | docs/html/*
11 | docs/doctrees/*
12 | docs/source/examples
13 | .ipynb_check*
14 | *.dump
15 |
--------------------------------------------------------------------------------
/.readthedocs.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 |
3 | build:
4 | os: ubuntu-22.04
5 | tools:
6 | #python: "mambaforge-4.10"
7 | python: "3.11"
8 |
9 | jobs:
10 | pre_build:
11 | # Generate the Sphinx configuration for this Jupyter Book so it builds.
12 | - "jupyter-book config sphinx ."
13 |
14 | #conda:
15 | # environment: environment-docs.yml
16 |
17 | python:
18 | install:
19 | - requirements: requirements.txt
20 | - method: pip
21 | path: .
22 |
23 | sphinx:
24 | builder: html
25 | fail_on_warning: false
26 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at sarath.menon@ruhr-uni-bochum.de. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/CONTRIBUTING.rst:
--------------------------------------------------------------------------------
1 | Extending and contributing
2 | ==========================
3 |
4 | **pyscal** welcomes contribution and extension to the module. Rather than local modifications, we request that the modifications be submitted through a pull request. **pyscal** follows the `pep8 `_ style. The quality of the code can be checked by `pylint `_ library by running ``pylint yourscript.py``. Rather than the style of code, what is more important is the documentation. We request that all improvements are documented in detail.
5 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2024, Sarath Menon
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | 1. Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | 2. Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | 3. Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include src/pyscal3/data/*.yaml
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # pyscal - python Structural Environment Calculator
3 |
4 | Complete documentation with examples available [here](https://pyscal.org/).
5 |
6 | pyscal3, a completely new pyscal which is faster and can handle a large number of atoms, with a much more user-friendly and intuitive interface. Adds more features such as more structure creation including grain boundaries, selection, and deletion of atoms
7 |
8 |
9 | ## Installation
10 |
11 | pyscal3 can be installed directly using conda by the following statement-
12 |
13 | ```
14 | conda install -c conda-forge pyscal3
15 | ```
16 |
17 | **From repository**
18 |
19 | pyscal can be built from the repository by-
20 |
21 | ```
22 | git clone https://github.com/pyscal/pyscal3.git
23 | cd pyscal3
24 | pip install .
25 | ```
26 |
27 | ## Citing the work
28 |
29 | If you use pyscal3 in your work, the citation of the [following article](https://joss.theoj.org/papers/10.21105/joss.01824) will be greatly appreciated:
30 |
31 | Sarath Menon, Grisell Díaz Leines and Jutta Rogal (2019). pyscal: A python module for structural analysis of atomic environments. Journal of Open Source Software, 4(43), 1824, https://doi.org/10.21105/joss.01824
32 |
33 | ## Works using pyscal
34 |
35 | For a complete list of publications which used pyscal, see [here](https://scholar.google.com/scholar?oi=bibs&hl=en&cites=315020929885190486&as_sdt=5).
36 |
37 |
--------------------------------------------------------------------------------
/Welcome.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | pyscal |
5 | |
6 |
7 |
8 | pyscal is a python module for the calculation of local atomic structural environments including Steinhardt's bond orientational order parameters during post-processing of atomistic simulation data. The core functionality of pyscal is written in C++ with python wrappers using pybind11 which allows for fast calculations with possibilities for easy expansion in python. |
9 |  |
10 |
11 |
12 |
13 | ## **Examples**
14 |
15 | 1. [Getting started](examples/01_getting_started.ipynb) : Explore basic features of pyscal and how to get started with pyscal.
16 | 2. [Finding neighbors](examples/02_finding_neighbors.ipynb) : Various methods of finding the local neighborhood of an atom in pyscal, including cutoff and Voronoi methods.
17 | 3. [Bond orientational order parameters](examples/03_steinhardt_parameters.ipynb) : Calculation of bond orientational parameters, averaged and Voronoi weighted versions, and distinction of structures.
18 | 4. [Disorder parameters](examples/04_disorder_parameters.ipynb) : Disorder parameters based on Steinhardts parameters.
19 | 5. [Distinguishing solid and liquid atoms](examples/05_distinguishing_solid_liquid.ipynb) : Use Steinhardts parameters to distinguish between solid and liquid, and how to cluster solid atoms based on a property.
20 | 6. [Voronoi tessellation](examples/06_voronoi_tessellation.ipynb) : Identifying Voronoi polyhedra and calculation of associated volume.
21 | 7. [Angular parameters](examples/07_angular_parameters.ipynb) : Angular parameters for identification of tetrahedral ordering.
22 | 8. [$\chi$ parameters](examples/08_chi_params.ipynb) : Angular parameters for structural identification.
23 | 9. [Centrosymmetry parameter](examples/09_centrosymmetry_parameter.ipynb) : Parameters for identification of defects in crystals.
24 | 10. [Short range order](examples/10_short_range_order.ipynb) : Calculating ordering in binary systems.
25 | 11. [Entropy parameter](examples/11_entropy_parameter.ipynb) : Use a measure of entropy to distinguish solid and liquid.
26 | 12. [Calculation of energy](examples/12_calculating_energy.ipynb) : Use pyscal in combination with LAMMPS to calculate energy of atoms.
27 | 13. [Structural identification using entropy and enthalpy](examples/13_combining_energy_enthalpy.ipynb) : Combine entropy and energy methods to identify crystal structures.
28 | 14. [Working with lammps trajectories](examples/03_01_Steinhardts_parameters_for_lammps.ipynb) : Reading in a lammps trajectory, calculating Steinhardt's parameter for slices and various cluster properties.
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | # Book settings
2 | # Learn more at https://jupyterbook.org/customize/config.html
3 |
4 | title: "pyscal3"
5 | #author: The Jupyter Book Community
6 | logo: docs/_static/pyscal_logo1.png
7 |
8 | # Force re-execution of notebooks on each build.
9 | # See https://jupyterbook.org/content/execute.html
10 | execute:
11 | execute_notebooks: 'auto'
12 |
13 | only_build_toc_files: true
14 |
15 | # Define the name of the latex output file for PDF builds
16 | latex:
17 | latex_documents:
18 | targetname: book.tex
19 |
20 | # Information about where the book exists on the web
21 | repository:
22 | url: https://github.com/pyiron/DGM_workshop
23 | path_to_book: book
24 | branch: main
25 |
26 | notebook_interface : "notebook"
27 |
28 | # Add GitHub buttons to your book
29 | # See https://jupyterbook.org/customize/config.html#add-a-link-to-your-repository
30 | html:
31 | use_issues_button: false
32 | use_repository_button: true
33 |
34 | parse:
35 | myst_enable_extensions:
36 | # don't forget to list any other extensions you want enabled,
37 | # including those that are enabled by default!
38 | - html_image
39 | - amsmath
40 | - dollarmath
41 | - linkify
42 | - substitution
43 | - colon_fence
44 | - html_admonition
45 |
46 | sphinx:
47 | config:
48 | mathjax_path: https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js
49 | html_theme: pydata_sphinx_theme
50 | html_js_files:
51 | - https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js
52 | html_sidebars:
53 | "**": []
54 |
--------------------------------------------------------------------------------
/_toc.yml:
--------------------------------------------------------------------------------
1 | # Table of contents
2 | # Learn more at https://jupyterbook.org/customize/toc.html
3 |
4 | format: jb-book
5 | root: docs/intro
6 | chapters:
7 | - file: docs/gettingstarted.md
8 | - file: docs/methods_landing.md
9 | sections:
10 | - file: docs/methods/01_neighbors.md
11 | - file: docs/methods/02_steinhardt.md
12 | - file: docs/methods/03_solidliquid.md
13 | - file: docs/methods/04_disorder.md
14 | - file: docs/methods/05_angular.md
15 | - file: docs/methods/06_voronoi.md
16 | - file: docs/methods/07_centrosymmetry.md
17 | - file: docs/methods/08_entropy.md
18 | - file: docs/examples.md
19 | sections:
20 | - file: examples/01_getting_started
21 | - file: examples/02_creating_structures
22 | - file: examples/03_atoms_in_more_detail
23 | - file: examples/04_creating_grain_boundaries
24 | - file: examples/05_finding_neighbors
25 | - file: examples/06_steinhardt_parameters
26 | - file: examples/07_disorder_parameters
27 | - file: examples/08_angular_parameters
28 | - file: examples/09_distinguishing_solid_liquid
29 | - file: examples/10_voronoi_tessellation
30 | - file: examples/11_chi_params
31 | - file: examples/12_centrosymmetry_parameter
32 | - file: examples/13_short_range_order
33 | - file: examples/14_common_neighbor_analysis
34 | - file: examples/15_trajectory_module
35 | - file: examples/16_entropy_parameter
36 | - file: docs/epilogue.md
37 |
38 |
39 |
--------------------------------------------------------------------------------
/binder/apt.txt:
--------------------------------------------------------------------------------
1 | cmake
2 |
--------------------------------------------------------------------------------
/binder/environment.yml:
--------------------------------------------------------------------------------
1 | channels:
2 | - conda-forge
3 | dependencies:
4 | - python
5 | - jupyterlab
6 | - nodejs
7 | - notebook
8 | - numpy
9 | - matplotlib
10 | - lammps
11 | - ase
12 | - ipywidgets
13 | - plotly
14 | - h5py
15 |
--------------------------------------------------------------------------------
/binder/jupyterlab-workspace.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": {
3 | "file-browser-filebrowser:cwd": {
4 | "path": ""
5 | },
6 | "dask-dashboard-launcher:individual-progress": {
7 | "data": {
8 | "route": "individual-progress",
9 | "label": "Progress"
10 | }
11 | },
12 | "dask-dashboard-launcher:individual-task-stream": {
13 | "data": {
14 | "route": "individual-task-stream",
15 | "label": "Task Stream"
16 | }
17 | },
18 | "layout-restorer:data": {
19 | "main": {
20 | "dock": {
21 | "type": "split-area",
22 | "orientation": "horizontal",
23 | "sizes": [
24 | 0.5,
25 | 0.5
26 | ],
27 | "children": [
28 | {
29 | "type": "tab-area",
30 | "currentIndex": 0,
31 | "widgets": [
32 | "markdownviewer-widget:Welcome.md"
33 | ]
34 | },
35 | {
36 | "type": "split-area",
37 | "orientation": "vertical",
38 | "sizes": [
39 | 0.67,
40 | 0.33
41 | ],
42 | "children": [
43 | {
44 | "type": "tab-area",
45 | "currentIndex": 0,
46 | "widgets": [
47 | "dask-dashboard-launcher:individual-task-stream"
48 | ]
49 | },
50 | {
51 | "type": "tab-area",
52 | "currentIndex": 0,
53 | "widgets": [
54 | "dask-dashboard-launcher:individual-progress"
55 | ]
56 | }
57 | ]
58 | }
59 | ]
60 | },
61 | "mode": "multiple-document",
62 | "current": "markdownviewer-widget:Welcome.md"
63 | },
64 | "left": {
65 | "collapsed": false,
66 | "current": "filebrowser",
67 | "widgets": [
68 | "filebrowser",
69 | "running-sessions",
70 | "dask-dashboard-launcher",
71 | "command-palette",
72 | "tab-manager"
73 | ]
74 | },
75 | "right": {
76 | "collapsed": true,
77 | "widgets": []
78 | }
79 | },
80 | "markdownviewer-widget:Welcome.md": {
81 | "data": {
82 | "path": "Welcome.md",
83 | "factory": "Markdown Preview"
84 | }
85 | },
86 | "dask-dashboard-launcher": {
87 | "url": "DASK_DASHBOARD_URL",
88 | "cluster": ""
89 | }
90 | },
91 | "metadata": {
92 | "id": "/lab"
93 | }
94 | }
--------------------------------------------------------------------------------
/binder/postBuild:
--------------------------------------------------------------------------------
1 | pip install .
2 | jupyter labextension install jupyterlab-plotly@4.11.0
3 | jupyter labextension install @jupyter-widgets/jupyterlab-manager plotlywidget@4.11.0
--------------------------------------------------------------------------------
/binder/start:
--------------------------------------------------------------------------------
1 |
2 | #!/bin/bash
3 |
4 | # Import the workspace
5 | jupyter lab workspaces import binder/jupyterlab-workspace.json
6 |
7 | exec "$@"
--------------------------------------------------------------------------------
/docs/.nojekyll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pyscal/pyscal3/ae76867ab0a315c39151666a5fda1121f0c4a899/docs/.nojekyll
--------------------------------------------------------------------------------
/docs/_static/img_time_memory.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pyscal/pyscal3/ae76867ab0a315c39151666a5fda1121f0c4a899/docs/_static/img_time_memory.png
--------------------------------------------------------------------------------
/docs/_static/img_time_neighbor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pyscal/pyscal3/ae76867ab0a315c39151666a5fda1121f0c4a899/docs/_static/img_time_neighbor.png
--------------------------------------------------------------------------------
/docs/_static/pyscal_logo1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pyscal/pyscal3/ae76867ab0a315c39151666a5fda1121f0c4a899/docs/_static/pyscal_logo1.png
--------------------------------------------------------------------------------
/docs/_static/pyscal_logo2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pyscal/pyscal3/ae76867ab0a315c39151666a5fda1121f0c4a899/docs/_static/pyscal_logo2.png
--------------------------------------------------------------------------------
/docs/_templates/download.html:
--------------------------------------------------------------------------------
1 | Download this documentation
2 |
3 |
4 | Documentation is available in the following formats
5 | PDF
6 | HTML
7 | Epub
8 |
9 |
--------------------------------------------------------------------------------
/docs/_templates/sidebarhelp.html:
--------------------------------------------------------------------------------
1 | Need help?
2 |
3 |
4 | Raise an issue at the
5 | Github repository
6 | or send an
7 | email.
8 |
9 |
--------------------------------------------------------------------------------
/docs/examples.md:
--------------------------------------------------------------------------------
1 | # Examples
2 |
3 | The gallery of examples below cover different ways in which pyscal can be used.
4 |
5 | ::::{grid} 1 1 2 3
6 | :class-container: text-center
7 | :gutter: 3
8 |
9 | :::{grid-item-card}
10 | :link: ../examples/01_getting_started
11 | :link-type: doc
12 | :class-header: bg-light
13 | Getting started with pyscal
14 | ^^^
15 | Learn the very basis, including the concepts of `System` and `Atoms`.
16 | :::
17 |
18 | :::{grid-item-card}
19 | :link: ../examples/02_creating_structures
20 | :link-type: doc
21 | :class-header: bg-light
22 | Creating structures
23 | ^^^
24 | Create common atomic structures like bcc, fcc; and custom ones. Save and read from files.
25 | :::
26 |
27 | :::{grid-item-card}
28 | :link: ../examples/03_atoms_in_more_detail
29 | :link-type: doc
30 | :class-header: bg-light
31 | More atom manipulation
32 | ^^^
33 | Work in progress
34 | :::
35 |
36 | :::{grid-item-card}
37 | :link: ../examples/04_creating_grain_boundaries
38 | :link-type: doc
39 | :class-header: bg-light
40 | Creating defects
41 | ^^^
42 | Create Grain boundaries and view them.
43 | :::
44 |
45 | :::{grid-item-card}
46 | :link: ../examples/05_finding_neighbors
47 | :link-type: doc
48 | :class-header: bg-light
49 | Finding neighbors
50 | ^^^
51 | Methods such as `cutoff` and its variations, and `voronoi` for finding neighbors.
52 | :::
53 |
54 | :::{grid-item-card}
55 | :link: ../examples/06_steinhardt_parameters
56 | :link-type: doc
57 | :class-header: bg-light
58 | Calculating Steinhardt parameters
59 | ^^^
60 | Combine neighbor calculation with Steinhardt parameters. The original function for which pyscal was developed for.
61 | :::
62 |
63 | :::{grid-item-card}
64 | :link: ../examples/07_disorder_parameters
65 | :link-type: doc
66 | :class-header: bg-light
67 | Disorder parameter
68 | ^^^
69 | Identify disorder in crystals using Steinhardt parameters.
70 | :::
71 |
72 | :::{grid-item-card}
73 | :link: ../examples/08_angular_parameters
74 | :link-type: doc
75 | :class-header: bg-light
76 | Angular parameters
77 | ^^^
78 | Parameters to quantify the angle around an atom, useful for detecting diamond structures.
79 | :::
80 |
81 | :::{grid-item-card}
82 | :link: ../examples/09_distinguishing_solid_liquid
83 | :link-type: doc
84 | :class-header: bg-light
85 | Distinguishing solid and liquid
86 | ^^^
87 | Steinhardt parameter based methods to distinguish solid atoms in liquid. Clustering methods to cluster atoms based on any property.
88 | :::
89 |
90 | :::{grid-item-card}
91 | :link: ../examples/10_voronoi_tessellation
92 | :link-type: doc
93 | :class-header: bg-light
94 | Voronoi tessellation
95 | ^^^
96 | Voronoi tessellation to calculate structural vector and Voronoi volume.
97 | :::
98 |
99 | :::{grid-item-card}
100 | :link: ../examples/11_chi_params
101 | :link-type: doc
102 | :class-header: bg-light
103 | Chi params
104 | ^^^
105 | Angle-based Chi params for structural identification.
106 | :::
107 |
108 | :::{grid-item-card}
109 | :link: ../examples/12_centrosymmetry_parameter
110 | :link-type: doc
111 | :class-header: bg-light
112 | Centrosymmetry parameter
113 | ^^^
114 | Useful parameters for finding breaks in the ordered crystal.
115 | :::
116 |
117 | :::{grid-item-card}
118 | :link: ../examples/13_short_range_order
119 | :link-type: doc
120 | :class-header: bg-light
121 | Chemical short range order
122 | ^^^
123 | Calculate multi-component chemical short range order in alloys.
124 | :::
125 |
126 | :::{grid-item-card}
127 | :link: ../examples/14_common_neighbor_analysis
128 | :link-type: doc
129 | :class-header: bg-light
130 | Common neighbor analysis
131 | ^^^
132 | CNA, adaptive CNA to identify bcc, fcc, and hcp. Extension of CNA to identify various flavors of diamond lattice.
133 | :::
134 |
135 | :::{grid-item-card}
136 | :link: ../examples/15_trajectory_module
137 | :link-type: doc
138 | :class-header: bg-light
139 | pyscal Trajectory
140 | ^^^
141 | Trajectory module enables fast and efficient analysis of LAMMPS dump trajectories.
142 | :::
143 |
144 | :::{grid-item-card}
145 | :link: ../examples/16_entropy_parameter
146 | :link-type: doc
147 | :class-header: bg-light
148 | Entropy parameters
149 | ^^^
150 | Entropy parameter can be used for distinguishing crystal structures.
151 | :::
152 | ::::
153 |
154 |
155 |
--------------------------------------------------------------------------------
/docs/gettingstarted.md:
--------------------------------------------------------------------------------
1 | # Installation
2 |
3 | `pyscal3` can be installed on Linux and Mac OS based systems. On Windows systems, it is recommended to use [Windows subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/install). The following instructions will help install `pyscal3`:
4 |
5 | ````{tab-set}
6 | ```{tab-item} pip
7 | `pip install pyscal3`
8 | ```
9 |
10 | ```{tab-item} conda
11 | `conda install -c conda-forge pyscal3`
12 | ```
13 |
14 | ```{tab-item} from source
15 | We strongly recommend creating a conda environment for the installation. To see how you can install conda see [here](https://docs.conda.io/projects/conda/en/latest/user-guide/install/).
16 |
17 | Once a conda distribution is available, the following steps will help set up an environment to use `pyscal3`. First step is to clone the repository.
18 |
19 | `git clone https://github.com/pyscal/pyscal3.git`
20 |
21 | After cloning, an environment can be created from the included file-
22 |
23 | `cd pyscal3`
24 | `conda env create -f .ci_support/environment.yml`
25 |
26 | This will install the necessary packages and create an environment called rdf. It can be activated by,
27 |
28 | `conda activate pyscal-test`
29 |
30 | then, install `pyscal3` using,
31 |
32 | `pip install .`
33 | ```
34 | ````
35 |
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | .. pyscal documentation master file, created by
2 | sphinx-quickstart on Wed Apr 24 14:11:20 2019.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | pyscal
7 | ======
8 |
9 | .. image:: https://dev.azure.com/sarathrmenon/pyscal/_apis/build/status/srmnitc.pyscal?branchName=master
10 | :target: https://dev.azure.com/sarathrmenon/pyscal/_build/latest?definitionId=1&branchName=master
11 | :width: 20%
12 |
13 | .. image:: https://codecov.io/gh/srmnitc/pyscal/branch/master/graph/badge.svg
14 | :target: https://codecov.io/gh/srmnitc/pyscal
15 | :width: 15 %
16 |
17 | .. image:: https://mybinder.org/badge_logo.svg
18 | :target: https://mybinder.org/v2/gh/srmnitc/pybop/master?filepath=examples%2F
19 | :width: 15 %
20 |
21 | .. image:: https://anaconda.org/pyscal/pyscal/badges/installer/conda.svg
22 | :target: https://anaconda.org/conda-forge/pyscal
23 | :width: 13 %
24 |
25 | .. image:: https://img.shields.io/conda/dn/conda-forge/pyscal.svg
26 | :target: https://conda.anaconda.org/pyscal
27 | :width: 13 %
28 |
29 | .. image:: https://joss.theoj.org/papers/168eca482155601dc517523899527a4e/status.svg
30 | :target: https://joss.theoj.org/papers/168eca482155601dc517523899527a4e
31 | :width: 20 %
32 |
33 | .. image:: https://img.shields.io/conda/pn/conda-forge/pyscal.svg
34 | :target: https://anaconda.org/conda-forge/pyscal
35 | :width: 20 %
36 |
37 |
38 | **pyscal** is a python module for the calculation of local atomic
39 | structural environments including `Steinhardt's bond orientational order
40 | parameters `__
41 | during post-processing of atomistic simulation data. The core
42 | functionality of pyscal is written in C++ with python wrappers using
43 | `pybind11 `__
44 | which allows for fast calculations with possibilities for easy expansion
45 | in python.
46 |
47 | Steinhardt's order parameters are widely used for `identification of
48 | crystal
49 | structures `__.
50 | They are also used to identify if an atom is `solid or
51 | liquid `__. pyscal is
52 | inspired by
53 | `BondOrderAnalysis `__
54 | code, but has since incorporated many additions and modifications.
55 |
56 |
57 | .. toctree::
58 | :hidden:
59 | :maxdepth: 2
60 |
61 | Installation
62 | Why version 3?
63 | Examples
64 | prologue/extending
65 | prologue/helpandsupport
66 | prologue/citing
67 | prologue/acknowledgements
68 | prologue/license
69 |
70 |
--------------------------------------------------------------------------------
/docs/intro.md:
--------------------------------------------------------------------------------
1 |
2 | # pyscal3 - python Structural Environment Calculator
3 |
4 |
5 | **pyscal3** is a completely new version of [pyscal](https://docs.pyscal.org/en/latest/), a python module for the calculation of local atomic structural environments including [Steinhardt's bond orientational order parameters](https://journals.aps.org/prb/abstract/10.1103/PhysRevB.28.784) during post-processing of atomistic simulation data. `pyscal3` is faster and can handle a large number of atoms, with a much more user-friendly and intuitive interface.
6 |
7 | Features of `pyscal3` includes:
8 |
9 | - fast and efficient calculations using C++ and expansion using python.
10 | - more structure creation routines, including defects such as grain boundaries.
11 | - calculation of [Steinhardt's order parameters](https://journals.aps.org/prb/abstract/10.1103/PhysRevB.28.784) and their [averaged version](https://aip.scitation.org/doi/full/10.1063/1.2977970) and [disorder parameters](https://doi.org/10.1063/1.3656762).
12 | - links with [Voro++](http://math.lbl.gov/voro++/)> code, for calculation of [Steinhardt parameters weighted using face area of Voronoi polyhedra](https://aip.scitation.org/doi/full/10.1063/1.4774084).
13 | - classification of atoms as [solid or liquid](https://link.springer.com/chapter/10.1007/b99429).
14 | - clustering of particles based on a user defined property.
15 | - methods for calculating radial distribution function, voronoi volumeof particles, number of vertices and face area of voronoi polyhedra and coordination number.
16 | - calculation of angular parameters such as [for identification of diamond structure](https://journals.aps.org/prb/abstract/10.1103/PhysRevB.47.15717) and [Ackland-Jones](https://doi.org/10.1103/PhysRevB.73.054104) angular parameters.
17 | - [Centrosymmetry parameter](https://doi.org/10.1103/PhysRevB.58.11085) for identification of defects.
18 | - [Adaptive common neighbor analysis](https://iopscience.iop.org/article/10.1088/0965-0393/20/4/045021) for identification of crystal structures.
19 | - [Cowley short-range](https://doi.org/10.1103/PhysRev.120.1648) order parameters.
20 |
21 |
22 | ## Why version 3?
23 |
24 | pyscal v3 is a new version with mostly updated codebase and breaking changes. Anybody who has working pyscal code will need to update it to get it working with this new version. Therefore, it is necessary to discuss why this new version was needed and the benefits of updating.
25 |
26 | ### Version 3 is much faster
27 |
28 | In the plot below, the time needed to calculate neighbors with the 'cutoff' method for systems with varying number of atoms with versions 2.10.15 and 3.0 is shown.
29 |
30 |
31 |
32 | v3 is faster for all system sizes. At a system size of about 50,000 atoms, v3 is about 4x faster.
33 |
34 | ### Version 3 uses less memory
35 |
36 | A major issue with pyscal v2.x series was that it not useful for large system sizes due to the large amount of memory needed. In the plot below, the memory usage of both versions for the same calculation above is shown.
37 |
38 |
39 |
40 | v3 uses less memory, for a system size of 50,000 atoms, v3 uses 14x less memory. A more interesting feature is the slope of the data, or how much the memory scales with the system size. For v3 it is only 0.008, while for v2 it is .12! For a system of 1 million atoms, v2 would use 117 GB of memory while v3 would need only 8 GB, making larger calculations accessible (these numbers will be updated after real use-case tests).
41 |
42 | ### What are reasons for these benefits?
43 |
44 | - The older C++ atoms class is deprecated. Instead, it is store as python dictionary. Therefore the copying between python and C++ sides is avoided.
45 | - The atoms python dictionary is directly exposed to the C++ side. The dictionary is passed by reference, which allows in-place modification directly.
46 |
47 | ### What are the other feature updates?
48 |
49 | The new version includes a number of new features and quality of life improvements. Please check the examples for details.
50 |
51 |
52 | ## Citing the work
53 |
54 | If you use pyscal in your work, the citation of the [following article](https://joss.theoj.org/papers/10.21105/joss.01824) will be greatly appreciated:
55 |
56 | Sarath Menon, Grisell Díaz Leines and Jutta Rogal (2019). pyscal: A python module for structural analysis of atomic environments. Journal of Open Source Software, 4(43), 1824, https://doi.org/10.21105/joss.01824
--------------------------------------------------------------------------------
/docs/license.md:
--------------------------------------------------------------------------------
1 | # License
2 |
3 | pyscal3
4 |
5 | BSD 3-Clause License
6 |
7 | Copyright (c) 2024, Sarath Menon $^1$
8 | $^1$: Max Planck Institut für Eisenforschung, Dusseldorf, Germany
9 | All rights reserved.
10 |
11 | Redistribution and use in source and binary forms, with or without
12 | modification, are permitted provided that the following conditions are met:
13 |
14 | 1. Redistributions of source code must retain the above copyright notice, this
15 | list of conditions and the following disclaimer.
16 |
17 | 2. Redistributions in binary form must reproduce the above copyright notice,
18 | this list of conditions and the following disclaimer in the documentation
19 | and/or other materials provided with the distribution.
20 |
21 | 3. Neither the name of the copyright holder nor the names of its
22 | contributors may be used to endorse or promote products derived from
23 | this software without specific prior written permission.
24 |
25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
29 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 |
36 | For more information contact:
37 | sarath.menon@pyscal.org
--------------------------------------------------------------------------------
/docs/methods/01_neighbors.md:
--------------------------------------------------------------------------------
1 | # Methods to calculate neighbors of a particle
2 |
3 | pyscal3 includes different methods to explore the local environment of a particle that rely on the calculation of nearest neighbors. Various approaches to compute the neighbors of particles are discussed here.
4 |
5 | ## Fixed cutoff method
6 |
7 | The most common method to calculate the nearest neighbors of an atom is using a cutoff radius. Commonly, a cutoff is selected as the first minimum of the radial distribution functions. Once a cutoff is selected, the neighbors of an atom are those that fall within this selected radius. The following code snippet will use the cutoff method to calculate neighbors. In this example, `conf.dump` is assumed to
8 | be the input configuration of the system. A cutoff radius of 3 is assumed for calculation of neighbors.
9 |
10 | ``` python
11 | from pyscal3 import System
12 | sys = pc.System()
13 | sys.read.file('conf.dump')
14 | sys.find.neighbors(method='cutoff', cutoff=3)
15 | ```
16 |
17 | ## Adaptive cutoff methods
18 |
19 | A fixed cutoff radius can introduce limitations to explore the local environment of the particle in some cases:
20 |
21 | - At finite temperatures, when thermal fluctuations take place, the selection of a fixed cutoff may result in an inaccurate description of the local environment.
22 | - If there is more than one structure present in the system, for example, bcc and fcc, the selection of cutoff such that it includes the first shell of both structures can be difficult.
23 |
24 | In order to achieve a more accurate description of the local environment, various adaptive approaches have been proposed. Two of the methods implemented in the module are discussed below.
25 |
26 | ### Solid angle based nearest neighbor algorithm (SANN)
27 |
28 | SANN algorithm [1] determines the cutoff radius by counting the solid angles around an atom and equating it to $4\pi$. The algorithm solves the following equation iteratively.
29 |
30 | $$
31 | R_i^{(m)} = \frac{\sum_{j=1}^m r_{i,j}}{m-2} < r_{i, m+1}
32 | $$
33 |
34 | where $i$ is the host atom, $j$ are its neighbors with $r_{ij}$ is the distance between atoms $i$ and $j$. $R_i$ is the cutoff radius for each particle $i$ which is found by increasing the neighbor of neighbors $m$ iteratively. For a description of the algorithm and more details, please check the reference [1]. SANN algorithm can be used to find the neighbors by,
35 |
36 | ``` python
37 | from pyscal3 import System
38 | sys = pc.System()
39 | sys.read.file('conf.dump')
40 | sys.find.neighbors(method='cutoff', cutoff='sann')
41 | ```
42 |
43 | Since SANN algorithm involves sorting, a sufficiently large cutoff is used in the beginning to reduce the number entries to be sorted. This parameter is calculated by,
44 |
45 | $$
46 | r_{initial} = \mathrm{threshold} \times \bigg(\frac{\mathrm{Simulation~box~volume}}{\mathrm{Number~of~particles}}\bigg)^{\frac{1}{3}}
47 | $$
48 |
49 | a tunable `threshold` parameter can be set through function arguments.
50 |
51 | ### Adaptive cutoff method
52 |
53 | An adaptive cutoff specific for each atom can also be found using an algorithm similar to adaptive common neighbor analysis [2]. This adaptive cutoff is calculated by first making a list of all neighbor
54 | distances for each atom similar to SANN method. Once this list is available, then the cutoff is calculated from,
55 |
56 | $$
57 | r_{cut}(i) = \mathrm{padding}\times \bigg(\frac{1}{\mathrm{nlimit}} \sum_{j=1}^{\mathrm{nlimit}} r_{ij} \bigg)
58 | $$
59 |
60 | This method can be chosen by,
61 |
62 | ``` python
63 | from pyscal3 import System
64 | sys = pc.System()
65 | sys.read.file('conf.dump')
66 | sys.find.neighbors(method='cutoff', cutoff='adaptive')
67 | ```
68 |
69 | The `padding` and `nlimit` parameters in the above equation can be tuned using the respective keywords.
70 |
71 | Either of the adaptive method can be used to find neighbors, which can then be used to calculate Steinhardt\'s parameters or their averaged version.
72 |
73 | ## Voronoi tessellation
74 |
75 | [Voronoi tessellation](https://en.wikipedia.org/wiki/Voronoi_diagram) provides a completely parameter free geometric approach for calculation of neighbors. [Voro++](http://math.lbl.gov/voro++/) code is used for Voronoi tessellation. Neighbors can be calculated using this method by,
76 |
77 | ``` python
78 | from pyscal3 import System
79 | sys = pc.System()
80 | sys.read.file('conf.dump')
81 | sys.find.neighbors(method='voronoi')
82 | ```
83 |
84 | Finding neighbors using Voronoi tessellation also calculates a weight for each neighbor. The weight of a neighbor $j$ towards a host atom $i$ is given by,
85 |
86 | $$
87 | W_{ij} = \frac{A_{ij}}{\sum_{j=1}^N A_{ij}}
88 | $$
89 |
90 | where $A_{ij}$ is the area of Voronoi facet between atom $i$ and $j$, $N$ are all the neighbors identified through Voronoi tessellation. This weight can be used later for calculation of weighted Steinhardt's
91 | parameters. Optionally, it is possible to choose the exponent for this weight. Option `voroexp` is used to set this option. For example if `voroexp=2`, the weight would be calculated as,
92 |
93 | $$
94 | W_{ij} = \frac{A_{ij}^2}{\sum_{j=1}^N A_{ij}^2}
95 | $$
96 |
97 | ## References
98 |
99 | 1. van Meel, J. A., Filion, L., Valeriani, C. & Frenkel, D. A parameter-free, solid-angle based, nearest- neighbor algorithm. J Chem Phys 234107, (2012).
100 | 2. Stukowski, A. Structure identification methods for atomistic simulations of crystalline materials. Modelling and Simulation in Materials Science and Engineering 20, (2012).
101 |
--------------------------------------------------------------------------------
/docs/methods/02_steinhardt.md:
--------------------------------------------------------------------------------
1 | # Steinhardt's parameters
2 |
3 | Steinhardt's bond orientational order parameters [1] are a set of parameters based on [spherical harmonics](https://en.wikipedia.org/wiki/Spherical_harmonics) to explore the local atomic environment. These parameters have been used extensively for various uses such as distinction of crystal structures, identification of solid and liquid atoms and identification of defects.
4 |
5 | These parameters, which are rotationally and translationally invariant are defined by,
6 |
7 | $$
8 | q_l (i) = \Big( \frac{4\pi}{2l+1} \sum_{m=-l}^l | q_{lm}(i) |^2 \Big )^{\frac{1}{2}}
9 | $$
10 |
11 | where,
12 |
13 | $$
14 | q_{lm} (i) = \frac{1}{N(i)} \sum_{j=1}^{N(i)} Y_{lm}(\pmb{r}_{ij})
15 | $$
16 |
17 | in which $Y_{lm}$ are the spherical harmonics and $N(i)$ is the number of neighbours of particle $i$, $\pmb{r}_{ij}$ is the vector connecting particles $i$ and $j$, and $l$ and $m$ are both intergers with $m \in [-l,+l]$. Various parameters have found specific uses, such as $q_2$ and $q_6$ for identification of crystallinity, $q_6$ for identification of solidity, and $q_4$ and $q_6$ for distinction of crystal structures [2]. Commonly this method uses a cutoff radius to identify the neighbors of an atom.
18 | Once the cutoff is chosen and neighbors are calculated, the calculation of Steinhardt's parameters is straightforward.
19 |
20 | ``` python
21 | q = sys.calculate.steinhardt_parameter([4,6])
22 | ```
23 |
24 | ## Averaged Steinhardt's parameters
25 |
26 | At high temperatures, thermal vibrations affect the atomic positions. This in turn leads to overlapping distributions of $q_l$ parameters, which makes the identification of crystal structures difficult. To address this problem, the averaged version $\bar{q}_l$ of Steinhardt's parameters was introduced by Lechner and Dellago [3]. $\bar{q}_l$ is given by,
27 |
28 | $$
29 | \bar{q}_l (i) = \Big( \frac{4\pi}{2l+1} \sum_{m=-l}^l \Big| \frac{1}{\tilde{N}(i)} \sum_{k=0}^{\tilde{N}(i)} q_{lm}(k) \Big|^2 \Big )^{\frac{1}{2}}
30 | $$
31 |
32 | where the sum from $k=0$ to $\tilde{N}(i)$ is over all the neighbors and the particle itself. The averaged parameters takes into account the first neighbor shell and also information from the neighboring atoms and thus reduces the overlap between the distributions. Commonly $\bar{q}_4$ and $\bar{q}_6$ are used in identification of crystal structures.
33 | Averaged versions can be calculated by setting the keyword `averaged=True` as follows.
34 |
35 | ``` python
36 | aq = sys.calculate.steinhardt_parameter([4,6], averaged=True)
37 | ```
38 |
39 | ## Voronoi weighted Steinhardt's parameters
40 |
41 | In order to improve the resolution of crystal structures Mickel et al [2] proposed weighting the contribution of each neighbor to the Steinhardt parameters by the ratio of the area of the Voronoi facet shared between the neighbor and host atom. The weighted parameters are given by,
42 |
43 | $$
44 | q_{lm} (i) = \frac{1}{N(i)} \sum_{j=1}^{N(i)} \frac{A_{ij}}{A} Y_{lm}(\pmb{r}_{ij})
45 | $$
46 |
47 | where $A_{ij}$ is the area of the Voronoi facet between atoms $i$ and $j$ and $A$ is the sum of the face areas of atom $i$. In pyscal, the area weights are already assigned during the neighbor calculation phase when the Voronoi method is used to calculate neighbors. The Voronoi weighted Steinhardt's parameters can be calculated as follows,
48 |
49 | ``` python
50 | sys.find.neighbors(method='voronoi')
51 | q = sys.calculate.steinhardt_parameter([4,6])
52 | ```
53 |
54 | The weighted Steinhardt's parameters can also be averaged as described above. Once again, the keyword `averaged=True` can be used for this purpose.
55 |
56 | ``` python
57 | sys.find_neighbors(method='voronoi')
58 | q = sys.calculate.steinhardt_parameter([4,6], averaged=True)
59 | ```
60 |
61 | It was also proposed that higher powers of the weight [4] $\frac{A_{ij}^{\alpha}}{A(\alpha)}$ where $\alpha = 2, 3$ can also be used, where $A(\alpha) = \sum_{j=1}^{N(i)} A_{ij}^{\alpha}$ The value of this can be set using the keyword `voroexp` during the neighbor calculation phase.
62 |
63 | ``` python
64 | sys.find.neighbors(method='voronoi', voroexp=2)
65 | ```
66 |
67 | If the value of `voroexp` is set to 0, the neighbors would be found using Voronoi method, but the calculated Steinhardt's parameters will not be weighted.
68 |
69 | ## References
70 |
71 | 1. Steinhardt, P. J., Nelson, D. R. & Ronchetti, M. Bond-orientational order in liquids and glasses. Physical Review B 28, 784–805 (1983).
72 | 2. Mickel, W., Kapfer, S. C., Schröder-Turk, G. E. & Mecke, K. Shortcomings of the bond orientational order parameters for the analysis of disordered particulate matter. Journal of Chemical Physics 138, (2013).
73 | 3. Lechner, W. & Dellago, C. Accurate determination of crystal structures based on averaged local bond order parameters. Journal of Chemical Physics 129, (2008).
74 | 4. Haeberle, J., Sperl, M. & Born, P. Distinguishing noisy crystalline structures using bond orientational order parameters. Eur. Phys. J. E 42, 149 (2019).
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/docs/methods/03_solidliquid.md:
--------------------------------------------------------------------------------
1 | # Classification of atoms as solid or liquid
2 |
3 |
4 | pyscal can also be used to distinguish solid and liquid atoms. The classification is based on Steinhardt's parameters,
5 | specifically $q_6$. The method defines two neighboring atoms $i$ and $j$ as having solid bonds if a parameter $s_{ij}$ [1],
6 |
7 | $$
8 | s_{ij} = \sum_{m=-6}^6 q_{6m}(i) q_{6m}^*(j) \geq \mathrm{threshold}
9 | $$
10 |
11 | Additionally, a second order parameter is used to improve the distinction in solid-liquid boundaries [2]. This is defined by the criteria,
12 |
13 | $$
14 | \langle s_{ij} \rangle > \mathrm{avgthreshold}
15 | $$
16 |
17 | If a particle has $n$ number of bonds with $s_{ij} \geq \mathrm{threshold}$ and the above condition is also satisfied, it is considered as a solid. The solid atoms can be clustered to find the largest solid cluster of atoms.
18 |
19 | Finding solid atoms in liquid start with reading in a file and calculation of neighbors.
20 |
21 | ``` python
22 | from pyscal3 import System
23 | sys = System('conf.dump')
24 | sys.find.neighbors(method='cutoff', cutoff=4)
25 | ```
26 |
27 | Once again, there are various methods for finding neighbors. Once the neighbors are calculated, solid atoms can be found directly by,
28 |
29 | ``` python
30 | sys.find.solids(bonds=6, threshold=0.5, avgthreshold=0.6, cluster=True)
31 | ```
32 |
33 | `bonds` set the number of minimum bonds a particle should have (as defined above), `threshold` and `avgthreshold` are the same quantities that appear in the equations above. Setting the keyword `cluster` to True returns the size of the largest solid cluster. It is also possible to check if each atom is solid or not.
34 |
35 | ``` python
36 | sys.atoms.solid
37 | ```
38 |
39 | ## References
40 |
41 | 1. Auer, S. & Frenkel, D. Numerical Simulation of Crystal Nucleation in Colloids. in Advanced Computer Simulation: Approaches for Soft Matter Sciences I (eds. Dr. Holm, C. & Prof. Dr. Kremer, K.) 149–208 (Springer Berlin Heidelberg, Berlin, Heidelberg, 2005). doi:10.1007/b99429.
42 | 2. Bokeloh, J., Wilde, G., Rozas, R. E., Benjamin, R. & Horbach, J. Nucleation barriers for the liquid-to-crystal transition in simple metals: Experiment vs. simulation. European Physical Journal: Special Topics 223, 511–526 (2014).
43 |
44 |
--------------------------------------------------------------------------------
/docs/methods/04_disorder.md:
--------------------------------------------------------------------------------
1 | # Disorder parameter
2 |
3 | Kawasaki and Onuki [1] proposed a disorder variable based on Steinhardt's order paramaters which can be used to distinguish between ordered and disordered structures
4 |
5 | The disorder variable for an atom is defined as,
6 |
7 | $$
8 | D_j = \frac{1}{n_b^j} \sum_{k \in neighbors } [S_{jj} + S_{kk} - 2S_{jk}]
9 | $$
10 |
11 | where S is given by,
12 |
13 | $$
14 | S_{jk} = \sum_{-l \leq m \leq l} q_{lm}^j (q_{lm}^k)^*
15 | $$
16 |
17 | l = 6 was used in the original publication as it is a good indicator of crystallinity. However, l = 4 can also be used for treating bcc structures. An averaged disorder parameter for each atom can also be calculated in pyscal,
18 |
19 | $$
20 | \bar{D}_j = \frac{1}{n_b^j} \sum_{k \in neighbors } D_j
21 | $$
22 |
23 | In pyscal, disorder parameter can be calculated by the following code-block,
24 |
25 | ``` python
26 | from pyscal3 import System
27 | sys = System('conf.dump')
28 | sys.find.neighbors(method='cutoff', cutoff=0)
29 | q = fcc.calculate.steinhardt_parameter(6)
30 | sys.calculate.disorder(averaged=True, q=6)
31 | ```
32 |
33 | The value of q can be replaced with whichever. The calculated values can be accessed by, `sys.atoms.steinhardt.disorder`
34 |
35 | ## References
36 |
37 | 1. Kawasaki, T. & Onuki, A. Construction of a disorder variable from Steinhardt order parameters in binary mixtures at high densities in three dimensions. Journal of Chemical Physics 135, (2011).
38 |
--------------------------------------------------------------------------------
/docs/methods/05_angular.md:
--------------------------------------------------------------------------------
1 | # Angular parameters
2 |
3 | ## Angular criteria for identification of diamond structure
4 |
5 | Angular parameter introduced by Uttormark et al is used to measure the tetrahedrality of local atomic structure. An atom belonging to diamond structure has four nearest neighbors which gives rise to six three body angles around the atom. The angular parameter $A$ is then defined as,
6 |
7 | $$
8 | A = \sum_{i=1}^6 (\cos(\theta_i)+\frac{1}{3})^2
9 | $$
10 |
11 | An atom belonging to diamond structure would show the value of angular params close to 0. Angular parameter can be calculated in pyscal using the following method -
12 |
13 | ``` python
14 | from pyscal3 import System
15 | sys = System('conf.dump')
16 | sys.find.neighbors(method='cutoff', cutoff='adaptive')
17 | sys.calculate.angular_criteria()
18 | ```
19 |
20 | The calculated angular criteria value can be accessed for each atom using `sys.atoms.angular_parameters.diamond_angle`.
21 |
22 | ## $\chi$ parameters for structural identification
23 |
24 | $\chi$ parameters introduced by Ackland and Jones [1] measures all local angles created by an atom with its neighbors and creates a histogram of these angles to produce vector which can be used to identify structures. After finding the neighbors of an atom, $\cos \theta_{ijk}$ for atoms j and k which are neighbors of i is calculated for all combinations of i, j and k. The set of all calculated cosine values are then added to a histogram with the following bins - \[-1.0, -0.945, -0.915, -0.755, -0.705, -0.195, 0.195, 0.245, 0.795, 1.0\]. Compared to $\chi$ parameters from $\chi_0$ to $\chi_7$ in the associated publication, the vector calculated in pyscal contains values from $\chi_0$ to $\chi_8$ which is due to an additional $\chi$ parameter which measures the number of neighbors between cosines -0.705 to -0.195. The $\chi$ vector is characteristic of the local atomic environment and can be used to identify crystal structures, details of which can be found in the publication[1].
25 |
26 | $\chi$ parameters can be calculated in pyscal using,
27 |
28 | ``` python
29 | import pyscal.core as pc
30 | from pyscal3 import System
31 | sys = System('conf.dump')
32 | sys.find.neighbors(method='cutoff', cutoff='adaptive')
33 | sys.calculate.chi_params()
34 | ```
35 |
36 | The calculated values for each atom can be accessed using `sys.atoms.angular_parameters.chi_params`.
37 |
38 | ## References
39 |
40 | 1. Ackland, G. J. & Jones, A. P. Applications of local crystal structure measures in experiment and simulation. Physical Review B - Condensed Matter and Materials Physics 73, 1–7 (2006).
41 |
--------------------------------------------------------------------------------
/docs/methods/06_voronoi.md:
--------------------------------------------------------------------------------
1 | # Voronoi tessellation to identify local structures
2 |
3 | Voronoi tessellation can be used for identification of local structure by counting the number of faces of the Voronoi polyhedra of an atom [1,2]. For each atom a vector $\langle n_3~n_4~n_5~n_6 \rangle$ can be calculated where $n_3$ is the number of Voronoi faces of the associated Voronoi polyhedron with three vertices, $n_4$ is with four vertices and so on. Each perfect crystal structure such as a signature vector, for example, bcc can be identified by $\langle 0~6~0~8 \rangle$
4 | and fcc can be identified using $\langle 0~12~0~0 \rangle$. It is also a useful tool for identifying icosahedral structure which has the fingerprint $\langle 0~0~12~0 \rangle$. In pyscal, the voronoi vector can be calculated using,
5 |
6 | ``` python
7 | from pyscal3 import System
8 | sys = System('conf.dump')
9 | sys.find.neighbors(method='voronoi')
10 | sys.calculate.voronoi_vector()
11 | ```
12 |
13 | The vector for each atom can be accessed using `sys.atoms.voronoi.vector`. Furthermore, the associated Voronoi volume of the polyhedron, which may be indicative of the local structure, is also automatically calculated
14 | when finding neighbors. This value for each atom can be accessed by `sys.atoms.voronoi.volume`.
15 |
16 | ## References
17 |
18 | 1. Finney, J. L. Random Packings and the Structure of Simple Liquids. I. The Geometry of Random Close Packing. Proceedings of the Royal Society A: Mathematical, Physical and Engineering Sciences 319, 479–493 (1970).
19 | 2. Tanemura, M. et al. Geometrical Analysis of Crystallization of the Soft-Core Model. Progress of Theoretical Physics 58, 1079–1095 (1977).
20 |
--------------------------------------------------------------------------------
/docs/methods/07_centrosymmetry.md:
--------------------------------------------------------------------------------
1 | # Centrosymmetry parameter
2 |
3 | Centrosymmetry parameter (CSP) was introduced by Kelchner et al. [1] to identify defects in crystals. The parameter measures the loss of local symmetry. For an atom with $N$ nearest neighbors, the parameter is given by,
4 |
5 | $$
6 | \mathrm{CSP} = \sum_{i=1}^{N/2} \big | \textbf{r}_i + \textbf{r}_{i+N/2} \big |^2
7 | $$
8 |
9 | $\textbf{r}_i$ and $\textbf{r}_{i+N/2}$ are vectors from the central atom to two opposite pairs of neighbors. There are two main methods to identify the opposite pairs of neighbors as described in [this publication](https://arxiv.org/abs/2003.08879). The first of the approaches is called Greedy Edge Selection (GES) [2]
10 | and is implemented in [LAMMPS](https://lammps.sandia.gov/) and [Ovito](https://www.ovito.org/). GES algorithm calculates a weight $w_{ij} = |\textbf{r}_i + \textbf{r}_j|$ for all combinations of neighbors around an atom and calculates CSP over the smallest $N/2$ weights.
11 |
12 | A centrosymmetry parameter calculation using GES algorithm can be carried out as follows-
13 |
14 | ``` python
15 | from pyscal3 import System
16 | sys = System('conf.dump')
17 | csm = sys.calculate.centrosymmetry(nmax = 12)
18 | ```
19 |
20 | `nmax` parameter specifies the number of nearest neighbors to be considered for the calculation of CSP.
21 |
22 | ## References
23 |
24 | 1. Kelchner, C. L., Plimpton, S. J. & Hamilton, J. C. Dislocation nucleation and defect structure during surface indentation. Phys. Rev. B 58, 11085–11088 (1998).
25 | 2. Stukowski, A. Structure identification methods for atomistic simulations of crystalline materials. Modelling and Simulation in Materials Science and Engineering 20, (2012).
26 |
27 |
--------------------------------------------------------------------------------
/docs/methods/08_entropy.md:
--------------------------------------------------------------------------------
1 | # Entropy parameter
2 |
3 | The entropy parameter was introduced by Piaggi et al [1] for identification of defects and distinction between solid and liquid. The entropy paramater $s_s^i$ is defined as,
4 |
5 | $$
6 | s_s^i = -2\pi\rho k_B \int_0^{r_m} [g_m^i(r)\ln g_m^i(r) - g_m^i(r) + 1] r^2 dr
7 | $$
8 |
9 | where $r_m$ is the upper bound of integration and $g_m^i$ is radial distribution function centered on atom $i$,
10 |
11 | $$
12 | g_m^i(r) = \frac{1}{4\pi\rho r^2} \sum_j \frac{1}{\sqrt{2\pi\sigma^2}} \exp{-(r-r_{ij})^2/(2\sigma^2)}
13 | $$
14 |
15 | $r_{ij}$ is the interatomic distance between atom $i$ and its neighbors $j$ and $\sigma$ is a broadening parameter.
16 |
17 | The averaged version of entropy parameters $\bar{s}_s^i$ can be calculated by using a simple averaging over the neighbors given by,
18 |
19 | $$
20 | \bar{s}_s^i = \frac{\sum_j s_s^j + s_s^i}{N + 1}
21 | $$
22 |
23 | Entropy parameters can be calculated in pyscal using the following code,
24 |
25 | ``` python
26 | from pyscal3 import System
27 | sys = System('conf.dump')
28 | sys.find.neighbors(method="cutoff", cutoff=0)
29 | lattice_constant=4.00
30 | avg_entropy = sys.calculate.entropy(1.4*lattice_constant, averaged=True)
31 | ```
32 |
33 | The value of $r_m$ is provided in units of lattice constant. Further parameters shown above, such as $\sigma$ can be specified using the various keyword arguments.
34 |
35 | In pyscal, a slightly different version of $s_s^i$ is calculated. This is given by,
36 |
37 | $$
38 | s_s^i = -\rho \int_0^{r_m} [g_m^i(r)\ln g_m^i(r) - g_m^i(r) + 1] r^2 dr
39 | $$
40 |
41 | The prefactor $2\pi k_B$ is dropped in the entropy values calculated in pyscal.
42 |
43 | ## References
44 |
45 | 1. Piaggi, P. M. & Parrinello, M. Entropy based fingerprint for local crystalline order. Journal of Chemical Physics 147, (2017).
46 |
--------------------------------------------------------------------------------
/docs/methods_landing.md:
--------------------------------------------------------------------------------
1 | # Descriptors
2 |
3 | pyscal can calculate the following descriptors:
4 |
5 | | | | |
6 | | -------- | ------- | ------- |
7 | | Isolating local environment: *Various approaches including fixed cutoff, adaptive cutoff, SANN, and Voronoi* | [Method](methods/01_neighbors) | [Example](../examples/05_finding_neighbors) |
8 | | Bond-orientational order parameters: *For structure identification* | [Method](methods/02_steinhardt) | [Example](../examples/06_steinhardt_parameters) |
9 | | Disorder parameters: *identify regions of disorder in crystalline materials* | [Method](methods/04_disorder) | [Example](../examples/07_disorder_parameters) |
10 | | Angular parameters: *parameters to quantify the angle around an atom, useful for detecting diamond structures.* | [Method](methods/05_angular) | [Example](../examples/08_angular_parameters) |
11 | | Solid identification: *distinguish solid atoms in liquid. Clustering methods to cluster atoms based on any property.* | [Method](methods/03_solidliquid) | [Example](../examples/09_distinguishing_solid_liquid) |
12 | | Voronoi tessellation: *to calculate structural vector and Voronoi volume.* | [Method](methods/06_voronoi) | [Example](../examples/10_voronoi_tessellation) |
13 | | Chi parameters: *angle-based params for structural identification.* | [Method](methods/05_angular) | [Example](../examples/11_chi_params) |
14 | | Centrosymmetry parameter: *for finding breaks in the ordered crystal.* | [Method](methods/07_centrosymmetry) | [Example](../examples/12_centrosymmetry_parameter) |
15 | | Chemical short range order: *multi-component chemical short range order in alloys.* | | [Example](../examples/13_short_range_order) |
16 | | Common neighbor analysis: *CNA, adaptive CNA to identify bcc, fcc, and hcp. Extension of CNA to identify various flavors of diamond lattice.* | | [Example](../examples/14_common_neighbor_analysis) |
17 | | Entropy parameter: *for distinguishing crystal structures.* | [Method](methods/08_entropy) | [Example](../examples/16_entropy_parameter) |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/docs/methodsandexamples.rst:
--------------------------------------------------------------------------------
1 | Methods and examples
2 | --------------------
3 |
4 | .. toctree::
5 |
6 | methodsindex
7 | examplesindex
--------------------------------------------------------------------------------
/docs/methodsindex.rst:
--------------------------------------------------------------------------------
1 | Methods
2 | -------
3 |
4 | .. toctree::
5 |
6 | methods/01_neighbors
7 | methods/02_steinhardt
8 | methods/03_solidliquid
9 | methods/04_disorder
10 | methods/05_angular
11 | methods/06_voronoi
12 | methods/07_centrosymmetry
13 | methods/08_entropy
14 |
15 |
--------------------------------------------------------------------------------
/docs/modules.rst:
--------------------------------------------------------------------------------
1 | pyscal reference
2 | ================
3 |
4 | .. toctree::
5 | :maxdepth: 4
6 |
7 | pyscal
8 |
--------------------------------------------------------------------------------
/docs/prologue/acknowledgements.md:
--------------------------------------------------------------------------------
1 | # Acknowledgements
2 |
3 | ## Developer
4 |
5 | - [Sarath
6 | Menon](http://sarathmenon.me)
7 | sarath.menon@pyscal.org
8 |
9 | ## Contributers
10 |
11 | - [Jan Janßen](https://jan-janssen.com/) - developing and
12 | maintaining a [conda-forge](https://conda-forge.org/) recipe.
13 |
14 | - [Pedro Antonio Santos Flórez](https://github.com/pedroantoniosantosf) - addition of the pairwise multicomponent short range order parameter.
15 |
16 | ## Acknowledgements
17 |
18 | We acknowledge [Bond order
19 | analysis](https://github.com/WolfgangLechner/StructureAnalysis) code for the
20 | inspiration and the base for what later grew to be `pyscal`. We are also
21 | thankful to the developers of [Voro++](math.lbl.gov/voro++/) and
22 | [pybind11](https://pybind11.readthedocs.io/en/stable/) for developing
23 | the great tools that we could use in `pyscal`. We are grateful for the help and support received during the [E-CAM High Throughput Computing ESDW](https://www.e-cam2020.eu/event/4424/?instance_id=71) held in
24 | [Turin](https://www.polito.it/?lang=en) in 2018 and 2019. This module was developed at the [Interdisciplinary Centre for Advanced
25 | Materials Simulation](http://www.icams.de/content), at the [Ruhr
26 | University Bochum](https://www.ruhr-uni-bochum.de/en), Germany.
27 |
28 |
29 | In addition, the following people are acknowledged:
30 |
31 | - Grisell Díaz Leines
32 | - Jutta Rogal
33 | - Alberto Ferrari
34 | - Abril Azócar Guzmán
35 | - Matteo Rinaldi
36 | - Yanyan Liang
37 | - David W.H. Swenson
38 | - Alan O'Cais
39 |
--------------------------------------------------------------------------------
/docs/prologue/api.md:
--------------------------------------------------------------------------------
1 | # API reference
2 |
3 | for pyscal API reference, see [here](https://docs.pyscal.org).
--------------------------------------------------------------------------------
/docs/prologue/citing.md:
--------------------------------------------------------------------------------
1 |
2 | # Citing the code
3 |
4 | If you use pyscal in your work, the citation of the [following
5 | article](https://joss.theoj.org/papers/10.21105/joss.01824) will be
6 | greatly appreciated:
7 |
8 | Sarath Menon, Grisell Díaz Leines and Jutta Rogal (2019). pyscal: A
9 | python module for structural analysis of atomic environments. Journal of
10 | Open Source Software, 4(43), 1824, Makefile.dep
20 |
21 | include Makefile.dep
22 |
23 | libvoro++.a: $(objs)
24 | rm -f libvoro++.a
25 | ar rs libvoro++.a $^
26 |
27 | voro++: libvoro++.a cmd_line.cc
28 | $(CXX) $(CFLAGS) -L. -o voro++ cmd_line.cc -lvoro++
29 |
30 | %.o: %.cc
31 | $(CXX) $(CFLAGS) -c $<
32 |
33 | help: Doxyfile $(SOURCE)
34 | doxygen Doxyfile
35 |
36 | clean:
37 | rm -f $(objs) voro++ libvoro++.a
38 |
39 | .PHONY: all help execs depend
40 |
--------------------------------------------------------------------------------
/lib/voro++/Makefile.dep:
--------------------------------------------------------------------------------
1 | cell.o: cell.cc config.hh common.hh cell.hh
2 | common.o: common.cc common.hh config.hh
3 | container.o: container.cc container.hh config.hh common.hh v_base.hh \
4 | worklist.hh cell.hh c_loops.hh v_compute.hh rad_option.hh
5 | unitcell.o: unitcell.cc unitcell.hh config.hh cell.hh common.hh
6 | v_compute.o: v_compute.cc worklist.hh v_compute.hh config.hh cell.hh \
7 | common.hh rad_option.hh container.hh v_base.hh c_loops.hh \
8 | container_prd.hh unitcell.hh
9 | c_loops.o: c_loops.cc c_loops.hh config.hh
10 | v_base.o: v_base.cc v_base.hh worklist.hh config.hh v_base_wl.cc
11 | wall.o: wall.cc wall.hh cell.hh config.hh common.hh container.hh \
12 | v_base.hh worklist.hh c_loops.hh v_compute.hh rad_option.hh
13 | pre_container.o: pre_container.cc config.hh pre_container.hh c_loops.hh \
14 | container.hh common.hh v_base.hh worklist.hh cell.hh v_compute.hh \
15 | rad_option.hh
16 | container_prd.o: container_prd.cc container_prd.hh config.hh common.hh \
17 | v_base.hh worklist.hh cell.hh c_loops.hh v_compute.hh unitcell.hh \
18 | rad_option.hh
19 |
--------------------------------------------------------------------------------
/lib/voro++/README:
--------------------------------------------------------------------------------
1 | Voro++ library source files
2 | ===========================
3 | This directory contains the source code for the library. For full details of
4 | each file, see the files section of the online reference manual at
5 | http://math.lbl.gov/voro++/doc/refman/
6 |
7 | Several other files are present:
8 |
9 | Makefile - the GNU Makefile controlling the compilation.
10 |
11 | Makefile.dep - a file containing all the dependencies of the source files,
12 | automatically generated by the GNU compiler.
13 |
14 | cmd_line.cc - source file for creating the command-line utility that makes use
15 | of the library.
16 |
17 | Doxyfile - configuration file for Doxygen, used to automatically generate
18 | documentation based on the source code comments.
19 |
20 | worklist_gen.pl - perl script for automatically generating the worklist.hh and
21 | v_base_wl.cc files.
22 |
--------------------------------------------------------------------------------
/lib/voro++/common.cc:
--------------------------------------------------------------------------------
1 | // Voro++, a 3D cell-based Voronoi library
2 | //
3 | // Author : Chris H. Rycroft (LBL / UC Berkeley)
4 | // Email : chr@alum.mit.edu
5 | // Date : August 30th 2011
6 |
7 | /** \file common.cc
8 | * \brief Implementations of the small helper functions. */
9 |
10 | #include "common.hh"
11 |
12 | namespace voro {
13 |
14 | /** \brief Prints a vector of integers.
15 | *
16 | * Prints a vector of integers.
17 | * \param[in] v the vector to print.
18 | * \param[in] fp the file stream to print to. */
19 | void voro_print_vector(std::vector &v,FILE *fp) {
20 | int k=0,s=v.size();
21 | while(k+4 &v,FILE *fp) {
40 | int k=0,s=v.size();
41 | while(k+4 &v,FILE *fp) {
63 | int j,k=0,l;
64 | if(v.size()>0) {
65 | l=v[k++];
66 | if(l<=1) {
67 | if(l==1) fprintf(fp,"(%d)",v[k++]);
68 | else fputs("()",fp);
69 | } else {
70 | j=k+l;
71 | fprintf(fp,"(%d",v[k++]);
72 | while(k
14 | #include
15 | #include
16 |
17 | #include "config.hh"
18 |
19 | namespace voro {
20 |
21 | /** \brief Function for printing fatal error messages and exiting.
22 | *
23 | * Function for printing fatal error messages and exiting.
24 | * \param[in] p a pointer to the message to print.
25 | * \param[in] status the status code to return with. */
26 | inline void voro_fatal_error(const char *p,int status) {
27 | fprintf(stderr,"voro++: %s\n",p);
28 | exit(status);
29 | }
30 |
31 | /** \brief Prints a vector of positions.
32 | *
33 | * Prints a vector of positions as bracketed triplets.
34 | * \param[in] v the vector to print.
35 | * \param[in] fp the file stream to print to. */
36 | inline void voro_print_positions(std::vector &v,FILE *fp=stdout) {
37 | if(v.size()>0) {
38 | fprintf(fp,"(%g,%g,%g)",v[0],v[1],v[2]);
39 | for(int k=3;(unsigned int) k &v,FILE *fp=stdout);
62 | void voro_print_vector(std::vector &v,FILE *fp=stdout);
63 | void voro_print_face_vertices(std::vector &v,FILE *fp=stdout);
64 |
65 | }
66 |
67 | #endif
68 |
--------------------------------------------------------------------------------
/lib/voro++/config.hh:
--------------------------------------------------------------------------------
1 | // Voro++, a 3D cell-based Voronoi library
2 | //
3 | // Author : Chris H. Rycroft (LBL / UC Berkeley)
4 | // Email : chr@alum.mit.edu
5 | // Date : August 30th 2011
6 |
7 | /** \file config.hh
8 | * \brief Master configuration file for setting various compile-time options. */
9 |
10 | #ifndef VOROPP_CONFIG_HH
11 | #define VOROPP_CONFIG_HH
12 |
13 | namespace voro {
14 |
15 | // These constants set the initial memory allocation for the Voronoi cell
16 | /** The initial memory allocation for the number of vertices. */
17 | const int init_vertices=256;
18 | /** The initial memory allocation for the maximum vertex order. */
19 | const int init_vertex_order=64;
20 | /** The initial memory allocation for the number of regular vertices of order
21 | * 3. */
22 | const int init_3_vertices=256;
23 | /** The initial memory allocation for the number of vertices of higher order.
24 | */
25 | const int init_n_vertices=8;
26 | /** The initial buffer size for marginal cases used by the suretest class. */
27 | const int init_marginal=64;
28 | /** The initial size for the delete stack. */
29 | const int init_delete_size=256;
30 | /** The initial size for the auxiliary delete stack. */
31 | const int init_delete2_size=256;
32 | /** The initial size for the wall pointer array. */
33 | const int init_wall_size=32;
34 | /** The default initial size for the ordering class. */
35 | const int init_ordering_size=4096;
36 | /** The initial size of the pre_container chunk index. */
37 | const int init_chunk_size=256;
38 |
39 | // If the initial memory is too small, the program dynamically allocates more.
40 | // However, if the limits below are reached, then the program bails out.
41 | /** The maximum memory allocation for the number of vertices. */
42 | const int max_vertices=16777216;
43 | /** The maximum memory allocation for the maximum vertex order. */
44 | const int max_vertex_order=2048;
45 | /** The maximum memory allocation for the any particular order of vertex. */
46 | const int max_n_vertices=16777216;
47 | /** The maximum buffer size for marginal cases used by the suretest class. */
48 | const int max_marginal=16777216;
49 | /** The maximum size for the delete stack. */
50 | const int max_delete_size=16777216;
51 | /** The maximum size for the auxiliary delete stack. */
52 | const int max_delete2_size=16777216;
53 | /** The maximum amount of particle memory allocated for a single region. */
54 | const int max_particle_memory=16777216;
55 | /** The maximum size for the wall pointer array. */
56 | const int max_wall_size=2048;
57 | /** The maximum size for the ordering class. */
58 | const int max_ordering_size=67108864;
59 | /** The maximum size for the pre_container chunk index. */
60 | const int max_chunk_size=65536;
61 |
62 | /** The chunk size in the pre_container classes. */
63 | const int pre_container_chunk_size=1024;
64 |
65 | #ifndef VOROPP_VERBOSE
66 | /** Voro++ can print a number of different status and debugging messages to
67 | * notify the user of special behavior, and this macro sets the amount which
68 | * are displayed. At level 0, no messages are printed. At level 1, messages
69 | * about unusual cases during cell construction are printed, such as when the
70 | * plane routine bails out due to floating point problems. At level 2, general
71 | * messages about memory expansion are printed. At level 3, technical details
72 | * about memory management are printed. */
73 | #define VOROPP_VERBOSE 0
74 | #endif
75 |
76 | /** If a point is within this distance of a cutting plane, then the code
77 | * assumes that point exactly lies on the plane. */
78 | const double tolerance=1e-11;
79 |
80 | /** If a point is within this distance of a cutting plane, then the code stores
81 | * whether this point is inside, outside, or exactly on the cutting plane in
82 | * the marginal cases buffer, to prevent the test giving a different result on
83 | * a subsequent evaluation due to floating point rounding errors. */
84 | const double tolerance2=2e-11;
85 |
86 | /** The square of the tolerance, used when deciding whether some squared
87 | * quantities are large enough to be used. */
88 | const double tolerance_sq=tolerance*tolerance;
89 |
90 | /** A large number that is used in the computation. */
91 | const double large_number=1e30;
92 |
93 | /** A radius to use as a placeholder when no other information is available. */
94 | const double default_radius=0.5;
95 |
96 | /** The maximum number of shells of periodic images to test over. */
97 | const int max_unit_voro_shells=10;
98 |
99 | /** A guess for the optimal number of particles per block, used to set up the
100 | * container grid. */
101 | const double optimal_particles=5.6;
102 |
103 | /** If this is set to 1, then the code reports any instances of particles being
104 | * put outside of the container geometry. */
105 | #define VOROPP_REPORT_OUT_OF_BOUNDS 0
106 |
107 | /** Voro++ returns this status code if there is a file-related error, such as
108 | * not being able to open file. */
109 | #define VOROPP_FILE_ERROR 1
110 |
111 | /** Voro++ returns this status code if there is a memory allocation error, if
112 | * one of the safe memory limits is exceeded. */
113 | #define VOROPP_MEMORY_ERROR 2
114 |
115 | /** Voro++ returns this status code if there is any type of internal error, if
116 | * it detects that representation of the Voronoi cell is inconsistent. This
117 | * status code will generally indicate a bug, and the developer should be
118 | * contacted. */
119 | #define VOROPP_INTERNAL_ERROR 3
120 |
121 | /** Voro++ returns this status code if it could not interpret the command line
122 | * arguments passed to the command line utility. */
123 | #define VOROPP_CMD_LINE_ERROR 4
124 |
125 | }
126 |
127 | #endif
128 |
--------------------------------------------------------------------------------
/lib/voro++/test.cpp:
--------------------------------------------------------------------------------
1 | #include "voro++.hh"
2 | #include
3 | using namespace voro;
4 | using namespace std;
5 | const int particles=20;
6 |
7 | double rnd() {return double(rand())/RAND_MAX;}
8 |
9 | int main(){
10 |
11 | int i;
12 | int id,nx,ny,nz;
13 | double x,y,z,r,rx,ry,rz;
14 | vector neigh,f_vert;
15 | vector face;
16 | voronoicell_neighbor c;
17 | // Create a container with the geometry given above, and make it
18 | // non-periodic in each of the three coordinates. Allocate space for
19 | // eight particles within each computational block
20 | pre_container pcon(0,1,0,1,0,1,true,true,true,8);
21 | container con(0,1,0,1,0,1,5,5,5,true,true,true,8);
22 |
23 | // Randomly add particles into the container
24 | for(i=0;i
14 |
15 | #include "config.hh"
16 | #include "cell.hh"
17 |
18 | namespace voro {
19 |
20 | /** \brief Class for computation of the unit Voronoi cell associated with
21 | * a 3D non-rectangular periodic domain. */
22 | class unitcell {
23 | public:
24 | /** The x coordinate of the first vector defining the periodic
25 | * domain. */
26 | const double bx;
27 | /** The x coordinate of the second vector defining the periodic
28 | * domain. */
29 | const double bxy;
30 | /** The y coordinate of the second vector defining the periodic
31 | * domain. */
32 | const double by;
33 | /** The x coordinate of the third vector defining the periodic
34 | * domain. */
35 | const double bxz;
36 | /** The y coordinate of the third vector defining the periodic
37 | * domain. */
38 | const double byz;
39 | /** The z coordinate of the third vector defining the periodic
40 | * domain. */
41 | const double bz;
42 | /** The computed unit Voronoi cell corresponding the given
43 | * 3D non-rectangular periodic domain geometry. */
44 | voronoicell unit_voro;
45 | unitcell(double bx_,double bxy_,double by_,double bxz_,double byz_,double bz_);
46 | /** Draws an outline of the domain in Gnuplot format.
47 | * \param[in] filename the filename to write to. */
48 | inline void draw_domain_gnuplot(const char* filename) {
49 | FILE *fp(safe_fopen(filename,"w"));
50 | draw_domain_gnuplot(fp);
51 | fclose(fp);
52 | }
53 | void draw_domain_gnuplot(FILE *fp=stdout);
54 | /** Draws an outline of the domain in Gnuplot format.
55 | * \param[in] filename the filename to write to. */
56 | inline void draw_domain_pov(const char* filename) {
57 | FILE *fp(safe_fopen(filename,"w"));
58 | draw_domain_pov(fp);
59 | fclose(fp);
60 | }
61 | void draw_domain_pov(FILE *fp=stdout);
62 | bool intersects_image(double dx,double dy,double dz,double &vol);
63 | void images(std::vector &vi,std::vector &vd);
64 | protected:
65 | /** The maximum y-coordinate that could possibly cut the
66 | * computed unit Voronoi cell. */
67 | double max_uv_y;
68 | /** The maximum z-coordinate that could possibly cut the
69 | * computed unit Voronoi cell. */
70 | double max_uv_z;
71 | private:
72 | inline void unit_voro_apply(int i,int j,int k);
73 | bool unit_voro_intersect(int l);
74 | inline bool unit_voro_test(int i,int j,int k);
75 | };
76 |
77 | }
78 |
79 | #endif
80 |
--------------------------------------------------------------------------------
/lib/voro++/v_base.cc:
--------------------------------------------------------------------------------
1 | // Voro++, a 3D cell-based Voronoi library
2 | //
3 | // Author : Chris H. Rycroft (LBL / UC Berkeley)
4 | // Email : chr@alum.mit.edu
5 | // Date : August 30th 2011
6 |
7 | /** \file v_base.cc
8 | * \brief Function implementations for the base Voronoi container class. */
9 |
10 | #include "v_base.hh"
11 | #include "config.hh"
12 |
13 | namespace voro {
14 |
15 | /** This function is called during container construction. The routine scans
16 | * all of the worklists in the wl[] array. For a given worklist of blocks
17 | * labeled \f$w_1\f$ to \f$w_n\f$, it computes a sequence \f$r_0\f$ to
18 | * \f$r_n\f$ so that $r_i$ is the minimum distance to all the blocks
19 | * \f$w_{j}\f$ where \f$j>i\f$ and all blocks outside the worklist. The values
20 | * of \f$r_n\f$ is calculated first, as the minimum distance to any block in
21 | * the shell surrounding the worklist. The \f$r_i\f$ are then computed in
22 | * reverse order by considering the distance to \f$w_{i+1}\f$. */
23 | voro_base::voro_base(int nx_,int ny_,int nz_,double boxx_,double boxy_,double boxz_) :
24 | nx(nx_), ny(ny_), nz(nz_), nxy(nx_*ny_), nxyz(nxy*nz_), boxx(boxx_), boxy(boxy_), boxz(boxz_),
25 | xsp(1/boxx_), ysp(1/boxy_), zsp(1/boxz_), mrad(new double[wl_hgridcu*wl_seq_length]) {
26 | const unsigned int b1=1<<21,b2=1<<22,b3=1<<24,b4=1<<25,b5=1<<27,b6=1<<28;
27 | const double xstep=boxx/wl_fgrid,ystep=boxy/wl_fgrid,zstep=boxz/wl_fgrid;
28 | int i,j,k,lx,ly,lz,q;
29 | unsigned int f,*e=const_cast (wl);
30 | double xlo,ylo,zlo,xhi,yhi,zhi,minr,*radp=mrad;
31 | for(zlo=0,zhi=zstep,lz=0;lz>7&127)-64;
39 | k=(f>>14&127)-64;
40 | if((f&b2)==b2) {
41 | compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i-1,j,k);
42 | if((f&b1)==0) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i+1,j,k);
43 | } else if((f&b1)==b1) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i+1,j,k);
44 | if((f&b4)==b4) {
45 | compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j-1,k);
46 | if((f&b3)==0) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j+1,k);
47 | } else if((f&b3)==b3) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j+1,k);
48 | if((f&b6)==b6) {
49 | compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j,k-1);
50 | if((f&b5)==0) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j,k+1);
51 | } else if((f&b5)==b5) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j,k+1);
52 | }
53 | q--;
54 | while(q>0) {
55 | radp[q]=minr;
56 | f=e[q];
57 | i=(f&127)-64;
58 | j=(f>>7&127)-64;
59 | k=(f>>14&127)-64;
60 | compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j,k);
61 | q--;
62 | }
63 | *radp=minr;
64 | e+=wl_seq_length;
65 | radp+=wl_seq_length;
66 | }
67 | }
68 | }
69 | }
70 |
71 | /** Computes the minimum distance from a subregion to a given block. If this distance
72 | * is smaller than the value of minr, then it passes
73 | * \param[in,out] minr a pointer to the current minimum distance. If the distance
74 | * computed in this function is smaller, then this distance is
75 | * set to the new one.
76 | * \param[out] (xlo,ylo,zlo) the lower coordinates of the subregion being
77 | * considered.
78 | * \param[out] (xhi,yhi,zhi) the upper coordinates of the subregion being
79 | * considered.
80 | * \param[in] (ti,tj,tk) the coordinates of the block. */
81 | void voro_base::compute_minimum(double &minr,double &xlo,double &xhi,double &ylo,double &yhi,double &zlo,double &zhi,int ti,int tj,int tk) {
82 | double radsq,temp;
83 | if(ti>0) {temp=boxx*ti-xhi;radsq=temp*temp;}
84 | else if(ti<0) {temp=xlo-boxx*(1+ti);radsq=temp*temp;}
85 | else radsq=0;
86 |
87 | if(tj>0) {temp=boxy*tj-yhi;radsq+=temp*temp;}
88 | else if(tj<0) {temp=ylo-boxy*(1+tj);radsq+=temp*temp;}
89 |
90 | if(tk>0) {temp=boxz*tk-zhi;radsq+=temp*temp;}
91 | else if(tk<0) {temp=zlo-boxz*(1+tk);radsq+=temp*temp;}
92 |
93 | if(radsq(format));
102 |
103 | // Check to see if "%n" appears in the format sequence
104 | while(*fmp!=0) {
105 | if(*fmp=='%') {
106 | fmp++;
107 | if(*fmp=='n') return true;
108 | else if(*fmp==0) return false;
109 | }
110 | fmp++;
111 | }
112 |
113 | return false;
114 | }
115 |
116 | #include "v_base_wl.cc"
117 |
118 | }
119 |
--------------------------------------------------------------------------------
/lib/voro++/v_base.hh:
--------------------------------------------------------------------------------
1 | // Voro++, a 3D cell-based Voronoi library
2 | //
3 | // Author : Chris H. Rycroft (LBL / UC Berkeley)
4 | // Email : chr@alum.mit.edu
5 | // Date : August 30th 2011
6 |
7 | /** \file v_base.hh
8 | * \brief Header file for the base Voronoi container class. */
9 |
10 | #ifndef VOROPP_V_BASE_HH
11 | #define VOROPP_V_BASE_HH
12 |
13 | #include "worklist.hh"
14 |
15 | namespace voro {
16 |
17 | /** \brief Class containing data structures common across all particle container classes.
18 | *
19 | * This class contains constants and data structures that are common across all
20 | * particle container classes. It contains constants setting the size of the
21 | * underlying subgrid of blocks that forms the basis of the Voronoi cell
22 | * computations. It also constructs bound tables that are used in the Voronoi
23 | * cell computation, and contains a number of routines that are common across
24 | * all container classes. */
25 | class voro_base {
26 | public:
27 | /** The number of blocks in the x direction. */
28 | const int nx;
29 | /** The number of blocks in the y direction. */
30 | const int ny;
31 | /** The number of blocks in the z direction. */
32 | const int nz;
33 | /** A constant, set to the value of nx multiplied by ny, which
34 | * is used in the routines that step through blocks in
35 | * sequence. */
36 | const int nxy;
37 | /** A constant, set to the value of nx*ny*nz, which is used in
38 | * the routines that step through blocks in sequence. */
39 | const int nxyz;
40 | /** The size of a computational block in the x direction. */
41 | const double boxx;
42 | /** The size of a computational block in the y direction. */
43 | const double boxy;
44 | /** The size of a computational block in the z direction. */
45 | const double boxz;
46 | /** The inverse box length in the x direction. */
47 | const double xsp;
48 | /** The inverse box length in the y direction. */
49 | const double ysp;
50 | /** The inverse box length in the z direction. */
51 | const double zsp;
52 | /** An array to hold the minimum distances associated with the
53 | * worklists. This array is initialized during container
54 | * construction, by the initialize_radii() routine. */
55 | double *mrad;
56 | /** The pre-computed block worklists. */
57 | static const unsigned int wl[wl_seq_length*wl_hgridcu];
58 | bool contains_neighbor(const char* format);
59 | voro_base(int nx_,int ny_,int nz_,double boxx_,double boxy_,double boxz_);
60 | ~voro_base() {delete [] mrad;}
61 | protected:
62 | /** A custom int function that returns consistent stepping
63 | * for negative numbers, so that (-1.5, -0.5, 0.5, 1.5) maps
64 | * to (-2,-1,0,1).
65 | * \param[in] a the number to consider.
66 | * \return The value of the custom int operation. */
67 | inline int step_int(double a) {return a<0?int(a)-1:int(a);}
68 | /** A custom modulo function that returns consistent stepping
69 | * for negative numbers. For example, (-2,-1,0,1,2) step_mod 2
70 | * is (0,1,0,1,0).
71 | * \param[in] (a,b) the input integers.
72 | * \return The value of a modulo b, consistent for negative
73 | * numbers. */
74 | inline int step_mod(int a,int b) {return a>=0?a%b:b-1-(b-1-a)%b;}
75 | /** A custom integer division function that returns consistent
76 | * stepping for negative numbers. For example, (-2,-1,0,1,2)
77 | * step_div 2 is (-1,-1,0,0,1).
78 | * \param[in] (a,b) the input integers.
79 | * \return The value of a div b, consistent for negative
80 | * numbers. */
81 | inline int step_div(int a,int b) {return a>=0?a/b:-1+(a+1)/b;}
82 | private:
83 | void compute_minimum(double &minr,double &xlo,double &xhi,double &ylo,double &yhi,double &zlo,double &zhi,int ti,int tj,int tk);
84 | };
85 |
86 | }
87 |
88 | #endif
89 |
--------------------------------------------------------------------------------
/lib/voro++/voro++.cc:
--------------------------------------------------------------------------------
1 | // Voro++, a 3D cell-based Voronoi library
2 | //
3 | // Author : Chris H. Rycroft (LBL / UC Berkeley)
4 | // Email : chr@alum.mit.edu
5 | // Date : August 30th 2011
6 |
7 | /** \file voro++.cc
8 | * \brief A file that loads all of the function implementation files. */
9 |
10 | #include "cell.cc"
11 | #include "common.cc"
12 | #include "v_base.cc"
13 | #include "container.cc"
14 | #include "unitcell.cc"
15 | #include "container_prd.cc"
16 | #include "pre_container.cc"
17 | #include "v_compute.cc"
18 | #include "c_loops.cc"
19 | #include "wall.cc"
20 |
--------------------------------------------------------------------------------
/lib/voro++/wall.hh:
--------------------------------------------------------------------------------
1 | // Voro++, a 3D cell-based Voronoi library
2 | //
3 | // Author : Chris H. Rycroft (LBL / UC Berkeley)
4 | // Email : chr@alum.mit.edu
5 | // Date : August 30th 2011
6 |
7 | /** \file wall.hh
8 | * \brief Header file for the derived wall classes. */
9 |
10 | #ifndef VOROPP_WALL_HH
11 | #define VOROPP_WALL_HH
12 |
13 | #include "cell.hh"
14 | #include "container.hh"
15 |
16 | namespace voro {
17 |
18 | /** \brief A class representing a spherical wall object.
19 | *
20 | * This class represents a spherical wall object. */
21 | struct wall_sphere : public wall {
22 | public:
23 | /** Constructs a spherical wall object.
24 | * \param[in] w_id_ an ID number to associate with the wall for
25 | * neighbor tracking.
26 | * \param[in] (xc_,yc_,zc_) a position vector for the sphere's
27 | * center.
28 | * \param[in] rc_ the radius of the sphere. */
29 | wall_sphere(double xc_,double yc_,double zc_,double rc_,int w_id_=-99)
30 | : w_id(w_id_), xc(xc_), yc(yc_), zc(zc_), rc(rc_) {}
31 | bool point_inside(double x,double y,double z);
32 | template
33 | bool cut_cell_base(v_cell &c,double x,double y,double z);
34 | bool cut_cell(voronoicell &c,double x,double y,double z) {return cut_cell_base(c,x,y,z);}
35 | bool cut_cell(voronoicell_neighbor &c,double x,double y,double z) {return cut_cell_base(c,x,y,z);}
36 | private:
37 | const int w_id;
38 | const double xc,yc,zc,rc;
39 | };
40 |
41 | /** \brief A class representing a plane wall object.
42 | *
43 | * This class represents a single plane wall object. */
44 | struct wall_plane : public wall {
45 | public:
46 | /** Constructs a plane wall object.
47 | * \param[in] (xc_,yc_,zc_) a normal vector to the plane.
48 | * \param[in] ac_ a displacement along the normal vector.
49 | * \param[in] w_id_ an ID number to associate with the wall for
50 | * neighbor tracking. */
51 | wall_plane(double xc_,double yc_,double zc_,double ac_,int w_id_=-99)
52 | : w_id(w_id_), xc(xc_), yc(yc_), zc(zc_), ac(ac_) {}
53 | bool point_inside(double x,double y,double z);
54 | template
55 | bool cut_cell_base(v_cell &c,double x,double y,double z);
56 | bool cut_cell(voronoicell &c,double x,double y,double z) {return cut_cell_base(c,x,y,z);}
57 | bool cut_cell(voronoicell_neighbor &c,double x,double y,double z) {return cut_cell_base(c,x,y,z);}
58 | private:
59 | const int w_id;
60 | const double xc,yc,zc,ac;
61 | };
62 |
63 | /** \brief A class representing a cylindrical wall object.
64 | *
65 | * This class represents a open cylinder wall object. */
66 | struct wall_cylinder : public wall {
67 | public:
68 | /** Constructs a cylinder wall object.
69 | * \param[in] (xc_,yc_,zc_) a point on the axis of the
70 | * cylinder.
71 | * \param[in] (xa_,ya_,za_) a vector pointing along the
72 | * direction of the cylinder.
73 | * \param[in] rc_ the radius of the cylinder
74 | * \param[in] w_id_ an ID number to associate with the wall for
75 | * neighbor tracking. */
76 | wall_cylinder(double xc_,double yc_,double zc_,double xa_,double ya_,double za_,double rc_,int w_id_=-99)
77 | : w_id(w_id_), xc(xc_), yc(yc_), zc(zc_), xa(xa_), ya(ya_), za(za_),
78 | asi(1/(xa_*xa_+ya_*ya_+za_*za_)), rc(rc_) {}
79 | bool point_inside(double x,double y,double z);
80 | template
81 | bool cut_cell_base(v_cell &c,double x,double y,double z);
82 | bool cut_cell(voronoicell &c,double x,double y,double z) {return cut_cell_base(c,x,y,z);}
83 | bool cut_cell(voronoicell_neighbor &c,double x,double y,double z) {return cut_cell_base(c,x,y,z);}
84 | private:
85 | const int w_id;
86 | const double xc,yc,zc,xa,ya,za,asi,rc;
87 | };
88 |
89 |
90 | /** \brief A class representing a conical wall object.
91 | *
92 | * This class represents a cone wall object. */
93 | struct wall_cone : public wall {
94 | public:
95 | /** Constructs a cone wall object.
96 | * \param[in] (xc_,yc_,zc_) the apex of the cone.
97 | * \param[in] (xa_,ya_,za_) a vector pointing along the axis of
98 | * the cone.
99 | * \param[in] ang the angle (in radians) of the cone, measured
100 | * from the axis.
101 | * \param[in] w_id_ an ID number to associate with the wall for
102 | * neighbor tracking. */
103 | wall_cone(double xc_,double yc_,double zc_,double xa_,double ya_,double za_,double ang,int w_id_=-99)
104 | : w_id(w_id_), xc(xc_), yc(yc_), zc(zc_), xa(xa_), ya(ya_), za(za_),
105 | asi(1/(xa_*xa_+ya_*ya_+za_*za_)),
106 | gra(tan(ang)), sang(sin(ang)), cang(cos(ang)) {}
107 | bool point_inside(double x,double y,double z);
108 | template
109 | bool cut_cell_base(v_cell &c,double x,double y,double z);
110 | bool cut_cell(voronoicell &c,double x,double y,double z) {return cut_cell_base(c,x,y,z);}
111 | bool cut_cell(voronoicell_neighbor &c,double x,double y,double z) {return cut_cell_base(c,x,y,z);}
112 | private:
113 | const int w_id;
114 | const double xc,yc,zc,xa,ya,za,asi,gra,sang,cang;
115 | };
116 |
117 | }
118 |
119 | #endif
120 |
--------------------------------------------------------------------------------
/lib/voro++/worklist.hh:
--------------------------------------------------------------------------------
1 | // Voro++, a 3D cell-based Voronoi library
2 | //
3 | // Author : Chris H. Rycroft (LBL / UC Berkeley)
4 | // Email : chr@alum.mit.edu
5 | // Date : August 30th 2011
6 |
7 | /** \file worklist.hh
8 | * \brief Header file for setting constants used in the block worklists that are
9 | * used during cell computation.
10 | *
11 | * This file is automatically generated by worklist_gen.pl and it is not
12 | * intended to be edited by hand. */
13 |
14 | #ifndef VOROPP_WORKLIST_HH
15 | #define VOROPP_WORKLIST_HH
16 |
17 | namespace voro {
18 |
19 | /** Each region is divided into a grid of subregions, and a worklist is
20 | # constructed for each. This parameter sets is set to half the number of
21 | # subregions that the block is divided into. */
22 | const int wl_hgrid=4;
23 | /** The number of subregions that a block is subdivided into, which is twice
24 | the value of hgrid. */
25 | const int wl_fgrid=8;
26 | /** The total number of worklists, set to the cube of hgrid. */
27 | const int wl_hgridcu=64;
28 | /** The number of elements in each worklist. */
29 | const int wl_seq_length=64;
30 |
31 | }
32 | #endif
33 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = [
3 | "setuptools",
4 | "wheel",
5 | "pybind11",
6 | ]
7 |
8 | [tool.cibuildwheel]
9 | skip = ["cp36-*", "cp37-*"]
10 |
11 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | numpy
2 | matplotlib
3 | ase
4 | plotly
5 | ipywidgets
6 | pybind11
7 | scipy
8 | spglib
9 | pyyaml
10 | jupyter-book
11 |
--------------------------------------------------------------------------------
/requirements_dev.txt:
--------------------------------------------------------------------------------
1 | pip
2 | pytest
3 | pytest-cov
4 | pytest-benchmark
5 | codecov
6 | h5py
7 | ipywidgets=7.5
8 | plotly=4.11.0
9 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | from pybind11.setup_helpers import Pybind11Extension, build_ext
2 | from setuptools import setup, find_packages
3 |
4 |
5 | with open('README.md') as readme_file:
6 | readme = readme_file.read()
7 |
8 | setup(
9 | name='pyscal3',
10 | version='3.3.0',
11 | author='Sarath Menon',
12 | author_email='sarath.menon@pyscal.org',
13 | description='Python library written in C++ for calculation of local atomic structural environment',
14 | long_description=readme,
15 | long_description_content_type = "text/markdown",
16 | # tell setuptools to look for any packages under 'src'
17 | packages=find_packages('src'),
18 | # tell setuptools that all packages will be under the 'src' directory
19 | # and nowhere else
20 | package_dir={'':'src'},
21 | headers=["src/pyscal3/system.h"],
22 | ext_modules=[
23 | Pybind11Extension(
24 | "pyscal3.csystem",
25 | ["src/pyscal3/neighbor.cpp", "src/pyscal3/sh.cpp",
26 | "src/pyscal3/solids.cpp", "src/pyscal3/voronoi.cpp",
27 | "src/pyscal3/cna.cpp", "src/pyscal3/centrosymmetry.cpp",
28 | "src/pyscal3/entropy.cpp",
29 | "src/pyscal3/system_binding.cpp", "lib/voro++/voro++.cc"],
30 | language='c++',
31 | include_dirs=['lib/voro++'],
32 | extra_compile_args=['-O3'],
33 | ),
34 | ],
35 | # add custom build_ext command
36 | cmdclass={"build_ext": build_ext},
37 | zip_safe=False,
38 | download_url = 'https://anaconda.org/conda-forge/pyscal',
39 | url = 'https://pyscal.org',
40 | install_requires=['pybind11', 'numpy', 'ase', 'pyyaml'],
41 | classifiers=[
42 | 'Programming Language :: Python :: 3'
43 | ],
44 | include_package_data=True,
45 | )
46 |
--------------------------------------------------------------------------------
/src/pyscal3/__init__.py:
--------------------------------------------------------------------------------
1 | from pyscal3.core import System
2 | from pyscal3.atoms import Atoms
3 | from pyscal3.trajectory import Trajectory
--------------------------------------------------------------------------------
/src/pyscal3/ase.py:
--------------------------------------------------------------------------------
1 | import inspect
2 |
3 | from ase.atoms import Atoms
4 |
5 | import pyscal3.core as pc
6 | from pyscal3.operations.centrosymmetry import calculate_centrosymmetry as _calculate_centrosymmetry
7 | from pyscal3.operations.calculations import (
8 | calculate_chiparams as _calculate_chiparams,
9 | calculate_q as _calculate_q,
10 | calculate_rdf as _calculate_rdf,
11 | )
12 | from pyscal3.operations.cna import (
13 | calculate_cna as _calculate_cna,
14 | identify_diamond as _identify_diamond,
15 | )
16 | from pyscal3.operations.identify import find_neighbors
17 | from pyscal3.operations.symmetry import get_symmetry as _get_symmetry
18 |
19 |
20 | def _get_voronoi_volume(system: pc.System) -> pc.System:
21 | """
22 | Calculate the Voronoi volume of atoms
23 |
24 | Parameters
25 | ----------
26 | system: System object
27 |
28 | Returns
29 | -------
30 | np.ndarray: Array of Voronoi volumes for each atom.
31 | """
32 | system.find.neighbors(method="voronoi")
33 | return system
34 |
35 |
36 | def _get_structure(ase_atoms: Atoms) -> pc.System:
37 | return pc.System(ase_atoms, format='ase')
38 |
39 |
40 | def _get_updated_signature(signature: inspect.Signature, add_find_neighbors: bool = False) -> inspect.Signature:
41 | parameters = signature.parameters.copy()
42 | del parameters["system"]
43 | parameters["ase_atoms"] = inspect.Parameter(
44 | name="ase_atoms",
45 | kind=inspect.Parameter.POSITIONAL_OR_KEYWORD,
46 | annotation=Atoms,
47 | )
48 | if add_find_neighbors:
49 | for k, v in inspect.signature(find_neighbors).parameters.items():
50 | if k != "system":
51 | parameters[k] = v
52 | parameters.move_to_end("ase_atoms", last = False)
53 | return signature.replace(parameters=parameters.values())
54 |
55 |
56 | def _wrap_function(funct: callable, add_find_neighbors: bool = False, return_system: bool = False, system_attribute: str = "") -> callable:
57 | sig_updated = _get_updated_signature(
58 | signature=inspect.signature(funct),
59 | add_find_neighbors=add_find_neighbors,
60 | )
61 |
62 | def ase_compatibility_wrapper(*args, **kwargs):
63 | input_dict = sig_updated.bind(*args, **kwargs).arguments
64 | pc_system = _get_structure(input_dict.pop("ase_atoms"))
65 | if add_find_neighbors:
66 | find_neighbor_keys = inspect.signature(find_neighbors).parameters.keys()
67 | find_neighbors_kwargs = {
68 | k: input_dict.pop(k)
69 | for k in find_neighbor_keys
70 | if k != "system" and k in input_dict
71 | }
72 | pc_system.find.neighbors(**find_neighbors_kwargs)
73 | input_dict["system"] = pc_system
74 | if not return_system:
75 | return funct(**input_dict)
76 | elif system_attribute != "":
77 | funct(**input_dict)
78 | obj = pc_system
79 | for attr in system_attribute.split("."):
80 | obj = getattr(obj, attr)
81 | return obj
82 | else:
83 | return pc_system
84 |
85 | ase_compatibility_wrapper.__name__ = funct.__name__
86 | ase_compatibility_wrapper.__signature__ = sig_updated
87 | ase_compatibility_wrapper.__doc__ = funct.__doc__.replace(
88 | "system: System object", "ase_atoms: ase.atoms.Atoms object"
89 | )
90 | return ase_compatibility_wrapper
91 |
92 |
93 | calculate_centrosymmetry = _wrap_function(
94 | funct=_calculate_centrosymmetry,
95 | add_find_neighbors=False,
96 | return_system=False,
97 | system_attribute="",
98 | )
99 | calculate_chiparams = _wrap_function(
100 | funct=_calculate_chiparams,
101 | add_find_neighbors=True,
102 | return_system=True,
103 | system_attribute="atoms.angular_parameters.chi_params",
104 | )
105 | calculate_cna = _wrap_function(
106 | funct=_calculate_cna,
107 | add_find_neighbors=False,
108 | return_system=False,
109 | system_attribute="",
110 | )
111 | calculate_diamond_structure = _wrap_function(
112 | funct=_identify_diamond,
113 | add_find_neighbors=False,
114 | return_system=False,
115 | system_attribute="",
116 | )
117 | calculate_radial_distribution_function = _wrap_function(
118 | funct=_calculate_rdf,
119 | add_find_neighbors=False,
120 | return_system=False,
121 | system_attribute="",
122 | )
123 | calculate_steinhardt_parameter = _wrap_function(
124 | funct=_calculate_q,
125 | add_find_neighbors=True,
126 | return_system=False,
127 | system_attribute="",
128 | )
129 | calculate_voronoi_volume = _wrap_function(
130 | funct=_get_voronoi_volume,
131 | add_find_neighbors=False,
132 | return_system=True,
133 | system_attribute="atoms.voronoi.volume",
134 | )
135 | get_symmetry = _wrap_function(
136 | funct=_get_symmetry,
137 | add_find_neighbors=False,
138 | return_system=False,
139 | system_attribute="",
140 | )
--------------------------------------------------------------------------------
/src/pyscal3/centrosymmetry.cpp:
--------------------------------------------------------------------------------
1 | #include "system.h"
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include "string.h"
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include