|
|
[[_TOC_]]
|
|
|
# General info
|
|
|
During the computation process W-SLDA codes exploit information about typical scales present in the problem. Precisely, *reference scales* define typical orders of magnitude for computed quantities. The most important reference scale is:
|
|
|
* $`k_F=(3\pi^2 n)^{1/3}`$ - Fermi momentum.
|
|
|
During the computation process, W-SLDA codes exploit information about typical scales present in the problem. Precisely, *reference scales* define typical orders of magnitude for computed quantities. The most important reference scale is Fermi momentum. For uniform system it is defined as
|
|
|
* $`k_F^{(1D)}=\frac{\pi n}{2}`$
|
|
|
* $`k_F^{(2D)}=\sqrt{2\pi n}`$
|
|
|
* $`k_F^{(3D)}=(3\pi^2 n)^{1/3}`$
|
|
|
|
|
|
Other reference scales computed automatically from $`k_F`$ are:
|
|
|
* $`\varepsilon_F=\frac{1}{2}k_F^2`$ - Fermi energy,
|
... | ... | @@ -14,18 +16,42 @@ Finally, chemical potentials also serve as reference scales for static problems: |
|
|
# Defining reference scales for static calculation
|
|
|
## Fermi momentum
|
|
|
There are the following methods of defining the $`k_F`$ reference scale:
|
|
|
* *automatic*: in each iteration code checks what is maximal density $`n=\max[n_{\uparrow}(\bm{r})+n_{\downarrow}(\bm{r})]`$ and next Fermi momentum is computed as $`k_F=(3\pi^2 n)^{1/3}`$,
|
|
|
* *via input file*: $`k_F`$ is provided by user in input file. To activate this mode you need to **uncomment** tag `referencekF`:
|
|
|
```bash
|
|
|
referencekF 1.0 # hard set for reference value of kF
|
|
|
```
|
|
|
* *via process_params() function*: you can code value of reference scales in [problem-definition.h](https://gitlab.fizyka.pw.edu.pl/wtools/wslda/-/blob/public/st-project-template/problem-definition.h) file
|
|
|
* *via problem-definition.h file*: (VERSION>=2022.02.21) by editing function:
|
|
|
```c
|
|
|
void process_params(double *params, double *kF, double *mu, size_t extra_data_size, void *extra_data)
|
|
|
/**
|
|
|
* This function computes Fermi momentum, which is used as the reference value.
|
|
|
* Other reference scales are set automatically to: eF=kF^2/2, Effg=(3/5)*N*eF (N-total number of particles)
|
|
|
* For more details see: https://gitlab.fizyka.pw.edu.pl/wtools/wslda/-/wikis/Reference%20scales
|
|
|
* NOTE units are: hbar=m=k_b=1
|
|
|
* @param it iteration number
|
|
|
* @param h_densities structure with densities, see (wiki) documentation for list of fields
|
|
|
* @param params array of input parameters, before 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()
|
|
|
* @return value of Fermi momentum for your problem
|
|
|
* */
|
|
|
double referencekF(int it, wslda_density h_densities, double *params, size_t extra_data_size, void *extra_data)
|
|
|
{
|
|
|
if(input->referencekF>0.0) return input->referencekF; // take it from input file
|
|
|
|
|
|
// define here your prescription for computing kF
|
|
|
// ...
|
|
|
(*kF) = MY_VALUE_FOR_KF;
|
|
|
// ...
|
|
|
// default: extract max density and use it for definition of kF
|
|
|
double max_dens=0.0, kF;
|
|
|
int ixyz;
|
|
|
for(ixyz=0; ixyz<h_densities.nx*h_densities.ny*h_densities.nz; ixyz++)
|
|
|
if(h_densities.rho_a[ixyz]+h_densities.rho_b[ixyz]>max_dens) max_dens=h_densities.rho_a[ixyz]+h_densities.rho_b[ixyz];
|
|
|
|
|
|
// depending on dimensionality of the problem
|
|
|
if(NY==1 && NZ==1) kF = 0.5*M_PI*max_dens; // 1D
|
|
|
else if(NZ==1) kF = pow(2.0*M_PI*max_dens,1./2.); // 2D
|
|
|
else kF = pow(3.*M_PI*M_PI*max_dens,1./3.); // 3D
|
|
|
|
|
|
return kF;
|
|
|
}
|
|
|
```
|
|
|
## Chemical potentials
|
... | ... | @@ -34,46 +60,28 @@ Chemical potentials are adjusted automatically when mode with fixed particle num |
|
|
## Examples
|
|
|
### Fermi momentum is fixed by density in the box center
|
|
|
```c
|
|
|
// Set kF via process_params function
|
|
|
void process_params(double *params, double *kF, double *mu, size_t extra_data_size, void *extra_data)
|
|
|
double referencekF(int it, wslda_density h_densities, double *params, size_t extra_data_size, void *extra_data)
|
|
|
{
|
|
|
// set kF
|
|
|
double *dens=(double *)extra_data;
|
|
|
if(dens[0]>0.0) // do it only if central density has been computed
|
|
|
{
|
|
|
(*kF) = pow(3.0*M_PI*M_PI*dens[0],1./3.);
|
|
|
if(wsldapid==0) wprintf("# UPDATE OF kF=%f\n", (*kF)); // print to stdout
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
// here you can extract needed data, like central density
|
|
|
void modify_potentials(int it, wslda_density h_densities, wslda_potential h_potentials, double *params, size_t extra_data_size, void *extra_data)
|
|
|
{
|
|
|
if(input->referencekF>0.0) return input->referencekF; // take it from input file
|
|
|
|
|
|
// Fermi momentum is fixed by density in the box center
|
|
|
// DETERMINE LOCAL SIZES OF ARRAYS (CODE DIMENSIONALITY DEPENDENT)
|
|
|
int lNX=h_densities.nx, lNY=h_densities.ny, lNZ=h_densities.nz; // local sizes
|
|
|
int ixyz;
|
|
|
|
|
|
// take value of density in box center and save it to extra_data
|
|
|
ixyz = lNZ/2 + lNZ*lNY/2 + lNZ*lNY*lNX/2;
|
|
|
double *dens=(double *)extra_data;
|
|
|
dens[0] = h_densities.rho_a[ixyz]+h_densities.rho_b[ixyz];
|
|
|
}
|
|
|
|
|
|
// since you want to pass data between functions, use extra_data buffer
|
|
|
size_t get_extra_data_size(double *params)
|
|
|
{
|
|
|
return sizeof(double); // I need buffer for density
|
|
|
}
|
|
|
// take value of density in box center and save it to extra_data
|
|
|
int ixyz = lNZ/2 + lNZ*lNY/2 + lNZ*lNY*lNX/2;
|
|
|
double dens = h_densities.rho_a[ixyz]+h_densities.rho_b[ixyz];
|
|
|
|
|
|
// here you initialize the buffer
|
|
|
int load_extra_data(size_t size, void *extra_data, double *params)
|
|
|
{
|
|
|
double *dens=(double *)extra_data;
|
|
|
dens[0]=0.0; // set initial value to zero
|
|
|
return 0;
|
|
|
|
|
|
// depending on dimensionality of the problem
|
|
|
double kF;
|
|
|
if(NY==1 && NZ==1) kF = 0.5*M_PI*dens; // 1D
|
|
|
else if(NZ==1) kF = pow(2.0*M_PI*dens,1./2.); // 2D
|
|
|
else kF = pow(3.*M_PI*M_PI*dens,1./3.); // 3D
|
|
|
|
|
|
return kF;
|
|
|
}
|
|
|
```
|
|
|
|
|
|
# Defining reference scales for time dependent calculations
|
|
|
# Defining reference scales for time-dependent calculations
|
|
|
All reference scales are provided together with an initial state, i.e. binary files produced by static codes contain this information. Presently there is no option of changing values for reference scales. |
|
|
\ No newline at end of file |