/************************************************************************************* Grid physics library, www.github.com/paboyle/Grid Source file: ./lib/qcd/modules/ActionModules.h Copyright (C) 2016 Author: Guido Cossu 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 ACTION_MODULES_H #define ACTION_MODULES_H /* Define loadable, serializable modules for the HMC execution */ namespace Grid { ////////////////////////////////////////////// // Actions ////////////////////////////////////////////// template class ActionModuleBase: public HMCModuleBase{ public: typedef R Resource; virtual void acquireResource(R& ){}; }; template class ActionModule : public Parametrized, public ActionModuleBase< QCD::Action , QCD::GridModule > { public: typedef ActionModuleBase< QCD::Action, QCD::GridModule > Base; typedef typename Base::Product Product; typedef APar Parameters; std::unique_ptr ActionPtr; ActionModule(APar Par) : Parametrized(Par) {} template ActionModule(Reader& Reader) : Parametrized(Reader){}; virtual void print_parameters(){ Parametrized::print_parameters(); } Product* getPtr() { if (!ActionPtr) initialize(); return ActionPtr.get(); } private: virtual void initialize() = 0; }; ////////////////////////// // Modules ////////////////////////// namespace QCD{ class PlaqPlusRectangleGaugeActionParameters : Serializable { public: GRID_SERIALIZABLE_CLASS_MEMBERS(PlaqPlusRectangleGaugeActionParameters, RealD, c_plaq, RealD, c_rect); }; class RBCGaugeActionParameters : Serializable { public: GRID_SERIALIZABLE_CLASS_MEMBERS(RBCGaugeActionParameters, RealD, beta, RealD, c1); }; class BetaGaugeActionParameters : Serializable { public: GRID_SERIALIZABLE_CLASS_MEMBERS(BetaGaugeActionParameters, RealD, beta); }; template class WilsonGModule: public ActionModule, BetaGaugeActionParameters> { typedef ActionModule, BetaGaugeActionParameters> ActionBase; using ActionBase::ActionBase; // for constructors // acquire resource virtual void initialize(){ this->ActionPtr.reset(new WilsonGaugeAction(this->Par_.beta)); } }; template class PlaqPlusRectangleGModule: public ActionModule, PlaqPlusRectangleGaugeActionParameters> { typedef ActionModule, PlaqPlusRectangleGaugeActionParameters> ActionBase; using ActionBase::ActionBase; // for constructors // acquire resource virtual void initialize(){ this->ActionPtr.reset(new PlaqPlusRectangleAction(this->Par_.c_plaq, this->Par_.c_rect)); } }; template class RBCGModule: public ActionModule, RBCGaugeActionParameters> { typedef ActionModule, RBCGaugeActionParameters> ActionBase; using ActionBase::ActionBase; // for constructors // acquire resource virtual void initialize(){ this->ActionPtr.reset(new RBCGaugeAction(this->Par_.beta, this->Par_.c1)); } }; template class SymanzikGModule: public ActionModule, BetaGaugeActionParameters> { typedef ActionModule, BetaGaugeActionParameters> ActionBase; using ActionBase::ActionBase; // for constructors // acquire resource virtual void initialize(){ this->ActionPtr.reset(new SymanzikGaugeAction(this->Par_.beta)); } }; template class IwasakiGModule: public ActionModule, BetaGaugeActionParameters> { typedef ActionModule, BetaGaugeActionParameters> ActionBase; using ActionBase::ActionBase; // for constructors // acquire resource virtual void initialize(){ this->ActionPtr.reset(new IwasakiGaugeAction(this->Par_.beta)); } }; template class DBW2GModule: public ActionModule, BetaGaugeActionParameters> { typedef ActionModule, BetaGaugeActionParameters> ActionBase; using ActionBase::ActionBase; // for constructors // acquire resource virtual void initialize(){ this->ActionPtr.reset(new DBW2GaugeAction(this->Par_.beta)); } }; ///////////////////////////////////////// // Fermion Actions ///////////////////////////////////////// template class FermionA > class PseudoFermionModuleBase: public ActionModule, NoParameters> { protected: typedef ActionModule, NoParameters> ActionBase; using ActionBase::ActionBase; // for constructors typedef std::unique_ptr> > operator_type; typedef std::unique_ptr > > solver_type; template void getFermionOperator(Reader& Reader, operator_type &fo, std::string section_name){ auto &FOFactory = HMC_FermionOperatorModuleFactory::getInstance(); Reader.push(section_name); std::string op_name; read(Reader,"name", op_name); fo = FOFactory.create(op_name, Reader); Reader.pop(); } template void getSolverOperator(Reader& Reader, solver_type &so, std::string section_name){ auto& SolverFactory = HMC_SolverModuleFactory::getInstance(); Reader.push(section_name); std::string solv_name; read(Reader,"name", solv_name); so = SolverFactory.create(solv_name, Reader); Reader.pop(); } }; template class TwoFlavourFModule: public PseudoFermionModuleBase{ typedef PseudoFermionModuleBase Base; using Base::Base; typename Base::operator_type fop_mod; typename Base::solver_type solver_mod; public: virtual void acquireResource(typename Base::Resource& GridMod){ fop_mod->AddGridPair(GridMod); } // constructor template TwoFlavourFModule(Reader& R): PseudoFermionModuleBase(R) { this->getSolverOperator(R, solver_mod, "Solver"); this->getFermionOperator(R, fop_mod, "Operator"); } // acquire resource virtual void initialize() { // here temporarily assuming that the force and action solver are the same this->ActionPtr.reset(new TwoFlavourPseudoFermionAction(*(this->fop_mod->getPtr()), *(this->solver_mod->getPtr()), *(this->solver_mod->getPtr()))); } }; // very similar, I could have templated this but it is overkilling template class TwoFlavourEOFModule: public PseudoFermionModuleBase{ typedef PseudoFermionModuleBase Base; using Base::Base; typename Base::operator_type fop_mod; typename Base::solver_type solver_mod; public: virtual void acquireResource(typename Base::Resource& GridMod){ fop_mod->AddGridPair(GridMod); } // constructor template TwoFlavourEOFModule(Reader& R): PseudoFermionModuleBase(R) { this->getSolverOperator(R, solver_mod, "Solver"); this->getFermionOperator(R, fop_mod, "Operator"); } // acquire resource virtual void initialize() { // here temporarily assuming that the force and action solver are the same this->ActionPtr.reset(new TwoFlavourEvenOddPseudoFermionAction(*(this->fop_mod->getPtr()), *(this->solver_mod->getPtr()), *(this->solver_mod->getPtr()))); } }; template class TwoFlavourRatioFModule: public PseudoFermionModuleBase{ typedef PseudoFermionModuleBase Base; using Base::Base; typename Base::operator_type fop_numerator_mod; typename Base::operator_type fop_denominator_mod; typename Base::solver_type solver_mod; public: virtual void acquireResource(typename Base::Resource& GridMod){ fop_numerator_mod->AddGridPair(GridMod); fop_denominator_mod->AddGridPair(GridMod); } // constructor template TwoFlavourRatioFModule(Reader& R): PseudoFermionModuleBase(R) { this->getSolverOperator(R, solver_mod, "Solver"); this->getFermionOperator(R, fop_numerator_mod, "Numerator"); this->getFermionOperator(R, fop_denominator_mod, "Denominator"); } // acquire resource virtual void initialize() { // here temporarily assuming that the force and action solver are the same this->ActionPtr.reset(new TwoFlavourRatioPseudoFermionAction(*(this->fop_numerator_mod->getPtr()), *(this->fop_denominator_mod->getPtr()), *(this->solver_mod->getPtr()), *(this->solver_mod->getPtr()))); } }; typedef WilsonGModule WilsonGMod; typedef SymanzikGModule SymanzikGMod; typedef IwasakiGModule IwasakiGMod; typedef DBW2GModule DBW2GMod; typedef RBCGModule RBCGMod; typedef PlaqPlusRectangleGModule PlaqPlusRectangleGMod; }// QCD temporarily here //////////////////////////////////////// // Factories specialisations //////////////////////////////////////// // use the same classed defined by Antonin, does not make sense to rewrite // Factory is perfectly fine // Registar must be changed because I do not want to use the ModuleFactory // explicit ref to LatticeGaugeField must be changed or put in the factory typedef ActionModuleBase< QCD::Action< QCD::LatticeGaugeField >, QCD::GridModule > HMC_LGTActionModBase; template class HMC_LGTActionModuleFactory : public Factory < HMC_LGTActionModBase , Reader > { public: typedef Reader TheReader; // use SINGLETON FUNCTOR MACRO HERE HMC_LGTActionModuleFactory(const HMC_LGTActionModuleFactory& e) = delete; void operator=(const HMC_LGTActionModuleFactory& e) = delete; static HMC_LGTActionModuleFactory& getInstance(void) { static HMC_LGTActionModuleFactory e; return e; } private: HMC_LGTActionModuleFactory(void) = default; std::string obj_type() const { return std::string(str); } }; extern char gauge_string[]; static Registrar > __WGmodXMLInit("Wilson"); static Registrar > __SymGmodXMLInit("Symanzik"); static Registrar > __IwGmodXMLInit("Iwasaki"); static Registrar > __DBW2GmodXMLInit("DBW2"); static Registrar > __RBCGmodXMLInit("RBC"); static Registrar > __PPRectGmodXMLInit("PlaqPlusRect"); // FIXME more general implementation static Registrar , HMC_LGTActionModuleFactory > __TwoFlavourFmodXMLInit("TwoFlavours"); static Registrar , HMC_LGTActionModuleFactory > __TwoFlavourRatioFmodXMLInit("TwoFlavoursRatio"); static Registrar , HMC_LGTActionModuleFactory > __TwoFlavourEOFmodXMLInit("TwoFlavoursEvenOdd"); // add here the registration for other implementations and readers } // Grid #endif //HMC_MODULES_H