mirror of
https://github.com/paboyle/Grid.git
synced 2024-11-09 23:45:36 +00:00
Adef2 implemented and working in an HDCG like context
This commit is contained in:
parent
6c3ade5d89
commit
0ec0de97e6
@ -33,15 +33,6 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|||||||
* Script A = SolverMatrix
|
* Script A = SolverMatrix
|
||||||
* Script P = Preconditioner
|
* Script P = Preconditioner
|
||||||
*
|
*
|
||||||
* Deflation methods considered
|
|
||||||
* -- Solve P A x = P b [ like Luscher ]
|
|
||||||
* DEF-1 M P A x = M P b [i.e. left precon]
|
|
||||||
* DEF-2 P^T M A x = P^T M b
|
|
||||||
* ADEF-1 Preconditioner = M P + Q [ Q + M + M A Q]
|
|
||||||
* ADEF-2 Preconditioner = P^T M + Q
|
|
||||||
* BNN Preconditioner = P^T M P + Q
|
|
||||||
* BNN2 Preconditioner = M P + P^TM +Q - M P A M
|
|
||||||
*
|
|
||||||
* Implement ADEF-2
|
* Implement ADEF-2
|
||||||
*
|
*
|
||||||
* Vstart = P^Tx + Qb
|
* Vstart = P^Tx + Qb
|
||||||
@ -49,45 +40,157 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|||||||
* M2=M3=1
|
* M2=M3=1
|
||||||
* Vout = x
|
* Vout = x
|
||||||
*/
|
*/
|
||||||
|
NAMESPACE_BEGIN(Grid);
|
||||||
|
|
||||||
// abstract base
|
template<class Field, class CoarseField, class Aggregation>
|
||||||
template<class Field, class CoarseField>
|
|
||||||
class TwoLevelFlexiblePcg : public LinearFunction<Field>
|
class TwoLevelFlexiblePcg : public LinearFunction<Field>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int verbose;
|
|
||||||
RealD Tolerance;
|
RealD Tolerance;
|
||||||
Integer MaxIterations;
|
Integer MaxIterations;
|
||||||
const int mmax = 5;
|
const int mmax = 1;
|
||||||
GridBase *grid;
|
GridBase *grid;
|
||||||
GridBase *coarsegrid;
|
GridBase *coarsegrid;
|
||||||
|
|
||||||
LinearOperatorBase<Field> *_Linop
|
// Fine operator, Smoother, CoarseSolver
|
||||||
OperatorFunction<Field> *_Smoother,
|
LinearOperatorBase<Field> &_FineLinop;
|
||||||
LinearFunction<CoarseField> *_CoarseSolver;
|
LinearFunction<Field> &_Smoother;
|
||||||
|
LinearFunction<CoarseField> &_CoarseSolver;
|
||||||
|
LinearFunction<CoarseField> &_CoarseSolverPrecise;
|
||||||
|
|
||||||
// Need somthing that knows how to get from Coarse to fine and back again
|
// Need something that knows how to get from Coarse to fine and back again
|
||||||
|
// void ProjectToSubspace(CoarseVector &CoarseVec,const FineField &FineVec){
|
||||||
|
// void PromoteFromSubspace(const CoarseVector &CoarseVec,FineField &FineVec){
|
||||||
|
Aggregation &_Aggregates;
|
||||||
|
|
||||||
// more most opertor functions
|
// more most opertor functions
|
||||||
TwoLevelFlexiblePcg(RealD tol,
|
TwoLevelFlexiblePcg(RealD tol,
|
||||||
Integer maxit,
|
Integer maxit,
|
||||||
LinearOperatorBase<Field> *Linop,
|
LinearOperatorBase<Field> &FineLinop,
|
||||||
LinearOperatorBase<Field> *SmootherLinop,
|
LinearFunction<Field> &Smoother,
|
||||||
OperatorFunction<Field> *Smoother,
|
LinearFunction<CoarseField> &CoarseSolver,
|
||||||
OperatorFunction<CoarseField> CoarseLinop
|
LinearFunction<CoarseField> &CoarseSolverPrecise,
|
||||||
|
Aggregation &Aggregates
|
||||||
) :
|
) :
|
||||||
Tolerance(tol),
|
Tolerance(tol),
|
||||||
MaxIterations(maxit),
|
MaxIterations(maxit),
|
||||||
_Linop(Linop),
|
_FineLinop(FineLinop),
|
||||||
_PreconditionerLinop(PrecLinop),
|
_Smoother(Smoother),
|
||||||
_Preconditioner(Preconditioner)
|
_CoarseSolver(CoarseSolver),
|
||||||
{
|
_CoarseSolverPrecise(CoarseSolverPrecise),
|
||||||
verbose=0;
|
_Aggregates(Aggregates)
|
||||||
|
{
|
||||||
|
coarsegrid = Aggregates.CoarseGrid;
|
||||||
|
grid = Aggregates.FineGrid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void Inflexible(Field &src,Field &psi)
|
||||||
|
{
|
||||||
|
Field resid(grid);
|
||||||
|
RealD f;
|
||||||
|
RealD rtzp,rtz,a,d,b;
|
||||||
|
RealD rptzp;
|
||||||
|
|
||||||
|
Field x(grid);
|
||||||
|
Field p(grid);
|
||||||
|
Field z(grid);
|
||||||
|
Field tmp(grid);
|
||||||
|
Field mmp(grid);
|
||||||
|
Field r (grid);
|
||||||
|
Field mu (grid);
|
||||||
|
Field rp (grid);
|
||||||
|
|
||||||
|
//Initial residual computation & set up
|
||||||
|
RealD guess = norm2(psi);
|
||||||
|
double tn;
|
||||||
|
|
||||||
|
//////////////////////////
|
||||||
|
// x0 = Vstart -- possibly modify guess
|
||||||
|
//////////////////////////
|
||||||
|
x=Zero();
|
||||||
|
Vstart(x,src);
|
||||||
|
|
||||||
|
// r0 = b -A x0
|
||||||
|
_FineLinop.HermOp(x,mmp);
|
||||||
|
|
||||||
|
axpy(r, -1.0, mmp, src); // Recomputes r=src-x0
|
||||||
|
rp=r;
|
||||||
|
|
||||||
|
//////////////////////////////////
|
||||||
|
// Compute z = M1 x
|
||||||
|
//////////////////////////////////
|
||||||
|
PcgM1(r,z);
|
||||||
|
rtzp =real(innerProduct(r,z));
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
// Except Def2, M2 is trivial
|
||||||
|
///////////////////////////////////////
|
||||||
|
p=z;
|
||||||
|
|
||||||
|
RealD ssq = norm2(src);
|
||||||
|
RealD rsq = ssq*Tolerance*Tolerance;
|
||||||
|
|
||||||
|
std::cout<<GridLogMessage<<"HDCG: k=0 residual "<<rtzp<<" target rsq "<<rsq<<" ssq "<<ssq<<std::endl;
|
||||||
|
|
||||||
|
for (int k=1;k<=MaxIterations;k++){
|
||||||
|
|
||||||
|
rtz=rtzp;
|
||||||
|
d= PcgM3(p,mmp);
|
||||||
|
a = rtz/d;
|
||||||
|
|
||||||
|
axpy(x,a,p,x);
|
||||||
|
RealD rn = axpy_norm(r,-a,mmp,r);
|
||||||
|
|
||||||
|
PcgM1(r,z);
|
||||||
|
|
||||||
|
rtzp =real(innerProduct(r,z));
|
||||||
|
|
||||||
|
int ipcg=1; // almost free inexact preconditioned CG
|
||||||
|
if (ipcg) {
|
||||||
|
rptzp =real(innerProduct(rp,z));
|
||||||
|
} else {
|
||||||
|
rptzp =0;
|
||||||
|
}
|
||||||
|
b = (rtzp-rptzp)/rtz;
|
||||||
|
|
||||||
|
PcgM2(z,mu); // ADEF-2 this is identity. Axpy possible to eliminate
|
||||||
|
|
||||||
|
axpy(p,b,p,mu); // mu = A r
|
||||||
|
|
||||||
|
RealD rrn=sqrt(rn/ssq);
|
||||||
|
RealD rtn=sqrt(rtz/ssq);
|
||||||
|
std::cout<<GridLogMessage<<"HDCG: Pcg k= "<<k<<" residual = "<<rrn<<std::endl;
|
||||||
|
|
||||||
|
if ( ipcg ) {
|
||||||
|
axpy(rp,0.0,r,r);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stopping condition
|
||||||
|
if ( rn <= rsq ) {
|
||||||
|
|
||||||
|
std::cout<<GridLogMessage<<"HDCG: Pcg converged in "<<k<<" iterations"<<std::endl;;
|
||||||
|
|
||||||
|
_FineLinop.HermOp(x,mmp);
|
||||||
|
axpy(tmp,-1.0,src,mmp);
|
||||||
|
|
||||||
|
RealD mmpnorm = sqrt(norm2(mmp));
|
||||||
|
RealD psinorm = sqrt(norm2(x));
|
||||||
|
RealD srcnorm = sqrt(norm2(src));
|
||||||
|
RealD tmpnorm = sqrt(norm2(tmp));
|
||||||
|
RealD true_residual = tmpnorm/srcnorm;
|
||||||
|
std::cout<<GridLogMessage<<"HDCG: true residual is "<<true_residual
|
||||||
|
<<" solution "<<psinorm<<" source "<<srcnorm<<std::endl;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
std::cout << "HDCG: Pcg not converged"<<std::endl;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
// The Pcg routine is common to all, but the various matrices differ from derived
|
// The Pcg routine is common to all, but the various matrices differ from derived
|
||||||
// implementation to derived implmentation
|
// implementation to derived implmentation
|
||||||
void operator() (const Field &src, Field &psi){
|
|
||||||
void operator() (const Field &src, Field &psi){
|
void operator() (const Field &src, Field &psi){
|
||||||
|
|
||||||
psi.Checkerboard() = src.Checkerboard();
|
psi.Checkerboard() = src.Checkerboard();
|
||||||
@ -108,7 +211,7 @@ class TwoLevelFlexiblePcg : public LinearFunction<Field>
|
|||||||
std::vector<Field> mmp(mmax,grid);
|
std::vector<Field> mmp(mmax,grid);
|
||||||
std::vector<RealD> pAp(mmax);
|
std::vector<RealD> pAp(mmax);
|
||||||
|
|
||||||
Field x (grid); x = psi;
|
Field x (grid);
|
||||||
Field z (grid);
|
Field z (grid);
|
||||||
Field tmp(grid);
|
Field tmp(grid);
|
||||||
Field r (grid);
|
Field r (grid);
|
||||||
@ -117,25 +220,23 @@ class TwoLevelFlexiblePcg : public LinearFunction<Field>
|
|||||||
//////////////////////////
|
//////////////////////////
|
||||||
// x0 = Vstart -- possibly modify guess
|
// x0 = Vstart -- possibly modify guess
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
x=src;
|
x=Zero();
|
||||||
Vstart(x,src);
|
Vstart(x,src);
|
||||||
|
|
||||||
// r0 = b -A x0
|
// r0 = b -A x0
|
||||||
HermOp(x,mmp); // Shouldn't this be something else?
|
_FineLinop.HermOp(x,mmp[0]); // Fine operator
|
||||||
axpy (r, -1.0,mmp[0], src); // Recomputes r=src-Ax0
|
axpy (r, -1.0,mmp[0], src); // Recomputes r=src-Ax0
|
||||||
|
|
||||||
//////////////////////////////////
|
//////////////////////////////////
|
||||||
// Compute z = M1 x
|
// Compute z = M1 r
|
||||||
//////////////////////////////////
|
//////////////////////////////////
|
||||||
M1(r,z,tmp,mp,SmootherMirs);
|
PcgM1(r,z);
|
||||||
rtzp =real(innerProduct(r,z));
|
rtzp =real(innerProduct(r,z));
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// Solve for Mss mu = P A z and set p = z-mu
|
// Solve for Mss mu = P A z and set p = z-mu
|
||||||
// Def2: p = 1 - Q Az = Pright z
|
|
||||||
// Other algos M2 is trivial
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
M2(z,p[0]);
|
PcgM2(z,p[0]);
|
||||||
|
|
||||||
for (int k=0;k<=MaxIterations;k++){
|
for (int k=0;k<=MaxIterations;k++){
|
||||||
|
|
||||||
@ -143,26 +244,38 @@ class TwoLevelFlexiblePcg : public LinearFunction<Field>
|
|||||||
int peri_kp = (k+1) % mmax;
|
int peri_kp = (k+1) % mmax;
|
||||||
|
|
||||||
rtz=rtzp;
|
rtz=rtzp;
|
||||||
d= M3(p[peri_k],mp,mmp[peri_k],tmp);
|
d= PcgM3(p[peri_k],mmp[peri_k]);
|
||||||
a = rtz/d;
|
a = rtz/d;
|
||||||
|
|
||||||
// Memorise this
|
// Memorise this
|
||||||
pAp[peri_k] = d;
|
pAp[peri_k] = d;
|
||||||
|
std::cout << GridLogMessage << " pCG d "<< d<<std::endl;
|
||||||
|
|
||||||
axpy(x,a,p[peri_k],x);
|
axpy(x,a,p[peri_k],x);
|
||||||
|
// std::cout << GridLogMessage << " pCG x "<< norm2(x)<<std::endl;
|
||||||
RealD rn = axpy_norm(r,-a,mmp[peri_k],r);
|
RealD rn = axpy_norm(r,-a,mmp[peri_k],r);
|
||||||
|
|
||||||
|
std::cout << GridLogMessage << " pCG rn "<< rn<<std::endl;
|
||||||
|
|
||||||
// Compute z = M x
|
// Compute z = M x
|
||||||
M1(r,z,tmp,mp);
|
PcgM1(r,z);
|
||||||
|
// std::cout << GridLogMessage << " pCG z "<< norm2(z)<<std::endl;
|
||||||
|
|
||||||
rtzp =real(innerProduct(r,z));
|
rtzp =real(innerProduct(r,z));
|
||||||
|
std::cout << GridLogMessage << " pCG rtzp "<<rtzp<<std::endl;
|
||||||
|
// std::cout << GridLogMessage << " pCG r "<<norm2(r)<<std::endl;
|
||||||
|
|
||||||
M2(z,mu); // ADEF-2 this is identity. Axpy possible to eliminate
|
PcgM2(z,mu); // ADEF-2 this is identity. Axpy possible to eliminate
|
||||||
|
|
||||||
p[peri_kp]=p[peri_k];
|
// std::cout << GridLogMessage << " pCG mu "<<norm2(mu)<<std::endl;
|
||||||
|
|
||||||
|
p[peri_kp]=mu;
|
||||||
|
|
||||||
// Standard search direction p -> z + b p ; b =
|
// std::cout << GridLogMessage << " pCG p[peri_kp] "<<norm2(p[peri_kp])<<std::endl;
|
||||||
|
|
||||||
|
// Standard search direction p -> z + b p
|
||||||
b = (rtzp)/rtz;
|
b = (rtzp)/rtz;
|
||||||
|
std::cout << GridLogMessage << " pCG b "<< b<<std::endl;
|
||||||
|
|
||||||
int northog;
|
int northog;
|
||||||
// northog = (peri_kp==0)?1:peri_kp; // This is the fCG(mmax) algorithm
|
// northog = (peri_kp==0)?1:peri_kp; // This is the fCG(mmax) algorithm
|
||||||
@ -174,6 +287,7 @@ class TwoLevelFlexiblePcg : public LinearFunction<Field>
|
|||||||
RealD beta = -pbApk/pAp[peri_back];
|
RealD beta = -pbApk/pAp[peri_back];
|
||||||
axpy(p[peri_kp],beta,p[peri_back],p[peri_kp]);
|
axpy(p[peri_kp],beta,p[peri_back],p[peri_kp]);
|
||||||
}
|
}
|
||||||
|
// std::cout << GridLogMessage << " pCG p[peri_kp] orthog "<< norm2(p[peri_kp])<<std::endl;
|
||||||
|
|
||||||
RealD rrn=sqrt(rn/ssq);
|
RealD rrn=sqrt(rn/ssq);
|
||||||
std::cout<<GridLogMessage<<"TwoLevelfPcg: k= "<<k<<" residual = "<<rrn<<std::endl;
|
std::cout<<GridLogMessage<<"TwoLevelfPcg: k= "<<k<<" residual = "<<rrn<<std::endl;
|
||||||
@ -181,7 +295,7 @@ class TwoLevelFlexiblePcg : public LinearFunction<Field>
|
|||||||
// Stopping condition
|
// Stopping condition
|
||||||
if ( rn <= rsq ) {
|
if ( rn <= rsq ) {
|
||||||
|
|
||||||
HermOp(x,mmp); // Shouldn't this be something else?
|
_FineLinop.HermOp(x,mmp[0]); // Shouldn't this be something else?
|
||||||
axpy(tmp,-1.0,src,mmp[0]);
|
axpy(tmp,-1.0,src,mmp[0]);
|
||||||
|
|
||||||
RealD psinorm = sqrt(norm2(x));
|
RealD psinorm = sqrt(norm2(x));
|
||||||
@ -190,7 +304,7 @@ class TwoLevelFlexiblePcg : public LinearFunction<Field>
|
|||||||
RealD true_residual = tmpnorm/srcnorm;
|
RealD true_residual = tmpnorm/srcnorm;
|
||||||
std::cout<<GridLogMessage<<"TwoLevelfPcg: true residual is "<<true_residual<<std::endl;
|
std::cout<<GridLogMessage<<"TwoLevelfPcg: true residual is "<<true_residual<<std::endl;
|
||||||
std::cout<<GridLogMessage<<"TwoLevelfPcg: target residual was"<<Tolerance<<std::endl;
|
std::cout<<GridLogMessage<<"TwoLevelfPcg: target residual was"<<Tolerance<<std::endl;
|
||||||
return k;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Non-convergence
|
// Non-convergence
|
||||||
@ -199,52 +313,42 @@ class TwoLevelFlexiblePcg : public LinearFunction<Field>
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual void M(Field & in,Field & out,Field & tmp) {
|
virtual void PcgM1(Field & in, Field & out)
|
||||||
|
{
|
||||||
}
|
|
||||||
|
|
||||||
virtual void M1(Field & in, Field & out) {// the smoother
|
|
||||||
|
|
||||||
// [PTM+Q] in = [1 - Q A] M in + Q in = Min + Q [ in -A Min]
|
// [PTM+Q] in = [1 - Q A] M in + Q in = Min + Q [ in -A Min]
|
||||||
|
|
||||||
Field tmp(grid);
|
Field tmp(grid);
|
||||||
Field Min(grid);
|
Field Min(grid);
|
||||||
|
CoarseField PleftProj(coarsegrid);
|
||||||
|
CoarseField PleftMss_proj(coarsegrid);
|
||||||
|
|
||||||
PcgM(in,Min); // Smoother call
|
_Smoother(in,Min);
|
||||||
|
|
||||||
HermOp(Min,out);
|
_FineLinop.HermOp(Min,out);
|
||||||
axpy(tmp,-1.0,out,in); // tmp = in - A Min
|
axpy(tmp,-1.0,out,in); // tmp = in - A Min
|
||||||
|
|
||||||
ProjectToSubspace(tmp,PleftProj);
|
_Aggregates.ProjectToSubspace(PleftProj,tmp);
|
||||||
ApplyInverse(PleftProj,PleftMss_proj); // Ass^{-1} [in - A Min]_s
|
_CoarseSolver(PleftProj,PleftMss_proj); // Ass^{-1} [in - A Min]_s
|
||||||
PromoteFromSubspace(PleftMss_proj,tmp);// tmp = Q[in - A Min]
|
_Aggregates.PromoteFromSubspace(PleftMss_proj,tmp);// tmp = Q[in - A Min]
|
||||||
|
|
||||||
axpy(out,1.0,Min,tmp); // Min+tmp
|
axpy(out,1.0,Min,tmp); // Min+tmp
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void M2(const Field & in, Field & out) {
|
virtual void PcgM2(const Field & in, Field & out) {
|
||||||
out=in;
|
out=in;
|
||||||
// Must override for Def2 only
|
|
||||||
// case PcgDef2:
|
|
||||||
// Pright(in,out);
|
|
||||||
// break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual RealD M3(const Field & p, Field & mmp){
|
virtual RealD PcgM3(const Field & p, Field & mmp){
|
||||||
double d,dd;
|
RealD dd;
|
||||||
HermOpAndNorm(p,mmp,d,dd);
|
_FineLinop.HermOp(p,mmp);
|
||||||
|
ComplexD dot = innerProduct(p,mmp);
|
||||||
|
dd=real(dot);
|
||||||
return dd;
|
return dd;
|
||||||
// Must override for Def1 only
|
|
||||||
// case PcgDef1:
|
|
||||||
// d=linop_d->Mprec(p,mmp,tmp,0,1);// Dag no
|
|
||||||
// linop_d->Mprec(mmp,mp,tmp,1);// Dag yes
|
|
||||||
// Pleft(mp,mmp);
|
|
||||||
// d=real(linop_d->inner(p,mmp));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void VstartDef2(Field & xconst Field & src){
|
virtual void Vstart(Field & x,const Field & src)
|
||||||
//case PcgDef2:
|
{
|
||||||
//case PcgAdef2:
|
|
||||||
//case PcgAdef2f:
|
|
||||||
//case PcgV11f:
|
|
||||||
///////////////////////////////////
|
///////////////////////////////////
|
||||||
// Choose x_0 such that
|
// Choose x_0 such that
|
||||||
// x_0 = guess + (A_ss^inv) r_s = guess + Ass_inv [src -Aguess]
|
// x_0 = guess + (A_ss^inv) r_s = guess + Ass_inv [src -Aguess]
|
||||||
@ -258,140 +362,22 @@ class TwoLevelFlexiblePcg : public LinearFunction<Field>
|
|||||||
///////////////////////////////////
|
///////////////////////////////////
|
||||||
Field r(grid);
|
Field r(grid);
|
||||||
Field mmp(grid);
|
Field mmp(grid);
|
||||||
|
CoarseField PleftProj(coarsegrid);
|
||||||
HermOp(x,mmp);
|
CoarseField PleftMss_proj(coarsegrid);
|
||||||
axpy (r, -1.0, mmp, src); // r_{-1} = src - A x
|
|
||||||
ProjectToSubspace(r,PleftProj);
|
|
||||||
ApplyInverseCG(PleftProj,PleftMss_proj); // Ass^{-1} r_s
|
|
||||||
PromoteFromSubspace(PleftMss_proj,mmp);
|
|
||||||
x=x+mmp;
|
|
||||||
|
|
||||||
}
|
_Aggregates.ProjectToSubspace(PleftProj,src);
|
||||||
|
_CoarseSolverPrecise(PleftProj,PleftMss_proj); // Ass^{-1} r_s
|
||||||
|
_Aggregates.PromoteFromSubspace(PleftMss_proj,x);
|
||||||
|
|
||||||
virtual void Vstart(Field & x,const Field & src){
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
// Only Def1 has non-trivial Vout. Override in Def1
|
// Only Def1 has non-trivial Vout.
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
virtual void Vout (Field & in, Field & out,Field & src){
|
virtual void Vout (Field & in, Field & out,Field & src){
|
||||||
out = in;
|
out = in;
|
||||||
//case PcgDef1:
|
|
||||||
// //Qb + PT x
|
|
||||||
// ProjectToSubspace(src,PleftProj);
|
|
||||||
// ApplyInverse(PleftProj,PleftMss_proj); // Ass^{-1} r_s
|
|
||||||
// PromoteFromSubspace(PleftMss_proj,tmp);
|
|
||||||
//
|
|
||||||
// Pright(in,out);
|
|
||||||
//
|
|
||||||
// linop_d->axpy(out,tmp,out,1.0);
|
|
||||||
// break;
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
NAMESPACE_END(Grid);
|
||||||
// Pright and Pleft are common to all implementations
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
virtual void Pright(Field & in,Field & out){
|
|
||||||
// P_R = [ 1 0 ]
|
|
||||||
// [ -Mss^-1 Msb 0 ]
|
|
||||||
Field in_sbar(grid);
|
|
||||||
|
|
||||||
ProjectToSubspace(in,PleftProj);
|
|
||||||
PromoteFromSubspace(PleftProj,out);
|
|
||||||
axpy(in_sbar,-1.0,out,in); // in_sbar = in - in_s
|
|
||||||
|
|
||||||
HermOp(in_sbar,out);
|
|
||||||
ProjectToSubspace(out,PleftProj); // Mssbar in_sbar (project)
|
|
||||||
|
|
||||||
ApplyInverse (PleftProj,PleftMss_proj); // Mss^{-1} Mssbar
|
|
||||||
PromoteFromSubspace(PleftMss_proj,out); //
|
|
||||||
|
|
||||||
axpy(out,-1.0,out,in_sbar); // in_sbar - Mss^{-1} Mssbar in_sbar
|
|
||||||
}
|
|
||||||
virtual void Pleft (Field & in,Field & out){
|
|
||||||
// P_L = [ 1 -Mbs Mss^-1]
|
|
||||||
// [ 0 0 ]
|
|
||||||
Field in_sbar(grid);
|
|
||||||
Field tmp2(grid);
|
|
||||||
Field Mtmp(grid);
|
|
||||||
|
|
||||||
ProjectToSubspace(in,PleftProj);
|
|
||||||
PromoteFromSubspace(PleftProj,out);
|
|
||||||
axpy(in_sbar,-1.0,out,in); // in_sbar = in - in_s
|
|
||||||
|
|
||||||
ApplyInverse(PleftProj,PleftMss_proj); // Mss^{-1} in_s
|
|
||||||
PromoteFromSubspace(PleftMss_proj,out);
|
|
||||||
|
|
||||||
HermOp(out,Mtmp);
|
|
||||||
|
|
||||||
ProjectToSubspace(Mtmp,PleftProj); // Msbar s Mss^{-1}
|
|
||||||
PromoteFromSubspace(PleftProj,tmp2);
|
|
||||||
|
|
||||||
axpy(out,-1.0,tmp2,Mtmp);
|
|
||||||
axpy(out,-1.0,out,in_sbar); // in_sbar - Msbars Mss^{-1} in_s
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Field>
|
|
||||||
class TwoLevelFlexiblePcgADef2 : public TwoLevelFlexiblePcg<Field> {
|
|
||||||
public:
|
|
||||||
virtual void M(Field & in,Field & out,Field & tmp){
|
|
||||||
|
|
||||||
}
|
|
||||||
virtual void M1(Field & in, Field & out,Field & tmp,Field & mp){
|
|
||||||
|
|
||||||
}
|
|
||||||
virtual void M2(Field & in, Field & out){
|
|
||||||
|
|
||||||
}
|
|
||||||
virtual RealD M3(Field & p, Field & mp,Field & mmp, Field & tmp){
|
|
||||||
|
|
||||||
}
|
|
||||||
virtual void Vstart(Field & in, Field & src, Field & r, Field & mp, Field & mmp, Field & tmp){
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
template<class Field>
|
|
||||||
class TwoLevelFlexiblePcgAD : public TwoLevelFlexiblePcg<Field> {
|
|
||||||
public:
|
|
||||||
virtual void M(Field & in,Field & out,Field & tmp);
|
|
||||||
virtual void M1(Field & in, Field & out,Field & tmp,Field & mp);
|
|
||||||
virtual void M2(Field & in, Field & out);
|
|
||||||
virtual RealD M3(Field & p, Field & mp,Field & mmp, Field & tmp);
|
|
||||||
virtual void Vstart(Field & in, Field & src, Field & r, Field & mp, Field & mmp, Field & tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Field>
|
|
||||||
class TwoLevelFlexiblePcgDef1 : public TwoLevelFlexiblePcg<Field> {
|
|
||||||
public:
|
|
||||||
virtual void M(Field & in,Field & out,Field & tmp);
|
|
||||||
virtual void M1(Field & in, Field & out,Field & tmp,Field & mp);
|
|
||||||
virtual void M2(Field & in, Field & out);
|
|
||||||
virtual RealD M3(Field & p, Field & mp,Field & mmp, Field & tmp);
|
|
||||||
virtual void Vstart(Field & in, Field & src, Field & r, Field & mp, Field & mmp, Field & tmp);
|
|
||||||
virtual void Vout (Field & in, Field & out,Field & src,Field & tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Field>
|
|
||||||
class TwoLevelFlexiblePcgDef2 : public TwoLevelFlexiblePcg<Field> {
|
|
||||||
public:
|
|
||||||
virtual void M(Field & in,Field & out,Field & tmp);
|
|
||||||
virtual void M1(Field & in, Field & out,Field & tmp,Field & mp);
|
|
||||||
virtual void M2(Field & in, Field & out);
|
|
||||||
virtual RealD M3(Field & p, Field & mp,Field & mmp, Field & tmp);
|
|
||||||
virtual void Vstart(Field & in, Field & src, Field & r, Field & mp, Field & mmp, Field & tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Field>
|
|
||||||
class TwoLevelFlexiblePcgV11: public TwoLevelFlexiblePcg<Field> {
|
|
||||||
public:
|
|
||||||
virtual void M(Field & in,Field & out,Field & tmp);
|
|
||||||
virtual void M1(Field & in, Field & out,Field & tmp,Field & mp);
|
|
||||||
virtual void M2(Field & in, Field & out);
|
|
||||||
virtual RealD M3(Field & p, Field & mp,Field & mmp, Field & tmp);
|
|
||||||
virtual void Vstart(Field & in, Field & src, Field & r, Field & mp, Field & mmp, Field & tmp);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user