static PetscErrorCode PCApplyTranspose_KSP(PC pc,Vec x,Vec y) { PetscErrorCode ierr; PetscInt its; PC_KSP *jac = (PC_KSP*)pc->data; PetscFunctionBegin; ierr = KSPSolveTranspose(jac->ksp,x,y);CHKERRQ(ierr); ierr = KSPGetIterationNumber(jac->ksp,&its);CHKERRQ(ierr); jac->its += its; PetscFunctionReturn(0); }
static PetscErrorCode PCApplyTranspose_Redundant(PC pc,Vec x,Vec y) { PC_Redundant *red = (PC_Redundant*)pc->data; PetscErrorCode ierr; PetscScalar *array; PetscFunctionBegin; if (!red->useparallelmat) { ierr = KSPSolveTranspose(red->ksp,x,y);CHKERRQ(ierr); ierr = KSPCheckSolve(red->ksp,pc,y);CHKERRQ(ierr); PetscFunctionReturn(0); } /* scatter x to xdup */ ierr = VecScatterBegin(red->scatterin,x,red->xdup,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(red->scatterin,x,red->xdup,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); /* place xdup's local array into xsub */ ierr = VecGetArray(red->xdup,&array);CHKERRQ(ierr); ierr = VecPlaceArray(red->xsub,(const PetscScalar*)array);CHKERRQ(ierr); /* apply preconditioner on each processor */ ierr = KSPSolveTranspose(red->ksp,red->xsub,red->ysub);CHKERRQ(ierr); ierr = KSPCheckSolve(red->ksp,pc,red->ysub);CHKERRQ(ierr); ierr = VecResetArray(red->xsub);CHKERRQ(ierr); ierr = VecRestoreArray(red->xdup,&array);CHKERRQ(ierr); /* place ysub's local array into ydup */ ierr = VecGetArray(red->ysub,&array);CHKERRQ(ierr); ierr = VecPlaceArray(red->ydup,(const PetscScalar*)array);CHKERRQ(ierr); /* scatter ydup to y */ ierr = VecScatterBegin(red->scatterout,red->ydup,y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(red->scatterout,red->ydup,y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecResetArray(red->ydup);CHKERRQ(ierr); ierr = VecRestoreArray(red->ysub,&array);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode MatMultTranspose_SchurComplement(Mat N,Vec x,Vec y) { Mat_SchurComplement *Na = (Mat_SchurComplement*)N->data; PetscErrorCode ierr; PetscFunctionBegin; if (!Na->work1) {ierr = MatCreateVecs(Na->A,&Na->work1,NULL);CHKERRQ(ierr);} if (!Na->work2) {ierr = MatCreateVecs(Na->A,&Na->work2,NULL);CHKERRQ(ierr);} ierr = MatMultTranspose(Na->C,x,Na->work1);CHKERRQ(ierr); ierr = KSPSolveTranspose(Na->ksp,Na->work1,Na->work2);CHKERRQ(ierr); ierr = MatMultTranspose(Na->B,Na->work2,y);CHKERRQ(ierr); ierr = VecScale(y,-1.0);CHKERRQ(ierr); if (Na->D) { ierr = MatMultTransposeAdd(Na->D,x,y,y);CHKERRQ(ierr); } PetscFunctionReturn(0); }
static PetscErrorCode PCBDDCScalingExtension_Deluxe(PC pc, Vec x, Vec y) { PC_IS* pcis=(PC_IS*)pc->data; PC_BDDC* pcbddc=(PC_BDDC*)pc->data; PCBDDCDeluxeScaling deluxe_ctx = pcbddc->deluxe_ctx; PetscErrorCode ierr; PetscFunctionBegin; ierr = VecSet(pcbddc->work_scaling,0.0);CHKERRQ(ierr); ierr = VecSet(y,0.0);CHKERRQ(ierr); if (deluxe_ctx->n_simple) { /* scale deluxe vertices using diagonal scaling */ PetscInt i; const PetscScalar *array_x,*array_D; PetscScalar *array; ierr = VecGetArrayRead(x,&array_x);CHKERRQ(ierr); ierr = VecGetArrayRead(pcis->D,&array_D);CHKERRQ(ierr); ierr = VecGetArray(pcbddc->work_scaling,&array);CHKERRQ(ierr); for (i=0;i<deluxe_ctx->n_simple;i++) { array[deluxe_ctx->idx_simple_B[i]] = array_x[deluxe_ctx->idx_simple_B[i]]*array_D[deluxe_ctx->idx_simple_B[i]]; } ierr = VecRestoreArray(pcbddc->work_scaling,&array);CHKERRQ(ierr); ierr = VecRestoreArrayRead(pcis->D,&array_D);CHKERRQ(ierr); ierr = VecRestoreArrayRead(x,&array_x);CHKERRQ(ierr); } /* sequential part : all problems and Schur applications collapsed into a single matrix vector multiplication or a matvec and a solve */ if (deluxe_ctx->seq_mat) { ierr = VecScatterBegin(deluxe_ctx->seq_scctx,x,deluxe_ctx->seq_work1,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(deluxe_ctx->seq_scctx,x,deluxe_ctx->seq_work1,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = MatMultTranspose(deluxe_ctx->seq_mat,deluxe_ctx->seq_work1,deluxe_ctx->seq_work2);CHKERRQ(ierr); if (deluxe_ctx->seq_ksp) { ierr = KSPSolveTranspose(deluxe_ctx->seq_ksp,deluxe_ctx->seq_work2,deluxe_ctx->seq_work2);CHKERRQ(ierr); } ierr = VecScatterBegin(deluxe_ctx->seq_scctx,deluxe_ctx->seq_work2,pcbddc->work_scaling,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); ierr = VecScatterEnd(deluxe_ctx->seq_scctx,deluxe_ctx->seq_work2,pcbddc->work_scaling,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); } /* put local boundary part in global vector */ ierr = VecScatterBegin(pcis->global_to_B,pcbddc->work_scaling,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); ierr = VecScatterEnd(pcis->global_to_B,pcbddc->work_scaling,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **args) { Mat C; PetscErrorCode ierr; PetscInt N = 2,rowidx,colidx; Vec u,b,r; KSP ksp; PetscReal norm; PetscMPIInt rank,size; PetscScalar v; PetscInitialize(&argc,&args,(char*)0,help); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank); CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size); CHKERRQ(ierr); /* create stiffness matrix C = [1 2; 2 3] */ ierr = MatCreate(PETSC_COMM_WORLD,&C); CHKERRQ(ierr); ierr = MatSetSizes(C,PETSC_DECIDE,PETSC_DECIDE,N,N); CHKERRQ(ierr); ierr = MatSetFromOptions(C); CHKERRQ(ierr); ierr = MatSetUp(C); CHKERRQ(ierr); if (!rank) { rowidx = 0; colidx = 0; v = 1.0; ierr = MatSetValues(C,1,&rowidx,1,&colidx,&v,INSERT_VALUES); CHKERRQ(ierr); rowidx = 0; colidx = 1; v = 2.0; ierr = MatSetValues(C,1,&rowidx,1,&colidx,&v,INSERT_VALUES); CHKERRQ(ierr); rowidx = 1; colidx = 0; v = 2.0; ierr = MatSetValues(C,1,&rowidx,1,&colidx,&v,INSERT_VALUES); CHKERRQ(ierr); rowidx = 1; colidx = 1; v = 3.0; ierr = MatSetValues(C,1,&rowidx,1,&colidx,&v,INSERT_VALUES); CHKERRQ(ierr); } ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); /* create right hand side and solution */ ierr = VecCreate(PETSC_COMM_WORLD,&u); CHKERRQ(ierr); ierr = VecSetSizes(u,PETSC_DECIDE,N); CHKERRQ(ierr); ierr = VecSetFromOptions(u); CHKERRQ(ierr); ierr = VecDuplicate(u,&b); CHKERRQ(ierr); ierr = VecDuplicate(u,&r); CHKERRQ(ierr); ierr = VecSet(u,0.0); CHKERRQ(ierr); ierr = VecSet(b,1.0); CHKERRQ(ierr); /* solve linear system C*u = b */ ierr = KSPCreate(PETSC_COMM_WORLD,&ksp); CHKERRQ(ierr); ierr = KSPSetOperators(ksp,C,C); CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp); CHKERRQ(ierr); ierr = KSPSolve(ksp,b,u); CHKERRQ(ierr); /* check residual r = C*u - b */ ierr = MatMult(C,u,r); CHKERRQ(ierr); ierr = VecAXPY(r,-1.0,b); CHKERRQ(ierr); ierr = VecNorm(r,NORM_2,&norm); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"|| C*u - b|| = %g\n",(double)norm); CHKERRQ(ierr); /* solve C^T*u = b twice */ ierr = KSPSolveTranspose(ksp,b,u); CHKERRQ(ierr); /* check residual r = C^T*u - b */ ierr = MatMultTranspose(C,u,r); CHKERRQ(ierr); ierr = VecAXPY(r,-1.0,b); CHKERRQ(ierr); ierr = VecNorm(r,NORM_2,&norm); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"|| C^T*u - b|| = %g\n",(double)norm); CHKERRQ(ierr); ierr = KSPSolveTranspose(ksp,b,u); CHKERRQ(ierr); ierr = MatMultTranspose(C,u,r); CHKERRQ(ierr); ierr = VecAXPY(r,-1.0,b); CHKERRQ(ierr); ierr = VecNorm(r,NORM_2,&norm); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"|| C^T*u - b|| = %g\n",(double)norm); CHKERRQ(ierr); /* solve C*u = b again */ ierr = KSPSolve(ksp,b,u); CHKERRQ(ierr); ierr = MatMult(C,u,r); CHKERRQ(ierr); ierr = VecAXPY(r,-1.0,b); CHKERRQ(ierr); ierr = VecNorm(r,NORM_2,&norm); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"|| C*u - b|| = %g\n",(double)norm); CHKERRQ(ierr); ierr = KSPDestroy(&ksp); CHKERRQ(ierr); ierr = VecDestroy(&u); CHKERRQ(ierr); ierr = VecDestroy(&r); CHKERRQ(ierr); ierr = VecDestroy(&b); CHKERRQ(ierr); ierr = MatDestroy(&C); CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
static PetscErrorCode PCBDDCScalingRestriction_Deluxe(PC pc, Vec x, Vec y) { PC_IS* pcis=(PC_IS*)pc->data; PC_BDDC* pcbddc=(PC_BDDC*)pc->data; PCBDDCDeluxeScaling deluxe_ctx = pcbddc->deluxe_ctx; PetscErrorCode ierr; PetscFunctionBegin; /* get local boundary part of global vector */ ierr = VecScatterBegin(pcis->global_to_B,x,y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(pcis->global_to_B,x,y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); if (deluxe_ctx->n_simple) { /* scale deluxe vertices using diagonal scaling */ PetscInt i; PetscScalar *array_y; const PetscScalar *array_D; ierr = VecGetArray(y,&array_y);CHKERRQ(ierr); ierr = VecGetArrayRead(pcis->D,&array_D);CHKERRQ(ierr); for (i=0;i<deluxe_ctx->n_simple;i++) { array_y[deluxe_ctx->idx_simple_B[i]] *= array_D[deluxe_ctx->idx_simple_B[i]]; } ierr = VecRestoreArrayRead(pcis->D,&array_D);CHKERRQ(ierr); ierr = VecRestoreArray(y,&array_y);CHKERRQ(ierr); } /* sequential part : all problems and Schur applications collapsed into a single matrix vector multiplication or a matvec and a solve */ if (deluxe_ctx->seq_mat) { PetscInt i; for (i=0;i<deluxe_ctx->seq_n;i++) { if (deluxe_ctx->change) { Mat change; ierr = VecScatterBegin(deluxe_ctx->seq_scctx[i],y,deluxe_ctx->seq_work2[i],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(deluxe_ctx->seq_scctx[i],y,deluxe_ctx->seq_work2[i],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = KSPGetOperators(deluxe_ctx->change[i],&change,NULL);CHKERRQ(ierr); ierr = MatMultTranspose(change,deluxe_ctx->seq_work2[i],deluxe_ctx->seq_work1[i]);CHKERRQ(ierr); } else { ierr = VecScatterBegin(deluxe_ctx->seq_scctx[i],y,deluxe_ctx->seq_work1[i],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(deluxe_ctx->seq_scctx[i],y,deluxe_ctx->seq_work1[i],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); } if (deluxe_ctx->seq_mat_inv_sum[i]) { PetscScalar *x; ierr = VecGetArray(deluxe_ctx->seq_work1[i],&x);CHKERRQ(ierr); ierr = VecPlaceArray(deluxe_ctx->seq_work2[i],x);CHKERRQ(ierr); ierr = VecRestoreArray(deluxe_ctx->seq_work1[i],&x);CHKERRQ(ierr); ierr = MatSolve(deluxe_ctx->seq_mat_inv_sum[i],deluxe_ctx->seq_work1[i],deluxe_ctx->seq_work2[i]);CHKERRQ(ierr); ierr = VecResetArray(deluxe_ctx->seq_work2[i]);CHKERRQ(ierr); } ierr = MatMult(deluxe_ctx->seq_mat[i],deluxe_ctx->seq_work1[i],deluxe_ctx->seq_work2[i]);CHKERRQ(ierr); if (deluxe_ctx->change) { if (deluxe_ctx->change_with_qr) { Mat change; ierr = KSPGetOperators(deluxe_ctx->change[i],&change,NULL);CHKERRQ(ierr); ierr = MatMult(change,deluxe_ctx->seq_work2[i],deluxe_ctx->seq_work1[i]);CHKERRQ(ierr); } else { ierr = KSPSolveTranspose(deluxe_ctx->change[i],deluxe_ctx->seq_work2[i],deluxe_ctx->seq_work1[i]);CHKERRQ(ierr); } ierr = VecScatterBegin(deluxe_ctx->seq_scctx[i],deluxe_ctx->seq_work1[i],y,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); ierr = VecScatterEnd(deluxe_ctx->seq_scctx[i],deluxe_ctx->seq_work1[i],y,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); } else { ierr = VecScatterBegin(deluxe_ctx->seq_scctx[i],deluxe_ctx->seq_work2[i],y,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); ierr = VecScatterEnd(deluxe_ctx->seq_scctx[i],deluxe_ctx->seq_work2[i],y,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); } } } PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscErrorCode ierr; KSP ksp; PC pc; Vec x,b; DM da; Mat A,Atrans; PetscInt dof=1,M=8; PetscBool flg,trans=PETSC_FALSE; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = PetscOptionsGetInt(NULL,NULL,"-dof",&dof,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-M",&M,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-trans",&trans,NULL);CHKERRQ(ierr); ierr = DMDACreate(PETSC_COMM_WORLD,&da);CHKERRQ(ierr); ierr = DMSetDimension(da,3);CHKERRQ(ierr); ierr = DMDASetBoundaryType(da,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE);CHKERRQ(ierr); ierr = DMDASetStencilType(da,DMDA_STENCIL_STAR);CHKERRQ(ierr); ierr = DMDASetSizes(da,M,M,M);CHKERRQ(ierr); ierr = DMDASetNumProcs(da,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); ierr = DMDASetDof(da,dof);CHKERRQ(ierr); ierr = DMDASetStencilWidth(da,1);CHKERRQ(ierr); ierr = DMDASetOwnershipRanges(da,NULL,NULL,NULL);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&x);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&b);CHKERRQ(ierr); ierr = ComputeRHS(da,b);CHKERRQ(ierr); ierr = DMSetMatType(da,MATBAIJ);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMCreateMatrix(da,&A);CHKERRQ(ierr); ierr = ComputeMatrix(da,A);CHKERRQ(ierr); /* A is non-symmetric. Make A = 0.5*(A + Atrans) symmetric for testing icc and cholesky */ ierr = MatTranspose(A,MAT_INITIAL_MATRIX,&Atrans);CHKERRQ(ierr); ierr = MatAXPY(A,1.0,Atrans,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); ierr = MatScale(A,0.5);CHKERRQ(ierr); ierr = MatDestroy(&Atrans);CHKERRQ(ierr); /* Test sbaij matrix */ flg = PETSC_FALSE; ierr = PetscOptionsGetBool(NULL,NULL, "-test_sbaij1", &flg,NULL);CHKERRQ(ierr); if (flg) { Mat sA; PetscBool issymm; ierr = MatIsTranspose(A,A,0.0,&issymm);CHKERRQ(ierr); if (issymm) { ierr = MatSetOption(A,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); } else {ierr = PetscPrintf(PETSC_COMM_WORLD,"Warning: A is non-symmetric\n");CHKERRQ(ierr);} ierr = MatConvert(A,MATSBAIJ,MAT_INITIAL_MATRIX,&sA);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); A = sA; } ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); ierr = KSPSetOperators(ksp,A,A);CHKERRQ(ierr); ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); ierr = PCSetDM(pc,(DM)da);CHKERRQ(ierr); if (trans) { ierr = KSPSolveTranspose(ksp,b,x);CHKERRQ(ierr); } else { ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); } /* check final residual */ flg = PETSC_FALSE; ierr = PetscOptionsGetBool(NULL,NULL, "-check_final_residual", &flg,NULL);CHKERRQ(ierr); if (flg) { Vec b1; PetscReal norm; ierr = KSPGetSolution(ksp,&x);CHKERRQ(ierr); ierr = VecDuplicate(b,&b1);CHKERRQ(ierr); ierr = MatMult(A,x,b1);CHKERRQ(ierr); ierr = VecAXPY(b1,-1.0,b);CHKERRQ(ierr); ierr = VecNorm(b1,NORM_2,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Final residual %g\n",norm);CHKERRQ(ierr); ierr = VecDestroy(&b1);CHKERRQ(ierr); } ierr = KSPDestroy(&ksp);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
static PetscErrorCode TSAdjointStep_Theta(TS ts) { TS_Theta *th = (TS_Theta*)ts->data; Vec *VecsDeltaLam = th->VecsDeltaLam,*VecsDeltaMu = th->VecsDeltaMu,*VecsSensiTemp = th->VecsSensiTemp; PetscInt nadj; PetscErrorCode ierr; Mat J,Jp; KSP ksp; PetscReal shift; PetscFunctionBegin; th->status = TS_STEP_INCOMPLETE; ierr = SNESGetKSP(ts->snes,&ksp);CHKERRQ(ierr); ierr = TSGetIJacobian(ts,&J,&Jp,NULL,NULL);CHKERRQ(ierr); /* If endpoint=1, th->ptime and th->X0 will be used; if endpoint=0, th->stage_time and th->X will be used. */ th->stage_time = ts->ptime + (th->endpoint ? ts->time_step : (1.-th->Theta)*ts->time_step); /* time_step is negative*/ th->ptime = ts->ptime + ts->time_step; /* Build RHS */ if (ts->vec_costintegral) { /* Cost function has an integral term */ if (th->endpoint) { ierr = TSAdjointComputeDRDYFunction(ts,ts->ptime,ts->vec_sol,ts->vecs_drdy);CHKERRQ(ierr); }else { ierr = TSAdjointComputeDRDYFunction(ts,th->stage_time,th->X,ts->vecs_drdy);CHKERRQ(ierr); } } for (nadj=0; nadj<ts->numcost; nadj++) { ierr = VecCopy(ts->vecs_sensi[nadj],VecsSensiTemp[nadj]);CHKERRQ(ierr); ierr = VecScale(VecsSensiTemp[nadj],-1./(th->Theta*ts->time_step));CHKERRQ(ierr); if (ts->vec_costintegral) { ierr = VecAXPY(VecsSensiTemp[nadj],1.,ts->vecs_drdy[nadj]);CHKERRQ(ierr); } } /* Build LHS */ shift = -1./(th->Theta*ts->time_step); if (th->endpoint) { ierr = TSComputeIJacobian(ts,ts->ptime,ts->vec_sol,th->Xdot,shift,J,Jp,PETSC_FALSE);CHKERRQ(ierr); }else { ierr = TSComputeIJacobian(ts,th->stage_time,th->X,th->Xdot,shift,J,Jp,PETSC_FALSE);CHKERRQ(ierr); } ierr = KSPSetOperators(ksp,J,Jp);CHKERRQ(ierr); /* Solve LHS X = RHS */ for (nadj=0; nadj<ts->numcost; nadj++) { ierr = KSPSolveTranspose(ksp,VecsSensiTemp[nadj],VecsDeltaLam[nadj]);CHKERRQ(ierr); } /* Update sensitivities, and evaluate integrals if there is any */ if(th->endpoint) { /* two-stage case */ if (th->Theta!=1.) { shift = -1./((th->Theta-1.)*ts->time_step); ierr = TSComputeIJacobian(ts,th->ptime,th->X0,th->Xdot,shift,J,Jp,PETSC_FALSE);CHKERRQ(ierr); if (ts->vec_costintegral) { ierr = TSAdjointComputeDRDYFunction(ts,th->ptime,th->X0,ts->vecs_drdy);CHKERRQ(ierr); } for (nadj=0; nadj<ts->numcost; nadj++) { ierr = MatMultTranspose(J,VecsDeltaLam[nadj],ts->vecs_sensi[nadj]);CHKERRQ(ierr); if (ts->vec_costintegral) { ierr = VecAXPY(ts->vecs_sensi[nadj],-1.,ts->vecs_drdy[nadj]);CHKERRQ(ierr); } ierr = VecScale(ts->vecs_sensi[nadj],1./shift);CHKERRQ(ierr); } }else { /* backward Euler */ shift = 0.0; ierr = TSComputeIJacobian(ts,ts->ptime,ts->vec_sol,th->Xdot,shift,J,Jp,PETSC_FALSE);CHKERRQ(ierr); /* get -f_y */ for (nadj=0; nadj<ts->numcost; nadj++) { ierr = MatMultTranspose(J,VecsDeltaLam[nadj],VecsSensiTemp[nadj]);CHKERRQ(ierr); ierr = VecAXPY(ts->vecs_sensi[nadj],ts->time_step,VecsSensiTemp[nadj]);CHKERRQ(ierr); if (ts->vec_costintegral) { ierr = VecAXPY(ts->vecs_sensi[nadj],-ts->time_step,ts->vecs_drdy[nadj]);CHKERRQ(ierr); } } } if (ts->vecs_sensip) { /* sensitivities wrt parameters */ ierr = TSAdjointComputeRHSJacobian(ts,ts->ptime,ts->vec_sol,ts->Jacp);CHKERRQ(ierr); for (nadj=0; nadj<ts->numcost; nadj++) { ierr = MatMultTranspose(ts->Jacp,VecsDeltaLam[nadj],VecsDeltaMu[nadj]);CHKERRQ(ierr); ierr = VecAXPY(ts->vecs_sensip[nadj],-ts->time_step*th->Theta,VecsDeltaMu[nadj]);CHKERRQ(ierr); } if (th->Theta!=1.) { ierr = TSAdjointComputeRHSJacobian(ts,th->ptime,th->X0,ts->Jacp);CHKERRQ(ierr); for (nadj=0; nadj<ts->numcost; nadj++) { ierr = MatMultTranspose(ts->Jacp,VecsDeltaLam[nadj],VecsDeltaMu[nadj]);CHKERRQ(ierr); ierr = VecAXPY(ts->vecs_sensip[nadj],-ts->time_step*(1.-th->Theta),VecsDeltaMu[nadj]);CHKERRQ(ierr); } } if (ts->vec_costintegral) { ierr = TSAdjointComputeDRDPFunction(ts,ts->ptime,ts->vec_sol,ts->vecs_drdp);CHKERRQ(ierr); for (nadj=0; nadj<ts->numcost; nadj++) { ierr = VecAXPY(ts->vecs_sensip[nadj],-ts->time_step*th->Theta,ts->vecs_drdp[nadj]);CHKERRQ(ierr); } if (th->Theta!=1.) { ierr = TSAdjointComputeDRDPFunction(ts,th->ptime,th->X0,ts->vecs_drdp);CHKERRQ(ierr); for (nadj=0; nadj<ts->numcost; nadj++) { ierr = VecAXPY(ts->vecs_sensip[nadj],-ts->time_step*(1.-th->Theta),ts->vecs_drdp[nadj]);CHKERRQ(ierr); } } } } }else { /* one-stage case */ shift = 0.0; ierr = TSComputeIJacobian(ts,th->stage_time,th->X,th->Xdot,shift,J,Jp,PETSC_FALSE);CHKERRQ(ierr); /* get -f_y */ if (ts->vec_costintegral) { ierr = TSAdjointComputeDRDYFunction(ts,th->stage_time,th->X,ts->vecs_drdy);CHKERRQ(ierr); } for (nadj=0; nadj<ts->numcost; nadj++) { ierr = MatMultTranspose(J,VecsDeltaLam[nadj],VecsSensiTemp[nadj]);CHKERRQ(ierr); ierr = VecAXPY(ts->vecs_sensi[nadj],ts->time_step,VecsSensiTemp[nadj]);CHKERRQ(ierr); if (ts->vec_costintegral) { ierr = VecAXPY(ts->vecs_sensi[nadj],-ts->time_step,ts->vecs_drdy[nadj]);CHKERRQ(ierr); } } if (ts->vecs_sensip) { ierr = TSAdjointComputeRHSJacobian(ts,th->stage_time,th->X,ts->Jacp);CHKERRQ(ierr); for (nadj=0; nadj<ts->numcost; nadj++) { ierr = MatMultTranspose(ts->Jacp,VecsDeltaLam[nadj],VecsDeltaMu[nadj]);CHKERRQ(ierr); ierr = VecAXPY(ts->vecs_sensip[nadj],-ts->time_step,VecsDeltaMu[nadj]);CHKERRQ(ierr); } if (ts->vec_costintegral) { ierr = TSAdjointComputeDRDPFunction(ts,th->stage_time,th->X,ts->vecs_drdp);CHKERRQ(ierr); for (nadj=0; nadj<ts->numcost; nadj++) { ierr = VecAXPY(ts->vecs_sensip[nadj],-ts->time_step,ts->vecs_drdp[nadj]);CHKERRQ(ierr); } } } } th->status = TS_STEP_COMPLETE; PetscFunctionReturn(0); }
Written as requested by [petsc-maint #63875] \n\n"; #include <petscksp.h> #undef __FUNCT__ #define __FUNCT__ "main" int main(int argc,char **args) { Vec x,x2,b,u; /* approx solution, RHS, exact solution */ Mat A; /* linear system matrix */ KSP ksp; /* linear solver context */ PC pc; /* preconditioner context */ PetscReal norm,tol=1.e-14; /* norm of solution error */ PetscErrorCode ierr; PetscInt i,n = 10,col[3],its; PetscMPIInt rank; PetscScalar neg_one = -1.0,one = 1.0,value[3]; PetscInitialize(&argc,&args,(char*)0,help); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-n",&n,NULL);CHKERRQ(ierr); /* Create vectors.*/ ierr = VecCreate(PETSC_COMM_WORLD,&x);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) x, "Solution");CHKERRQ(ierr); ierr = VecSetSizes(x,PETSC_DECIDE,n);CHKERRQ(ierr); ierr = VecSetFromOptions(x);CHKERRQ(ierr); ierr = VecDuplicate(x,&b);CHKERRQ(ierr); ierr = VecDuplicate(x,&u);CHKERRQ(ierr); ierr = VecDuplicate(x,&x2);CHKERRQ(ierr); /* Create matrix. Only proc[0] sets values - not efficient for parallel processing! See ex23.c for efficient parallel assembly matrix */ ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,n,n);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); if (!rank) { value[0] = -1.0; value[1] = 2.0; value[2] = -1.0; for (i=1; i<n-1; i++) { col[0] = i-1; col[1] = i; col[2] = i+1; ierr = MatSetValues(A,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); } i = n - 1; col[0] = n - 2; col[1] = n - 1; ierr = MatSetValues(A,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); i = 0; col[0] = 0; col[1] = 1; value[0] = 2.0; value[1] = -1.0; ierr = MatSetValues(A,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); i = 0; col[0] = n-1; value[0] = 0.5; /* make A non-symmetric */ ierr = MatSetValues(A,1,&i,1,col,value,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Set exact solution */ ierr = VecSet(u,one);CHKERRQ(ierr); /* Create linear solver context */ ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr); ierr = KSPSetOperators(ksp,A,A,SAME_PRECONDITIONER);CHKERRQ(ierr); ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); ierr = PCSetType(pc,PCLU);CHKERRQ(ierr); #if defined(PETSC_HAVE_MUMPS) ierr = PCFactorSetMatSolverPackage(pc,MATSOLVERMUMPS);CHKERRQ(ierr); #endif ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); /* 1. Solve linear system A x = b */ ierr = MatMult(A,u,b);CHKERRQ(ierr); ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); /* Check the error */ ierr = VecAXPY(x,neg_one,u);CHKERRQ(ierr); ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr); ierr = KSPGetIterationNumber(ksp,&its);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"1. Norm of error for Ax=b: %G, Iterations %D\n", norm,its);CHKERRQ(ierr); } /* 2. Solve linear system A^T x = b*/ ierr = MatMultTranspose(A,u,b);CHKERRQ(ierr); ierr = KSPSolveTranspose(ksp,b,x2);CHKERRQ(ierr); /* Check the error */ ierr = VecAXPY(x2,neg_one,u);CHKERRQ(ierr); ierr = VecNorm(x2,NORM_2,&norm);CHKERRQ(ierr); ierr = KSPGetIterationNumber(ksp,&its);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"2. Norm of error for A^T x=b: %G, Iterations %D\n", norm,its);CHKERRQ(ierr); } /* 3. Change A and solve A x = b with an iterative solver using A=LU as a preconditioner*/ if (!rank) { i = 0; col[0] = n-1; value[0] = 1.e-2; ierr = MatSetValues(A,1,&i,1,col,value,ADD_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatMult(A,u,b);CHKERRQ(ierr); ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); /* Check the error */ ierr = VecAXPY(x,neg_one,u);CHKERRQ(ierr); ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr); ierr = KSPGetIterationNumber(ksp,&its);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"3. Norm of error for (A+Delta) x=b: %G, Iterations %D\n",norm,its);CHKERRQ(ierr); } /* Free work space. */ ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = VecDestroy(&x2);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = KSPDestroy(&ksp);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **argv) { PetscErrorCode ierr; KSP ksp; PC pc; Vec x,b; DA da; Mat A,Atrans; PetscInt dof=1,M=-8; PetscTruth flg,trans=PETSC_FALSE; PetscInitialize(&argc,&argv,(char *)0,help); ierr = PetscOptionsGetInt(PETSC_NULL,"-dof",&dof,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-M",&M,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetTruth(PETSC_NULL,"-trans",&trans,PETSC_NULL);CHKERRQ(ierr); ierr = DACreate(PETSC_COMM_WORLD,&da);CHKERRQ(ierr); ierr = DASetDim(da,3);CHKERRQ(ierr); ierr = DASetPeriodicity(da,DA_NONPERIODIC);CHKERRQ(ierr); ierr = DASetStencilType(da,DA_STENCIL_STAR);CHKERRQ(ierr); ierr = DASetSizes(da,M,M,M);CHKERRQ(ierr); ierr = DASetNumProcs(da,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); ierr = DASetDof(da,dof);CHKERRQ(ierr); ierr = DASetStencilWidth(da,1);CHKERRQ(ierr); ierr = DASetVertexDivision(da,PETSC_NULL,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); ierr = DASetFromOptions(da);CHKERRQ(ierr); ierr = DACreateGlobalVector(da,&x);CHKERRQ(ierr); ierr = DACreateGlobalVector(da,&b);CHKERRQ(ierr); ierr = ComputeRHS(da,b);CHKERRQ(ierr); ierr = DAGetMatrix(da,MATBAIJ,&A);CHKERRQ(ierr); ierr = ComputeMatrix(da,A);CHKERRQ(ierr); /* A is non-symmetric. Make A = 0.5*(A + Atrans) symmetric for testing icc and cholesky */ ierr = MatTranspose(A,MAT_INITIAL_MATRIX,&Atrans);CHKERRQ(ierr); ierr = MatAXPY(A,1.0,Atrans,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); ierr = MatScale(A,0.5);CHKERRQ(ierr); ierr = MatDestroy(Atrans);CHKERRQ(ierr); /* Test sbaij matrix */ flg = PETSC_FALSE; ierr = PetscOptionsGetTruth(PETSC_NULL, "-test_sbaij1", &flg,PETSC_NULL);CHKERRQ(ierr); if (flg){ Mat sA; ierr = MatConvert(A,MATSBAIJ,MAT_INITIAL_MATRIX,&sA);CHKERRQ(ierr); ierr = MatDestroy(A);CHKERRQ(ierr); A = sA; } ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); ierr = KSPSetOperators(ksp,A,A,SAME_NONZERO_PATTERN);CHKERRQ(ierr); ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); ierr = PCSetDA(pc,da);CHKERRQ(ierr); if (trans) { ierr = KSPSolveTranspose(ksp,b,x);CHKERRQ(ierr); } else { ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); } /* check final residual */ flg = PETSC_FALSE; ierr = PetscOptionsGetTruth(PETSC_NULL, "-check_final_residual", &flg,PETSC_NULL);CHKERRQ(ierr); if (flg){ Vec b1; PetscReal norm; ierr = KSPGetSolution(ksp,&x);CHKERRQ(ierr); ierr = VecDuplicate(b,&b1);CHKERRQ(ierr); ierr = MatMult(A,x,b1);CHKERRQ(ierr); ierr = VecAXPY(b1,-1.0,b);CHKERRQ(ierr); ierr = VecNorm(b1,NORM_2,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Final residual %g\n",norm);CHKERRQ(ierr); ierr = VecDestroy(b1);CHKERRQ(ierr); } ierr = KSPDestroy(ksp);CHKERRQ(ierr); ierr = VecDestroy(x);CHKERRQ(ierr); ierr = VecDestroy(b);CHKERRQ(ierr); ierr = MatDestroy(A);CHKERRQ(ierr); ierr = DADestroy(da);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
typename SolverLinearPetsc<T>::solve_return_type SolverLinearPetsc<T>::solve ( MatrixSparse<T> const& matrix_in, MatrixSparse<T> const& precond_in, Vector<T> & solution_in, Vector<T> const& rhs_in, const double tol, const unsigned int m_its, bool transpose ) { this->setWorldComm( matrix_in.comm() ); this->init (); MatrixPetsc<T> * matrix = const_cast<MatrixPetsc<T> *>( dynamic_cast<MatrixPetsc<T> const*>( &matrix_in ) ); MatrixPetsc<T> * precond = const_cast<MatrixPetsc<T> *>( dynamic_cast<MatrixPetsc<T> const*>( &precond_in ) ); VectorPetsc<T> * solution = dynamic_cast<VectorPetsc<T>*>( &solution_in ); VectorPetsc<T> * rhs = const_cast<VectorPetsc<T> *>( dynamic_cast<VectorPetsc<T> const*>( &rhs_in ) ); // We cast to pointers so we can be sure that they succeeded // by comparing the result against NULL. FEELPP_ASSERT( matrix != NULL ).error( "non petsc matrix structure" ); FEELPP_ASSERT( precond != NULL ).error( "non petsc matrix structure" ); FEELPP_ASSERT( solution != NULL ).error( "non petsc vector structure" ); FEELPP_ASSERT( rhs != NULL ).error( "non petsc vector structure" ); int ierr=0; int its=0; PetscReal final_resid=0.; // Close the matrices and vectors in case this wasn't already done. matrix->close (); precond->close (); solution->close (); rhs->close (); if ( !this->M_preconditioner && this->preconditionerType() == FIELDSPLIT_PRECOND ) matrix->updatePCFieldSplit( M_pc ); // // If matrix != precond, then this means we have specified a // // special preconditioner, so reset preconditioner type to PCMAT. // if (matrix != precond) // { // this->_preconditioner_type = USER_PRECOND; // this->set_petsc_preconditioner_type (); // } // 2.1.x & earlier style #if (PETSC_VERSION_MAJOR == 2) && (PETSC_VERSION_MINOR <= 1) // Set operators. The input matrix works as the preconditioning matrix ierr = SLESSetOperators( M_sles, matrix->mat(), precond->mat(), SAME_NONZERO_PATTERN ); CHKERRABORT( this->worldComm().globalComm(),ierr ); // Set the tolerances for the iterative solver. Use the user-supplied // tolerance for the relative residual & leave the others at default values. ierr = KSPSetTolerances ( M_ksp, this->rTolerance(), this->aTolerance(), this->dTolerance(), this->maxIterations() ); CHKERRABORT( this->worldComm().globalComm(),ierr ); // makes the default convergence test use || B*(b - A*(initial guess))|| // instead of || B*b ||. In the case of right preconditioner or if // KSPSetNormType(ksp,KSP_NORM_UNPRECONDIITONED) is used there is no B in // the above formula. UIRNorm is short for Use Initial Residual Norm. #if PETSC_VERSION_GREATER_OR_EQUAL_THAN(3,4,4) KSPConvergedDefaultSetUIRNorm( M_ksp ); #else KSPDefaultConvergedSetUIRNorm( M_ksp ); #endif // Solve the linear system ierr = SLESSolve ( M_sles, rhs->vec(), solution->vec(), &its ); CHKERRABORT( this->worldComm().globalComm(),ierr ); // Get the norm of the final residual to return to the user. ierr = KSPGetResidualNorm ( M_ksp, &final_resid ); CHKERRABORT( this->worldComm().globalComm(),ierr ); // 2.2.0 #elif (PETSC_VERSION_MAJOR == 2) && (PETSC_VERSION_MINOR == 2) && (PETSC_VERSION_SUBMINOR == 0) // Set operators. The input matrix works as the preconditioning matrix ierr = KSPSetOperators( M_ksp, matrix->mat(), precond->mat(), MatStructure::SAME_NONZERO_PATTERN ); CHKERRABORT( this->worldComm().globalComm(),ierr ); // Set the tolerances for the iterative solver. Use the user-supplied // tolerance for the relative residual & leave the others at default values. // Convergence is detected at iteration k if // ||r_k||_2 < max(rtol*||b||_2 , abstol) // where r_k is the residual vector and b is the right-hand side. Note that // it is the *maximum* of the two values, the larger of which will almost // always be rtol*||b||_2. ierr = KSPSetTolerances ( M_ksp, this->rTolerance(), this->aTolerance(), this->dTolerance(), this->maxIterations() ); CHKERRABORT( this->worldComm().globalComm(),ierr ); // Set the solution vector to use ierr = KSPSetSolution ( M_ksp, solution->vec() ); CHKERRABORT( this->worldComm().globalComm(),ierr ); // Set the RHS vector to use ierr = KSPSetRhs ( M_ksp, rhs->vec() ); CHKERRABORT( this->worldComm().globalComm(),ierr ); // makes the default convergence test use || B*(b - A*(initial guess))|| // instead of || B*b ||. In the case of right preconditioner or if // KSPSetNormType(ksp,KSP_NORM_UNPRECONDIITONED) is used there is no B in // the above formula. UIRNorm is short for Use Initial Residual Norm. #if PETSC_VERSION_GREATER_OR_EQUAL_THAN(3,4,4) KSPConvergedDefaultSetUIRNorm( M_ksp ); #else KSPDefaultConvergedSetUIRNorm( M_ksp ); #endif // Solve the linear system if ( transpose ) ierr = KSPSolveTranspose ( M_ksp ); else ierr = KSPSolve ( M_ksp ); CHKERRABORT( this->worldComm().globalComm(),ierr ); // Get the number of iterations required for convergence ierr = KSPGetIterationNumber ( M_ksp, &its ); CHKERRABORT( this->worldComm().globalComm(),ierr ); // Get the norm of the final residual to return to the user. ierr = KSPGetResidualNorm ( M_ksp, &final_resid ); CHKERRABORT( this->worldComm().globalComm(),ierr ); // 2.2.1 & newer style #else //std::cout << "sles: " << this->precMatrixStructure() << "\n"; // Set operators. The input matrix works as the preconditioning matrix #if PETSC_VERSION_LESS_THAN(3,5,0) ierr = KSPSetOperators( M_ksp, matrix->mat(), precond->mat(), PetscGetMatStructureEnum(this->precMatrixStructure()) ); #else ierr = KSPSetReusePreconditioner( M_ksp, (this->precMatrixStructure() == Feel::SAME_PRECONDITIONER)? PETSC_TRUE : PETSC_FALSE ); CHKERRABORT( this->worldComm().globalComm(),ierr ); ierr = KSPSetOperators( M_ksp, matrix->mat(), precond->mat() ); #endif CHKERRABORT( this->worldComm().globalComm(),ierr ); // Set the tolerances for the iterative solver. Use the user-supplied // tolerance for the relative residual & leave the others at default values. ierr = KSPSetTolerances ( M_ksp, this->rTolerance(), //1e-15, this->aTolerance(), this->dTolerance(), this->maxIterations() ); CHKERRABORT( this->worldComm().globalComm(),ierr ); //PreconditionerPetsc<T>::setPetscPreconditionerType( this->preconditionerType(),this->matSolverPackageType(),M_pc, this->worldComm() ); // makes the default convergence test use || B*(b - A*(initial guess))|| // instead of || B*b ||. In the case of right preconditioner or if // KSPSetNormType(ksp,KSP_NORM_UNPRECONDIITONED) is used there is no B in // the above formula. UIRNorm is short for Use Initial Residual Norm. #if PETSC_VERSION_LESS_THAN(3,5,0) KSPDefaultConvergedSetUIRNorm( M_ksp ); #else KSPConvergedDefaultSetUIRNorm( M_ksp ); #endif // Solve the linear system if ( transpose ) ierr = KSPSolveTranspose ( M_ksp, rhs->vec(), solution->vec() ); else ierr = KSPSolve ( M_ksp, rhs->vec(), solution->vec() ); CHKERRABORT( this->worldComm().globalComm(),ierr ); // Get the number of iterations required for convergence ierr = KSPGetIterationNumber ( M_ksp, &its ); CHKERRABORT( this->worldComm().globalComm(),ierr ); // Get the norm of the final residual to return to the user. ierr = KSPGetResidualNorm ( M_ksp, &final_resid ); //std::cout << "final residual = " << final_resid << "\n"; CHKERRABORT( this->worldComm().globalComm(),ierr ); KSPConvergedReason reason; KSPGetConvergedReason( M_ksp,&reason ); if ( option( _prefix=this->prefix(), _name="ksp-view" ).template as<bool>() ) check( KSPView( M_ksp, PETSC_VIEWER_STDOUT_WORLD ) ); if ( reason==KSP_DIVERGED_INDEFINITE_PC ) { LOG(INFO) << "[solverlinearpetsc] Divergence because of indefinite preconditioner;\n"; LOG(INFO) << "[solverlinearpetsc] Run the executable again but with '-pc_factor_shift_type POSITIVE_DEFINITE' option.\n"; } else if ( reason<0 ) { LOG(INFO) <<"[solverlinearpetsc] Other kind of divergence: this should not happen.\n"; } bool hasConverged; if ( reason> 0 ) { hasConverged=true; if (this->showKSPConvergedReason() && this->worldComm().globalRank() == this->worldComm().masterRank() ) std::cout<< "Linear solve converged due to " << PetscConvertKSPReasonToString(reason) << " iterations " << its << std::endl; } else { hasConverged=false; if (this->showKSPConvergedReason() && this->worldComm().globalRank() == this->worldComm().masterRank() ) std::cout<< "Linear solve did not converge due to " << PetscConvertKSPReasonToString(reason) << " iterations " << its << std::endl; } #endif // return the # of its. and the final residual norm. //return std::make_pair(its, final_resid); return solve_return_type( boost::make_tuple( hasConverged, its, final_resid ) ); }
/* S^{-1} = ( G^T G )^{-1} G^T K G ( G^T G )^{-1} = A C A S^{-T} = A^T (A C)^T = A^T C^T A^T, but A = G^T G which is symmetric = A C^T A = A G^T ( G^T K )^T A = A G^T K^T G A */ PetscErrorCode BSSCR_PCApplyTranspose_ScGtKG( PC pc, Vec x, Vec y ) { PC_SC_GtKG ctx = (PC_SC_GtKG)pc->data; KSP ksp; Mat F, Bt; Vec s,t,X; PetscLogDouble t0,t1; ksp = ctx->ksp_BBt; F = ctx->F; Bt = ctx->Bt; s = ctx->s; t = ctx->t; X = ctx->X; /* Apply scaled Poisson operator */ /* scale x */ /* ======================================================== NOTE: I THINK TO OMIT THESE AS WE WANT TO UNSCALE THE PRECONDITIONER AS S IN THIS CASE IS NOT SCALED ======================================================== */ // VecPointwiseDivide( x, x, ctx->X2 ); /* x <- x/X2 */ /* NEED TO BE SURE */ if( ctx->BBt_has_cnst_nullspace == PETSC_TRUE ) { BSSCR_VecRemoveConstNullspace( x, PETSC_NULL ); } PetscGetTime(&t0); KSPSolveTranspose( ksp, x, t ); /* t <- GtG_inv x */ PetscGetTime(&t1); if (ctx->monitor_activated) { BSSCR_PCScBFBTSubKSPMonitor(ksp,1,(t1-t0)); } /* Apply Bt */ MatMult( Bt, t, s ); /* s <- G t */ VecPointwiseMult( s, s, ctx->X1 ); /* s <- s * X1 */ /* Apply F */ VecPointwiseMult( s, s, ctx->Y1 ); /* s <- s * Y1 */ MatMultTranspose( F, s, X ); /* X <- K s */ VecPointwiseMult( X, X, ctx->X1 ); /* X <- X * X1 */ /* Apply B */ VecPointwiseMult( X, X, ctx->Y1 ); /* X <- X * Y1 */ MatMultTranspose( Bt, X, t ); /* t <- Gt X */ if( ctx->BBt_has_cnst_nullspace == PETSC_TRUE ) { BSSCR_VecRemoveConstNullspace( t, PETSC_NULL ); } PetscGetTime(&t0); KSPSolveTranspose( ksp, t, y ); /* y <- GtG_inv t */ PetscGetTime(&t1); if (ctx->monitor_activated) { BSSCR_PCScBFBTSubKSPMonitor(ksp,2,(t1-t0)); } VecPointwiseMult( y, y, ctx->Y2 ); /* y <- y/Y2 */ /* undo modification made to x on entry */ // VecPointwiseMult( x, x, ctx->X2 ); /* x <- x/X2 */ /* NEED TO BE SURE */ PetscFunctionReturn(0); }