1
0
mirror of https://github.com/paboyle/Grid.git synced 2025-06-12 20:27:06 +01:00

Two flavour HMC for Wilson/Wilson is conserving energy.

Still to check plaq and <e(-dH)>, but nevertheless this is
progress
This commit is contained in:
Peter Boyle
2015-07-29 17:53:39 +09:00
parent 4cc2ef84d3
commit 4fe110bd07
20 changed files with 259 additions and 76 deletions

View File

@ -95,18 +95,18 @@ namespace Grid{
////////////////////////////////////////////////////////////////////////
// Two flavour pseudofermion action for any dop
////////////////////////////////////////////////////////////////////////
template<class GaugeField,class MatrixField,class FermionField,class FermionOperator>
template<class GaugeField,class MatrixField,class FermionField>
class TwoFlavourPseudoFermionAction : public Action<GaugeField> {
private:
FermionOperator<FermionField,GaugeField> & FermOp;// the basic operator
OperatorFunction<FermionField> &DerivativeSolver;
OperatorFunction<FermionField> &ActionSolver;
GridBase *Grid;
GridBase &Grid;
FermionField Phi; // the pseudo fermion field for this trajectory
@ -114,10 +114,11 @@ namespace Grid{
/////////////////////////////////////////////////
// Pass in required objects.
/////////////////////////////////////////////////
TwoFlavourPseudoFermionAction(FermionOperator &Op,
OperatorFunction<FermionField> & DS,
OperatorFunction<FermionField> & AS
) : FermOp(Op), DerivativeSolver(DS), ActionSolver(AS) {
TwoFlavourPseudoFermionAction(FermionOperator<FermionField,GaugeField> &Op,
OperatorFunction<FermionField> & DS,
OperatorFunction<FermionField> & AS,
GridBase &_Grid
) : FermOp(Op), DerivativeSolver(DS), ActionSolver(AS), Phi(&_Grid), Grid(_Grid) {
};
//////////////////////////////////////////////////////////////////////////////////////
@ -125,9 +126,28 @@ namespace Grid{
//////////////////////////////////////////////////////////////////////////////////////
virtual void init(const GaugeField &U, GridParallelRNG& pRNG) {
// width? Must check
gaussian(Phi,pRNG);
// P(phi) = e^{- phi^dag (MdagM)^-1 phi}
// Phi = Mdag eta
// P(eta) = e^{- eta^dag eta}
//
// e^{x^2/2 sig^2} => sig^2 = 0.5.
//
// So eta should be of width sig = 1/sqrt(2).
// and must multiply by 0.707....
//
// Chroma has this scale factor: two_flavor_monomial_w.h
// IroIro: does not use this scale. It is absorbed by a change of vars
// in the Phi integral, and thus is only an irrelevant prefactor for the partition function.
//
RealD scale = std::sqrt(0.5);
FermionField eta(&Grid);
gaussian(pRNG,eta);
FermOp.Mdag(eta,Phi);
Phi=Phi*scale;
};
//////////////////////////////////////////////////////
@ -135,38 +155,49 @@ namespace Grid{
//////////////////////////////////////////////////////
virtual RealD S(const GaugeField &U) {
FermionField X(Grid);
FermionField Y(Grid);
MdagMLinearOperator<FermionOperator<FermionField,GaugeField>,FermionField> MdagMOp(FermOp);
FermOp.ImportGauge(U);
ActionSolver(MdagMop,Phi,X);
FermionField X(&Grid);
FermionField Y(&Grid);
MdagMLinearOperator<FermionOperator<FermionField,GaugeField> ,FermionField> MdagMOp(FermOp);
X=zero;
ActionSolver(MdagMOp,Phi,X);
MdagMOp.Op(X,Y);
RealD action = norm2(Y);
std::cout << GridLogMessage << "Pseudofermion action "<<action<<std::endl;
return action;
};
//////////////////////////////////////////////////////
// dS/du = - phi^dag (Mdag M)^-1 [ Mdag dM + dMdag M ] (Mdag M)^-1 phi
// = - phi^dag M^-1 dM (MdagM)^-1 phi - phi^dag (MdagM)^-1 dMdag dM (Mdag)^-1 phi
//
// = - Ydag dM X - Xdag dMdag Y
//
//////////////////////////////////////////////////////
virtual void deriv(const GaugeField &U,GaugeField & dSdU) {
FermionField X(Grid);
FermionField Y(Grid);
GaugeField tmp(Grid);
FermOp.ImportGauge(U);
MdagMLinearOperator<FermionOperator<FermionField,GaugeField>,FermionField> MdagMOp(FermOp);
FermionField X(&Grid);
FermionField Y(&Grid);
GaugeField tmp(&Grid);
DerivativeSolver(MdagMop,Phi,X);
MdagMLinearOperator<FermionOperator<FermionField,GaugeField> ,FermionField> MdagMOp(FermOp);
X=zero;
DerivativeSolver(MdagMOp,Phi,X);
MdagMOp.Op(X,Y);
// Our conventions really make this UdSdU; We do not differentiate wrt Udag here.
// So must take dSdU - adj(dSdU) and left multiply by mom to get dS/dt.
FermOp.MDeriv(tmp , Y, X,DaggerNo ); dSdU=tmp;
FermOp.MDeriv(tmp , X, Y,DaggerYes); dSdU=-UdSdU-tmp;
FermOp.MDeriv(tmp , X, Y,DaggerYes); dSdU=dSdU+tmp;
dSdU = Ta(dSdU);
};