emerge 1.0.7__py3-none-any.whl → 1.1.1__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.

Potentially problematic release.


This version of emerge might be problematic. Click here for more details.

Files changed (33) hide show
  1. emerge/__init__.py +15 -3
  2. emerge/_emerge/const.py +2 -1
  3. emerge/_emerge/elements/ned2_interp.py +122 -42
  4. emerge/_emerge/geo/__init__.py +1 -1
  5. emerge/_emerge/geo/operations.py +20 -0
  6. emerge/_emerge/geo/pcb.py +162 -71
  7. emerge/_emerge/geo/shapes.py +12 -7
  8. emerge/_emerge/geo/step.py +177 -41
  9. emerge/_emerge/geometry.py +189 -27
  10. emerge/_emerge/logsettings.py +26 -2
  11. emerge/_emerge/material.py +2 -0
  12. emerge/_emerge/mesh3d.py +6 -8
  13. emerge/_emerge/mesher.py +67 -11
  14. emerge/_emerge/mth/common_functions.py +1 -1
  15. emerge/_emerge/mth/optimized.py +2 -2
  16. emerge/_emerge/physics/microwave/adaptive_mesh.py +549 -116
  17. emerge/_emerge/physics/microwave/assembly/assembler.py +9 -1
  18. emerge/_emerge/physics/microwave/microwave_3d.py +133 -83
  19. emerge/_emerge/physics/microwave/microwave_bc.py +158 -8
  20. emerge/_emerge/physics/microwave/microwave_data.py +94 -5
  21. emerge/_emerge/plot/pyvista/display.py +36 -23
  22. emerge/_emerge/selection.py +17 -2
  23. emerge/_emerge/settings.py +124 -6
  24. emerge/_emerge/simmodel.py +273 -150
  25. emerge/_emerge/simstate.py +106 -0
  26. emerge/_emerge/simulation_data.py +11 -23
  27. emerge/_emerge/solve_interfaces/cudss_interface.py +20 -1
  28. emerge/_emerge/solver.py +4 -4
  29. {emerge-1.0.7.dist-info → emerge-1.1.1.dist-info}/METADATA +7 -3
  30. {emerge-1.0.7.dist-info → emerge-1.1.1.dist-info}/RECORD +33 -32
  31. {emerge-1.0.7.dist-info → emerge-1.1.1.dist-info}/WHEEL +0 -0
  32. {emerge-1.0.7.dist-info → emerge-1.1.1.dist-info}/entry_points.txt +0 -0
  33. {emerge-1.0.7.dist-info → emerge-1.1.1.dist-info}/licenses/LICENSE +0 -0
emerge/__init__.py CHANGED
@@ -16,13 +16,23 @@ along with this program; if not, see
16
16
  <https://www.gnu.org/licenses/>.
17
17
 
18
18
  """
19
- import os
19
+ ############################################################
20
+ # WARNING SUPPRESSION #
21
+ ############################################################
20
22
 
21
- __version__ = "1.0.7"
23
+ import warnings
24
+ warnings.filterwarnings(
25
+ "ignore",
26
+ category=DeprecationWarning,
27
+ message="builtin type swigvarlink.*"
28
+ )
22
29
 
23
30
  ############################################################
24
31
  # HANDLE ENVIRONMENT VARIABLES #
25
32
  ############################################################
33
+ import os
34
+
35
+ __version__ = "1.1.1"
26
36
 
27
37
  NTHREADS = "1"
28
38
  os.environ["EMERGE_STD_LOGLEVEL"] = os.getenv("EMERGE_STD_LOGLEVEL", default="INFO")
@@ -36,6 +46,7 @@ os.environ["NUMEXPR_NUM_THREADS"] = NTHREADS
36
46
  os.environ["NUMBA_NUM_THREADS"] = os.getenv("NUMBA_NUM_THREADS", default="4")
37
47
  os.environ.setdefault("NUMBA_THREADING_LAYER", "workqueue")
38
48
 
49
+
39
50
  ############################################################
40
51
  # IMPORT MODULES #
41
52
  ############################################################
@@ -48,7 +59,7 @@ logger.debug('Importing modules')
48
59
  LOG_CONTROLLER._set_log_buffer()
49
60
 
50
61
  import gmsh
51
- from ._emerge.simmodel import Simulation
62
+ from ._emerge.simmodel import Simulation, SimulationBeta
52
63
  from ._emerge.material import Material, FreqCoordDependent, FreqDependent, CoordDependent
53
64
  from ._emerge import bc
54
65
  from ._emerge.solver import SolverBicgstab, SolverGMRES, SolveRoutine, ReverseCuthillMckee, Sorter, SolverPardiso, SolverUMFPACK, SolverSuperLU, EMSolver
@@ -63,6 +74,7 @@ from ._emerge.mesher import Algorithm2D, Algorithm3D
63
74
  from . import lib
64
75
  from ._emerge.howto import _HowtoClass
65
76
  from ._emerge.emerge_update import update_emerge
77
+
66
78
  howto = _HowtoClass()
67
79
 
68
80
  logger.debug('Importing complete!')
emerge/_emerge/const.py CHANGED
@@ -2,4 +2,5 @@ C0 = 299792458
2
2
  Z0 = 376.73031366857
3
3
  PI = 3.14159265358979323846
4
4
  EPS0 = 8.854187818814e-12
5
- MU0 = 1/(C0*C0*EPS0)#1.2566370612720e-6
5
+ #MU0 = 1.2566370612720e-6 #
6
+ MU0 = 1/(C0*C0*EPS0)#
@@ -14,9 +14,35 @@
14
14
  # You should have received a copy of the GNU General Public License
15
15
  # along with this program; if not, see
16
16
  # <https://www.gnu.org/licenses/>.
17
- from numba import njit, f8, c16, i8, types # type: ignore
17
+ from numba import njit, f8, c16, i8, types, prange # type: ignore
18
18
  import numpy as np
19
- from ..mth.optimized import compute_distances
19
+ from ..mth.optimized import compute_distances, matmul
20
+
21
+
22
+ @njit(f8[:,:](f8[:,:]), cache=True, nogil=True)
23
+ def matinv(M: np.ndarray) -> np.ndarray:
24
+ """Optimized matrix inverse of 3x3 matrix
25
+
26
+ Args:
27
+ M (np.ndarray): Input matrix M of shape (3,3)
28
+
29
+ Returns:
30
+ np.ndarray: The matrix inverse inv(M)
31
+ """
32
+ out = np.zeros((3,3), dtype=np.float64)
33
+
34
+ det = M[0,0]*M[1,1]*M[2,2] - M[0,0]*M[1,2]*M[2,1] - M[0,1]*M[1,0]*M[2,2] + M[0,1]*M[1,2]*M[2,0] + M[0,2]*M[1,0]*M[2,1] - M[0,2]*M[1,1]*M[2,0]
35
+ out[0,0] = M[1,1]*M[2,2] - M[1,2]*M[2,1]
36
+ out[0,1] = -M[0,1]*M[2,2] + M[0,2]*M[2,1]
37
+ out[0,2] = M[0,1]*M[1,2] - M[0,2]*M[1,1]
38
+ out[1,0] = -M[1,0]*M[2,2] + M[1,2]*M[2,0]
39
+ out[1,1] = M[0,0]*M[2,2] - M[0,2]*M[2,0]
40
+ out[1,2] = -M[0,0]*M[1,2] + M[0,2]*M[1,0]
41
+ out[2,0] = M[1,0]*M[2,1] - M[1,1]*M[2,0]
42
+ out[2,1] = -M[0,0]*M[2,1] + M[0,1]*M[2,0]
43
+ out[2,2] = M[0,0]*M[1,1] - M[0,1]*M[1,0]
44
+ out = out/det
45
+ return out
20
46
 
21
47
  @njit(types.Tuple((f8[:], f8[:], f8[:], f8[:], f8))(f8[:], f8[:], f8[:]), cache = True, nogil=True)
22
48
  def tet_coefficients(xs, ys, zs):
@@ -112,7 +138,7 @@ def local_mapping(vertex_ids, triangle_ids):
112
138
 
113
139
  return out
114
140
 
115
- @njit(types.Tuple((c16[:], c16[:], c16[:]))(f8[:,:], c16[:], i8[:,:], i8[:,:], i8[:,:], f8[:,:], i8[:,:], i8[:]), cache=True, nogil=True)
141
+ @njit(types.Tuple((c16[:], c16[:], c16[:]))(f8[:,:], c16[:], i8[:,:], i8[:,:], i8[:,:], f8[:,:], i8[:,:], i8[:]), cache=True, nogil=True, parallel=False)
116
142
  def ned2_tet_interp(coords: np.ndarray,
117
143
  solutions: np.ndarray,
118
144
  tets: np.ndarray,
@@ -130,22 +156,20 @@ def ned2_tet_interp(coords: np.ndarray,
130
156
  ys = coords[1,:]
131
157
  zs = coords[2,:]
132
158
 
133
- Ex = np.full((nNodes, ), np.nan, dtype=np.complex128)
134
- Ey = np.full((nNodes, ), np.nan, dtype=np.complex128)
135
- Ez = np.full((nNodes, ), np.nan, dtype=np.complex128)
159
+ # Ex = np.full((nNodes, ), np.nan, dtype=np.complex128)
160
+ # Ey = np.full((nNodes, ), np.nan, dtype=np.complex128)
161
+ # Ez = np.full((nNodes, ), np.nan, dtype=np.complex128)
162
+ Ex = np.zeros((nNodes, ), dtype=np.complex128)
163
+ Ey = np.zeros((nNodes, ), dtype=np.complex128)
164
+ Ez = np.zeros((nNodes, ), dtype=np.complex128)
165
+ setnan = np.zeros((nNodes, ), dtype=np.complex128)
166
+ assigned = np.zeros((nNodes,), dtype=np.int64)-1
136
167
 
137
168
  for i_iter in range(tetids.shape[0]):
138
169
  itet = tetids[i_iter]
139
170
 
140
171
  iv1, iv2, iv3, iv4 = tets[:, itet]
141
172
 
142
- g_node_ids = tets[:, itet]
143
- g_edge_ids = edges[:, tet_to_field[:6, itet]]
144
- g_tri_ids = tris[:, tet_to_field[6:10, itet]-nEdges]
145
-
146
- l_edge_ids = local_mapping(g_node_ids, g_edge_ids)
147
- l_tri_ids = local_mapping(g_node_ids, g_tri_ids)
148
-
149
173
  v1 = nodes[:,iv1]
150
174
  v2 = nodes[:,iv2]
151
175
  v3 = nodes[:,iv3]
@@ -159,19 +183,30 @@ def ned2_tet_interp(coords: np.ndarray,
159
183
  blocal[:,0] = bv1
160
184
  blocal[:,1] = bv2
161
185
  blocal[:,2] = bv3
162
- basis = np.linalg.pinv(blocal)
186
+ basis = matinv(blocal)
163
187
 
164
- coords_offset = coords - v1[:,np.newaxis]
165
- coords_local = (basis @ (coords_offset))
166
-
167
- field_ids = tet_to_field[:, itet]
168
- Etet = solutions[field_ids]
188
+ v1x, v1y, v1z = v1[0], v1[1], v1[2]
189
+
190
+ coords_offset = coords*1.0
191
+ coords_offset[0,:] = coords_offset[0,:] - v1x
192
+ coords_offset[1,:] = coords_offset[1,:] - v1y
193
+ coords_offset[2,:] = coords_offset[2,:] - v1z
194
+
195
+ coords_local = matmul(basis, coords_offset)#(basis @ (coords_offset))
169
196
 
170
197
  inside = ((coords_local[0,:] + coords_local[1,:] + coords_local[2,:]) <= 1.00000001) & (coords_local[0,:] >= -1e-6) & (coords_local[1,:] >= -1e-6) & (coords_local[2,:] >= -1e-6)
171
198
 
172
199
  if inside.sum() == 0:
173
200
  continue
174
201
 
202
+ assigned[inside] = itet
203
+
204
+ for i_iter in range(tetids.shape[0]):
205
+ itet = tetids[i_iter]
206
+
207
+ inside = assigned==itet
208
+ if inside.sum() == 0:
209
+ continue
175
210
  ######### INSIDE THE TETRAHEDRON #########
176
211
 
177
212
  x = xs[inside==1]
@@ -184,6 +219,16 @@ def ned2_tet_interp(coords: np.ndarray,
184
219
 
185
220
  a_s, b_s, c_s, d_s, V = tet_coefficients(xvs, yvs, zvs)
186
221
 
222
+ g_node_ids = tets[:, itet]
223
+ g_edge_ids = edges[:, tet_to_field[:6, itet]]
224
+ g_tri_ids = tris[:, tet_to_field[6:10, itet]-nEdges]
225
+
226
+ l_edge_ids = local_mapping(g_node_ids, g_edge_ids)
227
+ l_tri_ids = local_mapping(g_node_ids, g_tri_ids)
228
+
229
+ field_ids = tet_to_field[:, itet]
230
+ Etet = solutions[field_ids]
231
+
187
232
  Em1s = Etet[0:6]
188
233
  Ef1s = Etet[6:10]
189
234
  Em2s = Etet[10:16]
@@ -192,6 +237,7 @@ def ned2_tet_interp(coords: np.ndarray,
192
237
  Exl = np.zeros(x.shape, dtype=np.complex128)
193
238
  Eyl = np.zeros(x.shape, dtype=np.complex128)
194
239
  Ezl = np.zeros(x.shape, dtype=np.complex128)
240
+
195
241
  V1 = (216*V**3)
196
242
  for ie in range(6):
197
243
  Em1, Em2 = Em1s[ie], Em2s[ie]
@@ -243,12 +289,17 @@ def ned2_tet_interp(coords: np.ndarray,
243
289
  Eyl += ey
244
290
  Ezl += ez
245
291
 
246
- Ex[inside] = Exl
247
- Ey[inside] = Eyl
248
- Ez[inside] = Ezl
292
+ Ex[inside] += Exl
293
+ Ey[inside] += Eyl
294
+ Ez[inside] += Ezl
295
+ setnan[inside] += 1
296
+
297
+ Ex[setnan==0] = np.nan
298
+ Ey[setnan==0] = np.nan
299
+ Ez[setnan==0] = np.nan
249
300
  return Ex, Ey, Ez
250
301
 
251
- @njit(types.Tuple((c16[:], c16[:], c16[:]))(f8[:,:], c16[:], i8[:,:], i8[:,:], i8[:,:], f8[:,:], i8[:,:], c16[:], i8[:]), cache=True, nogil=True)
302
+ @njit(types.Tuple((c16[:], c16[:], c16[:]))(f8[:,:], c16[:], i8[:,:], i8[:,:], i8[:,:], f8[:,:], i8[:,:], c16[:], i8[:]), cache=True, nogil=True, parallel=False)
252
303
  def ned2_tet_interp_curl(coords: np.ndarray,
253
304
  solutions: np.ndarray,
254
305
  tets: np.ndarray,
@@ -266,22 +317,21 @@ def ned2_tet_interp_curl(coords: np.ndarray,
266
317
  xs = coords[0,:]
267
318
  ys = coords[1,:]
268
319
  zs = coords[2,:]
269
-
270
- Ex = np.full((nNodes, ), np.nan, dtype=np.complex128)
271
- Ey = np.full((nNodes, ), np.nan, dtype=np.complex128)
272
- Ez = np.full((nNodes, ), np.nan, dtype=np.complex128)
320
+
321
+ # Ex = np.full((nNodes, ), np.nan, dtype=np.complex128)
322
+ # Ey = np.full((nNodes, ), np.nan, dtype=np.complex128)
323
+ # Ez = np.full((nNodes, ), np.nan, dtype=np.complex128)
324
+ Ex = np.zeros((nNodes, ), dtype=np.complex128)
325
+ Ey = np.zeros((nNodes, ), dtype=np.complex128)
326
+ Ez = np.zeros((nNodes, ), dtype=np.complex128)
327
+ setnan = np.zeros((nNodes, ), dtype=np.complex128)
328
+ assigned = np.zeros((nNodes,), dtype=np.int64)-1
273
329
 
274
330
  for i_iter in range(tetids.shape[0]):
275
331
  itet = tetids[i_iter]
276
332
 
277
333
  iv1, iv2, iv3, iv4 = tets[:, itet]
278
334
 
279
- g_node_ids = tets[:, itet]
280
- g_edge_ids = edges[:, tet_to_field[:6, itet]]
281
- g_tri_ids = tris[:, tet_to_field[6:10, itet]-nEdges]
282
-
283
- l_edge_ids = local_mapping(g_node_ids, g_edge_ids)
284
- l_tri_ids = local_mapping(g_node_ids, g_tri_ids)
285
335
 
286
336
  v1 = nodes[:,iv1]
287
337
  v2 = nodes[:,iv2]
@@ -296,19 +346,43 @@ def ned2_tet_interp_curl(coords: np.ndarray,
296
346
  blocal[:,0] = bv1
297
347
  blocal[:,1] = bv2
298
348
  blocal[:,2] = bv3
299
- basis = np.linalg.pinv(blocal)
300
-
301
- coords_offset = coords - v1[:,np.newaxis]
302
- coords_local = (basis @ (coords_offset))
349
+ basis = matinv(blocal)
303
350
 
304
- field_ids = tet_to_field[:, itet]
305
- Etet = solutions[field_ids]
351
+ v1x, v1y, v1z = v1[0], v1[1], v1[2]
352
+
353
+ coords_offset = coords*1.0
354
+ coords_offset[0,:] = coords_offset[0,:] - v1x
355
+ coords_offset[1,:] = coords_offset[1,:] - v1y
356
+ coords_offset[2,:] = coords_offset[2,:] - v1z
357
+
358
+ #coords_local = (basis @ (coords_offset))
359
+ coords_local = matmul(basis, coords_offset)
306
360
 
307
361
  inside = ((coords_local[0,:] + coords_local[1,:] + coords_local[2,:]) <= 1.00000001) & (coords_local[0,:] >= -1e-6) & (coords_local[1,:] >= -1e-6) & (coords_local[2,:] >= -1e-6)
308
362
 
309
363
  if inside.sum() == 0:
310
364
  continue
311
365
 
366
+ assigned[inside] = itet
367
+
368
+
369
+ for i_iter in range(tetids.shape[0]):
370
+ itet = tetids[i_iter]
371
+
372
+ inside = (assigned==itet)
373
+ if inside.sum() == 0:
374
+ continue
375
+
376
+ g_node_ids = tets[:, itet]
377
+ g_edge_ids = edges[:, tet_to_field[:6, itet]]
378
+ g_tri_ids = tris[:, tet_to_field[6:10, itet]-nEdges]
379
+
380
+ l_edge_ids = local_mapping(g_node_ids, g_edge_ids)
381
+ l_tri_ids = local_mapping(g_node_ids, g_tri_ids)
382
+
383
+ field_ids = tet_to_field[:, itet]
384
+ Etet = solutions[field_ids]
385
+
312
386
  const = c[itet]
313
387
  ######### INSIDE THE TETRAHEDRON #########
314
388
 
@@ -420,9 +494,15 @@ def ned2_tet_interp_curl(coords: np.ndarray,
420
494
  Eyl += ey
421
495
  Ezl += ez
422
496
 
423
- Ex[inside] = Exl*const
424
- Ey[inside] = Eyl*const
425
- Ez[inside] = Ezl*const
497
+ Ex[inside] += Exl*const
498
+ Ey[inside] += Eyl*const
499
+ Ez[inside] += Ezl*const
500
+ setnan[inside] += 1
501
+
502
+ Ex[setnan==0] = np.nan
503
+ Ey[setnan==0] = np.nan
504
+ Ez[setnan==0] = np.nan
505
+
426
506
  return Ex, Ey, Ez
427
507
 
428
508
  @njit(types.Tuple((c16[:], c16[:], c16[:]))(f8[:,:], c16[:], i8[:,:], f8[:,:], i8[:,:]), cache=True, nogil=True)
@@ -19,6 +19,6 @@ from .pcb import PCB, PCBLayer
19
19
  from .pmlbox import pmlbox
20
20
  from .horn import Horn
21
21
  from .shapes import Cylinder, CoaxCylinder, Box, XYPlate, HalfSphere, Sphere, Plate, OldBox, Alignment, Cone
22
- from .operations import subtract, add, embed, remove, rotate, mirror, change_coordinate_system, translate, intersect, unite, expand_surface, stretch
22
+ from .operations import subtract, add, embed, remove, rotate, mirror, change_coordinate_system, translate, intersect, unite, expand_surface, stretch, extrude
23
23
  from .polybased import XYPolygon, GeoPrism, Disc, Curve
24
24
  from .step import STEPItems
@@ -282,6 +282,24 @@ def stretch(main: GeoObject, fx: float = 1, fy: float = 1, fz: float = 1, origin
282
282
 
283
283
  return main
284
284
 
285
+ def extrude(main: GeoSurface, dx: float = 0.0, dy: float = 0.0, dz: float = 0.0) -> GeoObject:
286
+ """Extrudes a surface entity by a displacement
287
+
288
+ Args:
289
+ main (GeoSurface): _description_
290
+ dx (float): _description_
291
+ dy (float): _description_
292
+ dz (float): _description_
293
+
294
+ Returns:
295
+ GeoObject: _description_
296
+ """
297
+ dtout = gmsh.model.occ.extrude(main.dimtags, dx, dy, dz)
298
+ out = [dt[1] for dt in dtout if dt[0]==3]
299
+ obj_out = GeoVolume(out, name=f'Extrusion[{main.name}]')
300
+ gmsh.model.occ.synchronize()
301
+ return obj_out
302
+
285
303
 
286
304
  @overload
287
305
  def unite(*objects: GeoVolume) -> GeoVolume: ...
@@ -313,7 +331,9 @@ def unite(*objects: GeoObject) -> GeoObject:
313
331
  other._exists = False
314
332
  new_dimtags, mapping = gmsh.model.occ.fuse(dts, main.dimtags)
315
333
 
334
+ newname = 'Union[' + ','.join([obj.name for obj in objects]) + ']'
316
335
  new_obj = GeoObject.from_dimtags(new_dimtags)._take_tools(*objects)
336
+ new_obj.name = newname
317
337
  new_obj.set_material(main.material)
318
338
  new_obj.prio_set(main._priority)
319
339