void Zoltan_Transform_Box( double *lo, double *hi, /* input: box bounds, output: bounds of transformed box */ double (*m)[3], /* 3x3 transformation */ int *perm, /* if transformation is simple coordinate permutation */ int d, /* dimension of box */ int ndims) /* dimension of transformed box */ { double v[8][3]; int i, npoints; npoints = ((d == 2) ? 4 : 8); Zoltan_Transform_Box_Points(lo, hi, m, perm, d, ndims, v); lo[0] = hi[0] = v[0][0]; lo[1] = hi[1] = 0.0; lo[2] = hi[2] = 0.0; if (ndims > 1){ lo[1] = hi[1] = v[0][1]; if (ndims > 2){ lo[2] = hi[2] = v[0][2]; } } for (i=1; i<npoints; i++){ if (v[i][0] < lo[0] ) lo[0] = v[i][0]; else if (v[i][0] > hi[0]) hi[0] = v[i][0]; if (ndims > 1){ if (v[i][1] < lo[1]) lo[1] = v[i][1]; else if (v[i][1] > hi[1]) hi[1] = v[i][1]; if (ndims > 2){ if (v[i][2] < lo[2]) lo[2] = v[i][2]; else if (v[i][2] > hi[2]) hi[2] = v[i][2]; } } } }
int Zoltan_RB_Box_Assign( ZZ *zz, /* The Zoltan structure */ double xmin, /* lower x extent of box */ double ymin, /* lower y extent of box */ double zmin, /* lower z extent of box */ double xmax, /* upper x extent of box */ double ymax, /* upper y extent of box */ double zmax, /* upper z extent of box */ int *procs, /* list of procs that box intersects */ int *numprocs, /* number of processors in proc list */ int *parts, /* list of parts that box intersects */ int *numparts) /* number of partitions in part list */ { /* Determine which partitions and processors a box intersects. Currently assumes that partitioning has used RCB or RIB, but should be modified to return an error message if other method was used */ static char *yo = "Zoltan_RB_Box_Assign"; RCB_STRUCT *rcb; /* Pointer to data structures for RCB. */ struct rcb_tree *treept; /* tree of RCB cuts */ RIB_STRUCT *rib; /* Pointer to data structures for RIB. */ struct rib_tree *itree; /* tree of RIB cuts */ struct rcb_box box; /* box data structure */ int *proc_array = NULL; /* Array of size zz->Num_Proc; initialized to 0; entry i incremented each time a found partition is on processor i. Added to support !zz->LB.Single_Proc_Per_Part. */ int include_procs = (procs != NULL); int include_parts = (parts != NULL); int ierr = ZOLTAN_OK; int i; double p[8][3]; if (zz->LB.Data_Structure == NULL) { ZOLTAN_PRINT_ERROR(-1, yo, "No Decomposition Data available; use KEEP_CUTS parameter."); ierr = ZOLTAN_FATAL; goto End; } if (include_procs) { proc_array = (int *) ZOLTAN_CALLOC(zz->Num_Proc, sizeof(int)); if (!proc_array) { ierr = ZOLTAN_MEMERR; goto End; } } *numprocs = *numparts = 0; if (zz->LB.Method == RCB) { rcb = (RCB_STRUCT *) (zz->LB.Data_Structure); treept = rcb->Tree_Ptr; if (treept[0].dim < 0) { /* RCB tree was never created. */ ZOLTAN_PRINT_ERROR(zz->Proc, yo, "No RCB tree saved; " " Must set parameter KEEP_CUTS to 1."); ierr = ZOLTAN_FATAL; goto End; } box.lo[0] = xmin; box.lo[1] = ymin; box.lo[2] = zmin; box.hi[0] = xmax; box.hi[1] = ymax; box.hi[2] = zmax; if (rcb->Tran.Target_Dim > 0){ /* * Degenerate geometry, transform box to the lower dimensional * space that the partitioning occured in. Our new box may * encompass more partitions, but it won't miss any. */ Zoltan_Transform_Box(box.lo, box.hi, rcb->Tran.Transformation, rcb->Tran.Permutation, rcb->Num_Dim, rcb->Tran.Target_Dim); } Box_Assign(zz, treept, &box, include_procs, include_parts, proc_array, parts, numparts, treept[0].right_leaf); } else if (zz->LB.Method == RIB) { rib = (RIB_STRUCT *) (zz->LB.Data_Structure); itree = rib->Tree_Ptr; if (itree[0].right_leaf < 0) { /* RIB tree was never created. */ ZOLTAN_PRINT_ERROR(zz->Proc, yo, "No RIB tree saved;" " Must set parameter KEEP_CUTS to 1."); ierr = ZOLTAN_FATAL; goto End; } switch (rib->Num_Geom) { case 3: box.lo[0] = xmin; box.lo[1] = ymin; box.lo[2] = zmin; box.hi[0] = xmax; box.hi[1] = ymax; box.hi[2] = zmax; if (rib->Tran.Target_Dim <= 0){ Box_Assign3(zz, itree, &box, include_procs, include_parts, proc_array, parts, numparts, itree[0].right_leaf); } else{ /* degenerate geometry, Target_Dim is 2 or 1 */ Zoltan_Transform_Box_Points(box.lo, box.hi, rib->Tran.Transformation, rib->Tran.Permutation, 3, rib->Tran.Target_Dim, p); if (rib->Tran.Target_Dim == 1){ /* box -> line */ box.lo[0] = box.hi[0] = p[0][0]; for (i=1; i<8; i++){ if (p[i][0] < box.lo[0]) box.lo[0] = p[i][0]; else if (p[i][0] > box.hi[0]) box.hi[0] = p[i][0]; } Box_Assign1(zz, itree, &box, include_procs, include_parts, proc_array, parts, numparts, itree[0].right_leaf); } else{ /* box -> plane, no longer axis-aligned */ Transformed_Box_Assign(zz, itree, p, rib->Tran.Target_Dim, include_procs, include_parts, proc_array, parts, numparts, itree[0].right_leaf); } } break; case 2: box.lo[0] = xmin; box.lo[1] = ymin; box.hi[0] = xmax; box.hi[1] = ymax; if (rib->Tran.Target_Dim <= 0){ Box_Assign2(zz, itree, &box, include_procs, include_parts, proc_array, parts, numparts, itree[0].right_leaf); } else{ /* degenerate geometry, Target_Dim is 1 */ Zoltan_Transform_Box_Points(box.lo, box.hi, rib->Tran.Transformation, rib->Tran.Permutation, 2, 1, p); box.lo[0] = box.hi[0] = p[0][0]; for (i=1; i<4; i++){ if (p[i][0] < box.lo[0]) box.lo[0] = p[i][0]; else if (p[i][0] > box.hi[0]) box.hi[0] = p[i][0]; } Box_Assign1(zz, itree, &box, include_procs, include_parts, proc_array, parts, numparts, itree[0].right_leaf); } break; case 1: box.lo[0] = xmin; box.hi[0] = xmax; Box_Assign1(zz, itree, &box, include_procs, include_parts, proc_array, parts, numparts, itree[0].right_leaf); break; } } else { ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Valid only when load-balancing method is RCB and RIB."); ierr = ZOLTAN_FATAL; goto End; } if (include_procs) { for (i = 0; i < zz->Num_Proc; i++) if (proc_array[i] > 0) procs[(*numprocs)++] = i; } End: ZOLTAN_FREE(&proc_array); if (ierr != ZOLTAN_OK) { if (include_procs) *procs = -1; *numprocs = 0; if (include_parts) *parts = -1; *numparts = 0; } return ierr; }