Grid 0.7.0
TwoFlavourEvenOddRatio.h
Go to the documentation of this file.
1 /*************************************************************************************
2
3 Grid physics library, www.github.com/paboyle/Grid
4
5 Source file: ./lib/qcd/action/pseudofermion/TwoFlavourEvenOddRatio.h
6
7 Copyright (C) 2015
8
9Author: Peter Boyle <paboyle@ph.ed.ac.uk>
10Author: paboyle <paboyle@ph.ed.ac.uk>
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License along
23 with this program; if not, write to the Free Software Foundation, Inc.,
24 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25
26 See the full license in the file "LICENSE" in the top level distribution directory
27 *************************************************************************************/
28 /* END LEGAL */
29#ifndef QCD_PSEUDOFERMION_TWO_FLAVOUR_EVEN_ODD_RATIO_H
30#define QCD_PSEUDOFERMION_TWO_FLAVOUR_EVEN_ODD_RATIO_H
31
33
35 // Two flavour ratio
37 template<class Impl>
38 class TwoFlavourEvenOddRatioPseudoFermionAction : public Action<typename Impl::GaugeField> {
39 public:
41
42 private:
43 FermionOperator<Impl> & NumOp;// the basic operator
44 FermionOperator<Impl> & DenOp;// the basic operator
45
49
50 FermionField PhiOdd; // the pseudo fermion field for this trajectory
51 FermionField PhiEven; // the pseudo fermion field for this trajectory
52
54
55 public:
61
63 FermionOperator<Impl> &_DenOp,
66 NumOp(_NumOp),
67 DenOp(_DenOp),
69 ActionSolver(AS),
71 PhiEven(_NumOp.FermionRedBlackGrid()),
72 PhiOdd(_NumOp.FermionRedBlackGrid())
73 {
74 conformable(_NumOp.FermionGrid(), _DenOp.FermionGrid());
76 conformable(_NumOp.GaugeGrid(), _DenOp.GaugeGrid());
78 };
79
80 virtual std::string action_name(){
81 std::stringstream sstream;
82 sstream<<"TwoFlavourEvenOddRatioPseudoFermionAction det("<<DenOp.Mass()<<") / det("<<NumOp.Mass()<<")";
83 return sstream.str();
84 }
85
86 virtual std::string LogParameters(){
87 std::stringstream sstream;
88 sstream<< GridLogMessage << "["<<action_name()<<"] -- No further parameters "<<std::endl;
89 return sstream.str();
90 }
91
92
93 const FermionField &getPhiOdd() const{ return PhiOdd; }
94
95 virtual void refresh(const GaugeField &U, GridSerialRNG &sRNG, GridParallelRNG& pRNG) {
96 // P(eta_o) = e^{- eta_o^dag eta_o}
97 //
98 // e^{x^2/2 sig^2} => sig^2 = 0.5.
99 //
100 RealD scale = std::sqrt(0.5);
101
102 FermionField eta (NumOp.FermionGrid());
103 gaussian(pRNG,eta); eta = eta * scale;
104
105 refresh(U,eta);
106 }
107
108 void refresh(const GaugeField &U, const FermionField &eta) {
109
110 // P(phi) = e^{- phi^dag Vpc (MpcdagMpc)^-1 Vpcdag phi}
111 //
112 // NumOp == V
113 // DenOp == M
114 //
115 FermionField etaOdd (NumOp.FermionRedBlackGrid());
116 FermionField etaEven(NumOp.FermionRedBlackGrid());
117 FermionField tmp (NumOp.FermionRedBlackGrid());
118
119 pickCheckerboard(Even,etaEven,eta);
120 pickCheckerboard(Odd,etaOdd,eta);
121
122 NumOp.ImportGauge(U);
123 DenOp.ImportGauge(U);
124 std::cout << " TwoFlavourRefresh: Imported gauge "<<std::endl;
125
128
129 std::cout << " TwoFlavourRefresh: Diff ops "<<std::endl;
130 // Odd det factors
131 Mpc.MpcDag(etaOdd,PhiOdd);
132 std::cout << " TwoFlavourRefresh: MpcDag "<<std::endl;
133 tmp=Zero();
134 std::cout << " TwoFlavourRefresh: Zero() guess "<<std::endl;
135 HeatbathSolver(Vpc,PhiOdd,tmp);
136 std::cout << " TwoFlavourRefresh: Heatbath solver "<<std::endl;
137 Vpc.Mpc(tmp,PhiOdd);
138 std::cout << " TwoFlavourRefresh: Mpc "<<std::endl;
139
140 // Even det factors
141 DenOp.MooeeDag(etaEven,tmp);
142 NumOp.MooeeInvDag(tmp,PhiEven);
143 std::cout << " TwoFlavourRefresh: Mee "<<std::endl;
144
145 RefreshAction = norm2(etaEven)+norm2(etaOdd);
146 std::cout << " refresh " <<action_name()<< " action "<<RefreshAction<<std::endl;
147 };
148
150 // S = phi^dag V (Mdag M)^-1 Vdag phi
152 virtual RealD Sinitial(const GaugeField &U) {
153 std::cout << GridLogMessage << "Returning stored two flavour refresh action "<<RefreshAction<<std::endl;
154 return RefreshAction;
155 }
156 virtual RealD S(const GaugeField &U) {
157
158 NumOp.ImportGauge(U);
159 DenOp.ImportGauge(U);
160
163
164 FermionField X(NumOp.FermionRedBlackGrid());
165 FermionField Y(NumOp.FermionRedBlackGrid());
166
167 Vpc.MpcDag(PhiOdd,Y); // Y= Vdag phi
168 X=Zero();
169 ActionSolver(Mpc,Y,X); // X= (MdagM)^-1 Vdag phi
170 //Mpc.Mpc(X,Y); // Y= Mdag^-1 Vdag phi
171 // Multiply by Ydag
172 RealD action = real(innerProduct(Y,X));
173
174 //RealD action = norm2(Y);
175
176 // The EE factorised block; normally can replace with zero if det is constant (gauge field indept)
177 // Only really clover term that creates this. Leave the EE portion as a future to do to make most
178 // rapid progresss on DWF for now.
179 //
180 NumOp.MooeeDag(PhiEven,X);
181 DenOp.MooeeInvDag(X,Y);
182 action = action + norm2(Y);
183
184 return action;
185 };
186
188 // dS/du = phi^dag dV (Mdag M)^-1 V^dag phi
189 // - phi^dag V (Mdag M)^-1 [ Mdag dM + dMdag M ] (Mdag M)^-1 V^dag phi
190 // + phi^dag V (Mdag M)^-1 dV^dag phi
192 virtual void deriv(const GaugeField &U,GaugeField & dSdU) {
193
194 NumOp.ImportGauge(U);
195 DenOp.ImportGauge(U);
196
199
200 FermionField X(NumOp.FermionRedBlackGrid());
201 FermionField Y(NumOp.FermionRedBlackGrid());
202
203 // This assignment is necessary to be compliant with the HMC grids
204 GaugeField force(dSdU.Grid());
205
206 //Y=Vdag phi
207 //X = (Mdag M)^-1 V^dag phi
208 //Y = (Mdag)^-1 V^dag phi
209 Vpc.MpcDag(PhiOdd,Y); // Y= Vdag phi
210 std::cout << GridLogMessage <<" Y "<<norm2(Y)<<std::endl;
211 X=Zero();
212 DerivativeSolver(Mpc,Y,X); // X= (MdagM)^-1 Vdag phi
213 std::cout << GridLogMessage <<" X "<<norm2(X)<<std::endl;
214 Mpc.Mpc(X,Y); // Y= Mdag^-1 Vdag phi
215 std::cout << GridLogMessage <<" Y "<<norm2(Y)<<std::endl;
216
217 // phi^dag V (Mdag M)^-1 dV^dag phi
218 Vpc.MpcDagDeriv(force , X, PhiOdd ); dSdU = force;
219 std::cout << GridLogMessage <<" deriv "<<norm2(force)<<std::endl;
220
221 // phi^dag dV (Mdag M)^-1 V^dag phi
222 Vpc.MpcDeriv(force , PhiOdd, X ); dSdU = dSdU+force;
223 std::cout << GridLogMessage <<" deriv "<<norm2(force)<<std::endl;
224
225 // - phi^dag V (Mdag M)^-1 Mdag dM (Mdag M)^-1 V^dag phi
226 // - phi^dag V (Mdag M)^-1 dMdag M (Mdag M)^-1 V^dag phi
227 Mpc.MpcDeriv(force,Y,X); dSdU = dSdU-force;
228 std::cout << GridLogMessage <<" deriv "<<norm2(force)<<std::endl;
229 Mpc.MpcDagDeriv(force,X,Y); dSdU = dSdU-force;
230 std::cout << GridLogMessage <<" deriv "<<norm2(force)<<std::endl;
231
232 // FIXME No force contribution from EvenEven assumed here
233 // Needs a fix for clover.
234 assert(NumOp.ConstEE() == 1);
235 assert(DenOp.ConstEE() == 1);
236
237 dSdU = -dSdU;
238
239 };
240 };
242#endif
static const int Even
static const int Odd
void conformable(const Lattice< obj1 > &lhs, const Lattice< obj2 > &rhs)
Lattice< vobj > real(const Lattice< vobj > &lhs)
ComplexD innerProduct(const Lattice< vobj > &left, const Lattice< vobj > &right)
RealD norm2(const Lattice< vobj > &arg)
void gaussian(GridParallelRNG &rng, Lattice< vobj > &l)
void pickCheckerboard(int cb, Lattice< vobj > &half, const Lattice< vobj > &full)
GridLogger GridLogMessage(1, "Message", GridLogColours, "NORMAL")
#define NAMESPACE_BEGIN(A)
Definition Namespace.h:35
#define NAMESPACE_END(A)
Definition Namespace.h:36
double RealD
Definition Simd.h:61
static INTERNAL_PRECISION U
Definition Zolotarev.cc:230
Base class for all actions.
Definition ActionBase.h:64
virtual GridBase * GaugeGrid(void)=0
virtual GridBase * FermionRedBlackGrid(void)=0
virtual GridBase * GaugeRedBlackGrid(void)=0
virtual GridBase * FermionGrid(void)=0
virtual void MpcDag(const Field &in, Field &out)
virtual void Mpc(const Field &in, Field &out)
void MpcDagDeriv(GaugeField &Force, const FermionField &U, const FermionField &V)
void MpcDeriv(GaugeField &Force, const FermionField &U, const FermionField &V)
virtual void deriv(const GaugeField &U, GaugeField &dSdU)
virtual std::string action_name()
Report the name of the action.
virtual RealD Sinitial(const GaugeField &U)
Get the action at the start of the trajectory.
OperatorFunction< FermionField > & ActionSolver
OperatorFunction< FermionField > & DerivativeSolver
virtual std::string LogParameters()
Print the parameters of the action.
void refresh(const GaugeField &U, const FermionField &eta)
virtual RealD S(const GaugeField &U)
Evaluate this action with the given gauge field.
OperatorFunction< FermionField > & HeatbathSolver
TwoFlavourEvenOddRatioPseudoFermionAction(FermionOperator< Impl > &_NumOp, FermionOperator< Impl > &_DenOp, OperatorFunction< FermionField > &DS, OperatorFunction< FermionField > &AS, OperatorFunction< FermionField > &HS)
TwoFlavourEvenOddRatioPseudoFermionAction(FermionOperator< Impl > &_NumOp, FermionOperator< Impl > &_DenOp, OperatorFunction< FermionField > &DS, OperatorFunction< FermionField > &AS)
virtual void refresh(const GaugeField &U, GridSerialRNG &sRNG, GridParallelRNG &pRNG)
Refresh pseudofermion fields.
Definition Simd.h:194