Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
1ab1f6b
first implementation of custom subset of active child FFDs for family…
anilyil Mar 29, 2023
b6b294a
Merge branch 'main' into children_dict
anilyil Mar 29, 2023
13b30e1
added reverse mode sensitivities w/ active children check
anilyil Apr 4, 2023
9da19f2
bug fix
anilyil Apr 4, 2023
be7d63f
fixed the derivative bug
anilyil Apr 11, 2023
a092672
Merge remote-tracking branch 'mdolab/main' into children_dict
anilyil Jul 18, 2023
5beaff3
modified the implementation to be more general
anilyil Jul 20, 2023
04ff66f
Merge branch 'main' into children_dict
anilyil Jul 20, 2023
6e3d586
Merge branch 'main' into children_dict
anilyil Sep 9, 2023
d16de96
Merge branch 'main' into children_dict
A-CGray Sep 12, 2023
32d4479
Merge branch 'main' into children_dict
anilyil Nov 24, 2023
9f047f4
add the missing jacvec modifications
anilyil Nov 26, 2023
bb2a6cd
fix fwd jacvec product
anilyil Nov 29, 2023
fa8821f
Merge remote-tracking branch 'mdolab/main' into children_dict
anilyil Apr 3, 2024
78109c1
Merge branch 'main' into children_dict
eirikurj Jun 28, 2024
6f99214
Merge remote-tracking branch 'mdolab/main' into children_dict
anilyil Aug 16, 2024
f217a3a
Merge remote-tracking branch 'mdolab/main' into children_dict
anilyil Jan 16, 2025
fc13695
add custom ptset kwargs for the blanking surfaces when they are used …
anilyil Jan 16, 2025
d5f1daa
Merge branch 'main' into children_dict
A-CGray Jan 27, 2025
1f6a90b
Merge remote-tracking branch 'mdolab/main' into children_dict
anilyil Feb 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 132 additions & 18 deletions adflow/pyADflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -3255,8 +3255,6 @@ def setAeroProblem(self, aeroProblem, releaseAdjointMemory=True):
Flag to release the adjoint memory when setting a new aeroproblem, by default True
"""

ptSetName = "adflow_%s_coords" % aeroProblem.name

newAP = False
# Tell the user if we are switching aeroProblems
if self.curAP != aeroProblem:
Expand All @@ -3270,9 +3268,23 @@ def setAeroProblem(self, aeroProblem, releaseAdjointMemory=True):
aeroProblem.adflowData
except AttributeError:
aeroProblem.adflowData = adflowFlowCase()
aeroProblem.ptSetName = ptSetName
aeroProblem.surfMesh = self.getSurfaceCoordinates(self.designFamilyGroup)

# dictionary that holds the ptsetname for each family
ptSetNames = {}
if self.customPointSetFamilies is None:
# we dont have a custom child dvgeo mapping. the surface family will be only
# designFamilyGroup and we will have a single pointset
ptSetName = f"adflow_{self.designFamilyGroup}_{aeroProblem.name}_coords"
ptSetNames[self.designFamilyGroup] = ptSetName
else:
# we have a custom surface family to child dvgeo mapping.
for familyName in self.customPointSetFamilies.keys():
ptSetName = f"adflow_{familyName}_{aeroProblem.name}_coords"
ptSetNames[familyName] = ptSetName
Comment on lines +3275 to +3284

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is the use of customPointSetFamilies exclusive to cases where you use child DVGeo's? If not then can you re-word these comments to avoid talking about child dvgeos as it's a bit confusing.


aeroProblem.ptSetNames = ptSetNames

if self.curAP is not None:
# If we have already solved something and are now
# switching, save what we need:
Expand Down Expand Up @@ -3300,10 +3312,31 @@ def setAeroProblem(self, aeroProblem, releaseAdjointMemory=True):

# Now check if we have an DVGeo object to deal with:
if self.DVGeo is not None:
# DVGeo appeared and we have not embedded points!
if ptSetName not in self.DVGeo.points:
coords0 = self.mapVector(self.coords0, self.allFamilies, self.designFamilyGroup, includeZipper=False)
self.DVGeo.addPointSet(coords0, ptSetName, **self.pointSetKwargs)
# we have a DVGeo added. check if we have already added the points for this AP
if self.customPointSetFamilies is None:
# we have a single pointset
ptSetName = aeroProblem.ptSetNames[self.designFamilyGroup]

if ptSetName not in self.DVGeo.points:
coords0 = self.mapVector(
self.coords0, self.allFamilies, self.designFamilyGroup, includeZipper=False
)
self.DVGeo.addPointSet(coords0, ptSetName, **self.pointSetKwargs)
else:
# we have custom pointsets
for family, familyKwargs in self.customPointSetFamilies.items():
ptSetName = aeroProblem.ptSetNames[family]

if ptSetName not in self.DVGeo.points:
# coords0 is now the subset of this family
coords0 = self.mapVector(self.coords0, self.allFamilies, family, includeZipper=False)
# this pointset is added with a custom familyKwargs
self.DVGeo.addPointSet(
coords0,
ptSetName,
**self.pointSetKwargs,
**familyKwargs,
)

# also check if we need to embed blanking surface points
if self.getOption("oversetUpdateMode") == "full" and self.getOption("explicitSurfaceCallback") is not None:
Expand All @@ -3313,6 +3346,7 @@ def setAeroProblem(self, aeroProblem, releaseAdjointMemory=True):
# used in the explicit hole cutting multiple times in different
# configurations.
surfFile = self.blankingSurfDict[surf]["surfFile"]
surfPointSetKwargs = self.blankingSurfDict[surf]["pointSetKwargs"]
surfPtSetName = f"points_{surfFile}"
if surfPtSetName not in self.DVGeo.points:
# we need to add the pointset to dvgeo. do it in parallel
Expand All @@ -3334,11 +3368,52 @@ def setAeroProblem(self, aeroProblem, releaseAdjointMemory=True):
# we already communicated the points when loading the file,
# so just add them to dvgeo now
procPts = surfPts[disp[self.comm.rank] : disp[self.comm.rank + 1]]
self.DVGeo.addPointSet(procPts, surfPtSetName, **self.pointSetKwargs)
self.DVGeo.addPointSet(procPts, surfPtSetName, **self.pointSetKwargs, **surfPointSetKwargs)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

How does passing two sets of kwargs to addPointSet work? What's the difference between pointSetKwargs and surfPointSetKwargs?


# Check if our point-set is up to date:
if not self.DVGeo.pointSetUpToDate(ptSetName) or aeroProblem.adflowData.disp is not None:
coords = self.DVGeo.update(ptSetName, config=aeroProblem.name)
updateSurface = False

# check for disp first. doing this check here is not the most efficient,
# but it results in simpler code
if aeroProblem.adflowData.disp is not None:
updateSurface = True

if self.customPointSetFamilies is None:
# we have a single pointset
ptSetName = aeroProblem.ptSetNames[self.designFamilyGroup]

if not self.DVGeo.pointSetUpToDate(ptSetName):
updateSurface = True

coords = self.DVGeo.update(ptSetName, config=aeroProblem.name)

else:
# we have custom pointsets
# first figure out if we want to update the pointset; check each family we are tracking
for family in self.customPointSetFamilies.keys():
# return immediately if we are flagged for a surfafce update
if updateSurface:
break

# check if any of the pointsets are out of date
ptSetName = aeroProblem.ptSetNames[family]
if not self.DVGeo.pointSetUpToDate(ptSetName):
updateSurface = True

# if we have the updateSurface flag True, compute the coords array
if updateSurface:
# get the current design surface family. we will overwrite this as we go through the families
coords = self.mapVector(self.coords0, self.allFamilies, self.designFamilyGroup, includeZipper=False)

for family in self.customPointSetFamilies.keys():
ptSetName = aeroProblem.ptSetNames[family]
familyCoords = self.DVGeo.update(ptSetName, config=aeroProblem.name)
# map this to the coords vector
self.mapVector(familyCoords, family, self.designFamilyGroup, vec2=coords, includeZipper=False)

if updateSurface:
# the coords array is computed above. if we have the update surface flag enabled,
# run the surface update

# Potentially add a fixed set of displacements to it.
if aeroProblem.adflowData.disp is not None:
Expand Down Expand Up @@ -4674,9 +4749,22 @@ def computeJacobianVectorProductFwd(
# already existing (and possibly nonzero) xsdot and xvdot
if xDvDot is not None or xSDot is not None:
if xDvDot is not None and self.DVGeo is not None:
xsdot += self.DVGeo.totalSensitivityProd(xDvDot, self.curAP.ptSetName, config=self.curAP.name).reshape(
xsdot.shape
)
if self.customPointSetFamilies is None:
# no custom pointset families, just process the entire dvdot and add to xsdot
xsdot += self.DVGeo.totalSensitivityProd(
xDvDot, self.curAP.ptSetNames[self.designFamilyGroup], config=self.curAP.name
).reshape(xsdot.shape)
else:
# custom pointsets. accumulate local xsdots in the complete vector
for family in self.customPointSetFamilies.keys():
# process this family's xsdot
ptSetName = self.curAP.ptSetNames[family]
xsdot_family = self.DVGeo.totalSensitivityProd(
xDvDot, ptSetName, self.comm, config=self.curAP.name
)
# map it to an empty surface vector and accumulate
xsdot += self.mapVector(xsdot_family, family, self.designFamilyGroup)

if self.mesh is not None:
xsdot = self.mapVector(xsdot, self.meshFamilyGroup, self.designFamilyGroup, includeZipper=False)
xvdot += self.mesh.warpDerivFwd(xsdot)
Expand Down Expand Up @@ -4992,12 +5080,38 @@ def computeJacobianVectorProductBwd(
if xDvDeriv:
xdvbar = {}
if self.mesh is not None: # Include geometric
# derivatives if mesh is
# present
# derivatives if mesh is present
if self.DVGeo is not None and self.DVGeo.getNDV() > 0:
xdvbar.update(
self.DVGeo.totalSensitivity(xsbar, self.curAP.ptSetName, self.comm, config=self.curAP.name)
)
# we have a DVGeo added. check if we have already added the points for this AP
if self.customPointSetFamilies is None:
# we have a single pointset
ptSetName = self.curAP.ptSetNames[self.designFamilyGroup]

xdvbar.update(
self.DVGeo.totalSensitivity(xsbar, ptSetName, self.comm, config=self.curAP.name)
)

else:
# we have custom pointsets
# start with an empty dict, we set the entries in the first pass,
# and add in the following passes
for family in self.customPointSetFamilies.keys():
ptSetName = self.curAP.ptSetNames[family]

# get the mapped xsbar
xsbarFamily = self.mapVector(xsbar, self.designFamilyGroup, family, includeZipper=False)

familySens = self.DVGeo.totalSensitivity(
xsbarFamily, ptSetName, self.comm, config=self.curAP.name
)

for key, val in familySens.items():
# not the best way to do this but should work...
if key in xdvbar:
xdvbar[key] += val
else:
xdvbar[key] = val

else:
if self.comm.rank == 0:
ADFLOWWarning(
Expand Down
7 changes: 7 additions & 0 deletions doc/options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,13 @@ explicitSurfaceCallback:
# We use this approach so that the users can have complete
# control over the surface mesh nodes after they are loaded.
"coordXfer": coordXfer,

# Optional entry: pointSetKwargs,
# This is a dictionary that contains custom kwargs that will be
# used with the addPointSet call when this surface is added to
# DVGeo. This is done when the solver does full overset updates
# between iterations, where we also track the blanking surfaces
# with DVGeo.
},

# Similar entries for the fuselage.
Expand Down