예제 #1
0
def write_vsp_turbofan(turbofan, OML_set_ind):
    """This converts turbofans into OpenVSP format.
    
    Assumptions:
    None

    Source:
    N/A

    Inputs:
    turbofan.
      number_of_engines                       [-]
      engine_length                           [m]
      nacelle_diameter                        [m]
      origin                                  [m] in all three dimension, should have as many origins as engines
      OpenVSP_flow_through                    <boolean> if True create a flow through nacelle, if False create a cylinder

    Outputs:
    Operates on the active OpenVSP model, no direct output

    Properties Used:
    N/A
    """    
    n_engines   = turbofan.number_of_engines
    length      = turbofan.engine_length
    width       = turbofan.nacelle_diameter
    origins     = turbofan.origin
    inlet_width = turbofan.inlet_diameter
    tf_tag      = turbofan.tag
    
    # True will create a flow-through subsonic nacelle (which may have dimensional errors)
    # False will create a cylindrical stack (essentially a cylinder)
    ft_flag = turbofan.OpenVSP_flow_through
    
    import operator # import here since engines are not always needed
    # sort engines per left to right convention
    origins_sorted = sorted(origins, key=operator.itemgetter(1))
    
    for ii in range(0,int(n_engines)):

        origin = origins_sorted[ii]
        
        x = origin[0]
        y = origin[1]
        z = origin[2]
        
        if ft_flag == True:
            nac_id = vsp.AddGeom( "BODYOFREVOLUTION")
            vsp.SetGeomName(nac_id, tf_tag+'_'+str(ii+1))
            
            # Origin
            vsp.SetParmVal(nac_id,'X_Location','XForm',x)
            vsp.SetParmVal(nac_id,'Y_Location','XForm',y)
            vsp.SetParmVal(nac_id,'Z_Location','XForm',z)
            vsp.SetParmVal(nac_id,'Abs_Or_Relitive_flag','XForm',vsp.ABS) # misspelling from OpenVSP  
            
            # Length and overall diameter
            vsp.SetParmVal(nac_id,"Diameter","Design",inlet_width)
            
            vsp.ChangeBORXSecShape(nac_id ,vsp.XS_SUPER_ELLIPSE)
            vsp.Update()
            vsp.SetParmVal(nac_id, "Super_Height", "XSecCurve", (width-inlet_width)/2)
            vsp.SetParmVal(nac_id, "Super_Width", "XSecCurve", length)
            vsp.SetParmVal(nac_id, "Super_MaxWidthLoc", "XSecCurve", -1.)
            vsp.SetParmVal(nac_id, "Super_M", "XSecCurve", 2.)
            vsp.SetParmVal(nac_id, "Super_N", "XSecCurve", 1.)             
            
        else:
            nac_id = vsp.AddGeom("STACK")
            vsp.SetGeomName(nac_id, tf_tag+'_'+str(ii+1))
            
            # Origin
            vsp.SetParmVal(nac_id,'X_Location','XForm',x)
            vsp.SetParmVal(nac_id,'Y_Location','XForm',y)
            vsp.SetParmVal(nac_id,'Z_Location','XForm',z)
            vsp.SetParmVal(nac_id,'Abs_Or_Relitive_flag','XForm',vsp.ABS) # misspelling from OpenVSP
            vsp.SetParmVal(nac_id,'Origin','XForm',0.5)            
            
            vsp.CutXSec(nac_id,2) # remove extra default subsurface
            xsecsurf = vsp.GetXSecSurf(nac_id,0)
            vsp.ChangeXSecShape(xsecsurf,1,vsp.XS_CIRCLE)
            vsp.ChangeXSecShape(xsecsurf,2,vsp.XS_CIRCLE)
            vsp.Update()
            vsp.SetParmVal(nac_id, "Circle_Diameter", "XSecCurve_1", width)
            vsp.SetParmVal(nac_id, "Circle_Diameter", "XSecCurve_2", width)
            vsp.SetParmVal(nac_id, "XDelta", "XSec_1", 0)
            vsp.SetParmVal(nac_id, "XDelta", "XSec_2", length)
            vsp.SetParmVal(nac_id, "XDelta", "XSec_3", 0)
            
        vsp.SetSetFlag(nac_id, OML_set_ind, True)
        
        vsp.Update()
예제 #2
0
def write_vsp_fuselage(fuselage,area_tags, main_wing, fuel_tank_set_ind, OML_set_ind):
    """This writes a fuselage into OpenVSP format.
    
    Assumptions:
    None

    Source:
    N/A

    Inputs:
    fuselage
      width                                   [m]
      lengths.total                           [m]
      heights.
        maximum                               [m]
        at_quarter_length                     [m]
        at_wing_root_quarter_chord            [m]
        at_three_quarters_length              [m]
      effective_diameter                      [m]
      fineness.nose                           [-] ratio of nose section length to fuselage width
      fineness.tail                           [-] ratio of tail section length to fuselage width
      tag                                     <string>
      OpenVSP_values.  (optional)
        nose.top.angle                        [degrees]
        nose.top.strength                     [-] this determines how much the specified angle influences that shape
        nose.side.angle                       [degrees]
        nose.side.strength                    [-]
        nose.TB_Sym                           <boolean> determines if top angle is mirrored on bottom
        nose.z_pos                            [-] z position of the nose as a percentage of fuselage length (.1 is 10%)
        tail.top.angle                        [degrees]
        tail.top.strength                     [-]
        tail.z_pos (optional, 0.02 default)   [-] z position of the tail as a percentage of fuselage length (.1 is 10%)
      Segments. (optional)
        width                                 [m]
        height                                [m]
        percent_x_location                    [-] .1 is 10% length
        percent_z_location                    [-] .1 is 10% length
    area_tags                                 <dict> used to keep track of all tags needed in wetted area computation           
    main_wing.origin                          [m]
    main_wing.chords.root                     [m]
    fuel_tank_set_index                       <int> OpenVSP object set containing the fuel tanks    

    Outputs:
    Operates on the active OpenVSP model, no direct output

    Properties Used:
    N/A
    """     
    
    num_segs           = len(fuselage.Segments)
    length             = fuselage.lengths.total
    fuse_x             = fuselage.origin[0][0]    
    fuse_y             = fuselage.origin[0][1]
    fuse_z             = fuselage.origin[0][2]
    fuse_x_rotation    = fuselage.x_rotation   
    fuse_y_rotation    = fuselage.y_rotation
    fuse_z_rotation    = fuselage.z_rotation    
    if num_segs==0: # SUAVE default fuselage shaping
    
        width    = fuselage.width
        hmax     = fuselage.heights.maximum
        height1  = fuselage.heights.at_quarter_length
        height2  = fuselage.heights.at_wing_root_quarter_chord 
        height3  = fuselage.heights.at_three_quarters_length
        effdia   = fuselage.effective_diameter
        n_fine   = fuselage.fineness.nose 
        t_fine   = fuselage.fineness.tail  
        
        try:
            if main_wing != None:                
                w_origin = main_wing.origin
                w_c_4    = main_wing.chords.root/4.
            else:
                w_origin = 0.5*length
                w_c_4    = 0.5*length
        except AttributeError:
            raise AttributeError('Main wing not detected. Fuselage must have specified sections in this configuration.')
        
        # Figure out the location x location of each section, 3 sections, end of nose, wing origin, and start of tail
        
        x1 = n_fine*width/length
        x2 = (w_origin[0][0]+w_c_4)/length
        x3 = 1-t_fine*width/length
        
        end_ind = 4
        
    else: # Fuselage shaping based on sections
        widths  = []
        heights = []
        x_poses = []
        z_poses = []
        segs = fuselage.Segments
        for seg in segs:
            widths.append(seg.width)
            heights.append(seg.height)
            x_poses.append(seg.percent_x_location)
            z_poses.append(seg.percent_z_location)
            
        end_ind = num_segs-1
    
    fuse_id = vsp.AddGeom("FUSELAGE") 
    vsp.SetGeomName(fuse_id, fuselage.tag)
    area_tags[fuselage.tag] = ['fuselages',fuselage.tag]

    tail_z_pos = 0.02 # default value

    # set fuselage relative location and rotation
    vsp.SetParmVal( fuse_id,'X_Rel_Rotation','XForm',fuse_x_rotation)
    vsp.SetParmVal( fuse_id,'Y_Rel_Rotation','XForm',fuse_y_rotation)
    vsp.SetParmVal( fuse_id,'Z_Rel_Rotation','XForm',fuse_z_rotation)
    
    vsp.SetParmVal( fuse_id,'X_Rel_Location','XForm',fuse_x)
    vsp.SetParmVal( fuse_id,'Y_Rel_Location','XForm',fuse_y)
    vsp.SetParmVal( fuse_id,'Z_Rel_Location','XForm',fuse_z)


    if 'OpenVSP_values' in fuselage:        
        vals = fuselage.OpenVSP_values

        # for wave drag testing
        fuselage.OpenVSP_ID = fuse_id
        
        # Nose
        vsp.SetParmVal(fuse_id,"TopLAngle","XSec_0",vals.nose.top.angle)
        vsp.SetParmVal(fuse_id,"TopLStrength","XSec_0",vals.nose.top.strength)
        vsp.SetParmVal(fuse_id,"RightLAngle","XSec_0",vals.nose.side.angle)
        vsp.SetParmVal(fuse_id,"RightLStrength","XSec_0",vals.nose.side.strength)
        vsp.SetParmVal(fuse_id,"TBSym","XSec_0",vals.nose.TB_Sym)
        vsp.SetParmVal(fuse_id,"ZLocPercent","XSec_0",vals.nose.z_pos)
        if not vals.nose.TB_Sym:
            vsp.SetParmVal(fuse_id,"BottomLAngle","XSec_0",vals.nose.bottom.angle)
            vsp.SetParmVal(fuse_id,"BottomLStrength","XSec_0",vals.nose.bottom.strength)           

        # Tail
        # Below can be enabled if AllSym (below) is removed
        #vsp.SetParmVal(fuse_id,"RightLAngle","XSec_4",vals.tail.side.angle)
        #vsp.SetParmVal(fuse_id,"RightLStrength","XSec_4",vals.tail.side.strength)
        #vsp.SetParmVal(fuse_id,"TBSym","XSec_4",vals.tail.TB_Sym)
        #vsp.SetParmVal(fuse_id,"BottomLAngle","XSec_4",vals.tail.bottom.angle)
        #vsp.SetParmVal(fuse_id,"BottomLStrength","XSec_4",vals.tail.bottom.strength)
        if 'z_pos' in vals.tail:
            tail_z_pos = vals.tail.z_pos
        else:
            pass # use above default


    if num_segs == 0:
        vsp.SetParmVal(fuse_id,"Length","Design",length)
        vsp.SetParmVal(fuse_id,"Diameter","Design",width)
        vsp.SetParmVal(fuse_id,"XLocPercent","XSec_1",x1)
        vsp.SetParmVal(fuse_id,"XLocPercent","XSec_2",x2)
        vsp.SetParmVal(fuse_id,"XLocPercent","XSec_3",x3)
        vsp.SetParmVal(fuse_id,"ZLocPercent","XSec_4",tail_z_pos)
        vsp.SetParmVal(fuse_id, "Ellipse_Width", "XSecCurve_1", width)
        vsp.SetParmVal(fuse_id, "Ellipse_Width", "XSecCurve_2", width)
        vsp.SetParmVal(fuse_id, "Ellipse_Width", "XSecCurve_3", width)
        vsp.SetParmVal(fuse_id, "Ellipse_Height", "XSecCurve_1", height1);
        vsp.SetParmVal(fuse_id, "Ellipse_Height", "XSecCurve_2", height2);
        vsp.SetParmVal(fuse_id, "Ellipse_Height", "XSecCurve_3", height3);  
    else:
        # OpenVSP vals do not exist:
        vals                   = Data()
        vals.nose              = Data()
        vals.tail              = Data()
        vals.tail.top          = Data()
        
        vals.nose.z_pos        = 0.0
        vals.tail.top.angle    = 0.0
        vals.tail.top.strength = 0.0
        
        if len(np.unique(x_poses)) != len(x_poses):
            raise ValueError('Duplicate fuselage section positions detected.')
        vsp.SetParmVal(fuse_id,"Length","Design",length)
        if num_segs != 5: # reduce to only nose and tail
            vsp.CutXSec(fuse_id,1) # remove extra default section
            vsp.CutXSec(fuse_id,1) # remove extra default section
            vsp.CutXSec(fuse_id,1) # remove extra default section
            for i in range(num_segs-2): # add back the required number of sections
                vsp.InsertXSec(fuse_id, 0, vsp.XS_ELLIPSE)           
                vsp.Update()
        for i in range(num_segs-2):
            # Bunch sections to allow proper length settings in the next step
            # This is necessary because OpenVSP will not move a section past an adjacent section
            vsp.SetParmVal(fuse_id, "XLocPercent", "XSec_"+str(i+1),1e-6*(i+1))
            vsp.Update()
        if x_poses[1] < (num_segs-2)*1e-6:
            print('Warning: Second fuselage section is too close to the nose. OpenVSP model may not be accurate.')
        for i in reversed(range(num_segs-2)):
            # order is reversed because sections are initially bunched in the front and cannot be extended passed the next
            vsp.SetParmVal(fuse_id, "XLocPercent", "XSec_"+str(i+1),x_poses[i+1])
            vsp.SetParmVal(fuse_id, "ZLocPercent", "XSec_"+str(i+1),z_poses[i+1])
            vsp.SetParmVal(fuse_id, "Ellipse_Width", "XSecCurve_"+str(i+1), widths[i+1])
            vsp.SetParmVal(fuse_id, "Ellipse_Height", "XSecCurve_"+str(i+1), heights[i+1])   
            vsp.Update()             
            set_section_angles(i, vals.nose.z_pos, tail_z_pos, x_poses, z_poses, heights, widths,length,end_ind,fuse_id)            
            
        vsp.SetParmVal(fuse_id, "XLocPercent", "XSec_"+str(0),x_poses[0])
        vsp.SetParmVal(fuse_id, "ZLocPercent", "XSec_"+str(0),z_poses[0])
        vsp.SetParmVal(fuse_id, "XLocPercent", "XSec_"+str(end_ind),x_poses[-1])
        vsp.SetParmVal(fuse_id, "ZLocPercent", "XSec_"+str(end_ind),z_poses[-1])    
        
        # Tail
        if heights[-1] > 0.:
            stdout = vsp.cvar.cstdout
            errorMgr = vsp.ErrorMgrSingleton_getInstance()
            errorMgr.PopErrorAndPrint(stdout)
            
            pos = len(heights)-1
            vsp.InsertXSec(fuse_id, pos-1, vsp.XS_ELLIPSE)
            vsp.Update()
            vsp.SetParmVal(fuse_id, "Ellipse_Width", "XSecCurve_"+str(pos), widths[-1])
            vsp.SetParmVal(fuse_id, "Ellipse_Height", "XSecCurve_"+str(pos), heights[-1])
            vsp.SetParmVal(fuse_id, "XLocPercent", "XSec_"+str(pos),x_poses[-1])
            vsp.SetParmVal(fuse_id, "ZLocPercent", "XSec_"+str(pos),z_poses[-1])              
            
            xsecsurf = vsp.GetXSecSurf(fuse_id,0)
            vsp.ChangeXSecShape(xsecsurf,pos+1,vsp.XS_POINT)
            vsp.Update()           
            vsp.SetParmVal(fuse_id, "XLocPercent", "XSec_"+str(pos+1),x_poses[-1])
            vsp.SetParmVal(fuse_id, "ZLocPercent", "XSec_"+str(pos+1),z_poses[-1])     
            
            # update strengths to make end flat
            vsp.SetParmVal(fuse_id,"TopRStrength","XSec_"+str(pos), 0.)
            vsp.SetParmVal(fuse_id,"RightRStrength","XSec_"+str(pos), 0.)
            vsp.SetParmVal(fuse_id,"BottomRStrength","XSec_"+str(pos), 0.)
            vsp.SetParmVal(fuse_id,"TopLStrength","XSec_"+str(pos+1), 0.)
            vsp.SetParmVal(fuse_id,"RightLStrength","XSec_"+str(pos+1), 0.)            
        
        else:
            vsp.SetParmVal(fuse_id,"TopLAngle","XSec_"+str(end_ind),vals.tail.top.angle)
            vsp.SetParmVal(fuse_id,"TopLStrength","XSec_"+str(end_ind),vals.tail.top.strength)
            vsp.SetParmVal(fuse_id,"AllSym","XSec_"+str(end_ind),1)
            vsp.Update()
            
            
        if 'z_pos' in vals.tail:
            tail_z_pos = vals.tail.z_pos
        else:
            pass # use above default         
    
    if 'Fuel_Tanks' in fuselage:
        for tank in fuselage.Fuel_Tanks:
            write_fuselage_conformal_fuel_tank(fuse_id, tank, fuel_tank_set_ind)    
            
    vsp.SetSetFlag(fuse_id, OML_set_ind, True)
                
    return area_tags
예제 #3
0
def write_vsp_nacelle(nacelle, OML_set_ind):
    """This converts nacelles into OpenVSP format.
    
    Assumptions: 
    1. If nacelle segments are defined, geometry written to OpenVSP is of type "StackGeom". 
       1.a  This type of nacelle can be either set as flow through or not flow through.
       1.b  Segments are defined in a similar manner to fuselage segments. See geometric 
            documentation in SUAVE-Components-Nacelles-Nacelle
    
    2. If nacelle segments are not defined, geometry written to OpenVSP is of type "BodyofRevolution".
       2.a This type of nacelle can be either set as flow through or not flow through.
       2.b BodyofRevolution can be either be a 4 digit airfoil (type string) or super ellipse (default)
    Source:
    N/A
    Inputs: 
      nacelle.
      origin                              [m] in all three dimension, should have as many origins as engines 
      length                              [m]
      diameter                            [m]
      flow_through                        <boolean> if True create a flow through nacelle, if False create a cylinder
      segment(optional).
         width                            [m]
         height                           [m]
         lenght                           [m]
         percent_x_location               [m]     
         percent_y_location               [m]        
         percent_z_location               [m] 
       
    Outputs:
    Operates on the active OpenVSP model, no direct output
    Properties Used:
    N/A
    """
    # default tesselation
    radial_tesselation = 21
    axial_tesselation = 25

    # True will create a flow-through subsonic nacelle (which may have dimensional errors)
    # False will create a cylindrical stack (essentially a cylinder)
    ft_flag = nacelle.flow_through
    length = nacelle.length
    height = nacelle.diameter - nacelle.inlet_diameter
    diameter = nacelle.diameter - height / 2
    nac_tag = nacelle.tag
    nac_x = nacelle.origin[0][0]
    nac_y = nacelle.origin[0][1]
    nac_z = nacelle.origin[0][2]
    nac_x_rotation = nacelle.orientation_euler_angles[0] / Units.degrees
    nac_y_rotation = nacelle.orientation_euler_angles[1] / Units.degrees
    nac_z_rotation = nacelle.orientation_euler_angles[2] / Units.degrees
    num_segs = len(nacelle.Segments)

    if num_segs > 0:
        if nacelle.Airfoil.naca_4_series_airfoil != None:
            raise AssertionError(
                'Nacelle segments defined. Airfoil section will not be used.')
        nac_id = vsp.AddGeom("STACK")
        vsp.SetGeomName(nac_id, nac_tag)

        # set nacelle relative location and rotation
        vsp.SetParmVal(nac_id, 'Abs_Or_Relitive_flag', 'XForm', vsp.ABS)
        vsp.SetParmVal(nac_id, 'X_Rotation', 'XForm', nac_x_rotation)
        vsp.SetParmVal(nac_id, 'Y_Rotation', 'XForm', nac_y_rotation)
        vsp.SetParmVal(nac_id, 'Z_Rotation', 'XForm', nac_z_rotation)
        vsp.SetParmVal(nac_id, 'X_Location', 'XForm', nac_x)
        vsp.SetParmVal(nac_id, 'Y_Location', 'XForm', nac_y)
        vsp.SetParmVal(nac_id, 'Z_Location', 'XForm', nac_z)
        vsp.SetParmVal(nac_id, 'Tess_U', 'Shape', radial_tesselation)
        vsp.SetParmVal(nac_id, 'Tess_W', 'Shape', axial_tesselation)

        widths = []
        heights = []
        x_delta = []
        x_poses = []
        z_delta = []

        segs = nacelle.Segments
        for seg in range(num_segs):
            widths.append(segs[seg].width)
            heights.append(segs[seg].height)
            x_poses.append(segs[seg].percent_x_location)
            if seg == 0:
                x_delta.append(0)
                z_delta.append(0)
            else:
                x_delta.append(length * (segs[seg].percent_x_location -
                                         segs[seg - 1].percent_x_location))
                z_delta.append(length * (segs[seg].percent_z_location -
                                         segs[seg - 1].percent_z_location))

        vsp.CutXSec(nac_id, 4)  # remove point section at end
        vsp.CutXSec(nac_id, 0)  # remove point section at beginning
        vsp.CutXSec(nac_id, 1)  # remove point section at beginning
        for _ in range(num_segs -
                       2):  # add back the required number of sections
            vsp.InsertXSec(nac_id, 1, vsp.XS_ELLIPSE)
            vsp.Update()
        xsec_surf = vsp.GetXSecSurf(nac_id, 0)
        for i3 in reversed(range(num_segs)):
            xsec = vsp.GetXSec(xsec_surf, i3)
            if i3 == 0:
                pass
            else:
                vsp.SetParmVal(nac_id, "XDelta", "XSec_" + str(i3),
                               x_delta[i3])
                vsp.SetParmVal(nac_id, "ZDelta", "XSec_" + str(i3),
                               z_delta[i3])
            vsp.SetXSecWidthHeight(xsec, widths[i3], heights[i3])
            vsp.SetXSecTanAngles(xsec, vsp.XSEC_BOTH_SIDES, 0, 0, 0, 0)
            vsp.SetXSecTanSlews(xsec, vsp.XSEC_BOTH_SIDES, 0, 0, 0, 0)
            vsp.SetXSecTanStrengths(xsec, vsp.XSEC_BOTH_SIDES, 0, 0, 0, 0)
            vsp.Update()

        if ft_flag:
            pass
        else:
            # append front point
            xsecsurf = vsp.GetXSecSurf(nac_id, 0)
            vsp.ChangeXSecShape(xsecsurf, 0, vsp.XS_POINT)
            vsp.Update()
            xsecsurf = vsp.GetXSecSurf(nac_id, 0)
            vsp.ChangeXSecShape(xsecsurf, num_segs - 1, vsp.XS_POINT)
            vsp.Update()

    else:
        nac_id = vsp.AddGeom("BODYOFREVOLUTION")
        vsp.SetGeomName(nac_id, nac_tag)

        # Origin
        vsp.SetParmVal(nac_id, 'Abs_Or_Relitive_flag', 'XForm', vsp.ABS)
        vsp.SetParmVal(nac_id, 'X_Rotation', 'XForm', nac_x_rotation)
        vsp.SetParmVal(nac_id, 'Y_Rotation', 'XForm', nac_y_rotation)
        vsp.SetParmVal(nac_id, 'Z_Rotation', 'XForm', nac_z_rotation)
        vsp.SetParmVal(nac_id, 'X_Location', 'XForm', nac_x)
        vsp.SetParmVal(nac_id, 'Y_Location', 'XForm', nac_y)
        vsp.SetParmVal(nac_id, 'Z_Location', 'XForm', nac_z)
        vsp.SetParmVal(nac_id, 'Tess_U', 'Shape', radial_tesselation)
        vsp.SetParmVal(nac_id, 'Tess_W', 'Shape', axial_tesselation)

        # Length and overall diameter
        vsp.SetParmVal(nac_id, "Diameter", "Design", diameter)
        if ft_flag:
            vsp.SetParmVal(nac_id, "Mode", "Design", 0.0)
        else:
            vsp.SetParmVal(nac_id, "Mode", "Design", 1.0)

        if nacelle.Airfoil.naca_4_series_airfoil != None:
            if isinstance(
                    nacelle.Airfoil.naca_4_series_airfoil,
                    str) and len(nacelle.Airfoil.naca_4_series_airfoil) != 4:
                raise AssertionError(
                    'Nacelle cowling airfoil must be of type < string > and length < 4 >'
                )
            else:
                angle = nacelle.cowling_airfoil_angle / Units.degrees
                camber = float(nacelle.Airfoil.naca_4_series_airfoil[0]) / 100
                camber_loc = float(
                    nacelle.Airfoil.naca_4_series_airfoil[1]) / 10
                thickness = float(
                    nacelle.Airfoil.naca_4_series_airfoil[2:]) / 100

                vsp.ChangeBORXSecShape(nac_id, vsp.XS_FOUR_SERIES)
                vsp.Update()
                vsp.SetParmVal(nac_id, "Diameter", "Design", diameter)
                vsp.SetParmVal(nac_id, "Angle", "Design", angle)
                vsp.SetParmVal(nac_id, "Chord", "XSecCurve", length)
                vsp.SetParmVal(nac_id, "ThickChord", "XSecCurve", thickness)
                vsp.SetParmVal(nac_id, "Camber", "XSecCurve", camber)
                vsp.SetParmVal(nac_id, "CamberLoc", "XSecCurve", camber_loc)
                vsp.Update()
        else:
            vsp.ChangeBORXSecShape(nac_id, vsp.XS_SUPER_ELLIPSE)
            vsp.Update()
            if ft_flag:
                vsp.SetParmVal(nac_id, "Super_Height", "XSecCurve", height)
                vsp.SetParmVal(nac_id, "Diameter", "Design", diameter)
            else:
                vsp.SetParmVal(nac_id, "Super_Height", "XSecCurve", diameter)
            vsp.SetParmVal(nac_id, "Super_Width", "XSecCurve", length)
            vsp.SetParmVal(nac_id, "Super_MaxWidthLoc", "XSecCurve", 0.)
            vsp.SetParmVal(nac_id, "Super_M", "XSecCurve", 2.)
            vsp.SetParmVal(nac_id, "Super_N", "XSecCurve", 1.)

    vsp.SetSetFlag(nac_id, OML_set_ind, True)

    vsp.Update()
    return