void CartCellDoubleLinearCFInterpolation::computeNormalExtension( Patch<NDIM>& patch, const IntVector<NDIM>& ratio, const IntVector<NDIM>& /*ghost_width_to_fill*/) { #if !defined(NDEBUG) TBOX_ASSERT(d_hierarchy); TBOX_ASSERT(!d_consistent_type_2_bdry); TBOX_ASSERT(ratio.min() == ratio.max()); #endif // Ensure that the fine patch is located on the expected destination level; // if not, we are not guaranteed to have appropriate coarse-fine interface // boundary box information. if (!patch.inHierarchy()) return; // Get the co-dimension 1 cf boundary boxes. const int patch_num = patch.getPatchNumber(); const int patch_level_num = patch.getPatchLevelNumber(); #if !defined(NDEBUG) Pointer<PatchLevel<NDIM> > level = d_hierarchy->getPatchLevel(patch_level_num); TBOX_ASSERT(&patch == level->getPatch(patch_num).getPointer()); #endif const Array<BoundaryBox<NDIM> >& cf_bdry_codim1_boxes = d_cf_boundary[patch_level_num]->getBoundaries(patch_num, 1); const int n_cf_bdry_codim1_boxes = cf_bdry_codim1_boxes.size(); // Check to see if there are any co-dimension 1 coarse-fine boundary boxes // associated with the patch; if not, there is nothing to do. if (n_cf_bdry_codim1_boxes == 0) return; // Get the patch data. for (std::set<int>::const_iterator cit = d_patch_data_indices.begin(); cit != d_patch_data_indices.end(); ++cit) { const int& patch_data_index = *cit; Pointer<CellData<NDIM, double> > data = patch.getPatchData(patch_data_index); #if !defined(NDEBUG) TBOX_ASSERT(data); #endif const int U_ghosts = (data->getGhostCellWidth()).max(); #if !defined(NDEBUG) if (U_ghosts != (data->getGhostCellWidth()).min()) { TBOX_ERROR("CartCellDoubleLinearCFInterpolation::computeNormalExtension():\n" << " patch data does not have uniform ghost cell widths" << std::endl); } #endif const int data_depth = data->getDepth(); const IntVector<NDIM> ghost_width_to_fill = GHOST_WIDTH_TO_FILL; Pointer<CartesianPatchGeometry<NDIM> > pgeom = patch.getPatchGeometry(); const Box<NDIM>& patch_box = patch.getBox(); for (int k = 0; k < n_cf_bdry_codim1_boxes; ++k) { const BoundaryBox<NDIM>& bdry_box = cf_bdry_codim1_boxes[k]; const Box<NDIM> bc_fill_box = pgeom->getBoundaryFillBox(bdry_box, patch_box, ghost_width_to_fill); const unsigned int location_index = bdry_box.getLocationIndex(); for (int depth = 0; depth < data_depth; ++depth) { double* const U = data->getPointer(depth); const int r = ratio.min(); CC_LINEAR_NORMAL_INTERPOLATION_FC(U, U_ghosts, patch_box.lower(0), patch_box.upper(0), patch_box.lower(1), patch_box.upper(1), #if (NDIM == 3) patch_box.lower(2), patch_box.upper(2), #endif location_index, r, bc_fill_box.lower(), bc_fill_box.upper()); } } } return; } // computeNormalExtension
void BoxLevelStatistics::computeLocalBoxLevelStatistics(const BoxLevel& box_level) { box_level.cacheGlobalReducedData(); /* * Compute per-processor statistics. Some quantities are readily * available while others are computed in the loop following. * * Aspect ratio uses a generalized formula that goes to 1 when box * has same length on all sides (regardless of dimension), * degenerates to the rectangular aspect ratio in 2D, and grows * appropriately for dimensions higher than 2. */ d_sq.d_values[HAS_ANY_BOX] = (box_level.getLocalNumberOfBoxes() > 0); d_sq.d_values[NUMBER_OF_CELLS] = static_cast<double>(box_level.getLocalNumberOfCells()); d_sq.d_values[NUMBER_OF_BOXES] = static_cast<double>(box_level.getLocalNumberOfBoxes()); d_sq.d_values[MAX_BOX_VOL] = 0; d_sq.d_values[MIN_BOX_VOL] = tbox::MathUtilities<double>::getMax(); d_sq.d_values[MAX_BOX_LEN] = 0; d_sq.d_values[MIN_BOX_LEN] = tbox::MathUtilities<double>::getMax(); d_sq.d_values[MAX_ASPECT_RATIO] = 0; d_sq.d_values[SUM_ASPECT_RATIO] = 0; d_sq.d_values[SUM_SURFACE_AREA] = 0.; d_sq.d_values[SUM_NORM_SURFACE_AREA] = 0.; const BoxContainer& boxes = box_level.getBoxes(); for (RealBoxConstIterator ni(boxes.realBegin()); ni != boxes.realEnd(); ++ni) { const Box& box = *ni; const IntVector boxdims = box.numberCells(); const double boxvol = static_cast<double>(boxdims.getProduct()); const int longdim = boxdims.max(); const int shortdim = boxdims.min(); double aspect_ratio = 0.0; double surfarea = 0.; for (int d = 0; d < d_dim.getValue(); ++d) { surfarea += 2 * double(boxvol) / boxdims(d); double tmp = static_cast<double>(boxdims(d)) / shortdim - 1.0; aspect_ratio += tmp * tmp; } aspect_ratio = 1.0 + sqrt(aspect_ratio); d_sq.d_values[MAX_BOX_VOL] = tbox::MathUtilities<double>::Max(d_sq.d_values[MAX_BOX_VOL], boxvol); d_sq.d_values[MIN_BOX_VOL] = tbox::MathUtilities<double>::Min(d_sq.d_values[MIN_BOX_VOL], boxvol); d_sq.d_values[MAX_BOX_LEN] = tbox::MathUtilities<double>::Max(d_sq.d_values[MAX_BOX_LEN], longdim); d_sq.d_values[MIN_BOX_LEN] = tbox::MathUtilities<double>::Min(d_sq.d_values[MIN_BOX_LEN], shortdim); d_sq.d_values[MAX_ASPECT_RATIO] = tbox::MathUtilities<double>::Max(d_sq.d_values[MAX_ASPECT_RATIO], aspect_ratio); d_sq.d_values[SUM_ASPECT_RATIO] += aspect_ratio; d_sq.d_values[SUM_SURFACE_AREA] += surfarea; } /* * Smallest surface area possible for the number of cells perfectly * distributed in d_mpi. */ const double ideal_surfarea = 2 * d_dim.getValue() * pow(double(box_level.getGlobalNumberOfCells()) / d_mpi.getSize(), double(d_dim.getValue() - 1) / d_dim.getValue()); d_sq.d_values[SUM_NORM_SURFACE_AREA] = d_sq.d_values[SUM_SURFACE_AREA] / ideal_surfarea; }