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

Child FFD constraint tests and fixes #103

Merged
merged 14 commits into from
Oct 5, 2021
72 changes: 55 additions & 17 deletions pygeo/constraints/DVCon.py
Original file line number Diff line number Diff line change
Expand Up @@ -1825,14 +1825,18 @@ def addLeTeConstraints(
indSetB : array of int
Indices of control points on the *other* side of the FFD
name : str
Normally this does not need to be set; a default name will
be generated automatically. Only use this if you have
multiple DVCon objects and the constriant names need to
be distinguished
Normally this does not need to be set; a default name will
be generated automatically. Only use this if you have
multiple DVCon objects and the constriant names need to
be distinguished
config : str
The DVGeo configuration to apply this LETE con to. Must be either None
which will allpy to *ALL* the local DV groups or a single string specifying
a particular configuration.
The DVGeo configuration to apply this constraint to. Must be either None
which will apply to *ALL* the local DV groups or a single string specifying
a particular configuration.
childIdx : int
The zero-based index of the child FFD, if this constraint is being applied to a child FFD.
The index is defined by the order in which you add the child FFD to the parent.
For example, the first child FFD has an index of 0, the second an index of 1, and so on.

Examples
--------
Expand Down Expand Up @@ -1944,7 +1948,17 @@ def addLeTeConstraints(
)

def addLinearConstraintsShape(
self, indSetA, indSetB, factorA, factorB, lower=0, upper=0, name=None, config=None, DVGeoName="default"
self,
indSetA,
indSetB,
factorA,
factorB,
lower=0,
upper=0,
name=None,
config=None,
childIdx=None,
DVGeoName="default",
):
"""
Add a complete generic set of linear constraints for the shape
Expand Down Expand Up @@ -1987,10 +2001,18 @@ def addLinearConstraintsShape(
upper : float or array
The upper bound of the constraint(s)
name : str
Normally this does not need to be set; a default name will
be generated automatically. Only use this if you have
multiple DVCon objects and the constriant names need to
be distinguished
Normally this does not need to be set; a default name will
be generated automatically. Only use this if you have
multiple DVCon objects and the constriant names need to
be distinguished
config : str
The DVGeo configuration to apply this constraint to. Must be either None
which will apply to *ALL* the local DV groups or a single string specifying
a particular configuration.
childIdx : int
The zero-based index of the child FFD, if this constraint is being applied to a child FFD.
The index is defined by the order in which you add the child FFD to the parent.
For example, the first child FFD has an index of 0, the second an index of 1, and so on.

Examples
--------
Expand All @@ -2007,6 +2029,11 @@ def addLinearConstraintsShape(

self._checkDVGeo(DVGeoName)

if childIdx is not None:
DVGeo = self.DVGeometries[DVGeoName].children[childIdx]
Copy link
Contributor

Choose a reason for hiding this comment

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

It took me a bit of code reading, but I see how this makes sense. We have a single DVcon object which "receives" the parent DVGeo, and we were previously applying the constraint to this object instead of the children (when present) as expected. This means that we now need to add one of these for each child ffd, right? Can you add a short description of what is going on and how to extract the childIdx index from DVGeo?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, without childIdx the constraint is applied on the parent. You only need to add this constraint to each FFD that needs it. childIdx is defined by the order in which you add the child FFD to the parent (the first is 0, second is 1, etc.). I will update the docstrings to include this description.

To be clear though, I took this approach directly from addLeTeConstraints which already worked with child FFDs.

else:
DVGeo = self.DVGeometries[DVGeoName]

if len(indSetA) != len(indSetB):
raise Error("The length of the supplied indices are not " "the same length")

Expand Down Expand Up @@ -2044,7 +2071,7 @@ def addLinearConstraintsShape(

# Finally add the linear constraint object
self.linearCon[conName] = LinearConstraint(
conName, indSetA, indSetB, factorA, factorB, lower, upper, self.DVGeometries[DVGeoName], config=config
conName, indSetA, indSetB, factorA, factorB, lower, upper, DVGeo, config=config
)

def addGearPostConstraint(
Expand Down Expand Up @@ -2751,7 +2778,9 @@ def addCurvatureConstraint(
addToPyOpt,
)

def addMonotonicConstraints(self, key, slope=1.0, name=None, start=0, stop=-1, config=None, DVGeoName="default"):
def addMonotonicConstraints(
self, key, slope=1.0, name=None, start=0, stop=-1, config=None, childIdx=None, DVGeoName="default"
):
"""
Parameters
----------
Expand All @@ -2773,16 +2802,25 @@ def addMonotonicConstraints(self, key, slope=1.0, name=None, start=0, stop=-1, c
a design variable vector [4, 3, 6.5, 2, -5.4, -1], start=1 and
stop=4 would constrain [3, 6.5, 2, -5.4] to be a monotonic sequence.
config : str
The DVGeo configuration to apply this LETE con to. Must be either None
which will allpy to *ALL* the local DV groups or a single string specifying
The DVGeo configuration to apply this constraint to. Must be either None
which will apply to *ALL* the local DV groups or a single string specifying
a particular configuration.
childIdx : int
The zero-based index of the child FFD, if this constraint is being applied to a child FFD.
The index is defined by the order in which you add the child FFD to the parent.
For example, the first child FFD has an index of 0, the second an index of 1, and so on.

Examples
--------
>>> DVCon.addMonotonicConstraints('chords', 1.0)
"""
self._checkDVGeo(DVGeoName)

if childIdx is not None:
DVGeo = self.DVGeometries[DVGeoName].children[childIdx]
else:
DVGeo = self.DVGeometries[DVGeoName]

if name is None:
conName = "%s_monotonic_constraint_%d" % (self.name, len(self.linearCon))
else:
Expand All @@ -2797,7 +2835,7 @@ def addMonotonicConstraints(self, key, slope=1.0, name=None, start=0, stop=-1, c
options=options,
lower=0,
upper=None,
DVGeo=self.DVGeometries[DVGeoName],
DVGeo=DVGeo,
config=config,
)

Expand Down
Loading