//-------------------------------------------------------------------- /*! @file Integrator_base.h * @brief Declaration of classes for the abstract Molecular Dynamics integrator * * @author Guido Cossu */ //-------------------------------------------------------------------- #ifndef INTEGRATOR_INCLUDED #define INTEGRATOR_INCLUDED #include class Observer; /*! @brief Abstract base class for Molecular Dynamics management */ namespace Grid{ namespace QCD{ typedef Action* ActPtr; // now force the same size as the rest of the code typedef std::vector ActionLevel; typedef std::vector ActionSet; typedef std::vector ObserverList; class LeapFrog; struct IntegratorParameters{ int Nexp; int MDsteps; // number of outer steps RealD trajL; // trajectory length RealD stepsize; IntegratorParameters(int Nexp_, int MDsteps_, RealD trajL_): Nexp(Nexp_),MDsteps(MDsteps_),trajL(trajL_),stepsize(trajL/MDsteps){}; }; namespace MDutils{ void generate_momenta(LatticeLorentzColourMatrix&,GridParallelRNG&); void generate_momenta_su3(LatticeLorentzColourMatrix&,GridParallelRNG&); } template< class IntegratorPolicy > class Integrator{ private: IntegratorParameters Params; const ActionSet as; const std::vector Nrel; //relative step size per level //ObserverList observers; // not yet std::unique_ptr P; IntegratorPolicy TheIntegrator;// contains parameters too void update_P(LatticeLorentzColourMatrix&U, int level,double ep){ for(int a=0; aderiv(U,force); *P -= force*ep; } } void update_U(LatticeLorentzColourMatrix&U, double ep){ //rewrite exponential to deal with the lorentz index? LatticeColourMatrix Umu(U._grid); LatticeColourMatrix Pmu(U._grid); for (int mu = 0; mu < Nd; mu++){ Umu=peekLorentz(U, mu); Pmu=peekLorentz(*P, mu); std::cout << "U norm ["<& clock, Integrator* Integ); public: Integrator(IntegratorParameters Par, ActionSet& Aset, std::vector Nrel_): Params(Par),as(Aset),Nrel(Nrel_){ assert(as.size() == Nrel.size()); }; ~Integrator(){} //Initialization of momenta and actions void init(LatticeLorentzColourMatrix& U, GridParallelRNG& pRNG){ std::cout<< "Integrator init\n"; if (!P){ std::unique_ptr Pnew(new LatticeLorentzColourMatrix(U._grid)); P = std::move(Pnew); } MDutils::generate_momenta(*P,pRNG); for(int level=0; level< as.size(); ++level){ for(int actionID=0; actionIDinit(U, pRNG); } } } RealD S(LatticeLorentzColourMatrix& U){ LatticeComplex Hloc(U._grid); Hloc = zero; // Momenta for (int mu=0; mu S(U); return H; } void integrate(LatticeLorentzColourMatrix& U, int level){ std::vector clock; clock.resize(as.size(),0); for(int step=0; step< Params.MDsteps; ++step) // MD step TheIntegrator.step(U,0,clock, (this)); } }; class MinimumNorm2{ const double lambda = 0.1931833275037836; public: void step (LatticeLorentzColourMatrix& U, int level, std::vector& clock); }; class LeapFrog{ public: void step (LatticeLorentzColourMatrix& U, int level, std::vector& clock, Integrator* Integ){ // cl : current level // fl : final level // eps : current step size int fl = Integ->as.size() -1; double eps = Integ->Params.stepsize; // Get current level step size for(int l=0; l<=level; ++l) eps/= Integ->Nrel[l]; int fin = 1; for(int l=0; l<=level; ++l) fin*= Integ->Nrel[l]; fin = 2*Integ->Params.MDsteps*fin - 1; for(int e=0; eNrel[level]; ++e){ if(clock[level] == 0){ // initial half step Integ->update_P(U, level,eps/2); ++clock[level]; for(int l=0; lupdate_U(U, eps); for(int l=0; lupdate_P(U, level,eps/2); ++clock[level]; for(int l=0; lupdate_P(U, level,eps); clock[level]+=2; for(int l=0; l