Update for case where the entire region is a complement. Addition of a cell and redefinition of another to test more robustly.

This commit is contained in:
Patrick Shriwise 2019-07-24 03:02:10 -05:00
parent d820e6777a
commit 3439797e32
3 changed files with 27 additions and 12 deletions

View file

@ -212,6 +212,7 @@ 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<int32_t> rpn);
static void apply_demorgan(std::vector<int32_t>& rpn);
};
//==============================================================================

View file

@ -587,8 +587,25 @@ BoundingBox CSGCell::bounding_box_simple() const {
return bbox;
}
void CSGCell::apply_demorgan(std::vector<int32_t>& rpn) {
for (auto& token : rpn) {
if (token < OP_UNION) { token *= -1; }
else if (token == OP_UNION) { token = OP_INTERSECTION; }
else if (token == OP_INTERSECTION) { token = OP_UNION; }
}
}
BoundingBox CSGCell::bounding_box_complex(std::vector<int32_t> rpn) {
// if the last operator is a complement op, there is no
// sub-region that the complement connects to. This indicates
// that the entire region is a complement and we can apply
// De Morgan's laws immediately
if ((rpn.back() == OP_COMPLEMENT)) {
rpn.pop_back();
apply_demorgan(rpn);
}
std::reverse(rpn.begin(), rpn.end());
BoundingBox current = model::surfaces[abs(rpn.back()) - 1]->bounding_box(rpn.back() > 0);
@ -626,11 +643,7 @@ BoundingBox CSGCell::bounding_box_complex(std::vector<int32_t> rpn) {
// handle complement case using De Morgan's laws
if (subrpn.back() == OP_COMPLEMENT) {
subrpn.pop_back();
for (auto& token : subrpn) {
if (token < OP_UNION) { token *= -1; }
else if (token == OP_UNION) { token = OP_INTERSECTION; }
else if (token == OP_INTERSECTION) { token = OP_UNION; }
}
apply_demorgan(subrpn);
subrpn.push_back(rpn.back());
rpn.pop_back();
}

View file

@ -46,7 +46,7 @@ def complex_cell(run_in_tmpdir):
s17 = openmc.YPlane(y0=0.0)
c1 = openmc.Cell(fill=u235)
c1.region = +s3 & -s4 & +s13 & -s14
c1.region = ~(-s3 | +s4 | ~(+s13 & -s14))
c2 = openmc.Cell(fill=u238)
c2.region = +s2 & -s5 & +s12 & -s15 & ~(+s3 & -s4 & +s13 & -s14)
@ -59,8 +59,11 @@ def complex_cell(run_in_tmpdir):
c4.region = ((+s1 & -s7 & +s11 & -s17) | (+s7 & -s6 & +s17 & -s16)) & \
~(+s2 & -s5 & +s12 & -s15)
c5 = openmc.Cell(fill=n14)
c5.region = ~(+s1 & -s6 & +s11 & -s16)
model.geometry.root_universe = openmc.Universe()
model.geometry.root_universe.add_cells([c1, c2, c3, c4])
model.geometry.root_universe.add_cells([c1, c2, c3, c4, c5])
model.settings.batches = 10
model.settings.inactive = 5
@ -84,13 +87,11 @@ inf = sys.float_info.max
expected_results = ( (1, (( -4., -4., -inf), ( 4., 4., inf))),
(2, (( -7., -7., -inf), ( 7., 7., inf))),
(3, ((-10., -10., -inf), (10., 10., inf))),
(4, ((-10., -10., -inf), (10., 10., inf))) )
(4, ((-10., -10., -inf), (10., 10., inf))),
(5, ((-inf, -inf, -inf), (inf, inf, inf))) )
@pytest.mark.parametrize("cell_id,expected_box", expected_results)
def test_cell_box(cell_id, expected_box):
print("Cell {}".format(cell_id))
cell_box = openmc.capi.cells[cell_id].bounding_box
assert tuple(cell_box[0]) == expected_box[0]
assert tuple(cell_box[1]) == expected_box[1]
cell_box = openmc.capi.bounding_box("Cell", cell_id)
assert tuple(cell_box[0]) == expected_box[0]
assert tuple(cell_box[1]) == expected_box[1]