ABACUS/src/ODSLF/ODSLF_Matrix_Element_Contri...

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