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 @@ [![MIT workflow](https://img.shields.io/badge/License-GPLv3-yellow.svg)](https://www.gnu.org/licenses/gpl-3.0.en.html "View GPLv3 license") [![Latest Release](https://img.shields.io/github/v/release/nedtaylor/RAFFLE?sort=semver)](https://github.com/nedtaylor/RAFFLE/releases "View on GitHub") [![Paper](https://img.shields.io/badge/Paper-Phys_Rev_B-blue.svg)](https://link.aps.org/doi/10.1103/PhysRevLett.132.066201) +[![Documentation Status](https://readthedocs.org/projects/raffle-fortran/badge/?version=latest)](https://raffle-fortran.readthedocs.io/en/latest/?badge=latest) [![FPM](https://img.shields.io/badge/fpm-0.10.1-purple)](https://github.com/fortran-lang/fpm "View Fortran Package Manager") [![CMAKE](https://img.shields.io/badge/cmake-3.27.7-red)](https://github.com/Kitware/CMake/releases/tag/v3.27.7 "View cmake") [![GCC compatibility](https://img.shields.io/badge/gcc-14.1.0-green)](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 @@

- +

[![MIT workflow](https://img.shields.io/badge/License-GPLv3-yellow.svg)](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 @@

[![MIT workflow](https://img.shields.io/badge/License-GPLv3-yellow.svg)](https://www.gnu.org/licenses/gpl-3.0.en.html "View GPLv3 license") -[![Latest Release](https://img.shields.io/github/v/release/nedtaylor/RAFFLE?sort=semver)](https://github.com/nedtaylor/RAFFLE/releases "View on GitHub") +[![Latest Release](https://img.shields.io/github/v/release/ExeQuantCode/RAFFLE?sort=semver)](https://github.com/ExeQuantCode/RAFFLE/releases "View on GitHub") [![Paper](https://img.shields.io/badge/Paper-Phys_Rev_B-blue.svg)](https://link.aps.org/doi/10.1103/PhysRevLett.132.066201) [![Documentation Status](https://readthedocs.org/projects/raffle-fortran/badge/?version=latest)](https://raffle-fortran.readthedocs.io/en/latest/?badge=latest) [![FPM](https://img.shields.io/badge/fpm-0.10.1-purple)](https://github.com/fortran-lang/fpm "View Fortran Package Manager") [![CMAKE](https://img.shields.io/badge/cmake-3.27.7-red)](https://github.com/Kitware/CMake/releases/tag/v3.27.7 "View cmake") [![GCC compatibility](https://img.shields.io/badge/gcc-14.1.0-green)](https://gcc.gnu.org/gcc-14/ "View GCC") -[![Coverage](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/nedtaylor/48f14ebb5636b54d3813e4b4494903eb/raw/raffle_coverage_main.json)](https://nedtaylor.github.io/RAFFLE/ "View coverage report") +[![Coverage](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/nedtaylor/48f14ebb5636b54d3813e4b4494903eb/raw/raffle_coverage_main.json)](https://ExeQuantCode.github.io/RAFFLE/ "View coverage report") +[![ReadTheDocs](https://img.shields.io/readthedocs/raffle-fortran)](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 @@ [![MIT workflow](https://img.shields.io/badge/License-GPLv3-yellow.svg)](https://www.gnu.org/licenses/gpl-3.0.en.html "View GPLv3 license") [![Latest Release](https://img.shields.io/github/v/release/ExeQuantCode/RAFFLE?sort=semver)](https://github.com/ExeQuantCode/RAFFLE/releases "View on GitHub") [![Paper](https://img.shields.io/badge/Paper-Phys_Rev_B-blue.svg)](https://link.aps.org/doi/10.1103/PhysRevLett.132.066201) -[![Documentation Status](https://readthedocs.org/projects/raffle-fortran/badge/?version=latest)](https://raffle-fortran.readthedocs.io/en/latest/?badge=latest) +[![Documentation Status](https://readthedocs.org/projects/raffle-fortran/badge/?version=latest)](https://raffle-fortran.readthedocs.io/en/latest/?badge=latest "RAFFLE ReadTheDocs") [![FPM](https://img.shields.io/badge/fpm-0.10.1-purple)](https://github.com/fortran-lang/fpm "View Fortran Package Manager") [![CMAKE](https://img.shields.io/badge/cmake-3.27.7-red)](https://github.com/Kitware/CMake/releases/tag/v3.27.7 "View cmake") [![GCC compatibility](https://img.shields.io/badge/gcc-14.1.0-green)](https://gcc.gnu.org/gcc-14/ "View GCC") [![Coverage](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/nedtaylor/48f14ebb5636b54d3813e4b4494903eb/raw/raffle_coverage_main.json)](https://ExeQuantCode.github.io/RAFFLE/ "View coverage report") -[![ReadTheDocs](https://img.shields.io/readthedocs/raffle-fortran)](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 @@

-[![MIT workflow](https://img.shields.io/badge/License-GPLv3-yellow.svg)](https://www.gnu.org/licenses/gpl-3.0.en.html "View GPLv3 license") +[![GPLv3 workflow](https://img.shields.io/badge/License-GPLv3-yellow.svg)](https://www.gnu.org/licenses/gpl-3.0.en.html "View GPLv3 license") [![Latest Release](https://img.shields.io/github/v/release/ExeQuantCode/RAFFLE?sort=semver)](https://github.com/ExeQuantCode/RAFFLE/releases "View on GitHub") [![Paper](https://img.shields.io/badge/Paper-Phys_Rev_B-blue.svg)](https://link.aps.org/doi/10.1103/PhysRevLett.132.066201) [![Documentation Status](https://readthedocs.org/projects/raffle-fortran/badge/?version=latest)](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'