Exemple #1
0
/*
 * Calculate the extent of the geometry in the directions indicated
 * by the orthonormal eigenvectors of the inertial matrix.  This is
 * essentially the dimensions of an oriented bounding box around
 * the geometry.
 */
static void projected_distances(ZZ *zz, double *coords, int num_obj,
        double *cm, double (*evecs)[3], double *d, int dim, int aa, int *order)
{
int i, j;
double val, min[3], max[3], *c, tmp;
int Tflops_Special, proc, nprocs, proclower;
MPI_Comm local_comm;

  Tflops_Special = zz->Tflops_Special;
  proc = zz->Proc;
  nprocs = zz->Num_Proc;
  proclower = 0;
  local_comm = zz->Communicator;

  if (aa){
    /* special case - eigenvectors are axis aligned */

    for (j=0; j<dim; j++){
      min[j] = max[j] = coords[j];
    }

    for (i=1, c = coords+dim; i<num_obj; i++, c += dim){
      for (j=0; j<dim; j++){
        if (c[j] < min[j]) min[j] = c[j];
        else if (c[j] > max[j]) max[j] = c[j];
      }
    }

    for (i=0; i<dim; i++){
      tmp = max[i];
      MPI_Allreduce(&tmp, max + i, 1, MPI_DOUBLE, MPI_MAX, local_comm);
      tmp = min[i];
      MPI_Allreduce(&tmp, min + i, 1, MPI_DOUBLE, MPI_MIN, local_comm);
    }

    for (j=0; j<dim; j++){
      /* distance along the j'th eigenvector */
      d[j] = max[order[j]] - min[order[j]];
    }
    
    return;
  }

  for (i=0; i<dim; i++){
    for (j=0, c=coords; j<num_obj; j++, c+=dim){

      val = (((c[0] - cm[0]) * evecs[0][i]) + ((c[1] - cm[1]) * evecs[1][i]));

      if (dim == 3){
        val += ((c[2] - cm[2]) * evecs[2][i]);
      }

      if (j){
        if (val < min[i]) min[i] = val;
        else if (val > max[i]) max[i] = val;
      }
      else{
        min[i] = max[i] = val;
      }
    }
  }

  if (Tflops_Special){
    for (i=0; i<dim; i++){
      Zoltan_RIB_min_max(min+i, max+i, proclower, proc, nprocs,
                       local_comm);
      d[i] = max[i] - min[i];
    }
  }
  else {
    for (i=0; i<dim; i++){
      tmp = max[i];
      MPI_Allreduce(&tmp, max + i, 1, MPI_DOUBLE, MPI_MAX, local_comm);
      tmp = min[i];
      MPI_Allreduce(&tmp, min + i, 1, MPI_DOUBLE, MPI_MIN, local_comm);

      d[i] = max[i] - min[i];
    }
  }

  return;
}
Exemple #2
0
static int compute_rib_direction(
  ZZ *zz, 
  int Tflops_Special,         /* Tflops_Special flag for special processing.
                                 Should be 0 when called by serial_rib. */
  int num_geom,               /* number of dimensions */
  double *valuelo,            /* smallest value of value[i] */
  double *valuehi,            /* largest value of value[i] */
  struct Dot_Struct *dotpt,   /* local dot array */
  int *dindx,                 /* index array into dotpt; if NULL, access dotpt
                                 directly */
  int dotnum,                 /* number of dots */
  int wgtflag,                /* (0) do not (1) do use weights.
                                 Multidimensional weights not supported */
  double *cm,                 /* Center of mass of objects */
  double *evec,               /* Eigenvector defining direction */
  double *value,              /* temp array for median_find; rotated coords */
  MPI_Comm local_comm,        /* MPI communicator for set */
  int proc,                   /* Current processor; needed for Tflops_Special */
  int nprocs,                 /* Number of procs in operation; needed for
                                 Tflops_Special */
  int proclower               /* Lowest numbered proc; needed for 
                                 Tflops_Special */
)
{
int i, ierr = 0;
double tmp;
RIB_STRUCT *rib;

  rib = (RIB_STRUCT *)zz->LB.Data_Structure;

  if (rib->Tran.Target_Dim > 0){ 
    num_geom = rib->Tran.Target_Dim; /* degenerate geometry */
  }

  switch (num_geom) {
  case 3:
    ierr = Zoltan_RIB_inertial3d(Tflops_Special, dotpt, dindx, dotnum, wgtflag, 
                                 cm, evec, value,
                                 local_comm, proc, nprocs, proclower);
    break;
  case 2:
    ierr = Zoltan_RIB_inertial2d(Tflops_Special, dotpt, dindx, dotnum, wgtflag, 
                                 cm, evec, value,
                                 local_comm, proc, nprocs, proclower);
    break;
  case 1:
    ierr = Zoltan_RIB_inertial1d(dotpt, dindx, dotnum, wgtflag,
                                 cm, evec, value);
    break;
  }
  *valuelo = DBL_MAX;
  *valuehi = -DBL_MAX;
  for (i = 0; i < dotnum; i++) {
    if (value[i] < *valuelo) *valuelo = value[i];
    if (value[i] > *valuehi) *valuehi = value[i];
  }
  if (Tflops_Special)
    Zoltan_RIB_min_max(valuelo, valuehi, proclower, proc, nprocs,
                       local_comm);
  else {
    tmp = *valuehi;
    MPI_Allreduce(&tmp, valuehi, 1, MPI_DOUBLE, MPI_MAX, local_comm);
    tmp = *valuelo;
    MPI_Allreduce(&tmp, valuelo, 1, MPI_DOUBLE, MPI_MIN, local_comm);
  }

  return ierr;
}