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

Adds Distance constarints #251

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
265 changes: 265 additions & 0 deletions pygeo/constraints/DVCon.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
ProximityConstraint,
ThicknessConstraint,
ThicknessToChordConstraint,
DistanceConstraint,
)
from .volumeConstraint import CompositeVolumeConstraint, TriangulatedVolumeConstraint, VolumeConstraint

Expand Down Expand Up @@ -3421,6 +3422,270 @@
config=config,
)

def addDistanceConstraints(
self,
anchored_pts,
moving_pts,
lower=1.0,
upper=3.0,
scaled=True,
scale=1.0,
name=None,
addToPyOpt=True,
DVGeoName="default",
compNames=None
):
r"""
Add a set of distance constraints.
The values of the distance costraints is just the distance from each
element in the achored_pts to the same element in the moving_pts array.
Only the 'moving_pts' are embedded into the geometry and are updated.

Parameters
----------
anchored_pts : list or array of size (N x 3)
The list of points used in the distance calculations that do not move

moving_pts : list or array of size (N x 3)
The list of points used in the distance calculations that are
embbeded in the geometry and are updated.

nCon : int
The number of thickness constraints to add

axis : list or array of length 3
The direction along which the projections will occur.
Typically this will be y or z axis ([0,1,0] or [0,0,1])

lower : float or array of size nCon
The lower bound for the constraint. A single float will
apply the same bounds to all constraints, while the array
option will use different bounds for each constraint.

upper : float or array of size nCon
The upper bound for the constraint. A single float will
apply the same bounds to all constraints, while the array
option will use different bounds for each constraint.

scaled : bool
Flag specifying whether or not the constraint is to be
implemented in a scaled fashion or not.

* scaled=True: The initial length of each thickness
constraint is defined to be 1.0. In this case, the lower
and upper bounds are given in multiple of the initial
length. lower=0.85, upper=1.15, would allow for 15%
change in each direction from the original length. For
aerodynamic shape optimizations, this option is used
most often.

* scaled=False: No scaling is applied and the physical lengths
must be specified for the lower and upper bounds.

scale : float or array of size nCon
This is the optimization scaling of the
constraint. Typically this parameter will not need to be
changed. If the thickness constraints are scaled, this
already results in well-scaled constraint values, and
scale can be left at 1.0. If scaled=False, it may changed
to a more suitable value of the resulting physical
thickness have magnitudes vastly different than O(1).

name : str
Normally this does not need to be set. Only use this if
you have multiple DVCon objects and the constraint names
need to be distinguished **or** you are using this set of
thickness constraints for something other than a direct
constraint in pyOptSparse.

addToPyOpt : bool
Normally this should be left at the default of True. If
the values need to be processed (modified) *before* they are
given to the optimizer, set this flag to False.

surfaceName : str
Name of the surface to project to. This should be the same
as the surfaceName provided when setSurface() was called.
For backward compatibility, the name is 'default' by default.

DVGeoName : str
Name of the DVGeo object to compute the constraint with. You only
need to set this if you're using multiple DVGeo objects
for a problem. For backward compatibility, the name is 'default' by default

compNames : list
If using DVGeometryMulti, the components to which the point set associated
with this constraint should be added.
If None, the point set is added to all components.

"""
self._checkDVGeo(DVGeoName)

typeName = "distCon"
if typeName not in self.constraints:
self.constraints[typeName] = OrderedDict()

if name is None:
conName = "%s_distance_constraints_%d" % (self.name, len(self.constraints[typeName]))
else:
conName = name

Check warning on line 3531 in pygeo/constraints/DVCon.py

View check run for this annotation

Codecov / codecov/patch

pygeo/constraints/DVCon.py#L3531

Added line #L3531 was not covered by tests

self.constraints[typeName][conName] = DistanceConstraint(
conName, moving_pts, anchored_pts, lower, upper, scaled, scale, self.DVGeometries[DVGeoName], addToPyOpt, compNames
)

def addDistanceConstraints1D(
self,
ptList,
nCon,
axis,
lower=1.0,
upper=3.0,
scaled=True,
scale=1.0,
name=None,
addToPyOpt=True,
surfaceName="default",
DVGeoName="default",
compNames=None
):
r"""
Add a set of distance constraints oriented along a poly-line.
It is different from a thickness contraint becuase it does not project
in both direactions to define a thickness contstraint.
It always meassures the distance from a surface to a fixed point.

See below for a schematic

.. code-block:: text

Planform view of the wing: The '+' are the (three dimensional)
points that are supplied in ptList:


Airfoil
\
\
---------------------- ___
/ ----
| --
\ ____-----
-----x------x---------
| |
--------------x |
\ | 2 distance constraints
\ |
\ |
x ---------- Ploy line
Parameters
----------
ptList : list or array of size (N x 3) where N >=2
The list of points forming a poly-line along which the
thickness constraints will be added.

nCon : int
The number of thickness constraints to add

axis : list or array of length 3
The direction along which the projections will occur.
Typically this will be y or z axis ([0,1,0] or [0,0,1])

lower : float or array of size nCon
The lower bound for the constraint. A single float will
apply the same bounds to all constraints, while the array
option will use different bounds for each constraint.

upper : float or array of size nCon
The upper bound for the constraint. A single float will
apply the same bounds to all constraints, while the array
option will use different bounds for each constraint.

scaled : bool
Flag specifying whether or not the constraint is to be
implemented in a scaled fashion or not.

* scaled=True: The initial length of each thickness
constraint is defined to be 1.0. In this case, the lower
and upper bounds are given in multiple of the initial
length. lower=0.85, upper=1.15, would allow for 15%
change in each direction from the original length. For
aerodynamic shape optimizations, this option is used
most often.

* scaled=False: No scaling is applied and the physical lengths
must be specified for the lower and upper bounds.

scale : float or array of size nCon
This is the optimization scaling of the
constraint. Typically this parameter will not need to be
changed. If the thickness constraints are scaled, this
already results in well-scaled constraint values, and
scale can be left at 1.0. If scaled=False, it may changed
to a more suitable value of the resulting physical
thickness have magnitudes vastly different than O(1).

name : str
Normally this does not need to be set. Only use this if
you have multiple DVCon objects and the constraint names
need to be distinguished **or** you are using this set of
thickness constraints for something other than a direct
constraint in pyOptSparse.

addToPyOpt : bool
Normally this should be left at the default of True. If
the values need to be processed (modified) *before* they are
given to the optimizer, set this flag to False.

surfaceName : str
Name of the surface to project to. This should be the same
as the surfaceName provided when setSurface() was called.
For backward compatibility, the name is 'default' by default.

DVGeoName : str
Name of the DVGeo object to compute the constraint with. You only
need to set this if you're using multiple DVGeo objects
for a problem. For backward compatibility, the name is 'default' by default

compNames : list
If using DVGeometryMulti, the components to which the point set associated
with this constraint should be added.
If None, the point set is added to all components.

"""
self._checkDVGeo(DVGeoName)

p0, p1, p2 = self._getSurfaceVertices(surfaceName=surfaceName)

# Create mesh of intersections
constr_line = Curve(X=ptList, k=2)
s = np.linspace(0, 1, nCon)
anchored_pts = constr_line(s)
moving_pts = np.zeros((nCon, 3))
# Project all the points
for i in range(nCon):
# Project actual node:
# we only take the up point
up, _, fail = geo_utils.projectNode(anchored_pts[i], axis, p0, p1 - p0, p2 - p0)
if fail > 0:
raise Error(

Check warning on line 3670 in pygeo/constraints/DVCon.py

View check run for this annotation

Codecov / codecov/patch

pygeo/constraints/DVCon.py#L3670

Added line #L3670 was not covered by tests
"There was an error projecting a node "
"at (%f, %f, %f) with normal (%f, %f, %f)." % (anchored_pts[i, 0], anchored_pts[i, 1], anchored_pts[i, 2], axis[0], axis[1], axis[2])
)
moving_pts[i] = up

typeName = "distCon"
if typeName not in self.constraints:
self.constraints[typeName] = OrderedDict()

if name is None:
conName = "%s_distance_constraints_%d" % (self.name, len(self.constraints[typeName]))
else:
conName = name

Check warning on line 3683 in pygeo/constraints/DVCon.py

View check run for this annotation

Codecov / codecov/patch

pygeo/constraints/DVCon.py#L3683

Added line #L3683 was not covered by tests

self.constraints[typeName][conName] = DistanceConstraint(
conName, moving_pts, anchored_pts, lower, upper, scaled, scale, self.DVGeometries[DVGeoName], addToPyOpt, compNames
)

def _checkDVGeo(self, name="default"):
"""check if DVGeo exists"""
if name not in self.DVGeometries.keys():
Expand Down
20 changes: 20 additions & 0 deletions pygeo/constraints/radiusConstraint.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@
to the open file handle
"""
r, c = self.computeCircle(self.coords)
p1, p2, p3 = self.splitPointSets(self.coords)

Check warning on line 185 in pygeo/constraints/radiusConstraint.py

View check run for this annotation

Codecov / codecov/patch

pygeo/constraints/radiusConstraint.py#L185

Added line #L185 was not covered by tests

# Compute origin and unit vectors (xi, eta) of 2d space
_, nxi, neta = self.computeReferenceFrames(self.coords)
Expand All @@ -204,3 +205,22 @@
for i in range(self.nCon):
for j in range(nres):
handle.write("%d %d\n" % (i * nres + j + 1, i * nres + (j + 1) % nres + 1))

handle.write("Zone T=%s_circ_points\n" % self.name)
handle.write("Nodes = %d, Elements = %d ZONETYPE=FELINESEG\n" % (self.nCon * 3*2, self.nCon * 3))
handle.write("DATAPACKING=POINT\n")

Check warning on line 211 in pygeo/constraints/radiusConstraint.py

View check run for this annotation

Codecov / codecov/patch

pygeo/constraints/radiusConstraint.py#L209-L211

Added lines #L209 - L211 were not covered by tests

for i in range(self.nCon):
for pt_dir in [p1, p2, p3]:

Check warning on line 214 in pygeo/constraints/radiusConstraint.py

View check run for this annotation

Codecov / codecov/patch

pygeo/constraints/radiusConstraint.py#L213-L214

Added lines #L213 - L214 were not covered by tests
# for each con plot the vecotrs from the center to the coord points defining the circle
pt1 = c[i]
pt2 = pt_dir[i]
handle.write(f"{pt1[0]:f} {pt1[1]:f} {pt1[2]:f}\n")
handle.write(f"{pt2[0]:f} {pt2[1]:f} {pt2[2]:f}\n")

Check warning on line 219 in pygeo/constraints/radiusConstraint.py

View check run for this annotation

Codecov / codecov/patch

pygeo/constraints/radiusConstraint.py#L216-L219

Added lines #L216 - L219 were not covered by tests

# write out the elements
for i in range(self.nCon*3):
handle.write("%d %d\n" % (2 * i + 1, 2 * i + 2))

Check warning on line 223 in pygeo/constraints/radiusConstraint.py

View check run for this annotation

Codecov / codecov/patch

pygeo/constraints/radiusConstraint.py#L222-L223

Added lines #L222 - L223 were not covered by tests



Loading
Loading