pyfoiltools 0.0.1__tar.gz → 0.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyfoiltools-0.0.1 → pyfoiltools-0.0.2}/PKG-INFO +2 -2
- {pyfoiltools-0.0.1 → pyfoiltools-0.0.2}/pyproject.toml +6 -2
- {pyfoiltools-0.0.1 → pyfoiltools-0.0.2}/src/pyfoiltools/fitting/airfoilbspline.py +93 -68
- {pyfoiltools-0.0.1 → pyfoiltools-0.0.2}/src/pyfoiltools/fitting/airfoilpoly.py +2 -2
- {pyfoiltools-0.0.1 → pyfoiltools-0.0.2}/src/pyfoiltools.egg-info/PKG-INFO +2 -2
- {pyfoiltools-0.0.1 → pyfoiltools-0.0.2}/LICENSE +0 -0
- {pyfoiltools-0.0.1 → pyfoiltools-0.0.2}/README.md +0 -0
- {pyfoiltools-0.0.1 → pyfoiltools-0.0.2}/setup.cfg +0 -0
- {pyfoiltools-0.0.1 → pyfoiltools-0.0.2}/src/pyfoiltools/__init__.py +0 -0
- {pyfoiltools-0.0.1 → pyfoiltools-0.0.2}/src/pyfoiltools/airfoil.py +0 -0
- {pyfoiltools-0.0.1 → pyfoiltools-0.0.2}/src/pyfoiltools/fitting/__init__.py +0 -0
- {pyfoiltools-0.0.1 → pyfoiltools-0.0.2}/src/pyfoiltools/fitting/airfoilshape.py +0 -0
- {pyfoiltools-0.0.1 → pyfoiltools-0.0.2}/src/pyfoiltools/fitting/chordspacing.py +0 -0
- {pyfoiltools-0.0.1 → pyfoiltools-0.0.2}/src/pyfoiltools/naca4.py +0 -0
- {pyfoiltools-0.0.1 → pyfoiltools-0.0.2}/src/pyfoiltools.egg-info/SOURCES.txt +0 -0
- {pyfoiltools-0.0.1 → pyfoiltools-0.0.2}/src/pyfoiltools.egg-info/dependency_links.txt +0 -0
- {pyfoiltools-0.0.1 → pyfoiltools-0.0.2}/src/pyfoiltools.egg-info/requires.txt +0 -0
- {pyfoiltools-0.0.1 → pyfoiltools-0.0.2}/src/pyfoiltools.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyfoiltools
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.2
|
|
4
4
|
Summary: Python Package containing tools for pyfoil
|
|
5
5
|
Author-email: Xero64 <xero64@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -8,7 +8,7 @@ Project-URL: Homepage, https://github.com/Xero64/pyfoiltools
|
|
|
8
8
|
Project-URL: Issues, https://github.com/Xero64/pyfoiltools/issues
|
|
9
9
|
Classifier: Programming Language :: Python :: 3
|
|
10
10
|
Classifier: Operating System :: OS Independent
|
|
11
|
-
Requires-Python: >=3.
|
|
11
|
+
Requires-Python: >=3.13
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
License-File: LICENSE
|
|
14
14
|
Requires-Dist: matplotlib>=3.10.5
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
1
5
|
[project]
|
|
2
6
|
name = "pyfoiltools"
|
|
3
|
-
version = "0.0.
|
|
7
|
+
version = "0.0.2"
|
|
4
8
|
authors = [
|
|
5
9
|
{ name="Xero64", email="xero64@gmail.com" },
|
|
6
10
|
]
|
|
7
11
|
description = "Python Package containing tools for pyfoil"
|
|
8
12
|
readme = "README.md"
|
|
9
|
-
requires-python = ">=3.
|
|
13
|
+
requires-python = ">=3.13"
|
|
10
14
|
classifiers = [
|
|
11
15
|
"Programming Language :: Python :: 3",
|
|
12
16
|
"Operating System :: OS Independent",
|
|
@@ -6,6 +6,7 @@ from numpy.linalg import lstsq, norm
|
|
|
6
6
|
from py2md.classes import MDReport
|
|
7
7
|
from pygeom.geom2d import BSplineCurve2D, Vector2D
|
|
8
8
|
from pygeom.tools.solvers import solve_clsq
|
|
9
|
+
from pygeom.tools.spacing import full_cosine_spacing
|
|
9
10
|
|
|
10
11
|
from .airfoilpoly import AirfoilPoly, AirfoilPolyFit
|
|
11
12
|
from .airfoilshape import AirfoilShape, AirfoilShapeFit
|
|
@@ -19,25 +20,25 @@ if TYPE_CHECKING:
|
|
|
19
20
|
class AirfoilBSpline():
|
|
20
21
|
name: str = None
|
|
21
22
|
adef: AirfoilPoly | AirfoilShape = None
|
|
22
|
-
|
|
23
|
-
bspline_l: 'BSplineCurve2D' = None
|
|
23
|
+
bspline: 'BSplineCurve2D' = None
|
|
24
24
|
c: float = None
|
|
25
25
|
num: int = None
|
|
26
|
-
|
|
26
|
+
_tu: 'NDArray' = None
|
|
27
27
|
_xu: 'NDArray' = None
|
|
28
28
|
_yu: 'NDArray' = None
|
|
29
|
+
_tl: 'NDArray' = None
|
|
29
30
|
_xl: 'NDArray' = None
|
|
30
31
|
_yl: 'NDArray' = None
|
|
32
|
+
# _t: 'NDArray' = None
|
|
31
33
|
_x: 'NDArray' = None
|
|
32
34
|
_y: 'NDArray' = None
|
|
33
35
|
|
|
34
36
|
def __init__(self, name: str, adef: AirfoilPoly | AirfoilShape,
|
|
35
|
-
|
|
37
|
+
bspline: 'BSplineCurve2D',
|
|
36
38
|
c: float = 1.0, num: int = 101) -> None:
|
|
37
39
|
self.name = name
|
|
38
40
|
self.adef = adef
|
|
39
|
-
self.
|
|
40
|
-
self.bspline_l = bspline_l
|
|
41
|
+
self.bspline = bspline
|
|
41
42
|
self.c = c
|
|
42
43
|
self.num = num
|
|
43
44
|
|
|
@@ -50,53 +51,65 @@ class AirfoilBSpline():
|
|
|
50
51
|
self.c = c
|
|
51
52
|
|
|
52
53
|
@property
|
|
53
|
-
def
|
|
54
|
-
if self.
|
|
55
|
-
self.
|
|
56
|
-
return self.
|
|
57
|
-
|
|
58
|
-
@property
|
|
59
|
-
def th(self) -> 'NDArray':
|
|
60
|
-
return self.spacing.th
|
|
54
|
+
def tu(self) -> 'NDArray':
|
|
55
|
+
if self._tu is None:
|
|
56
|
+
self._tu = full_cosine_spacing(self.num)*0.5 + 0.5
|
|
57
|
+
return self._tu
|
|
61
58
|
|
|
62
59
|
@property
|
|
63
60
|
def xu(self) -> 'NDArray':
|
|
64
61
|
if self._xu is None:
|
|
65
|
-
pnts_u = self.
|
|
62
|
+
pnts_u = self.bspline.evaluate_points_at_t(self.tu)
|
|
66
63
|
self._xu, self._yu = pnts_u.to_xy()
|
|
67
64
|
return self._xu
|
|
68
65
|
|
|
69
66
|
@property
|
|
70
67
|
def yu(self) -> 'NDArray':
|
|
71
68
|
if self._yu is None:
|
|
72
|
-
pnts_u = self.
|
|
69
|
+
pnts_u = self.bspline.evaluate_points_at_t(self.tu)
|
|
73
70
|
self._xu, self._yu = pnts_u.to_xy()
|
|
74
71
|
return self._yu
|
|
75
72
|
|
|
73
|
+
@property
|
|
74
|
+
def tl(self) -> 'NDArray':
|
|
75
|
+
if self._tl is None:
|
|
76
|
+
self._tl = (full_cosine_spacing(self.num)*0.5)[::-1]
|
|
77
|
+
return self._tl
|
|
78
|
+
|
|
76
79
|
@property
|
|
77
80
|
def xl(self) -> 'NDArray':
|
|
78
81
|
if self._xl is None:
|
|
79
|
-
pnts_l = self.
|
|
82
|
+
pnts_l = self.bspline.evaluate_points_at_t(self.tl)
|
|
80
83
|
self._xl, self._yl = pnts_l.to_xy()
|
|
81
84
|
return self._xl
|
|
82
85
|
|
|
83
86
|
@property
|
|
84
87
|
def yl(self) -> 'NDArray':
|
|
85
88
|
if self._yl is None:
|
|
86
|
-
pnts_l = self.
|
|
89
|
+
pnts_l = self.bspline.evaluate_points_at_t(self.tl)
|
|
87
90
|
self._xl, self._yl = pnts_l.to_xy()
|
|
88
91
|
return self._yl
|
|
89
92
|
|
|
93
|
+
@property
|
|
94
|
+
def t(self) -> 'NDArray':
|
|
95
|
+
if self._t is None:
|
|
96
|
+
self._t = concatenate((self.tl[::-1], self.tu[1:]))
|
|
97
|
+
return self._t
|
|
98
|
+
|
|
90
99
|
@property
|
|
91
100
|
def x(self) -> 'NDArray':
|
|
92
101
|
if self._x is None:
|
|
93
102
|
self._x = hstack((self.xl[::-1], self.xu[1:]))
|
|
103
|
+
# pnts = self.bspline.evaluate_points_at_t(self.t)
|
|
104
|
+
# self._x, self._y = pnts.to_xy()
|
|
94
105
|
return self._x
|
|
95
106
|
|
|
96
107
|
@property
|
|
97
108
|
def y(self) -> 'NDArray':
|
|
98
109
|
if self._y is None:
|
|
99
110
|
self._y = hstack((self.yl[::-1], self.yu[1:]))
|
|
111
|
+
# pnts = self.bspline.evaluate_points_at_t(self.t)
|
|
112
|
+
# self._x, self._y = pnts.to_xy()
|
|
100
113
|
return self._y
|
|
101
114
|
|
|
102
115
|
def plot_shape(self, ax: 'Axes' = None, **kwargs: dict[str, Any]) -> 'Axes':
|
|
@@ -123,13 +136,12 @@ class AirfoilBSpline():
|
|
|
123
136
|
return self.to_mdobj()._repr_markdown_()
|
|
124
137
|
|
|
125
138
|
def __str__(self) -> str:
|
|
126
|
-
return f'AirfoilBSpline: {self.name:s}\
|
|
139
|
+
return f'AirfoilBSpline: {self.name:s}\nBSpline = \n{self.bspline}\n'
|
|
127
140
|
|
|
128
141
|
|
|
129
142
|
class AirfoilBSplineFit():
|
|
130
143
|
afit: AirfoilPolyFit | AirfoilShapeFit = None
|
|
131
|
-
|
|
132
|
-
Nl: int = None
|
|
144
|
+
Nb: int = None
|
|
133
145
|
_adef: AirfoilPoly | AirfoilShape = None
|
|
134
146
|
_spcu: ChordSpacing = None
|
|
135
147
|
_THu: 'NDArray' = None
|
|
@@ -157,10 +169,9 @@ class AirfoilBSplineFit():
|
|
|
157
169
|
_lmda: 'NDArray' = None
|
|
158
170
|
|
|
159
171
|
def __init__(self, afit: AirfoilPolyFit | AirfoilShapeFit,
|
|
160
|
-
|
|
172
|
+
Nb: int) -> None:
|
|
161
173
|
self.afit = afit
|
|
162
|
-
self.
|
|
163
|
-
self.Nl = Nl
|
|
174
|
+
self.Nb = Nb
|
|
164
175
|
|
|
165
176
|
@property
|
|
166
177
|
def adef(self) -> AirfoilPoly | AirfoilShape:
|
|
@@ -176,7 +187,7 @@ class AirfoilBSplineFit():
|
|
|
176
187
|
@property
|
|
177
188
|
def spcu(self) -> ChordSpacing:
|
|
178
189
|
if self._spcu is None:
|
|
179
|
-
self._spcu = ChordSpacing.from_num(self.
|
|
190
|
+
self._spcu = ChordSpacing.from_num(self.Nb)
|
|
180
191
|
return self._spcu
|
|
181
192
|
|
|
182
193
|
@property
|
|
@@ -220,7 +231,7 @@ class AirfoilBSplineFit():
|
|
|
220
231
|
@property
|
|
221
232
|
def spcl(self) -> ChordSpacing:
|
|
222
233
|
if self._spcl is None:
|
|
223
|
-
self._spcl = ChordSpacing.from_num(self.
|
|
234
|
+
self._spcl = ChordSpacing.from_num(self.Nb)
|
|
224
235
|
return self._spcl
|
|
225
236
|
|
|
226
237
|
@property
|
|
@@ -265,37 +276,46 @@ class AirfoilBSplineFit():
|
|
|
265
276
|
def aspl(self) -> AirfoilBSpline:
|
|
266
277
|
if self._aspl is None:
|
|
267
278
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
279
|
+
Xl = self.Xcl + self.Ucl*self.Tcl
|
|
280
|
+
Yl = self.Ycl + self.Vcl*self.Tcl
|
|
281
|
+
|
|
282
|
+
Xu = self.Xcu + self.Ucu*self.Tcu
|
|
283
|
+
Yu = self.Ycu + self.Vcu*self.Tcu
|
|
284
|
+
|
|
285
|
+
Xb = concatenate((Xl[::-1], zeros((1,)), Xu))
|
|
286
|
+
Yb = concatenate((Yl[::-1], zeros((1,)), Yu))
|
|
287
|
+
|
|
288
|
+
ctlpnts = Vector2D(Xb, Yb)
|
|
272
289
|
|
|
273
|
-
|
|
274
|
-
ctlpnts_l.x[1:] = self.Xcl + self.Ucl*self.Tcl
|
|
275
|
-
ctlpnts_l.y[1:] = self.Ycl + self.Vcl*self.Tcl
|
|
276
|
-
bspline_l = BSplineCurve2D(ctlpnts_l, degree=self.Nl)
|
|
290
|
+
bspline = BSplineCurve2D(ctlpnts, degree=self.Nb)
|
|
277
291
|
|
|
278
292
|
self._aspl = AirfoilBSpline(self.adef.name, self.adef,
|
|
279
|
-
|
|
293
|
+
bspline)
|
|
280
294
|
|
|
281
295
|
return self._aspl
|
|
282
296
|
|
|
283
297
|
@property
|
|
284
298
|
def tu(self) -> 'NDArray':
|
|
285
299
|
if self._tu is None:
|
|
286
|
-
self._tu = self.afit.spcu.s.copy()
|
|
287
|
-
self._tu = bspline_lstsq_fit_t(self.aspl.
|
|
300
|
+
self._tu = self.afit.spcu.s.copy()*0.5 + 0.5
|
|
301
|
+
self._tu = bspline_lstsq_fit_t(self.aspl.bspline, self.afit.xu,
|
|
288
302
|
self.afit.yu, self._tu)
|
|
289
303
|
return self._tu
|
|
290
304
|
|
|
291
305
|
@property
|
|
292
306
|
def tl(self) -> 'NDArray':
|
|
293
307
|
if self._tl is None:
|
|
294
|
-
self._tl = self.afit.spcl.s.copy()
|
|
295
|
-
self._tl = bspline_lstsq_fit_t(self.aspl.
|
|
308
|
+
self._tl = (self.afit.spcl.s.copy()*0.5)[::-1]
|
|
309
|
+
self._tl = bspline_lstsq_fit_t(self.aspl.bspline, self.afit.xl,
|
|
296
310
|
self.afit.yl, self._tl)
|
|
297
311
|
return self._tl
|
|
298
312
|
|
|
313
|
+
@property
|
|
314
|
+
def t(self) -> 'NDArray':
|
|
315
|
+
if self._t is None:
|
|
316
|
+
self._t = concatenate((self.tu, self.tl))
|
|
317
|
+
return self._t
|
|
318
|
+
|
|
299
319
|
@property
|
|
300
320
|
def num_Tu(self) -> int:
|
|
301
321
|
return self.Tcu.size - 1
|
|
@@ -373,16 +393,12 @@ class AirfoilBSplineFit():
|
|
|
373
393
|
ax = self.adef.plot_shape(ax=ax)
|
|
374
394
|
ax = self.afit.airfoil.plot(ax=ax)
|
|
375
395
|
|
|
376
|
-
|
|
377
|
-
pnts_l = self.aspl.bspline_l.evaluate_points(100)
|
|
396
|
+
pnts = self.aspl.bspline.evaluate_points(100)
|
|
378
397
|
|
|
379
|
-
|
|
380
|
-
ctls_l = self.aspl.bspline_l.ctlpnts
|
|
398
|
+
ctls = self.aspl.bspline.ctlpnts
|
|
381
399
|
|
|
382
|
-
ax.plot(
|
|
383
|
-
ax.plot(
|
|
384
|
-
ax.plot(ctls_u.x, ctls_u.y, '-o', label='Control Points Upper')
|
|
385
|
-
ax.plot(ctls_l.x, ctls_l.y, '-o', label='Control Points Lower')
|
|
400
|
+
ax.plot(pnts.x, pnts.y, label='BSpline Fit')
|
|
401
|
+
ax.plot(ctls.x, ctls.y, '-o', label='Control Points')
|
|
386
402
|
ax.plot(self.afit.xu, self.afit.yu, 'x', label='Target Points Upper')
|
|
387
403
|
ax.plot(self.afit.xl, self.afit.yl, 'x', label='Target Points Lower')
|
|
388
404
|
_ = ax.legend()
|
|
@@ -390,41 +406,45 @@ class AirfoilBSplineFit():
|
|
|
390
406
|
|
|
391
407
|
def improved_fit(self, display: bool = False) -> tuple[float, float]:
|
|
392
408
|
|
|
393
|
-
xu, yu = self.aspl.
|
|
409
|
+
xu, yu = self.aspl.bspline.evaluate_points_at_t(self.tu).to_xy()
|
|
394
410
|
|
|
395
411
|
Dxu = xu - self.afit.xu
|
|
396
412
|
Dyu = yu - self.afit.yu
|
|
397
413
|
|
|
398
|
-
xl, yl = self.aspl.
|
|
414
|
+
xl, yl = self.aspl.bspline.evaluate_points_at_t(self.tl).to_xy()
|
|
399
415
|
|
|
400
416
|
Dxl = xl - self.afit.xl
|
|
401
417
|
Dyl = yl - self.afit.yl
|
|
402
418
|
|
|
403
419
|
f = concatenate((Dxu, Dyu, Dxl, Dyl))
|
|
404
420
|
|
|
405
|
-
|
|
421
|
+
Nt = self.aspl.bspline.basis_functions(self.tu).transpose()
|
|
422
|
+
|
|
423
|
+
Ntu = Nt[:, self.Nb:]
|
|
406
424
|
|
|
407
|
-
dDxudXu = Ntu[:, 1:self.
|
|
408
|
-
dDyudYu = Ntu[:, 1:self.
|
|
425
|
+
dDxudXu = Ntu[:, 1:self.Nb]
|
|
426
|
+
dDyudYu = Ntu[:, 1:self.Nb]
|
|
409
427
|
|
|
410
|
-
|
|
428
|
+
Nt = self.aspl.bspline.basis_functions(self.tl).transpose()
|
|
411
429
|
|
|
412
|
-
|
|
413
|
-
|
|
430
|
+
Ntl = Nt[:, self.Nb::-1]
|
|
431
|
+
|
|
432
|
+
dDxldXl = Ntl[:, 1:self.Nb]
|
|
433
|
+
dDyldYl = Ntl[:, 1:self.Nb]
|
|
414
434
|
|
|
415
435
|
dDxudTu = dDxudXu@self.dXudTu + dDyudYu@self.dYudTu
|
|
416
|
-
dDxudTl = zeros((xu.size, self.
|
|
436
|
+
dDxudTl = zeros((xu.size, self.Nb - 1))
|
|
417
437
|
|
|
418
438
|
dDyudTu = dDyudYu@self.dYudTu + dDyudYu@self.dYudTu
|
|
419
|
-
dDyudTl = zeros((yu.size, self.
|
|
439
|
+
dDyudTl = zeros((yu.size, self.Nb - 1))
|
|
420
440
|
|
|
421
441
|
dDxldTl = dDxldXl@self.dXldTl + dDyldYl@self.dYldTl
|
|
422
|
-
dDxldTu = zeros((xl.size, self.
|
|
442
|
+
dDxldTu = zeros((xl.size, self.Nb - 1))
|
|
423
443
|
|
|
424
444
|
dDyldTl = dDyldYl@self.dYldTl + dDyldYl@self.dYldTl
|
|
425
|
-
dDyldTu = zeros((yl.size, self.
|
|
445
|
+
dDyldTu = zeros((yl.size, self.Nb - 1))
|
|
426
446
|
|
|
427
|
-
dDxudtu, dDyudtu = self.aspl.
|
|
447
|
+
dDxudtu, dDyudtu = self.aspl.bspline.evaluate_first_derivatives_at_t(self.tu).to_xy()
|
|
428
448
|
|
|
429
449
|
dDxudtu = diag(dDxudtu)
|
|
430
450
|
dDxudtl = zeros((xu.size, self.tl.size))
|
|
@@ -432,7 +452,7 @@ class AirfoilBSplineFit():
|
|
|
432
452
|
dDyudtu = diag(dDyudtu)
|
|
433
453
|
dDyudtl = zeros((yu.size, self.tl.size))
|
|
434
454
|
|
|
435
|
-
dDxldtl, dDyldtl = self.aspl.
|
|
455
|
+
dDxldtl, dDyldtl = self.aspl.bspline.evaluate_first_derivatives_at_t(self.tl).to_xy()
|
|
436
456
|
|
|
437
457
|
dDxldtl = diag(dDxldtl)
|
|
438
458
|
dDxldtu = zeros((xl.size, self.tu.size))
|
|
@@ -441,9 +461,9 @@ class AirfoilBSplineFit():
|
|
|
441
461
|
dDyldtu = zeros((yl.size, self.tu.size))
|
|
442
462
|
|
|
443
463
|
dfdTt = block([[dDxudTu, dDxudTl, dDxudtu, dDxudtl],
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
464
|
+
[dDyudTu, dDyudTl, dDyudtu, dDyudtl],
|
|
465
|
+
[dDxldTu, dDxldTl, dDxldtu, dDxldtl],
|
|
466
|
+
[dDyldTu, dDyldTl, dDyldtu, dDyldtl]])
|
|
447
467
|
|
|
448
468
|
dvTt, dlTt = solve_clsq(dfdTt, f, self.carr, self.darr)
|
|
449
469
|
|
|
@@ -473,11 +493,13 @@ class AirfoilBSplineFit():
|
|
|
473
493
|
|
|
474
494
|
return normdcon, normdvar
|
|
475
495
|
|
|
476
|
-
def improved_fit_loop(self, tol_dcon: float = 1e-12,
|
|
477
|
-
|
|
496
|
+
def improved_fit_loop(self, tol_dcon: float = 1e-12,
|
|
497
|
+
tol_dvar: float = 1e-3, max_iter: int = 50,
|
|
498
|
+
display: bool = False) -> tuple[float, float, bool]:
|
|
478
499
|
|
|
479
500
|
normdcon, normdvar = float('inf'), float('inf')
|
|
480
501
|
|
|
502
|
+
conv = True
|
|
481
503
|
iter = 1
|
|
482
504
|
while normdcon > tol_dcon or normdvar > tol_dvar:
|
|
483
505
|
normdcon, normdvar = self.improved_fit()
|
|
@@ -487,11 +509,14 @@ class AirfoilBSplineFit():
|
|
|
487
509
|
print(f'normdvar = {normdvar:.12f}')
|
|
488
510
|
print()
|
|
489
511
|
if iter >= max_iter:
|
|
512
|
+
conv = False
|
|
490
513
|
err = f'Maximum number of iterations ({max_iter}) reached.'
|
|
491
|
-
|
|
514
|
+
print(err)
|
|
515
|
+
break
|
|
516
|
+
# raise RuntimeError(err)
|
|
492
517
|
iter += 1
|
|
493
518
|
|
|
494
|
-
return normdcon, normdvar
|
|
519
|
+
return normdcon, normdvar, conv
|
|
495
520
|
|
|
496
521
|
def __repr__(self) -> str:
|
|
497
522
|
return f'<AirfoilBSplineFit: {self.adef.name:s}>'
|
|
@@ -702,16 +702,16 @@ class AirfoilPoly():
|
|
|
702
702
|
def to_mdobj(self) -> MDReport:
|
|
703
703
|
report = MDReport()
|
|
704
704
|
report.add_heading(f'Airfoil Shape: {self.name:s}', level=1)
|
|
705
|
-
table = report.add_table()
|
|
706
705
|
if self.Cn.size > 0:
|
|
706
|
+
table = report.add_table()
|
|
707
707
|
table.add_column('Leading Edge Camber %', '.3f', data=[self.yc_le/self.c])
|
|
708
708
|
table.add_column('Trailing Edge Camber %', '.3f', data=[self.yc_te/self.c])
|
|
709
709
|
table.add_column('Max Camber %', '.3f', data=[self.max_yc/self.c*100])
|
|
710
710
|
table.add_column('Max Camber Position %', '.3f', data=[self.max_yc_pc*100])
|
|
711
711
|
table.add_column('Leading Edge Angle (deg)', '.3f', data=[degrees(self.thy_le)])
|
|
712
712
|
table.add_column('Trailing Edge Angle (deg)', '.3f', data=[degrees(self.thy_te)])
|
|
713
|
-
table = report.add_table()
|
|
714
713
|
if self.Tn.size > 0:
|
|
714
|
+
table = report.add_table()
|
|
715
715
|
table.add_column('Trailing Edge Thickness %', '.3f', data=[self.tc_te/self.c])
|
|
716
716
|
table.add_column('Max Thickness %', '.3f', data=[self.max_tc/self.c*100])
|
|
717
717
|
table.add_column('Max Thickness Position %', '.3f', data=[self.max_tc_pc*100])
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyfoiltools
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.2
|
|
4
4
|
Summary: Python Package containing tools for pyfoil
|
|
5
5
|
Author-email: Xero64 <xero64@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -8,7 +8,7 @@ Project-URL: Homepage, https://github.com/Xero64/pyfoiltools
|
|
|
8
8
|
Project-URL: Issues, https://github.com/Xero64/pyfoiltools/issues
|
|
9
9
|
Classifier: Programming Language :: Python :: 3
|
|
10
10
|
Classifier: Operating System :: OS Independent
|
|
11
|
-
Requires-Python: >=3.
|
|
11
|
+
Requires-Python: >=3.13
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
License-File: LICENSE
|
|
14
14
|
Requires-Dist: matplotlib>=3.10.5
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|