def test_static_stability_analysis(): """Test function 'staticStabilityAnalysis'""" MODULE_DIR = os.path.dirname(os.path.abspath(__file__)) cpacs_path = os.path.join(MODULE_DIR, "ToolInput", "CPACSTestStability.xml") cpacs_out_path = os.path.join(MODULE_DIR, "ToolOutput", "CPACSTestStability.xml") csv_path = MODULE_DIR + "/ToolInput/csvtest.csv" tixi = open_tixi(cpacs_path) # Get Aeromap UID list # aeromap_uid = uid_list[0] # # Import aeromap from the CSV to the xml # close_tixi(tixi, cpacs_out_path) # Make the static stability analysis, on the modified xml file static_stability_analysis(cpacs_path, cpacs_out_path) tixi = open_tixi(cpacs_out_path) static_xpath = "/cpacs/toolspecific/CEASIOMpy/stability/static" long_static_stable = get_value(tixi, static_xpath + "/results/longitudinalStaticStable") lat_static_stable = get_value(tixi, static_xpath + "/results/lateralStaticStable") dir_static_stable = get_value(tixi, static_xpath + "/results/directionnalStaticStable") assert long_static_stable assert lat_static_stable assert not dir_static_stable trim_longi_alt = get_value(tixi, static_xpath + "/trimConditions/longitudinal/altitude") trim_longi_mach = get_value(tixi, static_xpath + "/trimConditions/longitudinal/machNumber") trim_longi_aoa = get_value(tixi, static_xpath + "/trimConditions/longitudinal/angleOfAttack") trim_longi_aos = get_value(tixi, static_xpath + "/trimConditions/longitudinal/angleOfSideslip") assert trim_longi_alt == 1400 assert trim_longi_mach == 0.6 assert trim_longi_aoa == 3.25808 assert trim_longi_aos == 0 trim_dir_alt = get_string_vector(tixi, static_xpath + "/trimConditions/directional/altitude") trim_dir_mach = get_string_vector( tixi, static_xpath + "/trimConditions/directional/machNumber" ) trim_dir_aoa = get_string_vector( tixi, static_xpath + "/trimConditions/directional/angleOfAttack" ) trim_dir_aos = get_string_vector( tixi, static_xpath + "/trimConditions/directional/angleOfSideslip" ) assert trim_dir_alt == ["2400", "2500", "2600", "2700"] assert trim_dir_mach == ["0.6", "0.5", "0.5", "0.5"] assert trim_dir_aoa == ["1", "2", "4", "2.5"] assert trim_dir_aos == ["0", "0", "0", "0"] tixi.save(cpacs_out_path)
def export_aeromaps(cpacs_path, cpacs_out_path): cpacs = CPACS(cpacs_path) aeromap_to_export_xpath = CEASIOMPY_XPATH + "/export/aeroMapToExport" aeromap_uid_list = [] aeromap_uid_list = get_string_vector(cpacs.tixi, aeromap_to_export_xpath) results_dir = get_results_directory("ExportCSV") for aeromap_uid in aeromap_uid_list: aeromap = cpacs.get_aeromap_by_uid(aeromap_uid) csv_path = Path(results_dir, f"{aeromap_uid}.csv") aeromap.export_csv(csv_path) log.info(f"Aeromap(s) has been saved to {csv_path}") cpacs.save_cpacs(cpacs_out_path, overwrite=True)
def plot_aero_coef(cpacs_path, cpacs_out_path): """Plot Aero coefficients from the chosen aeroMap in the CPACS file Function 'plot_aero_coef' can plot one or several aeromap from the CPACS file according to some user option, these option will be shown in the the SettingGUI or default values will be used. Args: cpacs_path (str): Path to CPACS file cpacs_out_path (str):Path to CPACS output file """ # Open TIXI handle cpacs = CPACS(cpacs_path) # Get aeroMap list to plot aeromap_to_plot_xpath = PLOT_XPATH + "/aeroMapToPlot" aeromap_uid_list = [] # Option to select aeromap manualy manual_selct = get_value_or_default(cpacs.tixi, PLOT_XPATH + "/manualSelection", False) if manual_selct: aeromap_uid_list = open_select_aeromap_gui(cpacs) create_branch(cpacs.tixi, aeromap_to_plot_xpath) add_string_vector(cpacs.tixi, aeromap_to_plot_xpath, aeromap_uid_list) else: try: aeromap_uid_list = get_string_vector(cpacs.tixi, aeromap_to_plot_xpath) except ValueError: # If aeroMapToPlot is not define, select manualy anyway aeromap_uid_list = open_select_aeromap_gui(cpacs) create_branch(cpacs.tixi, aeromap_to_plot_xpath) add_string_vector(cpacs.tixi, aeromap_to_plot_xpath, aeromap_uid_list) # Create DataFrame from aeromap(s) aeromap_df_list = [] for aeromap_uid in aeromap_uid_list: aeromap_df = cpacs.get_aeromap_by_uid(aeromap_uid).df aeromap_df["uid"] = aeromap_uid aeromap_df_list.append(aeromap_df) aeromap = pd.concat(aeromap_df_list, ignore_index=True) if len(aeromap_uid_list) > 1: uid_crit = None else: uid_crit = aeromap_uid_list[0] # Default options title = cpacs.ac_name criterion = pd.Series([True] * len(aeromap.index)) groupby_list = ["uid", "machNumber", "altitude", "angleOfSideslip"] # Get criterion from CPACS crit_xpath = PLOT_XPATH + "/criterion" alt_crit = get_value_or_default(cpacs.tixi, crit_xpath + "/alt", "None") mach_crit = get_value_or_default(cpacs.tixi, crit_xpath + "/mach", "None") aos_crit = get_value_or_default(cpacs.tixi, crit_xpath + "/aos", "None") cpacs.save_cpacs(cpacs_out_path, overwrite=True) # Modify criterion and title according to user option if len(aeromap["altitude"].unique()) == 1: title += " - Alt = " + str(aeromap["altitude"].loc[0]) groupby_list.remove("altitude") elif alt_crit not in NONE_LIST: criterion = criterion & (aeromap.altitude == alt_crit) title += " - Alt = " + str(alt_crit) groupby_list.remove("altitude") if len(aeromap["machNumber"].unique()) == 1: title += " - Mach = " + str(aeromap["machNumber"].loc[0]) groupby_list.remove("machNumber") elif mach_crit not in NONE_LIST: criterion = criterion & (aeromap.machNumber == mach_crit) title += " - Mach = " + str(mach_crit) groupby_list.remove("machNumber") if len(aeromap["angleOfSideslip"].unique()) == 1: title += " - AoS = " + str(aeromap["angleOfSideslip"].loc[0]) groupby_list.remove("angleOfSideslip") elif aos_crit not in NONE_LIST: criterion = criterion & (aeromap.angleOfSideslip == aos_crit) title += " - AoS = " + str(aos_crit) groupby_list.remove("angleOfSideslip") if uid_crit is not None and len(groupby_list) > 1: criterion = criterion & (aeromap.uid == uid_crit) title += " - " + uid_crit groupby_list.remove("uid") # Plot settings fig, axs = plt.subplots(2, 3) fig.suptitle(title, fontsize=14) fig.set_figheight(8) fig.set_figwidth(15) fig.subplots_adjust(left=0.06) axs[0, 1].axhline(y=0.0, color="k", linestyle="-") # Line at Cm=0 # Plot aerodynamic coerfficients for value, grp in aeromap.loc[criterion].groupby(groupby_list): legend = write_legend(groupby_list, value) axs[0, 0].plot(grp["angleOfAttack"], grp["cl"], "x-", label=legend) axs[1, 0].plot(grp["angleOfAttack"], grp["cd"], "x-") axs[0, 1].plot(grp["angleOfAttack"], grp["cms"], "x-") axs[1, 1].plot(grp["angleOfAttack"], grp["cl"] / grp["cd"], "x-") axs[0, 2].plot(grp["cd"], grp["cl"], "x-") axs[1, 2].plot(grp["cl"], grp["cl"] / grp["cd"], "x-") # Set subplot options subplot_options(axs[0, 0], "CL", "AoA") subplot_options(axs[1, 0], "CD", "AoA") subplot_options(axs[0, 1], "Cm", "AoA") subplot_options(axs[1, 1], "CL/CD", "AoA") subplot_options(axs[0, 2], "CL", "CD") subplot_options(axs[1, 2], "CL/CD", "CL") fig.legend(loc="upper right") plt.show()
def __init__(self, tabs, cpacs, module_name): """Tab class Note: A tab will only be created if the module actually has any settings which are to be shown Args: tabs (object): Tab object cpacs (object): CPACS object module_name (str): String of the module name for which a tab is to be created """ self.var_dict = {} self.group_dict = {} self.module_name = module_name self.tabs = tabs self.cpacs = cpacs self.tab = tk.Frame(tabs, borderwidth=1) tabs.add(self.tab, text=module_name) # Get GUI dict from specs specs = mi.get_specs_for_module(module_name) self.gui_dict = specs.cpacs_inout.get_gui_dict() # canvas has replaced self.tab in the following lines space_label = tk.Label(self.tab, text=" ") space_label.grid(column=0, row=0) row_pos = 1 for ( key, (name, def_value, dtype, unit, xpath, description, group), ) in self.gui_dict.items(): # Create a LabelFrame for new groupe if group: if group not in self.group_dict: self.labelframe = tk.LabelFrame(self.tab, text=group) self.labelframe.grid( column=0, row=row_pos, columnspan=3, sticky=tk.W, padx=15, pady=5 ) self.group_dict[group] = self.labelframe parent = self.group_dict[group] else: # if not a group, use tab as parent parent = self.tab # Name label for variable if name not in ["__AEROMAP_SELECTION", "__AEROMAP_CHECHBOX"]: self.name_label = tk.Label(parent, text=name) self.name_label.grid(column=0, row=row_pos, sticky=tk.W, padx=5, pady=5) # Type and Value if dtype is bool: self.var_dict[key] = tk.BooleanVar() value = get_value_or_default(self.cpacs.tixi, xpath, def_value) self.var_dict[key].set(value) bool_entry = tk.Checkbutton(parent, text="", variable=self.var_dict[key]) bool_entry.grid(column=1, row=row_pos, padx=5, pady=5) elif dtype is int: value = get_value_or_default(self.cpacs.tixi, xpath, def_value) self.var_dict[key] = tk.IntVar() self.var_dict[key].set(int(value)) value_entry = tk.Entry(parent, bd=2, width=8, textvariable=self.var_dict[key]) value_entry.grid(column=1, row=row_pos, padx=5, pady=5) elif dtype is float: value = get_value_or_default(self.cpacs.tixi, xpath, def_value) self.var_dict[key] = tk.DoubleVar() self.var_dict[key].set(value) value_entry = tk.Entry(parent, bd=2, width=8, textvariable=self.var_dict[key]) value_entry.grid(column=1, row=row_pos, padx=5, pady=5) elif dtype == "pathtype": value = get_value_or_default(self.cpacs.tixi, xpath, def_value) self.var_dict[key] = tk.StringVar() self.var_dict[key].set(value) value_entry = tk.Entry(parent, textvariable=self.var_dict[key]) value_entry.grid(column=1, row=row_pos, padx=5, pady=5) self.key = key self.browse_button = tk.Button(parent, text="Browse", command=self._browse_file) self.browse_button.grid(column=2, row=row_pos, padx=5, pady=5) elif dtype is list: if name == "__AEROMAP_SELECTION": # Get the list of all AeroMaps self.aeromap_uid_list = self.cpacs.get_aeromap_uid_list() # Try to get the pre-selected AeroMap from the xpath try: selected_aeromap = get_value(self.cpacs.tixi, xpath) selected_aeromap_index = self.aeromap_uid_list.index(selected_aeromap) except: selected_aeromap = "" selected_aeromap_index = 0 self.labelframe = tk.LabelFrame(parent, text="Choose an AeroMap") self.labelframe.grid( column=0, row=row_pos, columnspan=3, sticky=tk.W, padx=15, pady=5 ) # The Combobox is directly use as the varaible self.var_dict[key] = ttk.Combobox( self.labelframe, values=self.aeromap_uid_list ) self.var_dict[key].current(selected_aeromap_index) self.var_dict[key].grid(column=1, row=row_pos, padx=15, pady=5) elif name == "__AEROMAP_CHECHBOX": # Just to find back the name when data are saved self.var_dict[key] = None # __AEROMAP_CHECHBOX is a bit different, data are saved in their own dictionary self.aeromap_var_dict = {} # Get the list of all AeroMaps self.aeromap_uid_list = self.cpacs.get_aeromap_uid_list() self.labelframe = tk.LabelFrame(parent, text="Selecte AeroMap(s)") self.labelframe.grid( column=0, row=row_pos, columnspan=3, sticky=tk.W, padx=15, pady=5 ) # Try to get pre-selected AeroMaps from the xpath try: selected_aeromap = get_string_vector(self.cpacs.tixi, xpath) except ValueError: selected_aeromap = "" # Create one checkbox for each AeroMap for aeromap in self.aeromap_uid_list: self.aeromap_var_dict[aeromap] = tk.BooleanVar() # if aeromap in selected_aeromap: # For now, set all to True self.aeromap_var_dict[aeromap].set(True) aeromap_entry = tk.Checkbutton( self.labelframe, text=aeromap, variable=self.aeromap_var_dict[aeromap] ) aeromap_entry.pack(padx=5, pady=3, anchor=tk.W) # side=tk.TOP) else: # Other kind of list (not aeroMap) # 'def_value' will be the list of possibilies in this case # Try to get the pre-selected AeroMap from the xpath try: # TODO Should be retested... selected_value = get_value(self.cpacs.tixi, xpath) selected_value_index = def_value.index(selected_value) except: selected_value = "" selected_value_index = 0 # The Combobox is directly use as the varaible self.var_dict[key] = ttk.Combobox(parent, width=12, values=def_value) self.var_dict[key].current(selected_value_index) self.var_dict[key].grid(column=1, row=row_pos, padx=5, pady=5) else: value = get_value_or_default(self.cpacs.tixi, xpath, def_value) self.var_dict[key] = tk.StringVar() self.var_dict[key].set(value) value_entry = tk.Entry(parent, textvariable=self.var_dict[key]) value_entry.grid(column=1, row=row_pos, padx=5, pady=5) # Units if unit and unit != "1": unit_label = tk.Label(parent, text=pretty_unit(unit)) unit_label.grid(column=2, row=row_pos) row_pos += 1
def add_skin_friction(cpacs_path, cpacs_out_path): """Function to add the skin frictions drag coefficient to aerodynamic coefficients Function 'add_skin_friction' add the skin friction drag 'cd0' to the SU2 and pyTornado aeroMap, if their UID is not given, it will add skin friction to all aeroMap. For each aeroMap it creates a new aeroMap where the skin friction drag coefficient is added with the correct projections. Args: cpacs_path (str): Path to CPACS file cpacs_out_path (str): Path to CPACS output file """ # Load a CPACS file cpacs = CPACS(cpacs_path) analyses_xpath = "/cpacs/toolspecific/CEASIOMpy/geometry/analysis" # Required input data from CPACS wetted_area = get_value(cpacs.tixi, analyses_xpath + "/wettedArea") # Wing area/span, default values will be calculated if no value found in the CPACS file wing_area_xpath = analyses_xpath + "/wingArea" wing_area = get_value_or_default(cpacs.tixi, wing_area_xpath, cpacs.aircraft.wing_area) wing_span_xpath = analyses_xpath + "/wingSpan" wing_span = get_value_or_default(cpacs.tixi, wing_span_xpath, cpacs.aircraft.wing_span) # Get aeroMapToCalculate aeroMap_to_calculate_xpath = SF_XPATH + "/aeroMapToCalculate" if cpacs.tixi.checkElement(aeroMap_to_calculate_xpath): aeromap_uid_list = get_string_vector(cpacs.tixi, aeroMap_to_calculate_xpath) else: aeromap_uid_list = [] # If no aeroMap in aeroMapToCalculate, get all existing aeroMap if len(aeromap_uid_list) == 0: aeromap_uid_list = cpacs.get_aeromap_uid_list() if not aeromap_uid_list: raise ValueError( "No aeroMap has been found in this CPACS file, skin friction cannot be added!" ) # Get unique aeroMap list aeromap_uid_list = list(set(aeromap_uid_list)) new_aeromap_uid_list = [] # Add skin friction to all listed aeroMap for aeromap_uid in aeromap_uid_list: log.info("adding skin friction coefficients to: " + aeromap_uid) aeromap = cpacs.get_aeromap_by_uid(aeromap_uid) # Create new aeromap object to store coef with added skin friction aeromap_sf = cpacs.duplicate_aeromap(aeromap_uid, aeromap_uid + "_SkinFriction") aeromap_sf.description = ( aeromap_sf.description + " Skin friction has been add to this AeroMap.") # Add skin friction to all force coefficient (with projections) aeromap_sf.df["cd"] = aeromap.df.apply( lambda row: row["cd"] + estimate_skin_friction_coef( wetted_area, wing_area, wing_span, row["machNumber"], row[ "altitude"]) * math.cos(math.radians(row["angleOfAttack"])) * math.cos(math.radians(row["angleOfSideslip"])), axis=1, ) aeromap_sf.df["cl"] = aeromap.df.apply( lambda row: row["cl"] + estimate_skin_friction_coef( wetted_area, wing_area, wing_span, row[ "machNumber"], row["altitude"]) * math.sin( math.radians(row["angleOfAttack"])), axis=1, ) aeromap_sf.df["cs"] = aeromap.df.apply( lambda row: row["cs"] + estimate_skin_friction_coef( wetted_area, wing_area, wing_span, row["machNumber"], row[ "altitude"]) * math.sin( math.radians(row["angleOfSideslip"])), axis=1, ) # TODO: Should we change something in moment coef? # e.i. if a force is not apply at aero center...? aeromap_sf.save() # Get aeroMap list to plot plot_xpath = "/cpacs/toolspecific/CEASIOMpy/aerodynamics/plotAeroCoefficient" aeromap_to_plot_xpath = plot_xpath + "/aeroMapToPlot" if cpacs.tixi.checkElement(aeromap_to_plot_xpath): aeromap_uid_list = get_string_vector(cpacs.tixi, aeromap_to_plot_xpath) new_aeromap_to_plot = aeromap_uid_list + new_aeromap_uid_list new_aeromap_to_plot = list(set(new_aeromap_to_plot)) add_string_vector(cpacs.tixi, aeromap_to_plot_xpath, new_aeromap_to_plot) else: create_branch(cpacs.tixi, aeromap_to_plot_xpath) add_string_vector(cpacs.tixi, aeromap_to_plot_xpath, new_aeromap_uid_list) log.info('AeroMap "' + aeromap_uid + '" has been added to the CPACS file') cpacs.save_cpacs(cpacs_out_path, overwrite=True)
def generate_su2_cfd_config(cpacs_path, cpacs_out_path, wkdir): """Function to create SU2 confif file. Function 'generate_su2_cfd_config' reads data in the CPACS file and generate configuration files for one or multible flight conditions (alt,mach,aoa,aos) Source: * SU2 config template: https://github.com/su2code/SU2/blob/master/config_template.cfg Args: cpacs_path (str): Path to CPACS file cpacs_out_path (str):Path to CPACS output file wkdir (str): Path to the working directory """ # Get value from CPACS cpacs = CPACS(cpacs_path) # Get SU2 mesh path su2_mesh_path = get_value(cpacs.tixi, SU2MESH_XPATH) # Get SU2 settings max_iter_xpath = SU2_XPATH + "/settings/maxIter" max_iter = get_value_or_default(cpacs.tixi, max_iter_xpath, 200) cfl_nb_xpath = SU2_XPATH + "/settings/cflNumber" cfl_nb = get_value_or_default(cpacs.tixi, cfl_nb_xpath, 1.0) mg_level_xpath = SU2_XPATH + "/settings/multigridLevel" mg_level = get_value_or_default(cpacs.tixi, mg_level_xpath, 3) # Mesh Marker bc_wall_xpath = SU2_XPATH + "/boundaryConditions/wall" bc_farfield_xpath = SU2_XPATH + "/boundaryConditions/farfield" bc_wall_list, engine_bc_list = get_mesh_marker(su2_mesh_path) create_branch(cpacs.tixi, bc_wall_xpath) bc_wall_str = ";".join(bc_wall_list) cpacs.tixi.updateTextElement(bc_wall_xpath, bc_wall_str) create_branch(cpacs.tixi, bc_farfield_xpath) bc_farfiled_str = ";".join(engine_bc_list) cpacs.tixi.updateTextElement(bc_farfield_xpath, bc_farfiled_str) # Fixed CL parameters fixed_cl_xpath = SU2_XPATH + "/fixedCL" fixed_cl = get_value_or_default(cpacs.tixi, fixed_cl_xpath, "NO") target_cl_xpath = SU2_XPATH + "/targetCL" target_cl = get_value_or_default(cpacs.tixi, target_cl_xpath, 1.0) if fixed_cl == "NO": active_aeroMap_xpath = SU2_XPATH + "/aeroMapUID" aeromap_uid = get_value(cpacs.tixi, active_aeroMap_xpath) log.info( f'Configuration file for "{aeromap_uid}" calculation will be created.' ) active_aeromap = cpacs.get_aeromap_by_uid(aeromap_uid) # Get parameters of the aeroMap (altitude, machNumber, angleOfAttack, angleOfSideslip) alt_list = active_aeromap.get("altitude").tolist() mach_list = active_aeromap.get("machNumber").tolist() aoa_list = active_aeromap.get("angleOfAttack").tolist() aos_list = active_aeromap.get("angleOfSideslip").tolist() param_count = len(alt_list) else: # if fixed_cl == 'YES': log.info( "Configuration file for fixed CL calculation will be created.") # Parameters fixed CL calulation param_count = 1 # Create a new aeroMap fix_cl_aeromap = cpacs.create_aeromap("aeroMap_fixedCL_SU2") fix_cl_aeromap.description = "AeroMap created for SU2 fixed CL value of: " + str( target_cl) # Get cruise mach and altitude cruise_mach_xpath = RANGE_XPATH + "/cruiseMach" mach = get_value_or_default(cpacs.tixi, cruise_mach_xpath, 0.78) cruise_alt_xpath = RANGE_XPATH + "/cruiseAltitude" alt = get_value_or_default(cpacs.tixi, cruise_alt_xpath, 12000) # Add new parameters to the aeroMap and save it fix_cl_aeromap.add_row(alt=alt, mach=mach, aos=0.0, aoa=0.0) fix_cl_aeromap.save() # Parameter lists alt_list = [alt] mach_list = [mach] aoa_list = [0.0] aos_list = [0.0] # Get and modify the default configuration file cfg = ConfigFile(DEFAULT_CONFIG_PATH) # General parmeters cfg["REF_LENGTH"] = cpacs.aircraft.ref_lenght cfg["REF_AREA"] = cpacs.aircraft.ref_area cfg["REF_ORIGIN_MOMENT_X"] = cpacs.aircraft.ref_point_x cfg["REF_ORIGIN_MOMENT_Y"] = cpacs.aircraft.ref_point_y cfg["REF_ORIGIN_MOMENT_Z"] = cpacs.aircraft.ref_point_z # Settings cfg["INNER_ITER"] = int(max_iter) cfg["CFL_NUMBER"] = cfl_nb cfg["MGLEVEL"] = int(mg_level) # Fixed CL mode (AOA will not be taken into account) cfg["FIXED_CL_MODE"] = fixed_cl cfg["TARGET_CL"] = target_cl cfg["DCL_DALPHA"] = "0.1" cfg["UPDATE_AOA_ITER_LIMIT"] = "50" cfg["ITER_DCL_DALPHA"] = "80" # TODO: correct value for the 3 previous parameters ?? # Mesh Marker bc_wall_str = "(" + ",".join(bc_wall_list) + ")" cfg["MARKER_EULER"] = bc_wall_str cfg["MARKER_FAR"] = " (Farfield, " + ",".join(engine_bc_list) + ")" cfg["MARKER_SYM"] = " (0)" # TODO: maybe make that a variable? cfg["MARKER_PLOTTING"] = bc_wall_str cfg["MARKER_MONITORING"] = bc_wall_str cfg["MARKER_MOVING"] = "( NONE )" # TODO: when do we need to define MARKER_MOVING? cfg["DV_MARKER"] = bc_wall_str # Parameters which will vary for the different cases (alt,mach,aoa,aos) for case_nb in range(param_count): cfg["MESH_FILENAME"] = su2_mesh_path alt = alt_list[case_nb] mach = mach_list[case_nb] aoa = aoa_list[case_nb] aos = aos_list[case_nb] Atm = Atmosphere(alt) cfg["MACH_NUMBER"] = mach cfg["AOA"] = aoa cfg["SIDESLIP_ANGLE"] = aos cfg["FREESTREAM_PRESSURE"] = Atm.pressure[0] cfg["FREESTREAM_TEMPERATURE"] = Atm.temperature[0] cfg["ROTATION_RATE"] = "0.0 0.0 0.0" config_file_name = "ConfigCFD.cfg" case_dir_name = "".join([ "Case", str(case_nb).zfill(2), "_alt", str(alt), "_mach", str(round(mach, 2)), "_aoa", str(round(aoa, 1)), "_aos", str(round(aos, 1)), ]) case_dir_path = os.path.join(wkdir, case_dir_name) if not os.path.isdir(case_dir_path): os.mkdir(case_dir_path) config_output_path = os.path.join(wkdir, case_dir_name, config_file_name) cfg.write_file(config_output_path, overwrite=True) # Damping derivatives damping_der_xpath = SU2_XPATH + "/options/clalculateDampingDerivatives" damping_der = get_value_or_default(cpacs.tixi, damping_der_xpath, False) if damping_der: rotation_rate_xpath = SU2_XPATH + "/options/rotationRate" rotation_rate = get_value_or_default(cpacs.tixi, rotation_rate_xpath, 1.0) cfg["GRID_MOVEMENT"] = "ROTATING_FRAME" cfg["ROTATION_RATE"] = str(rotation_rate) + " 0.0 0.0" os.mkdir(os.path.join(wkdir, case_dir_name + "_dp")) config_output_path = os.path.join(wkdir, case_dir_name + "_dp", config_file_name) cfg.write_file(config_output_path, overwrite=True) cfg["ROTATION_RATE"] = "0.0 " + str(rotation_rate) + " 0.0" os.mkdir(os.path.join(wkdir, case_dir_name + "_dq")) config_output_path = os.path.join(wkdir, case_dir_name + "_dq", config_file_name) cfg.write_file(config_output_path, overwrite=True) cfg["ROTATION_RATE"] = "0.0 0.0 " + str(rotation_rate) os.mkdir(os.path.join(wkdir, case_dir_name + "_dr")) config_output_path = os.path.join(wkdir, case_dir_name + "_dr", config_file_name) cfg.write_file(config_output_path, overwrite=True) log.info("Damping derivatives cases directory has been created.") # Control surfaces deflections control_surf_xpath = SU2_XPATH + "/options/clalculateCotrolSurfacesDeflections" control_surf = get_value_or_default(cpacs.tixi, control_surf_xpath, False) if control_surf: # Get deformed mesh list su2_def_mesh_xpath = SU2_XPATH + "/availableDeformedMesh" if cpacs.tixi.checkElement(su2_def_mesh_xpath): su2_def_mesh_list = get_string_vector(cpacs.tixi, su2_def_mesh_xpath) else: log.warning("No SU2 deformed mesh has been found!") su2_def_mesh_list = [] for su2_def_mesh in su2_def_mesh_list: mesh_path = os.path.join(wkdir, "MESH", su2_def_mesh) config_dir_path = os.path.join( wkdir, case_dir_name + "_" + su2_def_mesh.split(".")[0]) os.mkdir(config_dir_path) cfg["MESH_FILENAME"] = mesh_path config_file_name = "ConfigCFD.cfg" config_output_path = os.path.join(wkdir, config_dir_path, config_file_name) cfg.write_file(config_output_path, overwrite=True) # TODO: change that, but if it is save in tooloutput it will be erease by results... cpacs.save_cpacs(cpacs_out_path, overwrite=True)