Phoebe developer's documentation  1.1.0
Phonon and Electron Boltzmann Equations
ScatteringMatrix Class Referenceabstract

Base class of the scattering matrix. More...

#include <scattering_matrix.h>

Inheritance diagram for ScatteringMatrix:
Collaboration diagram for ScatteringMatrix:

Public Member Functions

 ScatteringMatrix (Context &context_, StatisticsSweep &statisticsSweep_, BaseBandStructure &innerBandStructure_, BaseBandStructure &outerBandStructure_)
 Scattering matrix constructor. More...
 
 ScatteringMatrix ()
 Default constructor.
 
void setup ()
 This method needs to be called right after the constructor. More...
 
VectorBTE diagonal ()
 Returns the diagonal matrix elements. More...
 
double & operator() (const int &row, const int &col)
 Get and set operator. More...
 
VectorBTE offDiagonalDot (VectorBTE &inPopulation)
 Computes the product A*f - diagonal(A)*f where A is the scattering matrix and f is the vector of quasiparticle populations.
 
std::vector< VectorBTEoffDiagonalDot (std::vector< VectorBTE > &inPopulations)
 
VectorBTE dot (VectorBTE &inPopulation)
 Computes the product A*f where A is the scattering matrix and f is the vector of quasiparticle populations.
 
std::vector< VectorBTEdot (std::vector< VectorBTE > &inPopulations)
 
VectorBTE getSingleModeTimes ()
 Call to obtain the single-particle relaxation times of the systems. More...
 
VectorBTE getLinewidths ()
 Converts symmetrized internal scattering matrix diagonal to linewidths and returns the result. More...
 
void setLinewidths (VectorBTE &linewidths)
 Call to set the single-particle linewidths. More...
 
VectorBTE getSingleModeTimes (const VectorBTE &anyInternalDiagonal)
 Call to obtain the single-particle relaxation times of the systems given any internal diagonal like object – (basically, the linewidths but potentially scaled by some symmetrization factor) More...
 
VectorBTE getLinewidths (const VectorBTE &anyInternalDiagonal)
 Call to obtain the single-particle linewidths. More...
 
void a2Omega ()
 Converts the scattering matrix from the form A to the symmetrised Omega. More...
 
void omega2A ()
 The inverse of a2Omega, converts the matrix Omega to A.
 
std::tuple< Eigen::VectorXd, ParallelMatrix< double > > diagonalize (int numEigenvalues=0)
 Diagonalize the scattering matrix. More...
 
int getSMatrixIndex (BteIndex &bteIndex, CartIndex &cartIndex)
 Function to combine a BTE index and a cartesian index into one index of the scattering matrix. More...
 
std::tuple< BteIndex, CartIndexgetSMatrixIndex (const int &iMat)
 Function to split a scattering matrix index (on rows/columns of S) into a BTE index and a cartesian index. More...
 
void symmetrize ()
 Reinforce the condition that the matrix is symmetric.
 
void relaxonsToJSON (const std::string &fileName, const Eigen::VectorXd &eigenvalues)
 Output relaxons scattering matrix quantities to file (particularly the tau values) Jenny's note: However, I have a feeling this should be elsewhere, as we're actually passing the eigenvalues back into this function. More...
 
std::vector< std::tuple< int, int > > getAllLocalStates ()
 Call the underlying PMatrix function to return the iterator of all elements of the matrix which are local. More...
 
void outputToHDF5 (const std::string &outFileName)
 Outputs the matrix to an hdf5 file. More...
 

Static Public Member Functions

static void symmetrizeCoupling (Eigen::Tensor< double, 3 > &coupling, const Eigen::VectorXd &energies1, const Eigen::VectorXd &energies2, const Eigen::VectorXd &energies3)
 Average the coupling for degenerate states. More...
 

Protected Member Functions

virtual void builder (std::shared_ptr< VectorBTE > linewidth, std::vector< VectorBTE > &inPopulations, std::vector< VectorBTE > &outPopulations)=0
 Method that actually computes the scattering matrix. More...
 
std::vector< std::tuple< std::vector< int >, int > > getIteratorWavevectorPairs (const bool &rowMajor=false)
 Returns a vector of pairs of wavevector indices to iterate over during the construction of the scattering matrix. More...
 
void degeneracyAveragingLinewidths (std::shared_ptr< VectorBTE > linewidth)
 Performs an average of the linewidths over degenerate states. More...
 
Eigen::MatrixXd precomputeOccupations (BaseBandStructure &bandStructure)
 Function to precompute particle populations before scattering rates are calculated. More...
 
std::vector< int > getExcludeIndices (BaseBandStructure &bandStructure)
 Method which for a phonon bandstructure returns the indices to be discarded in a phonon calculation due to very low phonon frequencies. More...
 
void setMatrixCase (std::shared_ptr< VectorBTE > linewidth, std::vector< VectorBTE > &inPopulations, std::vector< VectorBTE > &outPopulations)
 
void addRateToMatrix (const Context &context, double linewidthRate, double matrixRate, int iCalc, int is1, int is2Irr, int iBte1, int iBte2, const Particle &p1, const Particle &p2, const Eigen::Matrix3d &rotation, std::shared_ptr< VectorBTE > linewidth, const std::vector< VectorBTE > &inPopulations, std::vector< VectorBTE > &outPopulations)
 Method to add scattering rate to matrix and linewidth containers. More...
 
void enforceDetailedBalance ()
 A function to fix the linewidths to agree with the off diagonal elements, to enforce finding the special eigenvectors.
 
void replaceMatrixLinewidths ()
 Replace the linewidths of the scatterng matrix with the supplied VectorBTE values.
 
std::tuple< BaseBandStructure *, BaseBandStructure * > getStateBandStructures (const BteIndex &iBte1, const BteIndex &iBte2)
 Returns a tuple of final and initial particles for a give state. More...
 
std::tuple< int, int > coupledToBandStructureIndices (const int &iBte1, const int &iBte2, const Particle &p1, const Particle &p2)
 If we have a coupled scattering matrix, we need to shift the matrix element indices back to those associated with ph and el bandstructures before accessing their quantities. More...
 
template<size_t n>
void addUNRates (int iCalc, int iBte, double rate, const std::array< Point, n > &crysPoints, auto momentumConsExpr)
 Generic function to add UN times to their containers. More...
 

Protected Attributes

Contextcontext
 
StatisticsSweepstatisticsSweep
 
BaseBandStructureinnerBandStructure
 
BaseBandStructureouterBandStructure
 
enum MatrixCase matrixCase
 
bool constantRTA = false
 
bool highMemory = true
 
bool outputUNTimes = false
 
double boundaryLength
 
bool doBoundary
 
bool isMatrixOmega = false
 
bool isCoupled = false
 
std::function< std::tuple< long, long >long, long, const Particle &, const Particle &)> shiftToCoupledIndices
 
std::shared_ptr< VectorBTEinternalDiagonal
 
std::shared_ptr< VectorBTEinternalDiagonalUmklapp
 
std::shared_ptr< VectorBTEinternalDiagonalNormal
 
ParallelMatrix< double > theMatrix
 
int numStates
 
int numCalculations
 
int dimensionality_
 
int numElStates = 0
 
std::vector< int > excludeIndices
 

Friends

void addBoundaryScattering (ScatteringMatrix &matrix, Context &context, std::vector< VectorBTE > &inPopulations, std::vector< VectorBTE > &outPopulations, BaseBandStructure &outerBandStructure, std::shared_ptr< VectorBTE > linewidth)
 

Detailed Description

Note: this is an abstract class, which can only work if builder() is defined

Constructor & Destructor Documentation

◆ ScatteringMatrix()

ScatteringMatrix::ScatteringMatrix ( Context context_,
StatisticsSweep statisticsSweep_,
BaseBandStructure innerBandStructure_,
BaseBandStructure outerBandStructure_ 
)
Parameters
contextobject containing user input configuration.
statisticsSweepobject controlling the loops over temperature and chemical potential.
innerBandStructurebandStructure object. This is the mesh used to integrate the scattering rates for each state of outerBandStructure. For transport calculation, this object is typically equal to outerBandStructure. Might differ when outerBS is on a path of points.
outerBandStructurebandStructure object. The scattering rates properties are computed on the grid of points specified by this object, e.g. this could be a path of points or a uniform mesh of points
Here is the call graph for this function:

Member Function Documentation

◆ a2Omega()

void ScatteringMatrix::a2Omega ( )

A acts on the canonical phonon population f, while Omega acts on the symmetrised phonon population \tilde{n}. Note: for phonons, n = bose(bose+1)f , with bose being the bose–einstein distribution, while n = sqrt(bose(bose+1)) tilde(n). Only works if the matrix is kept in memory and after setup() has been called.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ addRateToMatrix()

void ScatteringMatrix::addRateToMatrix ( const Context context,
double  linewidthRate,
double  matrixRate,
int  iCalc,
int  is1,
int  is2Irr,
int  iBte1,
int  iBte2,
const Particle p1,
const Particle p2,
const Eigen::Matrix3d &  rotation,
std::shared_ptr< VectorBTE linewidth,
const std::vector< VectorBTE > &  inPopulations,
std::vector< VectorBTE > &  outPopulations 
)
protected
Parameters
contextthe context for the calculation
ratethe scattering rate being added
iBte1the BTE index of the first state
iBte2the BTE index of the second state
p1the particle type associated with iBte1
p2the particle type associated with iBte2
inPopulations
outPopulations
Here is the call graph for this function:

◆ addUNRates()

template<size_t n>
void ScatteringMatrix::addUNRates ( int  iCalc,
int  iBte,
double  rate,
const std::array< Point, n > &  crysPoints,
auto  momentumConsExpr 
)
inlineprotected
Parameters
iCalcthe calculation index labeling T and mu
iBtethe index of the linewidth container
ratescattering rate of this process
crysPointslist of Points objects which will be used to calculate if is U process. NOTE: this must be a list in the same order as the momentumConservation expects them...
momentumConsnExprlambda function returning the expression for the final wavevector to be folded
Here is the call graph for this function:

◆ builder()

virtual void ScatteringMatrix::builder ( std::shared_ptr< VectorBTE linewidth,
std::vector< VectorBTE > &  inPopulations,
std::vector< VectorBTE > &  outPopulations 
)
protectedpure virtual

Pure virtual function: needs an implementation in every subclass.

Implemented in PhElScatteringMatrix, PhScatteringMatrix, ElScatteringMatrix, and CoupledScatteringMatrix.

Here is the caller graph for this function:

◆ coupledToBandStructureIndices()

std::tuple< int, int > ScatteringMatrix::coupledToBandStructureIndices ( const int &  iBte1,
const int &  iBte2,
const Particle p1,
const Particle p2 
)
protected
Parameters
iBte1,iBte2the bte indices used to index the global matrix
p1,p2the particle types indicating the quadrant of this element
Returns
: a tuple containing the bandstructure relevant indices
Here is the call graph for this function:
Here is the caller graph for this function:

◆ degeneracyAveragingLinewidths()

void ScatteringMatrix::degeneracyAveragingLinewidths ( std::shared_ptr< VectorBTE linewidth)
protected

This is necessary since the coupling |V_3| is not averaged over different states, and hence introduces differences between degenerate states. Note: don't use this function when computing the scattering matrix, but only for computing lifetimes or the RTA approximation. If one wants to do something similar when computing the full scattering matrix (in memory) one should either average the coupling or somehow average rows and columns of the scattering matrix.

Parameters
linewidtha pointer (the one passed to builder()) containing the linewidths to be averaged.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ diagonal()

VectorBTE ScatteringMatrix::diagonal ( )

For the case of electrons, this is the linewidths – A_out = Linewidths For the case of phonons, this is A_out = linewidths * n(n+1)

Returns
diagonal: a VectorBTE containing the diagonal of the scattering matrix.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ diagonalize()

std::tuple< Eigen::VectorXd, ParallelMatrix< double > > ScatteringMatrix::diagonalize ( int  numEigenvalues = 0)
Parameters
numEigenvaluesif a number is supplied, calculate only the first few of these points
Returns
eigenvalues: a Eigen::VectorXd with the eigenvalues
eigenvectors: a Eigen::MatrixXd with the eigenvectors Eigenvectors are aligned on rows: eigenvectors(qpState,eigenIndex)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ getAllLocalStates()

std::vector< std::tuple< int, int > > ScatteringMatrix::getAllLocalStates ( )
Returns
: an iterator of local state index pairs
Here is the caller graph for this function:

◆ getExcludeIndices()

std::vector< int > ScatteringMatrix::getExcludeIndices ( BaseBandStructure bandStructure)
protected
Parameters
bandStructurebandstructure to compute indices for
Returns
excludeIndices: the irr indices to be excluded in ph calculations
Here is the call graph for this function:

◆ getIteratorWavevectorPairs()

std::vector< std::tuple< std::vector< int >, int > > ScatteringMatrix::getIteratorWavevectorPairs ( const bool &  rowMajor = false)
protected
Parameters
rowMajorset to true if the loop is in the form for iq1 { for iq2 {...}}. False for the opposite (default).
Returns
vector<tuple<iq1,iq2>>: a tuple of wavevector indices to loop over in the construction of the scattering matrix.

Implementation: note that ph and el scattering are implemented differently. In detail, ph is computed as (for iq2) {(for iq1)}. instead el is computed as (for ik1) {(for ik2)}. where index1 is computed over irreducible points and iq2 over reducible points. Therefore, we have to distinguish the two cases (they're inverted). Also, we distinguish the case of matrix in memory or not. For scattering matrix in memory, we parallelize over the matrix elements owned by an MPI process. Otherwise, we trivially parallelize over the outer loop on points.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getLinewidths() [1/2]

VectorBTE ScatteringMatrix::getLinewidths ( )

See general function of the same name for full notes

Returns
linewidths: a VectorBTE object storing the linewidths
Here is the caller graph for this function:

◆ getLinewidths() [2/2]

VectorBTE ScatteringMatrix::getLinewidths ( const VectorBTE anyInternalDiagonal)

Note that the definition of linewidths is slightly different between electrons and phonons. For phonons, linewidths satisfy the relation Gamma * Tau = hBar (in atomic units, Gamma * Tau = 1). This Tau is the same Tau that enters the Boltzmann equation, and Gamma/Tau are related to the scattering operator as A_{ii} = n_i(n_i+1) / tau_i = n_i(n_i+1) * Gamma_i

For electrons, we are using a modified definition A_{ii} = f_i(1-f_i) / tau_i = Gamma_i where Gamma_i is the imaginary part of the self-energy, and Tau is the transport relaxation time that enters the transport equations, and satisfy the relation Gamma_i * Tau_i = f_i * (1-f_i)

Regardless, this function just returns Gamma

Parameters
anyInteralDiagonal: vector bte or pointer to vector BTE
Returns
linewidths: a VectorBTE object storing the linewidths
Here is the call graph for this function:

◆ getSingleModeTimes() [1/2]

VectorBTE ScatteringMatrix::getSingleModeTimes ( )
Returns
tau: a VectorBTE object storing the relaxation times
Here is the caller graph for this function:

◆ getSingleModeTimes() [2/2]

VectorBTE ScatteringMatrix::getSingleModeTimes ( const VectorBTE anyInternalDiagonal)
Parameters
internalDiagonala VectorBTE object storing the linewidths (potentially symmetrization scaled)
Returns
tau: a VectorBTE object storing the relaxation times
Here is the call graph for this function:

◆ getSMatrixIndex() [1/2]

int ScatteringMatrix::getSMatrixIndex ( BteIndex bteIndex,
CartIndex cartIndex 
)

If no symmetries are used, the output is equal to the BteIndex.

Parameters
bteIndexBteIndex for a Bloch state entering the BTE
cartIndexCartIndex for a cartesian direction
Returns
sMatrixIndex: and index identifying the scattering matrix row/col.

Note: when symmetries are used, the scattering matrix has indices (i,j) where i,j = (BteIndex,CartIndex) combined together, where CartIndex is an index on cartesian directions, and BteIndex an index on the Bloch states entering the Boltzmann equation.

Here is the caller graph for this function:

◆ getSMatrixIndex() [2/2]

std::tuple< BteIndex, CartIndex > ScatteringMatrix::getSMatrixIndex ( const int &  iMat)

If no symmetries are used, the output is equal to the BteIndex and CartIndex is set to 0. It is suggested to skip this function if symmetries are NOT used.

Parameters
bteIndexBteIndex for a Bloch state entering the BTE
cartIndexCartIndex for a cartesian direction
Returns
sMatrixIndex: and index identifying the scattering matrix row/col.

Note: when symmetries are used, the scattering matrix has indices (i,j) where i,j = (BteIndex,CartIndex) combined together, where CartIndex is an index on cartesian directions, and BteIndex an index on the Bloch states entering the Boltzmann equation.

◆ getStateBandStructures()

std::tuple< BaseBandStructure *, BaseBandStructure * > ScatteringMatrix::getStateBandStructures ( const BteIndex iBte1,
const BteIndex iBte2 
)
protected
Parameters
iBte1,iBte2the bte indices used to index this state
Here is the caller graph for this function:

◆ operator()()

double & ScatteringMatrix::operator() ( const int &  row,
const int &  col 
)

Returns the stored value if the matrix element (row,col) is stored in memory by the MPI process, otherwise returns zero. Just calls this on the underlying PMatrix object

Here is the caller graph for this function:

◆ outputToHDF5()

void ScatteringMatrix::outputToHDF5 ( const std::string &  outFileName)
Parameters
outFileNamestring representing the name of the json file

◆ precomputeOccupations()

Eigen::MatrixXd ScatteringMatrix::precomputeOccupations ( BaseBandStructure bandStructure)
protected
Parameters
Bandstructurebandstructure of the particle species
Returns
MatrixXd occupationFactors: contains the occupations for all states
Here is the call graph for this function:
Here is the caller graph for this function:

◆ relaxonsToJSON()

void ScatteringMatrix::relaxonsToJSON ( const std::string &  fileName,
const Eigen::VectorXd &  eigenvalues 
)
Parameters
fileNamethe name of the file to write out to
eigenvaluesthe tau values from a relaxons solve
Here is the call graph for this function:
Here is the caller graph for this function:

◆ setLinewidths()

void ScatteringMatrix::setLinewidths ( VectorBTE linewidths)

See getLinewidths function for notes about linewidths.

Parameters
linewidthsthis is Gamma, without any population factors
Here is the call graph for this function:

◆ setup()

void ScatteringMatrix::setup ( )

It will setup variables of the scattering matrix, and compute at least the linewidths. If the user input ask to store the matrix in memory, the scattering matrix gets allocated and built here, through a call to a virtual member builder(), which is defined in subclasses.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ symmetrizeCoupling()

void ScatteringMatrix::symmetrizeCoupling ( Eigen::Tensor< double, 3 > &  coupling,
const Eigen::VectorXd &  energies1,
const Eigen::VectorXd &  energies2,
const Eigen::VectorXd &  energies3 
)
static

When there are degenerate energies, the freedom of choice of eigenvectors within the corresponding eigenspace should not affect the final coupling. We therefore average the coupling over the degenerate states.

Parameters
couplingCalculated coupling to be averaged.
energies1Energies to check for degeneracy in ib1.
energies2Energies to check for degeneracy in ib2.
energies3Energies to check for degeneracy in ib3.

Member Data Documentation

◆ shiftToCoupledIndices

std::function<std::tuple<long,long>long, long, const Particle&, const Particle &)> ScatteringMatrix::shiftToCoupledIndices
protected
Initial value:
= [](long iBte1, long iBte2, [[maybe_unused]] const Particle &p1, [[maybe_unused]] const Particle &p2){
return std::make_tuple(iBte1, iBte2); }
Determines whether we are dealing with phonons or electrons.
Definition: particle.h:17