Patching

Advanced npatch setup in divERGe

We can call diverge_patching_find_fs_pts() to find the Fermi surface and store it in an array. Note that we can provide NULL as the energy to the Fermi surface routine and make the code use its internals. To illustrate the usage of the extended mom_patching_t struct generation, we add some high symmetry points after finding the Fermi surface:

index_t* patches = diverge_patching_find_fs_pts( mod, NULL, 1, 4, 100 );
index_t n_patches = 0; while( patches[++n_patches] != -1 ) {}

// adding some high symmetry points
patches = (index_t*)realloc( patches, sizeof(*patches) * (n_patches + 4) );
patches[n_patches++] = 0;
patches[n_patches++] = mod->nk[0]/2*mod->nk[1]+mod->nk[1]/2;
patches[n_patches++] = mod->nk[0]/2*mod->nk[1];
patches[n_patches++] = mod->nk[1]/2;

Thereafter, we must allocate and fill the mom_patching_t struct diverge_model_t by calling diverge_patching_from_indices():

mod->patching = diverge_patching_from_indices( mod, patches, n_patches );

We can find an automatically optimized integration refinement with diverge_patching_autofine() for each of the patches. Again, passing NULL for the energies makes the code use its internals:

diverge_patching_autofine( mod, mod->patching, NULL, 1, 40, 0.1, 2.0, 0.5 );

Notice that in the function calls to diverge_patching_autofine() and diverge_patching_find_fs_pts() we put 1 as the number of bands. Passing NULL as the energy array makes the library use its internals. If using autofine, it is strongly recommended to also symmetrize the refinement with diverge_patching_symmetrize_refinement() – for this to work you must implement all the relevant point-group symmetries.

diverge_patching_symmetrize_refinement( mod, mod->patching );

Finally, we can call the patching internals diverge_model_internals_patch():

diverge_model_internals_patch( mod, -1 );

As mod->patching is now set, the second parameter is ignored in the above call to diverge_model_internals_patch().

void diverge_patching_find_fs_pts_C(diverge_model_t *mod, const double *E, index_t nb, index_t np_ibz, index_t np_search, index_t **pts, index_t *npts)
[source]

old C interface to the patching find function diverge_patching_find_fs_pts(). must free the pts memory with free(*pts).

Parameters:
  • mod (diverge_model_t) – model to operate on

  • E (const double*) – energy array. May be NULL for operation on model internals

  • nb (index_t) – number of bands. May be -1 for operation on model internals

  • np_ibz (index_t) – number of patches to generate in the irreducible BZ

  • np_search (index_t) – number of patches to include in the search array within the irreducible BZ

  • pts (index_t**) – output pointer for the fermi surface index array. allocated with standard malloc/calloc. must be free’d manually.

  • npts (index_t*) – output pointer for the length of the fermi surface array.

index_t *diverge_patching_find_fs_pts(diverge_model_t *mod, const double *E, index_t nb, index_t np_ibz, index_t np_search)
[source]

uses internal energy array if NULL is provided for E. Works like diverge_patching_find_fs_pts_C(), but with the number of patches encoded in the array itself: The (zero-based) index of the first element of the returned array that equals -1 yields the number of elements.

Note

In previous versions of divERGe, we exposed a C++ interface in this function (diverge_patching_find_fs_pts()). This behavior has changed, it is now a C function and the interface is adapted accordingly.

mom_patching_t *diverge_patching_from_indices(diverge_model_t *mod, const index_t *patches, index_t npatches)
[source]

allocates everything inside the mom_patching_t* struct given Fermi surface indices in the array patches. The mom_patching_t* internals as well as the struct itself are freed by the code when they are attached to a diverge_model_t* instance.

void diverge_patching_autofine(diverge_model_t *mod, mom_patching_t *patch, const double *E, index_t nb, index_t ngroups, double alpha, double beta, double gamma)
[source]

generate refinement with a heuristic function

Parameters:
  • mod (diverge_model_t*) – model to operate on

  • patch (mom_patching_t*) – patching to operate on

  • E (double*) – energy array to operate on. uses internal energy array if NULL is provided for E

  • nb (index_t) – #bands spanned by E. uses internal nb if NULL is set for E.

  • ngroups (index_t) – #groups to use for autofine function

  • alpha (double) – \((|E-E_\mathrm{min}|/|E_\mathrm{max}- E_\mathrm{min}|)^\alpha\) is used to calculate group index g

  • beta (double) – \((1-g/n_\mathrm{groups})^\beta\) is used to calculate number of clusters in group g

  • gamma (double) – if \(\gamma < \beta * n_\mathrm{groups}\) use all points in cluster

void diverge_patching_symmetrize_refinement(diverge_model_t *mod, mom_patching_t *patch)
[source]

according to the realspace symmetries defined in the model the refinement is symmetrized. useful if the refinement has been generated with the autofine method.

void diverge_patching_free(mom_patching_t *patching)
[source]

frees all resources of a mom_patching_t structure. Usage is typically not needed, but for advanced patching calculations it may be advantageous.

Vertex interface

As channel specific vertices in npatch are inherently different from TUFRG and grid FRG, we expose the interface in src/npatch/vertex.h to the user through the function pair diverge_patching_vertex(), diverge_patching_vertex_free().

type npatch_qvert_mat_t
[source]

see src/npatch/vertex.h for explanation of the structure

npatch_qvert_mat_t *diverge_patching_vertex(diverge_flow_step_t *s, char chan, index_t *nvq)
[source]

obtain npatch vertex in q space (channel specific). The result is an array of length *nqv.

void diverge_patching_vertex_free(npatch_qvert_mat_t *vq, index_t nvq)
[source]

free npatch vertex in q space, an array of length nvq.

In summary, calling of the above functions in the model would look like:

index_t *patches, npatches;
diverge_patching_find_fs_pts_C( mod, E, nb, np_ibz, np_ibz*10,
    &patches, &npatches );
mom_patching_t* pat = diverge_patching_from_indices( mod, patches,
    npatches );
free(patches);
diverge_patching_autofine( mod, pat, E, nb, 10, 0.5, 4.0, 0.4 );
diverge_patching_symmetrize_refinement( mod, pat );
mod->patching = pat;