void Zoltan_Oct_child_bounds_wrapper(OCT_Global_Info *OCT_info, pOctant oct, COORD cmin[], COORD cmax[]) { int i, j; COORD min, max; COORD origin; /* get the bounds of an octant */ Zoltan_Oct_bounds(oct,min,max); /* calculate the origin from the bounds */ Zoltan_Oct_bounds_to_origin(min,max,origin); /* KDDKDD 3/01 Added special cases depending on OCT_info->OCT_dimension. * KDDKDD 3/01 When OCT_dimension == 2, Zoltan_Oct_convert_idx_to_map was called * KDDKDD 3/01 with values >= 4, which are not supported in the GRAY and * KDDKDD 3/01 HILBERT maps used in Zoltan_Oct_convert_idx_to_map. * KDDKDD 3/01 This change calls Zoltan_Oct_convert_idx_to_map with only valid * KDDKDD 3/01 values, and sets cmin and cmax so that the loop following * KDDKDD 3/01 the call to Zoltan_Oct_child_bounds_wrapper "continues" for children * KDDKDD 3/01 4-7, rather than initializing them. */ if (OCT_info->OCT_dimension == 3) { for(i=0; i<8; i++) { Zoltan_Oct_child_bounds(min, max, origin, Zoltan_Oct_convert_idx_to_map(OCT_info, oct->dir, i), cmin[i], cmax[i]); } } else if (OCT_info->OCT_dimension == 2) { for(i=0; i<4; i++) { Zoltan_Oct_child_bounds(min, max, origin, Zoltan_Oct_convert_idx_to_map(OCT_info, oct->dir, i), cmin[i], cmax[i]); } for(i=4; i<8; i++) { for(j=0;j<3;j++) { cmin[i][j] = DBL_MAX; cmax[i][j] = -DBL_MAX; } } } else { fprintf(stderr, "Zoltan_Oct_child_bounds_wrapper: Invalid OCT_dimension\n"); abort(); } }
int Zoltan_Oct_migreg_migrate_orphans(ZZ *zz, pRegion RegionList, int nregions, int level, Map *array, int *c1, int *c2) { int i, j, k; /* index counters */ pRegion ptr; /* region in the mesh */ COORD origin; /* centroid coordinate information */ pRegion *regions = NULL; /* an array of regions */ int *npids = NULL; Region *regions2 = NULL; /* an array of regions */ int *npids2 = NULL; int nreg; /* number of regions */ COORD min, /* minimum bounds of an octant */ max; /* maximum bounds of an octant */ COORD cmin, /* minimum bounds of a child octant */ cmax; /* maximum bounds of a child octant */ COORD rmin, /* minimum bounds of a remote octant */ rmax; /* maximum bounds of a remote octant */ int new_num; int n; int dir = 0; pRList RootList; pOctant RootOct; OCT_Global_Info *OCT_info = (OCT_Global_Info *)(zz->LB.Data_Structure); char *yo = "Zoltan_Oct_migreg_migrate_orphans_static"; int ierr = ZOLTAN_OK; ZOLTAN_ID_PTR gids2, lids2; int num_gid_entries = zz->Num_GID; int num_lid_entries = zz->Num_LID; if(nregions > 0) { /* create the array of messages to be sent to other processors */ /* Array = (Message *) ZOLTAN_MALLOC(nregions * sizeof(Message)); */ if((regions = (pRegion *) ZOLTAN_MALLOC(nregions * sizeof(pRegion))) == NULL) { ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Insufficient memory."); ZOLTAN_TRACE_EXIT(zz, yo); return ZOLTAN_MEMERR; } if((npids = (int *) ZOLTAN_MALLOC(nregions * sizeof(int))) == NULL) { ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Insufficient memory."); ZOLTAN_TRACE_EXIT(zz, yo); ZOLTAN_FREE(®ions); return ZOLTAN_MEMERR; } } ptr = RegionList; n = nreg = 0; while((ptr != NULL) && (nregions > 0)) { if(ptr->attached == 1) { /* if region already attached to an octant, then skip to next region */ ptr = ptr->next; continue; } /* region not attached, have to find which processor to send to */ j=0; dir = 0; vector_set(min, OCT_info->OCT_gmin); vector_set(max, OCT_info->OCT_gmax); /* * for each level of refinement, find which child region belongs to. * translate which child to which entry in map array. */ for(i=0; i<level; i++) { Zoltan_Oct_bounds_to_origin(min, max, origin); if(OCT_info->OCT_dimension == 2) j = j * 4; else j = j * 8; k = Zoltan_Oct_child_which(OCT_info,origin, ptr->Coord); new_num = Zoltan_Oct_convert_idx_from_map(OCT_info, dir, k); dir = Zoltan_Oct_get_child_dir(OCT_info, dir, new_num); j += new_num; Zoltan_Oct_child_bounds(min, max, origin, k, cmin, cmax); vector_set(min, cmin); vector_set(max, cmax); } /* inform message which processor to send to */ npids[n] = array[j].npid; RootList = array[j].list; while((RootOct = RL_nextRootOctant(&RootList))) { Zoltan_Oct_bounds(RootOct,rmin,rmax); if (Zoltan_Oct_in_box_closure(OCT_info, ptr->Coord ,rmin, rmax)) { npids[n] = RootOct->npid; break; } } if((npids[n] != -1) && (npids[n] != zz->Proc)) { Zoltan_Oct_copy_info(zz, ptr, &(regions[n++])); } else { Zoltan_Oct_insert_orphan(zz, *ptr); } nreg++; /* increment region counter */ ptr = ptr->next; /* look at next region */ } /* * if regions looked at != number of regions in region list, * then there is an error */ if (nreg!=nregions) { ZOLTAN_PRINT_ERROR(zz->Proc, yo, "regions found != to expected number of regions"); return ZOLTAN_FATAL; } regions2 = (Region *) ZOLTAN_MALLOC(n * sizeof(Region)); gids2 = ZOLTAN_MALLOC_GID_ARRAY(zz, n); lids2 = ZOLTAN_MALLOC_LID_ARRAY(zz, n); npids2 = (int *) ZOLTAN_MALLOC(n * sizeof(int)); for(i=0; i<n; i++) { npids2[i] = npids[i]; vector_set(regions2[i].Coord, regions[i]->Coord); regions2[i].Weight = regions[i]->Weight; regions2[i].Global_ID = &(gids2[i*num_gid_entries]); regions2[i].Local_ID = (num_lid_entries ? &(lids2[i*num_lid_entries]) : NULL); ZOLTAN_SET_GID(zz, &(gids2[i*num_gid_entries]), regions[i]->Global_ID); ZOLTAN_SET_LID(zz, &(lids2[i*num_lid_entries]), regions[i]->Local_ID); regions2[i].Proc = regions[i]->Proc; regions2[i].attached = 0; } *c1 = n; /* migrate the orphan regions according to the message array */ Zoltan_Oct_migreg_migrate_regions(zz, regions2, gids2, lids2, npids2, n, c2); for (i=0; i < n; i++) { ZOLTAN_FREE(&(regions[i]->Global_ID)); ZOLTAN_FREE(&(regions[i]->Local_ID)); ZOLTAN_FREE(&(regions[i])); } ZOLTAN_FREE(®ions); ZOLTAN_FREE(&npids); ZOLTAN_FREE(®ions2); ZOLTAN_FREE(&gids2); ZOLTAN_FREE(&lids2); ZOLTAN_FREE(&npids2); return ierr; }