SecondHarmonicsGenerationSusceptibility

class SecondHarmonicsGenerationSusceptibility(configuration, kpoints=None, energies=None, broadening=None, bands_below_fermi_level=None, bands_above_fermi_level=None, use_symmetries=None, occupation_tolerance=None, tensor_indices=None)
Parameters:
  • configuration (BulkConfiguration) – The bulk configuration with an attached calculator for which to calculate the optical spectrum.

  • kpoints (sequence (size 3) of int | MonkhorstPackGrid | KpointDensity) – The k-points for which to calculate the transitions.
    Default: The Monkhorst-Pack grid used for the self-consistent calculation.

  • energies (PhysicalQuantity of type energy) – The energies for which to calculate the second harmonics generation susceptibility.
    Default: numpy.linspace(0, 4, 101) * eV

  • broadening (PhysicalQuantity of type energy) – The broadening parameter used for the optical spectrum.
    Default: 0.1 * eV

  • bands_below_fermi_level (int | All) – The maximum number of valence band states per principal spin channel to include at each k-point.
    Default: All valence bands

  • bands_above_fermi_level (int | All) – The maximum number of conduction band states per principal spin channel to include at each k-point.
    Default: All conduction bands

  • use_symmetries (bool) – Boolean to control if symmetries should be used to reduce k-points and abc-indices.
    Default: True

  • occupation_tolerance (float) – Terms with Fermi occupation differences smaller than the occupation tolerance will be skipped. If one is only interested in the low temperature limit, this can be set to a finite value, like 0.1 in order to speed up calculations. If the temperature set on the calculator should be fully respected, the occupation_tolerance should be set to 0.
    Default: 0.1

  • tensor_indices (list of tuples.) – List of tuples of x,y,z indices (0, 1, or 2) to be calculated, like [(0, 0, 0), (0, 1, 2)] for calculating the (x,x,x) and (x,y,z) component of the SHG tensor.
    Default: By default the list of indices is determined by the symmetries of the system and only those components, which contribute will be calculated. If use_symmetries=False all indices will be calculated.

bandsAboveFermiLevel()
Returns:

The number of above the Fermi level included in the calculation.

Return type:

int

bandsBelowFermiLevel()
Returns:

The number of below the Fermi level included in the calculation.

Return type:

int

broadening()
Returns:

The broadening parameter used for the spectrum.

Return type:

PhysicalQuantity of type energy

energies()
Returns:

The energies for which to calculate the spectrum.

Return type:

PhysicalQuantity of type energy

evaluate(spin=None)
Parameters:

spin (Spin.Up | Spin.Down | Spin.Sum | Spin.All) – The user provided spin parameter.
Default: Spin.Sum

Returns:

Returns the total SHG susceptibility tensor. The tensor has the shape (number_of_spins, number_of_enegies, 3, 3, 3) if spin=Spin.All, otherwise the shape is (number_of_enegies, 3, 3, 3).

Return type:

PhysicalQuantity of type Length / Volt

metatext()
Returns:

The metatext of the object or None if no metatext is present.

Return type:

str | None

nlprint(stream=None)

Print a string containing an ASCII table useful for plotting the AnalysisSpin object.

Parameters:

stream (python stream) – The stream the table should be written to.
Default: NLPrintLogger()

setMetatext(metatext)

Set a given metatext string on the object.

Parameters:

metatext (str | None) – The metatext string that should be set. A value of “None” can be given to remove the current metatext.

uniqueString()

Return a unique string representing the state of the object.

useSymmetries()
Returns:

Boolean controlling if symmetries should be applied or not.

Return type:

bool

Usage Examples

Calculate the SecondHarmonicsGenerationSusceptibility of GaAs using GGA-1/2 exchange-correlation.:

# -*- coding: utf-8 -*-
# -------------------------------------------------------------
# Bulk Configuration
# -------------------------------------------------------------

# Set up lattice
lattice = FaceCenteredCubic(5.6537*Angstrom)

# Define elements
elements = [Gallium, Arsenic]

# Define coordinates
fractional_coordinates = [[ 0.  ,  0.  ,  0.  ],
                          [ 0.25,  0.25,  0.25]]

# Set up configuration
bulk_configuration = BulkConfiguration(
    bravais_lattice=lattice,
    elements=elements,
    fractional_coordinates=fractional_coordinates
    )

# -------------------------------------------------------------
# Calculator
# -------------------------------------------------------------
#----------------------------------------
# Basis Set
#----------------------------------------
basis_set = [
    GGABasis.Gallium_DoubleZetaPolarized,
    GGABasis.Arsenic_DoubleZetaPolarized,
    ]

#----------------------------------------
# Exchange-Correlation
#----------------------------------------
exchange_correlation = GGAHalf.PBE

k_point_sampling = MonkhorstPackGrid(
    na=13,
    nb=13,
    nc=13,
    )
numerical_accuracy_parameters = NumericalAccuracyParameters(
    density_mesh_cutoff=45.0*Hartree,
    k_point_sampling=k_point_sampling,
    occupation_method=FermiDirac(100.0*Kelvin*boltzmann_constant),
    )

calculator = LCAOCalculator(
    basis_set=basis_set,
    exchange_correlation=exchange_correlation,
    numerical_accuracy_parameters=numerical_accuracy_parameters,
    )

bulk_configuration.setCalculator(calculator)
nlprint(bulk_configuration)
bulk_configuration.update()
nlsave('GaAs.hdf5', bulk_configuration)

# -------------------------------------------------------------
# Second Harmonics Generation Susceptibility
# -------------------------------------------------------------
kpoint_grid = MonkhorstPackGrid(
    na=14,
    nb=14,
    nc=14,
    )

second_harmonics_generation_susceptibility = SecondHarmonicsGenerationSusceptibility(
    configuration=bulk_configuration,
    kpoints=kpoint_grid,
    energies=numpy.linspace(0, 5, 101)*eV,
    broadening=0.1*eV,
    bands_below_fermi_level=4,
    bands_above_fermi_level=8,
    use_symmetries=True,
    tensor_indices=None,
    )
nlsave('GaAs.hdf5', second_harmonics_generation_susceptibility)

gaas_shg.py

Notes

Theory

The optical polarization \(P_a(\omega)\) can in general be expressed in terms of responce functions, called susceptibilities, and the total macroscopic electric field \(\mathbf{E}(\omega)\) [1]:

\[P_a(\omega) = \chi^{(1)}_{ab}(-\omega, \omega) E^b(\omega) + \chi^{(2)}_{abc}(-\omega' -\omega'', \omega', \omega'')E^b(\omega')E^c(\omega'') + ...\]

The first-order, or linear, susceptibility \(\chi^{(1)}_{ab}(-\omega, \omega)=\chi^{(1)}_{ab}(\omega)\) is a rank two tensor and available in QuantumATK from an OpticalSpectrum calculation.

The second order susceptibility is a rank three tensor and in general it depends on two frequency arguments, \(\omega'\) and \(\omega''\). The second harmonics generation (SHG) susceptibility, \(\chi^{(2)}_{SHG}(-2\omega, \omega, \omega)\) is the special case, where \(\omega'=\omega''\). This is obviously relevant for studying second harmonic generation in e.g. lasers applications. In the low-frequncy limit \(\omega\rightarrow 0\), \(\chi^{(2)}_{SHG}(-2\omega, \omega, \omega)\) coinsides with the linear electro-optic (LEO) susceptibility \(\chi^{(2)}_{LEO}(-\omega, \omega, 0)\) [2] and can thus be used to obtain the electronic contribution to the low-frequency electro-optic tensor.

The SecondHarmonicsGenerationSusceptibility class calculates the second harmonics genreration susceptibility tensor following the works of Sipe et al. [3][2] and Sharma et al. [4]. The methodology is based on perturbation theory within the independent particle approximation.

The total susceptibility can be divided into three terms: The interband transitions \(\chi^{(2)}_{inter}(-2\omega, \omega, \omega)\), the intraband transitions \(\chi^{(2)}_{intra}(-2\omega, \omega, \omega)\), and a modulation of interband terms by intraband terms, \(\chi^{(2)}_{mod}(-2\omega, \omega, \omega)\): such that

\[\chi^{(2)}(-2\omega, \omega, \omega) = \chi^{(2)}_{inter}(-2\omega, \omega, \omega) + \chi^{(2)}_{intra}(-2\omega, \omega, \omega) + \chi^{(2)}_{mod}(-2\omega, \omega, \omega)\]

Detailed expressions for the three terms are given in Eqs. A1-A3 in Ref. [4].

Tensor indices and symmetries

By default, the SecondHarmonicsGenerationSusceptibility will be constructed with the parameter use_symmetries=True implying that the k-point sampling is reduced to the irreducible part of the Brillouin zone and that the \(\chi^{(2)}_{abc}(-2\omega, \omega, \omega)\) tensor is symmetrized. This is the recommended setting since it significantly speeds up the calculation time due to the k-point reduction. The symmetrization of the tensor implies that only certain tensor elements are non-zero. For cubic structures, like GaAs in the script above, only tensor elements of the form \((a,b,c)=(x,y,z)\) i.e. where \(a \neq b \neq c\) are non-zero. For other symmetry classes the non-zero elements will be different.

If use_symmetries=False by default all tensor elements will be calculated. In that case it is possible to specify which indices to be calculated using the tensor_indices input parameters.

Convergence of results

When performing SecondHarmonicsGenerationSusceptibility calculations it is important to check that the calculated susceptibility is converged with respect to the numerical parameters. The important parameters to check convergence for are

  1. K-point sampling. Increase the k-point sampling to ensure the results are converged.

  2. Broadening. The energy broadening should inprinciple be infinitesimally small. Usually a value of 0.1*eV is reasonable, but results should be checked by lowering the value of the broadening parameter. Note that when lowering the broadening the k-point sampling needs to be increased in order to have comparable results.

  3. Bands above and below the Fermi level. The parameters bands_below_fermi_level and bands_above_fermi_level determines how many bands are included in the calculation. The calculated spectra needs to be converged wrt. to the number of bands included. Increase the number of bands above and below the Fermi level to verify convergence.

In general these numbers can be chosen by inspecting the band structure and selecting the bands that contribute to an energy range of interest. Reducing the number of included bands significantly speeds up the simulation.