示例#1
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])
示例#2
0
    def solve_nonlinear(self, params, unknowns, resids):

        n = params['npts']

        # finer power curve
        V, _, _ = linspace_with_deriv(params['control:Vin'],
                                      params['control:Vout'], n)
        unknowns['V'] = V
        spline = Akima(params['Vcoarse'], params['Pcoarse'])
        P, dP_dV, dP_dVcoarse, dP_dPcoarse = spline.interp(unknowns['V'])
        unknowns['P'] = P

        J = {}
        J['P', 'Vcoarse'] = dP_dVcoarse
        J['P', 'Pcoarse'] = dP_dPcoarse
        self.J = J
示例#3
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])
示例#4
0
    def apply_nonlinear(self, params, unknowns, resids):
        n = params['npts']
        Vrated = unknowns['Vrated']
        # residual
        spline = Akima(params['Vcoarse'], params['Pcoarse'])
        P, dres_dVrated, dres_dVcoarse, dres_dPcoarse = spline.interp(Vrated)

        resids['Vrated'] = P - params['control:ratedPower']

        if True:
            P1, _, _, _ = spline.interp(params['control:Vin'])
            P2, _, _, _ = spline.interp(params['control:Vout'])
            resids1 = P1 - params['control:ratedPower']
            resids2 = P2 - params['control:ratedPower']
            if ((resids1 < 0) == (resids2 < 0)):
                if Vrated == params['control:Vout']:
                    resids['Vrated'] = 10000
                elif Vrated != params['control:Vin']:
                    resids['Vrated'] = 0

        ## Test on

        # region 2
        V2, _, dV2_dVrated = linspace_with_deriv(params['control:Vin'], Vrated,
                                                 n / 2)
        P2, dP2_dV2, dP2_dVcoarse, dP2_dPcoarse = spline.interp(V2)

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

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

        R = params['R']
        # rated speed conditions
        Omega_d = params['control:tsr'] * Vrated / R * RS2RPM
        OmegaRated, dOmegaRated_dOmegad, dOmegaRated_dmaxOmega \
            = smooth_min(Omega_d, params['control:maxOmega'], pct_offset=0.01)

        splineT = Akima(params['Vcoarse'], params['Tcoarse'])
        Trated, dT_dVrated, dT_dVcoarse, dT_dTcoarse = splineT.interp(Vrated)

        unknowns['ratedConditions:V'] = Vrated
        unknowns['ratedConditions:Omega'] = OmegaRated
        unknowns['ratedConditions:pitch'] = params['control:pitch']
        unknowns['ratedConditions:T'] = Trated
        unknowns['ratedConditions:Q'] = params['control:ratedPower'] / (
            OmegaRated * RPM2RS)
        unknowns['azimuth'] = 180.0

        # gradients
        ncoarse = len(params['Vcoarse'])

        dV_dVrated = np.concatenate([dV2_dVrated, dV3_dVrated])

        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)])

        drOmega = np.concatenate(
            [[dOmegaRated_dOmegad * Vrated / R * RS2RPM],
             np.zeros(3 * ncoarse),
             [
                 dOmegaRated_dOmegad * params['control:tsr'] / R * RS2RPM,
                 -dOmegaRated_dOmegad * params['control:tsr'] * Vrated / R**2 *
                 RS2RPM, dOmegaRated_dmaxOmega
             ]])
        drQ = -params['control:ratedPower'] / (OmegaRated**2 *
                                               RPM2RS) * drOmega

        J = {}
        J['Vrated', 'Vcoarse'] = np.reshape(dres_dVcoarse,
                                            (1, len(dres_dVcoarse)))
        J['Vrated', 'Pcoarse'] = np.reshape(dres_dPcoarse,
                                            (1, len(dres_dPcoarse)))
        J['Vrated', 'Vrated'] = dres_dVrated

        J['V', 'Vrated'] = dV_dVrated
        J['P', 'Vrated'] = dP_dVrated
        J['P', 'Vcoarse'] = dP_dVcoarse
        J['P', 'Pcoarse'] = dP_dPcoarse
        J['ratedConditions:V', 'Vrated'] = 1.0
        J['ratedConditions:Omega',
          'control:tsr'] = dOmegaRated_dOmegad * Vrated / R * RS2RPM
        J['ratedConditions:Omega',
          'Vrated'] = dOmegaRated_dOmegad * params['control:tsr'] / R * RS2RPM
        J['ratedConditions:Omega', 'R'] = -dOmegaRated_dOmegad * params[
            'control:tsr'] * Vrated / R**2 * RS2RPM
        J['ratedConditions:Omega', 'control:maxOmega'] = dOmegaRated_dmaxOmega
        J['ratedConditions:T', 'Vcoarse'] = np.reshape(dT_dVcoarse,
                                                       (1, len(dT_dVcoarse)))
        J['ratedConditions:T', 'Tcoarse'] = np.reshape(dT_dTcoarse,
                                                       (1, len(dT_dTcoarse)))
        J['ratedConditions:T', 'Vrated'] = dT_dVrated
        J['ratedConditions:Q', 'control:tsr'] = drQ[0]
        J['ratedConditions:Q', 'Vrated'] = drQ[-3]
        J['ratedConditions:Q', 'R'] = drQ[-2]
        J['ratedConditions:Q', 'control:maxOmega'] = drQ[-1]

        self.J = J
示例#5
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])
示例#6
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])