engeom 0.1.1__cp38-abi3-musllinux_1_2_i686.whl → 0.2.1__cp38-abi3-musllinux_1_2_i686.whl

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.
@@ -0,0 +1,5 @@
1
+ from ..engeom import _airfoil
2
+
3
+ # Global import of all functions
4
+ for name in [n for n in dir(_airfoil) if not n.startswith("_")]:
5
+ globals()[name] = getattr(_airfoil, name)
engeom/airfoil.pyi ADDED
@@ -0,0 +1,334 @@
1
+ from typing import List
2
+
3
+ import numpy
4
+ from enum import Enum
5
+
6
+ from .geom2 import Circle2, Curve2, Point2, SurfacePoint2, Arc2
7
+ from .metrology import Length2
8
+
9
+ type MclOrientEnum = MclOrient.TmaxFwd | MclOrient.DirFwd
10
+ type FaceOrientEnum = FaceOrient.Detect | FaceOrient.UpperDir
11
+ type EdgeFindEnum = EdgeFind.Open | EdgeFind.OpenIntersect | EdgeFind.Intersect | EdgeFind.RansacRadius
12
+ type EdgeTypeEnum = EdgeType | Arc2
13
+ type AfGageEnum = AfGage.OnCamber | AfGage.Radius
14
+
15
+ class EdgeType(Enum):
16
+ Open=0
17
+ Closed=1
18
+
19
+ class AfGage:
20
+ """
21
+ A class representing a measurement for locating a position on an airfoil cross-section.
22
+ """
23
+ class OnCamber:
24
+ def __init__(self, d: float):
25
+ """
26
+ A gaging method that measures a distance along the mean camber line. A positive distance will be from the
27
+ leading edge towards the trailing edge, and a negative distance will be from the trailing edge towards the
28
+ leading edge.
29
+ :param d: the distance along the mean camber line to find the position
30
+ """
31
+ ...
32
+
33
+ class Radius:
34
+ def __init__(self, r: float):
35
+ """
36
+ A gaging method that measures by intersection with a circle of a given radius centered on either the
37
+ leading or trailing edge point. A positive radius indicates that the circle is located on the leading edge
38
+ while a negative radius indicates that the circle is located on the trailing edge.
39
+ :param r: the radius of the circle to find the position
40
+ """
41
+ ...
42
+
43
+ class FaceOrient:
44
+ """
45
+ An enumeration of the possible ways to orient the upper/lower (suction/pressure, convex/concave) faces of an
46
+ airfoil cross-section.
47
+ """
48
+
49
+ class Detect:
50
+ """
51
+ In an airfoil with an MCL that exhibits curvature, this will attempt to detect which direction the camber line
52
+ curves and thus identify convex/concave. This will fail if the MCL is straight.
53
+ """
54
+ ...
55
+
56
+ class UpperDir:
57
+ """
58
+ This method will orient the faces based on a vector direction provided by the user.
59
+ """
60
+
61
+ def __init__(self, x: float, y: float):
62
+ """
63
+ Create a new upper direction parameter. The x and y arguments are components of a direction vector which
64
+ should distinguish the upper (pressure side, convex) face of the airfoil. At the center of the mean camber
65
+ line, an intersection in this direction will be taken with each of the two faces. The intersection that
66
+ is further in the direction of this vector will be considered the upper face of the airfoil, and the other
67
+ will be considered the lower face.
68
+
69
+ :param x: the x component of the upper direction vector
70
+ :param y: the y component of the upper direction vector
71
+ """
72
+ ...
73
+
74
+
75
+ class MclOrient:
76
+ """
77
+ An enumeration of the possible ways to orient (to identify which side is the leading edge and which side is the
78
+ trailing edge) the mean camber line of an airfoil.
79
+ """
80
+
81
+ class TmaxFwd:
82
+ """
83
+ This method will take advantage of the fact that for most typical subsonic airfoils the maximum thickness point
84
+ is closer to the leading edge than the trailing edge.
85
+ """
86
+ ...
87
+
88
+ class DirFwd:
89
+ """
90
+ This method will orient the airfoil based on a vector direction provided by the user.
91
+ """
92
+
93
+ def __init__(self, x: float, y: float):
94
+ """
95
+ Create a new forward direction parameter. The x and y arguments are components of a direction vector which
96
+ should distinguish the forward (leading edge) direction of the airfoil. The position of the first and last
97
+ inscribed circle will be projected onto this vector, and the larger result (the one that is more in the
98
+ direction of this vector) will be considered the leading edge of the airfoil.
99
+
100
+ For instance, if you know that the airfoil is oriented so that the leading edge will have a smaller x value
101
+ than the trailing edge, `DirFwd(-1, 0)` will correctly orient the airfoil.
102
+ :param x: the x component of the forward direction vector
103
+ :param y: the y component of the forward direction vector
104
+ """
105
+ ...
106
+
107
+
108
+ class EdgeFind:
109
+ """
110
+ An enumeration of the possible techniques to find the leading and/or trailing edge geometry of an airfoil.
111
+ """
112
+
113
+ class Open:
114
+ """
115
+ This algorithm will not attempt to find edge geometry, and will simply leave the inscribed circles for the side
116
+ as they are. Use this if you know that the airfoil cross-section is open/incomplete on this side, and you don't
117
+ care to extend the MCL any further.
118
+ """
119
+ ...
120
+
121
+ class OpenIntersect:
122
+ def __init__(self, max_iter: int):
123
+ """
124
+ This algorithm will attempt to find the edge geometry by intersecting the end of the inscribed circles
125
+ camber curve with the open gap in the airfoil cross-section, then refining the end of the MCL with more
126
+ inscribed circles until the location of the end converges to within 1/100th of the general refinement
127
+ tolerance.
128
+
129
+ If the maximum number of iterations is reached before convergence, the method will throw an error instead.
130
+
131
+ :param max_iter: the maximum number of iterations to attempt to find the edge geometry
132
+ """
133
+ ...
134
+
135
+ class Intersect:
136
+ """
137
+ This algorithm will simply intersect the end of the inscribed circles camber curve with the airfoil
138
+ cross-section. This is the fastest method with the least amount of assumptions, and makes sense for airfoil
139
+ edges where you know the mean camber line has very low curvature in the vicinity of the edge.
140
+ """
141
+ ...
142
+
143
+ class RansacRadius:
144
+ def __init__(self, in_tol: float, n: int = 500):
145
+ """
146
+ This algorithm uses RANSAC (Random Sample Consensus) to find a constant radius leading edge circle that
147
+ fits the greatest number of points leftover at the edge within the tolerance `in_tol`.
148
+
149
+ The method will try `n` different combinations of three points picked at random from the remaining points
150
+ at the edge, construct a circle, and then count the number of points within `in_tol` distance of the circle
151
+ perimeter. The circle with the most points within tolerance will be considered the last inscribed circle.
152
+
153
+ The MCL will be extended to this final circle, and then intersected with the airfoil cross-section to find
154
+ the final edge point.
155
+
156
+ :param in_tol: the max distance from the circle perimeter for a point to be considered a RANSAC inlier
157
+ :param n: The number of RANSAC iterations to perform
158
+ """
159
+ ...
160
+
161
+
162
+ class InscribedCircle:
163
+ @property
164
+ def circle(self) -> Circle2: ...
165
+
166
+ @property
167
+ def contact_a(self) -> Point2:
168
+ """
169
+ A contact point of the inscribed circle with one side of the airfoil cross-section. Inscribed circles computed
170
+ together will have a consistent meaning of `a` and `b` sides, but which is the upper or lower surface will
171
+ depend on the ordering of the circles and the coordinate system of the airfoil.
172
+ """
173
+ ...
174
+
175
+ @property
176
+ def contact_b(self) -> Point2:
177
+ """
178
+ The other contact point of the inscribed circle with the airfoil cross-section. Inscribed circles computed
179
+ together will have a consistent meaning of `a` and `b` sides, but which is the upper or lower surface will
180
+ depend on the ordering of the circles and the coordinate system of the airfoil.
181
+ """
182
+ ...
183
+
184
+
185
+ class EdgeResult:
186
+ """
187
+ Represents the results of an edge detection algorithm
188
+ """
189
+
190
+ @property
191
+ def point(self) -> Point2:
192
+ """
193
+ The point on the airfoil cross-section that was detected as the edge.
194
+ """
195
+ ...
196
+
197
+ @property
198
+ def geometry(self):
199
+ ...
200
+
201
+
202
+ class AirfoilGeometry:
203
+ """
204
+ The result of an airfoil geometry computation.
205
+ """
206
+
207
+ @staticmethod
208
+ def from_analyze(
209
+ section: Curve2,
210
+ refine_tol: float,
211
+ camber_orient: MclOrientEnum,
212
+ leading: EdgeFindEnum,
213
+ trailing: EdgeFindEnum,
214
+ face_orient: FaceOrientEnum,
215
+ ) -> AirfoilGeometry:
216
+ ...
217
+
218
+ @property
219
+ def leading(self) -> EdgeResult | None:
220
+ """
221
+ The result of the leading edge detection algorithm.
222
+ """
223
+ ...
224
+
225
+ @property
226
+ def trailing(self) -> EdgeResult | None:
227
+ """
228
+ The result of the trailing edge detection algorithm.
229
+ """
230
+ ...
231
+
232
+ @property
233
+ def camber(self) -> Curve2:
234
+ """
235
+ The mean camber line of the airfoil cross-section. The curve will be oriented so that the first point is at
236
+ the leading edge of the airfoil and the last point is at the trailing edge.
237
+ :return:
238
+ """
239
+ ...
240
+
241
+ @property
242
+ def upper(self) -> Curve2 | None:
243
+ """
244
+ The curve representing the upper (suction, convex) side of the airfoil cross-section. The curve will be oriented
245
+ in the same winding direction as the original section, so the first point may be at either the leading or
246
+ trailing edge based on the airfoil geometry and the coordinate system.
247
+
248
+ :return: A Curve2, or None if there was an issue detecting the leading or trailing edge.
249
+ """
250
+ ...
251
+
252
+ @property
253
+ def lower(self) -> Curve2 | None:
254
+ """
255
+ The curve representing the lower (pressure, concave) side of the airfoil cross-section. The curve will be
256
+ oriented in the same winding direction as the original section, so the first point may be at either the leading
257
+ or trailing edge based on the airfoil geometry and the coordinate system.
258
+
259
+ :return: A Curve2, or None if there was an issue detecting the leading or trailing edge.
260
+ """
261
+ ...
262
+
263
+ @property
264
+ def circle_array(self) -> numpy.ndarray[float]:
265
+ """
266
+ Returns the list of inscribed circles as a numpy array of shape (N, 3) where N is the number of inscribed
267
+ circles. The first two columns are the x and y coordinates of the circle center, and the third column is the
268
+ radius of the circle.
269
+ """
270
+ ...
271
+
272
+ def get_thickness(self, gage: AfGageEnum) -> Length2:
273
+ """
274
+ Get the thickness dimension of the airfoil cross-section.
275
+ :param gage: the gaging method to use
276
+ :return:
277
+ """
278
+ ...
279
+
280
+ def get_tmax(self) -> Length2:
281
+ """
282
+ Get the maximum thickness dimension of the airfoil cross-section.
283
+ :return:
284
+ """
285
+ ...
286
+
287
+ def get_tmax_circle(self) -> Circle2:
288
+ """
289
+ Get the circle representing the maximum thickness dimension of the airfoil cross-section.
290
+ :return:
291
+ """
292
+ ...
293
+
294
+
295
+ def compute_inscribed_circles(section: Curve2, refine_tol: float) -> List[InscribedCircle]:
296
+ """
297
+ Compute the unambiguous inscribed circles of an airfoil cross-section.
298
+
299
+ The cross-section is represented by a curve in the x-y plane. The curve does not need to be closed, but the points
300
+ should be oriented in a counter-clockwise direction and should only contain data from the outer surface of the
301
+ airfoil (internal features/points should not be part of the data).
302
+
303
+ The method used to compute these circles is:
304
+
305
+ 1. We calculate the convex hull of the points in the section and find the longest distance between any two points.
306
+ 2. At the center of the longest distance line, we draw a perpendicular line and look for exactly two intersections
307
+ with the section. We assume that one of these is on the upper surface of the airfoil and the other is on the
308
+ lower, though it does not matter which is which.
309
+ 3. We fit the maximum inscribed circle whose center is constrained to the line between these two points. The
310
+ location and radius of this circle is refined until it converges to within 1/100th of `refine_tol`.
311
+ 4. The inscribed circle has two contact points with the section. The line between these contact points is a good
312
+ approximation of the direction orthogonal to the mean camber line near the circle. We create a parallel line
313
+ to this one, advancing from the circle center by 1/4 of the circle radius, and looking for exactly two
314
+ intersections with the section. If we fail, we try again with a slightly less aggressive advancement until we
315
+ either succeed or give up.
316
+ 5. We fit the maximum inscribed circle whose center is constrained to the new line, and refine it as in step 3.
317
+ 6. We recursively fit inscribed circles between this new circle and the previous one until the error between the
318
+ position and radius of any circle is less than `refine_tol` from the linear interpolation between its next and
319
+ previous neighbors.
320
+ 7. We repeat the process from step 4 until the distance between the center of the most recent circle and the
321
+ farthest point in the direction of the next advancement is less than 1/4 of the radius of the most recent
322
+ circle. This terminates the process before we get too close to the leading or trailing edge of the airfoil.
323
+ 8. We repeat the process from step 3, but this time in the opposite direction from the first circle. This will
324
+ give us the inscribed circles on the other side of the airfoil.
325
+
326
+ When finished, we have a list of inscribed circles from the unambiguous regions (not too close to the leading or
327
+ trailing edges) of the airfoil cross-section. The circles are ordered from one side of the airfoil to the other,
328
+ but the order may be *either* from the leading to the trailing edge *or* vice versa.
329
+
330
+ :param section: the curve representing the airfoil cross-section.
331
+ :param refine_tol: a tolerance used when refining the inscribed circles, see description for details.
332
+ :return: a list of inscribed circle objects whose order is contiguous but may be in either direction
333
+ """
334
+ ...
engeom/align.pyi CHANGED
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
  import numpy
3
- from typing import Any, List, Tuple, Union
4
- from .engeom import DeviationMode, Iso3, Mesh
3
+ from .engeom import DeviationMode
4
+ from .geom3 import Mesh, Iso3
5
5
 
6
6
 
7
7
  def points_to_mesh(
engeom/engeom.abi3.so CHANGED
Binary file
engeom/engeom.pyi CHANGED
@@ -1,14 +1,8 @@
1
1
  from __future__ import annotations
2
-
3
- from pathlib import Path
4
- from typing import Any, List, Tuple, Union
5
2
  from enum import Enum
6
3
 
7
- import numpy
8
-
4
+ type Resample = Resample_Count | Resample_Spacing | Resample_MaxSpacing
9
5
 
10
6
  class DeviationMode(Enum):
11
- Absolute = 0
12
- Normal = 1
13
-
14
-
7
+ Point = 0
8
+ Plane = 1