/************************************************************************************* Grid physics library, www.github.com/paboyle/Grid Source file: ./lib/qcd/action/gauge/WilsonGaugeAction.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 HMC_MODULES_H #define HMC_MODULES_H /* Define loadable, serializable modules for the HMC execution */ namespace Grid { /* Base class for modules with parameters */ template < class P > class Parametrized{ public: typedef P Parameters; Parametrized(Parameters Par):Par_(Par){}; template Parametrized(Reader & Reader){ read(Reader, section_name(), Par_); } void set_parameters(Parameters Par){ Par_ = Par; } void print_parameters(){ std::cout << Par_ << std::endl; } protected: Parameters Par_; private: // identifies the section name // override in derived classes if needed virtual std::string section_name(){ return std::string("parameters"); //default } }; /* Lowest level abstract module class */ template < class Prod > class HMCModuleBase{ public: typedef Prod Product; virtual Prod* getPtr() = 0; virtual void print_parameters(){}; //default to nothing }; ////////////////////////////////////////////// // Actions ////////////////////////////////////////////// template class ActionModule : public Parametrized, public HMCModuleBase > { public: typedef HMCModuleBase< QCD::Action > Base; typedef typename Base::Product Product; std::unique_ptr ActionPtr; ActionModule(APar Par) : Parametrized(Par) {} template ActionModule(Reader& Reader) : Parametrized(Reader){}; virtual void print_parameters(){ std::cout << this->Par_ << std::endl; } Product* getPtr() { if (!ActionPtr) initialize(); return ActionPtr.get(); } private: virtual void initialize() = 0; }; namespace QCD{ class WilsonGaugeActionParameters : Serializable { public: GRID_SERIALIZABLE_CLASS_MEMBERS(WilsonGaugeActionParameters, RealD, beta); }; template class WilsonGModule: public ActionModule, WilsonGaugeActionParameters> { typedef ActionModule, WilsonGaugeActionParameters> ActionBase; using ActionBase::ActionBase; // for constructors // acquire resource virtual void initialize(){ this->ActionPtr.reset(new WilsonGaugeAction(this->Par_.beta)); } }; typedef WilsonGModule WilsonGMod; }// 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 // ref to LatticeGaugeField must be changed typedef HMCModuleBase< QCD::Action< QCD::LatticeGaugeField > > 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); } }; /* then rewrite the registar when this is done we have all the modules that contain the pointer to the objects (actions, integrators, checkpointers, solvers) factory will create only the modules and prepare the parameters when needed a pointer is released */ template class Registrar { public: Registrar(std::string className) { // register the class factory function TheFactory::getInstance().registerBuilder(className, [&](typename TheFactory::TheReader Reader) { return std::unique_ptr(new T(Reader));}); } }; extern char gauge_string[]; static Registrar > __WGmodXMLInit("Wilson"); } #endif //HMC_MODULES_H