6 #include "../toolkits/toolkits.h"
7 #include "../classes/classes.h"
8 #include "../shared/shared.h"
9 #include "../modules/modules.h"
10 #include "../analyses/analyses.h"
23 Vec tmpu,tmpu2,resu,resp,tmpp,tmpp2,rhsu,rhsp;
24 Vec gold,gnew,wold,wnew,chi;
26 double rho,gamma,tmpScalar,tmpScalar2;
28 KSPConvergedReason reason;
30 double initRnorm, rnorm, TOL,ELLTOL;
36 double tmp1,tmp2,tmp3;
38 double tmp4,tmp5,tmp6,tmp7;
46 #if _PETSC_MAJOR_ < 3 || (_PETSC_MAJOR_ == 3 && _PETSC_MINOR_ < 2)
58 PetscOptionsGetString(PETSC_NULL,
"-ksp_type",ksp_type,49,&flg);
59 PetscOptionsGetString(PETSC_NULL,
"-pc_type",pc_type,49,&flg);
60 PetscOptionsGetReal(PETSC_NULL,
"-tol",&TOL,NULL);
61 PetscOptionsGetReal(PETSC_NULL,
"-elltol",&ELLTOL,NULL);
62 PetscOptionsGetInt(PETSC_NULL,
"-schur_pc",&precond,NULL);
63 PetscOptionsGetInt(PETSC_NULL,
"-max_iter",&maxiter,NULL);
65 PetscOptionsGetString(NULL,PETSC_NULL,
"-ksp_type",ksp_type,49,&flg);
66 PetscOptionsGetString(NULL,PETSC_NULL,
"-pc_type",pc_type,49,&flg);
67 PetscOptionsGetReal(NULL,PETSC_NULL,
"-tol",&TOL,NULL);
68 PetscOptionsGetReal(NULL,PETSC_NULL,
"-elltol",&ELLTOL,NULL);
69 PetscOptionsGetInt(NULL,PETSC_NULL,
"-schur_pc",&precond,NULL);
70 PetscOptionsGetInt(NULL,PETSC_NULL,
"-max_iter",&maxiter,NULL);
75 _printf0_(
"Running WITH preconditioner\n");
77 _printf0_(
"Running WITHOUT preconditioner\n");
91 MatCreateSubMatrix(Kff,isv,isv,MAT_INITIAL_MATRIX,&A);
92 MatCreateSubMatrix(Kff,isv,isp,MAT_INITIAL_MATRIX,&B);
93 MatCreateSubMatrix(Kff,isp,isv,MAT_INITIAL_MATRIX,&BT);
95 MatGetSubMatrix(Kff,isv,isv,MAT_INITIAL_MATRIX,&A);
96 MatGetSubMatrix(Kff,isv,isp,MAT_INITIAL_MATRIX,&B);
97 MatGetSubMatrix(Kff,isp,isv,MAT_INITIAL_MATRIX,&BT);
102 MatCreateSubMatrix(Kff,isp,isp,MAT_INITIAL_MATRIX,&IP);
104 MatGetSubMatrix(Kff,isp,isp,MAT_INITIAL_MATRIX,&IP);
109 MatGetSize(B,&nu,&np);
112 VecCreate(
IssmComm::GetComm(),&p);VecSetSizes(p,PETSC_DECIDE,np);VecSetFromOptions(p);
113 VecAssemblyBegin(p);VecAssemblyEnd(p);
114 VecCreate(
IssmComm::GetComm(),&uold);VecSetSizes(uold,PETSC_DECIDE,nu);VecSetFromOptions(uold);
115 VecAssemblyBegin(uold);VecAssemblyEnd(uold);
117 VecGetSubVector(out_uf->pvector->vector,isv,&uold);
118 VecGetSubVector(out_uf->pvector->vector,isp,&p);
122 VecDuplicate(uold,&f1);VecSet(f1,0.0);
123 VecDuplicate(p,&f2);VecSet(f2,0.0);
124 VecDuplicate(uold,&tmpu);VecSet(tmpu,0.0);
125 VecDuplicate(uold,&tmpu2);VecSet(tmpu2,0.0);
126 VecDuplicate(uold,&resu);VecSet(resu,0.0);
127 VecDuplicate(p,&tmpp);VecSet(tmpp,0.0);
128 VecDuplicate(p,&tmpp2);VecSet(tmpp2,0.0);
129 VecDuplicate(p,&rhsp);VecSet(rhsp,0.0);
130 VecDuplicate(p,&resp);VecSet(resp,0.0);
131 VecDuplicate(uold,&rhsu);VecSet(rhsu,0.0);
132 VecDuplicate(p,&gold);VecSet(gold,0.0);
133 VecDuplicate(p,&wnew);VecSet(wnew,0.0);
134 VecDuplicate(uold,&chi);VecSet(chi,0.0);
137 VecGetSubVector(pf,isv,&f1);
138 VecGetSubVector(pf,isp,&f2);
148 #if (_PETSC_MAJOR_==3) && (_PETSC_MINOR_>=5)
149 KSPSetOperators(kspu,A,A);
151 KSPSetOperators(kspu,A,A,DIFFERENT_NONZERO_PATTERN);
153 if (strcmp(ksp_type,
"gmres")==0){
154 KSPSetType(kspu,KSPGMRES);
155 }
else if(strcmp(ksp_type,
"pipegmres")==0){
156 KSPSetType(kspu,KSPPGMRES);
157 }
else if(strcmp(ksp_type,
"cg")==0){
158 KSPSetType(kspu,KSPCG);
159 }
else if(strcmp(ksp_type,
"pipecg")==0){
160 KSPSetType(kspu,KSPPIPECG);
161 }
else if(strcmp(ksp_type,
"bicg")==0){
162 KSPSetType(kspu,KSPBICG);
163 }
else if(strcmp(ksp_type,
"bicgstab")==0){
164 KSPSetType(kspu,KSPBCGS);
165 }
else if(strcmp(ksp_type,
"ibicgstab")==0){
166 KSPSetType(kspu,KSPIBCGS);
167 }
else if(strcmp(ksp_type,
"minres")==0){
168 KSPSetType(kspu,KSPMINRES);
169 }
else if(strcmp(ksp_type,
"cr")==0){
170 KSPSetType(kspu,KSPCR);
171 }
else if(strcmp(ksp_type,
"pipecr")==0){
172 KSPSetType(kspu,KSPPIPECR);
174 _error_(
"Suggested KSP method not implemented yet!\n");
177 KSPSetInitialGuessNonzero(kspu,PETSC_TRUE);
182 KSPSetTolerances(kspu,ELLTOL,PETSC_DEFAULT,PETSC_DEFAULT,maxiter);
187 if (strcmp(pc_type,
"bjacobi")==0){
188 PCSetType(pcu,PCBJACOBI);
189 }
else if(strcmp(pc_type,
"asm")==0){
190 PCSetType(pcu,PCASM);
191 }
else if(strcmp(pc_type,
"gamg")==0){
192 PCSetType(pcu,PCGAMG);
193 }
else if(strcmp(pc_type,
"gasm")==0){
194 PCSetType(pcu,PCGASM);
195 }
else if(strcmp(pc_type,
"jacobi")==0){
196 PCSetType(pcu,PCJACOBI);
197 }
else if(strcmp(pc_type,
"icc")==0){
198 PCSetType(pcu,PCICC);
199 }
else if(strcmp(pc_type,
"ilu")==0){
200 PCSetType(pcu,PCILU);
201 }
else if(strcmp(pc_type,
"sor")==0){
202 PCSetType(pcu,PCSOR);
203 }
else if(strcmp(pc_type,
"eisenstat")==0){
204 PCSetType(pcu,PCEISENSTAT);
205 }
else if(strcmp(pc_type,
"none")==0){
206 PCSetType(pcu,PCNONE);
208 _error_(
"Suggested preconditioner not implemented yet!\n");
215 VecScale(p,-1.);MatMultAdd(B,p,f1,rhsu);VecScale(p,-1.);
220 VecScale(rhsu,-1.);MatMultAdd(A,uold,rhsu,tmpu);VecScale(rhsu,-1.);
221 VecNorm(tmpu,NORM_2,&tmp4);
223 VecScale(f2,-1.);MatMultAdd(BT,uold,f2,tmpp);VecScale(f2,-1.);
224 VecNorm(tmpp,NORM_2,&tmp6);
226 KSPInitialResidual(kspu,uold,tmpu,tmpu2,resu,rhsu);
227 VecNorm(resu,NORM_2,&tmp5);
234 KSPSolve(kspu,rhsu,uold);
235 KSPGetIterationNumber(kspu,&noIt);
242 KSPGetIterationNumber(kspu,&tmpi);
243 VecScale(rhsu,-1.);MatMultAdd(A,uold,rhsu,tmpu);VecScale(rhsu,-1.);
244 VecNorm(tmpu,NORM_2,&tmp2);
245 KSPGetResidualNorm(kspu,&tmp1);
247 _printf0_(
"||Au_00 - rhsu||_euc: " << tmp4 <<
"\n||P(-1)(Au_00 - rhsu)||_euc: " << tmp5 <<
"\n ||Au_n0 - rhsu||_euc: " << tmp2<<
"\n||P(-1)(Au_n0 - rhsu)||_euc: " << tmp1 <<
"\nIteration number: "<<tmpi<<
"\n");
248 _printf0_(
"||BTu_00 - f2||_euc: " << tmp6 <<
"\n");
254 VecDuplicate(uold,&unew);VecCopy(uold,unew);
255 VecAssemblyBegin(unew);VecAssemblyEnd(unew);
266 #if (_PETSC_MAJOR_==3) && (_PETSC_MINOR_>=5)
267 KSPSetOperators(kspip,IP,IP);
269 KSPSetOperators(kspip,IP,IP,DIFFERENT_NONZERO_PATTERN);
274 VecScale(uold,-1.);MatMultAdd(BT,uold,f2,rhsp);VecScale(uold,-1.);
278 KSPSetType(kspip,KSPGMRES);
279 KSPSetInitialGuessNonzero(kspip,PETSC_TRUE);
282 KSPGetPC(kspip,&pcp);
283 PCSetType(pcp,PCJACOBI);
285 KSPSetTolerances(kspip,1e-12,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);
290 KSPInitialResidual(kspip,gold,tmpp,tmpp2,resp,rhsp);
291 VecScale(rhsp,-1.);MatMultAdd(IP,gold,rhsp,tmpp);VecScale(rhsp,-1.);
292 VecNorm(resp,NORM_2,&tmp5);
293 VecNorm(tmpp,NORM_2,&tmp4);
299 KSPSolve(kspip,rhsp,gold);
306 KSPGetResidualNorm(kspip,&tmp1);
307 VecScale(rhsp,-1.);MatMultAdd(IP,gold,rhsp,tmpp);VecScale(rhsp,-1.);
308 VecNorm(tmpp,NORM_2,&tmp2);
310 KSPGetIterationNumber(kspip,&tmpi);
311 _printf0_(
"||IP*g00 - rhsp||_euc: " << tmp4 <<
"\n||Jac(-1)*(IP*g00-rhsp)||_euc: " << tmp5 <<
"\n||IP*gn0-rhsp||_euc: " << tmp2<<
"\n||Jac(-1)*(IP*gn0-rhsp)||_euc: " << tmp1 <<
"\nIteration number: "<<tmpi<<
"\n");
316 MatMult(IP,gold,tmpp);VecDot(gold,tmpp,&initRnorm);
317 initRnorm = sqrt(initRnorm);
318 _printf0_(
"inner product norm g0: "<<initRnorm<<
"\n");
326 VecDuplicate(gold,&gnew);VecCopy(gold,gnew);
327 VecAssemblyBegin(gnew);VecAssemblyEnd(gnew);
334 VecDuplicate(gold,&wold);VecCopy(gold,wold);
335 VecAssemblyBegin(wold);VecAssemblyEnd(wold);
345 _printf0_(
"\n###### Step " << count <<
" ######\n");
351 VecScale(wold,1.);MatMult(B,wold,rhsu);VecScale(wold,1.);
357 VecScale(rhsu,-1.);MatMultAdd(A,chi,rhsu,tmpu);VecScale(rhsu,-1.);
358 VecNorm(tmpu,NORM_2,&tmp4);
360 KSPInitialResidual(kspu,chi,tmpu,tmpu2,resu,rhsu);
361 VecNorm(resu,NORM_2,&tmp5);
366 KSPSolve(kspu,rhsu,chi);
373 VecNorm(chi,NORM_2,&tmp1);
374 KSPGetResidualNorm(kspu,&tmp2);
376 VecScale(rhsu,-1.);MatMultAdd(A,chi,rhsu,tmpu);VecScale(rhsu,-1.);
377 VecNorm(tmpu,NORM_2,&tmp3);
380 KSPGetIterationNumber(kspu,&tmpi);
381 _printf0_(
"||chi_nk||_euc: "<< tmp1 <<
"\n||A*chi_0k - rhsu||_euc: "<<tmp4<<
"\n||P(-1)*(A*chi_0k-rhsu)||_euc: " << tmp5 <<
"\n||A*chi_nk - rhsu||_euc: "<< tmp3 <<
"\n||P(-1)*(A*chi_nk - rhsu)||_euc: " << tmp2 <<
"\nIteration Number: " << tmpi <<
"\n");
390 MatMult(IP,gold,tmpp);
391 VecDot(tmpp,wold,&rho);
393 MatMult(BT,chi,tmpp);
394 VecDot(tmpp,wold,&tmpScalar);
403 VecAXPY(p,-1.*rho,wold);
408 VecWAXPY(unew,rho,chi,uold);
409 VecNorm(unew,NORM_2,&tmpScalar);
414 VecScale(p,-1.);MatMultAdd(B,p,f1,rhsu);VecScale(p,-1.);
415 VecScale(rhsu,-1.);MatMultAdd(A,unew,rhsu,tmpu);VecScale(rhsu,-1.);
416 VecNorm(tmpu,NORM_2,&tmp6);
418 VecScale(f2,-1);MatMultAdd(BT,unew,f2,tmpp);VecScale(f2,-1);
419 VecNorm(tmpp,NORM_2,&tmp7);
420 _printf0_(
"Momentum balance norm: " << tmp6 <<
"\n");
421 _printf0_(
"Incompressibility norm: " << tmp7 <<
"\n");
430 MatMult(BT,chi,tmpp);
431 MatMult(IP,gold,tmpp2);
432 VecWAXPY(rhsp,-1.*rho,tmpp,tmpp2);
433 KSPSolve(kspip,rhsp,gnew);
439 MatMult(IP,gnew,tmpp);
441 VecDot(tmpp,gnew,&gamma);
445 if(rnorm < TOL*initRnorm)
448 }
else if(rnorm > 1000*initRnorm)
450 _printf0_(
"L2-Norm g: "<< rnorm <<
"\n");
451 _printf0_(
"Solver diverged and ends prematurely.\n");
454 _printf0_(
"L2-Norm g: "<< rnorm <<
"\n");
460 _printf0_(
"Ended after " << ceil(5./TOL) <<
" CG iterations\n");
469 MatMult(IP,gold,tmpp);
470 VecDot(tmpp,gold,&tmpScalar);
471 gamma = gamma/tmpScalar;
473 VecWAXPY(wnew,gamma,wold,gnew);
476 VecCopy(wnew,wold);VecCopy(gnew,gold);VecCopy(unew,uold);
483 VecRestoreSubVector(out_uf->pvector->vector,isv,&unew);
484 VecRestoreSubVector(out_uf->pvector->vector,isp,&p);
491 KSPDestroy(&kspu);KSPDestroy(&kspip);
493 MatDestroy(&A);MatDestroy(&B);MatDestroy(&BT);MatDestroy(&IP);
495 VecDestroy(&p);VecDestroy(&uold);VecDestroy(&unew);VecDestroy(&rhsu);VecDestroy(&rhsp);
496 VecDestroy(&gold);VecDestroy(&gnew);VecDestroy(&wold);VecDestroy(&wnew);VecDestroy(&chi);
497 VecDestroy(&tmpp);VecDestroy(&tmpu);VecDestroy(&f1);VecDestroy(&f2);
498 VecDestroy(&tmpu2);VecDestroy(&tmpp2);VecDestroy(&resu);VecDestroy(&resp);
504 bool converged=
false;
520 Vec u,p,uold,pold,f1,f2,tmp,res1,res2;
522 double rnorm1, rnorm2;
542 MatCreateSubMatrix(Kff->pmatrix->matrix,isv,isv,MAT_INITIAL_MATRIX,&A);
543 MatCreateSubMatrix(Kff->pmatrix->matrix,isv,isp,MAT_INITIAL_MATRIX,&B);
544 MatCreateSubMatrix(Kff->pmatrix->matrix,isp,isv,MAT_INITIAL_MATRIX,&BT);
546 MatGetSubMatrix(Kff->pmatrix->matrix,isv,isv,MAT_INITIAL_MATRIX,&A);
547 MatGetSubMatrix(Kff->pmatrix->matrix,isv,isp,MAT_INITIAL_MATRIX,&B);
548 MatGetSubMatrix(Kff->pmatrix->matrix,isp,isv,MAT_INITIAL_MATRIX,&BT);
552 MatGetSize(B,&n_u,&n_p);
555 VecCreate(
IssmComm::GetComm(),&p);VecSetSizes(p,PETSC_DECIDE,n_p);VecSetFromOptions(p);
556 VecAssemblyBegin(p);VecAssemblyEnd(p);
557 VecCreate(
IssmComm::GetComm(),&u);VecSetSizes(u,PETSC_DECIDE,n_u);VecSetFromOptions(u);
558 VecAssemblyBegin(u);VecAssemblyEnd(u);
560 VecGetSubVector(uf->pvector->vector,isv,&u);
561 VecGetSubVector(uf->pvector->vector,isp,&p);
565 VecDuplicate(u,&f1);VecSet(f1,1.0);
566 VecDuplicate(p,&f2);VecSet(f2,1.0);
567 VecGetSubVector(pf->pvector->vector,isv,&f1);
568 VecGetSubVector(pf->pvector->vector,isp,&f2);
571 VecDuplicate(u,&res1);VecSet(res1,1.0);
572 VecDuplicate(u,&tmp);VecSet(tmp,1.0);
573 VecDuplicate(p,&res2);VecSet(res2,1.0);
580 VecScale(f1,-1.);MatMultAdd(A,u,f1,tmp);MatMultAdd(B,p,tmp,res1);VecScale(f1,-1.);
582 VecScale(f2,-1.);MatMultAdd(BT,u,f2,res2);VecScale(f2,-1.);
586 VecNorm(res1,NORM_2,&rnorm1);VecNorm(res2,NORM_2,&rnorm2);
587 nKUF=sqrt(rnorm1*rnorm1 + rnorm2*rnorm2);
589 solver_residue=nKUF/nF;
590 _printf0_(
"\n" <<
" solver residue: norm(KU-F)/norm(F)=" << solver_residue <<
"\n");
591 if(xIsNan<IssmDouble>(solver_residue)){
597 VecRestoreSubVector(uf->pvector->vector,isv,&u);
598 VecRestoreSubVector(uf->pvector->vector,isp,&p);
601 VecGetSubVector(old_uf->pvector->vector,isv,&uold);
602 VecGetSubVector(old_uf->pvector->vector,isp,&pold);
608 VecScale(f1,-1.);MatMultAdd(A,uold,f1,tmp);MatMultAdd(B,pold,tmp,res1);VecScale(f1,-1.);
610 VecScale(f2,-1.);MatMultAdd(BT,uold,f2,res2);VecScale(f2,-1.);
613 VecNorm(res1,NORM_2,&rnorm1);VecNorm(res2,NORM_2,&rnorm2);
614 nKUoldF=sqrt(rnorm1*rnorm1 + rnorm2*rnorm2);
617 if (xIsNan<IssmDouble>(res)){
618 _printf0_(
"norm nf = " << nF <<
"f and norm kuold = " << nKUoldF <<
"f\n");
619 _error_(
"mechanical equilibrium convergence criterion is NaN!");
622 MatDestroy(&A);MatDestroy(&B);MatDestroy(&BT);
623 VecRestoreSubVector(pf->pvector->vector,isv,&f1);
624 VecRestoreSubVector(pf->pvector->vector,isp,&f2);
625 VecDestroy(&res1);VecDestroy(&res2);VecDestroy(&tmp);
626 VecRestoreSubVector(old_uf->pvector->vector,isv,&uold);
627 VecRestoreSubVector(old_uf->pvector->vector,isp,&pold);
633 if(
VerboseConvergence())
_printf0_(setw(50)<<left<<
" mechanical equilibrium convergence criterion"<<res*100<<
" < "<<eps_res*100<<
" %\n");
637 if(
VerboseConvergence())
_printf0_(setw(50)<<left<<
" mechanical equilibrium convergence criterion"<<res*100<<
" > "<<eps_res*100<<
" %\n");
648 if (xIsNan<IssmDouble>(ndu) || xIsNan<IssmDouble>(nu))
_error_(
"convergence criterion is NaN!");
654 if (!xIsNan<IssmDouble>(eps_rel)){
655 if((ndu/nu)<eps_rel){
656 if(
VerboseConvergence())
_printf0_(setw(50) << left <<
" Convergence criterion: norm(du)/norm(u)" << ndu/nu*100 <<
" < " << eps_rel*100 <<
" %\n");
659 if(
VerboseConvergence())
_printf0_(setw(50) << left <<
" Convergence criterion: norm(du)/norm(u)" << ndu/nu*100 <<
" > " << eps_rel*100 <<
" %\n");
663 else _printf0_(setw(50) << left <<
" Convergence criterion: norm(du)/norm(u)" << ndu/nu*100 <<
" %\n");
673 if (xIsNan<IssmDouble>(ndu) || xIsNan<IssmDouble>(nu))
_error_(
"convergence criterion is NaN!");
679 if (!xIsNan<IssmDouble>(eps_abs)){
680 if ((nduinf)<eps_abs){
688 else _printf0_(setw(50) << left <<
" Convergence criterion: max(du)" << nduinf <<
"\n");
693 *pconverged=converged;
708 int max_nonlinear_iterations;
709 int configuration_type;
722 bool converged=
false;
735 delete old_uf; old_uf=uf;
745 PetscOptionsGetInt(PETSC_NULL,
"-schur_pc",&precond,NULL);
747 PetscOptionsGetInt(NULL,PETSC_NULL,
"-schur_pc",&precond,NULL);
780 if(!(df->pvector->vector))
_error_(
"need doftypes for FS solver!\n");
794 Kff->pmatrix->matrix,
796 old_uf->pvector->vector,
806 convergence_schurcg(&converged,Kff,pf,uf,old_uf,eps_res,eps_rel,eps_abs,isv,isp);
delete Kff;
delete pf;
delete df;
809 if(count>=max_nonlinear_iterations){
810 _printf0_(
" maximum number of nonlinear iterations (" << max_nonlinear_iterations <<
") exceeded\n");