From ffa9976974c57b1a63bac7ccf0d21319a1ce3438 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Thu, 31 Oct 2024 09:26:00 +0000
Subject: [PATCH 01/60] Update format
---
README.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index d3289627..d72a9e9d 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,8 @@
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.
From 255dc501ab484dea659852336b8937dc95e6e15e Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Thu, 31 Oct 2024 09:26:19 +0000
Subject: [PATCH 02/60] Add files
---
docs/about.rst | 15 +++++++++++++
docs/conf.py | 57 ++++++++++++++++++++++++++++++++++++++++++++++++
docs/index.rst | 11 ++++++++++
docs/install.rst | 17 +++++++++++++++
4 files changed, 100 insertions(+)
create mode 100644 docs/about.rst
create mode 100644 docs/conf.py
create mode 100644 docs/index.rst
create mode 100644 docs/install.rst
diff --git a/docs/about.rst b/docs/about.rst
new file mode 100644
index 00000000..e2da12e7
--- /dev/null
+++ b/docs/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/conf.py b/docs/conf.py
new file mode 100644
index 00000000..fd432042
--- /dev/null
+++ b/docs/conf.py
@@ -0,0 +1,57 @@
+# Configuration file for the Sphinx documentation builder.
+
+# -- Project information
+import datetime
+
+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',
+]
+
+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']
+
+# -- Options for HTML output
+
+html_theme = 'sphinx_rtd_theme'
+
+# -- Options for EPUB output
+epub_show_urls = 'footnote'
+
+html_theme = 'sphinx_rtd_theme'
+html_static_path = ['_static']
+html_logo = "RAFFLE_logo_no_background.png"
+# html_favicon = 'favicon.ico'
+html_theme_options = {
+ 'logo_only': False,
+ 'display_version': 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
+}
\ No newline at end of file
diff --git a/docs/index.rst b/docs/index.rst
new file mode 100644
index 00000000..e3779196
--- /dev/null
+++ b/docs/index.rst
@@ -0,0 +1,11 @@
+======
+RAFFLE
+======
+
+
+.. toctree::
+ :maxdepth: 3
+ :caption: Contents:
+
+ about
+ install
\ No newline at end of file
diff --git a/docs/install.rst b/docs/install.rst
new file mode 100644
index 00000000..7137af42
--- /dev/null
+++ b/docs/install.rst
@@ -0,0 +1,17 @@
+.. _install:
+
+============
+Installation
+============
+
+Python
+======
+
+Requirements
+------------
+
+
+
+
+Fortran
+=======
\ No newline at end of file
From 6851be88e8278a505a3cdbc876a938912f52036c Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Thu, 31 Oct 2024 16:02:09 +0000
Subject: [PATCH 03/60] Add installation guide
---
docs/install.rst | 229 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 228 insertions(+), 1 deletion(-)
diff --git a/docs/install.rst b/docs/install.rst
index 7137af42..6042e8f5 100644
--- a/docs/install.rst
+++ b/docs/install.rst
@@ -4,14 +4,241 @@
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/nedtaylor/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
-=======
\ No newline at end of file
+=======
+
+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/nedtaylor/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
+
From e9688df42889f99e9b5954e5109f3b12c01b1bd5 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Thu, 31 Oct 2024 17:01:53 +0000
Subject: [PATCH 04/60] Add tutorial templates
---
docs/index.rst | 41 ++++++++++++++++++++++++-
docs/tutorials/BaTiO3_tutorial.rst | 5 +++
docs/tutorials/C-MgO_tutorial.rst | 5 +++
docs/tutorials/diamond_tutorial.rst | 5 +++
docs/tutorials/graphite_tutorial.rst | 5 +++
docs/tutorials/index.rst | 22 +++++++++++++
docs/tutorials/perovskites_tutorial.rst | 5 +++
7 files changed, 87 insertions(+), 1 deletion(-)
create mode 100644 docs/tutorials/BaTiO3_tutorial.rst
create mode 100644 docs/tutorials/C-MgO_tutorial.rst
create mode 100644 docs/tutorials/diamond_tutorial.rst
create mode 100644 docs/tutorials/graphite_tutorial.rst
create mode 100644 docs/tutorials/index.rst
create mode 100644 docs/tutorials/perovskites_tutorial.rst
diff --git a/docs/index.rst b/docs/index.rst
index e3779196..8b6f670b 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -2,10 +2,49 @@
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
\ No newline at end of file
+ install
+ tutorials/index
\ No newline at end of file
diff --git a/docs/tutorials/BaTiO3_tutorial.rst b/docs/tutorials/BaTiO3_tutorial.rst
new file mode 100644
index 00000000..3c136a68
--- /dev/null
+++ b/docs/tutorials/BaTiO3_tutorial.rst
@@ -0,0 +1,5 @@
+.. BaTiO3:
+
+========================
+BaTiO\ :sub:`3` tutorial
+========================
diff --git a/docs/tutorials/C-MgO_tutorial.rst b/docs/tutorials/C-MgO_tutorial.rst
new file mode 100644
index 00000000..7a9b11e3
--- /dev/null
+++ b/docs/tutorials/C-MgO_tutorial.rst
@@ -0,0 +1,5 @@
+.. C-MgO:
+
+=========================
+Graphene-encapsulated MgO
+=========================
\ No newline at end of file
diff --git a/docs/tutorials/diamond_tutorial.rst b/docs/tutorials/diamond_tutorial.rst
new file mode 100644
index 00000000..52b09303
--- /dev/null
+++ b/docs/tutorials/diamond_tutorial.rst
@@ -0,0 +1,5 @@
+.. diamond:
+
+================
+Diamond tutorial
+================
\ No newline at end of file
diff --git a/docs/tutorials/graphite_tutorial.rst b/docs/tutorials/graphite_tutorial.rst
new file mode 100644
index 00000000..0a2e6aa4
--- /dev/null
+++ b/docs/tutorials/graphite_tutorial.rst
@@ -0,0 +1,5 @@
+.. graphite:
+
+=================
+Graphite tutorial
+=================
\ No newline at end of file
diff --git a/docs/tutorials/index.rst b/docs/tutorials/index.rst
new file mode 100644
index 00000000..be4f1415
--- /dev/null
+++ b/docs/tutorials/index.rst
@@ -0,0 +1,22 @@
+.. 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:
+
+ diamond_tutorial
+ graphite_tutorial
+ BaTiO3_tutorial
+ perovskites_tutorial
+ C-MgO_tutorial
diff --git a/docs/tutorials/perovskites_tutorial.rst b/docs/tutorials/perovskites_tutorial.rst
new file mode 100644
index 00000000..d378b21f
--- /dev/null
+++ b/docs/tutorials/perovskites_tutorial.rst
@@ -0,0 +1,5 @@
+.. perovskites:
+
+====================================================
+BaTiO\ :sub:`3`\|SrTiO\ :sub:`3` interface tutorial
+====================================================
\ No newline at end of file
From ffeb2636a6e794f42f43f3209c28b415bc3a981a Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Thu, 31 Oct 2024 17:04:31 +0000
Subject: [PATCH 05/60] Add issue templates
---
.github/ISSUE_TEMPLATE/bug_report.yaml | 64 +++++++++++++++++++++
.github/ISSUE_TEMPLATE/feature_request.yaml | 29 ++++++++++
2 files changed, 93 insertions(+)
create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yaml
create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yaml
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
From 54b16ae11f05cd0c7a76999e52fbc977eafbe9e3 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Thu, 31 Oct 2024 17:10:41 +0000
Subject: [PATCH 06/60] Update README
---
README.md | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/README.md b/README.md
index d72a9e9d..1163c906 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,7 @@
[](https://www.gnu.org/licenses/gpl-3.0.en.html "View GPLv3 license")
[](https://github.com/nedtaylor/RAFFLE/releases "View on GitHub")
[](https://link.aps.org/doi/10.1103/PhysRevLett.132.066201)
+[](https://raffle-fortran.readthedocs.io/en/latest/?badge=latest)
[](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")
@@ -21,6 +22,13 @@ RAFFLE can interface with the [Atomic Simulation Environment (ASE)](https://gitl
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
From 88a9cf3e6616ac184bbbb84d77adeefcb6b7b074 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Thu, 31 Oct 2024 17:32:52 +0000
Subject: [PATCH 07/60] Tidy up examples
---
.../DC_MgO_hosts/POSCAR_10x10_5.4_separation | 408 ------------------
.../DC_MgO_hosts/POSCAR_10x10_6.0A_separation | 408 ------------------
.../DC_MgO_hosts/POSCAR_1x1_5.4A_separation | 17 -
.../POSCAR_1x5_orthorhombic_11.0A_separation | 48 ---
.../DC_MgO_hosts/POSCAR_2x2_5.4A_separation | 24 --
.../POSCAR_2x5_orthorhombic_11.0A_separation | 88 ----
.../DC_MgO_hosts/POSCAR_3x3_11.0A_separation | 44 --
.../DC_MgO_hosts/POSCAR_3x3_5.4A_separation | 44 --
.../DC_MgO_hosts/POSCAR_4x4_11.0A_separation | 72 ----
.../DC_MgO_hosts/POSCAR_4x4_14.7A_separation | 72 ----
.../DC_MgO_hosts/POSCAR_5x1_5.4A_separation | 28 --
.../DC_MgO_hosts/POSCAR_5x1_6.0A_separation | 108 -----
.../DC_MgO_hosts/POSCAR_6x6_5.4A_separation | 152 -------
.../DC_MgO_hosts/POSCAR_7x7_8.4A_separation | 204 ---------
.../example_files/DC_MgO_hosts/POSCAR_MgO_HEX | 204 ---------
...AR_orthorhombic_11.1A_separation_Mg_seeded | 50 ---
.../POSCAR_graphite_missing_layer | 15 -
example/example_files/POSCAR_host_BaTiO3 | 13 -
example/example_files/POSCAR_host_diamond | 16 -
example/example_files/POSCAR_host_graphene | 26 --
.../POSCAR_host_graphite_vacancy | 44 --
example/example_files/POSCAR_host_perovskites | 49 ---
example/{executable => fortran_exe}/param.in | 0
example/{executable => fortran_exe}/run.sh | 0
.../BaTiO3/run.py} | 4 +-
example/{wrapper => python_pkg/C-MgO}/run.py | 4 +-
.../diamond/run.py} | 6 +-
.../graphite/run.py} | 6 +-
.../perovskites}/database.xyz | 0
.../perovskites/run.py} | 4 +-
30 files changed, 14 insertions(+), 2144 deletions(-)
delete mode 100644 example/example_files/DC_MgO_hosts/POSCAR_10x10_5.4_separation
delete mode 100644 example/example_files/DC_MgO_hosts/POSCAR_10x10_6.0A_separation
delete mode 100644 example/example_files/DC_MgO_hosts/POSCAR_1x1_5.4A_separation
delete mode 100644 example/example_files/DC_MgO_hosts/POSCAR_1x5_orthorhombic_11.0A_separation
delete mode 100644 example/example_files/DC_MgO_hosts/POSCAR_2x2_5.4A_separation
delete mode 100644 example/example_files/DC_MgO_hosts/POSCAR_2x5_orthorhombic_11.0A_separation
delete mode 100644 example/example_files/DC_MgO_hosts/POSCAR_3x3_11.0A_separation
delete mode 100644 example/example_files/DC_MgO_hosts/POSCAR_3x3_5.4A_separation
delete mode 100644 example/example_files/DC_MgO_hosts/POSCAR_4x4_11.0A_separation
delete mode 100644 example/example_files/DC_MgO_hosts/POSCAR_4x4_14.7A_separation
delete mode 100644 example/example_files/DC_MgO_hosts/POSCAR_5x1_5.4A_separation
delete mode 100644 example/example_files/DC_MgO_hosts/POSCAR_5x1_6.0A_separation
delete mode 100644 example/example_files/DC_MgO_hosts/POSCAR_6x6_5.4A_separation
delete mode 100644 example/example_files/DC_MgO_hosts/POSCAR_7x7_8.4A_separation
delete mode 100644 example/example_files/DC_MgO_hosts/POSCAR_MgO_HEX
delete mode 100644 example/example_files/DC_MgO_hosts/POSCAR_orthorhombic_11.1A_separation_Mg_seeded
delete mode 100644 example/example_files/POSCAR_graphite_missing_layer
delete mode 100644 example/example_files/POSCAR_host_BaTiO3
delete mode 100644 example/example_files/POSCAR_host_diamond
delete mode 100644 example/example_files/POSCAR_host_graphene
delete mode 100644 example/example_files/POSCAR_host_graphite_vacancy
delete mode 100644 example/example_files/POSCAR_host_perovskites
rename example/{executable => fortran_exe}/param.in (100%)
rename example/{executable => fortran_exe}/run.sh (100%)
rename example/{wrapper/run_BaTiO3.py => python_pkg/BaTiO3/run.py} (98%)
rename example/{wrapper => python_pkg/C-MgO}/run.py (97%)
rename example/{wrapper/run_diamond.py => python_pkg/diamond/run.py} (96%)
rename example/{wrapper/run_graphite.py => python_pkg/graphite/run.py} (96%)
rename example/{example_files/database_perovskites => python_pkg/perovskites}/database.xyz (100%)
rename example/{wrapper/run_perovskites.py => python_pkg/perovskites/run.py} (96%)
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/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/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
From fccc79f933a881adf3930f9e5809a11776cdaf5d Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Thu, 31 Oct 2024 17:33:54 +0000
Subject: [PATCH 08/60] Update ignore list
---
.gitignore | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.gitignore b/.gitignore
index 3c7af6d8..7ff1d507 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
From aaaacf27e356e37308091e10f28972ef02b908b3 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Fri, 1 Nov 2024 07:33:03 +0000
Subject: [PATCH 09/60] Handle NaNs in angles and dfs
---
src/fortran/lib/mod_distribs.f90 | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/src/fortran/lib/mod_distribs.f90 b/src/fortran/lib/mod_distribs.f90
index 47dde273..b3bf8f3d 100644
--- a/src/fortran/lib/mod_distribs.f90
+++ b/src/fortran/lib/mod_distribs.f90
@@ -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
!###############################################################################
From 03202ef4d97f7c50b601c2ffee2b88f90f47bcd1 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Fri, 1 Nov 2024 09:55:14 +0000
Subject: [PATCH 10/60] Add bounds check
---
src/fortran/lib/mod_distribs.f90 | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/fortran/lib/mod_distribs.f90 b/src/fortran/lib/mod_distribs.f90
index b3bf8f3d..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
@@ -655,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
!------------------------------------------------------------------------
From 7632d255e77eb0ba12a8f471f0e0598c2b0d0852 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Fri, 1 Nov 2024 09:55:22 +0000
Subject: [PATCH 11/60] Change host setting
---
src/fortran/lib/mod_generator.f90 | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/src/fortran/lib/mod_generator.f90 b/src/fortran/lib/mod_generator.f90
index b90f1c27..8a64d7ec 100644
--- a/src/fortran/lib/mod_generator.f90
+++ b/src/fortran/lib/mod_generator.f90
@@ -162,10 +162,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()
From df74284a5c06bac8460c076340c96d8979e6cae3 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Fri, 1 Nov 2024 09:55:35 +0000
Subject: [PATCH 12/60] Add strip null for species setting
---
src/fortran/lib/mod_geom_rw.f90 | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
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
From 0f1f8ef4c5935b378093e12238c383bce4f37ff9 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Fri, 1 Nov 2024 19:44:48 +0000
Subject: [PATCH 13/60] Remove unused variable
---
src/fortran/lib/mod_distribs_container.f90 | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/fortran/lib/mod_distribs_container.f90 b/src/fortran/lib/mod_distribs_container.f90
index bd9de46e..a94e45fb 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
From 8e9640a6c4222116f70845e89157575117af4b70 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Fri, 1 Nov 2024 19:45:39 +0000
Subject: [PATCH 14/60] Improve gdf printing
---
src/fortran/lib/mod_distribs_container.f90 | 204 +++++++++++++++++-
src/raffle/raffle.py | 46 +++-
.../f90wrap_mod_distribs_container.f90 | 44 +++-
3 files changed, 276 insertions(+), 18 deletions(-)
diff --git a/src/fortran/lib/mod_distribs_container.f90 b/src/fortran/lib/mod_distribs_container.f90
index a94e45fb..0c9e8d66 100644
--- a/src/fortran/lib/mod_distribs_container.f90
+++ b/src/fortran/lib/mod_distribs_container.f90
@@ -151,9 +151,13 @@ 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.
@@ -576,7 +580,195 @@ 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.
+ character(256) :: buffer, buffer1, buffer2
+ !! Buffer for reading lines.
+
+ 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
@@ -630,12 +822,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
@@ -703,7 +895,7 @@ subroutine read(this, file)
end do
close(unit)
- end subroutine read
+ end subroutine read_dfs
!###############################################################################
diff --git a/src/raffle/raffle.py b/src/raffle/raffle.py
index a835306c..3d4dbeb0 100644
--- a/src/raffle/raffle.py
+++ b/src/raffle/raffle.py
@@ -1054,9 +1054,9 @@ def evolve(self): #, system=None):
# _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)
+ write_gdfs__binding__dc_type(self, file)
Defined at ../fortran/lib/mod_distribs_container.f90 \
@@ -1068,12 +1068,12 @@ def write(self, file):
file : str
"""
- _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)
+ read_gdfs__binding__dc_type(self, file)
Defined at ../fortran/lib/mod_distribs_container.f90 \
@@ -1085,7 +1085,41 @@ def read(self, file):
file : str
"""
- _raffle.f90wrap_raffle__dc__read__binding__dc_type(this=self._handle, \
+ _raffle.f90wrap_raffle__dc__read_gdfs__binding__dc_type(this=self._handle, \
+ file=file)
+
+ def write_dfs(self, file):
+ """
+ write_dfs__binding__dc_type(self, file)
+
+
+ Defined at ../fortran/lib/mod_distribs_container.f90 \
+ lines 510-559
+
+ Parameters
+ ----------
+ this : unknown
+ file : str
+
+ """
+ _raffle.f90wrap_raffle__dc__write_dfs__binding__dc_type(this=self._handle, \
+ file=file)
+
+ def read_dfs(self, file):
+ """
+ read_dfs__binding__dc_type(self, file)
+
+
+ Defined at ../fortran/lib/mod_distribs_container.f90 \
+ lines 563-620
+
+ Parameters
+ ----------
+ this : unknown
+ file : str
+
+ """
+ _raffle.f90wrap_raffle__dc__read_dfs__binding__dc_type(this=self._handle, \
file=file)
def write_2body(self, file):
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 &
From 4083bea610cdc8f136e06b82f118666e3c9f95f5 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Fri, 1 Nov 2024 19:58:46 +0000
Subject: [PATCH 15/60] Change build name
---
pyproject.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyproject.toml b/pyproject.toml
index 59be32b5..ede00d18 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -59,7 +59,7 @@ Repository = "https://github.com/nedtaylor/raffle"
Issues = "https://github.com/nedtaylor/raffle/issues"
[project.optional-dependencies]
-all = ["ase>=3.23.0"]
+ase = ["ase>=3.23.0"]
no-ase = []
[tool.scikit-build.metadata.version]
From 67ef316d97c45e3fd53a179d76d5051402316e0a Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Sat, 2 Nov 2024 09:02:13 +0000
Subject: [PATCH 16/60] Fix random placement viable boolean
---
src/fortran/lib/mod_place_methods.f90 | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/fortran/lib/mod_place_methods.f90 b/src/fortran/lib/mod_place_methods.f90
index e64496eb..701af50a 100644
--- a/src/fortran/lib/mod_place_methods.f90
+++ b/src/fortran/lib/mod_place_methods.f90
@@ -174,6 +174,8 @@ function place_method_rand( distribs_container, &
exit atom_loop
end do atom_loop
+ viable = .true.
+
end function place_method_rand
!###############################################################################
From 360855b70e7f1b66d6186abb8d6fb9d7a15318fd Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Sat, 2 Nov 2024 09:25:43 +0000
Subject: [PATCH 17/60] Update tutorials
---
docs/tutorials/databases_tutorial.rst | 127 +++++++++++++++++++++++++
docs/tutorials/diamond_tutorial.rst | 131 +++++++++++++++++++++++++-
docs/tutorials/index.rst | 1 +
3 files changed, 258 insertions(+), 1 deletion(-)
create mode 100644 docs/tutorials/databases_tutorial.rst
diff --git a/docs/tutorials/databases_tutorial.rst b/docs/tutorials/databases_tutorial.rst
new file mode 100644
index 00000000..a07170f0
--- /dev/null
+++ b/docs/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 website `_ 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/tutorials/diamond_tutorial.rst b/docs/tutorials/diamond_tutorial.rst
index 52b09303..21f894dc 100644
--- a/docs/tutorials/diamond_tutorial.rst
+++ b/docs/tutorials/diamond_tutorial.rst
@@ -2,4 +2,133 @@
================
Diamond tutorial
-================
\ No newline at end of file
+================
+
+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/tutorials/index.rst b/docs/tutorials/index.rst
index be4f1415..e0bb1311 100644
--- a/docs/tutorials/index.rst
+++ b/docs/tutorials/index.rst
@@ -15,6 +15,7 @@ Whilst RAFFLE is a random sturcture search package designed primarlily for inter
:maxdepth: 2
:caption: Tutorials:
+ databases_tutorial
diamond_tutorial
graphite_tutorial
BaTiO3_tutorial
From 22ba14f85f3ced15c692c4074ccf30b06a61c4b6 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Mon, 4 Nov 2024 09:24:21 +0000
Subject: [PATCH 18/60] Move readthedocs source files
---
.readthedocs.yaml | 2 +-
README.md | 2 +-
docs/{ => source}/RAFFLE_logo.pdf | Bin
docs/{ => source}/RAFFLE_logo_no_background.png | Bin
docs/{ => source}/about.rst | 0
docs/{ => source}/conf.py | 4 ++++
docs/{ => source}/index.rst | 3 ++-
docs/{ => source}/install.rst | 0
docs/{ => source}/tutorials/BaTiO3_tutorial.rst | 0
docs/{ => source}/tutorials/C-MgO_tutorial.rst | 0
docs/{ => source}/tutorials/databases_tutorial.rst | 0
docs/{ => source}/tutorials/diamond_tutorial.rst | 0
docs/{ => source}/tutorials/graphite_tutorial.rst | 0
docs/{ => source}/tutorials/index.rst | 0
.../{ => source}/tutorials/perovskites_tutorial.rst | 0
15 files changed, 8 insertions(+), 3 deletions(-)
rename docs/{ => source}/RAFFLE_logo.pdf (100%)
rename docs/{ => source}/RAFFLE_logo_no_background.png (100%)
rename docs/{ => source}/about.rst (100%)
rename docs/{ => source}/conf.py (92%)
rename docs/{ => source}/index.rst (98%)
rename docs/{ => source}/install.rst (100%)
rename docs/{ => source}/tutorials/BaTiO3_tutorial.rst (100%)
rename docs/{ => source}/tutorials/C-MgO_tutorial.rst (100%)
rename docs/{ => source}/tutorials/databases_tutorial.rst (100%)
rename docs/{ => source}/tutorials/diamond_tutorial.rst (100%)
rename docs/{ => source}/tutorials/graphite_tutorial.rst (100%)
rename docs/{ => source}/tutorials/index.rst (100%)
rename docs/{ => source}/tutorials/perovskites_tutorial.rst (100%)
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
index 243f0cca..bb958bfb 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:
diff --git a/README.md b/README.md
index 1163c906..a5ff815a 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-
+
[](https://www.gnu.org/licenses/gpl-3.0.en.html "View GPLv3 license")
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/about.rst b/docs/source/about.rst
similarity index 100%
rename from docs/about.rst
rename to docs/source/about.rst
diff --git a/docs/conf.py b/docs/source/conf.py
similarity index 92%
rename from docs/conf.py
rename to docs/source/conf.py
index fd432042..99af0a8e 100644
--- a/docs/conf.py
+++ b/docs/source/conf.py
@@ -2,6 +2,10 @@
# -- Project information
import datetime
+import os
+import sys
+
+sys.path.insert(0, os.path.abspath('../src/raffle')) # Sets the base path to find your modules
project = 'RAFFLE'
copyright = f'{datetime.date.today().year}, RAFFLE-developers'
diff --git a/docs/index.rst b/docs/source/index.rst
similarity index 98%
rename from docs/index.rst
rename to docs/source/index.rst
index 8b6f670b..637f8cc4 100644
--- a/docs/index.rst
+++ b/docs/source/index.rst
@@ -47,4 +47,5 @@ An example
about
install
- tutorials/index
\ No newline at end of file
+ tutorials/index
+ raffle
\ No newline at end of file
diff --git a/docs/install.rst b/docs/source/install.rst
similarity index 100%
rename from docs/install.rst
rename to docs/source/install.rst
diff --git a/docs/tutorials/BaTiO3_tutorial.rst b/docs/source/tutorials/BaTiO3_tutorial.rst
similarity index 100%
rename from docs/tutorials/BaTiO3_tutorial.rst
rename to docs/source/tutorials/BaTiO3_tutorial.rst
diff --git a/docs/tutorials/C-MgO_tutorial.rst b/docs/source/tutorials/C-MgO_tutorial.rst
similarity index 100%
rename from docs/tutorials/C-MgO_tutorial.rst
rename to docs/source/tutorials/C-MgO_tutorial.rst
diff --git a/docs/tutorials/databases_tutorial.rst b/docs/source/tutorials/databases_tutorial.rst
similarity index 100%
rename from docs/tutorials/databases_tutorial.rst
rename to docs/source/tutorials/databases_tutorial.rst
diff --git a/docs/tutorials/diamond_tutorial.rst b/docs/source/tutorials/diamond_tutorial.rst
similarity index 100%
rename from docs/tutorials/diamond_tutorial.rst
rename to docs/source/tutorials/diamond_tutorial.rst
diff --git a/docs/tutorials/graphite_tutorial.rst b/docs/source/tutorials/graphite_tutorial.rst
similarity index 100%
rename from docs/tutorials/graphite_tutorial.rst
rename to docs/source/tutorials/graphite_tutorial.rst
diff --git a/docs/tutorials/index.rst b/docs/source/tutorials/index.rst
similarity index 100%
rename from docs/tutorials/index.rst
rename to docs/source/tutorials/index.rst
diff --git a/docs/tutorials/perovskites_tutorial.rst b/docs/source/tutorials/perovskites_tutorial.rst
similarity index 100%
rename from docs/tutorials/perovskites_tutorial.rst
rename to docs/source/tutorials/perovskites_tutorial.rst
From e14c7a08e717b892bad506d7700adca60d539d9d Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Mon, 4 Nov 2024 11:31:42 +0000
Subject: [PATCH 19/60] Include docstrings
---
docs/Makefile | 20 +++++++++++
docs/make.bat | 35 +++++++++++++++++++
docs/source/conf.py | 30 +++++++++++++---
docs/source/index.rst | 9 ++++-
docs/source/modules.rst | 36 ++++++++++++++++++++
docs/source/raffle.distributions.rst | 12 +++++++
docs/source/raffle.generator.rst | 13 +++++++
docs/source/raffle.geom.rst | 12 +++++++
docs/source/tutorials/databases_tutorial.rst | 2 +-
9 files changed, 162 insertions(+), 7 deletions(-)
create mode 100644 docs/Makefile
create mode 100644 docs/make.bat
create mode 100644 docs/source/modules.rst
create mode 100644 docs/source/raffle.distributions.rst
create mode 100644 docs/source/raffle.generator.rst
create mode 100644 docs/source/raffle.geom.rst
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/source/conf.py b/docs/source/conf.py
index 99af0a8e..dd8f1b79 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -5,7 +5,13 @@
import os
import sys
-sys.path.insert(0, os.path.abspath('../src/raffle')) # Sets the base path to find your modules
+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'
@@ -21,6 +27,8 @@
'sphinx.ext.autodoc',
'sphinx.ext.autosummary',
'sphinx.ext.intersphinx',
+ 'sphinx.ext.napoleon',
+ 'sphinx.ext.viewcode',
]
intersphinx_mapping = {
@@ -31,6 +39,9 @@
templates_path = ['_templates']
+exclude_patterns = ['_build', '.DS_Store', 'build']
+
+
# -- Options for HTML output
html_theme = 'sphinx_rtd_theme'
@@ -39,12 +50,10 @@
epub_show_urls = 'footnote'
html_theme = 'sphinx_rtd_theme'
-html_static_path = ['_static']
html_logo = "RAFFLE_logo_no_background.png"
# html_favicon = 'favicon.ico'
html_theme_options = {
'logo_only': False,
- 'display_version': False,
'prev_next_buttons_location': 'bottom',
'style_external_links': False,
'vcs_pageview_mode': '',
@@ -57,5 +66,16 @@
'sticky_navigation': True,
'navigation_depth': 4,
'includehidden': True,
- 'titles_only': False
-}
\ No newline at end of file
+ 'titles_only': False,
+}
+
+
+html_context = {
+ "display_github": True,
+ "github_repo": "RAFFLE",
+ "github_user": "nedtaylor",
+ "github_version": "development",
+ "conf_py_path": "/docs/source",
+}
+
+autoclass_content="both"
\ No newline at end of file
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 637f8cc4..ece019a2 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -48,4 +48,11 @@ An example
about
install
tutorials/index
- raffle
\ No newline at end of file
+ Python API
+
+.. Indices and tables
+.. ==================
+
+.. * :ref:`genindex`
+.. * :ref:`modindex`
+.. * :ref:`search`
\ No newline at end of file
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..0a5808a1
--- /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..fe55e0cb
--- /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..ba19450c
--- /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/databases_tutorial.rst b/docs/source/tutorials/databases_tutorial.rst
index a07170f0..05fc496a 100644
--- a/docs/source/tutorials/databases_tutorial.rst
+++ b/docs/source/tutorials/databases_tutorial.rst
@@ -12,7 +12,7 @@ However, this process can be applied to any set of elements in the Materials Pro
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 website `_ for the most up-to-date information.
+ 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:
From 93a464437a568ca509c7799bd30cfd74dbae67cf Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Mon, 4 Nov 2024 14:55:25 +0000
Subject: [PATCH 20/60] Update docstrings
---
docs/source/raffle.distributions.rst | 8 +-
docs/source/raffle.generator.rst | 8 +-
docs/source/raffle.geom.rst | 8 +-
src/raffle/__init__.py | 9 +-
src/raffle/raffle.py | 1206 +++++++++-----------------
5 files changed, 410 insertions(+), 829 deletions(-)
diff --git a/docs/source/raffle.distributions.rst b/docs/source/raffle.distributions.rst
index 0a5808a1..27a93ff0 100644
--- a/docs/source/raffle.distributions.rst
+++ b/docs/source/raffle.distributions.rst
@@ -1,10 +1,10 @@
raffle.distributions module
===========================
-.. automodule:: raffle.Raffle__Distribs_Container
- :members:
- :undoc-members:
- :show-inheritance:
+.. .. automodule:: raffle.Raffle__Distribs_Container
+.. :members:
+.. :undoc-members:
+.. :show-inheritance:
.. autoclass:: raffle.Raffle__Distribs_Container
:members:
diff --git a/docs/source/raffle.generator.rst b/docs/source/raffle.generator.rst
index fe55e0cb..0afed5cc 100644
--- a/docs/source/raffle.generator.rst
+++ b/docs/source/raffle.generator.rst
@@ -1,10 +1,10 @@
raffle.generator module
=======================
-.. automodule:: raffle.Generator
- :members:
- :undoc-members:
- :show-inheritance:
+.. .. automodule:: raffle.Generator
+.. :members:
+.. :undoc-members:
+.. :show-inheritance:
.. autoclass:: raffle.Generator
diff --git a/docs/source/raffle.geom.rst b/docs/source/raffle.geom.rst
index ba19450c..9cbff07e 100644
--- a/docs/source/raffle.geom.rst
+++ b/docs/source/raffle.geom.rst
@@ -1,10 +1,10 @@
raffle.geom_rw module
=======================
-.. automodule:: raffle.Geom_Rw
- :members:
- :undoc-members:
- :show-inheritance:
+.. .. automodule:: raffle.Geom_Rw
+.. :members:
+.. :undoc-members:
+.. :show-inheritance:
.. autoclass:: raffle.Geom_Rw
:members:
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 3d4dbeb0..602758d5 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,34 +869,19 @@ 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, \
@@ -1056,164 +889,121 @@ def evolve(self): #, system=None):
def write_gdfs(self, file):
"""
- write_gdfs__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_gdfs__binding__dc_type(this=self._handle, \
file=file)
def read_gdfs(self, file):
"""
- read_gdfs__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_dfs__binding__dc_type(self, file)
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- lines 510-559
-
- Parameters
- ----------
- this : unknown
- file : str
-
+ 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__write_dfs__binding__dc_type(this=self._handle, \
file=file)
def read_dfs(self, file):
"""
- read_dfs__binding__dc_type(self, file)
-
-
- Defined at ../fortran/lib/mod_distribs_container.f90 \
- lines 563-620
-
- Parameters
- ----------
- this : unknown
- file : str
-
+ 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
-
- Parameters
- ----------
- this : unknown
- species1 : str
- species2 : str
+ 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.
- 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 = \
@@ -1224,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)
@@ -1241,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)
@@ -1259,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)
@@ -1275,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)
@@ -1293,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)
@@ -1318,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)
@@ -1343,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)
@@ -1368,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)
@@ -1393,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)
@@ -1418,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)
@@ -1441,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 : ')
@@ -1499,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)
@@ -1514,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()
-
-
- Defined at ../src/lib/mod_generator.f90 lines \
- 19-21
-
-
- Returns
- -------
- this : Stoichiometry_Type
- Object to be constructed
-
+ Object to store the stoichiometry of a structure.
- Automatically generated constructor for stoichiometry_type
+ Returns:
+ stoichiometry (stoichiometry_type):
+ Stoichiometry object
"""
f90wrap.runtime.FortranDerivedType.__init__(self)
result = _raffle.f90wrap_stoichiometry_type_initialise()
@@ -1566,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:
@@ -1580,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)
@@ -1596,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)
@@ -1623,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
@@ -1698,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)
@@ -1721,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()
@@ -1758,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
@@ -1795,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)
@@ -1817,54 +1450,40 @@ 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):
"""
- generate__binding__raffle_generator(self, num_structures, stoichiometry, method_probab)
-
- Defined at ../src/lib/mod_generator.f90 lines \
- 76-84
-
- Parameters
- ----------
- this : unknown
- num_structures : int
- stoichiometry : stoichiometry_array
- method_probab : dict
- verbose : int
+ 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.
+ verbose (int):
+ The verbosity level for the generation.
"""
method_probab_list = []
@@ -1896,6 +1515,13 @@ def generate(self, num_structures, stoichiometry, method_probab={"void": 0.0, "r
method_probab=method_probab_list, 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))
@@ -1904,21 +1530,17 @@ def get_structures(self, calculator=None):
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, \
@@ -1928,12 +1550,7 @@ def evaluate(self, basis):
@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)
@@ -1945,12 +1562,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:
@@ -1968,12 +1580,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)
@@ -1993,12 +1600,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)
@@ -2018,12 +1620,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)
@@ -2035,13 +1632,7 @@ def grid_spacing(self, grid_spacing):
@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)
@@ -2062,12 +1653,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)
@@ -2079,13 +1665,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)
@@ -2098,13 +1678,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)
@@ -2117,12 +1691,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)
@@ -2140,6 +1709,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,
From 6a47a24b0da43f7a497abd33c6327c87bff1916b Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Tue, 5 Nov 2024 10:37:40 +0000
Subject: [PATCH 21/60] Add more structure handling implement evaluate
---
src/fortran/lib/mod_generator.f90 | 132 +++++++++++++++++++++++---
src/raffle/raffle.py | 24 +++++
src/wrapper/f90wrap_mod_generator.f90 | 76 +++++++++++----
3 files changed, 203 insertions(+), 29 deletions(-)
diff --git a/src/fortran/lib/mod_generator.f90 b/src/fortran/lib/mod_generator.f90
index 8a64d7ec..110811bd 100644
--- a/src/fortran/lib/mod_generator.f90
+++ b/src/fortran/lib/mod_generator.f90
@@ -8,7 +8,7 @@ module raffle__generator
use raffle__io_utils, only: stop_program
use raffle__constants, only: real32
use raffle__misc_linalg, only: modu
- use raffle__misc, only: strip_null, set, shuffle
+ use raffle__misc, only: strip_null, set, shuffle, sort1D
use raffle__geom_rw, only: basis_type
use raffle__geom_extd, only: extended_basis_type
use raffle__distribs_container, only: distribs_container_type
@@ -78,6 +78,10 @@ module raffle__generator
!! 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.
end type raffle_generator_type
@@ -710,21 +714,77 @@ end function get_structures
!###############################################################################
- function evaluate(this, basis) result(viability)
- !! Evaluate the viability of the generated 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(in) :: this
+ class(raffle_generator_type), intent(inout) :: this
!! Instance of the raffle generator.
- type(basis_type), intent(in) :: basis
- !! Basis of the structure to evaluate.
- real(real32) :: viability
- !! Viability of the generated structures.
+ 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
+!###############################################################################
- viability = 0.0_real32
- call stop_program("Evaluate procedure not yet set up")
- return
- end function evaluate
+
+!###############################################################################
+ 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
!###############################################################################
@@ -744,4 +804,52 @@ subroutine allocate_structures(this, 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
+ !! Instance of the raffle generator.
+ type(basis_type), intent(in) :: basis
+ !! Basis of the structure to evaluate.
+ 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
+ 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
+ end function evaluate
+!###############################################################################
+
end module raffle__generator
\ No newline at end of file
diff --git a/src/raffle/raffle.py b/src/raffle/raffle.py
index 602758d5..2ed8a99a 100644
--- a/src/raffle/raffle.py
+++ b/src/raffle/raffle.py
@@ -1526,7 +1526,31 @@ def get_structures(self, calculator=None):
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):
"""
diff --git a/src/wrapper/f90wrap_mod_generator.f90 b/src/wrapper/f90wrap_mod_generator.f90
index 67480ce9..30365a19 100644
--- a/src/wrapper/f90wrap_mod_generator.f90
+++ b/src/wrapper/f90wrap_mod_generator.f90
@@ -807,28 +807,33 @@ subroutine f90wrap_generator__generate__binding__rgt( &
)
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 +851,50 @@ 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
!###############################################################################
! End of module generator defined in file ../src/lib/mod_generator.f90
From 737468c3631ba70b644cfbe2ea105431a47f9884 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Wed, 6 Nov 2024 06:15:37 +0000
Subject: [PATCH 22/60] Add atom division to evaluate
---
src/fortran/lib/mod_generator.f90 | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/fortran/lib/mod_generator.f90 b/src/fortran/lib/mod_generator.f90
index 110811bd..04516e8d 100644
--- a/src/fortran/lib/mod_generator.f90
+++ b/src/fortran/lib/mod_generator.f90
@@ -849,6 +849,8 @@ function evaluate(this, basis) result(viability)
)
end do
end do
+
+ viability = viability / real(basis%natom, real32)
end function evaluate
!###############################################################################
From c8b4bf9080b96ca1f6552a805f5bb94a6753fc10 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Wed, 6 Nov 2024 15:28:31 +0000
Subject: [PATCH 23/60] Fix placement methods
---
src/fortran/lib/mod_place_methods.f90 | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/fortran/lib/mod_place_methods.f90 b/src/fortran/lib/mod_place_methods.f90
index 701af50a..117d163f 100644
--- a/src/fortran/lib/mod_place_methods.f90
+++ b/src/fortran/lib/mod_place_methods.f90
@@ -164,18 +164,18 @@ function place_method_rand( distribs_container, &
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
- viable = .true.
-
end function place_method_rand
!###############################################################################
@@ -285,6 +285,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
@@ -463,6 +464,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
From 155338d61f87d35594e2ae1a85ca868257e4d6ac Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Wed, 6 Nov 2024 15:29:09 +0000
Subject: [PATCH 24/60] Fix element maps
---
src/fortran/lib/mod_distribs_container.f90 | 46 ++++++++++++++++++++++
src/fortran/lib/mod_evaluator.f90 | 4 +-
src/fortran/lib/mod_generator.f90 | 3 ++
3 files changed, 51 insertions(+), 2 deletions(-)
diff --git a/src/fortran/lib/mod_distribs_container.f90 b/src/fortran/lib/mod_distribs_container.f90
index 0c9e8d66..91195562 100644
--- a/src/fortran/lib/mod_distribs_container.f90
+++ b/src/fortran/lib/mod_distribs_container.f90
@@ -83,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
@@ -128,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
@@ -151,6 +156,8 @@ 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_gdfs
!! Write the generalised distribution functions to a file.
procedure, pass(this) :: read_gdfs
@@ -1125,6 +1132,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.
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 04516e8d..1a17d383 100644
--- a/src/fortran/lib/mod_generator.f90
+++ b/src/fortran/lib/mod_generator.f90
@@ -369,6 +369,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 &
)
From 2da59f20b0e556f3bc29352dbb8e3bc54163f2a8 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Thu, 21 Nov 2024 14:42:15 +0000
Subject: [PATCH 25/60] Add learning examples
---
.gitignore | 3 +-
example/python_pkg/Al_learn/learn.py | 212 +++++++++++++++++++
example/python_pkg/C_learn/learn.py | 212 +++++++++++++++++++
example/python_pkg/ScS2-Li_learn/POSCAR_host | 12 ++
example/python_pkg/ScS2-Li_learn/learn.py | 209 ++++++++++++++++++
5 files changed, 647 insertions(+), 1 deletion(-)
create mode 100644 example/python_pkg/Al_learn/learn.py
create mode 100644 example/python_pkg/C_learn/learn.py
create mode 100644 example/python_pkg/ScS2-Li_learn/POSCAR_host
create mode 100644 example/python_pkg/ScS2-Li_learn/learn.py
diff --git a/.gitignore b/.gitignore
index 7ff1d507..a6d1e5f2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,4 +31,5 @@ fort.*
*.agr
*.pdf
*.eps
-*.pyc
\ No newline at end of file
+*.pyc
+*.xyz
\ No newline at end of file
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/python_pkg/C_learn/learn.py b/example/python_pkg/C_learn/learn.py
new file mode 100644
index 00000000..997c76cd
--- /dev/null
+++ b/example/python_pkg/C_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.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 = 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 = '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.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('C', 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 = 12.011
+ 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.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 < 1.0:
+ print("Density too low", density, "u/A^3")
+ continue
+
+ seed += 1
+ print(f"Seed: {seed}")
+ generator.generate(
+ num_structures = 5,
+ stoichiometry = { 'C': 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/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
From 5edf5c7d96370d4ffa50173fc089bd3f9503e73f Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Mon, 2 Dec 2024 16:11:35 +0000
Subject: [PATCH 26/60] Add error and warning checks
---
src/fortran/lib/mod_distribs_container.f90 | 28 ++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/src/fortran/lib/mod_distribs_container.f90 b/src/fortran/lib/mod_distribs_container.f90
index 91195562..fabbe7bb 100644
--- a/src/fortran/lib/mod_distribs_container.f90
+++ b/src/fortran/lib/mod_distribs_container.f90
@@ -1921,6 +1921,11 @@ 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
@@ -2120,6 +2125,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
@@ -2406,6 +2412,14 @@ 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)))
@@ -2424,6 +2438,20 @@ 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)
From d1f277387709f32ffebde1316ede17e9f8ea74cd Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Thu, 5 Dec 2024 09:14:27 +0000
Subject: [PATCH 27/60] Add bounding box
---
src/fortran/lib/mod_generator.f90 | 61 ++++++++++++++++++++++++++-
src/fortran/lib/mod_place_methods.f90 | 60 +++++++++++++++++++-------
src/fortran/lib/mod_viability.f90 | 22 +++++-----
src/raffle/raffle.py | 41 ++++++++++++++++++
src/wrapper/f90wrap_mod_generator.f90 | 50 ++++++++++++++++++++++
test/test_evaluator_BTO.f90 | 1 +
test/test_evaluator_C.f90 | 1 +
test/test_place_methods.f90 | 5 ++-
test/test_viability.f90 | 12 +++++-
9 files changed, 221 insertions(+), 32 deletions(-)
diff --git a/src/fortran/lib/mod_generator.f90 b/src/fortran/lib/mod_generator.f90
index 1a17d383..47c57894 100644
--- a/src/fortran/lib/mod_generator.f90
+++ b/src/fortran/lib/mod_generator.f90
@@ -53,6 +53,13 @@ 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, 0.0_real32, 0.0_real32, &
+ 1.0_real32, 1.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,6 +79,10 @@ 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
@@ -214,7 +225,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
@@ -237,6 +251,43 @@ 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)
@@ -527,6 +578,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 ], &
@@ -585,6 +637,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 &
)
@@ -592,6 +645,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 ], &
@@ -603,6 +657,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 ], &
@@ -616,6 +671,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 ], &
@@ -630,6 +686,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 ], &
@@ -672,7 +729,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
diff --git a/src/fortran/lib/mod_place_methods.f90 b/src/fortran/lib/mod_place_methods.f90
index 117d163f..b2f9efc7 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,10 +161,8 @@ 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( &
@@ -182,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, &
@@ -201,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
@@ -217,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
@@ -243,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, &
@@ -253,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
@@ -263,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
@@ -277,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
@@ -327,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, &
@@ -350,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
@@ -366,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
@@ -410,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
@@ -424,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, &
@@ -432,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
@@ -442,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
@@ -456,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
diff --git a/src/fortran/lib/mod_viability.f90 b/src/fortran/lib/mod_viability.f90
index 338d3a59..fb46bc94 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
diff --git a/src/raffle/raffle.py b/src/raffle/raffle.py
index 2ed8a99a..751823ec 100644
--- a/src/raffle/raffle.py
+++ b/src/raffle/raffle.py
@@ -1469,6 +1469,25 @@ def reset_grid(self):
"""
_raffle.f90wrap_generator__reset_grid__binding__raffle_generator_type(this=self._handle)
+ def set_bounds(self, bounds=None):
+ """
+ Set the bounding box for the generation.
+
+ 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)
+
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):
"""
Generate structures using the RAFFLE method.
@@ -1652,7 +1671,27 @@ 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):
"""
@@ -1764,6 +1803,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_generator.f90 b/src/wrapper/f90wrap_mod_generator.f90
index 30365a19..a6e602de 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,6 +792,33 @@ 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)
diff --git a/test/test_evaluator_BTO.f90 b/test/test_evaluator_BTO.f90
index 439999e6..6e5dee9b 100644
--- a/test/test_evaluator_BTO.f90
+++ b/test/test_evaluator_BTO.f90
@@ -201,6 +201,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..c8017de6 100644
--- a/test/test_evaluator_C.f90
+++ b/test/test_evaluator_C.f90
@@ -185,6 +185,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_place_methods.f90 b/test/test_place_methods.f90
index b5e35c65..c7a54e14 100644
--- a/test/test_place_methods.f90
+++ b/test/test_place_methods.f90
@@ -55,9 +55,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 +70,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_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, &
From 162f4965a4cde7f07d751e4994505888c040bace Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Thu, 5 Dec 2024 12:14:47 +0000
Subject: [PATCH 28/60] Fix bounds default
---
src/fortran/lib/mod_generator.f90 | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/fortran/lib/mod_generator.f90 b/src/fortran/lib/mod_generator.f90
index 47c57894..c42bc299 100644
--- a/src/fortran/lib/mod_generator.f90
+++ b/src/fortran/lib/mod_generator.f90
@@ -55,8 +55,9 @@ module raffle__generator
!! Spacing of the gridpoints.
real(real32), dimension(2,3) :: bounds = reshape( &
(/ &
- 0.0_real32, 0.0_real32, 0.0_real32, &
- 1.0_real32, 1.0_real32, 1.0_real32 &
+ 0.0_real32, 1.0_real32, &
+ 0.0_real32, 1.0_real32, &
+ 0.0_real32, 1.0_real32 &
/), [2,3] &
)
!! Bounds for atom placement.
@@ -570,6 +571,7 @@ function generate_structure( &
call set(species_index_list)
+ write(*,*) "BOUNDS", this%bounds(1,:), this%bounds(2,:)
!---------------------------------------------------------------------------
! check for viable gridpoints
!---------------------------------------------------------------------------
From 555130a5a5e2062bfe4ec874c861a8e0998b152d Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Thu, 5 Dec 2024 12:15:08 +0000
Subject: [PATCH 29/60] Add unrelaxed structure print
---
example/python_pkg/C_learn/learn.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/example/python_pkg/C_learn/learn.py b/example/python_pkg/C_learn/learn.py
index 997c76cd..30297896 100644
--- a/example/python_pkg/C_learn/learn.py
+++ b/example/python_pkg/C_learn/learn.py
@@ -139,7 +139,7 @@ def process_structure(i, atoms, num_structures_old, calc, optimise_structure):
# print the number of structures generated
print("Total number of structures generated: ", generator.num_structures)
- generated_structures = generator.get_structures()
+ generated_structures = generator.get_structures(calc)
num_structures_new = len(generated_structures)
# check if directory iteration[iter] exists, if not create it
@@ -150,6 +150,9 @@ def process_structure(i, atoms, num_structures_old, calc, optimise_structure):
# 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:
From a4bcb3c7e2caff815f1340feadfcab8918dda772 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Thu, 5 Dec 2024 12:23:37 +0000
Subject: [PATCH 30/60] Remove dev print
---
src/fortran/lib/mod_generator.f90 | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/fortran/lib/mod_generator.f90 b/src/fortran/lib/mod_generator.f90
index c42bc299..468f6ead 100644
--- a/src/fortran/lib/mod_generator.f90
+++ b/src/fortran/lib/mod_generator.f90
@@ -571,7 +571,6 @@ function generate_structure( &
call set(species_index_list)
- write(*,*) "BOUNDS", this%bounds(1,:), this%bounds(2,:)
!---------------------------------------------------------------------------
! check for viable gridpoints
!---------------------------------------------------------------------------
From 84bee230da830113bfa95b67a2b2c871ac020950 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Mon, 16 Dec 2024 07:27:34 +0000
Subject: [PATCH 31/60] Fix theme name
---
docs/source/conf.py | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/docs/source/conf.py b/docs/source/conf.py
index dd8f1b79..342beaac 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -44,12 +44,11 @@
# -- Options for HTML output
-html_theme = 'sphinx_rtd_theme'
+html_theme = 'sphinx-rtd-theme'
# -- Options for EPUB output
epub_show_urls = 'footnote'
-html_theme = 'sphinx_rtd_theme'
html_logo = "RAFFLE_logo_no_background.png"
# html_favicon = 'favicon.ico'
html_theme_options = {
@@ -78,4 +77,4 @@
"conf_py_path": "/docs/source",
}
-autoclass_content="both"
\ No newline at end of file
+autoclass_content="both"
From afad901c353bf5952c307958072bf2cf76a7d443 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Mon, 16 Dec 2024 08:05:20 +0000
Subject: [PATCH 32/60] Fix theme
---
docs/source/conf.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 342beaac..86651f2c 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -29,6 +29,7 @@
'sphinx.ext.intersphinx',
'sphinx.ext.napoleon',
'sphinx.ext.viewcode',
+ 'sphinx_rtd_theme',
]
intersphinx_mapping = {
@@ -44,7 +45,7 @@
# -- Options for HTML output
-html_theme = 'sphinx-rtd-theme'
+html_theme = 'sphinx_rtd_theme'
# -- Options for EPUB output
epub_show_urls = 'footnote'
From 2c890e54c7067283b1342322e7145e02c17a8bf1 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Mon, 16 Dec 2024 08:10:39 +0000
Subject: [PATCH 33/60] Include requirements
---
.readthedocs.yaml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
index bb958bfb..f8a9957e 100644
--- a/.readthedocs.yaml
+++ b/.readthedocs.yaml
@@ -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
From 4829ed55aa75db57a70f78e4a90ba5f073c44e1e Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Mon, 16 Dec 2024 08:11:46 +0000
Subject: [PATCH 34/60] Add file
---
docs/requirements.txt | 2 ++
1 file changed, 2 insertions(+)
create mode 100644 docs/requirements.txt
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
From fb1b4426cc2258f20241fab1800f502fa41a1fd2 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Mon, 16 Dec 2024 08:33:35 +0000
Subject: [PATCH 35/60] Update links to ExeQuantCode
---
README.md | 7 ++++---
docs/source/conf.py | 2 +-
docs/source/install.rst | 6 +++---
ford.md | 6 +++---
pyproject.toml | 6 +++---
5 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/README.md b/README.md
index a5ff815a..0611cc53 100644
--- a/README.md
+++ b/README.md
@@ -3,13 +3,14 @@
[](https://www.gnu.org/licenses/gpl-3.0.en.html "View GPLv3 license")
-[](https://github.com/nedtaylor/RAFFLE/releases "View on GitHub")
+[](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)
[](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")
+[](https://raffle-fortran.readthedocs.io/en/latest/ "RAFFLE ReadTheDocs")
# RAFFLE
@@ -56,7 +57,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
```
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 86651f2c..e465c946 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -73,7 +73,7 @@
html_context = {
"display_github": True,
"github_repo": "RAFFLE",
- "github_user": "nedtaylor",
+ "github_user": "ExeQuantCode",
"github_version": "development",
"conf_py_path": "/docs/source",
}
diff --git a/docs/source/install.rst b/docs/source/install.rst
index 6042e8f5..59d98c0b 100644
--- a/docs/source/install.rst
+++ b/docs/source/install.rst
@@ -11,13 +11,13 @@ All versions rely on the core Fortran code, with the Python package and standalo
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 `_.
+The code is hosted on `GitHub `_.
This can be done by cloning the repository:
.. code-block:: bash
- git clone https://github.com/nedtaylor/RAFFLE
+ git clone https://github.com/ExeQuantCode/RAFFLE
cd RAFFLE
.. note::
@@ -136,7 +136,7 @@ This can also be set up as a dependency in your own fpm project by adding the fo
.. code-block:: toml
[dependencies]
- raffle = { git = "https://github.com/nedtaylor/RAFFLE" }
+ raffle = { git = "https://github.com/ExeQuantCode/RAFFLE" }
Installation using cmake
------------------------
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/pyproject.toml b/pyproject.toml
index ede00d18..41d38b5d 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -53,10 +53,10 @@ 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]
ase = ["ase>=3.23.0"]
From 9f6bd308d74c52249219d6b10184ae8824076275 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Mon, 16 Dec 2024 08:35:33 +0000
Subject: [PATCH 36/60] Remove duplicate badge
---
README.md | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 0611cc53..0ed446fd 100644
--- a/README.md
+++ b/README.md
@@ -5,12 +5,11 @@
[](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)
+[](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://ExeQuantCode.github.io/RAFFLE/ "View coverage report")
-[](https://raffle-fortran.readthedocs.io/en/latest/ "RAFFLE ReadTheDocs")
# RAFFLE
From d1f3e957fbc327d99c57f91d01584b3d00c826e3 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Mon, 16 Dec 2024 09:06:16 +0000
Subject: [PATCH 37/60] Add bounds unit tests
---
test/test_generator.f90 | 68 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 68 insertions(+)
diff --git a/test/test_generator.f90 b/test/test_generator.f90
index d350177a..57db7e84 100644
--- a/test/test_generator.f90
+++ b/test/test_generator.f90
@@ -10,9 +10,11 @@ program test_generator
class(raffle_generator_type), allocatable :: generator_var
type(basis_type) :: basis_host, basis_host_expected
type(basis_type), dimension(1) :: database
+ 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.
@@ -223,6 +225,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
!-----------------------------------------------------------------------------
From 7382d076db2925339f57f7c6d513f649c195443a Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Mon, 16 Dec 2024 10:20:02 +0000
Subject: [PATCH 38/60] Fix unit tests
---
test/test_evaluator_BTO.f90 | 6 ++++++
test/test_evaluator_C.f90 | 6 ++++++
2 files changed, 12 insertions(+)
diff --git a/test/test_evaluator_BTO.f90 b/test/test_evaluator_BTO.f90
index 6e5dee9b..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 &
+ )
!-----------------------------------------------------------------------------
diff --git a/test/test_evaluator_C.f90 b/test/test_evaluator_C.f90
index c8017de6..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 &
+ )
!-----------------------------------------------------------------------------
From fdee95e69670ceee90bc3a80ea21495d2d322a11 Mon Sep 17 00:00:00 2001
From: Ned Taylor <71959356+nedtaylor@users.noreply.github.com>
Date: Mon, 16 Dec 2024 10:55:02 +0000
Subject: [PATCH 39/60] Add file
---
CODE_OF_CONDUCT.md | 70 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 70 insertions(+)
create mode 100644 CODE_OF_CONDUCT.md
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).
From 2d18be0084ff3f6d19c91deb8a0f424b61238901 Mon Sep 17 00:00:00 2001
From: Ned Taylor <71959356+nedtaylor@users.noreply.github.com>
Date: Mon, 16 Dec 2024 10:58:55 +0000
Subject: [PATCH 40/60] Update README.md
---
README.md | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 0ed446fd..0b879da6 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
-[](https://www.gnu.org/licenses/gpl-3.0.en.html "View GPLv3 license")
+[](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")
@@ -176,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:
From d885d27ac4482054731d8fa441fceba9dbaf9f87 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Mon, 16 Dec 2024 11:07:30 +0000
Subject: [PATCH 41/60] Add file
---
CITATION.cff | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
create mode 100644 CITATION.cff
diff --git a/CITATION.cff b/CITATION.cff
new file mode 100644
index 00000000..23772a40
--- /dev/null
+++ b/CITATION.cff
@@ -0,0 +1,35 @@
+# 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.
+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: 696eae36488d0861001597e9aa848968a26cdd85
+version: 0.4.0
+date-released: '2024-10-23'
From df281a19da5ff656e575bed52d8d62f766d5b9e9 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Wed, 11 Dec 2024 13:56:46 +0000
Subject: [PATCH 42/60] Add file exist check
---
src/fortran/lib/mod_distribs_container.f90 | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/fortran/lib/mod_distribs_container.f90 b/src/fortran/lib/mod_distribs_container.f90
index fabbe7bb..5902b432 100644
--- a/src/fortran/lib/mod_distribs_container.f90
+++ b/src/fortran/lib/mod_distribs_container.f90
@@ -706,9 +706,19 @@ subroutine read_gdfs(this, file)
!! 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
From abc6cfc32d1db64a342d398e4ae23535a16d9e66 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Thu, 12 Dec 2024 14:58:28 +0000
Subject: [PATCH 43/60] Fix settings printing
---
src/fortran/lib/mod_generator.f90 | 155 +++++++++++++++++++++++++-
src/raffle/raffle.py | 23 +++-
src/wrapper/f90wrap_mod_generator.f90 | 21 +++-
3 files changed, 193 insertions(+), 6 deletions(-)
diff --git a/src/fortran/lib/mod_generator.f90 b/src/fortran/lib/mod_generator.f90
index 468f6ead..742ae830 100644
--- a/src/fortran/lib/mod_generator.f90
+++ b/src/fortran/lib/mod_generator.f90
@@ -96,6 +96,11 @@ module raffle__generator
!! 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
@@ -291,7 +296,9 @@ 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
@@ -311,6 +318,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.
@@ -349,7 +358,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
@@ -360,6 +374,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
!---------------------------------------------------------------------------
@@ -915,4 +938,132 @@ function evaluate(this, basis) result(viability)
end function evaluate
!###############################################################################
+
+!###############################################################################
+ 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 :: newunit
+ !! Unit number for the file.
+
+ ! Open the file
+ open(unit=newunit, file=file)
+
+ write(newunit,'("# RAFFLE Generator Settings")')
+ !print host lattice
+ write(newunit,'("# GENERATOR SETTINGS")')
+ write(newunit,'("HOST_LATTICE # not a setting, just for reference")')
+ write(newunit,'(" ",3(1X,F5.2))') this%host%lat(1,:)
+ write(newunit,'(" ",3(1X,F5.2))') this%host%lat(2,:)
+ write(newunit,'(" ",3(1X,F5.2))') this%host%lat(3,:)
+ write(newunit,'("END HOST_LATTICE")')
+
+ write(newunit,'("GRID =",3(1X,I0))') this%grid
+ write(newunit,'("GRID_OFFSET =",3(1X,F5.2))') this%grid_offset
+ write(newunit,'("GRID_SPACING = ",F5.2)') this%grid_spacing
+ write(newunit,'("BOUNDS_LW =",3(1X,F5.2))') this%bounds(1,:)
+ write(newunit,'("BOUNDS_UP =",3(1X,F5.2))') this%bounds(2,:)
+
+ write(newunit,'("MAX_ATTEMPTS =",I0)') this%max_attempts
+ write(newunit,'("WALK_STEP_SIZE_COARSE = ",F5.2)') this%walk_step_size_coarse
+ write(newunit,'("WALK_STEP_SIZE_FINE = ",F5.2)') this%walk_step_size_fine
+ write(newunit,'("METHOD_VOID = ",F7.4)') this%method_probab(1)
+ write(newunit,'("METHOD_RANDOM = ",F7.4)') this%method_probab(2)
+ write(newunit,'("METHOD_WALK = ",F7.4)') this%method_probab(3)
+ write(newunit,'("METHOD_GROW = ",F7.4)') this%method_probab(4)
+ write(newunit,'("METHOD_MIN = ",F7.4)') this%method_probab(5)
+
+ write(newunit,'("# DISTRIBUTION SETTINGS")')
+ write(newunit,'("KBT = ",F5.2)') this%distributions%kbt
+ write(newunit,'("SIGMA =",3(1X,F7.4))') this%distributions%sigma
+ write(newunit,'("WIDTH =",3(1X,F7.4))') this%distributions%width
+ write(newunit,'("CUTOFF_MIN =",3(1X,F7.4))') this%distributions%cutoff_min
+ write(newunit,'("CUTOFF_MAX =",3(1X,F7.4))') this%distributions%cutoff_max
+ write(newunit,'("RADIUS_DISTANCE_TOLERANCE = ",F7.4)') &
+ this%distributions%radius_distance_tol
+ write(newunit,'("ELEMENT_INFO # element : energy")')
+ do i = 1, size(this%distributions%element_info)
+ write(newunit,'(" ",A," : ",F15.9)') &
+ this%distributions%element_info(i)%name, &
+ this%distributions%element_info(i)%energy
+ end do
+ write(newunit,'("END ELEMENT_INFO")')
+ write(newunit,'("BOND_INFO # element1 element2 : radius")')
+ do i = 1, size(this%distributions%bond_info)
+ write(newunit,'(" ",A," ",A," : ",F7.4)') &
+ this%distributions%bond_info(i)%element(1), &
+ this%distributions%bond_info(i)%element(2), &
+ this%distributions%bond_info(i)%radius_covalent
+ end do
+ write(newunit,'("END BOND_INFO")')
+
+ close(newunit)
+
+ 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.
+ character(*), intent(in) :: file
+ !! Filename to read the settings from.
+
+ ! Local variables
+ integer :: i
+ !! Loop index.
+ integer :: newunit
+ !! Unit number for the file.
+ logical :: exist
+ !! Boolean for file existence.
+ character(len=256) :: line, buffer
+ !! Line from the file.
+
+ ! Check if the file exists
+ inquire(file=file, exist=exist)
+ if(.not.exist)then
+ call stop_program("File does not exist")
+ return
+ end if
+
+ call stop_program("Code not implemented")
+ return
+
+ ! Open the file
+ open(unit=newunit, file=file)
+
+ do
+ read(newunit,*) line
+ if(index(line,'#').gt.0) line = line(1:index(line,'#')-1)
+ line = trim(adjustl(line))
+ if(len(trim(line)).eq.0) cycle
+
+ read(line,*) buffer
+ if(buffer.eq.'HOST_LATTICE')then
+ do i = 1, 4
+ read(newunit,*)
+ end do
+ end if
+ end do
+
+ close(newunit)
+
+ end subroutine read_generator_settings
+!###############################################################################
+
end module raffle__generator
\ No newline at end of file
diff --git a/src/raffle/raffle.py b/src/raffle/raffle.py
index 751823ec..39e781f1 100644
--- a/src/raffle/raffle.py
+++ b/src/raffle/raffle.py
@@ -1488,7 +1488,7 @@ def reset_bounds(self):
"""
_raffle.f90wrap_generator__reset_bounds__binding__rgt(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 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.
@@ -1501,6 +1501,8 @@ def generate(self, num_structures, stoichiometry, method_probab={"void": 0.0, "r
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.
"""
@@ -1525,13 +1527,17 @@ 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):
"""
@@ -1590,6 +1596,17 @@ def evaluate(self, basis):
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)
+
@property
def num_structures(self):
"""
diff --git a/src/wrapper/f90wrap_mod_generator.f90 b/src/wrapper/f90wrap_mod_generator.f90
index a6e602de..0e09c38d 100644
--- a/src/wrapper/f90wrap_mod_generator.f90
+++ b/src/wrapper/f90wrap_mod_generator.f90
@@ -821,7 +821,7 @@ 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
@@ -843,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
@@ -853,6 +854,7 @@ 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
@@ -945,6 +947,23 @@ subroutine f90wrap_generator__evaluate__binding__rgt(this, ret_viability, basis)
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
!###############################################################################
! End of module generator defined in file ../src/lib/mod_generator.f90
From a3cc027718bc84a99329b6c84e17aae8e466318e Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Mon, 16 Dec 2024 11:49:22 +0000
Subject: [PATCH 44/60] Change parallel process
---
example/python_pkg/C_learn/learn.py | 212 +++++++++++++++++-----------
1 file changed, 126 insertions(+), 86 deletions(-)
diff --git a/example/python_pkg/C_learn/learn.py b/example/python_pkg/C_learn/learn.py
index 30297896..5514af5b 100644
--- a/example/python_pkg/C_learn/learn.py
+++ b/example/python_pkg/C_learn/learn.py
@@ -1,28 +1,58 @@
from mace.calculators import mace_mp
from raffle.generator import raffle_generator
from ase import build, Atoms
-from ase.optimize import BFGS
+from ase.optimize import BFGS, FIRE
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):
+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()
+ # 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 = BFGS(atoms, trajectory = f"traje{inew}.traj", logfile=f"optimisation{inew}.log")
- optimizer.run(fmax=0.05, steps=500)
+ 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)
@@ -55,12 +85,18 @@ def process_structure(i, atoms, num_structures_old, calc, optimise_structure):
if __name__ == "__main__":
+ calc_params = {
+ "model": "medium",
+ "dispersion": False,
+ "default_dtype": "float32",
+ "device": 'cpu'
+ }
calc = mace_mp(model="medium", dispersion=False, default_dtype="float32", device='cpu')
crystal_structures = [
'orthorhombic', 'diamond',
- 'bct', 'sc',
- 'fcc', 'bcc', 'hcp',
+ # 'bct', 'sc',
+ # 'fcc', 'bcc', 'hcp',
]
hosts = []
@@ -89,14 +125,15 @@ def process_structure(i, atoms, num_structures_old, calc, optimise_structure):
}
)
# set energy scale
- generator.distributions.set_kBT(0.4)
+ 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.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:
@@ -117,87 +154,90 @@ def process_structure(i, atoms, num_structures_old, calc, optimise_structure):
print("setting host")
generator.set_host(host)
volume = host.get_volume()
- for num_atoms in range(1, 20):
+ 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")
+ # print("Density too high:", density, "u/A^3")
continue
- elif density < 1.0:
- print("Density too low", density, "u/A^3")
+ elif density < 2.0:
+ # print("Density too low", density, "u/A^3")
continue
- seed += 1
- print(f"Seed: {seed}")
- generator.generate(
- num_structures = 5,
- stoichiometry = { 'C': 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(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(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, 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
+ 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")
+
+ # update the number of structures generated
+ num_structures_old = num_structures_new
generator.distributions.write_gdfs("gdfs.txt")
@@ -207,9 +247,9 @@ def process_structure(i, atoms, num_structures_old, calc, optimise_structure):
# Parse and sort the energies
energies = [line.strip().split() for line in energies]
- energies = sorted(energies, key=lambda x: float(x[0]))
+ 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"{entry[0]}\n")
\ No newline at end of file
+ energy_file.write(f"{int(entry[0])} {float(entry[1])}\n")
From 18c052b60dc100121658126540d148e8671f8f5b Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Mon, 16 Dec 2024 13:43:35 +0000
Subject: [PATCH 45/60] Remove trailing whitespace
---
src/fortran/lib/mod_place_methods.f90 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/fortran/lib/mod_place_methods.f90 b/src/fortran/lib/mod_place_methods.f90
index b2f9efc7..cb704429 100644
--- a/src/fortran/lib/mod_place_methods.f90
+++ b/src/fortran/lib/mod_place_methods.f90
@@ -249,7 +249,7 @@ 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
From 07624a3b3183aec87fd5b3b60ff4dee5ee4230c0 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Mon, 16 Dec 2024 13:43:55 +0000
Subject: [PATCH 46/60] Add unit tests
---
test/CMakeLists.txt | 1 +
test/test_dist_calcs.f90 | 90 ++++++++++++++++++++-
test/test_generator.f90 | 30 +++++++
test/test_io_utils.f90 | 34 ++++++++
test/test_place_methods.f90 | 157 ++++++++++++++++++++++++++++++++++++
5 files changed, 309 insertions(+), 3 deletions(-)
create mode 100644 test/test_io_utils.f90
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index d06716ce..8e92d87c 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -14,6 +14,7 @@ foreach(execid
evaluator_C
evaluator_BTO
generator
+ io_utils
)
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_generator.f90 b/test/test_generator.f90
index 57db7e84..348ded38 100644
--- a/test/test_generator.f90
+++ b/test/test_generator.f90
@@ -6,10 +6,12 @@ program test_generator
implicit none
integer :: i
+ real(real32) :: rtmp1
type(raffle_generator_type) :: generator
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
@@ -359,6 +361,34 @@ program test_generator
)
+ !-----------------------------------------------------------------------------
+ ! handle structures
+ !-----------------------------------------------------------------------------
+ structures_store = generator%get_structures()
+ if(size(structures_store) .ne. 3) then
+ write(0,*) 'Generator failed to get structures'
+ success = .false.
+ end if
+ call generator%remove_structure(1)
+ structures = generator%get_structures()
+ if(size(structures) .ne. 2) then
+ write(0,*) 'Generator failed to remove structure'
+ success = .false.
+ end if
+ call generator%set_structures( structures_store )
+ structures = generator%get_structures()
+ if(size(structures) .ne. 3) then
+ write(0,*) 'Generator failed to set structures'
+ success = .false.
+ end if
+ rtmp1 = generator%evaluate( structures_store(1) )
+ if(rtmp1 .lt. 0.0) then
+ write(0,*) 'Generator failed to evaluate structure'
+ success = .false.
+ end if
+
+
+
!-----------------------------------------------------------------------------
! check for any failed tests
!-----------------------------------------------------------------------------
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 c7a54e14..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
!-----------------------------------------------------------------------------
From 6eddd1bacb82fad3e832aee0fee2d6253098b60d Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Mon, 16 Dec 2024 15:15:44 +0000
Subject: [PATCH 47/60] Add file
---
src/fortran/lib/mod_tools_infile.f90 | 333 +++++++++++++++++++++++++++
1 file changed, 333 insertions(+)
create mode 100644 src/fortran/lib/mod_tools_infile.f90
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
From d7fd04edc334130c2794a78b17043f8725306bb3 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Mon, 16 Dec 2024 15:16:10 +0000
Subject: [PATCH 48/60] Handle settings read
---
CMakeLists.txt | 1 +
src/fortran/lib/mod_generator.f90 | 181 +++++++++++++++++++++---------
2 files changed, 129 insertions(+), 53 deletions(-)
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/src/fortran/lib/mod_generator.f90 b/src/fortran/lib/mod_generator.f90
index 742ae830..1d7ab293 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, sort1D
+ 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
@@ -953,61 +954,61 @@ subroutine print_generator_settings(this, file)
! Local variables
integer :: i
!! Loop index.
- integer :: newunit
+ integer :: unit
!! Unit number for the file.
! Open the file
- open(unit=newunit, file=file)
+ open(newunit=unit, file=file)
- write(newunit,'("# RAFFLE Generator Settings")')
+ write(unit,'("# RAFFLE Generator Settings")')
!print host lattice
- write(newunit,'("# GENERATOR SETTINGS")')
- write(newunit,'("HOST_LATTICE # not a setting, just for reference")')
- write(newunit,'(" ",3(1X,F5.2))') this%host%lat(1,:)
- write(newunit,'(" ",3(1X,F5.2))') this%host%lat(2,:)
- write(newunit,'(" ",3(1X,F5.2))') this%host%lat(3,:)
- write(newunit,'("END HOST_LATTICE")')
-
- write(newunit,'("GRID =",3(1X,I0))') this%grid
- write(newunit,'("GRID_OFFSET =",3(1X,F5.2))') this%grid_offset
- write(newunit,'("GRID_SPACING = ",F5.2)') this%grid_spacing
- write(newunit,'("BOUNDS_LW =",3(1X,F5.2))') this%bounds(1,:)
- write(newunit,'("BOUNDS_UP =",3(1X,F5.2))') this%bounds(2,:)
-
- write(newunit,'("MAX_ATTEMPTS =",I0)') this%max_attempts
- write(newunit,'("WALK_STEP_SIZE_COARSE = ",F5.2)') this%walk_step_size_coarse
- write(newunit,'("WALK_STEP_SIZE_FINE = ",F5.2)') this%walk_step_size_fine
- write(newunit,'("METHOD_VOID = ",F7.4)') this%method_probab(1)
- write(newunit,'("METHOD_RANDOM = ",F7.4)') this%method_probab(2)
- write(newunit,'("METHOD_WALK = ",F7.4)') this%method_probab(3)
- write(newunit,'("METHOD_GROW = ",F7.4)') this%method_probab(4)
- write(newunit,'("METHOD_MIN = ",F7.4)') this%method_probab(5)
-
- write(newunit,'("# DISTRIBUTION SETTINGS")')
- write(newunit,'("KBT = ",F5.2)') this%distributions%kbt
- write(newunit,'("SIGMA =",3(1X,F7.4))') this%distributions%sigma
- write(newunit,'("WIDTH =",3(1X,F7.4))') this%distributions%width
- write(newunit,'("CUTOFF_MIN =",3(1X,F7.4))') this%distributions%cutoff_min
- write(newunit,'("CUTOFF_MAX =",3(1X,F7.4))') this%distributions%cutoff_max
- write(newunit,'("RADIUS_DISTANCE_TOLERANCE = ",F7.4)') &
+ 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(newunit,'("ELEMENT_INFO # element : energy")')
+ write(unit,'("ELEMENT_INFO # element : energy")')
do i = 1, size(this%distributions%element_info)
- write(newunit,'(" ",A," : ",F15.9)') &
+ write(unit,'(" ",A," : ",F15.9)') &
this%distributions%element_info(i)%name, &
this%distributions%element_info(i)%energy
end do
- write(newunit,'("END ELEMENT_INFO")')
- write(newunit,'("BOND_INFO # element1 element2 : radius")')
+ write(unit,'("END ELEMENT_INFO")')
+ write(unit,'("BOND_INFO # element1 element2 : radius")')
do i = 1, size(this%distributions%bond_info)
- write(newunit,'(" ",A," ",A," : ",F7.4)') &
+ 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(newunit,'("END BOND_INFO")')
+ write(unit,'("END BOND_INFO")')
- close(newunit)
+ close(unit)
end subroutine print_generator_settings
!###############################################################################
@@ -1027,12 +1028,18 @@ subroutine read_generator_settings(this, file)
! Local variables
integer :: i
!! Loop index.
- integer :: newunit
+ integer :: itmp1, status
+ !! Temporary integer.
+ integer :: unit
!! Unit number for the file.
logical :: exist
!! Boolean for file existence.
- character(len=256) :: line, buffer
+ 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)
@@ -1041,27 +1048,95 @@ subroutine read_generator_settings(this, file)
return
end if
- call stop_program("Code not implemented")
- return
-
! Open the file
- open(unit=newunit, file=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(newunit,*) line
+ 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 = trim(adjustl(line))
+ line = to_upper(trim(adjustl(line)))
if(len(trim(line)).eq.0) cycle
- read(line,*) buffer
- if(buffer.eq.'HOST_LATTICE')then
+ 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(newunit,*)
+ read(unit,*)
end do
- end if
+ 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(newunit)
+ close(unit)
end subroutine read_generator_settings
!###############################################################################
From a144ba3094b85615008cac427d220dbdbe0cf644 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Mon, 16 Dec 2024 15:16:24 +0000
Subject: [PATCH 49/60] Add unit tests
---
test/CMakeLists.txt | 1 +
test/test_generator.f90 | 150 ++++++++++++++++++++++++++++++++-----
test/test_tools_infile.f90 | 83 ++++++++++++++++++++
3 files changed, 216 insertions(+), 18 deletions(-)
create mode 100644 test/test_tools_infile.f90
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 8e92d87c..0a56af58 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -15,6 +15,7 @@ foreach(execid
evaluator_BTO
generator
io_utils
+ tools_infile
)
add_executable(test_${execid} test_${execid}.f90)
# # Specify the include directories
diff --git a/test/test_generator.f90 b/test/test_generator.f90
index 348ded38..c10d422a 100644
--- a/test/test_generator.f90
+++ b/test/test_generator.f90
@@ -5,9 +5,11 @@ program test_generator
use raffle__generator, only: raffle_generator_type, stoichiometry_type
implicit none
- integer :: i
+ integer :: i, newunit
real(real32) :: rtmp1
- type(raffle_generator_type) :: generator
+ 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
@@ -365,28 +367,140 @@ program test_generator
! handle structures
!-----------------------------------------------------------------------------
structures_store = generator%get_structures()
- if(size(structures_store) .ne. 3) then
- write(0,*) 'Generator failed to get structures'
- success = .false.
- end if
+ call assert( &
+ size(structures_store) .eq. 3, &
+ 'Generator failed to get structures', &
+ success &
+ )
call generator%remove_structure(1)
structures = generator%get_structures()
- if(size(structures) .ne. 2) then
- write(0,*) 'Generator failed to remove structure'
- success = .false.
- end if
+ call assert( &
+ size(structures) .eq. 2, &
+ 'Generator failed to remove structure', &
+ success &
+ )
call generator%set_structures( structures_store )
structures = generator%get_structures()
- if(size(structures) .ne. 3) then
- write(0,*) 'Generator failed to set structures'
- success = .false.
- end if
+ call assert( &
+ size(structures) .eq. 3, &
+ 'Generator failed to set structures', &
+ success &
+ )
rtmp1 = generator%evaluate( structures_store(1) )
- if(rtmp1 .lt. 0.0) then
- write(0,*) 'Generator failed to evaluate structure'
- success = .false.
- end if
+ 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')
!-----------------------------------------------------------------------------
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
From 9dd89c0f6ceb7f7ce0d1fc74f6c3a1cd07a5f1f6 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Mon, 16 Dec 2024 15:56:13 +0000
Subject: [PATCH 50/60] Handle settings read
---
src/raffle/raffle.py | 11 +++++++++++
src/wrapper/f90wrap_mod_generator.f90 | 17 +++++++++++++++++
2 files changed, 28 insertions(+)
diff --git a/src/raffle/raffle.py b/src/raffle/raffle.py
index 39e781f1..5202e2cf 100644
--- a/src/raffle/raffle.py
+++ b/src/raffle/raffle.py
@@ -1606,6 +1606,17 @@ def print_settings(self, file):
"""
_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):
diff --git a/src/wrapper/f90wrap_mod_generator.f90 b/src/wrapper/f90wrap_mod_generator.f90
index 0e09c38d..689fade8 100644
--- a/src/wrapper/f90wrap_mod_generator.f90
+++ b/src/wrapper/f90wrap_mod_generator.f90
@@ -964,6 +964,23 @@ subroutine f90wrap_generator__print_settings__binding__rgt( &
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
From aa326503cf34a53b0d67be342c01d50aab217d91 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Mon, 16 Dec 2024 16:21:06 +0000
Subject: [PATCH 51/60] Add python unit tests
---
pyproject.toml | 4 +
test/test_raffle.py | 212 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 216 insertions(+)
create mode 100644 test/test_raffle.py
diff --git a/pyproject.toml b/pyproject.toml
index 41d38b5d..9b4c17b4 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -61,6 +61,10 @@ Issues = "https://github.com/ExeQuantCode/raffle/issues"
[project.optional-dependencies]
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/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
From 2f9b0ab08b012e5bbab1ca9050ae8ff4fa4cb824 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Mon, 16 Dec 2024 16:29:12 +0000
Subject: [PATCH 52/60] Update ignore list
---
.gitignore | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/.gitignore b/.gitignore
index a6d1e5f2..5ad42711 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,4 +32,5 @@ fort.*
*.pdf
*.eps
*.pyc
-*.xyz
\ No newline at end of file
+*.xyz
+.coverage
\ No newline at end of file
From 4a7353947aebcda1ae8735e27b07eda1cd7e7a3d Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Mon, 16 Dec 2024 16:45:45 +0000
Subject: [PATCH 53/60] Fix uninitialised tolerance
---
test/test_generator.f90 | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/test/test_generator.f90 b/test/test_generator.f90
index c10d422a..82dd2138 100644
--- a/test/test_generator.f90
+++ b/test/test_generator.f90
@@ -174,7 +174,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 &
)
@@ -336,7 +339,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 &
)
@@ -516,8 +520,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
From 1a322ada96b55e983ffaee74adcfeced0aac769c Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Tue, 17 Dec 2024 06:43:26 +0000
Subject: [PATCH 54/60] Fix missing tolerance
---
test/test_generator.f90 | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/test/test_generator.f90 b/test/test_generator.f90
index 82dd2138..6c3f5a2c 100644
--- a/test/test_generator.f90
+++ b/test/test_generator.f90
@@ -132,7 +132,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 &
)
From 8c17d268d8292a62b1018ab6076253e9070d49bc Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Tue, 17 Dec 2024 07:01:47 +0000
Subject: [PATCH 55/60] Add missing use statement
---
test/test_generator.f90 | 1 +
1 file changed, 1 insertion(+)
diff --git a/test/test_generator.f90 b/test/test_generator.f90
index 6c3f5a2c..d59be16d 100644
--- a/test/test_generator.f90
+++ b/test/test_generator.f90
@@ -1,5 +1,6 @@
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
From 3be9ab242e70140a8f5791025f460c4ba4375e95 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Tue, 17 Dec 2024 12:51:19 +0000
Subject: [PATCH 56/60] Fix viability update
---
src/fortran/lib/mod_viability.f90 | 33 +++++++++++++++++++++----------
1 file changed, 23 insertions(+), 10 deletions(-)
diff --git a/src/fortran/lib/mod_viability.f90 b/src/fortran/lib/mod_viability.f90
index fb46bc94..b5bfe028 100644
--- a/src/fortran/lib/mod_viability.f90
+++ b/src/fortran/lib/mod_viability.f90
@@ -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
!###############################################################################
From fa4d51760a4a5e58de5cd2d8afd10b9485abe179 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Tue, 17 Dec 2024 13:23:44 +0000
Subject: [PATCH 57/60] Fix indentation check
---
src/fortran/lib/mod_distribs_container.f90 | 21 +++++---
src/fortran/lib/mod_generator.f90 | 59 +++++++++++-----------
tools/check_indentation.py | 10 +++-
3 files changed, 52 insertions(+), 38 deletions(-)
diff --git a/src/fortran/lib/mod_distribs_container.f90 b/src/fortran/lib/mod_distribs_container.f90
index 5902b432..99252680 100644
--- a/src/fortran/lib/mod_distribs_container.f90
+++ b/src/fortran/lib/mod_distribs_container.f90
@@ -1932,8 +1932,10 @@ subroutine set_best_energy(this)
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.")')
+ 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
@@ -2423,9 +2425,12 @@ subroutine evolve(this, system)
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), &
+ 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
@@ -2451,13 +2456,15 @@ subroutine evolve(this, system)
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)') &
+ &" 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)') &
+ &" with norm of ",F0.3)' &
+ ) &
this%element_info(is)%name, this%norm_4body(is)
call stop_program( err_msg )
return
diff --git a/src/fortran/lib/mod_generator.f90 b/src/fortran/lib/mod_generator.f90
index 1d7ab293..1e070914 100644
--- a/src/fortran/lib/mod_generator.f90
+++ b/src/fortran/lib/mod_generator.f90
@@ -260,37 +260,37 @@ 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
+ !! 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
+ !! Reset the grid for the raffle generator.
+ implicit none
- ! Arguments
- class(raffle_generator_type), intent(inout) :: this
- !! Instance of the raffle generator.
+ ! 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
+ this%bounds(1,:) = 0.0_real32
+ this%bounds(2,:) = 1.0_real32
+ end subroutine reset_bounds
!###############################################################################
@@ -869,7 +869,7 @@ subroutine remove_structure(this, index)
this%num_structures = this%num_structures - 1
end do
- end subroutine remove_structure
+ end subroutine remove_structure
!###############################################################################
@@ -961,7 +961,6 @@ subroutine print_generator_settings(this, file)
open(newunit=unit, file=file)
write(unit,'("# RAFFLE Generator Settings")')
- !print host lattice
write(unit,'("# GENERATOR SETTINGS")')
write(unit,'("HOST_LATTICE # not a setting, just for reference")')
write(unit,'(" ",3(1X,F5.2))') this%host%lat(1,:)
@@ -1002,9 +1001,9 @@ subroutine print_generator_settings(this, file)
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
+ 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")')
@@ -1136,7 +1135,7 @@ subroutine read_generator_settings(this, file)
end select
end do
- close(unit)
+ close(unit)
end subroutine read_generator_settings
!###############################################################################
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
From a43eea109f61df33a2ba44655476e481bd7cec84 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Wed, 18 Dec 2024 06:45:13 +0000
Subject: [PATCH 58/60] Update example
---
example/python_pkg/C_learn/learn.py | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/example/python_pkg/C_learn/learn.py b/example/python_pkg/C_learn/learn.py
index 5514af5b..b840030f 100644
--- a/example/python_pkg/C_learn/learn.py
+++ b/example/python_pkg/C_learn/learn.py
@@ -86,15 +86,15 @@ def process_structure(i, atoms, num_structures_old, calc_params, optimise_struct
if __name__ == "__main__":
calc_params = {
- "model": "medium",
+ "model": "large",
"dispersion": False,
"default_dtype": "float32",
"device": 'cpu'
}
- calc = mace_mp(model="medium", dispersion=False, default_dtype="float32", device='cpu')
+ calc = mace_mp(**calc_params)
crystal_structures = [
- 'orthorhombic', 'diamond',
+ 'orthorhombic', #'diamond',
# 'bct', 'sc',
# 'fcc', 'bcc', 'hcp',
]
@@ -102,7 +102,7 @@ def process_structure(i, atoms, num_structures_old, calc_params, optimise_struct
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]:
+ for a in np.linspace(3.3, 4.3, num=7):
b = a
c = a
atom = build.bulk(
@@ -235,6 +235,7 @@ def process_structure(i, atoms, num_structures_old, calc_params, optimise_struct
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
@@ -253,3 +254,5 @@ def process_structure(i, atoms, num_structures_old, calc_params, optimise_struct
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
From 4cdf115d5d43d6f97037f6cb15c036dc9615eacb Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Wed, 18 Dec 2024 06:55:50 +0000
Subject: [PATCH 59/60] Update version number
---
CITATION.cff | 2 +-
fpm.toml | 2 +-
src/fortran/lib/mod_io_utils.F90 | 2 +-
tools/version_number.py | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/CITATION.cff b/CITATION.cff
index 23772a40..3fffaf8a 100644
--- a/CITATION.cff
+++ b/CITATION.cff
@@ -31,5 +31,5 @@ keywords:
- random structure search
license: GPL-3.0
commit: 696eae36488d0861001597e9aa848968a26cdd85
-version: 0.4.0
+version: 0.5.0
date-released: '2024-10-23'
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/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/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)
From bdf8f8a87dc6efeef312ae776448ec048b3d1ad5 Mon Sep 17 00:00:00 2001
From: Ned Taylor
Date: Wed, 18 Dec 2024 06:57:17 +0000
Subject: [PATCH 60/60] Update CITATION
---
CITATION.cff | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/CITATION.cff b/CITATION.cff
index 3fffaf8a..1d8ceb6d 100644
--- a/CITATION.cff
+++ b/CITATION.cff
@@ -7,7 +7,8 @@ title: >-
minima
message: >-
If you use this software, please cite it using the
- metadata from this file.
+ 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
@@ -30,6 +31,6 @@ keywords:
- structure prediction
- random structure search
license: GPL-3.0
-commit: 696eae36488d0861001597e9aa848968a26cdd85
+commit: 4cdf115d5d43d6f97037f6cb15c036dc9615eacb
version: 0.5.0
-date-released: '2024-10-23'
+date-released: '2024-12-18'