-
Notifications
You must be signed in to change notification settings - Fork 542
Add transformation boundary condition #3402
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Add transformation boundary condition #3402
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few streamlining suggestions
else: | ||
for key in transformation: | ||
if key not in ["direction", "position"]: | ||
msg = ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you need to use this msg
for key in transformation: | ||
if key not in ["direction", "position"]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for key in transformation: | |
if key not in ["direction", "position"]: | |
valid_keys = {"direction", "position"} | |
for key in set(transformation.keys()) - valid_keys: |
if "direction" in transformation.keys(): | ||
check_type( | ||
'transformation', transformation["direction"], | ||
Iterable, | ||
Real) | ||
check_length( | ||
'transformation', transformation["direction"], 12) | ||
else: | ||
transformation["direction"] = np.append( | ||
np.identity(3), np.zeros(3,1), axis=1).flatten() | ||
|
||
if "position" in transformation.keys(): | ||
check_type( | ||
'transformation', transformation["position"], | ||
Iterable, | ||
Real) | ||
check_length( | ||
'transformation', transformation["position"], 12) | ||
else: | ||
transformation["position"] = np.append( | ||
np.identity(3), np.zeros(3,1), axis=1).flatten() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if "direction" in transformation.keys(): | |
check_type( | |
'transformation', transformation["direction"], | |
Iterable, | |
Real) | |
check_length( | |
'transformation', transformation["direction"], 12) | |
else: | |
transformation["direction"] = np.append( | |
np.identity(3), np.zeros(3,1), axis=1).flatten() | |
if "position" in transformation.keys(): | |
check_type( | |
'transformation', transformation["position"], | |
Iterable, | |
Real) | |
check_length( | |
'transformation', transformation["position"], 12) | |
else: | |
transformation["position"] = np.append( | |
np.identity(3), np.zeros(3,1), axis=1).flatten() | |
for key in valid_keys | |
if key in transformation: | |
check_type( | |
'transformation', transformation[key], | |
Iterable, | |
Real) | |
check_length( | |
'transformation', transformation[key], 12) | |
else: | |
transformation[key] = np.append( | |
np.identity(3), np.zeros(3,1), axis=1).flatten() |
@@ -88,6 +88,38 @@ Surface::Surface(pugi::xml_node surf_node) | |||
bc_ = make_unique<WhiteBC>(); | |||
} else if (surf_bc == "periodic") { | |||
// Periodic BCs are handled separately | |||
} else if (surf_bc == "transformation" || surf_bc == "transform") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May not be necessary to support two similar keywords
|
||
// Reassign particle's cell and surface | ||
coord(0).cell = cell_last(0); | ||
surface() = -surface(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may require more thought and consideration
Description
Adds a transformation boundary condition to surfaces through which the user can define affine transformations to particle position and direction upon crossing the surface.
Mathematically, each affine transformation$\textbf{v} \rightarrow \textbf{v}'$ can be expressed as
where$A$ is a $3 \times 3$ matrix representing a linear map and $\textbf{b}$ is a vector of length 3 representing a translation. This transformation can be described in a single matrix-vector product via an augmented matrix and augmented vector:
where$\textbf{a}_i$ is the $i^{th}$ column of $A$ . I'll refer to this 3x4 augmented matrix $[A | \textbf{b}]$ as an "affine transformation matrix".
In the Python API, the affine transformations are defined by a keyword argument
transformation
of theSurface
class that is used only ifboundary_type == "transformation"
.transformation
takes the form of a dictionary with two optional keys:"direction"
: the affine transformation matrix modifying particle direction, given in row-major order"position"
: the affine transformation matrix modifying particle position, given in row-major orderWhen$[\mathbb{I}_3 | \textbf{0}_3]$ , where $\mathbb{I}_3$ is the $3 \times 3$ identity matrix and $\textbf{0}_3$ is the length-3 zero vector.
boundary_type == "transformation"
, for each key that is not provided, the affine transformation matrix is defined asA single regression test,
transformation_plane
has been added that mimics thereflective_plane
test, replacing the reflective BCs with transformation BCs that apply those same reflections. The expected results file is copied directly from thereflective_plane
directory. I can add additional regression tests that mimic the periodic BC tests for more robust testing.Fixes #3394
Checklist