Closed sseraj closed 1 year ago
Merging #179 (3634dc3) into main (1f6a7c3) will increase coverage by
0.02%
. The diff coverage is100.00%
.
@@ 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
Impacted Files | Coverage Δ | |
---|---|---|
pygeo/pyBlock.py | 47.87% <100.00%> (+0.85%) |
:arrow_up: |
:mega: We’re building smart automated test selection to slash your CI/CD build times. Learn more
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.
Do we want to handle these logical checks in this PR, or merge this, and work on the logical checks separately?
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.
@sseraj suggested merging this PR as is because it does not change the default behavior and only affects performance. So we will do my suggested changes in #181
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