-
Notifications
You must be signed in to change notification settings - Fork 55
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
Efficient interior-only embedding #179
Conversation
Codecov Report
@@ Coverage Diff @@
## main #179 +/- ##
==========================================
+ Coverage 64.74% 64.76% +0.02%
==========================================
Files 47 47
Lines 11941 11949 +8
==========================================
+ Hits 7731 7739 +8
Misses 4210 4210
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
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.
Excellent, just a couple of minor questions/comments
I suggest we combine the changes from #181 in this PR. I want the embedding logic to work with a few different scenarios: The points can be outside the convex hull, the points can be between convex hull and the embedding volume, points can be inside embedding volume but projection doesn't converge, and finally, points can be inside the volume and projection works. On top of this, the user may want all points to be tracked by the FFD, or only the points inside the embedding volume to be tracked. Right now, the parent FFD will try to embed all points; if some are outside the embedding volume, the closest projection is picked. We address this in #181 by throwing an error because this modifies the surface geometry without the users realizing. This default behavior was originally to catch any projection tolerance issues when points were inside the domain, but with the recent changes, these should happen much less frequently. I suggest we combine the convex hull check with these checks. There is also a use case where users only want part of the geometry modified. Previously, people would recommend using a parent FFD that includes the entire geometry while having a child FFD for the local design changes. This is absolutely pointless and we can just get the same effect by letting the FFD only work with the embedded points. This behavior can be achieved right now, but it is not intuitive; the users would need to pass an additional kwargs to the setDVGeo call. My question for @sseraj, @ArshSaja, and @hajdik: Do we want to handle these logical checks in this PR, or merge this, and work on the logical checks separately? I also want to add a more intuitive way to enable the "local FFD" approach where the entire geometry is not contained within the FFD, but the FFD only works with the points that can be successfully embedded. For example, it would be great if we could have a mode where the embedding just ignores all points outside the convex hull, and raises either a warning or an error if points are inside the convex hull, but cannot be fully embedded, which means they are either outside the embedding volume or the solver did not work. This would raise an error for the most general FFD usage case where the entire geometry is inside the FFD, and only a warning when a "local FFD" is used. Similarly, we can raise warnings when child FFDs are used but some points inside their convex hull is not embedded properly. Right now, there is no feedback for this, and users only realize embedding errors after they change the design on the child FFD. |
I'm fine either way. We could merge this now if there is anyone who needs this speedup on child FFDs right now, or keep all the changes together if we want one cohesive PR on embedding improvements. |
I would slightly prefer having the changes contained in one PR, but it is up to @sseraj. |
Purpose
I was running into long startup times when using child FFDs. The problem is that the embedding process for child FFDs can involve many points outside of the child FFD volume(s), and projecting these exterior points is expensive. In addition, projecting exterior points is more expensive with pySpline v1.5.2 than v1.5.1 because of the change in convergence criteria made in mdolab/pyspline#47.
To reduce the cost, I added a convex hull check for child FFDs (
interiorOnly=True
). One of the properties of B-splines is that they are contained within the convex hull of its control points. This means that if a point is outside the convex hull of the child FFD control points, we can skip the projection step because the point cannot be inside the FFD volume(s).To test this, I timed the projection of a wing triangulated surface to a parent wing FFD and two child flap FFDs. The times in seconds are given in the table below:
The projection times for the child FFDs are much faster with the convex hull check. The cost is similar now between pySpline versions because most exterior points are never passed to the projection routine.
I also initially tried a bounding box check, which you can see in the first commit on this branch. The bounding box is larger than the convex hull, so the projection is more expensive if the bounding box is not a close match for the FFD volume(s).
Expected time until merged
1 week
Type of change
Testing
One-level FFD behavior is unchanged. The current child FFD tests pass, including the box constraint tests, which test the edge case where the FFD volume and convex hull are coincident with points lying on surface of the FFD volume. I also tested this on more realistic wing and full configuration cases.
Checklist
flake8
andblack
to make sure the Python code adheres to PEP-8 and is consistently formattedfprettify
or C/C++ code withclang-format
as applicable