/********************************************************** 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