Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
    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'])
Exemplo n.º 3
0
    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.')

        
        '''
Exemplo n.º 4
0
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)
Exemplo n.º 5
0
    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)