mirror of
https://github.com/paboyle/Grid.git
synced 2024-11-14 01:35:36 +00:00
First cut on generalised HMC
Backward compatibility OK
This commit is contained in:
parent
7ea4b959a4
commit
e415260961
@ -38,15 +38,19 @@ namespace QCD {
|
|||||||
|
|
||||||
template <class Gimpl> class WilsonLoops;
|
template <class Gimpl> class WilsonLoops;
|
||||||
|
|
||||||
#define INHERIT_GIMPL_TYPES(GImpl) \
|
|
||||||
typedef typename GImpl::Simd Simd; \
|
|
||||||
typedef typename GImpl::GaugeLinkField GaugeLinkField; \
|
|
||||||
typedef typename GImpl::GaugeField GaugeField; \
|
|
||||||
typedef typename GImpl::SiteGaugeField SiteGaugeField; \
|
|
||||||
typedef typename GImpl::SiteGaugeLink SiteGaugeLink;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
template <class S, int Nrepresentation = Nc> class GaugeImplTypes {
|
#define INHERIT_GIMPL_TYPES(GImpl) \
|
||||||
|
typedef typename GImpl::Simd Simd; \
|
||||||
|
typedef typename GImpl::LinkField GaugeLinkField; \
|
||||||
|
typedef typename GImpl::Field GaugeField; \
|
||||||
|
typedef typename GImpl::SiteField SiteGaugeField; \
|
||||||
|
typedef typename GImpl::SiteLink SiteGaugeLink;
|
||||||
|
|
||||||
|
#define INHERIT_FIELD_TYPES(Impl) \
|
||||||
|
typedef typename Impl::Field Field;
|
||||||
|
|
||||||
|
|
||||||
|
template <class S, int Nrepresentation = Nc > class GaugeImplTypes {
|
||||||
public:
|
public:
|
||||||
typedef S Simd;
|
typedef S Simd;
|
||||||
|
|
||||||
@ -55,16 +59,14 @@ public:
|
|||||||
template <typename vtype>
|
template <typename vtype>
|
||||||
using iImplGaugeField = iVector<iScalar<iMatrix<vtype, Nrepresentation>>, Nd>;
|
using iImplGaugeField = iVector<iScalar<iMatrix<vtype, Nrepresentation>>, Nd>;
|
||||||
|
|
||||||
typedef iImplGaugeLink<Simd> SiteGaugeLink;
|
typedef iImplGaugeLink<Simd> SiteLink;
|
||||||
typedef iImplGaugeField<Simd> SiteGaugeField;
|
typedef iImplGaugeField<Simd> SiteField;
|
||||||
|
|
||||||
typedef Lattice<SiteGaugeLink> GaugeLinkField; // bit ugly naming; polarised
|
typedef Lattice<SiteLink> LinkField;
|
||||||
// gauge field, lorentz... all
|
typedef Lattice<SiteField> Field;
|
||||||
// ugly
|
|
||||||
typedef Lattice<SiteGaugeField> GaugeField;
|
|
||||||
|
|
||||||
// Move this elsewhere? FIXME
|
// Move this elsewhere? FIXME
|
||||||
static inline void AddGaugeLink(GaugeField &U, GaugeLinkField &W,
|
static inline void AddLink(Field &U, LinkField &W,
|
||||||
int mu) { // U[mu] += W
|
int mu) { // U[mu] += W
|
||||||
PARALLEL_FOR_LOOP
|
PARALLEL_FOR_LOOP
|
||||||
for (auto ss = 0; ss < U._grid->oSites(); ss++) {
|
for (auto ss = 0; ss < U._grid->oSites(); ss++) {
|
||||||
@ -72,6 +74,28 @@ public:
|
|||||||
U._odata[ss]._internal[mu] + W._odata[ss]._internal;
|
U._odata[ss]._internal[mu] + W._odata[ss]._internal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void generate_momenta(Field& P, GridParallelRNG& pRNG){
|
||||||
|
// specific for SU gauge fields
|
||||||
|
LinkField Pmu(P._grid);
|
||||||
|
Pmu = zero;
|
||||||
|
for (int mu = 0; mu < Nd; mu++) {
|
||||||
|
SU<Nrepresentation>::GaussianFundamentalLieAlgebraMatrix(pRNG, Pmu);
|
||||||
|
PokeIndex<LorentzIndex>(P, Pmu, mu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void update_field(Field& P, Field& U, double ep, unsigned int Nexp){
|
||||||
|
|
||||||
|
for (int mu = 0; mu < Nd; mu++) {
|
||||||
|
auto Umu = PeekIndex<LorentzIndex>(U, mu);
|
||||||
|
auto Pmu = PeekIndex<LorentzIndex>(P, mu);
|
||||||
|
Umu = expMat(Pmu, ep, Nexp) * Umu;
|
||||||
|
PokeIndex<LorentzIndex>(U, ProjectOnGroup(Umu), mu);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Composition with smeared link, bc's etc.. probably need multiple inheritance
|
// Composition with smeared link, bc's etc.. probably need multiple inheritance
|
||||||
|
@ -60,24 +60,25 @@ struct HMCparameters {
|
|||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
}
|
}
|
||||||
|
|
||||||
void print() const {
|
void print_parameters() const {
|
||||||
std::cout << GridLogMessage << "[HMC parameter] Trajectories : " << Trajectories << "\n";
|
std::cout << GridLogMessage << "[HMC parameters] Trajectories : " << Trajectories << "\n";
|
||||||
std::cout << GridLogMessage << "[HMC parameter] Start trajectory : " << StartTrajectory << "\n";
|
std::cout << GridLogMessage << "[HMC parameters] Start trajectory : " << StartTrajectory << "\n";
|
||||||
std::cout << GridLogMessage << "[HMC parameter] Metropolis test (on/off): " << MetropolisTest << "\n";
|
std::cout << GridLogMessage << "[HMC parameters] Metropolis test (on/off): " << MetropolisTest << "\n";
|
||||||
std::cout << GridLogMessage << "[HMC parameter] Thermalization trajs : " << NoMetropolisUntil << "\n";
|
std::cout << GridLogMessage << "[HMC parameters] Thermalization trajs : " << NoMetropolisUntil << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class GaugeField>
|
template <class Field>
|
||||||
class HmcObservable {
|
class HmcObservable {
|
||||||
public:
|
public:
|
||||||
virtual void TrajectoryComplete(int traj, GaugeField &U, GridSerialRNG &sRNG,
|
virtual void TrajectoryComplete(int traj, Field &U, GridSerialRNG &sRNG,
|
||||||
GridParallelRNG &pRNG) = 0;
|
GridParallelRNG &pRNG) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// this is only defined for a gauge theory
|
||||||
template <class Gimpl>
|
template <class Gimpl>
|
||||||
class PlaquetteLogger : public HmcObservable<typename Gimpl::GaugeField> {
|
class PlaquetteLogger : public HmcObservable<typename Gimpl::Field> {
|
||||||
private:
|
private:
|
||||||
std::string Stem;
|
std::string Stem;
|
||||||
|
|
||||||
@ -117,19 +118,19 @@ class PlaquetteLogger : public HmcObservable<typename Gimpl::GaugeField> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// template <class GaugeField, class Integrator, class Smearer, class
|
template <class IntegratorType>
|
||||||
// Boundary>
|
|
||||||
template <class GaugeField, class IntegratorType>
|
|
||||||
class HybridMonteCarlo {
|
class HybridMonteCarlo {
|
||||||
private:
|
private:
|
||||||
const HMCparameters Params;
|
const HMCparameters Params;
|
||||||
|
|
||||||
|
typedef typename IntegratorType::Field Field;
|
||||||
|
|
||||||
GridSerialRNG &sRNG; // Fixme: need a RNG management strategy.
|
GridSerialRNG &sRNG; // Fixme: need a RNG management strategy.
|
||||||
GridParallelRNG &pRNG; // Fixme: need a RNG management strategy.
|
GridParallelRNG &pRNG; // Fixme: need a RNG management strategy.
|
||||||
GaugeField &Ucur;
|
Field &Ucur;
|
||||||
|
|
||||||
IntegratorType &TheIntegrator;
|
IntegratorType &TheIntegrator;
|
||||||
std::vector<HmcObservable<GaugeField> *> Observables;
|
std::vector<HmcObservable<Field> *> Observables;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////
|
||||||
// Metropolis step
|
// Metropolis step
|
||||||
@ -164,7 +165,7 @@ class HybridMonteCarlo {
|
|||||||
/////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////
|
||||||
// Evolution
|
// Evolution
|
||||||
/////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////
|
||||||
RealD evolve_step(GaugeField &U) {
|
RealD evolve_step(Field &U) {
|
||||||
TheIntegrator.refresh(U, pRNG); // set U and initialize P and phi's
|
TheIntegrator.refresh(U, pRNG); // set U and initialize P and phi's
|
||||||
|
|
||||||
RealD H0 = TheIntegrator.S(U); // initial state action
|
RealD H0 = TheIntegrator.S(U); // initial state action
|
||||||
@ -191,20 +192,21 @@ class HybridMonteCarlo {
|
|||||||
// Constructor
|
// Constructor
|
||||||
/////////////////////////////////////////
|
/////////////////////////////////////////
|
||||||
HybridMonteCarlo(HMCparameters Pams, IntegratorType &_Int,
|
HybridMonteCarlo(HMCparameters Pams, IntegratorType &_Int,
|
||||||
GridSerialRNG &_sRNG, GridParallelRNG &_pRNG, GaugeField &_U)
|
GridSerialRNG &_sRNG, GridParallelRNG &_pRNG, Field &_U)
|
||||||
: Params(Pams), TheIntegrator(_Int), sRNG(_sRNG), pRNG(_pRNG), Ucur(_U) {}
|
: Params(Pams), TheIntegrator(_Int), sRNG(_sRNG), pRNG(_pRNG), Ucur(_U) {}
|
||||||
~HybridMonteCarlo(){};
|
~HybridMonteCarlo(){};
|
||||||
|
|
||||||
void AddObservable(HmcObservable<GaugeField> *obs) {
|
void AddObservable(HmcObservable<Field> *obs) {
|
||||||
Observables.push_back(obs);
|
Observables.push_back(obs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void evolve(void) {
|
void evolve(void) {
|
||||||
Real DeltaH;
|
Real DeltaH;
|
||||||
|
|
||||||
GaugeField Ucopy(Ucur._grid);
|
Field Ucopy(Ucur._grid);
|
||||||
|
|
||||||
Params.print();
|
Params.print_parameters();
|
||||||
|
TheIntegrator.print_parameters();
|
||||||
|
|
||||||
// Actual updates (evolve a copy Ucopy then copy back eventually)
|
// Actual updates (evolve a copy Ucopy then copy back eventually)
|
||||||
for (int traj = Params.StartTrajectory;
|
for (int traj = Params.StartTrajectory;
|
||||||
|
@ -32,6 +32,7 @@ directory
|
|||||||
namespace Grid {
|
namespace Grid {
|
||||||
namespace QCD {
|
namespace QCD {
|
||||||
|
|
||||||
|
// Class for HMC specific for gauge theories
|
||||||
template <class Gimpl, class RepresentationsPolicy = NoHirep >
|
template <class Gimpl, class RepresentationsPolicy = NoHirep >
|
||||||
class NerscHmcRunnerTemplate {
|
class NerscHmcRunnerTemplate {
|
||||||
public:
|
public:
|
||||||
@ -114,7 +115,7 @@ class NerscHmcRunnerTemplate {
|
|||||||
*/
|
*/
|
||||||
//////////////
|
//////////////
|
||||||
NoSmearing<Gimpl> SmearingPolicy;
|
NoSmearing<Gimpl> SmearingPolicy;
|
||||||
typedef MinimumNorm2<GaugeField, NoSmearing<Gimpl>, RepresentationsPolicy >
|
typedef MinimumNorm2<Gimpl, NoSmearing<Gimpl>, RepresentationsPolicy >
|
||||||
IntegratorType; // change here to change the algorithm
|
IntegratorType; // change here to change the algorithm
|
||||||
IntegratorParameters MDpar(20, 1.0);
|
IntegratorParameters MDpar(20, 1.0);
|
||||||
IntegratorType MDynamics(UGrid, MDpar, TheAction, SmearingPolicy);
|
IntegratorType MDynamics(UGrid, MDpar, TheAction, SmearingPolicy);
|
||||||
@ -157,10 +158,9 @@ class NerscHmcRunnerTemplate {
|
|||||||
// smeared set
|
// smeared set
|
||||||
// notice that the unit configuration is singular in this procedure
|
// notice that the unit configuration is singular in this procedure
|
||||||
std::cout << GridLogMessage << "Filling the smeared set\n";
|
std::cout << GridLogMessage << "Filling the smeared set\n";
|
||||||
SmearingPolicy.set_GaugeField(U);
|
SmearingPolicy.set_Field(U);
|
||||||
|
|
||||||
HybridMonteCarlo<GaugeField, IntegratorType> HMC(HMCpar, MDynamics, sRNG,
|
HybridMonteCarlo<IntegratorType> HMC(HMCpar, MDynamics, sRNG, pRNG, U);
|
||||||
pRNG, U);
|
|
||||||
HMC.AddObservable(&Checkpoint);
|
HMC.AddObservable(&Checkpoint);
|
||||||
HMC.AddObservable(&PlaqLog);
|
HMC.AddObservable(&PlaqLog);
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
|||||||
namespace Grid{
|
namespace Grid{
|
||||||
namespace QCD{
|
namespace QCD{
|
||||||
|
|
||||||
|
// Only for gauge fields
|
||||||
template<class Gimpl>
|
template<class Gimpl>
|
||||||
class NerscHmcCheckpointer : public HmcObservable<typename Gimpl::GaugeField> {
|
class NerscHmcCheckpointer : public HmcObservable<typename Gimpl::GaugeField> {
|
||||||
private:
|
private:
|
||||||
|
@ -49,60 +49,53 @@ namespace Grid {
|
|||||||
namespace QCD {
|
namespace QCD {
|
||||||
|
|
||||||
struct IntegratorParameters {
|
struct IntegratorParameters {
|
||||||
int Nexp;
|
unsigned int
|
||||||
int MDsteps; // number of outer steps
|
Nexp; // number of terms in the Taylor expansion of the exponential
|
||||||
RealD trajL; // trajectory length
|
unsigned int MDsteps; // number of outer steps
|
||||||
RealD stepsize;
|
RealD trajL; // trajectory length
|
||||||
|
RealD stepsize; // trajectory stepsize
|
||||||
|
|
||||||
IntegratorParameters(int MDsteps_, RealD trajL_ = 1.0, int Nexp_ = 12)
|
IntegratorParameters(int MDsteps_, RealD trajL_ = 1.0,
|
||||||
|
unsigned int Nexp_ = 12)
|
||||||
: Nexp(Nexp_),
|
: Nexp(Nexp_),
|
||||||
MDsteps(MDsteps_),
|
MDsteps(MDsteps_),
|
||||||
trajL(trajL_),
|
trajL(trajL_),
|
||||||
stepsize(trajL / MDsteps){
|
stepsize(trajL / MDsteps){
|
||||||
// empty body constructor
|
// empty body constructor
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void print_parameters() {
|
||||||
|
std::cout << GridLogMessage << "[Integrator] Trajectory length : " << trajL << std::endl;
|
||||||
|
std::cout << GridLogMessage << "[Integrator] Number of MD steps : " << MDsteps << std::endl;
|
||||||
|
std::cout << GridLogMessage << "[Integrator] Step size : " << stepsize << std::endl;
|
||||||
|
std::cout << GridLogMessage << "[Integrator] Exponential approx.: " << Nexp << std::endl;
|
||||||
|
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! @brief Class for Molecular Dynamics management */
|
/*! @brief Class for Molecular Dynamics management */
|
||||||
template <class GaugeField, class SmearingPolicy, class RepresentationPolicy>
|
template <class FieldImplementation, class SmearingPolicy, class RepresentationPolicy>
|
||||||
class Integrator {
|
class Integrator {
|
||||||
protected:
|
protected:
|
||||||
typedef IntegratorParameters ParameterType;
|
typedef IntegratorParameters ParameterType;
|
||||||
|
typedef typename FieldImplementation::Field MomentaField; //for readability
|
||||||
|
typedef typename FieldImplementation::Field Field;
|
||||||
|
|
||||||
IntegratorParameters Params;
|
IntegratorParameters Params;
|
||||||
|
|
||||||
const ActionSet<GaugeField, RepresentationPolicy> as;
|
const ActionSet<Field, RepresentationPolicy> as;
|
||||||
|
|
||||||
int levels; //
|
int levels; //
|
||||||
double t_U; // Track time passing on each level and for U and for P
|
double t_U; // Track time passing on each level and for U and for P
|
||||||
std::vector<double> t_P; //
|
std::vector<double> t_P; //
|
||||||
|
|
||||||
GaugeField P;
|
MomentaField P;
|
||||||
|
|
||||||
SmearingPolicy& Smearer;
|
SmearingPolicy& Smearer;
|
||||||
|
|
||||||
RepresentationPolicy Representations;
|
RepresentationPolicy Representations;
|
||||||
|
|
||||||
// Should match any legal (SU(n)) gauge field
|
void update_P(Field& U, int level, double ep) {
|
||||||
// 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) {
|
|
||||||
typedef Lattice<iScalar<iScalar<iMatrix<vec, Ncol> > > > GaugeLinkField;
|
|
||||||
GaugeLinkField Pmu(P._grid);
|
|
||||||
Pmu = zero;
|
|
||||||
for (int mu = 0; mu < Nd; mu++) {
|
|
||||||
SU<Ncol>::GaussianFundamentalLieAlgebraMatrix(pRNG, Pmu);
|
|
||||||
PokeIndex<LorentzIndex>(P, Pmu, mu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ObserverList observers; // not yet
|
|
||||||
// typedef std::vector<Observer*> ObserverList;
|
|
||||||
// void register_observers();
|
|
||||||
// void notify_observers();
|
|
||||||
|
|
||||||
void update_P(GaugeField& U, int level, double ep) {
|
|
||||||
t_P[level] += ep;
|
t_P[level] += ep;
|
||||||
update_P(P, U, level, ep);
|
update_P(P, U, level, ep);
|
||||||
|
|
||||||
@ -129,12 +122,12 @@ class Integrator {
|
|||||||
}
|
}
|
||||||
} update_P_hireps{};
|
} update_P_hireps{};
|
||||||
|
|
||||||
void update_P(GaugeField& Mom, GaugeField& U, int level, double ep) {
|
void update_P(MomentaField& Mom, Field& U, int level, double ep) {
|
||||||
// input U actually not used in the fundamental case
|
// input U actually not used in the fundamental case
|
||||||
// Fundamental updates, include smearing
|
// Fundamental updates, include smearing
|
||||||
for (int a = 0; a < as[level].actions.size(); ++a) {
|
for (int a = 0; a < as[level].actions.size(); ++a) {
|
||||||
GaugeField force(U._grid);
|
Field force(U._grid);
|
||||||
GaugeField& Us = Smearer.get_U(as[level].actions.at(a)->is_smeared);
|
Field& Us = Smearer.get_U(as[level].actions.at(a)->is_smeared);
|
||||||
as[level].actions.at(a)->deriv(Us, force); // deriv should NOT include Ta
|
as[level].actions.at(a)->deriv(Us, force); // deriv should NOT include Ta
|
||||||
|
|
||||||
std::cout << GridLogIntegrator
|
std::cout << GridLogIntegrator
|
||||||
@ -152,7 +145,7 @@ class Integrator {
|
|||||||
as[level].apply(update_P_hireps, Representations, Mom, U, ep);
|
as[level].apply(update_P_hireps, Representations, Mom, U, ep);
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_U(GaugeField& U, double ep) {
|
void update_U(Field& U, double ep) {
|
||||||
update_U(P, U, ep);
|
update_U(P, U, ep);
|
||||||
|
|
||||||
t_U += ep;
|
t_U += ep;
|
||||||
@ -161,26 +154,21 @@ class Integrator {
|
|||||||
<< "[" << fl << "] U "
|
<< "[" << fl << "] U "
|
||||||
<< " dt " << ep << " : t_U " << t_U << std::endl;
|
<< " dt " << ep << " : t_U " << t_U << std::endl;
|
||||||
}
|
}
|
||||||
void update_U(GaugeField& Mom, GaugeField& U, double ep) {
|
void update_U(MomentaField& Mom, Field& U, double ep) {
|
||||||
// rewrite exponential to deal internally with the lorentz index?
|
FieldImplementation::update_field(Mom, U, ep, Params.Nexp);
|
||||||
for (int mu = 0; mu < Nd; mu++) {
|
|
||||||
auto Umu = PeekIndex<LorentzIndex>(U, mu);
|
|
||||||
auto Pmu = PeekIndex<LorentzIndex>(Mom, mu);
|
|
||||||
Umu = expMat(Pmu, ep, Params.Nexp) * Umu;
|
|
||||||
PokeIndex<LorentzIndex>(U, ProjectOnGroup(Umu), mu);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the smeared fields, can be implemented as observer
|
// Update the smeared fields, can be implemented as observer
|
||||||
Smearer.set_GaugeField(U);
|
Smearer.set_Field(U);
|
||||||
|
|
||||||
// Update the higher representations fields
|
// Update the higher representations fields
|
||||||
Representations.update(U); // void functions if fundamental representation
|
Representations.update(U); // void functions if fundamental representation
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void step(GaugeField& U, int level, int first, int last) = 0;
|
virtual void step(Field& U, int level, int first, int last) = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Integrator(GridBase* grid, IntegratorParameters Par,
|
Integrator(GridBase* grid, IntegratorParameters Par,
|
||||||
ActionSet<GaugeField, RepresentationPolicy>& Aset,
|
ActionSet<Field, RepresentationPolicy>& Aset,
|
||||||
SmearingPolicy& Sm)
|
SmearingPolicy& Sm)
|
||||||
: Params(Par),
|
: Params(Par),
|
||||||
as(Aset),
|
as(Aset),
|
||||||
@ -195,6 +183,13 @@ class Integrator {
|
|||||||
|
|
||||||
virtual ~Integrator() {}
|
virtual ~Integrator() {}
|
||||||
|
|
||||||
|
virtual std::string integrator_name() = 0;
|
||||||
|
|
||||||
|
void print_parameters(){
|
||||||
|
std::cout << GridLogMessage << "[Integrator] Name : "<< integrator_name() << std::endl;
|
||||||
|
Params.print_parameters();
|
||||||
|
}
|
||||||
|
|
||||||
// to be used by the actionlevel class to iterate
|
// to be used by the actionlevel class to iterate
|
||||||
// over the representations
|
// over the representations
|
||||||
struct _refresh {
|
struct _refresh {
|
||||||
@ -210,14 +205,14 @@ class Integrator {
|
|||||||
} refresh_hireps{};
|
} refresh_hireps{};
|
||||||
|
|
||||||
// Initialization of momenta and actions
|
// Initialization of momenta and actions
|
||||||
void refresh(GaugeField& U, GridParallelRNG& pRNG) {
|
void refresh(Field& U, GridParallelRNG& pRNG) {
|
||||||
std::cout << GridLogIntegrator << "Integrator refresh\n";
|
std::cout << GridLogIntegrator << "Integrator refresh\n";
|
||||||
generate_momenta(P, pRNG);
|
FieldImplementation::generate_momenta(P, pRNG);
|
||||||
|
|
||||||
// Update the smeared fields, can be implemented as observer
|
// Update the smeared fields, can be implemented as observer
|
||||||
// necessary to keep the fields updated even after a reject
|
// necessary to keep the fields updated even after a reject
|
||||||
// of the Metropolis
|
// of the Metropolis
|
||||||
Smearer.set_GaugeField(U);
|
Smearer.set_Field(U);
|
||||||
// Set the (eventual) representations gauge fields
|
// Set the (eventual) representations gauge fields
|
||||||
Representations.update(U);
|
Representations.update(U);
|
||||||
|
|
||||||
@ -228,7 +223,7 @@ class Integrator {
|
|||||||
for (int actionID = 0; actionID < as[level].actions.size(); ++actionID) {
|
for (int actionID = 0; actionID < as[level].actions.size(); ++actionID) {
|
||||||
// get gauge field from the SmearingPolicy and
|
// get gauge field from the SmearingPolicy and
|
||||||
// based on the boolean is_smeared in actionID
|
// based on the boolean is_smeared in actionID
|
||||||
GaugeField& Us =
|
Field& Us =
|
||||||
Smearer.get_U(as[level].actions.at(actionID)->is_smeared);
|
Smearer.get_U(as[level].actions.at(actionID)->is_smeared);
|
||||||
as[level].actions.at(actionID)->refresh(Us, pRNG);
|
as[level].actions.at(actionID)->refresh(Us, pRNG);
|
||||||
}
|
}
|
||||||
@ -256,11 +251,12 @@ class Integrator {
|
|||||||
} S_hireps{};
|
} S_hireps{};
|
||||||
|
|
||||||
// Calculate action
|
// Calculate action
|
||||||
RealD S(GaugeField& U) { // here also U not used
|
RealD S(Field& U) { // here also U not used
|
||||||
|
|
||||||
LatticeComplex Hloc(U._grid);
|
LatticeComplex Hloc(U._grid);
|
||||||
Hloc = zero;
|
Hloc = zero;
|
||||||
// Momenta
|
// Momenta --- modify this (take the trace of field)
|
||||||
|
// momenta_action()
|
||||||
for (int mu = 0; mu < Nd; mu++) {
|
for (int mu = 0; mu < Nd; mu++) {
|
||||||
auto Pmu = PeekIndex<LorentzIndex>(P, mu);
|
auto Pmu = PeekIndex<LorentzIndex>(P, mu);
|
||||||
Hloc -= trace(Pmu * Pmu);
|
Hloc -= trace(Pmu * Pmu);
|
||||||
@ -276,7 +272,7 @@ class Integrator {
|
|||||||
for (int actionID = 0; actionID < as[level].actions.size(); ++actionID) {
|
for (int actionID = 0; actionID < as[level].actions.size(); ++actionID) {
|
||||||
// get gauge field from the SmearingPolicy and
|
// get gauge field from the SmearingPolicy and
|
||||||
// based on the boolean is_smeared in actionID
|
// based on the boolean is_smeared in actionID
|
||||||
GaugeField& Us =
|
Field& Us =
|
||||||
Smearer.get_U(as[level].actions.at(actionID)->is_smeared);
|
Smearer.get_U(as[level].actions.at(actionID)->is_smeared);
|
||||||
Hterm = as[level].actions.at(actionID)->S(Us);
|
Hterm = as[level].actions.at(actionID)->S(Us);
|
||||||
std::cout << GridLogMessage << "S Level " << level << " term "
|
std::cout << GridLogMessage << "S Level " << level << " term "
|
||||||
@ -289,7 +285,7 @@ class Integrator {
|
|||||||
return H;
|
return H;
|
||||||
}
|
}
|
||||||
|
|
||||||
void integrate(GaugeField& U) {
|
void integrate(Field& U) {
|
||||||
// reset the clocks
|
// reset the clocks
|
||||||
t_U = 0;
|
t_U = 0;
|
||||||
for (int level = 0; level < as.size(); ++level) {
|
for (int level = 0; level < as.size(); ++level) {
|
||||||
@ -312,7 +308,12 @@ class Integrator {
|
|||||||
// and that we indeed got to the end of the trajectory
|
// and that we indeed got to the end of the trajectory
|
||||||
assert(fabs(t_U - Params.trajL) < 1.0e-6);
|
assert(fabs(t_U - Params.trajL) < 1.0e-6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // INTEGRATOR_INCLUDED
|
#endif // INTEGRATOR_INCLUDED
|
||||||
|
|
||||||
|
@ -1,287 +1,291 @@
|
|||||||
/*************************************************************************************
|
/*************************************************************************************
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
Source file: ./lib/qcd/hmc/integrators/Integrator_algorithm.h
|
Source file: ./lib/qcd/hmc/integrators/Integrator_algorithm.h
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015
|
||||||
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||||
Author: neo <cossu@post.kek.jp>
|
Author: neo <cossu@post.kek.jp>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
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.,
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
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 */
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
/*! @file Integrator_algorithm.h
|
/*! @file Integrator_algorithm.h
|
||||||
* @brief Declaration of classes for the Molecular Dynamics algorithms
|
* @brief Declaration of classes for the Molecular Dynamics algorithms
|
||||||
*
|
*
|
||||||
* @author Guido Cossu
|
|
||||||
*/
|
*/
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
#ifndef INTEGRATOR_ALG_INCLUDED
|
#ifndef INTEGRATOR_ALG_INCLUDED
|
||||||
#define INTEGRATOR_ALG_INCLUDED
|
#define INTEGRATOR_ALG_INCLUDED
|
||||||
|
|
||||||
namespace Grid{
|
namespace Grid {
|
||||||
namespace QCD{
|
namespace QCD {
|
||||||
|
|
||||||
/* PAB:
|
/* PAB:
|
||||||
*
|
*
|
||||||
* Recursive leapfrog; explanation of nested stepping
|
* Recursive leapfrog; explanation of nested stepping
|
||||||
*
|
*
|
||||||
* Nested 1:4; units in dt for top level integrator
|
* Nested 1:4; units in dt for top level integrator
|
||||||
*
|
*
|
||||||
* CHROMA IroIro
|
* CHROMA IroIro
|
||||||
* 0 1 0
|
* 0 1 0
|
||||||
* P 1/2 P 1/2
|
* P 1/2 P 1/2
|
||||||
* P 1/16 P1/16
|
* P 1/16 P1/16
|
||||||
* U 1/8 U1/8
|
* U 1/8 U1/8
|
||||||
* P 1/8 P1/8
|
* P 1/8 P1/8
|
||||||
* U 1/8 U1/8
|
* U 1/8 U1/8
|
||||||
* P 1/8 P1/8
|
* P 1/8 P1/8
|
||||||
* U 1/8 U1/8
|
* U 1/8 U1/8
|
||||||
* P 1/8 P1/8
|
* P 1/8 P1/8
|
||||||
* U 1/8 U1/8
|
* U 1/8 U1/8
|
||||||
* P 1/16 P1/8
|
* P 1/16 P1/8
|
||||||
* P 1 P 1
|
* P 1 P 1
|
||||||
* P 1/16 * skipped --- avoids revaluating force
|
* P 1/16 * skipped --- avoids revaluating force
|
||||||
* U 1/8 U1/8
|
* U 1/8 U1/8
|
||||||
* P 1/8 P1/8
|
* P 1/8 P1/8
|
||||||
* U 1/8 U1/8
|
* U 1/8 U1/8
|
||||||
* P 1/8 P1/8
|
* P 1/8 P1/8
|
||||||
* U 1/8 U1/8
|
* U 1/8 U1/8
|
||||||
* P 1/8 P1/8
|
* P 1/8 P1/8
|
||||||
* U 1/8 U1/8
|
* U 1/8 U1/8
|
||||||
* P 1/16 P1/8
|
* P 1/16 P1/8
|
||||||
* P 1 P 1
|
* P 1 P 1
|
||||||
* P 1/16 * skipped
|
* P 1/16 * skipped
|
||||||
* U 1/8 U1/8
|
* U 1/8 U1/8
|
||||||
* P 1/8 P1/8
|
* P 1/8 P1/8
|
||||||
* U 1/8 U1/8
|
* U 1/8 U1/8
|
||||||
* P 1/8 P1/8
|
* P 1/8 P1/8
|
||||||
* U 1/8 U1/8
|
* U 1/8 U1/8
|
||||||
* P 1/8 P1/8
|
* P 1/8 P1/8
|
||||||
* U 1/8 U1/8
|
* U 1/8 U1/8
|
||||||
* P 1/16 * skipped
|
* P 1/16 * skipped
|
||||||
* P 1 P 1
|
* P 1 P 1
|
||||||
* P 1/16 P1/8
|
* P 1/16 P1/8
|
||||||
* U 1/8 U1/8
|
* U 1/8 U1/8
|
||||||
* P 1/8 P1/8
|
* P 1/8 P1/8
|
||||||
* U 1/8 U1/8
|
* U 1/8 U1/8
|
||||||
* P 1/8 P1/8
|
* P 1/8 P1/8
|
||||||
* U 1/8 U1/8
|
* U 1/8 U1/8
|
||||||
* P 1/8 P1/8
|
* P 1/8 P1/8
|
||||||
* U 1/8 U1/8
|
* U 1/8 U1/8
|
||||||
* P 1/16 P1/16
|
* P 1/16 P1/16
|
||||||
* P 1/2 P 1/2
|
* P 1/2 P 1/2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template<class GaugeField,
|
template <class FieldImplementation, class SmearingPolicy,
|
||||||
class SmearingPolicy,
|
class RepresentationPolicy =
|
||||||
class RepresentationPolicy = Representations< FundamentalRepresentation > > class LeapFrog :
|
Representations<FundamentalRepresentation> >
|
||||||
public Integrator<GaugeField, SmearingPolicy, RepresentationPolicy> {
|
class LeapFrog : public Integrator<FieldImplementation, SmearingPolicy,
|
||||||
public:
|
RepresentationPolicy> {
|
||||||
|
public:
|
||||||
|
typedef LeapFrog<FieldImplementation, SmearingPolicy, RepresentationPolicy>
|
||||||
|
Algorithm;
|
||||||
|
INHERIT_FIELD_TYPES(FieldImplementation);
|
||||||
|
|
||||||
typedef LeapFrog<GaugeField, SmearingPolicy, RepresentationPolicy> Algorithm;
|
std::string integrator_name(){return "LeapFrog";}
|
||||||
|
|
||||||
LeapFrog(GridBase* grid,
|
LeapFrog(GridBase* grid, IntegratorParameters Par,
|
||||||
IntegratorParameters Par,
|
ActionSet<Field, RepresentationPolicy>& Aset, SmearingPolicy& Sm)
|
||||||
ActionSet<GaugeField, RepresentationPolicy> & Aset,
|
: Integrator<FieldImplementation, SmearingPolicy, RepresentationPolicy>(
|
||||||
SmearingPolicy & Sm):
|
grid, Par, Aset, Sm){};
|
||||||
Integrator<GaugeField, SmearingPolicy, RepresentationPolicy>(grid,Par,Aset,Sm) {};
|
|
||||||
|
|
||||||
|
void step(Field& U, int level, int _first, int _last) {
|
||||||
|
int fl = this->as.size() - 1;
|
||||||
|
// level : current level
|
||||||
|
// fl : final level
|
||||||
|
// eps : current step size
|
||||||
|
|
||||||
void step (GaugeField& U, int level,int _first, int _last){
|
// Get current level step size
|
||||||
|
RealD eps = this->Params.stepsize;
|
||||||
|
for (int l = 0; l <= level; ++l) eps /= this->as[l].multiplier;
|
||||||
|
|
||||||
int fl = this->as.size() -1;
|
int multiplier = this->as[level].multiplier;
|
||||||
// level : current level
|
for (int e = 0; e < multiplier; ++e) {
|
||||||
// fl : final level
|
int first_step = _first && (e == 0);
|
||||||
// eps : current step size
|
int last_step = _last && (e == multiplier - 1);
|
||||||
|
|
||||||
// Get current level step size
|
if (first_step) { // initial half step
|
||||||
RealD eps = this->Params.stepsize;
|
this->update_P(U, level, eps / 2.0);
|
||||||
for(int l=0; l<=level; ++l) eps/= this->as[l].multiplier;
|
|
||||||
|
|
||||||
int multiplier = this->as[level].multiplier;
|
|
||||||
for(int e=0; e<multiplier; ++e){
|
|
||||||
|
|
||||||
int first_step = _first && (e==0);
|
|
||||||
int last_step = _last && (e==multiplier-1);
|
|
||||||
|
|
||||||
if(first_step){ // initial half step
|
|
||||||
this->update_P(U, level,eps/2.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(level == fl){ // lowest level
|
|
||||||
this->update_U(U, eps);
|
|
||||||
}else{ // recursive function call
|
|
||||||
this->step(U, level+1,first_step,last_step);
|
|
||||||
}
|
|
||||||
|
|
||||||
int mm = last_step ? 1 : 2;
|
|
||||||
this->update_P(U, level,mm*eps/2.0);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class GaugeField,
|
|
||||||
class SmearingPolicy,
|
|
||||||
class RepresentationPolicy = Representations < FundamentalRepresentation > > class MinimumNorm2 :
|
|
||||||
public Integrator<GaugeField, SmearingPolicy, RepresentationPolicy> {
|
|
||||||
private:
|
|
||||||
const RealD lambda = 0.1931833275037836;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
MinimumNorm2(GridBase* grid,
|
|
||||||
IntegratorParameters Par,
|
|
||||||
ActionSet<GaugeField, RepresentationPolicy> & Aset,
|
|
||||||
SmearingPolicy& Sm):
|
|
||||||
Integrator<GaugeField, SmearingPolicy, RepresentationPolicy>(grid,Par,Aset,Sm) {};
|
|
||||||
|
|
||||||
void step (GaugeField& U, int level, int _first,int _last){
|
|
||||||
|
|
||||||
// level : current level
|
|
||||||
// fl : final level
|
|
||||||
// eps : current step size
|
|
||||||
|
|
||||||
int fl = this->as.size() -1;
|
|
||||||
|
|
||||||
RealD eps = this->Params.stepsize*2.0;
|
|
||||||
for(int l=0; l<=level; ++l) eps/= 2.0*this->as[l].multiplier;
|
|
||||||
|
|
||||||
// Nesting: 2xupdate_U of size eps/2
|
|
||||||
// Next level is eps/2/multiplier
|
|
||||||
|
|
||||||
int multiplier = this->as[level].multiplier;
|
|
||||||
for(int e=0; e<multiplier; ++e){ // steps per step
|
|
||||||
|
|
||||||
int first_step = _first && (e==0);
|
|
||||||
int last_step = _last && (e==multiplier-1);
|
|
||||||
|
|
||||||
if(first_step){ // initial half step
|
|
||||||
this->update_P(U,level,lambda*eps);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(level == fl){ // lowest level
|
|
||||||
this->update_U(U,0.5*eps);
|
|
||||||
}else{ // recursive function call
|
|
||||||
this->step(U,level+1,first_step,0);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->update_P(U,level,(1.0-2.0*lambda)*eps);
|
|
||||||
|
|
||||||
if(level == fl){ // lowest level
|
|
||||||
this->update_U(U,0.5*eps);
|
|
||||||
}else{ // recursive function call
|
|
||||||
this->step(U,level+1,0,last_step);
|
|
||||||
}
|
|
||||||
|
|
||||||
int mm = (last_step) ? 1 : 2;
|
|
||||||
this->update_P(U,level,lambda*eps*mm);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template<class GaugeField,
|
|
||||||
class SmearingPolicy,
|
|
||||||
class RepresentationPolicy = Representations< FundamentalRepresentation > > class ForceGradient :
|
|
||||||
public Integrator<GaugeField, SmearingPolicy, RepresentationPolicy> {
|
|
||||||
private:
|
|
||||||
const RealD lambda = 1.0/6.0;;
|
|
||||||
const RealD chi = 1.0/72.0;
|
|
||||||
const RealD xi = 0.0;
|
|
||||||
const RealD theta = 0.0;
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Looks like dH scales as dt^4. tested wilson/wilson 2 level.
|
|
||||||
ForceGradient(GridBase* grid,
|
|
||||||
IntegratorParameters Par,
|
|
||||||
ActionSet<GaugeField, RepresentationPolicy> & Aset,
|
|
||||||
SmearingPolicy &Sm):
|
|
||||||
Integrator<GaugeField, SmearingPolicy, RepresentationPolicy>(grid,Par,Aset, Sm) {};
|
|
||||||
|
|
||||||
|
|
||||||
void FG_update_P(GaugeField&U, int level,double fg_dt,double ep){
|
|
||||||
GaugeField Ufg(U._grid);
|
|
||||||
GaugeField Pfg(U._grid);
|
|
||||||
Ufg = U;
|
|
||||||
Pfg = zero;
|
|
||||||
std::cout << GridLogMessage << "FG update "<<fg_dt<<" "<<ep<<std::endl;
|
|
||||||
// prepare_fg; no prediction/result cache for now
|
|
||||||
// could relax CG stopping conditions for the
|
|
||||||
// derivatives in the small step since the force gets multiplied by
|
|
||||||
// a tiny dt^2 term relative to main force.
|
|
||||||
//
|
|
||||||
// Presently 4 force evals, and should have 3, so 1.33x too expensive.
|
|
||||||
// could reduce this with sloppy CG to perhaps 1.15x too expensive
|
|
||||||
// even without prediction.
|
|
||||||
this->update_P(Pfg,Ufg,level,1.0);
|
|
||||||
this->update_U(Pfg,Ufg,fg_dt);
|
|
||||||
this->update_P(Ufg,level,ep);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void step (GaugeField& U, int level, int _first,int _last){
|
if (level == fl) { // lowest level
|
||||||
|
this->update_U(U, eps);
|
||||||
RealD eps = this->Params.stepsize*2.0;
|
} else { // recursive function call
|
||||||
for(int l=0; l<=level; ++l) eps/= 2.0*this->as[l].multiplier;
|
this->step(U, level + 1, first_step, last_step);
|
||||||
|
|
||||||
RealD Chi = chi*eps*eps*eps;
|
|
||||||
|
|
||||||
int fl = this->as.size() -1;
|
|
||||||
|
|
||||||
int multiplier = this->as[level].multiplier;
|
|
||||||
|
|
||||||
for(int e=0; e<multiplier; ++e){ // steps per step
|
|
||||||
|
|
||||||
|
|
||||||
int first_step = _first && (e==0);
|
|
||||||
int last_step = _last && (e==multiplier-1);
|
|
||||||
|
|
||||||
if(first_step){ // initial half step
|
|
||||||
this->update_P(U,level,lambda*eps);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(level == fl){ // lowest level
|
|
||||||
this->update_U(U,0.5*eps);
|
|
||||||
}else{ // recursive function call
|
|
||||||
this->step(U,level+1,first_step,0);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->FG_update_P(U,level,2*Chi/((1.0-2.0*lambda)*eps),(1.0-2.0*lambda)*eps);
|
|
||||||
|
|
||||||
if(level == fl){ // lowest level
|
|
||||||
this->update_U(U,0.5*eps);
|
|
||||||
}else{ // recursive function call
|
|
||||||
this->step(U,level+1,0,last_step);
|
|
||||||
}
|
|
||||||
|
|
||||||
int mm = (last_step) ? 1 : 2;
|
|
||||||
this->update_P(U,level,lambda*eps*mm);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
|
int mm = last_step ? 1 : 2;
|
||||||
|
this->update_P(U, level, mm * eps / 2.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class FieldImplementation, class SmearingPolicy,
|
||||||
|
class RepresentationPolicy =
|
||||||
|
Representations<FundamentalRepresentation> >
|
||||||
|
class MinimumNorm2 : public Integrator<FieldImplementation, SmearingPolicy,
|
||||||
|
RepresentationPolicy> {
|
||||||
|
private:
|
||||||
|
const RealD lambda = 0.1931833275037836;
|
||||||
|
|
||||||
|
public:
|
||||||
|
INHERIT_FIELD_TYPES(FieldImplementation);
|
||||||
|
|
||||||
|
MinimumNorm2(GridBase* grid, IntegratorParameters Par,
|
||||||
|
ActionSet<Field, RepresentationPolicy>& Aset, SmearingPolicy& Sm)
|
||||||
|
: Integrator<FieldImplementation, SmearingPolicy, RepresentationPolicy>(
|
||||||
|
grid, Par, Aset, Sm){};
|
||||||
|
|
||||||
|
std::string integrator_name(){return "MininumNorm2";}
|
||||||
|
|
||||||
|
void step(Field& U, int level, int _first, int _last) {
|
||||||
|
// level : current level
|
||||||
|
// fl : final level
|
||||||
|
// eps : current step size
|
||||||
|
|
||||||
|
int fl = this->as.size() - 1;
|
||||||
|
|
||||||
|
RealD eps = this->Params.stepsize * 2.0;
|
||||||
|
for (int l = 0; l <= level; ++l) eps /= 2.0 * this->as[l].multiplier;
|
||||||
|
|
||||||
|
// Nesting: 2xupdate_U of size eps/2
|
||||||
|
// Next level is eps/2/multiplier
|
||||||
|
|
||||||
|
int multiplier = this->as[level].multiplier;
|
||||||
|
for (int e = 0; e < multiplier; ++e) { // steps per step
|
||||||
|
|
||||||
|
int first_step = _first && (e == 0);
|
||||||
|
int last_step = _last && (e == multiplier - 1);
|
||||||
|
|
||||||
|
if (first_step) { // initial half step
|
||||||
|
this->update_P(U, level, lambda * eps);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (level == fl) { // lowest level
|
||||||
|
this->update_U(U, 0.5 * eps);
|
||||||
|
} else { // recursive function call
|
||||||
|
this->step(U, level + 1, first_step, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->update_P(U, level, (1.0 - 2.0 * lambda) * eps);
|
||||||
|
|
||||||
|
if (level == fl) { // lowest level
|
||||||
|
this->update_U(U, 0.5 * eps);
|
||||||
|
} else { // recursive function call
|
||||||
|
this->step(U, level + 1, 0, last_step);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mm = (last_step) ? 1 : 2;
|
||||||
|
this->update_P(U, level, lambda * eps * mm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class FieldImplementation, class SmearingPolicy,
|
||||||
|
class RepresentationPolicy =
|
||||||
|
Representations<FundamentalRepresentation> >
|
||||||
|
class ForceGradient : public Integrator<FieldImplementation, SmearingPolicy,
|
||||||
|
RepresentationPolicy> {
|
||||||
|
private:
|
||||||
|
const RealD lambda = 1.0 / 6.0;
|
||||||
|
;
|
||||||
|
const RealD chi = 1.0 / 72.0;
|
||||||
|
const RealD xi = 0.0;
|
||||||
|
const RealD theta = 0.0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
INHERIT_FIELD_TYPES(FieldImplementation);
|
||||||
|
|
||||||
|
// Looks like dH scales as dt^4. tested wilson/wilson 2 level.
|
||||||
|
ForceGradient(GridBase* grid, IntegratorParameters Par,
|
||||||
|
ActionSet<Field, RepresentationPolicy>& Aset,
|
||||||
|
SmearingPolicy& Sm)
|
||||||
|
: Integrator<FieldImplementation, SmearingPolicy, RepresentationPolicy>(
|
||||||
|
grid, Par, Aset, Sm){};
|
||||||
|
|
||||||
|
std::string integrator_name(){return "ForceGradient";}
|
||||||
|
|
||||||
|
void FG_update_P(Field& U, int level, double fg_dt, double ep) {
|
||||||
|
Field Ufg(U._grid);
|
||||||
|
Field Pfg(U._grid);
|
||||||
|
Ufg = U;
|
||||||
|
Pfg = zero;
|
||||||
|
std::cout << GridLogMessage << "FG update " << fg_dt << " " << ep
|
||||||
|
<< std::endl;
|
||||||
|
// prepare_fg; no prediction/result cache for now
|
||||||
|
// could relax CG stopping conditions for the
|
||||||
|
// derivatives in the small step since the force gets multiplied by
|
||||||
|
// a tiny dt^2 term relative to main force.
|
||||||
|
//
|
||||||
|
// Presently 4 force evals, and should have 3, so 1.33x too expensive.
|
||||||
|
// could reduce this with sloppy CG to perhaps 1.15x too expensive
|
||||||
|
// even without prediction.
|
||||||
|
this->update_P(Pfg, Ufg, level, 1.0);
|
||||||
|
this->update_U(Pfg, Ufg, fg_dt);
|
||||||
|
this->update_P(Ufg, level, ep);
|
||||||
|
}
|
||||||
|
|
||||||
|
void step(Field& U, int level, int _first, int _last) {
|
||||||
|
RealD eps = this->Params.stepsize * 2.0;
|
||||||
|
for (int l = 0; l <= level; ++l) eps /= 2.0 * this->as[l].multiplier;
|
||||||
|
|
||||||
|
RealD Chi = chi * eps * eps * eps;
|
||||||
|
|
||||||
|
int fl = this->as.size() - 1;
|
||||||
|
|
||||||
|
int multiplier = this->as[level].multiplier;
|
||||||
|
|
||||||
|
for (int e = 0; e < multiplier; ++e) { // steps per step
|
||||||
|
|
||||||
|
int first_step = _first && (e == 0);
|
||||||
|
int last_step = _last && (e == multiplier - 1);
|
||||||
|
|
||||||
|
if (first_step) { // initial half step
|
||||||
|
this->update_P(U, level, lambda * eps);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (level == fl) { // lowest level
|
||||||
|
this->update_U(U, 0.5 * eps);
|
||||||
|
} else { // recursive function call
|
||||||
|
this->step(U, level + 1, first_step, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->FG_update_P(U, level, 2 * Chi / ((1.0 - 2.0 * lambda) * eps),
|
||||||
|
(1.0 - 2.0 * lambda) * eps);
|
||||||
|
|
||||||
|
if (level == fl) { // lowest level
|
||||||
|
this->update_U(U, 0.5 * eps);
|
||||||
|
} else { // recursive function call
|
||||||
|
this->step(U, level + 1, 0, last_step);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mm = (last_step) ? 1 : 2;
|
||||||
|
this->update_P(U, level, lambda * eps * mm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif//INTEGRATOR_INCLUDED
|
#endif // INTEGRATOR_INCLUDED
|
||||||
|
@ -21,7 +21,7 @@ public:
|
|||||||
|
|
||||||
NoSmearing(): ThinLinks(NULL) {}
|
NoSmearing(): ThinLinks(NULL) {}
|
||||||
|
|
||||||
void set_GaugeField(GaugeField& U) { ThinLinks = &U; }
|
void set_Field(GaugeField& U) { ThinLinks = &U; }
|
||||||
|
|
||||||
void smeared_force(GaugeField& SigmaTilde) const {}
|
void smeared_force(GaugeField& SigmaTilde) const {}
|
||||||
|
|
||||||
@ -227,7 +227,7 @@ class SmearedConfiguration {
|
|||||||
|
|
||||||
|
|
||||||
// attach the smeared routines to the thin links U and fill the smeared set
|
// attach the smeared routines to the thin links U and fill the smeared set
|
||||||
void set_GaugeField(GaugeField& U) { fill_smearedSet(U); }
|
void set_Field(GaugeField& U) { fill_smearedSet(U); }
|
||||||
|
|
||||||
//====================================================================
|
//====================================================================
|
||||||
void smeared_force(GaugeField& SigmaTilde) const {
|
void smeared_force(GaugeField& SigmaTilde) const {
|
||||||
|
Loading…
Reference in New Issue
Block a user