Flow Step Object

Given the heterogenous nature of the three backends that can be chosen in divERGe, the flow step internals are not exposed to the user. The API is therefore private by construction and everything is done over the diverge_flow_step_t handle.

type diverge_flow_step_t
[source]

opaque typedef because none of the internal structure is needed by users. Pointers to this structure must be obtained through diverge_flow_step_init() (or diverge_flow_step_init_any()) and free’d with diverge_flow_step_free().

struct diverge_timing_t
[source]

flow step timings given by diverge_flow_step_timings()

double t
[source]

time in seconds

char nam[56]
[source]

name given for this timing

diverge_flow_step_t *diverge_flow_step_init(diverge_model_t *mod, const char *method, const char *channels)
[source]

internals of the model must be set up at the time of calling this function. Therefore, the model already holds all vertex data etc. returns NULL upon error.

Parameters:
  • model (diverge_model_t) – model to base the flow step on

  • method (const char*) – string that can be “patch”, “tu”, or “grid”; selecting one of the backends.

  • channels (const char*) – all channels present in the string (P,C,D) are selected, all other ones deselected.

Returns:

an pointer to a diverge_flow_step_t object.

void diverge_flow_step_set_interchannel(diverge_flow_step_t *st, const char *feedback)
[source]

Allows for a selective turning off of the feedback in between the channels, before or at any point during the flow. The format of the Feedback char is “C|D|CP” which means that in the P channel only the C channel, in the C channel only the D channel and in the D channel both of the other channels are included. The separators “|” are reqired!

diverge_flow_step_t *diverge_flow_step_init_any(diverge_model_t *mod, const char *channels)
[source]

initialize the flow step instance from a model instance that has its internals set to one method. Everything else works as in diverge_flow_step_init().

void diverge_flow_step_vertmax(diverge_flow_step_t *st, double vertmax[1])
[source]

outputs the maximum vertex element in vertmax

double diverge_flow_step_vertmax_r(diverge_flow_step_t *st, double *vertmax)
[source]

same as diverge_flow_step_vertmax() but with return value. Ignores argument in case it’s set to NULL

void diverge_flow_step_loopmax(diverge_flow_step_t *st, double loopmax[2])
[source]

outputs the maximum loop elements in loopmax

void diverge_flow_step_chanmax(diverge_flow_step_t *st, double chanmax[3])
[source]

outputs the maximum channel vertex elements in chanmax

double diverge_flow_step_eigchan(diverge_flow_step_t *st, char chan, int piter)
[source]

outputs the maximum channel singular value given a channel in chan. If piter > 0, calculate the leading eigenvalue using power iteration, if piter < 0, use Gerschgorin’s circle theorem for the (approximate) leading eigenvalue. Otherwise use batched_svd(). For how the channels are defined, see diverge_flow_step_vertex().

void diverge_flow_step_euler(diverge_flow_step_t *st, double Lambda, double dLambda)
[source]

Do an euler step starting at \(\Lambda\) ending at \(\Lambda+d_\Lambda\)

index_t diverge_flow_step_niter(diverge_flow_step_t *st)
[source]

return the number of iterations carried out by the diverge_flow_step_t

index_t diverge_flow_step_ntimings(diverge_flow_step_t *st)
[source]

return the length of the timing list attached to diverge_flow_step_t

diverge_timing_t *diverge_flow_step_timings(diverge_flow_step_t *st)
[source]

return timing vector (type diverge_timing_t, length given by diverge_flow_step_ntimings()) taken during the flow

double diverge_flow_step_timing(diverge_flow_step_t *st, index_t idx)
[source]

Deprecated since version 0.9: use diverge_flow_step_timings() instead.

return the timing list element at idx attached to diverge_flow_step_t

const char *diverge_flow_step_timing_descr(diverge_flow_step_t *st, index_t idx)
[source]

Deprecated since version 0.9: use diverge_flow_step_timings() instead.

the timing list element name at idx attached to diverge_flow_step_t

double *diverge_flow_step_timing_vec(diverge_flow_step_t *st)
[source]

Deprecated since version 0.9: use diverge_flow_step_timings() instead.

returns all timings as static vector (that must not be freed), maximal size 128. last element [128] is zerod.

cf. diverge_flow_step_timing()

char **diverge_flow_step_timing_descr_vec(diverge_flow_step_t *st)
[source]

Deprecated since version 0.9: use diverge_flow_step_timings() instead.

returns all timing descriptions as static vector (that must not be freed), maximal size 128. last element [128] is zerod.

cf. diverge_flow_step_timing_descr()

double diverge_flow_step_lambda(diverge_flow_step_t *st)
[source]

get the current \(\Lambda\)

double diverge_flow_step_dlambda(diverge_flow_step_t *st)
[source]

get the current \(d_\Lambda\)

void diverge_flow_step_attach_rpa(diverge_flow_step_t *s, index_t *kidx, index_t n_kidx)
[source]

perform rpa for the q=0 SC channel (only possible without refinement) with TUFRG vertex; only use the k indices given in this function; useful to constrain mesh to roughly the Fermi surface and get faster eigensolution and reasonable memory footprint in postprocessing.

void diverge_flow_step_free(diverge_flow_step_t *st)
[source]

free the resources attached to a diverge_flow_step_t().

Vertices

For maximum flexibility, we expose the memory of the vertex objects that are allocated for the FRG flow to users.

struct diverge_flow_step_vertex_t
[source]

Structure that can hold all vertex objects used in divERGe. depending on the backend and channel, the content differs.

complex128_t *ary
[source]

pointer to the raw memory behind the vertex

index_t q_0
[source]

start of the ‘q’ dimension (‘k1’ in the case of grid-FRG and chan == ‘V’)

index_t q_1
[source]

stop of the ‘q’ dimension (‘k1’ in the case of grid-FRG and chan == ‘V’)

index_t nk
[source]

number of k points, not used for TUFRG vertices

index_t n_orbff
[source]

number of orbitals & formfactors, returns number of orbitals for patch and grid

index_t n_spin
[source]

number of spins (==1 if SU2)

char backend
[source]

holds ‘T’U, ‘G’rid, ‘P’atch, or ‘I’nvalid

char channel
[source]

holds the channel.

diverge_flow_step_vertex_t diverge_flow_step_vertex(diverge_flow_step_t *st, char chan)
[source]

returns a vertex object defined by diverge_flow_step_vertex_t. behaves differently for the various backends:

TUFRG:

chan can be ‘P’, ‘C’, or ‘D’, both upper and lower case. For TUFRG, the case determines whether the vertex is just the channel (upper case), the full vertex projected to the respective channel (lower case), or a physical channel (su’p’erconducting, ‘m’agnetic, c’h’arge). The actual channel specific vertex object is returned, ordered as (q, s4,s3,ob2, s2,s1,ob1). Note that q is symmetry reduced as well as MPI distributed. Additionally, chan can be ‘S’ to yield the self-energy on the fine mesh (if used). Then, n_orbff contains the number of orbitals and nk the number of total (refined * coarse) kpts.

Grid FRG:

chan can be ‘P’, ‘C’, ‘D’, or ‘V’, both upper and lower case. In general, lower case references the differential vertex and upper case the full vertex. The three channels are returned in (q, k,O1,O2, k’,O3,O4) order. ‘V’ stands for (k1,k2,k3, O1,O2,O3,O4) ordering. In case of multiple MPI ranks, only the locally accessible part of the vertex is referenced in the returned array. For grid, the indices Oi are actually (oi, si).

Patch FRG:

chan may be ‘V’ (full vertex) or ‘v’ (differential vertex). The vertex in (p1,p2,p3, O1,O2,O3,O4) order is returned. As in the grid case, the indices Oi are actually (oi, si).

const index_t *diverge_flow_step_mi_to_tuffidx(const diverge_flow_step_t *st)
[source]

returns formfactor mapping from vertex convention to model convention (for the TU backend). returns NULL if TU is not selected as backend. returned array must not be freed manually. shape: (n_orbff,). Allocated memory extends one spot further than n_orbff, and last element is set to -1. That way you can obtain the array’s length without any other function call.

index_t *diverge_flow_step_tuffidx_to_mi(const diverge_flow_step_t *st)
[source]

returns inverse mapping to diverge_flow_step_mi_to_tuffidx(). Returned array must be free’d by the user. shape: (n_orbff,). Allocated memory extends one spot further than n_orbff, and last element is set to -1. That way you can obtain the array’s length without any other function call.

const index_t *diverge_flow_step_ibz(const diverge_flow_step_t *st)
[source]

returns ibz mapping for the TU vertex (not MPI distributed, the offset given by diverge_flow_step_vertex() must be applied to get the rank-local result). returns NULL if TU is not selected as backend. returned array must not be freed manually. shape: (n_ibz,).

index_t diverge_flow_step_n_ibz(const diverge_flow_step_t *st)
[source]

returns size of ibz for the TU vertex (not MPI distributed, use diverge_flow_step_vertex() for MPI distribution information), 0 if TU is not selected as backend.

Filling

For quasi-canonical calculations, where the filling \(\nu\) is forced to be fixed instead of the chemical potential \(\mu\), we provide functions that adjust the model’s kinetics depending on the self-energy.

void diverge_flow_step_refill(diverge_flow_step_t *s, double nu, void *workspace)
[source]

adjusts the filling value of the non-interacting Hamiltonian such that with self-energy, it is set to \(\nu\). Works only if the standard Hamiltonian- & Greensfunction-generators are used as it operates on the internal energy/hamiltonian/orbital2band arrays.

if workspace != NULL, use this space as scratch memory. size must be at least sizeof(complex128_t) * (nktot * nb * nb) + sizeof(double) * (nktot * nb). On return (if workspace != NULL) workspace contains the Hamiltonian matrices as complex128_t array (nktot, nb, nb) followed by the dispersion vectors as double array (nktot, nb), i.e.:

complex128_t* Utmp = (complex128_t*)workspace;
double* Etmp = (double*)( Utmp + nk*nb*nb );
double diverge_flow_step_refill_Hself(diverge_flow_step_t *s, double nu, void *workspace)
[source]

generates the Hamiltonian + self-energy and diagonalizes it in the workspace buffer (same size as diverge_flow_step_refill(), energies after matrices). Finds the filling and returns the chemical potential needed to obtain this filling value

double diverge_flow_step_get_filling_Hself(diverge_flow_step_t *s, void *workspace)
[source]

generates the Hamiltonian + self-energy and diagonalizes it in the workspace buffer (same size as diverge_flow_step_refill(), energies after matrices). Calculates the current filling