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

OM_DVGEOCOMP tests and forward mode derivatives #250

Open
wants to merge 57 commits into
base: main
Choose a base branch
from

Conversation

eytanadler
Copy link
Contributor

@eytanadler eytanadler commented Jul 7, 2024

Purpose

The MPhys component for pygeo supports only reverse mode derivatives and otherwise gives zero derivatives. However, no warning or error is thrown. This PR adds forward mode derivatives to the MPhys component so it supports mode="fwd".

The branch for testing the MPhys wrapper for DVGeo/DVCon was merged into this in order to test the forward mode derivatives. The tests so far include commonly used functions in DVGeo, DVCon, and DVGeoESP.

This also addresses the ESP side of #249.

Expected time until merged

A few days

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

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

@eytanadler eytanadler requested a review from a team as a code owner July 7, 2024 18:17
Copy link

codecov bot commented Jul 7, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 67.03%. Comparing base (191046d) to head (4712171).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #250      +/-   ##
==========================================
+ Coverage   65.41%   67.03%   +1.61%     
==========================================
  Files          47       47              
  Lines       12315    12331      +16     
==========================================
+ Hits         8056     8266     +210     
+ Misses       4259     4065     -194     

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

hajdik
hajdik previously approved these changes Jul 10, 2024
Copy link
Contributor

@hajdik hajdik left a comment

Choose a reason for hiding this comment

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

Thanks for catching this, LGTM

@eirikurj
Copy link
Contributor

@eytanadler, this was discussed during the maintenance meeting last week (missed the last one), but just want to clarify, do you plan to add the forward mode in this PR? We can also just add that in a separate PR, but in that case please make an issue documenting the forward mode additions etc.

@eytanadler
Copy link
Contributor Author

Yes, I’ll add it here. I just haven’t got around to it yet.

@eytanadler eytanadler requested review from lamkina and anilyil and removed request for ArshSaja July 19, 2024 15:50
@eytanadler
Copy link
Contributor Author

I did a first pass of forward mode derivatives for the MPhys DVGeo component. I'm not super familiar with the parallelization hacks, so @anilyil please check those and let me know if you have any concerns. Tests for this component and its derivatives are included on the mphys-tests branch, so I think it'd be best to either merge that branch into this one or this branch into that one. That way, we can ensure these derivatives work as expected before merging to main. I ran the tests locally and this seems to produce the same results as reverse mode.

A couple other things I found and changed while making this:

  • The check for missing variables in totalSensitivityProd incorrectly finds missing variables if the variable is not in the final DVGeo. I fixed this by initializing the set with the variables we want to find rather than adding them as we go.
  • The tests on the mphys-tests branch identify an incorrect derivative in the projected area constraint that is not tested elsewhere in the code. I looked into it for awhile and couldn't nail down the error. However, I did find one case where the inequality check in the derivative calculation is if XYZ > 0 [do something] else [do something else], whereas in the primal it is if XYZ < 0 [do something else] else [do something]. I switched the derivative version around so it matches the primal. @hajdik it'd be good for us to get to the bottom of this derivative problem. Nonetheless, the fwd and rev modes have the same problem, so I don't think it's something I introduced in this code.

In the meantime, I'll add fwd mode derivative checking to the tests on the mphys-tests branch.

@eytanadler eytanadler requested a review from hajdik July 19, 2024 15:59
@eytanadler
Copy link
Contributor Author

This is finally ready for review

@hajdik hajdik changed the title Implement forward mode derivatives in OM_DVGEOCOMP OM_DVGEOCOMP tests and forward mode derivatives Oct 28, 2024
@hajdik hajdik requested review from marcomangano and removed request for anilyil and hajdik November 4, 2024 17:07
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.

Thanks for the hard work @hajdik and @eytanadler . Just a few small changes, but overall this is great.

@@ -215,6 +219,9 @@ def nom_addPointSet(self, points, ptName, add_output=True, DVGeoName=None, **kwa
# add an output to the om component
self.add_output(ptName, distributed=True, val=points.flatten())

if isinstance(DVGeo, DVGeometryESP):
return dMax_global
Copy link
Contributor

Choose a reason for hiding this comment

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

I prefer to not use conditional returns, can we tweak this to set dMaxGlobal equal to None if the DVGeo type is not DVGeometryESP? Then just return the variable without the if-statement.

# check if this dv is present
if k in d_inputs:
# do the allreduce
# TODO remove the allreduce when this is fixed in openmdao
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can remove this TODO. MPhys and OM dev teams decided that individual codes, not OM, are responsible for correctly performing the allreduce in the matrix-free computation.

xdotg[k] = self.comm.allreduce(xdot[k], op=MPI.SUM)

# accumulate in the dict
# TODO
Copy link
Contributor

Choose a reason for hiding this comment

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

If this is working well I think we can clean up this comment as well. If there's actually plans to fix and move back to totalSensitivityTransProd then we should create and issue and reference this code in the issue. Otherwise this comment will probably get lost to the ether.

i_weight = (n_chord - ii - 1) / (n_chord - i_center - 1)

# get the direction vectors with unit length
dir_up = np.array([0.0, 1.0, 0.0])
Copy link
Contributor

Choose a reason for hiding this comment

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

Are these Cartesian direction vectors? Should they be an input? I'm not sure the +y and -y will always be considered up/down for all topologies.

Disregard if I'm misunderstanding this.


# input files for all DVGeo types
input_path = os.path.dirname(os.path.abspath(__file__))
outerFFD = os.path.join(input_path, "../../input_files/outerBoxFFD.xyz")
Copy link
Contributor

Choose a reason for hiding this comment

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

Should change "../../input_files/etc" to os.path.join(input_path, "..", "..", "input_files", etc.)

The whole point of using the join function is to eliminate the / character.

Going even further, I like pathlib much better, but that's extra credit.

self.prob.run_model()

totals = self.prob.check_totals(step=1e-7, out_stream=None)
assert_check_totals(totals)
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we add hard-coded tolerances for this check as well? Better to have them here than use the defaults from OM incase they change in the future.

paramKwargs.update(kwargs)

meshFile = os.path.join(input_path, "../../input_files/2x1x8_rectangle.stl")
ffdFile = os.path.join(input_path, "../../input_files/2x1x8_rectangle.xyz")
Copy link
Contributor

Choose a reason for hiding this comment

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

See path comment above.

self.prob.run_model()

totals = self.prob.check_totals(step=1e-7, out_stream=None)
assert_check_totals(totals)
Copy link
Contributor

Choose a reason for hiding this comment

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

We should add tolerances here.

DVGeo.addPointSet(points.reshape(len(points) // 3, 3), ptName, **kwargs)
if isinstance(DVGeo, DVGeometryESP):
# DVGeoESP can return a value to check the pointset distribution
dMax_global = DVGeo.addPointSet(points.reshape(len(points) // 3, 3), ptName, **kwargs)
Copy link
Contributor

Choose a reason for hiding this comment

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

Keep this as camel case: dMaxGlobal

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.

5 participants