mirror of
https://github.com/paboyle/Grid.git
synced 2025-04-09 21:50:45 +01:00
Beautification
This commit is contained in:
parent
4bcdb4ff95
commit
fcd90705bc
@ -3,12 +3,12 @@
|
|||||||
Grid physics library, www.github.com/paboyle/Grid
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
Source file: Hadrons/Modules/MDistil/DistilCommon.hpp
|
Source file: Hadrons/Modules/MDistil/DistilCommon.hpp
|
||||||
|
|
||||||
Copyright (C) 2015-2019
|
Copyright (C) 2015-2019
|
||||||
|
|
||||||
Author: Felix Erben <ferben@ed.ac.uk>
|
Author: Felix Erben <ferben@ed.ac.uk>
|
||||||
Author: Michael Marshall <Michael.Marshall@ed.ac.uk>
|
Author: Michael Marshall <Michael.Marshall@ed.ac.uk>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
@ -41,33 +41,33 @@ BEGIN_HADRONS_NAMESPACE
|
|||||||
BEGIN_MODULE_NAMESPACE(MDistil)
|
BEGIN_MODULE_NAMESPACE(MDistil)
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
Common elements for distillation
|
Distillation code that is common across modules
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
struct DistilParameters: Serializable {
|
struct DistilParameters: Serializable {
|
||||||
GRID_SERIALIZABLE_CLASS_MEMBERS(DistilParameters,
|
GRID_SERIALIZABLE_CLASS_MEMBERS(DistilParameters,
|
||||||
int, nnoise,
|
int, nnoise,
|
||||||
int, tsrc,
|
int, tsrc,
|
||||||
std::string, TI,
|
std::string, TI,
|
||||||
std::string, LI,
|
std::string, LI,
|
||||||
std::string, SI )
|
std::string, SI )
|
||||||
DistilParameters() = default;
|
DistilParameters() = default;
|
||||||
template <class ReaderClass> DistilParameters(Reader<ReaderClass>& Reader){read(Reader,"Distil",*this);}
|
template <class ReaderClass> DistilParameters(Reader<ReaderClass>& Reader){read(Reader,"Distil",*this);}
|
||||||
|
|
||||||
// Numeric parameter is allowed to be empty (in which case it = Default),
|
// Numeric parameter is allowed to be empty (in which case it = Default),
|
||||||
// but assert during setup() if specified but not numeric
|
// but assert during setup() if specified but not numeric
|
||||||
|
|
||||||
static int ParameterDefault( const std::string & s, int Default, bool bCalledFromSetup )
|
static int ParameterDefault( const std::string & s, int Default, bool bCalledFromSetup )
|
||||||
{
|
{
|
||||||
int i = Default;
|
int i = Default;
|
||||||
if( s.length() > 0 ) {
|
if( s.length() > 0 ) {
|
||||||
std::istringstream ss( s );
|
std::istringstream ss( s );
|
||||||
ss >> i;
|
ss >> i;
|
||||||
if( bCalledFromSetup )
|
if( bCalledFromSetup )
|
||||||
assert( !ss.fail() && "Parameter should either be empty or integer" );
|
assert( !ss.fail() && "Parameter should either be empty or integer" );
|
||||||
|
}
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
return i;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DISTIL_PARAMETERS_DEFINE( inSetup ) \
|
#define DISTIL_PARAMETERS_DEFINE( inSetup ) \
|
||||||
@ -88,54 +88,55 @@ const int Nt_inv{ full_tdil ? 1 : TI }
|
|||||||
|
|
||||||
inline GridCartesian * MakeLowerDimGrid( GridCartesian * gridHD )
|
inline GridCartesian * MakeLowerDimGrid( GridCartesian * gridHD )
|
||||||
{
|
{
|
||||||
int nd{static_cast<int>(gridHD->_ndimension)};
|
int nd{static_cast<int>(gridHD->_ndimension)};
|
||||||
Coordinate latt_size = gridHD->_gdimensions;
|
Coordinate latt_size = gridHD->_gdimensions;
|
||||||
latt_size[nd-1] = 1;
|
latt_size[nd-1] = 1;
|
||||||
Coordinate simd_layout = GridDefaultSimd(nd-1, vComplex::Nsimd());
|
Coordinate simd_layout = GridDefaultSimd(nd-1, vComplex::Nsimd());
|
||||||
simd_layout.push_back( 1 );
|
simd_layout.push_back( 1 );
|
||||||
Coordinate mpi_layout = gridHD->_processors;
|
Coordinate mpi_layout = gridHD->_processors;
|
||||||
mpi_layout[nd-1] = 1;
|
mpi_layout[nd-1] = 1;
|
||||||
GridCartesian * gridLD = new GridCartesian(latt_size,simd_layout,mpi_layout,*gridHD);
|
GridCartesian * gridLD = new GridCartesian(latt_size,simd_layout,mpi_layout,*gridHD);
|
||||||
return gridLD;
|
return gridLD;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************************
|
/*************************************************************************************
|
||||||
Rotate eigenvectors into our phase convention
|
Rotate eigenvectors into our phase convention
|
||||||
First component of first eigenvector is real and positive
|
First component of first eigenvector is real and positive
|
||||||
|
TODO: Should this be in Distil.hpp?
|
||||||
*************************************************************************************/
|
*************************************************************************************/
|
||||||
|
|
||||||
inline void RotateEigen(std::vector<LatticeColourVector> & evec)
|
inline void RotateEigen(std::vector<LatticeColourVector> & evec)
|
||||||
{
|
{
|
||||||
ColourVector cv0;
|
ColourVector cv0;
|
||||||
auto grid = evec[0].Grid();
|
auto grid = evec[0].Grid();
|
||||||
Coordinate siteFirst(grid->Nd(),0);
|
Coordinate siteFirst(grid->Nd(),0);
|
||||||
peekSite(cv0, evec[0], siteFirst);
|
peekSite(cv0, evec[0], siteFirst);
|
||||||
Grid::Complex cplx0 = cv0()()(0);
|
Grid::Complex cplx0 = cv0()()(0);
|
||||||
if( cplx0.imag() == 0 )
|
if( cplx0.imag() == 0 )
|
||||||
std::cout << GridLogMessage << "RotateEigen() : Site 0 : " << cplx0 << " => already meets phase convention" << std::endl;
|
std::cout << GridLogMessage << "RotateEigen() : Site 0 : " << cplx0 << " => already meets phase convention" << std::endl;
|
||||||
else {
|
else {
|
||||||
const Real cplx0_mag = Grid::abs(cplx0);
|
const Real cplx0_mag = Grid::abs(cplx0);
|
||||||
#ifdef GRID_NVCC
|
#ifdef GRID_NVCC
|
||||||
const Grid::Complex phase = thrust::conj(cplx0 / cplx0_mag);
|
const Grid::Complex phase = thrust::conj(cplx0 / cplx0_mag);
|
||||||
const Real argphase = thrust::arg(phase);
|
const Real argphase = thrust::arg(phase);
|
||||||
#else
|
#else
|
||||||
const Grid::Complex phase = std::conj(cplx0 / cplx0_mag);
|
const Grid::Complex phase = std::conj(cplx0 / cplx0_mag);
|
||||||
const Real argphase = std::arg(phase);
|
const Real argphase = std::arg(phase);
|
||||||
#endif
|
#endif
|
||||||
std::cout << GridLogMessage << "RotateEigen() : Site 0 : |" << cplx0 << "|=" << cplx0_mag << " => phase=" << (argphase / 3.14159265) << " pi" << std::endl;
|
std::cout << GridLogMessage << "RotateEigen() : Site 0 : |" << cplx0 << "|=" << cplx0_mag << " => phase=" << (argphase / 3.14159265) << " pi" << std::endl;
|
||||||
{
|
{
|
||||||
// TODO: Only really needed on the master slice
|
// TODO: Only really needed on the master slice
|
||||||
for( int k = 0 ; k < evec.size() ; k++ )
|
for( int k = 0 ; k < evec.size() ; k++ )
|
||||||
evec[k] *= phase;
|
evec[k] *= phase;
|
||||||
if(grid->IsBoss()){
|
if(grid->IsBoss()){
|
||||||
for( int c = 0 ; c < Nc ; c++ )
|
for( int c = 0 ; c < Nc ; c++ )
|
||||||
cv0()()(c) *= phase;
|
cv0()()(c) *= phase;
|
||||||
cplx0.imag(0); // This assumes phase convention is real, positive (so I get rid of rounding error)
|
cplx0.imag(0); // This assumes phase convention is real, positive (so I get rid of rounding error)
|
||||||
//pokeSite(cv0, evec[0], siteFirst);
|
//pokeSite(cv0, evec[0], siteFirst);
|
||||||
pokeLocalSite(cv0, evec[0], siteFirst);
|
pokeLocalSite(cv0, evec[0], siteFirst);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
END_MODULE_NAMESPACE
|
END_MODULE_NAMESPACE
|
||||||
|
@ -43,47 +43,47 @@ BEGIN_MODULE_NAMESPACE(MDistil)
|
|||||||
class DistilVectorsPar: Serializable
|
class DistilVectorsPar: Serializable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GRID_SERIALIZABLE_CLASS_MEMBERS(DistilVectorsPar,
|
GRID_SERIALIZABLE_CLASS_MEMBERS(DistilVectorsPar,
|
||||||
std::string, noise,
|
std::string, noise,
|
||||||
std::string, perambulator,
|
std::string, perambulator,
|
||||||
std::string, lapevec,
|
std::string, lapevec,
|
||||||
std::string, source,
|
std::string, source,
|
||||||
std::string, sink,
|
std::string, sink,
|
||||||
int, tsrc,
|
int, tsrc,
|
||||||
std::string, nvec,
|
std::string, nvec,
|
||||||
std::string, TI)
|
std::string, TI)
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
class TDistilVectors: public Module<DistilVectorsPar>
|
class TDistilVectors: public Module<DistilVectorsPar>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FERM_TYPE_ALIASES(FImpl,);
|
FERM_TYPE_ALIASES(FImpl,);
|
||||||
// constructor
|
// constructor
|
||||||
TDistilVectors(const std::string name);
|
TDistilVectors(const std::string name);
|
||||||
// destructor
|
// destructor
|
||||||
virtual ~TDistilVectors(void);
|
virtual ~TDistilVectors(void);
|
||||||
// dependency relation
|
// dependency relation
|
||||||
virtual std::vector<std::string> getInput(void);
|
virtual std::vector<std::string> getInput(void);
|
||||||
virtual std::vector<std::string> getOutput(void);
|
virtual std::vector<std::string> getOutput(void);
|
||||||
// setup
|
// setup
|
||||||
virtual void setup(void);
|
virtual void setup(void);
|
||||||
// execution
|
// execution
|
||||||
virtual void execute(void);
|
virtual void execute(void);
|
||||||
protected:
|
protected:
|
||||||
// These variables are created in setup() and freed in Cleanup()
|
// These variables are created in setup() and freed in Cleanup()
|
||||||
GridCartesian * grid3d; // Owned by me, so I must delete it
|
GridCartesian * grid3d; // Owned by me, so I must delete it
|
||||||
GridCartesian * grid4d; // Owned by environment (so I won't delete it)
|
GridCartesian * grid4d; // Owned by environment (so I won't delete it)
|
||||||
virtual void Cleanup(void);
|
virtual void Cleanup(void);
|
||||||
public:
|
public:
|
||||||
// These variables contain parameters
|
// These variables contain parameters
|
||||||
std::string PerambulatorName;
|
std::string PerambulatorName;
|
||||||
std::string NoiseVectorName;
|
std::string NoiseVectorName;
|
||||||
std::string LapEvecName;
|
std::string LapEvecName;
|
||||||
bool bMakeSource;
|
bool bMakeSource;
|
||||||
bool bMakeSink;
|
bool bMakeSink;
|
||||||
std::string SourceName;
|
std::string SourceName;
|
||||||
std::string SinkName;
|
std::string SinkName;
|
||||||
};
|
};
|
||||||
|
|
||||||
MODULE_REGISTER_TMP(DistilVectors, TDistilVectors<FIMPL>, MDistil);
|
MODULE_REGISTER_TMP(DistilVectors, TDistilVectors<FIMPL>, MDistil);
|
||||||
@ -100,193 +100,196 @@ TDistilVectors<FImpl>::TDistilVectors(const std::string name)
|
|||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
TDistilVectors<FImpl>::~TDistilVectors(void)
|
TDistilVectors<FImpl>::~TDistilVectors(void)
|
||||||
{
|
{
|
||||||
Cleanup();
|
Cleanup();
|
||||||
};
|
};
|
||||||
|
|
||||||
// dependencies/products ///////////////////////////////////////////////////////
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
std::vector<std::string> TDistilVectors<FImpl>::getInput(void)
|
std::vector<std::string> TDistilVectors<FImpl>::getInput(void)
|
||||||
{
|
{
|
||||||
PerambulatorName = par().perambulator;
|
PerambulatorName = par().perambulator;
|
||||||
if( PerambulatorName.size() == 0 ) {
|
if (PerambulatorName.empty())
|
||||||
PerambulatorName = getName();
|
{
|
||||||
PerambulatorName.append( "_peramb" );
|
PerambulatorName = getName();
|
||||||
}
|
PerambulatorName.append("_peramb");
|
||||||
NoiseVectorName = par().noise;
|
}
|
||||||
if( NoiseVectorName.size() == 0 ) {
|
NoiseVectorName = par().noise;
|
||||||
NoiseVectorName = PerambulatorName;
|
if (NoiseVectorName.empty())
|
||||||
NoiseVectorName.append( "_noise" );
|
{
|
||||||
}
|
NoiseVectorName = PerambulatorName;
|
||||||
LapEvecName = par().lapevec;
|
NoiseVectorName.append("_noise");
|
||||||
if( LapEvecName.size() == 0 ) {
|
}
|
||||||
LapEvecName = PerambulatorName;
|
LapEvecName = par().lapevec;
|
||||||
LapEvecName.append( "_lapevec" );
|
if (LapEvecName.empty())
|
||||||
}
|
{
|
||||||
return { PerambulatorName, NoiseVectorName, LapEvecName };
|
LapEvecName = PerambulatorName;
|
||||||
|
LapEvecName.append("_lapevec");
|
||||||
|
}
|
||||||
|
return { PerambulatorName, NoiseVectorName, LapEvecName };
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
std::vector<std::string> TDistilVectors<FImpl>::getOutput(void)
|
std::vector<std::string> TDistilVectors<FImpl>::getOutput(void)
|
||||||
{
|
{
|
||||||
SourceName = par().source;
|
SourceName = par().source;
|
||||||
SinkName = par().sink;
|
SinkName = par().sink;
|
||||||
bMakeSource = ( SourceName.size() > 0 );
|
bMakeSource = ( SourceName.size() > 0 );
|
||||||
bMakeSink = ( SinkName.size() > 0 );
|
bMakeSink = ( SinkName.size() > 0 );
|
||||||
if( !bMakeSource && !bMakeSink ) {
|
if (!bMakeSource && !bMakeSink)
|
||||||
SourceName = getName();
|
{
|
||||||
SinkName = SourceName;
|
SourceName = getName();
|
||||||
SourceName.append( "_rho" );
|
SinkName = SourceName;
|
||||||
SinkName.append( "_phi" );
|
SourceName.append("_rho");
|
||||||
bMakeSource = true;
|
SinkName.append("_phi");
|
||||||
bMakeSink = true;
|
bMakeSource = true;
|
||||||
}
|
bMakeSink = true;
|
||||||
std::vector<std::string> out;
|
}
|
||||||
if( bMakeSource )
|
std::vector<std::string> out;
|
||||||
out.push_back( SourceName );
|
if (bMakeSource)
|
||||||
if( bMakeSink )
|
out.push_back(SourceName);
|
||||||
out.push_back( SinkName );
|
if (bMakeSink)
|
||||||
return out;
|
out.push_back(SinkName);
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup ///////////////////////////////////////////////////////////////////////
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
void TDistilVectors<FImpl>::setup(void)
|
void TDistilVectors<FImpl>::setup(void)
|
||||||
{
|
{
|
||||||
Cleanup();
|
Cleanup();
|
||||||
auto &noise = envGet(NoiseTensor, NoiseVectorName);
|
auto &noise = envGet(NoiseTensor, NoiseVectorName);
|
||||||
auto &perambulator = envGet(PerambTensor, PerambulatorName);
|
auto &perambulator = envGet(PerambTensor, PerambulatorName);
|
||||||
|
|
||||||
// We expect the perambulator to have been created with these indices
|
// We expect the perambulator to have been created with these indices
|
||||||
assert( perambulator.ValidateIndexNames() && "Perambulator index names bad" );
|
assert( perambulator.ValidateIndexNames() && "Perambulator index names bad" );
|
||||||
|
|
||||||
const int Nt{ env().getDim(Tdir) };
|
const int Nt{ env().getDim(Tdir) };
|
||||||
assert( Nt == static_cast<int>( perambulator.tensor.dimension(0) ) && "PerambTensor time dimensionality bad" );
|
assert( Nt == static_cast<int>( perambulator.tensor.dimension(0) ) && "PerambTensor time dimensionality bad" );
|
||||||
const int TI{ Hadrons::MDistil::DistilParameters::ParameterDefault( par().TI, Nt, true) };
|
const int LI{ static_cast<int>( perambulator.tensor.dimension(2) ) };
|
||||||
const int LI{ static_cast<int>( perambulator.tensor.dimension(2) ) };
|
const int SI{ static_cast<int>( perambulator.tensor.dimension(5) ) };
|
||||||
const int SI{ static_cast<int>( perambulator.tensor.dimension(5) ) };
|
const int Nt_inv{ static_cast<int>( perambulator.tensor.dimension(4) ) };
|
||||||
const int Nt_inv{ static_cast<int>( perambulator.tensor.dimension(4) ) };
|
const int nnoise{ static_cast<int>( perambulator.tensor.dimension(3) ) };
|
||||||
const int nnoise{ static_cast<int>( perambulator.tensor.dimension(3) ) };
|
assert( nnoise >= static_cast<int>( noise.dimension(0) ) && "Not enough noise vectors for perambulator" );
|
||||||
assert( nnoise >= static_cast<int>( noise.dimension(0) ) && "Not enough noise vectors for perambulator" );
|
// Nvec defaults to what's in the perambulator unless overriden
|
||||||
// Nvec defaults to what's in the perambulator unless overriden
|
const int nvec_per{ static_cast<int>( perambulator.tensor.dimension(1) ) };
|
||||||
const int nvec_per{ static_cast<int>( perambulator.tensor.dimension(1) ) };
|
const int nvec{Hadrons::MDistil::DistilParameters::ParameterDefault(par().nvec, nvec_per, true) };
|
||||||
const int nvec{Hadrons::MDistil::DistilParameters::ParameterDefault(par().nvec, nvec_per, true) };
|
assert( nvec <= nvec_per && "Not enough distillation sub-space vectors" );
|
||||||
assert( nvec <= nvec_per && "Not enough distillation sub-space vectors" );
|
|
||||||
|
if (bMakeSource)
|
||||||
if( bMakeSource )
|
envCreate(std::vector<FermionField>, SourceName, 1, nnoise*LI*SI*Nt_inv, envGetGrid(FermionField));
|
||||||
envCreate(std::vector<FermionField>, SourceName, 1, nnoise*LI*SI*Nt_inv, envGetGrid(FermionField));
|
if (bMakeSink)
|
||||||
if( bMakeSink )
|
envCreate(std::vector<FermionField>, SinkName, 1, nnoise*LI*SI*Nt_inv, envGetGrid(FermionField));
|
||||||
envCreate(std::vector<FermionField>, SinkName, 1, nnoise*LI*SI*Nt_inv, envGetGrid(FermionField));
|
|
||||||
|
grid4d = env().getGrid();
|
||||||
grid4d = env().getGrid();
|
Coordinate latt_size = GridDefaultLatt();
|
||||||
Coordinate latt_size = GridDefaultLatt();
|
Coordinate mpi_layout = GridDefaultMpi();
|
||||||
Coordinate simd_layout = GridDefaultSimd(Nd, vComplex::Nsimd());
|
Coordinate simd_layout_3 = GridDefaultSimd(Nd-1, vComplex::Nsimd());
|
||||||
Coordinate mpi_layout = GridDefaultMpi();
|
latt_size[Nd-1] = 1;
|
||||||
Coordinate simd_layout_3 = GridDefaultSimd(Nd-1, vComplex::Nsimd());
|
simd_layout_3.push_back( 1 );
|
||||||
latt_size[Nd-1] = 1;
|
mpi_layout[Nd-1] = 1;
|
||||||
simd_layout_3.push_back( 1 );
|
grid3d = MakeLowerDimGrid(grid4d);
|
||||||
mpi_layout[Nd-1] = 1;
|
|
||||||
grid3d = MakeLowerDimGrid(grid4d);
|
envTmp(LatticeSpinColourVector, "tmp2",1,LatticeSpinColourVector(grid4d));
|
||||||
|
envTmp(LatticeSpinColourVector, "tmp3d",1,LatticeSpinColourVector(grid3d));
|
||||||
|
envTmp(LatticeColourVector, "tmp3d_nospin",1,LatticeColourVector(grid3d));
|
||||||
envTmp(LatticeSpinColourVector, "tmp2",1,LatticeSpinColourVector(grid4d));
|
envTmp(LatticeSpinColourVector, "sink_tslice",1,LatticeSpinColourVector(grid3d));
|
||||||
envTmp(LatticeSpinColourVector, "tmp3d",1,LatticeSpinColourVector(grid3d));
|
envTmp(LatticeColourVector, "evec3d",1,LatticeColourVector(grid3d));
|
||||||
envTmp(LatticeColourVector, "tmp3d_nospin",1,LatticeColourVector(grid3d));
|
|
||||||
envTmp(LatticeSpinColourVector, "sink_tslice",1,LatticeSpinColourVector(grid3d));
|
|
||||||
envTmp(LatticeColourVector, "evec3d",1,LatticeColourVector(grid3d));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// clean up any temporaries created by setup (that aren't stored in the environment)
|
// clean up any temporaries created by setup (that aren't stored in the environment)
|
||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
void TDistilVectors<FImpl>::Cleanup(void)
|
void TDistilVectors<FImpl>::Cleanup(void)
|
||||||
{
|
{
|
||||||
if( grid3d != nullptr ) {
|
if ( grid3d != nullptr)
|
||||||
delete grid3d;
|
{
|
||||||
grid3d = nullptr;
|
delete grid3d;
|
||||||
}
|
grid3d = nullptr;
|
||||||
grid4d = nullptr;
|
}
|
||||||
|
grid4d = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// execution ///////////////////////////////////////////////////////////////////
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
void TDistilVectors<FImpl>::execute(void)
|
void TDistilVectors<FImpl>::execute(void)
|
||||||
{
|
{
|
||||||
auto &noise = envGet(NoiseTensor, NoiseVectorName);
|
auto &noise = envGet(NoiseTensor, NoiseVectorName);
|
||||||
auto &perambulator = envGet(PerambTensor, PerambulatorName);
|
auto &perambulator = envGet(PerambTensor, PerambulatorName);
|
||||||
auto &epack = envGet(Grid::Hadrons::EigenPack<LatticeColourVector>, LapEvecName);
|
auto &epack = envGet(Grid::Hadrons::EigenPack<LatticeColourVector>, LapEvecName);
|
||||||
|
|
||||||
envGetTmp(LatticeSpinColourVector, tmp2);
|
envGetTmp(LatticeSpinColourVector, tmp2);
|
||||||
envGetTmp(LatticeSpinColourVector, tmp3d);
|
envGetTmp(LatticeSpinColourVector, tmp3d);
|
||||||
envGetTmp(LatticeColourVector, tmp3d_nospin);
|
envGetTmp(LatticeColourVector, tmp3d_nospin);
|
||||||
envGetTmp(LatticeSpinColourVector, sink_tslice);
|
envGetTmp(LatticeSpinColourVector, sink_tslice);
|
||||||
envGetTmp(LatticeColourVector, evec3d);
|
envGetTmp(LatticeColourVector, evec3d);
|
||||||
|
|
||||||
const int Ntlocal{ grid4d->LocalDimensions()[3] };
|
const int Ntlocal{ grid4d->LocalDimensions()[3] };
|
||||||
const int Ntfirst{ grid4d->LocalStarts()[3] };
|
const int Ntfirst{ grid4d->LocalStarts()[3] };
|
||||||
|
|
||||||
const int Nt{ env().getDim(Tdir) };
|
const int Nt{ env().getDim(Tdir) };
|
||||||
const int TI{ Hadrons::MDistil::DistilParameters::ParameterDefault( par().TI, Nt, false ) };
|
const int TI{ Hadrons::MDistil::DistilParameters::ParameterDefault( par().TI, Nt, false ) };
|
||||||
const int LI{ static_cast<int>( perambulator.tensor.dimension(2) ) };
|
const int LI{ static_cast<int>( perambulator.tensor.dimension(2) ) };
|
||||||
const int SI{ static_cast<int>( perambulator.tensor.dimension(5) ) };
|
const int SI{ static_cast<int>( perambulator.tensor.dimension(5) ) };
|
||||||
const int Nt_inv{ static_cast<int>( perambulator.tensor.dimension(4) ) };
|
const int Nt_inv{ static_cast<int>( perambulator.tensor.dimension(4) ) };
|
||||||
const int nnoise{ static_cast<int>( perambulator.tensor.dimension(3) ) };
|
const int nnoise{ static_cast<int>( perambulator.tensor.dimension(3) ) };
|
||||||
// Nvec defaults to what's in the perambulator unless overriden
|
// Nvec defaults to what's in the perambulator unless overriden
|
||||||
const int nvec{Hadrons::MDistil::DistilParameters::ParameterDefault(par().nvec, static_cast<int>( perambulator.tensor.dimension(1) ), false)};
|
const int nvec{Hadrons::MDistil::DistilParameters::ParameterDefault(par().nvec, static_cast<int>( perambulator.tensor.dimension(1) ), false)};
|
||||||
const int tsrc{ par().tsrc };
|
const int tsrc{ par().tsrc };
|
||||||
const bool full_tdil{ TI==Nt };
|
const bool full_tdil{ TI==Nt };
|
||||||
|
|
||||||
int vecindex;
|
int vecindex;
|
||||||
int t_inv;
|
int t_inv;
|
||||||
if( bMakeSource ) {
|
if (bMakeSource)
|
||||||
auto &rho = envGet(std::vector<FermionField>, SourceName);
|
{
|
||||||
for( int inoise = 0; inoise < nnoise; inoise++ ) {
|
auto &rho = envGet(std::vector<FermionField>, SourceName);
|
||||||
for( int dk = 0; dk < LI; dk++ ) {
|
for (int inoise = 0; inoise < nnoise; inoise++) {
|
||||||
for( int dt = 0; dt < Nt_inv; dt++ ) {
|
for (int dk = 0; dk < LI; dk++) {
|
||||||
for( int ds = 0; ds < SI; ds++ ) {
|
for (int dt = 0; dt < Nt_inv; dt++) {
|
||||||
vecindex = inoise + nnoise * dk + nnoise * LI * ds + nnoise *LI * SI*dt;
|
for (int ds = 0; ds < SI; ds++) {
|
||||||
rho[vecindex] = 0;
|
vecindex = inoise + nnoise * dk + nnoise * LI * ds + nnoise *LI * SI*dt;
|
||||||
tmp3d_nospin = 0;
|
rho[vecindex] = 0;
|
||||||
for (int it = dt; it < Nt; it += TI){
|
tmp3d_nospin = 0;
|
||||||
if (full_tdil) t_inv = tsrc; else t_inv = it;
|
for (int it = dt; it < Nt; it += TI){
|
||||||
if( t_inv >= Ntfirst && t_inv < Ntfirst + Ntlocal ) {
|
if (full_tdil) t_inv = tsrc; else t_inv = it;
|
||||||
for (int ik = dk; ik < nvec; ik += LI){
|
if (t_inv >= Ntfirst && t_inv < Ntfirst + Ntlocal) {
|
||||||
for (int is = ds; is < Ns; is += SI){
|
for (int ik = dk; ik < nvec; ik += LI){
|
||||||
ExtractSliceLocal(evec3d,epack.evec[ik],0,t_inv-Ntfirst,Tdir);
|
for (int is = ds; is < Ns; is += SI){
|
||||||
tmp3d_nospin = evec3d * noise(inoise, t_inv, ik, is);
|
ExtractSliceLocal(evec3d,epack.evec[ik],0,t_inv-Ntfirst,Tdir);
|
||||||
tmp3d=0;
|
tmp3d_nospin = evec3d * noise(inoise, t_inv, ik, is);
|
||||||
pokeSpin(tmp3d,tmp3d_nospin,is);
|
tmp3d=0;
|
||||||
tmp2=0;
|
pokeSpin(tmp3d,tmp3d_nospin,is);
|
||||||
InsertSliceLocal(tmp3d,tmp2,0,t_inv-Ntfirst,Tdir);
|
tmp2=0;
|
||||||
rho[vecindex] += tmp2;
|
InsertSliceLocal(tmp3d,tmp2,0,t_inv-Ntfirst,Tdir);
|
||||||
}
|
rho[vecindex] += tmp2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
if (bMakeSink) {
|
||||||
if( bMakeSink ) {
|
auto &phi = envGet(std::vector<FermionField>, SinkName);
|
||||||
auto &phi = envGet(std::vector<FermionField>, SinkName);
|
for (int inoise = 0; inoise < nnoise; inoise++) {
|
||||||
for( int inoise = 0; inoise < nnoise; inoise++ ) {
|
for (int dk = 0; dk < LI; dk++) {
|
||||||
for( int dk = 0; dk < LI; dk++ ) {
|
for (int dt = 0; dt < Nt_inv; dt++) {
|
||||||
for( int dt = 0; dt < Nt_inv; dt++ ) {
|
for (int ds = 0; ds < SI; ds++) {
|
||||||
for( int ds = 0; ds < SI; ds++ ) {
|
vecindex = inoise + nnoise * dk + nnoise * LI * ds + nnoise *LI * SI*dt;
|
||||||
vecindex = inoise + nnoise * dk + nnoise * LI * ds + nnoise *LI * SI*dt;
|
phi[vecindex] = 0;
|
||||||
phi[vecindex] = 0;
|
for (int t = Ntfirst; t < Ntfirst + Ntlocal; t++) {
|
||||||
for (int t = Ntfirst; t < Ntfirst + Ntlocal; t++) {
|
sink_tslice=0;
|
||||||
sink_tslice=0;
|
for (int ivec = 0; ivec < nvec; ivec++) {
|
||||||
for (int ivec = 0; ivec < nvec; ivec++) {
|
ExtractSliceLocal(evec3d,epack.evec[ivec],0,t-Ntfirst,Tdir);
|
||||||
ExtractSliceLocal(evec3d,epack.evec[ivec],0,t-Ntfirst,Tdir);
|
sink_tslice += evec3d * perambulator.tensor(t, ivec, dk, inoise,dt,ds);
|
||||||
sink_tslice += evec3d * perambulator.tensor(t, ivec, dk, inoise,dt,ds);
|
}
|
||||||
}
|
InsertSliceLocal(sink_tslice,phi[vecindex],0,t-Ntfirst,Tdir);
|
||||||
InsertSliceLocal(sink_tslice,phi[vecindex],0,t-Ntfirst,Tdir);
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
END_MODULE_NAMESPACE
|
END_MODULE_NAMESPACE
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
Grid physics library, www.github.com/paboyle/Grid
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
Source file: Hadrons/Modules/MDistil/LapEvec.hpp
|
Source file: Hadrons/Modules/MDistil/LapEvec.hpp
|
||||||
|
|
||||||
Copyright (C) 2019
|
Copyright (C) 2019
|
||||||
|
|
||||||
Author: Felix Erben <ferben@ed.ac.uk>
|
Author: Felix Erben <ferben@ed.ac.uk>
|
||||||
Author: Michael Marshall <Michael.Marshall@ed.ac.uk>
|
Author: Michael Marshall <Michael.Marshall@ed.ac.uk>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
@ -36,48 +36,48 @@ BEGIN_HADRONS_NAMESPACE
|
|||||||
BEGIN_MODULE_NAMESPACE(MDistil)
|
BEGIN_MODULE_NAMESPACE(MDistil)
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
|
||||||
Laplacian eigenvectors - parameters
|
Laplacian eigenvectors - parameters
|
||||||
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
struct StoutParameters: Serializable {
|
struct StoutParameters: Serializable {
|
||||||
GRID_SERIALIZABLE_CLASS_MEMBERS(StoutParameters,
|
GRID_SERIALIZABLE_CLASS_MEMBERS(StoutParameters,
|
||||||
int, steps,
|
int, steps,
|
||||||
double, rho)
|
double, rho)
|
||||||
StoutParameters() = default;
|
StoutParameters() = default;
|
||||||
template <class ReaderClass> StoutParameters(Reader<ReaderClass>& Reader){read(Reader,"StoutSmearing",*this);}
|
template <class ReaderClass> StoutParameters(Reader<ReaderClass>& Reader){read(Reader,"StoutSmearing",*this);}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ChebyshevParameters: Serializable {
|
struct ChebyshevParameters: Serializable {
|
||||||
GRID_SERIALIZABLE_CLASS_MEMBERS(ChebyshevParameters,
|
GRID_SERIALIZABLE_CLASS_MEMBERS(ChebyshevParameters,
|
||||||
int, PolyOrder,
|
int, PolyOrder,
|
||||||
double, alpha,
|
double, alpha,
|
||||||
double, beta)
|
double, beta)
|
||||||
ChebyshevParameters() = default;
|
ChebyshevParameters() = default;
|
||||||
template <class ReaderClass> ChebyshevParameters(Reader<ReaderClass>& Reader){read(Reader,"Chebyshev",*this);}
|
template <class ReaderClass> ChebyshevParameters(Reader<ReaderClass>& Reader){read(Reader,"Chebyshev",*this);}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LanczosParameters: Serializable {
|
struct LanczosParameters: Serializable {
|
||||||
GRID_SERIALIZABLE_CLASS_MEMBERS(LanczosParameters,
|
GRID_SERIALIZABLE_CLASS_MEMBERS(LanczosParameters,
|
||||||
int, Nvec,
|
int, Nvec,
|
||||||
int, Nk,
|
int, Nk,
|
||||||
int, Np,
|
int, Np,
|
||||||
int, MaxIt,
|
int, MaxIt,
|
||||||
double, resid,
|
double, resid,
|
||||||
int, IRLLog)
|
int, IRLLog)
|
||||||
LanczosParameters() = default;
|
LanczosParameters() = default;
|
||||||
template <class ReaderClass> LanczosParameters(Reader<ReaderClass>& Reader){read(Reader,"Lanczos",*this);}
|
template <class ReaderClass> LanczosParameters(Reader<ReaderClass>& Reader){read(Reader,"Lanczos",*this);}
|
||||||
};
|
};
|
||||||
|
|
||||||
// These are the actual parameters passed to the module during construction
|
// These are the actual parameters passed to the module during construction
|
||||||
|
|
||||||
struct LapEvecPar: Serializable {
|
struct LapEvecPar: Serializable {
|
||||||
GRID_SERIALIZABLE_CLASS_MEMBERS(LapEvecPar
|
GRID_SERIALIZABLE_CLASS_MEMBERS(LapEvecPar
|
||||||
,std::string, gauge
|
,std::string, gauge
|
||||||
,StoutParameters, Stout
|
,StoutParameters, Stout
|
||||||
,ChebyshevParameters, Cheby
|
,ChebyshevParameters, Cheby
|
||||||
,LanczosParameters, Lanczos)
|
,LanczosParameters, Lanczos)
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
@ -90,25 +90,25 @@ template <typename GImpl>
|
|||||||
class TLapEvec: public Module<LapEvecPar>
|
class TLapEvec: public Module<LapEvecPar>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GAUGE_TYPE_ALIASES(GImpl,);
|
GAUGE_TYPE_ALIASES(GImpl,);
|
||||||
// constructor
|
// constructor
|
||||||
TLapEvec(const std::string name);
|
TLapEvec(const std::string name);
|
||||||
// destructor
|
// destructor
|
||||||
virtual ~TLapEvec(void);
|
virtual ~TLapEvec(void);
|
||||||
// dependency relation
|
// dependency relation
|
||||||
virtual std::vector<std::string> getInput(void);
|
virtual std::vector<std::string> getInput(void);
|
||||||
virtual std::vector<std::string> getOutput(void);
|
virtual std::vector<std::string> getOutput(void);
|
||||||
// setup
|
// setup
|
||||||
virtual void setup(void);
|
virtual void setup(void);
|
||||||
// execution
|
// execution
|
||||||
virtual void execute(void);
|
virtual void execute(void);
|
||||||
protected:
|
protected:
|
||||||
// These variables are created in setup() and freed in Cleanup()
|
// These variables are created in setup() and freed in Cleanup()
|
||||||
GridCartesian * gridLD; // Owned by me, so I must delete it
|
GridCartesian * gridLD; // Owned by me, so I must delete it
|
||||||
GridCartesian * gridHD; // Owned by environment (so I won't delete it)
|
GridCartesian * gridHD; // Owned by environment (so I won't delete it)
|
||||||
std::string sGaugeName;
|
std::string sGaugeName;
|
||||||
protected:
|
protected:
|
||||||
virtual void Cleanup(void);
|
virtual void Cleanup(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
MODULE_REGISTER_TMP(LapEvec, TLapEvec<GIMPL>, MDistil);
|
MODULE_REGISTER_TMP(LapEvec, TLapEvec<GIMPL>, MDistil);
|
||||||
@ -127,19 +127,20 @@ TLapEvec<GImpl>::TLapEvec(const std::string name) : gridLD{nullptr}, Module<LapE
|
|||||||
template <typename GImpl>
|
template <typename GImpl>
|
||||||
TLapEvec<GImpl>::~TLapEvec()
|
TLapEvec<GImpl>::~TLapEvec()
|
||||||
{
|
{
|
||||||
Cleanup();
|
Cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
// dependencies/products ///////////////////////////////////////////////////////
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
template <typename GImpl>
|
template <typename GImpl>
|
||||||
std::vector<std::string> TLapEvec<GImpl>::getInput(void)
|
std::vector<std::string> TLapEvec<GImpl>::getInput(void)
|
||||||
{
|
{
|
||||||
sGaugeName = par().gauge;
|
sGaugeName = par().gauge;
|
||||||
if( sGaugeName.size() == 0 ) {
|
if (sGaugeName.empty())
|
||||||
sGaugeName = getName();
|
{
|
||||||
sGaugeName.append( "_gauge" );
|
sGaugeName = getName();
|
||||||
}
|
sGaugeName.append( "_gauge" );
|
||||||
return std::vector<std::string>{ sGaugeName };
|
}
|
||||||
|
return std::vector<std::string>{ sGaugeName };
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename GImpl>
|
template <typename GImpl>
|
||||||
@ -153,34 +154,35 @@ std::vector<std::string> TLapEvec<GImpl>::getOutput(void)
|
|||||||
template <typename GImpl>
|
template <typename GImpl>
|
||||||
void TLapEvec<GImpl>::setup(void)
|
void TLapEvec<GImpl>::setup(void)
|
||||||
{
|
{
|
||||||
Cleanup();
|
Cleanup();
|
||||||
Environment & e{env()};
|
Environment & e{env()};
|
||||||
gridHD = e.getGrid();
|
gridHD = e.getGrid();
|
||||||
gridLD = MakeLowerDimGrid( gridHD );
|
gridLD = MakeLowerDimGrid( gridHD );
|
||||||
const int Ntlocal{gridHD->LocalDimensions()[Tdir]};
|
const int Ntlocal{gridHD->LocalDimensions()[Tdir]};
|
||||||
// Temporaries
|
// Temporaries
|
||||||
envTmpLat(GaugeField, "Umu_stout");
|
envTmpLat(GaugeField, "Umu_stout");
|
||||||
envTmpLat(GaugeField, "Umu_smear");
|
envTmpLat(GaugeField, "Umu_smear");
|
||||||
envTmp(LatticeGaugeField, "UmuNoTime",1,LatticeGaugeField(gridLD));
|
envTmp(LatticeGaugeField, "UmuNoTime",1,LatticeGaugeField(gridLD));
|
||||||
envTmp(LatticeColourVector, "src",1,LatticeColourVector(gridLD));
|
envTmp(LatticeColourVector, "src",1,LatticeColourVector(gridLD));
|
||||||
envTmp(std::vector<LapEvecs>, "eig",1,std::vector<LapEvecs>(Ntlocal));
|
envTmp(std::vector<LapEvecs>, "eig",1,std::vector<LapEvecs>(Ntlocal));
|
||||||
// Output objects
|
// Output objects
|
||||||
envCreate(LapEvecs, getName(), 1, par().Lanczos.Nvec, gridHD );
|
envCreate(LapEvecs, getName(), 1, par().Lanczos.Nvec, gridHD );
|
||||||
}
|
}
|
||||||
|
|
||||||
// clean up any temporaries created by setup (that aren't stored in the environment)
|
// clean up any temporaries created by setup (that aren't stored in the environment)
|
||||||
template <typename GImpl>
|
template <typename GImpl>
|
||||||
void TLapEvec<GImpl>::Cleanup(void)
|
void TLapEvec<GImpl>::Cleanup(void)
|
||||||
{
|
{
|
||||||
if( gridLD != nullptr ) {
|
if (gridLD != nullptr)
|
||||||
delete gridLD;
|
{
|
||||||
gridLD = nullptr;
|
delete gridLD;
|
||||||
}
|
gridLD = nullptr;
|
||||||
gridHD = nullptr;
|
}
|
||||||
|
gridHD = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************************
|
/*************************************************************************************
|
||||||
|
|
||||||
-Grad^2 (Peardon, 2009, pg 2, equation 3, https://arxiv.org/abs/0905.2160)
|
-Grad^2 (Peardon, 2009, pg 2, equation 3, https://arxiv.org/abs/0905.2160)
|
||||||
Field Type of field the operator will be applied to
|
Field Type of field the operator will be applied to
|
||||||
GaugeField Gauge field the operator will smear using
|
GaugeField Gauge field the operator will smear using
|
||||||
@ -189,55 +191,52 @@ void TLapEvec<GImpl>::Cleanup(void)
|
|||||||
|
|
||||||
template<typename Field, typename GaugeField=LatticeGaugeField>
|
template<typename Field, typename GaugeField=LatticeGaugeField>
|
||||||
class Laplacian3D : public LinearOperatorBase<Field>, public LinearFunction<Field> {
|
class Laplacian3D : public LinearOperatorBase<Field>, public LinearFunction<Field> {
|
||||||
typedef typename GaugeField::vector_type vCoeff_t;
|
|
||||||
protected: // I don't really mind if _gf is messed with ... so make this public?
|
|
||||||
//GaugeField & _gf;
|
|
||||||
int nd; // number of spatial dimensions
|
|
||||||
std::vector<Lattice<iColourMatrix<vCoeff_t> > > U;
|
|
||||||
public:
|
|
||||||
// Construct this operator given a gauge field and the number of dimensions it should act on
|
|
||||||
Laplacian3D( GaugeField& gf, int dimSpatial = Tdir ) : /*_gf(gf),*/ nd{dimSpatial} {
|
|
||||||
assert(dimSpatial>=1);
|
|
||||||
for( int mu = 0 ; mu < nd ; mu++ )
|
|
||||||
U.push_back(PeekIndex<LorentzIndex>(gf,mu));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply this operator to "in", return result in "out"
|
|
||||||
void operator()(const Field& in, Field& out) {
|
|
||||||
assert( nd <= in.Grid()->Nd() );
|
|
||||||
conformable( in, out );
|
|
||||||
out = ( ( Real ) ( 2 * nd ) ) * in;
|
|
||||||
Field _tmp(in.Grid());
|
|
||||||
typedef typename GaugeField::vector_type vCoeff_t;
|
typedef typename GaugeField::vector_type vCoeff_t;
|
||||||
//Lattice<iColourMatrix<vCoeff_t> > U(in.Grid());
|
public:
|
||||||
for( int mu = 0 ; mu < nd ; mu++ ) {
|
int nd; // number of spatial dimensions
|
||||||
//U = PeekIndex<LorentzIndex>(_gf,mu);
|
std::vector<Lattice<iColourMatrix<vCoeff_t> > > U;
|
||||||
out -= U[mu] * Cshift( in, mu, 1);
|
// Construct this operator given a gauge field and the number of dimensions it should act on
|
||||||
_tmp = adj( U[mu] ) * in;
|
Laplacian3D( GaugeField& gf, int dimSpatial = Tdir ) : nd{dimSpatial}
|
||||||
out -= Cshift(_tmp,mu,-1);
|
{
|
||||||
|
assert(dimSpatial>=1);
|
||||||
|
for (int mu = 0 ; mu < nd ; mu++)
|
||||||
|
U.push_back(PeekIndex<LorentzIndex>(gf,mu));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// Apply this operator to "in", return result in "out"
|
||||||
void OpDiag (const Field &in, Field &out) { assert(0); };
|
void operator()(const Field& in, Field& out) {
|
||||||
void OpDir (const Field &in, Field &out,int dir,int disp) { assert(0); };
|
assert( nd <= in.Grid()->Nd() );
|
||||||
void Op (const Field &in, Field &out) { assert(0); };
|
conformable( in, out );
|
||||||
void AdjOp (const Field &in, Field &out) { assert(0); };
|
out = ( ( Real ) ( 2 * nd ) ) * in;
|
||||||
void HermOpAndNorm(const Field &in, Field &out,RealD &n1,RealD &n2) { assert(0); };
|
Field _tmp(in.Grid());
|
||||||
void HermOp(const Field &in, Field &out) { operator()(in,out); };
|
typedef typename GaugeField::vector_type vCoeff_t;
|
||||||
|
for (int mu = 0 ; mu < nd ; mu++)
|
||||||
|
{
|
||||||
|
out -= U[mu] * Cshift( in, mu, 1);
|
||||||
|
_tmp = adj( U[mu] ) * in;
|
||||||
|
out -= Cshift(_tmp,mu,-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpDiag (const Field &in, Field &out) { assert(0); };
|
||||||
|
void OpDir (const Field &in, Field &out,int dir,int disp) { assert(0); };
|
||||||
|
void Op (const Field &in, Field &out) { assert(0); };
|
||||||
|
void AdjOp (const Field &in, Field &out) { assert(0); };
|
||||||
|
void HermOpAndNorm(const Field &in, Field &out,RealD &n1,RealD &n2) { assert(0); };
|
||||||
|
void HermOp(const Field &in, Field &out) { operator()(in,out); };
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Field>
|
template<typename Field>
|
||||||
class Laplacian3DHerm : public LinearFunction<Field> {
|
class Laplacian3DHerm : public LinearFunction<Field> {
|
||||||
public:
|
public:
|
||||||
OperatorFunction<Field> & _poly;
|
OperatorFunction<Field> & _poly;
|
||||||
LinearOperatorBase<Field> &_Linop;
|
LinearOperatorBase<Field> &_Linop;
|
||||||
|
Laplacian3DHerm(OperatorFunction<Field> & poly,LinearOperatorBase<Field>& linop)
|
||||||
Laplacian3DHerm(OperatorFunction<Field> & poly,LinearOperatorBase<Field>& linop)
|
: _poly{poly}, _Linop{linop} {}
|
||||||
: _poly{poly}, _Linop{linop} {}
|
void operator()(const Field& in, Field& out)
|
||||||
|
{
|
||||||
void operator()(const Field& in, Field& out) {
|
_poly(_Linop,in,out);
|
||||||
_poly(_Linop,in,out);
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
@ -248,91 +247,93 @@ public:
|
|||||||
template <typename GImpl>
|
template <typename GImpl>
|
||||||
void TLapEvec<GImpl>::execute(void)
|
void TLapEvec<GImpl>::execute(void)
|
||||||
{
|
{
|
||||||
const ChebyshevParameters &ChebPar{par().Cheby};
|
const ChebyshevParameters &ChebPar{par().Cheby};
|
||||||
const LanczosParameters &LPar{par().Lanczos};
|
const LanczosParameters &LPar{par().Lanczos};
|
||||||
|
|
||||||
// Disable IRL logging if requested
|
|
||||||
LOG(Message) << "IRLLog=" << LPar.IRLLog << std::endl;
|
|
||||||
const int PreviousIRLLogState{GridLogIRL.isActive()};
|
|
||||||
GridLogIRL.Active( LPar.IRLLog == 0 ? 0 : 1 );
|
|
||||||
|
|
||||||
// Stout smearing
|
|
||||||
envGetTmp(GaugeField, Umu_smear);
|
|
||||||
Umu_smear = envGet(GaugeField, sGaugeName); // The smeared field starts off as the Gauge field
|
|
||||||
LOG(Message) << "Initial plaquette: " << WilsonLoops<PeriodicGimplR>::avgPlaquette(Umu_smear) << std::endl;
|
|
||||||
const StoutParameters &Stout{par().Stout};
|
|
||||||
if( Stout.steps )
|
|
||||||
{
|
|
||||||
envGetTmp(GaugeField, Umu_stout);
|
|
||||||
Smear_Stout<PeriodicGimplR> LS(Stout.rho, Tdir); // spatial smearing only
|
|
||||||
for (int i = 0; i < Stout.steps; i++) {
|
|
||||||
LS.smear(Umu_stout, Umu_smear);
|
|
||||||
Umu_smear = Umu_stout;
|
|
||||||
}
|
|
||||||
LOG(Message) << "Smeared plaquette: " << WilsonLoops<PeriodicGimplR>::avgPlaquette(Umu_smear) << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// Invert nabla operator separately on each time-slice
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
auto & eig4d = envGet(LapEvecs, getName() );
|
|
||||||
envGetTmp(std::vector<LapEvecs>, eig); // Eigenpack for each timeslice
|
|
||||||
envGetTmp(LatticeGaugeField, UmuNoTime); // Gauge field without time dimension
|
|
||||||
envGetTmp(LatticeColourVector, src);
|
|
||||||
const int Ntlocal{gridHD->LocalDimensions()[Tdir]};
|
|
||||||
const int Ntfirst{gridHD->LocalStarts()[Tdir]};
|
|
||||||
uint32_t ConvergenceErrors{0};
|
|
||||||
for(int t = 0; t < Ntlocal; t++ ) {
|
|
||||||
LOG(Message) << "------------------------------------------------------------" << std::endl;
|
|
||||||
LOG(Message) << " Compute eigenpack, local timeslice = " << t << " / " << Ntlocal << std::endl;
|
|
||||||
LOG(Message) << "------------------------------------------------------------" << std::endl;
|
|
||||||
eig[t].resize(LPar.Nk+LPar.Np,gridLD);
|
|
||||||
|
|
||||||
// Construct smearing operator
|
// Disable IRL logging if requested
|
||||||
ExtractSliceLocal(UmuNoTime,Umu_smear,0,t,Tdir); // switch to 3d/4d objects
|
LOG(Message) << "IRLLog=" << LPar.IRLLog << std::endl;
|
||||||
Laplacian3D<LatticeColourVector> Nabla(UmuNoTime);
|
const int PreviousIRLLogState{GridLogIRL.isActive()};
|
||||||
LOG(Debug) << "Chebyshev preconditioning to order " << ChebPar.PolyOrder
|
GridLogIRL.Active( LPar.IRLLog == 0 ? 0 : 1 );
|
||||||
<< " with parameters (alpha,beta) = (" << ChebPar.alpha << "," << ChebPar.beta << ")" << std::endl;
|
|
||||||
Chebyshev<LatticeColourVector> Cheb(ChebPar.alpha,ChebPar.beta,ChebPar.PolyOrder);
|
|
||||||
|
|
||||||
// Construct source vector according to Test_dwf_compressed_lanczos.cc
|
// Stout smearing
|
||||||
src = 11.0; //TODO: Why hard-coded 11?
|
envGetTmp(GaugeField, Umu_smear);
|
||||||
RealD nn = norm2(src);
|
Umu_smear = envGet(GaugeField, sGaugeName); // The smeared field starts off as the Gauge field
|
||||||
nn = Grid::sqrt(nn);
|
LOG(Message) << "Initial plaquette: " << WilsonLoops<PeriodicGimplR>::avgPlaquette(Umu_smear) << std::endl;
|
||||||
src = src * (1.0/nn);
|
const StoutParameters &Stout{par().Stout};
|
||||||
|
if( Stout.steps )
|
||||||
Laplacian3DHerm<LatticeColourVector> NablaCheby(Cheb,Nabla);
|
{
|
||||||
ImplicitlyRestartedLanczos<LatticeColourVector>
|
envGetTmp(GaugeField, Umu_stout);
|
||||||
IRL(NablaCheby,Nabla,LPar.Nvec,LPar.Nk,LPar.Nk+LPar.Np,LPar.resid,LPar.MaxIt);
|
Smear_Stout<PeriodicGimplR> LS(Stout.rho, Tdir); // spatial smearing only
|
||||||
int Nconv = 0;
|
for (int i = 0; i < Stout.steps; i++) {
|
||||||
IRL.calc(eig[t].eval,eig[t].evec,src,Nconv);
|
LS.smear(Umu_stout, Umu_smear);
|
||||||
if( Nconv < LPar.Nvec ) {
|
Umu_smear = Umu_stout;
|
||||||
// NB: Can't assert here since we are processing local slices - i.e. not all nodes would assert
|
}
|
||||||
ConvergenceErrors = 1;
|
LOG(Message) << "Smeared plaquette: " << WilsonLoops<PeriodicGimplR>::avgPlaquette(Umu_smear) << std::endl;
|
||||||
LOG(Error) << "MDistil::LapEvec : Not enough eigenvectors converged. If this occurs in practice, we should modify the eigensolver to iterate once more to ensure the second convergence test does not take us below the requested number of eigenvectors" << std::endl;
|
|
||||||
}
|
}
|
||||||
if( Nconv != LPar.Nvec )
|
|
||||||
eig[t].resize( LPar.Nvec, gridLD );
|
////////////////////////////////////////////////////////////////////////
|
||||||
RotateEigen( eig[t].evec ); // Rotate the eigenvectors into our phase convention
|
// Invert nabla operator separately on each time-slice
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
for (int i=0;i<LPar.Nvec;i++){
|
|
||||||
InsertSliceLocal(eig[t].evec[i],eig4d.evec[i],0,t,Tdir);
|
auto & eig4d = envGet(LapEvecs, getName() );
|
||||||
if(t==0 && Ntfirst==0)
|
envGetTmp(std::vector<LapEvecs>, eig); // Eigenpack for each timeslice
|
||||||
eig4d.eval[i] = eig[t].eval[i]; // TODO: Discuss: is this needed? Is there a better way?
|
envGetTmp(LatticeGaugeField, UmuNoTime); // Gauge field without time dimension
|
||||||
|
envGetTmp(LatticeColourVector, src);
|
||||||
|
const int Ntlocal{gridHD->LocalDimensions()[Tdir]};
|
||||||
|
const int Ntfirst{gridHD->LocalStarts()[Tdir]};
|
||||||
|
uint32_t ConvergenceErrors{0};
|
||||||
|
for (int t = 0; t < Ntlocal; t++ )
|
||||||
|
{
|
||||||
|
LOG(Message) << "------------------------------------------------------------" << std::endl;
|
||||||
|
LOG(Message) << " Compute eigenpack, local timeslice = " << t << " / " << Ntlocal << std::endl;
|
||||||
|
LOG(Message) << "------------------------------------------------------------" << std::endl;
|
||||||
|
eig[t].resize(LPar.Nk+LPar.Np,gridLD);
|
||||||
|
|
||||||
|
// Construct smearing operator
|
||||||
|
ExtractSliceLocal(UmuNoTime,Umu_smear,0,t,Tdir); // switch to 3d/4d objects
|
||||||
|
Laplacian3D<LatticeColourVector> Nabla(UmuNoTime);
|
||||||
|
LOG(Message) << "Chebyshev preconditioning to order " << ChebPar.PolyOrder
|
||||||
|
<< " with parameters (alpha,beta) = (" << ChebPar.alpha << "," << ChebPar.beta << ")" << std::endl;
|
||||||
|
Chebyshev<LatticeColourVector> Cheb(ChebPar.alpha,ChebPar.beta,ChebPar.PolyOrder);
|
||||||
|
|
||||||
|
// Construct source vector according to Test_dwf_compressed_lanczos.cc
|
||||||
|
src = 11.0; // NB: This is a dummy parameter and just needs to be non-zero
|
||||||
|
RealD nn = norm2(src);
|
||||||
|
nn = Grid::sqrt(nn);
|
||||||
|
src = src * (1.0/nn);
|
||||||
|
|
||||||
|
Laplacian3DHerm<LatticeColourVector> NablaCheby(Cheb,Nabla);
|
||||||
|
ImplicitlyRestartedLanczos<LatticeColourVector>
|
||||||
|
IRL(NablaCheby,Nabla,LPar.Nvec,LPar.Nk,LPar.Nk+LPar.Np,LPar.resid,LPar.MaxIt);
|
||||||
|
int Nconv = 0;
|
||||||
|
IRL.calc(eig[t].eval,eig[t].evec,src,Nconv);
|
||||||
|
if (Nconv < LPar.Nvec)
|
||||||
|
{
|
||||||
|
// NB: Can't assert here since we are processing local slices - i.e. not all nodes would assert
|
||||||
|
ConvergenceErrors = 1;
|
||||||
|
LOG(Error) << "MDistil::LapEvec : Not enough eigenvectors converged. If this occurs in practice, we should modify the eigensolver to iterate once more to ensure the second convergence test does not take us below the requested number of eigenvectors" << std::endl;
|
||||||
|
}
|
||||||
|
if( Nconv != LPar.Nvec )
|
||||||
|
eig[t].resize( LPar.Nvec, gridLD );
|
||||||
|
RotateEigen( eig[t].evec ); // Rotate the eigenvectors into our phase convention
|
||||||
|
|
||||||
|
for (int i=0;i<LPar.Nvec;i++){
|
||||||
|
InsertSliceLocal(eig[t].evec[i],eig4d.evec[i],0,t,Tdir);
|
||||||
|
if(t==0 && Ntfirst==0)
|
||||||
|
eig4d.eval[i] = eig[t].eval[i]; // TODO: Discuss: is this needed? Is there a better way?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
GridLogIRL.Active( PreviousIRLLogState );
|
||||||
GridLogIRL.Active( PreviousIRLLogState );
|
gridHD->GlobalSum(ConvergenceErrors);
|
||||||
gridHD->GlobalSum(ConvergenceErrors);
|
assert(ConvergenceErrors==0 && "The eingensolver failed to find enough eigenvectors on at least one node");
|
||||||
assert(ConvergenceErrors==0 && "The eingensolver failed to find enough eigenvectors on at least one node");
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
// Now write out the 4d eigenvectors
|
// Now write out the 4d eigenvectors
|
||||||
eig4d.record.operatorXml = "<OPERATOR>Distillation</OPERATOR>";
|
eig4d.record.operatorXml = "<OPERATOR>Distillation</OPERATOR>";
|
||||||
eig4d.record.solverXml = "<SOLVER>CG</SOLVER>";
|
eig4d.record.solverXml = "<SOLVER>CG</SOLVER>";
|
||||||
std::string sEigenPackName(getName());
|
std::string sEigenPackName(getName());
|
||||||
sEigenPackName.append(".");
|
sEigenPackName.append(".");
|
||||||
sEigenPackName.append(std::to_string(vm().getTrajectory()));
|
sEigenPackName.append(std::to_string(vm().getTrajectory()));
|
||||||
eig4d.write(sEigenPackName,false);
|
eig4d.write(sEigenPackName,false);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,17 +82,13 @@ TNoises<FImpl>::TNoises(const std::string name)
|
|||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
std::vector<std::string> TNoises<FImpl>::getInput(void)
|
std::vector<std::string> TNoises<FImpl>::getInput(void)
|
||||||
{
|
{
|
||||||
std::vector<std::string> in;
|
return {};
|
||||||
|
|
||||||
return in;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
std::vector<std::string> TNoises<FImpl>::getOutput(void)
|
std::vector<std::string> TNoises<FImpl>::getOutput(void)
|
||||||
{
|
{
|
||||||
std::vector<std::string> out = {getName()};
|
return {getName()};
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup ///////////////////////////////////////////////////////////////////////
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
@ -100,52 +96,49 @@ std::vector<std::string> TNoises<FImpl>::getOutput(void)
|
|||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
void TNoises<FImpl>::setup(void)
|
void TNoises<FImpl>::setup(void)
|
||||||
{
|
{
|
||||||
const int Nt{env().getDim(Tdir)};
|
const int Nt{env().getDim(Tdir)};
|
||||||
const int nnoise{par().nnoise};
|
const int nnoise{par().nnoise};
|
||||||
const int nvec{par().nvec};
|
const int nvec{par().nvec};
|
||||||
const int TI{ Hadrons::MDistil::DistilParameters::ParameterDefault( par().TI, Nt, true) };
|
envCreate(NoiseTensor, getName(), 1, nnoise, Nt, nvec, Ns);
|
||||||
const int LI{ Hadrons::MDistil::DistilParameters::ParameterDefault( par().LI, nvec, true) };
|
|
||||||
envCreate(NoiseTensor, getName(), 1, nnoise, Nt, nvec, Ns);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// execution ///////////////////////////////////////////////////////////////////
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
void TNoises<FImpl>::execute(void)
|
void TNoises<FImpl>::execute(void)
|
||||||
{
|
{
|
||||||
const int Nt{env().getDim(Tdir)};
|
const int Nt{env().getDim(Tdir)};
|
||||||
const int nnoise{par().nnoise};
|
const int nnoise{par().nnoise};
|
||||||
const int nvec{par().nvec};
|
const int nvec{par().nvec};
|
||||||
const int TI{ Hadrons::MDistil::DistilParameters::ParameterDefault( par().TI, Nt, false) };
|
const int TI{ Hadrons::MDistil::DistilParameters::ParameterDefault( par().TI, Nt, false) };
|
||||||
const int LI{ Hadrons::MDistil::DistilParameters::ParameterDefault( par().LI, nvec, false) };
|
const int LI{ Hadrons::MDistil::DistilParameters::ParameterDefault( par().LI, nvec, false) };
|
||||||
const bool full_tdil{ TI == Nt }; \
|
const bool full_tdil{ TI == Nt }; \
|
||||||
const bool exact_distillation{ full_tdil && LI == nvec }; \
|
const bool exact_distillation{ full_tdil && LI == nvec }; \
|
||||||
std::string UniqueIdentifier{par().UniqueIdentifier};
|
std::string UniqueIdentifier{par().UniqueIdentifier};
|
||||||
if( UniqueIdentifier.length() == 0 ) {
|
if (UniqueIdentifier.empty())
|
||||||
UniqueIdentifier = getName();
|
UniqueIdentifier = getName();
|
||||||
}
|
UniqueIdentifier.append( std::to_string( vm().getTrajectory() ) );
|
||||||
UniqueIdentifier.append( std::to_string( vm().getTrajectory() ) );
|
|
||||||
|
// We use our own seeds so we can specify different noises per quark
|
||||||
// We use our own seeds so we can specify different noises per quark
|
GridSerialRNG sRNG;
|
||||||
GridSerialRNG sRNG;
|
sRNG.SeedUniqueString(UniqueIdentifier);
|
||||||
sRNG.SeedUniqueString(UniqueIdentifier);
|
Real rn;
|
||||||
Real rn;
|
auto &noise = envGet(NoiseTensor, getName());
|
||||||
auto &noise = envGet(NoiseTensor, getName());
|
for (int inoise = 0; inoise < nnoise; inoise++) {
|
||||||
for( int inoise = 0; inoise < nnoise; inoise++ ) {
|
for (int t = 0; t < Nt; t++) {
|
||||||
for( int t = 0; t < Nt; t++ ) {
|
for (int ivec = 0; ivec < nvec; ivec++) {
|
||||||
for( int ivec = 0; ivec < nvec; ivec++ ) {
|
for (int is = 0; is < Ns; is++) {
|
||||||
for( int is = 0; is < Ns; is++ ) {
|
if (exact_distillation)
|
||||||
if( exact_distillation )
|
noise(inoise, t, ivec, is) = 1.;
|
||||||
noise(inoise, t, ivec, is) = 1.;
|
else{
|
||||||
else{
|
random(sRNG,rn);
|
||||||
random(sRNG,rn);
|
// We could use a greater number of complex roots of unity
|
||||||
// We could use a greater number of complex roots of unity
|
// ... but this seems to work well
|
||||||
// ... but this seems to work well
|
noise(inoise, t, ivec, is) = (rn > 0.5) ? -1 : 1;
|
||||||
noise(inoise, t, ivec, is) = (rn > 0.5) ? -1 : 1;
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
END_MODULE_NAMESPACE
|
END_MODULE_NAMESPACE
|
||||||
|
@ -69,11 +69,11 @@ public:
|
|||||||
// execution
|
// execution
|
||||||
virtual void execute(void);
|
virtual void execute(void);
|
||||||
protected:
|
protected:
|
||||||
GridCartesian * grid3d; // Owned by me, so I must delete it
|
GridCartesian * grid3d; // Owned by me, so I must delete it
|
||||||
GridCartesian * grid4d;
|
GridCartesian * grid4d;
|
||||||
protected:
|
protected:
|
||||||
virtual void Cleanup(void);
|
virtual void Cleanup(void);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
MODULE_REGISTER_TMP(PerambFromSolve, TPerambFromSolve<FIMPL>, MDistil);
|
MODULE_REGISTER_TMP(PerambFromSolve, TPerambFromSolve<FIMPL>, MDistil);
|
||||||
@ -90,100 +90,98 @@ TPerambFromSolve<FImpl>::TPerambFromSolve(const std::string name)
|
|||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
TPerambFromSolve<FImpl>::~TPerambFromSolve(void)
|
TPerambFromSolve<FImpl>::~TPerambFromSolve(void)
|
||||||
{
|
{
|
||||||
Cleanup();
|
Cleanup();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// dependencies/products ///////////////////////////////////////////////////////
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
std::vector<std::string> TPerambFromSolve<FImpl>::getInput(void)
|
std::vector<std::string> TPerambFromSolve<FImpl>::getInput(void)
|
||||||
{
|
{
|
||||||
return std::vector<std::string>{ par().solve, par().eigenPack };
|
return std::vector<std::string>{ par().solve, par().eigenPack };
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
std::vector<std::string> TPerambFromSolve<FImpl>::getOutput(void)
|
std::vector<std::string> TPerambFromSolve<FImpl>::getOutput(void)
|
||||||
{
|
{
|
||||||
return std::vector<std::string>{ getName() };
|
return std::vector<std::string>{ getName() };
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup ///////////////////////////////////////////////////////////////////////
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
void TPerambFromSolve<FImpl>::setup(void)
|
void TPerambFromSolve<FImpl>::setup(void)
|
||||||
{
|
{
|
||||||
Cleanup();
|
Cleanup();
|
||||||
DISTIL_PARAMETERS_DEFINE( true );
|
DISTIL_PARAMETERS_DEFINE( true );
|
||||||
const int nvec_reduced{ Hadrons::MDistil::DistilParameters::ParameterDefault( par().nvec_reduced, nvec, true) };
|
const int nvec_reduced{ Hadrons::MDistil::DistilParameters::ParameterDefault( par().nvec_reduced, nvec, true) };
|
||||||
const int LI_reduced{ Hadrons::MDistil::DistilParameters::ParameterDefault( par().LI_reduced, LI, true) };
|
const int LI_reduced{ Hadrons::MDistil::DistilParameters::ParameterDefault( par().LI_reduced, LI, true) };
|
||||||
grid4d = env().getGrid();
|
grid4d = env().getGrid();
|
||||||
grid3d = MakeLowerDimGrid(grid4d);
|
grid3d = MakeLowerDimGrid(grid4d);
|
||||||
envCreate(PerambTensor, getName(), 1, Nt,nvec_reduced,LI_reduced,nnoise,Nt_inv,SI);
|
envCreate(PerambTensor, getName(), 1, Nt,nvec_reduced,LI_reduced,nnoise,Nt_inv,SI);
|
||||||
envCreate(NoiseTensor, getName() + "_noise", 1, nnoise, Nt, nvec, Ns );
|
envCreate(NoiseTensor, getName() + "_noise", 1, nnoise, Nt, nvec, Ns );
|
||||||
envTmp(LatticeColourVector, "result_3d",1,LatticeColourVector(grid3d));
|
envTmp(LatticeColourVector, "result_3d",1,LatticeColourVector(grid3d));
|
||||||
envTmp(LatticeColourVector, "evec3d",1,LatticeColourVector(grid3d));
|
envTmp(LatticeColourVector, "evec3d",1,LatticeColourVector(grid3d));
|
||||||
envTmpLat(LatticeColourVector, "result_nospin");
|
envTmpLat(LatticeColourVector, "result_nospin");
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
void TPerambFromSolve<FImpl>::Cleanup(void)
|
void TPerambFromSolve<FImpl>::Cleanup(void)
|
||||||
{
|
{
|
||||||
if( grid3d != nullptr ) {
|
if (grid3d != nullptr)
|
||||||
delete grid3d;
|
{
|
||||||
grid3d = nullptr;
|
delete grid3d;
|
||||||
}
|
grid3d = nullptr;
|
||||||
grid4d = nullptr;
|
}
|
||||||
|
grid4d = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// execution ///////////////////////////////////////////////////////////////////
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
void TPerambFromSolve<FImpl>::execute(void)
|
void TPerambFromSolve<FImpl>::execute(void)
|
||||||
{
|
{
|
||||||
GridCartesian * grid4d = env().getGrid();
|
GridCartesian * grid4d = env().getGrid();
|
||||||
const int Ntlocal{grid4d->LocalDimensions()[3]};
|
const int Ntlocal{grid4d->LocalDimensions()[3]};
|
||||||
const int Ntfirst{grid4d->LocalStarts()[3]};
|
const int Ntfirst{grid4d->LocalStarts()[3]};
|
||||||
DISTIL_PARAMETERS_DEFINE( false );
|
DISTIL_PARAMETERS_DEFINE( false );
|
||||||
const int nvec_reduced{ Hadrons::MDistil::DistilParameters::ParameterDefault( par().nvec_reduced, nvec, false) };
|
const int nvec_reduced{ Hadrons::MDistil::DistilParameters::ParameterDefault( par().nvec_reduced, nvec, false) };
|
||||||
const int LI_reduced{ Hadrons::MDistil::DistilParameters::ParameterDefault( par().LI_reduced, LI, false) };
|
const int LI_reduced{ Hadrons::MDistil::DistilParameters::ParameterDefault( par().LI_reduced, LI, false) };
|
||||||
auto &perambulator = envGet(PerambTensor, getName());
|
auto &perambulator = envGet(PerambTensor, getName());
|
||||||
auto &solve = envGet(std::vector<FermionField>, par().solve);
|
auto &solve = envGet(std::vector<FermionField>, par().solve);
|
||||||
auto &epack = envGet(Grid::Hadrons::EigenPack<LatticeColourVector>, par().eigenPack);
|
auto &epack = envGet(Grid::Hadrons::EigenPack<LatticeColourVector>, par().eigenPack);
|
||||||
|
|
||||||
envGetTmp(LatticeColourVector, result_nospin);
|
envGetTmp(LatticeColourVector, result_nospin);
|
||||||
envGetTmp(LatticeColourVector, result_3d);
|
envGetTmp(LatticeColourVector, result_3d);
|
||||||
envGetTmp(LatticeColourVector, evec3d);
|
envGetTmp(LatticeColourVector, evec3d);
|
||||||
|
|
||||||
for (int inoise = 0; inoise < nnoise; inoise++) {
|
for (int inoise = 0; inoise < nnoise; inoise++) {
|
||||||
for (int dk = 0; dk < LI_reduced; dk++) {
|
for (int dk = 0; dk < LI_reduced; dk++) {
|
||||||
for (int dt = 0; dt < Nt_inv; dt++) {
|
for (int dt = 0; dt < Nt_inv; dt++) {
|
||||||
for (int ds = 0; ds < SI; ds++) {
|
for (int ds = 0; ds < SI; ds++) {
|
||||||
for (int is = 0; is < Ns; is++) {
|
for (int is = 0; is < Ns; is++) {
|
||||||
result_nospin = peekSpin(solve[inoise+nnoise*(dk+LI*(dt+Nt_inv*ds))],is);
|
result_nospin = peekSpin(solve[inoise+nnoise*(dk+LI*(dt+Nt_inv*ds))],is);
|
||||||
for (int t = Ntfirst; t < Ntfirst + Ntlocal; t++) {
|
for (int t = Ntfirst; t < Ntfirst + Ntlocal; t++) {
|
||||||
ExtractSliceLocal(result_3d,result_nospin,0,t-Ntfirst,Tdir);
|
ExtractSliceLocal(result_3d,result_nospin,0,t-Ntfirst,Tdir);
|
||||||
for (int ivec = 0; ivec < nvec_reduced; ivec++) {
|
for (int ivec = 0; ivec < nvec_reduced; ivec++) {
|
||||||
ExtractSliceLocal(evec3d,epack.evec[ivec],0,t-Ntfirst,Tdir);
|
ExtractSliceLocal(evec3d,epack.evec[ivec],0,t-Ntfirst,Tdir);
|
||||||
pokeSpin(perambulator.tensor(t, ivec, dk, inoise,dt,ds),static_cast<Complex>(innerProduct(evec3d, result_3d)),is);
|
pokeSpin(perambulator.tensor(t, ivec, dk, inoise,dt,ds),static_cast<Complex>(innerProduct(evec3d, result_3d)),is);
|
||||||
LOG(Message) << "perambulator(t, ivec, dk, inoise,dt,ds)(is) = (" << t << "," << ivec << "," << dk << "," << inoise << "," << dt << "," << ds << ")(" << is << ") = " << perambulator.tensor(t, ivec, dk, inoise,dt,ds)()(is)() << std::endl;
|
LOG(Message) << "perambulator(t, ivec, dk, inoise,dt,ds)(is) = (" << t << "," << ivec << "," << dk << "," << inoise << "," << dt << "," << ds << ")(" << is << ") = " << perambulator.tensor(t, ivec, dk, inoise,dt,ds)()(is)() << std::endl;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
if(grid4d->IsBoss())
|
||||||
|
{
|
||||||
if(grid4d->IsBoss()) {
|
std::string sPerambName{par().PerambFileName};
|
||||||
std::string sPerambName{par().PerambFileName};
|
if (sPerambName.empty())
|
||||||
if( sPerambName.length() == 0 )
|
sPerambName = getName();
|
||||||
sPerambName = getName();
|
sPerambName.append( "." );
|
||||||
sPerambName.append( "." );
|
sPerambName.append( std::to_string(vm().getTrajectory()));
|
||||||
sPerambName.append( std::to_string(vm().getTrajectory()));
|
perambulator.write(sPerambName.c_str());
|
||||||
perambulator.write(sPerambName.c_str());
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
END_MODULE_NAMESPACE
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
END_HADRONS_NAMESPACE
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
#endif // Hadrons_MDistil_PerambFromSolve_hpp_
|
#endif // Hadrons_MDistil_PerambFromSolve_hpp_
|
||||||
|
@ -126,7 +126,7 @@ void TPerambulator<FImpl>::setup(void)
|
|||||||
grid3d = MakeLowerDimGrid(grid4d);
|
grid3d = MakeLowerDimGrid(grid4d);
|
||||||
DISTIL_PARAMETERS_DEFINE( true );
|
DISTIL_PARAMETERS_DEFINE( true );
|
||||||
const std::string UnsmearedSinkFileName{ par().UnsmearedSinkFileName };
|
const std::string UnsmearedSinkFileName{ par().UnsmearedSinkFileName };
|
||||||
if( !UnsmearedSinkFileName.empty() )
|
if (!UnsmearedSinkFileName.empty())
|
||||||
bool bMulti = ( Hadrons::MDistil::DistilParameters::ParameterDefault( par().UnsmearedSinkMultiFile, 1, true ) != 0 );
|
bool bMulti = ( Hadrons::MDistil::DistilParameters::ParameterDefault( par().UnsmearedSinkMultiFile, 1, true ) != 0 );
|
||||||
|
|
||||||
envCreate(PerambTensor, getName(), 1, Nt,nvec,LI,nnoise,Nt_inv,SI);
|
envCreate(PerambTensor, getName(), 1, Nt,nvec,LI,nnoise,Nt_inv,SI);
|
||||||
@ -152,7 +152,7 @@ void TPerambulator<FImpl>::setup(void)
|
|||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
void TPerambulator<FImpl>::Cleanup(void)
|
void TPerambulator<FImpl>::Cleanup(void)
|
||||||
{
|
{
|
||||||
if( grid3d != nullptr )
|
if (grid3d != nullptr)
|
||||||
{
|
{
|
||||||
delete grid3d;
|
delete grid3d;
|
||||||
grid3d = nullptr;
|
grid3d = nullptr;
|
||||||
@ -185,67 +185,62 @@ void TPerambulator<FImpl>::execute(void)
|
|||||||
const int Ntlocal{grid4d->LocalDimensions()[3]};
|
const int Ntlocal{grid4d->LocalDimensions()[3]};
|
||||||
const int Ntfirst{grid4d->LocalStarts()[3]};
|
const int Ntfirst{grid4d->LocalStarts()[3]};
|
||||||
const std::string UnsmearedSinkFileName{ par().UnsmearedSinkFileName };
|
const std::string UnsmearedSinkFileName{ par().UnsmearedSinkFileName };
|
||||||
|
|
||||||
|
for (int inoise = 0; inoise < nnoise; inoise++)
|
||||||
{
|
{
|
||||||
int t_inv;
|
for (int dk = 0; dk < LI; dk++)
|
||||||
for (int inoise = 0; inoise < nnoise; inoise++)
|
|
||||||
{
|
{
|
||||||
for (int dk = 0; dk < LI; dk++)
|
for (int dt = 0; dt < Nt_inv; dt++)
|
||||||
{
|
{
|
||||||
for (int dt = 0; dt < Nt_inv; dt++)
|
for (int ds = 0; ds < SI; ds++)
|
||||||
{
|
{
|
||||||
for (int ds = 0; ds < SI; ds++)
|
LOG(Message) << "LapH source vector from noise " << inoise << " and dilution component (d_k,d_t,d_alpha) : (" << dk << ","<< dt << "," << ds << ")" << std::endl;
|
||||||
|
dist_source = 0;
|
||||||
|
tmp3d_nospin = 0;
|
||||||
|
evec3d = 0;
|
||||||
|
for (int it = dt; it < Nt; it += TI)
|
||||||
{
|
{
|
||||||
LOG(Message) << "LapH source vector from noise " << inoise << " and dilution component (d_k,d_t,d_alpha) : (" << dk << ","<< dt << "," << ds << ")" << std::endl;
|
const int t_inv{full_tdil ? tsrc : it};
|
||||||
dist_source = 0;
|
if( t_inv >= Ntfirst && t_inv < Ntfirst + Ntlocal )
|
||||||
tmp3d_nospin = 0;
|
|
||||||
evec3d = 0;
|
|
||||||
for (int it = dt; it < Nt; it += TI)
|
|
||||||
{
|
{
|
||||||
if (full_tdil) t_inv = tsrc; else t_inv = it;
|
for (int ik = dk; ik < nvec; ik += LI)
|
||||||
if( t_inv >= Ntfirst && t_inv < Ntfirst + Ntlocal )
|
|
||||||
{
|
{
|
||||||
for (int ik = dk; ik < nvec; ik += LI)
|
for (int is = ds; is < Ns; is += SI)
|
||||||
{
|
{
|
||||||
for (int is = ds; is < Ns; is += SI)
|
ExtractSliceLocal(evec3d,epack.evec[ik],0,t_inv-Ntfirst,Tdir);
|
||||||
{
|
tmp3d_nospin = evec3d * noise(inoise, t_inv, ik, is);
|
||||||
ExtractSliceLocal(evec3d,epack.evec[ik],0,t_inv-Ntfirst,Tdir);
|
tmp3d=0;
|
||||||
tmp3d_nospin = evec3d * noise(inoise, t_inv, ik, is);
|
pokeSpin(tmp3d,tmp3d_nospin,is);
|
||||||
tmp3d=0;
|
tmp2=0;
|
||||||
pokeSpin(tmp3d,tmp3d_nospin,is);
|
InsertSliceLocal(tmp3d,tmp2,0,t_inv-Ntfirst,Tdir);
|
||||||
tmp2=0;
|
dist_source += tmp2;
|
||||||
InsertSliceLocal(tmp3d,tmp2,0,t_inv-Ntfirst,Tdir);
|
|
||||||
dist_source += tmp2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result=0;
|
}
|
||||||
v4dtmp = dist_source;
|
result=0;
|
||||||
if (Ls_ == 1)
|
v4dtmp = dist_source;
|
||||||
|
if (Ls_ == 1)
|
||||||
|
solver(result, v4dtmp);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mat.ImportPhysicalFermionSource(v4dtmp, v5dtmp);
|
||||||
|
solver(v5dtmp_sol, v5dtmp);
|
||||||
|
mat.ExportPhysicalFermionSolution(v5dtmp_sol, v4dtmp);
|
||||||
|
result = v4dtmp;
|
||||||
|
}
|
||||||
|
if (!UnsmearedSinkFileName.empty())
|
||||||
|
unsmeared_sink[inoise+nnoise*(dk+LI*(dt+Nt_inv*ds))] = result;
|
||||||
|
for (int is = 0; is < Ns; is++)
|
||||||
|
{
|
||||||
|
result_nospin = peekSpin(result,is);
|
||||||
|
for (int t = Ntfirst; t < Ntfirst + Ntlocal; t++)
|
||||||
{
|
{
|
||||||
solver(result, v4dtmp);
|
ExtractSliceLocal(result_3d,result_nospin,0,t-Ntfirst,Tdir);
|
||||||
}
|
for (int ivec = 0; ivec < nvec; ivec++)
|
||||||
else
|
|
||||||
{
|
|
||||||
mat.ImportPhysicalFermionSource(v4dtmp, v5dtmp);
|
|
||||||
solver(v5dtmp_sol, v5dtmp);
|
|
||||||
mat.ExportPhysicalFermionSolution(v5dtmp_sol, v4dtmp);
|
|
||||||
result = v4dtmp;
|
|
||||||
}
|
|
||||||
if( !UnsmearedSinkFileName.empty() )
|
|
||||||
unsmeared_sink[inoise+nnoise*(dk+LI*(dt+Nt_inv*ds))] = result;
|
|
||||||
for (int is = 0; is < Ns; is++)
|
|
||||||
{
|
|
||||||
result_nospin = peekSpin(result,is);
|
|
||||||
for (int t = Ntfirst; t < Ntfirst + Ntlocal; t++)
|
|
||||||
{
|
{
|
||||||
ExtractSliceLocal(result_3d,result_nospin,0,t-Ntfirst,Tdir);
|
ExtractSliceLocal(evec3d,epack.evec[ivec],0,t-Ntfirst,Tdir);
|
||||||
for (int ivec = 0; ivec < nvec; ivec++)
|
pokeSpin(perambulator.tensor(t, ivec, dk, inoise,dt,ds),static_cast<Complex>(innerProduct(evec3d, result_3d)),is);
|
||||||
{
|
|
||||||
ExtractSliceLocal(evec3d,epack.evec[ivec],0,t-Ntfirst,Tdir);
|
|
||||||
pokeSpin(perambulator.tensor(t, ivec, dk, inoise,dt,ds),static_cast<Complex>(innerProduct(evec3d, result_3d)),is);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user