|
|
# Lattice calculations
|
|
|
W-SLDA Toolkit solves the problem on a Cartesian mesh grid with a lattice size $`N_x\times N_y\times N_z`$ and lattice spacing $`D_x\times D_y\times D_z`$. The total extend of the simulation box is $`L_x\times L_y\times L_z=N_xD_x\times N_yD_y\times N_zD_z`$.
|
|
|
The lattice parameters mast be provided at compilation stage via [predefines.h](https://gitlab.fizyka.pw.edu.pl/gabrielw/wslda/-/blob/public/st-project-template/predefines.h) file:
|
|
|
```c
|
|
|
/**
|
|
|
* Define lattice size and lattice spacing
|
|
|
* */
|
|
|
#define NX 8
|
|
|
#define NY 10
|
|
|
#define NZ 12
|
|
|
|
|
|
#define DX 1.0
|
|
|
#define DY 1.0
|
|
|
#define DZ 1.0
|
|
|
```
|
|
|
|
|
|
In addition we define parameters that you can use in all user-defined files:
|
|
|
```c
|
|
|
// integration elements
|
|
|
#define DXYZ (DX*DY*DZ)
|
|
|
#define DXY (DX*DY)
|
|
|
|
|
|
// lattice points
|
|
|
#define NXYZ (NX*NY*NZ)
|
|
|
#define NXY (NX*NY)
|
|
|
|
|
|
// volume
|
|
|
#define LX (DX*NX)
|
|
|
#define LY (DY*NY)
|
|
|
#define LZ (DZ*NZ)
|
|
|
#define LXYZ (LX*LY*LZ)
|
|
|
#define LXY (LX*LY)
|
|
|
```
|
|
|
|
|
|
# Coordinate frame
|
|
|
Simulation box contains volume `[0,DX*NX) x [0,DY*NY) x [0, DZ*NZ)`, where `NX, NY, NZ` and `DX, DY, DZ` are lattice dimensions and lattice spacings respectively. Image below represents the simulation box for `NX=NY=NZ=64` and `DX=DY=DZ=1`:
|
|
|
![Screenshot_20201012_123321](uploads/4cdd063f8c75431f728b314738c548d7/Screenshot_20201012_123321.png)
|
|
|
|
|
|
User defined functions, like:
|
|
|
```c
|
|
|
double v_ext(int ix, int iy, int iz, int it, int spin, double *params, size_t extra_data_size, void *extra_data)
|
|
|
```
|
|
|
take as input point coordinate `(ix,iy,iz)` expressed in lattice units. In order to convert it to Cartesian coordinate use:
|
|
|
```c
|
|
|
double x = DX*ix;
|
|
|
double y = DY*iy;
|
|
|
double z = DZ*iz;
|
|
|
```
|
|
|
**Note**: C language uses first variable in expression to set precision of calculations, thus `DX*ix` will be executed using double precision (`DX` is double), while `ix*DX` will be executed using integer precision.
|
|
|
In many cases it is convenient to set origin of simulation of domain in center of the simulations box. This we do by shifting the frame by vector `(NX/2, NY/2, NZ/2)`:
|
|
|
```c
|
|
|
double x = DX*(ix-NX/2);
|
|
|
double y = DY*(iy-NY/2);
|
|
|
double z = DZ*(iz-NZ/2);
|
|
|
```
|
|
|
|
|
|
# Converting lattice coordinate into array index
|
|
|
Variables (like `density_a`, `delta`, ...) are stored as one-dimensional arrays. Precisely, quantity for lattice coordinate `(ix,iy,iz)` is written in array element `quantity[ixyz]` where:
|
|
|
```c
|
|
|
int ixyz = iz + NZ*iy + NZ*NY*ix;
|
|
|
```
|
|
|
Typically access to quantities is provided via structures [wslda_density](https://gitlab.fizyka.pw.edu.pl/gabrielw/wslda/-/tree/public/hpc-engine/wslda_potdens.h) and [wslda_potential](https://gitlab.fizyka.pw.edu.pl/gabrielw/wslda/-/tree/public/hpc-engine/wslda_potdens.h). These structures contain information about the coordinate frame that was used for storing provided there quantities:
|
|
|
```c
|
|
|
typedef struct
|
|
|
{
|
|
|
int nx;
|
|
|
int ny; /// for 1d code it is set to 1
|
|
|
int nz; /// for 1d and 2d code it is set to 1
|
|
|
int datadim; /// dimensonality of data
|
|
|
int blocklength; /// number of elements in quantity array = nx*ny*nz
|
|
|
...
|
|
|
```
|
|
|
It is recommended to use these variables, as they take into account various dimensionality modes (3D, 2D and 1D). For example, in order to extract value of density in center of the box it is recommended to use:
|
|
|
```c
|
|
|
// INPUT: wslda_density h_densities
|
|
|
int lNX=h_densities.nx, lNY=h_densities.ny, lNZ=h_densities.nz; // local sizes
|
|
|
int ix = lNX/2, iy = lNY/2, iz = lNZ/2; // (ix,iy,iz) points now to box center
|
|
|
int ixyz = iz + lNZ*iy + lNZ*lNY*ix;
|
|
|
h_densities.density_a[ixyz]; // value of density in center of the box
|
|
|
```
|
|
|
|