├── .gitattributes
├── .gitignore
├── CMakeLists.txt
├── LICENSE
├── README.md
├── naca0012-lift-curve.png
├── old_setup.py
├── pyproject.toml
├── runs
├── cp_060_050.387
├── cp_100_040.387
├── cp_250_040.203
├── cp_500_080.lnv
├── dae11.dat
├── dae21.dat
├── dae31.dat
├── dae51.dat
├── e387.dat
├── e387_09.100
├── e387_11.100
├── la203.bl
├── la203.dat
├── la203t.dat
├── lnv109a.dat
├── polref_100.387
└── tad.dat
├── setup.py
└── src
├── __init__.py
├── example_data
└── bl.txt
├── fortran
├── api.f90
├── i_blpar.f90
├── i_circle.f90
├── i_pindex.f90
├── i_xbl.f90
├── i_xfoil.f90
├── m_aread.f90
├── m_iopol.f90
├── m_naca.f90
├── m_sort.f90
├── m_spline.f90
├── m_userio.f90
├── m_xbl.f90
├── m_xblsys.f90
├── m_xfoil.f90
├── m_xgdes.f90
├── m_xgeom.f90
├── m_xmdes.f90
├── m_xoper.f90
├── m_xpanel.f90
├── m_xpol.f90
├── m_xqdes.f90
├── m_xsolve.f90
├── m_xutils.f90
├── p_xfoil.f90
├── s_xbl.f90
├── s_xfoil.f90
└── s_xoper.f90
└── xfoil
├── __init__.py
├── bdlayer.py
├── cpdist.py
├── model.py
├── model_parametrized.py
├── test.py
└── xfoil.py
/.gitattributes:
--------------------------------------------------------------------------------
1 | static/* linguist-vendored
2 |
3 | # Basic .gitattributes for a python repo.
4 |
5 | # Source files
6 | # ============
7 | *.pxd text diff=python
8 | *.py text diff=python
9 | *.py3 text diff=python
10 | *.pyw text diff=python
11 | *.ipynb text
12 | *.pyx text diff=python
13 |
14 | # Binary files
15 | # ============
16 | *.db binary
17 | *.p binary
18 | *.pkl binary
19 | *.pickle binary
20 | *.pyc binary
21 | *.pyd binary
22 | *.pyo binary
23 |
24 | # Note: .db, .p, and .pkl files are associated
25 | # with the python modules ``pickle``, ``dbm.*``,
26 | # ``shelve``, ``marshal``, ``anydbm``, & ``bsddb``
27 | # (among others).
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 | dist/
3 | *.egg-info/
4 | venv/
5 | .idea/
6 | cmake-build-debug/
7 | pip-wheel-metadata/xfoil.dist-info/LICENSE
8 | pip-wheel-metadata/xfoil.dist-info/METADATA
9 | src/xfoil/__pycache__/test.cpython-36.pyc
10 | :00.bl
11 | Untitled.ipynb
12 | .ipynb_checkpoints/Untitled-checkpoint.ipynb
13 | .vscode/settings.json
14 | pip-wheel-metadata/xfoil.dist-info/top_level.txt
15 | src/__pycache__/__init__.cpython-36.pyc
16 | src/fortran/i_circle.mod
17 | src/fortran/i_pindex.mod
18 | src/xfoil/__pycache__/__init__.cpython-36.pyc
19 | src/xfoil/__pycache__/model.cpython-36.pyc
20 | src/xfoil/__pycache__/xfoil.cpython-36.pyc
21 | build_backup
22 | *.ipynb
23 | *.mod
24 |
25 | .vscode
26 | src/xfoil/__pycache__/*
27 | notebooks/*
28 | boundary_layer.txt
29 | cp.txt
30 | debug.py
31 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.12)
2 | project(xfoil Fortran)
3 |
4 | enable_language(Fortran)
5 | set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} \
6 | -O \
7 | -fbounds-check \
8 | -finit-real=inf \
9 | -ffpe-trap=invalid,zero \
10 | -fdefault-real-8")
11 | set(SRC_DIR "src/fortran")
12 |
13 | add_library(xfoil SHARED
14 | # Include modules
15 | ${SRC_DIR}/i_pindex.f90
16 | ${SRC_DIR}/i_xfoil.f90
17 | ${SRC_DIR}/i_blpar.f90
18 | ${SRC_DIR}/i_circle.f90
19 | ${SRC_DIR}/i_xbl.f90
20 | # Shared modules to avoid circular dependencies
21 | ${SRC_DIR}/s_xbl.f90
22 | ${SRC_DIR}/s_xoper.f90
23 | ${SRC_DIR}/s_xfoil.f90
24 | # Main modules
25 | ${SRC_DIR}/m_aread.f90
26 | ${SRC_DIR}/m_iopol.f90
27 | ${SRC_DIR}/m_naca.f90
28 | ${SRC_DIR}/m_sort.f90
29 | ${SRC_DIR}/m_spline.f90
30 | ${SRC_DIR}/m_userio.f90
31 | ${SRC_DIR}/m_xbl.f90
32 | ${SRC_DIR}/m_xblsys.f90
33 | ${SRC_DIR}/m_xfoil.f90
34 | ${SRC_DIR}/m_xgdes.f90
35 | ${SRC_DIR}/m_xgeom.f90
36 | ${SRC_DIR}/m_xmdes.f90
37 | ${SRC_DIR}/m_xoper.f90
38 | ${SRC_DIR}/m_xpanel.f90
39 | ${SRC_DIR}/m_xpol.f90
40 | ${SRC_DIR}/m_xqdes.f90
41 | ${SRC_DIR}/m_xsolve.f90
42 | ${SRC_DIR}/m_xutils.f90
43 | # API
44 | ${SRC_DIR}/api.f90)
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | > **IMPORTANT NOTE: major changes and upgrades are currently taking place. This readme file might not be up to date. Please contact me if you need any details on current usage. (July 2020)**
2 |
3 | General
4 | -------
5 | This is a stripped down version of XFOIL, presented in the form of a Python module. What's unique about this package
6 | w.r.t. many others out there allowing an interface to XFOIL, is the fact that the Python code talks directly to a
7 | compiled Fortran library. This approach avoids having to read/write in-/output files to the disk and communicating with
8 | the XFOIl executable. Eliminating the need for constant disk I/O operations can significantly speed up parallel
9 | frameworks in particular, giving this approach a clear advantage.
10 |
11 | Building and Installing the Python Module
12 | -----------------------------------------
13 | See https://github.com/KikeM/xfoil-python/issues/7#issuecomment-659533863 for installation instructions.
14 |
15 | Using the Module
16 | ----------------
17 | All XFoil operations are performed using the `XFoil` class. So the first step when using this module is to create an
18 | instance of this class:
19 |
20 | ```pycon
21 | >>> from xfoil import XFoil
22 | >>> xf = XFoil()
23 | ```
24 |
25 | If this does not produce any errors, the installation should be functioning properly.
26 |
27 |
28 | The symmetric NACA 0012 airfoil is included as a test case. It can be loaded into the XFoil library like this:
29 |
30 | ```pycon
31 | >>> from xfoil.test import naca0012
32 | >>> xf.airfoil = naca0012
33 |
34 | Number of input coordinate points: 160
35 | Counterclockwise ordering
36 | Max thickness = 0.120008 at x = 0.308
37 | Max camber = 0.000000 at x = 0.033
38 |
39 | LE x,y = -0.00000 0.00000 | Chord = 1.00000
40 | TE x,y = 1.00000 0.00000 |
41 |
42 | Current airfoil nodes set from buffer airfoil nodes ( 160 )
43 | ```
44 |
45 | Once the airfoil has been loaded successfully it can be analyzed. Let's analyze it for a range of angles of attack, at a
46 | Reynolds number of one million. Let's limit the maximum number of iterations to 40 (the default is 20) as well.
47 | For the range of angles of attack, we will go from -20 degrees to 20 degrees with steps of 0.5 degrees:
48 |
49 | ```pycon
50 | >>> xf.Re = 1e6
51 | >>> xf.max_iter = 40
52 | >>> a, cl, cd, cm = xf.aseq(-20, 20, 0.5)
53 | ```
54 |
55 | The XFOIL library should produce a lot of output, which should be familiar to those who have used the original XFOIL
56 | application before. The final result are lists of angles of attack, `a`, and the corresponding lift coefficients, `cl`,
57 | drag coefficients, `cd`, and moment coefficients, `cm`. We can now, for example, plot the lift curve for this airfoil:
58 |
59 | ```pycon
60 | >>> import matplotlib.pyplot as plt
61 | >>> plt.plot(a, cl)
62 | >>> plt.show()
63 | ```
64 |
65 | This should produce the following figure:
66 |
67 | 
68 |
69 | Just like in the original XFOIL application, an airfoil can also analyzed for a single angle of attack, single lift
70 | coefficient, or a range of lift coefficients. The commands for these operations are
71 |
72 | ```pycon
73 | >>> cl, cd, cm = xf.a(10)
74 | >>> a, cd, cm = xf.cl(1)
75 | >>> a, cl, cd, cm = xf.cseq(-0.5, 0.5, 0.05)
76 | ```
77 |
78 | to analyze for an angle of attack of 10 degrees, a lift coefficient of 1.0, and for a range of lift coefficients from
79 | -0.5 to 0.5 with steps of 0.05.
80 |
81 | For other features and specifics, see the documentation in the Python source files.
82 |
83 |
--------------------------------------------------------------------------------
/naca0012-lift-curve.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/emvalbuena/xfoil-python/7b09c55b149d121740724126741e7e3967667fff/naca0012-lift-curve.png
--------------------------------------------------------------------------------
/old_setup.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Copyright (c) 2019 D. de Vries
3 | #
4 | # This file is part of XFoil.
5 | #
6 | # XFoil is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # XFoil is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with XFoil. If not, see .
18 | import os
19 | import platform
20 | import subprocess
21 | import sys
22 |
23 | from setuptools import setup
24 | from setuptools.extension import Extension
25 | from setuptools.command.build_ext import build_ext
26 |
27 | version = '0.0.16'
28 |
29 | options = {k: 'OFF' for k in ['--opt', '--debug', '--cuda']}
30 | for flag in options.keys():
31 | if flag in sys.argv:
32 | options[flag] = 'ON'
33 | sys.argv.remove(flag)
34 |
35 | # Command line flags forwarded to CMake
36 | cmake_cmd_args = []
37 | for f in sys.argv:
38 | if f.startswith('-D'):
39 | cmake_cmd_args.append(f)
40 | sys.argv.remove(f)
41 |
42 |
43 | class CMakeExtension(Extension):
44 |
45 | def __init__(self, name, cmake_list_dir='.', **kwargs):
46 | super().__init__(name, sources=[], **kwargs)
47 | self.cmake_lists_dir = os.path.abspath(cmake_list_dir)
48 |
49 |
50 | class CMakeBuild(build_ext):
51 |
52 | def build_extensions(self):
53 | # Ensure that CMake is present and working
54 | try:
55 | out = subprocess.check_output(['cmake', '--version'])
56 | except OSError:
57 | raise RuntimeError('Cannot find CMake executable')
58 |
59 | for ext in self.extensions:
60 | extdir = os.path.abspath(os.path.dirname(self.get_ext_fullpath(ext.name)))
61 | cfg = 'Debug' if options['--debug'] == 'ON' else 'Release'
62 |
63 | cmake_args = [
64 | '-DCMAKE_BUILD_TYPE=%s' % cfg,
65 | # Ask CMake to place the resulting library in the directory
66 | # containing the extension
67 | '-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}'.format(cfg.upper(), extdir),
68 | # Other intermediate static libraries are placed in a
69 | # temporary build directory instead
70 | '-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_{}={}'.format(cfg.upper(), self.build_temp),
71 | # Hint CMake to use the same Python executable that
72 | # is launching the build, prevents possible mismatching if
73 | # multiple versions of Python are installed
74 | '-DPYTHON_EXECUTABLE={}'.format(sys.executable),
75 | # Add other project-specific CMake arguments if needed
76 | '-DCMAKE_Fortran_COMPILER=/usr/local/bin/gfortran',
77 | '-DCMAKE_MAKE_PROGRAM=make',
78 | ]
79 |
80 | # We can handle some platform-specific settings at our discretion
81 | if platform.system() == 'Windows':
82 | plat = ('x64' if platform.architecture()[0] == '64bit' else 'Win32')
83 | cmake_args += [
84 | # These options are likely to be needed under Windows
85 | '-DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=TRUE',
86 | '-DCMAKE_RUNTIME_OUTPUT_DIRECTORY_{}={}'.format(cfg.upper(), extdir),
87 | ]
88 | # Assuming that Visual Studio and MinGW are supported compilers
89 | if self.compiler.compiler_type == 'msvc':
90 | cmake_args += [
91 | '-DCMAKE_GENERATOR_PLATFORM=%s' % plat,
92 | ]
93 | else:
94 | cmake_args += [
95 | '-G', 'MinGW Makefiles',
96 | ]
97 |
98 | cmake_args += cmake_cmd_args
99 |
100 | print(cmake_args)
101 |
102 | if not os.path.exists(self.build_temp):
103 | os.makedirs(self.build_temp)
104 |
105 | # Config and build the extension
106 | subprocess.check_call(['cmake', ext.cmake_lists_dir] + cmake_args,
107 | cwd=self.build_temp)
108 | subprocess.check_call(['cmake', '--build', '.', '--config', cfg],
109 | cwd=self.build_temp)
110 |
111 |
112 | def readme():
113 | with open('README.md') as f:
114 | return f.read()
115 |
116 |
117 | setup(
118 | name='xfoil',
119 | version=version,
120 | description='Stripped down version of XFOIL as compiled python module ',
121 | long_description=readme(),
122 | classifiers=[
123 | 'Development Status :: 3 - Alpha',
124 | 'Intended Audience :: Science/Research',
125 | 'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)',
126 | 'Natural Language :: English',
127 | 'Operating System :: MacOS :: MacOS X',
128 | 'Operating System :: POSIX :: Linux',
129 | 'Operating System :: Microsoft :: Windows',
130 | 'Programming Language :: Fortran',
131 | 'Programming Language :: Python :: 3 :: Only',
132 | 'Topic :: Scientific/Engineering',
133 | ],
134 | keywords='xfoil airfoil aerodynamic analysis',
135 | url='https://github.com/daniel-de-vries/xfoil-python',
136 | download_url='https://github.com/daniel-de-vries/xfoil-python/tarball/' + version,
137 | author='Daniël de Vries',
138 | author_email='contact@daniel-de-vries.com',
139 | license='GNU General Public License v3 or later (GPLv3+)',
140 | packages=['xfoil'],
141 | package_dir={'': 'src'},
142 | ext_modules=[CMakeExtension('xfoil.xfoil')],
143 | cmdclass={'build_ext': CMakeBuild},
144 | install_requires=['numpy'],
145 | zip_save=False
146 | )
147 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = ["scikit-build", "cmake"]
--------------------------------------------------------------------------------
/runs/cp_060_050.387:
--------------------------------------------------------------------------------
1 | 0.950 -0.0370 | CL=0.838 (a=5 deg nominal) Re=60000
2 | 0.900 -0.1214
3 | 0.850 -0.2418
4 | 0.800 -0.4137
5 | 0.750 -0.5977
6 | 0.700 -0.6307
7 | 0.650 -0.6126
8 | 0.600 -0.6075
9 | 0.550 -0.5985
10 | 0.500 -0.5990
11 | 0.450 -0.6124
12 | 0.400 -0.6330
13 | 0.350 -0.6652
14 | 0.300 -0.7310
15 | 0.250 -0.8065
16 | 0.200 -0.8648
17 | 0.150 -0.9291
18 | 0.100 -1.0042
19 | 0.075 -1.0262
20 | 0.060 -1.0360
21 | 0.050 -1.0463
22 | 0.040 -1.0469
23 | 0.030 -1.0311
24 | 0.025 -1.0353
25 | 0.020 -1.0571
26 | 0.015 -1.0064
27 | 0.010 -0.9906
28 | 0.005 -0.8359
29 | 0.0 0.4274
30 | 0.950 0.1178
31 | 0.900 0.1461
32 | 0.850 0.1603
33 | 0.800 0.1754
34 | 0.750 0.1786
35 | 0.700 0.1837
36 | 0.650 0.1912
37 | 0.600 0.1977
38 | 0.550 0.1983
39 | 0.500 0.2044
40 | 0.450 0.2144
41 | 0.400 0.2156
42 | 0.350 0.2243
43 | 0.300 0.2354
44 | 0.250 0.2380
45 | 0.200 0.2570
46 | 0.150 0.2817
47 | 0.100 0.3200
48 | 0.075 0.3595
49 | 0.060 0.3932
50 | 0.050 0.4291
51 | 0.040 0.4701
52 | 0.031 0.5370
53 | 0.025 0.5845
54 | 0.020 0.6551
55 | 0.015 0.7133
56 | 0.010 0.8403
57 | 0.005 0.9710
58 |
--------------------------------------------------------------------------------
/runs/cp_100_040.387:
--------------------------------------------------------------------------------
1 | # Langley Cp data
2 | 0.950 0.0451 | CL=0.778 (a=4 deg nominal) Re=100000
3 | 0.900 -.0008
4 | 0.850 -.0410
5 | 0.800 -.1223
6 | 0.750 -.3670
7 | 0.700 -.6230
8 | 0.650 -.6383
9 | 0.600 -.6343
10 | 0.550 -.6327
11 | 0.500 -.6351
12 | 0.450 -.6557
13 | 0.400 -.6849
14 | 0.350 -.7470
15 | 0.300 -.8061
16 | 0.250 -.8481
17 | 0.200 -.8876
18 | 0.150 -.9254
19 | 0.100 -.9656
20 | 0.075 -.9831
21 | 0.060 -.9826
22 | 0.050 -.9700
23 | 0.040 -.9659
24 | 0.030 -.9529
25 | 0.025 -.9409
26 | 0.020 -.9137
27 | 0.015 -.8654
28 | 0.010 -.8129
29 | 0.005 -.6744
30 | 0.0 0.6121
31 | 0.950 0.1352
32 | 0.900 0.1558
33 | 0.850 0.1623
34 | 0.800 0.1692
35 | 0.750 0.1688
36 | 0.700 0.1743
37 | 0.650 0.1755
38 | 0.600 0.1795
39 | 0.550 0.1787
40 | 0.500 0.1851
41 | 0.450 0.1902
42 | 0.400 0.1894
43 | 0.350 0.1963
44 | 0.300 0.1978
45 | 0.250 0.1970
46 | 0.200 0.2121
47 | 0.150 0.2204
48 | 0.100 0.2585
49 | 0.075 0.2879
50 | 0.060 0.3143
51 | 0.050 0.3489
52 | 0.040 0.3891
53 | 0.031 0.4545
54 | 0.025 0.4966
55 | 0.020 0.5466
56 | 0.015 0.6190
57 | 0.010 0.7428
58 | 0.005 0.9269
59 |
--------------------------------------------------------------------------------
/runs/cp_250_040.203:
--------------------------------------------------------------------------------
1 | 1.000 0.088 | CL=1.08 (a=4 deg nominal) Re=250000
2 | 0.950 -.051
3 | 0.900 -.102
4 | 0.850 -.196
5 | 0.800 -.293
6 | 0.750 -.386
7 | 0.700 -.458
8 | 0.675 -.481
9 | 0.650 -.719
10 | 0.625 -1.098
11 | 0.600 -1.098
12 | 0.575 -1.098
13 | 0.550 -1.098
14 | 0.525 -1.098
15 | 0.500 -1.123
16 | 0.475 -1.146
17 | 0.450 -1.195
18 | 0.425 -1.244
19 | 0.400 -1.291
20 | 0.375 -1.344
21 | 0.350 -1.344
22 | 0.325 -1.363
23 | 0.300 -1.388
24 | 0.250 -1.388
25 | 0.200 -1.363
26 | 0.150 -1.342
27 | 0.100 -1.246
28 | 0.075 -1.195
29 | 0.050 -1.144
30 | 0.025 -1.007
31 | 0.012 -.811
32 | 0.000 0.760
33 | 0.012 0.430
34 | 0.025 0.140
35 | 0.050 0.189
36 | 0.075 0.189
37 | 0.100 0.189
38 | 0.150 0.189
39 | 0.200 0.160
40 | 0.300 0.163
41 | 0.400 0.140
42 | 0.500 0.139
43 | 0.600 0.189
44 | 0.700 0.212
45 | 0.800 0.212
46 | 0.850 0.237
47 | 0.900 0.330
48 | 0.950 0.430
49 |
--------------------------------------------------------------------------------
/runs/cp_500_080.lnv:
--------------------------------------------------------------------------------
1 | 1.000 0.055 | CL=1.234 (a=8 deg nominal) Re=500000
2 | 0.950 0.050
3 | 0.900 0.020
4 | 0.850 0.000
5 | 0.800 -.045
6 | 0.750 -.105
7 | 0.700 -.150
8 | 0.650 -.222
9 | 0.600 -.309
10 | 0.550 -.418
11 | 0.500 -.567
12 | 0.450 -.743
13 | 0.425 -.860
14 | 0.400 -1.216
15 | 0.375 -1.775
16 | 0.350 -1.784
17 | 0.325 -1.784
18 | 0.300 -1.870
19 | 0.275 -1.944
20 | 0.250 -2.022
21 | 0.225 -2.072
22 | 0.200 -2.111
23 | 0.150 -2.126
24 | 0.100 -2.063
25 | 0.075 -2.005
26 | 0.050 -1.946
27 | 0.025 -1.805
28 | 0.012 -1.171
29 | 0.000 0.202
30 | 0.012 0.750
31 | 0.025 0.486
32 | 0.050 0.414
33 | 0.075 0.400
34 | 0.100 0.408
35 | 0.150 0.400
36 | 0.200 0.395
37 | 0.300 0.336
38 | 0.400 0.371
39 | 0.500 0.357
40 | 0.600 0.332
41 | 0.700 0.250
42 | 0.800 0.211
43 | 0.900 0.152
44 | 0.950 0.077
45 |
--------------------------------------------------------------------------------
/runs/dae11.dat:
--------------------------------------------------------------------------------
1 | DAE 11
2 | # Daedalus wing center panel airfoil. Design Re = 500K
3 | 1.000000 0.000000
4 | 0.986485 0.002537
5 | 0.970011 0.005613
6 | 0.947881 0.010041
7 | 0.918618 0.016374
8 | 0.887980 0.023556
9 | 0.857968 0.031118
10 | 0.827970 0.039139
11 | 0.797803 0.047590
12 | 0.767378 0.056399
13 | 0.736634 0.065482
14 | 0.705687 0.074715
15 | 0.675260 0.083695
16 | 0.645478 0.092177
17 | 0.616310 0.099961
18 | 0.587628 0.106875
19 | 0.559192 0.112804
20 | 0.530735 0.117738
21 | 0.502104 0.121740
22 | 0.473284 0.124848
23 | 0.444338 0.127068
24 | 0.415323 0.128391
25 | 0.386255 0.128806
26 | 0.357167 0.128336
27 | 0.328135 0.126996
28 | 0.299232 0.124754
29 | 0.270512 0.121609
30 | 0.242030 0.117536
31 | 0.213885 0.112508
32 | 0.186216 0.106500
33 | 0.159197 0.099489
34 | 0.133039 0.091476
35 | 0.108024 0.082466
36 | 0.084520 0.072514
37 | 0.062995 0.061754
38 | 0.044085 0.050490
39 | 0.028485 0.039251
40 | 0.016619 0.028679
41 | 0.008417 0.019287
42 | 0.003417 0.011421
43 | 0.000883 0.005097
44 | 0.000128 0.000182
45 | 0.000626 -0.003555
46 | 0.002138 -0.006473
47 | 0.004541 -0.008835
48 | 0.008212 -0.010744
49 | 0.014240 -0.012418
50 | 0.024697 -0.013921
51 | 0.041573 -0.014931
52 | 0.065014 -0.015107
53 | 0.092723 -0.014502
54 | 0.122696 -0.013331
55 | 0.153786 -0.011784
56 | 0.185487 -0.010003
57 | 0.217549 -0.008087
58 | 0.249834 -0.006102
59 | 0.282263 -0.004093
60 | 0.314698 -0.002099
61 | 0.347047 -0.000149
62 | 0.379318 0.001724
63 | 0.411508 0.003509
64 | 0.443624 0.005174
65 | 0.475671 0.006709
66 | 0.507637 0.008092
67 | 0.539527 0.009282
68 | 0.571366 0.010264
69 | 0.603162 0.011026
70 | 0.634928 0.011552
71 | 0.666677 0.011849
72 | 0.698414 0.011916
73 | 0.730135 0.011759
74 | 0.761819 0.011381
75 | 0.793447 0.010763
76 | 0.825020 0.009891
77 | 0.856580 0.008751
78 | 0.888343 0.007325
79 | 0.920025 0.005610
80 | 0.948000 0.003865
81 | 0.969655 0.002348
82 | 0.986285 0.001076
83 | 1.000000 0.000000
84 |
--------------------------------------------------------------------------------
/runs/dae21.dat:
--------------------------------------------------------------------------------
1 | DAE 21
2 | # Daedalus outer panel break airfoil. Design Re = 375K
3 | 1.000000 0.000000
4 | 0.986712 0.002418
5 | 0.970362 0.005492
6 | 0.947691 0.010083
7 | 0.917703 0.016743
8 | 0.887293 0.024120
9 | 0.857161 0.031966
10 | 0.826867 0.040283
11 | 0.796262 0.048982
12 | 0.765287 0.057938
13 | 0.734180 0.066919
14 | 0.703358 0.075625
15 | 0.672878 0.083860
16 | 0.642725 0.091437
17 | 0.612839 0.098204
18 | 0.583189 0.104141
19 | 0.553743 0.109238
20 | 0.524452 0.113495
21 | 0.495245 0.116921
22 | 0.466044 0.119541
23 | 0.436797 0.121383
24 | 0.407512 0.122444
25 | 0.378226 0.122715
26 | 0.348985 0.122181
27 | 0.319838 0.120829
28 | 0.290842 0.118635
29 | 0.262053 0.115583
30 | 0.233558 0.111651
31 | 0.205468 0.106814
32 | 0.177922 0.101046
33 | 0.151092 0.094310
34 | 0.125176 0.086572
35 | 0.100450 0.077840
36 | 0.077317 0.068163
37 | 0.056331 0.057700
38 | 0.038181 0.046773
39 | 0.023556 0.035891
40 | 0.012848 0.025735
41 | 0.005879 0.016869
42 | 0.001956 0.009449
43 | 0.000266 0.003383
44 | 0.000061 -0.001451
45 | 0.000768 -0.005145
46 | 0.002174 -0.007971
47 | 0.004373 -0.010203
48 | 0.007802 -0.012025
49 | 0.013654 -0.013482
50 | 0.024269 -0.014572
51 | 0.041672 -0.014985
52 | 0.065976 -0.014369
53 | 0.094566 -0.012972
54 | 0.125275 -0.011034
55 | 0.156913 -0.008816
56 | 0.189022 -0.006461
57 | 0.221380 -0.004063
58 | 0.253714 -0.001687
59 | 0.285949 0.000632
60 | 0.318102 0.002874
61 | 0.350185 0.005015
62 | 0.382195 0.007039
63 | 0.414128 0.008920
64 | 0.445987 0.010630
65 | 0.477768 0.012157
66 | 0.509472 0.013465
67 | 0.541126 0.014532
68 | 0.572758 0.015351
69 | 0.604367 0.015925
70 | 0.635947 0.016240
71 | 0.667511 0.016282
72 | 0.699072 0.016053
73 | 0.730622 0.015565
74 | 0.762134 0.014807
75 | 0.793605 0.013763
76 | 0.825056 0.012422
77 | 0.856541 0.010783
78 | 0.888226 0.008848
79 | 0.920042 0.006634
80 | 0.948501 0.004447
81 | 0.970227 0.002643
82 | 0.986570 0.001203
83 | 1.000000 0.000000
84 |
--------------------------------------------------------------------------------
/runs/dae31.dat:
--------------------------------------------------------------------------------
1 | DAE 31
2 | # Daedalus tip panel airfoil (4ft from tip). Design Re = 250K
3 | 1.000000 0.000000
4 | 0.983670 0.003678
5 | 0.964831 0.008217
6 | 0.942298 0.013939
7 | 0.915136 0.021198
8 | 0.884751 0.029762
9 | 0.854418 0.038671
10 | 0.823963 0.047867
11 | 0.793343 0.057188
12 | 0.763399 0.066115
13 | 0.734041 0.074433
14 | 0.705002 0.082031
15 | 0.676045 0.088917
16 | 0.647058 0.095104
17 | 0.617978 0.100577
18 | 0.588755 0.105349
19 | 0.559366 0.109434
20 | 0.529812 0.112852
21 | 0.500123 0.115621
22 | 0.470348 0.117747
23 | 0.440557 0.119235
24 | 0.410816 0.120061
25 | 0.381154 0.120198
26 | 0.351603 0.119637
27 | 0.322220 0.118356
28 | 0.293057 0.116321
29 | 0.264162 0.113501
30 | 0.235612 0.109876
31 | 0.207525 0.105414
32 | 0.180030 0.100065
33 | 0.153293 0.093810
34 | 0.127559 0.086629
35 | 0.103134 0.078508
36 | 0.080386 0.069477
37 | 0.059755 0.059645
38 | 0.041713 0.049168
39 | 0.026721 0.038403
40 | 0.015173 0.027944
41 | 0.007269 0.018571
42 | 0.002584 0.010709
43 | 0.000358 0.004518
44 | 0.000025 -0.000558
45 | 0.000189 -0.002800
46 | 0.001175 -0.006664
47 | 0.002966 -0.009596
48 | 0.005693 -0.011873
49 | 0.009988 -0.013595
50 | 0.017247 -0.014838
51 | 0.029729 -0.015535
52 | 0.049021 -0.015193
53 | 0.074285 -0.013756
54 | 0.102957 -0.011523
55 | 0.133315 -0.008820
56 | 0.164511 -0.005908
57 | 0.196175 -0.002926
58 | 0.228118 0.000031
59 | 0.260168 0.002902
60 | 0.292125 0.005647
61 | 0.323993 0.008244
62 | 0.355786 0.010669
63 | 0.387504 0.012911
64 | 0.419145 0.014938
65 | 0.450717 0.016729
66 | 0.482216 0.018267
67 | 0.513641 0.019520
68 | 0.545019 0.020458
69 | 0.576374 0.021089
70 | 0.607695 0.021417
71 | 0.638977 0.021429
72 | 0.670233 0.021125
73 | 0.701474 0.020513
74 | 0.732690 0.019612
75 | 0.763858 0.018421
76 | 0.794976 0.016921
77 | 0.826072 0.015114
78 | 0.857232 0.012998
79 | 0.888815 0.010562
80 | 0.919284 0.007958
81 | 0.945604 0.005528
82 | 0.967071 0.003429
83 | 0.984882 0.001590
84 | 1.000000 0.000000
85 |
--------------------------------------------------------------------------------
/runs/dae51.dat:
--------------------------------------------------------------------------------
1 | DAE 51
2 | # Daedalus propeller airfoil
3 | 1.000000 -0.000051
4 | 0.989166 0.001996
5 | 0.975819 0.004501
6 | 0.957448 0.007991
7 | 0.931599 0.013004
8 | 0.901654 0.018957
9 | 0.870818 0.025167
10 | 0.839998 0.031363
11 | 0.809336 0.037430
12 | 0.778839 0.043301
13 | 0.748503 0.048933
14 | 0.718326 0.054243
15 | 0.688314 0.059175
16 | 0.658443 0.063716
17 | 0.628653 0.067839
18 | 0.598855 0.071530
19 | 0.569004 0.074792
20 | 0.539074 0.077652
21 | 0.509071 0.080095
22 | 0.479015 0.082100
23 | 0.448934 0.083641
24 | 0.418877 0.084690
25 | 0.388863 0.085217
26 | 0.358908 0.085197
27 | 0.329049 0.084600
28 | 0.299321 0.083399
29 | 0.269760 0.081570
30 | 0.240419 0.079081
31 | 0.211388 0.075895
32 | 0.182766 0.071967
33 | 0.154699 0.067243
34 | 0.127404 0.061670
35 | 0.101193 0.055204
36 | 0.076503 0.047832
37 | 0.054060 0.039675
38 | 0.034881 0.031085
39 | 0.020059 0.022737
40 | 0.010052 0.015405
41 | 0.004208 0.009557
42 | 0.001251 0.005050
43 | 0.000113 0.001479
44 | 0.000123 -0.001494
45 | 0.001002 -0.004085
46 | 0.002793 -0.006422
47 | 0.006019 -0.008524
48 | 0.011960 -0.010609
49 | 0.022698 -0.012727
50 | 0.040333 -0.014554
51 | 0.064233 -0.015717
52 | 0.091882 -0.016173
53 | 0.121305 -0.016067
54 | 0.151560 -0.015570
55 | 0.182231 -0.014790
56 | 0.213149 -0.013797
57 | 0.244240 -0.012649
58 | 0.275464 -0.011392
59 | 0.306798 -0.010061
60 | 0.338230 -0.008690
61 | 0.369725 -0.007318
62 | 0.401184 -0.005962
63 | 0.432597 -0.004640
64 | 0.463976 -0.003366
65 | 0.495325 -0.002147
66 | 0.526644 -0.000994
67 | 0.557930 0.000082
68 | 0.589182 0.001071
69 | 0.620390 0.001960
70 | 0.651547 0.002731
71 | 0.682648 0.003367
72 | 0.713694 0.003847
73 | 0.744690 0.004152
74 | 0.775644 0.004269
75 | 0.806546 0.004190
76 | 0.837373 0.003898
77 | 0.868134 0.003359
78 | 0.898985 0.002532
79 | 0.929868 0.001410
80 | 0.956572 0.000219
81 | 0.975393 -0.000742
82 | 0.988983 -0.001472
83 | 1.000000 -0.002051
84 |
--------------------------------------------------------------------------------
/runs/e387.dat:
--------------------------------------------------------------------------------
1 | E387
2 | 1.00000 0.00000
3 | 0.99677 0.00043
4 | 0.98729 0.00180
5 | 0.97198 0.00423
6 | 0.95128 0.00763
7 | 0.92554 0.01184
8 | 0.89510 0.01679
9 | 0.86035 0.02242
10 | 0.82183 0.02866
11 | 0.78007 0.03540
12 | 0.73567 0.04249
13 | 0.68922 0.04975
14 | 0.64136 0.05696
15 | 0.59272 0.06390
16 | 0.54394 0.07020
17 | 0.49549 0.07546
18 | 0.44767 0.07936
19 | 0.40077 0.08173
20 | 0.35505 0.08247
21 | 0.31078 0.08156
22 | 0.26813 0.07908
23 | 0.22742 0.07529
24 | 0.18906 0.07037
25 | 0.15345 0.06448
26 | 0.12094 0.05775
27 | 0.09185 0.05033
28 | 0.06643 0.04238
29 | 0.04493 0.03408
30 | 0.02748 0.02562
31 | 0.01423 0.01726
32 | 0.00519 0.00931
33 | 0.00044 0.00234
34 | 0.00091 -0.00286
35 | 0.00717 -0.00682
36 | 0.01890 -0.01017
37 | 0.03596 -0.01265
38 | 0.05827 -0.01425
39 | 0.08569 -0.01500
40 | 0.11800 -0.01502
41 | 0.15490 -0.01441
42 | 0.19599 -0.01329
43 | 0.24083 -0.01177
44 | 0.28892 -0.00998
45 | 0.33968 -0.00804
46 | 0.39252 -0.00605
47 | 0.44679 -0.00410
48 | 0.50182 -0.00228
49 | 0.55694 -0.00065
50 | 0.61147 0.00074
51 | 0.66472 0.00186
52 | 0.71602 0.00268
53 | 0.76475 0.00320
54 | 0.81027 0.00342
55 | 0.85202 0.00337
56 | 0.88944 0.00307
57 | 0.92205 0.00258
58 | 0.94942 0.00196
59 | 0.97118 0.00132
60 | 0.98705 0.00071
61 | 0.99674 0.00021
62 | 1.00000 0.00000
63 |
--------------------------------------------------------------------------------
/runs/e387_09.100:
--------------------------------------------------------------------------------
1 |
2 | XFOIL Version 6.90
3 |
4 | Calculated polar for: Eppler 387 1 elements
5 |
6 | 1 1 Reynolds number fixed Mach number fixed
7 |
8 | xtrf = 1.000 (top) 1.000 (bottom) element 1
9 | Mach = 0.000 Re = 0.100 e 6 Ncrit = 9.000
10 |
11 | alpha CL CD CDp CM Top Xtr Bot Xtr
12 | ------- -------- --------- --------- -------- ------- -------
13 | -3.000 0.1048 0.01946 0.01072 -0.1011 0.9086 0.0922
14 | -2.900 0.1145 0.01905 0.01039 -0.1009 0.9029 0.0999
15 | -2.800 0.1271 0.01856 0.00992 -0.1010 0.8993 0.1103
16 | -2.700 0.1402 0.01812 0.00956 -0.1013 0.8964 0.1268
17 | -2.600 0.1505 0.01776 0.00923 -0.1010 0.8914 0.1446
18 | -2.500 0.1617 0.01730 0.00895 -0.1011 0.8875 0.1717
19 | -2.400 0.1736 0.01670 0.00860 -0.1011 0.8845 0.2145
20 | -2.300 0.1837 0.01611 0.00840 -0.1011 0.8804 0.2881
21 | -2.200 0.1924 0.01544 0.00832 -0.1008 0.8761 0.4082
22 | -2.100 0.2001 0.01482 0.00828 -0.0998 0.8729 0.5607
23 | -2.000 0.2043 0.01437 0.00830 -0.0974 0.8701 0.7026
24 | -1.900 0.2064 0.01411 0.00836 -0.0945 0.8652 0.8362
25 | -1.800 0.2267 0.01386 0.00804 -0.0956 0.8620 1.0000
26 | -1.700 0.2383 0.01389 0.00790 -0.0955 0.8590 1.0000
27 | -1.600 0.2490 0.01398 0.00786 -0.0955 0.8547 1.0000
28 | -1.500 0.2599 0.01406 0.00781 -0.0955 0.8505 1.0000
29 | -1.400 0.2710 0.01411 0.00773 -0.0953 0.8474 1.0000
30 | -1.200 0.2926 0.01429 0.00768 -0.0953 0.8397 1.0000
31 | -1.000 0.3145 0.01440 0.00757 -0.0949 0.8337 1.0000
32 | -0.800 0.3359 0.01461 0.00763 -0.0949 0.8258 1.0000
33 | -0.600 0.3576 0.01473 0.00755 -0.0945 0.8204 1.0000
34 | -0.400 0.3791 0.01498 0.00767 -0.0946 0.8125 1.0000
35 | -0.200 0.4008 0.01510 0.00763 -0.0942 0.8075 1.0000
36 | 0.000 0.4222 0.01538 0.00782 -0.0943 0.7998 1.0000
37 | 0.200 0.4439 0.01551 0.00781 -0.0939 0.7950 1.0000
38 | 0.400 0.4654 0.01581 0.00804 -0.0941 0.7874 1.0000
39 | 0.600 0.4871 0.01596 0.00806 -0.0937 0.7827 1.0000
40 | 0.800 0.5086 0.01628 0.00835 -0.0939 0.7755 1.0000
41 | 1.000 0.5304 0.01644 0.00841 -0.0935 0.7706 1.0000
42 | 1.200 0.5518 0.01678 0.00872 -0.0937 0.7638 1.0000
43 | 1.400 0.5736 0.01697 0.00884 -0.0934 0.7588 1.0000
44 | 1.600 0.5950 0.01730 0.00916 -0.0935 0.7525 1.0000
45 | 1.800 0.6167 0.01754 0.00936 -0.0933 0.7471 1.0000
46 | 2.000 0.6382 0.01784 0.00964 -0.0933 0.7416 1.0000
47 | 2.200 0.6596 0.01813 0.00992 -0.0932 0.7355 1.0000
48 | 2.400 0.6814 0.01834 0.01009 -0.0929 0.7311 1.0000
49 | 2.600 0.7025 0.01875 0.01057 -0.0931 0.7240 1.0000
50 | 2.800 0.7244 0.01891 0.01069 -0.0927 0.7198 1.0000
51 | 3.000 0.7451 0.01938 0.01122 -0.0929 0.7124 1.0000
52 | 3.200 0.7669 0.01953 0.01136 -0.0924 0.7077 1.0000
53 | 3.400 0.7875 0.01998 0.01191 -0.0925 0.7003 1.0000
54 | 3.600 0.8092 0.02011 0.01203 -0.0920 0.6953 1.0000
55 | 3.800 0.8295 0.02053 0.01253 -0.0920 0.6875 1.0000
56 | 4.000 0.8514 0.02053 0.01252 -0.0913 0.6820 1.0000
57 | 4.100 0.8607 0.02079 0.01286 -0.0912 0.6764 1.0000
58 | 4.200 0.8712 0.02078 0.01286 -0.0908 0.6724 1.0000
59 | 4.300 0.8823 0.02067 0.01275 -0.0903 0.6695 1.0000
60 | 4.400 0.8916 0.02091 0.01307 -0.0902 0.6636 1.0000
61 | 4.500 0.9021 0.02088 0.01305 -0.0898 0.6596 1.0000
62 | 4.600 0.9133 0.02079 0.01293 -0.0893 0.6568 1.0000
63 | 4.700 0.9226 0.02106 0.01330 -0.0893 0.6512 1.0000
64 | 4.800 0.9332 0.02110 0.01337 -0.0890 0.6475 1.0000
65 | 4.900 0.9444 0.02106 0.01333 -0.0886 0.6448 1.0000
66 | 5.000 0.9540 0.02130 0.01366 -0.0885 0.6400 1.0000
67 | 5.100 0.9643 0.02140 0.01381 -0.0883 0.6358 1.0000
68 | 5.200 0.9754 0.02136 0.01378 -0.0880 0.6328 1.0000
69 | 5.300 0.9854 0.02152 0.01400 -0.0878 0.6284 1.0000
70 | 5.400 0.9954 0.02162 0.01420 -0.0875 0.6234 1.0000
71 | 5.500 1.0066 0.02145 0.01402 -0.0870 0.6197 1.0000
72 | 5.600 1.0157 0.02157 0.01424 -0.0867 0.6130 1.0000
73 | 5.700 1.0266 0.02137 0.01403 -0.0861 0.6079 1.0000
74 | 5.800 1.0360 0.02136 0.01410 -0.0856 0.6009 1.0000
75 | 5.900 1.0468 0.02109 0.01382 -0.0849 0.5951 1.0000
76 | 6.000 1.0560 0.02107 0.01389 -0.0844 0.5873 1.0000
77 | 6.100 1.0671 0.02078 0.01357 -0.0838 0.5817 1.0000
78 | 6.200 1.0760 0.02080 0.01370 -0.0834 0.5735 1.0000
79 | 6.300 1.0870 0.02056 0.01344 -0.0828 0.5676 1.0000
80 | 6.400 1.0961 0.02053 0.01356 -0.0823 0.5593 1.0000
81 | 6.500 1.1060 0.02045 0.01353 -0.0818 0.5519 1.0000
82 | 6.600 1.1163 0.02029 0.01341 -0.0813 0.5450 1.0000
83 | 6.700 1.1255 0.02029 0.01352 -0.0808 0.5365 1.0000
84 | 6.800 1.1358 0.02015 0.01341 -0.0803 0.5292 1.0000
85 | 6.900 1.1453 0.02008 0.01342 -0.0798 0.5203 1.0000
86 | 7.000 1.1544 0.02003 0.01348 -0.0793 0.5104 1.0000
87 | 7.100 1.1637 0.01995 0.01348 -0.0787 0.4999 1.0000
88 | 7.200 1.1728 0.01985 0.01346 -0.0781 0.4882 1.0000
89 | 7.300 1.1816 0.01977 0.01346 -0.0775 0.4749 1.0000
90 | 7.400 1.1903 0.01971 0.01347 -0.0768 0.4599 1.0000
91 | 7.500 1.1984 0.01965 0.01346 -0.0761 0.4411 1.0000
92 | 7.600 1.2055 0.01965 0.01347 -0.0753 0.4143 1.0000
93 | 7.700 1.2113 0.01978 0.01352 -0.0743 0.3772 1.0000
94 | 7.800 1.2151 0.02018 0.01362 -0.0731 0.3296 1.0000
95 | 7.900 1.2166 0.02093 0.01397 -0.0719 0.2827 1.0000
96 | 8.000 1.2176 0.02184 0.01455 -0.0708 0.2438 1.0000
97 | 8.100 1.2191 0.02276 0.01522 -0.0698 0.2131 1.0000
98 | 8.200 1.2206 0.02367 0.01595 -0.0688 0.1885 1.0000
99 | 8.300 1.2220 0.02459 0.01671 -0.0678 0.1669 1.0000
100 | 8.400 1.2224 0.02557 0.01750 -0.0667 0.1477 1.0000
101 | 8.500 1.2228 0.02655 0.01835 -0.0655 0.1267 1.0000
102 | 8.600 1.2212 0.02767 0.01929 -0.0642 0.1086 1.0000
103 |
--------------------------------------------------------------------------------
/runs/e387_11.100:
--------------------------------------------------------------------------------
1 |
2 | XFOIL Version 6.90
3 |
4 | Calculated polar for: Eppler 387
5 |
6 | 1 1 Reynolds number fixed Mach number fixed
7 |
8 | xtrf = 1.000 (top) 1.000 (bottom)
9 | Mach = 0.000 Re = 0.100 e 6 Ncrit = 11.000
10 |
11 | alpha CL CD CDp CM Top Xtr Bot Xtr
12 | ------- -------- --------- --------- -------- ------- -------
13 | -3.000 0.0560 0.02350 0.01498 -0.0988 0.9417 0.0994
14 | -2.900 0.0725 0.02284 0.01431 -0.0997 0.9384 0.1034
15 | -2.800 0.0920 0.02213 0.01360 -0.1013 0.9361 0.1128
16 | -2.700 0.1121 0.02138 0.01290 -0.1029 0.9341 0.1252
17 | -2.600 0.1330 0.02070 0.01217 -0.1045 0.9324 0.1443
18 | -2.400 0.1588 0.01962 0.01143 -0.1054 0.9245 0.1926
19 | -2.100 0.1963 0.01636 0.01058 -0.1056 0.9170 0.6517
20 | -1.900 0.2190 0.01570 0.01026 -0.1033 0.9104 1.0000
21 | -1.800 0.2368 0.01571 0.01006 -0.1045 0.9079 1.0000
22 | -1.700 0.2458 0.01589 0.01010 -0.1043 0.9028 1.0000
23 | -1.600 0.2595 0.01597 0.01003 -0.1048 0.8992 1.0000
24 | -1.500 0.2750 0.01599 0.00990 -0.1055 0.8965 1.0000
25 | -1.400 0.2863 0.01613 0.00992 -0.1057 0.8925 1.0000
26 | -1.300 0.2970 0.01627 0.00996 -0.1057 0.8882 1.0000
27 | -1.200 0.3107 0.01633 0.00990 -0.1061 0.8852 1.0000
28 | -1.100 0.3251 0.01635 0.00982 -0.1065 0.8829 1.0000
29 | -1.000 0.3331 0.01660 0.01000 -0.1063 0.8778 1.0000
30 | -0.900 0.3449 0.01670 0.01001 -0.1064 0.8743 1.0000
31 | -0.800 0.3581 0.01675 0.00997 -0.1066 0.8717 1.0000
32 | -0.700 0.3688 0.01690 0.01005 -0.1066 0.8682 1.0000
33 | -0.600 0.3785 0.01710 0.01017 -0.1066 0.8639 1.0000
34 | -0.500 0.3905 0.01718 0.01018 -0.1066 0.8609 1.0000
35 | -0.400 0.4031 0.01722 0.01015 -0.1066 0.8586 1.0000
36 | -0.300 0.4123 0.01748 0.01035 -0.1066 0.8543 1.0000
37 | -0.200 0.4227 0.01764 0.01047 -0.1066 0.8507 1.0000
38 | -0.100 0.4345 0.01772 0.01048 -0.1065 0.8479 1.0000
39 | 0.000 0.4466 0.01777 0.01047 -0.1064 0.8458 1.0000
40 | 0.100 0.4554 0.01808 0.01075 -0.1065 0.8412 1.0000
41 | 0.200 0.4660 0.01824 0.01086 -0.1064 0.8378 1.0000
42 | 0.300 0.4775 0.01832 0.01089 -0.1063 0.8353 1.0000
43 | 0.400 0.4894 0.01837 0.01089 -0.1062 0.8333 1.0000
44 | 0.500 0.4982 0.01873 0.01123 -0.1063 0.8286 1.0000
45 | 0.600 0.5087 0.01890 0.01136 -0.1063 0.8254 1.0000
46 | 0.700 0.5201 0.01898 0.01140 -0.1061 0.8229 1.0000
47 | 0.800 0.5316 0.01903 0.01141 -0.1059 0.8209 1.0000
48 | 0.900 0.5406 0.01942 0.01179 -0.1061 0.8164 1.0000
49 | 1.000 0.5510 0.01961 0.01196 -0.1061 0.8132 1.0000
50 | 1.100 0.5622 0.01970 0.01202 -0.1059 0.8107 1.0000
51 | 1.200 0.5736 0.01976 0.01204 -0.1056 0.8087 1.0000
52 | 1.300 0.5828 0.02015 0.01243 -0.1059 0.8045 1.0000
53 | 1.400 0.5930 0.02037 0.01264 -0.1059 0.8011 1.0000
54 | 1.500 0.6041 0.02048 0.01273 -0.1057 0.7986 1.0000
55 | 1.600 0.6154 0.02054 0.01276 -0.1054 0.7966 1.0000
56 | 1.700 0.6248 0.02092 0.01314 -0.1056 0.7928 1.0000
57 | 1.800 0.6348 0.02119 0.01341 -0.1057 0.7893 1.0000
58 | 1.900 0.6457 0.02131 0.01354 -0.1055 0.7867 1.0000
59 | 2.000 0.6570 0.02137 0.01357 -0.1052 0.7846 1.0000
60 | 2.100 0.6667 0.02171 0.01391 -0.1053 0.7812 1.0000
61 | 2.200 0.6763 0.02204 0.01426 -0.1054 0.7774 1.0000
62 | 2.300 0.6871 0.02218 0.01439 -0.1052 0.7746 1.0000
63 | 2.400 0.6983 0.02223 0.01443 -0.1049 0.7725 1.0000
64 | 2.500 0.7083 0.02250 0.01471 -0.1049 0.7695 1.0000
65 | 2.600 0.7175 0.02292 0.01515 -0.1051 0.7653 1.0000
66 | 2.700 0.7282 0.02305 0.01529 -0.1049 0.7625 1.0000
67 | 2.800 0.7394 0.02309 0.01531 -0.1045 0.7603 1.0000
68 | 2.900 0.7494 0.02335 0.01562 -0.1044 0.7572 1.0000
69 | 3.000 0.7584 0.02378 0.01609 -0.1046 0.7528 1.0000
70 | 3.100 0.7691 0.02389 0.01620 -0.1043 0.7499 1.0000
71 | 3.200 0.7804 0.02389 0.01619 -0.1038 0.7476 1.0000
72 | 3.300 0.7896 0.02428 0.01661 -0.1039 0.7437 1.0000
73 | 3.400 0.7990 0.02461 0.01697 -0.1039 0.7396 1.0000
74 | 3.500 0.8099 0.02464 0.01701 -0.1034 0.7368 1.0000
75 | 3.600 0.8213 0.02456 0.01692 -0.1028 0.7346 1.0000
76 | 3.700 0.8292 0.02516 0.01758 -0.1031 0.7292 1.0000
77 | 3.800 0.8396 0.02523 0.01767 -0.1027 0.7255 1.0000
78 | 3.900 0.8510 0.02505 0.01752 -0.1019 0.7228 1.0000
79 | 4.000 0.8591 0.02546 0.01799 -0.1018 0.7172 1.0000
80 | 4.100 0.8695 0.02542 0.01796 -0.1012 0.7129 1.0000
81 | 4.200 0.8810 0.02512 0.01764 -0.1002 0.7100 1.0000
82 | 4.300 0.8887 0.02559 0.01818 -0.1002 0.7036 1.0000
83 | 4.400 0.8995 0.02546 0.01806 -0.0994 0.6998 1.0000
84 | 4.500 0.9112 0.02517 0.01775 -0.0985 0.6972 1.0000
85 | 4.600 0.9187 0.02575 0.01842 -0.0987 0.6906 1.0000
86 | 4.700 0.9296 0.02564 0.01834 -0.0980 0.6871 1.0000
87 | 4.800 0.9414 0.02542 0.01811 -0.0973 0.6848 1.0000
88 | 5.000 0.9598 0.02594 0.01875 -0.0969 0.6748 1.0000
89 | 5.100 0.9717 0.02568 0.01853 -0.0961 0.6724 1.0000
90 | 5.300 0.9903 0.02610 0.01908 -0.0955 0.6620 1.0000
91 | 5.400 0.9998 0.02619 0.01923 -0.0950 0.6569 1.0000
92 | 5.500 1.0096 0.02612 0.01921 -0.0943 0.6511 1.0000
93 | 5.600 1.0221 0.02551 0.01855 -0.0931 0.6476 1.0000
94 | 5.700 1.0295 0.02575 0.01891 -0.0927 0.6392 1.0000
95 | 5.800 1.0413 0.02518 0.01830 -0.0915 0.6343 1.0000
96 | 5.900 1.0499 0.02511 0.01832 -0.0908 0.6261 1.0000
97 | 6.000 1.0598 0.02484 0.01808 -0.0899 0.6194 1.0000
98 | 6.100 1.0705 0.02445 0.01769 -0.0890 0.6128 1.0000
99 | 6.200 1.0796 0.02434 0.01765 -0.0883 0.6050 1.0000
100 | 6.300 1.0913 0.02379 0.01712 -0.0873 0.5992 1.0000
101 | 6.400 1.0999 0.02374 0.01718 -0.0866 0.5905 1.0000
102 | 6.500 1.1110 0.02333 0.01676 -0.0858 0.5843 1.0000
103 | 6.600 1.1205 0.02315 0.01665 -0.0851 0.5761 1.0000
104 | 6.700 1.1298 0.02301 0.01659 -0.0844 0.5678 1.0000
105 | 6.800 1.1417 0.02253 0.01609 -0.0836 0.5615 1.0000
106 | 6.900 1.1502 0.02244 0.01612 -0.0829 0.5516 1.0000
107 | 7.000 1.1595 0.02224 0.01601 -0.0822 0.5420 1.0000
108 | 7.100 1.1693 0.02193 0.01575 -0.0814 0.5321 1.0000
109 | 7.200 1.1789 0.02159 0.01545 -0.0805 0.5213 1.0000
110 | 7.300 1.1880 0.02127 0.01521 -0.0796 0.5087 1.0000
111 | 7.400 1.1965 0.02097 0.01499 -0.0787 0.4940 1.0000
112 | 7.500 1.2050 0.02057 0.01461 -0.0777 0.4767 1.0000
113 | 7.600 1.2118 0.02025 0.01440 -0.0765 0.4529 1.0000
114 | 7.700 1.2175 0.02003 0.01418 -0.0752 0.4195 1.0000
115 | 7.800 1.2217 0.02007 0.01403 -0.0738 0.3744 1.0000
116 | 7.900 1.2234 0.02059 0.01418 -0.0724 0.3208 1.0000
117 | 8.000 1.2233 0.02152 0.01468 -0.0710 0.2748 1.0000
118 | 8.100 1.2227 0.02261 0.01542 -0.0696 0.2392 1.0000
119 | 8.200 1.2222 0.02371 0.01625 -0.0683 0.2104 1.0000
120 | 8.300 1.2217 0.02480 0.01712 -0.0670 0.1860 1.0000
121 | 8.400 1.2208 0.02592 0.01804 -0.0657 0.1637 1.0000
122 | 8.500 1.2186 0.02714 0.01906 -0.0641 0.1423 1.0000
123 | 9.000 1.2117 0.03330 0.02451 -0.0564 0.0811 1.0000
124 |
--------------------------------------------------------------------------------
/runs/la203.bl:
--------------------------------------------------------------------------------
1 | # s x y Ue/Vinf Dstar Theta Cf H
2 | 0.00000 1.00000 0.00000********* 0.000000 0.000000 0.000000 1.000
3 | 0.00678 0.99394 0.00304 5.27909 0.000000 0.000000 0.000000 1.000
4 | 0.01507 0.98615 0.00588 0.66356 0.000000 0.000000 0.000000 1.000
5 | 0.02505 0.97667 0.00898 1.02369 0.000000 0.000000 0.000000 1.000
6 | 0.03671 0.96552 0.01241 0.98680 0.000000 0.000000 0.000000 1.000
7 | 0.05003 0.95274 0.01616 1.00600 0.000000 0.000000 0.000000 1.000
8 | 0.06496 0.93839 0.02026 1.01642 0.000000 0.000000 0.000000 1.000
9 | 0.08145 0.92250 0.02470 1.02850 0.000000 0.000000 0.000000 1.000
10 | 0.09946 0.90514 0.02949 1.04043 0.000000 0.000000 0.000000 1.000
11 | 0.11892 0.88637 0.03463 1.05326 0.000000 0.000000 0.000000 1.000
12 | 0.13978 0.86625 0.04011 1.06653 0.000000 0.000000 0.000000 1.000
13 | 0.16195 0.84486 0.04594 1.08119 0.000000 0.000000 0.000000 1.000
14 | 0.18537 0.82226 0.05209 1.09721 0.000000 0.000000 0.000000 1.000
15 | 0.20995 0.79854 0.05854 1.11490 0.000000 0.000000 0.000000 1.000
16 | 0.23560 0.77379 0.06529 1.13482 0.000000 0.000000 0.000000 1.000
17 | 0.26224 0.74809 0.07229 1.15776 0.000000 0.000000 0.000000 1.000
18 | 0.28977 0.72152 0.07949 1.18501 0.000000 0.000000 0.000000 1.000
19 | 0.31805 0.69419 0.08680 1.21576 0.000000 0.000000 0.000000 1.000
20 | 0.34698 0.66619 0.09406 1.25083 0.000000 0.000000 0.000000 1.000
21 | 0.37640 0.63762 0.10109 1.28741 0.000000 0.000000 0.000000 1.000
22 | 0.40618 0.60858 0.10764 1.32053 0.000000 0.000000 0.000000 1.000
23 | 0.43618 0.57917 0.11357 1.34930 0.000000 0.000000 0.000000 1.000
24 | 0.46631 0.54949 0.11877 1.37478 0.000000 0.000000 0.000000 1.000
25 | 0.49647 0.51965 0.12318 1.39617 0.000000 0.000000 0.000000 1.000
26 | 0.52658 0.48976 0.12674 1.41457 0.000000 0.000000 0.000000 1.000
27 | 0.55654 0.45992 0.12944 1.43028 0.000000 0.000000 0.000000 1.000
28 | 0.58628 0.43023 0.13122 1.44179 0.000000 0.000000 0.000000 1.000
29 | 0.61573 0.40080 0.13209 1.44937 0.000000 0.000000 0.000000 1.000
30 | 0.64479 0.37173 0.13207 1.45518 0.000000 0.000000 0.000000 1.000
31 | 0.67341 0.34313 0.13118 1.45792 0.000000 0.000000 0.000000 1.000
32 | 0.70150 0.31509 0.12943 1.45827 0.000000 0.000000 0.000000 1.000
33 | 0.72900 0.28772 0.12685 1.45747 0.000000 0.000000 0.000000 1.000
34 | 0.75583 0.26111 0.12342 1.44864 0.000000 0.000000 0.000000 1.000
35 | 0.78192 0.23535 0.11923 1.43613 0.000000 0.000000 0.000000 1.000
36 | 0.80720 0.21054 0.11439 1.42239 0.000000 0.000000 0.000000 1.000
37 | 0.83159 0.18676 0.10897 1.40732 0.000000 0.000000 0.000000 1.000
38 | 0.85502 0.16409 0.10305 1.39083 0.000000 0.000000 0.000000 1.000
39 | 0.87741 0.14263 0.09669 1.37245 0.000000 0.000000 0.000000 1.000
40 | 0.89869 0.12243 0.08996 1.35194 0.000000 0.000000 0.000000 1.000
41 | 0.91882 0.10358 0.08292 1.32911 0.000000 0.000000 0.000000 1.000
42 | 0.93772 0.08614 0.07564 1.30309 0.000000 0.000000 0.000000 1.000
43 | 0.95534 0.07016 0.06819 1.27319 0.000000 0.000000 0.000000 1.000
44 | 0.97165 0.05572 0.06064 1.23879 0.000000 0.000000 0.000000 1.000
45 | 0.98659 0.04285 0.05305 1.19811 0.000000 0.000000 0.000000 1.000
46 | 1.00014 0.03160 0.04549 1.14953 0.000000 0.000000 0.000000 1.000
47 | 1.01228 0.02201 0.03803 1.09034 0.000000 0.000000 0.000000 1.000
48 | 1.02307 0.01413 0.03068 1.01356 0.000000 0.000000 0.000000 1.000
49 | 1.03265 0.00796 0.02334 0.89499 0.000000 0.000000 0.000000 1.000
50 | 1.04136 0.00354 0.01584 0.70021 0.000000 0.000000 0.000000 1.000
51 | 1.04963 0.00089 0.00800 0.41358 0.000000 0.000000 0.000000 1.000
52 | 1.05768 0.00000 0.00000 0.07437 0.000000 0.000000 0.000000 1.000
53 | 1.06575 0.00089 -0.00802 -0.30981 0.000000 0.000000 0.000000 1.000
54 | 1.07335 0.00354 -0.01514 -0.67584 0.000000 0.000000 0.000000 1.000
55 | 1.08113 0.00796 -0.02154 -1.03868 0.000000 0.000000 0.000000 1.000
56 | 1.08905 0.01413 -0.02652 -1.30412 0.000000 0.000000 0.000000 1.000
57 | 1.09753 0.02201 -0.02964 -1.31181 0.000000 0.000000 0.000000 1.000
58 | 1.10726 0.03160 -0.03132 -1.21396 0.000000 0.000000 0.000000 1.000
59 | 1.11854 0.04285 -0.03221 -1.14228 0.000000 0.000000 0.000000 1.000
60 | 1.13142 0.05572 -0.03268 -1.09742 0.000000 0.000000 0.000000 1.000
61 | 1.14587 0.07016 -0.03287 -1.06685 0.000000 0.000000 0.000000 1.000
62 | 1.16184 0.08614 -0.03286 -1.04468 0.000000 0.000000 0.000000 1.000
63 | 1.17929 0.10358 -0.03269 -1.02851 0.000000 0.000000 0.000000 1.000
64 | 1.19814 0.12243 -0.03241 -1.01642 0.000000 0.000000 0.000000 1.000
65 | 1.21834 0.14263 -0.03202 -1.00732 0.000000 0.000000 0.000000 1.000
66 | 1.23981 0.16409 -0.03156 -1.00034 0.000000 0.000000 0.000000 1.000
67 | 1.26248 0.18676 -0.03102 -0.99532 0.000000 0.000000 0.000000 1.000
68 | 1.28627 0.21054 -0.03041 -0.99147 0.000000 0.000000 0.000000 1.000
69 | 1.31109 0.23535 -0.02972 -0.98880 0.000000 0.000000 0.000000 1.000
70 | 1.33686 0.26111 -0.02897 -0.98680 0.000000 0.000000 0.000000 1.000
71 | 1.36348 0.28772 -0.02812 -0.98556 0.000000 0.000000 0.000000 1.000
72 | 1.39087 0.31509 -0.02718 -0.98480 0.000000 0.000000 0.000000 1.000
73 | 1.41893 0.34313 -0.02612 -0.98446 0.000000 0.000000 0.000000 1.000
74 | 1.44756 0.37173 -0.02492 -0.98473 0.000000 0.000000 0.000000 1.000
75 | 1.47666 0.40080 -0.02351 -0.98475 0.000000 0.000000 0.000000 1.000
76 | 1.50614 0.43023 -0.02183 -0.98213 0.000000 0.000000 0.000000 1.000
77 | 1.53589 0.45992 -0.01983 -0.97642 0.000000 0.000000 0.000000 1.000
78 | 1.56583 0.48976 -0.01753 -0.96882 0.000000 0.000000 0.000000 1.000
79 | 1.59583 0.51965 -0.01495 -0.95900 0.000000 0.000000 0.000000 1.000
80 | 1.62580 0.54949 -0.01210 -0.94609 0.000000 0.000000 0.000000 1.000
81 | 1.65564 0.57917 -0.00905 -0.93071 0.000000 0.000000 0.000000 1.000
82 | 1.68522 0.60858 -0.00592 -0.91406 0.000000 0.000000 0.000000 1.000
83 | 1.71442 0.63762 -0.00282 -0.89802 0.000000 0.000000 0.000000 1.000
84 | 1.74315 0.66619 0.00014 -0.88328 0.000000 0.000000 0.000000 1.000
85 | 1.77129 0.69419 0.00292 -0.86902 0.000000 0.000000 0.000000 1.000
86 | 1.79873 0.72152 0.00545 -0.85540 0.000000 0.000000 0.000000 1.000
87 | 1.82539 0.74809 0.00769 -0.84247 0.000000 0.000000 0.000000 1.000
88 | 1.85116 0.77379 0.00959 -0.83037 0.000000 0.000000 0.000000 1.000
89 | 1.87597 0.79854 0.01115 -0.81896 0.000000 0.000000 0.000000 1.000
90 | 1.89971 0.82226 0.01231 -0.80866 0.000000 0.000000 0.000000 1.000
91 | 1.92232 0.84486 0.01309 -0.79895 0.000000 0.000000 0.000000 1.000
92 | 1.94372 0.86625 0.01346 -0.79065 0.000000 0.000000 0.000000 1.000
93 | 1.96384 0.88637 0.01345 -0.78324 0.000000 0.000000 0.000000 1.000
94 | 1.98261 0.90514 0.01306 -0.77687 0.000000 0.000000 0.000000 1.000
95 | 1.99999 0.92250 0.01230 -0.77234 0.000000 0.000000 0.000000 1.000
96 | 2.01591 0.93839 0.01122 -0.77013 0.000000 0.000000 0.000000 1.000
97 | 2.03033 0.95274 0.00984 -0.76862 0.000000 0.000000 0.000000 1.000
98 | 2.04321 0.96552 0.00821 -0.78701 0.000000 0.000000 0.000000 1.000
99 | 2.05451 0.97667 0.00639 -0.74096 0.000000 0.000000 0.000000 1.000
100 | 2.06419 0.98615 0.00443 -1.02456 0.000000 0.000000 0.000000 1.000
101 | 2.07224 0.99394 0.00238 -3.04501 0.000000 0.000000 0.000000 1.000
102 | 2.07876 1.00000 0.00000118.42509 0.000000 0.000000 0.000000 1.000
103 |
--------------------------------------------------------------------------------
/runs/la203.dat:
--------------------------------------------------------------------------------
1 | LA203A
2 | 1.000000 0.000000
3 | 0.993938 0.003044
4 | 0.986151 0.005883
5 | 0.976665 0.008985
6 | 0.965516 0.012408
7 | 0.952740 0.016162
8 | 0.938385 0.020258
9 | 0.922500 0.024700
10 | 0.905141 0.029490
11 | 0.886369 0.034630
12 | 0.866250 0.040113
13 | 0.844856 0.045936
14 | 0.822261 0.052086
15 | 0.798545 0.058545
16 | 0.773791 0.065291
17 | 0.748087 0.072292
18 | 0.721524 0.079495
19 | 0.694194 0.086797
20 | 0.666193 0.094063
21 | 0.637621 0.101087
22 | 0.608579 0.107640
23 | 0.579167 0.113566
24 | 0.549490 0.118770
25 | 0.519653 0.123176
26 | 0.489759 0.126743
27 | 0.459916 0.129436
28 | 0.430226 0.131219
29 | 0.400796 0.132090
30 | 0.371729 0.132075
31 | 0.343127 0.131182
32 | 0.315090 0.129435
33 | 0.287716 0.126854
34 | 0.261106 0.123424
35 | 0.235350 0.119234
36 | 0.210538 0.114389
37 | 0.186758 0.108970
38 | 0.164095 0.103048
39 | 0.142628 0.096688
40 | 0.122432 0.089956
41 | 0.103579 0.082919
42 | 0.086135 0.075641
43 | 0.070162 0.068190
44 | 0.055715 0.060636
45 | 0.042846 0.053047
46 | 0.031599 0.045492
47 | 0.022015 0.038031
48 | 0.014127 0.030677
49 | 0.007963 0.023336
50 | 0.003544 0.015836
51 | 0.000887 0.008000
52 | 0.000000 0.000000
53 | 0.000887 -0.008018
54 | 0.003544 -0.015138
55 | 0.007963 -0.021544
56 | 0.014127 -0.026519
57 | 0.022015 -0.029639
58 | 0.031599 -0.031320
59 | 0.042846 -0.032209
60 | 0.055715 -0.032676
61 | 0.070162 -0.032868
62 | 0.086135 -0.032857
63 | 0.103579 -0.032693
64 | 0.122432 -0.032408
65 | 0.142628 -0.032024
66 | 0.164095 -0.031556
67 | 0.186758 -0.031016
68 | 0.210538 -0.030405
69 | 0.235350 -0.029724
70 | 0.261106 -0.028966
71 | 0.287716 -0.028124
72 | 0.315090 -0.027183
73 | 0.343127 -0.026124
74 | 0.371729 -0.024919
75 | 0.400796 -0.023512
76 | 0.430226 -0.021827
77 | 0.459916 -0.019830
78 | 0.489759 -0.017533
79 | 0.519653 -0.014948
80 | 0.549490 -0.012098
81 | 0.579167 -0.009052
82 | 0.608579 -0.005918
83 | 0.637621 -0.002821
84 | 0.666193 0.000143
85 | 0.694194 0.002917
86 | 0.721524 0.005447
87 | 0.748087 0.007686
88 | 0.773791 0.009595
89 | 0.798545 0.011145
90 | 0.822261 0.012312
91 | 0.844856 0.013088
92 | 0.866250 0.013463
93 | 0.886369 0.013448
94 | 0.905141 0.013056
95 | 0.922500 0.012302
96 | 0.938385 0.011218
97 | 0.952740 0.009838
98 | 0.965516 0.008212
99 | 0.976665 0.006393
100 | 0.986151 0.004425
101 | 0.993938 0.002384
102 | 1.000000 0.000000
103 |
104 |
--------------------------------------------------------------------------------
/runs/la203t.dat:
--------------------------------------------------------------------------------
1 | LA230A blunt TE
2 | 1.000455 0.000895
3 | 0.993427 0.004332
4 | 0.981492 0.008450
5 | 0.967879 0.012697
6 | 0.952291 0.017269
7 | 0.934612 0.022276
8 | 0.914876 0.027744
9 | 0.893349 0.033633
10 | 0.870451 0.039856
11 | 0.846614 0.046320
12 | 0.822246 0.052928
13 | 0.797640 0.059604
14 | 0.773000 0.066294
15 | 0.748527 0.072935
16 | 0.724456 0.079441
17 | 0.700950 0.085719
18 | 0.678100 0.091696
19 | 0.655966 0.097294
20 | 0.634488 0.102460
21 | 0.613509 0.107185
22 | 0.592872 0.111482
23 | 0.572474 0.115369
24 | 0.552260 0.118854
25 | 0.532181 0.121940
26 | 0.512197 0.124633
27 | 0.492299 0.126938
28 | 0.472493 0.128851
29 | 0.452778 0.130366
30 | 0.433139 0.131481
31 | 0.413556 0.132197
32 | 0.394032 0.132519
33 | 0.374603 0.132449
34 | 0.355296 0.131983
35 | 0.336122 0.131120
36 | 0.317102 0.129862
37 | 0.298297 0.128215
38 | 0.279735 0.126157
39 | 0.261354 0.123677
40 | 0.243142 0.120790
41 | 0.225156 0.117523
42 | 0.207483 0.113902
43 | 0.190225 0.109959
44 | 0.173498 0.105734
45 | 0.157428 0.101275
46 | 0.142137 0.096640
47 | 0.127740 0.091896
48 | 0.114330 0.087111
49 | 0.101967 0.082352
50 | 0.090672 0.077676
51 | 0.080423 0.073127
52 | 0.071170 0.068734
53 | 0.062842 0.064514
54 | 0.055354 0.060471
55 | 0.048621 0.056601
56 | 0.042561 0.052894
57 | 0.037097 0.049337
58 | 0.032164 0.045916
59 | 0.027702 0.042615
60 | 0.023663 0.039417
61 | 0.020007 0.036305
62 | 0.016704 0.033262
63 | 0.013731 0.030267
64 | 0.011068 0.027303
65 | 0.008710 0.024356
66 | 0.006648 0.021414
67 | 0.004880 0.018473
68 | 0.003404 0.015529
69 | 0.002211 0.012581
70 | 0.001291 0.009644
71 | 0.000631 0.006741
72 | 0.000216 0.003893
73 | 0.000020 0.001100
74 | 0.000029 -0.001660
75 | 0.000247 -0.004414
76 | 0.000696 -0.007167
77 | 0.001403 -0.009910
78 | 0.002374 -0.012614
79 | 0.003602 -0.015256
80 | 0.005087 -0.017812
81 | 0.006845 -0.020249
82 | 0.008898 -0.022529
83 | 0.011262 -0.024606
84 | 0.013938 -0.026425
85 | 0.016933 -0.027936
86 | 0.020241 -0.029152
87 | 0.023844 -0.030106
88 | 0.027745 -0.030836
89 | 0.031980 -0.031393
90 | 0.036588 -0.031834
91 | 0.041629 -0.032180
92 | 0.047184 -0.032454
93 | 0.053351 -0.032666
94 | 0.060260 -0.032819
95 | 0.068071 -0.032916
96 | 0.076988 -0.032954
97 | 0.087263 -0.032928
98 | 0.099188 -0.032834
99 | 0.113069 -0.032661
100 | 0.129156 -0.032402
101 | 0.147544 -0.032052
102 | 0.168081 -0.031613
103 | 0.190368 -0.031094
104 | 0.213899 -0.030504
105 | 0.238204 -0.029853
106 | 0.262922 -0.029142
107 | 0.287810 -0.028374
108 | 0.312695 -0.027544
109 | 0.337469 -0.026643
110 | 0.362036 -0.025661
111 | 0.386318 -0.024578
112 | 0.410302 -0.023356
113 | 0.434088 -0.021960
114 | 0.457807 -0.020377
115 | 0.481536 -0.018608
116 | 0.505316 -0.016656
117 | 0.529216 -0.014513
118 | 0.553344 -0.012183
119 | 0.577787 -0.009687
120 | 0.602567 -0.007073
121 | 0.627482 -0.004428
122 | 0.652205 -0.001848
123 | 0.676637 0.000620
124 | 0.700697 0.002939
125 | 0.724337 0.005075
126 | 0.747521 0.006998
127 | 0.770218 0.008681
128 | 0.792379 0.010100
129 | 0.813952 0.011230
130 | 0.834872 0.012054
131 | 0.855042 0.012555
132 | 0.874384 0.012720
133 | 0.892795 0.012552
134 | 0.910177 0.012048
135 | 0.926478 0.011213
136 | 0.941673 0.010057
137 | 0.955776 0.008580
138 | 0.968861 0.006778
139 | 0.980995 0.004570
140 | 0.992375 0.001840
141 | 0.999545 -0.000895
142 |
--------------------------------------------------------------------------------
/runs/lnv109a.dat:
--------------------------------------------------------------------------------
1 | LNV-109A
2 | 1.000000 0.000000
3 | 0.993938 0.000543
4 | 0.986151 0.001101
5 | 0.976665 0.001787
6 | 0.965515 0.002657
7 | 0.952740 0.003737
8 | 0.938385 0.005056
9 | 0.922500 0.006639
10 | 0.905141 0.008509
11 | 0.886369 0.010690
12 | 0.866250 0.013204
13 | 0.844856 0.016069
14 | 0.822261 0.019300
15 | 0.798545 0.022912
16 | 0.773791 0.026914
17 | 0.748087 0.031312
18 | 0.721524 0.036110
19 | 0.694194 0.041303
20 | 0.666193 0.046886
21 | 0.637621 0.052846
22 | 0.608579 0.059164
23 | 0.579167 0.065813
24 | 0.549490 0.072756
25 | 0.519653 0.079934
26 | 0.489759 0.087276
27 | 0.459916 0.094701
28 | 0.430226 0.102116
29 | 0.400796 0.109249
30 | 0.371729 0.115295
31 | 0.343127 0.119496
32 | 0.315090 0.121941
33 | 0.287718 0.122784
34 | 0.261106 0.122185
35 | 0.235350 0.120264
36 | 0.210538 0.117155
37 | 0.186758 0.113001
38 | 0.164095 0.107922
39 | 0.142628 0.102024
40 | 0.122432 0.095430
41 | 0.103579 0.088284
42 | 0.086135 0.080712
43 | 0.070162 0.072825
44 | 0.055715 0.064730
45 | 0.042846 0.056528
46 | 0.031599 0.048318
47 | 0.022015 0.040194
48 | 0.014127 0.032222
49 | 0.007963 0.024369
50 | 0.003544 0.016413
51 | 0.000887 0.008081
52 | 0.000000 0.000000
53 | 0.000887 -.008081
54 | 0.003544 -.015530
55 | 0.007963 -.022138
56 | 0.014127 -.027272
57 | 0.022015 -.030455
58 | 0.031599 -.031544
59 | 0.042846 -.031202
60 | 0.055715 -.030105
61 | 0.070162 -.028554
62 | 0.086135 -.026666
63 | 0.103579 -.024529
64 | 0.122432 -.022211
65 | 0.142628 -.019767
66 | 0.164095 -.017246
67 | 0.186758 -.014689
68 | 0.210538 -.012132
69 | 0.235350 -.009608
70 | 0.261106 -.007151
71 | 0.287718 -.004782
72 | 0.315090 -.002532
73 | 0.343127 -.000425
74 | 0.371729 0.001516
75 | 0.400796 0.003265
76 | 0.430226 0.004793
77 | 0.459916 0.006064
78 | 0.489759 0.006997
79 | 0.519653 0.007552
80 | 0.549490 0.007802
81 | 0.579167 0.007826
82 | 0.608579 0.007672
83 | 0.637621 0.007376
84 | 0.666193 0.006968
85 | 0.694194 0.006477
86 | 0.721524 0.005927
87 | 0.748087 0.005340
88 | 0.773791 0.004735
89 | 0.798545 0.004130
90 | 0.822261 0.003538
91 | 0.844856 0.002973
92 | 0.866250 0.002443
93 | 0.886369 0.001955
94 | 0.905141 0.001515
95 | 0.922500 0.001126
96 | 0.938385 0.000789
97 | 0.952740 0.000505
98 | 0.965515 0.000273
99 | 0.976665 0.000093
100 | 0.986151 -.000038
101 | 0.993938 -.000097
102 | 1.000000 0.000000
103 |
--------------------------------------------------------------------------------
/runs/polref_100.387:
--------------------------------------------------------------------------------
1 | # Langley LTPT
2 | 0.0201 0.098 | Eppler 387 polar Re=100000 Langley LTPT
3 | 0.0201 0.101
4 | 0.0168 0.199
5 | 0.0164 0.289
6 | 0.0155 0.289
7 | 0.0173 0.392
8 | 0.0189 0.491
9 | 0.0218 0.589
10 | 0.0216 0.589
11 | 0.0238 0.686
12 | 0.0241 0.786
13 | 0.0241 0.880
14 | 0.0234 0.880
15 | 0.0237 0.880
16 | 0.0230 0.978
17 | 0.0232 0.978
18 | 0.0225 1.029
19 | 0.0219 1.029
20 | 0.0214 1.077
21 | 0.0212 1.077
22 | 0.0212 1.179
23 | 0.0207 1.179
24 | 0.0246 1.190
25 | 0.0285 1.199
26 | 0.0505 1.205
27 | 999. 999.
28 | -2.97 0.098
29 | -2.97 0.101
30 | -2.01 0.199
31 | -1.00 0.289
32 | -1.00 0.289
33 | 0.00 0.392
34 | 1.00 0.491
35 | 2.00 0.589
36 | 2.00 0.589
37 | 3.00 0.686
38 | 4.02 0.786
39 | 5.00 0.880
40 | 5.00 0.880
41 | 5.00 0.880
42 | 6.01 0.978
43 | 6.01 0.978
44 | 6.52 1.029
45 | 6.52 1.029
46 | 7.01 1.077
47 | 7.01 1.077
48 | 8.02 1.179
49 | 8.02 1.179
50 | 8.52 1.190
51 | 9.02 1.199
52 | 11.02 1.205
53 | 12.04 1.194
54 | 999. 999.
55 | -2.97 -0.1002
56 | -2.97 -0.1005
57 | -2.01 -0.0994
58 | -1.00 -0.0955
59 | -1.00 -0.0955
60 | 0.00 -0.0971
61 | 1.00 -0.0972
62 | 2.00 -0.0983
63 | 2.00 -0.0983
64 | 3.00 -0.0983
65 | 4.02 -0.0943
66 | 5.00 -0.0879
67 | 5.00 -0.0879
68 | 5.00 -0.0879
69 | 6.01 -0.0835
70 | 6.01 -0.0835
71 | 6.52 -0.0814
72 | 6.52 -0.0814
73 | 7.01 -0.0786
74 | 7.01 -0.0786
75 | 8.02 -0.0752
76 | 8.02 -0.0752
77 | 8.52 -0.0717
78 | 9.02 -0.0674
79 | 11.02 -0.0549
80 | 12.04 -0.0509
81 | 999. 999.
82 | 999. 999.
83 |
--------------------------------------------------------------------------------
/runs/tad.dat:
--------------------------------------------------------------------------------
1 | me993ym
2 | 1.000000 -1.663260
3 | 0.9963190 -1.657740
4 | 0.9923760 -1.652410
5 | 0.9881520 -1.647300
6 | 0.9836010 -1.642480
7 | 0.9788250 -1.637880
8 | 0.9739550 -1.633390
9 | 0.9689880 -1.628990
10 | 0.9639510 -1.624680
11 | 0.9588620 -1.620430
12 | 0.9537280 -1.616240
13 | 0.9485550 -1.612090
14 | 0.9433500 -1.607980
15 | 0.9381160 -1.603910
16 | 0.9328550 -1.599880
17 | 0.9275730 -1.595870
18 | 0.9222710 -1.591890
19 | 0.9169450 -1.587940
20 | 0.9116010 -1.584020
21 | 0.9062440 -1.580110
22 | 0.9008700 -1.576230
23 | 0.8954800 -1.572370
24 | 0.8900780 -1.568530
25 | 0.8846650 -1.564700
26 | 0.8792370 -1.560890
27 | 0.8737950 -1.557100
28 | 0.8628800 -1.549570
29 | 0.8574070 -1.545830
30 | 0.8519240 -1.542100
31 | 0.8464320 -1.538390
32 | 0.8409280 -1.534690
33 | 0.8354140 -1.531010
34 | 0.8298910 -1.527350
35 | 0.8243610 -1.523690
36 | 0.8188240 -1.520040
37 | 0.8132780 -1.516410
38 | 0.8077220 -1.512790
39 | 0.8021580 -1.509180
40 | 0.7965880 -1.505590
41 | 0.7910120 -1.502000
42 | 0.7854280 -1.498430
43 | 0.7798360 -1.494860
44 | 0.7742380 -1.491310
45 | 0.7686350 -1.487770
46 | 0.7630270 -1.484230
47 | 0.7574120 -1.480710
48 | 0.7517890 -1.477190
49 | 0.7461580 -1.473690
50 | 0.7405200 -1.470210
51 | 0.7348750 -1.466730
52 | 0.7292220 -1.463260
53 | 0.7235610 -1.459810
54 | 0.7178890 -1.456380
55 | 0.7122060 -1.452970
56 | 0.7065110 -1.449570
57 | 0.7008030 -1.446200
58 | 0.6950810 -1.442850
59 | 0.6893410 -1.439530
60 | 0.6835860 -1.436240
61 | 0.6778160 -1.432970
62 | 0.6720270 -1.429740
63 | 0.6662170 -1.426550
64 | 0.6603850 -1.423390
65 | 0.6545330 -1.420280
66 | 0.6486610 -1.417200
67 | 0.6427690 -1.414160
68 | 0.6368650 -1.411140
69 | 0.6309560 -1.408140
70 | 0.6250400 -1.405140
71 | 0.6191170 -1.402160
72 | 0.6131850 -1.399200
73 | 0.6072410 -1.396270
74 | 0.6012850 -1.393350
75 | 0.5953140 -1.390470
76 | 0.5893260 -1.387630
77 | 0.5833180 -1.384820
78 | 0.5772900 -1.382060
79 | 0.5712390 -1.379350
80 | 0.5651720 -1.376680
81 | 0.5591060 -1.374000
82 | 0.5530440 -1.371320
83 | 0.5469830 -1.368630
84 | 0.5409210 -1.365940
85 | 0.5348560 -1.363270
86 | 0.5287810 -1.360610
87 | 0.5226900 -1.357990
88 | 0.5165750 -1.355430
89 | 0.5104230 -1.352960
90 | 0.5042240 -1.350610
91 | 0.4979660 -1.348420
92 | 0.4916450 -1.346420
93 | 0.4852640 -1.344620
94 | 0.4788290 -1.343020
95 | 0.4723530 -1.341600
96 | 0.4658470 -1.340330
97 | 0.4593150 -1.339190
98 | 0.4527520 -1.338250
99 | 0.4461500 -1.337640
100 | 0.4395190 -1.337560
101 | 0.4329310 -1.338300
102 | 0.4266160 -1.340270
103 | 0.4211230 -1.343940
104 | 0.4171770 -1.349230
105 | 0.4148200 -1.355420
106 | 0.4141470 -1.361990
107 | 0.4159600 -1.368320
108 | 0.4201320 -1.373430
109 | 0.4256470 -1.377080
110 | 0.4317250 -1.379730
111 | 0.4380560 -1.381700
112 | 0.4445110 -1.383210
113 | 0.4510340 -1.384390
114 | 0.4575970 -1.385340
115 | 0.4641820 -1.386100
116 | 0.4707820 -1.386730
117 | 0.4840060 -1.387710
118 | 0.4906250 -1.388100
119 | 0.4972460 -1.388450
120 | 0.5038680 -1.388770
121 | 0.5104900 -1.389080
122 | 0.5171130 -1.389390
123 | 0.5237350 -1.389720
124 | 0.5303560 -1.390060
125 | 0.5369750 -1.390450
126 | 0.5435910 -1.390880
127 | 0.5502020 -1.391380
128 | 0.5568070 -1.391950
129 | 0.5634040 -1.392620
130 | 0.5699870 -1.393400
131 | 0.5765520 -1.394330
132 | 0.5830910 -1.395420
133 | 0.5895930 -1.396720
134 | 0.5960380 -1.398280
135 | 0.6023990 -1.400140
136 | 0.6086350 -1.402400
137 | 0.6146660 -1.405150
138 | 0.6205920 -1.408120
139 | 0.6265110 -1.411110
140 | 0.6324210 -1.414120
141 | 0.6383260 -1.417130
142 | 0.6442210 -1.420170
143 | 0.6501000 -1.423230
144 | 0.6559590 -1.426330
145 | 0.6676120 -1.432660
146 | 0.6734070 -1.435880
147 | 0.6791830 -1.439140
148 | 0.6849410 -1.442420
149 | 0.6906820 -1.445740
150 | 0.6964080 -1.449080
151 | 0.7021190 -1.452450
152 | 0.7078170 -1.455840
153 | 0.7135020 -1.459250
154 | 0.7191760 -1.462680
155 | 0.7248400 -1.466130
156 | 0.7304950 -1.469590
157 | 0.7361420 -1.473060
158 | 0.7417800 -1.476550
159 | 0.7474110 -1.480050
160 | 0.7530360 -1.483560
161 | 0.7586530 -1.487080
162 | 0.7642640 -1.490610
163 | 0.7698680 -1.494160
164 | 0.7754670 -1.497710
165 | 0.7810590 -1.501270
166 | 0.7866440 -1.504840
167 | 0.7922230 -1.508420
168 | 0.7977950 -1.512020
169 | 0.8033590 -1.515620
170 | 0.8089150 -1.519240
171 | 0.8144640 -1.522870
172 | 0.8200050 -1.526510
173 | 0.8255370 -1.530160
174 | 0.8310600 -1.533830
175 | 0.8365740 -1.537510
176 | 0.8420800 -1.541210
177 | 0.8475750 -1.544920
178 | 0.8530600 -1.548640
179 | 0.8585350 -1.552380
180 | 0.8640000 -1.556130
181 | 0.8694530 -1.559900
182 | 0.8748950 -1.563690
183 | 0.8803250 -1.567500
184 | 0.8857420 -1.571320
185 | 0.8911460 -1.575160
186 | 0.8965360 -1.579020
187 | 0.9019110 -1.582900
188 | 0.9072710 -1.586800
189 | 0.9126150 -1.590730
190 | 0.9179410 -1.594680
191 | 0.9232480 -1.598650
192 | 0.9285340 -1.602650
193 | 0.9337970 -1.606680
194 | 0.9390350 -1.610750
195 | 0.9442430 -1.614850
196 | 0.9494180 -1.619000
197 | 0.9545560 -1.623190
198 | 0.9596490 -1.627430
199 | 0.9646920 -1.631740
200 | 0.9696590 -1.636130
201 | 0.9745360 -1.640620
202 | 0.9793090 -1.645220
203 | 0.9838610 -1.650040
204 | 0.9880470 -1.655180
205 | 0.9919670 -1.660530
206 | 0.9955810 -1.666090
207 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | from setuptools import setup, find_packages
2 |
3 | version = '0.0.16'
4 |
5 | def readme():
6 | with open('README.md') as f:
7 | return f.read()
8 |
9 | setup(
10 | name='xfoil',
11 | version=version,
12 | description='Stripped down version of XFOIL as compiled python module ',
13 | #long_description=readme(),
14 | classifiers=[
15 | 'Development Status :: 3 - Alpha',
16 | 'Intended Audience :: Science/Research',
17 | 'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)',
18 | 'Natural Language :: English',
19 | 'Operating System :: MacOS :: MacOS X',
20 | 'Operating System :: POSIX :: Linux',
21 | 'Operating System :: Microsoft :: Windows',
22 | 'Programming Language :: Fortran',
23 | 'Programming Language :: Python :: 3 :: Only',
24 | 'Topic :: Scientific/Engineering',
25 | ],
26 | keywords='xfoil airfoil aerodynamic analysis',
27 | #url='https://github.com/daniel-de-vries/xfoil-python',
28 | #download_url='https://github.com/daniel-de-vries/xfoil-python/tarball/' + version,
29 | author='Daniël de Vries',
30 | author_email='contact@daniel-de-vries.com',
31 | license='GNU General Public License v3 or later (GPLv3+)',
32 | packages=['xfoil'],
33 | package_dir={'': 'src'},
34 | #ext_modules=[CMakeExtension('xfoil.xfoil')],
35 | #cmdclass={'build_ext': CMakeBuild},
36 | install_requires=['numpy'],
37 | #zip_save=False
38 | )
39 |
--------------------------------------------------------------------------------
/src/__init__.py:
--------------------------------------------------------------------------------
1 | from . import xfoil
--------------------------------------------------------------------------------
/src/fortran/api.f90:
--------------------------------------------------------------------------------
1 | !***********************************************************************
2 | ! Copyright (c) 2019 D. de Vries
3 | !
4 | ! This file is part of XFoil.
5 | !
6 | ! XFoil is free software: you can redistribute it and/or modify
7 | ! it under the terms of the GNU General Public License as published by
8 | ! the Free Software Foundation, either version 3 of the License, or
9 | ! (at your option) any later version.
10 | !
11 | ! XFoil is distributed in the hope that it will be useful,
12 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | ! GNU General Public License for more details.
15 | !
16 | ! You should have received a copy of the GNU General Public License
17 | ! along with XFoil. If not, see .
18 | !***********************************************************************
19 |
20 | module api
21 | use, intrinsic :: iso_c_binding, only: c_float, c_int, c_bool, c_null_ptr, c_char, c_null_char
22 | implicit none
23 | contains
24 | subroutine set_print(setting) bind(c, name='set_print')
25 | use i_xfoil, only: show_output
26 | logical(c_bool), intent(in) :: setting
27 | show_output = setting
28 | end subroutine set_print
29 |
30 | function get_print() bind(c, name='get_print')
31 | use i_xfoil, only: show_output
32 | logical(c_bool) :: get_print
33 | get_print = show_output
34 | end function get_print
35 |
36 | subroutine set_airfoil(x_in, y_in, n_in) bind(c, name='set_airfoil')
37 | use m_xgeom, only: geopar, norm
38 | use m_spline, only: seval, segspl, scalc
39 | use m_xgdes, only: abcopy
40 | use m_xgeom, only: cang
41 | use i_xfoil
42 |
43 | integer(c_int), intent(in) :: n_in
44 | real(c_float), intent(in) :: x_in(n_in), y_in(n_in)
45 |
46 | ! Local variables
47 | !
48 | real :: area, xble, xbte, xinl, xout, xtmp, yble, ybot, ybte, ytmp, ytop, amax, angtol
49 | integer :: i, ip, kdot, lu, imax, Itype
50 |
51 | data angtol/40.0/
52 |
53 | do i=1, n_in
54 | XB(i) = x_in(i)
55 | YB(i) = y_in(i)
56 | end do
57 | NB = n_in
58 |
59 | !---- calculate airfoil area assuming counterclockwise ordering
60 | area = 0.0
61 | do i = 1, NB
62 | ip = i + 1
63 | if (i==NB) ip = 1
64 | area = area + 0.5 * (YB(i) + YB(ip)) * (XB(i) - XB(ip))
65 | enddo
66 | !
67 | if (area>=0.0) then
68 | LCLock = .false.
69 | if (show_output) write (*, 99001) NB
70 | !...............................................................
71 | 99001 format (/' Number of input coordinate points:', i4/' Counterclockwise ordering')
72 | else
73 | !----- if area is negative (clockwise order), reverse coordinate order
74 | LCLock = .true.
75 | if (show_output) write (*, 99002) NB
76 | 99002 format (/' Number of input coordinate points:', i4/' Clockwise ordering')
77 | do i = 1, NB / 2
78 | xtmp = XB(NB - i + 1)
79 | ytmp = YB(NB - i + 1)
80 | XB(NB - i + 1) = XB(i)
81 | YB(NB - i + 1) = YB(i)
82 | XB(i) = xtmp
83 | YB(i) = ytmp
84 | enddo
85 | endif
86 | !
87 | if (LNOrm) then
88 | call norm(XB, XBP, YB, YBP, SB, NB)
89 | if (show_output) write (*, 99003)
90 | 99003 format (/' Airfoil has been normalized')
91 | endif
92 | !
93 | call scalc(XB, YB, SB, NB)
94 | call segspl(XB, XBP, SB, NB)
95 | call segspl(YB, YBP, SB, NB)
96 | !
97 | call geopar(XB, XBP, YB, YBP, SB, NB, W1, SBLe, CHOrdb, AREab, &
98 | RADble, ANGbte, EI11ba, EI22ba, APX1ba, APX2ba, EI11bt, EI22bt, APX1bt, &
99 | & APX2bt, THIckb, CAMbrb)
100 | !
101 | xble = seval(SBLe, XB, XBP, SB, NB)
102 | yble = seval(SBLe, YB, YBP, SB, NB)
103 | xbte = 0.5 * (XB(1) + XB(NB))
104 | ybte = 0.5 * (YB(1) + YB(NB))
105 | !
106 | if (show_output) write (*, 99004) xble, yble, CHOrdb, xbte, ybte
107 | 99004 format (/' LE x,y =', 2F10.5, ' | Chord =', f10.5/' TE x,y =', 2F10.5, ' |')
108 | !
109 | !---- set reasonable MSES domain parameters for non-MSES coordinate file
110 | if (Itype<=2 .and. ISPars==' ') then
111 | xble = seval(SBLe, XB, XBP, SB, NB)
112 | yble = seval(SBLe, YB, YBP, SB, NB)
113 | xinl = xble - 2.0 * CHOrdb
114 | xout = xble + 3.0 * CHOrdb
115 | ybot = yble - 2.5 * CHOrdb
116 | ytop = yble + 3.5 * CHOrdb
117 | xinl = aint(20.0 * abs(xinl / CHOrdb) + 0.5) / 20.0 * sign(CHOrdb, xinl)
118 | xout = aint(20.0 * abs(xout / CHOrdb) + 0.5) / 20.0 * sign(CHOrdb, xout)
119 | ybot = aint(20.0 * abs(ybot / CHOrdb) + 0.5) / 20.0 * sign(CHOrdb, ybot)
120 | ytop = aint(20.0 * abs(ytop / CHOrdb) + 0.5) / 20.0 * sign(CHOrdb, ytop)
121 | write (ISPars, 99005) xinl, xout, ybot, ytop
122 | 99005 format (1x, 4F8.2)
123 | endif
124 | !
125 | !---- wipe out old flap hinge location
126 | XBF = 0.0
127 | YBF = 0.0
128 | LBFlap = .false.
129 | !
130 | !---- wipe out off-design alphas, CLs
131 | !c NALOFF = 0
132 | !c NCLOFF = 0
133 | !
134 |
135 | call abcopy(.true.)
136 | !
137 | call cang(X, Y, N, 0, imax, amax)
138 | if (abs(amax)>angtol .and. show_output) write (*, 99007) amax, imax
139 | 99007 format (/&
140 | ' WARNING: Poor input coordinate distribution'/&
141 | ' Excessive panel angle', f7.1, ' at i =', i4/&
142 | ' Repaneling with PANE and/or PPAR suggested'/&
143 | ' (doing GDES,CADD before repaneling _may_'/&
144 | ' improve excessively coarse LE spacing')
145 | end subroutine set_airfoil
146 |
147 | function get_n_coords() bind(c, name='get_n_coords')
148 | use i_xfoil, only: NB
149 | integer(c_int) :: get_n_coords
150 | get_n_coords = NB
151 | end function get_n_coords
152 |
153 | subroutine get_airfoil(x, y, n) bind(c, name='get_airfoil')
154 | use i_xfoil, only: XB, YB
155 | integer(c_int), intent(in) :: n
156 | real(c_float), intent(inout) :: x(n), y(n)
157 | integer :: i
158 | do i=1, n
159 | x(i) = XB(i)
160 | y(i) = YB(i)
161 | end do
162 | end subroutine get_airfoil
163 |
164 | subroutine set_naca(spec) bind(c, name='set_naca')
165 | use m_xfoil, only: naca
166 | integer(c_int), intent(in) :: spec
167 | if (spec <= 0) then
168 | write(0, *) 'Invalid NACA specifier. Specify a NACA 4 or 5 series airfoil code.'
169 | else
170 | call naca(spec)
171 | end if
172 | end subroutine set_naca
173 |
174 | subroutine set_reynolds(Re) bind(c, name='set_reynolds')
175 | use i_xfoil
176 | real(c_float), intent(in) :: Re
177 |
178 | if (Re == 0.) then
179 | LVIsc = .false.
180 | else
181 | LVIsc = .true.
182 | end if
183 |
184 | REInf1 = Re
185 |
186 | LBLini = .false.
187 | LIPan = .false.
188 |
189 | LVConv = .false.
190 | end subroutine set_reynolds
191 |
192 | function get_reynolds() bind(c, name='get_reynolds')
193 | use i_xfoil, only: REInf1
194 | real(c_float) :: get_reynolds
195 | get_reynolds = REInf1
196 | end function get_reynolds
197 |
198 | subroutine set_mach(M) bind(c, name='set_mach')
199 | use s_xfoil, only: comset, cpcalc, clcalc, cdcalc
200 | use i_xfoil
201 |
202 | real(c_float), intent(in) :: M
203 |
204 | if (M /= MINf) then
205 | MINf = M
206 |
207 | call comset
208 | if (MINf>0.0 .and. show_output) write (*, 99003) CPStar, QSTar / QINf
209 | 99003 format (/' Sonic Cp =', f10.2, ' Sonic Q/Qinf =', f10.3/)
210 |
211 | call cpcalc(N, QINv, QINf, MINf, CPI)
212 | if (LVIsc) call cpcalc(N + NW, QVIs, QINf, MINf, CPV)
213 | call clcalc(N, X, Y, GAM, GAM_a, ALFa, MINf, QINf, XCMref, YCMref, CL, CM, CDP, CL_alf, CL_msq)
214 | call cdcalc
215 | end if
216 |
217 | LVConv = .false.
218 | end subroutine set_mach
219 |
220 | function get_mach() bind(c, name='get_mach')
221 | use i_xfoil, only: MINf
222 | real(c_float) :: get_mach
223 | get_mach = MINf
224 | end function get_mach
225 |
226 | subroutine set_xtr(xtr_top, xtr_bot) bind(c, name='set_xtr')
227 | use i_xfoil, only: XSTrip, LVConv
228 | real(c_float), intent(in) :: xtr_top, xtr_bot
229 | XSTrip(1) = xtr_top
230 | XSTrip(2) = xtr_bot
231 | LVConv = .false.
232 | end subroutine set_xtr
233 |
234 | subroutine get_xtr(xtr_top, xtr_bot) bind(c, name='get_xtr')
235 | use i_xfoil, only: XSTrip
236 | real(c_float) :: xtr_top, xtr_bot
237 | xtr_top = XSTrip(1)
238 | xtr_bot = XSTrip(2)
239 | end subroutine get_xtr
240 |
241 | subroutine set_n_crit(n_crit) bind(c, name='set_n_crit')
242 | use i_xfoil, only: ACRit, LVConv
243 | real(c_float), intent(in) :: n_crit
244 | ACRit(1) = n_crit
245 | ACRit(2) = n_crit
246 | LVConv = .false.
247 | end subroutine set_n_crit
248 |
249 | function get_n_crit() bind(c, name='get_n_crit')
250 | use i_xfoil, only: ACRit
251 | real(c_float) :: get_n_crit
252 | get_n_crit = ACRit(1)
253 | end function get_n_crit
254 |
255 | subroutine set_max_iter(max_iter) bind(c, name='set_max_iter')
256 | use i_xfoil, only: ITMax
257 | integer(c_int), intent(in) :: max_iter
258 | ITMax = max_iter
259 | end subroutine set_max_iter
260 |
261 | function get_max_iter() bind(c, name='get_max_iter')
262 | use i_xfoil, only: ITMax
263 | integer(c_int) :: get_max_iter
264 | get_max_iter = ITMax
265 | end function get_max_iter
266 |
267 | subroutine reset_bls() bind(c, name='reset_bls')
268 | use i_xfoil, only: LBLini, LIPan, show_output
269 | LBLini = .not.LBLini
270 | if (LBLini) then
271 | if (show_output) write (*, *) 'BLs are assumed to be initialized'
272 | else
273 | if (show_output) write (*, *) 'BLs will be initialized on next point'
274 | LIPan = .false.
275 | endif
276 | end subroutine reset_bls
277 |
278 | subroutine repanel(n_panel, cv_par, cte_ratio, ctr_ratio, &
279 | xs_ref1, xs_ref2, xp_ref1, xp_ref2) bind(c, name='repanel')
280 | use m_xfoil, only: pangen
281 | use m_xgeom, only: cang
282 | use i_xfoil
283 |
284 | integer :: imax
285 | real :: amax
286 | integer(c_int), intent(in) :: n_panel
287 | real(c_float), intent(in) :: cv_par, cte_ratio, ctr_ratio, xs_ref1, xs_ref2, xp_ref1, xp_ref2
288 |
289 | NPAn = min(n_panel, IQX - 6)
290 | CVPar = cv_par
291 | CTErat = cte_ratio
292 | CTRrat = ctr_ratio
293 | XSRef1 = xs_ref1
294 | XSRef2 = xs_ref2
295 | XPRef1 = xp_ref1
296 | XPRef2 = xp_ref2
297 |
298 | call pangen(.true.)
299 | if (N>0) call cang(X, Y, N, 1, imax, amax)
300 | end subroutine repanel
301 |
302 | subroutine filter(factor) bind(c, name='filter')
303 | use m_xmdes, only: cnfilt, piqsum, qspcir, qspint
304 | use i_xfoil
305 |
306 | real(c_float), intent(in) :: factor
307 |
308 | real :: cfilt, clq
309 | integer :: kqsp
310 |
311 | !----- apply modified Hanning filter to Cn coefficients
312 | cfilt = factor
313 | call cnfilt(cfilt)
314 | call piqsum
315 | call qspcir
316 |
317 | do kqsp = 1, NQSp
318 | call qspint(ALQsp(kqsp), QSPec(1, kqsp), QINf, MINf, clq, CMQsp(kqsp))
319 | if (IACqsp==1) CLQsp(kqsp) = clq
320 | enddo
321 | LQSppl = .false.
322 | end subroutine filter
323 |
324 | subroutine alfa_(a_input, cl_out, cd_out, cd_f_out, cd_p_out, cm_out, cp_out, conv) bind(c, name='alfa')
325 | use m_xoper, only: specal, viscal, fcpmin
326 | use i_xfoil
327 |
328 | real(c_float), intent(in) :: a_input
329 | real(c_float), intent(out) :: cl_out, cd_out, cd_f_out, cd_p_out, cm_out, cp_out
330 | logical(c_bool), intent(out) :: conv
331 | ADEg = a_input
332 |
333 | ALFa = a_input * DTOr
334 | QINf = 1.0
335 | LALfa = .true.
336 | call specal
337 | if (abs(ALFa - AWAke)>1.0E-5) LWAke = .false.
338 | if (abs(ALFa - AVIsc)>1.0E-5) LVConv = .false.
339 | if (abs(MINf - MVIsc)>1.0E-5) LVConv = .false.
340 | !
341 | if (LVIsc) then
342 | conv = viscal(ITMax)
343 | conv = LVConv .and. conv
344 | else
345 | conv = .true.
346 | end if
347 |
348 | cl_out = CL
349 | cd_out = CD
350 | cd_f_out = CDF
351 | cd_p_out = CDP
352 | cm_out = CM
353 |
354 | call fcpmin
355 | cp_out = CPMn
356 | end subroutine alfa_
357 |
358 | subroutine cl_(cl_input, a_out, cd_out, cd_f_out, cd_p_out, cm_out, cp_out, conv) bind(c, name='cl')
359 | use m_xoper, only: speccl, viscal, fcpmin
360 | use i_xfoil
361 |
362 | real(c_float), intent(in) :: cl_input
363 | real(c_float), intent(out) :: a_out, cd_out, cd_f_out, cd_p_out, cm_out, cp_out
364 | logical(c_bool), intent(out) :: conv
365 |
366 | CLSpec = cl_input
367 | ALFa = 0.0
368 | QINf = 1.0
369 | LALfa = .false.
370 | call speccl
371 | ADEg = ALFa / DTOr
372 | if (abs(ALFa - AWAke)>1.0E-5) LWAke = .false.
373 | if (abs(ALFa - AVIsc)>1.0E-5) LVConv = .false.
374 | if (abs(MINf - MVIsc)>1.0E-5) LVConv = .false.
375 |
376 | if (LVIsc) then
377 | conv = viscal(ITMax)
378 | conv = LVConv .and. conv
379 | else
380 | conv = .true.
381 | end if
382 |
383 | a_out = ALFa / DTOr
384 | cd_out = CD
385 | cd_f_out = CDF
386 | cd_p_out = CDP
387 | cm_out = CM
388 |
389 | call fcpmin
390 | cp_out = CPMn
391 | end subroutine cl_
392 |
393 | subroutine aseq(a_start, a_end, n_step, &
394 | a_arr, cl_arr, cd_arr, cm_arr, cp_arr, conv_arr) bind(c, name='aseq')
395 | use m_xoper, only: specal, viscal, fcpmin
396 | use i_xfoil
397 | real(c_float), intent(in) :: a_start, a_end
398 | integer(c_int), intent(in) :: n_step
399 | real(c_float), dimension(n_step), intent(inout) :: a_arr, cl_arr, cd_arr, cm_arr, cp_arr
400 | logical(c_bool), dimension(n_step), intent(inout) :: conv_arr
401 | integer :: i, j, iseqex, itmaxs
402 | real :: a0, da, nan
403 |
404 | nan = 0
405 | nan = 0/nan
406 |
407 | a0 = a_start * DTOr
408 | da = (a_end - a_start) / float(n_step) * DTOr
409 |
410 | LALfa = .true.
411 |
412 | !----- initialize unconverged-point counter
413 | iseqex = 0
414 |
415 | do i=1, n_step
416 | ALFa = a0 + da * float(i - 1)
417 | if (abs(ALFa - AWAke)>1.0E-5) LWAke = .false.
418 | if (abs(ALFa - AVIsc)>1.0E-5) LVConv = .false.
419 | if (abs(MINf - MVIsc)>1.0E-5) LVConv = .false.
420 | call specal
421 | itmaxs = ITMax + 5
422 | if (LVIsc) then
423 | conv_arr(i) = viscal(itmaxs)
424 | end if
425 | ADEg = ALFa / DTOr
426 |
427 | a_arr(i) = ADEg
428 | cl_arr(i) = CL
429 | cd_arr(i) = CD
430 | cm_arr(i) = CM
431 |
432 | call fcpmin
433 | cp_arr(i) = CPMn
434 |
435 | if ((LVConv .and. conv_arr(i)) .or. .not.LVIsc) then
436 | conv_arr(i) = .true.
437 | elseif (LVIsc .and. .not. (LVConv .and. conv_arr(i))) then
438 | conv_arr(i) = .false.
439 | endif
440 | end do
441 | end subroutine aseq
442 |
443 | subroutine cseq(cl_start, cl_end, n_step, &
444 | a_arr, cl_arr, cd_arr, cm_arr, cp_arr, conv_arr) bind(c, name='cseq')
445 | use m_xoper, only: specal, viscal, speccl, fcpmin
446 | use i_xfoil
447 | real(c_float), intent(in) :: cl_start, cl_end
448 | integer(c_int), intent(in) :: n_step
449 | real(c_float), dimension(n_step), intent(inout) :: a_arr, cl_arr, cd_arr, cm_arr, cp_arr
450 | logical(c_bool), dimension(n_step), intent(inout) :: conv_arr
451 | integer :: i, j, iseqex, itmaxs
452 | real :: cl0, dcl
453 |
454 | cl0 = cl_start
455 | dcl = (cl_end - cl_start) / float(n_step)
456 | LALfa = .false.
457 |
458 | !----- initialize unconverged-point counter
459 | iseqex = 0
460 |
461 | do i=1, n_step
462 | CLSpec = cl0 + dcl * float(i - 1)
463 | call speccl
464 | if (abs(ALFa - AWAke)>1.0E-5) LWAke = .false.
465 | if (abs(ALFa - AVIsc)>1.0E-5) LVConv = .false.
466 | if (abs(MINf - MVIsc)>1.0E-5) LVConv = .false.
467 |
468 | itmaxs = ITMax + 5
469 | if (LVIsc) then
470 | conv_arr(i) = viscal(itmaxs)
471 | end if
472 | ADEg = ALFa / DTOr
473 |
474 | a_arr(i) = ADEg
475 | cl_arr(i) = CL
476 | cd_arr(i) = CD
477 | cm_arr(i) = CM
478 |
479 | call fcpmin
480 | cp_arr(i) = CPMn
481 |
482 | if ((LVConv .and. conv_arr(i)) .or. .not.LVIsc) then
483 | conv_arr(i) = .true.
484 | elseif (LVIsc .and. .not. (LVConv .and. conv_arr(i))) then
485 | conv_arr(i) = .false.
486 | endif
487 | end do
488 | end subroutine cseq
489 |
490 | subroutine bldump_(c_filename, length) bind(c, name='boundary_layer_dump')
491 | use m_xoper, only: bldump
492 | use i_xfoil
493 | use iso_c_binding
494 | implicit none
495 |
496 | ! Input parameters
497 | integer(c_int), intent(in) :: length
498 | CHARACTER(kind=C_CHAR), intent(in) :: c_filename
499 |
500 | ! Fortran-like string
501 | character(len = length) :: f_filename
502 |
503 | ! Convert C char pointer array to Fortran string
504 | f_filename = char_array_to_string(c_filename, length)
505 |
506 | ! Output Fortran filename
507 | write(*,*) f_filename
508 |
509 | ! Dump boundary layer properties
510 | call bldump(f_filename)
511 |
512 | end subroutine bldump_
513 |
514 | subroutine cpdump_(c_filename, length) bind(c, name='cp_dump')
515 | use m_xoper, only: cpdump
516 | use i_xfoil
517 | use iso_c_binding
518 | implicit none
519 |
520 | ! Input parameters
521 | integer(c_int), intent(in) :: length
522 | CHARACTER(kind=C_CHAR), intent(in) :: c_filename
523 |
524 | ! Fortran-like string
525 | character(len = length) :: f_filename
526 |
527 | ! Convert C char pointer array to Fortran string
528 | f_filename = char_array_to_string(c_filename, length)
529 |
530 | ! Output Fortran filename
531 | write(*,*) f_filename
532 |
533 | ! Dump boundary layer properties
534 | call cpdump(f_filename)
535 |
536 | end subroutine cpdump_
537 |
538 |
539 | ! Utility functions
540 | ! fortran character(len=*) are not compatible with c
541 | ! To be compatible with c, strings sould be copied to a c_char array
542 | function char_array_to_string(char_array, length)
543 | integer(c_int) :: length
544 | character(c_char) :: char_array(length)
545 | character(len=length) :: char_array_to_string
546 | integer :: i
547 | do i = 1, length
548 | char_array_to_string(i:i) = char_array(i)
549 | enddo
550 | end function char_array_to_string
551 |
552 | ! C ends strings with a \0 character. Add this so it is received correctly in c compatible languages
553 | function string_to_char_array(s, length)
554 | integer(c_int) :: length
555 | character :: s(*)
556 | character(c_char) :: string_to_char_array(length)
557 | integer :: i
558 |
559 | do i = 1, length
560 | string_to_char_array(i:i) = s(i)
561 | enddo
562 |
563 | string_to_char_array(i+1:i+1) = c_null_char
564 |
565 | end function string_to_char_array
566 |
567 | end module api
568 |
--------------------------------------------------------------------------------
/src/fortran/i_blpar.f90:
--------------------------------------------------------------------------------
1 | !***********************************************************************
2 | ! Copyright (c) 2019 D. de Vries
3 | ! Original Copyright (c) 2000 Mark Drela
4 | !
5 | ! This file is part of XFoil.
6 | !
7 | ! XFoil is free software: you can redistribute it and/or modify
8 | ! it under the terms of the GNU General Public License as published by
9 | ! the Free Software Foundation, either version 3 of the License, or
10 | ! (at your option) any later version.
11 | !
12 | ! XFoil is distributed in the hope that it will be useful,
13 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | ! GNU General Public License for more details.
16 | !
17 | ! You should have received a copy of the GNU General Public License
18 | ! along with XFoil. If not, see .
19 | !***********************************************************************
20 |
21 | !*==I_BLPAR.f90 processed by SPAG 7.21DC at 11:25 on 11 Jan 2019
22 | module i_blpar
23 | implicit none
24 | !
25 | !*** Start of declarations rewritten by SPAG
26 | !
27 | ! Local variables
28 | !
29 | real :: cffac, ctcon, ctrcex, ctrcon, dlcon, duxcon, gacon, gbcon, gccon, sccon
30 | !
31 | !*** End of declarations rewritten by SPAG
32 | !
33 | !
34 | ! COMMON /BLPAR/
35 | !
36 | end module i_blpar
37 |
--------------------------------------------------------------------------------
/src/fortran/i_circle.f90:
--------------------------------------------------------------------------------
1 | !***********************************************************************
2 | ! Copyright (c) 2019 D. de Vries
3 | ! Original Copyright (c) 2000 Mark Drela
4 | !
5 | ! This file is part of XFoil.
6 | !
7 | ! XFoil is free software: you can redistribute it and/or modify
8 | ! it under the terms of the GNU General Public License as published by
9 | ! the Free Software Foundation, either version 3 of the License, or
10 | ! (at your option) any later version.
11 | !
12 | ! XFoil is distributed in the hope that it will be useful,
13 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | ! GNU General Public License for more details.
16 | !
17 | ! You should have received a copy of the GNU General Public License
18 | ! along with XFoil. If not, see .
19 | !***********************************************************************
20 |
21 | !*==I_CIRCLE.f90 processed by SPAG 7.21DC at 11:25 on 11 Jan 2019
22 | module i_circle
23 | implicit none
24 | !
25 | !*** Start of declarations rewritten by SPAG
26 | !
27 | ! PARAMETER definitions
28 | !
29 | integer, parameter :: ICX = 257, IMX = (ICX - 1) / 4
30 | !
31 | ! Local variables
32 | !
33 | real :: ag0, agte, dwc, pi, qim0, qimold
34 | complex :: chordz, dzte, zleold
35 | complex, dimension(0:IMX) :: cn
36 | complex, dimension(ICX, 0:IMX) :: eiw
37 | integer :: mc, mct, nc
38 | complex, dimension(ICX) :: piq, zc, zcoldw
39 | real, dimension(ICX) :: sc, scold, wc, xcold, ycold
40 | complex, dimension(ICX, IMX / 4) :: zc_cn
41 | !
42 | !*** End of declarations rewritten by SPAG
43 | !
44 | !
45 | ! PARAMETER definitions
46 | !
47 | !
48 | ! COMMON /CPC01/
49 | !
50 | !
51 | ! COMMON /CPI01/
52 | !
53 | !
54 | ! COMMON /CPR01/
55 | !
56 | end module i_circle
57 |
--------------------------------------------------------------------------------
/src/fortran/i_pindex.f90:
--------------------------------------------------------------------------------
1 | !***********************************************************************
2 | ! Copyright (c) 2019 D. de Vries
3 | ! Original Copyright (c) 2000 Mark Drela
4 | !
5 | ! This file is part of XFoil.
6 | !
7 | ! XFoil is free software: you can redistribute it and/or modify
8 | ! it under the terms of the GNU General Public License as published by
9 | ! the Free Software Foundation, either version 3 of the License, or
10 | ! (at your option) any later version.
11 | !
12 | ! XFoil is distributed in the hope that it will be useful,
13 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | ! GNU General Public License for more details.
16 | !
17 | ! You should have received a copy of the GNU General Public License
18 | ! along with XFoil. If not, see .
19 | !***********************************************************************
20 |
21 | !*==I_PINDEX.f90 processed by SPAG 7.21DC at 11:25 on 11 Jan 2019
22 | ! AREAD
23 | module i_pindex
24 | implicit none
25 | !
26 | !*** Start of declarations rewritten by SPAG
27 | !
28 | ! PARAMETER definitions
29 | !
30 | integer, parameter :: IAL = 1, ICL = 2, ICD = 3, ICM = 4, ICW = 5, ICV = 6, ICP = 7, IMA = 8, IRE = 9, &
31 | & ICH = 10, IMC = 11, ICDH = 12, ICMDOT = 13, IPTOT = 13, JNC = 1, JTP = 2, JTN = 3, &
32 | & JTI = 4, JPTOT = 4
33 | !
34 | ! Local variables
35 | !
36 | character(6), dimension(IPTOT), save :: cpolform
37 | character(10), dimension(IPTOT), save :: cpolname
38 | character(6), dimension(JPTOT), save :: cpolsform
39 | character(5), dimension(JPTOT), save :: cpolsname
40 | !
41 | !*** End of declarations rewritten by SPAG
42 | !
43 | !
44 | !*** Start of declarations rewritten by SPAG
45 | !
46 | ! PARAMETER definitions
47 | !
48 | !
49 | ! Local variables
50 | !
51 | !
52 | !*** End of declarations rewritten by SPAG
53 | !
54 | !
55 | !---- Pointers for referencing polar force coefficients
56 | ! First 4 pointers must be main polar plot variables.
57 | !
58 | ! ! alpha
59 | ! ! CL
60 | ! ! CD
61 | ! ! Cm
62 | ! ! CDwave
63 | ! ! CDvisc
64 | ! ! CDpres
65 | ! ! Mach
66 | ! ! Re
67 | ! ! Hinge moment
68 | ! ! Minimum Cp on surface
69 | ! ! CDh (engine thrust coeff.)
70 | !
71 | !
72 | !---------------------
73 | ! Pointers for referencing polar airfoil-side quantities
74 | !
75 | ! Cm_dot
76 | ! ! Ncrit
77 | ! ! trip
78 | ! ! transition
79 |
80 | !
81 | data cpolname/'alpha ', 'CL ', 'CD ', 'CM ', 'CDw ', 'CDv ', 'CDp ', &
82 | &'Mach ', 'Re ', 'Chinge ', 'Cpmin ', 'CDh ', 'Cmdot '/
83 | ! transition index
84 | ! ! alpha
85 | ! ! CL
86 | ! ! CD
87 | ! ! CM
88 | ! ! CDw
89 | ! ! CDv
90 | ! ! CDp
91 | ! ! Mach
92 | ! ! Re
93 | ! ! Chinge
94 | ! ! Cpmin
95 | ! ! CDh
96 | data cpolform/'F7.3 ', 'F9.4 ', 'F10.5 ', 'F9.4 ', 'F10.5 ', 'F10.5 ', 'F10.5 ', 'F8.4 ', 'E11.3 ', &
97 | &'F10.5 ', 'F9.4 ', 'F11.5 ', 'F9.5 '/
98 | ! Cmdot
99 |
100 | data cpolsname/'Ncrit', 'Xtrip', 'Xtr ', 'Itr '/
101 | ! ! Ncrit
102 | ! ! Xtrip
103 | ! ! Xtr
104 | data cpolsform/'F7.3 ', 'F9.4 ', 'F9.4 ', 'F9.4 '/
105 | ! Itr
106 | end module i_pindex
107 |
--------------------------------------------------------------------------------
/src/fortran/i_xbl.f90:
--------------------------------------------------------------------------------
1 | !***********************************************************************
2 | ! Copyright (c) 2019 D. de Vries
3 | ! Original Copyright (c) 2000 Mark Drela
4 | !
5 | ! This file is part of XFoil.
6 | !
7 | ! XFoil is free software: you can redistribute it and/or modify
8 | ! it under the terms of the GNU General Public License as published by
9 | ! the Free Software Foundation, either version 3 of the License, or
10 | ! (at your option) any later version.
11 | !
12 | ! XFoil is distributed in the hope that it will be useful,
13 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | ! GNU General Public License for more details.
16 | !
17 | ! You should have received a copy of the GNU General Public License
18 | ! along with XFoil. If not, see .
19 | !***********************************************************************
20 |
21 | !*==I_XBL.f90 processed by SPAG 7.21DC at 11:25 on 11 Jan 2019
22 | module i_xbl
23 | use i_blpar
24 | implicit none
25 | !
26 | !*** Start of declarations rewritten by SPAG
27 | !
28 | ! PARAMETER definitions
29 | !
30 | integer, parameter :: NCOM = 73
31 | !
32 | ! Local variables
33 | !
34 | real :: amcrit, bule, cfm, cfm_d1, cfm_d2, cfm_ms, cfm_re, cfm_t1, cfm_t2, cfm_u1, cfm_u2, dwte, gambl, &
35 | & gm1bl, hstinv, hstinv_ms, hvrat, qinfbl, reybl, reybl_ms, reybl_re, rstbl, rstbl_ms, tkbl, &
36 | & tkbl_ms, xiforc, xt, xt_a1, xt_d1, xt_d2, xt_ms, xt_re, xt_t1, xt_t2, xt_u1, xt_u2, xt_x1, &
37 | & xt_x2, xt_xf
38 | real, pointer :: ampl1, ampl2, cf1, cf1_d1, cf1_ms, cf1_re, cf1_t1, cf1_u1, cf2, cf2_d2, cf2_ms, cf2_re, &
39 | & cf2_t2, cf2_u2, cq1, cq1_d1, cq1_ms, cq1_re, cq1_t1, cq1_u1, cq2, cq2_d2, cq2_ms, &
40 | & cq2_re, cq2_t2, cq2_u2, d1, d2, de1, de1_d1, de1_ms, de1_t1, de1_u1, de2, de2_d2, &
41 | & de2_ms, de2_t2, de2_u2, di1, di1_d1, di1_ms, di1_re, di1_s1, di1_t1, di1_u1, di2, &
42 | & di2_d2, di2_ms, di2_re, di2_s2, di2_t2, di2_u2, dw1, dw2, h1, h1_d1, h1_t1, h2, h2_d2, &
43 | & h2_t2, hc1, hc1_d1, hc1_ms, hc1_t1, hc1_u1, hc2, hc2_d2, hc2_ms, hc2_t2, hc2_u2, hk1, &
44 | & hk1_d1, hk1_ms, hk1_t1, hk1_u1, hk2, hk2_d2, hk2_ms, hk2_t2, hk2_u2
45 | real, dimension(NCOM) :: c1sav, c2sav
46 | real, target, dimension(NCOM) :: com1, com2
47 | real, pointer :: hs1, hs1_d1, hs1_ms, hs1_re, hs1_t1, hs1_u1, hs2, hs2_d2, hs2_ms, hs2_re, hs2_t2, &
48 | & hs2_u2, m1, m1_ms, m1_u1, m2, m2_ms, m2_u2, r1, r1_ms, r1_u1, r2, r2_ms, r2_u2, rt1, &
49 | & rt1_ms, rt1_re, rt1_t1, rt1_u1, rt2, rt2_ms, rt2_re, rt2_t2, rt2_u2, s1, s2, t1, t2, &
50 | & u1, u1_ms, u1_uei, u2, u2_ms, u2_uei, us1, us1_d1, us1_ms, us1_re, us1_t1, us1_u1, us2, &
51 | & us2_d2, us2_ms, us2_re, us2_t2, us2_u2, v1, v1_ms, v1_re, v1_u1, v2, v2_ms, v2_re, &
52 | & v2_u2, x1, x2
53 | integer :: idampv
54 | logical :: simi, tran, trforc, trfree, turb, wake
55 | real, dimension(4, 5) :: vs1, vs2
56 | real, dimension(4) :: vsm, vsr, vsrez, vsx
57 | !
58 | !*** End of declarations rewritten by SPAG
59 | !
60 | !
61 | ! PARAMETER definitions
62 | !
63 | !
64 | ! COMMON /V_COM/
65 | !
66 | !
67 | ! COMMON /V_INT/
68 | !
69 | !
70 | ! COMMON /V_SAV/
71 | !
72 | !
73 | ! COMMON /V_SYS/
74 | !
75 | !
76 | ! COMMON /V_VAR/
77 | !
78 | !
79 | ! COMMON /V_VAR1/
80 | !
81 | !
82 | ! COMMON /V_VAR2/
83 | !
84 | !
85 | ! COMMON /V_VARA/
86 | !
87 | end module i_xbl
88 |
--------------------------------------------------------------------------------
/src/fortran/m_aread.f90:
--------------------------------------------------------------------------------
1 | !***********************************************************************
2 | ! Copyright (c) 2019 D. de Vries
3 | ! Original Copyright (c) 2000 Mark Drela
4 | !
5 | ! This file is part of XFoil.
6 | !
7 | ! XFoil is free software: you can redistribute it and/or modify
8 | ! it under the terms of the GNU General Public License as published by
9 | ! the Free Software Foundation, either version 3 of the License, or
10 | ! (at your option) any later version.
11 | !
12 | ! XFoil is distributed in the hope that it will be useful,
13 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | ! GNU General Public License for more details.
16 | !
17 | ! You should have received a copy of the GNU General Public License
18 | ! along with XFoil. If not, see .
19 | !***********************************************************************
20 |
21 | !*==AREAD.f90 processed by SPAG 7.21DC at 11:25 on 11 Jan 2019
22 | module m_aread
23 | contains
24 | subroutine aread(Lu, Fname, Nmax, X, Y, N, Name, Ispars, Itype, Info)
25 | use i_xfoil, only: show_output
26 | use m_userio, only: getflt, aski
27 | implicit none
28 | !
29 | !*** Start of declarations rewritten by SPAG
30 | !
31 | ! Dummy arguments
32 | !
33 | character(*) :: Fname, Ispars, Name
34 | integer :: Info, Itype, Lu, N, Nmax
35 | real, dimension(Nmax) :: X, Y
36 | intent (in) Fname, Info, Lu, Nmax
37 | intent (out) Ispars, Itype, N
38 | intent (inout) Name, X, Y
39 | !
40 | ! Local variables
41 | !
42 | real, dimension(10) :: a
43 | logical :: error, lopen
44 | integer :: i, iel, na, nel, nfn
45 | character(80) :: line, line1, line2
46 | !
47 | !*** End of declarations rewritten by SPAG
48 | !
49 | !
50 | !*** Start of declarations rewritten by SPAG
51 | !
52 | ! Dummy arguments
53 | !
54 | !
55 | ! Local variables
56 | !
57 | !
58 | !*** End of declarations rewritten by SPAG
59 | !
60 | !--------------------------------------------------------
61 | ! Reads in several types of airfoil coordinate file.
62 | !
63 | ! Input:
64 | ! LU logical unit to use for reading
65 | ! FNAME name of coordinate file to be read,
66 | ! if FNAME(1:1).eq.' ', unit LU is assumed
67 | ! to be already open
68 | ! INFO 0 keep quiet
69 | ! 1 print info on airfoil
70 | ! Output:
71 | ! X,Y coordinates
72 | ! N number of X,Y coordinates
73 | ! NAME character name string (if ITYPE > 1)
74 | ! ISPARS ISES/MSES domain-size string (if ITYPE > 2)
75 | ! ITYPE returns type of file:
76 | ! 0 None. Read error occurred.
77 | ! 1 Generic.
78 | ! 2 Labeled generic.
79 | ! 3 MSES single element.
80 | ! 4 MSES multi-element.
81 | !--------------------------------------------------------
82 | !
83 | iel = 0
84 | nel = 0
85 | !
86 | !---- assume read error will occur
87 | Itype = 0
88 | !
89 | lopen = Fname(1:1)/=' '
90 | if (lopen) open (Lu, file = Fname, status = 'OLD', err = 200)
91 | do
92 | !
93 | read (Lu, 99004, end = 300, err = 200) line1
94 | if (index('#!', line1(1:1))==0) then
95 | do
96 | !
97 | read (Lu, 99004, end = 300) line2
98 | if (index('#!', line2(1:1))==0) then
99 | !
100 | i = 1
101 | !
102 | !---- try to read two numbers from first line
103 | na = 2
104 | call getflt(line1, a, na, error)
105 | if (error .or. na<2) then
106 | !------ must be a name string
107 | Name = line1
108 | else
109 | !------ no name, just two valid numbers... must be plain airfoil file
110 | Name = ' '
111 | if (Info>0) then
112 | if (show_output) then
113 | write (*, *)
114 | write (*, *) 'Plain airfoil file'
115 | endif
116 | endif
117 | Itype = 1
118 | rewind (Lu)
119 | goto 5
120 | endif
121 | !
122 | !---- if we got here, there's a name line,
123 | !- so now try to read four MSES domain numbers from second line
124 | na = 4
125 | call getflt(line2, a, na, error)
126 | !------ less than two valid numbers... not a valid format
127 | if (error .or. na<2) goto 300
128 | !
129 | if (na<4) then
130 | !------ less than four numbers... usual .dat labeled file
131 | Name = line1
132 | if (Info>0) then
133 | if (show_output) then
134 | write (*, *)
135 | write (*, *) 'Labeled airfoil file. Name: ', Name
136 | endif
137 | endif
138 | Itype = 2
139 | rewind (Lu)
140 | read (Lu, 99004, end = 300) line1
141 | !
142 | else
143 | !------ four or more numbers... MSES or MISES file
144 | if (Info>0) then
145 | if (show_output) then
146 | write (*, *)
147 | write (*, *) 'MSES airfoil file. Name: ', Name
148 | endif
149 | endif
150 | Itype = 3
151 | Ispars = line2
152 | endif
153 | 5 do
154 | !
155 | !---- read each element until 999.0 or end of file is encountered
156 | nel = nel + 1
157 | do i = 1, Nmax
158 | do
159 | read (Lu, 99004, end = 100) line
160 | !
161 | !------ skip comment line
162 | if (index('#!', line(1:1))==0) then
163 | !
164 | na = 2
165 | call getflt(line, a, na, error)
166 | if (error) goto 300
167 | !
168 | !------ skip line without at least two numbers
169 | if (na>=2) then
170 | !
171 | X(i) = a(1)
172 | Y(i) = a(2)
173 | !
174 | if (X(i)==999.0 .and. Y(i)==999.0) then
175 | !-------- if this is the element we want, just exit
176 | if (iel==nel) goto 100
177 | !
178 | if (iel==0) then
179 | call aski('Enter element number^', iel)
180 | Itype = 4
181 | endif
182 | !
183 | !-------- if this is the specified element, exit.
184 | if (iel==nel) goto 100
185 | goto 10
186 | endif
187 | exit
188 | endif
189 | endif
190 | enddo
191 | enddo
192 | if (show_output) write (*, 99001) Nmax
193 | 99001 format (/' Buffer array size exceeded'/' Maximum number of points: ', i4)
194 | if (show_output) write (*, 99005)
195 | if (lopen) close (Lu)
196 | Itype = 0
197 | return
198 | 10 enddo
199 | endif
200 | enddo
201 | endif
202 | enddo
203 | !
204 | 100 N = i - 1
205 | if (lopen) close (Lu)
206 | return
207 | !
208 | 200 nfn = index(Fname, ' ') + 1
209 | if (show_output) write (*, 99002) Fname(1:nfn)
210 | 99002 format (/' File OPEN error. Nonexistent file: ', a)
211 | if (show_output) write (*, 99005)
212 | Itype = 0
213 | return
214 | !
215 | 300 if (lopen) close (Lu)
216 | if (show_output) write (*, 99003)
217 | 99003 format (/' File READ error. Unrecognizable file format')
218 | if (show_output) write (*, 99005)
219 | Itype = 0
220 | return
221 | !...............................................................
222 | 99004 format (a)
223 | 99005 format (' *** LOAD NOT COMPLETED ***')
224 | end subroutine aread
225 |
226 | end module m_aread
--------------------------------------------------------------------------------
/src/fortran/m_naca.f90:
--------------------------------------------------------------------------------
1 | !***********************************************************************
2 | ! Copyright (c) 2019 D. de Vries
3 | ! Original Copyright (c) 2000 Mark Drela
4 | !
5 | ! This file is part of XFoil.
6 | !
7 | ! XFoil is free software: you can redistribute it and/or modify
8 | ! it under the terms of the GNU General Public License as published by
9 | ! the Free Software Foundation, either version 3 of the License, or
10 | ! (at your option) any later version.
11 | !
12 | ! XFoil is distributed in the hope that it will be useful,
13 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | ! GNU General Public License for more details.
16 | !
17 | ! You should have received a copy of the GNU General Public License
18 | ! along with XFoil. If not, see .
19 | !***********************************************************************
20 |
21 | !*==NACA4.f90 processed by SPAG 7.21DC at 11:25 on 11 Jan 2019
22 | ! POLREF
23 | module m_naca
24 | contains
25 | subroutine naca4(Ides, Xx, Yt, Yc, Nside, Xb, Yb, Nb, Name)
26 | implicit none
27 | !
28 | !*** Start of declarations rewritten by SPAG
29 | !
30 | ! Dummy arguments
31 | !
32 | integer :: Ides, Nb, Nside
33 | character(*) :: Name
34 | real, dimension(2 * Nside) :: Xb, Yb
35 | real, dimension(Nside) :: Xx, Yc, Yt
36 | intent (in) Ides, Nside
37 | intent (out) Name, Nb, Xb, Yb
38 | intent (inout) Xx, Yc, Yt
39 | !
40 | ! Local variables
41 | !
42 | real, save :: an
43 | real :: anp, frac, m, p, t
44 | character(10), save :: digits
45 | integer :: i, ib, n1, n2, n3, n4
46 | !
47 | !*** End of declarations rewritten by SPAG
48 | !
49 | !
50 | !*** Start of declarations rewritten by SPAG
51 | !
52 | ! Dummy arguments
53 | !
54 | !
55 | ! Local variables
56 | !
57 | !
58 | !*** End of declarations rewritten by SPAG
59 | !
60 | !
61 | data digits/'0123456789'/
62 | !
63 | !---- TE point bunching parameter
64 | data an/1.5/
65 | !
66 | n4 = Ides / 1000
67 | n3 = (Ides - n4 * 1000) / 100
68 | n2 = (Ides - n4 * 1000 - n3 * 100) / 10
69 | n1 = (Ides - n4 * 1000 - n3 * 100 - n2 * 10)
70 | !
71 | m = float(n4) / 100.0
72 | p = float(n3) / 10.0
73 | t = float(n2 * 10 + n1) / 100.0
74 | !
75 | anp = an + 1.0
76 | do i = 1, Nside
77 | frac = float(i - 1) / float(Nside - 1)
78 | if (i==Nside) then
79 | Xx(i) = 1.0
80 | else
81 | Xx(i) = 1.0 - anp * frac * (1.0 - frac)**an - (1.0 - frac)**anp
82 | endif
83 | Yt(i) = (0.29690 * sqrt(Xx(i)) - 0.12600 * Xx(i) &
84 | - 0.35160 * Xx(i)**2 + 0.28430 * Xx(i)**3 - 0.10150 * Xx(i)**4) * t / 0.20
85 | if (Xx(i)
.
19 | !***********************************************************************
20 |
21 | !*==HSORT.f90 processed by SPAG 7.21DC at 11:25 on 11 Jan 2019
22 | module m_sort
23 | contains
24 | subroutine hsort(N, A, Indx)
25 | implicit none
26 | !
27 | !*** Start of declarations rewritten by SPAG
28 | !
29 | ! Dummy arguments
30 | !
31 | integer :: N
32 | real, dimension(*) :: A
33 | integer, dimension(*) :: Indx
34 | intent (in) A, N
35 | intent (inout) Indx
36 | !
37 | ! Local variables
38 | !
39 | integer :: i, indxt, ir, j, l
40 | real :: q
41 | !
42 | !*** End of declarations rewritten by SPAG
43 | !
44 | !
45 | !*** Start of declarations rewritten by SPAG
46 | !
47 | ! Dummy arguments
48 | !
49 | !
50 | ! Local variables
51 | !
52 | !
53 | !*** End of declarations rewritten by SPAG
54 | !
55 | !--------------------------------------
56 | ! Heapsort algorithm.
57 | ! Returns INDX(.) such that
58 | !
59 | ! A(INDX(i)) < A(INDX(i+1))
60 | !
61 | ! Stolen from Numerical Recipes.
62 | !--------------------------------------
63 | !
64 | do i = 1, N
65 | Indx(i) = i
66 | enddo
67 | !
68 | if (N<=1) return
69 | !
70 | l = N / 2 + 1
71 | ir = N
72 | do
73 | !
74 | if (l>1) then
75 | l = l - 1
76 | indxt = Indx(l)
77 | q = A(indxt)
78 | else
79 | indxt = Indx(ir)
80 | q = A(indxt)
81 | Indx(ir) = Indx(1)
82 | !
83 | ir = ir - 1
84 | if (ir==1) then
85 | Indx(1) = indxt
86 | return
87 | endif
88 | endif
89 | !
90 | i = l
91 | j = l + l
92 | do
93 | !
94 | if (j<=ir) then
95 | if (jTol) then
202 | k = k + 1
203 | Indx(k) = i
204 | endif
205 | enddo
206 | !
207 | Nnew = k
208 | !
209 | end subroutine remd
210 | !*==SORTDUP.f90 processed by SPAG 7.21DC at 11:25 on 11 Jan 2019
211 | ! REMD
212 |
213 |
214 | subroutine sortdup(Kk, S, W)
215 | use i_xfoil, only: show_output
216 | implicit none
217 | !
218 | !*** Start of declarations rewritten by SPAG
219 | !
220 | ! Dummy arguments
221 | !
222 | integer :: Kk
223 | real, dimension(Kk) :: S, W
224 | intent (in) Kk
225 | intent (inout) S, W
226 | !
227 | ! Local variables
228 | !
229 | logical :: done
230 | integer :: ipass, n, np
231 | real :: temp
232 | !
233 | !*** End of declarations rewritten by SPAG
234 | !
235 | !
236 | !*** Start of declarations rewritten by SPAG
237 | !
238 | ! Dummy arguments
239 | !
240 | !
241 | ! Local variables
242 | !
243 | !
244 | !*** End of declarations rewritten by SPAG
245 | !
246 | !--- Sort arrays in S with no removal of duplicates
247 | !
248 | !---- sort arrays
249 | do ipass = 1, 1234
250 | done = .true.
251 | do n = 1, Kk - 1
252 | np = n + 1
253 | if (S(np)=Kk) return
404 | if (S(k)==S(k + 1)) then
405 | !------- eliminate pair
406 | Kk = Kk - 2
407 | do kt = k, Kk
408 | S(kt) = S(kt + 2)
409 | W(kt) = W(kt + 2)
410 | enddo
411 | endif
412 | enddo
413 | !
414 | end subroutine sort
415 | !*==SORTOL.f90 processed by SPAG 7.21DC at 11:25 on 11 Jan 2019
416 |
417 |
418 | subroutine sortol(Tol, Kk, S, W)
419 | use i_xfoil, only: show_output
420 | implicit none
421 | !
422 | !*** Start of declarations rewritten by SPAG
423 | !
424 | ! Dummy arguments
425 | !
426 | integer :: Kk
427 | real :: Tol
428 | real, dimension(Kk) :: S, W
429 | intent (in) Tol
430 | intent (inout) Kk, S, W
431 | !
432 | ! Local variables
433 | !
434 | logical :: done
435 | real :: dsq, temp
436 | integer :: ipass, k, kks, kt, n, np
437 | !
438 | !*** End of declarations rewritten by SPAG
439 | !
440 | !
441 | !*** Start of declarations rewritten by SPAG
442 | !
443 | ! Dummy arguments
444 | !
445 | !
446 | ! Local variables
447 | !
448 | !
449 | !*** End of declarations rewritten by SPAG
450 | !
451 | !
452 | !---- sort arrays
453 | do ipass = 1, 1234
454 | done = .true.
455 | do n = 1, Kk - 1
456 | np = n + 1
457 | if (S(np).
19 | !***********************************************************************
20 |
21 | !*==ABCOPY.f90 processed by SPAG 7.21DC at 11:25 on 11 Jan 2019
22 | ! INTX
23 | !
24 | module m_xgdes
25 | contains
26 | subroutine abcopy(Lconf)
27 | use s_xfoil, only: tecalc
28 | use m_xpanel, only: apcalc, ncalc
29 | use m_xgeom, only: lefind
30 | use m_spline, only: seval, segspl, scalc
31 | use i_xfoil
32 | implicit none
33 | !
34 | !*** Start of declarations rewritten by SPAG
35 | !
36 | ! Dummy arguments
37 | !
38 | logical :: Lconf
39 | intent (in) Lconf
40 | !
41 | ! Local variables
42 | !
43 | integer :: i, j
44 | !
45 | !*** End of declarations rewritten by SPAG
46 | !
47 | !
48 | !*** Start of declarations rewritten by SPAG
49 | !
50 | ! Dummy arguments
51 | !
52 | !
53 | ! Local variables
54 | !
55 | !
56 | !*** End of declarations rewritten by SPAG
57 | !
58 | !
59 | if (NB<=1) then
60 | if (show_output) write (*, *) 'ABCOPY: Buffer airfoil not available.'
61 | return
62 | elseif (NB>IQX - 5) then
63 | if (show_output) then
64 | write (*, *) 'Maximum number of panel nodes : ', IQX - 5
65 | write (*, *) 'Number of buffer airfoil points: ', NB
66 | write (*, *) 'Current airfoil cannot be set.'
67 | write (*, *) 'Try executing PANE at Top Level instead.'
68 | endif
69 | return
70 | endif
71 | if (N/=NB) LBLini = .false.
72 | !
73 | N = NB
74 | do i = 1, N
75 | X(i) = XB(i)
76 | Y(i) = YB(i)
77 | enddo
78 | LGSame = .true.
79 | !
80 | if (LBFlap) then
81 | XOF = XBF
82 | YOF = YBF
83 | LFLap = .true.
84 | endif
85 | !
86 | !---- strip out doubled points
87 | i = 1
88 | do
89 | i = i + 1
90 | if (X(i - 1)==X(i) .and. Y(i - 1)==Y(i)) then
91 | do j = i, N - 1
92 | X(j) = X(j + 1)
93 | Y(j) = Y(j + 1)
94 | enddo
95 | N = N - 1
96 | endif
97 | if (i>=N) then
98 | !
99 | call scalc(X, Y, S, N)
100 | call segspl(X, XP, S, N)
101 | call segspl(Y, YP, S, N)
102 |
103 | call ncalc(X, Y, S, N, NX, NY)
104 |
105 | call lefind(SLE, X, XP, Y, YP, S, N)
106 | XLE = seval(SLE, X, XP, S, N)
107 | YLE = seval(SLE, Y, YP, S, N)
108 | XTE = 0.5 * (X(1) + X(N))
109 | YTE = 0.5 * (Y(1) + Y(N))
110 | CHOrd = sqrt((XTE - XLE)**2 + (YTE - YLE)**2)
111 |
112 | call tecalc
113 | call apcalc
114 | !
115 | LGAmu = .false.
116 | LQInu = .false.
117 | LWAke = .false.
118 | LQAij = .false.
119 | LADij = .false.
120 | LWDij = .false.
121 | LIPan = .false.
122 | LVConv = .false.
123 | LSCini = .false.
124 | !CC LBLINI = .FALSE.
125 | !
126 | if (Lconf .and. show_output) write (*, 99001) N
127 | 99001 format (/' Current airfoil nodes set from buffer airfoil nodes (', i4, ' )')
128 | exit
129 | endif
130 | enddo
131 | !
132 | end subroutine abcopy
133 | !*==GETXYF.f90 processed by SPAG 7.21DC at 11:25 on 11 Jan 2019
134 | ! ABCOPY
135 |
136 |
137 | subroutine getxyf(X, Xp, Y, Yp, S, N, Tops, Bots, Xf, Yf)
138 | use i_xfoil, only: show_output
139 | use m_userio, only: askr
140 | use m_spline, only: seval, sinvrt
141 | implicit none
142 | !
143 | !*** Start of declarations rewritten by SPAG
144 | !
145 | ! Dummy arguments
146 | !
147 | real :: Bots, Tops, Xf, Yf
148 | integer :: N
149 | real, dimension(N) :: S, X, Xp, Y, Yp
150 | intent (in) Y, Yp
151 | intent (inout) Bots, Tops, Yf
152 | !
153 | ! Local variables
154 | !
155 | real :: boty, topy, yrel
156 | !
157 | !*** End of declarations rewritten by SPAG
158 | !
159 | !
160 | !*** Start of declarations rewritten by SPAG
161 | !
162 | ! Dummy arguments
163 | !
164 | !
165 | ! Local variables
166 | !
167 | !
168 | !*** End of declarations rewritten by SPAG
169 | !
170 | !
171 | if (Xf==-999.0) call askr('Enter flap hinge x location^', Xf)
172 | !
173 | !---- find top and bottom y at hinge x location
174 | Tops = S(1) + (X(1) - Xf)
175 | Bots = S(N) - (X(N) - Xf)
176 | call sinvrt(Tops, Xf, X, Xp, S, N)
177 | call sinvrt(Bots, Xf, X, Xp, S, N)
178 | topy = seval(Tops, Y, Yp, S, N)
179 | boty = seval(Bots, Y, Yp, S, N)
180 | !
181 | if (show_output) write (*, 99001) topy, boty
182 | 99001 format (/' Top surface: y =', f8.4, ' y/t = 1.0'/' Bottom surface: y =', f8.4, ' y/t = 0.0')
183 | !
184 | if (Yf==-999.0) call askr('Enter flap hinge y location (or 999 to specify y/t)^', Yf)
185 | !
186 | if (Yf==999.0) then
187 | call askr('Enter flap hinge relative y/t location^', yrel)
188 | Yf = topy * yrel + boty * (1.0 - yrel)
189 | endif
190 | !
191 | end subroutine getxyf
192 |
193 | end module m_xgdes
--------------------------------------------------------------------------------
/src/fortran/m_xutils.f90:
--------------------------------------------------------------------------------
1 | !***********************************************************************
2 | ! Copyright (c) 2019 D. de Vries
3 | ! Original Copyright (c) 2000 Mark Drela
4 | !
5 | ! This file is part of XFoil.
6 | !
7 | ! XFoil is free software: you can redistribute it and/or modify
8 | ! it under the terms of the GNU General Public License as published by
9 | ! the Free Software Foundation, either version 3 of the License, or
10 | ! (at your option) any later version.
11 | !
12 | ! XFoil is distributed in the hope that it will be useful,
13 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | ! GNU General Public License for more details.
16 | !
17 | ! You should have received a copy of the GNU General Public License
18 | ! along with XFoil. If not, see .
19 | !***********************************************************************
20 |
21 | !*==M_XUTILS.f90 processed by SPAG 7.21DC at 11:25 on 11 Jan 2019
22 | module m_xutils
23 | implicit none
24 | !
25 | !*** Start of declarations rewritten by SPAG
26 | !
27 | !*** End of declarations rewritten by SPAG
28 | !
29 | !
30 | !*** Start of declarations rewritten by SPAG
31 | !
32 | !*** End of declarations rewritten by SPAG
33 | !
34 | contains
35 | subroutine setexp(S, Ds1, Smax, Nn)
36 | use i_xfoil, only: show_output
37 | implicit none
38 | !
39 | !*** Start of declarations rewritten by SPAG
40 | !
41 | ! Dummy arguments
42 | !
43 | real :: Ds1, Smax
44 | integer :: Nn
45 | real, dimension(Nn) :: S
46 | intent (in) Ds1, Nn, Smax
47 | intent (inout) S
48 | !
49 | ! Local variables
50 | !
51 | real :: aaa, bbb, ccc, disc, dratio, dresdr, ds, ratio, res, rnex, rni, sigma, sigman
52 | integer :: iter, n, nex
53 | !
54 | !*** End of declarations rewritten by SPAG
55 | !
56 | !
57 | !*** Start of declarations rewritten by SPAG
58 | !
59 | ! Dummy arguments
60 | !
61 | !
62 | ! Local variables
63 | !
64 | !
65 | !*** End of declarations rewritten by SPAG
66 | !
67 | !........................................................
68 | ! Sets geometrically stretched array S:
69 | !
70 | ! S(i+1) - S(i) = r * [S(i) - S(i-1)]
71 | !
72 | ! S (output) array to be set
73 | ! DS1 (input) first S increment: S(2) - S(1)
74 | ! SMAX (input) final S value: S(NN)
75 | ! NN (input) number of points
76 | !........................................................
77 | !
78 | sigma = Smax / Ds1
79 | nex = Nn - 1
80 | rnex = float(nex)
81 | rni = 1.0 / rnex
82 | !
83 | !---- solve quadratic for initial geometric ratio guess
84 | aaa = rnex * (rnex - 1.0) * (rnex - 2.0) / 6.0
85 | bbb = rnex * (rnex - 1.0) / 2.0
86 | ccc = rnex - sigma
87 | !
88 | disc = bbb**2 - 4.0 * aaa * ccc
89 | disc = max(0.0, disc)
90 | !
91 | if (nex<=1) then
92 | stop 'SETEXP: Cannot fill array. N too small.'
93 | elseif (nex==2) then
94 | ratio = -ccc / bbb + 1.0
95 | else
96 | ratio = (-bbb + sqrt(disc)) / (2.0 * aaa) + 1.0
97 | endif
98 | !
99 | if (ratio/=1.0) then
100 | !
101 | !---- Newton iteration for actual geometric ratio
102 | do iter = 1, 100
103 | sigman = (ratio**nex - 1.0) / (ratio - 1.0)
104 | res = sigman**rni - sigma**rni
105 | dresdr = rni * sigman**rni * (rnex * ratio**(nex - 1) - sigman) / (ratio**nex - 1.0)
106 | !
107 | dratio = -res / dresdr
108 | ratio = ratio + dratio
109 | !
110 | if (abs(dratio)<1.0E-5) goto 100
111 | !
112 | enddo
113 | if (show_output) write (*, *) 'SETEXP: Convergence failed. Continuing anyway ...'
114 | endif
115 | !
116 | !---- set up stretched array using converged geometric ratio
117 | 100 S(1) = 0.0
118 | ds = Ds1
119 | do n = 2, Nn
120 | S(n) = S(n - 1) + ds
121 | ds = ds * ratio
122 | enddo
123 | !
124 | end subroutine setexp
125 |
126 |
127 | function atanc(Y, X, Thold)
128 | implicit none
129 | !
130 | !*** Start of declarations rewritten by SPAG
131 | !
132 | ! Dummy arguments
133 | !
134 | real :: Thold, X, Y
135 | real :: atanc
136 | intent (in) Thold, X, Y
137 | !
138 | ! Local variables
139 | !
140 | real :: dtcorr, dthet, thnew
141 | real, save :: pi, tpi
142 | !
143 | !*** End of declarations rewritten by SPAG
144 | !
145 | !
146 | !*** Start of declarations rewritten by SPAG
147 | !
148 | ! Dummy arguments
149 | !
150 | !
151 | ! Local variables
152 | !
153 | !
154 | !*** End of declarations rewritten by SPAG
155 | !
156 | !---------------------------------------------------------------
157 | ! ATAN2 function with branch cut checking.
158 | !
159 | ! Increments position angle of point X,Y from some previous
160 | ! value THOLD due to a change in position, ensuring that the
161 | ! position change does not cross the ATAN2 branch cut
162 | ! (which is in the -x direction). For example:
163 | !
164 | ! ATANC( -1.0 , -1.0 , 0.75*pi ) returns 1.25*pi , whereas
165 | ! ATAN2( -1.0 , -1.0 ) returns -.75*pi .
166 | !
167 | ! Typically, ATANC is used to fill an array of angles:
168 | !
169 | ! THETA(1) = ATAN2( Y(1) , X(1) )
170 | ! DO i=2, N
171 | ! THETA(i) = ATANC( Y(i) , X(i) , THETA(i-1) )
172 | ! END DO
173 | !
174 | ! This will prevent the angle array THETA(i) from jumping by
175 | ! +/- 2 pi when the path X(i),Y(i) crosses the negative x axis.
176 | !
177 | ! Input:
178 | ! X,Y point position coordinates
179 | ! THOLD position angle of nearby point
180 | !
181 | ! Output:
182 | ! ATANC position angle of X,Y
183 | !---------------------------------------------------------------
184 | data pi/3.1415926535897932384/
185 | data tpi/6.2831853071795864769/
186 | !
187 | !---- set new position angle, ignoring branch cut in ATAN2 function for now
188 | thnew = atan2(Y, X)
189 | dthet = thnew - Thold
190 | !
191 | !---- angle change cannot exceed +/- pi, so get rid of any multiples of 2 pi
192 | dtcorr = dthet - tpi * int((dthet + sign(pi, dthet)) / tpi)
193 | !
194 | !---- set correct new angle
195 | atanc = Thold + dtcorr
196 | !
197 | end function atanc
198 | ! ATANC
199 | end module m_xutils
200 |
--------------------------------------------------------------------------------
/src/fortran/p_xfoil.f90:
--------------------------------------------------------------------------------
1 | !***********************************************************************
2 | ! Copyright (c) 2019 D. de Vries
3 | !
4 | ! This file is part of XFoil.
5 | !
6 | ! XFoil is free software: you can redistribute it and/or modify
7 | ! it under the terms of the GNU General Public License as published by
8 | ! the Free Software Foundation, either version 3 of the License, or
9 | ! (at your option) any later version.
10 | !
11 | ! XFoil is distributed in the hope that it will be useful,
12 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | ! GNU General Public License for more details.
15 | !
16 | ! You should have received a copy of the GNU General Public License
17 | ! along with XFoil. If not, see .
18 | !***********************************************************************
19 | !
20 | program p_xfoil
21 | use m_xfoil, only: xfoil
22 | call xfoil
23 | end program p_xfoil
24 |
--------------------------------------------------------------------------------
/src/fortran/s_xbl.f90:
--------------------------------------------------------------------------------
1 | !***********************************************************************
2 | ! Copyright (c) 2019 D. de Vries
3 | ! Original Copyright (c) 2000 Mark Drela
4 | !
5 | ! This file is part of XFoil.
6 | !
7 | ! XFoil is free software: you can redistribute it and/or modify
8 | ! it under the terms of the GNU General Public License as published by
9 | ! the Free Software Foundation, either version 3 of the License, or
10 | ! (at your option) any later version.
11 | !
12 | ! XFoil is distributed in the hope that it will be useful,
13 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | ! GNU General Public License for more details.
16 | !
17 | ! You should have received a copy of the GNU General Public License
18 | ! along with XFoil. If not, see .
19 | !***********************************************************************
20 |
21 | module s_xbl
22 | contains
23 | ! iblsys was originally in xbl between setbl and mrchue.
24 | ! It was moved here to avoid a circular use dependency.
25 | subroutine iblsys
26 | use i_xfoil
27 | use i_xbl
28 | implicit none
29 | !
30 | !*** Start of declarations rewritten by SPAG
31 | !
32 | ! Local variables
33 | !
34 | integer :: ibl, is, iv
35 | !
36 | !*** End of declarations rewritten by SPAG
37 | !
38 | !
39 | !*** Start of declarations rewritten by SPAG
40 | !
41 | ! Local variables
42 | !
43 | !
44 | !*** End of declarations rewritten by SPAG
45 | !
46 | !---------------------------------------------
47 | ! Sets the BL Newton system line number
48 | ! corresponding to each BL station.
49 | !---------------------------------------------
50 | iv = 0
51 | do is = 1, 2
52 | do ibl = 2, NBL(is)
53 | iv = iv + 1
54 | ISYs(ibl, is) = iv
55 | enddo
56 | enddo
57 | !
58 | NSYs = iv
59 | if (NSYs>2 * IVX) stop '*** IBLSYS: BL system array overflow. ***'
60 | !
61 | end subroutine iblsys
62 | !*==MRCHUE.f90 processed by SPAG 7.21DC at 11:25 on 11 Jan 2019
63 | end module s_xbl
--------------------------------------------------------------------------------
/src/fortran/s_xfoil.f90:
--------------------------------------------------------------------------------
1 | !***********************************************************************
2 | ! Copyright (c) 2019 D. de Vries
3 | ! Original Copyright (c) 2000 Mark Drela
4 | !
5 | ! This file is part of XFoil.
6 | !
7 | ! XFoil is free software: you can redistribute it and/or modify
8 | ! it under the terms of the GNU General Public License as published by
9 | ! the Free Software Foundation, either version 3 of the License, or
10 | ! (at your option) any later version.
11 | !
12 | ! XFoil is distributed in the hope that it will be useful,
13 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | ! GNU General Public License for more details.
16 | !
17 | ! You should have received a copy of the GNU General Public License
18 | ! along with XFoil. If not, see .
19 | !***********************************************************************
20 |
21 | module s_xfoil
22 | contains
23 | subroutine mrcl(Cls, M_cls, R_cls)
24 | use i_xfoil
25 | implicit none
26 | !
27 | !*** Start of declarations rewritten by SPAG
28 | !
29 | ! Dummy arguments
30 | !
31 | real :: Cls, M_cls, R_cls
32 | intent (in) Cls
33 | intent (out) M_cls, R_cls
34 | !
35 | ! Local variables
36 | !
37 | real :: cla, rrat
38 | !
39 | !*** End of declarations rewritten by SPAG
40 | !
41 | !
42 | !*** Start of declarations rewritten by SPAG
43 | !
44 | ! Dummy arguments
45 | !
46 | !
47 | ! Local variables
48 | !
49 | !
50 | !*** End of declarations rewritten by SPAG
51 | !
52 | !-------------------------------------------
53 | ! Sets actual Mach, Reynolds numbers
54 | ! from unit-CL values and specified CLS
55 | ! depending on MATYP,RETYP flags.
56 | !-------------------------------------------
57 | !
58 | cla = max(Cls, 0.000001)
59 | !
60 | if (RETyp<1 .or. RETyp>3) then
61 | if (show_output) then
62 | write (*, *) 'MRCL: Illegal Re(CL) dependence trigger.'
63 | write (*, *) ' Setting fixed Re.'
64 | endif
65 | RETyp = 1
66 | endif
67 | if (MATyp<1 .or. MATyp>3) then
68 | if (show_output) then
69 | write (*, *) 'MRCL: Illegal Mach(CL) dependence trigger.'
70 | write (*, *) ' Setting fixed Mach.'
71 | endif
72 | MATyp = 1
73 | endif
74 | !
75 | !
76 | if (MATyp==1) then
77 | !
78 | MINf = MINf1
79 | M_cls = 0.
80 | !
81 | elseif (MATyp==2) then
82 | !
83 | MINf = MINf1 / sqrt(cla)
84 | M_cls = -0.5 * MINf / cla
85 | !
86 | elseif (MATyp==3) then
87 | !
88 | MINf = MINf1
89 | M_cls = 0.
90 | !
91 | endif
92 | !
93 | !
94 | if (RETyp==1) then
95 | !
96 | REInf = REInf1
97 | R_cls = 0.
98 | !
99 | elseif (RETyp==2) then
100 | !
101 | REInf = REInf1 / sqrt(cla)
102 | R_cls = -0.5 * REInf / cla
103 | !
104 | elseif (RETyp==3) then
105 | !
106 | REInf = REInf1 / cla
107 | R_cls = -REInf / cla
108 | !
109 | endif
110 | !
111 | !
112 | if (MINf>=0.99) then
113 | if (show_output) then
114 | write (*, *)
115 | write (*, *) 'MRCL: CL too low for chosen Mach(CL) dependence'
116 | write (*, *) ' Aritificially limiting Mach to 0.99'
117 | endif
118 | MINf = 0.99
119 | M_cls = 0.
120 | endif
121 | !
122 | rrat = 1.0
123 | if (REInf1>0.0) rrat = REInf / REInf1
124 | !
125 | if (rrat>100.0) then
126 | if (show_output) then
127 | write (*, *)
128 | write (*, *) 'MRCL: CL too low for chosen Re(CL) dependence'
129 | write (*, *) ' Aritificially limiting Re to ', REInf1 * 100.0
130 | endif
131 | REInf = REInf1 * 100.0
132 | R_cls = 0.
133 | endif
134 | !
135 | end subroutine mrcl
136 | !*==GETDEF.f90 processed by SPAG 7.21DC at 11:25 on 11 Jan 2019
137 | ! MRCL
138 |
139 |
140 | subroutine comset
141 | use i_xfoil
142 | implicit none
143 | !
144 | !*** Start of declarations rewritten by SPAG
145 | !
146 | ! Local variables
147 | !
148 | real :: beta, beta_msq
149 | !
150 | !*** End of declarations rewritten by SPAG
151 | !
152 | !
153 | !*** Start of declarations rewritten by SPAG
154 | !
155 | ! Local variables
156 | !
157 | !
158 | !*** End of declarations rewritten by SPAG
159 | !
160 | !
161 | !---- set Karman-Tsien parameter TKLAM
162 | beta = sqrt(1.0 - MINf**2)
163 | beta_msq = -0.5 / beta
164 | !
165 | TKLam = MINf**2 / (1.0 + beta)**2
166 | TKL_msq = 1.0 / (1.0 + beta)**2 - 2.0 * TKLam / (1.0 + beta) * beta_msq
167 | !
168 | !---- set sonic Pressure coefficient and speed
169 | if (MINf==0.0) then
170 | CPStar = -999.0
171 | QSTar = 999.0
172 | else
173 | CPStar = 2.0 / (GAMma * MINf**2) &
174 | * (((1.0 + 0.5 * GAMm1 * MINf**2) / (1.0 + 0.5 * GAMm1))**(GAMma / GAMm1) - 1.0)
175 | QSTar = QINf / MINf * sqrt((1.0 + 0.5 * GAMm1 * MINf**2) / (1.0 + 0.5 * GAMm1))
176 | endif
177 | !
178 | end subroutine comset
179 | !*==CPCALC.f90 processed by SPAG 7.21DC at 11:25 on 11 Jan 2019
180 | ! COMSET
181 |
182 | subroutine cpcalc(N, Q, Qinf, Minf, Cp)
183 | use i_xfoil, only: show_output
184 | implicit none
185 | !
186 | !*** Start of declarations rewritten by SPAG
187 | !
188 | ! Dummy arguments
189 | !
190 | real :: Minf, Qinf
191 | integer :: N
192 | real, dimension(N) :: Cp, Q
193 | intent (in) Minf, N, Q, Qinf
194 | intent (out) Cp
195 | !
196 | ! Local variables
197 | !
198 | real :: beta, bfac, cpinc, den
199 | logical :: denneg
200 | integer :: i
201 | !
202 | !*** End of declarations rewritten by SPAG
203 | !
204 | !
205 | !*** Start of declarations rewritten by SPAG
206 | !
207 | ! Dummy arguments
208 | !
209 | !
210 | ! Local variables
211 | !
212 | !
213 | !*** End of declarations rewritten by SPAG
214 | !
215 | !---------------------------------------------
216 | ! Sets compressible Cp from speed.
217 | !---------------------------------------------
218 | !
219 | !
220 | beta = sqrt(1.0 - Minf**2)
221 | bfac = 0.5 * Minf**2 / (1.0 + beta)
222 | !
223 | denneg = .false.
224 | !
225 | do i = 1, N
226 | cpinc = 1.0 - (Q(i) / Qinf)**2
227 | den = beta + bfac * cpinc
228 | Cp(i) = cpinc / den
229 | if (den<=0.0) denneg = .true.
230 | enddo
231 | !
232 | if (denneg) then
233 | if (show_output) then
234 | write (*, *)
235 | write (*, *) 'CPCALC: Local speed too large. ', 'Compressibility corrections invalid.'
236 | endif
237 | endif
238 | !
239 | end subroutine cpcalc
240 | !*==CLCALC.f90 processed by SPAG 7.21DC at 11:25 on 11 Jan 2019
241 | ! CPCALC
242 |
243 |
244 | subroutine clcalc(N, X, Y, Gam, Gam_a, Alfa, Minf, Qinf, Xref, Yref, Cl, Cm, Cdp, Cl_alf, Cl_msq)
245 | implicit none
246 | !
247 | !*** Start of declarations rewritten by SPAG
248 | !
249 | ! Dummy arguments
250 | !
251 | real :: Alfa, Cdp, Cl, Cl_alf, Cl_msq, Cm, Minf, Qinf, Xref, Yref
252 | integer :: N
253 | real, dimension(N) :: Gam, Gam_a, X, Y
254 | intent (in) Alfa, Gam, Gam_a, Minf, N, Qinf, X, Xref, Y, Yref
255 | intent (inout) Cdp, Cl, Cl_alf, Cl_msq, Cm
256 | !
257 | ! Local variables
258 | !
259 | real :: ag, ag_alf, ag_msq, ax, ay, beta, beta_msq, bfac, bfac_msq, ca, cginc, cpc_cpi, cpg1, cpg1_alf, &
260 | & cpg1_msq, cpg2, cpg2_alf, cpg2_msq, cpi_gam, dg, dx, dx_alf, dy, sa
261 | integer :: i, ip
262 | !
263 | !*** End of declarations rewritten by SPAG
264 | !
265 | !
266 | !*** Start of declarations rewritten by SPAG
267 | !
268 | ! Dummy arguments
269 | !
270 | !
271 | ! Local variables
272 | !
273 | !
274 | !*** End of declarations rewritten by SPAG
275 | !
276 | !-----------------------------------------------------------
277 | ! Integrates surface pressures to get CL and CM.
278 | ! Integrates skin friction to get CDF.
279 | ! Calculates dCL/dAlpha for prescribed-CL routines.
280 | !-----------------------------------------------------------
281 | !
282 | !cC---- moment-reference coordinates
283 | !c XREF = 0.25
284 | !c YREF = 0.
285 | !
286 | sa = sin(Alfa)
287 | ca = cos(Alfa)
288 | !
289 | beta = sqrt(1.0 - Minf**2)
290 | beta_msq = -0.5 / beta
291 | !
292 | bfac = 0.5 * Minf**2 / (1.0 + beta)
293 | bfac_msq = 0.5 / (1.0 + beta) - bfac / (1.0 + beta) * beta_msq
294 | !
295 | Cl = 0.0
296 | Cm = 0.0
297 |
298 | Cdp = 0.0
299 | !
300 | Cl_alf = 0.
301 | Cl_msq = 0.
302 | !
303 | i = 1
304 | cginc = 1.0 - (Gam(i) / Qinf)**2
305 | cpg1 = cginc / (beta + bfac * cginc)
306 | cpg1_msq = -cpg1 / (beta + bfac * cginc) * (beta_msq + bfac_msq * cginc)
307 | !
308 | cpi_gam = -2.0 * Gam(i) / Qinf**2
309 | cpc_cpi = (1.0 - bfac * cpg1) / (beta + bfac * cginc)
310 | cpg1_alf = cpc_cpi * cpi_gam * Gam_a(i)
311 | !
312 | do i = 1, N
313 | ip = i + 1
314 | if (i==N) ip = 1
315 | !
316 | cginc = 1.0 - (Gam(ip) / Qinf)**2
317 | cpg2 = cginc / (beta + bfac * cginc)
318 | cpg2_msq = -cpg2 / (beta + bfac * cginc) * (beta_msq + bfac_msq * cginc)
319 | !
320 | cpi_gam = -2.0 * Gam(ip) / Qinf**2
321 | cpc_cpi = (1.0 - bfac * cpg2) / (beta + bfac * cginc)
322 | cpg2_alf = cpc_cpi * cpi_gam * Gam_a(ip)
323 | !
324 | dx = (X(ip) - X(i)) * ca + (Y(ip) - Y(i)) * sa
325 | dy = (Y(ip) - Y(i)) * ca - (X(ip) - X(i)) * sa
326 | dg = cpg2 - cpg1
327 | !
328 | ax = (0.5 * (X(ip) + X(i)) - Xref) * ca + (0.5 * (Y(ip) + Y(i)) - Yref) * sa
329 | ay = (0.5 * (Y(ip) + Y(i)) - Yref) * ca - (0.5 * (X(ip) + X(i)) - Xref) * sa
330 | ag = 0.5 * (cpg2 + cpg1)
331 | !
332 | dx_alf = -(X(ip) - X(i)) * sa + (Y(ip) - Y(i)) * ca
333 | ag_alf = 0.5 * (cpg2_alf + cpg1_alf)
334 | ag_msq = 0.5 * (cpg2_msq + cpg1_msq)
335 | !
336 | Cl = Cl + dx * ag
337 | Cdp = Cdp - dy * ag
338 | Cm = Cm - dx * (ag * ax + dg * dx / 12.0) - dy * (ag * ay + dg * dy / 12.0)
339 | !
340 | Cl_alf = Cl_alf + dx * ag_alf + ag * dx_alf
341 | Cl_msq = Cl_msq + dx * ag_msq
342 | !
343 | cpg1 = cpg2
344 | cpg1_alf = cpg2_alf
345 | cpg1_msq = cpg2_msq
346 | enddo
347 | !
348 | end subroutine clcalc
349 | !*==CDCALC.f90 processed by SPAG 7.21DC at 11:25 on 11 Jan 2019
350 | ! CLCALC
351 |
352 |
353 | subroutine cdcalc
354 | use i_xfoil
355 | implicit none
356 | !
357 | !*** Start of declarations rewritten by SPAG
358 | !
359 | ! Local variables
360 | !
361 | real :: ca, dx, sa, shwake, thwake, uewake, urat
362 | integer :: i, ibl, im, is
363 | !
364 | !*** End of declarations rewritten by SPAG
365 | !
366 | !
367 | !*** Start of declarations rewritten by SPAG
368 | !
369 | ! Local variables
370 | !
371 | !
372 | !*** End of declarations rewritten by SPAG
373 | !
374 | !
375 | sa = sin(ALFa)
376 | ca = cos(ALFa)
377 | !
378 | if (LVIsc .and. LBLini) then
379 | !
380 | !----- set variables at the end of the wake
381 | thwake = THEt(NBL(2), 2)
382 | urat = UEDg(NBL(2), 2) / QINf
383 | uewake = UEDg(NBL(2), 2) * (1.0 - TKLam) / (1.0 - TKLam * urat**2)
384 | shwake = DSTr(NBL(2), 2) / THEt(NBL(2), 2)
385 | !
386 | !----- extrapolate wake to downstream infinity using Squire-Young relation
387 | ! (reduces errors of the wake not being long enough)
388 | CD = 2.0 * thwake * (uewake / QINf)**(0.5 * (5.0 + shwake))
389 | !
390 | else
391 | !
392 | CD = 0.0
393 | !
394 | endif
395 | !
396 | !---- calculate friction drag coefficient
397 | CDF = 0.0
398 | do is = 1, 2
399 | do ibl = 3, IBLte(is)
400 | i = IPAn(ibl, is)
401 | im = IPAn(ibl - 1, is)
402 | dx = (X(i) - X(im)) * ca + (Y(i) - Y(im)) * sa
403 | CDF = CDF + 0.5 * (TAU(ibl, is) + TAU(ibl - 1, is)) * dx * 2.0 / QINf**2
404 | enddo
405 | enddo
406 | !
407 | end subroutine cdcalc
408 | !*==LOAD.f90 processed by SPAG 7.21DC at 11:25 on 11 Jan 2019
409 | ! CDCALC
410 |
411 |
412 | subroutine tecalc
413 | use i_xfoil
414 | implicit none
415 | !
416 | !*** Start of declarations rewritten by SPAG
417 | !
418 | ! Local variables
419 | !
420 | real :: dxs, dxte, dys, dyte, scs, sds
421 | !
422 | !*** End of declarations rewritten by SPAG
423 | !
424 | !
425 | !*** Start of declarations rewritten by SPAG
426 | !
427 | ! Local variables
428 | !
429 | !
430 | !*** End of declarations rewritten by SPAG
431 | !
432 | !-------------------------------------------
433 | ! Calculates total and projected TE gap
434 | ! areas and TE panel strengths.
435 | !-------------------------------------------
436 | !
437 | !---- set TE base vector and TE bisector components
438 | dxte = X(1) - X(N)
439 | dyte = Y(1) - Y(N)
440 | dxs = 0.5 * (-XP(1) + XP(N))
441 | dys = 0.5 * (-YP(1) + YP(N))
442 | !
443 | !---- normal and streamwise projected TE gap areas
444 | ANTe = dxs * dyte - dys * dxte
445 | ASTe = dxs * dxte + dys * dyte
446 | !
447 | !---- total TE gap area
448 | DSTe = sqrt(dxte**2 + dyte**2)
449 | !
450 | SHArp = DSTe<0.0001 * CHOrd
451 | !
452 | if (SHArp) then
453 | scs = 1.0
454 | sds = 0.0
455 | else
456 | scs = ANTe / DSTe
457 | sds = ASTe / DSTe
458 | endif
459 | !
460 | !---- TE panel source and vorticity strengths
461 | SIGte = 0.5 * (GAM(1) - GAM(N)) * scs
462 | GAMte = -.5 * (GAM(1) - GAM(N)) * sds
463 | !
464 | SIGte_a = 0.5 * (GAM_a(1) - GAM_a(N)) * scs
465 | GAMte_a = -.5 * (GAM_a(1) - GAM_a(N)) * sds
466 | !
467 | end subroutine tecalc
468 | !*==INTE.f90 processed by SPAG 7.21DC at 11:25 on 11 Jan 2019
469 | ! TECALC
470 |
471 | end module s_xfoil
--------------------------------------------------------------------------------
/src/fortran/s_xoper.f90:
--------------------------------------------------------------------------------
1 | !***********************************************************************
2 | ! Copyright (c) 2019 D. de Vries
3 | ! Original Copyright (c) 2000 Mark Drela
4 | !
5 | ! This file is part of XFoil.
6 | !
7 | ! XFoil is free software: you can redistribute it and/or modify
8 | ! it under the terms of the GNU General Public License as published by
9 | ! the Free Software Foundation, either version 3 of the License, or
10 | ! (at your option) any later version.
11 | !
12 | ! XFoil is distributed in the hope that it will be useful,
13 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | ! GNU General Public License for more details.
16 | !
17 | ! You should have received a copy of the GNU General Public License
18 | ! along with XFoil. If not, see .
19 | !***********************************************************************
20 |
21 | module s_xoper
22 | contains
23 | ! mhinge was originally in xoper between cpdump and vpar
24 | ! It was moved here to avoid a circular dependency.
25 | subroutine mhinge
26 | use m_xgdes, only : getxyf
27 | use m_spline, only : seval, sinvrt
28 | use i_xfoil
29 | implicit none
30 | !
31 | !*** Start of declarations rewritten by SPAG
32 | !
33 | ! Local variables
34 | !
35 | real :: botp, bots, botx, boty, dx, dy, frac, pmid, topp, tops, topx, topy, xmid, ymid
36 | integer :: i
37 | !
38 | !*** End of declarations rewritten by SPAG
39 | !
40 | !
41 | !*** Start of declarations rewritten by SPAG
42 | !
43 | ! Local variables
44 | !
45 | !
46 | !*** End of declarations rewritten by SPAG
47 | !
48 | !----------------------------------------------------
49 | ! Calculates the hinge moment of the flap about
50 | ! (XOF,YOF) by integrating surface pressures.
51 | !----------------------------------------------------
52 | !
53 | if (.not.LFLap) then
54 | !
55 | call getxyf(X, XP, Y, YP, S, N, tops, bots, XOF, YOF)
56 | LFLap = .true.
57 | !
58 | else
59 | !
60 | !------ find top and bottom y at hinge x location
61 | tops = XOF
62 | bots = S(N) - XOF
63 | call sinvrt(tops, XOF, X, XP, S, N)
64 | call sinvrt(bots, XOF, X, XP, S, N)
65 | !
66 | endif
67 | !
68 | topx = seval(tops, X, XP, S, N)
69 | topy = seval(tops, Y, YP, S, N)
70 | botx = seval(bots, X, XP, S, N)
71 | boty = seval(bots, Y, YP, S, N)
72 | !
73 | !
74 | HMOm = 0.
75 | HFX = 0.
76 | HFY = 0.
77 | !
78 | !---- integrate pressures on top and bottom sides of flap
79 | do i = 2, N
80 | if (S(i - 1)bots) then
81 | !
82 | dx = X(i) - X(i - 1)
83 | dy = Y(i) - Y(i - 1)
84 | xmid = 0.5 * (X(i) + X(i - 1)) - XOF
85 | ymid = 0.5 * (Y(i) + Y(i - 1)) - YOF
86 | if (LVIsc) then
87 | pmid = 0.5 * (CPV(i) + CPV(i - 1))
88 | else
89 | pmid = 0.5 * (CPI(i) + CPI(i - 1))
90 | endif
91 | HMOm = HMOm + pmid * (xmid * dx + ymid * dy)
92 | HFX = HFX - pmid * dy
93 | HFY = HFY + pmid * dx
94 | endif
95 | enddo
96 | !
97 | !---- find S(I)..S(I-1) interval containing s=TOPS
98 | do i = 2, N
99 | if (S(i)>tops) exit
100 | enddo
101 | !
102 | !---- add on top surface chunk TOPS..S(I-1), missed in the DO 20 loop.
103 | dx = topx - X(i - 1)
104 | dy = topy - Y(i - 1)
105 | xmid = 0.5 * (topx + X(i - 1)) - XOF
106 | ymid = 0.5 * (topy + Y(i - 1)) - YOF
107 | if (S(i)/=S(i - 1)) then
108 | frac = (tops - S(i - 1)) / (S(i) - S(i - 1))
109 | else
110 | frac = 0.
111 | endif
112 | if (LVIsc) then
113 | topp = CPV(i) * frac + CPV(i - 1) * (1.0 - frac)
114 | pmid = 0.5 * (topp + CPV(i - 1))
115 | else
116 | topp = CPI(i) * frac + CPI(i - 1) * (1.0 - frac)
117 | pmid = 0.5 * (topp + CPI(i - 1))
118 | endif
119 | HMOm = HMOm + pmid * (xmid * dx + ymid * dy)
120 | HFX = HFX - pmid * dy
121 | HFY = HFY + pmid * dx
122 | !
123 | !---- add on inside flap surface contribution from hinge to top surface
124 | dx = XOF - topx
125 | dy = YOF - topy
126 | xmid = 0.5 * (topx + XOF) - XOF
127 | ymid = 0.5 * (topy + YOF) - YOF
128 | HMOm = HMOm + pmid * (xmid * dx + ymid * dy)
129 | HFX = HFX - pmid * dy
130 | HFY = HFY + pmid * dx
131 | !
132 | !---- find S(I)..S(I-1) interval containing s=BOTS
133 | do i = N, 2, -1
134 | if (S(i - 1).
18 | from .xfoil import XFoil
19 | from .model import Airfoil
20 | from .model_parametrized import Parsec
21 | from .bdlayer import BoundaryLayer
22 | from .cpdist import CpAnalysis
--------------------------------------------------------------------------------
/src/xfoil/bdlayer.py:
--------------------------------------------------------------------------------
1 | import pandas as pd
2 | import numpy as np
3 |
4 | from dotmap import DotMap
5 |
6 | class BoundaryLayer():
7 | """Read and process the boundary layer file created by Xfoil.
8 |
9 | The boundary layer properties are created as a DotMap with
10 | the following levels:
11 | - upper
12 | - lower
13 | - wake
14 |
15 | Note
16 | ----
17 | It assumes the file already exists when it is instantiated.
18 | """
19 |
20 | def __init__(self, filename):
21 |
22 | self.filename = filename
23 |
24 | # Read the file
25 | self._read_file()
26 |
27 | # Postprocess
28 | self._find_airfoil()
29 | self._trim_coord()
30 | self._trim_boundary_layer()
31 |
32 | def _read_file(self):
33 | """Read the boundary layer file and
34 | extract the data in the right format.
35 | """
36 | # Read the boundary data file
37 | df_bl = pd.read_csv(self.filename, delim_whitespace=True)
38 |
39 | # Get all the variables
40 | self.variables = df_bl.columns
41 |
42 | # Remove the columns that do not contain data
43 | df_bl.dropna(axis=1, how='all', inplace=True)
44 |
45 | # Rename the columns appropriately
46 | df_bl.columns = self.variables[1:len(df_bl.columns)+1]
47 |
48 | # Extract all the variables
49 | self.s_raw = df_bl['s'].values
50 | self.x_raw = df_bl['x'].values
51 | self.y_raw = df_bl['y'].values
52 |
53 | self.ue_vinfty_raw = df_bl['Ue/Vinf'].values
54 | self.d_star_raw = df_bl['Dstar'].values
55 | self.theta_raw = df_bl['Theta'].values
56 |
57 | self.cf_raw = df_bl['Cf'].values
58 |
59 | self.H_raw = df_bl['H'].values
60 | self.H_star_raw = df_bl['H*'].values
61 |
62 | self.P_raw = df_bl['P'].values
63 | self.m_raw = df_bl['m'].values
64 |
65 | # Memory clean-up
66 | self.df_bl = df_bl
67 |
68 | def _find_airfoil(self):
69 | """Find the array index at the end of the profile.
70 |
71 | Notes
72 | -----
73 | Creates attribute last_index.
74 | """
75 | coord_LE = np.min(self.x_raw)
76 |
77 | self.idx_LE = np.where(self.x_raw == coord_LE)[0][0]
78 | _, self.idx_TE = np.where(self.x_raw == 1.0)[0]
79 |
80 | def _get_trimmed_values(self, property):
81 | """Trim the boundary layer property according to the three sections present:
82 | - Upper surface
83 | - Lower surface
84 | - Wake
85 |
86 | Parameters
87 | ----------
88 | property: numpy array
89 |
90 | Returns
91 | -------
92 | DotMap
93 | - Keys:
94 | - "upper"
95 | - "lower"
96 | - "wake"
97 | - Values: numpy arrays
98 |
99 | Notes
100 | -----
101 | The length of upper and lower is not necessarily the same due to curvature.
102 | """
103 | data = DotMap()
104 | data.upper = property[0 :self.idx_LE+1]
105 | data.lower = property[self.idx_LE :self.idx_TE+1]
106 | data.wake = property[self.idx_TE+1: ]
107 |
108 | return data
109 |
110 | def _trim_boundary_layer(self):
111 | """
112 | Cut the boundary layer properties between airfoil upper, lower sections and wake.
113 | """
114 | self.cf = self._get_trimmed_values(self.cf_raw)
115 | self.H = self._get_trimmed_values(self.H_raw)
116 | self.H_star = self._get_trimmed_values(self.H_star_raw)
117 | self.theta = self._get_trimmed_values(self.theta_raw)
118 | self.d_star = self._get_trimmed_values(self.d_star_raw)
119 |
120 | def _trim_coord(self):
121 | """Cut the coordinates (x,y,s) between airfoil upper, lower sections and wake.
122 | """
123 | self.x = self._get_trimmed_values(self.x_raw)
124 | self.y = self._get_trimmed_values(self.y_raw)
125 | self.s = self._get_trimmed_values(self.s_raw)
126 |
127 | def detect_bubbles(self):
128 | """
129 | Detect any recirculation bubble via the Cf coefficient.
130 |
131 | Returns
132 | -------
133 | dict:
134 | - Keys:
135 | - "upper"
136 | - exists
137 | - indices
138 | - length
139 | - "lower"
140 | - ...
141 | """
142 |
143 | bubble = DotMap()
144 |
145 | # Upper bubble
146 | bubble.upper.exists, bubble.upper.indices = self._detect_bubble(self.cf['upper'])
147 |
148 | # Lower bubble
149 | bubble.lower.exists, bubble.lower.indices = self._detect_bubble(self.cf['lower'])
150 |
151 | # Compute lengths (if any)
152 | if bubble.upper.exists is True:
153 | bubble.upper.length = self.s.upper[bubble.upper.indices[-1]] - self.s.upper[bubble.upper.indices[0]]
154 | else:
155 | bubble.upper.length = 0.0
156 |
157 | if bubble.lower.exists is True:
158 | bubble.lower.length = self.s.lower[bubble.lower.indices[-1]] - self.s.lower[bubble.lower.indices[0]]
159 | else:
160 | bubble.lower.length = 0.0
161 |
162 | return bubble
163 |
164 | def _detect_bubble(self, cf):
165 | """
166 | Detect bubble in cf section.
167 |
168 | Parameters
169 | ----------
170 | cf: np.array
171 |
172 | Returns
173 | -------
174 | tuple: bool, list
175 | bool: True when there is a bubble
176 | list: [start index, last index] of the bubble
177 | """
178 |
179 | # Look for the the indices with negative cf
180 | idx = np.where(cf<0)[0]
181 |
182 | # Assume no bubble
183 | flag_bubble = False
184 |
185 | # If there are no indices, there is no bubble
186 | if len(idx) == 0:
187 | return flag_bubble, []
188 | else:
189 | flag_bubble = True
190 | return flag_bubble, [idx[0], idx[-1]]
191 |
192 |
193 |
194 |
195 |
--------------------------------------------------------------------------------
/src/xfoil/cpdist.py:
--------------------------------------------------------------------------------
1 | import pandas as pd
2 | import numpy as np
3 |
4 | from dotmap import DotMap
5 |
6 | class CpAnalysis():
7 | """Read and process the boundary layer file created by Xfoil.
8 |
9 | Note
10 | ----
11 | It assumes the file already exists when it is instantiated.
12 | """
13 |
14 | def __init__(self, filename):
15 |
16 | self.filename = filename
17 |
18 | # Read the file
19 | self._read_file()
20 |
21 | self._find_airfoil()
22 | self._trim_variables()
23 |
24 | def _read_file(self):
25 | """Read the boundary layer file and
26 | extract the data in the right format.
27 | """
28 | # Read the boundary data file
29 | df_cp = pd.read_csv(self.filename, delim_whitespace=True)
30 |
31 | # Get all the variables
32 | self.variables = df_cp.columns
33 |
34 | # Remove the columns that do not contain data
35 | df_cp.dropna(axis=1, how='all', inplace=True)
36 |
37 | # Rename the columns appropriately
38 | df_cp.columns = self.variables[1:len(df_cp.columns)+1]
39 |
40 | # Extract all the variables
41 | self.df_cp = df_cp
42 |
43 | # Memory clean-up
44 | del df_cp
45 |
46 | def _find_airfoil(self):
47 | """Find the array index at the end of the profile.
48 |
49 | Notes
50 | -----
51 | Creates attribute last_index.
52 | """
53 | coord_LE = np.min(self.df_cp['x'].values)
54 |
55 | self.idx_LE = np.where(self.df_cp['x'].values == coord_LE)[0][0]
56 | _, self.idx_TE = np.where(self.df_cp['x'].values == 1.0)[0]
57 |
58 | def _trim_variables(self):
59 |
60 | self.cp = DotMap()
61 | self.x = DotMap()
62 |
63 | self.cp.upper = self.df_cp['Cp'].values[0 :self.idx_LE+1]
64 | self.cp.lower = self.df_cp['Cp'].values[self.idx_LE: ]
65 |
66 | self.x.upper = self.df_cp['x'].values[0 :self.idx_LE+1]
67 | self.x.lower = self.df_cp['x'].values[self.idx_LE: ]
68 |
--------------------------------------------------------------------------------
/src/xfoil/model.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Copyright (c) 2019 D. de Vries
3 | #
4 | # This file is part of XFoil.
5 | #
6 | # XFoil is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # XFoil is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with XFoil. If not, see .
18 | import numpy as np
19 |
20 | class Airfoil():
21 | """Airfoil
22 |
23 | Attributes
24 | ----------
25 | n_coords
26 | x
27 | y
28 | """
29 |
30 | def __init__(self, x, y):
31 | self.coords = np.ndarray((0, 2))
32 | self.x = x
33 | self.y = y
34 |
35 | @property
36 | def n_coords(self):
37 | """int: Number of coordinates which define the airfoil surface."""
38 | return self.coords.shape[0]
39 |
40 | @property
41 | def x(self):
42 | """np.ndarray: List of x-coordinates of the airfoil surface."""
43 | return self.coords[:, 0]
44 |
45 | @x.setter
46 | def x(self, value):
47 | v = value.flatten()
48 | self.coords.resize((v.size, 2))
49 | self.coords[:, 0] = v[:]
50 |
51 | @property
52 | def y(self):
53 | """np.ndarray: List of y-coordinates of the airfoil surface."""
54 | return self.coords[:, 1]
55 |
56 | @y.setter
57 | def y(self, value):
58 | v = value.flatten()
59 | self.coords.resize((v.size, 2))
60 | self.coords[:, 1] = v[:]
61 |
--------------------------------------------------------------------------------
/src/xfoil/model_parametrized.py:
--------------------------------------------------------------------------------
1 | """
2 | +------------------+------------------------------------------------+
3 | | PARSEC parameter | Definition |
4 | +------------------+------------------------------------------------+
5 | | p1 | Leading edge radius |
6 | +------------------+------------------------------------------------+
7 | | p2 | Upper crest position in horizontal coordinates |
8 | +------------------+------------------------------------------------+
9 | | p3 | Upper crest position in vertical coordinates |
10 | +------------------+------------------------------------------------+
11 | | p4 | Upper crest curvature |
12 | +------------------+------------------------------------------------+
13 | | p5 | Lower crest position in horizontal coordinates |
14 | +------------------+------------------------------------------------+
15 | | p6 | Lower crest position in vertical coordinates |
16 | +------------------+------------------------------------------------+
17 | | p7 | Lower crest curvature |
18 | +------------------+------------------------------------------------+
19 | | p8 | Trailing edge offset in vertical sense |
20 | +------------------+------------------------------------------------+
21 | | p9 | Trailing edge thickness |
22 | +------------------+------------------------------------------------+
23 | | p10 | Trailing edge direction |
24 | +------------------+------------------------------------------------+
25 | | p11 | Trailing edge wedge angle |
26 | +------------------+------------------------------------------------+
27 | (Generated with http://www.tablesgenerator.com/)
28 |
29 | Source
30 | ------
31 | Sobieczky H. (1999) Parametric Airfoils and Wings.
32 | In: Fujii K., Dulikravich G.S. (eds) Recent Development of Aerodynamic Design Methodologies.
33 | Notes on Numerical Fluid Mechanics (NNFM), vol 65. Vieweg+Teubner Verlag
34 | """
35 |
36 |
37 | from copy import deepcopy
38 |
39 | from scipy.optimize import minimize
40 |
41 | import numpy as np
42 | from numpy.linalg import solve
43 |
44 | from xfoil import Airfoil
45 | from dotmap import DotMap
46 |
47 | class ParametrizedAirfoil():
48 |
49 | def __init__(self, *args, **kwargs):
50 | pass
51 |
52 | def fit(airfoil:Airfoil):
53 |
54 | # Code to find the best fitting coefficients.
55 |
56 |
57 | return design_vector
58 |
59 | class Parsec(ParametrizedAirfoil):
60 | """
61 | Parsec airfoil parametrization.
62 |
63 | Parameters
64 | ----------
65 | design_vector: dict
66 | """
67 |
68 | def __init__(self, design_vector: dict = None, N = 160):
69 | super().__init__()
70 |
71 | # Save design vector
72 | if design_vector is None:
73 | self.dv = self._basic_design_vector()
74 | else:
75 | self.dv = design_vector
76 |
77 | self.N = N
78 |
79 | # Create specific PARSEC coefficient vectors
80 | self._q1 = [n + 1/2 for n in range(0,6)]
81 | self._q2 = [n**2 - 1/4 for n in range(0,6)]
82 |
83 | # Display attributes
84 | self._rhs_upper = None
85 | self._rhs_lower = None
86 | self._matrix_lower = None
87 | self._matrix_upper = None
88 | self._coeff_lower = None
89 | self._coeff_upper = None
90 |
91 | self.x = None
92 | self.y_upper = None
93 | self.y_lower = None
94 |
95 | def _basic_design_vector(self):
96 | """
97 | Load a basic design vector.
98 |
99 | Parameters
100 | ----------
101 | None
102 |
103 | Returns
104 | -------
105 | dict
106 | """
107 | coeff = [
108 | 0.05, # p1 | Leading edge radius
109 |
110 | 0.3, # p2 | Upper crest position in horizontal coordinates
111 | 0.1, # p3 | Upper crest position in vertical coordinates
112 | 1.0, # p4 | Upper crest curvature
113 |
114 | 0.3, # p5 | Lower crest position in horizontal coordinates
115 | -0.1, # p6 | Lower crest position in vertical coordinates
116 | 0.1, # p7 | Lower crest curvature
117 |
118 | 0.1, # p8 | Trailing edge offset in vertical sense
119 | 0.1, # p9 | Trailing edge thickness
120 | 1.0, # p10 | Trailing edge direction
121 | 20.0 # p11 | Trailing edge wedge angle
122 | ]
123 |
124 | return {'p{}'.format(q):value for q, value in zip(range(1,12), coeff)}
125 |
126 | def create_airfoil(self, p:dict = None, x: np.array = None):
127 | """
128 | Create airfoil coordinates compatible with xfoil.
129 |
130 | Parameters
131 | ----------
132 | p: dict
133 | Default: None
134 | New design vector
135 |
136 | Returns
137 | -------
138 | Airfoil
139 | """
140 | if p is not None:
141 | self.dv = deepcopy(p)
142 | else:
143 | pass
144 |
145 | if x is not None:
146 | self.N = len(x)
147 |
148 | # Prepare linear system
149 | self._create_matrices()
150 | self._create_rhs()
151 |
152 | # Solve linear system
153 | self._compute_coefficients()
154 |
155 | # Compute airfoil
156 | self._compute_coordinates(x)
157 |
158 | # Prepare output
159 | x = np.concatenate([np.flip(self.x), self.x[1:]])
160 | y = np.concatenate([np.flip(self.y_upper), self.y_lower[1:]])
161 |
162 | return Airfoil(x = x, y = y)
163 |
164 | def _create_rhs(self):
165 | """
166 | Assemble the RHS vectors for the upper and lower surface.
167 | """
168 | self._rhs_upper = self._fill_in_rhs(sign = '+')
169 | self._rhs_lower = self._fill_in_rhs(sign = '-')
170 |
171 | def _compute_coefficients(self):
172 | """
173 | Solve linear system to obtain PARSEC coefficients.
174 | """
175 |
176 | self._coeff_upper = solve(self._matrix_upper, self._rhs_upper)
177 | self._coeff_lower = solve(self._matrix_lower, self._rhs_lower)
178 |
179 | def _compute_coordinates(self, x: np.array = None):
180 | """
181 | Compute the airfoil coordinates for the current
182 | design vector.
183 |
184 | Parameters
185 | ----------
186 | x: np.array
187 |
188 | Returns
189 | -------
190 | """
191 |
192 | if x is None:
193 | x = self._cosine_distribution()
194 |
195 | # Make sure we are mapping the [0,1] domain
196 | x = np.sort(x)
197 |
198 | x_q = np.array([x**q for q in self._q1])
199 |
200 | self.y_upper = np.dot(np.transpose(self._coeff_upper), x_q)[0]
201 | self.y_lower = np.dot(np.transpose(self._coeff_lower), x_q)[0]
202 |
203 | self.x = x
204 |
205 | def _cosine_distribution(self, N:int = None):
206 | """
207 | Compute a cosine distribution in [0,1].
208 |
209 | Returns
210 | -------
211 | x: np.array
212 | """
213 |
214 | from math import cos, pi
215 |
216 | if N is None:
217 | N = self.N
218 |
219 | x = np.linspace(start = 0, stop = 1, num = N)
220 | x = list(map(cos, x * pi))
221 |
222 | # Sort from negative to positive
223 | x = np.sort(np.array(x))
224 |
225 | # Center and scale
226 | x += 1.0
227 | x /= 2.0
228 |
229 | return x
230 |
231 | def _fill_in_rhs(self, sign = '+'):
232 | """
233 | Fill-in vector according to airfoil surface.
234 |
235 | Parameters
236 | ---------
237 | sign: str
238 | '+': Upper surface
239 | '-': Lower surface
240 |
241 | Returns
242 | -------
243 | vec: np.array
244 | """
245 |
246 | from math import tan, sqrt, pi
247 |
248 | deg_to_rad = pi / 180.0
249 | vec = np.ndarray(shape=(6,1))
250 |
251 | if sign == '+':
252 | vec[0] = self.dv['p8'] + self.dv['p9'] / 2.0
253 | vec[1] = self.dv['p3']
254 | vec[2] = tan(deg_to_rad * (self.dv['p10'] - self.dv['p11'] / 2.0))
255 | vec[3] = 0.0
256 | vec[4] = self.dv['p4']
257 | vec[5] = sqrt(2.0 * self.dv['p1'])
258 | elif sign == '-':
259 | vec[0] = self.dv['p8'] - self.dv['p9'] / 2.0
260 | vec[1] = self.dv['p6']
261 | vec[2] = tan(deg_to_rad * (self.dv['p10'] + self.dv['p11'] / 2.0))
262 | vec[3] = 0.0
263 | vec[4] = self.dv['p7']
264 | vec[5] = -sqrt(2.0 * self.dv['p1'])
265 | else:
266 | raise ValueError('Which section do you want to create?')
267 |
268 | return vec
269 |
270 | def _create_matrices(self):
271 |
272 | self._matrix_upper = self._fill_in_matrix(p = self.dv['p2'])
273 | self._matrix_lower = self._fill_in_matrix(p = self.dv['p5'])
274 |
275 | def _fill_in_matrix(self, p:float):
276 | """
277 | Fill-in matrix according to parameter p2/p5.
278 |
279 | Parameters
280 | ----------
281 | p: float
282 | Crest position in horizontal coordinates
283 | - Upper: p2
284 | - Lower: p5
285 |
286 | Returns
287 | -------
288 | matrix: np.ndarray(shape=(6,6))
289 |
290 | Notes
291 | -----
292 | Row definitions:
293 | 0: TE height
294 | 1: Max. location
295 | 2: TE direction
296 | 3: Max. condition
297 | 4: Curvature
298 | 5: LE radius
299 |
300 | """
301 |
302 | matrix = np.ndarray(shape=(6,6))
303 |
304 | matrix[0] = np.ones(6, dtype=float)
305 | matrix[1] = np.array([p**q for q in self._q1], dtype=float)
306 | matrix[2] = np.array([q for q in self._q1], dtype=float)
307 | matrix[3] = np.array([q * p**(q-1.0) for q in self._q1], dtype=float)
308 | matrix[4] = np.array([q2 * p**(q1-2.0) for q1, q2 in zip(self._q1, self._q2)], dtype=float)
309 | matrix[5] = np.zeros(6, dtype = float)
310 | matrix[5,0] = 1.0
311 |
312 | return matrix
313 |
--------------------------------------------------------------------------------
/src/xfoil/test.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Copyright (c) 2019 D. de Vries
3 | #
4 | # This file is part of XFoil.
5 | #
6 | # XFoil is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # XFoil is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with XFoil. If not, see .
18 | import numpy as np
19 | import unittest
20 |
21 | from xfoil import XFoil
22 | from xfoil.model import Airfoil
23 |
24 | # from .xfoil import XFoil
25 | # from .model import Airfoil
26 |
27 | naca0012 = Airfoil(
28 | x=np.array([+1.0000e+00, +9.9168e-01, +9.8037e-01, +9.6727e-01, +9.5272e-01, +9.3720e-01, +9.2112e-01, +9.0474e-01,
29 | +8.8821e-01, +8.7160e-01, +8.5494e-01, +8.3827e-01, +8.2158e-01, +8.0488e-01, +7.8817e-01, +7.7146e-01,
30 | +7.5475e-01, +7.3803e-01, +7.2132e-01, +7.0460e-01, +6.8789e-01, +6.7118e-01, +6.5447e-01, +6.3777e-01,
31 | +6.2108e-01, +6.0440e-01, +5.8772e-01, +5.7106e-01, +5.5441e-01, +5.3778e-01, +5.2116e-01, +5.0456e-01,
32 | +4.8798e-01, +4.7143e-01, +4.5489e-01, +4.3839e-01, +4.2191e-01, +4.0546e-01, +3.8905e-01, +3.7268e-01,
33 | +3.5635e-01, +3.4007e-01, +3.2383e-01, +3.0766e-01, +2.9154e-01, +2.7550e-01, +2.5953e-01, +2.4366e-01,
34 | +2.2788e-01, +2.1222e-01, +1.9670e-01, +1.8135e-01, +1.6619e-01, +1.5127e-01, +1.3666e-01, +1.2246e-01,
35 | +1.0877e-01, +9.5752e-02, +8.3582e-02, +7.2423e-02, +6.2395e-02, +5.3537e-02, +4.5806e-02, +3.9101e-02,
36 | +3.3294e-02, +2.8256e-02, +2.3867e-02, +2.0028e-02, +1.6658e-02, +1.3692e-02, +1.1080e-02, +8.7858e-03,
37 | +6.7811e-03, +5.0484e-03, +3.5772e-03, +2.3627e-03, +1.4037e-03, +6.9909e-04, +2.4355e-04, +2.6000e-05,
38 | +2.6000e-05, +2.4355e-04, +6.9909e-04, +1.4037e-03, +2.3627e-03, +3.5772e-03, +5.0484e-03, +6.7811e-03,
39 | +8.7858e-03, +1.1080e-02, +1.3692e-02, +1.6658e-02, +2.0028e-02, +2.3867e-02, +2.8256e-02, +3.3294e-02,
40 | +3.9101e-02, +4.5806e-02, +5.3537e-02, +6.2395e-02, +7.2423e-02, +8.3582e-02, +9.5752e-02, +1.0877e-01,
41 | +1.2246e-01, +1.3666e-01, +1.5127e-01, +1.6619e-01, +1.8135e-01, +1.9670e-01, +2.1222e-01, +2.2788e-01,
42 | +2.4366e-01, +2.5953e-01, +2.7550e-01, +2.9154e-01, +3.0766e-01, +3.2383e-01, +3.4007e-01, +3.5635e-01,
43 | +3.7268e-01, +3.8905e-01, +4.0546e-01, +4.2191e-01, +4.3839e-01, +4.5489e-01, +4.7143e-01, +4.8798e-01,
44 | +5.0456e-01, +5.2116e-01, +5.3778e-01, +5.5441e-01, +5.7106e-01, +5.8772e-01, +6.0440e-01, +6.2108e-01,
45 | +6.3777e-01, +6.5447e-01, +6.7118e-01, +6.8789e-01, +7.0460e-01, +7.2132e-01, +7.3803e-01, +7.5475e-01,
46 | +7.7146e-01, +7.8817e-01, +8.0488e-01, +8.2158e-01, +8.3827e-01, +8.5494e-01, +8.7160e-01, +8.8821e-01,
47 | +9.0474e-01, +9.2112e-01, +9.3720e-01, +9.5272e-01, +9.6727e-01, +9.8037e-01, +9.9168e-01, +1.0000e+00]
48 | ),
49 | y=np.array([+1.2600e-03, +2.4215e-03, +3.9814e-03, +5.7619e-03, +7.7062e-03, +9.7433e-03, +1.1815e-02, +1.3886e-02,
50 | +1.5936e-02, +1.7956e-02, +1.9943e-02, +2.1894e-02, +2.3810e-02, +2.5689e-02, +2.7532e-02, +2.9338e-02,
51 | +3.1107e-02, +3.2839e-02, +3.4534e-02, +3.6190e-02, +3.7807e-02, +3.9384e-02, +4.0921e-02, +4.2415e-02,
52 | +4.3865e-02, +4.5271e-02, +4.6630e-02, +4.7940e-02, +4.9199e-02, +5.0406e-02, +5.1557e-02, +5.2650e-02,
53 | +5.3683e-02, +5.4652e-02, +5.5554e-02, +5.6385e-02, +5.7143e-02, +5.7822e-02, +5.8419e-02, +5.8930e-02,
54 | +5.9349e-02, +5.9671e-02, +5.9891e-02, +6.0004e-02, +6.0002e-02, +5.9879e-02, +5.9628e-02, +5.9241e-02,
55 | +5.8710e-02, +5.8027e-02, +5.7181e-02, +5.6164e-02, +5.4967e-02, +5.3580e-02, +5.1997e-02, +5.0216e-02,
56 | +4.8243e-02, +4.6095e-02, +4.3805e-02, +4.1422e-02, +3.9000e-02, +3.6592e-02, +3.4237e-02, +3.1957e-02,
57 | +2.9760e-02, +2.7644e-02, +2.5598e-02, +2.3613e-02, +2.1675e-02, +1.9770e-02, +1.7888e-02, +1.6017e-02,
58 | +1.4147e-02, +1.2270e-02, +1.0381e-02, +8.4792e-03, +6.5676e-03, +4.6570e-03, +2.7615e-03, +9.0564e-04,
59 | -9.0564e-04, -2.7615e-03, -4.6570e-03, -6.5676e-03, -8.4792e-03, -1.0381e-02, -1.2270e-02, -1.4147e-02,
60 | -1.6017e-02, -1.7888e-02, -1.9770e-02, -2.1675e-02, -2.3613e-02, -2.5598e-02, -2.7644e-02, -2.9760e-02,
61 | -3.1957e-02, -3.4237e-02, -3.6592e-02, -3.9000e-02, -4.1422e-02, -4.3805e-02, -4.6095e-02, -4.8243e-02,
62 | -5.0216e-02, -5.1997e-02, -5.3580e-02, -5.4967e-02, -5.6164e-02, -5.7181e-02, -5.8027e-02, -5.8710e-02,
63 | -5.9241e-02, -5.9628e-02, -5.9879e-02, -6.0002e-02, -6.0004e-02, -5.9891e-02, -5.9671e-02, -5.9349e-02,
64 | -5.8930e-02, -5.8419e-02, -5.7822e-02, -5.7143e-02, -5.6385e-02, -5.5554e-02, -5.4652e-02, -5.3683e-02,
65 | -5.2650e-02, -5.1557e-02, -5.0406e-02, -4.9199e-02, -4.7940e-02, -4.6630e-02, -4.5271e-02, -4.3865e-02,
66 | -4.2415e-02, -4.0921e-02, -3.9384e-02, -3.7807e-02, -3.6190e-02, -3.4534e-02, -3.2839e-02, -3.1107e-02,
67 | -2.9338e-02, -2.7532e-02, -2.5689e-02, -2.3810e-02, -2.1894e-02, -1.9943e-02, -1.7956e-02, -1.5936e-02,
68 | -1.3886e-02, -1.1815e-02, -9.7433e-03, -7.7062e-03, -5.7619e-03, -3.9814e-03, -2.4215e-03, -1.2600e-03]
69 | )
70 | )
71 |
72 |
73 | class TestXFoil(unittest.TestCase):
74 | """Test whether the XFOIL module functions properly."""
75 |
76 | def assertNumpyArraysAlmostEqual(self, first, second, decimal, msg=''):
77 | for i in range(first.size):
78 | self.assertAlmostEqual(first[i], second[i], decimal, msg)
79 |
80 | def test_a(self):
81 | """Analyse the NACA 0012 at Re = 1e6, M = 0, α = 10 degrees and verify the results."""
82 | xf = XFoil()
83 | xf.airfoil = naca0012
84 | xf.conditions = (50000, 0)
85 | xf.max_iter = 1000
86 | cl, cd, cm, cp = xf.a(5)
87 |
88 | print(cl, cd, cm, cp)
89 |
90 | self.assertAlmostEqual(cl, 1.0809, 4)
91 | self.assertAlmostEqual(cd, 0.0150, 4)
92 | self.assertAlmostEqual(cm, 0.0053, 4)
93 |
94 | def test_cl(self):
95 | """Analyse the NACA 0012 at Re = 1e6, M = 0, C_l = 1 and verify the results."""
96 | xf = XFoil()
97 | xf.airfoil = naca0012
98 | xf.conditions = (1e6, 0)
99 | a, cd, cm, cp= xf.cl(1)
100 |
101 | self.assertAlmostEqual(a, 9.0617, 4)
102 | self.assertAlmostEqual(cd, 0.0135, 4)
103 | self.assertAlmostEqual(cm, 0.0013, 4)
104 |
105 | def test_aseq(self):
106 | """Analyse the NACA 0012 at Re = 1e6, M = 0, α = -20, -19.5, ..., 19.5 and verify the results."""
107 | xf = XFoil()
108 | xf.airfoil = naca0012
109 | xf.conditions = (1e6, 0)
110 | xf.max_iter = 40
111 | a, cl, cd, cm, co = xf.aseq(-20, 20, 0.5)
112 |
113 | self.assertNumpyArraysAlmostEqual(a, np.arange(-20, 20, 0.5), 4)
114 | self.assertNumpyArraysAlmostEqual(cl, np.array([
115 | -1.1177, -1.1521, -1.1878, -1.2263, -1.2654, -1.3014, -1.3296, -1.3656, -1.3861, -1.3883,
116 | -1.3793, -1.3661, -1.3492, -1.3264, -1.3155, -1.2830, -1.2451, -1.2065, -1.1664, -1.1223,
117 | -1.0809, -1.0363, -0.9948, -0.9512, -0.9100, -0.8685, -0.8266, -0.7637, -0.6948, -0.6255,
118 | -0.5580, -0.4878, -0.4278, -0.3723, -0.3199, -0.2672, -0.2142, -0.1609, -0.1073, -0.0537,
119 | -0.0000, +0.0537, +0.1073, +0.1609, +0.2142, +0.2672, +0.3199, +0.3723, +0.4278, +0.4878,
120 | +0.5580, +0.6255, +0.6949, +0.7638, +0.8264, +0.8684, +0.9099, +0.9511, +0.9948, +1.0363,
121 | +1.0809, +1.1224, +1.1665, +1.2067, +1.2454, +1.2834, +1.3161, +1.3273, +1.3502, +1.3673,
122 | +1.3808, +1.3900, +1.3877, +1.3670, +1.3323, +1.3041, +1.2680, +1.2288, +1.1901, +1.1541]), 4)
123 | self.assertNumpyArraysAlmostEqual(cd, np.array([
124 | +0.1474, +0.1320, +0.1171, +0.1023, +0.0879, +0.0746, +0.0630, +0.0509, +0.0417, +0.0358,
125 | +0.0317, +0.0286, +0.0261, +0.0243, +0.0219, +0.0205, +0.0194, +0.0181, +0.0169, +0.0161,
126 | +0.0150, +0.0143, +0.0134, +0.0128, +0.0121, +0.0115, +0.0109, +0.0104, +0.0097, +0.0091,
127 | +0.0085, +0.0078, +0.0073, +0.0068, +0.0064, +0.0061, +0.0058, +0.0056, +0.0055, +0.0054,
128 | +0.0054, +0.0054, +0.0055, +0.0056, +0.0058, +0.0061, +0.0064, +0.0068, +0.0073, +0.0078,
129 | +0.0085, +0.0091, +0.0097, +0.0104, +0.0109, +0.0115, +0.0121, +0.0128, +0.0134, +0.0143,
130 | +0.0150, +0.0161, +0.0169, +0.0181, +0.0194, +0.0205, +0.0220, +0.0243, +0.0261, +0.0286,
131 | +0.0317, +0.0357, +0.0417, +0.0509, +0.0628, +0.0745, +0.0879, +0.1023, +0.1171, +0.1321]), 4)
132 | self.assertNumpyArraysAlmostEqual(cm, np.array([
133 | +0.0238, +0.0148, +0.0066, -0.0012, -0.0085, -0.0153, -0.0210, -0.0268, -0.0304, -0.0317,
134 | -0.0312, -0.0295, -0.0269, -0.0237, -0.0184, -0.0156, -0.0134, -0.0112, -0.0091, -0.0074,
135 | -0.0053, -0.0034, -0.0010, +0.0013, +0.0040, +0.0067, +0.0093, +0.0074, +0.0043, +0.0011,
136 | -0.0017, -0.0051, -0.0060, -0.0058, -0.0049, -0.0039, -0.0030, -0.0022, -0.0014, -0.0007,
137 | +0.0000, +0.0007, +0.0014, +0.0022, +0.0030, +0.0039, +0.0049, +0.0058, +0.0060, +0.0051,
138 | +0.0017, -0.0011, -0.0043, -0.0074, -0.0092, -0.0066, -0.0039, -0.0013, +0.0010, +0.0034,
139 | +0.0053, +0.0074, +0.0091, +0.0111, +0.0133, +0.0155, +0.0182, +0.0236, +0.0267, +0.0294,
140 | +0.0310, +0.0315, +0.0302, +0.0264, +0.0208, +0.0149, +0.0082, +0.0008, -0.0070, -0.0152]), 4)
141 |
142 | def test_cseq(self):
143 | """Analyse the NACA 0012 at Re = 1e6, M = 0, C_l = -0.5, -0.45, ..., 0.45 and verify the results."""
144 | xf = XFoil()
145 | xf.airfoil = naca0012
146 | xf.conditions = (1e6, 0.)
147 | xf.max_iter = 40
148 | a, cl, cd, cm = xf.cseq(-0.5, 0.5, 0.05)
149 |
150 | self.assertNumpyArraysAlmostEqual(cl, np.arange(-0.5, 0.5, 0.05), 4)
151 | self.assertNumpyArraysAlmostEqual(a, np.array([
152 | -4.5879, -4.1765, -3.7446, -3.2848, -2.8112, -2.3371, -1.8666, -1.3981, -0.9324, -0.4659,
153 | -0.0000, +0.4659, +0.9323, +1.3981, +1.8665, +2.3370, +2.8111, +3.2847, +3.7445, +4.1764]), +4)
154 | self.assertNumpyArraysAlmostEqual(cd, np.array([
155 | +0.0079, +0.0075, +0.0070, +0.0066, +0.0063, +0.0060, +0.0058, +0.0056, +0.0055, +0.0054,
156 | +0.0054, +0.0054, +0.0055, +0.0056, +0.0058, +0.0060, +0.0063, +0.0066, +0.0070, +0.0075]), 4)
157 | self.assertNumpyArraysAlmostEqual(cm, np.array([
158 | -0.0045, -0.0055, -0.0058, -0.0054, -0.0045, -0.0036, -0.0028, -0.0020, -0.0013, -0.0007,
159 | -0.0000, +0.0007, +0.0013, +0.0020, +0.0028, +0.0036, 0.0045, +0.0054, +0.0058, +0.0055]), 4)
160 |
161 |
162 | if __name__ == '__main__':
163 | unittest.main()
164 |
--------------------------------------------------------------------------------
/src/xfoil/xfoil.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Copyright (c) 2019 D. de Vries
3 | #
4 | # This file is part of XFoil.
5 | #
6 | # XFoil is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # XFoil is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with XFoil. If not, see .
18 |
19 | #import sys
20 | #sys.path.insert(0, '/Users/Kike/Library/Mobile Documents/com~apple~CloudDocs/Documents/Inbox/TU_Delft/MsC/Q1/Aircraft_Aerodynamics/Code/xfoil-python/')
21 |
22 |
23 | import numpy as np
24 | import ctypes
25 | import os
26 | import glob
27 |
28 | from deprecated import deprecated
29 |
30 | from ctypes import c_bool, c_int, c_float, byref, POINTER, cdll, c_char_p, c_char
31 | from shutil import copy2
32 | from tempfile import NamedTemporaryFile
33 |
34 |
35 | from xfoil.model import Airfoil
36 |
37 | here = os.path.abspath(os.path.dirname(__file__))
38 | #lib_path = glob.glob(os.path.join(here, 'libxfoil.*'))[0]
39 | #lib_ext = lib_path[lib_path.rfind('.'):]
40 |
41 | lib_path = '/Users/Kike/Library/Mobile Documents/com~apple~CloudDocs/Documents/Inbox/TU_Delft/MsC/Q1/Aircraft_Aerodynamics/Code/xfoil-python/build/lib.macosx-10.7-x86_64-3.6/xfoil/libxfoil.dylib'
42 | lib_ext = 'dylib'
43 |
44 | fptr = POINTER(c_float)
45 | bptr = POINTER(c_bool)
46 |
47 | class XFoil(object):
48 | """Interface to the XFoil Fortran routines.
49 |
50 | Attributes
51 | ----------
52 | airfoil
53 | Re
54 | M
55 | xtr
56 | n_crit
57 | max_iter
58 | """
59 |
60 | def __init__(self):
61 | super().__init__()
62 | tmp = NamedTemporaryFile(mode='wb', delete=False, suffix=lib_ext)
63 | tmp.close()
64 | self._lib_path = tmp.name
65 | copy2(lib_path, self._lib_path)
66 | self._lib = cdll.LoadLibrary(self._lib_path)
67 | self._lib.init()
68 | self._airfoil = None
69 |
70 | self._lib.get_print.restype = c_bool
71 | self._lib.get_reynolds.restype = c_float
72 | self._lib.get_mach.restype = c_float
73 | self._lib.get_n_crit.restype = c_float
74 |
75 | self.file_boundary_layer = str()
76 |
77 | def __del__(self):
78 | handle = self._lib._handle
79 | del self._lib
80 | try:
81 | ctypes.windll.kernel32.FreeLibrary(handle)
82 | except AttributeError:
83 | pass
84 | finally:
85 | os.remove(self._lib_path)
86 |
87 | @property
88 | def print(self):
89 | """bool: True if console output should be shown."""
90 | return self._lib.get_print()
91 |
92 | @print.setter
93 | def print(self, value):
94 | self._lib.set_print(byref(c_bool(value)))
95 |
96 | @property
97 | def airfoil(self):
98 | """Airfoil: Instance of the Airfoil class."""
99 | n = self._lib.get_n_coords()
100 | x = np.asfortranarray(np.zeros(n), dtype=c_float)
101 | y = np.asfortranarray(np.zeros(n), dtype=c_float)
102 | self._lib.get_airfoil(x.ctypes.data_as(fptr), y.ctypes.data_as(fptr), byref(c_int(n)))
103 | return Airfoil(x.astype(float), y.astype(float))
104 |
105 | @airfoil.setter
106 | def airfoil(self, airfoil):
107 | self._airfoil = airfoil
108 | self._lib.set_airfoil(
109 | np.asfortranarray(airfoil.x.flatten(), dtype=c_float).ctypes.data_as(fptr),
110 | np.asfortranarray(airfoil.y.flatten(), dtype=c_float).ctypes.data_as(fptr),
111 | byref(c_int(airfoil.n_coords))
112 | )
113 |
114 | @property
115 | def Re(self):
116 | """float: Reynolds number."""
117 | return float(self._lib.get_reynolds())
118 |
119 | @Re.setter
120 | def Re(self, value):
121 | self._lib.set_reynolds(byref(c_float(value)))
122 |
123 | @property
124 | def M(self):
125 | """float: Mach number."""
126 | return float(self._lib.get_mach())
127 |
128 | @M.setter
129 | def M(self, value):
130 | self._lib.set_mach(byref(c_float(value)))
131 |
132 | @property
133 | def xtr(self):
134 | """tuple(float, float): Top and bottom flow trip x/c locations."""
135 | xtr_top = c_float()
136 | xtr_bot = c_float()
137 | self._lib.get_xtr(byref(xtr_top), byref(xtr_bot))
138 | return float(xtr_top), float(xtr_bot)
139 |
140 | @xtr.setter
141 | def xtr(self, value):
142 | self._lib.set_xtr(byref(c_float(value[0])), byref(c_float(value[1])))
143 |
144 | @property
145 | def n_crit(self):
146 | """float: Critical amplification ratio."""
147 | return float(self._lib.get_n_crit())
148 |
149 | @n_crit.setter
150 | def n_crit(self, value):
151 | self._lib.set_n_crit(byref(c_float(value)))
152 |
153 | @property
154 | def max_iter(self):
155 | """int: Maximum number of iterations."""
156 | return int(self._lib.get_max_iter())
157 |
158 | @max_iter.setter
159 | def max_iter(self, max_iter):
160 | self._lib.set_max_iter(byref(c_int(max_iter)))
161 |
162 | def naca(self, specifier):
163 | """Set a NACA 4 or 5 series airfoil.
164 |
165 | Parameters
166 | ----------
167 | specifier : string
168 | A NACA 4 or 5 series identifier, such as '2412'.
169 | """
170 | self._lib.set_naca(byref(c_int(int(specifier))))
171 |
172 | def reset_bls(self):
173 | """Reset the boundary layers to be reinitialized on the next analysis."""
174 | self._lib.reset_bls()
175 |
176 | def repanel(self, n_nodes=160, cv_par=1, cte_ratio=0.15, ctr_ratio=0.2, xt_ref=(1, 1), xb_ref=(1, 1)):
177 | """Re-panel airfoil.
178 |
179 | Parameters
180 | ----------
181 | n_nodes : int
182 | Number of panel nodes
183 | cv_par : float
184 | Panel bunching parameter
185 | cte_ratio : float
186 | TE/LE panel density ratio
187 | ctr_ratio : float
188 | Refined-area/LE panel density ratio
189 | xt_ref : tuple of two floats
190 | Top side refined area x/c limits
191 | xb_ref : tuple of two floats
192 | Bottom side refined area x/c limits
193 | """
194 | self._lib.repanel(byref(c_int(n_nodes)), byref(c_float(cv_par)),
195 | byref(c_float(cte_ratio)), byref(c_float(ctr_ratio)),
196 | byref(c_float(xt_ref[0])), byref(c_float(xt_ref[1])),
197 | byref(c_float(xb_ref[0])), byref(c_float(xb_ref[1])))
198 |
199 | def filter(self, factor=0.2):
200 | """Filter surface speed distribution using modified Hanning filter.
201 |
202 | Parameters
203 | ----------
204 | factor : float
205 | Filter parameter. If set to 1, the standard, full Hanning filter is applied. Default is 0.2.
206 | """
207 | self._lib.filter(byref(c_float(factor)))
208 |
209 | def a(self, a):
210 | """Analyze airfoil at a fixed angle of attack.
211 |
212 | Parameters
213 | ----------
214 | a : float
215 | Angle of attack in degrees
216 |
217 | Returns
218 | -------
219 | cl, cd, cd_f, cd_p, cm, cp : float
220 | Corresponding values of the lift, drag, pressure drag, moment, and minimum pressure coefficients.
221 |
222 | # TODO: reorganize a and cl to always give the same output structure.
223 | """
224 | cl = c_float()
225 | cd = c_float()
226 | cd_f = c_float()
227 | cd_p = c_float()
228 | cm = c_float()
229 | cp = c_float()
230 | conv = c_bool()
231 |
232 | self._lib.alfa(byref(c_float(a)), byref(cl), byref(cd), byref(cd_f), byref(cd_p), byref(cm), byref(cp), byref(conv))
233 |
234 | return (cl.value, cd.value, cd_f.value, cd_p.value, cm.value, cp.value) if conv else (np.nan, np.nan, np.nan, np.nan, np.nan, np.nan)
235 |
236 | def cl(self, cl):
237 | """
238 | Analyze airfoil at a fixed lift coefficient.
239 |
240 | Parameters
241 | ----------
242 | cl : float
243 | Lift coefficient
244 |
245 | Returns
246 | -------
247 | a, cd, cd_f, cd_p, cm, cp : float
248 | Corresponding values of the angle of attack, drag, moment, and minimum pressure coefficients.
249 | """
250 | a = c_float()
251 | cd = c_float()
252 | cd_f = c_float()
253 | cd_p = c_float()
254 | cm = c_float()
255 | cp = c_float()
256 | conv = c_bool()
257 |
258 | self._lib.cl(byref(c_float(cl)), byref(a), byref(cd), byref(cd_f), byref(cd_p), byref(cm), byref(cp), byref(conv))
259 |
260 | return (a.value, cd.value, cd_f.value, cd_p.value, cm.value, cp.value) if conv else (np.nan, np.nan, np.nan, np.nan, np.nan, np.nan)
261 |
262 | @deprecated(reason='The changes in the Fortran API have not been included here. Unexpected behaviour if called.')
263 | def aseq(self, a_start, a_end, a_step):
264 | """Analyze airfoil at a sequence of angles of attack.
265 |
266 | The analysis is done for the angles of attack given by range(a_start, a_end, a_step).
267 |
268 | Parameters
269 | ----------
270 | a_start, a_end, a_step : float
271 | Start, end, and increment angles for the range.
272 |
273 | Returns
274 | -------
275 | a, cl, cd, cm, co : np.ndarray
276 | Lists of angles of attack and their corresponding lift, drag, moment, and minimum pressure coefficients.
277 | """
278 | n = abs(int((a_end - a_start) / a_step))
279 |
280 | a = np.zeros(n, dtype=c_float)
281 | cl = np.zeros(n, dtype=c_float)
282 | cd = np.zeros(n, dtype=c_float)
283 | cm = np.zeros(n, dtype=c_float)
284 | cp = np.zeros(n, dtype=c_float)
285 | conv = np.zeros(n, dtype=c_bool)
286 |
287 | self._lib.aseq(byref(c_float(a_start)), byref(c_float(a_end)), byref(c_int(n)),
288 | a.ctypes.data_as(fptr), cl.ctypes.data_as(fptr),
289 | cd.ctypes.data_as(fptr), cm.ctypes.data_as(fptr),
290 | cp.ctypes.data_as(fptr), conv.ctypes.data_as(bptr))
291 |
292 | isnan = np.logical_not(conv)
293 | a[isnan] = np.nan
294 | cl[isnan] = np.nan
295 | cd[isnan] = np.nan
296 | cm[isnan] = np.nan
297 | cp[isnan] = np.nan
298 |
299 | return a.astype(float), cl.astype(float), cd.astype(float), cm.astype(float), cp.astype(float)
300 |
301 | @deprecated(reason='The changes in the Fortran API have not been included here. Unexpected behaviour if called.')
302 | def cseq(self, cl_start, cl_end, cl_step):
303 | """Analyze airfoil at a sequence of lift coefficients.
304 |
305 | The analysis is done for the lift coefficients given by range(cl_start, cl_end, cl_step).
306 |
307 | Parameters
308 | ----------
309 | cl_start, cl_end, cl_step : float
310 | Start, end, and increment lift coefficients for the range.
311 |
312 | Returns
313 | -------
314 | a, cl, cd, cm, co : np.ndarray
315 | Lists of angles of attack and their corresponding lift, drag, moment, and minimum pressure coefficients.
316 | """
317 | n = abs(int((cl_end - cl_start) / cl_step))
318 |
319 | a = np.zeros(n, dtype=c_float)
320 | cl = np.zeros(n, dtype=c_float)
321 | cd = np.zeros(n, dtype=c_float)
322 | cm = np.zeros(n, dtype=c_float)
323 | cp = np.zeros(n, dtype=c_float)
324 | conv = np.zeros(n, dtype=c_bool)
325 |
326 | self._lib.cseq(byref(c_float(cl_start)), byref(c_float(cl_end)), byref(c_int(n)),
327 | a.ctypes.data_as(fptr), cl.ctypes.data_as(fptr),
328 | cd.ctypes.data_as(fptr), cm.ctypes.data_as(fptr),
329 | cp.ctypes.data_as(fptr), conv.ctypes.data_as(bptr))
330 |
331 | isnan = np.logical_not(conv)
332 | a[isnan] = np.nan
333 | cl[isnan] = np.nan
334 | cd[isnan] = np.nan
335 | cm[isnan] = np.nan
336 | cp[isnan] = np.nan
337 | return a.astype(float), cl.astype(float), cd.astype(float), cm.astype(float), cp.astype(float)
338 |
339 | def dump_boundary_layer(self, py_name='boundary_layer.txt'):
340 | """Dump boundary layer data to file.
341 |
342 | Parameters
343 | ----------
344 | fname: str
345 |
346 | Returns
347 | -------
348 | None
349 | """
350 | # Get file name in C format
351 | c_name, string_length = self._py2c_string(py_name)
352 |
353 | # Save it for later postprocessing
354 | self.file_boundary_layer = py_name
355 |
356 | # Compute the boundary layer properties and dump them
357 | self._lib.boundary_layer_dump(c_name, byref(string_length))
358 |
359 | def dump_cp(self, fname='cp.txt'):
360 | """Dump Cp coefficient to file.
361 |
362 | Parameters
363 | ----------
364 | fname: str
365 |
366 | Returns
367 | -------
368 | None
369 |
370 | """
371 | # Get file name length
372 | c_name, string_length = self._py2c_string(fname)
373 |
374 | self._lib.cp_dump(c_name, byref(string_length))
375 |
376 | def _py2c_string(self, fname):
377 | """Convert a Python string to a C char array.
378 |
379 | Parameters
380 | ----------
381 | fname: str
382 |
383 | Returns
384 | -------
385 | c_fname: ctypes.c_char_p
386 | fname as C char pointer
387 |
388 | string_length: ctypes.c_int
389 | string length as C int
390 |
391 | """
392 | # Get file name length
393 | string_length = c_int(len(fname))
394 |
395 | # Create a C char array from the string
396 | c_fname = c_char_p(fname.encode('utf-8'))
397 |
398 | # Return
399 | return c_fname, string_length
400 |
--------------------------------------------------------------------------------