pygeo/parameterization/DVGeo.py
def addSpanwiseLocalDV(
        self,
        dvName,
        spanIndex,
        axis="y",
        lower=None,
        upper=None,
        scale=1.0,
        pointSelect=None,
        volList=None,
        config=None,
    ):
        """
        Add one or more spanwise local design variables to the DVGeometry
        object. Spanwise local variables are alternative form of local shape
        variables used to apply equal DV changes in a chosen direction.
        Some scenarios were this could be useful are:

        1.  2D airfoil shape optimization. Because adflow works with 3D meshes,
            2D problems are represented my a mesh a single cell wide. Therefor,
            to change the 2D representation of the airfoil both sides of the
            mesh must be moved equally. This can be done with the addition of
            linear constraints on a set of local shape variables, however this
            approach requires more DVs than necessary (which complicates DV
            sweeps) and the constaints are only enforced to a tolerance. Using
            spanwise local design variables insures the airfoil is always
            correctly represented in the 3D mesh using the correct amount of
            design variables.

        2.  3D wing optimization with constant airfoil shape. If the initial
            wing geometry has a constant airfoil shape  and constant chord, then
            spanwise local dvs can be used to change the airfoil shape of the
            wing while still keeping it constant along the span of the wing.

        Parameters
        ----------
        dvName : str
            A unique name to be given to this design variable group

        spanIndex : str, ('i', 'j', 'k')
            the axis of the FFD along which the DVs are constant
            all shape variables

        axis : str. Default is `y`
            The coordinate directions to move. Permissible values are `x`,
            `y` and `z`. If more than one direction is required, use multiple
            calls to addLocalDV with different axis values.

        lower : float
            The lower bound for the variable(s). This will be applied to
            all shape variables

        upper : float
            The upper bound for the variable(s). This will be applied to
            all shape variables

        scale : flot
            The scaling of the variables. A good approximate scale to
            start with is approximately 1.0/(upper-lower). This gives
            variables that are of order ~1.0.

        pointSelect : pointSelect object. Default is None Use a
            pointSelect object to select a subset of the total number
            of control points. See the documentation for the
            pointSelect class in geo_utils. Using pointSelect discards everything in
            volList.

        volList : list
            Use the control points on the volume indicies given in volList.
            You should use pointSelect = None, otherwise this will not work.

        config : str or list
            Define what configurations this design variable will be applied to
            Use a string for a single configuration or a list for multiple
            configurations. The default value of None implies that the design
            variable applies to *ALL* configurations.

        Returns
        -------
        N : int
            The number of design variables added.

        Examples
        --------
        >>> # Add all spanwise local variables
        >>> # moving in the y direction, within +/- 0.5 units
        >>> DVGeo.addSpanwiseLocalDV("shape", 'k', lower=-0.5, upper=0.5, axis="z", scale=1.0)
        """
        if isinstance(config, str):
            config = [config]

        if pointSelect is not None:
            if pointSelect.type != "ijkBounds":
                pts, ind = pointSelect.getPoints(self.FFD.coef)
            else:
                pts, ind = pointSelect.getPoints_ijk(self)
        elif volList is not None:
            if self.FFD.symmPlane is not None:
                volListTmp = []
                for vol in volList:
                    volListTmp.append(vol)
                for vol in volList:
                    volListTmp.append(vol + self.FFD.nVol / 2)
                volList = volListTmp

            volList = np.atleast_1d(volList).astype("int")
            ind = []
            for iVol in volList:
                ind.extend(self.FFD.topo.lIndex[iVol].flatten())
            ind = geo_utils.unique(ind)
        else:
            # Just take'em all
            volList = np.arange(self.FFD.nVol)
            ind = np.arange(len(self.FFD.coef))

        # secLink = np.zeros(self.FFD.coef.shape[0], dtype=int)
        # secTransform = [np.eye(3)]

        if isinstance(spanIndex, str):
            spanIndex = [spanIndex] * len(volList)
        elif isinstance(spanIndex, list):
            if len(spanIndex) != len(volList):
                raise Error("If a list is given for spanIndex, the length must be" " equal to the length of volList.")

        ijk_2_idx = {"i": 0, "j": 1, "k": 2}

        volDVMap = []
        for ivol in volList:

            spanIdx = ijk_2_idx[spanIndex[ivol]]
            lIndex = self.FFD.topo.lIndex[ivol]

            topo_shape = lIndex.shape

            # remove the span axis since all dv in that axis are linked
            n_linked_coef = topo_shape[spanIdx]
            dvs_shape = np.delete(topo_shape, spanIdx)

            # get total number of dvs
            n_dvs = np.product(dvs_shape)

            # make a map from dvs to the ind that are controlled by that dv.
            # (phrased another way) map from dv to all ind in the same span size position
            dv_to_coef_ind = np.zeros((n_dvs, n_linked_coef), dtype="intc")

            # slice lIndex to get the indices of the coeffs that are in the same
            # spanwise position
            dv_idx = 0
            for i in range(dvs_shape[0]):
                for j in range(dvs_shape[1]):
                    # no need to use fancy axis manipulation, since it doesn't need
                    # to be fast and if statements are expressive
                    if spanIndex[ivol] == "i":
                        coef_ind = lIndex[:, i, j]
                    elif spanIndex[ivol] == "j":
                        coef_ind = lIndex[i, :, j]
                    elif spanIndex[ivol] == "k":
                        coef_ind = lIndex[i, j, :]

                    dv_to_coef_ind[dv_idx] = coef_ind
                    dv_idx += 1

            # the for this volume is complete and can be added to the list of maps
            volDVMap.append(dv_to_coef_ind)

        self.DV_listSpanwiseLocal[dvName] = geoDVSpanwiseLocal(
            dvName, lower, upper, scale, axis, volDVMap, self.masks, config
        )

        return self.DV_listSpanwiseLocal[dvName].nVal

        Add one or more spanwise local design variables to the DVGeometry
        object. Spanwise local variables are alternative form of local shape
        variables used to apply equal DV changes in a chosen direction.
        Some scenarios were this could be useful are:

        1.  2D airfoil shape optimization. Because adflow works with 3D meshes,
            2D problems are represented my a mesh a single cell wide. Therefor,
            to change the 2D representation of the airfoil both sides of the
            mesh must be moved equally. This can be done with the addition of
            linear constraints on a set of local shape variables, however this
            approach requires more DVs than necessary (which complicates DV
            sweeps) and the constaints are only enforced to a tolerance. Using
            spanwise local design variables insures the airfoil is always
            correctly represented in the 3D mesh using the correct amount of
            design variables.

        2.  3D wing optimization with constant airfoil shape. If the initial
            wing geometry has a constant airfoil shape  and constant chord, then
            spanwise local dvs can be used to change the airfoil shape of the
            wing while still keeping it constant along the span of the wing.

        Parameters
        ----------
        dvName : str
            A unique name to be given to this design variable group

        spanIndex : str, ('i', 'j', 'k')
            the axis of the FFD along which the DVs are constant
            all shape variables

        axis : str. Default is `y`
            The coordinate directions to move. Permissible values are `x`,
            `y` and `z`. If more than one direction is required, use multiple
            calls to addLocalDV with different axis values.

        lower : float
            The lower bound for the variable(s). This will be applied to
            all shape variables

        upper : float
            The upper bound for the variable(s). This will be applied to
            all shape variables

        scale : flot
            The scaling of the variables. A good approximate scale to
            start with is approximately 1.0/(upper-lower). This gives
            variables that are of order ~1.0.

        pointSelect : pointSelect object. Default is None Use a
            pointSelect object to select a subset of the total number
            of control points. See the documentation for the
            pointSelect class in geo_utils. Using pointSelect discards everything in
            volList.

        volList : list
            Use the control points on the volume indicies given in volList.
            You should use pointSelect = None, otherwise this will not work.

        config : str or list
            Define what configurations this design variable will be applied to
            Use a string for a single configuration or a list for multiple
            configurations. The default value of None implies that the design
            variable applies to *ALL* configurations.

        Returns
        -------
        N : int
            The number of design variables added.

        Examples
        --------
        >>> # Add all spanwise local variables
        >>> # moving in the y direction, within +/- 0.5 units
        >>> DVGeo.addSpanwiseLocalDV("shape", 'k', lower=-0.5, upper=0.5, axis="z", scale=1.0)
        
Add one or more spanwise local design variables to the DVGeometry
object. Spanwise local variables are alternative form of local shape
variables used to apply equal DV changes in a chosen direction.
Some scenarios were this could be useful are.

1.  2D airfoil shape optimization. Because adflow works with 3D meshes,
2D problems are represented my a mesh a single cell wide. Therefor,
to change the 2D representation of the airfoil both sides of the
mesh must be moved equally. This can be done with the addition of
linear constraints on a set of local shape variables, however this
approach requires more DVs than necessary (which complicates DV
sweeps) and the constaints are only enforced to a tolerance. Using
spanwise local design variables insures the airfoil is always
correctly represented in the 3D mesh using the correct amount of
design variables.

2.  3D wing optimization with constant airfoil shape. If the initial
wing geometry has a constant airfoil shape  and constant chord, then
spanwise local dvs can be used to change the airfoil shape of the
wing while still keeping it constant along the span of the wing.

Parameters

dvName : str
A unique name to be given to this design variable group



axis : str. Default is `y`
The coordinate directions to move.

lower : float
The lower bound for the variable(s). This will be applied to
all shape variables

upper : float
The upper bound for the variable(s). This will be applied to
all shape variables

scale : flot
The scaling of the variables. A good approximate scale to
start with is approximately 1.0/(upper-lower). This gives
variables that are of order ~1.0.

pointSelect : pointSelect object. Default is None Use a
pointSelect object to select a subset of the total number
of control points. See the documentation for the
pointSelect class in geo_utils. Using pointSelect discards everything in
volList.

volList : list
Use the control points on the volume indicies given in volList.
You should use pointSelect = None, otherwise this will not work.

config : str or list
Define what configurations this design variable will be applied to
Use a string for a single configuration or a list for multiple
configurations. The default value of None implies that the design
variable applies to *ALL* configurations.

Returns

N : int
The number of design variables added.

Examples


Add one or more spanwise local design variables to the DVGeometry object . Spanwise local variables are alternative form of local shape variables used to apply equal DV changes in a chosen direction . Some scenarios were this could be useful are . 1 . 2D airfoil shape optimization . Because adflow works with 3D meshes 2D problems are represented my a mesh a single cell wide . Therefor to change the 2D representation of the airfoil both sides of the mesh must be moved equally . This can be done with the addition of linear constraints on a set of local shape variables however this approach requires more DVs than necessary ( which complicates DV sweeps ) and the constaints are only enforced to a tolerance . Using spanwise local design variables insures the airfoil is always correctly represented in the 3D mesh using the correct amount of design variables . 2 . 3D wing optimization with constant airfoil shape . If the initial wing geometry has a constant airfoil shape and constant chord then spanwise local dvs can be used to change the airfoil shape of the wing while still keeping it constant along the span of the wing . Parameters dvName : str A unique name to be given to this design variable group axis : str . Default is ` y ` The coordinate directions to move . lower : float The lower bound for the variable ( s ) . This will be applied to all shape variables upper : float The upper bound for the variable ( s ) . This will be applied to all shape variables scale : flot The scaling of the variables . A good approximate scale to start with is approximately 1 . 0 / ( upper - lower ) . This gives variables that are of order ~1 . 0 . pointSelect : pointSelect object . Default is None Use a pointSelect object to select a subset of the total number of control points . See the documentation for the pointSelect class in geo_utils . Using pointSelect discards everything in volList . volList : list Use the control points on the volume indicies given in volList . You should use pointSelect = None otherwise this will not work . config : str or list Define what configurations this design variable will be applied to Use a string for a single configuration or a list for multiple configurations . The default value of None implies that the design variable applies to * ALL * configurations . Returns N : int The number of design variables added . Examples
def addSpanwiseLocalDV(
        self,
        dvName,
        spanIndex,
        axis="y",
        lower=None,
        upper=None,
        scale=1.0,
        pointSelect=None,
        volList=None,
        config=None,
    ):
        if isinstance(config, str):
            config = [config]
        if pointSelect is not None:
            if pointSelect.type != "ijkBounds":
                pts, ind = pointSelect.getPoints(self.FFD.coef)
            else:
                pts, ind = pointSelect.getPoints_ijk(self)
        elif volList is not None:
            if self.FFD.symmPlane is not None:
                volListTmp = []
                for vol in volList:
                    volListTmp.append(vol)
                for vol in volList:
                    volListTmp.append(vol + self.FFD.nVol / 2)
                volList = volListTmp
            volList = np.atleast_1d(volList).astype("int")
            ind = []
            for iVol in volList:
                ind.extend(self.FFD.topo.lIndex[iVol].flatten())
            ind = geo_utils.unique(ind)
        else:
            volList = np.arange(self.FFD.nVol)
            ind = np.arange(len(self.FFD.coef))
        if isinstance(spanIndex, str):
            spanIndex = [spanIndex] * len(volList)
        elif isinstance(spanIndex, list):
            if len(spanIndex) != len(volList):
                raise Error("If a list is given for spanIndex, the length must be" " equal to the length of volList.")
        ijk_2_idx = {"i": 0, "j": 1, "k": 2}
        volDVMap = []
        for ivol in volList:
            spanIdx = ijk_2_idx[spanIndex[ivol]]
            lIndex = self.FFD.topo.lIndex[ivol]
            topo_shape = lIndex.shape
            n_linked_coef = topo_shape[spanIdx]
            dvs_shape = np.delete(topo_shape, spanIdx)
            n_dvs = np.product(dvs_shape)
            dv_to_coef_ind = np.zeros((n_dvs, n_linked_coef), dtype="intc")
            dv_idx = 0
            for i in range(dvs_shape[0]):
                for j in range(dvs_shape[1]):
                    if spanIndex[ivol] == "i":
                        coef_ind = lIndex[:, i, j]
                    elif spanIndex[ivol] == "j":
                        coef_ind = lIndex[i, :, j]
                    elif spanIndex[ivol] == "k":
                        coef_ind = lIndex[i, j, :]
                    dv_to_coef_ind[dv_idx] = coef_ind
                    dv_idx += 1
            volDVMap.append(dv_to_coef_ind)
        self.DV_listSpanwiseLocal[dvName] = geoDVSpanwiseLocal(
            dvName, lower, upper, scale, axis, volDVMap, self.masks, config
        )
        return self.DV_listSpanwiseLocal[dvName].nVal
def addSpanwiseLocalDV ( self , dvName , spanIndex , axis = "y" , lower = None , upper = None , scale = 1.0 , pointSelect = None , volList = None , config = None , ) : if isinstance ( config , str ) : config = [ config ] if pointSelect is not None : if pointSelect . type != "ijkBounds" : pts , ind = pointSelect . getPoints ( self . FFD . coef ) else : pts , ind = pointSelect . getPoints_ijk ( self ) elif volList is not None : if self . FFD . symmPlane is not None : volListTmp = [ ] for vol in volList : volListTmp . append ( vol ) for vol in volList : volListTmp . append ( vol + self . FFD . nVol / 2 ) volList = volListTmp volList = np . atleast_1d ( volList ) . astype ( "int" ) ind = [ ] for iVol in volList : ind . extend ( self . FFD . topo . lIndex [ iVol ] . flatten ( ) ) ind = geo_utils . unique ( ind ) else : volList = np . arange ( self . FFD . nVol ) ind = np . arange ( len ( self . FFD . coef ) ) if isinstance ( spanIndex , str ) : spanIndex = [ spanIndex ] * len ( volList ) elif isinstance ( spanIndex , list ) : if len ( spanIndex ) != len ( volList ) : raise Error ( "If a list is given for spanIndex, the length must be" " equal to the length of volList." ) ijk_2_idx = { "i" : 0 , "j" : 1 , "k" : 2 } volDVMap = [ ] for ivol in volList : spanIdx = ijk_2_idx [ spanIndex [ ivol ] ] lIndex = self . FFD . topo . lIndex [ ivol ] topo_shape = lIndex . shape n_linked_coef = topo_shape [ spanIdx ] dvs_shape = np . delete ( topo_shape , spanIdx ) n_dvs = np . product ( dvs_shape ) dv_to_coef_ind = np . zeros ( ( n_dvs , n_linked_coef ) , dtype = "intc" ) dv_idx = 0 for i in range ( dvs_shape [ 0 ] ) : for j in range ( dvs_shape [ 1 ] ) : if spanIndex [ ivol ] == "i" : coef_ind = lIndex [ : , i , j ] elif spanIndex [ ivol ] == "j" : coef_ind = lIndex [ i , : , j ] elif spanIndex [ ivol ] == "k" : coef_ind = lIndex [ i , j , : ] dv_to_coef_ind [ dv_idx ] = coef_ind dv_idx += 1 volDVMap . append ( dv_to_coef_ind ) self . DV_listSpanwiseLocal [ dvName ] = geoDVSpanwiseLocal ( dvName , lower , upper , scale , axis , volDVMap , self . masks , config ) return self . DV_listSpanwiseLocal [ dvName ] . nVal
Add one or more spanwise local design variables to the DVGeometry
object.
Add one or more spanwise local design variables to the DVGeometry object .
"""
        Add one or more spanwise local design variables to the DVGeometry
        object. Spanwise local variables are alternative form of local shape
        variables used to apply equal DV changes in a chosen direction.
        Some scenarios were this could be useful are:

        1.  2D airfoil shape optimization. Because adflow works with 3D meshes,
            2D problems are represented my a mesh a single cell wide. Therefor,
            to change the 2D representation of the airfoil both sides of the
            mesh must be moved equally. This can be done with the addition of
            linear constraints on a set of local shape variables, however this
            approach requires more DVs than necessary (which complicates DV
            sweeps) and the constaints are only enforced to a tolerance. Using
            spanwise local design variables insures the airfoil is always
            correctly represented in the 3D mesh using the correct amount of
            design variables.

        2.  3D wing optimization with constant airfoil shape. If the initial
            wing geometry has a constant airfoil shape  and constant chord, then
            spanwise local dvs can be used to change the airfoil shape of the
            wing while still keeping it constant along the span of the wing.

        Parameters
        ----------
        dvName : str
            A unique name to be given to this design variable group

        spanIndex : str, ('i', 'j', 'k')
            the axis of the FFD along which the DVs are constant
            all shape variables

        axis : str. Default is `y`
            The coordinate directions to move. Permissible values are `x`,
            `y` and `z`. If more than one direction is required, use multiple
            calls to addLocalDV with different axis values.

        lower : float
            The lower bound for the variable(s). This will be applied to
            all shape variables

        upper : float
            The upper bound for the variable(s). This will be applied to
            all shape variables

        scale : flot
            The scaling of the variables. A good approximate scale to
            start with is approximately 1.0/(upper-lower). This gives
            variables that are of order ~1.0.

        pointSelect : pointSelect object. Default is None Use a
            pointSelect object to select a subset of the total number
            of control points. See the documentation for the
            pointSelect class in geo_utils. Using pointSelect discards everything in
            volList.

        volList : list
            Use the control points on the volume indicies given in volList.
            You should use pointSelect = None, otherwise this will not work.

        config : str or list
            Define what configurations this design variable will be applied to
            Use a string for a single configuration or a list for multiple
            configurations. The default value of None implies that the design
            variable applies to *ALL* configurations.

        Returns
        -------
        N : int
            The number of design variables added.

        Examples
        --------
        >>> # Add all spanwise local variables
        >>> # moving in the y direction, within +/- 0.5 units
        >>> DVGeo.addSpanwiseLocalDV("shape", 'k', lower=-0.5, upper=0.5, axis="z", scale=1.0)
        """ # Just take'em all # secLink = np.zeros(self.FFD.coef.shape[0], dtype=int) # secTransform = [np.eye(3)] # remove the span axis since all dv in that axis are linked # get total number of dvs # make a map from dvs to the ind that are controlled by that dv. # (phrased another way) map from dv to all ind in the same span size position # slice lIndex to get the indices of the coeffs that are in the same # spanwise position # no need to use fancy axis manipulation, since it doesn't need # to be fast and if statements are expressive # the for this volume is complete and can be added to the list of maps
self
dvName
spanIndex
axis
lower
upper
scale
pointSelect
volList
config