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; }
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; }
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; }
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; }
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); }
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)); } }
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); }
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; }
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; }
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; }
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)); } } }
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; }
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()))); }
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; }
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); } } }
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); }
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; } } } } } } }
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; }
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); }