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 deltas not calculated with the same point set as parent. #7

Open
joanibal opened this issue Apr 16, 2019 · 3 comments
Open
Labels
wontfix This will not be worked on

Comments

@joanibal
Copy link
Collaborator

Previously known issue written here for documentation.

The Problem

When working with a child FFD embed in a parent FFD, a sub set of the points embedded in the parent will also be embed in the child. When calculating the additional movement of embed points due to the modification of the child FFD, the child FFD will first update the points embed inside of itself according to how the control points of the child were moved when the parent deformed. However, updating the points according to how the control points of the child were moved will not produce a point set identical to those embed in the parent! So when the child calculates deltas (additional position modifications) and they are added to the modifications caused by the motion of the parent FFD, the deltas will not have the intended geometric effect. For example in cases where the parent FFD does shape modifications and the child rotates a subset of these points (think morphing LE/TE), the rotation will skew the shape modifications. An example of this is shown in the picture below.
shapeModificationsSkewed

When it's an Issue

  • when combining parent shape variables with child shape deformation that isn't uniform for each point (child shape variables and rotation will cause issues, but translation will not).
  • Especially apparent when using large child FFD modifications

Work Around

  • use a linear spline surface for the Child FFD (works well for rotations, but not for child shape variables)

long term fix

  • change the data structure for child FFDs so that it references the same point set as the parent (same object in memory) but only works with a sub set of these points (the ones inside the child FFD). This way the points that the child FFD uses to calculate its additional modifications will always be the same as the points warped by the parent deformation.
@joanibal joanibal self-assigned this Apr 16, 2019
@joanibal joanibal added the bug Something isn't working label Apr 16, 2019
@joanibal joanibal linked a pull request Feb 21, 2020 that will close this issue
@joanibal joanibal added the wontfix This will not be worked on label Feb 21, 2020
@joanibal joanibal removed their assignment Dec 21, 2020
@joanibal joanibal removed the bug Something isn't working label Dec 21, 2020
@bbrelje
Copy link
Collaborator

bbrelje commented Feb 28, 2021

@joanibal can you post the global design variable function you used in the child?

While writing the tutorial I wanted to understand why global variable funcs that use += operations work properly. When self.update() is called, the FFD coefficients are set back to their original (baseline) locations and then the global DVs are computed in order of their addition, then sectionlocal and local variables. So you don't accumulate changes across iterations via += operations.

On the other hand, child FFDs do some weird stuff that I don't totally understand, but I don't think it's doing the same reset. So if you used += or *= operations in your child global dv funcs, it could lead to some weird behavior. It may or may not be relevant to your debugging here

        if not self.isChild:
            self.FFD.coef = self.origFFDCoef.copy()
            self._setInitialValues()
        else:
            # Update all coef
            self.FFD._updateVolumeCoef()

            # Evaluate starting pointset
            Xstart = self.FFD.getAttachedPoints(ptSetName)

            if self.complex:
                # Now we have to propagate the complex part through Xstart
                tempCoef = self.FFD.coef.copy().astype('D')
                Xstart = Xstart.astype('D')
                imag_part = numpy.imag(tempCoef)
                imag_j = 1j

                dPtdCoef = self.FFD.embededVolumes[ptSetName].dPtdCoef
                if dPtdCoef is not None:
                    for ii in range(3):
                        Xstart[:, ii] += imag_j*dPtdCoef.dot(imag_part[:, ii])

@joanibal
Copy link
Collaborator Author

joanibal commented Mar 1, 2021

Here are the functions I used with child FFDs

def twist_flap(val, geo):
    geo.rot_z['flap_axis'].coef[:] = val[:] - 29.5


def translate_x_flap(val, geo):
    C = geo.extractCoef('flap_axis')
    C[:, 0] += val[:] + 0.15421028
    geo.restoreCoef(C, 'flap_axis')


def translate_y_flap(val, geo):
    C = geo.extractCoef('flap_axis')
    C[:, 1] += val[:] - 0.0816069
    geo.restoreCoef(C, 'flap_axis')


def twist_slat(val, geo):
    geo.rot_z['slat_axis'].coef[:] = val[:] + 29.0


def translate_x_slat(val, geo):
    C = geo.extractCoef('slat_axis')
    C[:, 0] += val[:] - .0911552
    geo.restoreCoef(C, 'slat_axis')


def translate_y_slat(val, geo):
    C = geo.extractCoef('slat_axis')
    C[:, 1] += val[:] - 0.0735696
    geo.restoreCoef(C, 'slat_axis')

@bbrelje
Copy link
Collaborator

bbrelje commented Mar 1, 2021

Yeah I can't say for certain that the weird behavior is caused by the per-iteration reset behavior of the coefficients referenced by C = geo.extractCoef('slat_axis') but it's possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wontfix This will not be worked on
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants