basicemergesolverhelperpackage 0.0.3__tar.gz → 0.0.4__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.
- {basicemergesolverhelperpackage-0.0.3 → basicemergesolverhelperpackage-0.0.4}/PKG-INFO +1 -1
- {basicemergesolverhelperpackage-0.0.3 → basicemergesolverhelperpackage-0.0.4}/setup.py +1 -1
- {basicemergesolverhelperpackage-0.0.3 → basicemergesolverhelperpackage-0.0.4}/src/basicemergesolverhelperpackage/EMergeHelperFunctions.py +256 -9
- {basicemergesolverhelperpackage-0.0.3 → basicemergesolverhelperpackage-0.0.4}/src/basicemergesolverhelperpackage.egg-info/PKG-INFO +1 -1
- {basicemergesolverhelperpackage-0.0.3 → basicemergesolverhelperpackage-0.0.4}/LICENSE +0 -0
- {basicemergesolverhelperpackage-0.0.3 → basicemergesolverhelperpackage-0.0.4}/README.md +0 -0
- {basicemergesolverhelperpackage-0.0.3 → basicemergesolverhelperpackage-0.0.4}/setup.cfg +0 -0
- {basicemergesolverhelperpackage-0.0.3 → basicemergesolverhelperpackage-0.0.4}/src/basicemergesolverhelperpackage/EMergeConstants.py +0 -0
- {basicemergesolverhelperpackage-0.0.3 → basicemergesolverhelperpackage-0.0.4}/src/basicemergesolverhelperpackage/__init__.py +0 -0
- {basicemergesolverhelperpackage-0.0.3 → basicemergesolverhelperpackage-0.0.4}/src/basicemergesolverhelperpackage.egg-info/SOURCES.txt +0 -0
- {basicemergesolverhelperpackage-0.0.3 → basicemergesolverhelperpackage-0.0.4}/src/basicemergesolverhelperpackage.egg-info/dependency_links.txt +0 -0
- {basicemergesolverhelperpackage-0.0.3 → basicemergesolverhelperpackage-0.0.4}/src/basicemergesolverhelperpackage.egg-info/requires.txt +0 -0
- {basicemergesolverhelperpackage-0.0.3 → basicemergesolverhelperpackage-0.0.4}/src/basicemergesolverhelperpackage.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: basicemergesolverhelperpackage
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.4
|
|
4
4
|
Summary: Mesh creation and plot utilities for EMerge solver or other FEM solver.
|
|
5
5
|
Home-page: https://github.com/LubomirJagos42/basic-emerge-solver-helper-package
|
|
6
6
|
Author: Lubomir Jagos
|
|
@@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
|
|
|
5
5
|
|
|
6
6
|
setup(
|
|
7
7
|
name="basicemergesolverhelperpackage",
|
|
8
|
-
version="0.0.
|
|
8
|
+
version="0.0.4",
|
|
9
9
|
author="Lubomir Jagos",
|
|
10
10
|
author_email="lubomir.jagos.42@gmail.com",
|
|
11
11
|
description="Mesh creation and plot utilities for EMerge solver or other FEM solver.",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import emerge as em
|
|
2
2
|
import emerge._emerge.geometry as emergeGeo
|
|
3
|
-
|
|
3
|
+
import emerge._emerge.physics.microwave.microwave_bc as emergeMicrowaveBC
|
|
4
|
+
from typing import Callable, Literal
|
|
4
5
|
import gmsh
|
|
5
6
|
import os
|
|
6
7
|
|
|
@@ -129,12 +130,29 @@ class EMergeHelperFunctions:
|
|
|
129
130
|
gmsh.model.addPhysicalGroup(2, objectTag2DList, name=groupName)
|
|
130
131
|
gmsh.model.addPhysicalGroup(3, objectTag3DList, name=groupName)
|
|
131
132
|
|
|
132
|
-
def addMaterial(self, name, materialObj, color="#000000", opacity: float =
|
|
133
|
+
def addMaterial(self, name, materialObj, color="#000000", opacity: float = 1.0):
|
|
133
134
|
self.materialList[name] = materialObj
|
|
134
135
|
self.materialList[name].color = color
|
|
135
136
|
self.materialList[name].opacity = opacity
|
|
136
137
|
|
|
137
|
-
def
|
|
138
|
+
def getMaterial(self, name):
|
|
139
|
+
#
|
|
140
|
+
# Get material from internal material list
|
|
141
|
+
#
|
|
142
|
+
materialObj = self.materialList[name] if name in self.materialList.keys() else None
|
|
143
|
+
|
|
144
|
+
#
|
|
145
|
+
# If material not found try to scan all geometries and their assigned materials if it will be found
|
|
146
|
+
#
|
|
147
|
+
if materialObj == None:
|
|
148
|
+
for geometryObj in self.simulationObj.state.manager.geometry_list[self.simulationObj.modelname].values():
|
|
149
|
+
if geometryObj.material.name == name:
|
|
150
|
+
materialObj = geometryObj.material
|
|
151
|
+
break
|
|
152
|
+
|
|
153
|
+
return materialObj
|
|
154
|
+
|
|
155
|
+
def setMaterialColor(self, name, color="#000000", opacity: float = 1.0):
|
|
138
156
|
"""Setter for color and opacity
|
|
139
157
|
:param name: Name of material
|
|
140
158
|
:param color: Color string in html for like #FF0000 (red)
|
|
@@ -143,7 +161,29 @@ class EMergeHelperFunctions:
|
|
|
143
161
|
self.materialList[name].color = color
|
|
144
162
|
self.materialList[name].opacity = opacity
|
|
145
163
|
|
|
146
|
-
def addPort(
|
|
164
|
+
def addPort(
|
|
165
|
+
self,
|
|
166
|
+
name="",
|
|
167
|
+
portStart=[0.0, 0.0, 0.0],
|
|
168
|
+
width=0.0,
|
|
169
|
+
height=0.0,
|
|
170
|
+
R=50.0,
|
|
171
|
+
direction=em.ZAX,
|
|
172
|
+
excitationAmplitude:float=0.0,
|
|
173
|
+
geometryObject:em._emerge.geometry.GeoObject=None,
|
|
174
|
+
portNumber:int=-1,
|
|
175
|
+
|
|
176
|
+
modalModeType: Literal['TE','TM','TEM'] | None = None,
|
|
177
|
+
modalMixedMaterials: bool = False,
|
|
178
|
+
modalImpedanceDefinition: Literal['PV','PI','VI'] = 'PV',
|
|
179
|
+
|
|
180
|
+
rectangularWaveguideMode: tuple[int, int] = (0, 0),
|
|
181
|
+
rectangularWaveguidePermittivity: float = 1.0,
|
|
182
|
+
|
|
183
|
+
coaxPortInnerRadius: float = 0.0,
|
|
184
|
+
coaxPortOuterRadius: float = 0.0,
|
|
185
|
+
coaxPortPermittivity: float = 1.0,
|
|
186
|
+
):
|
|
147
187
|
self.portList[name] = {}
|
|
148
188
|
self.portList[name]['portStart'] = portStart
|
|
149
189
|
self.portList[name]['width'] = width
|
|
@@ -154,9 +194,103 @@ class EMergeHelperFunctions:
|
|
|
154
194
|
self.portList[name]['object'] = geometryObject
|
|
155
195
|
self.portList[name]['portNumber'] = self._generatedPortIndex if portNumber == -1 else portNumber
|
|
156
196
|
|
|
197
|
+
self.portList[name]["modalModeType"] = modalModeType
|
|
198
|
+
self.portList[name]["modalMixedMaterials"] = modalMixedMaterials
|
|
199
|
+
self.portList[name]["modalImpedanceDefinition"] = modalImpedanceDefinition
|
|
200
|
+
|
|
201
|
+
self.portList[name]["rectangularWaveguideMode"] = rectangularWaveguideMode
|
|
202
|
+
self.portList[name]["rectangularWaveguidePermittivity"] = rectangularWaveguidePermittivity
|
|
203
|
+
|
|
204
|
+
self.portList[name]["coaxPortInnerRadius"] = coaxPortInnerRadius
|
|
205
|
+
self.portList[name]["coaxPortOuterRadius"] = coaxPortOuterRadius
|
|
206
|
+
self.portList[name]["coaxPortPermittivity"] = coaxPortPermittivity
|
|
207
|
+
|
|
157
208
|
if portNumber == -1:
|
|
158
209
|
self._generatedPortIndex += 1
|
|
159
210
|
|
|
211
|
+
def addLumpedPort(
|
|
212
|
+
self,
|
|
213
|
+
name = "",
|
|
214
|
+
portStart = [0.0, 0.0, 0.0],
|
|
215
|
+
width = 0.0,
|
|
216
|
+
height = 0.0,
|
|
217
|
+
R = 50.0,
|
|
218
|
+
direction = em.ZAX,
|
|
219
|
+
power:float = 0.0,
|
|
220
|
+
geometryObject:em._emerge.geometry.GeoObject = None,
|
|
221
|
+
portNumber:int = -1
|
|
222
|
+
):
|
|
223
|
+
self.addPort(
|
|
224
|
+
name=name,
|
|
225
|
+
portStart=portStart,
|
|
226
|
+
width=width,
|
|
227
|
+
height=height,
|
|
228
|
+
R=R,
|
|
229
|
+
direction=direction,
|
|
230
|
+
excitationAmplitude=power,
|
|
231
|
+
geometryObject=geometryObject,
|
|
232
|
+
portNumber=portNumber
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
def addModalPort(
|
|
236
|
+
self,
|
|
237
|
+
name = "",
|
|
238
|
+
mode: Literal["TE", "TM", "TEM"] = "TE",
|
|
239
|
+
mixedMaterials: bool = False,
|
|
240
|
+
impedanceDefinition: Literal["PV", "PI", "VI"] = "PV",
|
|
241
|
+
power:float = 0.0,
|
|
242
|
+
geometryObject:em._emerge.geometry.GeoObject = None,
|
|
243
|
+
portNumber:int = -1
|
|
244
|
+
):
|
|
245
|
+
self.addPort(
|
|
246
|
+
name=name,
|
|
247
|
+
modalModeType=mode,
|
|
248
|
+
modalMixedMaterials=mixedMaterials,
|
|
249
|
+
modalImpedanceDefinition=impedanceDefinition,
|
|
250
|
+
excitationAmplitude=power,
|
|
251
|
+
geometryObject=geometryObject,
|
|
252
|
+
portNumber=portNumber
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
def addRectangularWaveguidePort(
|
|
256
|
+
self,
|
|
257
|
+
name = "",
|
|
258
|
+
mode: tuple[int, int] = (0,0),
|
|
259
|
+
er: float = 1.0,
|
|
260
|
+
power:float = 1.0,
|
|
261
|
+
geometryObject:em._emerge.geometry.GeoObject = None,
|
|
262
|
+
portNumber:int = -1
|
|
263
|
+
):
|
|
264
|
+
self.addPort(
|
|
265
|
+
name=name,
|
|
266
|
+
rectangularWaveguideMode = mode,
|
|
267
|
+
rectangularWaveguidePermittivity = er,
|
|
268
|
+
excitationAmplitude=power,
|
|
269
|
+
geometryObject=geometryObject,
|
|
270
|
+
portNumber=portNumber
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
def addCoaxPort(
|
|
274
|
+
self,
|
|
275
|
+
name = "",
|
|
276
|
+
inner_radius: float = 0.0,
|
|
277
|
+
outer_radius: float = 0.0,
|
|
278
|
+
er: float = 1.0,
|
|
279
|
+
power:float = 1.0,
|
|
280
|
+
geometryObject:em._emerge.geometry.GeoObject = None,
|
|
281
|
+
portNumber:int = -1
|
|
282
|
+
):
|
|
283
|
+
self.addPort(
|
|
284
|
+
name=name,
|
|
285
|
+
coaxPortInnerRadius = inner_radius,
|
|
286
|
+
coaxPortOuterRadius = outer_radius,
|
|
287
|
+
coaxPortPermittivity = er,
|
|
288
|
+
excitationAmplitude=power,
|
|
289
|
+
geometryObject=geometryObject,
|
|
290
|
+
portNumber=portNumber
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
|
|
160
294
|
def getPort(self, name):
|
|
161
295
|
return self.portList[name]
|
|
162
296
|
|
|
@@ -172,8 +306,9 @@ class EMergeHelperFunctions:
|
|
|
172
306
|
if portObj['portNumber'] == name:
|
|
173
307
|
return portObj['portNumber']
|
|
174
308
|
|
|
175
|
-
def setPortAsLumpedPort(self, name, searchObjectName=""):
|
|
309
|
+
def setPortAsLumpedPort(self, name, searchObjectName="") -> list[emergeMicrowaveBC.LumpedPort]:
|
|
176
310
|
portObj = self.getPort(name)
|
|
311
|
+
resultBoundaryConditionList = []
|
|
177
312
|
|
|
178
313
|
#
|
|
179
314
|
# Port object can be splitted since there was fragmentation operation in EMerge
|
|
@@ -181,8 +316,8 @@ class EMergeHelperFunctions:
|
|
|
181
316
|
portGeometryObjectList = self.getAllObjectByName(name if searchObjectName == "" else searchObjectName)
|
|
182
317
|
for geometryObj in portGeometryObjectList:
|
|
183
318
|
if portObj['excitationAmplitude'] > 0.0:
|
|
184
|
-
self.simulationObj.mw.bc.LumpedPort(
|
|
185
|
-
geometryObj,
|
|
319
|
+
resultObj = self.simulationObj.mw.bc.LumpedPort(
|
|
320
|
+
face=geometryObj,
|
|
186
321
|
port_number=portObj['portNumber'],
|
|
187
322
|
width=portObj['width'],
|
|
188
323
|
height=portObj['height'],
|
|
@@ -191,17 +326,82 @@ class EMergeHelperFunctions:
|
|
|
191
326
|
power=portObj['excitationAmplitude']
|
|
192
327
|
)
|
|
193
328
|
else:
|
|
194
|
-
self.simulationObj.mw.bc.LumpedPort(
|
|
195
|
-
geometryObj,
|
|
329
|
+
resultObj = self.simulationObj.mw.bc.LumpedPort(
|
|
330
|
+
face=geometryObj,
|
|
196
331
|
port_number=portObj['portNumber'],
|
|
197
332
|
width=portObj['width'],
|
|
198
333
|
height=portObj['height'],
|
|
199
334
|
direction=portObj['direction'],
|
|
200
335
|
Z0=portObj['R']
|
|
201
336
|
)
|
|
337
|
+
resultBoundaryConditionList.append(resultObj)
|
|
202
338
|
|
|
203
339
|
self._temporaryInternalPortIndex += 1
|
|
204
340
|
|
|
341
|
+
return resultBoundaryConditionList
|
|
342
|
+
|
|
343
|
+
def setPortAsModalPort(self, name, searchObjectName="") -> list[emergeMicrowaveBC.ModalPort]:
|
|
344
|
+
"""Experimental implementation not tested on real world example!!!"""
|
|
345
|
+
|
|
346
|
+
resultBoundaryConditionList = []
|
|
347
|
+
|
|
348
|
+
portObj = self.getPort(name)
|
|
349
|
+
portGeometryObjectList = self.getAllObjectByName(name if searchObjectName == "" else searchObjectName)
|
|
350
|
+
|
|
351
|
+
for geometryObj in portGeometryObjectList:
|
|
352
|
+
resultObj = self.simulationObj.mw.bc.ModalPort(
|
|
353
|
+
face = geometryObj,
|
|
354
|
+
port_number=portObj['portNumber'],
|
|
355
|
+
power = portObj['excitationAmplitude'],
|
|
356
|
+
modetype = portObj["modalModeType"],
|
|
357
|
+
number_of_modes = 1,
|
|
358
|
+
mixed_materials = portObj["modalMixedMaterials"],
|
|
359
|
+
impedance_definition = portObj["modalImpedanceDefinition"]
|
|
360
|
+
)
|
|
361
|
+
resultBoundaryConditionList.append(resultObj)
|
|
362
|
+
|
|
363
|
+
return resultBoundaryConditionList
|
|
364
|
+
|
|
365
|
+
def setPortAsRectangularWaveguidePort(self, name, searchObjectName="") -> list[emergeMicrowaveBC.RectangularWaveguide]:
|
|
366
|
+
"""Experimental implementation not tested on real world example!!!"""
|
|
367
|
+
|
|
368
|
+
resultBoundaryConditionList = []
|
|
369
|
+
|
|
370
|
+
portObj = self.getPort(name)
|
|
371
|
+
portGeometryObjectList = self.getAllObjectByName(name if searchObjectName == "" else searchObjectName)
|
|
372
|
+
|
|
373
|
+
for geometryObj in portGeometryObjectList:
|
|
374
|
+
resultObj = self.simulationObj.mw.bc.RectangularWaveguide(
|
|
375
|
+
face = geometryObj,
|
|
376
|
+
port_number=portObj['portNumber'],
|
|
377
|
+
power = portObj['excitationAmplitude'],
|
|
378
|
+
mode = portObj["rectangularWaveguideMode"],
|
|
379
|
+
er = portObj["rectangularWaveguidePermittivity"]
|
|
380
|
+
)
|
|
381
|
+
resultBoundaryConditionList.append(resultObj)
|
|
382
|
+
|
|
383
|
+
return resultBoundaryConditionList
|
|
384
|
+
|
|
385
|
+
def setPortAsCoaxPort(self, name, searchObjectName="") -> list[emergeMicrowaveBC.CoaxPort]:
|
|
386
|
+
"""Experimental implementation not tested on real world example!!!"""
|
|
387
|
+
|
|
388
|
+
resultBoundaryConditionList = []
|
|
389
|
+
|
|
390
|
+
portObj = self.getPort(name)
|
|
391
|
+
portGeometryObjectList = self.getAllObjectByName(name if searchObjectName == "" else searchObjectName)
|
|
392
|
+
|
|
393
|
+
for geometryObj in portGeometryObjectList:
|
|
394
|
+
resultObj = self.simulationObj.mw.bc.CoaxPort(
|
|
395
|
+
face = geometryObj,
|
|
396
|
+
port_number=portObj['portNumber'],
|
|
397
|
+
power = portObj['excitationAmplitude'],
|
|
398
|
+
rad_in_out = (portObj["coaxPortInnerRadius"], portObj["coaxPortInnerRadius"]),
|
|
399
|
+
er = portObj["coaxPortPermittivity"]
|
|
400
|
+
)
|
|
401
|
+
resultBoundaryConditionList.append(resultObj)
|
|
402
|
+
|
|
403
|
+
return resultBoundaryConditionList
|
|
404
|
+
|
|
205
405
|
def plotSParamUsingPortName(self, sourcePortName, targetPortName, dblim=[-40, 0], plotSmithChart=False):
|
|
206
406
|
sourcePortNumber = self.getPortNumber(sourcePortName)
|
|
207
407
|
targetPortNumber = self.getPortNumber(targetPortName)
|
|
@@ -246,3 +446,50 @@ class EMergeHelperFunctions:
|
|
|
246
446
|
|
|
247
447
|
for geoObject in objectList:
|
|
248
448
|
self.simulationObj.display.add_object(geoObject, opacity=opacity)
|
|
449
|
+
|
|
450
|
+
def create_emerge_plane_data(self, port_start, port_stop, normal):
|
|
451
|
+
"""
|
|
452
|
+
Computes origin, u, and v vectors for an EMerge Plane using
|
|
453
|
+
start/stop diagonal points and a surface normal vector.
|
|
454
|
+
|
|
455
|
+
Inputs can be FreeCAD vectors or standard (x, y, z) tuples.
|
|
456
|
+
"""
|
|
457
|
+
# 1. Convert everything to numpy arrays for clean math
|
|
458
|
+
p1 = np.array([port_start[0], port_start[1], port_start[2]])
|
|
459
|
+
p4 = np.array([port_stop[0], port_stop[1], port_stop[2]])
|
|
460
|
+
n = np.array([normal[0], normal[1], normal[2]])
|
|
461
|
+
|
|
462
|
+
# Normalize the normal vector to ensure it is a unit vector
|
|
463
|
+
n = n / np.linalg.norm(n)
|
|
464
|
+
|
|
465
|
+
# 2. Calculate the full diagonal vector across the port
|
|
466
|
+
diag = p4 - p1
|
|
467
|
+
|
|
468
|
+
# 3. Project the diagonal vector to eliminate any component pointing
|
|
469
|
+
# along the normal (ensures the math stays strictly flat on the 2D plane)
|
|
470
|
+
diag_planar = diag - np.dot(diag, n) * n
|
|
471
|
+
|
|
472
|
+
# 4. Determine the primary coordinate alignment for the 'u' axis.
|
|
473
|
+
# We choose an axis that isn't parallel to our normal vector.
|
|
474
|
+
if abs(n[0]) < 0.9:
|
|
475
|
+
ref_dir = np.array([1.0, 0.0, 0.0]) # Fallback to X axis alignment
|
|
476
|
+
else:
|
|
477
|
+
ref_dir = np.array([0.0, 1.0, 0.0]) # Fallback to Y axis alignment
|
|
478
|
+
|
|
479
|
+
# Generate an orthogonal direction for 'u' using a cross product
|
|
480
|
+
u_direction = np.cross(n, ref_dir)
|
|
481
|
+
u_axis = u_direction / np.linalg.norm(u_direction)
|
|
482
|
+
|
|
483
|
+
# Generate the perpendicular 'v' direction
|
|
484
|
+
v_axis = np.cross(n, u_axis)
|
|
485
|
+
|
|
486
|
+
# 5. Project the planar diagonal onto our newly established u and v axes
|
|
487
|
+
u_magnitude = np.dot(diag_planar, u_axis)
|
|
488
|
+
v_magnitude = np.dot(diag_planar, v_axis)
|
|
489
|
+
|
|
490
|
+
# 6. Reconstruct the final u and v vectors as clean 3D tuples
|
|
491
|
+
u = tuple(u_axis * u_magnitude)
|
|
492
|
+
v = tuple(v_axis * v_magnitude)
|
|
493
|
+
origin = tuple(p1)
|
|
494
|
+
|
|
495
|
+
return origin, u, v
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: basicemergesolverhelperpackage
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.4
|
|
4
4
|
Summary: Mesh creation and plot utilities for EMerge solver or other FEM solver.
|
|
5
5
|
Home-page: https://github.com/LubomirJagos42/basic-emerge-solver-helper-package
|
|
6
6
|
Author: Lubomir Jagos
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|