├── MANIFEST.in
├── example
├── python_pkg
│ ├── requirements.txt
│ ├── visualisation
│ │ ├── host.traj
│ │ ├── converted_db.traj
│ │ ├── POSCAR_AB_stack
│ │ ├── POSCAR_lonsdaleite
│ │ ├── POSCAR_AA_stack
│ │ ├── POSCAR_diamond
│ │ ├── POSCAR_ABC_stack
│ │ ├── POSCAR_ABA_stack
│ │ ├── POSCAR_AABBCC_stack
│ │ └── POSCAR_ABAB_stack
│ ├── agox_runs
│ │ ├── Si-Ge_run
│ │ │ ├── host.traj
│ │ │ └── tidy.py
│ │ ├── n-body_run
│ │ │ └── tidy.py
│ │ └── graphene_grain_boundary_run
│ │ │ └── tidy.py
│ ├── C_learn
│ │ ├── DRSS
│ │ │ ├── DOutput
│ │ │ │ ├── rlxd_structures_seed0.traj
│ │ │ │ └── unrlxd_structures_seed0.traj
│ │ │ └── rss.py
│ │ ├── DRAFFLE
│ │ │ └── DOutput
│ │ │ │ ├── rlxd_structures_seed0.traj
│ │ │ │ ├── rlxd_structures_seed1.traj
│ │ │ │ ├── rlxd_structures_seed2.traj
│ │ │ │ ├── rlxd_structures_seed3.traj
│ │ │ │ ├── rlxd_structures_seed4.traj
│ │ │ │ ├── rlxd_structures_seed5.traj
│ │ │ │ ├── rlxd_structures_seed6.traj
│ │ │ │ ├── rlxd_structures_seed7.traj
│ │ │ │ ├── rlxd_structures_seed8.traj
│ │ │ │ ├── rlxd_structures_seed9.traj
│ │ │ │ ├── rlxd_structures_seed10.traj
│ │ │ │ ├── rlxd_structures_seed11.traj
│ │ │ │ ├── rlxd_structures_seed12.traj
│ │ │ │ ├── rlxd_structures_seed13.traj
│ │ │ │ ├── rlxd_structures_seed14.traj
│ │ │ │ ├── rlxd_structures_seed15.traj
│ │ │ │ ├── rlxd_structures_seed16.traj
│ │ │ │ ├── rlxd_structures_seed17.traj
│ │ │ │ ├── rlxd_structures_seed18.traj
│ │ │ │ ├── rlxd_structures_seed19.traj
│ │ │ │ ├── unrlxd_structures_seed0.traj
│ │ │ │ ├── unrlxd_structures_seed1.traj
│ │ │ │ ├── unrlxd_structures_seed2.traj
│ │ │ │ ├── unrlxd_structures_seed3.traj
│ │ │ │ ├── unrlxd_structures_seed4.traj
│ │ │ │ ├── unrlxd_structures_seed5.traj
│ │ │ │ ├── unrlxd_structures_seed6.traj
│ │ │ │ ├── unrlxd_structures_seed7.traj
│ │ │ │ ├── unrlxd_structures_seed8.traj
│ │ │ │ ├── unrlxd_structures_seed9.traj
│ │ │ │ ├── unrlxd_structures_seed10.traj
│ │ │ │ ├── unrlxd_structures_seed11.traj
│ │ │ │ ├── unrlxd_structures_seed12.traj
│ │ │ │ ├── unrlxd_structures_seed13.traj
│ │ │ │ ├── unrlxd_structures_seed14.traj
│ │ │ │ ├── unrlxd_structures_seed15.traj
│ │ │ │ ├── unrlxd_structures_seed16.traj
│ │ │ │ ├── unrlxd_structures_seed17.traj
│ │ │ │ ├── unrlxd_structures_seed18.traj
│ │ │ │ └── unrlxd_structures_seed19.traj
│ │ └── Dgraphite_diamond
│ │ │ ├── DOutput
│ │ │ ├── rlxd_structures_seed0.traj
│ │ │ └── unrlxd_structures_seed0.traj
│ │ │ └── graphite.vasp
│ ├── Al_learn
│ │ ├── DRSS
│ │ │ └── DOutput
│ │ │ │ ├── rlxd_structures_seed0.traj
│ │ │ │ └── unrlxd_structures_seed0.traj
│ │ ├── DRAFFLE
│ │ │ ├── DOutput
│ │ │ │ ├── rlxd_structures_seed0.traj
│ │ │ │ └── unrlxd_structures_seed0.traj
│ │ │ └── DOutput_placements
│ │ │ │ ├── method_v0.0_r0.0_w0.0_g0.0_m1.0
│ │ │ │ ├── rlxd_structures_seed0.traj
│ │ │ │ └── unrlxd_structures_seed0.traj
│ │ │ │ ├── method_v0.0_r0.0_w0.0_g1.0_m0.0
│ │ │ │ ├── rlxd_structures_seed0.traj
│ │ │ │ └── unrlxd_structures_seed0.traj
│ │ │ │ ├── method_v0.0_r0.0_w1.0_g0.0_m0.0
│ │ │ │ ├── rlxd_structures_seed0.traj
│ │ │ │ └── unrlxd_structures_seed0.traj
│ │ │ │ ├── method_v0.0_r1.0_w0.0_g0.0_m0.0
│ │ │ │ ├── rlxd_structures_seed0.traj
│ │ │ │ └── unrlxd_structures_seed0.traj
│ │ │ │ ├── method_v1.0_r0.0_w0.0_g0.0_m0.0
│ │ │ │ ├── rlxd_structures_seed0.traj
│ │ │ │ └── unrlxd_structures_seed0.traj
│ │ │ │ ├── method_v0.0_r15.0_w0.0_g0.0_m85.0
│ │ │ │ ├── rlxd_structures_seed0.traj
│ │ │ │ └── unrlxd_structures_seed0.traj
│ │ │ │ ├── method_v0.0_r15.0_w0.0_g85.0_m0.0
│ │ │ │ ├── rlxd_structures_seed0.traj
│ │ │ │ └── unrlxd_structures_seed0.traj
│ │ │ │ ├── method_v0.0_r15.0_w85.0_g0.0_m0.0
│ │ │ │ ├── rlxd_structures_seed0.traj
│ │ │ │ └── unrlxd_structures_seed0.traj
│ │ │ │ └── method_v85.0_r15.0_w0.0_g0.0_m0.0
│ │ │ │ ├── rlxd_structures_seed0.traj
│ │ │ │ └── unrlxd_structures_seed0.traj
│ │ └── known_phases
│ │ │ ├── mp-998860.vasp
│ │ │ ├── mp-134.vasp
│ │ │ ├── mp-2647008.vasp
│ │ │ └── mp-1183144.vasp
│ ├── MoS2_learn
│ │ ├── DRSS
│ │ │ └── DOutput
│ │ │ │ ├── rlxd_structures_seed0.traj
│ │ │ │ └── unrlxd_structures_seed0.traj
│ │ ├── DRAFFLE
│ │ │ ├── DOutput
│ │ │ │ ├── rlxd_structures_seed0.traj
│ │ │ │ └── unrlxd_structures_seed0.traj
│ │ │ └── DOutput_CHGNet-DFTD4
│ │ │ │ ├── rlxd_structures_seed0.traj
│ │ │ │ └── unrlxd_structures_seed0.traj
│ │ ├── MoS2_H-phase.poscar
│ │ ├── MoS2_T-phase.poscar
│ │ └── Mo.poscar
│ ├── Si-Ge_learn
│ │ ├── DRAFFLE
│ │ │ ├── DOutput
│ │ │ │ ├── rlxd_structures_seed2.traj
│ │ │ │ └── unrlxd_structures_seed2.traj
│ │ │ └── DOutput_CHGNet
│ │ │ │ ├── rlxd_structures_seed0.traj
│ │ │ │ └── unrlxd_structures_seed0.traj
│ │ ├── abrupt_shifts.py
│ │ ├── Ge_slab.vasp
│ │ └── Si_slab.vasp
│ ├── ScS2-Li_learn
│ │ ├── DRAFFLE
│ │ │ └── DOutput
│ │ │ │ ├── rlxd_structures_seed0.traj
│ │ │ │ └── unrlxd_structures_seed0.traj
│ │ ├── Li.xyz
│ │ └── ScS2.vasp
│ ├── graphene_grain_boundary_learn
│ │ ├── DRSS
│ │ │ └── DOutput
│ │ │ │ ├── rlxd_structures_seed42.traj
│ │ │ │ └── unrlxd_structures_seed42.traj
│ │ ├── DRAFFLE
│ │ │ └── DOutput
│ │ │ │ ├── rlxd_structures_seed0_combined.traj
│ │ │ │ └── unrlxd_structures_seed0_combined.traj
│ │ └── POSCAR_graphene
│ ├── .gitattributes
│ ├── graphite
│ │ ├── POSCAR_host_missing_layer
│ │ ├── POSCAR_host_graphene
│ │ └── POSCAR_host_graphite_vacancy
│ ├── diamond
│ │ ├── POSCAR_host
│ │ └── POSCAR_host_3x3
│ ├── perovskites
│ │ └── database.xyz
│ ├── README.md
│ └── benchmarks
│ │ ├── min_placement.py
│ │ ├── placement_methods.py
│ │ └── create_gdfs.py
├── fortran_exe
│ ├── run.sh
│ └── param.in
└── data
│ └── C-MgO_hosts
│ ├── POSCAR_1x1_5.4A_separation
│ ├── POSCAR_2x2_5.4A_separation
│ ├── POSCAR_5x1_5.4A_separation
│ ├── POSCAR_3x3_11.0A_separation
│ ├── POSCAR_3x3_5.4A_separation
│ ├── POSCAR_1x5_orthorhombic_11.0A_separation
│ ├── POSCAR_orthorhombic_11.1A_separation_Mg_seeded
│ ├── POSCAR_4x4_11.0A_separation
│ └── POSCAR_4x4_14.7A_separation
├── docs
├── source
│ ├── RAFFLE_logo.pdf
│ ├── RAFFLE_logo_no_background.png
│ ├── raffle.geom.rst
│ ├── raffle.generator.rst
│ ├── raffle.geom_rw_class.rst
│ ├── raffle.generator_class.rst
│ ├── raffle.distributions.rst
│ ├── raffle.distributions_class.rst
│ ├── raffle.geom_module.rst
│ ├── about.rst
│ ├── references.bib
│ ├── raffle.generator_module.rst
│ ├── tutorials
│ │ ├── index.rst
│ │ ├── aluminium_tutorial.rst
│ │ ├── quick_guide.rst
│ │ ├── host_tutorial.rst
│ │ └── generating_tutorial.rst
│ ├── modules.rst
│ ├── conf.py
│ └── index.rst
├── requirements.txt
├── Makefile
├── make.bat
└── RAFFLE.bib
├── src
├── wrapper
│ └── f90wrap_raffle.f90
├── fortran
│ ├── raffle.f90
│ └── lib
│ │ ├── mod_constants.f90
│ │ ├── mod_cache.f90
│ │ ├── mod_io_utils.F90
│ │ └── mod_misc_maths.f90
└── raffle
│ └── __init__.py
├── tools
├── .gitattributes
├── coverage_badge.py
├── version_number.py
├── check_accuracy_C-MgO.py
├── database.py
├── visualise_evaluator.py
├── check_accuracy_C-Li.py
├── check_accuracy_C.py
├── check_accuracy_MoS2.py
├── check_accuracy_Al.py
├── database.ipynb
└── check_accuracy_ScS2-Li.py
├── test
├── data
│ └── POSCAR_Si
├── CMakeLists.txt
├── test_io_utils.f90
├── test_tools_infile.f90
├── test_cache.f90
└── test_misc_maths.f90
├── .pre-commit-config.yaml
├── conftest.py
├── kind_map
├── fpm.toml
├── .github
├── PULL_REQUEST_TEMPLATE
│ └── pull_request_template.md
├── ISSUE_TEMPLATE
│ ├── feature_request.yaml
│ └── bug_report.yaml
└── workflows
│ ├── python.yml
│ ├── fpm.yml
│ └── coverage.yml
├── ford.md
├── .gitignore
├── .readthedocs.yaml
├── CITATION.cff
├── pyproject.toml
└── CODE_OF_CONDUCT.md
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include src/raffle/*.py
2 |
--------------------------------------------------------------------------------
/example/python_pkg/requirements.txt:
--------------------------------------------------------------------------------
1 | mace-torch==0.3.12
2 | chgnet==0.4.0
3 | joblib==1.4.2
4 |
--------------------------------------------------------------------------------
/example/fortran_exe/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | $HOME/.local/raffle/bin/raffle_executable -f param.in
4 |
--------------------------------------------------------------------------------
/docs/source/RAFFLE_logo.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/docs/source/RAFFLE_logo.pdf
--------------------------------------------------------------------------------
/docs/requirements.txt:
--------------------------------------------------------------------------------
1 | sphinx==8.1.3
2 | sphinx-rtd-theme==3.0.2
3 | sphinxcontrib-bibtex==2.6.3
4 | f90wrap==0.2.16
5 |
--------------------------------------------------------------------------------
/docs/source/RAFFLE_logo_no_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/docs/source/RAFFLE_logo_no_background.png
--------------------------------------------------------------------------------
/example/python_pkg/visualisation/host.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/visualisation/host.traj
--------------------------------------------------------------------------------
/src/wrapper/f90wrap_raffle.f90:
--------------------------------------------------------------------------------
1 | ! Module raffle defined in file ../raffle.f90
2 |
3 | ! End of module raffle defined in file ../raffle.f90
4 |
5 |
--------------------------------------------------------------------------------
/example/python_pkg/agox_runs/Si-Ge_run/host.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/agox_runs/Si-Ge_run/host.traj
--------------------------------------------------------------------------------
/example/python_pkg/visualisation/converted_db.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/visualisation/converted_db.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRSS/DOutput/rlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRSS/DOutput/rlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/Al_learn/DRSS/DOutput/rlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/Al_learn/DRSS/DOutput/rlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/Al_learn/DRSS/DOutput/unrlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/Al_learn/DRSS/DOutput/unrlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed1.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed1.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed2.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed2.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed3.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed3.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed4.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed4.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed5.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed5.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed6.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed6.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed7.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed7.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed8.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed8.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed9.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed9.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRSS/DOutput/unrlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRSS/DOutput/unrlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/MoS2_learn/DRSS/DOutput/rlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/MoS2_learn/DRSS/DOutput/rlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/Al_learn/DRAFFLE/DOutput/rlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/Al_learn/DRAFFLE/DOutput/rlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed10.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed10.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed11.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed11.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed12.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed12.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed13.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed13.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed14.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed14.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed15.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed15.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed16.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed16.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed17.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed17.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed18.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed18.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed19.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/rlxd_structures_seed19.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed1.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed1.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed2.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed2.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed3.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed3.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed4.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed4.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed5.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed5.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed6.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed6.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed7.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed7.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed8.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed8.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed9.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed9.traj
--------------------------------------------------------------------------------
/example/python_pkg/MoS2_learn/DRSS/DOutput/unrlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/MoS2_learn/DRSS/DOutput/unrlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/Al_learn/DRAFFLE/DOutput/unrlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/Al_learn/DRAFFLE/DOutput/unrlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed10.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed10.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed11.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed11.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed12.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed12.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed13.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed13.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed14.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed14.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed15.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed15.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed16.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed16.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed17.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed17.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed18.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed18.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed19.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/DRAFFLE/DOutput/unrlxd_structures_seed19.traj
--------------------------------------------------------------------------------
/example/python_pkg/MoS2_learn/DRAFFLE/DOutput/rlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/MoS2_learn/DRAFFLE/DOutput/rlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/MoS2_learn/DRAFFLE/DOutput/unrlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/MoS2_learn/DRAFFLE/DOutput/unrlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/Si-Ge_learn/DRAFFLE/DOutput/rlxd_structures_seed2.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/Si-Ge_learn/DRAFFLE/DOutput/rlxd_structures_seed2.traj
--------------------------------------------------------------------------------
/example/python_pkg/ScS2-Li_learn/DRAFFLE/DOutput/rlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/ScS2-Li_learn/DRAFFLE/DOutput/rlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/Si-Ge_learn/DRAFFLE/DOutput/unrlxd_structures_seed2.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/Si-Ge_learn/DRAFFLE/DOutput/unrlxd_structures_seed2.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/Dgraphite_diamond/DOutput/rlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/Dgraphite_diamond/DOutput/rlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/ScS2-Li_learn/DRAFFLE/DOutput/unrlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/ScS2-Li_learn/DRAFFLE/DOutput/unrlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/Dgraphite_diamond/DOutput/unrlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/C_learn/Dgraphite_diamond/DOutput/unrlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/Si-Ge_learn/DRAFFLE/DOutput_CHGNet/rlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/Si-Ge_learn/DRAFFLE/DOutput_CHGNet/rlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/Si-Ge_learn/DRAFFLE/DOutput_CHGNet/unrlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/Si-Ge_learn/DRAFFLE/DOutput_CHGNet/unrlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/MoS2_learn/DRAFFLE/DOutput_CHGNet-DFTD4/rlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/MoS2_learn/DRAFFLE/DOutput_CHGNet-DFTD4/rlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/MoS2_learn/DRAFFLE/DOutput_CHGNet-DFTD4/unrlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/MoS2_learn/DRAFFLE/DOutput_CHGNet-DFTD4/unrlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/graphene_grain_boundary_learn/DRSS/DOutput/rlxd_structures_seed42.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/graphene_grain_boundary_learn/DRSS/DOutput/rlxd_structures_seed42.traj
--------------------------------------------------------------------------------
/example/python_pkg/graphene_grain_boundary_learn/DRSS/DOutput/unrlxd_structures_seed42.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/graphene_grain_boundary_learn/DRSS/DOutput/unrlxd_structures_seed42.traj
--------------------------------------------------------------------------------
/tools/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto-remove output from Jupyter notebooks
2 | # Follow the guide from this link to set up the filter:
3 | # https://gist.github.com/33eyes/431e3d432f73371509d176d0dfb95b6e
4 | *.ipynb filter=strip-notebook-output
--------------------------------------------------------------------------------
/example/python_pkg/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto-remove output from Jupyter notebooks
2 | # Follow the guide from this link to set up the filter:
3 | # https://gist.github.com/33eyes/431e3d432f73371509d176d0dfb95b6e
4 | *.ipynb filter=strip-notebook-output
--------------------------------------------------------------------------------
/example/python_pkg/Al_learn/known_phases/mp-998860.vasp:
--------------------------------------------------------------------------------
1 | Al mp-998860
2 | 1.0
3 | 3.182437 0.000000 0.000000
4 | -0.000000 3.182437 0.000000
5 | 0.000000 0.000000 3.182437
6 | Al
7 | 2
8 | direct
9 | 0.0 0.0 0.0
10 | 0.5 0.5 0.5
11 |
--------------------------------------------------------------------------------
/example/python_pkg/graphene_grain_boundary_learn/DRAFFLE/DOutput/rlxd_structures_seed0_combined.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/graphene_grain_boundary_learn/DRAFFLE/DOutput/rlxd_structures_seed0_combined.traj
--------------------------------------------------------------------------------
/example/python_pkg/graphene_grain_boundary_learn/DRAFFLE/DOutput/unrlxd_structures_seed0_combined.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/graphene_grain_boundary_learn/DRAFFLE/DOutput/unrlxd_structures_seed0_combined.traj
--------------------------------------------------------------------------------
/example/python_pkg/Al_learn/known_phases/mp-134.vasp:
--------------------------------------------------------------------------------
1 | Al mp-134
2 | 1.0
3 | 4.03893 0.00000 0.00000
4 | 0.00000 4.03893 0.00000
5 | 0.00000 0.00000 4.03893
6 | Al
7 | 4
8 | direct
9 | 0.0 0.0 0.0
10 | 0.0 0.5 0.5
11 | 0.5 0.0 0.5
12 | 0.5 0.5 0.0
13 |
--------------------------------------------------------------------------------
/example/python_pkg/Al_learn/known_phases/mp-2647008.vasp:
--------------------------------------------------------------------------------
1 | Al mp-2647008
2 | 1.0
3 | 1.4062277 -2.4356578 0.00000
4 | 1.4062277 2.4356578 0.00000
5 | 0.0000000 0.0000000 4.86685
6 | Al
7 | 2
8 | direct
9 | 0.6666667 0.3333333 0.75
10 | 0.3333333 0.6666667 0.25
11 |
--------------------------------------------------------------------------------
/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r0.0_w0.0_g0.0_m1.0/rlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r0.0_w0.0_g0.0_m1.0/rlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r0.0_w0.0_g1.0_m0.0/rlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r0.0_w0.0_g1.0_m0.0/rlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r0.0_w1.0_g0.0_m0.0/rlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r0.0_w1.0_g0.0_m0.0/rlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r1.0_w0.0_g0.0_m0.0/rlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r1.0_w0.0_g0.0_m0.0/rlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v1.0_r0.0_w0.0_g0.0_m0.0/rlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v1.0_r0.0_w0.0_g0.0_m0.0/rlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r0.0_w0.0_g0.0_m1.0/unrlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r0.0_w0.0_g0.0_m1.0/unrlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r0.0_w0.0_g1.0_m0.0/unrlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r0.0_w0.0_g1.0_m0.0/unrlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r0.0_w1.0_g0.0_m0.0/unrlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r0.0_w1.0_g0.0_m0.0/unrlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r1.0_w0.0_g0.0_m0.0/unrlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r1.0_w0.0_g0.0_m0.0/unrlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r15.0_w0.0_g0.0_m85.0/rlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r15.0_w0.0_g0.0_m85.0/rlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r15.0_w0.0_g85.0_m0.0/rlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r15.0_w0.0_g85.0_m0.0/rlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r15.0_w85.0_g0.0_m0.0/rlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r15.0_w85.0_g0.0_m0.0/rlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v1.0_r0.0_w0.0_g0.0_m0.0/unrlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v1.0_r0.0_w0.0_g0.0_m0.0/unrlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v85.0_r15.0_w0.0_g0.0_m0.0/rlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v85.0_r15.0_w0.0_g0.0_m0.0/rlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r15.0_w0.0_g0.0_m85.0/unrlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r15.0_w0.0_g0.0_m85.0/unrlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r15.0_w0.0_g85.0_m0.0/unrlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r15.0_w0.0_g85.0_m0.0/unrlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r15.0_w85.0_g0.0_m0.0/unrlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v0.0_r15.0_w85.0_g0.0_m0.0/unrlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v85.0_r15.0_w0.0_g0.0_m0.0/unrlxd_structures_seed0.traj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExeQuantCode/RAFFLE/HEAD/example/python_pkg/Al_learn/DRAFFLE/DOutput_placements/method_v85.0_r15.0_w0.0_g0.0_m0.0/unrlxd_structures_seed0.traj
--------------------------------------------------------------------------------
/docs/source/raffle.geom.rst:
--------------------------------------------------------------------------------
1 | raffle.geom_rw module
2 | =======================
3 |
4 | .. .. automodule:: raffle.Geom_Rw
5 | .. :members:
6 | .. :undoc-members:
7 | .. :show-inheritance:
8 |
9 | .. autoclass:: raffle.Geom_Rw
10 | :members:
11 | :undoc-members:
12 | :show-inheritance:
13 |
--------------------------------------------------------------------------------
/test/data/POSCAR_Si:
--------------------------------------------------------------------------------
1 | Si
2 | 5.44
3 | 1.00 0.00 0.00
4 | 0.00 1.00 0.00
5 | 0.00 0.00 1.00
6 | Si
7 | 8
8 | direct
9 | 0.75 0.75 0.25
10 | 0.00 0.50 0.50
11 | 0.75 0.25 0.75
12 | 0.00 0.00 0.00
13 | 0.25 0.75 0.75
14 | 0.50 0.50 0.00
15 | 0.25 0.25 0.25
16 | 0.50 0.00 0.50
17 |
--------------------------------------------------------------------------------
/docs/source/raffle.generator.rst:
--------------------------------------------------------------------------------
1 | raffle.generator module
2 | =======================
3 |
4 | .. .. automodule:: raffle.Generator
5 | .. :members:
6 | .. :undoc-members:
7 | .. :show-inheritance:
8 |
9 |
10 | .. autoclass:: raffle.Generator
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
--------------------------------------------------------------------------------
/docs/source/raffle.geom_rw_class.rst:
--------------------------------------------------------------------------------
1 | raffle.Geom_Rw Class
2 | =======================
3 |
4 | .. .. automodule:: raffle.Geom_Rw
5 | .. :members:
6 | .. :undoc-members:
7 | .. :show-inheritance:
8 |
9 | .. autoclass:: raffle.raffle.Geom_Rw
10 | :members:
11 | :undoc-members:
12 | :show-inheritance:
13 |
--------------------------------------------------------------------------------
/docs/source/raffle.generator_class.rst:
--------------------------------------------------------------------------------
1 | raffle.Generator Class
2 | =======================
3 |
4 | .. .. automodule:: raffle.Generator
5 | .. :members:
6 | .. :undoc-members:
7 | .. :show-inheritance:
8 |
9 | .. autoclass:: raffle.raffle.Generator
10 | :members:
11 | :undoc-members:
12 | :show-inheritance:
--------------------------------------------------------------------------------
/example/python_pkg/Al_learn/known_phases/mp-1183144.vasp:
--------------------------------------------------------------------------------
1 | Al mp-1183144
2 | 1.0
3 | 1.413539 -2.448321 0.000000
4 | 1.413539 2.448321 0.000000
5 | 0.000000 0.000000 9.185993
6 | Al
7 | 4
8 | direct
9 | 0.0000000 0.0000000 0.00
10 | 0.3333333 0.6666666 0.25
11 | 0.0000000 0.0000000 0.50
12 | 0.6666666 0.3333333 0.75
13 |
--------------------------------------------------------------------------------
/docs/source/raffle.distributions.rst:
--------------------------------------------------------------------------------
1 | raffle.distributions module
2 | ===========================
3 |
4 | .. .. automodule:: raffle.Raffle__Distribs_Container
5 | .. :members:
6 | .. :undoc-members:
7 | .. :show-inheritance:
8 |
9 | .. autoclass:: raffle.Raffle__Distribs_Container
10 | :members:
11 | :undoc-members:
12 | :show-inheritance:
13 |
--------------------------------------------------------------------------------
/docs/source/raffle.distributions_class.rst:
--------------------------------------------------------------------------------
1 | raffle.distributions Class
2 | ===========================
3 |
4 | .. .. automodule:: raffle.Raffle__Distribs_Container
5 | .. :members:
6 | .. :undoc-members:
7 | .. :show-inheritance:
8 |
9 | .. autoclass:: raffle.raffle.Raffle__Distribs_Container
10 | :members:
11 | :undoc-members:
12 | :show-inheritance:
13 |
--------------------------------------------------------------------------------
/example/python_pkg/MoS2_learn/MoS2_H-phase.poscar:
--------------------------------------------------------------------------------
1 | MoS2 H-phase
2 | 1.0
3 | 1.592716 -2.758665 0.000000
4 | 1.592716 2.758665 0.000000
5 | 0.000000 0.000000 13.178390
6 | Mo S
7 | 2 4
8 | direct
9 | 0.000000 0.000000 0.250000
10 | 0.000000 0.000000 0.750000
11 | 0.333333 0.666666 0.367743
12 | 0.666666 0.333333 0.632256
13 | 0.666666 0.333333 0.867743
14 | 0.333333 0.666666 0.132256
--------------------------------------------------------------------------------
/example/python_pkg/MoS2_learn/MoS2_T-phase.poscar:
--------------------------------------------------------------------------------
1 | MoS2 T-phase
2 | 1.0
3 | 1.592716 -2.758665 0.000000
4 | 1.592716 2.758665 0.000000
5 | 0.000000 0.000000 12.62495
6 | Mo S
7 | 2 4
8 | direct
9 | 0.000000 0.000000 0.250000
10 | 0.000000 0.000000 0.750000
11 | 0.333333 0.666666 0.127659
12 | 0.666666 0.333333 0.372341
13 | 0.333333 0.666666 0.627659
14 | 0.666666 0.333333 0.872341
--------------------------------------------------------------------------------
/example/python_pkg/visualisation/POSCAR_AB_stack:
--------------------------------------------------------------------------------
1 | AB stack
2 | 1.0
3 | 0.000000000 4.255049746 0.000000000
4 | 2.456364992 0.000000000 0.000000000
5 | 0.000000000 -1.163571728 -3.507435407
6 | C
7 | 4
8 | direct
9 | 0.833330769 0.000000000 0.999957858
10 | 0.666669230 0.500000000 0.000042141
11 | 0.333330769 0.500000000 0.999957858
12 | 0.166669230 0.000000000 0.000042141
13 |
--------------------------------------------------------------------------------
/example/python_pkg/graphene_grain_boundary_learn/POSCAR_graphene:
--------------------------------------------------------------------------------
1 | C2
2 | 1.0
3 | 1.2336456308015411 -2.1367369110836258 0.0000000000000000
4 | 1.2336456308015411 2.1367369110836258 0.0000000000000000
5 | 0.0000000000000000 0.0000000000000000 10.0
6 | C
7 | 2
8 | direct
9 | 0.0000000000000000 0.0000000000000000 0.2500000000000000 C0+
10 | 0.3333333333333330 0.6666666666666661 0.2500000000000000 C0+
11 |
--------------------------------------------------------------------------------
/example/python_pkg/visualisation/POSCAR_lonsdaleite:
--------------------------------------------------------------------------------
1 | lonsdaleite
2 | 1.0
3 | 1.251651409 -2.167923835 0.000000000
4 | 1.251651409 2.167923835 0.000000000
5 | 0.000000000 0.000000000 4.168968810
6 | C
7 | 4
8 | direct
9 | 0.333333333 0.666666666 0.062805350
10 | 0.666666666 0.333333333 0.562805350
11 | 0.666666666 0.333333333 0.937194650
12 | 0.333333333 0.666666666 0.437194650
13 |
--------------------------------------------------------------------------------
/example/python_pkg/visualisation/POSCAR_AA_stack:
--------------------------------------------------------------------------------
1 | AA stack
2 | 1.0
3 | 1.2279976842911540 -2.1269543807692060 0.0000000000000000
4 | 1.2279976842911540 2.1269543807692060 0.0000000000000000
5 | 0.0000000000000000 0.0000000000000000 3.6596614593024759
6 | C
7 | 2
8 | direct
9 | 0.3333333333333330 0.6666666666666661 0.0000000000000000 C0+
10 | 0.6666666666666661 0.3333333333333330 0.0000000000000000 C0+
11 |
--------------------------------------------------------------------------------
/example/python_pkg/visualisation/POSCAR_diamond:
--------------------------------------------------------------------------------
1 | diamond
2 | 1.0
3 | 3.560745109 0.000000000 0.000000000
4 | -0.000000000 3.560745109 0.000000000
5 | 0.000000000 0.000000000 3.560745109
6 | C
7 | 8
8 | direct
9 | 0.00 0.00 0.50
10 | 0.25 0.25 0.75
11 | 0.00 0.50 0.00
12 | 0.25 0.75 0.25
13 | 0.50 0.00 0.00
14 | 0.75 0.25 0.25
15 | 0.50 0.50 0.50
16 | 0.75 0.75 0.75
17 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | repos:
2 | - repo: https://github.com/pre-commit/pre-commit-hooks
3 | rev: v5.0.0 # Use the ref you want to point at
4 | hooks:
5 | - id: trailing-whitespace
6 | - id: end-of-file-fixer
7 | - repo: https://github.com/nedtaylor/fortran-format-hooks
8 | rev: 749c61fce3a5f29f6d5d3b236ed9b693c6b2bf4e
9 | hooks:
10 | - id: check-fortran-indentation
11 | args: [--line-length=80, --ignore-directories=src/wrapper]
12 |
--------------------------------------------------------------------------------
/conftest.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | def pytest_addoption(parser):
4 | parser.addoption(
5 | "--fortran-compiler",
6 | action="store",
7 | default="gfortran", # Default compiler
8 | help="Specify the Fortran compiler to use"
9 | )
10 |
11 | def pytest_configure(config):
12 | # Make the Fortran compiler available globally during tests
13 | compiler = config.getoption("--fortran-compiler")
14 | os.environ["FORTRAN_COMPILER"] = compiler
--------------------------------------------------------------------------------
/example/python_pkg/MoS2_learn/Mo.poscar:
--------------------------------------------------------------------------------
1 | Mo2
2 | 1.00000000000000
3 | 3.1229640216873942 -0.0000000000000000 -0.0000000000000000
4 | 0.0000000000000000 3.1229640216873942 -0.0000000000000000
5 | 0.0000000000000000 0.0000000000000000 3.1229640216873942
6 | Mo
7 | 2
8 | Direct
9 | 0.0000000000000000 0.0000000000000000 0.0000000000000000
10 | 0.5000000000000000 0.5000000000000000 0.5000000000000000
11 |
--------------------------------------------------------------------------------
/example/python_pkg/ScS2-Li_learn/Li.xyz:
--------------------------------------------------------------------------------
1 | 2
2 | Lattice="3.35384128 0.0 0.0 0.0 3.35384128 0.0 0.0 0.0 3.35384128" Properties=species:S:1:pos:R:3:forces:R:3 energy=-7.55514851 stress="-0.0005756199522743655 0.0 -0.0 0.0 -0.0005756199522743655 -0.0 -0.0 -0.0 -0.0005756199522743655" free_energy=-7.55531811 pbc="T T T"
3 | Li 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000
4 | Li 1.67692064 1.67692064 1.67692064 0.00000000 0.00000000 0.00000000
5 |
--------------------------------------------------------------------------------
/src/fortran/raffle.f90:
--------------------------------------------------------------------------------
1 | module raffle
2 | use raffle__constants, only: real32
3 | use raffle__io_utils, only: raffle__version__
4 | use raffle__generator, only: raffle_generator_type
5 | use raffle__distribs_container, only: distribs_container_type
6 | use raffle__cache, only: &
7 | store_probability_density, retrieve_probability_density
8 | implicit none
9 |
10 |
11 | private
12 | public :: real32
13 | public :: distribs_container_type
14 | public :: raffle_generator_type
15 |
16 |
17 | end module raffle
18 |
--------------------------------------------------------------------------------
/example/python_pkg/graphite/POSCAR_host_missing_layer:
--------------------------------------------------------------------------------
1 | C
2 | 1.000000000
3 | 1.233645631 -2.136736911 0.000000000
4 | 1.233645631 2.136736911 0.000000000
5 | 0.000000000 0.000000000 15.606146000
6 | C
7 | 6
8 | Direct
9 | 0.000000000 0.000000000 0.125000000
10 | 0.000000000 0.000000000 0.375000000
11 | 0.000000000 0.000000000 0.875000000
12 | 0.333333333 0.666666667 0.125000000
13 | 0.666666667 0.333333333 0.375000000
14 | 0.666666667 0.333333333 0.875000000
15 |
16 |
--------------------------------------------------------------------------------
/kind_map:
--------------------------------------------------------------------------------
1 | {
2 | 'real': {'': 'float',
3 | '4': 'float',
4 | '8': 'double',
5 | 'dp': 'double',
6 | 'idp':'double',
7 | 'real32': 'float'},
8 | 'complex' : {'': 'complex_float',
9 | '8' : 'complex_double',
10 | '16': 'complex_long_double',
11 | 'dp': 'complex_double',
12 | 'real32': 'complex_float'},
13 | 'integer' : {'' : 'int',
14 | '4': 'int',
15 | '8': 'long_long',
16 | 'dp': 'long_long',
17 | 'quadint_k': 'long_long'}
18 | }
--------------------------------------------------------------------------------
/example/python_pkg/ScS2-Li_learn/ScS2.vasp:
--------------------------------------------------------------------------------
1 | ScS2
2 | 1.00000000000000
3 | 3.4373550228202143 1.2722491953399284 -0.0985749251780342
4 | 0.6164998078516010 3.5730165704323316 -0.5636062457623744
5 | -0.1941735091202983 0.9816038800609169 6.1273390509283345
6 | Sc S
7 | 1 2
8 | Direct
9 | 0.6762039103400640 0.1332178797064758 0.9103732174536018
10 | 0.0097462202190008 0.4656228504900874 0.6731159326278954
11 | 0.3427267534832620 0.8007351821914250 0.1476299218798714
12 |
13 |
--------------------------------------------------------------------------------
/fpm.toml:
--------------------------------------------------------------------------------
1 | name = "raffle"
2 | version = "1.1.1"
3 | author = "Ned Thaddeus Taylor"
4 | maintainer = "n.t.taylor@exeter.ac.uk"
5 | description = "A Fortran library and executable for structure prediction at material interfaces"
6 |
7 | [preprocess]
8 | [preprocess.cpp]
9 | suffixes = ["F90", "f90"]
10 |
11 | [library]
12 | source-dir="src/fortran"
13 |
14 | [dependencies]
15 | openmp = "*"
16 |
17 | [fortran]
18 | implicit-typing = false
19 | implicit-external = false
20 | source-form = "free"
21 |
22 | [[executable]]
23 | name="raffle_executable"
24 | source-dir="app"
25 | main="main.f90"
26 |
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/Dgraphite_diamond/graphite.vasp:
--------------------------------------------------------------------------------
1 | C4
2 | 1.0
3 | 0.0000000000000000 4.2546406144450799 0.0000000000000000
4 | 2.4565648800000002 0.0000000000000000 0.0000000000000000
5 | 0.0000000000000000 -1.3790696309310659 -3.5028300786042923
6 | C
7 | 4
8 | direct
9 | 0.1666444699999990 0.0000000000000000 0.9999069600000000 C0+
10 | 0.8333555300000001 0.0000000000000000 0.0000930400000000 C0+
11 | 0.6666444699999990 0.5000000000000000 0.9999069600000000 C0+
12 | 0.3333555300000000 0.5000000000000000 0.0000930400000000 C0+
13 |
--------------------------------------------------------------------------------
/example/python_pkg/diamond/POSCAR_host:
--------------------------------------------------------------------------------
1 | C8
2 | 1.000000000
3 | 3.560745109 0.000000000 0.000000000
4 | 0.000000000 3.560745109 0.000000000
5 | 0.000000000 0.000000000 7.121490218
6 | C
7 | 8
8 | Direct
9 | 0.000000000 0.000000000 0.000000000
10 | 0.500000000 0.500000000 0.000000000
11 | 0.500000000 0.000000000 0.250000000
12 | 0.000000000 0.500000000 0.250000000
13 | 0.250000000 0.250000000 0.125000000
14 | 0.750000000 0.750000000 0.125000000
15 | 0.750000000 0.250000000 0.375000000
16 | 0.250000000 0.750000000 0.375000000
17 |
--------------------------------------------------------------------------------
/example/python_pkg/visualisation/POSCAR_ABC_stack:
--------------------------------------------------------------------------------
1 | ABC stack
2 | 2.4500000000000002
3 | 1.0066380067671441 -0.0000007331712457 0.0000003579759198
4 | -0.5033196383284964 0.8717737197054177 -0.0000003579759198
5 | 0.0000009726444368 -0.0000005615565274 4.0456738842247359
6 | C
7 | 6
8 | Direct
9 | 0.9998104166167796 0.9996664427628408 0.9996638036663712
10 | 0.3331436245480242 0.6663332899081239 0.9997301605660306
11 | 0.3328565033263268 0.6661897228378959 0.3329667808200413
12 | 0.6661897228378950 0.3328565033263259 0.3330332191799555
13 | 0.9996664427628416 0.9998104166167796 0.6663361963336256
14 | 0.6663332899081230 0.3331436245480243 0.6662698394339662
15 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Minimal makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line, and also
5 | # from the environment for the first two.
6 | SPHINXOPTS ?=
7 | SPHINXBUILD ?= python -m sphinx
8 | SOURCEDIR = source
9 | BUILDDIR = build
10 |
11 | # Put it first so that "make" without argument is like "make help".
12 | help:
13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14 |
15 | .PHONY: help Makefile
16 |
17 | # Catch-all target: route all unknown targets to Sphinx using the new
18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19 | %: Makefile
20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
21 |
--------------------------------------------------------------------------------
/src/fortran/lib/mod_constants.f90:
--------------------------------------------------------------------------------
1 | module raffle__constants
2 | !! Module with global constants
3 | !!
4 | !! This module contains global constants that may be used throughout the
5 | !! library.
6 | implicit none
7 | integer, parameter, public :: real32 = Selected_real_kind(6,37)!(15,307)
8 | real(real32), parameter, public :: tau = 8._real32 * atan(1._real32)
9 | real(real32), parameter, public :: pi = 4._real32 * atan(1._real32)
10 | real(real32), parameter, public :: c = 0.26246582250210965422_real32
11 | real(real32), parameter, public :: c_vasp = 0.262465831_real32
12 | real(real32), parameter, public :: INF = huge(0._real32)
13 | complex(real32), parameter, public :: imag=(0._real32, 1._real32)
14 | end module raffle__constants
15 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md:
--------------------------------------------------------------------------------
1 | # Description
2 |
3 | > _Briefly describe the purpose and content of this merge request._
4 | > _E.g. "Add structure generation constraints", or "Fix bug in energy parsing"._
5 |
6 | # Checklist
7 |
8 | Mark with `x` when complete, or `~` if not applicable.
9 |
10 | - [ ] [I have read and followed the **RAFFLE's contribution guidelines.**](https://github.com/ExeQuantCode/RAFFLE/blob/main/CONTRIBUTING.md)
11 | - [ ] **Code is commented** appropriately, and API docstrings follow NumPy or FORD style.
12 | - [ ] **Read*the*Docs** documentation is added/updated (if applicable).
13 | - [ ] **Unit tests** are added/updated (if applicable).
14 | - [ ] **Linked issue** is resolved with a `closes #XXXX` reference (if applicable).
15 |
--------------------------------------------------------------------------------
/docs/source/raffle.geom_module.rst:
--------------------------------------------------------------------------------
1 | raffle.geom Module
2 | =======================
3 |
4 | This is a simulated module that holds the following class:
5 |
6 | - :class:`raffle.Geom_Rw()`
7 |
8 | This class cannot be directly accessed, but the two user-facing classes within it can be.
9 | Within this class, there exist two directly accessible sub-classes:
10 |
11 | - :class:`raffle.geom.basis()`
12 | - :class:`raffle.geom.basis_array()`
13 |
14 | These are used to handle the geometry of the system, where the former is a single instance of the geometry and the latter is an array of instances.
15 | The documentation for these can be found here: :doc:`raffle.geom_rw_class`.
16 |
17 | .. automodule:: raffle.geom
18 | :members:
19 | :undoc-members:
20 | :show-inheritance:
21 |
--------------------------------------------------------------------------------
/example/python_pkg/visualisation/POSCAR_ABA_stack:
--------------------------------------------------------------------------------
1 | ABA vacuum
2 | 1.0
3 | 1.228124980 -2.127174863 0.000000000
4 | 1.228124980 2.127174863 0.000000000
5 | 0.000000000 0.000000000 29.491878700
6 | C
7 | 12
8 | direct
9 | 0.666666666 0.333333333 0.998371799
10 | 0.666666666 0.333333333 0.498371910
11 | 0.666666666 0.333333333 0.732787949
12 | 0.666666666 0.333333333 0.232790329
13 | 0.000000000 0.000000000 0.615837989
14 | 0.333333333 0.666666666 0.232787949
15 | 0.000000000 0.000000000 0.115837989
16 | 0.666666666 0.333333333 0.615840009
17 | 0.333333333 0.666666666 0.732790329
18 | 0.333333333 0.666666666 0.115840009
19 | 0.333333333 0.666666666 0.498371799
20 | 0.333333333 0.666666666 0.998371910
21 |
--------------------------------------------------------------------------------
/ford.md:
--------------------------------------------------------------------------------
1 | project:
2 | summary: A Fortran library and executable for structure prediction at material interfaces
3 | src_dir: ./src/fortran
4 | ./app
5 | exclude: **/f90wrap_*.f90
6 | output_dir: docs/html
7 | preprocess: false
8 | predocmark: !!
9 | fpp_extensions: f90
10 | F90
11 | display: public
12 | protected
13 | private
14 | source: true
15 | graph: true
16 | md_extensions: markdown.extensions.toc
17 | coloured_edges: true
18 | sort: permission-alpha
19 | author: RAFFLE developers
20 | github: https://github.com/ExeQuantCode
21 | print_creation_date: true
22 | creation_date: %Y-%m-%d %H:%M %z
23 | project_github: https://github.com/ExeQuantCode/raffle
24 | project_download: https://github.com/ExeQuantCode/raffle/releases
25 | github: https://github.com/ExeQuantCode
26 |
27 | {!README.md!}
--------------------------------------------------------------------------------
/example/python_pkg/visualisation/POSCAR_AABBCC_stack:
--------------------------------------------------------------------------------
1 | AABBCC vacuum
2 | 1.0
3 | 1.228133983 -2.127190457 0.000000000
4 | 1.228133983 2.127190457 0.000000000
5 | 0.000000000 0.000000000 21.520840786
6 | C
7 | 12
8 | direct
9 | 0.666666666 0.333333333 0.251933742
10 | 0.000000000 0.000000000 0.251941534
11 | 0.666666666 0.333333333 0.081391799
12 | 0.000000000 0.000000000 0.081399590
13 | 0.333333333 0.666666666 0.585267076
14 | 0.666666666 0.333333333 0.585274867
15 | 0.333333333 0.666666666 0.414725132
16 | 0.666666666 0.333333333 0.414732923
17 | 0.000000000 0.000000000 0.918600409
18 | 0.333333333 0.666666666 0.918608200
19 | 0.000000000 0.000000000 0.748058465
20 | 0.333333333 0.666666666 0.748066257
21 |
--------------------------------------------------------------------------------
/tools/coverage_badge.py:
--------------------------------------------------------------------------------
1 | from bs4 import BeautifulSoup
2 |
3 | html_file = "./build/coverage/index.html"
4 |
5 | colour_dict = {'coverage-low':"red", 'coverage-medium':"yellow", 'coverage-high':"brightgreen"}
6 |
7 | with open(html_file, 'r') as file:
8 | soup = BeautifulSoup(file, 'html.parser')
9 |
10 | # Find the "coverage" table
11 | coverage_table = soup.find('table', {'class': 'coverage'})
12 |
13 | # Find the second row of the "coverage" table
14 | second_row = coverage_table.find_all('tr')[1]
15 |
16 | # Find the third column of the second row
17 | third_column = second_row.find_all('td')[2]
18 |
19 | percentage = third_column.get_text()
20 |
21 | # Get the class of the
element
22 | td_class = third_column.get('class')[0]
23 |
24 | print(int(float(percentage.replace("%", ""))))
--------------------------------------------------------------------------------
/docs/source/about.rst:
--------------------------------------------------------------------------------
1 | .. _about:
2 |
3 | =====
4 | About
5 | =====
6 |
7 |
8 | RAFFLE (pseudoRandom Approach For Finding Local Energetic minima) is a package for structural prediction applied to material interfaces.
9 | RAFFLE can interface with the `Atomic Simulation Environment (ASE) `_.
10 |
11 | RAFFLE is both a Fortran and a Python library, with the option of a Fortran executable.
12 | The code heavily relies on features of Fortran 2018 and above, so there is no backwards compatibility with Fortran95.
13 |
14 | 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.
15 | These methods are meant to bias towards energetically favourable configurations, whilst still providing a thorough search of the configuration space.
--------------------------------------------------------------------------------
/example/data/C-MgO_hosts/POSCAR_1x1_5.4A_separation:
--------------------------------------------------------------------------------
1 | c1
2 | 1.00000000000000
3 | 2.4639999866000002 0.0000000000000000 0.0000000000000000
4 | -1.2319999933000001 2.1338865833999998 0.0000000000000000
5 | 0.0000000000000000 0.0000000000000000 10.7109999657000001
6 | C
7 | 4
8 | Direct
9 | 0.0000000000000000 0.0000000000000000 0.2500000000000000
10 | 0.0000000000000000 0.0000000000000000 0.7499999819999985
11 | 0.3333333400000029 0.6666666830000025 0.2500000000000000
12 | 0.6666666570000004 0.3333333140000008 0.7499999819999985
13 |
14 | 0.00000000E+00 0.00000000E+00 0.00000000E+00
15 | 0.00000000E+00 0.00000000E+00 0.00000000E+00
16 | 0.00000000E+00 0.00000000E+00 0.00000000E+00
17 | 0.00000000E+00 0.00000000E+00 0.00000000E+00
18 |
--------------------------------------------------------------------------------
/example/fortran_exe/param.in:
--------------------------------------------------------------------------------
1 | &setup
2 | task = 0,
3 | filename_host = "../data/C-MgO_hosts/POSCAR_MgO_HEX",
4 | database_format = "xyz"
5 | database = "./",
6 | seed = 1,
7 | grid_spacing = 0.05,
8 | verbose = 0,
9 | output_dir = "iteration1"
10 | /
11 |
12 | &placement_method
13 | void = 1.0,
14 | rand = 1.0,
15 | walk = 1.0,
16 | grow = 1.0,
17 | min = 1.0
18 | /
19 |
20 | &structure
21 | num_structures=10,
22 | stoichiometry="{Mg:8, O:8}",
23 | /
24 |
25 | &volume
26 | vdW=10,
27 | volvar=10
28 | /
29 |
30 | &distribution
31 | cutoff_min = 0.5 0.0 0.0,
32 | cutoff_max = 6.0 "pi" "pi",
33 | sigma = 0.5 0.1 0.1
34 | /
35 |
36 | &element_info
37 | energies = "{
38 | C: -9.0266865,
39 | Mg: -1.5478236,
40 | O: -4.3707458
41 | }"
42 | bond_radii = "{
43 | C-C: 1.54461,
44 | C-Mg: 2.3
45 | }
46 | /
47 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 | \#
3 | bin/
4 | obj/
5 | *.mod
6 | *.smod
7 | *.so
8 | *.txt
9 | DTESTING/
10 | DTEST/
11 | build/
12 | src/*.egg-info
13 | *.egg-info
14 | iteration*
15 | doc/html
16 | docs/html
17 | settings.json
18 | example/**/database*.xyz
19 | **/POSCAR*
20 | iteration/
21 | *.traj
22 | *.png
23 | *.param
24 | fort.*
25 | *.o
26 | *.out
27 | *.dat
28 | *.err
29 | *.e
30 | *.log
31 | *.agr
32 | *.pdf
33 | *.eps
34 | *.pyc
35 | *.xyz
36 | .coverage
37 | *CAR
38 | *.pckl
39 | .DS_Store
40 | fortranobject.c*
41 | *.db
42 | CHG
43 | EIGENVAL
44 | IBZKPT
45 | KPOINTS
46 | PCDAT
47 | REPORT
48 | [0-9][0-9][0-9][0-9]_*.json
49 | vasprun.xml
50 | DVASP_MACE_comparison/
51 | pca_model*.pkl
52 | .benchmarks/
53 | .local-pre-commit-config.yaml
54 | *.tgz
55 | .ipynb_checkpoints
56 | *.model
57 | *.vasp
58 | *.pkl
59 | meta.json
60 | context.json
61 | options.json
62 | procedure.py
63 |
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | pushd %~dp0
4 |
5 | REM Command file for Sphinx documentation
6 |
7 | if "%SPHINXBUILD%" == "" (
8 | set SPHINXBUILD=sphinx-build
9 | )
10 | set SOURCEDIR=source
11 | set BUILDDIR=build
12 |
13 | %SPHINXBUILD% >NUL 2>NUL
14 | if errorlevel 9009 (
15 | echo.
16 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
17 | echo.installed, then set the SPHINXBUILD environment variable to point
18 | echo.to the full path of the 'sphinx-build' executable. Alternatively you
19 | echo.may add the Sphinx directory to PATH.
20 | echo.
21 | echo.If you don't have Sphinx installed, grab it from
22 | echo.https://www.sphinx-doc.org/
23 | exit /b 1
24 | )
25 |
26 | if "%1" == "" goto help
27 |
28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
29 | goto end
30 |
31 | :help
32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
33 |
34 | :end
35 | popd
36 |
--------------------------------------------------------------------------------
/.readthedocs.yaml:
--------------------------------------------------------------------------------
1 | # .readthedocs.yaml
2 | # Read the Docs configuration file
3 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
4 |
5 | # Required
6 | version: 2
7 |
8 | # Set the OS, Python version and other tools you might need
9 | build:
10 | os: ubuntu-22.04
11 | tools:
12 | python: "3.12"
13 | # You can also specify other tool versions:
14 | # nodejs: "19"
15 | # rust: "1.64"
16 | # golang: "1.19"
17 |
18 | # Build documentation in the "docs/" directory with Sphinx
19 | sphinx:
20 | configuration: docs/source/conf.py
21 |
22 | # Optionally build your docs in additional formats such as PDF and ePub
23 | # formats:
24 | # - pdf
25 | # - epub
26 |
27 | # Optional but recommended, declare the Python requirements required
28 | # to build your documentation
29 | # See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
30 | python:
31 | install:
32 | - requirements: docs/requirements.txt
--------------------------------------------------------------------------------
/test/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | message(STATUS "Building tests")
2 | foreach(execid
3 | misc
4 | misc_maths
5 | misc_linalg
6 | cache
7 | element_utils
8 | geom_rw
9 | geom_utils
10 | geom_extd
11 | dist_calcs
12 | place_methods
13 | viability
14 | distribs_container
15 | evaluator_C
16 | evaluator_BTO
17 | generator
18 | io_utils
19 | tools_infile
20 | )
21 | add_executable(test_${execid} test_${execid}.f90)
22 | # Specify the include directories
23 | target_include_directories(test_${execid} PRIVATE "${CMAKE_BUILD_DIR}" "${CMAKE_BUILD_DIR}/mod")
24 |
25 | target_link_libraries(test_${execid} PRIVATE ${PROJECT_NAME})
26 |
27 | # Link against OpenMP if the build type is Parallel
28 | if (CMAKE_BUILD_TYPE MATCHES "Parallel*")
29 | target_link_libraries(test_${execid} PRIVATE ${PROJECT_NAME} OpenMP::OpenMP_Fortran)
30 | endif()
31 |
32 | add_test(NAME test_${execid} COMMAND test_${execid})
33 | endforeach()
34 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.yaml:
--------------------------------------------------------------------------------
1 | name: Feature Proposal
2 | description: Suggest new functionality for RAFFLE
3 | title: "[PROPOSAL]"
4 | labels: [enhancement]
5 | body:
6 | - type: textarea
7 | id: reasoning
8 | attributes:
9 | label: Reasoning
10 | placeholder: |
11 | Provide clear reasoning why the proposed functionality should be added to the RAFFLE library.
12 | validations:
13 | required: true
14 | - type: textarea
15 | id: prior_art
16 | attributes:
17 | label: Prior Art
18 | placeholder: |
19 | Provide examples of where this has been implemented for machine learning before to help justify its presence in this library.
20 | validations:
21 | required: false
22 | - type: textarea
23 | id: additional
24 | attributes:
25 | label: Additional information
26 | placeholder: |
27 | Add any other context or screenshots about the feature request here.
28 | validations:
29 | required: false
--------------------------------------------------------------------------------
/docs/RAFFLE.bib:
--------------------------------------------------------------------------------
1 | @article{Pitfield2024PredictingPhaseStability,
2 | title = {Predicting Phase Stability at Interfaces},
3 | author = {Pitfield, J. and Taylor, N. T. and Hepplestone, S. P.},
4 | journal = {Phys. Rev. Lett.},
5 | volume = {132},
6 | issue = {6},
7 | pages = {066201},
8 | numpages = {8},
9 | year = {2024},
10 | month = {Feb},
11 | publisher = {American Physical Society},
12 | doi = {10.1103/PhysRevLett.132.066201},
13 | url = {https://link.aps.org/doi/10.1103/PhysRevLett.132.066201}
14 | }
15 |
16 | @article{Taylor2025RAFFLEActiveLearning,
17 | title = {RAFFLE: Active learning accelerated interface structure prediction},
18 | author = {Taylor, Ned Thaddeus and Pitfield, Joe and Davies, Francis Huw and Hepplestone, Steven Paul},
19 | year = {2025},
20 | eprint={2504.02528},
21 | archivePrefix={arXiv},
22 | primaryClass={cond-mat.mtrl-sci},
23 | doi = {10.48550/ARXIV.2504.02528},
24 | url = {https://arxiv.org/abs/2504.02528},
25 | publisher = {arXiv},
26 | }
27 |
--------------------------------------------------------------------------------
/example/data/C-MgO_hosts/POSCAR_2x2_5.4A_separation:
--------------------------------------------------------------------------------
1 | c1
2 | 1.000000000
3 | 4.927999973 0.000000000 0.000000000
4 | -2.463999987 4.267773167 0.000000000
5 | 0.000000000 0.000000000 10.710999966
6 | C
7 | 16
8 | Direct
9 | 0.000000000 0.000000000 0.250000000
10 | 0.500000000 0.000000000 0.250000000
11 | 0.000000000 0.500000000 0.250000000
12 | 0.500000000 0.500000000 0.250000000
13 | 0.000000000 0.000000000 0.749999982
14 | 0.500000000 0.000000000 0.749999982
15 | 0.000000000 0.500000000 0.749999982
16 | 0.500000000 0.500000000 0.749999982
17 | 0.166666670 0.333333342 0.250000000
18 | 0.666666670 0.333333342 0.250000000
19 | 0.166666670 0.833333342 0.250000000
20 | 0.666666670 0.833333342 0.250000000
21 | 0.333333329 0.166666657 0.749999982
22 | 0.833333329 0.166666657 0.749999982
23 | 0.333333329 0.666666657 0.749999982
24 | 0.833333329 0.666666657 0.749999982
25 |
--------------------------------------------------------------------------------
/test/test_io_utils.f90:
--------------------------------------------------------------------------------
1 | program test_io_utils
2 | use raffle__io_utils
3 | implicit none
4 |
5 | ! Test variables
6 | logical :: success = .true.
7 | character(100) :: message
8 |
9 | ! Test stop_program subroutine
10 | test_error_handling = .true.
11 | message = "Test error message"
12 | call stop_program(message)
13 |
14 | ! Test print_warning subroutine
15 | call print_warning("This is a test warning message")
16 |
17 | ! Test print_version subroutine
18 | call print_version()
19 |
20 | ! Test print_build_info subroutine
21 | call print_build_info()
22 |
23 | !-----------------------------------------------------------------------------
24 | ! check for any failed tests
25 | !-----------------------------------------------------------------------------
26 | write(*,*) "----------------------------------------"
27 | if(success)then
28 | write(*,*) 'test_misc_linalg passed all tests'
29 | else
30 | write(0,*) 'test_misc_linalg failed one or more tests'
31 | stop 1
32 | end if
33 |
34 | end program test_io_utils
--------------------------------------------------------------------------------
/docs/source/references.bib:
--------------------------------------------------------------------------------
1 | @article{Christiansen2022AtomisticGlobalOptimization,
2 | title = {Atomistic global optimization {X}: {A Python} package for optimization of atomistic structures},
3 | volume = {157},
4 | ISSN = {1089-7690},
5 | url = {http://dx.doi.org/10.1063/5.0094165},
6 | DOI = {10.1063/5.0094165},
7 | number = {5},
8 | journal = {The Journal of Chemical Physics},
9 | publisher = {AIP Publishing},
10 | author = {Christiansen, Mads-Peter V. and Rønne, Nikolaj and Hammer, Bjørk},
11 | year = {2022},
12 | month = aug
13 | }
14 |
15 | @article{Schusteritsch2014PredictingInterfaceStructures,
16 | title = {Predicting interface structures: From {SrTiO$_3$} to graphene},
17 | volume = {90},
18 | ISSN = {1550-235X},
19 | url = {http://dx.doi.org/10.1103/PhysRevB.90.035424},
20 | DOI = {10.1103/physrevb.90.035424},
21 | number = {3},
22 | journal = {Physical Review B},
23 | publisher = {American Physical Society (APS)},
24 | author = {Schusteritsch, Georg and Pickard, Chris J.},
25 | year = {2014},
26 | month = jul
27 | }
28 |
--------------------------------------------------------------------------------
/docs/source/raffle.generator_module.rst:
--------------------------------------------------------------------------------
1 | raffle.generator Module
2 | =======================
3 |
4 | This is a simulated module that holds the following class:
5 |
6 | - :class:`raffle.Generator()`
7 |
8 | This class cannot be directly accessed, but the two user-facing classes within it can be.
9 | Within this class, there exist two directly accessible sub-classes:
10 |
11 | - :class:`raffle.generator.stoichiometry_array()`
12 | - :class:`raffle.generator.raffle_generator()`
13 |
14 | The documentation for these can be found here: :doc:`raffle.generator_class`.
15 |
16 | Finally, the :class:`raffle.generator.raffle_generator()` contains instances of the following classes:
17 |
18 | - :class:`raffle.Raffle__Distribs_Container()` - raffle.generator.raffle_generator().distributions
19 | - :class:`raffle.Geom_Rw().basis()` - raffle.generator.raffle_generator().host
20 | - :class:`raffle.Geom_Rw().basis_arary()` - raffle.generator.raffle_generator().structures
21 |
22 |
23 |
24 | .. automodule:: raffle.generator
25 | :members:
26 | :undoc-members:
27 | :show-inheritance:
28 |
--------------------------------------------------------------------------------
/example/python_pkg/graphite/POSCAR_host_graphene:
--------------------------------------------------------------------------------
1 | C4
2 | 1.000000000
3 | 3.700936892 -6.410210733 0.000000000
4 | 3.700936892 6.410210733 0.000000000
5 | 0.000000000 0.000000000 7.803073000
6 | C
7 | 18
8 | Direct
9 | 0.000000000 0.000000000 0.250000000
10 | 0.333333333 0.000000000 0.250000000
11 | 0.666666667 0.000000000 0.250000000
12 | 0.000000000 0.333333333 0.250000000
13 | 0.333333333 0.333333333 0.250000000
14 | 0.666666667 0.333333333 0.250000000
15 | 0.000000000 0.666666667 0.250000000
16 | 0.333333333 0.666666667 0.250000000
17 | 0.666666667 0.666666667 0.250000000
18 | 0.111111111 0.222222222 0.250000000
19 | 0.444444444 0.222222222 0.250000000
20 | 0.777777778 0.222222222 0.250000000
21 | 0.111111111 0.555555556 0.250000000
22 | 0.444444444 0.555555556 0.250000000
23 | 0.777777778 0.555555556 0.250000000
24 | 0.111111111 0.888888889 0.250000000
25 | 0.444444444 0.888888889 0.250000000
26 | 0.777777778 0.888888889 0.250000000
--------------------------------------------------------------------------------
/tools/version_number.py:
--------------------------------------------------------------------------------
1 | import re
2 |
3 | def update_version(new_version):
4 | # Update fpm.toml
5 | with open('fpm.toml', 'r') as file:
6 | content = file.read()
7 | content = re.sub(r'version = "\d+\.\d+\.\d+.*"', f'version = "{new_version}"', content)
8 | with open('fpm.toml', 'w') as file:
9 | file.write(content)
10 |
11 | # Update Fortran module
12 | with open('src/fortran/lib/mod_io_utils.F90', 'r') as file:
13 | content = file.read()
14 | content = re.sub(r'character\(len=\*\), parameter :: raffle__version__ = "\d+\.\d+\.\d+.*"', f'character(len=*), parameter :: raffle__version__ = "{new_version}"', content)
15 | with open('src/fortran/lib/mod_io_utils.F90', 'w') as file:
16 | file.write(content)
17 |
18 | def get_version():
19 | # get the version number from fpm.toml
20 | with open('fpm.toml', 'r') as file:
21 | content = file.read()
22 | match = re.search(r'version = "(\d+\.\d+\.\d+.*)"', content)
23 | print(match.group(1))
24 | if match:
25 | return match.group(1)
26 |
27 | if __name__ == '__main__':
28 | update_version(get_version())
29 |
--------------------------------------------------------------------------------
/example/data/C-MgO_hosts/POSCAR_5x1_5.4A_separation:
--------------------------------------------------------------------------------
1 | c1
2 | 1.000000000
3 | 12.319999933 0.000000000 0.000000000
4 | -1.231999993 2.133886583 0.000000000
5 | 0.000000000 0.000000000 10.710999966
6 | C
7 | 20
8 | Direct
9 | 0.000000000 0.000000000 0.250000000
10 | 0.200000000 0.000000000 0.250000000
11 | 0.400000000 0.000000000 0.250000000
12 | 0.600000000 0.000000000 0.250000000
13 | 0.800000000 0.000000000 0.250000000
14 | 0.000000000 0.000000000 0.749999982
15 | 0.200000000 0.000000000 0.749999982
16 | 0.400000000 0.000000000 0.749999982
17 | 0.600000000 0.000000000 0.749999982
18 | 0.800000000 0.000000000 0.749999982
19 | 0.066666668 0.666666683 0.250000000
20 | 0.266666668 0.666666683 0.250000000
21 | 0.466666668 0.666666683 0.250000000
22 | 0.666666668 0.666666683 0.250000000
23 | 0.866666668 0.666666683 0.250000000
24 | 0.133333331 0.333333314 0.749999982
25 | 0.333333331 0.333333314 0.749999982
26 | 0.533333331 0.333333314 0.749999982
27 | 0.733333331 0.333333314 0.749999982
28 | 0.933333331 0.333333314 0.749999982
29 |
--------------------------------------------------------------------------------
/src/fortran/lib/mod_cache.f90:
--------------------------------------------------------------------------------
1 | module raffle__cache
2 | use raffle__constants, only: real32
3 | implicit none
4 |
5 | private
6 | public :: store_probability_density, retrieve_probability_density
7 |
8 | real(real32), allocatable, dimension(:,:), save :: cached_probability_density
9 |
10 | contains
11 |
12 | subroutine store_probability_density(probability_density)
13 | implicit none
14 | real(real32), intent(in) :: probability_density(:,:)
15 | if (allocated(cached_probability_density)) &
16 | deallocate(cached_probability_density)
17 | allocate(cached_probability_density, source = probability_density)
18 |
19 | end subroutine store_probability_density
20 |
21 | function retrieve_probability_density() result(probability_density)
22 | implicit none
23 | real(real32), allocatable :: probability_density(:,:)
24 | if(.not.allocated(cached_probability_density)) then
25 | write(0,*) "Probability density not allocated. Returning zero array."
26 | allocate(probability_density(1,1), source = 0._real32)
27 | else
28 | allocate(probability_density, source = cached_probability_density)
29 | end if
30 | end function retrieve_probability_density
31 |
32 | end module raffle__cache
33 |
--------------------------------------------------------------------------------
/example/python_pkg/agox_runs/n-body_run/tidy.py:
--------------------------------------------------------------------------------
1 | # This script tidies up the n-body database files by organizing them into subdirectories based on the number of bodies.
2 | # By running this script, then the following agox line in the command line:
3 | # agox analysis n-bodies/*
4 | # you will get analysis of the n-body successes split up by the number of contributing n-body distribution functions.
5 |
6 | import os
7 | import re
8 | import shutil
9 | from math import gcd
10 | from functools import reduce
11 |
12 | src_dir = "n-body"
13 | dst_base = "n-bodies"
14 |
15 | # Regex to match the filename pattern
16 | pattern = re.compile(
17 | r"^db(?P\d+)_dist_(?P[\d\.]+)\.db$"
18 | )
19 |
20 | os.makedirs(dst_base, exist_ok=True)
21 |
22 | for fname in os.listdir(src_dir):
23 | match = pattern.match(fname)
24 | if match:
25 | parts = match.groupdict()
26 | subdir_name = f"{parts['nbody']}-body"
27 | fname_new = f"db{parts['seed']}.db" #_{subdir_name}.db"
28 | subdir_path = os.path.join(dst_base, subdir_name)
29 | os.makedirs(subdir_path, exist_ok=True)
30 |
31 | src_path = os.path.join(src_dir, fname)
32 | dst_path = os.path.join(subdir_path, fname_new)
33 | shutil.copy2(src_path, dst_path)
34 |
--------------------------------------------------------------------------------
/CITATION.cff:
--------------------------------------------------------------------------------
1 | # This CITATION.cff file was generated with cffinit.
2 | # Visit https://bit.ly/cffinit to generate yours today!
3 |
4 | cff-version: 1.2.0
5 | title: >-
6 | RAFFLE: pseudoRandom Approach For Finding Local Energy
7 | minima
8 | message: >-
9 | If you use this software, please cite it using the
10 | metadata from this file and the following papers:
11 | https://link.aps.org/doi/10.1103/PhysRevLett.132.066201
12 | https://arxiv.org/abs/2504.02528
13 | type: software
14 | authors:
15 | - given-names: Ned Thaddeus
16 | family-names: Taylor
17 | orcid: 'https://orcid.org/0000-0002-9134-9712'
18 | affiliation: University of Exeter
19 | - given-names: Joe
20 | family-names: Pitfield
21 | orcid: 'https://orcid.org/0000-0002-9758-5230'
22 | affiliation: Aarhus Universitet
23 | - given-names: Steven Paul
24 | family-names: Hepplestone
25 | orcid: 'https://orcid.org/0000-0002-2528-1270'
26 | affiliation: University of Exeter
27 | repository-code: 'https://github.com/ExeQuantCode/RAFFLE'
28 | keywords:
29 | - materials science
30 | - interfaces
31 | - material interfaces
32 | - structure prediction
33 | - random structure search
34 | license: GPL-3.0
35 | commit: 1a4e7aacf07b4d9623d846df30aa7ac3a5e98e81
36 | version: 1.0.0
37 | date-released: '2025-03-03'
38 |
--------------------------------------------------------------------------------
/docs/source/tutorials/index.rst:
--------------------------------------------------------------------------------
1 | .. tutorials:
2 |
3 | =========
4 | Tutorials
5 | =========
6 |
7 | Whilst RAFFLE is a random sturcture search package designed primarlily for interfaces, the tutorials will use bulk systems to demonstrate its functionality.
8 |
9 | .. note::
10 | If you are looking for bulk random structure search, we recommend using packages such as `AIRSS `_, which are specifically designed for this purpose.
11 | They take advantage of symmetries prevalent in bulk structures to reduce the search space and improve efficiency.
12 | RAFFLE does not account for these symmetries, due to their usual absence in interfaces.
13 |
14 | .. toctree::
15 | :maxdepth: 2
16 | :caption: Setup and parameters:
17 |
18 | databases_tutorial
19 | parameters_tutorial
20 | host_tutorial
21 | generating_tutorial
22 | quick_guide
23 |
24 | .. toctree::
25 | :maxdepth: 2
26 | :caption: Static structure prediction:
27 |
28 | diamond_tutorial
29 | graphite_tutorial
30 |
31 | .. toctree::
32 | :maxdepth: 2
33 | :caption: Iterative structure learning:
34 |
35 | aluminium_tutorial
36 | Si-Ge_tutorial
37 | graphene_grain_boundary_tutorial
38 | agox_tutorial
39 |
40 | .. toctree::
41 | :maxdepth: 2
42 | :caption: Visualisation:
43 |
44 | visualisation
45 |
--------------------------------------------------------------------------------
/docs/source/modules.rst:
--------------------------------------------------------------------------------
1 | raffle
2 | ======
3 |
4 | .. Submodules
5 | .. ----------
6 |
7 | .. raffle.raffle module
8 | .. --------------------
9 |
10 | .. .. automodule:: raffle.raffle
11 | .. :members:
12 | .. :undoc-members:
13 | .. :show-inheritance:
14 |
15 | Module contents
16 | ---------------
17 |
18 | RAFFLE is a python package for performing structure prediction at interfaces.
19 | The package provides functionality for generating atomic structures by filling in host structures with additional atoms.
20 | 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).
21 | The package is built to accommodate energetic and structure data provided by the Atomic Simulation Environment (ASE) package (https://wiki.fysik.dtu.dk/ase/).
22 |
23 | Submodules
24 | ----------
25 |
26 | .. toctree::
27 | :maxdepth: 2
28 |
29 | raffle.generator_module
30 | raffle.geom_module
31 |
32 | Classes
33 | -------
34 |
35 | These are the main classes of the package (they are only indirectly accessible):
36 |
37 | .. toctree::
38 | :maxdepth: 2
39 |
40 | raffle.generator_class
41 | raffle.geom_rw_class
42 | raffle.distributions_class
43 |
44 | .. .. automodule:: raffle
45 | .. :members:
46 | .. :undoc-members:
47 | .. :show-inheritance:
48 |
--------------------------------------------------------------------------------
/example/python_pkg/visualisation/POSCAR_ABAB_stack:
--------------------------------------------------------------------------------
1 | ABAB vacuum
2 | 1.0
3 | 1.227975709 -2.126916320 0.000000000
4 | 1.227975709 2.126916320 0.000000000
5 | 0.000000000 0.000000000 54.715156838
6 | C
7 | 24
8 | direct
9 | 0.000000000 0.000000000 0.031579449
10 | 0.666666666 0.333333333 0.238822903
11 | 0.666666666 0.333333333 0.094505113
12 | 0.000000000 0.000000000 0.094510430
13 | 0.666666666 0.333333333 0.301753883
14 | 0.333333333 0.666666666 0.031587736
15 | 0.000000000 0.000000000 0.238828220
16 | 0.333333333 0.666666666 0.301745596
17 | 0.666666666 0.333333333 0.364912783
18 | 0.333333333 0.666666666 0.572156236
19 | 0.333333333 0.666666666 0.427838446
20 | 0.666666666 0.333333333 0.427843763
21 | 0.333333333 0.666666666 0.635087216
22 | 0.000000000 0.000000000 0.364921069
23 | 0.666666666 0.333333333 0.572161553
24 | 0.000000000 0.000000000 0.635078930
25 | 0.333333333 0.666666666 0.698246116
26 | 0.000000000 0.000000000 0.905489569
27 | 0.000000000 0.000000000 0.761171779
28 | 0.333333333 0.666666666 0.761177096
29 | 0.000000000 0.000000000 0.968420550
30 | 0.666666666 0.333333333 0.698254403
31 | 0.333333333 0.666666666 0.905494886
32 | 0.666666666 0.333333333 0.968412263
33 |
--------------------------------------------------------------------------------
/example/python_pkg/perovskites/database.xyz:
--------------------------------------------------------------------------------
1 | 5
2 | Lattice="3.93796462 0.0 0.0 0.0 3.93796462 0.0 0.0 0.0 3.93891698" Properties=species:S:1:pos:R:3:forces:R:3 energy=-40.12032428 stress="-0.0008424844130642804 -0.0 -0.0 -0.0 -0.0008424844130642804 0.0 -0.0 0.0 -0.000512511616596921" free_energy=-40.12032428 pbc="T T T"
3 | Sr 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000
4 | Ti 1.96898231 1.96898231 1.96945849 0.00000000 0.00000000 0.00000000
5 | O 0.00000000 1.96898231 1.96945849 0.00000000 0.00000000 0.00000000
6 | O 1.96898231 0.00000000 1.96945849 0.00000000 0.00000000 0.00000000
7 | O 1.96898231 1.96898231 0.00000000 0.00000000 0.00000000 0.00000000
8 | 5
9 | Lattice="4.03084376 0.0 0.0 0.0 4.03084376 0.0 0.0 0.0 4.03254345" Properties=species:S:1:pos:R:3:forces:R:3 energy=-40.00295673 stress="-0.0002488092354018701 -0.0 -0.0 -0.0 -0.0002488092354018701 0.0 -0.0 0.0 0.0002890913610814811" free_energy=-40.00295673 pbc="T T T"
10 | Ba 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000
11 | Ti 2.01542188 2.01542188 2.01627173 0.00000000 0.00000000 0.00000000
12 | O 2.01542188 0.00000000 2.01627173 0.00000000 0.00000000 0.00000000
13 | O 0.00000000 2.01542188 2.01627173 0.00000000 0.00000000 0.00000000
14 | O 2.01542188 2.01542188 0.00000000 0.00000000 0.00000000 0.00000000
15 |
--------------------------------------------------------------------------------
/src/raffle/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | raffle package
3 |
4 | This package provides functionality to interface with a Fortran library,
5 | including a Python wrapper around the Fortran code.
6 | """
7 |
8 | from importlib.metadata import PackageNotFoundError, version
9 | try:
10 | __version__ = version(__name__)
11 | except PackageNotFoundError:
12 | __version__ = "unknown"
13 |
14 | from .raffle import generator as _generator_class
15 | from .raffle import geom_rw as _geom_rw_class
16 | # from .raffle import generator
17 |
18 |
19 | # Use the 'types' module to create simulated 'generator' and 'geom submodules
20 | import types
21 | generator = types.ModuleType('generator')
22 | geom = types.ModuleType('geom')
23 |
24 | # Assign the respective class to the simulated 'generator' and 'geom' modules
25 | generator.raffle_generator = _generator_class.raffle_generator
26 | generator.stoichiometry_array = _generator_class.stoichiometry_array
27 |
28 | # Assign the class to the simulated 'geom' module
29 | geom.basis_array = _geom_rw_class.basis_array
30 | geom.basis = _geom_rw_class.basis
31 |
32 |
33 | # Add the simulated 'generator' and 'geom' module to the current package
34 | import sys
35 | sys.modules['raffle.generator'] = generator
36 | sys.modules['raffle.geom'] = geom
37 |
38 | # Clean up internal imports (remove access to the direct classes)
39 | del _generator_class
40 | del _geom_rw_class
41 | del PackageNotFoundError
42 | del version
43 | del sys
44 | del types
45 | del raffle
46 |
47 | __all__ = ['__version__', 'generator', 'geom']
48 |
49 | def __getattr__(name):
50 | if name == "generator":
51 | return generator
52 | elif name == "geom":
53 | return geom
54 | raise AttributeError(f"module {__name__} has no attribute {name}")
--------------------------------------------------------------------------------
/example/python_pkg/agox_runs/Si-Ge_run/tidy.py:
--------------------------------------------------------------------------------
1 | # This script tidies up the n-body database files by organizing them into subdirectories based on the number of bodies.
2 | # By running this script, then the following agox line in the command line:
3 | # agox analysis method_ratios/*
4 | # you will get analysis of the success split up by the method ratios used in the generation of the structures.
5 |
6 | import os
7 | import re
8 | import shutil
9 | from math import gcd
10 | from functools import reduce
11 |
12 | src_dir = "method_ratio"
13 | dst_base = "method_ratios"
14 |
15 | # Regex to match the filename pattern
16 | pattern = re.compile(
17 | r"^db(?P\d+)_dist_grow(?P[\d\.]+)_min(?P[\d\.]+)_rand(?P[\d\.]+)_void(?P[\d\.]+)_walk(?P[\d\.]+)\.db$"
18 | )
19 |
20 | def float_str_to_int_ratios(values):
21 | # Convert all to floats
22 | floats = [float(v) for v in values]
23 | scale = 1000 # To avoid float precision issues
24 | ints = [round(f * scale) for f in floats]
25 | divisor = reduce(gcd, ints)
26 | return [i // divisor for i in ints]
27 |
28 | os.makedirs(dst_base, exist_ok=True)
29 |
30 | for fname in os.listdir(src_dir):
31 | match = pattern.match(fname)
32 | if match:
33 | parts = match.groupdict()
34 | ratios = float_str_to_int_ratios([
35 | parts["void"], parts["rand"], parts["walk"], parts["grow"], parts["min"]
36 | ])
37 | # Assign to the appropriate method
38 | v, r, w, g, m = ratios
39 | # exit()
40 | subdir_name = f"v{v}_r{r}_w{w}_g{g}_m{m}"
41 | fname_new = f"db{parts['seed']}.db" #_{subdir_name}.db"
42 | subdir_path = os.path.join(dst_base, subdir_name)
43 | os.makedirs(subdir_path, exist_ok=True)
44 |
45 | src_path = os.path.join(src_dir, fname)
46 | dst_path = os.path.join(subdir_path, fname_new)
47 | shutil.copy2(src_path, dst_path)
48 |
--------------------------------------------------------------------------------
/example/python_pkg/agox_runs/graphene_grain_boundary_run/tidy.py:
--------------------------------------------------------------------------------
1 | # This script tidies up the n-body database files by organizing them into subdirectories based on the number of bodies.
2 | # By running this script, then the following agox line in the command line:
3 | # agox analysis method_ratios/*
4 | # you will get analysis of the success split up by the method ratios used in the generation of the structures.
5 |
6 | import os
7 | import re
8 | import shutil
9 | from math import gcd
10 | from functools import reduce
11 |
12 | src_dir = "method_ratio"
13 | dst_base = "method_ratios"
14 |
15 | # Regex to match the filename pattern
16 | pattern = re.compile(
17 | r"^db(?P\d+)_grow(?P[\d\.]+)_min(?P[\d\.]+)_rand(?P[\d\.]+)_void(?P[\d\.]+)_walk(?P[\d\.]+)\.db$"
18 | )
19 |
20 | def float_str_to_int_ratios(values):
21 | # Convert all to floats
22 | floats = [float(v) for v in values]
23 | scale = 1000 # To avoid float precision issues
24 | ints = [round(f * scale) for f in floats]
25 | divisor = reduce(gcd, ints)
26 | return [i // divisor for i in ints]
27 |
28 | os.makedirs(dst_base, exist_ok=True)
29 |
30 | for fname in os.listdir(src_dir):
31 | match = pattern.match(fname)
32 | if match:
33 | parts = match.groupdict()
34 | ratios = float_str_to_int_ratios([
35 | parts["void"], parts["rand"], parts["walk"], parts["grow"], parts["min"]
36 | ])
37 | # Assign to the appropriate method
38 | v, r, w, g, m = ratios
39 | # exit()
40 | subdir_name = f"v{v}_r{r}_w{w}_g{g}_m{m}"
41 | fname_new = f"db{parts['seed']}.db" #_{subdir_name}.db"
42 | subdir_path = os.path.join(dst_base, subdir_name)
43 | os.makedirs(subdir_path, exist_ok=True)
44 |
45 | src_path = os.path.join(src_dir, fname)
46 | dst_path = os.path.join(subdir_path, fname_new)
47 | shutil.copy2(src_path, dst_path)
48 |
--------------------------------------------------------------------------------
/tools/check_accuracy_C-MgO.py:
--------------------------------------------------------------------------------
1 | import os
2 | import numpy as np
3 |
4 | # import ASE (Atomic Simulation Environment) modules
5 | from ase import Atoms
6 | from ase.io import read, write
7 |
8 |
9 | ## load calculator
10 | calculator = "CHGNet"
11 | match calculator:
12 | case "CHGNet":
13 | from chgnet.model.dynamics import CHGNetCalculator
14 | print("Initialising CHGNet calculator")
15 | calc = CHGNetCalculator()
16 | label = "CHGNet"
17 | case "MACE":
18 | from mace.calculators import mace_mp
19 | print("Initialising MACE calculator")
20 | calc = mace_mp(model="medium", dispersion=False, default_dtype="float32", device='cpu')
21 | label = "MACE"
22 |
23 | ## Read the database
24 | print("Reading database")
25 | database = read("../example/data/C-MgO.xyz", index=":")
26 |
27 | ## Calculate the energies
28 | energies_dft = []
29 | energies_mlp = []
30 | for i, atoms in enumerate(database):
31 | if atoms.calc is None:
32 | database.remove(atoms)
33 | continue
34 | energies_dft.append(atoms.get_potential_energy()/len(atoms))
35 | atoms.calc = calc
36 | energies_mlp.append(atoms.get_potential_energy()/len(atoms))
37 | # if energies_mlp[-1] - energies_dft[-1] > 3e-1 and energies_mlp[-1] < -7.9:
38 | # print(f"Energy difference for structure {i} is {energies_mlp[-1] - energies_dft[-1]}, energy_mace: {energies_mlp[-1]}")
39 | # view(atoms)
40 |
41 |
42 | import matplotlib.pyplot as plt
43 |
44 | ## Write energies to a file
45 | with open("C-MgO_energies_comparison.txt", "w") as f:
46 | f.write("# DFT_Energy_per_atom "+label+"_Energy_per_atom\n")
47 | for dft_energy, mace_energy in zip(energies_dft, energies_mlp):
48 | f.write(f"{dft_energy} {mace_energy}\n")
49 |
50 | # Plotting the energies
51 | plt.figure(figsize=(10, 6))
52 | plt.scatter(energies_dft, energies_mlp, c='blue', marker='o', label=label+' vs DFT')
53 | plt.show()
--------------------------------------------------------------------------------
/example/python_pkg/graphite/POSCAR_host_graphite_vacancy:
--------------------------------------------------------------------------------
1 | C4
2 | 1.000000000
3 | 3.700936892 -6.410210733 0.000000000
4 | 3.700936892 6.410210733 0.000000000
5 | 0.000000000 0.000000000 7.803073000
6 | C
7 | 35
8 | Direct
9 | 0.000000000 0.000000000 0.250000000
10 | 0.333333333 0.000000000 0.250000000
11 | 0.666666667 0.000000000 0.250000000
12 | 0.000000000 0.333333333 0.250000000
13 | 0.333333333 0.333333333 0.250000000
14 | 0.666666667 0.333333333 0.250000000
15 | 0.000000000 0.666666667 0.250000000
16 | 0.333333333 0.666666667 0.250000000
17 | 0.666666667 0.666666667 0.250000000
18 | 0.000000000 0.000000000 0.750000000
19 | 0.333333333 0.000000000 0.750000000
20 | 0.666666667 0.000000000 0.750000000
21 | 0.000000000 0.333333333 0.750000000
22 | 0.333333333 0.333333333 0.750000000
23 | 0.666666667 0.333333333 0.750000000
24 | 0.000000000 0.666666667 0.750000000
25 | 0.333333333 0.666666667 0.750000000
26 | 0.666666667 0.666666667 0.750000000
27 | 0.111111111 0.222222222 0.250000000
28 | 0.444444444 0.222222222 0.250000000
29 | 0.777777778 0.222222222 0.250000000
30 | 0.111111111 0.555555556 0.250000000
31 | 0.444444444 0.555555556 0.250000000
32 | 0.777777778 0.555555556 0.250000000
33 | 0.111111111 0.888888889 0.250000000
34 | 0.444444444 0.888888889 0.250000000
35 | 0.777777778 0.888888889 0.250000000
36 | 0.222222222 0.111111111 0.750000000
37 | 0.555555556 0.111111111 0.750000000
38 | 0.888888889 0.111111111 0.750000000
39 | 0.222222222 0.444444444 0.750000000
40 | 0.555555556 0.444444444 0.750000000
41 | 0.888888889 0.444444444 0.750000000
42 | 0.222222222 0.777777778 0.750000000
43 | 0.555555556 0.777777778 0.750000000
44 |
45 |
--------------------------------------------------------------------------------
/example/data/C-MgO_hosts/POSCAR_3x3_11.0A_separation:
--------------------------------------------------------------------------------
1 | c1
2 | 1.000000000
3 | 7.391999960 0.000000000 0.000000000
4 | -3.695999980 6.401659750 0.000000000
5 | 0.000000000 0.000000000 14.710999966
6 | C
7 | 36
8 | Direct
9 | 0.000000000 0.000000000 0.000000000
10 | 0.333333333 0.000000000 0.000000000
11 | 0.666666667 0.000000000 0.000000000
12 | 0.000000000 0.333333333 0.000000000
13 | 0.333333333 0.333333333 0.000000000
14 | 0.666666667 0.333333333 0.000000000
15 | 0.000000000 0.666666667 0.000000000
16 | 0.333333333 0.666666667 0.000000000
17 | 0.666666667 0.666666667 0.000000000
18 | 0.000000000 0.000000000 0.749999982
19 | 0.333333333 0.000000000 0.749999982
20 | 0.666666667 0.000000000 0.749999982
21 | 0.000000000 0.333333333 0.749999982
22 | 0.333333333 0.333333333 0.749999982
23 | 0.666666667 0.333333333 0.749999982
24 | 0.000000000 0.666666667 0.749999982
25 | 0.333333333 0.666666667 0.749999982
26 | 0.666666667 0.666666667 0.749999982
27 | 0.111111113 0.222222228 0.000000000
28 | 0.444444447 0.222222228 0.000000000
29 | 0.777777780 0.222222228 0.000000000
30 | 0.111111113 0.555555561 0.000000000
31 | 0.444444447 0.555555561 0.000000000
32 | 0.777777780 0.555555561 0.000000000
33 | 0.111111113 0.888888894 0.000000000
34 | 0.444444447 0.888888894 0.000000000
35 | 0.777777780 0.888888894 0.000000000
36 | 0.222222219 0.111111105 0.749999982
37 | 0.555555552 0.111111105 0.749999982
38 | 0.888888886 0.111111105 0.749999982
39 | 0.222222219 0.444444438 0.749999982
40 | 0.555555552 0.444444438 0.749999982
41 | 0.888888886 0.444444438 0.749999982
42 | 0.222222219 0.777777771 0.749999982
43 | 0.555555552 0.777777771 0.749999982
44 | 0.888888886 0.777777771 0.749999982
45 |
--------------------------------------------------------------------------------
/example/data/C-MgO_hosts/POSCAR_3x3_5.4A_separation:
--------------------------------------------------------------------------------
1 | c1
2 | 1.000000000
3 | 7.391999960 0.000000000 0.000000000
4 | -3.695999980 6.401659750 0.000000000
5 | 0.000000000 0.000000000 10.710999966
6 | C
7 | 36
8 | Direct
9 | 0.000000000 0.000000000 0.250000000
10 | 0.333333333 0.000000000 0.250000000
11 | 0.666666667 0.000000000 0.250000000
12 | 0.000000000 0.333333333 0.250000000
13 | 0.333333333 0.333333333 0.250000000
14 | 0.666666667 0.333333333 0.250000000
15 | 0.000000000 0.666666667 0.250000000
16 | 0.333333333 0.666666667 0.250000000
17 | 0.666666667 0.666666667 0.250000000
18 | 0.000000000 0.000000000 0.749999982
19 | 0.333333333 0.000000000 0.749999982
20 | 0.666666667 0.000000000 0.749999982
21 | 0.000000000 0.333333333 0.749999982
22 | 0.333333333 0.333333333 0.749999982
23 | 0.666666667 0.333333333 0.749999982
24 | 0.000000000 0.666666667 0.749999982
25 | 0.333333333 0.666666667 0.749999982
26 | 0.666666667 0.666666667 0.749999982
27 | 0.111111113 0.222222228 0.250000000
28 | 0.444444447 0.222222228 0.250000000
29 | 0.777777780 0.222222228 0.250000000
30 | 0.111111113 0.555555561 0.250000000
31 | 0.444444447 0.555555561 0.250000000
32 | 0.777777780 0.555555561 0.250000000
33 | 0.111111113 0.888888894 0.250000000
34 | 0.444444447 0.888888894 0.250000000
35 | 0.777777780 0.888888894 0.250000000
36 | 0.222222219 0.111111105 0.749999982
37 | 0.555555552 0.111111105 0.749999982
38 | 0.888888886 0.111111105 0.749999982
39 | 0.222222219 0.444444438 0.749999982
40 | 0.555555552 0.444444438 0.749999982
41 | 0.888888886 0.444444438 0.749999982
42 | 0.222222219 0.777777771 0.749999982
43 | 0.555555552 0.777777771 0.749999982
44 | 0.888888886 0.777777771 0.749999982
45 |
--------------------------------------------------------------------------------
/example/data/C-MgO_hosts/POSCAR_1x5_orthorhombic_11.0A_separation:
--------------------------------------------------------------------------------
1 | c1+mg1 o1
2 | 1.000000000
3 | 4.267773167 0.000000000 0.000000000
4 | -0.000000000 12.319999933 0.000000000
5 | 0.000000000 0.000000000 14.398580001
6 | C
7 | 40
8 | Direct
9 | 0.000000000 0.000000000 0.000000000
10 | 0.000000000 0.200000000 0.000000000
11 | 0.000000000 0.400000000 0.000000000
12 | 0.000000000 0.600000000 0.000000000
13 | 0.000000000 0.800000000 0.000000000
14 | 0.500000000 0.100000000 0.000000000
15 | 0.500000000 0.300000000 0.000000000
16 | 0.500000000 0.500000000 0.000000000
17 | 0.500000000 0.700000000 0.000000000
18 | 0.500000000 0.900000000 0.000000000
19 | 0.000000000 0.000000000 0.766956196
20 | 0.000000000 0.200000000 0.766956196
21 | 0.000000000 0.400000000 0.766956196
22 | 0.000000000 0.600000000 0.766956196
23 | 0.000000000 0.800000000 0.766956196
24 | 0.500000000 0.100000000 0.766956196
25 | 0.500000000 0.300000000 0.766956196
26 | 0.500000000 0.500000000 0.766956196
27 | 0.500000000 0.700000000 0.766956196
28 | 0.500000000 0.900000000 0.766956196
29 | 0.333333342 1.000000000 0.000000000
30 | 0.333333342 0.200000000 0.000000000
31 | 0.333333342 0.400000000 0.000000000
32 | 0.333333342 0.600000000 0.000000000
33 | 0.333333342 0.800000000 0.000000000
34 | 0.833333342 0.100000000 0.000000000
35 | 0.833333342 0.300000000 0.000000000
36 | 0.833333342 0.500000000 0.000000000
37 | 0.833333342 0.700000000 0.000000000
38 | 0.833333342 0.900000000 0.000000000
39 | 0.166666657 0.100000000 0.766956196
40 | 0.166666657 0.300000000 0.766956196
41 | 0.166666657 0.500000000 0.766956196
42 | 0.166666657 0.700000000 0.766956196
43 | 0.166666657 0.900000000 0.766956196
44 | 0.666666657 0.000000000 0.766956196
45 | 0.666666657 0.200000000 0.766956196
46 | 0.666666657 0.400000000 0.766956196
47 | 0.666666657 0.600000000 0.766956196
48 | 0.666666657 0.800000000 0.766956196
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.yaml:
--------------------------------------------------------------------------------
1 | name: Bug Report
2 | description: Something is not working
3 | title: "[BUG]"
4 | labels: [bug]
5 | body:
6 | - type: textarea
7 | id: description
8 | attributes:
9 | label: Description
10 | placeholder: |
11 | A clear and concise description of what the bug is and what the expected behaviour is.
12 | validations:
13 | required: true
14 | - type: textarea
15 | id: reproduction
16 | attributes:
17 | label: Reproduction steps
18 | description: "How do you trigger this bug? If possible, please provide a minimal reproducible example."
19 | placeholder: |
20 | 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:
21 | 1.
22 | 2.
23 | 3.
24 | validations:
25 | required: true
26 | - type: input
27 | id: version
28 | attributes:
29 | label: Version number
30 | description: "What was the latest version (or branch) of RAFFLE is the bug reproducible in?"
31 | placeholder: 1.0.0
32 | validations:
33 | required: true
34 | - type: input
35 | id: compiler
36 | attributes:
37 | label: Fortran compiler
38 | description: "What Fortran compiler (and version) was used?"
39 | placeholder: gfortran version 14.0
40 | validations:
41 | required: true
42 | - type: input
43 | id: platform
44 | attributes:
45 | label: Platform and Architecture
46 | description: "What architecture and operating system was the bug encountered on?"
47 | placeholder: macOS/ARM 10.14
48 | validations:
49 | required: true
50 | - type: checkboxes
51 | id: build
52 | attributes:
53 | label: Build method
54 | description: "What build methods was this issue encountered with?"
55 | options:
56 | - label: fpm
57 | - label: cmake
58 | - label: pip
59 | - type: textarea
60 | id: additional
61 | attributes:
62 | label: Additional information
63 | placeholder: Any further relevant context, i.e. screenshots, links to other issues, version number of build method.
64 | validations:
65 | required: false
--------------------------------------------------------------------------------
/tools/database.py:
--------------------------------------------------------------------------------
1 | # %%
2 | #Imports MPRester
3 | # from mp_api.client import MPRester
4 | from ase import Atoms
5 | from ase.io import write, read
6 | from pymatgen.io.ase import AseAtomsAdaptor
7 | from mp_api.client import MPRester
8 |
9 |
10 | # %%
11 | # Personal api key for accessing materials project api
12 | # This is unique to each user
13 | # api_key = ""
14 |
15 | # %%
16 | #Gets the ID of materials we want. Ba is all structures with only Ba. Ba-O is all structures with only Ba and O, not only BaO.
17 |
18 | mpr = MPRester() # MPRester(api_key)
19 | materials = []
20 |
21 | materials.append(mpr.materials.summary.search(chemsys="C",
22 | fields=["material_id","structure", "energy_per_atom", "nsites"]))
23 | materials.append(mpr.materials.summary.search(chemsys="Mg",
24 | fields=["material_id","structure", "energy_per_atom", "nsites"]))
25 | materials.append(mpr.materials.summary.search(chemsys="O",
26 | fields=["material_id","structure", "energy_per_atom", "nsites"]))
27 | materials.append(mpr.materials.summary.search(chemsys="C-Mg",
28 | fields=["material_id","structure", "energy_per_atom", "nsites"]))
29 | materials.append(mpr.materials.summary.search(chemsys="C-O",
30 | fields=["material_id","structure", "energy_per_atom", "nsites"]))
31 | materials.append(mpr.materials.summary.search(chemsys="Mg-O",
32 | fields=["material_id","structure", "energy_per_atom", "nsites"]))
33 |
34 |
35 | # %%
36 | structures = []
37 | energies = []
38 | nsites = []
39 | for material_set in materials:
40 | for material in material_set:
41 | material_id = material.material_id
42 | structures.append(mpr.get_structure_by_material_id(material_id))
43 | energies.append(material.energy_per_atom)
44 | nsites.append(material.nsites)
45 |
46 | # %%
47 | all_atoms = []
48 | for structure, energy, nsite in zip(structures, energies, nsites):
49 | atom = AseAtomsAdaptor.get_atoms(structure)
50 | atom.info['free_energy'] = energy * nsite
51 | atom.info['energy'] = energy * nsite
52 | all_atoms.append(atom)
53 | write("database.xyz", all_atoms, format='extxyz')
54 |
55 | # %%
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/tools/visualise_evaluator.py:
--------------------------------------------------------------------------------
1 | from mpl_toolkits.mplot3d import Axes3D
2 | from mpl_toolkits.mplot3d import proj3d
3 | import numpy as np
4 |
5 | import matplotlib.pyplot as plt
6 |
7 | # Read the data from the file
8 | data = []
9 | atoms = []
10 | with open('viability.dat', 'r') as file:
11 | for line in file:
12 | values = line.strip().split()
13 | if len(values) == 3:
14 | atoms.append([float(values[0]), float(values[1]), float(values[2])])
15 |
16 | if len(values) == 4:
17 | data.append([float(values[0]), float(values[1]), float(values[2]), float(values[3])])
18 |
19 | # Drop all rows with row[3] less than 0.2
20 | # data = [row for row in data if row[3] > 0.4] # for 4-body only
21 | max_val = max([row[3] for row in data])
22 | avg_val = sum([row[3] for row in data])/len(data)
23 | print(f"Max value: {max_val}")
24 | print(f"Avg value: {avg_val}")
25 |
26 | # Extract the coordinates and values
27 | x = [row[0] for row in data]
28 | y = [row[1] for row in data]
29 | z = [row[2] for row in data]
30 | # alpha = [row[3] for row in data]
31 | alpha = [(row[3]*100)*2 for row in data]
32 | alpha = [val/max(alpha) for val in alpha]
33 | # size = [(row[3]*10)**3 for row in data] # for 2-body only
34 | # size = [(row[3]*100)*2 for row in data] # for 2-body and 3-body
35 | # size = [row[3] for row in data] # for 4-body only
36 | # size = [(row[3]*2000) for row in data] # for all
37 | size = [(row[3]*1000) for row in data] # for all
38 |
39 | # Extract the atom coordinates
40 | atoms_x = [row[0] for row in atoms]
41 | atoms_y = [row[1] for row in atoms]
42 | atoms_z = [row[2] for row in atoms]
43 |
44 | # Plot the data on a 3D graph
45 | fig = plt.figure()
46 | ax = fig.add_subplot(111, projection='3d')
47 |
48 | x_scale=max(x)-min(x)
49 | y_scale=max(y)-min(y)
50 | z_scale=max(z)-min(z)
51 |
52 | scale=np.diag([x_scale, y_scale, z_scale, 1.0])
53 | scale=scale*(1.0/scale.max())
54 | scale[3,3]=1.0
55 |
56 | def short_proj():
57 | return np.dot(Axes3D.get_proj(ax), scale)
58 |
59 | ax.get_proj=short_proj
60 | ax.mouse_init()
61 |
62 |
63 | ax.scatter(atoms_x, atoms_y, atoms_z, c='red', alpha=1.0, s=200)
64 |
65 | # ax.scatter(x, y, z, alpha=alpha, c='black', s=size)
66 | ax.scatter(x, y, z, c=alpha, cmap='viridis', s=size)
67 | ax.set_xlabel('X')
68 | ax.set_ylabel('Y')
69 | ax.set_zlabel('Z')
70 | plt.show()
71 |
--------------------------------------------------------------------------------
/example/data/C-MgO_hosts/POSCAR_orthorhombic_11.1A_separation_Mg_seeded:
--------------------------------------------------------------------------------
1 | c1+mg1 o1
2 | 1.000000000
3 | 4.267773167 0.000000000 0.000000000
4 | -0.000000000 12.319999933 0.000000000
5 | 0.000000000 0.000000000 14.398580001
6 | C Mg
7 | 40 2
8 | Direct
9 | 0.000000000 0.000000000 0.000000000
10 | 0.000000000 0.200000000 0.000000000
11 | 0.000000000 0.400000000 0.000000000
12 | 0.000000000 0.600000000 0.000000000
13 | 0.000000000 0.800000000 0.000000000
14 | 0.500000000 0.100000000 0.000000000
15 | 0.500000000 0.300000000 0.000000000
16 | 0.500000000 0.500000000 0.000000000
17 | 0.500000000 0.700000000 0.000000000
18 | 0.500000000 0.900000000 0.000000000
19 | 0.000000000 0.000000000 0.766956196
20 | 0.000000000 0.200000000 0.766956196
21 | 0.000000000 0.400000000 0.766956196
22 | 0.000000000 0.600000000 0.766956196
23 | 0.000000000 0.800000000 0.766956196
24 | 0.500000000 0.100000000 0.766956196
25 | 0.500000000 0.300000000 0.766956196
26 | 0.500000000 0.500000000 0.766956196
27 | 0.500000000 0.700000000 0.766956196
28 | 0.500000000 0.900000000 0.766956196
29 | 0.333333342 1.000000000 0.000000000
30 | 0.333333342 0.200000000 0.000000000
31 | 0.333333342 0.400000000 0.000000000
32 | 0.333333342 0.600000000 0.000000000
33 | 0.333333342 0.800000000 0.000000000
34 | 0.833333342 0.100000000 0.000000000
35 | 0.833333342 0.300000000 0.000000000
36 | 0.833333342 0.500000000 0.000000000
37 | 0.833333342 0.700000000 0.000000000
38 | 0.833333342 0.900000000 0.000000000
39 | 0.166666657 0.100000000 0.766956196
40 | 0.166666657 0.300000000 0.766956196
41 | 0.166666657 0.500000000 0.766956196
42 | 0.166666657 0.700000000 0.766956196
43 | 0.166666657 0.900000000 0.766956196
44 | 0.666666657 0.000000000 0.766956196
45 | 0.666666657 0.200000000 0.766956196
46 | 0.666666657 0.400000000 0.766956196
47 | 0.666666657 0.600000000 0.766956196
48 | 0.666666657 0.800000000 0.766956196
49 | 0.500000000 0.500000000 0.384000000
50 | 0.500000000 0.250000000 0.192000000
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = [
3 | "f90wrap>=0.2.14,<=0.2.16",
4 | "numpy>=1.26.4,<=2.2",
5 | "meson~=1.6.0",
6 | "cython~=3.0.11",
7 | "scikit-build-core",
8 | ]
9 | build-backend = "scikit_build_core.build"
10 |
11 | [tool.scikit-build]
12 | cmake.version = "CMakeLists.txt"
13 | ninja.version = ">=1.10"
14 | cmake.build-type = "Release"
15 | cmake.source-dir = "."
16 | cmake.args = [
17 | "-DBUILD_PYTHON=On",
18 | "-DBUILD_EXECUTABLE=Off",
19 | "-DREMAKE_F90WRAP=Off",
20 | ]
21 | sdist.cmake = true
22 | wheel.cmake = true
23 | build-dir="build/{wheel_tag}"
24 | wheel.expand-macos-universal-tags = true
25 | ninja.make-fallback = true
26 | sdist.reproducible = true
27 | # dev purposes only
28 | build.verbose = false
29 |
30 | [project]
31 | name = "raffle"
32 | dynamic = ["version"]
33 | dependencies = [
34 | "ase>=3.23.0",
35 | "numpy>=1.26.4,<=2.2",
36 | "f90wrap>=0.2.14,<=0.2.16",
37 | ]
38 | requires-python = ">=3.11,<3.14"
39 | authors = [
40 | { name = "Ned Thaddeus Taylor", email = "n.t.taylor@exeter.ac.uk" },
41 | { name = "Joe Pitfield", email = "joepitfield@gmail.com" },
42 | { name = "Steven Paul Hepplestone", email = "s.p.hepplestone@exeter.ac.uk" },
43 | ]
44 | description = "A material interface structure prediction package"
45 | readme = "README.md"
46 | license = { text = 'GNU General Public License v3.0 or later'}
47 | classifiers = [
48 | "Development Status :: 5 - Production/Stable",
49 | "Intended Audience :: Science/Research",
50 | "Programming Language :: Python :: 3.11",
51 | "Programming Language :: Python :: 3.12",
52 | "Programming Language :: Python :: 3.13",
53 | "Programming Language :: Fortran",
54 | "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
55 | "Operating System :: OS Independent",
56 | ]
57 |
58 | [project.urls]
59 | Homepage = "https://github.com/ExeQuantCode/raffle"
60 | Documentation = "https://raffle-fortran.readthedocs.io/"
61 | Repository = "https://github.com/ExeQuantCode/raffle"
62 | Issues = "https://github.com/ExeQuantCode/raffle/issues"
63 |
64 | [project.optional-dependencies]
65 | tests = [
66 | "pytest",
67 | "pytest-cov",
68 | "parameterized",
69 | "unittest",
70 | ]
71 |
72 | [tool.scikit-build.metadata.version]
73 | provider = "scikit_build_core.metadata.regex"
74 | input = "fpm.toml"
75 | regex = '(?i)^version *= \"(?P.+?)\"'
76 |
--------------------------------------------------------------------------------
/example/python_pkg/Si-Ge_learn/abrupt_shifts.py:
--------------------------------------------------------------------------------
1 | # %%
2 | import os
3 | from pathlib import Path
4 | from ase.io import read, write
5 | from ase.visualize import view
6 | from ase.optimize import FIRE
7 | from ase.calculators.singlepoint import SinglePointCalculator
8 | from mace.calculators import mace_mp
9 | from artemis.generator import artemis_generator
10 |
11 | script_dir = Path(__file__).resolve().parent
12 |
13 | # %%
14 | abrupt = read(script_dir / 'SiGe_abrupt_interface_rescaled.vasp')
15 | abrupt.set_pbc(True)
16 |
17 | # %%
18 | generator = artemis_generator()
19 |
20 | # %%
21 | loc, axis = generator.get_interface_location(abrupt)
22 |
23 | # %%
24 | generator.set_shift_method(
25 | num_shifts = 20
26 | )
27 | # %%
28 | structures = generator.regenerate(abrupt, verbose=1)
29 |
30 | # %%
31 | # make directory for the structures
32 | output_dir = script_dir / "SiGe_shifted_structures"
33 | output_dir.mkdir(parents=True, exist_ok=True)
34 | for i, structure in enumerate(structures):
35 | write(output_dir / f'SiGe_shifted_{i}.vasp', structure, format='vasp', sort=True, direct=True)
36 |
37 | exit()
38 | # %%
39 |
40 | # check if mace file exists
41 | if not os.path.exists(script_dir / ".." / "mace-mpa-0-medium.model"):
42 | print("MACE-MPA-0 model file not found. Please download the model from the MACE website.")
43 | print("https://github.com/ACEsuit/mace-foundations/releases/tag/mace_mpa_0")
44 | exit(1)
45 |
46 | # set up the calculator
47 | calc_params = { 'model': script_dir / ".." / "mace-mpa-0-medium.model" }
48 | calc = mace_mp(**calc_params)
49 |
50 | # %%
51 | structures = [ abrupt.copy() ]
52 | structures.extend(generator.get_structures(calculator = calc))
53 |
54 | for structure in structures:
55 | structure.calc = calc
56 | structure.calc = SinglePointCalculator(
57 | structure,
58 | energy=structure.get_potential_energy(),
59 | forces=structure.get_forces()
60 | )
61 |
62 |
63 | write('SiGe_shifted_unrlxd.traj', structures)
64 |
65 | view(structures)
66 |
67 | # %%
68 |
69 | for structure in structures:
70 | structure.calc = calc
71 | optimizer = FIRE(structure)
72 | optimizer.run(fmax=0.05, steps=200)
73 | structure.calc = SinglePointCalculator(
74 | structure,
75 | energy=structure.get_potential_energy(),
76 | forces=structure.get_forces()
77 | )
78 |
79 | write('SiGe_shifted_rlxd.traj', structures)
80 |
--------------------------------------------------------------------------------
/tools/check_accuracy_C-Li.py:
--------------------------------------------------------------------------------
1 | import os
2 | import numpy as np
3 |
4 | ## import ASE (Atomic Simulation Environment) modules
5 | from ase import Atoms
6 | from ase.io import read, write
7 |
8 |
9 | ## load calculator
10 | calculator = "MACE"
11 | match calculator:
12 | case "CHGNet":
13 | from chgnet.model.dynamics import CHGNetCalculator
14 | print("Initialising CHGNet calculator")
15 | calc = CHGNetCalculator()
16 | label = "CHGNet"
17 | case "MACE":
18 | from mace.calculators import mace_mp
19 | print("Initialising MACE calculator")
20 | calc_params = { 'model': "../example/python_pkg/Si-Ge_learn/DRAFFLE/mace-mpa-0-medium.model" }
21 | calc = mace_mp(**calc_params)
22 | # calc = mace_mp(model="medium", dispersion=False, default_dtype="float32", device='cpu')
23 | label = "MACE"
24 |
25 | from ase.build import bulk
26 | Li = bulk("Li")
27 | Li.calc = calc
28 | print("Energy of Li:", Li.get_potential_energy() / len(Li))
29 |
30 | ## Read the database
31 | print("Reading database")
32 | database = read("../../../../DBig_database/Li-Carbon.xyz", index=":")
33 | # database = read("../example/data/carbon.xyz", index=":")
34 |
35 | C_host = database[0]
36 | C_host.calc = calc
37 | print("Energy of C_host:", C_host.get_potential_energy())
38 |
39 | ## Calculate the energies
40 | energies_dft = []
41 | energies_mlp = []
42 | for i, atoms in enumerate(database):
43 | if atoms.calc is None:
44 | database.remove(atoms)
45 | continue
46 | energies_dft.append(atoms.get_potential_energy()/len(atoms))
47 | atoms.calc = calc
48 | energies_mlp.append(atoms.get_potential_energy()/len(atoms))
49 | # if energies_mlp[-1] - energies_dft[-1] > 3e-1 and energies_mlp[-1] < -7.9:
50 | # print(f"Energy difference for structure {i} is {energies_mlp[-1] - energies_dft[-1]}, energy_mace: {energies_mlp[-1]}")
51 | # view(atoms)
52 |
53 |
54 | import matplotlib.pyplot as plt
55 |
56 | ## Write energies to a file
57 | with open("Li-C_energies_comparison.txt", "w") as f:
58 | f.write("# DFT_Energy_per_atom "+label+"_Energy_per_atom\n")
59 | for dft_energy, mace_energy in zip(energies_dft, energies_mlp):
60 | f.write(f"{dft_energy} {mace_energy}\n")
61 |
62 | ## Plot the energies
63 | plt.figure(figsize=(10, 6))
64 | plt.scatter(energies_dft, energies_mlp, c='blue', marker='o', label=label+' vs DFT')
65 | plt.show()
--------------------------------------------------------------------------------
/example/python_pkg/README.md:
--------------------------------------------------------------------------------
1 | # Python Package Example
2 |
3 | This directory contains example Python files demonstrating how to use the raffle package.
4 |
5 | ## Directory Structure
6 |
7 | ```
8 | python_pkg/
9 | ├── # Example with dataset containing global minimum from which to learn RAFFLE descriptors
10 | └── run.py # Script to test placement methods
11 | └── # Example with no prior database, i.e. RAFFLE starts with no prior knowledge
12 | ├── DRAFFLE # Directory containing example RAFFLE learning script
13 | ├── learn.py # Script to run RSS generating and learning
14 | └── pca.ipynb # Notebook to plot principal component analysis of RAFFLE results
15 | └── DRSS # Directory containing example random structure search script using AGOX
16 | ├── rss.py # Script to run RSS
17 | └── pca.ipynb # Notebook to plot principal component analysis of RSS results
18 | ```
19 |
20 | ## File Descriptions
21 |
22 | - `run.py`: Example script highlighting placement method capabilities
23 | - `learn.py`: Example script highlighting learning capabilties of RAFFLE
24 | - `pca.ipynb`: Notebook to generate principal component analysis of generated structures
25 |
26 | ## Execution Order
27 |
28 | To run a RAFFLE example and analyse the results, the following order must be performed.
29 | 1. Move to the desired `SYSTEM_learn/DRAFFLE` directory and create a directory to work in:
30 | ```bash
31 | cd SYSTEM_learn/DRAFFLE
32 | mkdir DOutput
33 | cd DOutput
34 | ```
35 |
36 | 2. Run the `learn.py` script:
37 | ```bash
38 | python ../learn.py
39 | ```
40 |
41 | 3. Go to parent directory and open the notebook `pca.ipynb`, run all the cells.
42 |
43 | NOTE: for the `C_learn/DRSS/` example, the `pca.ipynb` notebook expects that the `C_learn/DRAFFLE/` example script and notebook have been fully run first.
44 | This is because it attempts to use the PCA of the RAFFLE results to transform its data.
45 | Doing so enables the two techniques to be properly compared.
46 |
47 | The `[un]rlxd_structures_seed0.traj` files are provided (as are the `energies_[un]rlxd+seed0.txt`) as the key outputs from the `learn.py` runs.
48 | For the `rss.py` scripts, the `[un]rlxd_structures_seed0.traj` files are provided.
49 | Whilst other output files are generated during the RAFFLE runs, these are optional files with mostly redundant data.
50 |
51 | ## Prerequisites
52 |
53 | - Python 3.11 or higher
54 | - raffle package installed (`pip install .`)
55 | - `ase` for handling atomic structure data
56 | - `CHGNet`, `MACE`, `VASP`, or some other `ase`-compatible calculator
57 |
--------------------------------------------------------------------------------
/test/test_tools_infile.f90:
--------------------------------------------------------------------------------
1 | program test_tools_infile
2 | use raffle__constants, only: real32
3 | use raffle__tools_infile
4 | implicit none
5 |
6 |
7 | integer :: ival = 0
8 | logical :: ltmp1
9 | character(256) :: stmp1
10 | character(256) :: line
11 |
12 | logical :: success = .true.
13 |
14 |
15 | line = "APPLES = string"
16 | call assign_val(line, stmp1, ival, keyword="APPLES")
17 | if( trim(stmp1) .ne. "string" .or. ival .ne. 1 )then
18 | write(0,*) "assign_val failed for string"
19 | success = .false.
20 | end if
21 |
22 | line = "ORANGES = 1"
23 | call assign_val(line, ltmp1, ival, keyword="ORANGES")
24 | if( .not. ltmp1 .or. ival .ne. 2 )then
25 | write(0,*) "assign_val failed for logical"
26 | success = .false.
27 | end if
28 | line = "ORANGES = 0"
29 | call assign_val(line, ltmp1, ival, keyword="ORANGES")
30 | if( ltmp1 .or. ival .ne. 3 )then
31 | write(0,*) "assign_val failed for logical"
32 | success = .false.
33 | end if
34 | line = "ORANGES = T"
35 | call assign_val(line, ltmp1, ival, keyword="ORANGES")
36 | if( .not. ltmp1 .or. ival .ne. 4 )then
37 | write(0,*) "assign_val failed for logical"
38 | success = .false.
39 | end if
40 | line = "ORANGES = F"
41 | call assign_val(line, ltmp1, ival, keyword="ORANGES")
42 | if( ltmp1 .or. ival .ne. 5 )then
43 | write(0,*) "assign_val failed for logical"
44 | success = .false.
45 | end if
46 | line = "ORANGES = t"
47 | call assign_val(line, ltmp1, ival, keyword="ORANGES")
48 | if( .not. ltmp1 .or. ival .ne. 6 )then
49 | write(0,*) "assign_val failed for logical"
50 | success = .false.
51 | end if
52 | line = "ORANGES = f"
53 | call assign_val(line, ltmp1, ival, keyword="ORANGES")
54 | if( ltmp1 .or. ival .ne. 7 )then
55 | write(0,*) "assign_val failed for logical"
56 | success = .false.
57 | end if
58 |
59 | line = "BANANAS = 1.0 # comment"
60 | ! ival = line number here
61 | call rm_comments(line, ival)
62 | if( trim(line) .ne. "BANANAS = 1.0")then
63 | write(0,*) "rm_comments failed"
64 | write(0,'("\",A,"\")') trim(line)
65 | success = .false.
66 | end if
67 |
68 |
69 | !-----------------------------------------------------------------------------
70 | ! check for any failed tests
71 | !-----------------------------------------------------------------------------
72 | write(*,*) "----------------------------------------"
73 | if(success)then
74 | write(*,*) 'test_tools_infile passed all tests'
75 | else
76 | write(0,*) 'test_tools_infile failed one or more tests'
77 | stop 1
78 | end if
79 |
80 |
81 |
82 | end program test_tools_infile
83 |
--------------------------------------------------------------------------------
/.github/workflows/python.yml:
--------------------------------------------------------------------------------
1 | name: run-python-build
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - main
7 | - development
8 | types:
9 | - opened
10 | - synchronize
11 | paths:
12 | - ".github/workflows/python.yml"
13 | - "CMakeLists.txt"
14 | - "pyproject.toml"
15 | - "src/*.py"
16 | - "**.f90"
17 | - "**.F90"
18 | workflow_dispatch:
19 |
20 | permissions:
21 | contents: read
22 | pages: write
23 | id-token: write
24 |
25 | concurrency:
26 | group: python
27 | cancel-in-progress: false
28 |
29 | jobs:
30 | build-and-test-python:
31 | environment:
32 | name: github-pages
33 | name: Build and test in debug mode
34 | runs-on: ${{ matrix.os }}
35 | strategy:
36 | fail-fast: false
37 | matrix:
38 | os: [ubuntu-latest, macos-latest]
39 | python-version: [ "3.11", "3.12", "3.13" ]
40 | toolchain:
41 | - {fortran-compiler: gcc, fc-version: 14}
42 | build_type: [Serial, Release]
43 |
44 | steps:
45 | - name: checkout repo
46 | uses: actions/checkout@v4
47 |
48 | - name: actions-setup-python ${{ matrix.python-version }}
49 | uses: actions/setup-python@v5
50 | with:
51 | python-version: ${{ matrix.python-version }}
52 |
53 | - name: actions-setup-cmake
54 | uses: jwlawson/actions-setup-cmake@v2.0.1
55 | with:
56 | cmake-version: '3.24.x'
57 |
58 | - uses: fortran-lang/setup-fortran@v1
59 | id: setup-fortran
60 | with:
61 | compiler: ${{ matrix.toolchain.fortran-compiler }}
62 | version: ${{ matrix.toolchain.fc-version }}
63 |
64 | - name: Install python dependencies
65 | run: |
66 | python --version
67 | python -m pip install pip-tools
68 | python -m pip install pytest
69 | python -m pip install parameterized
70 | python -m piptools compile -o requirements.txt pyproject.toml --all-build-deps
71 | python -m pip install -r requirements.txt
72 |
73 | - name: Install OpenMP runtime (Linux only)
74 | if: runner.os == 'Linux'
75 | run: sudo apt-get update && sudo apt-get install -y libgomp1
76 |
77 | - name: Build and install Python package with CMAKE_BUILD_TYPE=${{ matrix.build_type }}
78 | env:
79 | CMAKE_BUILD_TYPE: ${{ matrix.build_type }}
80 | run: |
81 | cmake --version
82 | echo "Building with CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
83 | python -m pip install ".[ase]" --config-settings="cmake.define.CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
84 |
85 | - name: Run tests
86 | run: |
87 | ${{ env.FC }} --version
88 | python -m pytest
89 |
--------------------------------------------------------------------------------
/docs/source/conf.py:
--------------------------------------------------------------------------------
1 | # Configuration file for the Sphinx documentation builder.
2 |
3 | # -- Project information
4 | import datetime
5 | import os
6 | import sys
7 |
8 | from unittest.mock import Mock
9 |
10 | MOCK_MODULES = ["raffle._raffle"] # List any other modules if needed
11 | sys.modules.update((mod_name, Mock()) for mod_name in MOCK_MODULES)
12 |
13 | # sys.path.insert(0, os.path.abspath(os.path.join('..', '..', 'src', 'raffle'))) # Sets the base path to find your modules
14 | sys.path.insert(0, os.path.abspath(os.path.join('..', '..', 'src'))) # Sets the base path to find your modules
15 |
16 | project = 'RAFFLE'
17 | copyright = f'{datetime.date.today().year}, RAFFLE-developers'
18 | # release = '1.0'
19 | # version = '1.0.0'
20 |
21 | # -- General configuration
22 | master_doc = 'index'
23 |
24 | # Identify the branch of the documentation
25 | on_rtd = os.environ.get('READTHEDOCS') == 'True'
26 | if on_rtd:
27 | git_branch = os.environ.get("READTHEDOCS_GIT_IDENTIFIER", "main")
28 | else:
29 | git_branch = "main" # or get from git directly with subprocess
30 |
31 | extensions = [
32 | 'sphinx.ext.duration',
33 | 'sphinx.ext.doctest',
34 | 'sphinx.ext.autodoc',
35 | 'sphinx.ext.autosummary',
36 | 'sphinx.ext.intersphinx',
37 | 'sphinxcontrib.bibtex',
38 | 'sphinx.ext.napoleon',
39 | 'sphinx.ext.viewcode',
40 | 'sphinx_rtd_theme',
41 | 'sphinx.ext.extlinks',
42 | ]
43 |
44 | extlinks = {
45 | 'git': ('https://github.com/ExeQuantCode/RAFFLE/blob/' + git_branch + '/%s', 'git: %s')
46 | }
47 |
48 | intersphinx_mapping = {
49 | 'python': ('https://docs.python.org/3/', None),
50 | 'sphinx': ('https://www.sphinx-doc.org/en/master/', None),
51 | }
52 | intersphinx_disabled_domains = ['std']
53 |
54 | templates_path = ['_templates']
55 |
56 | exclude_patterns = ['_build', '.DS_Store', 'build']
57 |
58 |
59 | # -- Options for HTML output
60 |
61 | html_theme = 'sphinx_rtd_theme'
62 |
63 | # -- Options for EPUB output
64 | epub_show_urls = 'footnote'
65 |
66 | html_logo = "RAFFLE_logo_no_background.png"
67 | # html_favicon = 'favicon.ico'
68 | html_theme_options = {
69 | 'logo_only': False,
70 | 'prev_next_buttons_location': 'bottom',
71 | 'style_external_links': False,
72 | 'vcs_pageview_mode': '',
73 | # 'style_nav_header_background': 'white',
74 | 'flyout_display': 'hidden',
75 | 'version_selector': True,
76 | 'language_selector': True,
77 | # Toc options
78 | 'collapse_navigation': True,
79 | 'sticky_navigation': True,
80 | 'navigation_depth': 4,
81 | 'includehidden': True,
82 | 'titles_only': False,
83 | }
84 |
85 |
86 | html_context = {
87 | "display_github": True,
88 | "github_repo": "RAFFLE",
89 | "github_user": "ExeQuantCode",
90 | "github_version": "main",
91 | "conf_py_path": "/docs/source/",
92 | }
93 |
94 | autoclass_content="both"
95 |
96 | bibtex_bibfiles = ['references.bib']
97 |
--------------------------------------------------------------------------------
/docs/source/index.rst:
--------------------------------------------------------------------------------
1 | ======
2 | RAFFLE
3 | ======
4 |
5 | RAFFLE (pseudoRandom Approach For Finding Local Energetic minima) is a Python and Fortran package for structure prediction applied to interfaces.
6 | RAFFLE can be utilised as a Python package, a Fortran library, or a standalone Fortran executable.
7 | The Python package provides a high-level interface to the Fortran library, which contains the core functionality.
8 |
9 | The Python package interfaces seemlessly with `ASE (Atomic Simulation Environment) `_, allowing for easy reading, writing, and manipulation of atomic structures.
10 | 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.
11 |
12 | The code is provided freely available under the `GNU General Public License v3.0 `_.
13 |
14 | An example
15 |
16 | .. code-block:: python
17 |
18 | # A simple example of how to use RAFFLE to generate 10 structures of diamond and write them to a single file
19 | from ase import Atoms
20 | from ase.io import write
21 | from ase.calculators.singlepoint import SinglePointCalculator
22 | from raffle.generator import raffle_generator
23 | from mace.calculators import mace_mp
24 |
25 | generator = raffle_generator()
26 | generator.distributions.set_history_len(10)
27 | calc = mace_mp(model="medium", dispersion=False, default_dtype="float32", device='cpu')
28 |
29 | host = Atoms('C', positions=[[0, 0, 0]], cell=[10, 10, 10])
30 | host.calc = calc
31 | generator.set_host(host)
32 |
33 | generator.distributions.set_element_energies( { 'C': 0.0 } )
34 | generator.distributions.create(host)
35 |
36 | num_structures_old = 0
37 | for i in range(10):
38 | structures = generator.generate(
39 | num_structures = 2,
40 | stoichiometry = { 'C': 7 }
41 | )
42 | for structure in structures:
43 | optimiser = FIRE(structure)
44 | optimiser.run(fmax=0.05)
45 |
46 | generator.distributions.update(structures)
47 | num_structures_old += len(structures)
48 | if generator.distributions.is_converged():
49 | break
50 |
51 | structures = generator.get_structures(calc)
52 | for structure in structures:
53 | structure.calc = SinglePointCalculator(
54 | structure,
55 | energy=structure.get_potential_energy(),
56 | forces=structure.get_forces()
57 | )
58 |
59 | write('structures.traj', structures)
60 |
61 | .. toctree::
62 | :maxdepth: 3
63 | :caption: Contents:
64 |
65 | about
66 | install
67 | tutorials/index
68 | faq
69 | Python API
70 |
71 | .. Indices and tables
72 | .. ==================
73 |
74 | .. * :ref:`genindex`
75 | .. * :ref:`modindex`
76 | .. * :ref:`search`
77 |
--------------------------------------------------------------------------------
/example/python_pkg/benchmarks/min_placement.py:
--------------------------------------------------------------------------------
1 | import os
2 | nthreads = 1
3 | os.environ["OMP_NUM_THREADS"] = str(nthreads)
4 | os.environ["OPENBLAS_NUM_THREADS"] = str(nthreads)
5 | os.environ["MKL_NUM_THREADS"] = str(nthreads)
6 |
7 | import pytest
8 | import time
9 | import numpy as np
10 | from ase import Atoms
11 | from chgnet.model import CHGNetCalculator
12 | from raffle.generator import raffle_generator
13 |
14 |
15 | @pytest.mark.parametrize("kBT", [0.4])
16 | @pytest.mark.parametrize("width", [
17 | [0.025, np.pi/200.0, np.pi/200.0]
18 | ])
19 | @pytest.mark.parametrize("grid_spacing", [0.5, 0.25, 0.1, 0.075, 0.05])
20 | @pytest.mark.benchmark(
21 | group="min_placement",
22 | min_rounds=5,
23 | timer=time.time,
24 | disable_gc=True,
25 | warmup=False
26 | )
27 | def test_min_placement(benchmark, grid_spacing, kBT, width):
28 |
29 | calc = CHGNetCalculator()
30 | host = Atoms('C', positions=[(0, 0, 0)], cell=[3.567, 3.567, 3.567], pbc=True, calculator=calc)
31 |
32 | # Initialize generator
33 | generator = raffle_generator()
34 |
35 | # set energy scale
36 | generator.distributions.set_kBT(kBT)
37 |
38 | # set the distribution function widths (2-body, 3-body, 4-body)
39 | generator.distributions.set_width(width)
40 |
41 | energies = {element: 0.0 for element in ['C']}
42 | generator.distributions.set_element_energies(energies)
43 |
44 | generator.set_grid(grid_spacing=grid_spacing)
45 | generator.set_host(host)
46 |
47 | initial_database = [Atoms('C', positions=[(0, 0, 0)], cell=[8, 8, 8], pbc=True, calculator=calc)]
48 |
49 | generator.distributions.create(initial_database)
50 |
51 | benchmark.extra_info = {
52 | "kBT": kBT,
53 | "width": width,
54 | "grid_spacing": grid_spacing
55 | }
56 |
57 |
58 | # Measure time for distributions.create()
59 | result = benchmark(generator.generate,
60 | num_structures = 1,
61 | stoichiometry = {'C': 1},
62 | seed = 0,
63 | method_ratio = {
64 | 'void': 0.0,
65 | 'rand': 0.0,
66 | 'walk': 0.0,
67 | 'grow': 0.0,
68 | 'min': 1.0
69 |
70 | },
71 | verbose = 0
72 | )
73 |
74 | return result
75 |
76 | if __name__ == '__main__':
77 | grid_spacings = [0.5, 0.25, 0.1, 0.075, 0.05]
78 | results = []
79 |
80 | for grid_spacing in grid_spacings:
81 | for _ in range(5): # Run the benchmark 5 times for each grid size
82 | result = test_min_placement(lambda x: x, grid_spacing, 0.4, [0.025, np.pi/200.0, np.pi/200.0])
83 | results.append({
84 | 'grid_spacing': grid_spacing,
85 | 'time': result
86 | })
87 |
88 | # Print results
89 | print("\nBenchmark Results:")
90 | print("-" * 40)
91 | print(f"{'Grid Size':<10} {'Time (s)':<10}")
92 | print("-" * 40)
93 | for result in results:
94 | print(f"{result['grid_spacing']:<10} {result['time']:<10.4f}")
95 |
--------------------------------------------------------------------------------
/src/fortran/lib/mod_io_utils.F90:
--------------------------------------------------------------------------------
1 | module raffle__io_utils
2 | !! Module for handling errors and io calls in the program.
3 | !!
4 | !! This module provides the expected procedure for stopping a program.
5 | !! If in testing mode, the stop can be suppressed.
6 | implicit none
7 | logical :: test_error_handling = .false.
8 |
9 | logical :: suppress_warnings = .false.
10 | character(len=*), parameter :: raffle__version__ = "1.1.1"
11 |
12 | private
13 |
14 | public :: raffle__version__
15 | public :: test_error_handling, suppress_warnings
16 | public :: stop_program, print_warning
17 | public :: print_version, print_build_info
18 |
19 |
20 | contains
21 |
22 | !###############################################################################
23 | subroutine stop_program(message, exit_code, block_stop)
24 | !! Stop the program and print an error message.
25 | implicit none
26 | character(len=*), intent(in) :: message
27 | integer, intent(in), optional :: exit_code
28 | logical, intent(in), optional :: block_stop
29 |
30 | integer :: exit_code_
31 | logical :: block_stop_
32 |
33 | if(present(exit_code)) then
34 | exit_code_ = exit_code
35 | else
36 | exit_code_ = 1
37 | end if
38 | if(present(block_stop)) then
39 | block_stop_ = block_stop
40 | else
41 | block_stop_ = .false.
42 | end if
43 |
44 | write(0,*) 'ERROR: ', trim(message)
45 | if(.not.block_stop_)then
46 | if(.not.test_error_handling) then
47 | stop exit_code_
48 | end if
49 | end if
50 | end subroutine stop_program
51 | !###############################################################################
52 |
53 |
54 | !###############################################################################
55 | subroutine print_warning(message)
56 | !! Print a warning message
57 | implicit none
58 | character(len=*), intent(in) :: message
59 |
60 | if(.not.suppress_warnings) then
61 | write(0,*) 'WARNING: ', trim(message)
62 | end if
63 | end subroutine print_warning
64 | !###############################################################################
65 |
66 |
67 | !###############################################################################
68 | subroutine print_version()
69 | !! Print the version number of the program.
70 | implicit none
71 |
72 | write(*,'("version: ",A)') raffle__version__
73 | end subroutine print_version
74 | !###############################################################################
75 |
76 |
77 | !###############################################################################
78 | subroutine print_build_info()
79 | !! Print the build information of the program.
80 | implicit none
81 |
82 | write(*,'("RAFFLE: pseudoRandom Approach For Finding Local Energy minima")')
83 | call print_version()
84 | write(*,'(" (build ",A,1X,A,")")') __DATE__, __TIME__
85 |
86 | end subroutine print_build_info
87 | !###############################################################################
88 |
89 | end module raffle__io_utils
90 |
--------------------------------------------------------------------------------
/src/fortran/lib/mod_misc_maths.f90:
--------------------------------------------------------------------------------
1 | module raffle__misc_maths
2 | !! Module for miscellaneous mathematical functions.
3 | use raffle__io_utils, only: stop_program
4 | use raffle__constants, only: real32
5 | implicit none
6 |
7 |
8 | private
9 |
10 | public :: lnsum, triangular_number, set_difference
11 |
12 |
13 |
14 | contains
15 |
16 | !###############################################################################
17 | function lnsum(n)
18 | !! Return the sum of the logs of the integers from 1 to n.
19 | implicit none
20 |
21 | ! Arguments
22 | integer :: n
23 | !! The upper limit of the range.
24 | real(real32) :: lnsum
25 | !! The sum of the logs of the integers from 1 to n.
26 |
27 | ! Local variables
28 | integer :: i
29 | !! Loop index.
30 |
31 | lnsum = 0._real32
32 | do i = 1, n
33 | lnsum = lnsum + log( real(i, real32) )
34 | end do
35 |
36 | return
37 | end function lnsum
38 | !###############################################################################
39 |
40 |
41 | !###############################################################################
42 | pure function triangular_number(n) result(output)
43 | !! Return the nth triangular number.
44 | implicit none
45 |
46 | ! Arguments
47 | integer, intent(in) :: n
48 | !! The index of the triangular number to return.
49 |
50 | integer :: output
51 | !! The nth triangular number.
52 |
53 | output = n * ( n + 1 ) / 2
54 | end function triangular_number
55 | !###############################################################################
56 |
57 |
58 | !###############################################################################
59 | function set_difference(a, b, set_min_zero)
60 | !! Return the set difference of two arrays.
61 | implicit none
62 |
63 | ! Arguments
64 | real(real32), dimension(:), intent(in) :: a
65 | !! The first array.
66 | real(real32), dimension(:), intent(in) :: b
67 | !! The second array.
68 | logical, optional :: set_min_zero
69 | !! Boolean to set the maximum value of the output array to zero.
70 | real(real32), dimension(size(a)) :: set_difference
71 | !! The set difference of the two arrays.
72 |
73 | ! Local variables
74 | integer :: i
75 | !! Loop indices.
76 | logical :: set_min_zero_
77 | !! Boolean to set all values below zero to zero.
78 |
79 |
80 | if(present(set_min_zero)) then
81 | set_min_zero_ = set_min_zero
82 | else
83 | set_min_zero_ = .false.
84 | end if
85 |
86 | if(size(a,1) .ne. size(b,1)) then
87 | call stop_program('Arrays must be the same size.')
88 | return
89 | end if
90 |
91 | if(set_min_zero_)then
92 | do i = 1, size(a,1)
93 | set_difference(i) = max(0.0_real32, a(i) - b(i))
94 | end do
95 | else
96 | set_difference = a - b
97 | end if
98 |
99 | end function set_difference
100 | !###############################################################################
101 |
102 | end module raffle__misc_maths
103 |
--------------------------------------------------------------------------------
/tools/check_accuracy_C.py:
--------------------------------------------------------------------------------
1 | import os
2 | import numpy as np
3 |
4 | ## import ASE (Atomic Simulation Environment) modules
5 | from ase import Atoms
6 | from ase.io import read, write
7 |
8 |
9 | ## load calculator
10 | from chgnet.model.dynamics import CHGNetCalculator
11 | print("Initialising CHGNet calculator")
12 | chgnet = CHGNetCalculator()
13 | from mace.calculators import mace_mp
14 | print("Initialising MACE calculator")
15 | calc_params = { 'model': "../example/python_pkg/mace-mpa-0-medium.model" }
16 | mace = mace_mp(**calc_params)
17 | # calc = mace_mp(model="medium", dispersion=False, default_dtype="float32", device='cpu')
18 |
19 | ## Read the database
20 | print("Reading database")
21 | database = read("../example/data/carbon.xyz", index=":")
22 |
23 | # get index of lowest energy structure
24 | lowest_energy_index = np.argmin([
25 | atoms.get_potential_energy() if atoms.calc is not None else float('inf')
26 | for atoms in database
27 | ])
28 | C_energy_dft = database[lowest_energy_index].get_potential_energy() / len(database[lowest_energy_index])
29 | C_ground_state = database[lowest_energy_index].copy()
30 | C_ground_state.calc = chgnet
31 | C_energy_chgnet = C_ground_state.get_potential_energy() / len(C_ground_state)
32 | C_ground_state.calc = mace
33 | C_energy_mace = C_ground_state.get_potential_energy() / len(C_ground_state)
34 |
35 |
36 | ## Calculate the energies
37 | energies_dft = []
38 | energies_mace = []
39 | energies_chgnet = []
40 | formation_energies_dft = []
41 | formation_energies_mace = []
42 | formation_energies_chgnet = []
43 | for i, atoms in enumerate(database):
44 | if atoms.calc is None:
45 | database.remove(atoms)
46 | continue
47 | formation_energy_dft = atoms.get_potential_energy() / len(atoms) - C_energy_dft
48 | formation_energies_dft.append(formation_energy_dft)
49 | energies_dft.append(atoms.get_potential_energy()/len(atoms))
50 | atoms.calc = chgnet
51 | formation_energy_chgnet = atoms.get_potential_energy() / len(atoms) - C_energy_chgnet
52 | formation_energies_chgnet.append(formation_energy_chgnet)
53 | energies_chgnet.append(atoms.get_potential_energy()/len(atoms))
54 | atoms.calc = mace
55 | formation_energy_mace = atoms.get_potential_energy() / len(atoms) - C_energy_mace
56 | formation_energies_mace.append(formation_energy_mace)
57 | energies_mace.append(atoms.get_potential_energy()/len(atoms))
58 |
59 |
60 | import matplotlib.pyplot as plt
61 |
62 | ## Write energies to a file
63 | with open("C_energies_comparison.txt", "w") as f:
64 | f.write("# DFT_Energy_per_atom MACE-MPA-0_Energy_per_atom CHGNet_Energy_per_atom\n")
65 | for dft_energy, mace_energy, chgnet_energy in zip(energies_dft, energies_mace, energies_chgnet):
66 | f.write(f"{dft_energy} {mace_energy} {chgnet_energy}\n")
67 |
68 | with open("C_formations_comparison.txt", "w") as f:
69 | f.write("# DFT_Formation_energy_per_atom MACE-MPA-0_Formation_energy_per_atom CHGNet_Formation_energy_per_atom\n")
70 | for dft_energy, mace_energy, chgnet_energy in zip(formation_energies_dft, formation_energies_mace, formation_energies_chgnet):
71 | f.write(f"{dft_energy} {mace_energy} {chgnet_energy}\n")
72 |
73 | ## Plot the energies
74 | plt.figure(figsize=(10, 6))
75 | plt.scatter(energies_dft, energies_mace, c='blue', marker='o', label='MLIP vs DFT')
76 | plt.show()
--------------------------------------------------------------------------------
/example/python_pkg/benchmarks/placement_methods.py:
--------------------------------------------------------------------------------
1 | import os
2 | nthreads = 1
3 | os.environ["OMP_NUM_THREADS"] = str(nthreads)
4 | os.environ["OPENBLAS_NUM_THREADS"] = str(nthreads)
5 | os.environ["MKL_NUM_THREADS"] = str(nthreads)
6 |
7 | import pytest
8 | import time
9 | import numpy as np
10 | from ase import Atoms
11 | from chgnet.model import CHGNetCalculator
12 | from raffle.generator import raffle_generator
13 |
14 |
15 | @pytest.mark.parametrize("kBT", [0.4])
16 | @pytest.mark.parametrize("width", [
17 | [0.025, np.pi/200.0, np.pi/200.0]
18 | ])
19 | @pytest.mark.parametrize("grid_spacing", [0.5, 0.25, 0.1, 0.075, 0.05])
20 | @pytest.mark.parametrize("method_ratio", [
21 | {'void': 0.0, 'rand': 0.0, 'walk': 0.0, 'grow': 0.0, 'min': 1.0},
22 | {'void': 0.0, 'rand': 0.0, 'walk': 0.0, 'grow': 1.0, 'min': 0.0},
23 | {'void': 0.0, 'rand': 0.0, 'walk': 1.0, 'grow': 0.0, 'min': 0.0},
24 | {'void': 0.0, 'rand': 1.0, 'walk': 0.0, 'grow': 0.0, 'min': 0.0},
25 | {'void': 1.0, 'rand': 0.0, 'walk': 0.0, 'grow': 0.0, 'min': 0.0}
26 | ])
27 | @pytest.mark.benchmark(
28 | group="placement_methods",
29 | min_rounds=5,
30 | timer=time.time,
31 | disable_gc=True,
32 | warmup=False
33 | )
34 | def test_placement_methods(benchmark, grid_spacing, kBT, width, method_ratio):
35 |
36 | calc = CHGNetCalculator()
37 | host = Atoms('C', positions=[(0, 0, 0)], cell=[3.567, 3.567, 3.567], pbc=True, calculator=calc)
38 |
39 | # Initialize generator
40 | generator = raffle_generator()
41 |
42 | # set energy scale
43 | generator.distributions.set_kBT(kBT)
44 |
45 | # set the distribution function widths (2-body, 3-body, 4-body)
46 | generator.distributions.set_width(width)
47 |
48 | energies = {element: 0.0 for element in ['C']}
49 | generator.distributions.set_element_energies(energies)
50 |
51 | generator.set_grid(grid_spacing=grid_spacing)
52 | generator.set_host(host)
53 |
54 | initial_database = [Atoms('C', positions=[(0, 0, 0)], cell=[8, 8, 8], pbc=True, calculator=calc)]
55 |
56 | generator.distributions.create(initial_database)
57 |
58 | benchmark.extra_info = {
59 | "kBT": kBT,
60 | "width": width,
61 | "grid_spacing": grid_spacing,
62 | "method_ratio": method_ratio
63 | }
64 |
65 | # Measure time for distributions.create()
66 | result = benchmark(generator.generate,
67 | num_structures = 1,
68 | stoichiometry = {'C': 1},
69 | seed = 0,
70 | method_ratio = method_ratio,
71 | verbose = 0
72 | )
73 |
74 | return result
75 |
76 | if __name__ == '__main__':
77 | grid_spacings = [0.5, 0.25, 0.1, 0.075, 0.05]
78 | results = []
79 |
80 | for grid_spacing in grid_spacings:
81 | for _ in range(5): # Run the benchmark 5 times for each grid size
82 | result = test_placement_methods(lambda x: x, grid_spacing, 0.4, [0.025, np.pi/200.0, np.pi/200.0])
83 | results.append({
84 | 'grid_spacing': grid_spacing,
85 | 'time': result
86 | })
87 |
88 | # Print results
89 | print("\nBenchmark Results:")
90 | print("-" * 40)
91 | print(f"{'Grid Size':<10} {'Time (s)':<10}")
92 | print("-" * 40)
93 | for result in results:
94 | print(f"{result['grid_spacing']:<10} {result['time']:<10.4f}")
95 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Code of Conduct - RAFFLE
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to make participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to a positive environment for our
15 | community include:
16 |
17 | * Demonstrating empathy and kindness toward other people
18 | * Being respectful of differing opinions, viewpoints, and experiences
19 | * Giving and gracefully accepting constructive feedback
20 | * Accepting responsibility and apologising to those affected by our mistakes,
21 | and learning from the experience
22 | * Focusing on what is best not just for us as individuals, but for the
23 | overall community
24 |
25 | Examples of unacceptable behavior include:
26 |
27 | * The use of sexualised language or imagery, and sexual attention or
28 | advances
29 | * Trolling, insulting or derogatory comments, and personal or political attacks
30 | * Public or private harassment
31 | * Publishing others' private information, such as a physical or email
32 | address, without their explicit permission
33 | * Other conduct which could reasonably be considered inappropriate in a
34 | professional setting
35 |
36 | ## Our Responsibilities
37 |
38 | Project maintainers are responsible for clarifying and enforcing our standards of
39 | acceptable behavior and will take appropriate and fair corrective action in
40 | response to any instances of unacceptable behavior.
41 |
42 | Project maintainers have the right and responsibility to remove, edit, or reject
43 | comments, commits, code, wiki edits, issues, and other contributions that are
44 | not aligned to this Code of Conduct, or to ban
45 | temporarily or permanently any contributor for other behaviors that they deem
46 | inappropriate, threatening, offensive, or harmful.
47 |
48 | ## Scope
49 |
50 | This Code of Conduct applies within all community spaces, and also applies when
51 | an individual is officially representing the community in public spaces.
52 | Examples of representing our community include using an official e-mail address,
53 | posting via an official social media account, or acting as an appointed
54 | representative at an online or offline event.
55 |
56 | ## Enforcement
57 |
58 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
59 | reported to the community leaders responsible for enforcement at .
60 | All complaints will be reviewed and investigated promptly and fairly.
61 |
62 | All community leaders are obligated to respect the privacy and security of the
63 | reporter of any incident.
64 |
65 | ## Attribution
66 |
67 | This Code of Conduct is adapted from the [Contributor Covenant](https://contributor-covenant.org/), version
68 | [1.4](https://www.contributor-covenant.org/version/1/4/code-of-conduct/code_of_conduct.md) and
69 | [2.0](https://www.contributor-covenant.org/version/2/0/code_of_conduct/code_of_conduct.md),
70 | and was generated by [contributing-gen](https://github.com/bttger/contributing-gen).
71 |
--------------------------------------------------------------------------------
/docs/source/tutorials/aluminium_tutorial.rst:
--------------------------------------------------------------------------------
1 | .. aluminium:
2 |
3 | ==================
4 | Aluminium tutorial
5 | ==================
6 |
7 | This tutorial will guide you through the process of performing RAFFLE-based structure search for the bulk phases of aluminium.
8 |
9 | The tutorial is designed to show how a RAFFLE generator given no prior knowledge can learn bonding and identify known phases.
10 | This is not an expected use-case of RAFFLE due to its application to a bulk system, but still demonstrates the expected workflow and capabilities.
11 |
12 | The example script can be found in the following directory:
13 |
14 | .. code-block:: bash
15 |
16 | raffle/example/python_pkg/Al_learn/DRAFFLE/learn.py
17 |
18 | We recommend reading through the file and running it to understand the process of learning and generating structures.
19 | However, we will provide a brief overview of the script here.
20 |
21 | First, we must import the required packages:
22 |
23 | .. code-block:: python
24 |
25 | from ase import Atoms
26 | from raffle.generator import raffle_generator
27 | from chgnet.model import CHGNetCalculator
28 | import numpy as np
29 |
30 | Next, we need to set up the RAFFLE generator and the calculator to calculate the energies of the structures.
31 | In this example, we use the CHGNet calculator:
32 |
33 | .. code-block:: python
34 |
35 | generator = raffle_generator()
36 |
37 | calc = CHGNetCalculator()
38 |
39 | Then, we need to create the host structure.
40 | Here, a set of host cells are generated to represent the multiple potential bulk phases of aluminium.
41 | These are then used to generate the structures.
42 |
43 | .. code-block:: python
44 |
45 | crystal_structures = ['orthorhombic', 'hcp']
46 | hosts = []
47 | for crystal_structure in crystal_structures:
48 | for a in np.linspace(3.1, 5.4, num=6):
49 | atom = build.bulk(
50 | name = 'Al',
51 | crystalstructure = crystal_structure,
52 | a = a, b = a, c = a,
53 | )
54 | hosts.append(Atoms(
55 | 'Al',
56 | positions = [(0, 0, 0)],
57 | cell = atom.get_cell(),
58 | pbc = True,
59 | calculator = calc
60 | ))
61 |
62 | The script then sets parameters for the generator and provides an initial database.
63 | Note, this database is effectively empty, as it only contains a single structure, which is an isolated aluminium atom.
64 |
65 | .. code-block:: python
66 |
67 | initial_database = [Atoms('Al', positions=[(0, 0, 0)], cell=[8, 8, 8], pbc=True)]
68 | initial_database[0].calc = calc
69 | generator.distributions.create(initial_database)
70 |
71 | Finally, the script generates structures using the generator.
72 | The generator is given the host structures.
73 | Finally, the generator is run for each host structure, providing a unique stoichiometry each time and using a custom method ratio.
74 |
75 | .. code-block:: python
76 |
77 | for host in hosts:
78 | generator.set_host(host)
79 | generator.generate(
80 | num_structures = 5,
81 | stoichiometry = { 'Al': num_atoms },
82 | method_ratio = {"void": 0.5, "rand": 0.001, "walk": 0.5, "grow": 0.0, "min": 1.0},
83 | )
84 |
85 | structures = generator.get_structures()
86 | write('structures.traj', structures)
87 |
--------------------------------------------------------------------------------
/example/data/C-MgO_hosts/POSCAR_4x4_11.0A_separation:
--------------------------------------------------------------------------------
1 | c1
2 | 1.000000000
3 | 9.855999947 0.000000000 0.000000000
4 | -4.927999973 8.535546333 0.000000000
5 | 0.000000000 0.000000000 14.710999966
6 | C
7 | 64
8 | Direct
9 | 0.000000000 0.000000000 0.000000000
10 | 0.750000000 0.000000000 0.000000000
11 | 0.000000000 0.750000000 0.000000000
12 | 0.750000000 0.750000000 0.000000000
13 | 0.250000000 0.000000000 0.000000000
14 | 0.250000000 0.750000000 0.000000000
15 | 0.500000000 0.000000000 0.000000000
16 | 0.500000000 0.750000000 0.000000000
17 | 0.000000000 0.250000000 0.000000000
18 | 0.750000000 0.250000000 0.000000000
19 | 0.250000000 0.250000000 0.000000000
20 | 0.500000000 0.250000000 0.000000000
21 | 0.000000000 0.500000000 0.000000000
22 | 0.750000000 0.500000000 0.000000000
23 | 0.250000000 0.500000000 0.000000000
24 | 0.500000000 0.500000000 0.000000000
25 | 0.000000000 0.000000000 0.749999982
26 | 0.750000000 0.000000000 0.749999982
27 | 0.000000000 0.750000000 0.749999982
28 | 0.750000000 0.750000000 0.749999982
29 | 0.250000000 0.000000000 0.749999982
30 | 0.250000000 0.750000000 0.749999982
31 | 0.500000000 0.000000000 0.749999982
32 | 0.500000000 0.750000000 0.749999982
33 | 0.000000000 0.250000000 0.749999982
34 | 0.750000000 0.250000000 0.749999982
35 | 0.250000000 0.250000000 0.749999982
36 | 0.500000000 0.250000000 0.749999982
37 | 0.000000000 0.500000000 0.749999982
38 | 0.750000000 0.500000000 0.749999982
39 | 0.250000000 0.500000000 0.749999982
40 | 0.500000000 0.500000000 0.749999982
41 | 0.083333335 0.166666671 0.000000000
42 | 0.833333335 0.166666671 0.000000000
43 | 0.083333335 0.916666671 0.000000000
44 | 0.833333335 0.916666671 0.000000000
45 | 0.333333335 0.166666671 0.000000000
46 | 0.333333335 0.916666671 0.000000000
47 | 0.583333335 0.166666671 0.000000000
48 | 0.583333335 0.916666671 0.000000000
49 | 0.083333335 0.416666671 0.000000000
50 | 0.833333335 0.416666671 0.000000000
51 | 0.333333335 0.416666671 0.000000000
52 | 0.583333335 0.416666671 0.000000000
53 | 0.083333335 0.666666671 0.000000000
54 | 0.833333335 0.666666671 0.000000000
55 | 0.333333335 0.666666671 0.000000000
56 | 0.583333335 0.666666671 0.000000000
57 | 0.166666664 0.083333329 0.749999982
58 | 0.916666664 0.083333329 0.749999982
59 | 0.166666664 0.833333329 0.749999982
60 | 0.916666664 0.833333329 0.749999982
61 | 0.416666664 0.083333329 0.749999982
62 | 0.416666664 0.833333329 0.749999982
63 | 0.666666665 0.083333329 0.749999982
64 | 0.666666665 0.833333329 0.749999982
65 | 0.166666664 0.333333329 0.749999982
66 | 0.916666664 0.333333329 0.749999982
67 | 0.416666664 0.333333329 0.749999982
68 | 0.666666665 0.333333329 0.749999982
69 | 0.166666664 0.583333328 0.749999982
70 | 0.916666664 0.583333328 0.749999982
71 | 0.416666664 0.583333328 0.749999982
72 | 0.666666665 0.583333328 0.749999982
73 |
--------------------------------------------------------------------------------
/example/data/C-MgO_hosts/POSCAR_4x4_14.7A_separation:
--------------------------------------------------------------------------------
1 | c1
2 | 1.000000000
3 | 9.855999947 0.000000000 0.000000000
4 | -4.927999973 8.535546333 0.000000000
5 | 0.000000000 0.000000000 18.388833288
6 | C
7 | 64
8 | Direct
9 | 0.000000000 0.000000000 0.000000000
10 | 0.750000000 0.000000000 0.000000000
11 | 0.000000000 0.750000000 0.000000000
12 | 0.750000000 0.750000000 0.000000000
13 | 0.250000000 0.000000000 0.000000000
14 | 0.250000000 0.750000000 0.000000000
15 | 0.500000000 0.000000000 0.000000000
16 | 0.500000000 0.750000000 0.000000000
17 | 0.000000000 0.250000000 0.000000000
18 | 0.750000000 0.250000000 0.000000000
19 | 0.250000000 0.250000000 0.000000000
20 | 0.500000000 0.250000000 0.000000000
21 | 0.000000000 0.500000000 0.000000000
22 | 0.750000000 0.500000000 0.000000000
23 | 0.250000000 0.500000000 0.000000000
24 | 0.500000000 0.500000000 0.000000000
25 | 0.000000000 0.000000000 0.800000892
26 | 0.750000000 0.000000000 0.800000892
27 | 0.000000000 0.750000000 0.800000892
28 | 0.750000000 0.750000000 0.800000892
29 | 0.250000000 0.000000000 0.800000892
30 | 0.250000000 0.750000000 0.800000892
31 | 0.500000000 0.000000000 0.800000892
32 | 0.500000000 0.750000000 0.800000892
33 | 0.000000000 0.250000000 0.800000892
34 | 0.750000000 0.250000000 0.800000892
35 | 0.250000000 0.250000000 0.800000892
36 | 0.500000000 0.250000000 0.800000892
37 | 0.000000000 0.500000000 0.800000892
38 | 0.750000000 0.500000000 0.800000892
39 | 0.250000000 0.500000000 0.800000892
40 | 0.500000000 0.500000000 0.800000892
41 | 0.083333335 0.166666671 0.000000000
42 | 0.833333335 0.166666671 0.000000000
43 | 0.083333335 0.916666671 0.000000000
44 | 0.833333335 0.916666671 0.000000000
45 | 0.333333335 0.166666671 0.000000000
46 | 0.333333335 0.916666671 0.000000000
47 | 0.583333335 0.166666671 0.000000000
48 | 0.583333335 0.916666671 0.000000000
49 | 0.083333335 0.416666671 0.000000000
50 | 0.833333335 0.416666671 0.000000000
51 | 0.333333335 0.416666671 0.000000000
52 | 0.583333335 0.416666671 0.000000000
53 | 0.083333335 0.666666671 0.000000000
54 | 0.833333335 0.666666671 0.000000000
55 | 0.333333335 0.666666671 0.000000000
56 | 0.583333335 0.666666671 0.000000000
57 | 0.166666664 0.083333329 0.800000892
58 | 0.916666664 0.083333329 0.800000892
59 | 0.166666664 0.833333329 0.800000892
60 | 0.916666664 0.833333329 0.800000892
61 | 0.416666664 0.083333329 0.800000892
62 | 0.416666664 0.833333329 0.800000892
63 | 0.666666665 0.083333329 0.800000892
64 | 0.666666665 0.833333329 0.800000892
65 | 0.166666664 0.333333329 0.800000892
66 | 0.916666664 0.333333329 0.800000892
67 | 0.416666664 0.333333329 0.800000892
68 | 0.666666665 0.333333329 0.800000892
69 | 0.166666664 0.583333328 0.800000892
70 | 0.916666664 0.583333328 0.800000892
71 | 0.416666664 0.583333328 0.800000892
72 | 0.666666665 0.583333328 0.800000892
73 |
--------------------------------------------------------------------------------
/tools/check_accuracy_MoS2.py:
--------------------------------------------------------------------------------
1 | import os
2 | import numpy as np
3 | from pathlib import Path
4 |
5 | script_dir = Path(__file__).resolve().parent
6 |
7 | ## import ASE (Atomic Simulation Environment) modules
8 | from ase import Atoms
9 | from ase.io import read, write
10 |
11 |
12 | ## load calculator
13 | from chgnet.model.dynamics import CHGNetCalculator
14 | print("Initialising CHGNet calculator")
15 | chgnet = CHGNetCalculator()
16 | from mace.calculators import mace_mp
17 | print("Initialising MACE calculator")
18 | calc_params = { 'model': "../example/python_pkg/mace-mpa-0-medium.model" }
19 | mace = mace_mp(**calc_params)
20 | # calc = mace_mp(model="medium", dispersion=False, default_dtype="float32", device='cpu')
21 |
22 | ## Read the database
23 | print("Reading database")
24 | database = read("../example/data/MoS2_vasp.xyz", index=":")
25 |
26 | # get index of lowest energy structure
27 | lowest_energy_index = np.argmin([
28 | atoms.get_potential_energy() if atoms.calc is not None else float('inf')
29 | for atoms in database
30 | ])
31 | MoS2_energy_dft = database[lowest_energy_index].get_potential_energy() / len(database[lowest_energy_index])
32 | MoS2_ground_state = database[lowest_energy_index].copy()
33 | MoS2_ground_state.calc = chgnet
34 | MoS2_energy_chgnet = MoS2_ground_state.get_potential_energy() / len(MoS2_ground_state)
35 | MoS2_ground_state.calc = mace
36 | MoS2_energy_mace = MoS2_ground_state.get_potential_energy() / len(MoS2_ground_state)
37 |
38 |
39 | ## Calculate the energies
40 | energies_dft = []
41 | energies_mace = []
42 | energies_chgnet = []
43 | formation_energies_dft = []
44 | formation_energies_mace = []
45 | formation_energies_chgnet = []
46 | for i, atoms in enumerate(database):
47 | if atoms.calc is None:
48 | database.remove(atoms)
49 | continue
50 | formation_energy_dft = atoms.get_potential_energy() / len(atoms) - MoS2_energy_dft
51 | formation_energies_dft.append(formation_energy_dft)
52 | energies_dft.append(atoms.get_potential_energy()/len(atoms))
53 | atoms.calc = chgnet
54 | formation_energy_chgnet = atoms.get_potential_energy() / len(atoms) - MoS2_energy_chgnet
55 | formation_energies_chgnet.append(formation_energy_chgnet)
56 | energies_chgnet.append(atoms.get_potential_energy()/len(atoms))
57 | atoms.calc = mace
58 | formation_energy_mace = atoms.get_potential_energy() / len(atoms) - MoS2_energy_mace
59 | formation_energies_mace.append(formation_energy_mace)
60 | energies_mace.append(atoms.get_potential_energy()/len(atoms))
61 |
62 |
63 | import matplotlib.pyplot as plt
64 |
65 | ## Write energies to a file
66 | with open("MoS2_energies_comparison.txt", "w") as f:
67 | f.write("# DFT_Energy_per_atom MACE-MPA-0_Energy_per_atom CHGNet_Energy_per_atom\n")
68 | for dft_energy, mace_energy, chgnet_energy in zip(energies_dft, energies_mace, energies_chgnet):
69 | f.write(f"{dft_energy} {mace_energy} {chgnet_energy}\n")
70 |
71 | with open("MoS2_formations_comparison.txt", "w") as f:
72 | f.write("# DFT_Formation_energy_per_atom MACE-MPA-0_Formation_energy_per_atom CHGNet_Formation_energy_per_atom\n")
73 | for dft_energy, mace_energy, chgnet_energy in zip(formation_energies_dft, formation_energies_mace, formation_energies_chgnet):
74 | f.write(f"{dft_energy} {mace_energy} {chgnet_energy}\n")
75 |
76 | ## Plot the energies
77 | plt.figure(figsize=(10, 6))
78 | plt.scatter(energies_dft, energies_mace, c='blue', marker='o', label='MLIP vs DFT')
79 | plt.show()
--------------------------------------------------------------------------------
/tools/check_accuracy_Al.py:
--------------------------------------------------------------------------------
1 | import os
2 | import numpy as np
3 |
4 | ## import ASE (Atomic Simulation Environment) modules
5 | from ase import Atoms
6 | from ase.io import read, write
7 |
8 |
9 | ## load calculator
10 | from chgnet.model.dynamics import CHGNetCalculator
11 | print("Initialising CHGNet calculator")
12 | chgnet = CHGNetCalculator()
13 | from mace.calculators import mace_mp
14 | print("Initialising MACE calculator")
15 | calc_params = { 'model': "../example/python_pkg/mace-mpa-0-medium.model" }
16 | mace = mace_mp(**calc_params)
17 | # calc = mace_mp(model="medium", dispersion=False, default_dtype="float32", device='cpu')
18 |
19 | ## Read the database
20 | print("Reading database")
21 | database = read("../example/data/aluminium.xyz", index=":")
22 |
23 | # get index of lowest energy structure
24 | lowest_energy_index = np.argmin([
25 | atoms.get_potential_energy() if atoms.calc is not None else float('inf')
26 | for atoms in database
27 | ])
28 | Al_energy_dft = database[lowest_energy_index].get_potential_energy() / len(database[lowest_energy_index])
29 | Al_ground_state = database[lowest_energy_index].copy()
30 | Al_ground_state.calc = chgnet
31 | Al_energy_chgnet = Al_ground_state.get_potential_energy() / len(Al_ground_state)
32 | Al_ground_state.calc = mace
33 | Al_energy_mace = Al_ground_state.get_potential_energy() / len(Al_ground_state)
34 |
35 | # Al_reference_energy_dft = -0.19810165
36 | # print("Al_reference_energy_mace: ", Al_reference_energy_mlp)
37 | # print("Al_reference_energy_dft: ", Al_reference_energy_dft)
38 |
39 |
40 | ## Calculate the energies
41 | energies_dft = []
42 | energies_mace = []
43 | energies_chgnet = []
44 | formation_energies_dft = []
45 | formation_energies_mace = []
46 | formation_energies_chgnet = []
47 | for i, atoms in enumerate(database):
48 | if atoms.calc is None:
49 | database.remove(atoms)
50 | continue
51 | formation_energy_dft = atoms.get_potential_energy() / len(atoms) - Al_energy_dft
52 | formation_energies_dft.append(formation_energy_dft)
53 | energies_dft.append(atoms.get_potential_energy()/len(atoms))
54 | atoms.calc = chgnet
55 | formation_energy_chgnet = atoms.get_potential_energy() / len(atoms) - Al_energy_chgnet
56 | formation_energies_chgnet.append(formation_energy_chgnet)
57 | energies_chgnet.append(atoms.get_potential_energy()/len(atoms))
58 | atoms.calc = mace
59 | formation_energy_mace = atoms.get_potential_energy() / len(atoms) - Al_energy_mace
60 | formation_energies_mace.append(formation_energy_mace)
61 | energies_mace.append(atoms.get_potential_energy()/len(atoms))
62 |
63 |
64 | import matplotlib.pyplot as plt
65 |
66 | ## Write energies to a file
67 | with open("Al_energies_comparison.txt", "w") as f:
68 | f.write("# DFT_Energy_per_atom MACE-MPA-0_Energy_per_atom CHGNet_Energy_per_atom\n")
69 | for dft_energy, mace_energy, chgnet_energy in zip(energies_dft, energies_mace, energies_chgnet):
70 | f.write(f"{dft_energy} {mace_energy} {chgnet_energy}\n")
71 |
72 | with open("Al_formations_comparison.txt", "w") as f:
73 | f.write("# DFT_Formation_energy_per_atom MACE-MPA-0_Formation_energy_per_atom CHGNet_Formation_energy_per_atom\n")
74 | for dft_energy, mace_energy, chgnet_energy in zip(formation_energies_dft, formation_energies_mace, formation_energies_chgnet):
75 | f.write(f"{dft_energy} {mace_energy} {chgnet_energy}\n")
76 |
77 | ## Plot the energies
78 | plt.figure(figsize=(10, 6))
79 | plt.scatter(energies_dft, energies_mace, c='blue', marker='o', label='MLIP vs DFT')
80 | plt.show()
--------------------------------------------------------------------------------
/test/test_cache.f90:
--------------------------------------------------------------------------------
1 | program test_cache
2 | use raffle__io_utils
3 | use raffle__cache
4 | use raffle__constants, only: real32
5 | implicit none
6 |
7 | logical :: success = .true.
8 |
9 | call test_retrieve_unallocated(success)
10 | call test_store_retrieve_probability_density(success)
11 |
12 | !-----------------------------------------------------------------------------
13 | ! check for any failed tests
14 | !-----------------------------------------------------------------------------
15 | write(*,*) "----------------------------------------"
16 | if(success)then
17 | write(*,*) 'test_cache passed all tests'
18 | else
19 | write(0,*) 'test_cache failed one or more tests'
20 | stop 1
21 | end if
22 |
23 | contains
24 |
25 | subroutine test_store_retrieve_probability_density(success)
26 | implicit none
27 | logical, intent(inout) :: success
28 | real(real32), allocatable :: test_data(:,:), retrieved_data(:,:)
29 | integer :: i, j
30 |
31 | ! Create test data - a 3x3 matrix with values
32 | allocate(test_data(3,3))
33 | do i = 1, 3
34 | do j = 1, 3
35 | test_data(i,j) = real(i*10 + j, real32)
36 | end do
37 | end do
38 |
39 | ! Store the test data in the cache
40 | call store_probability_density(test_data)
41 |
42 | ! Retrieve the data from the cache
43 | retrieved_data = retrieve_probability_density()
44 |
45 | ! Check dimensions match
46 | if (.not. all(shape(retrieved_data) == shape(test_data))) then
47 | write(0,*) 'test_store_retrieve_probability_density: array shapes do not match'
48 | success = .false.
49 | return
50 | end if
51 |
52 | ! Check all values match
53 | do i = 1, 3
54 | do j = 1, 3
55 | if (abs(retrieved_data(i,j) - test_data(i,j)) .gt. 1.e-6_real32) then
56 | write(0,*) &
57 | 'test_store_retrieve_probability_density: values do not match at', &
58 | i, j, retrieved_data(i,j), test_data(i,j)
59 | success = .false.
60 | return
61 | end if
62 | end do
63 | end do
64 |
65 | ! Clean up
66 | if (allocated(test_data)) deallocate(test_data)
67 | if (allocated(retrieved_data)) deallocate(retrieved_data)
68 |
69 | write(*,*) 'test_store_retrieve_probability_density: PASSED'
70 | end subroutine test_store_retrieve_probability_density
71 |
72 | subroutine test_retrieve_unallocated(success)
73 | implicit none
74 | logical, intent(inout) :: success
75 | real(real32), allocatable :: retrieved_data(:,:)
76 |
77 | ! Try to retrieve data when cache is not allocated
78 | retrieved_data = retrieve_probability_density()
79 |
80 | ! Verify returned array is a scalar with value 0
81 | if (size(retrieved_data) .ne. 1) then
82 | write(0,*) &
83 | 'test_retrieve_unallocated: returned array should be scalar but has size', &
84 | size(retrieved_data)
85 | success = .false.
86 | return
87 | end if
88 |
89 | if (abs(retrieved_data(1,1)) .gt. 1.e-6_real32) then
90 | write(0,*) &
91 | 'test_retrieve_unallocated: returned value should be 0 but is', &
92 | retrieved_data(1,1)
93 | success = .false.
94 | return
95 | end if
96 |
97 | ! Clean up
98 | if (allocated(retrieved_data)) deallocate(retrieved_data)
99 |
100 | write(*,*) 'test_retrieve_unallocated: PASSED'
101 | end subroutine test_retrieve_unallocated
102 |
103 | end program test_cache
104 |
--------------------------------------------------------------------------------
/test/test_misc_maths.f90:
--------------------------------------------------------------------------------
1 | program test_misc_maths
2 | use raffle__io_utils, only: test_error_handling
3 | use raffle__misc_maths
4 | use raffle__constants, only: real32
5 | implicit none
6 |
7 | logical :: success = .true.
8 |
9 | test_error_handling = .true.
10 |
11 |
12 | call test_lnsum(success)
13 | call test_triangular_number(success)
14 | call test_set_difference(success)
15 |
16 |
17 | !-----------------------------------------------------------------------------
18 | ! check for any failed tests
19 | !-----------------------------------------------------------------------------
20 | write(*,*) "----------------------------------------"
21 | if(success)then
22 | write(*,*) 'test_misc_maths passed all tests'
23 | else
24 | write(0,*) 'test_misc_maths failed one or more tests'
25 | stop 1
26 | end if
27 |
28 | contains
29 |
30 | subroutine test_lnsum(success)
31 | implicit none
32 | logical, intent(inout) :: success
33 | integer :: n
34 | real(real32) :: result
35 |
36 | n = 5
37 | result = lnsum(n)
38 | call assert( &
39 | abs( &
40 | result - &
41 | ( &
42 | log(1.0_real32) + &
43 | log(2.0_real32) + &
44 | log(3.0_real32) + &
45 | log(4.0_real32) + &
46 | log(5.0_real32) &
47 | ) &
48 | ) .lt. 1.E-6_real32, &
49 | 'lnsum failed', &
50 | success &
51 | )
52 | end subroutine test_lnsum
53 |
54 | subroutine test_triangular_number(success)
55 | implicit none
56 | logical, intent(inout) :: success
57 | integer :: n, result
58 |
59 | n = 5
60 | result = triangular_number(n)
61 | call assert( &
62 | result .eq. 15, &
63 | 'Triangular number failed', &
64 | success &
65 | )
66 | end subroutine test_triangular_number
67 |
68 | subroutine test_set_difference(success)
69 | implicit none
70 | logical, intent(inout) :: success
71 | real(real32), dimension(3) :: a, b, result, expected
72 | real(real32), dimension(4) :: c
73 |
74 | a = [1.0_real32, 2.0_real32, 3.0_real32]
75 | b = [1.0_real32, 1.0_real32, 1.0_real32]
76 | expected = [0.0_real32, 1.0_real32, 2.0_real32]
77 | result = set_difference(a, b)
78 |
79 | call assert( &
80 | all( abs(result - expected) .lt. 1.E-6_real32 ), &
81 | 'Set difference failed', &
82 | success &
83 | )
84 |
85 | b = [0.0_real32, 1.0_real32, 4.0_real32]
86 | expected = [1.0_real32, 1.0_real32, 0.0_real32]
87 | result = set_difference(a, b, set_min_zero=.true.)
88 |
89 | call assert( &
90 | all( abs(result - expected) .lt. 1.E-6_real32 ), &
91 | 'Set difference min zero failed', &
92 | success &
93 | )
94 |
95 | c = [1.0_real32, 2.0_real32, 3.0_real32, 4.0_real32]
96 | write(*,*) "Testing set_difference error handling"
97 | result = set_difference(a, c)
98 | write(*,*) "Handled error: set difference of arrays of different lengths"
99 |
100 |
101 | end subroutine test_set_difference
102 |
103 | !###############################################################################
104 |
105 | subroutine assert(condition, message, success)
106 | implicit none
107 | logical, intent(in) :: condition
108 | character(len=*), intent(in) :: message
109 | logical, intent(inout) :: success
110 | if (.not. condition) then
111 | write(0,*) "Test failed: ", message
112 | success = .false.
113 | end if
114 | end subroutine assert
115 |
116 | end program test_misc_maths
--------------------------------------------------------------------------------
/example/python_pkg/benchmarks/create_gdfs.py:
--------------------------------------------------------------------------------
1 | import os
2 | nthreads = 1
3 | os.environ["OMP_NUM_THREADS"] = str(nthreads)
4 | os.environ["OPENBLAS_NUM_THREADS"] = str(nthreads)
5 | os.environ["MKL_NUM_THREADS"] = str(nthreads)
6 |
7 | import glob
8 | from raffle.generator import raffle_generator
9 | import pytest
10 | from ase.io import read
11 | import time
12 | import numpy as np
13 |
14 |
15 | def get_xyz_files():
16 | """Get all .xyz files from the ../../data directory"""
17 | current_dir = os.path.dirname(os.path.abspath(__file__))
18 | data_dir = os.path.join(current_dir, '..', '..', '..', 'example', 'data')
19 | print("Data directory:", data_dir)
20 | return glob.glob(os.path.join(data_dir, '*.xyz'))
21 |
22 |
23 | @pytest.mark.parametrize("xyz_file", get_xyz_files())
24 | @pytest.mark.parametrize("kBT", [0.2, 0.4, 0.6])
25 | @pytest.mark.parametrize("width", [
26 | [0.025, np.pi/200.0, np.pi/200.0],
27 | [0.05, np.pi/100.0, np.pi/100.0],
28 | [0.1, np.pi/50.0, np.pi/50.0]
29 | ])
30 | @pytest.mark.benchmark(
31 | group="distributions",
32 | min_rounds=5,
33 | timer=time.time,
34 | disable_gc=True,
35 | warmup=False
36 | )
37 | def test_distributions_create(benchmark, xyz_file, kBT, width):
38 | atoms = read(xyz_file, index=":")
39 |
40 | # Initialize generator
41 | generator = raffle_generator()
42 |
43 | # get list of elements in list of atoms
44 | elements = []
45 | for atom in atoms:
46 | elements += atom.get_chemical_symbols()
47 | elements = list(set(elements))
48 | energies = {element: 0.0 for element in elements}
49 | generator.distributions.set_element_energies(energies)
50 |
51 | avg_num_atoms = 0
52 | for atom in atoms:
53 | avg_num_atoms += len(atom)
54 | avg_num_atoms = round(avg_num_atoms / len(atoms))
55 |
56 | benchmark.extra_info = {
57 | 'file': os.path.basename(xyz_file),
58 | 'num_structures': len(atoms),
59 | 'num_species': len(elements),
60 | "avg_num_atoms": avg_num_atoms,
61 | "kBT": kBT,
62 | "width": width
63 | }
64 |
65 | # set energy scale
66 | generator.distributions.set_kBT(kBT)
67 |
68 | # set the distribution function widths (2-body, 3-body, 4-body)
69 | generator.distributions.set_width(width)
70 |
71 | # Measure time for distributions.create()
72 | result = benchmark(generator.distributions.create, atoms)
73 |
74 |
75 | return {
76 | 'file': os.path.basename(xyz_file),
77 | 'time': result,
78 | 'num_structures': len(atoms),
79 | 'num_species': len(elements),
80 | "avg_num_atoms": avg_num_atoms
81 | }
82 |
83 | @pytest.fixture
84 | def make_customer_record():
85 | def _make_customer_record(name):
86 | return {"name": name, "orders": []}
87 |
88 | return _make_customer_record
89 |
90 | if __name__ == '__main__':
91 | xyz_files = get_xyz_files()
92 | results = []
93 |
94 | result = test_distributions_create(lambda x: x)
95 | # for xyz_file in xyz_files:
96 | # # for _ in range(5): # Run the benchmark 5 times for each file
97 | # result = test_distributions_create(lambda x: x, xyz_file)
98 | # results.append(result)
99 |
100 | # Print results
101 | print("\nBenchmark Results:")
102 | print("-" * 60)
103 | print(f"{'File':<20} {'Time (s)':<10} {'Num Structures':<10} {'Num Species':<10} {'Avg Num Atoms':<10}")
104 | print("-" * 60)
105 | for result in results:
106 | print(f"{result['file']:<20} {result['time']:<10.4f} {result['num_structures']:<10} {result['num_species']:<10} {result['avg_num_atoms']:<10}")
--------------------------------------------------------------------------------
/.github/workflows/fpm.yml:
--------------------------------------------------------------------------------
1 | name: run-fpm-build
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - main
7 | - development
8 | types:
9 | - opened
10 | - synchronize
11 | paths:
12 | - ".github/workflows/fpm.yml"
13 | - "fpm.toml"
14 | - "**.f90"
15 | - "**.F90"
16 | workflow_dispatch:
17 |
18 | permissions:
19 | contents: read
20 | pages: write
21 | id-token: write
22 |
23 | concurrency:
24 | group: fpm
25 | cancel-in-progress: false
26 |
27 | jobs:
28 | build-and-test-fpm-debug:
29 | environment:
30 | name: github-pages
31 | name: Build and test in debug mode
32 | runs-on: ubuntu-latest
33 | strategy:
34 | fail-fast: false
35 | matrix:
36 | os: [ubuntu-latest, macos-latest]
37 | toolchain:
38 | - {compiler: gcc, version: 13}
39 | - {fortran-compiler: gcc, fc-version: 14}
40 | # - {compiler: intel, version: '2024.1'}
41 | # - {compiler: intel-classic, version: '2021.10'}
42 | # exclude:
43 | # - os: macos-latest
44 | # toolchain: {compiler: intel, version: '2024.1'}
45 | # - os: macos-latest
46 | # toolchain: {compiler: intel-classic, version: '2021.10'}
47 | steps:
48 | - name: checkout repo
49 | uses: actions/checkout@v4
50 |
51 | - uses: fortran-lang/setup-fortran@v1
52 | id: setup-fortran
53 | with:
54 | compiler: ${{ matrix.toolchain.compiler }}
55 | version: ${{ matrix.toolchain.version }}
56 |
57 | - uses: fortran-lang/setup-fpm@v5
58 | id: setup-fpm
59 | with:
60 | fpm-version: "v0.10.0"
61 |
62 | - name: Install OpenMP runtime (Linux only)
63 | if: runner.os == 'Linux'
64 | run: sudo apt-get update && sudo apt-get install -y libgomp1
65 |
66 | - name: Compile
67 | run: |
68 | ${{ env.FC }} --version
69 | fpm build --profile debug --compiler ${{ env.FC }}
70 |
71 | - name: Test
72 | run: |
73 | ${{ env.FC }} --version
74 | fpm test --profile debug --compiler ${{ env.FC }}
75 |
76 | build-and-test-fpm-release:
77 | name: Build and test in release mode
78 | environment:
79 | name: github-pages
80 | runs-on: ubuntu-latest
81 | strategy:
82 | fail-fast: false
83 | matrix:
84 | os: [ubuntu-latest, macos-latest]
85 | toolchain:
86 | - {compiler: gcc, version: 13}
87 | # - {compiler: intel, version: '2024.1'}
88 | # - {compiler: intel-classic, version: '2021.10'}
89 | # exclude:
90 | # - os: macos-latest
91 | # toolchain: {compiler: intel, version: '2024.1'}
92 | # - os: macos-latest
93 | # toolchain: {compiler: intel-classic, version: '2021.10'}
94 |
95 | steps:
96 | - name: checkout repo
97 | uses: actions/checkout@v4
98 |
99 | - uses: fortran-lang/setup-fortran@v1
100 | id: setup-fortran
101 | with:
102 | compiler: ${{ matrix.toolchain.compiler }}
103 | version: ${{ matrix.toolchain.version }}
104 |
105 | - uses: fortran-lang/setup-fpm@v5
106 | id: setup-fpm
107 | with:
108 | fpm-version: "v0.10.0"
109 |
110 | - name: Install OpenMP runtime (Linux only)
111 | if: runner.os == 'Linux'
112 | run: sudo apt-get update && sudo apt-get install -y libgomp1
113 |
114 | - name: Compile
115 | run: |
116 | ${{ env.FC }} --version
117 | fpm build --profile release --compiler ${{ env.FC }}
118 |
119 | - name: Test
120 | run: |
121 | ${{ env.FC }} --version
122 | fpm test --profile release --compiler ${{ env.FC }}
123 |
--------------------------------------------------------------------------------
/docs/source/tutorials/quick_guide.rst:
--------------------------------------------------------------------------------
1 | .. quick_guide:
2 |
3 | ===========
4 | Quick guide
5 | ===========
6 |
7 |
8 | The quick guide is designed to give a brief overview of the steps required to run a RAFFLE calculation.
9 | It is assumed that the user has already installed RAFFLE and has a basic understanding of the command line.
10 | For a more detailed explanation of the parameters and options available, please see the :doc:`Main tutorial page ` for individual tutorials detailing each step.
11 |
12 |
13 | RAFFLE is a random structure search package designed primarily for interfaces.
14 | The tutorials will use bulk systems to demonstrate its functionality, but it is recommended to use packages such as `AIRSS `_ for bulk random structure search.
15 |
16 |
17 | Single iteration
18 | ----------------
19 |
20 | Here is a script to run a single iteration of the RAFFLE generator for structure search.
21 |
22 | .. code-block:: python
23 |
24 | # Single iteration of RAFFLE structure search
25 | from ase.io import read, write
26 | from raffle.generator import raffle_generator
27 |
28 | generator = raffle_generator()
29 |
30 | host = read("host.xyz")
31 | generator.set_host(host)
32 | generator.set_grid(grid_spacing=0.1)
33 | generator.set_bounds([[0, 0, 0.5], [1, 1, 0.75]])
34 | generator.distributions.set_element_energies(
35 | { 'C': -9.063733 }
36 | )
37 |
38 | database = read("database.xyz", index=":")
39 | generator.distributions.create(database)
40 |
41 | structures = generator.generate(
42 | num_structures = 1,
43 | stoichiometry = { 'C': 2 },
44 | )
45 |
46 | write("output.xyz", structures)
47 |
48 | This script will generate a single structure with a stoichiometry of two carbon atoms.
49 | The host structure is read from a file, and the grid spacing and bounds are set.
50 | The element energies are set to the energy of carbon, and the database is read from a file.
51 | The generator is then run, and the structures are written to an output file.
52 |
53 |
54 | Iterative structure search
55 | --------------------------
56 |
57 | Here is an example of how to run an iterative structure search with RAFFLE and check for convergence.
58 |
59 | .. code-block:: python
60 |
61 | # Iterative RAFFLE structure search
62 | from ase.io import read, write
63 | from ase.optimize import FIRE
64 | from raffle.generator import raffle_generator
65 | from mace.calculators import mace_mp
66 |
67 | generator = raffle_generator()
68 | generator.distributions.set_history_len(10)
69 | calc = mace_mp(model="medium", dispersion=False, default_dtype="float32", device='cpu')
70 |
71 | host = read("host.xyz")
72 | generator.set_host(host)
73 | generator.set_grid(grid_spacing=0.1)
74 | generator.set_bounds([[0, 0, 0.5], [1, 1, 0.75]])
75 | generator.distributions.set_element_energies(
76 | { 'C': -9.063733 }
77 | )
78 |
79 | database = read("database.xyz", index=":")
80 | generator.distributions.create(database)
81 |
82 | num_structures_old = 0
83 | rlxd_structures = []
84 | for i in range(10):
85 | structures = generator.generate(
86 | num_structures = 2,
87 | stoichiometry = { 'C': 2 },
88 | calc = calc
89 | )
90 | for structure in structures:
91 | optimiser = FIRE(structure)
92 | optimiser.run(fmax=0.05)
93 |
94 | generator.distributions.update(structures)
95 | rlxd_structures.extend(structures)
96 | if generator.distributions.is_converged():
97 | break
98 |
99 | write("output.xyz", structures)
100 |
--------------------------------------------------------------------------------
/example/python_pkg/diamond/POSCAR_host_3x3:
--------------------------------------------------------------------------------
1 | C8
2 | 1.000000000
3 | 14.242980436 0.000000000 0.000000000
4 | 0.000000000 14.242980436 0.000000000
5 | 0.000000000 0.000000000 7.121490218
6 | C
7 | 72
8 | Direct
9 | 0.000000000 0.000000000 0.000000000
10 | 0.333333333 0.000000000 0.000000000
11 | 0.666666667 0.000000000 0.000000000
12 | 0.000000000 0.333333333 0.000000000
13 | 0.333333333 0.333333333 0.000000000
14 | 0.666666667 0.333333333 0.000000000
15 | 0.000000000 0.666666667 0.000000000
16 | 0.333333333 0.666666667 0.000000000
17 | 0.666666667 0.666666667 0.000000000
18 | 0.166666667 0.166666667 0.000000000
19 | 0.500000000 0.166666667 0.000000000
20 | 0.833333333 0.166666667 0.000000000
21 | 0.166666667 0.500000000 0.000000000
22 | 0.500000000 0.500000000 0.000000000
23 | 0.833333333 0.500000000 0.000000000
24 | 0.166666667 0.833333333 0.000000000
25 | 0.500000000 0.833333333 0.000000000
26 | 0.833333333 0.833333333 0.000000000
27 | 0.166666667 0.000000000 0.250000000
28 | 0.500000000 0.000000000 0.250000000
29 | 0.833333333 0.000000000 0.250000000
30 | 0.166666667 0.333333333 0.250000000
31 | 0.500000000 0.333333333 0.250000000
32 | 0.833333333 0.333333333 0.250000000
33 | 0.166666667 0.666666667 0.250000000
34 | 0.500000000 0.666666667 0.250000000
35 | 0.833333333 0.666666667 0.250000000
36 | 0.000000000 0.166666667 0.250000000
37 | 0.333333333 0.166666667 0.250000000
38 | 0.666666667 0.166666667 0.250000000
39 | 0.000000000 0.500000000 0.250000000
40 | 0.333333333 0.500000000 0.250000000
41 | 0.666666667 0.500000000 0.250000000
42 | 0.000000000 0.833333333 0.250000000
43 | 0.333333333 0.833333333 0.250000000
44 | 0.666666667 0.833333333 0.250000000
45 | 0.083333333 0.083333333 0.125000000
46 | 0.416666667 0.083333333 0.125000000
47 | 0.750000000 0.083333333 0.125000000
48 | 0.083333333 0.416666667 0.125000000
49 | 0.416666667 0.416666667 0.125000000
50 | 0.750000000 0.416666667 0.125000000
51 | 0.083333333 0.750000000 0.125000000
52 | 0.416666667 0.750000000 0.125000000
53 | 0.750000000 0.750000000 0.125000000
54 | 0.250000000 0.250000000 0.125000000
55 | 0.583333333 0.250000000 0.125000000
56 | 0.916666667 0.250000000 0.125000000
57 | 0.250000000 0.583333333 0.125000000
58 | 0.583333333 0.583333333 0.125000000
59 | 0.916666667 0.583333333 0.125000000
60 | 0.250000000 0.916666667 0.125000000
61 | 0.583333333 0.916666667 0.125000000
62 | 0.916666667 0.916666667 0.125000000
63 | 0.250000000 0.083333333 0.375000000
64 | 0.583333333 0.083333333 0.375000000
65 | 0.916666667 0.083333333 0.375000000
66 | 0.250000000 0.416666667 0.375000000
67 | 0.583333333 0.416666667 0.375000000
68 | 0.916666667 0.416666667 0.375000000
69 | 0.250000000 0.750000000 0.375000000
70 | 0.583333333 0.750000000 0.375000000
71 | 0.916666667 0.750000000 0.375000000
72 | 0.083333333 0.250000000 0.375000000
73 | 0.416666667 0.250000000 0.375000000
74 | 0.750000000 0.250000000 0.375000000
75 | 0.083333333 0.583333333 0.375000000
76 | 0.416666667 0.583333333 0.375000000
77 | 0.750000000 0.583333333 0.375000000
78 | 0.083333333 0.916666667 0.375000000
79 | 0.416666667 0.916666667 0.375000000
80 | 0.750000000 0.916666667 0.375000000
81 |
--------------------------------------------------------------------------------
/.github/workflows/coverage.yml:
--------------------------------------------------------------------------------
1 | name: run-code-coverage
2 |
3 | on:
4 | push:
5 | branches:
6 | - "main"
7 | paths:
8 | - ".github/workflows/coverage.yml"
9 | - "CMakeLists.txt"
10 | - "**.f90"
11 | - "**.F90"
12 | - "**.cmake"
13 | pull_request:
14 | branches:
15 | - "main"
16 | types:
17 | - opened
18 | - synchronize
19 | paths:
20 | - ".github/workflows/coverage.yml"
21 | - "CMakeLists.txt"
22 | - "**.f90"
23 | - "**.F90"
24 | - "**.cmake"
25 | workflow_dispatch:
26 |
27 | permissions:
28 | contents: read
29 | pages: write
30 | id-token: write
31 |
32 | concurrency:
33 | group: pages
34 | cancel-in-progress: false
35 |
36 | jobs:
37 | run-code-coverage:
38 | # permissions:
39 | # contents: write
40 | environment:
41 | name: github-pages
42 | url: ${{ steps.deployment.outputs.page_url }}
43 | runs-on: ubuntu-latest
44 | strategy:
45 | fail-fast: false
46 | matrix:
47 | compiler: [gcc]
48 | version: [13]
49 | steps:
50 | - name: checkout repo
51 | uses: actions/checkout@v4
52 |
53 | - name: actions-setup-cmake
54 | uses: jwlawson/actions-setup-cmake@v2
55 | with:
56 | cmake-version: '3.24.x'
57 |
58 | - uses: fortran-lang/setup-fortran@v1
59 | id: setup-fortran
60 | with:
61 | compiler: ${{ matrix.compiler }}
62 | version: ${{ matrix.version }}
63 |
64 | - name: Install gcovr
65 | run: |
66 | pip --version
67 | pip install gcovr
68 |
69 | - name: Build project
70 | run: |
71 | sudo apt-get update
72 | sudo apt-get install -y cmake make
73 | cmake --version
74 | mkdir -p build
75 | cd build
76 | cmake -DCMAKE_BUILD_TYPE=Coverage -DBUILD_PYTHON=Off -DBUILD_EXECUTABLE=Off ..
77 | make
78 |
79 | - name: Run coverage tests
80 | run: |
81 | cd build
82 | env CTEST_OUTPUT_ON_FAILURE=1 make coverage
83 |
84 | - name: Get coverage percentage
85 | run: |
86 | pip install bs4
87 | echo "COVERAGE_PERCENTAGE="$(python ./tools/coverage_badge.py) >> $GITHUB_ENV
88 |
89 | - name: Create coverage badge
90 | uses: schneegans/dynamic-badges-action@v1.7.0
91 | with:
92 | auth: ${{ secrets.GIST_SECRET }}
93 | gistID: 48f14ebb5636b54d3813e4b4494903eb
94 | filename: raffle_coverage_${{ github.head_ref || github.ref_name }}.json # Use branch-specific file
95 | label: Coverage
96 | message: ${{ env.COVERAGE_PERCENTAGE }}%
97 | valColorRange: ${{ env.COVERAGE_PERCENTAGE }}
98 | maxColorRange: 100
99 | minColorRange: 0
100 |
101 | - name: upload artifact
102 | uses: actions/upload-pages-artifact@v3
103 | with:
104 | path: './build/coverage/'
105 |
106 | deploy:
107 | environment:
108 | name: github-pages
109 | url: ${{ steps.deployment.outputs.page_url }}
110 | runs-on: ubuntu-latest
111 | needs: run-code-coverage
112 | if: ${{ github.ref == 'refs/heads/main' }}
113 | steps:
114 | - name: deploy to Github Pages (main branch)
115 | id: deployment
116 | uses: actions/deploy-pages@v4
117 |
118 | # - name: deploy to Github Pages (development branch)
119 | # if: ${{ github.ref != 'refs/heads/main' }}
120 | # uses: peaceiris/actions-gh-pages@v4
121 | # with:
122 | # publish_dir: ./build/coverage/
123 | # github_token: ${{ secrets.GITHUB_TOKEN }}
124 | # destination_dir: development-branch/
--------------------------------------------------------------------------------
/docs/source/tutorials/host_tutorial.rst:
--------------------------------------------------------------------------------
1 | .. host:
2 |
3 | ======================
4 | Setting host structure
5 | ======================
6 |
7 | This tutorial will detail how to set the host structure for RAFFLE and the optional bounding box.
8 |
9 | The host structure is the base structure that will be added to in order to generate the structures.
10 | The bounding box is an optional parameter that can be used to limit the space in which atoms can be placed.
11 |
12 |
13 | It is recommended to set the host after changing parameters such as the Gaussian parameters and cutoffs (see :doc:`Parameters tutorial `).
14 | However, this is not strictly necessary, as the host can be set at any time.
15 | It is recommended that the host be provided with a calculator, as this will enable calculation of the host structure prior to atom placement.
16 |
17 |
18 | Follow the parameter tutorial to see how to initialise the generator.
19 |
20 | .. code-block:: python
21 |
22 | # Initialise RAFFLE generator
23 | from raffle.generator import raffle_generator
24 |
25 | generator = raffle_generator()
26 |
27 | We shall also initialise the calculator.
28 |
29 | .. code-block:: python
30 |
31 | # Set the calculator
32 | from mace.calculators import mace_mp
33 | calc = mace_mp(model="medium", dispersion=False, default_dtype="float32", device='cpu')
34 |
35 |
36 | Defining the host structure
37 | ---------------------------
38 |
39 | Now we shall initialise an atoms object and set it as the host structure.
40 |
41 | .. code-block:: python
42 |
43 | # Set the host structure
44 | host = Atoms(...)
45 | host.calc = calc
46 | generator.set_host(host)
47 |
48 |
49 | Preparing the host structure
50 | ----------------------------
51 |
52 | If a vacuum region has not been set within the host structure (i.e. a region with no atoms between two constituent substructures), the `prepare_host` method can be used to introduce such a region.
53 | The `prepare_host` method will remove atoms from the host structure within a specified distance from the interface location and returns a dictionary of the removed stoichiometry.
54 | The interface location is the location of the interface in the host structure and can be identified using `ARTEMIS `_.
55 |
56 | Below is an example of how to use both ARTEMIS and RAFFLE to prepare the host structure.
57 |
58 | .. code-block:: python
59 |
60 | # Import the required modules
61 | from artemis.generator import artemis_generator
62 | artemis_generator = artemis_generator()
63 |
64 | # Return the interface location using ARTEMIS
65 | location, axis = artemis_generator.get_interface_location( host, return_fractional = True )
66 | print("Interface found at", location, "along", axis)
67 |
68 | # Prepare the host structure
69 | missing_stoich = generator.prepare_host(
70 | interface_location = location,
71 | depth = 2.0,
72 | location_as_fractional = True
73 | )
74 | print("missing_stoich", missing_stoich)
75 |
76 | # Visualise the prepared host structure
77 | from ase.visualize import view
78 | host_modified = generator.get_host()
79 | view(host_modified)
80 |
81 |
82 | Defining the bounding box
83 | --------------------------
84 |
85 | An optional bounding box can restrict atom placement to a specified region.
86 | The limits are expressed in fractional coordinates relative to the lattice vectors :math:`(\vec{a}, \vec{b}, \vec{c})`.
87 |
88 | .. code-block:: python
89 |
90 | # Set the fractional limits of atom position placement
91 | a_min = 0.0; b_max = 0.0; c_min = 0.3
92 | a_max = 1.0; b_max = 1.0; c_max = 0.8
93 | generator.set_bounds( [
94 | [a_min, b_min, c_min],
95 | [a_max, b_max, c_max]
96 | ] )
97 |
--------------------------------------------------------------------------------
/tools/database.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": null,
6 | "metadata": {},
7 | "outputs": [],
8 | "source": [
9 | "#Imports MPRester\n",
10 | "# from mp_api.client import MPRester\n",
11 | "from ase import Atoms\n",
12 | "from ase.io import write, read\n",
13 | "from pymatgen.io.ase import AseAtomsAdaptor\n",
14 | "from pymatgen.ext.matproj import MPRester"
15 | ]
16 | },
17 | {
18 | "cell_type": "code",
19 | "execution_count": null,
20 | "metadata": {},
21 | "outputs": [],
22 | "source": [
23 | "# Personal api key for accessing materials project api\n",
24 | "# This is unique to each user\n",
25 | "# api_key = \"\""
26 | ]
27 | },
28 | {
29 | "cell_type": "code",
30 | "execution_count": null,
31 | "metadata": {},
32 | "outputs": [],
33 | "source": [
34 | "# Get the ID of materials from the materials project\n",
35 | "mpr = MPRester() # MPRester(api_key)\n",
36 | "materials = []\n",
37 | "\n",
38 | "materials.append(mpr.materials.summary.search(chemsys=\"C\", \n",
39 | " fields=[\"material_id\",\"structure\", \"energy_per_atom\", \"nsites\"]))\n",
40 | "materials.append(mpr.materials.summary.search(chemsys=\"Mg\", \n",
41 | " fields=[\"material_id\",\"structure\", \"energy_per_atom\", \"nsites\"]))\n",
42 | "materials.append(mpr.materials.summary.search(chemsys=\"O\", \n",
43 | " fields=[\"material_id\",\"structure\", \"energy_per_atom\", \"nsites\"]))\n",
44 | "materials.append(mpr.materials.summary.search(chemsys=\"C-Mg\", \n",
45 | " fields=[\"material_id\",\"structure\", \"energy_per_atom\", \"nsites\"]))\n",
46 | "materials.append(mpr.materials.summary.search(chemsys=\"C-O\", \n",
47 | " fields=[\"material_id\",\"structure\", \"energy_per_atom\", \"nsites\"]))\n",
48 | "materials.append(mpr.materials.summary.search(chemsys=\"Mg-O\", \n",
49 | " fields=[\"material_id\",\"structure\", \"energy_per_atom\", \"nsites\"]))"
50 | ]
51 | },
52 | {
53 | "cell_type": "code",
54 | "execution_count": null,
55 | "metadata": {},
56 | "outputs": [],
57 | "source": [
58 | "# Get the structures, energies, and number of sites for each material from the materials project\n",
59 | "structures = []\n",
60 | "energies = []\n",
61 | "nsites = []\n",
62 | "for material_set in materials:\n",
63 | " for material in material_set:\n",
64 | " material_id = material.material_id\n",
65 | " structures.append(mpr.get_structure_by_material_id(material_id))\n",
66 | " energies.append(material.energy_per_atom)\n",
67 | " nsites.append(material.nsites)"
68 | ]
69 | },
70 | {
71 | "cell_type": "code",
72 | "execution_count": null,
73 | "metadata": {},
74 | "outputs": [],
75 | "source": [
76 | "# Convert the structures to atoms and write them to a single extended xyz file\n",
77 | "all_atoms = []\n",
78 | "for structure, energy, nsite in zip(structures, energies, nsites):\n",
79 | " atom = AseAtomsAdaptor.get_atoms(structure)\n",
80 | " atom.info['free_energy'] = energy * nsite\n",
81 | " atom.info['energy'] = energy * nsite\n",
82 | " all_atoms.append(atom)\n",
83 | "write(\"database.xyz\", all_atoms, format='extxyz')"
84 | ]
85 | }
86 | ],
87 | "metadata": {
88 | "kernelspec": {
89 | "display_name": "py3.11",
90 | "language": "python",
91 | "name": "python3"
92 | },
93 | "language_info": {
94 | "codemirror_mode": {
95 | "name": "ipython",
96 | "version": 3
97 | },
98 | "file_extension": ".py",
99 | "mimetype": "text/x-python",
100 | "name": "python",
101 | "nbconvert_exporter": "python",
102 | "pygments_lexer": "ipython3",
103 | "version": "3.11.8"
104 | }
105 | },
106 | "nbformat": 4,
107 | "nbformat_minor": 2
108 | }
109 |
--------------------------------------------------------------------------------
/example/python_pkg/Si-Ge_learn/Ge_slab.vasp:
--------------------------------------------------------------------------------
1 | Ge
2 | 1.000000000
3 | 11.300000000 0.000000000 0.000000000
4 | 0.000000000 11.300000000 0.000000000
5 | 0.000000000 0.000000000 25.299999996
6 | Ge
7 | 80
8 | Direct
9 | 0.750000000 0.000000000 0.000000000
10 | 0.750000000 0.000000000 0.223320158
11 | 0.750000000 0.000000000 0.446640316
12 | 0.875000000 0.125000000 0.055830039
13 | 0.875000000 0.125000000 0.279150198
14 | 0.875000000 0.125000000 0.502470356
15 | 0.000000000 0.250000000 0.000000000
16 | 0.000000000 0.250000000 0.223320158
17 | 0.000000000 0.250000000 0.446640316
18 | 0.125000000 0.375000000 0.055830039
19 | 0.125000000 0.375000000 0.279150198
20 | 0.125000000 0.375000000 0.502470356
21 | 0.000000000 0.000000000 0.111660079
22 | 0.000000000 0.000000000 0.334980237
23 | 0.125000000 0.125000000 0.167490118
24 | 0.125000000 0.125000000 0.390810277
25 | 0.750000000 0.250000000 0.111660079
26 | 0.750000000 0.250000000 0.334980237
27 | 0.875000000 0.375000000 0.167490118
28 | 0.875000000 0.375000000 0.390810277
29 | 0.750000000 0.500000000 0.000000000
30 | 0.750000000 0.500000000 0.223320158
31 | 0.750000000 0.500000000 0.446640316
32 | 0.875000000 0.625000000 0.055830039
33 | 0.875000000 0.625000000 0.279150198
34 | 0.875000000 0.625000000 0.502470356
35 | 0.000000000 0.750000000 0.000000000
36 | 0.000000000 0.750000000 0.223320158
37 | 0.000000000 0.750000000 0.446640316
38 | 0.125000000 0.875000000 0.055830039
39 | 0.125000000 0.875000000 0.279150198
40 | 0.125000000 0.875000000 0.502470356
41 | 0.000000000 0.500000000 0.111660079
42 | 0.000000000 0.500000000 0.334980237
43 | 0.125000000 0.625000000 0.167490118
44 | 0.125000000 0.625000000 0.390810277
45 | 0.750000000 0.750000000 0.111660079
46 | 0.750000000 0.750000000 0.334980237
47 | 0.875000000 0.875000000 0.167490118
48 | 0.875000000 0.875000000 0.390810277
49 | 0.250000000 0.000000000 0.000000000
50 | 0.250000000 0.000000000 0.223320158
51 | 0.250000000 0.000000000 0.446640316
52 | 0.375000000 0.125000000 0.055830039
53 | 0.375000000 0.125000000 0.279150198
54 | 0.375000000 0.125000000 0.502470356
55 | 0.500000000 0.250000000 0.000000000
56 | 0.500000000 0.250000000 0.223320158
57 | 0.500000000 0.250000000 0.446640316
58 | 0.625000000 0.375000000 0.055830039
59 | 0.625000000 0.375000000 0.279150198
60 | 0.625000000 0.375000000 0.502470356
61 | 0.500000000 0.000000000 0.111660079
62 | 0.500000000 0.000000000 0.334980237
63 | 0.625000000 0.125000000 0.167490118
64 | 0.625000000 0.125000000 0.390810277
65 | 0.250000000 0.250000000 0.111660079
66 | 0.250000000 0.250000000 0.334980237
67 | 0.375000000 0.375000000 0.167490118
68 | 0.375000000 0.375000000 0.390810277
69 | 0.250000000 0.500000000 0.000000000
70 | 0.250000000 0.500000000 0.223320158
71 | 0.250000000 0.500000000 0.446640316
72 | 0.375000000 0.625000000 0.055830039
73 | 0.375000000 0.625000000 0.279150198
74 | 0.375000000 0.625000000 0.502470356
75 | 0.500000000 0.750000000 0.000000000
76 | 0.500000000 0.750000000 0.223320158
77 | 0.500000000 0.750000000 0.446640316
78 | 0.625000000 0.875000000 0.055830039
79 | 0.625000000 0.875000000 0.279150198
80 | 0.625000000 0.875000000 0.502470356
81 | 0.500000000 0.500000000 0.111660079
82 | 0.500000000 0.500000000 0.334980237
83 | 0.625000000 0.625000000 0.167490118
84 | 0.625000000 0.625000000 0.390810277
85 | 0.250000000 0.750000000 0.111660079
86 | 0.250000000 0.750000000 0.334980237
87 | 0.375000000 0.875000000 0.167490118
88 | 0.375000000 0.875000000 0.390810277
89 |
--------------------------------------------------------------------------------
/example/python_pkg/Si-Ge_learn/Si_slab.vasp:
--------------------------------------------------------------------------------
1 | Si
2 | 1.000000000
3 | 10.860000000 0.000000000 0.000000000
4 | 0.000000000 10.860000000 0.000000000
5 | 0.000000000 0.000000000 24.859999996
6 | Si
7 | 80
8 | Direct
9 | 0.000000000 0.000000000 0.000000000
10 | 0.000000000 0.000000000 0.218423170
11 | 0.000000000 0.000000000 0.436846339
12 | 0.125000000 0.125000000 0.054605792
13 | 0.125000000 0.125000000 0.273028962
14 | 0.125000000 0.125000000 0.491452132
15 | 0.250000000 0.250000000 0.000000000
16 | 0.250000000 0.250000000 0.218423170
17 | 0.250000000 0.250000000 0.436846339
18 | 0.375000000 0.375000000 0.054605792
19 | 0.375000000 0.375000000 0.273028962
20 | 0.375000000 0.375000000 0.491452132
21 | 0.250000000 0.000000000 0.109211585
22 | 0.250000000 0.000000000 0.327634755
23 | 0.375000000 0.125000000 0.163817377
24 | 0.375000000 0.125000000 0.382240547
25 | 0.000000000 0.250000000 0.109211585
26 | 0.000000000 0.250000000 0.327634755
27 | 0.125000000 0.375000000 0.163817377
28 | 0.125000000 0.375000000 0.382240547
29 | 0.000000000 0.500000000 0.000000000
30 | 0.000000000 0.500000000 0.218423170
31 | 0.000000000 0.500000000 0.436846339
32 | 0.125000000 0.625000000 0.054605792
33 | 0.125000000 0.625000000 0.273028962
34 | 0.125000000 0.625000000 0.491452132
35 | 0.250000000 0.750000000 0.000000000
36 | 0.250000000 0.750000000 0.218423170
37 | 0.250000000 0.750000000 0.436846339
38 | 0.375000000 0.875000000 0.054605792
39 | 0.375000000 0.875000000 0.273028962
40 | 0.375000000 0.875000000 0.491452132
41 | 0.250000000 0.500000000 0.109211585
42 | 0.250000000 0.500000000 0.327634755
43 | 0.375000000 0.625000000 0.163817377
44 | 0.375000000 0.625000000 0.382240547
45 | 0.000000000 0.750000000 0.109211585
46 | 0.000000000 0.750000000 0.327634755
47 | 0.125000000 0.875000000 0.163817377
48 | 0.125000000 0.875000000 0.382240547
49 | 0.500000000 0.000000000 0.000000000
50 | 0.500000000 0.000000000 0.218423170
51 | 0.500000000 0.000000000 0.436846339
52 | 0.625000000 0.125000000 0.054605792
53 | 0.625000000 0.125000000 0.273028962
54 | 0.625000000 0.125000000 0.491452132
55 | 0.750000000 0.250000000 0.000000000
56 | 0.750000000 0.250000000 0.218423170
57 | 0.750000000 0.250000000 0.436846339
58 | 0.875000000 0.375000000 0.054605792
59 | 0.875000000 0.375000000 0.273028962
60 | 0.875000000 0.375000000 0.491452132
61 | 0.750000000 0.000000000 0.109211585
62 | 0.750000000 0.000000000 0.327634755
63 | 0.875000000 0.125000000 0.163817377
64 | 0.875000000 0.125000000 0.382240547
65 | 0.500000000 0.250000000 0.109211585
66 | 0.500000000 0.250000000 0.327634755
67 | 0.625000000 0.375000000 0.163817377
68 | 0.625000000 0.375000000 0.382240547
69 | 0.500000000 0.500000000 0.000000000
70 | 0.500000000 0.500000000 0.218423170
71 | 0.500000000 0.500000000 0.436846339
72 | 0.625000000 0.625000000 0.054605792
73 | 0.625000000 0.625000000 0.273028962
74 | 0.625000000 0.625000000 0.491452132
75 | 0.750000000 0.750000000 0.000000000
76 | 0.750000000 0.750000000 0.218423170
77 | 0.750000000 0.750000000 0.436846339
78 | 0.875000000 0.875000000 0.054605792
79 | 0.875000000 0.875000000 0.273028962
80 | 0.875000000 0.875000000 0.491452132
81 | 0.750000000 0.500000000 0.109211585
82 | 0.750000000 0.500000000 0.327634755
83 | 0.875000000 0.625000000 0.163817377
84 | 0.875000000 0.625000000 0.382240547
85 | 0.500000000 0.750000000 0.109211585
86 | 0.500000000 0.750000000 0.327634755
87 | 0.625000000 0.875000000 0.163817377
88 | 0.625000000 0.875000000 0.382240547
89 |
--------------------------------------------------------------------------------
/docs/source/tutorials/generating_tutorial.rst:
--------------------------------------------------------------------------------
1 | .. generating_tutorial:
2 |
3 |
4 | =====================
5 | Generating structures
6 | =====================
7 |
8 |
9 | This tutorial will detail the `generate` procedure for generating structures using the RAFFLE generator.
10 |
11 | The `generator` procedure is the process of adding atoms to the host structure to generate new structures.
12 |
13 | .. note::
14 | The host structure must be set before generating structures. See :doc:`Host tutorial ` for more information.
15 |
16 |
17 | Input arguments
18 | ---------------
19 |
20 | The generating procedure has several arguments that can be set to control the generation of structures.
21 |
22 | The arguments are as follows:
23 |
24 | - ``num_structures``: The number of structures to generate.
25 | - ``stoichiometry``: A dictionary of the stoichiometry of atoms to add.
26 | - ``method_ratio``: A dictionary of the ratio of each method to use.
27 | - ``settings_out_file``: The file to write the settings to.
28 | - ``calc``: The calculator to attach to the generated structures.
29 | - ``seed``: The seed for the random number generator.
30 | - ``verbose``: The verbosity level of the generator.
31 | - ``return_exit_code``: Whether to return the exit code of the generator.
32 |
33 |
34 | The accepted keys for the ``method_ratio`` dictionary are:
35 |
36 | - ``min`` (or ``minimum`` or ``global``): The minimum method.
37 | - ``walk``: The walk method.
38 | - ``grow`` or (``growth``): The grow method.
39 | - ``void``: The void method.
40 | - ``rand`` or (``random``): The random method.
41 |
42 |
43 | Example
44 | -------
45 |
46 | The following example demonstrates how to generate structures using the RAFFLE generator.
47 |
48 | .. code-block:: python
49 |
50 | from raffle.generator import raffle_generator
51 | from mace.calculators import mace_mp
52 |
53 | ... # Define an ASE Atoms object for the host structure
54 |
55 | # Set the host structure
56 | generator = raffle_generator()
57 | generator.set_host(host)
58 |
59 | # Set the generating arguments
60 | generator.generate(
61 | num_structures = 10,
62 | stoichiometry = {'Al': 1, 'O': 2},
63 | method_ratio = {
64 | 'min': 5.0,
65 | 'walk': 3.0,
66 | 'grow': 2.0
67 | 'void': 1.0
68 | 'rand': 0.1
69 | },
70 | settings_out_file = 'settings.json',
71 | calc = mace_mp(),
72 | seed = 42,
73 | verbose = 1,
74 | return_exit_code = False
75 | )
76 |
77 |
78 |
79 | The above example generates 10 structures with a stoichiometry of 1 Al and 2 O atoms.
80 | The five methods are used with the specified ratios, with the values being renormalised to sum to 1 after the input.
81 |
82 | The settings are written to the file ``settings.json`` for future reference to improve reproducibility.
83 | By default, if no file is specified, the settings are not written to a file.
84 |
85 | The calculator is attached to the generated structures to calculate the energies of the structures.
86 | The seed is set to 42 to ensure reproducibility of the random number generator.
87 |
88 | The verbosity level is set to 2 to provide detailed information about the generation process.
89 | Default verbosity is 0, which provides no output.
90 |
91 |
92 | Retrieving generated structures
93 | -------------------------------
94 |
95 | The generated structures are returned as a list of ASE Atoms objects.
96 |
97 | .. code-block:: python
98 |
99 | structures = generator.generate()
100 |
101 | The ``structures`` variable contains the list of generated structures for that iteration
102 |
103 | Optionally, if the ``return_exit_code`` argument is set to ``True``, the exit code of the generator can be retrieved using the following command:
104 |
105 | .. code-block:: python
106 |
107 | structures, status = generator.generate(return_exit_code=True)
108 |
109 | The ``status`` variable contains the status of the generation process, which can be used to check for errors.
110 | A successful generation will return a status of 0, while an error will return a non-zero status.
111 |
112 | Optionally, all structures generated thus far using the generator can be retrieved using the following command:
113 |
114 | .. code-block:: python
115 |
116 | all_structures = generator.get_structures()
117 |
--------------------------------------------------------------------------------
/example/python_pkg/C_learn/DRSS/rss.py:
--------------------------------------------------------------------------------
1 | # https://agox.gitlab.io/agox/command_line_tools/command_line.html
2 |
3 | import matplotlib
4 |
5 | matplotlib.use("Agg")
6 |
7 |
8 | import numpy as np
9 | from ase import Atoms
10 | from ase.io import write
11 |
12 | from agox import AGOX
13 | from agox.databases import Database
14 | from agox.environments import Environment
15 | from agox.evaluators import LocalOptimizationEvaluator
16 | from agox.generators import RandomGenerator
17 | from agox.postprocessors import MinimumDistPostProcess
18 |
19 |
20 | database_index = 0
21 | iteration_directory = "iteration"
22 |
23 | ##############################################################################
24 | # Calculator
25 | ##############################################################################
26 |
27 | # from mace.calculators import mace_mp
28 | from chgnet.model import CHGNetCalculator
29 | from ase.build import bulk
30 | import os
31 |
32 | # calc = mace_mp()
33 | calc = CHGNetCalculator()
34 |
35 | ##############################################################################
36 | # System & general settings:
37 | ##############################################################################
38 |
39 |
40 | diamond = bulk("C", "diamond", a=3.567) # Lattice constant for diamond cubic carbon
41 | diamond.write("diamond.traj")
42 | post1 = MinimumDistPostProcess(order=1.5, c1=0.75)
43 | post2 = MinimumDistPostProcess(order=2.5, c1=0.75)
44 |
45 | # Make an empty template with a cubic cell of size 6x6x6 with periodic boundary conditions
46 | # in all directions
47 | a = 3.567
48 | iteration = 0
49 | template = Atoms("", cell=np.eye(3) * a, pbc=True)
50 |
51 |
52 | # Confinement cell matches the template cell in all dimensions and is placed at
53 | # the origin of the template cell.
54 | confinement_cell = template.cell.copy()
55 | confinement_corner = np.array([0, 0, 0])
56 |
57 | environment = Environment(
58 | template=template,
59 | symbols="C8",
60 | confinement_cell=confinement_cell,
61 | confinement_corner=confinement_corner,
62 | box_constraint_pbc=[True, True, True], # Confinement is periodic in all directions.
63 | )
64 |
65 | # Database
66 | db_directory = iteration_directory+"{}".format(iteration)+"/"
67 | if not os.path.exists(db_directory):
68 | os.makedirs(db_directory)
69 | db_path = db_directory+"db{}.db".format(database_index) # From input argument!
70 |
71 | for seed in range(20):
72 | database = Database(filename=db_path, order=3, initialize=True)
73 |
74 | ##############################################################################
75 | # Search Settings:
76 | ##############################################################################
77 |
78 | random_generator = RandomGenerator(**environment.get_confinement(), environment=environment, order=1)
79 |
80 | # Wont relax fully with steps:5 - more realistic setting would be 100+.
81 | evaluator = LocalOptimizationEvaluator(
82 | calc,
83 | gets={"get_key": "candidates"},
84 | optimizer_run_kwargs={"fmax": 0.05, "steps": 100},
85 | store_trajectory=True,
86 | order=2,
87 | constraints=environment.get_constraints(),
88 | )
89 |
90 | ##############################################################################
91 | # Let get the show running!
92 | ##############################################################################
93 |
94 | agox = AGOX(random_generator, database, evaluator, seed=seed)
95 |
96 | agox.run(N_iterations=1000)
97 |
98 | structure_data = database.get_all_structures_data()
99 | # check iteration number has changed
100 | iteration_check = -1
101 | unrlxd_structures = []
102 | rlxd_structures = []
103 | for idx, structure in enumerate(structure_data):
104 | if structure["iteration"] != iteration_check:
105 | iteration_check = structure["iteration"]
106 | unrlxd_structures.append(database.db_to_atoms(structure))
107 | if idx != 0:
108 | rlxd_structures.append(database.db_to_atoms(structure_data[idx-1]))
109 | if len(rlxd_structures) != len(unrlxd_structures):
110 | rlxd_structures.append(database.db_to_atoms(structure_data[-1]))
111 |
112 | print("Unrelaxed structures", len(unrlxd_structures))
113 | print("Relaxed structures", len(rlxd_structures))
114 | write(f"unrlxd_structures_seed{seed}.traj", unrlxd_structures)
115 | write(f"rlxd_structures_seed{seed}.traj", rlxd_structures)
116 |
117 | # database.restore_to_memory()
118 | # structures = database.get_all_candidates() # this is an Atoms object with some more stuff
119 |
--------------------------------------------------------------------------------
/tools/check_accuracy_ScS2-Li.py:
--------------------------------------------------------------------------------
1 | import os
2 | import numpy as np
3 | from pathlib import Path
4 |
5 | script_dir = Path(__file__).resolve().parent
6 |
7 | ## import ASE (Atomic Simulation Environment) modules
8 | from ase import Atoms
9 | from ase.optimize import BFGS
10 | from ase.filters import FrechetCellFilter
11 | from ase.constraints import FixAtoms
12 | from ase.io import read, write
13 | from ase.calculators.singlepoint import SinglePointCalculator
14 |
15 |
16 | ## load calculator
17 | from chgnet.model.dynamics import CHGNetCalculator
18 | print("Initialising CHGNet calculator")
19 | chgnet = CHGNetCalculator()
20 | from mace.calculators import mace_mp
21 | print("Initialising MACE calculator")
22 | calc_params = { 'model': "../example/python_pkg/mace-mpa-0-medium.model" }
23 | mace = mace_mp(**calc_params)
24 | # calc = mace_mp(model="medium", dispersion=False, default_dtype="float32", device='cpu')
25 |
26 |
27 | ## Read the database
28 | print("Reading database")
29 | database = read("../example/data/ScS2-Li.xyz", index=":")
30 | lowest_energy_index = -1
31 | lowest_energy = float('inf')
32 | # Get the lowest energy structure with just the stoichiometry ScS2
33 | for atoms in database:
34 | if atoms.calc is None:
35 | continue
36 | if atoms.get_chemical_formula(empirical=True) == "ScS2" or "S2Sc":
37 | n_Sc = atoms.get_atomic_numbers().tolist().count(21)
38 | energy = atoms.get_potential_energy() / n_Sc
39 | if energy < lowest_energy:
40 | lowest_energy = energy
41 | lowest_energy_index = database.index(atoms)
42 | print(f"Found ScS2 structure with energy {energy} at index {lowest_energy_index}")
43 |
44 | if atoms.get_chemical_formula(empirical=True) == "Li":
45 | print(f"Found Li structure at index {database.index(atoms)}")
46 |
47 | n_Sc = database[lowest_energy_index].get_atomic_numbers().tolist().count(21)
48 | Li = read( script_dir / "../example/python_pkg/ScS2-Li_learn/Li.xyz", index=0 )
49 | Li_energy_dft = Li.get_potential_energy() / len(Li) # Li_AE_GW POT
50 | ScS2_energy_dft = database[lowest_energy_index].get_potential_energy() / n_Sc
51 | ScS2_ground_state = database[lowest_energy_index].copy()
52 |
53 | Li_chgnet = Li.copy()
54 | Li_chgnet.calc = chgnet
55 | Li_chgnet.set_constraint(FixAtoms(mask=[True for atom in Li_chgnet]))
56 | ecf = FrechetCellFilter(Li_chgnet)
57 | # structurally optimized Li structure
58 | opt = BFGS(ecf)
59 | opt.run(fmax=0.02)
60 | Li.calc = chgnet
61 | Li_energy_chgnet = Li_chgnet.get_potential_energy() / len(Li_chgnet)
62 |
63 | Li_mace = Li.copy()
64 | Li_mace.calc = mace
65 | Li_mace.set_constraint(FixAtoms(mask=[True for atom in Li_mace]))
66 | ecf = FrechetCellFilter(Li_mace)
67 | # structurally optimized Li structure
68 | opt = BFGS(ecf)
69 | opt.run(fmax=0.02)
70 | Li_energy_mace = Li_mace.get_potential_energy() / len(Li_mace)
71 | ScS2_ground_state.calc = chgnet
72 | ScS2_energy_chgnet = ScS2_ground_state.get_potential_energy() / n_Sc
73 | ScS2_ground_state.calc = mace
74 | ScS2_energy_mace = ScS2_ground_state.get_potential_energy() / n_Sc
75 |
76 | ## Calculate the energies
77 | formation_energies_dft = []
78 | formation_energies_mace = []
79 | formation_energies_chgnet = []
80 | for i, atoms in enumerate(database):
81 | if atoms.calc is None:
82 | database.remove(atoms)
83 | continue
84 | if not atoms.get_chemical_formula(empirical=True) == "LiS2Sc":
85 | continue
86 | # get number of Li atoms in the structure
87 | n_Li = atoms.get_atomic_numbers().tolist().count(3)
88 | # get number of Sc atoms in the structure
89 | n_Sc = atoms.get_atomic_numbers().tolist().count(21)
90 | formation_energy_dft = ( atoms.get_potential_energy() - n_Li * Li_energy_dft - n_Sc * ScS2_energy_dft ) / n_Sc / n_Li
91 | formation_energies_dft.append(formation_energy_dft)
92 | atoms.calc = chgnet
93 | formation_energy_chgnet = ( atoms.get_potential_energy() - n_Li * Li_energy_chgnet - n_Sc * ScS2_energy_chgnet ) / n_Sc / n_Li
94 | formation_energies_chgnet.append(formation_energy_chgnet)
95 | atoms.calc = mace
96 | formation_energy_mace = ( atoms.get_potential_energy() - n_Li * Li_energy_mace - n_Sc * ScS2_energy_mace ) / n_Sc / n_Li
97 | formation_energies_mace.append(formation_energy_mace)
98 |
99 |
100 | ## Write energies to a file
101 | with open("ScS2-Li_formations_comparison.txt", "w") as f:
102 | f.write("# DFT_Formation_energy_per_atom MACE-MPA-0_Formation_energy_per_atom CHGNet_Formation_energy_per_atom\n")
103 | for dft_energy, mace_energy, chgnet_energy in zip(formation_energies_dft, formation_energies_mace, formation_energies_chgnet):
104 | f.write(f"{dft_energy} {mace_energy} {chgnet_energy}\n")
105 |
--------------------------------------------------------------------------------
|