Beispiel #1
0
    def _notebooks(args):
        """Copies the notebook folder in user-selected destination."""
        # Create and copy folder
        target_path = pth.abspath(pth.join(args.path, NOTEBOOK_FOLDER_NAME))
        if pth.exists(target_path):
            shutil.rmtree(target_path)
        os.makedirs(target_path)

        copy_resource_folder(tutorial, target_path)
        # Note: copy_resource_folder(tutorial, target_path) would fail because of IPython imports

        # Give info for running Jupyter
        print("")
        print("Notebooks have been created in %s" % target_path)
        print("You may now run Jupyter with:")
        print('   jupyter notebook "%s"' % target_path)
Beispiel #2
0
    def compute(self, inputs, outputs):

        # 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(pth.join(result_folder_path, 'OSWALD'), exist_ok=True)

        # Get inputs (and calculate missing ones)
        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"]
        fa_length = inputs["data:geometry:wing:MAC:at25percent:x"]
        sref_wing = inputs['data:geometry:wing:area']
        span_wing = inputs['data:geometry:wing:span']
        height_max = inputs["data:geometry:fuselage:maximum_height"]
        if self.options["low_speed_aero"]:
            altitude = 0.0
            atm = Atmosphere(altitude)
            mach = inputs["data:aerodynamics:low_speed:mach"]
        else:
            altitude = inputs["data:mission:sizing:main_route:cruise:altitude"]
            atm = Atmosphere(altitude)
            mach = inputs["data:aerodynamics:cruise:mach"]

            # Initial parameters calculation
        x_wing = fa_length - x0_wing - 0.25 * l0_wing
        z_wing = -(height_max - 0.12 * l2_wing) * 0.5
        span2_wing = y4_wing - y2_wing
        viscosity = atm.kinematic_viscosity
        rho = atm.density
        v_inf = max(atm.speed_of_sound * mach, 0.1)  # avoid V=0 m/s crashes
        reynolds = v_inf * l0_wing / viscosity

        # OPENVSP-SCRIPT: Geometry generation ######################################################

        # I/O files --------------------------------------------------------------------------------
        tmp_directory = self._create_tmp_directory()
        # avoid to dump void xternal_code_comp_error.out error file
        self.stderr = pth.join(tmp_directory.name, _STDERR_FILE_NAME)
        if self.options[OPTION_OPENVSP_EXE_PATH]:
            target_directory = pth.abspath(self.options[OPTION_OPENVSP_EXE_PATH])
        else:
            target_directory = tmp_directory.name
        input_file_list = [pth.join(target_directory, _INPUT_SCRIPT_FILE_NAME),
                           pth.join(target_directory, self.options['wing_airfoil_file'])]
        tmp_result_file_path = pth.join(target_directory, _INPUT_AERO_FILE_NAME + '0.csv')
        output_file_list = [tmp_result_file_path]
        self.options["external_input_files"] = input_file_list
        self.options["external_output_files"] = output_file_list

        # Pre-processing (populating temp directory and generate batch file) -----------------------
        # Copy resource in temp directory if needed
        if not (self.options[OPTION_OPENVSP_EXE_PATH]):
            # noinspection PyTypeChecker
            copy_resource_folder(openvsp3201, target_directory)
            # noinspection PyTypeChecker
            copy_resource(resources, self.options['wing_airfoil_file'], target_directory)
        # Create corresponding .bat file
        self.options["command"] = [pth.join(target_directory, 'vspscript.bat')]
        command = pth.join(target_directory, VSPSCRIPT_EXE_NAME) + ' -script ' \
                  + pth.join(target_directory, _INPUT_SCRIPT_FILE_NAME) + ' >nul 2>nul\n'
        batch_file = open(self.options["command"][0], "w+")
        batch_file.write("@echo off\n")
        batch_file.write(command)
        batch_file.close()

        # standard SCRIPT input file ---------------------------------------------------------------
        parser = InputFileGenerator()
        with path(local_resources, _INPUT_SCRIPT_FILE_NAME) as input_template_path:
            parser.set_template_file(str(input_template_path))
            parser.set_generated_file(input_file_list[0])
            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("airfoil_0_file")
            parser.transfer_var(self._rewrite_path(input_file_list[1]), 0, 3)
            parser.mark_anchor("airfoil_1_file")
            parser.transfer_var(self._rewrite_path(input_file_list[1]), 0, 3)
            parser.mark_anchor("airfoil_2_file")
            parser.transfer_var(self._rewrite_path(input_file_list[1]), 0, 3)
            parser.mark_anchor("csv_file")
            parser.transfer_var(self._rewrite_path(tmp_result_file_path), 0, 3)
            parser.generate()

        # Run SCRIPT --------------------------------------------------------------------------------
        super().compute(inputs, outputs)

        # Getting input/output files if needed
        if self.options[OPTION_RESULT_FOLDER_PATH] != "":
            for file_path in input_file_list:
                new_path = pth.join(result_folder_path, 'OSWALD', pth.split(file_path)[1])
                if pth.exists(file_path):
                    shutil.copyfile(file_path, new_path)
            for file_path in output_file_list:
                new_path = pth.join(result_folder_path, 'OSWALD', pth.split(file_path)[1])
                if pth.exists(file_path):
                    shutil.copyfile(file_path, new_path)

        # OPENVSP-AERO: aero calculation ############################################################

        # I/O files --------------------------------------------------------------------------------
        # Duplicate .csv file for multiple run
        input_file_list = [tmp_result_file_path]
        for idx in range(len(_INPUT_AOAList) - 1):
            shutil.copy(tmp_result_file_path, pth.join(target_directory, _INPUT_AERO_FILE_NAME + str(idx + 1) + '.csv'))
            input_file_list.append(pth.join(target_directory, _INPUT_AERO_FILE_NAME + str(idx + 1) + '.csv'))
        output_file_list = []
        for idx in range(len(_INPUT_AOAList)):
            input_file_list.append(pth.join(target_directory, _INPUT_AERO_FILE_NAME) + str(idx) + '.vspaero')
            output_file_list.append(pth.join(target_directory, _INPUT_AERO_FILE_NAME) + str(idx) + '.polar')
        self.options["external_input_files"] = input_file_list
        self.options["external_output_files"] = output_file_list

        # Pre-processing (create batch file) -------------------------------------------------------
        self.options["command"] = [pth.join(target_directory, 'vspaero.bat')]
        batch_file = open(self.options["command"][0], "w+")
        batch_file.write("@echo off\n")
        for idx in range(len(_INPUT_AOAList)):
            command = pth.join(target_directory, VSPAERO_EXE_NAME) + ' ' \
                      + pth.join(target_directory, _INPUT_AERO_FILE_NAME + str(idx) + ' >nul 2>nul\n')
            batch_file.write(command)
        batch_file.close()

        # standard AERO input file -----------------------------------------------------------------
        parser = InputFileGenerator()
        for idx in range(len(_INPUT_AOAList)):
            with path(local_resources, _INPUT_AERO_FILE_NAME + '.vspaero') as input_template_path:
                parser.set_template_file(str(input_template_path))
                parser.set_generated_file(input_file_list[len(_INPUT_AOAList) + idx])
                parser.reset_anchor()
                parser.mark_anchor("Sref")
                parser.transfer_var(float(sref_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(_INPUT_AOAList[idx]), 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()

        # Run AERO --------------------------------------------------------------------------------
        super().compute(inputs, outputs)

        # Post-processing --------------------------------------------------------------------------
        result_oswald = []
        for idx in range(len(_INPUT_AOAList)):
            _, _, oswald, _ = self._read_polar_file(output_file_list[idx])
            result_oswald.append(oswald)
        # Fuselage correction
        k_fus = 1 - 2 * (width_max / span_wing) ** 2
        # Full aircraft correction: Wing lift is 105% of total lift.
        # This means CDind = (CL*1.05)^2/(piAe) -> e' = e/1.05^2
        coef_e = float(result_oswald[0] * k_fus / 1.05 ** 2)
        coef_k = 1. / (math.pi * span_wing ** 2 / sref_wing * coef_e)

        if self.options["low_speed_aero"]:
            outputs["data:aerodynamics:aircraft:low_speed:induced_drag_coefficient"] = coef_k
        else:
            outputs["data:aerodynamics:aircraft:cruise:induced_drag_coefficient"] = coef_k

        # Getting input/output files if needed
        if self.options[OPTION_RESULT_FOLDER_PATH] != "":
            for file_path in input_file_list:
                new_path = pth.join(result_folder_path, 'OSWALD', pth.split(file_path)[1])
                if pth.exists(file_path):
                    shutil.copyfile(file_path, new_path)
            for file_path in output_file_list:
                new_path = pth.join(result_folder_path, 'OSWALD', pth.split(file_path)[1])
                if pth.exists(file_path):
                    shutil.copyfile(file_path, new_path)

        # Delete temporary directory    
        tmp_directory.cleanup()
Beispiel #3
0
    def compute(self, inputs, outputs):

        # 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(pth.join(result_folder_path, 'ClCmHT'), exist_ok=True)

        # Get inputs (and calculate missing ones)
        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"]
        fa_length = inputs["data:geometry:wing:MAC:at25percent:x"]
        sref_wing = inputs['data:geometry:wing:area']
        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"]
        mach = inputs["data:aerodynamics:low_speed:mach"]
        altitude = 0.0

        # Compute remaining inputs
        x_wing = fa_length - x0_wing - 0.25 * l0_wing
        z_wing = -(height_max - 0.12 * l2_wing) * 0.5
        span2_wing = y4_wing - y2_wing
        distance_htp = fa_length + lp_htp - 0.25 * l0_htp - x0_htp
        atm = Atmosphere(altitude)
        viscosity = atm.kinematic_viscosity
        rho = atm.density
        v_inf = max(atm.speed_of_sound * mach, 0.01)  # avoid V=0 m/s crashes
        reynolds = v_inf * l0_wing / viscosity

        # OPENVSP-SCRIPT: Geometry generation ######################################################

        # I/O files --------------------------------------------------------------------------------
        tmp_directory = self._create_tmp_directory()
        # avoid to dump void xternal_code_comp_error.out error file
        self.stderr = pth.join(tmp_directory.name, _STDERR_FILE_NAME)
        if self.options[OPTION_OPENVSP_EXE_PATH]:
            target_directory = pth.abspath(
                self.options[OPTION_OPENVSP_EXE_PATH])
        else:
            target_directory = tmp_directory.name
        input_file_list = [
            pth.join(target_directory, _INPUT_SCRIPT_FILE_NAME),
            pth.join(target_directory, self.options['wing_airfoil_file']),
            pth.join(target_directory, self.options['htp_airfoil_file'])
        ]
        tmp_result_file_path = pth.join(target_directory,
                                        _INPUT_AERO_FILE_NAME + '0.csv')
        output_file_list = [tmp_result_file_path]
        self.options["external_input_files"] = input_file_list
        self.options["external_output_files"] = output_file_list

        # Pre-processing (populating temp directory) -----------------------------------------------
        # Copy resource in temp directory if needed
        if not (self.options[OPTION_OPENVSP_EXE_PATH]):
            # noinspection PyTypeChecker
            copy_resource_folder(openvsp3201, target_directory)
            # noinspection PyTypeChecker
            copy_resource(resources, self.options['wing_airfoil_file'],
                          target_directory)
            # noinspection PyTypeChecker
            copy_resource(resources, self.options['htp_airfoil_file'],
                          target_directory)
        # Create corresponding .bat file
        self.options["command"] = [pth.join(target_directory, 'vspscript.bat')]
        command = pth.join(target_directory, VSPSCRIPT_EXE_NAME) + ' -script ' \
                  + pth.join(target_directory, _INPUT_SCRIPT_FILE_NAME) + ' >nul 2>nul\n'
        batch_file = open(self.options["command"][0], "w+")
        batch_file.write("@echo off\n")
        batch_file.write(command)
        batch_file.close()

        # standard SCRIPT input file ----------------------------------------------------------------
        parser = InputFileGenerator()
        with path(local_resources,
                  _INPUT_SCRIPT_FILE_NAME) as input_template_path:
            parser.set_template_file(str(input_template_path))
            parser.set_generated_file(input_file_list[0])
            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("airfoil_0_file")
            parser.transfer_var(self._rewrite_path(input_file_list[1]), 0, 3)
            parser.mark_anchor("airfoil_1_file")
            parser.transfer_var(self._rewrite_path(input_file_list[1]), 0, 3)
            parser.mark_anchor("airfoil_2_file")
            parser.transfer_var(self._rewrite_path(input_file_list[1]), 0, 3)
            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(self._rewrite_path(input_file_list[2]), 0, 3)
            parser.mark_anchor("airfoil_4_file")
            parser.transfer_var(self._rewrite_path(input_file_list[2]), 0, 3)
            parser.mark_anchor("csv_file")
            parser.transfer_var(self._rewrite_path(tmp_result_file_path), 0, 3)
            parser.generate()

        # Run SCRIPT --------------------------------------------------------------------------------
        super().compute(inputs, outputs)

        # Getting input/output files if needed
        if self.options[OPTION_RESULT_FOLDER_PATH] != "":
            for file_path in input_file_list:
                new_path = pth.join(result_folder_path, 'ClCmHT',
                                    pth.split(file_path)[1])
                if pth.exists(file_path):
                    shutil.copyfile(file_path, new_path)
            for file_path in output_file_list:
                new_path = pth.join(result_folder_path, 'ClCmHT',
                                    pth.split(file_path)[1])
                if pth.exists(file_path):
                    shutil.copyfile(file_path, new_path)

        # OPENVSP-AERO: aero calculation ############################################################

        # I/O files --------------------------------------------------------------------------------
        # Duplicate .csv file for multiple run
        input_file_list = [tmp_result_file_path]
        for idx in range(len(_INPUT_AOAList) - 1):
            shutil.copy(
                tmp_result_file_path,
                pth.join(target_directory,
                         _INPUT_AERO_FILE_NAME + str(idx + 1) + '.csv'))
            input_file_list.append(
                pth.join(target_directory,
                         _INPUT_AERO_FILE_NAME + str(idx + 1) + '.csv'))
        output_file_list = []
        for idx in range(len(_INPUT_AOAList)):
            input_file_list.append(
                pth.join(target_directory, _INPUT_AERO_FILE_NAME) + str(idx) +
                '.vspaero')
            output_file_list.append(
                pth.join(target_directory, _INPUT_AERO_FILE_NAME) + str(idx) +
                '.lod')
        self.options["external_input_files"] = input_file_list
        self.options["external_output_files"] = output_file_list

        # Pre-processing (create batch file) -------------------------------------------------------
        self.options["command"] = [pth.join(target_directory, 'vspaero.bat')]
        batch_file = open(self.options["command"][0], "w+")
        batch_file.write("@echo off\n")
        for idx in range(len(_INPUT_AOAList)):
            command = pth.join(target_directory, VSPAERO_EXE_NAME) + ' ' \
                      + pth.join(target_directory, _INPUT_AERO_FILE_NAME + str(idx) + ' >nul 2>nul\n')
            batch_file.write(command)
        batch_file.close()

        # standard AERO input file -----------------------------------------------------------------
        parser = InputFileGenerator()
        for idx in range(len(_INPUT_AOAList)):
            with path(local_resources, _INPUT_AERO_FILE_NAME +
                      '.vspaero') as input_template_path:
                parser.set_template_file(str(input_template_path))
                parser.set_generated_file(input_file_list[len(_INPUT_AOAList) +
                                                          idx])
                parser.reset_anchor()
                parser.mark_anchor("Sref")
                parser.transfer_var(float(sref_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(_INPUT_AOAList[idx]), 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()

        # Run AERO --------------------------------------------------------------------------------
        super().compute(inputs, outputs)

        # Post-processing --------------------------------------------------------------------------
        result_cl = []
        result_cm1 = []
        result_cm2 = []
        for idx in range(len(_INPUT_AOAList)):
            cl_htp, cm_htp, cm_wing = self._read_lod_file(
                output_file_list[idx])
            result_cl.append(cl_htp)
            result_cm1.append(cm_htp)
            result_cm2.append(cm_wing)

        outputs[
            'data:aerodynamics:horizontal_tail:low_speed:alpha'] = np.array(
                _INPUT_AOAList)
        outputs['data:aerodynamics:horizontal_tail:low_speed:CL'] = np.array(
            result_cl)
        outputs['data:aerodynamics:horizontal_tail:low_speed:CM'] = np.array(
            result_cm1)
        outputs['data:aerodynamics:wing:low_speed:alpha'] = np.array(
            _INPUT_AOAList)
        outputs['data:aerodynamics:wing:low_speed:CM'] = np.array(result_cm2)

        # Getting input/output files if needed
        if self.options[OPTION_RESULT_FOLDER_PATH] != "":
            for file_path in input_file_list:
                new_path = pth.join(result_folder_path, 'ClCmHT',
                                    pth.split(file_path)[1])
                if pth.exists(file_path):
                    shutil.copyfile(file_path, new_path)
            for file_path in output_file_list:
                new_path = pth.join(result_folder_path, 'ClCmHT',
                                    pth.split(file_path)[1])
                if pth.exists(file_path):
                    shutil.copyfile(file_path, new_path)

        # Delete temporary directory
        tmp_directory.cleanup()
    def compute(self, inputs, outputs):

        # 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(pth.join(result_folder_path, 'ClAlphaWING'),
                        exist_ok=True)

        # Get inputs (and calculate missing ones)
        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"]
        fa_length = inputs["data:geometry:wing:MAC:at25percent:x"]
        sref_wing = inputs['data:geometry:wing:area']
        span_wing = inputs['data:geometry:wing:span']
        height_max = inputs["data:geometry:fuselage:maximum_height"]
        if self.options["low_speed_aero"]:
            altitude = 0.0
            atm = Atmosphere(altitude)
            mach = inputs["data:aerodynamics:low_speed:mach"]
        else:
            altitude = inputs["data:mission:sizing:main_route:cruise:altitude"]
            atm = Atmosphere(altitude)
            mach = inputs["data:aerodynamics:cruise:mach"]

        # Initial parameters calculation
        x_wing = fa_length - x0_wing - 0.25 * l0_wing
        z_wing = -(height_max - 0.12 * l2_wing) * 0.5
        span2_wing = y4_wing - y2_wing
        viscosity = atm.kinematic_viscosity
        rho = atm.density
        v_inf = max(atm.speed_of_sound * mach, 0.01)  # avoid V=0 m/s crashes
        reynolds = v_inf * l0_wing / viscosity

        # OPENVSP-SCRIPT: Geometry generation ######################################################

        # I/O files --------------------------------------------------------------------------------
        tmp_directory = self._create_tmp_directory()
        # avoid to dump void xternal_code_comp_error.out error file
        self.stderr = pth.join(tmp_directory.name, _STDERR_FILE_NAME)
        if self.options[OPTION_OPENVSP_EXE_PATH]:
            target_directory = pth.abspath(
                self.options[OPTION_OPENVSP_EXE_PATH])
        else:
            target_directory = tmp_directory.name
        input_file_list = [
            pth.join(target_directory, _INPUT_SCRIPT_FILE_NAME),
            pth.join(target_directory, self.options['wing_airfoil_file'])
        ]
        tmp_result_file_path = pth.join(target_directory,
                                        _INPUT_AERO_FILE_NAME + '0.csv')
        output_file_list = [tmp_result_file_path]
        self.options["external_input_files"] = input_file_list
        self.options["external_output_files"] = output_file_list

        # Pre-processing (populating temp directory and generate batch file) -----------------------
        # Copy resource in temp directory if needed
        if not (self.options[OPTION_OPENVSP_EXE_PATH]):
            # noinspection PyTypeChecker
            copy_resource_folder(openvsp3201, target_directory)
            # noinspection PyTypeChecker
            copy_resource(resources, self.options['wing_airfoil_file'],
                          target_directory)
        # Create corresponding .bat file
        self.options["command"] = [pth.join(target_directory, 'vspscript.bat')]
        command = pth.join(target_directory, VSPSCRIPT_EXE_NAME) + ' -script ' \
                  + pth.join(target_directory, _INPUT_SCRIPT_FILE_NAME) + ' >nul 2>nul\n'
        batch_file = open(self.options["command"][0], "w+")
        batch_file.write("@echo off\n")
        batch_file.write(command)
        batch_file.close()

        # standard SCRIPT input file ---------------------------------------------------------------
        parser = InputFileGenerator()
        with path(local_resources,
                  _INPUT_SCRIPT_FILE_NAME) as input_template_path:
            parser.set_template_file(str(input_template_path))
            parser.set_generated_file(input_file_list[0])
            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("airfoil_0_file")
            parser.transfer_var(self._rewrite_path(input_file_list[1]), 0, 3)
            parser.mark_anchor("airfoil_1_file")
            parser.transfer_var(self._rewrite_path(input_file_list[1]), 0, 3)
            parser.mark_anchor("airfoil_2_file")
            parser.transfer_var(self._rewrite_path(input_file_list[1]), 0, 3)
            parser.mark_anchor("csv_file")
            parser.transfer_var(self._rewrite_path(tmp_result_file_path), 0, 3)
            parser.generate()

        # Run SCRIPT --------------------------------------------------------------------------------
        super().compute(inputs, outputs)

        # Getting input/output files if needed
        if self.options[OPTION_RESULT_FOLDER_PATH] != "":
            for file_path in input_file_list:
                new_path = pth.join(result_folder_path, 'ClAlphaWING',
                                    pth.split(file_path)[1])
                if pth.exists(file_path):
                    shutil.copyfile(file_path, new_path)
            for file_path in output_file_list:
                new_path = pth.join(result_folder_path, 'ClAlphaWING',
                                    pth.split(file_path)[1])
                if pth.exists(file_path):
                    shutil.copyfile(file_path, new_path)

        # OPENVSP-AERO: aero calculation ############################################################

        # I/O files --------------------------------------------------------------------------------
        # Duplicate .csv file for multiple run
        input_file_list = [tmp_result_file_path]
        for idx in range(len(_INPUT_AOAList) - 1):
            shutil.copy(
                tmp_result_file_path,
                pth.join(target_directory,
                         _INPUT_AERO_FILE_NAME + str(idx + 1) + '.csv'))
            input_file_list.append(
                pth.join(target_directory,
                         _INPUT_AERO_FILE_NAME + str(idx + 1) + '.csv'))
        output_file_list = []
        for idx in range(len(_INPUT_AOAList)):
            input_file_list.append(
                pth.join(target_directory, _INPUT_AERO_FILE_NAME) + str(idx) +
                '.vspaero')
            output_file_list.append(
                pth.join(target_directory, _INPUT_AERO_FILE_NAME) + str(idx) +
                '.polar')
        output_file_list.append(
            pth.join(target_directory, _INPUT_AERO_FILE_NAME) + '0.lod')
        self.options["external_input_files"] = input_file_list
        self.options["external_output_files"] = output_file_list

        # Pre-processing (create batch file) -------------------------------------------------------
        self.options["command"] = [pth.join(target_directory, 'vspaero.bat')]
        batch_file = open(self.options["command"][0], "w+")
        batch_file.write("@echo off\n")
        for idx in range(len(_INPUT_AOAList)):
            command = pth.join(target_directory, VSPAERO_EXE_NAME) + ' ' \
                      + pth.join(target_directory, _INPUT_AERO_FILE_NAME + str(idx) + ' >nul 2>nul\n')
            batch_file.write(command)
        batch_file.close()

        # standard AERO input file -----------------------------------------------------------------
        parser = InputFileGenerator()
        for idx in range(len(_INPUT_AOAList)):
            with path(local_resources, _INPUT_AERO_FILE_NAME +
                      '.vspaero') as input_template_path:
                parser.set_template_file(str(input_template_path))
                parser.set_generated_file(input_file_list[len(_INPUT_AOAList) +
                                                          idx])
                parser.reset_anchor()
                parser.mark_anchor("Sref")
                parser.transfer_var(float(sref_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(_INPUT_AOAList[idx]), 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()

        # Run AERO --------------------------------------------------------------------------------
        super().compute(inputs, outputs)

        # Post-processing --------------------------------------------------------------------------
        result_cl = []
        for idx in range(len(_INPUT_AOAList)):
            cl, _, _, _ = self._read_polar_file(output_file_list[idx])
            result_cl.append(cl)
        # Fuselage correction
        k_fus = 1 + 0.025 * width_max / span_wing - 0.025 * (width_max /
                                                             span_wing)**2
        cl_0 = float(result_cl[0] * k_fus)
        cl_1 = float(result_cl[1] * k_fus)
        # Calculate derivative
        cl_alpha = (cl_1 - cl_0) / (
            (_INPUT_AOAList[1] - _INPUT_AOAList[0]) * math.pi / 180)
        # Get lift curve
        y_vector, cl_vector = self._read_lod_file(output_file_list[-1])
        real_length = min(SPAN_MESH_POINT_OPENVSP, len(y_vector))
        if real_length < len(y_vector):
            warnings.warn(
                "Defined maximum span mesh in constants.py exceeded!")

        if self.options["low_speed_aero"]:
            outputs['data:aerodynamics:aircraft:low_speed:CL0_clean'] = cl_0
            outputs['data:aerodynamics:aircraft:low_speed:CL_alpha'] = cl_alpha
            if real_length >= len(y_vector):
                outputs[
                    'data:aerodynamics:wing:low_speed:Y_vector'] = np.zeros(
                        SPAN_MESH_POINT_OPENVSP)
                outputs[
                    'data:aerodynamics:wing:low_speed:CL_vector'] = np.zeros(
                        SPAN_MESH_POINT_OPENVSP)
                outputs['data:aerodynamics:wing:low_speed:Y_vector'][
                    0:real_length] = y_vector
                outputs['data:aerodynamics:wing:low_speed:CL_vector'][
                    0:real_length] = cl_vector
            else:
                outputs[
                    'data:aerodynamics:aircraft:wing:Y_vector'] = np.linspace(
                        y_vector[0], y_vector[1], SPAN_MESH_POINT_OPENVSP)
                outputs['data:aerodynamics:aircraft:wing:CL_vector'] = \
                    np.interp(outputs['data:aerodynamics:aircraft:low_speed:Y_vector'], y_vector, cl_vector)
        else:
            outputs['data:aerodynamics:aircraft:cruise:CL0_clean'] = cl_0
            outputs['data:aerodynamics:aircraft:cruise:CL_alpha'] = cl_alpha

        # Getting input/output files if needed
        if self.options[OPTION_RESULT_FOLDER_PATH] != "":
            for file_path in input_file_list:
                new_path = pth.join(result_folder_path, 'ClAlphaWING',
                                    pth.split(file_path)[1])
                if pth.exists(file_path):
                    shutil.copyfile(file_path, new_path)
            for file_path in output_file_list:
                new_path = pth.join(result_folder_path, 'ClAlphaWING',
                                    pth.split(file_path)[1])
                if pth.exists(file_path):
                    shutil.copyfile(file_path, new_path)

        # Delete temporary directory
        tmp_directory.cleanup()