Skip to content
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

Added option to project thickness contraints #238

Merged
merged 10 commits into from
Mar 25, 2024

Conversation

joanibal
Copy link
Collaborator

@joanibal joanibal commented Mar 7, 2024

Purpose

This PR adds the option to use the component of the toothpick thickness aligned with the original thickness direction for the constraint value.
I added this feature to combat situations where the skew of my toothpick constraints was allowing for self intersection.

In the figure below the gray mesh is the deformed FFD, the red line is the original directions of the thickness constraints and the thick black lines are the thickness constraints. The original direction of the thickness constraint is purely in the y-axis, but it is skewd by a deformation of FFD in the x-axis. With the an unprojected thickness constraint this would result in an increased thickness value, but with this projected constraint it would not.
Screenshot 2024-03-06 at 3 49 19 PM

Expected time until merged

a week would be nice

Type of change

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (non-backwards-compatible fix or feature)
  • Code style update (formatting, renaming)
  • Refactoring (no functional changes, no API changes)
  • Documentation update
  • Maintenance update
  • Other (please describe)

Testing

See the new tests added to test_DVConstraints.py

Checklist

  • I have run flake8 and black to make sure the Python code adheres to PEP-8 and is consistently formatted
  • I have formatted the Fortran code with fprettify or C/C++ code with clang-format as applicable
  • I have run unit and regression tests which pass locally with my changes
  • I have added new tests that prove my fix is effective or that my feature works
  • I have added necessary documentation

@joanibal joanibal requested a review from a team as a code owner March 7, 2024 00:35
@joanibal joanibal requested review from marcomangano and sseraj March 7, 2024 00:35
Copy link

codecov bot commented Mar 7, 2024

Codecov Report

Attention: Patch coverage is 68.33333% with 19 lines in your changes are missing coverage. Please review.

Project coverage is 65.46%. Comparing base (820ef71) to head (f60d9ad).

Files Patch % Lines
pygeo/constraints/thicknessConstraint.py 62.74% 19 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main     #238   +/-   ##
=======================================
  Coverage   65.45%   65.46%           
=======================================
  Files          47       47           
  Lines       12208    12265   +57     
=======================================
+ Hits         7991     8029   +38     
- Misses       4217     4236   +19     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@joanibal
Copy link
Collaborator Author

joanibal commented Mar 7, 2024

This is ready for review

@marcomangano
Copy link
Contributor

This looks really interesting, I will try and take a look at this in the next few days. Can I ask what kind of DV setup / optimization made you bump into this issue?

@joanibal
Copy link
Collaborator Author

joanibal commented Mar 7, 2024

Thank Marco. I'm doing some funky stuff with OpenVSP where I'm changing the shape in the x and y-axis.

@lamkina
Copy link
Contributor

lamkina commented Mar 10, 2024

I also want to take a look at this PR this week and dig into this problem some more. I have been facing this issue with toothpicks and OpenVSP for a few years now.

@lamkina lamkina self-requested a review March 10, 2024 18:49
@sseraj sseraj removed their request for review March 11, 2024 16:05
Copy link
Contributor

@marcomangano marcomangano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gave a first pass, left some comments, looking good! There's quite a bit of code duplication as per pyGeo fashion but we will address that in a future effort

@@ -320,6 +320,53 @@ def test_thickness1D_box(self, train=False, refDeriv=False):
funcs["DVCon1_thickness_constraints_2"], 8.0 * np.ones(3), name="thickness_base", rtol=1e-7, atol=1e-7
)

def test_projected_thickness1D_box(self, train=False, refDeriv=False):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we could use parameterized to avoid code duplication with the previous test

Copy link
Collaborator Author

@joanibal joanibal Mar 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps, but the skewing of the design variables (line 347 onward) is different enough that it wouldn't be trivial. If we add another thickness con it might be worth creating a common function like self.genertate_dvgo_dvcon that does some common thickness testing. But since it is only like 30 lines of duplicated code total for both tests, I think its probably fine.

@@ -399,6 +446,64 @@ def test_thickness2D_box(self, train=False, refDeriv=False):
funcs["DVCon1_thickness_constraints_2"], 8.0 * np.ones(4), name="thickness_base", rtol=1e-7, atol=1e-7
)

def test_projected_thickness2D_box(self, train=False, refDeriv=False):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here?

for i in range(len(self.coords) // 2):
handle.write("%d %d\n" % (2 * i + 1, 2 * i + 2))

handle.write("Zone T=%s_ref_directions\n" % self.name)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add a comment here to explain that the projected toothpicks are saved in a different zone for visualization purposes

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added!

if self.scaled:
D_b /= self.D0[i]

# d(dot(vec,n)/dvec = n
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mind making this derivative more explicit? There's a bracket missing but it looks like replacing eDist_b is the main step here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added more comments let me know what you think

@joanibal joanibal requested a review from marcomangano March 22, 2024 17:48
@joanibal
Copy link
Collaborator Author

It's ready for review again

Chill flake8 it's just white space it can't hurt you
@lamkina
Copy link
Contributor

lamkina commented Mar 22, 2024

I have a few concerns about this change, but it's mostly related to using thickness constraints with VSP generated surfaces in general.

VSP uses Bézier curves and surfaces to represent geometry. However, Bezier are not piecewise continuous like BSplines so the surface is actually decomposed into many Bézier patches. Each patch has its own u, v parameter space that can change individually. As we deform the surfaces in directions that are not parallel to the initial thickness constraints, the u, v parameters move on the individual surfaces and our initial mapping for toothpick endpoints is skewed.

With that said, if you change the top and bottom surface patches in directions non-parallel to the initial toothpick directions, it will actually move the entire constraint. This is very easy to do with VSP parameterizations. Again, this is a symptom of the thickness constraints in general with VSP, not just specific to this PR.

However, I do think this PR is a bit of a misnomer in the sense it's not actually fixing the underlying issue with the thickness constraints. In reality, the fix for this would be doing a nonlinear solve to find the new parametric coordinates that preserve the initial Cartesian orientation of the thickness constraints. I even think this issue permeates every geometry where we apply toothpick constraints with non-parallel deformations to the geometry. Most times this deformation is small and not picked up, but with VSP it is more noticeable because each Bezier patch has it's own parameter space.

@joanibal
Copy link
Collaborator Author

With that said, if you change the top and bottom surface patches in directions non-perpendicular to the initial toothpick directions, it will actually move the entire constraint. This is very easy to do with VSP parameterizations. Again, this is a symptom of the thickness constraints in general with VSP, not just specific to this PR.

I actually want the entire constraint to move for my particular case so I see this as a feature. I can see why you would also want constraints that are reprojected to the UV coordinate space.

However, I do think this PR is a bit of a misnomer in the sense it's not actually fixing the underlying issue with the thickness constraints.

I understand what you are saying and made the intentional choice to take a simpler path.
If time wasn't a factor, it would be nice to have a constraint where one end is locked to a U,V coordinate and the other end is reprojected to UV space. For me this PR improves upon the issue of skewed thickness constraints enough to be worth adding to the code even if there hypothetically better means.
In regard to the name, I'm not opposed to changing it if you have another idea. Although, I'd say this using the dot product here is just projecting in a different sense.

Let me know if I haven't interpreted what you are seeing as the underlying issue correctly (a picture may help me here).

@lamkina
Copy link
Contributor

lamkina commented Mar 22, 2024

I actually want the entire constraint to move for my particular case so I see this as a feature. I can see why you would also want constraints that are reprojected to the UV coordinate space.

I can see the utility of the constraints moving if you are changing the geometry in multiple axis directions. I don't have an issue with this in general, it's more that we don't clarify the behavior anywhere and it works differently depending on which tools created the underlying geometry.

I understand what you are saying and made the intentional choice to take a simpler path.
If time wasn't a factor, it would be nice to have a constraint where one end is locked to a U,V coordinate and the other end is reprojected to UV space. For me this PR improves upon the issue of skewed thickness constraints enough to be worth adding to the code even if there hypothetically better means.
In regard to the name, I'm not opposed to changing it if you have another idea. Although, I'd say this using the dot product here is just projecting in a different sense.

In this case, I am okay with adding the projected constraints, but I think we should add a description of the behavior to the docstrings of the toothpick constraints. We can tackle adding the feature I described above in a different PR, I didn't expect you to implement that as it's going to be involved. I just wanted to make sure you knew why these things are sliding around and skewing.

@lamkina
Copy link
Contributor

lamkina commented Mar 22, 2024

In regard to the name, I'm not opposed to changing it if you have another idea. Although, I'd say this using the dot product here is just projecting in a different sense.

The naming scheme makes sense. In the future I think we will have a few flavors of the thickness constraints with more consistent behavior.

@joanibal
Copy link
Collaborator Author

joanibal commented Mar 22, 2024

it works differently depending on which tools created the underlying geometry.

I'm not following this part. If the constraints was embedded in an DVGeo FFD object and there were changes along multiple axis it should work the same.

@lamkina
Copy link
Contributor

lamkina commented Mar 22, 2024

I'm not following this part. If the constraints was embedded in an DVGeo FFD object and there were changes along multiple axis it should work the same.

My fault, I thought you were directly changing VSP variables and forgot you mentioned you are using an FFD, in which case this works differently (but also kind of makes my point on why this is confusing).

Copy link
Contributor

@lamkina lamkina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks ready to go.

Copy link
Contributor

@marcomangano marcomangano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you!

@marcomangano marcomangano merged commit 9caea1a into mdolab:main Mar 25, 2024
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants