2019-01-22 15:06:45 +00:00
# ifndef Hadrons_MDistil_PerambLight_hpp_
# define Hadrons_MDistil_PerambLight_hpp_
2019-01-18 13:14:28 +00:00
# include <Hadrons/Global.hpp>
# include <Hadrons/Module.hpp>
# include <Hadrons/ModuleFactory.hpp>
2019-01-22 15:06:45 +00:00
# include <Hadrons/Solver.hpp>
# include <Hadrons/EigenPack.hpp>
# include <Hadrons/A2AVectors.hpp>
# include <Hadrons/DilutedNoise.hpp>
2019-01-22 17:59:55 +00:00
// These are members of Distillation
# include <Hadrons/Modules/MDistil/Distil.hpp>
2019-01-18 13:14:28 +00:00
BEGIN_HADRONS_NAMESPACE
2019-01-22 15:06:45 +00:00
2019-01-18 13:14:28 +00:00
/******************************************************************************
2019-01-22 15:06:45 +00:00
* PerambLight *
2019-01-18 13:14:28 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BEGIN_MODULE_NAMESPACE ( MDistil )
2019-01-31 12:24:32 +00:00
struct DistilParameters : Serializable {
GRID_SERIALIZABLE_CLASS_MEMBERS ( DistilParameters ,
int , TI ,
int , LI ,
int , nnoise ,
int , tsrc ,
int , SI ,
int , Ns ,
int , Nt ,
int , Nt_inv )
DistilParameters ( ) = default ;
template < class ReaderClass > DistilParameters ( Reader < ReaderClass > & Reader ) { read ( Reader , " Distil " , * this ) ; }
} ;
struct SolverParameters : Serializable {
GRID_SERIALIZABLE_CLASS_MEMBERS ( SolverParameters ,
double , CGPrecision ,
int , MaxIterations ,
double , mass ,
double , M5 )
SolverParameters ( ) = default ;
template < class ReaderClass > SolverParameters ( Reader < ReaderClass > & Reader ) { read ( Reader , " Solver " , * this ) ; }
} ;
2019-01-22 15:06:45 +00:00
class PerambLightPar : Serializable
2019-01-18 13:14:28 +00:00
{
public :
2019-01-22 15:06:45 +00:00
GRID_SERIALIZABLE_CLASS_MEMBERS ( PerambLightPar ,
std : : string , eigenPack ,
2019-02-04 11:30:30 +00:00
std : : string , PerambFileName ,
2019-01-23 11:26:07 +00:00
bool , multiFile ,
2019-01-31 12:24:32 +00:00
int , nvec ,
int , Ls , // For makeFiveDimGrid
DistilParameters , Distil ,
SolverParameters , Solver ) ;
2019-01-18 13:14:28 +00:00
} ;
2019-02-01 13:23:42 +00:00
template < typename FImpl >
2019-01-22 15:06:45 +00:00
class TPerambLight : public Module < PerambLightPar >
2019-01-18 13:14:28 +00:00
{
public :
2019-02-01 13:23:42 +00:00
FERM_TYPE_ALIASES ( FImpl , ) ;
2019-01-18 13:14:28 +00:00
// constructor
2019-01-22 15:06:45 +00:00
TPerambLight ( const std : : string name ) ;
2019-01-18 13:14:28 +00:00
// destructor
2019-01-31 12:24:32 +00:00
virtual ~ TPerambLight ( void ) ;
2019-01-18 13:14:28 +00:00
// dependency relation
virtual std : : vector < std : : string > getInput ( void ) ;
virtual std : : vector < std : : string > getOutput ( void ) ;
// setup
virtual void setup ( void ) ;
// execution
virtual void execute ( void ) ;
2019-01-30 21:16:09 +00:00
protected :
2019-01-31 12:24:32 +00:00
// These variables are created in setup() and freed in Cleanup()
GridCartesian * grid3d ; // Owned by me, so I must delete it
GridCartesian * grid4d ; // Owned by environment (so I won't delete it)
2019-01-30 21:16:09 +00:00
protected :
2019-01-31 12:24:32 +00:00
virtual void Cleanup ( void ) ;
2019-01-18 13:14:28 +00:00
} ;
2019-02-01 13:23:42 +00:00
MODULE_REGISTER_TMP ( PerambLight , TPerambLight < FIMPL > , MDistil ) ;
2019-01-18 13:14:28 +00:00
/******************************************************************************
2019-01-22 15:06:45 +00:00
* TPerambLight implementation *
2019-01-18 13:14:28 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// constructor /////////////////////////////////////////////////////////////////
2019-02-01 13:23:42 +00:00
template < typename FImpl >
TPerambLight < FImpl > : : TPerambLight ( const std : : string name )
2019-01-30 21:16:09 +00:00
: grid3d { nullptr } , grid4d { nullptr } , Module < PerambLightPar > ( name )
2019-01-18 13:14:28 +00:00
{ }
2019-01-30 21:16:09 +00:00
// destructor
2019-02-01 13:23:42 +00:00
template < typename FImpl >
TPerambLight < FImpl > : : ~ TPerambLight ( void )
2019-01-30 21:16:09 +00:00
{
Cleanup ( ) ;
} ;
2019-01-18 13:14:28 +00:00
// dependencies/products ///////////////////////////////////////////////////////
2019-02-01 13:23:42 +00:00
template < typename FImpl >
std : : vector < std : : string > TPerambLight < FImpl > : : getInput ( void )
2019-01-18 13:14:28 +00:00
{
std : : vector < std : : string > in ;
2019-01-22 15:06:45 +00:00
in . push_back ( par ( ) . eigenPack ) ;
2019-01-18 13:14:28 +00:00
return in ;
}
2019-02-01 13:23:42 +00:00
template < typename FImpl >
std : : vector < std : : string > TPerambLight < FImpl > : : getOutput ( void )
2019-01-18 13:14:28 +00:00
{
2019-02-01 13:23:42 +00:00
std : : vector < std : : string > out = { getName ( ) + " _perambulator_light " , getName ( ) + " _noise " , getName ( ) + " _unsmeared_sink " } ;
2019-01-18 13:14:28 +00:00
return out ;
}
// setup ///////////////////////////////////////////////////////////////////////
2019-02-01 13:23:42 +00:00
template < typename FImpl >
void TPerambLight < FImpl > : : setup ( void )
2019-01-18 13:14:28 +00:00
{
2019-01-31 12:24:32 +00:00
Cleanup ( ) ;
// auto &noise = envGet(std::vector<std::vector<std::vector<SpinVector>>>, par().noise);
const int nvec { par ( ) . nvec } ;
const DistilParameters & Distil { par ( ) . Distil } ;
2019-02-01 13:23:42 +00:00
const int LI { Distil . LI } ;
const int nnoise { Distil . nnoise } ;
const int Nt_inv { Distil . Nt_inv } ; // TODO: PROBABLY BETTER: if (full_tdil) Nt_inv=1; else Nt_inv = TI;
const int Ns { Distil . Ns } ;
2019-02-01 15:20:35 +00:00
std : : array < std : : string , 6 > sIndexNames { " Nt " , " nvec " , " LI " , " nnoise " , " Nt_inv " , " SI " } ;
//std::complex<double> z{0.6,-3.1};
//envCreate(std::string, getName() + "_debug_delete_me", 1, "Bingonuts");
//envCreate(std::complex<double>, getName() + "_debug_delete_me_2", 1, 0.6);
//envCreate(std::complex<double>, getName() + "_debug_delete_me_3", 1, z);
//envCreate(std::complex<double>, getName() + "_debug_delete_me_4", 1, {0.6 COMMA -3.1});
//envCreate(std::array<std::string COMMA 3>, getName() + "_debug_delete_me_5", 1, {"One" COMMA "Two" COMMA "Three"});
envCreate ( Perambulator < SpinVector COMMA 6 > , getName ( ) + " _perambulator_light " , 1 ,
sIndexNames , Distil . Nt , nvec , Distil . LI , Distil . nnoise , Distil . Nt_inv , Distil . SI ) ;
2019-01-31 12:24:32 +00:00
envCreate ( std : : vector < Complex > , getName ( ) + " _noise " , 1 ,
nvec * Distil . Ns * Distil . Nt * Distil . nnoise ) ;
2019-02-01 13:23:42 +00:00
envCreate ( std : : vector < FermionField > , getName ( ) + " _unsmeared_sink " , 1 ,
nnoise * LI * Ns * Nt_inv , envGetGrid ( FermionField ) ) ;
2019-01-31 12:24:32 +00:00
grid4d = env ( ) . getGrid ( ) ;
grid3d = MakeLowerDimGrid ( grid4d ) ; //new GridCartesian(latt_size,simd_layout_3,mpi_layout,*grid4d);
envTmpLat ( GaugeField , " Umu " ) ;
envTmpLat ( LatticeSpinColourVector , " dist_source " ) ;
envTmpLat ( LatticeSpinColourVector , " tmp2 " ) ;
envTmpLat ( LatticeSpinColourVector , " result " ) ;
//envTmpLat(LatticeSpinColourVector, "result_single_component");
envTmpLat ( LatticeColourVector , " result_nospin " ) ;
//envTmpLat(LatticeColourVector, "tmp_nospin");
//envTmpLat(LatticeSpinVector, "peramb_tmp");
envTmp ( LatticeSpinColourVector , " tmp3d " , 1 , LatticeSpinColourVector ( grid3d ) ) ;
envTmp ( LatticeColourVector , " tmp3d_nospin " , 1 , LatticeColourVector ( grid3d ) ) ;
envTmp ( LatticeColourVector , " result_3d " , 1 , LatticeColourVector ( grid3d ) ) ;
envTmp ( LatticeColourVector , " evec3d " , 1 , LatticeColourVector ( grid3d ) ) ;
2019-01-18 13:14:28 +00:00
}
2019-01-30 21:16:09 +00:00
// clean up any temporaries created by setup (that aren't stored in the environment)
2019-02-01 13:23:42 +00:00
template < typename FImpl >
void TPerambLight < FImpl > : : Cleanup ( void )
2019-01-30 21:16:09 +00:00
{
if ( grid3d ! = nullptr ) {
delete grid3d ;
grid3d = nullptr ;
}
grid4d = nullptr ;
}
2019-01-18 13:14:28 +00:00
// execution ///////////////////////////////////////////////////////////////////
2019-02-01 13:23:42 +00:00
template < typename FImpl >
void TPerambLight < FImpl > : : execute ( void )
2019-01-18 13:14:28 +00:00
{
2019-01-31 12:24:32 +00:00
const int nvec { par ( ) . nvec } ;
const DistilParameters & Distil { par ( ) . Distil } ;
const SolverParameters & Solver { par ( ) . Solver } ;
const int LI { Distil . LI } ;
//const int SI{Distil.SI};
const int TI { Distil . TI } ;
const int nnoise { Distil . nnoise } ;
const int Nt { Distil . Nt } ;
2019-01-31 16:54:11 +00:00
const int Nt_inv { Distil . Nt_inv } ; // TODO: PROBABLY BETTER: if (full_tdil) Nt_inv=1; else Nt_inv = TI;
2019-01-31 12:24:32 +00:00
const int tsrc { Distil . tsrc } ;
const int Ns { Distil . Ns } ;
const bool full_tdil { TI = = Nt } ;
const bool exact_distillation { full_tdil & & LI = = nvec } ;
2019-01-22 15:52:26 +00:00
2019-01-23 13:58:20 +00:00
//auto &noise = envGet(std::vector<std::vector<std::vector<SpinVector>>>, par().noise);
auto & noise = envGet ( std : : vector < Complex > , getName ( ) + " _noise " ) ;
2019-02-01 15:20:35 +00:00
auto & perambulator = envGet ( Perambulator < SpinVector COMMA 6 > , getName ( ) + " _perambulator_light " ) ;
2019-01-22 15:52:26 +00:00
auto & epack = envGet ( Grid : : Hadrons : : EigenPack < LatticeColourVector > , par ( ) . eigenPack ) ;
2019-02-01 13:23:42 +00:00
auto & unsmeared_sink = envGet ( std : : vector < FermionField > , getName ( ) + " _unsmeared_sink " ) ;
2019-01-22 15:52:26 +00:00
2019-01-31 12:24:32 +00:00
envGetTmp ( GaugeField , Umu ) ;
2019-01-22 15:52:26 +00:00
FieldMetaData header ;
2019-01-25 12:37:18 +00:00
if ( ( 1 ) ) {
const std : : vector < int > seeds ( { 1 , 2 , 3 , 4 , 5 } ) ;
GridParallelRNG pRNG4d ( grid4d ) ;
pRNG4d . SeedFixedIntegers ( seeds ) ;
std : : cout < < GridLogMessage < < " now hot config " < < std : : endl ;
SU < Nc > : : HotConfiguration ( pRNG4d , Umu ) ;
std : : cout < < GridLogMessage < < " hot cfg done. " < < std : : endl ;
2019-01-29 16:24:59 +00:00
// Set up the SAME gauge field on every time plane
// int Nt = grid4d->gDimensions()[Tdir];
Grid_unquiesce_nodes ( ) ;
auto Usft = Umu ;
Lattice < iScalar < vInteger > > coor ( grid4d ) ;
LatticeCoordinate ( coor , Tdir ) ;
2019-01-31 12:24:32 +00:00
for ( int t = 1 ; t < Nt ; t + + ) {
2019-01-29 16:24:59 +00:00
// t=1
// Umu Usft
// 0,1,2,3,4,5,6,7 -> 7,0,1,2,3,4,5,6 t=1
// 0,0,2,3,4,5,6,7 6,7,0,1,2,3,4,5 t=2
// 0,0,0,3,4,5,6,7 5,6,7,0,1,2,3,4 t=3
//...
Usft = Cshift ( Usft , Tdir , - 1 ) ;
Umu = where ( coor = = t , Usft , Umu ) ;
}
2019-01-25 12:37:18 +00:00
} else {
std : : string fileName ( " /home/dp008/dp008/dc-rich6/Scripts/ConfigsDeflQED/ckpoint_lat.3000 " ) ;
std : : cout < < GridLogMessage < < " Loading NERSC configuration from ' " < < fileName < < " ' " < < std : : endl ;
NerscIO : : readConfiguration ( Umu , header , fileName ) ;
std : : cout < < GridLogMessage < < " reading done. " < < std : : endl ;
}
2019-01-22 15:52:26 +00:00
envGetTmp ( LatticeSpinColourVector , dist_source ) ;
envGetTmp ( LatticeSpinColourVector , tmp2 ) ;
envGetTmp ( LatticeSpinColourVector , result ) ;
2019-01-31 12:24:32 +00:00
//envGetTmp(LatticeSpinColourVector, result_single_component);
2019-01-22 15:52:26 +00:00
envGetTmp ( LatticeColourVector , result_nospin ) ;
2019-01-31 12:24:32 +00:00
//envGetTmp(LatticeColourVector, tmp_nospin);
//envGetTmp(LatticeSpinVector, peramb_tmp);
2019-01-22 15:52:26 +00:00
envGetTmp ( LatticeSpinColourVector , tmp3d ) ;
envGetTmp ( LatticeColourVector , tmp3d_nospin ) ;
envGetTmp ( LatticeColourVector , result_3d ) ;
envGetTmp ( LatticeColourVector , evec3d ) ;
2019-01-31 12:24:32 +00:00
const int Ntlocal { grid4d - > LocalDimensions ( ) [ 3 ] } ;
const int Ntfirst { grid4d - > LocalStarts ( ) [ 3 ] } ;
2019-01-23 13:58:20 +00:00
//Create Noises
//std::cout << pszGaugeConfigFile << std::endl;
//GridSerialRNG sRNG; sRNG.SeedUniqueString(std::string(pszGaugeConfigFile));
2019-01-31 16:54:11 +00:00
GridSerialRNG sRNG ; sRNG . SeedUniqueString ( " unique_string " ) ; // TODO: Proper unique string. Include quark mass, gauge field? Maybe also nvec, but in a way that more nvec would only add noises, not change all of them???
2019-01-23 13:58:20 +00:00
Real rn ;
for ( int inoise = 0 ; inoise < nnoise ; inoise + + ) {
for ( int t = 0 ; t < Nt ; t + + ) {
for ( int ivec = 0 ; ivec < nvec ; ivec + + ) {
for ( int is = 0 ; is < Ns ; is + + ) {
if ( exact_distillation )
noise [ inoise + nnoise * ( t + Nt * ( ivec + nvec * is ) ) ] = 1. ;
//noises[inoise][t][ivec]()(is)() = 1.;
else {
2019-02-01 15:20:35 +00:00
random ( sRNG , rn ) ;
// We could use a greater number of complex roots of unity
// ... but this seems to work well
noise [ inoise + nnoise * ( t + Nt * ( ivec + nvec * is ) ) ] = ( rn > 0.5 ) ? - 1 : 1 ;
2019-01-23 13:58:20 +00:00
}
}
}
}
}
2019-01-23 11:26:07 +00:00
2019-01-31 12:24:32 +00:00
const Real mass { Solver . mass } ;
const Real M5 { Solver . M5 } ;
2019-01-22 15:52:26 +00:00
std : : cout < < " init RBG " < < std : : endl ;
GridRedBlackCartesian RBGrid ( grid4d ) ;
std : : cout < < " init RBG done " < < std : : endl ;
2019-01-31 12:24:32 +00:00
const int Ls { par ( ) . Ls } ;
const double CGPrecision { Solver . CGPrecision } ;
const int MaxIterations { Solver . MaxIterations } ;
{
2019-01-22 15:52:26 +00:00
GridCartesian * FGrid = SpaceTimeGrid : : makeFiveDimGrid ( Ls , grid4d ) ;
GridRedBlackCartesian * FrbGrid = SpaceTimeGrid : : makeFiveDimRedBlackGrid ( Ls , grid4d ) ;
typedef DomainWallFermionR FermionAction ;
FermionAction Dop ( Umu , * FGrid , * FrbGrid , * grid4d , RBGrid , mass , M5 ) ;
MdagMLinearOperator < FermionAction , LatticeFermion > HermOp ( Dop ) ;
ConjugateGradient < LatticeFermion > CG ( CGPrecision , MaxIterations ) ;
SchurRedBlackDiagMooeeSolve < LatticeFermion > SchurSolver ( CG ) ;
2019-01-31 11:35:05 +00:00
int t_inv ;
2019-01-18 17:47:41 +00:00
for ( int inoise = 0 ; inoise < nnoise ; inoise + + ) {
for ( int dk = 0 ; dk < LI ; dk + + ) {
for ( int dt = 0 ; dt < Nt_inv ; dt + + ) {
for ( int ds = 0 ; ds < Ns ; ds + + ) {
std : : cout < < " LapH source vector from noise " < < inoise < < " and dilution component (d_k,d_t,d_alpha) : ( " < < dk < < " , " < < dt < < " , " < < ds < < " ) " < < std : : endl ;
dist_source = zero ;
tmp3d_nospin = zero ;
evec3d = zero ;
for ( int it = dt ; it < Nt ; it + = TI ) {
2019-01-31 11:35:05 +00:00
if ( full_tdil ) t_inv = tsrc ; else t_inv = it ;
if ( t_inv > = Ntfirst & & t_inv < Ntfirst + Ntlocal ) {
2019-01-18 17:47:41 +00:00
for ( int ik = dk ; ik < nvec ; ik + = LI ) {
2019-01-31 16:54:11 +00:00
for ( int is = ds ; is < Ns ; is + = Ns ) { // TODO: Also allow non-full spin dilution (re-define exact_distillation?)
2019-01-31 11:35:05 +00:00
ExtractSliceLocal ( evec3d , epack . evec [ ik ] , 0 , t_inv , 3 ) ;
tmp3d_nospin = evec3d * noise [ inoise + nnoise * ( t_inv + Nt * ( ik + nvec * is ) ) ] ;
2019-01-18 17:47:41 +00:00
tmp3d = zero ;
pokeSpin ( tmp3d , tmp3d_nospin , is ) ;
tmp2 = zero ;
2019-01-31 11:35:05 +00:00
InsertSliceLocal ( tmp3d , tmp2 , 0 , t_inv - Ntfirst , Grid : : QCD : : Tdir ) ;
2019-01-18 17:47:41 +00:00
dist_source + = tmp2 ;
}
}
}
}
std : : cout < < " Inversion for noise " < < inoise < < " and dilution component (d_k,d_t,d_alpha) : ( " < < dk < < " , " < < dt < < " , " < < ds < < " ) " < < std : : endl ;
result = zero ;
LatticeFermion src5 ( FGrid ) ;
LatticeFermion sol5 ( FGrid ) ;
Dop . ImportPhysicalFermionSource ( dist_source , src5 ) ;
SchurSolver ( Dop , src5 , sol5 ) ;
Dop . ExportPhysicalFermionSolution ( sol5 , result ) ; //These are the meson sinks
2019-02-01 13:23:42 +00:00
if ( ( 1 ) ) // comment out if unsmeared sink is too large???
unsmeared_sink [ inoise + nnoise * ( dk + LI * ( dt + Nt_inv * ds ) ) ] = result ;
2019-01-18 17:47:41 +00:00
std : : cout < < " Contraction of perambulator from noise " < < inoise < < " and dilution component (d_k,d_t,d_alpha) : ( " < < dk < < " , " < < dt < < " , " < < ds < < " ) " < < std : : endl ;
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 , Grid : : QCD : : Tdir ) ;
for ( int ivec = 0 ; ivec < nvec ; ivec + + ) {
2019-01-22 15:52:26 +00:00
ExtractSliceLocal ( evec3d , epack . evec [ ivec ] , 0 , t , 3 ) ;
2019-01-18 17:47:41 +00:00
pokeSpin ( perambulator ( t , ivec , dk , inoise , dt , ds ) , innerProduct ( evec3d , result_3d ) , is ) ;
2019-01-29 16:24:59 +00:00
std : : cout < < " perambulator(t, ivec, dk, inoise,dt,ds)(is) = ( " < < t < < " , " < < ivec < < " , " < < dk < < " , " < < inoise < < " , " < < dt < < " , " < < ds < < " )( " < < is < < " ) = " < < perambulator ( t , ivec , dk , inoise , dt , ds ) ( ) ( is ) ( ) < < std : : endl ;
2019-01-18 17:47:41 +00:00
}
}
}
}
}
2019-01-22 15:52:26 +00:00
}
}
2019-01-31 12:24:32 +00:00
// Kill our 5 dimensional grid (avoid leaks). Should really declare these objects temporary
delete FrbGrid ;
delete FGrid ;
}
2019-01-18 17:47:41 +00:00
std : : cout < < " perambulator done " < < std : : endl ;
2019-01-22 17:59:55 +00:00
perambulator . SliceShare ( grid3d , grid4d ) ;
2019-01-18 17:47:41 +00:00
// THIS IS WHERE WE WANT TO SAVE THE PERAMBULATORS TO DISK
2019-02-04 11:30:30 +00:00
const std : : string & FileName { par ( ) . PerambFileName } ;
if ( FileName . length ( ) )
perambulator . WriteTemporary ( FileName ) ;
2019-01-18 13:14:28 +00:00
}
END_MODULE_NAMESPACE
END_HADRONS_NAMESPACE
2019-01-22 15:06:45 +00:00
# endif // Hadrons_MDistil_PerambLight_hpp_