modeling_options['tower']['frame3dd']['tol'] = 1e-9 modeling_options['tower']['frame3dd']['shift'] = 0.0 modeling_options['tower']['frame3dd']['add_gravity'] = True modeling_options['tower']['n_height'] = n_control_points modeling_options['tower']['n_layers'] = 1 modeling_options['monopile']['n_height'] = 0 modeling_options['monopile']['n_layers'] = 0 modeling_options['tower']['wind'] = 'PowerWind' modeling_options['tower']['nLC'] = n_load_cases modeling_options['materials']['n_mat'] = n_materials # --- # Instantiate OpenMDAO problem and create a model using the TowerSE group prob = om.Problem() prob.model = TowerSE(modeling_options=modeling_options) # --- # If performing optimization, set up the optimizer and problem formulation if opt_flag: # Choose the optimizer to use prob.driver = om.ScipyOptimizeDriver() prob.driver.options['optimizer'] = 'SLSQP' # Add objective prob.model.add_objective('tower_mass', scaler=1e-6) # Add design variables, in this case the tower diameter and wall thicknesses prob.model.add_design_var('tower_outer_diameter_in', lower=3.87, upper=max_diam) prob.model.add_design_var('tower_layer_thickness', lower=4e-3, upper=2e-1)
def setUp(self): # --- geometry ---- # --- geometry ---- z_param = np.array([0.0, 43.8, 87.6]) d_param = np.array([6.0, 4.935, 3.87]) t_param = np.array([0.027 * 1.3, 0.023 * 1.3, 0.019 * 1.3]) n = 15 z_full = np.linspace(0.0, 87.6, n) L_reinforced = 30.0 * np.ones(n) # [m] buckling length theta_stress = 0.0 * np.ones(n) yaw = 0.0 # --- material props --- E = 210e9 * np.ones(n) G = 80.8e9 * np.ones(n) rho = 8500.0 * np.ones(n) sigma_y = 450.0e6 * np.ones(n) # --- spring reaction data. Use float('inf') for rigid constraints. --- kidx = np.array([0], dtype=int) # applied at base kx = np.array([float('inf')]) ky = np.array([float('inf')]) kz = np.array([float('inf')]) ktx = np.array([float('inf')]) kty = np.array([float('inf')]) ktz = np.array([float('inf')]) nK = len(kidx) # --- extra mass ---- midx = np.array([n - 1], dtype=int) # RNA mass at top m = np.array([285598.8]) mIxx = np.array([1.14930678e+08]) mIyy = np.array([2.20354030e+07]) mIzz = np.array([1.87597425e+07]) mIxy = np.array([0.00000000e+00]) mIxz = np.array([5.03710467e+05]) mIyz = np.array([0.00000000e+00]) mrhox = np.array([-1.13197635]) mrhoy = np.array([0.]) mrhoz = np.array([0.50875268]) nMass = len(midx) addGravityLoadForExtraMass = True # ----------- # --- wind --- wind_zref = 90.0 wind_z0 = 0.0 shearExp = 0.2 # --------------- # if addGravityLoadForExtraMass=True be sure not to double count by adding those force here also # # --- loading case 1: max Thrust --- wind_Uref1 = 11.73732 plidx1 = np.array([n - 1], dtype=int) # at top Fx1 = np.array([1284744.19620519]) Fy1 = np.array([0.]) Fz1 = np.array([-2914124.84400512]) Mxx1 = np.array([3963732.76208099]) Myy1 = np.array([-2275104.79420872]) Mzz1 = np.array([-346781.68192839]) nPL = len(plidx1) # # --------------- # # --- loading case 2: max wind speed --- wind_Uref2 = 70.0 plidx2 = np.array([n - 1], dtype=int) # at top Fx2 = np.array([930198.60063279]) Fy2 = np.array([0.]) Fz2 = np.array([-2883106.12368949]) Mxx2 = np.array([-1683669.22411597]) Myy2 = np.array([-2522475.34625363]) Mzz2 = np.array([147301.97023764]) # # --------------- # --- safety factors --- gamma_f = 1.35 gamma_m = 1.3 gamma_n = 1.0 gamma_b = 1.1 # --------------- # --- fatigue --- z_DEL = np.array([ 0.000, 1.327, 3.982, 6.636, 9.291, 11.945, 14.600, 17.255, 19.909, 22.564, 25.218, 27.873, 30.527, 33.182, 35.836, 38.491, 41.145, 43.800, 46.455, 49.109, 51.764, 54.418, 57.073, 59.727, 62.382, 65.036, 67.691, 70.345, 73.000, 75.655, 78.309, 80.964, 83.618, 86.273, 87.600 ]) M_DEL = 1e3 * np.array([ 8.2940E+003, 8.1518E+003, 7.8831E+003, 7.6099E+003, 7.3359E+003, 7.0577E+003, 6.7821E+003, 6.5119E+003, 6.2391E+003, 5.9707E+003, 5.7070E+003, 5.4500E+003, 5.2015E+003, 4.9588E+003, 4.7202E+003, 4.4884E+003, 4.2577E+003, 4.0246E+003, 3.7942E+003, 3.5664E+003, 3.3406E+003, 3.1184E+003, 2.8977E+003, 2.6811E+003, 2.4719E+003, 2.2663E+003, 2.0673E+003, 1.8769E+003, 1.7017E+003, 1.5479E+003, 1.4207E+003, 1.3304E+003, 1.2780E+003, 1.2673E+003, 1.2761E+003 ]) nDEL = len(z_DEL) gamma_fatigue = 1.35 * 1.3 * 1.0 life = 20.0 m_SN = 4 # --------------- # --- constraints --- min_d_to_t = 120.0 min_taper = 0.4 # --------------- # # V_max = 80.0 # tip speed # # D = 126.0 # # .freq1p = V_max / (D/2) / (2*pi) # convert to Hz nPoints = len(z_param) nFull = len(z_full) wind = 'PowerWind' prob = Problem() root = prob.root = Group() prob.driver = pyOptSparseDriver() prob.driver.options['optimizer'] = 'SNOPT' prob.driver.opt_settings['Major iterations limit'] = 1000 root.add('z_param', IndepVarComp('z_param', z_param)) root.add('d_param', IndepVarComp('d_param', d_param)) root.add('t_param', IndepVarComp('t_param', t_param)) root.add('TowerSE', TowerSE(nPoints, nFull, nK, nMass, nPL, nDEL, wind=wind)) prob.driver.add_objective('TowerSE.tower1.mass', scaler=1E-6) prob.driver.add_desvar('z_param.z_param', lower=np.zeros(nPoints), upper=np.ones(nPoints) * 1000., scaler=1E-2) prob.driver.add_desvar('t_param.t_param', lower=np.ones(nPoints) * 0.001, upper=np.ones(nPoints) * 1000., scaler=1E-6) prob.driver.add_desvar('d_param.d_param', np.array([2, 2.1, 2.2]), upper=np.ones(nPoints) * 1000., scaler=1E-6) prob.root.connect('z_param.z_param', 'TowerSE.z_param') prob.root.connect('d_param.d_param', 'TowerSE.d_param') prob.root.connect('t_param.t_param', 'TowerSE.t_param') prob.driver.add_constraint('TowerSE.tower1.stress', upper=np.ones(n)) prob.driver.add_constraint('TowerSE.tower2.stress', upper=np.ones(n)) prob.driver.add_constraint('TowerSE.tower1.global_buckling', upper=np.ones(n)) prob.driver.add_constraint('TowerSE.tower2.global_buckling', upper=np.ones(n)) prob.driver.add_constraint('TowerSE.tower1.shell_buckling', upper=np.ones(n)) prob.driver.add_constraint('TowerSE.tower2.shell_buckling', upper=np.ones(n)) prob.driver.add_constraint('TowerSE.tower1.damage', upper=np.ones(n) * 0.8) prob.driver.add_constraint('TowerSE.gc.weldability', upper=np.zeros(n)) prob.driver.add_constraint('TowerSE.gc.manufacturability', upper=np.zeros(n)) freq1p = 0.2 # 1P freq in Hz prob.driver.add_constraint('TowerSE.tower1.f1', lower=1.1 * freq1p) prob.driver.add_constraint('TowerSE.tower2.f1', lower=1.1 * freq1p) prob.setup() if wind == 'PowerWind': prob['TowerSE.wind1.shearExp'] = shearExp prob['TowerSE.wind2.shearExp'] = shearExp # assign values to params # --- geometry ---- #prob['TowerSE.z_param'] = z_param #prob['TowerSE.d_param'] = d_param #prob['TowerSE.t_param'] = t_param prob['TowerSE.z_full'] = z_full prob['TowerSE.tower1.L_reinforced'] = L_reinforced prob['TowerSE.distLoads1.yaw'] = yaw # --- material props --- prob['TowerSE.tower1.E'] = E prob['TowerSE.tower1.G'] = G prob['TowerSE.tower1.rho'] = rho prob['TowerSE.tower1.sigma_y'] = sigma_y # --- spring reaction data. Use float('inf') for rigid constraints. --- prob['TowerSE.tower1.kidx'] = kidx prob['TowerSE.tower1.kx'] = kx prob['TowerSE.tower1.ky'] = ky prob['TowerSE.tower1.kz'] = kz prob['TowerSE.tower1.ktx'] = ktx prob['TowerSE.tower1.kty'] = kty prob['TowerSE.tower1.ktz'] = ktz # --- extra mass ---- prob['TowerSE.tower1.midx'] = midx prob['TowerSE.tower1.m'] = m prob['TowerSE.tower1.mIxx'] = mIxx prob['TowerSE.tower1.mIyy'] = mIyy prob['TowerSE.tower1.mIzz'] = mIzz prob['TowerSE.tower1.mIxy'] = mIxy prob['TowerSE.tower1.mIxz'] = mIxz prob['TowerSE.tower1.mIyz'] = mIyz prob['TowerSE.tower1.mrhox'] = mrhox prob['TowerSE.tower1.mrhoy'] = mrhoy prob['TowerSE.tower1.mrhoz'] = mrhoz prob[ 'TowerSE.tower1.addGravityLoadForExtraMass'] = addGravityLoadForExtraMass # ----------- # --- wind --- prob['TowerSE.wind1.zref'] = wind_zref prob['TowerSE.wind1.z0'] = wind_z0 # --------------- # # --- loading case 1: max Thrust --- prob['TowerSE.wind1.Uref'] = wind_Uref1 prob['TowerSE.tower1.plidx'] = plidx1 prob['TowerSE.tower1.Fx'] = Fx1 prob['TowerSE.tower1.Fy'] = Fy1 prob['TowerSE.tower1.Fz'] = Fz1 prob['TowerSE.tower1.Mxx'] = Mxx1 prob['TowerSE.tower1.Myy'] = Myy1 prob['TowerSE.tower1.Mzz'] = Mzz1 # # --------------- # # --- loading case 2: max Wind Speed --- prob['TowerSE.wind2.Uref'] = wind_Uref2 prob['TowerSE.tower2.plidx'] = plidx2 prob['TowerSE.tower2.Fx'] = Fx2 prob['TowerSE.tower2.Fy'] = Fy2 prob['TowerSE.tower2.Fz'] = Fz2 prob['TowerSE.tower2.Mxx'] = Mxx2 prob['TowerSE.tower2.Myy'] = Myy2 prob['TowerSE.tower2.Mzz'] = Mzz2 # # --------------- # --- safety factors --- prob['TowerSE.tower1.gamma_f'] = gamma_f prob['TowerSE.tower1.gamma_m'] = gamma_m prob['TowerSE.tower1.gamma_n'] = gamma_n prob['TowerSE.tower1.gamma_b'] = gamma_b # --------------- # --- fatigue --- prob['TowerSE.tower1.z_DEL'] = z_DEL prob['TowerSE.tower1.M_DEL'] = M_DEL prob['TowerSE.tower1.gamma_fatigue'] = gamma_fatigue prob['TowerSE.tower1.life'] = life prob['TowerSE.tower1.m_SN'] = m_SN # --------------- # --- constraints --- prob['TowerSE.gc.min_d_to_t'] = min_d_to_t prob['TowerSE.gc.min_taper'] = min_taper # --------------- # # --- run --- prob.run() print prob['TowerSE.gc.weldability'] print prob['TowerSE.gc.manufacturability'] self.J = prob.check_total_derivatives(out_stream=None) """
def design_monopile_tower(optFlag=False, floating_tower=True): nPoints = len(d_param) nFull = 5*(nPoints-1) + 1 prob = om.Problem() prob.model = TowerSE(nLC=1, nPoints=nPoints, nFull=nFull, wind='PowerWind', topLevelFlag=True, monopile=True) prob.driver = om.pyOptSparseDriver() #om.ScipyOptimizeDriver() # prob.driver.options['optimizer'] = 'SNOPT' #'SLSQP' #'CONMIN' # --- Objective --- prob.model.add_objective('tower_mass', scaler=1e-6) # ---------------------- # --- Design Variables --- if floating_tower: prob.model.add_design_var('tower_outer_diameter', lower=3.87, upper=10.0, indices=[m for m in range(itow)]) prob.model.add_design_var('tower_wall_thickness', lower=4e-3, upper=2e-1, indices=[m for m in range(itow)]) else: prob.model.add_design_var('tower_outer_diameter', lower=3.87, upper=10.0, indices=[m for m in range(nPoints-1)]) prob.model.add_design_var('tower_wall_thickness', lower=4e-3, upper=2e-1) #prob.model.add_design_var('suctionpile_depth', lower=10., upper=70.) # ---------------------- # --- Constraints --- #prob.model.add_constraint('height_constraint', lower=-1e-2,upper=1.e-2) prob.model.add_constraint('post.stress', upper=1.0) prob.model.add_constraint('post.global_buckling', upper=1.0) prob.model.add_constraint('post.shell_buckling', upper=1.0) prob.model.add_constraint('weldability', upper=0.0) prob.model.add_constraint('manufacturability', lower=0.0) prob.model.add_constraint('slope', upper=1.0) prob.model.add_constraint('tower.f1', lower=0.13, upper=0.24) # ---------------------- prob.setup() # Set common and then customized parameters prob = set_common_params(prob) prob['foundation_height'] = -30.0 prob['tower_section_height'] = h_param prob['tower_outer_diameter'] = d_param prob['tower_wall_thickness'] = t_param prob['tower_outfitting_factor'] = 1.07 prob['suctionpile_depth'] = 45.0 prob['transition_piece_mass'] = 100e3 prob['transition_piece_height'] = 15.0 prob['soil_G'] = 140e6 prob['soil_nu'] = 0.4 prob['air_viscosity'] = 1.7934e-5 prob['water_density'] = 1025.0 prob['water_viscosity'] = 1.3351e-3 prob['significant_wave_height'] = 4.52 prob['significant_wave_period'] = 9.52 # --- safety factors --- prob['gamma_f'] = 1.35 prob['gamma_m'] = 1.3 prob['gamma_n'] = 1.0 prob['gamma_b'] = 1.1 prob['gamma_fatigue'] = 1.35*1.3*1.0 # --- constraints --- prob['min_d_to_t'] = 120.0 prob['max_taper'] = 0.2 # Keep tower suitable for floating as static design if floating_tower: prob0 = design_floating_tower() prob['tower_outer_diameter'][itow:] = prob0['tower_outer_diameter'] prob['tower_wall_thickness'][itow:] = prob0['tower_wall_thickness'] else: # Make the optimizer work a little less hard by using a better starting point prob['tower_outer_diameter'] = np.array([10., 10., 10., 10., 10., 10., 10., 10., 10., 10., 10., 9.92647687, 9.44319282, 8.83283769, 8.15148167, 7.38976138, 6.90908962, 6.74803581, 6.57231775, 6.5]) prob['tower_wall_thickness'] = np.array([0.05534138, 0.05344902, 0.05150928, 0.04952705, 0.04751736, 0.04551709, 0.0435267, 0.04224176, 0.04105759, 0.0394965, 0.03645589, 0.03377851, 0.03219233, 0.03070819, 0.02910109, 0.02721289, 0.02400931, 0.0208264, 0.02399756]) # Run optimization if optFlag: prob.model.approx_totals() prob.run_driver() else: prob.run_model() print('-----MONOPILE TOWER RESULTS---------') # CSV output htow = np.cumsum(np.r_[0.0, prob['suctionpile_depth'], prob['tower_section_height']]) + (prob['foundation_height']-prob['suctionpile_depth']) towdata = np.c_[htow, np.r_[prob['tower_outer_diameter'][0], prob['tower_outer_diameter']], np.r_[prob['tower_wall_thickness'][0], prob['tower_wall_thickness'][0], prob['tower_wall_thickness']]] rowadd = [] for k in range(towdata.shape[0]): if k==0: continue if k+1 < towdata.shape[0]: rowadd.append([towdata[k,0]+1e-3, towdata[k,1], towdata[k+1,2]]) towdata = np.vstack((towdata, rowadd)) towdata[:,-1] *= 1e3 towdata = np.round( towdata[towdata[:,0].argsort(),], 3) colstr = ['Height [m]','OD [m]', 'Thickness [mm]'] towDF = pd.DataFrame(data=towdata, columns=colstr) mycomments = ['']*towdata.shape[0] mycomments[0] = 'Monopile start' mycomments[np.where(towdata[:,0] == prob['foundation_height'])[0][0]] = 'Mud line' mycomments[np.where(towdata[:,0] == 0.0)[0][0]] = 'Water line' mycomments[np.where(towdata[:,0] == prob['transition_piece_height'])[0][0]] = 'Tower start' mycomments[-1] = 'Tower top' towDF['Location'] = mycomments towDF = towDF[['Location']+colstr] postprocess(prob, towDF) return prob
def design_floating_tower(optFlag=False, ): # Optimize a fixed bottom tower with the frequency range such that when placed on a floating platform, the frequencies shift to not align with 1P/3P bounds # Set common and then customized parameters nPoints = len(d_param[itow:]) nFull = 5*(nPoints-1) + 1 prob = om.Problem() prob.model = TowerSE(nLC=1, nPoints=nPoints, nFull=nFull, wind='PowerWind', topLevelFlag=True, monopile=False) prob.driver = om.pyOptSparseDriver() #om.ScipyOptimizeDriver() # prob.driver.options['optimizer'] = 'SNOPT' #'SLSQP' #'CONMIN' # --- Objective --- prob.model.add_objective('tower_mass', scaler=1e-6) # ---------------------- # --- Design Variables --- prob.model.add_design_var('tower_outer_diameter', lower=3.87, upper=10.0, indices=[m for m in range(nPoints-1)]) prob.model.add_design_var('tower_wall_thickness', lower=4e-3, upper=2e-1) # ---------------------- # --- Constraints --- #prob.model.add_constraint('height_constraint', lower=-1e-2,upper=1.e-2) prob.model.add_constraint('post.stress', upper=1.0) prob.model.add_constraint('post.global_buckling', upper=1.0) prob.model.add_constraint('post.shell_buckling', upper=1.0) prob.model.add_constraint('weldability', upper=0.0) prob.model.add_constraint('manufacturability', lower=0.0) prob.model.add_constraint('slope', upper=1.0) prob.model.add_constraint('tower.f1', lower=0.4)#lower=0.09, upper=0.15) # ---------------------- prob.setup() prob = set_common_params(prob) prob['foundation_height'] = 0.0 prob['tower_section_height'] = h_param[itow:] prob['tower_outer_diameter'] = np.array([10., 9.964, 9.967, 9.927, 9.528, 9.149, 8.945, 8.735, 8.405, 7.321, 6.5]) #d_param[itow:] prob['tower_wall_thickness'] = np.array([0.082954, 0.083073, 0.082799, 0.0299, 0.027842, 0.025567, 0.022854, 0.02025, 0.018339, 0.021211]) #t_param[itow:] prob['tower_outfitting_factor'] = 1.0 prob['suctionpile_depth'] = 0.0 prob['transition_piece_mass'] = 1e-3 prob['transition_piece_height'] = 0.0 prob['soil_G'] = 1e30 prob['soil_nu'] = 0.0 # Floating will have higher loading coeff = 1.25 prob['pre.rna_F'][:2] *= coeff prob['pre.rna_M'] *= coeff # --- safety factors --- prob['gamma_f'] = 1.2*1.35 prob['gamma_m'] = 1.3 prob['gamma_n'] = 1.0 prob['gamma_b'] = 1.1 prob['gamma_fatigue'] = 1.35*1.3*1.0 # --- constraints --- prob['min_d_to_t'] = 100.0 prob['max_taper'] = 0.2 # Run optimization if optFlag: prob.model.approx_totals() prob.run_driver() else: prob.run_model() print('-----FLOATING TOWER RESULTS---------') # CSV output transition_piece_height = 15.0 htow = np.cumsum(np.r_[0.0, prob['tower_section_height']]) + transition_piece_height towdata = np.c_[htow, prob['tower_outer_diameter'], np.r_[prob['tower_wall_thickness'][0], prob['tower_wall_thickness']]] rowadd = [] for k in range(towdata.shape[0]): if k==0: continue if k+1 < towdata.shape[0]: rowadd.append([towdata[k,0]+1e-3, towdata[k,1], towdata[k+1,2]]) towdata = np.vstack((towdata, rowadd)) towdata[:,-1] *= 1e3 towdata = np.round( towdata[towdata[:,0].argsort(),], 3) colstr = ['Height [m]','OD [m]', 'Thickness [mm]'] towDF = pd.DataFrame(data=towdata, columns=colstr) postprocess(prob, towDF, spre='floating_tower') return prob
def setup(self): RefBlade = self.options['RefBlade'] Nsection_Tow = self.options['Nsection_Tow'] user_update_routine = self.options['user_update_routine'] if 'Analysis_Level' in self.options['FASTpref']: Analysis_Level = self.options['FASTpref']['Analysis_Level'] else: Analysis_Level = 0 # Define all input variables from all models myIndeps = IndepVarComp() myIndeps.add_discrete_output('crane', False) # Turbine Costs myIndeps.add_discrete_output('bearing_number', 0) # Tower and Frame3DD options myIndeps.add_output('project_lifetime', 0.0, units='yr') myIndeps.add_output('max_taper_ratio', 0.0) myIndeps.add_output('min_diameter_thickness_ratio', 0.0) # Environment myIndeps.add_output('wind_bottom_height', 0.0, units='m') myIndeps.add_output('wind_beta', 0.0, units='deg') myIndeps.add_output('cd_usr', -1.) # Environment Offshore myIndeps.add_output('offshore', True) myIndeps.add_output('water_depth', 0.0) myIndeps.add_output('wave_height', 0.0) myIndeps.add_output('wave_period', 0.0) myIndeps.add_output('mean_current_speed', 0.0) # Design standards myIndeps.add_output('gamma_b', 0.0) myIndeps.add_output('gamma_n', 0.0) # RNA myIndeps.add_discrete_output('rna_weightM', True) # Column myIndeps.add_output('morison_mass_coefficient', 2.0) myIndeps.add_output('material_density', 0.0, units='kg/m**3') myIndeps.add_output('E', 0.0, units='N/m**2') myIndeps.add_output('yield_stress', 0.0, units='N/m**2') # Pontoons myIndeps.add_output('G', 0.0, units='N/m**2') # LCOE myIndeps.add_output('labor_cost_rate', 0.0, units='USD/min') myIndeps.add_output('material_cost_rate', 0.0, units='USD/kg') myIndeps.add_output('painting_cost_rate', 0.0, units='USD/m**2') myIndeps.add_discrete_output('number_of_turbines', 0) myIndeps.add_output( 'annual_opex', 0.0, units='USD/kW/yr') # TODO: Replace with output connection myIndeps.add_output( 'bos_costs', 0.0, units='USD/kW') # TODO: Replace with output connection myIndeps.add_output('fixed_charge_rate', 0.0) myIndeps.add_output('wake_loss_factor', 0.0) self.add_subsystem('myIndeps', myIndeps, promotes=['*']) # Add components self.add_subsystem('rotorse', RotorSE(RefBlade=RefBlade, npts_coarse_power_curve=20, npts_spline_power_curve=200, regulation_reg_II5=True, regulation_reg_III=True, Analysis_Level=Analysis_Level, FASTpref=self.options['FASTpref'], topLevelFlag=True, user_update_routine=user_update_routine), promotes=['*']) self.add_subsystem('drive', DriveSE(debug=False, number_of_main_bearings=1, topLevelFlag=False), promotes=[ 'machine_rating', 'overhang', 'hub_mass', 'bedplate_mass', 'gearbox_mass', 'generator_mass', 'hss_mass', 'hvac_mass', 'lss_mass', 'cover_mass', 'pitch_system_mass', 'platforms_mass', 'spinner_mass', 'transformer_mass', 'vs_electronics_mass', 'yaw_mass' ]) # Tower and substructure self.add_subsystem( 'tow', TowerSE(nLC=1, nPoints=Nsection_Tow + 1, nFull=5 * Nsection_Tow + 1, wind='PowerWind', topLevelFlag=False, monopile=True), promotes=[ 'water_density', 'water_viscosity', 'wave_beta', 'significant_wave_height', 'significant_wave_period', 'material_density', 'E', 'G', 'tower_section_height', 'tower_wall_thickness', 'tower_outer_diameter', 'tower_outfitting_factor', 'tower_buckling_length', 'transition_piece_mass', 'transition_piece_height', 'max_taper', 'min_d_to_t', 'rna_mass', 'rna_cg', 'rna_I', 'tower_add_gravity', 'tower_mass', 'tower_I_base', 'hub_height', 'foundation_height', 'monopile', 'soil_G', 'soil_nu', 'suctionpile_depth', 'gamma_f', 'gamma_m', 'gamma_b', 'gamma_n', 'gamma_fatigue', 'labor_cost_rate', 'material_cost_rate', 'painting_cost_rate', 'z_full', 'd_full', 't_full', 'DC', 'shear', 'geom', 'tower_force_discretization', 'nM', 'Mmethod', 'lump', 'tol', 'shift' ]) # Turbine constraints self.add_subsystem('tcons', TurbineConstraints(nFull=5 * Nsection_Tow + 1), promotes=['*']) # Turbine costs self.add_subsystem('tcost', Turbine_CostsSE_2015( verbosity=self.options['VerbosityCosts'], topLevelFlag=False), promotes=['*']) # LCOE Calculation self.add_subsystem( 'plantfinancese', PlantFinance(verbosity=self.options['VerbosityCosts']), promotes=['machine_rating', 'lcoe']) # Set up connections # Connections to DriveSE self.connect('diameter', 'drive.rotor_diameter') self.connect('rated_Q', 'drive.rotor_torque') self.connect('rated_Omega', 'drive.rotor_rpm') self.connect('Fxyz_total', 'drive.Fxyz') self.connect('Mxyz_total', 'drive.Mxyz') self.connect('I_all_blades', 'drive.blades_I') self.connect('mass_one_blade', 'drive.blade_mass') self.connect('chord', 'drive.blade_root_diameter', src_indices=[0]) self.connect('Rtip', 'drive.blade_length', src_indices=[0]) self.connect('drivetrainEff', 'drive.drivetrain_efficiency', src_indices=[0]) self.connect('tower_outer_diameter', 'drive.tower_top_diameter', src_indices=[-1]) self.connect('material_density', 'tow.tower.rho') # Connections to TowerSE self.connect('drive.top_F', 'tow.pre.rna_F') self.connect('drive.top_M', 'tow.pre.rna_M') self.connect('drive.rna_I_TT', ['rna_I', 'tow.pre.mI']) self.connect('drive.rna_cm', ['rna_cg', 'tow.pre.mrho']) self.connect('drive.rna_mass', ['rna_mass', 'tow.pre.mass']) self.connect('rs.gust.V_gust', 'tow.wind.Uref') self.connect('wind_reference_height', ['tow.wind.zref', 'wind.zref']) # self.connect('wind_bottom_height', ['tow.wind.z0','tow.wave.z_surface', 'wind.z0']) # offshore self.connect('wind_bottom_height', ['tow.wind.z0', 'wind.z0']) self.connect('shearExp', ['tow.wind.shearExp']) # self.connect('morison_mass_coefficient','tow.cm') # offshore self.connect('yield_stress', 'tow.sigma_y') self.connect('max_taper_ratio', 'max_taper') self.connect('min_diameter_thickness_ratio', 'min_d_to_t') self.connect('rho', 'tow.windLoads.rho') self.connect('mu', 'tow.windLoads.mu') self.connect('wind_beta', 'tow.windLoads.beta') # Connections to TurbineConstraints self.connect('nBlades', ['blade_number', 'drive.number_of_blades']) self.connect('control_maxOmega', 'rotor_omega') self.connect('tow.post.structural_frequencies', 'tower_freq') # Connections to TurbineCostSE self.connect('mass_one_blade', 'blade_mass') self.connect('drive.mainBearing.mb_mass', 'main_bearing_mass') self.connect('total_blade_cost', 'blade_cost_external') # Connections to PlantFinanceSE self.connect('AEP', 'plantfinancese.turbine_aep') self.connect('turbine_cost_kW', 'plantfinancese.tcc_per_kW') self.connect('number_of_turbines', 'plantfinancese.turbine_number') self.connect('bos_costs', 'plantfinancese.bos_per_kW') self.connect('annual_opex', 'plantfinancese.opex_per_kW')
8.56494627, 8.18565418, 8.06162831, 7.92478627, 7.82113907, 7.33825148, 6.49121862 ]) t_new = np.array([ 0.06151846, 0.05619698, 0.05042458, 0.0444563, 0.04175584, 0.03929218, 0.03697146, 0.03528252, 0.03354286, 0.03162747, 0.02898613, 0.02551408, 0.02239292, 0.02025522, 0.02377017 ]) nPoints = len(d_param) nFull = 5 * (nPoints - 1) + 1 prob = om.Problem() prob.model = TowerSE(nLC=1, nPoints=nPoints, nFull=nFull, wind='PowerWind', topLevelFlag=True, monopile=True) prob.driver = om.pyOptSparseDriver() #om.ScipyOptimizeDriver() # # prob.driver.options['optimizer'] = 'SNOPT' #'SLSQP' #'CONMIN' # --- Objective --- prob.model.add_objective('tower_mass', scaler=1e-6) # ---------------------- # --- Design Variables --- prob.model.add_design_var('tower_outer_diameter', lower=3.87, upper=10.0) prob.model.add_design_var('tower_wall_thickness', lower=4e-3, upper=2e-1) # ---------------------- # --- Constraints ---
# --- constraints --- min_d_to_t = 120.0 max_taper = 0.2 # --------------- # # V_max = 80.0 # tip speed # # D = 126.0 # # .freq1p = V_max / (D/2) / (2*pi) # convert to Hz nPoints = len(d_param) nFull = 5*(nPoints-1) + 1 wind = 'PowerWind' nLC = 1 prob = om.Problem() prob.model = TowerSE(nLC=nLC, nPoints=nPoints, nFull=nFull, wind=wind, topLevelFlag=True, monopile=monopile) prob.driver = om.pyOptSparseDriver() #om.ScipyOptimizeDriver() # # prob.driver.options['optimizer'] = 'SNOPT' #'SLSQP' #'CONMIN' # --- Objective --- prob.model.add_objective('tower_mass', scaler=1e-6) # ---------------------- # --- Design Variables --- prob.model.add_design_var('tower_outer_diameter', lower=3.87, upper=10.0) prob.model.add_design_var('tower_wall_thickness', lower=4e-3, upper=2e-1) # ---------------------- # --- Constraints --- prob.model.add_constraint('height_constraint', lower=-1e-2,upper=1.e-2) prob.model.add_constraint('post.stress', upper=1.0)