def test_NREL_WISDEM_Turbine(self): turbine = TurbineSE() turbine.sea_depth = 0.0 # 0.0 for land-based turbine wind_class = 'I' configure_nrel5mw_turbine(turbine,wind_class,turbine.sea_depth) # === run === turbine.run() self.assertEqual(np.round(turbine.rotor.mass_all_blades, 1), 54674.8) self.assertEqual(np.round(turbine.maxdeflection.ground_clearance, 1), 28.5) print 'mass rotor blades (kg) =', turbine.rotor.mass_all_blades print 'mass hub system (kg) =', turbine.hubSystem.hub_system_mass print 'mass nacelle (kg) =', turbine.nacelle.nacelle_mass print 'mass tower (kg) =', turbine.tower.mass print 'maximum tip deflection (m) =', turbine.maxdeflection.max_tip_deflection print 'ground clearance (m) =', turbine.maxdeflection.ground_clearance
def test_NREL_WISDEM_Turbine(self): turbine = TurbineSE() turbine.sea_depth = 0.0 # 0.0 for land-based turbine wind_class = 'I' configure_nrel5mw_turbine(turbine, wind_class, turbine.sea_depth) # === run === turbine.run() self.assertEqual(np.round(turbine.rotor.mass_all_blades, 1), 54674.8) self.assertEqual(np.round(turbine.maxdeflection.ground_clearance, 1), 28.5) print 'mass rotor blades (kg) =', turbine.rotor.mass_all_blades print 'mass hub system (kg) =', turbine.hubSystem.hub_system_mass print 'mass nacelle (kg) =', turbine.nacelle.nacelle_mass print 'mass tower (kg) =', turbine.tower.mass print 'maximum tip deflection (m) =', turbine.maxdeflection.max_tip_deflection print 'ground clearance (m) =', turbine.maxdeflection.ground_clearance
def create_example_se_assembly(wind_class='I', sea_depth=0.0, with_new_nacelle=False, with_landbos=False, flexible_blade=False, with_3pt_drive=False, with_ecn_opex=False, ecn_file=None, var_file=None, obj_file=None, con_file=None, with_openwind=False, ow_file=None, ow_wkbook=None): """ Inputs: wind_class : str ('I', 'III', 'Offshore' - selected wind class for project) sea_depth : float (sea depth if an offshore wind plant) """ # === Create LCOE SE assembly ======== lcoe_se = lcoe_se_assembly(with_new_nacelle, with_landbos, flexible_blade, with_3pt_drive, with_ecn_opex, ecn_file) # === Set assembly variables and objects === lcoe_se.sea_depth = sea_depth # 0.0 for land-based turbine lcoe_se.turbine_number = 100 lcoe_se.year = 2009 lcoe_se.month = 12 rotor = lcoe_se.rotor nacelle = lcoe_se.nacelle tower = lcoe_se.tower tcc_a = lcoe_se.tcc_a # bos_a = lcoe_se.bos_a # opex_a = lcoe_se.opex_a aep_a = lcoe_se.aep_a fin_a = lcoe_se.fin_a # Turbine =========== from wisdem.reference_turbines.nrel5mw.nrel5mw import configure_nrel5mw_turbine configure_nrel5mw_turbine(lcoe_se, wind_class, lcoe_se.sea_depth) # tcc ==== lcoe_se.advanced_blade = True lcoe_se.offshore = False lcoe_se.assemblyCostMultiplier = 0.30 lcoe_se.profitMultiplier = 0.20 lcoe_se.overheadCostMultiplier = 0.0 lcoe_se.transportMultiplier = 0.0 # for new landBOS # === new landBOS === if with_landbos: lcoe_se.voltage = 137 lcoe_se.distInter = 5 lcoe_se.terrain = 'FLAT_TO_ROLLING' lcoe_se.layout = 'SIMPLE' lcoe_se.soil = 'STANDARD' # aep ==== # based on COE review for land-based machines if not with_openwind: lcoe_se.array_losses = 0.059 #lcoe_se.A = 8.9 # weibull of 7.25 at 50 m with shear exp of 0.143 lcoe_se.A = 10 * 2 / np.sqrt( np.pi ) # weibull of 7.25 at 50 m with shear exp of 0.143 # changed by HF 20190827 lcoe_se.k = 2.0 lcoe_se.other_losses = 0.101 if not with_ecn_opex: lcoe_se.availability = 0.94 # fin === lcoe_se.fixed_charge_rate = 0.095 lcoe_se.construction_finance_rate = 0.0 lcoe_se.tax_rate = 0.4 lcoe_se.discount_rate = 0.07 lcoe_se.construction_time = 1.0 lcoe_se.project_lifetime = 20.0 # Set plant level inputs === shearExp = 0.2 #TODO : should be an input to lcoe #rotor.cdf_reference_height_wind_speed = 90.0 if not with_openwind: lcoe_se.array_losses = 0.1 lcoe_se.other_losses = 0.0 if not with_ecn_opex: lcoe_se.availability = 0.98 rotor.turbulence_class = 'B' lcoe_se.multiplier = 2.23 if wind_class == 'Offshore': # rotor.cdf_reference_mean_wind_speed = 8.4 # TODO - aep from its own module # rotor.cdf_reference_height_wind_speed = 50.0 # rotor.weibull_shape = 2.1 shearExp = 0.14 # TODO : should be an input to lcoe lcoe_se.array_losses = 0.15 if not with_ecn_opex: lcoe_se.availability = 0.96 lcoe_se.offshore = True lcoe_se.multiplier = 2.33 lcoe_se.fixed_charge_rate = 0.118 rotor.shearExp = shearExp tower.wind1.shearExp = shearExp tower.wind2.shearExp = shearExp # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # ==== # === Run pop_vars assembly and print results variables = pd.read_csv(var_file, delimiter='\t', header=None).values # variables is numpy array npop = variables.shape[0] nvar = 32 nobj = 5 ncon = 22 objectives = np.ones((npop, nobj)) * 1.0E+30 constraints = np.ones((npop, ncon)) * -1.0E+30 variableRanges = np.zeros((2, nvar)) #DV 1 to 4 variableRanges[0][0:4] = [1.0] * 4 variableRanges[1][0:4] = [5.3] * 4 #DV 5 variableRanges[0][4] = 0.1 variableRanges[1][4] = 0.3 #DV 6 to 9 variableRanges[0][5:9] = [-5.0] * 4 variableRanges[1][5:9] = [30.0] * 4 #DV 10 to 14 variableRanges[0][9:14] = [0.005] * 5 variableRanges[1][9:14] = [0.200] * 5 #DV 15 to 19 variableRanges[0][14:19] = [0.005] * 5 variableRanges[1][14:19] = [0.200] * 5 #DV 20 to 22 variableRanges[0][19:22] = [-6.3] * 3 variableRanges[1][19:22] = [0.0] * 3 #DV 23 variableRanges[0][22] = 6.0 variableRanges[1][22] = 14.0 #DV 24 variableRanges[0][23] = 6.0 variableRanges[1][23] = 20.0 #DV 25 variableRanges[0][24] = 50.0 variableRanges[1][24] = 80.0 #DV 26 variableRanges[0][25] = 20.0 variableRanges[1][25] = 70.0 #DV 27 to 29 variableRanges[0][26:29] = [3.87] * 3 variableRanges[1][26:29] = [6.30] * 3 #DV 30 to 32 variableRanges[0][29:32] = [0.005] * 3 variableRanges[1][29:32] = [0.100] * 3 for ipop in range(npop): print "evaluating %d th pop..." % (ipop) # --- Design Variables --- # ##DV 1 to 4 lcoe_se.rotor.chord_sub = variableRanges[0][0:4] + ( variableRanges[1][0:4] - variableRanges[0][0:4] ) * variables[ipop][ 0: 4] # (Array, m): chord at control points. defined at hub, then at linearly spaced locations from r_max_chord to tip ##DV 5 lcoe_se.rotor.r_max_chord = variableRanges[0][4] + ( variableRanges[1][4] - variableRanges[0][4] ) * variables[ipop][4] # (Float): location of max chord on unit radius ##DV 6 to 9 lcoe_se.rotor.theta_sub = variableRanges[0][5:9] + ( variableRanges[1][5:9] - variableRanges[0][5:9] ) * variables[ipop][ 5: 9] # (Array, deg): twist at control points. defined at linearly spaced locations from r[idx_cylinder] to tip ##DV 10 to 14 lcoe_se.rotor.sparT = variableRanges[0][9:14] + ( variableRanges[1][9:14] - variableRanges[0][9:14] ) * variables[ipop][9:14] # (Array, m): spar cap thickness parameters ##DV 15 to 19 lcoe_se.rotor.teT = variableRanges[0][14:19] + ( variableRanges[1][14:19] - variableRanges[0][14:19]) * variables[ ipop][14:19] # (Array, m): trailing-edge thickness parameters ##DV 20 to 22 #lcoe_se.rotor.precone = 0.0 # this is necessary for using precurve_sub lcoe_se.rotor.precurve_sub = variableRanges[0][19:22] + ( variableRanges[1][19:22] - variableRanges[0][19:22] ) * variables[ipop][ 19: 22] # (Array, m): precurve at control points. defined at same locations at chord, starting at 2nd control point (root must be zero precurve) ##DV 23 lcoe_se.rotor.control.tsr = variableRanges[0][22] + ( variableRanges[1][22] - variableRanges[0][22] ) * variables[ipop][ 22] # (Float): tip-speed ratio in Region 2 (should be optimized externally) ##DV 24 lcoe_se.rotor.control.maxOmega = variableRanges[0][23] + ( variableRanges[1][23] - variableRanges[0][23]) * variables[ipop][ 23] # (Float, rpm): maximum allowed rotor rotation speed ##DV 25 lcoe_se.rotor.bladeLength = variableRanges[0][24] + ( variableRanges[1][24] - variableRanges[0][24]) * variables[ipop][24] ##DV 26 lcoe_se.tower.z_param[1] = variableRanges[0][25] + ( variableRanges[1][25] - variableRanges[0][25]) * variables[ipop][25] ##DV 27 to 29 lcoe_se.tower_d = variableRanges[0][26:29] + ( variableRanges[1][26:29] - variableRanges[0][26:29]) * variables[ipop][26:29] ##DV 30 to 32 lcoe_se.tower.t_param = variableRanges[0][29:32] + ( variableRanges[1][29:32] - variableRanges[0][29:32]) * variables[ipop][29:32] # === Run assembly lcoe_se.run() #MOP # --- Objectives --- AEP = lcoe_se.net_aep / lcoe_se.turbine_number #Objective 1: AEP per turbine iobj = 0 objectives[ipop][iobj] = -AEP #maximization ##Objective 2: COE iobj = 1 objectives[ipop][iobj] = lcoe_se.coe * AEP #Objective 3: Tower base load iobj = 2 objectives[ipop][ iobj] = lcoe_se.tower.tower1.Fx * lcoe_se.hub_height + lcoe_se.tower.tower1.Myy #Objective 4: Blade tip speed iobj = 3 objectives[ipop][iobj] = lcoe_se.rotor.ratedConditions.Omega / 60.0 * ( 2.0 * np.pi) * (lcoe_se.rotor.diameter * 0.5) #Objective 5: Fatigue iobj = 4 args = [] args.append(max(lcoe_se.rotor.damageU_spar)) args.append(max(lcoe_se.rotor.damageL_spar)) args.append(max(lcoe_se.rotor.damageU_te)) args.append(max(lcoe_se.rotor.damageL_te)) args.append(np.log(max(lcoe_se.tower.damage))) objectives[ipop][iobj] = max(args) # --- Constraints --- #Constraint 1: Tip deflection icon = 0 value = lcoe_se.rotor.tip_deflection * 1.485 threshold = lcoe_se.maxdeflection.max_tip_deflection constraints[ipop][icon] = threshold - value #Constraint 2: Ground clearance icon = 1 value = lcoe_se.maxdeflection.ground_clearance threshold = 20.0 constraints[ipop][icon] = value - threshold #Constraint 3: Blade eigen frequency icon = 2 value = lcoe_se.rotor.freq[0] threshold = 1.1 * lcoe_se.rotor.ratedConditions.Omega / 60.0 * lcoe_se.rotor.nBlades constraints[ipop][icon] = value - threshold #Constraint 4: Tower eigen frequency icon = 3 value = lcoe_se.tower.f1 threshold = 1.1 * lcoe_se.rotor.ratedConditions.Omega / 60.0 constraints[ipop][icon] = value - threshold #Constraint 5: Tower 1 stress icon = 4 value = max(lcoe_se.tower.stress1) threshold = 1.0 constraints[ipop][icon] = threshold - value #Constraint 6: Tower 2 stress icon = 5 value = max(lcoe_se.tower.stress2) threshold = 1.0 constraints[ipop][icon] = threshold - value #Constraint 7: Tower 1 global buckling icon = 6 value = max(lcoe_se.tower.global_buckling1) threshold = 1.0 constraints[ipop][icon] = threshold - value #Constraint 8: Tower 1 global buckling icon = 7 value = max(lcoe_se.tower.global_buckling2) threshold = 1.0 constraints[ipop][icon] = threshold - value #Constraint 9: Tower 1 shell buckling icon = 8 value = max(lcoe_se.tower.shell_buckling1) threshold = 1.0 constraints[ipop][icon] = threshold - value #Constraint 10: Tower 2 shell buckling icon = 9 value = max(lcoe_se.tower.shell_buckling2) threshold = 1.0 constraints[ipop][icon] = threshold - value #Constraint 11: Tower 1 fatigue icon = 10 value = max(lcoe_se.tower.damage) threshold = 1.0 constraints[ipop][icon] = threshold - value #Constraint 12: Manufacturability icon = 11 value = max(lcoe_se.tower.manufacturability) threshold = 0.0 constraints[ipop][icon] = threshold - value #Constraint 13: Weldability icon = 12 value = max(lcoe_se.tower.weldability) threshold = 0.0 constraints[ipop][icon] = threshold - value #Constraint 14: Blade tip speed icon = 13 value = lcoe_se.rotor.ratedConditions.Omega / 60.0 * (2.0 * np.pi) * ( lcoe_se.rotor.diameter * 0.5) threshold = 80.0 constraints[ipop][icon] = threshold - value #Constraint 15: Blade buckling for spar icon = 14 value = np.min( [lcoe_se.rotor.strainU_spar, lcoe_se.rotor.strainL_spar], axis=0) threshold = lcoe_se.rotor.eps_crit_spar constraints[ipop][icon] = min(value - threshold) #Constraint 16: Blade buckling for te icon = 15 value = np.min([lcoe_se.rotor.strainU_te, lcoe_se.rotor.strainL_te], axis=0) threshold = lcoe_se.rotor.eps_crit_te constraints[ipop][icon] = min(value - threshold) #Constraint 17: Blade fatigue icon = 16 args = [] args.append(max(lcoe_se.rotor.damageU_spar)) args.append(max(lcoe_se.rotor.damageL_spar)) args.append(max(lcoe_se.rotor.damageU_te)) args.append(max(lcoe_se.rotor.damageL_te)) value = max(args) threshold = 0.0 constraints[ipop][icon] = threshold - value #Constraint 18: Blade strain spar icon = 17 value = min(min(lcoe_se.rotor.strainU_spar), min(lcoe_se.rotor.strainL_spar)) threshold = -0.01 / 1.755 constraints[ipop][icon] = value - threshold #Constraint 19: Blade strain spar icon = 18 value = max(max(lcoe_se.rotor.strainU_spar), max(lcoe_se.rotor.strainL_spar)) threshold = 0.01 / 1.755 constraints[ipop][icon] = threshold - value #Constraint 20: Blade strain te icon = 19 value = min(min(lcoe_se.rotor.strainU_te), min(lcoe_se.rotor.strainL_te)) threshold = -0.0025 / 1.755 constraints[ipop][icon] = value - threshold #Constraint 21: Blade strain te icon = 20 value = min(min(lcoe_se.rotor.strainU_te), min(lcoe_se.rotor.strainL_te)) threshold = 0.0025 / 1.755 constraints[ipop][icon] = threshold - value #Constraint 22: AEP icon = 21 value = AEP threshold = 0.0 constraints[ipop][icon] = value - threshold pd.DataFrame(objectives).to_csv(obj_file, sep='\t', index=False, header=False) pd.DataFrame(constraints).to_csv(con_file, sep='\t', index=False, header=False)
def configure(self): super(Assembly, self).configure() # Let's analyze the lifetime cost of energy cost scaling model! wind_class = 'I' sea_depth = 0.0 with_new_nacelle = True with_landbos = False flexible_blade = False with_3pt_drive = False with_ecn_opex = False ecn_file = '' with_openwind = False #create_example_se_assembly(wind_class,sea_depth,with_new_nacelle,with_landbos,flexible_blade,with_3pt_drive,with_ecn_opex,ecn_file) self.add('lcoe_se', lcoe_se_assembly(with_new_nacelle,with_landbos,flexible_blade,with_3pt_drive,with_ecn_opex,ecn_file)) # === Set assembly variables and objects === self.lcoe_se.sea_depth = sea_depth # 0.0 for land-based turbine self.lcoe_se.turbine_number = 100 self.lcoe_se.year = 2009 self.lcoe_se.month = 12 rotor = self.lcoe_se.rotor nacelle = self.lcoe_se.nacelle tower = self.lcoe_se.tower tcc_a = self.lcoe_se.tcc_a # bos_a = self.lcoe_se.bos_a # opex_a = self.lcoe_se.opex_a aep_a = self.lcoe_se.aep_a fin_a = self.lcoe_se.fin_a # Turbine =========== from wisdem.reference_turbines.nrel5mw.nrel5mw import configure_nrel5mw_turbine configure_nrel5mw_turbine(self.lcoe_se,wind_class,self.lcoe_se.sea_depth) # tcc ==== self.lcoe_se.advanced_blade = True self.lcoe_se.offshore = False self.lcoe_se.assemblyCostMultiplier = 0.30 self.lcoe_se.profitMultiplier = 0.20 self.lcoe_se.overheadCostMultiplier = 0.0 self.lcoe_se.transportMultiplier = 0.0 # for new landBOS # === new landBOS === if with_landbos: self.lcoe_se.voltage = 137 self.lcoe_se.distInter = 5 self.lcoe_se.terrain = 'FLAT_TO_ROLLING' self.lcoe_se.layout = 'SIMPLE' self.lcoe_se.soil = 'STANDARD' # aep ==== # based on COE review for land-based machines if not with_openwind: self.lcoe_se.array_losses = 0.059 self.lcoe_se.A = 8.9 # weibull of 7.25 at 50 m with shear exp of 0.143 self.lcoe_se.k = 2.0 self.lcoe_se.other_losses = 0.101 if not with_ecn_opex: self.lcoe_se.availability = 0.94 # fin === self.lcoe_se.fixed_charge_rate = 0.095 self.lcoe_se.construction_finance_rate = 0.0 self.lcoe_se.tax_rate = 0.4 self.lcoe_se.discount_rate = 0.07 self.lcoe_se.construction_time = 1.0 self.lcoe_se.project_lifetime = 20.0 # Set plant level inputs === shearExp = 0.2 #TODO : should be an input to lcoe #rotor.cdf_reference_height_wind_speed = 90.0 if not with_openwind: self.lcoe_se.array_losses = 0.1 self.lcoe_se.other_losses = 0.0 if not with_ecn_opex: self.lcoe_se.availability = 0.98 rotor.turbulence_class = 'B' self.lcoe_se.multiplier = 2.23 if wind_class == 'Offshore': # rotor.cdf_reference_mean_wind_speed = 8.4 # TODO - aep from its own module # rotor.cdf_reference_height_wind_speed = 50.0 # rotor.weibull_shape = 2.1 shearExp = 0.14 # TODO : should be an input to lcoe self.lcoe_se.array_losses = 0.15 if not with_ecn_opex: self.lcoe_se.availability = 0.96 self.lcoe_se.offshore = True self.lcoe_se.multiplier = 2.33 self.lcoe_se.fixed_charge_rate = 0.118 rotor.shearExp = shearExp tower.wind1.shearExp = shearExp tower.wind2.shearExp = shearExp # ..using the cutting edge pydakdriver dakDriver = pydakdriver() dakDriver.UQ() dakDriver.seed = 4723 driver = self.add('driver',dakDriver) driver.workflow.add('lcoe_se') driver.stdout = 'dakota.out' driver.stderr = 'dakota.err' driver.add_parameter('lcoe_se.A',low=8.2*0.5, high=8.2*1.5) driver.add_parameter('lcoe_se.k',low=2.0*0.5, high=2.0*1.5) driver.add_parameter('lcoe_se.shear_exponent',low=.2*0.5, high=.2*1.5) # use same objectives as previous sensitivity analysis driver.add_objective('lcoe_se.coe') # driver.add_objective('lcoe_se.lcoe') driver.add_objective('lcoe_se.net_aep') driver.add_objective('lcoe_se.bos_costs') driver.add_objective('lcoe_se.avg_annual_opex') driver.add_objective('lcoe_se.turbine_cost')
def create_example_se_assembly(wind_class='I',sea_depth=0.0,with_new_nacelle=False,with_landbos=False,flexible_blade=False,with_3pt_drive=False, with_ecn_opex=False, ecn_file=None,with_openwind=False,ow_file=None,ow_wkbook=None): """ Inputs: wind_class : str ('I', 'III', 'Offshore' - selected wind class for project) sea_depth : float (sea depth if an offshore wind plant) """ # === Create LCOE SE assembly ======== lcoe_se = lcoe_se_assembly(with_new_nacelle,with_landbos,flexible_blade,with_3pt_drive,with_ecn_opex,ecn_file) # === Set assembly variables and objects === lcoe_se.sea_depth = sea_depth # 0.0 for land-based turbine lcoe_se.turbine_number = 100 lcoe_se.year = 2009 lcoe_se.month = 12 rotor = lcoe_se.rotor nacelle = lcoe_se.nacelle tower = lcoe_se.tower tcc_a = lcoe_se.tcc_a # bos_a = lcoe_se.bos_a # opex_a = lcoe_se.opex_a aep_a = lcoe_se.aep_a fin_a = lcoe_se.fin_a # Turbine =========== from wisdem.reference_turbines.nrel5mw.nrel5mw import configure_nrel5mw_turbine configure_nrel5mw_turbine(lcoe_se,wind_class,lcoe_se.sea_depth) # tcc ==== lcoe_se.advanced_blade = True lcoe_se.offshore = False lcoe_se.assemblyCostMultiplier = 0.30 lcoe_se.profitMultiplier = 0.20 lcoe_se.overheadCostMultiplier = 0.0 lcoe_se.transportMultiplier = 0.0 # for new landBOS # === new landBOS === if with_landbos: lcoe_se.voltage = 137 lcoe_se.distInter = 5 lcoe_se.terrain = 'FLAT_TO_ROLLING' lcoe_se.layout = 'SIMPLE' lcoe_se.soil = 'STANDARD' # aep ==== # based on COE review for land-based machines if not with_openwind: lcoe_se.array_losses = 0.059 lcoe_se.A = 8.9 # weibull of 7.25 at 50 m with shear exp of 0.143 lcoe_se.k = 2.0 lcoe_se.other_losses = 0.101 if not with_ecn_opex: lcoe_se.availability = 0.94 # fin === lcoe_se.fixed_charge_rate = 0.095 lcoe_se.construction_finance_rate = 0.0 lcoe_se.tax_rate = 0.4 lcoe_se.discount_rate = 0.07 lcoe_se.construction_time = 1.0 lcoe_se.project_lifetime = 20.0 # Set plant level inputs === shearExp = 0.2 #TODO : should be an input to lcoe #rotor.cdf_reference_height_wind_speed = 90.0 if not with_openwind: lcoe_se.array_losses = 0.1 lcoe_se.other_losses = 0.0 if not with_ecn_opex: lcoe_se.availability = 0.98 rotor.turbulence_class = 'B' lcoe_se.multiplier = 2.23 if wind_class == 'Offshore': # rotor.cdf_reference_mean_wind_speed = 8.4 # TODO - aep from its own module # rotor.cdf_reference_height_wind_speed = 50.0 # rotor.weibull_shape = 2.1 shearExp = 0.14 # TODO : should be an input to lcoe lcoe_se.array_losses = 0.15 if not with_ecn_opex: lcoe_se.availability = 0.96 lcoe_se.offshore = True lcoe_se.multiplier = 2.33 lcoe_se.fixed_charge_rate = 0.118 rotor.shearExp = shearExp tower.wind1.shearExp = shearExp tower.wind2.shearExp = shearExp # ==== # === Run default assembly and print results lcoe_se.run() # ==== # === Print === print "Key Turbine Outputs for NREL 5 MW Reference Turbine" print 'mass rotor blades:{0:.2f} (kg) '.format(lcoe_se.rotor.mass_all_blades) print 'mass hub system: {0:.2f} (kg) '.format(lcoe_se.hub.hub_system_mass) print 'mass nacelle: {0:.2f} (kg) '.format(lcoe_se.nacelle.nacelle_mass) print 'mass tower: {0:.2f} (kg) '.format(lcoe_se.tower.mass) print 'maximum tip deflection: {0:.2f} (m) '.format(lcoe_se.maxdeflection.max_tip_deflection) print 'ground clearance: {0:.2f} (m) '.format(lcoe_se.maxdeflection.ground_clearance) print print "Key Plant Outputs for wind plant with NREL 5 MW Turbine" #print "LCOE: ${0:.4f} USD/kWh".format(lcoe_se.lcoe) # not in base output set (add to assembly output if desired) print "COE: ${0:.4f} USD/kWh".format(lcoe_se.coe) print print "AEP per turbine: {0:.1f} kWh/turbine".format(lcoe_se.net_aep / lcoe_se.turbine_number) print "Turbine Cost: ${0:.2f} USD".format(lcoe_se.turbine_cost) print "BOS costs per turbine: ${0:.2f} USD/turbine".format(lcoe_se.bos_costs / lcoe_se.turbine_number) print "OPEX per turbine: ${0:.2f} USD/turbine".format(lcoe_se.avg_annual_opex / lcoe_se.turbine_number)
class TurbineSE(Assembly): def configure(self): configure_turbine(self) if __name__ == '__main__': turbine = TurbineSE() turbine.sea_depth = 0.0 # 0.0 for land-based turbine wind_class = 'I' from wisdem.reference_turbines.nrel5mw.nrel5mw import configure_nrel5mw_turbine configure_nrel5mw_turbine(turbine,wind_class,turbine.sea_depth) # === run === turbine.run() print 'mass rotor blades (kg) =', turbine.rotor.mass_all_blades print 'mass hub system (kg) =', turbine.hubSystem.hub_system_mass print 'mass nacelle (kg) =', turbine.nacelle.nacelle_mass print 'mass tower (kg) =', turbine.tower.mass print 'maximum tip deflection (m) =', turbine.maxdeflection.max_tip_deflection print 'ground clearance (m) =', turbine.maxdeflection.ground_clearance # print # print '"Torque":',turbine.nacelle.rotor_torque # print 'Mx:',turbine.nacelle.rotor_bending_moment_x # print 'My:',turbine.nacelle.rotor_bending_moment_y # print 'Mz:',turbine.nacelle.rotor_bending_moment_z # print 'Fx:',turbine.nacelle.rotor_force_x
def test1(self): wind_class = 'I' sea_depth = 0.0 with_new_nacelle = True with_landbos = False flexible_blade = False with_3pt_drive = False with_ecn_opex = False ecn_file = '' with_openwind=False ow_file=None ow_wkbook=None lcoe_se = lcoe_se_assembly(with_new_nacelle,with_landbos,flexible_blade,with_3pt_drive,with_ecn_opex,ecn_file) # === Set assembly variables and objects === lcoe_se.sea_depth = sea_depth # 0.0 for land-based turbine lcoe_se.turbine_number = 100 lcoe_se.year = 2009 lcoe_se.month = 12 rotor = lcoe_se.rotor nacelle = lcoe_se.nacelle tower = lcoe_se.tower tcc_a = lcoe_se.tcc_a # bos_a = lcoe_se.bos_a # opex_a = lcoe_se.opex_a aep_a = lcoe_se.aep_a fin_a = lcoe_se.fin_a # Turbine =========== from wisdem.reference_turbines.nrel5mw.nrel5mw import configure_nrel5mw_turbine configure_nrel5mw_turbine(lcoe_se,wind_class,lcoe_se.sea_depth) # tcc ==== lcoe_se.advanced_blade = True lcoe_se.offshore = False lcoe_se.assemblyCostMultiplier = 0.30 lcoe_se.profitMultiplier = 0.20 lcoe_se.overheadCostMultiplier = 0.0 lcoe_se.transportMultiplier = 0.0 # for new landBOS # === new landBOS === if with_landbos: lcoe_se.voltage = 137 lcoe_se.distInter = 5 lcoe_se.terrain = 'FLAT_TO_ROLLING' lcoe_se.layout = 'SIMPLE' lcoe_se.soil = 'STANDARD' # aep ==== # based on COE review for land-based machines if not with_openwind: lcoe_se.array_losses = 0.059 lcoe_se.A = 8.9 # weibull of 7.25 at 50 m with shear exp of 0.143 lcoe_se.k = 2.0 lcoe_se.other_losses = 0.101 if not with_ecn_opex: lcoe_se.availability = 0.94 # fin === lcoe_se.fixed_charge_rate = 0.095 lcoe_se.construction_finance_rate = 0.0 lcoe_se.tax_rate = 0.4 lcoe_se.discount_rate = 0.07 lcoe_se.construction_time = 1.0 lcoe_se.project_lifetime = 20.0 # Set plant level inputs === shearExp = 0.2 #TODO : should be an input to lcoe #rotor.cdf_reference_height_wind_speed = 90.0 if not with_openwind: lcoe_se.array_losses = 0.1 lcoe_se.other_losses = 0.0 if not with_ecn_opex: lcoe_se.availability = 0.98 rotor.turbulence_class = 'B' lcoe_se.multiplier = 2.23 if wind_class == 'Offshore': # rotor.cdf_reference_mean_wind_speed = 8.4 # TODO - aep from its own module # rotor.cdf_reference_height_wind_speed = 50.0 # rotor.weibull_shape = 2.1 shearExp = 0.14 # TODO : should be an input to lcoe lcoe_se.array_losses = 0.15 if not with_ecn_opex: lcoe_se.availability = 0.96 lcoe_se.offshore = True lcoe_se.multiplier = 2.33 lcoe_se.fixed_charge_rate = 0.118 rotor.shearExp = shearExp tower.wind1.shearExp = shearExp tower.wind2.shearExp = shearExp # ==== # === Run default assembly and print results lcoe_se.run() # ==== self.assertEqual(np.round(lcoe_se.rotor.mass_all_blades, 2), 54674.80) self.assertEqual(np.round(lcoe_se.maxdeflection.ground_clearance, 2), 28.47) # === Print === print "Key Turbine Outputs for NREL 5 MW Reference Turbine" print 'mass rotor blades:{0:.2f} (kg) '.format(lcoe_se.rotor.mass_all_blades) print 'mass hub system: {0:.2f} (kg) '.format(lcoe_se.hub.hub_system_mass) print 'mass nacelle: {0:.2f} (kg) '.format(lcoe_se.nacelle.nacelle_mass) print 'mass tower: {0:.2f} (kg) '.format(lcoe_se.tower.mass) print 'maximum tip deflection: {0:.2f} (m) '.format(lcoe_se.maxdeflection.max_tip_deflection) print 'ground clearance: {0:.2f} (m) '.format(lcoe_se.maxdeflection.ground_clearance) print print "Key Plant Outputs for wind plant with NREL 5 MW Turbine" #print "LCOE: ${0:.4f} USD/kWh".format(lcoe_se.lcoe) # not in base output set (add to assembly output if desired) print "COE: ${0:.4f} USD/kWh".format(lcoe_se.coe) print print "AEP per turbine: {0:.1f} kWh/turbine".format(lcoe_se.net_aep / lcoe_se.turbine_number) print "Turbine Cost: ${0:.2f} USD".format(lcoe_se.turbine_cost) print "BOS costs per turbine: ${0:.2f} USD/turbine".format(lcoe_se.bos_costs / lcoe_se.turbine_number) print "OPEX per turbine: ${0:.2f} USD/turbine".format(lcoe_se.avg_annual_opex / lcoe_se.turbine_number)
def example(wind_class='I', sea_depth=0.0, with_new_nacelle=False, with_landbos=False, flexible_blade=False, with_3pt_drive=False, with_ecn_opex=False, ecn_file=None, with_openwind=False, ow_file=None, ow_wkbook=None): """ Inputs: wind_class : str ('I', 'III', 'Offshore' - selected wind class for project) sea_depth : float (sea depth if an offshore wind plant) """ # === Create LCOE SE assembly ======== lcoe_se = lcoe_se_assembly(with_new_nacelle, with_landbos, flexible_blade, with_3pt_drive, with_ecn_opex, ecn_file) # === Set assembly variables and objects === lcoe_se.sea_depth = sea_depth # 0.0 for land-based turbine lcoe_se.turbine_number = 100 lcoe_se.year = 2009 lcoe_se.month = 12 rotor = lcoe_se.rotor nacelle = lcoe_se.nacelle tower = lcoe_se.tower tcc_a = lcoe_se.tcc_a # bos_a = lcoe_se.bos_a # opex_a = lcoe_se.opex_a aep_a = lcoe_se.aep_a fin_a = lcoe_se.fin_a # Turbine =========== from wisdem.reference_turbines.nrel5mw.nrel5mw import configure_nrel5mw_turbine configure_nrel5mw_turbine(lcoe_se, wind_class, lcoe_se.sea_depth) # TODO: these should be specified at the turbine level and connected to other system inputs lcoe_se.tower_d = [6.0, 4.935, 3.87] # (Array, m): diameters along tower lcoe_se.generator_speed = 1173.7 # (Float, rpm) # generator speed # extra variable constant for now #lcoe_se.nacelle.bedplate.rotor_bending_moment_y = -2.3250E+06 # shouldnt be needed anymore # tcc ==== lcoe_se.advanced_blade = True lcoe_se.offshore = False lcoe_se.assemblyCostMultiplier = 0.30 lcoe_se.profitMultiplier = 0.20 lcoe_se.overheadCostMultiplier = 0.0 lcoe_se.transportMultiplier = 0.0 # for new landBOS ''' # === new landBOS === lcoe_se.voltage = 137 lcoe_se.distInter = 5 lcoe_se.terrain = 'FLAT_TO_ROLLING' lcoe_se.layout = 'SIMPLE' lcoe_se.soil = 'STANDARD' ''' # aep ==== if not with_openwind: lcoe_se.array_losses = 0.059 lcoe_se.other_losses = 0.0 if not with_ecn_opex: lcoe_se.availability = 0.94 # fin === lcoe_se.fixed_charge_rate = 0.095 lcoe_se.construction_finance_rate = 0.0 lcoe_se.tax_rate = 0.4 lcoe_se.discount_rate = 0.07 lcoe_se.construction_time = 1.0 lcoe_se.project_lifetime = 20.0 # Set plant level inputs === shearExp = 0.2 #TODO : should be an input to lcoe rotor.cdf_reference_height_wind_speed = 90.0 if not with_openwind: lcoe_se.array_losses = 0.1 lcoe_se.other_losses = 0.0 if not with_ecn_opex: lcoe_se.availability = 0.98 rotor.turbulence_class = 'B' lcoe_se.multiplier = 2.23 if wind_class == 'Offshore': # rotor.cdf_reference_mean_wind_speed = 8.4 # TODO - aep from its own module # rotor.cdf_reference_height_wind_speed = 50.0 # rotor.weibull_shape = 2.1 shearExp = 0.14 # TODO : should be an input to lcoe lcoe_se.array_losses = 0.15 if not with_ecn_opex: lcoe_se.availability = 0.96 lcoe_se.offshore = True lcoe_se.multiplier = 2.33 lcoe_se.fixed_charge_rate = 0.118 rotor.shearExp = shearExp tower.wind1.shearExp = shearExp tower.wind2.shearExp = shearExp # ==== # === Run default assembly and print results lcoe_se.run() # ==== # === Print === print "Key Turbine Outputs for NREL 5 MW Reference Turbine" print 'mass rotor blades:{0:.2f} (kg) '.format( lcoe_se.rotor.mass_all_blades) print 'mass hub system: {0:.2f} (kg) '.format(lcoe_se.hub.hub_system_mass) print 'mass nacelle: {0:.2f} (kg) '.format(lcoe_se.nacelle.nacelle_mass) print 'mass tower: {0:.2f} (kg) '.format(lcoe_se.tower.mass) print 'maximum tip deflection: {0:.2f} (m) '.format( lcoe_se.maxdeflection.max_tip_deflection) print 'ground clearance: {0:.2f} (m) '.format( lcoe_se.maxdeflection.ground_clearance) print print "Key Plant Outputs for wind plant with NREL 5 MW Turbine" #print "LCOE: ${0:.4f} USD/kWh".format(lcoe_se.lcoe) # not in base output set (add to assembly output if desired) print "COE: ${0:.4f} USD/kWh".format(lcoe_se.coe) print print "AEP per turbine: {0:.1f} kWh/turbine".format(lcoe_se.net_aep / lcoe_se.turbine_number) print "Turbine Cost: ${0:.2f} USD".format(lcoe_se.turbine_cost) print "BOS costs per turbine: ${0:.2f} USD/turbine".format( lcoe_se.bos_costs / lcoe_se.turbine_number) print "OPEX per turbine: ${0:.2f} USD/turbine".format( lcoe_se.avg_annual_opex / lcoe_se.turbine_number)
'maxdeflection.towerHt') class TurbineSE(Assembly): def configure(self): configure_turbine(self) if __name__ == '__main__': turbine = TurbineSE() turbine.sea_depth = 0.0 # 0.0 for land-based turbine wind_class = 'I' from wisdem.reference_turbines.nrel5mw.nrel5mw import configure_nrel5mw_turbine configure_nrel5mw_turbine(turbine, wind_class, turbine.sea_depth) # === run === turbine.run() print 'mass rotor blades (kg) =', turbine.rotor.mass_all_blades print 'mass hub system (kg) =', turbine.hubSystem.hub_system_mass print 'mass nacelle (kg) =', turbine.nacelle.nacelle_mass print 'mass tower (kg) =', turbine.tower.mass print 'maximum tip deflection (m) =', turbine.maxdeflection.max_tip_deflection print 'ground clearance (m) =', turbine.maxdeflection.ground_clearance # print # print '"Torque":',turbine.nacelle.rotor_torque # print 'Mx:',turbine.nacelle.rotor_bending_moment_x # print 'My:',turbine.nacelle.rotor_bending_moment_y # print 'Mz:',turbine.nacelle.rotor_bending_moment_z # print 'Fx:',turbine.nacelle.rotor_force_x