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; }
TYPE ArrayDataMiscellaneousOpsReal<TYPE>::minPointwiseDivide( const pdat::ArrayData<TYPE>& numer, const pdat::ArrayData<TYPE>& denom, const hier::Box& box) const { TBOX_ASSERT_OBJDIM_EQUALITY3(numer, denom, box); TBOX_ASSERT(denom.getDepth() == numer.getDepth()); tbox::Dimension::dir_t dimVal = numer.getDim().getValue(); TYPE min = tbox::MathUtilities<TYPE>::getMax(); TYPE quot = tbox::MathUtilities<TYPE>::getMax(); const hier::Box n_box = numer.getBox(); const hier::Box d_box = denom.getBox(); const hier::Box ibox = box * d_box * n_box; if (!ibox.empty()) { const int ddepth = denom.getDepth(); int box_w[SAMRAI::MAX_DIM_VAL]; int n_w[SAMRAI::MAX_DIM_VAL]; int d_w[SAMRAI::MAX_DIM_VAL]; int dim_counter[SAMRAI::MAX_DIM_VAL]; for (tbox::Dimension::dir_t i = 0; i < dimVal; ++i) { box_w[i] = ibox.numberCells(i); n_w[i] = n_box.numberCells(i); d_w[i] = d_box.numberCells(i); dim_counter[i] = 0; } const size_t n_offset = numer.getOffset(); const size_t d_offset = denom.getOffset(); const int num_d0_blocks = static_cast<int>(ibox.size() / box_w[0]); size_t n_begin = n_box.offset(ibox.lower()); size_t d_begin = d_box.offset(ibox.lower()); const TYPE* nd = numer.getPointer(); const TYPE* dd = denom.getPointer(); for (int d = 0; d < ddepth; ++d) { size_t n_counter = n_begin; size_t d_counter = d_begin; int n_b[SAMRAI::MAX_DIM_VAL]; int d_b[SAMRAI::MAX_DIM_VAL]; for (tbox::Dimension::dir_t nm = 0; nm < dimVal; ++nm) { n_b[nm] = static_cast<int>(n_counter); d_b[nm] = static_cast<int>(d_counter); } for (int nb = 0; nb < num_d0_blocks; ++nb) { for (int i0 = 0; i0 < box_w[0]; ++i0) { if (dd[d_counter + i0] != 0.0) { quot = nd[n_counter + i0] / dd[d_counter + i0]; } if (quot < min) min = quot; } int dim_jump = 0; for (tbox::Dimension::dir_t j = 1; j < dimVal; ++j) { if (dim_counter[j] < box_w[j] - 1) { ++dim_counter[j]; dim_jump = j; break; } else { dim_counter[j] = 0; } } if (dim_jump > 0) { int n_step = 1; int d_step = 1; for (int k = 0; k < dim_jump; ++k) { n_step *= n_w[k]; d_step *= d_w[k]; } n_counter = n_b[dim_jump - 1] + n_step; d_counter = d_b[dim_jump - 1] + d_step; for (int m = 0; m < dim_jump; ++m) { n_b[m] = static_cast<int>(n_counter); d_b[m] = static_cast<int>(d_counter); } } } n_begin += n_offset; d_begin += d_offset; } } return min; }
int ArrayDataMiscellaneousOpsReal<TYPE>::testReciprocal( pdat::ArrayData<TYPE>& dst, const pdat::ArrayData<TYPE>& src, const hier::Box& box) const { // Ignore Intel warning about floating point comparisons #ifdef __INTEL_COMPILER #pragma warning (disable:1572) #endif TBOX_ASSERT_OBJDIM_EQUALITY3(dst, src, box); TBOX_ASSERT(dst.getDepth() == src.getDepth()); tbox::Dimension::dir_t dimVal = dst.getDim().getValue(); int test = 1; const hier::Box d_box = dst.getBox(); const hier::Box s_box = src.getBox(); const hier::Box ibox = box * d_box * s_box; if (!ibox.empty()) { const int ddepth = dst.getDepth(); int box_w[SAMRAI::MAX_DIM_VAL]; int d_w[SAMRAI::MAX_DIM_VAL]; int s_w[SAMRAI::MAX_DIM_VAL]; int dim_counter[SAMRAI::MAX_DIM_VAL]; for (tbox::Dimension::dir_t i = 0; i < dimVal; ++i) { box_w[i] = ibox.numberCells(i); d_w[i] = d_box.numberCells(i); s_w[i] = s_box.numberCells(i); dim_counter[i] = 0; } const size_t d_offset = dst.getOffset(); const size_t s_offset = src.getOffset(); const int num_d0_blocks = static_cast<int>(ibox.size() / box_w[0]); size_t d_begin = d_box.offset(ibox.lower()); size_t s_begin = s_box.offset(ibox.lower()); TYPE* dd = dst.getPointer(); const TYPE* sd = src.getPointer(); for (int d = 0; d < ddepth; ++d) { int d_counter = static_cast<int>(d_begin); int s_counter = static_cast<int>(s_begin); int d_b[SAMRAI::MAX_DIM_VAL]; int s_b[SAMRAI::MAX_DIM_VAL]; for (tbox::Dimension::dir_t nd = 0; nd < dimVal; ++nd) { d_b[nd] = d_counter; s_b[nd] = s_counter; } for (int nb = 0; nb < num_d0_blocks; ++nb) { for (int i0 = 0; i0 < box_w[0]; ++i0) { if (sd[s_counter + i0] == 0.0) { test = 0; dd[d_counter + i0] = 0.0F; } else { dd[d_counter + i0] = 1.0F / sd[s_counter + i0]; } } int dim_jump = 0; for (tbox::Dimension::dir_t j = 1; j < dimVal; ++j) { if (dim_counter[j] < box_w[j] - 1) { ++dim_counter[j]; dim_jump = j; break; } else { dim_counter[j] = 0; } } if (dim_jump > 0) { int d_step = 1; int s_step = 1; for (int k = 0; k < dim_jump; ++k) { d_step *= d_w[k]; s_step *= s_w[k]; } d_counter = d_b[dim_jump - 1] + d_step; s_counter = s_b[dim_jump - 1] + s_step; for (int m = 0; m < dim_jump; ++m) { d_b[m] = d_counter; s_b[m] = s_counter; } } } d_begin += d_offset; s_begin += s_offset; } } return test; }
int ArrayDataMiscellaneousOpsReal<TYPE>::computeConstrProdPosWithControlVolume( const pdat::ArrayData<TYPE>& data1, const pdat::ArrayData<TYPE>& data2, const pdat::ArrayData<double>& cvol, const hier::Box& box) const { TBOX_ASSERT_OBJDIM_EQUALITY4(data1, data2, cvol, box); TBOX_ASSERT(data1.getDepth() == data2.getDepth()); tbox::Dimension::dir_t dimVal = data1.getDim().getValue(); int test = 1; const hier::Box d1_box = data1.getBox(); const hier::Box d2_box = data2.getBox(); const hier::Box cv_box = cvol.getBox(); const hier::Box ibox = box * d1_box * d2_box * cv_box; if (!ibox.empty()) { const int ddepth = data1.getDepth(); const int cvdepth = cvol.getDepth(); TBOX_ASSERT((ddepth == cvdepth) || (cvdepth == 1)); int box_w[SAMRAI::MAX_DIM_VAL]; int d1_w[SAMRAI::MAX_DIM_VAL]; int d2_w[SAMRAI::MAX_DIM_VAL]; int cv_w[SAMRAI::MAX_DIM_VAL]; int dim_counter[SAMRAI::MAX_DIM_VAL]; for (tbox::Dimension::dir_t i = 0; i < dimVal; ++i) { box_w[i] = ibox.numberCells(i); d1_w[i] = d1_box.numberCells(i); d2_w[i] = d2_box.numberCells(i); cv_w[i] = cv_box.numberCells(i); dim_counter[i] = 0; } const size_t d1_offset = data1.getOffset(); const size_t d2_offset = data2.getOffset(); const size_t cv_offset = ((cvdepth == 1) ? 0 : cvol.getOffset()); const int num_d0_blocks = static_cast<int>(ibox.size() / box_w[0]); size_t d1_begin = d1_box.offset(ibox.lower()); size_t d2_begin = d2_box.offset(ibox.lower()); size_t cv_begin = cv_box.offset(ibox.lower()); const TYPE* dd1 = data1.getPointer(); const TYPE* dd2 = data2.getPointer(); const double* cvd = cvol.getPointer(); for (int d = 0; d < ddepth; ++d) { int d1_counter = static_cast<int>(d1_begin); int d2_counter = static_cast<int>(d2_begin); int cv_counter = static_cast<int>(cv_begin); int d1_b[SAMRAI::MAX_DIM_VAL]; int d2_b[SAMRAI::MAX_DIM_VAL]; int cv_b[SAMRAI::MAX_DIM_VAL]; for (tbox::Dimension::dir_t nd = 0; nd < dimVal; ++nd) { d1_b[nd] = d1_counter; d2_b[nd] = d2_counter; cv_b[nd] = cv_counter; } for (int nb = 0; nb < num_d0_blocks; ++nb) { for (int i0 = 0; i0 < box_w[0]; ++i0) { if (cvd[cv_counter + i0] > 0.0) { if (tbox::MathUtilities<TYPE>::Abs(dd2[d2_counter + i0]) > 0.0 && (dd1[d1_counter + i0] * dd2[d2_counter + i0] <= 0.0) ) { test = 0; } } } int dim_jump = 0; for (tbox::Dimension::dir_t j = 1; j < dimVal; ++j) { if (dim_counter[j] < box_w[j] - 1) { ++dim_counter[j]; dim_jump = j; break; } else { dim_counter[j] = 0; } } if (dim_jump > 0) { int d1_step = 1; int d2_step = 1; int cv_step = 1; for (int k = 0; k < dim_jump; ++k) { d1_step *= d1_w[k]; d2_step *= d2_w[k]; cv_step *= cv_w[k]; } d1_counter = d1_b[dim_jump - 1] + d1_step; d2_counter = d2_b[dim_jump - 1] + d1_step; cv_counter = cv_b[dim_jump - 1] + cv_step; for (int m = 0; m < dim_jump; ++m) { d1_b[m] = d1_counter; d2_b[m] = d2_counter; cv_b[m] = cv_counter; } } } d1_begin += d1_offset; d2_begin += d2_offset; cv_begin += cv_offset; } } return test; }
void ArrayDataMiscellaneousOpsReal<TYPE>::compareToScalar( pdat::ArrayData<TYPE>& dst, const pdat::ArrayData<TYPE>& src, const TYPE& alpha, const hier::Box& box) const { TBOX_ASSERT_OBJDIM_EQUALITY3(dst, src, box); TBOX_ASSERT(dst.getDepth() == src.getDepth()); tbox::Dimension::dir_t dimVal = dst.getDim().getValue(); const hier::Box d_box = dst.getBox(); const hier::Box s_box = src.getBox(); const hier::Box ibox = box * d_box * s_box; if (!ibox.empty()) { const int ddepth = dst.getDepth(); int box_w[SAMRAI::MAX_DIM_VAL]; int d_w[SAMRAI::MAX_DIM_VAL]; int s_w[SAMRAI::MAX_DIM_VAL]; int dim_counter[SAMRAI::MAX_DIM_VAL]; for (tbox::Dimension::dir_t i = 0; i < dimVal; ++i) { box_w[i] = ibox.numberCells(i); d_w[i] = d_box.numberCells(i); s_w[i] = s_box.numberCells(i); dim_counter[i] = 0; } const size_t d_offset = dst.getOffset(); const size_t s_offset = src.getOffset(); const int num_d0_blocks = static_cast<int>(ibox.size() / box_w[0]); size_t d_begin = d_box.offset(ibox.lower()); size_t s_begin = s_box.offset(ibox.lower()); TYPE* dd = dst.getPointer(); const TYPE* sd = src.getPointer(); for (int d = 0; d < ddepth; ++d) { size_t d_counter = d_begin; size_t s_counter = s_begin; int d_b[SAMRAI::MAX_DIM_VAL]; int s_b[SAMRAI::MAX_DIM_VAL]; for (tbox::Dimension::dir_t nd = 0; nd < dimVal; ++nd) { d_b[nd] = static_cast<int>(d_counter); s_b[nd] = static_cast<int>(s_counter); } for (int nb = 0; nb < num_d0_blocks; ++nb) { for (int i0 = 0; i0 < box_w[0]; ++i0) { dd[d_counter + i0] = ( (tbox::MathUtilities<TYPE>::Abs(sd[s_counter + i0]) >= alpha) ? 1.0F : 0.0F); } int dim_jump = 0; for (tbox::Dimension::dir_t j = 1; j < dimVal; ++j) { if (dim_counter[j] < box_w[j] - 1) { ++dim_counter[j]; dim_jump = j; break; } else { dim_counter[j] = 0; } } if (dim_jump > 0) { int d_step = 1; int s_step = 1; for (int k = 0; k < dim_jump; ++k) { d_step *= d_w[k]; s_step *= s_w[k]; } d_counter = d_b[dim_jump - 1] + d_step; s_counter = s_b[dim_jump - 1] + s_step; for (int m = 0; m < dim_jump; ++m) { d_b[m] = static_cast<int>(d_counter); s_b[m] = static_cast<int>(s_counter); } } } d_begin += d_offset; s_begin += s_offset; } } }
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); }