+++
title = "2D paracrystal"
weight = 30
+++

## 2D paracrystal

Scattering from monodisperse cylinders distributed along a two-dimensional
square paracrystal.

* The particles are cylinders with constant radii and heights equal to
  $5$ nm.
* They are deposited on a substrate, following a two-dimensional square
  paracrystalline pattern.
* This 2D paracrystal is characterized by:
  * a lattice length of $20$ nm along both axes of the reference Cartesian
    frame,
  * a damping length equal to $0$,
  * coherent domains with a size of $20$ $\mu$m along the axes of the
    reference Cartesian frame.
* The incident beam is characterized by a wavelength of 0.1 nm and angles
  $\alpha\_i = 0.2 ^{\circ}$ and $\varphi\_i = 0^{\circ}$.

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

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

## Explanation

Similarly to the 2D crystal structure, the 2D paracrystal is used to model the
scattering from particles positioned at regular intervals on a plane. The 2D
paracrystal model, however, possesses only short-range order. The disorder is
cumulative at further distance.

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

The plot above represents a schematic view of the 2D paracrystal. Each circle
on the plot represents an area where the probability to find a particle, given
a particle at the origin, is above some arbitrary threshold. The growing size
of the areas emphasizes the fact that our knowledge about the next neighbor's
location decreases with the distance to the origin.

The two-dimensional paracrystal model in BornAgain is implemented as a simple
convolution of two one-dimensional paracrystals along the lattice basis
directions.

### Constructor

Create the lattice first, then construct the paracrystal from the particle and
that lattice:

```python
lattice = ba.BasicLattice2D(length1, length2, alpha, xi)
structure = ba.Paracrystal2D(
    particle, lattice, damping_length, domain_size_1, domain_size_2
)
```

Arguments:

```python
length1, length2  # lattice-vector lengths, in nanometers
alpha             # angle between lattice vectors, in radians
xi                # lattice rotation with respect to the x axis, in radians
damping_length    # damping/coherence length, in nanometers
domain_size_1     # coherent-domain size along first lattice vector
domain_size_2     # coherent-domain size along second lattice vector
```

For square and hexagonal unit cells, use the convenience lattice classes:

```python
lattice = ba.SquareLattice2D(lattice_constant, xi)
lattice = ba.HexagonalLattice2D(lattice_constant, xi)
```

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

When the beam azimuthal angle $\varphi_f$ is zero, the beam direction
coincides with x-axis of the reference frame, so angle $\xi$ can be considered
as the lattice rotation with respect to the beam.

The parameter `damping_length` is used to introduce finite size effects by
applying a multiplicative coefficient equal to
`exp(-lattice_constant/damping_length)` to the Fourier transform of the
probability density of a nearest neighbor. `damping_length` equal to 0 means
no damping-length correction.

### Probability distributions

To account for next neighbor position uncertainty, assign probability
distributions with `setProbabilityDistributions(pdf1, pdf2)`.

```python
profile_1 = ba.Profile2DCauchy(30*nm, 30*nm, 0)
profile_2 = ba.Profile2DCauchy(30*nm, 30*nm, 0)
structure.setProbabilityDistributions(profile_1, profile_2)
```

The probability distribution is parameterized with its type, size and
orientation with respect to the lattice vector. $x_d$, $y_d$ on the plot below
represent an orthonormal coordinate system of the distribution in real space
which is rotated by the angle gamma with respect to the lattice vector.
`pdf1` is defined for lattice vector $a$, and `pdf2` for lattice vector $b$.

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

The following PDF distributions are available:

```python
ba.Profile2DCauchy(omega_x, omega_y, delta)
ba.Profile2DGauss(omega_x, omega_y, delta)
ba.Profile2DGate(omega_x, omega_y, delta)
ba.Profile2DTriangle(omega_x, omega_y, delta)
ba.Profile2DVoigt(omega_x, omega_y, eta, delta)
```

All distributions have parameters:

```python
omega_x  # half-width along distribution x-axis, in nanometers
omega_y  # half-width along distribution y-axis, in nanometers
gamma    # angle between first lattice vector and distribution x-axis
```

In the case of the Voigt distribution, an additional dimensionless parameter
`eta` is used to balance between Gaussian and Cauchy profiles.

### Sizes of coherence domains

The 2D paracrystal provides a way to calculate the scattering from a finite
portion of the paracrystal using the `setDomainSizes(size1, size2)` method.
Here `size1`, `size2` are given in nanometers and represent the sizes of the
coherence domains in the first and second lattice directions.

```python
lattice = ba.SquareLattice2D(20*nm, 0)
structure = ba.Paracrystal2D(particle, lattice, 0, 0, 0)
structure.setProbabilityDistributions(
    ba.Profile2DCauchy(30*nm, 30*nm, 0),
    ba.Profile2DCauchy(30*nm, 30*nm, 0),
)
structure.setDomainSizes(10000*nm, 10000*nm)
```

### Lattice-orientation averaging

The paracrystal can be averaged over all azimuthal angles $\xi$ using the
`setIntegrationOverXi(True)` method. In this case the initial lattice rotation
angle $\xi$, if set, will be ignored and numeric integration will be performed
for $\xi$ in the range 0 to 360 degrees. Averaging provides a convenient way
of getting an isotropic structure at the cost of longer computation time.

```python
structure.setIntegrationOverXi(True)
```

### Particle density

The particle density is determined from the 2D lattice parameters. There is no
separate particle-density setting for `Paracrystal2D`.
