From 85fa32150ad0788ed64ba1cd6011398d33bfd76f Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Mon, 9 Sep 2019 00:15:23 -0500 Subject: [PATCH] Still needs work --- include/openmc/cell.h | 3 +- src/cell.cpp | 139 ++++++++++++++++++++++++++++++------------ 2 files changed, 101 insertions(+), 41 deletions(-) diff --git a/include/openmc/cell.h b/include/openmc/cell.h index db8d60ed4..2c8495560 100644 --- a/include/openmc/cell.h +++ b/include/openmc/cell.h @@ -212,7 +212,8 @@ protected: bool contains_complex(Position r, Direction u, int32_t on_surface) const; BoundingBox bounding_box_simple() const; static BoundingBox bounding_box_complex(std::vector rpn); - static void apply_demorgan(std::vector& rpn); + static void apply_demorgan(std::vector::iterator start, + std::vector::iterator end); }; //============================================================================== diff --git a/src/cell.cpp b/src/cell.cpp index 225d2a53d..99ac9f43f 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -598,12 +598,48 @@ BoundingBox CSGCell::bounding_box_simple() const { return bbox; } +auto find_right_parenthesis(std::vector::iterator start, + std::vector& rpn) +{ + // parenthesis level counter + int counter = 1; + std::cout << "FINDING" << std::endl; + // start at the beginning + auto it = start; + while(it < rpn.end()) { + int32_t one = *it; + int32_t two = *(it+1); -void CSGCell::apply_demorgan(std::vector& rpn) { - for (auto& token : rpn) { + std::cout << "Counter: " << counter << std::endl; + std::cout << "One: " << one << std::endl; + std::cout << "Two: " << two << std::endl; + + if (one < OP_UNION && two < OP_UNION) { + counter++; + } else if (one >= OP_UNION && two >= OP_UNION) { + counter--; + } + + if (counter == 0) { + if (two == OP_COMPLEMENT) { it++; } + std::cout << "BREAK" << std::endl; + break; + } + it++; + } + std::cout << "DONE" << std::endl; + return it; +} + +void CSGCell::apply_demorgan(std::vector::iterator start, + std::vector::iterator end) { + auto it = start; + while (it <= end) { + int32_t token = *it; if (token < OP_UNION) { token *= -1; } else if (token == OP_UNION) { token = OP_INTERSECTION; } else if (token == OP_INTERSECTION) { token = OP_UNION; } + it++; } } @@ -615,19 +651,26 @@ BoundingBox CSGCell::bounding_box_complex(std::vector rpn) { // De Morgan's laws immediately if (rpn.back() == OP_COMPLEMENT) { rpn.pop_back(); - apply_demorgan(rpn); + apply_demorgan(rpn.begin(), rpn.end()); } - auto it = rpn.begin(); - BoundingBox current = model::surfaces[abs(*it) - 1]->bounding_box(*it > 0); - it++; + std::cout << "RPN" << std::endl; + for (auto i : rpn) { std::cout << i << " "; } + std::cout << std::endl; + // start with an invalid box + BoundingBox current; + current.xmin = INFTY; + current.xmax = -INFTY; + + auto it = rpn.begin(); while (it < rpn.end()) { // move through the rpn in twos - int32_t one = *it; - it++; - int32_t two = *it; - it++; + int32_t one = *it; it++; + int32_t two = *it; it++; + + std::cout << "One: " << one << std::endl; + std::cout << "Two: " << two << std::endl; // the first token should always be a surface Expects(one < OP_UNION); @@ -639,39 +682,55 @@ BoundingBox CSGCell::bounding_box_complex(std::vector rpn) { current &= model::surfaces[abs(one)-1]->bounding_box(one > 0); } } else { - // two surfaces in a row (left parenthesis), - // create sub-rpn for region in parenthesis - std::vector subrpn; - subrpn.push_back(one); - subrpn.push_back(two); - // add until last two tokens in the sub-rpn are operators - // (indicates a right parenthesis) - while (!((*it >= OP_UNION) && (*(it + 1) >= OP_UNION))) { - subrpn.push_back(*it); - it++; - } - // add first operator to the subrpn - subrpn.push_back(*it); - it++; + auto close = find_right_parenthesis(it, rpn); - // handle complement case using De Morgan's laws - if (*it == OP_COMPLEMENT) { - apply_demorgan(subrpn); - it++; - } - // save the last operator, tells us how to combine this region - // with our current bounding box - int32_t op = *it; - it++; - // get bounding box for the subrpn - BoundingBox sub_box = bounding_box_complex(subrpn); - // combine the sub-rpn bounding box with our current cell box - if (op == OP_UNION) { - current |= sub_box; - } else if (op == OP_INTERSECTION) { - current &= sub_box; + std::vector subrpn(it - 2, close); + + if (*close == OP_COMPLEMENT && *it < OP_UNION) { + apply_demorgan(it - 2, close); + it -= 2; + } else if (close == rpn.end()) { + current = model::surfaces[abs(one)-1]->bounding_box(one > 0); + it--; + } else { + int32_t op = *it; + BoundingBox sub_box = bounding_box_complex(subrpn); + // combine the sub-rpn bounding box with our current cell box + if (op == OP_UNION) { + current |= sub_box; + } else if (op == OP_INTERSECTION) { + current &= sub_box; + } + it = close; } + // // two surfaces in a row (left parenthesis), + // // create sub-rpn for region in parenthesis + // std::vector subrpn; + // subrpn.push_back(one); + // subrpn.push_back(two); + // // add until last two tokens in the sub-rpn are operators + // // (indicates a right parenthesis) + // while (!((*it >= OP_UNION) && (*(it + 1) >= OP_UNION))) { + // subrpn.push_back(*it); + // it++; + // } + + // // add first operator to the subrpn + // subrpn.push_back(*it); + // it++; + + // // handle complement case using De Morgan's laws + // if (*it == OP_COMPLEMENT) { + // apply_demorgan(subrpn); + // it++; + // } + // // save the last operator, tells us how to combine this region + // // with our current bounding box + // int32_t op = *it; + // it++; + // // get bounding box for the subrpn + // BoundingBox sub_box = bounding_box_complex(subrpn); } }