/************************************************************************************* 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_BEGIN(Grid); ////////////////////////////////////////////// // Actions ////////////////////////////////////////////// template class ActionModuleBase: public HMCModuleBase{ public: typedef R Resource; virtual void acquireResource(R& ){}; }; template class ActionModule : public Parametrized, public ActionModuleBase< Action , GridModule > { public: typedef ActionModuleBase< Action, 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 ////////////////////////// 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 Params = NoParameters > class PseudoFermionModuleBase: public ActionModule, Params> { protected: typedef ActionModule, Params> 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): Base(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()))); } }; template class TwoFlavourRatioEOFModule: 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 TwoFlavourRatioEOFModule(Reader& R): Base(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 TwoFlavourEvenOddRatioPseudoFermionAction(*(this->fop_numerator_mod->getPtr()), *(this->fop_denominator_mod->getPtr()), *(this->solver_mod->getPtr()), *(this->solver_mod->getPtr()))); } }; template class OneFlavourFModule: public PseudoFermionModuleBase{ typedef PseudoFermionModuleBase Base; using Base::Base; typename Base::operator_type fop_mod; public: virtual void acquireResource(typename Base::Resource& GridMod){ fop_mod->AddGridPair(GridMod); } // constructor template OneFlavourFModule(Reader& R): Base(R) { this->getFermionOperator(R, fop_mod, "Operator"); } // acquire resource virtual void initialize() { this->ActionPtr.reset(new OneFlavourRationalPseudoFermionAction(*(this->fop_mod->getPtr()), this->Par_ )); } }; template class OneFlavourEOFModule: public PseudoFermionModuleBase { typedef PseudoFermionModuleBase Base; using Base::Base; typename Base::operator_type fop_mod; public: virtual void acquireResource(typename Base::Resource& GridMod){ fop_mod->AddGridPair(GridMod); } // constructor template OneFlavourEOFModule(Reader& R): Base(R) { this->getFermionOperator(R, fop_mod, "Operator"); } // acquire resource virtual void initialize() { this->ActionPtr.reset(new OneFlavourEvenOddRationalPseudoFermionAction(*(this->fop_mod->getPtr()), this->Par_ )); } }; template class OneFlavourRatioFModule: public PseudoFermionModuleBase { typedef PseudoFermionModuleBase Base; using Base::Base; typename Base::operator_type fop_numerator_mod; typename Base::operator_type fop_denominator_mod; public: virtual void acquireResource(typename Base::Resource& GridMod){ fop_numerator_mod->AddGridPair(GridMod); fop_denominator_mod->AddGridPair(GridMod); } // constructor template OneFlavourRatioFModule(Reader& R): Base(R) { this->getFermionOperator(R, fop_numerator_mod, "Numerator"); this->getFermionOperator(R, fop_denominator_mod, "Denominator"); } // acquire resource virtual void initialize() { this->ActionPtr.reset(new OneFlavourRatioRationalPseudoFermionAction( *(this->fop_numerator_mod->getPtr()), *(this->fop_denominator_mod->getPtr()), this->Par_ )); } }; template class OneFlavourRatioEOFModule: public PseudoFermionModuleBase { typedef PseudoFermionModuleBase Base; using Base::Base; typename Base::operator_type fop_numerator_mod; typename Base::operator_type fop_denominator_mod; public: virtual void acquireResource(typename Base::Resource& GridMod){ fop_numerator_mod->AddGridPair(GridMod); fop_denominator_mod->AddGridPair(GridMod); } // constructor template OneFlavourRatioEOFModule(Reader& R): Base(R) { this->getFermionOperator(R, fop_numerator_mod, "Numerator"); this->getFermionOperator(R, fop_denominator_mod, "Denominator"); } // acquire resource virtual void initialize() { this->ActionPtr.reset(new OneFlavourEvenOddRatioRationalPseudoFermionAction(*(this->fop_numerator_mod->getPtr()), *(this->fop_denominator_mod->getPtr()), this->Par_ )); } }; //////////////////////////////////////// // 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< Action< LatticeGaugeField >, GridModule > HMC_LGTActionModBase; //typedef ActionModuleBase< Action< LatticeReal >, GridModule > HMC_ScalarActionModBase; template class HMC_ActionModuleFactory : public Factory < ActionModuleBase< Action< Field >, GridModule > , Reader > { public: typedef Reader TheReader; // use SINGLETON FUNCTOR MACRO HERE HMC_ActionModuleFactory(const HMC_ActionModuleFactory& e) = delete; void operator=(const HMC_ActionModuleFactory& e) = delete; static HMC_ActionModuleFactory& getInstance(void) { static HMC_ActionModuleFactory e; return e; } private: HMC_ActionModuleFactory(void) = default; std::string obj_type() const { return std::string(str); } }; extern char gauge_string[]; NAMESPACE_END(Grid); #endif //HMC_MODULES_H