# AtomsCalculators integration

AtomsCalculators.jl is an interface for doing standard computations (energies, forces, stresses, hessians) on atomistic structures. It is very much inspired by the calculator objects in the atomistic simulation environment.

DFTK by default ships a datastructure called a `DFTKCalculator`

, which implements the AtomsCalculators interface. A `DFTKCalculator`

can be constructed by passing three different named tuples, the `model_kwargs`

, the `basis_kwargs`

and the `scf_kwargs`

. The first two named tuples are passed as keyword arguments when constructing the DFT model using `model_DFT`

and its discretization using the `PlaneWaveBasis`

. The last one is used as keyword arguments when running the `self_consistent_field`

function on the resulting basis to solve the problem numerically. Thus when using the `DFTKCalculator`

the user is expected to pass these objects exactly the keyword argument one would pass when constructing a `model`

and `basis`

and when calling `self_consistent_field`

.

For example, to perform the calculation of the Tutorial using the AtomsCalculators interface we define the calculator as such:

```
using DFTK
model_kwargs = (; functionals=LDA())
basis_kwargs = (; kgrid=[4, 4, 4], Ecut=7)
scf_kwargs = (; tol=1e-5)
calc = DFTKCalculator(; model_kwargs, basis_kwargs, scf_kwargs)
```

`DFTKCalculator{Nothing}(DFTK.DFTKParameters((functionals = Xc(lda_x, lda_c_pw),), (kgrid = [4, 4, 4], Ecut = 7), (tol = 1.0e-5, callback = identity)), nothing, Base.RefValue{Int64}(0), Base.RefValue{Int64}(0), true)`

Note, that the `scf_kwargs`

is optional and can be missing (then the defaults of `self_consistent_field`

are used).

Note that DFTK's `kgrid_from_maximal_spacing`

function can also be used with `AbstractSystem`

objects to determine an appropriate `kgrid`

paramter for the `basis_kwargs`

. E.g. `kgrid_from_maximal_spacing(system, 0.25u"1/Å")`

gives a k-point spacing of `0.25`

per Angström for the passed system.

Based on this `calc`

object we can perform a DFT calculation on bulk silicon according to the `AtomsCalculators`

interface, e.g.

```
using AtomsBuilder
using AtomsCalculators
AC = AtomsCalculators
# Bulk silicon system of the Tutorial
silicon = attach_psp(bulk(:Si); Si="hgh/lda/si-q4")
AC.potential_energy(silicon, calc) # Compute total energy
```

`-7.905243533163027 Eₕ`

or we can compute the energy and forces:

```
results = AC.calculate((AC.Energy(), AC.Forces()), silicon, calc)
results.energy
```

`-7.905243533175222 Eₕ`

`results.forces`

```
2-element Vector{StaticArraysCore.SVector{3, Unitful.Quantity{Float64, 𝐋 𝐌 𝐓^-2, Unitful.FreeUnits{(a₀^-1, Eₕ), 𝐋 𝐌 𝐓^-2, nothing}}}}:
[-3.1581155172952736e-16 Eₕ a₀^-1, 7.610743088444412e-17 Eₕ a₀^-1, 1.188977294854993e-16 Eₕ a₀^-1]
[5.35371904152215e-16 Eₕ a₀^-1, -5.303797858876574e-16 Eₕ a₀^-1, -8.893280748290078e-16 Eₕ a₀^-1]
```

Note that the `results`

object returned by the call to `AtomsCalculators.calculate`

also contains a `state`

, which is a DFTK `scfres`

. This can be used to speed up subsequent computations:

```
# This is basically for free, since already computed:
results2 = @time AC.calculate((AC.Energy(), AC.Forces()), silicon, calc, nothing, results.state);
```

` 0.135661 seconds (502.25 k allocations: 61.702 MiB, 14.45% gc time)`

For an example using the `DFTKCalculator`

, see Geometry optimization.