emerge 1.0.6__py3-none-any.whl → 1.1.0__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.
- emerge/__init__.py +14 -3
- emerge/_emerge/elements/index_interp.py +45 -0
- emerge/_emerge/geo/pcb.py +132 -59
- emerge/_emerge/geo/shapes.py +11 -7
- emerge/_emerge/geometry.py +23 -8
- emerge/_emerge/logsettings.py +26 -2
- emerge/_emerge/material.py +1 -1
- emerge/_emerge/mesh3d.py +38 -8
- emerge/_emerge/mesher.py +61 -11
- emerge/_emerge/physics/microwave/adaptive_mesh.py +667 -0
- emerge/_emerge/physics/microwave/assembly/assembler.py +6 -5
- emerge/_emerge/physics/microwave/microwave_3d.py +251 -88
- emerge/_emerge/physics/microwave/microwave_bc.py +182 -11
- emerge/_emerge/physics/microwave/microwave_data.py +23 -6
- emerge/_emerge/plot/pyvista/display.py +31 -18
- emerge/_emerge/settings.py +124 -6
- emerge/_emerge/simmodel.py +238 -95
- emerge/_emerge/simstate.py +106 -0
- emerge/_emerge/simulation_data.py +11 -23
- emerge/_emerge/solve_interfaces/cudss_interface.py +20 -1
- emerge/_emerge/solver.py +2 -2
- {emerge-1.0.6.dist-info → emerge-1.1.0.dist-info}/METADATA +9 -4
- {emerge-1.0.6.dist-info → emerge-1.1.0.dist-info}/RECORD +26 -24
- {emerge-1.0.6.dist-info → emerge-1.1.0.dist-info}/WHEEL +0 -0
- {emerge-1.0.6.dist-info → emerge-1.1.0.dist-info}/entry_points.txt +0 -0
- {emerge-1.0.6.dist-info → emerge-1.1.0.dist-info}/licenses/LICENSE +0 -0
emerge/_emerge/mesher.py
CHANGED
|
@@ -75,6 +75,9 @@ class Mesher:
|
|
|
75
75
|
self.objects: list[GeoObject] = []
|
|
76
76
|
self.size_definitions: list[tuple[int, float]] = []
|
|
77
77
|
self.mesh_fields: list[int] = []
|
|
78
|
+
self._amr_fields: list[int] = []
|
|
79
|
+
self._amr_coords: np.ndarray = None
|
|
80
|
+
self._amr_sizes: np.ndarray = None
|
|
78
81
|
self.min_size: float = None
|
|
79
82
|
self.max_size: float = None
|
|
80
83
|
self.periodic_cell: PeriodicCell = None
|
|
@@ -172,11 +175,11 @@ class Mesher:
|
|
|
172
175
|
gmsh.model.mesh.set_periodic(2, face2.tags, face1.tags, translation)
|
|
173
176
|
|
|
174
177
|
def set_algorithm(self,
|
|
175
|
-
obj: GeoObject,
|
|
176
178
|
algorithm: Algorithm3D) -> None:
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
179
|
+
|
|
180
|
+
gmsh.option.setNumber("General.NumThreads", 16)
|
|
181
|
+
gmsh.option.setNumber("Mesh.Algorithm3D", algorithm.value)
|
|
182
|
+
|
|
180
183
|
def set_periodic_cell(self, cell: PeriodicCell, excluded_faces: Selection | None = None):
|
|
181
184
|
"""Sets the periodic cell information based on the PeriodicCell class object"""
|
|
182
185
|
if excluded_faces is None:
|
|
@@ -222,8 +225,13 @@ class Mesher:
|
|
|
222
225
|
gmsh.model.mesh.field.set_numbers(ctag, "CurvesList", tags)
|
|
223
226
|
gmsh.model.mesh.field.set_number(ctag, "VIn", max_size)
|
|
224
227
|
self.mesh_fields.append(ctag)
|
|
228
|
+
|
|
229
|
+
def _reset_amr_points(self) -> None:
|
|
230
|
+
for tag in self._amr_fields:
|
|
231
|
+
gmsh.model.mesh.field.remove(tag)
|
|
232
|
+
self._amr_fields = []
|
|
225
233
|
|
|
226
|
-
def
|
|
234
|
+
def _set_amr_point(self, tags: list[int], max_size: float) -> None:
|
|
227
235
|
"""Define the size of the mesh on a point
|
|
228
236
|
|
|
229
237
|
Args:
|
|
@@ -233,7 +241,7 @@ class Mesher:
|
|
|
233
241
|
ctag = gmsh.model.mesh.field.add("Constant")
|
|
234
242
|
gmsh.model.mesh.field.set_numbers(ctag, "PointsList", tags)
|
|
235
243
|
gmsh.model.mesh.field.set_number(ctag, "VIn", max_size)
|
|
236
|
-
self.
|
|
244
|
+
self._amr_fields.append(ctag)
|
|
237
245
|
|
|
238
246
|
def _configure_mesh_size(self, discretizer: Callable, resolution: float):
|
|
239
247
|
"""Defines the mesh sizes based on a discretization callable.
|
|
@@ -267,7 +275,7 @@ class Mesher:
|
|
|
267
275
|
logger.debug(f'Setting mesh size:{1000*size:.3f}mm in domains: {tag}')
|
|
268
276
|
self._set_size_in_domain([tag,], size)
|
|
269
277
|
|
|
270
|
-
gmsh.model.mesh.field.setNumbers(mintag, "FieldsList", self.mesh_fields)
|
|
278
|
+
gmsh.model.mesh.field.setNumbers(mintag, "FieldsList", self.mesh_fields + self._amr_fields)
|
|
271
279
|
gmsh.model.mesh.field.setAsBackgroundMesh(mintag)
|
|
272
280
|
|
|
273
281
|
for tag, size in self.size_definitions:
|
|
@@ -279,11 +287,53 @@ class Mesher:
|
|
|
279
287
|
logger.trace(f'Unsetting mesh size constraint for domains: {dimtags}')
|
|
280
288
|
for dimtag in dimtags:
|
|
281
289
|
gmsh.model.mesh.setSizeFromBoundary(dimtag[0], dimtag[1], 0)
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def add_refinement_points(self, coords: np.ndarray, sizes: np.ndarray) -> None:
|
|
293
|
+
if self._amr_coords is None:
|
|
294
|
+
self._amr_coords = coords
|
|
295
|
+
else:
|
|
296
|
+
self._amr_coords = np.hstack((self._amr_coords, coords))
|
|
297
|
+
|
|
298
|
+
if self._amr_sizes is None:
|
|
299
|
+
self._amr_sizes = sizes
|
|
300
|
+
else:
|
|
301
|
+
self._amr_sizes = np.hstack((self._amr_sizes, sizes))
|
|
282
302
|
|
|
303
|
+
def set_refinement_function(self,
|
|
304
|
+
refinement: float,
|
|
305
|
+
gr: float = 1.5,
|
|
306
|
+
_qf: float = 1.0):
|
|
307
|
+
xs = self._amr_coords[0,:]
|
|
308
|
+
ys = self._amr_coords[1,:]
|
|
309
|
+
zs = self._amr_coords[2,:]
|
|
310
|
+
newsize = refinement*self._amr_sizes
|
|
311
|
+
A = newsize/gr
|
|
312
|
+
B = (1-gr)/gr
|
|
313
|
+
from numba import njit, i8, f8
|
|
314
|
+
|
|
315
|
+
@njit(f8(i8,i8,f8,f8,f8,f8), nogil=True, fastmath=True, parallel=False)
|
|
316
|
+
def func(dim, tag, x, y, z, lc):
|
|
317
|
+
sizes = np.maximum(newsize, A - B * _qf*np.sqrt((x-xs)**2 + (y-ys)**2 + (z-zs)**2))
|
|
318
|
+
return min(lc, float(np.min(sizes)))
|
|
319
|
+
gmsh.model.mesh.setSizeCallback(func)
|
|
320
|
+
|
|
321
|
+
def add_refinement_point(self,
|
|
322
|
+
coordinate: np.ndarray,
|
|
323
|
+
refinement: float,
|
|
324
|
+
size: float,
|
|
325
|
+
gr: float = 1.5):
|
|
326
|
+
x0, y0, z0 = coordinate
|
|
327
|
+
disttag = gmsh.model.mesh.field.add("MathEval")
|
|
328
|
+
newsize = refinement*size
|
|
329
|
+
funcstr = f"({newsize})/({gr}) - (1-{gr})/({gr}) * Sqrt((x-({x0}))^2+ (y-({y0}))^2 + (z-({z0}))^2)"
|
|
330
|
+
gmsh.model.mesh.field.setString(disttag, "F", funcstr)
|
|
331
|
+
self.mesh_fields.append(disttag)
|
|
332
|
+
|
|
283
333
|
def set_boundary_size(self,
|
|
284
334
|
boundary: GeoObject | Selection | Iterable,
|
|
285
335
|
size:float,
|
|
286
|
-
growth_rate: float =
|
|
336
|
+
growth_rate: float = 3,
|
|
287
337
|
max_size: float | None = None) -> None:
|
|
288
338
|
"""Refine the mesh size along the boundary of a conducting surface
|
|
289
339
|
|
|
@@ -305,8 +355,8 @@ class Mesher:
|
|
|
305
355
|
self._check_ready()
|
|
306
356
|
max_size = self.max_size
|
|
307
357
|
|
|
308
|
-
growth_distance = np.log10(max_size/size)/np.log10(growth_rate)
|
|
309
|
-
|
|
358
|
+
#growth_distance = np.log10(max_size/size)/np.log10(growth_rate)
|
|
359
|
+
growth_distance = (growth_rate*max_size - size)/(growth_rate-1)
|
|
310
360
|
logger.debug(f'Setting boundary size for region {dimtags} to {size*1000:.3f}mm, GR={growth_rate:.3f}, dist={growth_distance*1000:.2f}mm, Max={max_size*1000:.3f}mm')
|
|
311
361
|
|
|
312
362
|
nodes = gmsh.model.getBoundary(dimtags, combined=False, oriented=False, recursive=False)
|
|
@@ -323,7 +373,7 @@ class Mesher:
|
|
|
323
373
|
gmsh.model.mesh.field.setNumber(thtag, "SizeMin", size)
|
|
324
374
|
gmsh.model.mesh.field.setNumber(thtag, "SizeMax", max_size)
|
|
325
375
|
gmsh.model.mesh.field.setNumber(thtag, "DistMin", size)
|
|
326
|
-
gmsh.model.mesh.field.setNumber(thtag, "DistMax", growth_distance
|
|
376
|
+
gmsh.model.mesh.field.setNumber(thtag, "DistMax", growth_distance)
|
|
327
377
|
|
|
328
378
|
self.mesh_fields.append(thtag)
|
|
329
379
|
|