diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml
new file mode 100644
index 00000000..ecc37ea1
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yaml
@@ -0,0 +1,64 @@
+name: Bug Report
+description: Something is not working
+title: "[BUG]"
+labels: [bug]
+body:
+ - type: textarea
+ id: description
+ attributes:
+ label: Description
+ placeholder: |
+ A clear and concise description of what the bug is and what the expected behaviour is.
+ validations:
+ required: true
+ - type: textarea
+ id: reproduction
+ attributes:
+ label: Reproduction steps
+ description: "How do you trigger this bug? If possible, please provide a minimal reproducible example."
+ placeholder: |
+ Does the library compile? Is there an issue with a unit test or example? Or is the bug encountered when calling the library? If possible, provide a step-by-step guide:
+ 1.
+ 2.
+ 3.
+ validations:
+ required: true
+ - type: input
+ id: version
+ attributes:
+ label: Version number
+ description: "What was the latest version (or branch) of RAFFLE is the bug reproducible in?"
+ placeholder: 1.0.0
+ validations:
+ required: true
+ - type: input
+ id: compiler
+ attributes:
+ label: Fortran compiler
+ description: "What Fortran compiler (and version) was used?"
+ placeholder: gfortran version 14.0
+ validations:
+ required: true
+ - type: input
+ id: platform
+ attributes:
+ label: Platform and Architecture
+ description: "What architecture and operating system was the bug encountered on?"
+ placeholder: macOS/ARM 10.14
+ validations:
+ required: true
+ - type: checkboxes
+ id: build
+ attributes:
+ label: Build method
+ description: "What build methods was this issue encountered with?"
+ options:
+ - label: fpm
+ - label: cmake
+ - type: textarea
+ id: additional
+ attributes:
+ label: Additional information
+ placeholder: Any further relevant context, i.e. screenshots, links to other issues, version number of build method.
+ validations:
+ required: false
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml
new file mode 100644
index 00000000..fb167998
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.yaml
@@ -0,0 +1,29 @@
+name: Feature Proposal
+description: Suggest new functionality for RAFFLE
+title: "[PROPOSAL]"
+labels: [enhancement]
+body:
+ - type: textarea
+ id: reasoning
+ attributes:
+ label: Reasoning
+ placeholder: |
+ Provide clear reasoning why the proposed functionality should be added to the RAFFLE library.
+ validations:
+ required: true
+ - type: textarea
+ id: prior_art
+ attributes:
+ label: Prior Art
+ placeholder: |
+ Provide examples of where this has been implemented for machine learning before to help justify its presence in this library.
+ validations:
+ required: false
+ - type: textarea
+ id: additional
+ attributes:
+ label: Additional information
+ placeholder: |
+ Add any other context or screenshots about the feature request here.
+ validations:
+ required: false
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 3c7af6d8..5ad42711 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,7 +15,7 @@ iteration*
doc/html
docs/html
settings.json
-example/example_files/database*
+example/**/database*.xyz
**/POSCAR*
iteration/
*.traj
@@ -31,4 +31,6 @@ fort.*
*.agr
*.pdf
*.eps
-*.pyc
\ No newline at end of file
+*.pyc
+*.xyz
+.coverage
\ No newline at end of file
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
index 243f0cca..f8a9957e 100644
--- a/.readthedocs.yaml
+++ b/.readthedocs.yaml
@@ -17,7 +17,7 @@ build:
# Build documentation in the "docs/" directory with Sphinx
sphinx:
- configuration: docs/conf.py
+ configuration: docs/source/conf.py
# Optionally build your docs in additional formats such as PDF and ePub
# formats:
@@ -27,6 +27,6 @@ sphinx:
# Optional but recommended, declare the Python requirements required
# to build your documentation
# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
-# python:
-# install:
-# - requirements: docs/requirements.txt
\ No newline at end of file
+python:
+ install:
+ - requirements: docs/requirements.txt
\ No newline at end of file
diff --git a/CITATION.cff b/CITATION.cff
new file mode 100644
index 00000000..1d8ceb6d
--- /dev/null
+++ b/CITATION.cff
@@ -0,0 +1,36 @@
+# This CITATION.cff file was generated with cffinit.
+# Visit https://bit.ly/cffinit to generate yours today!
+
+cff-version: 1.2.0
+title: >-
+ RAFFLE: pseudoRandom Approach For Finding Local Energy
+ minima
+message: >-
+ If you use this software, please cite it using the
+ metadata from this file and the following paper:
+ https://link.aps.org/doi/10.1103/PhysRevLett.132.066201
+type: software
+authors:
+ - given-names: Ned Thaddeus
+ family-names: Taylor
+ orcid: 'https://orcid.org/0000-0002-9134-9712'
+ affiliation: University of Exeter
+ - given-names: Joe
+ family-names: Pitfield
+ orcid: 'https://orcid.org/0000-0002-9758-5230'
+ affiliation: Aarhus Universitet
+ - given-names: Steven Paul
+ family-names: Hepplestone
+ orcid: 'https://orcid.org/0000-0002-2528-1270'
+ affiliation: University of Exeter
+repository-code: 'https://github.com/ExeQuantCode/RAFFLE'
+keywords:
+ - materials science
+ - interfaces
+ - material interfaces
+ - structure prediction
+ - random structure search
+license: GPL-3.0
+commit: 4cdf115d5d43d6f97037f6cb15c036dc9615eacb
+version: 0.5.0
+date-released: '2024-12-18'
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a5afac4f..22880291 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -72,6 +72,7 @@ set(LIB_FILES
mod_io_utils.F90
mod_constants.f90
mod_misc.f90
+ mod_tools_infile.f90
mod_misc_maths.f90
mod_misc_linalg.f90
mod_dist_calcs.f90
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 00000000..e52482c9
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,70 @@
+# Code of Conduct - RAFFLE
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as
+contributors and maintainers pledge to make participation in our project and
+our community a harassment-free experience for everyone, regardless of age, body
+size, disability, ethnicity, sex characteristics, gender identity and expression,
+level of experience, education, socio-economic status, nationality, personal
+appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologising to those affected by our mistakes,
+and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the
+overall community
+
+Examples of unacceptable behavior include:
+
+* The use of sexualised language or imagery, and sexual attention or
+advances
+* Trolling, insulting or derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or email
+address, without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, or to ban
+temporarily or permanently any contributor for other behaviors that they deem
+inappropriate, threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement at .
+All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant](https://contributor-covenant.org/), version
+[1.4](https://www.contributor-covenant.org/version/1/4/code-of-conduct/code_of_conduct.md) and
+[2.0](https://www.contributor-covenant.org/version/2/0/code_of_conduct/code_of_conduct.md),
+and was generated by [contributing-gen](https://github.com/bttger/contributing-gen).
diff --git a/README.md b/README.md
index d3289627..0b879da6 100644
--- a/README.md
+++ b/README.md
@@ -1,25 +1,34 @@
-
+
-[](https://www.gnu.org/licenses/gpl-3.0.en.html "View GPLv3 license")
-[](https://github.com/nedtaylor/RAFFLE/releases "View on GitHub")
+[](https://www.gnu.org/licenses/gpl-3.0.en.html "View GPLv3 license")
+[](https://github.com/ExeQuantCode/RAFFLE/releases "View on GitHub")
[](https://link.aps.org/doi/10.1103/PhysRevLett.132.066201)
+[](https://raffle-fortran.readthedocs.io/en/latest/?badge=latest "RAFFLE ReadTheDocs")
[](https://github.com/fortran-lang/fpm "View Fortran Package Manager")
[](https://github.com/Kitware/CMake/releases/tag/v3.27.7 "View cmake")
[](https://gcc.gnu.org/gcc-14/ "View GCC")
-[](https://nedtaylor.github.io/RAFFLE/ "View coverage report")
+[](https://ExeQuantCode.github.io/RAFFLE/ "View coverage report")
# RAFFLE
by Ned Thaddeus Taylor, Joe Pitfield, and Steven Paul Hepplestone
-RAFFLE (pseudoRandom Approach For Finding Local Energetic minima) is a package for structural prediction applied to material interfaces. RAFFLE can interface with the [Atomic Simulation Environment (ASE)](https://gitlab.com/ase/ase).
+RAFFLE (pseudoRandom Approach For Finding Local Energetic minima) is a package for structural prediction applied to material interfaces.
+RAFFLE can interface with the [Atomic Simulation Environment (ASE)](https://gitlab.com/ase/ase).
RAFFLE is both a Fortran and a Python library, with the option of a Fortran executable.
The code heavily relies on features of Fortran 2018 and above, so there is no backwards compatibility with Fortran95.
+## Documentation
+
+Tutorials and documentation are provided on the [docs](http://raffle-fortran.readthedocs.io/) website.
+The methodology is detailed in the [Phys Rev B paper](https://link.aps.org/doi/10.1103/PhysRevLett.132.066201).
+The software package will be submitted for publication soon.
+
+
## Requirements
- Fortran compiler supporting Fortran 2018 standard or later
@@ -47,7 +56,7 @@ The library is known to not currently work with the intel Fortran compilers.
To install RAFFLE, the source must be obtained from the git repository. Use the following commands to get started:
```
- git clone https://github.com/nedtaylor/raffle.git
+ git clone https://github.com/ExeQuantCode/raffle.git
cd raffle
```
@@ -167,6 +176,22 @@ It seems that the void finder works. I don't think that scan or pseudo-random wa
-->
+Contributing
+------------
+
+If you have any questions, bug reports, or feature requests, please post then in [issues](https://github.com/ExeQuantCode/RAFFLE/issues).
+
+
+License
+-------
+This work is licensed under a [GPL v3 license]([https://opensource.org/license/mit/](https://www.gnu.org/licenses/gpl-3.0.en.html)).
+
+Code Coverage
+-------------
+
+Automated reporting on unit test code coverage in the README is achieved through utilising the [cmake-modules](https://github.com/rpavlik/cmake-modules) and [dynamic-badges-action](https://github.com/Schneegans/dynamic-badges-action?tab=readme-ov-file) projects.
+
+
## References
If you use this code, please cite our papers:
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 00000000..99abc405
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,20 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line, and also
+# from the environment for the first two.
+SPHINXOPTS ?=
+SPHINXBUILD ?= python -m sphinx
+SOURCEDIR = source
+BUILDDIR = build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/make.bat b/docs/make.bat
new file mode 100644
index 00000000..747ffb7b
--- /dev/null
+++ b/docs/make.bat
@@ -0,0 +1,35 @@
+@ECHO OFF
+
+pushd %~dp0
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=sphinx-build
+)
+set SOURCEDIR=source
+set BUILDDIR=build
+
+%SPHINXBUILD% >NUL 2>NUL
+if errorlevel 9009 (
+ echo.
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+ echo.installed, then set the SPHINXBUILD environment variable to point
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
+ echo.may add the Sphinx directory to PATH.
+ echo.
+ echo.If you don't have Sphinx installed, grab it from
+ echo.https://www.sphinx-doc.org/
+ exit /b 1
+)
+
+if "%1" == "" goto help
+
+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+goto end
+
+:help
+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+
+:end
+popd
diff --git a/docs/requirements.txt b/docs/requirements.txt
new file mode 100644
index 00000000..1d628f2b
--- /dev/null
+++ b/docs/requirements.txt
@@ -0,0 +1,2 @@
+sphinx==7.1.2
+sphinx-rtd-theme==1.3.0rc1
\ No newline at end of file
diff --git a/docs/RAFFLE_logo.pdf b/docs/source/RAFFLE_logo.pdf
similarity index 100%
rename from docs/RAFFLE_logo.pdf
rename to docs/source/RAFFLE_logo.pdf
diff --git a/docs/RAFFLE_logo_no_background.png b/docs/source/RAFFLE_logo_no_background.png
similarity index 100%
rename from docs/RAFFLE_logo_no_background.png
rename to docs/source/RAFFLE_logo_no_background.png
diff --git a/docs/source/about.rst b/docs/source/about.rst
new file mode 100644
index 00000000..e2da12e7
--- /dev/null
+++ b/docs/source/about.rst
@@ -0,0 +1,15 @@
+.. _about:
+
+=====
+About
+=====
+
+
+RAFFLE (pseudoRandom Approach For Finding Local Energetic minima) is a package for structural prediction applied to material interfaces.
+RAFFLE can interface with the `Atomic Simulation Environment (ASE) `_.
+
+RAFFLE is both a Fortran and a Python library, with the option of a Fortran executable.
+The code heavily relies on features of Fortran 2018 and above, so there is no backwards compatibility with Fortran95.
+
+The library enables users to fill a host structure with additional atoms, where placement of those atoms is determined by a set of placement methods.
+These methods are meant to bias towards energetically favourable configurations, whilst still providing a thorough search of the configuration space.
\ No newline at end of file
diff --git a/docs/source/conf.py b/docs/source/conf.py
new file mode 100644
index 00000000..e465c946
--- /dev/null
+++ b/docs/source/conf.py
@@ -0,0 +1,81 @@
+# Configuration file for the Sphinx documentation builder.
+
+# -- Project information
+import datetime
+import os
+import sys
+
+from unittest.mock import Mock
+
+MOCK_MODULES = ["raffle._raffle"] # List any other modules if needed
+sys.modules.update((mod_name, Mock()) for mod_name in MOCK_MODULES)
+print("LOOK HERE",sys.executable)
+
+sys.path.insert(0, os.path.abspath(os.path.join('..', '..', 'src', 'raffle'))) # Sets the base path to find your modules
+
+project = 'RAFFLE'
+copyright = f'{datetime.date.today().year}, RAFFLE-developers'
+# release = '1.0'
+# version = '1.0.0'
+
+# -- General configuration
+master_doc = 'index'
+
+extensions = [
+ 'sphinx.ext.duration',
+ 'sphinx.ext.doctest',
+ 'sphinx.ext.autodoc',
+ 'sphinx.ext.autosummary',
+ 'sphinx.ext.intersphinx',
+ 'sphinx.ext.napoleon',
+ 'sphinx.ext.viewcode',
+ 'sphinx_rtd_theme',
+]
+
+intersphinx_mapping = {
+ 'python': ('https://docs.python.org/3/', None),
+ 'sphinx': ('https://www.sphinx-doc.org/en/master/', None),
+}
+intersphinx_disabled_domains = ['std']
+
+templates_path = ['_templates']
+
+exclude_patterns = ['_build', '.DS_Store', 'build']
+
+
+# -- Options for HTML output
+
+html_theme = 'sphinx_rtd_theme'
+
+# -- Options for EPUB output
+epub_show_urls = 'footnote'
+
+html_logo = "RAFFLE_logo_no_background.png"
+# html_favicon = 'favicon.ico'
+html_theme_options = {
+ 'logo_only': False,
+ 'prev_next_buttons_location': 'bottom',
+ 'style_external_links': False,
+ 'vcs_pageview_mode': '',
+ # 'style_nav_header_background': 'white',
+ 'flyout_display': 'hidden',
+ 'version_selector': True,
+ 'language_selector': True,
+ # Toc options
+ 'collapse_navigation': True,
+ 'sticky_navigation': True,
+ 'navigation_depth': 4,
+ 'includehidden': True,
+ 'titles_only': False,
+}
+
+
+html_context = {
+ "display_github": True,
+ "github_repo": "RAFFLE",
+ "github_user": "ExeQuantCode",
+ "github_version": "development",
+ "conf_py_path": "/docs/source",
+}
+
+autoclass_content="both"
diff --git a/docs/source/index.rst b/docs/source/index.rst
new file mode 100644
index 00000000..ece019a2
--- /dev/null
+++ b/docs/source/index.rst
@@ -0,0 +1,58 @@
+======
+RAFFLE
+======
+
+RAFFLE (pseudoRandom Approach For Finding Local Energetic minima) is a Python and Fortran package for structure prediction applied to interfaces.
+RAFFLE can be utilised as a Python package, a Fortran library, or a standalone Fortran executable.
+The Python package provides a high-level interface to the Fortran library, which contains the core functionality.
+
+The Python package interfaces seemlessly with `ASE (Atomic Simulation Environment) `_, allowing for easy reading, writing, and manipulation of atomic structures.
+Although the package comes with a built-in atomic structure reader and writer, it is recommended to use ASE due to its greater functionality and wide-reaching support.
+
+The code is provided freely available under the `GNU General Public License v3.0 `_.
+
+An example
+
+.. code-block:: python
+
+ # A simple example of how to use RAFFLE to generate 10 structures of diamond
+ from ase import Atoms
+ from raffle.generator import raffle_generator
+ from mace.calculators import mace_mp
+
+ generator = raffle_generator()
+
+ calc = mace_mp(model="medium", dispersion=False, default_dtype="float32", device='cpu')
+
+ host = Atoms('C', positions=[[0, 0, 0]], cell=[10, 10, 10])
+ host.calc = calc
+ generator.set_host(host)
+
+ generator.distributions.set_element_energies( { 'C': 0.0 } )
+ generator.distributions.create(host)
+
+ num_structures_old = 0
+ for i in range(10):
+ generator.generate(
+ num_structures = 2,
+ stoichiometry = { 'C': 7 }
+ )
+ structures = generator.get_structures(calc)
+ generator.update(structures[num_structures_old:])
+ num_structures_old = len(structures)
+
+.. toctree::
+ :maxdepth: 3
+ :caption: Contents:
+
+ about
+ install
+ tutorials/index
+ Python API
+
+.. Indices and tables
+.. ==================
+
+.. * :ref:`genindex`
+.. * :ref:`modindex`
+.. * :ref:`search`
\ No newline at end of file
diff --git a/docs/source/install.rst b/docs/source/install.rst
new file mode 100644
index 00000000..59d98c0b
--- /dev/null
+++ b/docs/source/install.rst
@@ -0,0 +1,244 @@
+.. _install:
+
+============
+Installation
+============
+
+RAFFLE can be installed in one of three ways; as a Python package, as a Fortran library, or as a standalone Fortran executable.
+All versions rely on the core Fortran code, with the Python package and standalone executable wrapping this code in a Python and Fortran interface, respectively.
+
+.. note::
+ Currently, RAFFLE is not available on any hosted package manager (e.g. PyPI, conda-forge or fpm), so you will need to download it manually from the Git repository.
+
+
+The code is hosted on `GitHub `_.
+
+This can be done by cloning the repository:
+
+.. code-block:: bash
+
+ git clone https://github.com/ExeQuantCode/RAFFLE
+ cd RAFFLE
+
+.. note::
+ Notes on the different versions of RAFFLE:
+
+ - The Python package is the most user-friendly way to use RAFFLE, as it provides a high-level interface to the Fortran code and allows for easy implementation into existing workflows.
+
+ - The Fortran library provides the same functionality as the Python package, but in Fortran instead, enabling slightly more (but not recommended) access to the underlying code.
+
+ - The standalone executable enables the use of RAFFLE without any Python dependencies and no need to code, just editing of a parameter file.
+
+
+Global requirements
+===================
+
+All installation methods require the following dependency:
+
+- Fortran compiler (gfortran>=13.1, not compatible with intel compilers)
+
+Python
+======
+
+Requirements
+------------
+
+- python (>=3.11)
+- `pip `_
+- `f90wrap `_ (>=0.2.14)
+- `numpy `_ (>=1.26)
+- `meson `_ (>=1.6)
+- `cython `_ (>=3.0)
+- `sckit-build-core `_ (>=0.11)
+- `cmake `_ (>=3.17)
+- `ninja `_ (>=1.10) or `GNU Make `_
+
+Optional
+--------
+
+- `ASE `_ (>=3.23)
+
+Installation using pip
+-----------------------
+
+The easiest way to install RAFFLE is via pip.
+Currently, the package is not available on PyPI, so you will need to install it from the source code.
+
+Once the library is cloned, navigate to the root directory of the repository and run:
+
+.. code-block:: bash
+
+ pip install --upgrade .[ase]
+
+
+The optional ``[ase]`` flag is used to install the ASE interface, which is not required for the core functionality of RAFFLE, but is recommended
+
+.. note::
+ If you are installing RAFFLE on a computer where you do not have root access, you may need to add the ``--user`` flag to the above command.
+
+Depending on your setup, this will install the Python package and all its dependencies in different places.
+To find where this has been installed, you can run:
+
+.. code-block:: bash
+
+ pip show raffle
+
+This will show you the location of the installed package, in addition to other information about the package.
+
+Installation using cmake
+------------------------
+
+If you would like to install RAFFLE using cmake, you can do so by running the following commands:
+
+.. code-block:: bash
+
+ mkdir build
+ cd build
+ cmake [-DBUILD_PYTHON=On] -DBUILD_EXECUTABLE=Off ..
+ make
+ make install
+
+This will build the Python package and install it in the default location.
+For Unix systems, this will typically be in:
+
+.. code-block:: bash
+
+ ~/.local/raffle
+
+
+Fortran
+=======
+
+Requirements
+------------
+
+- `cmake `_ (>=3.17) or `fpm `_ (>=0.9.0)
+- `GNU Make `_ (if using cmake)
+
+
+As mentioned, the Fortran library provides the same functionality as the Python package, but in Fortran instead.
+
+To install the Fortran library or executable, the recommended method is to use the Fortran package manager (fpm).
+Cmake is also supported.
+
+Installation using fpm
+----------------------
+
+To install the Fortran library and the executable using fpm, navigate to the root directory of the repository and run:
+
+.. code-block:: bash
+
+ fpm build
+ fpm install
+
+This can also be set up as a dependency in your own fpm project by adding the following to your ``fpm.toml`` file:
+
+.. code-block:: toml
+
+ [dependencies]
+ raffle = { git = "https://github.com/ExeQuantCode/RAFFLE" }
+
+Installation using cmake
+------------------------
+
+To install the Fortran library using cmake, navigate to the root directory of the repository and run:
+
+.. code-block:: bash
+
+ mkdir build
+ cd build
+ cmake -DBUILD_PYTHON=Off -DBUILD_EXECUTABLE=Off ..
+ make
+ make install
+
+This will build the Fortran library and install it in the default location (``~/.local/raffle``).
+
+To install the standalone executable, run:
+
+.. code-block:: bash
+
+ mkdir build
+ cd build
+ cmake -DBUILD_PYTHON=Off -DBUILD_EXECUTABLE=On ..
+ make
+ make install
+
+This will build the Fortran library and install it in the default location (``~/.local/raffle``).
+
+
+Installing on MacOS (Homebrew)
+==============================
+
+RAFFLE is developed on Linux and MacOS, and should work on both.
+However, there are likely some additional steps required to install RAFFLE on MacOS.
+This is because **it is not recommended to rely on the Mac system Python, or Fortran and C compilers**.
+
+The recommended way to install Python, gfortran and gcc on MacOS is to use `Homebrew `_.
+First, install Homebrew by following the guide on their website.
+
+Once Homebrew is installed, you can install the required dependencies by running:
+
+.. code-block:: bash
+
+ brew install python
+ brew install gcc
+ brew install gfortran
+ export CC=$(brew --prefix gfortran)
+ export FC=$(brew --prefix gcc)
+
+Confirm a successful Python installation by running:
+
+.. code-block:: bash
+
+ python --version
+ whereis python
+
+This should show the correct Python version (3.11 or later) and path.
+
+Next, if you are using ``pip``, then the following command is found to result in the least issues:
+
+.. code-block:: bash
+
+ python -m pip install --upgrade .[ase]
+
+This ensures that the correct Python version is being called, and that the correct version of ``pip`` is being used.
+
+
+
+Testing the installation
+=========================
+
+Currently, installation testing is only available for the Fortran library and executable.
+
+Both methods below run the same set of tests (found in the ``tests`` directory of the repository), and should give the same results.
+These unit tests are designed to test the core functionality of the Fortran code and ensure that it is working as expected.
+
+.. note::
+ The Python package does not currently have a test suite, but this is planned for a future release.
+ The functionality of the Python package is provided by the Fortran code.
+ The Python package is just a wrapper around the Fortran code, so if the Fortran code is working, then the Python package should also work.
+ However, these wrapper functions do definitely need a test suite, and this is planned for a future release.
+
+Testing with fpm
+----------------
+
+To test the installation of the Fortran library, navigate to the root directory of the repository and run:
+
+.. code-block:: bash
+
+ fpm test
+
+This will run the test suite for the Fortran library.
+
+Testing with cmake
+------------------
+
+To test the installation of the Fortran library, navigate to the directory where the library was built.
+If the installation instructions above were followed, this will be in the ``build`` directory within the repository.
+
+To run the test suite, run:
+
+.. code-block:: bash
+
+ ctest
+
diff --git a/docs/source/modules.rst b/docs/source/modules.rst
new file mode 100644
index 00000000..aeae1589
--- /dev/null
+++ b/docs/source/modules.rst
@@ -0,0 +1,36 @@
+raffle
+======
+
+.. Submodules
+.. ----------
+
+.. raffle.raffle module
+.. --------------------
+
+.. .. automodule:: raffle.raffle
+.. :members:
+.. :undoc-members:
+.. :show-inheritance:
+
+Module contents
+---------------
+
+RAFFLE is a python package for performing structure prediction at interfaces.
+The package provides functionality for generating atomic structures by filling in host structures with additional atoms.
+The method involves iteratively generating structures and learning the energetically favourable features of the structures (see https://link.aps.org/doi/10.1103/PhysRevLett.132.066201).
+The package is built to accommodate energetic and structure data provided by the Atomic Simulation Environment (ASE) package (https://wiki.fysik.dtu.dk/ase/).
+
+Submodules
+----------
+
+.. toctree::
+ :maxdepth: 2
+
+ raffle.generator
+ raffle.geom
+ raffle.distributions
+
+.. .. automodule:: raffle
+.. :members:
+.. :undoc-members:
+.. :show-inheritance:
diff --git a/docs/source/raffle.distributions.rst b/docs/source/raffle.distributions.rst
new file mode 100644
index 00000000..27a93ff0
--- /dev/null
+++ b/docs/source/raffle.distributions.rst
@@ -0,0 +1,12 @@
+raffle.distributions module
+===========================
+
+.. .. automodule:: raffle.Raffle__Distribs_Container
+.. :members:
+.. :undoc-members:
+.. :show-inheritance:
+
+.. autoclass:: raffle.Raffle__Distribs_Container
+ :members:
+ :undoc-members:
+ :show-inheritance:
diff --git a/docs/source/raffle.generator.rst b/docs/source/raffle.generator.rst
new file mode 100644
index 00000000..0afed5cc
--- /dev/null
+++ b/docs/source/raffle.generator.rst
@@ -0,0 +1,13 @@
+raffle.generator module
+=======================
+
+.. .. automodule:: raffle.Generator
+.. :members:
+.. :undoc-members:
+.. :show-inheritance:
+
+
+.. autoclass:: raffle.Generator
+ :members:
+ :undoc-members:
+ :show-inheritance:
\ No newline at end of file
diff --git a/docs/source/raffle.geom.rst b/docs/source/raffle.geom.rst
new file mode 100644
index 00000000..9cbff07e
--- /dev/null
+++ b/docs/source/raffle.geom.rst
@@ -0,0 +1,12 @@
+raffle.geom_rw module
+=======================
+
+.. .. automodule:: raffle.Geom_Rw
+.. :members:
+.. :undoc-members:
+.. :show-inheritance:
+
+.. autoclass:: raffle.Geom_Rw
+ :members:
+ :undoc-members:
+ :show-inheritance:
diff --git a/docs/source/tutorials/BaTiO3_tutorial.rst b/docs/source/tutorials/BaTiO3_tutorial.rst
new file mode 100644
index 00000000..3c136a68
--- /dev/null
+++ b/docs/source/tutorials/BaTiO3_tutorial.rst
@@ -0,0 +1,5 @@
+.. BaTiO3:
+
+========================
+BaTiO\ :sub:`3` tutorial
+========================
diff --git a/docs/source/tutorials/C-MgO_tutorial.rst b/docs/source/tutorials/C-MgO_tutorial.rst
new file mode 100644
index 00000000..7a9b11e3
--- /dev/null
+++ b/docs/source/tutorials/C-MgO_tutorial.rst
@@ -0,0 +1,5 @@
+.. C-MgO:
+
+=========================
+Graphene-encapsulated MgO
+=========================
\ No newline at end of file
diff --git a/docs/source/tutorials/databases_tutorial.rst b/docs/source/tutorials/databases_tutorial.rst
new file mode 100644
index 00000000..05fc496a
--- /dev/null
+++ b/docs/source/tutorials/databases_tutorial.rst
@@ -0,0 +1,127 @@
+.. databases:
+
+==================
+Databases Tutorial
+==================
+
+This tutorial will guide you through the process of obtaining a database of structures from the Materials Project database.
+The process will use a database of carbon, magnesium, and oxygen structures as an example.
+However, this process can be applied to any set of elements in the Materials Project database.
+
+.. note::
+
+ The guide is written for the Materials Project API v0.41.2.
+ The guide provided on this page might be out of date.
+ If you encounter issues, please refer to the `Materials Project API `_ for the most up-to-date information.
+ From our experience, it seems that the API still undergoes regular changes, so it is important to check the website for the most recent information.
+
+A script is provided to obtain a database of carbon structures from the Materials Project database, which can be found in the following directory:
+
+.. code-block:: bash
+
+ raffle/tools/database.py
+
+
+Requirements
+------------
+
+To run the script, you will need to install the following Python packages:
+
+- `pymatgen `_
+- `ase `_
+- `mp-api `_
+
+Materials Project API key
+-------------------------
+
+Once you have installed the required packages, you need to set up your Materials Project API key.
+To do so you must:
+
+1. Create an account on the `Materials Project website `_.
+2. Obtain your API key from the `API section `_.
+3. Run the following command via pymatgen ``pmg config --add PMG_MAPI_KEY ``.
+
+Further details (and up-to-date information) can be found at the following two pages:
+
+- `Materials Project API `_
+- `Setting the PMG_MAPI_KEY `_
+
+You might also need to set up a VASP_PSP_DIR environment variable to point to the directory containing the VASP pseudopotentials.
+If that is the case, follow the guide provided `here `_.
+
+Now we can start the script to obtain the database of structures.
+First, we must import the required packages:
+
+.. code-block:: python
+
+ from ase import Atoms
+ from ase.io import write
+ from pymatgen.io.ase import AseAtomsAdaptor
+ from mp_api.client import MPRester
+
+Next, we need to set up the Materials Project API key:
+
+.. code-block:: python
+
+ mpr = MPRester()
+
+Now we can obtain the database of carbon, magnesium, and oxygen structures.
+
+.. code-block:: python
+
+ materials = []
+ materials.append(mpr.materials.summary.search(chemsys="C",
+ fields=["material_id","structure", "energy_per_atom", "nsites"]))
+ materials.append(mpr.materials.summary.search(chemsys="Mg",
+ fields=["material_id","structure", "energy_per_atom", "nsites"]))
+ materials.append(mpr.materials.summary.search(chemsys="O",
+ fields=["material_id","structure", "energy_per_atom", "nsites"]))
+ materials.append(mpr.materials.summary.search(chemsys="C-Mg",
+ fields=["material_id","structure", "energy_per_atom", "nsites"]))
+ materials.append(mpr.materials.summary.search(chemsys="C-O",
+ fields=["material_id","structure", "energy_per_atom", "nsites"]))
+ materials.append(mpr.materials.summary.search(chemsys="Mg-O",
+ fields=["material_id","structure", "energy_per_atom", "nsites"]))
+
+Now that we have the structures, we need to extract the relevant information and save the structures to a file.
+This can be done more succinctly with `.traj` files, but for human readability, we will use `.xyz` files (extended XYZ format).
+
+.. code-block:: python
+
+ structures = []
+ energies = []
+ nsites = []
+ for material_set in materials:
+ for material in material_set:
+ material_id = material.material_id
+ structures.append(mpr.get_structure_by_material_id(material_id))
+ energies.append(material.energy_per_atom)
+ nsites.append(material.nsites)
+
+ all_atoms = []
+ for structure, energy, nsite in zip(structures, energies, nsites):
+ atom = AseAtomsAdaptor.get_atoms(structure)
+ atom.info['free_energy'] = energy * nsite
+ atom.info['energy'] = energy * nsite
+ all_atoms.append(atom)
+ write("database.xyz", all_atoms, format='extxyz')
+
+With this, we now have a database of structures that can be used to initialise the generalised distribution functions in RAFFLE.
+The database can be loaded in using the ASE package and then provided as an input to the RAFFLE generator's distributions.
+
+.. code-block:: python
+
+ from ase.io import read
+ from raffle.generator import raffle_generator
+
+ atoms = read("database.xyz", index=":")
+
+ generator = raffle_generator()
+ generator.distributions.create(atoms)
+
+.. note::
+
+ You may want to set some of the parameters of the distribution functions.
+ If so, this must be done BEFORE calling the `create` method.
+
+We are now ready to generate structures using the database of structures.
\ No newline at end of file
diff --git a/docs/source/tutorials/diamond_tutorial.rst b/docs/source/tutorials/diamond_tutorial.rst
new file mode 100644
index 00000000..21f894dc
--- /dev/null
+++ b/docs/source/tutorials/diamond_tutorial.rst
@@ -0,0 +1,134 @@
+.. diamond:
+
+================
+Diamond tutorial
+================
+
+This tutorial will guide you through the process of reconstructing diamond from a defected diamond cell.
+
+The tutorial is designed to show how RAFFLE learns from a database and uses this information to generate structures.
+This is not an expected use-case of RAFFLE, but merely a demonstration of its capabilities to rebuild a structure from a defected cell.
+
+The example files can be found in the following directory:
+
+.. code-block:: bash
+
+ raffle/example/python_pkg/diamond
+
+First, we need to establish an initial database of structures.
+This will be used to initialise the generalised distribution functions, which will inform the placement of atoms in the generated structures.
+Here, we detail two routes: 1) using an ASE object of bulk diamond and 2) using the Materials Project database.
+
+Here, we will simply use the ASE object of bulk diamond.
+If you wish to use the Materials Project database, please refer to the `Databases tutorial `_.
+
+First, we must import the required packages:
+
+.. code-block:: python
+
+ from ase import Atoms
+ from raffle.generator import raffle_generator
+ from mace.calculators import mace_mp
+ import numpy as np
+
+Next, we need to set up the RAFFLE generator and the calculator to calculate the energies of the structures.
+In this example, we use the MACE-MP0 calculator:
+
+.. code-block:: python
+
+ generator = raffle_generator()
+
+ calc = mace_mp(model="medium", dispersion=False, default_dtype="float32", device='cpu')
+
+
+Then, we need to create the host structure.
+This is the base structure that will be added to in order to generate the structures.
+
+.. code-block:: python
+
+ host = Atoms(
+ "C8",
+ positions=[
+ [0.0, 0.0, 1.7803725545451616],
+ [0.8901862772725809, 0.8901862772725808, 2.6705588318177425],
+ [2.863057429826727e-16, 1.7803725545451616, 1.0901637751067644e-16],
+ [0.8901862772725813, 2.6705588318177425, 0.890186277272581],
+ [1.7803725545451616, 0.0, 1.0901637751067644e-16],
+ [2.6705588318177425, 0.8901862772725808, 0.890186277272581],
+ [1.7803725545451619, 1.7803725545451616, 1.7803725545451619],
+ [2.670558831817743, 2.6705588318177425, 2.670558831817743]
+ ], cell=[
+ 3.5607451090903233, 3.5607451090903233, 7.1214902182
+ ], pbc=True
+ )
+ )
+
+ host.calc = calc
+ generator.set_host(host)
+
+Next, we need to set any variables we want to use for the distributions.
+None should be required other than the element energies, which will be used as reference energies to calculate the formation energies of the structures.
+However, for completeness, we will set other variables here.
+Because there is only one element in this structure, the reference energy is meaningless, so we set it to ``0.0`` here.
+This is due to all structures will have the same stoichiometry and thus use the exact same reference energy, so choice of this value is a global shift.
+
+.. code-block:: python
+
+ generator.distributions.set_element_energies( { 'C': 0.0 } )
+ generator.distributions.set_kBT(0.2)
+ generator.distributions.set_width([0.025, np.pi/200.0, np.pi/200.0])
+ generator.distributions.set_radius_distance_tol([1.5, 2.5, 3.0, 6.0])
+
+Now we need to generate the database of structures.
+We will provide bulk diamond as the only database entry here.
+
+.. code-block:: python
+
+ database = []
+ database.append(
+ Atoms(
+ "C8",
+ positions=[
+ [0.0, 0.0, 1.7803725545451616],
+ [0.8901862772725809, 0.8901862772725808, 2.6705588318177425],
+ [2.863057429826727e-16, 1.7803725545451616, 1.0901637751067644e-16],
+ [0.8901862772725813, 2.6705588318177425, 0.890186277272581],
+ [1.7803725545451616, 0.0, 1.0901637751067644e-16],
+ [2.6705588318177425, 0.8901862772725808, 0.890186277272581],
+ [1.7803725545451619, 1.7803725545451616, 1.7803725545451619],
+ [2.670558831817743, 2.6705588318177425, 2.670558831817743]
+ ], cell=[
+ 3.5607451090903233, 3.5607451090903233, 3.5607451090903233
+ ], pbc=True
+ )
+ )
+
+This database will now be used to initialise the generalised distribution functions in RAFFLE.
+
+.. code-block:: python
+
+ generator.distributions.create(database)
+
+Finally, we can set the grid on which atom searches are performed (this grid is applied to the host cell).
+By default, the grid is generated using a spacing of 0.1 Å.
+
+.. code-block:: python
+
+ generator.set_grid(grid_spacing=0.1, grid_offset=[0.0, 0.0, 0.0])
+
+We are now ready to generate structures using the database of structures.
+
+.. code-block:: python
+
+ num_structures_old = 0
+ generator.generate(
+ num_structures = 1,
+ stoichiometry = { 'C': 8 },
+ method_probab = {"void":0.0001, "min":1.0},
+ )
+ structures = generator.get_structures(calc)
+
+We should now have a structure of diamond.
+This structure can be visualised using the ASE package.
+But this can also be verified energetically.
+The generated structure should have double the energy of bulk diamond, found in ```database[0]```.
\ No newline at end of file
diff --git a/docs/source/tutorials/graphite_tutorial.rst b/docs/source/tutorials/graphite_tutorial.rst
new file mode 100644
index 00000000..0a2e6aa4
--- /dev/null
+++ b/docs/source/tutorials/graphite_tutorial.rst
@@ -0,0 +1,5 @@
+.. graphite:
+
+=================
+Graphite tutorial
+=================
\ No newline at end of file
diff --git a/docs/source/tutorials/index.rst b/docs/source/tutorials/index.rst
new file mode 100644
index 00000000..e0bb1311
--- /dev/null
+++ b/docs/source/tutorials/index.rst
@@ -0,0 +1,23 @@
+.. tutorials:
+
+=========
+Tutorials
+=========
+
+Whilst RAFFLE is a random sturcture search package designed primarlily for interfaces, the tutorials will use bulk systems to demonstrate its functionality.
+
+.. note::
+ If you are looking for bulk random structure search, we recommend using packages such as `AIRSS `_, which are specifically designed for this purpose.
+ They take advantage of symmetries prevalent in bulk structures to reduce the search space and improve efficiency.
+ RAFFLE does not account for these symmetries, due to their usual absence in interfaces.
+
+.. toctree::
+ :maxdepth: 2
+ :caption: Tutorials:
+
+ databases_tutorial
+ diamond_tutorial
+ graphite_tutorial
+ BaTiO3_tutorial
+ perovskites_tutorial
+ C-MgO_tutorial
diff --git a/docs/source/tutorials/perovskites_tutorial.rst b/docs/source/tutorials/perovskites_tutorial.rst
new file mode 100644
index 00000000..d378b21f
--- /dev/null
+++ b/docs/source/tutorials/perovskites_tutorial.rst
@@ -0,0 +1,5 @@
+.. perovskites:
+
+====================================================
+BaTiO\ :sub:`3`\|SrTiO\ :sub:`3` interface tutorial
+====================================================
\ No newline at end of file
diff --git a/example/example_files/DC_MgO_hosts/POSCAR_10x10_5.4_separation b/example/example_files/DC_MgO_hosts/POSCAR_10x10_5.4_separation
deleted file mode 100644
index 3ca82577..00000000
--- a/example/example_files/DC_MgO_hosts/POSCAR_10x10_5.4_separation
+++ /dev/null
@@ -1,408 +0,0 @@
-c1
- 1.000000000
- 24.639999866 0.000000000 0.000000000
- -12.319999933 21.338865834 0.000000000
- 0.000000000 0.000000000 10.710999966
-C
-400
-Direct
- 0.000000000 0.000000000 0.250000000
- 0.100000000 0.000000000 0.250000000
- 0.200000000 0.000000000 0.250000000
- 0.300000000 0.000000000 0.250000000
- 0.400000000 0.000000000 0.250000000
- 0.500000000 0.000000000 0.250000000
- 0.600000000 0.000000000 0.250000000
- 0.700000000 0.000000000 0.250000000
- 0.800000000 0.000000000 0.250000000
- 0.900000000 0.000000000 0.250000000
- 0.000000000 0.100000000 0.250000000
- 0.100000000 0.100000000 0.250000000
- 0.200000000 0.100000000 0.250000000
- 0.300000000 0.100000000 0.250000000
- 0.400000000 0.100000000 0.250000000
- 0.500000000 0.100000000 0.250000000
- 0.600000000 0.100000000 0.250000000
- 0.700000000 0.100000000 0.250000000
- 0.800000000 0.100000000 0.250000000
- 0.900000000 0.100000000 0.250000000
- 0.000000000 0.200000000 0.250000000
- 0.100000000 0.200000000 0.250000000
- 0.200000000 0.200000000 0.250000000
- 0.300000000 0.200000000 0.250000000
- 0.400000000 0.200000000 0.250000000
- 0.500000000 0.200000000 0.250000000
- 0.600000000 0.200000000 0.250000000
- 0.700000000 0.200000000 0.250000000
- 0.800000000 0.200000000 0.250000000
- 0.900000000 0.200000000 0.250000000
- 0.000000000 0.300000000 0.250000000
- 0.100000000 0.300000000 0.250000000
- 0.200000000 0.300000000 0.250000000
- 0.300000000 0.300000000 0.250000000
- 0.400000000 0.300000000 0.250000000
- 0.500000000 0.300000000 0.250000000
- 0.600000000 0.300000000 0.250000000
- 0.700000000 0.300000000 0.250000000
- 0.800000000 0.300000000 0.250000000
- 0.900000000 0.300000000 0.250000000
- 0.000000000 0.400000000 0.250000000
- 0.100000000 0.400000000 0.250000000
- 0.200000000 0.400000000 0.250000000
- 0.300000000 0.400000000 0.250000000
- 0.400000000 0.400000000 0.250000000
- 0.500000000 0.400000000 0.250000000
- 0.600000000 0.400000000 0.250000000
- 0.700000000 0.400000000 0.250000000
- 0.800000000 0.400000000 0.250000000
- 0.900000000 0.400000000 0.250000000
- 0.000000000 0.500000000 0.250000000
- 0.100000000 0.500000000 0.250000000
- 0.200000000 0.500000000 0.250000000
- 0.300000000 0.500000000 0.250000000
- 0.400000000 0.500000000 0.250000000
- 0.500000000 0.500000000 0.250000000
- 0.600000000 0.500000000 0.250000000
- 0.700000000 0.500000000 0.250000000
- 0.800000000 0.500000000 0.250000000
- 0.900000000 0.500000000 0.250000000
- 0.000000000 0.600000000 0.250000000
- 0.100000000 0.600000000 0.250000000
- 0.200000000 0.600000000 0.250000000
- 0.300000000 0.600000000 0.250000000
- 0.400000000 0.600000000 0.250000000
- 0.500000000 0.600000000 0.250000000
- 0.600000000 0.600000000 0.250000000
- 0.700000000 0.600000000 0.250000000
- 0.800000000 0.600000000 0.250000000
- 0.900000000 0.600000000 0.250000000
- 0.000000000 0.700000000 0.250000000
- 0.100000000 0.700000000 0.250000000
- 0.200000000 0.700000000 0.250000000
- 0.300000000 0.700000000 0.250000000
- 0.400000000 0.700000000 0.250000000
- 0.500000000 0.700000000 0.250000000
- 0.600000000 0.700000000 0.250000000
- 0.700000000 0.700000000 0.250000000
- 0.800000000 0.700000000 0.250000000
- 0.900000000 0.700000000 0.250000000
- 0.000000000 0.800000000 0.250000000
- 0.100000000 0.800000000 0.250000000
- 0.200000000 0.800000000 0.250000000
- 0.300000000 0.800000000 0.250000000
- 0.400000000 0.800000000 0.250000000
- 0.500000000 0.800000000 0.250000000
- 0.600000000 0.800000000 0.250000000
- 0.700000000 0.800000000 0.250000000
- 0.800000000 0.800000000 0.250000000
- 0.900000000 0.800000000 0.250000000
- 0.000000000 0.900000000 0.250000000
- 0.100000000 0.900000000 0.250000000
- 0.200000000 0.900000000 0.250000000
- 0.300000000 0.900000000 0.250000000
- 0.400000000 0.900000000 0.250000000
- 0.500000000 0.900000000 0.250000000
- 0.600000000 0.900000000 0.250000000
- 0.700000000 0.900000000 0.250000000
- 0.800000000 0.900000000 0.250000000
- 0.900000000 0.900000000 0.250000000
- 0.000000000 0.000000000 0.749999982
- 0.100000000 0.000000000 0.749999982
- 0.200000000 0.000000000 0.749999982
- 0.300000000 0.000000000 0.749999982
- 0.400000000 0.000000000 0.749999982
- 0.500000000 0.000000000 0.749999982
- 0.600000000 0.000000000 0.749999982
- 0.700000000 0.000000000 0.749999982
- 0.800000000 0.000000000 0.749999982
- 0.900000000 0.000000000 0.749999982
- 0.000000000 0.100000000 0.749999982
- 0.100000000 0.100000000 0.749999982
- 0.200000000 0.100000000 0.749999982
- 0.300000000 0.100000000 0.749999982
- 0.400000000 0.100000000 0.749999982
- 0.500000000 0.100000000 0.749999982
- 0.600000000 0.100000000 0.749999982
- 0.700000000 0.100000000 0.749999982
- 0.800000000 0.100000000 0.749999982
- 0.900000000 0.100000000 0.749999982
- 0.000000000 0.200000000 0.749999982
- 0.100000000 0.200000000 0.749999982
- 0.200000000 0.200000000 0.749999982
- 0.300000000 0.200000000 0.749999982
- 0.400000000 0.200000000 0.749999982
- 0.500000000 0.200000000 0.749999982
- 0.600000000 0.200000000 0.749999982
- 0.700000000 0.200000000 0.749999982
- 0.800000000 0.200000000 0.749999982
- 0.900000000 0.200000000 0.749999982
- 0.000000000 0.300000000 0.749999982
- 0.100000000 0.300000000 0.749999982
- 0.200000000 0.300000000 0.749999982
- 0.300000000 0.300000000 0.749999982
- 0.400000000 0.300000000 0.749999982
- 0.500000000 0.300000000 0.749999982
- 0.600000000 0.300000000 0.749999982
- 0.700000000 0.300000000 0.749999982
- 0.800000000 0.300000000 0.749999982
- 0.900000000 0.300000000 0.749999982
- 0.000000000 0.400000000 0.749999982
- 0.100000000 0.400000000 0.749999982
- 0.200000000 0.400000000 0.749999982
- 0.300000000 0.400000000 0.749999982
- 0.400000000 0.400000000 0.749999982
- 0.500000000 0.400000000 0.749999982
- 0.600000000 0.400000000 0.749999982
- 0.700000000 0.400000000 0.749999982
- 0.800000000 0.400000000 0.749999982
- 0.900000000 0.400000000 0.749999982
- 0.000000000 0.500000000 0.749999982
- 0.100000000 0.500000000 0.749999982
- 0.200000000 0.500000000 0.749999982
- 0.300000000 0.500000000 0.749999982
- 0.400000000 0.500000000 0.749999982
- 0.500000000 0.500000000 0.749999982
- 0.600000000 0.500000000 0.749999982
- 0.700000000 0.500000000 0.749999982
- 0.800000000 0.500000000 0.749999982
- 0.900000000 0.500000000 0.749999982
- 0.000000000 0.600000000 0.749999982
- 0.100000000 0.600000000 0.749999982
- 0.200000000 0.600000000 0.749999982
- 0.300000000 0.600000000 0.749999982
- 0.400000000 0.600000000 0.749999982
- 0.500000000 0.600000000 0.749999982
- 0.600000000 0.600000000 0.749999982
- 0.700000000 0.600000000 0.749999982
- 0.800000000 0.600000000 0.749999982
- 0.900000000 0.600000000 0.749999982
- 0.000000000 0.700000000 0.749999982
- 0.100000000 0.700000000 0.749999982
- 0.200000000 0.700000000 0.749999982
- 0.300000000 0.700000000 0.749999982
- 0.400000000 0.700000000 0.749999982
- 0.500000000 0.700000000 0.749999982
- 0.600000000 0.700000000 0.749999982
- 0.700000000 0.700000000 0.749999982
- 0.800000000 0.700000000 0.749999982
- 0.900000000 0.700000000 0.749999982
- 0.000000000 0.800000000 0.749999982
- 0.100000000 0.800000000 0.749999982
- 0.200000000 0.800000000 0.749999982
- 0.300000000 0.800000000 0.749999982
- 0.400000000 0.800000000 0.749999982
- 0.500000000 0.800000000 0.749999982
- 0.600000000 0.800000000 0.749999982
- 0.700000000 0.800000000 0.749999982
- 0.800000000 0.800000000 0.749999982
- 0.900000000 0.800000000 0.749999982
- 0.000000000 0.900000000 0.749999982
- 0.100000000 0.900000000 0.749999982
- 0.200000000 0.900000000 0.749999982
- 0.300000000 0.900000000 0.749999982
- 0.400000000 0.900000000 0.749999982
- 0.500000000 0.900000000 0.749999982
- 0.600000000 0.900000000 0.749999982
- 0.700000000 0.900000000 0.749999982
- 0.800000000 0.900000000 0.749999982
- 0.900000000 0.900000000 0.749999982
- 0.033333334 0.066666668 0.250000000
- 0.133333334 0.066666668 0.250000000
- 0.233333334 0.066666668 0.250000000
- 0.333333334 0.066666668 0.250000000
- 0.433333334 0.066666668 0.250000000
- 0.533333334 0.066666668 0.250000000
- 0.633333334 0.066666668 0.250000000
- 0.733333334 0.066666668 0.250000000
- 0.833333334 0.066666668 0.250000000
- 0.933333334 0.066666668 0.250000000
- 0.033333334 0.166666668 0.250000000
- 0.133333334 0.166666668 0.250000000
- 0.233333334 0.166666668 0.250000000
- 0.333333334 0.166666668 0.250000000
- 0.433333334 0.166666668 0.250000000
- 0.533333334 0.166666668 0.250000000
- 0.633333334 0.166666668 0.250000000
- 0.733333334 0.166666668 0.250000000
- 0.833333334 0.166666668 0.250000000
- 0.933333334 0.166666668 0.250000000
- 0.033333334 0.266666668 0.250000000
- 0.133333334 0.266666668 0.250000000
- 0.233333334 0.266666668 0.250000000
- 0.333333334 0.266666668 0.250000000
- 0.433333334 0.266666668 0.250000000
- 0.533333334 0.266666668 0.250000000
- 0.633333334 0.266666668 0.250000000
- 0.733333334 0.266666668 0.250000000
- 0.833333334 0.266666668 0.250000000
- 0.933333334 0.266666668 0.250000000
- 0.033333334 0.366666668 0.250000000
- 0.133333334 0.366666668 0.250000000
- 0.233333334 0.366666668 0.250000000
- 0.333333334 0.366666668 0.250000000
- 0.433333334 0.366666668 0.250000000
- 0.533333334 0.366666668 0.250000000
- 0.633333334 0.366666668 0.250000000
- 0.733333334 0.366666668 0.250000000
- 0.833333334 0.366666668 0.250000000
- 0.933333334 0.366666668 0.250000000
- 0.033333334 0.466666668 0.250000000
- 0.133333334 0.466666668 0.250000000
- 0.233333334 0.466666668 0.250000000
- 0.333333334 0.466666668 0.250000000
- 0.433333334 0.466666668 0.250000000
- 0.533333334 0.466666668 0.250000000
- 0.633333334 0.466666668 0.250000000
- 0.733333334 0.466666668 0.250000000
- 0.833333334 0.466666668 0.250000000
- 0.933333334 0.466666668 0.250000000
- 0.033333334 0.566666668 0.250000000
- 0.133333334 0.566666668 0.250000000
- 0.233333334 0.566666668 0.250000000
- 0.333333334 0.566666668 0.250000000
- 0.433333334 0.566666668 0.250000000
- 0.533333334 0.566666668 0.250000000
- 0.633333334 0.566666668 0.250000000
- 0.733333334 0.566666668 0.250000000
- 0.833333334 0.566666668 0.250000000
- 0.933333334 0.566666668 0.250000000
- 0.033333334 0.666666668 0.250000000
- 0.133333334 0.666666668 0.250000000
- 0.233333334 0.666666668 0.250000000
- 0.333333334 0.666666668 0.250000000
- 0.433333334 0.666666668 0.250000000
- 0.533333334 0.666666668 0.250000000
- 0.633333334 0.666666668 0.250000000
- 0.733333334 0.666666668 0.250000000
- 0.833333334 0.666666668 0.250000000
- 0.933333334 0.666666668 0.250000000
- 0.033333334 0.766666668 0.250000000
- 0.133333334 0.766666668 0.250000000
- 0.233333334 0.766666668 0.250000000
- 0.333333334 0.766666668 0.250000000
- 0.433333334 0.766666668 0.250000000
- 0.533333334 0.766666668 0.250000000
- 0.633333334 0.766666668 0.250000000
- 0.733333334 0.766666668 0.250000000
- 0.833333334 0.766666668 0.250000000
- 0.933333334 0.766666668 0.250000000
- 0.033333334 0.866666668 0.250000000
- 0.133333334 0.866666668 0.250000000
- 0.233333334 0.866666668 0.250000000
- 0.333333334 0.866666668 0.250000000
- 0.433333334 0.866666668 0.250000000
- 0.533333334 0.866666668 0.250000000
- 0.633333334 0.866666668 0.250000000
- 0.733333334 0.866666668 0.250000000
- 0.833333334 0.866666668 0.250000000
- 0.933333334 0.866666668 0.250000000
- 0.033333334 0.966666668 0.250000000
- 0.133333334 0.966666668 0.250000000
- 0.233333334 0.966666668 0.250000000
- 0.333333334 0.966666668 0.250000000
- 0.433333334 0.966666668 0.250000000
- 0.533333334 0.966666668 0.250000000
- 0.633333334 0.966666668 0.250000000
- 0.733333334 0.966666668 0.250000000
- 0.833333334 0.966666668 0.250000000
- 0.933333334 0.966666668 0.250000000
- 0.066666666 0.033333331 0.749999982
- 0.166666666 0.033333331 0.749999982
- 0.266666666 0.033333331 0.749999982
- 0.366666666 0.033333331 0.749999982
- 0.466666666 0.033333331 0.749999982
- 0.566666666 0.033333331 0.749999982
- 0.666666666 0.033333331 0.749999982
- 0.766666666 0.033333331 0.749999982
- 0.866666666 0.033333331 0.749999982
- 0.966666666 0.033333331 0.749999982
- 0.066666666 0.133333331 0.749999982
- 0.166666666 0.133333331 0.749999982
- 0.266666666 0.133333331 0.749999982
- 0.366666666 0.133333331 0.749999982
- 0.466666666 0.133333331 0.749999982
- 0.566666666 0.133333331 0.749999982
- 0.666666666 0.133333331 0.749999982
- 0.766666666 0.133333331 0.749999982
- 0.866666666 0.133333331 0.749999982
- 0.966666666 0.133333331 0.749999982
- 0.066666666 0.233333331 0.749999982
- 0.166666666 0.233333331 0.749999982
- 0.266666666 0.233333331 0.749999982
- 0.366666666 0.233333331 0.749999982
- 0.466666666 0.233333331 0.749999982
- 0.566666666 0.233333331 0.749999982
- 0.666666666 0.233333331 0.749999982
- 0.766666666 0.233333331 0.749999982
- 0.866666666 0.233333331 0.749999982
- 0.966666666 0.233333331 0.749999982
- 0.066666666 0.333333331 0.749999982
- 0.166666666 0.333333331 0.749999982
- 0.266666666 0.333333331 0.749999982
- 0.366666666 0.333333331 0.749999982
- 0.466666666 0.333333331 0.749999982
- 0.566666666 0.333333331 0.749999982
- 0.666666666 0.333333331 0.749999982
- 0.766666666 0.333333331 0.749999982
- 0.866666666 0.333333331 0.749999982
- 0.966666666 0.333333331 0.749999982
- 0.066666666 0.433333331 0.749999982
- 0.166666666 0.433333331 0.749999982
- 0.266666666 0.433333331 0.749999982
- 0.366666666 0.433333331 0.749999982
- 0.466666666 0.433333331 0.749999982
- 0.566666666 0.433333331 0.749999982
- 0.666666666 0.433333331 0.749999982
- 0.766666666 0.433333331 0.749999982
- 0.866666666 0.433333331 0.749999982
- 0.966666666 0.433333331 0.749999982
- 0.066666666 0.533333331 0.749999982
- 0.166666666 0.533333331 0.749999982
- 0.266666666 0.533333331 0.749999982
- 0.366666666 0.533333331 0.749999982
- 0.466666666 0.533333331 0.749999982
- 0.566666666 0.533333331 0.749999982
- 0.666666666 0.533333331 0.749999982
- 0.766666666 0.533333331 0.749999982
- 0.866666666 0.533333331 0.749999982
- 0.966666666 0.533333331 0.749999982
- 0.066666666 0.633333331 0.749999982
- 0.166666666 0.633333331 0.749999982
- 0.266666666 0.633333331 0.749999982
- 0.366666666 0.633333331 0.749999982
- 0.466666666 0.633333331 0.749999982
- 0.566666666 0.633333331 0.749999982
- 0.666666666 0.633333331 0.749999982
- 0.766666666 0.633333331 0.749999982
- 0.866666666 0.633333331 0.749999982
- 0.966666666 0.633333331 0.749999982
- 0.066666666 0.733333331 0.749999982
- 0.166666666 0.733333331 0.749999982
- 0.266666666 0.733333331 0.749999982
- 0.366666666 0.733333331 0.749999982
- 0.466666666 0.733333331 0.749999982
- 0.566666666 0.733333331 0.749999982
- 0.666666666 0.733333331 0.749999982
- 0.766666666 0.733333331 0.749999982
- 0.866666666 0.733333331 0.749999982
- 0.966666666 0.733333331 0.749999982
- 0.066666666 0.833333331 0.749999982
- 0.166666666 0.833333331 0.749999982
- 0.266666666 0.833333331 0.749999982
- 0.366666666 0.833333331 0.749999982
- 0.466666666 0.833333331 0.749999982
- 0.566666666 0.833333331 0.749999982
- 0.666666666 0.833333331 0.749999982
- 0.766666666 0.833333331 0.749999982
- 0.866666666 0.833333331 0.749999982
- 0.966666666 0.833333331 0.749999982
- 0.066666666 0.933333331 0.749999982
- 0.166666666 0.933333331 0.749999982
- 0.266666666 0.933333331 0.749999982
- 0.366666666 0.933333331 0.749999982
- 0.466666666 0.933333331 0.749999982
- 0.566666666 0.933333331 0.749999982
- 0.666666666 0.933333331 0.749999982
- 0.766666666 0.933333331 0.749999982
- 0.866666666 0.933333331 0.749999982
- 0.966666666 0.933333331 0.749999982
diff --git a/example/example_files/DC_MgO_hosts/POSCAR_10x10_6.0A_separation b/example/example_files/DC_MgO_hosts/POSCAR_10x10_6.0A_separation
deleted file mode 100644
index f28bfc5b..00000000
--- a/example/example_files/DC_MgO_hosts/POSCAR_10x10_6.0A_separation
+++ /dev/null
@@ -1,408 +0,0 @@
-c1
- 1.000000000
- 24.639999866 0.000000000 0.000000000
- -12.319999933 21.338865834 0.000000000
- 0.000000000 0.000000000 12.029835
-C
-400
-Direct
- 0.000000000 0.000000000 0.250000000
- 0.100000000 0.000000000 0.250000000
- 0.200000000 0.000000000 0.250000000
- 0.300000000 0.000000000 0.250000000
- 0.400000000 0.000000000 0.250000000
- 0.500000000 0.000000000 0.250000000
- 0.600000000 0.000000000 0.250000000
- 0.700000000 0.000000000 0.250000000
- 0.800000000 0.000000000 0.250000000
- 0.900000000 0.000000000 0.250000000
- 0.000000000 0.100000000 0.250000000
- 0.100000000 0.100000000 0.250000000
- 0.200000000 0.100000000 0.250000000
- 0.300000000 0.100000000 0.250000000
- 0.400000000 0.100000000 0.250000000
- 0.500000000 0.100000000 0.250000000
- 0.600000000 0.100000000 0.250000000
- 0.700000000 0.100000000 0.250000000
- 0.800000000 0.100000000 0.250000000
- 0.900000000 0.100000000 0.250000000
- 0.000000000 0.200000000 0.250000000
- 0.100000000 0.200000000 0.250000000
- 0.200000000 0.200000000 0.250000000
- 0.300000000 0.200000000 0.250000000
- 0.400000000 0.200000000 0.250000000
- 0.500000000 0.200000000 0.250000000
- 0.600000000 0.200000000 0.250000000
- 0.700000000 0.200000000 0.250000000
- 0.800000000 0.200000000 0.250000000
- 0.900000000 0.200000000 0.250000000
- 0.000000000 0.300000000 0.250000000
- 0.100000000 0.300000000 0.250000000
- 0.200000000 0.300000000 0.250000000
- 0.300000000 0.300000000 0.250000000
- 0.400000000 0.300000000 0.250000000
- 0.500000000 0.300000000 0.250000000
- 0.600000000 0.300000000 0.250000000
- 0.700000000 0.300000000 0.250000000
- 0.800000000 0.300000000 0.250000000
- 0.900000000 0.300000000 0.250000000
- 0.000000000 0.400000000 0.250000000
- 0.100000000 0.400000000 0.250000000
- 0.200000000 0.400000000 0.250000000
- 0.300000000 0.400000000 0.250000000
- 0.400000000 0.400000000 0.250000000
- 0.500000000 0.400000000 0.250000000
- 0.600000000 0.400000000 0.250000000
- 0.700000000 0.400000000 0.250000000
- 0.800000000 0.400000000 0.250000000
- 0.900000000 0.400000000 0.250000000
- 0.000000000 0.500000000 0.250000000
- 0.100000000 0.500000000 0.250000000
- 0.200000000 0.500000000 0.250000000
- 0.300000000 0.500000000 0.250000000
- 0.400000000 0.500000000 0.250000000
- 0.500000000 0.500000000 0.250000000
- 0.600000000 0.500000000 0.250000000
- 0.700000000 0.500000000 0.250000000
- 0.800000000 0.500000000 0.250000000
- 0.900000000 0.500000000 0.250000000
- 0.000000000 0.600000000 0.250000000
- 0.100000000 0.600000000 0.250000000
- 0.200000000 0.600000000 0.250000000
- 0.300000000 0.600000000 0.250000000
- 0.400000000 0.600000000 0.250000000
- 0.500000000 0.600000000 0.250000000
- 0.600000000 0.600000000 0.250000000
- 0.700000000 0.600000000 0.250000000
- 0.800000000 0.600000000 0.250000000
- 0.900000000 0.600000000 0.250000000
- 0.000000000 0.700000000 0.250000000
- 0.100000000 0.700000000 0.250000000
- 0.200000000 0.700000000 0.250000000
- 0.300000000 0.700000000 0.250000000
- 0.400000000 0.700000000 0.250000000
- 0.500000000 0.700000000 0.250000000
- 0.600000000 0.700000000 0.250000000
- 0.700000000 0.700000000 0.250000000
- 0.800000000 0.700000000 0.250000000
- 0.900000000 0.700000000 0.250000000
- 0.000000000 0.800000000 0.250000000
- 0.100000000 0.800000000 0.250000000
- 0.200000000 0.800000000 0.250000000
- 0.300000000 0.800000000 0.250000000
- 0.400000000 0.800000000 0.250000000
- 0.500000000 0.800000000 0.250000000
- 0.600000000 0.800000000 0.250000000
- 0.700000000 0.800000000 0.250000000
- 0.800000000 0.800000000 0.250000000
- 0.900000000 0.800000000 0.250000000
- 0.000000000 0.900000000 0.250000000
- 0.100000000 0.900000000 0.250000000
- 0.200000000 0.900000000 0.250000000
- 0.300000000 0.900000000 0.250000000
- 0.400000000 0.900000000 0.250000000
- 0.500000000 0.900000000 0.250000000
- 0.600000000 0.900000000 0.250000000
- 0.700000000 0.900000000 0.250000000
- 0.800000000 0.900000000 0.250000000
- 0.900000000 0.900000000 0.250000000
- 0.000000000 0.000000000 0.749999982
- 0.100000000 0.000000000 0.749999982
- 0.200000000 0.000000000 0.749999982
- 0.300000000 0.000000000 0.749999982
- 0.400000000 0.000000000 0.749999982
- 0.500000000 0.000000000 0.749999982
- 0.600000000 0.000000000 0.749999982
- 0.700000000 0.000000000 0.749999982
- 0.800000000 0.000000000 0.749999982
- 0.900000000 0.000000000 0.749999982
- 0.000000000 0.100000000 0.749999982
- 0.100000000 0.100000000 0.749999982
- 0.200000000 0.100000000 0.749999982
- 0.300000000 0.100000000 0.749999982
- 0.400000000 0.100000000 0.749999982
- 0.500000000 0.100000000 0.749999982
- 0.600000000 0.100000000 0.749999982
- 0.700000000 0.100000000 0.749999982
- 0.800000000 0.100000000 0.749999982
- 0.900000000 0.100000000 0.749999982
- 0.000000000 0.200000000 0.749999982
- 0.100000000 0.200000000 0.749999982
- 0.200000000 0.200000000 0.749999982
- 0.300000000 0.200000000 0.749999982
- 0.400000000 0.200000000 0.749999982
- 0.500000000 0.200000000 0.749999982
- 0.600000000 0.200000000 0.749999982
- 0.700000000 0.200000000 0.749999982
- 0.800000000 0.200000000 0.749999982
- 0.900000000 0.200000000 0.749999982
- 0.000000000 0.300000000 0.749999982
- 0.100000000 0.300000000 0.749999982
- 0.200000000 0.300000000 0.749999982
- 0.300000000 0.300000000 0.749999982
- 0.400000000 0.300000000 0.749999982
- 0.500000000 0.300000000 0.749999982
- 0.600000000 0.300000000 0.749999982
- 0.700000000 0.300000000 0.749999982
- 0.800000000 0.300000000 0.749999982
- 0.900000000 0.300000000 0.749999982
- 0.000000000 0.400000000 0.749999982
- 0.100000000 0.400000000 0.749999982
- 0.200000000 0.400000000 0.749999982
- 0.300000000 0.400000000 0.749999982
- 0.400000000 0.400000000 0.749999982
- 0.500000000 0.400000000 0.749999982
- 0.600000000 0.400000000 0.749999982
- 0.700000000 0.400000000 0.749999982
- 0.800000000 0.400000000 0.749999982
- 0.900000000 0.400000000 0.749999982
- 0.000000000 0.500000000 0.749999982
- 0.100000000 0.500000000 0.749999982
- 0.200000000 0.500000000 0.749999982
- 0.300000000 0.500000000 0.749999982
- 0.400000000 0.500000000 0.749999982
- 0.500000000 0.500000000 0.749999982
- 0.600000000 0.500000000 0.749999982
- 0.700000000 0.500000000 0.749999982
- 0.800000000 0.500000000 0.749999982
- 0.900000000 0.500000000 0.749999982
- 0.000000000 0.600000000 0.749999982
- 0.100000000 0.600000000 0.749999982
- 0.200000000 0.600000000 0.749999982
- 0.300000000 0.600000000 0.749999982
- 0.400000000 0.600000000 0.749999982
- 0.500000000 0.600000000 0.749999982
- 0.600000000 0.600000000 0.749999982
- 0.700000000 0.600000000 0.749999982
- 0.800000000 0.600000000 0.749999982
- 0.900000000 0.600000000 0.749999982
- 0.000000000 0.700000000 0.749999982
- 0.100000000 0.700000000 0.749999982
- 0.200000000 0.700000000 0.749999982
- 0.300000000 0.700000000 0.749999982
- 0.400000000 0.700000000 0.749999982
- 0.500000000 0.700000000 0.749999982
- 0.600000000 0.700000000 0.749999982
- 0.700000000 0.700000000 0.749999982
- 0.800000000 0.700000000 0.749999982
- 0.900000000 0.700000000 0.749999982
- 0.000000000 0.800000000 0.749999982
- 0.100000000 0.800000000 0.749999982
- 0.200000000 0.800000000 0.749999982
- 0.300000000 0.800000000 0.749999982
- 0.400000000 0.800000000 0.749999982
- 0.500000000 0.800000000 0.749999982
- 0.600000000 0.800000000 0.749999982
- 0.700000000 0.800000000 0.749999982
- 0.800000000 0.800000000 0.749999982
- 0.900000000 0.800000000 0.749999982
- 0.000000000 0.900000000 0.749999982
- 0.100000000 0.900000000 0.749999982
- 0.200000000 0.900000000 0.749999982
- 0.300000000 0.900000000 0.749999982
- 0.400000000 0.900000000 0.749999982
- 0.500000000 0.900000000 0.749999982
- 0.600000000 0.900000000 0.749999982
- 0.700000000 0.900000000 0.749999982
- 0.800000000 0.900000000 0.749999982
- 0.900000000 0.900000000 0.749999982
- 0.033333334 0.066666668 0.250000000
- 0.133333334 0.066666668 0.250000000
- 0.233333334 0.066666668 0.250000000
- 0.333333334 0.066666668 0.250000000
- 0.433333334 0.066666668 0.250000000
- 0.533333334 0.066666668 0.250000000
- 0.633333334 0.066666668 0.250000000
- 0.733333334 0.066666668 0.250000000
- 0.833333334 0.066666668 0.250000000
- 0.933333334 0.066666668 0.250000000
- 0.033333334 0.166666668 0.250000000
- 0.133333334 0.166666668 0.250000000
- 0.233333334 0.166666668 0.250000000
- 0.333333334 0.166666668 0.250000000
- 0.433333334 0.166666668 0.250000000
- 0.533333334 0.166666668 0.250000000
- 0.633333334 0.166666668 0.250000000
- 0.733333334 0.166666668 0.250000000
- 0.833333334 0.166666668 0.250000000
- 0.933333334 0.166666668 0.250000000
- 0.033333334 0.266666668 0.250000000
- 0.133333334 0.266666668 0.250000000
- 0.233333334 0.266666668 0.250000000
- 0.333333334 0.266666668 0.250000000
- 0.433333334 0.266666668 0.250000000
- 0.533333334 0.266666668 0.250000000
- 0.633333334 0.266666668 0.250000000
- 0.733333334 0.266666668 0.250000000
- 0.833333334 0.266666668 0.250000000
- 0.933333334 0.266666668 0.250000000
- 0.033333334 0.366666668 0.250000000
- 0.133333334 0.366666668 0.250000000
- 0.233333334 0.366666668 0.250000000
- 0.333333334 0.366666668 0.250000000
- 0.433333334 0.366666668 0.250000000
- 0.533333334 0.366666668 0.250000000
- 0.633333334 0.366666668 0.250000000
- 0.733333334 0.366666668 0.250000000
- 0.833333334 0.366666668 0.250000000
- 0.933333334 0.366666668 0.250000000
- 0.033333334 0.466666668 0.250000000
- 0.133333334 0.466666668 0.250000000
- 0.233333334 0.466666668 0.250000000
- 0.333333334 0.466666668 0.250000000
- 0.433333334 0.466666668 0.250000000
- 0.533333334 0.466666668 0.250000000
- 0.633333334 0.466666668 0.250000000
- 0.733333334 0.466666668 0.250000000
- 0.833333334 0.466666668 0.250000000
- 0.933333334 0.466666668 0.250000000
- 0.033333334 0.566666668 0.250000000
- 0.133333334 0.566666668 0.250000000
- 0.233333334 0.566666668 0.250000000
- 0.333333334 0.566666668 0.250000000
- 0.433333334 0.566666668 0.250000000
- 0.533333334 0.566666668 0.250000000
- 0.633333334 0.566666668 0.250000000
- 0.733333334 0.566666668 0.250000000
- 0.833333334 0.566666668 0.250000000
- 0.933333334 0.566666668 0.250000000
- 0.033333334 0.666666668 0.250000000
- 0.133333334 0.666666668 0.250000000
- 0.233333334 0.666666668 0.250000000
- 0.333333334 0.666666668 0.250000000
- 0.433333334 0.666666668 0.250000000
- 0.533333334 0.666666668 0.250000000
- 0.633333334 0.666666668 0.250000000
- 0.733333334 0.666666668 0.250000000
- 0.833333334 0.666666668 0.250000000
- 0.933333334 0.666666668 0.250000000
- 0.033333334 0.766666668 0.250000000
- 0.133333334 0.766666668 0.250000000
- 0.233333334 0.766666668 0.250000000
- 0.333333334 0.766666668 0.250000000
- 0.433333334 0.766666668 0.250000000
- 0.533333334 0.766666668 0.250000000
- 0.633333334 0.766666668 0.250000000
- 0.733333334 0.766666668 0.250000000
- 0.833333334 0.766666668 0.250000000
- 0.933333334 0.766666668 0.250000000
- 0.033333334 0.866666668 0.250000000
- 0.133333334 0.866666668 0.250000000
- 0.233333334 0.866666668 0.250000000
- 0.333333334 0.866666668 0.250000000
- 0.433333334 0.866666668 0.250000000
- 0.533333334 0.866666668 0.250000000
- 0.633333334 0.866666668 0.250000000
- 0.733333334 0.866666668 0.250000000
- 0.833333334 0.866666668 0.250000000
- 0.933333334 0.866666668 0.250000000
- 0.033333334 0.966666668 0.250000000
- 0.133333334 0.966666668 0.250000000
- 0.233333334 0.966666668 0.250000000
- 0.333333334 0.966666668 0.250000000
- 0.433333334 0.966666668 0.250000000
- 0.533333334 0.966666668 0.250000000
- 0.633333334 0.966666668 0.250000000
- 0.733333334 0.966666668 0.250000000
- 0.833333334 0.966666668 0.250000000
- 0.933333334 0.966666668 0.250000000
- 0.066666666 0.033333331 0.749999982
- 0.166666666 0.033333331 0.749999982
- 0.266666666 0.033333331 0.749999982
- 0.366666666 0.033333331 0.749999982
- 0.466666666 0.033333331 0.749999982
- 0.566666666 0.033333331 0.749999982
- 0.666666666 0.033333331 0.749999982
- 0.766666666 0.033333331 0.749999982
- 0.866666666 0.033333331 0.749999982
- 0.966666666 0.033333331 0.749999982
- 0.066666666 0.133333331 0.749999982
- 0.166666666 0.133333331 0.749999982
- 0.266666666 0.133333331 0.749999982
- 0.366666666 0.133333331 0.749999982
- 0.466666666 0.133333331 0.749999982
- 0.566666666 0.133333331 0.749999982
- 0.666666666 0.133333331 0.749999982
- 0.766666666 0.133333331 0.749999982
- 0.866666666 0.133333331 0.749999982
- 0.966666666 0.133333331 0.749999982
- 0.066666666 0.233333331 0.749999982
- 0.166666666 0.233333331 0.749999982
- 0.266666666 0.233333331 0.749999982
- 0.366666666 0.233333331 0.749999982
- 0.466666666 0.233333331 0.749999982
- 0.566666666 0.233333331 0.749999982
- 0.666666666 0.233333331 0.749999982
- 0.766666666 0.233333331 0.749999982
- 0.866666666 0.233333331 0.749999982
- 0.966666666 0.233333331 0.749999982
- 0.066666666 0.333333331 0.749999982
- 0.166666666 0.333333331 0.749999982
- 0.266666666 0.333333331 0.749999982
- 0.366666666 0.333333331 0.749999982
- 0.466666666 0.333333331 0.749999982
- 0.566666666 0.333333331 0.749999982
- 0.666666666 0.333333331 0.749999982
- 0.766666666 0.333333331 0.749999982
- 0.866666666 0.333333331 0.749999982
- 0.966666666 0.333333331 0.749999982
- 0.066666666 0.433333331 0.749999982
- 0.166666666 0.433333331 0.749999982
- 0.266666666 0.433333331 0.749999982
- 0.366666666 0.433333331 0.749999982
- 0.466666666 0.433333331 0.749999982
- 0.566666666 0.433333331 0.749999982
- 0.666666666 0.433333331 0.749999982
- 0.766666666 0.433333331 0.749999982
- 0.866666666 0.433333331 0.749999982
- 0.966666666 0.433333331 0.749999982
- 0.066666666 0.533333331 0.749999982
- 0.166666666 0.533333331 0.749999982
- 0.266666666 0.533333331 0.749999982
- 0.366666666 0.533333331 0.749999982
- 0.466666666 0.533333331 0.749999982
- 0.566666666 0.533333331 0.749999982
- 0.666666666 0.533333331 0.749999982
- 0.766666666 0.533333331 0.749999982
- 0.866666666 0.533333331 0.749999982
- 0.966666666 0.533333331 0.749999982
- 0.066666666 0.633333331 0.749999982
- 0.166666666 0.633333331 0.749999982
- 0.266666666 0.633333331 0.749999982
- 0.366666666 0.633333331 0.749999982
- 0.466666666 0.633333331 0.749999982
- 0.566666666 0.633333331 0.749999982
- 0.666666666 0.633333331 0.749999982
- 0.766666666 0.633333331 0.749999982
- 0.866666666 0.633333331 0.749999982
- 0.966666666 0.633333331 0.749999982
- 0.066666666 0.733333331 0.749999982
- 0.166666666 0.733333331 0.749999982
- 0.266666666 0.733333331 0.749999982
- 0.366666666 0.733333331 0.749999982
- 0.466666666 0.733333331 0.749999982
- 0.566666666 0.733333331 0.749999982
- 0.666666666 0.733333331 0.749999982
- 0.766666666 0.733333331 0.749999982
- 0.866666666 0.733333331 0.749999982
- 0.966666666 0.733333331 0.749999982
- 0.066666666 0.833333331 0.749999982
- 0.166666666 0.833333331 0.749999982
- 0.266666666 0.833333331 0.749999982
- 0.366666666 0.833333331 0.749999982
- 0.466666666 0.833333331 0.749999982
- 0.566666666 0.833333331 0.749999982
- 0.666666666 0.833333331 0.749999982
- 0.766666666 0.833333331 0.749999982
- 0.866666666 0.833333331 0.749999982
- 0.966666666 0.833333331 0.749999982
- 0.066666666 0.933333331 0.749999982
- 0.166666666 0.933333331 0.749999982
- 0.266666666 0.933333331 0.749999982
- 0.366666666 0.933333331 0.749999982
- 0.466666666 0.933333331 0.749999982
- 0.566666666 0.933333331 0.749999982
- 0.666666666 0.933333331 0.749999982
- 0.766666666 0.933333331 0.749999982
- 0.866666666 0.933333331 0.749999982
- 0.966666666 0.933333331 0.749999982
diff --git a/example/example_files/DC_MgO_hosts/POSCAR_1x1_5.4A_separation b/example/example_files/DC_MgO_hosts/POSCAR_1x1_5.4A_separation
deleted file mode 100644
index a18f5abf..00000000
--- a/example/example_files/DC_MgO_hosts/POSCAR_1x1_5.4A_separation
+++ /dev/null
@@ -1,17 +0,0 @@
-c1
- 1.00000000000000
- 2.4639999866000002 0.0000000000000000 0.0000000000000000
- -1.2319999933000001 2.1338865833999998 0.0000000000000000
- 0.0000000000000000 0.0000000000000000 10.7109999657000001
- C
- 4
-Direct
- 0.0000000000000000 0.0000000000000000 0.2500000000000000
- 0.0000000000000000 0.0000000000000000 0.7499999819999985
- 0.3333333400000029 0.6666666830000025 0.2500000000000000
- 0.6666666570000004 0.3333333140000008 0.7499999819999985
-
- 0.00000000E+00 0.00000000E+00 0.00000000E+00
- 0.00000000E+00 0.00000000E+00 0.00000000E+00
- 0.00000000E+00 0.00000000E+00 0.00000000E+00
- 0.00000000E+00 0.00000000E+00 0.00000000E+00
diff --git a/example/example_files/DC_MgO_hosts/POSCAR_1x5_orthorhombic_11.0A_separation b/example/example_files/DC_MgO_hosts/POSCAR_1x5_orthorhombic_11.0A_separation
deleted file mode 100644
index c55082f1..00000000
--- a/example/example_files/DC_MgO_hosts/POSCAR_1x5_orthorhombic_11.0A_separation
+++ /dev/null
@@ -1,48 +0,0 @@
-c1+mg1 o1
- 1.000000000
- 4.267773167 0.000000000 0.000000000
- -0.000000000 12.319999933 0.000000000
- 0.000000000 0.000000000 14.398580001
-C
-40
-Direct
- 0.000000000 0.000000000 0.000000000
- 0.000000000 0.200000000 0.000000000
- 0.000000000 0.400000000 0.000000000
- 0.000000000 0.600000000 0.000000000
- 0.000000000 0.800000000 0.000000000
- 0.500000000 0.100000000 0.000000000
- 0.500000000 0.300000000 0.000000000
- 0.500000000 0.500000000 0.000000000
- 0.500000000 0.700000000 0.000000000
- 0.500000000 0.900000000 0.000000000
- 0.000000000 0.000000000 0.766956196
- 0.000000000 0.200000000 0.766956196
- 0.000000000 0.400000000 0.766956196
- 0.000000000 0.600000000 0.766956196
- 0.000000000 0.800000000 0.766956196
- 0.500000000 0.100000000 0.766956196
- 0.500000000 0.300000000 0.766956196
- 0.500000000 0.500000000 0.766956196
- 0.500000000 0.700000000 0.766956196
- 0.500000000 0.900000000 0.766956196
- 0.333333342 1.000000000 0.000000000
- 0.333333342 0.200000000 0.000000000
- 0.333333342 0.400000000 0.000000000
- 0.333333342 0.600000000 0.000000000
- 0.333333342 0.800000000 0.000000000
- 0.833333342 0.100000000 0.000000000
- 0.833333342 0.300000000 0.000000000
- 0.833333342 0.500000000 0.000000000
- 0.833333342 0.700000000 0.000000000
- 0.833333342 0.900000000 0.000000000
- 0.166666657 0.100000000 0.766956196
- 0.166666657 0.300000000 0.766956196
- 0.166666657 0.500000000 0.766956196
- 0.166666657 0.700000000 0.766956196
- 0.166666657 0.900000000 0.766956196
- 0.666666657 0.000000000 0.766956196
- 0.666666657 0.200000000 0.766956196
- 0.666666657 0.400000000 0.766956196
- 0.666666657 0.600000000 0.766956196
- 0.666666657 0.800000000 0.766956196
\ No newline at end of file
diff --git a/example/example_files/DC_MgO_hosts/POSCAR_2x2_5.4A_separation b/example/example_files/DC_MgO_hosts/POSCAR_2x2_5.4A_separation
deleted file mode 100644
index 20995265..00000000
--- a/example/example_files/DC_MgO_hosts/POSCAR_2x2_5.4A_separation
+++ /dev/null
@@ -1,24 +0,0 @@
-c1
- 1.000000000
- 4.927999973 0.000000000 0.000000000
- -2.463999987 4.267773167 0.000000000
- 0.000000000 0.000000000 10.710999966
-C
-16
-Direct
- 0.000000000 0.000000000 0.250000000
- 0.500000000 0.000000000 0.250000000
- 0.000000000 0.500000000 0.250000000
- 0.500000000 0.500000000 0.250000000
- 0.000000000 0.000000000 0.749999982
- 0.500000000 0.000000000 0.749999982
- 0.000000000 0.500000000 0.749999982
- 0.500000000 0.500000000 0.749999982
- 0.166666670 0.333333342 0.250000000
- 0.666666670 0.333333342 0.250000000
- 0.166666670 0.833333342 0.250000000
- 0.666666670 0.833333342 0.250000000
- 0.333333329 0.166666657 0.749999982
- 0.833333329 0.166666657 0.749999982
- 0.333333329 0.666666657 0.749999982
- 0.833333329 0.666666657 0.749999982
diff --git a/example/example_files/DC_MgO_hosts/POSCAR_2x5_orthorhombic_11.0A_separation b/example/example_files/DC_MgO_hosts/POSCAR_2x5_orthorhombic_11.0A_separation
deleted file mode 100644
index 3e7dd7df..00000000
--- a/example/example_files/DC_MgO_hosts/POSCAR_2x5_orthorhombic_11.0A_separation
+++ /dev/null
@@ -1,88 +0,0 @@
-c1+mg1 o1
-1.0
- 8.5355463028 0.0000000000 0.0000000000
- 0.0000000000 12.3199996948 0.0000000000
- 0.0000000000 0.0000000000 14.3985795975
- C
- 80
-Direct
- 0.000000000 0.000000000 0.000000000
- 0.500000000 0.000000000 0.000000000
- 0.000000000 0.200000004 0.000000000
- 0.500000000 0.200000004 0.000000000
- 0.000000000 0.400000008 0.000000000
- 0.500000000 0.400000008 0.000000000
- 0.000000000 0.600000031 0.000000000
- 0.500000000 0.600000031 0.000000000
- 0.000000000 0.800000015 0.000000000
- 0.500000000 0.800000015 0.000000000
- 0.250000000 0.100000002 0.000000000
- 0.750000028 0.100000002 0.000000000
- 0.250000000 0.300000015 0.000000000
- 0.750000028 0.300000015 0.000000000
- 0.250000000 0.500000000 0.000000000
- 0.750000028 0.500000000 0.000000000
- 0.250000000 0.699999985 0.000000000
- 0.750000028 0.699999985 0.000000000
- 0.250000000 0.899999969 0.000000000
- 0.750000028 0.899999969 0.000000000
- -0.000000000 -0.000000000 0.766956230
- 0.500000000 -0.000000000 0.766956230
- -0.000000000 0.200000004 0.766956230
- 0.500000000 0.200000004 0.766956230
- -0.000000000 0.400000008 0.766956230
- 0.500000000 0.400000008 0.766956230
- 0.000000000 0.600000031 0.766956230
- 0.500000000 0.600000031 0.766956230
- 0.000000000 0.800000015 0.766956230
- 0.500000000 0.800000015 0.766956230
- 0.250000000 0.100000002 0.766956230
- 0.750000028 0.100000002 0.766956230
- 0.250000000 0.300000015 0.766956230
- 0.750000028 0.300000015 0.766956230
- 0.250000000 0.500000000 0.766956230
- 0.750000028 0.500000000 0.766956230
- 0.250000000 0.699999985 0.766956230
- 0.750000028 0.699999985 0.766956230
- 0.250000000 0.899999969 0.766956230
- 0.750000028 0.899999969 0.766956230
- 0.166666671 0.000000000 0.000000000
- 0.666666685 0.000000000 0.000000000
- 0.166666671 0.200000004 0.000000000
- 0.666666685 0.200000004 0.000000000
- 0.166666671 0.400000008 0.000000000
- 0.666666685 0.400000008 0.000000000
- 0.166666671 0.600000031 0.000000000
- 0.666666685 0.600000031 0.000000000
- 0.166666671 0.800000015 0.000000000
- 0.666666685 0.800000015 0.000000000
- 0.416666657 0.100000002 0.000000000
- 0.916666601 0.100000002 0.000000000
- 0.416666657 0.300000015 0.000000000
- 0.916666601 0.300000015 0.000000000
- 0.416666657 0.500000000 0.000000000
- 0.916666601 0.500000000 0.000000000
- 0.416666657 0.699999985 0.000000000
- 0.916666601 0.699999985 0.000000000
- 0.416666657 0.899999969 0.000000000
- 0.916666601 0.899999969 0.000000000
- 0.083333329 0.100000002 0.766956230
- 0.583333287 0.100000002 0.766956230
- 0.083333329 0.300000015 0.766956230
- 0.583333287 0.300000015 0.766956230
- 0.083333329 0.500000000 0.766956230
- 0.583333287 0.500000000 0.766956230
- 0.083333329 0.699999985 0.766956230
- 0.583333287 0.699999985 0.766956230
- 0.083333329 0.899999969 0.766956230
- 0.583333287 0.899999969 0.766956230
- 0.333333343 -0.000000000 0.766956230
- 0.833333371 -0.000000000 0.766956230
- 0.333333343 0.200000004 0.766956230
- 0.833333371 0.200000004 0.766956230
- 0.333333343 0.400000008 0.766956230
- 0.833333371 0.400000008 0.766956230
- 0.333333343 0.600000031 0.766956230
- 0.833333371 0.600000031 0.766956230
- 0.333333343 0.800000015 0.766956230
- 0.833333371 0.800000015 0.766956230
diff --git a/example/example_files/DC_MgO_hosts/POSCAR_3x3_11.0A_separation b/example/example_files/DC_MgO_hosts/POSCAR_3x3_11.0A_separation
deleted file mode 100644
index 29baf2d8..00000000
--- a/example/example_files/DC_MgO_hosts/POSCAR_3x3_11.0A_separation
+++ /dev/null
@@ -1,44 +0,0 @@
-c1
- 1.000000000
- 7.391999960 0.000000000 0.000000000
- -3.695999980 6.401659750 0.000000000
- 0.000000000 0.000000000 14.710999966
-C
-36
-Direct
- 0.000000000 0.000000000 0.000000000
- 0.333333333 0.000000000 0.000000000
- 0.666666667 0.000000000 0.000000000
- 0.000000000 0.333333333 0.000000000
- 0.333333333 0.333333333 0.000000000
- 0.666666667 0.333333333 0.000000000
- 0.000000000 0.666666667 0.000000000
- 0.333333333 0.666666667 0.000000000
- 0.666666667 0.666666667 0.000000000
- 0.000000000 0.000000000 0.749999982
- 0.333333333 0.000000000 0.749999982
- 0.666666667 0.000000000 0.749999982
- 0.000000000 0.333333333 0.749999982
- 0.333333333 0.333333333 0.749999982
- 0.666666667 0.333333333 0.749999982
- 0.000000000 0.666666667 0.749999982
- 0.333333333 0.666666667 0.749999982
- 0.666666667 0.666666667 0.749999982
- 0.111111113 0.222222228 0.000000000
- 0.444444447 0.222222228 0.000000000
- 0.777777780 0.222222228 0.000000000
- 0.111111113 0.555555561 0.000000000
- 0.444444447 0.555555561 0.000000000
- 0.777777780 0.555555561 0.000000000
- 0.111111113 0.888888894 0.000000000
- 0.444444447 0.888888894 0.000000000
- 0.777777780 0.888888894 0.000000000
- 0.222222219 0.111111105 0.749999982
- 0.555555552 0.111111105 0.749999982
- 0.888888886 0.111111105 0.749999982
- 0.222222219 0.444444438 0.749999982
- 0.555555552 0.444444438 0.749999982
- 0.888888886 0.444444438 0.749999982
- 0.222222219 0.777777771 0.749999982
- 0.555555552 0.777777771 0.749999982
- 0.888888886 0.777777771 0.749999982
diff --git a/example/example_files/DC_MgO_hosts/POSCAR_3x3_5.4A_separation b/example/example_files/DC_MgO_hosts/POSCAR_3x3_5.4A_separation
deleted file mode 100644
index cd93a31f..00000000
--- a/example/example_files/DC_MgO_hosts/POSCAR_3x3_5.4A_separation
+++ /dev/null
@@ -1,44 +0,0 @@
-c1
- 1.000000000
- 7.391999960 0.000000000 0.000000000
- -3.695999980 6.401659750 0.000000000
- 0.000000000 0.000000000 10.710999966
-C
-36
-Direct
- 0.000000000 0.000000000 0.250000000
- 0.333333333 0.000000000 0.250000000
- 0.666666667 0.000000000 0.250000000
- 0.000000000 0.333333333 0.250000000
- 0.333333333 0.333333333 0.250000000
- 0.666666667 0.333333333 0.250000000
- 0.000000000 0.666666667 0.250000000
- 0.333333333 0.666666667 0.250000000
- 0.666666667 0.666666667 0.250000000
- 0.000000000 0.000000000 0.749999982
- 0.333333333 0.000000000 0.749999982
- 0.666666667 0.000000000 0.749999982
- 0.000000000 0.333333333 0.749999982
- 0.333333333 0.333333333 0.749999982
- 0.666666667 0.333333333 0.749999982
- 0.000000000 0.666666667 0.749999982
- 0.333333333 0.666666667 0.749999982
- 0.666666667 0.666666667 0.749999982
- 0.111111113 0.222222228 0.250000000
- 0.444444447 0.222222228 0.250000000
- 0.777777780 0.222222228 0.250000000
- 0.111111113 0.555555561 0.250000000
- 0.444444447 0.555555561 0.250000000
- 0.777777780 0.555555561 0.250000000
- 0.111111113 0.888888894 0.250000000
- 0.444444447 0.888888894 0.250000000
- 0.777777780 0.888888894 0.250000000
- 0.222222219 0.111111105 0.749999982
- 0.555555552 0.111111105 0.749999982
- 0.888888886 0.111111105 0.749999982
- 0.222222219 0.444444438 0.749999982
- 0.555555552 0.444444438 0.749999982
- 0.888888886 0.444444438 0.749999982
- 0.222222219 0.777777771 0.749999982
- 0.555555552 0.777777771 0.749999982
- 0.888888886 0.777777771 0.749999982
diff --git a/example/example_files/DC_MgO_hosts/POSCAR_4x4_11.0A_separation b/example/example_files/DC_MgO_hosts/POSCAR_4x4_11.0A_separation
deleted file mode 100644
index 30f64a6f..00000000
--- a/example/example_files/DC_MgO_hosts/POSCAR_4x4_11.0A_separation
+++ /dev/null
@@ -1,72 +0,0 @@
-c1
- 1.000000000
- 9.855999947 0.000000000 0.000000000
- -4.927999973 8.535546333 0.000000000
- 0.000000000 0.000000000 14.710999966
-C
-64
-Direct
- 0.000000000 0.000000000 0.000000000
- 0.750000000 0.000000000 0.000000000
- 0.000000000 0.750000000 0.000000000
- 0.750000000 0.750000000 0.000000000
- 0.250000000 0.000000000 0.000000000
- 0.250000000 0.750000000 0.000000000
- 0.500000000 0.000000000 0.000000000
- 0.500000000 0.750000000 0.000000000
- 0.000000000 0.250000000 0.000000000
- 0.750000000 0.250000000 0.000000000
- 0.250000000 0.250000000 0.000000000
- 0.500000000 0.250000000 0.000000000
- 0.000000000 0.500000000 0.000000000
- 0.750000000 0.500000000 0.000000000
- 0.250000000 0.500000000 0.000000000
- 0.500000000 0.500000000 0.000000000
- 0.000000000 0.000000000 0.749999982
- 0.750000000 0.000000000 0.749999982
- 0.000000000 0.750000000 0.749999982
- 0.750000000 0.750000000 0.749999982
- 0.250000000 0.000000000 0.749999982
- 0.250000000 0.750000000 0.749999982
- 0.500000000 0.000000000 0.749999982
- 0.500000000 0.750000000 0.749999982
- 0.000000000 0.250000000 0.749999982
- 0.750000000 0.250000000 0.749999982
- 0.250000000 0.250000000 0.749999982
- 0.500000000 0.250000000 0.749999982
- 0.000000000 0.500000000 0.749999982
- 0.750000000 0.500000000 0.749999982
- 0.250000000 0.500000000 0.749999982
- 0.500000000 0.500000000 0.749999982
- 0.083333335 0.166666671 0.000000000
- 0.833333335 0.166666671 0.000000000
- 0.083333335 0.916666671 0.000000000
- 0.833333335 0.916666671 0.000000000
- 0.333333335 0.166666671 0.000000000
- 0.333333335 0.916666671 0.000000000
- 0.583333335 0.166666671 0.000000000
- 0.583333335 0.916666671 0.000000000
- 0.083333335 0.416666671 0.000000000
- 0.833333335 0.416666671 0.000000000
- 0.333333335 0.416666671 0.000000000
- 0.583333335 0.416666671 0.000000000
- 0.083333335 0.666666671 0.000000000
- 0.833333335 0.666666671 0.000000000
- 0.333333335 0.666666671 0.000000000
- 0.583333335 0.666666671 0.000000000
- 0.166666664 0.083333329 0.749999982
- 0.916666664 0.083333329 0.749999982
- 0.166666664 0.833333329 0.749999982
- 0.916666664 0.833333329 0.749999982
- 0.416666664 0.083333329 0.749999982
- 0.416666664 0.833333329 0.749999982
- 0.666666665 0.083333329 0.749999982
- 0.666666665 0.833333329 0.749999982
- 0.166666664 0.333333329 0.749999982
- 0.916666664 0.333333329 0.749999982
- 0.416666664 0.333333329 0.749999982
- 0.666666665 0.333333329 0.749999982
- 0.166666664 0.583333328 0.749999982
- 0.916666664 0.583333328 0.749999982
- 0.416666664 0.583333328 0.749999982
- 0.666666665 0.583333328 0.749999982
diff --git a/example/example_files/DC_MgO_hosts/POSCAR_4x4_14.7A_separation b/example/example_files/DC_MgO_hosts/POSCAR_4x4_14.7A_separation
deleted file mode 100644
index 1113bb09..00000000
--- a/example/example_files/DC_MgO_hosts/POSCAR_4x4_14.7A_separation
+++ /dev/null
@@ -1,72 +0,0 @@
-c1
- 1.000000000
- 9.855999947 0.000000000 0.000000000
- -4.927999973 8.535546333 0.000000000
- 0.000000000 0.000000000 18.388833288
-C
-64
-Direct
- 0.000000000 0.000000000 0.000000000
- 0.750000000 0.000000000 0.000000000
- 0.000000000 0.750000000 0.000000000
- 0.750000000 0.750000000 0.000000000
- 0.250000000 0.000000000 0.000000000
- 0.250000000 0.750000000 0.000000000
- 0.500000000 0.000000000 0.000000000
- 0.500000000 0.750000000 0.000000000
- 0.000000000 0.250000000 0.000000000
- 0.750000000 0.250000000 0.000000000
- 0.250000000 0.250000000 0.000000000
- 0.500000000 0.250000000 0.000000000
- 0.000000000 0.500000000 0.000000000
- 0.750000000 0.500000000 0.000000000
- 0.250000000 0.500000000 0.000000000
- 0.500000000 0.500000000 0.000000000
- 0.000000000 0.000000000 0.800000892
- 0.750000000 0.000000000 0.800000892
- 0.000000000 0.750000000 0.800000892
- 0.750000000 0.750000000 0.800000892
- 0.250000000 0.000000000 0.800000892
- 0.250000000 0.750000000 0.800000892
- 0.500000000 0.000000000 0.800000892
- 0.500000000 0.750000000 0.800000892
- 0.000000000 0.250000000 0.800000892
- 0.750000000 0.250000000 0.800000892
- 0.250000000 0.250000000 0.800000892
- 0.500000000 0.250000000 0.800000892
- 0.000000000 0.500000000 0.800000892
- 0.750000000 0.500000000 0.800000892
- 0.250000000 0.500000000 0.800000892
- 0.500000000 0.500000000 0.800000892
- 0.083333335 0.166666671 0.000000000
- 0.833333335 0.166666671 0.000000000
- 0.083333335 0.916666671 0.000000000
- 0.833333335 0.916666671 0.000000000
- 0.333333335 0.166666671 0.000000000
- 0.333333335 0.916666671 0.000000000
- 0.583333335 0.166666671 0.000000000
- 0.583333335 0.916666671 0.000000000
- 0.083333335 0.416666671 0.000000000
- 0.833333335 0.416666671 0.000000000
- 0.333333335 0.416666671 0.000000000
- 0.583333335 0.416666671 0.000000000
- 0.083333335 0.666666671 0.000000000
- 0.833333335 0.666666671 0.000000000
- 0.333333335 0.666666671 0.000000000
- 0.583333335 0.666666671 0.000000000
- 0.166666664 0.083333329 0.800000892
- 0.916666664 0.083333329 0.800000892
- 0.166666664 0.833333329 0.800000892
- 0.916666664 0.833333329 0.800000892
- 0.416666664 0.083333329 0.800000892
- 0.416666664 0.833333329 0.800000892
- 0.666666665 0.083333329 0.800000892
- 0.666666665 0.833333329 0.800000892
- 0.166666664 0.333333329 0.800000892
- 0.916666664 0.333333329 0.800000892
- 0.416666664 0.333333329 0.800000892
- 0.666666665 0.333333329 0.800000892
- 0.166666664 0.583333328 0.800000892
- 0.916666664 0.583333328 0.800000892
- 0.416666664 0.583333328 0.800000892
- 0.666666665 0.583333328 0.800000892
diff --git a/example/example_files/DC_MgO_hosts/POSCAR_5x1_5.4A_separation b/example/example_files/DC_MgO_hosts/POSCAR_5x1_5.4A_separation
deleted file mode 100644
index cbcc836d..00000000
--- a/example/example_files/DC_MgO_hosts/POSCAR_5x1_5.4A_separation
+++ /dev/null
@@ -1,28 +0,0 @@
-c1
- 1.000000000
- 12.319999933 0.000000000 0.000000000
- -1.231999993 2.133886583 0.000000000
- 0.000000000 0.000000000 10.710999966
-C
-20
-Direct
- 0.000000000 0.000000000 0.250000000
- 0.200000000 0.000000000 0.250000000
- 0.400000000 0.000000000 0.250000000
- 0.600000000 0.000000000 0.250000000
- 0.800000000 0.000000000 0.250000000
- 0.000000000 0.000000000 0.749999982
- 0.200000000 0.000000000 0.749999982
- 0.400000000 0.000000000 0.749999982
- 0.600000000 0.000000000 0.749999982
- 0.800000000 0.000000000 0.749999982
- 0.066666668 0.666666683 0.250000000
- 0.266666668 0.666666683 0.250000000
- 0.466666668 0.666666683 0.250000000
- 0.666666668 0.666666683 0.250000000
- 0.866666668 0.666666683 0.250000000
- 0.133333331 0.333333314 0.749999982
- 0.333333331 0.333333314 0.749999982
- 0.533333331 0.333333314 0.749999982
- 0.733333331 0.333333314 0.749999982
- 0.933333331 0.333333314 0.749999982
diff --git a/example/example_files/DC_MgO_hosts/POSCAR_5x1_6.0A_separation b/example/example_files/DC_MgO_hosts/POSCAR_5x1_6.0A_separation
deleted file mode 100644
index d335f3a7..00000000
--- a/example/example_files/DC_MgO_hosts/POSCAR_5x1_6.0A_separation
+++ /dev/null
@@ -1,108 +0,0 @@
-c1
- 1.000000000
- 12.319999933 0.000000000 0.000000000
- -6.159999967 10.669432917 0.000000000
- 0.000000000 0.000000000 12.029835
-C
-100
-Direct
- 0.000000000 0.000000000 0.250000000
- 0.200000000 0.000000000 0.250000000
- 0.400000000 0.000000000 0.250000000
- 0.600000000 0.000000000 0.250000000
- 0.800000000 0.000000000 0.250000000
- 0.000000000 0.200000000 0.250000000
- 0.200000000 0.200000000 0.250000000
- 0.400000000 0.200000000 0.250000000
- 0.600000000 0.200000000 0.250000000
- 0.800000000 0.200000000 0.250000000
- 0.000000000 0.400000000 0.250000000
- 0.200000000 0.400000000 0.250000000
- 0.400000000 0.400000000 0.250000000
- 0.600000000 0.400000000 0.250000000
- 0.800000000 0.400000000 0.250000000
- 0.000000000 0.600000000 0.250000000
- 0.200000000 0.600000000 0.250000000
- 0.400000000 0.600000000 0.250000000
- 0.600000000 0.600000000 0.250000000
- 0.800000000 0.600000000 0.250000000
- 0.000000000 0.800000000 0.250000000
- 0.200000000 0.800000000 0.250000000
- 0.400000000 0.800000000 0.250000000
- 0.600000000 0.800000000 0.250000000
- 0.800000000 0.800000000 0.250000000
- 0.000000000 0.000000000 0.749999982
- 0.200000000 0.000000000 0.749999982
- 0.400000000 0.000000000 0.749999982
- 0.600000000 0.000000000 0.749999982
- 0.800000000 0.000000000 0.749999982
- 0.000000000 0.200000000 0.749999982
- 0.200000000 0.200000000 0.749999982
- 0.400000000 0.200000000 0.749999982
- 0.600000000 0.200000000 0.749999982
- 0.800000000 0.200000000 0.749999982
- 0.000000000 0.400000000 0.749999982
- 0.200000000 0.400000000 0.749999982
- 0.400000000 0.400000000 0.749999982
- 0.600000000 0.400000000 0.749999982
- 0.800000000 0.400000000 0.749999982
- 0.000000000 0.600000000 0.749999982
- 0.200000000 0.600000000 0.749999982
- 0.400000000 0.600000000 0.749999982
- 0.600000000 0.600000000 0.749999982
- 0.800000000 0.600000000 0.749999982
- 0.000000000 0.800000000 0.749999982
- 0.200000000 0.800000000 0.749999982
- 0.400000000 0.800000000 0.749999982
- 0.600000000 0.800000000 0.749999982
- 0.800000000 0.800000000 0.749999982
- 0.066666668 0.133333337 0.250000000
- 0.266666668 0.133333337 0.250000000
- 0.466666668 0.133333337 0.250000000
- 0.666666668 0.133333337 0.250000000
- 0.866666668 0.133333337 0.250000000
- 0.066666668 0.333333337 0.250000000
- 0.266666668 0.333333337 0.250000000
- 0.466666668 0.333333337 0.250000000
- 0.666666668 0.333333337 0.250000000
- 0.866666668 0.333333337 0.250000000
- 0.066666668 0.533333337 0.250000000
- 0.266666668 0.533333337 0.250000000
- 0.466666668 0.533333337 0.250000000
- 0.666666668 0.533333337 0.250000000
- 0.866666668 0.533333337 0.250000000
- 0.066666668 0.733333337 0.250000000
- 0.266666668 0.733333337 0.250000000
- 0.466666668 0.733333337 0.250000000
- 0.666666668 0.733333337 0.250000000
- 0.866666668 0.733333337 0.250000000
- 0.066666668 0.933333337 0.250000000
- 0.266666668 0.933333337 0.250000000
- 0.466666668 0.933333337 0.250000000
- 0.666666668 0.933333337 0.250000000
- 0.866666668 0.933333337 0.250000000
- 0.133333331 0.066666663 0.749999982
- 0.333333331 0.066666663 0.749999982
- 0.533333331 0.066666663 0.749999982
- 0.733333331 0.066666663 0.749999982
- 0.933333331 0.066666663 0.749999982
- 0.133333331 0.266666663 0.749999982
- 0.333333331 0.266666663 0.749999982
- 0.533333331 0.266666663 0.749999982
- 0.733333331 0.266666663 0.749999982
- 0.933333331 0.266666663 0.749999982
- 0.133333331 0.466666663 0.749999982
- 0.333333331 0.466666663 0.749999982
- 0.533333331 0.466666663 0.749999982
- 0.733333331 0.466666663 0.749999982
- 0.933333331 0.466666663 0.749999982
- 0.133333331 0.666666663 0.749999982
- 0.333333331 0.666666663 0.749999982
- 0.533333331 0.666666663 0.749999982
- 0.733333331 0.666666663 0.749999982
- 0.933333331 0.666666663 0.749999982
- 0.133333331 0.866666663 0.749999982
- 0.333333331 0.866666663 0.749999982
- 0.533333331 0.866666663 0.749999982
- 0.733333331 0.866666663 0.749999982
- 0.933333331 0.866666663 0.749999982
diff --git a/example/example_files/DC_MgO_hosts/POSCAR_6x6_5.4A_separation b/example/example_files/DC_MgO_hosts/POSCAR_6x6_5.4A_separation
deleted file mode 100644
index a98f071f..00000000
--- a/example/example_files/DC_MgO_hosts/POSCAR_6x6_5.4A_separation
+++ /dev/null
@@ -1,152 +0,0 @@
-c1
- 1.000000000
- 14.783999920 0.000000000 0.000000000
- -7.391999960 12.803319500 0.000000000
- 0.000000000 0.000000000 10.710999966
-C
-144
-Direct
- 0.000000000 0.000000000 0.250000000
- 0.500000000 0.000000000 0.250000000
- 0.000000000 0.500000000 0.250000000
- 0.500000000 0.500000000 0.250000000
- 0.166666667 0.000000000 0.250000000
- 0.666666667 0.000000000 0.250000000
- 0.166666667 0.500000000 0.250000000
- 0.666666667 0.500000000 0.250000000
- 0.333333333 0.000000000 0.250000000
- 0.833333333 0.000000000 0.250000000
- 0.333333333 0.500000000 0.250000000
- 0.833333333 0.500000000 0.250000000
- 0.000000000 0.166666667 0.250000000
- 0.500000000 0.166666667 0.250000000
- 0.000000000 0.666666667 0.250000000
- 0.500000000 0.666666667 0.250000000
- 0.166666667 0.166666667 0.250000000
- 0.666666667 0.166666667 0.250000000
- 0.166666667 0.666666667 0.250000000
- 0.666666667 0.666666667 0.250000000
- 0.333333333 0.166666667 0.250000000
- 0.833333333 0.166666667 0.250000000
- 0.333333333 0.666666667 0.250000000
- 0.833333333 0.666666667 0.250000000
- 0.000000000 0.333333333 0.250000000
- 0.500000000 0.333333333 0.250000000
- 0.000000000 0.833333333 0.250000000
- 0.500000000 0.833333333 0.250000000
- 0.166666667 0.333333333 0.250000000
- 0.666666667 0.333333333 0.250000000
- 0.166666667 0.833333333 0.250000000
- 0.666666667 0.833333333 0.250000000
- 0.333333333 0.333333333 0.250000000
- 0.833333333 0.333333333 0.250000000
- 0.333333333 0.833333333 0.250000000
- 0.833333333 0.833333333 0.250000000
- 0.000000000 0.000000000 0.749999982
- 0.500000000 0.000000000 0.749999982
- 0.000000000 0.500000000 0.749999982
- 0.500000000 0.500000000 0.749999982
- 0.166666667 0.000000000 0.749999982
- 0.666666667 0.000000000 0.749999982
- 0.166666667 0.500000000 0.749999982
- 0.666666667 0.500000000 0.749999982
- 0.333333333 0.000000000 0.749999982
- 0.833333333 0.000000000 0.749999982
- 0.333333333 0.500000000 0.749999982
- 0.833333333 0.500000000 0.749999982
- 0.000000000 0.166666667 0.749999982
- 0.500000000 0.166666667 0.749999982
- 0.000000000 0.666666667 0.749999982
- 0.500000000 0.666666667 0.749999982
- 0.166666667 0.166666667 0.749999982
- 0.666666667 0.166666667 0.749999982
- 0.166666667 0.666666667 0.749999982
- 0.666666667 0.666666667 0.749999982
- 0.333333333 0.166666667 0.749999982
- 0.833333333 0.166666667 0.749999982
- 0.333333333 0.666666667 0.749999982
- 0.833333333 0.666666667 0.749999982
- 0.000000000 0.333333333 0.749999982
- 0.500000000 0.333333333 0.749999982
- 0.000000000 0.833333333 0.749999982
- 0.500000000 0.833333333 0.749999982
- 0.166666667 0.333333333 0.749999982
- 0.666666667 0.333333333 0.749999982
- 0.166666667 0.833333333 0.749999982
- 0.666666667 0.833333333 0.749999982
- 0.333333333 0.333333333 0.749999982
- 0.833333333 0.333333333 0.749999982
- 0.333333333 0.833333333 0.749999982
- 0.833333333 0.833333333 0.749999982
- 0.055555556 0.111111114 0.250000000
- 0.555555556 0.111111114 0.250000000
- 0.055555556 0.611111114 0.250000000
- 0.555555556 0.611111114 0.250000000
- 0.222222224 0.111111114 0.250000000
- 0.722222223 0.111111114 0.250000000
- 0.222222224 0.611111114 0.250000000
- 0.722222223 0.611111114 0.250000000
- 0.388888890 0.111111114 0.250000000
- 0.888888890 0.111111114 0.250000000
- 0.388888890 0.611111114 0.250000000
- 0.888888890 0.611111114 0.250000000
- 0.055555556 0.277777781 0.250000000
- 0.555555556 0.277777781 0.250000000
- 0.055555556 0.777777781 0.250000000
- 0.555555556 0.777777781 0.250000000
- 0.222222224 0.277777781 0.250000000
- 0.722222223 0.277777781 0.250000000
- 0.222222224 0.777777781 0.250000000
- 0.722222223 0.777777781 0.250000000
- 0.388888890 0.277777781 0.250000000
- 0.888888890 0.277777781 0.250000000
- 0.388888890 0.777777781 0.250000000
- 0.888888890 0.777777781 0.250000000
- 0.055555556 0.444444447 0.250000000
- 0.555555556 0.444444447 0.250000000
- 0.055555556 0.944444447 0.250000000
- 0.555555556 0.944444447 0.250000000
- 0.222222224 0.444444447 0.250000000
- 0.722222223 0.444444447 0.250000000
- 0.222222224 0.944444447 0.250000000
- 0.722222223 0.944444447 0.250000000
- 0.388888890 0.444444447 0.250000000
- 0.888888890 0.444444447 0.250000000
- 0.388888890 0.944444447 0.250000000
- 0.888888890 0.944444447 0.250000000
- 0.111111109 0.055555553 0.749999982
- 0.611111110 0.055555553 0.749999982
- 0.111111109 0.555555552 0.749999982
- 0.611111110 0.555555552 0.749999982
- 0.277777776 0.055555553 0.749999982
- 0.777777776 0.055555553 0.749999982
- 0.277777776 0.555555552 0.749999982
- 0.777777776 0.555555552 0.749999982
- 0.444444443 0.055555553 0.749999982
- 0.944444443 0.055555553 0.749999982
- 0.444444443 0.555555552 0.749999982
- 0.944444443 0.555555552 0.749999982
- 0.111111109 0.222222219 0.749999982
- 0.611111110 0.222222219 0.749999982
- 0.111111109 0.722222219 0.749999982
- 0.611111110 0.722222219 0.749999982
- 0.277777776 0.222222219 0.749999982
- 0.777777776 0.222222219 0.749999982
- 0.277777776 0.722222219 0.749999982
- 0.777777776 0.722222219 0.749999982
- 0.444444443 0.222222219 0.749999982
- 0.944444443 0.222222219 0.749999982
- 0.444444443 0.722222219 0.749999982
- 0.944444443 0.722222219 0.749999982
- 0.111111109 0.388888886 0.749999982
- 0.611111110 0.388888886 0.749999982
- 0.111111109 0.888888886 0.749999982
- 0.611111110 0.888888886 0.749999982
- 0.277777776 0.388888886 0.749999982
- 0.777777776 0.388888886 0.749999982
- 0.277777776 0.888888886 0.749999982
- 0.777777776 0.888888886 0.749999982
- 0.444444443 0.388888886 0.749999982
- 0.944444443 0.388888886 0.749999982
- 0.444444443 0.888888886 0.749999982
- 0.944444443 0.888888886 0.749999982
diff --git a/example/example_files/DC_MgO_hosts/POSCAR_7x7_8.4A_separation b/example/example_files/DC_MgO_hosts/POSCAR_7x7_8.4A_separation
deleted file mode 100644
index 701c643a..00000000
--- a/example/example_files/DC_MgO_hosts/POSCAR_7x7_8.4A_separation
+++ /dev/null
@@ -1,204 +0,0 @@
-c1
- 1.000000000
- 17.247999906 0.000000000 0.000000000
- -8.623999953 14.937206084 0.000000000
- 0.000000000 0.000000000 12.02983500
-C
-196
-Direct
- 0.000000000 0.000000000 0.000000000
- 0.142857143 0.000000000 0.000000000
- 0.285714286 0.000000000 0.000000000
- 0.428571429 0.000000000 0.000000000
- 0.571428571 0.000000000 0.000000000
- 0.714285714 0.000000000 0.000000000
- 0.857142857 0.000000000 0.000000000
- 0.000000000 0.142857143 0.000000000
- 0.142857143 0.142857143 0.000000000
- 0.285714286 0.142857143 0.000000000
- 0.428571429 0.142857143 0.000000000
- 0.571428571 0.142857143 0.000000000
- 0.714285714 0.142857143 0.000000000
- 0.857142857 0.142857143 0.000000000
- 0.000000000 0.285714286 0.000000000
- 0.142857143 0.285714286 0.000000000
- 0.285714286 0.285714286 0.000000000
- 0.428571429 0.285714286 0.000000000
- 0.571428571 0.285714286 0.000000000
- 0.714285714 0.285714286 0.000000000
- 0.857142857 0.285714286 0.000000000
- 0.000000000 0.428571429 0.000000000
- 0.142857143 0.428571429 0.000000000
- 0.285714286 0.428571429 0.000000000
- 0.428571429 0.428571429 0.000000000
- 0.571428571 0.428571429 0.000000000
- 0.714285714 0.428571429 0.000000000
- 0.857142857 0.428571429 0.000000000
- 0.000000000 0.571428571 0.000000000
- 0.142857143 0.571428571 0.000000000
- 0.285714286 0.571428571 0.000000000
- 0.428571429 0.571428571 0.000000000
- 0.571428571 0.571428571 0.000000000
- 0.714285714 0.571428571 0.000000000
- 0.857142857 0.571428571 0.000000000
- 0.000000000 0.714285714 0.000000000
- 0.142857143 0.714285714 0.000000000
- 0.285714286 0.714285714 0.000000000
- 0.428571429 0.714285714 0.000000000
- 0.571428571 0.714285714 0.000000000
- 0.714285714 0.714285714 0.000000000
- 0.857142857 0.714285714 0.000000000
- 0.000000000 0.857142857 0.000000000
- 0.142857143 0.857142857 0.000000000
- 0.285714286 0.857142857 0.000000000
- 0.428571429 0.857142857 0.000000000
- 0.571428571 0.857142857 0.000000000
- 0.714285714 0.857142857 0.000000000
- 0.857142857 0.857142857 0.000000000
- 0.000000000 0.000000000 0.69428092808
- 0.142857143 0.000000000 0.69428092808
- 0.285714286 0.000000000 0.69428092808
- 0.428571429 0.000000000 0.69428092808
- 0.571428571 0.000000000 0.69428092808
- 0.714285714 0.000000000 0.69428092808
- 0.857142857 0.000000000 0.69428092808
- 0.000000000 0.142857143 0.69428092808
- 0.142857143 0.142857143 0.69428092808
- 0.285714286 0.142857143 0.69428092808
- 0.428571429 0.142857143 0.69428092808
- 0.571428571 0.142857143 0.69428092808
- 0.714285714 0.142857143 0.69428092808
- 0.857142857 0.142857143 0.69428092808
- 0.000000000 0.285714286 0.69428092808
- 0.142857143 0.285714286 0.69428092808
- 0.285714286 0.285714286 0.69428092808
- 0.428571429 0.285714286 0.69428092808
- 0.571428571 0.285714286 0.69428092808
- 0.714285714 0.285714286 0.69428092808
- 0.857142857 0.285714286 0.69428092808
- 0.000000000 0.428571429 0.69428092808
- 0.142857143 0.428571429 0.69428092808
- 0.285714286 0.428571429 0.69428092808
- 0.428571429 0.428571429 0.69428092808
- 0.571428571 0.428571429 0.69428092808
- 0.714285714 0.428571429 0.69428092808
- 0.857142857 0.428571429 0.69428092808
- 0.000000000 0.571428571 0.69428092808
- 0.142857143 0.571428571 0.69428092808
- 0.285714286 0.571428571 0.69428092808
- 0.428571429 0.571428571 0.69428092808
- 0.571428571 0.571428571 0.69428092808
- 0.714285714 0.571428571 0.69428092808
- 0.857142857 0.571428571 0.69428092808
- 0.000000000 0.714285714 0.69428092808
- 0.142857143 0.714285714 0.69428092808
- 0.285714286 0.714285714 0.69428092808
- 0.428571429 0.714285714 0.69428092808
- 0.571428571 0.714285714 0.69428092808
- 0.714285714 0.714285714 0.69428092808
- 0.857142857 0.714285714 0.69428092808
- 0.000000000 0.857142857 0.69428092808
- 0.142857143 0.857142857 0.69428092808
- 0.285714286 0.857142857 0.69428092808
- 0.428571429 0.857142857 0.69428092808
- 0.571428571 0.857142857 0.69428092808
- 0.714285714 0.857142857 0.69428092808
- 0.857142857 0.857142857 0.69428092808
- 0.047619049 0.095238098 0.000000000
- 0.190476191 0.095238098 0.000000000
- 0.333333334 0.095238098 0.000000000
- 0.476190477 0.095238098 0.000000000
- 0.619047620 0.095238098 0.000000000
- 0.761904763 0.095238098 0.000000000
- 0.904761906 0.095238098 0.000000000
- 0.047619049 0.238095240 0.000000000
- 0.190476191 0.238095240 0.000000000
- 0.333333334 0.238095240 0.000000000
- 0.476190477 0.238095240 0.000000000
- 0.619047620 0.238095240 0.000000000
- 0.761904763 0.238095240 0.000000000
- 0.904761906 0.238095240 0.000000000
- 0.047619049 0.380952383 0.000000000
- 0.190476191 0.380952383 0.000000000
- 0.333333334 0.380952383 0.000000000
- 0.476190477 0.380952383 0.000000000
- 0.619047620 0.380952383 0.000000000
- 0.761904763 0.380952383 0.000000000
- 0.904761906 0.380952383 0.000000000
- 0.047619049 0.523809526 0.000000000
- 0.190476191 0.523809526 0.000000000
- 0.333333334 0.523809526 0.000000000
- 0.476190477 0.523809526 0.000000000
- 0.619047620 0.523809526 0.000000000
- 0.761904763 0.523809526 0.000000000
- 0.904761906 0.523809526 0.000000000
- 0.047619049 0.666666669 0.000000000
- 0.190476191 0.666666669 0.000000000
- 0.333333334 0.666666669 0.000000000
- 0.476190477 0.666666669 0.000000000
- 0.619047620 0.666666669 0.000000000
- 0.761904763 0.666666669 0.000000000
- 0.904761906 0.666666669 0.000000000
- 0.047619049 0.809523812 0.000000000
- 0.190476191 0.809523812 0.000000000
- 0.333333334 0.809523812 0.000000000
- 0.476190477 0.809523812 0.000000000
- 0.619047620 0.809523812 0.000000000
- 0.761904763 0.809523812 0.000000000
- 0.904761906 0.809523812 0.000000000
- 0.047619049 0.952380955 0.000000000
- 0.190476191 0.952380955 0.000000000
- 0.333333334 0.952380955 0.000000000
- 0.476190477 0.952380955 0.000000000
- 0.619047620 0.952380955 0.000000000
- 0.761904763 0.952380955 0.000000000
- 0.904761906 0.952380955 0.000000000
- 0.095238094 0.047619045 0.69428092808
- 0.238095237 0.047619045 0.69428092808
- 0.380952380 0.047619045 0.69428092808
- 0.523809522 0.047619045 0.69428092808
- 0.666666665 0.047619045 0.69428092808
- 0.809523808 0.047619045 0.69428092808
- 0.952380951 0.047619045 0.69428092808
- 0.095238094 0.190476188 0.69428092808
- 0.238095237 0.190476188 0.69428092808
- 0.380952380 0.190476188 0.69428092808
- 0.523809522 0.190476188 0.69428092808
- 0.666666665 0.190476188 0.69428092808
- 0.809523808 0.190476188 0.69428092808
- 0.952380951 0.190476188 0.69428092808
- 0.095238094 0.333333331 0.69428092808
- 0.238095237 0.333333331 0.69428092808
- 0.380952380 0.333333331 0.69428092808
- 0.523809522 0.333333331 0.69428092808
- 0.666666665 0.333333331 0.69428092808
- 0.809523808 0.333333331 0.69428092808
- 0.952380951 0.333333331 0.69428092808
- 0.095238094 0.476190473 0.69428092808
- 0.238095237 0.476190473 0.69428092808
- 0.380952380 0.476190473 0.69428092808
- 0.523809522 0.476190473 0.69428092808
- 0.666666665 0.476190473 0.69428092808
- 0.809523808 0.476190473 0.69428092808
- 0.952380951 0.476190473 0.69428092808
- 0.095238094 0.619047616 0.69428092808
- 0.238095237 0.619047616 0.69428092808
- 0.380952380 0.619047616 0.69428092808
- 0.523809522 0.619047616 0.69428092808
- 0.666666665 0.619047616 0.69428092808
- 0.809523808 0.619047616 0.69428092808
- 0.952380951 0.619047616 0.69428092808
- 0.095238094 0.761904759 0.69428092808
- 0.238095237 0.761904759 0.69428092808
- 0.380952380 0.761904759 0.69428092808
- 0.523809522 0.761904759 0.69428092808
- 0.666666665 0.761904759 0.69428092808
- 0.809523808 0.761904759 0.69428092808
- 0.952380951 0.761904759 0.69428092808
- 0.095238094 0.904761902 0.69428092808
- 0.238095237 0.904761902 0.69428092808
- 0.380952380 0.904761902 0.69428092808
- 0.523809522 0.904761902 0.69428092808
- 0.666666665 0.904761902 0.69428092808
- 0.809523808 0.904761902 0.69428092808
- 0.952380951 0.904761902 0.69428092808
diff --git a/example/example_files/DC_MgO_hosts/POSCAR_MgO_HEX b/example/example_files/DC_MgO_hosts/POSCAR_MgO_HEX
deleted file mode 100644
index cd191e18..00000000
--- a/example/example_files/DC_MgO_hosts/POSCAR_MgO_HEX
+++ /dev/null
@@ -1,204 +0,0 @@
-Mg2 O2
-1.0
- 24.639999866 0.0000000000 0.0000000000
- -12.319999933 21.338865834 0.0000000000
- 0.0000000000 0.0000000000 4.2310647964
- Mg O
- 98 98
-Direct
- 0.095238142 0.047618996 0.750000000
- 0.095238142 0.190476134 0.750000000
- 0.095238142 0.333333284 0.750000000
- 0.095238142 0.476190418 0.750000000
- 0.095238142 0.619047582 0.750000000
- 0.095238142 0.761904716 0.750000000
- 0.095238142 0.904761851 0.750000000
- 0.238095284 0.047618996 0.750000000
- 0.238095284 0.190476134 0.750000000
- 0.238095284 0.333333284 0.750000000
- 0.238095284 0.476190418 0.750000000
- 0.238095284 0.619047582 0.750000000
- 0.238095284 0.761904716 0.750000000
- 0.238095284 0.904761851 0.750000000
- 0.380952418 0.047618996 0.750000000
- 0.380952418 0.190476134 0.750000000
- 0.380952418 0.333333284 0.750000000
- 0.380952418 0.476190418 0.750000000
- 0.380952418 0.619047582 0.750000000
- 0.380952418 0.761904716 0.750000000
- 0.380952418 0.904761851 0.750000000
- 0.523809552 0.047618996 0.750000000
- 0.523809552 0.190476134 0.750000000
- 0.523809552 0.333333284 0.750000000
- 0.523809552 0.476190418 0.750000000
- 0.523809552 0.619047582 0.750000000
- 0.523809552 0.761904716 0.750000000
- 0.523809552 0.904761851 0.750000000
- 0.666666687 0.047618996 0.750000000
- 0.666666687 0.190476134 0.750000000
- 0.666666687 0.333333284 0.750000000
- 0.666666687 0.476190418 0.750000000
- 0.666666687 0.619047582 0.750000000
- 0.666666687 0.761904716 0.750000000
- 0.666666687 0.904761851 0.750000000
- 0.809523880 0.047618996 0.750000000
- 0.809523880 0.190476134 0.750000000
- 0.809523880 0.333333284 0.750000000
- 0.809523880 0.476190418 0.750000000
- 0.809523880 0.619047582 0.750000000
- 0.809523880 0.761904716 0.750000000
- 0.809523880 0.904761851 0.750000000
- 0.952381015 0.047618996 0.750000000
- 0.952381015 0.190476134 0.750000000
- 0.952381015 0.333333284 0.750000000
- 0.952381015 0.476190418 0.750000000
- 0.952381015 0.619047582 0.750000000
- 0.952381015 0.761904716 0.750000000
- 0.952381015 0.904761851 0.750000000
- 0.047618996 0.095238142 0.250000000
- 0.047618996 0.238095284 0.250000000
- 0.047618996 0.380952418 0.250000000
- 0.047618996 0.523809552 0.250000000
- 0.047618996 0.666666687 0.250000000
- 0.047618996 0.809523880 0.250000000
- 0.047618996 0.952381015 0.250000000
- 0.190476134 0.095238142 0.250000000
- 0.190476134 0.238095284 0.250000000
- 0.190476134 0.380952418 0.250000000
- 0.190476134 0.523809552 0.250000000
- 0.190476134 0.666666687 0.250000000
- 0.190476134 0.809523880 0.250000000
- 0.190476134 0.952381015 0.250000000
- 0.333333284 0.095238142 0.250000000
- 0.333333284 0.238095284 0.250000000
- 0.333333284 0.380952418 0.250000000
- 0.333333284 0.523809552 0.250000000
- 0.333333284 0.666666687 0.250000000
- 0.333333284 0.809523880 0.250000000
- 0.333333284 0.952381015 0.250000000
- 0.476190418 0.095238142 0.250000000
- 0.476190418 0.238095284 0.250000000
- 0.476190418 0.380952418 0.250000000
- 0.476190418 0.523809552 0.250000000
- 0.476190418 0.666666687 0.250000000
- 0.476190418 0.809523880 0.250000000
- 0.476190418 0.952381015 0.250000000
- 0.619047582 0.095238142 0.250000000
- 0.619047582 0.238095284 0.250000000
- 0.619047582 0.380952418 0.250000000
- 0.619047582 0.523809552 0.250000000
- 0.619047582 0.666666687 0.250000000
- 0.619047582 0.809523880 0.250000000
- 0.619047582 0.952381015 0.250000000
- 0.761904716 0.095238142 0.250000000
- 0.761904716 0.238095284 0.250000000
- 0.761904716 0.380952418 0.250000000
- 0.761904716 0.523809552 0.250000000
- 0.761904716 0.666666687 0.250000000
- 0.761904716 0.809523880 0.250000000
- 0.761904716 0.952381015 0.250000000
- 0.904761851 0.095238142 0.250000000
- 0.904761851 0.238095284 0.250000000
- 0.904761851 0.380952418 0.250000000
- 0.904761851 0.523809552 0.250000000
- 0.904761851 0.666666687 0.250000000
- 0.904761851 0.809523880 0.250000000
- 0.904761851 0.952381015 0.250000000
- 0.095238142 0.047618996 0.250000000
- 0.095238142 0.190476134 0.250000000
- 0.095238142 0.333333284 0.250000000
- 0.095238142 0.476190418 0.250000000
- 0.095238142 0.619047582 0.250000000
- 0.095238142 0.761904716 0.250000000
- 0.095238142 0.904761851 0.250000000
- 0.238095284 0.047618996 0.250000000
- 0.238095284 0.190476134 0.250000000
- 0.238095284 0.333333284 0.250000000
- 0.238095284 0.476190418 0.250000000
- 0.238095284 0.619047582 0.250000000
- 0.238095284 0.761904716 0.250000000
- 0.238095284 0.904761851 0.250000000
- 0.380952418 0.047618996 0.250000000
- 0.380952418 0.190476134 0.250000000
- 0.380952418 0.333333284 0.250000000
- 0.380952418 0.476190418 0.250000000
- 0.380952418 0.619047582 0.250000000
- 0.380952418 0.761904716 0.250000000
- 0.380952418 0.904761851 0.250000000
- 0.523809552 0.047618996 0.250000000
- 0.523809552 0.190476134 0.250000000
- 0.523809552 0.333333284 0.250000000
- 0.523809552 0.476190418 0.250000000
- 0.523809552 0.619047582 0.250000000
- 0.523809552 0.761904716 0.250000000
- 0.523809552 0.904761851 0.250000000
- 0.666666687 0.047618996 0.250000000
- 0.666666687 0.190476134 0.250000000
- 0.666666687 0.333333284 0.250000000
- 0.666666687 0.476190418 0.250000000
- 0.666666687 0.619047582 0.250000000
- 0.666666687 0.761904716 0.250000000
- 0.666666687 0.904761851 0.250000000
- 0.809523880 0.047618996 0.250000000
- 0.809523880 0.190476134 0.250000000
- 0.809523880 0.333333284 0.250000000
- 0.809523880 0.476190418 0.250000000
- 0.809523880 0.619047582 0.250000000
- 0.809523880 0.761904716 0.250000000
- 0.809523880 0.904761851 0.250000000
- 0.952381015 0.047618996 0.250000000
- 0.952381015 0.190476134 0.250000000
- 0.952381015 0.333333284 0.250000000
- 0.952381015 0.476190418 0.250000000
- 0.952381015 0.619047582 0.250000000
- 0.952381015 0.761904716 0.250000000
- 0.952381015 0.904761851 0.250000000
- 0.047618996 0.095238142 0.750000000
- 0.047618996 0.238095284 0.750000000
- 0.047618996 0.380952418 0.750000000
- 0.047618996 0.523809552 0.750000000
- 0.047618996 0.666666687 0.750000000
- 0.047618996 0.809523880 0.750000000
- 0.047618996 0.952381015 0.750000000
- 0.190476134 0.095238142 0.750000000
- 0.190476134 0.238095284 0.750000000
- 0.190476134 0.380952418 0.750000000
- 0.190476134 0.523809552 0.750000000
- 0.190476134 0.666666687 0.750000000
- 0.190476134 0.809523880 0.750000000
- 0.190476134 0.952381015 0.750000000
- 0.333333284 0.095238142 0.750000000
- 0.333333284 0.238095284 0.750000000
- 0.333333284 0.380952418 0.750000000
- 0.333333284 0.523809552 0.750000000
- 0.333333284 0.666666687 0.750000000
- 0.333333284 0.809523880 0.750000000
- 0.333333284 0.952381015 0.750000000
- 0.476190418 0.095238142 0.750000000
- 0.476190418 0.238095284 0.750000000
- 0.476190418 0.380952418 0.750000000
- 0.476190418 0.523809552 0.750000000
- 0.476190418 0.666666687 0.750000000
- 0.476190418 0.809523880 0.750000000
- 0.476190418 0.952381015 0.750000000
- 0.619047582 0.095238142 0.750000000
- 0.619047582 0.238095284 0.750000000
- 0.619047582 0.380952418 0.750000000
- 0.619047582 0.523809552 0.750000000
- 0.619047582 0.666666687 0.750000000
- 0.619047582 0.809523880 0.750000000
- 0.619047582 0.952381015 0.750000000
- 0.761904716 0.095238142 0.750000000
- 0.761904716 0.238095284 0.750000000
- 0.761904716 0.380952418 0.750000000
- 0.761904716 0.523809552 0.750000000
- 0.761904716 0.666666687 0.750000000
- 0.761904716 0.809523880 0.750000000
- 0.761904716 0.952381015 0.750000000
- 0.904761851 0.095238142 0.750000000
- 0.904761851 0.238095284 0.750000000
- 0.904761851 0.380952418 0.750000000
- 0.904761851 0.523809552 0.750000000
- 0.904761851 0.666666687 0.750000000
- 0.904761851 0.809523880 0.750000000
- 0.904761851 0.952381015 0.750000000
diff --git a/example/example_files/DC_MgO_hosts/POSCAR_orthorhombic_11.1A_separation_Mg_seeded b/example/example_files/DC_MgO_hosts/POSCAR_orthorhombic_11.1A_separation_Mg_seeded
deleted file mode 100644
index 5d2659c3..00000000
--- a/example/example_files/DC_MgO_hosts/POSCAR_orthorhombic_11.1A_separation_Mg_seeded
+++ /dev/null
@@ -1,50 +0,0 @@
-c1+mg1 o1
- 1.000000000
- 4.267773167 0.000000000 0.000000000
- -0.000000000 12.319999933 0.000000000
- 0.000000000 0.000000000 14.398580001
-C Mg
-40 2
-Direct
- 0.000000000 0.000000000 0.000000000
- 0.000000000 0.200000000 0.000000000
- 0.000000000 0.400000000 0.000000000
- 0.000000000 0.600000000 0.000000000
- 0.000000000 0.800000000 0.000000000
- 0.500000000 0.100000000 0.000000000
- 0.500000000 0.300000000 0.000000000
- 0.500000000 0.500000000 0.000000000
- 0.500000000 0.700000000 0.000000000
- 0.500000000 0.900000000 0.000000000
- 0.000000000 0.000000000 0.766956196
- 0.000000000 0.200000000 0.766956196
- 0.000000000 0.400000000 0.766956196
- 0.000000000 0.600000000 0.766956196
- 0.000000000 0.800000000 0.766956196
- 0.500000000 0.100000000 0.766956196
- 0.500000000 0.300000000 0.766956196
- 0.500000000 0.500000000 0.766956196
- 0.500000000 0.700000000 0.766956196
- 0.500000000 0.900000000 0.766956196
- 0.333333342 1.000000000 0.000000000
- 0.333333342 0.200000000 0.000000000
- 0.333333342 0.400000000 0.000000000
- 0.333333342 0.600000000 0.000000000
- 0.333333342 0.800000000 0.000000000
- 0.833333342 0.100000000 0.000000000
- 0.833333342 0.300000000 0.000000000
- 0.833333342 0.500000000 0.000000000
- 0.833333342 0.700000000 0.000000000
- 0.833333342 0.900000000 0.000000000
- 0.166666657 0.100000000 0.766956196
- 0.166666657 0.300000000 0.766956196
- 0.166666657 0.500000000 0.766956196
- 0.166666657 0.700000000 0.766956196
- 0.166666657 0.900000000 0.766956196
- 0.666666657 0.000000000 0.766956196
- 0.666666657 0.200000000 0.766956196
- 0.666666657 0.400000000 0.766956196
- 0.666666657 0.600000000 0.766956196
- 0.666666657 0.800000000 0.766956196
- 0.500000000 0.500000000 0.384000000
- 0.500000000 0.250000000 0.192000000
\ No newline at end of file
diff --git a/example/example_files/POSCAR_graphite_missing_layer b/example/example_files/POSCAR_graphite_missing_layer
deleted file mode 100644
index 024e65f9..00000000
--- a/example/example_files/POSCAR_graphite_missing_layer
+++ /dev/null
@@ -1,15 +0,0 @@
-C
- 1.000000000
- 1.233645631 -2.136736911 0.000000000
- 1.233645631 2.136736911 0.000000000
- 0.000000000 0.000000000 15.606146000
-C
-6
-Direct
- 0.000000000 0.000000000 0.125000000
- 0.000000000 0.000000000 0.375000000
- 0.000000000 0.000000000 0.875000000
- 0.333333333 0.666666667 0.125000000
- 0.666666667 0.333333333 0.375000000
- 0.666666667 0.333333333 0.875000000
-
diff --git a/example/example_files/POSCAR_host_BaTiO3 b/example/example_files/POSCAR_host_BaTiO3
deleted file mode 100644
index d8f60a12..00000000
--- a/example/example_files/POSCAR_host_BaTiO3
+++ /dev/null
@@ -1,13 +0,0 @@
-BaTiO3
-1.0
-4.01 0.00 0.00
-0.00 4.01 0.00
-0.00 0.00 8.02
-Ba Ti O
-1 1 3
-Direct
-0.0 0.0 0.0
-0.5 0.5 0.25
-0.5 0.5 0.0
-0.5 0.0 0.25
-0.0 0.5 0.25
\ No newline at end of file
diff --git a/example/example_files/POSCAR_host_diamond b/example/example_files/POSCAR_host_diamond
deleted file mode 100644
index 11242071..00000000
--- a/example/example_files/POSCAR_host_diamond
+++ /dev/null
@@ -1,16 +0,0 @@
-C8
- 1.000000000
- 3.560745109 0.000000000 0.000000000
- 0.000000000 3.560745109 0.000000000
- 0.000000000 0.000000000 7.121490218
-C
-8
-Direct
- 0.000000000 0.000000000 0.000000000
- 0.500000000 0.500000000 0.000000000
- 0.500000000 0.000000000 0.250000000
- 0.000000000 0.500000000 0.250000000
- 0.250000000 0.250000000 0.125000000
- 0.750000000 0.750000000 0.125000000
- 0.750000000 0.250000000 0.375000000
- 0.250000000 0.750000000 0.375000000
diff --git a/example/example_files/POSCAR_host_graphene b/example/example_files/POSCAR_host_graphene
deleted file mode 100644
index f5d05414..00000000
--- a/example/example_files/POSCAR_host_graphene
+++ /dev/null
@@ -1,26 +0,0 @@
-C4
- 1.000000000
- 3.700936892 -6.410210733 0.000000000
- 3.700936892 6.410210733 0.000000000
- 0.000000000 0.000000000 7.803073000
-C
-18
-Direct
- 0.000000000 0.000000000 0.250000000
- 0.333333333 0.000000000 0.250000000
- 0.666666667 0.000000000 0.250000000
- 0.000000000 0.333333333 0.250000000
- 0.333333333 0.333333333 0.250000000
- 0.666666667 0.333333333 0.250000000
- 0.000000000 0.666666667 0.250000000
- 0.333333333 0.666666667 0.250000000
- 0.666666667 0.666666667 0.250000000
- 0.111111111 0.222222222 0.250000000
- 0.444444444 0.222222222 0.250000000
- 0.777777778 0.222222222 0.250000000
- 0.111111111 0.555555556 0.250000000
- 0.444444444 0.555555556 0.250000000
- 0.777777778 0.555555556 0.250000000
- 0.111111111 0.888888889 0.250000000
- 0.444444444 0.888888889 0.250000000
- 0.777777778 0.888888889 0.250000000
\ No newline at end of file
diff --git a/example/example_files/POSCAR_host_graphite_vacancy b/example/example_files/POSCAR_host_graphite_vacancy
deleted file mode 100644
index 4fb28784..00000000
--- a/example/example_files/POSCAR_host_graphite_vacancy
+++ /dev/null
@@ -1,44 +0,0 @@
-C4
- 1.000000000
- 3.700936892 -6.410210733 0.000000000
- 3.700936892 6.410210733 0.000000000
- 0.000000000 0.000000000 7.803073000
-C
-35
-Direct
- 0.000000000 0.000000000 0.250000000
- 0.333333333 0.000000000 0.250000000
- 0.666666667 0.000000000 0.250000000
- 0.000000000 0.333333333 0.250000000
- 0.333333333 0.333333333 0.250000000
- 0.666666667 0.333333333 0.250000000
- 0.000000000 0.666666667 0.250000000
- 0.333333333 0.666666667 0.250000000
- 0.666666667 0.666666667 0.250000000
- 0.000000000 0.000000000 0.750000000
- 0.333333333 0.000000000 0.750000000
- 0.666666667 0.000000000 0.750000000
- 0.000000000 0.333333333 0.750000000
- 0.333333333 0.333333333 0.750000000
- 0.666666667 0.333333333 0.750000000
- 0.000000000 0.666666667 0.750000000
- 0.333333333 0.666666667 0.750000000
- 0.666666667 0.666666667 0.750000000
- 0.111111111 0.222222222 0.250000000
- 0.444444444 0.222222222 0.250000000
- 0.777777778 0.222222222 0.250000000
- 0.111111111 0.555555556 0.250000000
- 0.444444444 0.555555556 0.250000000
- 0.777777778 0.555555556 0.250000000
- 0.111111111 0.888888889 0.250000000
- 0.444444444 0.888888889 0.250000000
- 0.777777778 0.888888889 0.250000000
- 0.222222222 0.111111111 0.750000000
- 0.555555556 0.111111111 0.750000000
- 0.888888889 0.111111111 0.750000000
- 0.222222222 0.444444444 0.750000000
- 0.555555556 0.444444444 0.750000000
- 0.888888889 0.444444444 0.750000000
- 0.222222222 0.777777778 0.750000000
- 0.555555556 0.777777778 0.750000000
-
diff --git a/example/example_files/POSCAR_host_perovskites b/example/example_files/POSCAR_host_perovskites
deleted file mode 100644
index ed4d3847..00000000
--- a/example/example_files/POSCAR_host_perovskites
+++ /dev/null
@@ -1,49 +0,0 @@
-BTO
-1.0
- 4.0008373260 0.0000000000 0.0000000000
- 0.0000000000 4.0008373260 0.0000000000
- 0.0000000000 0.0000000000 64.0403900146
- Ba Sr Ti O
- 4 4 8 24
-Direct
- 0.000000000 0.000000000 0.000000000
- 0.000000000 0.000000000 0.062500000
- 0.000000000 0.000000000 0.125000000
- 0.000000000 0.000000000 0.187500000
- 0.000000000 0.000000000 0.500000000
- 0.000000000 0.000000000 0.562500000
- 0.000000000 0.000000000 0.625000000
- 0.000000000 0.000000000 0.687500000
- 0.500000000 0.500000000 0.031250000
- 0.500000000 0.500000000 0.093750000
- 0.500000000 0.500000000 0.156250000
- 0.500000000 0.500000000 0.218750000
- 0.500000000 0.500000000 0.531250000
- 0.500000000 0.500000000 0.593750000
- 0.500000000 0.500000000 0.656250000
- 0.500000000 0.500000000 0.718750000
- 0.500000000 0.000000000 0.031250000
- 0.500000000 0.000000000 0.093750000
- 0.500000000 0.000000000 0.156250000
- 0.500000000 0.000000000 0.218750000
- 0.500000000 0.000000000 0.531250000
- 0.500000000 0.000000000 0.593750000
- 0.500000000 0.000000000 0.656250000
- 0.500000000 0.000000000 0.718750000
- 0.000000000 0.500000000 0.031250000
- 0.000000000 0.500000000 0.093750000
- 0.000000000 0.500000000 0.156250000
- 0.000000000 0.500000000 0.218750000
- 0.000000000 0.500000000 0.531250000
- 0.000000000 0.500000000 0.593750000
- 0.000000000 0.500000000 0.656250000
- 0.000000000 0.500000000 0.718750000
- 0.500000000 0.500000000 0.000000000
- 0.500000000 0.500000000 0.062500000
- 0.500000000 0.500000000 0.125000000
- 0.500000000 0.500000000 0.187500000
- 0.500000000 0.500000000 0.500000000
- 0.500000000 0.500000000 0.562500000
- 0.500000000 0.500000000 0.625000000
- 0.500000000 0.500000000 0.687500000
-
diff --git a/example/executable/param.in b/example/fortran_exe/param.in
similarity index 100%
rename from example/executable/param.in
rename to example/fortran_exe/param.in
diff --git a/example/executable/run.sh b/example/fortran_exe/run.sh
similarity index 100%
rename from example/executable/run.sh
rename to example/fortran_exe/run.sh
diff --git a/example/python_pkg/Al_learn/learn.py b/example/python_pkg/Al_learn/learn.py
new file mode 100644
index 00000000..6edac5b1
--- /dev/null
+++ b/example/python_pkg/Al_learn/learn.py
@@ -0,0 +1,212 @@
+from mace.calculators import mace_mp
+from raffle.generator import raffle_generator
+from ase import build, Atoms
+from ase.optimize import BFGS
+from ase.io import write
+import numpy as np
+import os
+from concurrent.futures import ProcessPoolExecutor
+
+
+def process_structure(i, atoms, num_structures_old, calc, optimise_structure):
+ if i < num_structures_old:
+ return
+
+ inew = i - num_structures_old
+ atoms.calc = calc
+ positions_initial = atoms.get_positions()
+
+ # Calculate and save the initial energy per atom
+ energy_unrlxd = atoms.get_potential_energy() / len(atoms)
+
+ # Optimise the structure if requested
+ if optimise_structure:
+ optimizer = BFGS(atoms, trajectory = f"traje{inew}.traj", logfile=f"optimisation{inew}.log")
+ optimizer.run(fmax=0.05, steps=500)
+
+ # Save the optimised structure and its energy per atom
+ energy_rlxd = atoms.get_potential_energy() / len(atoms)
+
+ # Get the distance matrix
+ distances = atoms.get_all_distances(mic=True)
+
+ # Set self-distances (diagonal entries) to infinity to ignore them
+ np.fill_diagonal(distances, np.inf)
+
+ # Check if the minimum non-self distance is below 1.5
+ if distances.min() < 1.5:
+ print(f"Distance too small: {atoms.get_all_distances(mic=True).min()}")
+ return None, None, None
+
+ if abs(energy_rlxd - energy_unrlxd) > 5.0:
+ print(f"Energy difference too large: {energy_rlxd} vs {energy_unrlxd}")
+ return None, None, None
+
+ return atoms, energy_unrlxd, energy_rlxd
+
+# crystal_structures = [
+# 'sc', 'fcc', 'bcc', 'hcp',
+# 'diamond', 'zincblende', 'rocksalt', 'cesiumchloride',
+# 'fluorite', 'wurtzite', 'tetragonal', 'orthorhombic',
+# 'bct', 'rhombohedral', 'mcl'
+# ]
+
+
+
+if __name__ == "__main__":
+
+ calc = mace_mp(model="medium", dispersion=False, default_dtype="float32", device='cpu')
+
+ crystal_structures = [
+ 'orthorhombic', 'diamond',
+ 'bct', 'sc',
+ 'fcc', 'bcc', 'hcp',
+ ]
+
+ hosts = []
+ for crystal_structure in crystal_structures:
+ print(f'Crystal structure: {crystal_structure}')
+ for a in [5.0, 6.0, 7.0, 8.0, 9.0, 10.0]:
+ b = a
+ c = a
+ atom = build.bulk(
+ name = 'Al',
+ crystalstructure = crystal_structure,
+ a = a,
+ b = b,
+ c = c,
+ )
+ hosts.append(Atoms('Al', positions=[(0, 0, 0)]))
+ hosts[-1].set_cell(atom.get_cell())
+ hosts[-1].calc = calc
+ print(hosts[-1])
+
+
+ generator = raffle_generator()
+ generator.distributions.set_element_energies(
+ {
+ 'Al': 0.0
+ }
+ )
+ # set energy scale
+ generator.distributions.set_kBT(0.4)
+ # set the distribution function widths (2-body, 3-body, 4-body)
+ generator.distributions.set_width([0.025, np.pi/200.0, np.pi/200.0])
+
+ initial_database = [Atoms('Al', positions=[(0, 0, 0)], cell=[5, 5, 5])]
+ initial_database[0].calc = calc
+
+ generator.distributions.create(initial_database)
+
+ if os.path.exists("energies_rlxd.txt"):
+ with open("energies_rlxd.txt", "w") as energy_file:
+ pass
+ else:
+ open("energies_rlxd.txt", "w").close()
+
+ if os.path.exists("energies_unrlxd.txt"):
+ with open("energies_unrlxd.txt", "w") as energy_file:
+ pass
+ else:
+ open("energies_unrlxd.txt", "w").close()
+ seed = -1
+ num_structures_old = 0
+ optimise_structure = True
+ mass = 26.9815385
+ for host in hosts:
+ print("setting host")
+ generator.set_host(host)
+ volume = host.get_volume()
+ for num_atoms in range(1, 20):
+
+ density = ( num_atoms + 1 ) * mass / volume
+ if density > 2.2: # aluminium density is 2.7 g/cm^3 ~= 1.61 u/A^3
+ print("Density too high:", density, "u/A^3")
+ continue
+ elif density < 1.0:
+ print("Density too low", density, "u/A^3")
+ continue
+
+ seed += 1
+ print(f"Seed: {seed}")
+ generator.generate(
+ num_structures = 5,
+ stoichiometry = { 'Al': num_atoms },
+ seed = seed,
+ method_probab = {"void": 1.0, "rand": 1.0, "walk": 1.0, "grow": 0.0, "min": 1.0},
+ verbose = 0,
+ )
+
+ # print the number of structures generated
+ print("Total number of structures generated: ", generator.num_structures)
+ generated_structures = generator.get_structures()
+ num_structures_new = len(generated_structures)
+
+ # check if directory iteration[iter] exists, if not create it
+ iterdir = f"iteration{seed}/"
+ if not os.path.exists(iterdir):
+ os.makedirs(iterdir)
+
+ # set up list of energies
+ energy_unrlxd = np.zeros(num_structures_new - num_structures_old)
+ energy_rlxd = np.zeros(num_structures_new - num_structures_old)
+
+ # Parallel execution
+ with ProcessPoolExecutor() as executor:
+ futures = [
+ executor.submit(process_structure, i, generated_structures[i], num_structures_old, calc, optimise_structure)
+ for i in range(num_structures_old, num_structures_new)
+ ]
+
+ # Wait for all futures to complete
+ for j, future in enumerate(futures):
+ generated_structures[j+num_structures_old], energy_unrlxd[j], energy_rlxd[j] = future.result()
+
+ # Remove structures that failed the checks
+ for j, atoms in reversed(list(enumerate(generated_structures))):
+ if atoms is None:
+ energy_unrlxd = np.delete(energy_unrlxd, j-num_structures_old)
+ energy_rlxd = np.delete(energy_rlxd, j-num_structures_old)
+ del generated_structures[j]
+ generator.remove_structure(j)
+ num_structures_new = len(generated_structures)
+
+ # write the structures to files
+ for i in range(num_structures_new - num_structures_old):
+ write(iterdir+f"POSCAR_{i}", generated_structures[num_structures_old + i])
+ print(f"Structure {i} energy per atom: {energy_rlxd[i]}")
+ # append energy per atom to the energies_unrlxd.txt file
+ with open("energies_unrlxd.txt", "a") as energy_file:
+ energy_file.write(f"{energy_unrlxd[i]}\n")
+ # append energy per atom to the energies_rlxd.txt file
+ with open("energies_rlxd.txt", "a") as energy_file:
+ energy_file.write(f"{energy_rlxd[i]}\n")
+
+ # update the distribution functions
+ print("Updating distributions")
+ generator.distributions.update(generated_structures[num_structures_old:], from_host=False, deallocate_systems=False)
+
+ # print the new distribution functions to a file
+ print("Printing distributions")
+ generator.distributions.write_dfs(iterdir+"distributions.txt")
+ generator.distributions.write_2body(iterdir+"df2.txt")
+ generator.distributions.write_3body(iterdir+"df3.txt")
+ generator.distributions.write_4body(iterdir+"df4.txt")
+
+ # update the number of structures generated
+ num_structures_old = num_structures_new
+
+ generator.distributions.write_gdfs("gdfs.txt")
+
+ # Read energies from the file
+ with open("energies_rlxd.txt", "r") as energy_file:
+ energies = energy_file.readlines()
+
+ # Parse and sort the energies
+ energies = [line.strip().split() for line in energies]
+ energies = sorted(energies, key=lambda x: float(x[0]))
+
+ # Write the sorted energies back to the file
+ with open("energies_ordered.txt", "w") as energy_file:
+ for entry in energies:
+ energy_file.write(f"{entry[0]}\n")
\ No newline at end of file
diff --git a/example/wrapper/run_BaTiO3.py b/example/python_pkg/BaTiO3/run.py
similarity index 98%
rename from example/wrapper/run_BaTiO3.py
rename to example/python_pkg/BaTiO3/run.py
index be211da1..a947d970 100644
--- a/example/wrapper/run_BaTiO3.py
+++ b/example/python_pkg/BaTiO3/run.py
@@ -27,7 +27,7 @@
# read the host structure from a POSCAR file
print("Reading host")
-host = read("../example_files/POSCAR_host_BaTiO3")
+host = read("POSCAR_host")
host.calc = calculator
print("host energy: ", host.get_potential_energy())
@@ -98,7 +98,7 @@
print("Reading database")
use_database = False
if use_database:
- database = read("../example_files/database_perovskites/database.xyz", index=":")
+ database = read("database.xyz", index=":")
for i, atoms in enumerate(database):
# reset energy to use CHGNet
atoms.calc = calculator
diff --git a/example/wrapper/run.py b/example/python_pkg/C-MgO/run.py
similarity index 97%
rename from example/wrapper/run.py
rename to example/python_pkg/C-MgO/run.py
index 3f2d7b82..fa4385c4 100644
--- a/example/wrapper/run.py
+++ b/example/python_pkg/C-MgO/run.py
@@ -25,7 +25,7 @@
generator = raffle_generator()
print("Reading host")
-host = read("../example_files/DC_MgO_hosts/POSCAR_1x5_orthorhombic_11.0A_separation")
+host = read("hosts/POSCAR_1x5_orthorhombic_11.0A_separation")
host.calc = calculator
print("host energy: ", host.get_potential_energy())
@@ -67,7 +67,7 @@
generator.distributions.set_radius_distance_tol([1.5, 2.5, 3.0, 6.0])
print("Reading database")
-database = read("../example_files/database/database.xyz", index=":")
+database = read("database.xyz", index=":")
num_database = len(database)
print("Database read")
diff --git a/example/python_pkg/C_learn/learn.py b/example/python_pkg/C_learn/learn.py
new file mode 100644
index 00000000..b840030f
--- /dev/null
+++ b/example/python_pkg/C_learn/learn.py
@@ -0,0 +1,258 @@
+from mace.calculators import mace_mp
+from raffle.generator import raffle_generator
+from ase import build, Atoms
+from ase.optimize import BFGS, FIRE
+from ase.io import write
+import numpy as np
+import os
+from concurrent.futures import ProcessPoolExecutor, wait, as_completed
+from multiprocessing import Process
+from copy import deepcopy
+from multiprocessing import Queue
+from joblib import Parallel, delayed
+
+import logging
+logging.basicConfig(level=logging.DEBUG)
+
+def runInParallel(*fns):
+ proc = []
+ results = []
+ for fn in fns:
+ p = Process(target=fn)
+ p.start()
+ proc.append(p)
+ for p in proc:
+ results.append(p.join())
+
+ print("All processes finished")
+ print(results)
+
+
+def process_structure_with_queue(i, structure, num_old, calc_params, optimise_structure, queue):
+ # Perform the computation
+ result = process_structure(i, structure, num_old, calc_params, optimise_structure)
+ queue.put(result) # Report completion
+
+def process_structure(i, atoms, num_structures_old, calc_params, optimise_structure):
+ if i < num_structures_old:
+ return
+
+ inew = i - num_structures_old
+ atoms.calc = calc
+ # positions_initial = atoms.get_positions()
+
+ # Calculate and save the initial energy per atom
+ energy_unrlxd = atoms.get_potential_energy() / len(atoms)
+ print(f"Initial energy per atom: {energy_unrlxd}")
+
+ # Optimise the structure if requested
+ if optimise_structure:
+ optimizer = FIRE(atoms, trajectory = f"traje{inew}.traj", logfile=f"optimisation{inew}.log")
+ try:
+ optimizer.run(fmax=0.05, steps=500)
+ except Exception as e:
+ print(f"Optimisation failed: {e}")
+ return None, None, None
+
+ # Save the optimised structure and its energy per atom
+ energy_rlxd = atoms.get_potential_energy() / len(atoms)
+
+ # Get the distance matrix
+ distances = atoms.get_all_distances(mic=True)
+
+ # Set self-distances (diagonal entries) to infinity to ignore them
+ np.fill_diagonal(distances, np.inf)
+
+ # Check if the minimum non-self distance is below 1.5
+ if distances.min() < 1.0:
+ print(f"Distance too small: {atoms.get_all_distances(mic=True).min()}")
+ return None, None, None
+
+ if abs(energy_rlxd - energy_unrlxd) > 5.0:
+ print(f"Energy difference too large: {energy_rlxd} vs {energy_unrlxd}")
+ return None, None, None
+
+ return atoms, energy_unrlxd, energy_rlxd
+
+# crystal_structures = [
+# 'sc', 'fcc', 'bcc', 'hcp',
+# 'diamond', 'zincblende', 'rocksalt', 'cesiumchloride',
+# 'fluorite', 'wurtzite', 'tetragonal', 'orthorhombic',
+# 'bct', 'rhombohedral', 'mcl'
+# ]
+
+
+
+if __name__ == "__main__":
+
+ calc_params = {
+ "model": "large",
+ "dispersion": False,
+ "default_dtype": "float32",
+ "device": 'cpu'
+ }
+ calc = mace_mp(**calc_params)
+
+ crystal_structures = [
+ 'orthorhombic', #'diamond',
+ # 'bct', 'sc',
+ # 'fcc', 'bcc', 'hcp',
+ ]
+
+ hosts = []
+ for crystal_structure in crystal_structures:
+ print(f'Crystal structure: {crystal_structure}')
+ for a in np.linspace(3.3, 4.3, num=7):
+ b = a
+ c = a
+ atom = build.bulk(
+ name = 'C',
+ crystalstructure = crystal_structure,
+ a = a,
+ b = b,
+ c = c,
+ )
+ hosts.append(Atoms('C', positions=[(0, 0, 0)]))
+ hosts[-1].set_cell(atom.get_cell())
+ hosts[-1].calc = calc
+ print(hosts[-1])
+
+
+ generator = raffle_generator()
+ generator.distributions.set_element_energies(
+ {
+ 'C': 0.0
+ }
+ )
+ # set energy scale
+ generator.distributions.set_kBT(0.2)
+ # set the distribution function widths (2-body, 3-body, 4-body)
+ generator.distributions.set_width([0.025, np.pi/200.0, np.pi/200.0])
+
+ initial_database = [Atoms('C', positions=[(0, 0, 0)], cell=[5, 5, 5])]
+ initial_database[0].calc = calc
+
+ # generator.distributions.create(initial_database)
+ generator.distributions.read_gdfs("DATTEMPT4/gdfs.txt")
+
+ if os.path.exists("energies_rlxd.txt"):
+ with open("energies_rlxd.txt", "w") as energy_file:
+ pass
+ else:
+ open("energies_rlxd.txt", "w").close()
+
+ if os.path.exists("energies_unrlxd.txt"):
+ with open("energies_unrlxd.txt", "w") as energy_file:
+ pass
+ else:
+ open("energies_unrlxd.txt", "w").close()
+ seed = -1
+ num_structures_old = 0
+ optimise_structure = True
+ mass = 12.011
+ for host in hosts:
+ print("setting host")
+ generator.set_host(host)
+ volume = host.get_volume()
+ for num_atoms in range(10, 80):
+
+ density = ( num_atoms + 1 ) * mass / volume
+ if density > 2.4: # aluminium density is 2.7 g/cm^3 ~= 1.61 u/A^3
+ # print("Density too high:", density, "u/A^3")
+ continue
+ elif density < 2.0:
+ # print("Density too low", density, "u/A^3")
+ continue
+
+ for i in range(2):
+ seed += 1
+ print(f"Seed: {seed}")
+ generator.generate(
+ num_structures = 5,
+ stoichiometry = { 'C': num_atoms },
+ seed = seed,
+ method_probab = {"void": 0.5, "rand": 0.0, "walk": 0.5, "grow": 0.0, "min": 1.0},
+ verbose = 0,
+ )
+
+ # print the number of structures generated
+ print("Total number of structures generated: ", generator.num_structures)
+ generated_structures = generator.get_structures(calc)
+ num_structures_new = len(generated_structures)
+
+ # check if directory iteration[iter] exists, if not create it
+ iterdir = f"iteration{seed}/"
+ if not os.path.exists(iterdir):
+ os.makedirs(iterdir)
+ generator.print_settings(iterdir+"generator_settings.txt")
+
+ # set up list of energies
+ energy_unrlxd = np.zeros(num_structures_new - num_structures_old)
+ energy_rlxd = np.zeros(num_structures_new - num_structures_old)
+ for i in range(num_structures_new - num_structures_old):
+ write(iterdir+f"POSCAR_unrlxd_{i}", generated_structures[num_structures_old + i])
+ print(f"Structure {i} energy per atom: {generated_structures[num_structures_old + i].get_potential_energy() / len(generated_structures[num_structures_old + i])}")
+
+ # Start parallel execution
+ print("Starting parallel execution")
+ results = Parallel(n_jobs=5)(
+ delayed(process_structure)(i, deepcopy(generated_structures[i]), num_structures_old, calc_params, optimise_structure)
+ for i in range(num_structures_old, num_structures_new)
+ )
+
+ # Wait for all futures to complete
+ for j, result in enumerate(results):
+ generated_structures[j+num_structures_old], energy_unrlxd[j], energy_rlxd[j] = result
+ print("All futures completed")
+
+ # Remove structures that failed the checks
+ for j, atoms in reversed(list(enumerate(generated_structures))):
+ if atoms is None:
+ energy_unrlxd = np.delete(energy_unrlxd, j-num_structures_old)
+ energy_rlxd = np.delete(energy_rlxd, j-num_structures_old)
+ del generated_structures[j]
+ generator.remove_structure(j)
+ num_structures_new = len(generated_structures)
+
+ # write the structures to files
+ for i in range(num_structures_new - num_structures_old):
+ write(iterdir+f"POSCAR_{i}", generated_structures[num_structures_old + i])
+ print(f"Structure {i} energy per atom: {energy_rlxd[i]}")
+ # append energy per atom to the energies_unrlxd.txt file
+ with open("energies_unrlxd.txt", "a") as energy_file:
+ energy_file.write(f"{i+num_structures_old} {energy_unrlxd[i]}\n")
+ # append energy per atom to the energies_rlxd.txt file
+ with open("energies_rlxd.txt", "a") as energy_file:
+ energy_file.write(f"{i+num_structures_old} {energy_rlxd[i]}\n")
+
+ # update the distribution functions
+ print("Updating distributions")
+ generator.distributions.update(generated_structures[num_structures_old:], from_host=False, deallocate_systems=False)
+
+ # print the new distribution functions to a file
+ print("Printing distributions")
+ generator.distributions.write_dfs(iterdir+"distributions.txt")
+ generator.distributions.write_2body(iterdir+"df2.txt")
+ generator.distributions.write_3body(iterdir+"df3.txt")
+ generator.distributions.write_4body(iterdir+"df4.txt")
+ generator.distributions.deallocate_systems()
+
+ # update the number of structures generated
+ num_structures_old = num_structures_new
+
+ generator.distributions.write_gdfs("gdfs.txt")
+
+ # Read energies from the file
+ with open("energies_rlxd.txt", "r") as energy_file:
+ energies = energy_file.readlines()
+
+ # Parse and sort the energies
+ energies = [line.strip().split() for line in energies]
+ energies = sorted(energies, key=lambda x: float(x[1]))
+
+ # Write the sorted energies back to the file
+ with open("energies_ordered.txt", "w") as energy_file:
+ for entry in energies:
+ energy_file.write(f"{int(entry[0])} {float(entry[1])}\n")
+
+ print("Learning complete")
\ No newline at end of file
diff --git a/example/python_pkg/ScS2-Li_learn/POSCAR_host b/example/python_pkg/ScS2-Li_learn/POSCAR_host
new file mode 100644
index 00000000..d9e59f2d
--- /dev/null
+++ b/example/python_pkg/ScS2-Li_learn/POSCAR_host
@@ -0,0 +1,12 @@
+ScS2
+ 1.00000000000000
+ 3.4373550228202143 1.2722491953399284 -0.0985749251780342
+ 0.6164998078516010 3.5730165704323316 -0.5636062457623744
+ -0.1941735091202983 0.9816038800609169 6.1273390509283345
+ Sc S
+ 1 2
+Direct
+ 0.6762039103400640 0.1332178797064758 0.9103732174536018
+ 0.0097462202190008 0.4656228504900874 0.6731159326278954
+ 0.3427267534832620 0.8007351821914250 0.1476299218798714
+
diff --git a/example/python_pkg/ScS2-Li_learn/learn.py b/example/python_pkg/ScS2-Li_learn/learn.py
new file mode 100644
index 00000000..60187611
--- /dev/null
+++ b/example/python_pkg/ScS2-Li_learn/learn.py
@@ -0,0 +1,209 @@
+from mace.calculators import mace_mp
+from raffle.generator import raffle_generator
+from ase import build, Atoms
+from ase.optimize import BFGS
+from ase.io import write, read
+import numpy as np
+import os
+from concurrent.futures import ProcessPoolExecutor
+
+
+def process_structure(i, atoms, num_structures_old, calc, optimise_structure):
+ if i < num_structures_old:
+ return
+
+ inew = i - num_structures_old
+ atoms.calc = calc
+ positions_initial = atoms.get_positions()
+
+ # Calculate and save the initial energy per atom
+ energy_unrlxd = atoms.get_potential_energy() / len(atoms)
+
+ # Optimise the structure if requested
+ if optimise_structure:
+ optimizer = BFGS(atoms, trajectory = f"traje{inew}.traj", logfile=f"optimisation{inew}.log")
+ optimizer.run(fmax=0.05, steps=500)
+
+ # Save the optimised structure and its energy per atom
+ energy_rlxd = atoms.get_potential_energy() / len(atoms)
+
+ # Get the distance matrix
+ distances = atoms.get_all_distances(mic=True)
+
+ # Set self-distances (diagonal entries) to infinity to ignore them
+ np.fill_diagonal(distances, np.inf)
+
+ # Check if the minimum non-self distance is below 1.5
+ if distances.min() < 1.0:
+ print(f"Distance too small: {distances.min()}")
+ return None, None, None
+
+ if abs(energy_rlxd - energy_unrlxd) > 10.0:
+ print(f"Energy difference too large: {energy_rlxd} vs {energy_unrlxd}")
+ return None, None, None
+
+ return atoms, energy_unrlxd, energy_rlxd
+
+# crystal_structures = [
+# 'sc', 'fcc', 'bcc', 'hcp',
+# 'diamond', 'zincblende', 'rocksalt', 'cesiumchloride',
+# 'fluorite', 'wurtzite', 'tetragonal', 'orthorhombic',
+# 'bct', 'rhombohedral', 'mcl'
+# ]
+
+
+
+if __name__ == "__main__":
+
+ calc = mace_mp(model="medium", dispersion=False, default_dtype="float32", device='cpu')
+
+ host = read("POSCAR_host")
+ host.calc = calc
+ host_reference_energy = host.get_potential_energy() / len(host)
+
+ hosts = []
+ for a in [0.8, 0.9, 1.0, 1.1, 1.2]:
+ for c in [1.0, 1.1, 1.2, 1.3, 1.4]:
+ atom = host.copy()
+ atom.set_cell([a * host.cell[0], a * host.cell[1], c * host.cell[2]], scale_atoms=True)
+ hosts.append(atom)
+ hosts[-1].calc = calc
+ print(hosts[-1])
+
+ Li_reference = Atoms(
+ "Li2",
+ positions=[[0.0, 0.0, 0.0], [0.5, 0.5, 0.5]],
+ cell=[3.42, 3.42, 3.42],
+ pbc=[True, True, True],
+ )
+ Li_reference.calc = calc
+ Li_reference_energy = Li_reference.get_potential_energy() / len(Li_reference)
+
+ generator = raffle_generator()
+ generator.distributions.set_element_energies(
+ {
+ 'Sc': 0.0,
+ 'S': 0.0,
+ 'Li': Li_reference_energy,
+ }
+ )
+ # set energy scale
+ generator.distributions.set_kBT(0.4)
+ # set the distribution function widths (2-body, 3-body, 4-body)
+ generator.distributions.set_width([0.025, np.pi/200.0, np.pi/200.0])
+
+
+ initial_database = [host, Li_reference]
+
+ generator.distributions.create(initial_database)
+
+ if os.path.exists("energies_rlxd.txt"):
+ with open("energies_rlxd.txt", "w") as energy_file:
+ pass
+ else:
+ open("energies_rlxd.txt", "w").close()
+
+ if os.path.exists("energies_unrlxd.txt"):
+ with open("energies_unrlxd.txt", "w") as energy_file:
+ pass
+ else:
+ open("energies_unrlxd.txt", "w").close()
+ seed = -1
+ num_structures_old = 0
+ optimise_structure = True
+ for host in hosts:
+ print("setting host")
+ generator.set_host(host)
+ volume = host.get_volume()
+ for num_atoms in range(1, 3):
+
+ seed += 1
+ print(f"Seed: {seed}")
+ generator.generate(
+ num_structures = 5,
+ stoichiometry = { 'Li': num_atoms },
+ seed = seed,
+ method_probab = {"void": 1.0, "rand": 0.5, "walk": 1.0, "grow": 0.0, "min": 1.0},
+ verbose = 0,
+ )
+
+ # print the number of structures generated
+ print("Total number of structures generated: ", generator.num_structures)
+ generated_structures = generator.get_structures(calc)
+ num_structures_new = len(generated_structures)
+
+ # check if directory iteration[iter] exists, if not create it
+ iterdir = f"iteration{seed}/"
+ if not os.path.exists(iterdir):
+ os.makedirs(iterdir)
+
+ # set up list of energies
+ energy_unrlxd = np.zeros(num_structures_new - num_structures_old)
+ energy_rlxd = np.zeros(num_structures_new - num_structures_old)
+ for i in range(num_structures_new - num_structures_old):
+ write(iterdir+f"POSCAR_unrlxd_{i}", generated_structures[num_structures_old + i])
+ print(f"Structure {i} energy per atom: {generated_structures[num_structures_old + i].get_potential_energy() / len(generated_structures[num_structures_old + i])}")
+
+ # Parallel execution
+ with ProcessPoolExecutor() as executor:
+ futures = [
+ executor.submit(process_structure, i, generated_structures[i], num_structures_old, calc, optimise_structure)
+ for i in range(num_structures_old, num_structures_new)
+ ]
+
+ # Wait for all futures to complete
+ for j, future in enumerate(futures):
+ generated_structures[j+num_structures_old], energy_unrlxd[j], energy_rlxd[j] = future.result()
+
+ # Remove structures that failed the checks
+ for j, atoms in reversed(list(enumerate(generated_structures))):
+ if atoms is None:
+ energy_unrlxd = np.delete(energy_unrlxd, j-num_structures_old)
+ energy_rlxd = np.delete(energy_rlxd, j-num_structures_old)
+ del generated_structures[j]
+ generator.remove_structure(j)
+ num_structures_new = len(generated_structures)
+
+ # check if the number of structures has changed
+ if num_structures_new == num_structures_old:
+ continue
+
+ # write the structures to files
+ for i in range(num_structures_new - num_structures_old):
+ write(iterdir+f"POSCAR_{i}", generated_structures[num_structures_old + i])
+ print(f"Structure {i} energy per atom: {energy_rlxd[i]}")
+ # append energy per atom to the energies_unrlxd.txt file
+ with open("energies_unrlxd.txt", "a") as energy_file:
+ energy_file.write(f"{energy_unrlxd[i]}\n")
+ # append energy per atom to the energies_rlxd.txt file
+ with open("energies_rlxd.txt", "a") as energy_file:
+ energy_file.write(f"{energy_rlxd[i]}\n")
+
+ # update the distribution functions
+ print("Updating distributions")
+ generator.distributions.update(generated_structures[num_structures_old:], from_host=False, deallocate_systems=False)
+
+ # print the new distribution functions to a file
+ print("Printing distributions")
+ generator.distributions.write_dfs(iterdir+"distributions.txt")
+ generator.distributions.write_2body(iterdir+"df2.txt")
+ generator.distributions.write_3body(iterdir+"df3.txt")
+ generator.distributions.write_4body(iterdir+"df4.txt")
+
+ # update the number of structures generated
+ num_structures_old = num_structures_new
+
+ generator.distributions.write_gdfs("gdfs.txt")
+
+ # Read energies from the file
+ with open("energies_rlxd.txt", "r") as energy_file:
+ energies = energy_file.readlines()
+
+ # Parse and sort the energies
+ energies = [line.strip().split() for line in energies]
+ energies = sorted(energies, key=lambda x: float(x[0]))
+
+ # Write the sorted energies back to the file
+ with open("energies_ordered.txt", "w") as energy_file:
+ for entry in energies:
+ energy_file.write(f"{entry[0]}\n")
\ No newline at end of file
diff --git a/example/wrapper/run_diamond.py b/example/python_pkg/diamond/run.py
similarity index 96%
rename from example/wrapper/run_diamond.py
rename to example/python_pkg/diamond/run.py
index 1c5587f4..3cc6f3e0 100644
--- a/example/wrapper/run_diamond.py
+++ b/example/python_pkg/diamond/run.py
@@ -27,7 +27,7 @@
# read the host structure from a POSCAR file
print("Reading host")
-host = read("../example_files/POSCAR_host_diamond")
+host = read("POSCAR_host")
host.calc = calculator
print("host energy: ", host.get_potential_energy())
@@ -108,8 +108,10 @@
# read in the database of structures to use for generating the distribution functions
print("Reading database")
use_database = False
+# By default, the database is not used as it needs to be downloaded manually from the Materials Project.
+# A script to download the database can be found in tools/database.py (or a notebook in tools/database.ipynb)
if use_database:
- database = read("../example_files/database_carbon/database.xyz", index=":")
+ database = read("database.xyz", index=":")
for i, atoms in enumerate(database):
# reset energy to use CHGNet
atoms.calc = calculator
diff --git a/example/wrapper/run_graphite.py b/example/python_pkg/graphite/run.py
similarity index 96%
rename from example/wrapper/run_graphite.py
rename to example/python_pkg/graphite/run.py
index ac15043a..d52fbe00 100644
--- a/example/wrapper/run_graphite.py
+++ b/example/python_pkg/graphite/run.py
@@ -27,7 +27,7 @@
# read the host structure from a POSCAR file
print("Reading host")
-host = read("../example_files/POSCAR_graphite_missing_layer")
+host = read("POSCAR_host_missing_layer")
host.calc = calculator
print("host energy: ", host.get_potential_energy())
@@ -109,8 +109,10 @@
# read in the database of structures to use for generating the distribution functions
print("Reading database")
use_database = False
+# By default, the database is not used as it needs to be downloaded manually from the Materials Project.
+# A script to download the database can be found in tools/database.py (or a notebook in tools/database.ipynb)
if use_database:
- database = read("../example_files/database_carbon/database.xyz", index=":")
+ database = read("database.xyz", index=":")
for i, atoms in enumerate(database):
# reset energy to use CHGNet
atoms.calc = calculator
diff --git a/example/example_files/database_perovskites/database.xyz b/example/python_pkg/perovskites/database.xyz
similarity index 100%
rename from example/example_files/database_perovskites/database.xyz
rename to example/python_pkg/perovskites/database.xyz
diff --git a/example/wrapper/run_perovskites.py b/example/python_pkg/perovskites/run.py
similarity index 96%
rename from example/wrapper/run_perovskites.py
rename to example/python_pkg/perovskites/run.py
index 5a7911f4..e464a73d 100644
--- a/example/wrapper/run_perovskites.py
+++ b/example/python_pkg/perovskites/run.py
@@ -27,7 +27,7 @@
# read the host structure from a POSCAR file
print("Reading host")
-host = read("../example_files/POSCAR_host_perovskites")
+host = read("POSCAR_host")
generator.set_host(host)
print("Host read")
@@ -47,7 +47,7 @@
# set the distribution function widths (2-body, 3-body, 4-body)
print("Reading database")
-database = read("../example_files/database_perovskites/database.xyz", index=":")
+database = read("database.xyz", index=":")
# create the distribution functions
diff --git a/ford.md b/ford.md
index bc17c189..dc7801a1 100644
--- a/ford.md
+++ b/ford.md
@@ -18,8 +18,8 @@ sort: permission-alpha
author: Ned Thaddeus Taylor
print_creation_date: true
creation_date: %Y-%m-%d %H:%M %z
-project_github: https://github.com/nedtaylor/raffle
-project_download: https://github.com/nedtaylor/raffle/releases
-github: https://github.com/nedtaylor
+project_github: https://github.com/ExeQuantCode/raffle
+project_download: https://github.com/ExeQuantCode/raffle/releases
+github: https://github.com/ExeQuantCode
{!README.md!}
\ No newline at end of file
diff --git a/fpm.toml b/fpm.toml
index 25c6c428..9f9f6657 100644
--- a/fpm.toml
+++ b/fpm.toml
@@ -1,5 +1,5 @@
name = "raffle"
-version = "0.4.0"
+version = "0.5.0"
author = "Ned Thaddeus Taylor"
maintainer = "n.t.taylor@exeter.ac.uk"
description = "A Fortran library and executable for structure prediction at material interfaces"
diff --git a/pyproject.toml b/pyproject.toml
index 59be32b5..9b4c17b4 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -53,14 +53,18 @@ classifiers = [
]
[project.urls]
-Homepage = "https://github.com/nedtaylor/raffle"
+Homepage = "https://github.com/ExeQuantCode/raffle"
Documentation = "https://raffle-fortran.readthedocs.io/"
-Repository = "https://github.com/nedtaylor/raffle"
-Issues = "https://github.com/nedtaylor/raffle/issues"
+Repository = "https://github.com/ExeQuantCode/raffle"
+Issues = "https://github.com/ExeQuantCode/raffle/issues"
[project.optional-dependencies]
-all = ["ase>=3.23.0"]
+ase = ["ase>=3.23.0"]
no-ase = []
+tests = [
+ "pytest",
+ "pytest-cov",
+]
[tool.scikit-build.metadata.version]
provider = "scikit_build_core.metadata.regex"
diff --git a/src/fortran/lib/mod_distribs.f90 b/src/fortran/lib/mod_distribs.f90
index 47dde273..daf4c398 100644
--- a/src/fortran/lib/mod_distribs.f90
+++ b/src/fortran/lib/mod_distribs.f90
@@ -237,7 +237,7 @@ subroutine calculate(this, basis, &
i = 0
allocate(bond_info(num_pairs))
allocate(pair_index(basis%nspec,basis%nspec))
- do is = 1, basis%nspec
+ do is = 1, basis%nspec, 1
do js = is, basis%nspec, 1
i = i + 1
pair_index(js,is) = i
@@ -501,6 +501,14 @@ subroutine calculate(this, basis, &
)
end do
end do
+ ! a NaN in the angle refers to one where two of the vectors are
+ ! parallel, so the angle is undefined
+ do i = 1, size(angle_list)
+ if(isnan(angle_list(i)))then
+ angle_list(i) = -huge(1._real32)
+ distance(i) = 1._real32
+ end if
+ end do
this%df_3body(:,is) = this%df_3body(:,is) + &
get_distrib( &
angle_list, &
@@ -544,6 +552,14 @@ subroutine calculate(this, basis, &
modu(neighbour_basis%image_spec(1)%atom(la,:3)) ** 2
end do
end do
+ ! a NaN in the angle refers to one where two of the vectors are
+ ! parallel, so the angle is undefined
+ do i = 1, size(angle_list)
+ if(isnan(angle_list(i)))then
+ angle_list(i) = -huge(1._real32)
+ distance(i) = 1._real32
+ end if
+ end do
this%df_4body(:,is) = this%df_4body(:,is) + &
get_distrib( &
angle_list, &
@@ -582,6 +598,20 @@ subroutine calculate(this, basis, &
end if
end do
+
+ !---------------------------------------------------------------------------
+ ! check for NaN in the distribution functions
+ !---------------------------------------------------------------------------
+ if(any(isnan(this%df_2body)))then
+ call stop_program('NaN in 2-body distribution function')
+ end if
+ if(any(isnan(this%df_3body)))then
+ call stop_program('NaN in 3-body distribution function')
+ end if
+ if(any(isnan(this%df_4body)))then
+ call stop_program('NaN in 4-body distribution function')
+ end if
+
end subroutine calculate
!###############################################################################
@@ -625,6 +655,10 @@ function get_distrib(value_list, nbins, eta, width, cutoff_min, &
! get the bin closest to the value
!------------------------------------------------------------------------
bin = nint( ( value_list(i) - cutoff_min ) / width ) + 1
+ if( &
+ bin .lt. 1 - max_num_steps .or. &
+ bin .gt. nbins + max_num_steps &
+ ) cycle
!------------------------------------------------------------------------
diff --git a/src/fortran/lib/mod_distribs_container.f90 b/src/fortran/lib/mod_distribs_container.f90
index bd9de46e..99252680 100644
--- a/src/fortran/lib/mod_distribs_container.f90
+++ b/src/fortran/lib/mod_distribs_container.f90
@@ -42,8 +42,6 @@ module raffle__distribs_container
!! Boolean whether to weight the distribution functions by the energy
!! above the hull. If false, the formation energy from the element
!! reference energies is used.
- integer, dimension(:), allocatable :: host_to_df_species_map
- !! Mapping of host species to distribution function species.
real(real32) :: &
viability_3body_default = 0.1_real32, &
viability_4body_default = 0.1_real32
@@ -85,6 +83,8 @@ module raffle__distribs_container
!! Generalised distribution functions for all systems.
!! Generated from combining the energy-weighted distribution functions
!! of all systems
+ integer, dimension(:), allocatable :: element_map
+ !! Mapping of host elements to distribution function elements.
type(distribs_host_type) :: host_system
!! Host structure for the distribution functions.
type(distribs_type), dimension(:), allocatable :: system
@@ -130,6 +130,9 @@ module raffle__distribs_container
!! Return the energies of elements in the container.
!! Used in Python interface.
+
+ procedure, pass(this) :: set_element_map
+ !! Set the mapping of elements to distribution function elements.
procedure, pass(this), private :: set_bond_info
!! Set the 2-body bond information for the container.
procedure, pass(this), private :: update_bond_info
@@ -153,9 +156,15 @@ module raffle__distribs_container
!! Set the generalised distribution function to the default value.
procedure, pass(this) :: evolve
!! Evolve the learned distribution function.
- procedure, pass(this) :: write
+
+
+ procedure, pass(this) :: write_gdfs
+ !! Write the generalised distribution functions to a file.
+ procedure, pass(this) :: read_gdfs
+ !! Read the generalised distribution functions from a file.
+ procedure, pass(this) :: write_dfs
!! Write all distribution functions to a file.
- procedure, pass(this) :: read
+ procedure, pass(this) :: read_dfs
!! Read all distribution functions from a file.
procedure, pass(this) :: write_2body
!! Write the learned 2-body distribution function to a file.
@@ -578,7 +587,205 @@ end subroutine deallocate_systems
!###############################################################################
- subroutine write(this, file)
+ subroutine write_gdfs(this, file)
+ !! Write the generalised distribution functions to a file.
+ implicit none
+
+ ! Arguments
+ class(distribs_container_type), intent(in) :: this
+ !! Parent. Instance of distribution functions container.
+ character(*), intent(in) :: file
+ !! Filename to write the generalised distribution functions to.
+
+ ! Local variables
+ integer :: unit
+ !! File unit.
+ integer :: i
+ !! Loop index.
+ character(256) :: fmt
+ !! Format string.
+ character(256) :: stop_msg
+ !! Error message.
+
+ if(.not.allocated(this%gdf%df_2body))then
+ write(stop_msg,*) &
+ "Generalised distribution functions are not allocated." // &
+ achar(13) // achar(10) // &
+ "create() or read() must be called before writing the " // &
+ "generalised distribution functions."
+ call stop_program( stop_msg )
+ return
+ end if
+ open(newunit=unit, file=file)
+ write(unit, '("# nbins",3(1X,I0))') this%nbins
+ write(unit, '("# width",3(1X,ES0.4))') this%width
+ write(unit, '("# sigma",3(1X,ES0.4))') this%sigma
+ write(unit, '("# cutoff_min",3(1X,ES0.4))') this%cutoff_min
+ write(unit, '("# cutoff_max",3(1X,ES0.4))') this%cutoff_max
+ write(unit, '("# radius_distance_tol",4(1X,ES0.4))') &
+ this%radius_distance_tol
+ write(fmt, '("(""# "",A,",I0,"(1X,A))")') size(this%element_info)
+ write(unit, fmt) "elements", this%element_info(:)%name
+ write(fmt, '("(""# "",A,",I0,"(1X,ES0.4))")') size(this%element_info)
+ write(unit, fmt) "energies", this%element_info(:)%energy
+ write(unit, fmt) "best_energy_per_element", this%best_energy_per_species
+ write(unit, fmt) "3-body_norm", this%norm_3body
+ write(unit, fmt) "4-body_norm", this%norm_4body
+ write(fmt, '("(""# "",A,",I0,"(1X,L1))")') size(this%element_info)
+ write(unit, fmt) "in_dataset_3body", this%in_dataset_3body
+ write(unit, fmt) "in_dataset_4body", this%in_dataset_4body
+ write(fmt, '("(""# "",A,",I0,"(1X,A))")') size(this%bond_info)
+ write(unit, fmt) "element_pairs", &
+ ( &
+ trim(this%bond_info(i)%element(1)) // "-" // &
+ trim(this%bond_info(i)%element(2)), &
+ i = 1, size(this%bond_info) &
+ )
+ write(fmt, '("(""# "",A,",I0,"(1X,ES0.4))")') size(this%bond_info)
+ write(unit, fmt) "radii", this%bond_info(:)%radius_covalent
+ write(unit, fmt) "best_energy_per_pair", this%best_energy_pair
+ write(unit, fmt) "2-body_norm", this%norm_2body
+ write(fmt, '("(""# "",A,",I0,"(1X,L1))")') size(this%bond_info)
+ write(unit, fmt) "in_dataset_2body", this%in_dataset_2body
+ write(unit, *)
+ write(unit, '("# 2-body")')
+ write(fmt,'("(""# bond-length "",",I0,"(1X,A))")') size(this%bond_info)
+ write(unit, fmt) &
+ ( &
+ trim(this%bond_info(i)%element(1)) // "-" // &
+ trim(this%bond_info(i)%element(2)), &
+ i = 1, size(this%bond_info) &
+ )
+ do i = 1, this%nbins(1)
+ write(unit, *) &
+ this%cutoff_min(1) + this%width(1) * ( i - 1 ), &
+ this%gdf%df_2body(i,:)
+ end do
+ write(unit, *)
+ write(unit, '("# 3-body")')
+ write(fmt,'("(""# bond-angle "",",I0,"(1X,A))")') size(this%bond_info)
+ write(unit, fmt) this%element_info(:)%name
+ do i = 1, this%nbins(2)
+ write(unit, *) &
+ this%cutoff_min(2) + this%width(2) * ( i - 1 ), &
+ this%gdf%df_3body(i,:)
+ end do
+ write(unit, *)
+ write(unit, '("# 4-body")')
+ write(fmt,'("(""# dihedral-angle "",",I0,"(1X,A))")') size(this%bond_info)
+ write(unit, fmt) this%element_info(:)%name
+ do i = 1, this%nbins(3)
+ write(unit, *) &
+ this%cutoff_min(2) + this%width(2) * ( i - 1 ), &
+ this%gdf%df_4body(i,:)
+ end do
+ close(unit)
+
+ end subroutine write_gdfs
+!###############################################################################
+
+
+!###############################################################################
+ subroutine read_gdfs(this, file)
+ !! Read the generalised distribution functions from a file.
+ implicit none
+
+ ! Arguments
+ class(distribs_container_type), intent(inout) :: this
+ !! Parent. Instance of distribution functions container.
+ character(*), intent(in) :: file
+ !! Filename to read the generalised distribution functions from.
+
+ ! Local variables
+ integer :: unit
+ !! File unit.
+
+ integer :: i
+ !! Loop index.
+ integer :: iostat
+ !! I/O status.
+ integer :: nspec
+ !! Number of species.
+ logical :: exist
+ !! Boolean whether the file exists.
+ character(256) :: buffer, buffer1, buffer2
+ !! Buffer for reading lines.
+
+ ! check if file exists
+ inquire(file=file, exist=exist)
+ if(.not.exist)then
+ call stop_program( "File does not exist" )
+ return
+ end if
+
+ ! read the file
+ open(newunit=unit, file=file)
+ read(unit, *) buffer1, buffer2, this%nbins
+ read(unit, *) buffer1, buffer2, this%width
+ read(unit, *) buffer1, buffer2, this%sigma
+ read(unit, *) buffer1, buffer2, this%cutoff_min
+ read(unit, *) buffer1, buffer2, this%cutoff_max
+ read(unit, *) buffer1, buffer2, this%radius_distance_tol
+ read(unit, '(A)') buffer
+ nspec = icount(buffer(index(buffer,"elements")+8:))
+ allocate(this%element_info(nspec))
+ read(buffer, *) buffer1, buffer2, this%element_info(:)%name
+ read(unit, *) buffer1, buffer2, this%element_info(:)%energy
+ do i = 1, nspec
+ call this%set_element_energy( &
+ this%element_info(i)%name, &
+ this%element_info(i)%energy &
+ )
+ call this%element_info(i)%set(this%element_info(i)%name)
+ end do
+ call this%update_bond_info()
+ allocate(this%best_energy_per_species(nspec))
+ allocate(this%norm_3body(nspec))
+ allocate(this%norm_4body(nspec))
+ allocate(this%in_dataset_3body(nspec))
+ allocate(this%in_dataset_4body(nspec))
+ read(unit, *) buffer1, buffer2, this%best_energy_per_species
+ read(unit, *) buffer1, buffer2, this%norm_3body
+ read(unit, *) buffer1, buffer2, this%norm_4body
+ read(unit, *) buffer1, buffer2, this%in_dataset_3body
+ read(unit, *) buffer1, buffer2, this%in_dataset_4body
+ read(unit, *)
+ allocate(this%best_energy_pair(size(this%bond_info)))
+ allocate(this%norm_2body(size(this%bond_info)))
+ allocate(this%in_dataset_2body(size(this%bond_info)))
+ read(unit, *) buffer1, buffer2, this%bond_info(:)%radius_covalent
+ read(unit, *) buffer1, buffer2, this%best_energy_pair
+ read(unit, *) buffer1, buffer2, this%norm_2body
+ read(unit, *) buffer1, buffer2, this%in_dataset_2body
+ read(unit, *)
+ read(unit, *)
+ read(unit, *)
+ allocate(this%gdf%df_2body(this%nbins(1),size(this%bond_info)))
+ do i = 1, this%nbins(1)
+ read(unit, *) buffer, this%gdf%df_2body(i,:)
+ end do
+ read(unit, *)
+ read(unit, *)
+ read(unit, *)
+ allocate(this%gdf%df_3body(this%nbins(2),nspec))
+ do i = 1, this%nbins(2)
+ read(unit, *) buffer, this%gdf%df_3body(i,:)
+ end do
+ read(unit, *)
+ read(unit, *)
+ read(unit, *)
+ allocate(this%gdf%df_4body(this%nbins(3),nspec))
+ do i = 1, this%nbins(3)
+ read(unit, *) buffer, this%gdf%df_4body(i,:)
+ end do
+ close(unit)
+
+ end subroutine read_gdfs
+!###############################################################################
+
+
+!###############################################################################
+ subroutine write_dfs(this, file)
!! Write all distribution functions for each system to a file.
implicit none
@@ -632,12 +839,12 @@ subroutine write(this, file)
end do
close(unit)
- end subroutine write
+ end subroutine write_dfs
!###############################################################################
!###############################################################################
- subroutine read(this, file)
+ subroutine read_dfs(this, file)
!! Read all distribution functions for each system from a file.
implicit none
@@ -705,7 +912,7 @@ subroutine read(this, file)
end do
close(unit)
- end subroutine read
+ end subroutine read_dfs
!###############################################################################
@@ -935,6 +1142,45 @@ end subroutine add_basis
!###############################################################################
+!###############################################################################
+ subroutine set_element_map(this, element_list)
+ !! Set the element map for the container.
+ implicit none
+
+ ! Arguments
+ class(distribs_container_type), intent(inout) :: this
+ !! Parent of the procedure. Instance of distribution functions container.
+ character(3), dimension(:), intent(in) :: element_list
+ !! Element information.
+
+ ! Local variables
+ integer :: is
+ !! Loop index.
+ integer :: idx
+ !! Index of the element in the element_info array.
+ character(256) :: stop_msg
+ !! Error message.
+
+ if(allocated(this%element_map)) deallocate(this%element_map)
+ allocate(this%element_map(size(element_list)))
+ do is = 1, size(element_list)
+ idx = findloc( &
+ [ this%element_info(:)%name ], element_list(is), dim=1 &
+ )
+ if(idx.eq.0)then
+ write(stop_msg,*) "Element not found in element_info array" // &
+ achar(13) // achar(10) // &
+ "Element: ", element_list(is)
+ call stop_program( stop_msg )
+ return
+ end if
+ this%element_map(is) = idx
+ end do
+
+ end subroutine set_element_map
+!###############################################################################
+
+
!###############################################################################
subroutine set_element_info(this)
!! Set the list of elements for the container.
@@ -1685,6 +1931,13 @@ subroutine set_best_energy(this)
end do
end do
deallocate(idx_list)
+ if( this%best_energy_pair(j) .lt. -1.E1 )then
+ write(warn_msg, &
+ '("Best energy pair is less than -10 eV, &
+ &this is likely to be unphysical. Check the energy values.")' &
+ )
+ call print_warning(warn_msg)
+ end if
end do
@@ -1884,6 +2137,7 @@ subroutine evolve(this, system)
!! Temporary array for the distribution functions.
logical, dimension(:), allocatable :: tmp_in_dataset
+ character(256) :: err_msg
integer, dimension(:), allocatable :: host_idx_list
@@ -2170,6 +2424,17 @@ subroutine evolve(this, system)
end if
this%gdf%df_2body(:,j) = &
this%gdf%df_2body(:,j) / this%norm_2body(j)
+ if(any(isnan(this%gdf%df_2body(:,j))))then
+ write(err_msg, &
+ '("NaN in 2-body distribution function for ",A,"-",A,&
+ &" with norm of ",F0.3)' &
+ ) &
+ this%bond_info(j)%element(1), &
+ this%bond_info(j)%element(2), &
+ this%norm_2body(j)
+ call stop_program( err_msg )
+ return
+ end if
end do
allocate(this%norm_3body(size(this%element_info)))
allocate(this%norm_4body(size(this%element_info)))
@@ -2188,6 +2453,22 @@ subroutine evolve(this, system)
this%gdf%df_3body(:,is) / this%norm_3body(is)
this%gdf%df_4body(:,is) = &
this%gdf%df_4body(:,is) / this%norm_4body(is)
+
+ if(any(isnan(this%gdf%df_3body(:,is))))then
+ write(err_msg,'("NaN in 3-body distribution function for ",A,&
+ &" with norm of ",F0.3)' &
+ ) &
+ this%element_info(is)%name, this%norm_3body(is)
+ call stop_program( err_msg )
+ return
+ elseif(any(isnan(this%gdf%df_4body(:,is))))then
+ write(err_msg,'("NaN in 4-body distribution function for ",A,&
+ &" with norm of ",F0.3)' &
+ ) &
+ this%element_info(is)%name, this%norm_4body(is)
+ call stop_program( err_msg )
+ return
+ end if
end do
this%num_evaluated_allocated = size(this%system)
diff --git a/src/fortran/lib/mod_evaluator.f90 b/src/fortran/lib/mod_evaluator.f90
index 10601b79..6956b2e0 100644
--- a/src/fortran/lib/mod_evaluator.f90
+++ b/src/fortran/lib/mod_evaluator.f90
@@ -393,7 +393,7 @@ function evaluate_3body_contributions( distribs_container, &
output = output * &
distribs_container%gdf%df_3body( &
bin, &
- distribs_container%host_system%element_map(species) &
+ distribs_container%element_map(species) &
) ** ( 1._real32 / real( num_3body_local, real32 ) )
end associate
end do atom_loop
@@ -451,7 +451,7 @@ function evaluate_4body_contributions( distribs_container, &
output = output * &
distribs_container%gdf%df_4body( &
bin, &
- distribs_container%host_system%element_map(species) &
+ distribs_container%element_map(species) &
) ** ( 1._real32 / real( num_4body_local, real32 ) )
end associate
end do atom_loop
diff --git a/src/fortran/lib/mod_generator.f90 b/src/fortran/lib/mod_generator.f90
index b90f1c27..1e070914 100644
--- a/src/fortran/lib/mod_generator.f90
+++ b/src/fortran/lib/mod_generator.f90
@@ -7,8 +7,9 @@ module raffle__generator
!! provided host structure.
use raffle__io_utils, only: stop_program
use raffle__constants, only: real32
+ use raffle__tools_infile, only: assign_val, assign_vec
use raffle__misc_linalg, only: modu
- use raffle__misc, only: strip_null, set, shuffle
+ use raffle__misc, only: strip_null, set, shuffle, sort1D, to_upper
use raffle__geom_rw, only: basis_type
use raffle__geom_extd, only: extended_basis_type
use raffle__distribs_container, only: distribs_container_type
@@ -53,6 +54,14 @@ module raffle__generator
!! Offset of the gridpoints.
real(real32) :: grid_spacing = 0.1_real32
!! Spacing of the gridpoints.
+ real(real32), dimension(2,3) :: bounds = reshape( &
+ (/ &
+ 0.0_real32, 1.0_real32, &
+ 0.0_real32, 1.0_real32, &
+ 0.0_real32, 1.0_real32 &
+ /), [2,3] &
+ )
+ !! Bounds for atom placement.
type(distribs_container_type) :: distributions
!! Distribution function container for the 2-, 3-, and 4-body interactions.
integer :: max_attempts = 10000
@@ -72,14 +81,27 @@ module raffle__generator
!! Procedure to set the grid for the raffle generator.
procedure, pass(this) :: reset_grid
!! Procedure to reset the grid for the raffle generator.
+ procedure, pass(this) :: set_bounds
+ !! Procedure to set the bounds for the raffle generator.
+ procedure, pass(this) :: reset_bounds
+ !! Procedure to reset the bounds for the raffle generator.
procedure, pass(this) :: generate
!! Procedure to generate random structures.
procedure, pass(this), private :: generate_structure
!! Procedure to generate a single random structure.
procedure, pass(this) :: get_structures
!! Procedure to return the generated structures.
+ procedure, pass(this) :: set_structures
+ !! Procedure to set the array of generated structures.
+ procedure, pass(this) :: remove_structure
+ !! Procedure to remove a structure from the array of generated structures.
procedure, pass(this) :: evaluate
!! Procedure to evaluate the viability of a structure.
+
+ procedure, pass(this) :: print_settings => print_generator_settings
+ !! Procedure to print the raffle generator settings.
+ procedure, pass(this) :: read_settings => read_generator_settings
+ !! Procedure to read the raffle generator settings.
end type raffle_generator_type
interface raffle_generator_type
@@ -162,10 +184,7 @@ subroutine set_host(this, host)
!! Loop index.
- this%host = host
- do i = 1, this%host%nspec
- this%host%spec(i)%name = strip_null(this%host%spec(i)%name)
- end do
+ call this%host%copy(host)
call this%distributions%host_system%set(this%host)
call this%set_grid()
@@ -213,7 +232,10 @@ subroutine set_grid(this, grid, grid_spacing, grid_offset)
if(all(this%grid.eq.0))then
if(allocated(this%host%spec))then
do i = 1, 3
- this%grid(i) = nint( modu(this%host%lat(i,:)) / this%grid_spacing )
+ this%grid(i) = nint( &
+ ( this%bounds(2,i) - this%bounds(1,i) ) * &
+ modu(this%host%lat(i,:)) / this%grid_spacing &
+ )
end do
end if
end if
@@ -236,9 +258,48 @@ end subroutine reset_grid
!###############################################################################
+!###############################################################################
+ subroutine set_bounds(this, bounds)
+ !! Set the bounds for the raffle generator.
+ !!
+ !! This procedure sets the bounds for the raffle generator. The bounds are
+ !! used to determine the placement of atoms in the host structure.
+ implicit none
+
+ ! Arguments
+ class(raffle_generator_type), intent(inout) :: this
+ !! Instance of the raffle generator.
+ real(real32), dimension(2,3), intent(in) :: bounds
+ !! Bounds for atom placement.
+
+ this%bounds = bounds
+ call this%set_grid()
+
+ end subroutine set_bounds
+!###############################################################################
+
+
+!###############################################################################
+ subroutine reset_bounds(this)
+ !! Reset the grid for the raffle generator.
+ implicit none
+
+ ! Arguments
+ class(raffle_generator_type), intent(inout) :: this
+ !! Instance of the raffle generator.
+
+ this%bounds(1,:) = 0.0_real32
+ this%bounds(2,:) = 1.0_real32
+ end subroutine reset_bounds
+!###############################################################################
+
+
+
!###############################################################################
subroutine generate(this, num_structures, &
- stoichiometry, method_probab, seed, verbose)
+ stoichiometry, method_probab, seed, settings_out_file, &
+ verbose &
+ )
!! Generate random structures.
!!
!! This procedure generates random structures from the contained host
@@ -258,6 +319,8 @@ subroutine generate(this, num_structures, &
!! Probability of each placement method.
integer, intent(in), optional :: seed
!! Seed for the random number generator.
+ character(*), intent(in), optional :: settings_out_file
+ !! File to print the settings to.
integer, intent(in), optional :: verbose
!! Verbosity level.
@@ -296,7 +359,12 @@ subroutine generate(this, num_structures, &
! set the placement method probabilities
!---------------------------------------------------------------------------
if(verbose_.gt.0) write(*,*) "Setting method probabilities"
- if(present(method_probab)) method_probab_ = method_probab
+ if(present(method_probab))then
+ method_probab_ = method_probab
+ else
+ method_probab_ = this%method_probab
+ end if
+ this%method_probab = method_probab_
total_probab = real(sum(method_probab_), real32)
method_probab_ = method_probab_ / total_probab
do i = 2, 5, 1
@@ -307,6 +375,15 @@ subroutine generate(this, num_structures, &
method_probab_
+ !---------------------------------------------------------------------------
+ ! print the settings to a file
+ !---------------------------------------------------------------------------
+ if(present(settings_out_file))then
+ if(trim(settings_out_file).ne."")then
+ call this%print_settings(settings_out_file)
+ end if
+ end if
+
!---------------------------------------------------------------------------
! set the random seed
!---------------------------------------------------------------------------
@@ -368,6 +445,9 @@ subroutine generate(this, num_structures, &
!---------------------------------------------------------------------------
! ensure host element map is set
!---------------------------------------------------------------------------
+ call this%distributions%set_element_map( &
+ [ basis_template%spec(:)%name ] &
+ )
call this%distributions%host_system%set_element_map( &
this%distributions%element_info &
)
@@ -523,6 +603,7 @@ function generate_structure( &
gridpoint_viability = get_gridpoints_and_viability( &
this%distributions, &
this%grid, &
+ this%bounds, &
basis, &
species_index_list, &
[ this%distributions%bond_info(:)%radius_covalent ], &
@@ -581,6 +662,7 @@ function generate_structure( &
if(verbose.gt.0) write(*,*) "Add Atom Void"
point = place_method_void( this%grid, &
this%grid_offset, &
+ this%bounds, &
basis, &
placement_list_shuffled(iplaced+1:,:), viable &
)
@@ -588,6 +670,7 @@ function generate_structure( &
if(verbose.gt.0) write(*,*) "Add Atom Random"
point = place_method_rand( &
this%distributions, &
+ this%bounds, &
basis, &
placement_list_shuffled(iplaced+1:,:), &
[ this%distributions%bond_info(:)%radius_covalent ], &
@@ -599,6 +682,7 @@ function generate_structure( &
if(verbose.gt.0) write(*,*) "Add Atom Walk"
point = place_method_walk( &
this%distributions, &
+ this%bounds, &
basis, &
placement_list_shuffled(iplaced+1:,:), &
[ this%distributions%bond_info(:)%radius_covalent ], &
@@ -612,6 +696,7 @@ function generate_structure( &
if(verbose.gt.0) write(*,*) "Add Atom Random (growth seed)"
point = place_method_rand( &
this%distributions, &
+ this%bounds, &
basis, &
placement_list_shuffled(iplaced+1:,:), &
[ this%distributions%bond_info(:)%radius_covalent ], &
@@ -626,6 +711,7 @@ function generate_structure( &
placement_list_shuffled(iplaced,2),:3 &
), &
placement_list_shuffled(iplaced,1), &
+ this%bounds, &
basis, &
placement_list_shuffled(iplaced+1:,:), &
[ this%distributions%bond_info(:)%radius_covalent ], &
@@ -668,7 +754,7 @@ function generate_structure( &
if(.not. viable) then
if(void_ticker.gt.10) &
point = place_method_void( &
- this%grid, this%grid_offset, basis, &
+ this%grid, this%grid_offset, this%bounds, basis, &
placement_list_shuffled(iplaced+1:,:), viable &
)
void_ticker = 0
@@ -712,9 +798,102 @@ end function get_structures
!###############################################################################
+!###############################################################################
+ subroutine set_structures(this, structures)
+ !! Set the generated structures.
+ !!
+ !! This procedure overwrites the array of generated structures with the
+ !! input array.
+ !! This can be useful for removing structures that are not viable from the
+ !! array.
+ implicit none
+ ! Arguments
+ class(raffle_generator_type), intent(inout) :: this
+ !! Instance of the raffle generator.
+ type(basis_type), dimension(..), allocatable, intent(in) :: structures
+ !! Array of structures to set.
+
+ select rank(structures)
+ rank(0)
+ this%structures = [ structures ]
+ rank(1)
+ this%structures = structures
+ rank default
+ call stop_program("Invalid rank for structures")
+ end select
+ this%num_structures = size(this%structures)
+ end subroutine set_structures
+!###############################################################################
+
+
+!###############################################################################
+ subroutine remove_structure(this, index)
+ !! Remove structures from the generated structures.
+ !!
+ !! This procedure removes structures from the array of generated structures
+ !! at the specified indices.
+ implicit none
+ ! Arguments
+ class(raffle_generator_type), intent(inout) :: this
+ !! Instance of the raffle generator.
+ integer, dimension(..), intent(in) :: index
+ !! Indices of the structures to remove.
+
+ ! Local variables
+ integer :: i
+ !! Loop index.
+ integer, dimension(:), allocatable :: index_
+ !! Indices of the structures to keep.
+
+ select rank(index)
+ rank(0)
+ index_ = [ index ]
+ rank(1)
+ index_ = index
+ rank default
+ call stop_program("Invalid rank for index")
+ end select
+
+ if(any(index_.lt.1) .or. any(index_.gt.this%num_structures))then
+ call stop_program("Invalid index")
+ return
+ end if
+
+ call sort1D(index_, reverse=.true.)
+
+ do i = 1, size(index_)
+ this%structures = [ &
+ this%structures(:index_(i)-1:1), &
+ this%structures(index_(i)+1:this%num_structures:1) &
+ ]
+ this%num_structures = this%num_structures - 1
+ end do
+
+ end subroutine remove_structure
+!###############################################################################
+
+
+!###############################################################################
+ subroutine allocate_structures(this, num_structures)
+ !! Allocate memory for the generated structures.
+ implicit none
+ ! Arguments
+ class(raffle_generator_type), intent(inout) :: this
+ !! Instance of the raffle generator.
+ integer, intent(in) :: num_structures
+ !! Number of structures to allocate memory for.
+
+ if(allocated(this%structures)) deallocate(this%structures)
+ allocate(this%structures(num_structures))
+ this%num_structures = num_structures
+ end subroutine allocate_structures
+!###############################################################################
+
+
!###############################################################################
function evaluate(this, basis) result(viability)
!! Evaluate the viability of the generated structures.
+ use raffle__evaluator, only: evaluate_point
implicit none
! Arguments
class(raffle_generator_type), intent(in) :: this
@@ -724,27 +903,241 @@ function evaluate(this, basis) result(viability)
real(real32) :: viability
!! Viability of the generated structures.
+ ! Local variables
+ integer :: is, ia, species
+ !! Loop indices.
+ integer, dimension(1,2) :: atom_ignore
+ !! Atom to ignore.
+ type(extended_basis_type) :: basis_extd
+ !! Extended basis for the structure to evaluate.
+
+
+ call basis_extd%copy(basis)
+ call basis_extd%create_images( &
+ max_bondlength = this%distributions%cutoff_max(1) &
+ )
viability = 0.0_real32
- call stop_program("Evaluate procedure not yet set up")
- return
+ do is = 1, basis%nspec
+ species = this%distributions%get_element_index( basis%spec(is)%name )
+ if(species.eq.0)then
+ call stop_program("Species not found in distribution functions")
+ return
+ end if
+ do ia = 1, basis%spec(is)%num
+ atom_ignore(1,:) = [is,ia]
+ viability = viability + &
+ evaluate_point( this%distributions, &
+ basis%spec(is)%atom(ia,1:3), &
+ species, basis_extd, &
+ atom_ignore, &
+ [ this%distributions%bond_info(:)%radius_covalent ] &
+ )
+ end do
+ end do
+
+ viability = viability / real(basis%natom, real32)
end function evaluate
!###############################################################################
!###############################################################################
- subroutine allocate_structures(this, num_structures)
- !! Allocate memory for the generated structures.
+ subroutine print_generator_settings(this, file)
+ !! Print the raffle generator settings.
implicit none
+
+ ! Arguments
+ class(raffle_generator_type), intent(in) :: this
+ !! Instance of the raffle generator.
+ character(*), intent(in) :: file
+ !! Filename to write the settings to.
+
+ ! Local variables
+ integer :: i
+ !! Loop index.
+ integer :: unit
+ !! Unit number for the file.
+
+ ! Open the file
+ open(newunit=unit, file=file)
+
+ write(unit,'("# RAFFLE Generator Settings")')
+ write(unit,'("# GENERATOR SETTINGS")')
+ write(unit,'("HOST_LATTICE # not a setting, just for reference")')
+ write(unit,'(" ",3(1X,F5.2))') this%host%lat(1,:)
+ write(unit,'(" ",3(1X,F5.2))') this%host%lat(2,:)
+ write(unit,'(" ",3(1X,F5.2))') this%host%lat(3,:)
+ write(unit,'("END HOST_LATTICE")')
+
+ write(unit,'("GRID =",3(1X,I0))') this%grid
+ write(unit,'("GRID_OFFSET =",3(1X,F15.9))') this%grid_offset
+ write(unit,'("GRID_SPACING = ",F15.9)') this%grid_spacing
+ write(unit,'("BOUNDS_LW =",3(1X,F15.9))') this%bounds(1,:)
+ write(unit,'("BOUNDS_UP =",3(1X,F15.9))') this%bounds(2,:)
+
+ write(unit,'("MAX_ATTEMPTS =",I0)') this%max_attempts
+ write(unit,'("WALK_STEP_SIZE_COARSE = ",F15.9)') this%walk_step_size_coarse
+ write(unit,'("WALK_STEP_SIZE_FINE = ",F15.9)') this%walk_step_size_fine
+ write(unit,'("METHOD_VOID = ",F15.9)') this%method_probab(1)
+ write(unit,'("METHOD_RANDOM = ",F15.9)') this%method_probab(2)
+ write(unit,'("METHOD_WALK = ",F15.9)') this%method_probab(3)
+ write(unit,'("METHOD_GROW = ",F15.9)') this%method_probab(4)
+ write(unit,'("METHOD_MIN = ",F15.9)') this%method_probab(5)
+
+ write(unit,'("# DISTRIBUTION SETTINGS")')
+ write(unit,'("KBT = ",F5.2)') this%distributions%kbt
+ write(unit,'("SIGMA =",3(1X,F15.9))') this%distributions%sigma
+ write(unit,'("WIDTH =",3(1X,F15.9))') this%distributions%width
+ write(unit,'("CUTOFF_MIN =",3(1X,F15.9))') this%distributions%cutoff_min
+ write(unit,'("CUTOFF_MAX =",3(1X,F15.9))') this%distributions%cutoff_max
+ write(unit,'("RADIUS_DISTANCE_TOLERANCE =",4(1X,F15.9))') &
+ this%distributions%radius_distance_tol
+ write(unit,'("ELEMENT_INFO # element : energy")')
+ do i = 1, size(this%distributions%element_info)
+ write(unit,'(" ",A," : ",F15.9)') &
+ this%distributions%element_info(i)%name, &
+ this%distributions%element_info(i)%energy
+ end do
+ write(unit,'("END ELEMENT_INFO")')
+ write(unit,'("BOND_INFO # element1 element2 : radius")')
+ do i = 1, size(this%distributions%bond_info)
+ write(unit,'(" ",A," ",A," : ",F15.9)') &
+ this%distributions%bond_info(i)%element(1), &
+ this%distributions%bond_info(i)%element(2), &
+ this%distributions%bond_info(i)%radius_covalent
+ end do
+ write(unit,'("END BOND_INFO")')
+
+ close(unit)
+
+ end subroutine print_generator_settings
+!###############################################################################
+
+
+!###############################################################################
+ subroutine read_generator_settings(this, file)
+ !! Read the raffle generator settings.
+ implicit none
+
! Arguments
class(raffle_generator_type), intent(inout) :: this
!! Instance of the raffle generator.
- integer, intent(in) :: num_structures
- !! Number of structures to allocate memory for.
+ character(*), intent(in) :: file
+ !! Filename to read the settings from.
- if(allocated(this%structures)) deallocate(this%structures)
- allocate(this%structures(num_structures))
- this%num_structures = num_structures
- end subroutine allocate_structures
+ ! Local variables
+ integer :: i
+ !! Loop index.
+ integer :: itmp1, status
+ !! Temporary integer.
+ integer :: unit
+ !! Unit number for the file.
+ logical :: exist
+ !! Boolean for file existence.
+ character(len=256) :: line, buffer, tag
+ !! Line from the file.
+ character(3), dimension(2) :: elements
+ !! Element symbols.
+ real(real32) :: rtmp1
+ !! Temporary real number.
+
+ ! Check if the file exists
+ inquire(file=file, exist=exist)
+ if(.not.exist)then
+ call stop_program("File does not exist")
+ return
+ end if
+
+ ! Open the file
+ open(newunit=unit, file=file)
+
+ if(allocated(this%distributions%element_info)) &
+ deallocate(this%distributions%element_info)
+ if(allocated(this%distributions%bond_info)) &
+ deallocate(this%distributions%bond_info)
+ itmp1 = 0
+ do
+ read(unit, '(A)', iostat = status) line
+ ! encounter end of line
+ if(status.ne.0) exit
+
+ if(index(line,'#').gt.0) line = line(1:index(line,'#')-1)
+ line = to_upper(trim(adjustl(line)))
+ if(len(trim(line)).eq.0) cycle
+
+ tag=trim(adjustl(line))
+ if(scan(line,"=").ne.0) tag=trim(tag(:scan(tag,"=")-1))
+
+ select case(trim(adjustl(tag)))
+ case("HOST_LATTICE")
+ do i = 1, 4
+ read(unit,*)
+ end do
+ case("GRID")
+ call assign_vec(line, this%grid, itmp1)
+ case("GRID_OFFSET")
+ call assign_vec(line, this%grid_offset, itmp1)
+ case("GRID_SPACING")
+ call assign_val(line, this%grid_spacing, itmp1)
+ case("BOUNDS_LW")
+ call assign_vec(line, this%bounds(1,:), itmp1)
+ case("BOUNDS_UP")
+ call assign_vec(line, this%bounds(2,:), itmp1)
+ case("MAX_ATTEMPTS")
+ call assign_val(line, this%max_attempts, itmp1)
+ case("WALK_STEP_SIZE_COARSE")
+ call assign_val(line, this%walk_step_size_coarse, itmp1)
+ case("WALK_STEP_SIZE_FINE")
+ call assign_val(line, this%walk_step_size_fine, itmp1)
+ case("METHOD_VOID")
+ call assign_val(line, this%method_probab(1), itmp1)
+ case("METHOD_RANDOM")
+ call assign_val(line, this%method_probab(2), itmp1)
+ case("METHOD_WALK")
+ call assign_val(line, this%method_probab(3), itmp1)
+ case("METHOD_GROW")
+ call assign_val(line, this%method_probab(4), itmp1)
+ case("METHOD_MIN")
+ call assign_val(line, this%method_probab(5), itmp1)
+ case("KBT")
+ call assign_val(line, this%distributions%kbt, itmp1)
+ case("SIGMA")
+ call assign_vec(line, this%distributions%sigma, itmp1)
+ case("WIDTH")
+ call assign_vec(line, this%distributions%width, itmp1)
+ case("CUTOFF_MIN")
+ call assign_vec(line, this%distributions%cutoff_min, itmp1)
+ case("CUTOFF_MAX")
+ call assign_vec(line, this%distributions%cutoff_max, itmp1)
+ case("RADIUS_DISTANCE_TOLERANCE")
+ call assign_vec(line, this%distributions%radius_distance_tol, itmp1)
+ case("ELEMENT_INFO")
+ do
+ read(unit,'(A)') line
+ if(index(line,'#').gt.0) line = line(1:index(line,'#')-1)
+ line = to_upper(trim(adjustl(line)))
+ if(len(trim(line)).eq.0) exit
+ if(index(line,'END').gt.0) exit
+ read(line(:scan(line,":")-1),*) elements(1)
+ read(line(scan(line,":")+1:),*) rtmp1
+ call this%distributions%set_element_energy(elements(1), rtmp1)
+ end do
+ case("BOND_INFO")
+ do
+ read(unit,'(A)') line
+ if(index(line,'#').gt.0) line = line(1:index(line,'#')-1)
+ line = to_upper(trim(adjustl(line)))
+ if(len(trim(line)).eq.0) exit
+ if(index(line,'END').gt.0) exit
+ read(line(:scan(line,":")-1),*) elements(1), elements(2)
+ read(line(scan(line,":")+1:),*) rtmp1
+ call this%distributions%set_bond_radius(elements, rtmp1)
+ end do
+ end select
+ end do
+
+ close(unit)
+
+ end subroutine read_generator_settings
!###############################################################################
end module raffle__generator
\ No newline at end of file
diff --git a/src/fortran/lib/mod_geom_rw.f90 b/src/fortran/lib/mod_geom_rw.f90
index 24378543..8dc8073e 100644
--- a/src/fortran/lib/mod_geom_rw.f90
+++ b/src/fortran/lib/mod_geom_rw.f90
@@ -5,7 +5,7 @@ module raffle__geom_rw
!! It also contains the derived types used to store the geometry data.
use raffle__constants, only: pi,real32
use raffle__io_utils, only: stop_program
- use raffle__misc, only: to_upper, to_lower, jump, icount
+ use raffle__misc, only: to_upper, to_lower, jump, icount, strip_null
use raffle__misc_linalg, only: modu, inverse_3x3
implicit none
@@ -1388,7 +1388,7 @@ subroutine copy(this, basis, length)
this%spec(i)%atom(:,4) = 1._real32
end if
this%spec(i)%num = basis%spec(i)%num
- this%spec(i)%name = basis%spec(i)%name
+ this%spec(i)%name = strip_null(basis%spec(i)%name)
this%spec(i)%mass = basis%spec(i)%mass
this%spec(i)%charge = basis%spec(i)%charge
diff --git a/src/fortran/lib/mod_io_utils.F90 b/src/fortran/lib/mod_io_utils.F90
index 5669620e..769a239a 100644
--- a/src/fortran/lib/mod_io_utils.F90
+++ b/src/fortran/lib/mod_io_utils.F90
@@ -6,7 +6,7 @@ module raffle__io_utils
implicit none
logical :: test_error_handling = .false.
- character(len=*), parameter :: raffle__version__ = "0.4.0"
+ character(len=*), parameter :: raffle__version__ = "0.5.0"
private
diff --git a/src/fortran/lib/mod_place_methods.f90 b/src/fortran/lib/mod_place_methods.f90
index e64496eb..cb704429 100644
--- a/src/fortran/lib/mod_place_methods.f90
+++ b/src/fortran/lib/mod_place_methods.f90
@@ -32,7 +32,7 @@ module raffle__place_methods
!###############################################################################
function place_method_void( &
- grid, grid_offset, basis, atom_ignore_list, viable &
+ grid, grid_offset, bounds, basis, atom_ignore_list, viable &
) result(point)
!! VOID placement method.
!!
@@ -47,6 +47,8 @@ function place_method_void( &
!! Number of gridpoints in each direction.
real(real32), dimension(3), intent(in) :: grid_offset
!! Offset for gridpoints.
+ real(real32), dimension(2,3), intent(in) :: bounds
+ !! Bounds of the unit cell.
integer, dimension(:,:), intent(in) :: atom_ignore_list
!! List of atoms to ignore (i.e. indices of atoms not yet placed).
logical, intent(out) :: viable
@@ -76,11 +78,9 @@ function place_method_void( &
do i = 0, grid(1) - 1, 1
do j = 0, grid(2) - 1, 1
do k = 0, grid(3) - 1, 1
- tmpvector = [ &
- i + grid_offset(1), &
- j + grid_offset(2), &
- k + grid_offset(3) &
- ] / real(grid,real32)
+ tmpvector = bounds(1,:) + &
+ ( bounds(2,:) - bounds(1,:) ) * &
+ ( [ i, j, k ] + grid_offset ) / real(grid,real32)
smallest_bond = modu(get_min_dist(&
basis, tmpvector, .false., &
ignore_list = atom_ignore_list))
@@ -105,6 +105,7 @@ end function place_method_void
!###############################################################################
function place_method_rand( distribs_container, &
+ bounds, &
basis, atom_ignore_list, radius_list, max_attempts, viable &
) result(point)
!! Random placement method.
@@ -115,6 +116,8 @@ function place_method_rand( distribs_container, &
! Arguments
type(distribs_container_type), intent(in) :: distribs_container
!! Distribution function (gvector) container.
+ real(real32), dimension(2,3), intent(in) :: bounds
+ !! Bounds of the unit cell.
type(extended_basis_type), intent(inout) :: basis
!! Structure to add atom to.
integer, dimension(:,:), intent(in) :: atom_ignore_list
@@ -129,10 +132,12 @@ function place_method_rand( distribs_container, &
!! Point to add atom to.
! Local variables
- integer :: i, j, is, js
+ integer :: i, is, js
!! Loop indices.
real(real32) :: rtmp1
!! random number.
+ real(real32), dimension(3) :: rvec1
+ !! random vector.
integer, dimension(basis%nspec,basis%nspec) :: pair_index
@@ -156,21 +161,21 @@ function place_method_rand( distribs_container, &
! find a random gridpoint that is not too close to any other atom
!---------------------------------------------------------------------------
atom_loop: do i = 1, max_attempts
- do j = 1, 3
- call random_number(rtmp1)
- point(j) = rtmp1
- end do
+ call random_number(rvec1)
+ point = bounds(1,:) + ( bounds(2,:) - bounds(1,:) ) * rvec1
do js = 1, basis%nspec
if( &
get_min_dist_between_point_and_species( &
basis, point, &
- species = atom_ignore_list(1,1), &
+ species = js, &
ignore_list = atom_ignore_list &
- ) .lt. radius_list(pair_index(atom_ignore_list(1,1),js)) &
+ ) .lt. radius_list(pair_index(atom_ignore_list(1,1),js)) * &
+ distribs_container%radius_distance_tol(1) &
)then
cycle atom_loop
end if
end do
+ viable = .true.
exit atom_loop
end do atom_loop
@@ -180,6 +185,7 @@ end function place_method_rand
!###############################################################################
function place_method_walk( distribs_container, &
+ bounds, &
basis, atom_ignore_list, &
radius_list, max_attempts, &
step_size_coarse, step_size_fine, &
@@ -199,6 +205,8 @@ function place_method_walk( distribs_container, &
! Arguments
type(distribs_container_type), intent(in) :: distribs_container
!! Distribution function (gvector) container.
+ real(real32), dimension(2,3), intent(in) :: bounds
+ !! Bounds of the unit cell.
type(extended_basis_type), intent(inout) :: basis
!! Structure to add atom to.
integer, intent(in) :: max_attempts
@@ -215,7 +223,7 @@ function place_method_walk( distribs_container, &
!! Point to add atom to.
! Local variables
- integer :: i
+ integer :: i, j
!! Loop indices.
integer :: nattempt, nstuck
!! Number of attempts and number of times stuck at same site
@@ -241,8 +249,10 @@ function place_method_walk( distribs_container, &
end do
i = 0
random_loop : do
- i = i + 1
+ i = i + 1
+ if(i.gt.max_attempts) return
call random_number(site_vector)
+ site_vector = bounds(1,:) + ( bounds(2,:) - bounds(1,:) ) * site_vector
site_value = evaluate_point( distribs_container, &
site_vector, atom_ignore_list(1,1), basis, &
@@ -251,7 +261,6 @@ function place_method_walk( distribs_container, &
call random_number(rtmp1)
if(rtmp1.lt.site_value) exit random_loop
- if(i.ge.max_attempts) return
end do random_loop
@@ -261,7 +270,10 @@ function place_method_walk( distribs_container, &
nattempt = 0
nstuck = 0
crude_norm = 0.5_real32
+ i = 0
walk_loop : do
+ i = i + 1
+ if(i.gt.max_attempts) return
!------------------------------------------------------------------------
! if we have tried 10 times, then we need to reduce the step size
! get the new test point and map it back into the unit cell
@@ -275,6 +287,10 @@ function place_method_walk( distribs_container, &
( rvec1 * 2._real32 - 1._real32 ) * step_size_coarse / abc
end if
test_vector = test_vector - floor(test_vector)
+ do j = 1, 3
+ if(test_vector(j).lt.bounds(1,j) .or. test_vector(j).ge.bounds(2,j)) &
+ cycle walk_loop
+ end do
!------------------------------------------------------------------------
! evaluate the test point
@@ -283,6 +299,7 @@ function place_method_walk( distribs_container, &
test_vector, atom_ignore_list(1,1), basis, &
atom_ignore_list, radius_list &
)
+ if(test_value.lt.1.E-6) cycle walk_loop
!------------------------------------------------------------------------
! if viability of test point is less than current point, then we
! are stuck at the current point and need to try again
@@ -324,6 +341,7 @@ end function place_method_walk
!###############################################################################
function place_method_growth( distribs_container, &
prior_point, prior_species, &
+ bounds, &
basis, atom_ignore_list, &
radius_list, max_attempts, &
step_size_coarse, step_size_fine, &
@@ -347,6 +365,8 @@ function place_method_growth( distribs_container, &
!! Point to start walk from.
integer, intent(in) :: prior_species
!! Species of last atom placed.
+ real(real32), dimension(2,3), intent(in) :: bounds
+ !! Bounds of the unit cell.
type(extended_basis_type), intent(inout) :: basis
!! Structure to add atom to.
integer, intent(in) :: max_attempts
@@ -363,7 +383,7 @@ function place_method_growth( distribs_container, &
!! Point to add atom to.
! Local variables
- integer :: i, idx
+ integer :: i, j, idx
!! Loop indices.
integer :: nattempt, nstuck
!! Number of attempts and number of times stuck at same site
@@ -407,6 +427,7 @@ function place_method_growth( distribs_container, &
i = 0
shell_loop: do
i = i + 1
+ if(i.gt.max_attempts) return
call random_number(rvec1)
! map rvec1(1) to ring between min_radius and min_radius + 1.0
rvec1(1) = rvec1(1) + min_radius ! r
@@ -421,6 +442,10 @@ function place_method_growth( distribs_container, &
! convert from cartesian to direct
rvec1 = matmul(rvec1, inverse_lattice)
site_vector = prior_point + rvec1
+ do j = 1, 3
+ if(site_vector(j).lt.bounds(1,j) .or. site_vector(j).ge.bounds(2,j)) &
+ cycle shell_loop
+ end do
! now evaluate the point and check if it passes the initial criteria
site_value = evaluate_point( distribs_container, &
site_vector, atom_ignore_list(1,1), basis, &
@@ -429,7 +454,6 @@ function place_method_growth( distribs_container, &
call random_number(rtmp1)
if(rtmp1.lt.site_value) exit shell_loop
- if(i.ge.max_attempts) return
end do shell_loop
@@ -439,7 +463,10 @@ function place_method_growth( distribs_container, &
nattempt = 0
nstuck = 0
crude_norm = 0.5_real32
+ i = 0
walk_loop : do
+ i = i + 1
+ if(i.gt.max_attempts) return
!------------------------------------------------------------------------
! if we have tried 10 times, then we need to reduce the step size
! get the new test point and map it back into the unit cell
@@ -453,6 +480,10 @@ function place_method_growth( distribs_container, &
( rvec1 * 2._real32 - 1._real32 ) * step_size_coarse / abc
end if
test_vector = test_vector - floor(test_vector)
+ do j = 1, 3
+ if(test_vector(j).lt.bounds(1,j) .or. test_vector(j).ge.bounds(2,j)) &
+ cycle walk_loop
+ end do
!------------------------------------------------------------------------
! evaluate the test point
@@ -461,6 +492,7 @@ function place_method_growth( distribs_container, &
test_vector, atom_ignore_list(1,1), basis, &
atom_ignore_list, radius_list &
)
+ if(test_value.lt.1.E-6) cycle walk_loop
!------------------------------------------------------------------------
! if viability of test point is less than current point, then we
! are stuck at the current point and need to try again
diff --git a/src/fortran/lib/mod_tools_infile.f90 b/src/fortran/lib/mod_tools_infile.f90
new file mode 100644
index 00000000..358f442e
--- /dev/null
+++ b/src/fortran/lib/mod_tools_infile.f90
@@ -0,0 +1,333 @@
+!!!#############################################################################
+module raffle__tools_infile
+ !! This module contains a collection of tools for reading input files.
+ !!
+ !! Code written by Ned Thaddeus Taylor and Francis Huw Davies
+ !! Code part of the ARTEMIS group (Hepplestone research group).
+ !! Think Hepplestone, think HRG.
+ !! Original distribution: https://github.com/ExeQuantCode/ARTEMIS
+ !! This module is distributed under the CC-BY-3.0 license.
+ !! License: http://creativecommons.org/licenses/by/3.0/
+ !! This module has been copied and modified with permission from the
+ !! original authors.
+ use raffle__constants, only: real32
+ use raffle__misc, only: grep,icount
+
+ implicit none
+
+
+ private
+ public :: getline, rm_comments
+ public :: assign_val, assign_vec
+
+
+ interface assign_val
+ procedure assignI, assignR, assignS, assignL
+ end interface assign_val
+
+ interface assign_vec
+ procedure assignIvec, assignRvec
+ end interface assign_vec
+
+
+
+contains
+
+!###############################################################################
+ function val(buffer)
+ !! Return the section of buffer that occurs after an "=".
+ implicit none
+
+ ! Arguments
+ character(*), intent(in) :: buffer
+ !! The input buffer.
+
+ ! Local variables
+ character(100) :: val
+ !! The output value.
+
+ val = trim( adjustl( buffer((scan(buffer,"=",back=.false.)+1):) ) )
+
+ end function val
+!###############################################################################
+
+
+!###############################################################################
+ subroutine getline(unit, pattern, buffer)
+ !! Get the line from a grep and assign it to buffer.
+ implicit none
+
+ ! Arguments
+ integer, intent(in) :: unit
+ !! The unit to read from.
+ character(*), intent(in) :: pattern
+ !! The pattern to grep for.
+ character(*), intent(out) :: buffer
+ !! The buffer to assign the line to.
+
+ ! Local variables
+ integer :: iostat
+ !! input output status
+
+ call grep(unit,pattern)
+ backspace(unit)
+ read(unit,'(A)',iostat=iostat) buffer
+
+ end subroutine getline
+!###############################################################################
+
+
+!###############################################################################
+ subroutine assignI(buffer, variable, found, keyword)
+ !! Assign an integer to a variable.
+ implicit none
+
+ ! Arguments
+ integer, intent(inout) :: found
+ !! The number of variables found. External counter
+ character(*), intent(inout) :: buffer
+ !! The buffer to read from.
+ integer, intent(out) :: variable
+ !! The variable to assign to.
+ character(*), optional, intent(in) :: keyword
+ !! The keyword to search for.
+
+ character(1024) :: buffer2
+
+ if(present(keyword))then
+ buffer = buffer(index(buffer,keyword):)
+ end if
+ if(scan("=",buffer).ne.0) buffer2 = val(buffer)
+ if(trim(adjustl(buffer2)).ne.'') then
+ found = found + 1
+ read(buffer2,*) variable
+ end if
+ end subroutine assignI
+!###############################################################################
+
+
+!###############################################################################
+ subroutine assignIvec(buffer, variable, found, keyword)
+ !! Assign an arbitrary length vector of integers to a variable.
+ implicit none
+
+ ! Arguments
+ integer, intent(inout) :: found
+ !! The number of variables found. External counter
+ character(*), intent(inout) :: buffer
+ !! The buffer to read from.
+ integer, dimension(:) :: variable
+ !! The variable to assign to.
+ character(*), optional, intent(in) :: keyword
+ !! The keyword to search for.
+
+ ! Local variables
+ integer :: i
+ !! Loop counter
+ character(1024) :: buffer2
+ !! Temporary buffer
+
+
+ if(present(keyword))then
+ buffer = buffer(index(buffer,keyword):)
+ end if
+ if(scan("=",buffer).ne.0) buffer2 = val(buffer)
+ if(trim(adjustl(buffer2)).ne.'') then
+ found = found + 1
+ if(icount(buffer2).eq.1.and.&
+ icount(buffer2).ne.size(variable))then
+ read(buffer2,*) variable(1)
+ variable = variable(1)
+ else
+ read(buffer2,*) ( variable(i), i = 1, size(variable) )
+ end if
+ end if
+ end subroutine assignIvec
+!###############################################################################
+
+
+!###############################################################################
+ subroutine assignR(buffer, variable, found, keyword)
+ !! Assign a float value to a variable.
+ implicit none
+
+ ! Arguments
+ integer, intent(inout) :: found
+ !! The number of variables found. External counter
+ character(*), intent(inout) :: buffer
+ !! The buffer to read from.
+ real(real32), intent(out) :: variable
+ !! The variable to assign to.
+ character(*), optional, intent(in) :: keyword
+ !! The keyword to search for.
+
+ ! Local variables
+ character(1024) :: buffer2
+ !! Temporary buffer
+
+ if(present(keyword))then
+ buffer = buffer(index(buffer,keyword):)
+ end if
+ if(scan("=",buffer).ne.0) buffer2 = val(buffer)
+ if(trim(adjustl(buffer2)).ne.'') then
+ found = found + 1
+ read(buffer2,*) variable
+ end if
+ end subroutine assignR
+!###############################################################################
+
+
+!###############################################################################
+ subroutine assignRvec(buffer, variable, found, keyword)
+ !! Assign an arbitrary length float vector to a variable.
+ implicit none
+
+ ! Arguments
+ integer, intent(inout) :: found
+ !! The number of variables found. External counter
+ character(*), intent(inout) :: buffer
+ !! The buffer to read from.
+ real(real32), dimension(:), intent(out) :: variable
+ !! The variable to assign to.
+ character(*), optional, intent(in) :: keyword
+ !! The keyword to search for.
+
+ ! Local variables
+ integer :: i
+ !! Loop counter
+ character(1024) :: buffer2
+ !! Temporary buffer
+
+ if(present(keyword))then
+ buffer = buffer(index(buffer,keyword):)
+ end if
+ if(scan("=",buffer).ne.0) buffer2=val(buffer)
+ if(trim(adjustl(buffer2)).ne.'') then
+ found = found + 1
+ if(icount(buffer2).eq.1.and.&
+ icount(buffer2).ne.size(variable))then
+ read(buffer2,*) variable(1)
+ variable = variable(1)
+ else
+ read(buffer2,*) (variable(i),i=1,size(variable))
+ end if
+ end if
+ end subroutine assignRvec
+!###############################################################################
+
+
+!###############################################################################
+ subroutine assignS(buffer, variable, found, keyword)
+ !! Assign a string to a variable.
+ implicit none
+
+ ! Arguments
+ integer, intent(inout) :: found
+ !! The number of variables found. External counter
+ character(*), intent(inout) :: buffer
+ !! The buffer to read from.
+ character(*), intent(out) :: variable
+ !! The variable to assign to.
+ character(*), optional, intent(in) :: keyword
+ !! The keyword to search for.
+
+ ! Local variables
+ character(1024) :: buffer2
+ !! Temporary buffer
+
+ if(present(keyword))then
+ buffer = buffer(index(buffer,keyword):)
+ end if
+ if(scan("=",buffer).ne.0) buffer2 = val(buffer)
+ if(trim(adjustl(buffer2)).ne.'') then
+ found = found + 1
+ read(buffer2,'(A)') variable
+ end if
+ end subroutine assignS
+!###############################################################################
+
+
+!###############################################################################
+ subroutine assignL(buffer, variable, found, keyword)
+ !! Assign a logical to a variable.
+ !!
+ !! This subroutine will assign a logical value to a variable. The
+ !! logical can take the form of a string or an integer. The following
+ !! are all valid logical values:
+ !! T, F, t, f, 1, 0
+ implicit none
+
+ ! Arguments
+ integer, intent(inout) :: found
+ !! The number of variables found. External counter
+ character(*), intent(inout) :: buffer
+ !! The buffer to read from.
+ logical, intent(out) :: variable
+ !! The variable to assign to.
+ character(*), optional, intent(in) :: keyword
+ !! The keyword to search for.
+
+ ! Local variables
+ character(1024) :: buffer2
+ !! Buffer to read from
+
+ if(present(keyword))then
+ buffer=buffer(index(buffer,keyword):)
+ end if
+ if(scan("=",buffer).ne.0) buffer2 = val(buffer)
+ if(trim(adjustl(buffer2)).ne.'') then
+ found=found+1
+ if(index(buffer2,"T").ne.0.or.&
+ index(buffer2,"t").ne.0.or.&
+ index(buffer2,"1").ne.0) then
+ variable = .TRUE.
+ end if
+ if(index(buffer2,"F").ne.0.or.&
+ index(buffer2,"f").ne.0.or.&
+ index(buffer2,"0").ne.0) then
+ variable = .FALSE.
+ end if
+ end if
+ end subroutine assignL
+!###############################################################################
+
+
+!###############################################################################
+ subroutine rm_comments(buffer, iline)
+ !! Remove comments from a buffer.
+ implicit none
+
+ ! Arguments
+ character(*), intent(inout) :: buffer
+ !! Buffer to remove comments from.
+ integer, optional, intent(in) :: iline
+ !! Line number.
+
+ ! Local variables
+ integer :: lbracket,rbracket
+ !! Bracketing variables
+ integer :: iline_
+ !! Line number
+
+ iline_ = 0
+ if(present(iline)) iline_ = iline
+
+ if(scan(buffer,'!').ne.0) buffer = buffer(:(scan(buffer,'!')-1))
+ if(scan(buffer,'#').ne.0) buffer = buffer(:(scan(buffer,'#')-1))
+ do while(scan(buffer,'(').ne.0.or.scan(buffer,')').ne.0)
+ lbracket = scan( buffer, '(', back=.true. )
+ rbracket = scan( buffer(lbracket:), ')' )
+ if( lbracket .eq. 0 .or. rbracket .eq. 0 )then
+ write(6,'(A,I0)') &
+ ' NOTE: a bracketing error was encountered on line ',iline_
+ buffer = ""
+ return
+ end if
+ rbracket = rbracket + lbracket - 1
+ buffer = buffer(:(lbracket-1)) // buffer((rbracket+1):)
+ end do
+
+ end subroutine rm_comments
+!###############################################################################
+
+end module raffle__tools_infile
diff --git a/src/fortran/lib/mod_viability.f90 b/src/fortran/lib/mod_viability.f90
index 338d3a59..b5bfe028 100644
--- a/src/fortran/lib/mod_viability.f90
+++ b/src/fortran/lib/mod_viability.f90
@@ -20,7 +20,8 @@ module raffle__viability
contains
!###############################################################################
- function get_gridpoints_and_viability(distribs_container, grid, basis, &
+ function get_gridpoints_and_viability(distribs_container, grid, bounds, &
+ basis, &
species_index_list, &
radius_list, atom_ignore_list, grid_offset) result(points)
!! Return a list of viable gridpoints and their viability for each species.
@@ -35,6 +36,8 @@ function get_gridpoints_and_viability(distribs_container, grid, basis, &
!! Structure to add atom to.
integer, dimension(3), intent(in) :: grid
!! Number of gridpoints in each direction.
+ real(real32), dimension(2,3), intent(in) :: bounds
+ !! Bounds of the unit cell.
real(real32), dimension(:), intent(in) :: radius_list
!! List of radii for each pair of elements.
integer, dimension(:), intent(in) :: species_index_list
@@ -53,6 +56,8 @@ function get_gridpoints_and_viability(distribs_container, grid, basis, &
!! Number of gridpoints.
real(real32) :: min_radius
!! Minimum radius.
+ real(real32), dimension(3) :: point
+ !! Gridpoint.
real(real32), dimension(:,:), allocatable :: points_tmp
!! Temporary list of gridpoints.
@@ -68,6 +73,9 @@ function get_gridpoints_and_viability(distribs_container, grid, basis, &
grid_loop1: do i = 0, grid(1) - 1, 1
grid_loop2: do j = 0, grid(2) - 1, 1
grid_loop3: do k = 0, grid(3) - 1, 1
+ point = bounds(1,:) + &
+ ( bounds(2,:) - bounds(1,:) ) * &
+ ( [ i, j, k ] + grid_offset ) / real(grid,real32)
do is = 1, basis%nspec
atom_loop: do ia = 1, basis%spec(is)%num
do l = 1, size(atom_ignore_list,dim=1), 1
@@ -76,11 +84,7 @@ function get_gridpoints_and_viability(distribs_container, grid, basis, &
if( &
get_min_dist_between_point_and_atom( &
basis, &
- [ &
- i + grid_offset(1), &
- j + grid_offset(2), &
- k + grid_offset(3) &
- ] / real(grid,real32), &
+ point, &
[is,ia] &
) .lt. &
min_radius &
@@ -88,11 +92,7 @@ function get_gridpoints_and_viability(distribs_container, grid, basis, &
end do atom_loop
end do
num_points = num_points + 1
- points_tmp(:,num_points) = [ &
- i + grid_offset(1), &
- j + grid_offset(2), &
- k + grid_offset(3) &
- ] / real(grid,real32)
+ points_tmp(:,num_points) = point
end do grid_loop3
end do grid_loop2
end do grid_loop1
@@ -149,7 +149,7 @@ subroutine update_gridpoints_and_viability( &
!! List of atoms to ignore (i.e. indices of atoms not yet placed).
! Local variables
- integer :: i, j, is
+ integer :: i, j, k, is
!! Loop indices.
integer :: num_points
!! Number of gridpoints.
@@ -179,7 +179,6 @@ subroutine update_gridpoints_and_viability( &
viable(i) = .false.
cycle
elseif( distance .gt. distribs_container%cutoff_max(1) )then
- points(4:,i) = 0._real32
cycle
end if
do is = 1, size(species_index_list,1)
@@ -199,16 +198,30 @@ subroutine update_gridpoints_and_viability( &
end if
allocate(points_tmp(3+basis%nspec,num_points))
- i = 0
- j = 0
- do while (i .lt. num_points)
- j = j + 1
- if(.not.viable(j)) cycle
- i = i + 1
- points_tmp(:,i) = points(:,j)
+ ! j = 0
+ ! do i = 1, size(viable)
+ ! if(.not.viable(i)) cycle
+ ! j = j + 1
+ ! points_tmp(:,j) = points(:,i)
+ ! end do
+
+ i = findloc(viable, .true., 1)
+ j = 1
+ do while (j .le. num_points)
+ k = findloc(viable(i+1:), .false., 1)
+ select case(k)
+ case(0)
+ points_tmp(:,j:) = points(:,i:)
+ exit
+ case default
+ points_tmp(:,j:j+k-1) = points(:,i:i+k-1)
+ i = i + k - 1 + findloc(viable(i+k:), .true., 1)
+ j = j + k
+ end select
end do
+
deallocate(points)
- allocate(points, source = points_tmp)
+ call move_alloc(points_tmp, points)
end subroutine update_gridpoints_and_viability
!###############################################################################
diff --git a/src/raffle/__init__.py b/src/raffle/__init__.py
index 82620a22..096fa778 100644
--- a/src/raffle/__init__.py
+++ b/src/raffle/__init__.py
@@ -44,4 +44,11 @@
del types
del raffle
-__all__ = ['__version__', 'generator', 'geom']
\ No newline at end of file
+__all__ = ['__version__', 'generator', 'geom']
+
+def __getattr__(name):
+ if name == "generator":
+ return generator
+ elif name == "geom":
+ return geom
+ raise AttributeError(f"module {__name__} has no attribute {name}")
\ No newline at end of file
diff --git a/src/raffle/raffle.py b/src/raffle/raffle.py
index a835306c..5202e2cf 100644
--- a/src/raffle/raffle.py
+++ b/src/raffle/raffle.py
@@ -6,39 +6,30 @@
class Geom_Rw(f90wrap.runtime.FortranModule):
"""
- Module geom_rw
-
-
- Defined at ../src/lib/mod_geom_rw.f90 lines \
- 13-968
+ Code for handling geometry read/write operations.
+
+ This module provides the necessary functionality to read, write, and
+ store atomic geometries.
+ In this module, and all of the codebase, element and species are used
+ interchangeably.
+ Defined in ../src/lib/mod_geom_rw.f90
+
+ .. note::
+ It is recommended not to use this module directly, but to handle
+ atom objects through the ASE interface.
+ This is provided mostly for compatibility with the existing codebase
+ and Fortran code.
"""
@f90wrap.runtime.register_class("raffle.species_type")
class species_type(f90wrap.runtime.FortranDerivedType):
- """
- Type(name=species_type)
-
-
- Defined at ../src/lib/mod_geom_rw.f90 lines \
- 26-32
-
- """
def __init__(self, handle=None):
"""
- self = species_type()
-
-
- Defined at ../src/lib/mod_geom_rw.f90 lines \
- 26-32
-
-
- Returns
- -------
- this : species_type
- Object to be constructed
-
+ Create a ``species_type`` object.
- Automatically generated constructor for species_type
+ Returns:
+ species (species_type):
+ Object to be constructed
"""
f90wrap.runtime.FortranDerivedType.__init__(self)
result = _raffle.f90wrap_geom_rw__species_type_initialise()
@@ -66,11 +57,7 @@ def __del__(self):
@property
def atom(self):
"""
- Element atom ftype=real(real32) pytype=float
-
-
- Defined at ../src/lib/mod_geom_rw.f90 line 27
-
+ Derived type containing the atomic information of a crystal.
"""
array_ndim, array_type, array_shape, array_handle = \
_raffle.f90wrap_species_type__array__atom(self._handle)
@@ -90,11 +77,7 @@ def atom(self, atom):
@property
def mass(self):
"""
- Element mass ftype=real(real32) pytype=float
-
-
- Defined at ../src/lib/mod_geom_rw.f90 line 28
-
+ The mass of the element.
"""
return _raffle.f90wrap_species_type__get__mass(self._handle)
@@ -105,22 +88,14 @@ def mass(self, mass):
@property
def charge(self):
"""
- Element charge ftype=real(real32) pytype=float
-
-
- Defined at ../src/lib/mod_geom_rw.f90 line 29
-
+ The charge of the element.
"""
return _raffle.f90wrap_species_type__get__charge(self._handle)
@property
def radius(self):
"""
- Element radius ftype=real(real32) pytype=float
-
-
- Defined at ../src/lib/mod_geom_rw.f90 line 29
-
+ The radius of the element.
"""
return _raffle.f90wrap_species_type__get__radius(self._handle)
@@ -135,11 +110,7 @@ def charge(self, charge):
@property
def name(self):
"""
- Element name ftype=character(len=3) pytype=str
-
-
- Defined at ../src/lib/mod_geom_rw.f90 line 30
-
+ The symbol of the element.
"""
return _raffle.f90wrap_species_type__get__name(self._handle)
@@ -150,11 +121,7 @@ def name(self, name):
@property
def num(self):
"""
- Element num ftype=integer pytype=int
-
-
- Defined at ../src/lib/mod_geom_rw.f90 line 31
-
+ The number of atoms of this species/element.
"""
return _raffle.f90wrap_species_type__get__num(self._handle)
@@ -182,30 +149,17 @@ def __str__(self):
@f90wrap.runtime.register_class("raffle.basis")
class basis(f90wrap.runtime.FortranDerivedType):
- """
- Type(name=basis)
-
-
- Defined at ../src/lib/mod_geom_rw.f90 lines \
- 34-42
-
- """
def __init__(self, atoms=None, handle=None):
"""
- self = basis()
-
-
- Defined at ../src/lib/mod_geom_rw.f90 lines \
- 34-42
-
-
- Returns
- -------
- this : basis
- Object to be constructed
-
+ Create a ``basis`` object.
+
+ This object is used to store the atomic information of a crystal,
+ including lattice and basis information.
+ This is confusingly named as a crystal = lattice + basis.
- Automatically generated constructor for basis
+ Returns:
+ basis (basis):
+ Object to be constructed
"""
f90wrap.runtime.FortranDerivedType.__init__(self)
result = _raffle.f90wrap_geom_rw__basis_type_initialise()
@@ -236,27 +190,26 @@ def __del__(self):
def allocate_species(self, num_species=None, species_symbols=None, species_count=None, \
positions=None):
"""
- allocate_species__binding__basis_type(self[, num_species, species_symbols, \
- species_count, atoms])
-
-
- Defined at ../src/lib/mod_geom_rw.f90 lines \
- 47-74
-
- Parameters
- ----------
- this : unknown
- num_species : int
- species_symbols : str array
- species_count : int array
- atoms : float array
+ Allocate memory for the species list.
+ Parameters:
+ num_species (int):
+ Number of species
+ species_symbols (list of str):
+ List of species symbols
+ species_count (list of int):
+ List of species counts
+ atoms (list of float):
+ List of atomic positions
"""
_raffle.f90wrap_geom_rw__allocate_species__binding__basis_type(this=self._handle, \
num_species=num_species, species_symbols=species_symbols, species_count=species_count, \
atoms=positions)
def _init_array_spec(self):
+ """
+ Initialise the species array.
+ """
self.spec = f90wrap.runtime.FortranDerivedTypeArray(self,
_raffle.f90wrap_basis_type__array_getitem__spec,
_raffle.f90wrap_basis_type__array_setitem__spec,
@@ -271,6 +224,13 @@ def _init_array_spec(self):
return self.spec
def toase(self, calculator=None):
+ """
+ Convert the basis object to an ASE Atoms object.
+
+ Parameters:
+ calculator (ASE Calculator):
+ ASE calculator object to be assigned to the Atoms object.
+ """
from ase import Atoms
# Set the species list
@@ -292,6 +252,13 @@ def toase(self, calculator=None):
return atoms
def fromase(self, atoms):
+ """
+ Convert the ASE Atoms object to a basis object.
+
+ Parameters:
+ atoms (ASE Atoms):
+ ASE Atoms object to be converted.
+ """
from ase.calculators.singlepoint import SinglePointCalculator
# Get the species symbols
@@ -334,11 +301,7 @@ def fromase(self, atoms):
@property
def nspec(self):
"""
- Element nspec ftype=integer pytype=int
-
-
- Defined at ../src/lib/mod_geom_rw.f90 line 36
-
+ The number of species in the basis.
"""
return _raffle.f90wrap_basis_type__get__nspec(self._handle)
@@ -349,11 +312,7 @@ def nspec(self, nspec):
@property
def natom(self):
"""
- Element natom ftype=integer pytype=int
-
-
- Defined at ../src/lib/mod_geom_rw.f90 line 37
-
+ The number of atoms in the basis.
"""
return _raffle.f90wrap_basis_type__get__natom(self._handle)
@@ -364,11 +323,7 @@ def natom(self, natom):
@property
def energy(self):
"""
- Element energy ftype=real(real32) pytype=float
-
-
- Defined at ../src/lib/mod_geom_rw.f90 line 38
-
+ The energy associated with the basis (or crystal).
"""
return _raffle.f90wrap_basis_type__get__energy(self._handle)
@@ -379,11 +334,7 @@ def energy(self, energy):
@property
def lat(self):
"""
- Element lat ftype=real(real32) pytype=float
-
-
- Defined at ../src/lib/mod_geom_rw.f90 line 38
-
+ The lattice vectors of the basis.
"""
array_ndim, array_type, array_shape, array_handle = \
_raffle.f90wrap_basis_type__array__lat(self._handle)
@@ -403,11 +354,7 @@ def lat(self, lat):
@property
def lcart(self):
"""
- Element lcart ftype=logical pytype=bool
-
-
- Defined at ../src/lib/mod_geom_rw.f90 line 39
-
+ Boolean whether the atomic positions are in cartesian coordinates.
"""
return _raffle.f90wrap_basis_type__get__lcart(self._handle)
@@ -418,11 +365,7 @@ def lcart(self, lcart):
@property
def pbc(self):
"""
- Element pbc ftype=logical pytype=bool
-
-
- Defined at ../src/lib/mod_geom_rw.f90 line 40
-
+ Boolean array indicating the periodic boundary conditions.
"""
array_ndim, array_type, array_shape, array_handle = \
_raffle.f90wrap_basis_type__array__pbc(self._handle)
@@ -442,11 +385,7 @@ def pbc(self, pbc):
@property
def sysname(self):
"""
- Element sysname ftype=character(len=1024) pytype=str
-
-
- Defined at ../src/lib/mod_geom_rw.f90 line 41
-
+ The name of the system.
"""
return _raffle.f90wrap_basis_type__get__sysname(self._handle)
@@ -479,30 +418,14 @@ def __str__(self):
@f90wrap.runtime.register_class("raffle.basis_array")
class basis_array(f90wrap.runtime.FortranDerivedType):
- """
- Type(name=basis_array)
-
-
- Defined at ../src/lib/mod_generator.f90 lines \
- 19-21
-
- """
def __init__(self, atoms=None, handle=None):
"""
- self = basis_array()
-
-
- Defined at ../src/lib/mod_generator.f90 lines \
- 19-21
-
-
- Returns
- -------
- this : basis_array
- Object to be constructed
+ Create a ``basis_array`` object.
- Automatically generated constructor for basis_array
+ Returns:
+ basis_array (basis_array):
+ Object to be constructed
"""
f90wrap.runtime.FortranDerivedType.__init__(self)
@@ -541,6 +464,9 @@ def __del__(self):
_raffle.f90wrap_geom_rw__basis_type_xnum_array_finalise(this=self._handle)
def _init_array_items(self):
+ """
+ Initialise the items array.
+ """
self.items = f90wrap.runtime.FortranDerivedTypeArray(self,
_raffle.f90wrap_basis_type_xnum_array__array_getitem__items,
_raffle.f90wrap_basis_type_xnum_array__array_setitem__items,
@@ -555,6 +481,9 @@ def _init_array_items(self):
return self.items
def toase(self):
+ """
+ Convert the basis_array object to a list of ASE Atoms objects.
+ """
# Set the species list
atoms = []
@@ -564,13 +493,11 @@ def toase(self):
def allocate(self, size):
"""
- Allocate the items array with the given size
+ Allocate the items array with the given size.
- Parameters
- ----------
- self : basis_conatiner
- size : int
- Size of the items array
+ Parameters:
+ size (int):
+ Size of the items array
"""
_raffle.f90wrap_basis_type_xnum_array__array_alloc__items(self._handle, num=size)
@@ -589,40 +516,28 @@ def deallocate(self):
class Raffle__Distribs_Container(f90wrap.runtime.FortranModule):
"""
- Module raffle__distribs_container
-
+ Code for handling distribution functions.
+
+ This module provides the necessary functionality to create, update, and
+ store distribution functions.
+ The distribution functions are used as descriptors for the atomic
+ environments in a crystal.
+ The generalised distribution function (GDF) is a generalised descriptor
+ for the atomic configurations that each species can adopt.
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- lines 1-1839
+ Defined in ../src/fortran/lib/mod_distribs_container.f90
"""
@f90wrap.runtime.register_class("raffle.distribs_container_type")
class distribs_container_type(f90wrap.runtime.FortranDerivedType):
- """
- Type(name=distribs_container_type)
-
-
- Defined at \
- ../fortran/lib/mod_distribs_container.f90 \
- lines 25-162
-
- """
def __init__(self, handle=None):
"""
- self = Distribs_Container_Type()
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- lines 25-162
-
+ Create a ``Distribs_Container_Type`` object.
+
- Returns
- -------
- this : Distribs_Container_Type
+ Returns:
+ distribution_container (Distribs_Container_Type):
Object to be constructed
-
-
- Automatically generated constructor for distribs_container_type
"""
f90wrap.runtime.FortranDerivedType.__init__(self)
result = \
@@ -650,27 +565,28 @@ def __del__(self):
def set_kBT(self, kBT):
"""
- Parameters
- ----------
- this : unknown
- kBT : float
+ Set the energy scale for the distribution functions.
+
+ Parameters:
+ kBT (float):
+ Energy scale for the distribution functions.
"""
self.kBT = kBT
def set_weight_method(self, method):
"""
- Parameters
- ----------
- this : unknown
- method : str
+ Set the weight method for combining the the distribution functions
+ to form the generalised distribution function (GDF).
+
+ Parameters:
+ method (str):
+ Method to be used for weighting the distribution functions.
+ Allowed values are:
+ - 'formation_energy' or 'formation' or 'form' or 'e_form'
+ - 'energy_above_hull' or 'hull_distance' or 'hull' or 'distance' or 'convex_hull'
"""
- # method can be 'formation_energy' or 'energy_above_hull'
- # allowed abbreviations for 'formation_energy':
- # 'empirical', 'formation', 'form', 'e_form'
- # allowed abbreviations for 'hull_distance':
- # 'hull_distance', 'hull', 'distance', 'convex_hull'
if method in ['empirical', 'formation_energy', 'formation', 'form', 'e_form']:
self.weight_by_hull = False
@@ -681,104 +597,90 @@ def set_weight_method(self, method):
def set_width(self, width):
"""
- set_width__binding__dc_type(self, width)
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- lines 237-247
-
- Parameters
- ----------
- this : unknown
- width : float array
+ Set the distribution function widths.
+ Parameters:
+ width (list of float):
+ List of distribution function widths.
+ The first element is the 2-body distribution function width,
+ the second element is the 3-body distribution function width,
+ and the third element is the 4-body distribution function width.
"""
_raffle.f90wrap_raffle__dc__set_width__binding__dc_type(this=self._handle, \
width=width)
def set_sigma(self, sigma):
"""
- set_sigma__binding__dc_type(self, sigma)
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- lines 251-261
-
- Parameters
- ----------
- this : unknown
- sigma : float array
-
+ Set the sigma values of the Gaussians used to
+ build the distribution functions.
+
+ Parameters:
+ sigma (list of float):
+ List of sigma values.
+ The first element is the 2-body distribution function sigma,
+ the second element is the 3-body distribution function sigma,
+ and the third element is the 4-body distribution function sigma.
"""
_raffle.f90wrap_raffle__dc__set_sigma__binding__dc_type(this=self._handle, \
sigma=sigma)
def set_cutoff_min(self, cutoff_min):
"""
- set_cutoff_min__binding__dc_type(self, cutoff_min)
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- lines 265-273
-
- Parameters
- ----------
- this : unknown
- cutoff_min : float array
-
+ Set the minimum cutoff values for the distribution functions.
+
+ Parameters:
+ cutoff_min (list of float):
+ List of minimum cutoff values.
+ The first element is the 2-body distribution function minimum cutoff,
+ the second element is the 3-body distribution function minimum cutoff,
+ and the third element is the 4-body distribution function minimum cutoff.
"""
_raffle.f90wrap_raffle__dc__set_cutoff_min__binding__dc_type(this=self._handle, \
cutoff_min=cutoff_min)
def set_cutoff_max(self, cutoff_max):
"""
- set_cutoff_max__binding__dc_type(self, cutoff_max)
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- lines 277-285
-
- Parameters
- ----------
- this : unknown
- cutoff_max : float array
-
+ Set the maximum cutoff values for the distribution functions.
+
+ Parameters:
+ cutoff_min (list of float):
+ List of maximum cutoff values.
+ The first element is the 2-body distribution function maximum cutoff,
+ the second element is the 3-body distribution function maximum cutoff,
+ and the third element is the 4-body distribution function maximum cutoff.
"""
_raffle.f90wrap_raffle__dc__set_cutoff_max__binding__dc_type(this=self._handle, \
cutoff_max=cutoff_max)
def set_radius_distance_tol(self, radius_distance_tol):
"""
- set_radius_distance_tol__binding__dc_type(self, \
- radius_distance_tol)
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- lines 289-297
-
- Parameters
- ----------
- this : unknown
- radius_distance_tol : float array
+ Set the radius distance tolerance for the distribution functions.
+
+ The radius distance tolerance represents a multiplier to the bond radii to
+ determine the cutoff distance for the distribution functions.
+ Parameters:
+ radius_distance_tol (list of float):
+ List of radius distance tolerance values.
+ The first two values are the lower and upper bounds for the
+ 3-body distribution function radius distance tolerance.
+ The third and fourth values are the lower and upper bounds for the
+ 4-body distribution function radius distance tolerance.
"""
_raffle.f90wrap_raffle__dc__set_radius_distance_tol__binding__dc_type(this=self._handle, \
radius_distance_tol=radius_distance_tol)
def create(self, basis_list, energy_above_hull_list=None, deallocate_systems=True):
"""
- create__binding__dc_type(self, basis_list)
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- lines 353-440
-
- Parameters
- ----------
- this : unknown
- basis_list : basis_array or Atoms or list of Atoms
- energy_above_hull_list : list of float
- deallocate_systems : bool
+ Create the distribution functions.
+ Parameters:
+ basis_list (basis_array or Atoms or list of Atoms):
+ List of atomic configurations to be used to create the distribution functions.
+ energy_above_hull_list (list of float):
+ List of energy above hull values for the atomic configurations.
+ deallocate_systems (bool):
+ Boolean whether to deallocate the atomic configurations after creating the distribution functions.
"""
from ase import Atoms
if isinstance(basis_list, Atoms):
@@ -795,19 +697,17 @@ def create(self, basis_list, energy_above_hull_list=None, deallocate_systems=Tru
def update(self, basis_list, energy_above_hull_list=None, from_host=True, deallocate_systems=True):
"""
- update__binding__dc_type(self, basis_list)
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- 445-503
-
- Parameters
- ----------
- this : unknown
- basis_list : basis_array or list of Atoms
- energy_above_hull_list : list of float
- from_host : bool
- deallocate_systems : bool
+ Update the distribution functions.
+ Parameters:
+ basis_list (basis_array or Atoms or list of Atoms):
+ List of atomic configurations to be used to create the distribution functions.
+ energy_above_hull_list (list of float):
+ List of energy above hull values for the atomic configurations.
+ deallocate_systems (bool):
+ Boolean whether to deallocate the atomic configurations after creating the distribution functions.
+ from_host (bool):
+ Boolean whether the provided basis_list is based on the host.
"""
from ase import Atoms
if isinstance(basis_list, Atoms):
@@ -826,31 +726,20 @@ def update(self, basis_list, energy_above_hull_list=None, from_host=True, deallo
def deallocate_systems(self):
"""
- deallocate_systems__binding__dc_type(self)
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- lines 497-506
-
- Parameters
- ----------
- this : unknown
-
+ Deallocate the atomic configurations.
"""
_raffle.f90wrap_raffle__dc__deallocate_systems__binding__dc_type(this=self._handle)
def add_basis(self, basis):
"""
- add_basis__binding__dc_type(self, basis)
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- lines 776-797
+ Add a basis to the distribution functions.
+
+ It is not recommended to use this function directly, but to use the
+ create or update functions instead.
- Parameters
- ----------
- this : unknown
- basis : Basis_Type
+ Parameters:
+ basis (geom_rw.basis):
+ Basis object to be added to the distribution functions.
"""
_raffle.f90wrap_raffle__dc__add_basis__binding__dc_type(this=self._handle, \
@@ -858,16 +747,15 @@ def add_basis(self, basis):
def set_element_energies(self, element_energies):
"""
- set_element_energies__binding__dc_type(self, element_energies)
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- lines 944-958
+ Set the element reference energies for the distribution functions.
+
+ These energies are used to calculate the formation energies of the
+ atomic configurations.
- Parameters
- ----------
- this : unknown
- element_energies : dict
+ Parameters:
+ element_energies (dict):
+ Dictionary of element reference energies.
+ The keys are the element symbols and the values are the reference energies.
"""
element_list = list(element_energies.keys())
@@ -877,21 +765,12 @@ def set_element_energies(self, element_energies):
def get_element_energies(self):
"""
- get_element_energies_static__binding__dc_type(self, elements, \
- energies)
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- lines 984-1004
-
- Parameters
- ----------
- this : unknown
-
- Returns
- -------
- element_energies : dict
+ Get the element reference energies for the distribution functions.
+ Returns:
+ element_energies (dict):
+ Dictionary of element reference energies.
+ The keys are the element symbols and the values are the reference energies
"""
num_elements = _raffle.f90wrap_raffle__dc__get__num_elements(self._handle)
@@ -911,38 +790,21 @@ def get_element_energies(self):
def set_bond_info(self):
"""
- set_bond_info__binding__dc_type(self)
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- lines 1008-1052
-
- Parameters
- ----------
- this : unknown
-
- ---------------------------------------------------------------------------
- allocate the bond information array
- ---------------------------------------------------------------------------
+ Allocate the bond information array.
+
+ It is not recommended to use this function directly, but to use the
+ set_bond_radius or set_bond_radii functions instead.
"""
_raffle.f90wrap_raffle__dc__set_bond_info__binding__dc_type(this=self._handle)
def set_bond_radius(self, radius_dict):
"""
- set_bond_radius__binding__dc_type(self, elements, radius)
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- lines 1197-1247
+ Set the bond radius for the distribution functions.
- Parameters
- ----------
- this : unknown
- radius_dict : dict
-
- ---------------------------------------------------------------------------
- remove python formatting
- ---------------------------------------------------------------------------
+ Parameters:
+ radius_dict (dict):
+ Dictionary of bond radii.
+ The keys are a tuple of the two element symbols and the values are the bond radii.
"""
# convert radius_dict to elements and radius
@@ -955,17 +817,12 @@ def set_bond_radius(self, radius_dict):
def set_bond_radii(self, radius_dict):
"""
- set_bond_radii__binding__dc_type(self, elements, radii)
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- lines 1251-1266
-
- Parameters
- ----------
- this : unknown
- radius_dict : dict
+ Set the bond radii for the distribution functions.
+ Parameters:
+ radius_dict (dict):
+ Dictionary of bond radii.
+ The keys are a tuple of the two element symbols and the values are the bond radii.
"""
# convert radius_list to elements and radii
@@ -982,21 +839,12 @@ def set_bond_radii(self, radius_dict):
def get_bond_radii(self):
"""
- get_bond_radii_staticmem__binding__dc_type(self, elements, \
- radii)
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- lines 1292-1312
-
- Parameters
- ----------
- this : unknown
-
- Returns
- -------
- bond_radii : dict
+ Get the bond radii for the distribution functions.
+ Returns:
+ bond_radii (dict):
+ Dictionary of bond radii.
+ The keys are a tuple of the two element symbols and the values are the bond radii.
"""
num_elements = _raffle.f90wrap_raffle__dc__get__num_elements(self._handle)
@@ -1021,165 +869,141 @@ def get_bond_radii(self):
def initialise_gdfs(self):
"""
- initialise_gdfs__binding__dc_type(self)
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- lines 1474-1493
-
- Parameters
- ----------
- this : unknown
-
+ Initialise the generalised distribution functions (GDFs).
+
+ It is not recommended to use this function directly, but to use the
+ create or update functions instead.
"""
_raffle.f90wrap_raffle__dc__initialise_gdfs__binding__dc_type(this=self._handle)
def evolve(self): #, system=None):
"""
- evolve__binding__dc_type(self)
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- lines 1539-1838
-
- Parameters
- ----------
- this : unknown
-
- ---------------------------------------------------------------------------
- if present, add the system to the container
- ---------------------------------------------------------------------------
+ Evolve the distribution functions.
+
+ It is not recommended to use this function directly, but to use the
+ create or update functions instead.
"""
_raffle.f90wrap_raffle__dc__evolve__binding__dc_type(this=self._handle)
# _raffle.f90wrap_raffle__dc__evolve__binding__dc_type(this=self._handle, \
# system=None if system is None else system._handle)
- def write(self, file):
+ def write_gdfs(self, file):
"""
- write__binding__dc_type(self, file)
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- lines 510-559
-
- Parameters
- ----------
- this : unknown
- file : str
+ Write the generalised distribution functions (GDFs) to a file.
+ Parameters:
+ file (str):
+ Name of file to write the GDFs to.
"""
- _raffle.f90wrap_raffle__dc__write__binding__dc_type(this=self._handle, \
+ _raffle.f90wrap_raffle__dc__write_gdfs__binding__dc_type(this=self._handle, \
file=file)
- def read(self, file):
+ def read_gdfs(self, file):
"""
- read__binding__dc_type(self, file)
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- lines 563-620
-
- Parameters
- ----------
- this : unknown
- file : str
-
+ Read the generalised distribution functions (GDFs) from a file.
+
+ Parameters:
+ file (str):
+ Name of file to read the GDFs from.
+ """
+ _raffle.f90wrap_raffle__dc__read_gdfs__binding__dc_type(this=self._handle, \
+ file=file)
+
+ def write_dfs(self, file):
+ """
+ Write the distribution functions (DFs) associated with all
+ allocated systems to a file.
+
+ Parameters:
+ file (str):
+ Name of file to write the DFs to.
"""
- _raffle.f90wrap_raffle__dc__read__binding__dc_type(this=self._handle, \
+ _raffle.f90wrap_raffle__dc__write_dfs__binding__dc_type(this=self._handle, \
+ file=file)
+
+ def read_dfs(self, file):
+ """
+ Read the distribution functions (DFs) associated with a set of
+ systems from a file.
+
+ Parameters:
+ file (str):
+ Name of file to read the DFs from.
+ """
+ _raffle.f90wrap_raffle__dc__read_dfs__binding__dc_type(this=self._handle, \
file=file)
def write_2body(self, file):
"""
- write_2body__binding__dc_type(self, file)
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- lines 624-663
-
- Parameters
- ----------
- this : unknown
- file : str
+ Write the 2-body generalised distribution functions (GDFs) to a file.
+ Parameters:
+ file (str):
+ Name of file to write the 2-body GDFs to.
"""
_raffle.f90wrap_raffle__dc__write_2body__binding__dc_type(this=self._handle, \
file=file)
def write_3body(self, file):
"""
- write_3body__binding__dc_type(self, file)
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- lines 667-689
-
- Parameters
- ----------
- this : unknown
- file : str
+ Write the 3-body generalised distribution functions (GDFs) to a file.
+ Parameters:
+ file (str):
+ Name of file to write the 3-body GDFs to.
"""
_raffle.f90wrap_raffle__dc__write_3body__binding__dc_type(this=self._handle, \
file=file)
def write_4body(self, file):
"""
- write_4body__binding__dc_type(self, file)
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- lines 693-715
-
- Parameters
- ----------
- this : unknown
- file : str
+ Write the 4-body generalised distribution functions (GDFs) to a file.
+ Parameters:
+ file (str):
+ Name of file to write the 4-body GDFs to.
"""
_raffle.f90wrap_raffle__dc__write_4body__binding__dc_type(this=self._handle, \
file=file)
- def get_pair_index(self, species1, species2):
+ def _get_pair_index(self, species1, species2):
"""
- idx = get_pair_index__binding__dc_type(self, species1, species2)
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- lines 1408-1430
+ Get the index of the pair of species in the distribution functions.
+
+ This is meant as an internal function and not likely to be used directly.
- Parameters
- ----------
- this : unknown
- species1 : str
- species2 : str
-
- Returns
- -------
- idx : int
+ Parameters:
+ species1 (str):
+ Name of the first species
+ species2 (str):
+ Name of the second species
+ Returns:
+ idx (int):
+ Index of the pair of species in the distribution functions.
"""
idx = \
_raffle.f90wrap_raffle__dc__get_pair_index__binding__dc_type(this=self._handle, \
species1=species1, species2=species2)
return idx
- def get_bin(self, value, dim):
+ def _get_bin(self, value, dim):
"""
- bin = get_bin__binding__dc_type(self, value, dim)
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- lines 1451-1470
-
- Parameters
- ----------
- this : unknown
- value : float
- dim : int
+ Get the bin index for a value in the distribution functions.
+
+ This is meant as an internal function and not likely to be used directly.
+
+ Parameters:
+ value (float):
+ Value to get the bin index for.
+ dim (int):
+ Dimension of the distribution function.
+ 1 for 2-body, 2 for 3-body, and 3 for 4-body.
Returns
-------
- bin : int
+ bin (int):
+ Bin index for the value in the distribution functions.
"""
bin = \
@@ -1190,12 +1014,7 @@ def get_bin(self, value, dim):
@property
def num_evaluated(self):
"""
- Element num_evaluated ftype=integer pytype=int
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- line 30
-
+ Number of evaluated distribution functions.
"""
return _raffle.f90wrap_distribs_container_type__get__num_evaluated(self._handle)
@@ -1207,12 +1026,7 @@ def num_evaluated(self, num_evaluated):
@property
def num_evaluated_allocated(self):
"""
- Element num_evaluated_allocated ftype=integer pytype=int
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- line 32
-
+ Number of evaluated distribution functions still allocated.
"""
return \
_raffle.f90wrap_distribs_container_type__get__num_evaluated_allocated(self._handle)
@@ -1225,12 +1039,7 @@ def num_evaluated_allocated(self, num_evaluated_allocated):
@property
def kBT(self):
"""
- Element kBT ftype=real(real32) pytype=float
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- line 34
-
+ Energy scale for the distribution functions.
"""
return _raffle.f90wrap_distribs_container_type__get__kbt(self._handle)
@@ -1241,12 +1050,7 @@ def kBT(self, kBT):
@property
def weight_by_hull(self):
"""
- Element weight_by_hull ftype=logical pytype=bool
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- line 36
-
+ Boolean whether to weight the distribution functions by the energy above hull.
"""
return \
_raffle.f90wrap_distribs_container_type__get__weight_by_hull(self._handle)
@@ -1259,12 +1063,7 @@ def weight_by_hull(self, weight_by_hull):
@property
def nbins(self):
"""
- Element nbins ftype=integer pytype=int
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- line 54
-
+ Number of bins in the distribution functions.
"""
array_ndim, array_type, array_shape, array_handle = \
_raffle.f90wrap_distribs_container_type__array__nbins(self._handle)
@@ -1284,12 +1083,8 @@ def nbins(self, nbins):
@property
def sigma(self):
"""
- Element sigma ftype=real(real32) pytype=float
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- line 57
-
+ Sigma values for the Gaussians used by the
+ 2-, 3-, and 4-body distribution functions.
"""
array_ndim, array_type, array_shape, array_handle = \
_raffle.f90wrap_distribs_container_type__array__sigma(self._handle)
@@ -1309,12 +1104,7 @@ def sigma(self, sigma):
@property
def width(self):
"""
- Element width ftype=real(real32) pytype=float
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- line 61
-
+ Bin widths for the 2-, 3-, and 4-body distribution functions.
"""
array_ndim, array_type, array_shape, array_handle = \
_raffle.f90wrap_distribs_container_type__array__width(self._handle)
@@ -1334,12 +1124,7 @@ def width(self, width):
@property
def cutoff_min(self):
"""
- Element cutoff_min ftype=real(real32) pytype=float
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- line 64
-
+ The lower cutoff values for the 2-, 3-, and 4-body distribution functions.
"""
array_ndim, array_type, array_shape, array_handle = \
_raffle.f90wrap_distribs_container_type__array__cutoff_min(self._handle)
@@ -1359,12 +1144,7 @@ def cutoff_min(self, cutoff_min):
@property
def cutoff_max(self):
"""
- Element cutoff_max ftype=real(real32) pytype=float
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- line 67
-
+ The upper cutoff values for the 2-, 3-, and 4-body distribution functions.
"""
array_ndim, array_type, array_shape, array_handle = \
_raffle.f90wrap_distribs_container_type__array__cutoff_max(self._handle)
@@ -1384,12 +1164,15 @@ def cutoff_max(self, cutoff_max):
@property
def radius_distance_tol(self):
"""
- Element radius_distance_tol ftype=real(real32) pytype=float
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- line 70
+ The radius distance tolerance for the distribution functions.
+
+ The radius distance tolerance represents a multiplier to the bond radii to
+ determine the cutoff distance for the distribution functions.
+ The first two values are the lower and upper bounds for the
+ 3-body distribution function radius distance tolerance.
+ The third and fourth values are the lower and upper bounds for the
+ 4-body distribution function radius distance tolerance.
"""
array_ndim, array_type, array_shape, array_handle = \
_raffle.f90wrap_distribs_container_type__array__radius_distance_tol(self._handle)
@@ -1407,42 +1190,6 @@ def radius_distance_tol(self):
def radius_distance_tol(self, radius_distance_tol):
self.radius_distance_tol[...] = radius_distance_tol
- # @property
- # def total(self):
- # """
- # Element total ftype=type(distribs_base_type) pytype=Distribs_Base_Type
-
-
- # Defined at ../src/lib/mod_distribs_container.f90 line 38
-
- # """
- # total_handle = _raffle.f90wrap_distribs_container_type__get__total(self._handle)
- # if tuple(total_handle) in self._objs:
- # total = self._objs[tuple(total_handle)]
- # else:
- # total = distribs.distribs_base_type.from_handle(total_handle)
- # self._objs[tuple(total_handle)] = total
- # return total
-
- # @total.setter
- # def total(self, total):
- # total = total._handle
- # _raffle.f90wrap_distribs_container_type__set__total(self._handle, total)
-
- # def _init_array_system(self):
- # self.system = f90wrap.runtime.FortranDerivedTypeArray(self,
- # _raffle.f90wrap_distribs_container_type__array_getitem__system,
- # _raffle.f90wrap_distribs_container_type__array_setitem__system,
- # _raffle.f90wrap_distribs_container_type__array_len__system,
- # """
- # Element system ftype=type(distribs_type) pytype=Distribs_Type
-
-
- # Defined at ../src/lib/mod_distribs_container.f90 line 39
-
- # """, Distribs.distribs_type)
- # return self.system
-
def __str__(self):
ret = ['{\n']
ret.append(' num_evaluated : ')
@@ -1465,8 +1212,6 @@ def __str__(self):
ret.append(repr(self.cutoff_max))
ret.append(',\n radius_distance_tol : ')
ret.append(repr(self.radius_distance_tol))
- # ret.append(',\n total : ')
- # ret.append(repr(self.total))
ret.append('}')
return ''.join(ret)
@@ -1480,39 +1225,24 @@ def __str__(self):
class Generator(f90wrap.runtime.FortranModule):
"""
- Module generator
-
+ Code for generating interface structures.
+
+ The module handles converting Python objects to Fortran objects and vice versa.
+ These include converting between dictionaries and Fortran derived types, and
+ between ASE Atoms objects and Fortran derived types.
- Defined at ../src/lib/mod_generator.f90 lines \
- 1-286
+ Defined in ../src/lib/mod_generator.f90
"""
@f90wrap.runtime.register_class("raffle.stoichiometry_type")
class stoichiometry_type(f90wrap.runtime.FortranDerivedType):
- """
- Type(name=stoichiometry_type)
-
-
- Defined at ../src/lib/mod_generator.f90 lines \
- 19-21
-
- """
def __init__(self, dict=None, element=None, num=None, handle=None):
"""
- self = Stoichiometry_Type()
+ Object to store the stoichiometry of a structure.
-
- Defined at ../src/lib/mod_generator.f90 lines \
- 19-21
-
-
- Returns
- -------
- this : Stoichiometry_Type
- Object to be constructed
-
-
- Automatically generated constructor for stoichiometry_type
+ Returns:
+ stoichiometry (stoichiometry_type):
+ Stoichiometry object
"""
f90wrap.runtime.FortranDerivedType.__init__(self)
result = _raffle.f90wrap_stoichiometry_type_initialise()
@@ -1532,12 +1262,6 @@ def __del__(self):
Defined at ../src/lib/mod_generator.f90 lines \
19-21
- Parameters
- ----------
- this : Stoichiometry_Type
- Object to be destructed
-
-
Automatically generated destructor for stoichiometry_type
"""
if self._alloc:
@@ -1546,12 +1270,7 @@ def __del__(self):
@property
def element(self):
"""
- Element element ftype=character(len=3) pytype=str
-
-
- Defined at ../src/lib/mod_generator.f90 line \
- 20
-
+ String representing an element symbol.
"""
return _raffle.f90wrap_stoichiometry_type__get__element(self._handle)
@@ -1562,12 +1281,7 @@ def element(self, element):
@property
def num(self):
"""
- Element num ftype=integer pytype=int
-
-
- Defined at ../src/lib/mod_generator.f90 line \
- 21
-
+ Integer representing the number of atoms of the element.
"""
return _raffle.f90wrap_stoichiometry_type__get__num(self._handle)
@@ -1589,34 +1303,15 @@ def __str__(self):
@f90wrap.runtime.register_class("raffle.stoichiometry_array")
class stoichiometry_array(f90wrap.runtime.FortranDerivedType):
- """
- Type(name=stoichiometry_array)
-
-
- Defined at ../src/lib/mod_generator.f90 lines \
- 19-21
-
- """
def __init__(self, dict=None, handle=None):
"""
- self = Stoichiometry_Type()
-
-
- Defined at ../src/lib/mod_generator.f90 lines \
- 19-21
-
-
- Returns
- -------
- this : Stoichiometry_Type
- Object to be constructed
-
+ Array or list of stoichiometry objects.
- Automatically generated constructor for stoichiometry_type
+ Returns:
+ stoichiometry_array (stoichiometry_array):
+ Stoichiometry array object
"""
-
-
f90wrap.runtime.FortranDerivedType.__init__(self)
result = _raffle.f90wrap_generator__stoich_type_xnum_array_initialise()
self._handle = result[0] if isinstance(result, tuple) else result
@@ -1664,19 +1359,17 @@ def _init_array_items(self):
def allocate(self, size):
"""
- Allocate the items array with the given size
+ Allocate the items array with the given size.
- Parameters
- ----------
- self : Stoichiometry_Type
- size : int
- Size of the items array
+ Parameters:
+ size (int):
+ Size of the items array
"""
_raffle.f90wrap_stoich_type_xnum_array__array_alloc__items(self._handle, num=size)
def deallocate(self):
"""
- Deallocate the items array
+ Deallocate the items array.
"""
_raffle.f90wrap_stoich_type_xnum_array__array_dealloc__items(self._handle)
@@ -1687,30 +1380,14 @@ def deallocate(self):
@f90wrap.runtime.register_class("raffle.raffle_generator")
class raffle_generator(f90wrap.runtime.FortranDerivedType):
- """
- Type(name=raffle_generator)
-
-
- Defined at ../src/lib/mod_generator.f90 lines \
- 23-34
-
- """
+
def __init__(self, handle=None):
"""
- self = raffle_generator()
-
-
- Defined at ../src/lib/mod_generator.f90 lines \
- 23-34
-
-
- Returns
- -------
- this : raffle_generator
- Object to be constructed
-
-
- Automatically generated constructor for raffle_generator
+ Create a ``raffle_generator`` object.
+
+ This object is used to generate structures using the RAFFLE method.
+ The object has procedures to set the parameters for the generation
+ and to generate the structures.
"""
f90wrap.runtime.FortranDerivedType.__init__(self)
result = _raffle.f90wrap_generator__raffle_generator_type_initialise()
@@ -1724,35 +1401,31 @@ def __del__(self):
Defined at ../src/lib/mod_generator.f90 lines \
23-34
- Parameters
- ----------
- this : raffle_generator
- Object to be destructed
-
-
- Automatically generated destructor for raffle_generator
"""
if self._alloc:
_raffle.f90wrap_generator__raffle_generator_type_finalise(this=self._handle)
def set_max_attempts(self, max_attempts):
"""
- Parameters
- ----------
- this : unknown
- max_attempts : integer
-
+ Set the walk-method maximum attempts parameter.
+ This parameter determines the maximum number of attempts to generate a structure
+ using the walk method before reverting to the void method.
+
+ Parameters:
+ max_attempts (int):
+ The maximum number of attempts to generate a structure using the walk method.
"""
self.max_attempts = max_attempts
def set_walk_step_size(self, coarse=None, fine=None):
"""
- Parameters
- ----------
- this : unknown
- coarse : float
- fine: float
-
+ Set the walk-method step size parameters.
+
+ Parameters:
+ coarse (float):
+ The coarse step size for the walk method.
+ fine (float):
+ The fine step size for the walk method.
"""
if coarse is not None:
self.walk_step_size_coarse = coarse
@@ -1761,20 +1434,14 @@ def set_walk_step_size(self, coarse=None, fine=None):
def set_host(self, host):
"""
- set_host__binding__raffle_generator(self, host)
-
-
- Defined at ../src/lib/mod_generator.f90 lines \
- 99-108
-
- Parameters
- ----------
- this : unknown
- host : basis
+ Set the host structure for the generation.
+ Parameters:
+ host (ase.Atoms or geom_rw.basis):
+ The host structure for the generation.
"""
from ase import Atoms
- # check if host is ase.Atoms object
+ # check if host is ase.Atoms object or a Fortran derived type basis_type
if isinstance(host, Atoms):
host = geom_rw.basis(atoms=host)
@@ -1783,54 +1450,61 @@ def set_host(self, host):
def set_grid(self, grid=None, grid_spacing=None, grid_offset=None):
"""
- set_grid__binding__raffle_generator(self[, grid, grid_spacing, \
- grid_offset])
-
-
- Defined at ../fortran/lib/mod_generator.f90 lines \
- 142-173
-
- Parameters
- ----------
- this : unknown
- grid : int array
- grid_spacing : float
- grid_offset : float array
-
+ Set the grid parameters for the generation.
+
+ Parameters:
+ grid (list of int):
+ The number of grid points along each axis of the host.
+ grid_spacing (float)
+ The spacing between grid points.
+ grid_offset (list of float):
+ The offset of the grid from the origin.
"""
_raffle.f90wrap_generator__set_grid__binding__raffle_generator_type(this=self._handle, \
grid=grid, grid_spacing=grid_spacing, grid_offset=grid_offset)
def reset_grid(self):
"""
- reset_grid__binding__raffle_generator(self)
-
-
- Defined at ../fortran/lib/mod_generator.f90 lines \
- 170-176
-
- Parameters
- ----------
- this : unknown
-
+ Reset the grid parameters to their default values.
"""
_raffle.f90wrap_generator__reset_grid__binding__raffle_generator_type(this=self._handle)
- def generate(self, num_structures, stoichiometry, method_probab={"void": 0.0, "rand": 0.0, "walk": 0.0, "grow": 0.0, "min": 0.0}, seed=None, verbose=0):
+ def set_bounds(self, bounds=None):
"""
- generate__binding__raffle_generator(self, num_structures, stoichiometry, method_probab)
+ Set the bounding box for the generation.
- Defined at ../src/lib/mod_generator.f90 lines \
- 76-84
+ Parameters:
+ bounds (list of list of float):
+ The bounding box within which to constrain placement of atoms.
+ In the form [[a_min, a_max], [b_min, b_max], [c_min, c_max]].
+ Values given in direct (crystal) coordinates, ranging from 0 to 1.
+ """
+ _raffle.f90wrap_generator__set_bounds__binding__rgt(this=self._handle, \
+ bounds=bounds)
+
+ def reset_bounds(self):
+ """
+ Reset the bounding box to the full host structure.
+ """
+ _raffle.f90wrap_generator__reset_bounds__binding__rgt(this=self._handle)
- Parameters
- ----------
- this : unknown
- num_structures : int
- stoichiometry : stoichiometry_array
- method_probab : dict
- verbose : int
+ def generate(self, num_structures, stoichiometry, method_probab={"void": 0.0, "rand": 0.0, "walk": 0.0, "grow": 0.0, "min": 0.0}, seed=None, settings_out_file=None, verbose=0):
+ """
+ Generate structures using the RAFFLE method.
+ Parameters:
+ num_structures (int):
+ The number of structures to generate.
+ stoichiometry (stoichiometry_array or dict):
+ The stoichiometry of the structures to generate.
+ method_probab (dict):
+ The probabilities of using each method to generate a structure.
+ seed (int):
+ The seed for the random number generator.
+ print_settings (bool):
+ Boolean whether to print the settings for the generation.
+ verbose (int):
+ The verbosity level for the generation.
"""
method_probab_list = []
@@ -1853,53 +1527,101 @@ def generate(self, num_structures, stoichiometry, method_probab={"void": 0.0, "r
this=self._handle,
num_structures=num_structures,
stoichiometry=stoichiometry._handle,
- method_probab=method_probab_list, seed=seed, verbose=verbose)
+ method_probab=method_probab_list,
+ settings_out_file=settings_out_file,
+ seed=seed, verbose=verbose)
else:
_raffle.f90wrap_generator__generate__binding__rgt(
this=self._handle,
num_structures=num_structures,
stoichiometry=stoichiometry._handle,
- method_probab=method_probab_list, verbose=verbose)
+ method_probab=method_probab_list,
+ settings_out_file=settings_out_file,
+ verbose=verbose)
def get_structures(self, calculator=None):
+ """
+ Get the generated structures as a list of ASE Atoms objects.
+
+ Parameters:
+ calculator (ASE calculator):
+ The calculator to use for the generated structures.
+ """
atoms = []
for structure in self.structures:
atoms.append(structure.toase(calculator))
return atoms
+
+ def set_structures(self, structures):
+ """
+ Set the list of generated structures.
+ Parameters:
+ structures (list of geom_rw.basis or list of ase.Atoms):
+ The list of structures to set.
+ """
+ structures = geom_rw.basis_array(atoms=structures)
+ _raffle.f90wrap_generator__set_structures__binding__rgt(this=self._handle, \
+ structures=structures._handle)
+
+ def remove_structure(self, index):
+ """
+ Remove the structure at the given indices from the generator.
+
+ Parameters:
+ index (int or list of int):
+ The indices of the structure to remove.
+ """
+ index_list = [index] if isinstance(index, int) else index
+ index_list = [ i + 1 for i in index_list ]
+ _raffle.f90wrap_generator__remove_structure__binding__rgt(this=self._handle, \
+ index_bn=index_list)
def evaluate(self, basis):
"""
- viability = evaluate__binding__raffle_generator(self, basis)
-
-
- Defined at ../src/lib/mod_generator.f90 lines \
- 311-322
-
- Parameters
- ----------
- this : unknown
- basis : basis
+ Evaluate the viability of the structures.
+
+ WARNING: This function is not implemented yet.
- Returns
- -------
- viability : float
+ Parameters:
+ basis (geom_rw.basis):
+ The basis to use for the evaluation.
+ Returns:
+ viability (float):
+ The viability of the structures.
"""
viability = \
_raffle.f90wrap_generator__evaluate__binding__rgt(this=self._handle, \
basis=basis._handle)
return viability
+ def print_settings(self, file):
+ """
+ Print the settings for the generation to a file.
+
+ Parameters:
+ file (str):
+ Name of the file to write the settings to.
+ """
+ _raffle.f90wrap_generator__print_settings__binding__rgt(this=self._handle, \
+ file=file)
+
+ def read_settings(self, file):
+ """
+ Read the settings for the generation from a file.
+
+ Parameters:
+ file (str):
+ Name of the file to read the settings from.
+ """
+ _raffle.f90wrap_generator__read_settings__binding__rgt(this=self._handle, \
+ file=file)
+
@property
def num_structures(self):
"""
- Element num_structures ftype=integer pytype=int
-
-
- Defined at ../src/lib/mod_generator.f90 line \
- 24
-
+ The number of generated structures currently stored in the generator.
"""
return _raffle.f90wrap_raffle_generator_type__get__num_structures(self._handle)
@@ -1911,12 +1633,7 @@ def num_structures(self, num_structures):
@property
def host(self):
"""
- Element host ftype=type(basis_type) pytype=basis
-
-
- Defined at ../src/lib/mod_generator.f90 line \
- 25
-
+ The host structure for the generation.
"""
host_handle = _raffle.f90wrap_raffle_generator_type__get__host(self._handle)
if tuple(host_handle) in self._objs:
@@ -1934,12 +1651,7 @@ def host(self, host):
@property
def grid(self):
"""
- Element grid ftype=integer pytype=int
-
-
- Defined at ../src/lib/mod_generator.f90 line \
- 24
-
+ The grid parameters for the generation.
"""
array_ndim, array_type, array_shape, array_handle = \
_raffle.f90wrap_raffle_generator_type__array__grid(self._handle)
@@ -1959,12 +1671,7 @@ def grid(self, grid):
@property
def grid_offset(self):
"""
- Element grid_offset ftype=real pytype=float
-
-
- Defined at ../fortran/lib/mod_generator.f90 line \
- 45
-
+ The offset of the grid from the origin.
"""
array_ndim, array_type, array_shape, array_handle = \
_raffle.f90wrap_raffle_generator_type__array__grid_offset(self._handle)
@@ -1984,12 +1691,7 @@ def grid_offset(self, grid_offset):
@property
def grid_spacing(self):
"""
- Element grid_spacing ftype=real(real32) pytype=float
-
-
- Defined at ../fortran/lib/mod_generator.f90 line \
- 47
-
+ The spacing between grid points.
"""
return _raffle.f90wrap_raffle_generator_type__get__grid_spacing(self._handle)
@@ -1997,17 +1699,31 @@ def grid_spacing(self):
def grid_spacing(self, grid_spacing):
_raffle.f90wrap_raffle_generator_type__set__grid_spacing(self._handle, \
grid_spacing)
+
+ @property
+ def bounds(self):
+ """
+ The bounds in direct coordinates of the host cell for the generation.
+ """
+ array_ndim, array_type, array_shape, array_handle = \
+ _raffle.f90wrap_raffle_generator_type__array__bounds(self._handle)
+ if array_handle in self._arrays:
+ bounds = self._arrays[array_handle]
+ else:
+ bounds = f90wrap.runtime.get_array(f90wrap.runtime.sizeof_fortran_t,
+ self._handle,
+ _raffle.f90wrap_raffle_generator_type__array__bounds)
+ self._arrays[array_handle] = bounds
+ return bounds
+ @bounds.setter
+ def bounds(self, bounds):
+ self.bounds[...] = bounds
+
@property
def distributions(self):
"""
- Element distributions ftype=type(distribs_container_type) \
- pytype=Distribs_Container_Type
-
-
- Defined at ../fortran/lib/mod_generator.f90 line \
- 54
-
+ The container for the distribution functions used in the generation.
"""
distributions_handle = \
_raffle.f90wrap_raffle_generator_type__get__distributions(self._handle)
@@ -2028,12 +1744,7 @@ def distributions(self, distributions):
@property
def max_attempts(self):
"""
- Element max_attempts ftype=integer pytype=int
-
-
- Defined at ../src/lib/mod_generator.f90 line \
- 24
-
+ The maximum number of attempts to generate a structure using the walk method.
"""
return _raffle.f90wrap_raffle_generator_type__get__max_attempts(self._handle)
@@ -2045,13 +1756,7 @@ def max_attempts(self, max_attempts):
@property
def walk_step_size_coarse(self):
"""
- Element walk_step_size_coarse ftype=real(real12) pytype=float
-
-
- Defined at \
- /Users/nedtaylor/DCoding/DGit/raffle/src/fortran/lib/mod_generator.f90 line \
- 60
-
+ The coarse step size for the walk method.
"""
return \
_raffle.f90wrap_raffle_generator_type__get__walk_step_size_coarse(self._handle)
@@ -2064,13 +1769,7 @@ def walk_step_size_coarse(self, walk_step_size_coarse):
@property
def walk_step_size_fine(self):
"""
- Element walk_step_size_fine ftype=real(real12) pytype=float
-
-
- Defined at \
- /Users/nedtaylor/DCoding/DGit/raffle/src/fortran/lib/mod_generator.f90 line \
- 60
-
+ The fine step size for the walk method.
"""
return \
_raffle.f90wrap_raffle_generator_type__get__walk_step_size_fine(self._handle)
@@ -2083,12 +1782,7 @@ def walk_step_size_fine(self, walk_step_size_fine):
@property
def method_probab(self):
"""
- Element method_probab ftype=real(real32) pytype=float
-
-
- Defined at ../src/lib/mod_generator.f90 line \
- 67
-
+ The probabilities of using each method to generate a structure.
"""
array_ndim, array_type, array_shape, array_handle = \
_raffle.f90wrap_raffle_generator_type__array__method_probab(self._handle)
@@ -2106,6 +1800,11 @@ def method_probab(self, method_probab):
self.method_probab[...] = method_probab
def _init_array_structures(self):
+ """
+ Initialise the structures array.
+
+ It is not recommended to use this function directly. Use the `structures` property instead.
+ """
self.structures = f90wrap.runtime.FortranDerivedTypeArray(self,
_raffle.f90wrap_raffle_generator_type__array_getitem__structures,
_raffle.f90wrap_raffle_generator_type__array_setitem__structures,
@@ -2132,6 +1831,8 @@ def __str__(self):
ret.append(repr(self.grid_offset))
ret.append(',\n grid_spacing : ')
ret.append(repr(self.grid_spacing))
+ ret.append(',\n bounds : ')
+ ret.append(repr(self.bounds))
ret.append(',\n distributions : ')
ret.append(repr(self.distributions))
ret.append(',\n max_attempts : ')
diff --git a/src/wrapper/f90wrap_mod_distribs_container.f90 b/src/wrapper/f90wrap_mod_distribs_container.f90
index 2b85698a..9d030f28 100644
--- a/src/wrapper/f90wrap_mod_distribs_container.f90
+++ b/src/wrapper/f90wrap_mod_distribs_container.f90
@@ -789,7 +789,7 @@ end subroutine f90wrap_raffle__dc__evolve__binding__dc_type
!###############################################################################
! read and write distribution functions to file
!###############################################################################
-subroutine f90wrap_raffle__dc__read__binding__dc_type( &
+subroutine f90wrap_raffle__dc__read_gdfs__binding__dc_type( &
this, file &
)
use raffle__distribs_container, only: distribs_container_type
@@ -802,10 +802,10 @@ subroutine f90wrap_raffle__dc__read__binding__dc_type( &
integer, intent(in), dimension(2) :: this
character*(*), intent(in) :: file
this_ptr = transfer(this, this_ptr)
- call this_ptr%p%read(file=file)
-end subroutine f90wrap_raffle__dc__read__binding__dc_type
+ call this_ptr%p%read_gdfs(file=file)
+end subroutine f90wrap_raffle__dc__read_gdfs__binding__dc_type
-subroutine f90wrap_raffle__dc__write__binding__dc_type( &
+subroutine f90wrap_raffle__dc__write_gdfs__binding__dc_type( &
this, file &
)
use raffle__distribs_container, only: distribs_container_type
@@ -818,8 +818,40 @@ subroutine f90wrap_raffle__dc__write__binding__dc_type( &
integer, intent(in), dimension(2) :: this
character*(*), intent(in) :: file
this_ptr = transfer(this, this_ptr)
- call this_ptr%p%write(file=file)
-end subroutine f90wrap_raffle__dc__write__binding__dc_type
+ call this_ptr%p%write_gdfs(file=file)
+end subroutine f90wrap_raffle__dc__write_gdfs__binding__dc_type
+
+subroutine f90wrap_raffle__dc__read_dfs__binding__dc_type( &
+ this, file &
+)
+ use raffle__distribs_container, only: distribs_container_type
+ implicit none
+
+ type distribs_container_type_ptr_type
+ type(distribs_container_type), pointer :: p => NULL()
+ end type distribs_container_type_ptr_type
+ type(distribs_container_type_ptr_type) :: this_ptr
+ integer, intent(in), dimension(2) :: this
+ character*(*), intent(in) :: file
+ this_ptr = transfer(this, this_ptr)
+ call this_ptr%p%read_dfs(file=file)
+end subroutine f90wrap_raffle__dc__read_dfs__binding__dc_type
+
+subroutine f90wrap_raffle__dc__write_dfs__binding__dc_type( &
+ this, file &
+)
+ use raffle__distribs_container, only: distribs_container_type
+ implicit none
+
+ type distribs_container_type_ptr_type
+ type(distribs_container_type), pointer :: p => NULL()
+ end type distribs_container_type_ptr_type
+ type(distribs_container_type_ptr_type) :: this_ptr
+ integer, intent(in), dimension(2) :: this
+ character*(*), intent(in) :: file
+ this_ptr = transfer(this, this_ptr)
+ call this_ptr%p%write_dfs(file=file)
+end subroutine f90wrap_raffle__dc__write_dfs__binding__dc_type
subroutine f90wrap_raffle__dc__write_2body__binding__dc_type( &
this, file &
diff --git a/src/wrapper/f90wrap_mod_generator.f90 b/src/wrapper/f90wrap_mod_generator.f90
index 67480ce9..689fade8 100644
--- a/src/wrapper/f90wrap_mod_generator.f90
+++ b/src/wrapper/f90wrap_mod_generator.f90
@@ -405,6 +405,29 @@ subroutine f90wrap_raffle_generator_type__set__grid_spacing( &
this_ptr = transfer(this, this_ptr)
this_ptr%p%grid_spacing = f90wrap_grid_spacing
end subroutine f90wrap_raffle_generator_type__set__grid_spacing
+
+subroutine f90wrap_raffle_generator_type__array__bounds( &
+ this, nd, dtype, dshape, dloc &
+)
+ use raffle__generator, only: raffle_generator_type
+ use, intrinsic :: iso_c_binding, only : c_int
+ implicit none
+ type raffle_generator_type_ptr_type
+ type(raffle_generator_type), pointer :: p => NULL()
+ end type raffle_generator_type_ptr_type
+ integer(c_int), intent(in) :: this(2)
+ type(raffle_generator_type_ptr_type) :: this_ptr
+ integer(c_int), intent(out) :: nd
+ integer(c_int), intent(out) :: dtype
+ integer(c_int), dimension(10), intent(out) :: dshape
+ integer*8, intent(out) :: dloc
+
+ nd = 2
+ dtype = 11
+ this_ptr = transfer(this, this_ptr)
+ dshape(1:2) = shape(this_ptr%p%bounds)
+ dloc = loc(this_ptr%p%bounds)
+end subroutine f90wrap_raffle_generator_type__array__bounds
!###############################################################################
@@ -769,9 +792,36 @@ subroutine f90wrap_generator__reset_grid__binding__raffle_generator_type(this)
call this_ptr%p%reset_grid()
end subroutine f90wrap_generator__reset_grid__binding__raffle_generator_type
+subroutine f90wrap_generator__set_bounds__binding__rgt(this, bounds)
+ use raffle__generator, only: raffle_generator_type
+ implicit none
+
+ type raffle_generator_type_ptr_type
+ type(raffle_generator_type), pointer :: p => NULL()
+ end type raffle_generator_type_ptr_type
+ type(raffle_generator_type_ptr_type) :: this_ptr
+ integer, intent(in), dimension(2) :: this
+ real(4), dimension(2,3), intent(in) :: bounds
+ this_ptr = transfer(this, this_ptr)
+ call this_ptr%p%set_bounds(bounds=bounds)
+end subroutine f90wrap_generator__set_bounds__binding__rgt
+
+subroutine f90wrap_generator__reset_bounds__binding__rgt(this)
+ use raffle__generator, only: raffle_generator_type
+ implicit none
+
+ type raffle_generator_type_ptr_type
+ type(raffle_generator_type), pointer :: p => NULL()
+ end type raffle_generator_type_ptr_type
+ type(raffle_generator_type_ptr_type) :: this_ptr
+ integer, intent(in), dimension(2) :: this
+ this_ptr = transfer(this, this_ptr)
+ call this_ptr%p%reset_bounds()
+end subroutine f90wrap_generator__reset_bounds__binding__rgt
+
subroutine f90wrap_generator__generate__binding__rgt( &
this, num_structures, stoichiometry, &
- method_probab, seed, verbose)
+ method_probab, seed, settings_out_file, verbose)
use raffle__generator, only: raffle_generator_type, stoichiometry_type
implicit none
@@ -793,6 +843,7 @@ subroutine f90wrap_generator__generate__binding__rgt( &
type(stoichiometry_type_xnum_array_ptr_type) :: stoichiometry_ptr
integer, intent(in), dimension(2) :: stoichiometry
real(4), intent(in), optional, dimension(5) :: method_probab
+ character*(*), intent(in), optional :: settings_out_file
integer, intent(in), optional :: seed
integer, intent(in), optional :: verbose
@@ -803,32 +854,38 @@ subroutine f90wrap_generator__generate__binding__rgt( &
stoichiometry=stoichiometry_ptr%p%items, &
method_probab=method_probab, &
seed=seed, &
+ settings_out_file=settings_out_file, &
verbose=verbose &
)
end subroutine f90wrap_generator__generate__binding__rgt
-subroutine f90wrap_generator__evaluate__binding__rgt(this, ret_viability, basis)
+subroutine f90wrap_generator__get_structures__binding__rgt(this, ret_structures)
use raffle__geom_rw, only: basis_type
use raffle__generator, only: raffle_generator_type
implicit none
-
+
type raffle_generator_type_ptr_type
type(raffle_generator_type), pointer :: p => NULL()
end type raffle_generator_type_ptr_type
- type basis_type_ptr_type
- type(basis_type), pointer :: p => NULL()
- end type basis_type_ptr_type
+
+ type basis_type_xnum_array
+ type(basis_type), dimension(:), allocatable :: items
+ end type basis_type_xnum_array
+
+ type basis_type_xnum_array_ptr_type
+ type(basis_type_xnum_array), pointer :: p => NULL()
+ end type basis_type_xnum_array_ptr_type
type(raffle_generator_type_ptr_type) :: this_ptr
integer, intent(in), dimension(2) :: this
- real(4), intent(out) :: ret_viability
- type(basis_type_ptr_type) :: basis_ptr
- integer, intent(in), dimension(2) :: basis
+ integer, intent(out), dimension(2) :: ret_structures
+ type(basis_type_xnum_array_ptr_type) :: ret_structures_ptr
+
this_ptr = transfer(this, this_ptr)
- basis_ptr = transfer(basis, basis_ptr)
- ret_viability = this_ptr%p%evaluate(basis=basis_ptr%p)
-end subroutine f90wrap_generator__evaluate__binding__rgt
+ ret_structures_ptr%p%items = this_ptr%p%get_structures()
+ ret_structures = transfer(ret_structures_ptr,ret_structures)
+end subroutine f90wrap_generator__get_structures__binding__rgt
-subroutine f90wrap_generator__get_structures__binding__rgt(this, ret_structures)
+subroutine f90wrap_generator__set_structures__binding__rgt(this, structures)
use raffle__geom_rw, only: basis_type
use raffle__generator, only: raffle_generator_type
implicit none
@@ -846,13 +903,84 @@ subroutine f90wrap_generator__get_structures__binding__rgt(this, ret_structures)
end type basis_type_xnum_array_ptr_type
type(raffle_generator_type_ptr_type) :: this_ptr
integer, intent(in), dimension(2) :: this
- integer, intent(out), dimension(2) :: ret_structures
- type(basis_type_xnum_array_ptr_type) :: ret_structures_ptr
+ integer, intent(in), dimension(2) :: structures
+ type(basis_type_xnum_array_ptr_type) :: structures_ptr
this_ptr = transfer(this, this_ptr)
- ret_structures_ptr%p%items = this_ptr%p%get_structures()
- ret_structures = transfer(ret_structures_ptr,ret_structures)
-end subroutine f90wrap_generator__get_structures__binding__rgt
+ structures_ptr = transfer(structures, structures_ptr)
+ call this_ptr%p%set_structures(structures_ptr%p%items)
+end subroutine f90wrap_generator__set_structures__binding__rgt
+
+subroutine f90wrap_generator__remove_structure__binding__rgt(this, index_bn, n0)
+ use raffle__generator, only: raffle_generator_type
+ implicit none
+
+ type raffle_generator_type_ptr_type
+ type(raffle_generator_type), pointer :: p => NULL()
+ end type raffle_generator_type_ptr_type
+ type(raffle_generator_type_ptr_type) :: this_ptr
+ integer, intent(in), dimension(2) :: this
+ integer, dimension(n0), intent(in) :: index_bn
+ integer :: n0
+ !f2py intent(hide), depend(energy_above_hull_list) :: n0 = shape(energy_above_hull_list,0)
+ this_ptr = transfer(this, this_ptr)
+ call this_ptr%p%remove_structure(index=index_bn)
+end subroutine f90wrap_generator__remove_structure__binding__rgt
+
+subroutine f90wrap_generator__evaluate__binding__rgt(this, ret_viability, basis)
+ use raffle__geom_rw, only: basis_type
+ use raffle__generator, only: raffle_generator_type
+ implicit none
+
+ type raffle_generator_type_ptr_type
+ type(raffle_generator_type), pointer :: p => NULL()
+ end type raffle_generator_type_ptr_type
+ type basis_type_ptr_type
+ type(basis_type), pointer :: p => NULL()
+ end type basis_type_ptr_type
+ type(raffle_generator_type_ptr_type) :: this_ptr
+ integer, intent(in), dimension(2) :: this
+ real(4), intent(out) :: ret_viability
+ type(basis_type_ptr_type) :: basis_ptr
+ integer, intent(in), dimension(2) :: basis
+ this_ptr = transfer(this, this_ptr)
+ basis_ptr = transfer(basis, basis_ptr)
+ ret_viability = this_ptr%p%evaluate(basis=basis_ptr%p)
+end subroutine f90wrap_generator__evaluate__binding__rgt
+
+
+subroutine f90wrap_generator__print_settings__binding__rgt( &
+ this, file &
+)
+ use raffle__generator, only: raffle_generator_type
+ implicit none
+
+ type raffle_generator_type_ptr_type
+ type(raffle_generator_type), pointer :: p => NULL()
+ end type raffle_generator_type_ptr_type
+ type(raffle_generator_type_ptr_type) :: this_ptr
+ integer, intent(in), dimension(2) :: this
+ character*(*), intent(in) :: file
+ this_ptr = transfer(this, this_ptr)
+ call this_ptr%p%print_settings(file=file)
+end subroutine f90wrap_generator__print_settings__binding__rgt
+
+
+subroutine f90wrap_generator__read_settings__binding__rgt( &
+ this, file &
+)
+ use raffle__generator, only: raffle_generator_type
+ implicit none
+
+ type raffle_generator_type_ptr_type
+ type(raffle_generator_type), pointer :: p => NULL()
+ end type raffle_generator_type_ptr_type
+ type(raffle_generator_type_ptr_type) :: this_ptr
+ integer, intent(in), dimension(2) :: this
+ character*(*), intent(in) :: file
+ this_ptr = transfer(this, this_ptr)
+ call this_ptr%p%read_settings(file=file)
+end subroutine f90wrap_generator__read_settings__binding__rgt
!###############################################################################
! End of module generator defined in file ../src/lib/mod_generator.f90
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index d06716ce..0a56af58 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -14,6 +14,8 @@ foreach(execid
evaluator_C
evaluator_BTO
generator
+ io_utils
+ tools_infile
)
add_executable(test_${execid} test_${execid}.f90)
# # Specify the include directories
diff --git a/test/test_dist_calcs.f90 b/test/test_dist_calcs.f90
index cbf39a8b..025e0920 100644
--- a/test/test_dist_calcs.f90
+++ b/test/test_dist_calcs.f90
@@ -5,11 +5,13 @@ program test_edit_geom
use raffle__misc_linalg, only: modu
use raffle__dist_calcs, only: &
get_min_dist, &
- get_min_dist_between_point_and_atom
+ get_min_dist_between_point_and_atom, &
+ get_min_dist_between_point_and_species, &
+ get_dist_between_point_and_atom
implicit none
- type(basis_type) :: bas
+ type(basis_type) :: bas, bas2
real(real32) :: rtmp1, rtmp2
real(real32), dimension(3) :: loc
@@ -52,7 +54,11 @@ program test_edit_geom
!-----------------------------------------------------------------------------
! Test get_min_dist_between_point_and_atom
!-----------------------------------------------------------------------------
- rtmp1 = get_min_dist_between_point_and_atom(bas, loc=[0.9, 0.9, 0.9], atom=[1, 1])
+ rtmp1 = get_min_dist_between_point_and_atom( &
+ bas, &
+ loc=[0.9, 0.9, 0.9], &
+ atom=[1, 1] &
+ )
loc = [1.0, 1.0, 1.0] - [0.9, 0.9, 0.9]
loc = loc - ceiling(loc - 0.5)
@@ -65,6 +71,84 @@ program test_edit_geom
end if
+ !-----------------------------------------------------------------------------
+ ! Test get_min_dist_between_point_and_species
+ !-----------------------------------------------------------------------------
+ bas2%sysname = "Si|Ge"
+ bas2%nspec = 2
+ bas2%natom = 2
+ allocate(bas2%spec(bas2%nspec))
+ bas2%spec(1)%num = 1
+ bas2%spec(1)%name = 'Si'
+ allocate(bas2%spec(1)%atom(bas2%spec(1)%num, 3))
+ bas2%spec(1)%atom(1, :) = [0.0, 0.0, 0.0]
+ bas2%spec(2)%num = 1
+ bas2%spec(2)%name = 'Ge'
+ allocate(bas2%spec(2)%atom(bas2%spec(2)%num, 3))
+ bas2%spec(2)%atom(1, :) = [0.25, 0.25, 0.25]
+
+ rtmp1 = get_min_dist_between_point_and_species( &
+ bas2, &
+ loc=[0.9, 0.9, 0.9], &
+ species=1 &
+ )
+ loc = bas2%spec(1)%atom(1,:3) - [0.9, 0.9, 0.9]
+ loc = loc - ceiling(loc - 0.5)
+ loc = matmul(loc, bas2%lat)
+ rtmp2 = modu(loc)
+
+ if ( abs(rtmp1 - rtmp2) .gt. 1.E-6 ) then
+ write(0,*) 'get_min_dist_between_point_and_species failed'
+ success = .false.
+ end if
+
+ rtmp1 = get_min_dist_between_point_and_species( &
+ bas2, &
+ loc=[0.9, 0.9, 0.9], &
+ species=2 &
+ )
+ loc = bas2%spec(2)%atom(1,:3) - [0.9, 0.9, 0.9]
+ loc = loc - ceiling(loc - 0.5)
+ loc = matmul(loc, bas2%lat)
+ rtmp2 = modu(loc)
+
+ if ( abs(rtmp1 - rtmp2) .gt. 1.E-6 ) then
+ write(0,*) 'get_min_dist_between_point_and_species failed'
+ success = .false.
+ end if
+
+
+ !-----------------------------------------------------------------------------
+ ! Test get_dist_between_point_and_atom
+ !-----------------------------------------------------------------------------
+ rtmp1 = get_dist_between_point_and_atom( &
+ bas, &
+ loc=[0.9, 0.9, 0.9], &
+ atom=[1, 1] &
+ )
+ loc = bas%spec(1)%atom(1,:3) - [0.9, 0.9, 0.9]
+ loc = matmul(loc, bas%lat)
+ rtmp2 = modu(loc)
+ if ( abs(rtmp1 - rtmp2) .gt. 1.E-6 ) then
+ write(*,*) rtmp1, rtmp2
+ write(0,*) 'get_dist_between_point_and_atom failed'
+ success = .false.
+ end if
+ rtmp1 = get_dist_between_point_and_atom( &
+ bas, &
+ loc=[0.9, 0.9, 0.9], &
+ atom=[1, 2] &
+ )
+ loc = bas%spec(1)%atom(2,:3) - [0.9, 0.9, 0.9]
+ loc = matmul(loc, bas%lat)
+ rtmp2 = modu(loc)
+ if ( abs(rtmp1 - rtmp2) .gt. 1.E-6 ) then
+ write(*,*) rtmp1, rtmp2
+ write(0,*) 'get_dist_between_point_and_atom failed'
+ success = .false.
+ end if
+
+
!-----------------------------------------------------------------------------
! check for any failed tests
!-----------------------------------------------------------------------------
diff --git a/test/test_evaluator_BTO.f90 b/test/test_evaluator_BTO.f90
index 439999e6..73660213 100644
--- a/test/test_evaluator_BTO.f90
+++ b/test/test_evaluator_BTO.f90
@@ -192,6 +192,12 @@ program test_evaluator_BTO
basis_list = database, &
deallocate_systems = .true. &
)
+ call generator%distributions%set_element_map( &
+ [ "Ba ", "Ti ", "O "] &
+ )
+ call generator%distributions%host_system%set_element_map( &
+ generator%distributions%element_info &
+ )
!-----------------------------------------------------------------------------
@@ -201,6 +207,7 @@ program test_evaluator_BTO
gridpoints = get_gridpoints_and_viability( &
generator%distributions, &
generator%grid, &
+ generator%bounds, &
basis_host, &
[ 1, 2, 3 ], &
[ generator%distributions%bond_info(:)%radius_covalent ], &
diff --git a/test/test_evaluator_C.f90 b/test/test_evaluator_C.f90
index cd3491cd..c46093f8 100644
--- a/test/test_evaluator_C.f90
+++ b/test/test_evaluator_C.f90
@@ -176,6 +176,12 @@ program test_evaluator
basis_list = database, &
deallocate_systems = .true. &
)
+ call generator%distributions%set_element_map( &
+ [ "C "] &
+ )
+ call generator%distributions%host_system%set_element_map( &
+ generator%distributions%element_info &
+ )
!-----------------------------------------------------------------------------
@@ -185,6 +191,7 @@ program test_evaluator
gridpoints = get_gridpoints_and_viability( &
generator%distributions, &
generator%grid, &
+ generator%bounds, &
basis_host, &
[ 1 ], &
[ generator%distributions%bond_info(:)%radius_covalent ], &
diff --git a/test/test_generator.f90 b/test/test_generator.f90
index d350177a..d59be16d 100644
--- a/test/test_generator.f90
+++ b/test/test_generator.f90
@@ -1,18 +1,25 @@
program test_generator
use raffle__io_utils
+ use raffle__misc_linalg, only: modu
use raffle__constants, only: real32
use raffle__geom_rw, only: basis_type
use raffle__generator, only: raffle_generator_type, stoichiometry_type
implicit none
- integer :: i
- type(raffle_generator_type) :: generator
+ integer :: i, newunit
+ real(real32) :: rtmp1
+ logical :: exists
+ character(len=100) :: filename
+ type(raffle_generator_type) :: generator, generator2
class(raffle_generator_type), allocatable :: generator_var
type(basis_type) :: basis_host, basis_host_expected
type(basis_type), dimension(1) :: database
+ type(basis_type), dimension(:), allocatable :: structures, structures_store
+ integer, dimension(3) :: grid
character(3), dimension(1) :: element_symbols
real(real32), dimension(1) :: element_energies
real(real32), dimension(3) :: tolerance
+ real(real32), dimension(2, 3) :: bounds
logical :: success = .true.
@@ -126,7 +133,10 @@ program test_generator
! test generator setup with host
!-----------------------------------------------------------------------------
generator_var = raffle_generator_type(host = basis_host)
- call assert(compare_bas(generator_var%host, basis_host), &
+ do i = 1, 3
+ tolerance(i) = 1.E-6_real32 / modu(basis_host%lat(i,:))
+ end do
+ call assert(compare_bas(generator_var%host, basis_host, tolerance), &
'Generator failed to set host structure', &
success &
)
@@ -168,7 +178,10 @@ program test_generator
! set up host
!-----------------------------------------------------------------------------
call generator%set_host( basis_host )
- call assert(compare_bas(generator%host, basis_host), &
+ do i = 1, 3
+ tolerance(i) = 1.E-6_real32 / modu(basis_host%lat(i,:))
+ end do
+ call assert(compare_bas(generator%host, basis_host, tolerance), &
'Generator failed to set host structure', &
success &
)
@@ -223,6 +236,72 @@ program test_generator
call generator%reset_grid()
+ !-----------------------------------------------------------------------------
+ ! set up bounds
+ !-----------------------------------------------------------------------------
+
+ ! check initial bounds
+ bounds(1,:) = [ 0.0, 0.0, 0.0 ]
+ bounds(2,:) = [ 1.0, 1.0, 1.0 ]
+ call assert( &
+ all( &
+ abs( &
+ generator%bounds - &
+ bounds &
+ ) .lt. 1.E-6_real32 &
+ ), &
+ 'Generator failed to handle bounds', &
+ success &
+ )
+
+ ! check bounds setting
+ bounds(1,:) = [ 0.3, 0.4, 0.5 ]
+ bounds(2,:) = [ 0.6, 0.7, 0.8 ]
+ call generator%set_bounds( bounds = bounds )
+ call assert( &
+ all( &
+ abs( &
+ generator%bounds - &
+ bounds &
+ ) .lt. 1.E-6_real32 &
+ ), &
+ 'Generator failed to handle bounds', &
+ success &
+ )
+
+ ! check bounds resetting
+ call generator%reset_bounds()
+ bounds(1,:) = [ 0.0, 0.0, 0.0 ]
+ bounds(2,:) = [ 1.0, 1.0, 1.0 ]
+ call assert( &
+ all( &
+ abs( &
+ generator%bounds - &
+ bounds &
+ ) .lt. 1.E-6_real32 &
+ ), &
+ 'Generator failed to handle bounds', &
+ success &
+ )
+
+ ! check grid setting with bounds
+ bounds(1,:) = [ 0.0, 0.25, 0.5 ]
+ bounds(2,:) = [ 1.0, 1.0, 1.0 ]
+ call generator%set_bounds( bounds = bounds )
+ call generator%set_grid( grid_spacing = 0.2 )
+ grid(1) = nint( generator%host%lat(1,1) / 0.2 )
+ grid(2) = nint( 0.75 * generator%host%lat(2,2) / 0.2 )
+ grid(3) = nint( 0.5 * generator%host%lat(3,3) / 0.2 )
+ call assert( &
+ all( generator%grid .eq. grid ), &
+ 'Generator failed to handle grid_spacing with bounds', &
+ success &
+ )
+
+ call generator%reset_bounds()
+ call generator%reset_grid()
+
+
!-----------------------------------------------------------------------------
! set up generator
!-----------------------------------------------------------------------------
@@ -264,7 +343,8 @@ program test_generator
!-----------------------------------------------------------------------------
! compare the generated host structure
!-----------------------------------------------------------------------------
- call assert(compare_bas(generator%structures(1), basis_host_expected), &
+ call assert(&
+ compare_bas(generator%structures(1), basis_host_expected, tolerance), &
'Generated host structure does not match expected host structure', &
success &
)
@@ -291,6 +371,146 @@ program test_generator
)
+ !-----------------------------------------------------------------------------
+ ! handle structures
+ !-----------------------------------------------------------------------------
+ structures_store = generator%get_structures()
+ call assert( &
+ size(structures_store) .eq. 3, &
+ 'Generator failed to get structures', &
+ success &
+ )
+ call generator%remove_structure(1)
+ structures = generator%get_structures()
+ call assert( &
+ size(structures) .eq. 2, &
+ 'Generator failed to remove structure', &
+ success &
+ )
+ call generator%set_structures( structures_store )
+ structures = generator%get_structures()
+ call assert( &
+ size(structures) .eq. 3, &
+ 'Generator failed to set structures', &
+ success &
+ )
+ rtmp1 = generator%evaluate( structures_store(1) )
+ call assert( &
+ rtmp1 .gt. 0.0, &
+ 'Generator failed to evaluate structure', &
+ success &
+ )
+
+
+ !-----------------------------------------------------------------------------
+ ! test generator printing and reading
+ !-----------------------------------------------------------------------------
+ filename = '.raffle_unit_test_settings.txt'
+ do i = 1, 100
+ inquire(file=filename, exist=exists)
+ if(exists) then
+ write(filename,'(A,I0,A)') '.raffle_unit_test_settings', i, '.txt'
+ cycle
+ elseif(i.ge.100)then
+ write(0,*) 'Generator failed to find a unique filename'
+ write(0,*) 'Will not write over existing file, so test cannot continue'
+ write(0,*) 'Please remove the file: ', filename
+ write(0,*) 'This is a test error, not a failure'
+ success = .false.
+ stop 1
+ end if
+ exit
+ end do
+
+ call generator%print_settings(filename)
+ inquire(file=filename, exist=exists)
+ call assert( &
+ exists, &
+ 'Generator failed to print settings', &
+ success &
+ )
+
+ call generator2%read_settings(filename)
+ call assert( &
+ all( generator2%grid .eq. generator%grid), &
+ 'Generator failed to read grid settings', &
+ success &
+ )
+ call assert( &
+ all( abs( generator2%bounds - generator%bounds ) .lt. 1.E-6 ), &
+ 'Generator failed to read bounds settings', &
+ success &
+ )
+ call assert( &
+ generator2%max_attempts .eq. generator%max_attempts, &
+ 'Generator failed to read max_attempts settings', &
+ success &
+ )
+ call assert( &
+ abs( &
+ generator2%walk_step_size_coarse - &
+ generator%walk_step_size_coarse &
+ ) .lt. 1.E-6, &
+ 'Generator failed to read walk_step_size_coarse settings', &
+ success &
+ )
+ call assert( &
+ abs( &
+ generator2%walk_step_size_fine - generator%walk_step_size_fine &
+ ) .lt. 1.E-6, &
+ 'Generator failed to read walk_step_size_fine settings', &
+ success &
+ )
+ call assert( &
+ abs( &
+ generator2%distributions%kBT - generator%distributions%kBT &
+ ) .lt. 1.E-6, &
+ 'Generator failed to read kBT settings', &
+ success &
+ )
+ call assert( &
+ all( abs( &
+ generator2%distributions%width - generator%distributions%width &
+ ) .lt. 1.E-6 ), &
+ 'Generator failed to read width settings', &
+ success &
+ )
+ call assert( &
+ all( abs( &
+ generator2%distributions%sigma - generator%distributions%sigma &
+ ) .lt. 1.E-6 ), &
+ 'Generator failed to read sigma settings', &
+ success &
+ )
+ call assert( &
+ all( abs( &
+ generator2%distributions%cutoff_min - &
+ generator%distributions%cutoff_min &
+ ) .lt. 1.E-6 ), &
+ 'Generator failed to read cutoff_min settings', &
+ success &
+ )
+ call assert( &
+ all( abs( &
+ generator2%distributions%cutoff_max - &
+ generator%distributions%cutoff_max &
+ ) .lt. 1.E-6 ), &
+ 'Generator failed to read cutoff_max settings', &
+ success &
+ )
+ call assert( &
+ all( abs( &
+ generator2%distributions%radius_distance_tol - &
+ generator%distributions%radius_distance_tol &
+ ) .lt. 1.E-6 ), &
+ 'Generator failed to read radius_distance_tol settings', &
+ success &
+ )
+
+ open(newunit=newunit, file=filename, status='old')
+ close(newunit, status='delete')
+
+
!-----------------------------------------------------------------------------
! check for any failed tests
!-----------------------------------------------------------------------------
@@ -304,8 +524,10 @@ program test_generator
contains
- function compare_bas(bas1, bas2) result(output)
+ function compare_bas(bas1, bas2, tolerance) result(output)
+ implicit none
type(basis_type), intent(in) :: bas1, bas2
+ real(real32), dimension(3), intent(in) :: tolerance
logical :: output
integer :: is, ia, ja
diff --git a/test/test_io_utils.f90 b/test/test_io_utils.f90
new file mode 100644
index 00000000..d059095a
--- /dev/null
+++ b/test/test_io_utils.f90
@@ -0,0 +1,34 @@
+program test_io_utils
+ use raffle__io_utils
+ implicit none
+
+ ! Test variables
+ logical :: success = .true.
+ character(100) :: message
+
+ ! Test stop_program subroutine
+ test_error_handling = .true.
+ message = "Test error message"
+ call stop_program(message)
+
+ ! Test print_warning subroutine
+ call print_warning("This is a test warning message")
+
+ ! Test print_version subroutine
+ call print_version()
+
+ ! Test print_build_info subroutine
+ call print_build_info()
+
+ !-----------------------------------------------------------------------------
+ ! check for any failed tests
+ !-----------------------------------------------------------------------------
+ write(*,*) "----------------------------------------"
+ if(success)then
+ write(*,*) 'test_misc_linalg passed all tests'
+ else
+ write(0,*) 'test_misc_linalg failed one or more tests'
+ stop 1
+ end if
+
+end program test_io_utils
\ No newline at end of file
diff --git a/test/test_place_methods.f90 b/test/test_place_methods.f90
index b5e35c65..f5d292f4 100644
--- a/test/test_place_methods.f90
+++ b/test/test_place_methods.f90
@@ -5,13 +5,54 @@ program test_place_methods
use raffle__constants, only: real32
use raffle__geom_rw, only: basis_type
use raffle__geom_extd, only: extended_basis_type
+ use raffle__generator, only: raffle_generator_type
implicit none
+ integer :: num_seed, seed
+ logical :: viable = .true.
type(basis_type) :: basis
+ type(extended_basis_type) :: basis_extd
+ type(raffle_generator_type) :: generator
+ real(real32), dimension(3) :: point
+ real(real32), dimension(2, 3) :: bounds
+ character(3), dimension(1) :: element_symbols
+ real(real32), dimension(1) :: element_energies
+
+ integer, dimension(:), allocatable :: seed_arr
+ type(basis_type), allocatable :: database(:)
+ integer, dimension(:,:), allocatable :: atom_ignore_list
+
logical :: success = .true.
+
test_error_handling = .true.
+
+ !-----------------------------------------------------------------------------
+ ! set up database
+ !-----------------------------------------------------------------------------
+ allocate(database(1))
+ database(1)%nspec = 1
+ database(1)%natom = 8
+ allocate(database(1)%spec(database(1)%nspec))
+ database(1)%spec(1)%num = 8
+ database(1)%spec(1)%name = 'C'
+ allocate(database(1)%spec(1)%atom(database(1)%spec(1)%num, 3))
+ database(1)%spec(1)%atom(1, :3) = [0.0, 0.0, 0.0]
+ database(1)%spec(1)%atom(2, :3) = [0.5, 0.5, 0.0]
+ database(1)%spec(1)%atom(3, :3) = [0.5, 0.0, 0.5]
+ database(1)%spec(1)%atom(4, :3) = [0.0, 0.5, 0.5]
+ database(1)%spec(1)%atom(5, :3) = [0.25, 0.25, 0.25]
+ database(1)%spec(1)%atom(6, :3) = [0.75, 0.75, 0.25]
+ database(1)%spec(1)%atom(7, :3) = [0.75, 0.25, 0.75]
+ database(1)%spec(1)%atom(8, :3) = [0.25, 0.75, 0.75]
+
+ database(1)%lat(1,:) = [3.5607451090903233, 0.0, 0.0]
+ database(1)%lat(2,:) = [0.0, 3.5607451090903233, 0.0]
+ database(1)%lat(3,:) = [0.0, 0.0, 3.5607451090903233]
+ database(1)%energy = -72.213492
+
+
! Initialise basis
basis%nspec = 1
allocate(basis%spec(basis%nspec))
@@ -26,9 +67,125 @@ program test_place_methods
basis%lat(3,3) = 5.0_real32
+ !-----------------------------------------------------------------------------
+ ! test place_method_void
+ !-----------------------------------------------------------------------------
call test_place_method_void(basis, success)
+ !-----------------------------------------------------------------------------
+ ! set up distribution functions
+ !-----------------------------------------------------------------------------
+ bounds(1,:) = 0.25_real32
+ bounds(2,:) = 0.75_real32
+ call generator%set_host( basis )
+ element_symbols(1) = 'C'
+ element_energies(1) = -9.0266865
+ call generator%distributions%set_element_energies( &
+ element_symbols, &
+ element_energies &
+ )
+ call generator%distributions%create( &
+ basis_list = database, &
+ deallocate_systems = .true. &
+ )
+ call generator%distributions%set_element_map( &
+ [ "C "] &
+ )
+ call generator%distributions%host_system%set_element_map( &
+ generator%distributions%element_info &
+ )
+ allocate(atom_ignore_list(1, 2))
+ atom_ignore_list(1,:) = [1,2]
+ seed = 0
+ call random_seed(size=num_seed)
+ allocate(seed_arr(num_seed))
+ seed_arr = seed
+ call random_seed(put=seed_arr)
+ call basis_extd%copy(basis)
+ call basis_extd%create_images( &
+ max_bondlength = 6._real32, &
+ atom_ignore_list = atom_ignore_list &
+ )
+
+
+ !-----------------------------------------------------------------------------
+ ! test place_method_rand
+ !-----------------------------------------------------------------------------
+ viable = .true.
+ point = place_method_rand( &
+ generator%distributions, &
+ bounds, &
+ basis_extd, &
+ atom_ignore_list, &
+ radius_list = [ 0.5_real32 ], &
+ max_attempts = 1000, &
+ viable = viable &
+ )
+ if(.not. viable) then
+ write(*,*) "test_place_method_rand failed"
+ success = .false.
+ end if
+ if( any( point .gt. 0.75_real32 ) .or. any( point .lt. 0.25_real32 ) ) then
+ write(*,*) "test_place_method_rand failed"
+ success = .false.
+ end if
+
+
+ !-----------------------------------------------------------------------------
+ ! test place_method_walk
+ !-----------------------------------------------------------------------------
+ viable = .true.
+ point = place_method_walk( &
+ generator%distributions, &
+ bounds, &
+ basis_extd, &
+ atom_ignore_list, &
+ radius_list = [ 0.5_real32 ], &
+ max_attempts = 1000, &
+ step_size_fine = 0.1_real32, &
+ step_size_coarse = 0.5_real32, &
+ viable = viable &
+ )
+ if(.not. viable) then
+ write(*,*) "test_place_method_walk failed, viable = ", viable
+ success = .false.
+ end if
+ if( any( point .gt. 0.75_real32 ) .or. any( point .lt. 0.25_real32 ) ) then
+ write(*,*) "test_place_method_walk failed, point = ", point
+ success = .false.
+ end if
+
+
+ !-----------------------------------------------------------------------------
+ ! test place_method_growth
+ !-----------------------------------------------------------------------------
+ viable = .true.
+ point = place_method_growth( &
+ generator%distributions, &
+ prior_point = [0.45_real32, 0.45_real32, 0.45_real32], &
+ prior_species = 1, &
+ bounds = bounds, &
+ basis = basis_extd, &
+ atom_ignore_list = atom_ignore_list, &
+ radius_list = [ 0.5_real32 ], &
+ max_attempts = 1000, &
+ step_size_fine = 0.1_real32, &
+ step_size_coarse = 0.5_real32, &
+ viable = viable &
+ )
+ if(.not. viable) then
+ write(*,*) "test_place_method_growth failed, viable = ", viable
+ success = .false.
+ end if
+ if( any( point .gt. 0.75_real32 ) .or. any( point .lt. 0.25_real32 ) ) then
+ write(*,*) "test_place_method_growth failed, point = ", point
+ success = .false.
+ end if
+
+
+
+
!-----------------------------------------------------------------------------
! check for any failed tests
!-----------------------------------------------------------------------------
@@ -55,9 +212,12 @@ subroutine test_place_method_void(basis, success)
real(real32), dimension(3) :: point
integer, dimension(:,:), allocatable :: atom_ignore_list
real(real32), dimension(3) :: tolerance
+ real(real32), dimension(2,3) :: bounds
! Initialise test data
grid = [10, 10, 10]
+ bounds(1,:) = 0.0_real32
+ bounds(2,:) = 1.0_real32
allocate(atom_ignore_list(1, 2)) ! No atoms to ignore
atom_ignore_list(1,:) = [1,2]
grid_offset = [0.5_real32, 0.5_real32, 0.5_real32]
@@ -67,7 +227,7 @@ subroutine test_place_method_void(basis, success)
! Call the void subroutine
point = place_method_void( &
- grid, grid_offset, basis_copy, &
+ grid, grid_offset, bounds, basis_copy, &
atom_ignore_list, &
viable &
)
diff --git a/test/test_raffle.py b/test/test_raffle.py
new file mode 100644
index 00000000..865f4adf
--- /dev/null
+++ b/test/test_raffle.py
@@ -0,0 +1,212 @@
+import unittest
+import os
+from raffle.raffle import Geom_Rw, Raffle__Distribs_Container, Generator
+from ase import Atoms
+
+class TestGeomRw(unittest.TestCase):
+
+ def test_species_type_initialization(self):
+ species = Geom_Rw.species_type()
+ self.assertIsNotNone(species._handle)
+
+ def test_species_type_properties(self):
+ species = Geom_Rw.species_type()
+ species.mass = 12.0
+ self.assertEqual(species.mass, 12.0)
+ species.charge = 1.0
+ self.assertEqual(species.charge, 1.0)
+ species.radius = 0.5
+ self.assertEqual(species.radius, 0.5)
+ species.name = "C"
+ self.assertEqual(species.name, b"C")
+ species.num = 2
+ self.assertEqual(species.num, 2)
+
+ def test_basis_initialization(self):
+ basis = Geom_Rw.basis()
+ self.assertIsNotNone(basis._handle)
+
+ def test_basis_properties(self):
+ basis = Geom_Rw.basis()
+ basis.nspec = 2
+ self.assertEqual(basis.nspec, 2)
+ basis.natom = 4
+ self.assertEqual(basis.natom, 4)
+ basis.energy = -10.0
+ self.assertEqual(basis.energy, -10.0)
+ basis.lat = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]
+ self.assertTrue((basis.lat == [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]).all())
+ basis.lcart = True
+ self.assertTrue(basis.lcart)
+ basis.pbc = [True, True, True]
+ self.assertTrue((basis.pbc == [True, True, True]).all())
+ basis.sysname = "Test"
+ self.assertEqual(basis.sysname, b"Test")
+
+ def test_basis_array_initialization(self):
+ basis_array = Geom_Rw.basis_array()
+ self.assertIsNotNone(basis_array._handle)
+
+ def test_basis_array_allocate(self):
+ basis_array = Geom_Rw.basis_array()
+ basis_array.allocate(2)
+ self.assertEqual(len(basis_array.items), 2)
+
+class TestRaffleDistribsContainer(unittest.TestCase):
+
+ def test_distribs_container_initialization(self):
+ distribs_container = Raffle__Distribs_Container.distribs_container_type()
+ self.assertIsNotNone(distribs_container._handle)
+
+ def test_distribs_container_set_kBT(self):
+ distribs_container = Raffle__Distribs_Container.distribs_container_type()
+ distribs_container.set_kBT(0.025)
+ self.assertTrue( abs(distribs_container.kBT - 0.025) < 1e-6 )
+
+ def test_distribs_container_set_weight_method(self):
+ distribs_container = Raffle__Distribs_Container.distribs_container_type()
+ distribs_container.set_weight_method('formation_energy')
+ self.assertFalse(distribs_container.weight_by_hull)
+ distribs_container.set_weight_method('energy_above_hull')
+ self.assertTrue(distribs_container.weight_by_hull)
+
+ def test_distribs_container_set_width(self):
+ distribs_container = Raffle__Distribs_Container.distribs_container_type()
+ distribs_container.set_width([0.1, 0.2, 0.3])
+ self.assertTrue( ( abs( distribs_container.width - [0.1, 0.2, 0.3] ) < 1e-6 ).all() )
+
+ def test_distribs_container_set_sigma(self):
+ distribs_container = Raffle__Distribs_Container.distribs_container_type()
+ distribs_container.set_sigma([0.1, 0.2, 0.3])
+ self.assertTrue( ( abs( distribs_container.sigma - [0.1, 0.2, 0.3] ) < 1e-6 ).all() )
+
+ def test_distribs_container_set_cutoff_min(self):
+ distribs_container = Raffle__Distribs_Container.distribs_container_type()
+ distribs_container.set_cutoff_min([0.1, 0.2, 0.3])
+ self.assertTrue( ( abs( distribs_container.cutoff_min - [0.1, 0.2, 0.3] ) < 1e-6 ).all() )
+
+ def test_distribs_container_set_cutoff_max(self):
+ distribs_container = Raffle__Distribs_Container.distribs_container_type()
+ distribs_container.set_cutoff_max([0.1, 0.2, 0.3])
+ self.assertTrue( ( abs( distribs_container.cutoff_max - [0.1, 0.2, 0.3] ) < 1e-6 ).all() )
+
+ def test_distribs_container_set_radius_distance_tol(self):
+ distribs_container = Raffle__Distribs_Container.distribs_container_type()
+ distribs_container.set_radius_distance_tol([0.1, 0.2, 0.3, 0.4])
+ self.assertTrue( ( abs(distribs_container.radius_distance_tol - [0.1, 0.2, 0.3, 0.4]) < 1e-6 ).all() )
+
+class TestGenerator(unittest.TestCase):
+
+ def test_generator_initialization(self):
+ generator = Generator.raffle_generator()
+ self.assertIsNotNone(generator._handle)
+
+ def test_set_max_attempts(self):
+ generator = Generator.raffle_generator()
+ generator.set_max_attempts(10)
+ self.assertEqual(generator.max_attempts, 10)
+
+ def test_set_walk_step_size(self):
+ generator = Generator.raffle_generator()
+ generator.set_walk_step_size(coarse=0.5, fine=0.1)
+ self.assertTrue( abs( generator.walk_step_size_coarse - 0.5 ) < 1e-6 )
+ self.assertTrue( abs( generator.walk_step_size_fine - 0.1 ) < 1e-6 )
+
+ def test_set_host(self):
+ generator = Generator.raffle_generator()
+ atoms = Atoms('H2', positions=[[0, 0, 0], [0, 0, 0.74]])
+ generator.set_host(atoms)
+ self.assertIsNotNone(generator.host)
+
+ def test_set_grid(self):
+ generator = Generator.raffle_generator()
+ generator.set_grid(grid=[10, 10, 10], grid_offset=[0.1, 0.2, 0.3])
+ self.assertTrue( ( generator.grid == [10, 10, 10] ).all() )
+ self.assertTrue( ( abs( generator.grid_offset - [0.1, 0.2, 0.3] ) < 1e-6 ).all() )
+
+ generator.set_grid(grid_spacing=0.1)
+ self.assertTrue( abs( generator.grid_spacing - 0.1 ) < 1e-6 )
+
+ def test_reset_grid(self):
+ generator = Generator.raffle_generator()
+ generator.set_grid(grid=[10, 10, 10], grid_offset=[0.0, 0.0, 0.0])
+ generator.reset_grid()
+ self.assertTrue((generator.grid == [0, 0, 0]).all())
+
+ def test_set_bounds(self):
+ generator = Generator.raffle_generator()
+ bounds = [ [ 0.1, 0.2, 0.3 ], [0.4, 0.5, 0.6 ] ]
+ generator.set_bounds(bounds)
+ self.assertTrue( ( abs( generator.bounds - bounds ) < 1e-6 ).all() )
+
+ def test_reset_bounds(self):
+ generator = Generator.raffle_generator()
+ bounds = [ [ 0.1, 0.2, 0.3 ], [0.4, 0.5, 0.6 ] ]
+ generator.set_bounds(bounds)
+ generator.reset_bounds()
+ self.assertTrue( ( abs( generator.bounds - [ [ 0.0, 0.0, 0.0 ], [ 1.0, 1.0, 1.0 ] ] ) < 1e-6 ).all() )
+
+ # def test_generate(self):
+ # generator = Generator.raffle_generator()
+ # atoms = Atoms('H2', positions=[[0, 0, 0], [0, 0, 0.74]], cell=[10, 10, 10])
+ # generator.set_host(atoms)
+ # generator.distributions.set_element_energies( {"H": 0.0} )
+ # stoichiometry = {"H": 2}
+ # generator.generate(num_structures=1, stoichiometry=stoichiometry)
+ # self.assertEqual(generator.num_structures, 1)
+
+ def test_get_structures(self):
+ generator = Generator.raffle_generator()
+ atoms = Atoms('H2', positions=[[0, 0, 0], [0, 0, 0.74]], cell=[10, 10, 10])
+ generator.set_structures([atoms])
+ structures = generator.get_structures()
+ self.assertEqual( len(structures), 1 )
+
+ def test_set_structures(self):
+ generator = Generator.raffle_generator()
+ atoms = Atoms('H2', positions=[[0, 0, 0], [0, 0, 0.74]], cell=[10, 10, 10])
+ generator.set_structures([atoms])
+ self.assertEqual(generator.num_structures, 1)
+
+ def test_remove_structure(self):
+ generator = Generator.raffle_generator()
+ atoms = []
+ atoms.append(Atoms('H2', positions=[[0, 0, 0], [0, 0, 0.74]], cell=[10, 10, 10]))
+ atoms.append(Atoms('H2', positions=[[0, 0, 0], [0, 0, 0.74]], cell=[10, 10, 10]))
+ generator.set_structures(atoms)
+ generator.remove_structure(0)
+ self.assertEqual(generator.num_structures, 1)
+
+ # def test_evaluate(self):
+ # generator = Generator.raffle_generator()
+ # atoms = Atoms('H2', positions=[[0, 0, 0], [0, 0, 0.74]], cell=[10, 10, 10])
+ # generator.set_host(atoms)
+ # generator.distributions.set_element_energies( {"H": 0.0} )
+ # generator.distributions.create([atoms])
+ # basis = Geom_Rw.basis(atoms)
+ # viability = generator.evaluate(basis)
+ # self.assertIsNotNone(viability)
+
+ def test_print_settings(self):
+ generator = Generator.raffle_generator()
+ atoms = Atoms('H2', positions=[[0, 0, 0], [0, 0, 0.74]], cell=[10, 10, 10])
+ generator.set_host(atoms)
+ generator.distributions.set_element_energies( {"H": 0.0} )
+ generator.distributions.create([atoms])
+
+ # check if filename exists
+ i = 0
+ filename = ".raffle_generator_settings.txt"
+ while os.path.isfile(filename):
+ i += 1
+ filename = ".raffle_generator_settings"+str(i)+".txt"
+
+ generator.print_settings(filename)
+ with open(filename, "r") as file:
+ settings = file.read()
+ self.assertTrue(len(settings) > 0)
+ os.remove(filename)
+
+
+if __name__ == '__main__':
+ unittest.main()
\ No newline at end of file
diff --git a/test/test_tools_infile.f90 b/test/test_tools_infile.f90
new file mode 100644
index 00000000..12c062c4
--- /dev/null
+++ b/test/test_tools_infile.f90
@@ -0,0 +1,83 @@
+program test_tools_infile
+ use raffle__constants, only: real32
+ use raffle__tools_infile
+ implicit none
+
+
+ integer :: ival = 0
+ logical :: ltmp1
+ real(real32) :: rtmp1
+ character(256) :: stmp1
+ character(256) :: line
+
+ logical :: success = .true.
+
+
+ line = "APPLES = string"
+ call assign_val(line, stmp1, ival, keyword="APPLES")
+ if( trim(stmp1) .ne. "string" .or. ival .ne. 1 )then
+ write(0,*) "assign_val failed for string"
+ success = .false.
+ end if
+
+ line = "ORANGES = 1"
+ call assign_val(line, ltmp1, ival, keyword="ORANGES")
+ if( .not. ltmp1 .or. ival .ne. 2 )then
+ write(0,*) "assign_val failed for logical"
+ success = .false.
+ end if
+ line = "ORANGES = 0"
+ call assign_val(line, ltmp1, ival, keyword="ORANGES")
+ if( ltmp1 .or. ival .ne. 3 )then
+ write(0,*) "assign_val failed for logical"
+ success = .false.
+ end if
+ line = "ORANGES = T"
+ call assign_val(line, ltmp1, ival, keyword="ORANGES")
+ if( .not. ltmp1 .or. ival .ne. 4 )then
+ write(0,*) "assign_val failed for logical"
+ success = .false.
+ end if
+ line = "ORANGES = F"
+ call assign_val(line, ltmp1, ival, keyword="ORANGES")
+ if( ltmp1 .or. ival .ne. 5 )then
+ write(0,*) "assign_val failed for logical"
+ success = .false.
+ end if
+ line = "ORANGES = t"
+ call assign_val(line, ltmp1, ival, keyword="ORANGES")
+ if( .not. ltmp1 .or. ival .ne. 6 )then
+ write(0,*) "assign_val failed for logical"
+ success = .false.
+ end if
+ line = "ORANGES = f"
+ call assign_val(line, ltmp1, ival, keyword="ORANGES")
+ if( ltmp1 .or. ival .ne. 7 )then
+ write(0,*) "assign_val failed for logical"
+ success = .false.
+ end if
+
+ line = "BANANAS = 1.0 # comment"
+ ! ival = line number here
+ call rm_comments(line, ival)
+ if( trim(line) .ne. "BANANAS = 1.0")then
+ write(0,*) "rm_comments failed"
+ write(0,'("\",A,"\")') trim(line)
+ success = .false.
+ end if
+
+
+ !-----------------------------------------------------------------------------
+ ! check for any failed tests
+ !-----------------------------------------------------------------------------
+ write(*,*) "----------------------------------------"
+ if(success)then
+ write(*,*) 'test_tools_infile passed all tests'
+ else
+ write(0,*) 'test_tools_infile failed one or more tests'
+ stop 1
+ end if
+
+
+
+end program test_tools_infile
\ No newline at end of file
diff --git a/test/test_viability.f90 b/test/test_viability.f90
index 6f74142a..f340ea9c 100644
--- a/test/test_viability.f90
+++ b/test/test_viability.f90
@@ -57,9 +57,12 @@ subroutine test_get_gridpoints_and_viability(basis, success)
real(real32) :: lowtol
real(real32), dimension(:,:), allocatable :: points
real(real32), dimension(3) :: grid_offset
+ real(real32), dimension(2,3) :: bounds
! Initialise test data
grid = [10, 10, 10]
+ bounds(1,:) = 0.0_real32
+ bounds(2,:) = 1.0_real32
allocate(atom_ignore_list(1, 2)) ! No atoms to ignore
atom_ignore_list(1,:) = [1,2]
allocate(radius_list(1))
@@ -84,7 +87,8 @@ subroutine test_get_gridpoints_and_viability(basis, success)
! Call the function to test
points = get_gridpoints_and_viability( &
distribs_container, &
- grid, basis_copy, &
+ grid, bounds, &
+ basis_copy, &
[ 1 ], &
radius_list, &
atom_ignore_list, &
@@ -123,9 +127,12 @@ subroutine test_update_gridpoints_and_viability(basis, success)
real(real32) :: lowtol
real(real32), dimension(:,:), allocatable :: points
real(real32), dimension(3) :: grid_offset
+ real(real32), dimension(2,3) :: bounds
! Initialise test data
grid = [10, 10, 10]
+ bounds(1,:) = 0.0_real32
+ bounds(2,:) = 1.0_real32
allocate(atom_ignore_list(1, 2)) ! No atoms to ignore
atom_ignore_list(1,:) = [1,2]
allocate(radius_list(1))
@@ -150,7 +157,8 @@ subroutine test_update_gridpoints_and_viability(basis, success)
! Call the function to test
points = get_gridpoints_and_viability( &
distribs_container, &
- grid, basis_copy, &
+ grid, bounds, &
+ basis_copy, &
[ 1 ], &
radius_list, &
atom_ignore_list, &
diff --git a/tools/check_indentation.py b/tools/check_indentation.py
index 998d9ebf..1404f1ae 100644
--- a/tools/check_indentation.py
+++ b/tools/check_indentation.py
@@ -34,6 +34,7 @@ def check_indentation(file_path):
inside_associate_arguments = False
inside_do_concurrent_limits = False
interface_block = False
+ readwrite_line = False
expected_indent = 0 # Default expected indentation
continuation_line = False # Flag to indicate if the previous line was a continuation
@@ -140,7 +141,7 @@ def check_indentation(file_path):
num_double_quotes = 0
# Check if line starts with close bracket, if so, update the indentation
- if re.match(r'^\s*[)\]]', stripped_line_excld_quote):
+ if re.match(r'^\s*(\)|/\)|\])', stripped_line_excld_quote):
continued_indent = expected_indent + ( unbalanced_brackets - 1 ) * continuation_indent
# Count open and close brackets
@@ -151,6 +152,8 @@ def check_indentation(file_path):
if stripped_line_excld_quote.count('(') + stripped_line_excld_quote.count('[') < \
stripped_line_excld_quote.count(')') + stripped_line_excld_quote.count(']'):
unbalanced_brackets -= 1
+ if readwrite_line:
+ unbalanced_brackets += 1
elif stripped_line_excld_quote.count('(') + stripped_line_excld_quote.count('[') > \
stripped_line_excld_quote.count(')') + stripped_line_excld_quote.count(']'):
unbalanced_brackets += 1
@@ -248,6 +251,8 @@ def check_indentation(file_path):
if inside_associate_arguments:
inside_associate_arguments = False
expected_indent += loop_conditional_indent
+ if readwrite_line:
+ readwrite_line = False
# Reset from contains line
@@ -338,6 +343,9 @@ def check_indentation(file_path):
expected_indent += loop_conditional_indent
inside_select = True
+ # Detect read/write statement
+ if re.match(r'^\s*(read|write)\(\b', stripped_line, re.IGNORECASE):
+ readwrite_line = True
return success
diff --git a/tools/version_number.py b/tools/version_number.py
index e72ed526..ef527028 100644
--- a/tools/version_number.py
+++ b/tools/version_number.py
@@ -11,7 +11,7 @@ def update_version(new_version):
# Update Fortran module
with open('src/fortran/lib/mod_io_utils.F90', 'r') as file:
content = file.read()
- content = re.sub(r'character\(len=\*\), parameter :: version = "\d+\.\d+\.\d+"', f'character(len=*), parameter :: version = "{new_version}"', content)
+ content = re.sub(r'character\(len=\*\), parameter :: raffle__version__ = "\d+\.\d+\.\d+"', f'character(len=*), parameter :: raffle__version__ = "{new_version}"', content)
with open('src/fortran/lib/mod_io_utils.F90', 'w') as file:
file.write(content)