#ifndef Hadrons_MSource_Convolution_hpp_ #define Hadrons_MSource_Convolution_hpp_ #include #include #include BEGIN_HADRONS_NAMESPACE /****************************************************************************** * Convolution * ******************************************************************************/ BEGIN_MODULE_NAMESPACE(MSource) class ConvolutionPar: Serializable { public: GRID_SERIALIZABLE_CLASS_MEMBERS(ConvolutionPar, std::string, field1, std::string, field2, std::string, mom); }; template class TConvolution: public Module { public: //BASIC_TYPE_ALIASES(FImpl,); FERM_TYPE_ALIASES(FImpl,); public: // constructor TConvolution(const std::string name); // destructor virtual ~TConvolution(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); // setup virtual void setup(void); // execution virtual void execute(void); private: std::vector mom_; }; MODULE_REGISTER_TMP(Convolution, TConvolution, MSource); //MODULE_REGISTER_TMP(ScalarConvolution, TConvolution, MSource); /****************************************************************************** * TConvolution implementation * ******************************************************************************/ // constructor ///////////////////////////////////////////////////////////////// template TConvolution::TConvolution(const std::string name) : Module(name) {} // dependencies/products /////////////////////////////////////////////////////// template std::vector TConvolution::getInput(void) { std::vector in = {par().field1, par().field2}; return in; } template std::vector TConvolution::getOutput(void) { std::vector out = {getName()}; return out; } // setup /////////////////////////////////////////////////////////////////////// template void TConvolution::setup(void) { mom_ = strToVec(par().mom); if(mom_.size() != env().getNd()-1) { HADRONS_ERROR(Size, std::string("momentum has ") + std::to_string(mom_.size()) + " instead of " + std::to_string(env().getNd()-1) + " components"); } envCreateLat(PropagatorField, getName()); envTmpLat(LatticeComplex, "momfield1"); envTmp(FFT, "fft", 1, env().getGrid()); } // execution /////////////////////////////////////////////////////////////////// template void TConvolution::execute(void) { auto &field1 = envGet(LatticeComplex, par().field1); auto &field2 = envGet(PropagatorField, par().field2); auto &out = envGet(PropagatorField, getName()); envGetTmp(LatticeComplex, momfield1); envGetTmp(FFT, fft); std::vector mask(env().getNd(), 1); mask.back()=0; //transform only the spatial dimensions startTimer("Fourier transform"); fft.FFT_dim_mask(momfield1, field1, mask, FFT::forward); fft.FFT_dim_mask(out, field2, mask, FFT::forward); stopTimer("Fourier transform"); startTimer("momentum-space multiplication"); out=momfield1*out; stopTimer("momentum-space multiplication"); startTimer("adding momentum"); for(int mu=0; mu