├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README.md ├── naca0012-lift-curve.png ├── 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 ├── 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 ├── model.py ├── test.py └── xfoil.py /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | dist/ 3 | *.egg-info/ 4 | venv/ 5 | .idea/ 6 | cmake-build-debug/ -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 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 | 12 | add_library(xfoil SHARED 13 | # Include modules 14 | src/i_pindex.f90 15 | src/i_xfoil.f90 16 | src/i_blpar.f90 17 | src/i_circle.f90 18 | src/i_xbl.f90 19 | # Shared modules to avoid circular dependencies 20 | src/s_xbl.f90 21 | src/s_xoper.f90 22 | src/s_xfoil.f90 23 | # Main modules 24 | src/m_aread.f90 25 | src/m_iopol.f90 26 | src/m_naca.f90 27 | src/m_sort.f90 28 | src/m_spline.f90 29 | src/m_userio.f90 30 | src/m_xbl.f90 31 | src/m_xblsys.f90 32 | src/m_xfoil.f90 33 | src/m_xgdes.f90 34 | src/m_xgeom.f90 35 | src/m_xmdes.f90 36 | src/m_xoper.f90 37 | src/m_xpanel.f90 38 | src/m_xpol.f90 39 | src/m_xqdes.f90 40 | src/m_xsolve.f90 41 | src/m_xutils.f90 42 | # API 43 | src/api.f90) 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | General 3 | ------- 4 | This is a stripped down version of XFOIL, presented in the form of a Python module. What's unique about this package 5 | w.r.t. many others out there allowing an interface to XFOIL, is the fact that the Python code talks directly to a 6 | compiled Fortran library. This approach avoids having to read/write in-/output files to the disk and communicating with 7 | the XFOIl executable. Eliminating the need for constant disk I/O operations can significantly speed up parallel 8 | frameworks in particular, giving this approach a clear advantage. 9 | 10 | Building and Installing the Python Module 11 | ----------------------------------------- 12 | If you are on a Windows machine (64bit) with Python 3.6, installing XFoil is a simple matter of running: 13 | 14 | ```bash 15 | pip install xfoil 16 | ``` 17 | 18 | If you are using a different type of machine, or a different version of Python, you will have to make sure some 19 | software is installed on your system in order for the package to be successfully built. First of all, the module targets 20 | Python 3, and does NOT support Python 2. So make sure a Python 3 environment is installed and available. 21 | Furthermore, working compilers for C and Fortran have to be installed and on the PATH. On Windows, the build and 22 | installation have ONLY been tested with MinGW, using gcc and gfortran. 23 | 24 | Then, installing XFoil should be as simple as running 25 | 26 | ```bash 27 | pip install . 28 | ``` 29 | 30 | from the root of the downloaded repository. 31 | 32 | On Windows, you may have to force the system to use MinGW. To do so, create a file named `distutils.cfg` in 33 | `PYTHONPATH\Lib\distutils` with the following contents: 34 | 35 | ```INI 36 | [build] 37 | compiler=mingw32 38 | ``` 39 | 40 | If you are not able to create this file for your Python environment, you can instead create a file named `setup.cfg` in 41 | the root of the repo with the same contents. It is also possible to force the use of MinGW directly when invoking 42 | `pip` by calling: 43 | 44 | ```bash 45 | pip install --global-option build_ext --global-option --compiler=mingw32 . 46 | ``` 47 | 48 | Using the Module 49 | ---------------- 50 | All XFoil operations are performed using the `XFoil` class. So the first step when using this module is to create an 51 | instance of this class: 52 | 53 | ```pycon 54 | >>> from xfoil import XFoil 55 | >>> xf = XFoil() 56 | ``` 57 | 58 | If this does not produce any errors, the installation should be functioning properly. 59 | 60 | 61 | The symmetric NACA 0012 airfoil is included as a test case. It can be loaded into the XFoil library like this: 62 | 63 | ```pycon 64 | >>> from xfoil.test import naca0012 65 | >>> xf.airfoil = naca0012 66 | 67 | Number of input coordinate points: 160 68 | Counterclockwise ordering 69 | Max thickness = 0.120008 at x = 0.308 70 | Max camber = 0.000000 at x = 0.033 71 | 72 | LE x,y = -0.00000 0.00000 | Chord = 1.00000 73 | TE x,y = 1.00000 0.00000 | 74 | 75 | Current airfoil nodes set from buffer airfoil nodes ( 160 ) 76 | ``` 77 | 78 | Once the airfoil has been loaded successfully it can be analyzed. Let's analyze it for a range of angles of attack, at a 79 | Reynolds number of one million. Let's limit the maximum number of iterations to 40 (the default is 20) as well. 80 | For the range of angles of attack, we will go from -20 degrees to 20 degrees with steps of 0.5 degrees: 81 | 82 | ```pycon 83 | >>> xf.Re = 1e6 84 | >>> xf.max_iter = 40 85 | >>> a, cl, cd, cm, cp = xf.aseq(-20, 20, 0.5) 86 | ``` 87 | 88 | The XFOIL library should produce a lot of output, which should be familiar to those who have used the original XFOIL 89 | application before. The final result are lists of angles of attack, `a`, and the corresponding lift coefficients, `cl`, 90 | drag coefficients, `cd`, moment coefficients, `cm`, and minimum pressure coefficients `cp`. We can now, for example, plot the lift curve for this airfoil: 91 | 92 | ```pycon 93 | >>> import matplotlib.pyplot as plt 94 | >>> plt.plot(a, cl) 95 | >>> plt.show() 96 | ``` 97 | 98 | This should produce the following figure: 99 | 100 | ![NACA 0012 Lift Curve](https://github.com/daniel-de-vries/xfoil-python/raw/master/naca0012-lift-curve.png) 101 | 102 | Just like in the original XFOIL application, an airfoil can also analyzed for a single angle of attack, single lift 103 | coefficient, or a range of lift coefficients. The commands for these operations are 104 | 105 | ```pycon 106 | >>> cl, cd, cm = xf.a(10) 107 | >>> a, cd, cm = xf.cl(1) 108 | >>> a, cl, cd, cm, cp = xf.cseq(-0.5, 0.5, 0.05) 109 | ``` 110 | 111 | to analyze for an angle of attack of 10 degrees, a lift coefficient of 1.0, and for a range of lift coefficients from 112 | -0.5 to 0.5 with steps of 0.05. 113 | 114 | For other features and specifics, see the documentation in the Python source files. 115 | -------------------------------------------------------------------------------- /naca0012-lift-curve.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DARcorporation/xfoil-python/0a8c2fce02ba73b7f89f72306e43d78291d1e024/naca0012-lift-curve.png -------------------------------------------------------------------------------- /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 | # -*- 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 re 21 | import subprocess 22 | import sys 23 | 24 | from setuptools import setup 25 | from setuptools.extension import Extension 26 | from setuptools.command.build_ext import build_ext 27 | 28 | __version__ = re.findall( 29 | r"""__version__ = ["']+([0-9\.]*)["']+""", 30 | open('xfoil/__init__.py').read(), 31 | )[0] 32 | 33 | options = {k: 'OFF' for k in ['--opt', '--debug', '--cuda']} 34 | for flag in options.keys(): 35 | if flag in sys.argv: 36 | options[flag] = 'ON' 37 | sys.argv.remove(flag) 38 | 39 | # Command line flags forwarded to CMake 40 | cmake_cmd_args = [] 41 | for f in sys.argv: 42 | if f.startswith('-D'): 43 | cmake_cmd_args.append(f) 44 | sys.argv.remove(f) 45 | 46 | 47 | class CMakeExtension(Extension): 48 | 49 | def __init__(self, name, cmake_list_dir='.', **kwargs): 50 | super().__init__(name, sources=[], **kwargs) 51 | self.cmake_lists_dir = os.path.abspath(cmake_list_dir) 52 | 53 | 54 | class CMakeBuild(build_ext): 55 | 56 | def build_extensions(self): 57 | # Ensure that CMake is present and working 58 | try: 59 | out = subprocess.check_output(['cmake', '--version']) 60 | except OSError: 61 | raise RuntimeError('Cannot find CMake executable') 62 | 63 | for ext in self.extensions: 64 | extdir = os.path.abspath(os.path.dirname(self.get_ext_fullpath(ext.name))) 65 | cfg = 'Debug' if options['--debug'] == 'ON' else 'Release' 66 | 67 | cmake_args = [ 68 | '-DCMAKE_BUILD_TYPE=%s' % cfg, 69 | # Ask CMake to place the resulting library in the directory 70 | # containing the extension 71 | '-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}'.format(cfg.upper(), extdir), 72 | # Other intermediate static libraries are placed in a 73 | # temporary build directory instead 74 | '-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_{}={}'.format(cfg.upper(), self.build_temp), 75 | # Hint CMake to use the same Python executable that 76 | # is launching the build, prevents possible mismatching if 77 | # multiple versions of Python are installed 78 | '-DPYTHON_EXECUTABLE={}'.format(sys.executable), 79 | # Add other project-specific CMake arguments if needed 80 | # ... 81 | ] 82 | 83 | # We can handle some platform-specific settings at our discretion 84 | if platform.system() == 'Windows': 85 | plat = ('x64' if platform.architecture()[0] == '64bit' else 'Win32') 86 | cmake_args += [ 87 | # These options are likely to be needed under Windows 88 | '-DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=TRUE', 89 | '-DCMAKE_RUNTIME_OUTPUT_DIRECTORY_{}={}'.format(cfg.upper(), extdir), 90 | ] 91 | # Assuming that Visual Studio and MinGW are supported compilers 92 | if self.compiler.compiler_type == 'msvc': 93 | cmake_args += [ 94 | '-DCMAKE_GENERATOR_PLATFORM=%s' % plat, 95 | ] 96 | else: 97 | cmake_args += [ 98 | '-G', 'MinGW Makefiles', 99 | ] 100 | 101 | cmake_args += cmake_cmd_args 102 | 103 | print(cmake_args) 104 | 105 | if not os.path.exists(self.build_temp): 106 | os.makedirs(self.build_temp) 107 | 108 | # Config and build the extension 109 | subprocess.check_call(['cmake', ext.cmake_lists_dir] + cmake_args, 110 | cwd=self.build_temp) 111 | subprocess.check_call(['cmake', '--build', '.', '--config', cfg], 112 | cwd=self.build_temp) 113 | 114 | 115 | def readme(): 116 | with open('README.md') as f: 117 | return f.read() 118 | 119 | 120 | setup( 121 | name='xfoil', 122 | version=__version__, 123 | description='Stripped down version of XFOIL as compiled python module ', 124 | long_description=readme(), 125 | long_description_content_type='text/markdown', 126 | classifiers=[ 127 | 'Development Status :: 3 - Alpha', 128 | 'Intended Audience :: Science/Research', 129 | 'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)', 130 | 'Natural Language :: English', 131 | 'Operating System :: MacOS :: MacOS X', 132 | 'Operating System :: POSIX :: Linux', 133 | 'Operating System :: Microsoft :: Windows', 134 | 'Programming Language :: Fortran', 135 | 'Programming Language :: Python :: 3 :: Only', 136 | 'Topic :: Scientific/Engineering', 137 | ], 138 | keywords='xfoil airfoil aerodynamic analysis', 139 | url='https://github.com/daniel-de-vries/xfoil-python', 140 | download_url='https://github.com/daniel-de-vries/xfoil-python/tarball/' + __version__, 141 | author='Daniël de Vries', 142 | author_email='contact@daniel-de-vries.com', 143 | license='GNU General Public License v3 or later (GPLv3+)', 144 | packages=['xfoil'], 145 | # package_dir={'': 'src'}, 146 | ext_modules=[CMakeExtension('xfoil.xfoil')], 147 | cmdclass={'build_ext': CMakeBuild}, 148 | install_requires=['numpy'], 149 | zip_safe=False 150 | ) 151 | -------------------------------------------------------------------------------- /src/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 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 | MINf1 = M 207 | 208 | call comset 209 | if (MINf>0.0 .and. show_output) write (*, 99003) CPStar, QSTar / QINf 210 | 99003 format (/' Sonic Cp =', f10.2, ' Sonic Q/Qinf =', f10.3/) 211 | 212 | call cpcalc(N, QINv, QINf, MINf, CPI) 213 | if (LVIsc) call cpcalc(N + NW, QVIs, QINf, MINf, CPV) 214 | call clcalc(N, X, Y, GAM, GAM_a, ALFa, MINf, QINf, XCMref, YCMref, CL, CM, CDP, CL_alf, CL_msq) 215 | call cdcalc 216 | end if 217 | 218 | LVConv = .false. 219 | end subroutine set_mach 220 | 221 | function get_mach() bind(c, name='get_mach') 222 | use i_xfoil, only: MINf 223 | real(c_float) :: get_mach 224 | get_mach = MINf 225 | end function get_mach 226 | 227 | subroutine set_xtr(xtr_top, xtr_bot) bind(c, name='set_xtr') 228 | use i_xfoil, only: XSTrip, LVConv 229 | real(c_float), intent(in) :: xtr_top, xtr_bot 230 | XSTrip(1) = xtr_top 231 | XSTrip(2) = xtr_bot 232 | LVConv = .false. 233 | end subroutine set_xtr 234 | 235 | subroutine get_xtr(xtr_top, xtr_bot) bind(c, name='get_xtr') 236 | use i_xfoil, only: XSTrip 237 | real(c_float) :: xtr_top, xtr_bot 238 | xtr_top = XSTrip(1) 239 | xtr_bot = XSTrip(2) 240 | end subroutine get_xtr 241 | 242 | subroutine set_n_crit(n_crit) bind(c, name='set_n_crit') 243 | use i_xfoil, only: ACRit, LVConv 244 | real(c_float), intent(in) :: n_crit 245 | ACRit(1) = n_crit 246 | ACRit(2) = n_crit 247 | LVConv = .false. 248 | end subroutine set_n_crit 249 | 250 | function get_n_crit() bind(c, name='get_n_crit') 251 | use i_xfoil, only: ACRit 252 | real(c_float) :: get_n_crit 253 | get_n_crit = ACRit(1) 254 | end function get_n_crit 255 | 256 | subroutine set_max_iter(max_iter) bind(c, name='set_max_iter') 257 | use i_xfoil, only: ITMax 258 | integer(c_int), intent(in) :: max_iter 259 | ITMax = max_iter 260 | end subroutine set_max_iter 261 | 262 | function get_max_iter() bind(c, name='get_max_iter') 263 | use i_xfoil, only: ITMax 264 | integer(c_int) :: get_max_iter 265 | get_max_iter = ITMax 266 | end function get_max_iter 267 | 268 | subroutine reset_bls() bind(c, name='reset_bls') 269 | use i_xfoil, only: LBLini, LIPan, show_output 270 | LBLini = .false. 271 | LIPan = .false. 272 | if (show_output) write (*, *) 'BLs will be initialized on next point' 273 | end subroutine reset_bls 274 | 275 | subroutine repanel(n_panel, cv_par, cte_ratio, ctr_ratio, & 276 | xs_ref1, xs_ref2, xp_ref1, xp_ref2) bind(c, name='repanel') 277 | use m_xfoil, only: pangen 278 | use m_xgeom, only: cang 279 | use i_xfoil 280 | 281 | integer :: imax 282 | real :: amax 283 | integer(c_int), intent(in) :: n_panel 284 | real(c_float), intent(in) :: cv_par, cte_ratio, ctr_ratio, xs_ref1, xs_ref2, xp_ref1, xp_ref2 285 | 286 | NPAn = min(n_panel, IQX - 6) 287 | CVPar = cv_par 288 | CTErat = cte_ratio 289 | CTRrat = ctr_ratio 290 | XSRef1 = xs_ref1 291 | XSRef2 = xs_ref2 292 | XPRef1 = xp_ref1 293 | XPRef2 = xp_ref2 294 | 295 | call pangen(.true.) 296 | if (N>0) call cang(X, Y, N, 1, imax, amax) 297 | end subroutine repanel 298 | 299 | subroutine filter(factor) bind(c, name='filter') 300 | use m_xmdes, only: cnfilt, piqsum, qspcir, qspint 301 | use i_xfoil 302 | 303 | real(c_float), intent(in) :: factor 304 | 305 | real :: cfilt, clq 306 | integer :: kqsp 307 | 308 | !----- apply modified Hanning filter to Cn coefficients 309 | cfilt = factor 310 | call cnfilt(cfilt) 311 | call piqsum 312 | call qspcir 313 | 314 | do kqsp = 1, NQSp 315 | call qspint(ALQsp(kqsp), QSPec(1, kqsp), QINf, MINf, clq, CMQsp(kqsp)) 316 | if (IACqsp==1) CLQsp(kqsp) = clq 317 | enddo 318 | LQSppl = .false. 319 | end subroutine filter 320 | 321 | subroutine alfa_(a_input, cl_out, cd_out, cm_out, cp_out, conv) bind(c, name='alfa') 322 | use m_xoper, only: specal, viscal, fcpmin 323 | use i_xfoil 324 | 325 | real(c_float), intent(in) :: a_input 326 | real(c_float), intent(out) :: cl_out, cd_out, cm_out, cp_out 327 | logical(c_bool), intent(out) :: conv 328 | ADEg = a_input 329 | 330 | ALFa = a_input * DTOr 331 | QINf = 1.0 332 | LALfa = .true. 333 | call specal 334 | if (abs(ALFa - AWAke)>1.0E-5) LWAke = .false. 335 | if (abs(ALFa - AVIsc)>1.0E-5) LVConv = .false. 336 | if (abs(MINf - MVIsc)>1.0E-5) LVConv = .false. 337 | ! 338 | if (LVIsc) then 339 | conv = viscal(ITMax) 340 | conv = LVConv .and. conv 341 | else 342 | conv = .true. 343 | end if 344 | 345 | cl_out = CL 346 | cd_out = CD 347 | cm_out = CM 348 | 349 | call fcpmin 350 | cp_out = CPMn 351 | end subroutine alfa_ 352 | 353 | subroutine cl_(cl_input, a_out, cd_out, cm_out, cp_out, conv) bind(c, name='cl') 354 | use m_xoper, only: speccl, viscal, fcpmin 355 | use i_xfoil 356 | 357 | real(c_float), intent(in) :: cl_input 358 | real(c_float), intent(out) :: a_out, cd_out, cm_out, cp_out 359 | logical(c_bool), intent(out) :: conv 360 | 361 | CLSpec = cl_input 362 | ALFa = 0.0 363 | QINf = 1.0 364 | LALfa = .false. 365 | call speccl 366 | ADEg = ALFa / DTOr 367 | if (abs(ALFa - AWAke)>1.0E-5) LWAke = .false. 368 | if (abs(ALFa - AVIsc)>1.0E-5) LVConv = .false. 369 | if (abs(MINf - MVIsc)>1.0E-5) LVConv = .false. 370 | 371 | if (LVIsc) then 372 | conv = viscal(ITMax) 373 | conv = LVConv .and. conv 374 | else 375 | conv = .true. 376 | end if 377 | 378 | a_out = ALFa / DTOr 379 | cd_out = CD 380 | cm_out = CM 381 | 382 | call fcpmin 383 | cp_out = CPMn 384 | end subroutine cl_ 385 | 386 | subroutine aseq(a_start, a_end, n_step, & 387 | a_arr, cl_arr, cd_arr, cm_arr, cp_arr, conv_arr) bind(c, name='aseq') 388 | use m_xoper, only: specal, viscal, fcpmin 389 | use i_xfoil 390 | real(c_float), intent(in) :: a_start, a_end 391 | integer(c_int), intent(in) :: n_step 392 | real(c_float), dimension(n_step), intent(inout) :: a_arr, cl_arr, cd_arr, cm_arr, cp_arr 393 | logical(c_bool), dimension(n_step), intent(inout) :: conv_arr 394 | integer :: i, j, iseqex, itmaxs 395 | real :: a0, da, nan 396 | 397 | nan = 0 398 | nan = 0/nan 399 | 400 | a0 = a_start * DTOr 401 | da = (a_end - a_start) / float(n_step) * DTOr 402 | 403 | LALfa = .true. 404 | 405 | !----- initialize unconverged-point counter 406 | iseqex = 0 407 | 408 | do i=1, n_step 409 | ALFa = a0 + da * float(i - 1) 410 | if (abs(ALFa - AWAke)>1.0E-5) LWAke = .false. 411 | if (abs(ALFa - AVIsc)>1.0E-5) LVConv = .false. 412 | if (abs(MINf - MVIsc)>1.0E-5) LVConv = .false. 413 | call specal 414 | itmaxs = ITMax + 5 415 | if (LVIsc) then 416 | conv_arr(i) = viscal(itmaxs) 417 | end if 418 | ADEg = ALFa / DTOr 419 | 420 | a_arr(i) = ADEg 421 | cl_arr(i) = CL 422 | cd_arr(i) = CD 423 | cm_arr(i) = CM 424 | 425 | call fcpmin 426 | cp_arr(i) = CPMn 427 | 428 | if ((LVConv .and. conv_arr(i)) .or. .not.LVIsc) then 429 | conv_arr(i) = .true. 430 | elseif (LVIsc .and. .not. (LVConv .and. conv_arr(i))) then 431 | conv_arr(i) = .false. 432 | endif 433 | end do 434 | end subroutine aseq 435 | 436 | subroutine cseq(cl_start, cl_end, n_step, & 437 | a_arr, cl_arr, cd_arr, cm_arr, cp_arr, conv_arr) bind(c, name='cseq') 438 | use m_xoper, only: specal, viscal, speccl, fcpmin 439 | use i_xfoil 440 | real(c_float), intent(in) :: cl_start, cl_end 441 | integer(c_int), intent(in) :: n_step 442 | real(c_float), dimension(n_step), intent(inout) :: a_arr, cl_arr, cd_arr, cm_arr, cp_arr 443 | logical(c_bool), dimension(n_step), intent(inout) :: conv_arr 444 | integer :: i, j, iseqex, itmaxs 445 | real :: cl0, dcl 446 | 447 | cl0 = cl_start 448 | dcl = (cl_end - cl_start) / float(n_step) 449 | LALfa = .false. 450 | 451 | !----- initialize unconverged-point counter 452 | iseqex = 0 453 | 454 | do i=1, n_step 455 | CLSpec = cl0 + dcl * float(i - 1) 456 | call speccl 457 | if (abs(ALFa - AWAke)>1.0E-5) LWAke = .false. 458 | if (abs(ALFa - AVIsc)>1.0E-5) LVConv = .false. 459 | if (abs(MINf - MVIsc)>1.0E-5) LVConv = .false. 460 | 461 | itmaxs = ITMax + 5 462 | if (LVIsc) then 463 | conv_arr(i) = viscal(itmaxs) 464 | end if 465 | ADEg = ALFa / DTOr 466 | 467 | a_arr(i) = ADEg 468 | cl_arr(i) = CL 469 | cd_arr(i) = CD 470 | cm_arr(i) = CM 471 | 472 | call fcpmin 473 | cp_arr(i) = CPMn 474 | 475 | if ((LVConv .and. conv_arr(i)) .or. .not.LVIsc) then 476 | conv_arr(i) = .true. 477 | elseif (LVIsc .and. .not. (LVConv .and. conv_arr(i))) then 478 | conv_arr(i) = .false. 479 | endif 480 | end do 481 | end subroutine cseq 482 | 483 | 484 | function get_n_cp() bind(c, name='get_n_cp') 485 | use i_xfoil, only: N 486 | integer(c_int) :: get_n_cp 487 | get_n_cp = N 488 | end function get_n_cp 489 | 490 | subroutine get_cp(x_out, y_out, cp_out, n_points) bind(c, name='get_cp') 491 | use s_xfoil, only: comset 492 | use m_xoper 493 | use i_xfoil 494 | implicit none 495 | 496 | integer(c_int), intent(in) :: n_points 497 | real(c_float), dimension(n_points), intent(inout) :: x_out, y_out, cp_out 498 | 499 | real :: beta, bfac, cpcom, cpinc, den 500 | integer :: i 501 | 502 | call comset 503 | beta = sqrt(1.0 - MINf**2) 504 | bfac = 0.5 * MINf**2 / (1.0 + beta) 505 | 506 | do i = 1, N 507 | cpinc = 1.0 - (GAM(i) / QINf)**2 508 | den = beta + bfac * cpinc 509 | cp_out(i) = cpinc / den 510 | x_out(i) = X(i) 511 | y_out(i) = Y(i) 512 | enddo 513 | end subroutine get_cp 514 | 515 | end module api 516 | -------------------------------------------------------------------------------- /src/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/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/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/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/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/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/m_xqdes.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_XQDES.f90 processed by SPAG 7.21DC at 11:25 on 11 Jan 2019 22 | ! 23 | module m_xqdes 24 | implicit none 25 | ! 26 | !*** Start of declarations rewritten by SPAG 27 | ! 28 | !*** End of declarations rewritten by SPAG 29 | ! 30 | contains 31 | subroutine qdes 32 | use s_xfoil, only: clcalc, tecalc 33 | use m_xpanel, only: apcalc, ncalc 34 | use m_xoper, only: specal 35 | use m_xgeom, only: lefind 36 | use m_userio, only: getflt, askc, getint 37 | use m_spline, only: seval, splind, scalc 38 | use i_xfoil 39 | implicit none 40 | ! 41 | !*** Start of declarations rewritten by SPAG 42 | ! 43 | ! Local variables 44 | ! 45 | character(128), save :: argold 46 | real :: cdpq, chsq, chx, chy, clq_alf, clq_msq, g 47 | character(4) :: comand 48 | character(128) :: comarg 49 | character(4), save :: comold 50 | logical :: error, lrecalc 51 | integer :: i, kqsp, ninput, ntqspl 52 | integer, dimension(20) :: iinput 53 | real :: qcomp 54 | real, dimension(20) :: rinput 55 | ! 56 | !*** End of declarations rewritten by SPAG 57 | ! 58 | ! 59 | !*** Start of declarations rewritten by SPAG 60 | ! 61 | ! Local variables 62 | ! 63 | ! 64 | !*** End of declarations rewritten by SPAG 65 | ! 66 | !------------------------------------------------------ 67 | ! Mixed-Inverse design routine. Based on the 68 | ! same panel formulation as basic analysis method. 69 | !------------------------------------------------------ 70 | ! 71 | ! 72 | ! 73 | ! 74 | ! 75 | !---- statement function for compressible Karman-Tsien velocity 76 | qcomp(g) = g * (1.0 - TKLam) / (1.0 - TKLam * (g / QINf)**2) 77 | ! 78 | ! 79 | comand = '****' 80 | comarg = ' ' 81 | lrecalc = .false. 82 | ! 83 | if (N==0) then 84 | if (show_output) then 85 | write (*, *) 86 | write (*, *) '*** No airfoil available ***' 87 | endif 88 | return 89 | endif 90 | ! 91 | LSYm = .true. 92 | ! 93 | !---- number of sub-intervals for Qspec(s) plotting 94 | ntqspl = 1 95 | if (LQSlop) ntqspl = 8 96 | ! 97 | !---- make sure a current solution exists 98 | call specal 99 | ! 100 | !---- see if current Qspec, if any, didn't come from Full-Inverse 101 | if (NSP/=N) then 102 | LQSpec = .false. 103 | LIQset = .false. 104 | endif 105 | ! 106 | !---- set alpha, etc corresponding to Q 107 | ALGam = ALFa 108 | CLGam = CL 109 | CMGam = CM 110 | ! 111 | !---- set "old" speed distribution Q, arc length, and x/c,y/c arrays 112 | chx = XTE - XLE 113 | chy = YTE - YLE 114 | chsq = chx**2 + chy**2 115 | NSP = N 116 | do i = 1, NSP 117 | QGAmm(i) = GAM(i) 118 | SSPec(i) = S(i) / S(N) 119 | XSPoc(i) = ((X(i) - XLE) * chx + (Y(i) - YLE) * chy) / chsq 120 | YSPoc(i) = ((Y(i) - YLE) * chx - (X(i) - XLE) * chy) / chsq 121 | enddo 122 | SSPle = SLE / S(N) 123 | ! 124 | if (show_output) write (*, 99001) ALGam / DTOr, CLGam 125 | 99001 format (/' Current Q operating condition:'/' alpha = ', f8.3, ' deg. CL = ', f8.4/) 126 | ! 127 | if (.not.LQSpec) then 128 | !----- initialize Qspec to "old" solution and notify user 129 | NQSp = 1 130 | KQTarg = 1 131 | call gamqsp(1) 132 | if (show_output) write (*, 99002) 133 | ! 134 | !.................................................... 135 | ! 136 | 99002 format (/' Qspec initialized to current Q.'/) 137 | LQSpec = .true. 138 | endif 139 | do 140 | ! 141 | ! 142 | !==================================================== 143 | !---- start of menu loop 144 | comold = comand 145 | argold = comarg 146 | do 147 | ! 148 | call askc('.QDES^', comand, comarg) 149 | ! 150 | !-------------------------------------------------------- 151 | !---- process previous command ? 152 | if (comand(1:1)/='!') then 153 | lrecalc = .false. 154 | elseif (comold=='****') then 155 | if (show_output) write (*, *) 'Previous .QDES command not valid' 156 | cycle 157 | else 158 | comand = comold 159 | comarg = argold 160 | lrecalc = .true. 161 | endif 162 | ! 163 | !----- just was typed... clean up plotting and exit OPER 164 | if (comand==' ') return 165 | ! 166 | !---- extract command line numeric arguments 167 | do i = 1, 20 168 | iinput(i) = 0 169 | rinput(i) = 0.0 170 | enddo 171 | ninput = 0 172 | call getint(comarg, iinput, ninput, error) 173 | ninput = 0 174 | call getflt(comarg, rinput, ninput, error) 175 | ! 176 | !-------------------------------------------------------- 177 | if (comand=='? ') then 178 | if (show_output) write (*, 99003) 179 | 99003 format (& 180 | /' Return to Top Level'& 181 | //' QSET Reset Qspec <== Q'& 182 | /' SMOO Smooth Qspec inside target segment'& 183 | /' SLOP Toggle modified-Qspec slope matching flag'& 184 | /' REST Restore geometry from buffer airfoil'& 185 | /' CPXX CPxx endpoint constraint toggle') 186 | ! 187 | !-------------------------------------------------------- 188 | !---- re-initialize Qspec to Q 189 | elseif (comand=='QSET') then 190 | call gamqsp(1) 191 | ! 192 | !-------------------------------------------------------- 193 | !---- smooth Qspec within target segment, or entire Qspec if not marked off 194 | elseif (comand=='SMOO') then 195 | ! 196 | kqsp = 1 197 | call smooq(IQ1, IQ2, kqsp) 198 | call splqsp(kqsp) 199 | ! 200 | call clcalc(N, X, Y, QSPec(1, kqsp), W1, ALFa, MINf, QINf, & 201 | XCMref, YCMref, CLQsp(kqsp), CMQsp(kqsp), cdpq, clq_alf, clq_msq) 202 | if (show_output) write (*, 99004) CL, CM, CLQsp(kqsp), CMQsp(kqsp) 203 | 99004 format (/' Q : CL =', f11.6, ' CM =', f11.6/& 204 | ' Qspec: CL =', f11.6, ' CM =', f11.6) 205 | ! 206 | !-------------------------------------------------------- 207 | !---- toggle Qspec endpoint slope matching 208 | elseif (comand=='SLOP') then 209 | LQSlop = .not.LQSlop 210 | if (LQSlop) then 211 | if (show_output) write (*, *) 'Modified Qspec piece will be made tangent at endpoints' 212 | else 213 | if (show_output) write (*, *) 'Modified Qspec piece will not be made tangent at endpoints' 214 | endif 215 | ! 216 | !-------------------------------------------------------- 217 | !---- toggle CPxx preservation constraints 218 | elseif (comand=='CPXX') then 219 | LCPxx = .not.LCPxx 220 | if (LCPxx) then 221 | if (show_output) write (*, *) 'CPxx will be constrained' 222 | else 223 | if (show_output) write (*, *) 'CPxx will not be constrained' 224 | endif 225 | ! 226 | !-------------------------------------------------------- 227 | !---- restore and spline old airfoil 228 | elseif (comand=='REST') then 229 | do i = 1, N 230 | X(i) = XB(i) 231 | Y(i) = YB(i) 232 | enddo 233 | call scalc(X, Y, S, N) 234 | call splind(X, XP, S, N, -999.0, -999.0) 235 | call splind(Y, YP, S, N, -999.0, -999.0) 236 | call ncalc(X, Y, S, N, NX, NY) 237 | call lefind(SLE, X, XP, Y, YP, S, N) 238 | XLE = seval(SLE, X, XP, S, N) 239 | YLE = seval(SLE, Y, YP, S, N) 240 | CHOrd = sqrt((0.5 * (X(1) + X(N)) - XLE)**2 + (0.5 * (Y(1) + Y(N)) - YLE)**2) 241 | call tecalc 242 | call apcalc 243 | LGAmu = .false. 244 | LQInu = .false. 245 | LGSame = .true. 246 | ! 247 | !c CALL NAMMOD(NAME,-1,1) 248 | !c CALL STRIP(NAME,NNAME) 249 | ! 250 | !-------------------------------------------------------- 251 | else 252 | if (show_output) write (*, 99005) comand 253 | 99005 format (' Command ', a4, ' not recognized. Type a " ? " for list.') 254 | ! 255 | comand = '****' 256 | endif 257 | ! 258 | goto 100 259 | enddo 260 | exit 261 | 100 enddo 262 | end subroutine qdes 263 | 264 | 265 | subroutine splqsp(Kqsp) 266 | use m_spline, only: splind 267 | use i_xfoil 268 | implicit none 269 | ! 270 | !*** Start of declarations rewritten by SPAG 271 | ! 272 | ! Dummy arguments 273 | ! 274 | integer :: Kqsp 275 | intent (in) Kqsp 276 | ! 277 | ! Local variables 278 | ! 279 | integer :: i 280 | ! 281 | !*** End of declarations rewritten by SPAG 282 | ! 283 | ! 284 | !*** Start of declarations rewritten by SPAG 285 | ! 286 | ! Dummy arguments 287 | ! 288 | ! 289 | ! Local variables 290 | ! 291 | ! 292 | !*** End of declarations rewritten by SPAG 293 | ! 294 | !------------------------------------------------------ 295 | ! Splines Qspec(s). The end intervals are treated 296 | ! specially to avoid Gibbs-type problems from 297 | ! blindly splining to the stagnation point. 298 | !------------------------------------------------------ 299 | ! 300 | !---- usual spline with natural end BCs 301 | call splind(QSPec(2, Kqsp), QSPecp(2, Kqsp), SSPec(2), NSP - 2, -999.0, -999.0) 302 | ! 303 | !cC---- pseudo-monotonic spline with simple secant slope calculation 304 | !c CALL SPLINA(QSPEC(2,KQSP),QSPECP(2,KQSP),SSPEC(2),NSP-2) 305 | ! 306 | !---- end intervals are splined separately with natural BCs at 307 | ! the trailing edge and matching slopes at the interior points 308 | ! 309 | i = 1 310 | call splind(QSPec(i, Kqsp), QSPecp(i, Kqsp), SSPec(i), 2, -999.0, QSPecp(i + 1, Kqsp)) 311 | ! 312 | i = NSP - 1 313 | call splind(QSPec(i, Kqsp), QSPecp(i, Kqsp), SSPec(i), 2, QSPecp(i, Kqsp), -999.0) 314 | ! 315 | end subroutine splqsp 316 | 317 | 318 | subroutine smooq(Kq1, Kq2, Kqsp) 319 | use m_spline, only: trisol 320 | use i_xfoil 321 | implicit none 322 | ! 323 | !*** Start of declarations rewritten by SPAG 324 | ! 325 | ! Dummy arguments 326 | ! 327 | integer :: Kq1, Kq2, Kqsp 328 | intent (in) Kq1, Kq2, Kqsp 329 | ! 330 | ! Local variables 331 | ! 332 | real :: ds, dsm, dso, dsp, qspp1, qspp2, smool, smoosq 333 | integer :: i 334 | ! 335 | !*** End of declarations rewritten by SPAG 336 | ! 337 | ! 338 | !*** Start of declarations rewritten by SPAG 339 | ! 340 | ! Dummy arguments 341 | ! 342 | ! 343 | ! Local variables 344 | ! 345 | ! 346 | !*** End of declarations rewritten by SPAG 347 | ! 348 | !-------------------------------------------- 349 | ! Smooths Qspec(s) inside target segment 350 | !-------------------------------------------- 351 | ! 352 | !C---- calculate smoothing coordinate 353 | !cc IF(NSP.EQ.NC1) THEN 354 | !C 355 | !C------ mapping inverse: use circle plane coordinate 356 | ! I = 1 357 | ! W8(I) = 0.0 358 | ! DO 10 I=2, NSP 359 | ! SINW = 2.0*SIN( 0.25*(WC(I)+WC(I-1)) ) 360 | ! SINWE = SINW**(1.0-AGTE) 361 | !C 362 | ! DSDW = SINWE * EXP( REAL(0.5*(PIQ(I)+PIQ(I-1)) )) 363 | ! W8(I) = W8(I-1) + (WC(I)-WC(I-1))/DSDW 364 | ! 10 CONTINUE 365 | ! DO 11 I=1, NSP 366 | ! W8(I) = W8(I)/W8(NSP) 367 | ! 11 CONTINUE 368 | !C 369 | !C------ do not smooth first and last intervals in circle plane 370 | ! KQ1 = MAX(IQ1,2) 371 | ! KQ2 = MIN(IQ2,NSP-1) 372 | !C 373 | !cc ELSE 374 | ! 375 | !------ mixed inverse: use arc length coordinate 376 | do i = 1, NSP 377 | W8(i) = SSPec(i) 378 | enddo 379 | ! 380 | !cc ENDIF 381 | ! 382 | ! 383 | if (Kq2 - Kq1<2) then 384 | if (show_output) write (*, *) 'Segment is too short. No smoothing possible.' 385 | return 386 | endif 387 | ! 388 | !---- set smoothing length ( ~ distance over which data is smeared ) 389 | smool = 0.002 * (W8(NSP) - W8(1)) 390 | !CC CALL ASKR('Enter Qspec smoothing length^',SMOOL) 391 | ! 392 | !---- set up tri-diagonal system for smoothed Qspec 393 | smoosq = smool**2 394 | do i = Kq1 + 1, Kq2 - 1 395 | dsm = W8(i) - W8(i - 1) 396 | dsp = W8(i + 1) - W8(i) 397 | dso = 0.5 * (W8(i + 1) - W8(i - 1)) 398 | ! 399 | W1(i) = smoosq * (-1.0 / dsm) / dso 400 | W2(i) = smoosq * (1.0 / dsp + 1.0 / dsm) / dso + 1.0 401 | W3(i) = smoosq * (-1.0 / dsp) / dso 402 | enddo 403 | ! 404 | !---- set fixed-Qspec end conditions 405 | W2(Kq1) = 1.0 406 | W3(Kq1) = 0.0 407 | ! 408 | W1(Kq2) = 0.0 409 | W2(Kq2) = 1.0 410 | ! 411 | if (LQSlop) then 412 | !----- also enforce slope matching at endpoints 413 | i = Kq1 + 1 414 | dsm = W8(i) - W8(i - 1) 415 | dsp = W8(i + 1) - W8(i) 416 | ds = W8(i + 1) - W8(i - 1) 417 | W1(i) = -1.0 / dsm - (dsm / ds) / dsm 418 | W2(i) = 1.0 / dsm + (dsm / ds) / dsm + (dsm / ds) / dsp 419 | W3(i) = -(dsm / ds) / dsp 420 | qspp1 = W1(i) * QSPec(i - 1, Kqsp) + W2(i) * QSPec(i, Kqsp) + W3(i) * QSPec(i + 1, Kqsp) 421 | ! 422 | i = Kq2 - 1 423 | dsm = W8(i) - W8(i - 1) 424 | dsp = W8(i + 1) - W8(i) 425 | ds = W8(i + 1) - W8(i - 1) 426 | W1(i) = (dsp / ds) / dsm 427 | W2(i) = -1.0 / dsp - (dsp / ds) / dsp - (dsp / ds) / dsm 428 | W3(i) = 1.0 / dsp + (dsp / ds) / dsp 429 | qspp2 = W1(i) * QSPec(i - 1, Kqsp) + W2(i) * QSPec(i, Kqsp) + W3(i) * QSPec(i + 1, Kqsp) 430 | ! 431 | QSPec(Kq1 + 1, Kqsp) = qspp1 432 | QSPec(Kq2 - 1, Kqsp) = qspp2 433 | endif 434 | ! 435 | ! 436 | !---- solve for smoothed Qspec array 437 | call trisol(W2(Kq1), W1(Kq1), W3(Kq1), QSPec(Kq1, Kqsp), (Kq2 - Kq1 + 1)) 438 | ! 439 | ! 440 | !c IF(LQSYM) THEN 441 | !c DO 40 I=KQ1+1, KQ2-1 442 | !c QSPEC(NSP-I+1,KQSP) = -QSPEC(I,KQSP) 443 | !c 40 CONTINUE 444 | !c ENDIF 445 | ! 446 | end subroutine smooq 447 | 448 | 449 | function qincom(Qc, Qinf, Tklam) 450 | implicit none 451 | ! 452 | !*** Start of declarations rewritten by SPAG 453 | ! 454 | ! Dummy arguments 455 | ! 456 | real :: Qc, Qinf, Tklam 457 | real :: qincom 458 | intent (in) Qc, Qinf, Tklam 459 | ! 460 | ! Local variables 461 | ! 462 | real :: tmp 463 | ! 464 | !*** End of declarations rewritten by SPAG 465 | ! 466 | ! 467 | !*** Start of declarations rewritten by SPAG 468 | ! 469 | ! Dummy arguments 470 | ! 471 | ! 472 | ! Local variables 473 | ! 474 | ! 475 | !*** End of declarations rewritten by SPAG 476 | ! 477 | !------------------------------------- 478 | ! Sets incompressible speed from 479 | ! Karman-Tsien compressible speed 480 | !------------------------------------- 481 | ! 482 | if (Tklam<1.0E-4 .or. abs(Qc)<1.0E-4) then 483 | !----- for nearly incompressible case or very small speed, use asymptotic 484 | ! expansion of singular quadratic formula to avoid numerical problems 485 | qincom = Qc / (1.0 - Tklam) 486 | else 487 | !----- use quadratic formula for typical case 488 | tmp = 0.5 * (1.0 - Tklam) * Qinf / (Qc * Tklam) 489 | qincom = Qinf * tmp * (sqrt(1.0 + 1.0 / (Tklam * tmp**2)) - 1.0) 490 | endif 491 | end function qincom 492 | 493 | 494 | subroutine gamqsp(Kqsp) 495 | use i_xfoil 496 | implicit none 497 | ! 498 | !*** Start of declarations rewritten by SPAG 499 | ! 500 | ! Dummy arguments 501 | ! 502 | integer :: Kqsp 503 | ! 504 | ! Local variables 505 | ! 506 | integer :: i 507 | ! 508 | !*** End of declarations rewritten by SPAG 509 | ! 510 | ! 511 | !*** Start of declarations rewritten by SPAG 512 | ! 513 | ! Dummy arguments 514 | ! 515 | ! 516 | ! Local variables 517 | ! 518 | ! 519 | !*** End of declarations rewritten by SPAG 520 | ! 521 | !------------------------------------------------ 522 | ! Sets Qspec(s,k) from current speed Q(s). 523 | !------------------------------------------------ 524 | ! 525 | ALQsp(Kqsp) = ALGam 526 | CLQsp(Kqsp) = CLGam 527 | CMQsp(Kqsp) = CMGam 528 | ! 529 | do i = 1, NSP 530 | QSPec(i, Kqsp) = QGAmm(i) 531 | enddo 532 | ! 533 | !---- zero out Qspec DOFs 534 | QDOf0 = 0.0 535 | QDOf1 = 0.0 536 | QDOf2 = 0.0 537 | QDOf3 = 0.0 538 | ! 539 | call splqsp(Kqsp) 540 | ! 541 | !---- reset target segment endpoints 542 | if (.not.LIQset) then 543 | IQ1 = 1 544 | IQ2 = NSP 545 | endif 546 | ! 547 | end subroutine gamqsp 548 | 549 | end module m_xqdes 550 | -------------------------------------------------------------------------------- /src/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/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/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/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/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 | 20 | __version__ = "1.1.1" 21 | -------------------------------------------------------------------------------- /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 | 21 | class Airfoil(object): 22 | """Airfoil 23 | 24 | Attributes 25 | ---------- 26 | n_coords 27 | x 28 | y 29 | """ 30 | 31 | def __init__(self, x, y): 32 | super().__init__() 33 | self.coords = np.ndarray((0, 2)) 34 | self.x = x 35 | self.y = y 36 | 37 | @property 38 | def n_coords(self): 39 | """int: Number of coordinates which define the airfoil surface.""" 40 | return self.coords.shape[0] 41 | 42 | @property 43 | def x(self): 44 | """np.ndarray: List of x-coordinates of the airfoil surface.""" 45 | return self.coords[:, 0] 46 | 47 | @x.setter 48 | def x(self, value): 49 | v = value.flatten() 50 | self.coords = np.resize(self.coords, (v.size, 2)) 51 | self.coords[:, 0] = v[:] 52 | 53 | @property 54 | def y(self): 55 | """np.ndarray: List of y-coordinates of the airfoil surface.""" 56 | return self.coords[:, 1] 57 | 58 | @y.setter 59 | def y(self, value): 60 | v = value.flatten() 61 | self.coords = np.resize(self.coords, (v.size, 2)) 62 | self.coords[:, 1] = v[:] 63 | -------------------------------------------------------------------------------- /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 .model import Airfoil 23 | 24 | naca0012 = Airfoil( 25 | 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, 26 | +8.8821e-01, +8.7160e-01, +8.5494e-01, +8.3827e-01, +8.2158e-01, +8.0488e-01, +7.8817e-01, +7.7146e-01, 27 | +7.5475e-01, +7.3803e-01, +7.2132e-01, +7.0460e-01, +6.8789e-01, +6.7118e-01, +6.5447e-01, +6.3777e-01, 28 | +6.2108e-01, +6.0440e-01, +5.8772e-01, +5.7106e-01, +5.5441e-01, +5.3778e-01, +5.2116e-01, +5.0456e-01, 29 | +4.8798e-01, +4.7143e-01, +4.5489e-01, +4.3839e-01, +4.2191e-01, +4.0546e-01, +3.8905e-01, +3.7268e-01, 30 | +3.5635e-01, +3.4007e-01, +3.2383e-01, +3.0766e-01, +2.9154e-01, +2.7550e-01, +2.5953e-01, +2.4366e-01, 31 | +2.2788e-01, +2.1222e-01, +1.9670e-01, +1.8135e-01, +1.6619e-01, +1.5127e-01, +1.3666e-01, +1.2246e-01, 32 | +1.0877e-01, +9.5752e-02, +8.3582e-02, +7.2423e-02, +6.2395e-02, +5.3537e-02, +4.5806e-02, +3.9101e-02, 33 | +3.3294e-02, +2.8256e-02, +2.3867e-02, +2.0028e-02, +1.6658e-02, +1.3692e-02, +1.1080e-02, +8.7858e-03, 34 | +6.7811e-03, +5.0484e-03, +3.5772e-03, +2.3627e-03, +1.4037e-03, +6.9909e-04, +2.4355e-04, +2.6000e-05, 35 | +2.6000e-05, +2.4355e-04, +6.9909e-04, +1.4037e-03, +2.3627e-03, +3.5772e-03, +5.0484e-03, +6.7811e-03, 36 | +8.7858e-03, +1.1080e-02, +1.3692e-02, +1.6658e-02, +2.0028e-02, +2.3867e-02, +2.8256e-02, +3.3294e-02, 37 | +3.9101e-02, +4.5806e-02, +5.3537e-02, +6.2395e-02, +7.2423e-02, +8.3582e-02, +9.5752e-02, +1.0877e-01, 38 | +1.2246e-01, +1.3666e-01, +1.5127e-01, +1.6619e-01, +1.8135e-01, +1.9670e-01, +2.1222e-01, +2.2788e-01, 39 | +2.4366e-01, +2.5953e-01, +2.7550e-01, +2.9154e-01, +3.0766e-01, +3.2383e-01, +3.4007e-01, +3.5635e-01, 40 | +3.7268e-01, +3.8905e-01, +4.0546e-01, +4.2191e-01, +4.3839e-01, +4.5489e-01, +4.7143e-01, +4.8798e-01, 41 | +5.0456e-01, +5.2116e-01, +5.3778e-01, +5.5441e-01, +5.7106e-01, +5.8772e-01, +6.0440e-01, +6.2108e-01, 42 | +6.3777e-01, +6.5447e-01, +6.7118e-01, +6.8789e-01, +7.0460e-01, +7.2132e-01, +7.3803e-01, +7.5475e-01, 43 | +7.7146e-01, +7.8817e-01, +8.0488e-01, +8.2158e-01, +8.3827e-01, +8.5494e-01, +8.7160e-01, +8.8821e-01, 44 | +9.0474e-01, +9.2112e-01, +9.3720e-01, +9.5272e-01, +9.6727e-01, +9.8037e-01, +9.9168e-01, +1.0000e+00] 45 | ), 46 | 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, 47 | +1.5936e-02, +1.7956e-02, +1.9943e-02, +2.1894e-02, +2.3810e-02, +2.5689e-02, +2.7532e-02, +2.9338e-02, 48 | +3.1107e-02, +3.2839e-02, +3.4534e-02, +3.6190e-02, +3.7807e-02, +3.9384e-02, +4.0921e-02, +4.2415e-02, 49 | +4.3865e-02, +4.5271e-02, +4.6630e-02, +4.7940e-02, +4.9199e-02, +5.0406e-02, +5.1557e-02, +5.2650e-02, 50 | +5.3683e-02, +5.4652e-02, +5.5554e-02, +5.6385e-02, +5.7143e-02, +5.7822e-02, +5.8419e-02, +5.8930e-02, 51 | +5.9349e-02, +5.9671e-02, +5.9891e-02, +6.0004e-02, +6.0002e-02, +5.9879e-02, +5.9628e-02, +5.9241e-02, 52 | +5.8710e-02, +5.8027e-02, +5.7181e-02, +5.6164e-02, +5.4967e-02, +5.3580e-02, +5.1997e-02, +5.0216e-02, 53 | +4.8243e-02, +4.6095e-02, +4.3805e-02, +4.1422e-02, +3.9000e-02, +3.6592e-02, +3.4237e-02, +3.1957e-02, 54 | +2.9760e-02, +2.7644e-02, +2.5598e-02, +2.3613e-02, +2.1675e-02, +1.9770e-02, +1.7888e-02, +1.6017e-02, 55 | +1.4147e-02, +1.2270e-02, +1.0381e-02, +8.4792e-03, +6.5676e-03, +4.6570e-03, +2.7615e-03, +9.0564e-04, 56 | -9.0564e-04, -2.7615e-03, -4.6570e-03, -6.5676e-03, -8.4792e-03, -1.0381e-02, -1.2270e-02, -1.4147e-02, 57 | -1.6017e-02, -1.7888e-02, -1.9770e-02, -2.1675e-02, -2.3613e-02, -2.5598e-02, -2.7644e-02, -2.9760e-02, 58 | -3.1957e-02, -3.4237e-02, -3.6592e-02, -3.9000e-02, -4.1422e-02, -4.3805e-02, -4.6095e-02, -4.8243e-02, 59 | -5.0216e-02, -5.1997e-02, -5.3580e-02, -5.4967e-02, -5.6164e-02, -5.7181e-02, -5.8027e-02, -5.8710e-02, 60 | -5.9241e-02, -5.9628e-02, -5.9879e-02, -6.0002e-02, -6.0004e-02, -5.9891e-02, -5.9671e-02, -5.9349e-02, 61 | -5.8930e-02, -5.8419e-02, -5.7822e-02, -5.7143e-02, -5.6385e-02, -5.5554e-02, -5.4652e-02, -5.3683e-02, 62 | -5.2650e-02, -5.1557e-02, -5.0406e-02, -4.9199e-02, -4.7940e-02, -4.6630e-02, -4.5271e-02, -4.3865e-02, 63 | -4.2415e-02, -4.0921e-02, -3.9384e-02, -3.7807e-02, -3.6190e-02, -3.4534e-02, -3.2839e-02, -3.1107e-02, 64 | -2.9338e-02, -2.7532e-02, -2.5689e-02, -2.3810e-02, -2.1894e-02, -1.9943e-02, -1.7956e-02, -1.5936e-02, 65 | -1.3886e-02, -1.1815e-02, -9.7433e-03, -7.7062e-03, -5.7619e-03, -3.9814e-03, -2.4215e-03, -1.2600e-03] 66 | ) 67 | ) 68 | 69 | 70 | class TestXFoil(unittest.TestCase): 71 | """Test whether the XFOIL module functions properly.""" 72 | 73 | def assertNumpyArraysAlmostEqual(self, first, second, decimal, msg=''): 74 | for i in range(first.size): 75 | self.assertAlmostEqual(first[i], second[i], decimal, msg) 76 | 77 | def test_a(self): 78 | """Analyse the NACA 0012 at Re = 1e6, M = 0, α = 10 degrees and verify the results.""" 79 | xf = XFoil() 80 | xf.airfoil = naca0012 81 | xf.Re = 1e6 82 | xf.max_iter = 100 83 | cl, cd, cm, cp = xf.a(10) 84 | 85 | self.assertAlmostEqual(cl, 1.0809, 4) 86 | self.assertAlmostEqual(cd, 0.0150, 4) 87 | self.assertAlmostEqual(cm, 0.0053, 4) 88 | self.assertAlmostEqual(cp, -5.5766, 4) 89 | 90 | def test_cl(self): 91 | """Analyse the NACA 0012 at Re = 1e6, M = 0, C_l = 1 and verify the results.""" 92 | xf = XFoil() 93 | xf.airfoil = naca0012 94 | xf.Re = 1e6 95 | xf.max_iter = 40 96 | a, cd, cm, cp = xf.cl(1) 97 | 98 | self.assertAlmostEqual(a, 9.0617, 4) 99 | self.assertAlmostEqual(cd, 0.0135, 4) 100 | self.assertAlmostEqual(cm, 0.0013, 4) 101 | self.assertAlmostEqual(cp, -4.7361, 4) 102 | 103 | def test_aseq(self): 104 | """Analyse the NACA 0012 at Re = 1e6, M = 0, α = -20, -19.5, ..., 19.5 and verify the results.""" 105 | xf = XFoil() 106 | xf.airfoil = naca0012 107 | xf.Re = 1e6 108 | xf.max_iter = 150 109 | a, cl, cd, cm, cp = xf.aseq(-20, 20, 0.5) 110 | 111 | self.assertNumpyArraysAlmostEqual(a, np.arange(-20, 20, 0.5), 4) 112 | self.assertNumpyArraysAlmostEqual(cl, np.array([ 113 | -1.1177, -1.1521, -1.1878, -1.2263, -1.2654, -1.3014, -1.3296, -1.3656, -1.3861, -1.3883, 114 | -1.3793, -1.3661, -1.3492, -1.3264, -1.3155, -1.2830, -1.2451, -1.2065, -1.1664, -1.1223, 115 | -1.0809, -1.0363, -0.9948, -0.9512, -0.9100, -0.8685, -0.8266, -0.7637, -0.6948, -0.6255, 116 | -0.5580, -0.4878, -0.4278, -0.3723, -0.3199, -0.2672, -0.2142, -0.1609, -0.1073, -0.0537, 117 | -0.0000, +0.0537, +0.1073, +0.1609, +0.2142, +0.2672, +0.3199, +0.3723, +0.4278, +0.4878, 118 | +0.5580, +0.6255, +0.6949, +0.7638, +0.8264, +0.8684, +0.9099, +0.9511, +0.9948, +1.0363, 119 | +1.0809, +1.1224, +1.1665, +1.2067, +1.2454, +1.2834, +1.3161, +1.3273, +1.3502, +1.3673, 120 | +1.3808, +1.3900, +1.3877, +1.3670, +1.3323, +1.3041, +1.2680, +1.2288, +1.1901, +1.1541]), 4) 121 | self.assertNumpyArraysAlmostEqual(cd, np.array([ 122 | +0.1474, +0.1320, +0.1171, +0.1023, +0.0879, +0.0746, +0.0630, +0.0509, +0.0417, +0.0358, 123 | +0.0317, +0.0286, +0.0261, +0.0243, +0.0219, +0.0205, +0.0194, +0.0181, +0.0169, +0.0161, 124 | +0.0150, +0.0143, +0.0134, +0.0128, +0.0121, +0.0115, +0.0109, +0.0104, +0.0097, +0.0091, 125 | +0.0085, +0.0078, +0.0073, +0.0068, +0.0064, +0.0061, +0.0058, +0.0056, +0.0055, +0.0054, 126 | +0.0054, +0.0054, +0.0055, +0.0056, +0.0058, +0.0061, +0.0064, +0.0068, +0.0073, +0.0078, 127 | +0.0085, +0.0091, +0.0097, +0.0104, +0.0109, +0.0115, +0.0121, +0.0128, +0.0134, +0.0143, 128 | +0.0150, +0.0161, +0.0169, +0.0181, +0.0194, +0.0205, +0.0220, +0.0243, +0.0261, +0.0286, 129 | +0.0317, +0.0357, +0.0417, +0.0509, +0.0628, +0.0745, +0.0879, +0.1023, +0.1171, +0.1321]), 4) 130 | self.assertNumpyArraysAlmostEqual(cm, np.array([ 131 | +0.0238, +0.0148, +0.0066, -0.0012, -0.0085, -0.0153, -0.0210, -0.0268, -0.0304, -0.0317, 132 | -0.0312, -0.0295, -0.0269, -0.0237, -0.0184, -0.0156, -0.0134, -0.0112, -0.0091, -0.0074, 133 | -0.0053, -0.0034, -0.0010, +0.0013, +0.0040, +0.0067, +0.0093, +0.0074, +0.0043, +0.0011, 134 | -0.0017, -0.0051, -0.0060, -0.0058, -0.0049, -0.0039, -0.0030, -0.0022, -0.0014, -0.0007, 135 | +0.0000, +0.0007, +0.0014, +0.0022, +0.0030, +0.0039, +0.0049, +0.0058, +0.0060, +0.0051, 136 | +0.0017, -0.0011, -0.0043, -0.0074, -0.0092, -0.0066, -0.0039, -0.0013, +0.0010, +0.0034, 137 | +0.0053, +0.0074, +0.0091, +0.0111, +0.0133, +0.0155, +0.0182, +0.0236, +0.0267, +0.0294, 138 | +0.0310, +0.0315, +0.0302, +0.0264, +0.0208, +0.0149, +0.0082, +0.0008, -0.0070, -0.0152]), 4) 139 | self.assertNumpyArraysAlmostEqual(cp, np.array([ 140 | -8.7529, -9.1022, -9.4043, -9.6795, -9.9144,-10.0823,-10.1471,-10.2631,-10.2124, -9.9857, 141 | -9.6607, -9.3056, -8.9297, -8.5174, -8.1933, -7.7313, -7.252 , -6.8146, -6.3743, -5.9255, 142 | -5.5074, -5.0771, -4.6898, -4.3144, -3.9609, -3.6169, -3.2973, -2.9287, -2.5654, -2.2316, 143 | -1.9300, -1.6496, -1.4162, -1.2171, -1.0441, -0.8914, -0.7602, -0.6490, -0.5560, -0.4790, 144 | -0.4139, -0.4790, -0.5560, -0.6490, -0.7602, -0.8914, -1.0441, -1.2172, -1.4162, -1.6497, 145 | -1.9301, -2.2316, -2.5655, -2.9289, -3.2968, -3.6164, -3.9604, -4.3141, -4.6896, -5.0771, 146 | -5.5077, -5.9260, -6.3751, -6.8156, -7.2537, -7.7335, -8.1964, -8.5225, -8.9357, -9.3128, 147 | -9.6696, -9.9962,-10.2224,-10.2701,-10.1655,-10.1009, -9.9321, -9.6953, -9.4179, -9.1134]), 4) 148 | 149 | def test_cseq(self): 150 | """Analyse the NACA 0012 at Re = 1e6, M = 0, C_l = -0.5, -0.45, ..., 0.45 and verify the results.""" 151 | xf = XFoil() 152 | xf.airfoil = naca0012 153 | xf.Re = 1e6 154 | xf.max_iter = 100 155 | a, cl, cd, cm, cp = xf.cseq(-0.5, 0.5, 0.05) 156 | 157 | self.assertNumpyArraysAlmostEqual(cl, np.arange(-0.5, 0.5, 0.05), 4) 158 | self.assertNumpyArraysAlmostEqual(a, np.array([ 159 | -4.5879, -4.1765, -3.7446, -3.2848, -2.8112, -2.3371, -1.8666, -1.3981, -0.9324, -0.4659, 160 | -0.0000, +0.4659, +0.9323, +1.3981, +1.8665, +2.3370, +2.8111, +3.2847, +3.7445, +4.1764]), 4) 161 | self.assertNumpyArraysAlmostEqual(cd, np.array([ 162 | +0.0079, +0.0075, +0.0070, +0.0066, +0.0063, +0.0060, +0.0058, +0.0056, +0.0055, +0.0054, 163 | +0.0054, +0.0054, +0.0055, +0.0056, +0.0058, +0.0060, +0.0063, +0.0066, +0.0070, +0.0075]), 4) 164 | self.assertNumpyArraysAlmostEqual(cm, np.array([ 165 | -0.0045, -0.0055, -0.0058, -0.0054, -0.0045, -0.0036, -0.0028, -0.0020, -0.0013, -0.0007, 166 | -0.0000, +0.0007, +0.0013, +0.0020, +0.0028, +0.0036, 0.0045, +0.0054, +0.0058, +0.0055]), 4) 167 | self.assertNumpyArraysAlmostEqual(cp, np.array([ 168 | -1.6956, -1.4979, -1.3122, -1.1402, -0.9828, -0.8469, -0.7287, -0.6286, -0.5449, -0.4743, 169 | -0.4139, -0.4743, -0.5449, -0.6286, -0.7287, -0.8469, -0.9828, -1.1402, -1.3122, -1.4979]), 4) 170 | 171 | 172 | if __name__ == '__main__': 173 | unittest.main() 174 | -------------------------------------------------------------------------------- /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 | import numpy as np 19 | import ctypes 20 | import os 21 | import glob 22 | 23 | from ctypes import c_bool, c_int, c_float, byref, POINTER, cdll 24 | from shutil import copy2 25 | from tempfile import NamedTemporaryFile 26 | 27 | from .model import Airfoil 28 | 29 | here = os.path.abspath(os.path.dirname(__file__)) 30 | lib_path = glob.glob(os.path.join(here, 'libxfoil.*'))[0] 31 | lib_ext = lib_path[lib_path.rfind('.'):] 32 | 33 | fptr = POINTER(c_float) 34 | bptr = POINTER(c_bool) 35 | 36 | 37 | class XFoil(object): 38 | """Interface to the XFoil Fortran routines. 39 | 40 | Attributes 41 | ---------- 42 | airfoil 43 | Re 44 | M 45 | xtr 46 | n_crit 47 | max_iter 48 | """ 49 | 50 | def __init__(self): 51 | super().__init__() 52 | tmp = NamedTemporaryFile(mode='wb', delete=False, suffix=lib_ext) 53 | tmp.close() 54 | self._lib_path = tmp.name 55 | copy2(lib_path, self._lib_path) 56 | self._lib = cdll.LoadLibrary(self._lib_path) 57 | self._lib.init() 58 | self._airfoil = None 59 | 60 | self._lib.get_print.restype = c_bool 61 | self._lib.get_reynolds.restype = c_float 62 | self._lib.get_mach.restype = c_float 63 | self._lib.get_n_crit.restype = c_float 64 | 65 | def __del__(self): 66 | handle = self._lib._handle 67 | del self._lib 68 | try: 69 | ctypes.windll.kernel32.FreeLibrary(handle) 70 | except AttributeError: 71 | pass 72 | finally: 73 | os.remove(self._lib_path) 74 | 75 | @property 76 | def print(self): 77 | """bool: True if console output should be shown.""" 78 | return self._lib.get_print() 79 | 80 | @print.setter 81 | def print(self, value): 82 | self._lib.set_print(byref(c_bool(value))) 83 | 84 | @property 85 | def airfoil(self): 86 | """Airfoil: Instance of the Airfoil class.""" 87 | n = self._lib.get_n_coords() 88 | x = np.asfortranarray(np.zeros(n), dtype=c_float) 89 | y = np.asfortranarray(np.zeros(n), dtype=c_float) 90 | self._lib.get_airfoil(x.ctypes.data_as(fptr), y.ctypes.data_as(fptr), byref(c_int(n))) 91 | return Airfoil(x.astype(float), y.astype(float)) 92 | 93 | @airfoil.setter 94 | def airfoil(self, airfoil): 95 | self._airfoil = airfoil 96 | self._lib.set_airfoil( 97 | np.asfortranarray(airfoil.x.flatten(), dtype=c_float).ctypes.data_as(fptr), 98 | np.asfortranarray(airfoil.y.flatten(), dtype=c_float).ctypes.data_as(fptr), 99 | byref(c_int(airfoil.n_coords)) 100 | ) 101 | 102 | @property 103 | def Re(self): 104 | """float: Reynolds number.""" 105 | return float(self._lib.get_reynolds()) 106 | 107 | @Re.setter 108 | def Re(self, value): 109 | self._lib.set_reynolds(byref(c_float(value))) 110 | 111 | @property 112 | def M(self): 113 | """float: Mach number.""" 114 | return float(self._lib.get_mach()) 115 | 116 | @M.setter 117 | def M(self, value): 118 | self._lib.set_mach(byref(c_float(value))) 119 | 120 | @property 121 | def xtr(self): 122 | """tuple(float, float): Top and bottom flow trip x/c locations.""" 123 | xtr_top = c_float() 124 | xtr_bot = c_float() 125 | self._lib.get_xtr(byref(xtr_top), byref(xtr_bot)) 126 | return float(xtr_top), float(xtr_bot) 127 | 128 | @xtr.setter 129 | def xtr(self, value): 130 | self._lib.set_xtr(byref(c_float(value[0])), byref(c_float(value[1]))) 131 | 132 | @property 133 | def n_crit(self): 134 | """float: Critical amplification ratio.""" 135 | return float(self._lib.get_n_crit()) 136 | 137 | @n_crit.setter 138 | def n_crit(self, value): 139 | self._lib.set_n_crit(byref(c_float(value))) 140 | 141 | @property 142 | def max_iter(self): 143 | """int: Maximum number of iterations.""" 144 | return int(self._lib.get_max_iter()) 145 | 146 | @max_iter.setter 147 | def max_iter(self, max_iter): 148 | self._lib.set_max_iter(byref(c_int(max_iter))) 149 | 150 | def naca(self, specifier): 151 | """Set a NACA 4 or 5 series airfoil. 152 | 153 | Parameters 154 | ---------- 155 | specifier : string 156 | A NACA 4 or 5 series identifier, such as '2412'. 157 | """ 158 | self._lib.set_naca(byref(c_int(int(specifier)))) 159 | 160 | def reset_bls(self): 161 | """Reset the boundary layers to be reinitialized on the next analysis.""" 162 | self._lib.reset_bls() 163 | 164 | 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)): 165 | """Re-panel airfoil. 166 | 167 | Parameters 168 | ---------- 169 | n_nodes : int 170 | Number of panel nodes 171 | cv_par : float 172 | Panel bunching parameter 173 | cte_ratio : float 174 | TE/LE panel density ratio 175 | ctr_ratio : float 176 | Refined-area/LE panel density ratio 177 | xt_ref : tuple of two floats 178 | Top side refined area x/c limits 179 | xb_ref : tuple of two floats 180 | Bottom side refined area x/c limits 181 | """ 182 | self._lib.repanel(byref(c_int(n_nodes)), byref(c_float(cv_par)), 183 | byref(c_float(cte_ratio)), byref(c_float(ctr_ratio)), 184 | byref(c_float(xt_ref[0])), byref(c_float(xt_ref[1])), 185 | byref(c_float(xb_ref[0])), byref(c_float(xb_ref[1]))) 186 | 187 | def filter(self, factor=0.2): 188 | """Filter surface speed distribution using modified Hanning filter. 189 | 190 | Parameters 191 | ---------- 192 | factor : float 193 | Filter parameter. If set to 1, the standard, full Hanning filter is applied. Default is 0.2. 194 | """ 195 | self._lib.filter(byref(c_float(factor))) 196 | 197 | def a(self, a): 198 | """Analyze airfoil at a fixed angle of attack. 199 | 200 | Parameters 201 | ---------- 202 | a : float 203 | Angle of attack in degrees 204 | 205 | Returns 206 | ------- 207 | cl, cd, cm, cp : float 208 | Corresponding values of the lift, drag, moment, and minimum pressure coefficients. 209 | """ 210 | cl = c_float() 211 | cd = c_float() 212 | cm = c_float() 213 | cp = c_float() 214 | conv = c_bool() 215 | 216 | self._lib.alfa(byref(c_float(a)), byref(cl), byref(cd), byref(cm), byref(cp), byref(conv)) 217 | 218 | return (cl.value, cd.value, cm.value, cp.value) if conv else (np.nan, np.nan, np.nan, np.nan) 219 | 220 | def cl(self, cl): 221 | """"Analyze airfoil at a fixed lift coefficient. 222 | 223 | Parameters 224 | ---------- 225 | cl : float 226 | Lift coefficient 227 | 228 | Returns 229 | ------- 230 | a, cd, cm, cp : float 231 | Corresponding values of the angle of attack, drag, moment, and minimum pressure coefficients. 232 | """ 233 | a = c_float() 234 | cd = c_float() 235 | cm = c_float() 236 | cp = c_float() 237 | conv = c_bool() 238 | 239 | self._lib.cl(byref(c_float(cl)), byref(a), byref(cd), byref(cm), byref(cp), byref(conv)) 240 | 241 | return (a.value, cd.value, cm.value, cp.value) if conv else (np.nan, np.nan, np.nan, np.nan) 242 | 243 | def aseq(self, a_start, a_end, a_step): 244 | """Analyze airfoil at a sequence of angles of attack. 245 | 246 | The analysis is done for the angles of attack given by range(a_start, a_end, a_step). 247 | 248 | Parameters 249 | ---------- 250 | a_start, a_end, a_step : float 251 | Start, end, and increment angles for the range. 252 | 253 | Returns 254 | ------- 255 | a, cl, cd, cm, co : np.ndarray 256 | Lists of angles of attack and their corresponding lift, drag, moment, and minimum pressure coefficients. 257 | """ 258 | n = abs(int((a_end - a_start) / a_step)) 259 | 260 | a = np.zeros(n, dtype=c_float) 261 | cl = np.zeros(n, dtype=c_float) 262 | cd = np.zeros(n, dtype=c_float) 263 | cm = np.zeros(n, dtype=c_float) 264 | cp = np.zeros(n, dtype=c_float) 265 | conv = np.zeros(n, dtype=c_bool) 266 | 267 | self._lib.aseq(byref(c_float(a_start)), byref(c_float(a_end)), byref(c_int(n)), 268 | a.ctypes.data_as(fptr), cl.ctypes.data_as(fptr), 269 | cd.ctypes.data_as(fptr), cm.ctypes.data_as(fptr), 270 | cp.ctypes.data_as(fptr), conv.ctypes.data_as(bptr)) 271 | 272 | isnan = np.logical_not(conv) 273 | a[isnan] = np.nan 274 | cl[isnan] = np.nan 275 | cd[isnan] = np.nan 276 | cm[isnan] = np.nan 277 | cp[isnan] = np.nan 278 | return a.astype(float), cl.astype(float), cd.astype(float), cm.astype(float), cp.astype(float) 279 | 280 | def cseq(self, cl_start, cl_end, cl_step): 281 | """Analyze airfoil at a sequence of lift coefficients. 282 | 283 | The analysis is done for the lift coefficients given by range(cl_start, cl_end, cl_step). 284 | 285 | Parameters 286 | ---------- 287 | cl_start, cl_end, cl_step : float 288 | Start, end, and increment lift coefficients for the range. 289 | 290 | Returns 291 | ------- 292 | a, cl, cd, cm, co : np.ndarray 293 | Lists of angles of attack and their corresponding lift, drag, moment, and minimum pressure coefficients. 294 | """ 295 | n = abs(int((cl_end - cl_start) / cl_step)) 296 | 297 | a = np.zeros(n, dtype=c_float) 298 | cl = np.zeros(n, dtype=c_float) 299 | cd = np.zeros(n, dtype=c_float) 300 | cm = np.zeros(n, dtype=c_float) 301 | cp = np.zeros(n, dtype=c_float) 302 | conv = np.zeros(n, dtype=c_bool) 303 | 304 | self._lib.cseq(byref(c_float(cl_start)), byref(c_float(cl_end)), byref(c_int(n)), 305 | a.ctypes.data_as(fptr), cl.ctypes.data_as(fptr), 306 | cd.ctypes.data_as(fptr), cm.ctypes.data_as(fptr), 307 | cp.ctypes.data_as(fptr), conv.ctypes.data_as(bptr)) 308 | 309 | isnan = np.logical_not(conv) 310 | a[isnan] = np.nan 311 | cl[isnan] = np.nan 312 | cd[isnan] = np.nan 313 | cm[isnan] = np.nan 314 | cp[isnan] = np.nan 315 | return a.astype(float), cl.astype(float), cd.astype(float), cm.astype(float), cp.astype(float) 316 | 317 | def get_cp_distribution(self): 318 | """Get the Cp distribution from the last converged point. 319 | 320 | Returns 321 | ------- 322 | x : np.array 323 | X-coordinates 324 | y : np.array 325 | Y-coordinates 326 | cp : np.ndarray 327 | Pressure coefficients at the corresponding x-coordinates 328 | """ 329 | n = self._lib.get_n_cp() 330 | x = np.zeros(n, dtype=c_float) 331 | y = np.zeros(n, dtype=c_float) 332 | cp = np.zeros(n, dtype=c_float) 333 | 334 | self._lib.get_cp(x.ctypes.data_as(fptr), y.ctypes.data_as(fptr), cp.ctypes.data_as(fptr), byref(c_int(n))) 335 | return x.astype(float), y.astype(float), cp.astype(float) 336 | --------------------------------------------------------------------------------