diff --git a/weight_and_balance_analysis/src/tube_and_wing/standard/basic/methodbasic.py b/weight_and_balance_analysis/src/tube_and_wing/standard/basic/methodbasic.py index eac847d11afa75b68fab3b08985647b9df2ec4e8..23c4e2cd216d24d363116a08429bff1b10964332 100644 --- a/weight_and_balance_analysis/src/tube_and_wing/standard/basic/methodbasic.py +++ b/weight_and_balance_analysis/src/tube_and_wing/standard/basic/methodbasic.py @@ -93,7 +93,7 @@ def method_basic(paths_and_names, routing_dict, dict_ac_exchange, dict_mod_confi # Select loading and active modes # ferry range or design mission refueling_mode = dict_mod_config["refueling_mode"] - defueling_mode = dict_mod_config["defueling_mode"] # active or not active + defueling_mode = refueling_mode # because this regards the design or ferry range mission # row-wise or window-aisle passengers_boarding_mode = dict_mod_config["passengers_boarding_mode"] @@ -507,7 +507,7 @@ def method_basic(paths_and_names, routing_dict, dict_ac_exchange, dict_mod_confi "Defueling CG change": cg_positions_dict["defueling"], "Defueling xCG": cg_pos_out["defueling_xCG"], "Defueling mass change": total_mass_dict["defueling"], - "Defueling mode": defueling_mode, + "Defueling mode": dict_mod_config["defueling_mode"], "Passengers boarding front back CG change": cg_positions_dict["passengers_boarding"], "Passengers boarding front back mass change": total_mass_dict["passengers_boarding"], "Passengers boarding back front CG change": cg_positions_dict["passengers_boarding_back_front"], @@ -902,7 +902,6 @@ def calculate_maximum_fuel_mass(tanks, ome, LE, mac, mtom, runtime_output): filled_tank_wo_structure.mass = empty_tank.energy / empty_tank.gravimetric_density filled_tank_wo_structure.tank_location = empty_tank.tank_location filled_tank_wo_structure.energy_carrier = empty_tank.energy_carrier - filled_tank_wo_structure.used_tank = empty_tank.used_tank # No adaption of Center of gravity or Inertia here filled_tank_wo_structure.moment_change = ( @@ -1041,6 +1040,12 @@ def calculate_fuel_mass_properties(tanks, fuel_mass, routing_dict, dict_ac_excha if fuel_mass > total_capacity: runtime_output.critical( "Fuel mass to be filled up exceeds the total capacity of all tanks!") + + if fuel_mass < 0: + runtime_output.critical( + "Fuel mass to be filled inside the tanks is negative. Please check the mission information!") + raise ValueError( + "Fuel mass to be filled inside the tanks is negative. Please check the mission information!") # Distribute fuel across left and right wing tanks first remaining_fuel = fuel_mass @@ -1054,127 +1059,107 @@ def calculate_fuel_mass_properties(tanks, fuel_mass, routing_dict, dict_ac_excha filled_tank_wo_structure_left = MassPropertiesIO().initialize_zero() filled_tank_wo_structure_right = MassPropertiesIO().initialize_zero() + filled_tank_wo_structure_left.center_of_gravity = left_tank.mass_properties.center_of_gravity + filled_tank_wo_structure_left.tank_location = left_tank.tank_location + filled_tank_wo_structure_left.energy_carrier = right_tank.energy_carrier + filled_tank_wo_structure_left.maximum_capacity = left_tank.max_fuel_mass_capacity + filled_tank_wo_structure_right.tank_location = right_tank.tank_location + filled_tank_wo_structure_right.energy_carrier = right_tank.energy_carrier + filled_tank_wo_structure_right.maximum_capacity = right_tank.max_fuel_mass_capacity + filled_tank_wo_structure_right.center_of_gravity = right_tank.mass_properties.center_of_gravity # Amount to fill equally fuel_to_fill = min( left_capacity, right_capacity, remaining_fuel / 2) # Fill both left and right tanks - if fuel_to_fill > 0: + if fuel_to_fill > 0 : remaining_fuel -= 2 * fuel_to_fill filled_tank_wo_structure_left.mass = fuel_to_fill - filled_tank_wo_structure_left.center_of_gravity = left_tank.mass_properties.center_of_gravity filled_tank_wo_structure_left.moment_change = ( fuel_to_fill * filled_tank_wo_structure_left.center_of_gravity["x"]) - filled_tank_wo_structure_left.tank_location = left_tank.tank_location - filled_tank_wo_structure_left.energy_carrier = right_tank.energy_carrier - filled_tank_wo_structure_left.used_tank = left_tank.used_tank - filled_tank_wo_structure_left.maximum_capacity = left_tank.max_fuel_mass_capacity - filled_tank_wo_structure_right.mass = fuel_to_fill - filled_tank_wo_structure_right.center_of_gravity = right_tank.mass_properties.center_of_gravity filled_tank_wo_structure_right.moment_change = ( fuel_to_fill * filled_tank_wo_structure_right.center_of_gravity["x"]) - filled_tank_wo_structure_right.tank_location = right_tank.tank_location - filled_tank_wo_structure_right.energy_carrier = right_tank.energy_carrier - filled_tank_wo_structure_right.used_tank = right_tank.used_tank - filled_tank_wo_structure_right.maximum_capacity = right_tank.max_fuel_mass_capacity - fuel_mass_per_tank.append(filled_tank_wo_structure_left) fuel_mass_per_tank.append(filled_tank_wo_structure_right) + else: filled_tank_wo_structure_left.mass = 0 - filled_tank_wo_structure_left.center_of_gravity = left_tank.mass_properties.center_of_gravity filled_tank_wo_structure_left.moment_change = 0 - filled_tank_wo_structure_left.tank_location = left_tank.tank_location - filled_tank_wo_structure_left.energy_carrier = left_tank.energy_carrier - filled_tank_wo_structure_left.used_tank = left_tank.used_tank - filled_tank_wo_structure_left.maximum_capacity = left_tank.max_fuel_mass_capacity - filled_tank_wo_structure_right.mass = 0 - filled_tank_wo_structure_right.center_of_gravity = right_tank.mass_properties.center_of_gravity filled_tank_wo_structure_right.moment_change = 0 - filled_tank_wo_structure_right.tank_location = right_tank.tank_location - filled_tank_wo_structure_right.energy_carrier = right_tank.energy_carrier - filled_tank_wo_structure_right.used_tank = right_tank.used_tank - filled_tank_wo_structure_right.maximum_capacity = right_tank.max_fuel_mass_capacity - fuel_mass_per_tank.append(filled_tank_wo_structure_left) fuel_mass_per_tank.append(filled_tank_wo_structure_right) # Fill the center tank (if available) if center_tanks: for center_tank in center_tanks: - if remaining_fuel > 0: + filled_tank_wo_structure = MassPropertiesIO().initialize_zero() + filled_tank_wo_structure.center_of_gravity = center_tank.mass_properties.center_of_gravity + filled_tank_wo_structure.tank_location = center_tank.tank_location + filled_tank_wo_structure.energy_carrier = center_tank.energy_carrier + filled_tank_wo_structure.maximum_capacity = center_tank.max_fuel_mass_capacity + filled_tank_wo_structure.mass = 0 + filled_tank_wo_structure.moment_change = 0 + + if remaining_fuel <= 0: + filled_tank_wo_structure.mass = 0 + filled_tank_wo_structure.moment_change = 0 + else: center_capacity = center_tank.energy / center_tank.gravimetric_density fuel_to_fill = min(center_capacity, remaining_fuel) + if fuel_to_fill > 0: - filled_tank_wo_structure = MassPropertiesIO().initialize_zero() filled_tank_wo_structure.mass = fuel_to_fill - filled_tank_wo_structure.center_of_gravity = center_tank.mass_properties.center_of_gravity filled_tank_wo_structure.moment_change = ( fuel_to_fill * filled_tank_wo_structure.center_of_gravity["x"]) - filled_tank_wo_structure.tank_location = center_tank.tank_location - filled_tank_wo_structure.energy_carrier = center_tank.energy_carrier - filled_tank_wo_structure.used_tank = center_tank.used_tank - filled_tank_wo_structure.maximum_capacity = center_tank.max_fuel_mass_capacity - fuel_mass_per_tank.append(filled_tank_wo_structure) remaining_fuel -= fuel_to_fill - else: - filled_tank_wo_structure = MassPropertiesIO().initialize_zero() - filled_tank_wo_structure.mass = 0 - filled_tank_wo_structure.center_of_gravity = center_tank.mass_properties.center_of_gravity - filled_tank_wo_structure.moment_change = 0 - filled_tank_wo_structure.tank_location = center_tank.tank_location - filled_tank_wo_structure.energy_carrier = center_tank.energy_carrier - filled_tank_wo_structure.used_tank = center_tank.used_tank - filled_tank_wo_structure.maximum_capacity = center_tank.max_fuel_mass_capacity - fuel_mass_per_tank.append(filled_tank_wo_structure) + + fuel_mass_per_tank.append(filled_tank_wo_structure) # Fill the remaining tanks with any leftover fuel for other_tank in other_tanks: + filled_tank_wo_structure = MassPropertiesIO().initialize_zero() + filled_tank_wo_structure.center_of_gravity = other_tank.mass_properties.center_of_gravity + filled_tank_wo_structure.tank_location = other_tank.tank_location + filled_tank_wo_structure.energy_carrier = other_tank.energy_carrier + filled_tank_wo_structure.maximum_capacity = other_tank.max_fuel_mass_capacity + filled_tank_wo_structure.mass = 0 + filled_tank_wo_structure.moment_change = 0 + if remaining_fuel <= 0: - filled_tank_wo_structure = MassPropertiesIO().initialize_zero() filled_tank_wo_structure.mass = 0 - filled_tank_wo_structure.center_of_gravity = other_tank.mass_properties.center_of_gravity filled_tank_wo_structure.moment_change = 0 - filled_tank_wo_structure.tank_location = other_tank.tank_location - filled_tank_wo_structure.energy_carrier = other_tank.energy_carrier - filled_tank_wo_structure.used_tank = other_tank.used_tank - filled_tank_wo_structure.maximum_capacity = other_tank.max_fuel_mass_capacity - fuel_mass_per_tank.append(filled_tank_wo_structure) else: other_capacity = other_tank.energy / other_tank.gravimetric_density fuel_to_fill = min(other_capacity, remaining_fuel) - if fuel_to_fill > 0: - filled_tank_wo_structure = MassPropertiesIO().initialize_zero() + + if fuel_to_fill > 0 : filled_tank_wo_structure.mass = fuel_to_fill - filled_tank_wo_structure.center_of_gravity = other_tank.mass_properties.center_of_gravity filled_tank_wo_structure.moment_change = ( fuel_to_fill * filled_tank_wo_structure.center_of_gravity["x"]) - filled_tank_wo_structure.tank_location = other_tank.tank_location - filled_tank_wo_structure.energy_carrier = other_tank.energy_carrier - filled_tank_wo_structure.used_tank = other_tank.used_tank - filled_tank_wo_structure.maximum_capacity = other_tank.max_fuel_mass_capacity - fuel_mass_per_tank.append(filled_tank_wo_structure) remaining_fuel -= fuel_to_fill + fuel_mass_per_tank.append(filled_tank_wo_structure) + # Check if there is still remaining fuel (should not happen unless there is a capacity error) if remaining_fuel > 0: if int(dict_ac_exchange['tool_level']) < int(routing_dict['tool_level']): runtime_output.critical( - "Fuel mass calculation failed ... Not enough capacity in tanks!") + "Fuel mass calculation failed ... Not enough capacity in the availabe tanks!") else: if tanks[0].energy_carrier == 'kerosene': raise ValueError( - "Fuel mass calculation failed ... Not enough capacity in tanks!") + "Fuel mass calculation failed ... Not enough capacity in the availabe tanks for the needed mission fuel! Please redesign the tanks or change the mission.") fuel_mass_properties = MassPropertiesIO().initialize_zero() fuel_mass_properties.mass = sum( [filled_tank.mass for filled_tank in fuel_mass_per_tank]) - fuel_mass_properties.center_of_gravity = calculate_center_of_gravity( - fuel_mass_per_tank) + if fuel_mass_properties.mass != 0 : + fuel_mass_properties.center_of_gravity = calculate_center_of_gravity( + fuel_mass_per_tank) fuel_mass_properties.initialize_zero_inertia() # Return the fuel mass properties and distribution per tank @@ -1244,11 +1229,11 @@ def calculate_fuel_properties_defueling( if fuel_to_remove > total_fuel_available: if int(dict_ac_exchange['tool_level']) < int(routing_dict['tool_level']): - runtime_output.warning( + runtime_output.critical( "Fuel to remove exceeds the available fuel in all tanks!") else: raise ValueError( - "Fuel to remove exceeds the available fuel in all tanks!") + "Fuel to remove exceeds the available fuel in all tanks! Please check the mission information.") remaining_fuel_to_remove = fuel_to_remove defueled_mass_per_tank = [] @@ -1259,54 +1244,51 @@ def calculate_fuel_properties_defueling( fuel_available = other_tank.filled_fuel_mass fuel_to_defuel = min(fuel_available, remaining_fuel_to_remove) + defueled_tank = MassPropertiesIO().initialize_zero() + defueled_tank.center_of_gravity = other_tank.mass_properties.center_of_gravity + defueled_tank.name = other_tank.tank_location + if fuel_to_defuel > 0: remaining_fuel_to_remove -= fuel_to_defuel - defueled_tank = MassPropertiesIO().initialize_zero() defueled_tank.mass = -fuel_to_defuel # Negative for defueling - defueled_tank.center_of_gravity = other_tank.mass_properties.center_of_gravity defueled_tank.moment_change = (-fuel_to_defuel * defueled_tank.center_of_gravity["x"]) - defueled_tank.name = other_tank.tank_location defueled_tank.fuel_left_in_tank = fuel_available - fuel_to_defuel - defueled_mass_per_tank.append(defueled_tank) other_tank.filled_fuel_mass -= fuel_to_defuel else: - defueled_tank = MassPropertiesIO().initialize_zero() - defueled_tank.mass = 0 # Negative for defueling - defueled_tank.center_of_gravity = other_tank.mass_properties.center_of_gravity + defueled_tank.mass = 0 defueled_tank.moment_change = 0 - defueled_tank.name = other_tank.tank_location defueled_tank.fuel_left_in_tank = fuel_available - 0 - defueled_mass_per_tank.append(defueled_tank) other_tank.filled_fuel_mass -= 0 + defueled_mass_per_tank.append(defueled_tank) + # Step 2: Defuel center tank for center_tank in center_tanks: if remaining_fuel_to_remove > 0: fuel_available = center_tank.filled_fuel_mass fuel_to_defuel = min(fuel_available, remaining_fuel_to_remove) + + defueled_tank = MassPropertiesIO().initialize_zero() + defueled_tank.center_of_gravity = center_tank.mass_properties.center_of_gravity + defueled_tank.name = center_tank.tank_location + if fuel_to_defuel > 0: - defueled_tank = MassPropertiesIO().initialize_zero() defueled_tank.mass = -fuel_to_defuel # Negative for defueling - defueled_tank.center_of_gravity = center_tank.mass_properties.center_of_gravity defueled_tank.moment_change = (-fuel_to_defuel * defueled_tank.center_of_gravity["x"]) - defueled_tank.name = center_tank.tank_location defueled_tank.fuel_left_in_tank = fuel_available - fuel_to_defuel - defueled_mass_per_tank.append(defueled_tank) center_tank.filled_fuel_mass -= fuel_to_defuel remaining_fuel_to_remove -= fuel_to_defuel else: - defueled_tank = MassPropertiesIO().initialize_zero() defueled_tank.mass = 0 # nothing to remove - defueled_tank.center_of_gravity = center_tank.mass_properties.center_of_gravity defueled_tank.moment_change = 0 - defueled_tank.name = center_tank.tank_location defueled_tank.fuel_left_in_tank = fuel_available - 0 - defueled_mass_per_tank.append(defueled_tank) center_tank.filled_fuel_mass -= 0 + defueled_mass_per_tank.append(defueled_tank) + # Step 3: Defuel wing tanks (opposite to refueling) if left_wing_tanks and right_wing_tanks and remaining_fuel_to_remove > 0: for left_tank, right_tank in zip(left_wing_tanks, right_wing_tanks): @@ -1317,59 +1299,51 @@ def calculate_fuel_properties_defueling( fuel_to_defuel = min( left_fuel_available, right_fuel_available, remaining_fuel_to_remove / 2) + defueled_tank_left = MassPropertiesIO().initialize_zero() + defueled_tank_left.center_of_gravity = left_tank.mass_properties.center_of_gravity + defueled_tank_left.name = left_tank.tank_location + defueled_tank_right = MassPropertiesIO().initialize_zero() + defueled_tank_right.center_of_gravity = right_tank.mass_properties.center_of_gravity + defueled_tank_right.name = right_tank.tank_location + if fuel_to_defuel > 0: remaining_fuel_to_remove -= 2 * fuel_to_defuel - defueled_tank_left = MassPropertiesIO().initialize_zero() defueled_tank_left.mass = -fuel_to_defuel # Negative for defueling - defueled_tank_left.center_of_gravity = left_tank.mass_properties.center_of_gravity defueled_tank_left.moment_change = ( -fuel_to_defuel * defueled_tank_left.center_of_gravity["x"]) - defueled_tank_left.name = left_tank.tank_location defueled_tank_left.fuel_left_in_tank = left_fuel_available - fuel_to_defuel - defueled_tank_right = MassPropertiesIO().initialize_zero() defueled_tank_right.mass = -fuel_to_defuel # Negative for defueling - defueled_tank_right.center_of_gravity = right_tank.mass_properties.center_of_gravity defueled_tank_right.moment_change = ( -fuel_to_defuel * defueled_tank_right.center_of_gravity["x"]) - defueled_tank_right.name = right_tank.tank_location defueled_tank_right.fuel_left_in_tank = right_fuel_available - fuel_to_defuel - defueled_mass_per_tank.append(defueled_tank_left) - defueled_mass_per_tank.append(defueled_tank_right) - left_tank.filled_fuel_mass -= fuel_to_defuel right_tank.filled_fuel_mass -= fuel_to_defuel else: - defueled_tank_left = MassPropertiesIO().initialize_zero() defueled_tank_left.mass = 0 # nothing to remove - defueled_tank_left.center_of_gravity = left_tank.mass_properties.center_of_gravity defueled_tank_left.moment_change = 0 - defueled_tank_left.name = left_tank.tank_location defueled_tank_left.fuel_left_in_tank = left_fuel_available - 0 - defueled_tank_right = MassPropertiesIO().initialize_zero() defueled_tank_right.mass = 0 - defueled_tank_right.center_of_gravity = right_tank.mass_properties.center_of_gravity defueled_tank_right.moment_change = 0 - defueled_tank_right.name = right_tank.tank_location defueled_tank_right.fuel_left_in_tank = right_fuel_available - 0 - defueled_mass_per_tank.append(defueled_tank_left) - defueled_mass_per_tank.append(defueled_tank_right) - left_tank.filled_fuel_mass -= 0 right_tank.filled_fuel_mass -= 0 + defueled_mass_per_tank.append(defueled_tank_left) + defueled_mass_per_tank.append(defueled_tank_right) + # Check if we have defueled the correct amount if remaining_fuel_to_remove > 0: if int(dict_ac_exchange['tool_level']) < int(routing_dict['tool_level']): - runtime_output.warning( + runtime_output.critical( "Not enough fuel in the tanks to complete defueling!") else: raise ValueError( - "Not enough fuel in the tanks to complete defueling!") + "Not enough fuel in the tanks to complete defueling! Please check the mission information.") return defueled_mass_per_tank @@ -2327,7 +2301,7 @@ def defueling(runtime_output, defueling_mode, **kwargs): kwargs['starting_cg'], kwargs['starting_mass'], kwargs['defueling_mass_per_tank'], kwargs['mac'], kwargs['x_leading_edge_mac']) - for fuel in kwargs['defueling_mass_per_tank_ferry']: + for fuel in kwargs['defueling_mass_per_tank']: runtime_output.print( f"From tank '{fuel.name}' was defueld {-fuel.mass:.4f} kg. Fuel left in tank: {fuel.fuel_left_in_tank:.4f} kg.") else: diff --git a/weight_and_balance_analysis/src/tube_and_wing/standard/basic/tankIO.py b/weight_and_balance_analysis/src/tube_and_wing/standard/basic/tankIO.py index a39b5251a80e90388d53a21c79e645589fd4d712..3a1feade1877774b4c0feec312da780ccf90e13d 100644 --- a/weight_and_balance_analysis/src/tube_and_wing/standard/basic/tankIO.py +++ b/weight_and_balance_analysis/src/tube_and_wing/standard/basic/tankIO.py @@ -85,13 +85,5 @@ class TankIO: "./mass_properties").read(xml_node) self.energy = float(xml_node.find( "./maximum_energy_capacity/value").text) - self.used_tank = (xml_node.find( - "./energy_capacity_required_for_mission/value").text) - # self.volume = { - # "value": float(xml_node.find("./volume/value").text), - # "unit": xml_node.find("./volume/unit").text, - # "lower_boundary": float(xml_node.find("./volume/lower_boundary").text), - # "upper_boundary": float(xml_node.find("./volume/upper_boundary").text) - # } return self diff --git a/weight_and_balance_analysis/src/tube_and_wing/standard/usermethoddatapreparation.py b/weight_and_balance_analysis/src/tube_and_wing/standard/usermethoddatapreparation.py index 354c3036e96085fd288ab17ac64156916c6532c8..310f0641f35758bdde6f2aaabe58f08ff3b839c5 100644 --- a/weight_and_balance_analysis/src/tube_and_wing/standard/usermethoddatapreparation.py +++ b/weight_and_balance_analysis/src/tube_and_wing/standard/usermethoddatapreparation.py @@ -77,9 +77,9 @@ def user_method_data_input_preparation(routing_dict): "taxi_energy_out_carrier": [ mission_analysis_path + 'taxi_energy/taxi_out_energy[@ID="0"]/energy_carrier_ID', float], "take_off_energy": [ - mission_analysis_path + 'in_flight_energy/takoff_energy[@ID="0"]/consumed_energy', float], + mission_analysis_path + 'in_flight_energy/takeoff_energy[@ID="0"]/consumed_energy', float], "take_off_energy_carrier": [ - mission_analysis_path + 'in_flight_energy/takoff_energy[@ID="0"]/energy_carrier_ID', float], + mission_analysis_path + 'in_flight_energy/takeoff_energy[@ID="0"]/energy_carrier_ID', float], "landing_energy": [ mission_analysis_path + 'in_flight_energy/landing_energy[@ID="0"]/consumed_energy', float], "landing_energy_carrier": [