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

        n = params['npts']
        R = params['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(params['control:Vin'], params['control:Vout'], n)

        # corresponding rotation speed
        Omega_d = params['control:tsr'] * V / R * RS2RPM
        Omega, dOmega_dOmegad, dOmega_dmaxOmega = smooth_min(
            Omega_d, params['control:maxOmega'], pct_offset=0.01)

        # store values
        unknowns['Uhub'] = V
        unknowns['Omega'] = Omega
        unknowns['pitch'] = params['control:pitch'] * np.ones_like(V)

        # gradients
        J = {}
        J['Omega', 'control:tsr'] = dOmega_dOmegad * V / R * RS2RPM
        J['Omega',
          'R'] = dOmega_dOmegad * -params['control:tsr'] * V / R**2 * RS2RPM
        J['Omega', 'control:maxOmega'] = dOmega_dmaxOmega

        self.J = J
示例#3
0
def CSMDrivetrain(aeroPower, ratedPower, drivetrainType):

    if drivetrainType == DRIVETRAIN_TYPE['GEARED']:
        constant = 0.01289
        linear = 0.08510
        quadratic = 0.0

    elif drivetrainType == DRIVETRAIN_TYPE['SINGLE_STAGE']:
        constant = 0.01331
        linear = 0.03655
        quadratic = 0.06107

    elif drivetrainType == DRIVETRAIN_TYPE['MULTI_DRIVE']:
        constant = 0.01547
        linear = 0.04463
        quadratic = 0.05790

    elif drivetrainType == DRIVETRAIN_TYPE['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)

    return aeroPower * eff, eff
示例#4
0
def ApiFa(E, fy, D, t, Klr):
    """Allowable axial stress in compression"""
    #make inputs into arrays just incase they were simple floats
    fyy = np.array([fy])
    EE = np.array([E])
    DD = np.array([D])
    tt = np.array([t])
    KlrK = np.array([Klr])

    n = len(fyy.squeeze())
    fyy2 = np.zeros(n)
    for i in range(n):
        fyy2[i], _, _ = smooth_min(
            ApiFxc(EE.squeeze()[i],
                   fyy.squeeze()[i],
                   DD.squeeze()[i],
                   tt.squeeze()[i]),
            fyy.squeeze()[i])

    Cc = np.sqrt(2. * np.pi**2 * EE / fyy2)
    out = (1 - KlrK**2 /
           (2. * Cc**2)) * fyy2 / (5. / 3. + 3. / 8. * KlrK / Cc - KlrK**3 /
                                   (8. * Cc**3))
    idx = (Klr >= Cc)
    out[idx] = 12. * np.pi**2 * EE[idx] / (23. * KlrK[idx]**2)
    return out.squeeze()
示例#5
0
def CSMDrivetrain(aeroPower, ratedPower, drivetrainType):

    if drivetrainType == DRIVETRAIN_TYPE['GEARED']:
        constant = 0.01289
        linear = 0.08510
        quadratic = 0.0

    elif drivetrainType == DRIVETRAIN_TYPE['SINGLE_STAGE']:
        constant = 0.01331
        linear = 0.03655
        quadratic = 0.06107

    elif drivetrainType == DRIVETRAIN_TYPE['MULTI_DRIVE']:
        constant = 0.01547
        linear = 0.04463
        quadratic = 0.05790

    elif drivetrainType == DRIVETRAIN_TYPE['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)

    return aeroPower * eff, eff
示例#6
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])
示例#7
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])
def hoopStressEurocode(z, d, t, L_reinforced, q_dyn):
    """default method for computing hoop stress using Eurocode method"""

    r = d/2.0-t/2.0  # radius of cylinder middle surface
    omega = L_reinforced/np.sqrt(r*t)

    C_theta = 1.5  # clamped-clamped
    k_w = 0.46*(1.0 + 0.1*np.sqrt(C_theta/omega*r/t))
    kw = smooth_max(k_w, 0.65)
    kw = smooth_min(k_w, 1.0)
    Peq = k_w*q_dyn
    hoop_stress = -Peq*r/t

    return hoop_stress
示例#9
0
def hoopStressEurocode(z, d, t, L_reinforced, q_dyn):
    """default method for computing hoop stress using Eurocode method"""

    r = d / 2.0 - t / 2.0  # radius of cylinder middle surface
    omega = L_reinforced / np.sqrt(r * t)

    C_theta = 1.5  # clamped-clamped
    k_w = 0.46 * (1.0 + 0.1 * np.sqrt(C_theta / omega * r / t))
    kw = smooth_max(k_w, 0.65)
    kw = smooth_min(k_w, 1.0)
    Peq = k_w * q_dyn
    hoop_stress = -Peq * r / t

    return hoop_stress
示例#10
0
def hoopStressEurocode(z, d, t, L_reinforced, q_dyn):
    """default method for computing hoop stress using Eurocode method
       GB 06/21/2018: Ansys comparisons for submerged case suggests this over-compensates for stiffener
                      I'm not even sure the Eurocode is implemented correctly here.  Suggest using the standard
                      hoop stress expression above or API's handling of ring stiffeners below.
    """

    r = d / 2.0 - t / 2.0  # radius of cylinder middle surface
    omega = L_reinforced / np.sqrt(r * t)

    C_theta = 1.5  # clamped-clamped
    k_w = 0.46 * (1.0 + 0.1 * np.sqrt(C_theta / omega * r / t))
    kw = smooth_max(k_w, 0.65)
    kw = smooth_min(k_w, 1.0)
    Peq = k_w * q_dyn
    return hoopStress(d, t, Peq)
示例#11
0
def hoopStressEurocode(z, d, t, L_reinforced, q_dyn):
    """default method for computing hoop stress using Eurocode method
       GB 06/21/2018: Ansys comparisons for submerged case suggests this over-compensates for stiffener
                      I'm not even sure the Eurocode is implemented correctly here.  Suggest using the standard
                      hoop stress expression above or API's handling of ring stiffeners below.
    """

    r = d/2.0-t/2.0  # radius of cylinder middle surface
    omega = L_reinforced/np.sqrt(r*t)

    C_theta = 1.5  # clamped-clamped
    k_w = 0.46*(1.0 + 0.1*np.sqrt(C_theta/omega*r/t))
    kw = smooth_max(k_w, 0.65)
    kw = smooth_min(k_w, 1.0)
    Peq = k_w*q_dyn
    return hoopStress(d, t, Peq)
示例#12
0
def ApiFa(E,fy,D,t,Klr):
    """Allowable axial stress in compression"""
    #make inputs into arrays just incase they were simple floats
    fyy=np.array([fy])
    EE=np.array([E])
    DD=np.array([D])
    tt=np.array([t])
    KlrK=np.array([Klr])

    n = len(fyy.squeeze())
    fyy2 = np.zeros(n)
    for i in range(n):
        fyy2[i], _ , _ = smooth_min(ApiFxc(EE.squeeze()[i], fyy.squeeze()[i], DD.squeeze()[i], tt.squeeze()[i]), fyy.squeeze()[i])

    Cc=np.sqrt(2.*np.pi**2*EE/fyy2)
    out=(1-KlrK**2/(2.*Cc**2))*fyy2 / (5./3. + 3./8.*KlrK/Cc - KlrK**3/(8.*Cc**3))
    idx= (Klr>=Cc)
    out[idx]=12.*np.pi**2 * EE[idx]/ (23. * KlrK[idx]**2)
    return out.squeeze()
示例#13
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
示例#14
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])
示例#15
0
def ApiCmPile(fa, Fe):
    """Reduction factor for buckling allowables for pile and leg"""
    Cm, _, _ = smooth_min(1. - 0.4 * fa / Fe, 0.85, pct_offset=0.01)
    return Cm
示例#16
0
def ApiCmPile(fa,Fe):
    """Reduction factor for buckling allowables for pile and leg"""
    Cm, _, _ = smooth_min(1.-0.4*fa/Fe, 0.85, pct_offset=0.01)
    return Cm