Source code for edipack2py.func_bath

import ctypes as ct
import numpy as np
import os, sys
import types


# get_bath_dimension
[docs] def get_bath_dimension(self): """ This function returns the correct dimension for the bath to be allocated \ (for each impurity) given the parameters of the system. :return: a number which is the dimension of the bath array for each impurity. :rtype: int """ get_bath_dimension_direct_wrap = self.library.get_bath_dimension_direct get_bath_dimension_direct_wrap.argtypes = None get_bath_dimension_direct_wrap.restype = ct.c_int get_bath_dimension_symmetries_wrap = self.library.get_bath_dimension_symmetries get_bath_dimension_symmetries_wrap.argtypes = [ct.c_int] get_bath_dimension_symmetries_wrap.restype = ct.c_int if self.get_bath_type() > 2: # replica/general if self.Nsym is None: raise RuntimeError( "get_bath_dimension: no replica/general matrix is initialized " ) else: bathdim = get_bath_dimension_symmetries_wrap(self.Nsym) else: bathdim = get_bath_dimension_direct_wrap() return bathdim
# init_hreplica
[docs] def set_hreplica(self, hvec, lambdavec): """ This function is specific to :f:var:`bath_type` = :code:`=replica`. \ It sets the basis of matrices and scalar parameters that, \ upon linear combination, make up the bath replica. :type hvec: np.array(dtype=complex) :param hvec: array of bath matrices. They decompose the nonzero part of \ the replica in a set. Each element of the set correspond to a \ variational parameter.\ That way the bath replica matrix is updated while preserving symmetries\ of the user's choosing. The array can have the following shapes: * [ :code:`(Nnambu)` :math:`\\cdot` :data:`Nspin` :math:`\\cdot` \ :data:`Norb` , :code:`(Nnambu)` :math:`\\cdot` :data:`Nspin` \ :math:`\\cdot` :data:`Norb` , :code:`Nsym` ]:\ 3-dimensional, where Nnambu refers to the superconducting case and Nsym \ is the number of matrices that make up the linear combination * [:code:`(Nnambu)` :math:`\\cdot` :data:`Nspin` , :code:`(Nnambu)` \ :data:`Nspin` , :data:`Norb` , :data:`Norb` , :code:`Nsym` ]:\ 5-dimensional, where Nnambu refers to the superconducting case and Nsym \ is the number of matrices that make up the linear combination :type lambdavec: np.array(dtype=float) :param lambdavec: the array of coefficients of the linear combination.\ This, along with the hybridizations V, are the fitting parameters of \ the bath. The array has the following shape * [ :data:`Nbath` , :code:`Nsym` ]: for single-impurity DMFT, 2-dimensional,\ where Nsym is the number of matrices that make up the linear combination * [ :code:`Nlat`, :data:`Nbath` , :code:`Nsym` ]: for real-space DMFT, \ 3-dimensional, where Nlat is the number of inequivalent impurity sites \ and Nsym is the number of matrices that make up the linear combination :raise ValueError: if the shapes of the arrays are inconsistent :return: Nothing :rtype: None """ init_hreplica_symmetries_d5 = self.library.init_Hreplica_symmetries_d5 init_hreplica_symmetries_d5.argtypes = [ np.ctypeslib.ndpointer(dtype=complex, ndim=5, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=float, ndim=2, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), ] init_hreplica_symmetries_d5.restype = None init_hreplica_symmetries_d3 = self.library.init_Hreplica_symmetries_d3 init_hreplica_symmetries_d3.argtypes = [ np.ctypeslib.ndpointer(dtype=complex, ndim=3, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=float, ndim=2, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), ] init_hreplica_symmetries_d3.restype = None if self.has_ineq: init_hreplica_symmetries_lattice_d5 = ( self.library.init_Hreplica_symmetries_lattice_d5 ) init_hreplica_symmetries_lattice_d5.argtypes = [ np.ctypeslib.ndpointer(dtype=complex, ndim=5, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=float, ndim=3, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), ] init_hreplica_symmetries_lattice_d5.restype = None init_hreplica_symmetries_lattice_d3 = ( self.library.init_Hreplica_symmetries_lattice_d3 ) init_hreplica_symmetries_lattice_d3.argtypes = [ np.ctypeslib.ndpointer(dtype=complex, ndim=3, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=float, ndim=3, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), ] init_hreplica_symmetries_lattice_d3.restype = None aux_norb = ct.c_int.in_dll(self.library, "Norb").value aux_nspin = ct.c_int.in_dll(self.library, "Nspin").value dim_hvec = np.asarray(np.shape(hvec), dtype=np.int64, order="F") dim_lambdavec = np.asarray(np.shape(lambdavec), dtype=np.int64, order="F") self.Nsym = dim_lambdavec[1] # Arrays in Fortran ordering lambdavec = np.asfortranarray(lambdavec) hvec = np.asfortranarray(hvec) if len(dim_hvec) == 3: if len(dim_lambdavec) == 2: init_hreplica_symmetries_d3(hvec, dim_hvec, lambdavec, dim_lambdavec) elif len(dim_lambdavec) == 3: if self.has_ineq: init_hreplica_symmetries_lattice_d3( hvec, dim_hvec, lambdavec, dim_lambdavec ) else: raise RuntimeError( "Can't use r-DMFT routines without installing EDIpack2ineq" ) else: raise ValueError("Shape(lambdavec) != 2 or 3 in set_Hreplica") elif len(dim_hvec) == 5: if len(dim_lambdavec) == 2: init_hreplica_symmetries_d5(hvec, dim_hvec, lambdavec, dim_lambdavec) elif len(dim_lambdavec) == 3: if self.has_ineq: init_hreplica_symmetries_lattice_d5( hvec, dim_hvec, lambdavec, dim_lambdavec ) else: raise RuntimeError( "Can't use r-DMFT routines without installing EDIpack2ineq" ) else: raise ValueError("Shape(lambdavec) != 2 or 3 in set_Hreplica") else: raise ValueError("Shape(Hvec) != 3 or 5 in set_Hreplica") return
# init_hgeneral
[docs] def set_hgeneral(self, hvec, lambdavec): """ This function is specific to :code:`BATH_TYPE=GENERAL`. It sets the \ basis of matrices and scalar parameters that, upon linear combination, \ make up the bath replica. \ The input is the same as that of :func:`set_hreplica`. :type hvec: np.array(dtype=complex) :param hvec: array of bath matrices. They decompose the nonzero part of \ the replica in a set.\ Each element of the set correspond to a variational parameter.\ That way the bath replica matrix is updated while preserving symmetries\ of the user's choosing. The array can have the following shapes: * [:code:`(Nnambu)` :math:`\\cdot`:data:`Nspin` :math:`\\cdot` \ :data:`Norb` , :code:`(Nnambu)` :math:`\\cdot` :data:`Nspin` \ :math:`\\cdot` :data:`Norb` , :code:`Nsym` ]:\ 3-dimensional, where Nnambu refers to the superconducting case and Nsym \ is the number of matrices that make up the linear combination * [:code:`(Nnambu)` :math:`\\cdot` :data:`Nspin` , :code:`(Nnambu)` \ :math:`\\cdot` :data:`Nspin` , :data:`Norb` , :data:`Norb` , :code:`Nsym` ]:\ 5-dimensional, where Nnambu refers to the superconducting case and Nsym is \ the number of matrices that make up the linear combination :type lambdavec: np.array(dtype=float) :param lambdavec: the array of coefficients of the linear combination.\ This, along with the hybridizations V, are the fitting parameters of \ the bath. The array has the following shape * [ :data:`Nbath` , :code:`Nsym` ]: for single-impurity DMFT, 2-dimensional,\ where Nsym is the number of matrices that make up the linear combination * [ :code:`Nlat`, :data:`Nbath` , :code:`Nsym` ]: for real-space DMFT, \ 3-dimensional, where Nlat is the number of inequivalent impurity sites \ and Nsym is the number of matrices that make up the linear combination :raise ValueError: if the shapes of the arrays are inconsistent :return: Nothing :rtype: None """ init_hgeneral_symmetries_d5 = self.library.init_Hgeneral_symmetries_d5 init_hgeneral_symmetries_d5.argtypes = [ np.ctypeslib.ndpointer(dtype=complex, ndim=5, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=float, ndim=2, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), ] init_hgeneral_symmetries_d5.restype = None init_hgeneral_symmetries_d3 = self.library.init_Hgeneral_symmetries_d3 init_hgeneral_symmetries_d3.argtypes = [ np.ctypeslib.ndpointer(dtype=complex, ndim=3, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=float, ndim=2, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), ] init_hgeneral_symmetries_d3.restype = None if self.has_ineq: init_hgeneral_symmetries_lattice_d5 = ( self.library.init_Hgeneral_symmetries_lattice_d5 ) init_hgeneral_symmetries_lattice_d5.argtypes = [ np.ctypeslib.ndpointer(dtype=complex, ndim=5, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=float, ndim=3, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), ] init_hgeneral_symmetries_lattice_d5.restype = None init_hgeneral_symmetries_lattice_d3 = ( self.library.init_Hgeneral_symmetries_lattice_d3 ) init_hgeneral_symmetries_lattice_d3.argtypes = [ np.ctypeslib.ndpointer(dtype=complex, ndim=3, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=float, ndim=3, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), ] init_hgeneral_symmetries_lattice_d3.restype = None # Arrays in Fortran ordering lambdavec = np.asfortranarray(lambdavec) hvec = np.asfortranarray(hvec) aux_norb = ct.c_int.in_dll(self.library, "Norb").value aux_nspin = ct.c_int.in_dll(self.library, "Nspin").value dim_hvec = np.asarray(np.shape(hvec), dtype=np.int64, order="F") dim_lambdavec = np.asarray(np.shape(lambdavec), dtype=np.int64, order="F") self.Nsym = dim_lambdavec[1] if len(dim_hvec) == 3: if len(dim_lambdavec) == 2: init_hgeneral_symmetries_d3(hvec, dim_hvec, lambdavec, dim_lambdavec) elif len(dim_lambdavec) == 3: if self.has_ineq: init_hgeneral_symmetries_lattice_d3( hvec, dim_hvec, lambdavec, dim_lambdavec ) else: raise RuntimeError( "Can't use r-DMFT routines without installing EDIpack2ineq" ) else: raise ValueError("Shape(lambdavec) != 2 or 3 in set_Hgeneral") elif len(dim_hvec) == 5: if len(dim_lambdavec) == 2: init_hgeneral_symmetries_d5(hvec, dim_hvec, lambdavec, dim_lambdavec) elif len(dim_lambdavec) == 3: if self.has_ineq: init_hgeneral_symmetries_lattice_d5( hvec, dim_hvec, lambdavec, dim_lambdavec ) else: raise RuntimeError( "Can't use r-DMFT routines without installing EDIpack2ineq" ) else: raise ValueError("Shape(lambdavec) != 2 or 3 in set_Hgeneral") else: raise ValueError("Shape(Hvec) != 3 or 5 in set_Hgeneral") return
# break_symmetry_bath
[docs] def break_symmetry_bath(self, bath, field, sign, save=True): """ This function breaks the spin symmetry of the bath, useful \ for magnetic calculations to incite symmetry breaking.\ Not compatible with :code:`REPLICA` or :code:`GENERAL` bath types. :type bath: np.array(dtype=float) :param bath: The user-accessible bath array :type field: float :param field: the magnitude of the symmetry-breaking shift :type sign: float or np.array(dtype=float) :param sign: the sign of the symmetry-breaking shift. In the case of \ real-space DMFT, this function supports an array of floats of the same \ shape of bath along dimension 0. If a scalar is passed, it is \ automatically converted into a constant array of the appropriate dimension. \ :type save: bool :param save: whether to save the symmetry-broken bath for reading :return: the modified bath array :rtype: np.array(dtype=float) """ break_symmetry_bath_site = self.library.break_symmetry_bath_site break_symmetry_bath_site.argtypes = [ np.ctypeslib.ndpointer(dtype=float, ndim=1, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), ct.c_double, ct.c_double, ct.c_int, ] break_symmetry_bath_site.restype = None if self.has_ineq: break_symmetry_bath_ineq = self.library.break_symmetry_bath_ineq break_symmetry_bath_ineq.argtypes = [ np.ctypeslib.ndpointer(dtype=float, ndim=1, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), ct.c_double, np.ctypeslib.ndpointer(dtype=float, ndim=1, flags="F_CONTIGUOUS"), ct.c_int, ] break_symmetry_bath_ineq.restype = None if save: save_int = 1 else: save_int = 0 bath = np.ascontiguousarray(bath) bath_shape = np.asarray(np.shape(bath), dtype=np.int64, order="F") if (len(bath_shape)) == 1: break_symmetry_bath_site(bath, bath_shape, field, float(sign), save_int) else: if self.has_ineq: sign = sign * np.ones(bath_shape[0], order="F") break_symmetry_bath_ineq(bath, bath_shape, field, sign, save_int) else: raise RuntimeError( "Can't use r-DMFT routines without installing EDIpack2ineq" ) bath = np.ascontiguousarray(bath) return bath
# spin_symmetrize_bath
[docs] def spin_symmetrize_bath(self, bath, save=True): """ This function enforces equality of the opposite-spin components\ of the bath array. Not compatible with :code:`REPLICA` or \ :code:`GENERAL` bath types. :type bath: np.array(dtype=float) :param bath: The user-accessible bath array :type save: bool :param save: whether to save the symmetry-broken bath for reading :return: the modified bath array :rtype: np.array(dtype=float) """ spin_symmetrize_bath_site = self.library.spin_symmetrize_bath_site spin_symmetrize_bath_site.argtypes = [ np.ctypeslib.ndpointer(dtype=float, ndim=1, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), ct.c_int, ] spin_symmetrize_bath_site.restypes = None if self.has_ineq: spin_symmetrize_bath_ineq = self.library.spin_symmetrize_bath_ineq spin_symmetrize_bath_ineq.argtypes = [ np.ctypeslib.ndpointer(dtype=float, ndim=1, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), ct.c_int, ] spin_symmetrize_bath_ineq.restypes = None if save: save_int = 1 else: save_int = 0 bath = np.asfortranarray(bath) bath_shape = np.asarray(np.shape(bath), dtype=np.int64, order="F") if (len(bath_shape)) == 1: spin_symmetrize_bath_site(bath, bath_shape, save_int) else: if self.has_ineq: spin_symmetrize_bath_ineq(bath, bath_shape, save_int) else: raise RuntimeError( "Can't use r-DMFT routines without installing EDIpack2ineq" ) bath = np.ascontiguousarray(bath) return bath
# orb_symmetrize_bath
[docs] def orb_symmetrize_bath(self, bath, orb1, orb2, save=True): """ This function enforces equality of the different-orbital components \ of the bath array. Not compatible with :code:`REPLICA` or \ :code:`GENERAL` bath types. :type bath: np.array(dtype=float) :param bath: The user-accessible bath array :type orb1: int :param orb1: first orbital index :type orb2: int :param orb2: second orbital index :type save: bool :param save: whether to save the symmetry-broken bath for reading :return: the modified bath array :rtype: np.array(dtype=float) """ orb_symmetrize_bath_site = self.library.orb_symmetrize_bath_site orb_symmetrize_bath_site.argtypes = [ np.ctypeslib.ndpointer(dtype=float, ndim=1, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), ct.c_int, ] orb_symmetrize_bath_site.restypes = None if self.has_ineq: orb_symmetrize_bath_ineq = self.library.orb_symmetrize_bath_ineq orb_symmetrize_bath_ineq.argtypes = [ np.ctypeslib.ndpointer(dtype=float, ndim=1, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), ct.c_int, ] orb_symmetrize_bath_ineq.restypes = None if save: save_int = 1 else: save_int = 0 bath = np.asfortranarray(bath) bath_shape = np.asarray(np.shape(bath), dtype=np.int64, order="F") if (len(bath_shape)) == 1: orb_symmetrize_bath_site(bath, bath_shape, orb1 + 1, orb2 + 1, save_int) else: if self.has_ineq: orb_symmetrize_bath_ineq(bath, bath_shape, orb1 + 1, orb2 + 1, save_int) else: raise RuntimeError( "Can't use r-DMFT routines without installing EDIpack2ineq" ) bath = np.ascontiguousarray(bath) return bath
# orb_equality_bath
[docs] def orb_equality_bath(self, bath, indx, save=True): """ This function sets every orbital component to be equal to the \ one of orbital :code:`indx`. Not compatible with :code:`REPLICA` or \ :code:`GENERAL` bath types. :type bath: np.array(dtype=float) :param bath: The user-accessible bath array :type iorb: int :param iorb: the orbital index to which every other will be set as equal :type save: bool :param save: whether to save the symmetry-broken bath for reading :raise ValueError: if the orbital index is out of bounds :return: the modified bath array :rtype: np.array(dtype=float) """ orb_equality_bath_site = self.library.orb_equality_bath_site orb_equality_bath_site.argtypes = [ np.ctypeslib.ndpointer(dtype=float, ndim=1, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), ct.c_int, ct.c_int, ] orb_equality_bath_site.restypes = None if self.has_ineq: orb_equality_bath_ineq = self.library.orb_equality_bath_ineq orb_equality_bath_ineq.argtypes = [ np.ctypeslib.ndpointer(dtype=float, ndim=1, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), ct.c_int, ct.c_int, ] orb_equality_bath_ineq.restypes = None aux_norb = ct.c_int.in_dll(self.library, "Norb").value if save: save_int = 1 else: save_int = 0 bath = np.asfortranarray(bath) bath_shape = np.asarray(np.shape(bath), dtype=np.int64, order="F") if (indx < 0) or (indx >= aux_norb): raise ValueError("orb_equality_bath: orbital index should be in [0,Norb]") else: indx = indx + 1 # python to fortran convention if (len(bath_shape)) == 1: orb_equality_bath_site(bath, bath_shape, indx, save_int) else: if self.has_ineq: orb_equality_bath_ineq(bath, bath_shape, indx, save_int) else: raise RuntimeError( "Can't use r-DMFT routines without installing EDIpack2ineq" ) bath = np.ascontiguousarray(bath) return bath
# ph_symmetrize_bath
[docs] def ph_symmetrize_bath(self, bath, save): """ This function enforces particle-hole symmetry of the bath hybridization \ function. Not compatible with :code:`REPLICA` or :code:`GENERAL` bath types. :type bath: np.array(dtype=float) :param bath: The user-accessible bath array :type save: bool :param save: whether to save the symmetry-broken bath for reading :return: the modified bath array :rtype: np.array(dtype=float) """ ph_symmetrize_bath_site = self.library.ph_symmetrize_bath_site ph_symmetrize_bath_site.argtypes = [ np.ctypeslib.ndpointer(dtype=float, ndim=1, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), ct.c_int, ] ph_symmetrize_bath_site.restypes = None if self.has_ineq: ph_symmetrize_bath_ineq = self.library.ph_symmetrize_bath_ineq ph_symmetrize_bath_ineq.argtypes = [ np.ctypeslib.ndpointer(dtype=float, ndim=1, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), ct.c_int, ] ph_symmetrize_bath_ineq.restypes = None if save: save_int = 1 else: save_int = 0 bath = np.asfortranarray(bath) bath_shape = np.asarray(np.shape(bath), dtype=np.int64, order="F") if (len(bath_shape)) == 1: ph_symmetrize_bath_site(bath, bath_shape, save_int) else: if self.has_ineq: ph_symmetrize_bath_ineq(bath, bath_shape, save_int) else: raise RuntimeError( "Can't use r-DMFT routines without installing EDIpack2ineq" ) bath = np.ascontiguousarray(bath) return bath
# save array as .restart file
[docs] def save_array_as_bath(self, bath): """ This function takes the user-accessible array and saves it in the \ correct format for every bath type in the file :code:`hamiltonian.restart` :type bath: np.array(dtype=float) :param bath: The user-accessible bath array :return: Nothing :rtype: None """ save_array_as_bath_site = self.library.save_array_as_bath_site save_array_as_bath_site.argtypes = [ np.ctypeslib.ndpointer(dtype=float, ndim=1, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), ] save_array_as_bath_site.restypes = None if self.has_ineq: save_array_as_bath_ineq = self.library.save_array_as_bath_ineq save_array_as_bath_ineq.argtypes = [ np.ctypeslib.ndpointer(dtype=float, ndim=2, flags="F_CONTIGUOUS"), np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags="F_CONTIGUOUS"), ] save_array_as_bath_ineq.restypes = None bath = np.asfortranarray(bath) bath_shape = np.asarray(np.shape(bath), dtype=np.int64, order="F") if (len(bath_shape)) == 1: save_array_as_bath_site(bath, bath_shape) else: if self.has_ineq: save_array_as_bath_ineq(bath, bath_shape) else: raise RuntimeError( "Can't use r-DMFT routines without installing EDIpack2ineq" ) return
# auxiliary functions to get/set bath structure. Only works for single-site. # User has to do a loop on sites
[docs] def bath_inspect(self, bath=None, e=None, v=None, d=None, u=None, l=None): """ This function translates between the user-accessible continuous \ bath array and the bath components (energy level, hybridization and so on). \ It functions in both ways, given the array returns the components and \ vice-versa. It autonomously determines the type of bath and ED mode. :type bath: np.array(dtype=float) :param bath: The user-accessible bath array :type e: np.array(dtype=float) :param e: an array for the bath levels ( :f:var:`ed_mode` = \ :code:`NORMAL, NONSU2, SUPERC`). It has dimension [ :data:`Nspin` , \ :data:`Norb` , :data:`Nbath` ] for :code:`NORMAL` bath, \ [ :data:`Nspin` , :data:`Nbath` ] for :code:`HYBRID` bath :type v: np.array(dtype=float) :param v: an array for the bath hybridizations ( :f:var:`ed_mode` = \ :code:`NORMAL, NONSU2, SUPERC`). It has dimension [ :data:`Nspin` , :data:`Norb` , \ :data:`Nbath` ] for :code:`NORMAL` and :code:`HYBRID` bath. \ For :code:`REPLICA` bath it has dimension [ :data:`Nbath` ] and for \ :code:`GENERAL` bath it has dimension [ :data:`Nbath` , :data:`Nspin` \ :math:`\\cdot` :data:`Norb` ] :type d: np.array(dtype=float) :param d: an array for the bath anomalous enery levels( :f:var:`ed_mode` \ = :code:`SUPERC`). It has dimension [ :data:`Nspin` , :data:`Norb` , \ :data:`Nbath` ] for :code:`NORMAL` bath, [ :data:`Nspin` , :data:`Nbath` ] \ for :code:`HYBRID` bath :type u: np.array(dtype=float) :param u: an array for the bath spin off-diagonal hybridization \ ( :f:var:`ed_mode` = :code:`NONSU2`). It has dimension [ :data:`Nspin`, \ :data:`Norb` , :data:`Nbath` ] for :code:`NORMAL` and :code:`HYBRID` bath :type l: np.array(dtype=float) :param l: an array for the linear coefficients of the Replica matrix \ linear combination ( :f:var:`bath_type` = :code:`REPLICA,GENERAL`). \ It has dimension [ :data:`Nbath` , :code:`Nsym` ], the latter being \ the number of terms on the linear combination :raise ValueError: if both :code:`bath` and some among :code:`e,u,v,d,l` \ are provided, none is provided, the shapes are inconsistent \ or the inputs are inconsistent with :f:var:`bath_type` and :f:var:`ed_mode` . :return: a dictionary containing the bath or the coefficients, with their name :rtype: dict """ def arr(x): return np.asarray(x, order="F") if x is not None else None def flat(x): return np.ravel(x, order="C") def check(x, shape, name): if x.shape != shape: raise ValueError(f"{name} must be {shape}") def pack(vals, order, bathtype): if bathtype > 2: return { "bath": np.ascontiguousarray( np.concatenate([[Nsym]] + [flat(vals[k]) for k in order]) ) } else: return { "bath": np.ascontiguousarray( np.concatenate([flat(vals[k]) for k in order]) ) } def unpack(b, spec): out = {} i = 0 for name, shape in spec["fields"].items(): n = int(np.prod(shape)) out[name] = np.ascontiguousarray(b[i : i + n].reshape(shape, order="C")) i += n return out Norb = ct.c_int.in_dll(self.library, "Norb").value Nspin = ct.c_int.in_dll(self.library, "Nspin").value Nbath = ct.c_int.in_dll(self.library, "Nbath").value Nsym = self.Nsym key = (self.get_ed_mode(), self.get_bath_type()) shape3 = (Nspin, Norb, Nbath) SPEC = { # normal mode, normal bath (1, 1): dict( fields={"e": shape3, "v": shape3}, order=["e", "v"], ), # superc mode, normal bath (2, 1): dict( fields={"e": shape3, "d": shape3, "v": shape3}, order=["e", "d", "v"], ), # nonsu2 mode, normal bath (3, 1): dict( fields={"e": shape3, "v": shape3, "u": shape3}, order=["e", "v", "u"], ), # normal mode, hybrid bath (1, 2): dict( fields={"e": (Nspin, Nbath), "v": shape3}, order=["e", "v"], ), # superc mode, hybrid bath (2, 2): dict( fields={"e": (Nspin, Nbath), "d": (Nspin, Nbath), "v": shape3}, order=["e", "d", "v"], ), # nonsu2 mode, hybrid bath (3, 2): dict( fields={"e": (Nspin, Nbath), "v": shape3, "u": shape3}, order=["e", "v", "u"], ), # normal mode, replica bath (1, 3): dict( fields={"v": (Nbath,), "l": (Nbath, Nsym)}, order=["v", "l"], ), # superc mode, replica bath (2, 3): dict( fields={"v": (Nbath,), "l": (Nbath, Nsym)}, order=["v", "l"], ), # nonsu2 mode, replica bath (3, 3): dict( fields={"v": (Nbath,), "l": (Nbath, Nsym)}, order=["v", "l"], ), # normal mode, general bath (1, 4): dict( fields={"v": (Nbath, Nspin * Norb), "l": (Nbath, Nsym)}, order=["v", "l"], ), # superc mode, general bath (2, 4): dict( fields={"v": (Nbath, Nspin * Norb), "l": (Nbath, Nsym)}, order=["v", "l"], ), # nonsu2 mode, general bath (3, 4): dict( fields={"v": (Nbath, Nspin * Norb), "l": (Nbath, Nsym)}, order=["v", "l"], ), } spec = SPEC.get(key) if spec is None: raise ValueError("bath_inspect: unsupported ED/bath combination") if bath is None: source = {"e": e, "v": v, "d": d, "u": u, "l": l} vals = {} for k, shape in spec["fields"].items(): vals[k] = arr(source[k]) check(vals[k], shape, k) return pack(vals, spec["order"], key[1]) else: bath = np.asarray(bath, order="F") Nb_dim = self.get_bath_dimension() if bath.shape[0] != Nb_dim: raise ValueError("bath_inspect: bath has wrong length") if key[1] > 2: if bath[0] != Nsym: raise ValueError("bath_inspect: bath[0] is not Nsym") bath = bath[1:] result = unpack(bath, spec) return {k: result[k] for k in spec["order"]}