81 lines
2.9 KiB
C++
81 lines
2.9 KiB
C++
/**********************************************************
|
|
|
|
This software is part of J.-S. Caux's ABACUS library.
|
|
|
|
Copyright (c) J.-S. Caux.
|
|
|
|
-----------------------------------------------------------
|
|
|
|
File: src/ODSLF/ODSLF_Matrix_Element_Contrib.cc
|
|
|
|
Purpose: handles the generic call for a matrix element.
|
|
|
|
***********************************************************/
|
|
|
|
#include "ABACUS.h"
|
|
|
|
using namespace std;
|
|
using namespace ABACUS;
|
|
|
|
namespace ABACUS {
|
|
|
|
DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, ODSLF_XXZ_Bethe_State& LeftState,
|
|
ODSLF_XXZ_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile)
|
|
{
|
|
// This function prints the matrix element information to the fstream,
|
|
// and returns a weighed `data_value' to be multiplied by sumrule_factor,
|
|
// to determine if scanning along this thread should be continued.
|
|
|
|
// Identify which matrix is needed from the number of particles in Left and Right states:
|
|
|
|
bool fixed_iK = (iKmin == iKmax);
|
|
|
|
DP ME = 0.0;
|
|
if (whichDSF == 'Z')
|
|
ME = LeftState.E - RefState.E;
|
|
else if (whichDSF == 'm')
|
|
ME = exp(real(ln_Smin_ME (RefState, LeftState)));
|
|
else if (whichDSF == 'z') {
|
|
if (LeftState.base_id == RefState.base_id && LeftState.type_id == RefState.type_id && LeftState.id == RefState.id)
|
|
ME = sqrt(RefState.chain.Nsites * 0.25) * (1.0 - 2.0*RefState.base.Mdown/RefState.chain.Nsites);
|
|
else ME = exp(real(ln_Sz_ME (RefState, LeftState)));
|
|
}
|
|
else if (whichDSF == 'p')
|
|
ME = exp(real(ln_Smin_ME (LeftState, RefState)));
|
|
else ABACUSerror("Wrong whichDSF in Compute_Matrix_Element_Contrib.");
|
|
|
|
if (is_nan(ME)) ME = 0.0;
|
|
|
|
// Do the momentum business:
|
|
int iKout = LeftState.iK - RefState.iK;
|
|
while(iKout < 0) iKout += RefState.chain.Nsites;
|
|
while(iKout >= RefState.chain.Nsites) iKout -= RefState.chain.Nsites;
|
|
|
|
DAT_outfile << setprecision(16);
|
|
// Print information to fstream:
|
|
if (iKout >= iKmin && iKout <= iKmax) {
|
|
if (whichDSF == 'Z') {
|
|
DAT_outfile << endl << LeftState.E - RefState.E - (LeftState.base.Mdown - RefState.base.Mdown) * Chem_Pot << "\t"
|
|
<< iKout << "\t"
|
|
<< LeftState.base_id << "\t" << LeftState.type_id << "\t" << LeftState.id;
|
|
}
|
|
else {
|
|
DAT_outfile << endl << LeftState.E - RefState.E - (LeftState.base.Mdown - RefState.base.Mdown) * Chem_Pot << "\t"
|
|
<< iKout << "\t"
|
|
<< ME << "\t"
|
|
<< LeftState.base_id << "\t" << LeftState.type_id << "\t" << LeftState.id;
|
|
}
|
|
} // if iKmin <= iKout <= iKmax
|
|
|
|
// Calculate and return the data_value:
|
|
DP data_value = ME * ME;
|
|
if (whichDSF == 'Z') // use 1/(1 + omega)
|
|
data_value = 1.0/(1.0 + LeftState.E - RefState.E - (LeftState.base.Mdown - RefState.base.Mdown) * Chem_Pot);
|
|
else if (fixed_iK) // data value is MEsq * omega:
|
|
data_value = ME * ME * (LeftState.E - RefState.E - (LeftState.base.Mdown - RefState.base.Mdown) * Chem_Pot);
|
|
|
|
return(data_value);
|
|
}
|
|
|
|
} // namespace ABACUS
|