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: #undef __FUNCT__
12: int GVecView_Triangular_2D_Draw(GVec gvec, PetscViewer v)
13: {
17: VecView(gvec, v);
18: PetscFunctionReturn(ierr);
19: }
21: #ifdef PETSC_HAVE_SILO
22: #include "src/sys/src/viewer/impls/silo/vsilo.h"
24: #undef __FUNCT__
26: int GVecView_Triangular_2D_Silo(GVec gvec, PetscViewer viewer)
27: {
28: Viewer_Silo *vsilo = (Viewer_Silo *) viewer->data;
29: Grid grid;
30: Mesh mesh;
31: Mesh_Triangular *tri;
32: VarOrdering order;
33: FieldClassMap cm;
34: Vec ghostVec;
35: VecScatter ghostScatter;
36: ElementVec elemVec;
37: PetscTruth reduceSystem;
38: PetscTruth reduceElement;
39: int numElements, numCorners;
40: int *elements;
41: char **subNames;
42: float **newArrays;
43: int **localStart;
44: PetscScalar *array;
45: DBfile *fp;
46: DBoptlist *optlist;
47: int *classes;
48: int *offsets;
49: char *fieldName;
50: char name[256];
51: char buf[1024];
52: int numFields, numNodes;
53: int *elemStart;
54: int size, elemSize, comp, len;
55: int f, field, elem, func, node, c, index;
56: int ierr;
57:
60: GVecGetGrid(gvec, &grid);
61: GVecGetOrder(gvec, &order);
62: VarOrderingGetClassMap(order, &cm);
63: VecGetSize(gvec, &size);
64: offsets = order->offsets;
65: localStart = order->localStart;
66: numFields = cm->numFields;
67: classes = cm->classes;
68: ViewerSiloGetFilePointer(viewer, &fp);
69: GridGetMesh(grid, &mesh);
70: ViewerSiloCheckMesh(viewer, mesh);
71: MeshGetInfo(mesh, PETSC_NULL, &numNodes, PETSC_NULL, PETSC_NULL);
73: /* Construct names */
74: for(f = 0; f < numFields; f++) {
75: field = cm->fields[f];
76: GridGetFieldComponents(grid, field, &comp);
77: GridGetFieldName(grid, field, &fieldName);
78: /* GridGetFieldUnits(grid, field, &fieldUnits); */
80: if (vsilo->objName != PETSC_NULL) {
81: PetscStrncpy(name, vsilo->objName, 240);
82: } else {
83: PetscStrcpy(name, "");
84: }
85: if (fieldName == PETSC_NULL) {
86: sprintf(buf, "field%d", field);
87: PetscStrcat(name, buf);
88: } else {
89: PetscStrcat(name, fieldName);
90: }
92: PetscMalloc(comp * sizeof(char *), &subNames);
93: PetscMalloc(comp * sizeof(float *), &newArrays);
94: PetscStrlen(name, &len);
95: len += (int) log10((double) comp) + 6;
96: for(c = 0; c < comp; c++) {
97: PetscMalloc(len * sizeof(char), &subNames[c]);
98: PetscMalloc(numNodes * sizeof(float), &newArrays[c]);
99: sprintf(subNames[c], "%scomp%d", name, c);
100: }
102: #if 1
103: /* Setup reduction */
104: (*grid->ops->gridsetupghostscatter)(grid, order, &ghostVec, &ghostScatter);
105: /* Fill the local vector */
106: GridGlobalToLocalGeneral(grid, gvec, ghostVec, INSERT_VALUES, ghostScatter);
107: /* Setup element vector and matrix */
108: elemSize = grid->locOrder->elemSize;
109: elemStart = grid->locOrder->elemStart;
110: if (cm->isConstrained == PETSC_TRUE) {
111: for(f = 0; f < numFields; f++) {
112: if (grid->isFieldConstrained[cm->fields[f]])
113: elemSize += grid->disc[cm->fields[f]]->funcs*grid->constraintCompDiff[cm->fields[f]];
114: }
115: }
116: ElementVecCreate(gvec->comm, elemSize, &elemVec);
117: array = elemVec->array;
118: reduceSystem = grid->reduceSystem;
119: reduceElement = grid->reduceElement;
120: tri = (Mesh_Triangular *) mesh->data;
121: numElements = tri->numFaces;
122: numCorners = tri->numCorners;
123: elements = tri->faces;
124: for(elem = 0; elem < numElements; elem++) {
125: /* Initialize element vector */
126: ElementVecZero(elemVec);
127: elemVec->reduceSize = grid->locOrder->elemSize;
128: /* Setup local row indices */
129: GridCalcGeneralElementVecIndices(grid, elem, order, PETSC_TRUE, elemVec);
130: /* Setup local vectors */
131: GridLocalToElementGeneral(grid, ghostVec, reduceSystem, reduceElement, elemVec);
132: /* Must transform to unconstrained variables */
133: GridProjectElementVec(grid, mesh, elem, order, PETSC_FALSE, elemVec);
134: /* Put values into new arrays */
135: index = elemStart[field];
136: for(func = 0; func < grid->disc[field]->funcs; func++) {
137: node = elements[elem*numCorners+func];
138: for(c = 0; c < comp; c++, index++) {
139: #ifdef PETSC_USE_BOPT_g
140: if ((index < 0) || (index >= elemSize)) {
141: SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE, "Bad index %d should be in [0,%d)", index, elemSize);
142: }
143: #endif
144: newArrays[c][node] = array[index];
145: }
146: }
147: }
148: /* Cleanup */
149: ElementVecDestroy(elemVec);
150: VecDestroy(ghostVec);
151: VecScatterDestroy(ghostScatter);
152: #else
153: VecGetArray(gvec, &array);
154: for(node = 0; node < numNodes; node++) {
155: nclass = classes[node];
156: if (localStart[field] == PETSC_NULL) {
157: continue;
158: } else if (localStart[field][nclass] == -1) {
159: for(c = 0; c < comp; c++) {
160: newArrays[c][node] = 0.0;
161: }
162: } else {
163: for(c = 0; c < comp; c++) {
164: index = offsets[node]+localStart[field][nclass]+c;
165: #ifdef PETSC_USE_BOPT_g
166: if ((index < 0) || (index >= size)) {
167: SETERRQ4(PETSC_ERR_ARG_OUTOFRANGE, "Bad index %d+%d= %d should be in [0,%d)",
168: offsets[node], localStart[field][nclass]+c, index, size);
169: }
170: #endif
171: newArrays[c][node] = array[offsets[node]+localStart[field][nclass]+c];
172: }
173: }
174: }
175: VecRestoreArray(gvec, &array);
176: #endif
178: /* Put the vector into the archive */
179: for(c = 0; c < comp; c++) {
180: optlist = DBMakeOptlist(3);
181: DBAddOption(optlist, DBOPT_LABEL, name);
182: /* DBAddOption(optlist, DBOPT_UNITS, fieldUnits); */
183: DBAddOption(optlist, DBOPT_UNITS, "units");
184: if (vsilo->meshName == PETSC_NULL) {
185: DBPutUcdvar1(fp, subNames[c], "PetscMesh", newArrays[c], numNodes, PETSC_NULL, 0, DB_FLOAT, DB_NODECENT, optlist);
186:
187: } else {
188: DBPutUcdvar1(fp, subNames[c], vsilo->meshName, newArrays[c], numNodes, PETSC_NULL, 0, DB_FLOAT, DB_NODECENT, optlist);
189:
190: }
191: DBFreeOptlist(optlist);
193: }
195: /* Define a vecor variable for multicomponent fields */
196: if(comp > 1) {
197: PetscMemzero(buf, 1024 * sizeof(char));
198: len = DBGetVarLength(fp, "_meshtv_defvars");
199: if (len > 0) {
200: if (DBGetVarType(fp, "_meshtv_defvars") != DB_CHAR) {
201: SETERRQ(PETSC_ERR_FILE_READ, "Invalid type for variable _meshtv_defvars");
202: }
203: if (len > 1024) SETERRQ(PETSC_ERR_SUP, "Need to do dyanmic allocation here");
204: DBReadVar(fp, "_meshtv_defvars", buf);
205: PetscStrcat(buf, ";vec");
206: } else {
207: PetscStrcpy(buf, "vec");
208: }
209: PetscStrcat(buf, name);
210: PetscStrcat(buf, " vector {");
211: for(c = 0; c < comp-1; c++) {
212: PetscStrcat(buf, subNames[c]);
213: PetscStrcat(buf, ",");
214: }
215: PetscStrcat(buf, subNames[c]);
216: PetscStrcat(buf, "}");
217: PetscStrlen(buf, &len);
218: if (len > 1024) SETERRQ(PETSC_ERR_SUP, "Need to do dyanmic allocation here");
219: len = 1024;
220: DBWrite(fp, "_meshtv_defvars", buf, &len, 1, DB_CHAR);
221: }
223: /* Cleanup */
224: for(c = 0; c < comp; c++) {
225: PetscFree(newArrays[c]);
226: }
227: PetscFree(newArrays);
228: }
229: return(0);
230: }
231: #endif
233: #undef __FUNCT__
235: static int GVecCreateElementVec_Private(GVec gvec, LocalVarOrdering locOrder, ElementVec *elemVec) {
236: MPI_Comm comm;
237: Grid grid;
238: VarOrdering order;
239: FieldClassMap cm;
240: Discretization disc;
241: PetscTruth isConstrained, isFieldConstrained;
242: int numFields, numFuncs, elemSize;
243: int f, field;
244: int ierr;
247: PetscObjectGetComm((PetscObject) gvec, &comm);
248: GVecGetGrid(gvec, &grid);
249: GVecGetOrder(gvec, &order);
250: VarOrderingGetClassMap(order, &cm);
252: LocalVarOrderingGetSize(locOrder, &elemSize);
253: FieldClassMapIsConstrained(cm, &isConstrained);
254: FieldClassMapGetNumFields(cm, &numFields);
255: if (isConstrained == PETSC_TRUE) {
256: for(f = 0; f < numFields; f++) {
257: FieldClassMapGetField(cm, f, &field);
258: GridIsFieldConstrained(grid, field, &isFieldConstrained);
259: if (isFieldConstrained == PETSC_TRUE) {
260: GridGetDiscretization(grid, field, &disc);
261: DiscretizationGetNumFunctions(disc, &numFuncs);
262: elemSize += numFuncs*grid->fields[field].constraintCompDiff;
263: }
264: }
265: }
266: ElementVecCreate(comm, elemSize, elemVec);
267: return(0);
268: }
270: #undef __FUNCT__
272: static int MeshGetNumLocalVertices_Private(Mesh mesh, int *numLocalVertices) {
273: Partition part;
274: PetscTruth *seen;
275: int numOverlapElements, numCorners, numLocalNodes;
276: int elem, corner, node;
277: int ierr;
280: *numLocalVertices = 0;
281: MeshGetPartition(mesh, &part);
282: MeshGetNumCorners(mesh, &numCorners);
283: PartitionGetNumOverlapElements(part, &numOverlapElements);
284: PartitionGetNumNodes(part, &numLocalNodes);
285: if (numCorners == 3) {
286: *numLocalVertices = numLocalNodes;
287: return(0);
288: }
289: PetscMalloc(numLocalNodes * sizeof(PetscTruth), &seen);
290: PetscMemzero(seen, numLocalNodes * sizeof(PetscTruth));
291: for(elem = 0; elem < numOverlapElements; elem++) {
292: for(corner = 0; corner < 3; corner++) {
293: MeshGetNodeFromElement(mesh, elem, corner, &node);
294: if ((node < numLocalNodes) && (seen[node] == PETSC_FALSE)) {
295: seen[node] = PETSC_TRUE;
296: *numLocalVertices += 1;
297: }
298: }
299: }
300: PetscFree(seen);
301: return(0);
302: }
304: #undef __FUNCT__
306: static int MeshGetNumVertices_Private(Mesh mesh, int *numVertices) {
310: MeshGetInfo(mesh, numVertices, 0, 0, 0);
311: return(0);
312: }
314: #undef __FUNCT__
316: static int GVecCanonicalizeField_Private(GVec gvec, int canonicalField, LocalVarOrdering locOrder, Vec *canonicalVec) {
317: MPI_Comm comm;
318: Grid grid;
319: Mesh mesh;
320: Partition part;
321: VarOrdering order, reductionOrder;
322: AO meshOrdering, partOrdering;
323: Discretization disc;
324: Vec ghostVec, reductionVec;
325: VecScatter ghostScatter;
326: ElementVec elemVec;
327: PetscTruth reduceSystem;
328: PetscScalar reduceAlpha;
329: PetscScalar minusOne = -1.0;
330: int *nodes, *indices;
331: PetscScalar *array;
332: int numLocNodes, numNodes, fieldStart, numComp, numLocElements, numCorners, numFuncs, elemSize;
333: int elem, func, node, c;
334: int ierr;
338: PetscObjectGetComm((PetscObject) gvec, &comm);
339: GVecGetGrid(gvec, &grid);
340: GVecGetOrder(gvec, &order);
341: PetscObjectQuery((PetscObject) gvec, "reductionOrder", (PetscObject *) &reductionOrder);
342: PetscObjectQuery((PetscObject) gvec, "reductionVec", (PetscObject *) &reductionVec);
343: GridGetMesh(grid, &mesh);
344: MeshGetPartition(mesh, &part);
345: if (reductionVec == PETSC_NULL) reductionVec = grid->bdReduceVecCur;
346: /* Create canonical vector */
347: MeshGetNumCorners(mesh, &numCorners);
348: GridGetDiscretization(grid, canonicalField, &disc);
349: DiscretizationGetNumFunctions(disc, &numFuncs);
350: GridGetFieldComponents(grid, canonicalField, &numComp);
351: if (numFuncs < numCorners) {
352: MeshGetNumLocalVertices_Private(mesh, &numLocNodes);
353: MeshGetNumVertices_Private(mesh, &numNodes);
354: } else {
355: PartitionGetNumNodes(part, &numLocNodes);
356: PartitionGetTotalNodes(part, &numNodes);
357: }
358: VecCreate(comm, canonicalVec);
359: VecSetSizes(*canonicalVec, numLocNodes*numComp, numNodes*numComp);
360: VecSetType(*canonicalVec, VECMPI);
361: /* Setup reduction */
362: (*grid->ops->gridsetupghostscatter)(grid, order, &ghostVec, &ghostScatter);
363: /* Fill the local vector */
364: GridGlobalToLocalGeneral(grid, gvec, ghostVec, INSERT_VALUES, ghostScatter);
365: /* Setup element vector */
366: GVecCreateElementVec_Private(gvec, locOrder, &elemVec);
367: LocalVarOrderingGetFieldStart(locOrder, canonicalField, &fieldStart);
368: array = &elemVec->array[fieldStart];
370: GridGetReduceSystem(grid, &reduceSystem);
371: GridGetBCMultiplier(grid, &reduceAlpha);
372: GridSetBCMultiplier(grid, minusOne);
373: MeshGetNodeOrdering(mesh, &meshOrdering);
374: PartitionGetNodeOrdering(part, &partOrdering);
375: LocalVarOrderingGetSize(locOrder, &elemSize);
376: PetscMalloc(numFuncs * sizeof(int), &nodes);
377: PetscMalloc(numFuncs*numComp * sizeof(int), &indices);
378: PartitionGetNumElements(part, &numLocElements);
379: for(elem = 0; elem < numLocElements; elem++) {
380: /* Initialize element vector */
381: ElementVecZero(elemVec);
382: elemVec->reduceSize = elemSize;
383: /* Setup local row indices */
384: GridCalcGeneralElementVecIndices(grid, elem, order, reductionOrder, PETSC_TRUE, elemVec);
385: /* Setup local vectors */
386: GridLocalToElementGeneral(grid, ghostVec, reductionVec, reduceSystem, PETSC_TRUE, elemVec);
387: /* Must transform to unconstrained variables */
388: GridProjectElementVec(grid, mesh, elem, order, PETSC_FALSE, elemVec);
389: /* Put values into canonical vector */
390: for(func = 0; func < numFuncs; func++) {
391: MeshGetNodeFromElement(mesh, elem, func, &node);
392: PartitionLocalToGlobalNodeIndex(part, node, &nodes[func]);
393: }
394: /* We must globally renumber so that midnodes come after vertices */
395: if (partOrdering != PETSC_NULL) {
396: AOPetscToApplication(partOrdering, numFuncs, nodes);
397: }
398: if (meshOrdering != PETSC_NULL) {
399: AOPetscToApplication(meshOrdering, numFuncs, nodes);
400: }
401: for(func = 0; func < numFuncs; func++) {
402: for(c = 0; c < numComp; c++) {
403: indices[func*numComp+c] = nodes[func]*numComp+c;
404: }
405: }
406: VecSetValues(*canonicalVec, numFuncs*numComp, indices, array, INSERT_VALUES);
407: /* Usually reset by ElementVecSetValues() */
408: elemVec->reduceSize = elemVec->size;
409: }
410: VecAssemblyBegin(*canonicalVec);
411: VecAssemblyEnd(*canonicalVec);
412: GridSetBCMultiplier(grid, reduceAlpha);
413: /* Cleanup */
414: PetscFree(nodes);
415: PetscFree(indices);
416: ElementVecDestroy(elemVec);
417: VecDestroy(ghostVec);
418: VecScatterDestroy(ghostScatter);
419: return(0);
420: }
422: #undef __FUNCT__
424: int GVecView_Triangular_2D_VU(GVec gvec, PetscViewer viewer) {
425: MPI_Comm comm;
426: Grid grid;
427: Mesh mesh;
428: Partition part;
429: VarOrdering order;
430: LocalVarOrdering locOrder;
431: FieldClassMap cm;
432: Discretization disc;
433: Vec locCanonicalVec, canonicalVec;
434: PetscTruth vecSeen;
435: FILE *fp;
436: PetscScalar *values;
437: char *fieldName;
438: int *fields;
439: int rank, numFields, numComp, numFuncs, numNodes;
440: int f, field, node, c;
441: int ierr;
444: PetscObjectGetComm((PetscObject) gvec, &comm);
445: MPI_Comm_rank(comm, &rank);
446: GVecGetGrid(gvec, &grid);
447: GVecGetOrder(gvec, &order);
448: GridGetMesh(grid, &mesh);
449: MeshGetPartition(mesh, &part);
450: VarOrderingGetClassMap(order, &cm);
451: FieldClassMapGetNumFields(cm, &numFields);
452: PetscViewerVUGetPointer(viewer, &fp);
453: /* Create local ordering */
454: PetscMalloc(numFields * sizeof(int), &fields);
455: for(f = 0; f < numFields; f++) {
456: FieldClassMapGetField(cm, f, &fields[f]);
457: }
458: LocalVarOrderingCreate(grid, numFields, fields, &locOrder);
459: PetscFree(fields);
460: /* Write each field */
461: PetscFPrintf(comm, fp, "// Field valuesn");
462: for(f = 0; f < numFields; f++) {
463: FieldClassMapGetField(cm, f, &field);
464: GridGetFieldComponents(grid, field, &numComp);
465: GridGetFieldName(grid, field, &fieldName);
466: if (fieldName == PETSC_NULL) SETERRQ(PETSC_ERR_ARG_WRONG, "You must name the fields for VU");
467: GridGetDiscretization(grid, field, &disc);
468: DiscretizationGetNumFunctions(disc, &numFuncs);
469: GVecCanonicalizeField_Private(gvec, field, locOrder, &canonicalVec);
470: VecConvertMPIToMPIZero(canonicalVec, &locCanonicalVec);
471: VecGetSize(locCanonicalVec, &numNodes);
472: VecGetArray(locCanonicalVec, &values);
473: if (rank == 0) {
474: if (numNodes%numComp) SETERRQ(PETSC_ERR_ARG_CORRUPT, "Invalid size for canonical field vector");
475: numNodes /= numComp;
476: for(c = 0; c < numComp; c++) {
477: PetscFPrintf(comm, fp, "FIELD %s%d( ) = {n", fieldName, c);
478: for(node = 0; node < numNodes; node++) {
479: PetscFPrintf(comm, fp, "%gn", PetscRealPart(values[node*numComp+c]));
480: }
481: PetscFPrintf(comm, fp, "};nn");
482: }
483: }
484: VecRestoreArray(locCanonicalVec, &values);
485: VecDestroy(locCanonicalVec);
486: VecDestroy(canonicalVec);
487: PetscFree(fieldName);
488: }
489: LocalVarOrderingDestroy(locOrder);
490: /* Write solution as field union */
491: PetscViewerVUGetVecSeen(viewer, &vecSeen);
492: if (vecSeen == PETSC_FALSE) {
493: PetscViewerVUPrintDeferred(viewer, "// The full solutionnSOLUTION VecSolution( ) =n{n");
494: PetscViewerVUSetVecSeen(viewer, PETSC_TRUE);
495: }
496: for(f = 0; f < numFields; f++) {
497: FieldClassMapGetField(cm, f, &field);
498: GridGetFieldName(grid, field, &fieldName);
499: GridGetFieldComponents(grid, field, &numComp);
500: GridGetDiscretization(grid, field, &disc);
501: DiscretizationGetNumFunctions(disc, &numFuncs);
502: for(c = 0; c < numComp; c++) {
503: switch(numFuncs) {
504: case 3:
505: PetscViewerVUPrintDeferred(viewer, " VARIABLE %s%d(LagrTrian03, %s%d, Connectivity, Zone1);n", fieldName, c, fieldName, c);
506: break;
507: case 6:
508: PetscViewerVUPrintDeferred(viewer, " VARIABLE %s%d(LagrTrian06, %s%d, FullConnectivity, Zone1);n", fieldName, c, fieldName, c);
509: break;
510: default:
511: SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid number of function in discretization %d", numFuncs);
512: }
513: }
514: PetscFree(fieldName);
515: }
516: return(0);
517: }
519: #undef __FUNCT__
521: int GVecView_Triangular_2D(GVec gvec, PetscViewer viewer)
522: {
523: Grid grid;
524: PetscTruth isascii, isdraw, isvu, ismathematica, issilo;
525: int ierr;
528: PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_ASCII, &isascii);
529: PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_DRAW, &isdraw);
530: PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_VU, &isvu);
531: PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_MATHEMATICA, &ismathematica);
532: PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_SILO, &issilo);
533: if (isascii == PETSC_TRUE) {
534: GVecGetGrid(gvec, &grid);
535: GridView(grid, viewer);
536: PetscViewerFlush(viewer);
537: VecView(gvec, viewer);
538: } else if (isdraw == PETSC_TRUE) {
539: GVecView_Triangular_2D_Draw(gvec, viewer);
540: } else if (isvu == PETSC_TRUE) {
541: GVecView_Triangular_2D_VU(gvec, viewer);
542: #ifdef PETSC_HAVE_MATHEMATICA
543: } else if (ismathematica == PETSC_TRUE) {
544: ViewerMathematica_GVec_Triangular_2D(viewer, gvec);
545: #endif
546: #ifdef PETSC_HAVE_MATHEMATICA
547: } else if (issilo == PETSC_TRUE) {
548: GVecView_Triangular_2D_Silo(gvec, viewer);
549: #endif
550: }
552: return(0);
553: }