예제 #1
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;
                  }
               }
            }
         }
      }
   }
}
예제 #2
0
void PoissonGaussianSolution::setBcCoefs(
   const boost::shared_ptr<pdat::ArrayData<double> >& acoef_data,
   const boost::shared_ptr<pdat::ArrayData<double> >& bcoef_data,
   const boost::shared_ptr<pdat::ArrayData<double> >& gcoef_data,
   const boost::shared_ptr<hier::Variable>& variable,
   const hier::Patch& patch,
   const hier::BoundaryBox& bdry_box,
   const double fill_time) const
{
   NULL_USE(variable);
   NULL_USE(fill_time);

   boost::shared_ptr<geom::CartesianPatchGeometry> patch_geom(
      BOOST_CAST<geom::CartesianPatchGeometry, hier::PatchGeometry>(
         patch.getPatchGeometry()));
   TBOX_ASSERT(patch_geom);
   /*
    * Set to an inhomogeneous Dirichlet boundary condition.
    */
   hier::Box patch_box(patch.getBox());

   const double* xlo = patch_geom->getXLower();
   const double* xup = patch_geom->getXUpper();
   const double* dx = patch_geom->getDx();

   if (bdry_box.getBoundaryType() != 1) {
      // Must be a face boundary.
      TBOX_ERROR("Bad boundary type in\n"
         << "PoissonGaussianSolution::setBcCoefs \n");
   }
   const hier::Box& box = bdry_box.getBox();
   hier::Index lower = box.lower();
   hier::Index upper = box.upper();

   if (d_dim == tbox::Dimension(2)) {
      double* a_array = acoef_data ? acoef_data->getPointer() : 0;
      double* b_array = bcoef_data ? bcoef_data->getPointer() : 0;
      double* g_array = gcoef_data ? gcoef_data->getPointer() : 0;
      int i, j, ibeg, iend, jbeg, jend;
      double x, y;
      switch (bdry_box.getLocationIndex()) {
         case 0:
            // min i edge
            jbeg = box.lower()[1];
            jend = box.upper()[1];
            x = xlo[0];
            for (j = jbeg; j <= jend; ++j) {
               y = xlo[1] + dx[1] * (j - patch_box.lower()[1] + 0.5);
               if (a_array) a_array[j - jbeg] = 1.0;
               if (b_array) b_array[j - jbeg] = 0.0;
               if (g_array) g_array[j - jbeg] = exactFcn(x, y);
            }
            break;
         case 1:
            // max i edge
            jbeg = box.lower()[1];
            jend = box.upper()[1];
            x = xup[0];
            for (j = jbeg; j <= jend; ++j) {
               y = xlo[1] + dx[1] * (j - patch_box.lower()[1] + 0.5);
               if (a_array) a_array[j - jbeg] = 1.0;
               if (b_array) b_array[j - jbeg] = 0.0;
               if (g_array) g_array[j - jbeg] = exactFcn(x, y);
            }
            break;
         case 2:
            // min j edge
            ibeg = box.lower()[0];
            iend = box.upper()[0];
            y = xlo[1];
            for (i = ibeg; i <= iend; ++i) {
               x = xlo[0] + dx[0] * (i - patch_box.lower()[0] + 0.5);
               if (a_array) a_array[i - ibeg] = 1.0;
               if (b_array) b_array[i - ibeg] = 0.0;
               if (g_array) g_array[i - ibeg] = exactFcn(x, y);
            }
            break;
         case 3:
            // max j edge
            ibeg = box.lower()[0];
            iend = box.upper()[0];
            y = xup[1];
            for (i = ibeg; i <= iend; ++i) {
               x = xlo[0] + dx[0] * (i - patch_box.lower()[0] + 0.5);
               if (a_array) a_array[i - ibeg] = 1.0;
               if (b_array) b_array[i - ibeg] = 0.0;
               if (g_array) g_array[i - ibeg] = exactFcn(x, y);
            }
            break;
         default:
            TBOX_ERROR("Invalid location index in\n"
            << "PoissonGaussianSolution::setBcCoefs");
      }
   }

   if (d_dim == tbox::Dimension(3)) {
      MDA_Access<double, 3, MDA_OrderColMajor<3> > a_array, b_array, g_array;
      if (acoef_data) a_array = pdat::ArrayDataAccess::access<3, double>(
               *acoef_data);
      if (bcoef_data) b_array = pdat::ArrayDataAccess::access<3, double>(
               *bcoef_data);
      if (gcoef_data) g_array = pdat::ArrayDataAccess::access<3, double>(
               *gcoef_data);
      int i, j, k, ibeg, iend, jbeg, jend, kbeg, kend;
      double x, y, z;
      switch (bdry_box.getLocationIndex()) {
         case 0:
            // min i side
            jbeg = box.lower()[1];
            jend = box.upper()[1];
            kbeg = box.lower()[2];
            kend = box.upper()[2];
            i = box.lower()[0] + 1;
            x = xlo[0];
            for (k = kbeg; k <= kend; ++k) {
               z = xlo[2] + dx[2] * (k - patch_box.lower()[2] + 0.5);
               for (j = jbeg; j <= jend; ++j) {
                  y = xlo[1] + dx[1] * (j - patch_box.lower()[1] + 0.5);
                  if (a_array) a_array(i, j, k) = 1.0;
                  if (b_array) b_array(i, j, k) = 0.0;
                  if (g_array) g_array(i, j, k) = exactFcn(x, y, z);
               }
            }
            break;
         case 1:
            // max i side
            jbeg = box.lower()[1];
            jend = box.upper()[1];
            kbeg = box.lower()[2];
            kend = box.upper()[2];
            i = box.upper()[0];
            x = xup[0];
            for (k = kbeg; k <= kend; ++k) {
               z = xlo[2] + dx[2] * (k - patch_box.lower()[2] + 0.5);
               for (j = jbeg; j <= jend; ++j) {
                  y = xlo[1] + dx[1] * (j - patch_box.lower()[1] + 0.5);
                  if (a_array) a_array(i, j, k) = 1.0;
                  if (b_array) b_array(i, j, k) = 0.0;
                  if (g_array) g_array(i, j, k) = exactFcn(x, y, z);
               }
            }
            break;
         case 2:
            // min j side
            ibeg = box.lower()[0];
            iend = box.upper()[0];
            kbeg = box.lower()[2];
            kend = box.upper()[2];
            j = box.lower()[1] + 1;
            y = xlo[1];
            for (k = kbeg; k <= kend; ++k) {
               z = xlo[2] + dx[2] * (k - patch_box.lower()[2] + 0.5);
               for (i = ibeg; i <= iend; ++i) {
                  x = xlo[0] + dx[0] * (i - patch_box.lower()[0] + 0.5);
                  if (a_array) a_array(i, j, k) = 1.0;
                  if (b_array) b_array(i, j, k) = 0.0;
                  if (g_array) g_array(i, j, k) = exactFcn(x, y, z);
               }
            }
            break;
         case 3:
            // max j side
            ibeg = box.lower()[0];
            iend = box.upper()[0];
            kbeg = box.lower()[2];
            kend = box.upper()[2];
            j = box.upper()[1];
            y = xup[1];
            for (k = kbeg; k <= kend; ++k) {
               z = xlo[2] + dx[2] * (k - patch_box.lower()[2] + 0.5);
               for (i = ibeg; i <= iend; ++i) {
                  x = xlo[0] + dx[0] * (i - patch_box.lower()[0] + 0.5);
                  if (a_array) a_array(i, j, k) = 1.0;
                  if (b_array) b_array(i, j, k) = 0.0;
                  if (g_array) g_array(i, j, k) = exactFcn(x, y, z);
               }
            }
            break;
         case 4:
            // min k side
            ibeg = box.lower()[0];
            iend = box.upper()[0];
            jbeg = box.lower()[1];
            jend = box.upper()[1];
            k = box.lower()[2] + 1;
            z = xlo[2];
            for (j = jbeg; j <= jend; ++j) {
               y = xlo[1] + dx[1] * (j - patch_box.lower()[1] + 0.5);
               for (i = ibeg; i <= iend; ++i) {
                  x = xlo[0] + dx[0] * (i - patch_box.lower()[0] + 0.5);
                  if (a_array) a_array(i, j, k) = 1.0;
                  if (b_array) b_array(i, j, k) = 0.0;
                  if (g_array) g_array(i, j, k) = exactFcn(x, y, z);
               }
            }
            break;
         case 5:
            // max k side
            ibeg = box.lower()[0];
            iend = box.upper()[0];
            jbeg = box.lower()[1];
            jend = box.upper()[1];
            k = box.upper()[2];
            z = xup[2];
            for (j = jbeg; j <= jend; ++j) {
               y = xlo[1] + dx[1] * (j - patch_box.lower()[1] + 0.5);
               for (i = ibeg; i <= iend; ++i) {
                  x = xlo[0] + dx[0] * (i - patch_box.lower()[0] + 0.5);
                  if (a_array) a_array(i, j, k) = 1.0;
                  if (b_array) b_array(i, j, k) = 0.0;
                  if (g_array) g_array(i, j, k) = exactFcn(x, y, z);
               }
            }
            break;
         default:
            TBOX_ERROR("Invalid location index in\n"
            << "PoissonGaussianSolution::setBcCoefs");
      }
   }
}
예제 #3
0
int SkeletonBoundaryUtilities2::checkBdryData(
   const string& varname,
   const hier::Patch& patch,
   int data_id,
   int depth,
   const hier::IntVector& gcw_to_check,
   const hier::BoundaryBox& bbox,
   int bcase,
   double bstate)
{
   TBOX_ASSERT(!varname.empty());
   TBOX_ASSERT(data_id >= 0);
   TBOX_ASSERT(depth >= 0);

   int num_bad_values = 0;

   int btype = bbox.getBoundaryType();
   int bloc = bbox.getLocationIndex();

   std::shared_ptr<hier::PatchGeometry> pgeom(patch.getPatchGeometry());

   std::shared_ptr<pdat::CellData<double> > vardata(
      SAMRAI_SHARED_PTR_CAST<pdat::CellData<double>, hier::PatchData>(
         patch.getPatchData(data_id)));
   TBOX_ASSERT(vardata);

   string bdry_type_str;
   if (btype == Bdry::EDGE2D) {
      bdry_type_str = "EDGE";
   } else if (btype == Bdry::NODE2D) {
      bdry_type_str = "NODE";
   } else {
      TBOX_ERROR(
         "Unknown btype " << btype
                          << " passed to SkeletonBoundaryUtilities2::checkBdryData()! "
                          << endl);
   }

   tbox::plog << "\n\nCHECKING 2D " << bdry_type_str << " BDRY DATA..." << endl;
   tbox::plog << "varname = " << varname << " : depth = " << depth << endl;
   tbox::plog << "bbox = " << bbox.getBox() << endl;
   tbox::plog << "btype, bloc, bcase = "
              << btype << ", = " << bloc << ", = " << bcase << endl;

   tbox::Dimension::dir_t idir;
   double valfact = 0.0, constval = 0.0, dxfact = 0.0;
   int offsign;

   get2dBdryDirectionCheckValues(idir, offsign,
      btype, bloc, bcase);

   if (btype == Bdry::EDGE2D) {

      if (bcase == BdryCond::FLOW) {
         valfact = 1.0;
         constval = 0.0;
         dxfact = 0.0;
      } else if (bcase == BdryCond::REFLECT) {
         valfact = -1.0;
         constval = 0.0;
         dxfact = 0.0;
      } else if (bcase == BdryCond::DIRICHLET) {
         valfact = 0.0;
         constval = bstate;
         dxfact = 0.0;
      } else {
         TBOX_ERROR(
            "Unknown bcase " << bcase
                             << " passed to SkeletonBoundaryUtilities2::checkBdryData()"
                             << "\n for " << bdry_type_str
                             << " at location " << bloc << endl);
      }

   } else if (btype == Bdry::NODE2D) {

      if (bcase == BdryCond::XFLOW || bcase == BdryCond::YFLOW) {
         valfact = 1.0;
         constval = 0.0;
         dxfact = 0.0;
      } else if (bcase == BdryCond::XREFLECT || bcase == BdryCond::YREFLECT) {
         valfact = -1.0;
         constval = 0.0;
         dxfact = 0.0;
      } else if (bcase == BdryCond::XDIRICHLET ||
                 bcase == BdryCond::YDIRICHLET) {
         valfact = 0.0;
         constval = bstate;
         dxfact = 0.0;
      } else {
         TBOX_ERROR(
            "Unknown bcase " << bcase
                             << " passed to SkeletonBoundaryUtilities2::checkBdryData()"
                             << "\n for " << bdry_type_str
                             << " at location " << bloc << endl);
      }

   }

   hier::Box gbox_to_check(
      vardata->getGhostBox() * pgeom->getBoundaryFillBox(bbox,
         patch.getBox(),
         gcw_to_check));

   hier::Box cbox(gbox_to_check);
   hier::Box dbox(gbox_to_check);
   hier::Index ifirst(vardata->getBox().lower());
   hier::Index ilast(vardata->getBox().upper());

   if (offsign == -1) {
      cbox.setLower(idir, ifirst(idir) - 1);
      cbox.setUpper(idir, ifirst(idir) - 1);
      dbox.setLower(idir, ifirst(idir));
      dbox.setUpper(idir, ifirst(idir));
   } else {
      cbox.setLower(idir, ilast(idir) + 1);
      cbox.setUpper(idir, ilast(idir) + 1);
      dbox.setLower(idir, ilast(idir));
      dbox.setUpper(idir, ilast(idir));
   }

   pdat::CellIterator id(pdat::CellGeometry::begin(dbox));
   pdat::CellIterator icend(pdat::CellGeometry::end(cbox));
   for (pdat::CellIterator ic(pdat::CellGeometry::begin(cbox));
        ic != icend; ++ic) {
      double checkval = valfact * (*vardata)(*id, depth) + constval;
      pdat::CellIndex check = *ic;
      for (int p = 0; p < gbox_to_check.numberCells(idir); ++p) {
         double offcheckval = checkval + dxfact * (p + 1);
         if ((*vardata)(check, depth) != offcheckval) {
            ++num_bad_values;
            TBOX_WARNING("Bad " << bdry_type_str
                                << " boundary value for " << varname
                                << " found in cell " << check
                                << "\n   found = " << (*vardata)(check, depth)
                                << " : correct = " << offcheckval << endl);
         }
         check(idir) += offsign;
      }
      ++id;
   }

   return num_bad_values;

}