/* Performs y <- S*^{-1} x S*^{-1} = ( B' Bt' )^{-1} B' F' Bt' ( B' Bt' )^{-1} where F' = X1 F Y1 Bt' = X1 Bt Y2 B' = X2 B Y1 Thus, S*^{-1} = [ X2 B Y1 X1 Bt Y2 ]^{-1} . [ X2 B Y1 . X1 F Y1 . X1 Bt Y2 ] . [ X2 B Y1 X1 Bt Y2 ]^{-1} = Y2^{-1} ksp_BBt X2^{-1} . [ B' F' Bt' ] . Y2^{-1} ksp_BBt X2^{-1} = Y2^{-1} ksp_BBt . [ B Y1 . X1 F Y1 . X1 Bt ] . ksp_BBt X2^{-1} */ PetscErrorCode BSSCR_PCApply_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); KSPSolve( 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 */ MatMult( 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); KSPSolve( 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); }
void bsscr_summary(KSP_BSSCR * bsscrp_self, KSP ksp_S, KSP ksp_inner, Mat K,Mat K2,Mat D,Mat G,Mat C,Vec u,Vec p,Vec f,Vec h,Vec t, double penaltyNumber,PetscTruth KisJustK,double mgSetupTime,double scrSolveTime,double a11SingleSolveTime){ PetscTruth flg, found; PetscInt uSize, pSize, lmax, lmin, iterations; PetscReal rNorm, fNorm, uNorm, uNormInf, pNorm, pNormInf, p_sum, min, max; Vec q, qq, t2, t3; double solutionAnalysisTime; PetscPrintf( PETSC_COMM_WORLD, "\n\nSCR Solver Summary:\n\n"); if(bsscrp_self->mg) PetscPrintf( PETSC_COMM_WORLD, " Multigrid setup: = %.4g secs \n", mgSetupTime); KSPGetIterationNumber( ksp_S, &iterations); bsscrp_self->solver->stats.pressure_its = iterations; PetscPrintf( PETSC_COMM_WORLD, " Pressure Solve: = %.4g secs / %d its\n", scrSolveTime, iterations); KSPGetIterationNumber( ksp_inner, &iterations); bsscrp_self->solver->stats.velocity_backsolve_its = iterations; PetscPrintf( PETSC_COMM_WORLD, " Final V Solve: = %.4g secs / %d its\n\n", a11SingleSolveTime, iterations); /***************************************************************************************************************/ flg = PETSC_TRUE; PetscOptionsGetTruth( PETSC_NULL, "-scr_ksp_solution_summary", &flg, &found ); if(flg) { PetscScalar KuNorm; solutionAnalysisTime = MPI_Wtime(); VecGetSize( u, &uSize ); VecGetSize( p, &pSize ); VecDuplicate( u, &t2 ); VecDuplicate( u, &t3 ); MatMult( K, u, t3); VecNorm( t3, NORM_2, &KuNorm ); double angle, kdot; if(penaltyNumber > 1e-10){/* should change this to ifK2built maybe */ MatMult( K2, u, t2); VecNorm( t2, NORM_2, &rNorm ); VecDot(t2,t3,&kdot); angle = (kdot/(rNorm*KuNorm)); PetscPrintf( PETSC_COMM_WORLD, " <K u, K2 u>/(|K u| |K2 u|) = %.6e\n", angle); } VecNorm( t, NORM_2, &rNorm ); /* t = f- G p should be the formal residual vector, calculated on line 267 in auglag-driver-DGTGD.c */ VecDot(t3,t,&kdot); angle = (kdot/(rNorm*KuNorm)); PetscPrintf( PETSC_COMM_WORLD, " <K u, (f-G p)>/(|K u| |f- G p|) = %.6e\n\n", angle); MatMult( K, u, t2); VecNorm(t2, NORM_2, &KuNorm); VecAYPX( t2, -1.0, t ); /* t2 <- -t2 + t : t = f- G p should be the formal residual vector, calculated on line 267 in auglag-driver-DGTGD.c*/ VecNorm( t2, NORM_2, &rNorm ); VecNorm( f, NORM_2, &fNorm ); if(KisJustK){ PetscPrintf( PETSC_COMM_WORLD,"Velocity back-solve with original K matrix\n"); PetscPrintf( PETSC_COMM_WORLD,"Solved K u = G p -f\n"); PetscPrintf( PETSC_COMM_WORLD,"Residual with original K matrix\n"); PetscPrintf( PETSC_COMM_WORLD, " |f - K u - G p| = %.12e\n", rNorm); PetscPrintf( PETSC_COMM_WORLD, " |f - K u - G p|/|f| = %.12e\n", rNorm/fNorm); if(penaltyNumber > 1e-10){/* means the restore_K flag was used */ //if(K2 && f2){ MatAXPY(K,penaltyNumber,K2,DIFFERENT_NONZERO_PATTERN);/* Computes K = penaltyNumber*K2 + K */ //VecAXPY(f,penaltyNumber,f2); /* f = penaltyNumber*f2 + f */ KisJustK=PETSC_FALSE; MatMult( K, u, t2); MatMult( G, p, t); VecAYPX( t, -1.0, f ); /* t <- -t + f */ VecAYPX( t2, -1.0, t ); /* t2 <- -t2 + t */ VecNorm( t2, NORM_2, &rNorm ); PetscPrintf( PETSC_COMM_WORLD,"Residual with K+K2 matrix and f rhs vector\n"); PetscPrintf( PETSC_COMM_WORLD, " |(f) - (K + K2) u - G p| = %.12e\n", rNorm); //} } } else{ PetscPrintf( PETSC_COMM_WORLD,"Velocity back-solve with K+K2 matrix\n"); PetscPrintf( PETSC_COMM_WORLD,"Solved (K + K2) u = G p - (f)\n"); PetscPrintf( PETSC_COMM_WORLD,"Residual with K+K2 matrix and f rhs vector\n"); PetscPrintf( PETSC_COMM_WORLD, " |(f) - (K + K2) u - G p| = %.12e\n", rNorm); PetscReal KK2Norm,KK2Normf; MatNorm(K,NORM_1,&KK2Norm); MatNorm(K,NORM_FROBENIUS,&KK2Normf); penaltyNumber = -penaltyNumber; MatAXPY(K,penaltyNumber,K2,DIFFERENT_NONZERO_PATTERN);/* Computes K = penaltyNumber*K2 + K */ //VecAXPY(f,penaltyNumber,f2); /* f = penaltyNumber*f2 + f */ KisJustK=PETSC_FALSE; MatMult( K, u, t2); /* t2 = K*u */ MatMult( G, p, t); /* t = G*p */ VecAYPX( t, -1.0, f ); /* t <- f - t ; t = f - G*p */ VecAYPX( t2, -1.0, t ); /* t2 <- t - t2; t2 = f - G*p - K*u */ VecNorm( t2, NORM_2, &rNorm ); PetscPrintf( PETSC_COMM_WORLD,"Residual with original K matrix\n"); PetscPrintf( PETSC_COMM_WORLD, " |f - K u - G p| = %.12e\n", rNorm); PetscPrintf( PETSC_COMM_WORLD, " |f - K u - G p|/|f| = %.12e\n", rNorm/fNorm); PetscReal KNorm, K2Norm; MatNorm(K,NORM_1,&KNorm); MatNorm(K2,NORM_1,&K2Norm); PetscPrintf( PETSC_COMM_WORLD,"K and K2 norm_1 %.12e %.12e ratio %.12e\n",KNorm,K2Norm,K2Norm/KNorm); MatNorm(K,NORM_INFINITY,&KNorm); MatNorm(K2,NORM_INFINITY,&K2Norm); PetscPrintf( PETSC_COMM_WORLD,"K and K2 norm_inf %.12e %.12e ratio %.12e\n",KNorm,K2Norm,K2Norm/KNorm); MatNorm(K,NORM_FROBENIUS,&KNorm); MatNorm(K2,NORM_FROBENIUS,&K2Norm); PetscPrintf( PETSC_COMM_WORLD,"K and K2 norm_frob %.12e %.12e ratio %.12e\n",KNorm,K2Norm,K2Norm/KNorm); PetscPrintf( PETSC_COMM_WORLD,"K+r*K2 norm_1 %.12e\n",KK2Norm); PetscPrintf( PETSC_COMM_WORLD,"K+r*K2 norm_frob %.12e\n",KK2Normf); penaltyNumber = -penaltyNumber; MatAXPY(K,penaltyNumber,K2,DIFFERENT_NONZERO_PATTERN);/* Computes K = penaltyNumber*K2 + K */ } PetscPrintf( PETSC_COMM_WORLD,"\n"); PetscPrintf( PETSC_COMM_WORLD, " |K u| = %.12e\n", KuNorm); if(penaltyNumber > 1e-10){ MatMult( K2, u, t2); VecNorm( t2, NORM_2, &rNorm ); PetscPrintf( PETSC_COMM_WORLD, " |K2 u| = %.12e\n", rNorm); PetscPrintf( PETSC_COMM_WORLD,"\n"); } VecDuplicate( p, &q ); MatMult( D, u, q ); /* q = G'*u = D*u */ VecNorm( u, NORM_2, &uNorm ); VecNorm( q, NORM_2, &rNorm ); PetscPrintf( PETSC_COMM_WORLD, " |G^T u|_2 = %.6e\n", rNorm ); PetscPrintf( PETSC_COMM_WORLD, " |G^T u|_2/|u|_2 = %.6e\n", sqrt( (double) uSize / (double) pSize ) * rNorm / uNorm); VecDuplicate( p, &qq ); MatMultTranspose( G, u, qq ); VecNorm( qq, NORM_2, &rNorm ); PetscPrintf( PETSC_COMM_WORLD, " |G^T u|/|u| = %.8e\n", rNorm/uNorm ); /* to compare directly with Uzawa */ VecNorm( q, NORM_INFINITY, &rNorm ); PetscPrintf( PETSC_COMM_WORLD, " |G^T u|_infty/|u|_2 = %.6e\n", sqrt( (double) uSize ) * rNorm / uNorm); /* create G'*u+C*p-h to check on this constraint */ /* already have q = D*u */ VecZeroEntries(qq); if(C){ MatMult( C, p, qq ); } VecAYPX( q, 1.0, qq ); /* q = q+qq; G'*u + C*p*/ VecAXPY( q, -1.0, h ); /* q = q-h; G'*u + C*p - h */ VecNorm( q, NORM_2, &rNorm ); PetscPrintf( PETSC_COMM_WORLD, " |G^T u + C p - h| = %.8e :constraint\n", rNorm ); VecNorm( u, NORM_INFINITY, &uNormInf ); VecNorm( u, NORM_2, &uNorm ); VecGetSize( u, &uSize ); VecNorm( p, NORM_INFINITY, &pNormInf ); VecNorm( p, NORM_2, &pNorm ); PetscPrintf( PETSC_COMM_WORLD, " |u|_{\\infty} = %.6e , u_rms = %.6e\n", uNormInf, uNorm / sqrt( (double) uSize ) ); PetscPrintf( PETSC_COMM_WORLD, " |p|_{\\infty} = %.6e , p_rms = %.6e\n", pNormInf, pNorm / sqrt( (double) pSize ) ); VecMax( u, &lmax, &max ); VecMin( u, &lmin, &min ); PetscPrintf( PETSC_COMM_WORLD, " min/max(u) = %.6e [%d] / %.6e [%d]\n",min,lmin,max,lmax); bsscrp_self->solver->stats.vmin = min; bsscrp_self->solver->stats.vmax = max; VecMax( p, &lmax, &max ); VecMin( p, &lmin, &min ); PetscPrintf( PETSC_COMM_WORLD, " min/max(p) = %.6e [%d] / %.6e [%d]\n",min,lmin,max,lmax); bsscrp_self->solver->stats.pmin = min; bsscrp_self->solver->stats.pmax = max; VecSum( p, &p_sum ); PetscPrintf( PETSC_COMM_WORLD, " \\sum_i p_i = %.6e \n", p_sum ); bsscrp_self->solver->stats.p_sum=p_sum; solutionAnalysisTime = MPI_Wtime() - solutionAnalysisTime; PetscPrintf( PETSC_COMM_WORLD, "\n Time for this analysis = %.4g secs\n\n",solutionAnalysisTime); Stg_VecDestroy(&t2 ); Stg_VecDestroy(&t3 ); Stg_VecDestroy(&q ); Stg_VecDestroy(&qq ); } }
PetscInt main(PetscInt argc,char **args) { PetscErrorCode ierr; PetscMPIInt rank,size; PetscInt N0=50,N1=20,N=N0*N1; PetscRandom rdm; PetscScalar a; PetscReal enorm; Vec x,y,z; PetscBool view=PETSC_FALSE,use_interface=PETSC_TRUE; ierr = PetscInitialize(&argc,&args,(char *)0,help);CHKERRQ(ierr); #if !defined(PETSC_USE_COMPLEX) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP, "This example requires complex numbers"); #endif ierr = PetscOptionsBegin(PETSC_COMM_WORLD, PETSC_NULL, "FFTW Options", "ex143");CHKERRQ(ierr); ierr = PetscOptionsBool("-vec_view draw", "View the vectors", "ex143", view, &view, PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-use_FFTW_interface", "Use PETSc-FFTW interface", "ex143",use_interface, &use_interface, PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); ierr = PetscOptionsGetBool(PETSC_NULL,"-use_FFTW_interface",&use_interface,PETSC_NULL);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD, &size);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_WORLD, &rdm);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rdm);CHKERRQ(ierr); if (!use_interface){ /* Use mpi FFTW without PETSc-FFTW interface, 2D case only */ /*---------------------------------------------------------*/ fftw_plan fplan,bplan; fftw_complex *data_in,*data_out,*data_out2; ptrdiff_t alloc_local,local_n0,local_0_start; if (!rank) printf("Use FFTW without PETSc-FFTW interface\n"); fftw_mpi_init(); N = N0*N1; alloc_local = fftw_mpi_local_size_2d(N0,N1,PETSC_COMM_WORLD,&local_n0,&local_0_start); data_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*alloc_local); data_out = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*alloc_local); data_out2 = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*alloc_local); ierr = VecCreateMPIWithArray(PETSC_COMM_WORLD,1,(PetscInt)local_n0*N1,(PetscInt)N,(const PetscScalar*)data_in,&x);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) x, "Real Space vector");CHKERRQ(ierr); ierr = VecCreateMPIWithArray(PETSC_COMM_WORLD,1,(PetscInt)local_n0*N1,(PetscInt)N,(const PetscScalar*)data_out,&y);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) y, "Frequency space vector");CHKERRQ(ierr); ierr = VecCreateMPIWithArray(PETSC_COMM_WORLD,1,(PetscInt)local_n0*N1,(PetscInt)N,(const PetscScalar*)data_out2,&z);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) z, "Reconstructed vector");CHKERRQ(ierr); fplan = fftw_mpi_plan_dft_2d(N0,N1,data_in,data_out,PETSC_COMM_WORLD,FFTW_FORWARD,FFTW_ESTIMATE); bplan = fftw_mpi_plan_dft_2d(N0,N1,data_out,data_out2,PETSC_COMM_WORLD,FFTW_BACKWARD,FFTW_ESTIMATE); ierr = VecSetRandom(x, rdm);CHKERRQ(ierr); if (view){ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);} fftw_execute(fplan); if (view){ierr = VecView(y,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);} fftw_execute(bplan); /* Compare x and z. FFTW computes an unnormalized DFT, thus z = N*x */ a = 1.0/(PetscReal)N; ierr = VecScale(z,a);CHKERRQ(ierr); if (view){ierr = VecView(z, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);} ierr = VecAXPY(z,-1.0,x);CHKERRQ(ierr); ierr = VecNorm(z,NORM_1,&enorm);CHKERRQ(ierr); if (enorm > 1.e-11){ ierr = PetscPrintf(PETSC_COMM_SELF," Error norm of |x - z| %G\n",enorm);CHKERRQ(ierr); } /* Free spaces */ fftw_destroy_plan(fplan); fftw_destroy_plan(bplan); fftw_free(data_in); ierr = VecDestroy(&x);CHKERRQ(ierr); fftw_free(data_out); ierr = VecDestroy(&y);CHKERRQ(ierr); fftw_free(data_out2);ierr = VecDestroy(&z);CHKERRQ(ierr); } else { /* Use PETSc-FFTW interface */ /*-------------------------------------------*/ PetscInt i,*dim,k,DIM; Mat A; N=1; for (i=1; i<5; i++){ DIM = i; ierr = PetscMalloc(i*sizeof(PetscInt),&dim);CHKERRQ(ierr); for (k=0;k<i;k++){ dim[k]=30; } N *= dim[i-1]; /* Create FFTW object */ if (!rank) printf("Use PETSc-FFTW interface...%d-DIM:%d \n",DIM,N); ierr = MatCreateFFT(PETSC_COMM_WORLD,DIM,dim,MATFFTW,&A);CHKERRQ(ierr); /* Create vectors that are compatible with parallel layout of A - must call MatGetVecs()! */ ierr = MatGetVecsFFTW(A,&x,&y,&z);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) x, "Real space vector");CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) y, "Frequency space vector");CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) z, "Reconstructed vector");CHKERRQ(ierr); /* Set values of space vector x */ ierr = VecSetRandom(x,rdm);CHKERRQ(ierr); if (view){ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);} // Apply FFTW_FORWARD and FFTW_BACKWARD ierr = MatMult(A,x,y);CHKERRQ(ierr); if (view){ierr = VecView(y,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);} ierr = MatMultTranspose(A,y,z);CHKERRQ(ierr); // Compare x and z. FFTW computes an unnormalized DFT, thus z = N*x a = 1.0/(PetscReal)N; ierr = VecScale(z,a);CHKERRQ(ierr); if (view){ierr = VecView(z,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);} ierr = VecAXPY(z,-1.0,x);CHKERRQ(ierr); ierr = VecNorm(z,NORM_1,&enorm);CHKERRQ(ierr); if (enorm > 1.e-9 && !rank){ ierr = PetscPrintf(PETSC_COMM_SELF," Error norm of |x - z| %e\n",enorm);CHKERRQ(ierr); } ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&y);CHKERRQ(ierr); ierr = VecDestroy(&z);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = PetscFree(dim);CHKERRQ(ierr); } } ierr = PetscRandomDestroy(&rdm);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **argv) { Mat A,A11,A12,A21,A22; Vec X,X1,X2,Y,Z,Z1,Z2; PetscScalar *a,*b,*x,*y,*z,v,one=1; PetscReal nrm; PetscErrorCode ierr; PetscInt size=8,size1=6,size2=2, i,j; PetscInitialize(&argc,&argv,0,0); /* * Create matrix and three vectors: these are all normal */ ierr = PetscMalloc(size*size*sizeof(PetscScalar),&a);CHKERRQ(ierr); ierr = PetscMalloc(size*size*sizeof(PetscScalar),&b);CHKERRQ(ierr); for (i=0; i<size; i++) { for (j=0; j<size; j++) { a[i+j*size] = rand(); b[i+j*size] = a[i+j*size]; } } ierr = MatCreate(MPI_COMM_SELF,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,size,size,size,size);CHKERRQ(ierr); ierr = MatSetType(A,MATSEQDENSE);CHKERRQ(ierr); ierr = MatSeqDenseSetPreallocation(A,a);CHKERRQ(ierr); ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = PetscMalloc(size*sizeof(PetscScalar),&x);CHKERRQ(ierr); for (i=0; i<size; i++) { x[i] = one; } ierr = VecCreateSeqWithArray(MPI_COMM_SELF,size,x,&X);CHKERRQ(ierr); ierr = VecAssemblyBegin(X);CHKERRQ(ierr); ierr = VecAssemblyEnd(X);CHKERRQ(ierr); ierr = PetscMalloc(size*sizeof(PetscScalar),&y);CHKERRQ(ierr); ierr = VecCreateSeqWithArray(MPI_COMM_SELF,size,y,&Y);CHKERRQ(ierr); ierr = VecAssemblyBegin(Y);CHKERRQ(ierr); ierr = VecAssemblyEnd(Y);CHKERRQ(ierr); ierr = PetscMalloc(size*sizeof(PetscScalar),&z);CHKERRQ(ierr); ierr = VecCreateSeqWithArray(MPI_COMM_SELF,size,z,&Z);CHKERRQ(ierr); ierr = VecAssemblyBegin(Z);CHKERRQ(ierr); ierr = VecAssemblyEnd(Z);CHKERRQ(ierr); /* * Now create submatrices and subvectors */ ierr = MatCreate(MPI_COMM_SELF,&A11);CHKERRQ(ierr); ierr = MatSetSizes(A11,size1,size1,size1,size1);CHKERRQ(ierr); ierr = MatSetType(A11,MATSEQDENSE);CHKERRQ(ierr); ierr = MatSeqDenseSetPreallocation(A11,b);CHKERRQ(ierr); ierr = MatSeqDenseSetLDA(A11,size);CHKERRQ(ierr); ierr = MatAssemblyBegin(A11,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A11,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatCreate(MPI_COMM_SELF,&A12);CHKERRQ(ierr); ierr = MatSetSizes(A12,size1,size2,size1,size2);CHKERRQ(ierr); ierr = MatSetType(A12,MATSEQDENSE);CHKERRQ(ierr); ierr = MatSeqDenseSetPreallocation(A12,b+size1*size);CHKERRQ(ierr); ierr = MatSeqDenseSetLDA(A12,size);CHKERRQ(ierr); ierr = MatAssemblyBegin(A12,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A12,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatCreate(MPI_COMM_SELF,&A21);CHKERRQ(ierr); ierr = MatSetSizes(A21,size2,size1,size2,size1);CHKERRQ(ierr); ierr = MatSetType(A21,MATSEQDENSE);CHKERRQ(ierr); ierr = MatSeqDenseSetPreallocation(A21,b+size1);CHKERRQ(ierr); ierr = MatSeqDenseSetLDA(A21,size);CHKERRQ(ierr); ierr = MatAssemblyBegin(A21,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A21,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatCreate(MPI_COMM_SELF,&A22);CHKERRQ(ierr); ierr = MatSetSizes(A22,size2,size2,size2,size2);CHKERRQ(ierr); ierr = MatSetType(A22,MATSEQDENSE);CHKERRQ(ierr); ierr = MatSeqDenseSetPreallocation(A22,b+size1*size+size1);CHKERRQ(ierr); ierr = MatSeqDenseSetLDA(A22,size);CHKERRQ(ierr); ierr = MatAssemblyBegin(A22,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A22,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = VecCreateSeqWithArray(MPI_COMM_SELF,size1,x,&X1);CHKERRQ(ierr); ierr = VecCreateSeqWithArray(MPI_COMM_SELF,size2,x+size1,&X2);CHKERRQ(ierr); ierr = VecCreateSeqWithArray(MPI_COMM_SELF,size1,z,&Z1);CHKERRQ(ierr); ierr = VecCreateSeqWithArray(MPI_COMM_SELF,size2,z+size1,&Z2);CHKERRQ(ierr); /* * Now multiple matrix times input in two ways; * compare the results */ ierr = MatMult(A,X,Y);CHKERRQ(ierr); ierr = MatMult(A11,X1,Z1);CHKERRQ(ierr); ierr = MatMultAdd(A12,X2,Z1,Z1);CHKERRQ(ierr); ierr = MatMult(A22,X2,Z2);CHKERRQ(ierr); ierr = MatMultAdd(A21,X1,Z2,Z2);CHKERRQ(ierr); ierr = VecAXPY(Z,-1.0,Y);CHKERRQ(ierr); ierr = VecNorm(Z,NORM_2,&nrm); printf("Test1; error norm=%e\n",nrm); /* printf("MatMult the usual way:\n"); VecView(Y,0); printf("MatMult by subblock:\n"); VecView(Z,0); */ /* * Next test: change both matrices */ v = rand(); i=1; j=size-2; ierr = MatSetValues(A,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); j -= size1; ierr = MatSetValues(A12,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); v = rand(); i=j=size1+1; ierr = MatSetValues(A,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); i=j=1; ierr = MatSetValues(A22,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyBegin(A12,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A12,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyBegin(A22,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A22,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatMult(A,X,Y);CHKERRQ(ierr); ierr = MatMult(A11,X1,Z1);CHKERRQ(ierr); ierr = MatMultAdd(A12,X2,Z1,Z1);CHKERRQ(ierr); ierr = MatMult(A22,X2,Z2);CHKERRQ(ierr); ierr = MatMultAdd(A21,X1,Z2,Z2);CHKERRQ(ierr); ierr = VecAXPY(Z,-1.0,Y);CHKERRQ(ierr); ierr = VecNorm(Z,NORM_2,&nrm); printf("Test2; error norm=%e\n",nrm); /* * Transpose product */ ierr = MatMultTranspose(A,X,Y);CHKERRQ(ierr); ierr = MatMultTranspose(A11,X1,Z1);CHKERRQ(ierr); ierr = MatMultTransposeAdd(A21,X2,Z1,Z1);CHKERRQ(ierr); ierr = MatMultTranspose(A22,X2,Z2);CHKERRQ(ierr); ierr = MatMultTransposeAdd(A12,X1,Z2,Z2);CHKERRQ(ierr); ierr = VecAXPY(Z,-1.0,Y);CHKERRQ(ierr); ierr = VecNorm(Z,NORM_2,&nrm); printf("Test3; error norm=%e\n",nrm); ierr = PetscFree(a);CHKERRQ(ierr); ierr = PetscFree(b);CHKERRQ(ierr); ierr = PetscFree(x);CHKERRQ(ierr); ierr = PetscFree(y);CHKERRQ(ierr); ierr = PetscFree(z);CHKERRQ(ierr); ierr = MatDestroy(A);CHKERRQ(ierr); ierr = MatDestroy(A11);CHKERRQ(ierr); ierr = MatDestroy(A12);CHKERRQ(ierr); ierr = MatDestroy(A21);CHKERRQ(ierr); ierr = MatDestroy(A22);CHKERRQ(ierr); ierr = VecDestroy(X);CHKERRQ(ierr); ierr = VecDestroy(Y);CHKERRQ(ierr); ierr = VecDestroy(Z);CHKERRQ(ierr); ierr = VecDestroy(X1);CHKERRQ(ierr); ierr = VecDestroy(X2);CHKERRQ(ierr); ierr = VecDestroy(Z1);CHKERRQ(ierr); ierr = VecDestroy(Z2);CHKERRQ(ierr); /*ierr = PetscLogPrintSummary(MPI_COMM_SELF,"ex2.log");CHKERRQ(ierr);*/ ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
PetscInt main(PetscInt argc,char **args) { typedef enum {RANDOM, CONSTANT, TANH, NUM_FUNCS} FuncType; const char *funcNames[NUM_FUNCS] = {"random", "constant", "tanh"}; Mat A, AA; PetscMPIInt size; PetscInt N,i, stencil=1,dof=1; PetscInt dim[3] = {10,10,10}, ndim = 3; Vec coords,x,y,z,xx,yy,zz; PetscReal h[3]; PetscScalar s; PetscRandom rdm; PetscReal norm, enorm; PetscInt func; FuncType function = TANH; DM da, coordsda; PetscBool view_x = PETSC_FALSE, view_y = PETSC_FALSE, view_z = PETSC_FALSE; PetscErrorCode ierr; ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; ierr = MPI_Comm_size(PETSC_COMM_WORLD, &size);CHKERRQ(ierr); if (size != 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP, "This is a uniprocessor example only!"); ierr = PetscOptionsBegin(PETSC_COMM_WORLD, NULL, "USFFT Options", "ex27");CHKERRQ(ierr); ierr = PetscOptionsEList("-function", "Function type", "ex27", funcNames, NUM_FUNCS, funcNames[function], &func, NULL);CHKERRQ(ierr); function = (FuncType) func; ierr = PetscOptionsEnd();CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-view_x",&view_x,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-view_y",&view_y,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-view_z",&view_z,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetIntArray(NULL,NULL,"-dim",dim,&ndim,NULL);CHKERRQ(ierr); ierr = DMDACreate3d(PETSC_COMM_SELF,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,dim[0], dim[1], dim[2], PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE,dof, stencil,NULL, NULL, NULL,&da);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); /* Coordinates */ ierr = DMGetCoordinateDM(da, &coordsda); ierr = DMGetGlobalVector(coordsda, &coords);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) coords, "Grid coordinates");CHKERRQ(ierr); for (i = 0, N = 1; i < 3; i++) { h[i] = 1.0/dim[i]; PetscScalar *a; ierr = VecGetArray(coords, &a);CHKERRQ(ierr); PetscInt j,k,n = 0; for (i = 0; i < 3; ++i) { for (j = 0; j < dim[i]; ++j) { for (k = 0; k < 3; ++k) { a[n] = j*h[i]; /* coordinate along the j-th point in the i-th dimension */ ++n; } } } ierr = VecRestoreArray(coords, &a);CHKERRQ(ierr); } ierr = DMSetCoordinates(da, coords);CHKERRQ(ierr); /* Work vectors */ ierr = DMGetGlobalVector(da, &x);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) x, "Real space vector");CHKERRQ(ierr); ierr = DMGetGlobalVector(da, &xx);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) xx, "Real space vector");CHKERRQ(ierr); ierr = DMGetGlobalVector(da, &y);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) y, "USFFT frequency space vector");CHKERRQ(ierr); ierr = DMGetGlobalVector(da, &yy);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) yy, "FFTW frequency space vector");CHKERRQ(ierr); ierr = DMGetGlobalVector(da, &z);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) z, "USFFT reconstructed vector");CHKERRQ(ierr); ierr = DMGetGlobalVector(da, &zz);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) zz, "FFTW reconstructed vector");CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF, "%3-D: USFFT on vector of ");CHKERRQ(ierr); for (i = 0, N = 1; i < 3; i++) { ierr = PetscPrintf(PETSC_COMM_SELF, "dim[%d] = %d ",i,dim[i]);CHKERRQ(ierr); N *= dim[i]; } ierr = PetscPrintf(PETSC_COMM_SELF, "; total size %d \n",N);CHKERRQ(ierr); if (function == RANDOM) { ierr = PetscRandomCreate(PETSC_COMM_SELF, &rdm);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rdm);CHKERRQ(ierr); ierr = VecSetRandom(x, rdm);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rdm);CHKERRQ(ierr); } else if (function == CONSTANT) { ierr = VecSet(x, 1.0);CHKERRQ(ierr); } else if (function == TANH) { PetscScalar *a; ierr = VecGetArray(x, &a);CHKERRQ(ierr); PetscInt j,k = 0; for (i = 0; i < 3; ++i) { for (j = 0; j < dim[i]; ++j) { a[k] = tanh((j - dim[i]/2.0)*(10.0/dim[i])); ++k; } } ierr = VecRestoreArray(x, &a);CHKERRQ(ierr); } if (view_x) { ierr = VecView(x, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = VecCopy(x,xx);CHKERRQ(ierr); ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF, "|x|_2 = %g\n",norm);CHKERRQ(ierr); /* create USFFT object */ ierr = MatCreateSeqUSFFT(coords,da,&A);CHKERRQ(ierr); /* create FFTW object */ ierr = MatCreateSeqFFTW(PETSC_COMM_SELF,3,dim,&AA);CHKERRQ(ierr); /* apply USFFT and FFTW FORWARD "preemptively", so the fftw_plans can be reused on different vectors */ ierr = MatMult(A,x,z);CHKERRQ(ierr); ierr = MatMult(AA,xx,zz);CHKERRQ(ierr); /* Now apply USFFT and FFTW forward several (3) times */ for (i=0; i<3; ++i) { ierr = MatMult(A,x,y);CHKERRQ(ierr); ierr = MatMult(AA,xx,yy);CHKERRQ(ierr); ierr = MatMultTranspose(A,y,z);CHKERRQ(ierr); ierr = MatMultTranspose(AA,yy,zz);CHKERRQ(ierr); } if (view_y) { ierr = PetscPrintf(PETSC_COMM_WORLD, "y = \n");CHKERRQ(ierr); ierr = VecView(y, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "yy = \n");CHKERRQ(ierr); ierr = VecView(yy, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } if (view_z) { ierr = PetscPrintf(PETSC_COMM_WORLD, "z = \n");CHKERRQ(ierr); ierr = VecView(z, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "zz = \n");CHKERRQ(ierr); ierr = VecView(zz, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } /* compare x and z. USFFT computes an unnormalized DFT, thus z = N*x */ s = 1.0/(PetscReal)N; ierr = VecScale(z,s);CHKERRQ(ierr); ierr = VecAXPY(x,-1.0,z);CHKERRQ(ierr); ierr = VecNorm(x,NORM_1,&enorm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF, "|x-z| = %g\n",enorm);CHKERRQ(ierr); /* compare xx and zz. FFTW computes an unnormalized DFT, thus zz = N*x */ s = 1.0/(PetscReal)N; ierr = VecScale(zz,s);CHKERRQ(ierr); ierr = VecAXPY(xx,-1.0,zz);CHKERRQ(ierr); ierr = VecNorm(xx,NORM_1,&enorm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF, "|xx-zz| = %g\n",enorm);CHKERRQ(ierr); /* compare y and yy: USFFT and FFTW results*/ ierr = VecNorm(y,NORM_2,&norm);CHKERRQ(ierr); ierr = VecAXPY(y,-1.0,yy);CHKERRQ(ierr); ierr = VecNorm(y,NORM_1,&enorm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF, "|y|_2 = %g\n",norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF, "|y-yy| = %g\n",enorm);CHKERRQ(ierr); /* compare z and zz: USFFT and FFTW results*/ ierr = VecNorm(z,NORM_2,&norm);CHKERRQ(ierr); ierr = VecAXPY(z,-1.0,zz);CHKERRQ(ierr); ierr = VecNorm(z,NORM_1,&enorm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF, "|z|_2 = %g\n",norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF, "|z-zz| = %g\n",enorm);CHKERRQ(ierr); /* free spaces */ ierr = DMRestoreGlobalVector(da,&x);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(da,&xx);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(da,&y);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(da,&yy);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(da,&z);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(da,&zz);CHKERRQ(ierr); ierr = VecDestroy(&coords);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc,char **args) { Mat A,C,Bdense,Cdense; PetscErrorCode ierr; PetscViewer fd; /* viewer */ char file[PETSC_MAX_PATH_LEN]; /* input file name */ PetscBool flg,viewmats=PETSC_FALSE; PetscMPIInt rank,size; PetscReal fill=1.0; PetscInt m,n,i,j,BN=10,rstart,rend,*rows,*cols; PetscScalar *Barray,*Carray,rval,*array; Vec x,y; PetscRandom rand; PetscInitialize(&argc,&args,(char*)0,help); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); /* Determine file from which we read the matrix A */ ierr = PetscOptionsGetString(NULL,"-f",file,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (!flg) SETERRQ(PETSC_COMM_WORLD,1,"Must indicate binary file with the -f option"); /* Load matrix A */ ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file,FILE_MODE_READ,&fd);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatLoad(A,fd);CHKERRQ(ierr); ierr = PetscViewerDestroy(&fd);CHKERRQ(ierr); /* Print (for testing only) */ ierr = PetscOptionsHasName(NULL, "-view_mats", &viewmats);CHKERRQ(ierr); if (viewmats) { if (!rank) printf("A_aij:\n"); ierr = MatView(A,0);CHKERRQ(ierr); } /* Test MatTransposeMatMult_aij_aij() */ ierr = MatTransposeMatMult(A,A,MAT_INITIAL_MATRIX,fill,&C);CHKERRQ(ierr); if (viewmats) { if (!rank) printf("\nC = A_aij^T * A_aij:\n"); ierr = MatView(C,0);CHKERRQ(ierr); } ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); /* create a dense matrix Bdense */ ierr = MatCreate(PETSC_COMM_WORLD,&Bdense);CHKERRQ(ierr); ierr = MatSetSizes(Bdense,m,PETSC_DECIDE,PETSC_DECIDE,BN);CHKERRQ(ierr); ierr = MatSetType(Bdense,MATDENSE);CHKERRQ(ierr); ierr = MatSetFromOptions(Bdense);CHKERRQ(ierr); ierr = MatSetUp(Bdense);CHKERRQ(ierr); ierr = MatGetOwnershipRange(Bdense,&rstart,&rend);CHKERRQ(ierr); //printf("[%d] rstart/end %d %d; local size %d %d\n",rank,rstart,rend,m,n); ierr = PetscMalloc3(m,PetscInt,&rows,BN,PetscInt,&cols,m*BN,PetscScalar,&array);CHKERRQ(ierr); for (i=0; i<m; i++) rows[i] = rstart + i; ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rand);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rand);CHKERRQ(ierr); for (j=0; j<BN; j++) { cols[j] = j; for (i=0; i<m; i++) { ierr = PetscRandomGetValue(rand,&rval);CHKERRQ(ierr); array[m*j+i] = rval; } } ierr = MatSetValues(Bdense,m,rows,BN,cols,array,INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(Bdense,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(Bdense,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rand);CHKERRQ(ierr); ierr = PetscFree3(rows,cols,array);CHKERRQ(ierr); if (viewmats) { if (!rank) printf("\nBdense:\n"); ierr = MatView(Bdense,0);CHKERRQ(ierr); } /* Test MatTransposeMatMult_aij_dense() */ ierr = MatTransposeMatMult(A,Bdense,MAT_INITIAL_MATRIX,fill,&C);CHKERRQ(ierr); ierr = MatTransposeMatMult(A,Bdense,MAT_REUSE_MATRIX,fill,&C);CHKERRQ(ierr); if (viewmats) { if (!rank) printf("\nC=A^T*Bdense:\n"); ierr = MatView(C,0);CHKERRQ(ierr); } /* Check accuracy */ ierr = MatCreate(PETSC_COMM_WORLD,&Cdense);CHKERRQ(ierr); ierr = MatSetSizes(Cdense,n,PETSC_DECIDE,PETSC_DECIDE,BN);CHKERRQ(ierr); ierr = MatSetType(Cdense,MATDENSE);CHKERRQ(ierr); ierr = MatSetFromOptions(Cdense);CHKERRQ(ierr); ierr = MatSetUp(Cdense);CHKERRQ(ierr); ierr = MatAssemblyBegin(Cdense,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(Cdense,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size == 1) { ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,m,NULL,&x);CHKERRQ(ierr); ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,n,NULL,&y);CHKERRQ(ierr); } else { ierr = VecCreateMPIWithArray(PETSC_COMM_WORLD,1,m,PETSC_DECIDE,NULL,&x);CHKERRQ(ierr); ierr = VecCreateMPIWithArray(PETSC_COMM_WORLD,1,n,PETSC_DECIDE,NULL,&y);CHKERRQ(ierr); } /* Cdense[:,j] = A^T * Bdense[:,j] */ ierr = MatDenseGetArray(Bdense,&Barray);CHKERRQ(ierr); ierr = MatDenseGetArray(Cdense,&Carray);CHKERRQ(ierr); for (j=0; j<BN; j++) { ierr = VecPlaceArray(x,Barray);CHKERRQ(ierr); ierr = VecPlaceArray(y,Carray);CHKERRQ(ierr); ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); ierr = VecResetArray(x);CHKERRQ(ierr); ierr = VecResetArray(y);CHKERRQ(ierr); Barray += m; Carray += n; } ierr = MatDenseRestoreArray(Bdense,&Barray);CHKERRQ(ierr); ierr = MatDenseRestoreArray(Cdense,&Carray);CHKERRQ(ierr); if (viewmats) { if (!rank) printf("\nCdense:\n"); ierr = MatView(Cdense,0);CHKERRQ(ierr); } ierr = MatEqual(C,Cdense,&flg);CHKERRQ(ierr); if (!flg) { if (!rank) printf(" C != Cdense\n"); } /* Free data structures */ ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = MatDestroy(&Bdense);CHKERRQ(ierr); ierr = MatDestroy(&Cdense);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&y);CHKERRQ(ierr); ierr = PetscFinalize(); return 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; ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; 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 ierr; }
int main(int argc,char **argv) { PetscInt M1 = 3,M2,dof = 1,s = 1,ratio = 2,dim = 1; PetscErrorCode ierr; DM da_c,da_f; Vec v_c,v_f; Mat Interp; PetscScalar one = 1.0; PetscBool pt; DMDABoundaryType bx = DMDA_BOUNDARY_NONE,by = DMDA_BOUNDARY_NONE,bz = DMDA_BOUNDARY_NONE; ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-dim",&dim,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-M",&M1,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-stencil_width",&s,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-ratio",&ratio,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-dof",&dof,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,"-periodic",(PetscBool*)&pt,NULL);CHKERRQ(ierr); if (pt) { if (dim > 0) bx = DMDA_BOUNDARY_PERIODIC; if (dim > 1) by = DMDA_BOUNDARY_PERIODIC; if (dim > 2) bz = DMDA_BOUNDARY_PERIODIC; } if (bx == DMDA_BOUNDARY_NONE) { M2 = ratio*(M1-1) + 1; } else { M2 = ratio*M1; } /* Set up the array */ if (dim == 1) { ierr = DMDACreate1d(PETSC_COMM_WORLD,bx,M1,dof,s,NULL,&da_c);CHKERRQ(ierr); ierr = DMDACreate1d(PETSC_COMM_WORLD,bx,M2,dof,s,NULL,&da_f);CHKERRQ(ierr); } else if (dim == 2) { ierr = DMDACreate2d(PETSC_COMM_WORLD,bx,by,DMDA_STENCIL_BOX,M1,M1,PETSC_DECIDE,PETSC_DECIDE,dof,s,NULL,NULL,&da_c);CHKERRQ(ierr); ierr = DMDACreate2d(PETSC_COMM_WORLD,bx,by,DMDA_STENCIL_BOX,M2,M2,PETSC_DECIDE,PETSC_DECIDE,dof,s,NULL,NULL,&da_f);CHKERRQ(ierr); } else if (dim == 3) { ierr = DMDACreate3d(PETSC_COMM_WORLD,bx,by,bz,DMDA_STENCIL_BOX,M1,M1,M1,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,dof,s,NULL,NULL,NULL,&da_c);CHKERRQ(ierr); ierr = DMDACreate3d(PETSC_COMM_WORLD,bx,by,bz,DMDA_STENCIL_BOX,M2,M2,M2,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,dof,s,NULL,NULL,NULL,&da_f);CHKERRQ(ierr); } else SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"dim must be 1,2, or 3"); ierr = DMCreateGlobalVector(da_c,&v_c);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da_f,&v_f);CHKERRQ(ierr); ierr = VecSet(v_c,one);CHKERRQ(ierr); ierr = DMCreateInterpolation(da_c,da_f,&Interp,NULL);CHKERRQ(ierr); ierr = MatMult(Interp,v_c,v_f);CHKERRQ(ierr); ierr = VecView(v_f,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = MatMultTranspose(Interp,v_f,v_c);CHKERRQ(ierr); ierr = VecView(v_c,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = MatDestroy(&Interp);CHKERRQ(ierr); ierr = VecDestroy(&v_c);CHKERRQ(ierr); ierr = DMDestroy(&da_c);CHKERRQ(ierr); ierr = VecDestroy(&v_f);CHKERRQ(ierr); ierr = DMDestroy(&da_f);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **args) { Mat C; Vec s,u,w,x,y,z; PetscErrorCode ierr; PetscInt i,j,m = 8,n,rstart,rend,vstart,vend; PetscScalar one = 1.0,negone = -1.0,v,alpha=0.1; PetscReal norm, tol = PETSC_SQRT_MACHINE_EPSILON; PetscBool flg; ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_WORLD,PETSC_VIEWER_ASCII_COMMON);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-m",&m,NULL);CHKERRQ(ierr); n = m; ierr = PetscOptionsHasName(NULL,NULL,"-rectA",&flg);CHKERRQ(ierr); if (flg) n += 2; ierr = PetscOptionsHasName(NULL,NULL,"-rectB",&flg);CHKERRQ(ierr); if (flg) n -= 2; /* ---------- Assemble matrix and vectors ----------- */ ierr = MatCreate(PETSC_COMM_WORLD,&C);CHKERRQ(ierr); ierr = MatSetSizes(C,PETSC_DECIDE,PETSC_DECIDE,m,n);CHKERRQ(ierr); ierr = MatSetFromOptions(C);CHKERRQ(ierr); ierr = MatSetUp(C);CHKERRQ(ierr); ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_WORLD,&x);CHKERRQ(ierr); ierr = VecSetSizes(x,PETSC_DECIDE,m);CHKERRQ(ierr); ierr = VecSetFromOptions(x);CHKERRQ(ierr); ierr = VecDuplicate(x,&z);CHKERRQ(ierr); ierr = VecDuplicate(x,&w);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_WORLD,&y);CHKERRQ(ierr); ierr = VecSetSizes(y,PETSC_DECIDE,n);CHKERRQ(ierr); ierr = VecSetFromOptions(y);CHKERRQ(ierr); ierr = VecDuplicate(y,&u);CHKERRQ(ierr); ierr = VecDuplicate(y,&s);CHKERRQ(ierr); ierr = VecGetOwnershipRange(y,&vstart,&vend);CHKERRQ(ierr); /* Assembly */ for (i=rstart; i<rend; i++) { v = 100*(i+1); ierr = VecSetValues(z,1,&i,&v,INSERT_VALUES);CHKERRQ(ierr); for (j=0; j<n; j++) { v = 10*(i+1)+j+1; ierr = MatSetValues(C,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); } } /* Flush off proc Vec values and do more assembly */ ierr = VecAssemblyBegin(z);CHKERRQ(ierr); for (i=vstart; i<vend; i++) { v = one*((PetscReal)i); ierr = VecSetValues(y,1,&i,&v,INSERT_VALUES);CHKERRQ(ierr); v = 100.0*i; ierr = VecSetValues(u,1,&i,&v,INSERT_VALUES);CHKERRQ(ierr); } /* Flush off proc Mat values and do more assembly */ ierr = MatAssemblyBegin(C,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); for (i=rstart; i<rend; i++) { for (j=0; j<n; j++) { v = 10*(i+1)+j+1; ierr = MatSetValues(C,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); } } /* Try overlap Coomunication with the next stage XXXSetValues */ ierr = VecAssemblyEnd(z);CHKERRQ(ierr); ierr = MatAssemblyEnd(C,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); CHKMEMQ; /* The Assembly for the second Stage */ ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = VecAssemblyBegin(y);CHKERRQ(ierr); ierr = VecAssemblyEnd(y);CHKERRQ(ierr); ierr = MatScale(C,alpha);CHKERRQ(ierr); ierr = VecAssemblyBegin(u);CHKERRQ(ierr); ierr = VecAssemblyEnd(u);CHKERRQ(ierr); /* ------------ Test MatMult(), MatMultAdd() ---------- */ ierr = PetscPrintf(PETSC_COMM_WORLD,"testing MatMult()\n");CHKERRQ(ierr); CHKMEMQ; ierr = MatMult(C,y,x);CHKERRQ(ierr); CHKMEMQ; ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"testing MatMultAdd()\n");CHKERRQ(ierr); ierr = MatMultAdd(C,y,z,w);CHKERRQ(ierr); ierr = VecAXPY(x,one,z);CHKERRQ(ierr); ierr = VecAXPY(x,negone,w);CHKERRQ(ierr); ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Norm of error difference = %g\n",(double)norm);CHKERRQ(ierr); } /* ------- Test MatMultTranspose(), MatMultTransposeAdd() ------- */ for (i=rstart; i<rend; i++) { v = one*((PetscReal)i); ierr = VecSetValues(x,1,&i,&v,INSERT_VALUES);CHKERRQ(ierr); } ierr = VecAssemblyBegin(x);CHKERRQ(ierr); ierr = VecAssemblyEnd(x);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"testing MatMultTranspose()\n");CHKERRQ(ierr); ierr = MatMultTranspose(C,x,y);CHKERRQ(ierr); ierr = VecView(y,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"testing MatMultTransposeAdd()\n");CHKERRQ(ierr); ierr = MatMultTransposeAdd(C,x,u,s);CHKERRQ(ierr); ierr = VecAXPY(y,one,u);CHKERRQ(ierr); ierr = VecAXPY(y,negone,s);CHKERRQ(ierr); ierr = VecNorm(y,NORM_2,&norm);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Norm of error difference = %g\n",(double)norm);CHKERRQ(ierr); } /* -------------------- Test MatGetDiagonal() ------------------ */ ierr = PetscPrintf(PETSC_COMM_WORLD,"testing MatGetDiagonal(), MatDiagonalScale()\n");CHKERRQ(ierr); ierr = MatView(C,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecSet(x,one);CHKERRQ(ierr); ierr = MatGetDiagonal(C,x);CHKERRQ(ierr); ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); for (i=vstart; i<vend; i++) { v = one*((PetscReal)(i+1)); ierr = VecSetValues(y,1,&i,&v,INSERT_VALUES);CHKERRQ(ierr); } /* -------------------- Test () MatDiagonalScale ------------------ */ ierr = PetscOptionsHasName(NULL,NULL,"-test_diagonalscale",&flg);CHKERRQ(ierr); if (flg) { ierr = MatDiagonalScale(C,x,y);CHKERRQ(ierr); ierr = MatView(C,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } /* Free data structures */ ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = VecDestroy(&s);CHKERRQ(ierr); ierr = VecDestroy(&w);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&y);CHKERRQ(ierr); ierr = VecDestroy(&z);CHKERRQ(ierr); ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
PetscErrorCode KSPSolve_CGNE(KSP ksp) { PetscErrorCode ierr; PetscInt i,stored_max_it,eigs; PetscScalar dpi,a = 1.0,beta,betaold = 1.0,b = 0,*e = 0,*d = 0; PetscReal dp = 0.0; Vec X,B,Z,R,P,T; KSP_CG *cg; Mat Amat,Pmat; PetscBool diagonalscale,transpose_pc; PetscFunctionBegin; ierr = PCGetDiagonalScale(ksp->pc,&diagonalscale);CHKERRQ(ierr); if (diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"Krylov method %s does not support diagonal scaling",((PetscObject)ksp)->type_name); ierr = PCApplyTransposeExists(ksp->pc,&transpose_pc);CHKERRQ(ierr); cg = (KSP_CG*)ksp->data; eigs = ksp->calc_sings; stored_max_it = ksp->max_it; X = ksp->vec_sol; B = ksp->vec_rhs; R = ksp->work[0]; Z = ksp->work[1]; P = ksp->work[2]; T = ksp->work[3]; #define VecXDot(x,y,a) (((cg->type) == (KSP_CG_HERMITIAN)) ? VecDot(x,y,a) : VecTDot(x,y,a)) if (eigs) {e = cg->e; d = cg->d; e[0] = 0.0; } ierr = PCGetOperators(ksp->pc,&Amat,&Pmat);CHKERRQ(ierr); ksp->its = 0; ierr = MatMultTranspose(Amat,B,T);CHKERRQ(ierr); if (!ksp->guess_zero) { ierr = KSP_MatMult(ksp,Amat,X,P);CHKERRQ(ierr); ierr = KSP_MatMultTranspose(ksp,Amat,P,R);CHKERRQ(ierr); ierr = VecAYPX(R,-1.0,T);CHKERRQ(ierr); } else { ierr = VecCopy(T,R);CHKERRQ(ierr); /* r <- b (x is 0) */ } ierr = KSP_PCApply(ksp,R,T);CHKERRQ(ierr); if (transpose_pc) { ierr = KSP_PCApplyTranspose(ksp,T,Z);CHKERRQ(ierr); } else { ierr = KSP_PCApply(ksp,T,Z);CHKERRQ(ierr); } if (ksp->normtype == KSP_NORM_PRECONDITIONED) { ierr = VecNorm(Z,NORM_2,&dp);CHKERRQ(ierr); /* dp <- z'*z */ } else if (ksp->normtype == KSP_NORM_UNPRECONDITIONED) { ierr = VecNorm(R,NORM_2,&dp);CHKERRQ(ierr); /* dp <- r'*r */ } else if (ksp->normtype == KSP_NORM_NATURAL) { ierr = VecXDot(Z,R,&beta);CHKERRQ(ierr); dp = PetscSqrtReal(PetscAbsScalar(beta)); } else dp = 0.0; ierr = KSPLogResidualHistory(ksp,dp);CHKERRQ(ierr); ierr = KSPMonitor(ksp,0,dp);CHKERRQ(ierr); ksp->rnorm = dp; ierr = (*ksp->converged)(ksp,0,dp,&ksp->reason,ksp->cnvP);CHKERRQ(ierr); /* test for convergence */ if (ksp->reason) PetscFunctionReturn(0); i = 0; do { ksp->its = i+1; ierr = VecXDot(Z,R,&beta);CHKERRQ(ierr); /* beta <- r'z */ if (beta == 0.0) { ksp->reason = KSP_CONVERGED_ATOL; ierr = PetscInfo(ksp,"converged due to beta = 0\n");CHKERRQ(ierr); break; #if !defined(PETSC_USE_COMPLEX) } else if (beta < 0.0) { ksp->reason = KSP_DIVERGED_INDEFINITE_PC; ierr = PetscInfo(ksp,"diverging due to indefinite preconditioner\n");CHKERRQ(ierr); break; #endif } if (!i) { ierr = VecCopy(Z,P);CHKERRQ(ierr); /* p <- z */ b = 0.0; } else { b = beta/betaold; if (eigs) { if (ksp->max_it != stored_max_it) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"Can not change maxit AND calculate eigenvalues"); e[i] = PetscSqrtReal(PetscAbsScalar(b))/a; } ierr = VecAYPX(P,b,Z);CHKERRQ(ierr); /* p <- z + b* p */ } betaold = beta; ierr = MatMult(Amat,P,T);CHKERRQ(ierr); ierr = MatMultTranspose(Amat,T,Z);CHKERRQ(ierr); ierr = VecXDot(P,Z,&dpi);CHKERRQ(ierr); /* dpi <- z'p */ a = beta/dpi; /* a = beta/p'z */ if (eigs) d[i] = PetscSqrtReal(PetscAbsScalar(b))*e[i] + 1.0/a; ierr = VecAXPY(X,a,P);CHKERRQ(ierr); /* x <- x + ap */ ierr = VecAXPY(R,-a,Z);CHKERRQ(ierr); /* r <- r - az */ if (ksp->normtype == KSP_NORM_PRECONDITIONED) { ierr = KSP_PCApply(ksp,R,T);CHKERRQ(ierr); if (transpose_pc) { ierr = KSP_PCApplyTranspose(ksp,T,Z);CHKERRQ(ierr); } else { ierr = KSP_PCApply(ksp,T,Z);CHKERRQ(ierr); } ierr = VecNorm(Z,NORM_2,&dp);CHKERRQ(ierr); /* dp <- z'*z */ } else if (ksp->normtype == KSP_NORM_UNPRECONDITIONED) { ierr = VecNorm(R,NORM_2,&dp);CHKERRQ(ierr); } else if (ksp->normtype == KSP_NORM_NATURAL) { dp = PetscSqrtReal(PetscAbsScalar(beta)); } else { dp = 0.0; } ksp->rnorm = dp; ierr = KSPLogResidualHistory(ksp,dp);CHKERRQ(ierr); ierr = KSPMonitor(ksp,i+1,dp);CHKERRQ(ierr); ierr = (*ksp->converged)(ksp,i+1,dp,&ksp->reason,ksp->cnvP);CHKERRQ(ierr); if (ksp->reason) break; if (ksp->normtype != KSP_NORM_PRECONDITIONED) { if (transpose_pc) { ierr = KSP_PCApplyTranspose(ksp,T,Z);CHKERRQ(ierr); } else { ierr = KSP_PCApply(ksp,T,Z);CHKERRQ(ierr); } } i++; } while (i<ksp->max_it); if (i >= ksp->max_it) ksp->reason = KSP_DIVERGED_ITS; PetscFunctionReturn(0); }