Actual source code: gvec2dView.c

  1: #ifdef PETSC_RCS_HEADER
  2: static char vcid[] = "$Id: gvec2dView.c,v 1.22 2000/10/08 00:27:05 knepley Exp $";
  3: #endif

  5: #include "src/gvec/gvecimpl.h"         /*I "gvec.h" I*/
  6: #include "gvec2dView.h"

  8: extern int ViewerSiloCheckMesh(PetscViewer, Mesh);

 10: int GVecView_Triangular_2D_Draw(GVec gvec, PetscViewer v)
 11: {

 15:   VecView(gvec, v);
 16:   PetscFunctionReturn(ierr);
 17: }

 19: #ifdef PETSC_HAVE_SILO
 20: #include "src/sys/src/viewer/impls/silo/vsilo.h"

 22: int GVecView_Triangular_2D_Silo(GVec gvec, PetscViewer viewer)
 23: {
 24:   Viewer_Silo     *vsilo = (Viewer_Silo *) viewer->data;
 25:   Grid             grid;
 26:   Mesh             mesh;
 27:   Mesh_Triangular *tri;
 28:   VarOrdering      order;
 29:   FieldClassMap    cm;
 30:   Vec              ghostVec;
 31:   VecScatter       ghostScatter;
 32:   ElementVec       elemVec;
 33:   PetscTruth       reduceSystem;
 34:   PetscTruth       reduceElement;
 35:   int              numElements, numCorners;
 36:   int             *elements;
 37:   char           **subNames;
 38:   float          **newArrays;
 39:   int            **localStart;
 40:   PetscScalar     *array;
 41:   DBfile          *fp;
 42:   DBoptlist       *optlist;
 43:   int             *classes;
 44:   int             *offsets;
 45:   char            *fieldName;
 46:   char             name[256];
 47:   char             buf[1024];
 48:   int              numFields, numNodes;
 49:   int             *elemStart;
 50:   int              size, elemSize, comp, len;
 51:   int              f, field, elem, func, node, c, index;
 52:   int              ierr;
 53: 

 56:   GVecGetGrid(gvec, &grid);
 57:   GVecGetOrder(gvec, &order);
 58:   VarOrderingGetClassMap(order, &cm);
 59:   VecGetSize(gvec, &size);
 60:   offsets    = order->offsets;
 61:   localStart = order->localStart;
 62:   numFields  = cm->numFields;
 63:   classes    = cm->classes;
 64:   ViewerSiloGetFilePointer(viewer, &fp);
 65:   GridGetMesh(grid, &mesh);
 66:   ViewerSiloCheckMesh(viewer, mesh);
 67:   MeshGetInfo(mesh, PETSC_NULL, &numNodes, PETSC_NULL, PETSC_NULL);

 69:   /* Construct names */
 70:   for(f = 0; f < numFields; f++) {
 71:     field = cm->fields[f];
 72:     GridGetFieldComponents(grid, field, &comp);
 73:     GridGetFieldName(grid, field, &fieldName);
 74:     /* GridGetFieldUnits(grid, field, &fieldUnits);                                                 */

 76:     if (vsilo->objName != PETSC_NULL) {
 77:       PetscStrncpy(name, vsilo->objName, 240);
 78:     } else {
 79:       PetscStrcpy(name, "");
 80:     }
 81:     if (fieldName == PETSC_NULL) {
 82:       sprintf(buf, "field%d", field);
 83:       PetscStrcat(name, buf);
 84:     } else {
 85:       PetscStrcat(name, fieldName);
 86:     }

 88:     PetscMalloc(comp * sizeof(char *),  &subNames);
 89:     PetscMalloc(comp * sizeof(float *), &newArrays);
 90:     PetscStrlen(name, &len);
 91:     len += (int) log10((double) comp) + 6;
 92:     for(c = 0; c < comp; c++) {
 93:       PetscMalloc(len      * sizeof(char),  &subNames[c]);
 94:       PetscMalloc(numNodes * sizeof(float), &newArrays[c]);
 95:       sprintf(subNames[c], "%scomp%d", name, c);
 96:     }

 98: #if 1
 99:     /* Setup reduction */
100:     (*grid->ops->gridsetupghostscatter)(grid, order, &ghostVec, &ghostScatter);
101:     /* Fill the local vector */
102:     GridGlobalToLocalGeneral(grid, gvec, ghostVec, INSERT_VALUES, ghostScatter);
103:     /* Setup element vector and matrix */
104:     elemSize  = grid->locOrder->elemSize;
105:     elemStart = grid->locOrder->elemStart;
106:     if (cm->isConstrained == PETSC_TRUE) {
107:       for(f = 0; f < numFields; f++) {
108:         if (grid->isFieldConstrained[cm->fields[f]])
109:           elemSize += grid->disc[cm->fields[f]]->funcs*grid->constraintCompDiff[cm->fields[f]];
110:       }
111:     }
112:     ElementVecCreate(gvec->comm, elemSize, &elemVec);
113:     array         = elemVec->array;
114:     reduceSystem  = grid->reduceSystem;
115:     reduceElement = grid->reduceElement;
116:     tri           = (Mesh_Triangular *) mesh->data;
117:     numElements   = tri->numFaces;
118:     numCorners    = tri->numCorners;
119:     elements      = tri->faces;
120:     for(elem = 0; elem < numElements; elem++) {
121:       /* Initialize element vector */
122:       ElementVecZero(elemVec);
123:       elemVec->reduceSize = grid->locOrder->elemSize;
124:       /* Setup local row indices */
125:       GridCalcGeneralElementVecIndices(grid, elem, order, PETSC_TRUE, elemVec);
126:       /* Setup local vectors */
127:       GridLocalToElementGeneral(grid, ghostVec, reduceSystem, reduceElement, elemVec);
128:       /* Must transform to unconstrained variables */
129:       GridProjectElementVec(grid, mesh, elem, order, PETSC_FALSE, elemVec);
130:       /* Put values into new arrays */
131:       index = elemStart[field];
132:       for(func = 0; func < grid->disc[field]->funcs; func++) {
133:         node = elements[elem*numCorners+func];
134:         for(c = 0; c < comp; c++, index++) {
135: #ifdef PETSC_USE_BOPT_g
136:           if ((index < 0) || (index >= elemSize)) {
137:             SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE, "Bad index %d should be in [0,%d)", index, elemSize);
138:           }
139: #endif
140:           newArrays[c][node] = array[index];
141:         }
142:       }
143:     }
144:     /* Cleanup */
145:     ElementVecDestroy(elemVec);
146:     VecDestroy(ghostVec);
147:     VecScatterDestroy(ghostScatter);
148: #else
149:     VecGetArray(gvec, &array);
150:     for(node = 0; node < numNodes; node++) {
151:       nclass = classes[node];
152:       if (localStart[field] == PETSC_NULL) {
153:         continue;
154:       } else if (localStart[field][nclass] == -1) {
155:         for(c = 0; c < comp; c++) {
156:           newArrays[c][node] = 0.0;
157:         }
158:       } else {
159:         for(c = 0; c < comp; c++) {
160:           index = offsets[node]+localStart[field][nclass]+c;
161: #ifdef PETSC_USE_BOPT_g
162:           if ((index < 0) || (index >= size)) {
163:             SETERRQ4(PETSC_ERR_ARG_OUTOFRANGE, "Bad index %d+%d= %d should be in [0,%d)",
164:                      offsets[node], localStart[field][nclass]+c, index, size);
165:           }
166: #endif
167:           newArrays[c][node] = array[offsets[node]+localStart[field][nclass]+c];
168:         }
169:       }
170:     }
171:     VecRestoreArray(gvec, &array);
172: #endif

174:     /* Put the vector into the archive */
175:     for(c = 0; c < comp; c++) {
176:       optlist = DBMakeOptlist(3);
177:       DBAddOption(optlist, DBOPT_LABEL, name);
178:       /* DBAddOption(optlist, DBOPT_UNITS, fieldUnits);                                            */
179:       DBAddOption(optlist, DBOPT_UNITS, "units");
180:       if (vsilo->meshName == PETSC_NULL) {
181:         DBPutUcdvar1(fp, subNames[c], "PetscMesh",     newArrays[c], numNodes, PETSC_NULL, 0, DB_FLOAT, DB_NODECENT, optlist);
182: 
183:       } else {
184:         DBPutUcdvar1(fp, subNames[c], vsilo->meshName, newArrays[c], numNodes, PETSC_NULL, 0, DB_FLOAT, DB_NODECENT, optlist);
185: 
186:       }
187:       DBFreeOptlist(optlist);

189:     }

191:     /* Define a vecor variable for multicomponent fields */
192:     if(comp > 1) {
193:       PetscMemzero(buf, 1024 * sizeof(char));
194:       len  = DBGetVarLength(fp, "_meshtv_defvars");
195:       if (len > 0) {
196:         if (DBGetVarType(fp, "_meshtv_defvars") != DB_CHAR) {
197:           SETERRQ(PETSC_ERR_FILE_READ, "Invalid type for variable _meshtv_defvars");
198:         }
199:         if (len > 1024) SETERRQ(PETSC_ERR_SUP, "Need to do dyanmic allocation here");
200:         DBReadVar(fp, "_meshtv_defvars", buf);
201:         PetscStrcat(buf, ";vec");
202:       } else {
203:         PetscStrcpy(buf, "vec");
204:       }
205:       PetscStrcat(buf, name);
206:       PetscStrcat(buf, " vector {");
207:       for(c = 0; c < comp-1; c++) {
208:         PetscStrcat(buf, subNames[c]);
209:         PetscStrcat(buf, ",");
210:       }
211:       PetscStrcat(buf, subNames[c]);
212:       PetscStrcat(buf, "}");
213:       PetscStrlen(buf, &len);
214:       if (len > 1024) SETERRQ(PETSC_ERR_SUP, "Need to do dyanmic allocation here");
215:       len  = 1024;
216:       DBWrite(fp, "_meshtv_defvars", buf, &len, 1, DB_CHAR);
217:     }

219:     /* Cleanup */
220:     for(c = 0; c < comp; c++) {
221:       PetscFree(newArrays[c]);
222:     }
223:     PetscFree(newArrays);
224:   }
225:   return(0);
226: }
227: #endif

229: static int GVecCreateElementVec_Private(GVec gvec, LocalVarOrdering locOrder, ElementVec *elemVec) {
230:   MPI_Comm         comm;
231:   Grid             grid;
232:   VarOrdering      order;
233:   FieldClassMap    cm;
234:   Discretization   disc;
235:   PetscTruth       isConstrained, isFieldConstrained;
236:   int              numFields, numFuncs, elemSize;
237:   int              f, field;
238:   int              ierr;

241:   PetscObjectGetComm((PetscObject) gvec, &comm);
242:   GVecGetGrid(gvec, &grid);
243:   GVecGetOrder(gvec, &order);
244:   VarOrderingGetClassMap(order, &cm);

246:   LocalVarOrderingGetSize(locOrder, &elemSize);
247:   FieldClassMapIsConstrained(cm, &isConstrained);
248:   FieldClassMapGetNumFields(cm, &numFields);
249:   if (isConstrained == PETSC_TRUE) {
250:     for(f = 0; f < numFields; f++) {
251:       FieldClassMapGetField(cm, f, &field);
252:       GridIsFieldConstrained(grid, field, &isFieldConstrained);
253:       if (isFieldConstrained == PETSC_TRUE) {
254:         GridGetDiscretization(grid, field, &disc);
255:         DiscretizationGetNumFunctions(disc, &numFuncs);
256:         elemSize += numFuncs*grid->fields[field].constraintCompDiff;
257:       }
258:     }
259:   }
260:   ElementVecCreate(comm, elemSize, elemVec);
261:   return(0);
262: }

264: static int MeshGetNumLocalVertices_Private(Mesh mesh, int *numLocalVertices) {
265:   Partition   part;
266:   PetscTruth *seen;
267:   int         numOverlapElements, numCorners, numLocalNodes;
268:   int         elem, corner, node;
269:   int         ierr;

272:   *numLocalVertices = 0;
273:   MeshGetPartition(mesh, &part);
274:   MeshGetNumCorners(mesh, &numCorners);
275:   PartitionGetNumOverlapElements(part, &numOverlapElements);
276:   PartitionGetNumNodes(part, &numLocalNodes);
277:   if (numCorners == 3) {
278:     *numLocalVertices = numLocalNodes;
279:     return(0);
280:   }
281:   PetscMalloc(numLocalNodes * sizeof(PetscTruth), &seen);
282:   PetscMemzero(seen, numLocalNodes * sizeof(PetscTruth));
283:   for(elem = 0; elem < numOverlapElements; elem++) {
284:     for(corner = 0; corner < 3; corner++) {
285:       MeshGetNodeFromElement(mesh, elem, corner, &node);
286:       if ((node < numLocalNodes) && (seen[node] == PETSC_FALSE)) {
287:         seen[node] = PETSC_TRUE;
288:         *numLocalVertices += 1;
289:       }
290:     }
291:   }
292:   PetscFree(seen);
293:   return(0);
294: }

296: static int MeshGetNumVertices_Private(Mesh mesh, int *numVertices) {

300:   MeshGetInfo(mesh, numVertices, 0, 0, 0);
301:   return(0);
302: }

304: static int GVecCanonicalizeField_Private(GVec gvec, int canonicalField, LocalVarOrdering locOrder, Vec *canonicalVec) {
305:   MPI_Comm         comm;
306:   Grid             grid;
307:   Mesh             mesh;
308:   Partition        part;
309:   VarOrdering      order, reductionOrder;
310:   AO               meshOrdering, partOrdering;
311:   Discretization   disc;
312:   Vec              ghostVec, reductionVec;
313:   VecScatter       ghostScatter;
314:   ElementVec       elemVec;
315:   PetscTruth       reduceSystem;
316:   PetscScalar      reduceAlpha;
317:   PetscScalar      minusOne = -1.0;
318:   int             *nodes, *indices;
319:   PetscScalar     *array;
320:   int              numLocNodes, numNodes, fieldStart, numComp, numLocElements, numCorners, numFuncs, elemSize;
321:   int              elem, func, node, c;
322:   int              ierr;

326:   PetscObjectGetComm((PetscObject) gvec, &comm);
327:   GVecGetGrid(gvec, &grid);
328:   GVecGetOrder(gvec, &order);
329:   PetscObjectQuery((PetscObject) gvec, "reductionOrder", (PetscObject *) &reductionOrder);
330:   PetscObjectQuery((PetscObject) gvec, "reductionVec",   (PetscObject *) &reductionVec);
331:   GridGetMesh(grid, &mesh);
332:   MeshGetPartition(mesh, &part);
333:   if (reductionVec == PETSC_NULL) reductionVec = grid->bdReduceVecCur;
334:   /* Create canonical vector */
335:   MeshGetNumCorners(mesh, &numCorners);
336:   GridGetDiscretization(grid, canonicalField, &disc);
337:   DiscretizationGetNumFunctions(disc, &numFuncs);
338:   GridGetFieldComponents(grid, canonicalField, &numComp);
339:   if (numFuncs < numCorners) {
340:     MeshGetNumLocalVertices_Private(mesh, &numLocNodes);
341:     MeshGetNumVertices_Private(mesh, &numNodes);
342:   } else {
343:     PartitionGetNumNodes(part, &numLocNodes);
344:     PartitionGetTotalNodes(part, &numNodes);
345:   }
346:   VecCreate(comm, canonicalVec);
347:   VecSetSizes(*canonicalVec, numLocNodes*numComp, numNodes*numComp);
348:   VecSetType(*canonicalVec, VECMPI);
349:   /* Setup reduction */
350:   (*grid->ops->gridsetupghostscatter)(grid, order, &ghostVec, &ghostScatter);
351:   /* Fill the local vector */
352:   GridGlobalToLocalGeneral(grid, gvec, ghostVec, INSERT_VALUES, ghostScatter);
353:   /* Setup element vector */
354:   GVecCreateElementVec_Private(gvec, locOrder, &elemVec);
355:   LocalVarOrderingGetFieldStart(locOrder, canonicalField, &fieldStart);
356:   array = &elemVec->array[fieldStart];

358:   GridGetReduceSystem(grid, &reduceSystem);
359:   GridGetBCMultiplier(grid, &reduceAlpha);
360:   GridSetBCMultiplier(grid, minusOne);
361:   MeshGetNodeOrdering(mesh, &meshOrdering);
362:   PartitionGetNodeOrdering(part, &partOrdering);
363:   LocalVarOrderingGetSize(locOrder, &elemSize);
364:   PetscMalloc(numFuncs         * sizeof(int), &nodes);
365:   PetscMalloc(numFuncs*numComp * sizeof(int), &indices);
366:   PartitionGetNumElements(part, &numLocElements);
367:   for(elem = 0; elem < numLocElements; elem++) {
368:     /* Initialize element vector */
369:     ElementVecZero(elemVec);
370:     elemVec->reduceSize = elemSize;
371:     /* Setup local row indices */
372:     GridCalcGeneralElementVecIndices(grid, elem, order, reductionOrder, PETSC_TRUE, elemVec);
373:     /* Setup local vectors */
374:     GridLocalToElementGeneral(grid, ghostVec, reductionVec, reduceSystem, PETSC_TRUE, elemVec);
375:     /* Must transform to unconstrained variables */
376:     GridProjectElementVec(grid, mesh, elem, order, PETSC_FALSE, elemVec);
377:     /* Put values into canonical vector */
378:     for(func = 0; func < numFuncs; func++) {
379:       MeshGetNodeFromElement(mesh, elem, func, &node);
380:       PartitionLocalToGlobalNodeIndex(part, node, &nodes[func]);
381:     }
382:     /* We must globally renumber so that midnodes come after vertices */
383:     if (partOrdering != PETSC_NULL) {
384:       AOPetscToApplication(partOrdering, numFuncs, nodes);
385:     }
386:     if (meshOrdering != PETSC_NULL) {
387:       AOPetscToApplication(meshOrdering, numFuncs, nodes);
388:     }
389:     for(func = 0; func < numFuncs; func++) {
390:       for(c = 0; c < numComp; c++) {
391:         indices[func*numComp+c] = nodes[func]*numComp+c;
392:       }
393:     }
394:     VecSetValues(*canonicalVec, numFuncs*numComp, indices, array, INSERT_VALUES);
395:     /* Usually reset by ElementVecSetValues() */
396:     elemVec->reduceSize = elemVec->size;
397:   }
398:   VecAssemblyBegin(*canonicalVec);
399:   VecAssemblyEnd(*canonicalVec);
400:   GridSetBCMultiplier(grid, reduceAlpha);
401:   /* Cleanup */
402:   PetscFree(nodes);
403:   PetscFree(indices);
404:   ElementVecDestroy(elemVec);
405:   VecDestroy(ghostVec);
406:   VecScatterDestroy(ghostScatter);
407:   return(0);
408: }

410: int GVecView_Triangular_2D_VU(GVec gvec, PetscViewer viewer) {
411:   MPI_Comm         comm;
412:   Grid             grid;
413:   Mesh             mesh;
414:   Partition        part;
415:   VarOrdering      order;
416:   LocalVarOrdering locOrder;
417:   FieldClassMap    cm;
418:   Discretization   disc;
419:   Vec              locCanonicalVec, canonicalVec;
420:   PetscTruth       vecSeen;
421:   FILE            *fp;
422:   PetscScalar     *values;
423:   char            *fieldName;
424:   int             *fields;
425:   int              rank, numFields, numComp, numFuncs, numNodes;
426:   int              f, field, node, c;
427:   int              ierr;

430:   PetscObjectGetComm((PetscObject) gvec, &comm);
431:   MPI_Comm_rank(comm, &rank);
432:   GVecGetGrid(gvec, &grid);
433:   GVecGetOrder(gvec, &order);
434:   GridGetMesh(grid, &mesh);
435:   MeshGetPartition(mesh, &part);
436:   VarOrderingGetClassMap(order, &cm);
437:   FieldClassMapGetNumFields(cm, &numFields);
438:   PetscViewerVUGetPointer(viewer, &fp);
439:   /* Create local ordering */
440:   PetscMalloc(numFields * sizeof(int), &fields);
441:   for(f = 0; f < numFields; f++) {
442:     FieldClassMapGetField(cm, f, &fields[f]);
443:   }
444:   LocalVarOrderingCreate(grid, numFields, fields, &locOrder);
445:   PetscFree(fields);
446:   /* Write each field */
447:   PetscFPrintf(comm, fp, "// Field valuesn");
448:   for(f = 0; f < numFields; f++) {
449:     FieldClassMapGetField(cm, f, &field);
450:     GridGetFieldComponents(grid, field, &numComp);
451:     GridGetFieldName(grid, field, &fieldName);
452:     if (fieldName == PETSC_NULL) SETERRQ(PETSC_ERR_ARG_WRONG, "You must name the fields for VU");
453:     GridGetDiscretization(grid, field, &disc);
454:     DiscretizationGetNumFunctions(disc, &numFuncs);
455:     GVecCanonicalizeField_Private(gvec, field, locOrder, &canonicalVec);
456:     VecConvertMPIToMPIZero(canonicalVec, &locCanonicalVec);
457:     VecGetSize(locCanonicalVec, &numNodes);
458:     VecGetArray(locCanonicalVec, &values);
459:     if (rank == 0) {
460:       if (numNodes%numComp) SETERRQ(PETSC_ERR_ARG_CORRUPT, "Invalid size for canonical field vector");
461:       numNodes /= numComp;
462:       for(c = 0; c < numComp; c++) {
463:         PetscFPrintf(comm, fp, "FIELD %s%d( ) = {n", fieldName, c);
464:         for(node = 0; node < numNodes; node++) {
465:           PetscFPrintf(comm, fp, "%gn", PetscRealPart(values[node*numComp+c]));
466:         }
467:         PetscFPrintf(comm, fp, "};nn");
468:       }
469:     }
470:     VecRestoreArray(locCanonicalVec, &values);
471:     VecDestroy(locCanonicalVec);
472:     VecDestroy(canonicalVec);
473:     PetscFree(fieldName);
474:   }
475:   LocalVarOrderingDestroy(locOrder);
476:   /* Write solution as field union */
477:   PetscViewerVUGetVecSeen(viewer, &vecSeen);
478:   if (vecSeen == PETSC_FALSE) {
479:     PetscViewerVUPrintDeferred(viewer, "// The full solutionnSOLUTION VecSolution( ) =n{n");
480:     PetscViewerVUSetVecSeen(viewer, PETSC_TRUE);
481:   }
482:   for(f = 0; f < numFields; f++) {
483:     FieldClassMapGetField(cm, f, &field);
484:     GridGetFieldName(grid, field, &fieldName);
485:     GridGetFieldComponents(grid, field, &numComp);
486:     GridGetDiscretization(grid, field, &disc);
487:     DiscretizationGetNumFunctions(disc, &numFuncs);
488:     for(c = 0; c < numComp; c++) {
489:       switch(numFuncs) {
490:       case 3:
491:         PetscViewerVUPrintDeferred(viewer, "  VARIABLE %s%d(LagrTrian03, %s%d, Connectivity, Zone1);n", fieldName, c, fieldName, c);
492:         break;
493:       case 6:
494:         PetscViewerVUPrintDeferred(viewer, "  VARIABLE %s%d(LagrTrian06, %s%d, FullConnectivity, Zone1);n", fieldName, c, fieldName, c);
495:         break;
496:       default:
497:         SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid number of function in discretization %d", numFuncs);
498:       }
499:     }
500:     PetscFree(fieldName);
501:   }
502:   return(0);
503: }

505: int GVecView_Triangular_2D(GVec gvec, PetscViewer viewer)
506: {
507:   Grid       grid;
508:   PetscTruth isascii, isdraw, isvu, ismathematica, issilo;
509:   int        ierr;

512:   PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_ASCII,       &isascii);
513:   PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_DRAW,        &isdraw);
514:   PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_VU,          &isvu);
515:   PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_MATHEMATICA, &ismathematica);
516:   PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_SILO,        &issilo);
517:   if (isascii == PETSC_TRUE) {
518:     GVecGetGrid(gvec, &grid);
519:     GridView(grid, viewer);
520:     PetscViewerFlush(viewer);
521:     VecView(gvec, viewer);
522:   } else if (isdraw == PETSC_TRUE) {
523:     GVecView_Triangular_2D_Draw(gvec, viewer);
524:   } else if (isvu == PETSC_TRUE) {
525:     GVecView_Triangular_2D_VU(gvec, viewer);
526: #ifdef PETSC_HAVE_MATHEMATICA
527:   } else if (ismathematica == PETSC_TRUE) {
528:     ViewerMathematica_GVec_Triangular_2D(viewer, gvec);
529: #endif
530: #ifdef PETSC_HAVE_MATHEMATICA
531:   } else if (issilo == PETSC_TRUE) {
532:     GVecView_Triangular_2D_Silo(gvec, viewer);
533: #endif
534:   }

536:   return(0);
537: }