Actual source code: ex72.c

  1: static char help[] = "Reads a PETSc matrix and vector from a file and solves a linear system.\n\
  2: This version first preloads and solves a small system, then loads \n\
  3: another (larger) system and solves it as well.  This example illustrates\n\
  4: preloading of instructions with the smaller system so that more accurate\n\
  5: performance monitoring can be done with the larger one (that actually\n\
  6: is the system of interest).  See the 'Performance Hints' chapter of the\n\
  7: users manual for a discussion of preloading.  Input parameters include\n\
  8:   -f0 <input_file> : first file to load (small system)\n\
  9:   -f1 <input_file> : second file to load (larger system)\n\n\
 10:   -nearnulldim <0> : number of vectors in the near-null space immediately following matrix\n\n\
 11:   -assemble_local : assemble repeated local indices after loading a MATIS matrix\n\n\
 12:   -trans  : solve transpose system instead\n\n";
 13: /*
 14:   This code can be used to test PETSc interface to other packages.\n\
 15:   Examples of command line options:       \n\
 16:    ./ex72 -f0 <datafile> -ksp_type preonly  \n\
 17:         -help -ksp_view                  \n\
 18:         -num_numfac <num_numfac> -num_rhs <num_rhs> \n\
 19:         -ksp_type preonly -pc_type lu -pc_factor_mat_solver_type superlu or superlu_dist or mumps \n\
 20:         -ksp_type preonly -pc_type cholesky -pc_factor_mat_solver_type mumps \n\
 21:    mpiexec -n <np> ./ex72 -f0 <datafile> -ksp_type cg -pc_type asm -pc_asm_type basic -sub_pc_type icc -mat_type sbaij
 22:  \n\n";
 23: */

 25: /*
 26:   Include "petscksp.h" so that we can use KSP solvers.  Note that this file
 27:   automatically includes:
 28:      petscsys.h       - base PETSc routines   petscvec.h - vectors
 29:      petscmat.h - matrices
 30:      petscis.h     - index sets            petscksp.h - Krylov subspace methods
 31:      petscviewer.h - viewers               petscpc.h  - preconditioners
 32: */
 33: #include <petscksp.h>

 35: static PetscErrorCode TestBDDCCustomization(PC pc, Vec b)
 36: {
 37:   PC           restored;
 38:   Mat          A, P;
 39:   Vec          x, y;
 40:   PetscOptions options;
 41:   char        *alloptions;
 42:   PetscReal    norm, error;

 44:   PetscFunctionBeginUser;
 45:   PetscCall(PCBDDCSaveCustomization(pc, "bddc_roundtrip.dat", PETSC_DECIDE));
 46:   PetscCall(PetscOptionsCreate(&options));
 47:   PetscCall(PetscOptionsGetAll(NULL, &alloptions));
 48:   PetscCall(PetscOptionsInsertString(options, alloptions));
 49:   PetscCall(PetscFree(alloptions));
 50:   // Load only the saved customization into a fresh preconditioner.
 51:   PetscCall(PetscOptionsSetValue(options, "-pc_bddc_load", "bddc_roundtrip.dat"));
 52:   PetscCall(PetscOptionsClearValue(options, "-pc_bddc_load_version"));
 53:   PetscCall(PCCreate(PetscObjectComm((PetscObject)pc), &restored));
 54:   PetscCall(PetscObjectSetOptions((PetscObject)restored, options));
 55:   PetscCall(PCGetOperators(pc, &A, &P));
 56:   PetscCall(PCSetOperators(restored, A, P));
 57:   PetscCall(PCSetType(restored, PCBDDC));
 58:   PetscCall(PCSetFromOptions(restored));
 59:   PetscCall(PCSetUp(restored));
 60:   PetscCall(VecDuplicate(b, &x));
 61:   PetscCall(VecDuplicate(b, &y));
 62:   PetscCall(PCApply(pc, b, x));
 63:   PetscCall(PCApply(restored, b, y));
 64:   PetscCall(VecNorm(x, NORM_2, &norm));
 65:   PetscCall(VecAXPY(y, -1.0, x));
 66:   PetscCall(VecNorm(y, NORM_2, &error));
 67:   PetscCheck(error <= 1000 * PETSC_MACHINE_EPSILON * PetscMax(1.0, norm), PetscObjectComm((PetscObject)pc), PETSC_ERR_PLIB, "Restored BDDC action differs by %g (reference norm %g)", (double)error, (double)norm);
 68:   PetscCall(VecDestroy(&x));
 69:   PetscCall(VecDestroy(&y));
 70:   PetscCall(PCDestroy(&restored));
 71:   PetscCall(PetscOptionsDestroy(&options));
 72:   PetscFunctionReturn(PETSC_SUCCESS);
 73: }

 75: int main(int argc, char **args)
 76: {
 77:   KSP         ksp;                         /* linear solver context */
 78:   Mat         A;                           /* matrix */
 79:   Vec         x, b, u;                     /* approx solution, RHS, exact solution */
 80:   PetscViewer viewer;                      /* viewer */
 81:   char        file[4][PETSC_MAX_PATH_LEN]; /* input file name */
 82:   PetscBool   table = PETSC_FALSE, flg, trans = PETSC_FALSE, initialguess = PETSC_FALSE;
 83:   PetscBool   outputSoln = PETSC_FALSE, constantnullspace = PETSC_FALSE;
 84:   PetscInt    its, num_numfac, m, n, M, p, nearnulldim = 0;
 85:   PetscReal   norm;
 86:   PetscBool   preload = PETSC_TRUE, isSymmetric, cknorm = PETSC_FALSE, initialguessfile = PETSC_FALSE;
 87:   PetscMPIInt rank;
 88:   char        initialguessfilename[PETSC_MAX_PATH_LEN];
 89:   char        mtype[PETSC_MAX_PATH_LEN];

 91:   PetscFunctionBeginUser;
 92:   PetscCall(PetscInitialize(&argc, &args, NULL, help));
 93:   PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
 94:   PetscCall(PetscOptionsGetBool(NULL, NULL, "-table", &table, NULL));
 95:   PetscCall(PetscOptionsGetBool(NULL, NULL, "-constantnullspace", &constantnullspace, NULL));
 96:   PetscCall(PetscOptionsGetBool(NULL, NULL, "-trans", &trans, NULL));
 97:   PetscCall(PetscOptionsGetBool(NULL, NULL, "-initialguess", &initialguess, NULL));
 98:   PetscCall(PetscOptionsGetBool(NULL, NULL, "-output_solution", &outputSoln, NULL));
 99:   PetscCall(PetscOptionsGetString(NULL, NULL, "-initialguessfilename", initialguessfilename, sizeof(initialguessfilename), &initialguessfile));
100:   PetscCall(PetscOptionsGetInt(NULL, NULL, "-nearnulldim", &nearnulldim, NULL));

102:   /*
103:      Determine files from which we read the two linear systems
104:      (matrix and right-hand-side vector).
105:   */
106:   PetscCall(PetscOptionsGetString(NULL, NULL, "-f", file[0], sizeof(file[0]), &flg));
107:   if (flg) {
108:     PetscCall(PetscStrncpy(file[1], file[0], sizeof(file[1])));
109:     preload = PETSC_FALSE;
110:   } else {
111:     PetscCall(PetscOptionsGetString(NULL, NULL, "-f0", file[0], sizeof(file[0]), &flg));
112:     PetscCheck(flg, PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT, "Must indicate binary file with the -f0 or -f option");
113:     PetscCall(PetscOptionsGetString(NULL, NULL, "-f1", file[1], sizeof(file[1]), &flg));
114:     if (!flg) preload = PETSC_FALSE; /* don't bother with second system */
115:   }

117:   /* -----------------------------------------------------------
118:                   Beginning of linear solver loop
119:      ----------------------------------------------------------- */
120:   /*
121:      Loop through the linear solve 2 times.
122:       - The intention here is to preload and solve a small system;
123:         then load another (larger) system and solve it as well.
124:         This process preloads the instructions with the smaller
125:         system so that more accurate performance monitoring (via
126:         -log_view) can be done with the larger one (that actually
127:         is the system of interest).
128:   */
129:   PetscPreLoadBegin(preload, "Load system");

131:   /* - - - - - - - - - - - New Stage - - - - - - - - - - - - -
132:                          Load system
133:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

135:   /*
136:      Open binary file.  Note that we use FILE_MODE_READ to indicate
137:      reading from this file.
138:   */
139:   PetscCall(PetscViewerBinaryOpen(PETSC_COMM_WORLD, file[PetscPreLoadIt], FILE_MODE_READ, &viewer));

141:   /*
142:      Load the matrix and vector; then destroy the viewer.
143:   */
144:   PetscCall(MatCreate(PETSC_COMM_WORLD, &A));
145:   PetscCall(MatSetFromOptions(A));
146:   PetscCall(MatLoad(A, viewer));
147:   flg = PETSC_FALSE;
148:   PetscCall(PetscOptionsGetBool(NULL, NULL, "-assemble_local", &flg, NULL));
149:   if (flg) PetscCall(MatISSetAllowRepeated(A, PETSC_FALSE));

151:   PetscCall(PetscOptionsGetString(NULL, NULL, "-mat_convert_type", mtype, sizeof(mtype), &flg));
152:   if (flg) PetscCall(MatConvert(A, mtype, MAT_INPLACE_MATRIX, &A));

154:   if (nearnulldim) {
155:     MatNullSpace nullsp;
156:     Vec         *nullvecs;
157:     PetscCall(PetscMalloc1(nearnulldim, &nullvecs));
158:     for (PetscInt i = 0; i < nearnulldim; i++) {
159:       PetscCall(VecCreate(PETSC_COMM_WORLD, &nullvecs[i]));
160:       PetscCall(VecLoad(nullvecs[i], viewer));
161:     }
162:     PetscCall(MatNullSpaceCreate(PETSC_COMM_WORLD, PETSC_FALSE, nearnulldim, nullvecs, &nullsp));
163:     PetscCall(MatSetNearNullSpace(A, nullsp));
164:     for (PetscInt i = 0; i < nearnulldim; i++) PetscCall(VecDestroy(&nullvecs[i]));
165:     PetscCall(PetscFree(nullvecs));
166:     PetscCall(MatNullSpaceDestroy(&nullsp));
167:   }
168:   if (constantnullspace) {
169:     MatNullSpace constant;
170:     PetscCall(MatNullSpaceCreate(PETSC_COMM_WORLD, PETSC_TRUE, 0, NULL, &constant));
171:     PetscCall(MatSetNullSpace(A, constant));
172:     PetscCall(MatNullSpaceDestroy(&constant));
173:   }
174:   flg = PETSC_FALSE;
175:   PetscCall(PetscOptionsGetString(NULL, NULL, "-rhs", file[2], sizeof(file[2]), &flg));
176:   PetscCall(VecCreate(PETSC_COMM_WORLD, &b));
177:   if (flg) { /* rhs is stored in a separate file */
178:     if (file[2][0] == '0' || file[2][0] == 0) {
179:       PetscInt    m;
180:       PetscScalar one = 1.0;
181:       PetscCall(PetscInfo(0, "Using vector of ones for RHS\n"));
182:       PetscCall(MatGetLocalSize(A, &m, NULL));
183:       PetscCall(VecSetSizes(b, m, PETSC_DECIDE));
184:       PetscCall(VecSetFromOptions(b));
185:       PetscCall(VecSet(b, one));
186:     } else {
187:       PetscCall(PetscViewerDestroy(&viewer));
188:       PetscCall(PetscViewerBinaryOpen(PETSC_COMM_WORLD, file[2], FILE_MODE_READ, &viewer));
189:       PetscCall(VecSetFromOptions(b));
190:       PetscCall(VecLoad(b, viewer));
191:     }
192:   } else { /* rhs is stored in the same file as matrix */
193:     PetscCall(VecSetFromOptions(b));
194:     PetscCall(VecLoad(b, viewer));
195:   }
196:   PetscCall(PetscViewerDestroy(&viewer));

198:   /* Make A singular for testing zero-pivot of ilu factorization */
199:   /* Example: ./ex72 -f0 <datafile> -test_zeropivot -pc_factor_shift_type <shift_type> */
200:   flg = PETSC_FALSE;
201:   PetscCall(PetscOptionsGetBool(NULL, NULL, "-test_zeropivot", &flg, NULL));
202:   if (flg) { /* set a row as zeros */
203:     PetscInt row = 0;
204:     PetscCall(MatSetOption(A, MAT_KEEP_NONZERO_PATTERN, PETSC_TRUE));
205:     PetscCall(MatZeroRows(A, 1, &row, 0.0, NULL, NULL));
206:   }

208:   /* Check whether A is symmetric, then set A->symmetric option */
209:   flg = PETSC_FALSE;
210:   PetscCall(PetscOptionsGetBool(NULL, NULL, "-check_symmetry", &flg, NULL));
211:   if (flg) {
212:     PetscCall(MatIsSymmetric(A, 0.0, &isSymmetric));
213:     if (!isSymmetric) PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Warning: A is non-symmetric \n"));
214:   }

216:   /*
217:      If the loaded matrix is larger than the vector (due to being padded
218:      to match the block size of the system), then create a new padded vector.
219:   */

221:   PetscCall(MatGetLocalSize(A, NULL, &n));
222:   PetscCall(MatGetSize(A, &M, NULL));
223:   PetscCall(VecGetSize(b, &m));
224:   PetscCall(VecGetLocalSize(b, &p));
225:   flg = (PetscBool)(M != m || p != n); /* Global or local dimension mismatch */
226:   PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, &flg, 1, MPI_C_BOOL, MPI_LOR, PetscObjectComm((PetscObject)A)));
227:   if (flg) { /* Create a new vector b by padding the old one */
228:     PetscInt     j, mvec, start, end, indx;
229:     Vec          tmp;
230:     PetscScalar *bold;

232:     PetscCall(VecCreate(PETSC_COMM_WORLD, &tmp));
233:     PetscCall(VecSetSizes(tmp, n, PETSC_DECIDE));
234:     PetscCall(VecSetFromOptions(tmp));
235:     PetscCall(VecGetOwnershipRange(b, &start, &end));
236:     PetscCall(VecGetLocalSize(b, &mvec));
237:     PetscCall(VecGetArray(b, &bold));
238:     for (j = 0; j < mvec; j++) {
239:       indx = start + j;
240:       PetscCall(VecSetValues(tmp, 1, &indx, bold + j, INSERT_VALUES));
241:     }
242:     PetscCall(VecRestoreArray(b, &bold));
243:     PetscCall(VecDestroy(&b));
244:     PetscCall(VecAssemblyBegin(tmp));
245:     PetscCall(VecAssemblyEnd(tmp));
246:     b = tmp;
247:   }

249:   PetscCall(MatCreateVecs(A, &x, NULL));
250:   PetscCall(VecDuplicate(b, &u));
251:   if (initialguessfile) {
252:     PetscCall(PetscViewerBinaryOpen(PETSC_COMM_WORLD, initialguessfilename, FILE_MODE_READ, &viewer));
253:     PetscCall(VecLoad(x, viewer));
254:     PetscCall(PetscViewerDestroy(&viewer));
255:     initialguess = PETSC_TRUE;
256:   } else if (initialguess) PetscCall(VecSet(x, 1.0));
257:   else PetscCall(VecSet(x, 0.0));

259:   /* Check scaling in A */
260:   flg = PETSC_FALSE;
261:   PetscCall(PetscOptionsGetBool(NULL, NULL, "-check_scaling", &flg, NULL));
262:   if (flg) {
263:     Vec       max, min, l1;
264:     PetscInt  idx;
265:     PetscReal val;

267:     PetscCall(VecDuplicate(x, &max));
268:     PetscCall(VecDuplicate(x, &min));
269:     PetscCall(VecDuplicate(x, &l1));
270:     PetscCall(MatGetRowMaxAbs(A, max, NULL));
271:     PetscCall(MatGetRowMinAbs(A, min, NULL));
272:     PetscCall(MatGetRowSumAbs(A, l1));
273:     if (PETSC_FALSE) {
274:       PetscCall(PetscViewerASCIIOpen(PETSC_COMM_WORLD, "max.data", &viewer));
275:       PetscCall(VecView(max, viewer));
276:       PetscCall(PetscViewerDestroy(&viewer));
277:       PetscCall(PetscViewerASCIIOpen(PETSC_COMM_WORLD, "min.data", &viewer));
278:       PetscCall(VecView(min, viewer));
279:       PetscCall(PetscViewerDestroy(&viewer));
280:       PetscCall(PetscViewerASCIIOpen(PETSC_COMM_WORLD, "l1.data", &viewer));
281:       PetscCall(VecView(l1, viewer));
282:       PetscCall(PetscViewerDestroy(&viewer));
283:     }
284:     PetscCall(VecView(max, PETSC_VIEWER_DRAW_WORLD));
285:     PetscCall(VecMax(max, &idx, &val));
286:     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Largest max row element %g at row %" PetscInt_FMT "\n", (double)val, idx));
287:     PetscCall(VecView(min, PETSC_VIEWER_DRAW_WORLD));
288:     PetscCall(VecMin(min, &idx, &val));
289:     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Smallest min row element %g at row %" PetscInt_FMT "\n", (double)val, idx));
290:     PetscCall(VecMin(max, &idx, &val));
291:     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Smallest max row element %g at row %" PetscInt_FMT "\n", (double)val, idx));
292:     PetscCall(VecPointwiseDivide(max, max, min));
293:     PetscCall(VecMax(max, &idx, &val));
294:     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Largest row ratio %g at row %" PetscInt_FMT "\n", (double)val, idx));
295:     PetscCall(VecView(max, PETSC_VIEWER_DRAW_WORLD));
296:     PetscCall(VecMax(max, &idx, &val));
297:     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Largest row ratio %g at row %" PetscInt_FMT "\n", (double)val, idx));
298:     PetscCall(VecView(max, PETSC_VIEWER_DRAW_WORLD));
299:     PetscCall(VecView(max, PETSC_VIEWER_DRAW_WORLD));
300:     PetscCall(VecMax(l1, &idx, &val));
301:     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Largest l1 row element %g at row %" PetscInt_FMT "\n", (double)val, idx));
302:     PetscCall(VecDestroy(&max));
303:     PetscCall(VecDestroy(&min));
304:     PetscCall(VecDestroy(&l1));
305:   }

307:   /*  PetscCall(MatView(A,PETSC_VIEWER_STDOUT_WORLD)); */
308:   /* - - - - - - - - - - - New Stage - - - - - - - - - - - - -
309:                     Setup solve for system
310:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
311:   /*
312:      Conclude profiling last stage; begin profiling next stage.
313:   */
314:   PetscPreLoadStage("KSPSetUpSolve");

316:   /*
317:      Create linear solver; set operators; set runtime options.
318:   */
319:   PetscCall(KSPCreate(PETSC_COMM_WORLD, &ksp));
320:   PetscCall(KSPSetInitialGuessNonzero(ksp, initialguess));
321:   num_numfac = 1;
322:   PetscCall(PetscOptionsGetInt(NULL, NULL, "-num_numfac", &num_numfac, NULL));
323:   while (num_numfac--) {
324:     PC        pc;
325:     PetscBool lsqr, isbddc, ismatis;
326:     char      str[32];

328:     PetscCall(PetscOptionsGetString(NULL, NULL, "-ksp_type", str, sizeof(str), &lsqr));
329:     if (lsqr) PetscCall(PetscStrcmp("lsqr", str, &lsqr));
330:     if (lsqr) {
331:       Mat BtB;
332:       PetscCall(MatTransposeMatMult(A, A, MAT_INITIAL_MATRIX, 4, &BtB));
333:       PetscCall(KSPSetOperators(ksp, A, BtB));
334:       PetscCall(MatDestroy(&BtB));
335:     } else PetscCall(KSPSetOperators(ksp, A, A));
336:     PetscCall(KSPSetFromOptions(ksp));

338:     /* if we test BDDC, make sure pmat is of type MATIS */
339:     PetscCall(KSPGetPC(ksp, &pc));
340:     PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCBDDC, &isbddc));
341:     PetscCall(PetscObjectTypeCompare((PetscObject)A, MATIS, &ismatis));
342:     if (isbddc && !ismatis) {
343:       Mat J;

345:       PetscCall(MatConvert(A, MATIS, MAT_INITIAL_MATRIX, &J));
346:       PetscCall(KSPSetOperators(ksp, A, J));
347:       PetscCall(MatDestroy(&J));
348:     }
349:     if (isbddc) {
350:       PetscInt nfields = 0;

352:       PetscCall(PetscOptionsGetInt(NULL, NULL, "-test_bddc_dofs_splitting", &nfields, NULL));
353:       if (nfields) {
354:         IS      *fields;
355:         PetscInt rstart, rend;

357:         PetscCall(PetscMalloc1(nfields, &fields));
358:         PetscCall(MatGetOwnershipRange(A, &rstart, &rend));
359:         for (PetscInt i = 0; i < nfields; i++) {
360:           PetscInt start = rstart + (i - rstart % nfields + nfields) % nfields;

362:           PetscCall(ISCreateStride(PetscObjectComm((PetscObject)A), (rend - start + nfields - 1) / nfields, start, nfields, &fields[i]));
363:         }
364:         PetscCall(PCBDDCSetDofsSplitting(pc, nfields, fields));
365:         for (PetscInt i = 0; i < nfields; i++) PetscCall(ISDestroy(&fields[i]));
366:         PetscCall(PetscFree(fields));
367:       }
368:     }

370:     /*
371:      Here we explicitly call KSPSetUp() and KSPSetUpOnBlocks() to
372:      enable more precise profiling of setting up the preconditioner.
373:      These calls are optional, since both will be called within
374:      KSPSolve() if they haven't been called already.
375:     */
376:     PetscCall(KSPSetUp(ksp));
377:     PetscCall(KSPSetUpOnBlocks(ksp));
378:     if (isbddc) {
379:       PetscBool test_save_load = PETSC_FALSE;

381:       PetscCall(PetscOptionsGetBool(NULL, NULL, "-test_bddc_save_load", &test_save_load, NULL));
382:       if (test_save_load) PetscCall(TestBDDCCustomization(pc, b));
383:     }

385:     /* - - - - - - - - - - - New Stage - - - - - - - - - - - - -
386:                          Solve system
387:       - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

389:     /*
390:      Solve linear system;
391:     */
392:     if (trans) {
393:       PetscCall(KSPSolveTranspose(ksp, b, x));
394:       PetscCall(KSPGetIterationNumber(ksp, &its));
395:     } else {
396:       PetscInt num_rhs = 1;
397:       PetscCall(PetscOptionsGetInt(NULL, NULL, "-num_rhs", &num_rhs, NULL));
398:       cknorm = PETSC_FALSE;
399:       PetscCall(PetscOptionsGetBool(NULL, NULL, "-cknorm", &cknorm, NULL));
400:       while (num_rhs--) {
401:         if (num_rhs == 1) PetscCall(VecSet(x, 0.0));
402:         PetscCall(KSPSolve(ksp, b, x));
403:       }
404:       PetscCall(KSPGetIterationNumber(ksp, &its));
405:       if (cknorm) { /* Check error for each rhs */
406:         if (trans) PetscCall(MatMultTranspose(A, x, u));
407:         else PetscCall(MatMult(A, x, u));
408:         PetscCall(VecAXPY(u, -1.0, b));
409:         PetscCall(VecNorm(u, NORM_2, &norm));
410:         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "  Number of iterations = %3" PetscInt_FMT "\n", its));
411:         if (!PetscIsNanScalar(norm)) PetscCall(PetscPrintf(PETSC_COMM_WORLD, "  Residual norm %g\n", (double)norm));
412:       }
413:     } /* while (num_rhs--) */

415:     /* - - - - - - - - - - - New Stage - - - - - - - - - - - - -
416:           Check error, print output, free data structures.
417:      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

419:     /*
420:        Check error
421:     */
422:     if (trans) PetscCall(MatMultTranspose(A, x, u));
423:     else PetscCall(MatMult(A, x, u));
424:     PetscCall(VecAXPY(u, -1.0, b));
425:     PetscCall(VecNorm(u, NORM_2, &norm));
426:     /*
427:      Write output (optionally using table for solver details).
428:       - PetscPrintf() handles output for multiprocessor jobs
429:         by printing from only one processor in the communicator.
430:       - KSPView() prints information about the linear solver.
431:     */
432:     if (table) {
433:       char *matrixname = NULL, kspinfo[120];

435:       /*
436:        Open a string viewer; then write info to it.
437:       */
438:       PetscCall(PetscViewerStringOpen(PETSC_COMM_WORLD, kspinfo, sizeof(kspinfo), &viewer));
439:       PetscCall(KSPView(ksp, viewer));
440:       PetscCall(PetscStrrchr(file[PetscPreLoadIt], '/', &matrixname));
441:       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%-8.8s %3" PetscInt_FMT " %2.0e %s \n", matrixname, its, (double)norm, kspinfo));

443:       /*
444:         Destroy the viewer
445:       */
446:       PetscCall(PetscViewerDestroy(&viewer));
447:     } else {
448:       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Number of iterations = %3" PetscInt_FMT "\n", its));
449:       if (!PetscIsNanReal(norm)) PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Residual norm %g\n", (double)norm));
450:     }
451:     PetscCall(PetscOptionsGetString(NULL, NULL, "-solution", file[3], sizeof(file[3]), &flg));
452:     if (flg) {
453:       Vec       xstar;
454:       PetscReal norm;

456:       PetscCall(PetscViewerBinaryOpen(PETSC_COMM_WORLD, file[3], FILE_MODE_READ, &viewer));
457:       PetscCall(VecCreate(PETSC_COMM_WORLD, &xstar));
458:       PetscCall(VecLoad(xstar, viewer));
459:       PetscCall(VecAXPY(xstar, -1.0, x));
460:       PetscCall(VecNorm(xstar, NORM_2, &norm));
461:       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error norm %g\n", (double)norm));
462:       PetscCall(VecDestroy(&xstar));
463:       PetscCall(PetscViewerDestroy(&viewer));
464:     }
465:     if (outputSoln) {
466:       PetscCall(PetscViewerBinaryOpen(PETSC_COMM_WORLD, "solution.petsc", FILE_MODE_WRITE, &viewer));
467:       PetscCall(VecView(x, viewer));
468:       PetscCall(PetscViewerDestroy(&viewer));
469:     }

471:     flg = PETSC_FALSE;
472:     PetscCall(PetscOptionsGetBool(NULL, NULL, "-ksp_reason", &flg, NULL));
473:     if (flg) {
474:       KSPConvergedReason reason;
475:       PetscCall(KSPGetConvergedReason(ksp, &reason));
476:       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "KSPConvergedReason: %s\n", KSPConvergedReasons[reason]));
477:     }

479:   } /* while (num_numfac--) */

481:   /*
482:      Free work space.  All PETSc objects should be destroyed when they
483:      are no longer needed.
484:   */
485:   PetscCall(MatDestroy(&A));
486:   PetscCall(VecDestroy(&b));
487:   PetscCall(VecDestroy(&u));
488:   PetscCall(VecDestroy(&x));
489:   PetscCall(KSPDestroy(&ksp));
490:   PetscPreLoadEnd();
491:   /* -----------------------------------------------------------
492:                       End of linear solver loop
493:      ----------------------------------------------------------- */

495:   PetscCall(PetscFinalize());
496:   return 0;
497: }

499: /*TEST

501:    build:
502:       requires: !complex

504:    testset:
505:       suffix: 1
506:       nsize: 2
507:       args: -f0 ${wPETSC_DIR}/share/petsc/datafiles/matrices/spd-real-int@PETSC_INDEX_SIZE@-float@PETSC_SCALAR_SIZE@
508:       requires: !__float128

510:    testset:
511:       suffix: 1a
512:       args: -f0 ${wPETSC_DIR}/share/petsc/datafiles/matrices/spd-real-int@PETSC_INDEX_SIZE@-float@PETSC_SCALAR_SIZE@
513:       requires: !__float128

515:    testset:
516:       nsize: 2
517:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
518:       args: -f0 ${DATAFILESPATH}/matrices/medium
519:       args: -ksp_type bicg
520:       test:
521:          suffix: 2

523:    testset:
524:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
525:       args: -f0 ${DATAFILESPATH}/matrices/medium
526:       args: -ksp_type bicg
527:       test:
528:          suffix: 4
529:          args: -pc_type lu
530:       test:
531:          suffix: 5

533:    testset:
534:       suffix: 6
535:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
536:       args: -f0 ${DATAFILESPATH}/matrices/fem1
537:       args: -pc_factor_levels 2 -pc_factor_fill 1.73 -ksp_orthogonalization_cgs_refinement_type refine_always

539:    testset:
540:       TODO: Matrix row/column sizes are not compatible with block size
541:       suffix: 7
542:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
543:       args: -f0 ${DATAFILESPATH}/matrices/medium
544:       args: -viewer_binary_skip_info -mat_type seqbaij
545:       args: -matload_block_size {{2 3 4 5 6 7 8}separate output}
546:       args: -ksp_max_it 100 -ksp_orthogonalization_cgs_refinement_type refine_always
547:       args: -ksp_rtol 1.0e-15 -ksp_monitor
548:       test:
549:          suffix: a
550:       test:
551:          suffix: b
552:          args: -pc_factor_mat_ordering_type nd
553:       test:
554:          suffix: c
555:          args: -pc_factor_levels 1
556:       test:
557:          requires: metis
558:          suffix: d
559:          args: -pc_factor_mat_ordering_type metisnd

561:    testset:
562:       TODO: Matrix row/column sizes are not compatible with block size
563:       suffix: 7_d
564:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
565:       args: -f0 ${DATAFILESPATH}/matrices/medium
566:       args: -viewer_binary_skip_info -mat_type seqbaij
567:       args: -matload_block_size {{2 3 4 5 6 7 8}shared output}
568:       args: -ksp_type preonly -pc_type lu

570:    testset:
571:       TODO: Matrix row/column sizes are not compatible with block size
572:       suffix: 9
573:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
574:       args: -f0 ${DATAFILESPATH}/matrices/medium
575:       args: -viewer_binary_skip_info -matload_block_size {{1 2 3 4 5 6 7}separate output} -ksp_max_it 100 -ksp_orthogonalization_cgs_refinement_type refine_always -ksp_rtol 1.0e-15 -ksp_monitor
576:       test:
577:          suffix: a
578:          args: -mat_type seqbaij
579:       test:
580:          suffix: b
581:          args: -mat_type seqbaij -trans
582:       test:
583:          suffix: c
584:          nsize: 2
585:          args: -mat_type mpibaij
586:       test:
587:          suffix: d
588:          nsize: 2
589:          args: -mat_type mpibaij -trans
590:       test:
591:          suffix: e
592:          nsize: 3
593:          args: -mat_type mpibaij
594:       test:
595:          suffix: f
596:          nsize: 3
597:          args: -mat_type mpibaij -trans

599:    testset:
600:       suffix: 10
601:       nsize: 2
602:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
603:       args: -ksp_type fgmres -pc_type ksp -f0 ${DATAFILESPATH}/matrices/medium -ksp_fgmres_modifypcksp -ksp_monitor

605:    testset:
606:       suffix: 12
607:       requires: datafilespath matlab
608:       args: -pc_type lu -pc_factor_mat_solver_type matlab -f0 ${DATAFILESPATH}/matrices/arco1

610:    testset:
611:       suffix: 13
612:       requires: datafilespath lusol
613:       args: -f0 ${DATAFILESPATH}/matrices/arco1
614:       args: -mat_type lusol -pc_type lu

616:    testset:
617:       nsize: 3
618:       args: -f0 ${DATAFILESPATH}/matrices/medium
619:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
620:       test:
621:          suffix: 14
622:          requires: spai
623:          args: -pc_type spai
624:       test:
625:          suffix: 15
626:          requires: hypre !defined(PETSC_HAVE_HYPRE_DEVICE)
627:          args: -pc_type hypre -pc_hypre_type pilut
628:       test:
629:          suffix: 16
630:          requires: hypre !defined(PETSC_HAVE_HYPRE_DEVICE)
631:          args: -pc_type hypre -pc_hypre_type parasails
632:       test:
633:          suffix: 17
634:          requires: hypre !defined(PETSC_HAVE_HYPRE_DEVICE)
635:          args: -pc_type hypre -pc_hypre_type boomeramg
636:       test:
637:          suffix: 18
638:          requires: hypre !defined(PETSC_HAVE_HYPRE_DEVICE)
639:          args: -pc_type hypre -pc_hypre_type euclid
640:       test:
641:          suffix: 20
642:          requires: hypre !defined(PETSC_HAVE_HYPRE_DEVICE)
643:          args: -pc_type hypre -pc_hypre_type ilu

645:    testset:
646:       suffix: 19
647:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
648:       args: -f0 ${DATAFILESPATH}/matrices/poisson1
649:       args: -ksp_type cg -pc_type icc
650:       args: -pc_factor_levels {{0 2 4}separate output}
651:       test:
652:       test:
653:          args: -mat_type seqsbaij

655:    testset:
656:       suffix: ILU
657:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
658:       args: -f0 ${DATAFILESPATH}/matrices/small
659:       args: -pc_factor_levels 1
660:       test:
661:       test:
662:          # This is tested against regular ILU (used to be denoted ILUBAIJ)
663:          args: -mat_type baij

665:    testset:
666:       suffix: aijcusparse
667:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) cuda
668:       args: -f0 ${DATAFILESPATH}/matrices/medium -ksp_monitor -ksp_view -mat_view ascii::ascii_info -mat_type aijcusparse -pc_factor_mat_solver_type cusparse -pc_type ilu -vec_type cuda

670:    testset:
671:       TODO: No output file. Need to determine if deprecated
672:       suffix: asm_viennacl
673:       nsize: 2
674:       requires: viennacl
675:       args: -pc_type asm -pc_asm_sub_mat_type aijviennacl -f0 ${wPETSC_DIR}/share/petsc/datafiles/matrices/spd-real-int${PETSC_INDEX_SIZE}-float${PETSC_SCALAR_SIZE}

677:    testset:
678:       nsize: 2
679:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) hypre !defined(PETSC_HAVE_HYPRE_DEVICE)
680:       args: -f0 ${DATAFILESPATH}/matrices/poisson2.gz -ksp_monitor -ksp_rtol 1.E-9 -pc_type hypre -pc_hypre_type boomeramg
681:       test:
682:          suffix: boomeramg_euclid
683:          args: -pc_hypre_boomeramg_smooth_type Euclid -pc_hypre_boomeramg_smooth_num_levels 2 -pc_hypre_boomeramg_eu_level 1 -pc_hypre_boomeramg_eu_droptolerance 0.01
684:       test:
685:          suffix: boomeramg_euclid_bj
686:          args: -pc_hypre_boomeramg_smooth_type Euclid -pc_hypre_boomeramg_smooth_num_levels 2 -pc_hypre_boomeramg_eu_level 1 -pc_hypre_boomeramg_eu_droptolerance 0.01 -pc_hypre_boomeramg_eu_bj
687:       test:
688:          suffix: boomeramg_parasails
689:          args: -pc_hypre_boomeramg_smooth_type ParaSails -pc_hypre_boomeramg_smooth_num_levels 2
690:       test:
691:          suffix: boomeramg_pilut
692:          args: -pc_hypre_boomeramg_smooth_type Pilut -pc_hypre_boomeramg_smooth_num_levels 2
693:       test:
694:          suffix: boomeramg_schwarz
695:          args: -pc_hypre_boomeramg_smooth_type Schwarz-smoothers

697:    testset:
698:       suffix: cg_singlereduction
699:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
700:       args: -f0 ${DATAFILESPATH}/matrices/small
701:       args: -mat_type mpisbaij -ksp_type cg -pc_type eisenstat -ksp_monitor -ksp_converged_reason
702:       test:
703:       test:
704:          args: -ksp_cg_single_reduction

706:    testset:
707:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
708:       args: -f0 ${DATAFILESPATH}/matrices/poisson2.gz
709:       args: -ksp_monitor -pc_type icc
710:       test:
711:          suffix: cr
712:          args: -ksp_type cr
713:       test:
714:          suffix: lcd
715:          args: -ksp_type lcd

717:    testset:
718:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
719:       args: -f0 ${DATAFILESPATH}/matrices/small
720:       args: -ksp_monitor -ksp_view -mat_view ascii::ascii_info
721:       test:
722:          suffix: seqaijcrl
723:          args: -mat_type seqaijcrl
724:       test:
725:          suffix: seqaijperm
726:          args: -mat_type seqaijperm

728:    testset:
729:       nsize: 2
730:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
731:       args: -f0 ${DATAFILESPATH}/matrices/small
732:       args: -ksp_monitor -ksp_view
733:       # Different output files
734:       test:
735:          suffix: mpiaijcrl
736:          args: -mat_type mpiaijcrl
737:       test:
738:          suffix: mpiaijperm
739:          args: -mat_type mpiaijperm

741:    testset:
742:       nsize: 4
743:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) !defined(PETSC_HAVE_I_MPI)
744:       args: -ksp_monitor -ksp_view
745:       test:
746:          suffix: xxt
747:          args: -f0 ${DATAFILESPATH}/matrices/poisson1 -check_symmetry -check_scaling -ksp_type cg -pc_type tfs
748:       test:
749:          suffix: xyt
750:          args: -f0 ${DATAFILESPATH}/matrices/medium -ksp_type gmres -pc_type tfs

752:    testset:
753:       # The output file here is the same as mumps
754:       suffix: mumps_cholesky
755:       output_file: output/ex72_mumps.out
756:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) mumps
757:       args: -f0 ${DATAFILESPATH}/matrices/small -ksp_type preonly -pc_type cholesky -pc_factor_mat_solver_type mumps -num_numfac 2 -num_rhs 2
758:       nsize: {{1 2}}
759:       test:
760:          args: -mat_type sbaij -mat_ignore_lower_triangular
761:       test:
762:          args: -mat_type aij
763:       test:
764:          args: -mat_type aij -matload_spd

766:    testset:
767:       # The output file here is the same as mumps
768:       suffix: mumps_lu
769:       output_file: output/ex72_mumps.out
770:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) mumps
771:       args: -f0 ${DATAFILESPATH}/matrices/small -ksp_type preonly -pc_type lu -pc_factor_mat_solver_type mumps -num_numfac 2 -num_rhs 2
772:       test:
773:          args: -mat_type seqaij
774:       test:
775:          nsize: 2
776:          args: -mat_type mpiaij
777:       test:
778:          args: -mat_type seqbaij -matload_block_size 2
779:       test:
780:          nsize: 2
781:          args: -mat_type mpibaij -matload_block_size 2
782:       test:
783:          args: -mat_type aij -mat_mumps_icntl_7 5
784:          TODO: Need to determine if deprecated

786:    test:
787:       suffix: mumps_lu_parmetis
788:       output_file: output/ex72_mumps.out
789:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) mumps parmetis
790:       nsize: 2
791:       args: -f0 ${DATAFILESPATH}/matrices/small -ksp_type preonly -pc_type lu -pc_factor_mat_solver_type mumps -num_numfac 2 -num_rhs 2 -mat_type mpiaij -mat_mumps_icntl_28 2 -mat_mumps_icntl_29 2

793:    test:
794:       suffix: mumps_lu_ptscotch
795:       output_file: output/ex72_mumps.out
796:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) mumps ptscotch
797:       nsize: 2
798:       args: -f0 ${DATAFILESPATH}/matrices/small -ksp_type preonly -pc_type lu -pc_factor_mat_solver_type mumps -num_numfac 2 -num_rhs 2 -mat_type mpiaij -mat_mumps_icntl_28 2 -mat_mumps_icntl_29 1

800:    testset:
801:       # The output file here is the same as mumps
802:       suffix: mumps_redundant
803:       output_file: output/ex72_mumps_redundant.out
804:       nsize: 8
805:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) mumps
806:       args: -f0 ${DATAFILESPATH}/matrices/medium -ksp_type preonly -pc_type redundant -pc_redundant_number {{8 7 6 5 4 3 2 1}} -redundant_pc_factor_mat_solver_type mumps -num_numfac 2 -num_rhs 2

808:    testset:
809:       suffix: pastix_cholesky
810:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) pastix
811:       output_file: output/ex72_mumps.out
812:       nsize: {{1 2}}
813:       args: -f0 ${DATAFILESPATH}/matrices/small -ksp_type preonly -pc_factor_mat_solver_type pastix -num_numfac 2 -num_rhs 2 -pc_type cholesky -mat_type sbaij -mat_ignore_lower_triangular -mat_pastix_thread_nbr 1

815:    testset:
816:       suffix: pastix_lu
817:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) pastix
818:       args: -f0 ${DATAFILESPATH}/matrices/small -ksp_type preonly -pc_type lu -pc_factor_mat_solver_type pastix -num_numfac 2 -num_rhs 2 -mat_pastix_thread_nbr 1
819:       output_file: output/ex72_mumps.out
820:       test:
821:          args: -mat_type seqaij
822:       test:
823:          nsize: 2
824:          args: -mat_type mpiaij

826:    testset:
827:       suffix: pastix_redundant
828:       output_file: output/ex72_mumps_redundant.out
829:       nsize: 8
830:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) pastix
831:       args: -f0 ${DATAFILESPATH}/matrices/medium -ksp_type preonly -pc_type redundant -pc_redundant_number {{8 7 6 5 4 3 2 1}} -redundant_pc_factor_mat_solver_type pastix -num_numfac 2 -num_rhs 2 -mat_pastix_thread_nbr 1

833:    testset:
834:       suffix: superlu_dist_lu
835:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) superlu_dist
836:       output_file: output/ex72_mumps.out
837:       args: -f0 ${DATAFILESPATH}/matrices/small -ksp_type preonly -pc_type lu -pc_factor_mat_solver_type superlu_dist -num_numfac 2 -num_rhs 2
838:       nsize: {{1 2}}

840:    testset:
841:       suffix: superlu_dist_redundant
842:       nsize: 8
843:       output_file: output/ex72_mumps_redundant.out
844:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) superlu_dist
845:       args: -f0 ${DATAFILESPATH}/matrices/medium -ksp_type preonly -pc_type redundant -pc_redundant_number {{8 7 6 5 4 3 2 1}} -redundant_pc_factor_mat_solver_type superlu_dist -num_numfac 2 -num_rhs 2

847:    testset:
848:       suffix: superlu_lu
849:       output_file: output/ex72_mumps.out
850:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) superlu
851:       args: -f0 ${DATAFILESPATH}/matrices/small -ksp_type preonly -pc_type lu -pc_factor_mat_solver_type superlu -num_numfac 2 -num_rhs 2

853:    testset:
854:       suffix: umfpack
855:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) suitesparse
856:       args: -f0 ${DATAFILESPATH}/matrices/small -ksp_type preonly -pc_type lu -mat_type seqaij -pc_factor_mat_solver_type umfpack -num_numfac 2 -num_rhs 2

858:    testset:
859:       suffix: zeropivot
860:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
861:       args: -f0 ${DATAFILESPATH}/matrices/small -test_zeropivot -ksp_converged_reason -ksp_type fgmres -pc_type ksp -fp_trap 0
862:       test:
863:          nsize: 3
864:          args: -ksp_pc_type bjacobi
865:       test:
866:          nsize: 2
867:          args: -ksp_ksp_type cg -ksp_pc_type bjacobi -ksp_pc_bjacobi_blocks 1
868:       #test:
869:          #nsize: 3
870:          #args: -ksp_ksp_converged_reason -ksp_pc_type bjacobi -ksp_sub_ksp_converged_reason
871:          #TODO: Need to determine if deprecated

873:    testset:
874:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
875:       args: -mat_convert_type is -f0 ${DATAFILESPATH}/matrices/medium -ksp_type fgmres
876:       test:
877:          suffix: aij_gdsw
878:          nsize: 4
879:          args: -mat_convert_type aij -pc_type mg -pc_mg_levels 2 -pc_mg_adapt_interp_coarse_space gdsw -pc_mg_galerkin -mg_levels_pc_type asm
880:       test:
881:          output_file: output/ex72_aij_gdsw.out
882:          suffix: is_gdsw
883:          nsize: 4
884:          args: -pc_type mg -pc_mg_levels 2 -pc_mg_adapt_interp_coarse_space gdsw -pc_mg_galerkin -mg_levels_pc_type asm
885:       test:
886:          suffix: is_asm
887:          nsize: {{1 2}separate output}
888:          args: -pc_type asm
889:       test:
890:          suffix: bddc_seq
891:          nsize: 1
892:          args: -pc_type bddc
893:       test:
894:          suffix: bddc_par
895:          nsize: 2
896:          args: -pc_type bddc
897:       test:
898:          requires: parmetis
899:          suffix: bddc_par_nd_parmetis
900:          filter: sed -e "s/Number of iterations =   [0-9]/Number of iterations = 9/g"
901:          nsize: 4
902:          args: -ksp_error_if_not_converged -pc_type bddc -mat_is_disassemble_l2g_type nd -mat_partitioning_type parmetis
903:       test:
904:          requires: ptscotch defined(PETSC_HAVE_SCOTCH_PARMETIS_V3_NODEND)
905:          suffix: bddc_par_nd_ptscotch
906:          filter: sed -e "s/Number of iterations =   [0-9]/Number of iterations = 9/g"
907:          nsize: 4
908:          args: -ksp_error_if_not_converged -pc_type bddc -mat_is_disassemble_l2g_type nd -mat_partitioning_type ptscotch

910:    testset:
911:       requires: !__float128 hpddm slepc defined(PETSC_HAVE_DYNAMIC_LIBRARIES) defined(PETSC_USE_SHARED_LIBRARIES)
912:       test:
913:          suffix: hpddm_mat
914:          output_file: output/ex72_bddc_seq.out
915:          filter: sed -e "s/Number of iterations =   2/Number of iterations =   1/g"
916:          nsize: 2
917:          args: -f0 ${wPETSC_DIR}/share/petsc/datafiles/matrices/spd-real-int@PETSC_INDEX_SIZE@-float@PETSC_SCALAR_SIZE@ -pc_type hpddm -pc_hpddm_define_subdomains -pc_hpddm_levels_1_sub_pc_type cholesky -pc_hpddm_levels_1_eps_nev 5 -pc_hpddm_levels_1_st_pc_type mat -mat_type {{aij sbaij}shared output}
918:       test:
919:          requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
920:          suffix: hpddm_gen_non_hermitian
921:          output_file: output/ex72_2.out
922:          nsize: 4
923:          args: -f0 ${DATAFILESPATH}/matrices/arco1 -pc_type hpddm -pc_hpddm_define_subdomains -pc_hpddm_levels_1_sub_pc_type lu -pc_hpddm_levels_1_eps_nev 10 -pc_hpddm_levels_1_st_share_sub_ksp -pc_hpddm_levels_1_eps_gen_non_hermitian -pc_hpddm_coarse_mat_type baij -pc_hpddm_block_splitting -pc_hpddm_levels_1_eps_threshold_absolute 0.7 -ksp_pc_side right
924:       test:
925:          requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) mumps !defined(PETSCTEST_VALGRIND)
926:          suffix: hpddm_gen_non_hermitian_baij
927:          output_file: output/ex72_10.out
928:          nsize: 4
929:          timeoutfactor: 2
930:          args: -f0 ${DATAFILESPATH}/matrices/arco6 -pc_type hpddm -pc_hpddm_define_subdomains -pc_hpddm_levels_1_sub_pc_type lu -pc_hpddm_levels_1_eps_nev 30 -pc_hpddm_levels_1_st_share_sub_ksp -pc_hpddm_levels_1_eps_gen_non_hermitian -pc_hpddm_coarse_mat_type baij -pc_hpddm_block_splitting -pc_hpddm_levels_1_eps_threshold_absolute 0.8 -ksp_pc_side right -mat_type baij -pc_hpddm_levels_1_sub_pc_factor_mat_solver_type mumps -pc_hpddm_levels_1_eps_tol 1.0e-2 -ksp_monitor
931:       test:
932:          requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
933:          suffix: hpddm_too_much_oversampling
934:          output_file: output/ex72_2.out
935:          nsize: 2
936:          filter: sed -e "s/Number of iterations =   3/Number of iterations =  10/g"
937:          args: -f0 ${DATAFILESPATH}/matrices/small -pc_type hpddm -pc_hpddm_levels_1_svd_nsv 1 -pc_hpddm_levels_1_st_share_sub_ksp -pc_hpddm_levels_1_sub_pc_type lu -pc_hpddm_harmonic_overlap 3 -pc_hpddm_coarse_mat_type aij

939:    # BDDC multiple subdomains per process tests
940:    test:
941:      requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
942:      suffix: matis_bddc_multisub_3d
943:      nsize: {{1 2 3 4 5 6 7 8}}
944:      args: -f ${DATAFILESPATH}/matrices/matis/poisson_DMDA_9x9x9_3x3x3.dat -pc_type bddc -ksp_type cg -ksp_norm_type natural -ksp_error_if_not_converged -mat_type is -pc_bddc_use_faces

946:    test:
947:      requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
948:      suffix: matis_bddc_multisub_2d
949:      nsize: {{1 2 3 4 5 6 7 8}}
950:      args: -f ${DATAFILESPATH}/matrices/matis/poisson_DMDA_9x9_3x3.dat -pc_type bddc -ksp_type cg -ksp_norm_type natural -ksp_error_if_not_converged -mat_type is

952:    test:
953:      requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
954:      suffix: matis_bddc_multisub_plex_2d
955:      nsize: {{1 2 3 4 5 6 7 8}}
956:      args: -f ${DATAFILESPATH}/matrices/matis/poisson_DMPLEX_32x32_16.dat -pc_type bddc -ksp_type cg -ksp_norm_type natural -ksp_error_if_not_converged -mat_type is

958:    test:
959:      requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
960:      suffix: matis_bddc_multisub_plex_3d
961:      nsize: {{1 2 3 4 5 6 7 8}}
962:      args: -f ${DATAFILESPATH}/matrices/matis/poisson_DMPLEX_16x16x16_16.dat -pc_type bddc -ksp_type cg -ksp_norm_type natural -ksp_error_if_not_converged -mat_type is

964:    test:
965:      requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
966:      suffix: matis_bddc_multisub_plex_3d_deluxe
967:      nsize: {{1 2 3 4 5 6 7 8}}
968:      args: -f ${DATAFILESPATH}/matrices/matis/poisson_DMPLEX_16x16x16_16.dat -pc_type bddc -ksp_type cg -ksp_norm_type natural -ksp_error_if_not_converged -mat_type is -pc_bddc_use_deluxe_scaling

970:    test:
971:      requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
972:      suffix: matis_bddc_multisub_hcurl_2d
973:      nsize: {{1 2 3 4 5 6 7 8}}
974:      args: -f ${DATAFILESPATH}/matrices/matis/hcurl_mfem_amrquad2_16.dat -pc_bddc_load_version 0 -pc_bddc_load ${DATAFILESPATH}/matrices/matis/bddc_hcurl_mfem_amrquad2_16.dat -pc_type bddc -ksp_type cg -ksp_norm_type natural -ksp_error_if_not_converged -mat_type is -pc_bddc_local_mat_graph_square 1

976:    test:
977:      requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
978:      suffix: matis_bddc_multisub_hcurl_2d_multilevel
979:      filter: sed -e "s/Number of iterations =  17/Number of iterations =  16/g"
980:      nsize: {{1 2 3 4 5 6 7 8}}
981:      args: -f ${DATAFILESPATH}/matrices/matis/hcurl_mfem_amrquad2_16.dat -pc_bddc_load_version 0 -pc_bddc_load ${DATAFILESPATH}/matrices/matis/bddc_hcurl_mfem_amrquad2_16.dat -pc_type bddc -ksp_type cg -ksp_norm_type natural -ksp_error_if_not_converged -mat_type is -pc_bddc_use_local_mat_graph 0 -pc_bddc_levels 2 -pc_bddc_coarsening_ratio 2 -pc_bddc_aggregator_petscpartitioner_type simple

983:    test:
984:      requires: datafilespath double mumps !defined(PETSC_USE_64BIT_INDICES)
985:      suffix: matis_bddc_multisub_hcurl_2d_adaptive
986:      nsize: {{1 2 3 4 5 6 7 8}}
987:      args: -f ${DATAFILESPATH}/matrices/matis/hcurl_mfem_amrquad2_16.dat -pc_bddc_load_version 0 -pc_bddc_load ${DATAFILESPATH}/matrices/matis/bddc_hcurl_mfem_amrquad2_16.dat -pc_type bddc -ksp_type cg -ksp_norm_type natural -ksp_error_if_not_converged -mat_type is -pc_bddc_local_mat_graph_square 1 -pc_bddc_use_deluxe_scaling -pc_bddc_adaptive_threshold 2 -pc_bddc_schur_exact {{0 1}}

989:    test:
990:      requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
991:      suffix: matis_bddc_multisub_hdiv_3d
992:      nsize: {{1 2 3 4 5 6 7 8}}
993:      args: -f ${DATAFILESPATH}/matrices/matis/hdiv_mfem_inlinehex2_16.dat -pc_bddc_load_version 0 -pc_bddc_load ${DATAFILESPATH}/matrices/matis/bddc_hdiv_mfem_inlinehex2_16.dat -pc_type bddc -ksp_type cg -ksp_norm_type natural -ksp_error_if_not_converged -mat_type is -pc_bddc_use_local_mat_graph 0

995:    test:
996:      requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
997:      suffix: matis_bddc_multisub_hcurl_3d
998:      nsize: {{1 3 4 8}}
999:      args: -f ${DATAFILESPATH}/matrices/matis/hcurl_mfem_inlinehex_16.dat -pc_bddc_load_version 0 -pc_bddc_load ${DATAFILESPATH}/matrices/matis/bddc_hcurl_mfem_inlinehex_16.dat -pc_type bddc -ksp_type cg -ksp_norm_type natural -ksp_error_if_not_converged -mat_type is -pc_bddc_local_mat_graph_square 1

1001:    test:
1002:      requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
1003:      suffix: matis_bddc_multisub_hcurl_3d_amr
1004:      nsize: {{1 3 4 8}}
1005:      args: -f ${DATAFILESPATH}/matrices/matis/hcurl_mfem_amrhex_16.dat -pc_bddc_load_version 0 -pc_bddc_load ${DATAFILESPATH}/matrices/matis/bddc_hcurl_mfem_amrhex_16.dat -pc_type bddc -ksp_type cg -ksp_norm_type natural -ksp_error_if_not_converged -mat_type is -pc_bddc_local_mat_graph_square 1

1007:    test:
1008:      requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
1009:      suffix: matis_bddc_multisub_hcurl_3d_fdm
1010:      nsize: {{1 3 4 8}}
1011:      args: -f ${DATAFILESPATH}/matrices/matis/fdm_hcurl_multi_deg3_4x4x4.dat -pc_bddc_load ${DATAFILESPATH}/matrices/matis/bddc_fdm_hcurl_multi_deg3_4x4x4.dat -pc_type bddc -ksp_type cg -ksp_norm_type natural -ksp_error_if_not_converged -mat_type is -pc_bddc_use_local_mat_graph 0

1013:    test:
1014:      requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
1015:      suffix: matis_bddc_multisub_hcurl_3d_fdm_multilevel
1016:      nsize: {{1 2 8}}
1017:      args: -f ${DATAFILESPATH}/matrices/matis/fdm_hcurl_multi_deg3_4x4x4.dat -pc_bddc_load ${DATAFILESPATH}/matrices/matis/bddc_fdm_hcurl_multi_deg3_4x4x4.dat -pc_type bddc -ksp_type cg -ksp_norm_type natural -ksp_error_if_not_converged -mat_type is -pc_bddc_use_local_mat_graph 0 -pc_bddc_levels 2 -pc_bddc_coarsening_ratio 8 -pc_bddc_aggregator_petscpartitioner_type simple -mat_is_load_variableblocksizes

1019:    test:
1020:      requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
1021:      suffix: matis_bddc_multisub_h1_3d_fdm
1022:      nsize: {{1 3}}
1023:      args: -f ${DATAFILESPATH}/matrices/matis/fdm_h1_multi_deg3_4x4x4.dat -pc_bddc_load ${DATAFILESPATH}/matrices/matis/bddc_fdm_h1_multi_deg3_4x4x4.dat -pc_type bddc -ksp_type cg -ksp_norm_type natural -ksp_error_if_not_converged -mat_type is -mat_is_load_variableblocksizes -pc_bddc_use_local_mat_graph 0 -pc_bddc_corner_selection

1025:    testset:
1026:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
1027:       nsize: {{1 3}}
1028:       args: -pc_type bddc -ksp_type cg -ksp_norm_type natural -ksp_error_if_not_converged -mat_type is -mat_is_load_variableblocksizes -pc_bddc_use_local_mat_graph 0 -test_bddc_save_load -pc_bddc_save bddc_setup.dat
1029:       temporaries: bddc_setup.dat bddc_setup.dat.info bddc_roundtrip.dat bddc_roundtrip.dat.info
1030:       test:
1031:          suffix: bddc_save_load_h1
1032:          output_file: output/ex72_matis_bddc_multisub_h1_3d_fdm.out
1033:          args: -f ${DATAFILESPATH}/matrices/matis/fdm_h1_multi_deg3_4x4x4.dat -pc_bddc_load ${DATAFILESPATH}/matrices/matis/bddc_fdm_h1_multi_deg3_4x4x4.dat -pc_bddc_corner_selection
1034:       test:
1035:          suffix: bddc_save_load_hcurl
1036:          output_file: output/ex72_matis_bddc_multisub_hcurl_3d_fdm_multilevel.out
1037:          args: -f ${DATAFILESPATH}/matrices/matis/fdm_hcurl_multi_deg3_4x4x4.dat -pc_bddc_load ${DATAFILESPATH}/matrices/matis/bddc_fdm_hcurl_multi_deg3_4x4x4.dat -pc_bddc_levels 2 -pc_bddc_coarsening_ratio 8 -pc_bddc_aggregator_petscpartitioner_type simple
1038:       test:
1039:          suffix: bddc_save_load_fields
1040:          args: -f ${DATAFILESPATH}/matrices/matis/fdm_h1_multi_deg3_4x4x4.dat -pc_bddc_load ${DATAFILESPATH}/matrices/matis/bddc_fdm_h1_multi_deg3_4x4x4.dat -pc_bddc_corner_selection -test_bddc_dofs_splitting 2

1042:    test:
1043:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
1044:       suffix: bddc_hcurl_restrict
1045:       nsize: 4
1046:       args: -f ${DATAFILESPATH}/matrices/matis/hcurl_mfem_inlinehex_16.dat -pc_bddc_load ${DATAFILESPATH}/matrices/matis/bddc_hcurl_mfem_inlinehex_16.dat -pc_bddc_load_version 0 -mat_type is -assemble_local -test_bddc_dofs_splitting 1 -pc_type bddc -ksp_type cg -ksp_norm_type natural -ksp_error_if_not_converged -pc_bddc_levels 1 -pc_bddc_coarsening_ratio 2 -pc_bddc_coarse_eqs_limit 0 -pc_bddc_aggregator_mat_partitioning_type average

1048: TEST*/