// // Here are useful functions that can speed-up coding of your problem #include "../extensions/wslda_utils.h" /** * THIS FUNCTION IS CALLED DURING THE SELF-CONSISTENT PROCESS. * After loading params array from input file, the parameters are processed by this routine. * The routine is executed at beginning of each iteration. * @param params array of size MAX_USER_PARAMS with parameters from input file. * @param kF typical Fermi momentum scale of the problem. * kF=referencekF if the referencekF tag is indicated in the input file, * otherwise to kF value is assigned according formula kF=(3*pi^2*n)^{1/3}, where n corresponds to maximal density. * You can also set kF at request in this function using (*kF)=myvalue; * @param mu array with chemical potentials: mu[SPINA] and mu[SPINB]. * @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() * For more info see: Wiki->User defined parameters * */ void process_params(double *params, double *kF, double *mu, size_t extra_data_size, void *extra_data) { // if akF is active, then overwrite the value of input->sclgth // value of kF is generated by the function referencekF(...) if(input->akF!=0.0) input->sclgth = input->akF/kF[0]; // PROCESS INPUT FILE PARAMETERS // Definition of R_TF: (1/2)*omega^2 * x_TF^2 = mu // => omega_x = sqrt(2*mu)/x_TF params[11] = sqrt(2.*mu[SPINA])/ (params[1]*LX*0.5); // omega_x double eF = kF[0]*kF[0]/2.0; // Fermi energy // convert parameters to internal units params[4] = params[4]*eF; // convert barrier height to internal units params[5] = params[5]/kF[0]; // convert barrier width to internal units } /** * EXTERNAL POTENTIAL V_ext * @param ix x-coordinate from range [0,NX), to convert to Cartesian use: x = DX*(ix-NX/2) * @param iy y-coordinate from range [0,NY), to convert to Cartesian use: y = DY*(iy-NY/2), * NOTE: in case of 1d code iy=0 * @param iz z-coordinate from range [0,NZ), to convert to Cartesian use: z = DZ*(iz-NZ/2) * NOTE: in case of 1d and 2d codes iz=0 * @param it iteration number * @param spin spin indicator, value from set {SPINA,SPINB} * @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 the external potential V_spin(x,y,z) * */ double v_ext(int ix, int iy, int iz, int it, int spin, double *params, size_t extra_data_size, void *extra_data) { double x = DX*(ix-NX/2); double V_ho = harmonic_oscillator_smooth_edges(x, params[11], params[2]*LX*0.5, params[3]*LX*0.5, 1.0); double V_barrier = params[4] * exp(-2.0*pow(x/params[5],2)); double V_tilt = params[6]*x/(LX/2); return V_ho + V_barrier + V_tilt; } /** * EXTERNAL PAIRING POTENTIAL Delta_ext * @param ix x-coordinate from range [0,NX), to convert to Cartesian use: x = DX*(ix-NX/2) * @param iy y-coordinate from range [0,NY), to convert to Cartesian use: y = DY*(iy-NY/2) * NOTE: in case of 1d code iy=0 * @param iz z-coordinate from range [0,NZ), to convert to Cartesian use: z = DZ*(iz-NZ/2) * NOTE: in case of 1d and 2d codes iz=0 * @param it iteration number * @param delta - value of delta computed self-consistently for given iteration it. * @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 external pairing potential Delta_{ext}(x,y,z) * */ double complex delta_ext(int ix, int iy, int iz, int it, double complex delta, double *params, size_t extra_data_size, void *extra_data) { // double x = DX*(ix-NX/2); // double y = DY*(iy-NY/2); // for 1d code iy will be always 0 // double z = DZ*(iz-NZ/2); // for 1d and 2d codes iz will be always 0 // ADD HERE FORMULA FOR Delta_ext(r) double complex D_ext = 0.0 + I*0.0; return D_ext; } /** * EXTERNAL VELOCITY FIELD vec[v]_ext * @param ix x-coordinate from range [0,NX), to convert to Cartesian use: x = DX*(ix-NX/2) * @param iy y-coordinate from range [0,NY), to convert to Cartesian use: y = DY*(iy-NY/2) * NOTE: in case of 1d code iy=0 * @param iz z-coordinate from range [0,NZ), to convert to Cartesian use: z = DZ*(iz-NZ/2) * NOTE: in case of 1d and 2d codes iz=0 * @param it iteration number * @param spin spin indicator, value from set {SPINA,SPINB} * @param coordinate - Cartesian coordinate of the external velocity vector that should be computed, value from set {XAXIS, YAXIS, ZAXIS} * NOTE: for 1d code only XAXIS is requested, for 2d code XAXIS and YAXIS are requested. * @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 the external velocity vector v_ext(x,y,z) * */ double velocity_ext(int ix, int iy, int iz, int it, int spin, int coordinate, double *params, size_t extra_data_size, void *extra_data) { // double x = DX*(ix-NX/2); // double y = DY*(iy-NY/2); // for 1d code iy will be always 0 // double z = DZ*(iz-NZ/2); // for 1d and 2d codes iz will be always 0 // ADD HERE FORMULAS FOR vec{v}_ext=(vx, vy, vz) double v_ext; if(coordinate==XAXIS) v_ext=0.0; if(coordinate==YAXIS) v_ext=0.0; if(coordinate==ZAXIS) v_ext=0.0; return v_ext; } /** * 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 // ... // default: extract max density and use it for definition of kF double max_dens=0.0, kF; int ixyz; for(ixyz=0; ixyzmax_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; } /** * THIS FUNCTION IS CALLED DURING THE SELF-CONSISTENT PROCESS. * Before each diagonalization process, the user can modify densities arbitrarily. * @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() * */ void modify_densities(int it, wslda_density h_densities, 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; // ITERATE OVER ALL POINTS ixyz=0; for(ix=0; ixsclgth; // by default return value from input file. // however, here you can define your own prescription // it can be time and position dependent // ... } /** * ------------------------ FOR FUNCTIONAL == CUSTOMEDF ------------------------ * */ /** * This function computes internal energy in case is CUSTOMEDF functional is selected. * Otherwise the function is ignored. * For more info see wiki pages. * @param it iteration number * @param h_densities array with all densities (INPUT) * @param h_potentials potentials corresponding to the densities (INPUT) * @param energy array with contributions to the energy (OUTPUT) * @param npart array with contributions to the particle number (OUTPUT) * @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 0 if computation is successful, otherwise return error code. If nonzero value is returned the main code will terminate. * */ int compute_energy_custom(int it, wslda_density h_densities, wslda_potential h_potentials, double *energy, double *npart, double *params, size_t extra_data_size, void *extra_data) { return 0; } /** * This function computes potentials defining Hamiltonian in case is CUSTOMEDF functional is selected. * Otherwise the function is ignored. * For more info see wiki pages. * @param it iteration number * @param h_densities array with all densities (INPUT) * @param h_potentials potentials from PREVIOUS iteration as input, * updated values as output (INPUT/OUTPUT) * @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 0 if computation is successful, otherwise return error code. If nonzero value is returned the main code will terminate. * */ int compute_potentials_custom(int it, wslda_density h_densities, wslda_potential h_potentials, double *params, size_t extra_data_size, void *extra_data) { return 0; }