[petsc-users] KSP not solving correctly

Massimiliano Leoni leoni.massimiliano1 at gmail.com
Thu Feb 5 04:14:23 CST 2015


Hi petsc-users,
  I stumbled across a curious issue while trying to setup some solver for 
Navier-Stokes.
In one sentence, I tested a solver computing b = Ax with x known, then solving 
the system with b to find the original x back, but it's not working.

In detail, I want to implement a matrix free method for a matrix C2 = D^T 
M_L^{-1} D, where M_L^{-1} is the inverse lumped of M; here's what I do

[I'm sorry for posting code, but I suspect the error could be quite subtle...]

////// define utility struct
typedef struct _C2ctx 
{
    Mat D;
    Vec Mdiag;
} C2ctx;

////// define multiplication
int C2mult(Mat A,Vec x,Vec y)
{
    C2ctx* ctx;
    MatShellGetContext(A,&ctx);
    Mat D = ctx->D;
    Vec Mdiag = ctx->Mdiag;
    int Nu;
    VecGetSize(Mdiag,&Nu);

    Vec tmp;
    VecCreate(PETSC_COMM_WORLD,&tmp);
    VecSetType(tmp,VECSTANDARD);
    VecSetSizes(tmp,PETSC_DECIDE,Nu);

    MatMultTranspose(D,x,tmp);
    VecPointwiseDivide(tmp,tmp,Mdiag);
    MatMult(D,tmp,y);

    VecDestroy(&tmp);
    return 0;
}

Later on, I assemble D and M, and then

////// lump M into _Mdiag
    Vec _Mdiag;
    VecCreate(PETSC_COMM_WORLD,&_Mdiag);
    VecSetType(_Mdiag,VECSTANDARD);
    VecSetSizes(_Mdiag,PETSC_DECIDE,Nu);
    MatGetRowSum(_M,_Mdiag);

////// set context
    C2ctx ctx;
    ctx.D = _D;
    ctx.Mdiag = _Mdiag;

////// create _C2 [= A]
    Mat _C2;
    MatCreateShell(PETSC_COMM_WORLD,Np,Np,PETSC_DETERMINE,PETSC_DETERMINE,&ctx,&_C2);
    MatShellSetOperation(_C2,MATOP_MULT,(void(*)(void))C2mult);

////// create _b2 [= b]
    Vec _b2;
    VecCreate(PETSC_COMM_WORLD,&_b2);
    VecSetType(_b2,VECSTANDARD);
    VecSetSizes(_b2,PETSC_DECIDE,Np);

////// create _deltaP [= x]
    Vec _deltaP;
    VecCreate(PETSC_COMM_WORLD,&_deltaP);
    VecSetType(_deltaP,VECSTANDARD);
    VecSetSizes(_deltaP,PETSC_DECIDE,Np);

////// set _deltaP = 1 and _b2 = _C2*_deltaP, then change _deltaP for check
    VecSet(_deltaP,1.0);
    MatMult(_C2,_deltaP,_b2);
    VecSet(_deltaP,2.0);

////// setup KSP
    KSP _ksp2;
    KSPCreate(PETSC_COMM_WORLD,&_ksp2);
    KSPSetOperators(_ksp2,_C2,_C2,DIFFERENT_NONZERO_PATTERN);
    KSPSetType(_ksp2,"cg");

    KSPSolve(_ksp2,_b2,_deltaP);

According to my understanding, now _deltaP should be a nice row on 1s, but 
what happens is that it has some [apparently] random zeros here and there.

Additional infos:
[*] the problem comes from the cavity problem with navier-stokes. This 
particular step is to solve for the pressure and the matrix _C2 is singular 
[it's a laplacian] with nullspace the constants. I was told I can ignore this 
and avoid setting the nullspace as long as I use a CG or GMRES solver.

[*] the number of "random zero entries" is very high with P2-P1 elements, and 
is significantly lower with P1+Bubble - P1.

[*] Matrices M and D are automatically assembled by FEniCS, not by me.

Can anybody please advice on what I am doing wrong? What could be causing 
this?

Thanks in advance
Massimiliano


More information about the petsc-users mailing list