<div dir="ltr">Hi, <br><br>I am still struggling to use petsc to solve variable coefficient poisson problems (which orinates from a multi-phase(liquid-gas two phase flow with sharp interface method, the density ratio is 1000, and with surface tension) flow problem) successively. <br>
<br>Initially petsc produces good results with icc pc_type , cg iterative method and with _pc_factor_shift_positive_define flag.&nbsp; I follow petsc&#39;s null space method to constrain the singular property of coefficient matrix. However,&nbsp; after several time steps good results of simulation, the KSP Residual Norm suddenly reaches to a number greater than 1000. I guess that petsc diverges. I have also tried to swith to other types of methods, e.g. to gmeres, it just behaves similar to cg method.&nbsp; However, when I use my previous self-coded SOR iterative solver, it produces nice results.&nbsp; And I have tested the same petsc solver class for a single phase driven cavity flow problem, it also produces nice results. <br>
<br>It seems that I have missed something important setup procedure in my solver class. could anyone to point me the problem ?&nbsp; I have attached large part of&nbsp; the code&nbsp; below: <br><br>//in Header<br>class CPETScPoissonSolver<br>
{<br>&nbsp;&nbsp;&nbsp; typedef struct {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; Vec&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x,b;&nbsp;&nbsp;&nbsp;&nbsp; //x, b<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; Mat&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //A<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; KSP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ksp;&nbsp;&nbsp; //Krylov subspace preconditioner&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; PC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pc; <br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; MatNullSpace&nbsp; nullspace;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; PetscInt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; l, m, n;//L, M, N&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; } UserContext;&nbsp;&nbsp; <br><br>public:<br>&nbsp;&nbsp;&nbsp; CPETScPoissonSolver(int argc, char** argv);<br>&nbsp;&nbsp;&nbsp; ~CPETScPoissonSolver(void);<br><br>&nbsp;&nbsp;&nbsp; //........<br>
<br>private:<br><br>&nbsp;&nbsp;&nbsp; //Yale Sparse Matrix format matrix<br>&nbsp;&nbsp;&nbsp;&nbsp; PetscScalar*&nbsp; A; <br>&nbsp;&nbsp;&nbsp; &nbsp;PetscInt&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp; I; <br>&nbsp;&nbsp;&nbsp; &nbsp;PetscInt&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp; J;<br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp;// Number of Nonzero Element<br>&nbsp;&nbsp;&nbsp; &nbsp;PetscInt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nnz;&nbsp; <br>
&nbsp;&nbsp;&nbsp; &nbsp;//grid step<br>&nbsp;&nbsp;&nbsp; &nbsp;PetscInt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; L, M, N; <br>&nbsp;&nbsp;&nbsp; &nbsp;UserContext&nbsp;&nbsp;&nbsp; userctx;<br>private:<br>&nbsp;&nbsp;&nbsp; bool&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FirstTime; <br>};<br clear="all"><br>//in cpp <br>static char helpPetscPoisson[] = &quot;PETSc class Solves a variable Poisson problem with Null Space Method.\n\n&quot;;<br>
<br>CPETScPoissonSolver::CPETScPoissonSolver(int argc, char** argv)<br>{<br>&nbsp;&nbsp;&nbsp; PetscInitialize(&amp;argc, &amp;argv, (char*)0, helpPetscPoisson);<br>&nbsp;&nbsp;&nbsp; FirstTime=true;<br>}<br>CPETScPoissonSolver::~CPETScPoissonSolver(void)<br>
{<br>&nbsp;&nbsp;&nbsp; PetscFinalize();<br>}<br>......<br>void CPETScPoissonSolver::SetAIJ(PetscScalar *a, PetscInt *i, PetscInt *j, PetscInt Nnz)<br>{<br>&nbsp;&nbsp;&nbsp; A= a; I=i; J=j; nnz = Nnz;<br>}<br><br>PetscErrorCode CPETScPoissonSolver::UserInitializeLinearSolver()<br>
{<br>&nbsp;&nbsp;&nbsp; PetscErrorCode ierr = 0;<br>&nbsp;&nbsp;&nbsp; PetscInt Num = L*M*N;<br><br>&nbsp;&nbsp;&nbsp; //Since we use successive solvers, so in the second time step we must deallocate the original matrix then setup a new one <br>&nbsp;&nbsp;&nbsp; if(FirstTime==true) <br>
&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,&nbsp; Num,&nbsp; Num,&nbsp; I,&nbsp; J,&nbsp; A, &amp;userctx.A); CHKERRQ(ierr);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; FirstTime = false;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; ierr = MatDestroy(userctx.A);CHKERRQ(ierr);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,&nbsp; Num,&nbsp; Num,&nbsp; I,&nbsp; J,&nbsp; A, &amp;userctx.A); CHKERRQ(ierr);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; if(FirstTime==true)<br>&nbsp;&nbsp;&nbsp; {<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,Num,PETSC_NULL,&amp;userctx.b);CHKERRQ(ierr);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ierr = VecDuplicate(userctx.b,&amp;userctx.x);CHKERRQ(ierr);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ierr = MatNullSpaceCreate(PETSC_COMM_SELF, PETSC_TRUE, 0, PETSC_NULL, &amp;userctx.nullspace); CHKERRQ(ierr);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ierr = KSPCreate(PETSC_COMM_SELF,&amp;userctx.ksp);CHKERRQ(ierr);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /*Set Null Space for KSP*/<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ierr = KSPSetNullSpace(userctx.ksp, userctx.nullspace);CHKERRQ(ierr);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; return 0;<br>}<br><br><br>PetscErrorCode CPETScPoissonSolver::UserSetBX(PetscScalar *x, PetscScalar *b)<br>
{<br>&nbsp;&nbsp;&nbsp; &nbsp; PetscErrorCode ierr ; <br>&nbsp;&nbsp;&nbsp; &nbsp; //below code we must set it every time step<br>&nbsp;&nbsp;&nbsp; &nbsp; ierr = VecPlaceArray(userctx.x,x);CHKERRQ(ierr);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ierr = VecPlaceArray(userctx.b,b);CHKERRQ(ierr);<br>&nbsp;&nbsp;&nbsp; &nbsp; ierr =&nbsp; MatNullSpaceRemove(userctx.nullspace,userctx.b, PETSC_NULL);CHKERRQ(ierr);<br>
&nbsp;&nbsp;&nbsp; &nbsp; return 0;<br>}<br><br>PetscInt CPETScPoissonSolver::UserSolve()<br>{&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp; PetscErrorCode ierr;<br>&nbsp;&nbsp; &nbsp;&nbsp; ierr = KSPSetOperators(userctx.ksp,userctx.A,userctx.A,SAME_NONZERO_PATTERN);CHKERRQ(ierr);<br>&nbsp;&nbsp;&nbsp; &nbsp; ierr = KSPSetType(userctx.ksp, KSPCG);<br>
&nbsp;&nbsp;&nbsp; &nbsp; ierr = KSPSetInitialGuessNonzero(userctx.ksp, PETSC_TRUE);<br>&nbsp;&nbsp;&nbsp; &nbsp; ierr = KSPGetPC(userctx.ksp,&amp;userctx.pc);CHKERRQ(ierr);<br>&nbsp;&nbsp;&nbsp; &nbsp; ierr = PCSetType(userctx.pc,PCICC);CHKERRQ(ierr);<br>&nbsp;&nbsp;&nbsp; &nbsp; ierr = PCFactorSetShiftPd(userctx.pc, PETSC_TRUE);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ierr = KSPSetTolerances(userctx.ksp,1.e-4,PETSC_DEFAULT,PETSC_DEFAULT,2000);<br>&nbsp;&nbsp;&nbsp; &nbsp; ierr = KSPSetFromOptions(userctx.ksp);CHKERRQ(ierr);<br>&nbsp;&nbsp;&nbsp; &nbsp; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; Solve the linear system<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */<br>&nbsp;&nbsp;&nbsp; &nbsp; ierr = KSPSolve(userctx.ksp,userctx.b,userctx.x);CHKERRQ(ierr);<br>&nbsp;&nbsp;&nbsp; &nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ierr = VecResetArray(userctx.x);CHKERRQ(ierr);<br>
&nbsp;&nbsp;&nbsp; &nbsp; ierr = VecResetArray(userctx.b);CHKERRQ(ierr);<br><br>&nbsp;&nbsp;&nbsp; &nbsp; return 0;<br>}<br><br>PetscErrorCode CPETScPoissonSolver::ReleaseMem()<br>{<br>&nbsp;&nbsp;&nbsp; &nbsp; PetscErrorCode ierr;<br>&nbsp;&nbsp;&nbsp; &nbsp; ierr = KSPDestroy(userctx.ksp);CHKERRQ(ierr);<br>
&nbsp;&nbsp;&nbsp; &nbsp; ierr = VecDestroy(userctx.x);&nbsp;&nbsp;&nbsp;&nbsp; CHKERRQ(ierr);<br>&nbsp;&nbsp;&nbsp; &nbsp; ierr = VecDestroy(userctx.b);&nbsp;&nbsp;&nbsp;&nbsp; CHKERRQ(ierr);&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp; ierr = MatDestroy(userctx.A);&nbsp;&nbsp;&nbsp; CHKERRQ(ierr);<br>&nbsp;&nbsp;&nbsp; &nbsp; ierr = MatNullSpaceDestroy(userctx.nullspace); CHKERRQ(ierr);<br>
&nbsp;&nbsp;&nbsp; &nbsp; return 0;<br>}<br><br>Thanks very much!<br><br><br>-- <br>Pang Shengyong<br>Solidification Simulation Lab, <br>State Key Lab of Mould &amp; Die Technology,<br>Huazhong Univ. of Sci. &amp; Tech. China<br>
</div>