Description
SVD (U \Sigma V^T = A) is used to figure out a local coordinate frame. This is done by looking at the columns of the U matrix. The first column is a best fit line through the points that define that FFD section. The second column is the next best fit that is orthogonal to the first one; this ends up being the second vector that defines the section tangents (although not exactly). Then the third one is the last orthogonal vector that spans the 3 dimensional space, and that ends up being orthogonal to the section surface itself.
The SVD is only unique up to a sign change of these vectors in the U and V matrices. So while the U1 U2 and U3 vectorsโ orientations are correct, their โsenseโ (what way the arrow is pointing to) can vary based on what machine its running on.
I realized that the sectional DVs on the dlr f6 case ended up getting a wrong direction on some of the sections when I ran it on docker, vs natively on the same computer. So far, seems like the SVD has been giving consistent results for everyone, but it can totally flip direction if not careful. I think even if you provide an โorient0" direction, the other two directions can still flip. If you do not provide any orient directions, then all 3 vectors can flip either way.
The method to create sectional DVs: https://github.com/mdolab/pygeo/blob/master/pygeo/DVGeometry.py#L689
During its setup, it calls https://github.com/mdolab/pygeo/blob/master/pygeo/DVGeometry.py#L3407 to figure out the sectional coordinates.
Here is the SVD where we take the U matrix from: https://github.com/mdolab/pygeo/blob/master/pygeo/DVGeometry.py#L3505
The sectionFrame
method can take in an optional argument orient0
, which is a way to correctly orient the first basis vector. However, this does not fully fix the solution as the other two vectors can still flip among themselves. If orient0
is not provided, then all 3 vectors can flip direction.
Suggested Solution
My suggested solution is to make sure we align these vectors with some of the directions introduced by the FFD. So I am proposing computing the โfinite differenceโ version of these vectors with the FFD, and then using the sign of the dot product of these FFD vectors with the SVD vectors to flip the SVD vectors if required.
At least for Neyโs F6 stuff, this fix flips the direction of the sectional DV changes. However, this fix does make it consistent between my native and docker runs.
My suggested solution will most likely break the runscripts that have been using this in the past.
Steps to reproduce issue
I am attaching a simple FFD box and a python test script. There are 16 total FFD control points we select and we define normal DVs using these. When run with the current default branch of pygeo (commit: f8176b0) the control points on the upper side ends up flipping in direction when I run it natively on my mac vs docker running on my mac.
pygeo_sectional_test.zip
Current behavior
The SVD can result in vectors that change in sense between computers, and this can lead to "flipping" of design variable directions.
Expected behavior
The local coordinate system computed for FFD sections should be unique.