├── .gitattributes ├── .github └── workflows │ ├── build.yml │ ├── pypi.yml │ └── testpypi.yml ├── .gitignore ├── .readthedocs.yaml ├── CHANGELOG.md ├── Contributors ├── LICENSE ├── MANIFEST.in ├── README.md ├── conda ├── anaconda_deploy.sh └── meta.yaml ├── docs ├── Makefile ├── _config.yml ├── index.md ├── notebook │ └── lib-usage.ipynb ├── requirements.txt └── source │ ├── _static │ └── favicon.ico │ ├── _templates │ └── layout.html │ ├── cli-usage.rst │ ├── conf.py │ ├── conf.py.tmpl │ ├── endmatter.rst │ ├── examples.rst │ ├── fig │ ├── favicon.ico │ ├── favicon.png │ ├── favicon.svg │ ├── plot1.pdf │ ├── plot1.png │ ├── plot1.svg │ ├── plot2.pdf │ ├── plot2.png │ ├── plot2.svg │ ├── plot3.pdf │ ├── plot3.png │ ├── plot3.svg │ ├── plot3a.pdf │ ├── plot3a.png │ ├── plot3a.svg │ ├── plot3b.pdf │ ├── plot3b.png │ └── plot3b.svg │ ├── index.rst │ ├── intro.rst │ ├── lib-usage.rst │ ├── lib-usage_files │ ├── lib-usage_12_1.png │ ├── lib-usage_18_1.png │ └── lib-usage_9_1.png │ └── modules.rst ├── elastic ├── __init__.py ├── cli │ ├── __init__.py │ └── elastic.py └── elastic.py ├── examples ├── example1.py ├── example2.py ├── example3.py └── scripts │ ├── check-job │ ├── run-on-tsi │ ├── run-vasp5-lock │ └── run_vasp.py ├── paper.bib ├── paper.md ├── parcalc ├── __init__.py └── parcalc.py ├── pyproject.toml ├── requirements.txt ├── setup.py ├── test └── test_elastic.py └── tests ├── data ├── INCAR ├── KPOINTS ├── POSCAR ├── POTCAR ├── abinit ├── calc-cij_000 │ └── vasprun.xml ├── calc-cij_001 │ └── vasprun.xml ├── calc-cij_002 │ └── vasprun.xml ├── calc-cij_003 │ └── vasprun.xml ├── calc-cij_004 │ └── vasprun.xml ├── calc-cij_005 │ └── vasprun.xml ├── calc-cij_006 │ └── vasprun.xml ├── calc-cij_007 │ └── vasprun.xml ├── calc-cij_008 │ └── vasprun.xml ├── calc-cij_009 │ └── vasprun.xml ├── calc-cij_010 │ └── vasprun.xml ├── calc-eos_000 │ └── vasprun.xml ├── calc-eos_001 │ └── vasprun.xml ├── calc-eos_002 │ └── vasprun.xml ├── calc-eos_003 │ └── vasprun.xml ├── calc-eos_004 │ └── vasprun.xml ├── calc-eos_005 │ └── vasprun.xml ├── cij_000.POSCAR ├── cij_001.POSCAR ├── cij_002.POSCAR ├── cij_003.POSCAR ├── cij_004.POSCAR ├── cij_005.POSCAR ├── cij_006.POSCAR ├── cij_007.POSCAR ├── cij_008.POSCAR ├── cij_009.POSCAR ├── cij_010.POSCAR ├── eos_000.POSCAR ├── eos_001.POSCAR ├── eos_002.POSCAR ├── eos_003.POSCAR ├── eos_004.POSCAR ├── eos_005.POSCAR └── run-calcs ├── runtest.sh ├── test_01.py ├── test_02.py └── test_elastic.py /.gitattributes: -------------------------------------------------------------------------------- 1 | 2 | *.ipynb diff=jupyternotebook 3 | 4 | *.ipynb merge=jupyternotebook 5 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build and test 2 | on: workflow_call 3 | 4 | jobs: 5 | build: 6 | name: Build distribution 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@main 11 | with: 12 | fetch-depth: 0 13 | 14 | - name: Set up Python 15 | uses: actions/setup-python@main 16 | with: 17 | python-version: "3.x" 18 | 19 | - name: Install pypa/build 20 | run: >- 21 | python3 -m 22 | pip install 23 | build 24 | --user 25 | 26 | - name: Build a binary wheel and a source tarball 27 | run: python3 -m build 28 | 29 | - name: Test 30 | run: | 31 | python3 -m pip install hypothesis 32 | python3 -m pip install dist/elastic*.whl 33 | elastic --version 34 | python3 -m unittest discover -s test -b 35 | elastic -v --cij proc tests/data/calc-cij_*/vasprun.xml 36 | elastic -v --eos proc tests/data/calc-eos_*/vasprun.xml 37 | 38 | - name: Store the distribution packages 39 | uses: actions/upload-artifact@main 40 | with: 41 | name: python-package-distributions 42 | path: dist/ 43 | 44 | -------------------------------------------------------------------------------- /.github/workflows/pypi.yml: -------------------------------------------------------------------------------- 1 | name: Publish to PyPI 2 | on: 3 | push: 4 | tags: 5 | - 'v*' # matches semantic versioning (e.g., v1.2.3) 6 | branches: 7 | - master 8 | - main 9 | 10 | jobs: 11 | build: 12 | uses: ./.github/workflows/build.yml 13 | 14 | publish-to-pypi: 15 | name: Publish to PyPI 16 | if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes 17 | needs: 18 | - build 19 | runs-on: ubuntu-latest 20 | 21 | environment: 22 | name: pypi 23 | url: https://pypi.org/p/elastic 24 | 25 | permissions: 26 | id-token: write # IMPORTANT: mandatory for trusted publishing 27 | 28 | steps: 29 | - name: Download all the dists 30 | uses: actions/download-artifact@main 31 | with: 32 | name: python-package-distributions 33 | path: dist/ 34 | 35 | - name: Publish to PyPI 36 | uses: pypa/gh-action-pypi-publish@release/v1 37 | -------------------------------------------------------------------------------- /.github/workflows/testpypi.yml: -------------------------------------------------------------------------------- 1 | name: Publish to testPyPI 2 | on: 3 | push: 4 | tags: 5 | - 'v*' # matches semantic versioning (e.g., v1.2.3) 6 | branches: 7 | - dev 8 | - hotfix 9 | 10 | jobs: 11 | build: 12 | uses: ./.github/workflows/build.yml 13 | 14 | publish-to-testpypi: 15 | name: Publish to TestPyPI 16 | # Only on dev pushes 17 | # if: ${{ github.event_name == 'push' && ( github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/master' ) }} 18 | # Run on tagged push 19 | if: startsWith(github.ref, 'refs/tags/') 20 | needs: 21 | - build 22 | runs-on: ubuntu-latest 23 | 24 | environment: 25 | name: testpypi 26 | url: https://test.pypi.org/p/elastic 27 | 28 | permissions: 29 | id-token: write # IMPORTANT: mandatory for trusted publishing 30 | 31 | steps: 32 | - name: Download all the dists 33 | uses: actions/download-artifact@main 34 | with: 35 | name: python-package-distributions 36 | path: dist/ 37 | 38 | - name: Publish distribution to TestPyPI 39 | uses: pypa/gh-action-pypi-publish@release/v1 40 | with: 41 | repository-url: https://test.pypi.org/legacy/ 42 | 43 | 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | 3 | # Backups 4 | *~ 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Packages 10 | *.egg 11 | *.egg-info 12 | .eggs 13 | dist 14 | build 15 | eggs 16 | parts 17 | bin 18 | var 19 | sdist 20 | develop-eggs 21 | .installed.cfg 22 | lib 23 | lib64 24 | __pycache__ 25 | 26 | # Installer logs 27 | pip-log.txt 28 | MANIFEST 29 | __conda_version__.txt 30 | elastic/_version.py 31 | 32 | # Unit test / coverage reports 33 | .coverage 34 | .tox 35 | .hypothesis 36 | nosetests.xml 37 | tests/data/calc-*_*/ 38 | tests/data 39 | docs/notebook 40 | 41 | # Translations 42 | *.mo 43 | 44 | # VSCode 45 | .vscode 46 | 47 | # Mr Developer 48 | .mr.developer.cfg 49 | .project 50 | .pydevproject 51 | .spyproject 52 | 53 | # Notebooks 54 | .ipynb_checkpoints 55 | 56 | -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | # Read the Docs configuration file for Sphinx projects 2 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 3 | 4 | # Required 5 | version: 2 6 | 7 | # Set the OS, Python version and other tools you might need 8 | build: 9 | os: ubuntu-22.04 10 | tools: 11 | python: "3.12" 12 | # You can also specify other tool versions: 13 | # nodejs: "20" 14 | # rust: "1.70" 15 | # golang: "1.20" 16 | 17 | # Build documentation in the "docs/" directory with Sphinx 18 | sphinx: 19 | configuration: docs/source/conf.py 20 | # You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs 21 | # builder: "dirhtml" 22 | # Fail on all warnings to avoid broken references 23 | # fail_on_warning: true 24 | 25 | # Optionally build your docs in additional formats such as PDF and ePub 26 | # formats: 27 | # - pdf 28 | # - epub 29 | 30 | # Optional but recommended, declare the Python requirements required 31 | # to build your documentation 32 | # See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html 33 | python: 34 | install: 35 | - requirements: docs/requirements.txt 36 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | * 5.2.4 2 | - FHI interface 3 | - New spglib api used (pinned >= 2.5.0) 4 | * 5.2.3 5 | - Fix RTD build config 6 | * 5.2.2 7 | - Re-activate RTD build 8 | * 5.2.1 9 | - Fix wrong coefficients in the hexagonal structure 10 | - Fix wrong Cij names in tetragonal structure 11 | - Update use of new spglib API 12 | * 5.2.0 13 | - New build infrastructure (github actions) 14 | - Changelog ;) 15 | -------------------------------------------------------------------------------- /Contributors: -------------------------------------------------------------------------------- 1 | Paweł T. Jochy - Primary developer 2 | Georgios Tritsaris - Siesta computing 3 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | recursive-include docs * 2 | recursive-include test * 3 | recursive-include tests * 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Elastic 2 | ======= 3 | 4 | ![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/jochym/Elastic/pypi.yml) 5 | ![PyPI - Version](https://img.shields.io/pypi/v/elastic) 6 | ![PyPI - Downloads](https://img.shields.io/pypi/dm/elastic?label=PyPi) 7 | ![Conda Version](https://img.shields.io/conda/vn/conda-forge/elastic) 8 | ![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/elastic?label=forge) 9 | ![GitHub License](https://img.shields.io/github/license/jochym/Elastic) 10 | [![DOI](https://zenodo.org/badge/doi/10.5281/zenodo.593721.svg)](https://doi.org/10.5281/zenodo.593721) 11 | [![Documentation Status](https://readthedocs.org/projects/elastic/badge/?version=latest)](https://elastic.readthedocs.io/latest) 12 | 13 | Elastic is a set of python routines for calculation of elastic 14 | properties of crystals (elastic constants, equation of state, sound 15 | velocities, etc.). It is a third version of the in-house code I have 16 | written over few years and is implemented as a extension to the 17 | [ASE](https://wiki.fysik.dtu.dk/ase/) system. The code was a basis for 18 | some of my publications and was described briefly in these papers. The 19 | code was available to anyone, presented at the [Workshop on ab initio 20 | Calculations in Geosciences](http://wolf.ifj.edu.pl/workshop/work2008/) 21 | and used by some of my co-workers. This code is a re-implementation of 22 | elastic as a module for the ASE. 23 | 24 | The on-line documentation is placed on 25 | [ReadTheDocs](http://elastic.rtfd.org/) or [Elastic 26 | website](http://wolf.ifj.edu.pl/elastic/). You can obtain the 27 | [documentation as a PDF 28 | file](https://media.readthedocs.org/pdf/elastic/stable/elastic.pdf) as 29 | well. 30 | 31 | 32 | Installation 33 | ------------ 34 | 35 | The installation is simple if you are using conda package menager: 36 | 37 | conda install -c conda-forge elastic 38 | 39 | If you need a more elaborate [installation 40 | instruction](http://nbviewer.ipython.org/github/jochym/qe-doc/blob/master/Installation.ipynb) 41 | for computing environment to work with ASE - I have written just such a 42 | document. It is a first in the series of tutorials of this subject and 43 | you can find it under nbviewer link above. 44 | 45 | The project is open and I welcome patches, ideas and other feedback. 46 | 47 | Acknowledgments 48 | --------------- 49 | 50 | In the past the project was partially supported by: 51 | 52 | - Department of Computational Material Science, Institute of Nuclear 53 | Physics, PAN, Poland 54 | - Department of Engineering, University of Saskatchewan, Canada 55 | -------------------------------------------------------------------------------- /conda/anaconda_deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export LBL=$1 4 | export TKN=$2 5 | export GIT_BRANCH=$3 6 | 7 | conda install conda-build anaconda-client --yes 8 | conda build conda --no-anaconda-upload 9 | TRG=`conda build conda --output |sed -e 's/--/-*-/'` 10 | echo "Uploading: $TRG to $LBL" 11 | anaconda --token $TKN upload --label $LBL $TRG 12 | 13 | -------------------------------------------------------------------------------- /conda/meta.yaml: -------------------------------------------------------------------------------- 1 | package: 2 | name: elastic 3 | version: {{ environ.get('GIT_DESCRIBE_TAG', '') | replace('v','',1) }} 4 | 5 | source: 6 | git_url: https://github.com/jochym/Elastic.git 7 | git_branch: {{ environ.get('GIT_BRANCH','master') }} 8 | 9 | build: 10 | preserve_egg_dir: True 11 | number: {{ environ.get('GIT_DESCRIBE_NUMBER', 0) }} 12 | script: python setup.py install 13 | entry_points: 14 | # Put any entry points (scripts to be generated automatically) here. The 15 | # syntax is module:function. For example 16 | # 17 | # - elastic = elastic:main 18 | # 19 | # Would create an entry point called elastic that calls elastic.main() 20 | - elastic = elastic.cli.elastic:cli 21 | 22 | 23 | # If this is a new build for the same version, increment the build 24 | # number. If you do not include this key, it defaults to 0. 25 | number: {{ GIT_DESCRIBE_NUMBER }} 26 | 27 | requirements: 28 | build: 29 | - python 30 | - future 31 | - setuptools 32 | - setuptools_scm 33 | - sphinx 34 | - docutils 35 | - click 36 | 37 | run: 38 | - python 39 | - ase 40 | - numpy 41 | - scipy 42 | - spglib 43 | - future 44 | - click 45 | 46 | test: 47 | source_files: 48 | - test 49 | - tests 50 | requires: 51 | - hypothesis 52 | imports: 53 | - elastic 54 | commands: 55 | - python -m unittest discover -s test 56 | - elastic --version 57 | - elastic -v --cij proc tests/data/calc-cij_*/vasprun.xml 58 | 59 | 60 | about: 61 | home: https://github.com/jochym/Elastic 62 | license: GPLv3 63 | summary: 'Extension for ASE to calculate elastic constants' 64 | 65 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = build 9 | 10 | # Internal variables. 11 | PAPEROPT_a4 = -D latex_paper_size=a4 12 | PAPEROPT_letter = -D latex_paper_size=letter 13 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source 14 | 15 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest 16 | 17 | help: 18 | @echo "Please use \`make ' where is one of" 19 | @echo " html to make standalone HTML files" 20 | @echo " dirhtml to make HTML files named index.html in directories" 21 | @echo " singlehtml to make a single large HTML file" 22 | @echo " pickle to make pickle files" 23 | @echo " json to make JSON files" 24 | @echo " htmlhelp to make HTML files and a HTML help project" 25 | @echo " qthelp to make HTML files and a qthelp project" 26 | @echo " devhelp to make HTML files and a Devhelp project" 27 | @echo " epub to make an epub" 28 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 29 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 30 | @echo " text to make text files" 31 | @echo " man to make manual pages" 32 | @echo " changes to make an overview of all changed/added/deprecated items" 33 | @echo " linkcheck to check all external links for integrity" 34 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 35 | 36 | clean: 37 | -rm -rf $(BUILDDIR)/* 38 | 39 | html: 40 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 41 | @echo 42 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 43 | 44 | dirhtml: 45 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 46 | @echo 47 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 48 | 49 | singlehtml: 50 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 51 | @echo 52 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 53 | 54 | pickle: 55 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 56 | @echo 57 | @echo "Build finished; now you can process the pickle files." 58 | 59 | json: 60 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 61 | @echo 62 | @echo "Build finished; now you can process the JSON files." 63 | 64 | htmlhelp: 65 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 66 | @echo 67 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 68 | ".hhp project file in $(BUILDDIR)/htmlhelp." 69 | 70 | qthelp: 71 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 72 | @echo 73 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 74 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 75 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Elastic.qhcp" 76 | @echo "To view the help file:" 77 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Elastic.qhc" 78 | 79 | devhelp: 80 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 81 | @echo 82 | @echo "Build finished." 83 | @echo "To view the help file:" 84 | @echo "# mkdir -p $$HOME/.local/share/devhelp/Elastic" 85 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Elastic" 86 | @echo "# devhelp" 87 | 88 | epub: 89 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 90 | @echo 91 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 92 | 93 | latex: 94 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 95 | @echo 96 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 97 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 98 | "(use \`make latexpdf' here to do that automatically)." 99 | 100 | latexpdf: 101 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 102 | @echo "Running LaTeX files through pdflatex..." 103 | make -C $(BUILDDIR)/latex all-pdf 104 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 105 | 106 | text: 107 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 108 | @echo 109 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 110 | 111 | man: 112 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 113 | @echo 114 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 115 | 116 | changes: 117 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 118 | @echo 119 | @echo "The overview file is in $(BUILDDIR)/changes." 120 | 121 | linkcheck: 122 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 123 | @echo 124 | @echo "Link check complete; look for any errors in the above output " \ 125 | "or in $(BUILDDIR)/linkcheck/output.txt." 126 | 127 | doctest: 128 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 129 | @echo "Testing of doctests in the sources finished, look at the " \ 130 | "results in $(BUILDDIR)/doctest/output.txt." 131 | -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | title: Elastic 2 | description: A module for ASE for elastic constants calculation. 3 | google_analytics: UA-4999088-11 4 | show_downloads: true 5 | theme: jekyll-theme-dinky 6 | 7 | gems: 8 | - jekyll-mentions 9 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | Elastic 2 | ======= 3 | 4 | ![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/jochym/Elastic/pypi.yml) 5 | ![PyPI - Version](https://img.shields.io/pypi/v/elastic) 6 | ![PyPI - Downloads](https://img.shields.io/pypi/dm/elastic?label=PyPi) 7 | ![Conda Version](https://img.shields.io/conda/vn/conda-forge/elastic) 8 | ![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/elastic?label=forge) 9 | ![GitHub License](https://img.shields.io/github/license/jochym/Elastic) 10 | [![DOI](https://zenodo.org/badge/doi/10.5281/zenodo.593721.svg)](https://doi.org/10.5281/zenodo.593721) 11 | [![Documentation Status](https://readthedocs.org/projects/elastic/badge/?version=latest)](https://elastic.readthedocs.io/en/latest/?badge=latest) 12 | 13 | Elastic is a set of python routines for calculation of elastic 14 | properties of crystals (elastic constants, equation of state, sound 15 | velocities, etc.). It is a third version of the in-house code I have 16 | written over few years and is implemented as a extension to the 17 | [ASE](https://wiki.fysik.dtu.dk/ase/) system. The code was a basis for 18 | some of my publications and was described briefly in these papers. The 19 | code was available to anyone, presented at the [Workshop on ab initio 20 | Calculations in Geosciences](http://wolf.ifj.edu.pl/workshop/work2008/) 21 | and used by some of my co-workers. This code is a re-implementation of 22 | elastic as a module for the ASE. 23 | 24 | The on-line documentation is placed on 25 | [ReadTheDocs](http://elastic.rtfd.org/) or [Elastic 26 | website](http://wolf.ifj.edu.pl/elastic/). You can obtain the 27 | [documentation as a PDF 28 | file](https://media.readthedocs.org/pdf/elastic/stable/elastic.pdf) as 29 | well. 30 | 31 | 32 | Installation 33 | ------------ 34 | 35 | The installation is simple if you are using conda package menager: 36 | 37 | conda install -c conda-forge elastic 38 | 39 | If you need a more elaborate [installation 40 | instruction](http://nbviewer.ipython.org/github/jochym/qe-doc/blob/master/Installation.ipynb) 41 | for computing environment to work with ASE - I have written just such a 42 | document. It is a first in the series of tutorials of this subject and 43 | you can find it under nbviewer link above. 44 | 45 | The project is open and I welcome patches, ideas and other feedback. 46 | 47 | Acknowledgments 48 | --------------- 49 | 50 | In the past the project was partially supported by: 51 | 52 | - Department of Computational Material Science, Institute of Nuclear 53 | Physics, PAN, Poland 54 | - Department of Engineering, University of Saskatchewan, Canada 55 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | sphinx-rtd-theme 2 | -------------------------------------------------------------------------------- /docs/source/_static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jochym/Elastic/a8f63b811481439084727062d9c8b2ab8f869376/docs/source/_static/favicon.ico -------------------------------------------------------------------------------- /docs/source/_templates/layout.html: -------------------------------------------------------------------------------- 1 | {% extends "!layout.html" %} 2 | 3 | {%- block extrahead %} 4 | {{ super() }} 5 | 18 | 19 | {% endblock %} 20 | 21 | {% block sidebarsearch %} 22 | {{ super() }} 23 |
24 | 25 |
26 | {% endblock %} 27 | 28 | {% block footer %} 29 | {{ super() }} 30 | 34 | {% endblock %} 35 | 36 | -------------------------------------------------------------------------------- /docs/source/cli-usage.rst: -------------------------------------------------------------------------------- 1 | Installation 2 | ============ 3 | 4 | .. image:: https://anaconda.org/conda-forge/elastic/badges/version.svg 5 | :target: https://anaconda.org/conda-forge/elastic 6 | .. image:: https://anaconda.org/conda-forge/elastic/badges/latest_release_date.svg 7 | :target: https://anaconda.org/conda-forge/elastic 8 | .. image:: https://anaconda.org/conda-forge/elastic/badges/platforms.svg 9 | :target: https://anaconda.org/conda-forge/elastic 10 | 11 | Conda 12 | ------- 13 | 14 | .. highlight:: bash 15 | 16 | The installation procedure is quite simple if you use, *highly recommended* 17 | `conda package manager `_:: 18 | 19 | conda install -c conda-forge elastic 20 | 21 | The above command installs elastic with all dependencies into your current 22 | conda environment. If you want to add my anaconda.org channel into your conda 23 | installation you need to run following command:: 24 | 25 | conda config --add channels conda-forge 26 | 27 | The above method has additional benefit of providing current installation of 28 | ASE and spglib libraries. 29 | 30 | PyPi 31 | ------ 32 | 33 | The package is published simultaneously on conda and pypi. The second 34 | recommended way to install elastic is with pip:: 35 | 36 | pip install elastic 37 | 38 | which should install the package and all its dependencies. 39 | Note that the number of dependencies is rather large and some of them are 40 | fairly large. Most of them, however, are just standard scientific python 41 | packages - almost all are present in standard anaconda install. 42 | 43 | 44 | Manual 45 | -------- 46 | 47 | To install the code *pedestrian way* you need to install following python 48 | packages (most, if not all, are available in major linux distributions): 49 | 50 | * `SciPy and NumPy `_ libraries 51 | * `matplotlib `_ (not strictly required, 52 | but needed for testing and plotting) 53 | * `ASE `_ system 54 | * `spglib `_ space group library 55 | * Some ASE calculator (VASP, GPAW, abinit, ...), but be warned 56 | that for now the code was developed using VASP only. I will be happy to 57 | help you extending it to other calculators. The code can be used without 58 | supported ASE calculator using command line interface and external, 59 | independent calculation tool. 60 | 61 | This is highly system-dependent and I am unable to provide detailed support for 62 | this type of install - I use conda install of ASE/elastic myself! 63 | 64 | Some legacy `installation guides `_ 65 | which may help you with manual process could be find at the 66 | `QE-doc project pages `_. 67 | 68 | Essentially, you need to clone the repository and run:: 69 | 70 | python setup.py install 71 | 72 | in the main directory. But this is really not recommended way to install. 73 | Use it at your own risk and if you know what you are doing. 74 | 75 | Testing 76 | ------- 77 | 78 | The simplest verification if everything works is just using the ``elastic`` 79 | utility to see the help screen:: 80 | 81 | elastic --help 82 | 83 | or version of the package:: 84 | 85 | elastic --version 86 | 87 | Additionally the whole package has a set of unittests based on hypothesis 88 | package. The tests are self-contained and do not require any external packages 89 | like DFT programs (e.g. VASP). You can run these tests by executing 90 | following command in the source directory:: 91 | 92 | python -m unittest discover -s test -b 93 | 94 | 95 | Usage 96 | ===== 97 | 98 | Starting from ver. 5.0, the command line utility ``elastic`` is a primary 99 | interface to the package and the direct python programming with the library 100 | is relegated to non-standard calculations. 101 | The basic calculation scheme can be summarized with the following list: 102 | 103 | * Prepare the basic structure data in the form of VASP POSCAR file or 104 | abinit input file. Support for other programs can be added relatively 105 | easily. Contact the author if you need it. 106 | The structure should be fully optimized represent what you consider to 107 | be ground state of the system. 108 | 109 | * run ``elastic`` on the structure to generate deformed structures probing 110 | the properties of the system:: 111 | 112 | elastic -v --cij gen -n 5 -s 2 POSCAR 113 | 114 | which generates a set of deformed systems named ``cij_XXX.POSCAR``, where 115 | ``XXX`` is replaced by numbers with 000 corresponding to undisturbed structure. 116 | 117 | * run your DFT program (VASP, abinit, etc.) on all systems. This step depends 118 | on your particular system, and you need to handle it yourself. You need to 119 | make sure that for each system the internal degrees of freedom are 120 | optimized and full stress tensor gets calculated. Example 121 | bash script handling this task on my cluster looks like this:: 122 | 123 | #!/bin/bash 124 | 125 | # Command to run vasp in current directory 126 | RUN_VASP="/opt/bin/run-vasp541" 127 | 128 | for s in $* ; do 129 | d=${s%%.POSCAR} 130 | echo -n $d ": " 131 | mkdir calc-$d 132 | ( 133 | cd calc-$d 134 | ln -s ../INCAR ../KPOINTS ../POTCAR ../vasprun.conf . 135 | ln -s ../$s POSCAR 136 | $RUN_VASP 137 | ) 138 | done 139 | 140 | This produces a set of directories: ``calc-cij_XXX`` with completed 141 | single-point calculations. 142 | 143 | * run ``elastic`` again to post-process the calculations. 144 | We do that by feeding it with output from the DFT calculations. 145 | Remember to put undisturbed structure at the first position:: 146 | 147 | elastic -v --cij proc calc-cij_000/vasprun.xml calc-cij_*/vasprun.xml 148 | 149 | .. highlight:: console 150 | 151 | You can test this procedure using data provided as a reference in the 152 | ``tests/data`` directory. If you run the script on the provided data you 153 | should get following output:: 154 | 155 | elastic -v --cij proc calc-cij_000/vasprun.xml calc-cij_*/vasprun.xml 156 | 157 | Cij solution 158 | ------------------------------ 159 | Solution rank: 3 160 | Square of residuals: 0.00053 161 | Relative singular values: 162 | 1.0000 0.7071 0.6354 163 | 164 | Elastic tensor (GPa): 165 | C_11 C_12 C_44 166 | ------------------------------ 167 | 321.15 95.88 143.44 168 | 169 | The data provided correspond to cubic MgO crystal. The DFT calculation setup 170 | is tuned to provide quick results for testing and *should not* be used as 171 | a guide for production calculations. You *need* to determine proper 172 | calculation setup for your system. 173 | -------------------------------------------------------------------------------- /docs/source/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Elastic documentation build configuration file, created by 4 | # sphinx-quickstart on Sun Aug 7 17:19:50 2011. 5 | # 6 | # This file is execfile()d with the current directory set to its containing dir. 7 | # 8 | # Note that not all possible configuration values are present in this 9 | # autogenerated file. 10 | # 11 | # All configuration values have a default; values that are commented out 12 | # serve to show the default. 13 | 14 | import sys, os 15 | 16 | # If extensions (or modules to document with autodoc) are in another directory, 17 | # add these directories to sys.path here. If the directory is relative to the 18 | # documentation root, use os.path.abspath to make it absolute, like shown here. 19 | sys.path.insert(0, os.path.abspath('../..')) 20 | sys.path.insert(0, os.path.abspath('../../example')) 21 | 22 | # -- General configuration ----------------------------------------------------- 23 | 24 | # If your documentation needs a minimal Sphinx version, state it here. 25 | # needs_sphinx = '1.6' 26 | 27 | # Add any Sphinx extension module names here, as strings. They can be extensions 28 | # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. 29 | extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.mathjax', 'sphinx.ext.viewcode'] 30 | 31 | # Add any paths that contain templates here, relative to this directory. 32 | templates_path = ['_templates'] 33 | 34 | # The suffix of source filenames. 35 | source_suffix = '.rst' 36 | 37 | # The encoding of source files. 38 | #source_encoding = 'utf-8-sig' 39 | 40 | # The master toctree document. 41 | master_doc = 'index' 42 | 43 | # General information about the project. 44 | project = u'Elastic' 45 | copyright = u'2017, Paweł T. Jochym' 46 | 47 | # The version info for the project you're documenting, acts as replacement for 48 | # |version| and |release|, also used in various other places throughout the 49 | # built documents. 50 | # 51 | # The short X.Y version. 52 | import subprocess 53 | release = subprocess.check_output(["git", "describe", "--tags","--always"]).decode('utf-8') 54 | version = release 55 | 56 | # The language for content autogenerated by Sphinx. Refer to documentation 57 | # for a list of supported languages. 58 | #language = None 59 | 60 | # There are two options for replacing |today|: either, you set today to some 61 | # non-false value, then it is used: 62 | #today = '' 63 | # Else, today_fmt is used as the format for a strftime call. 64 | #today_fmt = '%B %d, %Y' 65 | 66 | # List of patterns, relative to source directory, that match files and 67 | # directories to ignore when looking for source files. 68 | exclude_patterns = [] 69 | 70 | # The reST default role (used for this markup: `text`) to use for all documents. 71 | #default_role = None 72 | 73 | # If true, '()' will be appended to :func: etc. cross-reference text. 74 | #add_function_parentheses = True 75 | 76 | # If true, the current module name will be prepended to all description 77 | # unit titles (such as .. function::). 78 | #add_module_names = True 79 | 80 | # If true, sectionauthor and moduleauthor directives will be shown in the 81 | # output. They are ignored by default. 82 | #show_authors = False 83 | 84 | # The name of the Pygments (syntax highlighting) style to use. 85 | #pygments_style = 'sphinx' 86 | 87 | # A list of ignored prefixes for module index sorting. 88 | #modindex_common_prefix = [] 89 | 90 | 91 | # -- Options for HTML output --------------------------------------------------- 92 | 93 | # The theme to use for HTML and HTML Help pages. See the documentation for 94 | # a list of builtin themes. 95 | # html_theme = 'bizstyle' 96 | # html_theme = 'sphinxdoc' 97 | # html_theme = 'default' 98 | html_theme = 'sphinx_rtd_theme' 99 | 100 | #jsmath_path = 'jsmath/easy/load.js' 101 | 102 | # Theme options are theme-specific and customize the look and feel of a theme 103 | # further. For a list of options available for each theme, see the 104 | # documentation. 105 | html_theme_options = { 106 | 'display_version': True, 107 | } 108 | 109 | # Add any paths that contain custom themes here, relative to this directory. 110 | #html_theme_path = [] 111 | 112 | # The name for this set of Sphinx documents. If None, it defaults to 113 | # " v documentation". 114 | #html_title = None 115 | 116 | # A shorter title for the navigation bar. Default is the same as html_title. 117 | #html_short_title = None 118 | 119 | # The name of an image file (relative to this directory) to place at the top 120 | # of the sidebar. 121 | #html_logo = None 122 | 123 | # The name of an image file (within the static path) to use as favicon of the 124 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 125 | # pixels large. 126 | html_favicon = "favicon.ico" 127 | 128 | # Add any paths that contain custom static files (such as style sheets) here, 129 | # relative to this directory. They are copied after the builtin static files, 130 | # so a file named "default.css" will overwrite the builtin "default.css". 131 | html_static_path = ['_static'] 132 | 133 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 134 | # using the given strftime format. 135 | html_last_updated_fmt = '%b %d, %Y' 136 | 137 | # If true, SmartyPants will be used to convert quotes and dashes to 138 | # typographically correct entities. 139 | #html_use_smartypants = True 140 | 141 | # Custom sidebar templates, maps document names to template names. 142 | #html_sidebars = {} 143 | 144 | # Additional templates that should be rendered to pages, maps page names to 145 | # template names. 146 | #html_additional_pages = {} 147 | 148 | # If false, no module index is generated. 149 | #html_domain_indices = True 150 | 151 | # If false, no index is generated. 152 | #html_use_index = True 153 | 154 | # If true, the index is split into individual pages for each letter. 155 | #html_split_index = False 156 | 157 | # If true, links to the reST sources are added to the pages. 158 | #html_show_sourcelink = True 159 | 160 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 161 | #html_show_sphinx = True 162 | 163 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 164 | #html_show_copyright = True 165 | 166 | # If true, an OpenSearch description file will be output, and all pages will 167 | # contain a tag referring to it. The value of this option must be the 168 | # base URL from which the finished HTML is served. 169 | #html_use_opensearch = '' 170 | 171 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 172 | #html_file_suffix = None 173 | 174 | # Output file base name for HTML help builder. 175 | htmlhelp_basename = 'Elasticdoc' 176 | 177 | 178 | # -- Options for LaTeX output -------------------------------------------------- 179 | 180 | # The paper size ('letter' or 'a4'). 181 | latex_paper_size = 'a4' 182 | 183 | # The font size ('10pt', '11pt' or '12pt'). 184 | #latex_font_size = '10pt' 185 | 186 | # Grouping the document tree into LaTeX files. List of tuples 187 | # (source start file, target name, title, author, documentclass [howto/manual]). 188 | latex_documents = [ 189 | ('index', 'Elastic.tex', u'Elastic', 190 | u'Paweł T. Jochym', 'manual'), 191 | ] 192 | 193 | # The name of an image file (relative to this directory) to place at the top of 194 | # the title page. 195 | #latex_logo = None 196 | 197 | # For "manual" documents, if this is true, then toplevel headings are parts, 198 | # not chapters. 199 | #latex_use_parts = False 200 | 201 | # If true, show page references after internal links. 202 | #latex_show_pagerefs = False 203 | 204 | # If true, show URL addresses after external links. 205 | #latex_show_urls = False 206 | 207 | # Additional stuff for the LaTeX preamble. 208 | #latex_preamble = '' 209 | 210 | # Documents to append as an appendix to all manuals. 211 | #latex_appendices = [] 212 | 213 | # If false, no module index is generated. 214 | #latex_domain_indices = True 215 | 216 | 217 | # -- Options for manual page output -------------------------------------------- 218 | 219 | # One entry per manual page. List of tuples 220 | # (source start file, name, description, authors, manual section). 221 | man_pages = [ 222 | ('index', 'elastic', u'Elastic Documentation', 223 | [u'Paweł T. Jochym'], 1) 224 | ] 225 | 226 | 227 | # -- Options for Epub output --------------------------------------------------- 228 | 229 | # Bibliographic Dublin Core info. 230 | epub_title = u'Elastic' 231 | epub_author = u'Paweł T. Jochym' 232 | epub_publisher = u'Paweł T. Jochym' 233 | epub_copyright = u'2017, Paweł T. Jochym' 234 | 235 | # The language of the text. It defaults to the language option 236 | # or en if the language is not set. 237 | #epub_language = '' 238 | 239 | # The scheme of the identifier. Typical schemes are ISBN or URL. 240 | #epub_scheme = '' 241 | 242 | # The unique identifier of the text. This can be a ISBN number 243 | # or the project homepage. 244 | #epub_identifier = '' 245 | 246 | # A unique identification for the text. 247 | #epub_uid = '' 248 | 249 | # HTML files that should be inserted before the pages created by sphinx. 250 | # The format is a list of tuples containing the path and title. 251 | #epub_pre_files = [] 252 | 253 | # HTML files shat should be inserted after the pages created by sphinx. 254 | # The format is a list of tuples containing the path and title. 255 | #epub_post_files = [] 256 | 257 | # A list of files that should not be packed into the epub file. 258 | #epub_exclude_files = [] 259 | 260 | # The depth of the table of contents in toc.ncx. 261 | #epub_tocdepth = 3 262 | 263 | # Allow duplicate toc entries. 264 | #epub_tocdup = True 265 | -------------------------------------------------------------------------------- /docs/source/conf.py.tmpl: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Elastic documentation build configuration file, created by 4 | # sphinx-quickstart on Sun Aug 7 17:19:50 2011. 5 | # 6 | # This file is execfile()d with the current directory set to its containing dir. 7 | # 8 | # Note that not all possible configuration values are present in this 9 | # autogenerated file. 10 | # 11 | # All configuration values have a default; values that are commented out 12 | # serve to show the default. 13 | 14 | import sys, os 15 | 16 | # If extensions (or modules to document with autodoc) are in another directory, 17 | # add these directories to sys.path here. If the directory is relative to the 18 | # documentation root, use os.path.abspath to make it absolute, like shown here. 19 | sys.path.insert(0, os.path.abspath('../..')) 20 | sys.path.insert(0, os.path.abspath('../../example')) 21 | 22 | # -- General configuration ----------------------------------------------------- 23 | 24 | # If your documentation needs a minimal Sphinx version, state it here. 25 | #needs_sphinx = '1.0' 26 | 27 | # Add any Sphinx extension module names here, as strings. They can be extensions 28 | # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. 29 | extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.mathjax', 'sphinx.ext.viewcode'] 30 | 31 | # Add any paths that contain templates here, relative to this directory. 32 | templates_path = ['_templates'] 33 | 34 | # The suffix of source filenames. 35 | source_suffix = '.rst' 36 | 37 | # The encoding of source files. 38 | #source_encoding = 'utf-8-sig' 39 | 40 | # The master toctree document. 41 | master_doc = 'index' 42 | 43 | # General information about the project. 44 | project = u'Elastic' 45 | copyright = u'2015, Paweł T. Jochym' 46 | 47 | # The version info for the project you're documenting, acts as replacement for 48 | # |version| and |release|, also used in various other places throughout the 49 | # built documents. 50 | # 51 | # The short X.Y version. 52 | version = XXXX 53 | # The full version, including alpha/beta/rc tags. 54 | release = version 55 | 56 | # The language for content autogenerated by Sphinx. Refer to documentation 57 | # for a list of supported languages. 58 | #language = None 59 | 60 | # There are two options for replacing |today|: either, you set today to some 61 | # non-false value, then it is used: 62 | #today = '' 63 | # Else, today_fmt is used as the format for a strftime call. 64 | #today_fmt = '%B %d, %Y' 65 | 66 | # List of patterns, relative to source directory, that match files and 67 | # directories to ignore when looking for source files. 68 | exclude_patterns = [] 69 | 70 | # The reST default role (used for this markup: `text`) to use for all documents. 71 | #default_role = None 72 | 73 | # If true, '()' will be appended to :func: etc. cross-reference text. 74 | #add_function_parentheses = True 75 | 76 | # If true, the current module name will be prepended to all description 77 | # unit titles (such as .. function::). 78 | #add_module_names = True 79 | 80 | # If true, sectionauthor and moduleauthor directives will be shown in the 81 | # output. They are ignored by default. 82 | #show_authors = False 83 | 84 | # The name of the Pygments (syntax highlighting) style to use. 85 | #pygments_style = 'sphinx' 86 | 87 | # A list of ignored prefixes for module index sorting. 88 | #modindex_common_prefix = [] 89 | 90 | 91 | # -- Options for HTML output --------------------------------------------------- 92 | 93 | # The theme to use for HTML and HTML Help pages. See the documentation for 94 | # a list of builtin themes. 95 | html_theme = 'bizstyle' 96 | 97 | #jsmath_path = 'jsmath/easy/load.js' 98 | 99 | # Theme options are theme-specific and customize the look and feel of a theme 100 | # further. For a list of options available for each theme, see the 101 | # documentation. 102 | #html_theme_options = {} 103 | 104 | # Add any paths that contain custom themes here, relative to this directory. 105 | #html_theme_path = [] 106 | 107 | # The name for this set of Sphinx documents. If None, it defaults to 108 | # " v documentation". 109 | #html_title = None 110 | 111 | # A shorter title for the navigation bar. Default is the same as html_title. 112 | #html_short_title = None 113 | 114 | # The name of an image file (relative to this directory) to place at the top 115 | # of the sidebar. 116 | #html_logo = None 117 | 118 | # The name of an image file (within the static path) to use as favicon of the 119 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 120 | # pixels large. 121 | html_favicon = "favicon.ico" 122 | 123 | # Add any paths that contain custom static files (such as style sheets) here, 124 | # relative to this directory. They are copied after the builtin static files, 125 | # so a file named "default.css" will overwrite the builtin "default.css". 126 | html_static_path = ['_static'] 127 | 128 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 129 | # using the given strftime format. 130 | html_last_updated_fmt = '%b %d, %Y' 131 | 132 | # If true, SmartyPants will be used to convert quotes and dashes to 133 | # typographically correct entities. 134 | #html_use_smartypants = True 135 | 136 | # Custom sidebar templates, maps document names to template names. 137 | #html_sidebars = {} 138 | 139 | # Additional templates that should be rendered to pages, maps page names to 140 | # template names. 141 | #html_additional_pages = {} 142 | 143 | # If false, no module index is generated. 144 | #html_domain_indices = True 145 | 146 | # If false, no index is generated. 147 | #html_use_index = True 148 | 149 | # If true, the index is split into individual pages for each letter. 150 | #html_split_index = False 151 | 152 | # If true, links to the reST sources are added to the pages. 153 | #html_show_sourcelink = True 154 | 155 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 156 | #html_show_sphinx = True 157 | 158 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 159 | #html_show_copyright = True 160 | 161 | # If true, an OpenSearch description file will be output, and all pages will 162 | # contain a tag referring to it. The value of this option must be the 163 | # base URL from which the finished HTML is served. 164 | #html_use_opensearch = '' 165 | 166 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 167 | #html_file_suffix = None 168 | 169 | # Output file base name for HTML help builder. 170 | htmlhelp_basename = 'Elasticdoc' 171 | 172 | 173 | # -- Options for LaTeX output -------------------------------------------------- 174 | 175 | # The paper size ('letter' or 'a4'). 176 | latex_paper_size = 'a4' 177 | 178 | # The font size ('10pt', '11pt' or '12pt'). 179 | #latex_font_size = '10pt' 180 | 181 | # Grouping the document tree into LaTeX files. List of tuples 182 | # (source start file, target name, title, author, documentclass [howto/manual]). 183 | latex_documents = [ 184 | ('index', 'Elastic.tex', u'Elastic', 185 | u'Paweł T. Jochym', 'manual'), 186 | ] 187 | 188 | # The name of an image file (relative to this directory) to place at the top of 189 | # the title page. 190 | #latex_logo = None 191 | 192 | # For "manual" documents, if this is true, then toplevel headings are parts, 193 | # not chapters. 194 | #latex_use_parts = False 195 | 196 | # If true, show page references after internal links. 197 | #latex_show_pagerefs = False 198 | 199 | # If true, show URL addresses after external links. 200 | #latex_show_urls = False 201 | 202 | # Additional stuff for the LaTeX preamble. 203 | #latex_preamble = '' 204 | 205 | # Documents to append as an appendix to all manuals. 206 | #latex_appendices = [] 207 | 208 | # If false, no module index is generated. 209 | #latex_domain_indices = True 210 | 211 | 212 | # -- Options for manual page output -------------------------------------------- 213 | 214 | # One entry per manual page. List of tuples 215 | # (source start file, name, description, authors, manual section). 216 | man_pages = [ 217 | ('index', 'elastic', u'Elastic Documentation', 218 | [u'Paweł T. Jochym'], 1) 219 | ] 220 | 221 | 222 | # -- Options for Epub output --------------------------------------------------- 223 | 224 | # Bibliographic Dublin Core info. 225 | epub_title = u'Elastic' 226 | epub_author = u'Paweł T. Jochym' 227 | epub_publisher = u'Paweł T. Jochym' 228 | epub_copyright = u'2015, Paweł T. Jochym' 229 | 230 | # The language of the text. It defaults to the language option 231 | # or en if the language is not set. 232 | #epub_language = '' 233 | 234 | # The scheme of the identifier. Typical schemes are ISBN or URL. 235 | #epub_scheme = '' 236 | 237 | # The unique identifier of the text. This can be a ISBN number 238 | # or the project homepage. 239 | #epub_identifier = '' 240 | 241 | # A unique identification for the text. 242 | #epub_uid = '' 243 | 244 | # HTML files that should be inserted before the pages created by sphinx. 245 | # The format is a list of tuples containing the path and title. 246 | #epub_pre_files = [] 247 | 248 | # HTML files shat should be inserted after the pages created by sphinx. 249 | # The format is a list of tuples containing the path and title. 250 | #epub_post_files = [] 251 | 252 | # A list of files that should not be packed into the epub file. 253 | #epub_exclude_files = [] 254 | 255 | # The depth of the table of contents in toc.ncx. 256 | #epub_tocdepth = 3 257 | 258 | # Allow duplicate toc entries. 259 | #epub_tocdup = True 260 | -------------------------------------------------------------------------------- /docs/source/endmatter.rst: -------------------------------------------------------------------------------- 1 | 2 | Indices and tables 3 | ------------------ 4 | 5 | * :ref:`genindex` 6 | * :ref:`modindex` 7 | * :ref:`search` 8 | 9 | 10 | References 11 | ---------- 12 | .. image:: https://zenodo.org/badge/doi/10.5281/zenodo.593721.svg 13 | :target: https://doi.org/10.5281/zenodo.593721 14 | 15 | The Elastic package should be cited using one or both of the following papers 16 | (TiC, ZrC) and its own reference.: 17 | 18 | .. [Elastic] P.T. Jochym, 19 | *Module for calculating elastic tensor of crystals*, 20 | software, https://github.com/jochym/Elastic/, 21 | `doi:10.5281/zenodo.593721 `_. 22 | .. [TiC] P.T. Jochym, K. Parlinski and M. Sternik, 23 | *TiC lattice dynamics from ab initio calculations*, 24 | European Physical Journal B; **10**, 1 (1999) 9-13 ; 25 | `doi:10.1007/s100510050823 `_ 26 | .. [ZrC] P.T. Jochym and K. Parlinski, 27 | *Ab initio lattice dynamics and elastic constants of ZrC*, 28 | European Physical Journal B; **15**, 2 (2000) 265-268 ; 29 | `doi:10.1007/s100510051124 `_ 30 | .. [LL] L.D. Landau, E.M. Lifszyc, `Theory of elasticity `_, Elsevier (1986) ; ISBN: 075062633X, 9780750626330 31 | .. [SVD] G. Golub and W. Kahan, 32 | *Calculating the Singular Values and Pseudo-Inverse of a Matrix*, 33 | J. Soc. Indus,.Appl. Math.: Ser. B **2**, (1964) pp. 205-224 ; 34 | `doi:10.1137/0702016 `_ ; 35 | `Wikipedia article on SVD `_ 36 | 37 | -------------------------------------------------------------------------------- /docs/source/examples.rst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jochym/Elastic/a8f63b811481439084727062d9c8b2ab8f869376/docs/source/examples.rst -------------------------------------------------------------------------------- /docs/source/fig/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jochym/Elastic/a8f63b811481439084727062d9c8b2ab8f869376/docs/source/fig/favicon.ico -------------------------------------------------------------------------------- /docs/source/fig/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jochym/Elastic/a8f63b811481439084727062d9c8b2ab8f869376/docs/source/fig/favicon.png -------------------------------------------------------------------------------- /docs/source/fig/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 23 | 30 | 35 | 36 | 43 | 44 | 62 | 64 | 65 | 67 | image/svg+xml 68 | 70 | 71 | 72 | 73 | 74 | 78 | 85 | 91 | 97 | 103 | 109 | 115 | 121 | 122 | 127 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /docs/source/fig/plot1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jochym/Elastic/a8f63b811481439084727062d9c8b2ab8f869376/docs/source/fig/plot1.pdf -------------------------------------------------------------------------------- /docs/source/fig/plot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jochym/Elastic/a8f63b811481439084727062d9c8b2ab8f869376/docs/source/fig/plot1.png -------------------------------------------------------------------------------- /docs/source/fig/plot1.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 11 | 12 | 14 | 15 | 16 | 17 | 19 | 20 | 21 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | -------------------------------------------------------------------------------- /docs/source/fig/plot2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jochym/Elastic/a8f63b811481439084727062d9c8b2ab8f869376/docs/source/fig/plot2.pdf -------------------------------------------------------------------------------- /docs/source/fig/plot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jochym/Elastic/a8f63b811481439084727062d9c8b2ab8f869376/docs/source/fig/plot2.png -------------------------------------------------------------------------------- /docs/source/fig/plot2.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 11 | 12 | 14 | 15 | 16 | 17 | 19 | 20 | 21 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | -------------------------------------------------------------------------------- /docs/source/fig/plot3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jochym/Elastic/a8f63b811481439084727062d9c8b2ab8f869376/docs/source/fig/plot3.pdf -------------------------------------------------------------------------------- /docs/source/fig/plot3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jochym/Elastic/a8f63b811481439084727062d9c8b2ab8f869376/docs/source/fig/plot3.png -------------------------------------------------------------------------------- /docs/source/fig/plot3a.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jochym/Elastic/a8f63b811481439084727062d9c8b2ab8f869376/docs/source/fig/plot3a.pdf -------------------------------------------------------------------------------- /docs/source/fig/plot3a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jochym/Elastic/a8f63b811481439084727062d9c8b2ab8f869376/docs/source/fig/plot3a.png -------------------------------------------------------------------------------- /docs/source/fig/plot3b.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jochym/Elastic/a8f63b811481439084727062d9c8b2ab8f869376/docs/source/fig/plot3b.pdf -------------------------------------------------------------------------------- /docs/source/fig/plot3b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jochym/Elastic/a8f63b811481439084727062d9c8b2ab8f869376/docs/source/fig/plot3b.png -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | .. Elastic documentation master file, created by 2 | sphinx-quickstart on Sun Aug 7 17:19:50 2011. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Calculation of elastic properties of crystals 7 | ============================================= 8 | 9 | .. image:: https://zenodo.org/badge/doi/10.5281/zenodo.18759.svg 10 | :target: http://dx.doi.org/10.5281/zenodo.18759 11 | 12 | ------ 13 | 14 | **New version 5.0 released** 15 | 16 | The new version is API *incompatible* with the previous versions. 17 | It provides a new command line utility as the main user interface 18 | to the package - which hoppefully will broaden the user base byond 19 | python users. 20 | 21 | ------ 22 | 23 | Elastic is a set of python routines for calculation of elastic properties of 24 | crystals (elastic constants, equation of state, sound velocities, etc.). 25 | It is a fifth version of the in-house code I have 26 | written over several years and is implemented as a extension to the 27 | `ASE `_ system and a script providing 28 | interface to the library not requiring knowledge of python or ASE system. 29 | The code was a basis for some of my publications and was 30 | described briefly in these papers. The code was available to anyone, presented 31 | at our `Workshop on ab initio Calculations in Geosciences `_ 32 | and used by some of my co-workers but was never properly published with 33 | full documentation, project page etc. In 2010, I have decided to re-implement 34 | elastic as a module for the `ASE `_ system 35 | and publish it properly under the GPL as versions 3 and 4. 36 | 37 | Later, in 2017, needs of users nudged me into implementing the command-line 38 | front-end to the library which is included with version 5.0 of the package. 39 | 40 | The version 5.0 also changes API of the library from mix-in class to the set 41 | of simple functions providing functionality of the module. The workflow of the 42 | package was also changed to prepare data - calculate - post-process style, 43 | which is better suited to serious research work. 44 | 45 | The source code started live on the 46 | `launchpad project page `_ and later in 2014 47 | moved to the `github repository `_ with 48 | corresponding `elastic web page `_ and 49 | on-line documentation placed at `Elastic website `_ 50 | (you are probably reading from it already). 51 | 52 | The project is free software and I welcome patches, ideas and other feedback. 53 | 54 | 55 | .. toctree:: 56 | :maxdepth: 3 57 | 58 | intro 59 | cli-usage 60 | lib-usage 61 | modules 62 | endmatter 63 | 64 | * :ref:`search` 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /docs/source/intro.rst: -------------------------------------------------------------------------------- 1 | Physical Principles 2 | =================== 3 | 4 | Elastic is based on the standard elasticity theory (see [LL]_ for the detailed 5 | introduction) and *finite deformation* approach to the calculation of elastic 6 | tensor of the crystal. 7 | I have described basic physical principles on which the code rests in my 8 | habilitation thesis. Here I will include slightly edited second chapter of the 9 | thesis introducing the method and some implementation details. 10 | 11 | Elasticity of crystals 12 | ---------------------- 13 | 14 | The classical, linear theory of elasticity of crystalline materials has been 15 | formulated already in the 18th and 19th century by Cauchy, Euler, Poisson, 16 | Young and many other great mathematicians and physicists of that time. The 17 | standard textbook formulation (e.g. classical book by Landau et al. [LL]_) can 18 | be, in principle, directly used as a basis for numerical determination of the 19 | elastic tensor and other mechanical properties of the crystal. Nevertheless, 20 | practical implementation of these formulas have some non-obvious aspects, 21 | worthy of explicit presentation. The *finite deformation* method developed and 22 | used in the mentioned papers [TiC]_, [ZrC]_ is based on the fundamental 23 | relationship between stress and strain of the solid crystalline body with a 24 | particular symmetry. This is a simple tensor equation, sometimes called 25 | generalised *Hook’s law* (in standard tensor notation): 26 | 27 | .. math:: 28 | \sigma_{\lambda\xi} = C_{\lambda\xi\mu\nu} s_{\mu\nu} 29 | 30 | This formula simply states that the stress in the crystal 31 | :math:`\sigma_{\lambda\xi}` is a linear function of the strain 32 | :math:`s_{\mu\nu}` incurred by its deformation, and the elasticity tensor 33 | :math:`C_{\lambda\xi\mu\nu}` is just a tensor proportionality coefficient. The 34 | Greek indexes run through coordinates x, y, z. The elasticity tensor inherits 35 | symmetries of the crystal and has some intrinsic symmetries of its own. 36 | Therefore, only a small number of its components are independent. This fact 37 | leads to customary representation of this entity in the form of the matrix with 38 | components assigned according to Voight’s notation. Thus, instead of the rank-4 39 | three dimensional tensor we have :math:`6 \times 6` matrix :math:`C_{ij}` where 40 | the indexes :math:`i, j = 1 \ldots 6`. The stress and strain tensors are 41 | represented as six-dimensional vectors. The symmetries of the elastic tensor are 42 | directly translated into symmetries of the :math:`C_{ij}` matrix. The Voight’s 43 | notation is commonly used in tensor calculus. For this particular case we can 44 | write it as an index assignment where each pair of Greek indexes is replaced 45 | with a corresponding Latin index (i, j, k, l, m, n): xx=1, yy=2, zz=3, 46 | yz=4, xz=5, xy=6. 47 | 48 | While this convention makes presentation of elastic constants much easier - 49 | since it is just a square table of numbers - it slightly complicates algebraic 50 | procedures as we lose the simplicity of the tensor formalism. Every class of 51 | crystal implies, through its symmetry, a different number of independent 52 | elements in the :math:`C_{ij}` matrix. 53 | 54 | For example, the cubic lattice has just three independent elements in the 55 | elastic matrix: :math:`C_{11}, C_{12}, C_{44}`, and the matrix itself has the following shape: 56 | 57 | .. math:: 58 | \left[\begin{array}{cccccc} 59 | C_{11} & C_{12} & C_{12} & 0 & 0 & 0\\ 60 | C_{12} & C_{11} & C_{12} & 0 & 0 & 0\\ 61 | C_{12} & C_{12} & C_{11} & 0 & 0 & 0\\ 62 | 0 & 0 & 0 & C_{44} & 0 & 0\\ 63 | 0 & 0 & 0 & 0 & C_{44} & 0\\ 64 | 0 & 0 & 0 & 0 & 0 & C_{44}\end{array}\right] 65 | 66 | Less symmetric crystals have, naturally, a higher number of independent elastic 67 | constants and lower symmetry of the :math:`C_{ij}` matrix (see [LL]_ for full 68 | introduction to theory of elasticity). 69 | 70 | Numerical derivation of elastic matrix 71 | -------------------------------------- 72 | 73 | Numerical derivation of the :math:`C_{ij}` matrix may be approached in many 74 | different ways. Basically, we can employ the same methods as used 75 | effectively in experimental work. From all experimental procedures we can select 76 | three classes which are relevant to our discussion: 77 | 78 | #. Based on the measured sound velocity, including various methods based on determination of lattice dynamics of the crystal. 79 | #. Based on the strain-energy relation. 80 | #. Based on the measured stress-strain relations for some particular, simple strains. 81 | 82 | While the first method is frequently used in laboratory measurements, it is not 83 | direct and is not well suited to numerical derivation. For example, you can 84 | measure the tangent of all acoustic branches of phonon dispersion curves in 85 | several directions to get enough data points to solve the set of equations 86 | for most of the independent components of the :math:`C_{ij}` matrix. The 87 | tangent of the acoustic branch is connected with the sound velocity and with 88 | components of elastic matrix by a set of equations of the general form: 89 | 90 | .. math:: 91 | \varrho v_{k}^{2}=L(C_{ij}) 92 | 93 | where :math:`L(C_{ij})` is a linear combination of independent components 94 | of elastic tensor, :math:`v_{k}` is a long-wave sound velocity in particular 95 | direction, which is equivalent to the slope of the acoustic branch 96 | of phonon dispersion curve in this direction, and :math:`\varrho` is crystal 97 | density. Full set of these equations for the cubic crystal is included 98 | in [TiC]_. Unfortunately, it is difficult and non-practical 99 | to use this method to obtain more then few of the simplest of components, 100 | since the numerical properties of the non-linear formulas involved 101 | lead to the error pile-up in the results. It is particularly susceptible 102 | to errors in long-wave sound velocities -- due to the quadratic function 103 | in above equation. Unfortunately, these asymptotic velocities 104 | are particularly weakly constrained by most of available computational 105 | methods. The same formulas can also be used to obtain elastic matrix 106 | from straight-forward sound velocity measurements. The same unfavourable 107 | numerical properties lead to high demands on accuracy of the measurements 108 | -- but in this case these requirements could be quite easily met in 109 | experiment since sound velocity can be measured with very high precision. 110 | 111 | The second method is not practical for laboratory measurements - it is not easy 112 | to accurately measure energy of the deformed crystal. Furthermore, the 113 | strain-energy relation is non-linear and we need to extract a derivative of the 114 | function -- the procedure is quite complex, needs more data points and is prone 115 | to errors. 116 | 117 | The third method is well suited for experimental work as well as computational 118 | derivation of the elastic matrix. The numerical properties of the formulas -- 119 | being just a set of linear equations -- are well known and provide stable and 120 | well-controlled error propagation. Furthermore, while the sound velocity is not 121 | directly accessible to computational quantum mechanical methods, the stresses 122 | induced by strains on the crystal are almost universally provided by DFT based 123 | programs and often do not require any additional computational effort. The 124 | comparison of these methods used for computational derivation of the elastic 125 | matrix is included in [TiC]_, [ZrC]_. The comparison shows that the finite 126 | deformation (stress-strain) method compares favourably to the pure 127 | energy-derivative method. The results clearly show that the strain--stress 128 | relationship approach described here is much better suited for computational 129 | derivation of elastic matrix and provides lower error level than other two 130 | methods. 131 | 132 | .. _symmetry: 133 | 134 | Crystal symmetry and elastic matrix derivation 135 | ---------------------------------------------- 136 | 137 | As mentioned above, the symmetry of the crystal determines the number and 138 | position of independent components of the :math:`C_{ij}` matrix. Therefore, the 139 | stress-strain relation is effectively modified by the symmetry of the case by a 140 | simple fact that most, of the coefficients are not independent from one another. 141 | We aim to derive the complete set of :math:`C_{ij}` elements from the set of 142 | computational or experimental measurements of strain and stress tensors 143 | :math:`s^{a}`, :math:`\sigma^{a}` where the upper Latin index a numbers a 144 | calculation/experiment setup. In the case described here the “measurement” is a 145 | particular computational setup with the crystal deformed in various ways in 146 | order to provide enough data points to derive all independent components of the 147 | :math:`C_{ij}` matrix. The set of necessary deformations can be determined by 148 | the symmetry of the crystal and contains tetragonal and sheer deformations along 149 | some or all axis -- as the symmetry of the case dictates. To improve the 150 | accuracy of the results the deformations may be of different sizes (typically 151 | 0.1-1% in length or 0.1-1 degree in angle). 152 | 153 | Having a set of calculation data :math:`\{s^{a}, \sigma^{a}\}`, we can rewrite 154 | generalised Hook's law to form a set of linear equations (in Voight notation for 155 | :math:`i,j` indexes): :math:`C_{ij}s_{j}^{a}=\sigma_{i}^{a}`. This set can be 156 | further transformed for each symmetry case to the form in which the independent 157 | components of the :math:`C_{ij}` matrix create a vector of unknowns and the 158 | symmetry relations and strains :math:`s_{j}^{a}` create a new equation matrix 159 | :math:`S`. :math:`S_{ju}(s^{a})C_{u}=\sigma_{j}^{a}`. The :math:`S(s)` matrix is 160 | a linear function of the strain vector s with all symmetry relations taken into 161 | account. The index a runs over all data sets we have in the calculation while 162 | index u runs over all independent components of the :math:`C_{ij}` matrix. For 163 | the cubic crystal the above equation takes explicit form: 164 | 165 | .. math:: 166 | \left[\begin{array}{ccc} 167 | s_{1} & s_{2}+s_{3} & 0\\ 168 | s_{2} & s_{1}+s_{3} & 0\\ 169 | s_{3} & s_{1}+s_{2} & 0\\ 170 | 0 & 0 & 2s_{4}\\ 171 | 0 & 0 & 2s_{5}\\ 172 | 0 & 0 & 2s_{6}\end{array}\right]^{a}\left[\begin{array}{c} 173 | C_{11}\\ 174 | C_{12}\\ 175 | C_{44}\end{array}\right]=\left[\begin{array}{c} 176 | \sigma_{1}\\ 177 | \sigma_{2}\\ 178 | \sigma_{3}\\ 179 | \sigma_{4}\\ 180 | \sigma_{5}\\ 181 | \sigma_{6}\end{array}\right]^{a}. 182 | 183 | Note the a index of S and :math:`\sigma`, which creates a set of 184 | :math:`n\times6` linear equations for 3 unknowns 185 | :math:`\left[C_{11},C_{12},C_{44}\right]`, where n is a number of independent 186 | calculations of stresses incurred in crystal by strains. In principle, the above 187 | relations could be expressed in the non-symmetry specific form with either a 188 | full set of indexes and the symmetry information encoded in the single matrix of 189 | constant elements or even in the pure tensor formulation with the four-index 190 | elastic tensor :math:`C` and two-index stress and strain tensors. While this 191 | type of formulation is definitely more regular and sometimes easier to 192 | manipulate in formal transformations, it is not very useful for numerical 193 | calculations or writing computer code -- multi-dimensional arrays are difficult 194 | to manipulate and are prone to many trivial notation errors. Thus, it is better 195 | to split the general formula to crystal classes with different number of 196 | :math:`C_{ij}` components (i.e. length of the :math:`C_{u}` vector) 197 | and separate shape of the :math:`S` matrix. This is an approach used by Elastic. 198 | 199 | For example, in the orthorhombic crystal the vector of independent 200 | :math:`C_{ij}` components has nine elements and the S matrix is a :math:`9\times6` one: 201 | 202 | .. math:: 203 | \left[\begin{array}{ccccccccc} 204 | s_{1} & 0 & 0 & s_{2} & s_{3} & 0 & 0 & 0 & 0\\ 205 | 0 & s_{2} & 0 & s_{1} & 0 & s_{3} & 0 & 0 & 0\\ 206 | 0 & 0 & s_{3} & 0 & s_{1} & s_{2} & 0 & 0 & 0\\ 207 | 0 & 0 & 0 & 0 & 0 & 0 & 2s_{4} & 0 & 0\\ 208 | 0 & 0 & 0 & 0 & 0 & 0 & 0 & 2s_{5} & 0\\ 209 | 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 2s_{6}\end{array}\right]^{a}\left[\begin{array}{c} 210 | C_{11}\\ 211 | C_{22}\\ 212 | C_{33}\\ 213 | C_{12}\\ 214 | C_{13}\\ 215 | C_{23}\\ 216 | C_{44}\\ 217 | C_{55}\\ 218 | C_{66}\end{array}\right]=\left[\begin{array}{c} 219 | \sigma_{1}\\ 220 | \sigma_{2}\\ 221 | \sigma_{3}\\ 222 | \sigma_{4}\\ 223 | \sigma_{5}\\ 224 | \sigma_{6}\end{array}\right]^{a}. 225 | 226 | The elements of the matrix S have direct relation to the terms of expansion of 227 | the elastic free energy as a function of deformation (strain tensor) F(s). For 228 | example, the orthorhombic equation can be derived from the free energy formula 229 | (see [LL]_ for derivation): 230 | 231 | .. math:: 232 | F(s) = \frac{1}{2}C_{11}s_{1}^{2}+ 233 | \frac{1}{2}C_{22}s_{2}^{2}+ 234 | \frac{1}{2}C_{33}s_{3}^{2}+ 235 | C_{12}s_{1}s_{2}+C_{13}s_{1}s_{3}+C_{23}s_{2}s_{3}+ \\ 236 | 2C_{44}s_{4}^{2}+2C_{55}s_{5}^{2}+2C_{66}s_{6}^{2} 237 | 238 | The elements of the S matrix are simply coefficients of first derivatives of the 239 | F(s) over respective strain components. Alternatively, we can rewrite the S(s) 240 | matrix in the compact form as a mixed derivative: 241 | 242 | .. math:: 243 | S_{iu}=A\frac{\partial^{2}F}{\partial s_{i}\partial C_{u}}, 244 | 245 | where A is a multiplier taking into account the double counting of the 246 | off-diagonal components in the free energy formula (see note at the end of the 247 | exercises in [LL]_). The multiplier :math:`A=1` for 248 | :math:`i \leq 4`, and :math:`1/2` otherwise. The above general formula turns out to be quite 249 | helpful in less trivial cases of trigonal or hexagonal classes. For instance, 250 | the hexagonal elastic free energy (see [LL]_ for rather lengthy formula) leads 251 | to the following set of equations: 252 | 253 | .. math:: 254 | \left[\begin{array}{ccccc} 255 | s_{1} & 0 & s_{2} & s_{3} & 0\\ 256 | s_{2} & 0 & s_{1} & s_{3} & 0\\ 257 | 0 & s_{3} & 0 & s_{1}+s_{2} & 0\\ 258 | 0 & 0 & 0 & 0 & 2s_{4}\\ 259 | 0 & 0 & 0 & 0 & 2s_{5}\\ 260 | s_{6} & 0 & -s_{6} & 0 & 0\end{array}\right]^{a}\left[\begin{array}{c} 261 | C_{11}\\ 262 | C_{33}\\ 263 | C_{12}\\ 264 | C_{13}\\ 265 | C_{44}\end{array}\right]=\left[\begin{array}{c} 266 | \sigma_{1}\\ 267 | \sigma_{2}\\ 268 | \sigma_{3}\\ 269 | \sigma_{4}\\ 270 | \sigma_{5}\\ 271 | \sigma_{6}\end{array}\right]^{a}. 272 | 273 | The set of linear equations, with calculated strains and stresses inserted 274 | into the :math:`S^{a}` matrix and :math:`\sigma^{a}` vector, could be 275 | constructed for any crystal -- only the form of the S matrix and the length of 276 | the :math:`C_{u}` vector will be different for each symmetry. 277 | 278 | The set of equations is usually over-determined. Therefore, it 279 | cannot be solved in the strict linear-algebra sense since no exact solution 280 | could exist. Nevertheless, this set of equations can be solved in approximate 281 | sense -- i.e. minimising the length of the residual vector of the solution. 282 | Fortunately, a very clever algorithm capable of dealing with just this type of 283 | linear equations has been known for a long time. It is called Singular Value 284 | Decomposition [SVD]_. Not only does it provide the approximate solution 285 | minimising the residual vector of the equation but also is stable against 286 | numerically ill-conditioned equations or equations which provide too little data 287 | to determine all components of the solution. The SVD provides also some 288 | indication of the quality of the obtained solution in the form of the vector of 289 | singular values, which could be used to judge whether the solution is 290 | well-determined. It is a well known algorithm and its implementations are 291 | available in every self-respecting numerical linear algebra library. The 292 | implementation used in the Elastic code is the one included in the Scientific 293 | Python library `SciPy `_. 294 | 295 | 296 | 297 | -------------------------------------------------------------------------------- /docs/source/lib-usage.rst: -------------------------------------------------------------------------------- 1 | 2 | Library usage 3 | ============= 4 | 5 | Simple Parallel Calculation 6 | --------------------------- 7 | 8 | Once you have everything installed and running you can run your first 9 | real calculation. The first step is to import the modules to your 10 | program (the examples here use VASP calculator) 11 | 12 | .. code:: python 13 | 14 | from ase.spacegroup import crystal 15 | import ase.units as units 16 | import numpy 17 | import matplotlib.pyplot as plt 18 | 19 | from parcalc import ClusterVasp, ParCalculate 20 | 21 | from elastic import get_pressure, BMEOS, get_strain 22 | from elastic import get_elementary_deformations, scan_volumes 23 | from elastic import get_BM_EOS, get_elastic_tensor 24 | 25 | next we need to create our example MgO crystal: 26 | 27 | .. code:: python 28 | 29 | a = 4.194 30 | cryst = crystal(['Mg', 'O'], 31 | [(0, 0, 0), (0.5, 0.5, 0.5)], 32 | spacegroup=225, 33 | cellpar=[a, a, a, 90, 90, 90]) 34 | 35 | We need a calculator for our job, here we use VASP and ClusterVasp 36 | defined in the parcalc module. You can probably replace this calculator 37 | by any other ASE calculator but this was not tested yet. Thus let us 38 | define the calculator: 39 | 40 | .. code:: python 41 | 42 | # Create the calculator running on one, eight-core node. 43 | # This is specific to the setup on my cluster. 44 | # You have to adapt this part to your environment 45 | calc = ClusterVasp(nodes=1, ppn=8) 46 | 47 | # Assign the calculator to the crystal 48 | cryst.set_calculator(calc) 49 | 50 | # Set the calculation parameters 51 | calc.set(prec = 'Accurate', xc = 'PBE', lreal = False, 52 | nsw=30, ediff=1e-8, ibrion=2, kpts=[3,3,3]) 53 | 54 | # Set the calculation mode first. 55 | # Full structure optimization in this case. 56 | # Not all calculators have this type of internal minimizer! 57 | calc.set(isif=3) 58 | 59 | Finally, run our first calculation. Obtain relaxed structure and 60 | residual pressure after optimization: 61 | 62 | .. code:: python 63 | 64 | print("Residual pressure: %.3f bar" % ( 65 | get_pressure(cryst.get_stress()))) 66 | 67 | 68 | .. parsed-literal:: 69 | 70 | Residual pressure: 0.000 bar 71 | 72 | 73 | If this returns proper pressure (close to zero) we can use the obtained 74 | structure for further calculations. For example we can scan the volume 75 | axis to obtain points for equation of state fitting. This will 76 | demonstrate the ability to run several calculations in parallel - if you 77 | have a cluster of machines at your disposal this will speed up the 78 | calculation considerably. 79 | 80 | .. code:: python 81 | 82 | # Lets extract optimized lattice constant. 83 | # MgO is cubic so a is a first diagonal element of lattice matrix 84 | a=cryst.get_cell()[0,0] 85 | 86 | # Clean up the directory 87 | calc.clean() 88 | 89 | systems=[] 90 | # Iterate over lattice constant in the +/-5% range 91 | for av in numpy.linspace(a*0.95,a*1.05,5): 92 | systems.append(crystal(['Mg', 'O'], [(0, 0, 0), (0.5, 0.5, 0.5)], 93 | spacegroup=225, cellpar=[av, av, av, 90, 90, 90])) 94 | 95 | # Define the template calculator for this run 96 | # We can use the calc from above. It is only used as a template. 97 | # Just change the params to fix the cell volume 98 | calc.set(isif=2) 99 | 100 | # Run the calculation for all systems in sys in parallel 101 | # The result will be returned as list of systems res 102 | res=ParCalculate(systems,calc) 103 | 104 | # Collect the results 105 | v=[] 106 | p=[] 107 | for s in res : 108 | v.append(s.get_volume()) 109 | p.append(get_pressure(s.get_stress())) 110 | 111 | # Plot the result (you need matplotlib for this 112 | plt.plot(v,p,'o') 113 | plt.show() 114 | 115 | 116 | .. parsed-literal:: 117 | 118 | Workers started: 5 119 | 120 | 121 | 122 | .. image:: lib-usage_files/lib-usage_9_1.png 123 | 124 | 125 | Birch-Murnaghan Equation of State 126 | --------------------------------- 127 | 128 | Let us now use the tools provided by the modules to calculate equation 129 | of state for the crystal and verify it by plotting the data points 130 | against fitted EOS curve. The EOS used by the module is a well 131 | established Birch-Murnaghan formula (P - pressure, V - volume, B - 132 | parameters): 133 | 134 | .. math:: 135 | 136 | 137 | P(V)= \frac{B_0}{B'_0}\left[ 138 | \left({\frac{V}{V_0}}\right)^{-B'_0} - 1 139 | \right] 140 | 141 | Now we repeat the setup and optimization procedure from the example 1 142 | above but using a new Crystal class (see above we skip this part for 143 | brevity). Then comes a new part (IDOF - Internal Degrees of Freedom): 144 | 145 | .. code:: python 146 | 147 | # Switch to cell shape+IDOF optimizer 148 | calc.set(isif=4) 149 | 150 | # Calculate few volumes and fit B-M EOS to the result 151 | # Use +/-3% volume deformation and 5 data points 152 | deform=scan_volumes(cryst, n=5,lo=0.97,hi=1.03) 153 | 154 | # Run the calculations - here with Cluster VASP 155 | res=ParCalculate(deform,calc) 156 | 157 | # Post-process the results 158 | fit=get_BM_EOS(cryst, systems=res) 159 | 160 | # Get the P(V) data points just calculated 161 | pv=numpy.array(cryst.pv) 162 | 163 | # Sort data on the first column (V) 164 | pv=pv[pv[:, 0].argsort()] 165 | 166 | # Print just fitted parameters 167 | print("V0=%.3f A^3 ; B0=%.2f GPa ; B0'=%.3f ; a0=%.5f A" % ( 168 | fit[0], fit[1]/units.GPa, fit[2], pow(fit[0],1./3))) 169 | 170 | v0=fit[0] 171 | 172 | # B-M EOS for plotting 173 | fitfunc = lambda p, x: numpy.array([BMEOS(xv,p[0],p[1],p[2]) for xv in x]) 174 | 175 | # Ranges - the ordering in pv is not guarateed at all! 176 | # In fact it may be purely random. 177 | x=numpy.array([min(pv[:,0]),max(pv[:,0])]) 178 | y=numpy.array([min(pv[:,1]),max(pv[:,1])]) 179 | 180 | 181 | # Plot the P(V) curves and points for the crystal 182 | # Plot the points 183 | plt.plot(pv[:,0]/v0,pv[:,1]/units.GPa,'o') 184 | 185 | # Mark the center P=0 V=V0 186 | plt.axvline(1,ls='--') 187 | plt.axhline(0,ls='--') 188 | 189 | # Plot the fitted B-M EOS through the points 190 | xa=numpy.linspace(x[0],x[-1],20) 191 | plt.plot(xa/v0,fitfunc(fit,xa)/units.GPa,'-') 192 | plt.title('MgO pressure vs. volume') 193 | plt.xlabel('$V/V_0$') 194 | plt.ylabel('P (GPa)') 195 | plt.show() 196 | 197 | 198 | .. parsed-literal:: 199 | 200 | Workers started: 5 201 | V0=74.233 A^3 ; B0=168.19 GPa ; B0'=4.270 ; a0=4.20275 A 202 | 203 | 204 | 205 | .. image:: lib-usage_files/lib-usage_12_1.png 206 | 207 | 208 | If you set up everything correctly you should obtain fitted parameters 209 | printed out in the output close to: 210 | 211 | .. math:: 212 | 213 | 214 | V_0 = 73.75 \text{ A}^3 \quad 215 | B_0 = 170 \text{ GPa} \quad 216 | B'_0 = 4.3 \quad 217 | a_0 = 4.1936 \text{ A} 218 | 219 | Calculation of the elastic tensor 220 | --------------------------------- 221 | 222 | Finally let us calculate an elastic tensor for the same simple cubic 223 | crystal - magnesium oxide (MgO). For this we need to create the crystal 224 | and optimize its structure (see :ref:``parcalc`` above). Once we have an 225 | optimized structure we can switch the calculator to internal degrees of 226 | freedom optimization (IDOF) and calculate the elastic tensor: 227 | 228 | .. code:: python 229 | 230 | # Switch to IDOF optimizer 231 | calc.set(isif=2) 232 | 233 | # Create elementary deformations 234 | systems = get_elementary_deformations(cryst, n=5, d=0.33) 235 | 236 | # Run the stress calculations on deformed cells 237 | res = ParCalculate(systems, calc) 238 | 239 | # Elastic tensor by internal routine 240 | Cij, Bij = get_elastic_tensor(cryst, systems=res) 241 | print("Cij (GPa):", Cij/units.GPa) 242 | 243 | 244 | .. parsed-literal:: 245 | 246 | Workers started: 10 247 | Cij (GPa): [ 338.46921273 103.64272667 152.2150523 ] 248 | 249 | 250 | To make sure we are getting the correct answer let us make the 251 | calculation for :math:`C_{11}, C_{12}` by hand. We will deform the cell 252 | along a (x) axis by +/-0.2% and fit the :math:`3^{rd}` order polynomial 253 | to the stress-strain data. The linear component of the fit is the 254 | element of the elastic tensor: 255 | 256 | .. code:: python 257 | 258 | from elastic.elastic import get_cart_deformed_cell 259 | 260 | # Create 10 deformation points on the a axis 261 | systems = [] 262 | for d in numpy.linspace(-0.2,0.2,10): 263 | systems.append(get_cart_deformed_cell(cryst, axis=0, size=d)) 264 | 265 | # Calculate the systems and collect the stress tensor for each system 266 | r = ParCalculate(systems, cryst.calc) 267 | ss=[] 268 | for s in r: 269 | ss.append([get_strain(s, cryst), s.get_stress()]) 270 | 271 | ss=numpy.array(ss) 272 | lo=min(ss[:,0,0]) 273 | hi=max(ss[:,0,0]) 274 | mi=(lo+hi)/2 275 | wi=(hi-lo)/2 276 | xa=numpy.linspace(mi-1.1*wi,mi+1.1*wi, 50) 277 | 278 | 279 | .. parsed-literal:: 280 | 281 | Workers started: 10 282 | 283 | 284 | .. code:: python 285 | 286 | # Make a plot 287 | plt.plot(ss[:,0,0],ss[:,1,0]/units.GPa,'.') 288 | plt.plot(ss[:,0,0],ss[:,1,1]/units.GPa,'.') 289 | 290 | plt.axvline(0,ls='--') 291 | plt.axhline(0,ls='--') 292 | 293 | # Now fit the polynomials to the data to get elastic constants 294 | # C11 component 295 | f=numpy.polyfit(ss[:,0,0],ss[:,1,0],3) 296 | c11=f[-2]/units.GPa 297 | 298 | # Plot the fitted function 299 | plt.plot(xa,numpy.polyval(f,xa)/units.GPa,'-', label='$C_{11}$') 300 | 301 | # C12 component 302 | f=numpy.polyfit(ss[:,0,0],ss[:,1,1],3) 303 | c12=f[-2]/units.GPa 304 | 305 | # Plot the fitted function 306 | plt.plot(xa,numpy.polyval(f,xa)/units.GPa,'-', label='$C_{12}$') 307 | plt.xlabel('Relative strain') 308 | plt.ylabel('Stress componnent (GPa)') 309 | plt.title('MgO, strain-stress relation ($C_{11}, C_{12}$)') 310 | plt.legend(loc='best') 311 | # Here are the results. They should agree with the results 312 | # of the internal routine. 313 | print('C11 = %.3f GPa, C12 = %.3f GPa => K= %.3f GPa' % ( 314 | c11, c12, (c11+2*c12)/3)) 315 | 316 | plt.show() 317 | 318 | 319 | .. parsed-literal:: 320 | 321 | C11 = 325.005 GPa, C12 = 102.441 GPa => K= 176.629 GPa 322 | 323 | 324 | 325 | .. image:: lib-usage_files/lib-usage_18_1.png 326 | 327 | 328 | If you set up everything correctly you should obtain fitted parameters 329 | printed out in the output close to: 330 | 331 | :: 332 | 333 | Cij (GPa): [ 340 100 180] 334 | 335 | With the following result of fitting: 336 | 337 | :: 338 | 339 | C11 = 325 GPa, C12 = 100 GPa => K= 180 GPa 340 | 341 | The actual numbers depend on the details of the calculations setup but 342 | should be fairly close to the above results. 343 | -------------------------------------------------------------------------------- /docs/source/lib-usage_files/lib-usage_12_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jochym/Elastic/a8f63b811481439084727062d9c8b2ab8f869376/docs/source/lib-usage_files/lib-usage_12_1.png -------------------------------------------------------------------------------- /docs/source/lib-usage_files/lib-usage_18_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jochym/Elastic/a8f63b811481439084727062d9c8b2ab8f869376/docs/source/lib-usage_files/lib-usage_18_1.png -------------------------------------------------------------------------------- /docs/source/lib-usage_files/lib-usage_9_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jochym/Elastic/a8f63b811481439084727062d9c8b2ab8f869376/docs/source/lib-usage_files/lib-usage_9_1.png -------------------------------------------------------------------------------- /docs/source/modules.rst: -------------------------------------------------------------------------------- 1 | Implementation 2 | ============== 3 | 4 | Elastic is implemented as an extension module to 5 | `ASE `_ system 6 | 7 | The Elastic package provides, basically, one main python module and one 8 | auxiliary module (:ref:`par-calc-mod`) which can be useful outside of 9 | the scope of the main code. The :ref:`par-calc-mod` is not distributed 10 | separately but can be just placed by itself somewhere in your python path 11 | and used with any part of the ASE. 12 | I hope it will be incorporated in the main project sometime in the future. 13 | 14 | .. _modules: 15 | 16 | Modules 17 | ------- 18 | 19 | .. automodule:: parcalc.parcalc 20 | :members: 21 | 22 | .. automodule:: elastic.elastic 23 | :members: 24 | 25 | 26 | -------------------------------------------------------------------------------- /elastic/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright 1998-2011 by Paweł T. Jochym 5 | # 6 | # This file is part of Elastic. 7 | 8 | # Elastic is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | 13 | # Elastic is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | 18 | # You should have received a copy of the GNU General Public License 19 | # along with Elastic. If not, see . 20 | 21 | ''' 22 | 23 | .. _elastic-mod: 24 | 25 | Elastic Module 26 | ^^^^^^^^^^^^^^ 27 | 28 | Elastic is a module for calculation of :math:`C_{ij}` components of elastic 29 | tensor from the strain-stress relation. 30 | 31 | The strain components here are ordered in standard way which is different 32 | to ordering in previous versions of the code (up to 4.0). 33 | The ordering is: :math:`u_{xx}, u_{yy}, u_{zz}, u_{yz}, u_{xz}, u_{xy}`. 34 | 35 | The general ordering of :math:`C_{ij}` components is (except for triclinic 36 | symmetry and taking into account customary names of constants - e.g. 37 | :math:`C_{16} \\rightarrow C_{14}`): 38 | 39 | .. math:: 40 | C_{11}, C_{22}, C_{33}, C_{12}, C_{13}, C_{23}, 41 | C_{44}, C_{55}, C_{66}, C_{16}, C_{26}, C_{36}, C_{45} 42 | 43 | The functions with the name of bravais lattices define the symmetry of the 44 | :math:`C_{ij}` matrix. The matrix is N columns by 6 rows where the columns 45 | corespond to independent elastic constants of the given crystal, while the rows 46 | corespond to the canonical deformations of a crystal. The elements are the 47 | second partial derivatives of the free energy formula for the crystal written 48 | down as a quadratic form of the deformations with respect to elastic constant 49 | and deformation. 50 | 51 | *Note:* 52 | The elements for deformations :math:`u_{xy}, u_{xz}, u_{yz}` 53 | have to be divided by 2 to properly match the usual definition 54 | of elastic constants. 55 | 56 | See: [LL]_ L.D. Landau, E.M. Lifszyc, "Theory of elasticity" 57 | 58 | There is some usefull summary also at: 59 | `ScienceWorld `_ 60 | 61 | --------- 62 | 63 | ''' 64 | 65 | from __future__ import print_function, division, absolute_import 66 | from .elastic import get_BM_EOS, get_elastic_tensor 67 | from .elastic import get_elementary_deformations, scan_volumes 68 | from .elastic import get_pressure, get_strain, BMEOS 69 | 70 | # To reach "elastic.__version__" attribute in other programs 71 | from ._version import __version__ 72 | -------------------------------------------------------------------------------- /elastic/cli/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jochym/Elastic/a8f63b811481439084727062d9c8b2ab8f869376/elastic/cli/__init__.py -------------------------------------------------------------------------------- /elastic/cli/elastic.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright 1998-2015 by Paweł T. Jochym 5 | # 6 | # This file is part of Elastic. 7 | 8 | # Elastic is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | 13 | # Elastic is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | 18 | # You should have received a copy of the GNU General Public License 19 | # along with Elastic. If not, see . 20 | 21 | ''' 22 | The elastic command is a command-line tool exposing the functionality 23 | of elastic library for direct use - without writing any python code. 24 | ''' 25 | 26 | from __future__ import print_function, absolute_import, division 27 | import click 28 | import ase.io 29 | import elastic 30 | from click import echo 31 | 32 | verbose = 0 33 | 34 | 35 | def banner(): 36 | if verbose > 1: 37 | echo('Elastic ver. %s\n----------------------' % 38 | elastic._version.version) 39 | 40 | 41 | def set_verbosity(v): 42 | global verbose 43 | verbose = v 44 | 45 | 46 | def process_calc(fn): 47 | from time import sleep 48 | sleep(1) 49 | 50 | 51 | @click.group() 52 | @click.option('--vasp', 'frmt', flag_value='vasp', 53 | help='Use VASP formats (default)', default=True) 54 | @click.option('--abinit', 'frmt', flag_value='abinit', 55 | help='Use AbInit formats') 56 | @click.option('--aims', 'frmt', flag_value='aims', 57 | help='Use FHI-aims formats') 58 | @click.option('--cij', 'action', flag_value='cij', 59 | help='Generate deformations for Cij (default)', default=True) 60 | @click.option('--eos', 'action', flag_value='eos', 61 | help='Generate deformations for Equation of State') 62 | @click.option('-v', '--verbose', count=True, help='Increase verbosity') 63 | @click.version_option() 64 | @click.pass_context 65 | def cli(ctx, frmt, action, verbose): 66 | '''Command-line interface to the elastic library.''' 67 | 68 | if verbose: 69 | set_verbosity(verbose) 70 | banner() 71 | 72 | 73 | @cli.command() 74 | @click.option('-n', '--num', 'num', default=5, type=int, 75 | help='Number of generated deformations per axis (default: 5)') 76 | @click.option('-l', '--lo', 'lo', default=0.98, type=float, 77 | help='Lower relative volume for EOS scan (default: 0.98)') 78 | @click.option('-h', '--hi', 'hi', default=1.02, type=float, 79 | help='Upper relative volume for EOS scan (default: 1.02)') 80 | @click.option('-s', '--size', 'size', default=2.0, type=float, 81 | help='Deformation size for Cij scan (% or deg., default: 2.0)') 82 | @click.argument('struct', type=click.Path(exists=True)) 83 | @click.pass_context 84 | def gen(ctx, num, lo, hi, size, struct): 85 | '''Generate deformed structures''' 86 | 87 | frmt = ctx.parent.params['frmt'] 88 | action = ctx.parent.params['action'] 89 | cryst = ase.io.read(struct, format=frmt) 90 | fn_tmpl = action 91 | if frmt == 'vasp': 92 | fn_tmpl += '_%03d.POSCAR' 93 | kwargs = {'vasp5': True, 'direct': True} 94 | elif frmt == 'abinit': 95 | fn_tmpl += '_%03d.abinit' 96 | kwargs = {} 97 | elif frmt == "aims": 98 | fn_tmpl += '_%03d.in' 99 | kwargs = {} 100 | 101 | if verbose: 102 | from elastic.elastic import get_lattice_type 103 | nr, brav, sg, sgn = get_lattice_type(cryst) 104 | echo('%s lattice (%s): %s' % (brav, sg, cryst.get_chemical_formula())) 105 | if action == 'cij': 106 | echo('Generating {:d} deformations of {:.1f}(%/degs.) per axis'.format( 107 | num, size)) 108 | elif action == 'eos': 109 | echo('Generating {:d} deformations from {:.3f} to {:.3f} of V0'.format( 110 | num, lo, hi)) 111 | 112 | if action == 'cij': 113 | systems = elastic.get_elementary_deformations(cryst, n=num, d=size) 114 | elif action == 'eos': 115 | systems = elastic.scan_volumes(cryst, n=num, lo=lo, hi=hi) 116 | 117 | systems.insert(0, cryst) 118 | if verbose: 119 | echo('Writing %d deformation files.' % len(systems)) 120 | for n, s in enumerate(systems): 121 | ase.io.write(fn_tmpl % n, s, format=frmt, **kwargs) 122 | 123 | 124 | @cli.command() 125 | @click.argument('files', type=click.Path(exists=True), nargs=-1) 126 | @click.pass_context 127 | def proc(ctx, files): 128 | '''Process calculated structures''' 129 | 130 | def calc_reader(fn, verb): 131 | if verb: 132 | echo('Reading: {:<60s}\r'.format(fn), nl=False, err=True) 133 | return ase.io.read(fn) 134 | 135 | action = ctx.parent.params['action'] 136 | systems = [calc_reader(calc, verbose) for calc in files] 137 | if verbose : 138 | echo('', err=True) 139 | if action == 'cij': 140 | cij = elastic.get_elastic_tensor(systems[0], systems=systems[1:]) 141 | msv = cij[1][3].max() 142 | eps = 1e-4 143 | if verbose: 144 | echo('Cij solution\n'+30*'-') 145 | echo(' Solution rank: {:2d}{}'.format( 146 | cij[1][2], 147 | ' (undetermined)' if cij[1][2] < len(cij[0]) else '')) 148 | if cij[1][2] == len(cij[0]): 149 | echo(' Square of residuals: {:7.2g}'.format(cij[1][1])) 150 | echo(' Relative singular values:') 151 | for sv in cij[1][3]/msv: 152 | echo('{:7.4f}{}'.format( 153 | sv, '* ' if (sv) < eps else ' '), nl=False) 154 | echo('\n\nElastic tensor (GPa):') 155 | for dsc in elastic.elastic.get_cij_order(systems[0]): 156 | echo('{: >7s} '.format(dsc), nl=False) 157 | echo('\n'+30*'-') 158 | for c, sv in zip(cij[0], cij[1][3]/msv): 159 | echo('{:7.2f}{}'.format( 160 | c/ase.units.GPa, '* ' if sv < eps else ' '), nl=False) 161 | echo() 162 | elif action == 'eos': 163 | eos = elastic.get_BM_EOS(systems[0], systems=systems[1:]) 164 | eos[1] /= ase.units.GPa 165 | if verbose: 166 | echo('# %7s (A^3) %7s (GPa) %7s' % ("V0", "B0", "B0'")) 167 | echo(' %7.2f %7.2f %7.2f' % tuple(eos)) 168 | 169 | 170 | if __name__ == '__main__': 171 | cli() 172 | -------------------------------------------------------------------------------- /examples/example1.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright 2011 by Paweł T. Jochym 5 | # 6 | # This file is part of Elastic. 7 | 8 | # Elastic is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | 13 | # Elastic is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | 18 | # You should have received a copy of the GNU General Public License 19 | # along with Elastic. If not, see . 20 | 21 | ''' 22 | Example of parallel volume scan using VASP calculator and parcalc module. 23 | ''' 24 | 25 | from ase.lattice.spacegroup import crystal 26 | from parcalc import ClusterVasp, ParCalculate 27 | import ase.units as units 28 | import numpy 29 | import matplotlib.pyplot as plt 30 | 31 | a = 4.194 32 | cryst = crystal(['Mg', 'O'], 33 | [(0, 0, 0), (0.5, 0.5, 0.5)], 34 | spacegroup=225, 35 | cellpar=[a, a, a, 90, 90, 90]) 36 | 37 | # Create the calculator running on one, eight-core node. 38 | # This is specific to the setup on my cluster. 39 | # You have to adapt this part to your environment 40 | calc=ClusterVasp(nodes=1,ppn=8) 41 | 42 | # Assign the calculator to the crystal 43 | cryst.set_calculator(calc) 44 | 45 | # Set the calculation parameters 46 | calc.set(prec = 'Accurate', 47 | xc = 'PBE', 48 | lreal = False, 49 | nsw=30, 50 | ediff=1e-8, 51 | ibrion=2, 52 | kpts=[3,3,3]) 53 | 54 | # Set the calculation mode first. 55 | # Full structure optimization in this case. 56 | # Not all calculators have this type of internal minimizer! 57 | calc.set(isif=3) 58 | 59 | print "Running initial optimization ... ", 60 | print "Residual pressure: %.3f bar" % ( 61 | cryst.get_isotropic_pressure(cryst.get_stress())) 62 | 63 | # Lets extract optimized lattice constant. 64 | # MgO is cubic so a is a first diagonal element of lattice matrix 65 | a=cryst.get_cell()[0,0] 66 | 67 | # Clean up the directory 68 | calc.clean() 69 | 70 | sys=[] 71 | # Iterate over lattice constant in the +/-5% range 72 | for av in numpy.linspace(a*0.95,a*1.05,5): 73 | sys.append(crystal(['Mg', 'O'], [(0, 0, 0), (0.5, 0.5, 0.5)], 74 | spacegroup=225, cellpar=[av, av, av, 90, 90, 90])) 75 | 76 | # Define the template calculator for this run 77 | # We can use the calc from above. It is only used as a template. 78 | # Just change the params to fix the cell volume 79 | calc.set(isif=2) 80 | 81 | # Run the calculation for all systems in sys in parallel 82 | # The result will be returned as list of systems res 83 | res=ParCalculate(sys,calc) 84 | 85 | # Collect the results 86 | v=[] 87 | p=[] 88 | for s in res : 89 | v.append(s.get_volume()) 90 | p.append(s.get_isotropic_pressure(s.get_stress())) 91 | 92 | # Plot the result (you need matplotlib for this 93 | plt.plot(v,p,'o') 94 | plt.show() 95 | 96 | -------------------------------------------------------------------------------- /examples/example2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright 2011 by Paweł T. Jochym 5 | # 6 | # This file is part of Elastic. 7 | 8 | # Elastic is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | 13 | # Elastic is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | 18 | # You should have received a copy of the GNU General Public License 19 | # along with Elastic. If not, see . 20 | 21 | ''' 22 | Example of Birch-Murnaghan EOS calculation using VASP calculator and 23 | elastic module. 24 | ''' 25 | 26 | from ase.lattice.spacegroup import crystal 27 | from parcalc import ClusterVasp, ParCalculate 28 | from elastic import Crystal, BMEOS 29 | import ase.units as units 30 | from numpy import array, linspace 31 | import matplotlib.pyplot as plt 32 | 33 | a = 4.194 34 | cryst = Crystal(crystal(['Mg', 'O'], 35 | [(0, 0, 0), (0.5, 0.5, 0.5)], 36 | spacegroup=225, 37 | cellpar=[a, a, a, 90, 90, 90])) 38 | 39 | # Create the calculator running on one, eight-core node. 40 | # This is specific to the setup on my cluster. 41 | # You have to adapt this part to your environment 42 | calc=ClusterVasp(nodes=1,ppn=8) 43 | 44 | # Assign the calculator to the crystal 45 | cryst.set_calculator(calc) 46 | 47 | # Set the calculation parameters 48 | calc.set(prec = 'Accurate', 49 | xc = 'PBE', 50 | lreal = False, 51 | nsw=30, 52 | ediff=1e-8, 53 | ibrion=2, 54 | kpts=[3,3,3]) 55 | 56 | # Set the calculation mode first. 57 | # Full structure optimization in this case. 58 | # Not all calculators have this type of internal minimizer! 59 | calc.set(isif=3) 60 | print "Running initial optimization ... ", 61 | print "Residual pressure: %.3f bar" % ( 62 | cryst.get_isotropic_pressure(cryst.get_stress())) 63 | 64 | # Lets extract optimized lattice constant. 65 | # MgO is cubic so a is a first diagonal element of lattice matrix 66 | a=cryst.get_cell()[0,0] 67 | 68 | # Clean up the directory 69 | calc.clean() 70 | 71 | # Switch to cell shape+IDOF optimizer 72 | calc.set(isif=4) 73 | 74 | # Calculate few volumes and fit B-M EOS to the result 75 | # Use +/-3% volume deformation and 5 data points 76 | fit=cryst.get_BM_EOS(n=5,lo=0.97,hi=1.03) 77 | 78 | # Get the P(V) data points just calculated 79 | pv=array(cryst.pv) 80 | 81 | # Sort data on the first column (V) 82 | pv=pv[pv[:,0].argsort()] 83 | 84 | # Print just fitted parameters 85 | print "V0=%.3f A^3 ; B0=%.2f GPa ; B0'=%.3f ; a0=%.5f A" % ( 86 | fit[0], fit[1]/units.GPa, fit[2], pow(fit[0],1./3)) 87 | 88 | v0=fit[0] 89 | 90 | # B-M EOS for plotting 91 | fitfunc = lambda p, x: [BMEOS(xv,p[0],p[1],p[2]) for xv in x] 92 | 93 | # Ranges - the ordering in pv is not guarateed at all! 94 | # In fact it may be purely random. 95 | x=array([min(pv[:,0]),max(pv[:,0])]) 96 | y=array([min(pv[:,1]),max(pv[:,1])]) 97 | 98 | 99 | # Plot the P(V) curves and points for the crystal 100 | # Plot the points 101 | plt.plot(pv[:,0]/v0,pv[:,1],'o') 102 | 103 | # Mark the center P=0 V=V0 104 | plt.axvline(1,ls='--') 105 | plt.axhline(0,ls='--') 106 | 107 | # Plot the fitted B-M EOS through the points 108 | xa=linspace(x[0],x[-1],20) 109 | plt.plot(xa/v0,fitfunc(fit,xa),'-') 110 | plt.show() 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /examples/example3.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright 2011 by Paweł T. Jochym 5 | # 6 | # This file is part of Elastic. 7 | 8 | # Elastic is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | 13 | # Elastic is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | 18 | # You should have received a copy of the GNU General Public License 19 | # along with Elastic. If not, see . 20 | 21 | ''' 22 | Example of elastic tensor calculation using VASP calculator and 23 | elastic module. 24 | ''' 25 | 26 | from ase.lattice.spacegroup import crystal 27 | from parcalc import ClusterVasp, ParCalculate 28 | from elastic import Crystal 29 | import ase.units as units 30 | from numpy import array, linspace 31 | import matplotlib.pyplot as plt 32 | import numpy 33 | 34 | # Create the MgO crystal 35 | a = 4.194 36 | cryst = Crystal(crystal(['Mg', 'O'], 37 | [(0, 0, 0), (0.5, 0.5, 0.5)], 38 | spacegroup=225, 39 | cellpar=[a, a, a, 90, 90, 90])) 40 | 41 | # Create the calculator running on one, eight-core node. 42 | # This is specific to the setup on my cluster. 43 | # You have to adapt this part to your environment 44 | calc=ClusterVasp(nodes=1,ppn=8) 45 | 46 | # Assign the calculator to the crystal 47 | cryst.set_calculator(calc) 48 | 49 | # Set the calculation parameters 50 | calc.set(prec = 'Accurate', 51 | xc = 'PBE', 52 | lreal = False, 53 | nsw=30, 54 | ediff=1e-8, 55 | ibrion=2, 56 | kpts=[3,3,3]) 57 | 58 | # Set the calculation mode first. 59 | # Full structure optimization in this case. 60 | # Not all calculators have this type of internal minimizer! 61 | calc.set(isif=3) 62 | 63 | print "Running initial optimization ... ", 64 | print "Residual pressure: %.3f bar" % ( 65 | cryst.get_isotropic_pressure(cryst.get_stress())) 66 | 67 | # Clean up the directory 68 | calc.clean() 69 | 70 | # Switch to cell IDOF optimizer 71 | calc.set(isif=2) 72 | 73 | # Elastic tensor by internal routine 74 | Cij, Bij=cryst.get_elastic_tensor(n=5,d=0.2) 75 | print "Cij (GPa):", Cij/units.GPa 76 | 77 | 78 | # Now let us do it (only c11 and c12) by hand 79 | # with 3rd order polynomial fitting the points. 80 | sys=[] 81 | for d in linspace(-0.2,0.2,10): 82 | sys.append(cryst.get_cart_deformed_cell(axis=0,size=d)) 83 | r=ParCalculate(sys,cryst.calc) 84 | ss=[] 85 | for s in r: 86 | ss.append([s.get_strain(cryst), s.get_stress()]) 87 | 88 | # Plot strain-stress relation 89 | ss=[] 90 | for p in r: 91 | ss.append([p.get_strain(cryst),p.get_stress()]) 92 | ss=array(ss) 93 | lo=min(ss[:,0,0]) 94 | hi=max(ss[:,0,0]) 95 | mi=(lo+hi)/2 96 | wi=(hi-lo)/2 97 | xa=linspace(mi-1.1*wi,mi+1.1*wi, 50) 98 | plt.plot(ss[:,0,0],ss[:,1,0],'k.') 99 | plt.plot(ss[:,0,0],ss[:,1,1],'r.') 100 | 101 | plt.axvline(0,ls='--') 102 | plt.axhline(0,ls='--') 103 | 104 | 105 | # C11 component 106 | f=numpy.polyfit(ss[:,0,0],ss[:,1,0],3) 107 | c11=f[-2]/units.GPa 108 | plt.plot(xa,numpy.polyval(f,xa),'b-') 109 | 110 | # C12 component 111 | f=numpy.polyfit(ss[:,0,0],ss[:,1,1],3) 112 | c12=f[-2]/units.GPa 113 | plt.plot(xa,numpy.polyval(f,xa),'g-') 114 | 115 | print 'C11 = %.3f GPa, C12 = %.3f GPa => K= %.3f GPa' % (c11, c12, (c11+2*c12)/3) 116 | 117 | plt.show() 118 | 119 | -------------------------------------------------------------------------------- /examples/scripts/check-job: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Check the status of the job running in the current directory 4 | 5 | # The job starting script MUST create the JOBDATA file upon submission 6 | . JOBDATA 7 | 8 | jid=`echo $JID|awk -F='.' '{print $1.$2}'` 9 | 10 | js=`run-on-tsi "qstat -l -f $jid" 2>/dev/null |grep job_state|awk '{print $3}'` 11 | 12 | if [ -e $LOCK ]; then 13 | if [ $js = R -o $js = Q -o $js = H ]; then 14 | res='RL' 15 | else 16 | # something crashed - inconsistent state 17 | res='UL' 18 | fi 19 | else 20 | res='FN' 21 | fi 22 | 23 | echo $res 24 | 25 | -------------------------------------------------------------------------------- /examples/scripts/run-on-tsi: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | WD=`pwd` 4 | 5 | ssh tsi "cd $WD ; $1" 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /examples/scripts/run-vasp5-lock: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | MAIL=$USER@wolf.ifj.edu.pl 4 | NAME=`basename \`pwd\`` 5 | NODES="nodes=1:ppn=1" 6 | VASP=/home/jochym/src/VASP/newbuild/bin/vasp.Linux.barcelona-64.PGI 7 | VASP=/home/vasp/bin/vasp5 8 | NAME=`echo $NAME|sed 's/\(^[^a-zA-Z]\)/J\1/'` 9 | NCL=0 10 | QUEUE=batch 11 | BLOCK=1 12 | LOCK=`mktemp lockfile.XXXXX` 13 | 14 | if [ -f vasprun.conf ] ; then 15 | . ./vasprun.conf 16 | fi 17 | 18 | VASPMPI=${VASP}-mpi 19 | 20 | if [ $NCL == 1 ] ; then 21 | VASP=${VASP}-ncl 22 | VASPMPI=${VASPMPI}-ncl 23 | fi 24 | 25 | echo $VASP $VASPMPI $NODES 26 | 27 | echo "LOCK=$LOCK" >JOBDATA 28 | echo -n "JID=" >>JOBDATA 29 | 30 | qsub <>JOBDATA 31 | #!/bin/bash 32 | #PBS -N $NAME 33 | #PBS -m be 34 | #PBS -l $NODES 35 | #PBS -M $MAIL 36 | #PBS -r n 37 | #PBS -q $QUEUE 38 | ## 39 | 40 | trap "rm -f \$PBS_O_WORKDIR/$LOCK" EXIT 41 | 42 | #PATH=/opt/mpi/bin/:\$PATH 43 | #export LD_LIBRARY_PATH=/opt/lib 44 | # export MPD_USE_ROOT_MPD=1 45 | numprocs=\`wc -l <\$PBS_NODEFILE\` 46 | nodes=\`sort <\$PBS_NODEFILE | uniq |wc -l \` 47 | 48 | if [ \$numprocs -gt 1 ] ; then 49 | type="MPI " 50 | else 51 | type="Scalar " 52 | fi 53 | 54 | echo \$type job started 55 | echo " " at \`date\` 56 | echo " " on host \`hostname\` 57 | echo " " working directory is \$PBS_O_WORKDIR 58 | echo " " will run on \`cat < \$PBS_NODEFILE\` 59 | echo " " basic executable: $VASP 60 | 61 | hn=\`hostname\` 62 | 63 | 64 | hn=\${hn/#c/i} 65 | hn=\${hn/#h/j} 66 | 67 | echo " " Head node: \$hn 68 | 69 | 70 | cd \$PBS_O_WORKDIR/ 71 | 72 | 73 | echo "" 74 | echo "=================== JOB OUTPUT ==========================" 75 | echo "" 76 | 77 | if [ \$numprocs -gt 1 ] ; then 78 | nodefile=\`mktemp nodefile.XXXXXX\` 79 | #sed -e 's/^c/i/g' -e 's/^h/j/g' < \$PBS_NODEFILE >\$nodefile 80 | sed -e 's/^c/i/g' -e 's/^h/j/g' -e 's/^bl/k/g' < \$PBS_NODEFILE |xargs -l1 getent hosts |sort|uniq -c|awk '{ printf("%s:%s\n",\$2,\$1) }' >\$nodefile 81 | mpiexec.mpich -f \$nodefile -n \$numprocs $VASPMPI 82 | rm -f \$nodefile 83 | else 84 | $VASP 85 | fi 86 | 87 | echo "" 88 | echo "=================== JOB OUTPUT ==========================" 89 | echo "" 90 | 91 | cd \$PBS_O_WORKDIR/ 92 | 93 | echo Job finished at \`date\` 94 | rm -f $LOCK 95 | 96 | EOF 97 | 98 | if [ ".$BLOCK" != ".0" ] ; then 99 | # Default mode - we are blocking until the job removes the lock 100 | # or vanishes from the queue 101 | #echo "Job submitted. Waiting for it to finish" 102 | while [ -e $LOCK ] ; do 103 | sleep 10 104 | done 105 | fi 106 | #echo "Job finished" 107 | -------------------------------------------------------------------------------- /examples/scripts/run_vasp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import os 4 | exitcode = os.system('run-on-tsi ~/bin/run-vasp5-lock >/dev/null') 5 | #exitcode = os.system('run-on-tsi /opt/bin/run-vasp5 >/dev/null') 6 | 7 | #exitcode = os.system('~/bin/run-vasp5-lock') 8 | -------------------------------------------------------------------------------- /paper.bib: -------------------------------------------------------------------------------- 1 | 2 | @misc{https://doi.org/10.5281/zenodo.18759, 3 | doi = {10.5281/zenodo.18759}, 4 | author = {{Paweł T. Jochym}}, 5 | keywords = {}, 6 | title = {Elastic: Bugfix + conda build}, 7 | publisher = {Zenodo}, 8 | year = {2015} 9 | } 10 | 11 | @article{Jochym1999, 12 | doi = {10.1007/s100510050823}, 13 | url = {https://doi.org/10.1007/s100510050823}, 14 | year = {1999}, 15 | month = {jul}, 16 | publisher = {Springer Nature}, 17 | volume = {10}, 18 | number = {1}, 19 | pages = {9--13}, 20 | author = {P.T. Jochym and K. Parlinski and M. Sternik}, 21 | title = {{TiC} lattice dynamics from ab initio calculations}, 22 | journal = {The European Physical Journal B} 23 | } 24 | 25 | @article{Jochym2000, 26 | doi = {10.1007/s100510051124}, 27 | url = {https://doi.org/10.1007/s100510051124}, 28 | year = {2000}, 29 | month = {may}, 30 | publisher = {Springer Nature}, 31 | volume = {15}, 32 | number = {2}, 33 | pages = {265--268}, 34 | author = {P.T. Jochym and K. Parlinski}, 35 | title = {Ab initio lattice dynamics and elastic constants of {ZrC}}, 36 | journal = {The European Physical Journal B} 37 | } 38 | 39 | @article{Golub1965, 40 | doi = {10.1137/0702016}, 41 | url = {https://doi.org/10.1137/0702016}, 42 | year = {1965}, 43 | month = {jan}, 44 | publisher = {Society for Industrial {\&} Applied Mathematics ({SIAM})}, 45 | volume = {2}, 46 | number = {2}, 47 | pages = {205--224}, 48 | author = {G. Golub and W. Kahan}, 49 | title = {Calculating the Singular Values and Pseudo-Inverse of a Matrix}, 50 | journal = {Journal of the Society for Industrial and Applied Mathematics Series B Numerical Analysis} 51 | } 52 | 53 | @book{landau1986theory, 54 | title={Theory of Elasticity}, 55 | author={Landau, L.D. and Lifshitz, E.M. and Kosevich, A.M. and Pitaevski{\u\i}}, L.P.}, 56 | isbn={9780750626330}, 57 | series={Course of theoretical physics}, 58 | url={https://books.google.pl/books?id=tpY-VkwCkAIC}, 59 | year={1986}, 60 | publisher={Butterworth-Heinemann} 61 | } 62 | -------------------------------------------------------------------------------- /paper.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Elastic: computing elasticity tensor of crystalline materials' 3 | tags: 4 | - computational material science 5 | - ase 6 | - python 7 | authors: 8 | - name: Paweł T. Jochym 9 | orcid: 0000-0003-0427-7333 10 | affiliation: 1 11 | affiliations: 12 | - name: Institute of Nuclear Physics, Polish Academy of Sciences, Poland 13 | index: 1 14 | date: 20 June 2017 15 | bibliography: paper.bib 16 | --- 17 | 18 | # Summary 19 | 20 | Elastic is a set of python routines for calculation of elastic properties of 21 | crystals (elastic constants, equation of state, sound velocities, etc.). 22 | It is a third version of the in-house code I have 23 | written over several years and is implemented as a extension to the 24 | [ASE](https://wiki.fysik.dtu.dk/ase/) system. 25 | The code was a basis for some of my publications and was 26 | described briefly in these papers. It was also presented 27 | at [Workshop on ab initio Calculations in Geosciences](http://wolf.ifj.edu.pl/workshop/work2008/) 28 | and used by some of my co-workers. The code is published and developed on 29 | [github repository](https://github.com/jochym/Elastic) with 30 | corresponding [elastic web page](https://jochym.github.io/Elastic/) and 31 | on-line documentation placed at [Elastic website](http://wolf.ifj.edu.pl/elastic/) 32 | and on [ReadTheDocs](http://elastic.rtfd.org/). 33 | 34 | # References 35 | 36 | -------------------------------------------------------------------------------- /parcalc/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright 2011 by Pawel T. Jochym 5 | # 6 | # This file is part of Elastic. 7 | 8 | # Elastic is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | 13 | # Elastic is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | 18 | # You should have received a copy of the GNU General Public License 19 | # along with Elastic. If not, see . 20 | ''' 21 | 22 | .. _par-calc-mod: 23 | 24 | Parallel Calculator Module 25 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ 26 | 27 | Parallel calculator module is an extension of the standard 28 | `ASE `_ calculator working in the 29 | parallel cluster environment. It is very useful in all situations where 30 | you need to run several, independent calculations and you have a large 31 | cluster of machines at your disposal (probably with some queuing system). 32 | 33 | This implementation uses VASP but the code can be easily adapted for use 34 | with other ASE calculators with minor changes. 35 | The final goal is to provide a universal module for parallel 36 | calculator execution in the cluster environment. 37 | 38 | The SIESTA code by Georgios Tritsaris 39 | Not fully tested after merge. 40 | 41 | ''' 42 | 43 | from .parcalc import ClusterVasp, ClusterSiesta, ParCalculate, RemoteCalculator 44 | 45 | 46 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools", "setuptools-scm"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project] 6 | dynamic = ["version"] 7 | name = "elastic" 8 | dependencies = [ 9 | "ase", 10 | "spglib", 11 | "numpy", 12 | "scipy", 13 | "click", 14 | ] 15 | authors = [ 16 | {name = "Paweł T. Jochym", email = "Pawel.Jochym@ifj.edu.pl"}, 17 | {name = "Georgios Tritsaris", email = "gtritsaris@seas.harvard.edu"}, 18 | ] 19 | maintainers = [ 20 | {name = "Paweł T. Jochym", email = "Pawel.Jochym@ifj.edu.pl"}, 21 | ] 22 | description = "Extension for ASE to calculate elastic constants" 23 | readme = "README.md" 24 | license = {text = "GPLv3"} 25 | keywords = ['science', 'physics', 'ase', 'elastic constants', 'crystals'] 26 | classifiers = [ 27 | "Development Status :: 5 - Production/Stable", 28 | "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", 29 | "Programming Language :: Python :: 3", 30 | ] 31 | 32 | [project.scripts] 33 | elastic = "elastic.cli.elastic:cli" 34 | 35 | [project.urls] 36 | Homepage = "https://wolf.ifj.edu.pl/elastic" 37 | Documentation = "http://elastic.rtfd.org/" 38 | Repository = "https://github.com/jochym/Elastic" 39 | Issues = "https://github.com/jochym/Elastic/issues" 40 | Changelog = "https://github.com/jochym/Elastic/blob/master/CHANGELOG.md" 41 | 42 | 43 | 44 | [tool.setuptools.packages] 45 | find = {} # Scan the project directory with the default parameters 46 | 47 | [tool.setuptools_scm] 48 | version_file = "elastic/_version.py" 49 | 50 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | ase 2 | spglib >= 2.5.0 3 | numpy 4 | scipy 5 | setuptools_scm 6 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from __future__ import annotations 4 | from setuptools import setup 5 | from setuptools_scm import ScmVersion 6 | from setuptools_scm.version import get_no_local_node 7 | 8 | def current_version(version: ScmVersion) -> str: 9 | from setuptools_scm.version import guess_next_version 10 | 11 | delim = '.' 12 | if version.branch in ("master", "main"): 13 | delim = '.' 14 | if version.branch in ("dev", "devel"): 15 | delim = '-dev' 16 | if version.branch in ("fix", "hotfix"): 17 | delim = '-post' 18 | 19 | return version.format_next_version(guess_next_version, 20 | "{tag}"+ delim +"{distance}") 21 | 22 | setup(use_scm_version={"version_scheme": current_version, 23 | "local_scheme": get_no_local_node}) 24 | -------------------------------------------------------------------------------- /test/test_elastic.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function, division 2 | import unittest 3 | from hypothesis import given, assume 4 | from hypothesis.strategies import integers, floats, builds 5 | from numpy import pi, allclose, cos, sin, array, zeros 6 | 7 | from elastic.elastic import get_deformed_cell, get_lattice_type 8 | from elastic.elastic import get_vecang_cell, scan_volumes 9 | 10 | 11 | def ctg(x): 12 | return cos(x)/sin(x) 13 | 14 | 15 | def csc(x): 16 | return 1/sin(x) 17 | 18 | 19 | def build_crystal(a, b, c, al, be, ga): 20 | from ase.atoms import Atoms 21 | if (al+be+ga > 350): return 22 | if (al+be < 1.1*ga): return 23 | if (al+ga < 1.1*be): return 24 | if (be+ga < 1.1*al): return 25 | 26 | atms = Atoms('Mg', positions=[(0, 0, 0)], 27 | cell=[a, b, c, al, be, ga], pbc=True) 28 | atms._test_data = [a, b, c, al*pi/180, be*pi/180, ga*pi/180] 29 | return atms 30 | 31 | 32 | crystals = builds(build_crystal, 33 | a=floats(min_value=1.0, max_value=20.0), 34 | b=floats(min_value=1.0, max_value=20.0), 35 | c=floats(min_value=1.0, max_value=20.0), 36 | al=floats(min_value=15.0, max_value=120.0), 37 | be=floats(min_value=15.0, max_value=120.0), 38 | ga=floats(min_value=15.0, max_value=120.0), 39 | ) 40 | 41 | 42 | class TestElastic(unittest.TestCase): 43 | 44 | def setUp(self): 45 | pass 46 | 47 | def tearDown(self): 48 | pass 49 | 50 | def test_elastic_import(self): 51 | import elastic 52 | 53 | def test_parcalc_import(self): 54 | import parcalc 55 | 56 | @given(cr=crystals) 57 | def test_lattice_type(self, cr): 58 | assume(cr is not None) 59 | assert get_lattice_type(cr)[0] in (1, 2, 3, 4, 5, 6, 7) 60 | 61 | @given(cr=crystals) 62 | def test_lattice_vecang(self, cr): 63 | assume(cr is not None) 64 | assert allclose(get_vecang_cell(cr), cr._test_data) 65 | 66 | @given(cr=crystals, 67 | ax=integers(min_value=0, max_value=2), 68 | prc=floats(min_value=-90, max_value=90), 69 | ) 70 | def test_deform_shrink(self, cr, ax, prc): 71 | assume(cr is not None) 72 | dc = get_deformed_cell(cr, axis=ax, size=prc) 73 | assert allclose((dc.get_volume()/cr.get_volume()-1)*100, prc) 74 | assert allclose((dc.get_cell_lengths_and_angles()[ax]/cr._test_data[ax] - 1)*100, prc) 75 | 76 | @given(cr=crystals, 77 | ax=integers(min_value=0, max_value=2), 78 | size=floats(min_value=-10, max_value=10), 79 | ) 80 | def test_deform_angels(self, cr, ax, size): 81 | assume(cr is not None) 82 | delta = zeros(3) 83 | delta[ax] = pi*size/180 84 | (alp, bet, gam) = array(cr._test_data[3:]) + delta 85 | # Guard against non-existing lattice vectors 86 | t = 1 - (ctg(bet)*ctg(gam)-cos(alp)*csc(bet)*csc(gam))**2 87 | assume(t > 1e-6) 88 | dc = get_deformed_cell(cr, axis=ax+3, size=size) 89 | assert allclose(pi*dc.get_cell_lengths_and_angles()[ax+3]/180, 90 | cr._test_data[ax+3] + pi*size/180, atol=pi*1e-3/180) 91 | 92 | @given(cr=crystals, 93 | lo=floats(min_value=0.1, max_value=1.0), 94 | hi=floats(min_value=1.0, max_value=2.0), 95 | n=integers(min_value=2, max_value=20), 96 | ) 97 | def test_volume_scan(self, cr, lo, hi, n): 98 | assume(cr is not None) 99 | cl = scan_volumes(cr, lo, hi, n, True) 100 | eps = 1e-6 101 | assert len(cl) == n 102 | assert allclose(cl[0].get_volume(), cr.get_volume()*lo) 103 | assert allclose(cl[-1].get_volume(), cr.get_volume()*hi) 104 | for c in cl[1:-1]: 105 | assert cr.get_volume()*lo <= c.get_volume() <= cr.get_volume()*hi 106 | 107 | 108 | if __name__ == '__main__': 109 | unittest.main() 110 | -------------------------------------------------------------------------------- /tests/data/INCAR: -------------------------------------------------------------------------------- 1 | INCAR created by Atomic Simulation Environment 2 | EDIFF = 1.00e-08 3 | GGA = PE 4 | PREC = Accurate 5 | IBRION = 2 6 | ISIF = 2 7 | NSW = 30 8 | LREAL = A 9 | LCHARG = .FALSE. 10 | LWAVE = .FALSE. 11 | ALGO = Fast 12 | NPAR = 4 -------------------------------------------------------------------------------- /tests/data/KPOINTS: -------------------------------------------------------------------------------- 1 | KPOINTS created by Atomic Simulation Environment 2 | 0 3 | Monkhorst-Pack 4 | 3 3 3 5 | 0 0 0 6 | -------------------------------------------------------------------------------- /tests/data/POSCAR: -------------------------------------------------------------------------------- 1 | Mg O 2 | 1.0000000000000000 3 | 4.2004725253589212 0.0000000000000000 0.0000000000000000 4 | 0.0000000000000000 4.2004725253589212 0.0000000000000000 5 | 0.0000000000000000 0.0000000000000000 4.2004725253589212 6 | Mg O 7 | 4 4 8 | Direct 9 | 0.0000000000000000 0.0000000000000000 0.0000000000000000 10 | 0.0000000000000000 0.5000000000000000 0.5000000000000000 11 | 0.5000000000000000 0.0000000000000000 0.5000000000000000 12 | 0.5000000000000000 0.5000000000000000 0.0000000000000000 13 | 0.5000000000000000 0.5000000000000000 0.5000000000000000 14 | 0.5000000000000000 0.0000000000000000 0.0000000000000000 15 | 0.0000000000000000 0.5000000000000000 0.0000000000000000 16 | 0.0000000000000000 0.0000000000000000 0.5000000000000000 17 | -------------------------------------------------------------------------------- /tests/data/abinit: -------------------------------------------------------------------------------- 1 | 2 | # Definition of the atom types 3 | ntypat 2 4 | znucl 12 8 5 | 6 | # Definition of the atoms 7 | natom 8 8 | typat 1 1 1 1 2 2 2 2 9 | 10 | # Definition of the unit cell 11 | acell 12 | 1.00000000000000 1.00000000000000 1.00000000000000 Angstrom 13 | 14 | rprim 15 | 4.2004725253589212 0.0000000000000000 0.0000000000000000 16 | 0.0000000000000000 4.2004725253589212 0.0000000000000000 17 | 0.0000000000000000 0.0000000000000000 4.2004725253589212 18 | 19 | xred 20 | 0.0000000000000000 0.0000000000000000 0.0000000000000000 21 | 0.0000000000000000 0.5000000000000000 0.5000000000000000 22 | 0.5000000000000000 0.0000000000000000 0.5000000000000000 23 | 0.5000000000000000 0.5000000000000000 0.0000000000000000 24 | 0.5000000000000000 0.5000000000000000 0.5000000000000000 25 | 0.5000000000000000 0.0000000000000000 0.0000000000000000 26 | 0.0000000000000000 0.5000000000000000 0.0000000000000000 27 | 0.0000000000000000 0.0000000000000000 0.5000000000000000 28 | -------------------------------------------------------------------------------- /tests/data/cij_000.POSCAR: -------------------------------------------------------------------------------- 1 | Mg O 2 | 1.0000000000000000 3 | 4.2004725253589212 0.0000000000000000 0.0000000000000000 4 | 0.0000000000000000 4.2004725253589212 0.0000000000000000 5 | 0.0000000000000000 0.0000000000000000 4.2004725253589212 6 | Mg O 7 | 4 4 8 | Direct 9 | 0.0000000000000000 0.0000000000000000 0.0000000000000000 10 | 0.0000000000000000 0.5000000000000000 0.5000000000000000 11 | 0.5000000000000000 0.0000000000000000 0.5000000000000000 12 | 0.5000000000000000 0.5000000000000000 0.0000000000000000 13 | 0.5000000000000000 0.5000000000000000 0.5000000000000000 14 | 0.5000000000000000 0.0000000000000000 0.0000000000000000 15 | 0.0000000000000000 0.5000000000000000 0.0000000000000000 16 | 0.0000000000000000 0.0000000000000000 0.5000000000000000 17 | -------------------------------------------------------------------------------- /tests/data/cij_001.POSCAR: -------------------------------------------------------------------------------- 1 | Mg O 2 | 1.0000000000000000 3 | 4.1164630748517430 0.0000000000000000 0.0000000000000000 4 | 0.0000000000000000 4.2004725253589212 0.0000000000000000 5 | 0.0000000000000000 0.0000000000000000 4.2004725253589212 6 | Mg O 7 | 4 4 8 | Direct 9 | 0.0000000000000000 0.0000000000000000 0.0000000000000000 10 | 0.0000000000000000 0.5000000000000000 0.5000000000000000 11 | 0.5000000000000000 0.0000000000000000 0.5000000000000000 12 | 0.5000000000000000 0.5000000000000000 0.0000000000000000 13 | 0.5000000000000000 0.5000000000000000 0.5000000000000000 14 | 0.5000000000000000 0.0000000000000000 0.0000000000000000 15 | 0.0000000000000000 0.5000000000000000 0.0000000000000000 16 | 0.0000000000000000 0.0000000000000000 0.5000000000000000 17 | -------------------------------------------------------------------------------- /tests/data/cij_002.POSCAR: -------------------------------------------------------------------------------- 1 | Mg O 2 | 1.0000000000000000 3 | 4.1584678001053321 0.0000000000000000 0.0000000000000000 4 | 0.0000000000000000 4.2004725253589212 0.0000000000000000 5 | 0.0000000000000000 0.0000000000000000 4.2004725253589212 6 | Mg O 7 | 4 4 8 | Direct 9 | 0.0000000000000000 0.0000000000000000 0.0000000000000000 10 | 0.0000000000000000 0.5000000000000000 0.5000000000000000 11 | 0.5000000000000000 0.0000000000000000 0.5000000000000000 12 | 0.5000000000000000 0.5000000000000000 0.0000000000000000 13 | 0.5000000000000000 0.5000000000000000 0.5000000000000000 14 | 0.5000000000000000 0.0000000000000000 0.0000000000000000 15 | 0.0000000000000000 0.5000000000000000 0.0000000000000000 16 | 0.0000000000000000 0.0000000000000000 0.5000000000000000 17 | -------------------------------------------------------------------------------- /tests/data/cij_003.POSCAR: -------------------------------------------------------------------------------- 1 | Mg O 2 | 1.0000000000000000 3 | 4.2004725253589212 0.0000000000000000 0.0000000000000000 4 | 0.0000000000000000 4.2004725253589212 0.0000000000000000 5 | 0.0000000000000000 0.0000000000000000 4.2004725253589212 6 | Mg O 7 | 4 4 8 | Direct 9 | 0.0000000000000000 0.0000000000000000 0.0000000000000000 10 | 0.0000000000000000 0.5000000000000000 0.5000000000000000 11 | 0.5000000000000000 0.0000000000000000 0.5000000000000000 12 | 0.5000000000000000 0.5000000000000000 0.0000000000000000 13 | 0.5000000000000000 0.5000000000000000 0.5000000000000000 14 | 0.5000000000000000 0.0000000000000000 0.0000000000000000 15 | 0.0000000000000000 0.5000000000000000 0.0000000000000000 16 | 0.0000000000000000 0.0000000000000000 0.5000000000000000 17 | -------------------------------------------------------------------------------- /tests/data/cij_004.POSCAR: -------------------------------------------------------------------------------- 1 | Mg O 2 | 1.0000000000000000 3 | 4.2424772506125104 0.0000000000000000 0.0000000000000000 4 | 0.0000000000000000 4.2004725253589212 0.0000000000000000 5 | 0.0000000000000000 0.0000000000000000 4.2004725253589212 6 | Mg O 7 | 4 4 8 | Direct 9 | 0.0000000000000000 0.0000000000000000 0.0000000000000000 10 | 0.0000000000000000 0.5000000000000000 0.5000000000000000 11 | 0.5000000000000000 0.0000000000000000 0.5000000000000000 12 | 0.5000000000000000 0.5000000000000000 0.0000000000000000 13 | 0.5000000000000000 0.5000000000000000 0.5000000000000000 14 | 0.5000000000000000 0.0000000000000000 0.0000000000000000 15 | 0.0000000000000000 0.5000000000000000 0.0000000000000000 16 | 0.0000000000000000 0.0000000000000000 0.5000000000000000 17 | -------------------------------------------------------------------------------- /tests/data/cij_005.POSCAR: -------------------------------------------------------------------------------- 1 | Mg O 2 | 1.0000000000000000 3 | 4.2844819758660995 0.0000000000000000 0.0000000000000000 4 | 0.0000000000000000 4.2004725253589212 0.0000000000000000 5 | 0.0000000000000000 0.0000000000000000 4.2004725253589212 6 | Mg O 7 | 4 4 8 | Direct 9 | 0.0000000000000000 0.0000000000000000 0.0000000000000000 10 | 0.0000000000000000 0.5000000000000000 0.5000000000000000 11 | 0.5000000000000000 0.0000000000000000 0.5000000000000000 12 | 0.5000000000000000 0.5000000000000000 0.0000000000000000 13 | 0.5000000000000000 0.5000000000000000 0.5000000000000000 14 | 0.5000000000000000 0.0000000000000000 0.0000000000000000 15 | 0.0000000000000000 0.5000000000000000 0.0000000000000000 16 | 0.0000000000000000 0.0000000000000000 0.5000000000000000 17 | -------------------------------------------------------------------------------- /tests/data/cij_006.POSCAR: -------------------------------------------------------------------------------- 1 | Mg O 2 | 1.0000000000000000 3 | 4.2004725253589212 0.0000000000000000 0.0000000000000000 4 | 0.0000000000000000 4.2004725253589212 0.0084009450507178 5 | 0.0000000000000000 0.0000000000000000 4.2004725253589212 6 | Mg O 7 | 4 4 8 | Direct 9 | 0.0000000000000000 0.0000000000000000 0.0000000000000000 10 | 0.0000000000000000 0.5000000000000000 0.5000000000000000 11 | 0.5000000000000000 0.0000000000000000 0.5000000000000000 12 | 0.5000000000000000 0.5000000000000000 0.0000000000000000 13 | 0.5000000000000000 0.5000000000000000 0.5000000000000000 14 | 0.5000000000000000 0.0000000000000000 0.0000000000000000 15 | 0.0000000000000000 0.5000000000000000 0.0000000000000000 16 | 0.0000000000000000 0.0000000000000000 0.5000000000000000 17 | -------------------------------------------------------------------------------- /tests/data/cij_007.POSCAR: -------------------------------------------------------------------------------- 1 | Mg O 2 | 1.0000000000000000 3 | 4.2004725253589212 0.0000000000000000 0.0000000000000000 4 | 0.0000000000000000 4.2004725253589212 0.0273030714148330 5 | 0.0000000000000000 0.0000000000000000 4.2004725253589212 6 | Mg O 7 | 4 4 8 | Direct 9 | 0.0000000000000000 0.0000000000000000 0.0000000000000000 10 | 0.0000000000000000 0.5000000000000000 0.5000000000000000 11 | 0.5000000000000000 0.0000000000000000 0.5000000000000000 12 | 0.5000000000000000 0.5000000000000000 0.0000000000000000 13 | 0.5000000000000000 0.5000000000000000 0.5000000000000000 14 | 0.5000000000000000 0.0000000000000000 0.0000000000000000 15 | 0.0000000000000000 0.5000000000000000 0.0000000000000000 16 | 0.0000000000000000 0.0000000000000000 0.5000000000000000 17 | -------------------------------------------------------------------------------- /tests/data/cij_008.POSCAR: -------------------------------------------------------------------------------- 1 | Mg O 2 | 1.0000000000000000 3 | 4.2004725253589212 0.0000000000000000 0.0000000000000000 4 | 0.0000000000000000 4.2004725253589212 0.0462051977789481 5 | 0.0000000000000000 0.0000000000000000 4.2004725253589212 6 | Mg O 7 | 4 4 8 | Direct 9 | 0.0000000000000000 0.0000000000000000 0.0000000000000000 10 | 0.0000000000000000 0.5000000000000000 0.5000000000000000 11 | 0.5000000000000000 0.0000000000000000 0.5000000000000000 12 | 0.5000000000000000 0.5000000000000000 0.0000000000000000 13 | 0.5000000000000000 0.5000000000000000 0.5000000000000000 14 | 0.5000000000000000 0.0000000000000000 0.0000000000000000 15 | 0.0000000000000000 0.5000000000000000 0.0000000000000000 16 | 0.0000000000000000 0.0000000000000000 0.5000000000000000 17 | -------------------------------------------------------------------------------- /tests/data/cij_009.POSCAR: -------------------------------------------------------------------------------- 1 | Mg O 2 | 1.0000000000000000 3 | 4.2004725253589212 0.0000000000000000 0.0000000000000000 4 | 0.0000000000000000 4.2004725253589212 0.0651073241430633 5 | 0.0000000000000000 0.0000000000000000 4.2004725253589212 6 | Mg O 7 | 4 4 8 | Direct 9 | 0.0000000000000000 0.0000000000000000 0.0000000000000000 10 | 0.0000000000000000 0.5000000000000000 0.5000000000000000 11 | 0.5000000000000000 0.0000000000000000 0.5000000000000000 12 | 0.5000000000000000 0.5000000000000000 0.0000000000000000 13 | 0.5000000000000000 0.5000000000000000 0.5000000000000000 14 | 0.5000000000000000 0.0000000000000000 0.0000000000000000 15 | 0.0000000000000000 0.5000000000000000 0.0000000000000000 16 | 0.0000000000000000 0.0000000000000000 0.5000000000000000 17 | -------------------------------------------------------------------------------- /tests/data/cij_010.POSCAR: -------------------------------------------------------------------------------- 1 | Mg O 2 | 1.0000000000000000 3 | 4.2004725253589212 0.0000000000000000 0.0000000000000000 4 | 0.0000000000000000 4.2004725253589212 0.0840094505071784 5 | 0.0000000000000000 0.0000000000000000 4.2004725253589212 6 | Mg O 7 | 4 4 8 | Direct 9 | 0.0000000000000000 0.0000000000000000 0.0000000000000000 10 | 0.0000000000000000 0.5000000000000000 0.5000000000000000 11 | 0.5000000000000000 0.0000000000000000 0.5000000000000000 12 | 0.5000000000000000 0.5000000000000000 0.0000000000000000 13 | 0.5000000000000000 0.5000000000000000 0.5000000000000000 14 | 0.5000000000000000 0.0000000000000000 0.0000000000000000 15 | 0.0000000000000000 0.5000000000000000 0.0000000000000000 16 | 0.0000000000000000 0.0000000000000000 0.5000000000000000 17 | -------------------------------------------------------------------------------- /tests/data/eos_000.POSCAR: -------------------------------------------------------------------------------- 1 | Mg O 2 | 1.0000000000000000 3 | 4.2004725253589212 0.0000000000000000 0.0000000000000000 4 | 0.0000000000000000 4.2004725253589212 0.0000000000000000 5 | 0.0000000000000000 0.0000000000000000 4.2004725253589212 6 | Mg O 7 | 4 4 8 | Direct 9 | 0.0000000000000000 0.0000000000000000 0.0000000000000000 10 | 0.0000000000000000 0.5000000000000000 0.5000000000000000 11 | 0.5000000000000000 0.0000000000000000 0.5000000000000000 12 | 0.5000000000000000 0.5000000000000000 0.0000000000000000 13 | 0.5000000000000000 0.5000000000000000 0.5000000000000000 14 | 0.5000000000000000 0.0000000000000000 0.0000000000000000 15 | 0.0000000000000000 0.5000000000000000 0.0000000000000000 16 | 0.0000000000000000 0.0000000000000000 0.5000000000000000 17 | -------------------------------------------------------------------------------- /tests/data/eos_001.POSCAR: -------------------------------------------------------------------------------- 1 | Mg O 2 | 1.0000000000000000 3 | 4.1722805851451596 0.0000000000000000 0.0000000000000000 4 | 0.0000000000000000 4.1722805851451596 0.0000000000000000 5 | 0.0000000000000000 0.0000000000000000 4.1722805851451596 6 | Mg O 7 | 4 4 8 | Direct 9 | 0.0000000000000000 0.0000000000000000 0.0000000000000000 10 | 0.0000000000000000 0.5000000000000000 0.5000000000000000 11 | 0.5000000000000000 0.0000000000000000 0.5000000000000000 12 | 0.5000000000000000 0.5000000000000000 0.0000000000000000 13 | 0.5000000000000000 0.5000000000000000 0.5000000000000000 14 | 0.5000000000000000 0.0000000000000000 0.0000000000000000 15 | 0.0000000000000000 0.5000000000000000 0.0000000000000000 16 | 0.0000000000000000 0.0000000000000000 0.5000000000000000 17 | -------------------------------------------------------------------------------- /tests/data/eos_002.POSCAR: -------------------------------------------------------------------------------- 1 | Mg O 2 | 1.0000000000000000 3 | 4.1864240173276501 0.0000000000000000 0.0000000000000000 4 | 0.0000000000000000 4.1864240173276501 0.0000000000000000 5 | 0.0000000000000000 0.0000000000000000 4.1864240173276501 6 | Mg O 7 | 4 4 8 | Direct 9 | 0.0000000000000000 0.0000000000000000 0.0000000000000000 10 | 0.0000000000000000 0.5000000000000000 0.5000000000000000 11 | 0.5000000000000000 0.0000000000000000 0.5000000000000000 12 | 0.5000000000000000 0.5000000000000000 0.0000000000000000 13 | 0.5000000000000000 0.5000000000000000 0.5000000000000000 14 | 0.5000000000000000 0.0000000000000000 0.0000000000000000 15 | 0.0000000000000000 0.5000000000000000 0.0000000000000000 16 | 0.0000000000000000 0.0000000000000000 0.5000000000000000 17 | -------------------------------------------------------------------------------- /tests/data/eos_003.POSCAR: -------------------------------------------------------------------------------- 1 | Mg O 2 | 1.0000000000000000 3 | 4.2004725253589212 0.0000000000000000 0.0000000000000000 4 | 0.0000000000000000 4.2004725253589212 0.0000000000000000 5 | 0.0000000000000000 0.0000000000000000 4.2004725253589212 6 | Mg O 7 | 4 4 8 | Direct 9 | 0.0000000000000000 0.0000000000000000 0.0000000000000000 10 | 0.0000000000000000 0.5000000000000000 0.5000000000000000 11 | 0.5000000000000000 0.0000000000000000 0.5000000000000000 12 | 0.5000000000000000 0.5000000000000000 0.0000000000000000 13 | 0.5000000000000000 0.5000000000000000 0.5000000000000000 14 | 0.5000000000000000 0.0000000000000000 0.0000000000000000 15 | 0.0000000000000000 0.5000000000000000 0.0000000000000000 16 | 0.0000000000000000 0.0000000000000000 0.5000000000000000 17 | -------------------------------------------------------------------------------- /tests/data/eos_004.POSCAR: -------------------------------------------------------------------------------- 1 | Mg O 2 | 1.0000000000000000 3 | 4.2144276860989187 0.0000000000000000 0.0000000000000000 4 | 0.0000000000000000 4.2144276860989187 0.0000000000000000 5 | 0.0000000000000000 0.0000000000000000 4.2144276860989187 6 | Mg O 7 | 4 4 8 | Direct 9 | 0.0000000000000000 0.0000000000000000 0.0000000000000000 10 | 0.0000000000000000 0.5000000000000000 0.5000000000000000 11 | 0.5000000000000000 0.0000000000000000 0.5000000000000000 12 | 0.5000000000000000 0.5000000000000000 0.0000000000000000 13 | 0.5000000000000000 0.5000000000000000 0.5000000000000000 14 | 0.5000000000000000 0.0000000000000000 0.0000000000000000 15 | 0.0000000000000000 0.5000000000000000 0.0000000000000000 16 | 0.0000000000000000 0.0000000000000000 0.5000000000000000 17 | -------------------------------------------------------------------------------- /tests/data/eos_005.POSCAR: -------------------------------------------------------------------------------- 1 | Mg O 2 | 1.0000000000000000 3 | 4.2282910349096081 0.0000000000000000 0.0000000000000000 4 | 0.0000000000000000 4.2282910349096081 0.0000000000000000 5 | 0.0000000000000000 0.0000000000000000 4.2282910349096081 6 | Mg O 7 | 4 4 8 | Direct 9 | 0.0000000000000000 0.0000000000000000 0.0000000000000000 10 | 0.0000000000000000 0.5000000000000000 0.5000000000000000 11 | 0.5000000000000000 0.0000000000000000 0.5000000000000000 12 | 0.5000000000000000 0.5000000000000000 0.0000000000000000 13 | 0.5000000000000000 0.5000000000000000 0.5000000000000000 14 | 0.5000000000000000 0.0000000000000000 0.0000000000000000 15 | 0.0000000000000000 0.5000000000000000 0.0000000000000000 16 | 0.0000000000000000 0.0000000000000000 0.5000000000000000 17 | -------------------------------------------------------------------------------- /tests/data/run-calcs: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Command to run vasp in current directory 4 | RUN_VASP="run-on-tsi /opt/bin/run-vasp541" 5 | 6 | for s in $* ; do 7 | d=${s%%.POSCAR} 8 | echo -n $d ": " 9 | mkdir calc-$d 10 | ( 11 | cd calc-$d 12 | ln -s ../INCAR ../KPOINTS ../POTCAR ../vasprun.conf . 13 | ln -s ../$s POSCAR 14 | $RUN_VASP 15 | ) 16 | done 17 | -------------------------------------------------------------------------------- /tests/runtest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | mkdir tmp 4 | cd tmp 5 | ln -s ../parcalc ../elastic ../test_*.py . 6 | 7 | if [ ".$1" = "." ] ; then 8 | for t in test_*.py ; do 9 | python $t 10 | done 11 | else 12 | python test_$1.py 13 | fi 14 | 15 | cd .. 16 | rm -rf tmp 17 | 18 | -------------------------------------------------------------------------------- /tests/test_01.py: -------------------------------------------------------------------------------- 1 | # Test case for the code. Calculate few well-known crystals 2 | 3 | from __future__ import print_function, division 4 | 5 | import os 6 | import sys 7 | from numpy import linspace, array, arange 8 | import numpy 9 | from math import pow 10 | 11 | from matplotlib.pyplot import plot, show, figure, draw, axvline, axhline 12 | from pylab import * 13 | 14 | from ase.lattice.spacegroup import crystal 15 | from ase.visualize import view 16 | from ase.units import GPa 17 | 18 | import elastic 19 | from parcalc import ParCalculate, ClusterVasp 20 | from elastic import BMEOS 21 | 22 | def banner(msg): 23 | print() 24 | print(60*'=') 25 | print(max(0,(60-len(msg))//2-1)*' ',msg) 26 | print(60*'=') 27 | 28 | def secban(msg): 29 | print() 30 | print(max(0,(60-len(msg))//2-1)*' ',msg) 31 | print(60*'-') 32 | 33 | 34 | banner('Structure optimization on MgO') 35 | 36 | a = 4.291 37 | MgO = crystal(['Mg', 'O'], [(0, 0, 0), (0.5, 0.5, 0.5)], spacegroup=225, 38 | cellpar=[a, a, a, 90, 90, 90]) 39 | 40 | ################################## 41 | # Provide your own calculator here 42 | ################################## 43 | calc=ClusterVasp(nodes=1,ppn=8) 44 | # The calculator must be runnable in an isolated directory 45 | # Without disturbing other running instances of the same calculator 46 | # They are run in separate processes (not threads!) 47 | 48 | MgO.set_calculator(calc) 49 | calc.set(prec = 'Accurate', xc = 'PBE', lreal = False, isif=2, nsw=20, ibrion=2, kpts=[1,1,1]) 50 | 51 | print("Residual pressure: %.3f GPa" % (MgO.get_pressure()/GPa)) 52 | calc.clean() 53 | 54 | banner('Volume scan on MgO (+/- 5%)') 55 | 56 | systems=[] 57 | for av in numpy.linspace(a*0.95,a*1.05,5): 58 | systems.append(crystal(['Mg', 'O'], [(0, 0, 0), (0.5, 0.5, 0.5)], spacegroup=225, 59 | cellpar=[av, av, av, 90, 90, 90])) 60 | 61 | pcalc=ClusterVasp(nodes=1,ppn=8) 62 | pcalc.set(prec = 'Accurate', xc = 'PBE', lreal = False, isif=2, nsw=20, ibrion=2, kpts=[1,1,1]) 63 | res=ParCalculate(systems,pcalc) 64 | 65 | v=[] 66 | p=[] 67 | for s in res : 68 | v.append(s.get_volume()) 69 | p.append(s.get_pressure()/GPa) 70 | 71 | plot(v,p,'o') 72 | show() 73 | 74 | 75 | 76 | # You can specify the directory with prepared VASP crystal for the test run 77 | # or run through all prepared cases. 78 | if len(sys.argv)>1 : 79 | crystals=[crystal(ase.io.read(sys.argv[1]+'/CONTCAR'))] 80 | else : 81 | # Pre-cooked test cases 82 | crystals=[] 83 | 84 | # Cubic 85 | a = 4.194 86 | crystals.append(crystal(['Mg', 'O'], [(0, 0, 0), (0.5, 0.5, 0.5)], 87 | spacegroup=225, cellpar=[a, a, a, 90, 90, 90])) 88 | # a = 4.194 89 | # crystals.append(Crystal(crystal(['Ti', 'C'], [(0, 0, 0), (0.5, 0.5, 0.5)], 90 | # spacegroup=225, cellpar=[a, a, a, 90, 90, 90]))) 91 | # Tetragonal 92 | a = 4.60 93 | c = 2.96 94 | crystals.append(crystal(['Ti', 'O'], [(0, 0, 0), (0.302, 0.302, 0)], 95 | spacegroup=136, cellpar=[a, a, c, 90, 90, 90])) 96 | # Trigonal (this is metal - for sure the k spacing will be too small) 97 | a = 4.48 98 | c = 11.04 99 | crystals.append(crystal(['Sb'], [(0, 0, 0.24098)], 100 | spacegroup=166, cellpar=[a, a, c, 90, 90, 120])) 101 | 102 | 103 | banner("Running tests for Elastic") 104 | # Iterate over all crystals. 105 | # We do not paralelize over test cases for clarity. 106 | for cryst in crystals[:] : 107 | 108 | cryst.get_lattice_type() 109 | banner('Calculating: %s, %s, %s' % 110 | (cryst.get_chemical_formula(), cryst.bravais, cryst.sg_name)) 111 | # Setup the calculator 112 | calc=ClusterVasp(nodes=1,ppn=8) 113 | cryst.set_calculator(calc) 114 | calc.set(prec = 'Accurate', 115 | xc = 'PBE', 116 | lreal = False, 117 | isif=4, 118 | nsw=30, 119 | ediff=1e-8, 120 | ibrion=2) 121 | calc.set(kpts=[3,3,3]) 122 | 123 | # Run the calculations 124 | 125 | # Optimize the structure first 126 | calc.set(isif=3) 127 | 128 | secban('Structure optimization') 129 | 130 | # Run the internal optimizer 131 | print("Residual pressure: %.3f GPa" % ( 132 | cryst.get_pressure()/GPa)) 133 | print("Residual stress (GPa):", cryst.get_stress()/GPa) 134 | 135 | calc.clean() 136 | cryst.get_lattice_type() 137 | 138 | secban('Lattice parameters') 139 | 140 | print(cryst.get_vecang_cell()) 141 | print(cryst.bravais, cryst.sg_type, cryst.sg_name, cryst.sg_nr) 142 | 143 | #view(cryst) 144 | 145 | # Switch to cell shape+IDOF optimizer 146 | calc.set(isif=4) 147 | 148 | secban('Birch-Murnaghan EOS') 149 | 150 | # Calculate few volumes and fit B-M EOS to the result 151 | # Use +/-3% volume deformation and 5 data points 152 | fit=cryst.get_BM_EOS(n=5,lo=0.97,hi=1.03) 153 | 154 | # Get the P(V) data points just calculated 155 | pv=array(cryst.pv) 156 | 157 | # Sort data on the first column (V) 158 | pv=pv[pv[:,0].argsort()] 159 | 160 | # Print the fitted parameters 161 | print("V0=%.3f A^3 ; B0=%.2f GPa ; B0'=%.3f ; a0=%.5f A" % ( 162 | fit[0], fit[1]/GPa, fit[2], pow(fit[0],1./3))) 163 | 164 | v0=fit[0] 165 | 166 | # B-M EOS for plotting 167 | fitfunc = lambda p, x: [BMEOS(xv,p[0],p[1],p[2]) for xv in x] 168 | 169 | # Ranges - the ordering in pv is not guarateed at all! 170 | # In fact it may be purely random. 171 | x=array([min(pv[:,0]),max(pv[:,0])]) 172 | y=array([min(pv[:,1]),max(pv[:,1])]) 173 | 174 | 175 | # Plot b/a and c/a as a function of v/v0 176 | figure(1) 177 | plot(pv[:,0]/v0,pv[:,3]/pv[:,2],'o') 178 | plot(pv[:,0]/v0,pv[:,4]/pv[:,2],'x-') 179 | #print(pv[:,4]/pv[:,2]) 180 | axvline(1,ls='--') 181 | title('b/a and c/a as a function of v/v0') 182 | draw() 183 | 184 | # Plot the P(V) curves and points for the crystal 185 | figure(2) 186 | # Plot the points 187 | plot(pv[:,0]/v0,pv[:,1],'o') 188 | 189 | # Mark the center P=0 V=V0 190 | axvline(1,ls='--') 191 | axhline(0,ls='--') 192 | 193 | # Plot the fitted B-M EOS through the points 194 | xa=linspace(x[0],x[-1],20) 195 | #xa=v0*linspace(0.90,1.10,20) 196 | plot(xa/v0,fitfunc(fit,xa),'-') 197 | title('Birch-Murnaghan Equation of state') 198 | draw() 199 | 200 | # Scan over deformations 201 | 202 | # Switch to IDOF optimizer 203 | calc.set(isif=2) 204 | 205 | secban('Elastic tensor by internal routine') 206 | 207 | # Elastic tensor by internal routine 208 | Cij, Bij=cryst.get_elastic_tensor(n=5,d=0.33) 209 | print("Cij (GPa):", Cij/GPa) 210 | 211 | calc.clean() 212 | 213 | secban('C11 and C12 by hand') 214 | 215 | # Now let us do it (only c11 and c12) by hand 216 | sys=[] 217 | for d in linspace(-0.5,0.5,6): 218 | sys.append(cryst.get_cart_deformed_cell(axis=0,size=d)) 219 | r=ParCalculate(sys,cryst.calc) 220 | ss=[] 221 | for s in r: 222 | ss.append([s.get_strain(cryst), s.get_stress()]) 223 | # Plot strain-stress relation 224 | figure(3) 225 | 226 | ss=[] 227 | for p in r: 228 | ss.append([p.get_strain(cryst),p.get_stress()]) 229 | ss=array(ss) 230 | lo=min(ss[:,0,0]) 231 | hi=max(ss[:,0,0]) 232 | mi=(lo+hi)/2 233 | wi=(hi-lo)/2 234 | xa=linspace(mi-1.1*wi,mi+1.1*wi, 50) 235 | plot(ss[:,0,0],ss[:,1,0],'k.') 236 | plot(ss[:,0,0],ss[:,1,1],'r.') 237 | 238 | # C11 component 239 | f=numpy.polyfit(ss[:,0,0],ss[:,1,0],3) 240 | c11=f[-2]/GPa 241 | plot(xa,numpy.polyval(f,xa),'b-') 242 | 243 | # C12 component 244 | f=numpy.polyfit(ss[:,0,0],ss[:,1,1],3) 245 | c12=f[-2]/GPa 246 | plot(xa,numpy.polyval(f,xa),'g-') 247 | print('C11 = %.3f GPa, C12 = %.3f GPa => K= %.3f GPa (cubic only)' % (c11, c12, (c11+2*c12)/3)) 248 | axvline(0,ls='--') 249 | axhline(0,ls='--') 250 | title('C11, C12 manual fits') 251 | draw() 252 | 253 | # # Now make a short scan over pressures 254 | # 255 | # # Switch just shape+IDOF optimization 256 | # calc.set(isif=4) 257 | # sys=[] 258 | # sys=cryst.scan_pressures(-5.0, 5.0, 3) 259 | # r=ParCalculate(sys,cryst.calc) 260 | # print("Pressure scan (GPa):",end=" ") 261 | # for s in r : 262 | # print(cryst.get_pressure(s.get_stress())/GPa, end=" ") 263 | # print() 264 | # vl=array([s.get_volume() for s in r]) 265 | # pl=array([cryst.get_pressure(s.get_stress())/GPa for s in r]) 266 | # figure(2) 267 | # plot(vl/v0,pl,'+') 268 | # 269 | # # Check for proper inverse eos 270 | # invbmeos = lambda b, bp, x: array([pow(b/(bp*xv+b),1/bp) for xv in x]) 271 | # xa=linspace(max(-8,-0.9*fit[1]/fit[2]),8,20) 272 | # ya=invbmeos(fit[1],fit[2],xa) 273 | # plot(ya,xa,'-') 274 | 275 | banner('Tests finished, showing plots') 276 | 277 | show() 278 | 279 | 280 | 281 | -------------------------------------------------------------------------------- /tests/test_02.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from __future__ import division, print_function 3 | 4 | from ase import Atom, Atoms 5 | from parcalc import ParCalculate, ClusterVasp 6 | import elastic 7 | from ase import io 8 | from ase.lattice.spacegroup import crystal 9 | from pyspglib import spglib 10 | from time import sleep 11 | import os, sys 12 | 13 | def wait_for_results(systems): 14 | for n,r in enumerate(systems): 15 | print(n+1,end='') 16 | while not r.get_calculator().calc_finished() : 17 | print('.',end='') 18 | sys.stdout.flush() 19 | sleep(10) 20 | print(end=' ') 21 | sys.stdout.flush() 22 | print() 23 | 24 | 25 | a=4 ; c=crystal('Si',[(0,0,0)],spacegroup=221,cellpar=[a,a,a,90,90,90]) 26 | spglib.get_spacegroup(c) 27 | 28 | block=False 29 | 30 | calc = ClusterVasp(block=block) 31 | 32 | calc.set(prec = 'Accurate', xc = 'PBE', lreal = False, 33 | nsw=30, ediff=1e-8, ibrion=2, kpts=[3,3,3]) 34 | 35 | calc.set(isif=3) 36 | 37 | c.set_calculator(calc) 38 | 39 | l=ParCalculate(c,calc,cleanup=False,block=block) 40 | 41 | s = l[0] 42 | 43 | wait_for_results(l) 44 | 45 | print(s.get_forces(), s.get_cell(), s.get_stress(), s.get_pressure()) 46 | 47 | calc.set(isif=2) 48 | sl=s.get_BM_EOS(mode='gener') 49 | res=ParCalculate(sl,calc,block=block,prefix='BMEOS_') 50 | 51 | wait_for_results(res) 52 | 53 | print(s.get_BM_EOS(data=res)) 54 | 55 | deformations=s.get_elastic_tensor(mode='deformations') 56 | results=ParCalculate(deformations,calc,block=block,prefix='Cij_') 57 | 58 | wait_for_results(results) 59 | 60 | Cij,Bij=s.get_elastic_tensor(mode='restart',systems=results) 61 | 62 | print(Cij) 63 | 64 | -------------------------------------------------------------------------------- /tests/test_elastic.py: -------------------------------------------------------------------------------- 1 | #============================================= 2 | # Test cases for module 3 | #============================================= 4 | 5 | if __name__ == '__main__': 6 | # Test case for the code. Calculate few well-known crystals 7 | 8 | import sys 9 | import numpy 10 | from math import pow 11 | 12 | from matplotlib.pyplot import plot, show, figure, draw, axvline, axhline 13 | from ase.lattice.spacegroup import crystal 14 | import ase.units as units 15 | from parcalc import ClusterVasp 16 | import elastic 17 | from elastic import Crystal, BMEOS 18 | from parcalc import ClusterVasp, ClusterSiesta, ParCalculate 19 | 20 | # You can specify the directory with prepared VASP crystal for the test run 21 | # or run through all prepared cases. 22 | if len(sys.argv)>1 : 23 | crystals=[crystal(ase.io.read(sys.argv[1]+'/CONTCAR'))] 24 | else : 25 | # Pre-cooked test cases 26 | crystals=[] 27 | 28 | # Cubic 29 | a = 4.194 30 | crystals.append(crystal(['Mg', 'O'], [(0, 0, 0), (0.5, 0.5, 0.5)], 31 | spacegroup=225, cellpar=[a, a, a, 90, 90, 90])) 32 | # a = 4.194 33 | # crystals.append(Crystal(crystal(['Ti', 'C'], [(0, 0, 0), (0.5, 0.5, 0.5)], 34 | # spacegroup=225, cellpar=[a, a, a, 90, 90, 90]))) 35 | # Tetragonal 36 | a = 4.60 37 | c = 2.96 38 | crystals.append(Crystal(crystal(['Ti', 'O'], [(0, 0, 0), (0.302, 0.302, 0)], 39 | spacegroup=136, cellpar=[a, a, c, 90, 90, 90]))) 40 | # Trigonal (this is metal - for sure the k spacing will be too small) 41 | a = 4.48 42 | c = 11.04 43 | crystals.append(Crystal(crystal(['Sb'], [(0, 0, 0.24098)], 44 | spacegroup=166, cellpar=[a, a, c, 90, 90, 120]))) 45 | 46 | 47 | print("Running tests") 48 | # Iterate over all crystals. 49 | # We do not paralelize over test cases for clarity. 50 | for cryst in crystals[:] : 51 | 52 | 53 | # Setup the calculator 54 | calc=ClusterVasp(nodes=1,ppn=8) 55 | cryst.set_calculator(calc) 56 | calc.set(prec = 'Accurate', 57 | xc = 'PBE', 58 | lreal = False, 59 | isif=4, 60 | nsw=30, 61 | ediff=1e-8, 62 | ibrion=2) 63 | calc.set(kpts=[3,3,3]) 64 | 65 | # Run the calculations 66 | 67 | # Optimize the structure first 68 | calc.set(isif=3) 69 | 70 | # Run the internal optimizer 71 | print("Residual pressure: %.3f GPa" % ( 72 | (cryst.get_stress()[:3]).mean()/units.GPa)) 73 | print("Residual stress (GPa):", cryst.get_stress()/units.GPa) 74 | 75 | calc.clean() 76 | cryst.get_lattice_type() 77 | 78 | print(cryst.get_vecang_cell()) 79 | print(cryst.bravais, cryst.sg_type, cryst.sg_name, cryst.sg_nr) 80 | 81 | #view(cryst) 82 | 83 | # Switch to cell shape+IDOF optimizer 84 | calc.set(isif=4) 85 | 86 | # Calculate few volumes and fit B-M EOS to the result 87 | # Use +/-3% volume deformation and 5 data points 88 | fit=cryst.get_BM_EOS(n=5,lo=0.97,hi=1.03) 89 | 90 | # Get the P(V) data points just calculated 91 | pv=array(cryst.pv) 92 | 93 | # Sort data on the first column (V) 94 | pv=pv[pv[:,0].argsort()] 95 | 96 | # Print the fitted parameters 97 | print("V0=%.3f A^3 ; B0=%.2f GPa ; B0'=%.3f ; a0=%.5f A" % ( 98 | fit[0], fit[1]/units.GPa, fit[2], pow(fit[0],1./3))) 99 | 100 | v0=fit[0] 101 | 102 | # B-M EOS for plotting 103 | fitfunc = lambda p, x: [BMEOS(xv,p[0],p[1],p[2]) for xv in x] 104 | 105 | # Ranges - the ordering in pv is not guarateed at all! 106 | # In fact it may be purely random. 107 | x=array([min(pv[:,0]),max(pv[:,0])]) 108 | y=array([min(pv[:,1]),max(pv[:,1])]) 109 | 110 | 111 | # Plot b/a and c/a as a function of v/v0 112 | figure(1) 113 | plot(pv[:,0]/v0,pv[:,3]/pv[:,2],'o') 114 | plot(pv[:,0]/v0,pv[:,4]/pv[:,2],'x-') 115 | #print(pv[:,4]/pv[:,2]) 116 | axvline(1,ls='--') 117 | draw() 118 | 119 | # Plot the P(V) curves and points for the crystal 120 | figure(2) 121 | # Plot the points 122 | plot(pv[:,0]/v0,pv[:,1],'o') 123 | 124 | # Mark the center P=0 V=V0 125 | axvline(1,ls='--') 126 | axhline(0,ls='--') 127 | 128 | # Plot the fitted B-M EOS through the points 129 | xa=linspace(x[0],x[-1],20) 130 | #xa=v0*linspace(0.90,1.10,20) 131 | plot(xa/v0,fitfunc(fit,xa),'-') 132 | draw() 133 | 134 | # Scan over deformations 135 | 136 | # Switch to IDOF optimizer 137 | calc.set(isif=2) 138 | 139 | # Elastic tensor by internal routine 140 | Cij, Bij=cryst.get_elastic_tensor(n=5,d=0.33) 141 | print("Cij (GPa):", Cij/units.GPa) 142 | 143 | calc.clean() 144 | 145 | # Now let us do it (only c11 and c12) by hand 146 | sys=[] 147 | for d in linspace(-0.5,0.5,6): 148 | sys.append(cryst.get_cart_deformed_cell(axis=0,size=d)) 149 | r=ParCalculate(sys,cryst.get_calculator()) 150 | ss=[] 151 | for s in r: 152 | ss.append([s.get_strain(cryst), s.get_stress()]) 153 | # Plot strain-stress relation 154 | figure(3) 155 | 156 | ss=[] 157 | for p in r: 158 | ss.append([p.get_strain(cryst),p.get_stress()]) 159 | ss=array(ss) 160 | lo=min(ss[:,0,0]) 161 | hi=max(ss[:,0,0]) 162 | mi=(lo+hi)/2 163 | wi=(hi-lo)/2 164 | xa=linspace(mi-1.1*wi,mi+1.1*wi, 50) 165 | plot(ss[:,0,0],ss[:,1,0],'k.') 166 | plot(ss[:,0,0],ss[:,1,1],'r.') 167 | 168 | # C11 component 169 | f=numpy.polyfit(ss[:,0,0],ss[:,1,0],3) 170 | c11=f[-2]/units.GPa 171 | plot(xa,numpy.polyval(f,xa),'b-') 172 | 173 | # C12 component 174 | f=numpy.polyfit(ss[:,0,0],ss[:,1,1],3) 175 | c12=f[-2]/units.GPa 176 | plot(xa,numpy.polyval(f,xa),'g-') 177 | print('C11 = %.3f GPa, C12 = %.3f GPa => K= %.3f GPa (cubic only)' % (c11, c12, (c11+2*c12)/3)) 178 | axvline(0,ls='--') 179 | axhline(0,ls='--') 180 | draw() 181 | 182 | # # Now make a short scan over pressures 183 | # 184 | # # Switch just shape+IDOF optimization 185 | # calc.set(isif=4) 186 | # sys=[] 187 | # sys=cryst.scan_pressures(-5.0, 5.0, 3) 188 | # r=ParCalculate(sys,cryst.get_calculator()) 189 | # print("Pressure scan (GPa):",end=" ") 190 | # for s in r : 191 | # print(cryst.get_pressure(s.get_stress())/units.GPa, end=" ") 192 | # print() 193 | # vl=array([s.get_volume() for s in r]) 194 | # pl=array([cryst.get_pressure(s.get_stress())/units.GPa for s in r]) 195 | # figure(2) 196 | # plot(vl/v0,pl,'+') 197 | # 198 | # # Check for proper inverse eos 199 | # invbmeos = lambda b, bp, x: array([pow(b/(bp*xv+b),1/bp) for xv in x]) 200 | # xa=linspace(max(-8,-0.9*fit[1]/fit[2]),8,20) 201 | # ya=invbmeos(fit[1],fit[2],xa) 202 | # plot(ya,xa,'-') 203 | 204 | show() 205 | 206 | 207 | --------------------------------------------------------------------------------