Exemple #1
0
    def provideJ(self):

        V = self.V
        R = self.R
        CT = self.CT
        CQ = self.CQ
        CP = self.CP
        n = len(self.V)
        q = 0.5 * self.rho * V**2
        A = pi * R**2
        zeronn = np.zeros((n, n))

        dCT_dV = np.diag(-2.0*CT/V)
        dCT_dT = np.diag(1.0/(q*A))
        dCT_dR = -2.0*CT/R
        dCT = hstack((dCT_dV, dCT_dT, zeronn, zeronn, dCT_dR))

        dCQ_dV = np.diag(-2.0*CQ/V)
        dCQ_dQ = np.diag(1.0/(q*R*A))
        dCQ_dR = -3.0*CQ/R
        dCQ = hstack((dCQ_dV, zeronn, dCQ_dQ, zeronn, dCQ_dR))

        dCP_dV = np.diag(-3.0*CP/V)
        dCP_dP = np.diag(1.0/(q*A*V))
        dCP_dR = -2.0*CP/R
        dCP = hstack((dCP_dV, zeronn, zeronn, dCP_dP, dCP_dR))

        J = vstack((dCT, dCQ, dCP))

        return J
Exemple #2
0
    def linearize(self, params, unknowns, resids):

        dF = DirectionVector.fromArray(params['F']).hubToYaw(params['tilt'])
        dFx, dFy, dFz = dF.dx, dF.dy, dF.dz

        dtopF_dFx = np.array([dFx['dx'], dFy['dx'], dFz['dx']])
        dtopF_dFy = np.array([dFx['dy'], dFy['dy'], dFz['dy']])
        dtopF_dFz = np.array([dFx['dz'], dFy['dz'], dFz['dz']])
        dtopF_dF = hstack([dtopF_dFx, dtopF_dFy, dtopF_dFz])
        dtopF_w_dm = np.array([0.0, 0.0, -self.g])

        #dtopF = hstack([dtopF_dF, np.zeros((3, 6)), dtopF_w_dm, np.zeros((3, 3))])


        dM = DirectionVector.fromArray(params['M']).hubToYaw(params['tilt'])
        dMx, dMy, dMz = dM.dx, dM.dy, dM.dz
        dMxcross, dMycross, dMzcross = self.save_rhub.cross_deriv(self.saveF, 'dr', 'dF')

        dtopM_dMx = np.array([dMx['dx'], dMy['dx'], dMz['dx']])
        dtopM_dMy = np.array([dMx['dy'], dMy['dy'], dMz['dy']])
        dtopM_dMz = np.array([dMx['dz'], dMy['dz'], dMz['dz']])
        dtopM_dM = hstack([dtopM_dMx, dtopM_dMy, dtopM_dMz])
        dM_dF = np.array([dMxcross['dF'], dMycross['dF'], dMzcross['dF']])

        dtopM_dFx = np.dot(dM_dF, dtopF_dFx)
        dtopM_dFy = np.dot(dM_dF, dtopF_dFy)
        dtopM_dFz = np.dot(dM_dF, dtopF_dFz)
        dtopM_dF = hstack([dtopM_dFx, dtopM_dFy, dtopM_dFz])
        dtopM_dr = np.array([dMxcross['dr'], dMycross['dr'], dMzcross['dr']])

        dMx_w_cross, dMy_w_cross, dMz_w_cross = self.save_rcm.cross_deriv(self.saveF_w, 'dr', 'dF')

        if params['rna_weightM']:
            dtopM_drnacm = np.array([dMx_w_cross['dr'], dMy_w_cross['dr'], dMz_w_cross['dr']])
            dtopM_dF_w = np.array([dMx_w_cross['dF'], dMy_w_cross['dF'], dMz_w_cross['dF']])
        else:
            dtopM_drnacm = np.zeros((3, 3))
            dtopM_dF_w = np.zeros((3, 3))
        dtopM_dm = np.dot(dtopM_dF_w, dtopF_w_dm)

        if params['downwind']:
            dtopM_dr[:, 0] *= -1
            dtopM_drnacm[:, 0] *= -1

        #dtopM = hstack([dtopM_dF, dtopM_dM, dtopM_dr, dtopM_dm, dtopM_drnacm])

        J = {}
        J['top_F', 'F'] = dtopF_dF
        J['top_F', 'M'] = np.zeros((3, 3))
        J['top_F', 'r_hub'] = np.zeros((3, 3))
        J['top_F', 'rna_mass'] = dtopF_w_dm
        J['top_F', 'rna_cm'] = np.zeros((3, 3))

        J['top_M', 'F'] = dtopM_dF
        J['top_M', 'M'] = dtopM_dM
        J['top_M', 'r_hub'] = dtopM_dr
        J['top_M', 'rna_mass'] = dtopM_dm
        J['top_M', 'rna_cm'] = dtopM_drnacm

        return J
Exemple #3
0
    def provideJ(self):

        dF = DirectionVector.fromArray(self.F).hubToYaw(self.tilt)
        dFx, dFy, dFz = dF.dx, dF.dy, dF.dz

        dtopF_dFx = np.array([dFx['dx'], dFy['dx'], dFz['dx']])
        dtopF_dFy = np.array([dFx['dy'], dFy['dy'], dFz['dy']])
        dtopF_dFz = np.array([dFx['dz'], dFy['dz'], dFz['dz']])
        dtopF_dF = hstack([dtopF_dFx, dtopF_dFy, dtopF_dFz])
        dtopF_w_dm = np.array([0.0, 0.0, -self.g])

        dtopF = hstack(
            [dtopF_dF,
             np.zeros((3, 6)), dtopF_w_dm,
             np.zeros((3, 3))])

        dM = DirectionVector.fromArray(self.M).hubToYaw(self.tilt)
        dMx, dMy, dMz = dM.dx, dM.dy, dM.dz
        dMxcross, dMycross, dMzcross = self.save_rhub.cross_deriv(
            self.saveF, 'dr', 'dF')

        dtopM_dMx = np.array([dMx['dx'], dMy['dx'], dMz['dx']])
        dtopM_dMy = np.array([dMx['dy'], dMy['dy'], dMz['dy']])
        dtopM_dMz = np.array([dMx['dz'], dMy['dz'], dMz['dz']])
        dtopM_dM = hstack([dtopM_dMx, dtopM_dMy, dtopM_dMz])
        dM_dF = np.array([dMxcross['dF'], dMycross['dF'], dMzcross['dF']])

        dtopM_dFx = np.dot(dM_dF, dtopF_dFx)
        dtopM_dFy = np.dot(dM_dF, dtopF_dFy)
        dtopM_dFz = np.dot(dM_dF, dtopF_dFz)
        dtopM_dF = hstack([dtopM_dFx, dtopM_dFy, dtopM_dFz])
        dtopM_dr = np.array([dMxcross['dr'], dMycross['dr'], dMzcross['dr']])

        dMx_w_cross, dMy_w_cross, dMz_w_cross = self.save_rcm.cross_deriv(
            self.saveF_w, 'dr', 'dF')

        if self.rna_weightM:
            dtopM_drnacm = np.array(
                [dMx_w_cross['dr'], dMy_w_cross['dr'], dMz_w_cross['dr']])
            dtopM_dF_w = np.array(
                [dMx_w_cross['dF'], dMy_w_cross['dF'], dMz_w_cross['dF']])
        else:
            dtopM_drnacm = np.zeros((3, 3))
            dtopM_dF_w = np.zeros((3, 3))
        dtopM_dm = np.dot(dtopM_dF_w, dtopF_w_dm)

        if self.downwind:
            dtopM_dr[:, 0] *= -1
            dtopM_drnacm[:, 0] *= -1

        dtopM = hstack([dtopM_dF, dtopM_dM, dtopM_dr, dtopM_dm, dtopM_drnacm])

        J = vstack([dtopF, dtopM])

        return J
Exemple #4
0
    def provideJ(self):

        dF = DirectionVector.fromArray(self.F).hubToYaw(self.tilt)
        dFx, dFy, dFz = dF.dx, dF.dy, dF.dz

        dtopF_dFx = np.array([dFx['dx'], dFy['dx'], dFz['dx']])
        dtopF_dFy = np.array([dFx['dy'], dFy['dy'], dFz['dy']])
        dtopF_dFz = np.array([dFx['dz'], dFy['dz'], dFz['dz']])
        dtopF_dF = hstack([dtopF_dFx, dtopF_dFy, dtopF_dFz])
        dtopF_w_dm = np.array([0.0, 0.0, -self.g])

        dtopF = hstack([dtopF_dF, np.zeros((3, 6)), dtopF_w_dm, np.zeros((3, 3))])


        dM = DirectionVector.fromArray(self.M).hubToYaw(self.tilt)
        dMx, dMy, dMz = dM.dx, dM.dy, dM.dz
        dMxcross, dMycross, dMzcross = self.save_rhub.cross_deriv(self.saveF, 'dr', 'dF')

        dtopM_dMx = np.array([dMx['dx'], dMy['dx'], dMz['dx']])
        dtopM_dMy = np.array([dMx['dy'], dMy['dy'], dMz['dy']])
        dtopM_dMz = np.array([dMx['dz'], dMy['dz'], dMz['dz']])
        dtopM_dM = hstack([dtopM_dMx, dtopM_dMy, dtopM_dMz])
        dM_dF = np.array([dMxcross['dF'], dMycross['dF'], dMzcross['dF']])

        dtopM_dFx = np.dot(dM_dF, dtopF_dFx)
        dtopM_dFy = np.dot(dM_dF, dtopF_dFy)
        dtopM_dFz = np.dot(dM_dF, dtopF_dFz)
        dtopM_dF = hstack([dtopM_dFx, dtopM_dFy, dtopM_dFz])
        dtopM_dr = np.array([dMxcross['dr'], dMycross['dr'], dMzcross['dr']])

        dMx_w_cross, dMy_w_cross, dMz_w_cross = self.save_rcm.cross_deriv(self.saveF_w, 'dr', 'dF')

        if self.rna_weightM:
            dtopM_drnacm = np.array([dMx_w_cross['dr'], dMy_w_cross['dr'], dMz_w_cross['dr']])
            dtopM_dF_w = np.array([dMx_w_cross['dF'], dMy_w_cross['dF'], dMz_w_cross['dF']])
        else:
            dtopM_drnacm = np.zeros((3, 3))
            dtopM_dF_w = np.zeros((3, 3))
        dtopM_dm = np.dot(dtopM_dF_w, dtopF_w_dm)

        if self.downwind:
            dtopM_dr[:, 0] *= -1
            dtopM_drnacm[:, 0] *= -1

        dtopM = hstack([dtopM_dF, dtopM_dM, dtopM_dr, dtopM_dm, dtopM_drnacm])

        J = vstack([dtopF, dtopM])

        return J
Exemple #5
0
    def execute(self):

        ctrl = self.control
        n = self.npts
        R = self.R

        # # attempt to distribute points mostly before rated
        # cpguess = 0.5
        # Vr0 = (ctrl.ratedPower/(cpguess*0.5*rho*pi*R**2))**(1.0/3)
        # Vr0 *= 1.20

        # V1 = np.linspace(Vin, Vr0, 15)
        # V2 = np.linspace(Vr0, Vout, 6)
        # V = np.concatenate([V1, V2[1:]])

        # velocity sweep
        V = np.linspace(ctrl.Vin, ctrl.Vout, n)

        # corresponding rotation speed
        Omega_d = ctrl.tsr*V/R*RS2RPM
        Omega, dOmega_dOmegad, dOmega_dmaxOmega = smooth_min(Omega_d, ctrl.maxOmega, pct_offset=0.01)

        # store values
        self.Uhub = V
        self.Omega = Omega
        self.pitch = ctrl.pitch*np.ones_like(V)

        # gradients
        dV = np.zeros((n, 3))
        dOmega_dtsr = dOmega_dOmegad * V/R*RS2RPM
        dOmega_dR = dOmega_dOmegad * -ctrl.tsr*V/R**2*RS2RPM
        dOmega = hstack([dOmega_dtsr, dOmega_dR, dOmega_dmaxOmega])
        dpitch = np.zeros((n, 3))
        self.J = vstack([dV, dOmega, dpitch])
Exemple #6
0
    def provideJ(self):

        x = self.x
        xbar = self.xbar
        dx = np.diag(np.exp(-pi/4.0*(x/xbar)**2)*pi*x/(2.0*xbar**2))
        dxbar = -np.exp(-pi/4.0*(x/xbar)**2)*pi*x**2/(2.0*xbar**3)
        J = hstack([dx, dxbar])

        return J
Exemple #7
0
    def provideJ(self):

        # mass
        dmass = np.hstack([np.array([1.0, 1.0, 1.0]), np.zeros(2*3+3*6)])

        # cm
        top = (self.rotor_mass*self.hub_cm + self.nac_mass*self.nac_cm)
        dcm_dblademass = (self.rna_mass*self.hub_cm - top)/self.rna_mass**2
        dcm_dhubmass = (self.rna_mass*self.hub_cm - top)/self.rna_mass**2
        dcm_dnacmass = (self.rna_mass*self.nac_cm - top)/self.rna_mass**2
        dcm_dhubcm = self.rotor_mass/self.rna_mass*np.eye(3)
        dcm_dnaccm = self.nac_mass/self.rna_mass*np.eye(3)

        dcm = hstack([dcm_dblademass, dcm_dhubmass, dcm_dnacmass, dcm_dhubcm,
            dcm_dnaccm, np.zeros((3, 3*6))])

        # I
        R = self.hub_cm
        const = self._unassembleI(np.dot(R, R)*np.eye(3) - np.outer(R, R))
        dI_dblademass = const
        dI_dhubmass = const
        dI_drx = self.rotor_mass*self._unassembleI(2*R[0]*np.eye(3) - np.array([[2*R[0], R[1], R[2]], [R[1], 0.0, 0.0], [R[2], 0.0, 0.0]]))
        dI_dry = self.rotor_mass*self._unassembleI(2*R[1]*np.eye(3) - np.array([[0.0, R[0], 0.0], [R[0], 2*R[1], R[2]], [0.0, R[2], 0.0]]))
        dI_drz = self.rotor_mass*self._unassembleI(2*R[2]*np.eye(3) - np.array([[0.0, 0.0, R[0]], [0.0, 0.0, R[1]], [R[0], R[1], 2*R[2]]]))
        dI_dhubcm = np.vstack([dI_drx, dI_dry, dI_drz]).T

        R = self.nac_cm
        const = self._unassembleI(np.dot(R, R)*np.eye(3) - np.outer(R, R))
        dI_dnacmass = const
        dI_drx = self.nac_mass*self._unassembleI(2*R[0]*np.eye(3) - np.array([[2*R[0], R[1], R[2]], [R[1], 0.0, 0.0], [R[2], 0.0, 0.0]]))
        dI_dry = self.nac_mass*self._unassembleI(2*R[1]*np.eye(3) - np.array([[0.0, R[0], 0.0], [R[0], 2*R[1], R[2]], [0.0, R[2], 0.0]]))
        dI_drz = self.nac_mass*self._unassembleI(2*R[2]*np.eye(3) - np.array([[0.0, 0.0, R[0]], [0.0, 0.0, R[1]], [R[0], R[1], 2*R[2]]]))
        dI_dnaccm = np.vstack([dI_drx, dI_dry, dI_drz]).T

        dI_dbladeI = np.eye(6)
        dI_dhubI = np.eye(6)
        dI_dnacI = np.eye(6)

        dI = hstack([dI_dblademass, dI_dhubmass, dI_dnacmass, dI_dhubcm, dI_dnaccm,
            dI_dbladeI, dI_dhubI, dI_dnacI])

        J = np.vstack([dmass, dcm, dI])

        return J
Exemple #8
0
    def provideJ(self):

        x = self.x
        k = self.k
        A = self.xbar / gamma(1.0 + 1.0/k)
        dx = np.diag(np.exp(-(x/A)**k)*(x/A)**(k-1)*k/A)
        dxbar = -np.exp(-(x/A)**k)*(x/A)**(k-1)*k*x/A**2/gamma(1.0 + 1.0/k)

        J = hstack([dx, dxbar])

        return J
Exemple #9
0
    def provideJ(self):

        x = self.x
        xbar = self.xbar
        dx = np.diag(
            np.exp(-pi / 4.0 * (x / xbar)**2) * pi * x / (2.0 * xbar**2))
        dxbar = -np.exp(-pi / 4.0 *
                        (x / xbar)**2) * pi * x**2 / (2.0 * xbar**3)
        J = hstack([dx, dxbar])

        return J
Exemple #10
0
    def execute(self):

        ctrl = self.control
        n = self.npts

        # finer power curve
        self.V, _, _ = linspace_with_deriv(ctrl.Vin, ctrl.Vout, n)
        spline = Akima(self.Vcoarse, self.Pcoarse)
        self.P, dP_dV, dP_dVcoarse, dP_dPcoarse = spline.interp(self.V)

        self.J = hstack([dP_dVcoarse, dP_dPcoarse])
Exemple #11
0
    def execute(self):

        drivetrainType = self.drivetrainType
        aeroPower = self.aeroPower
        aeroTorque = self.aeroTorque
        ratedPower = self.ratedPower


        if drivetrainType == 'geared':
            constant = 0.01289
            linear = 0.08510
            quadratic = 0.0

        elif drivetrainType == 'single_stage':
            constant = 0.01331
            linear = 0.03655
            quadratic = 0.06107

        elif drivetrainType == 'multi_drive':
            constant = 0.01547
            linear = 0.04463
            quadratic = 0.05790

        elif drivetrainType == 'pm_direct_drive':
            constant = 0.01007
            linear = 0.02000
            quadratic = 0.06899


        Pbar0 = aeroPower / ratedPower

        # handle negative power case (with absolute value)
        Pbar1, dPbar1_dPbar0 = smooth_abs(Pbar0, dx=0.01)

        # truncate idealized power curve for purposes of efficiency calculation
        Pbar, dPbar_dPbar1, _ = smooth_min(Pbar1, 1.0, pct_offset=0.01)

        # compute efficiency
        eff = 1.0 - (constant/Pbar + linear + quadratic*Pbar)

        self.power = aeroPower * eff

        # gradients
        dPbar_dPa = dPbar_dPbar1*dPbar1_dPbar0/ratedPower
        dPbar_dPr = -dPbar_dPbar1*dPbar1_dPbar0*aeroPower/ratedPower**2

        deff_dPa = dPbar_dPa*(constant/Pbar**2 - quadratic)
        deff_dPr = dPbar_dPr*(constant/Pbar**2 - quadratic)

        dP_dPa = eff + aeroPower*deff_dPa
        dP_dPr = aeroPower*deff_dPr

        self.J = hstack([np.diag(dP_dPa), dP_dPr])
Exemple #12
0
    def provideJ(self):

        x = self.x
        k = self.k
        A = self.xbar / gamma(1.0 + 1.0 / k)
        dx = np.diag(np.exp(-(x / A)**k) * (x / A)**(k - 1) * k / A)
        dxbar = -np.exp(-(x / A)**k) * (x / A)**(
            k - 1) * k * x / A**2 / gamma(1.0 + 1.0 / k)

        J = hstack([dx, dxbar])

        return J
Exemple #13
0
    def execute(self):

        drivetrainType = self.drivetrainType
        aeroPower = self.aeroPower
        aeroTorque = self.aeroTorque
        ratedPower = self.ratedPower

        if drivetrainType == 'geared':
            constant = 0.01289
            linear = 0.08510
            quadratic = 0.0

        elif drivetrainType == 'single_stage':
            constant = 0.01331
            linear = 0.03655
            quadratic = 0.06107

        elif drivetrainType == 'multi_drive':
            constant = 0.01547
            linear = 0.04463
            quadratic = 0.05790

        elif drivetrainType == 'pm_direct_drive':
            constant = 0.01007
            linear = 0.02000
            quadratic = 0.06899

        Pbar0 = aeroPower / ratedPower

        # handle negative power case (with absolute value)
        Pbar1, dPbar1_dPbar0 = smooth_abs(Pbar0, dx=0.01)

        # truncate idealized power curve for purposes of efficiency calculation
        Pbar, dPbar_dPbar1, _ = smooth_min(Pbar1, 1.0, pct_offset=0.01)

        # compute efficiency
        eff = 1.0 - (constant / Pbar + linear + quadratic * Pbar)

        self.power = aeroPower * eff

        # gradients
        dPbar_dPa = dPbar_dPbar1 * dPbar1_dPbar0 / ratedPower
        dPbar_dPr = -dPbar_dPbar1 * dPbar1_dPbar0 * aeroPower / ratedPower**2

        deff_dPa = dPbar_dPa * (constant / Pbar**2 - quadratic)
        deff_dPr = dPbar_dPr * (constant / Pbar**2 - quadratic)

        dP_dPa = eff + aeroPower * deff_dPa
        dP_dPr = aeroPower * deff_dPr

        self.J = hstack([np.diag(dP_dPa), dP_dPr])
Exemple #14
0
    def provideJ(self):

        if self.run_case == 'power':

            dP = self.dP
            dT = self.dT
            dQ = self.dQ

            jP = hstack([dP['dprecone'], dP['dtilt'], dP['dhubHt'], dP['dRhub'], dP['dRtip'],
                dP['dyaw'], dP['dUinf'], dP['dOmega'], dP['dpitch'], dP['dr'], dP['dchord'], dP['dtheta'],
                dP['dprecurve'], dP['dprecurveTip']])
            jT = hstack([dT['dprecone'], dT['dtilt'], dT['dhubHt'], dT['dRhub'], dT['dRtip'],
                dT['dyaw'], dT['dUinf'], dT['dOmega'], dT['dpitch'], dT['dr'], dT['dchord'], dT['dtheta'],
                dT['dprecurve'], dT['dprecurveTip']])
            jQ = hstack([dQ['dprecone'], dQ['dtilt'], dQ['dhubHt'], dQ['dRhub'], dQ['dRtip'],
                dQ['dyaw'], dQ['dUinf'], dQ['dOmega'], dQ['dpitch'], dQ['dr'], dQ['dchord'], dQ['dtheta'],
                dQ['dprecurve'], dQ['dprecurveTip']])

            J = vstack([jP, jT, jQ])


        elif self.run_case == 'loads':

            dNp = self.dNp
            dTp = self.dTp
            n = len(self.r)

            dr_dr = vstack([np.zeros(n), np.eye(n), np.zeros(n)])
            dr_dRhub = np.zeros(n+2)
            dr_dRtip = np.zeros(n+2)
            dr_dRhub[0] = 1.0
            dr_dRtip[-1] = 1.0
            dr = hstack([dr_dr, np.zeros((n+2, 2*n)), dr_dRhub, dr_dRtip, np.zeros((n+2, 8+n))])

            jNp = hstack([dNp['dr'], dNp['dchord'], dNp['dtheta'], dNp['dRhub'], dNp['dRtip'],
                dNp['dhubHt'], dNp['dprecone'], dNp['dtilt'], dNp['dyaw'], dNp['dUinf'],
                dNp['dOmega'], dNp['dpitch'], dNp['dazimuth'], dNp['dprecurve']])
            jTp = hstack([dTp['dr'], dTp['dchord'], dTp['dtheta'], dTp['dRhub'], dTp['dRtip'],
                dTp['dhubHt'], dTp['dprecone'], dTp['dtilt'], dTp['dyaw'], dTp['dUinf'],
                dTp['dOmega'], dTp['dpitch'], dTp['dazimuth'], dTp['dprecurve']])
            dPx = vstack([np.zeros(4*n+10), jNp, np.zeros(4*n+10)])
            dPy = vstack([np.zeros(4*n+10), -jTp, np.zeros(4*n+10)])
            dPz = np.zeros((n+2, 4*n+10))

            dV = np.zeros(4*n+10)
            dV[3*n+6] = 1.0
            dOmega = np.zeros(4*n+10)
            dOmega[3*n+7] = 1.0
            dpitch = np.zeros(4*n+10)
            dpitch[3*n+8] = 1.0
            dazimuth = np.zeros(4*n+10)
            dazimuth[3*n+9] = 1.0

            J = vstack([dr, dPx, dPy, dPz, dV, dOmega, dpitch, dazimuth])


        return J
Exemple #15
0
    def provideJ(self):

        # mass
        dmass = np.hstack([np.array([1.0, 1.0, 1.0]), np.zeros(2 * 3 + 3 * 6)])

        # cm
        top = (self.rotor_mass * self.hub_cm + self.nac_mass * self.nac_cm)
        dcm_dblademass = (self.rna_mass * self.hub_cm - top) / self.rna_mass**2
        dcm_dhubmass = (self.rna_mass * self.hub_cm - top) / self.rna_mass**2
        dcm_dnacmass = (self.rna_mass * self.nac_cm - top) / self.rna_mass**2
        dcm_dhubcm = self.rotor_mass / self.rna_mass * np.eye(3)
        dcm_dnaccm = self.nac_mass / self.rna_mass * np.eye(3)

        dcm = hstack([
            dcm_dblademass, dcm_dhubmass, dcm_dnacmass, dcm_dhubcm, dcm_dnaccm,
            np.zeros((3, 3 * 6))
        ])

        # I
        R = self.hub_cm
        const = self._unassembleI(np.dot(R, R) * np.eye(3) - np.outer(R, R))
        dI_dblademass = const
        dI_dhubmass = const
        dI_drx = self.rotor_mass * self._unassembleI(
            2 * R[0] * np.eye(3) -
            np.array([[2 *
                       R[0], R[1], R[2]], [R[1], 0.0, 0.0], [R[2], 0.0, 0.0]]))
        dI_dry = self.rotor_mass * self._unassembleI(
            2 * R[1] * np.eye(3) -
            np.array([[0.0, R[0], 0.0], [R[0], 2 *
                                         R[1], R[2]], [0.0, R[2], 0.0]]))
        dI_drz = self.rotor_mass * self._unassembleI(
            2 * R[2] * np.eye(3) - np.array(
                [[0.0, 0.0, R[0]], [0.0, 0.0, R[1]], [R[0], R[1], 2 * R[2]]]))
        dI_dhubcm = np.vstack([dI_drx, dI_dry, dI_drz]).T

        R = self.nac_cm
        const = self._unassembleI(np.dot(R, R) * np.eye(3) - np.outer(R, R))
        dI_dnacmass = const
        dI_drx = self.nac_mass * self._unassembleI(
            2 * R[0] * np.eye(3) -
            np.array([[2 *
                       R[0], R[1], R[2]], [R[1], 0.0, 0.0], [R[2], 0.0, 0.0]]))
        dI_dry = self.nac_mass * self._unassembleI(
            2 * R[1] * np.eye(3) -
            np.array([[0.0, R[0], 0.0], [R[0], 2 *
                                         R[1], R[2]], [0.0, R[2], 0.0]]))
        dI_drz = self.nac_mass * self._unassembleI(
            2 * R[2] * np.eye(3) - np.array(
                [[0.0, 0.0, R[0]], [0.0, 0.0, R[1]], [R[0], R[1], 2 * R[2]]]))
        dI_dnaccm = np.vstack([dI_drx, dI_dry, dI_drz]).T

        dI_dbladeI = np.eye(6)
        dI_dhubI = np.eye(6)
        dI_dnacI = np.eye(6)

        dI = hstack([
            dI_dblademass, dI_dhubmass, dI_dnacmass, dI_dhubcm, dI_dnaccm,
            dI_dbladeI, dI_dhubI, dI_dnacI
        ])

        J = np.vstack([dmass, dcm, dI])

        return J
Exemple #16
0
    def execute(self):

        nc = len(self.chord_sub)
        nt = len(self.theta_sub)
        Rhub = self.Rhub
        Rtip = self.Rtip
        idxc = self.idx_cylinder
        r_max_chord = Rhub + (Rtip-Rhub)*self.r_max_chord
        r_cylinder = Rhub + (Rtip-Rhub)*self.r_af[idxc]

        # chord parameterization
        rc_outer, drc_drcmax, drc_drtip = linspace_with_deriv(r_max_chord, Rtip, nc-1)
        r_chord = np.concatenate([[Rhub], rc_outer])
        drc_drcmax = np.concatenate([[0.0], drc_drcmax])
        drc_drtip = np.concatenate([[0.0], drc_drtip])
        drc_drhub = np.concatenate([[1.0], np.zeros(nc-1)])

        # theta parameterization
        r_theta, drt_drcyl, drt_drtip = linspace_with_deriv(r_cylinder, Rtip, nt)

        # spline
        chord_spline = Akima(r_chord, self.chord_sub)
        theta_spline = Akima(r_theta, self.theta_sub)

        self.r = Rhub + (Rtip-Rhub)*self.r_af
        self.chord, dchord_dr, dchord_drchord, dchord_dchordsub = chord_spline.interp(self.r)
        theta_outer, dthetaouter_dr, dthetaouter_drtheta, dthetaouter_dthetasub = theta_spline.interp(self.r[idxc:])

        theta_inner = theta_outer[0] * np.ones(idxc)
        self.theta = np.concatenate([theta_inner, theta_outer])

        self.r_af_spacing = np.diff(self.r_af)

        self.precurve = np.zeros_like(self.chord)  # TODO: for now I'm forcing this to zero, just for backwards compatibility

        # gradients (TODO: rethink these a bit or use Tapenade.)
        n = len(self.r_af)
        dr_draf = (Rtip-Rhub)*np.ones(n)
        dr_dRhub = 1.0 - self.r_af
        dr_dRtip = self.r_af
        dr = hstack([np.diag(dr_draf), np.zeros((n, 1)), dr_dRhub, dr_dRtip, np.zeros((n, nc+nt))])

        dchord_draf = dchord_dr * dr_draf
        dchord_drmaxchord0 = np.dot(dchord_drchord, drc_drcmax)
        dchord_drmaxchord = dchord_drmaxchord0 * (Rtip-Rhub)
        dchord_drhub = np.dot(dchord_drchord, drc_drhub) + dchord_drmaxchord0*(1.0 - self.r_max_chord) + dchord_dr*dr_dRhub
        dchord_drtip = np.dot(dchord_drchord, drc_drtip) + dchord_drmaxchord0*(self.r_max_chord) + dchord_dr*dr_dRtip
        dchord = hstack([np.diag(dchord_draf), dchord_drmaxchord, dchord_drhub, dchord_drtip, dchord_dchordsub, np.zeros((n, nt))])

        dthetaouter_dcyl = np.dot(dthetaouter_drtheta, drt_drcyl)
        dthetaouter_draf = dthetaouter_dr*dr_draf[idxc:]
        dthetaouter_drhub = dthetaouter_dr*dr_dRhub[idxc:]
        dthetaouter_drtip = dthetaouter_dr*dr_dRtip[idxc:] + np.dot(dthetaouter_drtheta, drt_drtip)

        dtheta_draf = np.concatenate([np.zeros(idxc), dthetaouter_draf])
        dtheta_drhub = np.concatenate([dthetaouter_drhub[0]*np.ones(idxc), dthetaouter_drhub])
        dtheta_drtip = np.concatenate([dthetaouter_drtip[0]*np.ones(idxc), dthetaouter_drtip])
        sub = dthetaouter_dthetasub[0, :]
        dtheta_dthetasub = vstack([np.dot(np.ones((idxc, 1)), sub[np.newaxis, :]), dthetaouter_dthetasub])

        dtheta_draf = np.diag(dtheta_draf)
        dtheta_dcyl = np.concatenate([dthetaouter_dcyl[0]*np.ones(idxc), dthetaouter_dcyl])
        dtheta_draf[idxc:, idxc] += dthetaouter_dcyl*(Rtip-Rhub)
        dtheta_drhub += dtheta_dcyl*(1.0 - self.r_af[idxc])
        dtheta_drtip += dtheta_dcyl*self.r_af[idxc]

        dtheta = hstack([dtheta_draf, np.zeros((n, 1)), dtheta_drhub, dtheta_drtip, np.zeros((n, nc)), dtheta_dthetasub])

        drafs_dr = np.zeros((n-1, n))
        for i in range(n-1):
            drafs_dr[i, i] = -1.0
            drafs_dr[i, i+1] = 1.0
        drafs = hstack([drafs_dr, np.zeros((n-1, 3+nc+nt))])

        dprecurve = np.zeros((len(self.precurve), n+3+nc+nt))

        self.J = vstack([dr, dchord, dtheta, drafs, dprecurve])
Exemple #17
0
    def provideJ(self):

        dbyx = self.blade_yaw.dx
        # dbyy = self.blade_yaw.dy
        dbyz = self.blade_yaw.dz

        # Rtip
        drtower_dRtip = self.drtower_dztower * dbyz['dz'] / self.towerHt
        if self.precone >= 0:
            dtd_dRtip = -dbyx['dz'] - drtower_dRtip
        else:
            dtd_dRtip = dbyx['dz'] - drtower_dRtip
        dgc_dRtip = dbyz['dz']

        # precurveTip
        drtower_dprecurveTip = self.drtower_dztower * dbyz['dx'] / self.towerHt
        if self.precone >= 0:
            dtd_dprecurveTip = -dbyx['dx'] - drtower_dprecurveTip
        else:
            dtd_dprecurveTip = dbyx['dx'] - drtower_dprecurveTip
        dgc_dprecurveTip = dbyz['dx']

        # presweep
        drtower_dpresweepTip = self.drtower_dztower * dbyz['dy'] / self.towerHt
        if self.precone >= 0:
            dtd_dpresweepTip = -dbyx['dy'] - drtower_dpresweepTip
        else:
            dtd_dpresweepTip = dbyx['dy'] - drtower_dpresweepTip
        dgc_dpresweepTip = dbyz['dy']

        # precone
        drtower_dprecone = self.drtower_dztower * dbyz[
            'dprecone'] / self.towerHt
        if self.precone >= 0:
            dtd_dprecone = -dbyx['dprecone'] - drtower_dprecone
        else:
            dtd_dprecone = dbyx['dprecone'] - drtower_dprecone
        dgc_dprecone = dbyz['dprecone']

        # tilt
        drtower_dtilt = self.drtower_dztower * dbyz['dtilt'] / self.towerHt
        if self.precone >= 0:
            dtd_dtilt = -dbyx['dtilt'] - drtower_dtilt
        else:
            dtd_dtilt = dbyx['dtilt'] - drtower_dtilt
        dgc_dtilt = dbyz['dtilt']

        # hubtt
        drtower_dhubtt = self.drtower_dztower * np.array(
            [0.0, 0.0, 1.0 / self.towerHt])
        dtd_dhubtt = np.array([-1.0, 0.0, 0.0]) - drtower_dhubtt
        dgc_dhubtt = np.array([0.0, 0.0, 1.0])

        # tower_z
        dtd_dtowerz = -self.drtower_dtowerz
        dgc_dtowerz = np.zeros_like(self.tower_z)

        # tower_d
        dtd_dtowerd = -self.drtower_dtowerd
        dgc_dtowerd = np.zeros_like(self.tower_d)

        # towerHt
        drtower_dtowerHt = self.drtower_dztower * -(
            self.hub_tt[2] + self.blade_yaw.z) / self.towerHt**2
        dtd_dtowerHt = -drtower_dtowerHt
        dgc_dtowerHt = 1.0

        dtd = hstack([
            dtd_dRtip, dtd_dprecurveTip, dtd_dpresweepTip, dtd_dprecone,
            dtd_dtilt, dtd_dhubtt, dtd_dtowerz, dtd_dtowerd, dtd_dtowerHt
        ])
        dgc = np.concatenate([[dgc_dRtip], [dgc_dprecurveTip],
                              [dgc_dpresweepTip], [dgc_dprecone], [dgc_dtilt],
                              dgc_dhubtt, dgc_dtowerz, dgc_dtowerd,
                              [dgc_dtowerHt]])

        J = vstack([dtd, dgc])

        return J
Exemple #18
0
    def provideJ(self):

        dbyx = self.blade_yaw.dx
        # dbyy = self.blade_yaw.dy
        dbyz = self.blade_yaw.dz

        # Rtip
        drtower_dRtip = self.drtower_dztower * dbyz['dz']/self.towerHt
        if self.precone >= 0:
            dtd_dRtip = -dbyx['dz'] - drtower_dRtip
        else:
            dtd_dRtip = dbyx['dz'] - drtower_dRtip
        dgc_dRtip = dbyz['dz']

        # precurveTip
        drtower_dprecurveTip = self.drtower_dztower * dbyz['dx']/self.towerHt
        if self.precone >= 0:
            dtd_dprecurveTip = -dbyx['dx'] - drtower_dprecurveTip
        else:
            dtd_dprecurveTip = dbyx['dx'] - drtower_dprecurveTip
        dgc_dprecurveTip = dbyz['dx']

        # presweep
        drtower_dpresweepTip = self.drtower_dztower * dbyz['dy']/self.towerHt
        if self.precone >= 0:
            dtd_dpresweepTip = -dbyx['dy'] - drtower_dpresweepTip
        else:
            dtd_dpresweepTip = dbyx['dy'] - drtower_dpresweepTip
        dgc_dpresweepTip = dbyz['dy']


        # precone
        drtower_dprecone = self.drtower_dztower * dbyz['dprecone']/self.towerHt
        if self.precone >= 0:
            dtd_dprecone = -dbyx['dprecone'] - drtower_dprecone
        else:
            dtd_dprecone = dbyx['dprecone'] - drtower_dprecone
        dgc_dprecone = dbyz['dprecone']

        # tilt
        drtower_dtilt = self.drtower_dztower * dbyz['dtilt']/self.towerHt
        if self.precone >= 0:
            dtd_dtilt = -dbyx['dtilt'] - drtower_dtilt
        else:
            dtd_dtilt = dbyx['dtilt'] - drtower_dtilt
        dgc_dtilt = dbyz['dtilt']

        # hubtt
        drtower_dhubtt = self.drtower_dztower * np.array([0.0, 0.0, 1.0/self.towerHt])
        dtd_dhubtt = np.array([-1.0, 0.0, 0.0]) - drtower_dhubtt
        dgc_dhubtt = np.array([0.0, 0.0, 1.0])

        # tower_z
        dtd_dtowerz = -self.drtower_dtowerz
        dgc_dtowerz = np.zeros_like(self.tower_z)

        # tower_d
        dtd_dtowerd = -self.drtower_dtowerd
        dgc_dtowerd = np.zeros_like(self.tower_d)

        # towerHt
        drtower_dtowerHt = self.drtower_dztower * -(self.hub_tt[2] + self.blade_yaw.z)/self.towerHt**2
        dtd_dtowerHt = -drtower_dtowerHt
        dgc_dtowerHt = 1.0

        dtd = hstack([dtd_dRtip, dtd_dprecurveTip, dtd_dpresweepTip, dtd_dprecone, dtd_dtilt,
            dtd_dhubtt, dtd_dtowerz, dtd_dtowerd, dtd_dtowerHt])
        dgc = np.concatenate([[dgc_dRtip], [dgc_dprecurveTip], [dgc_dpresweepTip], [dgc_dprecone],
            [dgc_dtilt], dgc_dhubtt, dgc_dtowerz, dgc_dtowerd, [dgc_dtowerHt]])

        J = vstack([dtd, dgc])

        return J
Exemple #19
0
    def evaluate(self):

        ctrl = self.control
        n = self.npts
        Vrated = self.Vrated

        # residual
        spline = Akima(self.Vcoarse, self.Pcoarse)
        P, dres_dVrated, dres_dVcoarse, dres_dPcoarse = spline.interp(Vrated)
        self.residual = P - ctrl.ratedPower

        # functional

        # place half of points in region 2, half in region 3
        # even though region 3 is constant we still need lots of points there
        # because we will be integrating against a discretized wind
        # speed distribution

        # region 2
        V2, _, dV2_dVrated = linspace_with_deriv(ctrl.Vin, Vrated, n/2)
        P2, dP2_dV2, dP2_dVcoarse, dP2_dPcoarse = spline.interp(V2)

        # region 3
        V3, dV3_dVrated, _ = linspace_with_deriv(Vrated, ctrl.Vout, n/2+1)
        V3 = V3[1:]  # remove duplicate point
        dV3_dVrated = dV3_dVrated[1:]
        P3 = ctrl.ratedPower*np.ones_like(V3)

        # concatenate
        self.V = np.concatenate([V2, V3])
        self.P = np.concatenate([P2, P3])

        # rated speed conditions
        Omega_d = ctrl.tsr*Vrated/self.R*RS2RPM
        OmegaRated, dOmegaRated_dOmegad, dOmegaRated_dmaxOmega \
            = smooth_min(Omega_d, ctrl.maxOmega, pct_offset=0.01)

        splineT = Akima(self.Vcoarse, self.Tcoarse)
        Trated, dT_dVrated, dT_dVcoarse, dT_dTcoarse = splineT.interp(Vrated)

        self.ratedConditions.V = Vrated
        self.ratedConditions.Omega = OmegaRated
        self.ratedConditions.pitch = ctrl.pitch
        self.ratedConditions.T = Trated
        self.ratedConditions.Q = ctrl.ratedPower / (self.ratedConditions.Omega * RPM2RS)


        # gradients
        ncoarse = len(self.Vcoarse)

        dres = np.concatenate([[0.0], dres_dVcoarse, dres_dPcoarse, np.zeros(ncoarse), np.array([dres_dVrated]), [0.0, 0.0]])

        dV_dVrated = np.concatenate([dV2_dVrated, dV3_dVrated])
        dV = hstack([np.zeros((n, 1)), np.zeros((n, 3*ncoarse)), dV_dVrated, np.zeros((n, 2))])

        dP_dVcoarse = vstack([dP2_dVcoarse, np.zeros((n/2, ncoarse))])
        dP_dPcoarse = vstack([dP2_dPcoarse, np.zeros((n/2, ncoarse))])
        dP_dVrated = np.concatenate([dP2_dV2*dV2_dVrated, np.zeros(n/2)])
        dP = hstack([np.zeros((n, 1)), dP_dVcoarse, dP_dPcoarse, np.zeros((n, ncoarse)), dP_dVrated, np.zeros((n, 2))])

        drV = np.concatenate([[0.0], np.zeros(3*ncoarse), [1.0, 0.0, 0.0]])
        drOmega = np.concatenate([[dOmegaRated_dOmegad*Vrated/self.R*RS2RPM], np.zeros(3*ncoarse),
            [dOmegaRated_dOmegad*ctrl.tsr/self.R*RS2RPM, -dOmegaRated_dOmegad*ctrl.tsr*Vrated/self.R**2*RS2RPM,
            dOmegaRated_dmaxOmega]])
        drpitch = np.zeros(3*ncoarse+4)
        drT = np.concatenate([[0.0], dT_dVcoarse, np.zeros(ncoarse), dT_dTcoarse, [dT_dVrated, 0.0, 0.0]])
        drQ = -ctrl.ratedPower / (self.ratedConditions.Omega**2 * RPM2RS) * drOmega

        self.J = vstack([dres, dV, dP, drV, drOmega, drpitch, drT, drQ])
Exemple #20
0
    def provideJ(self):

        if self.run_case == 'power':

            dP = self.dP
            dT = self.dT
            dQ = self.dQ

            jP = hstack([
                dP['dprecone'], dP['dtilt'], dP['dhubHt'], dP['dRhub'],
                dP['dRtip'], dP['dyaw'], dP['dUinf'], dP['dOmega'],
                dP['dpitch'], dP['dr'], dP['dchord'], dP['dtheta'],
                dP['dprecurve'], dP['dprecurveTip']
            ])
            jT = hstack([
                dT['dprecone'], dT['dtilt'], dT['dhubHt'], dT['dRhub'],
                dT['dRtip'], dT['dyaw'], dT['dUinf'], dT['dOmega'],
                dT['dpitch'], dT['dr'], dT['dchord'], dT['dtheta'],
                dT['dprecurve'], dT['dprecurveTip']
            ])
            jQ = hstack([
                dQ['dprecone'], dQ['dtilt'], dQ['dhubHt'], dQ['dRhub'],
                dQ['dRtip'], dQ['dyaw'], dQ['dUinf'], dQ['dOmega'],
                dQ['dpitch'], dQ['dr'], dQ['dchord'], dQ['dtheta'],
                dQ['dprecurve'], dQ['dprecurveTip']
            ])

            J = vstack([jP, jT, jQ])

        elif self.run_case == 'loads':

            dNp = self.dNp
            dTp = self.dTp
            n = len(self.r)

            dr_dr = vstack([np.zeros(n), np.eye(n), np.zeros(n)])
            dr_dRhub = np.zeros(n + 2)
            dr_dRtip = np.zeros(n + 2)
            dr_dRhub[0] = 1.0
            dr_dRtip[-1] = 1.0
            dr = hstack([
                dr_dr,
                np.zeros((n + 2, 2 * n)), dr_dRhub, dr_dRtip,
                np.zeros((n + 2, 8 + n))
            ])

            jNp = hstack([
                dNp['dr'], dNp['dchord'], dNp['dtheta'], dNp['dRhub'],
                dNp['dRtip'], dNp['dhubHt'], dNp['dprecone'], dNp['dtilt'],
                dNp['dyaw'], dNp['dUinf'], dNp['dOmega'], dNp['dpitch'],
                dNp['dazimuth'], dNp['dprecurve']
            ])
            jTp = hstack([
                dTp['dr'], dTp['dchord'], dTp['dtheta'], dTp['dRhub'],
                dTp['dRtip'], dTp['dhubHt'], dTp['dprecone'], dTp['dtilt'],
                dTp['dyaw'], dTp['dUinf'], dTp['dOmega'], dTp['dpitch'],
                dTp['dazimuth'], dTp['dprecurve']
            ])
            dPx = vstack([np.zeros(4 * n + 10), jNp, np.zeros(4 * n + 10)])
            dPy = vstack([np.zeros(4 * n + 10), -jTp, np.zeros(4 * n + 10)])
            dPz = np.zeros((n + 2, 4 * n + 10))

            dV = np.zeros(4 * n + 10)
            dV[3 * n + 6] = 1.0
            dOmega = np.zeros(4 * n + 10)
            dOmega[3 * n + 7] = 1.0
            dpitch = np.zeros(4 * n + 10)
            dpitch[3 * n + 8] = 1.0
            dazimuth = np.zeros(4 * n + 10)
            dazimuth[3 * n + 9] = 1.0

            J = vstack([dr, dPx, dPy, dPz, dV, dOmega, dpitch, dazimuth])

        return J
Exemple #21
0
    def linearize(self, params, unknowns, resids):

        dF = DirectionVector.fromArray(params['F']).hubToYaw(params['tilt'])
        dFx, dFy, dFz = dF.dx, dF.dy, dF.dz

        dtopF_dFx = np.array([dFx['dx'], dFy['dx'], dFz['dx']])
        dtopF_dFy = np.array([dFx['dy'], dFy['dy'], dFz['dy']])
        dtopF_dFz = np.array([dFx['dz'], dFy['dz'], dFz['dz']])
        dtopF_dF = hstack([dtopF_dFx, dtopF_dFy, dtopF_dFz])
        dtopF_w_dm = np.array([0.0, 0.0, -self.g])

        #dtopF = hstack([dtopF_dF, np.zeros((3, 6)), dtopF_w_dm, np.zeros((3, 3))])

        dM = DirectionVector.fromArray(params['M']).hubToYaw(params['tilt'])
        dMx, dMy, dMz = dM.dx, dM.dy, dM.dz
        dMxcross, dMycross, dMzcross = self.save_rhub.cross_deriv(
            self.saveF, 'dr', 'dF')

        dtopM_dMx = np.array([dMx['dx'], dMy['dx'], dMz['dx']])
        dtopM_dMy = np.array([dMx['dy'], dMy['dy'], dMz['dy']])
        dtopM_dMz = np.array([dMx['dz'], dMy['dz'], dMz['dz']])
        dtopM_dM = hstack([dtopM_dMx, dtopM_dMy, dtopM_dMz])
        dM_dF = np.array([dMxcross['dF'], dMycross['dF'], dMzcross['dF']])

        dtopM_dFx = np.dot(dM_dF, dtopF_dFx)
        dtopM_dFy = np.dot(dM_dF, dtopF_dFy)
        dtopM_dFz = np.dot(dM_dF, dtopF_dFz)
        dtopM_dF = hstack([dtopM_dFx, dtopM_dFy, dtopM_dFz])
        dtopM_dr = np.array([dMxcross['dr'], dMycross['dr'], dMzcross['dr']])

        dMx_w_cross, dMy_w_cross, dMz_w_cross = self.save_rcm.cross_deriv(
            self.saveF_w, 'dr', 'dF')

        if params['rna_weightM']:
            dtopM_drnacm = np.array(
                [dMx_w_cross['dr'], dMy_w_cross['dr'], dMz_w_cross['dr']])
            dtopM_dF_w = np.array(
                [dMx_w_cross['dF'], dMy_w_cross['dF'], dMz_w_cross['dF']])
        else:
            dtopM_drnacm = np.zeros((3, 3))
            dtopM_dF_w = np.zeros((3, 3))
        dtopM_dm = np.dot(dtopM_dF_w, dtopF_w_dm)

        if params['downwind']:
            dtopM_dr[:, 0] *= -1
            dtopM_drnacm[:, 0] *= -1

        #dtopM = hstack([dtopM_dF, dtopM_dM, dtopM_dr, dtopM_dm, dtopM_drnacm])

        J = {}
        J['top_F', 'F'] = dtopF_dF
        J['top_F', 'M'] = np.zeros((3, 3))
        J['top_F', 'r_hub'] = np.zeros((3, 3))
        J['top_F', 'rna_mass'] = dtopF_w_dm
        J['top_F', 'rna_cm'] = np.zeros((3, 3))

        J['top_M', 'F'] = dtopM_dF
        J['top_M', 'M'] = dtopM_dM
        J['top_M', 'r_hub'] = dtopM_dr
        J['top_M', 'rna_mass'] = dtopM_dm
        J['top_M', 'rna_cm'] = dtopM_drnacm

        return J
Exemple #22
0
    def execute(self):

        nc = len(self.chord_sub)
        nt = len(self.theta_sub)
        Rhub = self.Rhub
        Rtip = self.Rtip
        idxc = self.idx_cylinder
        r_max_chord = Rhub + (Rtip - Rhub) * self.r_max_chord
        r_cylinder = Rhub + (Rtip - Rhub) * self.r_af[idxc]

        # chord parameterization
        rc_outer, drc_drcmax, drc_drtip = linspace_with_deriv(
            r_max_chord, Rtip, nc - 1)
        r_chord = np.concatenate([[Rhub], rc_outer])
        drc_drcmax = np.concatenate([[0.0], drc_drcmax])
        drc_drtip = np.concatenate([[0.0], drc_drtip])
        drc_drhub = np.concatenate([[1.0], np.zeros(nc - 1)])

        # theta parameterization
        r_theta, drt_drcyl, drt_drtip = linspace_with_deriv(
            r_cylinder, Rtip, nt)

        # spline
        chord_spline = Akima(r_chord, self.chord_sub)
        theta_spline = Akima(r_theta, self.theta_sub)

        self.r = Rhub + (Rtip - Rhub) * self.r_af
        self.chord, dchord_dr, dchord_drchord, dchord_dchordsub = chord_spline.interp(
            self.r)
        theta_outer, dthetaouter_dr, dthetaouter_drtheta, dthetaouter_dthetasub = theta_spline.interp(
            self.r[idxc:])

        theta_inner = theta_outer[0] * np.ones(idxc)
        self.theta = np.concatenate([theta_inner, theta_outer])

        self.r_af_spacing = np.diff(self.r_af)

        self.precurve = np.zeros_like(
            self.chord
        )  # TODO: for now I'm forcing this to zero, just for backwards compatibility

        # gradients (TODO: rethink these a bit or use Tapenade.)
        n = len(self.r_af)
        dr_draf = (Rtip - Rhub) * np.ones(n)
        dr_dRhub = 1.0 - self.r_af
        dr_dRtip = self.r_af
        dr = hstack([
            np.diag(dr_draf),
            np.zeros((n, 1)), dr_dRhub, dr_dRtip,
            np.zeros((n, nc + nt))
        ])

        dchord_draf = dchord_dr * dr_draf
        dchord_drmaxchord0 = np.dot(dchord_drchord, drc_drcmax)
        dchord_drmaxchord = dchord_drmaxchord0 * (Rtip - Rhub)
        dchord_drhub = np.dot(
            dchord_drchord, drc_drhub) + dchord_drmaxchord0 * (
                1.0 - self.r_max_chord) + dchord_dr * dr_dRhub
        dchord_drtip = np.dot(dchord_drchord,
                              drc_drtip) + dchord_drmaxchord0 * (
                                  self.r_max_chord) + dchord_dr * dr_dRtip
        dchord = hstack([
            np.diag(dchord_draf), dchord_drmaxchord, dchord_drhub,
            dchord_drtip, dchord_dchordsub,
            np.zeros((n, nt))
        ])

        dthetaouter_dcyl = np.dot(dthetaouter_drtheta, drt_drcyl)
        dthetaouter_draf = dthetaouter_dr * dr_draf[idxc:]
        dthetaouter_drhub = dthetaouter_dr * dr_dRhub[idxc:]
        dthetaouter_drtip = dthetaouter_dr * dr_dRtip[idxc:] + np.dot(
            dthetaouter_drtheta, drt_drtip)

        dtheta_draf = np.concatenate([np.zeros(idxc), dthetaouter_draf])
        dtheta_drhub = np.concatenate(
            [dthetaouter_drhub[0] * np.ones(idxc), dthetaouter_drhub])
        dtheta_drtip = np.concatenate(
            [dthetaouter_drtip[0] * np.ones(idxc), dthetaouter_drtip])
        sub = dthetaouter_dthetasub[0, :]
        dtheta_dthetasub = vstack([
            np.dot(np.ones((idxc, 1)), sub[np.newaxis, :]),
            dthetaouter_dthetasub
        ])

        dtheta_draf = np.diag(dtheta_draf)
        dtheta_dcyl = np.concatenate(
            [dthetaouter_dcyl[0] * np.ones(idxc), dthetaouter_dcyl])
        dtheta_draf[idxc:, idxc] += dthetaouter_dcyl * (Rtip - Rhub)
        dtheta_drhub += dtheta_dcyl * (1.0 - self.r_af[idxc])
        dtheta_drtip += dtheta_dcyl * self.r_af[idxc]

        dtheta = hstack([
            dtheta_draf,
            np.zeros((n, 1)), dtheta_drhub, dtheta_drtip,
            np.zeros((n, nc)), dtheta_dthetasub
        ])

        drafs_dr = np.zeros((n - 1, n))
        for i in range(n - 1):
            drafs_dr[i, i] = -1.0
            drafs_dr[i, i + 1] = 1.0
        drafs = hstack([drafs_dr, np.zeros((n - 1, 3 + nc + nt))])

        dprecurve = np.zeros((len(self.precurve), n + 3 + nc + nt))

        self.J = vstack([dr, dchord, dtheta, drafs, dprecurve])