Commit f1210e0d authored by Malthe Kjær Bisbo's avatar Malthe Kjær Bisbo
Browse files

Initialized sphinx documentation with a few turorials + added hessian to gauss_kernel

parent b9ff7151
import numpy as np
from ase.calculators.dftb import Dftb
from ase.io import read
from candidate_operations.candidate_generation import CandidateGenerator, StartGenerator
from candidate_operations.basic_mutations import RattleMutation, PermutationMutation
from gofee import GOFEE
### Define calculator ###
calc = Dftb(label='TiO2_surface',
Hamiltonian_SCC='No',
Hamiltonian_MaxAngularMomentum_='',
Hamiltonian_MaxAngularMomentum_Ti='"d"',
Hamiltonian_MaxAngularMomentum_O='"p"',
Hamiltonian_Charge='0.000000',
Hamiltonian_Filling ='Fermi {',
Hamiltonian_Filling_empty= 'Temperature [Kelvin] = 0.000000',
kpts=(2,1,1))
### Set up StartGenerator and mutations ###
# read slab
slab = read('TiO2_slab.traj', index='0')
# Stoichiometry of atoms to be placed
stoichiometry = 5*[22]+10*[8]
# Box in which to place atoms
v = slab.get_cell()
v[2,2] = 2.5
p0 = np.array((0.0,0.,8.))
box = [p0, v]
# initialize startgenerator
sg = StartGenerator(slab, stoichiometry, box)
# initialize rattle and permutation mutations
n_to_optimize = len(stoichiometry)
permutation = PermutationMutation(n_to_optimize, Npermute=2)
rattle = RattleMutation(n_to_optimize, Nrattle=3, rattle_range=4)
candidate_generator = CandidateGenerator([0.2, 0.2, 0.6],
[sg, permutation, rattle])
### Initialize and run search ###
search = GOFEE(calc=calc,
startgenerator=sg,
candidate_generator=candidate_generator,
max_steps=100,
population_size=5)
search.run()
\ No newline at end of file
# Creates: structures.traj
import numpy as np
from ase import Atoms
from ase.calculators.dftb import Dftb
from candidate_operations.candidate_generation import CandidateGenerator, StartGenerator
from candidate_operations.basic_mutations import RattleMutation
from gofee import GOFEE
### Define calculator ###
calc = Dftb(label='TiO2_surface',
Hamiltonian_SCC='No',
Hamiltonian_MaxAngularMomentum_='',
Hamiltonian_MaxAngularMomentum_Ti='"d"',
Hamiltonian_MaxAngularMomentum_O='"p"',
Hamiltonian_Charge='0.000000',
Hamiltonian_Filling ='Fermi {',
Hamiltonian_Filling_empty= 'Temperature [Kelvin] = 0.000000',
kpts=(1,1,1))
### Set up system ###
# make empty cell
template = Atoms('',
cell=[20,20,20],
pbc=[0, 0, 0])
# Stoichiometry of atoms to be placed
stoichiometry = 5*[22]+10*[8]
# Box in which to place atoms randomly
v = 4*np.eye(3)
p0 = np.array((8.0, 8.0, 8.0))
box = [p0, v]
# initialize startgenerator (used to generate initial structures)
sg = StartGenerator(template, stoichiometry, box)
### Set up candidate generation operations ###
# initialize rattle mutation
n_to_optimize = len(stoichiometry)
rattle = RattleMutation(n_to_optimize, Nrattle=3, rattle_range=4)
candidate_generator = CandidateGenerator(probabilities=[0.2, 0.8],
operations=[sg, rattle])
### Initialize and run search ###
search = GOFEE(calc=calc,
startgenerator=sg,
candidate_generator=candidate_generator,
max_steps=100,
population_size=5)
search.run()
\ No newline at end of file
......@@ -3,19 +3,14 @@
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to GOFEE's documentation!
Welcome to the documentation for GOFEE!
=================================
The global optimization with first-principles energy expression (GOFEE) is
a global optimization method used to optimize the geometry of atomistic
systems.
.. toctree::
:maxdepth: 2
:caption: Contents:
modules
getting_started
tutorial/tutorial
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
......@@ -151,12 +151,5 @@ the :class:`StartGenerator` with 20% probability, the
Gaussian Process Regression (GPR) model
=======================================
.. module:: gofee
:synopsis: GOFEE
.. autoclass:: GOFEE
.. autoclass:: gofee.GOFEE
.. class:: GOFEE
\ No newline at end of file
:members:
\ No newline at end of file
================
GOFEE
================
The following is an introduction to the structure determination method
:class:`GOFEE`, which relies on Gaussian Process Regression model to
more efficiently explore the configurational search space.
When initializing the search, the two most important pieces of
information, is what system to optimize and what energy expression
(in the form of an ase.calculator) to optimize with respect to.
There two ways of supplying the information of what system to optimize.
1) The search can be initialized with one or more :class:`ase.Atoms`
objects, and the search will optimize all non-fixed atoms in the
system.
2) By defining a :class:`StartGenerator`, that randomly initializes
the atoms, to be optimized, within a user-specified box. Using this
box, the atoms ate placed within the cell of a supplied
:class:`ase.Atoms` objects, which potentially contains fixed slab
atoms.
Initializing the search with just a structure and a calculator looks
like this::
# Creates: structures.traj
import numpy as np
from ase import Atoms
from gpaw import GPAW, FermiDirac, PoissonSolver, Mixer, PW
from gpaw import extra_parameters
extra_parameters['blacs'] = True
from gpaw.utilities import h2gpts
from gofee import GOFEE
# Define calculator
calc=GPAW(poissonsolver = PoissonSolver(relax = 'GS',eps = 1.0e-7),
mode = 'lcao',
basis = 'dzp',
xc='PBE',
gpts = h2gpts(0.2, slab.get_cell(), idiv = 8),
occupations=FermiDirac(0.1),
maxiter=99,
mixer=Mixer(nmaxold=5, beta=0.05, weight=75),
nbands=-50,
kpts=(1,1,1))
# Load structure to initialise search
positions = np.random.uniform(8.5,11.5,36).reshape(-1,3)
a = Atoms('C6H6',
positions=positions,
cell=(20,20,20))
# Initialize and run search
search = GOFEE(structures=a,
calc=calc,
trajectory='structures.traj',
max_steps=200)
search.run()
Specifying the system - supplying Structures
============================================
Specifying the system - supplying StartGenerator
================================================
Basic settings
==============
CandidateGenerator
==================
Gaussian Process Regression (GPR) model
=======================================
=========================
Modifying surrogate model
=========================
This tutorial extends the previous one for TiO clusters,
:ref:`searching for TiO clusters <searching-for-TiO-clusters>`. It is
therefore recomended that you do that one before the present one.
In the avove mentioned tutorial GOFEE was initialized with the following
arguments::
search = GOFEE(calc=calc,
startgenerator=sg,
candidate_generator=candidate_generator,
max_steps=100,
population_size=5)
however GOFEE takes a number of other arguments, including a
Gaussian Process regression (GPR) model, which is actively learned
during the search and used for cheap optimization of new candidates.
One can for example apply a GPR model with another degree of regularization
in the search. As the regularization is a parameter of the *kernel*, passed
to the GPR model, the code will look like this::
from surrogate.gpr import GPR
from surrogate.kernel import double_gauss_kernel
kernel = double_gauss_kernel(noise=1e-6)
gpr = GPR(kernel=kernel)
search = GOFEE(calc=calc,
gpr=gpr,
startgenerator=sg,
candidate_generator=candidate_generator,
max_steps=100,
population_size=5)
================================================
Searching for the TiO2(001)-(1x4) reconstruction
================================================
For this tutorial we will use the dftb-calculator with
the tiorg parameters.
This tutorial is very similar to the previous one for TiO clusters,
:ref:`searching for TiO clusters <searching-for-TiO-clusters>`. It is
recomended that you do that one before the present one, as it is more
detailed.
The major difference in the present tutorial is that the template will
now not be empty, but contain a number of atoms fixed at bulk positions.
The template is defined in the file :download:`TiO2_slab.traj`. The
following code :download:`TiO2.py` is used to carry out the search:
.. literalinclude:: TiO2.py
If ASE, GPAW and dftb are set up and sourced propperly, you can run
the code as::
mpiexec --mca mpi_warn_on_fork 0 gpaw-python run_search.py
Setting up the system - atoms in template
=========================================
In this case the *template* contains a number of fixed atoms representing the
slap, on top of which we want to optimize a number of atoms given by
*stoichiometry*. The final thing we need to initialize the :class:`StartGenerator`
, used for generation initial structures, is the *box* within which the
:class:`StartGenerator` places atoms randomly.
In this case we choose a box=[p0, v] of height 2.5 starting at p0=(0,0,8), which
is slightly above the slab atoms.
To initialize the startgenerator, we first read in the template::
from ase.io import read
slab = read('TiO2_slab.traj', index='0')
then define the stoichiometry of atoms to be optimized on top of the slab,
in the form of a list of atomic numbers::
stoichiometry = 5*[22]+10*[8]
Then define the *box* within which the :class:`StartGenerator` places atoms randomly::
import numpy as np
v = slab.get_cell()
v[2,2] = 2.5
p0 = np.array((0.0,0.,8.))
box = [p0, v]
Finally the :class:`StartGenerator` can be initialized::
from candidate_operations.candidate_generation import StartGenerator
sg = StartGenerator(slab, stoichiometry, box)
\ No newline at end of file
.. _searching-for-TiO-clusters:
==========================
Searching for TiO clusters
==========================
For this tutorial we will use the dftb-calculator with
the tiorg parameters.
In this tutorial we carry out a search for titanium-oxide clusters using
dftb to evaluate energies and forses of the structures.
The following script :download:`Ti5O10.py` is used to carry out the search (the indivitual elements are
explainted further below):
.. literalinclude:: Ti5O10.py
If ASE, GPAW and dftb are set up and sourced propperly, you can run
the code as::
mpiexec --mca mpi_warn_on_fork 0 gpaw-python run_search.py
What follows is a description of the python script above.
Setting up the system
=====================
An important prerequisite for starting a search is to set up the system.
This is done by defining a template and a stoichiometry of the atoms to
optimize.
The *template* is an :class:`Atoms` object, either describing an empty cell or
a cell containing for example a slab of atoms. For most purposes, the atoms
in the template shold be fixed using :class:`ase.constraints.FixAtoms`
constraint, as the template atoms are kept fixed during mutation operation,
but will take part in surrogate-relaxation if not fixed.
In this example the template is taken to be an empty 20Åx20Åx20Å cell, since
we considder isolated TiO-clusters. The code to generate the template is::
from ase import Atoms
template = Atoms('',
cell=[20,20,20],
pbc=[0, 0, 0])
The *stoichiometry* of atoms to optimize is a list of atomic numbers. In this
case 5 titanium (atomic nymber 22) and 10 oxygen (atomic number 8) atoms::
stoichiometry = 5*[22]+10*[8]
Startgenerater - for making initial structures
==============================================
To initialize the search, initial structures need to be generated. This is
carried out using the :class:`StartGenerator`, which in addition to the
*template* and *stoichiometry* defined above, need a *box* in which to randomly
place the atoms defined in the *stoichiometry*.
The *box* is naturally defined by a point *p0* and three spanning vectors going
out from that point. These are defined bu the 3x3 matrix *v* in the example.
In the example a 20Åx20Åx20Å square box in the center of the cell is used::
import numpy as np
v = 4*np.eye(3)
p0 = np.array((8.0, 8.0, 8.0))
box = [p0, v]
The *startgenerator* can then be initialized with the code::
from candidate_operations.candidate_generation import StartGenerator
sg = StartGenerator(template, stoichiometry, box)
CandidateGenerator
==================
In GOFEE, the configurational space is explored by generation new candidate structures.
New candidates can be either completely random structures made using the *startgenerator*
or they can be the result of applying mutation operations to a population of some of the
best structures visited during the search. Examples of mutaion operations are the
:class:'RattleMutation', which randomly shifts some of the atoms and the
:class:`PermutaionMutation` which randomly permutes some atoms of different type.
The rattle mutation in the example, which rattles on average Natoms=3 atom a maximum distance of
rattle_range=4Å, is initialized as::
from candidate_operations.basic_mutations import RattleMutation
n_to_optimize = len(stoichiometry)
rattle = RattleMutation(n_to_optimize, Nrattle=3, rattle_range=4)
Given some of the above described operations. e.g. a :class:`StartGenerator`
and a :class:'RattleMutation', one can initialize a :class:`CandidateGenerator`,
which handles the generation of new candidates by applying the supplied
*operations* with probability specified in the *probabilities* list.
A CandidateGenerator which uses the startgenerator *sg* with 20% probability and
the rattle operation *rattle* with 80% probability, is initialized as follows::
from candidate_operations.candidate_generation import CandidateGenerator
candidate_generator = CandidateGenerator(probabilities=[0.2, 0.8],
operations=[sg, rattle])
Initialize and run GOFEE
========================
With all the above objects defined, we are ready to initialize and run GOFEE.
To run the search for 100 iterations with a population size of 5, use::
from gofee import GOFEE
search = GOFEE(calc=calc,
startgenerator=sg,
candidate_generator=candidate_generator,
max_steps=100,
population_size=5)
search.run()
This tutorial relies on many default settings of GOFEE, which could be changed.
To see how these settings are changed, have a look at the other tutorials.
========
Tutorial
========
This is the turorial for the GOFEE structure search.
.. toctree::
:maxdepth: 1
tio_clusters/tio_clusters
tio2_reconstruction/tio2_reconstruction
modifying_surrogate_model/modifying_surrogate_model
\ No newline at end of file
@import url("basic.css");
/* -- page layout ----------------------------------------------------------- */
body {
font-family: Georgia, serif;
font-size: 17px;
background-color: #fff;
color: #000;
margin: 0;
padding: 0;
}
div.document {
width: 940px;
margin: 30px auto 0 auto;
}
div.documentwrapper {
float: left;
width: 100%;
}
div.bodywrapper {
margin: 0 0 0 220px;
}
div.sphinxsidebar {
width: 220px;
font-size: 14px;
line-height: 1.5;
}
hr {
border: 1px solid #B1B4B6;
}
div.body {
background-color: #fff;
color: #3E4349;
padding: 0 30px 0 30px;
}
div.body > .section {
text-align: left;
}
div.footer {
width: 940px;
margin: 20px auto 30px auto;
font-size: 14px;
color: #888;
text-align: right;
}
div.footer a {
color: #888;
}
p.caption {
font-family: inherit;
font-size: inherit;
}
div.relations {
display: none;
}
div.sphinxsidebar a {
color: #444;
text-decoration: none;
border-bottom: 1px dotted #999;
}
div.sphinxsidebar a:hover {
border-bottom: 1px solid #999;
}
div.sphinxsidebarwrapper {
padding: 18px 10px;
}
div.sphinxsidebarwrapper p.logo {
padding: 0;
margin: -10px 0 0 0px;
text-align: center;
}
div.sphinxsidebarwrapper h1.logo {
margin-top: -10px;
text-align: center;
margin-bottom: 5px;
text-align: left;
}
div.sphinxsidebarwrapper h1.logo-name {
margin-top: 0px;
}
div.sphinxsidebarwrapper p.blurb {
margin-top: 0;
font-style: normal;
}
div.sphinxsidebar h3,
div.sphinxsidebar h4 {
font-family: Georgia, serif;
color: #444;
font-size: 24px;
font-weight: normal;
margin: 0 0 5px 0;
padding: 0;
}
div.sphinxsidebar h4 {
font-size: 20px;
}
div.sphinxsidebar h3 a {
color: #444;
}
div.sphinxsidebar p.logo a,
div.sphinxsidebar h3 a,
div.sphinxsidebar p.logo a:hover,
div.sphinxsidebar h3 a:hover {
border: none;
}
div.sphinxsidebar p {
color: #555;
margin: 10px 0;
}
div.sphinxsidebar ul {
margin: 10px 0;
padding: 0;
color: #000;
}