Grid 0.7.0
SchurRedBlack.h
Go to the documentation of this file.
1 /*************************************************************************************
2
3 Grid physics library, www.github.com/paboyle/Grid
4
5 Source file: ./lib/algorithms/iterative/SchurRedBlack.h
6
7 Copyright (C) 2015
8
9Author: Peter Boyle <paboyle@ph.ed.ac.uk>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License along
22 with this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
25 See the full license in the file "LICENSE" in the top level distribution directory
26 *************************************************************************************/
27 /* END LEGAL */
28#ifndef GRID_SCHUR_RED_BLACK_H
29#define GRID_SCHUR_RED_BLACK_H
30
31
32 /*
33 * Red black Schur decomposition
34 *
35 * M = (Mee Meo) = (1 0 ) (Mee 0 ) (1 Mee^{-1} Meo)
36 * (Moe Moo) (Moe Mee^-1 1 ) (0 Moo-Moe Mee^-1 Meo) (0 1 )
37 * = L D U
38 *
39 * L^-1 = (1 0 )
40 * (-MoeMee^{-1} 1 )
41 * L^{dag} = ( 1 Mee^{-dag} Moe^{dag} )
42 * ( 0 1 )
43 * L^{-d} = ( 1 -Mee^{-dag} Moe^{dag} )
44 * ( 0 1 )
45 *
46 * U^-1 = (1 -Mee^{-1} Meo)
47 * (0 1 )
48 * U^{dag} = ( 1 0)
49 * (Meo^dag Mee^{-dag} 1)
50 * U^{-dag} = ( 1 0)
51 * (-Meo^dag Mee^{-dag} 1)
52 ***********************
53 * M psi = eta
54 ***********************
55 *Odd
56 * i) D_oo psi_o = L^{-1} eta_o
57 * eta_o' = (D_oo)^dag (eta_o - Moe Mee^{-1} eta_e)
58 *
59 * Wilson:
60 * (D_oo)^{\dag} D_oo psi_o = (D_oo)^dag L^{-1} eta_o
61 * Stag:
62 * D_oo psi_o = L^{-1} eta = (eta_o - Moe Mee^{-1} eta_e)
63 *
64 * L^-1 eta_o= (1 0 ) (e
65 * (-MoeMee^{-1} 1 )
66 *
67 *Even
68 * ii) Mee psi_e + Meo psi_o = src_e
69 *
70 * => sol_e = M_ee^-1 * ( src_e - Meo sol_o )...
71 *
72 *
73 * TODO: Other options:
74 *
75 * a) change checkerboards for Schur e<->o
76 *
77 * Left precon by Moo^-1
78 * b) Doo^{dag} M_oo^-dag Moo^-1 Doo psi_0 = (D_oo)^dag M_oo^-dag Moo^-1 L^{-1} eta_o
79 * eta_o' = (D_oo)^dag M_oo^-dag Moo^-1 (eta_o - Moe Mee^{-1} eta_e)
80 *
81 * Right precon by Moo^-1
82 * c) M_oo^-dag Doo^{dag} Doo Moo^-1 phi_0 = M_oo^-dag (D_oo)^dag L^{-1} eta_o
83 * eta_o' = M_oo^-dag (D_oo)^dag (eta_o - Moe Mee^{-1} eta_e)
84 * psi_o = M_oo^-1 phi_o
85 * TODO: Deflation
86 */
87namespace Grid {
88
90 // Use base class to share code
93 // Take a matrix and form a Red Black solver calling a Herm solver
94 // Use of RB info prevents making SchurRedBlackSolve conform to standard interface
96 template<class Field> class SchurRedBlackBase {
97 protected:
102 bool useSolnAsInitGuess; // if true user-supplied solution vector is used as initial guess for solver
103 public:
104
105 SchurRedBlackBase(OperatorFunction<Field> &HermitianRBSolver, const bool initSubGuess = false,
106 const bool _solnAsInitGuess = false) :
107 _HermitianRBSolver(HermitianRBSolver),
108 useSolnAsInitGuess(_solnAsInitGuess)
109 {
110 CBfactorise = 0;
111 subtractGuess(initSubGuess);
112 };
113 void subtractGuess(const bool initSubGuess)
114 {
115 subGuess = initSubGuess;
116 }
118 {
119 return subGuess;
120 }
121
123 // Shared code
125 void operator() (Matrix & _Matrix,const Field &in, Field &out){
126 ZeroGuesser<Field> guess;
127 (*this)(_Matrix,in,out,guess);
128 }
129 void operator()(Matrix &_Matrix, const std::vector<Field> &in, std::vector<Field> &out)
130 {
131 ZeroGuesser<Field> guess;
132 (*this)(_Matrix,in,out,guess);
133 }
134
135 void RedBlackSource(Matrix &_Matrix, const std::vector<Field> &in, std::vector<Field> &src_o)
136 {
137 GridBase *grid = _Matrix.RedBlackGrid();
138 Field tmp(grid);
139 int nblock = in.size();
140 for(int b=0;b<nblock;b++){
141 RedBlackSource(_Matrix,in[b],tmp,src_o[b]);
142 }
143 }
144 // James can write his own deflated guesser
145 // with optimised code for the inner products
146 // RedBlackSolveSplitGrid();
147 // RedBlackSolve(_Matrix,src_o,sol_o);
148
149 void RedBlackSolution(Matrix &_Matrix, const std::vector<Field> &in, const std::vector<Field> &sol_o, std::vector<Field> &out)
150 {
151 GridBase *grid = _Matrix.RedBlackGrid();
152 Field tmp(grid);
153 int nblock = in.size();
154 for(int b=0;b<nblock;b++) {
155 pickCheckerboard(Even,tmp,in[b]);
156 RedBlackSolution(_Matrix,sol_o[b],tmp,out[b]);
157 }
158 }
159
160 template<class Guesser>
161 void operator()(Matrix &_Matrix, const std::vector<Field> &in, std::vector<Field> &out,Guesser &guess)
162 {
163 GridBase *grid = _Matrix.RedBlackGrid();
164 GridBase *fgrid= _Matrix.Grid();
165 int nblock = in.size();
166
167 std::vector<Field> src_o(nblock,grid);
168 std::vector<Field> sol_o(nblock,grid);
169
170 std::vector<Field> guess_save;
171
172 Field resid(fgrid);
173 Field tmp(grid);
174
176 // Prepare RedBlack source
178 RedBlackSource(_Matrix,in,src_o);
179 // for(int b=0;b<nblock;b++){
180 // RedBlackSource(_Matrix,in[b],tmp,src_o[b]);
181 // }
182
184 // Make the guesses
186 if ( subGuess ) guess_save.resize(nblock,grid);
187
188
190 for(int b=0;b<nblock;b++){
191 pickCheckerboard(Odd, sol_o[b], out[b]);
192 }
193 } else {
194 guess(src_o, sol_o);
195 }
196
197 if ( subGuess ) {
198 for(int b=0;b<nblock;b++){
199 guess_save[b] = sol_o[b];
200 }
201 }
203 // Call the block solver
205 std::cout<<GridLogMessage << "SchurRedBlackBase calling the solver for "<<nblock<<" RHS" <<std::endl;
206 RedBlackSolve(_Matrix,src_o,sol_o);
207
209 // A2A boolean behavioural control & reconstruct other checkerboard
211 for(int b=0;b<nblock;b++) {
212
213 if (subGuess) sol_o[b] = sol_o[b] - guess_save[b];
214
216 pickCheckerboard(Even,tmp,in[b]);
217 RedBlackSolution(_Matrix,sol_o[b],tmp,out[b]);
218
220 // Check unprec residual if possible
222 if ( ! subGuess ) {
223 _Matrix.M(out[b],resid);
224 resid = resid-in[b];
225 RealD ns = norm2(in[b]);
226 RealD nr = norm2(resid);
227
228 std::cout<<GridLogMessage<< "SchurRedBlackBase solver true unprec resid["<<b<<"] "<<std::sqrt(nr/ns) << std::endl;
229 } else {
230 std::cout<<GridLogMessage<< "SchurRedBlackBase Guess subtracted after solve["<<b<<"] " << std::endl;
231 }
232
233 }
234 }
235 template<class Guesser>
236 void operator() (Matrix & _Matrix,const Field &in, Field &out,Guesser &guess){
237
238 // FIXME CGdiagonalMee not implemented virtual function
239 // FIXME use CBfactorise to control schur decomp
240 GridBase *grid = _Matrix.RedBlackGrid();
241 GridBase *fgrid= _Matrix.Grid();
242
243 Field resid(fgrid);
244 Field src_o(grid);
245 Field src_e(grid);
246 Field sol_o(grid);
247
249 // RedBlack source
251 RedBlackSource(_Matrix,in,src_e,src_o);
252
254 // Construct the guess
257 pickCheckerboard(Odd, sol_o, out);
258 } else {
259 guess(src_o,sol_o);
260 }
261
262 Field guess_save(grid);
263 guess_save = sol_o;
264
266 // Call the red-black solver
268 RedBlackSolve(_Matrix,src_o,sol_o);
269
271 // Fionn A2A boolean behavioural control
273 if (subGuess) sol_o= sol_o-guess_save;
274
276 // RedBlack solution needs the even source
278 RedBlackSolution(_Matrix,sol_o,src_e,out);
279
280 // Verify the unprec residual
281 if ( ! subGuess ) {
282 _Matrix.M(out,resid);
283 resid = resid-in;
284 RealD ns = norm2(in);
285 RealD nr = norm2(resid);
286
287 std::cout<<GridLogMessage << "SchurRedBlackBase solver true unprec resid "<< std::sqrt(nr/ns) << std::endl;
288 } else {
289 std::cout << GridLogMessage << "SchurRedBlackBase Guess subtracted after solve." << std::endl;
290 }
291 }
292
294 // Override in derived.
296 virtual void RedBlackSource (Matrix & _Matrix,const Field &src, Field &src_e,Field &src_o) =0;
297 virtual void RedBlackSolution(Matrix & _Matrix,const Field &sol_o, const Field &src_e,Field &sol) =0;
298 virtual void RedBlackSolve (Matrix & _Matrix,const Field &src_o, Field &sol_o) =0;
299 virtual void RedBlackSolve (Matrix & _Matrix,const std::vector<Field> &src_o, std::vector<Field> &sol_o)=0;
300
301 };
302
303 template<class Field> class SchurRedBlackStaggeredSolve : public SchurRedBlackBase<Field> {
304 public:
306
307 SchurRedBlackStaggeredSolve(OperatorFunction<Field> &HermitianRBSolver, const bool initSubGuess = false,
308 const bool _solnAsInitGuess = false)
309 : SchurRedBlackBase<Field> (HermitianRBSolver,initSubGuess,_solnAsInitGuess)
310 {
311 }
312
314 // Override RedBlack specialisation
316 virtual void RedBlackSource(Matrix & _Matrix,const Field &src, Field &src_e,Field &src_o)
317 {
318 GridBase *grid = _Matrix.RedBlackGrid();
319 GridBase *fgrid= _Matrix.Grid();
320
321 Field tmp(grid);
322 Field Mtmp(grid);
323
324 pickCheckerboard(Even,src_e,src);
325 pickCheckerboard(Odd ,src_o,src);
326
328 // src_o = (source_o - Moe MeeInv source_e)
330 _Matrix.MooeeInv(src_e,tmp); assert( tmp.Checkerboard() ==Even);
331 _Matrix.Meooe (tmp,Mtmp); assert( Mtmp.Checkerboard() ==Odd);
332 tmp=src_o-Mtmp; assert( tmp.Checkerboard() ==Odd);
333
334 _Matrix.Mooee(tmp,src_o); // Extra factor of "m" in source from dumb choice of matrix norm.
335 }
336 virtual void RedBlackSolution(Matrix & _Matrix,const Field &sol_o, const Field &src_e_c,Field &sol)
337 {
338 GridBase *grid = _Matrix.RedBlackGrid();
339 GridBase *fgrid= _Matrix.Grid();
340
341 Field tmp(grid);
342 Field sol_e(grid);
343 Field src_e(grid);
344
345 src_e = src_e_c; // Const correctness
346
348 // sol_e = M_ee^-1 * ( src_e - Meo sol_o )...
350 _Matrix.Meooe(sol_o,tmp); assert( tmp.Checkerboard() ==Even);
351 src_e = src_e-tmp; assert( src_e.Checkerboard() ==Even);
352 _Matrix.MooeeInv(src_e,sol_e); assert( sol_e.Checkerboard() ==Even);
353
354 setCheckerboard(sol,sol_e); assert( sol_e.Checkerboard() ==Even);
355 setCheckerboard(sol,sol_o); assert( sol_o.Checkerboard() ==Odd );
356 }
357 virtual void RedBlackSolve (Matrix & _Matrix,const Field &src_o, Field &sol_o)
358 {
359 SchurStaggeredOperator<Matrix,Field> _HermOpEO(_Matrix);
360 this->_HermitianRBSolver(_HermOpEO,src_o,sol_o); assert(sol_o.Checkerboard()==Odd);
361 };
362 virtual void RedBlackSolve (Matrix & _Matrix,const std::vector<Field> &src_o, std::vector<Field> &sol_o)
363 {
364 SchurStaggeredOperator<Matrix,Field> _HermOpEO(_Matrix);
365 this->_HermitianRBSolver(_HermOpEO,src_o,sol_o);
366 }
367 };
369
371 // Site diagonal has Mooee on it.
373 template<class Field> class SchurRedBlackDiagMooeeSolve : public SchurRedBlackBase<Field> {
374 public:
376
377 SchurRedBlackDiagMooeeSolve(OperatorFunction<Field> &HermitianRBSolver, const bool initSubGuess = false,
378 const bool _solnAsInitGuess = false)
379 : SchurRedBlackBase<Field> (HermitianRBSolver,initSubGuess,_solnAsInitGuess) {};
380
381
383 // Override RedBlack specialisation
385 virtual void RedBlackSource(Matrix & _Matrix,const Field &src, Field &src_e,Field &src_o)
386 {
387 GridBase *grid = _Matrix.RedBlackGrid();
388 GridBase *fgrid= _Matrix.Grid();
389
390 Field tmp(grid);
391 Field Mtmp(grid);
392
393 pickCheckerboard(Even,src_e,src);
394 pickCheckerboard(Odd ,src_o,src);
395
397 // src_o = Mdag * (source_o - Moe MeeInv source_e)
399 _Matrix.MooeeInv(src_e,tmp); assert( tmp.Checkerboard() ==Even);
400 _Matrix.Meooe (tmp,Mtmp); assert( Mtmp.Checkerboard() ==Odd);
401 tmp=src_o-Mtmp; assert( tmp.Checkerboard() ==Odd);
402
403 // get the right MpcDag
404 SchurDiagMooeeOperator<Matrix,Field> _HermOpEO(_Matrix);
405 _HermOpEO.MpcDag(tmp,src_o); assert(src_o.Checkerboard() ==Odd);
406
407 }
408 virtual void RedBlackSolution(Matrix & _Matrix,const Field &sol_o, const Field &src_e,Field &sol)
409 {
410 GridBase *grid = _Matrix.RedBlackGrid();
411 GridBase *fgrid= _Matrix.Grid();
412
413 Field tmp(grid);
414 Field sol_e(grid);
415 Field src_e_i(grid);
417 // sol_e = M_ee^-1 * ( src_e - Meo sol_o )...
419 _Matrix.Meooe(sol_o,tmp); assert( tmp.Checkerboard() ==Even);
420 src_e_i = src_e-tmp; assert( src_e_i.Checkerboard() ==Even);
421 _Matrix.MooeeInv(src_e_i,sol_e); assert( sol_e.Checkerboard() ==Even);
422
423 setCheckerboard(sol,sol_e); assert( sol_e.Checkerboard() ==Even);
424 setCheckerboard(sol,sol_o); assert( sol_o.Checkerboard() ==Odd );
425 }
426 virtual void RedBlackSolve (Matrix & _Matrix,const Field &src_o, Field &sol_o)
427 {
428 SchurDiagMooeeOperator<Matrix,Field> _HermOpEO(_Matrix);
429 this->_HermitianRBSolver(_HermOpEO,src_o,sol_o); assert(sol_o.Checkerboard()==Odd);
430 };
431 virtual void RedBlackSolve (Matrix & _Matrix,const std::vector<Field> &src_o, std::vector<Field> &sol_o)
432 {
433 SchurDiagMooeeOperator<Matrix,Field> _HermOpEO(_Matrix);
434 this->_HermitianRBSolver(_HermOpEO,src_o,sol_o);
435 }
436 };
437
438 template<class Field> class NonHermitianSchurRedBlackDiagMooeeSolve : public SchurRedBlackBase<Field>
439 {
440 public:
442
443 NonHermitianSchurRedBlackDiagMooeeSolve(OperatorFunction<Field>& RBSolver, const bool initSubGuess = false,
444 const bool _solnAsInitGuess = false)
445 : SchurRedBlackBase<Field>(RBSolver, initSubGuess, _solnAsInitGuess) {};
446
448 // Override RedBlack specialisation
450 virtual void RedBlackSource(Matrix& _Matrix, const Field& src, Field& src_e, Field& src_o)
451 {
452 GridBase* grid = _Matrix.RedBlackGrid();
453 GridBase* fgrid = _Matrix.Grid();
454
455 Field tmp(grid);
456 Field Mtmp(grid);
457
458 pickCheckerboard(Even, src_e, src);
459 pickCheckerboard(Odd , src_o, src);
460
462 // src_o = Mdag * (source_o - Moe MeeInv source_e)
464 _Matrix.MooeeInv(src_e, tmp); assert( tmp.Checkerboard() == Even );
465 _Matrix.Meooe (tmp, Mtmp); assert( Mtmp.Checkerboard() == Odd );
466 src_o -= Mtmp; assert( src_o.Checkerboard() == Odd );
467 }
468
469 virtual void RedBlackSolution(Matrix& _Matrix, const Field& sol_o, const Field& src_e, Field& sol)
470 {
471 GridBase* grid = _Matrix.RedBlackGrid();
472 GridBase* fgrid = _Matrix.Grid();
473
474 Field tmp(grid);
475 Field sol_e(grid);
476 Field src_e_i(grid);
477
479 // sol_e = M_ee^-1 * ( src_e - Meo sol_o )...
481 _Matrix.Meooe(sol_o, tmp); assert( tmp.Checkerboard() == Even );
482 src_e_i = src_e - tmp; assert( src_e_i.Checkerboard() == Even );
483 _Matrix.MooeeInv(src_e_i, sol_e); assert( sol_e.Checkerboard() == Even );
484
485 setCheckerboard(sol, sol_e); assert( sol_e.Checkerboard() == Even );
486 setCheckerboard(sol, sol_o); assert( sol_o.Checkerboard() == Odd );
487 }
488
489 virtual void RedBlackSolve(Matrix& _Matrix, const Field& src_o, Field& sol_o)
490 {
492 this->_HermitianRBSolver(_OpEO, src_o, sol_o); assert(sol_o.Checkerboard() == Odd);
493 }
494
495 virtual void RedBlackSolve(Matrix& _Matrix, const std::vector<Field>& src_o, std::vector<Field>& sol_o)
496 {
498 this->_HermitianRBSolver(_OpEO, src_o, sol_o);
499 }
500 };
501
503 // Site diagonal is identity, left preconditioned by Mee^inv
504 // ( 1 - Mee^inv Meo Moo^inv Moe ) phi = Mee_inv ( Mee - Meo Moo^inv Moe Mee^inv ) phi = Mee_inv eta
505 //
506 // Solve:
507 // ( 1 - Mee^inv Meo Moo^inv Moe )^dag ( 1 - Mee^inv Meo Moo^inv Moe ) phi = ( 1 - Mee^inv Meo Moo^inv Moe )^dag Mee_inv eta
508 //
509 // Old notation e<->o
510 //
511 // Left precon by Moo^-1
512 // b) (Doo^{dag} M_oo^-dag) (Moo^-1 Doo) psi_o = [ (D_oo)^dag M_oo^-dag ] Moo^-1 L^{-1} eta_o
513 // eta_o' = (D_oo)^dag M_oo^-dag Moo^-1 (eta_o - Moe Mee^{-1} eta_e)
515 template<class Field> class SchurRedBlackDiagOneSolve : public SchurRedBlackBase<Field> {
516 public:
518
520 // Wrap the usual normal equations Schur trick
522 SchurRedBlackDiagOneSolve(OperatorFunction<Field> &HermitianRBSolver, const bool initSubGuess = false,
523 const bool _solnAsInitGuess = false)
524 : SchurRedBlackBase<Field>(HermitianRBSolver,initSubGuess,_solnAsInitGuess) {};
525
526 virtual void RedBlackSource(Matrix & _Matrix,const Field &src, Field &src_e,Field &src_o)
527 {
528 GridBase *grid = _Matrix.RedBlackGrid();
529 GridBase *fgrid= _Matrix.Grid();
530
531 SchurDiagOneOperator<Matrix,Field> _HermOpEO(_Matrix);
532
533 Field tmp(grid);
534 Field Mtmp(grid);
535
536 pickCheckerboard(Even,src_e,src);
537 pickCheckerboard(Odd ,src_o,src);
538
540 // src_o = Mpcdag *MooeeInv * (source_o - Moe MeeInv source_e)
542 _Matrix.MooeeInv(src_e,tmp); assert( tmp.Checkerboard() ==Even);
543 _Matrix.Meooe (tmp,Mtmp); assert( Mtmp.Checkerboard() ==Odd);
544 Mtmp=src_o-Mtmp;
545 _Matrix.MooeeInv(Mtmp,tmp); assert( tmp.Checkerboard() ==Odd);
546
547 // get the right MpcDag
548 _HermOpEO.MpcDag(tmp,src_o); assert(src_o.Checkerboard() ==Odd);
549 }
550
551 virtual void RedBlackSolution(Matrix & _Matrix,const Field &sol_o, const Field &src_e,Field &sol)
552 {
553 GridBase *grid = _Matrix.RedBlackGrid();
554 GridBase *fgrid= _Matrix.Grid();
555
556 Field tmp(grid);
557 Field sol_e(grid);
558
559
561 // sol_e = M_ee^-1 * ( src_e - Meo sol_o )...
563 _Matrix.Meooe(sol_o,tmp); assert( tmp.Checkerboard() ==Even);
564 tmp = src_e-tmp; assert( src_e.Checkerboard() ==Even);
565 _Matrix.MooeeInv(tmp,sol_e); assert( sol_e.Checkerboard() ==Even);
566
567 setCheckerboard(sol,sol_e); assert( sol_e.Checkerboard() ==Even);
568 setCheckerboard(sol,sol_o); assert( sol_o.Checkerboard() ==Odd );
569 };
570
571 virtual void RedBlackSolve (Matrix & _Matrix,const Field &src_o, Field &sol_o)
572 {
573 SchurDiagOneOperator<Matrix,Field> _HermOpEO(_Matrix);
574 this->_HermitianRBSolver(_HermOpEO,src_o,sol_o);
575 };
576 virtual void RedBlackSolve (Matrix & _Matrix,const std::vector<Field> &src_o, std::vector<Field> &sol_o)
577 {
578 SchurDiagOneOperator<Matrix,Field> _HermOpEO(_Matrix);
579 this->_HermitianRBSolver(_HermOpEO,src_o,sol_o);
580 }
581 };
582
584 // Site diagonal is identity, right preconditioned by Mee^inv
585 // ( 1 - Meo Moo^inv Moe Mee^inv ) phi =( 1 - Meo Moo^inv Moe Mee^inv ) Mee psi = = eta = eta
586 //=> psi = MeeInv phi
588 template<class Field> class SchurRedBlackDiagTwoSolve : public SchurRedBlackBase<Field> {
589 public:
591
593 // Wrap the usual normal equations Schur trick
595 SchurRedBlackDiagTwoSolve(OperatorFunction<Field> &HermitianRBSolver, const bool initSubGuess = false,
596 const bool _solnAsInitGuess = false)
597 : SchurRedBlackBase<Field>(HermitianRBSolver,initSubGuess,_solnAsInitGuess) {};
598
599 virtual void RedBlackSource(Matrix & _Matrix,const Field &src, Field &src_e,Field &src_o)
600 {
601 GridBase *grid = _Matrix.RedBlackGrid();
602 GridBase *fgrid= _Matrix.Grid();
603
604 SchurDiagTwoOperator<Matrix,Field> _HermOpEO(_Matrix);
605
606 Field tmp(grid);
607 Field Mtmp(grid);
608
609 pickCheckerboard(Even,src_e,src);
610 pickCheckerboard(Odd ,src_o,src);
611
613 // src_o = Mdag * (source_o - Moe MeeInv source_e)
615 _Matrix.MooeeInv(src_e,tmp); assert( tmp.Checkerboard() ==Even);
616 _Matrix.Meooe (tmp,Mtmp); assert( Mtmp.Checkerboard() ==Odd);
617 tmp=src_o-Mtmp; assert( tmp.Checkerboard() ==Odd);
618
619 // get the right MpcDag
620 _HermOpEO.MpcDag(tmp,src_o); assert(src_o.Checkerboard() ==Odd);
621 }
622
623 virtual void RedBlackSolution(Matrix & _Matrix,const Field &sol_o, const Field &src_e,Field &sol)
624 {
625 GridBase *grid = _Matrix.RedBlackGrid();
626 GridBase *fgrid= _Matrix.Grid();
627
628 Field sol_o_i(grid);
629 Field tmp(grid);
630 Field sol_e(grid);
631
633 // MooeeInv due to pecond
635 _Matrix.MooeeInv(sol_o,tmp);
636 sol_o_i = tmp;
637
639 // sol_e = M_ee^-1 * ( src_e - Meo sol_o )...
641 _Matrix.Meooe(sol_o_i,tmp); assert( tmp.Checkerboard() ==Even);
642 tmp = src_e-tmp; assert( src_e.Checkerboard() ==Even);
643 _Matrix.MooeeInv(tmp,sol_e); assert( sol_e.Checkerboard() ==Even);
644
645 setCheckerboard(sol,sol_e); assert( sol_e.Checkerboard() ==Even);
646 setCheckerboard(sol,sol_o_i); assert( sol_o_i.Checkerboard() ==Odd );
647 };
648
649 virtual void RedBlackSolve (Matrix & _Matrix,const Field &src_o, Field &sol_o)
650 {
651 SchurDiagTwoOperator<Matrix,Field> _HermOpEO(_Matrix);
652 this->_HermitianRBSolver(_HermOpEO,src_o,sol_o);
653 };
654 virtual void RedBlackSolve (Matrix & _Matrix,const std::vector<Field> &src_o, std::vector<Field> &sol_o)
655 {
656 SchurDiagTwoOperator<Matrix,Field> _HermOpEO(_Matrix);
657 this->_HermitianRBSolver(_HermOpEO,src_o,sol_o);
658 }
659 };
660
661 template<class Field> class NonHermitianSchurRedBlackDiagTwoSolve : public SchurRedBlackBase<Field>
662 {
663 public:
665
667 // Wrap the usual normal equations Schur trick
669 NonHermitianSchurRedBlackDiagTwoSolve(OperatorFunction<Field>& RBSolver, const bool initSubGuess = false,
670 const bool _solnAsInitGuess = false)
671 : SchurRedBlackBase<Field>(RBSolver, initSubGuess, _solnAsInitGuess) {};
672
673 virtual void RedBlackSource(Matrix& _Matrix, const Field& src, Field& src_e, Field& src_o)
674 {
675 GridBase* grid = _Matrix.RedBlackGrid();
676 GridBase* fgrid = _Matrix.Grid();
677
678 Field tmp(grid);
679 Field Mtmp(grid);
680
681 pickCheckerboard(Even, src_e, src);
682 pickCheckerboard(Odd , src_o, src);
683
685 // src_o = Mdag * (source_o - Moe MeeInv source_e)
687 _Matrix.MooeeInv(src_e, tmp); assert( tmp.Checkerboard() == Even );
688 _Matrix.Meooe (tmp, Mtmp); assert( Mtmp.Checkerboard() == Odd );
689 src_o -= Mtmp; assert( src_o.Checkerboard() == Odd );
690 }
691
692 virtual void RedBlackSolution(Matrix& _Matrix, const Field& sol_o, const Field& src_e, Field& sol)
693 {
694 GridBase* grid = _Matrix.RedBlackGrid();
695 GridBase* fgrid = _Matrix.Grid();
696
697 Field sol_o_i(grid);
698 Field tmp(grid);
699 Field sol_e(grid);
700
702 // MooeeInv due to pecond
704 _Matrix.MooeeInv(sol_o, tmp);
705 sol_o_i = tmp;
706
708 // sol_e = M_ee^-1 * ( src_e - Meo sol_o )...
710 _Matrix.Meooe(sol_o_i, tmp); assert( tmp.Checkerboard() == Even );
711 tmp = src_e - tmp; assert( src_e.Checkerboard() == Even );
712 _Matrix.MooeeInv(tmp, sol_e); assert( sol_e.Checkerboard() == Even );
713
714 setCheckerboard(sol, sol_e); assert( sol_e.Checkerboard() == Even );
715 setCheckerboard(sol, sol_o_i); assert( sol_o_i.Checkerboard() == Odd );
716 };
717
718 virtual void RedBlackSolve(Matrix& _Matrix, const Field& src_o, Field& sol_o)
719 {
721 this->_HermitianRBSolver(_OpEO, src_o, sol_o);
722 };
723
724 virtual void RedBlackSolve(Matrix& _Matrix, const std::vector<Field>& src_o, std::vector<Field>& sol_o)
725 {
727 this->_HermitianRBSolver(_OpEO, src_o, sol_o);
728 }
729 };
730}
731
732#endif
static const int Even
static const int Odd
RealD norm2(const Lattice< vobj > &arg)
void setCheckerboard(Lattice< vobj > &full, const Lattice< vobj > &half)
void pickCheckerboard(int cb, Lattice< vobj > &half, const Lattice< vobj > &full)
GridLogger GridLogMessage(1, "Message", GridLogColours, "NORMAL")
double RealD
Definition Simd.h:61
virtual void Mooee(const Field &in, Field &out)=0
virtual void MooeeInv(const Field &in, Field &out)=0
virtual void Meooe(const Field &in, Field &out)=0
virtual GridBase * RedBlackGrid(void)=0
NonHermitianSchurRedBlackDiagMooeeSolve(OperatorFunction< Field > &RBSolver, const bool initSubGuess=false, const bool _solnAsInitGuess=false)
virtual void RedBlackSource(Matrix &_Matrix, const Field &src, Field &src_e, Field &src_o)
virtual void RedBlackSolution(Matrix &_Matrix, const Field &sol_o, const Field &src_e, Field &sol)
virtual void RedBlackSolve(Matrix &_Matrix, const Field &src_o, Field &sol_o)
virtual void RedBlackSolve(Matrix &_Matrix, const std::vector< Field > &src_o, std::vector< Field > &sol_o)
CheckerBoardedSparseMatrixBase< Field > Matrix
virtual void RedBlackSolution(Matrix &_Matrix, const Field &sol_o, const Field &src_e, Field &sol)
virtual void RedBlackSolve(Matrix &_Matrix, const std::vector< Field > &src_o, std::vector< Field > &sol_o)
virtual void RedBlackSource(Matrix &_Matrix, const Field &src, Field &src_e, Field &src_o)
virtual void RedBlackSolve(Matrix &_Matrix, const Field &src_o, Field &sol_o)
CheckerBoardedSparseMatrixBase< Field > Matrix
NonHermitianSchurRedBlackDiagTwoSolve(OperatorFunction< Field > &RBSolver, const bool initSubGuess=false, const bool _solnAsInitGuess=false)
virtual void RedBlackSolve(Matrix &_Matrix, const Field &src_o, Field &sol_o)=0
virtual void RedBlackSolution(Matrix &_Matrix, const Field &sol_o, const Field &src_e, Field &sol)=0
OperatorFunction< Field > & _HermitianRBSolver
CheckerBoardedSparseMatrixBase< Field > Matrix
void operator()(Matrix &_Matrix, const std::vector< Field > &in, std::vector< Field > &out, Guesser &guess)
SchurRedBlackBase(OperatorFunction< Field > &HermitianRBSolver, const bool initSubGuess=false, const bool _solnAsInitGuess=false)
virtual void RedBlackSource(Matrix &_Matrix, const Field &src, Field &src_e, Field &src_o)=0
void operator()(Matrix &_Matrix, const std::vector< Field > &in, std::vector< Field > &out)
void RedBlackSource(Matrix &_Matrix, const std::vector< Field > &in, std::vector< Field > &src_o)
void subtractGuess(const bool initSubGuess)
virtual void RedBlackSolve(Matrix &_Matrix, const std::vector< Field > &src_o, std::vector< Field > &sol_o)=0
void operator()(Matrix &_Matrix, const Field &in, Field &out)
void RedBlackSolution(Matrix &_Matrix, const std::vector< Field > &in, const std::vector< Field > &sol_o, std::vector< Field > &out)
CheckerBoardedSparseMatrixBase< Field > Matrix
virtual void RedBlackSolve(Matrix &_Matrix, const std::vector< Field > &src_o, std::vector< Field > &sol_o)
virtual void RedBlackSolve(Matrix &_Matrix, const Field &src_o, Field &sol_o)
SchurRedBlackDiagMooeeSolve(OperatorFunction< Field > &HermitianRBSolver, const bool initSubGuess=false, const bool _solnAsInitGuess=false)
virtual void RedBlackSource(Matrix &_Matrix, const Field &src, Field &src_e, Field &src_o)
virtual void RedBlackSolution(Matrix &_Matrix, const Field &sol_o, const Field &src_e, Field &sol)
virtual void RedBlackSolve(Matrix &_Matrix, const Field &src_o, Field &sol_o)
virtual void RedBlackSource(Matrix &_Matrix, const Field &src, Field &src_e, Field &src_o)
virtual void RedBlackSolve(Matrix &_Matrix, const std::vector< Field > &src_o, std::vector< Field > &sol_o)
CheckerBoardedSparseMatrixBase< Field > Matrix
SchurRedBlackDiagOneSolve(OperatorFunction< Field > &HermitianRBSolver, const bool initSubGuess=false, const bool _solnAsInitGuess=false)
virtual void RedBlackSolution(Matrix &_Matrix, const Field &sol_o, const Field &src_e, Field &sol)
virtual void RedBlackSolve(Matrix &_Matrix, const std::vector< Field > &src_o, std::vector< Field > &sol_o)
CheckerBoardedSparseMatrixBase< Field > Matrix
virtual void RedBlackSolution(Matrix &_Matrix, const Field &sol_o, const Field &src_e, Field &sol)
virtual void RedBlackSource(Matrix &_Matrix, const Field &src, Field &src_e, Field &src_o)
virtual void RedBlackSolve(Matrix &_Matrix, const Field &src_o, Field &sol_o)
SchurRedBlackDiagTwoSolve(OperatorFunction< Field > &HermitianRBSolver, const bool initSubGuess=false, const bool _solnAsInitGuess=false)
virtual void RedBlackSolve(Matrix &_Matrix, const std::vector< Field > &src_o, std::vector< Field > &sol_o)
SchurRedBlackStaggeredSolve(OperatorFunction< Field > &HermitianRBSolver, const bool initSubGuess=false, const bool _solnAsInitGuess=false)
virtual void RedBlackSource(Matrix &_Matrix, const Field &src, Field &src_e, Field &src_o)
virtual void RedBlackSolve(Matrix &_Matrix, const Field &src_o, Field &sol_o)
CheckerBoardedSparseMatrixBase< Field > Matrix
virtual void RedBlackSolution(Matrix &_Matrix, const Field &sol_o, const Field &src_e_c, Field &sol)
virtual void MpcDag(const Field &in, Field &out)
virtual void MpcDag(const Field &in, Field &out)
virtual void MpcDag(const Field &in, Field &out)
virtual void M(const Field &in, Field &out)=0
virtual GridBase * Grid(void)=0
SchurRedBlackStaggeredSolve< Field > SchurRedBlackStagSolve