+++
title = "1D lattice"
weight = 10
+++

## 1D lattice

In this example we simulate the scattering from a one-dimensional repetition
of rectangular patches. This is done by using `Crystal1D` together with very
long boxes.

* By default, the axis of the one-dimensional lattice coincides with the
  $x$-axis of the reference Cartesian frame.
* Long boxes are placed along a one-dimensional lattice on top of a substrate;
  the lattice length corresponds to the grating period.
* `length`, `width`, `height` in the `Box(length, width, height)` constructor
  correspond to the $x$, $y$, $z$ axes, in that order.
* The grating can be rotated by rotating both the `Crystal1D` lattice direction
  and the particle.
* To avoid rapidly oscillating form factors of long boxes, the simulation is
  performed in Monte Carlo integration mode.

{{< galleryscg >}}
{{< figscg src="/img/auto/scatter2d/RectangularGrating.png" width="350px" caption="Scattering intensity">}}
{{< /galleryscg >}}

{{< show-ex file="scatter2d/RectangularGrating.py" >}}

## Explanation

A one-dimensional lattice can be viewed as a chain of particles placed at
regular intervals on a single axis. One use case is a grating, where very long
boxes are placed at nodes of a 1D lattice.

{{< figscg src="/img/draw/particles_at_1d_latice.jpg" width="600px" class="center">}}

See the BornAgain user manual (Chapter 3.4.1, One Dimensional Lattice) for
details about the theory.

### Crystal1D constructor

The structure is created with

```python
structure = ba.Crystal1D(particle, length, xi, linear_density)
```

Arguments:

```python
particle        # particle or Mixture placed at lattice sites
length          # lattice constant, in nanometers
xi              # rotation of the lattice with respect to x-axis, in radians
linear_density  # number of lattice lines per nanometer in the transverse axis
```

{{< figscg src="/img/draw/interference_1d_C.png" width="800px" class="center">}}

When the beam azimuthal angle $\varphi_f$ is zero, the beam direction
coincides with x-axis. In this case, $\xi$ can be considered as the lattice
rotation with respect to the beam.

### Position variance

The position variance parameter allows uncertainty for each particle position
around the lattice point by applying a corresponding Debye-Waller factor.

It can be set using the `setLateralPositionVariance(value)` method, where
`value` is given in nm$^2$.

```python
structure = ba.Crystal1D(particle, 100*nm, 0*deg, 1/box_length)
structure.setLateralPositionVariance(0.1)
```

By default the variance is set to zero.

### Decay function

To account for finite size effects of the lattice, assign a decay function to
the structure. This function encodes the loss of coherent scattering from
lattice points with increasing distance between them. The origin of this loss
of coherence could be attributed to the coherence length of the beam or to the
domain structure of the lattice.

In the picture below a one-dimensional lattice is represented in real space as
a probability density function for finding a particle at a given coordinate on
the x-axis. In the presence of a decay function, this density can be given as
$\sum F\_{decay}(x)\cdot\delta(x-na)$.

{{< figscg src="/img/draw/lattice1d_decay_real.png" width="800px" class="center">}}

The Fourier transform of this distribution $P(x)$ provides the scattering
amplitude in reciprocal space. An exponential decay law in real space with the
decay length $\lambda$ will give a Cauchy distribution with characteristic
width $1/\lambda$ in reciprocal space, as shown below.

{{< figscg src="/img/draw/lattice1d_decay_reciprocal.png" width="800px" class="center">}}

The decay function is assigned with `setDecayFunction(decay)`:

```python
structure = ba.Crystal1D(particle, 10*nm, 0*deg, 1/box_length)
structure.setDecayFunction(ba.Profile1DCauchy(1000*nm))
```

### List of decay functions

BornAgain supports four types of one-dimensional decay functions.

* `Profile1DCauchy(decay_length)`: one-dimensional Cauchy decay function in
  reciprocal space, corresponding to $exp(-|x|/\lambda)$ in real space.
* `Profile1DGauss(decay_length)`: one-dimensional Gauss decay function in
  reciprocal space, corresponding to $exp(-x^2/(2*\lambda^2))$ in real space.
* `Profile1DTriangle(decay_length)`: one-dimensional triangle decay function
  in reciprocal space, corresponding to $1-|x|/\lambda$ if $|x|<\lambda$ in
  real space.
* `Profile1DVoigt(decay_length, eta)`: one-dimensional pseudo-Voigt decay
  function in reciprocal space, corresponding to
  $eta*Gauss + (1-eta)*Cauchy$.

The parameter $\lambda$ is given in nanometers and sets the characteristic
length scale at which loss of coherence takes place. In the case of the
pseudo-Voigt distribution, an additional dimensionless parameter `eta`
balances between the Gaussian and Cauchy profiles.

### Particle density

The `linear_density` constructor argument gives the number of lattice lines per
nanometer in the direction transverse to the 1D lattice. For a grating made of
long boxes, use the inverse box length.

### Lattice rotation in detail

The rotation of the lattice does not change the orientation of the particles
with respect to the beam direction. To rotate a grating as a physical object,
rotate both the particle and the lattice direction.

For example:

```python
box = ba.Particle(material, ba.Box(10*nm, 1000*nm, 10*nm))
box.rotate(ba.RotationZ(30*deg))

structure = ba.Crystal1D(box, 40*nm, 30*deg, 1/(1000*nm))
layer.deposit2D(structure)
```
