mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-28 14:15:42 -04:00
added infix evaluation and removed conversion of infix to postfix
This commit is contained in:
parent
925a5f6bb6
commit
29a741a441
1 changed files with 38 additions and 41 deletions
79
src/cell.cpp
79
src/cell.cpp
|
|
@ -515,7 +515,8 @@ CSGCell::CSGCell(pugi::xml_node cell_node)
|
|||
}
|
||||
|
||||
// Convert the infix region spec to RPN.
|
||||
rpn_ = generate_rpn(id_, region_);
|
||||
//rpn_ = generate_rpn(id_, region_);
|
||||
rpn_ = region_;
|
||||
|
||||
// Check if this is a simple cell.
|
||||
simple_ = true;
|
||||
|
|
@ -768,50 +769,46 @@ bool CSGCell::contains_simple(Position r, Direction u, int32_t on_surface) const
|
|||
bool CSGCell::contains_complex(
|
||||
Position r, Direction u, int32_t on_surface) const
|
||||
{
|
||||
// Make a stack of booleans. We don't know how big it needs to be, but we do
|
||||
// know that rpn.size() is an upper-bound.
|
||||
vector<bool> stack(rpn_.size());
|
||||
int i_stack = -1;
|
||||
bool in_cell = true;
|
||||
bool negate = false;
|
||||
int paren_depth = 0;
|
||||
int negate_depth = 0;
|
||||
|
||||
for (int32_t token : rpn_) {
|
||||
// If the token is a binary operator (intersection/union), apply it to
|
||||
// the last two items on the stack. If the token is a unary operator
|
||||
// (complement), apply it to the last item on the stack.
|
||||
if (token == OP_UNION) {
|
||||
stack[i_stack - 1] = stack[i_stack - 1] || stack[i_stack];
|
||||
i_stack--;
|
||||
} else if (token == OP_INTERSECTION) {
|
||||
stack[i_stack - 1] = stack[i_stack - 1] && stack[i_stack];
|
||||
i_stack--;
|
||||
} else if (token == OP_COMPLEMENT) {
|
||||
stack[i_stack] = !stack[i_stack];
|
||||
} else {
|
||||
// If the token is not an operator, evaluate the sense of particle with
|
||||
// respect to the surface and see if the token matches the sense. If the
|
||||
// particle's surface attribute is set and matches the token, that
|
||||
// overrides the determination based on sense().
|
||||
i_stack++;
|
||||
if (token == on_surface) {
|
||||
stack[i_stack] = true;
|
||||
} else if (-token == on_surface) {
|
||||
stack[i_stack] = false;
|
||||
} else {
|
||||
// Note the off-by-one indexing
|
||||
bool sense = model::surfaces[abs(token) - 1]->sense(r, u);
|
||||
stack[i_stack] = (sense == (token > 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (token < OP_UNION && in_cell == true) {
|
||||
if (token == on_surface) {
|
||||
in_cell = true;
|
||||
} else if (-token == on_surface) {
|
||||
in_cell = false;
|
||||
} else {
|
||||
// Note the off-by-one
|
||||
bool sense = model::surfaces[abs(token) - 1]->sense(r, u);
|
||||
in_cell = (sense == (token > 0));
|
||||
}
|
||||
} else if (token == OP_UNION) {
|
||||
if (in_cell == false) {
|
||||
in_cell = true;
|
||||
} else if (paren_depth == 0) {
|
||||
break;
|
||||
}
|
||||
} else if (token == OP_RIGHT_PAREN) {
|
||||
paren_depth--;
|
||||
} else if (token == OP_LEFT_PAREN) {
|
||||
paren_depth++;
|
||||
} else if (token == OP_COMPLEMENT) {
|
||||
negate = true;
|
||||
negate_depth = paren_depth;
|
||||
continue;
|
||||
} else if (paren_depth == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (i_stack == 0) {
|
||||
// The one remaining bool on the stack indicates whether the particle is
|
||||
// in the cell.
|
||||
return stack[i_stack];
|
||||
} else {
|
||||
// This case occurs if there is no region specification since i_stack will
|
||||
// still be -1.
|
||||
return true;
|
||||
if (negate == true && negate_depth == paren_depth) {
|
||||
in_cell = !in_cell;
|
||||
negate = false;
|
||||
}
|
||||
}
|
||||
return in_cell;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue