Actual source code: partQuery.c
1: #ifdef PETSC_RCS_HEADER
2: static char vcid[] = "$Id: partQuery.c,v 1.6 2000/01/31 17:37:32 knepley Exp $";
3: #endif
5: /*
6: Defines the interface to the partition query functions
7: */
9: #include src/mesh/meshimpl.h
11: /*-------------------------------------------- Partition Query Functions ---------------------------------------------*/
12: /*@
13: PartitionGetDimension - This function returns the dimension of the Partition.
15: Not collective
17: Input Parameter:
18: . part - The partition
20: Output Parameter:
21: . dim - The partition dimension
23: Level: intermediate
25: .keywords: Partition, dimension
26: .seealso: MeshGetDimension()
27: @*/
28: int PartitionGetDimension(Partition part, int *dim)
29: {
30: Mesh mesh;
36: PartitionGetMesh(part, &mesh);
37: MeshGetDimension(mesh, dim);
38: return(0);
39: }
41: /*@
42: PartitionGetMesh - Returns the Mesh object for this Partition.
44: Not collective
46: Input Parameter:
47: . part - The partition
49: Output Parameter:
50: . mesh - The mesh
52: Level: intermediate
54: .keywords: Mesh, Partition, get
55: .seealso: MeshGetPartition()
56: @*/
57: int PartitionGetMesh(Partition part, Mesh *mesh)
58: {
62: *mesh = part->mesh;
63: return(0);
64: }
66: /*--------------------------------------------- Element Query Functions ----------------------------------------------*/
67: /*@
68: PartitionGetTotalElements - Gets the number of elements in the mesh.
70: Not collective
72: Input Parameter:
73: . part - The partition
75: Output Parameter:
76: . size - The number of elements in the mesh
78: Level: intermediate
80: .keywords: partition, element
81: .seealso: PartitionGetStartElement(), PartitionGetEndElement()
82: @*/
83: int PartitionGetTotalElements(Partition part, int *size)
84: {
88: *size = part->numElements;
89: return(0);
90: }
92: /*@
93: PartitionGetStartElement - Gets the first element in this domain.
95: Not collective
97: Input Parameter:
98: . part - The partition
100: Output Parameter:
101: . elem - The first element in this domain
103: Level: intermediate
105: .keywords: partition, element
106: .seealso: PartitionGetEndElement(), PartitionGetNumElements()
107: @*/
108: int PartitionGetStartElement(Partition part, int *elem)
109: {
113: *elem = part->firstElement[part->rank];
114: return(0);
115: }
117: /*@
118: PartitionGetEndElement - Gets the first element in the next domain.
120: Not collective
122: Input Parameter:
123: . part - The partition
125: Output Parameter:
126: . elem - The first element in the next domain
128: Level: intermediate
130: .keywords: partition, element
131: .seealso: PartitionGetStartElement(), PartitionGetNumElements()
132: @*/
133: int PartitionGetEndElement(Partition part, int *elem)
134: {
138: *elem = part->firstElement[part->rank+1];
139: return(0);
140: }
142: /*@
143: PartitionGetNumElements - Gets the number of elements in this domain.
145: Not collective
147: Input Parameter:
148: . part - The partition
150: Output Parameter:
151: . size - The number of elements in this domain
153: Level: intermediate
155: .keywords: partition, element
156: .seealso: PartitionGetStartElement(), PartitionGetEndElement()
157: @*/
158: int PartitionGetNumElements(Partition part, int *size)
159: {
163: *size = part->firstElement[part->rank+1] - part->firstElement[part->rank];
164: return(0);
165: }
167: /*@
168: PartitionGetNumOverlapElements - Gets the number of elements and ghost elements for this domain.
170: Not collective
172: Input Parameter:
173: . part - The partition
175: Output Parameter:
176: . size - The number of elements and ghost element for this domain
178: Level: intermediate
180: .keywords: partition, element
181: .seealso: PartitionGetStartElement(), PartitionGetEndElement()
182: @*/
183: int PartitionGetNumOverlapElements(Partition part, int *size)
184: {
188: *size = part->numOverlapElements;
189: return(0);
190: }
192: static int PartitionGhostElementIndex_Private(Partition p, int elem, int *gElem)
193: {
194: int low, high, mid;
197: /* Use bisection since the array is assumed to be sorted */
198: low = 0;
199: high = p->numOverlapElements - (p->firstElement[p->rank+1] - p->firstElement[p->rank]) - 1;
200: while (low <= high) {
201: mid = (low + high)/2;
202: if (elem == p->ghostElements[mid]) {
203: *gElem = mid;
204: return(0);
205: } else if (elem < p->ghostElements[mid]) {
206: high = mid - 1;
207: } else {
208: low = mid + 1;
209: }
210: }
211: /* We indicate elements which are not local and also not ghost by -2 */
212: *gElem = -2;
213: return(0);
214: }
216: /*@
217: PartitionGlobalToLocalElementIndex - Returns the local element number
218: corresponding to the global element number.
220: Not collective
222: Input Parameters:
223: + part - The partition
224: - elem - The canonical global element number
226: Output Parameter:
227: . locElem - The local element number
229: Level: intermediate
231: .keywords: partition, local, global
232: .seealso PartitionLocalToGlobalElementIndex()
233: @*/
234: int PartitionGlobalToLocalElementIndex(Partition part, int elem, int *locElem)
235: {
236: int numLocElements;
237: int gElem; /* The local ghost element number */
243: numLocElements = part->firstElement[part->rank+1] - part->firstElement[part->rank];
244: if (elem < 0) {
245: *locElem = elem;
246: return(0);
247: }
248: /* Check for ghost element */
249: if ((elem < part->firstElement[part->rank]) || (elem >= part->firstElement[part->rank+1])) {
250: /* Search for canonical number */
251: PartitionGhostElementIndex_Private(part, elem, &gElem);
252: if (gElem < 0) {
253: *locElem = gElem;
254: } else {
255: *locElem = numLocElements + gElem;
256: }
257: } else {
258: *locElem = elem - part->firstElement[part->rank];
259: }
260: return(0);
261: }
263: /*@
264: PartitionLocalToGlobalElementIndex - Returns the global element number
265: corresponding to the local element number.
267: Not collective
269: Input Parameters:
270: + part - The partition
271: - locElem - The canonical local element number
273: Output Parameter:
274: . elem - The global element number
276: Level: intermediate
278: .keywords: partition, local, global
279: .seealso: PartitionGlobalToLocalElementIndex()
280: @*/
281: int PartitionLocalToGlobalElementIndex(Partition part, int locElem, int *elem)
282: {
283: int numLocElements;
288: numLocElements = part->firstElement[part->rank+1] - part->firstElement[part->rank];
289: if (locElem < 0) {
290: *elem = locElem;
291: return(0);
292: } else if (locElem < numLocElements) {
293: *elem = locElem + part->firstElement[part->rank];
294: } else if (locElem < part->numOverlapElements) {
295: *elem = part->ghostElements[locElem - numLocElements];
296: } else {
297: SETERRQ(PETSC_ERR_ARG_WRONG, "Invalid local element index (too large)");
298: }
299: return(0);
300: }
302: /*@
303: PartitionGetElementOrdering - This function gets the AO which was used to reorder the mesh elements
304: during partitioning.
306: Not collective
308: Input Parameter:
309: . part - The partition
311: Output Parameter:
312: . order - The element ordering, or PETSC_NULL if none exists
314: Level: intermediate
316: .keywords: Partition, element, ordering, AO
317: .seealso: MeshGetNodeOrdering()
318: @*/
319: int PartitionGetElementOrdering(Partition part, AO *order)
320: {
324: *order = part->ordering;
325: return(0);
326: }
328: /*----------------------------------------------- Node Query Functions -----------------------------------------------*/
329: /*@
330: PartitionGetTotalNodes - Gets the number of nodes in the mesh.
332: Not collective
334: Input Parameter:
335: . part - The partition
337: Output Parameter:
338: . size - The number of nodes in the mesh
340: Level: intermediate
342: .keywords: partition, node
343: .seealso: PartitionGetStartNode(), PartitionGetEndNode(), PartitionGetTotalElements()
344: @*/
345: int PartitionGetTotalNodes(Partition part, int *size)
346: {
352: if (part->ops->gettotalnodes == PETSC_NULL) {
353: SETERRQ(PETSC_ERR_SUP, "Not implemented for this partition type");
354: }
355: (*part->ops->gettotalnodes)(part, size);
356: return(0);
357: }
359: /*@
360: PartitionGetStartNode - Gets the first node in this domain.
362: Not collective
364: Input Parameter:
365: . part - The partition
367: Output Parameter:
368: . node - The first node in this domain
370: Level: intermediate
372: .keywords: partition, node
373: .seealso: PartitionGetEndNode(), PartitionGetNumNodes(), PartitionGetStartElement()
374: @*/
375: int PartitionGetStartNode(Partition part, int *node)
376: {
382: if (part->ops->getstartnode == PETSC_NULL) {
383: SETERRQ(PETSC_ERR_SUP, "Not implemented for this partition type");
384: }
385: (*part->ops->getstartnode)(part, node);
386: return(0);
387: }
389: /*@
390: PartitionGetEndNode - Gets the first node in the next domain.
392: Not collective
394: Input Parameter:
395: . part - The partition
397: Output Parameter:
398: . node - The first node in the next domain
400: Level: intermediate
402: .keywords: partition, node
403: .seealso: PartitionGetStartNode(), PartitionGetNumNodes(), PartitionGetEndElement()
404: @*/
405: int PartitionGetEndNode(Partition part, int *node)
406: {
412: if (part->ops->getendnode == PETSC_NULL) {
413: SETERRQ(PETSC_ERR_SUP, "Not implemented for this partition type");
414: }
415: (*part->ops->getendnode)(part, node);
416: return(0);
417: }
419: /*@
420: PartitionGetNumNodes - Gets the number of nodes in this domain.
422: Not collective
424: Input Parameter:
425: . part - The partition
427: Output Parameter:
428: . size - The number of nodes in this domain
430: Level: intermediate
432: .keywords: partition, node
433: .seealso: PartitionGetStartNode(), PartitionGetEndNode(), PartitionGetNumElements()
434: @*/
435: int PartitionGetNumNodes(Partition part, int *size)
436: {
442: if (part->ops->getnumnodes == PETSC_NULL) {
443: SETERRQ(PETSC_ERR_SUP, "Not implemented for this partition type");
444: }
445: (*part->ops->getnumnodes)(part, size);
446: return(0);
447: }
449: /*@
450: PartitionGetNumOverlapNodes - Gets the number of nodes and ghost nodes for this domain.
452: Not collective
454: Input Parameter:
455: . part - The partition
457: Output Parameter:
458: . size - The number of nodes and ghost nodes this domain
460: Level: intermediate
462: .keywords: partition, node
463: .seealso: PartitionGetStartNode(), PartitionGetEndNode(), PartitionGetNumOverlapElements()
464: @*/
465: int PartitionGetNumOverlapNodes(Partition part, int *size)
466: {
472: if (part->ops->getnumoverlapnodes == PETSC_NULL) {
473: SETERRQ(PETSC_ERR_SUP, "Not implemented for this partition type");
474: }
475: (*part->ops->getnumoverlapnodes)(part, size);
476: return(0);
477: }
479: /*@
480: PartitionGlobalToLocalNodeIndex - Returns the local node number
481: corresponding to the global node number.
483: Not collective
485: Input Parameters:
486: + part - The partition
487: - node - The canonical global node number
489: Output Parameter:
490: . locNode - The local node number
492: Level: intermediate
494: .keywords: partition, local, global
495: .seealso: PartitionLocalToGlobalNodeIndex(), PartitionGlobalToLocalElementIndex()
496: @*/
497: int PartitionGlobalToLocalNodeIndex(Partition part, int node, int *locNode)
498: {
504: if (part->ops->globaltolocalnodeindex == PETSC_NULL) {
505: SETERRQ(PETSC_ERR_SUP, "Not implemented for this partition type");
506: }
507: (*part->ops->globaltolocalnodeindex)(part, node, locNode);
508: return(0);
509: }
511: /*@
512: PartitionLocalToGlobalNodeIndex - Returns the global node number
513: corresponding to the local node number.
515: Not collective
517: Input Parameters:
518: + part - The partition
519: - locNode - The canonical local node number
521: Output Parameter:
522: . node - The global node number
524: Level: intermediate
526: .keywords: partition, local, global
527: .seealso: PartitionGlobalToLocalNodeIndex(), PartitionLocalToGlobalElementIndex()
528: @*/
529: int PartitionLocalToGlobalNodeIndex(Partition part, int locNode, int *node)
530: {
536: if (part->ops->localtoglobalnodeindex == PETSC_NULL) {
537: SETERRQ(PETSC_ERR_SUP, "Not implemented for this partition type");
538: }
539: (*part->ops->localtoglobalnodeindex)(part, locNode, node);
540: return(0);
541: }
543: /*@
544: PartitionGetNodeOrdering - This function gets the AO which was used to reorder the mesh nodes
545: during partitioning.
547: Not collective
549: Input Parameter:
550: . part - The partition
552: Output Parameter:
553: . order - The node ordering, or PETSC_NULL if none exists
555: Level: intermediate
557: .keywords: Partition, node, ordering, AO
558: .seealso: MeshGetNodeOrdering()
559: @*/
560: int PartitionGetNodeOrdering(Partition part, AO *order)
561: {
567: (*part->ops->getnodeordering)(part, order);
568: return(0);
569: }
571: /*----------------------------------------------- Face Query Functions -----------------------------------------------*/
572: /*@
573: PartitionGetTotalFaces - Gets the number of faces in the mesh.
575: Not collective
577: Input Parameter:
578: . part - The partition
580: Output Parameter:
581: . size - The number of faces in the mesh
583: Level: intermediate
585: .keywords: partition, face
586: .seealso: PartitionGetStartFace(), PartitionGetEndFace(), PartitionGetTotalElements()
587: @*/
588: int PartitionGetTotalFaces(Partition part, int *size)
589: {
595: if (part->ops->gettotalfaces == PETSC_NULL) {
596: SETERRQ(PETSC_ERR_SUP, "Not implemented for this partition type");
597: }
598: (*part->ops->gettotalfaces)(part, size);
599: return(0);
600: }
602: /*@
603: PartitionGetStartFace - Gets the first face in this domain.
605: Not collective
607: Input Parameter:
608: . part - The partition
610: Output Parameter:
611: . face - The first face in this domain
613: Level: intermediate
615: .keywords: partition, face
616: .seealso: PartitionGetEndFace(), PartitionGetNumFaces(), PartitionGetStartElement()
617: @*/
618: int PartitionGetStartFace(Partition part, int *face)
619: {
625: if (part->ops->getstartface == PETSC_NULL) {
626: SETERRQ(PETSC_ERR_SUP, "Not implemented for this partition type");
627: }
628: (*part->ops->getstartface)(part, face);
629: return(0);
630: }
632: /*@
633: PartitionGetEndFace - Gets the first face in the next domain.
635: Not collective
637: Input Parameter:
638: . part - The partition
640: Output Parameter:
641: . face - The first face in the next domain
643: Level: intermediate
645: .keywords: partition, face
646: .seealso: PartitionGetStartFace(), PartitionGetNumFaces(), PartitionGetEndElement()
647: @*/
648: int PartitionGetEndFace(Partition part, int *face)
649: {
655: if (part->ops->getendface == PETSC_NULL) {
656: SETERRQ(PETSC_ERR_SUP, "Not implemented for this partition type");
657: }
658: (*part->ops->getendface)(part, face);
659: return(0);
660: }
662: /*@
663: PartitionGetNumFaces - Gets the number of faces in this domain.
665: Not collective
667: Input Parameter:
668: . part - The partition
670: Output Parameter:
671: . size - The number of faces in this domain
673: Level: intermediate
675: .keywords: partition, face
676: .seealso: PartitionGetStartFace(), PartitionGetEndFace(), PartitionGetNumElements()
677: @*/
678: int PartitionGetNumFaces(Partition part, int *size)
679: {
685: if (part->ops->getnumfaces == PETSC_NULL) {
686: SETERRQ(PETSC_ERR_SUP, "Not implemented for this partition type");
687: }
688: (*part->ops->getnumfaces)(part, size);
689: return(0);
690: }
692: /*@
693: PartitionGetNumOverlapFaces - Gets the number of faces and ghost faces this domain.
695: Not collective
697: Input Parameter:
698: . part - The partition
700: Output Parameter:
701: . size - The number of faces and ghost faces this domain
703: Level: intermediate
705: .keywords: partition, face
706: .seealso: PartitionGetStartFace(), PartitionGetEndFace(), PartitionGetNumOverlapElements()
707: @*/
708: int PartitionGetNumOverlapFaces(Partition part, int *size)
709: {
715: if (part->ops->getnumoverlapfaces == PETSC_NULL) {
716: SETERRQ(PETSC_ERR_SUP, "Not implemented for this partition type");
717: }
718: (*part->ops->getnumoverlapfaces)(part, size);
719: return(0);
720: }
722: /*@
723: PartitionGlobalToLocalFaceIndex - Returns the local face number
724: corresponding to the global face number.
726: Not collective
728: Input Parameters:
729: + part - The partition
730: - face - The canonical global face number
732: Output Parameter:
733: . locFace - The local face number
735: Level: intermediate
737: .keywords: partition, local, global
738: .seealso: PartitionLocalToGlobalFaceIndex(), PartitionGlobalToLocalElementIndex()
739: @*/
740: int PartitionGlobalToLocalFaceIndex(Partition part, int face, int *locFace)
741: {
747: if (part->ops->globaltolocalfaceindex == PETSC_NULL) {
748: SETERRQ(PETSC_ERR_SUP, "Not implemented for this partition type");
749: }
750: (*part->ops->globaltolocalfaceindex)(part, face, locFace);
751: return(0);
752: }
754: /*@
755: PartitionLocalToGlobalFaceIndex - Returns the global face number
756: corresponding to the local face number.
758: Not collective
760: Input Parameters:
761: + part - The partition
762: - locFace - The canonical local face number
764: Output Parameter:
765: . face - The global face number
767: Level: intermediate
769: .keywords: partition, local, global
770: .seealso: PartitionGlobalToLocalNodeIndex(), PartitionLocalToGlobalElementIndex()
771: @*/
772: int PartitionLocalToGlobalFaceIndex(Partition part, int locFace, int *face)
773: {
779: if (part->ops->localtoglobalfaceindex == PETSC_NULL) {
780: SETERRQ(PETSC_ERR_SUP, "Not implemented for this partition type");
781: }
782: (*part->ops->localtoglobalfaceindex)(part, locFace, face);
783: return(0);
784: }
786: /*@
787: PartitionGetFaceOrdering - This function gets the AO which was used to reorder the mesh faces
788: during partitioning.
790: Not collective
792: Input Parameter:
793: . part - The partition
795: Output Parameter:
796: . order - The face ordering, or PETSC_NULL if none exists
798: Level: intermediate
800: .keywords: Partition, face, ordering, AO
801: .seealso: MeshGetNodeOrdering()
802: @*/
803: int PartitionGetFaceOrdering(Partition part, AO *order)
804: {
810: (*part->ops->getfaceordering)(part, order);
811: return(0);
812: }
814: /*----------------------------------------------- Edge Query Functions -----------------------------------------------*/
815: /*@
816: PartitionGetTotalEdges - Gets the number of edges in the mesh.
818: Not collective
820: Input Parameter:
821: . part - The partition
823: Output Parameter:
824: . size - The number of edges in the mesh
826: Level: intermediate
828: .keywords: partition, edge
829: .seealso: PartitionGetStartEdge(), PartitionGetEndEdge(), PartitionGetTotalElements()
830: @*/
831: int PartitionGetTotalEdges(Partition part, int *size)
832: {
838: if (part->ops->gettotaledges == PETSC_NULL) {
839: SETERRQ(PETSC_ERR_SUP, "Not implemented for this partition type");
840: }
841: (*part->ops->gettotaledges)(part, size);
842: return(0);
843: }
845: /*@
846: PartitionGetStartEdge - Gets the first edge in this domain.
848: Not collective
850: Input Parameter:
851: . part - The partition
853: Output Parameter:
854: . edge - The first edge in this domain
856: Level: intermediate
858: .keywords: partition, edge
859: .seealso: PartitionGetEndEdge(), PartitionGetNumEdges(), PartitionGetStartElement()
860: @*/
861: int PartitionGetStartEdge(Partition part, int *edge)
862: {
868: if (part->ops->getstartedge == PETSC_NULL) {
869: SETERRQ(PETSC_ERR_SUP, "Not implemented for this partition type");
870: }
871: (*part->ops->getstartedge)(part, edge);
872: return(0);
873: }
875: /*@
876: PartitionGetEndEdge - Gets the first edge in the next domain.
878: Not collective
880: Input Parameter:
881: . part - The partition
883: Output Parameter:
884: . edge - The first edge in the next domain
886: Level: intermediate
888: .keywords: partition, edge
889: .seealso: PartitionGetStartEdge(), PartitionGetNumEdges(), PartitionGetEndElement()
890: @*/
891: int PartitionGetEndEdge(Partition part, int *edge)
892: {
898: if (part->ops->getendedge == PETSC_NULL) {
899: SETERRQ(PETSC_ERR_SUP, "Not implemented for this partition type");
900: }
901: (*part->ops->getendedge)(part, edge);
902: return(0);
903: }
905: /*@
906: PartitionGetNumEdges - Gets the number of edges in this domain.
908: Not collective
910: Input Parameter:
911: . part - The partition
913: Output Parameter:
914: . size - The number of edges in this domain
916: Level: intermediate
918: .keywords: partition, edge
919: .seealso: PartitionGetStartEdge(), PartitionGetEndEdge(), PartitionGetNumElements()
920: @*/
921: int PartitionGetNumEdges(Partition part, int *size)
922: {
928: if (part->ops->getnumedges == PETSC_NULL) {
929: SETERRQ(PETSC_ERR_SUP, "Not implemented for this partition type");
930: }
931: (*part->ops->getnumedges)(part, size);
932: return(0);
933: }
935: /*@
936: PartitionGetNumOverlapEdges - Gets the number of edges and ghost edges this domain.
938: Not collective
940: Input Parameter:
941: . part - The partition
943: Output Parameter:
944: . size - The number of edges and ghost edges this domain
946: Level: intermediate
948: .keywords: partition, edge
949: .seealso: PartitionGetStartEdge(), PartitionGetEndEdge(), PartitionGetNumOverlapElements()
950: @*/
951: int PartitionGetNumOverlapEdges(Partition part, int *size)
952: {
958: if (part->ops->getnumoverlapedges == PETSC_NULL) {
959: SETERRQ(PETSC_ERR_SUP, "Not implemented for this partition type");
960: }
961: (*part->ops->getnumoverlapedges)(part, size);
962: return(0);
963: }
965: /*@
966: PartitionGetEdgeOrdering - This function gets the AO which was used to reorder the mesh edges
967: during partitioning.
969: Not collective
971: Input Parameter:
972: . part - The partition
974: Output Parameter:
975: . order - The edge ordering, or PETSC_NULL if none exists
977: Level: intermediate
979: .keywords: Partition, edge, ordering, AO
980: .seealso: MeshGetNodeOrdering()
981: @*/
982: int PartitionGetEdgeOrdering(Partition part, AO *order)
983: {
989: (*part->ops->getedgeordering)(part, order);
990: return(0);
991: }