# Simulations

Simulating diffraction patterns

## Polycrystalline Diffraction Simulation

The simplest diffraction simulation available in scikit-ued is polycrystalline diffraction simulation.

All you need is a `crystals.Crystal`

object and a range of scattering length, defined from
scattering angles s as \(s = \sin{\theta}/\lambda\):

```
>>> import matplotlib.pyplot as plt
>>> import numpy as np
>>> from skued import powdersim
>>> from crystals import Crystal
>>>
>>> graphite = Crystal.from_database('C')
>>>
>>> q = np.linspace(1, 10, 1024)
>>> diff = powdersim(graphite, q)
>>>
>>> fig, ax = plt.subplots(1,1)
>>> ax.plot(q, diff/diff.max())
```

After plot formatting:

(`Source code`

, `png`

, `hires.png`

, `pdf`

)

## Kinematical single-crystal simulation

Single-crystal kinematical diffraction simulation is available via the `kinematicsim()`

function:

```
>>> from crystals import Crystal
>>> from skued import kinematicsim
>>> import numpy as np
>>>
>>> extent = np.linspace(-10, 10, num=1024)
>>> kx, ky = np.meshgrid(extent, extent)
>>> kk = np.sqrt(kx**2 + ky**2)
>>>
>>> crystal = Crystal.from_database('C') # graphite
>>> I = kinematicsim(crystal, kx=kx, ky=ky, energy=50)
```

(`Source code`

, `png`

, `hires.png`

, `pdf`

)

## Electrostatic Potential Simulation

The scattering potential of electrons is the crystal electrostatic potential; hence computing such potential is a useful tool.

To compute the electrostatic potential for an infinite crystal on an arbitrary 3D mesh,
take a look at `electrostatic()`

:

```
>>> import numpy as np
>>> from crystals import Crystal
>>> from skued import electrostatic
>>>
>>> graphite = Crystal.from_database('C')
>>>
>>> extent = np.linspace(-10, 10, 128)
>>> xx, yy, zz = np.meshgrid(extent, extent, extent)
>>> potential = electrostatic(graphite, xx, yy, zz)
```

In order to look at a slice in 2D, take a look at the function `plane_mesh()`

:

```
>>> import numpy as np
>>> from crystals import Crystal
>>> from skued import electrostatic, plane_mesh
>>>
>>> vo2 = Crystal.from_database('vo2-m1')
>>> a, b, _ = vo2.lattice_vectors
>>>
>>> extent = np.linspace(-10, 10, 128)
>>> xx, yy, zz = plane_mesh(a, b, extent, extent)
>>> potential = electrostatic(vo2, xx, yy, zz)
```

Another possibility is to calculate the electrostatic potential for an infinite slab in the
x-y plane, but finite in z-direction, using `pelectrostatic()`

(p for projected):

```
>>> import numpy as np
>>> from skued import pelectrostatic
>>>
>>> extent = np.linspace(-5, 5, 256)
>>> xx, yy= np.meshgrid(extent, extent)
>>> potential = pelectrostatic(graphite, xx, yy)
```

After plot formatting:

(`Source code`

, `png`

, `hires.png`

, `pdf`

)