wolfhece 2.1.127__py3-none-any.whl → 2.1.129__py3-none-any.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,335 @@
1
+ import math
2
+ import numpy as np
3
+ from numba import jit
4
+
5
+ """ JIT is a decorator that tells Numba to compile this function using the Numba JIT compiler. """
6
+
7
+ @jit(nopython=True)
8
+ def A_from_h(h:float, diameter:float):
9
+ """ Compute the area of a circular segment from its height """
10
+ d = diameter / 2.0 - h
11
+ theta = math.acos(1.0 - 2.0 * h / diameter)
12
+ chord = math.sqrt(h * (diameter - h))
13
+ area = theta * diameter**2 / 4.0 - chord * d
14
+
15
+ return area
16
+
17
+ @jit(nopython=True)
18
+ def dichotomy_A2h(f, a:float, b:float, args, tol=1e-10, max_iter=1000):
19
+ """ Dichotomy algorithm to find the root of a function f between a and b.
20
+ The function f must be defined as f(x, *args) and must return a scalar.
21
+ The function must have a single root in the interval [a, b].
22
+ """
23
+ def cond_fun(val):
24
+ a, b, i = val
25
+ return (b - a) > tol
26
+
27
+ def body_fun(val):
28
+ a, b, i = val
29
+ c = (a + b) / 2.
30
+ diameter = args[0]
31
+ fa = f(a, diameter)
32
+ fc = f(c, diameter)
33
+ if fc == 0:
34
+ return (c, c, i + 1)
35
+ else:
36
+ if fa * fc < 0:
37
+ return (a, c, i + 1)
38
+ else:
39
+ return (c, b, i + 1)
40
+
41
+ i=0
42
+ while cond_fun((a, b, i)) and i < max_iter:
43
+ a, b, i = body_fun((a, b, 0))
44
+
45
+ return (a + b) / 2
46
+
47
+ @jit(nopython=True)
48
+ def segment_of_circle(diameter:float, h:float=None, chord:float=None,
49
+ arc_length:float=None, area:float=None,
50
+ from_which:int=None, init_val:bool=None,
51
+ eps:float=1e-8) -> tuple:
52
+ """ Calcul des caractristiques d'un segment circulaire
53
+ plus d'infos sur http://mathworld.wolfram.com/CircularSegment.html.
54
+
55
+ :param diameter: diamtre du cercle [m]
56
+ :param h: hauteur du segment [m]
57
+ :param chord: longueur de la corde [m]
58
+ :param arc_length: longueur de l'arc soutenu par la corde [m]
59
+ :param area: aire du sgment [m]
60
+ :param from_which: variable de calcul sur base de laquelle les autres grandeurs doivent tre values [index dans l'ordre des paramètres (h = 1, area = 4...)]
61
+ :param init_val: utilise h comme valeur initiale pour le calcul de h depuis A [booléen]
62
+ """
63
+
64
+ R = diameter / 2.0
65
+
66
+ if from_which == 1: # from h
67
+ # The solution is unique
68
+
69
+ d = diameter / 2.0 - h
70
+ theta = math.acos(1.0 - 2.0 * h / diameter)
71
+
72
+ arc_length = theta * diameter
73
+ chord = math.sqrt(h * (diameter - h))
74
+ area = theta * diameter**2 / 4.0 - chord * d
75
+ chord = 2.0 * chord
76
+
77
+ elif from_which == 2: # from chord
78
+ # The solution is not unique --> two possible values for h
79
+ # Conserve the value of h that is the closest to the previous value of h
80
+
81
+ # h1 as root of the quadratic equation
82
+ h1 = (diameter - math.sqrt(diameter**2 - chord**2)) / 2.0
83
+
84
+ if init_val is not None:
85
+ if init_val:
86
+ h2 = diameter - h1
87
+ dh1 = abs(h - h1)
88
+ dh2 = abs(h + h1 - diameter)
89
+
90
+ h = h1 if dh1 < dh2 else h2
91
+ else:
92
+ # Conserve the lowest value of h
93
+ h = h1
94
+ else:
95
+ h = h1
96
+
97
+ d = diameter / 2.0 - h
98
+ theta = math.acos(1.0 - 2.0 * h / diameter)
99
+
100
+ arc_length = theta * diameter
101
+ area = theta * diameter**2 / 4.0 - chord /2. * d
102
+
103
+ elif from_which == 3: # from arc_length
104
+ # The solution is unique
105
+
106
+ theta = arc_length / diameter
107
+ h = R * (1.0 - math.cos(theta))
108
+ d = R - h
109
+
110
+ chord = math.sqrt(h * (diameter - h))
111
+ area = theta * diameter**2 / 4.0 - chord * d
112
+ chord = 2.0 * chord
113
+
114
+ elif from_which in [4,41]: # from area using Newton's method
115
+ # The solution is unique BUT the calculation is iterative
116
+
117
+ cur_error = 1.0
118
+
119
+ d2by4 = diameter**2 / 4.0
120
+ area_max = math.pi * d2by4
121
+
122
+ if area == 0.0:
123
+ h = 0.0
124
+ chord = 0.0
125
+ arc_length = 0.0
126
+
127
+ elif area_max > area:
128
+ if init_val is not None:
129
+ if not init_val or h == 0.0:
130
+ h = R
131
+ else:
132
+ h = R
133
+
134
+ while abs(cur_error) > eps:
135
+ d = R - h
136
+ theta = math.acos(1.0 - h / R)
137
+ chord = math.sqrt(h * (diameter - h))
138
+ area_loc = theta * d2by4 - chord * d
139
+ dAdh = chord - ((h - R)**2 - d2by4) / (chord + 1e-200)
140
+
141
+ cur_error = (area_loc - area) / dAdh
142
+ if h - cur_error < 0.0:
143
+ h = h / 2.0
144
+ elif h - cur_error > diameter:
145
+ h = (h + diameter) / 2.0
146
+ else:
147
+ h = h - cur_error
148
+
149
+ chord = 2.0 * chord
150
+ arc_length = theta * diameter
151
+
152
+ else:
153
+ h = diameter
154
+ chord = 0.0
155
+ arc_length = math.pi * diameter
156
+
157
+ elif from_which == 42: # from area but using dichotomy rather than Newton-Raphson
158
+ # The solution is unique BUT the calculation is iterative
159
+
160
+ cur_error = 1.0
161
+
162
+ d2by4 = diameter**2 / 4.0
163
+ area_max = math.pi * d2by4
164
+
165
+ if area == 0.0:
166
+ h = 0.0
167
+ chord = 0.0
168
+ arc_length = 0.0
169
+
170
+ elif area_max > area:
171
+ if init_val is not None:
172
+ if not init_val or h == 0.0:
173
+ h = R
174
+ else:
175
+ h = R
176
+
177
+ h = dichotomy_A2h(f=A_from_h, a=0., b=diameter, args=(diameter,), tol=eps)
178
+
179
+ d = diameter / 2.0 - h
180
+ theta = math.acos(1.0 - 2.0 * h / diameter)
181
+ arc_length = theta * diameter
182
+ chord = math.sqrt(h * (diameter - h))
183
+ chord = 2.0 * chord
184
+
185
+ else:
186
+ h = diameter
187
+ chord = 0.0
188
+ arc_length = math.pi * diameter
189
+
190
+ return diameter, h, chord, arc_length, area
191
+
192
+
193
+ if __name__ == '__main__':
194
+
195
+ diameter = 10.0
196
+ h = 5.0
197
+ chord = -1.
198
+ arc_length = -1.
199
+ area = -1.
200
+ from_which = 1
201
+ init_val = None
202
+
203
+ res1 = segment_of_circle(diameter, h, chord, arc_length, area, from_which, init_val)
204
+ diameter, h, chord, arc_length, area = res1
205
+
206
+ print(f"diameter = {diameter}")
207
+ print(f"h = {h}")
208
+ print(f"chord = {chord}")
209
+ print(f"arc_length = {arc_length}")
210
+ print(f"area = {area}")
211
+
212
+ from_which = 2
213
+ res2 = segment_of_circle(diameter, h, chord, arc_length, area, from_which, init_val)
214
+ diameter, h, chord, arc_length, area = res2
215
+
216
+ print(f"diameter = {diameter}")
217
+ print(f"h = {h}")
218
+ print(f"chord = {chord}")
219
+ print(f"arc_length = {arc_length}")
220
+ print(f"area = {area}")
221
+
222
+ from_which = 2
223
+ res2 = segment_of_circle(diameter, h, chord/2., arc_length, area, from_which, False)
224
+ diameter, h, chord, arc_length, area = res2
225
+
226
+ print(f"diameter = {diameter}")
227
+ print(f"h = {h}")
228
+ print(f"chord = {chord}")
229
+ print(f"arc_length = {arc_length}")
230
+ print(f"area = {area}")
231
+
232
+ from_which = 3
233
+ res3 = segment_of_circle(diameter, h, chord, arc_length, area, from_which, init_val)
234
+ diameter, h, chord, arc_length, area = res3
235
+
236
+ print(f"diameter = {diameter}")
237
+ print(f"h = {h}")
238
+ print(f"chord = {chord}")
239
+ print(f"arc_length = {arc_length}")
240
+ print(f"area = {area}")
241
+
242
+ from_which = 2
243
+ res2 = segment_of_circle(diameter, h, chord/2., arc_length, area, from_which, init_val)
244
+ diameter, h, chord, arc_length, area = res2
245
+
246
+ print(f"diameter = {diameter}")
247
+ print(f"h = {h}")
248
+ print(f"chord = {chord}")
249
+ print(f"arc_length = {arc_length}")
250
+ print(f"area = {area}")
251
+
252
+ diameter = 10.0
253
+ h = 1.
254
+ chord = -1.
255
+ arc_length = -1.
256
+ area = 10.0
257
+ from_which = 4
258
+ init_val = True
259
+
260
+ res4 = segment_of_circle(diameter, h, chord, arc_length, area, from_which, init_val)
261
+ diameter, h, chord, arc_length, area = res4
262
+
263
+ print(f"diameter = {diameter}")
264
+ print(f"h = {h}")
265
+ print(f"chord = {chord}")
266
+ print(f"arc_length = {arc_length}")
267
+ print(f"area = {area}")
268
+
269
+ diameter = 10.0
270
+ h = -1.
271
+ chord = -1.
272
+ arc_length = -1.
273
+ area = 10.0
274
+ from_which = 4
275
+ init_val = False
276
+
277
+ res5 = segment_of_circle(diameter, h, chord, arc_length, area, from_which, init_val)
278
+ diameter, h, chord, arc_length, area = res5
279
+
280
+ print(f"diameter = {diameter}")
281
+ print(f"h = {h}")
282
+ print(f"chord = {chord}")
283
+ print(f"arc_length = {arc_length}")
284
+ print(f"area = {area}")
285
+
286
+ diameter = 10.0
287
+ h = 9.
288
+ chord = -1.
289
+ arc_length = -1.
290
+ area = 10.0
291
+ from_which = 4
292
+ init_val = True
293
+
294
+ res6 = segment_of_circle(diameter, h, chord, arc_length, area, from_which, init_val)
295
+ diameter, h, chord, arc_length, area = res6
296
+
297
+ print(f"diameter = {diameter}")
298
+ print(f"h = {h}")
299
+ print(f"chord = {chord}")
300
+ print(f"arc_length = {arc_length}")
301
+ print(f"area = {area}")
302
+
303
+ diameter = 10.0
304
+ h = 2.
305
+ chord = -1.
306
+ arc_length = -1.
307
+ area = 10.0
308
+ from_which = 4 # from area using Newton's method
309
+ init_val = True
310
+
311
+ res7 = segment_of_circle(diameter, h, chord, arc_length, area, from_which, init_val, eps= 1e-12)
312
+ diameter, h, chord, arc_length, area = res7
313
+
314
+ print(f"diameter = {diameter}")
315
+ print(f"h = {h}")
316
+ print(f"chord = {chord}")
317
+ print(f"arc_length = {arc_length}")
318
+ print(f"area = {area}")
319
+
320
+ diameter = 10.0
321
+ h = 2.
322
+ chord = -1.
323
+ arc_length = -1.
324
+ area = 10.0
325
+ from_which = 42 # from area using dichotomy
326
+ init_val = True
327
+
328
+ res8 = segment_of_circle(diameter, h, chord, arc_length, area, from_which, init_val, eps= 1e-12)
329
+ diameter, h, chord, arc_length, area = res7
330
+
331
+ print(f"diameter = {diameter}")
332
+ print(f"h = {h}")
333
+ print(f"chord = {chord}")
334
+ print(f"arc_length = {arc_length}")
335
+ print(f"area = {area}")