Repository: supaero-aircraft-design/FAST-GA (language: python)

Issue:
VLM code / TBM example
Issue with the VLM code when it is used to size the TBM aircraft. The second angle of attack, INPUT_AOA = 10, causes troubles for the code to converge. When it is set up at 5, the polar looks better. However, there is no problem when the sizing is done with OpenVSP.
So, to use the VLM method, we have to change the value of INPUT_AOA. This could be done by adding an option in OpenMDAO.
VLM code / TBM example
Issue with the VLM code when it is used to size the TBM aircraft. The second angle of attack, INPUT_AOA = 10, causes troubles for the code to converge. When it is set up at 5, the polar looks better. However, there is no problem when the sizing is done with OpenVSP.
So, to use the VLM method, we have to change the value of INPUT_AOA. This could be done by adding an option in OpenMDAO.


Discussion / hints:

Fix patch:
diff --git a/src/fastga/command/api.py b/src/fastga/command/api.py
index 8c59060a..cfc50e0b 100644
--- a/src/fastga/command/api.py
+++ b/src/fastga/command/api.py
@@ -806,3 +806,12 @@ def list_outputs(component: Union[om.ExplicitComponent, om.Group]) -> list:
     output_names = [var.name for var in variables if not var.is_input]
 
     return output_names
+
+
+def string_to_array(arr):
+    """
+    Convert a numpy array that was stored as a string back to a numpy array.
+
+    "[-20.0, -19.5, -19.0, ..., 19.0, 19.5, 20.0]" --> [-20.0, -19.5, -19.0, ..., 19.0, 19.5, 20.0]
+    """
+    return np.array(arr.strip("[]").split(","), dtype=float)
diff --git a/src/fastga/models/aerodynamics/aerodynamics.py b/src/fastga/models/aerodynamics/aerodynamics.py
index 136b9622..c8867548 100644
--- a/src/fastga/models/aerodynamics/aerodynamics.py
+++ b/src/fastga/models/aerodynamics/aerodynamics.py
@@ -21,6 +21,8 @@
 from fastga.models.aerodynamics.aerodynamics_high_speed import AerodynamicsHighSpeed
 from fastga.models.aerodynamics.aerodynamics_low_speed import AerodynamicsLowSpeed
 
+from .constants import DEFAULT_INPUT_AOA
+
 
 @oad.RegisterOpenMDAOSystem("fastga.aerodynamics.legacy", domain=ModelDomain.AERODYNAMICS)
 class Aerodynamics(om.Group):
@@ -42,6 +44,7 @@ def initialize(self):
         self.options.declare("wing_airfoil", default="naca23012.af", types=str, allow_none=True)
         self.options.declare("htp_airfoil", default="naca0012.af", types=str, allow_none=True)
         self.options.declare("vtp_airfoil", default="naca0012.af", types=str, allow_none=True)
+        self.options.declare("input_angle_of_attack", default=DEFAULT_INPUT_AOA, types=float)
 
     def setup(self):
         """Add the LowSpeed and HighSpeedAerodynamics subsystems."""
@@ -58,6 +61,7 @@ def setup(self):
                 wing_airfoil=self.options["wing_airfoil"],
                 htp_airfoil=self.options["htp_airfoil"],
                 vtp_airfoil=self.options["vtp_airfoil"],
+                input_angle_of_attack=self.options["input_angle_of_attack"],
             ),
             promotes=["*"],
         )
@@ -76,6 +80,7 @@ def setup(self):
                 wing_airfoil=self.options["wing_airfoil"],
                 htp_airfoil=self.options["htp_airfoil"],
                 vtp_airfoil=self.options["vtp_airfoil"],
+                input_angle_of_attack=self.options["input_angle_of_attack"],
             ),
             promotes=["*"],
         )
diff --git a/src/fastga/models/aerodynamics/aerodynamics_high_speed.py b/src/fastga/models/aerodynamics/aerodynamics_high_speed.py
index 04fdffff..f5a1eef8 100644
--- a/src/fastga/models/aerodynamics/aerodynamics_high_speed.py
+++ b/src/fastga/models/aerodynamics/aerodynamics_high_speed.py
@@ -17,14 +17,14 @@
 import fastoad.api as oad
 from fastoad.module_management.constants import ModelDomain
 
-from fastga.models.aerodynamics.external.openvsp import ComputeAEROopenvsp
+from fastga.models.aerodynamics.external.openvsp import ComputeAeroOpenVSP
 from fastga.models.aerodynamics.components import ComputeMachInterpolation
 
 # noinspection PyProtectedMember
 from fastga.models.aerodynamics.external.openvsp.compute_aero_slipstream import (
     ComputeSlipstreamOpenvspSubGroup,
 )
-from fastga.models.aerodynamics.external.vlm import ComputeAEROvlm
+from fastga.models.aerodynamics.external.vlm import ComputeAeroVLM
 from .constants import (
     SUBMODEL_CD0,
     SUBMODEL_CL_ALPHA_VT,
@@ -36,6 +36,7 @@
     SUBMODEL_DOWNWASH,
     SUBMODEL_CY_BETA,
     SUBMODEL_CN_BETA,
+    DEFAULT_INPUT_AOA,
 )
 
 
@@ -54,6 +55,7 @@ def initialize(self):
         self.options.declare("wing_airfoil", default="naca23012.af", types=str, allow_none=True)
         self.options.declare("htp_airfoil", default="naca0012.af", types=str, allow_none=True)
         self.options.declare("vtp_airfoil", default="naca0012.af", types=str, allow_none=True)
+        self.options.declare("input_angle_of_attack", default=DEFAULT_INPUT_AOA, types=float)
 
     # noinspection PyTypeChecker
     def setup(self):
@@ -61,26 +63,28 @@ def setup(self):
             if self.options["compute_mach_interpolation"]:
                 self.add_subsystem(
                     "aero_vlm",
-                    ComputeAEROvlm(
+                    ComputeAeroVLM(
                         low_speed_aero=False,
                         result_folder_path=self.options["result_folder_path"],
                         compute_mach_interpolation=True,
                         airfoil_folder_path=self.options["airfoil_folder_path"],
                         wing_airfoil_file=self.options["wing_airfoil"],
                         htp_airfoil_file=self.options["htp_airfoil"],
+                        input_angle_of_attack=self.options["input_angle_of_attack"],
                     ),
                     promotes=["*"],
                 )
             else:
                 self.add_subsystem(
                     "aero_vlm",
-                    ComputeAEROvlm(
+                    ComputeAeroVLM(
                         low_speed_aero=False,
                         result_folder_path=self.options["result_folder_path"],
                         compute_mach_interpolation=False,
                         airfoil_folder_path=self.options["airfoil_folder_path"],
                         wing_airfoil_file=self.options["wing_airfoil"],
                         htp_airfoil_file=self.options["htp_airfoil"],
+                        input_angle_of_attack=self.options["input_angle_of_attack"],
                     ),
                     promotes=["*"],
                 )
@@ -97,7 +101,7 @@ def setup(self):
             if self.options["compute_mach_interpolation"]:
                 self.add_subsystem(
                     "aero_openvsp",
-                    ComputeAEROopenvsp(
+                    ComputeAeroOpenVSP(
                         low_speed_aero=False,
                         compute_mach_interpolation=True,
                         result_folder_path=self.options["result_folder_path"],
@@ -105,13 +109,14 @@ def setup(self):
                         airfoil_folder_path=self.options["airfoil_folder_path"],
                         wing_airfoil_file=self.options["wing_airfoil"],
                         htp_airfoil_file=self.options["htp_airfoil"],
+                        input_angle_of_attack=self.options["input_angle_of_attack"],
                     ),
                     promotes=["*"],
                 )
             else:
                 self.add_subsystem(
                     "aero_openvsp",
-                    ComputeAEROopenvsp(
+                    ComputeAeroOpenVSP(
                         low_speed_aero=False,
                         compute_mach_interpolation=False,
                         result_folder_path=self.options["result_folder_path"],
@@ -119,6 +124,7 @@ def setup(self):
                         openvsp_exe_path=self.options["openvsp_exe_path"],
                         wing_airfoil_file=self.options["wing_airfoil"],
                         htp_airfoil_file=self.options["htp_airfoil"],
+                        input_angle_of_attack=self.options["input_angle_of_attack"],
                     ),
                     promotes=["*"],
                 )
diff --git a/src/fastga/models/aerodynamics/aerodynamics_low_speed.py b/src/fastga/models/aerodynamics/aerodynamics_low_speed.py
index 5e8de6c4..26057b19 100644
--- a/src/fastga/models/aerodynamics/aerodynamics_low_speed.py
+++ b/src/fastga/models/aerodynamics/aerodynamics_low_speed.py
@@ -17,13 +17,13 @@
 import fastoad.api as oad
 from fastoad.module_management.constants import ModelDomain
 
-from fastga.models.aerodynamics.external.openvsp import ComputeAEROopenvsp
+from fastga.models.aerodynamics.external.openvsp import ComputeAeroOpenVSP
 
 # noinspection PyProtectedMember
 from fastga.models.aerodynamics.external.openvsp.compute_aero_slipstream import (
     ComputeSlipstreamOpenvspSubGroup,
 )
-from fastga.models.aerodynamics.external.vlm import ComputeAEROvlm
+from fastga.models.aerodynamics.external.vlm import ComputeAeroVLM
 from .constants import (
     SUBMODEL_CD0,
     SUBMODEL_AIRFOIL_LIFT_SLOPE,
@@ -38,6 +38,7 @@
     SUBMODEL_DOWNWASH,
     SUBMODEL_CY_BETA,
     SUBMODEL_CN_BETA,
+    DEFAULT_INPUT_AOA,
 )
 
 
@@ -55,26 +56,28 @@ def initialize(self):
         self.options.declare("wing_airfoil", default="naca23012.af", types=str, allow_none=True)
         self.options.declare("htp_airfoil", default="naca0012.af", types=str, allow_none=True)
         self.options.declare("vtp_airfoil", default="naca0012.af", types=str, allow_none=True)
+        self.options.declare("input_angle_of_attack", default=DEFAULT_INPUT_AOA, types=float)
 
     # noinspection PyTypeChecker
     def setup(self):
         if not self.options["use_openvsp"]:
             self.add_subsystem(
                 "aero_vlm",
-                ComputeAEROvlm(
+                ComputeAeroVLM(
                     low_speed_aero=True,
                     compute_mach_interpolation=False,
                     result_folder_path=self.options["result_folder_path"],
                     airfoil_folder_path=self.options["airfoil_folder_path"],
                     wing_airfoil_file=self.options["wing_airfoil"],
                     htp_airfoil_file=self.options["htp_airfoil"],
+                    input_angle_of_attack=self.options["input_angle_of_attack"],
                 ),
                 promotes=["*"],
             )
         else:
             self.add_subsystem(
                 "aero_openvsp",
-                ComputeAEROopenvsp(
+                ComputeAeroOpenVSP(
                     low_speed_aero=True,
                     compute_mach_interpolation=False,
                     result_folder_path=self.options["result_folder_path"],
@@ -82,6 +85,7 @@ def setup(self):
                     airfoil_folder_path=self.options["airfoil_folder_path"],
                     wing_airfoil_file=self.options["wing_airfoil"],
                     htp_airfoil_file=self.options["htp_airfoil"],
+                    input_angle_of_attack=self.options["input_angle_of_attack"],
                 ),
                 promotes=["*"],
             )
diff --git a/src/fastga/models/aerodynamics/constants.py b/src/fastga/models/aerodynamics/constants.py
index 131abdd2..45ad9624 100644
--- a/src/fastga/models/aerodynamics/constants.py
+++ b/src/fastga/models/aerodynamics/constants.py
@@ -16,6 +16,7 @@
 MACH_NB_PTS = 5
 ENGINE_COUNT = 10
 FIRST_INVALID_COEFF = 100.0
+DEFAULT_INPUT_AOA = 10.0  # only one value given since calculation is done by default around 0.0!
 
 SUBMODEL_CD0 = "submodel.aerodynamics.aircraft.cd0"
 SUBMODEL_CD0_WING = "submodel.aerodynamics.wing.cd0"
diff --git a/src/fastga/models/aerodynamics/external/openvsp/__init__.py b/src/fastga/models/aerodynamics/external/openvsp/__init__.py
index ca629fc2..0fc8d4ef 100644
--- a/src/fastga/models/aerodynamics/external/openvsp/__init__.py
+++ b/src/fastga/models/aerodynamics/external/openvsp/__init__.py
@@ -12,4 +12,4 @@
 #  You should have received a copy of the GNU General Public License
 #  along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
-from .compute_aero import ComputeAEROopenvsp
+from .compute_aero import ComputeAeroOpenVSP
diff --git a/src/fastga/models/aerodynamics/external/openvsp/compute_aero.py b/src/fastga/models/aerodynamics/external/openvsp/compute_aero.py
index 67317fe0..8879b15e 100644
--- a/src/fastga/models/aerodynamics/external/openvsp/compute_aero.py
+++ b/src/fastga/models/aerodynamics/external/openvsp/compute_aero.py
@@ -20,16 +20,14 @@
 import numpy as np
 from openmdao.core.group import Group
 
-from .openvsp import OPENVSPSimpleGeometry, DEFAULT_WING_AIRFOIL, DEFAULT_HTP_AIRFOIL
+from .openvsp import OpenVSPSimpleGeometry, DEFAULT_WING_AIRFOIL, DEFAULT_HTP_AIRFOIL
 from ...components.compute_reynolds import ComputeUnitReynolds
-from ...constants import SPAN_MESH_POINT, MACH_NB_PTS
+from ...constants import SPAN_MESH_POINT, MACH_NB_PTS, DEFAULT_INPUT_AOA
 
 _LOGGER = logging.getLogger(__name__)
 
-INPUT_AOA = 10.0  # only one value given since calculation is done by default around 0.0!
 
-
-class ComputeAEROopenvsp(Group):
+class ComputeAeroOpenVSP(Group):
     def initialize(self):
         self.options.declare("low_speed_aero", default=False, types=bool)
         self.options.declare("compute_mach_interpolation", default=False, types=bool)
@@ -42,6 +40,7 @@ def initialize(self):
         self.options.declare(
             "htp_airfoil_file", default=DEFAULT_HTP_AIRFOIL, types=str, allow_none=True
         )
+        self.options.declare("input_angle_of_attack", default=DEFAULT_INPUT_AOA, types=float)
 
     def setup(self):
         self.add_subsystem(
@@ -51,7 +50,7 @@ def setup(self):
         )
         self.add_subsystem(
             "aero_openvsp",
-            _ComputeAEROopenvsp(
+            _ComputeAeroOpenVSP(
                 low_speed_aero=self.options["low_speed_aero"],
                 compute_mach_interpolation=self.options["compute_mach_interpolation"],
                 result_folder_path=self.options["result_folder_path"],
@@ -59,16 +58,18 @@ def setup(self):
                 airfoil_folder_path=self.options["airfoil_folder_path"],
                 wing_airfoil_file=self.options["wing_airfoil_file"],
                 htp_airfoil_file=self.options["htp_airfoil_file"],
+                input_angle_of_attack=self.options["input_angle_of_attack"],
             ),
             promotes=["*"],
         )
 
 
-class _ComputeAEROopenvsp(OPENVSPSimpleGeometry):
+class _ComputeAeroOpenVSP(OpenVSPSimpleGeometry):
     def initialize(self):
         super().initialize()
         self.options.declare("low_speed_aero", default=False, types=bool)
         self.options.declare("compute_mach_interpolation", default=False, types=bool)
+        self.options.declare("input_angle_of_attack", default=DEFAULT_INPUT_AOA, types=float)
 
     def setup(self):
         super().setup()
@@ -138,10 +139,11 @@ def check_config(self, logger):
     def compute(self, inputs, outputs):
 
         _LOGGER.debug("Entering aerodynamic computation")
+        input_aoa = self.options["input_angle_of_attack"]
 
         # Check AOA input is float
-        if not isinstance(INPUT_AOA, float):
-            raise TypeError("INPUT_AOA should be a float!")
+        if not isinstance(input_aoa, float):
+            raise TypeError("Option input_angle_of_attack should be a float!")
 
         if self.options["low_speed_aero"]:
             altitude = 0.0
@@ -166,11 +168,12 @@ def compute(self, inputs, outputs):
             y_vector_htp,
             cl_vector_htp,
             coef_k_htp,
-        ) = self.compute_aero_coeff(inputs, outputs, altitude, mach, INPUT_AOA)
+            _,
+        ) = self.compute_aero_coeff(inputs, outputs, altitude, mach, input_aoa)
 
         if not self.options["low_speed_aero"] and self.options["compute_mach_interpolation"]:
             mach_interp, cl_alpha_interp = self.compute_cl_alpha_mach(
-                inputs, outputs, INPUT_AOA, altitude, mach
+                inputs, outputs, input_aoa, altitude, mach
             )
             outputs["data:aerodynamics:aircraft:mach_interpolation:mach_vector"] = mach_interp
             outputs[
diff --git a/src/fastga/models/aerodynamics/external/openvsp/compute_aero_slipstream.py b/src/fastga/models/aerodynamics/external/openvsp/compute_aero_slipstream.py
index 3dc96a11..1a445c1d 100644
--- a/src/fastga/models/aerodynamics/external/openvsp/compute_aero_slipstream.py
+++ b/src/fastga/models/aerodynamics/external/openvsp/compute_aero_slipstream.py
@@ -24,7 +24,7 @@
 from fastoad.module_management._bundle_loader import BundleLoader
 from fastoad.constants import EngineSetting
 
-from .openvsp import OPENVSPSimpleGeometryDP, DEFAULT_WING_AIRFOIL
+from .openvsp import OpenVSPSimpleGeometryDP, DEFAULT_WING_AIRFOIL
 from ...components.compute_reynolds import ComputeUnitReynolds
 from ...constants import SPAN_MESH_POINT, SUBMODEL_THRUST_POWER_SLIPSTREAM
 
@@ -124,7 +124,7 @@ def setup(self):
         )
 
 
-class _ComputeSlipstreamOpenvsp(OPENVSPSimpleGeometryDP):
+class _ComputeSlipstreamOpenvsp(OpenVSPSimpleGeometryDP):
     def initialize(self):
         super().initialize()
         self.options.declare("low_speed_aero", default=False, types=bool)
@@ -234,7 +234,7 @@ def compute(self, inputs, outputs):
         wing_rotor = self.compute_wing_rotor(
             inputs, outputs, altitude, mach, alpha_max, inputs["thrust"], inputs["shaft_power"]
         )
-        wing = self.compute_wing(inputs, outputs, altitude, mach, alpha_max)
+        wing = self.compute_aero(inputs, outputs, altitude, mach, alpha_max, comp_opt="wing")
 
         cl_vector_prop_on = wing_rotor["cl_vector"]
         y_vector_prop_on = wing_rotor["y_vector"]
@@ -248,9 +248,9 @@ def compute(self, inputs, outputs):
         cl_vector_prop_off.extend(additional_zeros)
         y_vector_prop_off.extend(additional_zeros)
 
-        cl_diff = []
-        for i in range(len(cl_vector_prop_on)):
-            cl_diff.append(round(cl_vector_prop_on[i] - cl_vector_prop_off[i], 4))
+        cl_diff = np.round(
+            np.asarray(cl_vector_prop_on) - np.asarray(cl_vector_prop_off), 4
+        ).tolist()
 
         if self.options["low_speed_aero"]:
             outputs[
diff --git a/src/fastga/models/aerodynamics/external/openvsp/openvsp.py b/src/fastga/models/aerodynamics/external/openvsp/openvsp.py
index 1fd9337f..df1b6bf2 100644
--- a/src/fastga/models/aerodynamics/external/openvsp/openvsp.py
+++ b/src/fastga/models/aerodynamics/external/openvsp/openvsp.py
@@ -28,7 +28,7 @@
 from stdatm import Atmosphere
 
 # noinspection PyProtectedMember
-from fastga.command.api import _create_tmp_directory
+from fastga.command.api import _create_tmp_directory, string_to_array
 from fastga.utils.resource_management.copy import copy_resource_from_path
 from . import openvsp3201
 from . import resources as local_resources
@@ -46,7 +46,7 @@
 VSPAERO_EXE_NAME = "vspaero.exe"
 
 
-class OPENVSPSimpleGeometry(ExternalCodeComp):
+class OpenVSPSimpleGeometry(ExternalCodeComp):
     """Execution of OpenVSP for clean surfaces."""
 
     def __init__(self, **kwargs):
@@ -129,6 +129,7 @@ def compute_cl_alpha_aircraft(self, inputs, outputs, altitude, mach, aoa_angle):
             _,
             _,
             _,
+            _,
         ) = self.compute_aero_coeff(inputs, outputs, altitude, mach, aoa_angle)
         return float(cl_alpha_wing + cl_alpha_htp)
 
@@ -166,39 +167,13 @@ def compute_aero_coeff(self, inputs, outputs, altitude, mach, aoa_angle):
         cl_0_htp,  cl_aoa_htp, cl_alpha_htp, cl_alpha_htp_isolated, y_vector_htp, cl_vector_htp,
         coeff_k_htp parameters.
         """
-
+        # initialize
+        results = [None] * 16
         # Fix mach number of digits to consider similar results
         mach = round(float(mach) * 1e3) / 1e3
 
         # Get inputs necessary to define global geometry
-        s_ref_wing = float(inputs["data:geometry:wing:area"])
-        s_ref_htp = float(inputs["data:geometry:horizontal_tail:area"])
-        area_ratio = s_ref_htp / s_ref_wing
-        sweep25_wing = float(inputs["data:geometry:wing:sweep_25"])
-        taper_ratio_wing = float(inputs["data:geometry:wing:taper_ratio"])
-        aspect_ratio_wing = float(inputs["data:geometry:wing:aspect_ratio"])
-        sweep25_htp = float(inputs["data:geometry:horizontal_tail:sweep_25"])
-        aspect_ratio_htp = float(inputs["data:geometry:horizontal_tail:aspect_ratio"])
-        taper_ratio_htp = float(inputs["data:geometry:horizontal_tail:taper_ratio"])
-        dihedral_angle = float(inputs["data:geometry:wing:dihedral"])
-        twist_angle = float(inputs["data:geometry:wing:twist"])
-        geometry_set = np.around(
-            np.array(
-                [
-                    sweep25_wing,
-                    taper_ratio_wing,
-                    aspect_ratio_wing,
-                    dihedral_angle,
-                    twist_angle,
-                    sweep25_htp,
-                    taper_ratio_htp,
-                    aspect_ratio_htp,
-                    mach,
-                    area_ratio,
-                ]
-            ),
-            decimals=6,
-        )
+        s_ref_wing, area_ratio, geometry_set = self.define_geometry(inputs, mach)
 
         # Search if results already exist:
         result_folder_path = self.options["result_folder_path"]
@@ -222,74 +197,57 @@ def compute_aero_coeff(self, inputs, outputs, altitude, mach, aoa_angle):
                 result_file_path = self.save_geometry(result_folder_path, geometry_set)
 
             # Compute wing alone @ 0°/X° angle of attack
-            wing_0 = self.compute_wing(inputs, outputs, altitude, mach, 0.0)
-            wing_aoa = self.compute_wing(inputs, outputs, altitude, mach, aoa_angle)
+            wing_0 = self.compute_aero(inputs, outputs, altitude, mach, 0.0, comp_opt="wing")
+            wing_aoa = self.compute_aero(
+                inputs, outputs, altitude, mach, aoa_angle, comp_opt="wing"
+            )
 
             # Compute complete aircraft @ 0°/X° angle of attack
-            _, htp_0, _ = self.compute_aircraft(inputs, outputs, altitude, mach, 0.0)
-            _, htp_aoa, _ = self.compute_aircraft(inputs, outputs, altitude, mach, aoa_angle)
+            _, htp_0, _ = self.compute_aero(inputs, outputs, altitude, mach, 0.0, comp_opt="ac")
+            _, htp_aoa, _ = self.compute_aero(
+                inputs, outputs, altitude, mach, aoa_angle, comp_opt="ac"
+            )
+
+            # Small remark: we could used the full aircraft simulation to get the wing aerodynamic
+            # data because HTP should have a minor impact on the wing characteristics.
+            # Unfortunately, results are a bit different in value and format
 
             # Compute isolated HTP @ 0°/X° angle of attack
-            htp_0_isolated = self.compute_isolated_htp(inputs, outputs, altitude, mach, 0.0)
-            htp_aoa_isolated = self.compute_isolated_htp(inputs, outputs, altitude, mach, aoa_angle)
+            htp_0_isolated = self.compute_aero(inputs, outputs, altitude, mach, 0.0, comp_opt="htp")
+            htp_aoa_isolated = self.compute_aero(
+                inputs, outputs, altitude, mach, aoa_angle, comp_opt="htp"
+            )
 
             # Post-process wing data ---------------------------------------------------------------
-            width_max = inputs["data:geometry:fuselage:maximum_width"]
-            span_wing = inputs["data:geometry:wing:span"]
-            k_fus = 1 + 0.025 * width_max / span_wing - 0.025 * (width_max / span_wing) ** 2
-            cl_0_wing = float(wing_0["cl"] * k_fus)
-            cl_x_wing = float(wing_aoa["cl"] * k_fus)
-            cm_0_wing = float(wing_0["cm"] * k_fus)
-            cl_alpha_wing = (cl_x_wing - cl_0_wing) / (aoa_angle * np.pi / 180)
-            y_vector_wing = wing_aoa["y_vector"]
-            cl_vector_wing = (np.array(wing_aoa["cl_vector"]) * k_fus).tolist()
-            chord_vector_wing = wing_aoa["chord_vector"]
-            k_fus = 1 - 2 * (width_max / span_wing) ** 2  # Fuselage correction
-            # Full aircraft correction: Wing lift is 105% of total lift, so: CDi = (CL*1.05)^2/(
-            # piAe) -> e' = e/1.05^2
-            coeff_e = float(wing_aoa["coeff_e"] * k_fus / 1.05 ** 2)
-            coeff_k_wing = float(1.0 / (np.pi * span_wing ** 2 / s_ref_wing * coeff_e))
-
-            # Post-process HTP-aircraft data -------------------------------------------------------
-            cl_0_htp = float(htp_0["cl"])
-            cl_aoa_htp = float(htp_aoa["cl"])
-            cl_alpha_htp = float((cl_aoa_htp - cl_0_htp) / (aoa_angle * np.pi / 180))
-            coeff_k_htp = float(htp_aoa["cdi"]) / cl_aoa_htp ** 2
-            y_vector_htp = htp_aoa["y_vector"]
-            cl_vector_htp = (np.array(htp_aoa["cl_vector"]) * area_ratio).tolist()
-
-            # Post-process HTP-isolated data -------------------------------------------------------
-            cl_alpha_htp_isolated = (
-                float(htp_aoa_isolated["cl"] - htp_0_isolated["cl"])
-                * area_ratio
-                / (aoa_angle * np.pi / 180)
+            (
+                cl_0_wing,
+                cl_x_wing,
+                cl_alpha_wing,
+                cm_0_wing,
+                y_vector_wing,
+                cl_vector_wing,
+                chord_vector_wing,
+                coeff_k_wing,
+            ) = self.post_process_wing(inputs, wing_0, wing_aoa, s_ref_wing, aoa_angle)
+
+            # Post-process HTP data ----------------------------------------------------------------
+            (
+                cl_0_htp,
+                cl_aoa_htp,
+                cl_alpha_htp,
+                cl_alpha_htp_isolated,
+                y_vector_htp,
+                cl_vector_htp,
+                coeff_k_htp,
+            ) = self.post_process_htp(
+                htp_0, htp_aoa, htp_0_isolated, htp_aoa_isolated, aoa_angle, area_ratio
             )
 
             # Resize vectors -----------------------------------------------------------------------
-            if SPAN_MESH_POINT < len(y_vector_wing):
-                y_interp = np.linspace(y_vector_wing[0], y_vector_wing[-1], SPAN_MESH_POINT)
-                cl_vector_wing = np.interp(y_interp, y_vector_wing, cl_vector_wing)
-                chord_vector_wing = np.interp(y_interp, y_vector_wing, chord_vector_wing)
-                y_vector_wing = y_interp
-                warnings.warn(
-                    "Defined maximum span mesh in fast aerodynamics\\constants.py exceeded!"
-                )
-            else:
-                additional_zeros = list(np.zeros(SPAN_MESH_POINT - len(y_vector_wing)))
-                y_vector_wing.extend(additional_zeros)
-                cl_vector_wing.extend(additional_zeros)
-                chord_vector_wing.extend(additional_zeros)
-            if SPAN_MESH_POINT < len(y_vector_htp):
-                y_interp = np.linspace(y_vector_htp[0], y_vector_htp[-1], SPAN_MESH_POINT)
-                cl_vector_htp = np.interp(y_interp, y_vector_htp, cl_vector_htp)
-                y_vector_htp = y_interp
-                warnings.warn(
-                    "Defined maximum span mesh in fast aerodynamics\\constants.py exceeded!"
-                )
-            else:
-                additional_zeros = list(np.zeros(SPAN_MESH_POINT - len(y_vector_htp)))
-                y_vector_htp.extend(additional_zeros)
-                cl_vector_htp.extend(additional_zeros)
+            vector_wing = [y_vector_wing, cl_vector_wing, chord_vector_wing]
+            y_vector_wing, cl_vector_wing, chord_vector_wing = self.resize_vector(vector_wing)
+            vector_htp = [y_vector_htp, cl_vector_htp]
+            y_vector_htp, cl_vector_htp = self.resize_vector(vector_htp)
 
             # Save results to defined path ---------------------------------------------------------
             if self.options["result_folder_path"] != "":
@@ -317,70 +275,30 @@ def compute_aero_coeff(self, inputs, outputs, altitude, mach, aoa_angle):
         else:
             # Read values from result file ---------------------------------------------------------
             data = self.read_results(result_file_path)
-            saved_area_wing = float(data.loc["saved_ref_area", 0])
-            cl_0_wing = float(data.loc["cl_0_wing", 0])
-            cl_x_wing = float(data.loc["cl_X_wing", 0])
-            cl_alpha_wing = float(data.loc["cl_alpha_wing", 0])
-            cm_0_wing = float(data.loc["cm_0_wing", 0])
-            y_vector_wing = np.array(
-                [float(i) for i in data.loc["y_vector_wing", 0][1:-2].split(",")]
-            ) * np.sqrt(s_ref_wing / saved_area_wing)
-            cl_vector_wing = np.array(
-                [float(i) for i in data.loc["cl_vector_wing", 0][1:-2].split(",")]
-            )
-            chord_vector_wing = np.array(
-                [float(i) for i in data.loc["chord_vector_wing", 0][1:-2].split(",")]
-            ) * np.sqrt(s_ref_wing / saved_area_wing)
-            coeff_k_wing = float(data.loc["coeff_k_wing", 0])
-            cl_0_htp = float(data.loc["cl_0_htp", 0]) * (area_ratio / saved_area_ratio)
-            cl_aoa_htp = float(data.loc["cl_X_htp", 0]) * (area_ratio / saved_area_ratio)
-            cl_alpha_htp = float(data.loc["cl_alpha_htp", 0]) * (area_ratio / saved_area_ratio)
-            cl_alpha_htp_isolated = float(data.loc["cl_alpha_htp_isolated", 0]) * (
-                area_ratio / saved_area_ratio
-            )
-            y_vector_htp = np.array(
-                [float(i) for i in data.loc["y_vector_htp", 0][1:-2].split(",")]
-            )
-            cl_vector_htp = np.array(
-                [float(i) for i in data.loc["cl_vector_htp", 0][1:-2].split(",")]
-            ) * (area_ratio / saved_area_ratio)
-            coeff_k_htp = float(data.loc["coeff_k_htp", 0]) * (area_ratio / saved_area_ratio)
-
-        return (
-            cl_0_wing,
-            cl_x_wing,
-            cl_alpha_wing,
-            cm_0_wing,
-            y_vector_wing,
-            cl_vector_wing,
-            chord_vector_wing,
-            coeff_k_wing,
-            cl_0_htp,
-            cl_aoa_htp,
-            cl_alpha_htp,
-            cl_alpha_htp_isolated,
-            y_vector_htp,
-            cl_vector_htp,
-            coeff_k_htp,
-        )
+            results = self.assign_read_data(data, area_ratio, saved_area_ratio, s_ref_wing)
+        return results
 
-    def compute_wing(self, inputs, outputs, altitude, mach, aoa_angle):
+    def compute_aero(self, inputs, outputs, altitude, mach, aoa_angle, comp_opt="wing"):
         """
-        Function that computes in OpenVSP environment the wing alone and returns the different
-        aerodynamic parameters.
-
-        @param inputs: inputs parameters defined within FAST-OAD-GA
-        @param outputs: outputs parameters defined within FAST-OAD-GA
-        @param altitude: altitude for aerodynamic calculation in meters
-        @param mach: air speed expressed in mach
-        @param aoa_angle: air speed angle of attack with respect to wing (degree)
-        @return: wing dictionary including aero parameters as keys: y_vector, cl_vector, cd_vector,
-        cm_vector, cl, cdi, cm, coeff_e
+        Function that computes in OpenVSP environment the wing, horizontal stablizer(htp),
+        and complete aircraft (considering wing and horizontal tail plan) and returns the
+        different aerodynamic parameters. The downwash is done by OpenVSP considering far field.
+
+        :param inputs: inputs parameters defined within FAST-OAD-GA
+        :param outputs: outputs parameters defined within FAST-OAD-GA
+        :param altitude: altitude for aerodynamic calculation in meters
+        :param mach: air speed expressed in mach
+        :param aoa_angle: air speed angle of attack with respect to aircraft
+        :param comp_opt: component to evaluate can be "wing", "htp" or "ac"
+
+        :return: wing/htp and aircraft dictionaries including their respective aerodynamic
+        coefficients
         """
-
+        output_result = {}
         # STEP 1/XX - DEFINE OR CALCULATE INPUT DATA FOR AERODYNAMIC EVALUATION ####################
         ############################################################################################
 
+        # WING
         # Get inputs (and calculate missing ones)
         s_ref_wing = float(inputs["data:geometry:wing:area"])
         x0_wing = inputs["data:geometry:wing:MAC:leading_edge:x:local"]
@@ -406,232 +324,16 @@ def compute_wing(self, inputs, outputs, altitude, mach, aoa_angle):
         span2_wing = y4_wing - y2_wing
         rho = atm.density
         v_inf = max(atm.speed_of_sound * mach, 0.01)  # avoid V=0 m/s crashes
-        reynolds = v_inf * l0_wing / atm.kinematic_viscosity
-
-        # STEP 2/XX - DEFINE WORK DIRECTORY, COPY RESOURCES AND CREATE COMMAND BATCH ###############
-        ############################################################################################
-
-        # If a folder path is specified for openvsp .exe, it becomes working directory (target),
-        # if not temporary folder is created
-        if self.options["openvsp_exe_path"]:
-            target_directory = pth.abspath(self.options["openvsp_exe_path"])
-        else:
-            tmp_directory = _create_tmp_directory()
-            target_directory = tmp_directory.name
-        # Define the list of necessary input files: geometry script and foil file for both wing/HTP
-        input_file_list = [
-            pth.join(target_directory, INPUT_WING_SCRIPT),
-            pth.join(target_directory, self.options["wing_airfoil_file"]),
-        ]
-        self.options["external_input_files"] = input_file_list
-        # Define standard error file by default to avoid error code return
-        self.stderr = pth.join(target_directory, STDERR_FILE_NAME)
-        # Copy resource in working (target) directory
-        # noinspection PyTypeChecker
-        copy_resource_folder(openvsp3201, target_directory)
-        # noinspection PyTypeChecker
-        if self.options["airfoil_folder_path"] is None:
-            copy_resource(airfoil_folder, self.options["wing_airfoil_file"], target_directory)
-        else:
-            copy_resource_from_path(
-                self.options["airfoil_folder_path"],
-                self.options["wing_airfoil_file"],
-                target_directory,
-            )
-        # Create corresponding .bat files (one for each geometry configuration)
-        self.options["command"] = [pth.join(target_directory, "vspscript.bat")]
-        batch_file = open(self.options["command"][0], "w+")
-        batch_file.write("@echo off\n")
-        command = (
-            pth.join(target_directory, VSPSCRIPT_EXE_NAME)
-            + " -script "
-            + pth.join(target_directory, INPUT_WING_SCRIPT)
-            + " >nul 2>nul\n"
-        )
-        batch_file.write(command)
-        batch_file.close()
-
-        # STEP 3/XX - OPEN THE TEMPLATE SCRIPT FOR GEOMETRY GENERATION, MODIFY VALUES AND SAVE TO
-        # WORKDIR #################################################################################
-
-        output_file_list = [
-            pth.join(target_directory, INPUT_WING_SCRIPT.replace(".vspscript", "_DegenGeom.csv"))
-        ]
-        parser = InputFileGenerator()
-        with path(local_resources, INPUT_WING_SCRIPT) as input_template_path:
-            parser.set_template_file(str(input_template_path))
-            parser.set_generated_file(input_file_list[0])
-            # Modify wing parameters
-            parser.mark_anchor("x_wing")
-            parser.transfer_var(float(x_wing), 0, 5)
-            parser.mark_anchor("z_wing")
-            parser.transfer_var(float(z_wing), 0, 5)
-            parser.mark_anchor("y1_wing")
-            parser.transfer_var(float(y1_wing), 0, 5)
-            for i in range(3):
-                parser.mark_anchor("l2_wing")
-                parser.transfer_var(float(l2_wing), 0, 5)
-            parser.reset_anchor()
-            parser.mark_anchor("span2_wing")
-            parser.transfer_var(float(span2_wing), 0, 5)
-            parser.mark_anchor("l4_wing")
-            parser.transfer_var(float(l4_wing), 0, 5)
-            parser.mark_anchor("sweep_0_wing")
-            parser.transfer_var(float(sweep_0_wing), 0, 5)
-            parser.mark_anchor("twist")
-            parser.transfer_var(float(twist), 0, 5)
-            parser.mark_anchor("dihedral_angle")
-            parser.transfer_var(float(dihedral_angle), 0, 5)
-            parser.mark_anchor("airfoil_0_file")
-            parser.transfer_var('"' + input_file_list[1].replace("\\", "/") + '"', 0, 3)
-            parser.mark_anchor("airfoil_1_file")
-            parser.transfer_var('"' + input_file_list[1].replace("\\", "/") + '"', 0, 3)
-            parser.mark_anchor("airfoil_2_file")
-            parser.transfer_var('"' + input_file_list[1].replace("\\", "/") + '"', 0, 3)
-            parser.mark_anchor("csv_file")
-            csv_name = output_file_list[0]
-            parser.transfer_var('"' + csv_name.replace("\\", "/") + '"', 0, 3)
-            parser.generate()
-
-        # STEP 4/XX - RUN BATCH TO GENERATE GEOMETRY .CSV FILE #####################################
-        ############################################################################################
-
-        self.options["external_output_files"] = output_file_list
-        super().compute(inputs, outputs)
-
-        # STEP 5/XX - DEFINE NEW INPUT/OUTPUT FILES LIST AND CREATE BATCH FOR VLM COMPUTATION ######
-        ############################################################################################
-
-        input_file_list = output_file_list
-        input_file_list.append(input_file_list[0].replace(".csv", ".vspaero"))
-        output_file_list = [
-            input_file_list[0].replace(".csv", ".lod"),
-            input_file_list[0].replace(".csv", ".polar"),
-        ]
-        self.options["external_input_files"] = input_file_list
-        self.options["external_output_files"] = output_file_list
-        self.options["command"] = [pth.join(target_directory, "vspaero.bat")]
-        batch_file = open(self.options["command"][0], "w+")
-        batch_file.write("@echo off\n")
-        command = (
-            pth.join(target_directory, VSPAERO_EXE_NAME)
-            + " "
-            + input_file_list[1].replace(".vspaero", "")
-            + " >nul 2>nul\n"
-        )
-        batch_file.write(command)
-        batch_file.close()
-
-        # STEP 6/XX - OPEN THE TEMPLATE VSPAERO FOR COMPUTATION, MODIFY VALUES AND SAVE TO WORKDIR #
-        ############################################################################################
-
-        parser = InputFileGenerator()
-        template_file = pth.split(input_file_list[1])[1]
-        with path(local_resources, template_file) as input_template_path:
-            parser.set_template_file(str(input_template_path))
-            parser.set_generated_file(input_file_list[1])
-            parser.reset_anchor()
-            parser.mark_anchor("Sref")
-            parser.transfer_var(float(s_ref_wing), 0, 3)
-            parser.mark_anchor("Cref")
-            parser.transfer_var(float(l0_wing), 0, 3)
-            parser.mark_anchor("Bref")
-            parser.transfer_var(float(span_wing), 0, 3)
-            parser.mark_anchor("X_cg")
-            parser.transfer_var(float(fa_length), 0, 3)
-            parser.mark_anchor("Mach")
-            parser.transfer_var(float(mach), 0, 3)
-            parser.mark_anchor("AOA")
-            parser.transfer_var(float(aoa_angle), 0, 3)
-            parser.mark_anchor("Vinf")
-            parser.transfer_var(float(v_inf), 0, 3)
-            parser.mark_anchor("Rho")
-            parser.transfer_var(float(rho), 0, 3)
-            parser.mark_anchor("ReCref")
-            parser.transfer_var(float(reynolds), 0, 3)
-            parser.generate()
-
-        # STEP 7/XX - RUN BATCH TO GENERATE AERO OUTPUT FILES (.lod, .polar...) ####################
-        ############################################################################################
-
-        super().compute(inputs, outputs)
-
-        # STEP 8/XX - READ FILES, RETURN RESULTS (AND CLEAR TEMPORARY WORKDIR) #####################
-        ############################################################################################
-
-        # Open .lod file and extract data
-        wing_y_vect = []
-        wing_chord_vect = []
-        wing_cl_vect = []
-        wing_cd_vect = []
-        wing_cm_vect = []
-        with open(output_file_list[0], "r") as file_stream:
-            data = file_stream.readlines()
-            for i, _ in enumerate(data):
-                line = data[i].split()
-                line.append("**")
-                if line[0] == "1":
-                    wing_y_vect.append(float(line[2]))
-                    wing_chord_vect.append(float(line[3]))
-                    wing_cl_vect.append(float(line[5]))
-                    wing_cd_vect.append(float(line[6]))
-                    wing_cm_vect.append(float(line[12]))
-                if line[0] == "Comp":
-                    cl_wing = float(data[i + 1].split()[5]) + float(
-                        data[i + 2].split()[5]
-                    )  # sum CL left/right
-                    cdi_wing = float(data[i + 1].split()[6]) + float(
-                        data[i + 2].split()[6]
-                    )  # sum CDi left/right
-                    cm_wing = float(data[i + 1].split()[12]) + float(
-                        data[i + 2].split()[12]
-                    )  # sum CM left/right
-                    break
-        # Open .polar file and extract data
-        with open(output_file_list[1], "r") as file_stream:
-            data = file_stream.readlines()
-            wing_e = float(data[1].split()[10])
-        # Delete temporary directory
-        if not self.options["openvsp_exe_path"]:
-            # noinspection PyUnboundLocalVariable
-            tmp_directory.cleanup()
-        # Return values
-        wing = {
-            "y_vector": wing_y_vect,
-            "cl_vector": wing_cl_vect,
-            "chord_vector": wing_chord_vect,
-            "cd_vector": wing_cd_vect,
-            "cm_vector": wing_cm_vect,
-            "cl": cl_wing,
-            "cdi": cdi_wing,
-            "cm": cm_wing,
-            "coeff_e": wing_e,
-        }
-        return wing
-
-    def compute_isolated_htp(self, inputs, outputs, altitude, mach, aoa_angle):
-        """
-        Function that computes in OpenVSP environment the HTP alone and returns the different
-        aerodynamic parameters.
-
-        @param inputs: inputs parameters defined within FAST-OAD-GA
-        @param outputs: outputs parameters defined within FAST-OAD-GA
-        @param altitude: altitude for aerodynamic calculation in meters
-        @param mach: air speed expressed in mach
-        @param aoa_angle: air speed angle of attack with respect to htp (degree)
-        @return: htp dictionary including aero parameters as keys: y_vector, cl_vector, cd_vector,
-        cm_vector, cl, cdi, cm, coeff_e
-        """
-
-        # STEP 1/XX - DEFINE OR CALCULATE INPUT DATA FOR AERODYNAMIC EVALUATION ####################
-        ############################################################################################
+        reynolds_wing = v_inf * l0_wing / atm.kinematic_viscosity
 
+        # HTP
         # Get inputs (and calculate missing ones)
         s_ref_htp = float(inputs["data:geometry:horizontal_tail:area"])
-        fa_length = inputs["data:geometry:wing:MAC:at25percent:x"]
-        height_max = inputs["data:geometry:fuselage:maximum_height"]
         sweep_25_htp = inputs["data:geometry:horizontal_tail:sweep_25"]
         semi_span_htp = inputs["data:geometry:horizontal_tail:span"] / 2.0
+        span_htp = (
+            inputs["data:geometry:horizontal_tail:span"] / 2.0
+        )  # full span? half span for htp?
         root_chord_htp = inputs["data:geometry:horizontal_tail:root:chord"]
         tip_chord_htp = inputs["data:geometry:horizontal_tail:tip:chord"]
         lp_htp = inputs["data:geometry:horizontal_tail:MAC:at25percent:x:from_wingMAC25"]
@@ -639,254 +341,12 @@ def compute_isolated_htp(self, inputs, outputs, altitude, mach, aoa_angle):
         x0_htp = inputs["data:geometry:horizontal_tail:MAC:at25percent:x:local"]
         height_htp = inputs["data:geometry:horizontal_tail:z:from_wingMAC25"]
         # Compute remaining inputs
-        atm = Atmosphere(altitude, altitude_in_feet=False)
         x_htp = fa_length + lp_htp - x0_htp - 0.25 * l0_htp
         z_htp = -(height_max - 0.12 * l0_htp) * 0.5 - height_htp
-        rho = atm.density
-        v_inf = max(atm.speed_of_sound * mach, 0.01)  # avoid V=0 m/s crashes
-        reynolds = v_inf * l0_htp / atm.kinematic_viscosity
-
-        # STEP 2/XX - DEFINE WORK DIRECTORY, COPY RESOURCES AND CREATE COMMAND BATCH ###############
-        ############################################################################################
-
-        # If a folder path is specified for openvsp .exe, it becomes working directory (target),
-        # if not temporary folder is created
-        if self.options["openvsp_exe_path"]:
-            target_directory = pth.abspath(self.options["openvsp_exe_path"])
-        else:
-            tmp_directory = _create_tmp_directory()
-            target_directory = tmp_directory.name
-        # Define the list of necessary input files: geometry script and foil file for both wing/HTP
-        input_file_list = [
-            pth.join(target_directory, INPUT_HTP_SCRIPT),
-            pth.join(target_directory, self.options["htp_airfoil_file"]),
-        ]
-        self.options["external_input_files"] = input_file_list
-        # Define standard error file by default to avoid error code return
-        self.stderr = pth.join(target_directory, STDERR_FILE_NAME)
-        # Copy resource in working (target) directory
-        # noinspection PyTypeChecker
-        copy_resource_folder(openvsp3201, target_directory)
-        # noinspection PyTypeChecker
-        if self.options["airfoil_folder_path"] is None:
-            copy_resource(airfoil_folder, self.options["htp_airfoil_file"], target_directory)
-        else:
-            copy_resource_from_path(
-                self.options["airfoil_folder_path"],
-                self.options["htp_airfoil_file"],
-                target_directory,
-            )
-        # Create corresponding .bat files (one for each geometry configuration)
-        self.options["command"] = [pth.join(target_directory, "vspscript.bat")]
-        batch_file = open(self.options["command"][0], "w+")
-        batch_file.write("@echo off\n")
-        command = (
-            pth.join(target_directory, VSPSCRIPT_EXE_NAME)
-            + " -script "
-            + pth.join(target_directory, INPUT_HTP_SCRIPT)
-            + " >nul 2>nul\n"
-        )
-        batch_file.write(command)
-        batch_file.close()
-
-        # STEP 3/XX - OPEN THE TEMPLATE SCRIPT FOR GEOMETRY GENERATION, MODIFY VALUES AND SAVE TO
-        # WORKDIR ##################################################################################
-
-        output_file_list = [
-            pth.join(target_directory, INPUT_HTP_SCRIPT.replace(".vspscript", "_DegenGeom.csv"))
-        ]
-        parser = InputFileGenerator()
-        with path(local_resources, INPUT_HTP_SCRIPT) as input_template_path:
-            parser.set_template_file(str(input_template_path))
-            parser.set_generated_file(input_file_list[0])
-            # Modify htp parameters
-            parser.mark_anchor("x_htp")
-            parser.transfer_var(float(x_htp), 0, 5)
-            parser.mark_anchor("z_htp")
-            parser.transfer_var(float(z_htp), 0, 5)
-            parser.mark_anchor("semi_span_htp")
-            parser.transfer_var(float(semi_span_htp), 0, 5)
-            parser.mark_anchor("root_chord_htp")
-            parser.transfer_var(float(root_chord_htp), 0, 5)
-            parser.mark_anchor("tip_chord_htp")
-            parser.transfer_var(float(tip_chord_htp), 0, 5)
-            parser.mark_anchor("sweep_25_htp")
-            parser.transfer_var(float(sweep_25_htp), 0, 5)
-            parser.mark_anchor("airfoil_0_file")
-            parser.transfer_var('"' + input_file_list[1].replace("\\", "/") + '"', 0, 3)
-            parser.mark_anchor("airfoil_1_file")
-            parser.transfer_var('"' + input_file_list[1].replace("\\", "/") + '"', 0, 3)
-            parser.mark_anchor("csv_file")
-            csv_name = output_file_list[0]
-            parser.transfer_var('"' + csv_name.replace("\\", "/") + '"', 0, 3)
-            parser.generate()
-
-        # STEP 4/XX - RUN BATCH TO GENERATE GEOMETRY .CSV FILE #####################################
-        ############################################################################################
-
-        self.options["external_output_files"] = output_file_list
-        super().compute(inputs, outputs)
-
-        # STEP 5/XX - DEFINE NEW INPUT/OUTPUT FILES LIST AND CREATE BATCH FOR VLM COMPUTATION ######
-        ############################################################################################
-
-        input_file_list = output_file_list
-        input_file_list.append(input_file_list[0].replace(".csv", ".vspaero"))
-        output_file_list = [
-            input_file_list[0].replace(".csv", ".lod"),
-            input_file_list[0].replace(".csv", ".polar"),
-        ]
-        self.options["external_input_files"] = input_file_list
-        self.options["external_output_files"] = output_file_list
-        self.options["command"] = [pth.join(target_directory, "vspaero.bat")]
-        batch_file = open(self.options["command"][0], "w+")
-        batch_file.write("@echo off\n")
-        command = (
-            pth.join(target_directory, VSPAERO_EXE_NAME)
-            + " "
-            + input_file_list[1].replace(".vspaero", "")
-            + " >nul 2>nul\n"
-        )
-        batch_file.write(command)
-        batch_file.close()
-
-        # STEP 6/XX - OPEN THE TEMPLATE VSPAERO FOR COMPUTATION, MODIFY VALUES AND SAVE TO WORKDIR #
-        ############################################################################################
-
-        parser = InputFileGenerator()
-        template_file = pth.split(input_file_list[1])[1]
-        with path(local_resources, template_file) as input_template_path:
-            parser.set_template_file(str(input_template_path))
-            parser.set_generated_file(input_file_list[1])
-            parser.reset_anchor()
-            parser.mark_anchor("Sref")
-            parser.transfer_var(float(s_ref_htp), 0, 3)
-            parser.mark_anchor("Cref")
-            parser.transfer_var(float(l0_htp), 0, 3)
-            parser.mark_anchor("Bref")
-            parser.transfer_var(float(2.0 * semi_span_htp), 0, 3)
-            parser.mark_anchor("X_cg")
-            parser.transfer_var(float(fa_length + lp_htp), 0, 3)
-            parser.mark_anchor("Mach")
-            parser.transfer_var(float(mach), 0, 3)
-            parser.mark_anchor("AOA")
-            parser.transfer_var(float(aoa_angle), 0, 3)
-            parser.mark_anchor("Vinf")
-            parser.transfer_var(float(v_inf), 0, 3)
-            parser.mark_anchor("Rho")
-            parser.transfer_var(float(rho), 0, 3)
-            parser.mark_anchor("ReCref")
-            parser.transfer_var(float(reynolds), 0, 3)
-            parser.generate()
-
-        # STEP 7/XX - RUN BATCH TO GENERATE AERO OUTPUT FILES (.lod, .polar...) ####################
-        ############################################################################################
-
-        super().compute(inputs, outputs)
-
-        # STEP 8/XX - READ FILES, RETURN RESULTS (AND CLEAR TEMPORARY WORKDIR) #####################
-        ############################################################################################
-
-        # Open .lod file and extract data
-        htp_y_vect = []
-        htp_cl_vect = []
-        htp_cd_vect = []
-        htp_cm_vect = []
-        with open(output_file_list[0], "r") as lf:
-            data = lf.readlines()
-            for i in range(len(data)):
-                line = data[i].split()
-                line.append("**")
-                if line[0] == "1":
-                    htp_y_vect.append(float(line[2]))
-                    htp_cl_vect.append(float(line[5]))
-                    htp_cd_vect.append(float(line[6]))
-                    htp_cm_vect.append(float(line[12]))
-                if line[0] == "Comp":
-                    cl_htp = float(data[i + 1].split()[5]) + float(
-                        data[i + 2].split()[5]
-                    )  # sum CL left/right
-                    cdi_htp = float(data[i + 1].split()[6]) + float(
-                        data[i + 2].split()[6]
-                    )  # sum CDi left/right
-                    cm_htp = float(data[i + 1].split()[12]) + float(
-                        data[i + 2].split()[12]
-                    )  # sum CM left/right
-                    break
-        # Open .polar file and extract data
-        with open(output_file_list[1], "r") as lf:
-            data = lf.readlines()
-            htp_e = float(data[1].split()[10])
-        # Delete temporary directory
-        if not (self.options["openvsp_exe_path"]):
-            # noinspection PyUnboundLocalVariable
-            tmp_directory.cleanup()
-        # Return values
-        htp = {
-            "y_vector": htp_y_vect,
-            "cl_vector": htp_cl_vect,
-            "cd_vector": htp_cd_vect,
-            "cm_vector": htp_cm_vect,
-            "cl": cl_htp,
-            "cdi": cdi_htp,
-            "cm": cm_htp,
-            "coeff_e": htp_e,
-        }
-        return htp
-
-    def compute_aircraft(self, inputs, outputs, altitude, mach, aoa_angle):
-        """
-        Function that computes in OpenVSP environment the complete aircraft (considering wing and
-        horizontal tail plan) and returns the different aerodynamic parameters. The downwash is
-        done by OpenVSP considering far field.
-
-        @param inputs: inputs parameters defined within FAST-OAD-GA
-        @param outputs: outputs parameters defined within FAST-OAD-GA
-        @param altitude: altitude for aerodynamic calculation in meters
-        @param mach: air speed expressed in mach
-        @param aoa_angle: air speed angle of attack with respect to aircraft
-        @return: wing/htp and aircraft dictionaries including their respective aerodynamic
-        coefficients
-        """
-
-        # STEP 1/XX - DEFINE OR CALCULATE INPUT DATA FOR AERODYNAMIC EVALUATION ####################
-        ############################################################################################
+        reynolds_htp = v_inf * l0_htp / atm.kinematic_viscosity
 
-        # Get inputs (and calculate missing ones)
-        s_ref_wing = float(inputs["data:geometry:wing:area"])
-        x0_wing = inputs["data:geometry:wing:MAC:leading_edge:x:local"]
-        l0_wing = inputs["data:geometry:wing:MAC:length"]
-        width_max = inputs["data:geometry:fuselage:maximum_width"]
-        y1_wing = width_max / 2.0
-        y2_wing = inputs["data:geometry:wing:root:y"]
-        l2_wing = inputs["data:geometry:wing:root:chord"]
-        y4_wing = inputs["data:geometry:wing:tip:y"]
-        l4_wing = inputs["data:geometry:wing:tip:chord"]
-        sweep_0_wing = inputs["data:geometry:wing:sweep_0"]
-        dihedral_angle = inputs["data:geometry:wing:dihedral"]
-        twist = inputs["data:geometry:wing:twist"]
-        fa_length = inputs["data:geometry:wing:MAC:at25percent:x"]
-        span_wing = inputs["data:geometry:wing:span"]
-        height_max = inputs["data:geometry:fuselage:maximum_height"]
-        sweep_25_htp = inputs["data:geometry:horizontal_tail:sweep_25"]
-        span_htp = inputs["data:geometry:horizontal_tail:span"] / 2.0
-        root_chord_htp = inputs["data:geometry:horizontal_tail:root:chord"]
-        tip_chord_htp = inputs["data:geometry:horizontal_tail:tip:chord"]
-        lp_htp = inputs["data:geometry:horizontal_tail:MAC:at25percent:x:from_wingMAC25"]
-        l0_htp = inputs["data:geometry:horizontal_tail:MAC:length"]
-        x0_htp = inputs["data:geometry:horizontal_tail:MAC:at25percent:x:local"]
-        height_htp = inputs["data:geometry:horizontal_tail:z:from_wingMAC25"]
-        # Compute remaining inputs
-        atm = Atmosphere(altitude, altitude_in_feet=False)
-        x_wing = fa_length - x0_wing - 0.25 * l0_wing
-        # In the rest of the code the convention for z_wing is positive when wing below the
-        # fuselage centerline, for OpenVSP it seems to be the other way around, hence the - sign
-        z_wing = -inputs["data:geometry:wing:root:z"]
-        span2_wing = y4_wing - y2_wing
+        # A/C
         distance_htp = fa_length + lp_htp - 0.25 * l0_htp - x0_htp
-        rho = atm.density
-        v_inf = max(atm.speed_of_sound * mach, 0.01)  # avoid V=0 m/s crashes
-        reynolds = v_inf * l0_wing / atm.kinematic_viscosity
 
         # STEP 2/XX - DEFINE WORK DIRECTORY, COPY RESOURCES AND CREATE COMMAND BATCH ###############
         ############################################################################################
@@ -898,12 +358,27 @@ def compute_aircraft(self, inputs, outputs, altitude, mach, aoa_angle):
         else:
             tmp_directory = _create_tmp_directory()
             target_directory = tmp_directory.name
-        # Define the list of necessary input files: geometry script and foil file for both wing/HTP
-        input_file_list = [
-            pth.join(target_directory, INPUT_AIRCRAFT_SCRIPT),
-            pth.join(target_directory, self.options["wing_airfoil_file"]),
-            pth.join(target_directory, self.options["htp_airfoil_file"]),
-        ]
+
+        # Define the list of necessary input files: geometry script and foil file for wing, HTP,
+        # and aircraft
+        if comp_opt == "wing":
+            input_file_list = [
+                pth.join(target_directory, INPUT_WING_SCRIPT),
+                pth.join(target_directory, self.options["wing_airfoil_file"]),
+            ]
+        elif comp_opt == "htp":
+            input_file_list = [
+                pth.join(target_directory, INPUT_HTP_SCRIPT),
+                pth.join(target_directory, self.options["htp_airfoil_file"]),
+            ]
+        else:
+            # When in doubt we compute everything
+            input_file_list = [
+                pth.join(target_directory, INPUT_AIRCRAFT_SCRIPT),
+                pth.join(target_directory, self.options["wing_airfoil_file"]),
+                pth.join(target_directory, self.options["htp_airfoil_file"]),
+            ]
+
         self.options["external_input_files"] = input_file_list
         # Define standard error file by default to avoid error code return
         self.stderr = pth.join(target_directory, STDERR_FILE_NAME)
@@ -911,111 +386,218 @@ def compute_aircraft(self, inputs, outputs, altitude, mach, aoa_angle):
         # noinspection PyTypeChecker
         copy_resource_folder(openvsp3201, target_directory)
         if self.options["airfoil_folder_path"] is None:
-            # noinspection PyTypeChecker
-            copy_resource(airfoil_folder, self.options["wing_airfoil_file"], target_directory)
-            # noinspection PyTypeChecker
-            copy_resource(airfoil_folder, self.options["htp_airfoil_file"], target_directory)
+            if comp_opt == "wing":
+                copy_resource(airfoil_folder, self.options["wing_airfoil_file"], target_directory)
+            elif comp_opt == "htp":
+                copy_resource(airfoil_folder, self.options["htp_airfoil_file"], target_directory)
+            elif comp_opt == "ac":
+                copy_resource(airfoil_folder, self.options["wing_airfoil_file"], target_directory)
+                copy_resource(airfoil_folder, self.options["htp_airfoil_file"], target_directory)
         else:
-            # noinspection PyTypeChecker
-            copy_resource_from_path(
-                self.options["airfoil_folder_path"],
-                self.options["wing_airfoil_file"],
-                target_directory,
-            )
-            # noinspection PyTypeChecker
-            copy_resource_from_path(
-                self.options["airfoil_folder_path"],
-                self.options["htp_airfoil_file"],
-                target_directory,
-            )
+            if comp_opt == "wing":
+                copy_resource_from_path(
+                    self.options["airfoil_folder_path"],
+                    self.options["wing_airfoil_file"],
+                    target_directory,
+                )
+            elif comp_opt == "htp":
+                copy_resource_from_path(
+                    self.options["airfoil_folder_path"],
+                    self.options["htp_airfoil_file"],
+                    target_directory,
+                )
+            elif comp_opt == "ac":
+                copy_resource_from_path(
+                    self.options["airfoil_folder_path"],
+                    self.options["wing_airfoil_file"],
+                    target_directory,
+                )
+                copy_resource_from_path(
+                    self.options["airfoil_folder_path"],
+                    self.options["htp_airfoil_file"],
+                    target_directory,
+                )
+
         # Create corresponding .bat files (one for each geometry configuration)
         self.options["command"] = [pth.join(target_directory, "vspscript.bat")]
         batch_file = open(self.options["command"][0], "w+")
         batch_file.write("@echo off\n")
-        command = (
-            pth.join(target_directory, VSPSCRIPT_EXE_NAME)
-            + " -script "
-            + pth.join(target_directory, INPUT_AIRCRAFT_SCRIPT)
-            + " >nul 2>nul\n"
-        )
+
+        if comp_opt == "wing":
+            command = (
+                pth.join(target_directory, VSPSCRIPT_EXE_NAME)
+                + " -script "
+                + pth.join(target_directory, INPUT_WING_SCRIPT)
+                + " >nul 2>nul\n"
+            )
+        elif comp_opt == "htp":
+            command = (
+                pth.join(target_directory, VSPSCRIPT_EXE_NAME)
+                + " -script "
+                + pth.join(target_directory, INPUT_HTP_SCRIPT)
+                + " >nul 2>nul\n"
+            )
+        else:
+            # When in doubt we compute everything
+            command = (
+                pth.join(target_directory, VSPSCRIPT_EXE_NAME)
+                + " -script "
+                + pth.join(target_directory, INPUT_AIRCRAFT_SCRIPT)
+                + " >nul 2>nul\n"
+            )
+
         batch_file.write(command)
         batch_file.close()
 
         # STEP 3/XX - OPEN THE TEMPLATE SCRIPT FOR GEOMETRY GENERATION, MODIFY VALUES AND SAVE TO
-        # WORKDIR ##################################################################################
-
-        output_file_list = [
-            pth.join(
-                target_directory, INPUT_AIRCRAFT_SCRIPT.replace(".vspscript", "_DegenGeom.csv")
-            )
-        ]
-        parser = InputFileGenerator()
-        with path(local_resources, INPUT_AIRCRAFT_SCRIPT) as input_template_path:
-            parser.set_template_file(str(input_template_path))
-            parser.set_generated_file(input_file_list[0])
-            # Modify wing parameters
-            parser.mark_anchor("x_wing")
-            parser.transfer_var(float(x_wing), 0, 5)
-            parser.mark_anchor("z_wing")
-            parser.transfer_var(float(z_wing), 0, 5)
-            parser.mark_anchor("y1_wing")
-            parser.transfer_var(float(y1_wing), 0, 5)
-            for i in range(3):
-                parser.mark_anchor("l2_wing")
-                parser.transfer_var(float(l2_wing), 0, 5)
-            parser.reset_anchor()
-            parser.mark_anchor("span2_wing")
-            parser.transfer_var(float(span2_wing), 0, 5)
-            parser.mark_anchor("l4_wing")
-            parser.transfer_var(float(l4_wing), 0, 5)
-            parser.mark_anchor("sweep_0_wing")
-            parser.transfer_var(float(sweep_0_wing), 0, 5)
-            parser.mark_anchor("twist")
-            parser.transfer_var(float(twist), 0, 5)
-            parser.mark_anchor("dihedral_angle")
-            parser.transfer_var(float(dihedral_angle), 0, 5)
-            parser.mark_anchor("airfoil_0_file")
-            parser.transfer_var('"' + input_file_list[-2].replace("\\", "/") + '"', 0, 3)
-            parser.mark_anchor("airfoil_1_file")
-            parser.transfer_var('"' + input_file_list[-2].replace("\\", "/") + '"', 0, 3)
-            parser.mark_anchor("airfoil_2_file")
-            parser.transfer_var('"' + input_file_list[-2].replace("\\", "/") + '"', 0, 3)
-            # Modify HTP parameters
-            parser.mark_anchor("distance_htp")
-            parser.transfer_var(float(distance_htp), 0, 5)
-            parser.mark_anchor("height_htp")
-            parser.transfer_var(float(height_htp), 0, 5)
-            parser.mark_anchor("span_htp")
-            parser.transfer_var(float(span_htp), 0, 5)
-            parser.mark_anchor("root_chord_htp")
-            parser.transfer_var(float(root_chord_htp), 0, 5)
-            parser.mark_anchor("tip_chord_htp")
-            parser.transfer_var(float(tip_chord_htp), 0, 5)
-            parser.mark_anchor("sweep_25_htp")
-            parser.transfer_var(float(sweep_25_htp), 0, 5)
-            parser.mark_anchor("airfoil_3_file")
-            parser.transfer_var('"' + input_file_list[-1].replace("\\", "/") + '"', 0, 3)
-            parser.mark_anchor("airfoil_4_file")
-            parser.transfer_var('"' + input_file_list[-1].replace("\\", "/") + '"', 0, 3)
-            parser.mark_anchor("csv_file")
-            csv_name = output_file_list[0]
-            parser.transfer_var('"' + csv_name.replace("\\", "/") + '"', 0, 3)
-            parser.generate()
+        # WORKDIR #################################################################################
+        if comp_opt == "wing":
+            output_file_list = [
+                pth.join(
+                    target_directory,
+                    INPUT_WING_SCRIPT.replace(".vspscript", "_DegenGeom.csv"),
+                )
+            ]
+            parser = InputFileGenerator()
+            with path(local_resources, INPUT_WING_SCRIPT) as input_template_path:
+                parser.set_template_file(str(input_template_path))
+                parser.set_generated_file(input_file_list[0])
+                # Modify wing parameters
+                parser.mark_anchor("x_wing")
+                parser.transfer_var(float(x_wing), 0, 5)
+                parser.mark_anchor("z_wing")
+                parser.transfer_var(float(z_wing), 0, 5)
+                parser.mark_anchor("y1_wing")
+                parser.transfer_var(float(y1_wing), 0, 5)
+                for i in range(3):
+                    parser.mark_anchor("l2_wing")
+                    parser.transfer_var(float(l2_wing), 0, 5)
+                parser.reset_anchor()
+                parser.mark_anchor("span2_wing")
+                parser.transfer_var(float(span2_wing), 0, 5)
+                parser.mark_anchor("l4_wing")
+                parser.transfer_var(float(l4_wing), 0, 5)
+                parser.mark_anchor("sweep_0_wing")
+                parser.transfer_var(float(sweep_0_wing), 0, 5)
+                parser.mark_anchor("twist")
+                parser.transfer_var(float(twist), 0, 5)
+                parser.mark_anchor("dihedral_angle")
+                parser.transfer_var(float(dihedral_angle), 0, 5)
+                parser.mark_anchor("airfoil_0_file")
+                parser.transfer_var('"' + input_file_list[1].replace("\\", "/") + '"', 0, 3)
+                parser.mark_anchor("airfoil_1_file")
+                parser.transfer_var('"' + input_file_list[1].replace("\\", "/") + '"', 0, 3)
+                parser.mark_anchor("airfoil_2_file")
+                parser.transfer_var('"' + input_file_list[1].replace("\\", "/") + '"', 0, 3)
+                parser.mark_anchor("csv_file")
+                csv_name = output_file_list[0]
+                parser.transfer_var('"' + csv_name.replace("\\", "/") + '"', 0, 3)
+                parser.generate()
+        elif comp_opt == "htp":
+            output_file_list = [
+                pth.join(
+                    target_directory,
+                    INPUT_HTP_SCRIPT.replace(".vspscript", "_DegenGeom.csv"),
+                )
+            ]
+            parser = InputFileGenerator()
+            with path(local_resources, INPUT_HTP_SCRIPT) as input_template_path:
+                parser.set_template_file(str(input_template_path))
+                parser.set_generated_file(input_file_list[0])
+                # Modify htp parameters
+                parser.mark_anchor("x_htp")
+                parser.transfer_var(float(x_htp), 0, 5)
+                parser.mark_anchor("z_htp")
+                parser.transfer_var(float(z_htp), 0, 5)
+                parser.mark_anchor("semi_span_htp")
+                parser.transfer_var(float(semi_span_htp), 0, 5)
+                parser.mark_anchor("root_chord_htp")
+                parser.transfer_var(float(root_chord_htp), 0, 5)
+                parser.mark_anchor("tip_chord_htp")
+                parser.transfer_var(float(tip_chord_htp), 0, 5)
+                parser.mark_anchor("sweep_25_htp")
+                parser.transfer_var(float(sweep_25_htp), 0, 5)
+                parser.mark_anchor("airfoil_0_file")
+                parser.transfer_var('"' + input_file_list[1].replace("\\", "/") + '"', 0, 3)
+                parser.mark_anchor("airfoil_1_file")
+                parser.transfer_var('"' + input_file_list[1].replace("\\", "/") + '"', 0, 3)
+                parser.mark_anchor("csv_file")
+                csv_name = output_file_list[0]
+                parser.transfer_var('"' + csv_name.replace("\\", "/") + '"', 0, 3)
+                parser.generate()
+        else:
+            # When in doubt we compute everything
+            output_file_list = [
+                pth.join(
+                    target_directory,
+                    INPUT_AIRCRAFT_SCRIPT.replace(".vspscript", "_DegenGeom.csv"),
+                )
+            ]
+            parser = InputFileGenerator()
+            with path(local_resources, INPUT_AIRCRAFT_SCRIPT) as input_template_path:
+                parser.set_template_file(str(input_template_path))
+                parser.set_generated_file(input_file_list[0])
+                # Modify wing parameters
+                parser.mark_anchor("x_wing")
+                parser.transfer_var(float(x_wing), 0, 5)
+                parser.mark_anchor("z_wing")
+                parser.transfer_var(float(z_wing), 0, 5)
+                parser.mark_anchor("y1_wing")
+                parser.transfer_var(float(y1_wing), 0, 5)
+                for i in range(3):
+                    parser.mark_anchor("l2_wing")
+                    parser.transfer_var(float(l2_wing), 0, 5)
+                parser.reset_anchor()
+                parser.mark_anchor("span2_wing")
+                parser.transfer_var(float(span2_wing), 0, 5)
+                parser.mark_anchor("l4_wing")
+                parser.transfer_var(float(l4_wing), 0, 5)
+                parser.mark_anchor("sweep_0_wing")
+                parser.transfer_var(float(sweep_0_wing), 0, 5)
+                parser.mark_anchor("twist")
+                parser.transfer_var(float(twist), 0, 5)
+                parser.mark_anchor("dihedral_angle")
+                parser.transfer_var(float(dihedral_angle), 0, 5)
+                parser.mark_anchor("airfoil_0_file")
+                parser.transfer_var('"' + input_file_list[-2].replace("\\", "/") + '"', 0, 3)
+                parser.mark_anchor("airfoil_1_file")
+                parser.transfer_var('"' + input_file_list[-2].replace("\\", "/") + '"', 0, 3)
+                parser.mark_anchor("airfoil_2_file")
+                parser.transfer_var('"' + input_file_list[-2].replace("\\", "/") + '"', 0, 3)
+                # Modify HTP parameters
+                parser.mark_anchor("distance_htp")
+                parser.transfer_var(float(distance_htp), 0, 5)
+                parser.mark_anchor("height_htp")
+                parser.transfer_var(float(height_htp), 0, 5)
+                parser.mark_anchor("span_htp")
+                parser.transfer_var(float(span_htp), 0, 5)
+                parser.mark_anchor("root_chord_htp")
+                parser.transfer_var(float(root_chord_htp), 0, 5)
+                parser.mark_anchor("tip_chord_htp")
+                parser.transfer_var(float(tip_chord_htp), 0, 5)
+                parser.mark_anchor("sweep_25_htp")
+                parser.transfer_var(float(sweep_25_htp), 0, 5)
+                parser.mark_anchor("airfoil_3_file")
+                parser.transfer_var('"' + input_file_list[-1].replace("\\", "/") + '"', 0, 3)
+                parser.mark_anchor("airfoil_4_file")
+                parser.transfer_var('"' + input_file_list[-1].replace("\\", "/") + '"', 0, 3)
+                parser.mark_anchor("csv_file")
+                csv_name = output_file_list[0]
+                parser.transfer_var('"' + csv_name.replace("\\", "/") + '"', 0, 3)
+                parser.generate()
 
         # STEP 4/XX - RUN BATCH TO GENERATE GEOMETRY .CSV FILE #####################################
         ############################################################################################
-
         self.options["external_output_files"] = output_file_list
         super().compute(inputs, outputs)
 
         # STEP 5/XX - DEFINE NEW INPUT/OUTPUT FILES LIST AND CREATE BATCH FOR VLM COMPUTATION ######
         ############################################################################################
-
         input_file_list = output_file_list
-        input_file_list.append(input_file_list[0].replace("csv", "vspaero"))
+        input_file_list.append(input_file_list[0].replace(".csv", ".vspaero"))
         output_file_list = [
-            input_file_list[0].replace("csv", "lod"),
-            input_file_list[0].replace("csv", "polar"),
+            input_file_list[0].replace(".csv", ".lod"),
+            input_file_list[0].replace(".csv", ".polar"),
         ]
         self.options["external_input_files"] = input_file_list
         self.options["external_output_files"] = output_file_list
@@ -1033,21 +615,35 @@ def compute_aircraft(self, inputs, outputs, altitude, mach, aoa_angle):
 
         # STEP 6/XX - OPEN THE TEMPLATE VSPAERO FOR COMPUTATION, MODIFY VALUES AND SAVE TO WORKDIR #
         ############################################################################################
-
         parser = InputFileGenerator()
         template_file = pth.split(input_file_list[1])[1]
         with path(local_resources, template_file) as input_template_path:
             parser.set_template_file(str(input_template_path))
             parser.set_generated_file(input_file_list[1])
             parser.reset_anchor()
-            parser.mark_anchor("Sref")
-            parser.transfer_var(float(s_ref_wing), 0, 3)
-            parser.mark_anchor("Cref")
-            parser.transfer_var(float(l0_wing), 0, 3)
-            parser.mark_anchor("Bref")
-            parser.transfer_var(float(span_wing), 0, 3)
-            parser.mark_anchor("X_cg")
-            parser.transfer_var(float(fa_length), 0, 3)
+
+            if comp_opt == "htp":
+                parser.mark_anchor("Sref")
+                parser.transfer_var(float(s_ref_htp), 0, 3)
+                parser.mark_anchor("Cref")
+                parser.transfer_var(float(l0_htp), 0, 3)
+                parser.mark_anchor("Bref")
+                parser.transfer_var(float(2.0 * semi_span_htp), 0, 3)
+                parser.mark_anchor("X_cg")
+                parser.transfer_var(float(fa_length + lp_htp), 0, 3)
+                reynolds = reynolds_htp
+            else:
+                # For wing and AC evaluation, same reference length and area
+                parser.mark_anchor("Sref")
+                parser.transfer_var(float(s_ref_wing), 0, 3)
+                parser.mark_anchor("Cref")
+                parser.transfer_var(float(l0_wing), 0, 3)
+                parser.mark_anchor("Bref")
+                parser.transfer_var(float(span_wing), 0, 3)
+                parser.mark_anchor("X_cg")
+                parser.transfer_var(float(fa_length), 0, 3)
+                reynolds = reynolds_wing
+
             parser.mark_anchor("Mach")
             parser.transfer_var(float(mach), 0, 3)
             parser.mark_anchor("AOA")
@@ -1062,97 +658,197 @@ def compute_aircraft(self, inputs, outputs, altitude, mach, aoa_angle):
 
         # STEP 7/XX - RUN BATCH TO GENERATE AERO OUTPUT FILES (.lod, .polar...) ####################
         ############################################################################################
-
         super().compute(inputs, outputs)
 
         # STEP 8/XX - READ FILES, RETURN RESULTS (AND CLEAR TEMPORARY WORKDIR) #####################
         ############################################################################################
-
-        # Open .lod file and extract data
-        wing_y_vect = []
-        wing_cl_vect = []
-        wing_cd_vect = []
-        wing_cm_vect = []
-        htp_y_vect = []
-        htp_cl_vect = []
-        htp_cd_vect = []
-        htp_cm_vect = []
-        with open(output_file_list[0], "r") as lf:
-            data = lf.readlines()
-            for i in range(len(data)):
-                line = data[i].split()
-                line.append("**")
-                if line[0] == "1":
-                    wing_y_vect.append(float(line[2]))
-                    wing_cl_vect.append(float(line[5]))
-                    wing_cd_vect.append(float(line[6]))
-                    wing_cm_vect.append(float(line[12]))
-                elif line[0] == "3":
-                    htp_y_vect.append(float(line[2]))
-                    htp_cl_vect.append(float(line[5]))
-                    htp_cd_vect.append(float(line[6]))
-                    htp_cm_vect.append(float(line[12]))
-                if line[0] == "Comp":
-                    cl_wing = float(data[i + 1].split()[5]) + float(
-                        data[i + 2].split()[5]
-                    )  # sum CL left/right
-                    cdi_wing = float(data[i + 1].split()[6]) + float(
-                        data[i + 2].split()[6]
-                    )  # sum CDi left/right
-                    cm_wing = float(data[i + 1].split()[12]) + float(
-                        data[i + 2].split()[12]
-                    )  # sum CM left/right
-                    cl_htp = float(data[i + 3].split()[5]) + float(
-                        data[i + 4].split()[5]
-                    )  # sum CL left/right
-                    cdi_htp = float(data[i + 3].split()[6]) + float(
-                        data[i + 4].split()[6]
-                    )  # sum CDi left/right
-                    cm_htp = float(data[i + 3].split()[12]) + float(
-                        data[i + 4].split()[12]
-                    )  # sum CM left/right
-                    break
-        # Open .polar file and extract data
-        with open(output_file_list[1], "r") as lf:
-            data = lf.readlines()
-            aircraft_cl = float(data[1].split()[4])
-            aircraft_cd0 = float(data[1].split()[5])
-            aircraft_cdi = float(data[1].split()[6])
-            aircraft_e = float(data[1].split()[10])
-        # Delete temporary directory
-        if not (self.options["openvsp_exe_path"]):
-            # noinspection PyUnboundLocalVariable
-            tmp_directory.cleanup()
-        # Return values
-        wing = {
-            "y_vector": wing_y_vect,
-            "cl_vector": wing_cl_vect,
-            "cd_vector": wing_cd_vect,
-            "cm_vector": wing_cm_vect,
-            "cl": cl_wing,
-            "cdi": cdi_wing,
-            "cm": cm_wing,
-        }
-        htp = {
-            "y_vector": htp_y_vect,
-            "cl_vector": htp_cl_vect,
-            "cd_vector": htp_cd_vect,
-            "cm_vector": htp_cm_vect,
-            "cl": cl_htp,
-            "cdi": cdi_htp,
-            "cm": cm_htp,
-        }
-        aircraft = {
-            "cl": aircraft_cl,
-            "cd0": aircraft_cd0,
-            "cdi": aircraft_cdi,
-            "coeff_e": aircraft_e,
-        }
-        return wing, htp, aircraft
+        if comp_opt == "wing":
+            # Open .lod file and extract data
+            wing_y_vect = []
+            wing_chord_vect = []
+            wing_cl_vect = []
+            wing_cd_vect = []
+            wing_cm_vect = []
+            with open(output_file_list[0], "r") as file_stream:
+                data = file_stream.readlines()
+                for i, _ in enumerate(data):
+                    line = data[i].split()
+                    line.append("**")
+                    if line[0] == "1":
+                        wing_y_vect.append(float(line[2]))
+                        wing_chord_vect.append(float(line[3]))
+                        wing_cl_vect.append(float(line[5]))
+                        wing_cd_vect.append(float(line[6]))
+                        wing_cm_vect.append(float(line[12]))
+                    if line[0] == "Comp":
+                        cl_wing = float(data[i + 1].split()[5]) + float(
+                            data[i + 2].split()[5]
+                        )  # sum CL left/right
+                        cdi_wing = float(data[i + 1].split()[6]) + float(
+                            data[i + 2].split()[6]
+                        )  # sum CDi left/right
+                        cm_wing = float(data[i + 1].split()[12]) + float(
+                            data[i + 2].split()[12]
+                        )  # sum CM left/right
+                        break
+            # Open .polar file and extract data
+            with open(output_file_list[1], "r") as file_stream:
+                data = file_stream.readlines()
+                wing_e = float(data[1].split()[10])
+            # Delete temporary directory
+            if not self.options["openvsp_exe_path"]:
+                # noinspection PyUnboundLocalVariable
+                tmp_directory.cleanup()
+            # Return values
+            wing = {
+                "y_vector": wing_y_vect,
+                "cl_vector": wing_cl_vect,
+                "chord_vector": wing_chord_vect,
+                "cd_vector": wing_cd_vect,
+                "cm_vector": wing_cm_vect,
+                "cl": cl_wing,
+                "cdi": cdi_wing,
+                "cm": cm_wing,
+                "coeff_e": wing_e,
+            }
+            output_result = wing
+        elif comp_opt == "htp":
+            # Open .lod file and extract data
+            htp_y_vect = []
+            htp_cl_vect = []
+            htp_cd_vect = []
+            htp_cm_vect = []
+            with open(output_file_list[0], "r") as lf:
+                data = lf.readlines()
+                for i, _ in enumerate(data):
+                    line = data[i].split()
+                    line.append("**")
+                    if line[0] == "1":
+                        htp_y_vect.append(float(line[2]))
+                        htp_cl_vect.append(float(line[5]))
+                        htp_cd_vect.append(float(line[6]))
+                        htp_cm_vect.append(float(line[12]))
+                    if line[0] == "Comp":
+                        cl_htp = float(data[i + 1].split()[5]) + float(
+                            data[i + 2].split()[5]
+                        )  # sum CL left/right
+                        cdi_htp = float(data[i + 1].split()[6]) + float(
+                            data[i + 2].split()[6]
+                        )  # sum CDi left/right
+                        cm_htp = float(data[i + 1].split()[12]) + float(
+                            data[i + 2].split()[12]
+                        )  # sum CM left/right
+                        break
+            # Open .polar file and extract data
+            with open(output_file_list[1], "r") as lf:
+                data = lf.readlines()
+                htp_e = float(data[1].split()[10])
+            # Delete temporary directory
+            if not self.options["openvsp_exe_path"]:
+                # noinspection PyUnboundLocalVariable
+                tmp_directory.cleanup()
+            # Return values
+            htp = {
+                "y_vector": htp_y_vect,
+                "cl_vector": htp_cl_vect,
+                "cd_vector": htp_cd_vect,
+                "cm_vector": htp_cm_vect,
+                "cl": cl_htp,
+                "cdi": cdi_htp,
+                "cm": cm_htp,
+                "coeff_e": htp_e,
+            }
+            output_result = htp
+        elif comp_opt == "ac":
+            # Open .lod file and extract data
+            wing_y_vect = []
+            wing_cl_vect = []
+            wing_cd_vect = []
+            wing_cm_vect = []
+            htp_y_vect = []
+            htp_cl_vect = []
+            htp_cd_vect = []
+            htp_cm_vect = []
+            with open(output_file_list[0], "r") as lf:
+                data = lf.readlines()
+                for i in range(len(data)):
+                    line = data[i].split()
+                    line.append("**")
+                    if line[0] == "1":
+                        wing_y_vect.append(float(line[2]))
+                        wing_cl_vect.append(float(line[5]))
+                        wing_cd_vect.append(float(line[6]))
+                        wing_cm_vect.append(float(line[12]))
+                    elif line[0] == "3":
+                        htp_y_vect.append(float(line[2]))
+                        htp_cl_vect.append(float(line[5]))
+                        htp_cd_vect.append(float(line[6]))
+                        htp_cm_vect.append(float(line[12]))
+                    if line[0] == "Comp":
+                        cl_wing = float(data[i + 1].split()[5]) + float(
+                            data[i + 2].split()[5]
+                        )  # sum CL left/right
+                        cdi_wing = float(data[i + 1].split()[6]) + float(
+                            data[i + 2].split()[6]
+                        )  # sum CDi left/right
+                        cm_wing = float(data[i + 1].split()[12]) + float(
+                            data[i + 2].split()[12]
+                        )  # sum CM left/right
+                        cl_htp = float(data[i + 3].split()[5]) + float(
+                            data[i + 4].split()[5]
+                        )  # sum CL left/right
+                        cdi_htp = float(data[i + 3].split()[6]) + float(
+                            data[i + 4].split()[6]
+                        )  # sum CDi left/right
+                        cm_htp = float(data[i + 3].split()[12]) + float(
+                            data[i + 4].split()[12]
+                        )  # sum CM left/right
+                        break
+            # Open .polar file and extract data
+            with open(output_file_list[1], "r") as lf:
+                data = lf.readlines()
+                aircraft_cl = float(data[1].split()[4])
+                aircraft_cd0 = float(data[1].split()[5])
+                aircraft_cdi = float(data[1].split()[6])
+                aircraft_e = float(data[1].split()[10])
+            # Delete temporary directory
+            if not (self.options["openvsp_exe_path"]):
+                # noinspection PyUnboundLocalVariable
+                tmp_directory.cleanup()
+            # Return values
+            wing = {
+                "y_vector": wing_y_vect,
+                "cl_vector": wing_cl_vect,
+                "cd_vector": wing_cd_vect,
+                "cm_vector": wing_cm_vect,
+                "cl": cl_wing,
+                "cdi": cdi_wing,
+                "cm": cm_wing,
+            }
+            htp = {
+                "y_vector": htp_y_vect,
+                "cl_vector": htp_cl_vect,
+                "cd_vector": htp_cd_vect,
+                "cm_vector": htp_cm_vect,
+                "cl": cl_htp,
+                "cdi": cdi_htp,
+                "cm": cm_htp,
+            }
+            aircraft = {
+                "cl": aircraft_cl,
+                "cd0": aircraft_cd0,
+                "cdi": aircraft_cdi,
+                "coeff_e": aircraft_e,
+            }
+            output_result = wing, htp, aircraft
+
+        return output_result
 
     @staticmethod
     def search_results(result_folder_path, geometry_set):
         """Search the results folder to see if the geometry has already been calculated."""
+        result_file_path = None
+        saved_area_ratio = 1.0
         if os.path.exists(result_folder_path):
             geometry_set_labels = [
                 "sweep25_wing",
@@ -1184,14 +880,16 @@ def search_results(result_folder_path, geometry_set):
                                 == len(geometry_set_labels) - 1
                             ):
                                 saved_set = np.around(
-                                    data.loc[geometry_set_labels[0:-1], 0].to_numpy(), decimals=6
+                                    data.loc[geometry_set_labels[0:-1], 0].to_numpy(),
+                                    decimals=6,
                                 )
                                 if (
                                     np.sum(saved_set == geometry_set[0:-1])
                                     == len(geometry_set_labels) - 1
                                 ):
                                     result_file_path = pth.join(
-                                        result_folder_path, "openvsp_" + str(idx) + ".csv"
+                                        result_folder_path,
+                                        "openvsp_" + str(idx) + ".csv",
                                     )
                                     saved_area_ratio = data.loc["area_ratio", 0]
                                     return result_file_path, saved_area_ratio
@@ -1199,7 +897,7 @@ def search_results(result_folder_path, geometry_set):
                             break
                     idx += 1
 
-        return None, 1.0
+        return result_file_path, saved_area_ratio
 
     @staticmethod
     def save_geometry(result_folder_path, geometry_set):
@@ -1258,8 +956,232 @@ def read_results(result_file_path):
 
         return pd.DataFrame(values, index=labels)
 
+    @staticmethod
+    def define_geometry(inputs, mach):
+        """
+        Extract geometrical parameters
+
+        :param inputs: inputs in the OpenMDAO format
+        :param mach: Mach number
+
+        :return s_ref_wing: wing reference surface area
+        :return area_ratio: rea ratio between wing and horizontal stabilizer
+        :return s_ref_wing: geometry dataset for openvsp calculation
+        """
+        s_ref_wing = float(inputs["data:geometry:wing:area"])
+        s_ref_htp = float(inputs["data:geometry:horizontal_tail:area"])
+        area_ratio = s_ref_htp / s_ref_wing
+        sweep25_wing = float(inputs["data:geometry:wing:sweep_25"])
+        taper_ratio_wing = float(inputs["data:geometry:wing:taper_ratio"])
+        aspect_ratio_wing = float(inputs["data:geometry:wing:aspect_ratio"])
+        sweep25_htp = float(inputs["data:geometry:horizontal_tail:sweep_25"])
+        aspect_ratio_htp = float(inputs["data:geometry:horizontal_tail:aspect_ratio"])
+        taper_ratio_htp = float(inputs["data:geometry:horizontal_tail:taper_ratio"])
+        dihedral_angle = float(inputs["data:geometry:wing:dihedral"])
+        twist_angle = float(inputs["data:geometry:wing:twist"])
+        geometry_set = np.around(
+            np.array(
+                [
+                    sweep25_wing,
+                    taper_ratio_wing,
+                    aspect_ratio_wing,
+                    dihedral_angle,
+                    twist_angle,
+                    sweep25_htp,
+                    taper_ratio_htp,
+                    aspect_ratio_htp,
+                    mach,
+                    area_ratio,
+                ]
+            ),
+            decimals=6,
+        )
+
+        return s_ref_wing, area_ratio, geometry_set
+
+    @staticmethod
+    def post_process_wing(inputs, wing_0, wing_aoa, s_ref_wing, aoa_angle):
+        """
+        Computes wing data not produced by OpenVSP based on available ones
+
+        :param inputs: inputs in the OpenMDAO format
+        :param wing_0: wing aerodynamic coefficient with 0 angle of attack
+        :param wing_aoa: wing aerodynamic coefficient with input angle of attack
+        :param s_ref_wing: wing reference surface area
+        :param aoa_angle: input angle of attack
+
+        :return: lift coefficient at 0 aoa, lift coefficient at input aoa, lift slope coefficient,
+        pitching moment coefficient, span vector, lift coefficient vector, chord vector,
+        lift induced drag coefficient
+        """
+        width_max = inputs["data:geometry:fuselage:maximum_width"]
+        span_wing = inputs["data:geometry:wing:span"]
+        k_fus = 1 + 0.025 * width_max / span_wing - 0.025 * (width_max / span_wing) ** 2
+        cl_0_wing = float(wing_0["cl"] * k_fus)
+        cl_x_wing = float(wing_aoa["cl"] * k_fus)
+        cm_0_wing = float(wing_0["cm"] * k_fus)
+        cl_alpha_wing = (cl_x_wing - cl_0_wing) / (aoa_angle * np.pi / 180)
+        y_vector_wing = wing_aoa["y_vector"]
+        cl_vector_wing = (np.array(wing_aoa["cl_vector"]) * k_fus).tolist()
+        chord_vector_wing = wing_aoa["chord_vector"]
+        k_fus = 1 - 2 * (width_max / span_wing) ** 2  # Fuselage correction
+        coeff_e = float(wing_aoa["coeff_e"] * k_fus)
+        coeff_k_wing = float(1.0 / (np.pi * span_wing ** 2 / s_ref_wing * coeff_e))
+
+        return (
+            cl_0_wing,
+            cl_x_wing,
+            cl_alpha_wing,
+            cm_0_wing,
+            y_vector_wing,
+            cl_vector_wing,
+            chord_vector_wing,
+            coeff_k_wing,
+        )
+
+    @staticmethod
+    def post_process_htp(htp_0, htp_aoa, htp_0_isolated, htp_aoa_isolated, aoa_angle, area_ratio):
+        """
+        Computes htp data not produced by OpenVSP based on available ones
+
+        :param htp_0: htp aerodynamic coefficient with 0 angle of attack
+        :param htp_aoa: htp aerodynamic coefficient with input angle of attack
+        :param htp_0_isolated: isolated htp aerodynamic coefficient with 0 angle of attack
+        :param htp_aoa_isolated: isolated htp aerodynamic coefficient with input angle of attack
+        :param aoa_angle: input angle of attack
+        :param area_ratio: ratio between htp reference area and wing reference area
+
+        :return: htp lift coefficient at 0 aoa, htp lift coefficient at input aoa, htp lift slope
+        coefficient, isolated htp lift slope coefficient, span vector, lift coefficient vector,
+        lift induced drag coefficient
+        """
+
+        # Post-process HTP-aircraft data -------------------------------------------------------
+        cl_0_htp = float(htp_0["cl"])
+        cl_aoa_htp = float(htp_aoa["cl"])
+        cl_alpha_htp = float((cl_aoa_htp - cl_0_htp) / (aoa_angle * np.pi / 180))
+        coeff_k_htp = float(htp_aoa["cdi"]) / cl_aoa_htp ** 2  # area ratio missing ?
+        y_vector_htp = htp_aoa["y_vector"]
+        cl_vector_htp = (np.array(htp_aoa["cl_vector"]) * area_ratio).tolist()
+
+        # Post-process HTP-isolated data -------------------------------------------------------
+        cl_alpha_htp_isolated = (
+            float(htp_aoa_isolated["cl"] - htp_0_isolated["cl"])
+            * area_ratio
+            / (aoa_angle * np.pi / 180)
+        )
+
+        return (
+            cl_0_htp,
+            cl_aoa_htp,
+            cl_alpha_htp,
+            cl_alpha_htp_isolated,
+            y_vector_htp,
+            cl_vector_htp,
+            coeff_k_htp,
+        )
+
+    @staticmethod
+    def resize_vector(vectors):
+        """
+        Format the size of results that need to be passed as array to the size declared to
+        OpenMDAO if the original array is bigger we resize it, otherwise we complete with zeros.
+        First vector always has to be the y vector, any other vector can be a quantity expressed
+        as that vector.
+
+        :param vectors: a tuple with wing aerodynamic results
+
+        :return: length-modified aerodynamic results
+        """
+        y_vector = vectors[0]
+
+        resized_vectors = []
+
+        # shorter
+        if SPAN_MESH_POINT < len(y_vector):
+
+            y_interp = np.linspace(y_vector[0], y_vector[-1], SPAN_MESH_POINT)
+            warnings.warn("Defined maximum span mesh in fast aerodynamics\\constants.py exceeded!")
+
+            resized_vectors.append(y_interp)
+
+            for vector in vectors[1:]:
+                resized_vector = np.interp(y_interp, y_vector, vector)
+                resized_vectors.append(resized_vector)
+
+        # longer
+        else:
+            additional_zeros = list(np.zeros(SPAN_MESH_POINT - len(y_vector)))
+            y_vector = y_vector + additional_zeros
+
+            resized_vectors.append(y_vector)
+
+            for vector in vectors[1:]:
 
-class OPENVSPSimpleGeometryDP(OPENVSPSimpleGeometry):
+                resized_vector = vector + additional_zeros
+                resized_vectors.append(resized_vector)
+
+        return resized_vectors
+
+    @staticmethod
+    def assign_read_data(data, area_ratio, saved_area_ratio, s_ref_wing):
+        """
+        When results already exists, read and assign existing data and apply the new area ratio
+
+        :param data: existing results under the form of a dataframe
+        :param area_ratio: area ratio between the wing and the horizontal stabilizer
+        :param saved_area_ratio: area ratio between the wing and the horizontal stabilizer in
+        existing results
+        :param s_ref_wing: wing reference surface area
+
+        :return: aerodynamic characteristic parameters of wing and horizontal stabilizer
+        """
+        saved_area_wing = float(data.loc["saved_ref_area", 0])
+        cl_0_wing = float(data.loc["cl_0_wing", 0])
+        cl_x_wing = float(data.loc["cl_X_wing", 0])
+        cl_alpha_wing = float(data.loc["cl_alpha_wing", 0])
+        cm_0_wing = float(data.loc["cm_0_wing", 0])
+        y_vector_wing = string_to_array(data.loc["y_vector_wing", 0][1:-2]) * np.sqrt(
+            s_ref_wing / saved_area_wing
+        )
+        cl_vector_wing = string_to_array(data.loc["cl_vector_wing", 0][1:-2])
+        chord_vector_wing = string_to_array(data.loc["chord_vector_wing", 0][1:-2]) * np.sqrt(
+            s_ref_wing / saved_area_wing
+        )
+        coeff_k_wing = float(data.loc["coeff_k_wing", 0])
+        cl_0_htp = float(data.loc["cl_0_htp", 0]) * (area_ratio / saved_area_ratio)
+        cl_aoa_htp = float(data.loc["cl_X_htp", 0]) * (area_ratio / saved_area_ratio)
+        cl_alpha_htp = float(data.loc["cl_alpha_htp", 0]) * (area_ratio / saved_area_ratio)
+        cl_alpha_htp_isolated = float(data.loc["cl_alpha_htp_isolated", 0]) * (
+            area_ratio / saved_area_ratio
+        )
+        y_vector_htp = string_to_array(data.loc["y_vector_htp", 0][1:-2])
+        cl_vector_htp = string_to_array(data.loc["cl_vector_htp", 0][1:-2]) * (
+            area_ratio / saved_area_ratio
+        )
+        coeff_k_htp = float(data.loc["coeff_k_htp", 0]) * (area_ratio / saved_area_ratio)
+
+        return (
+            cl_0_wing,
+            cl_x_wing,
+            cl_alpha_wing,
+            cm_0_wing,
+            y_vector_wing,
+            cl_vector_wing,
+            chord_vector_wing,
+            coeff_k_wing,
+            cl_0_htp,
+            cl_aoa_htp,
+            cl_alpha_htp,
+            cl_alpha_htp_isolated,
+            y_vector_htp,
+            cl_vector_htp,
+            coeff_k_htp,
+            s_ref_wing,
+        )
+
+
+class OpenVSPSimpleGeometryDP(OpenVSPSimpleGeometry):
     """Execution of OpenVSP for surfaces with slipstream effects."""
 
     def __init__(self, **kwargs):
@@ -1322,7 +1244,6 @@ def compute_wing_rotor(self, inputs, outputs, altitude, mach, aoa_angle, thrust,
         twist = inputs["data:geometry:wing:twist"]
         fa_length = inputs["data:geometry:wing:MAC:at25percent:x"]
         span_wing = inputs["data:geometry:wing:span"]
-        height_max = inputs["data:geometry:fuselage:maximum_height"]
         engine_rpm = inputs["data:propulsion:max_rpm"]
         propeller_diameter = float(inputs["data:geometry:propeller:diameter"])
         nac_length = inputs["data:geometry:propulsion:nacelle:length"]
diff --git a/src/fastga/models/aerodynamics/external/propeller_code/compute_propeller_aero.py b/src/fastga/models/aerodynamics/external/propeller_code/compute_propeller_aero.py
index 7eca16d3..77d61b04 100644
--- a/src/fastga/models/aerodynamics/external/propeller_code/compute_propeller_aero.py
+++ b/src/fastga/models/aerodynamics/external/propeller_code/compute_propeller_aero.py
@@ -49,6 +49,13 @@ def initialize(self):
             types=list,
         )
         self.options.declare("elements_number", default=20, types=int)
+        self.options.declare(
+            "pitch_step_size",
+            default=1.0,
+            types=float,
+            desc="Fineness between two blade pitch for the construction of the propeller efficiency"
+            "map, in deg",
+        )
 
     def setup(self):
         ivc = om.IndepVarComp()
@@ -80,6 +87,7 @@ def setup(self):
                 sections_profile_position_list=self.options["sections_profile_position_list"],
                 sections_profile_name_list=self.options["sections_profile_name_list"],
                 elements_number=self.options["elements_number"],
+                pitch_step_size=self.options["pitch_step_size"],
             ),
             promotes_inputs=["data:*"],
             promotes_outputs=["*"],
@@ -100,6 +108,18 @@ def setup(self):
 
 
 class _ComputePropellerPerformance(PropellerCoreModule):
+    def initialize(self):
+
+        super().initialize()
+
+        self.options.declare(
+            "pitch_step_size",
+            default=1.0,
+            types=float,
+            desc="Fineness between two blade pitch for the construction of the propeller efficiency"
+            "map, in deg",
+        )
+
     def setup(self):
 
         super().setup()
@@ -231,7 +251,12 @@ def construct_table(self, inputs, speed_interp, altitude, omega):
 
         for v_inf in speed_interp:
             self.compute_extreme_pitch(inputs, v_inf)
-            theta_interp = np.linspace(self.theta_min, self.theta_max, 100)
+            # Compute performances for evenly space theta every degree
+            pitch_step_size = self.options["pitch_step_size"]
+            theta_interp = np.append(
+                np.arange(self.theta_min, self.theta_max, pitch_step_size),
+                np.array([self.theta_max]),
+            )
             local_thrust_vect = []
             local_theta_vect = []
             local_eta_vect = []
diff --git a/src/fastga/models/aerodynamics/external/propeller_code/propeller_core.py b/src/fastga/models/aerodynamics/external/propeller_code/propeller_core.py
index a4a79081..62d88b8e 100644
--- a/src/fastga/models/aerodynamics/external/propeller_code/propeller_core.py
+++ b/src/fastga/models/aerodynamics/external/propeller_code/propeller_core.py
@@ -42,6 +42,10 @@ def __init__(self, **kwargs):
         self.theta_min = 0.0
         self.theta_max = 0.0
 
+        # Store values for induced velocities
+        self.vi_vect = None
+        self.vt_vect = None
+
     def initialize(self):
         self.options.declare("sections_profile_position_list", types=list)
         self.options.declare("sections_profile_name_list", types=list)
@@ -103,7 +107,16 @@ def compute_extreme_pitch(self, inputs, v_inf):
         self.theta_max = phi_75 + 25.0
 
     def compute_pitch_performance(
-        self, inputs, theta_75, v_inf, altitude, omega, radius, alpha_list, cl_list, cd_list
+        self,
+        inputs,
+        theta_75,
+        v_inf,
+        altitude,
+        omega,
+        radius,
+        alpha_list,
+        cl_list,
+        cd_list,
     ):
 
         """
@@ -142,8 +155,12 @@ def compute_pitch_performance(
         theta_75_ref = np.interp(0.75, radius_ratio_vect, twist_vect)
 
         # Initialise vectors
-        vi_vect = np.zeros_like(radius)
-        vt_vect = np.zeros_like(radius)
+        if self.vi_vect is None:
+            self.vi_vect = np.zeros_like(radius)
+
+        if self.vt_vect is None:
+            self.vt_vect = np.zeros_like(radius)
+
         thrust_element_vector = np.zeros_like(radius)
         torque_element_vector = np.zeros_like(radius)
         alpha_vect = np.zeros_like(radius)
@@ -182,8 +199,8 @@ def compute_pitch_performance(
                 method="hybr",
                 options={"xtol": 1e-3},
             ).x
-            vi_vect[idx] = speed_vect[0]
-            vt_vect[idx] = speed_vect[1]
+            self.vi_vect[idx] = speed_vect[0]
+            self.vt_vect[idx] = speed_vect[1]
             results = self.bem_theory(
                 speed_vect,
                 radius[idx],
diff --git a/src/fastga/models/aerodynamics/external/vlm/__init__.py b/src/fastga/models/aerodynamics/external/vlm/__init__.py
index 3ff957e4..95633cae 100644
--- a/src/fastga/models/aerodynamics/external/vlm/__init__.py
+++ b/src/fastga/models/aerodynamics/external/vlm/__init__.py
@@ -11,4 +11,4 @@
 #  You should have received a copy of the GNU General Public License
 #  along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
-from .compute_aero import ComputeAEROvlm
+from .compute_aero import ComputeAeroVLM
diff --git a/src/fastga/models/aerodynamics/external/vlm/compute_aero.py b/src/fastga/models/aerodynamics/external/vlm/compute_aero.py
index b96afc5d..27a63feb 100644
--- a/src/fastga/models/aerodynamics/external/vlm/compute_aero.py
+++ b/src/fastga/models/aerodynamics/external/vlm/compute_aero.py
@@ -23,16 +23,15 @@
 from .vlm import VLMSimpleGeometry
 from ..xfoil.xfoil_polar import XfoilPolar
 from ...components.compute_reynolds import ComputeUnitReynolds
-from ...constants import SPAN_MESH_POINT, MACH_NB_PTS
+from ...constants import SPAN_MESH_POINT, MACH_NB_PTS, DEFAULT_INPUT_AOA
 
 _LOGGER = logging.getLogger(__name__)
 
 DEFAULT_WING_AIRFOIL = "naca23012.af"
 DEFAULT_HTP_AIRFOIL = "naca0012.af"
-INPUT_AOA = 10.0  # only one value given since calculation is done by default around 0.0!
 
 
-class ComputeAEROvlm(Group):
+class ComputeAeroVLM(Group):
     def initialize(self):
         self.options.declare("low_speed_aero", default=False, types=bool)
         self.options.declare("result_folder_path", default="", types=str)
@@ -44,6 +43,7 @@ def initialize(self):
         self.options.declare(
             "htp_airfoil_file", default=DEFAULT_HTP_AIRFOIL, types=str, allow_none=True
         )
+        self.options.declare("input_angle_of_attack", default=DEFAULT_INPUT_AOA, types=float)
 
     def setup(self):
         self.add_subsystem(
@@ -100,13 +100,14 @@ def setup(self):
             )
         self.add_subsystem(
             "aero_vlm",
-            _ComputeAEROvlm(
+            _ComputeAeroVLM(
                 low_speed_aero=self.options["low_speed_aero"],
                 result_folder_path=self.options["result_folder_path"],
                 compute_mach_interpolation=self.options["compute_mach_interpolation"],
                 airfoil_folder_path=self.options["airfoil_folder_path"],
                 wing_airfoil_file=self.options["wing_airfoil_file"],
                 htp_airfoil_file=self.options["htp_airfoil_file"],
+                input_angle_of_attack=self.options["input_angle_of_attack"],
             ),
             promotes=["*"],
         )
@@ -182,11 +183,12 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None):
             )
 
 
-class _ComputeAEROvlm(VLMSimpleGeometry):
+class _ComputeAeroVLM(VLMSimpleGeometry):
     def initialize(self):
         super().initialize()
         self.options.declare("result_folder_path", default="", types=str)
         self.options.declare("compute_mach_interpolation", default=False, types=bool)
+        self.options.declare("input_angle_of_attack", default=DEFAULT_INPUT_AOA, types=float)
 
     def setup(self):
 
@@ -253,10 +255,11 @@ def setup(self):
     def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None):
 
         _LOGGER.debug("Entering aerodynamic computation")
+        input_aoa = self.options["input_angle_of_attack"]
 
         # Check AOA input is float
-        if not isinstance(INPUT_AOA, float):
-            raise TypeError("INPUT_AOA should be a float!")
+        if not isinstance(input_aoa, float):
+            raise TypeError("Option input_angle_of_attack should be a float!")
 
         if self.options["low_speed_aero"]:
             altitude = 0.0
@@ -281,14 +284,14 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None):
             y_vector_htp,
             cl_vector_htp,
             coef_k_htp,
-        ) = self.compute_aero_coeff(inputs, altitude, mach, INPUT_AOA)
+        ) = self.compute_aero_coeff(inputs, altitude, mach, input_aoa)
 
         if self.options["low_speed_aero"]:
             pass
         else:
             if self.options["compute_mach_interpolation"]:
                 mach_interp, cl_alpha_interp = self.compute_cl_alpha_mach(
-                    inputs, INPUT_AOA, altitude, mach
+                    inputs, input_aoa, altitude, mach
                 )
 
         # Defining outputs
diff --git a/src/fastga/models/aerodynamics/external/vlm/vlm.py b/src/fastga/models/aerodynamics/external/vlm/vlm.py
index cc1b40e1..03c64248 100644
--- a/src/fastga/models/aerodynamics/external/vlm/vlm.py
+++ b/src/fastga/models/aerodynamics/external/vlm/vlm.py
@@ -25,6 +25,7 @@
 from stdatm import Atmosphere
 
 from fastga.models.geometry.profiles.get_profile import get_profile
+from fastga.command.api import string_to_array
 from ...constants import SPAN_MESH_POINT, POLAR_POINT_COUNT, MACH_NB_PTS
 
 DEFAULT_NX = 19
@@ -43,11 +44,23 @@ def __init__(self, **kwargs):
         super().__init__(**kwargs)
         self.wing = None
         self.htp = None
-        self.n_x = None
+        self.n_x = None  # number of chord wise panel
         self.ny1 = None
         self.ny2 = None
         self.ny3 = None
-        self.n_y = None
+        self.n_y = None  # number of semi-span wise panel
+
+        # The computation of the aircraft aerodynamics relies on the computation of the wing
+        # based on which a downwash angle is computed and used to compute the HTP. This
+        # assumption means that the wing is undisturbed by the HTP. This means the wing alone and
+        # the wing as part of the aircraft will give the same results. We can thus spare some
+        # computation by saving the results of the wing alone and reusing it in the aircraft
+        # instead of recomputing it. A proper cache should be used but I don't see any easy way
+        # to do it right now because one of the input of the compute_ac function is th inputs in
+        # the OpenMDAO format which seems hard to compare. Instead we will save the results and
+        # clear them as soon as we are done with the aircraft computation.
+        self.saved_wing_0 = None
+        self.saved_wing_aoa = None
 
     def initialize(self):
         self.options.declare("low_speed_aero", default=False, types=bool)
@@ -162,6 +175,17 @@ def compute_aero_coeff(self, inputs, altitude, mach, aoa_angle):
         @return: cl_0_wing, cl_alpha_wing, cm_0_wing, y_vector_wing, cl_vector_wing, coef_k_wing,
         cl_0_htp, cl_X_htp, cl_alpha_htp, cl_alpha_htp_isolated, y_vector_htp, cl_vector_htp,
         coef_k_htp parameters.
+
+                ^
+              y |                Points defining the panel
+                |                are named clockwise. A(x_1,y_1), B(x_2,y_2), P(x_c,y_c)
+        P3--B---|-----P4         Reference:
+        |   |   |     |          John J. Bertin, Russell M. Cummings - Aerodynamics for Engineers
+        |   |   |     |          p.394-398
+        T1  |   +--P--T2---->
+        |   |         |     x
+        |   |         |
+        P2--A--------P1
         """
 
         # Fix mach number of digits to consider similar results
@@ -234,68 +258,81 @@ def compute_aero_coeff(self, inputs, altitude, mach, aoa_angle):
             wing_0 = self.compute_wing(
                 inputs, altitude, mach, 0.0, flaps_angle=0.0, use_airfoil=True
             )
+            self.saved_wing_0 = wing_0
             wing_aoa = self.compute_wing(
                 inputs, altitude, mach, aoa_angle, flaps_angle=0.0, use_airfoil=True
             )
+            self.saved_wing_aoa = wing_aoa
 
             # Compute complete aircraft @ 0°/X° angle of attack
             _, htp_0, _ = self.compute_aircraft(
-                inputs, altitude, mach, 0.0, flaps_angle=0.0, use_airfoil=True
+                inputs,
+                altitude,
+                mach,
+                0.0,
+                flaps_angle=0.0,
+                use_airfoil=True,
+                saved_wing_result=self.saved_wing_0,
             )
+            self.saved_wing_0 = None
             _, htp_aoa, _ = self.compute_aircraft(
-                inputs, altitude, mach, aoa_angle, flaps_angle=0.0, use_airfoil=True
+                inputs,
+                altitude,
+                mach,
+                aoa_angle,
+                flaps_angle=0.0,
+                use_airfoil=True,
+                saved_wing_result=self.saved_wing_aoa,
             )
+            self.saved_wing_aoa = None
 
             # Compute isolated HTP @ 0°/X° angle of attack
             htp_0_isolated = self.compute_htp(inputs, altitude, mach, 0.0, use_airfoil=True)
             htp_aoa_isolated = self.compute_htp(inputs, altitude, mach, aoa_angle, use_airfoil=True)
 
             # Post-process wing data ---------------------------------------------------------------
-            k_fus = 1 + 0.025 * width_max / span_wing - 0.025 * (width_max / span_wing) ** 2
-            beta = np.sqrt(1 - mach ** 2)  # Prandtl-Glauert
-            cl_0_wing = float((wing_0["cl"] * k_fus / beta) * np.cos(dihedral_angle) ** 2.0)
-            cl_x_wing = float(wing_aoa["cl"] * k_fus / beta)
-            cm_0_wing = float(wing_0["cm"] * k_fus / beta)
-            cl_alpha_wing = ((cl_x_wing - cl_0_wing) / (aoa_angle * np.pi / 180)) * np.cos(
-                dihedral_angle
-            ) ** 2.0
-
-            # The correction on the effect of dihedral angle cannot be taken into account by
-            # modifying the generation of panel since only the surfaces of the panel and their
-            # aoa impact the computation, so we will stick with this "post processing" of the
-            # dihedral
-
-            y_vector_wing = wing_aoa["y_vector"]
-            cl_vector_wing = (np.array(wing_aoa["cl_vector"]) * k_fus / beta).tolist()
-            chord_vector_wing = wing_aoa["chord_vector"]
-            cdp_foil = self._interpolate_cdp(cl_wing_airfoil, cdp_wing_airfoil, cl_x_wing)
-            if mach <= 0.4:
-                coef_e = wing_aoa["coef_e"]
-            else:
-                coef_e = wing_aoa["coef_e"] * (
-                    -0.001521 * ((mach - 0.05) / 0.3 - 1) ** 10.82 + 1
-                )  # Mach correction
-            cdi = cl_x_wing ** 2 / (np.pi * aspect_ratio_wing * coef_e) + cdp_foil
-            coef_e = wing_aoa["cl"] ** 2 / (np.pi * aspect_ratio_wing * cdi)
-            k_fus = 1 - 2 * (width_max / span_wing) ** 2  # Fuselage correction
-            coef_e = float(coef_e * k_fus)
-            coef_k_wing = float(1.0 / (np.pi * aspect_ratio_wing * coef_e))
+            (
+                beta,
+                cl_0_wing,
+                cl_x_wing,
+                cm_0_wing,
+                cl_alpha_wing,
+                y_vector_wing,
+                cl_vector_wing,
+                chord_vector_wing,
+                coef_k_wing,
+            ) = self.post_processing_wing(
+                width_max,
+                span_wing,
+                mach,
+                dihedral_angle,
+                wing_0,
+                wing_aoa,
+                aoa_angle,
+                aspect_ratio_wing,
+                cl_wing_airfoil,
+                cdp_wing_airfoil,
+            )
 
             # Post-process HTP-aircraft data -------------------------------------------------------
-            cl_0_htp = float(htp_0["cl"]) / beta * area_ratio
-            cl_aoa_htp = float(htp_aoa["cl"]) / beta * area_ratio
-            cl_alpha_htp = float((cl_aoa_htp - cl_0_htp) / (aoa_angle * np.pi / 180))
-            cdp_foil = self._interpolate_cdp(cl_htp_airfoil, cdp_htp_airfoil, htp_aoa["cl"] / beta)
-            if mach <= 0.4:
-                coef_e = htp_aoa["coef_e"]
-            else:
-                coef_e = htp_aoa["coef_e"] * (
-                    -0.001521 * ((mach - 0.05) / 0.3 - 1) ** 10.82 + 1
-                )  # Mach correction
-            cdi = (htp_aoa["cl"] / beta) ** 2 / (np.pi * aspect_ratio_htp * coef_e) + cdp_foil
-            coef_k_htp = float(cdi / cl_aoa_htp ** 2 * area_ratio)
-            y_vector_htp = htp_aoa["y_vector"]
-            cl_vector_htp = (np.array(htp_aoa["cl_vector"]) / beta * area_ratio).tolist()
+            (
+                cl_0_htp,
+                cl_aoa_htp,
+                cl_alpha_htp,
+                coef_k_htp,
+                y_vector_htp,
+                cl_vector_htp,
+            ) = self.post_processing_htp_ac(
+                beta,
+                aspect_ratio_htp,
+                area_ratio,
+                mach,
+                aoa_angle,
+                cl_htp_airfoil,
+                cdp_htp_airfoil,
+                htp_0,
+                htp_aoa,
+            )
 
             # Post-process HTP-isolated data -------------------------------------------------------
             cl_alpha_htp_isolated = (
@@ -306,30 +343,11 @@ def compute_aero_coeff(self, inputs, altitude, mach, aoa_angle):
             )
 
             # Resize vectors -----------------------------------------------------------------------
-            if SPAN_MESH_POINT < len(y_vector_wing):
-                y_interp = np.linspace(y_vector_wing[0], y_vector_wing[-1], SPAN_MESH_POINT)
-                cl_vector_wing = np.interp(y_interp, y_vector_wing, cl_vector_wing)
-                chord_vector_wing = np.interp(y_interp, y_vector_wing, chord_vector_wing)
-                y_vector_wing = y_interp
-                warnings.warn(
-                    "Defined maximum span mesh in fast aerodynamics\\constants.py exceeded!"
-                )
-            else:
-                additional_zeros = list(np.zeros(SPAN_MESH_POINT - len(y_vector_wing)))
-                y_vector_wing.extend(additional_zeros)
-                cl_vector_wing.extend(additional_zeros)
-                chord_vector_wing.extend(additional_zeros)
-            if SPAN_MESH_POINT < len(y_vector_htp):
-                y_interp = np.linspace(y_vector_htp[0], y_vector_htp[-1], SPAN_MESH_POINT)
-                cl_vector_htp = np.interp(y_interp, y_vector_htp, cl_vector_htp)
-                y_vector_htp = y_interp
-                warnings.warn(
-                    "Defined maximum span mesh in fast aerodynamics\\constants.py exceeded!"
-                )
-            else:
-                additional_zeros = list(np.zeros(SPAN_MESH_POINT - len(y_vector_htp)))
-                y_vector_htp.extend(additional_zeros)
-                cl_vector_htp.extend(additional_zeros)
+
+            y_vector_wing, cl_vector_wing, chord_vector_wing = self.resize_vector(
+                [y_vector_wing, cl_vector_wing, chord_vector_wing]
+            )
+            y_vector_htp, cl_vector_htp = self.resize_vector([y_vector_htp, cl_vector_htp])
 
             # Save results to defined path ---------------------------------------------------------
             if self.options["result_folder_path"] != "":
@@ -356,35 +374,23 @@ def compute_aero_coeff(self, inputs, altitude, mach, aoa_angle):
         # Else retrieved results are used, eventually adapted with new area ratio
         else:
             # Read values from result file ---------------------------------------------------------
-            data = self.read_results(result_file_path)
-            saved_area_wing = float(data.loc["saved_ref_area", 0])
-            cl_0_wing = float(data.loc["cl_0_wing", 0])
-            cl_x_wing = float(data.loc["cl_X_wing", 0])
-            cl_alpha_wing = float(data.loc["cl_alpha_wing", 0])
-            cm_0_wing = float(data.loc["cm_0_wing", 0])
-            y_vector_wing = np.array(
-                [float(i) for i in data.loc["y_vector_wing", 0][1:-2].split(",")]
-            ) * np.sqrt(sref_wing / saved_area_wing)
-            cl_vector_wing = np.array(
-                [float(i) for i in data.loc["cl_vector_wing", 0][1:-2].split(",")]
-            )
-            chord_vector_wing = np.array(
-                [float(i) for i in data.loc["chord_vector_wing", 0][1:-2].split(",")]
-            ) * np.sqrt(sref_wing / saved_area_wing)
-            coef_k_wing = float(data.loc["coef_k_wing", 0])
-            cl_0_htp = float(data.loc["cl_0_htp", 0]) * (area_ratio / saved_area_ratio)
-            cl_aoa_htp = float(data.loc["cl_X_htp", 0]) * (area_ratio / saved_area_ratio)
-            cl_alpha_htp = float(data.loc["cl_alpha_htp", 0]) * (area_ratio / saved_area_ratio)
-            cl_alpha_htp_isolated = float(data.loc["cl_alpha_htp_isolated", 0]) * (
-                area_ratio / saved_area_ratio
-            )
-            y_vector_htp = np.array(
-                [float(i) for i in data.loc["y_vector_htp", 0][1:-2].split(",")]
-            )
-            cl_vector_htp = np.array(
-                [float(i) for i in data.loc["cl_vector_htp", 0][1:-2].split(",")]
-            )
-            coef_k_htp = float(data.loc["coef_k_htp", 0]) * (area_ratio / saved_area_ratio)
+            (
+                cl_0_wing,
+                cl_x_wing,
+                cl_alpha_wing,
+                cm_0_wing,
+                y_vector_wing,
+                cl_vector_wing,
+                chord_vector_wing,
+                coef_k_wing,
+                cl_0_htp,
+                cl_aoa_htp,
+                cl_alpha_htp,
+                cl_alpha_htp_isolated,
+                y_vector_htp,
+                cl_vector_htp,
+                coef_k_htp,
+            ) = self.read_value_from_data(result_file_path, sref_wing, area_ratio, saved_area_ratio)
 
         return (
             cl_0_wing,
@@ -416,22 +422,22 @@ def compute_wing(
         """
         VLM computations for the wing alone.
 
-        @param inputs: inputs parameters defined within FAST-OAD-GA
-        @param altitude: altitude for aerodynamic calculation in meters
-        @param mach: air speed expressed in mach
-        @param aoa_angle: air speed angle of attack with respect to aircraft (degree)
-        @param flaps_angle: flaps angle in Deg (default=0.0: i.e. no deflection)
-        @param use_airfoil: adds the camberline coordinates of the selected airfoil (default=True)
-        @return: wing dictionary including aero parameters as keys: y_vector, cl_vector, cd_vector,
+        :param inputs: inputs parameters defined within FAST-OAD-GA
+        :param altitude: altitude for aerodynamic calculation in meters
+        :param mach: air speed expressed in mach
+        :param aoa_angle: air speed angle of attack with respect to aircraft (degree)
+        :param flaps_angle: flaps angle in Deg (default=0.0: i.e. no deflection)
+        :param use_airfoil: adds the camber line coordinates of the selected airfoil (default=True)
+        :return: wing dictionary including aero parameters as keys: y_vector, cl_vector, cd_vector,
         cm_vector, cl, cdi, cm, coef_e
         """
 
         # Generate geometries
-        self._run(inputs)
+        self._run(inputs, run_opt="wing")
 
         # Get inputs
         aspect_ratio = float(inputs["data:geometry:wing:aspect_ratio"])
-        meanchord = inputs["data:geometry:wing:MAC:length"]
+        l0_wing = inputs["data:geometry:wing:MAC:length"]
 
         y2_wing = float(inputs["data:geometry:wing:root:y"])
         semi_span = float(inputs["data:geometry:wing:span"]) / 2.0
@@ -439,13 +445,13 @@ def compute_wing(
 
         # Initialization
         x_c = self.wing["x_c"]
-        panelchord = self.wing["panel_chord"]
-        panelsurf = self.wing["panel_surf"]
+        panel_chord = self.wing["panel_chord"]
+        panel_surf = self.wing["panel_surf"]
         if use_airfoil:
             self.generate_curvature(self.wing, self.options["wing_airfoil_file"])
         self.apply_deflection(inputs, flaps_angle)
         self.generate_twist(self.wing, wing_twist, y2_wing, semi_span)
-        panelangle_vect = self.wing["panel_angle_vect"]
+        panel_angle_vect = self.wing["panel_angle_vect"]
         aic = self.wing["aic"]
         aic_inv = np.linalg.inv(aic)
         aic_wake = self.wing["aic_wake"]
@@ -456,35 +462,28 @@ def compute_wing(
         )  # avoid V=0 m/s crashes
 
         # Calculate all the aerodynamic parameters
-        aoa_angle = aoa_angle * np.pi / 180
-        alpha = np.add(panelangle_vect, aoa_angle)
+        panel_surf_sum = np.sum(panel_surf)
+        aoa_angle = np.deg2rad(aoa_angle)
+        alpha = np.add(panel_angle_vect, aoa_angle)
         gamma = -np.dot(aic_inv, alpha) * v_inf
-        c_p = -2 / v_inf * np.divide(gamma, panelchord)
-        for i in range(self.n_x):
-            c_p[i * self.n_y] = c_p[i * self.n_y] * 1
-        cl_wing = -np.sum(c_p * panelsurf) / np.sum(panelsurf)
-        alphaind = np.dot(aic_wake, gamma) / v_inf
-        cdind_panel = c_p * alphaind
-        cdi_wing = np.sum(cdind_panel * panelsurf) / np.sum(panelsurf)
-        wing_e = cl_wing ** 2 / (np.pi * aspect_ratio * cdi_wing) * 0.955  # !!!: manual correction?
-        cmpanel = np.multiply(c_p, (x_c[: self.n_x * self.n_y] - meanchord / 4))
-        cm_wing = np.sum(cmpanel * panelsurf) / np.sum(panelsurf)
-
-        # Calculate curves
+        c_p = -2 / v_inf * np.divide(gamma, panel_chord)
+        cl_wing = -np.sum(c_p * panel_surf) / panel_surf_sum
+        alpha_ind = np.dot(aic_wake, gamma) / v_inf
+        cd_ind_panel = c_p * alpha_ind
+        cdi_wing = np.sum(cd_ind_panel * panel_surf) / panel_surf_sum
+        wing_e = cl_wing ** 2 / (np.pi * aspect_ratio * cdi_wing) * 0.955
+        cm_panel = np.multiply(c_p, (x_c[: self.n_x * self.n_y] - l0_wing / 4))
+        cm_wing = np.sum(cm_panel * panel_surf) / panel_surf_sum
+
+        wing_y_vect = list(self.wing["yc"][: self.n_y])
+        wing_chord_vect = list(
+            (self.wing["chord"][: self.n_y] + self.wing["chord"][1 : self.n_y + 1]) / 2.0
+        )
+
         wing_cl_vect = []
-        wing_y_vect = []
-        wing_chord_vect = []
-        yc_wing = self.wing["yc"]
-        chord_wing = self.wing["chord"]
         for j in range(self.n_y):
-            cl_span = 0.0
-            y_local = yc_wing[j]
-            chord = (chord_wing[j] + chord_wing[j + 1]) / 2.0
-            for i in range(self.n_x):
-                cl_span += -c_p[i * self.n_y + j] * panelchord[i * self.n_y + j] / chord
+            cl_span = np.sum(-c_p[j :: self.n_y] * panel_chord[j :: self.n_y] / wing_chord_vect[j])
             wing_cl_vect.append(cl_span)
-            wing_y_vect.append(y_local)
-            wing_chord_vect.append(chord)
 
         # Return values
         wing = {
@@ -512,29 +511,29 @@ def compute_htp(
         """
         VLM computation for the horizontal tail alone.
 
-        @param inputs: inputs parameters defined within FAST-OAD-GA.
-        @param altitude: altitude for aerodynamic calculation in meters.
-        @param mach: air speed expressed in mach.
-        @param aoa_angle: air speed angle of attack with respect to aircraft (degree).
-        @param use_airfoil: adds the camberline coordinates of the selected airfoil (default=True).
-        @return: htp dictionary including aero parameters as keys: y_vector, cl_vector, cd_vector,
+        :param inputs: inputs parameters defined within FAST-OAD-GA.
+        :param altitude: altitude for aerodynamic calculation in meters.
+        :param mach: air speed expressed in mach.
+        :param aoa_angle: air speed angle of attack with respect to aircraft (degree).
+        :param use_airfoil: adds the camber line coordinates of the selected airfoil (default=True).
+        :return: htp dictionary including aero parameters as keys: y_vector, cl_vector, cd_vector,
         cm_vector, cl, cdi, cm, coef_e.
         """
 
         # Generate geometries
-        self._run(inputs)
+        self._run(inputs, run_opt="htp")
 
         # Get inputs
         aspect_ratio = float(inputs["data:geometry:horizontal_tail:aspect_ratio"])
-        meanchord = inputs["data:geometry:horizontal_tail:MAC:length"]
+        l0_wing = inputs["data:geometry:horizontal_tail:MAC:length"]
 
         # Initialization
         x_c = self.htp["x_c"]
-        panelchord = self.htp["panel_chord"]
-        panelsurf = self.htp["panel_surf"]
+        panel_chord = self.htp["panel_chord"]
+        panel_surf = self.htp["panel_surf"]
         if use_airfoil:
             self.generate_curvature(self.htp, self.options["htp_airfoil_file"])
-        panelangle_vect = self.htp["panel_angle_vect"]
+        panel_angle_vect = self.htp["panel_angle_vect"]
         aic = self.htp["aic"]
         aic_inv = np.linalg.inv(aic)
         aic_wake = self.htp["aic_wake"]
@@ -545,33 +544,28 @@ def compute_htp(
         )  # avoid V=0 m/s crashes
 
         # Calculate all the aerodynamic parameters
-        aoa_angle = aoa_angle * np.pi / 180
-        alpha = np.add(panelangle_vect, aoa_angle)
+        panel_surf_sum = np.sum(panel_surf)
+        aoa_angle = np.deg2rad(aoa_angle)
+        alpha = np.add(panel_angle_vect, aoa_angle)
         gamma = -np.dot(aic_inv, alpha) * v_inf
-        c_p = -2 / v_inf * np.divide(gamma, panelchord)
-        for i in range(self.n_x):
-            c_p[i * self.n_y] = c_p[i * self.n_y] * 1
-        cl_htp = -np.sum(c_p * panelsurf) / np.sum(panelsurf)
-        alphaind = np.dot(aic_wake, gamma) / v_inf
-        cdind_panel = c_p * alphaind
-        cdi_htp = np.sum(cdind_panel * panelsurf) / np.sum(panelsurf)
-        htp_e = cl_htp ** 2 / (np.pi * aspect_ratio * max(cdi_htp, 1e-12))  # avod 0.0 division
-        cmpanel = np.multiply(c_p, (x_c[: self.n_x * self.n_y] - meanchord / 4))
-        cm_htp = np.sum(cmpanel * panelsurf) / np.sum(panelsurf)
-
-        # Calculate curves
+        c_p = -2 / v_inf * np.divide(gamma, panel_chord)
+        cl_htp = -np.sum(c_p * panel_surf) / panel_surf_sum
+        alpha_ind = np.dot(aic_wake, gamma) / v_inf
+        cd_ind_panel = c_p * alpha_ind
+        cdi_htp = np.sum(cd_ind_panel * panel_surf) / panel_surf_sum
+        htp_e = cl_htp ** 2 / (np.pi * aspect_ratio * max(cdi_htp, 1e-12))  # avoid 0.0 division
+        cm_panel = np.multiply(c_p, (x_c[: self.n_x * self.n_y] - l0_wing / 4))
+        cm_htp = np.sum(cm_panel * panel_surf) / panel_surf_sum
+
+        htp_y_vect = list(self.htp["yc"][: self.n_y])
+        htp_chord_vect = list(
+            (self.htp["chord"][: self.n_y] + self.htp["chord"][1 : self.n_y + 1]) / 2.0
+        )
+
         htp_cl_vect = []
-        htp_y_vect = []
-        yc_htp = self.htp["yc"]
-        chord_htp = self.htp["chord"]
         for j in range(self.n_y):
-            cl_span = 0.0
-            y_local = yc_htp[j]
-            chord = (chord_htp[j] + chord_htp[j + 1]) / 2.0
-            for i in range(self.n_x):
-                cl_span += -c_p[i * self.n_y + j] * panelchord[i * self.n_y + j] / chord
+            cl_span = np.sum(-c_p[j :: self.n_y] * panel_chord[j :: self.n_y] / htp_chord_vect[j])
             htp_cl_vect.append(cl_span)
-            htp_y_vect.append(y_local)
 
         # Return values
         htp = {
@@ -595,17 +589,20 @@ def compute_aircraft(
         aoa_angle: float,
         flaps_angle: Optional[float] = 0.0,
         use_airfoil: Optional[bool] = True,
+        saved_wing_result: Optional[dict] = None,
     ):
         """
         VLM computation for the complete aircraft.
 
-        @param inputs: inputs parameters defined within FAST-OAD-GA.
-        @param altitude: altitude for aerodynamic calculation in meters.
-        @param mach: air speed expressed in mach.
-        @param aoa_angle: air speed angle of attack with respect to aircraft (degree).
-        @param use_airfoil: adds the camberline coordinates of the selected airfoil (default=True).
-        @param flaps_angle: flaps angle in Deg (default=0.0: i.e. no deflection).
-        @return: wing/htp and aircraft dictionaries including their respective aerodynamic
+        :param inputs: inputs parameters defined within FAST-OAD-GA.
+        :param altitude: altitude for aerodynamic calculation in meters.
+        :param mach: air speed expressed in mach.
+        :param aoa_angle: air speed angle of attack with respect to aircraft (degree).
+        :param use_airfoil: adds the camber line coordinates of the selected airfoil (default=True).
+        :param flaps_angle: flaps angle in Deg (default=0.0: i.e. no deflection).
+        :param saved_wing_result: if existing result are available, used them instead of
+        recomputing.
+        :return: wing/htp and aircraft dictionaries including their respective aerodynamic
         coefficients.
         """
 
@@ -613,9 +610,12 @@ def compute_aircraft(
         aspect_ratio_wing = float(inputs["data:geometry:wing:aspect_ratio"])
 
         # Compute wing
-        wing = self.compute_wing(
-            inputs, altitude, mach, aoa_angle, flaps_angle=flaps_angle, use_airfoil=use_airfoil
-        )
+        if saved_wing_result is None:
+            wing = self.compute_wing(
+                inputs, altitude, mach, aoa_angle, flaps_angle=flaps_angle, use_airfoil=use_airfoil
+            )
+        else:
+            wing = saved_wing_result
 
         # Calculate downwash angle based on Gudmundsson model (p.467)
         cl_wing = wing["cl"]
@@ -631,7 +631,7 @@ def compute_aircraft(
 
         return wing, htp, aircraft
 
-    def _run(self, inputs):
+    def _run(self, inputs, run_opt="wing"):
 
         wing_break = float(inputs["data:geometry:wing:kink:span_ratio"])
 
@@ -648,38 +648,75 @@ def _run(self, inputs):
         self.ny3 = self.ny2  # n° of panels in the un-flapped exterior portion of the wing
 
         self.n_y = int(self.ny1 + self.ny2 + self.ny3)
-        # Define elements
-        self.wing = {
-            "x_panel": np.zeros((self.n_x + 1, 2 * self.n_y + 1)),
-            "y_panel": np.zeros(2 * self.n_y + 1),
-            "z": np.zeros(self.n_x + 1),
-            "x_le": np.zeros(2 * self.n_y + 1),
-            "chord": np.zeros(2 * self.n_y + 1),
-            "panel_span": np.zeros(2 * self.n_y),
-            "panel_chord": np.zeros(self.n_x * self.n_y),
-            "panel_surf": np.zeros(self.n_x * self.n_y),
-            "x_c": np.zeros(self.n_x * 2 * self.n_y),
-            "yc": np.zeros(self.n_x * 2 * self.n_y),
-            "x1": np.zeros(self.n_x * 2 * self.n_y),
-            "x2": np.zeros(self.n_x * 2 * self.n_y),
-            "y1": np.zeros(self.n_x * 2 * self.n_y),
-            "y2": np.zeros(self.n_x * 2 * self.n_y),
-            "panel_angle": np.zeros(self.n_x),
-            "panel_angle_vect": np.zeros(self.n_x * self.n_y),
-            "aic": np.zeros((self.n_x * self.n_y, self.n_x * self.n_y)),
-            "aic_wake": np.zeros((self.n_x * self.n_y, self.n_x * self.n_y)),
-        }
-        # Duplicate for HTP
-        self.htp = copy.deepcopy(self.wing)
 
         # Generate WING
-        self._generate_wing(inputs)
+        if run_opt == "wing":
+            self.wing = {
+                "x_panel": np.zeros((self.n_x + 1, 2 * self.n_y + 1)),
+                "y_panel": np.zeros(2 * self.n_y + 1),
+                "z": np.zeros(self.n_x + 1),
+                "x_le": np.zeros(2 * self.n_y + 1),
+                "chord": np.zeros(2 * self.n_y + 1),
+                "panel_span": np.zeros(2 * self.n_y),
+                "panel_chord": np.zeros(self.n_x * self.n_y),
+                "panel_surf": np.zeros(self.n_x * self.n_y),
+                "x_c": np.zeros(self.n_x * 2 * self.n_y),
+                "yc": np.zeros(self.n_x * 2 * self.n_y),
+                "x1": np.zeros(self.n_x * 2 * self.n_y),
+                "x2": np.zeros(self.n_x * 2 * self.n_y),
+                "y1": np.zeros(self.n_x * 2 * self.n_y),
+                "y2": np.zeros(self.n_x * 2 * self.n_y),
+                "panel_angle": np.zeros(self.n_x),
+                "panel_angle_vect": np.zeros(self.n_x * self.n_y),
+                "aic": np.zeros((self.n_x * self.n_y, self.n_x * self.n_y)),
+                "aic_wake": np.zeros((self.n_x * self.n_y, self.n_x * self.n_y)),
+            }
+            self._generate_wing(inputs)
 
         # Generate HTP
-        self._generate_htp(inputs)
+        if run_opt == "htp":
+            # Define elements
+            self.htp = {
+                "x_panel": np.zeros((self.n_x + 1, 2 * self.n_y + 1)),
+                "y_panel": np.zeros(2 * self.n_y + 1),
+                "z": np.zeros(self.n_x + 1),
+                "x_le": np.zeros(2 * self.n_y + 1),
+                "chord": np.zeros(2 * self.n_y + 1),
+                "panel_span": np.zeros(2 * self.n_y),
+                "panel_chord": np.zeros(self.n_x * self.n_y),
+                "panel_surf": np.zeros(self.n_x * self.n_y),
+                "x_c": np.zeros(self.n_x * 2 * self.n_y),
+                "yc": np.zeros(self.n_x * 2 * self.n_y),
+                "x1": np.zeros(self.n_x * 2 * self.n_y),
+                "x2": np.zeros(self.n_x * 2 * self.n_y),
+                "y1": np.zeros(self.n_x * 2 * self.n_y),
+                "y2": np.zeros(self.n_x * 2 * self.n_y),
+                "panel_angle": np.zeros(self.n_x),
+                "panel_angle_vect": np.zeros(self.n_x * self.n_y),
+                "aic": np.zeros((self.n_x * self.n_y, self.n_x * self.n_y)),
+                "aic_wake": np.zeros((self.n_x * self.n_y, self.n_x * self.n_y)),
+            }
+            self._generate_htp(inputs)
 
     def _generate_wing(self, inputs):
-        """Generates the coordinates for VLM calculations and aic matrix of the wing."""
+        """
+        Generates the coordinates for VLM calculations and aic matrix of the wing.
+           Pi +......> y     Given a trapezoid defined by vertices Pi and Pf
+              | \            and chords 1 and 2 representing a wing segment
+              |  \           that complies with the VLM theory, returns the
+              |   + Pf       points and panels of the mesh:
+        chord1|   |
+              |   |             - Points are given as a list of Np elements,
+              |   |chord2         being Np the number of points of the mesh.
+              +---+
+              |                 - Panels are given as a list of list of NP
+              x 				      elements, each element composed of 4 points,
+                                  where NP is the number of panels of the mesh.
+              x - chord wise direction
+              y - span wise direction
+          x_le array identifies the x-coordinate of Pi and Pf along the span-direction
+        """
+
         y2_wing = inputs["data:geometry:wing:root:y"]
         semi_span = inputs["data:geometry:wing:span"] / 2.0
         root_chord = inputs["data:geometry:wing:root:chord"]
@@ -689,7 +726,7 @@ def _generate_wing(self, inputs):
         # Initial data (zero matrix/array)
         y_panel = self.wing["y_panel"]
         x_le = self.wing["x_le"]
-        y_endflaps = y2_wing + flap_span_ratio * (semi_span - y2_wing)
+        y_end_flaps = y2_wing + flap_span_ratio * (semi_span - y2_wing)
         # Definition of x_panel, y_panel, x_le and chord (Right side)
 
         indices = np.indices(y_panel.shape)[0].astype(float)
@@ -698,7 +735,7 @@ def _generate_wing(self, inputs):
 
         y_panel = np.where(
             indices >= self.ny1,
-            y2_wing + (y_endflaps - y2_wing) * (indices - self.ny1) / self.ny2,
+            y2_wing + (y_end_flaps - y2_wing) * (indices - self.ny1) / self.ny2,
             y_panel,
         )
         y_tapered_section = y_panel - y2_wing
@@ -715,7 +752,7 @@ def _generate_wing(self, inputs):
 
         y_panel = np.where(
             indices >= self.ny1 + self.ny2,
-            y_endflaps + (semi_span - y_endflaps) * (indices - (self.ny1 + self.ny2)) / self.ny3,
+            y_end_flaps + (semi_span - y_end_flaps) * (indices - (self.ny1 + self.ny2)) / self.ny3,
             y_panel,
         )
         y_tapered_section = y_panel - y2_wing
@@ -730,6 +767,7 @@ def _generate_wing(self, inputs):
             x_le,
         )
 
+        # Mirror the right side to define the left side for y_panel, x_le and chord
         y_panel[self.n_y + 1 :] = -y_panel[1 : self.n_y + 1]
         chord[self.n_y + 1 :] = chord[1 : self.n_y + 1]
         x_le[self.n_y + 1 :] = x_le[1 : self.n_y + 1]
@@ -741,7 +779,23 @@ def _generate_wing(self, inputs):
         self._generate_common(self.wing)
 
     def _generate_htp(self, inputs):
-        """Generates the coordinates for VLM calculations and AIC matrix of the htp."""
+        """
+        Generates the coordinates for VLM calculations and AIC matrix of the htp.
+           Pi +......> y     Given a trapezoid defined by vertices Pi and Pf
+              | \            and chords 1 and 2 representing a wing segment
+              |  \           that complies with the VLM theory, returns the
+              |   + Pf       points and panels of the mesh:
+        chord1|   |
+              |   |             - Points are given as a list of Np elements,
+              |   |chord2         being Np the number of points of the mesh.
+              +---+
+              |                 - Panels are given as a list of list of NP
+              x 				      elements, each element composed of 4 points,
+                                  where NP is the number of panels of the mesh.
+              x - chord wise direction
+              y - span wise direction
+          x_le array identifies the x-coordinate of Pi and Pf along the span-direction
+        """
         semi_span = inputs["data:geometry:horizontal_tail:span"] / 2.0
         root_chord = inputs["data:geometry:horizontal_tail:root:chord"]
         tip_chord = inputs["data:geometry:horizontal_tail:tip:chord"]
@@ -755,6 +809,7 @@ def _generate_htp(self, inputs):
         chord = root_chord + (tip_chord - root_chord) * y_panel / semi_span
         x_le = y_panel * (root_chord - tip_chord) / (4 * semi_span)
 
+        # Mirror the right side to define the left side for  y_panel, x_le and chord
         y_panel[self.n_y + 1 :] = -y_panel[1 : self.n_y + 1]
         chord[self.n_y + 1 :] = chord[1 : self.n_y + 1]
         x_le[self.n_y + 1 :] = x_le[1 : self.n_y + 1]
@@ -767,143 +822,75 @@ def _generate_htp(self, inputs):
         self._generate_common(self.htp)
 
     def _generate_common(self, dictionary):
-        """Common code shared between wing and htp to calculate geometry/aero parameters."""
+        """Common code shared between wing and htp to calculate geometry/aero parameters.
+
+                ^
+              y |                Points defining the panel
+                |                are named clockwise. A(x_1,y_1), B(x_2,y_2), P(x_c,y_c)
+        P3--B---|-----P4         Reference:
+        |   |   |     |          John J. Bertin, Russell M. Cummings - Aerodynamics for Engineers
+        |   |   |     |          p.394-398
+        T1  |   +--P--T2---->
+        |   |         |     x
+        |   |         |
+        P2--A--------P1
+
+        """
         # Initial data (zero matrix/array)
         x_le = dictionary["x_le"]
         chord = dictionary["chord"]
         x_panel = dictionary["x_panel"]
         y_panel = dictionary["y_panel"]
-        panelchord = dictionary["panel_chord"]
-        panelsurf = dictionary["panel_surf"]
+        panel_chord = dictionary["panel_chord"]
+        panel_surf = dictionary["panel_surf"]
         x_c = dictionary["x_c"]
         y_c = dictionary["yc"]
         x_1 = dictionary["x1"]
         y_1 = dictionary["y1"]
         x_2 = dictionary["x2"]
         y_2 = dictionary["y2"]
-        aic = dictionary["aic"]
-        aic_wake = dictionary["aic_wake"]
-        # Calculate panel corners x-coordinate
-        for i in range(self.n_x + 1):
-            x_panel[i, :] = x_le + chord * i / self.n_x
-
-        # Calculate panel span with symmetry
-        panelspan = y_panel[1:] - y_panel[:-1]
-        panelspan[self.n_y :] = panelspan[: self.n_y]
-
-        # Calculate characteristic points (Right and left side)
-        for i in range(self.n_x):
-            panelchord[i * self.n_y : (i + 1) * self.n_y] = 0.5 * (
-                (x_panel[i + 1, : self.n_y] - x_panel[i, : self.n_y])
-                + (x_panel[i + 1, 1 : self.n_y + 1] - x_panel[i, 1 : self.n_y + 1])
-            )
-            panelsurf[i * self.n_y : (i + 1) * self.n_y] = (
-                panelspan[: self.n_y] * panelchord[i * self.n_y : (i + 1) * self.n_y]
-            )
-
-            x_c[i * self.n_y : (i + 1) * self.n_y] = (
-                x_panel[i, : self.n_y] + x_panel[i, 1 : self.n_y + 1]
-            ) * 0.5 + 0.75 * panelchord[i * self.n_y : (i + 1) * self.n_y]
-
-            y_c[i * self.n_y : (i + 1) * self.n_y] = (
-                y_panel[: self.n_y] + y_panel[1 : self.n_y + 1]
-            ) * 0.5
-
-            x_1[i * self.n_y : (i + 1) * self.n_y] = x_panel[i, : self.n_y] + 0.25 * (
-                x_panel[i + 1, : self.n_y] - x_panel[i, : self.n_y]
-            )
-            x_1[
-                self.n_x * self.n_y + i * self.n_y : self.n_x * self.n_y + (i + 1) * self.n_y
-            ] = x_panel[i, self.n_y + 1 : 2 * self.n_y + 1] + 0.25 * (
-                x_panel[i + 1, self.n_y + 1 : 2 * self.n_y + 1]
-                - x_panel[i, self.n_y + 1 : 2 * self.n_y + 1]
-            )
 
-            x_2[i * self.n_y : (i + 1) * self.n_y] = x_panel[i, 1 : self.n_y + 1] + 0.25 * (
-                x_panel[i + 1, 1 : self.n_y + 1] - x_panel[i, 1 : self.n_y + 1]
-            )
-            x_2[
-                self.n_x * self.n_y + i * self.n_y : self.n_x * self.n_y + (i + 1) * self.n_y
-            ] = np.concatenate(
-                (
-                    np.array([x_panel[i, 0] + 0.25 * (x_panel[i + 1, 0] - x_panel[i, 0])]),
-                    (
-                        x_panel[i, self.n_y : 2 * self.n_y]
-                        + 0.25
-                        * (
-                            x_panel[i + 1, self.n_y : 2 * self.n_y]
-                            - x_panel[i, self.n_y : 2 * self.n_y]
-                        )
-                    )[1:],
-                )
-            )
-
-            y_1[i * self.n_y : (i + 1) * self.n_y] = y_panel[: self.n_y]
-            y_1[
-                self.n_x * self.n_y + i * self.n_y : self.n_x * self.n_y + (i + 1) * self.n_y
-            ] = y_panel[self.n_y + 1 : 2 * self.n_y + 1]
+        n_x = self.n_x
+        n_y = self.n_y
+        # calculate panel geometry and coordinate value
+        (
+            x_panel,
+            y_panel,
+            x_le,
+            chord,
+            panel_chord,
+            panel_span,
+            panel_surf,
+            x_1,
+            y_1,
+            x_2,
+            y_2,
+            x_c,
+            y_c,
+        ) = self.panel_point_calculation(
+            x_panel,
+            y_panel,
+            x_le,
+            chord,
+            panel_chord,
+            panel_surf,
+            x_1,
+            y_1,
+            x_2,
+            y_2,
+            x_c,
+            y_c,
+            n_x,
+            n_y,
+        )
 
-            y_2[i * self.n_y : (i + 1) * self.n_y] = y_panel[1 : self.n_y + 1]
-            y_2[
-                self.n_x * self.n_y + i * self.n_y : self.n_x * self.n_y + (i + 1) * self.n_y
-            ] = np.concatenate(
-                (
-                    np.array([0.0]),
-                    y_panel[self.n_y + 1 : 2 * self.n_y],
-                )
-            )
-        # Calculate remaining characteristic points (Left side)
+        aic, aic_wake = self.aic_computation(x_1, y_1, x_2, y_2, x_c, y_c, n_x, n_y)
 
-        x_c[self.n_x * self.n_y :] = x_c[: self.n_x * self.n_y]
-        y_c[self.n_x * self.n_y :] = -y_c[: self.n_x * self.n_y]
-
-        # Aerodynamic coefficients computation (Right side)
-        for i in range(self.n_x * self.n_y):
-            for j in range(self.n_x * self.n_y):
-                # Right wing
-                coeff_1 = x_c[i] - x_1[j]
-                coeff_2 = y_c[i] - y_1[j]
-                coeff_3 = x_c[i] - x_2[j]
-                coeff_4 = y_c[i] - y_2[j]
-                coeff_5 = np.sqrt(coeff_1 ** 2 + coeff_2 ** 2)
-                coeff_6 = np.sqrt(coeff_3 ** 2 + coeff_4 ** 2)
-                coeff_7 = x_2[j] - x_1[j]
-                coeff_8 = y_2[j] - y_1[j]
-                coeff_10 = (coeff_7 * coeff_1 + coeff_8 * coeff_2) / coeff_5 - (
-                    coeff_7 * coeff_3 + coeff_8 * coeff_4
-                ) / coeff_6
-                coeff_11 = (1 + coeff_3 / coeff_6) / coeff_4 - (1 + coeff_1 / coeff_5) / coeff_2
-                if coeff_1 * coeff_4 - coeff_2 * coeff_3 != 0:
-                    aic[i, j] = (coeff_10 / (coeff_1 * coeff_4 - coeff_2 * coeff_3)) / (4 * np.pi)
-                aic_wake[i, j] = coeff_11 / (4 * np.pi)
-                aic[i, j] = aic[i, j] + coeff_11 / (4 * np.pi)
-        # Aerodynamic coefficients computation (Left side)
-        for i in range(self.n_x * self.n_y):
-            for j in range(self.n_x * self.n_y):
-                # Left wing
-                coeff_1 = x_c[i] - x_1[self.n_x * self.n_y + j]
-                coeff_2 = y_c[i] - y_1[self.n_x * self.n_y + j]
-                coeff_3 = x_c[i] - x_2[self.n_x * self.n_y + j]
-                coeff_4 = y_c[i] - y_2[self.n_x * self.n_y + j]
-                coeff_5 = np.sqrt(coeff_1 ** 2 + coeff_2 ** 2)
-                coeff_6 = np.sqrt(coeff_3 ** 2 + coeff_4 ** 2)
-                coeff_7 = x_2[self.n_x * self.n_y + j] - x_1[self.n_x * self.n_y + j]
-                coeff_8 = y_2[self.n_x * self.n_y + j] - y_1[self.n_x * self.n_y + j]
-                coeff_9 = (coeff_7 * coeff_1 + coeff_8 * coeff_2) / coeff_5 - (
-                    coeff_7 * coeff_3 + coeff_8 * coeff_4
-                ) / coeff_6
-                coeff_10 = (1 + coeff_3 / coeff_6) / coeff_4 - (1 + coeff_1 / coeff_5) / coeff_2
-                if coeff_1 * coeff_4 - coeff_2 * coeff_3 != 0:
-                    aic[i, j] = aic[i, j] + (coeff_9 / (coeff_1 * coeff_4 - coeff_2 * coeff_3)) / (
-                        4 * np.pi
-                    )
-                aic_wake[i, j] = aic_wake[i, j] + coeff_10 / (4 * np.pi)
-                aic[i, j] = aic[i, j] + coeff_10 / (4 * np.pi)
         # Save data
         dictionary["x_panel"] = x_panel
-        dictionary["panel_span"] = panelspan
-        dictionary["panel_chord"] = panelchord
-        dictionary["panel_surf"] = panelsurf
+        dictionary["panel_span"] = panel_span
+        dictionary["panel_chord"] = panel_chord
+        dictionary["panel_surf"] = panel_surf
         dictionary["x_c"] = x_c
         dictionary["yc"] = y_c
         dictionary["x1"] = x_1
@@ -935,32 +922,26 @@ def generate_curvature(self, dictionary, file_name):
         """Generates curvature corresponding to the airfoil contained in .af file."""
         x_panel = dictionary["x_panel"]
 
-        # Initialization
-        z_panel = np.zeros(self.n_x + 1)
-        rootchord = x_panel[self.n_x, 0] - x_panel[0, 0]
-        # Calculation of panelangle_vect
+        root_chord = x_panel[self.n_x, 0] - x_panel[0, 0]
+        # Calculation of panel_angle_vect
         profile = get_profile(
             airfoil_folder_path=self.options["airfoil_folder_path"], file_name=file_name
         )
         mean_line = profile.get_mean_line()
-        for i in range(self.n_x + 1):
-            xred = (x_panel[i, 0] - x_panel[0, 0]) / rootchord
-            z_panel[i] = np.interp(
-                np.clip(xred, min(mean_line["x"]), max(mean_line["x"])),
-                mean_line["x"],
-                mean_line["z"],
-            )
-        z_panel = z_panel * rootchord
+        x_red = (x_panel[: self.n_x + 1, 0] - x_panel[0, 0]) / root_chord
+        x_red_clipped = np.clip(x_red, min(mean_line["x"]), max(mean_line["x"]))
+        z_panel = np.interp(x_red_clipped, mean_line["x"], mean_line["z"]) * root_chord
+
         x_coord_chord = x_panel[:, 0]
 
-        panelangle = (z_panel[: self.n_x] - z_panel[1 : self.n_x + 1]) / (
+        panel_angle = (z_panel[: self.n_x] - z_panel[1 : self.n_x + 1]) / (
             x_coord_chord[1 : self.n_x + 1] - x_coord_chord[: self.n_x]
         )
-        panelangle_vect = np.repeat(panelangle, self.n_y)
+        panel_angle_vect = np.repeat(panel_angle, self.n_y)
 
         # Save results
-        dictionary["panel_angle_vect"] = panelangle_vect
-        dictionary["panel_angle"] = panelangle
+        dictionary["panel_angle_vect"] = panel_angle_vect
+        dictionary["panel_angle"] = panel_angle
         dictionary["z"] = z_panel
 
     def apply_deflection(self, inputs, deflection_angle):
@@ -971,44 +952,39 @@ def apply_deflection(self, inputs, deflection_angle):
 
         deflection_angle *= np.pi / 180  # converted to radian
         x_panel = self.wing["x_panel"]
-        panelangle = self.wing["panel_angle"]
-        panelangle_vect = self.wing["panel_angle_vect"]
+        panel_angle_vect = self.wing["panel_angle_vect"]
 
-        z_panel = np.zeros(self.n_x + 1)
         z_panel_no_flaps = copy.deepcopy(self.wing["z"])
-        for i in range(self.n_x + 1):
-            if x_panel[i, 0] > x_start:
-                z_panel[i] = z_panel_no_flaps[i] - np.sin(deflection_angle) * (
-                    x_panel[i, 0] - x_start
-                )
-            else:
-                z_panel[i] = z_panel_no_flaps[i]
+        mask = x_panel[:, 0] <= x_start
+        z_panel = z_panel_no_flaps - np.sin(deflection_angle) * (x_panel[:, 0] - x_start)
+        z_panel[mask] = z_panel_no_flaps[mask]
 
         # At this point z_panel contains the z coordinate of the flapped part of the wing,
         # panel angle vector should not change in the un-flapped part
-        for i in range(self.n_x):
-            panelangle[i] = (z_panel[i] - z_panel[i + 1]) / (x_panel[i + 1, 0] - x_panel[i, 0])
+        panel_angle = (z_panel[: self.n_x] - z_panel[1 : self.n_x + 1]) / (
+            x_panel[1 : self.n_x + 1, 0] - x_panel[: self.n_x, 0]
+        )
 
-        # At this point panelangle contains the panel angle of the flapped part of the wing,
+        # At this point panel_angle contains the panel angle of the flapped part of the wing,
         # panel angle vector should not change in the un-flapped part
 
         # If we are in the flapped portion of the wing
         for j in range(self.ny1, self.ny1 + self.ny2):
             for i in range(self.n_x):
-                panelangle_vect[i * self.n_y + j] = panelangle[i]
+                panel_angle_vect[i * self.n_y + j] = panel_angle[i]
 
         # Save results
-        self.wing["panel_angle_vect"] = panelangle_vect
-        self.wing["panel_angle"] = panelangle
+        self.wing["panel_angle_vect"] = panel_angle_vect
+        self.wing["panel_angle"] = panel_angle
         self.wing["z"] = z_panel
 
     @staticmethod
-    def _interpolate_cdp(lift_coeff: np.ndarray, drag_coeff: np.ndarray, ojective: float) -> float:
+    def _interpolate_cdp(lift_coeff: np.ndarray, drag_coeff: np.ndarray, objective: float) -> float:
         """
 
         :param lift_coeff: CL array
         :param drag_coeff: CDp array
-        :param ojective: CL_ref objective value
+        :param objective: CL_ref objective value
         :return: CD_ref if CL_ref encountered, or default value otherwise.
         """
         # Reduce vectors for interpolation
@@ -1019,15 +995,15 @@ def _interpolate_cdp(lift_coeff: np.ndarray, drag_coeff: np.ndarray, ojective: f
                 break
 
         # Interpolate value if within the interpolation range
-        if min(lift_coeff) <= ojective <= max(lift_coeff):
+        if min(lift_coeff) <= objective <= max(lift_coeff):
             idx_max = int(float(np.where(lift_coeff == max(lift_coeff))[0]))
-            return np.interp(ojective, lift_coeff[0 : idx_max + 1], drag_coeff[0 : idx_max + 1])
-        elif ojective < lift_coeff[0]:
-            cdp = drag_coeff[0] + (ojective - lift_coeff[0]) * (drag_coeff[1] - drag_coeff[0]) / (
+            return np.interp(objective, lift_coeff[0 : idx_max + 1], drag_coeff[0 : idx_max + 1])
+        if objective < lift_coeff[0]:
+            cdp = drag_coeff[0] + (objective - lift_coeff[0]) * (drag_coeff[1] - drag_coeff[0]) / (
                 lift_coeff[1] - lift_coeff[0]
             )
         else:
-            cdp = drag_coeff[-1] + (ojective - lift_coeff[-1]) * (
+            cdp = drag_coeff[-1] + (objective - lift_coeff[-1]) * (
                 drag_coeff[-1] - drag_coeff[-2]
             ) / (lift_coeff[-1] - lift_coeff[-2])
         _LOGGER.warning("CL not in range. Linear extrapolation of CDp value %f", cdp)
@@ -1036,6 +1012,9 @@ def _interpolate_cdp(lift_coeff: np.ndarray, drag_coeff: np.ndarray, ojective: f
     @staticmethod
     def search_results(result_folder_path, geometry_set):
         """Search the results folder to see if the geometry has already been calculated."""
+        # default value
+        result_file_path = None
+        saved_area_ratio = 1.0
         if os.path.exists(result_folder_path):
             geometry_set_labels = [
                 "sweep25_wing",
@@ -1082,7 +1061,7 @@ def search_results(result_folder_path, geometry_set):
                             break
                     idx += 1
 
-        return None, 1.0
+        return result_file_path, saved_area_ratio
 
     @staticmethod
     def save_geometry(result_folder_path, geometry_set):
@@ -1140,3 +1119,412 @@ def read_results(result_file_path):
         labels = data.to_numpy()[:, 0].tolist()
 
         return pd.DataFrame(values, index=labels)
+
+    def post_processing_wing(
+        self,
+        width_max,
+        span_wing,
+        mach,
+        dihedral_angle,
+        wing_0,
+        wing_aoa,
+        aoa_angle,
+        aspect_ratio_wing,
+        cl_wing_airfoil,
+        cdp_wing_airfoil,
+    ):
+        """
+        Calculate aerodynamic characteristic with VLM results
+        :param width_max: maximum fuselage width
+        :param span_wing: wing span
+        :param mach: Mach number
+        :param dihedral_angle: wing dihedral angle
+        :param wing_0: wing aerodynamic characteristics with zero angle of attack
+        :param wing_aoa: wing aerodynamic characteristics with input angle of attack
+        :param aoa_angle: input angle of attack
+        :param aspect_ratio_wing: wing aspect ratio
+        :param cl_wing_airfoil: airfoil lift coefficient curve
+        :param cdp_wing_airfoil: airfoil pressure drag coefficient curve
+
+        :return: post-processed data for other use
+        """
+        k_fus = 1 + 0.025 * width_max / span_wing - 0.025 * (width_max / span_wing) ** 2
+        beta = np.sqrt(1 - mach ** 2)  # Prandtl-Glauert
+        cl_0_wing = float((wing_0["cl"] * k_fus / beta) * np.cos(dihedral_angle) ** 2.0)
+        cl_x_wing = float(wing_aoa["cl"] * k_fus / beta)
+        cm_0_wing = float(wing_0["cm"] * k_fus / beta)
+        cl_alpha_wing = ((cl_x_wing - cl_0_wing) / (aoa_angle * np.pi / 180)) * np.cos(
+            dihedral_angle
+        ) ** 2.0
+
+        # The correction on the effect of dihedral angle cannot be taken into account by
+        # modifying the generation of panel since only the surfaces of the panel and their
+        # aoa impact the computation, so we will stick with this "post processing" of the
+        # dihedral
+
+        y_vector_wing = wing_aoa["y_vector"]
+        cl_vector_wing = (np.array(wing_aoa["cl_vector"]) * k_fus / beta).tolist()
+        chord_vector_wing = wing_aoa["chord_vector"]
+        cdp_foil = self._interpolate_cdp(cl_wing_airfoil, cdp_wing_airfoil, cl_x_wing)
+        # Mach correction
+        if mach <= 0.4:
+            coef_e = wing_aoa["coef_e"]
+        else:
+            coef_e = wing_aoa["coef_e"] * (-0.001521 * ((mach - 0.05) / 0.3 - 1) ** 10.82 + 1)
+        cdi = cl_x_wing ** 2 / (np.pi * aspect_ratio_wing * coef_e) + cdp_foil
+        coef_e = wing_aoa["cl"] ** 2 / (np.pi * aspect_ratio_wing * cdi)
+        # Fuselage correction
+        k_fus = 1 - 2 * (width_max / span_wing) ** 2
+        coef_e = float(coef_e * k_fus)
+        coef_k_wing = float(1.0 / (np.pi * aspect_ratio_wing * coef_e))
+
+        return (
+            beta,
+            cl_0_wing,
+            cl_x_wing,
+            cm_0_wing,
+            cl_alpha_wing,
+            y_vector_wing,
+            cl_vector_wing,
+            chord_vector_wing,
+            coef_k_wing,
+        )
+
+    def post_processing_htp_ac(
+        self,
+        beta,
+        aspect_ratio_htp,
+        area_ratio,
+        mach,
+        aoa_angle,
+        cl_htp_airfoil,
+        cdp_htp_airfoil,
+        htp_0,
+        htp_aoa,
+    ):
+        """
+        Calculate aerodynamic characteristic with VLM results
+
+        :param beta: sweep angle of the htp
+        :param aspect_ratio_htp: htp aspect ratio
+        :param area_ratio: area ratio between wing and htp
+        :param mach: Mach number
+        :param aoa_angle: input angle of attack
+        :param cl_htp_airfoil: airfoil lift coefficient curve
+        :param cdp_htp_airfoil: airfoil pressure drag coefficient curve
+        :param htp_0: htp aerodynamic characteristics data list with zero angle of attack
+        :param htp_aoa: htp aerodynamic characteristics data list with input angle of attack
+
+        :return: post-processed data for other use
+        """
+        cl_0_htp = float(htp_0["cl"]) / beta * area_ratio
+        cl_aoa_htp = float(htp_aoa["cl"]) / beta * area_ratio
+        cl_alpha_htp = float((cl_aoa_htp - cl_0_htp) / (aoa_angle * np.pi / 180))
+        cdp_foil = self._interpolate_cdp(cl_htp_airfoil, cdp_htp_airfoil, htp_aoa["cl"] / beta)
+        # Mach correction
+        if mach <= 0.4:
+            coef_e = htp_aoa["coef_e"]
+        else:
+            coef_e = htp_aoa["coef_e"] * (-0.001521 * ((mach - 0.05) / 0.3 - 1) ** 10.82 + 1)
+        cdi = (htp_aoa["cl"] / beta) ** 2 / (np.pi * aspect_ratio_htp * coef_e) + cdp_foil
+        coef_k_htp = float(cdi / cl_aoa_htp ** 2 * area_ratio)
+        y_vector_htp = htp_aoa["y_vector"]
+        cl_vector_htp = (np.array(htp_aoa["cl_vector"]) / beta * area_ratio).tolist()
+
+        return (
+            cl_0_htp,
+            cl_aoa_htp,
+            cl_alpha_htp,
+            coef_k_htp,
+            y_vector_htp,
+            cl_vector_htp,
+        )
+
+    def read_value_from_data(self, result_file_path, sref_wing, area_ratio, saved_area_ratio):
+        """
+        Read existed data to speed up the process
+
+        :param result_file_path: path to the file with existing data
+        :param sref_wing: wing reference area
+        :param area_ratio: area ratio between wing and horizontal stabilizer
+        :param saved_area_ratio:  area ratio between wing and horizontal stabilizer in existing data
+
+        :return: existing data
+        """
+        data = self.read_results(result_file_path)
+        saved_area_wing = float(data.loc["saved_ref_area", 0])
+        cl_0_wing = float(data.loc["cl_0_wing", 0])
+        cl_x_wing = float(data.loc["cl_X_wing", 0])
+        cl_alpha_wing = float(data.loc["cl_alpha_wing", 0])
+        cm_0_wing = float(data.loc["cm_0_wing", 0])
+        y_vector_wing = string_to_array(data.loc["y_vector_wing", 0][1:-2]) * np.sqrt(
+            sref_wing / saved_area_wing
+        )
+        cl_vector_wing = string_to_array(data.loc["cl_vector_wing", 0][1:-2])
+        chord_vector_wing = string_to_array(data.loc["chord_vector_wing", 0][1:-2]) * np.sqrt(
+            sref_wing / saved_area_wing
+        )
+        coef_k_wing = float(data.loc["coef_k_wing", 0])
+        cl_0_htp = float(data.loc["cl_0_htp", 0]) * (area_ratio / saved_area_ratio)
+        cl_aoa_htp = float(data.loc["cl_X_htp", 0]) * (area_ratio / saved_area_ratio)
+        cl_alpha_htp = float(data.loc["cl_alpha_htp", 0]) * (area_ratio / saved_area_ratio)
+        cl_alpha_htp_isolated = float(data.loc["cl_alpha_htp_isolated", 0]) * (
+            area_ratio / saved_area_ratio
+        )
+        y_vector_htp = string_to_array(data.loc["y_vector_htp", 0][1:-2])
+        cl_vector_htp = string_to_array(data.loc["cl_vector_htp", 0][1:-2])
+        coef_k_htp = float(data.loc["coef_k_htp", 0]) * (area_ratio / saved_area_ratio)
+
+        return (
+            cl_0_wing,
+            cl_x_wing,
+            cl_alpha_wing,
+            cm_0_wing,
+            y_vector_wing,
+            cl_vector_wing,
+            chord_vector_wing,
+            coef_k_wing,
+            cl_0_htp,
+            cl_aoa_htp,
+            cl_alpha_htp,
+            cl_alpha_htp_isolated,
+            y_vector_htp,
+            cl_vector_htp,
+            coef_k_htp,
+        )
+
+    @staticmethod
+    def resize_vector(vectors):
+        """
+        Format the size of results that need to be passed as array to the size declared to
+        OpenMDAO if the original array is bigger we resize it, otherwise we complete with zeros.
+        First vector always has to be the y vector, any other vector can be a quantity expressed
+        as that vector.
+
+        :param vectors: a tuple with wing aerodynamic results
+
+        :return: length-modified aerodynamic results
+        """
+        y_vector = vectors[0]
+
+        resized_vectors = []
+
+        # shorter
+        if SPAN_MESH_POINT < len(y_vector):
+
+            y_interp = np.linspace(y_vector[0], y_vector[-1], SPAN_MESH_POINT)
+            warnings.warn("Defined maximum span mesh in fast aerodynamics\\constants.py exceeded!")
+
+            resized_vectors.append(y_interp)
+
+            for vector in vectors[1:]:
+                resized_vector = np.interp(y_interp, y_vector, vector)
+                resized_vectors.append(resized_vector)
+
+        # longer
+        else:
+            additional_zeros = list(np.zeros(SPAN_MESH_POINT - len(y_vector)))
+            y_vector = y_vector + additional_zeros
+
+            resized_vectors.append(y_vector)
+
+            for vector in vectors[1:]:
+                resized_vector = vector + additional_zeros
+                resized_vectors.append(resized_vector)
+
+        return resized_vectors
+
+    @staticmethod
+    def aic_computation(x_1, y_1, x_2, y_2, x_c, y_c, n_x, n_y):
+        """
+                ^
+              y |                Points defining the panel
+                |                are named clockwise. A(x_1,y_1), B(x_2,y_2), P(x_c,y_c)
+        P3--B---|-----P4         Reference:
+        |   |   |     |          John J. Bertin, Russell M. Cummings - Aerodynamics for Engineers
+        |   |   |     |          p.394-398
+        T1  |   +--P--T2---->
+        |   |         |     x
+        |   |         |
+        P2--A--------P1
+
+        The P point is the center point of all the panel in AIC matrix construction. For each
+        linear equations in the AIC linear system, each P point of each panel is  considered
+        (double for loop).
+        """
+        midpoint = len(x_c) // 2
+
+        x_c = x_c[:midpoint]
+        x_c = np.repeat(x_c[:, np.newaxis], midpoint, axis=1).ravel()
+        y_c = y_c[:midpoint]
+        y_c = np.repeat(y_c[:, np.newaxis], midpoint, axis=1).ravel()
+        x_1_r = x_1[:midpoint]
+        x_1_r = np.tile(x_1_r, len(x_1_r))
+        y_1_r = y_1[:midpoint]
+        y_1_r = np.tile(y_1_r, len(y_1_r))
+        x_2_r = x_2[:midpoint]
+        x_2_r = np.tile(x_2_r, len(x_2_r))
+        y_2_r = y_2[:midpoint]
+        y_2_r = np.tile(y_2_r, len(y_2_r))
+        x_1_l = x_1[midpoint:]
+        x_1_l = np.tile(x_1_l, len(x_1_l))
+        y_1_l = y_1[midpoint:]
+        y_1_l = np.tile(y_1_l, len(y_1_l))
+        x_2_l = x_2[midpoint:]
+        x_2_l = np.tile(x_2_l, len(x_2_l))
+        y_2_l = y_2[midpoint:]
+        y_2_l = np.tile(y_2_l, len(y_2_l))
+
+        coeff_1_r = x_c - x_1_r
+        coeff_2_r = y_c - y_1_r
+        coeff_3_r = x_c - x_2_r
+        coeff_4_r = y_c - y_2_r
+        coeff_5_r = np.sqrt(coeff_1_r ** 2 + coeff_2_r ** 2)
+        coeff_6_r = np.sqrt(coeff_3_r ** 2 + coeff_4_r ** 2)
+        coeff_7_r = x_2_r - x_1_r
+        coeff_8_r = y_2_r - y_1_r
+        coeff_9_r = (coeff_7_r * coeff_1_r + coeff_8_r * coeff_2_r) / coeff_5_r - (
+            coeff_7_r * coeff_3_r + coeff_8_r * coeff_4_r
+        ) / coeff_6_r
+        coeff_10_r = (1 + coeff_3_r / coeff_6_r) / coeff_4_r - (
+            1 + coeff_1_r / coeff_5_r
+        ) / coeff_2_r
+        coeff_1_l = x_c - x_1_l
+        coeff_2_l = y_c - y_1_l
+        coeff_3_l = x_c - x_2_l
+        coeff_4_l = y_c - y_2_l
+        coeff_5_l = np.sqrt(coeff_1_l ** 2 + coeff_2_l ** 2)
+        coeff_6_l = np.sqrt(coeff_3_l ** 2 + coeff_4_l ** 2)
+        coeff_7_l = x_2_l - x_1_l
+        coeff_8_l = y_2_l - y_1_l
+        coeff_9_l = (coeff_7_l * coeff_1_l + coeff_8_l * coeff_2_l) / coeff_5_l - (
+            coeff_7_l * coeff_3_l + coeff_8_l * coeff_4_l
+        ) / coeff_6_l
+        coeff_10_l = (1 + coeff_3_l / coeff_6_l) / coeff_4_l - (
+            1 + coeff_1_l / coeff_5_l
+        ) / coeff_2_l
+        aic_wake = coeff_10_r / (4 * np.pi) + coeff_10_l / (4 * np.pi)
+        aic = coeff_10_l / (4 * np.pi) + coeff_10_r / (4 * np.pi)
+
+        # Calculate cross products
+        den_r = coeff_1_r * coeff_4_r - coeff_2_r * coeff_3_r
+        den_l = coeff_1_l * coeff_4_l - coeff_2_l * coeff_3_l
+
+        # Create masks
+        mask_r = den_r != 0
+        mask_l = den_l != 0
+        # Update aic
+        aic[mask_r] = aic[mask_r] + coeff_9_r[mask_r] / den_r[mask_r] / (4 * np.pi)
+        aic[mask_l] = aic[mask_l] + coeff_9_l[mask_l] / den_l[mask_l] / (4 * np.pi)
+        # reshape into 2D array for later matrix computation
+        aic = aic.reshape(int(n_x * n_y), int(n_x * n_y), order="C")
+        aic_wake = aic_wake.reshape(int(n_x * n_y), int(n_x * n_y), order="C")
+
+        return aic, aic_wake
+
+    @staticmethod
+    def panel_point_calculation(
+        x_panel,
+        y_panel,
+        x_le,
+        chord,
+        panel_chord,
+        panel_surf,
+        x_1,
+        y_1,
+        x_2,
+        y_2,
+        x_c,
+        y_c,
+        n_x,
+        n_y,
+    ):
+
+        """
+        Calculate the coordinate value of each geometry points in each panel.
+        Store this value into position arrays for later AIC matrix computation.
+        """
+        for i in range(n_x + 1):
+            x_panel[i, :] = x_le + chord * i / n_x
+
+        # Calculate panel span with symmetry
+        panel_span = y_panel[1:] - y_panel[:-1]
+        panel_span[n_y:] = panel_span[:n_y]
+
+        # Calculate characteristic points (Right and left side)
+        for i in range(n_x):
+            panel_chord[i * n_y : (i + 1) * n_y] = 0.5 * (
+                (x_panel[i + 1, :n_y] - x_panel[i, :n_y])
+                + (x_panel[i + 1, 1 : n_y + 1] - x_panel[i, 1 : n_y + 1])
+            )
+            panel_surf[i * n_y : (i + 1) * n_y] = (
+                panel_span[:n_y] * panel_chord[i * n_y : (i + 1) * n_y]
+            )
+            # right side
+
+            # point A for the right-half
+            x_1[i * n_y : (i + 1) * n_y] = x_panel[i, :n_y] + 0.25 * (
+                x_panel[i + 1, :n_y] - x_panel[i, :n_y]
+            )
+
+            y_1[i * n_y : (i + 1) * n_y] = y_panel[:n_y]
+
+            # point B for the right-half
+            x_2[i * n_y : (i + 1) * n_y] = x_panel[i, 1 : n_y + 1] + 0.25 * (
+                x_panel[i + 1, 1 : n_y + 1] - x_panel[i, 1 : n_y + 1]
+            )
+
+            y_2[i * n_y : (i + 1) * n_y] = y_panel[1 : n_y + 1]
+
+            # point P for the right-half
+            x_c[i * n_y : (i + 1) * n_y] = (
+                x_panel[i, :n_y] + x_panel[i, 1 : n_y + 1]
+            ) * 0.5 + 0.75 * panel_chord[i * n_y : (i + 1) * n_y]
+
+            y_c[i * n_y : (i + 1) * n_y] = (y_panel[:n_y] + y_panel[1 : n_y + 1]) * 0.5
+
+            # left side
+
+            # point A for the left-half
+            x_1[n_x * n_y + i * n_y : n_x * n_y + (i + 1) * n_y] = x_panel[
+                i, n_y + 1 : 2 * n_y + 1
+            ] + 0.25 * (x_panel[i + 1, n_y + 1 : 2 * n_y + 1] - x_panel[i, n_y + 1 : 2 * n_y + 1])
+
+            y_1[n_x * n_y + i * n_y : n_x * n_y + (i + 1) * n_y] = y_panel[n_y + 1 : 2 * n_y + 1]
+
+            # point B for the left-half
+            x_2[n_x * n_y + i * n_y : n_x * n_y + (i + 1) * n_y] = np.concatenate(
+                (
+                    np.array([x_panel[i, 0] + 0.25 * (x_panel[i + 1, 0] - x_panel[i, 0])]),
+                    (
+                        x_panel[i, n_y : 2 * n_y]
+                        + 0.25 * (x_panel[i + 1, n_y : 2 * n_y] - x_panel[i, n_y : 2 * n_y])
+                    )[1:],
+                )
+            )
+            y_2[n_x * n_y + i * n_y : n_x * n_y + (i + 1) * n_y] = np.concatenate(
+                (
+                    np.array([0.0]),
+                    y_panel[n_y + 1 : 2 * n_y],
+                )
+            )
+        # Calculate remaining characteristic points (Left side)
+        # point P for the left-half
+        x_c[n_x * n_y :] = x_c[: n_x * n_y]
+        y_c[n_x * n_y :] = -y_c[: n_x * n_y]
+
+        return (
+            x_panel,
+            y_panel,
+            x_le,
+            chord,
+            panel_chord,
+            panel_span,
+            panel_surf,
+            x_1,
+            y_1,
+            x_2,
+            y_2,
+            x_c,
+            y_c,
+        )
diff --git a/src/fastga/models/aerodynamics/external/xfoil/resources/naca23012_inv.csv b/src/fastga/models/aerodynamics/external/xfoil/resources/naca23012_inv.csv
new file mode 100644
index 00000000..54493d93
--- /dev/null
+++ b/src/fastga/models/aerodynamics/external/xfoil/resources/naca23012_inv.csv
@@ -0,0 +1,11 @@
+,0
+mach,0.245
+reynolds,7081672
+cl_max_2d,1.416
+cl_min_2d,0.2727
+cd_min_2d,0.0
+alpha,"[1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0]"
+cl,"[0.2727, 0.3355, 0.3983, 0.4612, 0.5241, 0.587, 0.6501, 0.7132, 0.7764, 0.8397, 0.9031, 0.9666, 1.0303, 1.0941, 1.158, 1.2222, 1.2866, 1.3511, 1.416]"
+cd,"[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]"
+cdp,"[-0.0019, -0.00197, -0.00206, -0.00217, -0.00232, -0.00251, -0.00274, -0.00302, -0.00337, -0.00379, -0.0043, -0.00491, -0.00565, -0.00652, -0.00755, -0.00876, -0.01017, -0.01182, -0.01373]"
+cm,"[-0.0117, -0.0123, -0.013, -0.0137, -0.0144, -0.0151, -0.0157, -0.0164, -0.0171, -0.0177, -0.0183, -0.0189, -0.0195, -0.02, -0.0205, -0.021, -0.0215, -0.0219, -0.0223]"
diff --git a/src/fastga/models/aerodynamics/external/xfoil/resources/polar_session_inv.txt b/src/fastga/models/aerodynamics/external/xfoil/resources/polar_session_inv.txt
new file mode 100644
index 00000000..a723a432
--- /dev/null
+++ b/src/fastga/models/aerodynamics/external/xfoil/resources/polar_session_inv.txt
@@ -0,0 +1,26 @@
+PLOP
+G F
+
+LOAD
+/profile
+PANE
+GDES
+GSET
+EXEC
+
+OPER
+M
+mach_number
+INV
+ITER
+100
+PACC
+/polar_result
+
+ASEQ
+0
+30
+0.5
+PACC
+
+QUIT
diff --git a/src/fastga/models/aerodynamics/external/xfoil/resources/polar_session_single_AoA.txt b/src/fastga/models/aerodynamics/external/xfoil/resources/polar_session_single_AoA.txt
new file mode 100644
index 00000000..5d012263
--- /dev/null
+++ b/src/fastga/models/aerodynamics/external/xfoil/resources/polar_session_single_AoA.txt
@@ -0,0 +1,28 @@
+PLOP
+G F
+
+LOAD
+/profile
+PANE
+GDES
+GSET
+EXEC
+
+OPER
+RE
+reynolds_number
+M
+mach_number
+VISC
+ITER
+100
+PACC
+/polar_result
+
+ALFA
+5.0
+
+
+PACC
+
+QUIT
diff --git a/src/fastga/models/aerodynamics/external/xfoil/resources/polar_session_single_AoA_inv.txt b/src/fastga/models/aerodynamics/external/xfoil/resources/polar_session_single_AoA_inv.txt
new file mode 100644
index 00000000..57e0cf3e
--- /dev/null
+++ b/src/fastga/models/aerodynamics/external/xfoil/resources/polar_session_single_AoA_inv.txt
@@ -0,0 +1,26 @@
+PLOP
+G F
+
+LOAD
+/profile
+PANE
+GDES
+GSET
+EXEC
+
+OPER
+M
+mach_number
+INV
+ITER
+100
+PACC
+/polar_result
+
+ALFA
+5.0
+
+
+PACC
+
+QUIT
diff --git a/src/fastga/models/aerodynamics/external/xfoil/resources/sample_airfoil_inv.csv b/src/fastga/models/aerodynamics/external/xfoil/resources/sample_airfoil_inv.csv
new file mode 100644
index 00000000..7f05ae31
--- /dev/null
+++ b/src/fastga/models/aerodynamics/external/xfoil/resources/sample_airfoil_inv.csv
@@ -0,0 +1,11 @@
+,0
+mach,0.1284
+reynolds,2993524
+cl_max_2d,3.0692
+cl_min_2d,0.6103
+cd_min_2d,0.0
+alpha,"[5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0, 10.5, 11.0, 11.5, 12.0, 12.5, 13.0, 13.5, 14.0, 14.5, 15.0, 15.5, 16.0, 16.5, 17.0, 17.5, 18.0, 18.5, 19.0, 19.5, 20.0, 20.5, 21.0, 21.5, 22.0, 22.5, 23.0, 23.5, 24.0, 24.5, 25.0]"
+cl,"[0.6103, 0.6713, 0.7323, 0.7933, 0.8543, 0.9153, 0.9763, 1.0372, 1.0982, 1.1592, 1.2201, 1.2811, 1.342, 1.403, 1.464, 1.525, 1.586, 1.647, 1.708, 1.7691, 1.8302, 1.8913, 1.9525, 2.0137, 2.075, 2.1363, 2.1977, 2.2592, 2.3207, 2.3824, 2.4441, 2.5059, 2.5679, 2.63, 2.6922, 2.7546, 2.8171, 2.8798, 2.9427, 3.0058, 3.0692]"
+cd,"[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]"
+cdp,"[-0.00159, -0.00172, -0.00187, -0.00205, -0.00226, -0.00251, -0.0028, -0.00314, -0.00353, -0.00398, -0.00449, -0.00506, -0.00572, -0.00645, -0.00727, -0.00819, -0.00921, -0.01034, -0.01158, -0.01295, -0.01445, -0.0161, -0.01789, -0.01983, -0.02195, -0.02423, -0.0267, -0.02936, -0.03222, -0.03529, -0.03858, -0.0421, -0.04585, -0.04985, -0.05411, -0.05863, -0.06342, -0.0685, -0.07387, -0.07953, -0.08551]"
+cm,"[-0.0069, -0.0076, -0.0082, -0.0088, -0.0095, -0.0101, -0.0107, -0.0112, -0.0118, -0.0124, -0.0129, -0.0134, -0.0139, -0.0144, -0.0148, -0.0153, -0.0157, -0.0161, -0.0164, -0.0168, -0.0171, -0.0174, -0.0176, -0.0179, -0.0181, -0.0183, -0.0184, -0.0186, -0.0187, -0.0187, -0.0188, -0.0188, -0.0187, -0.0187, -0.0186, -0.0185, -0.0183, -0.0182, -0.0179, -0.0177, -0.0174]"
diff --git a/src/fastga/models/aerodynamics/external/xfoil/xfoil_polar.py b/src/fastga/models/aerodynamics/external/xfoil/xfoil_polar.py
index 721a36bd..592dbcab 100644
--- a/src/fastga/models/aerodynamics/external/xfoil/xfoil_polar.py
+++ b/src/fastga/models/aerodynamics/external/xfoil/xfoil_polar.py
@@ -31,6 +31,7 @@
 from openmdao.components.external_code_comp import ExternalCodeComp
 from openmdao.utils.file_wrap import InputFileGenerator
 
+from fastga.command.api import string_to_array
 from fastga.models.aerodynamics.external.xfoil import xfoil699
 from fastga.models.geometry.profiles.get_profile import get_profile
 from . import resources as local_resources
@@ -63,8 +64,11 @@
 class XfoilPolar(ExternalCodeComp):
     """Runs a polar computation with XFOIL and returns the 2D max lift coefficient."""
 
-    _xfoil_output_names = ["alpha", "CL", "CD", "CDp", "CM", "Top_Xtr", "Bot_Xtr"]
-    """Column names in XFOIL polar result"""
+    def __init__(self, **kwargs):
+        super().__init__(**kwargs)
+
+        # Column names in XFOIL polar result
+        self._xfoil_output_names = ["alpha", "CL", "CD", "CDp", "CM", "Top_Xtr", "Bot_Xtr"]
 
     def initialize(self):
 
@@ -77,6 +81,7 @@ def initialize(self):
         self.options.declare(OPTION_ALPHA_END, default=90.0, types=float)
         self.options.declare(OPTION_ITER_LIMIT, default=100, types=int)
         self.options.declare(OPTION_COMP_NEG_AIR_SYM, default=False, types=bool)
+        self.options.declare("inviscid_calculation", default=False, types=bool)
         self.options.declare(
             "single_AoA",
             default=False,
@@ -91,11 +96,17 @@ def initialize(self):
         )
 
     def setup(self):
+        """
+        Set up inputs and outputs required for this operation
+        """
+
+        multiple_aoa = not self.options["single_AoA"]
 
         self.add_input("xfoil:mach", val=np.nan)
         self.add_input("xfoil:reynolds", val=np.nan)
 
-        if not self.options["single_AoA"]:
+        if multiple_aoa:
+
             self.add_output("xfoil:alpha", shape=POLAR_POINT_COUNT, units="deg")
             self.add_output("xfoil:CL", shape=POLAR_POINT_COUNT)
             self.add_output("xfoil:CD", shape=POLAR_POINT_COUNT)
@@ -103,7 +114,10 @@ def setup(self):
             self.add_output("xfoil:CM", shape=POLAR_POINT_COUNT)
             self.add_output("xfoil:CL_max_2D")
             self.add_output("xfoil:CL_min_2D")
+            self.add_output("xfoil:CD_min_2D")
+
         else:
+
             self.add_output("xfoil:alpha", units="deg")
             self.add_output("xfoil:CL")
             self.add_output("xfoil:CD")
@@ -117,12 +131,19 @@ def check_config(self, logger):
         pass
 
     def compute(self, inputs, outputs):
+        """
+        Function that computes airfoil aerodynamics with XFoil and returns the different 2D
+        aerodynamic parameters.
+
+        @param inputs: inputs parameters defined within FAST-OAD-GA
+        @param outputs: outputs parameters defined within FAST-OAD-GA
+        """
 
         # Define timeout for the function
         self.options["timeout"] = 15.0
 
         # Get inputs and initialise outputs
-        mach = round(float(inputs["xfoil:mach"]) * 1e4) / 1e4
+        mach = round(float(inputs["xfoil:mach"]), 4)
         reynolds = round(float(inputs["xfoil:reynolds"]))
 
         # Search if data already stored for this profile and mach with reynolds values bounding
@@ -130,284 +151,48 @@ def compute(self, inputs, outputs):
         no_file = True
         data_saved = None
         interpolated_result = None
-        if self.options[OPTION_COMP_NEG_AIR_SYM]:
-            result_file = pth.join(
-                pth.split(os.path.realpath(__file__))[0],
-                "resources",
-                self.options["airfoil_file"].replace(
-                    ".af", "_" + str(int(np.ceil(self.options[OPTION_ALPHA_END])))
-                )
-                + "S.csv",
-            )
-        else:
-            result_file = pth.join(
-                pth.split(os.path.realpath(__file__))[0],
-                "resources",
-                self.options["airfoil_file"].replace(".af", "") + ".csv",
-            )
-        if pth.exists(result_file) and not self.options["single_AoA"]:
-            no_file = False
-            data_saved = pd.read_csv(result_file)
-            values = data_saved.to_numpy()[:, 1 : len(data_saved.to_numpy()[0])]
-            labels = data_saved.to_numpy()[:, 0].tolist()
-            data_saved = pd.DataFrame(values, index=labels)
-            saved_mach_list = data_saved.loc["mach", :].to_numpy().astype(float)
-            index_near_mach = np.where(abs(saved_mach_list - mach) < 0.03)[0]
-            near_mach = []
-            distance_to_mach = []
-            for index in index_near_mach:
-                if not (saved_mach_list[index] in near_mach):
-                    near_mach.append(saved_mach_list[index])
-                    distance_to_mach.append(abs(saved_mach_list[index] - mach))
-            if not near_mach:
-                index_mach = np.where(data_saved.loc["mach", :].to_numpy() == str(mach))[0]
-            else:
-                selected_mach_index = distance_to_mach.index(min(distance_to_mach))
-                index_mach = np.where(saved_mach_list == near_mach[selected_mach_index])[0]
-            data_reduced = data_saved.loc[labels, index_mach]
-            # Search if this exact reynolds has been computed and save results
-            reynolds_vect = np.array(
-                [float(x) for x in list(data_reduced.loc["reynolds", :].to_numpy())]
-            )
-            index_reynolds = index_mach[np.where(reynolds_vect == reynolds)[0]]
-            if len(index_reynolds) == 1:
-                interpolated_result = data_reduced.loc[labels, index_reynolds]
-            # Else search for lower/upper Reynolds
-            else:
-                lower_reynolds = reynolds_vect[np.where(reynolds_vect < reynolds)[0]]
-                upper_reynolds = reynolds_vect[np.where(reynolds_vect > reynolds)[0]]
-                if not (len(lower_reynolds) == 0 or len(upper_reynolds) == 0):
-                    index_lower_reynolds = index_mach[
-                        np.where(reynolds_vect == max(lower_reynolds))[0]
-                    ]
-                    index_upper_reynolds = index_mach[
-                        np.where(reynolds_vect == min(upper_reynolds))[0]
-                    ]
-                    lower_values = data_reduced.loc[labels, index_lower_reynolds]
-                    upper_values = data_reduced.loc[labels, index_upper_reynolds]
-                    # Initialise values with lower reynolds
-                    interpolated_result = lower_values
-                    # Calculate reynolds ratio split for linear interpolation
-                    x_ratio = (min(upper_reynolds) - reynolds) / (
-                        min(upper_reynolds) - max(lower_reynolds)
-                    )
-                    # Search for common alpha range for linear interpolation
-                    alpha_lower = (
-                        np.array(
-                            np.matrix(lower_values.loc["alpha", index_lower_reynolds].to_numpy()[0])
-                        )
-                        .ravel()
-                        .tolist()
-                    )
-                    alpha_upper = (
-                        np.array(
-                            np.matrix(upper_values.loc["alpha", index_upper_reynolds].to_numpy()[0])
-                        )
-                        .ravel()
-                        .tolist()
-                    )
-                    alpha_shared = np.array(list(set(alpha_upper).intersection(alpha_lower)))
-                    interpolated_result.loc["alpha", index_lower_reynolds] = str(
-                        alpha_shared.tolist()
-                    )
-                    labels.remove("alpha")
-                    # Calculate average values (cd, cl...) with linear interpolation
-                    for label in labels:
-                        lower_value = np.array(
-                            np.matrix(lower_values.loc[label, index_lower_reynolds].to_numpy()[0])
-                        ).ravel()
-                        upper_value = np.array(
-                            np.matrix(upper_values.loc[label, index_upper_reynolds].to_numpy()[0])
-                        ).ravel()
-                        # If values relative to alpha vector, performs interpolation with shared
-                        # vector
-                        if np.size(lower_value) == len(alpha_lower):
-                            lower_value = np.interp(
-                                alpha_shared, np.array(alpha_lower), lower_value
-                            )
-                            upper_value = np.interp(
-                                alpha_shared, np.array(alpha_upper), upper_value
-                            )
-                        value = (lower_value * x_ratio + upper_value * (1 - x_ratio)).tolist()
-                        interpolated_result.loc[label, index_lower_reynolds] = str(value)
-
-        if interpolated_result is None:
-            # Create result folder first (if it must fail, let it fail as soon as possible)
-            result_folder_path = self.options[OPTION_RESULT_FOLDER_PATH]
-            if result_folder_path != "":
-                os.makedirs(result_folder_path, exist_ok=True)
-
-            # Pre-processing (populating temp directory)
-            # XFoil exe
-            tmp_directory = self._create_tmp_directory()
-            if self.options[OPTION_XFOIL_EXE_PATH]:
-                # if a path for Xfoil has been provided, simply use it
-                self.options["command"] = [self.options[OPTION_XFOIL_EXE_PATH]]
-            else:
-                # otherwise, copy the embedded resource in tmp dir
-                # noinspection PyTypeChecker
-                copy_resource(xfoil699, XFOIL_EXE_NAME, tmp_directory.name)
-                self.options["command"] = [pth.join(tmp_directory.name, XFOIL_EXE_NAME)]
 
-            # I/O files
-            self.stdin = pth.join(tmp_directory.name, _INPUT_FILE_NAME)
-            self.stdout = pth.join(tmp_directory.name, _STDOUT_FILE_NAME)
-            self.stderr = pth.join(tmp_directory.name, _STDERR_FILE_NAME)
+        # Modify file type respect to negative AoA/inviscid/single AoA options
+        result_file = self._define_result_file_path()
+        multiple_aoa = not self.options["single_AoA"]
 
-            # profile file
-            tmp_profile_file_path = pth.join(tmp_directory.name, _TMP_PROFILE_FILE_NAME)
-            profile = get_profile(
-                airfoil_folder_path=self.options["airfoil_folder_path"],
-                file_name=self.options["airfoil_file"],
-            ).get_sides()
-            # noinspection PyTypeChecker
-            np.savetxt(
-                tmp_profile_file_path,
-                profile.to_numpy(),
-                fmt="%.15f",
-                delimiter=" ",
-                header="Wing",
-                comments="",
+        if pth.exists(result_file):
+            no_file = False
+            interpolated_result, data_saved = self._interpolation_for_exist_data(
+                result_file, mach, reynolds
             )
 
-            # standard input file
-            tmp_result_file_path = pth.join(tmp_directory.name, _TMP_RESULT_FILE_NAME)
-            self._write_script_file(
-                reynolds,
-                mach,
-                tmp_profile_file_path,
+        if interpolated_result is None:
+            (
+                result_array_p,
+                result_array_n,
+                result_folder_path,
+                tmp_directory,
                 tmp_result_file_path,
-                self.options[OPTION_ALPHA_START],
-                self.options[OPTION_ALPHA_END],
-                ALPHA_STEP,
-            )
-
-            # Run XFOIL
-            self.options["external_input_files"] = [self.stdin, tmp_profile_file_path]
-            self.options["external_output_files"] = [tmp_result_file_path]
-            # noinspection PyBroadException
-            try:
-                super().compute(inputs, outputs)
-                result_array_p = self._read_polar(tmp_result_file_path)
-            except:
-                # catch the error and try to read result file for non-convergence on higher angles
-                error = sys.exc_info()[1]
-                try:
-                    result_array_p = self._read_polar(tmp_result_file_path)
-                except:
-                    raise TimeoutError("<p>Error: %s</p>" % error)
-
-            if self.options[OPTION_COMP_NEG_AIR_SYM]:
-                os.remove(self.stdin)
-                os.remove(self.stdout)
-                os.remove(self.stderr)
-                os.remove(tmp_result_file_path)
-                alpha_start = min(-1 * self.options[OPTION_ALPHA_START], -ALPHA_STEP)
-                self._write_script_file(
-                    reynolds,
-                    mach,
-                    tmp_profile_file_path,
-                    tmp_result_file_path,
-                    alpha_start,
-                    -1 * self.options[OPTION_ALPHA_END],
-                    -ALPHA_STEP,
-                )
-                # noinspection PyBroadException
-                try:
-                    super().compute(inputs, outputs)
-                    result_array_n = self._read_polar(tmp_result_file_path)
-                except:
-                    # catch the error and try to read result file for non-convergence on higher
-                    # angles
-                    e = sys.exc_info()[1]
-                    try:
-                        result_array_n = self._read_polar(tmp_result_file_path)
-                    except:
-                        raise TimeoutError("<p>Error: %s</p>" % e)
-
-            # Post-processing
-            if self.options["single_AoA"]:
-                alpha = result_array_p["alpha"].tolist()
-                cl = result_array_p["CL"].tolist()
-                cd = result_array_p["CD"].tolist()
-                cdp = result_array_p["CDp"].tolist()
-                cm = result_array_p["CM"].tolist()
-            elif self.options[OPTION_COMP_NEG_AIR_SYM]:
-                cl_max_2d, error = self._get_max_cl(result_array_p["alpha"], result_array_p["CL"])
-                # noinspection PyUnboundLocalVariable
-                cl_min_2d, _ = self._get_min_cl(result_array_n["alpha"], result_array_n["CL"])
-                alpha = result_array_n["alpha"].tolist()
-                alpha.reverse()
-                alpha.extend(result_array_p["alpha"].tolist())
-                cl = result_array_n["CL"].tolist()
-                cl.reverse()
-                cl.extend(result_array_p["CL"].tolist())
-                cd = result_array_n["CD"].tolist()
-                cd.reverse()
-                cd.extend(result_array_p["CD"].tolist())
-                cdp = result_array_n["CDp"].tolist()
-                cdp.reverse()
-                cdp.extend(result_array_p["CDp"].tolist())
-                cm = result_array_n["CM"].tolist()
-                cm.reverse()
-                cm.extend(result_array_p["CM"].tolist())
-            else:
-                cl_max_2d, error = self._get_max_cl(result_array_p["alpha"], result_array_p["CL"])
-                cl_min_2d, _ = self._get_min_cl(result_array_p["alpha"], result_array_p["CL"])
-                alpha = result_array_p["alpha"].tolist()
-                cl = result_array_p["CL"].tolist()
-                cd = result_array_p["CD"].tolist()
-                cdp = result_array_p["CDp"].tolist()
-                cm = result_array_p["CM"].tolist()
-
-            if not self.options["single_AoA"]:
-                if POLAR_POINT_COUNT < len(alpha):
-                    alpha_interp = np.linspace(alpha[0], alpha[-1], POLAR_POINT_COUNT)
-                    cl = np.interp(alpha_interp, alpha, cl)
-                    cd = np.interp(alpha_interp, alpha, cd)
-                    cdp = np.interp(alpha_interp, alpha, cdp)
-                    cm = np.interp(alpha_interp, alpha, cm)
-                    alpha = alpha_interp
-                    warnings.warn(
-                        "Defined polar point in fast aerodynamics\\constants.py exceeded!"
-                    )
-                else:
-                    additional_zeros = list(np.zeros(POLAR_POINT_COUNT - len(alpha)))
-                    alpha.extend(additional_zeros)
-                    alpha = np.array(alpha)
-                    cl.extend(additional_zeros)
-                    cl = np.array(cl)
-                    cd.extend(additional_zeros)
-                    cd = np.array(cd)
-                    cdp.extend(additional_zeros)
-                    cdp = np.array(cdp)
-                    cm.extend(additional_zeros)
-                    cm = np.array(cm)
+            ) = self._run_xfoil(inputs, outputs, reynolds, mach)
+
+            (
+                alpha,
+                cl,
+                cd,
+                cdp,
+                cm,
+                cl_max_2d,
+                cl_min_2d,
+                cd_min_2d,
+                error,
+            ) = self._post_processing_fill_value(result_array_p, result_array_n)
+
+            if multiple_aoa:
+                # We chose not to save the results for now when there is a single AoA
+                # Fix output length if needed
+                alpha, cl, cd, cdp, cm = self.fix_multiple_aoa_output_length(alpha, cl, cd, cdp, cm)
 
                 # Save results to defined path
                 if not error:
-                    results = [
-                        np.array(mach),
-                        np.array(reynolds),
-                        np.array(cl_max_2d),
-                        np.array(cl_min_2d),
-                        str(self._reshape(alpha, alpha).tolist()),
-                        str(self._reshape(alpha, cl).tolist()),
-                        str(self._reshape(alpha, cd).tolist()),
-                        str(self._reshape(alpha, cdp).tolist()),
-                        str(self._reshape(alpha, cm).tolist()),
-                    ]
-                    labels = [
-                        "mach",
-                        "reynolds",
-                        "cl_max_2d",
-                        "cl_min_2d",
-                        "alpha",
-                        "cl",
-                        "cd",
-                        "cdp",
-                        "cm",
-                    ]
+                    results, labels = self._give_data_labels(
+                        alpha, cl, cd, cdp, cm, cl_max_2d, cl_min_2d, cd_min_2d, mach, reynolds
+                    )
                     if no_file or (data_saved is None):
                         data = pd.DataFrame(results, index=labels)
                     else:
@@ -417,25 +202,13 @@ def compute(self, inputs, outputs):
                         data.to_csv(result_file)
                     except:
                         warnings.warn(
-                            "Unable to save XFoil results to *.csv file: writing permission denied for "
-                            "%s folder!" % local_resources.__path__[0]
+                            "Unable to save XFoil results to *.csv file: writing permission denied "
+                            "for %s folder!" % local_resources.__path__[0]
                         )
 
             # Getting output files if needed
             if self.options[OPTION_RESULT_FOLDER_PATH] != "":
-                if pth.exists(tmp_result_file_path):
-                    polar_file_path = pth.join(
-                        result_folder_path, self.options[OPTION_RESULT_POLAR_FILENAME]
-                    )
-                    shutil.move(tmp_result_file_path, polar_file_path)
-
-                if pth.exists(self.stdout):
-                    stdout_file_path = pth.join(result_folder_path, _STDOUT_FILE_NAME)
-                    shutil.move(self.stdout, stdout_file_path)
-
-                if pth.exists(self.stderr):
-                    stderr_file_path = pth.join(result_folder_path, _STDERR_FILE_NAME)
-                    shutil.move(self.stderr, stderr_file_path)
+                self._get_output_files(result_folder_path, tmp_result_file_path)
             # Try to delete the temp directory, if process not finished correctly try to
             # close files before removing directory for second attempt
             # noinspection PyBroadException
@@ -459,48 +232,18 @@ def compute(self, inputs, outputs):
                     )
 
         else:
-            # Extract results
-            cl_max_2d = np.array(
-                np.matrix(interpolated_result.loc["cl_max_2d", :].to_numpy()[0])
-            ).ravel()
-            cl_min_2d = np.array(
-                np.matrix(interpolated_result.loc["cl_min_2d", :].to_numpy()[0])
-            ).ravel()
-            ALPHA = np.array(np.matrix(interpolated_result.loc["alpha", :].to_numpy()[0])).ravel()
-            CL = np.array(np.matrix(interpolated_result.loc["cl", :].to_numpy()[0])).ravel()
-            CD = np.array(np.matrix(interpolated_result.loc["cd", :].to_numpy()[0])).ravel()
-            CDP = np.array(np.matrix(interpolated_result.loc["cdp", :].to_numpy()[0])).ravel()
-            CM = np.array(np.matrix(interpolated_result.loc["cm", :].to_numpy()[0])).ravel()
-
-            # Modify vector length if necessary
-            if POLAR_POINT_COUNT < len(ALPHA):
-                alpha = np.linspace(ALPHA[0], ALPHA[-1], POLAR_POINT_COUNT)
-                cl = np.interp(alpha, ALPHA, CL)
-                cd = np.interp(alpha, ALPHA, CD)
-                cdp = np.interp(alpha, ALPHA, CDP)
-                cm = np.interp(alpha, ALPHA, CM)
-            else:
-                additional_zeros = list(np.zeros(POLAR_POINT_COUNT - len(ALPHA)))
-                alpha = ALPHA.tolist()
-                alpha.extend(additional_zeros)
-                # noinspection PyTypeChecker
-                alpha = np.asarray(alpha)
-                cl = CL.tolist()
-                cl.extend(additional_zeros)
-                # noinspection PyTypeChecker
-                cl = np.asarray(cl)
-                cd = CD.tolist()
-                cd.extend(additional_zeros)
-                # noinspection PyTypeChecker
-                cd = np.asarray(cd)
-                cdp = CDP.tolist()
-                cdp.extend(additional_zeros)
-                # noinspection PyTypeChecker
-                cdp = np.asarray(cdp)
-                cm = CM.tolist()
-                cm.extend(additional_zeros)
-                # noinspection PyTypeChecker
-                cm = np.asarray(cm)
+            # adjust the interpolated results size for other model use
+
+            (
+                alpha,
+                cl,
+                cd,
+                cdp,
+                cm,
+                cl_max_2d,
+                cl_min_2d,
+                cd_min_2d,
+            ) = self._extract_fix_interpolated_result_length(interpolated_result)
 
         # Defining outputs -------------------------------------------------------------------------
         outputs["xfoil:alpha"] = alpha
@@ -508,9 +251,10 @@ def compute(self, inputs, outputs):
         outputs["xfoil:CD"] = cd
         outputs["xfoil:CDp"] = cdp
         outputs["xfoil:CM"] = cm
-        if not self.options["single_AoA"]:
+        if multiple_aoa:
             outputs["xfoil:CL_max_2D"] = cl_max_2d
             outputs["xfoil:CL_min_2D"] = cl_min_2d
+            outputs["xfoil:CD_min_2D"] = cd_min_2d
 
     def _write_script_file(
         self,
@@ -522,19 +266,54 @@ def _write_script_file(
         alpha_end,
         step,
     ):
+        """
+        Create command script to run XFoil for obtaining results
+
+        :param reynolds: Reynolds number
+        :param mach: Mach number
+        :param tmp_profile_file_path: temporary profile path
+        :param tmp_result_file_path: temporary result path
+        :param alpha_start: starting angle of attack in XFoil calculation
+        :param alpha_end: ending angle of attack in XFoil calculation
+        :param step: step between each angle of attack in XFoil calculation
+        """
+
         parser = InputFileGenerator()
-        with path(local_resources, _INPUT_FILE_NAME) as input_template_path:
+        inviscid = self.options["inviscid_calculation"]
+        single_aoa = self.options["single_AoA"]
+
+        # Check the computation options and select different script templates
+        if not single_aoa:
+            if inviscid:
+                input_file_name = "polar_session_inv.txt"
+            else:
+                input_file_name = "polar_session.txt"
+        else:
+            if inviscid:
+                input_file_name = "polar_session_single_AoA_inv.txt"
+            else:
+                input_file_name = "polar_session_single_AoA.txt"
+
+        # input command to run XFoil
+        with path(local_resources, input_file_name) as input_template_path:
             parser.set_template_file(str(input_template_path))
             parser.set_generated_file(self.stdin)
-            parser.mark_anchor("RE")
-            parser.transfer_var(float(reynolds), 1, 1)
+            if not inviscid:
+                parser.mark_anchor("RE")
+                parser.transfer_var(float(reynolds), 1, 1)
             parser.mark_anchor("M")
             parser.transfer_var(float(mach), 1, 1)
             parser.mark_anchor("ITER")
             parser.transfer_var(self.options[OPTION_ITER_LIMIT], 1, 1)
-            parser.mark_anchor("ASEQ")
-            parser.transfer_var(alpha_start, 1, 1)
-            parser.transfer_var(alpha_end, 2, 1)
+
+            if single_aoa:
+                parser.mark_anchor("ALFA")
+                parser.transfer_var(alpha_start, 1, 1)
+            else:
+                parser.mark_anchor("ASEQ")
+                parser.transfer_var(alpha_start, 1, 1)
+                parser.transfer_var(alpha_end, 2, 1)
+
             parser.transfer_var(step, 3, 1)
             parser.reset_anchor()
             parser.mark_anchor("/profile")
@@ -543,14 +322,13 @@ def _write_script_file(
             parser.transfer_var(tmp_result_file_path, 0, 1)
             parser.generate()
 
-    @staticmethod
-    def _read_polar(xfoil_result_file_path: str) -> np.ndarray:
+    def _read_polar(self, xfoil_result_file_path: str) -> np.ndarray:
         """
         :param xfoil_result_file_path:
         :return: numpy array with XFoil polar results
         """
         if os.path.isfile(xfoil_result_file_path):
-            dtypes = [(name, "f8") for name in XfoilPolar._xfoil_output_names]
+            dtypes = [(name, "f8") for name in self._xfoil_output_names]
             result_array = np.genfromtxt(xfoil_result_file_path, skip_header=12, dtype=dtypes)
             return result_array
 
@@ -622,13 +400,15 @@ def _reshape(x: np.ndarray, y: np.ndarray) -> np.ndarray:
 
     @staticmethod
     def _create_tmp_directory() -> TemporaryDirectory:
-        # Dev Note: XFOIL fails if length of provided file path exceeds 64 characters.
-        #           Changing working directory to the tmp dir would allow to just provide file name,
-        #           but it is not really safe (at least, it does mess with the coverage report).
-        #           Then the point is to get a tmp directory with a short path.
-        #           On Windows, the default (user-dependent) tmp dir can exceed the limit.
-        #           Therefore, as a second choice, tmp dir is created as close of user home
-        #           directory as possible.
+        """
+        Dev Note: XFOIL fails if length of provided file path exceeds 64 characters.
+        Changing working directory to the tmp dir would allow to just provide file name,
+        but it is not really safe (at least, it does mess with the coverage report).
+        Then the point is to get a tmp directory with a short path.
+        On Windows, the default (user-dependent) tmp dir can exceed the limit.
+        Therefore, as a second choice, tmp dir is created as close of user home
+        directory as possible.
+        """
         tmp_candidates = []
         for tmp_base_path in [None, pth.join(str(Path.home()), ".fast")]:
             if tmp_base_path is not None:
@@ -651,3 +431,435 @@ def _create_tmp_directory() -> TemporaryDirectory:
             )
 
         return tmp_directory
+
+    def _run_xfoil(self, inputs, outputs, reynolds, mach):
+        """
+        Run Xfoil to obtain the 2D aerodynamics of selected airfoil.
+
+        :param inputs: inputs in the OpenMDAO format
+        :param outputs: outputs in the OpenMDAO format
+        :param reynolds: Reynolds number
+        :param mach: Mach number
+
+        :return: list of results for post-processing
+        """
+
+        # Create result folder first (if it must fail, let it fail as soon as possible)
+        result_folder_path = self.options[OPTION_RESULT_FOLDER_PATH]
+        if result_folder_path != "":
+            os.makedirs(result_folder_path, exist_ok=True)
+
+        # Pre-processing (populating temp directory)
+        # XFoil exe
+        tmp_directory = self._create_tmp_directory()
+        if self.options[OPTION_XFOIL_EXE_PATH]:
+            # if a path for Xfoil has been provided, simply use it
+            self.options["command"] = [self.options[OPTION_XFOIL_EXE_PATH]]
+        else:
+            # otherwise, copy the embedded resource in tmp dir
+            # noinspection PyTypeChecker
+            copy_resource(xfoil699, XFOIL_EXE_NAME, tmp_directory.name)
+            self.options["command"] = [pth.join(tmp_directory.name, XFOIL_EXE_NAME)]
+
+        # I/O files
+        self.stdin = pth.join(tmp_directory.name, _INPUT_FILE_NAME)
+        self.stdout = pth.join(tmp_directory.name, _STDOUT_FILE_NAME)
+        self.stderr = pth.join(tmp_directory.name, _STDERR_FILE_NAME)
+
+        # profile file
+        tmp_profile_file_path = pth.join(tmp_directory.name, _TMP_PROFILE_FILE_NAME)
+        profile = get_profile(
+            airfoil_folder_path=self.options["airfoil_folder_path"],
+            file_name=self.options["airfoil_file"],
+        ).get_sides()
+        # noinspection PyTypeChecker
+        np.savetxt(
+            tmp_profile_file_path,
+            profile.to_numpy(),
+            fmt="%.15f",
+            delimiter=" ",
+            header="Wing",
+            comments="",
+        )
+
+        # standard input file
+        tmp_result_file_path = pth.join(tmp_directory.name, _TMP_RESULT_FILE_NAME)
+        self._write_script_file(
+            reynolds,
+            mach,
+            tmp_profile_file_path,
+            tmp_result_file_path,
+            self.options[OPTION_ALPHA_START],
+            self.options[OPTION_ALPHA_END],
+            ALPHA_STEP,
+        )
+
+        # Run XFOIL
+        self.options["external_input_files"] = [self.stdin, tmp_profile_file_path]
+        self.options["external_output_files"] = [tmp_result_file_path]
+        # noinspection PyBroadException
+        try:
+            super().compute(inputs, outputs)
+            result_array_p = self._read_polar(tmp_result_file_path)
+        except:
+            # catch the error and try to read result file for non-convergence on higher angles
+            error = sys.exc_info()[1]
+            try:
+                result_array_p = self._read_polar(tmp_result_file_path)
+            except:
+                raise TimeoutError("<p>Error: %s</p>" % error)
+        result_array_n = np.array([])
+
+        if self.options[OPTION_COMP_NEG_AIR_SYM]:
+            os.remove(self.stdin)
+            os.remove(self.stdout)
+            os.remove(self.stderr)
+            os.remove(tmp_result_file_path)
+            alpha_start = min(-1 * self.options[OPTION_ALPHA_START], -ALPHA_STEP)
+            self._write_script_file(
+                reynolds,
+                mach,
+                tmp_profile_file_path,
+                tmp_result_file_path,
+                alpha_start,
+                -1 * self.options[OPTION_ALPHA_END],
+                -ALPHA_STEP,
+            )
+            # noinspection PyBroadException
+            try:
+                super().compute(inputs, outputs)
+                result_array_n = self._read_polar(tmp_result_file_path)
+            except:
+                # catch the error and try to read result file for non-convergence on higher
+                # angles
+                e = sys.exc_info()[1]
+                try:
+                    result_array_n = self._read_polar(tmp_result_file_path)
+                except:
+                    raise TimeoutError("<p>Error: %s</p>" % e)
+
+        return (
+            result_array_p,
+            result_array_n,
+            result_folder_path,
+            tmp_directory,
+            tmp_result_file_path,
+        )
+
+    @staticmethod
+    def _interpolation_for_exist_data(result_file, mach, reynolds):
+        """
+        If a result file exist, we then check if the proper Mach number exists. If it does we
+        check if a Reynolds number below and above it exist, in which case we interpolate between
+        the two. Even if interpolated results can't be obtained (Reynold too low or too high),
+        if we enter this function, it means the corresponding airfoil exists ad the Xfoil run we
+        are about to do should be added to the existing results.
+
+        :return interpolated_result: the interpolated results if they exists, None otherwise.
+        :return data_saved: existing results
+        """
+
+        interpolated_result = None
+
+        data_saved = pd.read_csv(result_file)
+
+        # Pre-processing of the dataframe
+        values = data_saved.to_numpy()[:, 1 : len(data_saved.to_numpy()[0])]
+        labels = data_saved.to_numpy()[:, 0].tolist()
+        data_saved = pd.DataFrame(values, index=labels)
+
+        # Look for existing mach or one close enough
+        saved_mach_list = data_saved.loc["mach", :].to_numpy().astype(float)
+        index_near_mach = np.where(abs(saved_mach_list - mach) < 0.03)[0]
+        near_mach = []
+        distance_to_mach = []
+        # Check if there is a velocity (Mach) value that is close to this one
+        for index in index_near_mach:
+            if not saved_mach_list[index] in near_mach:
+                near_mach.append(saved_mach_list[index])
+                distance_to_mach.append(abs(saved_mach_list[index] - mach))
+        if not near_mach:
+            index_mach = np.where(data_saved.loc["mach", :].to_numpy() == str(mach))[0]
+        else:
+            selected_mach_index = distance_to_mach.index(min(distance_to_mach))
+            index_mach = np.where(saved_mach_list == near_mach[selected_mach_index])[0]
+        data_reduced = data_saved.loc[labels, index_mach]
+
+        # Search if this exact reynolds has been computed and save results
+        reynolds_vect = data_reduced.loc["reynolds", :].to_numpy().astype(float)
+
+        index_reynolds = index_mach[np.where(reynolds_vect == reynolds)]
+        if len(index_reynolds) == 1:
+            interpolated_result = data_reduced.loc[labels, index_reynolds]
+
+        # Else search for lower/upper Reynolds
+        else:
+
+            lower_reynolds = reynolds_vect[np.where(reynolds_vect < reynolds)[0]]
+            upper_reynolds = reynolds_vect[np.where(reynolds_vect > reynolds)[0]]
+
+            if not (len(lower_reynolds) == 0 or len(upper_reynolds) == 0):
+
+                index_lower_reynolds = index_mach[np.where(reynolds_vect == max(lower_reynolds))[0]]
+                index_upper_reynolds = index_mach[np.where(reynolds_vect == min(upper_reynolds))[0]]
+                lower_values = data_reduced.loc[labels, index_lower_reynolds]
+                upper_values = data_reduced.loc[labels, index_upper_reynolds]
+
+                # Initialise values with lower reynolds
+                interpolated_result = lower_values
+                # Calculate reynolds ratio split for linear interpolation
+                x_ratio = (min(upper_reynolds) - reynolds) / (
+                    min(upper_reynolds) - max(lower_reynolds)
+                )
+
+                # Search for common alpha range for linear interpolation
+                alpha_lower = list(
+                    string_to_array(lower_values.loc["alpha", index_lower_reynolds].to_numpy()[0])
+                )
+                alpha_upper = list(
+                    string_to_array(upper_values.loc["alpha", index_upper_reynolds].to_numpy()[0])
+                )
+                alpha_shared = np.array(list(set(alpha_upper).intersection(alpha_lower)))
+                interpolated_result.loc["alpha", index_lower_reynolds] = str(alpha_shared.tolist())
+
+                labels.remove("alpha")
+
+                # Calculate average values (cd, cl...) with linear interpolation
+                for label in labels:
+                    lower_value = string_to_array(
+                        lower_values.loc[label, index_lower_reynolds].to_numpy()[0]
+                    ).astype(float)
+                    upper_value = string_to_array(
+                        upper_values.loc[label, index_upper_reynolds].to_numpy()[0]
+                    ).astype(float)
+
+                    # If values relative to alpha vector, performs interpolation with shared
+                    # vector
+                    if np.size(lower_value) == len(alpha_lower):
+                        lower_value = np.interp(
+                            alpha_shared,
+                            np.array(alpha_lower),
+                            lower_value,
+                        )
+                        upper_value = np.interp(
+                            alpha_shared,
+                            np.array(alpha_upper),
+                            upper_value,
+                        )
+
+                    value = list(lower_value * x_ratio + upper_value * (1 - x_ratio))
+
+                    interpolated_result.loc[label, index_lower_reynolds] = str(value)
+
+        return interpolated_result, data_saved
+
+    def _define_result_file_path(self):
+        """
+        Each computation option (airfoil name, max AOA, single AOA, ...) will lead to unique file
+        name for stored results. We can thus check if results already exists if the file name
+        already exists. This function generate file name corresponding to the computation options.
+
+        :return result_file: path to result file if it exists
+        """
+
+        # Generate tags for the different options
+        if self.options[OPTION_COMP_NEG_AIR_SYM]:
+            negative_angle_tag = "_" + str(int(np.ceil(self.options[OPTION_ALPHA_END]))) + "S"
+        else:
+            negative_angle_tag = ""
+
+        if self.options["single_AoA"]:
+            single_aoa_tag = "_1_AOA"
+        else:
+            single_aoa_tag = ""
+
+        if self.options["inviscid_calculation"]:
+            inviscid_tag = "_inv"
+        else:
+            inviscid_tag = ""
+
+        naming = negative_angle_tag + single_aoa_tag + inviscid_tag
+
+        result_file = pth.join(
+            pth.split(os.path.realpath(__file__))[0],
+            "resources",
+            self.options["airfoil_file"].replace(".af", naming) + ".csv",
+        )
+
+        return result_file
+
+    def _post_processing_fill_value(self, result_array_p, result_array_n):
+        """
+        Prepare value for post-processing. If positive and negative angle were computed, concatenate
+        results. If only one AOA is required, max and min CL/CD will be empty.
+
+        :param result_array_p: results with positive angle of attacks
+        :param result_array_n: results with negative angle of attacks
+
+        :return: aerodynamic characteristics of the airfoil
+        """
+        if self.options["single_AoA"]:
+            alpha = result_array_p["alpha"].tolist()
+            cl = result_array_p["CL"].tolist()
+            cd = result_array_p["CD"].tolist()
+            cdp = result_array_p["CDp"].tolist()
+            cm = result_array_p["CM"].tolist()
+            cl_max_2d = []
+            cl_min_2d = []
+            cd_min_2d = []
+            error = []
+
+        elif self.options[OPTION_COMP_NEG_AIR_SYM]:
+            cl_max_2d, error = self._get_max_cl(result_array_p["alpha"], result_array_p["CL"])
+            # noinspection PyUnboundLocalVariable
+            cl_min_2d, _ = self._get_min_cl(result_array_n["alpha"], result_array_n["CL"])
+            cd_min_2d = np.min(result_array_p["CD"])
+            alpha = result_array_n["alpha"].tolist()
+            alpha.reverse()
+            alpha.extend(result_array_p["alpha"].tolist())
+            cl = result_array_n["CL"].tolist()
+            cl.reverse()
+            cl.extend(result_array_p["CL"].tolist())
+            cd = result_array_n["CD"].tolist()
+            cd.reverse()
+            cd.extend(result_array_p["CD"].tolist())
+            cdp = result_array_n["CDp"].tolist()
+            cdp.reverse()
+            cdp.extend(result_array_p["CDp"].tolist())
+            cm = result_array_n["CM"].tolist()
+            cm.reverse()
+            cm.extend(result_array_p["CM"].tolist())
+
+        else:
+            cl_max_2d, error = self._get_max_cl(result_array_p["alpha"], result_array_p["CL"])
+            cl_min_2d, _ = self._get_min_cl(result_array_p["alpha"], result_array_p["CL"])
+            cd_min_2d = np.min(result_array_p["CD"])
+            alpha = result_array_p["alpha"].tolist()
+            cl = result_array_p["CL"].tolist()
+            cd = result_array_p["CD"].tolist()
+            cdp = result_array_p["CDp"].tolist()
+            cm = result_array_p["CM"].tolist()
+
+        return alpha, cl, cd, cdp, cm, cl_max_2d, cl_min_2d, cd_min_2d, error
+
+    @staticmethod
+    def fix_multiple_aoa_output_length(alpha, cl, cd, cdp, cm):
+        """
+        Format the size of results that need to be passed as array to the size declared to
+        OpenMDAO if the original array is bigger we resize it, otherwise we complete with zeros.
+        Used when alpha, cl, cd, cdp and cm are arrays. If inside a dataframe use
+        _extract_fix_interpolated_result_length
+
+        :param alpha: angle of attach array
+        :param cl: lift coefficient array
+        :param cd: drag coefficient array
+        :param cdp: pressure drag coefficient array
+        :param cm: moment coefficient array
+
+        :return: the input array with the proper size for OpenMDAO
+        """
+
+        # use interpolation to fill missing values and add zero for values that are out of range
+        if POLAR_POINT_COUNT < len(alpha):
+            alpha_interp = np.linspace(alpha[0], alpha[-1], POLAR_POINT_COUNT)
+            cl = np.interp(alpha_interp, alpha, cl)
+            cd = np.interp(alpha_interp, alpha, cd)
+            cdp = np.interp(alpha_interp, alpha, cdp)
+            cm = np.interp(alpha_interp, alpha, cm)
+            alpha = alpha_interp
+            warnings.warn("Defined polar point in fast aerodynamics\\constants.py exceeded!")
+        else:
+            filler = np.zeros(POLAR_POINT_COUNT - len(alpha))
+            alpha = np.append(alpha, filler)
+            cl = np.append(cl, filler)
+            cd = np.append(cd, filler)
+            cdp = np.append(cdp, filler)
+            cm = np.append(cm, filler)
+
+        return alpha, cl, cd, cdp, cm
+
+    @staticmethod
+    def _extract_fix_interpolated_result_length(interpolated_result):
+        """
+        Format the size of results that need to be passed as array to the size declared to
+        OpenMDAO if the original array is bigger we resize it, otherwise we complete with zeros.
+
+        :param interpolated_result: result dataset with labels and values
+
+        :return: length-modified aerodynamic characteristic array
+        """
+
+        # Extract results
+        cl_max_2d = string_to_array(interpolated_result.loc["cl_max_2d", :].values[0])
+        cl_min_2d = string_to_array(interpolated_result.loc["cl_min_2d", :].values[0])
+        alpha = string_to_array(interpolated_result.loc["alpha", :].values[0])
+        cl = string_to_array(interpolated_result.loc["cl", :].values[0])
+        cd = string_to_array(interpolated_result.loc["cd", :].values[0])
+        cdp = string_to_array(interpolated_result.loc["cdp", :].values[0])
+        cm = string_to_array(interpolated_result.loc["cm", :].values[0])
+        cd_min_2d = np.min(cd)
+
+        # Modify vector length if necessary
+        if POLAR_POINT_COUNT < len(alpha):
+            alpha = np.linspace(alpha[0], alpha[-1], POLAR_POINT_COUNT)
+            cl = np.interp(alpha, alpha, cl)
+            cd = np.interp(alpha, alpha, cd)
+            cdp = np.interp(alpha, alpha, cdp)
+            cm = np.interp(alpha, alpha, cm)
+        else:
+            filler = np.zeros(POLAR_POINT_COUNT - len(alpha))
+            alpha = np.append(alpha, filler)
+            cl = np.append(cl, filler)
+            cd = np.append(cd, filler)
+            cdp = np.append(cdp, filler)
+            cm = np.append(cm, filler)
+
+        return alpha, cl, cd, cdp, cm, cl_max_2d, cl_min_2d, cd_min_2d
+
+    def _give_data_labels(
+        self, alpha, cl, cd, cdp, cm, cl_max_2d, cl_min_2d, cd_min_2d, mach, reynolds
+    ):
+        """
+        Five data labels and prepare list for later writing to the file
+        """
+
+        results = [
+            np.array(mach),
+            np.array(reynolds),
+            np.array(cl_max_2d),
+            np.array(cl_min_2d),
+            np.array(cd_min_2d),
+            str(self._reshape(alpha, alpha).tolist()),
+            str(self._reshape(alpha, cl).tolist()),
+            str(self._reshape(alpha, cd).tolist()),
+            str(self._reshape(alpha, cdp).tolist()),
+            str(self._reshape(alpha, cm).tolist()),
+        ]
+        labels = [
+            "mach",
+            "reynolds",
+            "cl_max_2d",
+            "cl_min_2d",
+            "cd_min_2d",
+            "alpha",
+            "cl",
+            "cd",
+            "cdp",
+            "cm",
+        ]
+        return results, labels
+
+    def _get_output_files(self, result_folder_path, tmp_result_file_path):
+        if pth.exists(tmp_result_file_path):
+            polar_file_path = pth.join(
+                result_folder_path, self.options[OPTION_RESULT_POLAR_FILENAME]
+            )
+            shutil.move(tmp_result_file_path, polar_file_path)
+
+        if pth.exists(self.stdout):
+            stdout_file_path = pth.join(result_folder_path, _STDOUT_FILE_NAME)
+            shutil.move(self.stdout, stdout_file_path)
+
+        if pth.exists(self.stderr):
+            stderr_file_path = pth.join(result_folder_path, _STDERR_FILE_NAME)
+            shutil.move(self.stderr, stderr_file_path)
diff --git a/src/fastga/models/performances/mission_vector/initialization/initialize_gamma.py b/src/fastga/models/performances/mission_vector/initialization/initialize_gamma.py
index 9eede094..27123ff6 100644
--- a/src/fastga/models/performances/mission_vector/initialization/initialize_gamma.py
+++ b/src/fastga/models/performances/mission_vector/initialization/initialize_gamma.py
@@ -56,7 +56,7 @@ def setup(self):
 
     def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None):
 
-        cruise_altitude = inputs["data:mission:sizing:main_route:cruise:altitude"]
+        cruise_altitude = np.array(inputs["data:mission:sizing:main_route:cruise:altitude"]).item()
         climb_rate_sl = float(inputs["data:mission:sizing:main_route:climb:climb_rate:sea_level"])
         climb_rate_cl = float(
             inputs["data:mission:sizing:main_route:climb:climb_rate:cruise_level"]


Test patch:
diff --git a/integration_tests/oad_process/data/oad_process_sr22.yml b/integration_tests/oad_process/data/oad_process_sr22.yml
index cdce8d70..e1f5d9e0 100644
--- a/integration_tests/oad_process/data/oad_process_sr22.yml
+++ b/integration_tests/oad_process/data/oad_process_sr22.yml
@@ -14,6 +14,7 @@ driver: om.ScipyOptimizeDriver(tol=1e-2, optimizer='COBYLA')
 model:
     propeller:
         id: fastga.aerodynamics.propeller
+        pitch_step_size: 2.5
     aircraft_sizing:
         nonlinear_solver: om.NonlinearBlockGS(maxiter=100, iprint=2, rtol=1e-3, debug_print=True, reraise_child_analysiserror=True)
         linear_solver: om.DirectSolver()
diff --git a/integration_tests/oad_process/test_oad_process.py b/integration_tests/oad_process/test_oad_process.py
index 7a3cd45a..bb9dd4ae 100644
--- a/integration_tests/oad_process/test_oad_process.py
+++ b/integration_tests/oad_process/test_oad_process.py
@@ -117,9 +117,9 @@ def test_oad_process_vlm_be76(cleanup):
     assert_allclose(problem.get_val("data:mission:sizing:fuel", units="kg"), 258.0, atol=1)
     assert_allclose(problem["data:handling_qualities:stick_fixed_static_margin"], 0.25, atol=1e-2)
     # noinspection PyTypeChecker
-    assert_allclose(problem.get_val("data:weight:aircraft:MTOW", units="kg"), 1747.0, atol=1)
+    assert_allclose(problem.get_val("data:weight:aircraft:MTOW", units="kg"), 1748.0, atol=1)
     # noinspection PyTypeChecker
-    assert_allclose(problem.get_val("data:weight:aircraft:OWE", units="kg"), 1109.0, atol=1)
+    assert_allclose(problem.get_val("data:weight:aircraft:OWE", units="kg"), 1110.0, atol=1)
 
 
 def test_oad_process_tbm_900(cleanup):
@@ -154,10 +154,10 @@ def test_oad_process_tbm_900(cleanup):
     _check_weight_performance_loop(problem)
 
     # noinspection PyTypeChecker
-    assert_allclose(problem.get_val("data:mission:sizing:fuel", units="kg"), 766.0, atol=1)
+    assert_allclose(problem.get_val("data:mission:sizing:fuel", units="kg"), 765.0, atol=1)
     assert_allclose(problem["data:handling_qualities:stick_fixed_static_margin"], 0.23, atol=1e-2)
     # noinspection PyTypeChecker
-    assert_allclose(problem.get_val("data:weight:aircraft:MTOW", units="kg"), 3360.0, atol=1)
+    assert_allclose(problem.get_val("data:weight:aircraft:MTOW", units="kg"), 3357.0, atol=1)
     # noinspection PyTypeChecker
     assert_allclose(problem.get_val("data:weight:aircraft:OWE", units="kg"), 2114.0, atol=1)
 
@@ -194,10 +194,10 @@ def test_oad_process_vlm_mission_vector(cleanup):
     _check_weight_performance_loop(problem)
 
     # noinspection PyTypeChecker
-    assert_allclose(problem.get_val("data:mission:sizing:fuel", units="kg"), 252.0, atol=1)
+    assert_allclose(problem.get_val("data:mission:sizing:fuel", units="kg"), 253.0, atol=1)
     assert_allclose(problem["data:handling_qualities:stick_fixed_static_margin"], 0.15, atol=1e-2)
     # noinspection PyTypeChecker
-    assert_allclose(problem.get_val("data:weight:aircraft:MTOW", units="kg"), 1656.0, atol=1)
+    assert_allclose(problem.get_val("data:weight:aircraft:MTOW", units="kg"), 1657.0, atol=1)
     # noinspection PyTypeChecker
     assert_allclose(problem.get_val("data:weight:aircraft:OWE", units="kg"), 1028.0, atol=1)
 
@@ -239,10 +239,10 @@ def test_oad_process_openvsp(cleanup):
 
     # Check values
     # noinspection PyTypeChecker
-    assert_allclose(problem.get_val("data:mission:sizing:fuel", units="kg"), 249.0, atol=1)
+    assert_allclose(problem.get_val("data:mission:sizing:fuel", units="kg"), 246, atol=1)
     assert_allclose(problem["data:handling_qualities:stick_fixed_static_margin"], 0.15, atol=1e-2)
     # noinspection PyTypeChecker
-    assert_allclose(problem.get_val("data:weight:aircraft:MTOW", units="kg"), 1654.0, atol=1)
+    assert_allclose(problem.get_val("data:weight:aircraft:MTOW", units="kg"), 1650.0, atol=1)
     # noinspection PyTypeChecker
     assert_allclose(problem.get_val("data:weight:aircraft:OWE", units="kg"), 1030.0, atol=1)
 
diff --git a/src/fastga/models/aerodynamics/unitary_tests/test_beechcraft_76.py b/src/fastga/models/aerodynamics/unitary_tests/test_beechcraft_76.py
index 63baf114..8019e9fd 100644
--- a/src/fastga/models/aerodynamics/unitary_tests/test_beechcraft_76.py
+++ b/src/fastga/models/aerodynamics/unitary_tests/test_beechcraft_76.py
@@ -24,10 +24,16 @@
     cd0_high_speed,
     cd0_low_speed,
     polar,
+    polar_single_aoa,
+    polar_interpolation,
+    polar_single_aoa_inv,
+    polar_ext_folder_inv,
     airfoil_slope_wt_xfoil,
     airfoil_slope_xfoil,
     comp_high_speed,
     comp_low_speed,
+    comp_low_speed_input_aoa,
+    comp_high_speed_input_aoa,
     hinge_moment_2d,
     hinge_moment_3d,
     hinge_moments,
@@ -158,6 +164,43 @@ def test_polar():
     )
 
 
+@pytest.mark.skipif(
+    system() != "Windows" and xfoil_path is None or SKIP_STEPS,
+    reason="No XFOIL executable available (or skipped)",
+)
+def test_polar_single_aoa():
+    """Tests polar execution (XFOIL) @ low speed."""
+    polar_single_aoa(
+        XML_FILE,
+        mach_low_speed=0.1179,
+        reynolds_low_speed=2746999 * 1.549,
+    )
+
+
+@pytest.mark.skipif(
+    system() != "Windows" and xfoil_path is None or SKIP_STEPS,
+    reason="No XFOIL executable available (or skipped)",
+)
+def test_polar_interpolation():
+    """Tests polar execution interpolation (XFOIL)."""
+    polar_interpolation(
+        mach=0.1179,
+    )
+
+
+@pytest.mark.skipif(
+    system() != "Windows" and xfoil_path is None or SKIP_STEPS,
+    reason="No XFOIL executable available (or skipped)",
+)
+def test_polar_single_aoa_inv():
+    """Tests polar execution (XFOIL) @ high and low speed."""
+    polar_single_aoa_inv(
+        XML_FILE,
+        mach_low_speed=0.1179,
+        reynolds_low_speed=2746999 * 1.549,
+    )
+
+
 @pytest.mark.skipif(
     system() != "Windows" and xfoil_path is None or SKIP_STEPS,
     reason="No XFOIL executable available",
@@ -176,6 +219,19 @@ def test_polar_with_ext_folder():
     )
 
 
+@pytest.mark.skipif(
+    system() != "Windows" and xfoil_path is None or SKIP_STEPS,
+    reason="No XFOIL executable available",
+)
+def test_polar_with_ext_folder_inv():
+    """Tests polar execution (XFOIL) @ high and low speed."""
+    polar_ext_folder_inv(
+        XML_FILE,
+        mach_low_speed=0.1284,
+        reynolds_low_speed=2993524,
+    )
+
+
 @pytest.mark.skipif(
     system() != "Windows" and xfoil_path is None or SKIP_STEPS,
     reason="No XFOIL executable available (or skipped)",
@@ -193,6 +249,10 @@ def test_airfoil_slope():
     )
 
 
+@pytest.mark.skipif(
+    system() != "Windows" and xfoil_path is None or SKIP_STEPS,
+    reason="No XFOIL executable available (or skipped)",
+)
 def test_airfoil_slope_wt_xfoil():
     """Tests polar reading @ low speed."""
     airfoil_slope_wt_xfoil(
@@ -229,6 +289,20 @@ def test_vlm_comp_high_speed():
     )
 
 
+@pytest.mark.skipif(
+    system() != "Windows" or SKIP_STEPS,
+    reason="No XFOIL executable available: VLM basic function not computed with "
+    "empty result folder (or skipped)",
+)
+def test_vlm_comp_high_speed_input_aoa():
+    """Tests openvsp components @ low speed."""
+
+    comp_high_speed_input_aoa(
+        XML_FILE,
+        use_openvsp=False,
+    )
+
+
 @pytest.mark.skipif(
     system() != "Windows" or SKIP_STEPS,
     reason="No XFOIL executable available: VLM basic function not computed with "
@@ -362,6 +436,20 @@ def test_vlm_comp_low_speed():
     )
 
 
+@pytest.mark.skipif(
+    system() != "Windows" or SKIP_STEPS,
+    reason="No XFOIL executable available: VLM basic function not computed with "
+    "empty result folder (or skipped)",
+)
+def test_vlm_comp_low_speed_input_aoa():
+    """Tests openvsp components @ low speed."""
+
+    comp_low_speed_input_aoa(
+        XML_FILE,
+        use_openvsp=False,
+    )
+
+
 @pytest.mark.skipif(
     system() != "Windows" or SKIP_STEPS, reason="OPENVSP is windows dependent platform (or skipped)"
 )
@@ -374,7 +462,7 @@ def test_openvsp_comp_high_speed():
         cl_ref_wing=0.81641273,
         cl_alpha_wing=4.53407067,
         cm0=-0.02583991,
-        coeff_k_wing=0.04808614,
+        coeff_k_wing=0.04361555,
         cl0_htp=-0.0052,
         cl_alpha_htp=0.60332456,
         cl_alpha_htp_isolated=0.943331,
@@ -386,6 +474,18 @@ def test_openvsp_comp_high_speed():
     )
 
 
+@pytest.mark.skipif(
+    system() != "Windows" or SKIP_STEPS, reason="OPENVSP is windows dependent platform (or skipped)"
+)
+def test_openvsp_comp_high_speed_input_aoa():
+    """Tests openvsp components @ low speed."""
+
+    comp_high_speed_input_aoa(
+        XML_FILE,
+        use_openvsp=True,
+    )
+
+
 @pytest.mark.skipif(
     system() != "Windows" or SKIP_STEPS, reason="OPENVSP is windows dependent platform (or skipped)"
 )
@@ -588,7 +688,7 @@ def test_openvsp_comp_low_speed():
         cl_ref_wing=0.80189909,
         cl_alpha_wing=4.45499105,
         cm0=-0.0252786,
-        coeff_k_wing=0.04803734,
+        coeff_k_wing=0.04357129,
         cl0_htp=-0.00506,
         cl_alpha_htp=0.59971492,
         cl_alpha_htp_isolated=0.93017298,
@@ -602,6 +702,18 @@ def test_openvsp_comp_low_speed():
     )
 
 
+@pytest.mark.skipif(
+    system() != "Windows" or SKIP_STEPS, reason="OPENVSP is windows dependent platform (or skipped)"
+)
+def test_openvsp_comp_low_speed_input_aoa():
+    """Tests openvsp components @ low speed."""
+
+    comp_low_speed_input_aoa(
+        XML_FILE,
+        use_openvsp=True,
+    )
+
+
 def test_2d_hinge_moment():
     """Tests tail hinge-moments."""
     hinge_moment_2d(XML_FILE, ch_alpha_2d=-0.4329339, ch_delta_2d=-0.63319245)
@@ -1254,41 +1366,41 @@ def test_load_factor():
 def test_propeller():
     thrust_SL = np.array(
         [
-            118.15673631,
-            310.5000776,
-            502.84341889,
-            695.18676018,
-            887.53010147,
-            1079.87344276,
-            1272.21678406,
-            1464.56012535,
-            1656.90346664,
-            1849.24680793,
-            2041.59014922,
-            2233.93349051,
-            2426.2768318,
-            2618.62017309,
-            2810.96351438,
-            3003.30685567,
-            3195.65019696,
-            3387.99353825,
-            3580.33687954,
-            3772.68022083,
-            3965.02356212,
-            4157.36690341,
-            4349.7102447,
-            4542.05358599,
-            4734.39692728,
-            4926.74026857,
-            5119.08360986,
-            5311.42695115,
-            5503.77029244,
+            281.50813308,
+            468.21866758,
+            654.92920209,
+            841.63973659,
+            1028.3502711,
+            1215.0608056,
+            1401.77134011,
+            1588.48187461,
+            1775.19240912,
+            1961.90294363,
+            2148.61347813,
+            2335.32401264,
+            2522.03454714,
+            2708.74508165,
+            2895.45561615,
+            3082.16615066,
+            3268.87668516,
+            3455.58721967,
+            3642.29775417,
+            3829.00828868,
+            4015.71882318,
+            4202.42935769,
+            4389.13989219,
+            4575.8504267,
+            4762.56096121,
+            4949.27149571,
+            5135.98203022,
+            5322.69256472,
+            5509.40309923,
             5696.11363373,
         ]
     )
     thrust_SL_limit = np.array(
         [
-            3907.31825729,
+            3909.96732951,
             4177.75124865,
             4414.4531561,
             4623.80209745,
@@ -1303,60 +1415,60 @@ def test_propeller():
     efficiency_SL = np.array(
         [
             [
-                0.05351056,
-                0.12347525,
-                0.1655366,
-                0.18736827,
-                0.19602648,
-                0.19775442,
-                0.19508082,
-                0.19063943,
-                0.18487364,
-                0.17870561,
-                0.1723861,
-                0.16619065,
-                0.16002567,
-                0.15399872,
-                0.14811737,
-                0.14224821,
-                0.1364682,
-                0.13062113,
-                0.12400109,
-                0.11464944,
-                0.09811579,
-                0.09811579,
-                0.09811579,
-                0.09811579,
-                0.09811579,
-                0.09811579,
-                0.09811579,
-                0.09811579,
-                0.09811579,
-                0.09811579,
+                0.11481833,
+                0.15851086,
+                0.18298579,
+                0.19407307,
+                0.19732919,
+                0.19595566,
+                0.19206767,
+                0.1869762,
+                0.18108355,
+                0.17501583,
+                0.16894467,
+                0.16293479,
+                0.15703208,
+                0.15119315,
+                0.14554806,
+                0.1399436,
+                0.13430438,
+                0.12834843,
+                0.12147371,
+                0.1100042,
+                0.09598577,
+                0.09598577,
+                0.09598577,
+                0.09598577,
+                0.09598577,
+                0.09598577,
+                0.09598577,
+                0.09598577,
+                0.09598577,
+                0.09598577,
             ],
             [
-                0.15212887,
-                0.31088291,
-                0.39613769,
-                0.43886415,
-                0.45704566,
-                0.46225846,
-                0.45973704,
-                0.4529451,
-                0.44392854,
-                0.43317449,
-                0.42234271,
-                0.41085589,
-                0.3996228,
-                0.38825868,
-                0.37701942,
-                0.36584575,
-                0.35464311,
-                0.34360865,
-                0.33232289,
-                0.31989642,
-                0.30413892,
-                0.2726115,
+                0.29228526,
+                0.38491963,
+                0.43201356,
+                0.45386967,
+                0.4612585,
+                0.46072763,
+                0.45519724,
+                0.44713986,
+                0.43729253,
+                0.42685449,
+                0.41594434,
+                0.40493836,
+                0.39394536,
+                0.38302247,
+                0.37202289,
+                0.36133046,
+                0.3505104,
+                0.33969028,
+                0.32849101,
+                0.31590828,
+                0.29852058,
+                0.26511387,
                 0.26511387,
                 0.26511387,
                 0.26511387,
@@ -1367,29 +1479,29 @@ def test_propeller():
                 0.26511387,
             ],
             [
-                0.23023238,
-                0.43000268,
-                0.5278268,
-                0.57425912,
-                0.59650032,
-                0.60440535,
-                0.60412381,
-                0.59945007,
-                0.59166534,
-                0.58203983,
-                0.57155435,
-                0.56038186,
-                0.54903238,
-                0.53743479,
-                0.52574809,
-                0.51393612,
-                0.5018895,
-                0.49002145,
-                0.47807279,
-                0.46540016,
-                0.45188711,
-                0.43499559,
-                0.40519931,
+                0.39445204,
+                0.50817379,
+                0.56513528,
+                0.5925015,
+                0.60272736,
+                0.6041827,
+                0.60091575,
+                0.59442654,
+                0.58575312,
+                0.57589411,
+                0.56537669,
+                0.55444607,
+                0.54329212,
+                0.53195226,
+                0.52055016,
+                0.5090512,
+                0.49734605,
+                0.48583131,
+                0.47401405,
+                0.46158032,
+                0.44770676,
+                0.42972617,
+                0.39260997,
                 0.38297328,
                 0.38297328,
                 0.38297328,
@@ -1399,30 +1511,30 @@ def test_propeller():
                 0.38297328,
             ],
             [
-                0.28761175,
-                0.50166067,
-                0.59939487,
-                0.6476175,
-                0.67085559,
-                0.68159472,
-                0.68356075,
-                0.68210814,
-                0.67661848,
-                0.66935286,
-                0.66111029,
-                0.65167786,
-                0.64210062,
-                0.63186332,
-                0.62154945,
-                0.61080021,
-                0.59999679,
-                0.58862685,
-                0.57759716,
-                0.5663487,
-                0.55396148,
-                0.54074353,
-                0.52398734,
-                0.49506023,
+                0.46022042,
+                0.57754496,
+                0.63586353,
+                0.6657085,
+                0.67959102,
+                0.68288622,
+                0.68218717,
+                0.67853964,
+                0.67221994,
+                0.66473891,
+                0.65574861,
+                0.64662482,
+                0.6369957,
+                0.62704078,
+                0.61684956,
+                0.60636335,
+                0.59567063,
+                0.58475111,
+                0.57406769,
+                0.56277604,
+                0.55051411,
+                0.536896,
+                0.51896606,
+                0.48536666,
                 0.46716978,
                 0.46716978,
                 0.46716978,
@@ -1431,31 +1543,31 @@ def test_propeller():
                 0.46716978,
             ],
             [
-                0.32069764,
-                0.541321,
-                0.63822562,
-                0.6864212,
-                0.71207749,
-                0.72433804,
-                0.72918718,
-                0.7296413,
-                0.72687497,
-                0.72216855,
-                0.71606534,
-                0.70902618,
-                0.70129704,
-                0.69300748,
-                0.68433384,
-                0.67535611,
-                0.66600112,
-                0.65628052,
-                0.64636828,
-                0.63653445,
-                0.62606511,
-                0.61444673,
-                0.60166919,
-                0.58468842,
-                0.55447484,
+                0.51603977,
+                0.61654254,
+                0.67373395,
+                0.70553702,
+                0.72217537,
+                0.72755174,
+                0.72920635,
+                0.7278833,
+                0.72412463,
+                0.71859143,
+                0.71211405,
+                0.70494927,
+                0.69722768,
+                0.68894076,
+                0.68041033,
+                0.67153613,
+                0.66231291,
+                0.65286483,
+                0.64327429,
+                0.6334608,
+                0.62311275,
+                0.61157338,
+                0.59848769,
+                0.58085838,
+                0.54694408,
                 0.52878067,
                 0.52878067,
                 0.52878067,
@@ -1463,274 +1575,272 @@ def test_propeller():
                 0.52878067,
             ],
             [
-                0.32615364,
-                0.55784211,
-                0.65564798,
-                0.70611297,
-                0.73365953,
-                0.74829785,
-                0.75625535,
-                0.75864927,
-                0.75813581,
-                0.75543376,
-                0.75120066,
-                0.74612532,
-                0.74031364,
-                0.73375519,
-                0.72685545,
-                0.71943779,
-                0.71169491,
-                0.7034785,
-                0.69523726,
-                0.68644327,
-                0.67758409,
-                0.66802486,
-                0.65729226,
-                0.64480346,
-                0.62784666,
-                0.59657543,
+                0.51376066,
+                0.64339978,
+                0.69213795,
+                0.72576516,
+                0.74479881,
+                0.75350293,
+                0.75756459,
+                0.75822471,
+                0.75651653,
+                0.75286044,
+                0.74835052,
+                0.74313423,
+                0.73703541,
+                0.73052087,
+                0.72358086,
+                0.71625161,
+                0.70859018,
+                0.70057034,
+                0.69243174,
+                0.68397381,
+                0.67507798,
+                0.66555512,
+                0.65471747,
+                0.64238183,
+                0.62453374,
+                0.59106659,
                 0.57476014,
                 0.57476014,
                 0.57476014,
                 0.57476014,
             ],
             [
-                0.32561457,
-                0.56130587,
-                0.6617216,
-                0.71441466,
-                0.74379777,
-                0.76126431,
-                0.77113823,
-                0.77613669,
-                0.77751853,
-                0.77725604,
-                0.77497526,
-                0.77139447,
-                0.76703237,
-                0.76191999,
-                0.75645111,
-                0.75055875,
-                0.7442092,
-                0.7374678,
-                0.73053459,
-                0.72316607,
-                0.71548982,
-                0.70743423,
-                0.69864038,
-                0.68831136,
-                0.67648118,
-                0.65864525,
-                0.62772564,
+                0.50196347,
+                0.64329711,
+                0.70140893,
+                0.7349125,
+                0.75642549,
+                0.76770742,
+                0.77393902,
+                0.77711801,
+                0.77738243,
+                0.77579919,
+                0.77300154,
+                0.76905762,
+                0.76440795,
+                0.75935107,
+                0.75389504,
+                0.74799043,
+                0.74166119,
+                0.73504854,
+                0.72812576,
+                0.72089568,
+                0.71337285,
+                0.70537766,
+                0.69654622,
+                0.68623366,
+                0.67429586,
+                0.65585544,
+                0.62134408,
                 0.60942032,
                 0.60942032,
                 0.60942032,
             ],
             [
-                0.33074231,
-                0.56005884,
-                0.66128982,
-                0.71591916,
-                0.74805988,
-                0.76759916,
-                0.77934301,
-                0.78623483,
-                0.78986265,
-                0.79099224,
-                0.79069427,
-                0.78891854,
-                0.78603615,
-                0.78244391,
-                0.77788408,
-                0.77320643,
-                0.76806351,
-                0.76253505,
-                0.75677387,
-                0.75063256,
-                0.74432472,
-                0.73730386,
-                0.72988231,
-                0.72174948,
-                0.71179596,
-                0.69985144,
-                0.68290923,
-                0.64882489,
+                0.49190493,
+                0.63667359,
+                0.70619582,
+                0.73788804,
+                0.76209538,
+                0.77540647,
+                0.78342062,
+                0.78877331,
+                0.79039305,
+                0.79064225,
+                0.78986781,
+                0.78733897,
+                0.78415126,
+                0.78038538,
+                0.77587299,
+                0.77104945,
+                0.76592566,
+                0.76048152,
+                0.75482113,
+                0.74886346,
+                0.74240654,
+                0.73564663,
+                0.72825023,
+                0.71996313,
+                0.71032554,
+                0.69802261,
+                0.68043235,
+                0.6422306,
                 0.63602945,
                 0.63602945,
             ],
             [
-                0.31198127,
-                0.5491285,
-                0.65730568,
-                0.7136968,
-                0.74802543,
-                0.77002801,
-                0.7838479,
-                0.79209167,
-                0.79747594,
-                0.80013123,
-                0.80117461,
-                0.80101464,
-                0.79949339,
-                0.79708448,
-                0.79415851,
-                0.79034036,
-                0.78613476,
-                0.78160823,
-                0.77673881,
-                0.77173767,
-                0.76637982,
-                0.76067214,
-                0.75425053,
-                0.74738372,
-                0.73965203,
-                0.73029931,
-                0.71848966,
-                0.70115195,
-                0.6622709,
+                0.49631709,
+                0.62596998,
+                0.70307145,
+                0.73681636,
+                0.76358553,
+                0.77918978,
+                0.78882839,
+                0.79582596,
+                0.79876075,
+                0.80062211,
+                0.80116018,
+                0.80007094,
+                0.7983172,
+                0.79574362,
+                0.7923783,
+                0.78859366,
+                0.78448534,
+                0.77984613,
+                0.77507494,
+                0.77015508,
+                0.76492467,
+                0.75927385,
+                0.75282898,
+                0.74601885,
+                0.73813678,
+                0.72905906,
+                0.71675553,
+                0.69981493,
+                0.65675128,
                 0.65675128,
             ],
             [
-                0.31671695,
-                0.53980013,
-                0.64787489,
-                0.70905619,
-                0.74527768,
-                0.76944244,
-                0.78515551,
-                0.79539174,
-                0.80223884,
-                0.80628252,
-                0.80830042,
-                0.80931701,
-                0.80913849,
-                0.80789866,
-                0.80594715,
-                0.8033943,
-                0.8002341,
-                0.7964891,
-                0.79243861,
-                0.78818161,
-                0.78375784,
-                0.77894492,
-                0.77377229,
-                0.76776127,
-                0.76139284,
-                0.75393309,
-                0.74484163,
-                0.73315728,
-                0.71673281,
+                0.52067183,
+                0.61547868,
+                0.69526392,
+                0.73309225,
+                0.76200406,
+                0.77970568,
+                0.79133394,
+                0.80003056,
+                0.80428981,
+                0.80751428,
+                0.80877268,
+                0.80908696,
+                0.80855083,
+                0.80688716,
+                0.80481125,
+                0.80206918,
+                0.79873532,
+                0.79508155,
+                0.79113451,
+                0.78688405,
+                0.78243226,
+                0.77772652,
+                0.77261264,
+                0.76665099,
+                0.76031542,
+                0.75298855,
+                0.74386389,
+                0.73205485,
+                0.71524196,
                 0.67288554,
             ],
         ]
     )
     thrust_CL = np.array(
         [
-            90.62542317,
-            233.05398451,
-            375.48254584,
-            517.91110717,
-            660.33966851,
-            802.76822984,
-            945.19679117,
-            1087.6253525,
-            1230.05391384,
-            1372.48247517,
-            1514.9110365,
-            1657.33959784,
-            1799.76815917,
-            1942.1967205,
-            2084.62528183,
-            2227.05384317,
-            2369.4824045,
-            2511.91096583,
-            2654.33952717,
-            2796.7680885,
-            2939.19664983,
-            3081.62521116,
-            3224.0537725,
-            3366.48233383,
-            3508.91089516,
-            3651.3394565,
-            3793.76801783,
-            3936.19657916,
-            4078.62514049,
+            214.78415226,
+            352.9313781,
+            491.07860395,
+            629.2258298,
+            767.37305564,
+            905.52028149,
+            1043.66750734,
+            1181.81473319,
+            1319.96195903,
+            1458.10918488,
+            1596.25641073,
+            1734.40363658,
+            1872.55086242,
+            2010.69808827,
+            2148.84531412,
+            2286.99253996,
+            2425.13976581,
+            2563.28699166,
+            2701.43421751,
+            2839.58144335,
+            2977.7286692,
+            3115.87589505,
+            3254.0231209,
+            3392.17034674,
+            3530.31757259,
+            3668.46479844,
+            3806.61202428,
+            3944.75925013,
+            4082.90647598,
             4221.05370183,
         ]
     )
     thrust_CL_limit = np.array(
-        (
-            [
-                2892.27511752,
-                3092.52843453,
-                3268.24054129,
-                3423.69146545,
-                3565.02500064,
-                3697.14844501,
-                3822.19984334,
-                3948.81792225,
-                4081.24433611,
-                4221.05370183,
-            ]
-        )
+        [
+            2893.90572693,
+            3092.52843453,
+            3268.24054129,
+            3423.69146545,
+            3565.02500064,
+            3697.14844501,
+            3822.19984334,
+            3948.81792225,
+            4081.24433611,
+            4221.05370183,
+        ]
     )
     efficiency_CL = np.array(
         [
             [
-                0.05257415,
-                0.11979227,
-                0.16096558,
-                0.18297609,
-                0.19214585,
-                0.19440941,
-                0.192262,
-                0.18819478,
-                0.18278735,
-                0.17687579,
-                0.17079108,
-                0.16476462,
-                0.15874091,
-                0.15282559,
-                0.14702722,
-                0.141222,
-                0.13547444,
-                0.12963448,
-                0.12296689,
-                0.11337435,
-                0.09681287,
-                0.09681287,
-                0.09681287,
-                0.09681287,
-                0.09681287,
-                0.09681287,
-                0.09681287,
-                0.09681287,
-                0.09681287,
-                0.09681287,
+                0.11264201,
+                0.15464073,
+                0.17883864,
+                0.19018175,
+                0.1938572,
+                0.1929139,
+                0.18943307,
+                0.18466698,
+                0.17906085,
+                0.17323259,
+                0.16734975,
+                0.16150264,
+                0.1557252,
+                0.14998988,
+                0.14442439,
+                0.13887608,
+                0.13325483,
+                0.12729098,
+                0.12031881,
+                0.10818041,
+                0.09463903,
+                0.09463903,
+                0.09463903,
+                0.09463903,
+                0.09463903,
+                0.09463903,
+                0.09463903,
+                0.09463903,
+                0.09463903,
+                0.09463903,
             ],
             [
-                0.14926816,
-                0.30255758,
-                0.3869083,
-                0.43039255,
-                0.4495968,
-                0.455774,
-                0.45421453,
-                0.44807051,
-                0.43969649,
-                0.42941572,
-                0.41899432,
-                0.40781953,
-                0.39687339,
-                0.3857249,
-                0.37467091,
-                0.3636227,
-                0.35250853,
-                0.34153471,
-                0.33026362,
-                0.31774249,
-                0.30173587,
-                0.2674251,
+                0.28765872,
+                0.37654177,
+                0.42447955,
+                0.44667293,
+                0.45466556,
+                0.45491239,
+                0.44999877,
+                0.44254,
+                0.4331936,
+                0.42319176,
+                0.41261619,
+                0.40190184,
+                0.39115897,
+                0.38044669,
+                0.36960001,
+                0.35903619,
+                0.34828187,
+                0.33752925,
+                0.32630265,
+                0.31362749,
+                0.29559765,
+                0.26221563,
                 0.26221563,
                 0.26221563,
                 0.26221563,
@@ -1741,29 +1851,29 @@ def test_propeller():
                 0.26221563,
             ],
             [
-                0.2272604,
-                0.42014606,
-                0.51750325,
-                0.56501515,
-                0.58842143,
-                0.59734449,
-                0.59801777,
-                0.59400213,
-                0.58687457,
-                0.57772152,
-                0.56764364,
-                0.5568075,
-                0.5457584,
-                0.53439755,
-                0.5229025,
-                0.51124324,
-                0.49931821,
-                0.48749642,
-                0.47559818,
-                0.46292757,
-                0.44931731,
-                0.43214163,
-                0.40096745,
+                0.38870381,
+                0.49928912,
+                0.55623818,
+                0.58437298,
+                0.59560881,
+                0.59779913,
+                0.59517731,
+                0.589261,
+                0.58109912,
+                0.57165915,
+                0.5615182,
+                0.55087169,
+                0.53998958,
+                0.52886476,
+                0.51764602,
+                0.5062978,
+                0.49468411,
+                0.48321499,
+                0.47144341,
+                0.45897933,
+                0.44498075,
+                0.42661665,
+                0.38700306,
                 0.37920128,
                 0.37920128,
                 0.37920128,
@@ -1773,30 +1883,30 @@ def test_propeller():
                 0.37920128,
             ],
             [
-                0.28258325,
-                0.49152952,
-                0.58941955,
-                0.6387258,
-                0.66303983,
-                0.67480876,
-                0.67749572,
-                0.67675665,
-                0.67183388,
-                0.66497311,
-                0.65715631,
-                0.64799263,
-                0.63870722,
-                0.62869586,
-                0.61856311,
-                0.60796659,
-                0.59728514,
-                0.58596093,
-                0.57500529,
-                0.56378502,
-                0.55135094,
-                0.53802846,
-                0.52095436,
-                0.49114681,
+                0.45656603,
+                0.56929127,
+                0.6274439,
+                0.65798458,
+                0.67274706,
+                0.67663431,
+                0.67656013,
+                0.67347415,
+                0.66759399,
+                0.66046872,
+                0.6518014,
+                0.64296386,
+                0.63358328,
+                0.62382533,
+                0.61380437,
+                0.60346078,
+                0.59286734,
+                0.58201317,
+                0.57139602,
+                0.56010787,
+                0.54779089,
+                0.53402689,
+                0.51563085,
+                0.47988445,
                 0.46287248,
                 0.46287248,
                 0.46287248,
@@ -1805,31 +1915,31 @@ def test_propeller():
                 0.46287248,
             ],
             [
-                0.3169378,
-                0.53166132,
-                0.62885052,
-                0.67806778,
-                0.70471403,
-                0.71790601,
-                0.72341201,
-                0.72451657,
-                0.72224434,
-                0.71790192,
-                0.71216668,
-                0.70539743,
-                0.69790546,
-                0.68983891,
-                0.68133038,
-                0.67249712,
-                0.6632631,
-                0.65361981,
-                0.64377054,
-                0.63394701,
-                0.62348395,
-                0.61179762,
-                0.59892232,
-                0.58155994,
-                0.55010639,
+                0.50876069,
+                0.60935459,
+                0.66598059,
+                0.69832916,
+                0.71575158,
+                0.72167346,
+                0.7238545,
+                0.72301644,
+                0.71964616,
+                0.71444896,
+                0.70826051,
+                0.70133926,
+                0.69384331,
+                0.68574675,
+                0.67737123,
+                0.66862466,
+                0.65951821,
+                0.65012897,
+                0.6405707,
+                0.63078975,
+                0.62043663,
+                0.60882453,
+                0.59554171,
+                0.57750498,
+                0.5418194,
                 0.52411352,
                 0.52411352,
                 0.52411352,
@@ -1837,163 +1947,163 @@ def test_propeller():
                 0.52411352,
             ],
             [
-                0.32353556,
-                0.54884734,
-                0.64681185,
-                0.69816534,
-                0.72670374,
-                0.74206723,
-                0.75071338,
-                0.75368305,
-                0.75361529,
-                0.75128918,
-                0.74738236,
-                0.74253023,
-                0.7369738,
-                0.73059401,
-                0.72386936,
-                0.71658765,
-                0.70896539,
-                0.7008357,
-                0.69263774,
-                0.68385797,
-                0.67504122,
-                0.66544948,
-                0.65464611,
-                0.641931,
-                0.62457278,
-                0.59191798,
+                0.5086281,
+                0.63577424,
+                0.68500802,
+                0.71903777,
+                0.73872235,
+                0.74790903,
+                0.75246848,
+                0.75355133,
+                0.75215935,
+                0.74882911,
+                0.74459332,
+                0.73961608,
+                0.73370068,
+                0.72735333,
+                0.72056863,
+                0.71336973,
+                0.70581091,
+                0.69784471,
+                0.68978114,
+                0.68135209,
+                0.67245494,
+                0.66291037,
+                0.65196617,
+                0.6394427,
+                0.62108936,
+                0.58546456,
                 0.56983154,
                 0.56983154,
                 0.56983154,
                 0.56983154,
             ],
             [
-                0.32338264,
-                0.55300397,
-                0.65338506,
-                0.70692798,
-                0.73716818,
-                0.75526264,
-                0.76572501,
-                0.77124892,
-                0.77302957,
-                0.77312801,
-                0.77115456,
-                0.76784993,
-                0.76369383,
-                0.75879055,
-                0.75345259,
-                0.74770606,
-                0.7414678,
-                0.7348289,
-                0.72792545,
-                0.72059014,
-                0.71296217,
-                0.70490419,
-                0.69607696,
-                0.68567164,
-                0.67359105,
-                0.65535684,
-                0.62288359,
+                0.49904387,
+                0.63643231,
+                0.69465593,
+                0.72850979,
+                0.75054973,
+                0.76225725,
+                0.7689854,
+                0.7725744,
+                0.77309678,
+                0.77182345,
+                0.76929998,
+                0.7655531,
+                0.76110058,
+                0.75621659,
+                0.75091091,
+                0.74510802,
+                0.73889308,
+                0.73234744,
+                0.7254713,
+                0.71828569,
+                0.71078927,
+                0.70278288,
+                0.6939,
+                0.68345516,
+                0.67137799,
+                0.65236627,
+                0.61560986,
                 0.60425046,
                 0.60425046,
                 0.60425046,
             ],
             [
-                0.32863484,
-                0.55167925,
-                0.65307233,
-                0.70855423,
-                0.74143156,
-                0.76170944,
-                0.77393145,
-                0.78132021,
-                0.78538012,
-                0.78685849,
-                0.78683111,
-                0.78533997,
-                0.78267127,
-                0.77927545,
-                0.77487478,
-                0.77031219,
-                0.76529027,
-                0.75987303,
-                0.75414226,
-                0.74805849,
-                0.74181818,
-                0.73476803,
-                0.72737216,
-                0.71915874,
-                0.70904889,
-                0.6969101,
-                0.67936002,
-                0.64335958,
+                0.49075864,
+                0.63035812,
+                0.69945409,
+                0.73165165,
+                0.75634336,
+                0.76999841,
+                0.77849992,
+                0.78425478,
+                0.78611765,
+                0.78667526,
+                0.78617227,
+                0.78382325,
+                0.78084366,
+                0.77725398,
+                0.77285514,
+                0.7681551,
+                0.76314379,
+                0.75777834,
+                0.75217291,
+                0.74624524,
+                0.73982982,
+                0.73306533,
+                0.72565307,
+                0.71732414,
+                0.70754858,
+                0.6950077,
+                0.67675746,
+                0.63527555,
                 0.63060161,
                 0.63060161,
             ],
             [
-                0.31057148,
-                0.54154904,
-                0.6496374,
-                0.70616132,
-                0.74131582,
-                0.76409586,
-                0.77833761,
-                0.78708837,
-                0.79288785,
-                0.79594933,
-                0.79721747,
-                0.79730933,
-                0.79603582,
-                0.79380921,
-                0.79105327,
-                0.78741428,
-                0.78328362,
-                0.77888976,
-                0.77404434,
-                0.76914398,
-                0.7638046,
-                0.75812719,
-                0.75174459,
-                0.7448244,
-                0.7370901,
-                0.72755628,
-                0.71551339,
-                0.69761567,
-                0.65622207,
+                0.495229,
+                0.62000354,
+                0.69678401,
+                0.73055538,
+                0.75784792,
+                0.77369513,
+                0.78387097,
+                0.79127123,
+                0.79441528,
+                0.79660353,
+                0.7973098,
+                0.79649126,
+                0.79494974,
+                0.79249243,
+                0.78930383,
+                0.78565044,
+                0.78162948,
+                0.77708359,
+                0.77237175,
+                0.7675294,
+                0.7623227,
+                0.75668361,
+                0.75026337,
+                0.74341128,
+                0.73547675,
+                0.72625209,
+                0.71369156,
+                0.69627214,
+                0.65105509,
                 0.65105509,
             ],
             [
-                0.31571388,
-                0.53176652,
-                0.639908,
-                0.70145019,
-                0.73835971,
-                0.76331659,
-                0.77943871,
-                0.79020517,
-                0.79750604,
-                0.80185271,
-                0.80419706,
-                0.80545482,
-                0.80555951,
-                0.80447942,
-                0.80270285,
-                0.80031786,
-                0.79728609,
-                0.79368892,
-                0.789671,
-                0.78551172,
-                0.78109309,
-                0.77636061,
-                0.77120532,
-                0.76522801,
-                0.75880436,
-                0.75126506,
-                0.74219109,
-                0.73019016,
-                0.7129783,
+                0.51663834,
+                0.60945865,
+                0.68897227,
+                0.72661533,
+                0.7561824,
+                0.77400467,
+                0.78622124,
+                0.79508451,
+                0.79980267,
+                0.80337701,
+                0.80478667,
+                0.80537813,
+                0.80498079,
+                0.80353581,
+                0.80164508,
+                0.79899565,
+                0.79581385,
+                0.79226857,
+                0.78835197,
+                0.7841637,
+                0.77976851,
+                0.7751211,
+                0.77004135,
+                0.7640504,
+                0.7576655,
+                0.7502525,
+                0.74112058,
+                0.72893318,
+                0.71158236,
                 0.66692487,
             ],
         ]
diff --git a/src/fastga/models/aerodynamics/unitary_tests/test_cirrus_sr22.py b/src/fastga/models/aerodynamics/unitary_tests/test_cirrus_sr22.py
index 1b41bc85..f1444cc1 100644
--- a/src/fastga/models/aerodynamics/unitary_tests/test_cirrus_sr22.py
+++ b/src/fastga/models/aerodynamics/unitary_tests/test_cirrus_sr22.py
@@ -24,10 +24,14 @@
     cd0_high_speed,
     cd0_low_speed,
     polar,
+    polar_single_aoa,
+    polar_single_aoa_inv,
     airfoil_slope_wt_xfoil,
     airfoil_slope_xfoil,
     comp_high_speed,
     comp_low_speed,
+    comp_high_speed_input_aoa,
+    comp_low_speed_input_aoa,
     hinge_moment_2d,
     hinge_moment_3d,
     hinge_moments,
@@ -157,6 +161,32 @@ def test_polar():
     )
 
 
+@pytest.mark.skipif(
+    system() != "Windows" and xfoil_path is None or SKIP_STEPS,
+    reason="No XFOIL executable available (or skipped)",
+)
+def test_polar_single_aoa():
+    """Tests polar execution (XFOIL) @ low speed."""
+    polar_single_aoa(
+        XML_FILE,
+        mach_low_speed=0.1179,
+        reynolds_low_speed=2746999 * 1.549,
+    )
+
+
+@pytest.mark.skipif(
+    system() != "Windows" and xfoil_path is None or SKIP_STEPS,
+    reason="No XFOIL executable available (or skipped)",
+)
+def test_polar_single_aoa_inv():
+    """Tests polar execution (XFOIL) @ low speed."""
+    polar_single_aoa_inv(
+        XML_FILE,
+        mach_low_speed=0.1179,
+        reynolds_low_speed=2746999 * 1.549,
+    )
+
+
 @pytest.mark.skipif(
     system() != "Windows" and xfoil_path is None or SKIP_STEPS,
     reason="No XFOIL executable available",
@@ -192,6 +222,10 @@ def test_airfoil_slope():
     )
 
 
+@pytest.mark.skipif(
+    system() != "Windows" and xfoil_path is None or SKIP_STEPS,
+    reason="No XFOIL executable available (or skipped)",
+)
 def test_airfoil_slope_wt_xfoil():
     """Tests polar reading @ low speed!"""
     airfoil_slope_wt_xfoil(
@@ -228,6 +262,20 @@ def test_vlm_comp_high_speed():
     )
 
 
+@pytest.mark.skipif(
+    system() != "Windows" or SKIP_STEPS,
+    reason="No XFOIL executable available: VLM basic function not computed with "
+    "empty result folder (or skipped)",
+)
+def test_vlm_comp_high_speed_input_aoa():
+    """Tests openvsp components @ low speed."""
+
+    comp_high_speed_input_aoa(
+        XML_FILE,
+        use_openvsp=False,
+    )
+
+
 @pytest.mark.skipif(
     system() != "Windows" or SKIP_STEPS,
     reason="No XFOIL executable available: VLM basic function not computed with "
@@ -361,6 +409,20 @@ def test_vlm_comp_low_speed():
     )
 
 
+@pytest.mark.skipif(
+    system() != "Windows" or SKIP_STEPS,
+    reason="No XFOIL executable available: VLM basic function not computed with "
+    "empty result folder (or skipped)",
+)
+def test_vlm_comp_low_speed_input_aoa():
+    """Tests openvsp components @ low speed."""
+
+    comp_low_speed_input_aoa(
+        XML_FILE,
+        use_openvsp=False,
+    )
+
+
 @pytest.mark.skipif(
     system() != "Windows" or SKIP_STEPS, reason="OPENVSP is windows dependent platform (or skipped)"
 )
@@ -373,7 +435,7 @@ def test_openvsp_comp_high_speed():
         cl_ref_wing=1.01371823,
         cl_alpha_wing=5.08046827,
         cm0=-0.0271461,
-        coeff_k_wing=0.03820337,
+        coeff_k_wing=0.03465158,
         cl0_htp=-0.00758,
         cl_alpha_htp=0.50460393,
         cl_alpha_htp_isolated=0.939527,
@@ -385,6 +447,18 @@ def test_openvsp_comp_high_speed():
     )
 
 
+@pytest.mark.skipif(
+    system() != "Windows" or SKIP_STEPS, reason="OPENVSP is windows dependent platform (or skipped)"
+)
+def test_openvsp_comp_high_speed_input_aoa():
+    """Tests openvsp components @ low speed."""
+
+    comp_high_speed_input_aoa(
+        XML_FILE,
+        use_openvsp=True,
+    )
+
+
 @pytest.mark.skipif(
     system() != "Windows" or SKIP_STEPS, reason="OPENVSP is windows dependent platform (or skipped)"
 )
@@ -582,7 +656,7 @@ def test_openvsp_comp_low_speed():
         cl_ref_wing=0.99389998,
         cl_alpha_wing=4.98208104,
         cm0=-0.02652458,
-        coeff_k_wing=0.03816438,
+        coeff_k_wing=0.03461622,
         cl0_htp=-0.00734,
         cl_alpha_htp=0.50042134,
         cl_alpha_htp_isolated=0.92249372,
@@ -596,6 +670,18 @@ def test_openvsp_comp_low_speed():
     )
 
 
+@pytest.mark.skipif(
+    system() != "Windows" or SKIP_STEPS, reason="OPENVSP is windows dependent platform (or skipped)"
+)
+def test_openvsp_comp_low_speed_input_aoa():
+    """Tests openvsp components @ low speed."""
+
+    comp_low_speed_input_aoa(
+        XML_FILE,
+        use_openvsp=True,
+    )
+
+
 def test_2d_hinge_moment():
     """Tests tail hinge-moments."""
     hinge_moment_2d(XML_FILE, ch_alpha_2d=-0.3548, ch_delta_2d=-0.5755)
diff --git a/src/fastga/models/aerodynamics/unitary_tests/test_daher_tbm900.py b/src/fastga/models/aerodynamics/unitary_tests/test_daher_tbm900.py
index 8d68428c..6b95eb43 100644
--- a/src/fastga/models/aerodynamics/unitary_tests/test_daher_tbm900.py
+++ b/src/fastga/models/aerodynamics/unitary_tests/test_daher_tbm900.py
@@ -24,6 +24,8 @@
     cd0_high_speed,
     cd0_low_speed,
     polar,
+    polar_single_aoa,
+    polar_single_aoa_inv,
     airfoil_slope_wt_xfoil,
     airfoil_slope_xfoil,
     comp_high_speed,
@@ -158,6 +160,32 @@ def test_polar():
     )
 
 
+@pytest.mark.skipif(
+    system() != "Windows" and xfoil_path is None or SKIP_STEPS,
+    reason="No XFOIL executable available (or skipped)",
+)
+def test_polar_single_aoa():
+    """Tests polar execution (XFOIL) @ low speed."""
+    polar_single_aoa(
+        XML_FILE,
+        mach_low_speed=0.1284,
+        reynolds_low_speed=2993524,
+    )
+
+
+@pytest.mark.skipif(
+    system() != "Windows" and xfoil_path is None or SKIP_STEPS,
+    reason="No XFOIL executable available (or skipped)",
+)
+def test_polar_single_aoa_inv():
+    """Tests polar execution (XFOIL) @ high and low speed."""
+    polar_single_aoa_inv(
+        XML_FILE,
+        mach_low_speed=0.1284,
+        reynolds_low_speed=2993524,
+    )
+
+
 @pytest.mark.skipif(
     system() != "Windows" and xfoil_path is None or SKIP_STEPS,
     reason="No XFOIL executable available",
@@ -193,6 +221,10 @@ def test_airfoil_slope():
     )
 
 
+@pytest.mark.skipif(
+    system() != "Windows" and xfoil_path is None or SKIP_STEPS,
+    reason="No XFOIL executable available (or skipped)",
+)
 def test_airfoil_slope_wt_xfoil():
     """Tests polar reading @ low speed."""
     airfoil_slope_wt_xfoil(
@@ -375,7 +407,7 @@ def test_openvsp_comp_high_speed():
         cl_ref_wing=0.99980785,
         cl_alpha_wing=5.26725348,
         cm0=-0.03043512,
-        coeff_k_wing=0.04715152,
+        coeff_k_wing=0.04276782,
         cl0_htp=-0.01313,
         cl_alpha_htp=0.65987549,
         cl_alpha_htp_isolated=1.35235907,
@@ -584,7 +616,7 @@ def test_openvsp_comp_low_speed():
         cl_ref_wing=0.88722998,
         cl_alpha_wing=4.6824243,
         cm0=-0.02618463,
-        coeff_k_wing=0.0467615,
+        coeff_k_wing=0.04241406,
         cl0_htp=-0.01092,
         cl_alpha_htp=0.64939037,
         cl_alpha_htp_isolated=1.20916995,
@@ -1241,36 +1273,36 @@ def test_load_factor():
 def test_propeller():
     thrust_SL = np.array(
         [
-            514.2204107,
-            1535.78395058,
-            2557.34749045,
-            3578.91103032,
-            4600.4745702,
-            5622.03811007,
-            6643.60164994,
-            7665.16518982,
-            8686.72872969,
-            9708.29226956,
-            10729.85580943,
-            11751.41934931,
-            12772.98288918,
-            13794.54642905,
-            14816.10996893,
-            15837.6735088,
-            16859.23704867,
-            17880.80058855,
-            18902.36412842,
-            19923.92766829,
-            20945.49120816,
-            21967.05474804,
-            22988.61828791,
-            24010.18182778,
-            25031.74536766,
-            26053.30890753,
-            27074.8724474,
-            28096.43598728,
-            29117.99952715,
-            30139.56306702,
+            1619.09853324,
+            2602.82704064,
+            3586.55554805,
+            4570.28405545,
+            5554.01256285,
+            6537.74107026,
+            7521.46957766,
+            8505.19808506,
+            9488.92659247,
+            10472.65509987,
+            11456.38360727,
+            12440.11211468,
+            13423.84062208,
+            14407.56912948,
+            15391.29763689,
+            16375.02614429,
+            17358.75465169,
+            18342.4831591,
+            19326.2116665,
+            20309.9401739,
+            21293.66868131,
+            22277.39718871,
+            23261.12569611,
+            24244.85420352,
+            25228.58271092,
+            26212.31121832,
+            27196.03972573,
+            28179.76823313,
+            29163.49674053,
+            30147.22524794,
         ]
     )
     thrust_SL_limit = np.array(
@@ -1279,29 +1311,29 @@ def test_propeller():
             14452.03746608,
             16361.14103439,
             18127.72811316,
-            19830.77998727,
-            21624.1966522,
-            23535.53147827,
-            25569.30975885,
-            27796.04974286,
-            30139.56306702,
+            19829.48638845,
+            21615.24341967,
+            23527.81586163,
+            25566.66895535,
+            27775.34315136,
+            30147.22524794,
         ]
     )
     efficiency_SL = np.array(
         [
             [
-                0.06268934,
-                0.13350106,
-                0.15124139,
-                0.14880385,
-                0.14046632,
-                0.13121184,
-                0.12219378,
-                0.11385834,
-                0.10624182,
-                0.09918256,
-                0.09256645,
-                0.0859352,
+                0.13570735,
+                0.15106952,
+                0.1486958,
+                0.14073689,
+                0.13184291,
+                0.123116,
+                0.11499258,
+                0.10754134,
+                0.10066374,
+                0.09420358,
+                0.08791837,
+                0.08032182,
                 0.07714809,
                 0.07714809,
                 0.07714809,
@@ -1322,20 +1354,20 @@ def test_propeller():
                 0.07714809,
             ],
             [
-                0.26960116,
-                0.4833758,
-                0.53548431,
-                0.53645756,
-                0.52098868,
-                0.50010553,
-                0.47764496,
-                0.4557525,
-                0.43495506,
-                0.41513241,
-                0.39617339,
-                0.37803318,
-                0.36019558,
-                0.34075111,
+                0.49086071,
+                0.53574852,
+                0.53605402,
+                0.52145497,
+                0.50157065,
+                0.47995812,
+                0.45882415,
+                0.43863121,
+                0.41931143,
+                0.40089268,
+                0.38317133,
+                0.36612626,
+                0.34837845,
+                0.32371967,
                 0.32210935,
                 0.32210935,
                 0.32210935,
@@ -1354,22 +1386,22 @@ def test_propeller():
                 0.32210935,
             ],
             [
-                0.39692462,
-                0.62802538,
-                0.68526128,
-                0.69387247,
-                0.68506288,
-                0.67012715,
-                0.65137409,
-                0.63214575,
-                0.61257988,
-                0.59336546,
-                0.57456598,
-                0.55609898,
-                0.53780758,
-                0.51992797,
-                0.5009556,
-                0.47715458,
+                0.63628586,
+                0.68407107,
+                0.69383579,
+                0.68540138,
+                0.671207,
+                0.65337285,
+                0.63490542,
+                0.61599581,
+                0.59748463,
+                0.57928448,
+                0.56140313,
+                0.54367468,
+                0.52648251,
+                0.5086539,
+                0.48885733,
+                0.453276,
                 0.453276,
                 0.453276,
                 0.453276,
@@ -1386,24 +1418,24 @@ def test_propeller():
                 0.453276,
             ],
             [
-                0.43839235,
-                0.67813935,
-                0.74059736,
-                0.75746823,
-                0.75697371,
-                0.74898236,
-                0.73711288,
-                0.72311714,
-                0.70828415,
-                0.69290688,
-                0.67752152,
-                0.66192717,
-                0.64628267,
-                0.63071754,
-                0.61503052,
-                0.59851886,
-                0.57975543,
-                0.54839456,
+                0.68317267,
+                0.73934389,
+                0.75653735,
+                0.7571197,
+                0.74961593,
+                0.73826701,
+                0.72513254,
+                0.71087643,
+                0.69624596,
+                0.68138942,
+                0.66642509,
+                0.65143485,
+                0.636374,
+                0.62134979,
+                0.60591193,
+                0.58906629,
+                0.56758262,
+                0.52783961,
                 0.52783961,
                 0.52783961,
                 0.52783961,
@@ -1418,231 +1450,231 @@ def test_propeller():
                 0.52783961,
             ],
             [
-                0.44093012,
-                0.68810282,
-                0.75793588,
-                0.78273516,
-                0.78921313,
-                0.78777122,
-                0.78134433,
-                0.77275688,
-                0.76228855,
-                0.75100335,
-                0.73911183,
-                0.72690827,
-                0.71436443,
-                0.70150011,
-                0.6885878,
-                0.67529536,
-                0.66139407,
-                0.64590332,
-                0.62636703,
-                0.57987099,
-                0.57987099,
-                0.57987099,
-                0.57987099,
-                0.57987099,
-                0.57987099,
-                0.57987099,
-                0.57987099,
-                0.57987099,
-                0.57987099,
-                0.57987099,
+                0.68638823,
+                0.75623255,
+                0.78148109,
+                0.78884328,
+                0.78798731,
+                0.78218123,
+                0.77392035,
+                0.76417658,
+                0.75345291,
+                0.742126,
+                0.73046688,
+                0.71845837,
+                0.70620402,
+                0.6937825,
+                0.68121266,
+                0.6681134,
+                0.65418756,
+                0.63783862,
+                0.61382019,
+                0.57936623,
+                0.57936623,
+                0.57936623,
+                0.57936623,
+                0.57936623,
+                0.57936623,
+                0.57936623,
+                0.57936623,
+                0.57936623,
+                0.57936623,
+                0.57936623,
             ],
             [
-                0.42572439,
-                0.6808189,
-                0.75936425,
-                0.79128769,
-                0.80371642,
-                0.80731003,
-                0.80572445,
-                0.80099433,
-                0.79449617,
-                0.78667394,
-                0.77789638,
-                0.76852196,
-                0.75869622,
-                0.74853284,
-                0.73791275,
-                0.72715887,
-                0.71614356,
-                0.70434062,
-                0.69178903,
-                0.67685161,
-                0.65523735,
-                0.62020807,
-                0.62020807,
-                0.62020807,
-                0.62020807,
-                0.62020807,
-                0.62020807,
-                0.62020807,
-                0.62020807,
-                0.62020807,
+                0.68877265,
+                0.76114212,
+                0.79139152,
+                0.80340228,
+                0.80708426,
+                0.80591733,
+                0.80168953,
+                0.79567902,
+                0.78838095,
+                0.7801391,
+                0.77127693,
+                0.76191848,
+                0.75227699,
+                0.74222554,
+                0.73188952,
+                0.72140288,
+                0.71042605,
+                0.69876636,
+                0.68597997,
+                0.66988957,
+                0.6433912,
+                0.6216385,
+                0.6216385,
+                0.6216385,
+                0.6216385,
+                0.6216385,
+                0.6216385,
+                0.6216385,
+                0.6216385,
+                0.6216385,
             ],
             [
-                0.40280863,
-                0.66638953,
-                0.75293675,
-                0.79096884,
-                0.80901759,
-                0.81678664,
-                0.81895379,
-                0.81772708,
-                0.81418424,
-                0.80913663,
-                0.80309676,
-                0.79610352,
-                0.78855824,
-                0.78050145,
-                0.77215527,
-                0.76329914,
-                0.75428123,
-                0.744909,
-                0.73505882,
-                0.72438969,
-                0.7127915,
-                0.69825585,
-                0.67706437,
-                0.64359819,
-                0.64359819,
-                0.64359819,
-                0.64359819,
-                0.64359819,
-                0.64359819,
-                0.64359819,
+                0.65818804,
+                0.74866759,
+                0.78883082,
+                0.80765768,
+                0.81638988,
+                0.8187754,
+                0.81781098,
+                0.81468138,
+                0.81016684,
+                0.80462498,
+                0.79814705,
+                0.79102045,
+                0.7835012,
+                0.77552978,
+                0.76725202,
+                0.75855161,
+                0.74968923,
+                0.7405345,
+                0.73066572,
+                0.72013319,
+                0.7081813,
+                0.6926135,
+                0.66627085,
+                0.64455868,
+                0.64455868,
+                0.64455868,
+                0.64455868,
+                0.64455868,
+                0.64455868,
+                0.64455868,
             ],
             [
-                0.3792615,
-                0.64814155,
-                0.74164501,
-                0.78578839,
-                0.80819361,
-                0.81980821,
-                0.82518457,
-                0.82671003,
-                0.82592405,
-                0.82322709,
-                0.81917973,
-                0.81446503,
-                0.80880368,
-                0.80251485,
-                0.79599755,
-                0.78887916,
-                0.78153444,
-                0.77371036,
-                0.76576694,
-                0.75747299,
-                0.74854376,
-                0.73878524,
-                0.72803671,
-                0.71449283,
-                0.69400003,
-                0.66273073,
-                0.66273073,
-                0.66273073,
-                0.66273073,
-                0.66273073,
+                0.63895133,
+                0.74147953,
+                0.78407232,
+                0.80558896,
+                0.81814227,
+                0.82465119,
+                0.82639728,
+                0.82588777,
+                0.82375198,
+                0.82014037,
+                0.81585385,
+                0.81061492,
+                0.80482023,
+                0.79859641,
+                0.79198909,
+                0.78508085,
+                0.77771636,
+                0.77017312,
+                0.7623335,
+                0.75412308,
+                0.74525184,
+                0.73571908,
+                0.72466562,
+                0.710447,
+                0.68712086,
+                0.65989749,
+                0.65989749,
+                0.65989749,
+                0.65989749,
+                0.65989749,
             ],
             [
-                0.37144162,
-                0.62755811,
-                0.72622209,
-                0.7753951,
-                0.80198993,
-                0.81694045,
-                0.82577559,
-                0.82995477,
-                0.83131511,
-                0.83090759,
-                0.828885,
-                0.82553564,
-                0.82189984,
-                0.81728407,
-                0.81205333,
-                0.80663593,
-                0.80064911,
-                0.79438711,
-                0.7878645,
-                0.78084178,
-                0.77375844,
-                0.76627133,
-                0.75822326,
-                0.74926348,
-                0.73951055,
-                0.7275205,
-                0.70969473,
-                0.67700305,
-                0.67700305,
-                0.67700305,
+                0.62699198,
+                0.72104764,
+                0.77024112,
+                0.80077678,
+                0.81502794,
+                0.82392585,
+                0.82951724,
+                0.83077812,
+                0.83074618,
+                0.82960826,
+                0.82647097,
+                0.82294382,
+                0.81905397,
+                0.81411439,
+                0.80897178,
+                0.80354558,
+                0.79756561,
+                0.79144877,
+                0.78493336,
+                0.77814803,
+                0.77120581,
+                0.76387318,
+                0.75587905,
+                0.74706524,
+                0.73722947,
+                0.72519168,
+                0.70627209,
+                0.67974103,
+                0.67974103,
+                0.67974103,
             ],
             [
-                0.3118491,
-                0.59748583,
-                0.70560858,
-                0.75873146,
-                0.79020556,
-                0.80869589,
-                0.82016028,
-                0.82729559,
-                0.83095838,
-                0.83238514,
-                0.83224541,
-                0.83103328,
-                0.82843586,
-                0.82539958,
-                0.8218673,
-                0.81768462,
-                0.81302208,
-                0.80815502,
-                0.8028398,
-                0.79728014,
-                0.79146556,
-                0.78516583,
-                0.77885831,
-                0.77203601,
-                0.76490485,
-                0.75685161,
-                0.74809396,
-                0.7376948,
-                0.72311432,
-                0.69058815,
+                0.6144616,
+                0.69134058,
+                0.75716697,
+                0.78525393,
+                0.80610881,
+                0.81817152,
+                0.8254837,
+                0.83021363,
+                0.83166414,
+                0.83234654,
+                0.83110742,
+                0.82934953,
+                0.8265146,
+                0.82316047,
+                0.81954338,
+                0.81515891,
+                0.81060329,
+                0.80580983,
+                0.80053893,
+                0.7950676,
+                0.78940613,
+                0.78327861,
+                0.77694646,
+                0.77036819,
+                0.76334488,
+                0.75549931,
+                0.74685472,
+                0.73653179,
+                0.72229007,
+                0.68542609,
             ],
         ]
     )
     thrust_CL = np.array(
         [
-            202.47447884,
-            626.21849655,
-            1049.96251426,
-            1473.70653197,
-            1897.45054968,
-            2321.19456739,
-            2744.9385851,
-            3168.68260281,
-            3592.42662052,
-            4016.17063823,
-            4439.91465594,
-            4863.65867366,
-            5287.40269137,
-            5711.14670908,
-            6134.89072679,
-            6558.6347445,
-            6982.37876221,
-            7406.12277992,
-            7829.86679763,
-            8253.61081534,
-            8677.35483305,
-            9101.09885076,
-            9524.84286847,
-            9948.58688618,
-            10372.33090389,
-            10796.0749216,
-            11219.81893931,
-            11643.56295703,
-            12067.30697474,
-            12491.05099245,
+            634.37045222,
+            1043.01485082,
+            1451.65924941,
+            1860.30364801,
+            2268.94804661,
+            2677.5924452,
+            3086.2368438,
+            3494.88124239,
+            3903.52564099,
+            4312.17003959,
+            4720.81443818,
+            5129.45883678,
+            5538.10323538,
+            5946.74763397,
+            6355.39203257,
+            6764.03643116,
+            7172.68082976,
+            7581.32522836,
+            7989.96962695,
+            8398.61402555,
+            8807.25842415,
+            9215.90282274,
+            9624.54722134,
+            10033.19161993,
+            10441.83601853,
+            10850.48041713,
+            11259.12481572,
+            11667.76921432,
+            12076.41361292,
+            12485.05801151,
         ]
     )
     thrust_CL_limit = np.array(
@@ -1651,29 +1683,29 @@ def test_propeller():
             5859.18963494,
             6636.81246242,
             7350.87824006,
-            8052.09311552,
-            8777.76322785,
-            9586.37415027,
-            10466.34375643,
-            11420.73698075,
-            12491.05099245,
+            8051.12299935,
+            8792.6564392,
+            9588.99001105,
+            10466.51566556,
+            11423.44161641,
+            12485.05801151,
         ]
     )
     efficiency_CL = np.array(
         [
             [
-                0.05315209,
-                0.12295759,
-                0.1433242,
-                0.14293574,
-                0.1358365,
-                0.12740032,
-                0.11888282,
-                0.1108729,
-                0.10344103,
-                0.09647314,
-                0.0898715,
-                0.08282266,
+                0.12333056,
+                0.14285193,
+                0.1430762,
+                0.13655046,
+                0.12847886,
+                0.12021237,
+                0.11239194,
+                0.10511165,
+                0.09829881,
+                0.09183378,
+                0.08529839,
+                0.07593118,
                 0.07549633,
                 0.07549633,
                 0.07549633,
@@ -1694,20 +1726,20 @@ def test_propeller():
                 0.07549633,
             ],
             [
-                0.23452478,
-                0.45265347,
-                0.51318283,
-                0.51954672,
-                0.50739007,
-                0.48846474,
-                0.4672588,
-                0.44626738,
-                0.42605523,
-                0.4065763,
-                0.38774885,
-                0.36957739,
-                0.35116945,
-                0.3294163,
+                0.45440186,
+                0.5118183,
+                0.51937963,
+                0.50870812,
+                0.49088433,
+                0.47068788,
+                0.45035362,
+                0.43066549,
+                0.41169668,
+                0.39337744,
+                0.37565149,
+                0.35818762,
+                0.33929959,
+                0.31655753,
                 0.31655753,
                 0.31655753,
                 0.31655753,
@@ -1726,22 +1758,22 @@ def test_propeller():
                 0.31655753,
             ],
             [
-                0.35036576,
-                0.59474664,
-                0.66167829,
-                0.67560837,
-                0.67017371,
-                0.65714347,
-                0.63965797,
-                0.62130002,
-                0.60230671,
-                0.5834439,
-                0.5648472,
-                0.54636218,
-                0.52794868,
-                0.50957248,
-                0.48935527,
-                0.45696352,
+                0.59370273,
+                0.65886668,
+                0.67518688,
+                0.6709731,
+                0.65894439,
+                0.64251976,
+                0.62498621,
+                0.60659673,
+                0.58847376,
+                0.57045626,
+                0.55261394,
+                0.53472844,
+                0.51721436,
+                0.49857159,
+                0.47614623,
+                0.44484842,
                 0.44484842,
                 0.44484842,
                 0.44484842,
@@ -1758,23 +1790,23 @@ def test_propeller():
                 0.44484842,
             ],
             [
-                0.39077689,
-                0.64582059,
-                0.71756227,
-                0.73932579,
-                0.74190149,
-                0.73591063,
-                0.72523708,
-                0.71211523,
-                0.6978055,
-                0.6828478,
-                0.66768651,
-                0.65220974,
-                0.63649297,
-                0.62069092,
-                0.60460499,
-                0.58717167,
-                0.56571095,
+                0.64705371,
+                0.71421953,
+                0.73756136,
+                0.74197754,
+                0.73685059,
+                0.72691312,
+                0.71472819,
+                0.70106575,
+                0.68687958,
+                0.67226796,
+                0.65742714,
+                0.64246449,
+                0.62719711,
+                0.61184951,
+                0.59577064,
+                0.57742956,
+                0.54992961,
                 0.51657519,
                 0.51657519,
                 0.51657519,
@@ -1790,196 +1822,196 @@ def test_propeller():
                 0.51657519,
             ],
             [
-                0.39576493,
-                0.65525283,
-                0.73398151,
-                0.76404041,
-                0.77348603,
-                0.77413337,
-                0.76907808,
-                0.76131939,
-                0.75154811,
-                0.74072651,
-                0.72917081,
-                0.71717986,
-                0.70471838,
-                0.69176649,
-                0.6787151,
-                0.66507989,
-                0.65052832,
-                0.63329784,
-                0.60751244,
-                0.56670973,
-                0.56670973,
-                0.56670973,
-                0.56670973,
-                0.56670973,
-                0.56670973,
-                0.56670973,
-                0.56670973,
-                0.56670973,
-                0.56670973,
-                0.56670973,
+                0.64690793,
+                0.72929195,
+                0.7613184,
+                0.77255007,
+                0.77416574,
+                0.77019423,
+                0.76283932,
+                0.75390046,
+                0.74362784,
+                0.73268477,
+                0.72126512,
+                0.70936041,
+                0.69709996,
+                0.68462952,
+                0.67169114,
+                0.6582501,
+                0.64344859,
+                0.62502786,
+                0.58921368,
+                0.56613697,
+                0.56613697,
+                0.56613697,
+                0.56613697,
+                0.56613697,
+                0.56613697,
+                0.56613697,
+                0.56613697,
+                0.56613697,
+                0.56613697,
+                0.56613697,
             ],
             [
-                0.38024791,
-                0.64668063,
-                0.73325136,
-                0.77042095,
-                0.78623276,
-                0.79218562,
-                0.79218849,
-                0.78854902,
-                0.78288492,
-                0.77563758,
-                0.76735239,
-                0.75831734,
-                0.74870596,
-                0.7386761,
-                0.72808943,
-                0.71723943,
-                0.70600331,
-                0.69375456,
-                0.68039679,
-                0.66332362,
-                0.63331588,
-                0.6155829,
-                0.6155829,
-                0.6155829,
-                0.6155829,
-                0.6155829,
-                0.6155829,
-                0.6155829,
-                0.6155829,
-                0.6155829,
+                0.64547795,
+                0.72994359,
+                0.76779654,
+                0.78469262,
+                0.79132737,
+                0.79215213,
+                0.78925062,
+                0.78418575,
+                0.77757981,
+                0.76987526,
+                0.76138931,
+                0.7523206,
+                0.74283989,
+                0.73283977,
+                0.72243211,
+                0.71184564,
+                0.70058683,
+                0.68830915,
+                0.67444215,
+                0.65560716,
+                0.60726434,
+                0.60726434,
+                0.60726434,
+                0.60726434,
+                0.60726434,
+                0.60726434,
+                0.60726434,
+                0.60726434,
+                0.60726434,
+                0.60726434,
             ],
             [
-                0.3492019,
-                0.62786604,
-                0.72201039,
-                0.76654491,
-                0.78822383,
-                0.79874484,
-                0.80296269,
-                0.80308491,
-                0.80074214,
-                0.79642265,
-                0.79109959,
-                0.78468931,
-                0.77747345,
-                0.76982277,
-                0.76163301,
-                0.75298613,
-                0.74385626,
-                0.73438969,
-                0.72440965,
-                0.71328198,
-                0.70086608,
-                0.68391259,
-                0.65172812,
-                0.6370844,
-                0.6370844,
-                0.6370844,
-                0.6370844,
-                0.6370844,
-                0.6370844,
-                0.6370844,
+                0.60700744,
+                0.71456823,
+                0.76288838,
+                0.78668932,
+                0.7974669,
+                0.80207181,
+                0.80293046,
+                0.80115585,
+                0.79759664,
+                0.79273702,
+                0.78692097,
+                0.78020373,
+                0.77304794,
+                0.76528252,
+                0.75718476,
+                0.74854281,
+                0.73972292,
+                0.73034347,
+                0.72023666,
+                0.70918342,
+                0.69611618,
+                0.6779283,
+                0.62754228,
+                0.62754228,
+                0.62754228,
+                0.62754228,
+                0.62754228,
+                0.62754228,
+                0.62754228,
+                0.62754228,
             ],
             [
-                0.3336473,
-                0.60105677,
-                0.70327433,
-                0.75425167,
-                0.78153631,
-                0.79653488,
-                0.80474546,
-                0.80831387,
-                0.80885529,
-                0.80756685,
-                0.80433345,
-                0.80039957,
-                0.79555513,
-                0.78976407,
-                0.78370943,
-                0.77696718,
-                0.7699338,
-                0.76236512,
-                0.75438071,
-                0.74600066,
-                0.73708924,
-                0.72692068,
-                0.71554386,
-                0.70025224,
-                0.67116142,
-                0.6501757,
-                0.6501757,
-                0.6501757,
-                0.6501757,
-                0.6501757,
+                0.58736137,
+                0.70228109,
+                0.74763776,
+                0.7775739,
+                0.79462253,
+                0.80330687,
+                0.80724905,
+                0.80861033,
+                0.80800815,
+                0.80525141,
+                0.80168133,
+                0.79733574,
+                0.79220498,
+                0.78641121,
+                0.78021791,
+                0.77356593,
+                0.76655101,
+                0.75906316,
+                0.75118169,
+                0.74299536,
+                0.7340609,
+                0.72404511,
+                0.71212,
+                0.69607049,
+                0.65876601,
+                0.65006983,
+                0.65006983,
+                0.65006983,
+                0.65006983,
+                0.65006983,
             ],
             [
-                0.27845075,
-                0.56240429,
-                0.67402315,
-                0.73236067,
-                0.76530728,
-                0.7846813,
-                0.79669147,
-                0.80403422,
-                0.80765291,
-                0.80891893,
-                0.80846262,
-                0.80661945,
-                0.80361676,
-                0.80019795,
-                0.79587529,
-                0.79099252,
-                0.78579673,
-                0.78002013,
-                0.77391773,
-                0.76744059,
-                0.76030466,
-                0.75304301,
-                0.74523343,
-                0.73622737,
-                0.72599615,
-                0.71298539,
-                0.69187112,
-                0.66341644,
-                0.66341644,
-                0.66341644,
+                0.57003245,
+                0.65799217,
+                0.72566447,
+                0.76032698,
+                0.78090251,
+                0.79483242,
+                0.80194359,
+                0.80656216,
+                0.80867876,
+                0.80839903,
+                0.80718959,
+                0.80469465,
+                0.80151874,
+                0.79781389,
+                0.7933785,
+                0.78846081,
+                0.78315016,
+                0.77748074,
+                0.77158866,
+                0.76498277,
+                0.75818211,
+                0.75089231,
+                0.74307419,
+                0.73416382,
+                0.72411293,
+                0.71094159,
+                0.6886737,
+                0.6544762,
+                0.6544762,
+                0.6544762,
             ],
             [
-                0.234251,
-                0.50247548,
-                0.62379532,
-                0.68918689,
-                0.72966275,
-                0.75517321,
-                0.77238402,
-                0.78378774,
-                0.79105467,
-                0.7957369,
-                0.79832641,
-                0.79913837,
-                0.79872723,
-                0.79727825,
-                0.79503428,
-                0.79228652,
-                0.7889125,
-                0.78521291,
-                0.78091034,
-                0.77633714,
-                0.77133732,
-                0.76594595,
-                0.76022882,
-                0.75380559,
-                0.7470767,
-                0.73956588,
-                0.73109294,
-                0.72046528,
-                0.70630642,
-                0.66200086,
+                0.43755858,
+                0.61043062,
+                0.67747725,
+                0.7226726,
+                0.74973033,
+                0.76823355,
+                0.78079882,
+                0.78878455,
+                0.79430656,
+                0.79707219,
+                0.79883664,
+                0.79865031,
+                0.79805297,
+                0.79596231,
+                0.79361861,
+                0.79058591,
+                0.78715869,
+                0.78346059,
+                0.7791489,
+                0.77457979,
+                0.76969748,
+                0.76437368,
+                0.75865129,
+                0.75249474,
+                0.74585436,
+                0.73849754,
+                0.73011223,
+                0.71958991,
+                0.70573877,
+                0.65930626,
             ],
         ]
     )
diff --git a/src/fastga/models/aerodynamics/unitary_tests/test_functions.py b/src/fastga/models/aerodynamics/unitary_tests/test_functions.py
index c92eed02..28042bc8 100644
--- a/src/fastga/models/aerodynamics/unitary_tests/test_functions.py
+++ b/src/fastga/models/aerodynamics/unitary_tests/test_functions.py
@@ -26,6 +26,8 @@
 import numpy as np
 import pytest
 
+import openmdao.api as om
+
 from fastga.models.aerodynamics.aerodynamics_high_speed import AerodynamicsHighSpeed
 from fastga.models.aerodynamics.aerodynamics_low_speed import AerodynamicsLowSpeed
 from fastga.models.aerodynamics.components import (
@@ -101,11 +103,11 @@
 from fastga.models.aerodynamics.external.propeller_code.compute_propeller_aero import (
     ComputePropellerPerformance,
 )
-from fastga.models.aerodynamics.external.openvsp import ComputeAEROopenvsp
+from fastga.models.aerodynamics.external.openvsp import ComputeAeroOpenVSP
 from fastga.models.aerodynamics.external.openvsp.compute_aero_slipstream import (
     ComputeSlipstreamOpenvsp,
 )
-from fastga.models.aerodynamics.external.vlm import ComputeAEROvlm
+from fastga.models.aerodynamics.external.vlm import ComputeAeroVLM
 from fastga.models.aerodynamics.external.xfoil import resources
 from fastga.models.aerodynamics.external.xfoil.xfoil_polar import XfoilPolar
 from fastga.models.aerodynamics.load_factor import LoadFactor
@@ -358,7 +360,7 @@ def polar(
 
     # Run problem
     xfoil_comp = XfoilPolar(
-        alpha_start=0.0, alpha_end=25.0, iter_limit=20, xfoil_exe_path=xfoil_path
+        alpha_start=0.0, alpha_end=20.0, iter_limit=20, xfoil_exe_path=xfoil_path
     )
     problem = run_system(xfoil_comp, ivc)
 
@@ -396,6 +398,186 @@ def polar(
     assert np.interp(1.0, cl, cdp) == pytest.approx(cdp_1_low_speed, abs=1e-4)
 
 
+def polar_interpolation(mach: float):
+    """
+    Tests the interpolation mechanism from XfoilPolar. To do so we will run XfoilPolar twice and
+    then a third time a a Reynolds number in between, it should trigger the interpolation mechanism.
+    """
+
+    # Transfer saved polar results to temporary folder
+    tmp_folder = polar_result_transfer()
+
+    ivc = om.IndepVarComp()
+    ivc.add_output("xfoil:mach", mach)
+    ivc.add_output("xfoil:reynolds", 5e6)
+
+    # Run problem
+    xfoil_comp = XfoilPolar(
+        alpha_start=0.0, alpha_end=20.0, iter_limit=20, xfoil_exe_path=xfoil_path
+    )
+    t1_start = time.time()
+    _ = run_system(xfoil_comp, ivc)
+    t1_end = time.time()
+    t1_duration = t1_end - t1_start
+
+    ivc = om.IndepVarComp()
+    ivc.add_output("xfoil:mach", mach)
+    ivc.add_output("xfoil:reynolds", 7e6)
+    t2_start = time.time()
+    _ = run_system(xfoil_comp, ivc)
+    t2_end = time.time()
+    t2_duration = t2_end - t2_start
+
+    # Run a third time between the two other Reynolds
+
+    ivc = om.IndepVarComp()
+    ivc.add_output("xfoil:mach", mach)
+    ivc.add_output("xfoil:reynolds", 6e6)
+
+    # Run problem
+    t3_start = time.time()
+    _ = run_system(xfoil_comp, ivc)
+    t3_end = time.time()
+    t3_duration = t3_end - t3_start
+
+    # Retrieve polar results from temporary folder
+    polar_result_retrieve(tmp_folder)
+
+    assert t3_duration < (t1_duration + t2_duration) / 2
+
+
+def polar_single_aoa(
+    XML_FILE: str,
+    mach_low_speed: float,
+    reynolds_low_speed: float,
+):
+    """
+    Tests polar execution (XFOIL) @ low speed! Run Xfoil once with multiple AOA then extract the
+    value for 5.0 degree and run Xfoil for a single Aoa at 5.0 degree and compare results
+    """
+
+    # Transfer saved polar results to temporary folder
+    tmp_folder = polar_result_transfer()
+
+    # Define low-speed parameters (with .xml file and additional inputs)
+    ivc = get_indep_var_comp(list_inputs(XfoilPolar()), __file__, XML_FILE)
+    ivc.add_output("xfoil:mach", mach_low_speed)
+    ivc.add_output("xfoil:reynolds", reynolds_low_speed)
+
+    # Run problem
+    xfoil_comp = XfoilPolar(
+        alpha_start=2.0, alpha_end=7.5, iter_limit=20, xfoil_exe_path=xfoil_path
+    )
+    problem = run_system(xfoil_comp, ivc)
+
+    # Retrieve polar results from temporary folder
+    polar_result_retrieve(tmp_folder)
+
+    # Extract value for 5.0 deg
+    cl = problem["xfoil:CL"]
+    cdp = problem["xfoil:CDp"]
+
+    alpha = problem["xfoil:alpha"]
+    index_5_deg = list(alpha).index(5.0)
+
+    cl, cdp = reshape_polar(cl, cdp)
+
+    cl_5 = cl[index_5_deg]
+    cdp_5 = cdp[index_5_deg]
+
+    # Transfer saved polar results to temporary folder
+    tmp_folder = polar_result_transfer()
+
+    # Define high-speed parameters (with .xml file and additional inputs)
+    ivc = get_indep_var_comp(list_inputs(XfoilPolar()), __file__, XML_FILE)
+    ivc.add_output("xfoil:mach", mach_low_speed)
+    ivc.add_output("xfoil:reynolds", reynolds_low_speed)
+    # Run problem
+    xfoil_comp = XfoilPolar(
+        alpha_start=5.0, iter_limit=20, xfoil_exe_path=xfoil_path, single_AoA=True
+    )
+    problem = run_system(xfoil_comp, ivc)
+
+    # Retrieve polar results from temporary folder
+    polar_result_retrieve(tmp_folder)
+
+    # Check obtained value(s) is/(are) correct
+    cl_s = problem["xfoil:CL"]
+    cdp_s = problem["xfoil:CDp"]
+    assert cl_5 == pytest.approx(cl_s, abs=1e-4)
+    assert cdp_5 == pytest.approx(cdp_s, abs=1e-4)
+
+
+def polar_single_aoa_inv(
+    XML_FILE: str,
+    mach_low_speed: float,
+    reynolds_low_speed: float,
+):
+    """
+    Tests polar execution (XFOIL) @ low speed and inviscid! Run Xfoil once with multiple AOA then
+    extract the value for 5.0 degree and run Xfoil for a single Aoa at 5.0 degree and compare
+    results
+    """
+
+    # Transfer saved polar results to temporary folder
+    tmp_folder = polar_result_transfer()
+
+    # Define low-speed parameters (with .xml file and additional inputs)
+    ivc = get_indep_var_comp(list_inputs(XfoilPolar()), __file__, XML_FILE)
+    ivc.add_output("xfoil:mach", mach_low_speed)
+    ivc.add_output("xfoil:reynolds", reynolds_low_speed)
+
+    # Run problem
+    xfoil_comp = XfoilPolar(
+        alpha_start=2.5,
+        alpha_end=7.5,
+        iter_limit=20,
+        xfoil_exe_path=xfoil_path,
+        inviscid_calculation=True,
+    )
+    problem = run_system(xfoil_comp, ivc)
+    # Retrieve polar results from temporary folder
+    polar_result_retrieve(tmp_folder)
+
+    # Check obtained value(s) is/(are) correct
+    cl = problem["xfoil:CL"]
+    cdp = problem["xfoil:CDp"]
+
+    alpha = problem["xfoil:alpha"]
+    index_5_deg = list(alpha).index(5.0)
+
+    cl, cdp = reshape_polar(cl, cdp)
+
+    cl_5 = cl[index_5_deg]
+    cdp_5 = cdp[index_5_deg]
+
+    # Transfer saved polar results to temporary folder
+    tmp_folder = polar_result_transfer()
+
+    # Define high-speed parameters (with .xml file and additional inputs)
+    ivc = get_indep_var_comp(list_inputs(XfoilPolar()), __file__, XML_FILE)
+    ivc.add_output("xfoil:mach", mach_low_speed)
+    ivc.add_output("xfoil:reynolds", reynolds_low_speed)
+    # Run problem
+    xfoil_comp = XfoilPolar(
+        alpha_start=5.0,
+        iter_limit=20,
+        xfoil_exe_path=xfoil_path,
+        inviscid_calculation=True,
+        single_AoA=True,
+    )
+    problem = run_system(xfoil_comp, ivc)
+
+    # Retrieve polar results from temporary folder
+    polar_result_retrieve(tmp_folder)
+
+    # Check obtained value(s) is/(are) correct
+    cl_s = problem["xfoil:CL"]
+    cdp_s = problem["xfoil:CDp"]
+    assert cl_5 == pytest.approx(cl_s, abs=1e-4)
+    assert cdp_5 == pytest.approx(cdp_s, abs=1e-4)
+
+
 def polar_ext_folder(
     XML_FILE: str,
     mach_high_speed: float,
@@ -471,6 +653,77 @@ def polar_ext_folder(
     assert np.interp(1.0, cl, cdp) == pytest.approx(cdp_1_low_speed, abs=1e-4)
 
 
+def polar_ext_folder_inv(
+    XML_FILE: str,
+    mach_low_speed: float,
+    reynolds_low_speed: float,
+):
+    """Tests polar execution (XFOIL) @ high and low speed! with the option airfoil_folder_path"""
+    # Transfer saved polar results to temporary folder
+    tmp_folder = polar_result_transfer()
+    shutil.copy(
+        pth.join(DATA_FOLDER, "sample_airfoil.af"), pth.join(tmp_folder.name, "sample_airfoil.af")
+    )
+
+    # Define high-speed parameters (with .xml file and additional inputs)
+    ivc = get_indep_var_comp(list_inputs(XfoilPolar()), __file__, XML_FILE)
+    ivc.add_output("xfoil:mach", mach_low_speed)
+    ivc.add_output("xfoil:reynolds", reynolds_low_speed)
+
+    # Run problem
+    xfoil_comp = XfoilPolar(
+        alpha_start=5.0,
+        alpha_end=25.0,
+        iter_limit=20,
+        xfoil_exe_path=xfoil_path,
+        airfoil_folder_path=tmp_folder.name,
+        airfoil_file="sample_airfoil.af",
+    )
+    xfoil_comp.options["inviscid_calculation"] = True
+    problem = run_system(xfoil_comp, ivc)
+
+    # Retrieve polar results from temporary folder
+    polar_result_retrieve(tmp_folder)
+
+    # Check obtained value(s) is/(are) correct
+    cl_1 = problem["xfoil:CL"]
+    cdp_1 = problem["xfoil:CDp"]
+    # cl_1, cdp_1 = reshape_polar(cl, cdp)
+
+    # Transfer saved polar results to temporary folder
+    tmp_folder = polar_result_transfer()
+    shutil.copy(
+        pth.join(DATA_FOLDER, "sample_airfoil.af"), pth.join(tmp_folder.name, "sample_airfoil.af")
+    )
+
+    # Define high-speed parameters (with .xml file and additional inputs)
+    ivc = get_indep_var_comp(list_inputs(XfoilPolar()), __file__, XML_FILE)
+    ivc.add_output("xfoil:mach", mach_low_speed)
+    ivc.add_output("xfoil:reynolds", reynolds_low_speed)
+
+    # Run problem
+    xfoil_comp = XfoilPolar(
+        alpha_start=5.0,
+        iter_limit=20,
+        xfoil_exe_path=xfoil_path,
+        airfoil_folder_path=tmp_folder.name,
+        airfoil_file="sample_airfoil.af",
+    )
+    xfoil_comp.options["inviscid_calculation"] = True
+    xfoil_comp.options["single_AoA"] = True
+    problem = run_system(xfoil_comp, ivc)
+
+    # Retrieve polar results from temporary folder
+    polar_result_retrieve(tmp_folder)
+
+    # Check obtained value(s) is/(are) correct
+    cl_2 = problem["xfoil:CL"]
+    cdp_2 = problem["xfoil:CDp"]
+    # cl_2, cdp_2 = reshape_polar(cl, cdp)
+    assert cl_1[0] == pytest.approx(cl_2, abs=1e-4)
+    assert cdp_1[0] == pytest.approx(cdp_2, abs=1e-4)
+
+
 def airfoil_slope_wt_xfoil(
     XML_FILE: str,
     wing_airfoil_file: str,
@@ -557,62 +810,58 @@ def compute_aero(
     if use_openvsp:
         # noinspection PyTypeChecker
         ivc = get_indep_var_comp(
-            list_inputs(ComputeAEROopenvsp(low_speed_aero=low_speed_aero)), __file__, XML_FILE
+            list_inputs(ComputeAeroOpenVSP(low_speed_aero=low_speed_aero)), __file__, XML_FILE
         )
 
         # Run problem twice
         start = time.time()
         # noinspection PyTypeChecker
-        problem = run_system(
-            ComputeAEROopenvsp(
-                low_speed_aero=low_speed_aero,
-                result_folder_path=results_folder.name,
-                compute_mach_interpolation=mach_interpolation,
-            ),
-            ivc,
+        openvsp_comp = ComputeAeroOpenVSP(
+            low_speed_aero=low_speed_aero,
+            result_folder_path=results_folder.name,
+            compute_mach_interpolation=mach_interpolation,
         )
+
+        problem = run_system(openvsp_comp, ivc)
         stop = time.time()
         duration_1st_run = stop - start
         start = time.time()
         # noinspection PyTypeChecker
-        run_system(
-            ComputeAEROopenvsp(
-                low_speed_aero=low_speed_aero,
-                result_folder_path=results_folder.name,
-                compute_mach_interpolation=mach_interpolation,
-            ),
-            ivc,
+        openvsp_comp = ComputeAeroOpenVSP(
+            low_speed_aero=low_speed_aero,
+            result_folder_path=results_folder.name,
+            compute_mach_interpolation=mach_interpolation,
         )
+
+        problem = run_system(openvsp_comp, ivc)
         stop = time.time()
     else:
         # noinspection PyTypeChecker
         ivc = get_indep_var_comp(
-            list_inputs(ComputeAEROvlm(low_speed_aero=low_speed_aero)), __file__, XML_FILE
+            list_inputs(ComputeAeroVLM(low_speed_aero=low_speed_aero)), __file__, XML_FILE
         )
 
         # Run problem twice
         start = time.time()
         # noinspection PyTypeChecker
-        problem = run_system(
-            ComputeAEROvlm(
-                low_speed_aero=low_speed_aero,
-                result_folder_path=results_folder.name,
-                compute_mach_interpolation=mach_interpolation,
-            ),
-            ivc,
+        vlm_comp = ComputeAeroVLM(
+            low_speed_aero=low_speed_aero,
+            result_folder_path=results_folder.name,
+            compute_mach_interpolation=mach_interpolation,
         )
+
+        problem = run_system(vlm_comp, ivc)
         stop = time.time()
         duration_1st_run = stop - start
         start = time.time()
         # noinspection PyTypeChecker
-        run_system(
-            ComputeAEROvlm(
-                low_speed_aero=low_speed_aero,
-                result_folder_path=results_folder.name,
-                compute_mach_interpolation=mach_interpolation,
-            ),
-            ivc,
+        vlm_comp = ComputeAeroVLM(
+            low_speed_aero=low_speed_aero,
+            result_folder_path=results_folder.name,
+            compute_mach_interpolation=mach_interpolation,
         )
+
+        problem = run_system(vlm_comp, ivc)
         stop = time.time()
     duration_2nd_run = stop - start
 
@@ -623,8 +872,101 @@ def compute_aero(
     results_folder.cleanup()
 
     # Check obtained value(s) is/(are) correct
-    assert (duration_2nd_run / duration_1st_run) <= 0.1
+    if use_openvsp:
+        assert (duration_2nd_run / duration_1st_run) <= 0.5  # original 0.1
+    else:
+        assert (duration_2nd_run / duration_1st_run) <= 1
+    # Return problem for complementary values check
+    return problem
 
+
+def comp_aero_input_aoa(
+    XML_FILE: str,
+    use_openvsp: bool,
+    mach_interpolation: bool,
+    low_speed_aero: bool,
+):
+    """Compute aero components!"""
+    # Create result temporary directory
+    results_folder = _create_tmp_directory()
+
+    # Transfer saved polar results to temporary folder
+    tmp_folder = polar_result_transfer()
+
+    # Research independent input value in .xml file
+    if use_openvsp:
+        # noinspection PyTypeChecker
+        ivc = get_indep_var_comp(
+            list_inputs(ComputeAeroOpenVSP(low_speed_aero=low_speed_aero)), __file__, XML_FILE
+        )
+
+        # Run problem twice
+        start = time.time()
+        # noinspection PyTypeChecker
+        openvsp_comp = ComputeAeroOpenVSP(
+            low_speed_aero=low_speed_aero,
+            result_folder_path=results_folder.name,
+            compute_mach_interpolation=mach_interpolation,
+            input_angle_of_attack=10.5,
+        )
+
+        problem = run_system(openvsp_comp, ivc)
+        stop = time.time()
+        duration_1st_run = stop - start
+        start = time.time()
+        # noinspection PyTypeChecker
+        openvsp_comp = ComputeAeroOpenVSP(
+            low_speed_aero=low_speed_aero,
+            result_folder_path=results_folder.name,
+            compute_mach_interpolation=mach_interpolation,
+            input_angle_of_attack=10.5,
+        )
+
+        problem = run_system(openvsp_comp, ivc)
+        stop = time.time()
+    else:
+        # noinspection PyTypeChecker
+        ivc = get_indep_var_comp(
+            list_inputs(ComputeAeroVLM(low_speed_aero=low_speed_aero)), __file__, XML_FILE
+        )
+
+        # Run problem twice
+        start = time.time()
+        # noinspection PyTypeChecker
+        vlm_comp = ComputeAeroVLM(
+            low_speed_aero=low_speed_aero,
+            result_folder_path=results_folder.name,
+            compute_mach_interpolation=mach_interpolation,
+            input_angle_of_attack=10.5,
+        )
+
+        problem = run_system(vlm_comp, ivc)
+        stop = time.time()
+        duration_1st_run = stop - start
+        start = time.time()
+        # noinspection PyTypeChecker
+        vlm_comp = ComputeAeroVLM(
+            low_speed_aero=low_speed_aero,
+            result_folder_path=results_folder.name,
+            compute_mach_interpolation=mach_interpolation,
+            input_angle_of_attack=10.5,
+        )
+
+        problem = run_system(vlm_comp, ivc)
+        stop = time.time()
+    duration_2nd_run = stop - start
+
+    # Retrieve polar results from temporary folder
+    polar_result_retrieve(tmp_folder)
+
+    # Remove existing result files
+    results_folder.cleanup()
+
+    # Check obtained value(s) is/(are) correct
+    if use_openvsp:
+        assert (duration_2nd_run / duration_1st_run) <= 0.5  # original 0.1
+    else:
+        assert (duration_2nd_run / duration_1st_run) <= 1
     # Return problem for complementary values check
     return problem
 
@@ -686,6 +1028,56 @@ def comp_high_speed(
             ] == pytest.approx(coeff_k_htp, abs=1e-4)
 
 
+def comp_high_speed_input_aoa(
+    XML_FILE: str,
+    use_openvsp: bool,
+):
+
+    """Tests components @ high speed!"""
+    for mach_interpolation in [True, False]:
+        problem = compute_aero(XML_FILE, use_openvsp, mach_interpolation, False)
+        problem_input_aoa = comp_aero_input_aoa(XML_FILE, use_openvsp, mach_interpolation, False)
+        # Check obtained value(s) is/(are) correct
+        if mach_interpolation:
+            assert problem[
+                "data:aerodynamics:aircraft:mach_interpolation:CL_alpha_vector"
+            ] == pytest.approx(
+                problem_input_aoa["data:aerodynamics:aircraft:mach_interpolation:CL_alpha_vector"],
+                abs=1e-2,
+            )
+            assert problem[
+                "data:aerodynamics:aircraft:mach_interpolation:mach_vector"
+            ] == pytest.approx(
+                problem_input_aoa["data:aerodynamics:aircraft:mach_interpolation:mach_vector"],
+                abs=1e-2,
+            )
+        else:
+            assert problem.get_val(
+                "data:aerodynamics:wing:cruise:CL_alpha", units="rad**-1"
+            ) == pytest.approx(
+                problem_input_aoa.get_val(
+                    "data:aerodynamics:wing:cruise:CL_alpha", units="rad**-1"
+                ),
+                abs=1e-2,
+            )
+            assert problem.get_val(
+                "data:aerodynamics:horizontal_tail:cruise:CL_alpha", units="rad**-1"
+            ) == pytest.approx(
+                problem_input_aoa.get_val(
+                    "data:aerodynamics:horizontal_tail:cruise:CL_alpha", units="rad**-1"
+                ),
+                abs=1e-2,
+            )
+            assert problem.get_val(
+                "data:aerodynamics:horizontal_tail:cruise:CL_alpha_isolated", units="rad**-1"
+            ) == pytest.approx(
+                problem_input_aoa.get_val(
+                    "data:aerodynamics:horizontal_tail:cruise:CL_alpha_isolated", units="rad**-1"
+                ),
+                abs=1e-2,
+            )
+
+
 def comp_low_speed(
     XML_FILE: str,
     use_openvsp: bool,
@@ -756,6 +1148,39 @@ def comp_low_speed(
     assert np.max(np.abs(cl_vector_htp - cl)) <= 1e-3
 
 
+def comp_low_speed_input_aoa(
+    XML_FILE: str,
+    use_openvsp: bool,
+):
+    """Tests components @ low speed!"""
+    problem = compute_aero(XML_FILE, use_openvsp, False, True)
+    problem_input_aoa = comp_aero_input_aoa(XML_FILE, use_openvsp, False, True)
+    # Check obtained value(s) is/(are) correct
+
+    assert problem.get_val(
+        "data:aerodynamics:wing:low_speed:CL_alpha", units="rad**-1"
+    ) == pytest.approx(
+        problem_input_aoa.get_val("data:aerodynamics:wing:low_speed:CL_alpha", units="rad**-1"),
+        abs=1e-2,
+    )
+    assert problem.get_val(
+        "data:aerodynamics:horizontal_tail:low_speed:CL_alpha", units="rad**-1"
+    ) == pytest.approx(
+        problem_input_aoa.get_val(
+            "data:aerodynamics:horizontal_tail:low_speed:CL_alpha", units="rad**-1"
+        ),
+        abs=1e-2,
+    )
+    assert problem.get_val(
+        "data:aerodynamics:horizontal_tail:low_speed:CL_alpha_isolated", units="rad**-1"
+    ) == pytest.approx(
+        problem_input_aoa.get_val(
+            "data:aerodynamics:horizontal_tail:low_speed:CL_alpha_isolated", units="rad**-1"
+        ),
+        abs=1e-2,
+    )
+
+
 def hinge_moment_2d(XML_FILE: str, ch_alpha_2d: float, ch_delta_2d: float):
     """Tests tail hinge-moments"""
     # Research independent input value in .xml file
@@ -1370,70 +1795,30 @@ def propeller(
     polar_result_retrieve(tmp_folder)
 
     # Check obtained value(s) is/(are) correct
-    assert (
-        np.sum(
-            np.abs(
-                thrust_SL
-                - problem.get_val("data:aerodynamics:propeller:sea_level:thrust", units="N")
-            )
-        )
-        < 1
-    )
-    assert (
-        np.sum(
-            np.abs(
-                thrust_SL_limit
-                - problem.get_val("data:aerodynamics:propeller:sea_level:thrust_limit", units="N")
-            )
-        )
-        < 1
-    )
-    assert (
-        np.sum(
-            np.abs(
-                speed - problem.get_val("data:aerodynamics:propeller:sea_level:speed", units="m/s")
-            )
-        )
-        < 1e-2
-    )
-    assert (
-        np.sum(np.abs(efficiency_SL - problem["data:aerodynamics:propeller:sea_level:efficiency"]))
-        < 1e-5
-    )
-    assert (
-        np.sum(
-            np.abs(
-                thrust_CL
-                - problem.get_val("data:aerodynamics:propeller:cruise_level:thrust", units="N")
-            )
-        )
-        < 1
-    )
-    assert (
-        np.sum(
-            np.abs(
-                thrust_CL_limit
-                - problem.get_val(
-                    "data:aerodynamics:propeller:cruise_level:thrust_limit", units="N"
-                )
-            )
-        )
-        < 1
-    )
-    assert (
-        np.sum(
-            np.abs(
-                speed
-                - problem.get_val("data:aerodynamics:propeller:cruise_level:speed", units="m/s")
-            )
-        )
-        < 1e-2
+    assert problem.get_val(
+        "data:aerodynamics:propeller:sea_level:thrust", units="N"
+    ) == pytest.approx(thrust_SL, abs=1)
+    assert problem.get_val(
+        "data:aerodynamics:propeller:sea_level:thrust_limit", units="N"
+    ) == pytest.approx(thrust_SL_limit, abs=1)
+    assert problem.get_val(
+        "data:aerodynamics:propeller:sea_level:speed", units="m/s"
+    ) == pytest.approx(speed, abs=1e-2)
+    assert problem.get_val("data:aerodynamics:propeller:sea_level:efficiency") == pytest.approx(
+        efficiency_SL, abs=1e-5
     )
-    assert (
-        np.sum(
-            np.abs(efficiency_CL - problem["data:aerodynamics:propeller:cruise_level:efficiency"])
-        )
-        < 1e-5
+
+    assert problem.get_val(
+        "data:aerodynamics:propeller:cruise_level:thrust", units="N"
+    ) == pytest.approx(thrust_CL, abs=1)
+    assert problem.get_val(
+        "data:aerodynamics:propeller:cruise_level:thrust_limit", units="N"
+    ) == pytest.approx(thrust_CL_limit, abs=1)
+    assert problem.get_val(
+        "data:aerodynamics:propeller:cruise_level:speed", units="m/s"
+    ) == pytest.approx(speed, abs=1e-2)
+    assert problem.get_val("data:aerodynamics:propeller:cruise_level:efficiency") == pytest.approx(
+        efficiency_CL, abs=1e-5
     )
 
 
diff --git a/src/fastga/models/aerodynamics/unitary_tests/test_partenavia_p68.py b/src/fastga/models/aerodynamics/unitary_tests/test_partenavia_p68.py
index 61fc87fb..57fd3c12 100644
--- a/src/fastga/models/aerodynamics/unitary_tests/test_partenavia_p68.py
+++ b/src/fastga/models/aerodynamics/unitary_tests/test_partenavia_p68.py
@@ -27,7 +27,7 @@
 
 
 @pytest.mark.skipif(
-    system() != "Windows" or SKIP_STEPS,
+    system() != "Windows" or False,
     reason="No XFOIL executable available: VLM basic function not computed with "
     "empty result folder (or skipped)",
 )
@@ -225,7 +225,7 @@ def test_openvsp_comp_low_speed():
         cl_ref_wing=0.82957738,
         cl_alpha_wing=4.44953801,
         cm0=-0.02545115,
-        coeff_k_wing=0.04827684,
+        coeff_k_wing=0.04378852,
         cl0_htp=-0.00732,
         cl_alpha_htp=0.50168185,
         cl_alpha_htp_isolated=0.79058386,