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: }