From e2e7f212f772a0964dd46ef4109c3740d566524f Mon Sep 17 00:00:00 2001 From: mrf1g12 Date: Mon, 9 Feb 2026 15:48:02 +0100 Subject: [PATCH 1/5] bugfixes --- yambopy/bse/excitonradiativelifetimes.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/yambopy/bse/excitonradiativelifetimes.py b/yambopy/bse/excitonradiativelifetimes.py index 7724e6f8..dd7a3e08 100644 --- a/yambopy/bse/excitonradiativelifetimes.py +++ b/yambopy/bse/excitonradiativelifetimes.py @@ -136,7 +136,7 @@ def get_radiative_lifetime_3D_aniso(T,state,ylat,ydip,yexc,Meff,eps): -def get_radiative_lifetime_2D(T,state,ylat,ydip,yexc,Meff,eps=1): +def get_radiative_lifetime_2D(T,state,ylat,ydip,yexc,Meff,eps=1,dip_dir=[0,0,1]): """ Function to compute the radiative lifetime tau_S(T) of a single exciton state for 2D materials. @@ -147,7 +147,8 @@ def get_radiative_lifetime_2D(T,state,ylat,ydip,yexc,Meff,eps=1): * ydip: dipoles database, YamboDipolesDB * yexc: BSE database, YamboExcitonDB * Meff: exciton effective mass in electron rest mass (m_e) units. - * eps: environment dielectric constant. Default: eps=1, vacuum + * eps: environment dielectric constant. Default: eps=1, vacuum. + * dip_dir: orientation of the dipole moments. Default: [1,1,0] in the xy plane. Output * Radiative lifetime of exciton state in seconds @@ -159,7 +160,7 @@ def get_radiative_lifetime_2D(T,state,ylat,ydip,yexc,Meff,eps=1): lat = ylat.lat A = np.cross(lat[0],lat[1])[2] # Bohr**2 - muS2 = get_exciton_dipole(state,[1,1,0],ylat,ydip,yexc) # Bohr**2 + muS2 = get_exciton_dipole(state,dip_dir,ylat,ydip,yexc) # Bohr**2 ES = np.real(yexc.eigenvalues[state]) # eV Meff_eV = Meff*m_e # eV @@ -171,7 +172,7 @@ def get_radiative_lifetime_2D(T,state,ylat,ydip,yexc,Meff,eps=1): return 1/(prefactor*gamma0_factor*T_factor) # seconds -def get_radiative_lifetime_1D(T,state,ylat,ydip,yexc,Meff,eps=1): +def get_radiative_lifetime_1D(T,state,ylat,ydip,yexc,Meff,eps=1,dip_dir=[0,0,1]): """ Function to compute the radiative lifetime tau_S(T) of a single exciton state for 1D materials. @@ -182,7 +183,8 @@ def get_radiative_lifetime_1D(T,state,ylat,ydip,yexc,Meff,eps=1): * ydip: dipoles database, YamboDipolesDB * yexc: BSE database, YamboExcitonDB * Meff: exciton effective mass in electron rest mass (m_e) units. - * eps: environment dielectric constant. Default: eps=1, vacuum + * eps: environment dielectric constant. Default: eps=1, vacuum. + * dip_dir: orientation of the dipole moments. Default: [0,0,1] along z. Output * Radiative lifetime of exciton state in seconds @@ -192,9 +194,9 @@ def get_radiative_lifetime_1D(T,state,ylat,ydip,yexc,Meff,eps=1): raise ValueError("Meff and eps must be floats") lat = ylat.lat - Lz = lat[2] + Lz = lat[2,2] - muS2 = get_exciton_dipole(state,[0,0,1],ylat,ydip,yexc) # Bohr**2 + muS2 = get_exciton_dipole(state,dip_dir,ylat,ydip,yexc) # Bohr**2 ES = np.real(yexc.eigenvalues[state]) # eV Meff_eV = Meff*m_e # eV @@ -234,7 +236,7 @@ def get_radiative_lifetime_0D(state,ylat,ydip,yexc,eps=1): -def average_lifetime(Trange,states,ylat,ydip,yexc,dimension,Meff=None,eps=None): +def average_lifetime(Trange,states,ylat,ydip,yexc,dimension,Meff=None,eps=None,dip_dir=None): """ Function to compute the material's exciton radiative lifetime thermally averaged on the exciton states `states`. @@ -258,9 +260,9 @@ def average_lifetime(Trange,states,ylat,ydip,yexc,dimension,Meff=None,eps=None): elif dimension=='3D_aniso': gammas = np.array([1/get_radiative_lifetime_3D_aniso(Trange,state,ylat,ydip,yexc,Meff,eps) for state in states]) elif dimension=='2D': - gammas = np.array([1/get_radiative_lifetime_2D(Trange,state,ylat,ydip,yexc,Meff,eps) for state in states]) + gammas = np.array([1/get_radiative_lifetime_2D(Trange,state,ylat,ydip,yexc,Meff,eps,dip_dir) for state in states]) elif dimension=='1D': - gammas = np.array([1/get_radiative_lifetime_1D(Trange,state,ylat,ydip,yexc,Meff,eps) for state in states]) + gammas = np.array([1/get_radiative_lifetime_1D(Trange,state,ylat,ydip,yexc,Meff,eps,dip_dir) for state in states]) elif dimension=='0D': gammas = np.array([1/get_radiative_lifetime_0D(state,ylat,ydip,yexc,eps) for state in states]) else: From 6107f9f58de78e4d3745b32ff071beaf7d300dc2 Mon Sep 17 00:00:00 2001 From: mrf1g12 Date: Mon, 9 Feb 2026 16:06:57 +0100 Subject: [PATCH 2/5] bugfixes --- yambopy/bse/excitonradiativelifetimes.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/yambopy/bse/excitonradiativelifetimes.py b/yambopy/bse/excitonradiativelifetimes.py index dd7a3e08..b009a37a 100644 --- a/yambopy/bse/excitonradiativelifetimes.py +++ b/yambopy/bse/excitonradiativelifetimes.py @@ -250,28 +250,32 @@ def average_lifetime(Trange,states,ylat,ydip,yexc,dimension,Meff=None,eps=None,d - '3D' or '3D_iso' for isotropic 3D bulk systems - '3D_aniso' for anisotropic (uniaxial) 3D bulks - '2D', '1D', '0D' for lower-dimensional systems + * Meff: exciton effective mass. Needed by 3D, 2D, 1D calculations. + * eps: environment dielectric constant. + * dip_dir: dipole orientation. Needed by 2D and 1D calculations. Output * Array of averaged radiative lifetime with length as Trange in input """ + + ES = np.real(yexc.eigenvalues) + DeltaE = ES-ES[states[0]] if dimension in ['3D','3D_iso']: - gammas = np.array([1/get_radiative_lifetime_3D_iso(Trange,state,ylat,ydip,yexc,Meff,eps) for state in states]) + gammas = np.array([np.exp(-DeltaE[state]/(kb*Trange))/get_radiative_lifetime_3D_iso(Trange,state,ylat,ydip,yexc,Meff,eps) for state in states]) elif dimension=='3D_aniso': - gammas = np.array([1/get_radiative_lifetime_3D_aniso(Trange,state,ylat,ydip,yexc,Meff,eps) for state in states]) + gammas = np.array([np.exp(-DeltaE[state]/(kb*Trange))/get_radiative_lifetime_3D_aniso(Trange,state,ylat,ydip,yexc,Meff,eps) for state in states]) elif dimension=='2D': - gammas = np.array([1/get_radiative_lifetime_2D(Trange,state,ylat,ydip,yexc,Meff,eps,dip_dir) for state in states]) + gammas = np.array([np.exp(-DeltaE[state]/(kb*Trange))/get_radiative_lifetime_2D(Trange,state,ylat,ydip,yexc,Meff,eps,dip_dir) for state in states]) elif dimension=='1D': - gammas = np.array([1/get_radiative_lifetime_1D(Trange,state,ylat,ydip,yexc,Meff,eps,dip_dir) for state in states]) + gammas = np.array([np.exp(-DeltaE[state]/(kb*Trange))/get_radiative_lifetime_1D(Trange,state,ylat,ydip,yexc,Meff,eps,dip_dir) for state in states]) elif dimension=='0D': - gammas = np.array([1/get_radiative_lifetime_0D(state,ylat,ydip,yexc,eps) for state in states]) + gammas = np.array([np.exp(-DeltaE[state]/(kb*Trange))/get_radiative_lifetime_0D(state,ylat,ydip,yexc,eps) for state in states]) else: raise ValueError("dimension must be one of the following: '3D','3D_iso','3D_aniso', '2D', '1D', '0D'") gamma_sum = np.sum(gammas,axis=0) - ES = np.real(yexc.eigenvalues) - DeltaE = ES-ES[states[0]] normalize = np.array([np.exp(-DeltaE[state]/(kb*Trange)) for state in states]) normalize_sum = np.sum(normalize,axis=0) From e750d41e09367b13ca77b7140fdee0ee09605d37 Mon Sep 17 00:00:00 2001 From: mrf1g12 Date: Tue, 10 Feb 2026 16:16:37 +0100 Subject: [PATCH 3/5] bugfixes --- yambopy/bse/excitonradiativelifetimes.py | 40 ++++++++++++++---------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/yambopy/bse/excitonradiativelifetimes.py b/yambopy/bse/excitonradiativelifetimes.py index b009a37a..2037fa40 100644 --- a/yambopy/bse/excitonradiativelifetimes.py +++ b/yambopy/bse/excitonradiativelifetimes.py @@ -60,7 +60,7 @@ def get_exciton_dipole(state, blongdir, ylat, ydip, yexc, _cache={}): -def get_radiative_lifetime_3D_iso(T,state,ylat,ydip,yexc,Meff,eps): +def get_radiative_lifetime_3D_iso(T,state,ylat,ydip,yexc,Meff,eps,shiftE=0): """ Function to compute the radiative lifetime tau_S(T) of a single exciton state for *isotropic* 3D materials. @@ -72,6 +72,7 @@ def get_radiative_lifetime_3D_iso(T,state,ylat,ydip,yexc,Meff,eps): * yexc: BSE database, YamboExcitonDB * Meff: exciton effective mass in electron rest mass (m_e) units. * eps: material's relative optical dielectric constant + * shiftE: rigid shift of exciton energies. Default: shift=0 eV Output * Radiative lifetime of exciton state in seconds @@ -83,7 +84,7 @@ def get_radiative_lifetime_3D_iso(T,state,ylat,ydip,yexc,Meff,eps): Omega = ylat.lat_vol #Bohr**3 muS2 = get_exciton_dipole(state,[1,1,1],ylat,ydip,yexc) # Bohr**2 - ES = np.real(yexc.eigenvalues[state]) # eV + ES = np.real(yexc.eigenvalues[state])+shiftE # eV Meff_eV = Meff*m_e # eV @@ -94,7 +95,7 @@ def get_radiative_lifetime_3D_iso(T,state,ylat,ydip,yexc,Meff,eps): return 1/(prefactor*dipole_factor*T_factor) -def get_radiative_lifetime_3D_aniso(T,state,ylat,ydip,yexc,Meff,eps): +def get_radiative_lifetime_3D_aniso(T,state,ylat,ydip,yexc,Meff,eps,shiftE=0): """ Function to compute the radiative lifetime tau_S(T) of a single exciton state for *anisotropic* (uniaxial) 3D materials. @@ -106,6 +107,7 @@ def get_radiative_lifetime_3D_aniso(T,state,ylat,ydip,yexc,Meff,eps): * yexc: BSE database, YamboExcitonDB * Meff: 2 element list: exciton effective masses in electron rest mass (m_e) units in-plane, out-of-plane: [Meff_xy, Meff_z] * eps: 2 element list: material's relative optical dielectric constants in-plane, out-of-plane: [eps_xy, eps_z] + * shiftE: rigid shift of exciton energies. Default: shift=0 eV Output * Radiative lifetime of exciton state in seconds @@ -120,7 +122,7 @@ def get_radiative_lifetime_3D_aniso(T,state,ylat,ydip,yexc,Meff,eps): muS2_xy = get_exciton_dipole(state,[1,1,0],ylat,ydip,yexc) # Bohr**2 muS2_z = get_exciton_dipole(state,[0,0,1],ylat,ydip,yexc) # Bohr**2 - ES = np.real(yexc.eigenvalues[state]) # eV + ES = np.real(yexc.eigenvalues[state])+shiftE # eV Meff_xy_eV = Meff[0]*m_e # eV Meff_z_eV = Meff[1]*m_e # eV @@ -136,7 +138,7 @@ def get_radiative_lifetime_3D_aniso(T,state,ylat,ydip,yexc,Meff,eps): -def get_radiative_lifetime_2D(T,state,ylat,ydip,yexc,Meff,eps=1,dip_dir=[0,0,1]): +def get_radiative_lifetime_2D(T,state,ylat,ydip,yexc,Meff,eps=1,dip_dir=[1,1,0],shiftE=0): """ Function to compute the radiative lifetime tau_S(T) of a single exciton state for 2D materials. @@ -149,6 +151,7 @@ def get_radiative_lifetime_2D(T,state,ylat,ydip,yexc,Meff,eps=1,dip_dir=[0,0,1]) * Meff: exciton effective mass in electron rest mass (m_e) units. * eps: environment dielectric constant. Default: eps=1, vacuum. * dip_dir: orientation of the dipole moments. Default: [1,1,0] in the xy plane. + * shiftE: rigid shift of exciton energies. Default: shift=0 eV Output * Radiative lifetime of exciton state in seconds @@ -161,7 +164,7 @@ def get_radiative_lifetime_2D(T,state,ylat,ydip,yexc,Meff,eps=1,dip_dir=[0,0,1]) A = np.cross(lat[0],lat[1])[2] # Bohr**2 muS2 = get_exciton_dipole(state,dip_dir,ylat,ydip,yexc) # Bohr**2 - ES = np.real(yexc.eigenvalues[state]) # eV + ES = np.real(yexc.eigenvalues[state])+shiftE # eV Meff_eV = Meff*m_e # eV @@ -172,7 +175,7 @@ def get_radiative_lifetime_2D(T,state,ylat,ydip,yexc,Meff,eps=1,dip_dir=[0,0,1]) return 1/(prefactor*gamma0_factor*T_factor) # seconds -def get_radiative_lifetime_1D(T,state,ylat,ydip,yexc,Meff,eps=1,dip_dir=[0,0,1]): +def get_radiative_lifetime_1D(T,state,ylat,ydip,yexc,Meff,eps=1,dip_dir=[0,0,1],shiftE=0): """ Function to compute the radiative lifetime tau_S(T) of a single exciton state for 1D materials. @@ -185,6 +188,7 @@ def get_radiative_lifetime_1D(T,state,ylat,ydip,yexc,Meff,eps=1,dip_dir=[0,0,1]) * Meff: exciton effective mass in electron rest mass (m_e) units. * eps: environment dielectric constant. Default: eps=1, vacuum. * dip_dir: orientation of the dipole moments. Default: [0,0,1] along z. + * shiftE: rigid shift of exciton energies. Default: shift=0 eV Output * Radiative lifetime of exciton state in seconds @@ -197,7 +201,7 @@ def get_radiative_lifetime_1D(T,state,ylat,ydip,yexc,Meff,eps=1,dip_dir=[0,0,1]) Lz = lat[2,2] muS2 = get_exciton_dipole(state,dip_dir,ylat,ydip,yexc) # Bohr**2 - ES = np.real(yexc.eigenvalues[state]) # eV + ES = np.real(yexc.eigenvalues[state])+shiftE # eV Meff_eV = Meff*m_e # eV @@ -208,7 +212,7 @@ def get_radiative_lifetime_1D(T,state,ylat,ydip,yexc,Meff,eps=1,dip_dir=[0,0,1]) return 1/(prefactor*gamma0_factor*T_factor) # seconds -def get_radiative_lifetime_0D(state,ylat,ydip,yexc,eps=1): +def get_radiative_lifetime_0D(state,ylat,ydip,yexc,eps=1,shiftE=0): """ Function to compute the radiative lifetime tau_S(T) of a single exciton state for 0D materials. @@ -218,6 +222,7 @@ def get_radiative_lifetime_0D(state,ylat,ydip,yexc,eps=1): * ydip: dipoles database, YamboDipolesDB * yexc: BSE database, YamboExcitonDB * eps: environment dielectric constant. Default: eps=1, vacuum + * shiftE: rigid shift of exciton energies. Default: shift=0 eV Output * Radiative lifetime of exciton state in seconds @@ -227,7 +232,7 @@ def get_radiative_lifetime_0D(state,ylat,ydip,yexc,eps=1): raise ValueError("eps must be float") muS2 = get_exciton_dipole(state,[1,1,1],ylat,ydip,yexc) # Bohr**2 - ES = np.real(yexc.eigenvalues[state]) # eV + ES = np.real(yexc.eigenvalues[state])+shiftE # eV gamma0_factor = np.sqrt(eps)*(ES/ha2ev)**3*muS2 prefactor = 4*np.pi/(3*speed_of_light**3)/autime2s @@ -236,7 +241,7 @@ def get_radiative_lifetime_0D(state,ylat,ydip,yexc,eps=1): -def average_lifetime(Trange,states,ylat,ydip,yexc,dimension,Meff=None,eps=None,dip_dir=None): +def average_lifetime(Trange,states,ylat,ydip,yexc,dimension,Meff=None,eps=None,dip_dir=None,shiftE=0): """ Function to compute the material's exciton radiative lifetime thermally averaged on the exciton states `states`. @@ -253,24 +258,25 @@ def average_lifetime(Trange,states,ylat,ydip,yexc,dimension,Meff=None,eps=None,d * Meff: exciton effective mass. Needed by 3D, 2D, 1D calculations. * eps: environment dielectric constant. * dip_dir: dipole orientation. Needed by 2D and 1D calculations. + * shiftE: rigid shift of exciton energies. Default: shift=0 eV Output * Array of averaged radiative lifetime with length as Trange in input """ - ES = np.real(yexc.eigenvalues) + ES = np.real(yexc.eigenvalues)+shiftE DeltaE = ES-ES[states[0]] if dimension in ['3D','3D_iso']: - gammas = np.array([np.exp(-DeltaE[state]/(kb*Trange))/get_radiative_lifetime_3D_iso(Trange,state,ylat,ydip,yexc,Meff,eps) for state in states]) + gammas = np.array([np.exp(-DeltaE[state]/(kb*Trange))/get_radiative_lifetime_3D_iso(Trange,state,ylat,ydip,yexc,Meff,eps,shiftE) for state in states]) elif dimension=='3D_aniso': - gammas = np.array([np.exp(-DeltaE[state]/(kb*Trange))/get_radiative_lifetime_3D_aniso(Trange,state,ylat,ydip,yexc,Meff,eps) for state in states]) + gammas = np.array([np.exp(-DeltaE[state]/(kb*Trange))/get_radiative_lifetime_3D_aniso(Trange,state,ylat,ydip,yexc,Meff,eps,shiftE) for state in states]) elif dimension=='2D': - gammas = np.array([np.exp(-DeltaE[state]/(kb*Trange))/get_radiative_lifetime_2D(Trange,state,ylat,ydip,yexc,Meff,eps,dip_dir) for state in states]) + gammas = np.array([np.exp(-DeltaE[state]/(kb*Trange))/get_radiative_lifetime_2D(Trange,state,ylat,ydip,yexc,Meff,eps,dip_dir,shiftE) for state in states]) elif dimension=='1D': - gammas = np.array([np.exp(-DeltaE[state]/(kb*Trange))/get_radiative_lifetime_1D(Trange,state,ylat,ydip,yexc,Meff,eps,dip_dir) for state in states]) + gammas = np.array([np.exp(-DeltaE[state]/(kb*Trange))/get_radiative_lifetime_1D(Trange,state,ylat,ydip,yexc,Meff,eps,dip_dir,shiftE) for state in states]) elif dimension=='0D': - gammas = np.array([np.exp(-DeltaE[state]/(kb*Trange))/get_radiative_lifetime_0D(state,ylat,ydip,yexc,eps) for state in states]) + gammas = np.array([np.exp(-DeltaE[state]/(kb*Trange))/get_radiative_lifetime_0D(state,ylat,ydip,yexc,eps,shiftE) for state in states]) else: raise ValueError("dimension must be one of the following: '3D','3D_iso','3D_aniso', '2D', '1D', '0D'") From ba06fe3327a93aafc115103105fd1b41d23491b9 Mon Sep 17 00:00:00 2001 From: mrf1g12 Date: Tue, 10 Feb 2026 16:17:26 +0100 Subject: [PATCH 4/5] bugfixes --- yambopy/bse/excitonradiativelifetimes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yambopy/bse/excitonradiativelifetimes.py b/yambopy/bse/excitonradiativelifetimes.py index 2037fa40..093156a3 100644 --- a/yambopy/bse/excitonradiativelifetimes.py +++ b/yambopy/bse/excitonradiativelifetimes.py @@ -222,7 +222,7 @@ def get_radiative_lifetime_0D(state,ylat,ydip,yexc,eps=1,shiftE=0): * ydip: dipoles database, YamboDipolesDB * yexc: BSE database, YamboExcitonDB * eps: environment dielectric constant. Default: eps=1, vacuum - * shiftE: rigid shift of exciton energies. Default: shift=0 eV + * shiftE: rigid shift of exciton energies. Default: shift=0 eV. Output * Radiative lifetime of exciton state in seconds From 94fd29f86590650b8cb84c41a2a6b29f3388688b Mon Sep 17 00:00:00 2001 From: mrf1g12 Date: Tue, 10 Feb 2026 16:24:04 +0100 Subject: [PATCH 5/5] bugfixes --- yambopy/bse/excitonradiativelifetimes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yambopy/bse/excitonradiativelifetimes.py b/yambopy/bse/excitonradiativelifetimes.py index 093156a3..62867dc6 100644 --- a/yambopy/bse/excitonradiativelifetimes.py +++ b/yambopy/bse/excitonradiativelifetimes.py @@ -258,7 +258,7 @@ def average_lifetime(Trange,states,ylat,ydip,yexc,dimension,Meff=None,eps=None,d * Meff: exciton effective mass. Needed by 3D, 2D, 1D calculations. * eps: environment dielectric constant. * dip_dir: dipole orientation. Needed by 2D and 1D calculations. - * shiftE: rigid shift of exciton energies. Default: shift=0 eV + * shiftE: rigid shift of exciton energies. Default: shift=0 eV. Output * Array of averaged radiative lifetime with length as Trange in input