mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-11-04 05:54:32 +00:00 
			
		
		
		
	Adding metric and the implicit steps
This commit is contained in:
		@@ -33,6 +33,32 @@ directory
 | 
			
		||||
namespace Grid {
 | 
			
		||||
namespace QCD {
 | 
			
		||||
 | 
			
		||||
struct LaplacianParams : Serializable {
 | 
			
		||||
  GRID_SERIALIZABLE_CLASS_MEMBERS(LaplacianParams, 
 | 
			
		||||
                                  RealD, lo, 
 | 
			
		||||
                                  RealD, hi, 
 | 
			
		||||
                                  int,   MaxIter, 
 | 
			
		||||
                                  RealD, tolerance, 
 | 
			
		||||
                                  int,   degree, 
 | 
			
		||||
                                  int,   precision);
 | 
			
		||||
  
 | 
			
		||||
  // constructor 
 | 
			
		||||
  LaplacianParams(RealD lo      = 0.0, 
 | 
			
		||||
                  RealD hi      = 1.0, 
 | 
			
		||||
                  int maxit     = 1000,
 | 
			
		||||
                  RealD tol     = 1.0e-8, 
 | 
			
		||||
                  int degree    = 10,
 | 
			
		||||
                  int precision = 64)
 | 
			
		||||
    : lo(lo),
 | 
			
		||||
      hi(hi),
 | 
			
		||||
      MaxIter(maxit),
 | 
			
		||||
      tolerance(tol),
 | 
			
		||||
      degree(degree),
 | 
			
		||||
      precision(precision){};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////
 | 
			
		||||
// Laplacian operator L on adjoint fields
 | 
			
		||||
//
 | 
			
		||||
@@ -48,12 +74,22 @@ namespace QCD {
 | 
			
		||||
////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template <class Impl>
 | 
			
		||||
class LaplacianAdjointField {
 | 
			
		||||
class LaplacianAdjointField: public Metric<typename Impl::Field> {
 | 
			
		||||
  OperatorFunction<typename Impl::Field> &Solver;
 | 
			
		||||
  LaplacianParams param;
 | 
			
		||||
  MultiShiftFunction PowerNegHalf;    
 | 
			
		||||
 | 
			
		||||
 public:
 | 
			
		||||
  INHERIT_GIMPL_TYPES(Impl);
 | 
			
		||||
  
 | 
			
		||||
  LaplacianAdjointField(GridBase* grid, const RealD k = 1.0) : 
 | 
			
		||||
    U(Nd, grid), kappa(k){};
 | 
			
		||||
 | 
			
		||||
  LaplacianAdjointField(GridBase* grid, OperatorFunction<GaugeField>& S, LaplacianParams& p, const RealD k = 1.0)
 | 
			
		||||
      : U(Nd, grid), Solver(S), param(p), kappa(k){
 | 
			
		||||
        AlgRemez remez(param.lo,param.hi,param.precision);
 | 
			
		||||
        std::cout<<GridLogMessage << "Generating degree "<<param.degree<<" for x^(1/2)"<<std::endl;
 | 
			
		||||
        remez.generateApprox(param.degree,1,2);
 | 
			
		||||
        PowerNegHalf.Init(remez,param.tolerance,true);
 | 
			
		||||
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
  void ImportGauge(const GaugeField& _U) {
 | 
			
		||||
    for (int mu = 0; mu < Nd; mu++) {
 | 
			
		||||
@@ -61,41 +97,63 @@ class LaplacianAdjointField {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void Mdiag(const GaugeLinkField& in, GaugeLinkField& out) { assert(0); }
 | 
			
		||||
 | 
			
		||||
  void Mdir(const GaugeLinkField& in, GaugeLinkField& out, int dir, int disp) {
 | 
			
		||||
    assert(0);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void M(const GaugeLinkField& in, GaugeLinkField& out) {
 | 
			
		||||
  void M(const GaugeField& in, GaugeField& out) {
 | 
			
		||||
    GaugeLinkField tmp(in._grid);
 | 
			
		||||
    GaugeLinkField tmp2(in._grid);
 | 
			
		||||
    GaugeLinkField sum(in._grid);
 | 
			
		||||
    sum = zero;
 | 
			
		||||
    for (int mu = 0; mu < Nd; mu++) {
 | 
			
		||||
      tmp = U[mu] * Cshift(in, mu, +1) * adj(U[mu]);
 | 
			
		||||
      tmp2 = adj(U[mu]) * in * U[mu];
 | 
			
		||||
      sum += tmp + Cshift(tmp2, mu, -1) - 2.0 * in;
 | 
			
		||||
 | 
			
		||||
    for (int nu = 0; nu < Nd; nu++) {
 | 
			
		||||
      sum = zero;
 | 
			
		||||
      GaugeLinkField in_nu = PeekIndex<LorentzIndex>(in, nu);
 | 
			
		||||
      GaugeLinkField out_nu(out._grid);
 | 
			
		||||
      for (int mu = 0; mu < Nd; mu++) {
 | 
			
		||||
        tmp = U[mu] * Cshift(in_nu, mu, +1) * adj(U[mu]);
 | 
			
		||||
        tmp2 = adj(U[mu]) * in_nu * U[mu];
 | 
			
		||||
        sum += tmp + Cshift(tmp2, mu, -1) - 2.0 * in_nu;
 | 
			
		||||
      }
 | 
			
		||||
      out_nu = (1.0 - kappa) * in_nu - kappa / (double(4 * Nd)) * sum;
 | 
			
		||||
      PokeIndex<LorentzIndex>(out, out_nu, nu);
 | 
			
		||||
    }
 | 
			
		||||
    out = (1.0 - kappa) * in - kappa / (double(4 * Nd)) * sum;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void MDeriv(const GaugeLinkField& in, GaugeLinkField& out, bool dag){
 | 
			
		||||
    RealD factor = - kappa / (double(4 * Nd))
 | 
			
		||||
    if (!dag)
 | 
			
		||||
      out = factor * Cshift(in, mu, +1) * adj(U[mu]) + adj(U[mu]) * in;
 | 
			
		||||
    else
 | 
			
		||||
      out = factor * U[mu] * Cshift(in, mu, +1) + in * U[mu];
 | 
			
		||||
  void MDeriv(const GaugeField& in, GaugeField& der, bool dag) {
 | 
			
		||||
    RealD factor = -kappa / (double(4 * Nd));
 | 
			
		||||
    for (int mu = 0; mu < Nd; mu++) {
 | 
			
		||||
      GaugeLinkField in_mu = PeekIndex<LorentzIndex>(in, mu);
 | 
			
		||||
      GaugeLinkField der_mu(der._grid);
 | 
			
		||||
      if (!dag)
 | 
			
		||||
        der_mu =
 | 
			
		||||
            factor * Cshift(in_mu, mu, +1) * adj(U[mu]) + adj(U[mu]) * in_mu;
 | 
			
		||||
      else
 | 
			
		||||
        der_mu = factor * U[mu] * Cshift(in_mu, mu, +1) + in_mu * U[mu];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void Minv(const GaugeField& in, GaugeField& inverted){
 | 
			
		||||
    HermitianLinearOperator<LaplacianAdjointField<Impl>,GaugeField> HermOp(*this);
 | 
			
		||||
    Solver(HermOp, in, inverted);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void MInvSquareRoot(GaugeField& P){
 | 
			
		||||
    // Takes a gaussian gauge field and multiplies by the metric
 | 
			
		||||
    // need the rational approximation for the square root 
 | 
			
		||||
    GaugeField Gp(P._grid);
 | 
			
		||||
    HermitianLinearOperator<LaplacianAdjointField<Impl>,GaugeField> HermOp(*this);
 | 
			
		||||
    ConjugateGradientMultiShift<GaugeField> msCG(param.MaxIter,PowerNegHalf);
 | 
			
		||||
    msCG(HermOp,P,Gp);
 | 
			
		||||
    P = Gp; // now P has the correct distribution
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  RealD kappa;
 | 
			
		||||
  std::vector<GaugeLinkField> U;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// This is just a debug tests
 | 
			
		||||
// not meant to be used 
 | 
			
		||||
// This is just for debuggin purposes
 | 
			
		||||
// not meant to be used by the final users
 | 
			
		||||
 | 
			
		||||
template <class Impl>
 | 
			
		||||
class LaplacianAlgebraField {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										121
									
								
								lib/qcd/utils/Metric.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								lib/qcd/utils/Metric.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,121 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid
 | 
			
		||||
 | 
			
		||||
Source file: ./lib/qcd/hmc/integrators/Integrator.h
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
 | 
			
		||||
Author: Guido Cossu <guido.cossu@ed.ac.uk>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution
 | 
			
		||||
directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
//--------------------------------------------------------------------
 | 
			
		||||
#ifndef METRIC_H
 | 
			
		||||
#define METRIC_H
 | 
			
		||||
 | 
			
		||||
namespace Grid{
 | 
			
		||||
namespace QCD{
 | 
			
		||||
 | 
			
		||||
template <typename Field> 
 | 
			
		||||
class Metric{
 | 
			
		||||
public:
 | 
			
		||||
  virtual void ImportGauge(const Field&)   = 0;
 | 
			
		||||
  virtual void M(const Field&, Field&)     = 0;
 | 
			
		||||
  virtual void Minv(const Field&, Field&)  = 0;
 | 
			
		||||
  virtual void MInvSquareRoot(Field&) = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Need a trivial operator
 | 
			
		||||
template <typename Field>
 | 
			
		||||
class TrivialMetric : public Metric<Field>{
 | 
			
		||||
public:
 | 
			
		||||
  virtual void ImportGauge(const Field&){};
 | 
			
		||||
  virtual void M(const Field& in, Field& out){
 | 
			
		||||
    out = in;
 | 
			
		||||
  }
 | 
			
		||||
  virtual void Minv(const Field& in, Field& out){
 | 
			
		||||
    out = in;
 | 
			
		||||
  }
 | 
			
		||||
  virtual void MInvSquareRoot(Field& P){
 | 
			
		||||
    // do nothing
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
///////////////////////////////
 | 
			
		||||
// Generalised momenta
 | 
			
		||||
///////////////////////////////
 | 
			
		||||
 | 
			
		||||
template <typename Implementation, typename Metric>
 | 
			
		||||
class GeneralisedMomenta{
 | 
			
		||||
public:
 | 
			
		||||
  typedef typename Implementation::Field MomentaField;  //for readability
 | 
			
		||||
 | 
			
		||||
  Metric M;
 | 
			
		||||
  MomentaField Mom;
 | 
			
		||||
 | 
			
		||||
  GeneralisedMomenta(GridBase* grid): Mom(grid){}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  void MomentaDistribution(GridParallelRNG& pRNG){
 | 
			
		||||
    // Generate a distribution for
 | 
			
		||||
    // 1/2 P^dag G P
 | 
			
		||||
    // where G = M^-1
 | 
			
		||||
 | 
			
		||||
    // Generate gaussian momenta
 | 
			
		||||
    Implementation::generate_momenta(Mom, pRNG);
 | 
			
		||||
    // Modify the distribution with the metric
 | 
			
		||||
    M.MInvSquareRoot(Mom);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void Derivative(MomentaField& in, MomentaField& der){
 | 
			
		||||
    // Compute the derivative of the kinetic term
 | 
			
		||||
    // with respect to the gauge field
 | 
			
		||||
    MomentaField MomDer(in._grid);
 | 
			
		||||
    MomentaField X(in._grid);
 | 
			
		||||
 | 
			
		||||
    M.Minv(in, X); // X = G in
 | 
			
		||||
    M.MDeriv(X, MomDer, DaggerNo); // MomDer = dM/dU X
 | 
			
		||||
    // MomDer is just the derivative
 | 
			
		||||
    MomDer = adj(X)* MomDer;
 | 
			
		||||
    // Traceless Antihermitian
 | 
			
		||||
    // assuming we are in the algebra
 | 
			
		||||
    der = Implementation::projectForce(MomDer);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void DerivativeP(MomentaField& der){
 | 
			
		||||
    M.Minv(Mom, der);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif //METRIC_H
 | 
			
		||||
		Reference in New Issue
	
	Block a user