示例#1
0
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];
         }
       }
     }
}
示例#2
0
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;
}