void CartCellDoubleCubicCoarsen::coarsen(Patch<NDIM>& coarse,
                                         const Patch<NDIM>& fine,
                                         const int dst_component,
                                         const int src_component,
                                         const Box<NDIM>& coarse_box,
                                         const IntVector<NDIM>& ratio) const
{
    if (ratio.min() < 4)
    {
        IBTK_DO_ONCE(TBOX_WARNING("CartCellDoubleCubicCoarsen::coarsen():\n"
                                  << "  cubic coarsening requires a refinement ratio of 4 or larger.\n"
                                  << "  reverting to weighted averaging." << std::endl););
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
Exemplo n.º 3
0
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;

}