示例#1
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;
}
示例#2
0
bool
NodeDataFactory<TYPE>::validCopyTo(
   const std::shared_ptr<hier::PatchDataFactory>& dst_pdf) const
{
   TBOX_ASSERT_OBJDIM_EQUALITY2(*this, *dst_pdf);

   bool valid_copy = false;

   /*
    * Valid options are NodeData and OuternodeData.
    */
   if (!valid_copy) {
      std::shared_ptr<NodeDataFactory<TYPE> > ndf(
         std::dynamic_pointer_cast<NodeDataFactory<TYPE>,
                                     hier::PatchDataFactory>(dst_pdf));
      if (ndf) {
         valid_copy = true;
      }
   }

   if (!valid_copy) {
      std::shared_ptr<OuternodeDataFactory<TYPE> > ondf(
         std::dynamic_pointer_cast<OuternodeDataFactory<TYPE>,
                                     hier::PatchDataFactory>(
            dst_pdf));
      if (ondf) {
         valid_copy = true;
      }
   }

   return valid_copy;
}
示例#3
0
boost::shared_ptr<hier::BoxGeometry>
CellDataFactory<TYPE>::getBoxGeometry(
   const hier::Box& box) const
{
   TBOX_ASSERT_OBJDIM_EQUALITY2(*this, box);

   return boost::make_shared<CellGeometry>(box, d_ghosts);
}
示例#4
0
boost::shared_ptr<hier::PatchDataFactory>
CellDataFactory<TYPE>::cloneFactory(
   const hier::IntVector& ghosts)
{
   TBOX_ASSERT_OBJDIM_EQUALITY2(*this, ghosts);

   return boost::make_shared<CellDataFactory<TYPE> >(d_depth, ghosts);
}
示例#5
0
OuterfaceGeometry::OuterfaceGeometry(
   const hier::Box& box,
   const hier::IntVector& ghosts):
   d_box(box),
   d_ghosts(ghosts)
{
   TBOX_ASSERT_OBJDIM_EQUALITY2(box, ghosts);
   TBOX_ASSERT(ghosts.min() >= 0);
}
示例#6
0
double
PatchSideDataNormOpsReal<TYPE>::weightedRMSNorm(
   const boost::shared_ptr<pdat::SideData<TYPE> >& data,
   const boost::shared_ptr<pdat::SideData<TYPE> >& weight,
   const hier::Box& box,
   const boost::shared_ptr<pdat::SideData<double> >& cvol) const
{
   TBOX_ASSERT(data && weight);
   TBOX_ASSERT_OBJDIM_EQUALITY2(*data, box);

   double retval = weightedL2Norm(data, weight, box, cvol);
   if (!cvol) {
      retval /= sqrt((double)numberOfEntries(data, box));
   } else {
      TBOX_ASSERT_OBJDIM_EQUALITY2(*data, *cvol);
      retval /= sqrt(sumControlVolumes(data, cvol, box));
   }
   return retval;
}
示例#7
0
std::shared_ptr<hier::PatchDataFactory>
NodeDataFactory<TYPE>::cloneFactory(
   const hier::IntVector& ghosts)
{
   TBOX_ASSERT_OBJDIM_EQUALITY2(*this, ghosts);

   return std::make_shared<NodeDataFactory<TYPE> >(
             d_depth,
             ghosts,
             d_fine_boundary_represents_var);
}
示例#8
0
boost::shared_ptr<hier::PatchData>
CellDataFactory<TYPE>::allocate(
   const hier::Patch& patch) const
{
   TBOX_ASSERT_OBJDIM_EQUALITY2(*this, patch);

   return boost::make_shared<CellData<TYPE> >(
             patch.getBox(),
             d_depth,
             d_ghosts);
}
示例#9
0
void
PatchSideDataOpsReal<TYPE>::setToScalar(
   const std::shared_ptr<pdat::SideData<TYPE> >& dst,
   const TYPE& alpha,
   const hier::Box& box) const
{
   TBOX_ASSERT(dst);
   TBOX_ASSERT_OBJDIM_EQUALITY2(*dst, box);

   dst->fillAll(alpha, box);
}
示例#10
0
double
PatchSideDataNormOpsReal<TYPE>::maxNorm(
   const boost::shared_ptr<pdat::SideData<TYPE> >& data,
   const hier::Box& box,
   const boost::shared_ptr<pdat::SideData<double> >& cvol) const
{
   TBOX_ASSERT(data);
   TBOX_ASSERT_OBJDIM_EQUALITY2(*data, box);

   tbox::Dimension::dir_t dimVal = data->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_OBJDIM_EQUALITY2(*data, *cvol);
      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;
}
示例#11
0
size_t
CellDataFactory<TYPE>::getSizeOfMemory(
   const hier::Box& box) const
{
   TBOX_ASSERT_OBJDIM_EQUALITY2(*this, box);

   const size_t obj =
      tbox::MemoryUtilities::align(sizeof(CellData<TYPE>));
   const size_t data =
      CellData<TYPE>::getSizeOfData(box, d_depth, d_ghosts);
   return obj + data;
}
示例#12
0
void
PatchSideDataOpsReal<TYPE>::printData(
   const std::shared_ptr<pdat::SideData<TYPE> >& data,
   const hier::Box& box,
   std::ostream& s) const
{
   TBOX_ASSERT(data);
   TBOX_ASSERT_OBJDIM_EQUALITY2(*data, box);

   s << "Data box = " << box << std::endl;
   data->print(box, s);
   s << "\n";
}
double
PatchSideDataNormOpsComplex::L2Norm(
   const boost::shared_ptr<pdat::SideData<dcomplex> >& data,
   const hier::Box& box,
   const boost::shared_ptr<pdat::SideData<double> >& cvol) const
{
   TBOX_ASSERT(data);
   TBOX_ASSERT_OBJDIM_EQUALITY2(*data, box);

   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);
            double aval = d_array_ops.L2Norm(data->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.L2NormWithControlVolume(
                  data->getArrayData(d),
                  cvol->getArrayData(d),
                  side_box);
            retval += aval * aval;
         }
      }
   }
   return sqrt(retval);
}
示例#14
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;
}
示例#15
0
bool
CellDataFactory<TYPE>::validCopyTo(
   const boost::shared_ptr<hier::PatchDataFactory>& dst_pdf) const
{
   TBOX_ASSERT_OBJDIM_EQUALITY2(*this, *dst_pdf);

   bool valid_copy = false;

   /*
    * Only valid option is CellData.
    */
   boost::shared_ptr<CellDataFactory<TYPE> > cdf(
      boost::dynamic_pointer_cast<CellDataFactory<TYPE>,
                                  hier::PatchDataFactory>(dst_pdf));
   if (cdf) {
      valid_copy = true;
   }
   return valid_copy;
}
示例#16
0
TYPE
PatchSideDataNormOpsReal<TYPE>::dot(
   const boost::shared_ptr<pdat::SideData<TYPE> >& data1,
   const boost::shared_ptr<pdat::SideData<TYPE> >& data2,
   const hier::Box& box,
   const boost::shared_ptr<pdat::SideData<double> >& cvol) const
{
   TBOX_ASSERT(data1 && data2);
   TBOX_ASSERT(data1->getDirectionVector() == data2->getDirectionVector());

   tbox::Dimension::dir_t dimVal = data1->getDim().getValue();

   TYPE retval = 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_OBJDIM_EQUALITY2(*data1, *cvol);
      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;
}
示例#17
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;
}
示例#18
0
boost::shared_ptr<hier::BoxOverlap>
OuterfaceGeometry::calculateOverlap(
   const hier::BoxGeometry& dst_geometry,
   const hier::BoxGeometry& src_geometry,
   const hier::Box& src_mask,
   const hier::Box& fill_box,
   const bool overwrite_interior,
   const hier::Transformation& transformation,
   const bool retry,
   const hier::BoxContainer& dst_restrict_boxes) const
{

   TBOX_ASSERT_OBJDIM_EQUALITY2(d_box, src_mask);

   const FaceGeometry* t_dst_face =
      dynamic_cast<const FaceGeometry *>(&dst_geometry);
   const OuterfaceGeometry* t_dst_oface =
      dynamic_cast<const OuterfaceGeometry *>(&dst_geometry);
   const OuterfaceGeometry* t_src =
      dynamic_cast<const OuterfaceGeometry *>(&src_geometry);

   boost::shared_ptr<hier::BoxOverlap> over;

   if ((t_src != 0) && (t_dst_face != 0)) {
      over = doOverlap(*t_dst_face, *t_src, src_mask, fill_box,
            overwrite_interior,
            transformation, dst_restrict_boxes);
   } else if ((t_src != 0) && (t_dst_oface != 0)) {
      over = doOverlap(*t_dst_oface, *t_src, src_mask, fill_box,
            overwrite_interior,
            transformation, dst_restrict_boxes);
   } else if (retry) {
      over = src_geometry.calculateOverlap(dst_geometry, src_geometry,
            src_mask, fill_box, overwrite_interior,
            transformation, false,
            dst_restrict_boxes);
   }
   return over;

}
示例#19
0
boost::shared_ptr<TimeInterpolateOperator>
TransferOperatorRegistry::lookupTimeInterpolateOperator(
   const boost::shared_ptr<Variable>& var,
   const std::string& op_name)
{
   TBOX_ASSERT(var);
   TBOX_ASSERT_OBJDIM_EQUALITY2(d_min_stencil_width, *var);

   boost::shared_ptr<TimeInterpolateOperator> time_op;

   if ((op_name == "NO_TIME_INTERPOLATE") ||
       (op_name.empty())) {
   } else {

      boost::unordered_map<std::string, boost::unordered_map<std::string,
                                                             boost::shared_ptr<
                                                                TimeInterpolateOperator> > >::
      iterator time_ops =
         d_time_operators.find(op_name);
      if (time_ops == d_time_operators.end()) {
         TBOX_ERROR(
            "TransferOperatorRegistry::lookupTimeInterpolateOperator"
            << " could not find any operators with name " << op_name
            << std::endl);
      }
      boost::unordered_map<std::string,
                           boost::shared_ptr<TimeInterpolateOperator> >::iterator the_op =
         time_ops->second.find(typeid(*var).name());
      if (the_op == time_ops->second.end()) {
         TBOX_ERROR(
            "TransferOperatorRegistry::lookupTimeInterpolateOperator"
            << " could not find operator with name " << op_name
            << " for variable named " << typeid(*var).name() << std::endl);
      }
      time_op = the_op->second;
   }

   return time_op;
}
示例#20
0
boost::shared_ptr<RefineOperator>
TransferOperatorRegistry::lookupRefineOperator(
   const boost::shared_ptr<Variable>& var,
   const std::string& op_name)
{
   TBOX_ASSERT(var);
   TBOX_ASSERT_OBJDIM_EQUALITY2(d_min_stencil_width, *var);

   boost::shared_ptr<RefineOperator> refine_op;

   if ((op_name == "NO_REFINE") ||
       (op_name == "USER_DEFINED_REFINE") ||
       (op_name.empty())) {
   } else {

      boost::unordered_map<std::string, boost::unordered_map<std::string,
                                                             boost::shared_ptr<RefineOperator> > >
      ::iterator refine_ops =
         d_refine_operators.find(op_name);
      if (refine_ops == d_refine_operators.end()) {
         TBOX_ERROR(
            "TransferOperatorRegistry::lookupRefineOperator"
            << " could not find any operators with name " << op_name
            << std::endl);
      }
      boost::unordered_map<std::string,
                           boost::shared_ptr<RefineOperator> >::iterator the_op =
         refine_ops->second.find(typeid(*var).name());
      if (the_op == refine_ops->second.end()) {
         TBOX_ERROR(
            "TransferOperatorRegistry::lookupRefineOperator"
            << " could not find operator with name " << op_name
            << " for variable named " << typeid(*var).name() << std::endl);
      }
      refine_op = the_op->second;
   }

   return refine_op;
}
/*
 *************************************************************************
 *
 * Calculate the overlap according to the desired pattern
 *
 *************************************************************************
 */
std::shared_ptr<hier::BoxOverlap>
FirstLayerCellVariableFillPattern::calculateOverlap(
   const hier::BoxGeometry& dst_geometry,
   const hier::BoxGeometry& src_geometry,
   const hier::Box& dst_patch_box,
   const hier::Box& src_mask,
   const hier::Box& fill_box,
   const bool overwrite_interior,
   const hier::Transformation& transformation) const
{
   TBOX_ASSERT_OBJDIM_EQUALITY2(dst_patch_box, src_mask);

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

   return dst_geometry.calculateOverlap(src_geometry,
      src_mask,
      fill_box,
      overwrite_interior,
      transformation,
      stencil_boxes);

}
/*
 *************************************************************************
 *
 * computeFillBoxesAndNeighborhoodSets
 *
 *************************************************************************
 */
void
PatchLevelEnhancedFillPattern::computeFillBoxesAndNeighborhoodSets(
   boost::shared_ptr<hier::BoxLevel>& fill_box_level,
   boost::shared_ptr<hier::Connector>& dst_to_fill,
   const hier::BoxLevel& dst_box_level,
   const hier::IntVector& fill_ghost_width,
   bool data_on_patch_border)
{
   NULL_USE(data_on_patch_border);
   TBOX_ASSERT_OBJDIM_EQUALITY2(dst_box_level, fill_ghost_width);

   fill_box_level.reset(new hier::BoxLevel(
         dst_box_level.getRefinementRatio(),
         dst_box_level.getGridGeometry(),
         dst_box_level.getMPI()));

   dst_to_fill.reset(new hier::Connector(dst_box_level,
         *fill_box_level,
         fill_ghost_width));

   boost::shared_ptr<const hier::BaseGridGeometry> grid_geometry(
      dst_box_level.getGridGeometry());

   const hier::BoxContainer& dst_boxes = dst_box_level.getBoxes();

   hier::LocalId last_id = dst_box_level.getLastLocalId();
   for (hier::RealBoxConstIterator ni(dst_boxes.realBegin());
        ni != dst_boxes.realEnd(); ++ni) {
      const hier::Box& dst_box = *ni;
      const hier::BoxId& dst_box_id = dst_box.getBoxId();
      hier::BoxContainer fill_boxes(
         hier::Box::grow(dst_box, fill_ghost_width));

      hier::BoxContainer constructed_fill_boxes;

      hier::Connector::NeighborhoodIterator base_box_itr =
         dst_to_fill->findLocal(dst_box_id);
      bool has_base_box = base_box_itr != dst_to_fill->end();

      for (hier::BaseGridGeometry::ConstNeighborIterator ni =
              grid_geometry->begin(dst_box.getBlockId());
           ni != grid_geometry->end(dst_box.getBlockId()); ++ni) {
         const hier::BaseGridGeometry::Neighbor& nbr = *ni;
         if (nbr.isSingularity()) {

            hier::BoxContainer encon_boxes(nbr.getTransformedDomain());
            encon_boxes.refine(dst_box_level.getRefinementRatio());
            encon_boxes.intersectBoxes(fill_boxes);
            encon_boxes.removeIntersections(constructed_fill_boxes);

            if (encon_boxes.size()) {

               if (!has_base_box) {
                  base_box_itr = dst_to_fill->makeEmptyLocalNeighborhood(
                        dst_box_id);
                  has_base_box = true;
               }
               for (hier::BoxContainer::iterator ei = encon_boxes.begin();
                    ei != encon_boxes.end(); ++ei) {

                  hier::Box fill_box(
                     *ei,
                     ++last_id,
                     dst_box.getOwnerRank());

                  TBOX_ASSERT(fill_box.getBlockId() == dst_box.getBlockId());

                  fill_box_level->addBoxWithoutUpdate(fill_box);

                  dst_to_fill->insertLocalNeighbor(
                     fill_box,
                     base_box_itr);

                  constructed_fill_boxes.pushBack(*ei);
               }
            }
         }
      }

      d_max_fill_boxes = tbox::MathUtilities<int>::Max(
            d_max_fill_boxes,
            constructed_fill_boxes.size());
   }
   fill_box_level->finalize();
}
示例#23
0
boost::shared_ptr<HierarchyDataOpsReal<double> >
HierarchyDataOpsManager::getOperationsDouble(
   const boost::shared_ptr<hier::Variable>& variable,
   const boost::shared_ptr<hier::PatchHierarchy>& hierarchy,
   bool get_unique)
{
   TBOX_ASSERT(variable);
   TBOX_ASSERT(hierarchy);
   TBOX_ASSERT_OBJDIM_EQUALITY2(*variable, *hierarchy);

   const boost::shared_ptr<pdat::CellVariable<double> > cellvar(
      boost::dynamic_pointer_cast<pdat::CellVariable<double>,
                                  hier::Variable>(variable));
   const boost::shared_ptr<pdat::FaceVariable<double> > facevar(
      boost::dynamic_pointer_cast<pdat::FaceVariable<double>,
                                  hier::Variable>(variable));
   const boost::shared_ptr<pdat::NodeVariable<double> > nodevar(
      boost::dynamic_pointer_cast<pdat::NodeVariable<double>,
                                  hier::Variable>(variable));
   const boost::shared_ptr<pdat::SideVariable<double> > sidevar(
      boost::dynamic_pointer_cast<pdat::SideVariable<double>,
                                  hier::Variable>(variable));
   const boost::shared_ptr<pdat::EdgeVariable<double> > edgevar(
      boost::dynamic_pointer_cast<pdat::EdgeVariable<double>,
                                  hier::Variable>(variable));

   boost::shared_ptr<HierarchyDataOpsReal<double> > ops;

   if (cellvar) {

      if (get_unique) {
         ops.reset(new HierarchyCellDataOpsReal<double>(hierarchy));
      } else {
         const int n = static_cast<int>(d_cell_ops_double.size());
         for (int i = 0; i < n && !ops; ++i) {
            if (hierarchy !=
                d_cell_ops_double[i]->getPatchHierarchy()) continue;
            // A compatible operator has been found at i.
            ops = d_cell_ops_double[i];
         }
         if (!ops) {
            // No compatible operator has been found.
            ops.reset(new HierarchyCellDataOpsReal<double>(hierarchy));
            d_cell_ops_double.resize(n + 1);
            d_cell_ops_double[n] = ops;
         }
      }

   } else if (facevar) {

      if (get_unique) {
         ops.reset(new HierarchyFaceDataOpsReal<double>(hierarchy));
      } else {
         const int n = static_cast<int>(d_face_ops_double.size());
         for (int i = 0; i < n && !ops; ++i) {
            if (hierarchy !=
                d_face_ops_double[i]->getPatchHierarchy()) continue;
            // A compatible operator has been found at i.
            ops = d_face_ops_double[i];
         }
         if (!ops) {
            // No compatible operator has been found.
            ops.reset(new HierarchyFaceDataOpsReal<double>(hierarchy));
            d_face_ops_double.resize(n + 1);
            d_face_ops_double[n] = ops;
         }
      }

   } else if (nodevar) {

      if (get_unique) {
         ops.reset(new HierarchyNodeDataOpsReal<double>(hierarchy));
      } else {
         const int n = static_cast<int>(d_node_ops_double.size());
         for (int i = 0; i < n && !ops; ++i) {
            if (hierarchy !=
                d_node_ops_double[i]->getPatchHierarchy()) continue;
            // A compatible operator has been found at i.
            ops = d_node_ops_double[i];
         }
         if (!ops) {
            // No compatible operator has been found.
            ops.reset(new HierarchyNodeDataOpsReal<double>(hierarchy));
            d_node_ops_double.resize(n + 1);
            d_node_ops_double[n] = ops;
         }
      }

   } else if (sidevar) {

      if (get_unique) {
         ops.reset(new HierarchySideDataOpsReal<double>(hierarchy));
      } else {
         const int n = static_cast<int>(d_side_ops_double.size());
         for (int i = 0; i < n && !ops; ++i) {
            if (hierarchy !=
                d_side_ops_double[i]->getPatchHierarchy()) continue;
            // A compatible operator has been found at i.
            ops = d_side_ops_double[i];
         }
         if (!ops) {
            // No compatible operator has been found.
            ops.reset(new HierarchySideDataOpsReal<double>(hierarchy));
            d_side_ops_double.resize(n + 1);
            d_side_ops_double[n] = ops;
         }
      }

   } else if (edgevar) {

      if (get_unique) {
         ops.reset(new HierarchyEdgeDataOpsReal<double>(hierarchy));
      } else {
         const int n = static_cast<int>(d_edge_ops_double.size());
         for (int i = 0; i < n && !ops; ++i) {
            if (hierarchy !=
                d_edge_ops_double[i]->getPatchHierarchy()) continue;
            // A compatible operator has been found at i.
            ops = d_edge_ops_double[i];
         }
         if (!ops) {
            // No compatible operator has been found.
            ops.reset(new HierarchyEdgeDataOpsReal<double>(hierarchy));
            d_edge_ops_double.resize(n + 1);
            d_edge_ops_double[n] = ops;
         }
      }

   }

   if (!ops) {
      TBOX_ERROR("HierarchyDataOpsManager internal error...\n"
         << "Operations for variable " << variable->getName()
         << " not defined.");
   }

   return ops;
}
/*
 *************************************************************************
 *
 * computeFillBoxesAndNeighborhoodSets
 *
 *************************************************************************
 */
void
PatchLevelBorderFillPattern::computeFillBoxesAndNeighborhoodSets(
   boost::shared_ptr<hier::BoxLevel>& fill_box_level,
   boost::shared_ptr<hier::Connector>& dst_to_fill,
   const hier::BoxLevel& dst_box_level,
   const hier::IntVector& fill_ghost_width,
   bool data_on_patch_border)
{
   TBOX_ASSERT_OBJDIM_EQUALITY2(dst_box_level, fill_ghost_width);

   fill_box_level.reset(new hier::BoxLevel(
         dst_box_level.getRefinementRatio(),
         dst_box_level.getGridGeometry(),
         dst_box_level.getMPI()));

   dst_to_fill.reset(new hier::Connector(dst_box_level,
         *fill_box_level,
         fill_ghost_width));

   const hier::BoxContainer& dst_boxes = dst_box_level.getBoxes();

   const int dst_level_num = dst_box_level.getGridGeometry()->
      getEquivalentLevelNumber(dst_box_level.getRefinementRatio());

   hier::IntVector dst_to_dst_width(fill_ghost_width);
   if (data_on_patch_border) {
      dst_to_dst_width += hier::IntVector::getOne(fill_ghost_width.getDim());
   }

   const hier::Connector& dst_to_dst =
      dst_box_level.findConnector(dst_box_level,
         dst_to_dst_width,
         hier::CONNECTOR_IMPLICIT_CREATION_RULE,
         true);

   /*
    * To get the level border, grow each patch box and remove
    * the level from it.
    */
   hier::LocalId last_id = dst_box_level.getLastLocalId();
   for (hier::RealBoxConstIterator ni(dst_boxes.realBegin());
        ni != dst_boxes.realEnd(); ++ni) {
      const hier::Box& dst_box = *ni;
      hier::BoxContainer fill_boxes(
         hier::Box::grow(dst_box, fill_ghost_width));
      hier::Connector::ConstNeighborhoodIterator nabrs =
         dst_to_dst.find(dst_box.getBoxId());
      for (hier::Connector::ConstNeighborIterator na = dst_to_dst.begin(nabrs);
           na != dst_to_dst.end(nabrs); ++na) {
         if (dst_box.getBlockId() == na->getBlockId()) {
            fill_boxes.removeIntersections(*na);
         } else {
            boost::shared_ptr<const hier::BaseGridGeometry> grid_geometry(
               dst_box_level.getGridGeometry());

            const hier::BlockId& dst_block_id = dst_box.getBlockId();
            const hier::BlockId& nbr_block_id = na->getBlockId();

            TBOX_ASSERT(grid_geometry->areNeighbors(dst_block_id,
                  nbr_block_id));

            hier::Transformation::RotationIdentifier rotation =
               grid_geometry->getRotationIdentifier(dst_block_id,
                  nbr_block_id);
            hier::IntVector offset(
               grid_geometry->getOffset(dst_block_id, nbr_block_id, dst_level_num));

            hier::Transformation transformation(rotation, offset,
                                                nbr_block_id, dst_block_id);

            hier::Box nbr_box(*na);
            transformation.transform(nbr_box);

            fill_boxes.removeIntersections(nbr_box);
         }
      }

      if (!fill_boxes.empty()) {
         d_max_fill_boxes = tbox::MathUtilities<int>::Max(d_max_fill_boxes,
               fill_boxes.size());
         hier::Connector::NeighborhoodIterator base_box_itr =
            dst_to_fill->makeEmptyLocalNeighborhood(dst_box.getBoxId());
         for (hier::BoxContainer::iterator li = fill_boxes.begin();
              li != fill_boxes.end(); ++li) {
            hier::Box fill_box(*li,
                               ++last_id,
                               dst_box.getOwnerRank());
            TBOX_ASSERT(fill_box.getBlockId() == dst_box.getBlockId());
            fill_box_level->addBoxWithoutUpdate(fill_box);
            dst_to_fill->insertLocalNeighbor(fill_box, base_box_itr);
         }
      }
   }
   fill_box_level->finalize();
}