예제 #1
0
dcomplex
PatchFaceDataNormOpsComplex::dot(
   const std::shared_ptr<pdat::FaceData<dcomplex> >& data1,
   const std::shared_ptr<pdat::FaceData<dcomplex> >& data2,
   const hier::Box& box,
   const std::shared_ptr<pdat::FaceData<double> >& cvol) const
{
   TBOX_ASSERT(data1 && data2);

   tbox::Dimension::dir_t dimVal = box.getDim().getValue();

   dcomplex retval = dcomplex(0.0, 0.0);
   if (!cvol) {
      for (tbox::Dimension::dir_t d = 0; d < dimVal; ++d) {
         const hier::Box face_box = pdat::FaceGeometry::toFaceBox(box, d);
         retval += d_array_ops.dot(data1->getArrayData(d),
               data2->getArrayData(d),
               face_box);
      }
   } else {
      for (tbox::Dimension::dir_t d = 0; d < dimVal; ++d) {
         const hier::Box face_box = pdat::FaceGeometry::toFaceBox(box, d);
         retval += d_array_ops.dotWithControlVolume(
               data1->getArrayData(d),
               data2->getArrayData(d),
               cvol->getArrayData(d),
               face_box);
      }
   }
   return retval;
}
예제 #2
0
dcomplex
PatchSideDataNormOpsComplex::integral(
   const boost::shared_ptr<pdat::SideData<dcomplex> >& data,
   const hier::Box& box,
   const boost::shared_ptr<pdat::SideData<double> >& vol) const
{
   TBOX_ASSERT(data);

   int dimVal = box.getDim().getValue();
   dcomplex retval = dcomplex(0.0, 0.0);
   const hier::IntVector& directions = data->getDirectionVector();

   TBOX_ASSERT(directions ==
      hier::IntVector::min(directions, vol->getDirectionVector()));

   for (tbox::Dimension::dir_t d = 0; d < dimVal; ++d) {
      if (directions(d)) {
         retval += d_array_ops.integral(
               data->getArrayData(d),
               vol->getArrayData(d),
               pdat::SideGeometry::toSideBox(box, d));
      }
   }
   return retval;
}
예제 #3
0
double
PatchFaceDataNormOpsComplex::maxNorm(
   const std::shared_ptr<pdat::FaceData<dcomplex> >& data,
   const hier::Box& box,
   const std::shared_ptr<pdat::FaceData<double> >& cvol) const
{
   TBOX_ASSERT(data);

   tbox::Dimension::dir_t dimVal = box.getDim().getValue();

   double retval = 0.0;
   if (!cvol) {
      for (tbox::Dimension::dir_t d = 0; d < dimVal; ++d) {
         const hier::Box face_box =
            pdat::FaceGeometry::toFaceBox(box, d);
         retval = tbox::MathUtilities<double>::Max(retval,
               d_array_ops.maxNorm(data->getArrayData(d), face_box));
      }
   } else {
      for (tbox::Dimension::dir_t d = 0; d < dimVal; ++d) {
         const hier::Box face_box =
            pdat::FaceGeometry::toFaceBox(box, d);
         retval = tbox::MathUtilities<double>::Max(retval,
               d_array_ops.maxNormWithControlVolume(
                  data->getArrayData(d), cvol->getArrayData(d), face_box));
      }
   }
   return retval;
}
예제 #4
0
double
PatchFaceDataNormOpsComplex::L1Norm(
   const std::shared_ptr<pdat::FaceData<dcomplex> >& data,
   const hier::Box& box,
   const std::shared_ptr<pdat::FaceData<double> >& cvol) const
{
   TBOX_ASSERT(data);
   TBOX_ASSERT_OBJDIM_EQUALITY2(*data, box);

   tbox::Dimension::dir_t dimVal = box.getDim().getValue();

   double retval = 0.0;
   if (!cvol) {
      for (tbox::Dimension::dir_t d = 0; d < dimVal; ++d) {
         const hier::Box face_box = pdat::FaceGeometry::toFaceBox(box, d);
         retval += d_array_ops.L1Norm(data->getArrayData(d), face_box);
      }
   } else {
      TBOX_ASSERT_OBJDIM_EQUALITY2(*data, *cvol);

      for (tbox::Dimension::dir_t d = 0; d < dimVal; ++d) {
         const hier::Box face_box = pdat::FaceGeometry::toFaceBox(box, d);
         retval += d_array_ops.L1NormWithControlVolume(data->getArrayData(d),
               cvol->getArrayData(d),
               face_box);
      }
   }
   return retval;
}
예제 #5
0
NodeIterator::NodeIterator(
   const hier::Box& box,
   bool begin):
   d_index(box.lower(), hier::IntVector::getZero(box.getDim())),
   d_box(NodeGeometry::toNodeBox(box))
{
   if (!d_box.empty() && !begin) {
      d_index(d_box.getDim().getValue() - 1) =
         d_box.upper(static_cast<tbox::Dimension::dir_t>(d_box.getDim().getValue() - 1)) + 1;
   }
}
/*
 *************************************************************************
 *
 * Compute the boxes for the stencil around a given patch box
 *
 *************************************************************************
 */
void
FirstLayerCellVariableFillPattern::computeStencilBoxes(
   hier::BoxContainer& stencil_boxes,
   const hier::Box& dst_box) const
{
   TBOX_ASSERT(stencil_boxes.size() == 0);

   hier::Box ghost_box(
      hier::Box::grow(dst_box,
         hier::IntVector::getOne(dst_box.getDim())));
   stencil_boxes.removeIntersections(ghost_box, dst_box);
}
예제 #7
0
void
PatchFaceDataNormOpsComplex::abs(
   const std::shared_ptr<pdat::FaceData<double> >& dst,
   const std::shared_ptr<pdat::FaceData<dcomplex> >& src,
   const hier::Box& box) const
{
   TBOX_ASSERT(dst && src);
   TBOX_ASSERT_OBJDIM_EQUALITY3(*dst, *src, box);

   tbox::Dimension::dir_t dimVal = box.getDim().getValue();
   for (tbox::Dimension::dir_t d = 0; d < dimVal; ++d) {
      d_array_ops.abs(dst->getArrayData(d),
         src->getArrayData(d),
         pdat::FaceGeometry::toFaceBox(box, d));
   }
}
예제 #8
0
double
PatchSideDataNormOpsComplex::weightedL2Norm(
   const boost::shared_ptr<pdat::SideData<dcomplex> >& data,
   const boost::shared_ptr<pdat::SideData<dcomplex> >& weight,
   const hier::Box& box,
   const boost::shared_ptr<pdat::SideData<double> >& cvol) const
{
   TBOX_ASSERT(data && weight);
   TBOX_ASSERT_OBJDIM_EQUALITY3(*data, *weight, box);

   int dimVal = box.getDim().getValue();

   double retval = 0.0;
   const hier::IntVector& directions = data->getDirectionVector();

   TBOX_ASSERT(directions ==
      hier::IntVector::min(directions, weight->getDirectionVector()));

   if (!cvol) {
      for (tbox::Dimension::dir_t d = 0; d < dimVal; ++d) {
         if (directions(d)) {
            const hier::Box side_box = pdat::SideGeometry::toSideBox(box, d);
            double aval = d_array_ops.weightedL2Norm(data->getArrayData(d),
                  weight->getArrayData(d),
                  side_box);
            retval += aval * aval;
         }
      }
   } else {
      TBOX_ASSERT(directions ==
         hier::IntVector::min(directions, cvol->getDirectionVector()));
      TBOX_ASSERT_OBJDIM_EQUALITY2(*data, *cvol);

      for (tbox::Dimension::dir_t d = 0; d < dimVal; ++d) {
         if (directions(d)) {
            const hier::Box side_box = pdat::SideGeometry::toSideBox(box, d);
            double aval = d_array_ops.weightedL2NormWithControlVolume(
                  data->getArrayData(d),
                  weight->getArrayData(d),
                  cvol->getArrayData(d),
                  side_box);
            retval += aval * aval;
         }
      }
   }
   return sqrt(retval);
}
예제 #9
0
double
PatchFaceDataNormOpsComplex::sumControlVolumes(
   const std::shared_ptr<pdat::FaceData<dcomplex> >& data,
   const std::shared_ptr<pdat::FaceData<double> >& cvol,
   const hier::Box& box) const
{
   TBOX_ASSERT(data && cvol);

   tbox::Dimension::dir_t dimVal = box.getDim().getValue();
   double retval = 0.0;
   for (tbox::Dimension::dir_t d = 0; d < dimVal; ++d) {
      retval += d_array_ops.sumControlVolumes(data->getArrayData(d),
            cvol->getArrayData(d),
            pdat::FaceGeometry::toFaceBox(box, d));
   }
   return retval;
}
예제 #10
0
int
PatchFaceDataNormOpsComplex::numberOfEntries(
   const std::shared_ptr<pdat::FaceData<dcomplex> >& data,
   const hier::Box& box) const
{
   TBOX_ASSERT(data);
   TBOX_ASSERT_OBJDIM_EQUALITY2(*data, box);

   tbox::Dimension::dir_t dimVal = box.getDim().getValue();
   int retval = 0;
   const hier::Box ibox = box * data->getGhostBox();
   const int data_depth = data->getDepth();
   for (tbox::Dimension::dir_t d = 0; d < dimVal; ++d) {
      retval += static_cast<int>((pdat::FaceGeometry::toFaceBox(ibox, d).size()) * data_depth);
   }
   return retval;
}
예제 #11
0
dcomplex
PatchFaceDataNormOpsComplex::integral(
   const std::shared_ptr<pdat::FaceData<dcomplex> >& data,
   const hier::Box& box,
   const std::shared_ptr<pdat::FaceData<double> >& vol) const
{
   TBOX_ASSERT(data);

   tbox::Dimension::dir_t dimVal = box.getDim().getValue();
   dcomplex retval = dcomplex(0.0, 0.0);
   for (tbox::Dimension::dir_t d = 0; d < dimVal; ++d) {
      retval += d_array_ops.integral(data->getArrayData(d),
            vol->getArrayData(d),
            pdat::FaceGeometry::toFaceBox(box, d));
   }
   return retval;
}
예제 #12
0
void
PatchSideDataOpsComplex::copyData(
   const std::shared_ptr<pdat::SideData<dcomplex> >& dst,
   const std::shared_ptr<pdat::SideData<dcomplex> >& src,
   const hier::Box& box) const
{
   TBOX_ASSERT(dst && src);
   TBOX_ASSERT(dst->getDirectionVector() == src->getDirectionVector());
   TBOX_ASSERT_OBJDIM_EQUALITY3(*dst, *src, box);

   int dimVal = box.getDim().getValue();
   const hier::IntVector& directions = dst->getDirectionVector();
   for (tbox::Dimension::dir_t d = 0; d < dimVal; ++d) {
      if (directions(d)) {
         dst->getArrayData(d).copy(src->getArrayData(d),
            pdat::SideGeometry::toSideBox(box, d));
      }
   }
}
예제 #13
0
size_t
PatchSideDataNormOpsReal<TYPE>::numberOfEntries(
   const boost::shared_ptr<pdat::SideData<TYPE> >& data,
   const hier::Box& box) const
{
   TBOX_ASSERT(data);
   TBOX_ASSERT_OBJDIM_EQUALITY2(*data, box);

   tbox::Dimension::dir_t dimVal = box.getDim().getValue();

   size_t retval = 0;
   const hier::Box ibox = box * data->getGhostBox();
   const hier::IntVector& directions = data->getDirectionVector();
   for (tbox::Dimension::dir_t d = 0; d < dimVal; ++d) {
      if (directions(d)) {
         const hier::Box dbox = pdat::SideGeometry::toSideBox(ibox, d);
         retval += (dbox.size() * data->getDepth());
      }
   }
   return retval;
}
예제 #14
0
dcomplex
PatchSideDataNormOpsComplex::dot(
   const boost::shared_ptr<pdat::SideData<dcomplex> >& data1,
   const boost::shared_ptr<pdat::SideData<dcomplex> >& data2,
   const hier::Box& box,
   const boost::shared_ptr<pdat::SideData<double> >& cvol) const
{
   TBOX_ASSERT(data1 && data2);
   TBOX_ASSERT(data1->getDirectionVector() == data2->getDirectionVector());

   int dimVal = box.getDim().getValue();

   dcomplex retval = dcomplex(0.0, 0.0);
   const hier::IntVector& directions = data1->getDirectionVector();
   if (!cvol) {
      for (tbox::Dimension::dir_t d = 0; d < dimVal; ++d) {
         if (directions(d)) {
            const hier::Box side_box = pdat::SideGeometry::toSideBox(box, d);
            retval += d_array_ops.dot(data1->getArrayData(d),
                  data2->getArrayData(d),
                  side_box);
         }
      }
   } else {
      TBOX_ASSERT(directions ==
         hier::IntVector::min(directions, cvol->getDirectionVector()));

      for (tbox::Dimension::dir_t d = 0; d < dimVal; ++d) {
         if (directions(d)) {
            const hier::Box side_box = pdat::SideGeometry::toSideBox(box, d);
            retval += d_array_ops.dotWithControlVolume(
                  data1->getArrayData(d),
                  data2->getArrayData(d),
                  cvol->getArrayData(d),
                  side_box);
         }
      }
   }
   return retval;
}
/*
 *************************************************************************
 *
 * Compute BoxOverlap that specifies data to be filled by refinement
 * operator.
 *
 *************************************************************************
 */
std::shared_ptr<hier::BoxOverlap>
FirstLayerCellVariableFillPattern::computeFillBoxesOverlap(
   const hier::BoxContainer& fill_boxes,
   const hier::BoxContainer& node_fill_boxes,
   const hier::Box& patch_box,
   const hier::Box& data_box,
   const hier::PatchDataFactory& pdf) const
{
   NULL_USE(pdf);
   NULL_USE(node_fill_boxes);

   hier::BoxContainer stencil_boxes;
   computeStencilBoxes(stencil_boxes, patch_box);

   hier::BoxContainer overlap_boxes(fill_boxes);
   overlap_boxes.intersectBoxes(data_box);
   overlap_boxes.intersectBoxes(stencil_boxes);

   return std::make_shared<CellOverlap>(
             overlap_boxes,
             hier::Transformation(hier::IntVector::getZero(patch_box.getDim())));
}
예제 #16
0
double
PatchSideDataNormOpsComplex::maxNorm(
   const boost::shared_ptr<pdat::SideData<dcomplex> >& data,
   const hier::Box& box,
   const boost::shared_ptr<pdat::SideData<double> >& cvol) const
{
   TBOX_ASSERT(data);

   int dimVal = box.getDim().getValue();

   double retval = 0.0;
   const hier::IntVector& directions = data->getDirectionVector();
   if (!cvol) {
      for (tbox::Dimension::dir_t d = 0; d < dimVal; ++d) {
         if (directions(d)) {
            const hier::Box side_box =
               pdat::SideGeometry::toSideBox(box, d);
            retval = tbox::MathUtilities<double>::Max(retval,
                  d_array_ops.maxNorm(data->getArrayData(d), side_box));
         }
      }
   } else {
      TBOX_ASSERT(directions ==
         hier::IntVector::min(directions, cvol->getDirectionVector()));

      for (tbox::Dimension::dir_t d = 0; d < dimVal; ++d) {
         if (directions(d)) {
            const hier::Box side_box =
               pdat::SideGeometry::toSideBox(box, d);
            retval = tbox::MathUtilities<double>::Max(retval,
                  d_array_ops.maxNormWithControlVolume(
                     data->getArrayData(d),
                     cvol->getArrayData(d), side_box));
         }
      }
   }
   return retval;
}
예제 #17
0
double
PatchSideDataNormOpsComplex::sumControlVolumes(
   const boost::shared_ptr<pdat::SideData<dcomplex> >& data,
   const boost::shared_ptr<pdat::SideData<double> >& cvol,
   const hier::Box& box) const
{
   TBOX_ASSERT(data && cvol);

   double retval = 0.0;
   const hier::IntVector& directions = data->getDirectionVector();

   TBOX_ASSERT(directions ==
      hier::IntVector::min(directions, cvol->getDirectionVector()));

   int dimVal = box.getDim().getValue();
   for (tbox::Dimension::dir_t d = 0; d < dimVal; ++d) {
      if (directions(d)) {
         retval += d_array_ops.sumControlVolumes(data->getArrayData(d),
               cvol->getArrayData(d),
               pdat::SideGeometry::toSideBox(box, d));
      }
   }
   return retval;
}
void
CellComplexLinearTimeInterpolateOp::timeInterpolate(
   hier::PatchData& dst_data,
   const hier::Box& where,
   const hier::PatchData& src_data_old,
   const hier::PatchData& src_data_new) const
{
   const tbox::Dimension& dim(where.getDim());

   const CellData<dcomplex>* old_dat =
      CPP_CAST<const CellData<dcomplex> *>(&src_data_old);
   const CellData<dcomplex>* new_dat =
      CPP_CAST<const CellData<dcomplex> *>(&src_data_new);
   CellData<dcomplex>* dst_dat =
      CPP_CAST<CellData<dcomplex> *>(&dst_data);

   TBOX_ASSERT(old_dat != 0);
   TBOX_ASSERT(new_dat != 0);
   TBOX_ASSERT(dst_dat != 0);
   TBOX_ASSERT((where * old_dat->getGhostBox()).isSpatiallyEqual(where));
   TBOX_ASSERT((where * new_dat->getGhostBox()).isSpatiallyEqual(where));
   TBOX_ASSERT((where * dst_dat->getGhostBox()).isSpatiallyEqual(where));
   TBOX_ASSERT_OBJDIM_EQUALITY4(dst_data, where, src_data_old, src_data_new);

   const hier::Index& old_ilo = old_dat->getGhostBox().lower();
   const hier::Index& old_ihi = old_dat->getGhostBox().upper();
   const hier::Index& new_ilo = new_dat->getGhostBox().lower();
   const hier::Index& new_ihi = new_dat->getGhostBox().upper();

   const hier::Index& dst_ilo = dst_dat->getGhostBox().lower();
   const hier::Index& dst_ihi = dst_dat->getGhostBox().upper();

   const hier::Index& ifirst = where.lower();
   const hier::Index& ilast = where.upper();

   const double old_time = old_dat->getTime();
   const double new_time = new_dat->getTime();
   const double dst_time = dst_dat->getTime();

   TBOX_ASSERT((old_time < dst_time ||
                tbox::MathUtilities<double>::equalEps(old_time, dst_time)) &&
      (dst_time < new_time ||
       tbox::MathUtilities<double>::equalEps(dst_time, new_time)));

   double tfrac = dst_time - old_time;
   double denom = new_time - old_time;
   if (denom > tbox::MathUtilities<double>::getMin()) {
      tfrac /= denom;
   } else {
      tfrac = 0.0;
   }

   for (int d = 0; d < dst_dat->getDepth(); ++d) {
      if (dim == tbox::Dimension(1)) {
         SAMRAI_F77_FUNC(lintimeintcellcmplx1d, LINTIMEINTCELLCMPLX1D) (ifirst(0),
            ilast(0),
            old_ilo(0), old_ihi(0),
            new_ilo(0), new_ihi(0),
            dst_ilo(0), dst_ihi(0),
            tfrac,
            old_dat->getPointer(d),
            new_dat->getPointer(d),
            dst_dat->getPointer(d));
      } else if (dim == tbox::Dimension(2)) {
         SAMRAI_F77_FUNC(lintimeintcellcmplx2d, LINTIMEINTCELLCMPLX2D) (ifirst(0),
            ifirst(1), ilast(0), ilast(1),
            old_ilo(0), old_ilo(1), old_ihi(0), old_ihi(1),
            new_ilo(0), new_ilo(1), new_ihi(0), new_ihi(1),
            dst_ilo(0), dst_ilo(1), dst_ihi(0), dst_ihi(1),
            tfrac,
            old_dat->getPointer(d),
            new_dat->getPointer(d),
            dst_dat->getPointer(d));
      } else if (dim == tbox::Dimension(3)) {
         SAMRAI_F77_FUNC(lintimeintcellcmplx3d, LINTIMEINTCELLCMPLX3D) (ifirst(0),
            ifirst(1), ifirst(2),
            ilast(0), ilast(1), ilast(2),
            old_ilo(0), old_ilo(1), old_ilo(2),
            old_ihi(0), old_ihi(1), old_ihi(2),
            new_ilo(0), new_ilo(1), new_ilo(2),
            new_ihi(0), new_ihi(1), new_ihi(2),
            dst_ilo(0), dst_ilo(1), dst_ilo(2),
            dst_ihi(0), dst_ihi(1), dst_ihi(2),
            tfrac,
            old_dat->getPointer(d),
            new_dat->getPointer(d),
            dst_dat->getPointer(d));
      } else {
         TBOX_ERROR(
            "CellComplexLinearTimeInterpolateOp::TimeInterpolate dim > 3 not supported"
            << std::endl);
      }

   }
}
예제 #19
0
boost::shared_ptr<hier::BoxOverlap>
OuterfaceGeometry::doOverlap(
   const OuterfaceGeometry& dst_geometry,
   const OuterfaceGeometry& src_geometry,
   const hier::Box& src_mask,
   const hier::Box& fill_box,
   const bool overwrite_interior,
   const hier::Transformation& transformation,
   const hier::BoxContainer& dst_restrict_boxes)
{
   const tbox::Dimension& dim(src_mask.getDim());

   std::vector<hier::BoxContainer> dst_boxes(dim.getValue());

   // Perform a quick-and-dirty intersection to see if the boxes might overlap

   hier::Box src_box(src_geometry.d_box);
   src_box.grow(src_geometry.d_ghosts);
   src_box = src_box * src_mask;
   transformation.transform(src_box);
   hier::Box dst_ghost(dst_geometry.getBox());
   dst_ghost.grow(dst_geometry.getGhosts());

   // Compute the intersection (if any) for each of the face directions

   const hier::IntVector one_vector(dim, 1);

   const hier::Box quick_check(
      hier::Box::grow(src_box, one_vector) * hier::Box::grow(dst_ghost,
         one_vector));

   if (!quick_check.empty()) {

      hier::Box mask_shift(src_mask);
      transformation.transform(mask_shift);

      for (tbox::Dimension::dir_t d = 0; d < dim.getValue(); ++d) {

         const hier::Box dst_face(
            FaceGeometry::toFaceBox(dst_geometry.getBox(), d));
         const hier::Box src_face(
            FaceGeometry::toFaceBox(src_box, d));
         const hier::Box fill_face(
            FaceGeometry::toFaceBox(fill_box, d));

         const hier::Box together(dst_face * src_face * fill_face);

         if (!together.empty()) {

            const hier::Box msk_face(
               FaceGeometry::toFaceBox(mask_shift, d));

            hier::Box low_dst_face(dst_face);
            low_dst_face.setUpper(0, low_dst_face.lower(0));
            hier::Box hig_dst_face(dst_face);
            hig_dst_face.setLower(0, hig_dst_face.upper(0));

            // Add lower face intersection (if any) to the box list
            hier::Box low_src_face(src_face);
            low_src_face.setUpper(0, low_src_face.lower(0));

            hier::Box low_low_overlap(low_src_face * msk_face * low_dst_face);
            if (!low_low_overlap.empty()) {
               dst_boxes[d].pushBack(low_low_overlap);
            }

            hier::Box low_hig_overlap(low_src_face * msk_face * hig_dst_face);
            if (!low_hig_overlap.empty()) {
               dst_boxes[d].pushBack(low_hig_overlap);
            }

            // Add upper face intersection (if any) to the box list
            hier::Box hig_src_face(src_face);
            hig_src_face.setLower(0, hig_src_face.upper(0));  //-ghosts;

            hier::Box hig_low_overlap(hig_src_face * msk_face * low_dst_face);
            if (!hig_low_overlap.empty()) {
               dst_boxes[d].pushBack(hig_low_overlap);
            }

            hier::Box hig_hig_overlap(hig_src_face * msk_face * hig_dst_face);
            if (!hig_hig_overlap.empty()) {
               dst_boxes[d].pushBack(hig_hig_overlap);
            }

            // Take away the interior of over_write interior is not set
            if (!overwrite_interior) {
               dst_boxes[d].removeIntersections(
                  FaceGeometry::toFaceBox(dst_geometry.getBox(), d));
            }

         }  // if (!together.empty())

         if (!dst_restrict_boxes.empty() && !dst_boxes[d].empty()) {
            hier::BoxContainer face_restrict_boxes;
            for (hier::BoxContainer::const_iterator b = dst_restrict_boxes.begin();
                 b != dst_restrict_boxes.end(); ++b) {
               face_restrict_boxes.pushBack(FaceGeometry::toFaceBox(*b, d));
            }
            dst_boxes[d].intersectBoxes(face_restrict_boxes);
         }

         dst_boxes[d].coalesce();

      }  // loop over dim

   } // if (!quick_check.empty())

   // Create the face overlap data object using the boxes and source shift

   return boost::make_shared<FaceOverlap>(dst_boxes, transformation);
}
예제 #20
0
void EdgeMultiblockTest::fillSingularityBoundaryConditions(
   hier::Patch& patch,
   const hier::PatchLevel& encon_level,
   std::shared_ptr<const hier::Connector> dst_to_encon,
   const hier::Box& fill_box,
   const hier::BoundaryBox& bbox,
   const std::shared_ptr<hier::BaseGridGeometry>& grid_geometry)
{
   const tbox::Dimension& dim = fill_box.getDim();

   const hier::BoxId& dst_mb_id = patch.getBox().getBoxId();

   const hier::BlockId& patch_blk_id = patch.getBox().getBlockId();

   for (int i = 0; i < static_cast<int>(d_variables.size()); ++i) {

      std::shared_ptr<pdat::EdgeData<double> > edge_data(
         SAMRAI_SHARED_PTR_CAST<pdat::EdgeData<double>, hier::PatchData>(
            patch.getPatchData(d_variables[i], getDataContext())));
      TBOX_ASSERT(edge_data);

      hier::Box sing_fill_box(edge_data->getGhostBox() * fill_box);

      int depth = edge_data->getDepth();

      for (int axis = 0; axis < d_dim.getValue(); ++axis) {
         hier::Box pbox = pdat::EdgeGeometry::toEdgeBox(patch.getBox(), axis);

         hier::Index plower(pbox.lower());
         hier::Index pupper(pbox.upper());

         pdat::EdgeIterator niend(pdat::EdgeGeometry::end(sing_fill_box, axis));
         for (pdat::EdgeIterator ni(pdat::EdgeGeometry::begin(sing_fill_box, axis));
              ni != niend; ++ni) {
            bool use_index = true;
            for (tbox::Dimension::dir_t n = 0; n < d_dim.getValue(); ++n) {
               if (axis != n && bbox.getBox().numberCells(n) == 1) {
                  if ((*ni)(n) == plower(n) || (*ni)(n) == pupper(n)) {
                     use_index = false;
                     break;
                  }
               }
            }
            if (use_index) {
               for (int d = 0; d < depth; ++d) {
                  (*edge_data)(*ni, d) = 0.0;
               }
            }
         }
      }

      int num_encon_used = 0;

      if (grid_geometry->hasEnhancedConnectivity()) {

         hier::Connector::ConstNeighborhoodIterator ni =
            dst_to_encon->findLocal(dst_mb_id);

         if (ni != dst_to_encon->end()) {

            for (hier::Connector::ConstNeighborIterator ei = dst_to_encon->begin(ni);
                 ei != dst_to_encon->end(ni); ++ei) {

               const hier::BlockId& encon_blk_id = ei->getBlockId();
               std::shared_ptr<hier::Patch> encon_patch(
                  encon_level.getPatch(ei->getBoxId()));

               hier::Transformation::RotationIdentifier rotation =
                  hier::Transformation::NO_ROTATE;
               hier::IntVector offset(dim);

               hier::BaseGridGeometry::ConstNeighborIterator itr =
                  grid_geometry->find(patch_blk_id, encon_blk_id);
               if (itr != grid_geometry->end(patch_blk_id)) {
                  rotation = (*itr).getRotationIdentifier();
                  offset = (*itr).getShift(encon_level.getLevelNumber());
               }

               hier::Transformation transformation(rotation, offset,
                                                   encon_blk_id,
                                                   patch_blk_id);
               hier::Box encon_patch_box(encon_patch->getBox());
               transformation.transform(encon_patch_box);

               hier::Box encon_fill_box(encon_patch_box * sing_fill_box);
               if (!encon_fill_box.empty()) {

                  const hier::Transformation::RotationIdentifier back_rotate =
                     hier::Transformation::getReverseRotationIdentifier(
                        rotation, dim);

                  hier::IntVector back_shift(dim);

                  hier::Transformation::calculateReverseShift(
                     back_shift, offset, rotation);

                  hier::Transformation back_trans(back_rotate, back_shift,
                                                  patch_blk_id,
                                                  encon_blk_id);

                  std::shared_ptr<pdat::EdgeData<double> > sing_data(
                     SAMRAI_SHARED_PTR_CAST<pdat::EdgeData<double>, hier::PatchData>(
                        encon_patch->getPatchData(
                           d_variables[i], getDataContext())));
                  TBOX_ASSERT(sing_data);

                  for (int axis = 0; axis < d_dim.getValue(); ++axis) {

                     hier::Box pbox(
                        pdat::EdgeGeometry::toEdgeBox(patch.getBox(), axis));

                     hier::Index plower(pbox.lower());
                     hier::Index pupper(pbox.upper());

                     pdat::EdgeIterator ciend(pdat::EdgeGeometry::end(sing_fill_box, axis));
                     for (pdat::EdgeIterator ci(pdat::EdgeGeometry::begin(sing_fill_box, axis));
                          ci != ciend; ++ci) {
                        bool use_index = true;
                        for (tbox::Dimension::dir_t n = 0; n < d_dim.getValue(); ++n) {
                           if (axis != n && bbox.getBox().numberCells(n) == 1) {
                              if ((*ci)(n) == plower(n) || (*ci)(n) == pupper(n)) {
                                 use_index = false;
                                 break;
                              }
                           }
                        }
                        if (use_index) {

                           pdat::EdgeIndex src_index(*ci);
                           pdat::EdgeGeometry::transform(src_index, back_trans);

                           for (int d = 0; d < depth; ++d) {
                              (*edge_data)(*ci, d) += (*sing_data)(src_index, d);
                           }
                        }
                     }
                  }

                  ++num_encon_used;
               }
            }
         }

      }

      if (num_encon_used) {

         for (int axis = 0; axis < d_dim.getValue(); ++axis) {

            hier::Box pbox =
               pdat::EdgeGeometry::toEdgeBox(patch.getBox(), axis);

            hier::Index plower(pbox.lower());
            hier::Index pupper(pbox.upper());

            pdat::EdgeIterator ciend(pdat::EdgeGeometry::end(sing_fill_box, axis));
            for (pdat::EdgeIterator ci(pdat::EdgeGeometry::begin(sing_fill_box, axis));
                 ci != ciend; ++ci) {
               bool use_index = true;
               for (tbox::Dimension::dir_t n = 0; n < d_dim.getValue(); ++n) {
                  if (axis != n && bbox.getBox().numberCells(n) == 1) {
                     if ((*ci)(n) == plower(n) || (*ci)(n) == pupper(n)) {
                        use_index = false;
                        break;
                     }
                  }
               }
               if (use_index) {
                  for (int d = 0; d < depth; ++d) {
                     (*edge_data)(*ci, d) /= num_encon_used;
                  }
               }
            }
         }

      } else {

         /*
          * In cases of reduced connectivity, there are no other blocks
          * from which to acquire data.
          */

         for (int axis = 0; axis < d_dim.getValue(); ++axis) {

            hier::Box pbox =
               pdat::EdgeGeometry::toEdgeBox(patch.getBox(), axis);

            hier::Index plower(pbox.lower());
            hier::Index pupper(pbox.upper());

            pdat::EdgeIterator ciend(pdat::EdgeGeometry::end(sing_fill_box, axis));
            for (pdat::EdgeIterator ci(pdat::EdgeGeometry::begin(sing_fill_box, axis));
                 ci != ciend; ++ci) {
               bool use_index = true;
               for (tbox::Dimension::dir_t n = 0; n < d_dim.getValue(); ++n) {
                  if (axis != n && bbox.getBox().numberCells(n) == 1) {
                     if ((*ci)(n) == plower(n) || (*ci)(n) == pupper(n)) {
                        use_index = false;
                        break;
                     }
                  }
               }
               if (use_index) {
                  for (int d = 0; d < depth; ++d) {
                     (*edge_data)(*ci, d) =
                        (double)bbox.getLocationIndex() + 200.0;
                  }
               }
            }
         }
      }
   }
}
예제 #21
0
hier::Box
OuteredgeGeometry::toOuteredgeBox(
   const hier::Box& box,
   tbox::Dimension::dir_t axis,
   tbox::Dimension::dir_t face_normal,
   int side)
{
   const tbox::Dimension& dim(box.getDim());

   TBOX_ASSERT(axis < dim.getValue());
   TBOX_ASSERT(face_normal < dim.getValue());
   TBOX_ASSERT(face_normal != axis);
   TBOX_ASSERT(side == 0 || side == 1);

   hier::Box oedge_box(dim);

   /*
    * If data is defined (i.e., face_normal != axis), then
    *    1) Make an edge box for the given axis.
    *    2) Trim box as needed to avoid redundant edge indices
    *       for different face normal directions.
    *    3) Restrict box to lower or upper face for given
    *       face normal direction.
    */

   if ((face_normal != axis) && !box.empty()) {

      oedge_box = EdgeGeometry::toEdgeBox(box, axis);

      for (tbox::Dimension::dir_t d = 0; d < dim.getValue(); ++d) {

         if (d != axis) {    // do not trim in axis direction

            for (tbox::Dimension::dir_t dh = static_cast<tbox::Dimension::dir_t>(d + 1);
                 dh < dim.getValue();
                 ++dh) {                                                                                              // trim higher directions

               if (dh != axis && dh != face_normal) {
                  // do not trim in axis or face_normal direction

                  oedge_box.setLower(dh, oedge_box.lower(dh) + 1);
                  oedge_box.setUpper(dh, oedge_box.upper(dh) - 1);

               }

            }

         }

      }

      if (side == 0) {   // lower side in face normal direction
         oedge_box.setUpper(face_normal, oedge_box.lower(face_normal));
      } else {  // side == 1; upper side in face normal direction
         oedge_box.setLower(face_normal, oedge_box.upper(face_normal));
      }

   }

   return oedge_box;
}
예제 #22
0
std::shared_ptr<hier::BoxOverlap>
OuteredgeGeometry::doOverlap(
   const OuteredgeGeometry& dst_geometry,
   const OuteredgeGeometry& src_geometry,
   const hier::Box& src_mask,
   const hier::Box& fill_box,
   const bool overwrite_interior,
   const hier::Transformation& transformation,
   const hier::BoxContainer& dst_restrict_boxes)
{

   const tbox::Dimension& dim(src_mask.getDim());

   std::vector<hier::BoxContainer> dst_boxes(dim.getValue());

   // Perform a quick-and-dirty intersection to see if the boxes might overlap

   const hier::Box src_box(
      hier::Box::grow(src_geometry.d_box, src_geometry.d_ghosts) * src_mask);
   hier::Box src_box_shifted(src_box);
   transformation.transform(src_box_shifted);
   const hier::Box dst_box(
      hier::Box::grow(dst_geometry.getBox(), dst_geometry.getGhosts()));

   // Compute the intersection (if any) for each of the edge directions

   const hier::IntVector one_vector(dim, 1);

   bool quick_boxes_intersect =
      (hier::Box::grow(src_box_shifted, one_vector)).intersects(
         hier::Box::grow(dst_box, one_vector));
   if (quick_boxes_intersect) {

      for (tbox::Dimension::dir_t axis = 0; axis < dim.getValue(); ++axis) {

         const hier::Box dst_edge_box(
            EdgeGeometry::toEdgeBox(dst_box, axis));
         const hier::Box src_edge_box(
            EdgeGeometry::toEdgeBox(src_box_shifted, axis));

         bool boxes_intersect = dst_edge_box.intersects(src_edge_box);

         if (boxes_intersect) {

            const hier::Box fill_edge_box(
               EdgeGeometry::toEdgeBox(fill_box, axis));

            for (tbox::Dimension::dir_t src_face_normal = 0;
                 src_face_normal < dim.getValue();
                 ++src_face_normal) {

               if (src_face_normal != axis) {

                  hier::Box outeredge_src_box_lo(toOuteredgeBox(
                                                    src_box_shifted,
                                                    axis,
                                                    src_face_normal,
                                                    0));
                  hier::Box outeredge_src_box_up(toOuteredgeBox(
                                                    src_box_shifted,
                                                    axis,
                                                    src_face_normal,
                                                    1));

                  for (tbox::Dimension::dir_t dst_face_normal = 0;
                       dst_face_normal < dim.getValue();
                       ++dst_face_normal) {

                     if (dst_face_normal != axis) {

                        hier::Box outeredge_dst_box_lo(toOuteredgeBox(dst_box,
                                                          axis,
                                                          dst_face_normal,
                                                          0));
                        hier::Box outeredge_dst_box_up(toOuteredgeBox(dst_box,
                                                          axis,
                                                          dst_face_normal,
                                                          1));

                        outeredge_dst_box_lo =
                           outeredge_dst_box_lo * fill_edge_box;
                        outeredge_dst_box_up =
                           outeredge_dst_box_up * fill_edge_box;

                        hier::Box lo_lo_box(
                           outeredge_src_box_lo * outeredge_dst_box_lo);
                        if (!lo_lo_box.empty()) {
                           dst_boxes[axis].pushBack(lo_lo_box);
                        }

                        hier::Box lo_up_box(
                           outeredge_src_box_lo * outeredge_dst_box_up);
                        if (!lo_up_box.empty()) {
                           dst_boxes[axis].pushBack(lo_up_box);
                        }

                        hier::Box up_lo_box(
                           outeredge_src_box_up * outeredge_dst_box_lo);
                        if (!up_lo_box.empty()) {
                           dst_boxes[axis].pushBack(up_lo_box);
                        }

                        hier::Box up_up_box(
                           outeredge_src_box_up * outeredge_dst_box_up);
                        if (!up_up_box.empty()) {
                           dst_boxes[axis].pushBack(up_up_box);
                        }

                     }  // dst data undefined when dst_face_normal == axis

                  }  // iterate over dst face normal directions

               }  // src data undefined when src_face_normal == axis

            }  // iterate over src face normal directions

         }  // if source and destination edge boxes overlap in axis direction

         if (!overwrite_interior) {
            const hier::Box interior_edges(
               EdgeGeometry::toEdgeBox(dst_geometry.getBox(),
                  axis));
            dst_boxes[axis].removeIntersections(interior_edges);
         }

         if (!dst_restrict_boxes.empty() && !dst_boxes[axis].empty()) {
            hier::BoxContainer edge_restrict_boxes;
            for (hier::BoxContainer::const_iterator b = dst_restrict_boxes.begin();
                 b != dst_restrict_boxes.end(); ++b) {
               edge_restrict_boxes.pushBack(EdgeGeometry::toEdgeBox(*b, axis));
            }
            dst_boxes[axis].intersectBoxes(edge_restrict_boxes);
         }

      }  // iterate over axis directions

   }  // if quick check passes

   // Create the edge overlap data object using the boxes and source shift
   return std::make_shared<EdgeOverlap>(dst_boxes, transformation);
}