def update_cpacs_file(cpacs_path, cpacs_out_path, optim_var_dict): """Function to update a CPACS file with value from the optimiser This function sets the new values of the design variables given by the routine driver to the CPACS file, using the Tigl and Tixi handler. Source: * See CPACSCreator api function, Args: cpacs_path (str): Path to CPACS file to update cpacs_out_path (str):Path to the updated CPACS file optim_var_dict (dict): Dictionary containing all the variable value/min/max and command to modify a CPACS file """ log.info("----- Start of CPACSUpdater -----") log.info(f"{cpacs_path} will be updated.") tixi = open_tixi(cpacs_path) tigl = open_tigl(tixi) # Object seems to be unused, but are use in "eval" function aircraft = get_tigl_configuration(tigl) wings = aircraft.get_wings() fuselage = aircraft.get_fuselages().get_fuselage(1) # Perform update of all the variable contained in 'optim_var_dict' for name, vars in optim_var_dict.items(): # Unpack the variables val_type, listval, _, _, getcommand, setcommand = vars if val_type == "des" and listval[0] not in ["-", "True", "False"]: if setcommand not in ["-", ""]: # Define variable (var1,var2,..) locals()[str(name)] = listval[-1] # Update value by using tigl configuration if ";" in setcommand: # if more than one command on the line command_split = setcommand.split(";") for setcommand in command_split: eval(setcommand) else: eval(setcommand) else: # Update value directly in the CPACS file xpath = getcommand tixi.updateTextElement(xpath, str(listval[-1])) aircraft.write_cpacs(aircraft.get_uid()) tigl.close() tixi.save(cpacs_out_path) log.info(f"{cpacs_out_path} has been saved.") log.info("----- Start of CPACSUpdater -----")
def init_geom_var_dict(tixi): """Create design variable dictionary Return the dictionary of the design variables using the TIGL library. Add design variables and constrains relative to the aircraft fuselages to the dictionnary. Args: tixi (handle) : Handle of the CPACS file Returns: geom_var_dict (dict) : dictionary with the geometric parameters of the routine. """ tigl = open_tigl(tixi) aircraft = get_tigl_configuration(tigl) fuse_nb = aircraft.get_fuselage_count() if fuse_nb: init_fuse_param(aircraft, fuse_nb) wing_nb = aircraft.get_wing_count() if wing_nb: init_wing_param(aircraft, wing_nb) return geom_var_dict
def fuselage_inertia(SPACING, center_of_gravity, mass_seg_i, afg, cpacs_in): """Thefunction evaluates the inertia of the fuselage using the lumped masses method. INPUT (float) SPACING --Arg.: Maximum distance between fuselage nodes [m]. (float_array) center_of_gravity --Arg.: x,y,z coordinates of the CoG. (float_array) mass_seg_i --Arg.: Mass of each segment of each component of the aircraft. (class) afg --Arg.: AircraftFuseGeometry class. ##======= Class is defined in the InputClasses folder =======## (char) cpacs_in --Arg.: Cpacs xml file location. OUTPUT (float) sfx --Out.: Lumped nodes x-coordinate [m]. (float) sfy --Out.: Lumped nodes y-coordinate [m]. (float) sfz --Out.: Lumped nodes z-coordinate [m]. (float) Ixx --Out.: Moment of inertia respect to the x-axis [kgm^2]. (float) Iyy --Out.: Moment of inertia respect to the y-axis [kgm^]. (float) Izz --Out.: Moment of inertia respect to the z-axis [kgm^2]. """ tixi = open_tixi(cpacs_in) tigl = open_tigl(tixi) sfx = [] sfy = [] sfz = [] Ixx = 0 Iyy = 0 Izz = 0 Ixy = 0 Iyz = 0 Ixz = 0 log.info("-------------------------------------------------------------") log.info("---- Evaluating fuselage nodes for lumped masses inertia ----") log.info("-------------------------------------------------------------") for f in range(1, afg.fus_nb + 1): for i in afg.f_seg_sec[:, f - 1, 2]: fx = [] fy = [] fz = [] # Number of subdivisions along the longitudinal axis subd_l = math.ceil( (afg.fuse_seg_length[int(i) - 1][f - 1] / SPACING)) # Number of subdivisions along the perimeter SUBD_C0 = math.ceil( (afg.fuse_sec_per[int(i) - 1][f - 1] / SPACING)) # Number of subdivisions along the radial axis subd_r = math.ceil( ((afg.fuse_sec_width[int(i) - 1][f - 1] / 2) / SPACING)) if subd_l == 0: subd_l = 1.0 if SUBD_C0 == 0: SUBD_C0 = 1.0 if subd_r == 0: subd_r = 1.0 eta = 1.0 / (subd_l) zeta = 1.0 / (SUBD_C0) D0 = np.sqrt(np.arange(subd_r * SUBD_C0) / float(subd_r * SUBD_C0)) D = np.array([t for t in (D0 - (D0[-1] - 0.98)) if not t < 0]) (xc, yc, zc) = afg.fuse_center_section_point[int(i) - 1][f - 1][:] for j in range(int(subd_l) + 1): et = j * eta for k in range(int(SUBD_C0) + 1): ze = k * zeta (x0, y0, z0) = tigl.fuselageGetPoint(f, int(i), et, ze) fx.append(x0) fy.append(y0) fz.append(z0) sfx.append(x0) sfy.append(y0) sfz.append(z0) if subd_r > 0.0: deltar = np.sqrt((y0 - yc)**2 + (z0 - zc)**2) * D theta = np.pi * (3 - np.sqrt(5)) * np.arange(len(D)) x = np.zeros(np.shape(deltar)) + x0 y = yc + deltar * np.cos(theta) z = zc + deltar * np.sin(theta) fx.extend(x) fy.extend(y) fz.extend(z) sfx.extend(x) sfy.extend(y) sfz.extend(z) M = mass_seg_i[int(i) - 1, f - 1] / np.max(np.shape(fx)) fcx = fx - (np.zeros((np.shape(fx))) + center_of_gravity[0]) fcy = fy - (np.zeros((np.shape(fx))) + center_of_gravity[1]) fcz = fz - (np.zeros((np.shape(fx))) + center_of_gravity[2]) Ixx += np.sum(M * np.add(fcy**2, fcz**2)) Iyy += np.sum(M * np.add(fcx**2, fcz**2)) Izz += np.sum(M * np.add(fcx**2, fcy**2)) Ixy += np.sum(M * fcx * fcy) Iyz += np.sum(M * fcy * fcz) Ixz += np.sum(M * fcx * fcz) return (sfx, sfy, sfz, Ixx, Iyy, Izz, Ixy, Iyz, Ixz)
def wing_inertia(subd_c, SPACING, fuse, center_of_gravity, mass_seg_i, awg, cpacs_in): """The function evaluates the inertia of the wings using the lumped masses method. INPUT (float) subd_c --Arg.: Number of subdivisions along the perimeter on each surface, total number of points for each section subd_c * 2 (float) SPACING --Arg.: Maximum distance between wing nodes along the span [m]. (float) fuse --Arg.: Number of fuselages. (float_array) center_of_gravity --Arg.: x,y,z coordinates of the CoG. (float_array) mass_seg_i --Arg.: Mass of each segment of each component of the aircraft. (class) awg --Arg.: AircraftWingGeometry class. ##======= Class is defined in the InputClasses folder =======## (char) cpacs_in --Arg.: Cpacs xml file location. OUTPUT (float) swx --Out.: Lumped nodes x-coordinate [m]. (float) swy --Out.: Lumped nodes y-coordinate [m]. (float) swz --Out.: Lumped nodes z-coordinate [m]. (float) Ixx --Out.: Moment of inertia respect to the x-axis [kgm^2]. (float) Iyy --Out.: Moment of inertia respect to the y-axis [kgm^]. (float) Izz --Out.: Moment of inertia respect to the z-axis [kgm^2]. """ tixi = open_tixi(cpacs_in) tigl = open_tigl(tixi) log.info("-------------------------------------------------------------") log.info("------ Evaluating wing nodes for lumped masses inertia ------") log.info("-------------------------------------------------------------") Ixx = 0 Iyy = 0 Izz = 0 Ixy = 0 Iyz = 0 Ixz = 0 swx = [] swy = [] swz = [] a = 0 for w in range(1, awg.w_nb + 1): DEN = 0.0 for d in range(int(subd_c + 2)): DEN = DEN + d zeta = 1.0 / DEN for i in awg.w_seg_sec[:, w - 1, 2]: if i == 0.0: break wx = [] wy = [] wz = [] # Number of subdivisions along the longitudinal axis subd_l = math.ceil( (awg.wing_seg_length[int(i) - 1][w + a - 1] / SPACING)) if subd_l == 0: subd_l = 1 eta = 1.0 / subd_l et = 0.0 (xc, yc, zc) = awg.wing_center_seg_point[int(i) - 1][w + a - 1][:] for j in range(int(subd_l) + 1): et = j * eta (xle, yle, zle) = tigl.wingGetLowerPoint(w, int(i), et, 0.0) (xle2, yle2, zle2) = tigl.wingGetLowerPoint(w, int(i), et, 1.0) if xle < xle2: ZLE = 0.0 ze = 0.0 else: ZLE = 1.0 ze = 1.0 wx.extend((xle, xle2)) wy.extend((yle, yle2)) wz.extend((zle, zle2)) swx.extend((xle, xle2)) swy.extend((yle, yle2)) swz.extend((zle, zle2)) for k in range(int(subd_c) + 1): if ZLE == 0.0: ze += float(k) * zeta elif ZLE == 1.0: ze -= float(k) * zeta (xl, yl, zl) = tigl.wingGetLowerPoint(w, int(i), et, ze) (xu, yu, zu) = tigl.wingGetUpperPoint(w, int(i), et, ze) wx.extend((xl, xu)) wy.extend((yl, yu)) wz.extend((zl, zu)) swx.extend((xl, xu)) swy.extend((yl, yu)) swz.extend((zl, zu)) M = mass_seg_i[int(i) - 1, fuse + w + a - 1] / np.max(np.shape(wx)) wcx = wx - (np.zeros((np.shape(wx))) + center_of_gravity[0]) wcy = wy - (np.zeros((np.shape(wy))) + center_of_gravity[1]) wcz = wz - (np.zeros((np.shape(wz))) + center_of_gravity[2]) Ixx += np.sum(M * np.add(wcy**2, wcz**2)) Iyy += np.sum(M * np.add(wcx**2, wcz**2)) Izz += np.sum(M * np.add(wcx**2, wcy**2)) Ixy += np.sum(M * wcx * wcy) Iyz += np.sum(M * wcy * wcz) Ixz += np.sum(M * wcx * wcz) if awg.wing_sym[int(w) - 1] != 0: if awg.wing_sym[int(w) - 1] == 1: # x-y plane symy = 1 + np.zeros(np.shape(wy)) symx = 1 + np.zeros(np.shape(wx)) symz = -1 + np.zeros(np.shape(wz)) elif awg.wing_sym[int(w) - 1] == 2: # x-z plane symy = -1 + np.zeros(np.shape(wy)) symx = 1 + np.zeros(np.shape(wx)) symz = 1 + np.zeros(np.shape(wz)) elif awg.wing_sym[int(w) - 1] == 3: # y-z plane symy = 1 + np.zeros(np.shape(wy)) symx = -1 + np.zeros(np.shape(wx)) symz = 1 + np.zeros(np.shape(wz)) wx_t = wx * symx wy_t = wy * symy wz_t = wz * symz [swx.append(x) for x in wx_t] [swy.append(y) for y in wy_t] [swz.append(z) for z in wz_t] M = mass_seg_i[int(i) - 1, fuse + w + a - 1] / np.max( np.shape(wx_t)) wcx_t = wx_t - (np.zeros( (np.shape(wx_t))) + center_of_gravity[0]) wcy_t = wy_t - (np.zeros( (np.shape(wy_t))) + center_of_gravity[1]) wcz_t = wz_t - (np.zeros( (np.shape(wz_t))) + center_of_gravity[2]) Ixx += np.sum(M * np.add(wcy_t**2, wcz_t**2)) Iyy += np.sum(M * np.add(wcx_t**2, wcz_t**2)) Izz += np.sum(M * np.add(wcx_t**2, wcy_t**2)) Ixy += np.sum(M * wcx_t * wcy_t) Iyz += np.sum(M * wcy_t * wcz_t) Ixz += np.sum(M * wcx_t * wcz_t) if awg.wing_sym[int(w) - 1] != 0: a += 1 return (swx, swy, swz, Ixx, Iyy, Izz, Ixy, Iyz, Ixz)
def geom_eval(w_nb, awg, cpacs_in): """Main function to evaluate the wings geometry. Args: w_nb (integer): Number of wings [-]. awg (class): AircraftWingGeometry class look at aircraft_geometry_class.py in the classes folder for explanation. cpacs_in (str): Path to the CPACS file Returns: awg: AircraftWingGeometry class updated. """ log.info("-----------------------------------------------------------") log.info("---------- Analysing wing geometry ------------------------") log.info("-----------------------------------------------------------") # Opening tixi and tigl tixi = open_tixi(cpacs_in) tigl = open_tigl(tixi) # INITIALIZATION 1 --------------------------------------------------------- awg.w_nb = w_nb awg.wing_nb = w_nb wing_plt_area_xz = [] wing_plt_area_yz = [] wingUID = [] # Counting sections and segments-------------------------------------------- for i in range(1, awg.w_nb + 1): double = 1 awg.wing_sym.append(tigl.wingGetSymmetry(i)) if awg.wing_sym[i - 1] != 0: double = 2 # To consider the real amount of wing # when they are defined using symmetry awg.wing_nb += 1 awg.wing_sec_nb.append(tigl.wingGetSectionCount(i)) awg.wing_seg_nb.append(tigl.wingGetSegmentCount(i)) awg.wing_vol.append(tigl.wingGetVolume(i) * double) # x-y plane awg.wing_plt_area.append(tigl.wingGetReferenceArea(i, 1) * double) # x-z plane wing_plt_area_xz.append(tigl.wingGetReferenceArea(i, 2) * double) # y-z plane wing_plt_area_yz.append(tigl.wingGetReferenceArea(i, 3) * double) if (awg.wing_plt_area[i - 1] > wing_plt_area_xz[i - 1] and awg.wing_plt_area[i - 1] > wing_plt_area_yz[i - 1]): awg.is_horiz.append(True) if awg.wing_sym[i - 1] != 0: awg.is_horiz.append(True) else: awg.is_horiz.append(False) if awg.wing_sym[i - 1] != 0: awg.is_horiz.append(False) awg.wing_tot_vol += awg.wing_vol[i - 1] # Checking segment and section connection and reordering them (awg.wing_sec_nb, start_index, seg_sec, wing_sec_index) = check_segment_connection(wing_plt_area_xz, wing_plt_area_yz, awg, tigl) # INITIALIZATION 2 --------------------------------------------------------- max_wing_sec_nb = np.amax(awg.wing_sec_nb) max_wing_seg_nb = np.amax(awg.wing_seg_nb) wing_center_section_point = np.zeros((max_wing_sec_nb, awg.w_nb, 3)) awg.wing_center_seg_point = np.zeros((max_wing_seg_nb, awg.wing_nb, 3)) awg.wing_seg_vol = np.zeros((max_wing_seg_nb, awg.w_nb)) awg.wing_mac = np.zeros((4, awg.w_nb)) awg.wing_sec_thicknes = np.zeros((max_wing_sec_nb, awg.w_nb)) # WING ANALYSIS ------------------------------------------------------------ # Wing: MAC,chords,thicknes,span,plantform area ---------------------------- b = 0 for i in range(1, awg.w_nb + 1): wingUID.append(tigl.wingGetUID(i)) mac = tigl.wingGetMAC(wingUID[i - 1]) (wpx, wpy, wpz) = tigl.wingGetChordPoint(i, 1, 0.0, 0.0) (wpx2, wpy2, wpz2) = tigl.wingGetChordPoint(i, 1, 0.0, 1.0) awg.wing_max_chord.append( np.sqrt((wpx2 - wpx)**2 + (wpy2 - wpy)**2 + (wpz2 - wpz)**2)) (wpx, wpy, wpz) = tigl.wingGetChordPoint(i, awg.wing_seg_nb[i - 1], 1.0, 0.0) (wpx2, wpy2, wpz2) = tigl.wingGetChordPoint(i, awg.wing_seg_nb[i - 1], 1.0, 1.0) awg.wing_min_chord.append( np.sqrt((wpx2 - wpx)**2 + (wpy2 - wpy)**2 + (wpz2 - wpz)**2)) for k in range(1, 5): awg.wing_mac[k - 1][i - 1] = mac[k - 1] for jj in range(1, awg.wing_seg_nb[i - 1] + 1): j = int(seg_sec[jj - 1, i - 1, 2]) cle = tigl.wingGetChordPoint(i, j, 0.0, 0.0) awg.wing_seg_vol[j - 1][i - 1] = tigl.wingGetSegmentVolume(i, j) lp = tigl.wingGetLowerPoint(i, j, 0.0, 0.0) up = tigl.wingGetUpperPoint(i, j, 0.0, 0.0) if np.all(cle == lp): L = 0.25 else: L = 0.75 if np.all(cle == up): U = 0.25 else: U = 0.75 (wplx, wply, wplz) = tigl.wingGetLowerPoint(i, j, 0.0, L) (wpux, wpuy, wpuz) = tigl.wingGetUpperPoint(i, j, 0.0, U) wing_center_section_point[j - 1][i - 1][0] = (wplx + wpux) / 2 wing_center_section_point[j - 1][i - 1][1] = (wply + wpuy) / 2 wing_center_section_point[j - 1][i - 1][2] = (wplz + wpuz) / 2 awg.wing_sec_thicknes[j - 1][i - 1] = np.sqrt((wpux - wplx)**2 + (wpuy - wply)**2 + (wpuz - wplz)**2) j = int(seg_sec[awg.wing_seg_nb[i - 1] - 1, i - 1, 2]) (wplx, wply, wplz) = tigl.wingGetLowerPoint(i, awg.wing_seg_nb[i - 1], 1.0, L) (wpux, wpuy, wpuz) = tigl.wingGetUpperPoint(i, awg.wing_seg_nb[i - 1], 1.0, U) awg.wing_sec_thicknes[j][i - 1] = np.sqrt((wpux - wplx)**2 + (wpuy - wply)**2 + (wpuz - wplz)**2) wing_center_section_point[awg.wing_seg_nb[i - 1]][i - 1][0] = (wplx + wpux) / 2 wing_center_section_point[awg.wing_seg_nb[i - 1]][i - 1][1] = (wply + wpuy) / 2 wing_center_section_point[awg.wing_seg_nb[i - 1]][i - 1][2] = (wplz + wpuz) / 2 awg.wing_sec_mean_thick.append( np.mean(awg.wing_sec_thicknes[0:awg.wing_seg_nb[i - 1] + 1, i - 1])) # Wing Span Evaluation, Considering symmetry awg.wing_span.append(round(tigl.wingGetSpan(wingUID[i - 1]), 3)) a = np.amax(awg.wing_span) # Evaluating the index that corresponds to the main wing if a > b: awg.main_wing_index = i b = a # Main wing plantform area awg.wing_plt_area_main = awg.wing_plt_area[awg.main_wing_index - 1] # Wing segment length evaluatin function awg = getwingsegmentlength(awg, wing_center_section_point) awg.w_seg_sec = seg_sec # Wings wetted area for i in range(1, awg.w_nb + 1): a = str(wingUID[i - 1]) s = tigl.wingGetSurfaceArea(i) if awg.wing_sym[i - 1] != 0: s *= 2 if i == awg.main_wing_index: awg.main_wing_surface = s else: awg.tail_wings_surface.append(s) awg.total_wings_surface += s # Evaluating the point at the center of each segment, the center # is placed at 1/4 of the chord, symmetry is considered. a = 0 c = False for i in range(1, int(awg.wing_nb) + 1): if c: c = False continue for jj in range(1, awg.wing_seg_nb[i - a - 1] + 1): j = int(seg_sec[jj - 1, i - a - 1, 2]) awg.wing_center_seg_point[j - 1][ i - 1][0] = (wing_center_section_point[j - 1][i - a - 1][0] + wing_center_section_point[j][i - a - 1][0]) / 2 awg.wing_center_seg_point[j - 1][ i - 1][1] = (wing_center_section_point[j - 1][i - a - 1][1] + wing_center_section_point[j][i - a - 1][1]) / 2 awg.wing_center_seg_point[j - 1][ i - 1][2] = (wing_center_section_point[j - 1][i - a - 1][2] + wing_center_section_point[j][i - a - 1][2]) / 2 if awg.wing_sym[i - 1 - a] != 0: if awg.wing_sym[i - 1 - a] == 1: symy = 1 symx = 1 symz = -1 if awg.wing_sym[i - 1 - a] == 2: symy = -1 symx = 1 symz = 1 if awg.wing_sym[i - 1 - a] == 3: symy = 1 symx = -1 symz = 1 awg.wing_center_seg_point[:, i, 0] = awg.wing_center_seg_point[:, i - 1, 0] * symx awg.wing_center_seg_point[:, i, 1] = awg.wing_center_seg_point[:, i - 1, 1] * symy awg.wing_center_seg_point[:, i, 2] = awg.wing_center_seg_point[:, i - 1, 2] * symz c = True a += 1 tixi.save(cpacs_in) # log info display ------------------------------------------------------------ log.info("-----------------------------------------------------------") log.info("---------- Wing Results -----------------------------------") log.info("Number of Wings [-]: " + str(awg.wing_nb)) log.info("Wing symmetry plane [-]: " + str(awg.wing_sym)) log.info("Number of wing sections (not counting symmetry) [-]: " + str(awg.wing_sec_nb)) log.info("Number of wing segments (not counting symmetry) [-]: " + str(awg.wing_seg_nb)) log.info("Wing Span (counting symmetry)[m]: \n" + str(awg.wing_span)) log.info("Wing MAC length [m]: " + str(awg.wing_mac[0, ])) log.info("Wing MAC x,y,z coordinate [m]: \n" + str(awg.wing_mac[1:4, ])) log.info("Wings sections thicknes [m]: \n" + str(awg.wing_sec_thicknes)) log.info("Wings sections mean thicknes [m]: \n" + str(awg.wing_sec_mean_thick)) log.info("Wing segments length [m]: \n" + str(awg.wing_seg_length)) log.info("Wing max chord length [m]: \n" + str(awg.wing_max_chord)) log.info("Wing min chord length [m]: \n" + str(awg.wing_min_chord)) log.info("Main wing plantform area [m^2]: " + str(awg.wing_plt_area_main)) log.info("Main wing wetted surface [m^2]: " + str(awg.main_wing_surface)) log.info("Tail wings wetted surface [m^2]: \n" + str(awg.tail_wings_surface)) log.info("Total wings wetted surface [m^2]: \n" + str(awg.total_wings_surface)) log.info("Wings plantform area [m^2]: \n" + str(awg.wing_plt_area)) log.info("Volume of each wing [m^3]: " + str(awg.wing_vol)) log.info("Total wing volume [m^3]: " + str(awg.wing_tot_vol)) log.info("-----------------------------------------------------------") return awg
def generate_mesh_def_config(tixi, wkdir, ted_uid, wing_uid, sym_dir, defl_list): """Function to create config file for a TED. Function 'generate_mesh_def_config' will create SU2 configuration files to create SU2 deformed mesh for a specific Trailing Edge Device (TED) at several deflection angle (from defl_list) Args: tixi (handle): TIXI handle wkdir (str): Path to the working directory ted_uid (str): uID of the TED wing_uid (str): uID of the coresponding wing sym_dir (str): Direction of the axis of symmetry ('x','y','z' or '') defl_list (str): List of deflection angles to generate """ tigl = open_tigl(tixi) ac_name = aircraft_name(tixi) DEFAULT_CONFIG_PATH = MODULE_DIR + "/files/DefaultConfig_v7.cfg" cfg = ConfigFile(DEFAULT_CONFIG_PATH) config_dir_name = ac_name + "_TED_" + ted_uid # TODO: add check or remove if already exist? os.mkdir(os.path.join(wkdir, "MESH", config_dir_name)) # Get TED and hinge line definition ted_corner = get_ted_corner(tixi, tigl, ted_uid) ted_corner_list, ted_corner_sym_list = get_ffd_box(ted_corner, sym_dir) ted_hinge = get_ted_hinge(tixi, tigl, ted_uid) hinge_list, hinge_sym_list = get_hinge_lists(ted_hinge, sym_dir) # General parmeters ref_len = get_value(tixi, REF_XPATH + "/length") ref_area = get_value(tixi, REF_XPATH + "/area") ref_ori_moment_x = get_value_or_default(tixi, REF_XPATH + "/point/x", 0.0) ref_ori_moment_y = get_value_or_default(tixi, REF_XPATH + "/point/y", 0.0) ref_ori_moment_z = get_value_or_default(tixi, REF_XPATH + "/point/z", 0.0) cfg["REF_LENGTH"] = ref_len cfg["REF_AREA"] = ref_area cfg["REF_ORIGIN_MOMENT_X"] = ref_ori_moment_x cfg["REF_ORIGIN_MOMENT_Y"] = ref_ori_moment_y cfg["REF_ORIGIN_MOMENT_Z"] = ref_ori_moment_z cfg["GRID_MOVEMENT"] = "NONE" cfg["ROTATION_RATE"] = "0.0 0.0 0.0" # TODO: is it the best way or should be pass as arg? mesh_dir = os.path.join(wkdir, "MESH") su2_mesh_path = os.path.join(mesh_dir, ac_name + "_baseline.su2") cfg["MESH_FILENAME"] = "../" + ac_name + "_baseline.su2" # Mesh Marker bc_wall_list, engine_bc_list = get_mesh_marker(su2_mesh_path) bc_wall_str = "(" + ",".join(bc_wall_list) + ")" cfg["MARKER_EULER"] = bc_wall_str cfg["MARKER_FAR"] = " (Farfield)" cfg["MARKER_SYM"] = " (0)" cfg["MARKER_PLOTTING"] = bc_wall_str cfg["MARKER_MONITORING"] = bc_wall_str cfg["MARKER_MOVING"] = "( NONE )" cfg["DV_MARKER"] = bc_wall_str # FFD BOX definition cfg["DV_KIND"] = "FFD_SETTING" cfg["DV_MARKER"] = "( " + wing_uid + ")" cfg["FFD_CONTINUITY"] = "2ND_DERIVATIVE" cfg["FFD_DEFINITION"] = "( " + ted_uid + ", " + ",".join(ted_corner_list) + ")" cfg["FFD_DEGREE"] = "( 6, 10, 3 )" # TODO: how to chose/calculate these value? if sym_dir: cfg["FFD_DEFINITION"] += "; (" + ted_uid + "_sym, " + ",".join(ted_corner_sym_list) + ")" cfg["FFD_DEGREE"] += ";( 6, 10, 3 )" # TODO: how to chose/calculate these value? cfg["MESH_OUT_FILENAME"] = "_mesh_ffd_box.su2" # Write Config definition for FFD box config_file_name = "ConfigDEF.cfg" config_path = os.path.join(wkdir, "MESH", config_dir_name, config_file_name) cfg.write_file(config_path, overwrite=True) log.info(config_path + " have has been written.") # FFD BOX rotation for defl in defl_list: cfg["DV_KIND"] = "FFD_ROTATION" cfg["DV_MARKER"] = "( " + wing_uid + ")" cfg["DV_PARAM"] = "( " + ted_uid + ", " + ",".join(hinge_list) + ")" cfg["DV_VALUE"] = str(defl / 1000) # SU2 use 1/1000 degree... cfg["MESH_FILENAME"] = "_mesh_ffd_box.su2" defl_mesh_name = ac_name + "_TED_" + ted_uid + "_defl" + str(defl) + ".su2" if sym_dir: defl_mesh_name = "_" + defl_mesh_name cfg["MESH_OUT_FILENAME"] = defl_mesh_name # Write Config rotation for FFD box config_file_name = "ConfigROT_defl" + str(defl) + ".cfg" config_path = os.path.join(wkdir, "MESH", config_dir_name, config_file_name) cfg.write_file(config_path, overwrite=True) log.info(config_path + " have has been written.") if sym_dir: # TODO: add a condition for anti symmetric deflection (e.g. ailerons) cfg["DV_MARKER"] = "( " + wing_uid + ")" cfg["DV_PARAM"] = "( " + ted_uid + "_sym, " + ",".join(hinge_sym_list) + ")" cfg["DV_VALUE"] = str(defl / 1000) # SU2 use 1/1000 degree... cfg["MESH_FILENAME"] = defl_mesh_name defl_mesh_sym_name = ac_name + "_TED_" + ted_uid + "_defl" + str(defl) + "_sym.su2" cfg["MESH_OUT_FILENAME"] = defl_mesh_sym_name config_file_name = "ConfigROT_sym_defl" + str(defl) + ".cfg" config_path = os.path.join(wkdir, "MESH", config_dir_name, config_file_name) cfg.write_file(config_path, overwrite=True) log.info(config_path + " have has been written.")
def fuse_geom_eval(ag, cpacs_in): """Main function to evaluate the fuselage geometry. INPUT (class) ag --Arg.: AircraftGeometry class. # ======= Class is defined in the InputClasses folder =======## (char) cpacs_in -- Arg.: Cpacs xml file location OUTPUT (class) ag --Out.: AircraftGeometry class updated . """ # ===========================================================================## log.info("---------------------------------------------") log.info("-------- Analysing fuselage geometry --------") log.info("---------------------------------------------") # Opening tixi and tigl tixi = open_tixi(cpacs_in) tigl = open_tigl(tixi) # ---------------------------------------------------------------------------- # COUNTING 1 ----------------------------------------------------------------- # Counting fuselage number --------------------------------------------------- # ---------------------------------------------------------------------------- fus_nb = tixi.getNamedChildrenCount( "/cpacs/vehicles/aircraft/model/fuselages", "fuselage") # ---------------------------------------------------------------------------- # INITIALIZATION 1 ----------------------------------------------------------- # ---------------------------------------------------------------------------- ag.fus_nb = fus_nb ag.fuse_nb = fus_nb i = ag.fus_nb # ---------------------------------------------------------------------------- # COUNTING 2 ----------------------------------------------------------------- # Counting sections and segments---------------------------------------------- # ---------------------------------------------------------------------------- double = 1 ag.fuse_sym.append(tigl.fuselageGetSymmetry(i)) if ag.fuse_sym[i - 1] != 0: ag.fuse_nb += 1 double = 2 ag.fuse_sec_nb.append(tigl.fuselageGetSectionCount(i)) ag.fuse_seg_nb.append(tigl.fuselageGetSegmentCount(i)) ag.fuse_vol.append(tigl.fuselageGetVolume(i) * double) # Checking segment and section connection and reordering them (ag.fuse_sec_nb, start_index, seg_sec, fuse_sec_index) = check_segment_connection(fus_nb, ag.fuse_seg_nb, ag.fuse_sec_nb, tigl) # ---------------------------------------------------------------------------- # INITIALIZATION 2 ----------------------------------------------------------- # ---------------------------------------------------------------------------- max_sec_nb = np.amax(ag.fuse_sec_nb) max_seg_nb = np.amax(ag.fuse_seg_nb) ag.fuse_sec_circ = np.zeros((max_sec_nb, fus_nb)) ag.fuse_sec_width = np.zeros((max_sec_nb, fus_nb)) ag.fuse_sec_rel_dist = np.zeros((max_sec_nb, fus_nb)) ag.fuse_seg_index = np.zeros((max_sec_nb, fus_nb)) ag.fuse_seg_length = np.zeros((max_seg_nb, fus_nb)) fuse_center_section_point = np.zeros((max_sec_nb, fus_nb, 3)) ag.fuse_center_seg_point = np.zeros((max_seg_nb, ag.fuse_nb, 3)) ag.fuse_center_sec_point = np.zeros((max_sec_nb, ag.fuse_nb, 3)) ag.fuse_seg_vol = np.zeros((max_seg_nb, fus_nb)) # ===========================================================================## # ---------------------------------------------------------------------------- # FUSELAGE ANALYSIS ---------------------------------------------------------- # ---------------------------------------------------------------------------- # Aircraft total length ------------------------------------------------------ ag.tot_length = tigl.configurationGetLength() # Evaluating fuselage: sections circumference, segments volume and length --- (ag.fuse_sec_rel_dist[:, i - 1], ag.fuse_seg_index[:, i - 1]) = rel_dist( i, ag.fuse_sec_nb[i - 1], ag.fuse_seg_nb[i - 1], tigl, seg_sec[:, i - 1, :], start_index[i - 1], ) ag.fuse_length.append(ag.fuse_sec_rel_dist[-1, i - 1]) for j in range(1, ag.fuse_seg_nb[i - 1] + 1): k = int(ag.fuse_seg_index[j][i - 1]) ag.fuse_sec_circ[j][i - 1] = tigl.fuselageGetCircumference(i, k, 1.0) (fpx, fpy, fpz) = tigl.fuselageGetPoint(i, k, 1.0, 0.0) (fpx2, fpy2, fpz2) = tigl.fuselageGetPoint(i, k, 1.0, 0.5) ag.fuse_seg_vol[j - 1][i - 1] = abs(tigl.fuselageGetSegmentVolume( i, k)) fuse_center_section_point[j][i - 1][0] = (fpx + fpx2) / 2 fuse_center_section_point[j][i - 1][1] = (fpy + fpy2) / 2 fuse_center_section_point[j][i - 1][2] = (fpz + fpz2) / 2 hw1 = 0 hw2 = 0 for zeta in np.arange(0.0, 1.0, 0.001): (fpx, fpy, fpz) = tigl.fuselageGetPoint(i, k, 1.0, zeta) if abs(fpz - fuse_center_section_point[j][i - 1][2]) < 0.01: if fpy > fuse_center_section_point[j][i - 1][1] and hw1 == 0: hw1 = abs(fpy - fuse_center_section_point[j][i - 1][1]) elif fpy < fuse_center_section_point[j][i - 1][1] and hw2 == 0: hw2 = abs(fpy - fuse_center_section_point[j][i - 1][1]) break ag.fuse_sec_width[j][i - 1] = hw1 + hw2 (fslpx, fslpy, fslpz) = tigl.fuselageGetPoint(1, k, 0.0, 0.0) (fslpx2, fslpy2, fslpz2) = tigl.fuselageGetPoint(1, k, 1.0, 0.0) ag.fuse_seg_length[j - 1][i - 1] = abs(fslpx2 - fslpx) k = int(ag.fuse_seg_index[1][i - 1]) ag.fuse_sec_circ[0][i - 1] = tigl.fuselageGetCircumference(i, k, 0.0) (fpx, fpy, fpz) = tigl.fuselageGetPoint(i, k, 0.0, 0.0) (fpx2, fpy2, fpz2) = tigl.fuselageGetPoint(i, k, 0.0, 0.5) fuse_center_section_point[0][i - 1][0] = (fpx + fpx2) / 2 fuse_center_section_point[0][i - 1][1] = (fpy + fpy2) / 2 fuse_center_section_point[0][i - 1][2] = (fpz + fpz2) / 2 hw1 = 0 hw2 = 0 for zeta in np.arange(0.0, 1.0, 0.001): (fpx, fpy, fpz) = tigl.fuselageGetPoint(i, k, 0.0, zeta) if abs(fpz - fuse_center_section_point[0][i - 1][2]) < 0.01: if fpy > fuse_center_section_point[0][i - 1][1] and hw1 == 0: hw1 = abs(fpy - fuse_center_section_point[0][i - 1][1]) elif fpy < fuse_center_section_point[0][i - 1][1] and hw2 == 0: hw2 = abs(fpy - fuse_center_section_point[0][i - 1][1]) break ag.fuse_sec_width[0][i - 1] = hw1 + hw2 ag.fuse_mean_width.append(np.mean(ag.fuse_sec_width[:, i - 1])) # Evaluating the point at the center of each segment, symmetry is considered a = 0 cs = False for i in range(int(ag.fuse_nb)): if cs: cs = False continue for j in range(1, ag.fuse_seg_nb[i - a - 1] + 1): ag.fuse_center_seg_point[j - 1][ i - 1][0] = (fuse_center_section_point[j - 1][i - a - 1][0] + fuse_center_section_point[j][i - a - 1][0]) / 2 ag.fuse_center_seg_point[j - 1][ i - 1][1] = (fuse_center_section_point[j - 1][i - a - 1][1] + fuse_center_section_point[j][i - a - 1][1]) / 2 ag.fuse_center_seg_point[j - 1][ i - 1][2] = (fuse_center_section_point[j - 1][i - a - 1][2] + fuse_center_section_point[j][i - a - 1][2]) / 2 ag.fuse_center_sec_point[j - 1][ i - 1][:] = fuse_center_section_point[j - 1][i - a - 1][:] if ag.fuse_sym[i - 1 - a] != 0: if ag.fuse_sym[i - 1 - a] == 1: symy = 1 symx = 1 symz = -1 if ag.fuse_sym[i - 1 - a] == 2: symy = -1 symx = 1 symz = 1 if ag.fuse_sym[i - 1 - a] == 3: symy = 1 symx = -1 symz = 1 ag.fuse_center_seg_point[:, i, 0] = ag.fuse_center_seg_point[:, i - 1, 0] * symx ag.fuse_center_seg_point[:, i, 1] = ag.fuse_center_seg_point[:, i - 1, 1] * symy ag.fuse_center_seg_point[:, i, 2] = ag.fuse_center_seg_point[:, i - 1, 2] * symz ag.fuse_center_sec_point[j - 1][i][:] = fuse_center_section_point[ j - 1][i - a - 1][:] cs = True a += 1 # Evaluating cabin length and volume, nose length and tail_length ------------ ex = False corr = 1.25 + np.zeros((1, fus_nb)) c = False cabin_nb = np.zeros((1, fus_nb)) cabin_seg = np.zeros((max_seg_nb, fus_nb)) cabin_length = 0 cabin_volume = 0 nose_length = 0 tail_length = 0 for j in range(1, ag.fuse_seg_nb[i - 1] + 1): if round(ag.fuse_sec_width[j][i - 1], 3) == round(np.amax(ag.fuse_sec_width[:, i - 1]), 3): cabin_length += ag.fuse_seg_length[j - 1, i - 1] cabin_volume += ag.fuse_seg_vol[j - 1, i - 1] cabin_seg[j - 1][i - 1] = 1 c = True elif not c: nose_length += ag.fuse_seg_length[j - 1, i - 1] if cabin_length >= 0.65 * ag.fuse_length[i - 1]: # If the aircraft is designed with 1 or more sections with # maximum width and the sun of their length is greater the 65% # of the total length, the cabin will be considered only in those # sections tail_length = ag.fuse_length[i - 1] - cabin_length - nose_length cabin_nb[i - 1] = 1 ex = True while ex is False: c = False cabin_seg = np.zeros((max_seg_nb, fus_nb)) nose_length = 0 tail_length = 0 cabin_length = 0 cabin_volume = 0 for j in range(1, ag.fuse_seg_nb[i - 1] + 1): if ag.fuse_sec_width[j][i - 1] >= (corr[i - 1] * ag.fuse_mean_width[i - 1]): cabin_length += ag.fuse_seg_length[j - 1, i - 1] cabin_volume += ag.fuse_seg_vol[j - 1, i - 1] cabin_seg[j - 1][i - 1] = 1 c = True elif c: tail_length += ag.fuse_seg_length[j - 1, i - 1] else: nose_length += ag.fuse_seg_length[j - 1, i - 1] if corr[i - 1] > 0.0 and cabin_length < (0.20 * ag.fuse_length[i - 1]): corr[i - 1] -= 0.05 else: ex = True ag.fuse_nose_length.append(nose_length) ag.fuse_tail_length.append(tail_length) ag.fuse_cabin_length.append(cabin_length) ag.fuse_cabin_vol.append(cabin_volume) ag.f_seg_sec = seg_sec ag.cabin_nb = cabin_nb ag.cabin_seg = cabin_seg ag.fuse_mean_width = ag.fuse_mean_width[0] tixi.save(cpacs_in) # log info display ------------------------------------------------------------ log.info("---------------------------------------------") log.info("---------- Geometry Evaluations -------------") log.info("---------- USEFUL INFO ----------------------\n" "If fuselage or wing number is greater than 1 the " "informations\nof each part is listed in an " "array ordered per column progressively") log.info("Symmetry output: 0 = no symmetry, 1 = x-y, " + "2 = x-z, 3 = y-z planes") log.info("---------------------------------------------") log.info("---------- Fuselage Results -----------------") log.info("Number of fuselage [-]: " + str(ag.fuse_nb)) log.info("Fuselage symmetry plane [-]: " + str(ag.fuse_sym)) log.info("Number of fuselage sections (not counting symmetry) [-]: " + str(ag.fuse_sec_nb)) log.info("Number of fuselage segments (not counting symmetry) [-]: " + str(ag.fuse_seg_nb)) log.info("Fuse Length [m]: " + str(ag.fuse_length)) log.info("Fuse nose Length [m]: " + str(ag.fuse_nose_length)) log.info("Fuse cabin Length [m]: " + str(ag.fuse_cabin_length)) log.info("Fuse tail Length [m]: " + str(ag.fuse_tail_length)) log.info("Aircraft Length [m]: " + str(ag.tot_length)) log.info("Mean fuselage width [m]: " + str(ag.fuse_mean_width)) log.info("Volume of each cabin [m^3]: " + str(ag.fuse_cabin_vol)) log.info("Volume of each fuselage [m^3]: " + str(ag.fuse_vol)) log.info("---------------------------------------------") return ag
def fuse_geom_eval(fus_nb, h_min, fuse_thick, F_FUEL, afg, cpacs_in): """Main function to evaluate the fuselage geometry Args: fus_nb (int): Number of fuselages. h_min (float): Minimum height for the fuselage [m]. fuse_thick(float) : Thickness of the fuselage [mm]. F_FUEL (float-array): Percentage of the total volume of the fuel tank fuselage, used for fuel straging (set False if fuselage is ment for payload/passengers). afg (class): AircraftGeometry class look at aircraft_geometry_class.py in the classes folder for explanation. cpacs_in (str): Path to the CPACS file Returns: afg (class): Updated aircraft_geometry class """ log.info("-----------------------------------------------------------") log.info("---------- Analysing fuselage geometry --------------------") log.info("-----------------------------------------------------------") # Opening tixi and tigl tixi = open_tixi(cpacs_in) tigl = open_tigl(tixi) # INITIALIZATION 1 ---------------------------------------------------------- afg.fus_nb = fus_nb # Counting sections and segments---------------------------------------------- for i in range(1, afg.fus_nb + 1): afg.fuse_sec_nb.append(tigl.fuselageGetSectionCount(i)) afg.fuse_seg_nb.append(tigl.fuselageGetSegmentCount(i)) afg.fuse_vol.append(tigl.fuselageGetVolume(i)) afg.fuse_surface.append(tigl.fuselageGetSurfaceArea(i)) # Checking segment and section connection and reordering them (afg.fuse_sec_nb, start_index, seg_sec, fuse_sec_index) = check_segment_connection(afg.fus_nb, afg.fuse_seg_nb, afg.fuse_sec_nb, tigl) afg.f_seg_sec = seg_sec # INITIALIZATION 2 ----------------------------------------------------------- max_sec_nb = np.amax(afg.fuse_sec_nb) max_seg_nb = np.amax(afg.fuse_seg_nb) afg.fuse_sec_per = np.zeros((max_sec_nb, afg.fus_nb)) afg.fuse_sec_width = np.zeros((max_sec_nb, afg.fus_nb)) afg.fuse_sec_height = np.zeros((max_sec_nb, afg.fus_nb)) afg.fuse_sec_rel_dist = np.zeros((max_sec_nb, afg.fus_nb)) afg.fuse_seg_index = np.zeros((max_sec_nb, afg.fus_nb)) afg.fuse_seg_length = np.zeros((max_seg_nb, afg.fus_nb)) afg.fuse_center_section_point = np.zeros((max_sec_nb, afg.fus_nb, 3)) afg.fuse_center_seg_point = np.zeros((max_sec_nb, afg.fus_nb, 3)) afg.fuse_seg_vol = np.zeros((max_seg_nb, afg.fus_nb)) x1 = np.zeros((max_sec_nb, afg.fus_nb)) y1 = np.zeros((max_sec_nb, afg.fus_nb)) z1 = np.zeros((max_sec_nb, afg.fus_nb)) x2 = np.zeros((max_sec_nb, afg.fus_nb)) y2 = np.zeros((max_sec_nb, afg.fus_nb)) z2 = np.zeros((max_sec_nb, afg.fus_nb)) # FUSELAGE ANALYSIS ---------------------------------------------------------- # Aircraft total length ------------------------------------------------------ afg.tot_length = tigl.configurationGetLength() # Evaluating fuselage: sections perimeter, segments volume and length --- for i in range(1, afg.fus_nb + 1): (afg.fuse_sec_rel_dist[:, i - 1], afg.fuse_seg_index[:, i - 1]) = rel_dist( i, afg.fuse_sec_nb[i - 1], afg.fuse_seg_nb[i - 1], tigl, seg_sec[:, i - 1, :], start_index[i - 1], ) afg.fuse_length.append(round(afg.fuse_sec_rel_dist[-1, i - 1], 3)) for j in range(1, afg.fuse_seg_nb[i - 1] + 1): k = int(afg.fuse_seg_index[j][i - 1]) afg.fuse_sec_per[j][i - 1] = tigl.fuselageGetCircumference( i, k, 1.0) (fpx, fpy, fpz) = tigl.fuselageGetPoint(i, k, 1.0, 0.0) (fpx2, fpy2, fpz2) = tigl.fuselageGetPoint(i, k, 1.0, 0.5) afg.fuse_seg_vol[j - 1][i - 1] = tigl.fuselageGetSegmentVolume( i, k) afg.fuse_center_section_point[j][i - 1][0] = (fpx + fpx2) / 2 afg.fuse_center_section_point[j][i - 1][1] = (fpy + fpy2) / 2 afg.fuse_center_section_point[j][i - 1][2] = (fpz + fpz2) / 2 hw1 = 0.0 hw2 = 0.0 for zeta in np.arange(0.0, 1.0, 0.001): (fpx, fpy, fpz) = tigl.fuselageGetPoint(i, k, 1.0, zeta) if abs(fpz - afg.fuse_center_section_point[j][i - 1][2]) < 0.01: if fpy > afg.fuse_center_section_point[j][ i - 1][1] and hw1 == 0.0: hw1 = abs(fpy - afg.fuse_center_section_point[j][i - 1][1]) x1[j, i - 1] = fpx y1[j, i - 1] = fpy z1[j, i - 1] = fpz elif fpy < afg.fuse_center_section_point[j][ i - 1][1] and hw2 == 0.0: hw2 = abs(fpy - afg.fuse_center_section_point[j][i - 1][1]) x2[j, i - 1] = fpx y2[j, i - 1] = fpy z2[j, i - 1] = fpz break afg.fuse_sec_width[j][i - 1] = hw1 + hw2 hh1 = 0.0 hh2 = 0.0 for zeta in np.arange(0.0, 1.0, 0.001): (fpx, fpy, fpz) = tigl.fuselageGetPoint(i, k, 1.0, zeta) if abs(fpy - afg.fuse_center_section_point[j][i - 1][1]) < 0.01: if fpz > afg.fuse_center_section_point[j][ i - 1][2] and hh1 == 0.0: hh1 = abs(fpz - afg.fuse_center_section_point[j][i - 1][2]) elif fpz < afg.fuse_center_section_point[j][ i - 1][2] and hh2 == 0.0: hh2 = abs(fpz - afg.fuse_center_section_point[j][i - 1][2]) break afg.fuse_sec_height[j][i - 1] = hh1 + hh2 (fslpx, fslpy, fslpz) = tigl.fuselageGetPoint(1, k, 0.0, 0.0) (fslpx2, fslpy2, fslpz2) = tigl.fuselageGetPoint(1, k, 1.0, 0.0) afg.fuse_seg_length[j - 1][i - 1] = abs(fslpx2 - fslpx) k = int(afg.fuse_seg_index[1][i - 1]) afg.fuse_sec_per[0][i - 1] = tigl.fuselageGetCircumference(i, k, 0.0) (fpx, fpy, fpz) = tigl.fuselageGetPoint(i, k, 0.0, 0.0) (fpx2, fpy2, fpz2) = tigl.fuselageGetPoint(i, k, 0.0, 0.5) afg.fuse_center_section_point[0][i - 1][0] = (fpx + fpx2) / 2 afg.fuse_center_section_point[0][i - 1][1] = (fpy + fpy2) / 2 afg.fuse_center_section_point[0][i - 1][2] = (fpz + fpz2) / 2 hw1 = 0 hw2 = 0 for zeta in np.arange(0.0, 1.0, 0.001): (fpx, fpy, fpz) = tigl.fuselageGetPoint(i, k, 0.0, zeta) if abs(fpz - afg.fuse_center_section_point[0][i - 1][2]) < 0.01: if fpy > afg.fuse_center_section_point[0][i - 1][1] and hw1 == 0: hw1 = abs(fpy - afg.fuse_center_section_point[0][i - 1][1]) x1[0, i - 1] = fpx y1[0, i - 1] = fpy z1[0, i - 1] = fpz elif fpy < afg.fuse_center_section_point[0][i - 1][1] and hw2 == 0: hw2 = abs(fpy - afg.fuse_center_section_point[0][i - 1][1]) x2[0, i - 1] = fpx y2[0, i - 1] = fpy z2[0, i - 1] = fpz break afg.fuse_sec_width[0][i - 1] = hw1 + hw2 hh1 = 0.0 hh2 = 0.0 for zeta in np.arange(0.0, 1.0, 0.001): (fpx, fpy, fpz) = tigl.fuselageGetPoint(i, k, 1.0, zeta) if abs(fpy - afg.fuse_center_section_point[0][i - 1][1]) < 0.01: if fpz > afg.fuse_center_section_point[0][i - 1][2] and hh1 == 0.0: hh1 = abs(fpz - afg.fuse_center_section_point[0][i - 1][2]) elif fpz < afg.fuse_center_section_point[0][ i - 1][2] and hh2 == 0.0: hh2 = abs(fpz - afg.fuse_center_section_point[0][i - 1][2]) break afg.fuse_sec_height[0][i - 1] = hh1 + hh2 afg.fuse_mean_width.append( round(np.mean(afg.fuse_sec_width[:, i - 1]), 3)) # Evaluating the point at the center of each segment. for i in range(int(afg.fuse_nb)): for j in range(1, afg.fuse_seg_nb[i - 1] + 1): afg.fuse_center_seg_point[j - 1][ i - 1][0] = (afg.fuse_center_section_point[j - 1][i - 1][0] + afg.fuse_center_section_point[j][i - 1][0]) / 2 afg.fuse_center_seg_point[j - 1][ i - 1][1] = (afg.fuse_center_section_point[j - 1][i - 1][1] + afg.fuse_center_section_point[j][i - 1][1]) / 2 afg.fuse_center_seg_point[j - 1][ i - 1][2] = (afg.fuse_center_section_point[j - 1][i - 1][2] + afg.fuse_center_section_point[j][i - 1][2]) / 2 # Evaluating cabin length and volume, nose length and tail_length ------------ log.info("-----------------------------------------------------------") log.info("----------- Analysing cabin dimensions --------------------") log.info("-----------------------------------------------------------") corr = (1.3) + np.zeros((afg.fus_nb)) c = False afg.cabin_nb = np.zeros((afg.fus_nb)) afg.cabin_area = np.zeros((afg.fus_nb)) afg.fuse_cabin_length = np.zeros((afg.fus_nb)) afg.cabin_seg = np.zeros((max_seg_nb, afg.fus_nb)) afg.cabin_length = np.zeros((afg.fus_nb)) afg.fuse_cabin_vol = np.zeros((afg.fus_nb)) afg.fuse_nose_length = np.zeros((afg.fus_nb)) afg.fuse_tail_length = np.zeros((afg.fus_nb)) afg.fuse_fuel_vol = np.zeros((afg.fus_nb)) for i in range(1, afg.fus_nb + 1): ex = False cabin_seg = np.zeros((max_seg_nb, 1)) cabin_nb = 0 cabin_length = 0 cabin_volume = 0 nose_length = 0 tail_length = 0 if not F_FUEL[i - 1]: for j in range(1, afg.fuse_seg_nb[i - 1] + 1): if round(afg.fuse_sec_width[j][i - 1], 3) == round( np.amax(afg.fuse_sec_width[:, i - 1]), 3) and (h_min <= afg.fuse_sec_height[j, i - 1]): cabin_length += afg.fuse_seg_length[j - 1, i - 1] cabin_volume += afg.fuse_seg_vol[j - 1, i - 1] cabin_seg[j - 1] = 1 c = True elif not c: nose_length += afg.fuse_seg_length[j - 1, i - 1] if cabin_length >= 0.65 * afg.fuse_length[i - 1]: # If the aircraft is designed with 1 or more sections with # maximum width and the sun of their length is greater the 65% # of the total length, the cabin will be considered only in those # sections tail_length = afg.fuse_length[i - 1] - cabin_length - nose_length cabin_nb = 1 ex = True while ex is False: c = False cabin_seg[:] = 0 nose_length = 0 tail_length = 0 cabin_length = 0 cabin_volume = 0 for j in range(1, afg.fuse_seg_nb[i - 1] + 1): if afg.fuse_sec_width[j][i - 1] >= ( corr[i - 1] * afg.fuse_mean_width[i - 1]) and ( h_min <= afg.fuse_sec_height[j, i - 1]): cabin_length += afg.fuse_seg_length[j - 1, i - 1] cabin_volume += afg.fuse_seg_vol[j - 1, i - 1] cabin_seg[j - 1] = 1 c += 1 elif c > 1: tail_length += afg.fuse_seg_length[j - 1, i - 1] else: nose_length += afg.fuse_seg_length[j - 1, i - 1] if corr[i - 1] > 0.0 and cabin_length < ( 0.20 * afg.fuse_length[i - 1]): corr[i - 1] -= 0.05 else: ex = True afg.fuse_nose_length[i - 1] = round(nose_length, 3) afg.fuse_fuel_vol[i - 1] = 0 afg.fuse_tail_length[i - 1] = round(tail_length, 3) afg.fuse_cabin_length[i - 1] = round(cabin_length, 3) afg.fuse_cabin_vol[i - 1] = round(cabin_volume, 3) afg.cabin_nb[i - 1] = cabin_nb afg.cabin_seg[:, i - 1] = cabin_seg[:, 0] afg.fuse_cabin_length[i - 1] = round(cabin_length, 3) cabin_area = 0 for j in range(0, afg.fuse_seg_nb[i - 1]): if afg.cabin_seg[j, i - 1] == 1: (x11, y11, _) = (x1[j, i - 1], y1[j, i - 1], z1[j, i - 1]) (x12, y12, _) = (x1[j + 1, i - 1], y1[j + 1, i - 1], z1[j + 1, i - 1]) (x21, y21, _) = (x2[j, i - 1], y2[j, i - 1], z2[j, i - 1]) (x22, y22, _) = (x2[j + 1, i - 1], y2[j + 1, i - 1], z2[j + 1, i - 1]) cabin_area += 0.5 * abs( x11 * y12 + x12 * y22 + x22 * y21 + x21 * y11 - (y11 * x12 + y12 * x22 + y22 * x21 + y21 * x11)) elif cabin_area > 0 and afg.cabin_seg[j, i - 1] == 0: break thick_area = afg.fuse_cabin_length[i - 1] * (fuse_thick * 2.0) afg.cabin_area[i - 1] = round((cabin_area - thick_area), 3) else: afg.fuse_fuel_vol[i - 1] *= F_FUEL[i - 1] / 100.0 afg.fuse_nose_length[i - 1] = 0 afg.fuse_tail_length[i - 1] = 0 afg.fuse_cabin_length[i - 1] = 0 afg.fuse_cabin_vol[i - 1] = 0 afg.cabin_area[i - 1] = 0 tixi.save(cpacs_in) # log info display ------------------------------------------------------------ log.info("-----------------------------------------------------------") log.info("---------- Fuselage Geometry Evaluations ------------------") log.info("---------- USEFUL INFO ----------------------------------\n" + "If fuselage number is greater than 1 the\n" + "informations of each obj are listed in an\n " + "array ordered progressively") log.info("-----------------------------------------------------------") log.info("---------- Fuselage Results -------------------------------") log.info("Number of fuselage [-]: " + str(afg.fus_nb)) log.info("Number of fuselage sections [-]: " + str(afg.fuse_sec_nb)) log.info("Number of fuselage segments [-]: " + str(afg.fuse_seg_nb)) log.info("Cabin segments array [-]:\n" + str(cabin_seg)) log.info("Fuse Length [m]:\n" + str(afg.fuse_length)) log.info("Fuse nose Length [m]:\n" + str(afg.fuse_nose_length)) log.info("Fuse cabin Length [m]:\n" + str(afg.fuse_cabin_length)) log.info("Fuse tail Length [m]:\n" + str(afg.fuse_tail_length)) log.info("Aircraft Length [m]: " + str(afg.tot_length)) log.info("Perimeter of each section of each fuselage [m]: \n" + str(afg.fuse_sec_per)) log.info("Relative distance of each section of each fuselage [m]: \n" + str(afg.fuse_sec_rel_dist)) log.info("Length of each segment of each fuselage [m]: \n" + str(afg.fuse_seg_length)) log.info("Mean fuselage width [m]: " + str(afg.fuse_mean_width)) log.info("Width of each section of each fuselage [m]: \n" + str(afg.fuse_sec_width)) log.info("Cabin area [m^2]:\n" + str(afg.cabin_area)) log.info("Fuselage wetted surface [m^2]:\n" + str(afg.fuse_surface)) log.info("Volume of all the segmetns of each fuselage [m^3]: \n" + str(afg.fuse_seg_vol)) log.info("Volume of each cabin [m^3]:\n" + str(afg.fuse_cabin_vol)) log.info("Volume of each fuselage [m^3]:\n" + str(afg.fuse_vol)) log.info("Volume of fuel in each fuselage [m^3]:\n" + str(afg.fuse_fuel_vol)) log.info("-----------------------------------------------------------") return afg
def wing_geom_eval(ag, cpacs_in): """Main function to evaluate the wings geometry ARGUMENTS (class) ag --Arg.: AircraftGeometry class. # ======= Class are defined in the InputClasses folder =======## (char) cpacs_in -- Arg.: Cpacs xml file location. RETURN (class) ag --Out.: AircraftGeometry class updated. """ # ===========================================================================## log.info("---------------------------------------------") log.info("---------- Analysing wing geometry ----------") log.info("---------------------------------------------") # Opening tixi and tigl tixi = open_tixi(cpacs_in) tigl = open_tigl(tixi) # ---------------------------------------------------------------------------- # COUNTING 1 ----------------------------------------------------------------- # Counting wing number without symmetry -------------------------------------- # ---------------------------------------------------------------------------- w_nb = tixi.getNamedChildrenCount( "/cpacs/vehicles/aircraft\ /model/wings", "wing", ) # ---------------------------------------------------------------------------- # INITIALIZATION 1 ----------------------------------------------------------- # ---------------------------------------------------------------------------- ag.w_nb = w_nb ag.wing_nb = w_nb wing_plt_area_xz = [] wing_plt_area_yz = [] wingUID = [] # ---------------------------------------------------------------------------- # COUNTING 2 ----------------------------------------------------------------- # Counting sections and segments---------------------------------------------- # ---------------------------------------------------------------------------- b = 0 for i in range(1, w_nb + 1): double = 1 ag.wing_sym.append(tigl.wingGetSymmetry(i)) if ag.wing_sym[i - 1] != 0: double = 2 # To consider the real amount of wing # when they are defined using symmetry ag.wing_nb += 1 ag.wing_sec_nb.append(tigl.wingGetSectionCount(i)) ag.wing_seg_nb.append(tigl.wingGetSegmentCount(i)) ag.wing_vol.append(tigl.wingGetVolume(i) * double) # x-y plane ag.wing_plt_area.append(tigl.wingGetReferenceArea(i, 1) * double) # x-z plane wing_plt_area_xz.append(tigl.wingGetReferenceArea(i, 2) * double) # y-z plane wing_plt_area_yz.append(tigl.wingGetReferenceArea(i, 3) * double) ag.wing_tot_vol = ag.wing_tot_vol + ag.wing_vol[i - 1] wingUID.append(tigl.wingGetUID(i)) ag.wing_span.append(tigl.wingGetSpan(wingUID[i - 1])) a = np.amax(ag.wing_span) # Evaluating the index that corresponds to the main wing if a > b: ag.main_wing_index = i b = a # Checking segment and section connection and reordering them (ag.wing_sec_nb, start_index, seg_sec, wing_sec_index) = check_segment_connection( wing_plt_area_xz, wing_plt_area_yz, ag, tigl ) # ---------------------------------------------------------------------------- # INITIALIZATION 2 ----------------------------------------------------------- # ---------------------------------------------------------------------------- max_wing_sec_nb = np.amax(ag.wing_sec_nb) max_wing_seg_nb = np.amax(ag.wing_seg_nb) wing_center_section_point = np.zeros((max_wing_sec_nb, w_nb, 3)) ag.wing_center_seg_point = np.zeros((max_wing_seg_nb, ag.wing_nb, 3)) ag.wing_seg_vol = np.zeros((max_wing_seg_nb, w_nb)) ag.wing_fuel_seg_vol = np.zeros((max_wing_seg_nb, w_nb)) ag.wing_fuel_vol = 0 ag.wing_mac = np.zeros((4, w_nb)) ag.wing_sec_thicknes = np.zeros((max_wing_sec_nb + 1, w_nb)) # ===========================================================================## # ---------------------------------------------------------------------------- # WING ANALYSIS -------------------------------------------------------------- # ---------------------------------------------------------------------------- # Main wing plantform area ag.wing_plt_area_main = ag.wing_plt_area[ag.main_wing_index - 1] # Wing: MAC,chords,thicknes,span,plantform area ------------------------------ for i in range(1, w_nb + 1): mac = tigl.wingGetMAC(wingUID[i - 1]) (wpx, wpy, wpz) = tigl.wingGetChordPoint(i, 1, 0.0, 0.0) (wpx2, wpy2, wpz2) = tigl.wingGetChordPoint(i, 1, 0.0, 1.0) ag.wing_max_chord.append( np.sqrt((wpx2 - wpx) ** 2 + (wpy2 - wpy) ** 2 + (wpz2 - wpz) ** 2) ) (wpx, wpy, wpz) = tigl.wingGetChordPoint(i, ag.wing_seg_nb[i - 1], 1.0, 0.0) (wpx2, wpy2, wpz2) = tigl.wingGetChordPoint(i, ag.wing_seg_nb[i - 1], 1.0, 1.0) ag.wing_min_chord.append( np.sqrt((wpx2 - wpx) ** 2 + (wpy2 - wpy) ** 2 + (wpz2 - wpz) ** 2) ) for k in range(1, 5): ag.wing_mac[k - 1][i - 1] = mac[k - 1] for jj in range(1, ag.wing_seg_nb[i - 1] + 1): j = int(seg_sec[jj - 1, i - 1, 2]) cle = tigl.wingGetChordPoint(i, j, 0.0, 0.0) ag.wing_seg_vol[j - 1][i - 1] = tigl.wingGetSegmentVolume(i, j) lp = tigl.wingGetLowerPoint(i, j, 0.0, 0.0) up = tigl.wingGetUpperPoint(i, j, 0.0, 0.0) if np.all(cle == lp): L = 0.25 else: L = 0.75 if np.all(cle == up): U = 0.25 else: U = 0.75 (wplx, wply, wplz) = tigl.wingGetLowerPoint(i, j, 0.0, L) (wpux, wpuy, wpuz) = tigl.wingGetUpperPoint(i, j, 0.0, U) wing_center_section_point[j - 1][i - 1][0] = (wplx + wpux) / 2 wing_center_section_point[j - 1][i - 1][1] = (wply + wpuy) / 2 wing_center_section_point[j - 1][i - 1][2] = (wplz + wpuz) / 2 ag.wing_sec_thicknes[j - 1][i - 1] = np.sqrt( (wpux - wplx) ** 2 + (wpuy - wply) ** 2 + (wpuz - wplz) ** 2 ) j = int(seg_sec[ag.wing_seg_nb[i - 1] - 1, i - 1, 2]) (wplx, wply, wplz) = tigl.wingGetLowerPoint(i, ag.wing_seg_nb[i - 1], 1.0, L) (wpux, wpuy, wpuz) = tigl.wingGetUpperPoint(i, ag.wing_seg_nb[i - 1], 1.0, U) ag.wing_sec_thicknes[j][i - 1] = np.sqrt( (wpux - wplx) ** 2 + (wpuy - wply) ** 2 + (wpuz - wplz) ** 2 ) wing_center_section_point[ag.wing_seg_nb[i - 1]][i - 1][0] = (wplx + wpux) / 2 wing_center_section_point[ag.wing_seg_nb[i - 1]][i - 1][1] = (wply + wpuy) / 2 wing_center_section_point[ag.wing_seg_nb[i - 1]][i - 1][2] = (wplz + wpuz) / 2 ag.wing_sec_mean_thick.append( np.mean(ag.wing_sec_thicknes[0 : ag.wing_seg_nb[i - 1] + 1, i - 1]) ) # Evaluating wing fuel tank volume in the main wings if abs(round(ag.wing_plt_area[i - 1], 3) - ag.wing_plt_area_main) < 0.001: tp_ratio = ag.wing_min_chord[i - 1] / ag.wing_max_chord[i - 1] ratio = round(tp_ratio * ag.wing_plt_area[i - 1] / 100, 1) if ratio >= 1.0: ag.wing_fuel_vol = round(ag.wing_vol[i - 1] * 0.8, 2) elif ratio >= 0.5: ag.wing_fuel_vol = round(ag.wing_vol[i - 1] * 0.72, 2) else: ag.wing_fuel_vol = round(ag.wing_vol[i - 1] * 0.5, 2) for j in seg_sec[:, i - 1, 2]: if j == 0.0: break ag.wing_fuel_seg_vol[int(j) - 1][i - 1] = round( (ag.wing_seg_vol[int(j) - 1][i - 1] / (sum(ag.wing_vol))) * ag.wing_fuel_vol, 2 ) if ( ag.wing_plt_area[i - 1] > wing_plt_area_xz[i - 1] and ag.wing_plt_area[i - 1] > wing_plt_area_yz[i - 1] ): ag.is_horiz.append(True) if ag.wing_sym[i - 1] != 0: ag.is_horiz.append(True) else: ag.is_horiz.append(False) if ag.wing_sym[i - 1] != 0: ag.is_horiz.append(False) # Wing segment length evaluatin function ag = get_wing_segment_length(ag, wing_center_section_point) # Evaluating the point at the center of each segment, the center # is placed at 1/4 of the chord, symmetry is considered. a = 0 c = False for i in range(1, int(ag.wing_nb) + 1): if c: c = False continue for jj in range(1, ag.wing_seg_nb[i - a - 1] + 1): j = int(seg_sec[jj - 1, i - a - 1, 2]) ag.wing_center_seg_point[j - 1][i - 1][0] = ( wing_center_section_point[j - 1][i - a - 1][0] + wing_center_section_point[j][i - a - 1][0] ) / 2 ag.wing_center_seg_point[j - 1][i - 1][1] = ( wing_center_section_point[j - 1][i - a - 1][1] + wing_center_section_point[j][i - a - 1][1] ) / 2 ag.wing_center_seg_point[j - 1][i - 1][2] = ( wing_center_section_point[j - 1][i - a - 1][2] + wing_center_section_point[j][i - a - 1][2] ) / 2 if ag.wing_sym[i - 1 - a] != 0: if ag.wing_sym[i - 1 - a] == 1: symy = 1 symx = 1 symz = -1 if ag.wing_sym[i - 1 - a] == 2: symy = -1 symx = 1 symz = 1 if ag.wing_sym[i - 1 - a] == 3: symy = 1 symx = -1 symz = 1 ag.wing_center_seg_point[:, i, 0] = ag.wing_center_seg_point[:, i - 1, 0] * symx ag.wing_center_seg_point[:, i, 1] = ag.wing_center_seg_point[:, i - 1, 1] * symy ag.wing_center_seg_point[:, i, 2] = ag.wing_center_seg_point[:, i - 1, 2] * symz c = True a += 1 ag.w_seg_sec = seg_sec tixi.save(cpacs_in) # log info display ------------------------------------------------------------ log.info("---------------------------------------------") log.info("--------------- Wing Results ----------------") log.info("Number of Wings [-]: " + str(ag.wing_nb)) log.info("Wing symmetry plane [-]: " + str(ag.wing_sym)) log.info("Number of wing sections (not counting symmetry) [-]: " + str(ag.wing_sec_nb)) log.info("Number of wing segments (not counting symmetry) [-]: " + str(ag.wing_seg_nb)) log.info("Wing Span [m]: " + str(ag.wing_span)) log.info( "Wing MAC length [m]: " + str( ag.wing_mac[ 0, ] ) ) log.info( "Wing MAC x,y,z coordinate [m]: \n" + str( ag.wing_mac[ 1:4, ] ) ) log.info("Wings sections thicknes [m]: " + str(ag.wing_sec_thicknes)) log.info("Wings sections mean thicknes [m]: " + str(ag.wing_sec_mean_thick)) log.info("Wing segments length [m]: " + str(ag.wing_seg_length)) log.info("Wing max chord length [m]: " + str(ag.wing_max_chord)) log.info("Wing min chord length [m]: " + str(ag.wing_min_chord)) log.info("Main wing plantform area [m^2]: " + str(ag.wing_plt_area_main)) log.info("Wings plantform area [m^2]: " + str(ag.wing_plt_area)) log.info("Volume of each wing [m^3]: " + str(ag.wing_vol)) log.info("Total wing volume [m^3]: " + str(ag.wing_tot_vol)) log.info("Wing volume for fuel storage [m^3]: " + str(ag.wing_fuel_vol)) log.info("---------------------------------------------") return ag
def wing_check_thickness(h_min, awg, cpacs_in, TP, FUEL_ON_CABIN=0): """The fuction subdivides the main wing into nodes and defines the fuel and cabin volumes. Args: h_min (float): Minimum height for the fuselage [m]. awg (class): AircraftWingGeometry class look at aircraft_geometry_class.py in the classes folder for explanation. cpacs_in (str): Path to the CPACS file. TP (boolean): True if the aircraft is a turboprop. FUEL_ON_CABIN (float): Percentage of the cabin volume used for fuel storaging instead for passengers. (default 0%) Returns: wing_nodes (float-array): 3D array containing the nodes coordinates (x,y,z) [m,m,m]. awg (class): AircraftWingGeometry class look at aircraft_geometry_class.py in the classes folder for explanation. """ log.info("-----------------------------------------------------------") log.info("----------- Evaluating fuselage and wing volume -----------") log.info("-----------------------------------------------------------") tixi = open_tixi(cpacs_in) tigl = open_tigl(tixi) SPACING = 0.1 subd_c = 30 # Number of subdivisions along the perimeter on eachsurface, # total number of points for each section subd_c * 2 DEN = 0.0 w = awg.main_wing_index - 1 wing_nodes = 0 c = False for d in range(1, subd_c + 2): DEN += d zeta = 1.0 / DEN for i in awg.w_seg_sec[:, w, 2]: if i == 0.0: break w_temp = np.zeros((2, subd_c + 2, 3)) # Number of subdivisions along the longitudinal axis subd_l = math.ceil((awg.wing_seg_length[int(i) - 1][w] / SPACING)) if subd_l == 0: subd_l = 1 eta = 1.0 / subd_l et = 0.0 (xc, yc, zc) = awg.wing_center_seg_point[int(i) - 1][w][:] for j in range(0, int(subd_l) - 1): (xle, yle, zle) = tigl.wingGetLowerPoint(w + 1, int(i), et, 0.0) (xle2, yle2, zle2) = tigl.wingGetLowerPoint(w + 1, int(i), et, 1.0) if xle < xle2: ZLE = 0.0 ze = 0.0 else: ZLE = 1.0 ze = 1.0 for k in range(0, subd_c + 2): if ZLE == 0.0: ze += float(k) * zeta elif ZLE == 1.0: ze -= float(k) * zeta (xl, yl, zl) = tigl.wingGetLowerPoint(w + 1, int(i), et, ze) (xu, yu, zu) = tigl.wingGetUpperPoint(w + 1, int(i), et, ze) w_temp[0, k, :] = (xu, yu, zu) w_temp[1, k, :] = (xl, yl, zl) if c is False: wing_nodes = w_temp c = True else: wing_nodes = np.concatenate((wing_nodes, w_temp), axis=0) et = j * eta (rows, columns, pages) = wing_nodes.shape # wing_nodes 3D matrix: the even rows and the zero row correspond # to the upper profile of the wing, while all the odd rows correspond # to the lower profile. The columns contain the coordinates of each nodes. # The page 0,1 and 2 contain respectively the x,y and z coordinate. h_max = [] h_mean = [] y_sec = [] for r in range(0, rows - 1, 2): h_max_temp = 0 z_min = 9999 z_max = 0 h = [] for c in range(0, columns): (xu, yu, zu) = wing_nodes[r, c, :] (xl, yl, zl) = wing_nodes[r + 1, c, :] h.append(abs(zu - zl)) if abs(zu - zl) > h_max_temp: h_max_temp = abs(zu - zl) if r == 0: if zl < z_min: (_, y13, z13) = (xl, yl, zl) z_min = zl if zu > z_max: (_, y14, z14) = (xu, yu, zu) z_max = zu else: if zl < z_min: (x23_t, y23_t, z23_t) = (xl, yl, zl) z_min = zl if zu > z_max: (x24_t, y24_t, z24_t) = (xu, yu, zu) z_max = zu h_max.append(h_max_temp) h_mean.append(np.mean(h)) y_sec.append(yl) if np.mean(h) >= h_min: # h_mean_cabin = np.mean(h_mean) awg.y_max_cabin = yl seg = r if r != 0: (_, y23, z23) = (x23_t, y23_t, z23_t) (_, y24, z24) = (x24_t, y24_t, z24_t) else: (x11, y11, z11) = wing_nodes[0, 0, :] (x12, y12, z12) = wing_nodes[0, -1, :] (x21, y21, z21) = wing_nodes[seg, 0, :] (x22, y22, z22) = wing_nodes[seg, -1, :] break for c in range(0, columns): (xu, yu, zu) = wing_nodes[0, c, :] (xl, yl, zl) = wing_nodes[1, c, :] if abs(zu - zl) >= h_min: xs1 = xu yse1 = yl break for c in range(0, columns): (xu, yu, zu) = wing_nodes[seg, c, :] (xl, yl, zl) = wing_nodes[seg + 1, c, :] if abs(zu - zl) >= h_min: xs2 = xu yse2 = yl break for c in range(columns - 1, -1, -1): (xu, yu, zu) = wing_nodes[0, c, :] (xl, yl, zl) = wing_nodes[1, c, :] if abs(zu - zl) >= h_min: xe1 = xu break for c in range(columns - 1, -1, -1): (xu, yu, zu) = wing_nodes[seg, c, :] (xl, yl, zl) = wing_nodes[seg + 1, c, :] if abs(zu - zl) >= h_min: xe2 = xu # ze2u = zu # ze2l = zl break awg.cabin_area = 0.5 * abs(xs1 * yse2 + xs2 * yse2 + xe2 * yse1 + xe1 * yse1 - xs2 * yse1 - xe2 * yse2 - xe1 * yse2 - xs1 * yse1) fuse_plt_area = 0.5 * abs(x11 * y21 + x21 * y22 + x22 * y12 + x12 * y11 - x21 * y11 - x22 * y21 - x12 * y22 - x11 * y12) fuse_frontal_area = 0.5 * abs(y24 * z23 + y23 * z13 + y13 * z14 + y14 * z24 - z24 * y23 - z23 * y13 - z13 * y14 - z14 * y24) c1 = math.sqrt((x11 - x12)**2 + (y11 - y12)**2 + (z11 - z12)**2) c2 = math.sqrt((x21 - x22)**2 + (y21 - y22)**2 + (z21 - z22)**2) awg.cabin_span = abs(awg.y_max_cabin - y11) awg.fuse_vol = ((0.95 * fuse_frontal_area) * (fuse_plt_area / (awg.cabin_span)) / (math.sqrt(1 + (c2 / c1)))) if awg.wing_sym[w - 1] != 0: awg.fuse_vol *= 2 awg.cabin_area *= 2 awg.cabin_vol = awg.cabin_area * h_min delta_vol = awg.fuse_vol - awg.cabin_vol awg.fuse_fuel_vol = (float(FUEL_ON_CABIN) / 100.0) * delta_vol if TP: t = 0.5 else: t = 0.55 awg.wing_fuel_vol = t * (awg.wing_vol[w] - awg.fuse_vol) awg.fuel_vol_tot = awg.fuse_fuel_vol + awg.wing_fuel_vol # log info display ------------------------------------------------------------ log.info("--------------------- Main wing Volumes -------------------") log.info("Wing volume [m^3]: " + str(awg.wing_vol[w])) log.info("Cabin volume [m^3]: " + str(awg.cabin_vol)) log.info("Volume of the wing as fuselage [m^3]: " + str(awg.fuse_vol)) log.info("Volume of the remaining portion of the wing [m^3]: " + str(awg.wing_vol[w] - awg.fuse_vol)) log.info("Fuel volume in the fuselage [m^3]: " + str(awg.fuse_fuel_vol)) log.info("Fuel volume in the wing [m^3]: " + str(awg.wing_fuel_vol)) log.info("Total fuel Volume [m^3]: " + str(awg.fuel_vol_tot)) log.info("-----------------------------------------------------------") return (awg, wing_nodes)