def setUp(self): self.inputs = {} self.outputs = {} self.discrete_inputs = {} self.discrete_outputs = {} # Use the API 2U Appendix B as a big unit test! ksi_to_si = 6894757.29317831 lbperft3_to_si = 16.0185 ft_to_si = 0.3048 in_to_si = ft_to_si / 12.0 kip_to_si = 4.4482216 * 1e3 onepts = np.ones((NPTS, )) onesec = np.ones((NPTS - 1, )) #onesec0 = np.ones((NHEIGHT,)) self.inputs['d_full'] = 600 * onepts * in_to_si self.inputs['t_full'] = 0.75 * onesec * in_to_si self.inputs['t_web'] = 5. / 8. * onesec * in_to_si self.inputs['h_web'] = 14.0 * onesec * in_to_si self.inputs['t_flange'] = 1.0 * onesec * in_to_si self.inputs['w_flange'] = 10.0 * onesec * in_to_si self.inputs['L_stiffener'] = 5.0 * onesec * ft_to_si #self.inputs['section_height'] = 50.0 * onesec0 * ft_to_si self.inputs['pressure'] = (64.0 * lbperft3_to_si) * g * ( 60 * ft_to_si) * onepts self.inputs['E_full'] = 29e3 * ksi_to_si * onesec self.inputs['nu_full'] = 0.3 * onesec self.inputs['sigma_y_full'] = 50 * ksi_to_si * onesec self.inputs['wave_height'] = 0.0 # gives only static pressure self.inputs['stack_mass_in'] = 9000 * kip_to_si / g self.inputs['section_mass'] = 0.0 * np.ones((NPTS - 1, )) self.discrete_inputs['loading'] = 'radial' self.inputs['z_full'] = np.linspace(0, 1, NPTS) self.inputs['z_section'], _ = nodal2sectional(self.inputs['z_full']) self.inputs['z_param'] = np.linspace(0, 1, NHEIGHT) opt = {} opt['gamma_f'] = 1.0 opt['gamma_b'] = 1.0 self.buckle = column.ColumnBuckling(n_height=NHEIGHT, modeling_options=opt)
prob['pre1.rna_F'] = np.array([Fx1, Fy1, Fz1]) prob['pre1.rna_M'] = np.array([Mxx1, Myy1, Mzz1]) # # --------------- # # --- loading case 2: max Wind Speed --- prob['wind2.Uref'] = wind_Uref2 prob['pre2.rna_F'] = np.array([Fx2, Fy2, Fz2]) prob['pre2.rna_M' ] = np.array([Mxx2, Myy2, Mzz2]) # # --- run --- prob.run_driver() z,_ = nodal2sectional(prob['z_full']) print('zs=', z) print('ds=', prob['d_full']) print('ts=', prob['t_full']) print('mass (kg) =', prob['tower_mass']) print('cg (m) =', prob['tower_center_of_mass']) print('weldability =', prob['weldability']) print('manufacturability =', prob['manufacturability']) print('\nwind: ', prob['wind1.Uref']) print('f1 (Hz) =', prob['tower1.f1']) print('top_deflection1 (m) =', prob['post1.top_deflection']) print('stress1 =', prob['post1.stress']) print('GL buckling =', prob['post1.global_buckling']) print('Shell buckling =', prob['post1.shell_buckling']) #print('damage =', prob['post1.damage'])
def compute(self, inputs, outputs): PBEAM = False # Unpack inputs x_ref = inputs['blade_ref_axis'][:,0] # from PS to SS y_ref = inputs['blade_ref_axis'][:,1] # from LE to TE z_ref = inputs['blade_ref_axis'][:,2] # from root to tip r = util.arc_length(inputs['blade_ref_axis']) blade_length = r[-1] theta = inputs['theta'] chord = inputs['chord'] x_sc = inputs['x_sc'] y_sc = inputs['y_sc'] A = inputs['A'] rhoA = inputs['rhoA'] rhoJ = inputs['rhoJ'] GJ = inputs['GJ'] EA = inputs['EA'] EIxx = inputs['EIxx'] # edge (rotation about x) EIyy = inputs['EIyy'] # flap (rotation about y) EIxy = inputs['EIxy'] lateral_clearance = 0.5*inputs['lateral_clearance'][0] vertical_clearance = inputs['vertical_clearance'][0] max_strains = inputs['max_strains'][0] max_rot = inputs['max_root_rot_deg'][0] max_LV = inputs['max_LV'][0] mass_car_4axle = inputs['max_flatcar_weight_4axle'][0] mass_car_8axle = inputs['max_flatcar_weight_8axle'][0] flatcar_tc_length = inputs['flatcar_tc_length'][0] #------- Get turn radius geometry for horizontal and vertical curves # Horizontal turns- defined as a degree of arc assuming a 100ft "chord" # https://trn.trains.com/railroads/ask-trains/2011/01/measuring-track-curvature angleH_rad = np.deg2rad(inputs['horizontal_angle_deg'][0]) r_curveH = spc.foot * 100. /(2.*np.sin(0.5*angleH_rad)) arcsH = r / r_curveH # Vertical curves on hills and sags defined directly by radius r_curveV = inputs['min_vertical_radius'][0] arcsV = r / r_curveV # ---------- #---------- Put airfoil cross sections into principle axes # Determine principal C.S. (with swap of x, y for profile c.s.) EIxx_cs , EIyy_cs = EIyy.copy() , EIxx.copy() x_sc_cs , y_sc_cs = y_sc.copy() , x_sc.copy() EIxy_cs = EIxy.copy() # translate to elastic center EIxx_cs -= y_sc_cs**2 * EA EIyy_cs -= x_sc_cs**2 * EA EIxy_cs -= x_sc_cs * y_sc_cs * EA # get rotation angle alpha = 0.5*np.arctan2(2*EIxy_cs, EIyy_cs-EIxx_cs) # get moments and positions in principal axes EI11 = EIxx_cs - EIxy_cs*np.tan(alpha) EI22 = EIyy_cs + EIxy_cs*np.tan(alpha) ca = np.cos(alpha) sa = np.sin(alpha) def rotate(x,y): x2 = x*ca + y*sa y2 = -x*sa + y*ca return x2, y2 # Now store alpha for later use in degrees alpha = np.rad2deg(alpha) # ------------------- # ---------- Frame3dd blade prep # Nodes: Prep data, but node x,y,z will shift for vertical and horizontal curves rad = np.zeros(self.n_span) # 'radius' of rigidity at node- set to zero inode = 1+np.arange(self.n_span) # Node numbers (will convert to 1-based indexing later) L = np.diff(r) # Reactions: attachment at root ireact = np.array([inode[0]]) rigid = 1e16 pinned = rigid*np.ones(1) reactions = pyframe3dd.ReactionData(ireact, pinned, pinned, pinned, pinned, pinned, pinned, float(rigid)) # Element data ielem = np.arange(1, self.n_span) # Element Numbers N1 = np.arange(1, self.n_span) # Node number start N2 = np.arange(2, self.n_span+1) # Node number finish E = EA / A rho = rhoA / A J = rhoJ / rho G = GJ / J Ix = EIyy / E if PBEAM else EI11 / E Iy = EIxx / E if PBEAM else EI22 / E Asx = Asy = 1e-6*np.ones(ielem.shape) # Unused when shear=False # Have to convert nodal values to find average at center of element Abar,_ = util.nodal2sectional(A) Ebar,_ = util.nodal2sectional(E) rhobar,_ = util.nodal2sectional(rho) Jbar,_ = util.nodal2sectional(J) Gbar,_ = util.nodal2sectional(G) Ixbar,_ = util.nodal2sectional(Ix) Iybar,_ = util.nodal2sectional(Iy) # Angle of element principal axes relative to global coordinate system # Global c.s. is blade with z from root to tip, y from ss to ps, and x from LE to TE (TE points up) # Local element c.s. is airfoil (twist + principle rotation) if PBEAM: roll = np.zeros(theta.shape) else: roll,_ = util.nodal2sectional(theta + alpha) elements = pyframe3dd.ElementData(ielem, N1, N2, Abar, Asx, Asy, Jbar, Ixbar, Iybar, Ebar, Gbar, roll, rhobar) # Frame3dd options: no need for shear, axial stiffening, or higher resolution force calculations options = pyframe3dd.Options(False, False, -1) #----------- #------ Airfoil positions at which to measure strain # Find the cross sectional points furthest from the elastic center at each spanwise location to be used for strain measurement xps = np.zeros(self.n_span) xss = np.zeros(self.n_span) yps = np.zeros(self.n_span) yss = np.zeros(self.n_span) xle = np.zeros(self.n_span) xte = np.zeros(self.n_span) yle = np.zeros(self.n_span) yte = np.zeros(self.n_span) for i in range(self.n_span): ## Rotate the profiles to the blade reference system profile_i = inputs['coord_xy_interp'][i,:,:] profile_i_rot = np.column_stack(util.rotate(inputs['pitch_axis'][i], 0., profile_i[:,0], profile_i[:,1], np.radians(theta[i]))) # normalize profile_i_rot[:,0] -= min(profile_i_rot[:,0]) profile_i_rot = profile_i_rot/ max(profile_i_rot[:,0]) profile_i_rot_precomp = profile_i_rot.copy() idx_s = 0 idx_le_precomp = np.argmax(profile_i_rot_precomp[:,0]) if idx_le_precomp != 0: if profile_i_rot_precomp[0,0] == profile_i_rot_precomp[-1,0]: idx_s = 1 profile_i_rot_precomp = np.row_stack((profile_i_rot_precomp[idx_le_precomp:], profile_i_rot_precomp[idx_s:idx_le_precomp,:])) profile_i_rot_precomp[:,1] -= profile_i_rot_precomp[np.argmin(profile_i_rot_precomp[:,0]),1] # # renormalize profile_i_rot_precomp[:,0] -= min(profile_i_rot_precomp[:,0]) profile_i_rot_precomp = profile_i_rot_precomp/ max(profile_i_rot_precomp[:,0]) if profile_i_rot_precomp[-1,0] != 1.: profile_i_rot_precomp = np.row_stack((profile_i_rot_precomp, profile_i_rot_precomp[0,:])) # 'web' at trailing edge needed for flatback airfoils if profile_i_rot_precomp[0,1] != profile_i_rot_precomp[-1,1] and profile_i_rot_precomp[0,0] == profile_i_rot_precomp[-1,0]: flatback = True else: flatback = False xnode = profile_i_rot_precomp[:,0] xnode_pa = xnode - inputs['pitch_axis'][i] ynode = profile_i_rot_precomp[:,1] theta_rad = theta[i] * np.pi / 180. xnode_no_theta = xnode_pa * np.cos(-theta_rad) - ynode * np.sin(-theta_rad) ynode_no_theta = xnode_pa * np.sin(-theta_rad) + ynode * np.cos(-theta_rad) xnode_dim_no_theta = xnode_no_theta * chord[i] ynode_dim_no_theta = ynode_no_theta * chord[i] xnode_dim = xnode_dim_no_theta * np.cos(theta_rad) - ynode_dim_no_theta * np.sin(theta_rad) ynode_dim = xnode_dim_no_theta * np.sin(theta_rad) + ynode_dim_no_theta * np.cos(theta_rad) yss[i] = max(ynode_dim) - y_sc_cs[i] yps[i] = y_sc_cs[i] - min(ynode_dim) xte[i] = max(xnode_dim) - x_sc_cs[i] xle[i] = x_sc_cs[i] - min(xnode_dim) # Put these sectional points in airfoil principle directions xps_cs, yps_cs = yps, xps xss_cs, yss_cs = yss, xss ps1, ps2 = rotate(xps_cs, yps_cs) ss1, ss2 = rotate(xss_cs, yss_cs) xle_cs, yle_cs = yle, xle xte_cs, yte_cs = yte, xte le1, le2 = rotate(xle_cs, yle_cs) te1, te2 = rotate(xte_cs, yte_cs) #---------------- #-------- Horizontal curve where we select blade support nodes on flat cars # Gravity field orientation gy = -gravity gx = gz = 0.0 # Set clearance boundary r_envelopeH = r_curveH + lateral_clearance*np.array([-1, 1]) # Use blade shape and clearance envelope to determine node position limits r_envelopeH_inner1 = r_envelopeH.min() + yss r_envelopeH_inner2 = r_envelopeH.min() + yps r_envelopeH_outer1 = r_envelopeH.max() - yps r_envelopeH_outer2 = r_envelopeH.max() - yss # Find rotation angles that keep blade within inner boundary # Function that does the structural analysis to be called during optimization def rotate_blade(ang): # Node location starting points when curving towards SS # (towards the LEFT with LE pointed down and standing at the root looking at tip) x_rot1, z_rot1 = util.rotate(r_curveH, 0.0, r_curveH + x_ref, z_ref, ang[0]) # Node location starting points when curving towards PS # (towards the RIGHT with LE pointed down and standing at the root looking at tip) x_rot2, z_rot2 = util.rotate(-r_curveH, 0.0, -r_curveH + x_ref, z_ref, ang[1]) # Check solved blade shape against envelope r_check1 = np.sqrt( x_rot1**2 + z_rot1**2) r_check2 = np.sqrt( x_rot2**2 + z_rot2**2) # Formulate as constraints for SLSQP cboundary = (np.sum( np.maximum(r_envelopeH_inner1 - r_check1, 0.0) ) + np.sum( np.maximum(r_envelopeH_inner2 - r_check2, 0.0) ) ) return -cboundary # Initiliaze scipy minimization to find the right angle- biggest deflection that keeps blade away from inner envelope const = {} const['type'] = 'ineq' const['fun'] = rotate_blade bounds = [np.deg2rad(max_rot)*np.r_[0,1], np.deg2rad(max_rot)*np.r_[-1,0]] x0 = np.deg2rad( max_rot*np.array([1.0, -1.0]) ) result = minimize(lambda x: -np.sum(np.abs(x)), x0, method='slsqp', bounds=bounds, tol=1e-3, constraints=const) # Now rotate blade at optimized angle # Node location starting points when curving towards SS # (towards the LEFT with LE pointed down and standing at the root looking at tip) x_rot1, z_rot1 = util.rotate(r_curveH, 0.0, r_curveH + x_ref, z_ref, result.x[0]) nodes1 = pyframe3dd.NodeData(inode, x_rot1, y_ref, z_rot1, rad) # Node location starting points when curving towards PS # (towards the RIGHT with LE pointed down and standing at the root looking at tip) x_rot2, z_rot2 = util.rotate(-r_curveH, 0.0, -r_curveH + x_ref, z_ref, result.x[1]) nodes2 = pyframe3dd.NodeData(inode, x_rot2, y_ref, z_rot2, rad) # Initialize Frame3dd objects blade1 = pyframe3dd.Frame(nodes1, reactions, elements, options) blade2 = pyframe3dd.Frame(nodes2, reactions, elements, options) # Tolerance for envelop compliance checking tol = 3e-1 # Function that does the structural analysis to be called during optimization def run_hcurve(FrIn, optFlag=True): Fr = FrIn.reshape((self.n_span-1, 2)) # Will only worry about radial loads Fy = Mx = My = Mz = np.zeros(self.n_span-1) # Output containers RF_derailH = np.zeros(2) # Derailment reaction force r_check = np.zeros((self.n_span, 2)) # Envelope constraint strainPS = np.zeros((self.n_span, 2)) strainSS = np.zeros((self.n_span, 2)) # Look over bend to PS/SS cases for k in range(2): if k == 0: blade, r_outer, angs = blade1, r_envelopeH_outer1, arcsH[1:] else: blade, r_outer, angs = blade2, r_envelopeH_outer2, np.pi-arcsH[1:] # Load case: gravity + blade bending to conform to outer boundary load = pyframe3dd.StaticLoadCase(gx, gy, gz) # Put radial loads in x,z plane Fx = -1e4*Fr[:,k]*np.cos(angs) Fz = -1e4*Fr[:,k]*np.sin(angs) load.changePointLoads(inode[1:], Fx, Fy, Fz, Mx, My, Mz) # Add load case to Frame3DD objects and run blade.clearLoadCases() blade.addLoadCase(load) # Run the case displacements, forces, forces_rxn, internalForces, mass, modal = blade.run() # Check solved blade shape against envelope r_check[:,k] = np.sqrt( (blade.nx+displacements.dx[0,:])**2 + (blade.nz+displacements.dz[0,:])**2) - r_outer # Derailing reaction force on root node # - Lateral force on wheels (multiply by 0.5 for 2 wheel sets) # - Moment around axis perpendicular to ground RF_derailH[k] = 0.5*np.sqrt(forces_rxn.Fx**2 + forces_rxn.Fz**2) + np.abs(forces_rxn.Myy)/flatcar_tc_length # Element shear and bending, one per element, which are already in principle directions in Hansen's notation # Zero-ing out axial stress as there shouldn't be any for pure beam bending Fz = np.r_[-forces.Nx[ 0,0], forces.Nx[ 0, 1::2]] M1 = np.r_[-forces.Myy[0,0], forces.Myy[0, 1::2]] M2 = np.r_[ forces.Mzz[0,0], -forces.Mzz[0, 1::2]] if PBEAM: M1,M2 = rotate(M1,M2) # Compute strain at the two points: pressure/suction side extremes strainPS[:,k] = -(M1/EI11*ps2 - M2/EI22*ps1 + Fz/EA) # negative sign because Hansen c3 is opposite of Precomp z strainSS[:,k] = -(M1/EI11*ss2 - M2/EI22*ss1 + Fz/EA) if optFlag: # First constraint is compliance with outer boundary cboundary = np.maximum(r_check, 0) # Second constraint is reaction forces for derailment: crxn = np.maximum(RF_derailH - (0.5 * mass_car_8axle * gravity)/max_LV, 0.0) # Third constraint is keeping the strains reasonable cstrainPS = np.maximum(np.abs(strainPS) - max_strains, 0.0) cstrainSS = np.maximum(np.abs(strainSS) - max_strains, 0.0) # Accumulate constraints cons = np.array([np.sum(cboundary) , np.sum(crxn) , np.sum(cstrainPS) , np.sum(cstrainSS)]) return -cons else: return RF_derailH, strainPS, strainSS # Initiliaze scipy minimization: Minimize force applied that keeps blade within all constraints const = {} const['type'] = 'ineq' const['fun'] = run_hcurve npts = 2*(self.n_span-1) bounds = [(0.0, 1e2)]*npts x0 = 1e2*np.ones(npts) result = minimize(lambda x: np.sum(np.abs(x)), x0, method='slsqp', bounds=bounds, tol=1e-3, constraints=const, options={'maxiter': 100} ) # if result.success: # Evaluate optimized solution RF_derailH, strainPS, strainSS = run_hcurve(result.x, optFlag=False) # Express derailing force as a constraint outputs['constr_LV_4axle_horiz'] = RF_derailH / (0.5 * mass_car_4axle * gravity) / max_LV outputs['constr_LV_8axle_horiz'] = RF_derailH / (0.5 * mass_car_8axle * gravity) / max_LV # Strain constraint outputs outputs['constr_strainPS'] = np.max(np.abs(strainPS) / max_strains, axis = 1) outputs['constr_strainSS'] = np.max(np.abs(strainSS) / max_strains, axis = 1) # else: # outputs['LV_constraint_4axle_horiz'] = 2. # outputs['LV_constraint_8axle_horiz'] = 2. # outputs['constr_strainPS'] = 2. * np.ones([npts,2]) # outputs['constr_strainSS'] = 2. * np.ones([npts,2]) # print('The optimization cannot satisfy the blade rail transport constraints.') '''
def postprocess(prob, towDF, spre='monopile'): z,_ = nodal2sectional(prob['z_full']) print('section_height [m]', prob['tower_section_height']) print('section_diam [m]', prob['tower_outer_diameter']) print('section_thick [m]', prob['tower_wall_thickness']) print('pile depth [m]', prob['suctionpile_depth']) print('zs=', z) print('ds=', prob['d_full']) print('ts=', prob['t_full']) print('mass (kg) =', prob['tower_mass']) print('cg (m) =', prob['tower_center_of_mass']) print('weldability =', prob['weldability']) print('manufacturability =', prob['manufacturability']) print('\nwind: ', prob['wind.Uref']) print('f1 (Hz) =', prob['tower.f1']) print('top_deflection1 (m) =', prob['post.top_deflection']) print('stress1 =', prob['post.stress']) print('GL buckling =', prob['post.global_buckling']) print('Shell buckling =', prob['post.shell_buckling']) print(prob['tower.base_F']) print(prob['tower.base_M']) ''' stress1 = np.copy( prob['post.stress'] ) shellBuckle1 = np.copy( prob['post.shell_buckling'] ) globalBuckle1 = np.copy( prob['post.global_buckling'] ) import matplotlib.pyplot as plt fig = plt.figure(1) ax1 = fig.add_subplot(121) ax2 = fig.add_subplot(122) ax1.plot(stress1, z, label='stress 1') ax1.plot(shellBuckle1, z, label='shell buckling 1') ax1.plot(globalBuckle1, z, label='global buckling 1') ax1.legend(bbox_to_anchor=(1.05, 1.0), loc=2) ax1.set_xlabel('utilization') ax1.set_ylabel('height along tower (m)') ax2.plot(prob['d_full']/2.+max(prob['d_full']), prob['z_full'], 'ok') ax2.plot(prob['d_full']/-2.+max(prob['d_full']), prob['z_full'], 'ok') plt.show() ''' # Outputs from tower diameter-thickness schedule A = 0.25*np.pi*(towDF['OD [m]']**2 - (towDF['OD [m]']-2*1e-3*towDF['Thickness [mm]'])**2) I = (1/64.)*np.pi*(towDF['OD [m]']**4 - (towDF['OD [m]']-2*1e-3*towDF['Thickness [mm]'])**4) towDF['Mass Density [kg/m]'] = prob['material_density'] * A towDF['Fore-aft inertia [kg.m]'] = towDF['Mass Density [kg/m]'] * I/A towDF['Side-side inertia [kg.m]'] = towDF['Mass Density [kg/m]'] * I/A towDF['Fore-aft stiffness [N.m^2]'] = prob['E'] * I towDF['Side-side stiffness [N.m^2]'] = prob['E'] * I towDF['Torsional stiffness [N.m^2]'] = prob['G'] * 2*I towDF['Axial stiffness [N]'] = prob['E'] * A towDF.to_csv(folder_output + os.sep + spre+'_tower.csv', index=False) def format_save(fig, fig_name): plt.xticks(fontsize=12) plt.yticks(fontsize=12) plt.grid(color=[0.8,0.8,0.8], linestyle='--') plt.subplots_adjust(bottom = 0.15, left = 0.15) fig.savefig(folder_output + os.sep + fig_name+'.pdf', pad_inches=0.1, bbox_inches='tight') fig.savefig(folder_output + os.sep + fig_name+'.png', pad_inches=0.1, bbox_inches='tight') # Tower stiffness plots figsize=(5.3, 4) fig = plt.figure(figsize=figsize) fig.clf() ax = fig.add_subplot(111) ax.plot(towDF['Height [m]'], towDF['Mass Density [kg/m]'], linewidth=2) plt.xlabel('Location [m]', fontsize=14, fontweight='bold') plt.ylabel('Mass Density [kg/m]', fontsize=14, fontweight='bold') fig_name = spre+'_massdens' format_save(fig, fig_name) fig.clf() ax = fig.add_subplot(111) ax.plot(towDF['Height [m]'], towDF['Fore-aft inertia [kg.m]'], linewidth=2) plt.xlabel('Location [m]', fontsize=14, fontweight='bold') plt.ylabel('Fore-aft/side-side inertia [kg.m]', fontsize=14, fontweight='bold') fig_name = spre+'_foreaft_sideside-inertia' format_save(fig, fig_name) fig.clf() ax = fig.add_subplot(111) ax.plot(towDF['Height [m]'], towDF['Fore-aft stiffness [N.m^2]'], linewidth=2) ax.plot(towDF['Height [m]'], towDF['Torsional stiffness [N.m^2]'], linewidth=2) ax.legend(('Fore-aft/side-side','Torsional'), loc='best') plt.xlabel('Location [m]', fontsize=14, fontweight='bold') plt.ylabel('Stiffness [N.m^2]', fontsize=14, fontweight='bold') fig_name = spre+'_stiffness' format_save(fig, fig_name) fig.clf() ax = fig.add_subplot(111) ax.plot(towDF['Height [m]'], towDF['Axial stiffness [N]'], linewidth=2) plt.xlabel('Location [m]', fontsize=14, fontweight='bold') plt.ylabel('Axial Stiffness [N]', fontsize=14, fontweight='bold') fig_name = spre+'_axial_stiffness' format_save(fig, fig_name)
def setUp(self): self.inputs = {} self.outputs = {} self.resid = None # For Geometry call this_nheight = 3 this_npts = column.get_nfull(this_nheight) this_sec = np.ones(this_npts - 1) this_ones = np.ones(this_npts) self.inputs['z_full_in'] = np.linspace(0, 50.0, this_npts) self.inputs['z_section'], _ = nodal2sectional(self.inputs['z_full_in']) self.inputs['z_param_in'] = np.array([0.0, 20.0, 50.0]) self.inputs['section_height'] = np.array([20.0, 30.0]) self.inputs['freeboard'] = 15.0 self.inputs['fairlead'] = 10.0 self.inputs['water_depth'] = 100.0 self.inputs['hsig_wave'] = 5.0 self.inputs['max_draft'] = 70.0 self.inputs['t_full'] = 0.5 * this_sec self.inputs['d_full'] = 2 * 10.0 * this_ones self.inputs['stack_mass_in'] = 0.0 self.inputs['shell_I_keel'] = 1e5 * np.array( [1.0, 1.0, 1.0, 0.0, 0.0, 0.0]) self.inputs['stiffener_I_keel'] = 2e5 * np.array( [1.0, 1.0, 1.0, 0.0, 0.0, 0.0]) self.inputs['bulkhead_I_keel'] = 3e5 * np.array( [1.0, 1.0, 1.0, 0.0, 0.0, 0.0]) self.inputs['buoyancy_tank_I_keel'] = 5e6 * np.array( [1.0, 1.0, 1.0, 0.0, 0.0, 0.0]) self.inputs['ballast_I_keel'] = 2e3 * np.array( [1.0, 1.0, 1.0, 0.0, 0.0, 0.0]) self.inputs['buoyancy_tank_diameter'] = 15.0 self.inputs['rho_water'] = 1e3 self.inputs['bulkhead_mass'] = 10.0 * this_sec self.inputs['bulkhead_z_cg'] = -10.0 self.inputs['shell_mass'] = 500.0 * this_sec self.inputs['stiffener_mass'] = 100.0 * this_sec self.inputs['ballast_mass'] = 20.0 * this_sec self.inputs['ballast_z_cg'] = -35.0 self.inputs['buoyancy_tank_mass'] = 20.0 self.inputs['buoyancy_tank_cg'] = -15.0 self.inputs['buoyancy_tank_location'] = 0.3 self.inputs['buoyancy_tank_displacement'] = 300.0 self.inputs['outfitting_factor'] = 1.05 self.inputs['shell_cost'] = 1.0 self.inputs['stiffener_cost'] = 2.0 self.inputs['bulkhead_cost'] = 3.0 self.inputs['buoyancy_tank_cost'] = 4.0 self.inputs['ballast_cost'] = 5.0 self.inputs['mooring_mass'] = 50.0 self.inputs['mooring_vertical_load'] = 25.0 self.inputs['mooring_restoring_force'] = 1e5 self.inputs['mooring_cost'] = 1e4 self.inputs['outfitting_cost_rate'] = 1.0 self.inputs['unit_cost'] = 1.0 * np.ones(2) self.inputs['E'] = 2e9 * np.ones(2) self.inputs['G'] = 2e7 * np.ones(2) self.inputs['rho'] = 7850 * np.ones(2) self.inputs['sigma_y'] = 3e9 * np.ones(2) self.inputs['stiffener_web_thickness'] = np.array([0.5, 0.5]) self.inputs['stiffener_flange_thickness'] = np.array([0.3, 0.3]) self.inputs['stiffener_web_height'] = np.array([1.0, 1.0]) self.inputs['stiffener_flange_width'] = np.array([2.0, 2.0]) self.inputs['stiffener_spacing'] = np.array([0.1, 0.1]) self.geom = column.ColumnGeometry(n_height=this_nheight) self.set_geometry() self.mycolumn = column.ColumnProperties(n_height=this_nheight)