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 withfree(*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-1yields 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 arraypatches. Themom_patching_t*internals as well as the struct itself are freed by the code when they are attached to adiverge_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_tstructure. 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().
-
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;