.. parameters:

==================
Setting parameters
==================

This tutorial will detail how to change RAFFLE parameters.
These parameters are mainly used in building the RAFFLE descriptors for a database.
For a guide on how to build a database, see the :doc:`Databases tutorial </tutorials/databases_tutorial>`.





Initialisation
--------------

RAFFLE is initialised by importing the generator object.
This object is the main interface for the user to interact with the RAFFLE package.

.. code-block:: python

    # Initialise RAFFLE generator
    from raffle.generator import raffle_generator

    generator = raffle_generator()


It is recommended to use the Atomic Simulation Environment (ASE)~\cite{ase-paper} for handling structure data.
Whilst RAFFLE can handle its own atomic structure object, ASE is more widely used and has a more extensive feature set.


Convergence criteria
--------------------

RAFFLE has a convergence criterion that compares the amount of change in the RAFFLE descriptor over the last ``history_len`` update iterations.
When the total change in the descriptor for the last ``history_len`` iterations is less than ``threshold``, the generator can be considered converged.
Without explicitly setting the ``history_len``, the convergence is not checked.

To set the convergence criteria, the user can use the ``set_history_len`` method.

.. code-block:: python

    # Set convergence criteria
    generator.set_history_len(
        history_len=10
    )

To check the convergence, the user can use the ``is_converged`` method (default ``threshold = 1e-4``).

.. code-block:: python

    # Check convergence
    converged = generator.is_converged(threshold=1e-5)
    print(f"Converged: {converged}")

Note, the convergence criterion is not enforced, i.e. the generator will not stop generating structures when the convergence criterion is met and the ``update`` method can still be called.
As such, it is recommended that the user implement their own convergence check in their code.

.. note::
    The convergence criterion is not tested without explicitly setting the ``history_len`` parameter.
    The convergence criterion is also not enforced even when set, it is simply a check for the user to use.


Placement methods
-----------------

RAFFLE uses a random sampling of five placement methods to place atoms in the host structure.
These methods are:
- ``rand``: Randomly place atoms in the host structure.
- ``void``: Place atoms at the point furthest from the nearest atom in the host structure.
- ``walk``: Start from a random position and walk to a local minimum in the RAFFLE-calculated probability.
- ``grow``: Start from the previously placed atom and walk to a local minimum in the RAFFLE-calculated probability.
- ``min``: Place atoms at the point of highest RAFFLE-calculated probability.

The ratio of these methods can be set by the user.
This can either be done on a per-generate method basis, or as a global setting.

To set the default placement method ratios, the user can use the ``set_method_ratio_default`` method.

.. code-block:: python

    # Set default placement method ratios
    generator.set_method_ratio_default(
        method_ratio = {
            'rand': 0.1,
            'void': 0.1,
            'walk': 0.25,
            'grow': 0.25,
            'min': 1.0
        }
    )

These defaults will then be used for all generation methods where the user does not specify a method ratio.

To set the placement method ratios for a specific generation method, the user can define the method ratio ``dict`` in the ``generate`` method.

.. code-block:: python

    # Set placement method ratios for a specific generation method
    generator.generate(
        method_ratio = {
            'rand': 0.1,
            'void': 0.1,
            'walk': 0.25,
            'grow': 0.25,
            'min': 1.0
        },
        # Other generation parameters
        ...
    )


.. _element-energies:

Energy references
-----------------

Energy references do not have built-in default values, as they depend on specific calculation conditions (e.g. calculator choice, DFT functional choice, pseudopotential selection).
To avoid misleading or inaccurate results, users must define reference energies explicitly:

.. code-block:: python

    # Set reference energies
    generator.distributions.set_element_energies( {
        'Si': -5.31218, # energy per atom of Si bulk
        'Ge': -4.44257  # energy per atom fo Ge bulk
    } )


These reference energies are used to calculate the formation energies of the structures generated by RAFFLE.
These are ignored if using the convex hull energies instead, but still need to be set to a value (e.g. 0.0) to avoid errors.
The formation energy is calculated as:

.. math::
  E_f = \frac{ E_{\text{structure}} - \sum_i n_i E_i }{ \sum_i n_i }


where :math:`E_{\text{structure}}` is the energy of the structure, :math:`n_i` is the number of atoms of element :math:`i` in the structure, and :math:`E_i` is the reference energy of element :math:`i`.


Gaussian parameters and cutoffs
-------------------------------

The distribution functions are built using Gaussian functions.
They are used to determine the probability of placing an atom at a given position.
The distribution functions are scaled by the relative energies of the systems (i.e. formation energy) and combined to form a generalised descriptor.
The user can set the energy scaling, Gaussian smearing, width, and cutoff tolerances.

.. code-block:: python

    # Set Gaussian parameters
    generator.distributions.set_kBT(0.2)
    generator.distributions.set_sigma(
        [0.1, 0.2, 0.3]
    )
    generator.distributions.set_width(
        [0.1, 0.2, 0.3]
    )
    generator.distributions.cutoff_min(
        [0.0, 0.0, 0.0]
    )
    generator.distributions.cutoff_max(
        [6.0, 3.14159, 3.14159]
    )
    generator.distributions.set_radius_distance_tol(
        [1.5, 2.5, 3.0, 6.0]
    )


The Gaussian width is the standard deviation of the Gaussian function.
The cutoffs are the minimum and maximum values of the Gaussian function.
The radius distance tolerance is a multiple of the element-pair covalent radius, similar to that used in AGOX :footcite:t:`Christiansen2022AtomisticGlobalOptimization`.

The default value for the element-pair covalent radius is the average of the covalent radii of the two elements.
This can be customised by the user:

.. code-block:: python

    # Set reference element-pair covalent radii
    generator.distributions.set_bond_radii( {
        ('Si', 'Ge'): 1.165 # average bond length
    } )


Grid settings
-------------

The grid settings are used to define the grid on which the generator operates.
This grid is used for the placement of atoms in the host structure, specifically, the void and min methods.
The grid spacing is the distance between grid points.
The grid offset is the displacement of grid points from the cell origin (0,0,0) in fractional coordinates.

.. code-block:: python

    # Define grid for placement methods
    generator.set_grid(
        grid_spacing=0.1,
        grid_offset=[0.0, 0.0, 0.0]
    )


Alternatively, the user can define the number of grid points along the three axes:

.. code-block:: python

    # Define grid for placement methods
    generator.set_grid(
        grid=[1, 2, 3],
        grid_offset=[0.1, 0.1, 0.1]
    )



.. footbibliography::
