mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-11-04 05:54:32 +00:00 
			
		
		
		
	Check-in of working Mobius EOFA class and tests
This commit is contained in:
		
							
								
								
									
										241
									
								
								tests/core/Test_mobius_eofa_even_odd.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										241
									
								
								tests/core/Test_mobius_eofa_even_odd.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,241 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid
 | 
			
		||||
 | 
			
		||||
Source file: ./tests/core/Test_dwf_eofa_even_odd.cc
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2017
 | 
			
		||||
 | 
			
		||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
Author: David Murphy <dmurphy@phys.columbia.edu>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#include <Grid/Grid.h>
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
using namespace Grid;
 | 
			
		||||
using namespace Grid::QCD;
 | 
			
		||||
 | 
			
		||||
template<class d>
 | 
			
		||||
struct scal {
 | 
			
		||||
    d internal;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Gamma::Algebra Gmu [] = {
 | 
			
		||||
    Gamma::Algebra::GammaX,
 | 
			
		||||
    Gamma::Algebra::GammaY,
 | 
			
		||||
    Gamma::Algebra::GammaZ,
 | 
			
		||||
    Gamma::Algebra::GammaT
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int main (int argc, char ** argv)
 | 
			
		||||
{
 | 
			
		||||
    Grid_init(&argc, &argv);
 | 
			
		||||
 | 
			
		||||
    int threads = GridThread::GetThreads();
 | 
			
		||||
    std::cout << GridLogMessage << "Grid is setup to use " << threads << " threads" << std::endl;
 | 
			
		||||
 | 
			
		||||
    const int Ls = 8;
 | 
			
		||||
    // GridCartesian*         UGrid   = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
 | 
			
		||||
    GridCartesian*         UGrid   = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
 | 
			
		||||
    GridCartesian*         FGrid   = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
 | 
			
		||||
    GridRedBlackCartesian* UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
 | 
			
		||||
    GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
 | 
			
		||||
 | 
			
		||||
    std::vector<int> seeds4({1,2,3,4});
 | 
			
		||||
    std::vector<int> seeds5({5,6,7,8});
 | 
			
		||||
 | 
			
		||||
    GridParallelRNG RNG4(UGrid); RNG4.SeedFixedIntegers(seeds4);
 | 
			
		||||
    GridParallelRNG RNG5(FGrid); RNG5.SeedFixedIntegers(seeds5);
 | 
			
		||||
 | 
			
		||||
    LatticeFermion    src   (FGrid); random(RNG5, src);
 | 
			
		||||
    LatticeFermion    phi   (FGrid); random(RNG5, phi);
 | 
			
		||||
    LatticeFermion    chi   (FGrid); random(RNG5, chi);
 | 
			
		||||
    LatticeFermion    result(FGrid); result = zero;
 | 
			
		||||
    LatticeFermion    ref   (FGrid); ref = zero;
 | 
			
		||||
    LatticeFermion    tmp   (FGrid); tmp = zero;
 | 
			
		||||
    LatticeFermion    err   (FGrid); err = zero;
 | 
			
		||||
    LatticeGaugeField Umu   (UGrid); SU3::HotConfiguration(RNG4, Umu);
 | 
			
		||||
    std::vector<LatticeColourMatrix> U(4,UGrid);
 | 
			
		||||
 | 
			
		||||
    // Only one non-zero (y)
 | 
			
		||||
    Umu = zero;
 | 
			
		||||
    for(int nn=0; nn<Nd; nn++){
 | 
			
		||||
        random(RNG4, U[nn]);
 | 
			
		||||
        if(nn>0){ U[nn] = zero; }
 | 
			
		||||
        PokeIndex<LorentzIndex>(Umu, U[nn], nn);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    RealD b     = 2.5;
 | 
			
		||||
    RealD c     = 1.5;
 | 
			
		||||
    RealD mq1   = 0.1;
 | 
			
		||||
    RealD mq2   = 0.5;
 | 
			
		||||
    RealD mq3   = 1.0;
 | 
			
		||||
    RealD shift = 0.1234;
 | 
			
		||||
    RealD M5    = 1.8;
 | 
			
		||||
    int   pm    = 1;
 | 
			
		||||
    MobiusEOFAFermionR Ddwf(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mq1, mq2, mq3, shift, pm, M5, b, c);
 | 
			
		||||
 | 
			
		||||
    LatticeFermion src_e (FrbGrid);
 | 
			
		||||
    LatticeFermion src_o (FrbGrid);
 | 
			
		||||
    LatticeFermion r_e   (FrbGrid);
 | 
			
		||||
    LatticeFermion r_o   (FrbGrid);
 | 
			
		||||
    LatticeFermion r_eo  (FGrid);
 | 
			
		||||
    LatticeFermion r_eeoo(FGrid);
 | 
			
		||||
 | 
			
		||||
    std::cout << GridLogMessage << "==========================================================" << std::endl;
 | 
			
		||||
    std::cout << GridLogMessage << "= Testing that Meo + Moe + Moo + Mee = Munprec " << std::endl;
 | 
			
		||||
    std::cout << GridLogMessage << "==========================================================" << std::endl;
 | 
			
		||||
 | 
			
		||||
    pickCheckerboard(Even, src_e, src);
 | 
			
		||||
    pickCheckerboard(Odd,  src_o, src);
 | 
			
		||||
 | 
			
		||||
    Ddwf.Meooe(src_e, r_o); std::cout << GridLogMessage << "Applied Meo" << std::endl;
 | 
			
		||||
    Ddwf.Meooe(src_o, r_e); std::cout << GridLogMessage << "Applied Moe" << std::endl;
 | 
			
		||||
    setCheckerboard(r_eo, r_o);
 | 
			
		||||
    setCheckerboard(r_eo, r_e);
 | 
			
		||||
 | 
			
		||||
    Ddwf.Mooee(src_e, r_e); std::cout << GridLogMessage << "Applied Mee" << std::endl;
 | 
			
		||||
    Ddwf.Mooee(src_o, r_o); std::cout << GridLogMessage << "Applied Moo" << std::endl;
 | 
			
		||||
    setCheckerboard(r_eeoo, r_e);
 | 
			
		||||
    setCheckerboard(r_eeoo, r_o);
 | 
			
		||||
 | 
			
		||||
    r_eo = r_eo + r_eeoo;
 | 
			
		||||
    Ddwf.M(src, ref);
 | 
			
		||||
 | 
			
		||||
    // std::cout << GridLogMessage << r_eo << std::endl;
 | 
			
		||||
    // std::cout << GridLogMessage << ref  << std::endl;
 | 
			
		||||
 | 
			
		||||
    err = ref - r_eo;
 | 
			
		||||
    std::cout << GridLogMessage << "EO norm diff   " << norm2(err) << " " << norm2(ref) << " " << norm2(r_eo) << std::endl;
 | 
			
		||||
 | 
			
		||||
    LatticeComplex cerr(FGrid);
 | 
			
		||||
    cerr = localInnerProduct(err,err);
 | 
			
		||||
    // std::cout << GridLogMessage << cerr << std::endl;
 | 
			
		||||
 | 
			
		||||
    std::cout << GridLogMessage << "==============================================================" << std::endl;
 | 
			
		||||
    std::cout << GridLogMessage << "= Test Ddagger is the dagger of D by requiring                " << std::endl;
 | 
			
		||||
    std::cout << GridLogMessage << "=  < phi | Deo | chi > * = < chi | Deo^dag| phi>  " << std::endl;
 | 
			
		||||
    std::cout << GridLogMessage << "==============================================================" << std::endl;
 | 
			
		||||
 | 
			
		||||
    LatticeFermion chi_e (FrbGrid);
 | 
			
		||||
    LatticeFermion chi_o (FrbGrid);
 | 
			
		||||
 | 
			
		||||
    LatticeFermion dchi_e(FrbGrid);
 | 
			
		||||
    LatticeFermion dchi_o(FrbGrid);
 | 
			
		||||
 | 
			
		||||
    LatticeFermion phi_e (FrbGrid);
 | 
			
		||||
    LatticeFermion phi_o (FrbGrid);
 | 
			
		||||
 | 
			
		||||
    LatticeFermion dphi_e(FrbGrid);
 | 
			
		||||
    LatticeFermion dphi_o(FrbGrid);
 | 
			
		||||
 | 
			
		||||
    pickCheckerboard(Even, chi_e, chi);
 | 
			
		||||
    pickCheckerboard(Odd , chi_o, chi);
 | 
			
		||||
    pickCheckerboard(Even, phi_e, phi);
 | 
			
		||||
    pickCheckerboard(Odd , phi_o, phi);
 | 
			
		||||
 | 
			
		||||
    Ddwf.Meooe   (chi_e, dchi_o);
 | 
			
		||||
    Ddwf.Meooe   (chi_o, dchi_e);
 | 
			
		||||
    Ddwf.MeooeDag(phi_e, dphi_o);
 | 
			
		||||
    Ddwf.MeooeDag(phi_o, dphi_e);
 | 
			
		||||
 | 
			
		||||
    ComplexD pDce = innerProduct(phi_e, dchi_e);
 | 
			
		||||
    ComplexD pDco = innerProduct(phi_o, dchi_o);
 | 
			
		||||
    ComplexD cDpe = innerProduct(chi_e, dphi_e);
 | 
			
		||||
    ComplexD cDpo = innerProduct(chi_o, dphi_o);
 | 
			
		||||
 | 
			
		||||
    std::cout << GridLogMessage << "e " << pDce << " " << cDpe << std::endl;
 | 
			
		||||
    std::cout << GridLogMessage << "o " << pDco << " " << cDpo << std::endl;
 | 
			
		||||
 | 
			
		||||
    std::cout << GridLogMessage << "pDce - conj(cDpo) " << pDce-conj(cDpo) << std::endl;
 | 
			
		||||
    std::cout << GridLogMessage << "pDco - conj(cDpe) " << pDco-conj(cDpe) << std::endl;
 | 
			
		||||
 | 
			
		||||
    std::cout << GridLogMessage << "==============================================================" << std::endl;
 | 
			
		||||
    std::cout << GridLogMessage << "= Test MeeInv Mee = 1                                         " << std::endl;
 | 
			
		||||
    std::cout << GridLogMessage << "==============================================================" << std::endl;
 | 
			
		||||
 | 
			
		||||
    pickCheckerboard(Even, chi_e, chi);
 | 
			
		||||
    pickCheckerboard(Odd , chi_o, chi);
 | 
			
		||||
 | 
			
		||||
    Ddwf.Mooee   (chi_e, src_e);
 | 
			
		||||
    Ddwf.MooeeInv(src_e, phi_e);
 | 
			
		||||
 | 
			
		||||
    Ddwf.Mooee   (chi_o, src_o);
 | 
			
		||||
    Ddwf.MooeeInv(src_o, phi_o);
 | 
			
		||||
 | 
			
		||||
    setCheckerboard(phi, phi_e);
 | 
			
		||||
    setCheckerboard(phi, phi_o);
 | 
			
		||||
 | 
			
		||||
    err = phi - chi;
 | 
			
		||||
    std::cout << GridLogMessage << "norm diff   " << norm2(err) << std::endl;
 | 
			
		||||
 | 
			
		||||
    std::cout << GridLogMessage << "==============================================================" << std::endl;
 | 
			
		||||
    std::cout << GridLogMessage << "= Test MeeInvDag MeeDag = 1                                   " << std::endl;
 | 
			
		||||
    std::cout << GridLogMessage << "==============================================================" << std::endl;
 | 
			
		||||
 | 
			
		||||
    pickCheckerboard(Even, chi_e, chi);
 | 
			
		||||
    pickCheckerboard(Odd , chi_o, chi);
 | 
			
		||||
 | 
			
		||||
    Ddwf.MooeeDag   (chi_e, src_e);
 | 
			
		||||
    Ddwf.MooeeInvDag(src_e, phi_e);
 | 
			
		||||
 | 
			
		||||
    Ddwf.MooeeDag   (chi_o, src_o);
 | 
			
		||||
    Ddwf.MooeeInvDag(src_o, phi_o);
 | 
			
		||||
 | 
			
		||||
    setCheckerboard(phi, phi_e);
 | 
			
		||||
    setCheckerboard(phi, phi_o);
 | 
			
		||||
 | 
			
		||||
    err = phi - chi;
 | 
			
		||||
    std::cout << GridLogMessage << "norm diff   " << norm2(err) << std::endl;
 | 
			
		||||
 | 
			
		||||
    std::cout << GridLogMessage << "==============================================================" << std::endl;
 | 
			
		||||
    std::cout << GridLogMessage << "= Test MpcDagMpc is Hermitian              " << std::endl;
 | 
			
		||||
    std::cout << GridLogMessage << "==============================================================" << std::endl;
 | 
			
		||||
 | 
			
		||||
    random(RNG5, phi);
 | 
			
		||||
    random(RNG5, chi);
 | 
			
		||||
    pickCheckerboard(Even, chi_e, chi);
 | 
			
		||||
    pickCheckerboard(Odd , chi_o, chi);
 | 
			
		||||
    pickCheckerboard(Even, phi_e, phi);
 | 
			
		||||
    pickCheckerboard(Odd , phi_o, phi);
 | 
			
		||||
    RealD t1,t2;
 | 
			
		||||
 | 
			
		||||
    SchurDiagMooeeOperator<MobiusEOFAFermionR,LatticeFermion> HermOpEO(Ddwf);
 | 
			
		||||
    HermOpEO.MpcDagMpc(chi_e, dchi_e, t1, t2);
 | 
			
		||||
    HermOpEO.MpcDagMpc(chi_o, dchi_o, t1, t2);
 | 
			
		||||
 | 
			
		||||
    HermOpEO.MpcDagMpc(phi_e, dphi_e, t1, t2);
 | 
			
		||||
    HermOpEO.MpcDagMpc(phi_o, dphi_o, t1, t2);
 | 
			
		||||
 | 
			
		||||
    pDce = innerProduct(phi_e, dchi_e);
 | 
			
		||||
    pDco = innerProduct(phi_o, dchi_o);
 | 
			
		||||
    cDpe = innerProduct(chi_e, dphi_e);
 | 
			
		||||
    cDpo = innerProduct(chi_o, dphi_o);
 | 
			
		||||
 | 
			
		||||
    std::cout << GridLogMessage << "e " << pDce << " " << cDpe << std::endl;
 | 
			
		||||
    std::cout << GridLogMessage << "o " << pDco << " " << cDpo << std::endl;
 | 
			
		||||
 | 
			
		||||
    std::cout << GridLogMessage << "pDce - conj(cDpo) " << pDco-conj(cDpo) << std::endl;
 | 
			
		||||
    std::cout << GridLogMessage << "pDco - conj(cDpe) " << pDce-conj(cDpe) << std::endl;
 | 
			
		||||
 | 
			
		||||
    Grid_finalize();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										104
									
								
								tests/debug/Test_heatbath_mobius_eofa.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								tests/debug/Test_heatbath_mobius_eofa.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,104 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid
 | 
			
		||||
 | 
			
		||||
Source file: ./tests/debug/Test_heatbath_dwf_eofa.cc
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2017
 | 
			
		||||
 | 
			
		||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
Author: David Murphy <dmurphy@phys.columbia.edu>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// This program sets up the initial pseudofermion field |Phi> = Meofa^{-1/2}*|eta>, and
 | 
			
		||||
// then uses this Phi to compute the action <Phi|Meofa|Phi>.
 | 
			
		||||
// If all is working, one should find that <eta|eta> = <Phi|Meofa|Phi>.
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
#include <Grid/Grid.h>
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
using namespace Grid;
 | 
			
		||||
using namespace Grid::QCD;
 | 
			
		||||
 | 
			
		||||
// Parameters for test
 | 
			
		||||
const std::vector<int> grid_dim = { 8, 8, 8, 8 };
 | 
			
		||||
const int              Ls       = 8;
 | 
			
		||||
const int              Npoles   = 12;
 | 
			
		||||
const RealD            b        = 2.5;
 | 
			
		||||
const RealD            c        = 1.5;
 | 
			
		||||
const RealD            mf       = 0.01;
 | 
			
		||||
const RealD            mpv      = 1.0;
 | 
			
		||||
const RealD            M5       = 1.8;
 | 
			
		||||
 | 
			
		||||
int main(int argc, char** argv)
 | 
			
		||||
{
 | 
			
		||||
  Grid_init(&argc, &argv);
 | 
			
		||||
 | 
			
		||||
  int threads = GridThread::GetThreads();
 | 
			
		||||
  std::cout << GridLogMessage << "Grid is set up to use " << threads << " threads" << std::endl;
 | 
			
		||||
 | 
			
		||||
  // Initialize spacetime grid
 | 
			
		||||
  std::cout << GridLogMessage << "Lattice dimensions: " << grid_dim << "  Ls: " << Ls << std::endl;
 | 
			
		||||
  GridCartesian*         UGrid   = SpaceTimeGrid::makeFourDimGrid(grid_dim,
 | 
			
		||||
                                    GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
 | 
			
		||||
  GridRedBlackCartesian* UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
 | 
			
		||||
  GridCartesian*         FGrid   = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
 | 
			
		||||
  GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
 | 
			
		||||
 | 
			
		||||
  // Set up RNGs
 | 
			
		||||
  std::vector<int> seeds4({1, 2, 3, 4});
 | 
			
		||||
  std::vector<int> seeds5({5, 6, 7, 8});
 | 
			
		||||
  GridParallelRNG RNG5(FGrid);
 | 
			
		||||
  RNG5.SeedFixedIntegers(seeds5);
 | 
			
		||||
  GridParallelRNG RNG4(UGrid);
 | 
			
		||||
  RNG4.SeedFixedIntegers(seeds4);
 | 
			
		||||
 | 
			
		||||
  // Random gauge field
 | 
			
		||||
  LatticeGaugeField Umu(UGrid);
 | 
			
		||||
  SU3::HotConfiguration(RNG4, Umu);
 | 
			
		||||
 | 
			
		||||
  MobiusEOFAFermionR Lop(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf,  mf, mpv,  0.0, -1, M5, b, c);
 | 
			
		||||
  MobiusEOFAFermionR Rop(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mpv, mf, mpv, -1.0,  1, M5, b, c);
 | 
			
		||||
 | 
			
		||||
  // Construct the action and test the heatbath (zero initial guess)
 | 
			
		||||
  {
 | 
			
		||||
    OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, Npoles);
 | 
			
		||||
    ConjugateGradient<LatticeFermion> CG(1.0e-12, 5000);
 | 
			
		||||
    ExactOneFlavourRatioPseudoFermionAction<WilsonImplR> Meofa(Lop, Rop, CG, Params, false);
 | 
			
		||||
 | 
			
		||||
    Meofa.refresh(Umu, RNG5);
 | 
			
		||||
    printf("<Phi|Meofa|Phi> = %1.15e\n", Meofa.S(Umu));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Construct the action and test the heatbath (forecasted initial guesses)
 | 
			
		||||
  {
 | 
			
		||||
    OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, Npoles);
 | 
			
		||||
    ConjugateGradient<LatticeFermion> CG(1.0e-12, 5000);
 | 
			
		||||
    ExactOneFlavourRatioPseudoFermionAction<WilsonImplR> Meofa(Lop, Rop, CG, Params, true);
 | 
			
		||||
 | 
			
		||||
    Meofa.refresh(Umu, RNG5);
 | 
			
		||||
    printf("<Phi|Meofa|Phi> = %1.15e\n", Meofa.S(Umu));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										109
									
								
								tests/debug/Test_heatbath_mobius_eofa_gparity.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								tests/debug/Test_heatbath_mobius_eofa_gparity.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,109 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid
 | 
			
		||||
 | 
			
		||||
Source file: ./tests/debug/Test_heatbath_dwf_eofa.cc
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2017
 | 
			
		||||
 | 
			
		||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
Author: David Murphy <dmurphy@phys.columbia.edu>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// This program sets up the initial pseudofermion field |Phi> = Meofa^{-1/2}*|eta>, and
 | 
			
		||||
// then uses this Phi to compute the action <Phi|Meofa|Phi>.
 | 
			
		||||
// If all is working, one should find that <eta|eta> = <Phi|Meofa|Phi>.
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
#include <Grid/Grid.h>
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
using namespace Grid;
 | 
			
		||||
using namespace Grid::QCD;
 | 
			
		||||
 | 
			
		||||
typedef GparityWilsonImplR FermionImplPolicy;
 | 
			
		||||
typedef GparityMobiusEOFAFermionR FermionAction;
 | 
			
		||||
typedef typename FermionAction::FermionField FermionField;
 | 
			
		||||
 | 
			
		||||
// Parameters for test
 | 
			
		||||
const std::vector<int> grid_dim = { 8, 8, 8, 8 };
 | 
			
		||||
const int              Ls       = 8;
 | 
			
		||||
const int              Npoles   = 12;
 | 
			
		||||
const RealD            b        = 2.5;
 | 
			
		||||
const RealD            c        = 1.5;
 | 
			
		||||
const RealD            mf       = 0.01;
 | 
			
		||||
const RealD            mpv      = 1.0;
 | 
			
		||||
const RealD            M5       = 1.8;
 | 
			
		||||
 | 
			
		||||
int main(int argc, char** argv)
 | 
			
		||||
{
 | 
			
		||||
  Grid_init(&argc, &argv);
 | 
			
		||||
 | 
			
		||||
  int threads = GridThread::GetThreads();
 | 
			
		||||
  std::cout << GridLogMessage << "Grid is set up to use " << threads << " threads" << std::endl;
 | 
			
		||||
 | 
			
		||||
  // Initialize spacetime grid
 | 
			
		||||
  std::cout << GridLogMessage << "Lattice dimensions: " << grid_dim << "  Ls: " << Ls << std::endl;
 | 
			
		||||
  GridCartesian*         UGrid   = SpaceTimeGrid::makeFourDimGrid(grid_dim,
 | 
			
		||||
                                    GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
 | 
			
		||||
  GridRedBlackCartesian* UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
 | 
			
		||||
  GridCartesian*         FGrid   = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
 | 
			
		||||
  GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
 | 
			
		||||
 | 
			
		||||
  // Set up RNGs
 | 
			
		||||
  std::vector<int> seeds4({1, 2, 3, 4});
 | 
			
		||||
  std::vector<int> seeds5({5, 6, 7, 8});
 | 
			
		||||
  GridParallelRNG RNG5(FGrid);
 | 
			
		||||
  RNG5.SeedFixedIntegers(seeds5);
 | 
			
		||||
  GridParallelRNG RNG4(UGrid);
 | 
			
		||||
  RNG4.SeedFixedIntegers(seeds4);
 | 
			
		||||
 | 
			
		||||
  // Random gauge field
 | 
			
		||||
  LatticeGaugeField Umu(UGrid);
 | 
			
		||||
  SU3::HotConfiguration(RNG4, Umu);
 | 
			
		||||
 | 
			
		||||
  FermionAction::ImplParams params;
 | 
			
		||||
  FermionAction Lop(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf,  mf, mpv,  0.0, -1, M5, b, c, params);
 | 
			
		||||
  FermionAction Rop(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mpv, mf, mpv, -1.0,  1, M5, b, c, params);
 | 
			
		||||
 | 
			
		||||
  // Construct the action and test the heatbath (zero initial guess)
 | 
			
		||||
  {
 | 
			
		||||
    OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, Npoles);
 | 
			
		||||
    ConjugateGradient<FermionField> CG(1.0e-12, 5000);
 | 
			
		||||
    ExactOneFlavourRatioPseudoFermionAction<FermionImplPolicy> Meofa(Lop, Rop, CG, Params, false);
 | 
			
		||||
 | 
			
		||||
    Meofa.refresh(Umu, RNG5);
 | 
			
		||||
    printf("<Phi|Meofa|Phi> = %1.15e\n", Meofa.S(Umu));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Construct the action and test the heatbath (forecasted initial guesses)
 | 
			
		||||
  {
 | 
			
		||||
    OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, Npoles);
 | 
			
		||||
    ConjugateGradient<FermionField> CG(1.0e-12, 5000);
 | 
			
		||||
    ExactOneFlavourRatioPseudoFermionAction<FermionImplPolicy> Meofa(Lop, Rop, CG, Params, true);
 | 
			
		||||
 | 
			
		||||
    Meofa.refresh(Umu, RNG5);
 | 
			
		||||
    printf("<Phi|Meofa|Phi> = %1.15e\n", Meofa.S(Umu));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid
 | 
			
		||||
 | 
			
		||||
Source file: ./tests/debug/Test_reweight_dwf_eofa.cc
 | 
			
		||||
Source file: ./tests/debug/Test_reweight_dwf_eofa_gparity.cc
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2017
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										215
									
								
								tests/debug/Test_reweight_mobius_eofa.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										215
									
								
								tests/debug/Test_reweight_mobius_eofa.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,215 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid
 | 
			
		||||
 | 
			
		||||
Source file: ./tests/debug/Test_reweight_dwf_eofa.cc
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2017
 | 
			
		||||
 | 
			
		||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
Author: David Murphy <dmurphy@phys.columbia.edu>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
#include <Grid/Grid.h>
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
using namespace Grid;
 | 
			
		||||
using namespace Grid::QCD;
 | 
			
		||||
 | 
			
		||||
// parameters for test
 | 
			
		||||
const std::vector<int> grid_dim = { 8, 8, 8, 8 };
 | 
			
		||||
const int Ls = 8;
 | 
			
		||||
const int Nhits = 10;
 | 
			
		||||
const int max_iter = 5000;
 | 
			
		||||
const RealD b  = 2.5;
 | 
			
		||||
const RealD c  = 1.5;
 | 
			
		||||
const RealD mf = 0.1;
 | 
			
		||||
const RealD mb = 0.11;
 | 
			
		||||
const RealD M5 = 1.8;
 | 
			
		||||
const RealD stop_tol = 1.0e-12;
 | 
			
		||||
 | 
			
		||||
RealD mean(const std::vector<RealD>& data)
 | 
			
		||||
{
 | 
			
		||||
    int N = data.size();
 | 
			
		||||
    RealD mean(0.0);
 | 
			
		||||
    for(int i=0; i<N; ++i){ mean += data[i]; }
 | 
			
		||||
    return mean/RealD(N);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RealD jack_mean(const std::vector<RealD>& data, int sample)
 | 
			
		||||
{
 | 
			
		||||
    int N = data.size();
 | 
			
		||||
    RealD mean(0.0);
 | 
			
		||||
    for(int i=0; i<N; ++i){ if(i != sample){ mean += data[i]; } }
 | 
			
		||||
    return mean/RealD(N-1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RealD jack_std(const std::vector<RealD>& jacks, RealD mean)
 | 
			
		||||
{
 | 
			
		||||
    int N = jacks.size();
 | 
			
		||||
    RealD std(0.0);
 | 
			
		||||
    for(int i=0; i<N; ++i){ std += std::pow(jacks[i]-mean, 2.0); }
 | 
			
		||||
    return std::sqrt(RealD(N-1)/RealD(N)*std);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<RealD> jack_stats(const std::vector<RealD>& data)
 | 
			
		||||
{
 | 
			
		||||
    int N = data.size();
 | 
			
		||||
    std::vector<RealD> jack_samples(N);
 | 
			
		||||
    std::vector<RealD> jack_stats(2);
 | 
			
		||||
 | 
			
		||||
    jack_stats[0] = mean(data);
 | 
			
		||||
    for(int i=0; i<N; i++){ jack_samples[i] = jack_mean(data,i); }
 | 
			
		||||
    jack_stats[1] = jack_std(jack_samples, jack_stats[0]);
 | 
			
		||||
    return jack_stats;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
  Grid_init(&argc, &argv);
 | 
			
		||||
 | 
			
		||||
  // Initialize spacetime grid
 | 
			
		||||
  std::cout << GridLogMessage << "Lattice dimensions: "
 | 
			
		||||
    << grid_dim << "   Ls: " << Ls << std::endl;
 | 
			
		||||
  GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid(grid_dim,
 | 
			
		||||
      GridDefaultSimd(Nd, vComplex::Nsimd()), GridDefaultMpi());
 | 
			
		||||
  GridRedBlackCartesian* UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
 | 
			
		||||
  GridCartesian* FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
 | 
			
		||||
  GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
 | 
			
		||||
 | 
			
		||||
  // Set up RNGs
 | 
			
		||||
  std::vector<int> seeds4({1, 2, 3, 4});
 | 
			
		||||
  std::vector<int> seeds5({5, 6, 7, 8});
 | 
			
		||||
  GridParallelRNG RNG5(FGrid);
 | 
			
		||||
  RNG5.SeedFixedIntegers(seeds5);
 | 
			
		||||
  GridParallelRNG RNG4(UGrid);
 | 
			
		||||
  RNG4.SeedFixedIntegers(seeds4);
 | 
			
		||||
 | 
			
		||||
  // Random gauge field
 | 
			
		||||
  LatticeGaugeField Umu(UGrid);
 | 
			
		||||
  SU3::HotConfiguration(RNG4, Umu);
 | 
			
		||||
 | 
			
		||||
  // Initialize RHMC fermion operators
 | 
			
		||||
  MobiusFermionR Ddwf_f(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, M5, b, c);
 | 
			
		||||
  MobiusFermionR Ddwf_b(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, M5, b, c);
 | 
			
		||||
  SchurDiagMooeeOperator<MobiusFermionR, LatticeFermion> MdagM(Ddwf_f);
 | 
			
		||||
  SchurDiagMooeeOperator<MobiusFermionR, LatticeFermion> VdagV(Ddwf_b);
 | 
			
		||||
 | 
			
		||||
  // Degree 12 rational approximations to x^(1/4) and x^(-1/4)
 | 
			
		||||
  double     lo = 0.0001;
 | 
			
		||||
  double     hi = 95.0;
 | 
			
		||||
  int precision = 64;
 | 
			
		||||
  int    degree = 12;
 | 
			
		||||
  AlgRemez remez(lo, hi, precision);
 | 
			
		||||
  std::cout << GridLogMessage << "Generating degree " << degree << " for x^(1/4)" << std::endl;
 | 
			
		||||
  remez.generateApprox(degree, 1, 4);
 | 
			
		||||
  MultiShiftFunction PowerQuarter(remez, stop_tol, false);
 | 
			
		||||
  MultiShiftFunction PowerNegQuarter(remez, stop_tol, true);
 | 
			
		||||
 | 
			
		||||
  // Stochastically estimate reweighting factor via RHMC
 | 
			
		||||
  RealD scale = std::sqrt(0.5);
 | 
			
		||||
  std::vector<RealD> rw_rhmc(Nhits);
 | 
			
		||||
  ConjugateGradientMultiShift<LatticeFermion> msCG_V(max_iter, PowerQuarter);
 | 
			
		||||
  ConjugateGradientMultiShift<LatticeFermion> msCG_M(max_iter, PowerNegQuarter);
 | 
			
		||||
  std::cout.precision(12);
 | 
			
		||||
 | 
			
		||||
  for(int hit=0; hit<Nhits; hit++){
 | 
			
		||||
 | 
			
		||||
    // Gaussian source
 | 
			
		||||
    LatticeFermion Phi    (Ddwf_f.FermionGrid());
 | 
			
		||||
    LatticeFermion PhiOdd (Ddwf_f.FermionRedBlackGrid());
 | 
			
		||||
    std::vector<LatticeFermion> tmp(2, Ddwf_f.FermionRedBlackGrid());
 | 
			
		||||
    gaussian(RNG5, Phi);
 | 
			
		||||
    Phi = Phi*scale;
 | 
			
		||||
 | 
			
		||||
    pickCheckerboard(Odd, PhiOdd, Phi);
 | 
			
		||||
 | 
			
		||||
    // evaluate -log(rw)
 | 
			
		||||
    msCG_V(VdagV, PhiOdd, tmp[0]);
 | 
			
		||||
    msCG_M(MdagM, tmp[0], tmp[1]);
 | 
			
		||||
    rw_rhmc[hit] = norm2(tmp[1]) - norm2(PhiOdd);
 | 
			
		||||
    std::cout << std::endl << "==================================================" << std::endl;
 | 
			
		||||
    std::cout << " --- RHMC: Hit " << hit << ": rw = " << rw_rhmc[hit];
 | 
			
		||||
    std::cout << std::endl << "==================================================" << std::endl << std::endl;
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Initialize EOFA fermion operators
 | 
			
		||||
  RealD shift_L = 0.0;
 | 
			
		||||
  RealD shift_R = -1.0;
 | 
			
		||||
  int pm = 1;
 | 
			
		||||
  MobiusEOFAFermionR Deofa_L(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mb, shift_L, pm, M5, b, c);
 | 
			
		||||
  MobiusEOFAFermionR Deofa_R(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, mf, mb, shift_R, pm, M5, b, c);
 | 
			
		||||
  MdagMLinearOperator<MobiusEOFAFermionR, LatticeFermion> LdagL(Deofa_L);
 | 
			
		||||
  MdagMLinearOperator<MobiusEOFAFermionR, LatticeFermion> RdagR(Deofa_R);
 | 
			
		||||
 | 
			
		||||
  // Stochastically estimate reweighting factor via EOFA
 | 
			
		||||
  RealD k = Deofa_L.k;
 | 
			
		||||
  std::vector<RealD> rw_eofa(Nhits);
 | 
			
		||||
  ConjugateGradient<LatticeFermion> CG(stop_tol, max_iter);
 | 
			
		||||
  SchurRedBlackDiagMooeeSolve<LatticeFermion> SchurSolver(CG);
 | 
			
		||||
 | 
			
		||||
  // Compute -log(Z), where: ( RHMC det ratio ) = Z * ( EOFA det ratio )
 | 
			
		||||
  RealD Z = std::pow(b+c+1.0,Ls) + mf*std::pow(b+c-1.0,Ls);
 | 
			
		||||
  Z /= std::pow(b+c+1.0,Ls) + mb*std::pow(b+c-1.0,Ls);
 | 
			
		||||
  Z = -12.0*grid_dim[0]*grid_dim[1]*grid_dim[2]*grid_dim[3]*std::log(Z);
 | 
			
		||||
 | 
			
		||||
  for(int hit=0; hit<Nhits; hit++){
 | 
			
		||||
 | 
			
		||||
    // Gaussian source
 | 
			
		||||
    LatticeFermion Phi       (Deofa_L.FermionGrid());
 | 
			
		||||
    LatticeFermion spProj_Phi(Deofa_L.FermionGrid());
 | 
			
		||||
    std::vector<LatticeFermion> tmp(2, Deofa_L.FermionGrid());
 | 
			
		||||
    gaussian(RNG5, Phi);
 | 
			
		||||
    Phi = Phi*scale;
 | 
			
		||||
 | 
			
		||||
    // evaluate -log(rw)
 | 
			
		||||
    // LH term
 | 
			
		||||
    for(int s=0; s<Ls; ++s){ axpby_ssp_pminus(spProj_Phi, 0.0, Phi, 1.0, Phi, s, s); }
 | 
			
		||||
    Deofa_L.Omega(spProj_Phi, tmp[0], -1, 0);
 | 
			
		||||
    G5R5(tmp[1], tmp[0]);
 | 
			
		||||
    tmp[0] = zero;
 | 
			
		||||
    SchurSolver(Deofa_L, tmp[1], tmp[0]);
 | 
			
		||||
    Deofa_L.Dtilde(tmp[0], tmp[1]);
 | 
			
		||||
    Deofa_L.Omega(tmp[1], tmp[0], -1, 1);
 | 
			
		||||
    rw_eofa[hit] = Z - k*innerProduct(spProj_Phi,tmp[0]).real();
 | 
			
		||||
 | 
			
		||||
    // RH term
 | 
			
		||||
    for(int s=0; s<Ls; ++s){ axpby_ssp_pplus(spProj_Phi, 0.0, Phi, 1.0, Phi, s, s); }
 | 
			
		||||
    Deofa_R.Omega(spProj_Phi, tmp[0], 1, 0);
 | 
			
		||||
    G5R5(tmp[1], tmp[0]);
 | 
			
		||||
    tmp[0] = zero;
 | 
			
		||||
    SchurSolver(Deofa_R, tmp[1], tmp[0]);
 | 
			
		||||
    Deofa_R.Dtilde(tmp[0], tmp[1]);
 | 
			
		||||
    Deofa_R.Omega(tmp[1], tmp[0], 1, 1);
 | 
			
		||||
    rw_eofa[hit] += k*innerProduct(spProj_Phi,tmp[0]).real();
 | 
			
		||||
    std::cout << std::endl << "==================================================" << std::endl;
 | 
			
		||||
    std::cout << " --- EOFA: Hit " << hit << ": rw = " << rw_eofa[hit];
 | 
			
		||||
    std::cout << std::endl << "==================================================" << std::endl << std::endl;
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  std::vector<RealD> rhmc_result = jack_stats(rw_rhmc);
 | 
			
		||||
  std::vector<RealD> eofa_result = jack_stats(rw_eofa);
 | 
			
		||||
  std::cout << std::endl << "RHMC: rw = " << rhmc_result[0] << " +/- " << rhmc_result[1] << std::endl;
 | 
			
		||||
  std::cout << std::endl << "EOFA: rw = " << eofa_result[0] << " +/- " << eofa_result[1] << std::endl;
 | 
			
		||||
 | 
			
		||||
  Grid_finalize();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										218
									
								
								tests/debug/Test_reweight_mobius_eofa_gparity.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										218
									
								
								tests/debug/Test_reweight_mobius_eofa_gparity.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,218 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid
 | 
			
		||||
 | 
			
		||||
Source file: ./tests/debug/Test_reweight_dwf_eofa.cc
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2017
 | 
			
		||||
 | 
			
		||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
Author: David Murphy <dmurphy@phys.columbia.edu>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
#include <Grid/Grid.h>
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
using namespace Grid;
 | 
			
		||||
using namespace Grid::QCD;
 | 
			
		||||
 | 
			
		||||
typedef typename GparityDomainWallFermionR::FermionField FermionField;
 | 
			
		||||
 | 
			
		||||
// parameters for test
 | 
			
		||||
const std::vector<int> grid_dim = { 8, 8, 8, 8 };
 | 
			
		||||
const int Ls = 8;
 | 
			
		||||
const int Nhits = 10;
 | 
			
		||||
const int max_iter = 5000;
 | 
			
		||||
const RealD b  = 2.5;
 | 
			
		||||
const RealD c  = 1.5;
 | 
			
		||||
const RealD mf = 0.1;
 | 
			
		||||
const RealD mb = 0.11;
 | 
			
		||||
const RealD M5 = 1.8;
 | 
			
		||||
const RealD stop_tol = 1.0e-12;
 | 
			
		||||
 | 
			
		||||
RealD mean(const std::vector<RealD>& data)
 | 
			
		||||
{
 | 
			
		||||
    int N = data.size();
 | 
			
		||||
    RealD mean(0.0);
 | 
			
		||||
    for(int i=0; i<N; ++i){ mean += data[i]; }
 | 
			
		||||
    return mean/RealD(N);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RealD jack_mean(const std::vector<RealD>& data, int sample)
 | 
			
		||||
{
 | 
			
		||||
    int N = data.size();
 | 
			
		||||
    RealD mean(0.0);
 | 
			
		||||
    for(int i=0; i<N; ++i){ if(i != sample){ mean += data[i]; } }
 | 
			
		||||
    return mean/RealD(N-1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RealD jack_std(const std::vector<RealD>& jacks, RealD mean)
 | 
			
		||||
{
 | 
			
		||||
    int N = jacks.size();
 | 
			
		||||
    RealD std(0.0);
 | 
			
		||||
    for(int i=0; i<N; ++i){ std += std::pow(jacks[i]-mean, 2.0); }
 | 
			
		||||
    return std::sqrt(RealD(N-1)/RealD(N)*std);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<RealD> jack_stats(const std::vector<RealD>& data)
 | 
			
		||||
{
 | 
			
		||||
    int N = data.size();
 | 
			
		||||
    std::vector<RealD> jack_samples(N);
 | 
			
		||||
    std::vector<RealD> jack_stats(2);
 | 
			
		||||
 | 
			
		||||
    jack_stats[0] = mean(data);
 | 
			
		||||
    for(int i=0; i<N; i++){ jack_samples[i] = jack_mean(data,i); }
 | 
			
		||||
    jack_stats[1] = jack_std(jack_samples, jack_stats[0]);
 | 
			
		||||
    return jack_stats;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
  Grid_init(&argc, &argv);
 | 
			
		||||
 | 
			
		||||
  // Initialize spacetime grid
 | 
			
		||||
  std::cout << GridLogMessage << "Lattice dimensions: "
 | 
			
		||||
    << grid_dim << "   Ls: " << Ls << std::endl;
 | 
			
		||||
  GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid(grid_dim,
 | 
			
		||||
      GridDefaultSimd(Nd, vComplex::Nsimd()), GridDefaultMpi());
 | 
			
		||||
  GridRedBlackCartesian* UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
 | 
			
		||||
  GridCartesian* FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
 | 
			
		||||
  GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
 | 
			
		||||
 | 
			
		||||
  // Set up RNGs
 | 
			
		||||
  std::vector<int> seeds4({1, 2, 3, 4});
 | 
			
		||||
  std::vector<int> seeds5({5, 6, 7, 8});
 | 
			
		||||
  GridParallelRNG RNG5(FGrid);
 | 
			
		||||
  RNG5.SeedFixedIntegers(seeds5);
 | 
			
		||||
  GridParallelRNG RNG4(UGrid);
 | 
			
		||||
  RNG4.SeedFixedIntegers(seeds4);
 | 
			
		||||
 | 
			
		||||
  // Random gauge field
 | 
			
		||||
  LatticeGaugeField Umu(UGrid);
 | 
			
		||||
  SU3::HotConfiguration(RNG4, Umu);
 | 
			
		||||
 | 
			
		||||
  // Initialize RHMC fermion operators
 | 
			
		||||
  GparityDomainWallFermionR::ImplParams params;
 | 
			
		||||
  GparityMobiusFermionR Ddwf_f(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, M5, b, c, params);
 | 
			
		||||
  GparityMobiusFermionR Ddwf_b(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, M5, b, c, params);
 | 
			
		||||
  SchurDiagMooeeOperator<GparityMobiusFermionR, FermionField> MdagM(Ddwf_f);
 | 
			
		||||
  SchurDiagMooeeOperator<GparityMobiusFermionR, FermionField> VdagV(Ddwf_b);
 | 
			
		||||
 | 
			
		||||
  // Degree 12 rational approximations to x^(1/4) and x^(-1/4)
 | 
			
		||||
  double     lo = 0.0001;
 | 
			
		||||
  double     hi = 95.0;
 | 
			
		||||
  int precision = 64;
 | 
			
		||||
  int    degree = 12;
 | 
			
		||||
  AlgRemez remez(lo, hi, precision);
 | 
			
		||||
  std::cout << GridLogMessage << "Generating degree " << degree << " for x^(1/4)" << std::endl;
 | 
			
		||||
  remez.generateApprox(degree, 1, 4);
 | 
			
		||||
  MultiShiftFunction PowerQuarter(remez, stop_tol, false);
 | 
			
		||||
  MultiShiftFunction PowerNegQuarter(remez, stop_tol, true);
 | 
			
		||||
 | 
			
		||||
  // Stochastically estimate reweighting factor via RHMC
 | 
			
		||||
  RealD scale = std::sqrt(0.5);
 | 
			
		||||
  std::vector<RealD> rw_rhmc(Nhits);
 | 
			
		||||
  ConjugateGradientMultiShift<FermionField> msCG_V(max_iter, PowerQuarter);
 | 
			
		||||
  ConjugateGradientMultiShift<FermionField> msCG_M(max_iter, PowerNegQuarter);
 | 
			
		||||
  std::cout.precision(12);
 | 
			
		||||
 | 
			
		||||
  for(int hit=0; hit<Nhits; hit++){
 | 
			
		||||
 | 
			
		||||
    // Gaussian source
 | 
			
		||||
    FermionField Phi    (Ddwf_f.FermionGrid());
 | 
			
		||||
    FermionField PhiOdd (Ddwf_f.FermionRedBlackGrid());
 | 
			
		||||
    std::vector<FermionField> tmp(2, Ddwf_f.FermionRedBlackGrid());
 | 
			
		||||
    gaussian(RNG5, Phi);
 | 
			
		||||
    Phi = Phi*scale;
 | 
			
		||||
 | 
			
		||||
    pickCheckerboard(Odd, PhiOdd, Phi);
 | 
			
		||||
 | 
			
		||||
    // evaluate -log(rw)
 | 
			
		||||
    msCG_V(VdagV, PhiOdd, tmp[0]);
 | 
			
		||||
    msCG_M(MdagM, tmp[0], tmp[1]);
 | 
			
		||||
    rw_rhmc[hit] = norm2(tmp[1]) - norm2(PhiOdd);
 | 
			
		||||
    std::cout << std::endl << "==================================================" << std::endl;
 | 
			
		||||
    std::cout << " --- RHMC: Hit " << hit << ": rw = " << rw_rhmc[hit];
 | 
			
		||||
    std::cout << std::endl << "==================================================" << std::endl << std::endl;
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Initialize EOFA fermion operators
 | 
			
		||||
  RealD shift_L = 0.0;
 | 
			
		||||
  RealD shift_R = -1.0;
 | 
			
		||||
  int pm = 1;
 | 
			
		||||
  GparityMobiusEOFAFermionR Deofa_L(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mb, shift_L, pm, M5, b, c, params);
 | 
			
		||||
  GparityMobiusEOFAFermionR Deofa_R(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, mf, mb, shift_R, pm, M5, b, c, params);
 | 
			
		||||
  MdagMLinearOperator<GparityMobiusEOFAFermionR, FermionField> LdagL(Deofa_L);
 | 
			
		||||
  MdagMLinearOperator<GparityMobiusEOFAFermionR, FermionField> RdagR(Deofa_R);
 | 
			
		||||
 | 
			
		||||
  // Stochastically estimate reweighting factor via EOFA
 | 
			
		||||
  RealD k = Deofa_L.k;
 | 
			
		||||
  std::vector<RealD> rw_eofa(Nhits);
 | 
			
		||||
  ConjugateGradient<FermionField> CG(stop_tol, max_iter);
 | 
			
		||||
  SchurRedBlackDiagMooeeSolve<FermionField> SchurSolver(CG);
 | 
			
		||||
 | 
			
		||||
  // Compute -log(Z), where: ( RHMC det ratio ) = Z * ( EOFA det ratio )
 | 
			
		||||
  RealD Z = std::pow(b+c+1.0,Ls) + mf*std::pow(b+c-1.0,Ls);
 | 
			
		||||
  Z /= std::pow(b+c+1.0,Ls) + mb*std::pow(b+c-1.0,Ls);
 | 
			
		||||
  Z = -12.0*grid_dim[0]*grid_dim[1]*grid_dim[2]*grid_dim[3]*std::log(Z);
 | 
			
		||||
 | 
			
		||||
  for(int hit=0; hit<Nhits; hit++){
 | 
			
		||||
 | 
			
		||||
    // Gaussian source
 | 
			
		||||
    FermionField Phi       (Deofa_L.FermionGrid());
 | 
			
		||||
    FermionField spProj_Phi(Deofa_L.FermionGrid());
 | 
			
		||||
    std::vector<FermionField> tmp(2, Deofa_L.FermionGrid());
 | 
			
		||||
    gaussian(RNG5, Phi);
 | 
			
		||||
    Phi = Phi*scale;
 | 
			
		||||
 | 
			
		||||
    // evaluate -log(rw)
 | 
			
		||||
    // LH term
 | 
			
		||||
    for(int s=0; s<Ls; ++s){ axpby_ssp_pminus(spProj_Phi, 0.0, Phi, 1.0, Phi, s, s); }
 | 
			
		||||
    Deofa_L.Omega(spProj_Phi, tmp[0], -1, 0);
 | 
			
		||||
    G5R5(tmp[1], tmp[0]);
 | 
			
		||||
    tmp[0] = zero;
 | 
			
		||||
    SchurSolver(Deofa_L, tmp[1], tmp[0]);
 | 
			
		||||
    Deofa_L.Dtilde(tmp[0], tmp[1]);
 | 
			
		||||
    Deofa_L.Omega(tmp[1], tmp[0], -1, 1);
 | 
			
		||||
    rw_eofa[hit] = 2.0*Z - k*innerProduct(spProj_Phi,tmp[0]).real();
 | 
			
		||||
 | 
			
		||||
    // RH term
 | 
			
		||||
    for(int s=0; s<Ls; ++s){ axpby_ssp_pplus(spProj_Phi, 0.0, Phi, 1.0, Phi, s, s); }
 | 
			
		||||
    Deofa_R.Omega(spProj_Phi, tmp[0], 1, 0);
 | 
			
		||||
    G5R5(tmp[1], tmp[0]);
 | 
			
		||||
    tmp[0] = zero;
 | 
			
		||||
    SchurSolver(Deofa_R, tmp[1], tmp[0]);
 | 
			
		||||
    Deofa_R.Dtilde(tmp[0], tmp[1]);
 | 
			
		||||
    Deofa_R.Omega(tmp[1], tmp[0], 1, 1);
 | 
			
		||||
    rw_eofa[hit] += k*innerProduct(spProj_Phi,tmp[0]).real();
 | 
			
		||||
    std::cout << std::endl << "==================================================" << std::endl;
 | 
			
		||||
    std::cout << " --- EOFA: Hit " << hit << ": rw = " << rw_eofa[hit];
 | 
			
		||||
    std::cout << std::endl << "==================================================" << std::endl << std::endl;
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  std::vector<RealD> rhmc_result = jack_stats(rw_rhmc);
 | 
			
		||||
  std::vector<RealD> eofa_result = jack_stats(rw_eofa);
 | 
			
		||||
  std::cout << std::endl << "RHMC: rw = " << rhmc_result[0] << " +/- " << rhmc_result[1] << std::endl;
 | 
			
		||||
  std::cout << std::endl << "EOFA: rw = " << eofa_result[0] << " +/- " << eofa_result[1] << std::endl;
 | 
			
		||||
 | 
			
		||||
  Grid_finalize();
 | 
			
		||||
}
 | 
			
		||||
@@ -71,9 +71,9 @@ int main (int argc, char** argv)
 | 
			
		||||
  int threads = GridThread::GetThreads();
 | 
			
		||||
  std::cout << GridLogMessage << "Grid is setup to use " << threads << " threads" << std::endl;
 | 
			
		||||
 | 
			
		||||
  LatticeFermion phi        (FGrid);  gaussian(RNG5, phi);
 | 
			
		||||
  LatticeFermion Mphi       (FGrid);
 | 
			
		||||
  LatticeFermion MphiPrime  (FGrid);
 | 
			
		||||
  FermionField phi        (FGrid);  gaussian(RNG5, phi);
 | 
			
		||||
  FermionField Mphi       (FGrid);
 | 
			
		||||
  FermionField MphiPrime  (FGrid);
 | 
			
		||||
 | 
			
		||||
  LatticeGaugeField U(UGrid);
 | 
			
		||||
  SU3::HotConfiguration(RNG4,U);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										166
									
								
								tests/forces/Test_mobius_force_eofa.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								tests/forces/Test_mobius_force_eofa.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,166 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid
 | 
			
		||||
 | 
			
		||||
Source file: ./tests/forces/Test_dwf_force_eofa.cc
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2017
 | 
			
		||||
 | 
			
		||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
Author: David Murphy <dmurphy@phys.columbia.edu>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#include <Grid/Grid.h>
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
using namespace Grid;
 | 
			
		||||
using namespace Grid::QCD;
 | 
			
		||||
 | 
			
		||||
int main (int argc, char** argv)
 | 
			
		||||
{
 | 
			
		||||
  Grid_init(&argc, &argv);
 | 
			
		||||
 | 
			
		||||
  std::vector<int> latt_size   = GridDefaultLatt();
 | 
			
		||||
  std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
 | 
			
		||||
  std::vector<int> mpi_layout  = GridDefaultMpi();
 | 
			
		||||
 | 
			
		||||
  const int Ls = 8;
 | 
			
		||||
 | 
			
		||||
  GridCartesian         *UGrid   = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
 | 
			
		||||
  GridRedBlackCartesian *UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
 | 
			
		||||
  GridCartesian         *FGrid   = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
 | 
			
		||||
  GridRedBlackCartesian *FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
 | 
			
		||||
 | 
			
		||||
  // Want a different conf at every run
 | 
			
		||||
  // First create an instance of an engine.
 | 
			
		||||
  std::random_device rnd_device;
 | 
			
		||||
  // Specify the engine and distribution.
 | 
			
		||||
  std::mt19937 mersenne_engine(rnd_device());
 | 
			
		||||
  std::uniform_int_distribution<int> dist(1, 100);
 | 
			
		||||
 | 
			
		||||
  auto gen = std::bind(dist, mersenne_engine);
 | 
			
		||||
  std::vector<int> seeds4(4);
 | 
			
		||||
  generate(begin(seeds4), end(seeds4), gen);
 | 
			
		||||
 | 
			
		||||
  //std::vector<int> seeds4({1,2,3,5});
 | 
			
		||||
  std::vector<int> seeds5({5,6,7,8});
 | 
			
		||||
  GridParallelRNG RNG5(FGrid);  RNG5.SeedFixedIntegers(seeds5);
 | 
			
		||||
  GridParallelRNG RNG4(UGrid);  RNG4.SeedFixedIntegers(seeds4);
 | 
			
		||||
 | 
			
		||||
  int threads = GridThread::GetThreads();
 | 
			
		||||
  std::cout << GridLogMessage << "Grid is setup to use " << threads << " threads" << std::endl;
 | 
			
		||||
 | 
			
		||||
  LatticeFermion phi        (FGrid);  gaussian(RNG5, phi);
 | 
			
		||||
  LatticeFermion Mphi       (FGrid);
 | 
			
		||||
  LatticeFermion MphiPrime  (FGrid);
 | 
			
		||||
 | 
			
		||||
  LatticeGaugeField U(UGrid);
 | 
			
		||||
  SU3::HotConfiguration(RNG4,U);
 | 
			
		||||
 | 
			
		||||
  ////////////////////////////////////
 | 
			
		||||
  // Unmodified matrix element
 | 
			
		||||
  ////////////////////////////////////
 | 
			
		||||
  RealD b  = 2.5;
 | 
			
		||||
  RealD c  = 1.5;
 | 
			
		||||
  RealD mf = 0.01;
 | 
			
		||||
  RealD mb = 1.0;
 | 
			
		||||
  RealD M5 = 1.8;
 | 
			
		||||
  MobiusEOFAFermionR Lop(U, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mb, 0.0, -1, M5, b, c);
 | 
			
		||||
  MobiusEOFAFermionR Rop(U, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, mf, mb, -1.0, 1, M5, b, c);
 | 
			
		||||
  OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, 12);
 | 
			
		||||
  ConjugateGradient<LatticeFermion> CG(1.0e-12, 5000);
 | 
			
		||||
  ExactOneFlavourRatioPseudoFermionAction<WilsonImplR> Meofa(Lop, Rop, CG, Params, false);
 | 
			
		||||
 | 
			
		||||
  Meofa.refresh(U, RNG5);
 | 
			
		||||
  RealD S = Meofa.S(U); // pdag M p
 | 
			
		||||
 | 
			
		||||
  // get the deriv of phidag M phi with respect to "U"
 | 
			
		||||
  LatticeGaugeField UdSdU(UGrid);
 | 
			
		||||
  Meofa.deriv(U, UdSdU);
 | 
			
		||||
 | 
			
		||||
  ////////////////////////////////////
 | 
			
		||||
  // Modify the gauge field a little
 | 
			
		||||
  ////////////////////////////////////
 | 
			
		||||
  RealD dt = 0.0001;
 | 
			
		||||
 | 
			
		||||
  LatticeColourMatrix mommu(UGrid);
 | 
			
		||||
  LatticeColourMatrix forcemu(UGrid);
 | 
			
		||||
  LatticeGaugeField mom(UGrid);
 | 
			
		||||
  LatticeGaugeField Uprime(UGrid);
 | 
			
		||||
 | 
			
		||||
  for(int mu=0; mu<Nd; mu++){
 | 
			
		||||
 | 
			
		||||
    SU3::GaussianFundamentalLieAlgebraMatrix(RNG4, mommu); // Traceless antihermitian momentum; gaussian in lie alg
 | 
			
		||||
 | 
			
		||||
    PokeIndex<LorentzIndex>(mom, mommu, mu);
 | 
			
		||||
 | 
			
		||||
    // fourth order exponential approx
 | 
			
		||||
    parallel_for(auto i=mom.begin(); i<mom.end(); i++){
 | 
			
		||||
      Uprime[i](mu) = U[i](mu) + mom[i](mu)*U[i](mu)*dt + mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt/2.0)
 | 
			
		||||
                        + mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt/6.0)
 | 
			
		||||
                        + mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt/24.0)
 | 
			
		||||
                        + mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt*dt/120.0)
 | 
			
		||||
                        + mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt*dt*dt/720.0);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /*Ddwf.ImportGauge(Uprime);
 | 
			
		||||
  Ddwf.M          (phi,MphiPrime);
 | 
			
		||||
 | 
			
		||||
  ComplexD Sprime    = innerProduct(MphiPrime   ,MphiPrime);*/
 | 
			
		||||
  RealD Sprime = Meofa.S(Uprime);
 | 
			
		||||
 | 
			
		||||
  //////////////////////////////////////////////
 | 
			
		||||
  // Use derivative to estimate dS
 | 
			
		||||
  //////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
  LatticeComplex dS(UGrid);
 | 
			
		||||
  dS = zero;
 | 
			
		||||
  for(int mu=0; mu<Nd; mu++){
 | 
			
		||||
    mommu = PeekIndex<LorentzIndex>(UdSdU, mu);
 | 
			
		||||
    mommu = Ta(mommu)*2.0;
 | 
			
		||||
    PokeIndex<LorentzIndex>(UdSdU, mommu, mu);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for(int mu=0; mu<Nd; mu++){
 | 
			
		||||
    forcemu = PeekIndex<LorentzIndex>(UdSdU, mu);
 | 
			
		||||
    mommu   = PeekIndex<LorentzIndex>(mom, mu);
 | 
			
		||||
 | 
			
		||||
    // Update PF action density
 | 
			
		||||
    dS = dS + trace(mommu*forcemu)*dt;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ComplexD dSpred = sum(dS);
 | 
			
		||||
 | 
			
		||||
  /*std::cout << GridLogMessage << " S      " << S << std::endl;
 | 
			
		||||
  std::cout << GridLogMessage << " Sprime " << Sprime << std::endl;
 | 
			
		||||
  std::cout << GridLogMessage << "dS      " << Sprime-S << std::endl;
 | 
			
		||||
  std::cout << GridLogMessage << "predict dS    " << dSpred << std::endl;*/
 | 
			
		||||
  printf("\nS = %1.15e\n", S);
 | 
			
		||||
  printf("Sprime = %1.15e\n", Sprime);
 | 
			
		||||
  printf("dS = %1.15e\n", Sprime - S);
 | 
			
		||||
  printf("real(dS_predict) = %1.15e\n", dSpred.real());
 | 
			
		||||
  printf("imag(dS_predict) = %1.15e\n\n", dSpred.imag());
 | 
			
		||||
 | 
			
		||||
  assert( fabs(real(Sprime-S-dSpred)) < 1.0 ) ;
 | 
			
		||||
 | 
			
		||||
  std::cout << GridLogMessage << "Done" << std::endl;
 | 
			
		||||
  Grid_finalize();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										171
									
								
								tests/forces/Test_mobius_gpforce_eofa.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								tests/forces/Test_mobius_gpforce_eofa.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,171 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid
 | 
			
		||||
 | 
			
		||||
Source file: ./tests/forces/Test_dwf_force_eofa.cc
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2017
 | 
			
		||||
 | 
			
		||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
Author: David Murphy <dmurphy@phys.columbia.edu>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#include <Grid/Grid.h>
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
using namespace Grid;
 | 
			
		||||
using namespace Grid::QCD;
 | 
			
		||||
 | 
			
		||||
typedef GparityWilsonImplR FermionImplPolicy;
 | 
			
		||||
typedef GparityMobiusEOFAFermionR FermionAction;
 | 
			
		||||
typedef typename FermionAction::FermionField FermionField;
 | 
			
		||||
 | 
			
		||||
int main (int argc, char** argv)
 | 
			
		||||
{
 | 
			
		||||
  Grid_init(&argc, &argv);
 | 
			
		||||
 | 
			
		||||
  std::vector<int> latt_size   = GridDefaultLatt();
 | 
			
		||||
  std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
 | 
			
		||||
  std::vector<int> mpi_layout  = GridDefaultMpi();
 | 
			
		||||
 | 
			
		||||
  const int Ls = 8;
 | 
			
		||||
 | 
			
		||||
  GridCartesian         *UGrid   = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
 | 
			
		||||
  GridRedBlackCartesian *UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
 | 
			
		||||
  GridCartesian         *FGrid   = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
 | 
			
		||||
  GridRedBlackCartesian *FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
 | 
			
		||||
 | 
			
		||||
  // Want a different conf at every run
 | 
			
		||||
  // First create an instance of an engine.
 | 
			
		||||
  std::random_device rnd_device;
 | 
			
		||||
  // Specify the engine and distribution.
 | 
			
		||||
  std::mt19937 mersenne_engine(rnd_device());
 | 
			
		||||
  std::uniform_int_distribution<int> dist(1, 100);
 | 
			
		||||
 | 
			
		||||
  auto gen = std::bind(dist, mersenne_engine);
 | 
			
		||||
  std::vector<int> seeds4(4);
 | 
			
		||||
  generate(begin(seeds4), end(seeds4), gen);
 | 
			
		||||
 | 
			
		||||
  //std::vector<int> seeds4({1,2,3,5});
 | 
			
		||||
  std::vector<int> seeds5({5,6,7,8});
 | 
			
		||||
  GridParallelRNG RNG5(FGrid);  RNG5.SeedFixedIntegers(seeds5);
 | 
			
		||||
  GridParallelRNG RNG4(UGrid);  RNG4.SeedFixedIntegers(seeds4);
 | 
			
		||||
 | 
			
		||||
  int threads = GridThread::GetThreads();
 | 
			
		||||
  std::cout << GridLogMessage << "Grid is setup to use " << threads << " threads" << std::endl;
 | 
			
		||||
 | 
			
		||||
  FermionField phi        (FGrid);  gaussian(RNG5, phi);
 | 
			
		||||
  FermionField Mphi       (FGrid);
 | 
			
		||||
  FermionField MphiPrime  (FGrid);
 | 
			
		||||
 | 
			
		||||
  LatticeGaugeField U(UGrid);
 | 
			
		||||
  SU3::HotConfiguration(RNG4,U);
 | 
			
		||||
 | 
			
		||||
  ////////////////////////////////////
 | 
			
		||||
  // Unmodified matrix element
 | 
			
		||||
  ////////////////////////////////////
 | 
			
		||||
  RealD b  = 2.5;
 | 
			
		||||
  RealD c  = 1.5;
 | 
			
		||||
  RealD mf = 0.01;
 | 
			
		||||
  RealD mb = 1.0;
 | 
			
		||||
  RealD M5 = 1.8;
 | 
			
		||||
  FermionAction::ImplParams params;
 | 
			
		||||
  FermionAction Lop(U, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mb, 0.0, -1, M5, b, c, params);
 | 
			
		||||
  FermionAction Rop(U, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, mf, mb, -1.0, 1, M5, b, c, params);
 | 
			
		||||
  OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, 12);
 | 
			
		||||
  ConjugateGradient<FermionField> CG(1.0e-12, 5000);
 | 
			
		||||
  ExactOneFlavourRatioPseudoFermionAction<FermionImplPolicy> Meofa(Lop, Rop, CG, Params, false);
 | 
			
		||||
 | 
			
		||||
  Meofa.refresh(U, RNG5);
 | 
			
		||||
  RealD S = Meofa.S(U); // pdag M p
 | 
			
		||||
 | 
			
		||||
  // get the deriv of phidag M phi with respect to "U"
 | 
			
		||||
  LatticeGaugeField UdSdU(UGrid);
 | 
			
		||||
  Meofa.deriv(U, UdSdU);
 | 
			
		||||
 | 
			
		||||
  ////////////////////////////////////
 | 
			
		||||
  // Modify the gauge field a little
 | 
			
		||||
  ////////////////////////////////////
 | 
			
		||||
  RealD dt = 0.0001;
 | 
			
		||||
 | 
			
		||||
  LatticeColourMatrix mommu(UGrid);
 | 
			
		||||
  LatticeColourMatrix forcemu(UGrid);
 | 
			
		||||
  LatticeGaugeField mom(UGrid);
 | 
			
		||||
  LatticeGaugeField Uprime(UGrid);
 | 
			
		||||
 | 
			
		||||
  for(int mu=0; mu<Nd; mu++){
 | 
			
		||||
 | 
			
		||||
    SU3::GaussianFundamentalLieAlgebraMatrix(RNG4, mommu); // Traceless antihermitian momentum; gaussian in lie alg
 | 
			
		||||
 | 
			
		||||
    PokeIndex<LorentzIndex>(mom, mommu, mu);
 | 
			
		||||
 | 
			
		||||
    // fourth order exponential approx
 | 
			
		||||
    parallel_for(auto i=mom.begin(); i<mom.end(); i++){
 | 
			
		||||
      Uprime[i](mu) = U[i](mu) + mom[i](mu)*U[i](mu)*dt + mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt/2.0)
 | 
			
		||||
                        + mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt/6.0)
 | 
			
		||||
                        + mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt/24.0)
 | 
			
		||||
                        + mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt*dt/120.0)
 | 
			
		||||
                        + mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt*dt*dt/720.0);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /*Ddwf.ImportGauge(Uprime);
 | 
			
		||||
  Ddwf.M          (phi,MphiPrime);
 | 
			
		||||
 | 
			
		||||
  ComplexD Sprime    = innerProduct(MphiPrime   ,MphiPrime);*/
 | 
			
		||||
  RealD Sprime = Meofa.S(Uprime);
 | 
			
		||||
 | 
			
		||||
  //////////////////////////////////////////////
 | 
			
		||||
  // Use derivative to estimate dS
 | 
			
		||||
  //////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
  LatticeComplex dS(UGrid);
 | 
			
		||||
  dS = zero;
 | 
			
		||||
  for(int mu=0; mu<Nd; mu++){
 | 
			
		||||
    mommu = PeekIndex<LorentzIndex>(UdSdU, mu);
 | 
			
		||||
    mommu = Ta(mommu)*2.0;
 | 
			
		||||
    PokeIndex<LorentzIndex>(UdSdU, mommu, mu);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for(int mu=0; mu<Nd; mu++){
 | 
			
		||||
    forcemu = PeekIndex<LorentzIndex>(UdSdU, mu);
 | 
			
		||||
    mommu   = PeekIndex<LorentzIndex>(mom, mu);
 | 
			
		||||
 | 
			
		||||
    // Update PF action density
 | 
			
		||||
    dS = dS + trace(mommu*forcemu)*dt;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ComplexD dSpred = sum(dS);
 | 
			
		||||
 | 
			
		||||
  /*std::cout << GridLogMessage << " S      " << S << std::endl;
 | 
			
		||||
  std::cout << GridLogMessage << " Sprime " << Sprime << std::endl;
 | 
			
		||||
  std::cout << GridLogMessage << "dS      " << Sprime-S << std::endl;
 | 
			
		||||
  std::cout << GridLogMessage << "predict dS    " << dSpred << std::endl;*/
 | 
			
		||||
  printf("\nS = %1.15e\n", S);
 | 
			
		||||
  printf("Sprime = %1.15e\n", Sprime);
 | 
			
		||||
  printf("dS = %1.15e\n", Sprime - S);
 | 
			
		||||
  printf("real(dS_predict) = %1.15e\n", dSpred.real());
 | 
			
		||||
  printf("imag(dS_predict) = %1.15e\n\n", dSpred.imag());
 | 
			
		||||
 | 
			
		||||
  assert( fabs(real(Sprime-S-dSpred)) < 1.0 ) ;
 | 
			
		||||
 | 
			
		||||
  std::cout << GridLogMessage << "Done" << std::endl;
 | 
			
		||||
  Grid_finalize();
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user