diff --git a/tank_design/src/tube_and_wing/empirical/tank_design_tu_berlin/general/call_functions/_00_readenergycarrierandtankconfiguration.py b/tank_design/src/tube_and_wing/empirical/tank_design_tu_berlin/general/call_functions/_00_readenergycarrierandtankconfiguration.py index b4c787bc0980caeb1909d164cdd1b04c0dd9a64e..792cd19a046cb6e8169fc4aff537c936e867f6b3 100644 --- a/tank_design/src/tube_and_wing/empirical/tank_design_tu_berlin/general/call_functions/_00_readenergycarrierandtankconfiguration.py +++ b/tank_design/src/tube_and_wing/empirical/tank_design_tu_berlin/general/call_functions/_00_readenergycarrierandtankconfiguration.py @@ -135,6 +135,7 @@ def read_energy_carrier_and_tank_configuration(paths_and_names, dict_ac_data, di energy_carrier_lookup[tank['energy_carrier_id']]['energy_carrier']), 'tank_location': tank['tank_location'], 'tank_position': tank['tank_position'], + 'designator': tank['tank_location'] + '_' + tank['tank_position'], 'energy_share': tank['energy_share'], 'energy_required': tank['energy_required'], 'volume_available': 0.0, diff --git a/tank_design/src/tube_and_wing/empirical/tank_design_tu_berlin/general/call_functions/_01_checktankconfiguration.py b/tank_design/src/tube_and_wing/empirical/tank_design_tu_berlin/general/call_functions/_01_checktankconfiguration.py index 44617f75b84057a8816596712ade89703a39d3b7..a03f589c6f715402e4a53c5603b5de31144f2089 100644 --- a/tank_design/src/tube_and_wing/empirical/tank_design_tu_berlin/general/call_functions/_01_checktankconfiguration.py +++ b/tank_design/src/tube_and_wing/empirical/tank_design_tu_berlin/general/call_functions/_01_checktankconfiguration.py @@ -20,26 +20,47 @@ def check_tank_configuration(paths_and_names, dict_ac_data, dict_tank_design, ru # Extract values from 'dict_ac_data' and 'dict_tank_design'. energy_carrier = dict_ac_data['energy_carrier'] tank_entity_list = [key for key in dict_tank_design if key.startswith('tank_') and key[5:].isdigit()] + wing_mounting = dict_ac_data['wing_mounting'] number_of_tanks = 0 """Kerosene.""" if energy_carrier == 'kerosene': - # Define tank combination dict based on energy carrier. - combinations = { - # Standard integral wing tanks. - 'wing': - {'inner_left': False, - 'outer_left': False, - 'inner_right': False, - 'outer_right': False, - 'center': False}, - # Trim tank. - 'horizontal_stabilizer': - {'total': False}, - # Additional center tank. - 'fuselage': - {'center': False} - } + # Define tank combination dict based on energy carrier and wing mounting. + if wing_mounting == 'low': + combinations = { + # Standard integral wing tanks. + 'wing': + {'inner_left': False, + 'outer_left': False, + 'inner_right': False, + 'outer_right': False, + 'center': False}, + # Trim tank. + 'horizontal_stabilizer': + {'total': False}, + # Additional center tank. + 'fuselage': + {'center': False} + } + elif wing_mounting == 'high': + combinations = { + # Standard integral wing tanks. + 'wing': + {'inner_left': False, + 'inner_right': False, + 'center': False}, + # Trim tank. + 'horizontal_stabilizer': + {'total': False}, + # Additional center tank. + 'fuselage': + {'center': False} + } + else: + # If wing mounting is not high or low, wing definition is invalid. Abort program. + runtime_output.critical('Error: Wing mounting not "high" or "low". Invalid wing definition. ' + + 'Program aborted.') + sys.exit('Exit information: Invalid wing definition in aircraft exchange file.') # Iterate over tank entities of 'tank_entity_list'. for tank_entity in tank_entity_list: @@ -84,22 +105,34 @@ def check_tank_configuration(paths_and_names, dict_ac_data, dict_tank_design, ru # Define number of tanks and set tank configuration name for valid tank configurations. if valid_wing_tanks and not (trim_tank or additional_center_tank): - number_of_tanks = 5 + if wing_mounting == 'low': + number_of_tanks = 5 + elif wing_mounting == 'high': + number_of_tanks = 3 tank_configuration = 'wing_all_tanks' # Print. runtime_output.print('Valid tank configuration found in acXML: ' + tank_configuration) elif valid_wing_with_trim_tank and not additional_center_tank: - number_of_tanks = 6 + if wing_mounting == 'low': + number_of_tanks = 6 + elif wing_mounting == 'high': + number_of_tanks = 4 tank_configuration = 'wing_with_trim_tank' # Print. runtime_output.print('Valid tank configuration found in acXML: ' + tank_configuration) elif valid_wing_with_additional_center_tank and not trim_tank: - number_of_tanks = 6 + if wing_mounting == 'low': + number_of_tanks = 6 + elif wing_mounting == 'high': + number_of_tanks = 4 tank_configuration = 'wing_with_additional_center_tank' # Print. runtime_output.print('Valid tank configuration found in acXML: ' + tank_configuration) elif valid_wing_with_additional_center_and_trim_tank: - number_of_tanks = 7 + if wing_mounting == 'low': + number_of_tanks = 7 + elif wing_mounting == 'high': + number_of_tanks = 5 tank_configuration = 'wing_with_additional_center_and_trim_tank' # Print. runtime_output.print('Valid tank configuration found in acXML: ' + tank_configuration) diff --git a/tank_design/src/tube_and_wing/empirical/tank_design_tu_berlin/general/call_functions/_02_preparegeometricaldata.py b/tank_design/src/tube_and_wing/empirical/tank_design_tu_berlin/general/call_functions/_02_preparegeometricaldata.py index 43246f5a4a27cd718bb94ac2fea083bc601d3e87..544310ce3c8daca57bd7d8acc699c9957c2e34bb 100644 --- a/tank_design/src/tube_and_wing/empirical/tank_design_tu_berlin/general/call_functions/_02_preparegeometricaldata.py +++ b/tank_design/src/tube_and_wing/empirical/tank_design_tu_berlin/general/call_functions/_02_preparegeometricaldata.py @@ -93,9 +93,6 @@ def prepare_for_kerosene(dict_ac_data, dict_tank_design, runtime_output): dict_tank_design = prepare_wing_tanks(dict_ac_data, dict_tank_design, runtime_output) # Trim tank. if 'trim' in dict_tank_design['tank_configuration']: - # # Not implemented yet. - # runtime_output.critical('Error: Trim tank not implemented yet! Program aborted.') - # sys.exit('Exit information: Trim tank calculation not implemented yet!') dict_tank_design = prepare_trim_tank(dict_ac_data, dict_tank_design, runtime_output) # Additional center tank. if 'additional_center' in dict_tank_design['tank_configuration']: diff --git a/tank_design/src/tube_and_wing/empirical/tank_design_tu_berlin/general/tankdesigntuberlin.py b/tank_design/src/tube_and_wing/empirical/tank_design_tu_berlin/general/tankdesigntuberlin.py index 01485ca847ffd81aaf8cd0a251f92a565cdcec32..fd0d089daadcaaa63c55aa524611803c39b63f2f 100644 --- a/tank_design/src/tube_and_wing/empirical/tank_design_tu_berlin/general/tankdesigntuberlin.py +++ b/tank_design/src/tube_and_wing/empirical/tank_design_tu_berlin/general/tankdesigntuberlin.py @@ -60,63 +60,32 @@ def tank_design_tu_berlin(paths_and_names, routing_dict, dict_ac_data, runtime_o thickness_to_length.append(thickness/chord) dict_ac_data['horizontal_stabilizer_thickness_to_length'] = thickness_to_length - """Convert coordinates from CGAL to aircraft coordinate system.""" - # List of parameters to be considered for CGAL to aircraft coordinate system conversion. - param_list = ["fuselage_position", "wing_position", "empennage_position", "fuselage_entity_position", - "fuselage_section_origin", "fuselage_payload_deck_origin", "wing_section_chord_origin", - "empennage_entity_position", "empennage_section_chord_origin"] - - # for param in param_list: - # if dict_ac_data[param + "_x"] is not None: - # if type(dict_ac_data[param + "_x"]) != float: - # for key in dict_ac_data[param + "_x"].keys(): - # index = key.split("_").index("x") + 1 - # if dict_ac_data[param + "_x"][param + "_x_" + key.split("_", index)[-1]] is not None: - # element3D = py11csc.Element3D(dict_ac_data[param + "_x"][param + "_x_" + key.split("_", index)[-1]], - # dict_ac_data[param + "_y"][param + "_y_" + key.split("_", index)[-1]], - # dict_ac_data[param + "_z"][param + "_z_" + key.split("_", index)[-1]]) - # element3D.CGAL2AC() - # dict_ac_data[param + "_x"][param + "_x_" + key.split("_", index)[-1]] = element3D.x() - # dict_ac_data[param + "_y"][param + "_y_" + key.split("_", index)[-1]] = element3D.y() - # dict_ac_data[param + "_z"][param + "_z_" + key.split("_", index)[-1]] = element3D.z() - # else: - # runtime_output.warning("WARNING: The parameter " + param + "_x is missing in the aircraft exchange file. No need to convert the coordinates.") - # else: - # element3D = py11csc.Element3D(dict_ac_data[param + "_x"], - # dict_ac_data[param + "_y"], - # dict_ac_data[param + "_z"]) - # element3D.CGAL2AC() - # dict_ac_data[param + "_x"] = element3D.x() - # dict_ac_data[param + "_y"] = element3D.y() - # dict_ac_data[param + "_z"] = element3D.z() - # else: - # runtime_output.warning("WARNING: The parameter " + param + "_x is missing in the aircraft exchange file. No need to convert the coordinates.") - - # Transform fuselage cgal coordinates to aircraft coordinates. - # Store the current values of each sub-dict in temporary variables + """Convert coordinates from CGAL to aircraft coordinate system.""" + # Transform fuselage CGAL coordinates to aircraft coordinates. + # Store the current values of each sub-dict in temporary variables. temp_x_values = dict_ac_data['fuselage_section_origin_x'].values() temp_y_values = dict_ac_data['fuselage_section_origin_y'].values() temp_z_values = dict_ac_data['fuselage_section_origin_z'].values() - # Update each dictionary's values by iterating over keys + # Update each dictionary's values by iterating over keys. # Swap values: z -> x, y -> z, x -> y dict_ac_data['fuselage_section_origin_x'] = dict(zip(dict_ac_data['fuselage_section_origin_x'].keys(), temp_z_values)) dict_ac_data['fuselage_section_origin_y'] = dict(zip(dict_ac_data['fuselage_section_origin_y'].keys(), temp_x_values)) dict_ac_data['fuselage_section_origin_z'] = dict(zip(dict_ac_data['fuselage_section_origin_z'].keys(), temp_y_values)) - # Transform wing cgal coordinates to aircraft coordinates. + # Transform wing CGAL coordinates to aircraft coordinates. # Store the current values of each sub-dict in temporary variables temp_y_values = dict_ac_data['wing_section_chord_origin_y'].values() temp_z_values = dict_ac_data['wing_section_chord_origin_z'].values() - # Update each dictionary's values by iterating over keys + # Update each dictionary's values by iterating over keys. # Swap values: z -> y, y -> z dict_ac_data['wing_section_chord_origin_y'] = dict(zip(dict_ac_data['wing_section_chord_origin_y'].keys(), temp_z_values)) dict_ac_data['wing_section_chord_origin_z'] = dict(zip(dict_ac_data['wing_section_chord_origin_z'].keys(), temp_y_values)) - # Transform empennage cgal coordinates to aircraft coordinates. + # Transform empennage CGAL coordinates to aircraft coordinates. # Store the current values of each sub-dict in temporary variables temp_y_values = dict_ac_data['empennage_section_chord_origin_y'].values() temp_z_values = dict_ac_data['empennage_section_chord_origin_z'].values() - # Update each dictionary's values by iterating over keys + # Update each dictionary's values by iterating over keys. # Swap values: z -> y, y -> z dict_ac_data['empennage_section_chord_origin_y'] = dict(zip(dict_ac_data['empennage_section_chord_origin_y'].keys(), temp_z_values)) dict_ac_data['empennage_section_chord_origin_z'] = dict(zip(dict_ac_data['empennage_section_chord_origin_z'].keys(), temp_y_values)) diff --git a/tank_design/src/tube_and_wing/empirical/tank_design_tu_berlin/kerosene/calculatetanks.py b/tank_design/src/tube_and_wing/empirical/tank_design_tu_berlin/kerosene/calculatetanks.py index b95bba00108caf1d1f4a6dd438b5df4541c35e66..57eb774d5252a11b7c2490fb52d32c3e62ba33bb 100644 --- a/tank_design/src/tube_and_wing/empirical/tank_design_tu_berlin/kerosene/calculatetanks.py +++ b/tank_design/src/tube_and_wing/empirical/tank_design_tu_berlin/kerosene/calculatetanks.py @@ -112,7 +112,6 @@ def calculate_kerosene_tanks(dict_ac_data, dict_tank_design, runtime_output): else: energy_demand_covered = False - # TEST # If energy amount not covered by wing tanks: Calculate other fuel tanks (depending on tank configuration). # Calculate additional tank volumes according to defined tank configuration. match dict_tank_design['tank_configuration']: @@ -144,8 +143,14 @@ def calculate_kerosene_tanks(dict_ac_data, dict_tank_design, runtime_output): runtime_output.print('Energy check: Energy demand covered.') case 'wing_with_additional_center_and_trim_tank': - first_act_then_trim = (dict_tank_design['tank_5']['tank_location'] == 'fuselage') - first_trim_then_act = (dict_tank_design['tank_5']['tank_location'] == 'horizontal_stabilizer') + additional_center_tank_entity = [k for k, v in dict_tank_design.items() + if k.startswith('tank_') and k[5:].isdigit() + and v['tank_location'] == 'fuselage' + and v['tank_position'] == 'center'] + trim_tank_entity = [k for k, v in dict_tank_design.items() if k.startswith('tank_') and k[5:].isdigit() + and v['tank_location'] == 'horizontal_stabilizer' and v['tank_position'] == 'total'] + first_act_then_trim = (int(additional_center_tank_entity[-1][-1]) < int(trim_tank_entity[-1][-1])) + first_trim_then_act = not first_act_then_trim if first_act_then_trim and not first_trim_then_act: if not energy_demand_covered: runtime_output.print('Energy check: Demand not covered yet. Continue with design of additional ' @@ -209,80 +214,6 @@ def calculate_kerosene_tanks(dict_ac_data, dict_tank_design, runtime_output): runtime_output.print('Attention: Necessary amount of fuel cannot be stored in selected tanks! ' + str(int(round(energy_missing,0))) + 'J (' + str(round(volume_missing,2)) + 'L) missing.') - - # TEST END - - # """ Print information or calculate other fuel tanks. """ - # if energy_demand_covered: - # # Energy amount that can be stored in wing tanks already covers mission energy amount. All other tanks are - # # generated but remain empty ('volume_available' and 'energy_available' are 0.0). - # match dict_tank_design['tank_configuration']: - # case 'wing_with_trim_tank': - # runtime_output.print('Trim tank is generated but unnecessary and remains empty.') - # case 'wing_with_additional_center_tank': - # runtime_output.print('Additional center tank is generated but unnecessary and remains empty.') - # case 'wing_with_additional_center_and_trim_tank': - # runtime_output.print('Trim and additional center tank are generated but unnecessary and ' - # + 'remain empty.') - # else: - # # If energy amount not covered by wing tanks: Calculate other fuel tanks (depending on tank configuration). - # # Calculate additional tank volumes according to defined tank configuration. - # match dict_tank_design['tank_configuration']: - # case 'wing_with_trim_tank': - # dict_tank_design = calculate_trim_tank(dict_ac_data, dict_tank_design, runtime_output) - # total_tank_energy += dict_tank_design['tmp_energies']['trim_tank'] - # if total_tank_energy >= mission_energy_amount: - # energy_demand_covered = True - # case 'wing_with_additional_center_tank': - # dict_tank_design = calculate_additional_center_tank(dict_ac_data, dict_tank_design, runtime_output) - # total_tank_energy += ( - # dict_tank_design['tmp_energies']['additional_center_tank']) - # if total_tank_energy >= mission_energy_amount: - # energy_demand_covered = True - # case 'wing_with_additional_center_and_trim_tank': - # first_act_then_trim = (dict_tank_design['tank_5']['tank_location'] == 'fuselage') - # first_trim_then_act = (dict_tank_design['tank_5']['tank_location'] == 'horizontal_stabilizer') - # if first_act_then_trim and not first_trim_then_act: - # dict_tank_design = calculate_additional_center_tank(dict_ac_data, dict_tank_design, runtime_output) - # total_tank_energy += dict_tank_design['tmp_energies']['additional_center_tank'] - # if total_tank_energy >= mission_energy_amount: - # energy_demand_covered = True - # runtime_output.print('Energy check: Energy demand covered.') - # runtime_output.print('Trim tank is generated but unnecessary and remains empty.') - # else: - # runtime_output.print('Energy check: Demand not covered yet. Continue with design of trim ' - # + 'tank.') - # dict_tank_design = calculate_trim_tank(dict_ac_data, dict_tank_design, runtime_output) - # additional_tank_energy += dict_tank_design['tmp_energies']['trim_tank'] - # total_tank_energy += additional_tank_energy - # if total_tank_energy >= mission_energy_amount: - # energy_demand_covered = True - # if first_trim_then_act and not first_act_then_trim: - # dict_tank_design = calculate_trim_tank(dict_ac_data, dict_tank_design, runtime_output) - # total_tank_energy += dict_tank_design['tmp_energies']['trim_tank'] - # if total_tank_energy >= mission_energy_amount: - # energy_demand_covered = True - # runtime_output.print('Energy check: Energy demand covered.') - # runtime_output.print('Additional center tank is generated but unnecessary and remains empty.') - # else: - # runtime_output.print('Energy check: Demand not covered yet. Continue with design of ' - # + 'additional center tank.') - # dict_tank_design = calculate_additional_center_tank(dict_ac_data, dict_tank_design, - # runtime_output) - # additional_tank_energy += dict_tank_design['tmp_energies']['additional_center_tank'] - # total_tank_energy += additional_tank_energy - # if total_tank_energy >= mission_energy_amount: - # energy_demand_covered = True - - # # Final check if tanks can store mission energy amount. - # if energy_demand_covered: - # runtime_output.print('Tank design successful.') - # else: - # energy_missing = mission_energy_amount - total_tank_energy - # volume_missing = energy_missing/kerosene_volumetric_energy_density - # runtime_output.print('Attention: Necessary amount of fuel cannot be stored in selected tanks! ' - # + str(int(round(energy_missing,0))) + 'J (' + str(round(volume_missing,2)) + - # 'L) missing.') """ Calculate total tank parameters. """ dict_tank_design['total_tank_parameters'] = {} @@ -412,7 +343,7 @@ def calculate_wing_tanks(dict_ac_data, dict_tank_design, runtime_output, mission # span_index = wing_section_dict[sec]['span_index'] i += 1 - # -------------------------- START OF NEW VENT TANK CALCULATION ------------------------- + # Vent tank calculation. def calculate_wing_tanks_volume(): """Calculate tank volumes (wing geometry does not change from here).""" # Initialize parameter. @@ -443,8 +374,20 @@ def calculate_wing_tanks(dict_ac_data, dict_tank_design, runtime_output, mission case 'center': inner_surface_str = 'fuselage_center_line' outer_surface_str = 'outer_center_tank_section' + elif number_of_wing_sections == 3: + # Set sections depending on tank position. + match dict_tank_design[wing_tank_entity]['tank_position']: + case 'inner_left' | 'inner_right': + inner_surface_str = 'section_0' + outer_surface_str = 'section_1' + # case 'outer_left' | 'outer_right': + # inner_surface_str = 'section_1' + # outer_surface_str = 'section_2' + case 'center': + inner_surface_str = 'fuselage_center_line' + outer_surface_str = 'outer_center_tank_section' else: - runtime_output.critical('Error: Wing without kink not implemented yet! Program aborted.') + runtime_output.critical('Error: Unknown wing geometry! Program aborted.') sys.exit(1) else: runtime_output.critical('Error: Wing not symmetric! ' @@ -544,13 +487,6 @@ def calculate_wing_tanks(dict_ac_data, dict_tank_design, runtime_output, mission else: y_coordinate_section = surface_data['position']['y'] y_coordinate = (abs(y_coordinate_section) - abs(y_coordinate_entity)) - # old - # y_coordinate = y_coordinate_section - y_coordinate_entity - # NEW: - # y_coordinate = -(abs(y_coordinate_section) - abs(y_coordinate_entity)) - # if 'left' in dict_tank_design[wing_tank_entity]['tank_position']: - # y_coordinate = y_coordinate*(-1) - # x coordinate. x_coordinate_entity = dict_tank_design[wing_tank_entity]['geometry']['total']['position']['x'] x_coordinate_section = wing_geometry_dict['interpolated_values']['x_coordinate_front_spar'][span_idx] if x_coordinate_entity < 0 and x_coordinate_section > 0 and x_coordinate_section > x_coordinate_entity: @@ -629,10 +565,6 @@ def calculate_wing_tanks(dict_ac_data, dict_tank_design, runtime_output, mission dict_tank_design[wing_tank_entity]['geometry']['total']['centroid'] = {} if wing_tank_entity == wing_center_tank_entity: dict_tank_design[wing_tank_entity]['geometry']['total']['centroid']['x'] = x_position_center_of_mass - # dict_tank_design[wing_tank_entity]['geometry']['total']['centroid']['x'] = ( - # dict_tank_design['tank_4']['geometry']['inner_surface']['position']['x'] - # + dict_tank_design['tank_4']['geometry']['inner_surface']['width']/2 - # ) dict_tank_design[wing_tank_entity]['geometry']['total']['centroid']['y'] = 0 dict_tank_design[wing_tank_entity]['geometry']['total']['centroid']['z'] = 0 else: @@ -684,7 +616,7 @@ def calculate_wing_tanks(dict_ac_data, dict_tank_design, runtime_output, mission wing_geometry_dict['interpolated_values']['x_coordinate_leading_edge'][span_idx]) wing_section_dict[vent_tank_inner_surface]['position']['y'] = span_idx/100 - # TODO: Eventuell löschen, wenn plot nicht mehr benötigt. + # TODO: Delete if plot not necessary any longer. dict_tank_design['vent_tank']['geometry'] = {} dict_tank_design['vent_tank']['geometry']['total'] = {} dict_tank_design['vent_tank']['geometry']['total']['position'] = {} @@ -705,292 +637,6 @@ def calculate_wing_tanks(dict_ac_data, dict_tank_design, runtime_output, mission print_outputs = True calculate_vent_tank_volume(energy_wing_tank_with_center_tank) energy_wing_tank_without_center_tank, energy_wing_tank_with_center_tank = calculate_wing_tanks_volume() - # calculate_wing_tanks_volume() - # output is volume_wing_tank_with_center_tank - # this is input for calculate_vent_tank() - # then calculate_wing_tanks_volume() - # -------------------------- END OF NEW VENT TANK CALCULATION ------------------------- - - # -------------------------- START OF OLD VENT TANK CALCULATION ------------------------- - # """Calculate vent tank.""" - # # § 25.969 Fuel tank expansion space. Each fuel tank must have an expansion space of not less than 2 percent - # # of the tank capacity. It must be impossible to fill the expansion space inadvertently with the airplane in the - # # normal ground attitude. For pressure fueling systems, compliance with this section may be shown with the means - # # provided to comply with §25.979(b). - # # Add vent tank to tank design dict. - # dict_tank_design['vent_tank'] = {} - # dict_tank_design['vent_tank']['tank_location'] = 'wing' - # dict_tank_design['vent_tank']['tank_position'] = 'vent' - # # CS 25.969: Vent tank capacity must at least be equal to 2 percent of tank capacity (1 percent per side). - # dict_tank_design['vent_tank']['energy_required'] = 0.01*mission_energy_amount - # vent_tank_outer_surface = 'outer_vent_tank_section' - - # # Calculate energy contained in vent tank iteratively. Position of inner surface is adjusted in 1 mm steps. - # vent_tank_energy = 0 - # while vent_tank_energy < dict_tank_design['vent_tank']['energy_required']: - # vent_tank_volume = calculate_obelisk_volume(dict_ac_data['obelisk_volume_calculation_method'], - # wing_geometry_dict, - # vent_tank_inner_surface, vent_tank_outer_surface) - # vent_tank_volume_actual = factor_volume_usable*temperature_expansion_allowance*vent_tank_volume - # vent_tank_energy = vent_tank_volume_actual*kerosene_volumetric_energy_density - # wing_section_dict[vent_tank_inner_surface]['span_index'] -= 1 - - # # Update x position of 'section_2' aka. 'vent_tank_inner_surface'. - # span_idx = wing_section_dict[vent_tank_inner_surface]['span_index'] - # wing_section_dict[vent_tank_inner_surface]['position']['x'] = ( - # wing_geometry_dict['interpolated_values']['x_coordinate_leading_edge'][span_idx]) - # wing_section_dict[vent_tank_inner_surface]['position']['y'] = span_idx/100 - - # # TODO: Eventuell löschen, wenn plot nicht mehr benötigt. - # dict_tank_design['vent_tank']['geometry'] = {} - # dict_tank_design['vent_tank']['geometry']['total'] = {} - # dict_tank_design['vent_tank']['geometry']['total']['position'] = {} - # dict_tank_design['vent_tank']['geometry']['total']['position']['x'] = ( - # wing_geometry_dict['interpolated_values']['x_coordinate_front_spar'][span_idx]) - # dict_tank_design['vent_tank']['geometry']['total']['position']['y'] = ( - # wing_section_dict[vent_tank_inner_surface]['position']['y']) - # dict_tank_design['vent_tank']['geometry']['inner_surface'] = {} - # dict_tank_design['vent_tank']['geometry']['inner_surface']['width'] = ( - # wing_geometry_dict['interpolated_values']['tank_lengths'][span_idx]) - # dict_tank_design['vent_tank']['volume_available'] = vent_tank_volume_actual - # dict_tank_design['vent_tank']['energy_available'] = vent_tank_energy - # # Print. - # runtime_output.print('Vent tank (located near each wing tip) calculated.') - - # """Calculate tank volumes (wing geometry does not change from here).""" - # # Initialize parameter. - # actual_volume_center_tank = 0 - # actual_volume_without_center_tank = 0 - - # # Iterate through tank entities. - # wing_tank_entity_list = [key for key, value in dict_tank_design.items() if key.startswith('tank_') - # and key[5:].isdigit() and value['tank_location'] == 'wing'] - # for wing_tank_entity in wing_tank_entity_list: - # # Initialize empty dictionary and lists. - # dict_tank_design[wing_tank_entity]['geometry'] = {} - # dict_tank_design[wing_tank_entity]['geometry']['inner_surface'] = {} - # dict_tank_design[wing_tank_entity]['geometry']['outer_surface'] = {} - # inner_surface_str = str() - # outer_surface_str = str() - - # if wing_symmetry: - # if number_of_wing_sections == 4: - # # Set sections depending on tank position. - # match dict_tank_design[wing_tank_entity]['tank_position']: - # case 'inner_left' | 'inner_right': - # inner_surface_str = 'section_0' - # outer_surface_str = 'section_1' - # case 'outer_left' | 'outer_right': - # inner_surface_str = 'section_1' - # outer_surface_str = 'section_2' - # case 'center': - # inner_surface_str = 'fuselage_center_line' - # outer_surface_str = 'outer_center_tank_section' - # else: - # runtime_output.critical('Error: Wing without kink not implemented yet! Program aborted.') - # sys.exit(1) - # else: - # runtime_output.critical('Error: Wing not symmetric! ' - # + 'Program aborted.') - # sys.exit(1) - - # # Calculate obelisk volume. - # obelisk_volume = calculate_obelisk_volume(dict_ac_data['obelisk_volume_calculation_method'], - # wing_geometry_dict, inner_surface_str, outer_surface_str) - # # Calculate actual tank volume (considering volume loss due to internal structure of integral tanks and buffer - # # for temperature-dependent expansion of fuel). - # if dict_tank_design[wing_tank_entity]['tank_position'] == 'center': - # obelisk_volume *= 2 - # actual_volume = factor_volume_usable*temperature_expansion_allowance*obelisk_volume - # # Sum up volume of all tanks except wing center tank. - # if dict_tank_design[wing_tank_entity]['tank_position'] != 'center': - # actual_volume_without_center_tank += actual_volume - # # Set volume of wing center tank. - # else: - # actual_volume_center_tank = actual_volume - - # # Write data to 'dict_tank_design'. - # dict_tank_design[wing_tank_entity]['volume_available'] = actual_volume - # dict_tank_design[wing_tank_entity]['energy_available'] = ( - # actual_volume*kerosene_volumetric_energy_density) - # # Print. - # # inner left wing tank (ID="0") calculated. Volume (energy) available: 3.51 l (). - # # f'{a*1000:,.2f}' - # if dict_tank_design[wing_tank_entity]['tank_position'] == 'center': - # runtime_output.print('Wing center tank (' + wing_tank_entity + ') calculated. ' - # + 'Volume (energy) available: ' + f"{actual_volume:,.2f}" + ' L (' - # + f"{dict_tank_design[wing_tank_entity]['energy_available']/1e6:,.2f}" + ' MJ)') - # else: - # print_position = (dict_tank_design[wing_tank_entity]['tank_position'].split('_')[0].capitalize() - # + ' ' + dict_tank_design[wing_tank_entity]['tank_position'].split('_')[1] + ' ') - # runtime_output.print(print_position + 'wing tank (' + wing_tank_entity + ') calculated. ' - # + 'Volume (energy) available: ' + f"{actual_volume:,.2f}" + ' L (' - # + f"{dict_tank_design[wing_tank_entity]['energy_available']/1e6:,.2f}" + ' MJ)') - - # # Calculate tank mass (equals zero due to integral tank). - # dict_tank_design[wing_tank_entity]['geometry']['total'] = {} - # dict_tank_design[wing_tank_entity]['geometry']['total']['mass'] = 0.0 - # # Set inertia to zero. - # inertia_list = ['j_xx', 'j_yy', 'j_zz', 'j_xy', 'j_xz', 'j_yx', 'j_yz', 'j_zx', 'j_zy'] - # dict_tank_design[wing_tank_entity]['geometry']['total']['inertia'] = {} - # for inertia in inertia_list: - # dict_tank_design[wing_tank_entity]['geometry']['total']['inertia'][inertia] = 0.0 - # # Center of gravity equals zero since integral tank has no mass. - # dict_tank_design[wing_tank_entity]['geometry']['total']['center_of_gravity'] = {} - # dict_tank_design[wing_tank_entity]['geometry']['total']['center_of_gravity']['x'] = 0.0 - # dict_tank_design[wing_tank_entity]['geometry']['total']['center_of_gravity']['y'] = 0.0 - # dict_tank_design[wing_tank_entity]['geometry']['total']['center_of_gravity']['z'] = 0.0 - - # # Calculate position of tank entity (foremost point of tank). - # dict_tank_design[wing_tank_entity]['geometry']['total']['position'] = {} - # dict_tank_design[wing_tank_entity]['geometry']['total']['position']['x'] = ( - # wing_geometry_dict['interpolated_values']['x_coordinate_front_spar'][ - # wing_section_dict[inner_surface_str]['span_index'] - # ]) - # if (dict_tank_design[wing_tank_entity]['tank_position'] == 'inner_left') or ( - # dict_tank_design[wing_tank_entity]['tank_position'] == 'outer_left'): - # dict_tank_design[wing_tank_entity]['geometry']['total']['position']['y'] = -abs( - # wing_section_dict[inner_surface_str]['position']['y']) - # else: - # dict_tank_design[wing_tank_entity]['geometry']['total']['position']['y'] = abs( - # wing_section_dict[inner_surface_str]['position']['y']) - # dict_tank_design[wing_tank_entity]['geometry']['total']['position']['z'] = ( - # wing_section_dict[inner_surface_str]['position']['z']) - # # Direction. - # dict_tank_design[wing_tank_entity]['geometry']['total']['direction'] = {} - # dict_tank_design[wing_tank_entity]['geometry']['total']['direction']['x'] = 0 - # dict_tank_design[wing_tank_entity]['geometry']['total']['direction']['y'] = 1 - # dict_tank_design[wing_tank_entity]['geometry']['total']['direction']['z'] = 0 - # # Set required energy. - # dict_tank_design[wing_tank_entity]['energy_required_for_mission'] = True - - # # Add required output data: x, y, and z position, shape, height, width, and length. - # for surface_str, surface_name in zip([inner_surface_str, outer_surface_str], - # ['inner_surface', 'outer_surface']): - # surface_data = wing_section_dict[surface_str] - # span_idx = surface_data['span_index'] - # # Inner surface equals tank entity position. - # if surface_name == 'inner_surface': - # x_coordinate = 0.0 - # y_coordinate = 0.0 - # z_coordinate = 0.0 - # else: - # # Adjust y coordinate for left hand tanks. - # y_coordinate_entity = dict_tank_design[wing_tank_entity]['geometry']['total']['position']['y'] - # if 'left' in dict_tank_design[wing_tank_entity]['tank_position']: - # y_coordinate_section = -surface_data['position']['y'] - # y_coordinate = -(abs(y_coordinate_section) - abs(y_coordinate_entity)) - # else: - # y_coordinate_section = surface_data['position']['y'] - # y_coordinate = (abs(y_coordinate_section) - abs(y_coordinate_entity)) - # # old - # # y_coordinate = y_coordinate_section - y_coordinate_entity - # # NEW: - # # y_coordinate = -(abs(y_coordinate_section) - abs(y_coordinate_entity)) - # # if 'left' in dict_tank_design[wing_tank_entity]['tank_position']: - # # y_coordinate = y_coordinate*(-1) - # # x coordinate. - # x_coordinate_entity = dict_tank_design[wing_tank_entity]['geometry']['total']['position']['x'] - # x_coordinate_section = wing_geometry_dict['interpolated_values']['x_coordinate_front_spar'][span_idx] - # if x_coordinate_entity < 0 and x_coordinate_section > 0 and x_coordinate_section > x_coordinate_entity: - # delta_x = x_coordinate_entity - x_coordinate_section - # else: - # delta_x = x_coordinate_section - x_coordinate_entity - # x_coordinate = delta_x - # # z coordinate. - # z_coordinate_entity = dict_tank_design[wing_tank_entity]['geometry']['total']['position']['z'] - # z_coordinate_section = surface_data['position']['z'] - # z_coordinate = z_coordinate_section - z_coordinate_entity - - # dict_tank_design[wing_tank_entity]['geometry'][surface_name] = { - # 'section_name': surface_str, - # 'position': { - # 'x': x_coordinate, - # 'y': y_coordinate, - # 'z': z_coordinate, - # }, - # 'shape': 'rectangular', - # 'height': wing_geometry_dict['interpolated_values']['tank_heights'][span_idx], - # 'width': wing_geometry_dict['interpolated_values']['tank_lengths'][span_idx], - # 'length': 0.0 - # } - - # # Correct wing center tank information. - # if 'center' in dict_tank_design[wing_tank_entity]['tank_position']: - # dict_tank_design[wing_tank_entity]['geometry']['inner_surface']['position']['y'] = ( - # dict_tank_design[wing_tank_entity]['geometry']['outer_surface']['position']['y']/2 - # ) - # dict_tank_design[wing_tank_entity]['geometry']['outer_surface']['position']['y'] = -( - # dict_tank_design[wing_tank_entity]['geometry']['inner_surface']['position']['y'] - # ) - - # # Centroid. - # # Assumption: inner surface area always greater than outer surface area. - # inner_surface_area = (dict_tank_design[wing_tank_entity]['geometry']['inner_surface']['height'] - # *dict_tank_design[wing_tank_entity]['geometry']['inner_surface']['width']) - # outer_surface_area = (dict_tank_design[wing_tank_entity]['geometry']['outer_surface']['height'] - # *dict_tank_design[wing_tank_entity]['geometry']['outer_surface']['width']) - # y_position_outer_surface = dict_tank_design[wing_tank_entity]['geometry']['outer_surface']['position']['y'] - # y_position_inner_surface = dict_tank_design[wing_tank_entity]['geometry']['total']['position']['y'] - # tank_span = y_position_outer_surface - y_position_inner_surface - # y_position_center_of_mass = y_position_inner_surface + (tank_span/4*((inner_surface_area - # + 2*math.sqrt(inner_surface_area*outer_surface_area) - # + outer_surface_area)/(inner_surface_area + outer_surface_area))) - # centroid_y = y_position_inner_surface + ((tank_span - # *((dict_tank_design[wing_tank_entity]['geometry']['inner_surface']['height'] - # *dict_tank_design[wing_tank_entity]['geometry']['inner_surface']['width']) - # +(dict_tank_design[wing_tank_entity]['geometry']['inner_surface']['height'] - # *dict_tank_design[wing_tank_entity]['geometry']['outer_surface']['width']) - # +(dict_tank_design[wing_tank_entity]['geometry']['outer_surface']['height'] - # *dict_tank_design[wing_tank_entity]['geometry']['inner_surface']['width']) - # +(3*dict_tank_design[wing_tank_entity]['geometry']['outer_surface']['height'] - # *dict_tank_design[wing_tank_entity]['geometry']['outer_surface']['width']))) - # /(2 - # *(2*dict_tank_design[wing_tank_entity]['geometry']['inner_surface']['height'] - # *dict_tank_design[wing_tank_entity]['geometry']['inner_surface']['width']) - # + (dict_tank_design[wing_tank_entity]['geometry']['inner_surface']['height'] - # *dict_tank_design[wing_tank_entity]['geometry']['outer_surface']['width']) - # + (dict_tank_design[wing_tank_entity]['geometry']['outer_surface']['height'] - # *dict_tank_design[wing_tank_entity]['geometry']['inner_surface']['width']) - # + (2*dict_tank_design[wing_tank_entity]['geometry']['outer_surface']['height'] - # *dict_tank_design[wing_tank_entity]['geometry']['outer_surface']['width']))) - # x_position_cog_inner_surface = dict_tank_design[wing_tank_entity]['geometry']['inner_surface']['width']/2 - # x_position_cog_outer_surface = dict_tank_design[wing_tank_entity]['geometry']['outer_surface']['width']/2 - # z_position_cog_inner_surface = dict_tank_design[wing_tank_entity]['geometry']['inner_surface']['height']/2 - # z_position_cog_outer_surface = dict_tank_design[wing_tank_entity]['geometry']['outer_surface']['height']/2 - # x_position_center_of_mass = ((inner_surface_area*x_position_cog_inner_surface - # + outer_surface_area*x_position_cog_outer_surface) - # /(inner_surface_area + outer_surface_area)) - # z_position_center_of_mass = ((inner_surface_area*z_position_cog_inner_surface - # + outer_surface_area*z_position_cog_outer_surface) - # /(inner_surface_area + outer_surface_area)) - - # dict_tank_design[wing_tank_entity]['geometry']['total']['centroid'] = {} - # if wing_tank_entity == wing_center_tank_entity: - # dict_tank_design[wing_tank_entity]['geometry']['total']['centroid']['x'] = x_position_center_of_mass - # # dict_tank_design[wing_tank_entity]['geometry']['total']['centroid']['x'] = ( - # # dict_tank_design['tank_4']['geometry']['inner_surface']['position']['x'] - # # + dict_tank_design['tank_4']['geometry']['inner_surface']['width']/2 - # # ) - # dict_tank_design[wing_tank_entity]['geometry']['total']['centroid']['y'] = 0 - # dict_tank_design[wing_tank_entity]['geometry']['total']['centroid']['z'] = 0 - # else: - # dict_tank_design[wing_tank_entity]['geometry']['total']['centroid']['x'] = x_position_center_of_mass - # dict_tank_design[wing_tank_entity]['geometry']['total']['centroid']['y'] = y_position_center_of_mass - # dict_tank_design[wing_tank_entity]['geometry']['total']['centroid']['z'] = z_position_center_of_mass - - # # Sum up. - # volume_wing_tank_without_center_tank = actual_volume_without_center_tank - # volume_wing_tank_with_center_tank = actual_volume_without_center_tank + actual_volume_center_tank - - # """Calculate fuel mass and energy.""" - # # Convert wing fuel volume to energy. - # energy_wing_tank_without_center_tank = (volume_wing_tank_without_center_tank - # *kerosene_volumetric_energy_density) - # energy_wing_tank_with_center_tank = (volume_wing_tank_with_center_tank - # *kerosene_volumetric_energy_density) - - # -------------------------- END OF OLD VENT TANK CALCULATION ------------------------- """Check if tanks can store required energy.""" # If left and right inner and outer wing tanks are big enough to store required amount of energy, wing center tank @@ -1098,10 +744,8 @@ def calculate_additional_center_tank(dict_ac_data, dict_tank_design, runtime_out # Prepare geometrical data for additional center tank. # Assumption: Landing gear bay ends at wing trailing edge position. - # x_coordinate_wing_leading_edge = dict_ac_data['wing_position_x'] chord_length_at_fuselage_center_line = ( dict_tank_design['geometry']['wing']['sections']['fuselage_center_line']['chord_length']) - # x_coordinate_wing_trailing_edge = x_coordinate_wing_leading_edge + chord_length_at_fuselage_center_line buffer = 0.1 x_coordinate = chord_length_at_fuselage_center_line + buffer y_coordinate = [width_top_container*0.5, width_base_container*0.5, 0.0, @@ -1430,17 +1074,15 @@ def calculate_trim_tank(dict_ac_data, dict_tank_design, runtime_output, energy_d # Centroid. # Assumption: inner surface area always greater than outer surface area. - inner_surface = dict_tank_design['tank_5']['geometry']['cross_section_1'] - outer_surface = dict_tank_design['tank_5']['geometry']['cross_section_2'] + inner_surface = dict_tank_design[tank_entity]['geometry']['cross_section_1'] + outer_surface = dict_tank_design[tank_entity]['geometry']['cross_section_2'] inner_surface_area = (inner_surface['height'] *inner_surface['width']) outer_surface_area = (outer_surface['height'] *outer_surface['width']) - y_position_outer_surface = outer_surface['position']['y'] - y_position_inner_surface = inner_surface['position']['y'] - tank_span = y_position_outer_surface - y_position_inner_surface + # y_position_outer_surface = outer_surface['position']['y'] + # y_position_inner_surface = inner_surface['position']['y'] y_position_center_of_mass = 0 - centroid_y = 0 x_position_cog_inner_surface = inner_surface['width']/2 x_position_cog_outer_surface = outer_surface['width']/2 z_position_cog_inner_surface = inner_surface['height']/2 diff --git a/tank_design/src/tube_and_wing/empirical/tank_design_tu_berlin/usermethoddatapreparation.py b/tank_design/src/tube_and_wing/empirical/tank_design_tu_berlin/usermethoddatapreparation.py index 8b8525a535177b507ca76bbe0168be588721e4c4..d91e385386757c75b8aa357d68e67ff48a576c6d 100644 --- a/tank_design/src/tube_and_wing/empirical/tank_design_tu_berlin/usermethoddatapreparation.py +++ b/tank_design/src/tube_and_wing/empirical/tank_design_tu_berlin/usermethoddatapreparation.py @@ -50,7 +50,6 @@ def user_method_data_input_preparation(routing_dict): [tmp_mission_analysis_path +'loaded_mission_energy/mission_energy[@ID="0"]/consumed_energy', float], 'mission_energy_ID': [tmp_mission_analysis_path +'loaded_mission_energy/mission_energy[@ID="0"]/energy_carrier_ID', int], - # TODO here only loaded mission energy is used, but there are also trip, taxi & landing energy 'energy_carrier_name': [tmp_design_specs_path + 'energy_carriers/energy_carrier[@ID="0"]/type', str], # Tank configuration. @@ -81,6 +80,7 @@ def user_method_data_input_preparation(routing_dict): 'fuselage_payload_deck_structural_floor_thickness': [tmp_fuselage_payload_deck_path + 'payload_deck_structural_floor_thickness', float], # Wing data. + 'wing_mounting': [tmp_design_specs_path + 'configuration/wing_definition/mounting', str], 'wing_name': [tmp_wing_path + 'name', str], 'wing_position_x': ['./component_design/wing/position/x', float], 'wing_position_y': ['./component_design/wing/position/y', float],