Source code for aerosandbox.geometry.openvsp_io.asb_to_openvsp.fuselage_vspscript_generator

import aerosandbox.numpy as np
from aerosandbox.geometry.fuselage import Fuselage, FuselageXSec
from textwrap import indent, dedent
from aerosandbox.geometry.openvsp_io.asb_to_openvsp import _utilities


[docs]def generate_fuselage( fuselage: Fuselage, include_main=True, continuity_type: str = "C2", ) -> str: """ Generates a VSPScript file for a Fuselage object. Args: fuselage: The Fuselage object to generate a VSPScript file for. Returns: A VSPScript file as a string. """ script = "" script += f"""\ //==== Add Fuselage "{fuselage.name}" ====// string fid = AddGeom("FUSELAGE"); ChangeXSecShape( GetXSecSurf( fid, 0 ), 0, XS_SUPER_ELLIPSE ); ChangeXSecShape( GetXSecSurf( fid, 4 ), 4, XS_SUPER_ELLIPSE ); """ script += """//==== Generate Blank Fuselage Sections ====//\n""" if len(fuselage.xsecs) < 2: raise ValueError("Fuselages must have at least 2 cross sections.") else: script += f"""\ SetParmVal( fid, "XLocPercent", "XSec_3", 1.0 ); // Causes all sections to be generated at x/L = 1, so they don't conflict """ for i in range(len(fuselage.xsecs) - 1): script += f"""\ InsertXSec( fid, 3, XS_SUPER_ELLIPSE ); // FuselageXSecs {i} to {i + 1} """ length = fuselage.xsecs[-1].xyz_c[0] - fuselage.xsecs[0].xyz_c[0] script += f"""\ //===== Cut The Original Section =====// CutXSec( fid, 0 ); CutXSec( fid, 0 ); CutXSec( fid, 0 ); CutXSec( fid, 0 ); //==== Set Overall Fuselage Options and First Section ====// SetParmVal( fid, "X_Rel_Location", "XForm", {fuselage.xsecs[0].xyz_c[0]} ); SetParmVal( fid, "Y_Rel_Location", "XForm", {fuselage.xsecs[0].xyz_c[1]} ); SetParmVal( fid, "Z_Rel_Location", "XForm", {fuselage.xsecs[0].xyz_c[2]} ); SetParmVal( fid, "Length", "Design", {length} ); Update(); """ # TODO symmetry here script += """//==== Set Fuselage Section Options ====//\n""" if continuity_type == "C0": continuity_type_string = "0.0" elif continuity_type == "C1": continuity_type_string = "1.0" elif continuity_type == "C2": continuity_type_string = "2.0" else: raise ValueError("Continuity type must be 'C0', 'C1', or 'C2'.") for i, xsec in enumerate(fuselage.xsecs): script += f"""\ // ASB Section {i}, VSP Section {i} SetParmVal( fid, "XLocPercent", "XSec_{i}", {xsec.xyz_c[0] / length} ); SetParmVal( fid, "YLocPercent", "XSec_{i}", {xsec.xyz_c[1] / length} ); SetParmVal( fid, "ZLocPercent", "XSec_{i}", {xsec.xyz_c[2] / length} ); SetParmVal( fid, "SectTess_U", "XSec_{i}", 10 ); SetParmVal( fid, "AllSym", "XSec_{i}", 1.0 ); SetParmVal( fid, "TopLAngleSet", "XSec_{i}", 0.0 ); SetParmVal( fid, "TopLAngle", "XSec_{i}", 0.0 ); SetParmVal( fid, "TopLStrengthSet", "XSec_{i}", 0.0 ); SetParmVal( fid, "TopLStrength", "XSec_{i}", 0.5 ); SetParmVal( fid, "ContinuityTop", "XSec_{i}", {continuity_type_string} ); Update(); """ script += """\ //==== Set Shapes ====// """ for i in range(len(fuselage.xsecs)): xsec = fuselage.xsecs[i] script += f"""\ {{ string xsec_surf = GetXSecSurf( fid, {i} ); xsec_surf = GetXSecSurf( fid, {i} ); string xsec = GetXSec( xsec_surf, {i} ); SetParmVal( fid, "Super_Width", "XSecCurve_{i}", {xsec.width} ); SetParmVal( fid, "Super_Height", "XSecCurve_{i}", {xsec.height} ); SetParmVal( fid, "Super_M", "XSecCurve_{i}", {xsec.shape} ); SetParmVal( fid, "Super_N", "XSecCurve_{i}", {xsec.shape} ); Update(); }} """ script += """\ SetParmVal( fid, "Tess_W", "Shape", 100 ); Update(); """ if include_main: script = _utilities.wrap_script(script) return script
if __name__ == '__main__': import aerosandbox as asb import aerosandbox.numpy as np
[docs] af = asb.Airfoil("ls013")
x = np.linspace(0, 1, 10) fuse = Fuselage( name="Fuse", xsecs=[ FuselageXSec( xyz_c=[xi, 0, 0.05 * xi ** 2], width=2 * af.local_thickness(xi), height=af.local_thickness(xi), shape=4 ) for xi in x ] ) print(generate_fuselage(fuse)) with open("test.vspscript", "w") as f: f.write(generate_fuselage(fuse))