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

Gaussian Process Buckling Constraints in Blade Stiffened Shell Constitutive Subclass #311

Merged
merged 124 commits into from
Oct 22, 2024

Conversation

sean-engelstad
Copy link
Contributor

@sean-engelstad sean-engelstad commented Apr 25, 2024

This code is linked to the repo, ml_buckling

  • Use Gaussian Processes (statistical machine learning approach) to learn buckling constraints
  • Created a new subclass TACSGPBladeStiffenedShellConstitutive from the base class TACSBladeStiffenedShellConstitutive, which overrides the buckling constraints and combined buckling-stress failure criterion
  • Buckling constraints include global + local modes for axial and shear (same as before except more accurate). Also stiffener crippling modes are treated as well.
  • The TACSBladeStiffenedShellConstitutive used panel length as a DV which was enforced to be equal to the actual panel length from a separate computation of a panel length constraint. In the new class TACSGPBladeStiffenedShellConstitutive, panel width is also required, and both the panel length and width need to be set in at runtime through some additional infrastructure in TACS (not through a constraint => as this doesn't work great with our FUNtoFEM + ESP/CAPS infrastructure).

TODO:

  • Implement the machine learning buckling constraints (so far just have the closed-form ones implemented).
  • Update the failure criterion and sensitivity computations using the new buckling constraints.
  • Add panel width constraint in tacs/constraints
  • Add internal tests to the TACSGPBladeStiffenedShellConstitutive class for the following subtests:
    • Nondimensional parameters
    • Critical loads
    • GP Model kernel and predictMeanTestData sens tests
  • Fix so all internal tests pass
    • Closed-form case
    • Machine learning case
    • Add printLevel to each of these tests so you can turn it off
  • Fix so failure tests pass
    • Add ply fraction derivs in DV failure test
    • failStrain test
    • failDV test
  • Check the physical correctness of the smeared vs unsmeared stiffness computation when using the energy closed-form
    • Double check if the computePanelStiffness() which uses smearedStiffnesses is correct or if we need a new unsmeared routine here.
    • Add computeStiffenerCripplingStiffness() routine for panel-like stiffness of the stiffener
  • Add cython objects for this class to be constructed.
  • Add full up test of the failure criterion and internal tests from the python level
  • Implement the panel length, width constraints as state variables for each TACS component in the FUNtoFEM TACS interface. Probably don't need a new state variable class, just store these values in lists representing each TACS component.
    • Compute a chain rule product of panel length, width variables to get the total shape derivatives for these state variables in FUNtoFEM and just update these state variables inside of FUNtoFEM. Don't want to expose these to the optimizer.
  • Add in the ML data and a way to read in this data using a classmethod in the cython probably.
  • Question : Should I change to using the smeared stiffener properties for the in plane load computation for global buckling? Answer: the actual in plane loads observed in the panel are what is computed in the local buckling section with B = 0 matrix. Smearing is done for global buckling to use an unstiffened panel closed-form approach. Of course I don't need to do that since I have a stiffened panel closed-form solution directly on the regular properties (and then later I use ML instead).
  • Additional tests for the constitutive class
    • Add verification test of the buckling constraints (closed-form and ML) implemented in this class. This will make sure that they are giving the correct values (not just that the derivatives are correct).
    • Time the constitutive class on the whole datasets and ensure the forward + adjoint eval time is reasonable.
    • If the time to compute Ytest on the ML models in each constitutive class don't scale well with 30k+ elements/constitutive objects => then I could register previous forward and adjoint inputs + outputs and return previous computed outputs.
    • Add shape derivative test over the panel length and width constraints
  • May also need to check whether the axial, shear, stiffener crippling data is duplicated for each element, constitutive object (I would not like to repeat and duplicate the data for each 30k elements if there are ~20k trials for ~100k floats per each trio of GP model objects as that would lead to about 3*10^9 floats of storage). There are ways to prevent an object from being copied, moved, etc. https://www.javatpoint.com/cpp-class-to-prevent-object-copies. [Answer: appears to not be duplicated as I use pointers according to @timryanb]
  • Add in sphinx and full documentation of each method
  • Rename ShearGaussianProcessModel and the other GP classes as TACSShearGaussianProcessModel etc.
  • Add a train routine feature so that if KS on the GPs are changed, it updates the weights by inverting a matrix (maybe in Cython / Python level)

@sean-engelstad sean-engelstad changed the title Gaussian Process Buckling Constraints implemented in Blade Stiffened Shell Constitutive Subclass Gaussian Process Buckling Constraints in Blade Stiffened Shell Constitutive Subclass Apr 25, 2024
@timryanb
Copy link
Collaborator

@sean-engelstad, before you go further down this path, you should review the element routines that already exists. There already exists sub-routines to compute the mass centroid, moments of inertia, etc. Please review them to avoid duplicating code.

@A-CGray
Copy link
Contributor

A-CGray commented Apr 29, 2024

Also @sean-engelstad , not sure how you're intending to do the panel length/width computation but you may be able to re-use what I have implemented in the panel length constraint

@sean-engelstad
Copy link
Contributor Author

@A-CGray I decided to replicate what you did with the panel length constraint, with some small modifications for the panel width constraint. I will just add some code into FUNtoFEM to compute chain rule products of panel length, panel width DVs with the coordinate derivatives sensitivities for our workflow.

@sean-engelstad
Copy link
Contributor Author

sean-engelstad commented Oct 9, 2024

@A-CGray, ok I switched to virtual functions in your base class for the methods that I need to override in my subclass and use the override keyword (optional but extra compiler check) for the methods I override. I double checked that my buckling load predictions are still the same as well. No functors or lambda expressions now so much cleaner

Copy link
Collaborator

@timryanb timryanb left a comment

Choose a reason for hiding this comment

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

Can you make sure that all classes/methods added to constitutive.pyx have proper docstrings, describing what they do, inputs, outputs etc. See the other classes/methods for formatting reference

@sean-engelstad
Copy link
Contributor Author

@timryanb I finished adding the docstrings for all methods, classes in the constitutive.pyx file that I added.

@timryanb
Copy link
Collaborator

@A-CGray, did you have a chance to take a look at this?

Copy link
Contributor

@A-CGray A-CGray left a comment

Choose a reason for hiding this comment

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

Hey @sean-engelstad this is really good work. I have a lot of comments but they're mostly duplicates about using new and delete[] in places that you don't need to. I commented all the examples of this that I saw in the constitutive class, I think there are some more cases in the GPModel classes that I didn't leave comments on but should still be fixed.

Also, you could add a panel width constraint to this integration test that already tests the panel length constraint

src/constitutive/TACSBladeStiffenedShellConstitutive.h Outdated Show resolved Hide resolved
src/constitutive/TACSGPBladeStiffenedShellConstitutive.h Outdated Show resolved Hide resolved
src/constitutive/TACSGPBladeStiffenedShellConstitutive.h Outdated Show resolved Hide resolved
src/constitutive/TACSGPBladeStiffenedShellConstitutive.cpp Outdated Show resolved Hide resolved
src/constitutive/TACSGPBladeStiffenedShellConstitutive.h Outdated Show resolved Hide resolved
tacs/constraints/panel_width.py Outdated Show resolved Hide resolved
examples/gp_stiffened_plate/eval_stiffened_plate.py Outdated Show resolved Hide resolved
examples/gp_panel_buckling/1_closed_form_axial_modes.py Outdated Show resolved Hide resolved
@sean-engelstad
Copy link
Contributor Author

sean-engelstad commented Oct 18, 2024

Hey @sean-engelstad this is really good work. I have a lot of comments but they're mostly duplicates about using new and delete[] in places that you don't need to. I commented all the examples of this that I saw in the constitutive class, I think there are some more cases in the GPModel classes that I didn't leave comments on but should still be fixed.

Also, you could add a panel width constraint to this integration test that already tests the panel length constraint

Thanks @A-CGray, I'm resolving the comment discussions as I go through and update the code if that's good with you. For comments where there might be more discussion I'll leave it unresolved

@sean-engelstad
Copy link
Contributor Author

sean-engelstad commented Oct 18, 2024

@A-CGray @timryanb, alright I'm done addressing all the items in Ali's review. The only point left up for debate is whether I should change my constitutive object to be a subclass of Ali's in constitutive.pyx which would cleanup a few repeated methods. It caused me quite a bit of problems last time I tried that, but maybe I would be able to figure it out now since I have more experience with the Cython.

Also I verified that the buckling loads still match my trained ML models in ml_buckling repo, so the changes I made didn't break anything.

Copy link
Contributor

@A-CGray A-CGray left a comment

Choose a reason for hiding this comment

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

Thanks @sean-engelstad , this addresses all my comments, with the exception of the cython wrapper like you said, so I'd like @timryanb to give final approval on that.

I did a little reading of the cython documentation and it seems like you can't override the cinit of a parent class, so it will always be called, which causes issues here because we don't want to actually create a BladeStiffenedShell object when trying to create a GPBladeStiffenedShell object.

@timryanb would it work if we switched these classes from using __cinit__ to __init__?

@A-CGray A-CGray requested a review from timryanb October 18, 2024 20:54
@timryanb
Copy link
Collaborator

timryanb commented Oct 21, 2024

@sean-engelstad @A-CGray, I believe it should be possible to make this class into a cython sub-class. Both the GP and regular version of the cython class would have to inherit from a parent base class that held the common API between the two classes.

An example of this would be the ShellConstitutive parent class that all shell constitutive classes inherit from (IsoShellConstitutive, CompShellConstitutive, etc.).

In this case you could add the new common baseclass to the constitutive.pxd file like below:

cdef class StiffenedShellConstitutive(ShellConstitutive):
    cdef TACSBladeStiffenedShellConstitutive *base_ptr
    
 cdef class BladeStiffenedShellConstitutive(StiffenedShellConstitutive):
    cdef TACSBladeStiffenedShellConstitutive *blade_ptr
    
cdef class GPBladeStiffenedShell(StiffenedShellConstitutive):
    cdef TACSGPBladeStiffenedShell *blade_ptr

You can then add the API to the constitutive.pyx file using ShellConstitutive as a template (see here)

Both your and @A-CGray's class would have to be updated in the constitutive.pyx file to inherit from this new class rather than ShellConstitutive

Also make sure to set the cptr, base_ptr, and blade_ptr during the cinit for both of your classes, see here for example

@sean-engelstad
Copy link
Contributor Author

Ok @timryanb @A-CGray => I removed the redundant code in constitutive.pyx using Tim's suggestions. As long as these tests pass, it should be good to go now.

@sean-engelstad
Copy link
Contributor Author

sean-engelstad commented Oct 21, 2024

@timryanb Wait => don't merge it yet, there is a problem when running on big cases right now which I've traced back to incref(). Unittests pass, but large case doesn't work at the moment

@sean-engelstad
Copy link
Contributor Author

Update: I needed to also store one of the other constitutive subclass ptrs namely cptr otherwise constructing any elements (from element.pyx) will fail in self.cptr.incref(). So I added the copy self.cptr = back in the constructors

@sean-engelstad
Copy link
Contributor Author

@timryanb should be good to merge now if you wanna take one more look. I can run the wing examples and the tests pass now with the updates to constitutive.pyx

@timryanb
Copy link
Collaborator

I should be able to take a look at it sometime tomorrow @sean-engelstad

tacs/constitutive.pyx Outdated Show resolved Hide resolved
@timryanb
Copy link
Collaborator

@sean-engelstad also can you add your new panel constraints to the constraint autodocs list here. You just have to add the name of the python file in the constraints module folder that your new code lives in

@sean-engelstad
Copy link
Contributor Author

sean-engelstad commented Oct 22, 2024

@timryanb - ok I added the docs for panel width and fixed constitutive.pyx

@sean-engelstad
Copy link
Contributor Author

@timryanb I fixed the docs mistake you just caught

@timryanb timryanb merged commit 6e97dda into smdogroup:master Oct 22, 2024
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants