Implement support for pygeo and OM wrapper for custom meshes#64
Implement support for pygeo and OM wrapper for custom meshes#64sabakhshi wants to merge 75 commits intojoanibal:mainfrom
Conversation
… fixed scale and translate of custom meshes not working
…ng in common block
…fortran layer indexing bugs. runtime mesh updating still needs to be implemented
joanibal
left a comment
There was a problem hiding this comment.
Nice work! Here are a few questions and suggestions
| self.set_reference_ad_seeds(ref_seeds) | ||
|
|
||
| # Since DVGeo seeds operate entirely within the python layer we set them here | ||
| if self.DVGeo is not None and dvgeo_seeds is not None: |
There was a problem hiding this comment.
This chunk appears 4 times with some variation. Could we generalize these chunks into a function?
There was a problem hiding this comment.
I get what your saying but all four of these chunks have a different task despite the first couple lines being shared. Fundamentally, the first couple lines of each of these loops check if a surface has a pointset associated with it so I execute the desired task on a surface that is actually embedded in the FFD. I could put this check into another function but I can't generalize the actual task each chunk does. So there would still be a check if we have DVGeo and there would be a loop over surfaces with pointsets. Should I still do that?
| sens[func_key][surf_key] = geom_seeds[surf_key] | mesh_seeds[surf_key] | ||
| for key in geom_seeds: | ||
| sens[func_key][key] = geom_seeds[key] | mesh_seeds[key] | dvgeo_seeds[key] | ||
| # sens[func_key].update(geom_seeds) |
There was a problem hiding this comment.
left over comments? or was that intentional
There was a problem hiding this comment.
It was intentional. I wasn't sure what you thought of my approach of doing a union here. Basically you have all the seeds associated with the surface under a key of that surface's name. This was fine when all that was under that key was the geom_seeds but now we have mesh seeds and dvgeo seeds that are also associated with a surface and placed under that surfaces key name. We have to merge these dictionaries into one for easier optimization and merging nested dictionaries in Python is annoying and the union approach is the best I came up with. What do you think of this?
tests/test_om_wrapper.py
Outdated
| # prob.model.add_design_var("ovlsolver.Wing:zles") | ||
| # prob.model.add_design_var("ovlsolver.Wing:chords") | ||
| # prob.model.add_design_var("ovlsolver.Wing:mesh") # This is a really costly test | ||
| # prob.model.add_design_var("ovlsolver.Wing:aincs") # dCL/dalpha on the first element fails |
There was a problem hiding this comment.
Yes. The first few I should delete since those inputs don't exist for a mesh surface. The test with respect to the mesh is really costly and dramatically increases the time required to run the tests since it computes the total derivative wrt to each (x,y,z) component of each point in the mesh. I could use a smaller mesh but I wanted to use what was given in aircraft.avl to match the nonmesh OM wrapper stuff. The last comment is test that I am struggling to get passed. When computing d(dCL/dalpha)/d(aincs), I found that the derivative wrt to the first two indicies of aincs was off.
UPDATE: Now that I look at the last issue again I think it would be fine if we just relaxed the test tolerance. For some reason I recall this being orders of magnitude off but it appear it isn't.
AssertionError: Not equal to tolerance rtol=0.01, atol=1e-09 deriv of ovlsolver.dCL/dalpha wrt ovlsolver.Wing:aincs does not agree with FD to rtol=0.01 Mismatched elements: 1 / 21 (4.76%) Mismatch at index: [0, 1]: -7.450580596923828e-09 (ACTUAL), 4.960020677913534e-09 (DESIRED) Max absolute difference among violations: 1.24106013e-08 Max relative difference among violations: 2.50212692 ACTUAL: array([[ 3.241003e-07, -7.450581e-09, -1.247972e-06, -4.470348e-07, 9.872019e-06, 7.454306e-06, 8.620322e-06, 3.216788e-05, 5.760044e-05, 9.340048e-05, 1.171790e-04, 1.486540e-04,... DESIRED: array([[ 3.213856e-07, 4.960021e-09, -1.235720e-06, -4.461515e-07, 9.864236e-06, 7.449540e-06, 8.614240e-06, 3.216888e-05, 5.758156e-05, 9.340394e-05, 1.171690e-04, 1.486690e-04,...
This PR includes support for pygeo FFD parameterization in the OVLSolver class and support for dictionary input/custom meshes in the OM wrapper.
The pygeo api is very easy to use. The user just needs to set up their FFD box and their DVGeo object with all design variables set. Then it's just a matter of setting the DVGeo instance to the OVLSolver object using the set_DVGeo function. To apply any changes made to the DVGeo design variables to the OptVL mesh the update_DVGeo function needs to be called. This will embed any mesh surfaces in the FFD if needed and then perform the pointset update. The updated point set will then be set back into OptVL and the and update surfaces routine called to update the Fortran layer. Currently, OptVL will try to embed all meshes into the same FFD so for now we suggest that FFDs only be used with cases that only have a single mesh surface. A unit test is included for the pyGeo API. A FFD box generator for VLM meshes is also included in utilities.
The OM wrapper can also now be used with meshes and input dictionaries. When a mesh is used for a particular surface all geometry inputs for that surfaces are replaced with a single mesh input. The shape of this mesh input is set by the input_mesh_shape option in the OVLGroup class. Input arrays shapes of 1,2, or 3 dimensions can be chosen with it defaulting to 1 (which is a flat array). This input shape selection allows for wide compatibility with a variety of geometry parameterization components. A unit test for the mesh features in the OM wrapper are also included.