Switching to strict 2D and 1D cases
In the W-SLDA toolkit, it is possible to simulate "strict 2d" cases without any restriction for the z-direction. This can be done by simply choosing the simulation box size as NxNy1. To do that, one needs to modify the predefines.h:
/**
* Define lattice size and lattice spacing
* */
#define NX (100)
#define NY (100)
#define NZ (1)
By analogy, setting NZ=NY=1 will switch the code to the strict 1D case.
Important: the regularization scheme depends on the dimensionality. The scheme implemented by default in W-SLDA is valid only for 3D cases. It is the user's responsibility to provide a correct regularization scheme when computing for a strict 2D or 1D case.
Setting the correct Fermi Momentum
The default Fermi momentum is defined in the toolkit for the 3d case. If you are using strict 2d or 1d cases, it is highly suggested to set the value of the Fermi momentum in the input file as referencekF.
The Fermi momentum for the 2d case:
k_F = \sqrt{2\pi n}
The Fermi momentum for the 1d case:
k_F = \frac{\pi n}{2}
where n is the total density (spin up + spin down) of the gas. You can also define the reference scale using a dedicated function in problem-definition.h. See here for more details.
Choosing the functional
The SLDA (and consequently ASLDA and SLDAE) functional has a self-energy term, which is designed for 3d cases. For the strict 2d case, we suggest using the BDG functional. This can be done by choosing the BDG flag in the predefines.h file:
// #define FUNCTIONAL SLDA
// #define FUNCTIONAL ASLDA
// #define FUNCTIONAL SLDAE
#define FUNCTIONAL BDG
// #define FUNCTIONAL CUSTOMEDF
Then one needs to use sclgth or akF tags in the input file.
Redefining the regularization scheme in static calculations
In practice, the regularization scheme is a formula that prescribes how to convert an anomalous density into a pairing field.
To introduce a custom regularization scheme, one must override the default scheme. This can be done by utilizing modify_potentials(...) function:
void modify_potentials(int it, wslda_density h_densities, wslda_potential h_potentials, double *params, size_t extra_data_size, void *extra_data)
{
// DETERMINE LOCAL SIZES OF ARRAYS (CODE DIMENSIONALITY DEPENDENT)
int lNX=h_densities.nx, lNY=h_densities.ny, lNZ=h_densities.nz; // local sizes
int ix, iy, iz, ixyz;
// params0 -> effective coupling strength
// you can also access tags from the input file, like input->sclgth here
ixyz=0;
for(ix=0; ix<lNX; ix++) for(iy=0; iy<lNY; iy++) for(iz=0; iz<lNZ; iz++)
{
h_potentials.delta[ixyz] = -1.0*params[0]*h_densities.nu[ixyz];
...
ixyz++;
}
}
In the example above, we assumed the coupling constant is provided directly by the user. Here, params[0] is the effective coupling constant, which has to be set in the input file:
# ------------------- PARAMS -----------------------
params[0] = -2.30 # g_eff
By changing this parameter, one can set the magnitude of the pairing field to a desired value.
Redefining the regularization scheme in time-dependent calculations
We do this in an analogous way as in the case of static calculations, i.e., by utilizing the function again modify_potentials(...):
/**
* THIS FUNCTION IS CALLED AFTER EACH COMPUTATION OF POTENTIALS.
* IT IS CALLED ONLY IF ENABLE_MODIFY_POTENTIALS IS DEFINED (in predefines.h)
* Before each application of the Hamiltonian, the user can arbitrarily modify potentials.
* The function is called by DEVICE. All pointers are DEVICE pointers.
* @param it iteration number
* @param h_densities structure with densities, see (wiki) documentation for list of fields
* NOTE: densities structure is processed by modify_densities(...) function before call ot this function.
* @param h_potentials structure with potentials, see (wiki) documentation for list of fields
* Global variabls deliver by tdwslda_functionals_framework_enable.h are:
* GLOBAL VARIABLES ACCESSIBLE WITHIN THIS ROUTINE
* @param params array of input parameters, before the call of this routine, the params array is processed by process_params() routine
* @param extra_data_size size of extra_data in bytes, if extra_data size=0 the optional data is not uploaded
* @param extra_data optional set of data uploaded by load_extra_data()
* */
#include "tdwslda_functionals_framework_enable.h" // DO NOT REMOVE!
__global__ void modify_potentials(int it, wslda_density h_densities, wslda_potential h_potentials)
{
size_t ixyz= threadIdx.x + blockIdx.x * blockDim.x; // compute for this point
int ix, iy, iz, i;
if(ixyz<NUMBER_ELEMENT)
{
// decode_ixyz2ixiyiz(ixyz,ix,iy,iz, i);
// // Now ix, iy, iz keeps lattice coordinate.
// global variable that you can use here
// - dc_sclgth: scattering length
// - dc_kF: reference kF value
// - dc_mu_a, dc_mu_b: chemical potentials
// - dc_ec: energy cut-off
h_potentials.delta[ixyz] = -1.0*params[0]*h_densities.nu[ixyz];
// ...
}
}
#include "tdwslda_functionals_framework_disable.h" // DO NOT REMOVE!