Actual source code: ex46.c
petsc-3.13.6 2020-09-29
2: static char help[] = "Solves a linear system in parallel with KSP and DM.\n\
3: Compare this to ex2 which solves the same problem without a DM.\n\n";
5: /*T
6: Concepts: KSP^basic parallel example;
7: Concepts: KSP^Laplacian, 2d
8: Concepts: DM^using distributed arrays;
9: Concepts: Laplacian, 2d
10: Processors: n
11: T*/
15: /*
16: Include "petscdmda.h" so that we can use distributed arrays (DMDAs).
17: Include "petscksp.h" so that we can use KSP solvers. Note that this file
18: automatically includes:
19: petscsys.h - base PETSc routines petscvec.h - vectors
20: petscmat.h - matrices
21: petscis.h - index sets petscksp.h - Krylov subspace methods
22: petscviewer.h - viewers petscpc.h - preconditioners
23: */
24: #include <petscdm.h>
25: #include <petscdmda.h>
26: #include <petscksp.h>
28: int main(int argc,char **argv)
29: {
30: DM da; /* distributed array */
31: Vec x,b,u; /* approx solution, RHS, exact solution */
32: Mat A; /* linear system matrix */
33: KSP ksp; /* linear solver context */
34: PetscRandom rctx; /* random number generator context */
35: PetscReal norm; /* norm of solution error */
36: PetscInt i,j,its;
38: PetscBool flg = PETSC_FALSE;
39: PetscLogStage stage;
40: DMDALocalInfo info;
42: PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr;
43: /*
44: Create distributed array to handle parallel distribution.
45: The problem size will default to 8 by 7, but this can be
46: changed using -da_grid_x M -da_grid_y N
47: */
48: DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,8,7,PETSC_DECIDE,PETSC_DECIDE,1,1,NULL,NULL,&da);
49: DMSetFromOptions(da);
50: DMSetUp(da);
52: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
53: Compute the matrix and right-hand-side vector that define
54: the linear system, Ax = b.
55: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
56: /*
57: Create parallel matrix preallocated according to the DMDA, format AIJ by default.
58: To use symmetric storage, run with -dm_mat_type sbaij -mat_ignore_lower_triangular
59: */
60: DMCreateMatrix(da,&A);
62: /*
63: Set matrix elements for the 2-D, five-point stencil in parallel.
64: - Each processor needs to insert only elements that it owns
65: locally (but any non-local elements will be sent to the
66: appropriate processor during matrix assembly).
67: - Rows and columns are specified by the stencil
68: - Entries are normalized for a domain [0,1]x[0,1]
69: */
70: PetscLogStageRegister("Assembly", &stage);
71: PetscLogStagePush(stage);
72: DMDAGetLocalInfo(da,&info);
73: for (j=info.ys; j<info.ys+info.ym; j++) {
74: for (i=info.xs; i<info.xs+info.xm; i++) {
75: PetscReal hx = 1./info.mx,hy = 1./info.my;
76: MatStencil row = {0},col[5] = {{0}};
77: PetscScalar v[5];
78: PetscInt ncols = 0;
79: row.j = j; row.i = i;
80: col[ncols].j = j; col[ncols].i = i; v[ncols++] = 2*(hx/hy + hy/hx);
81: /* boundaries */
82: if (i>0) {col[ncols].j = j; col[ncols].i = i-1; v[ncols++] = -hy/hx;}
83: if (i<info.mx-1) {col[ncols].j = j; col[ncols].i = i+1; v[ncols++] = -hy/hx;}
84: if (j>0) {col[ncols].j = j-1; col[ncols].i = i; v[ncols++] = -hx/hy;}
85: if (j<info.my-1) {col[ncols].j = j+1; col[ncols].i = i; v[ncols++] = -hx/hy;}
86: MatSetValuesStencil(A,1,&row,ncols,col,v,INSERT_VALUES);
87: }
88: }
90: /*
91: Assemble matrix, using the 2-step process:
92: MatAssemblyBegin(), MatAssemblyEnd()
93: Computations can be done while messages are in transition
94: by placing code between these two statements.
95: */
96: MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);
97: MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);
98: PetscLogStagePop();
100: /*
101: Create parallel vectors compatible with the DMDA.
102: */
103: DMCreateGlobalVector(da,&u);
104: VecDuplicate(u,&b);
105: VecDuplicate(u,&x);
107: /*
108: Set exact solution; then compute right-hand-side vector.
109: By default we use an exact solution of a vector with all
110: elements of 1.0; Alternatively, using the runtime option
111: -random_sol forms a solution vector with random components.
112: */
113: PetscOptionsGetBool(NULL,NULL,"-random_exact_sol",&flg,NULL);
114: if (flg) {
115: PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
116: PetscRandomSetFromOptions(rctx);
117: VecSetRandom(u,rctx);
118: PetscRandomDestroy(&rctx);
119: } else {
120: VecSet(u,1.);
121: }
122: MatMult(A,u,b);
124: /*
125: View the exact solution vector if desired
126: */
127: flg = PETSC_FALSE;
128: PetscOptionsGetBool(NULL,NULL,"-view_exact_sol",&flg,NULL);
129: if (flg) {VecView(u,PETSC_VIEWER_STDOUT_WORLD);}
131: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
132: Create the linear solver and set various options
133: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
135: /*
136: Create linear solver context
137: */
138: KSPCreate(PETSC_COMM_WORLD,&ksp);
140: /*
141: Set operators. Here the matrix that defines the linear system
142: also serves as the preconditioning matrix.
143: */
144: KSPSetOperators(ksp,A,A);
146: /*
147: Set runtime options, e.g.,
148: -ksp_type <type> -pc_type <type> -ksp_monitor -ksp_rtol <rtol>
149: These options will override those specified above as long as
150: KSPSetFromOptions() is called _after_ any other customization
151: routines.
152: */
153: KSPSetFromOptions(ksp);
155: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
156: Solve the linear system
157: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
159: KSPSolve(ksp,b,x);
161: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
162: Check solution and clean up
163: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
165: /*
166: Check the error
167: */
168: VecAXPY(x,-1.,u);
169: VecNorm(x,NORM_2,&norm);
170: KSPGetIterationNumber(ksp,&its);
172: /*
173: Print convergence information. PetscPrintf() produces a single
174: print statement from all processes that share a communicator.
175: An alternative is PetscFPrintf(), which prints to a file.
176: */
177: PetscPrintf(PETSC_COMM_WORLD,"Norm of error %g iterations %D\n",(double)norm,its);
179: /*
180: Free work space. All PETSc objects should be destroyed when they
181: are no longer needed.
182: */
183: KSPDestroy(&ksp);
184: VecDestroy(&u);
185: VecDestroy(&x);
186: VecDestroy(&b);
187: MatDestroy(&A);
188: DMDestroy(&da);
190: /*
191: Always call PetscFinalize() before exiting a program. This routine
192: - finalizes the PETSc libraries as well as MPI
193: - provides summary and diagnostic information if certain runtime
194: options are chosen (e.g., -log_view).
195: */
196: PetscFinalize();
197: return ierr;
198: }
201: /*TEST
203: testset:
204: requires: cuda
205: args: -dm_mat_type aijcusparse -dm_vec_type cuda -random_exact_sol
206: output_file: output/ex46_aijcusparse.out
208: test:
209: suffix: aijcusparse
210: args: -use_gpu_aware_mpi 0
211: test:
212: suffix: aijcusparse_mpi_gpu_aware
214: testset:
215: requires: cuda
216: args: -dm_mat_type aijcusparse -dm_vec_type cuda -random_exact_sol -pc_type ilu -pc_factor_mat_solver_type cusparse
217: output_file: output/ex46_aijcusparse_2.out
218: test:
219: suffix: aijcusparse_2
220: args: -use_gpu_aware_mpi 0
221: test:
222: suffix: aijcusparse_2_mpi_gpu_aware
225: TEST*/