mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-11-04 14:04:32 +00:00 
			
		
		
		
	Merge branch 'temporary-smearing' into develop
This commit is contained in:
		
							
								
								
									
										
											BIN
										
									
								
								benchmarks/Benchmark_dwf_ntpf
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								benchmarks/Benchmark_dwf_ntpf
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								benchmarks/Benchmark_zmm
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								benchmarks/Benchmark_zmm
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										42
									
								
								lib/Init.cc
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								lib/Init.cc
									
									
									
									
									
								
							@@ -193,7 +193,7 @@ void Grid_init(int *argc,char ***argv)
 | 
			
		||||
    std::cout<<GridLogMessage<<"--mpi n.n.n.n   : default MPI decomposition"<<std::endl;    
 | 
			
		||||
    std::cout<<GridLogMessage<<"--threads n     : default number of OMP threads"<<std::endl;
 | 
			
		||||
    std::cout<<GridLogMessage<<"--grid n.n.n.n  : default Grid size"<<std::endl;    
 | 
			
		||||
    std::cout<<GridLogMessage<<"--log list      : comma separted list of streams from Error,Warning,Message,Performance,Iterative,Integrator,Debug"<<std::endl;
 | 
			
		||||
    std::cout<<GridLogMessage<<"--log list      : comma separted list of streams from Error,Warning,Message,Performance,Iterative,Integrator,Debug,Colours"<<std::endl;
 | 
			
		||||
    exit(EXIT_SUCCESS);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -234,24 +234,33 @@ void Grid_init(int *argc,char ***argv)
 | 
			
		||||
    std::cout<<GridLogMessage<<"\tvComplexD      : "<<sizeof(vComplexD)*8 <<"bits ; " <<GridCmdVectorIntToString(GridDefaultSimd(4,vComplexD::Nsimd()))<<std::endl;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  std::string COL_RED    = GridLogColours.colour["RED"];
 | 
			
		||||
  std::string COL_PURPLE = GridLogColours.colour["PURPLE"];
 | 
			
		||||
  std::string COL_BLACK  = GridLogColours.colour["BLACK"];
 | 
			
		||||
  std::string COL_GREEN  = GridLogColours.colour["GREEN"];
 | 
			
		||||
  std::string COL_BLUE   = GridLogColours.colour["BLUE"];
 | 
			
		||||
  std::string COL_YELLOW = GridLogColours.colour["YELLOW"];
 | 
			
		||||
  std::string COL_BACKGROUND = GridLogColours.colour["NORMAL"];
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  std::cout <<std::endl;
 | 
			
		||||
  std::cout << "__|__|__|__|__|__|__|__|__|__|__|__|__|__|__"<<std::endl; 
 | 
			
		||||
  std::cout << "__|__|__|__|__|__|__|__|__|__|__|__|__|__|__"<<std::endl; 
 | 
			
		||||
  std::cout << "__|_ |  |  |  |  |  |  |  |  |  |  |  | _|__"<<std::endl; 
 | 
			
		||||
  std::cout << "__|_                                    _|__"<<std::endl; 
 | 
			
		||||
  std::cout << "__|_    GGGG    RRRR    III    DDDD     _|__"<<std::endl;
 | 
			
		||||
  std::cout << "__|_   G        R   R    I     D   D    _|__"<<std::endl;
 | 
			
		||||
  std::cout << "__|_   G        R   R    I     D    D   _|__"<<std::endl;
 | 
			
		||||
  std::cout << "__|_   G  GG    RRRR     I     D    D   _|__"<<std::endl;
 | 
			
		||||
  std::cout << "__|_   G   G    R  R     I     D   D    _|__"<<std::endl;
 | 
			
		||||
  std::cout << "__|_    GGGG    R   R   III    DDDD     _|__"<<std::endl;
 | 
			
		||||
  std::cout << "__|_                                    _|__"<<std::endl; 
 | 
			
		||||
  std::cout << "__|__|__|__|__|__|__|__|__|__|__|__|__|__|__"<<std::endl; 
 | 
			
		||||
  std::cout << "__|__|__|__|__|__|__|__|__|__|__|__|__|__|__"<<std::endl; 
 | 
			
		||||
  std::cout << "  |  |  |  |  |  |  |  |  |  |  |  |  |  |  "<<std::endl; 
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
  std::cout <<COL_RED  << "__|__|__|__|__"<<             "|__|__|_"<<COL_PURPLE<<"_|__|__|"<<                "__|__|__|__|__"<<std::endl; 
 | 
			
		||||
  std::cout <<COL_RED  << "__|__|__|__|__"<<             "|__|__|_"<<COL_PURPLE<<"_|__|__|"<<                "__|__|__|__|__"<<std::endl; 
 | 
			
		||||
  std::cout <<COL_RED  << "__|__|  |  |  "<<             "|  |  | "<<COL_PURPLE<<" |  |  |"<<                "  |  |  | _|__"<<std::endl; 
 | 
			
		||||
  std::cout <<COL_RED  << "__|__         "<<             "        "<<COL_PURPLE<<"        "<<                "          _|__"<<std::endl; 
 | 
			
		||||
  std::cout <<COL_RED  << "__|_  "<<COL_GREEN<<" GGGG   "<<COL_RED<<" RRRR   "<<COL_BLUE  <<" III    "<<COL_PURPLE<<"DDDD  "<<COL_PURPLE<<"    _|__"<<std::endl;
 | 
			
		||||
  std::cout <<COL_RED  << "__|_  "<<COL_GREEN<<"G       "<<COL_RED<<" R   R  "<<COL_BLUE  <<"  I     "<<COL_PURPLE<<"D   D "<<COL_PURPLE<<"    _|__"<<std::endl;
 | 
			
		||||
  std::cout <<COL_RED  << "__|_  "<<COL_GREEN<<"G       "<<COL_RED<<" R   R  "<<COL_BLUE  <<"  I     "<<COL_PURPLE<<"D    D"<<COL_PURPLE<<"    _|__"<<std::endl;
 | 
			
		||||
  std::cout <<COL_BLUE << "__|_  "<<COL_GREEN<<"G  GG   "<<COL_RED<<" RRRR   "<<COL_BLUE  <<"  I     "<<COL_PURPLE<<"D    D"<<COL_GREEN <<"    _|__"<<std::endl;
 | 
			
		||||
  std::cout <<COL_BLUE << "__|_  "<<COL_GREEN<<"G   G   "<<COL_RED<<" R  R   "<<COL_BLUE  <<"  I     "<<COL_PURPLE<<"D   D "<<COL_GREEN <<"    _|__"<<std::endl;
 | 
			
		||||
  std::cout <<COL_BLUE << "__|_  "<<COL_GREEN<<" GGGG   "<<COL_RED<<" R   R  "<<COL_BLUE  <<" III    "<<COL_PURPLE<<"DDDD  "<<COL_GREEN <<"    _|__"<<std::endl;
 | 
			
		||||
  std::cout <<COL_BLUE << "__|__         "<<             "        "<<COL_GREEN <<"        "<<                "          _|__"<<std::endl; 
 | 
			
		||||
  std::cout <<COL_BLUE << "__|__|__|__|__"<<             "|__|__|_"<<COL_GREEN <<"_|__|__|"<<                "__|__|__|__|__"<<std::endl; 
 | 
			
		||||
  std::cout <<COL_BLUE << "__|__|__|__|__"<<             "|__|__|_"<<COL_GREEN <<"_|__|__|"<<                "__|__|__|__|__"<<std::endl; 
 | 
			
		||||
  std::cout <<COL_BLUE << "  |  |  |  |  "<<             "|  |  | "<<COL_GREEN <<" |  |  |"<<                "  |  |  |  |  "<<std::endl; 
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
  std::cout <<COL_YELLOW<< std::endl;
 | 
			
		||||
  std::cout << "Copyright (C) 2015 Peter Boyle, Azusa Yamaguchi, Guido Cossu, Antonin Portelli and other authors"<<std::endl;
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
  std::cout << "This program is free software; you can redistribute it and/or modify"<<std::endl;
 | 
			
		||||
@@ -263,6 +272,7 @@ void Grid_init(int *argc,char ***argv)
 | 
			
		||||
  std::cout << "but WITHOUT ANY WARRANTY; without even the implied warranty of"<<std::endl;
 | 
			
		||||
  std::cout << "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the"<<std::endl;
 | 
			
		||||
  std::cout << "GNU General Public License for more details."<<std::endl;
 | 
			
		||||
  std::cout << COL_BACKGROUND <<std::endl;
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										72
									
								
								lib/Log.cc
									
									
									
									
									
								
							
							
						
						
									
										72
									
								
								lib/Log.cc
									
									
									
									
									
								
							@@ -25,7 +25,8 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
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
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution
 | 
			
		||||
directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
#include <Grid.h>
 | 
			
		||||
@@ -34,74 +35,43 @@ namespace Grid {
 | 
			
		||||
 | 
			
		||||
GridStopWatch Logger::StopWatch;
 | 
			
		||||
std::ostream Logger::devnull(0);
 | 
			
		||||
std::string Logger::BLACK("\033[30m");
 | 
			
		||||
std::string Logger::RED("\033[31m");
 | 
			
		||||
std::string Logger::GREEN("\033[32m");
 | 
			
		||||
std::string Logger::YELLOW("\033[33m");
 | 
			
		||||
std::string Logger::BLUE("\033[34m");
 | 
			
		||||
std::string Logger::PURPLE("\033[35m");
 | 
			
		||||
std::string Logger::CYAN("\033[36m");
 | 
			
		||||
std::string Logger::WHITE("\033[37m");
 | 
			
		||||
std::string Logger::NORMAL("\033[0;39m");
 | 
			
		||||
std::string EMPTY("");
 | 
			
		||||
 | 
			
		||||
#if 0  
 | 
			
		||||
  GridLogger GridLogError      (1,"Error",Logger::RED);
 | 
			
		||||
  GridLogger GridLogWarning    (1,"Warning",Logger::YELLOW);
 | 
			
		||||
  GridLogger GridLogMessage    (1,"Message",Logger::BLACK);
 | 
			
		||||
  GridLogger GridLogDebug      (1,"Debug",Logger::PURPLE);
 | 
			
		||||
  GridLogger GridLogPerformance(1,"Performance",Logger::GREEN);
 | 
			
		||||
  GridLogger GridLogIterative  (1,"Iterative",Logger::BLUE);
 | 
			
		||||
  GridLogger GridLogIntegrator (1,"Integrator",Logger::BLUE);
 | 
			
		||||
#else
 | 
			
		||||
  GridLogger GridLogError      (1,"Error",EMPTY);
 | 
			
		||||
  GridLogger GridLogWarning    (1,"Warning",EMPTY);
 | 
			
		||||
  GridLogger GridLogMessage    (1,"Message",EMPTY);
 | 
			
		||||
  GridLogger GridLogDebug      (1,"Debug",EMPTY);
 | 
			
		||||
  GridLogger GridLogPerformance(1,"Performance",EMPTY);
 | 
			
		||||
  GridLogger GridLogIterative  (1,"Iterative",EMPTY);
 | 
			
		||||
  GridLogger GridLogIntegrator (1,"Integrator",EMPTY);
 | 
			
		||||
#endif
 | 
			
		||||
Colours GridLogColours(0);
 | 
			
		||||
GridLogger GridLogError(1, "Error", GridLogColours, "RED");
 | 
			
		||||
GridLogger GridLogWarning(1, "Warning", GridLogColours, "YELLOW");
 | 
			
		||||
GridLogger GridLogMessage(1, "Message", GridLogColours, "NORMAL");
 | 
			
		||||
GridLogger GridLogDebug(1, "Debug", GridLogColours, "PURPLE");
 | 
			
		||||
GridLogger GridLogPerformance(1, "Performance", GridLogColours, "GREEN");
 | 
			
		||||
GridLogger GridLogIterative(1, "Iterative", GridLogColours, "BLUE");
 | 
			
		||||
GridLogger GridLogIntegrator(1, "Integrator", GridLogColours, "BLUE");
 | 
			
		||||
 | 
			
		||||
void GridLogConfigure(std::vector<std::string> &logstreams)
 | 
			
		||||
{
 | 
			
		||||
void GridLogConfigure(std::vector<std::string> &logstreams) {
 | 
			
		||||
  GridLogError.Active(0);
 | 
			
		||||
  GridLogWarning.Active(0);
 | 
			
		||||
  GridLogMessage.Active(0);
 | 
			
		||||
  GridLogMessage.Active(1); // at least the messages should be always on
 | 
			
		||||
  GridLogIterative.Active(0);
 | 
			
		||||
  GridLogDebug.Active(0);
 | 
			
		||||
  GridLogPerformance.Active(0);
 | 
			
		||||
  GridLogIntegrator.Active(0);
 | 
			
		||||
 | 
			
		||||
  int blackAndWhite = 1;
 | 
			
		||||
  if(blackAndWhite){
 | 
			
		||||
    Logger::BLACK = std::string("");
 | 
			
		||||
    Logger::RED    =Logger::BLACK;
 | 
			
		||||
    Logger::GREEN  =Logger::BLACK;
 | 
			
		||||
    Logger::YELLOW =Logger::BLACK;
 | 
			
		||||
    Logger::BLUE   =Logger::BLACK;
 | 
			
		||||
    Logger::PURPLE =Logger::BLACK;
 | 
			
		||||
    Logger::CYAN   =Logger::BLACK;
 | 
			
		||||
    Logger::WHITE  =Logger::BLACK;
 | 
			
		||||
    Logger::NORMAL =Logger::BLACK;
 | 
			
		||||
  }
 | 
			
		||||
  GridLogColours.Active(0);
 | 
			
		||||
 | 
			
		||||
  for (int i = 0; i < logstreams.size(); i++) {
 | 
			
		||||
    if (logstreams[i] == std::string("Error")) GridLogError.Active(1);
 | 
			
		||||
    if (logstreams[i] == std::string("Warning")) GridLogWarning.Active(1);
 | 
			
		||||
    if ( logstreams[i]== std::string("Message")     ) GridLogMessage.Active(1);
 | 
			
		||||
    if (logstreams[i] == std::string("NoMessage")) GridLogMessage.Active(0);
 | 
			
		||||
    if (logstreams[i] == std::string("Iterative")) GridLogIterative.Active(1);
 | 
			
		||||
    if (logstreams[i] == std::string("Debug")) GridLogDebug.Active(1);
 | 
			
		||||
    if ( logstreams[i]== std::string("Performance") ) GridLogPerformance.Active(1);
 | 
			
		||||
    if (logstreams[i] == std::string("Performance"))
 | 
			
		||||
      GridLogPerformance.Active(1);
 | 
			
		||||
    if (logstreams[i] == std::string("Integrator")) GridLogIntegrator.Active(1);
 | 
			
		||||
    if (logstreams[i] == std::string("Colours")) GridLogColours.Active(1);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////
 | 
			
		||||
// Verbose limiter on MPI tasks
 | 
			
		||||
////////////////////////////////////////////////////////////
 | 
			
		||||
void Grid_quiesce_nodes(void)
 | 
			
		||||
{
 | 
			
		||||
void Grid_quiesce_nodes(void) {
 | 
			
		||||
  int me = 0;
 | 
			
		||||
#ifdef GRID_COMMS_MPI
 | 
			
		||||
  MPI_Comm_rank(MPI_COMM_WORLD, &me);
 | 
			
		||||
@@ -114,13 +84,9 @@ void Grid_quiesce_nodes(void)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Grid_unquiesce_nodes(void)
 | 
			
		||||
{
 | 
			
		||||
void Grid_unquiesce_nodes(void) {
 | 
			
		||||
#ifdef GRID_COMMS_MPI
 | 
			
		||||
  std::cout.clear();
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										84
									
								
								lib/Log.h
									
									
									
									
									
								
							
							
						
						
									
										84
									
								
								lib/Log.h
									
									
									
									
									
								
							@@ -27,6 +27,9 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
    *************************************************************************************/
 | 
			
		||||
    /*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#include <map>
 | 
			
		||||
 | 
			
		||||
#ifndef GRID_LOG_H
 | 
			
		||||
#define GRID_LOG_H
 | 
			
		||||
 | 
			
		||||
@@ -40,39 +43,81 @@ namespace Grid {
 | 
			
		||||
int Rank(void); // used for early stage debug before library init
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Colours{
 | 
			
		||||
protected:
 | 
			
		||||
  bool is_active;
 | 
			
		||||
public:
 | 
			
		||||
  std::map<std::string, std::string> colour;
 | 
			
		||||
 | 
			
		||||
  Colours(bool activate=false){
 | 
			
		||||
    Active(activate);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  void Active(bool activate){
 | 
			
		||||
    is_active=activate;
 | 
			
		||||
 | 
			
		||||
    if (is_active){
 | 
			
		||||
     colour["BLACK"]  ="\033[30m";
 | 
			
		||||
     colour["RED"]    ="\033[31m";
 | 
			
		||||
     colour["GREEN"]  ="\033[32m";
 | 
			
		||||
     colour["YELLOW"] ="\033[33m";
 | 
			
		||||
     colour["BLUE"]   ="\033[34m";
 | 
			
		||||
     colour["PURPLE"] ="\033[35m";
 | 
			
		||||
     colour["CYAN"]   ="\033[36m";
 | 
			
		||||
     colour["WHITE"]  ="\033[37m";
 | 
			
		||||
     colour["NORMAL"] ="\033[0;39m";
 | 
			
		||||
   } else {
 | 
			
		||||
    colour["BLACK"] ="";
 | 
			
		||||
    colour["RED"]   ="";
 | 
			
		||||
    colour["GREEN"] ="";
 | 
			
		||||
    colour["YELLOW"]="";
 | 
			
		||||
    colour["BLUE"]  ="";
 | 
			
		||||
    colour["PURPLE"]="";
 | 
			
		||||
    colour["CYAN"]  ="";
 | 
			
		||||
    colour["WHITE"] ="";
 | 
			
		||||
    colour["NORMAL"]="";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Logger {
 | 
			
		||||
protected:
 | 
			
		||||
  Colours &Painter;
 | 
			
		||||
  int active;
 | 
			
		||||
    std::string name, topName, COLOUR;
 | 
			
		||||
  std::string name, topName;
 | 
			
		||||
  std::string COLOUR;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  static GridStopWatch StopWatch;
 | 
			
		||||
  static std::ostream devnull;
 | 
			
		||||
 | 
			
		||||
    static std::string BLACK;
 | 
			
		||||
    static std::string RED  ;
 | 
			
		||||
    static std::string GREEN;
 | 
			
		||||
    static std::string YELLOW;
 | 
			
		||||
    static std::string BLUE  ;
 | 
			
		||||
    static std::string PURPLE;
 | 
			
		||||
    static std::string CYAN  ;
 | 
			
		||||
    static std::string WHITE ;
 | 
			
		||||
    static std::string NORMAL;
 | 
			
		||||
  std::string background() {return Painter.colour["NORMAL"];}
 | 
			
		||||
  std::string evidence() {return Painter.colour["YELLOW"];}
 | 
			
		||||
  std::string colour() {return Painter.colour[COLOUR];}
 | 
			
		||||
 | 
			
		||||
 Logger(std::string topNm, int on, std::string nm,std::string col)
 | 
			
		||||
   : active(on), name(nm), topName(topNm), COLOUR(col) {};
 | 
			
		||||
  Logger(std::string topNm, int on, std::string nm, Colours& col_class, std::string col)
 | 
			
		||||
  : active(on),
 | 
			
		||||
  name(nm),
 | 
			
		||||
  topName(topNm),
 | 
			
		||||
  Painter(col_class),
 | 
			
		||||
  COLOUR(col){} ;
 | 
			
		||||
  
 | 
			
		||||
  void Active(int on) {active = on;};
 | 
			
		||||
  int  isActive(void) {return active;};
 | 
			
		||||
  
 | 
			
		||||
    friend std::ostream& operator<< (std::ostream& stream, const Logger& log){
 | 
			
		||||
  friend std::ostream& operator<< (std::ostream& stream, Logger& log){
 | 
			
		||||
 | 
			
		||||
    if ( log.active ) {
 | 
			
		||||
      StopWatch.Stop();
 | 
			
		||||
      GridTime now = StopWatch.Elapsed();
 | 
			
		||||
      StopWatch.Start();
 | 
			
		||||
            stream << BLACK <<std::setw(8) << std::left << log.topName << BLACK<< " : ";
 | 
			
		||||
            stream << log.COLOUR <<std::setw(11)  << log.name << BLACK << " : ";
 | 
			
		||||
            stream << YELLOW <<std::setw(6) << now <<BLACK << " : " ;
 | 
			
		||||
            stream << log.COLOUR;
 | 
			
		||||
      stream << log.background()<< log.topName << log.background()<< " : ";
 | 
			
		||||
      stream << log.colour() <<std::setw(14) << std::left << log.name << log.background() << " : ";
 | 
			
		||||
      stream << log.evidence()<< now << log.background() << " : " << log.colour();
 | 
			
		||||
      return stream;
 | 
			
		||||
    } else { 
 | 
			
		||||
      return devnull;
 | 
			
		||||
@@ -83,7 +128,8 @@ public:
 | 
			
		||||
 | 
			
		||||
class GridLogger: public Logger {
 | 
			
		||||
public:
 | 
			
		||||
 GridLogger(int on, std::string nm, std::string col = Logger::BLACK): Logger("Grid", on, nm, col){};
 | 
			
		||||
  GridLogger(int on, std::string nm, Colours&col_class, std::string col_key = "NORMAL"):
 | 
			
		||||
  Logger("Grid", on, nm, col_class, col_key){};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void GridLogConfigure(std::vector<std::string> &logstreams);
 | 
			
		||||
@@ -95,6 +141,7 @@ extern GridLogger GridLogDebug  ;
 | 
			
		||||
extern GridLogger GridLogPerformance;
 | 
			
		||||
extern GridLogger GridLogIterative  ;
 | 
			
		||||
extern GridLogger GridLogIntegrator  ;
 | 
			
		||||
extern Colours    GridLogColours;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define _NBACKTRACE (256)
 | 
			
		||||
@@ -128,5 +175,6 @@ extern void * Grid_backtrace_buffer[_NBACKTRACE];
 | 
			
		||||
 | 
			
		||||
#define BACKTRACE() BACKTRACEFP(stdout) 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										11
									
								
								lib/Simd.h
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								lib/Simd.h
									
									
									
									
									
								
							@@ -24,7 +24,8 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
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
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution
 | 
			
		||||
directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
#ifndef GRID_SIMD_H
 | 
			
		||||
@@ -118,6 +119,14 @@ namespace Grid {
 | 
			
		||||
  inline ComplexD timesI(const ComplexD &r)     { return(r*ComplexD(0.0,1.0));}
 | 
			
		||||
  inline ComplexF timesMinusI(const ComplexF &r){ return(r*ComplexF(0.0,-1.0));}
 | 
			
		||||
  inline ComplexD timesMinusI(const ComplexD &r){ return(r*ComplexD(0.0,-1.0));}
 | 
			
		||||
 | 
			
		||||
  // define projections to real and imaginay parts
 | 
			
		||||
  inline ComplexF projReal(const ComplexF &r){return( ComplexF(std::real(r), 0.0));}
 | 
			
		||||
  inline ComplexD projReal(const ComplexD &r){return( ComplexD(std::real(r), 0.0));}
 | 
			
		||||
  inline ComplexF projImag(const ComplexF &r){return (ComplexF(std::imag(r), 0.0 ));}
 | 
			
		||||
  inline ComplexD projImag(const ComplexD &r){return (ComplexD(std::imag(r), 0.0));}
 | 
			
		||||
 | 
			
		||||
  // define auxiliary functions for complex computations
 | 
			
		||||
  inline void timesI(ComplexF &ret,const ComplexF &r)     { ret = timesI(r);}
 | 
			
		||||
  inline void timesI(ComplexD &ret,const ComplexD &r)     { ret = timesI(r);}
 | 
			
		||||
  inline void timesMinusI(ComplexF &ret,const ComplexF &r){ ret = timesMinusI(r);}
 | 
			
		||||
 
 | 
			
		||||
@@ -24,16 +24,17 @@ Author: neo <cossu@post.kek.jp>
 | 
			
		||||
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
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution
 | 
			
		||||
directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
#ifndef GRID_LATTICE_ET_H
 | 
			
		||||
#define GRID_LATTICE_ET_H
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <tuple>
 | 
			
		||||
#include <typeinfo>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
@@ -41,8 +42,8 @@ namespace Grid {
 | 
			
		||||
// Predicated where support
 | 
			
		||||
////////////////////////////////////////////////////
 | 
			
		||||
template <class iobj, class vobj, class robj>
 | 
			
		||||
    inline vobj predicatedWhere(const iobj &predicate,const vobj &iftrue,const robj &iffalse) {
 | 
			
		||||
 | 
			
		||||
inline vobj predicatedWhere(const iobj &predicate, const vobj &iftrue,
 | 
			
		||||
                            const robj &iffalse) {
 | 
			
		||||
  typename std::remove_const<vobj>::type ret;
 | 
			
		||||
 | 
			
		||||
  typedef typename vobj::scalar_object scalar_object;
 | 
			
		||||
@@ -75,10 +76,13 @@ namespace Grid {
 | 
			
		||||
// from tuple is hideous; C++14 introduces std::make_index_sequence for this
 | 
			
		||||
////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// leaf eval of lattice ; should enable if protect using traits
 | 
			
		||||
 | 
			
		||||
template <typename T> using is_lattice      = std::is_base_of<LatticeBase,T >;
 | 
			
		||||
template <typename T>
 | 
			
		||||
using is_lattice = std::is_base_of<LatticeBase, T>;
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
using is_lattice_expr = std::is_base_of<LatticeExpressionBase, T>;
 | 
			
		||||
 | 
			
		||||
template <typename T> using is_lattice_expr = std::is_base_of<LatticeExpressionBase,T >;
 | 
			
		||||
 | 
			
		||||
@@ -94,37 +98,47 @@ inline sobj eval(const unsigned int ss, const sobj &arg)
 | 
			
		||||
  return arg;
 | 
			
		||||
}
 | 
			
		||||
template <class lobj>
 | 
			
		||||
inline const lobj &eval(const unsigned int ss, const Lattice<lobj> &arg)
 | 
			
		||||
{
 | 
			
		||||
inline const lobj &eval(const unsigned int ss, const Lattice<lobj> &arg) {
 | 
			
		||||
  return arg._odata[ss];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// handle nodes in syntax tree
 | 
			
		||||
template <typename Op, typename T1>
 | 
			
		||||
auto inline eval(const unsigned int ss, const LatticeUnaryExpression<Op,T1 > &expr) // eval one operand
 | 
			
		||||
  -> decltype(expr.first.func(eval(ss,std::get<0>(expr.second))))
 | 
			
		||||
{
 | 
			
		||||
auto inline eval(
 | 
			
		||||
    const unsigned int ss,
 | 
			
		||||
    const LatticeUnaryExpression<Op, T1> &expr)  // eval one operand
 | 
			
		||||
    -> decltype(expr.first.func(eval(ss, std::get<0>(expr.second)))) {
 | 
			
		||||
  return expr.first.func(eval(ss, std::get<0>(expr.second)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Op, typename T1, typename T2>
 | 
			
		||||
auto inline eval(const unsigned int ss, const LatticeBinaryExpression<Op,T1,T2> &expr) // eval two operands
 | 
			
		||||
  -> decltype(expr.first.func(eval(ss,std::get<0>(expr.second)),eval(ss,std::get<1>(expr.second))))
 | 
			
		||||
{
 | 
			
		||||
  return expr.first.func(eval(ss,std::get<0>(expr.second)),eval(ss,std::get<1>(expr.second)));
 | 
			
		||||
auto inline eval(
 | 
			
		||||
    const unsigned int ss,
 | 
			
		||||
    const LatticeBinaryExpression<Op, T1, T2> &expr)  // eval two operands
 | 
			
		||||
    -> decltype(expr.first.func(eval(ss, std::get<0>(expr.second)),
 | 
			
		||||
                                eval(ss, std::get<1>(expr.second)))) {
 | 
			
		||||
  return expr.first.func(eval(ss, std::get<0>(expr.second)),
 | 
			
		||||
                         eval(ss, std::get<1>(expr.second)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Op, typename T1, typename T2, typename T3>
 | 
			
		||||
auto inline eval(const unsigned int ss, const LatticeTrinaryExpression<Op,T1,T2,T3 > &expr) // eval three operands
 | 
			
		||||
  -> decltype(expr.first.func(eval(ss,std::get<0>(expr.second)),eval(ss,std::get<1>(expr.second)),eval(ss,std::get<2>(expr.second))))
 | 
			
		||||
{
 | 
			
		||||
  return expr.first.func(eval(ss,std::get<0>(expr.second)),eval(ss,std::get<1>(expr.second)),eval(ss,std::get<2>(expr.second)) );
 | 
			
		||||
auto inline eval(const unsigned int ss,
 | 
			
		||||
                 const LatticeTrinaryExpression<Op, T1, T2, T3>
 | 
			
		||||
                     &expr)  // eval three operands
 | 
			
		||||
    -> decltype(expr.first.func(eval(ss, std::get<0>(expr.second)),
 | 
			
		||||
                                eval(ss, std::get<1>(expr.second)),
 | 
			
		||||
                                eval(ss, std::get<2>(expr.second)))) {
 | 
			
		||||
  return expr.first.func(eval(ss, std::get<0>(expr.second)),
 | 
			
		||||
                         eval(ss, std::get<1>(expr.second)),
 | 
			
		||||
                         eval(ss, std::get<2>(expr.second)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Obtain the grid from an expression, ensuring conformable. This must follow a tree recursion
 | 
			
		||||
// Obtain the grid from an expression, ensuring conformable. This must follow a
 | 
			
		||||
// tree recursion
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////
 | 
			
		||||
template<class T1, typename std::enable_if<is_lattice<T1>::value, T1>::type * =nullptr >
 | 
			
		||||
template <class T1,
 | 
			
		||||
          typename std::enable_if<is_lattice<T1>::value, T1>::type * = nullptr>
 | 
			
		||||
inline void GridFromExpression(GridBase *&grid, const T1 &lat)  // Lattice leaf
 | 
			
		||||
{
 | 
			
		||||
  if (grid) {
 | 
			
		||||
@@ -132,35 +146,37 @@ inline void GridFromExpression(GridBase * &grid,const T1& lat)   // Lattice leaf
 | 
			
		||||
  }
 | 
			
		||||
  grid = lat._grid;
 | 
			
		||||
}
 | 
			
		||||
template<class T1,typename std::enable_if<!is_lattice<T1>::value, T1>::type * = nullptr >
 | 
			
		||||
inline void GridFromExpression(GridBase * &grid,const T1& notlat)   // non-lattice leaf
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
template <class T1,
 | 
			
		||||
          typename std::enable_if<!is_lattice<T1>::value, T1>::type * = nullptr>
 | 
			
		||||
inline void GridFromExpression(GridBase *&grid,
 | 
			
		||||
                               const T1 ¬lat)  // non-lattice leaf
 | 
			
		||||
{}
 | 
			
		||||
template <typename Op, typename T1>
 | 
			
		||||
inline void GridFromExpression(GridBase * &grid,const LatticeUnaryExpression<Op,T1 > &expr)
 | 
			
		||||
{
 | 
			
		||||
inline void GridFromExpression(GridBase *&grid,
 | 
			
		||||
                               const LatticeUnaryExpression<Op, T1> &expr) {
 | 
			
		||||
  GridFromExpression(grid, std::get<0>(expr.second));  // recurse
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Op, typename T1, typename T2>
 | 
			
		||||
inline void GridFromExpression(GridBase * &grid,const LatticeBinaryExpression<Op,T1,T2> &expr) 
 | 
			
		||||
{
 | 
			
		||||
inline void GridFromExpression(
 | 
			
		||||
    GridBase *&grid, const LatticeBinaryExpression<Op, T1, T2> &expr) {
 | 
			
		||||
  GridFromExpression(grid, std::get<0>(expr.second));  // recurse
 | 
			
		||||
  GridFromExpression(grid, std::get<1>(expr.second));
 | 
			
		||||
}
 | 
			
		||||
template <typename Op, typename T1, typename T2, typename T3>
 | 
			
		||||
inline void GridFromExpression( GridBase * &grid,const LatticeTrinaryExpression<Op,T1,T2,T3 > &expr) 
 | 
			
		||||
{
 | 
			
		||||
inline void GridFromExpression(
 | 
			
		||||
    GridBase *&grid, const LatticeTrinaryExpression<Op, T1, T2, T3> &expr) {
 | 
			
		||||
  GridFromExpression(grid, std::get<0>(expr.second));  // recurse
 | 
			
		||||
  GridFromExpression(grid, std::get<1>(expr.second));
 | 
			
		||||
  GridFromExpression(grid, std::get<2>(expr.second));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Obtain the CB from an expression, ensuring conformable. This must follow a tree recursion
 | 
			
		||||
// Obtain the CB from an expression, ensuring conformable. This must follow a
 | 
			
		||||
// tree recursion
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////
 | 
			
		||||
template<class T1, typename std::enable_if<is_lattice<T1>::value, T1>::type * =nullptr >
 | 
			
		||||
template <class T1,
 | 
			
		||||
          typename std::enable_if<is_lattice<T1>::value, T1>::type * = nullptr>
 | 
			
		||||
inline void CBFromExpression(int &cb, const T1 &lat)  // Lattice leaf
 | 
			
		||||
{
 | 
			
		||||
  if ((cb == Odd) || (cb == Even)) {
 | 
			
		||||
@@ -169,28 +185,29 @@ inline void CBFromExpression(int &cb,const T1& lat)   // Lattice leaf
 | 
			
		||||
  cb = lat.checkerboard;
 | 
			
		||||
  //  std::cout<<GridLogMessage<<"Lattice leaf cb "<<cb<<std::endl;
 | 
			
		||||
}
 | 
			
		||||
template<class T1,typename std::enable_if<!is_lattice<T1>::value, T1>::type * = nullptr >
 | 
			
		||||
template <class T1,
 | 
			
		||||
          typename std::enable_if<!is_lattice<T1>::value, T1>::type * = nullptr>
 | 
			
		||||
inline void CBFromExpression(int &cb, const T1 ¬lat)  // non-lattice leaf
 | 
			
		||||
{
 | 
			
		||||
  //  std::cout<<GridLogMessage<<"Non lattice leaf cb"<<cb<<std::endl;
 | 
			
		||||
}
 | 
			
		||||
template <typename Op, typename T1>
 | 
			
		||||
inline void CBFromExpression(int &cb,const LatticeUnaryExpression<Op,T1 > &expr)
 | 
			
		||||
{
 | 
			
		||||
inline void CBFromExpression(int &cb,
 | 
			
		||||
                             const LatticeUnaryExpression<Op, T1> &expr) {
 | 
			
		||||
  CBFromExpression(cb, std::get<0>(expr.second));  // recurse
 | 
			
		||||
  //  std::cout<<GridLogMessage<<"Unary node cb "<<cb<<std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Op, typename T1, typename T2>
 | 
			
		||||
inline void CBFromExpression(int &cb,const LatticeBinaryExpression<Op,T1,T2> &expr) 
 | 
			
		||||
{
 | 
			
		||||
inline void CBFromExpression(int &cb,
 | 
			
		||||
                             const LatticeBinaryExpression<Op, T1, T2> &expr) {
 | 
			
		||||
  CBFromExpression(cb, std::get<0>(expr.second));  // recurse
 | 
			
		||||
  CBFromExpression(cb, std::get<1>(expr.second));
 | 
			
		||||
  //  std::cout<<GridLogMessage<<"Binary node cb "<<cb<<std::endl;
 | 
			
		||||
}
 | 
			
		||||
template <typename Op, typename T1, typename T2, typename T3>
 | 
			
		||||
inline void CBFromExpression( int &cb,const LatticeTrinaryExpression<Op,T1,T2,T3 > &expr) 
 | 
			
		||||
{
 | 
			
		||||
inline void CBFromExpression(
 | 
			
		||||
    int &cb, const LatticeTrinaryExpression<Op, T1, T2, T3> &expr) {
 | 
			
		||||
  CBFromExpression(cb, std::get<0>(expr.second));  // recurse
 | 
			
		||||
  CBFromExpression(cb, std::get<1>(expr.second));
 | 
			
		||||
  CBFromExpression(cb, std::get<2>(expr.second));
 | 
			
		||||
@@ -201,8 +218,8 @@ inline void CBFromExpression( int &cb,const LatticeTrinaryExpression<Op,T1,T2,T3
 | 
			
		||||
// Unary operators and funcs
 | 
			
		||||
////////////////////////////////////////////
 | 
			
		||||
#define GridUnopClass(name, ret)                                          \
 | 
			
		||||
template <class arg> struct name\
 | 
			
		||||
{\
 | 
			
		||||
  template <class arg>                                                    \
 | 
			
		||||
  struct name {                                                           \
 | 
			
		||||
    static auto inline func(const arg a) -> decltype(ret) { return ret; } \
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
@@ -218,11 +235,15 @@ GridUnopClass(UnaryReal,real(a));
 | 
			
		||||
GridUnopClass(UnaryImag, imag(a));
 | 
			
		||||
GridUnopClass(UnaryToReal, toReal(a));
 | 
			
		||||
GridUnopClass(UnaryToComplex, toComplex(a));
 | 
			
		||||
GridUnopClass(UnaryTimesI, timesI(a));
 | 
			
		||||
GridUnopClass(UnaryTimesMinusI, timesMinusI(a));
 | 
			
		||||
GridUnopClass(UnaryAbs, abs(a));
 | 
			
		||||
GridUnopClass(UnarySqrt, sqrt(a));
 | 
			
		||||
GridUnopClass(UnaryRsqrt, rsqrt(a));
 | 
			
		||||
GridUnopClass(UnarySin, sin(a));
 | 
			
		||||
GridUnopClass(UnaryCos, cos(a));
 | 
			
		||||
GridUnopClass(UnaryAsin, asin(a));
 | 
			
		||||
GridUnopClass(UnaryAcos, acos(a));
 | 
			
		||||
GridUnopClass(UnaryLog, log(a));
 | 
			
		||||
GridUnopClass(UnaryExp, exp(a));
 | 
			
		||||
 | 
			
		||||
@@ -231,10 +252,9 @@ GridUnopClass(UnaryExp,exp(a));
 | 
			
		||||
////////////////////////////////////////////
 | 
			
		||||
#define GridBinOpClass(name, combination)                      \
 | 
			
		||||
  template <class left, class right>                           \
 | 
			
		||||
struct name\
 | 
			
		||||
{\
 | 
			
		||||
  static auto inline func(const left &lhs,const right &rhs)-> decltype(combination) const \
 | 
			
		||||
    {\
 | 
			
		||||
  struct name {                                                \
 | 
			
		||||
    static auto inline func(const left &lhs, const right &rhs) \
 | 
			
		||||
        -> decltype(combination) const {                       \
 | 
			
		||||
      return combination;                                      \
 | 
			
		||||
    }                                                          \
 | 
			
		||||
  }
 | 
			
		||||
@@ -252,17 +272,18 @@ GridBinOpClass(BinaryOrOr  ,lhs||rhs);
 | 
			
		||||
////////////////////////////////////////////////////
 | 
			
		||||
#define GridTrinOpClass(name, combination)                                     \
 | 
			
		||||
  template <class predicate, class left, class right>                          \
 | 
			
		||||
struct name\
 | 
			
		||||
{\
 | 
			
		||||
  static auto inline func(const predicate &pred,const left &lhs,const right &rhs)-> decltype(combination) const \
 | 
			
		||||
    {\
 | 
			
		||||
  struct name {                                                                \
 | 
			
		||||
    static auto inline func(const predicate &pred, const left &lhs,            \
 | 
			
		||||
                            const right &rhs) -> decltype(combination) const { \
 | 
			
		||||
      return combination;                                                      \
 | 
			
		||||
    }                                                                          \
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
GridTrinOpClass(TrinaryWhere,(predicatedWhere<predicate, \
 | 
			
		||||
			       typename std::remove_reference<left>::type, \
 | 
			
		||||
			       typename std::remove_reference<right>::type> (pred,lhs,rhs)));
 | 
			
		||||
GridTrinOpClass(
 | 
			
		||||
    TrinaryWhere,
 | 
			
		||||
    (predicatedWhere<predicate, typename std::remove_reference<left>::type,
 | 
			
		||||
                     typename std::remove_reference<right>::type>(pred, lhs,
 | 
			
		||||
                                                                  rhs)));
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////
 | 
			
		||||
// Operator syntactical glue
 | 
			
		||||
@@ -270,49 +291,66 @@ GridTrinOpClass(TrinaryWhere,(predicatedWhere<predicate, \
 | 
			
		||||
 | 
			
		||||
#define GRID_UNOP(name) name<decltype(eval(0, arg))>
 | 
			
		||||
#define GRID_BINOP(name) name<decltype(eval(0, lhs)), decltype(eval(0, rhs))>
 | 
			
		||||
#define GRID_TRINOP(name) name<decltype(eval(0, pred)), decltype(eval(0, lhs)), decltype(eval(0, rhs))>
 | 
			
		||||
#define GRID_TRINOP(name) \
 | 
			
		||||
  name<decltype(eval(0, pred)), decltype(eval(0, lhs)), decltype(eval(0, rhs))>
 | 
			
		||||
 | 
			
		||||
#define GRID_DEF_UNOP(op, name)                                             \
 | 
			
		||||
  template <typename T1,                                                    \
 | 
			
		||||
  typename std::enable_if<is_lattice<T1>::value||is_lattice_expr<T1>::value, T1>::type* = nullptr> inline auto op(const T1 &arg) \
 | 
			
		||||
  -> decltype(LatticeUnaryExpression<GRID_UNOP(name),const T1&>(std::make_pair(GRID_UNOP(name)(),std::forward_as_tuple(arg)))) \
 | 
			
		||||
{ return LatticeUnaryExpression<GRID_UNOP(name), const T1 &>(std::make_pair(GRID_UNOP(name)(),std::forward_as_tuple(arg))); }
 | 
			
		||||
            typename std::enable_if<is_lattice<T1>::value ||                \
 | 
			
		||||
                                        is_lattice_expr<T1>::value,         \
 | 
			
		||||
                                    T1>::type * = nullptr>                  \
 | 
			
		||||
  inline auto op(const T1 &arg)                                             \
 | 
			
		||||
      ->decltype(LatticeUnaryExpression<GRID_UNOP(name), const T1 &>(       \
 | 
			
		||||
          std::make_pair(GRID_UNOP(name)(), std::forward_as_tuple(arg)))) { \
 | 
			
		||||
    return LatticeUnaryExpression<GRID_UNOP(name), const T1 &>(             \
 | 
			
		||||
        std::make_pair(GRID_UNOP(name)(), std::forward_as_tuple(arg)));     \
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#define GRID_BINOP_LEFT(op, name)                                             \
 | 
			
		||||
  template <typename T1, typename T2,                                         \
 | 
			
		||||
          typename std::enable_if<is_lattice<T1>::value||is_lattice_expr<T1>::value, T1>::type* = nullptr>\
 | 
			
		||||
            typename std::enable_if<is_lattice<T1>::value ||                  \
 | 
			
		||||
                                        is_lattice_expr<T1>::value,           \
 | 
			
		||||
                                    T1>::type * = nullptr>                    \
 | 
			
		||||
  inline auto op(const T1 &lhs, const T2 &rhs)                                \
 | 
			
		||||
  -> decltype(LatticeBinaryExpression<GRID_BINOP(name),const T1&,const T2 &>(std::make_pair(GRID_BINOP(name)(),\
 | 
			
		||||
											    std::forward_as_tuple(lhs, rhs)))) \
 | 
			
		||||
{\
 | 
			
		||||
 return LatticeBinaryExpression<GRID_BINOP(name), const T1 &, const T2 &>(std::make_pair(GRID_BINOP(name)(),\
 | 
			
		||||
									  std::forward_as_tuple(lhs, rhs))); \
 | 
			
		||||
      ->decltype(                                                             \
 | 
			
		||||
          LatticeBinaryExpression<GRID_BINOP(name), const T1 &, const T2 &>(  \
 | 
			
		||||
              std::make_pair(GRID_BINOP(name)(),                              \
 | 
			
		||||
                             std::forward_as_tuple(lhs, rhs)))) {             \
 | 
			
		||||
    return LatticeBinaryExpression<GRID_BINOP(name), const T1 &, const T2 &>( \
 | 
			
		||||
        std::make_pair(GRID_BINOP(name)(), std::forward_as_tuple(lhs, rhs))); \
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#define GRID_BINOP_RIGHT(op, name)                                            \
 | 
			
		||||
  template <typename T1, typename T2,                                         \
 | 
			
		||||
           typename std::enable_if<!is_lattice<T1>::value && !is_lattice_expr<T1>::value, T1>::type* = nullptr,\
 | 
			
		||||
           typename std::enable_if< is_lattice<T2>::value ||  is_lattice_expr<T2>::value, T2>::type* = nullptr> \
 | 
			
		||||
            typename std::enable_if<!is_lattice<T1>::value &&                 \
 | 
			
		||||
                                        !is_lattice_expr<T1>::value,          \
 | 
			
		||||
                                    T1>::type * = nullptr,                    \
 | 
			
		||||
            typename std::enable_if<is_lattice<T2>::value ||                  \
 | 
			
		||||
                                        is_lattice_expr<T2>::value,           \
 | 
			
		||||
                                    T2>::type * = nullptr>                    \
 | 
			
		||||
  inline auto op(const T1 &lhs, const T2 &rhs)                                \
 | 
			
		||||
  -> decltype(LatticeBinaryExpression<GRID_BINOP(name),const T1&,const T2 &>(std::make_pair(GRID_BINOP(name)(),\
 | 
			
		||||
											    std::forward_as_tuple(lhs, rhs)))) \
 | 
			
		||||
{\
 | 
			
		||||
 return LatticeBinaryExpression<GRID_BINOP(name), const T1 &, const T2 &>(std::make_pair(GRID_BINOP(name)(),\
 | 
			
		||||
								          std::forward_as_tuple(lhs, rhs))); \
 | 
			
		||||
      ->decltype(                                                             \
 | 
			
		||||
          LatticeBinaryExpression<GRID_BINOP(name), const T1 &, const T2 &>(  \
 | 
			
		||||
              std::make_pair(GRID_BINOP(name)(),                              \
 | 
			
		||||
                             std::forward_as_tuple(lhs, rhs)))) {             \
 | 
			
		||||
    return LatticeBinaryExpression<GRID_BINOP(name), const T1 &, const T2 &>( \
 | 
			
		||||
        std::make_pair(GRID_BINOP(name)(), std::forward_as_tuple(lhs, rhs))); \
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#define GRID_DEF_BINOP(op, name) \
 | 
			
		||||
  GRID_BINOP_LEFT(op, name);     \
 | 
			
		||||
  GRID_BINOP_RIGHT(op, name);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define GRID_DEF_TRINOP(op, name)                                              \
 | 
			
		||||
template <typename T1,typename T2,typename T3> inline auto op(const T1 &pred,const T2&lhs,const T3 &rhs) \
 | 
			
		||||
  -> decltype(LatticeTrinaryExpression<GRID_TRINOP(name),const T1&,const T2 &,const T3&>(std::make_pair(GRID_TRINOP(name)(),\
 | 
			
		||||
										   std::forward_as_tuple(pred,lhs,rhs)))) \
 | 
			
		||||
{\
 | 
			
		||||
  return LatticeTrinaryExpression<GRID_TRINOP(name), const T1 &, const T2 &,const T3&>(std::make_pair(GRID_TRINOP(name)(), \
 | 
			
		||||
										 std::forward_as_tuple(pred,lhs, rhs))); \
 | 
			
		||||
  template <typename T1, typename T2, typename T3>                             \
 | 
			
		||||
  inline auto op(const T1 &pred, const T2 &lhs, const T3 &rhs)                 \
 | 
			
		||||
      ->decltype(                                                              \
 | 
			
		||||
          LatticeTrinaryExpression<GRID_TRINOP(name), const T1 &, const T2 &,  \
 | 
			
		||||
                                   const T3 &>(std::make_pair(                 \
 | 
			
		||||
              GRID_TRINOP(name)(), std::forward_as_tuple(pred, lhs, rhs)))) {  \
 | 
			
		||||
    return LatticeTrinaryExpression<GRID_TRINOP(name), const T1 &, const T2 &, \
 | 
			
		||||
                                    const T3 &>(std::make_pair(                \
 | 
			
		||||
        GRID_TRINOP(name)(), std::forward_as_tuple(pred, lhs, rhs)));          \
 | 
			
		||||
  }
 | 
			
		||||
////////////////////////
 | 
			
		||||
// Operator definitions
 | 
			
		||||
@@ -331,11 +369,16 @@ GRID_DEF_UNOP(real,UnaryReal);
 | 
			
		||||
GRID_DEF_UNOP(imag, UnaryImag);
 | 
			
		||||
GRID_DEF_UNOP(toReal, UnaryToReal);
 | 
			
		||||
GRID_DEF_UNOP(toComplex, UnaryToComplex);
 | 
			
		||||
GRID_DEF_UNOP(abs  ,UnaryAbs); //abs overloaded in cmath C++98; DON'T do the abs-fabs-dabs-labs thing
 | 
			
		||||
GRID_DEF_UNOP(timesI, UnaryTimesI);
 | 
			
		||||
GRID_DEF_UNOP(timesMinusI, UnaryTimesMinusI);
 | 
			
		||||
GRID_DEF_UNOP(abs, UnaryAbs);  // abs overloaded in cmath C++98; DON'T do the
 | 
			
		||||
                               // abs-fabs-dabs-labs thing
 | 
			
		||||
GRID_DEF_UNOP(sqrt, UnarySqrt);
 | 
			
		||||
GRID_DEF_UNOP(rsqrt, UnaryRsqrt);
 | 
			
		||||
GRID_DEF_UNOP(sin, UnarySin);
 | 
			
		||||
GRID_DEF_UNOP(cos, UnaryCos);
 | 
			
		||||
GRID_DEF_UNOP(asin, UnaryAsin);
 | 
			
		||||
GRID_DEF_UNOP(acos, UnaryAcos);
 | 
			
		||||
GRID_DEF_UNOP(log, UnaryLog);
 | 
			
		||||
GRID_DEF_UNOP(exp, UnaryExp);
 | 
			
		||||
 | 
			
		||||
@@ -355,29 +398,29 @@ GRID_DEF_TRINOP(where,TrinaryWhere);
 | 
			
		||||
/////////////////////////////////////////////////////////////
 | 
			
		||||
template <class Op, class T1>
 | 
			
		||||
auto closure(const LatticeUnaryExpression<Op, T1> &expr)
 | 
			
		||||
  -> Lattice<decltype(expr.first.func(eval(0,std::get<0>(expr.second))))>
 | 
			
		||||
{
 | 
			
		||||
  Lattice<decltype(expr.first.func(eval(0,std::get<0>(expr.second))))> ret(expr);
 | 
			
		||||
    -> Lattice<decltype(expr.first.func(eval(0, std::get<0>(expr.second))))> {
 | 
			
		||||
  Lattice<decltype(expr.first.func(eval(0, std::get<0>(expr.second))))> ret(
 | 
			
		||||
      expr);
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
template <class Op, class T1, class T2>
 | 
			
		||||
auto closure(const LatticeBinaryExpression<Op, T1, T2> &expr)
 | 
			
		||||
    -> Lattice<decltype(expr.first.func(eval(0, std::get<0>(expr.second)),
 | 
			
		||||
				      eval(0,std::get<1>(expr.second))))>
 | 
			
		||||
{
 | 
			
		||||
                                        eval(0, std::get<1>(expr.second))))> {
 | 
			
		||||
  Lattice<decltype(expr.first.func(eval(0, std::get<0>(expr.second)),
 | 
			
		||||
				   eval(0,std::get<1>(expr.second))))> ret(expr);
 | 
			
		||||
                                   eval(0, std::get<1>(expr.second))))>
 | 
			
		||||
      ret(expr);
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
template <class Op, class T1, class T2, class T3>
 | 
			
		||||
auto closure(const LatticeTrinaryExpression<Op, T1, T2, T3> &expr)
 | 
			
		||||
    -> Lattice<decltype(expr.first.func(eval(0, std::get<0>(expr.second)),
 | 
			
		||||
                                        eval(0, std::get<1>(expr.second)),
 | 
			
		||||
				      eval(0,std::get<2>(expr.second))))>
 | 
			
		||||
{
 | 
			
		||||
                                        eval(0, std::get<2>(expr.second))))> {
 | 
			
		||||
  Lattice<decltype(expr.first.func(eval(0, std::get<0>(expr.second)),
 | 
			
		||||
                                   eval(0, std::get<1>(expr.second)),
 | 
			
		||||
				   eval(0,std::get<2>(expr.second))))> ret(expr);
 | 
			
		||||
                                   eval(0, std::get<2>(expr.second))))>
 | 
			
		||||
      ret(expr);
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -388,7 +431,6 @@ template<class Op,class T1, class T2, class T3>
 | 
			
		||||
#undef GRID_DEF_UNOP
 | 
			
		||||
#undef GRID_DEF_BINOP
 | 
			
		||||
#undef GRID_DEF_TRINOP
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,8 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
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
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution
 | 
			
		||||
directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
#ifndef GRID_LATTICE_BASE_H
 | 
			
		||||
@@ -255,6 +256,18 @@ PARALLEL_FOR_LOOP
 | 
			
		||||
        checkerboard=0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Lattice(const Lattice& r){ // copy constructor
 | 
			
		||||
    	_grid = r._grid;
 | 
			
		||||
    	checkerboard = r.checkerboard;
 | 
			
		||||
    	_odata.resize(_grid->oSites());// essential
 | 
			
		||||
  		PARALLEL_FOR_LOOP
 | 
			
		||||
        for(int ss=0;ss<_grid->oSites();ss++){
 | 
			
		||||
            _odata[ss]=r._odata[ss];
 | 
			
		||||
        }  	
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    virtual ~Lattice(void) = default;
 | 
			
		||||
    
 | 
			
		||||
    template<class sobj> strong_inline Lattice<vobj> & operator = (const sobj & r){
 | 
			
		||||
@@ -267,7 +280,7 @@ PARALLEL_FOR_LOOP
 | 
			
		||||
    template<class robj> strong_inline Lattice<vobj> & operator = (const Lattice<robj> & r){
 | 
			
		||||
      this->checkerboard = r.checkerboard;
 | 
			
		||||
      conformable(*this,r);
 | 
			
		||||
      std::cout<<GridLogMessage<<"Lattice operator ="<<std::endl;
 | 
			
		||||
      
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
        for(int ss=0;ss<_grid->oSites();ss++){
 | 
			
		||||
            this->_odata[ss]=r._odata[ss];
 | 
			
		||||
 
 | 
			
		||||
@@ -40,7 +40,7 @@ namespace Grid {
 | 
			
		||||
    ////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
  template<class vobj> inline RealD norm2(const Lattice<vobj> &arg){
 | 
			
		||||
    ComplexD nrm = innerProduct(arg,arg);
 | 
			
		||||
    return real(nrm); 
 | 
			
		||||
    return std::real(nrm); 
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    template<class vobj>
 | 
			
		||||
 
 | 
			
		||||
@@ -495,5 +495,6 @@ namespace QCD {
 | 
			
		||||
#include <qcd/hmc/integrators/Integrator_algorithm.h>
 | 
			
		||||
#include <qcd/hmc/HMC.h>
 | 
			
		||||
 | 
			
		||||
#include <qcd/smearing/Smearing.h>
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -35,6 +35,7 @@ template<class GaugeField>
 | 
			
		||||
class Action { 
 | 
			
		||||
 | 
			
		||||
 public:
 | 
			
		||||
  bool is_smeared = false;
 | 
			
		||||
  // Boundary conditions? // Heatbath?
 | 
			
		||||
  virtual void  refresh(const GaugeField &U, GridParallelRNG& pRNG) = 0;// refresh pseudofermions
 | 
			
		||||
  virtual RealD S    (const GaugeField &U)                        = 0;  // evaluate the action
 | 
			
		||||
 
 | 
			
		||||
@@ -75,7 +75,7 @@ namespace Grid {
 | 
			
		||||
    //
 | 
			
		||||
    //
 | 
			
		||||
    // template<class Impl>
 | 
			
		||||
    // class MyOp : pubic<Impl> { 
 | 
			
		||||
    // class MyOp : public<Impl> { 
 | 
			
		||||
    // public:
 | 
			
		||||
    //
 | 
			
		||||
    //    INHERIT_ALL_IMPL_TYPES(Impl);
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,8 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
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
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution
 | 
			
		||||
directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
#ifndef GRID_QCD_GAUGE_IMPL_H
 | 
			
		||||
@@ -32,7 +33,6 @@ namespace Grid {
 | 
			
		||||
 | 
			
		||||
namespace QCD {
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Implementation dependent gauge types
 | 
			
		||||
////////////////////////////////////////////////////////////////////////
 | 
			
		||||
@@ -46,110 +46,120 @@ template<class Gimpl> class WilsonLoops;
 | 
			
		||||
  typedef typename GImpl::SiteGaugeField SiteGaugeField;                       \
 | 
			
		||||
  typedef typename GImpl::SiteGaugeLink SiteGaugeLink;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
    template<class S,int Nrepresentation=Nc>
 | 
			
		||||
    class GaugeImplTypes { 
 | 
			
		||||
template <class S, int Nrepresentation = Nc> class GaugeImplTypes {
 | 
			
		||||
public:
 | 
			
		||||
    
 | 
			
		||||
  typedef S Simd;
 | 
			
		||||
 | 
			
		||||
      template<typename vtype> using iImplGaugeLink          = iScalar<iScalar<iMatrix<vtype, Nrepresentation> > >;
 | 
			
		||||
      template<typename vtype> using iImplGaugeField         = iVector<iScalar<iMatrix<vtype, Nrepresentation> >, Nd  >;
 | 
			
		||||
  template <typename vtype>
 | 
			
		||||
  using iImplGaugeLink = iScalar<iScalar<iMatrix<vtype, Nrepresentation>>>;
 | 
			
		||||
  template <typename vtype>
 | 
			
		||||
  using iImplGaugeField = iVector<iScalar<iMatrix<vtype, Nrepresentation>>, Nd>;
 | 
			
		||||
 | 
			
		||||
  typedef iImplGaugeLink<Simd> SiteGaugeLink;
 | 
			
		||||
  typedef iImplGaugeField<Simd> SiteGaugeField;
 | 
			
		||||
 | 
			
		||||
      typedef Lattice<SiteGaugeLink>                GaugeLinkField; // bit ugly naming; polarised gauge field, lorentz... all ugly
 | 
			
		||||
  typedef Lattice<SiteGaugeLink> GaugeLinkField; // bit ugly naming; polarised
 | 
			
		||||
                                                 // gauge field, lorentz... all
 | 
			
		||||
                                                 // ugly
 | 
			
		||||
  typedef Lattice<SiteGaugeField> GaugeField;
 | 
			
		||||
 | 
			
		||||
  // Move this elsewhere?
 | 
			
		||||
  static inline void AddGaugeLink(GaugeField &U, GaugeLinkField &W,
 | 
			
		||||
                                  int mu) { // U[mu] += W
 | 
			
		||||
    PARALLEL_FOR_LOOP
 | 
			
		||||
    for (auto ss = 0; ss < U._grid->oSites(); ss++) {
 | 
			
		||||
      U._odata[ss]._internal[mu] =
 | 
			
		||||
          U._odata[ss]._internal[mu] + W._odata[ss]._internal;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Composition with smeared link, bc's etc.. probably need multiple inheritance
 | 
			
		||||
// Variable precision "S" and variable Nc
 | 
			
		||||
    template<class GimplTypes>
 | 
			
		||||
    class PeriodicGaugeImpl : public GimplTypes  { 
 | 
			
		||||
template <class GimplTypes> class PeriodicGaugeImpl : public GimplTypes {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
  INHERIT_GIMPL_TYPES(GimplTypes);
 | 
			
		||||
 | 
			
		||||
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    // Support needed for the assembly of loops including all boundary condition effects such as conjugate bcs
 | 
			
		||||
  // Support needed for the assembly of loops including all boundary condition
 | 
			
		||||
  // effects such as conjugate bcs
 | 
			
		||||
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
      template<class covariant>  static inline
 | 
			
		||||
      Lattice<covariant> CovShiftForward (const GaugeLinkField &Link, int mu, const Lattice<covariant> &field) {
 | 
			
		||||
  template <class covariant>
 | 
			
		||||
  static inline Lattice<covariant>
 | 
			
		||||
  CovShiftForward(const GaugeLinkField &Link, int mu,
 | 
			
		||||
                  const Lattice<covariant> &field) {
 | 
			
		||||
    return PeriodicBC::CovShiftForward(Link, mu, field);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
      template<class covariant> static inline
 | 
			
		||||
      Lattice<covariant> CovShiftBackward(const GaugeLinkField &Link, int mu,const Lattice<covariant> &field) {
 | 
			
		||||
  template <class covariant>
 | 
			
		||||
  static inline Lattice<covariant>
 | 
			
		||||
  CovShiftBackward(const GaugeLinkField &Link, int mu,
 | 
			
		||||
                   const Lattice<covariant> &field) {
 | 
			
		||||
    return PeriodicBC::CovShiftBackward(Link, mu, field);
 | 
			
		||||
  }
 | 
			
		||||
      static inline
 | 
			
		||||
      GaugeLinkField CovShiftIdentityBackward(const GaugeLinkField &Link, int mu) {
 | 
			
		||||
  static inline GaugeLinkField
 | 
			
		||||
  CovShiftIdentityBackward(const GaugeLinkField &Link, int mu) {
 | 
			
		||||
    return Cshift(adj(Link), mu, -1);
 | 
			
		||||
  }
 | 
			
		||||
      static inline
 | 
			
		||||
      GaugeLinkField CovShiftIdentityForward(const GaugeLinkField &Link, int mu) {
 | 
			
		||||
  static inline GaugeLinkField
 | 
			
		||||
  CovShiftIdentityForward(const GaugeLinkField &Link, int mu) {
 | 
			
		||||
    return Link;
 | 
			
		||||
  }
 | 
			
		||||
      static inline
 | 
			
		||||
      GaugeLinkField ShiftStaple(const GaugeLinkField &Link, int mu) {
 | 
			
		||||
  static inline GaugeLinkField ShiftStaple(const GaugeLinkField &Link, int mu) {
 | 
			
		||||
    return Cshift(Link, mu, 1);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
      static inline bool isPeriodicGaugeField(void) {
 | 
			
		||||
	return true;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
  static inline bool isPeriodicGaugeField(void) { return true; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
// Composition with smeared link, bc's etc.. probably need multiple inheritance
 | 
			
		||||
// Variable precision "S" and variable Nc
 | 
			
		||||
    template<class GimplTypes>
 | 
			
		||||
    class ConjugateGaugeImpl : public GimplTypes { 
 | 
			
		||||
template <class GimplTypes> class ConjugateGaugeImpl : public GimplTypes {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
  INHERIT_GIMPL_TYPES(GimplTypes);
 | 
			
		||||
 | 
			
		||||
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    // Support needed for the assembly of loops including all boundary condition effects such as Gparity.
 | 
			
		||||
  // Support needed for the assembly of loops including all boundary condition
 | 
			
		||||
  // effects such as Gparity.
 | 
			
		||||
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    template<class covariant>  static
 | 
			
		||||
    Lattice<covariant> CovShiftForward (const GaugeLinkField &Link, int mu, const Lattice<covariant> &field) {
 | 
			
		||||
  template <class covariant>
 | 
			
		||||
  static Lattice<covariant> CovShiftForward(const GaugeLinkField &Link, int mu,
 | 
			
		||||
                                            const Lattice<covariant> &field) {
 | 
			
		||||
    return ConjugateBC::CovShiftForward(Link, mu, field);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    template<class covariant> static
 | 
			
		||||
    Lattice<covariant> CovShiftBackward(const GaugeLinkField &Link, int mu,const Lattice<covariant> &field) {
 | 
			
		||||
  template <class covariant>
 | 
			
		||||
  static Lattice<covariant> CovShiftBackward(const GaugeLinkField &Link, int mu,
 | 
			
		||||
                                             const Lattice<covariant> &field) {
 | 
			
		||||
    return ConjugateBC::CovShiftBackward(Link, mu, field);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    static inline
 | 
			
		||||
    GaugeLinkField CovShiftIdentityBackward(const GaugeLinkField &Link, int mu) {
 | 
			
		||||
  static inline GaugeLinkField
 | 
			
		||||
  CovShiftIdentityBackward(const GaugeLinkField &Link, int mu) {
 | 
			
		||||
    GridBase *grid = Link._grid;
 | 
			
		||||
    int Lmu = grid->GlobalDimensions()[mu] - 1;
 | 
			
		||||
 | 
			
		||||
      Lattice<iScalar<vInteger> > coor(grid);    LatticeCoordinate(coor,mu);
 | 
			
		||||
    Lattice<iScalar<vInteger>> coor(grid);
 | 
			
		||||
    LatticeCoordinate(coor, mu);
 | 
			
		||||
 | 
			
		||||
    GaugeLinkField tmp(grid);
 | 
			
		||||
    tmp = adj(Link);
 | 
			
		||||
    tmp = where(coor == Lmu, conjugate(tmp), tmp);
 | 
			
		||||
    return Cshift(tmp, mu, -1); // moves towards positive mu
 | 
			
		||||
  }
 | 
			
		||||
    static inline
 | 
			
		||||
    GaugeLinkField CovShiftIdentityForward(const GaugeLinkField &Link, int mu) {
 | 
			
		||||
  static inline GaugeLinkField
 | 
			
		||||
  CovShiftIdentityForward(const GaugeLinkField &Link, int mu) {
 | 
			
		||||
    return Link;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    static inline
 | 
			
		||||
    GaugeLinkField ShiftStaple(const GaugeLinkField &Link, int mu) {
 | 
			
		||||
  static inline GaugeLinkField ShiftStaple(const GaugeLinkField &Link, int mu) {
 | 
			
		||||
    GridBase *grid = Link._grid;
 | 
			
		||||
    int Lmu = grid->GlobalDimensions()[mu] - 1;
 | 
			
		||||
 | 
			
		||||
      Lattice<iScalar<vInteger> > coor(grid);    LatticeCoordinate(coor,mu);
 | 
			
		||||
    Lattice<iScalar<vInteger>> coor(grid);
 | 
			
		||||
    LatticeCoordinate(coor, mu);
 | 
			
		||||
 | 
			
		||||
    GaugeLinkField tmp(grid);
 | 
			
		||||
    tmp = Cshift(Link, mu, 1);
 | 
			
		||||
@@ -157,10 +167,7 @@ template<class Gimpl> class WilsonLoops;
 | 
			
		||||
    return tmp;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    static inline bool isPeriodicGaugeField(void) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
  static inline bool isPeriodicGaugeField(void) { return false; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef GaugeImplTypes<vComplex, Nc> GimplTypesR;
 | 
			
		||||
@@ -171,10 +178,10 @@ template<class Gimpl> class WilsonLoops;
 | 
			
		||||
typedef PeriodicGaugeImpl<GimplTypesF> PeriodicGimplF; // Float
 | 
			
		||||
typedef PeriodicGaugeImpl<GimplTypesD> PeriodicGimplD; // Double
 | 
			
		||||
 | 
			
		||||
    typedef ConjugateGaugeImpl<GimplTypesR> ConjugateGimplR; // Real.. whichever prec
 | 
			
		||||
typedef ConjugateGaugeImpl<GimplTypesR>
 | 
			
		||||
    ConjugateGimplR; // Real.. whichever prec
 | 
			
		||||
typedef ConjugateGaugeImpl<GimplTypesF> ConjugateGimplF; // Float
 | 
			
		||||
typedef ConjugateGaugeImpl<GimplTypesD> ConjugateGimplD; // Double
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,8 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
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
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution
 | 
			
		||||
directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
#ifndef QCD_PSEUDOFERMION_ONE_FLAVOUR_EVEN_ODD_RATIONAL_H
 | 
			
		||||
@@ -42,7 +43,8 @@ namespace Grid{
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
template <class Impl>
 | 
			
		||||
    class OneFlavourEvenOddRationalPseudoFermionAction : public Action<typename Impl::GaugeField> {
 | 
			
		||||
class OneFlavourEvenOddRationalPseudoFermionAction
 | 
			
		||||
    : public Action<typename Impl::GaugeField> {
 | 
			
		||||
 public:
 | 
			
		||||
  INHERIT_IMPL_TYPES(Impl);
 | 
			
		||||
 | 
			
		||||
@@ -55,41 +57,40 @@ namespace Grid{
 | 
			
		||||
  MultiShiftFunction PowerNegQuarter;
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
     
 | 
			
		||||
  FermionOperator<Impl> &FermOp;  // the basic operator
 | 
			
		||||
 | 
			
		||||
      // NOT using "Nroots"; IroIro is -- perhaps later, but this wasn't good for us historically
 | 
			
		||||
  // NOT using "Nroots"; IroIro is -- perhaps later, but this wasn't good for us
 | 
			
		||||
  // historically
 | 
			
		||||
  // and hasenbusch works better
 | 
			
		||||
 | 
			
		||||
  FermionField PhiEven;  // the pseudo fermion field for this trajectory
 | 
			
		||||
  FermionField PhiOdd;   // the pseudo fermion field for this trajectory
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 public:
 | 
			
		||||
 | 
			
		||||
  OneFlavourEvenOddRationalPseudoFermionAction(FermionOperator<Impl> &Op,
 | 
			
		||||
						   Params & p ) : FermOp(Op), 
 | 
			
		||||
                                               Params &p)
 | 
			
		||||
      : FermOp(Op),
 | 
			
		||||
        PhiEven(Op.FermionRedBlackGrid()),
 | 
			
		||||
        PhiOdd(Op.FermionRedBlackGrid()),
 | 
			
		||||
	param(p) 
 | 
			
		||||
      {
 | 
			
		||||
        param(p) {
 | 
			
		||||
    AlgRemez remez(param.lo, param.hi, param.precision);
 | 
			
		||||
 | 
			
		||||
    // MdagM^(+- 1/2)
 | 
			
		||||
	std::cout<<GridLogMessage << "Generating degree "<<param.degree<<" for x^(1/2)"<<std::endl;
 | 
			
		||||
    std::cout << GridLogMessage << "Generating degree " << param.degree
 | 
			
		||||
              << " for x^(1/2)" << std::endl;
 | 
			
		||||
    remez.generateApprox(param.degree, 1, 2);
 | 
			
		||||
    PowerHalf.Init(remez, param.tolerance, false);
 | 
			
		||||
    PowerNegHalf.Init(remez, param.tolerance, true);
 | 
			
		||||
 | 
			
		||||
    // MdagM^(+- 1/4)
 | 
			
		||||
	std::cout<<GridLogMessage << "Generating degree "<<param.degree<<" for x^(1/4)"<<std::endl;
 | 
			
		||||
    std::cout << GridLogMessage << "Generating degree " << param.degree
 | 
			
		||||
              << " for x^(1/4)" << std::endl;
 | 
			
		||||
    remez.generateApprox(param.degree, 1, 4);
 | 
			
		||||
    PowerQuarter.Init(remez, param.tolerance, false);
 | 
			
		||||
    PowerNegQuarter.Init(remez, param.tolerance, true);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  virtual void refresh(const GaugeField &U, GridParallelRNG &pRNG) {
 | 
			
		||||
 | 
			
		||||
    // P(phi) = e^{- phi^dag (MpcdagMpc)^-1/2 phi}
 | 
			
		||||
    //        = e^{- phi^dag (MpcdagMpc)^-1/4 (MpcdagMpc)^-1/4 phi}
 | 
			
		||||
    // Phi = MpcdagMpc^{1/4} eta
 | 
			
		||||
@@ -106,7 +107,8 @@ namespace Grid{
 | 
			
		||||
    FermionField etaOdd(FermOp.FermionRedBlackGrid());
 | 
			
		||||
    FermionField etaEven(FermOp.FermionRedBlackGrid());
 | 
			
		||||
 | 
			
		||||
	gaussian(pRNG,eta);	eta=eta*scale;
 | 
			
		||||
    gaussian(pRNG, eta);
 | 
			
		||||
    eta = eta * scale;
 | 
			
		||||
 | 
			
		||||
    pickCheckerboard(Even, etaEven, eta);
 | 
			
		||||
    pickCheckerboard(Odd, etaOdd, eta);
 | 
			
		||||
@@ -124,26 +126,27 @@ namespace Grid{
 | 
			
		||||
 | 
			
		||||
    assert(FermOp.ConstEE() == 1);
 | 
			
		||||
    PhiEven = zero;
 | 
			
		||||
	
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  //////////////////////////////////////////////////////
 | 
			
		||||
  // S = phi^dag (Mdag M)^-1/2 phi
 | 
			
		||||
  //////////////////////////////////////////////////////
 | 
			
		||||
  virtual RealD S(const GaugeField &U) {
 | 
			
		||||
 | 
			
		||||
    FermOp.ImportGauge(U);
 | 
			
		||||
 | 
			
		||||
    FermionField Y(FermOp.FermionRedBlackGrid());
 | 
			
		||||
 | 
			
		||||
    SchurDifferentiableOperator<Impl> Mpc(FermOp);
 | 
			
		||||
 | 
			
		||||
	ConjugateGradientMultiShift<FermionField> msCG(param.MaxIter,PowerNegQuarter);
 | 
			
		||||
    ConjugateGradientMultiShift<FermionField> msCG(param.MaxIter,
 | 
			
		||||
                                                   PowerNegQuarter);
 | 
			
		||||
 | 
			
		||||
    msCG(Mpc, PhiOdd, Y);
 | 
			
		||||
 | 
			
		||||
    RealD action = norm2(Y);
 | 
			
		||||
	std::cout << GridLogMessage << "Pseudofermion action FIXME -- is -1/4 solve or -1/2 solve faster??? "<<action<<std::endl;
 | 
			
		||||
    std::cout << GridLogMessage << "Pseudofermion action FIXME -- is -1/4 "
 | 
			
		||||
                                   "solve or -1/2 solve faster??? "
 | 
			
		||||
              << action << std::endl;
 | 
			
		||||
 | 
			
		||||
    return action;
 | 
			
		||||
  };
 | 
			
		||||
@@ -158,7 +161,8 @@ namespace Grid{
 | 
			
		||||
  //
 | 
			
		||||
  // d[N/D] is then
 | 
			
		||||
  //
 | 
			
		||||
      //          \sum_k -ak [M^dagM+bk]^{-1}  [ dM^dag M + M^dag dM ] [M^dag M + bk]^{-1}
 | 
			
		||||
  //          \sum_k -ak [M^dagM+bk]^{-1}  [ dM^dag M + M^dag dM ] [M^dag M +
 | 
			
		||||
  //          bk]^{-1}
 | 
			
		||||
  //
 | 
			
		||||
  // Need
 | 
			
		||||
  //       Mf Phi_k = [MdagM+bk]^{-1} Phi
 | 
			
		||||
@@ -166,11 +170,11 @@ namespace Grid{
 | 
			
		||||
  //
 | 
			
		||||
  // With these building blocks
 | 
			
		||||
  //
 | 
			
		||||
      //       dS/dU =  \sum_k -ak Mf Phi_k^dag      [ dM^dag M + M^dag dM ] Mf Phi_k
 | 
			
		||||
  //       dS/dU =  \sum_k -ak Mf Phi_k^dag      [ dM^dag M + M^dag dM ] Mf
 | 
			
		||||
  //       Phi_k
 | 
			
		||||
  //        S    = innerprodReal(Phi,Mf Phi);
 | 
			
		||||
  //////////////////////////////////////////////////////
 | 
			
		||||
  virtual void deriv(const GaugeField &U, GaugeField &dSdU) {
 | 
			
		||||
 | 
			
		||||
    const int Npole = PowerNegHalf.poles.size();
 | 
			
		||||
 | 
			
		||||
    std::vector<FermionField> MPhi_k(Npole, FermOp.FermionRedBlackGrid());
 | 
			
		||||
@@ -190,23 +194,21 @@ namespace Grid{
 | 
			
		||||
 | 
			
		||||
    dSdU = zero;
 | 
			
		||||
    for (int k = 0; k < Npole; k++) {
 | 
			
		||||
 | 
			
		||||
      RealD ak = PowerNegHalf.residues[k];
 | 
			
		||||
 | 
			
		||||
      X = MPhi_k[k];
 | 
			
		||||
 | 
			
		||||
      Mpc.Mpc(X, Y);
 | 
			
		||||
	  Mpc.MpcDeriv   (tmp , Y, X );  dSdU=dSdU+ak*tmp;
 | 
			
		||||
	  Mpc.MpcDagDeriv(tmp , X, Y );  dSdU=dSdU+ak*tmp;
 | 
			
		||||
 | 
			
		||||
      Mpc.MpcDeriv(tmp, Y, X);
 | 
			
		||||
      dSdU = dSdU + ak * tmp;
 | 
			
		||||
      Mpc.MpcDagDeriv(tmp, X, Y);
 | 
			
		||||
      dSdU = dSdU + ak * tmp;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	dSdU = Ta(dSdU);
 | 
			
		||||
 | 
			
		||||
    // dSdU = Ta(dSdU);
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -256,7 +256,7 @@ namespace Grid{
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dSdU = Ta(dSdU);
 | 
			
		||||
	//dSdU = Ta(dSdU);
 | 
			
		||||
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
 
 | 
			
		||||
@@ -186,7 +186,7 @@ namespace Grid{
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dSdU = Ta(dSdU);
 | 
			
		||||
	//dSdU = Ta(dSdU);
 | 
			
		||||
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
 
 | 
			
		||||
@@ -242,7 +242,7 @@ namespace Grid{
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dSdU = Ta(dSdU);
 | 
			
		||||
	//dSdU = Ta(dSdU);
 | 
			
		||||
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
 
 | 
			
		||||
@@ -137,7 +137,7 @@ namespace Grid{
 | 
			
		||||
	FermOp.MDeriv(tmp , Y, X,DaggerNo );  dSdU=tmp;
 | 
			
		||||
	FermOp.MDeriv(tmp , X, Y,DaggerYes);  dSdU=dSdU+tmp;
 | 
			
		||||
	
 | 
			
		||||
	dSdU = Ta(dSdU);
 | 
			
		||||
	//dSdU = Ta(dSdU);
 | 
			
		||||
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -173,7 +173,7 @@ namespace Grid{
 | 
			
		||||
	FermOp.MeeDeriv(tmp , X, Y,DaggerYes);  dSdU=dSdU+tmp;
 | 
			
		||||
	*/
 | 
			
		||||
	
 | 
			
		||||
	dSdU = Ta(dSdU);
 | 
			
		||||
	//dSdU = Ta(dSdU);
 | 
			
		||||
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -188,7 +188,8 @@ namespace Grid{
 | 
			
		||||
	assert(NumOp.ConstEE() == 1);
 | 
			
		||||
	assert(DenOp.ConstEE() == 1);
 | 
			
		||||
 | 
			
		||||
	dSdU = -Ta(dSdU);
 | 
			
		||||
	//dSdU = -Ta(dSdU);
 | 
			
		||||
	dSdU = -dSdU;
 | 
			
		||||
	
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
 
 | 
			
		||||
@@ -155,7 +155,8 @@ namespace Grid{
 | 
			
		||||
	DenOp.MDeriv(force,Y,X,DaggerNo);   dSdU=dSdU-force;
 | 
			
		||||
	DenOp.MDeriv(force,X,Y,DaggerYes);  dSdU=dSdU-force;
 | 
			
		||||
 | 
			
		||||
	dSdU = - Ta(dSdU);
 | 
			
		||||
	dSdU *= -1.0;
 | 
			
		||||
	//dSdU = - Ta(dSdU);
 | 
			
		||||
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,8 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
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
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution
 | 
			
		||||
directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
//--------------------------------------------------------------------
 | 
			
		||||
@@ -41,13 +42,10 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
namespace QCD {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct HMCparameters {
 | 
			
		||||
 | 
			
		||||
  Integer StartTrajectory;
 | 
			
		||||
  Integer Trajectories; /* @brief Number of sweeps in this run */
 | 
			
		||||
  bool MetropolisTest;
 | 
			
		||||
@@ -61,27 +59,40 @@ namespace Grid{
 | 
			
		||||
    Trajectories = 200;
 | 
			
		||||
    /////////////////////////////////
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void print() const {
 | 
			
		||||
    std::cout << GridLogMessage << "[HMC parameter] Trajectories            : " << Trajectories << "\n";
 | 
			
		||||
    std::cout << GridLogMessage << "[HMC parameter] Start trajectory        : " << StartTrajectory << "\n";
 | 
			
		||||
    std::cout << GridLogMessage << "[HMC parameter] Metropolis test (on/off): " << MetropolisTest << "\n";
 | 
			
		||||
    std::cout << GridLogMessage << "[HMC parameter] Thermalization trajs    : " << NoMetropolisUntil << "\n";
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class GaugeField>
 | 
			
		||||
class HmcObservable {
 | 
			
		||||
 public:
 | 
			
		||||
      virtual void TrajectoryComplete (int traj, GaugeField &U, GridSerialRNG &sRNG, GridParallelRNG & pRNG )=0;
 | 
			
		||||
  virtual void TrajectoryComplete(int traj, GaugeField &U, GridSerialRNG &sRNG,
 | 
			
		||||
                                  GridParallelRNG &pRNG) = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class Gimpl>
 | 
			
		||||
class PlaquetteLogger : public HmcObservable<typename Gimpl::GaugeField> {
 | 
			
		||||
 private:
 | 
			
		||||
  std::string Stem;
 | 
			
		||||
 | 
			
		||||
 public:
 | 
			
		||||
  INHERIT_GIMPL_TYPES(Gimpl);
 | 
			
		||||
      PlaquetteLogger(std::string cf) {
 | 
			
		||||
        Stem  = cf;
 | 
			
		||||
      };
 | 
			
		||||
  PlaquetteLogger(std::string cf) { Stem = cf; };
 | 
			
		||||
 | 
			
		||||
      void TrajectoryComplete(int traj, GaugeField &U, GridSerialRNG &sRNG, GridParallelRNG & pRNG )
 | 
			
		||||
  void TrajectoryComplete(int traj, GaugeField &U, GridSerialRNG &sRNG,
 | 
			
		||||
                          GridParallelRNG &pRNG) {
 | 
			
		||||
    std::string file;
 | 
			
		||||
    {
 | 
			
		||||
	  std::string file;   { std::ostringstream os; os << Stem     <<"."<< traj; file = os.str(); }
 | 
			
		||||
      std::ostringstream os;
 | 
			
		||||
      os << Stem << "." << traj;
 | 
			
		||||
      file = os.str();
 | 
			
		||||
    }
 | 
			
		||||
    std::ofstream of(file);
 | 
			
		||||
 | 
			
		||||
    RealD peri_plaq = WilsonLoops<PeriodicGimplR>::avgPlaquette(U);
 | 
			
		||||
@@ -90,17 +101,27 @@ namespace Grid{
 | 
			
		||||
    RealD impl_plaq = WilsonLoops<Gimpl>::avgPlaquette(U);
 | 
			
		||||
    RealD impl_rect = WilsonLoops<Gimpl>::avgRectangle(U);
 | 
			
		||||
 | 
			
		||||
	  of << traj<<" "<< impl_plaq << " " << impl_rect << "  "<< peri_plaq<<" "<<peri_rect<<std::endl;
 | 
			
		||||
	  std::cout<< GridLogMessage<< "traj"<<" "<< "plaq " << " " << " rect  " << "  "<< "peri_plaq" <<" "<<"peri_rect"<<std::endl;
 | 
			
		||||
	  std::cout<< GridLogMessage<< traj<<" "<< impl_plaq << " " << impl_rect << "  "<< peri_plaq<<" "<<peri_rect<<std::endl;
 | 
			
		||||
    of << traj << " " << impl_plaq << " " << impl_rect << "  " << peri_plaq
 | 
			
		||||
       << " " << peri_rect << std::endl;
 | 
			
		||||
    std::cout << GridLogMessage << "traj"
 | 
			
		||||
              << " "
 | 
			
		||||
              << "plaq "
 | 
			
		||||
              << " "
 | 
			
		||||
              << " rect  "
 | 
			
		||||
              << "  "
 | 
			
		||||
              << "peri_plaq"
 | 
			
		||||
              << " "
 | 
			
		||||
              << "peri_rect" << std::endl;
 | 
			
		||||
    std::cout << GridLogMessage << traj << " " << impl_plaq << " " << impl_rect
 | 
			
		||||
              << "  " << peri_plaq << " " << peri_rect << std::endl;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
    //    template <class GaugeField, class Integrator, class Smearer, class Boundary> 
 | 
			
		||||
//    template <class GaugeField, class Integrator, class Smearer, class
 | 
			
		||||
//    Boundary>
 | 
			
		||||
template <class GaugeField, class IntegratorType>
 | 
			
		||||
class HybridMonteCarlo {
 | 
			
		||||
 private:
 | 
			
		||||
 | 
			
		||||
  const HMCparameters Params;
 | 
			
		||||
 | 
			
		||||
  GridSerialRNG &sRNG;    // Fixme: need a RNG management strategy.
 | 
			
		||||
@@ -114,60 +135,64 @@ namespace Grid{
 | 
			
		||||
  // Metropolis step
 | 
			
		||||
  /////////////////////////////////////////////////////////
 | 
			
		||||
  bool metropolis_test(const RealD DeltaH) {
 | 
			
		||||
 | 
			
		||||
    RealD rn_test;
 | 
			
		||||
 | 
			
		||||
    RealD prob = std::exp(-DeltaH);
 | 
			
		||||
 | 
			
		||||
    random(sRNG, rn_test);
 | 
			
		||||
 | 
			
		||||
	std::cout<<GridLogMessage<< "--------------------------------------------\n";
 | 
			
		||||
	std::cout<<GridLogMessage<< "dH = "<<DeltaH << "  Random = "<< rn_test <<"\n";
 | 
			
		||||
	std::cout<<GridLogMessage<< "Acc. Probability = " << ((prob<1.0)? prob: 1.0)<< "   ";
 | 
			
		||||
    std::cout << GridLogMessage
 | 
			
		||||
              << "--------------------------------------------------\n";
 | 
			
		||||
    std::cout << GridLogMessage << "exp(-dH) = " << prob
 | 
			
		||||
              << "  Random = " << rn_test << "\n";
 | 
			
		||||
    std::cout << GridLogMessage
 | 
			
		||||
              << "Acc. Probability = " << ((prob < 1.0) ? prob : 1.0) << "\n";
 | 
			
		||||
 | 
			
		||||
    if ((prob > 1.0) || (rn_test <= prob)) {  // accepted
 | 
			
		||||
	  std::cout<<GridLogMessage <<"-- ACCEPTED\n";
 | 
			
		||||
      std::cout << GridLogMessage << "Metropolis_test -- ACCEPTED\n";
 | 
			
		||||
      std::cout << GridLogMessage
 | 
			
		||||
                << "--------------------------------------------------\n";
 | 
			
		||||
      return true;
 | 
			
		||||
    } else {  // rejected
 | 
			
		||||
	  std::cout<<GridLogMessage <<"-- REJECTED\n";
 | 
			
		||||
      std::cout << GridLogMessage << "Metropolis_test -- REJECTED\n";
 | 
			
		||||
      std::cout << GridLogMessage
 | 
			
		||||
                << "--------------------------------------------------\n";
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /////////////////////////////////////////////////////////
 | 
			
		||||
  // Evolution
 | 
			
		||||
  /////////////////////////////////////////////////////////
 | 
			
		||||
  RealD evolve_step(GaugeField &U) {
 | 
			
		||||
 | 
			
		||||
    TheIntegrator.refresh(U, pRNG);  // set U and initialize P and phi's
 | 
			
		||||
 | 
			
		||||
    RealD H0 = TheIntegrator.S(U);  // initial state action
 | 
			
		||||
 | 
			
		||||
	std::cout<<GridLogMessage<<"Total H before = "<< H0 << "\n";
 | 
			
		||||
    std::streamsize current_precision = std::cout.precision();
 | 
			
		||||
    std::cout.precision(17);
 | 
			
		||||
    std::cout << GridLogMessage << "Total H before trajectory = " << H0 << "\n";
 | 
			
		||||
    std::cout.precision(current_precision);
 | 
			
		||||
 | 
			
		||||
    TheIntegrator.integrate(U);
 | 
			
		||||
 | 
			
		||||
    RealD H1 = TheIntegrator.S(U);  // updated state action
 | 
			
		||||
 | 
			
		||||
	std::cout<<GridLogMessage<<"Total H after = "<< H1 << "\n";
 | 
			
		||||
    std::cout.precision(17);
 | 
			
		||||
    std::cout << GridLogMessage << "Total H after trajectory  = " << H1
 | 
			
		||||
              << "  dH = " << H1 - H0 << "\n";
 | 
			
		||||
    std::cout.precision(current_precision);
 | 
			
		||||
 | 
			
		||||
    return (H1 - H0);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 public:
 | 
			
		||||
 | 
			
		||||
  /////////////////////////////////////////
 | 
			
		||||
  // Constructor
 | 
			
		||||
  /////////////////////////////////////////
 | 
			
		||||
      HybridMonteCarlo(HMCparameters Pms,  IntegratorType &_Int, GridSerialRNG &_sRNG, GridParallelRNG &_pRNG, GaugeField &_U ) :
 | 
			
		||||
        Params(Pms), 
 | 
			
		||||
	TheIntegrator(_Int), 
 | 
			
		||||
	sRNG(_sRNG),
 | 
			
		||||
	pRNG(_pRNG),
 | 
			
		||||
	Ucur(_U)
 | 
			
		||||
      {
 | 
			
		||||
      }
 | 
			
		||||
  HybridMonteCarlo(HMCparameters Pams, IntegratorType &_Int,
 | 
			
		||||
                   GridSerialRNG &_sRNG, GridParallelRNG &_pRNG, GaugeField &_U)
 | 
			
		||||
      : Params(Pams), TheIntegrator(_Int), sRNG(_sRNG), pRNG(_pRNG), Ucur(_U) {}
 | 
			
		||||
  ~HybridMonteCarlo(){};
 | 
			
		||||
 | 
			
		||||
  void AddObservable(HmcObservable<GaugeField> *obs) {
 | 
			
		||||
@@ -175,21 +200,22 @@ namespace Grid{
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void evolve(void) {
 | 
			
		||||
 | 
			
		||||
    Real DeltaH;
 | 
			
		||||
 | 
			
		||||
    GaugeField Ucopy(Ucur._grid);
 | 
			
		||||
 | 
			
		||||
	// Actual updates (evolve a copy Ucopy then copy back eventually)
 | 
			
		||||
	for(int traj=Params.StartTrajectory; traj < Params.Trajectories+Params.StartTrajectory; ++traj){
 | 
			
		||||
    Params.print();
 | 
			
		||||
 | 
			
		||||
    // Actual updates (evolve a copy Ucopy then copy back eventually)
 | 
			
		||||
    for (int traj = Params.StartTrajectory;
 | 
			
		||||
         traj < Params.Trajectories + Params.StartTrajectory; ++traj) {
 | 
			
		||||
      std::cout << GridLogMessage << "-- # Trajectory = " << traj << "\n";
 | 
			
		||||
      Ucopy = Ucur;
 | 
			
		||||
 | 
			
		||||
      DeltaH = evolve_step(Ucopy);
 | 
			
		||||
 | 
			
		||||
      bool accept = true;
 | 
			
		||||
	  if ( traj > Params.NoMetropolisUntil) { 
 | 
			
		||||
      if (traj >= Params.NoMetropolisUntil) {
 | 
			
		||||
        accept = metropolis_test(DeltaH);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@@ -200,7 +226,6 @@ namespace Grid{
 | 
			
		||||
      for (int obs = 0; obs < Observables.size(); obs++) {
 | 
			
		||||
        Observables[obs]->TrajectoryComplete(traj + 1, Ucur, sRNG, pRNG);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
@@ -208,5 +233,4 @@ namespace Grid{
 | 
			
		||||
}  // QCD
 | 
			
		||||
}  // Grid
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -47,7 +47,7 @@ public:
 | 
			
		||||
  GridRedBlackCartesian * UrbGrid ;
 | 
			
		||||
  GridRedBlackCartesian * FrbGrid ;
 | 
			
		||||
 | 
			
		||||
  virtual void BuildTheAction (int argc, char **argv) = 0;
 | 
			
		||||
  virtual void BuildTheAction (int argc, char **argv) = 0; // necessary?
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  void Run (int argc, char  **argv){
 | 
			
		||||
@@ -81,10 +81,37 @@ public:
 | 
			
		||||
      NumTraj = ivec[0];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Create integrator
 | 
			
		||||
    typedef MinimumNorm2<GaugeField>  IntegratorType;// change here to change the algorithm
 | 
			
		||||
    int NumThermalizations = 10;
 | 
			
		||||
    if( GridCmdOptionExists(argv,argv+argc,"--Thermalizations") ){
 | 
			
		||||
      arg= GridCmdOptionPayload(argv,argv+argc,"--Thermalizations");
 | 
			
		||||
      std::vector<int> ivec(0);
 | 
			
		||||
      GridCmdOptionIntVector(arg,ivec);
 | 
			
		||||
      NumThermalizations = ivec[0];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    GridSerialRNG    sRNG;
 | 
			
		||||
    GridParallelRNG  pRNG(UGrid);
 | 
			
		||||
    LatticeGaugeField  U(UGrid); // change this to an extended field (smearing class)
 | 
			
		||||
 | 
			
		||||
    std::vector<int> SerSeed({1,2,3,4,5});
 | 
			
		||||
    std::vector<int> ParSeed({6,7,8,9,10});
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    // Create integrator, including the smearing policy
 | 
			
		||||
    // Smearing policy
 | 
			
		||||
    std::cout << GridLogDebug << " Creating the Stout class\n";
 | 
			
		||||
    double rho = 0.1; // smearing parameter, now hardcoded
 | 
			
		||||
    int Nsmear = 1;   // number of smearing levels
 | 
			
		||||
    Smear_Stout<Gimpl> Stout(rho);
 | 
			
		||||
    std::cout << GridLogDebug << " Creating the SmearedConfiguration class\n";
 | 
			
		||||
    SmearedConfiguration<Gimpl> SmearingPolicy(UGrid, Nsmear, Stout);
 | 
			
		||||
    std::cout << GridLogDebug << " done\n";
 | 
			
		||||
    //////////////
 | 
			
		||||
    typedef MinimumNorm2<GaugeField, SmearedConfiguration<Gimpl> >  IntegratorType;// change here to change the algorithm
 | 
			
		||||
    IntegratorParameters MDpar(20);
 | 
			
		||||
    IntegratorType MDynamics(UGrid,MDpar, TheAction);
 | 
			
		||||
    IntegratorType MDynamics(UGrid, MDpar, TheAction, SmearingPolicy);
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    // Checkpoint strategy
 | 
			
		||||
    NerscHmcCheckpointer<Gimpl> Checkpoint(std::string("ckpoint_lat"),std::string("ckpoint_rng"),1);
 | 
			
		||||
@@ -93,42 +120,38 @@ public:
 | 
			
		||||
    HMCparameters HMCpar;
 | 
			
		||||
    HMCpar.StartTrajectory   = StartTraj;
 | 
			
		||||
    HMCpar.Trajectories      = NumTraj;
 | 
			
		||||
    HMCpar.NoMetropolisUntil = NumThermalizations;
 | 
			
		||||
    
 | 
			
		||||
    GridSerialRNG    sRNG;
 | 
			
		||||
    GridParallelRNG  pRNG(UGrid);
 | 
			
		||||
    LatticeGaugeField  U(UGrid);
 | 
			
		||||
 | 
			
		||||
    std::vector<int> SerSeed({1,2,3,4,5});
 | 
			
		||||
    std::vector<int> ParSeed({6,7,8,9,10});
 | 
			
		||||
 | 
			
		||||
    if ( StartType == HotStart ) {
 | 
			
		||||
      // Hot start
 | 
			
		||||
      HMCpar.NoMetropolisUntil =10;
 | 
			
		||||
      HMCpar.MetropolisTest = true;
 | 
			
		||||
      sRNG.SeedFixedIntegers(SerSeed);
 | 
			
		||||
      pRNG.SeedFixedIntegers(ParSeed);
 | 
			
		||||
      SU3::HotConfiguration(pRNG, U);
 | 
			
		||||
    } else if ( StartType == ColdStart ) { 
 | 
			
		||||
      // Cold start
 | 
			
		||||
      HMCpar.NoMetropolisUntil =10;
 | 
			
		||||
      HMCpar.MetropolisTest = true;
 | 
			
		||||
      sRNG.SeedFixedIntegers(SerSeed);
 | 
			
		||||
      pRNG.SeedFixedIntegers(ParSeed);
 | 
			
		||||
      SU3::ColdConfiguration(pRNG, U);
 | 
			
		||||
    } else if ( StartType == TepidStart ) {       
 | 
			
		||||
      // Tepid start
 | 
			
		||||
      HMCpar.NoMetropolisUntil =10;
 | 
			
		||||
      HMCpar.MetropolisTest = true;
 | 
			
		||||
      sRNG.SeedFixedIntegers(SerSeed);
 | 
			
		||||
      pRNG.SeedFixedIntegers(ParSeed);
 | 
			
		||||
      SU3::TepidConfiguration(pRNG, U);
 | 
			
		||||
    } else if ( StartType == CheckpointStart ) { 
 | 
			
		||||
      HMCpar.NoMetropolisUntil =10;
 | 
			
		||||
      HMCpar.MetropolisTest = true;
 | 
			
		||||
      // CheckpointRestart
 | 
			
		||||
      Checkpoint.CheckpointRestore(StartTraj, U, sRNG, pRNG);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Attach the gauge field to the smearing Policy and create the fill the smeared set
 | 
			
		||||
    // notice that the unit configuration is singular in this procedure
 | 
			
		||||
    std::cout << GridLogMessage << "Filling the smeared set\n"; 
 | 
			
		||||
    SmearingPolicy.set_GaugeField(U);
 | 
			
		||||
    
 | 
			
		||||
    HybridMonteCarlo<GaugeField,IntegratorType>  HMC(HMCpar, MDynamics,sRNG,pRNG,U); 
 | 
			
		||||
    HMC.AddObservable(&Checkpoint);
 | 
			
		||||
    HMC.AddObservable(&PlaqLog);
 | 
			
		||||
 
 | 
			
		||||
@@ -68,7 +68,7 @@ namespace Grid{
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
    /*! @brief Class for Molecular Dynamics management */   
 | 
			
		||||
    template<class GaugeField>
 | 
			
		||||
    template<class GaugeField, class SmearingPolicy>
 | 
			
		||||
  class Integrator {
 | 
			
		||||
 | 
			
		||||
  protected:
 | 
			
		||||
@@ -85,6 +85,8 @@ namespace Grid{
 | 
			
		||||
 | 
			
		||||
      GaugeField P;
 | 
			
		||||
 | 
			
		||||
      SmearingPolicy &Smearer;
 | 
			
		||||
      
 | 
			
		||||
      // Should match any legal (SU(n)) gauge field
 | 
			
		||||
      // Need to use this template to match Ncol to pass to SU<N> class
 | 
			
		||||
      template<int Ncol,class vec> void generate_momenta(Lattice< iVector< iScalar< iMatrix<vec,Ncol> >, Nd> > & P,GridParallelRNG& pRNG){
 | 
			
		||||
@@ -111,10 +113,17 @@ namespace Grid{
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void update_P(GaugeField &Mom,GaugeField&U, int level,double ep){
 | 
			
		||||
  	// input U actually not used... 
 | 
			
		||||
  	for(int a=0; a<as[level].actions.size(); ++a){
 | 
			
		||||
  		GaugeField force(U._grid);
 | 
			
		||||
	  as[level].actions.at(a)->deriv(U,force);
 | 
			
		||||
	  Mom = Mom - force*ep;
 | 
			
		||||
  		GaugeField& Us = Smearer.get_U(as[level].actions.at(a)->is_smeared);
 | 
			
		||||
  		as[level].actions.at(a)->deriv(Us,force); // deriv should NOT include Ta
 | 
			
		||||
 | 
			
		||||
	  	std::cout<< GridLogIntegrator << "Smearing (on/off): "<<as[level].actions.at(a)->is_smeared <<std::endl;
 | 
			
		||||
	  	if (as[level].actions.at(a)->is_smeared) Smearer.smeared_force(force);
 | 
			
		||||
	  	force = Ta(force);
 | 
			
		||||
	  	std::cout<< GridLogIntegrator << "Force average: "<< norm2(force)/(U._grid->gSites()) <<std::endl;
 | 
			
		||||
	  	Mom -= force*ep;
 | 
			
		||||
	  }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -137,6 +146,8 @@ namespace Grid{
 | 
			
		||||
			ProjectOnGroup(Umu);
 | 
			
		||||
			PokeIndex<LorentzIndex>(U, Umu, mu);
 | 
			
		||||
		}
 | 
			
		||||
	// Update the smeared fields, can be implemented as observer
 | 
			
		||||
		Smearer.set_GaugeField(U);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	virtual void step (GaugeField& U,int level, int first,int last)=0;
 | 
			
		||||
@@ -145,14 +156,17 @@ namespace Grid{
 | 
			
		||||
 | 
			
		||||
	Integrator(GridBase* grid, 
 | 
			
		||||
		IntegratorParameters Par,
 | 
			
		||||
		 ActionSet<GaugeField> & Aset):
 | 
			
		||||
		ActionSet<GaugeField> & Aset,
 | 
			
		||||
		SmearingPolicy &Sm):
 | 
			
		||||
	Params(Par),
 | 
			
		||||
	as(Aset),
 | 
			
		||||
	P(grid),
 | 
			
		||||
	  levels(Aset.size())
 | 
			
		||||
	levels(Aset.size()),
 | 
			
		||||
	Smearer(Sm)
 | 
			
		||||
	{
 | 
			
		||||
		t_P.resize(levels,0.0);
 | 
			
		||||
		t_U=0.0;
 | 
			
		||||
	// initialization of smearer delegated outside of Integrator
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	virtual ~Integrator(){}
 | 
			
		||||
@@ -163,13 +177,16 @@ namespace Grid{
 | 
			
		||||
		generate_momenta(P,pRNG);
 | 
			
		||||
		for(int level=0; level< as.size(); ++level){
 | 
			
		||||
			for(int actionID=0; actionID<as[level].actions.size(); ++actionID){
 | 
			
		||||
	    as[level].actions.at(actionID)->refresh(U, pRNG);
 | 
			
		||||
	    // get gauge field from the SmearingPolicy and
 | 
			
		||||
	    // based on the boolean is_smeared in actionID
 | 
			
		||||
				GaugeField& Us = Smearer.get_U(as[level].actions.at(actionID)->is_smeared);
 | 
			
		||||
				as[level].actions.at(actionID)->refresh(Us, pRNG);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      // Calculate action
 | 
			
		||||
      RealD S(GaugeField& U){
 | 
			
		||||
	RealD S(GaugeField& U){// here also U not used
 | 
			
		||||
 | 
			
		||||
		LatticeComplex Hloc(U._grid);	Hloc = zero;
 | 
			
		||||
	// Momenta
 | 
			
		||||
@@ -186,8 +203,11 @@ namespace Grid{
 | 
			
		||||
	// Actions
 | 
			
		||||
		for(int level=0; level<as.size(); ++level){
 | 
			
		||||
			for(int actionID=0; actionID<as[level].actions.size(); ++actionID){
 | 
			
		||||
	    Hterm = as[level].actions.at(actionID)->S(U);
 | 
			
		||||
	    std::cout<<GridLogMessage << "Level "<<level<<" term "<<actionID<<" H = "<<Hterm<<std::endl;
 | 
			
		||||
	    // get gauge field from the SmearingPolicy and
 | 
			
		||||
	    // based on the boolean is_smeared in actionID
 | 
			
		||||
				GaugeField& Us = Smearer.get_U(as[level].actions.at(actionID)->is_smeared);
 | 
			
		||||
				Hterm = as[level].actions.at(actionID)->S(Us);
 | 
			
		||||
				std::cout<<GridLogMessage << "S Level "<<level<<" term "<<actionID<<" H = "<<Hterm<<std::endl;
 | 
			
		||||
				H += Hterm;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -91,14 +91,17 @@ namespace Grid{
 | 
			
		||||
    *  P 1/2                            P 1/2
 | 
			
		||||
    */    
 | 
			
		||||
 | 
			
		||||
    template<class GaugeField> class LeapFrog : public Integrator<GaugeField> {
 | 
			
		||||
    template<class GaugeField, class SmearingPolicy> class LeapFrog :
 | 
			
		||||
      public Integrator<GaugeField, SmearingPolicy> {
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
      typedef LeapFrog<GaugeField> Algorithm;
 | 
			
		||||
      typedef LeapFrog<GaugeField, SmearingPolicy> Algorithm;
 | 
			
		||||
 | 
			
		||||
      LeapFrog(GridBase* grid, 
 | 
			
		||||
	       IntegratorParameters Par,
 | 
			
		||||
	       ActionSet<GaugeField> & Aset): Integrator<GaugeField>(grid,Par,Aset) {};
 | 
			
		||||
	       ActionSet<GaugeField> & Aset,
 | 
			
		||||
	       SmearingPolicy & Sm):
 | 
			
		||||
	Integrator<GaugeField, SmearingPolicy>(grid,Par,Aset,Sm) {};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      void step (GaugeField& U, int level,int _first, int _last){
 | 
			
		||||
@@ -135,7 +138,8 @@ namespace Grid{
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    template<class GaugeField> class MinimumNorm2 : public Integrator<GaugeField> {
 | 
			
		||||
    template<class GaugeField, class SmearingPolicy> class MinimumNorm2 :
 | 
			
		||||
      public Integrator<GaugeField, SmearingPolicy> {
 | 
			
		||||
    private:
 | 
			
		||||
      const RealD lambda = 0.1931833275037836;
 | 
			
		||||
 | 
			
		||||
@@ -143,7 +147,9 @@ namespace Grid{
 | 
			
		||||
 | 
			
		||||
      MinimumNorm2(GridBase* grid, 
 | 
			
		||||
		   IntegratorParameters Par,
 | 
			
		||||
		   ActionSet<GaugeField> & Aset): Integrator<GaugeField>(grid,Par,Aset) {};
 | 
			
		||||
		   ActionSet<GaugeField> & Aset,
 | 
			
		||||
		   SmearingPolicy& Sm):
 | 
			
		||||
	Integrator<GaugeField, SmearingPolicy>(grid,Par,Aset,Sm) {};
 | 
			
		||||
 | 
			
		||||
      void step (GaugeField& U, int level, int _first,int _last){
 | 
			
		||||
 | 
			
		||||
@@ -191,7 +197,8 @@ namespace Grid{
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    template<class GaugeField> class ForceGradient : public Integrator<GaugeField> {
 | 
			
		||||
    template<class GaugeField, class SmearingPolicy> class ForceGradient :
 | 
			
		||||
      public Integrator<GaugeField, SmearingPolicy> {
 | 
			
		||||
    private:
 | 
			
		||||
      const RealD lambda = 1.0/6.0;;
 | 
			
		||||
      const RealD chi    = 1.0/72.0;
 | 
			
		||||
@@ -202,7 +209,9 @@ namespace Grid{
 | 
			
		||||
      // Looks like dH scales as dt^4. tested wilson/wilson 2 level.
 | 
			
		||||
    ForceGradient(GridBase* grid, 
 | 
			
		||||
		  IntegratorParameters Par,
 | 
			
		||||
		  ActionSet<GaugeField> & Aset): Integrator<GaugeField>(grid,Par,Aset) {};
 | 
			
		||||
		  ActionSet<GaugeField> & Aset,
 | 
			
		||||
		  SmearingPolicy &Sm):
 | 
			
		||||
      Integrator<GaugeField, SmearingPolicy>(grid,Par,Aset, Sm) {};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      void FG_update_P(GaugeField&U, int level,double fg_dt,double ep){
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										130
									
								
								lib/qcd/smearing/APEsmearing.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								lib/qcd/smearing/APEsmearing.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,130 @@
 | 
			
		||||
/*!
 | 
			
		||||
  @brief Declaration of Smear_APE class for APE smearing
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef APE_SMEAR_
 | 
			
		||||
#define APE_SMEAR_
 | 
			
		||||
 | 
			
		||||
  namespace Grid {
 | 
			
		||||
  	namespace QCD {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /*!  @brief APE type smearing of link variables. */
 | 
			
		||||
    template <class Gimpl> 
 | 
			
		||||
  		class Smear_APE: public Smear<Gimpl>{
 | 
			
		||||
  		private:
 | 
			
		||||
      	const std::vector<double> rho;/*!< Array of weights */
 | 
			
		||||
 | 
			
		||||
//This member must be private - we do not want to control from outside 
 | 
			
		||||
  			std::vector<double> set_rho(const double common_rho) const {
 | 
			
		||||
  				std::vector<double> res;
 | 
			
		||||
 | 
			
		||||
  				for(int mn=0; mn<Nd*Nd; ++mn) res.push_back(common_rho);
 | 
			
		||||
  					for(int mu=0; mu<Nd; ++mu) res[mu + mu*Nd] = 0.0;
 | 
			
		||||
  						return res;
 | 
			
		||||
  				}
 | 
			
		||||
 | 
			
		||||
  			public:
 | 
			
		||||
      // Defines the gauge field types
 | 
			
		||||
  				INHERIT_GIMPL_TYPES(Gimpl)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      // Constructors and destructors
 | 
			
		||||
  				Smear_APE(const std::vector<double>& rho_):rho(rho_){} // check vector size
 | 
			
		||||
  				Smear_APE(double rho_val):rho(set_rho(rho_val)){}
 | 
			
		||||
  				Smear_APE():rho(set_rho(1.0)){}
 | 
			
		||||
  				~Smear_APE(){}
 | 
			
		||||
 | 
			
		||||
      ///////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
  				void smear(GaugeField& u_smr, const GaugeField& U)const{
 | 
			
		||||
  					GridBase *grid = U._grid;
 | 
			
		||||
  					GaugeLinkField Cup(grid), tmp_stpl(grid);
 | 
			
		||||
  					WilsonLoops<Gimpl> WL;
 | 
			
		||||
  					u_smr = zero; 
 | 
			
		||||
 | 
			
		||||
  					for(int mu=0; mu<Nd; ++mu){
 | 
			
		||||
  						Cup = zero;
 | 
			
		||||
  						for(int nu=0; nu<Nd; ++nu){
 | 
			
		||||
  							if (nu != mu) {
 | 
			
		||||
  								// get the staple in direction mu, nu
 | 
			
		||||
	      						WL.Staple(tmp_stpl, U, mu, nu);  //nb staple conventions of IroIro and Grid differ by a dagger
 | 
			
		||||
	      						Cup += tmp_stpl*rho[mu + Nd * nu];
 | 
			
		||||
	      					}
 | 
			
		||||
	      				}
 | 
			
		||||
	  					// save the Cup link-field on the u_smr gauge-field
 | 
			
		||||
	  					pokeLorentz(u_smr, adj(Cup), mu); // u_smr[mu] = Cup^dag   see conventions for Staple
 | 
			
		||||
	  				}
 | 
			
		||||
	  			}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
	  			void derivative(GaugeField& SigmaTerm,
 | 
			
		||||
	  				const GaugeField& iLambda,
 | 
			
		||||
	  				const GaugeField& U)const{
 | 
			
		||||
 | 
			
		||||
	// Reference 
 | 
			
		||||
	// Morningstar, Peardon, Phys.Rev.D69,054501(2004)
 | 
			
		||||
	// Equation 75
 | 
			
		||||
    // Computing Sigma_mu, derivative of S[fat links] with respect to the thin links
 | 
			
		||||
    // Output SigmaTerm
 | 
			
		||||
 | 
			
		||||
	  				GridBase *grid = U._grid;
 | 
			
		||||
 | 
			
		||||
	  				WilsonLoops<Gimpl> WL;
 | 
			
		||||
	  				GaugeLinkField staple(grid), u_tmp(grid);
 | 
			
		||||
	  				GaugeLinkField iLambda_mu(grid), iLambda_nu(grid);
 | 
			
		||||
	  				GaugeLinkField U_mu(grid), U_nu(grid);
 | 
			
		||||
	  				GaugeLinkField sh_field(grid), temp_Sigma(grid);
 | 
			
		||||
	  				Real rho_munu, rho_numu;
 | 
			
		||||
 | 
			
		||||
	  				for(int mu = 0; mu < Nd; ++mu){
 | 
			
		||||
	  					U_mu       = peekLorentz(      U, mu);
 | 
			
		||||
	  					iLambda_mu = peekLorentz(iLambda, mu);
 | 
			
		||||
 | 
			
		||||
	  					for(int nu = 0; nu < Nd; ++nu){
 | 
			
		||||
	  						if(nu==mu) continue;
 | 
			
		||||
	  						U_nu       = peekLorentz(      U, nu);
 | 
			
		||||
	  						iLambda_nu = peekLorentz(iLambda, nu);
 | 
			
		||||
 | 
			
		||||
	  						rho_munu = rho[mu + Nd * nu];
 | 
			
		||||
	  						rho_numu = rho[nu + Nd * mu];
 | 
			
		||||
 | 
			
		||||
	  						WL.StapleUpper(staple, U, mu, nu);
 | 
			
		||||
 | 
			
		||||
	  						temp_Sigma = -rho_numu*staple*iLambda_nu;  //ok
 | 
			
		||||
	        				//-r_numu*U_nu(x+mu)*Udag_mu(x+nu)*Udag_nu(x)*Lambda_nu(x)
 | 
			
		||||
	  						Gimpl::AddGaugeLink(SigmaTerm, temp_Sigma, mu);
 | 
			
		||||
 | 
			
		||||
	    					sh_field = Cshift(iLambda_nu, mu, 1);// general also for Gparity?
 | 
			
		||||
 | 
			
		||||
	    					temp_Sigma = rho_numu*sh_field*staple; //ok
 | 
			
		||||
	    					//r_numu*Lambda_nu(mu)*U_nu(x+mu)*Udag_mu(x+nu)*Udag_nu(x)
 | 
			
		||||
	    					Gimpl::AddGaugeLink(SigmaTerm, temp_Sigma, mu);
 | 
			
		||||
 | 
			
		||||
	    					sh_field = Cshift(iLambda_mu, nu, 1);
 | 
			
		||||
 | 
			
		||||
	    					temp_Sigma = -rho_munu*staple*U_nu*sh_field*adj(U_nu); //ok
 | 
			
		||||
	    					//-r_munu*U_nu(x+mu)*Udag_mu(x+nu)*Lambda_mu(x+nu)*Udag_nu(x)
 | 
			
		||||
	    					Gimpl::AddGaugeLink(SigmaTerm, temp_Sigma, mu);
 | 
			
		||||
 | 
			
		||||
	    					staple = zero;
 | 
			
		||||
	    					sh_field = Cshift(U_nu, mu, 1);
 | 
			
		||||
 | 
			
		||||
	    					temp_Sigma = -rho_munu*adj(sh_field)*adj(U_mu)*iLambda_mu*U_nu;
 | 
			
		||||
	    					temp_Sigma += rho_numu*adj(sh_field)*adj(U_mu)*iLambda_nu*U_nu;
 | 
			
		||||
 | 
			
		||||
	    					u_tmp = adj(U_nu)*iLambda_nu;
 | 
			
		||||
	    					sh_field = Cshift(u_tmp, mu, 1);
 | 
			
		||||
	    					temp_Sigma += -rho_numu*sh_field*adj(U_mu)*U_nu;
 | 
			
		||||
	    					sh_field = Cshift(temp_Sigma, nu, -1);
 | 
			
		||||
	    					Gimpl::AddGaugeLink(SigmaTerm, sh_field, mu);
 | 
			
		||||
 | 
			
		||||
	    				}
 | 
			
		||||
	    			}
 | 
			
		||||
	    		}
 | 
			
		||||
	    	};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  }// namespace QCD
 | 
			
		||||
}//namespace Grid
 | 
			
		||||
#endif  
 | 
			
		||||
							
								
								
									
										17
									
								
								lib/qcd/smearing/BaseSmearing.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								lib/qcd/smearing/BaseSmearing.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
/*
 | 
			
		||||
  @brief Declares base smearing class Smear
 | 
			
		||||
 */
 | 
			
		||||
#ifndef BASE_SMEAR_
 | 
			
		||||
#define BASE_SMEAR_
 | 
			
		||||
 | 
			
		||||
template <class Gimpl> 
 | 
			
		||||
class Smear{
 | 
			
		||||
public:
 | 
			
		||||
  INHERIT_GIMPL_TYPES(Gimpl) // inherits the types for the gauge fields
 | 
			
		||||
 | 
			
		||||
  virtual ~Smear(){}
 | 
			
		||||
  virtual void smear     (GaugeField&,const GaugeField&)const = 0;
 | 
			
		||||
  virtual void derivative(GaugeField&,
 | 
			
		||||
			  const GaugeField&,const GaugeField&) const = 0;
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										262
									
								
								lib/qcd/smearing/GaugeConfiguration.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										262
									
								
								lib/qcd/smearing/GaugeConfiguration.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,262 @@
 | 
			
		||||
/*!
 | 
			
		||||
  @file GaugeConfiguration.h
 | 
			
		||||
 | 
			
		||||
  @brief Declares the GaugeConfiguration class
 | 
			
		||||
*/
 | 
			
		||||
#ifndef GAUGE_CONFIG_
 | 
			
		||||
#define GAUGE_CONFIG_
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
namespace QCD {
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  @brief Smeared configuration container
 | 
			
		||||
 | 
			
		||||
  It will behave like a configuration from the point of view of
 | 
			
		||||
  the HMC update and integrators.
 | 
			
		||||
  An "advanced configuration" object that can provide not only the
 | 
			
		||||
  data to store the gauge configuration but also operations to manipulate
 | 
			
		||||
  it, like smearing.
 | 
			
		||||
 | 
			
		||||
  It stores a list of smeared configurations.
 | 
			
		||||
*/
 | 
			
		||||
template <class Gimpl>
 | 
			
		||||
class SmearedConfiguration {
 | 
			
		||||
 public:
 | 
			
		||||
  INHERIT_GIMPL_TYPES(Gimpl);
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  const unsigned int smearingLevels;
 | 
			
		||||
  Smear_Stout<Gimpl> StoutSmearing;
 | 
			
		||||
  std::vector<GaugeField> SmearedSet;
 | 
			
		||||
 | 
			
		||||
  // Member functions
 | 
			
		||||
  //====================================================================
 | 
			
		||||
  void fill_smearedSet(GaugeField& U) {
 | 
			
		||||
    ThinLinks = &U;  // attach the smearing routine to the field U
 | 
			
		||||
 | 
			
		||||
    // check the pointer is not null
 | 
			
		||||
    if (ThinLinks == NULL)
 | 
			
		||||
      std::cout << GridLogError
 | 
			
		||||
                << "[SmearedConfiguration] Error in ThinLinks pointer\n";
 | 
			
		||||
 | 
			
		||||
    if (smearingLevels > 0) {
 | 
			
		||||
      std::cout << GridLogDebug
 | 
			
		||||
                << "[SmearedConfiguration] Filling SmearedSet\n";
 | 
			
		||||
      GaugeField previous_u(ThinLinks->_grid);
 | 
			
		||||
 | 
			
		||||
      previous_u = *ThinLinks;
 | 
			
		||||
      for (int smearLvl = 0; smearLvl < smearingLevels; ++smearLvl) {
 | 
			
		||||
        StoutSmearing.smear(SmearedSet[smearLvl], previous_u);
 | 
			
		||||
        previous_u = SmearedSet[smearLvl];
 | 
			
		||||
 | 
			
		||||
        // For debug purposes
 | 
			
		||||
        RealD impl_plaq = WilsonLoops<Gimpl>::avgPlaquette(previous_u);
 | 
			
		||||
        std::cout << GridLogDebug
 | 
			
		||||
                  << "[SmearedConfiguration] Plaq: " << impl_plaq << std::endl;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  //====================================================================
 | 
			
		||||
  GaugeField AnalyticSmearedForce(const GaugeField& SigmaKPrime,
 | 
			
		||||
                                  const GaugeField& GaugeK) const {
 | 
			
		||||
    GridBase* grid = GaugeK._grid;
 | 
			
		||||
    GaugeField C(grid), SigmaK(grid), iLambda(grid);
 | 
			
		||||
    GaugeLinkField iLambda_mu(grid);
 | 
			
		||||
    GaugeLinkField iQ(grid), e_iQ(grid);
 | 
			
		||||
    GaugeLinkField SigmaKPrime_mu(grid);
 | 
			
		||||
    GaugeLinkField GaugeKmu(grid), Cmu(grid);
 | 
			
		||||
 | 
			
		||||
    StoutSmearing.BaseSmear(C, GaugeK);
 | 
			
		||||
    SigmaK = zero;
 | 
			
		||||
    iLambda = zero;
 | 
			
		||||
 | 
			
		||||
    for (int mu = 0; mu < Nd; mu++) {
 | 
			
		||||
      Cmu = peekLorentz(C, mu);
 | 
			
		||||
      GaugeKmu = peekLorentz(GaugeK, mu);
 | 
			
		||||
      SigmaKPrime_mu = peekLorentz(SigmaKPrime, mu);
 | 
			
		||||
      iQ = Ta(Cmu * adj(GaugeKmu));
 | 
			
		||||
      set_iLambda(iLambda_mu, e_iQ, iQ, SigmaKPrime_mu, GaugeKmu);
 | 
			
		||||
      pokeLorentz(SigmaK, SigmaKPrime_mu * e_iQ + adj(Cmu) * iLambda_mu, mu);
 | 
			
		||||
      pokeLorentz(iLambda, iLambda_mu, mu);
 | 
			
		||||
    }
 | 
			
		||||
    StoutSmearing.derivative(SigmaK, iLambda,
 | 
			
		||||
                             GaugeK);  // derivative of SmearBase
 | 
			
		||||
    return SigmaK;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /*! @brief Returns smeared configuration at level 'Level' */
 | 
			
		||||
  const GaugeField& get_smeared_conf(int Level) const {
 | 
			
		||||
    return SmearedSet[Level];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //====================================================================
 | 
			
		||||
  void set_iLambda(GaugeLinkField& iLambda, GaugeLinkField& e_iQ,
 | 
			
		||||
                   const GaugeLinkField& iQ, const GaugeLinkField& Sigmap,
 | 
			
		||||
                   const GaugeLinkField& GaugeK) const {
 | 
			
		||||
    GridBase* grid = iQ._grid;
 | 
			
		||||
    GaugeLinkField iQ2(grid), iQ3(grid), B1(grid), B2(grid), USigmap(grid);
 | 
			
		||||
    GaugeLinkField unity(grid);
 | 
			
		||||
    unity = 1.0;
 | 
			
		||||
 | 
			
		||||
    LatticeComplex u(grid), w(grid);
 | 
			
		||||
    LatticeComplex f0(grid), f1(grid), f2(grid);
 | 
			
		||||
    LatticeComplex xi0(grid), xi1(grid), tmp(grid);
 | 
			
		||||
    LatticeComplex u2(grid), w2(grid), cosw(grid);
 | 
			
		||||
    LatticeComplex emiu(grid), e2iu(grid), qt(grid), fden(grid);
 | 
			
		||||
    LatticeComplex r01(grid), r11(grid), r21(grid), r02(grid), r12(grid);
 | 
			
		||||
    LatticeComplex r22(grid), tr1(grid), tr2(grid);
 | 
			
		||||
    LatticeComplex b10(grid), b11(grid), b12(grid), b20(grid), b21(grid),
 | 
			
		||||
        b22(grid);
 | 
			
		||||
    LatticeComplex LatticeUnitComplex(grid);
 | 
			
		||||
 | 
			
		||||
    LatticeUnitComplex = 1.0;
 | 
			
		||||
 | 
			
		||||
    // Exponential
 | 
			
		||||
    iQ2 = iQ * iQ;
 | 
			
		||||
    iQ3 = iQ * iQ2;
 | 
			
		||||
    StoutSmearing.set_uw(u, w, iQ2, iQ3);
 | 
			
		||||
    StoutSmearing.set_fj(f0, f1, f2, u, w);
 | 
			
		||||
    e_iQ = f0 * unity + timesMinusI(f1) * iQ - f2 * iQ2;
 | 
			
		||||
 | 
			
		||||
    // Getting B1, B2, Gamma and Lambda
 | 
			
		||||
    // simplify this part, reduntant calculations in set_fj
 | 
			
		||||
    xi0 = StoutSmearing.func_xi0(w);
 | 
			
		||||
    xi1 = StoutSmearing.func_xi1(w);
 | 
			
		||||
    u2 = u * u;
 | 
			
		||||
    w2 = w * w;
 | 
			
		||||
    cosw = cos(w);
 | 
			
		||||
 | 
			
		||||
    emiu = cos(u) - timesI(sin(u));
 | 
			
		||||
    e2iu = cos(2.0 * u) + timesI(sin(2.0 * u));
 | 
			
		||||
 | 
			
		||||
    r01 = (2.0 * u + timesI(2.0 * (u2 - w2))) * e2iu +
 | 
			
		||||
          emiu * ((16.0 * u * cosw + 2.0 * u * (3.0 * u2 + w2) * xi0) +
 | 
			
		||||
                  timesI(-8.0 * u2 * cosw + 2.0 * (9.0 * u2 + w2) * xi0));
 | 
			
		||||
 | 
			
		||||
    r11 = (2.0 * LatticeUnitComplex + timesI(4.0 * u)) * e2iu +
 | 
			
		||||
          emiu * ((-2.0 * cosw + (3.0 * u2 - w2) * xi0) +
 | 
			
		||||
                  timesI((2.0 * u * cosw + 6.0 * u * xi0)));
 | 
			
		||||
 | 
			
		||||
    r21 =
 | 
			
		||||
        2.0 * timesI(e2iu) + emiu * (-3.0 * u * xi0 + timesI(cosw - 3.0 * xi0));
 | 
			
		||||
 | 
			
		||||
    r02 = -2.0 * e2iu +
 | 
			
		||||
          emiu * (-8.0 * u2 * xi0 +
 | 
			
		||||
                  timesI(2.0 * u * (cosw + xi0 + 3.0 * u2 * xi1)));
 | 
			
		||||
 | 
			
		||||
    r12 = emiu * (2.0 * u * xi0 + timesI(-cosw - xi0 + 3.0 * u2 * xi1));
 | 
			
		||||
 | 
			
		||||
    r22 = emiu * (xi0 - timesI(3.0 * u * xi1));
 | 
			
		||||
 | 
			
		||||
    fden = LatticeUnitComplex / (2.0 * (9.0 * u2 - w2) * (9.0 * u2 - w2));
 | 
			
		||||
 | 
			
		||||
    b10 = 2.0 * u * r01 + (3.0 * u2 - w2) * r02 - (30.0 * u2 + 2.0 * w2) * f0;
 | 
			
		||||
    b11 = 2.0 * u * r11 + (3.0 * u2 - w2) * r12 - (30.0 * u2 + 2.0 * w2) * f1;
 | 
			
		||||
    b12 = 2.0 * u * r21 + (3.0 * u2 - w2) * r22 - (30.0 * u2 + 2.0 * w2) * f2;
 | 
			
		||||
 | 
			
		||||
    b20 = r01 - (3.0 * u) * r02 - (24.0 * u) * f0;
 | 
			
		||||
    b21 = r11 - (3.0 * u) * r12 - (24.0 * u) * f1;
 | 
			
		||||
    b22 = r21 - (3.0 * u) * r22 - (24.0 * u) * f2;
 | 
			
		||||
 | 
			
		||||
    b10 *= fden;
 | 
			
		||||
    b11 *= fden;
 | 
			
		||||
    b12 *= fden;
 | 
			
		||||
    b20 *= fden;
 | 
			
		||||
    b21 *= fden;
 | 
			
		||||
    b22 *= fden;
 | 
			
		||||
 | 
			
		||||
    B1 = b10 * unity + timesMinusI(b11) * iQ - b12 * iQ2;
 | 
			
		||||
    B2 = b20 * unity + timesMinusI(b21) * iQ - b22 * iQ2;
 | 
			
		||||
    USigmap = GaugeK * Sigmap;
 | 
			
		||||
 | 
			
		||||
    tr1 = trace(USigmap * B1);
 | 
			
		||||
    tr2 = trace(USigmap * B2);
 | 
			
		||||
 | 
			
		||||
    GaugeLinkField QUS = iQ * USigmap;
 | 
			
		||||
    GaugeLinkField USQ = USigmap * iQ;
 | 
			
		||||
 | 
			
		||||
    GaugeLinkField iGamma = tr1 * iQ - timesI(tr2) * iQ2 +
 | 
			
		||||
                            timesI(f1) * USigmap + f2 * QUS + f2 * USQ;
 | 
			
		||||
 | 
			
		||||
    iLambda = Ta(iGamma);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //====================================================================
 | 
			
		||||
 public:
 | 
			
		||||
  GaugeField*
 | 
			
		||||
      ThinLinks; /*!< @brief Pointer to the thin
 | 
			
		||||
                                                         links configuration */
 | 
			
		||||
 | 
			
		||||
  /*! @brief Standard constructor */
 | 
			
		||||
  SmearedConfiguration(GridCartesian* UGrid, unsigned int Nsmear,
 | 
			
		||||
                       Smear_Stout<Gimpl>& Stout)
 | 
			
		||||
      : smearingLevels(Nsmear), StoutSmearing(Stout), ThinLinks(NULL) {
 | 
			
		||||
    for (unsigned int i = 0; i < smearingLevels; ++i)
 | 
			
		||||
      SmearedSet.push_back(*(new GaugeField(UGrid)));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /*! For just thin links */
 | 
			
		||||
  SmearedConfiguration()
 | 
			
		||||
      : smearingLevels(0), StoutSmearing(), SmearedSet(), ThinLinks(NULL) {}
 | 
			
		||||
 | 
			
		||||
  // attach the smeared routines to the thin links U and fill the smeared set
 | 
			
		||||
  void set_GaugeField(GaugeField& U) { fill_smearedSet(U); }
 | 
			
		||||
 | 
			
		||||
  //====================================================================
 | 
			
		||||
  void smeared_force(GaugeField& SigmaTilde) const {
 | 
			
		||||
    if (smearingLevels > 0) {
 | 
			
		||||
      GaugeField force = SigmaTilde; // actually = U*SigmaTilde
 | 
			
		||||
      GaugeLinkField tmp_mu(SigmaTilde._grid);
 | 
			
		||||
 | 
			
		||||
      for (int mu = 0; mu < Nd; mu++) {
 | 
			
		||||
        // to get just SigmaTilde
 | 
			
		||||
        tmp_mu = adj(peekLorentz(SmearedSet[smearingLevels - 1], mu)) *
 | 
			
		||||
                 peekLorentz(force, mu);
 | 
			
		||||
        pokeLorentz(force, tmp_mu, mu);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      for (int ismr = smearingLevels - 1; ismr > 0; --ismr)
 | 
			
		||||
        force = AnalyticSmearedForce(force, get_smeared_conf(ismr - 1));
 | 
			
		||||
 | 
			
		||||
      force = AnalyticSmearedForce(force, *ThinLinks);
 | 
			
		||||
 | 
			
		||||
      for (int mu = 0; mu < Nd; mu++) {
 | 
			
		||||
        tmp_mu = peekLorentz(*ThinLinks, mu) * peekLorentz(force, mu);
 | 
			
		||||
        pokeLorentz(SigmaTilde, tmp_mu, mu);
 | 
			
		||||
      }
 | 
			
		||||
    }  // if smearingLevels = 0 do nothing
 | 
			
		||||
  }
 | 
			
		||||
  //====================================================================
 | 
			
		||||
 | 
			
		||||
  GaugeField& get_SmearedU() { return SmearedSet[smearingLevels - 1]; }
 | 
			
		||||
 | 
			
		||||
  GaugeField& get_U(bool smeared = false) {
 | 
			
		||||
    // get the config, thin links by default
 | 
			
		||||
    if (smeared) {
 | 
			
		||||
      if (smearingLevels) {
 | 
			
		||||
        RealD impl_plaq =
 | 
			
		||||
            WilsonLoops<Gimpl>::avgPlaquette(SmearedSet[smearingLevels - 1]);
 | 
			
		||||
        std::cout << GridLogDebug << "getting Usmr Plaq: " << impl_plaq
 | 
			
		||||
                  << std::endl;
 | 
			
		||||
        return get_SmearedU();
 | 
			
		||||
 | 
			
		||||
      } else {
 | 
			
		||||
        RealD impl_plaq = WilsonLoops<Gimpl>::avgPlaquette(*ThinLinks);
 | 
			
		||||
        std::cout << GridLogDebug << "getting Thin Plaq: " << impl_plaq
 | 
			
		||||
                  << std::endl;
 | 
			
		||||
        return *ThinLinks;
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      RealD impl_plaq = WilsonLoops<Gimpl>::avgPlaquette(*ThinLinks);
 | 
			
		||||
      std::cout << GridLogDebug << "getting Thin Plaq: " << impl_plaq
 | 
			
		||||
                << std::endl;
 | 
			
		||||
      return *ThinLinks;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										9
									
								
								lib/qcd/smearing/Smearing.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								lib/qcd/smearing/Smearing.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
#ifndef GRID_QCD_SMEARING_H
 | 
			
		||||
#define GRID_QCD_SMEARING_H
 | 
			
		||||
 | 
			
		||||
#include <qcd/smearing/BaseSmearing.h>
 | 
			
		||||
#include <qcd/smearing/APEsmearing.h>
 | 
			
		||||
#include <qcd/smearing/StoutSmearing.h>
 | 
			
		||||
#include <qcd/smearing/GaugeConfiguration.h>
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										160
									
								
								lib/qcd/smearing/StoutSmearing.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								lib/qcd/smearing/StoutSmearing.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,160 @@
 | 
			
		||||
/*
 | 
			
		||||
  @file stoutSmear.hpp
 | 
			
		||||
  @brief Declares Stout smearing class
 | 
			
		||||
*/
 | 
			
		||||
#ifndef STOUT_SMEAR_
 | 
			
		||||
#define STOUT_SMEAR_
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
namespace QCD {
 | 
			
		||||
 | 
			
		||||
/*!  @brief Stout smearing of link variable. */
 | 
			
		||||
template <class Gimpl>
 | 
			
		||||
class Smear_Stout : public Smear<Gimpl> {
 | 
			
		||||
 private:
 | 
			
		||||
  const Smear<Gimpl>* SmearBase;
 | 
			
		||||
 | 
			
		||||
 public:
 | 
			
		||||
  INHERIT_GIMPL_TYPES(Gimpl)
 | 
			
		||||
 | 
			
		||||
  Smear_Stout(Smear<Gimpl>* base) : SmearBase(base) {
 | 
			
		||||
    static_assert(Nc == 3,
 | 
			
		||||
                  "Stout smearing currently implemented only for Nc==3");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /*! Default constructor */
 | 
			
		||||
  Smear_Stout(double rho = 1.0) : SmearBase(new Smear_APE<Gimpl>(rho)) {
 | 
			
		||||
    static_assert(Nc == 3,
 | 
			
		||||
                  "Stout smearing currently implemented only for Nc==3");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ~Smear_Stout() {}  // delete SmearBase...
 | 
			
		||||
 | 
			
		||||
  void smear(GaugeField& u_smr, const GaugeField& U) const {
 | 
			
		||||
    GaugeField C(U._grid);
 | 
			
		||||
    GaugeLinkField tmp(U._grid), iq_mu(U._grid), Umu(U._grid);
 | 
			
		||||
 | 
			
		||||
    std::cout << GridLogDebug << "Stout smearing started\n";
 | 
			
		||||
 | 
			
		||||
    // Smear the configurations
 | 
			
		||||
    SmearBase->smear(C, U);
 | 
			
		||||
 | 
			
		||||
    for (int mu = 0; mu < Nd; mu++) {
 | 
			
		||||
      tmp = peekLorentz(C, mu);
 | 
			
		||||
      Umu = peekLorentz(U, mu);
 | 
			
		||||
      iq_mu = Ta(
 | 
			
		||||
          tmp *
 | 
			
		||||
          adj(Umu));  // iq_mu = Ta(Omega_mu) to match the signs with the paper
 | 
			
		||||
      exponentiate_iQ(tmp, iq_mu);
 | 
			
		||||
      pokeLorentz(u_smr, tmp * Umu, mu);  // u_smr = exp(iQ_mu)*U_mu
 | 
			
		||||
    }
 | 
			
		||||
    std::cout << GridLogDebug << "Stout smearing completed\n";
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  void derivative(GaugeField& SigmaTerm, const GaugeField& iLambda,
 | 
			
		||||
                  const GaugeField& Gauge) const {
 | 
			
		||||
    SmearBase->derivative(SigmaTerm, iLambda, Gauge);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  void BaseSmear(GaugeField& C, const GaugeField& U) const {
 | 
			
		||||
    SmearBase->smear(C, U);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  void exponentiate_iQ(GaugeLinkField& e_iQ, const GaugeLinkField& iQ) const {
 | 
			
		||||
    // Put this outside
 | 
			
		||||
    // only valid for SU(3) matrices
 | 
			
		||||
 | 
			
		||||
    // only one Lorentz direction at a time
 | 
			
		||||
 | 
			
		||||
    // notice that it actually computes
 | 
			
		||||
    // exp ( input matrix )
 | 
			
		||||
    // the i sign is coming from outside
 | 
			
		||||
    // input matrix is anti-hermitian NOT hermitian
 | 
			
		||||
 | 
			
		||||
    GridBase* grid = iQ._grid;
 | 
			
		||||
    GaugeLinkField unity(grid);
 | 
			
		||||
    unity = 1.0;
 | 
			
		||||
 | 
			
		||||
    GaugeLinkField iQ2(grid), iQ3(grid);
 | 
			
		||||
    LatticeComplex u(grid), w(grid);
 | 
			
		||||
    LatticeComplex f0(grid), f1(grid), f2(grid);
 | 
			
		||||
 | 
			
		||||
    iQ2 = iQ * iQ;
 | 
			
		||||
    iQ3 = iQ * iQ2;
 | 
			
		||||
 | 
			
		||||
    set_uw(u, w, iQ2, iQ3);
 | 
			
		||||
    set_fj(f0, f1, f2, u, w);
 | 
			
		||||
 | 
			
		||||
    e_iQ = f0 * unity + timesMinusI(f1) * iQ - f2 * iQ2;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  void set_uw(LatticeComplex& u, LatticeComplex& w, GaugeLinkField& iQ2,
 | 
			
		||||
              GaugeLinkField& iQ3) const {
 | 
			
		||||
    Complex one_over_three = 1.0 / 3.0;
 | 
			
		||||
    Complex one_over_two = 1.0 / 2.0;
 | 
			
		||||
 | 
			
		||||
    GridBase* grid = u._grid;
 | 
			
		||||
    LatticeComplex c0(grid), c1(grid), tmp(grid), c0max(grid), theta(grid);
 | 
			
		||||
 | 
			
		||||
    // sign in c0 from the conventions on the Ta
 | 
			
		||||
    c0 = -imag(trace(iQ3)) * one_over_three;  
 | 
			
		||||
    c1 = -real(trace(iQ2)) * one_over_two;
 | 
			
		||||
 | 
			
		||||
    // Cayley Hamilton checks to machine precision, tested
 | 
			
		||||
    tmp = c1 * one_over_three;
 | 
			
		||||
    c0max = 2.0 * pow(tmp, 1.5);
 | 
			
		||||
 | 
			
		||||
    theta = acos(c0 / c0max) *
 | 
			
		||||
            one_over_three;  // divide by three here, now leave as it is
 | 
			
		||||
    u = sqrt(tmp) * cos(theta);
 | 
			
		||||
    w = sqrt(c1) * sin(theta);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void set_fj(LatticeComplex& f0, LatticeComplex& f1, LatticeComplex& f2,
 | 
			
		||||
              const LatticeComplex& u, const LatticeComplex& w) const {
 | 
			
		||||
    GridBase* grid = u._grid;
 | 
			
		||||
    LatticeComplex xi0(grid), u2(grid), w2(grid), cosw(grid);
 | 
			
		||||
    LatticeComplex fden(grid);
 | 
			
		||||
    LatticeComplex h0(grid), h1(grid), h2(grid);
 | 
			
		||||
    LatticeComplex e2iu(grid), emiu(grid), ixi0(grid), qt(grid);
 | 
			
		||||
    LatticeComplex unity(grid);
 | 
			
		||||
    unity = 1.0;
 | 
			
		||||
 | 
			
		||||
    xi0 = func_xi0(w);
 | 
			
		||||
    u2 = u * u;
 | 
			
		||||
    w2 = w * w;
 | 
			
		||||
    cosw = cos(w);
 | 
			
		||||
 | 
			
		||||
    ixi0 = timesI(xi0);
 | 
			
		||||
    emiu = cos(u) - timesI(sin(u));
 | 
			
		||||
    e2iu = cos(2.0 * u) + timesI(sin(2.0 * u));
 | 
			
		||||
 | 
			
		||||
    h0 = e2iu * (u2 - w2) +
 | 
			
		||||
         emiu * ((8.0 * u2 * cosw) + (2.0 * u * (3.0 * u2 + w2) * ixi0));
 | 
			
		||||
    h1 = e2iu * (2.0 * u) - emiu * ((2.0 * u * cosw) - (3.0 * u2 - w2) * ixi0);
 | 
			
		||||
    h2 = e2iu - emiu * (cosw + (3.0 * u) * ixi0);
 | 
			
		||||
 | 
			
		||||
    fden = unity / (9.0 * u2 - w2);  // reals
 | 
			
		||||
    f0 = h0 * fden;
 | 
			
		||||
    f1 = h1 * fden;
 | 
			
		||||
    f2 = h2 * fden;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  LatticeComplex func_xi0(const LatticeComplex& w) const {
 | 
			
		||||
    // Define a function to do the check
 | 
			
		||||
    // if( w < 1e-4 ) std::cout << GridLogWarning<< "[Smear_stout] w too small:
 | 
			
		||||
    // "<< w <<"\n";
 | 
			
		||||
    return sin(w) / w;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  LatticeComplex func_xi1(const LatticeComplex& w) const {
 | 
			
		||||
    // Define a function to do the check
 | 
			
		||||
    // if( w < 1e-4 ) std::cout << GridLogWarning << "[Smear_stout] w too small:
 | 
			
		||||
    // "<< w <<"\n";
 | 
			
		||||
    return cos(w) / (w * w) - sin(w) / (w * w * w);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -25,7 +25,8 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
    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
 | 
			
		||||
    See the full license in the file "LICENSE" in the top level distribution
 | 
			
		||||
directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
#ifndef QCD_UTILS_WILSON_LOOPS_H
 | 
			
		||||
@@ -34,10 +35,8 @@ namespace Grid {
 | 
			
		||||
namespace QCD {
 | 
			
		||||
 | 
			
		||||
// Common wilson loop observables
 | 
			
		||||
template<class Gimpl>
 | 
			
		||||
class WilsonLoops : public Gimpl {
 | 
			
		||||
template <class Gimpl> class WilsonLoops : public Gimpl {
 | 
			
		||||
public:
 | 
			
		||||
  
 | 
			
		||||
  INHERIT_GIMPL_TYPES(Gimpl);
 | 
			
		||||
 | 
			
		||||
  typedef typename Gimpl::GaugeLinkField GaugeMat;
 | 
			
		||||
@@ -46,21 +45,25 @@ public:
 | 
			
		||||
  //////////////////////////////////////////////////
 | 
			
		||||
  // directed plaquette oriented in mu,nu plane
 | 
			
		||||
  //////////////////////////////////////////////////
 | 
			
		||||
  static void dirPlaquette(GaugeMat &plaq,const std::vector<GaugeMat> &U, const int mu, const int nu)
 | 
			
		||||
  {
 | 
			
		||||
    // Annoyingly, must use either scope resolution to find dependent base class, 
 | 
			
		||||
    // or this-> ; there is no "this" in a static method. This forces explicit Gimpl scope
 | 
			
		||||
    // resolution throughout the usage in this file, and rather defeats the purpose of deriving
 | 
			
		||||
  static void dirPlaquette(GaugeMat &plaq, const std::vector<GaugeMat> &U,
 | 
			
		||||
                           const int mu, const int nu) {
 | 
			
		||||
    // Annoyingly, must use either scope resolution to find dependent base
 | 
			
		||||
    // class,
 | 
			
		||||
    // or this-> ; there is no "this" in a static method. This forces explicit
 | 
			
		||||
    // Gimpl scope
 | 
			
		||||
    // resolution throughout the usage in this file, and rather defeats the
 | 
			
		||||
    // purpose of deriving
 | 
			
		||||
    // from Gimpl.
 | 
			
		||||
    plaq= Gimpl::CovShiftBackward(U[mu],mu,
 | 
			
		||||
	  Gimpl::CovShiftBackward(U[nu],nu,
 | 
			
		||||
          Gimpl::CovShiftForward (U[mu],mu,U[nu])));
 | 
			
		||||
    plaq = Gimpl::CovShiftBackward(
 | 
			
		||||
        U[mu], mu, Gimpl::CovShiftBackward(
 | 
			
		||||
                       U[nu], nu, Gimpl::CovShiftForward(U[mu], mu, U[nu])));
 | 
			
		||||
  }
 | 
			
		||||
  //////////////////////////////////////////////////
 | 
			
		||||
  // trace of directed plaquette oriented in mu,nu plane
 | 
			
		||||
  //////////////////////////////////////////////////
 | 
			
		||||
  static void traceDirPlaquette(LatticeComplex &plaq, const std::vector<GaugeMat> &U, const int mu, const int nu)
 | 
			
		||||
  {
 | 
			
		||||
  static void traceDirPlaquette(LatticeComplex &plaq,
 | 
			
		||||
                                const std::vector<GaugeMat> &U, const int mu,
 | 
			
		||||
                                const int nu) {
 | 
			
		||||
    GaugeMat sp(U[0]._grid);
 | 
			
		||||
    dirPlaquette(sp, U, mu, nu);
 | 
			
		||||
    plaq = trace(sp);
 | 
			
		||||
@@ -68,8 +71,8 @@ public:
 | 
			
		||||
  //////////////////////////////////////////////////
 | 
			
		||||
  // sum over all planes of plaquette
 | 
			
		||||
  //////////////////////////////////////////////////
 | 
			
		||||
  static void sitePlaquette(LatticeComplex &Plaq,const std::vector<GaugeMat> &U)
 | 
			
		||||
  {
 | 
			
		||||
  static void sitePlaquette(LatticeComplex &Plaq,
 | 
			
		||||
                            const std::vector<GaugeMat> &U) {
 | 
			
		||||
    LatticeComplex sitePlaq(U[0]._grid);
 | 
			
		||||
    Plaq = zero;
 | 
			
		||||
    for (int mu = 1; mu < Nd; mu++) {
 | 
			
		||||
@@ -83,7 +86,7 @@ public:
 | 
			
		||||
  // sum over all x,y,z,t and over all planes of plaquette
 | 
			
		||||
  //////////////////////////////////////////////////
 | 
			
		||||
  static RealD sumPlaquette(const GaugeLorentz &Umu) {
 | 
			
		||||
    std::vector<GaugeMat> U(Nd,Umu._grid);
 | 
			
		||||
    std::vector<GaugeMat> U(4, Umu._grid);
 | 
			
		||||
 | 
			
		||||
    for (int mu = 0; mu < Nd; mu++) {
 | 
			
		||||
      U[mu] = PeekIndex<LorentzIndex>(Umu, mu);
 | 
			
		||||
@@ -101,19 +104,20 @@ public:
 | 
			
		||||
  // average over all x,y,z,t and over all planes of plaquette
 | 
			
		||||
  //////////////////////////////////////////////////
 | 
			
		||||
  static RealD avgPlaquette(const GaugeLorentz &Umu) {
 | 
			
		||||
 | 
			
		||||
    RealD sumplaq = sumPlaquette(Umu);
 | 
			
		||||
    
 | 
			
		||||
    double vol = Umu._grid->gSites();
 | 
			
		||||
    
 | 
			
		||||
    double faces = (1.0 * Nd * (Nd - 1)) / 2.0;
 | 
			
		||||
    
 | 
			
		||||
    return sumplaq / vol / faces / Nc; // Nd , Nc dependent... FIXME
 | 
			
		||||
  }
 | 
			
		||||
  static RealD linkTrace(const GaugeLorentz &Umu){
 | 
			
		||||
    std::vector<GaugeMat> U(Nd,Umu._grid);
 | 
			
		||||
 | 
			
		||||
    LatticeComplex Tr(Umu._grid); Tr=zero;
 | 
			
		||||
  //////////////////////////////////////////////////
 | 
			
		||||
  // average over traced single links
 | 
			
		||||
  //////////////////////////////////////////////////
 | 
			
		||||
  static RealD linkTrace(const GaugeLorentz &Umu) {
 | 
			
		||||
    std::vector<GaugeMat> U(4, Umu._grid);
 | 
			
		||||
 | 
			
		||||
    LatticeComplex Tr(Umu._grid);
 | 
			
		||||
    Tr = zero;
 | 
			
		||||
    for (int mu = 0; mu < Nd; mu++) {
 | 
			
		||||
      U[mu] = PeekIndex<LorentzIndex>(Umu, mu);
 | 
			
		||||
      Tr = Tr + trace(U[mu]);
 | 
			
		||||
@@ -124,8 +128,53 @@ public:
 | 
			
		||||
 | 
			
		||||
    double vol = Umu._grid->gSites();
 | 
			
		||||
 | 
			
		||||
    return p.real()/vol/((double)(Nd*(Nd-1)));
 | 
			
		||||
    return p.real() / vol / 4.0 / 3.0;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  //////////////////////////////////////////////////
 | 
			
		||||
  // the sum over all staples on each site in direction mu,nu
 | 
			
		||||
  //////////////////////////////////////////////////
 | 
			
		||||
  static void Staple(GaugeMat &staple, const GaugeLorentz &Umu, int mu,
 | 
			
		||||
                     int nu) {
 | 
			
		||||
 | 
			
		||||
    GridBase *grid = Umu._grid;
 | 
			
		||||
 | 
			
		||||
    std::vector<GaugeMat> U(4, grid);
 | 
			
		||||
    for (int d = 0; d < Nd; d++) {
 | 
			
		||||
      U[d] = PeekIndex<LorentzIndex>(Umu, d);
 | 
			
		||||
    }
 | 
			
		||||
    staple = zero;
 | 
			
		||||
 | 
			
		||||
    if (nu != mu) {
 | 
			
		||||
 | 
			
		||||
      // mu
 | 
			
		||||
      // ^
 | 
			
		||||
      // |__>  nu
 | 
			
		||||
 | 
			
		||||
      //    __
 | 
			
		||||
      //      |
 | 
			
		||||
      //    __|
 | 
			
		||||
      //
 | 
			
		||||
 | 
			
		||||
      staple += Gimpl::ShiftStaple(
 | 
			
		||||
          Gimpl::CovShiftForward(
 | 
			
		||||
              U[nu], nu,
 | 
			
		||||
              Gimpl::CovShiftBackward(
 | 
			
		||||
                  U[mu], mu, Gimpl::CovShiftIdentityBackward(U[nu], nu))),
 | 
			
		||||
          mu);
 | 
			
		||||
 | 
			
		||||
      //  __
 | 
			
		||||
      // |
 | 
			
		||||
      // |__
 | 
			
		||||
      //
 | 
			
		||||
      //
 | 
			
		||||
      staple += Gimpl::ShiftStaple(
 | 
			
		||||
          Gimpl::CovShiftBackward(U[nu], nu,
 | 
			
		||||
                                  Gimpl::CovShiftBackward(U[mu], mu, U[nu])),
 | 
			
		||||
          mu);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //////////////////////////////////////////////////
 | 
			
		||||
  // the sum over all staples on each site
 | 
			
		||||
  //////////////////////////////////////////////////
 | 
			
		||||
@@ -140,7 +189,6 @@ public:
 | 
			
		||||
    staple = zero;
 | 
			
		||||
    GaugeMat tmp(grid);
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    for (int nu = 0; nu < Nd; nu++) {
 | 
			
		||||
 | 
			
		||||
      if (nu != mu) {
 | 
			
		||||
@@ -155,9 +203,11 @@ public:
 | 
			
		||||
        //
 | 
			
		||||
 | 
			
		||||
        staple += Gimpl::ShiftStaple(
 | 
			
		||||
	        Gimpl::CovShiftForward (U[nu],nu, 
 | 
			
		||||
		Gimpl::CovShiftBackward(U[mu],mu,
 | 
			
		||||
		Gimpl::CovShiftIdentityBackward(U[nu],nu))),mu);
 | 
			
		||||
            Gimpl::CovShiftForward(
 | 
			
		||||
                U[nu], nu,
 | 
			
		||||
                Gimpl::CovShiftBackward(
 | 
			
		||||
                    U[mu], mu, Gimpl::CovShiftIdentityBackward(U[nu], nu))),
 | 
			
		||||
            mu);
 | 
			
		||||
 | 
			
		||||
        //  __
 | 
			
		||||
        // |
 | 
			
		||||
@@ -166,30 +216,70 @@ public:
 | 
			
		||||
        //
 | 
			
		||||
        staple += Gimpl::ShiftStaple(
 | 
			
		||||
            Gimpl::CovShiftBackward(U[nu], nu,
 | 
			
		||||
		Gimpl::CovShiftBackward(U[mu],mu,U[nu])),mu);
 | 
			
		||||
                                    Gimpl::CovShiftBackward(U[mu], mu, U[nu])),
 | 
			
		||||
            mu);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //////////////////////////////////////////////////
 | 
			
		||||
  // the sum over all staples on each site in direction mu,nu, upper part
 | 
			
		||||
  //////////////////////////////////////////////////
 | 
			
		||||
  static void StapleUpper(GaugeMat &staple, const GaugeLorentz &Umu, int mu,
 | 
			
		||||
                          int nu) {
 | 
			
		||||
 | 
			
		||||
    staple = zero;
 | 
			
		||||
 | 
			
		||||
    if (nu != mu) {
 | 
			
		||||
      GridBase *grid = Umu._grid;
 | 
			
		||||
 | 
			
		||||
      std::vector<GaugeMat> U(4, grid);
 | 
			
		||||
      for (int d = 0; d < Nd; d++) {
 | 
			
		||||
        U[d] = PeekIndex<LorentzIndex>(Umu, d);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // mu
 | 
			
		||||
      // ^
 | 
			
		||||
      // |__>  nu
 | 
			
		||||
 | 
			
		||||
      //    __
 | 
			
		||||
      //      |
 | 
			
		||||
      //    __|
 | 
			
		||||
      //
 | 
			
		||||
 | 
			
		||||
      staple += Gimpl::ShiftStaple(
 | 
			
		||||
          Gimpl::CovShiftForward(
 | 
			
		||||
              U[nu], nu,
 | 
			
		||||
              Gimpl::CovShiftBackward(
 | 
			
		||||
                  U[mu], mu, Gimpl::CovShiftIdentityBackward(U[nu], nu))),
 | 
			
		||||
          mu);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //////////////////////////////////////////////////////
 | 
			
		||||
  // Similar to above for rectangle is required
 | 
			
		||||
  //////////////////////////////////////////////////////
 | 
			
		||||
  static void dirRectangle(GaugeMat &rect,const std::vector<GaugeMat> &U, const int mu, const int nu)
 | 
			
		||||
  {
 | 
			
		||||
    rect =  Gimpl::CovShiftForward(U[mu],mu,Gimpl::CovShiftForward(U[mu],mu,U[nu]))* // ->->|
 | 
			
		||||
	adj(Gimpl::CovShiftForward(U[nu],nu,Gimpl::CovShiftForward(U[mu],mu,U[mu]))) ;
 | 
			
		||||
  static void dirRectangle(GaugeMat &rect, const std::vector<GaugeMat> &U,
 | 
			
		||||
                           const int mu, const int nu) {
 | 
			
		||||
    rect = Gimpl::CovShiftForward(
 | 
			
		||||
               U[mu], mu, Gimpl::CovShiftForward(U[mu], mu, U[nu])) * // ->->|
 | 
			
		||||
           adj(Gimpl::CovShiftForward(
 | 
			
		||||
               U[nu], nu, Gimpl::CovShiftForward(U[mu], mu, U[mu])));
 | 
			
		||||
    rect = rect +
 | 
			
		||||
          Gimpl::CovShiftForward(U[mu],mu,Gimpl::CovShiftForward(U[nu],nu,U[nu]))* // ->||
 | 
			
		||||
      adj(Gimpl::CovShiftForward(U[nu],nu,Gimpl::CovShiftForward(U[nu],nu,U[mu]))) ;
 | 
			
		||||
           Gimpl::CovShiftForward(
 | 
			
		||||
               U[mu], mu, Gimpl::CovShiftForward(U[nu], nu, U[nu])) * // ->||
 | 
			
		||||
               adj(Gimpl::CovShiftForward(
 | 
			
		||||
                   U[nu], nu, Gimpl::CovShiftForward(U[nu], nu, U[mu])));
 | 
			
		||||
  }
 | 
			
		||||
  static void traceDirRectangle(LatticeComplex &rect, const std::vector<GaugeMat> &U, const int mu, const int nu)
 | 
			
		||||
  {
 | 
			
		||||
  static void traceDirRectangle(LatticeComplex &rect,
 | 
			
		||||
                                const std::vector<GaugeMat> &U, const int mu,
 | 
			
		||||
                                const int nu) {
 | 
			
		||||
    GaugeMat sp(U[0]._grid);
 | 
			
		||||
    dirRectangle(sp, U, mu, nu);
 | 
			
		||||
    rect = trace(sp);
 | 
			
		||||
  }
 | 
			
		||||
  static void siteRectangle(LatticeComplex &Rect,const std::vector<GaugeMat> &U)
 | 
			
		||||
  {
 | 
			
		||||
  static void siteRectangle(LatticeComplex &Rect,
 | 
			
		||||
                            const std::vector<GaugeMat> &U) {
 | 
			
		||||
    LatticeComplex siteRect(U[0]._grid);
 | 
			
		||||
    Rect = zero;
 | 
			
		||||
    for (int mu = 1; mu < Nd; mu++) {
 | 
			
		||||
@@ -199,6 +289,7 @@ public:
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //////////////////////////////////////////////////
 | 
			
		||||
  // sum over all x,y,z,t and over all planes of plaquette
 | 
			
		||||
  //////////////////////////////////////////////////
 | 
			
		||||
@@ -239,11 +330,14 @@ public:
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
  // Hop by two optimisation strategy does not work nicely with Gparity. (could do,
 | 
			
		||||
  // Hop by two optimisation strategy does not work nicely with Gparity. (could
 | 
			
		||||
  // do,
 | 
			
		||||
  // but need to track two deep where cross boundary and apply a conjugation).
 | 
			
		||||
  // Must differentiate this in Gimpl, and use Gimpl::isPeriodicGaugeField to do so .
 | 
			
		||||
  // Must differentiate this in Gimpl, and use Gimpl::isPeriodicGaugeField to do
 | 
			
		||||
  // so .
 | 
			
		||||
  ////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
  static void RectStapleOptimised(GaugeMat &Stap,std::vector<GaugeMat> &U2,std::vector<GaugeMat> &U,int mu){
 | 
			
		||||
  static void RectStapleOptimised(GaugeMat &Stap, std::vector<GaugeMat> &U2,
 | 
			
		||||
                                  std::vector<GaugeMat> &U, int mu) {
 | 
			
		||||
 | 
			
		||||
    Stap = zero;
 | 
			
		||||
 | 
			
		||||
@@ -263,14 +357,12 @@ public:
 | 
			
		||||
 | 
			
		||||
        Staple2x1 = Gimpl::CovShiftForward(U[nu], nu, tmp);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        // Down staple
 | 
			
		||||
        //             |___ ___|
 | 
			
		||||
        //
 | 
			
		||||
        tmp = adj(U2[mu]) * U[nu];
 | 
			
		||||
        Staple2x1 += Gimpl::CovShiftBackward(U[nu], nu, Cshift(tmp, mu, -2));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        //              ___ ___
 | 
			
		||||
        //             |    ___|
 | 
			
		||||
        //             |___ ___|
 | 
			
		||||
@@ -285,7 +377,8 @@ public:
 | 
			
		||||
 | 
			
		||||
        //	tmp= Staple2x1* Cshift(U[mu],mu,-2);
 | 
			
		||||
        //	Stap+= Cshift(tmp,mu,1) ;
 | 
			
		||||
	Stap+= Cshift(Staple2x1,mu,1)*Cshift(U[mu],mu,-1); ;
 | 
			
		||||
        Stap += Cshift(Staple2x1, mu, 1) * Cshift(U[mu], mu, -1);
 | 
			
		||||
        ;
 | 
			
		||||
 | 
			
		||||
        //       --
 | 
			
		||||
        //      |  |
 | 
			
		||||
@@ -306,19 +399,16 @@ public:
 | 
			
		||||
        tmp = adj(U2[nu]) * tmp;
 | 
			
		||||
        tmp = Cshift(tmp, nu, -2);
 | 
			
		||||
        Stap += Cshift(tmp, mu, 1);
 | 
			
		||||
    }}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static void RectStaple(GaugeMat &Stap,const GaugeLorentz & Umu,int mu)
 | 
			
		||||
  {
 | 
			
		||||
  static void RectStaple(GaugeMat &Stap, const GaugeLorentz &Umu, int mu) {
 | 
			
		||||
    RectStapleUnoptimised(Stap, Umu, mu);
 | 
			
		||||
  }
 | 
			
		||||
  static void RectStaple(const GaugeLorentz &Umu, GaugeMat &Stap,
 | 
			
		||||
			 std::vector<GaugeMat> &U2,
 | 
			
		||||
			 std::vector<GaugeMat> &U, int mu)
 | 
			
		||||
  {
 | 
			
		||||
                         std::vector<GaugeMat> &U2, std::vector<GaugeMat> &U,
 | 
			
		||||
                         int mu) {
 | 
			
		||||
    if (Gimpl::isPeriodicGaugeField()) {
 | 
			
		||||
      RectStapleOptimised(Stap, U2, U, mu);
 | 
			
		||||
    } else {
 | 
			
		||||
@@ -326,7 +416,8 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static void RectStapleUnoptimised(GaugeMat &Stap,const GaugeLorentz &Umu,int mu){
 | 
			
		||||
  static void RectStapleUnoptimised(GaugeMat &Stap, const GaugeLorentz &Umu,
 | 
			
		||||
                                    int mu) {
 | 
			
		||||
    GridBase *grid = Umu._grid;
 | 
			
		||||
 | 
			
		||||
    std::vector<GaugeMat> U(Nd, grid);
 | 
			
		||||
@@ -342,38 +433,52 @@ public:
 | 
			
		||||
        //          |    __ |
 | 
			
		||||
        //
 | 
			
		||||
        Stap += Gimpl::ShiftStaple(
 | 
			
		||||
		  Gimpl::CovShiftForward (U[mu],mu,
 | 
			
		||||
		  Gimpl::CovShiftForward (U[nu],nu,
 | 
			
		||||
		  Gimpl::CovShiftBackward(U[mu],mu,
 | 
			
		||||
                  Gimpl::CovShiftBackward(U[mu],mu,
 | 
			
		||||
		  Gimpl::CovShiftIdentityBackward(U[nu],nu))))) , mu);
 | 
			
		||||
            Gimpl::CovShiftForward(
 | 
			
		||||
                U[mu], mu,
 | 
			
		||||
                Gimpl::CovShiftForward(
 | 
			
		||||
                    U[nu], nu,
 | 
			
		||||
                    Gimpl::CovShiftBackward(
 | 
			
		||||
                        U[mu], mu,
 | 
			
		||||
                        Gimpl::CovShiftBackward(
 | 
			
		||||
                            U[mu], mu,
 | 
			
		||||
                            Gimpl::CovShiftIdentityBackward(U[nu], nu))))),
 | 
			
		||||
            mu);
 | 
			
		||||
 | 
			
		||||
        //              __
 | 
			
		||||
        //          |__ __ |
 | 
			
		||||
 | 
			
		||||
        Stap += Gimpl::ShiftStaple(
 | 
			
		||||
                  Gimpl::CovShiftForward (U[mu],mu,
 | 
			
		||||
		  Gimpl::CovShiftBackward(U[nu],nu,
 | 
			
		||||
		  Gimpl::CovShiftBackward(U[mu],mu,
 | 
			
		||||
                  Gimpl::CovShiftBackward(U[mu],mu, U[nu])))) , mu);
 | 
			
		||||
            Gimpl::CovShiftForward(
 | 
			
		||||
                U[mu], mu,
 | 
			
		||||
                Gimpl::CovShiftBackward(
 | 
			
		||||
                    U[nu], nu,
 | 
			
		||||
                    Gimpl::CovShiftBackward(
 | 
			
		||||
                        U[mu], mu, Gimpl::CovShiftBackward(U[mu], mu, U[nu])))),
 | 
			
		||||
            mu);
 | 
			
		||||
 | 
			
		||||
        //           __
 | 
			
		||||
        //          |__ __ |
 | 
			
		||||
 | 
			
		||||
        Stap += Gimpl::ShiftStaple(
 | 
			
		||||
		  Gimpl::CovShiftBackward(U[nu],nu,
 | 
			
		||||
		  Gimpl::CovShiftBackward(U[mu],mu,
 | 
			
		||||
		  Gimpl::CovShiftBackward(U[mu],mu,
 | 
			
		||||
		  Gimpl::CovShiftForward(U[nu],nu,U[mu])))) , mu);
 | 
			
		||||
            Gimpl::CovShiftBackward(
 | 
			
		||||
                U[nu], nu,
 | 
			
		||||
                Gimpl::CovShiftBackward(
 | 
			
		||||
                    U[mu], mu,
 | 
			
		||||
                    Gimpl::CovShiftBackward(
 | 
			
		||||
                        U[mu], mu, Gimpl::CovShiftForward(U[nu], nu, U[mu])))),
 | 
			
		||||
            mu);
 | 
			
		||||
 | 
			
		||||
        //           __ ___
 | 
			
		||||
        //          |__    |
 | 
			
		||||
 | 
			
		||||
        Stap += Gimpl::ShiftStaple(
 | 
			
		||||
		   Gimpl::CovShiftForward (U[nu],nu,
 | 
			
		||||
	           Gimpl::CovShiftBackward(U[mu],mu,
 | 
			
		||||
                   Gimpl::CovShiftBackward(U[mu],mu,
 | 
			
		||||
                   Gimpl::CovShiftBackward(U[nu],nu,U[mu])))) , mu);
 | 
			
		||||
            Gimpl::CovShiftForward(
 | 
			
		||||
                U[nu], nu,
 | 
			
		||||
                Gimpl::CovShiftBackward(
 | 
			
		||||
                    U[mu], mu,
 | 
			
		||||
                    Gimpl::CovShiftBackward(
 | 
			
		||||
                        U[mu], mu, Gimpl::CovShiftBackward(U[nu], nu, U[mu])))),
 | 
			
		||||
            mu);
 | 
			
		||||
 | 
			
		||||
        //       --
 | 
			
		||||
        //      |  |
 | 
			
		||||
@@ -381,12 +486,16 @@ public:
 | 
			
		||||
        //      |  |
 | 
			
		||||
 | 
			
		||||
        Stap += Gimpl::ShiftStaple(
 | 
			
		||||
		   Gimpl::CovShiftForward(U[nu],nu,
 | 
			
		||||
		   Gimpl::CovShiftForward(U[nu],nu,
 | 
			
		||||
                   Gimpl::CovShiftBackward(U[mu],mu,
 | 
			
		||||
                   Gimpl::CovShiftBackward(U[nu],nu,
 | 
			
		||||
		   Gimpl::CovShiftIdentityBackward(U[nu],nu))))) , mu);
 | 
			
		||||
 | 
			
		||||
            Gimpl::CovShiftForward(
 | 
			
		||||
                U[nu], nu,
 | 
			
		||||
                Gimpl::CovShiftForward(
 | 
			
		||||
                    U[nu], nu,
 | 
			
		||||
                    Gimpl::CovShiftBackward(
 | 
			
		||||
                        U[mu], mu,
 | 
			
		||||
                        Gimpl::CovShiftBackward(
 | 
			
		||||
                            U[nu], nu,
 | 
			
		||||
                            Gimpl::CovShiftIdentityBackward(U[nu], nu))))),
 | 
			
		||||
            mu);
 | 
			
		||||
 | 
			
		||||
        //      |  |
 | 
			
		||||
        //
 | 
			
		||||
@@ -394,22 +503,23 @@ public:
 | 
			
		||||
        //       --
 | 
			
		||||
 | 
			
		||||
        Stap += Gimpl::ShiftStaple(
 | 
			
		||||
		   Gimpl::CovShiftBackward(U[nu],nu,
 | 
			
		||||
		   Gimpl::CovShiftBackward(U[nu],nu,
 | 
			
		||||
                   Gimpl::CovShiftBackward(U[mu],mu,
 | 
			
		||||
                   Gimpl::CovShiftForward (U[nu],nu,U[nu])))) , mu);
 | 
			
		||||
    }}
 | 
			
		||||
            Gimpl::CovShiftBackward(
 | 
			
		||||
                U[nu], nu,
 | 
			
		||||
                Gimpl::CovShiftBackward(
 | 
			
		||||
                    U[nu], nu,
 | 
			
		||||
                    Gimpl::CovShiftBackward(
 | 
			
		||||
                        U[mu], mu, Gimpl::CovShiftForward(U[nu], nu, U[nu])))),
 | 
			
		||||
            mu);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef WilsonLoops<PeriodicGimplR> ColourWilsonLoops;
 | 
			
		||||
typedef WilsonLoops<PeriodicGimplR> U1WilsonLoops;
 | 
			
		||||
typedef WilsonLoops<PeriodicGimplR> SU2WilsonLoops;
 | 
			
		||||
typedef WilsonLoops<PeriodicGimplR> SU3WilsonLoops;
 | 
			
		||||
 | 
			
		||||
}}
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -25,7 +25,8 @@ Author: neo <cossu@post.kek.jp>
 | 
			
		||||
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
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution
 | 
			
		||||
directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
//---------------------------------------------------------------------------
 | 
			
		||||
@@ -64,10 +65,12 @@ namespace Grid {
 | 
			
		||||
//////////////////////////////////////
 | 
			
		||||
// To take the floating point type of real/complex type
 | 
			
		||||
//////////////////////////////////////
 | 
			
		||||
  template <typename T> struct RealPart {
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct RealPart {
 | 
			
		||||
  typedef T type;
 | 
			
		||||
};
 | 
			
		||||
  template <typename T> struct RealPart< std::complex<T> >{
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct RealPart<std::complex<T> > {
 | 
			
		||||
  typedef T type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -76,24 +79,36 @@ namespace Grid {
 | 
			
		||||
//////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
// type alias used to simplify the syntax of std::enable_if
 | 
			
		||||
  template <typename T> using Invoke                                  =  typename T::type;
 | 
			
		||||
  template <typename Condition, typename ReturnType> using EnableIf   =  Invoke<std::enable_if<Condition::value, ReturnType> >;
 | 
			
		||||
  template <typename Condition, typename ReturnType> using NotEnableIf=  Invoke<std::enable_if<!Condition::value, ReturnType> >;
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
using Invoke = typename T::type;
 | 
			
		||||
template <typename Condition, typename ReturnType>
 | 
			
		||||
using EnableIf = Invoke<std::enable_if<Condition::value, ReturnType> >;
 | 
			
		||||
template <typename Condition, typename ReturnType>
 | 
			
		||||
using NotEnableIf = Invoke<std::enable_if<!Condition::value, ReturnType> >;
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////
 | 
			
		||||
// Check for complexity with type traits
 | 
			
		||||
  template <typename T>   struct is_complex : public std::false_type {};
 | 
			
		||||
  template <> struct is_complex<std::complex<double> >: public std::true_type {};
 | 
			
		||||
  template <> struct is_complex<std::complex<float> > : public std::true_type {};
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct is_complex : public std::false_type {};
 | 
			
		||||
template <>
 | 
			
		||||
struct is_complex<std::complex<double> > : public std::true_type {};
 | 
			
		||||
template <>
 | 
			
		||||
struct is_complex<std::complex<float> > : public std::true_type {};
 | 
			
		||||
 | 
			
		||||
  template <typename T> using IfReal    = Invoke<std::enable_if<std::is_floating_point<T>::value,int> > ;
 | 
			
		||||
  template <typename T> using IfComplex = Invoke<std::enable_if<is_complex<T>::value,int> > ;
 | 
			
		||||
  template <typename T> using IfInteger = Invoke<std::enable_if<std::is_integral<T>::value,int> > ;
 | 
			
		||||
template <typename T>
 | 
			
		||||
using IfReal = Invoke<std::enable_if<std::is_floating_point<T>::value, int> >;
 | 
			
		||||
template <typename T>
 | 
			
		||||
using IfComplex = Invoke<std::enable_if<is_complex<T>::value, int> >;
 | 
			
		||||
template <typename T>
 | 
			
		||||
using IfInteger = Invoke<std::enable_if<std::is_integral<T>::value, int> >;
 | 
			
		||||
 | 
			
		||||
  template <typename T> using IfNotReal    = Invoke<std::enable_if<!std::is_floating_point<T>::value,int> > ;
 | 
			
		||||
  template <typename T> using IfNotComplex = Invoke<std::enable_if<!is_complex<T>::value,int> > ;
 | 
			
		||||
  template <typename T> using IfNotInteger = Invoke<std::enable_if<!std::is_integral<T>::value,int> > ;
 | 
			
		||||
template <typename T>
 | 
			
		||||
using IfNotReal =
 | 
			
		||||
    Invoke<std::enable_if<!std::is_floating_point<T>::value, int> >;
 | 
			
		||||
template <typename T>
 | 
			
		||||
using IfNotComplex = Invoke<std::enable_if<!is_complex<T>::value, int> >;
 | 
			
		||||
template <typename T>
 | 
			
		||||
using IfNotInteger = Invoke<std::enable_if<!std::is_integral<T>::value, int> >;
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////
 | 
			
		||||
// Define the operation templates functors
 | 
			
		||||
@@ -111,33 +126,36 @@ namespace Grid {
 | 
			
		||||
}
 | 
			
		||||
///////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  @brief Grid_simd class for the SIMD vector type operations
 | 
			
		||||
 */
 | 
			
		||||
template <class Scalar_type, class Vector_type>
 | 
			
		||||
class Grid_simd {
 | 
			
		||||
    
 | 
			
		||||
 public:
 | 
			
		||||
  typedef typename RealPart<Scalar_type>::type Real;
 | 
			
		||||
  typedef Vector_type vector_type;
 | 
			
		||||
  typedef Scalar_type scalar_type;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  typedef union conv_t_union {
 | 
			
		||||
    Vector_type v;
 | 
			
		||||
    Scalar_type s[sizeof(Vector_type) / sizeof(Scalar_type)];
 | 
			
		||||
    conv_t_union(){};
 | 
			
		||||
  } conv_t;
 | 
			
		||||
 | 
			
		||||
   
 | 
			
		||||
  Vector_type v;
 | 
			
		||||
 | 
			
		||||
    static inline int Nsimd(void) { return sizeof(Vector_type)/sizeof(Scalar_type);}
 | 
			
		||||
  static inline int Nsimd(void) {
 | 
			
		||||
    return sizeof(Vector_type) / sizeof(Scalar_type);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    Grid_simd& operator=(const Grid_simd&& rhs){v=rhs.v;return *this;};
 | 
			
		||||
    Grid_simd& operator=(const Grid_simd& rhs){v=rhs.v;return *this;}; //faster than not declaring it and leaving to the compiler
 | 
			
		||||
  Grid_simd &operator=(const Grid_simd &&rhs) {
 | 
			
		||||
    v = rhs.v;
 | 
			
		||||
    return *this;
 | 
			
		||||
  };
 | 
			
		||||
  Grid_simd &operator=(const Grid_simd &rhs) {
 | 
			
		||||
    v = rhs.v;
 | 
			
		||||
    return *this;
 | 
			
		||||
  };  // faster than not declaring it and leaving to the compiler
 | 
			
		||||
  Grid_simd() = default;
 | 
			
		||||
  Grid_simd(const Grid_simd &rhs) : v(rhs.v){};  // compiles in movaps
 | 
			
		||||
  Grid_simd(const Grid_simd &&rhs) : v(rhs.v){};
 | 
			
		||||
@@ -156,31 +174,76 @@ namespace Grid {
 | 
			
		||||
    vsplat(*this, a);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
    Grid_simd(const Real a){
 | 
			
		||||
      vsplat(*this,Scalar_type(a));
 | 
			
		||||
    };
 | 
			
		||||
  Grid_simd(const Real a) { vsplat(*this, Scalar_type(a)); };
 | 
			
		||||
 | 
			
		||||
  ///////////////////////////////////////////////
 | 
			
		||||
  // mac, mult, sub, add, adj
 | 
			
		||||
  ///////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
  // FIXME -- alias this to an inline MAC struct.
 | 
			
		||||
    friend inline void mac (Grid_simd * __restrict__ y,const Grid_simd * __restrict__ a,const Grid_simd *__restrict__ x){ *y = (*a)*(*x)+(*y); };
 | 
			
		||||
  friend inline void mac(Grid_simd *__restrict__ y,
 | 
			
		||||
                         const Grid_simd *__restrict__ a,
 | 
			
		||||
                         const Grid_simd *__restrict__ x) {
 | 
			
		||||
    *y = (*a) * (*x) + (*y);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  friend inline void mult(Grid_simd *__restrict__ y,
 | 
			
		||||
                          const Grid_simd *__restrict__ l,
 | 
			
		||||
                          const Grid_simd *__restrict__ r) {
 | 
			
		||||
    *y = (*l) * (*r);
 | 
			
		||||
  }
 | 
			
		||||
  friend inline void sub(Grid_simd *__restrict__ y,
 | 
			
		||||
                         const Grid_simd *__restrict__ l,
 | 
			
		||||
                         const Grid_simd *__restrict__ r) {
 | 
			
		||||
    *y = (*l) - (*r);
 | 
			
		||||
  }
 | 
			
		||||
  friend inline void add(Grid_simd *__restrict__ y,
 | 
			
		||||
                         const Grid_simd *__restrict__ l,
 | 
			
		||||
                         const Grid_simd *__restrict__ r) {
 | 
			
		||||
    *y = (*l) + (*r);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    friend inline void mult(Grid_simd * __restrict__ y,const Grid_simd * __restrict__ l,const Grid_simd *__restrict__ r){ *y = (*l) * (*r); }
 | 
			
		||||
    friend inline void sub (Grid_simd * __restrict__ y,const Grid_simd * __restrict__ l,const Grid_simd *__restrict__ r){ *y = (*l) - (*r); }
 | 
			
		||||
    friend inline void add (Grid_simd * __restrict__ y,const Grid_simd * __restrict__ l,const Grid_simd *__restrict__ r){ *y = (*l) + (*r); }
 | 
			
		||||
  friend inline void mac(Grid_simd *__restrict__ y,
 | 
			
		||||
                         const Scalar_type *__restrict__ a,
 | 
			
		||||
                         const Grid_simd *__restrict__ x) {
 | 
			
		||||
    *y = (*a) * (*x) + (*y);
 | 
			
		||||
  };
 | 
			
		||||
  friend inline void mult(Grid_simd *__restrict__ y,
 | 
			
		||||
                          const Scalar_type *__restrict__ l,
 | 
			
		||||
                          const Grid_simd *__restrict__ r) {
 | 
			
		||||
    *y = (*l) * (*r);
 | 
			
		||||
  }
 | 
			
		||||
  friend inline void sub(Grid_simd *__restrict__ y,
 | 
			
		||||
                         const Scalar_type *__restrict__ l,
 | 
			
		||||
                         const Grid_simd *__restrict__ r) {
 | 
			
		||||
    *y = (*l) - (*r);
 | 
			
		||||
  }
 | 
			
		||||
  friend inline void add(Grid_simd *__restrict__ y,
 | 
			
		||||
                         const Scalar_type *__restrict__ l,
 | 
			
		||||
                         const Grid_simd *__restrict__ r) {
 | 
			
		||||
    *y = (*l) + (*r);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    friend inline void mac (Grid_simd *__restrict__ y,const Scalar_type *__restrict__ a,const Grid_simd   *__restrict__ x){ *y = (*a)*(*x)+(*y); };
 | 
			
		||||
    friend inline void mult(Grid_simd *__restrict__ y,const Scalar_type *__restrict__ l,const Grid_simd   *__restrict__ r){ *y = (*l) * (*r); }
 | 
			
		||||
    friend inline void sub (Grid_simd *__restrict__ y,const Scalar_type *__restrict__ l,const Grid_simd   *__restrict__ r){ *y = (*l) - (*r); }
 | 
			
		||||
    friend inline void add (Grid_simd *__restrict__ y,const Scalar_type *__restrict__ l,const Grid_simd   *__restrict__ r){ *y = (*l) + (*r); }
 | 
			
		||||
 | 
			
		||||
    friend inline void mac (Grid_simd *__restrict__ y,const Grid_simd   *__restrict__ a,const Scalar_type *__restrict__ x){ *y = (*a)*(*x)+(*y); };
 | 
			
		||||
    friend inline void mult(Grid_simd *__restrict__ y,const Grid_simd   *__restrict__ l,const Scalar_type *__restrict__ r){ *y = (*l) * (*r); }
 | 
			
		||||
    friend inline void sub (Grid_simd *__restrict__ y,const Grid_simd   *__restrict__ l,const Scalar_type *__restrict__ r){ *y = (*l) - (*r); }
 | 
			
		||||
    friend inline void add (Grid_simd *__restrict__ y,const Grid_simd   *__restrict__ l,const Scalar_type *__restrict__ r){ *y = (*l) + (*r); }
 | 
			
		||||
  friend inline void mac(Grid_simd *__restrict__ y,
 | 
			
		||||
                         const Grid_simd *__restrict__ a,
 | 
			
		||||
                         const Scalar_type *__restrict__ x) {
 | 
			
		||||
    *y = (*a) * (*x) + (*y);
 | 
			
		||||
  };
 | 
			
		||||
  friend inline void mult(Grid_simd *__restrict__ y,
 | 
			
		||||
                          const Grid_simd *__restrict__ l,
 | 
			
		||||
                          const Scalar_type *__restrict__ r) {
 | 
			
		||||
    *y = (*l) * (*r);
 | 
			
		||||
  }
 | 
			
		||||
  friend inline void sub(Grid_simd *__restrict__ y,
 | 
			
		||||
                         const Grid_simd *__restrict__ l,
 | 
			
		||||
                         const Scalar_type *__restrict__ r) {
 | 
			
		||||
    *y = (*l) - (*r);
 | 
			
		||||
  }
 | 
			
		||||
  friend inline void add(Grid_simd *__restrict__ y,
 | 
			
		||||
                         const Grid_simd *__restrict__ l,
 | 
			
		||||
                         const Scalar_type *__restrict__ r) {
 | 
			
		||||
    *y = (*l) + (*r);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ////////////////////////////////////////////////////////////////////////
 | 
			
		||||
  // FIXME:  gonna remove these load/store, get, set, prefetch
 | 
			
		||||
@@ -199,16 +262,14 @@ namespace Grid {
 | 
			
		||||
  ///////////////////////
 | 
			
		||||
  // Vprefetch
 | 
			
		||||
  ///////////////////////
 | 
			
		||||
    friend inline void vprefetch(const Grid_simd &v)
 | 
			
		||||
    {
 | 
			
		||||
  friend inline void vprefetch(const Grid_simd &v) {
 | 
			
		||||
    prefetch_HINT_T0((const char *)&v.v);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ///////////////////////
 | 
			
		||||
  // Reduce
 | 
			
		||||
  ///////////////////////
 | 
			
		||||
    friend inline Scalar_type Reduce(const Grid_simd & in)
 | 
			
		||||
    {
 | 
			
		||||
  friend inline Scalar_type Reduce(const Grid_simd &in) {
 | 
			
		||||
    return unary<Scalar_type>(in.v, ReduceSIMD<Scalar_type, Vector_type>());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -255,7 +316,8 @@ namespace Grid {
 | 
			
		||||
  // provides support
 | 
			
		||||
  ///////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
    template<class functor> friend inline Grid_simd SimdApply (const functor &func,const Grid_simd &v) {
 | 
			
		||||
  template <class functor>
 | 
			
		||||
  friend inline Grid_simd SimdApply(const functor &func, const Grid_simd &v) {
 | 
			
		||||
    Grid_simd ret;
 | 
			
		||||
    Grid_simd::conv_t conv;
 | 
			
		||||
 | 
			
		||||
@@ -266,7 +328,10 @@ namespace Grid {
 | 
			
		||||
    ret.v = conv.v;
 | 
			
		||||
    return ret;
 | 
			
		||||
  }
 | 
			
		||||
    template<class functor> friend inline Grid_simd SimdApplyBinop (const functor &func,const Grid_simd &x,const Grid_simd &y) {
 | 
			
		||||
  template <class functor>
 | 
			
		||||
  friend inline Grid_simd SimdApplyBinop(const functor &func,
 | 
			
		||||
                                         const Grid_simd &x,
 | 
			
		||||
                                         const Grid_simd &y) {
 | 
			
		||||
    Grid_simd ret;
 | 
			
		||||
    Grid_simd::conv_t cx;
 | 
			
		||||
    Grid_simd::conv_t cy;
 | 
			
		||||
@@ -297,19 +362,27 @@ namespace Grid {
 | 
			
		||||
  friend inline void permute3(Grid_simd &y, Grid_simd b) {
 | 
			
		||||
    y.v = Optimization::Permute::Permute3(b.v);
 | 
			
		||||
  }
 | 
			
		||||
    friend inline void permute(Grid_simd &y,Grid_simd b,int perm)
 | 
			
		||||
    {
 | 
			
		||||
  friend inline void permute(Grid_simd &y, Grid_simd b, int perm) {
 | 
			
		||||
    if (perm & RotateBit) {
 | 
			
		||||
      int dist = perm & 0xF;
 | 
			
		||||
      y = rotate(b, dist);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    switch (perm) {
 | 
			
		||||
      case 3: permute3(y,b); break;
 | 
			
		||||
      case 2: permute2(y,b); break;
 | 
			
		||||
      case 1: permute1(y,b); break;
 | 
			
		||||
      case 0: permute0(y,b); break;
 | 
			
		||||
      default: assert(0);
 | 
			
		||||
      case 3:
 | 
			
		||||
        permute3(y, b);
 | 
			
		||||
        break;
 | 
			
		||||
      case 2:
 | 
			
		||||
        permute2(y, b);
 | 
			
		||||
        break;
 | 
			
		||||
      case 1:
 | 
			
		||||
        permute1(y, b);
 | 
			
		||||
        break;
 | 
			
		||||
      case 0:
 | 
			
		||||
        permute0(y, b);
 | 
			
		||||
        break;
 | 
			
		||||
      default:
 | 
			
		||||
        assert(0);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -319,8 +392,7 @@ namespace Grid {
 | 
			
		||||
// General rotate
 | 
			
		||||
////////////////////////////////////////////////////////////////////
 | 
			
		||||
template <class S, class V, IfNotComplex<S> = 0>
 | 
			
		||||
  inline Grid_simd<S,V> rotate(Grid_simd<S,V> b,int nrot)
 | 
			
		||||
  {
 | 
			
		||||
inline Grid_simd<S, V> rotate(Grid_simd<S, V> b, int nrot) {
 | 
			
		||||
  nrot = nrot % Grid_simd<S, V>::Nsimd();
 | 
			
		||||
  Grid_simd<S, V> ret;
 | 
			
		||||
  //    std::cout << "Rotate Real by "<<nrot<<std::endl;
 | 
			
		||||
@@ -328,8 +400,7 @@ namespace Grid {
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
template <class S, class V, IfComplex<S> = 0>
 | 
			
		||||
  inline Grid_simd<S,V> rotate(Grid_simd<S,V> b,int nrot)
 | 
			
		||||
  {
 | 
			
		||||
inline Grid_simd<S, V> rotate(Grid_simd<S, V> b, int nrot) {
 | 
			
		||||
  nrot = nrot % Grid_simd<S, V>::Nsimd();
 | 
			
		||||
  Grid_simd<S, V> ret;
 | 
			
		||||
  //    std::cout << "Rotate Complex by "<<nrot<<std::endl;
 | 
			
		||||
@@ -348,11 +419,13 @@ namespace Grid {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// overload if complex
 | 
			
		||||
  template <class S,class V> inline void vsplat(Grid_simd<S,V> &ret, EnableIf<is_complex < S >, S> c) {
 | 
			
		||||
template <class S, class V>
 | 
			
		||||
inline void vsplat(Grid_simd<S, V> &ret, EnableIf<is_complex<S>, S> c) {
 | 
			
		||||
  vsplat(ret, real(c), imag(c));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  //if real fill with a, if complex fill with a in the real part (first function above)
 | 
			
		||||
// if real fill with a, if complex fill with a in the real part (first function
 | 
			
		||||
// above)
 | 
			
		||||
template <class S, class V>
 | 
			
		||||
inline void vsplat(Grid_simd<S, V> &ret, NotEnableIf<is_complex<S>, S> a) {
 | 
			
		||||
  ret.v = unary<V>(a, VsplatSIMD());
 | 
			
		||||
@@ -363,24 +436,60 @@ namespace Grid {
 | 
			
		||||
// Initialise to 1,0,i for the correct types
 | 
			
		||||
///////////////////////////////////////////////
 | 
			
		||||
// For complex types
 | 
			
		||||
  template <class S,class V, IfComplex<S> = 0 > inline void vone(Grid_simd<S,V>  &ret)     { vsplat(ret,S(1.0,0.0)); }
 | 
			
		||||
  template <class S,class V, IfComplex<S> = 0 > inline void vzero(Grid_simd<S,V> &ret)     { vsplat(ret,S(0.0,0.0)); }// use xor?
 | 
			
		||||
  template <class S,class V, IfComplex<S> = 0 > inline void vcomplex_i(Grid_simd<S,V> &ret){ vsplat(ret,S(0.0,1.0));} 
 | 
			
		||||
template <class S, class V, IfComplex<S> = 0>
 | 
			
		||||
inline void vone(Grid_simd<S, V> &ret) {
 | 
			
		||||
  vsplat(ret, S(1.0, 0.0));
 | 
			
		||||
}
 | 
			
		||||
template <class S, class V, IfComplex<S> = 0>
 | 
			
		||||
inline void vzero(Grid_simd<S, V> &ret) {
 | 
			
		||||
  vsplat(ret, S(0.0, 0.0));
 | 
			
		||||
}  // use xor?
 | 
			
		||||
template <class S, class V, IfComplex<S> = 0>
 | 
			
		||||
inline void vcomplex_i(Grid_simd<S, V> &ret) {
 | 
			
		||||
  vsplat(ret, S(0.0, 1.0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  template <class S,class V, IfComplex<S> = 0 > inline void visign(Grid_simd<S,V> &ret){ vsplat(ret,S(1.0,-1.0));} 
 | 
			
		||||
  template <class S,class V, IfComplex<S> = 0 > inline void vrsign(Grid_simd<S,V> &ret){ vsplat(ret,S(-1.0,1.0));} 
 | 
			
		||||
template <class S, class V, IfComplex<S> = 0>
 | 
			
		||||
inline void visign(Grid_simd<S, V> &ret) {
 | 
			
		||||
  vsplat(ret, S(1.0, -1.0));
 | 
			
		||||
}
 | 
			
		||||
template <class S, class V, IfComplex<S> = 0>
 | 
			
		||||
inline void vrsign(Grid_simd<S, V> &ret) {
 | 
			
		||||
  vsplat(ret, S(-1.0, 1.0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// if not complex overload here
 | 
			
		||||
  template <class S,class V, IfReal<S> = 0 > inline void vone (Grid_simd<S,V> &ret){ vsplat(ret,S(1.0)); }
 | 
			
		||||
  template <class S,class V, IfReal<S> = 0 > inline void vzero(Grid_simd<S,V> &ret){ vsplat(ret,S(0.0)); }
 | 
			
		||||
template <class S, class V, IfReal<S> = 0>
 | 
			
		||||
inline void vone(Grid_simd<S, V> &ret) {
 | 
			
		||||
  vsplat(ret, S(1.0));
 | 
			
		||||
}
 | 
			
		||||
template <class S, class V, IfReal<S> = 0>
 | 
			
		||||
inline void vzero(Grid_simd<S, V> &ret) {
 | 
			
		||||
  vsplat(ret, S(0.0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// For integral types
 | 
			
		||||
  template <class S,class V,IfInteger<S> = 0 > inline void vone(Grid_simd<S,V> &ret)  {vsplat(ret,1); }
 | 
			
		||||
  template <class S,class V,IfInteger<S> = 0 > inline void vzero(Grid_simd<S,V> &ret) {vsplat(ret,0); }
 | 
			
		||||
  template <class S,class V,IfInteger<S> = 0 > inline void vtrue (Grid_simd<S,V> &ret){vsplat(ret,0xFFFFFFFF);}
 | 
			
		||||
  template <class S,class V,IfInteger<S> = 0 > inline void vfalse(Grid_simd<S,V> &ret){vsplat(ret,0);}
 | 
			
		||||
template <class S, class V, IfInteger<S> = 0>
 | 
			
		||||
inline void vone(Grid_simd<S, V> &ret) {
 | 
			
		||||
  vsplat(ret, 1);
 | 
			
		||||
}
 | 
			
		||||
template <class S, class V, IfInteger<S> = 0>
 | 
			
		||||
inline void vzero(Grid_simd<S, V> &ret) {
 | 
			
		||||
  vsplat(ret, 0);
 | 
			
		||||
}
 | 
			
		||||
template <class S, class V, IfInteger<S> = 0>
 | 
			
		||||
inline void vtrue(Grid_simd<S, V> &ret) {
 | 
			
		||||
  vsplat(ret, 0xFFFFFFFF);
 | 
			
		||||
}
 | 
			
		||||
template <class S, class V, IfInteger<S> = 0>
 | 
			
		||||
inline void vfalse(Grid_simd<S, V> &ret) {
 | 
			
		||||
  vsplat(ret, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  template<class S,class V> inline void zeroit(Grid_simd<S,V> &z){ vzero(z);}
 | 
			
		||||
template <class S, class V>
 | 
			
		||||
inline void zeroit(Grid_simd<S, V> &z) {
 | 
			
		||||
  vzero(z);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///////////////////////
 | 
			
		||||
// Vstream
 | 
			
		||||
@@ -403,33 +512,36 @@ namespace Grid {
 | 
			
		||||
////////////////////////////////////
 | 
			
		||||
// Arithmetic operator overloads +,-,*
 | 
			
		||||
////////////////////////////////////
 | 
			
		||||
  template<class S,class V> inline Grid_simd<S,V> operator + (Grid_simd<S,V> a, Grid_simd<S,V> b) {
 | 
			
		||||
template <class S, class V>
 | 
			
		||||
inline Grid_simd<S, V> operator+(Grid_simd<S, V> a, Grid_simd<S, V> b) {
 | 
			
		||||
  Grid_simd<S, V> ret;
 | 
			
		||||
  ret.v = binary<V>(a.v, b.v, SumSIMD());
 | 
			
		||||
  return ret;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
  template<class S,class V> inline Grid_simd<S,V> operator - (Grid_simd<S,V> a, Grid_simd<S,V> b) {
 | 
			
		||||
template <class S, class V>
 | 
			
		||||
inline Grid_simd<S, V> operator-(Grid_simd<S, V> a, Grid_simd<S, V> b) {
 | 
			
		||||
  Grid_simd<S, V> ret;
 | 
			
		||||
  ret.v = binary<V>(a.v, b.v, SubSIMD());
 | 
			
		||||
  return ret;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Distinguish between complex types and others
 | 
			
		||||
  template<class S,class V, IfComplex<S> = 0 > inline Grid_simd<S,V> operator * (Grid_simd<S,V> a, Grid_simd<S,V> b) {
 | 
			
		||||
template <class S, class V, IfComplex<S> = 0>
 | 
			
		||||
inline Grid_simd<S, V> operator*(Grid_simd<S, V> a, Grid_simd<S, V> b) {
 | 
			
		||||
  Grid_simd<S, V> ret;
 | 
			
		||||
  ret.v = binary<V>(a.v, b.v, MultComplexSIMD());
 | 
			
		||||
  return ret;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Real/Integer types
 | 
			
		||||
  template<class S,class V, IfNotComplex<S> = 0 > inline Grid_simd<S,V> operator * (Grid_simd<S,V> a, Grid_simd<S,V> b) {
 | 
			
		||||
template <class S, class V, IfNotComplex<S> = 0>
 | 
			
		||||
inline Grid_simd<S, V> operator*(Grid_simd<S, V> a, Grid_simd<S, V> b) {
 | 
			
		||||
  Grid_simd<S, V> ret;
 | 
			
		||||
  ret.v = binary<V>(a.v, b.v, MultSIMD());
 | 
			
		||||
  return ret;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
///////////////////////
 | 
			
		||||
// Conjugate
 | 
			
		||||
///////////////////////
 | 
			
		||||
@@ -439,13 +551,16 @@ namespace Grid {
 | 
			
		||||
  ret.v = unary<V>(in.v, ConjSIMD());
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
  template <class S,class V, IfNotComplex<S> = 0 > inline Grid_simd<S,V> conjugate(const Grid_simd<S,V>  &in){
 | 
			
		||||
template <class S, class V, IfNotComplex<S> = 0>
 | 
			
		||||
inline Grid_simd<S, V> conjugate(const Grid_simd<S, V> &in) {
 | 
			
		||||
  return in;  // for real objects
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Suppress adj for integer types... // odd; why conjugate above but not adj??
 | 
			
		||||
template <class S, class V, IfNotInteger<S> = 0>
 | 
			
		||||
    inline Grid_simd<S,V> adj(const Grid_simd<S,V> &in){ return conjugate(in); }
 | 
			
		||||
inline Grid_simd<S, V> adj(const Grid_simd<S, V> &in) {
 | 
			
		||||
  return conjugate(in);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///////////////////////
 | 
			
		||||
// timesMinusI
 | 
			
		||||
@@ -492,14 +607,14 @@ namespace Grid {
 | 
			
		||||
/////////////////////
 | 
			
		||||
 | 
			
		||||
template <class S, class V>
 | 
			
		||||
    inline Grid_simd< S, V>  innerProduct(const Grid_simd< S, V> & l, const Grid_simd< S, V> & r) 
 | 
			
		||||
  {
 | 
			
		||||
inline Grid_simd<S, V> innerProduct(const Grid_simd<S, V> &l,
 | 
			
		||||
                                    const Grid_simd<S, V> &r) {
 | 
			
		||||
  return conjugate(l) * r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class S, class V>
 | 
			
		||||
  inline Grid_simd< S, V> outerProduct(const Grid_simd< S, V> &l, const Grid_simd< S, V> & r)
 | 
			
		||||
  {
 | 
			
		||||
inline Grid_simd<S, V> outerProduct(const Grid_simd<S, V> &l,
 | 
			
		||||
                                    const Grid_simd<S, V> &r) {
 | 
			
		||||
  return l * conjugate(r);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -508,7 +623,6 @@ namespace Grid {
 | 
			
		||||
  return arg;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////
 | 
			
		||||
// copy/splat complex real parts into real;
 | 
			
		||||
// insert real into complex and zero imag;
 | 
			
		||||
@@ -516,12 +630,11 @@ namespace Grid {
 | 
			
		||||
 | 
			
		||||
// real = toReal( complex )
 | 
			
		||||
template <class S, class V, IfReal<S> = 0>
 | 
			
		||||
  inline Grid_simd<S,V> toReal(const Grid_simd<std::complex<S>,V> &in)
 | 
			
		||||
  {
 | 
			
		||||
inline Grid_simd<S, V> toReal(const Grid_simd<std::complex<S>, V> &in) {
 | 
			
		||||
  typedef Grid_simd<S, V> simd;
 | 
			
		||||
  simd ret;
 | 
			
		||||
  typename simd::conv_t conv;
 | 
			
		||||
    conv.v = in.v;
 | 
			
		||||
  conv.v = in.v;  // copy the vector content (bytewise)
 | 
			
		||||
  for (int i = 0; i < simd::Nsimd(); i += 2) {
 | 
			
		||||
    conv.s[i + 1] = conv.s[i];  // duplicate (r,r);(r,r);(r,r); etc...
 | 
			
		||||
  }
 | 
			
		||||
@@ -531,16 +644,17 @@ namespace Grid {
 | 
			
		||||
 | 
			
		||||
// complex = toComplex( real )
 | 
			
		||||
template <class R, class V, IfReal<R> = 0>  // must be a real arg
 | 
			
		||||
  inline Grid_simd<std::complex<R>,V> toComplex (const Grid_simd<R,V> &in)
 | 
			
		||||
  {
 | 
			
		||||
inline Grid_simd<std::complex<R>, V> toComplex(const Grid_simd<R, V> &in) {
 | 
			
		||||
  typedef Grid_simd<R, V> Rsimd;
 | 
			
		||||
  typedef Grid_simd<std::complex<R>, V> Csimd;
 | 
			
		||||
  typename Rsimd::conv_t conv;  // address as real
 | 
			
		||||
 | 
			
		||||
  conv.v = in.v;
 | 
			
		||||
  for (int i = 0; i < Rsimd::Nsimd(); i += 2) {
 | 
			
		||||
      assert(conv.s[i+1]==conv.s[i]); // trap any cases where real was not duplicated 
 | 
			
		||||
      // indicating the SIMD grids of real and imag assignment did not correctly match
 | 
			
		||||
    assert(conv.s[i + 1] ==
 | 
			
		||||
           conv.s[i]);  // trap any cases where real was not duplicated
 | 
			
		||||
    // indicating the SIMD grids of real and imag assignment did not correctly
 | 
			
		||||
    // match
 | 
			
		||||
    conv.s[i + 1] = 0.0;  // zero imaginary parts
 | 
			
		||||
  }
 | 
			
		||||
  Csimd ret;
 | 
			
		||||
@@ -560,16 +674,23 @@ namespace Grid {
 | 
			
		||||
/////////////////////////////////////////
 | 
			
		||||
// Some traits to recognise the types
 | 
			
		||||
/////////////////////////////////////////
 | 
			
		||||
  template <typename T> struct is_simd : public std::false_type{};
 | 
			
		||||
  template <> struct is_simd<vRealF>   : public std::true_type {};
 | 
			
		||||
  template <> struct is_simd<vRealD>   : public std::true_type {};
 | 
			
		||||
  template <> struct is_simd<vComplexF>: public std::true_type {};
 | 
			
		||||
  template <> struct is_simd<vComplexD>: public std::true_type {};
 | 
			
		||||
  template <> struct is_simd<vInteger> : public std::true_type {};
 | 
			
		||||
 | 
			
		||||
  template <typename T> using IfSimd     = Invoke<std::enable_if< is_simd<T>::value,int> > ;
 | 
			
		||||
  template <typename T> using IfNotSimd  = Invoke<std::enable_if<!is_simd<T>::value,unsigned> > ;
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct is_simd : public std::false_type {};
 | 
			
		||||
template <>
 | 
			
		||||
struct is_simd<vRealF> : public std::true_type {};
 | 
			
		||||
template <>
 | 
			
		||||
struct is_simd<vRealD> : public std::true_type {};
 | 
			
		||||
template <>
 | 
			
		||||
struct is_simd<vComplexF> : public std::true_type {};
 | 
			
		||||
template <>
 | 
			
		||||
struct is_simd<vComplexD> : public std::true_type {};
 | 
			
		||||
template <>
 | 
			
		||||
struct is_simd<vInteger> : public std::true_type {};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
using IfSimd = Invoke<std::enable_if<is_simd<T>::value, int> >;
 | 
			
		||||
template <typename T>
 | 
			
		||||
using IfNotSimd = Invoke<std::enable_if<!is_simd<T>::value, unsigned> >;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,8 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
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
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution
 | 
			
		||||
directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
#ifndef GRID_VECTOR_UNOPS
 | 
			
		||||
@@ -35,85 +36,84 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
  template<class scalar> struct SqrtRealFunctor {
 | 
			
		||||
    scalar operator()(const scalar &a) const {
 | 
			
		||||
      return sqrt(real(a));
 | 
			
		||||
    }
 | 
			
		||||
template <class scalar>
 | 
			
		||||
struct SqrtRealFunctor {
 | 
			
		||||
  scalar operator()(const scalar &a) const { return sqrt(real(a)); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
  template<class scalar> struct RSqrtRealFunctor {
 | 
			
		||||
template <class scalar>
 | 
			
		||||
struct RSqrtRealFunctor {
 | 
			
		||||
  scalar operator()(const scalar &a) const {
 | 
			
		||||
    return scalar(1.0 / sqrt(real(a)));
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
  template<class scalar> struct CosRealFunctor {
 | 
			
		||||
    scalar operator()(const scalar &a)  const {
 | 
			
		||||
      return cos(real(a));
 | 
			
		||||
    }
 | 
			
		||||
template <class scalar>
 | 
			
		||||
struct CosRealFunctor {
 | 
			
		||||
  scalar operator()(const scalar &a) const { return cos(real(a)); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
  template<class scalar> struct SinRealFunctor {
 | 
			
		||||
    scalar operator()(const scalar &a)  const {
 | 
			
		||||
      return sin(real(a));
 | 
			
		||||
    }
 | 
			
		||||
template <class scalar>
 | 
			
		||||
struct SinRealFunctor {
 | 
			
		||||
  scalar operator()(const scalar &a) const { return sin(real(a)); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
  template<class scalar> struct LogRealFunctor {
 | 
			
		||||
    scalar operator()(const scalar &a)  const {
 | 
			
		||||
      return log(real(a));
 | 
			
		||||
    }
 | 
			
		||||
template <class scalar>
 | 
			
		||||
struct AcosRealFunctor {
 | 
			
		||||
  scalar operator()(const scalar &a) const { return acos(real(a)); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
  template<class scalar> struct ExpRealFunctor {
 | 
			
		||||
    scalar operator()(const scalar &a)  const {
 | 
			
		||||
      return exp(real(a));
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
  template<class scalar> struct NotFunctor {
 | 
			
		||||
    scalar operator()(const scalar &a)  const {
 | 
			
		||||
      return (!a);
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
  template<class scalar> struct AbsRealFunctor {
 | 
			
		||||
    scalar operator()(const scalar &a)  const {
 | 
			
		||||
      return std::abs(real(a));
 | 
			
		||||
    }
 | 
			
		||||
template <class scalar>
 | 
			
		||||
struct AsinRealFunctor {
 | 
			
		||||
  scalar operator()(const scalar &a) const { return asin(real(a)); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
  template<class scalar> struct PowRealFunctor {
 | 
			
		||||
template <class scalar>
 | 
			
		||||
struct LogRealFunctor {
 | 
			
		||||
  scalar operator()(const scalar &a) const { return log(real(a)); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class scalar>
 | 
			
		||||
struct ExpRealFunctor {
 | 
			
		||||
  scalar operator()(const scalar &a) const { return exp(real(a)); }
 | 
			
		||||
};
 | 
			
		||||
template <class scalar>
 | 
			
		||||
struct NotFunctor {
 | 
			
		||||
  scalar operator()(const scalar &a) const { return (!a); }
 | 
			
		||||
};
 | 
			
		||||
template <class scalar>
 | 
			
		||||
struct AbsRealFunctor {
 | 
			
		||||
  scalar operator()(const scalar &a) const { return std::abs(real(a)); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class scalar>
 | 
			
		||||
struct PowRealFunctor {
 | 
			
		||||
  double y;
 | 
			
		||||
  PowRealFunctor(double _y) : y(_y){};
 | 
			
		||||
    scalar operator()(const scalar &a)  const {
 | 
			
		||||
      return pow(real(a),y);
 | 
			
		||||
    }
 | 
			
		||||
  scalar operator()(const scalar &a) const { return pow(real(a), y); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
  template<class scalar> struct ModIntFunctor {
 | 
			
		||||
template <class scalar>
 | 
			
		||||
struct ModIntFunctor {
 | 
			
		||||
  Integer y;
 | 
			
		||||
  ModIntFunctor(Integer _y) : y(_y){};
 | 
			
		||||
    scalar operator()(const scalar &a)  const {
 | 
			
		||||
      return Integer(a)%y;
 | 
			
		||||
    }
 | 
			
		||||
  scalar operator()(const scalar &a) const { return Integer(a) % y; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
  template<class scalar> struct DivIntFunctor {
 | 
			
		||||
template <class scalar>
 | 
			
		||||
struct DivIntFunctor {
 | 
			
		||||
  Integer y;
 | 
			
		||||
  DivIntFunctor(Integer _y) : y(_y){};
 | 
			
		||||
    scalar operator()(const scalar &a)  const {
 | 
			
		||||
      return Integer(a)/y;
 | 
			
		||||
    }
 | 
			
		||||
  scalar operator()(const scalar &a) const { return Integer(a) / y; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
  template<class scalar> struct RealFunctor {
 | 
			
		||||
    scalar operator()(const scalar &a)  const {
 | 
			
		||||
      return real(a);
 | 
			
		||||
    }
 | 
			
		||||
template <class scalar>
 | 
			
		||||
struct RealFunctor {
 | 
			
		||||
  scalar operator()(const scalar &a) const { return std::real(a); }
 | 
			
		||||
};
 | 
			
		||||
  template<class scalar> struct ImagFunctor {
 | 
			
		||||
    scalar operator()(const scalar &a)  const {
 | 
			
		||||
      return imag(a);
 | 
			
		||||
    }
 | 
			
		||||
template <class scalar>
 | 
			
		||||
struct ImagFunctor {
 | 
			
		||||
  scalar operator()(const scalar &a) const { return std::imag(a); }
 | 
			
		||||
};
 | 
			
		||||
template <class S, class V>
 | 
			
		||||
inline Grid_simd<S, V> real(const Grid_simd<S, V> &r) {
 | 
			
		||||
@@ -123,7 +123,6 @@ namespace Grid {
 | 
			
		||||
inline Grid_simd<S, V> imag(const Grid_simd<S, V> &r) {
 | 
			
		||||
  return SimdApply(ImagFunctor<S>(), r);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class S, class V>
 | 
			
		||||
inline Grid_simd<S, V> sqrt(const Grid_simd<S, V> &r) {
 | 
			
		||||
  return SimdApply(SqrtRealFunctor<S>(), r);
 | 
			
		||||
@@ -146,6 +145,14 @@ namespace Grid {
 | 
			
		||||
  return SimdApply(SinRealFunctor<S>(), r);
 | 
			
		||||
}
 | 
			
		||||
template <class S, class V>
 | 
			
		||||
inline Grid_simd<S, V> acos(const Grid_simd<S, V> &r) {
 | 
			
		||||
  return SimdApply(AcosRealFunctor<S>(), r);
 | 
			
		||||
}
 | 
			
		||||
template <class S, class V>
 | 
			
		||||
inline Grid_simd<S, V> asin(const Grid_simd<S, V> &r) {
 | 
			
		||||
  return SimdApply(AsinRealFunctor<S>(), r);
 | 
			
		||||
}
 | 
			
		||||
template <class S, class V>
 | 
			
		||||
inline Grid_simd<S, V> log(const Grid_simd<S, V> &r) {
 | 
			
		||||
  return SimdApply(LogRealFunctor<S>(), r);
 | 
			
		||||
}
 | 
			
		||||
@@ -177,51 +184,51 @@ namespace Grid {
 | 
			
		||||
// Allows us to assign into **conformable** real vectors from complex
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
//  template < class S, class V >
 | 
			
		||||
  //  inline auto ComplexRemove(const Grid_simd<S,V> &c) -> Grid_simd<Grid_simd<S,V>::Real,V> {
 | 
			
		||||
//  inline auto ComplexRemove(const Grid_simd<S,V> &c) ->
 | 
			
		||||
//  Grid_simd<Grid_simd<S,V>::Real,V> {
 | 
			
		||||
//    Grid_simd<Grid_simd<S,V>::Real,V> ret;
 | 
			
		||||
//    ret.v = c.v;
 | 
			
		||||
//    return ret;
 | 
			
		||||
//  }
 | 
			
		||||
  template<class scalar> struct AndFunctor {
 | 
			
		||||
    scalar operator()(const scalar &x, const scalar &y)  const {
 | 
			
		||||
      return x & y;
 | 
			
		||||
    }
 | 
			
		||||
template <class scalar>
 | 
			
		||||
struct AndFunctor {
 | 
			
		||||
  scalar operator()(const scalar &x, const scalar &y) const { return x & y; }
 | 
			
		||||
};
 | 
			
		||||
  template<class scalar> struct OrFunctor {
 | 
			
		||||
    scalar operator()(const scalar &x, const scalar &y)  const {
 | 
			
		||||
      return x | y;
 | 
			
		||||
    }
 | 
			
		||||
template <class scalar>
 | 
			
		||||
struct OrFunctor {
 | 
			
		||||
  scalar operator()(const scalar &x, const scalar &y) const { return x | y; }
 | 
			
		||||
};
 | 
			
		||||
  template<class scalar> struct AndAndFunctor {
 | 
			
		||||
    scalar operator()(const scalar &x, const scalar &y)  const {
 | 
			
		||||
      return x && y;
 | 
			
		||||
    }
 | 
			
		||||
template <class scalar>
 | 
			
		||||
struct AndAndFunctor {
 | 
			
		||||
  scalar operator()(const scalar &x, const scalar &y) const { return x && y; }
 | 
			
		||||
};
 | 
			
		||||
  template<class scalar> struct OrOrFunctor {
 | 
			
		||||
    scalar operator()(const scalar &x, const scalar &y)  const {
 | 
			
		||||
      return x || y;
 | 
			
		||||
    }
 | 
			
		||||
template <class scalar>
 | 
			
		||||
struct OrOrFunctor {
 | 
			
		||||
  scalar operator()(const scalar &x, const scalar &y) const { return x || y; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
////////////////////////////////
 | 
			
		||||
// Calls to simd binop functors
 | 
			
		||||
////////////////////////////////
 | 
			
		||||
template <class S, class V>
 | 
			
		||||
  inline Grid_simd<S,V> operator &(const Grid_simd<S,V> &x,const Grid_simd<S,V> &y) {
 | 
			
		||||
inline Grid_simd<S, V> operator&(const Grid_simd<S, V> &x,
 | 
			
		||||
                                 const Grid_simd<S, V> &y) {
 | 
			
		||||
  return SimdApplyBinop(AndFunctor<S>(), x, y);
 | 
			
		||||
}
 | 
			
		||||
template <class S, class V>
 | 
			
		||||
  inline Grid_simd<S,V> operator &&(const Grid_simd<S,V> &x,const Grid_simd<S,V> &y) {
 | 
			
		||||
inline Grid_simd<S, V> operator&&(const Grid_simd<S, V> &x,
 | 
			
		||||
                                  const Grid_simd<S, V> &y) {
 | 
			
		||||
  return SimdApplyBinop(AndAndFunctor<S>(), x, y);
 | 
			
		||||
}
 | 
			
		||||
template <class S, class V>
 | 
			
		||||
  inline Grid_simd<S,V> operator |(const Grid_simd<S,V> &x,const Grid_simd<S,V> &y) {
 | 
			
		||||
inline Grid_simd<S, V> operator|(const Grid_simd<S, V> &x,
 | 
			
		||||
                                 const Grid_simd<S, V> &y) {
 | 
			
		||||
  return SimdApplyBinop(OrFunctor<S>(), x, y);
 | 
			
		||||
}
 | 
			
		||||
template <class S, class V>
 | 
			
		||||
  inline Grid_simd<S,V> operator ||(const Grid_simd<S,V> &x,const Grid_simd<S,V> &y) {
 | 
			
		||||
inline Grid_simd<S, V> operator||(const Grid_simd<S, V> &x,
 | 
			
		||||
                                  const Grid_simd<S, V> &y) {
 | 
			
		||||
  return SimdApplyBinop(OrOrFunctor<S>(), x, y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,8 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
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
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution
 | 
			
		||||
directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
#ifndef GRID_MATH_TENSORS_H
 | 
			
		||||
@@ -38,7 +39,8 @@ namespace Grid {
 | 
			
		||||
 | 
			
		||||
// It is useful to NOT have any constructors
 | 
			
		||||
// so that these classes assert "is_pod<class> == true"
 | 
			
		||||
// because then the standard C++ valarray container eliminates fill overhead on new allocation and 
 | 
			
		||||
// because then the standard C++ valarray container eliminates fill overhead on
 | 
			
		||||
// new allocation and
 | 
			
		||||
// non-move copying.
 | 
			
		||||
//
 | 
			
		||||
// However note that doing this eliminates some syntactical sugar such as
 | 
			
		||||
@@ -46,8 +48,8 @@ namespace Grid {
 | 
			
		||||
//
 | 
			
		||||
class GridTensorBase {};
 | 
			
		||||
 | 
			
		||||
template<class vtype> class iScalar 
 | 
			
		||||
{
 | 
			
		||||
template <class vtype>
 | 
			
		||||
class iScalar {
 | 
			
		||||
 public:
 | 
			
		||||
  vtype _internal;
 | 
			
		||||
 | 
			
		||||
@@ -66,7 +68,8 @@ public:
 | 
			
		||||
  enum { TensorLevel = GridTypeMapper<vtype>::TensorLevel + 1 };
 | 
			
		||||
 | 
			
		||||
  // Scalar no action
 | 
			
		||||
  //  template<int Level> using tensor_reduce_level = typename iScalar<GridTypeMapper<vtype>::tensor_reduce_level<Level> >;
 | 
			
		||||
  //  template<int Level> using tensor_reduce_level = typename
 | 
			
		||||
  //  iScalar<GridTypeMapper<vtype>::tensor_reduce_level<Level> >;
 | 
			
		||||
  iScalar() = default;
 | 
			
		||||
  /*
 | 
			
		||||
  iScalar(const iScalar<vtype> ©me)=default;
 | 
			
		||||
@@ -74,14 +77,16 @@ public:
 | 
			
		||||
  iScalar<vtype> & operator= (const iScalar<vtype> ©me) = default;
 | 
			
		||||
  iScalar<vtype> & operator= (iScalar<vtype> &©me) = default;
 | 
			
		||||
  */
 | 
			
		||||
  iScalar(scalar_type s) : _internal(s) {};// recurse down and hit the constructor for vector_type
 | 
			
		||||
  iScalar(scalar_type s)
 | 
			
		||||
      : _internal(s){};  // recurse down and hit the constructor for vector_type
 | 
			
		||||
  iScalar(const Zero &z) { *this = zero; };
 | 
			
		||||
 | 
			
		||||
  iScalar<vtype> &operator=(const Zero &hero) {
 | 
			
		||||
    zeroit(*this);
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
  friend strong_inline void vstream(iScalar<vtype> &out,const iScalar<vtype> &in){
 | 
			
		||||
  friend strong_inline void vstream(iScalar<vtype> &out,
 | 
			
		||||
                                    const iScalar<vtype> &in) {
 | 
			
		||||
    vstream(out._internal, in._internal);
 | 
			
		||||
  }
 | 
			
		||||
  friend strong_inline void zeroit(iScalar<vtype> &that) {
 | 
			
		||||
@@ -90,7 +95,8 @@ public:
 | 
			
		||||
  friend strong_inline void prefetch(iScalar<vtype> &that) {
 | 
			
		||||
    prefetch(that._internal);
 | 
			
		||||
  }
 | 
			
		||||
  friend strong_inline void permute(iScalar<vtype> &out,const iScalar<vtype> &in,int permutetype){
 | 
			
		||||
  friend strong_inline void permute(iScalar<vtype> &out,
 | 
			
		||||
                                    const iScalar<vtype> &in, int permutetype) {
 | 
			
		||||
    permute(out._internal, in._internal, permutetype);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -113,28 +119,43 @@ public:
 | 
			
		||||
    *this = (*this) + r;
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
  strong_inline vtype & operator ()(void) {
 | 
			
		||||
    return _internal;
 | 
			
		||||
  }
 | 
			
		||||
  strong_inline const vtype & operator ()(void) const {
 | 
			
		||||
    return _internal;
 | 
			
		||||
  }
 | 
			
		||||
  strong_inline vtype &operator()(void) { return _internal; }
 | 
			
		||||
  strong_inline const vtype &operator()(void) const { return _internal; }
 | 
			
		||||
 | 
			
		||||
  // Type casts meta programmed, must be pure scalar to match TensorRemove
 | 
			
		||||
  template<class U=vtype,class V=scalar_type,IfComplex<V> = 0,IfNotSimd<U> = 0> operator ComplexF () const { return(TensorRemove(_internal)); };
 | 
			
		||||
  template<class U=vtype,class V=scalar_type,IfComplex<V> = 0,IfNotSimd<U> = 0> operator ComplexD () const { return(TensorRemove(_internal)); };
 | 
			
		||||
  //  template<class U=vtype,class V=scalar_type,IfComplex<V> = 0,IfNotSimd<U> = 0> operator RealD    () const { return(real(TensorRemove(_internal))); }
 | 
			
		||||
  template<class U=vtype,class V=scalar_type,IfReal<V>    = 0,IfNotSimd<U> = 0> operator RealD    () const { return TensorRemove(_internal); }
 | 
			
		||||
  template<class U=vtype,class V=scalar_type,IfInteger<V> = 0,IfNotSimd<U> = 0> operator Integer  () const { return Integer(TensorRemove(_internal)); }
 | 
			
		||||
  template <class U = vtype, class V = scalar_type, IfComplex<V> = 0,
 | 
			
		||||
            IfNotSimd<U> = 0>
 | 
			
		||||
  operator ComplexF() const {
 | 
			
		||||
    return (TensorRemove(_internal));
 | 
			
		||||
  };
 | 
			
		||||
  template <class U = vtype, class V = scalar_type, IfComplex<V> = 0,
 | 
			
		||||
            IfNotSimd<U> = 0>
 | 
			
		||||
  operator ComplexD() const {
 | 
			
		||||
    return (TensorRemove(_internal));
 | 
			
		||||
  };
 | 
			
		||||
  //  template<class U=vtype,class V=scalar_type,IfComplex<V> = 0,IfNotSimd<U> =
 | 
			
		||||
  //  0> operator RealD    () const { return(real(TensorRemove(_internal))); }
 | 
			
		||||
  template <class U = vtype, class V = scalar_type, IfReal<V> = 0,
 | 
			
		||||
            IfNotSimd<U> = 0>
 | 
			
		||||
  operator RealD() const {
 | 
			
		||||
    return TensorRemove(_internal);
 | 
			
		||||
  }
 | 
			
		||||
  template <class U = vtype, class V = scalar_type, IfInteger<V> = 0,
 | 
			
		||||
            IfNotSimd<U> = 0>
 | 
			
		||||
  operator Integer() const {
 | 
			
		||||
    return Integer(TensorRemove(_internal));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // convert from a something to a scalar via constructor of something arg
 | 
			
		||||
  template<class T,typename std::enable_if<!isGridTensor<T>::value, T>::type* = nullptr > strong_inline iScalar<vtype> operator = (T arg)
 | 
			
		||||
    { 
 | 
			
		||||
  template <class T, typename std::enable_if<!isGridTensor<T>::value, T>::type
 | 
			
		||||
                         * = nullptr>
 | 
			
		||||
  strong_inline iScalar<vtype> operator=(T arg) {
 | 
			
		||||
    _internal = arg;
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    friend std::ostream& operator<< (std::ostream& stream, const iScalar<vtype> &o){
 | 
			
		||||
  friend std::ostream &operator<<(std::ostream &stream,
 | 
			
		||||
                                  const iScalar<vtype> &o) {
 | 
			
		||||
    stream << "S {" << o._internal << "}";
 | 
			
		||||
    return stream;
 | 
			
		||||
  };
 | 
			
		||||
@@ -142,14 +163,19 @@ public:
 | 
			
		||||
///////////////////////////////////////////////////////////
 | 
			
		||||
// Allows to turn scalar<scalar<scalar<double>>>> back to double.
 | 
			
		||||
///////////////////////////////////////////////////////////
 | 
			
		||||
template<class T>     strong_inline typename std::enable_if<!isGridTensor<T>::value, T>::type TensorRemove(T arg) { return arg;}
 | 
			
		||||
template<class vtype> strong_inline auto TensorRemove(iScalar<vtype> arg) -> decltype(TensorRemove(arg._internal))
 | 
			
		||||
{
 | 
			
		||||
template <class T>
 | 
			
		||||
strong_inline typename std::enable_if<!isGridTensor<T>::value, T>::type
 | 
			
		||||
TensorRemove(T arg) {
 | 
			
		||||
  return arg;
 | 
			
		||||
}
 | 
			
		||||
template <class vtype>
 | 
			
		||||
strong_inline auto TensorRemove(iScalar<vtype> arg)
 | 
			
		||||
    -> decltype(TensorRemove(arg._internal)) {
 | 
			
		||||
  return TensorRemove(arg._internal);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class vtype,int N> class iVector 
 | 
			
		||||
{
 | 
			
		||||
template <class vtype, int N>
 | 
			
		||||
class iVector {
 | 
			
		||||
 public:
 | 
			
		||||
  vtype _internal[N];
 | 
			
		||||
 | 
			
		||||
@@ -165,11 +191,11 @@ public:
 | 
			
		||||
  typedef iVector<typename GridTypeMapper<vtype>::Complexified, N> Complexified;
 | 
			
		||||
  typedef iVector<typename GridTypeMapper<vtype>::Realified, N> Realified;
 | 
			
		||||
 | 
			
		||||
  template<class T,typename std::enable_if<!isGridTensor<T>::value, T>::type* = nullptr > strong_inline auto operator = (T arg) -> iVector<vtype,N>
 | 
			
		||||
    { 
 | 
			
		||||
  template <class T, typename std::enable_if<!isGridTensor<T>::value, T>::type
 | 
			
		||||
                         * = nullptr>
 | 
			
		||||
  strong_inline auto operator=(T arg) -> iVector<vtype, N> {
 | 
			
		||||
    zeroit(*this);
 | 
			
		||||
      for(int i=0;i<N;i++)
 | 
			
		||||
	_internal[i] = arg;
 | 
			
		||||
    for (int i = 0; i < N; i++) _internal[i] = arg;
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -195,12 +221,15 @@ public:
 | 
			
		||||
  friend strong_inline void prefetch(iVector<vtype, N> &that) {
 | 
			
		||||
    for (int i = 0; i < N; i++) prefetch(that._internal[i]);
 | 
			
		||||
  }
 | 
			
		||||
  friend strong_inline void vstream(iVector<vtype,N> &out,const iVector<vtype,N> &in){
 | 
			
		||||
  friend strong_inline void vstream(iVector<vtype, N> &out,
 | 
			
		||||
                                    const iVector<vtype, N> &in) {
 | 
			
		||||
    for (int i = 0; i < N; i++) {
 | 
			
		||||
      vstream(out._internal[i], in._internal[i]);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  friend strong_inline void permute(iVector<vtype,N> &out,const iVector<vtype,N> &in,int permutetype){
 | 
			
		||||
  friend strong_inline void permute(iVector<vtype, N> &out,
 | 
			
		||||
                                    const iVector<vtype, N> &in,
 | 
			
		||||
                                    int permutetype) {
 | 
			
		||||
    for (int i = 0; i < N; i++) {
 | 
			
		||||
      permute(out._internal[i], in._internal[i], permutetype);
 | 
			
		||||
    }
 | 
			
		||||
@@ -225,13 +254,10 @@ public:
 | 
			
		||||
    *this = (*this) + r;
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
  strong_inline vtype & operator ()(int i) {
 | 
			
		||||
    return _internal[i];
 | 
			
		||||
  }
 | 
			
		||||
  strong_inline const vtype & operator ()(int i) const {
 | 
			
		||||
    return _internal[i];
 | 
			
		||||
  }
 | 
			
		||||
  friend std::ostream& operator<< (std::ostream& stream, const iVector<vtype,N> &o){
 | 
			
		||||
  strong_inline vtype &operator()(int i) { return _internal[i]; }
 | 
			
		||||
  strong_inline const vtype &operator()(int i) const { return _internal[i]; }
 | 
			
		||||
  friend std::ostream &operator<<(std::ostream &stream,
 | 
			
		||||
                                  const iVector<vtype, N> &o) {
 | 
			
		||||
    stream << "V<" << N << ">{";
 | 
			
		||||
    for (int i = 0; i < N; i++) {
 | 
			
		||||
      stream << o._internal[i];
 | 
			
		||||
@@ -245,8 +271,8 @@ public:
 | 
			
		||||
  //    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class vtype,int N> class iMatrix 
 | 
			
		||||
{
 | 
			
		||||
template <class vtype, int N>
 | 
			
		||||
class iMatrix {
 | 
			
		||||
 public:
 | 
			
		||||
  vtype _internal[N][N];
 | 
			
		||||
 | 
			
		||||
@@ -266,20 +292,18 @@ public:
 | 
			
		||||
 | 
			
		||||
  enum { TensorLevel = GridTypeMapper<vtype>::TensorLevel + 1 };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  iMatrix(const Zero &z) { *this = zero; };
 | 
			
		||||
  iMatrix() = default;
 | 
			
		||||
 | 
			
		||||
  iMatrix &operator=(const iMatrix &rhs) {
 | 
			
		||||
    for (int i = 0; i < N; i++)
 | 
			
		||||
      for(int j=0;j<N;j++)
 | 
			
		||||
	vstream(_internal[i][j],rhs._internal[i][j]);
 | 
			
		||||
      for (int j = 0; j < N; j++) vstream(_internal[i][j], rhs._internal[i][j]);
 | 
			
		||||
    return *this;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
  iMatrix(scalar_type s)  { (*this) = s ;};// recurse down and hit the constructor for vector_type
 | 
			
		||||
  iMatrix(scalar_type s) {
 | 
			
		||||
    (*this) = s;
 | 
			
		||||
  };  // recurse down and hit the constructor for vector_type
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
  iMatrix(const iMatrix<vtype,N> ©me)=default;
 | 
			
		||||
@@ -288,17 +312,15 @@ public:
 | 
			
		||||
  iMatrix<vtype,N> & operator= (iMatrix<vtype,N> &©me) = default;
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  iMatrix<vtype, N> &operator=(const Zero &hero) {
 | 
			
		||||
    zeroit(*this);
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
  template<class T,typename std::enable_if<!isGridTensor<T>::value, T>::type* = nullptr > strong_inline auto operator = (T arg) -> iMatrix<vtype,N>
 | 
			
		||||
    { 
 | 
			
		||||
  template <class T, typename std::enable_if<!isGridTensor<T>::value, T>::type
 | 
			
		||||
                         * = nullptr>
 | 
			
		||||
  strong_inline auto operator=(T arg) -> iMatrix<vtype, N> {
 | 
			
		||||
    zeroit(*this);
 | 
			
		||||
      for(int i=0;i<N;i++)
 | 
			
		||||
	_internal[i][i] = arg;
 | 
			
		||||
    for (int i = 0; i < N; i++) _internal[i][i] = arg;
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -306,27 +328,31 @@ public:
 | 
			
		||||
    for (int i = 0; i < N; i++) {
 | 
			
		||||
      for (int j = 0; j < N; j++) {
 | 
			
		||||
        zeroit(that._internal[i][j]);
 | 
			
		||||
    }}
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  friend strong_inline void prefetch(iMatrix<vtype, N> &that) {
 | 
			
		||||
    for (int i = 0; i < N; i++)
 | 
			
		||||
    for(int j=0;j<N;j++) 
 | 
			
		||||
      prefetch(that._internal[i][j]);
 | 
			
		||||
      for (int j = 0; j < N; j++) prefetch(that._internal[i][j]);
 | 
			
		||||
  }
 | 
			
		||||
  friend strong_inline void vstream(iMatrix<vtype,N> &out,const iMatrix<vtype,N> &in){
 | 
			
		||||
  friend strong_inline void vstream(iMatrix<vtype, N> &out,
 | 
			
		||||
                                    const iMatrix<vtype, N> &in) {
 | 
			
		||||
    for (int i = 0; i < N; i++) {
 | 
			
		||||
      for (int j = 0; j < N; j++) {
 | 
			
		||||
        vstream(out._internal[i][j], in._internal[i][j]);
 | 
			
		||||
      }}
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  friend strong_inline void permute(iMatrix<vtype,N> &out,const iMatrix<vtype,N> &in,int permutetype){
 | 
			
		||||
  friend strong_inline void permute(iMatrix<vtype, N> &out,
 | 
			
		||||
                                    const iMatrix<vtype, N> &in,
 | 
			
		||||
                                    int permutetype) {
 | 
			
		||||
    for (int i = 0; i < N; i++) {
 | 
			
		||||
      for (int j = 0; j < N; j++) {
 | 
			
		||||
        permute(out._internal[i][j], in._internal[i][j], permutetype);
 | 
			
		||||
    }}
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Unary negation
 | 
			
		||||
  friend strong_inline iMatrix<vtype, N> operator-(const iMatrix<vtype, N> &r) {
 | 
			
		||||
@@ -334,7 +360,8 @@ public:
 | 
			
		||||
    for (int i = 0; i < N; i++) {
 | 
			
		||||
      for (int j = 0; j < N; j++) {
 | 
			
		||||
        ret._internal[i][j] = -r._internal[i][j];
 | 
			
		||||
    }}
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return ret;
 | 
			
		||||
  }
 | 
			
		||||
  // *=,+=,-= operators inherit from corresponding "*,-,+" behaviour
 | 
			
		||||
@@ -355,13 +382,12 @@ public:
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // returns an lvalue reference
 | 
			
		||||
  strong_inline vtype & operator ()(int i,int j) {
 | 
			
		||||
    return _internal[i][j];
 | 
			
		||||
  }
 | 
			
		||||
  strong_inline vtype &operator()(int i, int j) { return _internal[i][j]; }
 | 
			
		||||
  strong_inline const vtype &operator()(int i, int j) const {
 | 
			
		||||
    return _internal[i][j];
 | 
			
		||||
  }
 | 
			
		||||
  friend std::ostream& operator<< (std::ostream& stream, const iMatrix<vtype,N> &o){
 | 
			
		||||
  friend std::ostream &operator<<(std::ostream &stream,
 | 
			
		||||
                                  const iMatrix<vtype, N> &o) {
 | 
			
		||||
    stream << "M<" << N << ">{";
 | 
			
		||||
    for (int i = 0; i < N; i++) {
 | 
			
		||||
      stream << "{";
 | 
			
		||||
@@ -379,27 +405,25 @@ public:
 | 
			
		||||
  //  strong_inline vtype && operator ()(int i,int j) {
 | 
			
		||||
  //    return _internal[i][j];
 | 
			
		||||
  //  }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class v> void vprefetch(const iScalar<v> &vv)
 | 
			
		||||
{
 | 
			
		||||
template <class v>
 | 
			
		||||
void vprefetch(const iScalar<v> &vv) {
 | 
			
		||||
  vprefetch(vv._internal);
 | 
			
		||||
}
 | 
			
		||||
template<class v,int N> void vprefetch(const iVector<v,N> &vv)
 | 
			
		||||
{
 | 
			
		||||
template <class v, int N>
 | 
			
		||||
void vprefetch(const iVector<v, N> &vv) {
 | 
			
		||||
  for (int i = 0; i < N; i++) {
 | 
			
		||||
    vprefetch(vv._internal[i]);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
template<class v,int N> void vprefetch(const iMatrix<v,N> &vv)
 | 
			
		||||
{
 | 
			
		||||
template <class v, int N>
 | 
			
		||||
void vprefetch(const iMatrix<v, N> &vv) {
 | 
			
		||||
  for (int i = 0; i < N; i++) {
 | 
			
		||||
    for (int j = 0; j < N; j++) {
 | 
			
		||||
      vprefetch(vv._internal[i][j]);
 | 
			
		||||
  }}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -86,6 +86,8 @@ UNARY(sqrt);
 | 
			
		||||
UNARY(rsqrt);
 | 
			
		||||
UNARY(sin);
 | 
			
		||||
UNARY(cos);
 | 
			
		||||
UNARY(asin);
 | 
			
		||||
UNARY(acos);
 | 
			
		||||
UNARY(log);
 | 
			
		||||
UNARY(exp);
 | 
			
		||||
UNARY(abs);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								scripts/Make.inc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								scripts/Make.inc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
 | 
			
		||||
HFILES=
 | 
			
		||||
 | 
			
		||||
CCFILES=
 | 
			
		||||
@@ -66,6 +66,9 @@ public:
 | 
			
		||||
 | 
			
		||||
    TwoFlavourEvenOddPseudoFermionAction<ImplPolicy> Nf2(FermOp,CG,CG);
 | 
			
		||||
 | 
			
		||||
    //Set smearing (true/false), default: false
 | 
			
		||||
    Nf2.is_smeared=false;
 | 
			
		||||
    
 | 
			
		||||
    //Collect actions
 | 
			
		||||
    ActionLevel<LatticeGaugeField> Level1(1);
 | 
			
		||||
    Level1.push_back(&Nf2);
 | 
			
		||||
 
 | 
			
		||||
@@ -66,6 +66,9 @@ public:
 | 
			
		||||
    ConjugateGradient<FermionField>  CG(1.0e-8,10000);
 | 
			
		||||
    TwoFlavourEvenOddRatioPseudoFermionAction<ImplPolicy> Nf2(NumOp, DenOp,CG,CG);
 | 
			
		||||
  
 | 
			
		||||
    //Set smearing (true/false), default: false
 | 
			
		||||
    Nf2.is_smeared=true;
 | 
			
		||||
  
 | 
			
		||||
    //Collect actions
 | 
			
		||||
    ActionLevel<LatticeGaugeField> Level1;
 | 
			
		||||
    Level1.push_back(&Nf2);
 | 
			
		||||
 
 | 
			
		||||
@@ -67,6 +67,10 @@ public:
 | 
			
		||||
 | 
			
		||||
    TwoFlavourPseudoFermionAction<ImplPolicy> Nf2(FermOp,CG,CG);
 | 
			
		||||
  
 | 
			
		||||
    //Set smearing (true/false), default: false
 | 
			
		||||
    Nf2.is_smeared = true;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    //Collect actions
 | 
			
		||||
    ActionLevel<LatticeGaugeField> Level1(1);
 | 
			
		||||
    Level1.push_back(&Nf2);
 | 
			
		||||
 
 | 
			
		||||
@@ -66,6 +66,9 @@ public:
 | 
			
		||||
    ConjugateGradient<FermionField>  CG(1.0e-8,10000);
 | 
			
		||||
    TwoFlavourRatioPseudoFermionAction<ImplPolicy> Nf2(NumOp, DenOp,CG,CG);
 | 
			
		||||
 | 
			
		||||
    //Set smearing (true/false), default: false
 | 
			
		||||
    Nf2.is_smeared=true;
 | 
			
		||||
  
 | 
			
		||||
    //Collect actions
 | 
			
		||||
    ActionLevel<LatticeGaugeField> Level1;
 | 
			
		||||
    Level1.push_back(&Nf2);
 | 
			
		||||
 
 | 
			
		||||
@@ -25,35 +25,38 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
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
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution
 | 
			
		||||
directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
#include "Grid.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
using namespace Grid;
 | 
			
		||||
using namespace Grid::QCD;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 Grid_main.cc(232): error: no suitable user-defined conversion from "Grid::iScalar<Grid::iMatrix<Grid::iScalar<Grid::Complex>, 4>>" to "const Grid::iScalar<Grid::iScalar<Grid::iMatrix<Grid::Complex, 3>>>" exists
 | 
			
		||||
 Grid_main.cc(232): error: no suitable user-defined conversion from
 | 
			
		||||
"Grid::iScalar<Grid::iMatrix<Grid::iScalar<Grid::Complex>, 4>>" to "const
 | 
			
		||||
Grid::iScalar<Grid::iScalar<Grid::iMatrix<Grid::Complex, 3>>>" exists
 | 
			
		||||
c_m = peekIdiot<SpinColourMatrix>(scm,1,2);
 | 
			
		||||
*/
 | 
			
		||||
template<class vobj> auto peekIdiot(const vobj &rhs,int i,int j) -> decltype(peekIndex<2>(rhs,0,0))
 | 
			
		||||
{
 | 
			
		||||
template <class vobj>
 | 
			
		||||
auto peekIdiot(const vobj &rhs, int i, int j)
 | 
			
		||||
    -> decltype(peekIndex<2>(rhs, 0, 0)) {
 | 
			
		||||
  return peekIndex<2>(rhs, i, j);
 | 
			
		||||
}
 | 
			
		||||
template<class vobj> auto peekDumKopf(const vobj &rhs,int i,int j) -> decltype(peekIndex<3>(rhs,0,0))
 | 
			
		||||
{
 | 
			
		||||
template <class vobj>
 | 
			
		||||
auto peekDumKopf(const vobj &rhs, int i, int j)
 | 
			
		||||
    -> decltype(peekIndex<3>(rhs, 0, 0)) {
 | 
			
		||||
  return peekIndex<3>(rhs, i, j);
 | 
			
		||||
}
 | 
			
		||||
template<class vobj> auto peekDumKopf(const vobj &rhs,int i) -> decltype(peekIndex<3>(rhs,0))
 | 
			
		||||
{
 | 
			
		||||
template <class vobj>
 | 
			
		||||
auto peekDumKopf(const vobj &rhs, int i) -> decltype(peekIndex<3>(rhs, 0)) {
 | 
			
		||||
  return peekIndex<3>(rhs, i);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main (int argc, char ** argv)
 | 
			
		||||
{
 | 
			
		||||
int main(int argc, char **argv) {
 | 
			
		||||
  Grid_init(&argc, &argv);
 | 
			
		||||
 | 
			
		||||
  std::vector<int> latt_size = GridDefaultLatt();
 | 
			
		||||
@@ -73,7 +76,6 @@ int main (int argc, char ** argv)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    for (int lat = 8; lat <= 16; lat += 40) {
 | 
			
		||||
 | 
			
		||||
      std::cout << "Lat " << lat << std::endl;
 | 
			
		||||
 | 
			
		||||
      latt_size[0] = lat;
 | 
			
		||||
@@ -132,7 +134,6 @@ int main (int argc, char ** argv)
 | 
			
		||||
 | 
			
		||||
      LatticeLorentzColourMatrix lcMat(&Fine);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      LatticeComplex scalar(&Fine);
 | 
			
		||||
      LatticeReal rscalar(&Fine);
 | 
			
		||||
      LatticeReal iscalar(&Fine);
 | 
			
		||||
@@ -154,24 +155,40 @@ int main (int argc, char ** argv)
 | 
			
		||||
      random(FineRNG, sVec);
 | 
			
		||||
      random(FineRNG, scVec);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      fflush(stdout);
 | 
			
		||||
 | 
			
		||||
      LatticeColourMatrix newFoo = Foo; 
 | 
			
		||||
      // confirm correctness of copy constructor
 | 
			
		||||
      Bar = Foo - newFoo;
 | 
			
		||||
      std::cout << "Copy constructor diff check: "; 
 | 
			
		||||
      double test_cc = norm2(Bar);
 | 
			
		||||
      if (test_cc < 1e-5){
 | 
			
		||||
        std::cout << "OK\n";
 | 
			
		||||
    }
 | 
			
		||||
      else{
 | 
			
		||||
        std::cout << "fail\n";
 | 
			
		||||
        abort();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
      TComplex tr = trace(cmat);
 | 
			
		||||
 | 
			
		||||
     
 | 
			
		||||
    cVec = cMat * cVec;  // LatticeColourVector     = LatticeColourMatrix     * LatticeColourVector
 | 
			
		||||
    sVec = sMat * sVec;  // LatticeSpinVector       = LatticeSpinMatrix       * LatticeSpinVector
 | 
			
		||||
    scVec= scMat * scVec;// LatticeSpinColourVector = LatticeSpinColourMatrix * LatticeSpinColourVector
 | 
			
		||||
    scVec= cMat * scVec; // LatticeSpinColourVector = LatticeColourMatrix     * LatticeSpinColourVector
 | 
			
		||||
    scVec= sMat * scVec; // LatticeSpinColourVector = LatticeSpinMatrix       * LatticeSpinColourVector
 | 
			
		||||
      cVec = cMat * cVec;     // LatticeColourVector     = LatticeColourMatrix
 | 
			
		||||
                              // * LatticeColourVector
 | 
			
		||||
      sVec = sMat * sVec;     // LatticeSpinVector       = LatticeSpinMatrix
 | 
			
		||||
                              // * LatticeSpinVector
 | 
			
		||||
      scVec = scMat * scVec;  // LatticeSpinColourVector =
 | 
			
		||||
                              // LatticeSpinColourMatrix *
 | 
			
		||||
                              // LatticeSpinColourVector
 | 
			
		||||
      scVec = cMat * scVec;   // LatticeSpinColourVector = LatticeColourMatrix
 | 
			
		||||
                              // * LatticeSpinColourVector
 | 
			
		||||
      scVec = sMat * scVec;   // LatticeSpinColourVector = LatticeSpinMatrix
 | 
			
		||||
                              // * LatticeSpinColourVector
 | 
			
		||||
 | 
			
		||||
      cMat = outerProduct(cVec, cVec);
 | 
			
		||||
      scalar = localInnerProduct(cVec, cVec);
 | 
			
		||||
 | 
			
		||||
      cMat = Ta(cMat);  // traceless antihermitian
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      scalar += scalar;
 | 
			
		||||
      scalar -= scalar;
 | 
			
		||||
      scalar *= scalar;
 | 
			
		||||
@@ -193,7 +210,6 @@ int main (int argc, char ** argv)
 | 
			
		||||
      //    scalar =cmplx(rscalar,iscalar);
 | 
			
		||||
      PokeIndex<ColourIndex>(cVec, scalar, 1);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      scalar = transpose(scalar);
 | 
			
		||||
      scalar = TransposeIndex<ColourIndex>(scalar);
 | 
			
		||||
      scalar = TraceIndex<SpinIndex>(scalar);
 | 
			
		||||
@@ -214,9 +230,8 @@ int main (int argc, char ** argv)
 | 
			
		||||
      //     localNorm2
 | 
			
		||||
      //     localInnerProduct
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
    scMat = sMat*scMat;  // LatticeSpinColourMatrix = LatticeSpinMatrix       * LatticeSpinColourMatrix
 | 
			
		||||
 | 
			
		||||
      scMat = sMat * scMat;  // LatticeSpinColourMatrix = LatticeSpinMatrix
 | 
			
		||||
                             // * LatticeSpinColourMatrix
 | 
			
		||||
 | 
			
		||||
      ///////////////////////
 | 
			
		||||
      // Non-lattice (const objects) * Lattice
 | 
			
		||||
@@ -229,10 +244,13 @@ int main (int argc, char ** argv)
 | 
			
		||||
 | 
			
		||||
      //    vSpinColourMatrix vscm;
 | 
			
		||||
      scMat = cMat * scMat;
 | 
			
		||||
    scm = cm * scm;         // SpinColourMatrix  = ColourMatrix     * SpinColourMatrix
 | 
			
		||||
      scm =
 | 
			
		||||
          cm * scm;  // SpinColourMatrix  = ColourMatrix     * SpinColourMatrix
 | 
			
		||||
      scm = scm * cm;  // SpinColourMatrix  = SpinColourMartix * ColourMatrix
 | 
			
		||||
    scm = GammaFive * scm ; // SpinColourMatrix  = SpinMatrix       * SpinColourMatrix
 | 
			
		||||
    scm = scm* GammaFive  ; // SpinColourMatrix  = SpinColourMatrix * SpinMatrix
 | 
			
		||||
      scm = GammaFive *
 | 
			
		||||
            scm;  // SpinColourMatrix  = SpinMatrix       * SpinColourMatrix
 | 
			
		||||
      scm =
 | 
			
		||||
          scm * GammaFive;  // SpinColourMatrix  = SpinColourMatrix * SpinMatrix
 | 
			
		||||
 | 
			
		||||
      scm = scm * cplx;
 | 
			
		||||
      vscm = vscm * cplx;
 | 
			
		||||
@@ -261,7 +279,6 @@ int main (int argc, char ** argv)
 | 
			
		||||
      scm = transpose(scm);
 | 
			
		||||
      scm = transposeIndex<1>(scm);
 | 
			
		||||
 | 
			
		||||
   
 | 
			
		||||
      random(SerialRNG, cm);
 | 
			
		||||
      std::cout << GridLogMessage << cm << std::endl;
 | 
			
		||||
 | 
			
		||||
@@ -269,7 +286,6 @@ int main (int argc, char ** argv)
 | 
			
		||||
      TComplex tracecm = trace(cm);
 | 
			
		||||
      std::cout << GridLogMessage << cm << std::endl;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      cm = Exponentiate(cm, 2.0, 12);
 | 
			
		||||
      std::cout << GridLogMessage << cm << "  " << std::endl;
 | 
			
		||||
      Complex det = Determinant(cm);
 | 
			
		||||
@@ -283,11 +299,9 @@ int main (int argc, char ** argv)
 | 
			
		||||
      std::cout << GridLogMessage << cm << "  " << std::endl;
 | 
			
		||||
      std::cout << GridLogMessage << "norm: " << norm2(cm) << std::endl;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      //    det = Determinant(cm);
 | 
			
		||||
      //    std::cout<<GridLogMessage << "determinant: " << det <<  std::endl;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      //    Foo = Foo+scalar; // LatticeColourMatrix+Scalar
 | 
			
		||||
      //    Foo = Foo*scalar; // LatticeColourMatrix*Scalar
 | 
			
		||||
      //    Foo = Foo-scalar; // LatticeColourMatrix-Scalar
 | 
			
		||||
@@ -308,19 +322,20 @@ int main (int argc, char ** argv)
 | 
			
		||||
      std::cout << GridLogMessage << cm << "  " << std::endl;
 | 
			
		||||
      std::cout << GridLogMessage << "norm: " << norm2(cm) << std::endl;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    std::cout<<GridLogMessage << "norm cMmat : " << norm2(cMat) <<  std::endl;
 | 
			
		||||
      std::cout << GridLogMessage << "norm cMmat : " << norm2(cMat)
 | 
			
		||||
                << std::endl;
 | 
			
		||||
      cMat = expMat(cMat, ComplexD(1.0, 0.0));
 | 
			
		||||
    std::cout<<GridLogMessage << "norm expMat: " << norm2(cMat) <<  std::endl;
 | 
			
		||||
      std::cout << GridLogMessage << "norm expMat: " << norm2(cMat)
 | 
			
		||||
                << std::endl;
 | 
			
		||||
      peekSite(cm, cMat, mysite);
 | 
			
		||||
      std::cout << GridLogMessage << cm << "  " << std::endl;
 | 
			
		||||
    std::cout<<GridLogMessage << "determinant: " << Determinant(cm) <<  std::endl;
 | 
			
		||||
      std::cout << GridLogMessage << "determinant: " << Determinant(cm)
 | 
			
		||||
                << std::endl;
 | 
			
		||||
      std::cout << GridLogMessage << "norm: " << norm2(cm) << std::endl;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      // LatticeComplex trlcMat(&Fine);
 | 
			
		||||
    // trlcMat = trace(lcMat); // Trace involving iVector - now generates error
 | 
			
		||||
    
 | 
			
		||||
      // trlcMat = trace(lcMat); // Trace involving iVector - now generates
 | 
			
		||||
      // error
 | 
			
		||||
 | 
			
		||||
      {  // Peek-ology and Poke-ology, with a little app-ology
 | 
			
		||||
        Complex c;
 | 
			
		||||
@@ -328,8 +343,10 @@ int main (int argc, char ** argv)
 | 
			
		||||
        SpinMatrix s_m;
 | 
			
		||||
        SpinColourMatrix sc_m;
 | 
			
		||||
 | 
			
		||||
      s_m = TensorIndexRecursion<ColourIndex>::traceIndex(sc_m); // Map to traceColour
 | 
			
		||||
      c_m = TensorIndexRecursion<SpinIndex>::traceIndex(sc_m); // map to traceSpin
 | 
			
		||||
        s_m = TensorIndexRecursion<ColourIndex>::traceIndex(
 | 
			
		||||
            sc_m);  // Map to traceColour
 | 
			
		||||
        c_m = TensorIndexRecursion<SpinIndex>::traceIndex(
 | 
			
		||||
            sc_m);  // map to traceSpin
 | 
			
		||||
 | 
			
		||||
        c = TensorIndexRecursion<SpinIndex>::traceIndex(s_m);
 | 
			
		||||
        c = TensorIndexRecursion<ColourIndex>::traceIndex(c_m);
 | 
			
		||||
@@ -343,8 +360,10 @@ int main (int argc, char ** argv)
 | 
			
		||||
        printf("c. Level %d\n", c_m().TensorLevel);
 | 
			
		||||
        printf("c. Level %d\n", c_m()().TensorLevel);
 | 
			
		||||
 | 
			
		||||
      c_m()()    = scm()(0,0); //ColourComponents of CM <= ColourComponents of SpinColourMatrix
 | 
			
		||||
      scm()(1,1) = cm()();  //ColourComponents of CM <= ColourComponents of SpinColourMatrix
 | 
			
		||||
        c_m()() = scm()(0, 0);  // ColourComponents of CM <= ColourComponents of
 | 
			
		||||
                                // SpinColourMatrix
 | 
			
		||||
        scm()(1, 1) = cm()();  // ColourComponents of CM <= ColourComponents of
 | 
			
		||||
                               // SpinColourMatrix
 | 
			
		||||
        c = scm()(1, 1)(1, 2);
 | 
			
		||||
        scm()(1, 1)(2, 1) = c;
 | 
			
		||||
 | 
			
		||||
@@ -364,12 +383,12 @@ int main (int argc, char ** argv)
 | 
			
		||||
      */
 | 
			
		||||
      lex_sites(Foo);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      Integer mm[4];
 | 
			
		||||
      mm[0] = 1;
 | 
			
		||||
      mm[1] = Fine._rdimensions[0];
 | 
			
		||||
      mm[2] = Fine._ldimensions[0] * Fine._ldimensions[1];
 | 
			
		||||
    mm[3]=Fine._ldimensions[0]*Fine._ldimensions[1]*Fine._ldimensions[2];
 | 
			
		||||
      mm[3] =
 | 
			
		||||
          Fine._ldimensions[0] * Fine._ldimensions[1] * Fine._ldimensions[2];
 | 
			
		||||
 | 
			
		||||
      LatticeInteger lex(&Fine);
 | 
			
		||||
      lex = zero;
 | 
			
		||||
@@ -377,35 +396,37 @@ int main (int argc, char ** argv)
 | 
			
		||||
        LatticeInteger coor(&Fine);
 | 
			
		||||
        LatticeCoordinate(coor, d);
 | 
			
		||||
        lex = lex + coor * mm[d];
 | 
			
		||||
      
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      //    Bar = zero;
 | 
			
		||||
      //    Bar = where(lex<Integer(10),Foo,Bar);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      cout << "peeking sites..\n";
 | 
			
		||||
      {
 | 
			
		||||
        std::vector<int> coor(4);
 | 
			
		||||
        for (coor[3] = 0; coor[3] < latt_size[3] / mpi_layout[3]; coor[3]++) {
 | 
			
		||||
          for (coor[2] = 0; coor[2] < latt_size[2] / mpi_layout[2]; coor[2]++) {
 | 
			
		||||
      for(coor[1]=0;coor[1]<latt_size[1]/mpi_layout[1];coor[1]++){
 | 
			
		||||
      for(coor[0]=0;coor[0]<latt_size[0]/mpi_layout[0];coor[0]++){
 | 
			
		||||
            for (coor[1] = 0; coor[1] < latt_size[1] / mpi_layout[1];
 | 
			
		||||
                 coor[1]++) {
 | 
			
		||||
              for (coor[0] = 0; coor[0] < latt_size[0] / mpi_layout[0];
 | 
			
		||||
                   coor[0]++) {
 | 
			
		||||
                ColourMatrix bar;
 | 
			
		||||
                peekSite(bar, Bar, coor);
 | 
			
		||||
                for (int r = 0; r < 3; r++) {
 | 
			
		||||
                  for (int c = 0; c < 3; c++) {
 | 
			
		||||
	  //	  cout<<"bar "<<coor[0]<<coor[1]<<coor[2]<<coor[3] <<" "<<bar()()(r,c)<<std::endl;
 | 
			
		||||
	}}
 | 
			
		||||
      }}}}
 | 
			
		||||
                    //      cout<<"bar "<<coor[0]<<coor[1]<<coor[2]<<coor[3] <<"
 | 
			
		||||
                    //      "<<bar()()(r,c)<<std::endl;
 | 
			
		||||
                  }
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // setCheckerboard(ShiftedCheck,rFoo);
 | 
			
		||||
      // setCheckerboard(ShiftedCheck,bFoo);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      // Lattice SU(3) x SU(3)
 | 
			
		||||
      Fine.Barrier();
 | 
			
		||||
      FooBar = Foo * Bar;
 | 
			
		||||
@@ -440,11 +461,15 @@ int main (int argc, char ** argv)
 | 
			
		||||
      Fine.Barrier();
 | 
			
		||||
      if (Fine.IsBoss()) {
 | 
			
		||||
#ifdef OMP
 | 
			
		||||
      printf("mult NumThread %d , Lattice size %d , %f us per call\n",omp_get_max_threads(),lat,(t1-t0)/ncall);
 | 
			
		||||
        printf("mult NumThread %d , Lattice size %d , %f us per call\n",
 | 
			
		||||
               omp_get_max_threads(), lat, (t1 - t0) / ncall);
 | 
			
		||||
#endif
 | 
			
		||||
      printf("mult NumThread %d , Lattice size %d , %f us per call\n",omp,lat,(t1-t0)/ncall);
 | 
			
		||||
      printf("mult NumThread %d , Lattice size %d , %f Mflop/s\n",omp,lat,flops/(t1-t0));
 | 
			
		||||
      printf("mult NumThread %d , Lattice size %d , %f MB/s\n",omp,lat,bytes/(t1-t0));
 | 
			
		||||
        printf("mult NumThread %d , Lattice size %d , %f us per call\n", omp,
 | 
			
		||||
               lat, (t1 - t0) / ncall);
 | 
			
		||||
        printf("mult NumThread %d , Lattice size %d , %f Mflop/s\n", omp, lat,
 | 
			
		||||
               flops / (t1 - t0));
 | 
			
		||||
        printf("mult NumThread %d , Lattice size %d , %f MB/s\n", omp, lat,
 | 
			
		||||
               bytes / (t1 - t0));
 | 
			
		||||
      }
 | 
			
		||||
      mult(FooBar, Foo, Bar);
 | 
			
		||||
      FooBar = Foo * Bar;
 | 
			
		||||
@@ -464,9 +489,12 @@ int main (int argc, char ** argv)
 | 
			
		||||
      FooBar = Foo * Bar;
 | 
			
		||||
 | 
			
		||||
      if (Fine.IsBoss()) {
 | 
			
		||||
      printf("Cshift Mult: NumThread %d , Lattice size %d , %f us per call\n",omp,lat,(t1-t0)/ncall);
 | 
			
		||||
      printf("Cshift Mult: NumThread %d , Lattice size %d , %f Mflop/s\n",omp,lat,flops/(t1-t0));
 | 
			
		||||
      printf("Cshift Mult: NumThread %d , Lattice size %d , %f MB/s\n",omp,lat,bytes/(t1-t0));
 | 
			
		||||
        printf("Cshift Mult: NumThread %d , Lattice size %d , %f us per call\n",
 | 
			
		||||
               omp, lat, (t1 - t0) / ncall);
 | 
			
		||||
        printf("Cshift Mult: NumThread %d , Lattice size %d , %f Mflop/s\n",
 | 
			
		||||
               omp, lat, flops / (t1 - t0));
 | 
			
		||||
        printf("Cshift Mult: NumThread %d , Lattice size %d , %f MB/s\n", omp,
 | 
			
		||||
               lat, bytes / (t1 - t0));
 | 
			
		||||
      }
 | 
			
		||||
      //    pickCheckerboard(0,rFoo,FooBar);
 | 
			
		||||
      //    pickCheckerboard(1,bFoo,FooBar);
 | 
			
		||||
@@ -475,20 +503,19 @@ int main (int argc, char ** argv)
 | 
			
		||||
 | 
			
		||||
      double nrm = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      LatticeColourMatrix deriv(&Fine);
 | 
			
		||||
      double half = 0.5;
 | 
			
		||||
      deriv = 0.5 * Cshift(Foo, 0, 1) - 0.5 * Cshift(Foo, 0, -1);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      for (int dir = 0; dir < 4; dir++) {
 | 
			
		||||
        for (int shift = 0; shift < latt_size[dir]; shift++) {
 | 
			
		||||
 | 
			
		||||
	pickCheckerboard(0,rFoo,Foo);    // Pick out red or black checkerboards
 | 
			
		||||
          pickCheckerboard(0, rFoo,
 | 
			
		||||
                           Foo);  // Pick out red or black checkerboards
 | 
			
		||||
          pickCheckerboard(1, bFoo, Foo);
 | 
			
		||||
 | 
			
		||||
          if (Fine.IsBoss()) {
 | 
			
		||||
	  std::cout<<GridLogMessage << "Shifting both parities by "<< shift <<" direction "<< dir <<std::endl;
 | 
			
		||||
            std::cout << GridLogMessage << "Shifting both parities by " << shift
 | 
			
		||||
                      << " direction " << dir << std::endl;
 | 
			
		||||
          }
 | 
			
		||||
          Shifted = Cshift(Foo, dir, shift);  // Shift everything
 | 
			
		||||
 | 
			
		||||
@@ -497,45 +524,48 @@ int main (int argc, char ** argv)
 | 
			
		||||
 | 
			
		||||
          ShiftedCheck = zero;
 | 
			
		||||
          setCheckerboard(ShiftedCheck, bShifted);  // Put them all together
 | 
			
		||||
	setCheckerboard(ShiftedCheck,rShifted); // and check the results (later)
 | 
			
		||||
          setCheckerboard(ShiftedCheck,
 | 
			
		||||
                          rShifted);  // and check the results (later)
 | 
			
		||||
 | 
			
		||||
          // Check results
 | 
			
		||||
          std::vector<int> coor(4);
 | 
			
		||||
          for (coor[3] = 0; coor[3] < latt_size[3] / mpi_layout[3]; coor[3]++) {
 | 
			
		||||
	for(coor[2]=0;coor[2]<latt_size[2]/mpi_layout[2];coor[2]++){
 | 
			
		||||
	for(coor[1]=0;coor[1]<latt_size[1]/mpi_layout[1];coor[1]++){
 | 
			
		||||
	for(coor[0]=0;coor[0]<latt_size[0]/mpi_layout[0];coor[0]++){
 | 
			
		||||
 | 
			
		||||
	 
 | 
			
		||||
 
 | 
			
		||||
            for (coor[2] = 0; coor[2] < latt_size[2] / mpi_layout[2];
 | 
			
		||||
                 coor[2]++) {
 | 
			
		||||
              for (coor[1] = 0; coor[1] < latt_size[1] / mpi_layout[1];
 | 
			
		||||
                   coor[1]++) {
 | 
			
		||||
                for (coor[0] = 0; coor[0] < latt_size[0] / mpi_layout[0];
 | 
			
		||||
                     coor[0]++) {
 | 
			
		||||
                  std::complex<Grid::Real> diff;
 | 
			
		||||
 | 
			
		||||
                  std::vector<int> shiftcoor = coor;
 | 
			
		||||
        shiftcoor[dir]=(shiftcoor[dir]+shift+latt_size[dir])%(latt_size[dir]/mpi_layout[dir]);
 | 
			
		||||
                  shiftcoor[dir] = (shiftcoor[dir] + shift + latt_size[dir]) %
 | 
			
		||||
                                   (latt_size[dir] / mpi_layout[dir]);
 | 
			
		||||
 | 
			
		||||
                  std::vector<int> rl(4);
 | 
			
		||||
                  for (int dd = 0; dd < 4; dd++) {
 | 
			
		||||
                    rl[dd] = latt_size[dd] / simd_layout[dd] / mpi_layout[dd];
 | 
			
		||||
                  }
 | 
			
		||||
	int lex =  coor[0]%rl[0]
 | 
			
		||||
	  + (coor[1]%rl[1])*rl[0]
 | 
			
		||||
	  + (coor[2]%rl[2])*rl[0]*rl[1]
 | 
			
		||||
	  + (coor[3]%rl[3])*rl[0]*rl[1]*rl[2];
 | 
			
		||||
	lex += 
 | 
			
		||||
	  +1000*(coor[0]/rl[0])
 | 
			
		||||
	  +1000*(coor[1]/rl[1])*simd_layout[0]
 | 
			
		||||
	  +1000*(coor[2]/rl[2])*simd_layout[0]*simd_layout[1]
 | 
			
		||||
	  +1000*(coor[3]/rl[3])*simd_layout[0]*simd_layout[1]*simd_layout[2];
 | 
			
		||||
                  int lex = coor[0] % rl[0] + (coor[1] % rl[1]) * rl[0] +
 | 
			
		||||
                            (coor[2] % rl[2]) * rl[0] * rl[1] +
 | 
			
		||||
                            (coor[3] % rl[3]) * rl[0] * rl[1] * rl[2];
 | 
			
		||||
                  lex += +1000 * (coor[0] / rl[0]) +
 | 
			
		||||
                         1000 * (coor[1] / rl[1]) * simd_layout[0] +
 | 
			
		||||
                         1000 * (coor[2] / rl[2]) * simd_layout[0] *
 | 
			
		||||
                             simd_layout[1] +
 | 
			
		||||
                         1000 * (coor[3] / rl[3]) * simd_layout[0] *
 | 
			
		||||
                             simd_layout[1] * simd_layout[2];
 | 
			
		||||
 | 
			
		||||
	int lex_coor = shiftcoor[0]%rl[0]
 | 
			
		||||
	  + (shiftcoor[1]%rl[1])*rl[0]
 | 
			
		||||
	  + (shiftcoor[2]%rl[2])*rl[0]*rl[1]
 | 
			
		||||
	  + (shiftcoor[3]%rl[3])*rl[0]*rl[1]*rl[2];
 | 
			
		||||
	lex_coor += 
 | 
			
		||||
	  +1000*(shiftcoor[0]/rl[0])
 | 
			
		||||
	  +1000*(shiftcoor[1]/rl[1])*simd_layout[0]
 | 
			
		||||
	  +1000*(shiftcoor[2]/rl[2])*simd_layout[0]*simd_layout[1]
 | 
			
		||||
	  +1000*(shiftcoor[3]/rl[3])*simd_layout[0]*simd_layout[1]*simd_layout[2];
 | 
			
		||||
                  int lex_coor = shiftcoor[0] % rl[0] +
 | 
			
		||||
                                 (shiftcoor[1] % rl[1]) * rl[0] +
 | 
			
		||||
                                 (shiftcoor[2] % rl[2]) * rl[0] * rl[1] +
 | 
			
		||||
                                 (shiftcoor[3] % rl[3]) * rl[0] * rl[1] * rl[2];
 | 
			
		||||
                  lex_coor += +1000 * (shiftcoor[0] / rl[0]) +
 | 
			
		||||
                              1000 * (shiftcoor[1] / rl[1]) * simd_layout[0] +
 | 
			
		||||
                              1000 * (shiftcoor[2] / rl[2]) * simd_layout[0] *
 | 
			
		||||
                                  simd_layout[1] +
 | 
			
		||||
                              1000 * (shiftcoor[3] / rl[3]) * simd_layout[0] *
 | 
			
		||||
                                  simd_layout[1] * simd_layout[2];
 | 
			
		||||
 | 
			
		||||
                  ColourMatrix foo;
 | 
			
		||||
                  ColourMatrix bar;
 | 
			
		||||
@@ -558,36 +588,46 @@ int main (int argc, char ** argv)
 | 
			
		||||
                  Real Ttr = real(trprod);
 | 
			
		||||
                  double nn = Ttr;
 | 
			
		||||
                  if (nn > 0)
 | 
			
		||||
            cout<<"Shift real trace fail "<<coor[0]<<coor[1]<<coor[2]<<coor[3] <<endl;
 | 
			
		||||
     
 | 
			
		||||
                    cout << "Shift real trace fail " << coor[0] << coor[1]
 | 
			
		||||
                         << coor[2] << coor[3] << endl;
 | 
			
		||||
 | 
			
		||||
                  for (int r = 0; r < 3; r++) {
 | 
			
		||||
                    for (int c = 0; c < 3; c++) {
 | 
			
		||||
                      diff = shifted1()()(r, c) - shifted2()()(r, c);
 | 
			
		||||
                      nn = real(conjugate(diff) * diff);
 | 
			
		||||
                      if (nn > 0)
 | 
			
		||||
                cout<<"Shift fail (shifted1/shifted2-ref) "<<coor[0]<<coor[1]<<coor[2]<<coor[3] <<" "
 | 
			
		||||
                        cout << "Shift fail (shifted1/shifted2-ref) " << coor[0]
 | 
			
		||||
                             << coor[1] << coor[2] << coor[3] << " "
 | 
			
		||||
                             << shifted1()()(r, c) << " " << shifted2()()(r, c)
 | 
			
		||||
                    << " "<< foo()()(r,c)<< " lex expect " << lex_coor << " lex "<<lex<<endl;
 | 
			
		||||
                             << " " << foo()()(r, c) << " lex expect "
 | 
			
		||||
                             << lex_coor << " lex " << lex << endl;
 | 
			
		||||
                      else if (0)
 | 
			
		||||
                cout<<"Shift pass 1vs2 "<<coor[0]<<coor[1]<<coor[2]<<coor[3] <<" "
 | 
			
		||||
                    <<shifted1()()(r,c)<<" "<<shifted2()()(r,c)
 | 
			
		||||
                    << " "<< foo()()(r,c)<< " lex expect " << lex_coor << " lex "<<lex<<endl;
 | 
			
		||||
        }}
 | 
			
		||||
                        cout << "Shift pass 1vs2 " << coor[0] << coor[1]
 | 
			
		||||
                             << coor[2] << coor[3] << " " << shifted1()()(r, c)
 | 
			
		||||
                             << " " << shifted2()()(r, c) << " "
 | 
			
		||||
                             << foo()()(r, c) << " lex expect " << lex_coor
 | 
			
		||||
                             << " lex " << lex << endl;
 | 
			
		||||
                    }
 | 
			
		||||
                  }
 | 
			
		||||
 | 
			
		||||
                  for (int r = 0; r < 3; r++) {
 | 
			
		||||
                    for (int c = 0; c < 3; c++) {
 | 
			
		||||
                      diff = shifted3()()(r, c) - shifted2()()(r, c);
 | 
			
		||||
                      nn = real(conjugate(diff) * diff);
 | 
			
		||||
                      if (nn > 0)
 | 
			
		||||
                cout<<"Shift rb fail (shifted3/shifted2-ref) "<<coor[0]<<coor[1]<<coor[2]<<coor[3] <<" "
 | 
			
		||||
                        cout << "Shift rb fail (shifted3/shifted2-ref) "
 | 
			
		||||
                             << coor[0] << coor[1] << coor[2] << coor[3] << " "
 | 
			
		||||
                             << shifted3()()(r, c) << " " << shifted2()()(r, c)
 | 
			
		||||
                << " "<< foo()()(r,c)<< " lex expect " << lex_coor << " lex "<<lex<<endl;
 | 
			
		||||
                             << " " << foo()()(r, c) << " lex expect "
 | 
			
		||||
                             << lex_coor << " lex " << lex << endl;
 | 
			
		||||
                      else if (0)
 | 
			
		||||
                cout<<"Shift rb pass 3vs2 "<<coor[0]<<coor[1]<<coor[2]<<coor[3] <<" "
 | 
			
		||||
                <<shifted3()()(r,c)<<" "<<shifted2()()(r,c)
 | 
			
		||||
                << " "<< foo()()(r,c)<< " lex expect " << lex_coor << " lex "<<lex<<endl;
 | 
			
		||||
        }}
 | 
			
		||||
                        cout << "Shift rb pass 3vs2 " << coor[0] << coor[1]
 | 
			
		||||
                             << coor[2] << coor[3] << " " << shifted3()()(r, c)
 | 
			
		||||
                             << " " << shifted2()()(r, c) << " "
 | 
			
		||||
                             << foo()()(r, c) << " lex expect " << lex_coor
 | 
			
		||||
                             << " lex " << lex << endl;
 | 
			
		||||
                    }
 | 
			
		||||
                  }
 | 
			
		||||
                  peekSite(bar, Bar, coor);
 | 
			
		||||
 | 
			
		||||
                  peekSite(foobar1, FooBar, coor);
 | 
			
		||||
@@ -596,18 +636,31 @@ int main (int argc, char ** argv)
 | 
			
		||||
                    for (int c = 0; c < Nc; c++) {
 | 
			
		||||
                      diff = foobar2()()(r, c) - foobar1()()(r, c);
 | 
			
		||||
                      nrm = nrm + real(conjugate(diff) * diff);
 | 
			
		||||
        }}
 | 
			
		||||
    }}}}
 | 
			
		||||
	if( Fine.IsBoss() ){
 | 
			
		||||
	  std::cout<<GridLogMessage << "LatticeColorMatrix * LatticeColorMatrix nrm diff = "<<nrm<<std::endl;
 | 
			
		||||
                    }
 | 
			
		||||
      }}
 | 
			
		||||
                  }
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
          if (Fine.IsBoss()) {
 | 
			
		||||
            std::cout << GridLogMessage
 | 
			
		||||
                      << "LatticeColorMatrix * LatticeColorMatrix nrm diff = "
 | 
			
		||||
                      << nrm << std::endl;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    }  // loop for lat
 | 
			
		||||
  }    // loop for omp
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
  // Testing Smearing routine compilation, separate in a different file
 | 
			
		||||
  GridCartesian           Fine(latt_size,simd_layout,mpi_layout);
 | 
			
		||||
  Smear_APE< PeriodicGimplR > APEsmearing; // periodic gauge implemetation
 | 
			
		||||
  Smear_Stout< PeriodicGimplR > StoutSmearing(&APEsmearing);
 | 
			
		||||
  SmearedConfiguration< PeriodicGimplR > SmartConf(&Fine, 3, StoutSmearing);
 | 
			
		||||
 | 
			
		||||
  std::cout<<GridLogMessage << sizeof(vComplexF) << std::endl;
 | 
			
		||||
 
 | 
			
		||||
  */
 | 
			
		||||
  Grid_finalize();
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,8 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
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
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution
 | 
			
		||||
directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
#include "Grid.h"
 | 
			
		||||
@@ -35,10 +36,8 @@ using namespace Grid::QCD;
 | 
			
		||||
namespace Grid {
 | 
			
		||||
namespace QCD {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class HmcRunner : public NerscHmcRunner {
 | 
			
		||||
 public:
 | 
			
		||||
 | 
			
		||||
  void BuildTheAction(int argc, char **argv)
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
@@ -46,7 +45,9 @@ public:
 | 
			
		||||
    typedef WilsonFermionR FermionAction;
 | 
			
		||||
    typedef typename FermionAction::FermionField FermionField;
 | 
			
		||||
 | 
			
		||||
    UGrid   = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());
 | 
			
		||||
    UGrid = SpaceTimeGrid::makeFourDimGrid(
 | 
			
		||||
        GridDefaultLatt(), GridDefaultSimd(Nd, vComplex::Nsimd()),
 | 
			
		||||
        GridDefaultMpi());
 | 
			
		||||
    UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
 | 
			
		||||
 | 
			
		||||
    FGrid = UGrid;
 | 
			
		||||
@@ -62,9 +63,15 @@ public:
 | 
			
		||||
    FermionAction FermOp(U, *FGrid, *FrbGrid, mass);
 | 
			
		||||
 | 
			
		||||
    // 1+1 flavour
 | 
			
		||||
    OneFlavourRationalParams Params(1.0e-4,64.0,1000,1.0e-6);
 | 
			
		||||
    OneFlavourEvenOddRationalPseudoFermionAction<WilsonImplR> WilsonNf1a(FermOp,Params);
 | 
			
		||||
    OneFlavourEvenOddRationalPseudoFermionAction<WilsonImplR> WilsonNf1b(FermOp,Params);
 | 
			
		||||
    OneFlavourRationalParams Params(1.0e-4, 64.0, 2000, 1.0e-6);
 | 
			
		||||
    OneFlavourEvenOddRationalPseudoFermionAction<WilsonImplR> WilsonNf1a(
 | 
			
		||||
        FermOp, Params);
 | 
			
		||||
    OneFlavourEvenOddRationalPseudoFermionAction<WilsonImplR> WilsonNf1b(
 | 
			
		||||
        FermOp, Params);
 | 
			
		||||
 | 
			
		||||
    //Smearing on/off
 | 
			
		||||
    WilsonNf1a.is_smeared = true;
 | 
			
		||||
    WilsonNf1b.is_smeared = true;
 | 
			
		||||
 | 
			
		||||
    // Collect actions
 | 
			
		||||
    ActionLevel<LatticeGaugeField> Level1;
 | 
			
		||||
@@ -76,22 +83,18 @@ public:
 | 
			
		||||
 | 
			
		||||
    Run(argc, argv);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}}
 | 
			
		||||
 | 
			
		||||
int main (int argc, char ** argv)
 | 
			
		||||
{
 | 
			
		||||
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;
 | 
			
		||||
  std::cout << GridLogMessage << "Grid is setup to use " << threads
 | 
			
		||||
            << " threads" << std::endl;
 | 
			
		||||
 | 
			
		||||
  HmcRunner TheHMC;
 | 
			
		||||
 | 
			
		||||
  TheHMC.BuildTheAction(argc, argv);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -66,6 +66,10 @@ public:
 | 
			
		||||
    OneFlavourRationalPseudoFermionAction<WilsonImplR> WilsonNf1a(FermOp,Params);
 | 
			
		||||
    OneFlavourRationalPseudoFermionAction<WilsonImplR> WilsonNf1b(FermOp,Params);
 | 
			
		||||
 | 
			
		||||
    //Set smearing (true/false), default: false
 | 
			
		||||
    WilsonNf1a.is_smeared=false;
 | 
			
		||||
    WilsonNf1b.is_smeared=false;
 | 
			
		||||
 | 
			
		||||
    //Collect actions
 | 
			
		||||
    ActionLevel<LatticeGaugeField> Level1;
 | 
			
		||||
    Level1.push_back(&WilsonNf1a);
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,8 @@ Author: neo <cossu@post.kek.jp>
 | 
			
		||||
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
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution
 | 
			
		||||
directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
#include <Grid.h>
 | 
			
		||||
@@ -62,6 +63,18 @@ public:
 | 
			
		||||
  template<class vec> void operator()(vec &rr,vec &i1,vec &i2) const { rr = adj(i1);}
 | 
			
		||||
  std::string name(void) const { return std::string("Adj"); }
 | 
			
		||||
};
 | 
			
		||||
class funcImag {
 | 
			
		||||
public:
 | 
			
		||||
  funcImag() {};
 | 
			
		||||
  template<class vec> void operator()(vec &rr,vec &i1,vec &i2) const { rr = imag(i1);}
 | 
			
		||||
  std::string name(void) const { return std::string("imag"); }
 | 
			
		||||
};
 | 
			
		||||
class funcReal {
 | 
			
		||||
public:
 | 
			
		||||
  funcReal() {};
 | 
			
		||||
  template<class vec> void operator()(vec &rr,vec &i1,vec &i2) const { rr = real(i1);}
 | 
			
		||||
  std::string name(void) const { return std::string("real"); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class funcTimesI {
 | 
			
		||||
public:
 | 
			
		||||
@@ -141,8 +154,14 @@ void Tester(const functor &func)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  extract<vec,scal>(v_result,result);
 | 
			
		||||
 | 
			
		||||
  std::cout << GridLogMessage << " " << func.name() << std::endl;
 | 
			
		||||
 | 
			
		||||
  std::cout << GridLogDebug << v_input1 << std::endl;
 | 
			
		||||
  std::cout << GridLogDebug << v_result << std::endl;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  int ok=0;
 | 
			
		||||
  for(int i=0;i<Nsimd;i++){
 | 
			
		||||
    if ( abs(reference[i]-result[i])>1.0e-7){
 | 
			
		||||
@@ -389,6 +408,8 @@ int main (int argc, char ** argv)
 | 
			
		||||
  Tester<ComplexF,vComplexF>(funcTimes());
 | 
			
		||||
  Tester<ComplexF,vComplexF>(funcConj());
 | 
			
		||||
  Tester<ComplexF,vComplexF>(funcAdj());
 | 
			
		||||
  Tester<ComplexF,vComplexF>(funcReal());
 | 
			
		||||
  Tester<ComplexF,vComplexF>(funcImag());
 | 
			
		||||
  Tester<ComplexF,vComplexF>(funcInnerProduct());
 | 
			
		||||
  ReductionTester<ComplexF,ComplexF,vComplexF>(funcReduce());
 | 
			
		||||
 | 
			
		||||
@@ -421,13 +442,17 @@ int main (int argc, char ** argv)
 | 
			
		||||
  Tester<ComplexD,vComplexD>(funcTimes());
 | 
			
		||||
  Tester<ComplexD,vComplexD>(funcConj());
 | 
			
		||||
  Tester<ComplexD,vComplexD>(funcAdj());
 | 
			
		||||
  Tester<ComplexD, vComplexD>(funcReal());
 | 
			
		||||
  Tester<ComplexD, vComplexD>(funcImag());
 | 
			
		||||
 | 
			
		||||
  Tester<ComplexD, vComplexD>(funcInnerProduct());
 | 
			
		||||
  ReductionTester<ComplexD, ComplexD, vComplexD>(funcReduce());
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  std::cout<<GridLogMessage << "==================================="<<  std::endl;
 | 
			
		||||
  std::cout << GridLogMessage
 | 
			
		||||
            << "===================================" << std::endl;
 | 
			
		||||
  std::cout << GridLogMessage << "Testing vComplexD permutes " << std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "==================================="<<  std::endl;
 | 
			
		||||
  std::cout << GridLogMessage
 | 
			
		||||
            << "===================================" << std::endl;
 | 
			
		||||
 | 
			
		||||
  // Log2 iteration
 | 
			
		||||
  for (int i = 0; (1 << i) < vComplexD::Nsimd(); i++) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user