basicemergesolverhelperpackage 0.0.2__tar.gz → 0.0.3__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.2 → basicemergesolverhelperpackage-0.0.3}/PKG-INFO +1 -1
- {basicemergesolverhelperpackage-0.0.2 → basicemergesolverhelperpackage-0.0.3}/setup.py +2 -2
- basicemergesolverhelperpackage-0.0.3/src/basicemergesolverhelperpackage/EMergeConstants.py +44 -0
- basicemergesolverhelperpackage-0.0.3/src/basicemergesolverhelperpackage/EMergeHelperFunctions.py +248 -0
- basicemergesolverhelperpackage-0.0.3/src/basicemergesolverhelperpackage/__init__.py +9 -0
- {basicemergesolverhelperpackage-0.0.2 → basicemergesolverhelperpackage-0.0.3}/src/basicemergesolverhelperpackage.egg-info/PKG-INFO +1 -1
- {basicemergesolverhelperpackage-0.0.2 → basicemergesolverhelperpackage-0.0.3}/src/basicemergesolverhelperpackage.egg-info/SOURCES.txt +3 -0
- basicemergesolverhelperpackage-0.0.3/src/basicemergesolverhelperpackage.egg-info/top_level.txt +1 -0
- basicemergesolverhelperpackage-0.0.2/src/basicemergesolverhelperpackage.egg-info/top_level.txt +0 -1
- {basicemergesolverhelperpackage-0.0.2 → basicemergesolverhelperpackage-0.0.3}/LICENSE +0 -0
- {basicemergesolverhelperpackage-0.0.2 → basicemergesolverhelperpackage-0.0.3}/README.md +0 -0
- {basicemergesolverhelperpackage-0.0.2 → basicemergesolverhelperpackage-0.0.3}/setup.cfg +0 -0
- {basicemergesolverhelperpackage-0.0.2 → basicemergesolverhelperpackage-0.0.3}/src/basicemergesolverhelperpackage.egg-info/dependency_links.txt +0 -0
- {basicemergesolverhelperpackage-0.0.2 → basicemergesolverhelperpackage-0.0.3}/src/basicemergesolverhelperpackage.egg-info/requires.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.3
|
|
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,14 +5,14 @@ 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.3",
|
|
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.",
|
|
12
12
|
long_description="Helper methods to make easier to do simulation when working with imported STEP files from FreeCAD",
|
|
13
13
|
long_description_content_type="text/markdown",
|
|
14
14
|
url="https://github.com/LubomirJagos42/basic-emerge-solver-helper-package",
|
|
15
|
-
packages=find_packages(where=
|
|
15
|
+
packages=find_packages(where="src"),
|
|
16
16
|
package_dir={"": "src"},
|
|
17
17
|
classifiers=[
|
|
18
18
|
"Programming Language :: Python :: 3",
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
m = 1.0
|
|
4
|
+
cm = 1e-2
|
|
5
|
+
mm = 1e-3
|
|
6
|
+
um = 1e-6
|
|
7
|
+
nm = 1e-9
|
|
8
|
+
|
|
9
|
+
GOhm = 1e9
|
|
10
|
+
MOhm = 1e6
|
|
11
|
+
kOhm = 1e3
|
|
12
|
+
Ohm = 1.0
|
|
13
|
+
mOhm = 1e-3
|
|
14
|
+
uOhm = 1e-6
|
|
15
|
+
|
|
16
|
+
H = 1.0
|
|
17
|
+
mH = 1e-3
|
|
18
|
+
uH = 1e-6
|
|
19
|
+
nH = 1e-9
|
|
20
|
+
pH = 1e-12
|
|
21
|
+
|
|
22
|
+
F = 1.0
|
|
23
|
+
mF = 1e-3
|
|
24
|
+
uF = 1e-6
|
|
25
|
+
nF = 1e-9
|
|
26
|
+
pF = 1e-12
|
|
27
|
+
|
|
28
|
+
class series_impedance:
|
|
29
|
+
def __init__(self, R=0.0, L=0.0, C=0.0):
|
|
30
|
+
self.R = R
|
|
31
|
+
self.L = L
|
|
32
|
+
self.C = C
|
|
33
|
+
|
|
34
|
+
def __call__(self, f):
|
|
35
|
+
return self.R + 1j*2*np.pi*f*self.L + (0.0 if self.C==0.0 else 1/(1j*2*np.pi*f*self.C))
|
|
36
|
+
|
|
37
|
+
class parallel_impedance:
|
|
38
|
+
def __init__(self, R=0.0, L=0.0, C=0.0):
|
|
39
|
+
self.R = R
|
|
40
|
+
self.L = L
|
|
41
|
+
self.C = C
|
|
42
|
+
|
|
43
|
+
def __call__(self, f):
|
|
44
|
+
return 1/((0.0 if self.R==0.0 else 1/self.R) + (0.0 if self.L==0 else 1/(1j*2*np.pi*f*self.L)) + 1j*2*np.pi*f*self.C)
|
basicemergesolverhelperpackage-0.0.3/src/basicemergesolverhelperpackage/EMergeHelperFunctions.py
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import emerge as em
|
|
2
|
+
import emerge._emerge.geometry as emergeGeo
|
|
3
|
+
from typing import Callable
|
|
4
|
+
import gmsh
|
|
5
|
+
import os
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
from emerge.plot import smith, plot_sp
|
|
9
|
+
|
|
10
|
+
class EMergeHelperFunctions:
|
|
11
|
+
simulationObj = None
|
|
12
|
+
materialList = {}
|
|
13
|
+
portList = {}
|
|
14
|
+
_generatedPortIndex = 1
|
|
15
|
+
_temporaryInternalPortIndex = 1 #this shouldn't exists, but it's helper counter if port somehow will be from more objects
|
|
16
|
+
|
|
17
|
+
def __init__(self, simulationObj):
|
|
18
|
+
self.simulationObj = simulationObj
|
|
19
|
+
print("EMerge helper created")
|
|
20
|
+
|
|
21
|
+
def getAllObjectByName(self, name: str):
|
|
22
|
+
resultObjList = []
|
|
23
|
+
for geometryObj in self.simulationObj.state.manager.geometry_list[self.simulationObj.modelname].values():
|
|
24
|
+
if geometryObj.name == name or geometryObj.name.startswith(name+"_"):
|
|
25
|
+
resultObjList.append(geometryObj)
|
|
26
|
+
|
|
27
|
+
return resultObjList
|
|
28
|
+
|
|
29
|
+
def getObjectSurface(self, name: str):
|
|
30
|
+
boundaryObjList = []
|
|
31
|
+
for geometryObj in self.simulationObj.state.manager.geometry_list[self.simulationObj.modelname].values():
|
|
32
|
+
if geometryObj.name == name or geometryObj.name.startswith(name+"_"):
|
|
33
|
+
if isinstance(geometryObj, emergeGeo.GeoSurface):
|
|
34
|
+
boundaryObjList.append(geometryObj)
|
|
35
|
+
else:
|
|
36
|
+
boundaryObjList.append(geometryObj.boundary())
|
|
37
|
+
|
|
38
|
+
return boundaryObjList
|
|
39
|
+
|
|
40
|
+
def getObjectVolume(self, name: str):
|
|
41
|
+
resultObjList = []
|
|
42
|
+
for geometryObj in self.simulationObj.state.manager.geometry_list[self.simulationObj.modelname].values():
|
|
43
|
+
if geometryObj.name == name or geometryObj.name.startswith(name+"_"):
|
|
44
|
+
if isinstance(geometryObj, emergeGeo.GeoVolume):
|
|
45
|
+
resultObjList.append(geometryObj)
|
|
46
|
+
|
|
47
|
+
return resultObjList
|
|
48
|
+
|
|
49
|
+
def importStepFile(self, name:str, filename:str,directory:list[str] | str = "", unit:float=1.0, priority:int=-1, materialName:str = ""):
|
|
50
|
+
targetDirectory:str = ""
|
|
51
|
+
if directory != "" and directory != []:
|
|
52
|
+
if type(directory) == str:
|
|
53
|
+
targetDirectory = directory
|
|
54
|
+
elif type(directory) == list:
|
|
55
|
+
for dirName in directory:
|
|
56
|
+
targetDirectory = os.path.join(targetDirectory, dirName)
|
|
57
|
+
|
|
58
|
+
stepObjectGroup = em.geo.step.STEPItems(name=name, filename=os.path.join(targetDirectory, filename), unit=unit)
|
|
59
|
+
|
|
60
|
+
for geoObj in stepObjectGroup.objects:
|
|
61
|
+
geoObj.prio_set(priority)
|
|
62
|
+
if materialName != "":
|
|
63
|
+
geoObj.set_material(self.materialList[materialName])
|
|
64
|
+
|
|
65
|
+
def setObjSize(self, name:str, size:float):
|
|
66
|
+
objectList = self.getAllObjectByName(name)
|
|
67
|
+
for obj in objectList:
|
|
68
|
+
self.simulationObj.mesher.set_size(obj, size)
|
|
69
|
+
|
|
70
|
+
def setObjBoundarySize(self, name:str, size:float):
|
|
71
|
+
objectList = self.getObjectSurface(name)
|
|
72
|
+
for obj in objectList:
|
|
73
|
+
self.simulationObj.mesher.set_boundary_size(obj, size)
|
|
74
|
+
|
|
75
|
+
def setObjFaceSize(self, name:str, size:float):
|
|
76
|
+
objectList = self.getObjectSurface(name)
|
|
77
|
+
for obj in objectList:
|
|
78
|
+
self.simulationObj.mesher.set_face_size(obj, size)
|
|
79
|
+
|
|
80
|
+
def setObjVolumeSize(self, name:str, size:float):
|
|
81
|
+
objectList = self.getObjectVolume(name)
|
|
82
|
+
for obj in objectList:
|
|
83
|
+
self.simulationObj.mesher.set_domain_size(obj, size)
|
|
84
|
+
|
|
85
|
+
def setLumpedElementToObject(
|
|
86
|
+
self,
|
|
87
|
+
name: str,
|
|
88
|
+
impedance_function: Callable | None = None,
|
|
89
|
+
width: float | None = None,
|
|
90
|
+
height: float | None = None,
|
|
91
|
+
):
|
|
92
|
+
objectList = self.getObjectSurface(name)
|
|
93
|
+
for obj in objectList:
|
|
94
|
+
self.simulationObj.mw.bc.LumpedElement(face=obj, impedance_function=impedance_function, width=width, height=height)
|
|
95
|
+
|
|
96
|
+
def setBoundaryConditionToObject(self, name: str, type: str):
|
|
97
|
+
objectList = self.getObjectSurface(name)
|
|
98
|
+
for obj in objectList:
|
|
99
|
+
if type.lower() == "absorbing":
|
|
100
|
+
self.simulationObj.mw.bc.AbsorbingBoundary(obj)
|
|
101
|
+
elif type == "PEC":
|
|
102
|
+
self.simulationObj.mw.bc.PEC(obj)
|
|
103
|
+
elif type == "PMC":
|
|
104
|
+
self.simulationObj.mw.bc.PMC(obj)
|
|
105
|
+
else:
|
|
106
|
+
raise Exception(f"ERROR: Unknown type of boundary condition: {type}")
|
|
107
|
+
|
|
108
|
+
def createGmshNamedGroup(self, geometryObjName: str, groupName: str, groupTag: int = -1, useBoundary: bool = False, useSuffixToRecognizeGeometryName: bool = True):
|
|
109
|
+
objectTag1DList = []
|
|
110
|
+
objectTag2DList = []
|
|
111
|
+
objectTag3DList = []
|
|
112
|
+
|
|
113
|
+
for geometryObj in self.simulationObj.state.manager.geometry_list[self.simulationObj.modelname].values():
|
|
114
|
+
if geometryObj.name == geometryObjName or geometryObj.name.startswith(geometryObjName + ('_' if useSuffixToRecognizeGeometryName else '')):
|
|
115
|
+
for tagTuple in (geometryObj.boundary().dimtags if (useBoundary and not isinstance(geometryObj, emergeGeo.GeoSurface)) else geometryObj.dimtags):
|
|
116
|
+
if tagTuple[0] == 1:
|
|
117
|
+
objectTag1DList.append(tagTuple[1])
|
|
118
|
+
if tagTuple[0] == 2:
|
|
119
|
+
objectTag2DList.append(tagTuple[1])
|
|
120
|
+
if tagTuple[0] == 3:
|
|
121
|
+
objectTag3DList.append(tagTuple[1])
|
|
122
|
+
|
|
123
|
+
if groupTag > -1:
|
|
124
|
+
gmsh.model.addPhysicalGroup(1, objectTag1DList, name=groupName, tag=groupTag)
|
|
125
|
+
gmsh.model.addPhysicalGroup(2, objectTag2DList, name=groupName, tag=groupTag + 1)
|
|
126
|
+
gmsh.model.addPhysicalGroup(3, objectTag3DList, name=groupName, tag=groupTag + 2)
|
|
127
|
+
else:
|
|
128
|
+
gmsh.model.addPhysicalGroup(1, objectTag1DList, name=groupName)
|
|
129
|
+
gmsh.model.addPhysicalGroup(2, objectTag2DList, name=groupName)
|
|
130
|
+
gmsh.model.addPhysicalGroup(3, objectTag3DList, name=groupName)
|
|
131
|
+
|
|
132
|
+
def addMaterial(self, name, materialObj, color="#000000", opacity: float = -89.0):
|
|
133
|
+
self.materialList[name] = materialObj
|
|
134
|
+
self.materialList[name].color = color
|
|
135
|
+
self.materialList[name].opacity = opacity
|
|
136
|
+
|
|
137
|
+
def setMaterialColor(self, name, color="#000000", opacity: float = -89.0):
|
|
138
|
+
"""Setter for color and opacity
|
|
139
|
+
:param name: Name of material
|
|
140
|
+
:param color: Color string in html for like #FF0000 (red)
|
|
141
|
+
:param opacity: Makes material transparent (0.0) or non-transparent (1.0)
|
|
142
|
+
"""
|
|
143
|
+
self.materialList[name].color = color
|
|
144
|
+
self.materialList[name].opacity = opacity
|
|
145
|
+
|
|
146
|
+
def addPort(self, name="", portStart=[0.0, 0.0, 0.0], width=0.0, height=0.0, R=50.0, direction=em.ZAX, excitationAmplitude:float=0.0, geometryObject:em._emerge.geometry.GeoObject=None, portNumber:int=-1):
|
|
147
|
+
self.portList[name] = {}
|
|
148
|
+
self.portList[name]['portStart'] = portStart
|
|
149
|
+
self.portList[name]['width'] = width
|
|
150
|
+
self.portList[name]['height'] = height
|
|
151
|
+
self.portList[name]['R'] = R
|
|
152
|
+
self.portList[name]['direction'] = direction
|
|
153
|
+
self.portList[name]['excitationAmplitude'] = excitationAmplitude
|
|
154
|
+
self.portList[name]['object'] = geometryObject
|
|
155
|
+
self.portList[name]['portNumber'] = self._generatedPortIndex if portNumber == -1 else portNumber
|
|
156
|
+
|
|
157
|
+
if portNumber == -1:
|
|
158
|
+
self._generatedPortIndex += 1
|
|
159
|
+
|
|
160
|
+
def getPort(self, name):
|
|
161
|
+
return self.portList[name]
|
|
162
|
+
|
|
163
|
+
def getPortByNumber(self, portNumber):
|
|
164
|
+
resultPortObj = None
|
|
165
|
+
for portObj in self.portList:
|
|
166
|
+
if portNumber == portObj['portNumber']:
|
|
167
|
+
resultPortObj = portObj
|
|
168
|
+
return resultPortObj
|
|
169
|
+
|
|
170
|
+
def getPortNumber(self, name):
|
|
171
|
+
for portObj in self.portList:
|
|
172
|
+
if portObj['portNumber'] == name:
|
|
173
|
+
return portObj['portNumber']
|
|
174
|
+
|
|
175
|
+
def setPortAsLumpedPort(self, name, searchObjectName=""):
|
|
176
|
+
portObj = self.getPort(name)
|
|
177
|
+
|
|
178
|
+
#
|
|
179
|
+
# Port object can be splitted since there was fragmentation operation in EMerge
|
|
180
|
+
#
|
|
181
|
+
portGeometryObjectList = self.getAllObjectByName(name if searchObjectName == "" else searchObjectName)
|
|
182
|
+
for geometryObj in portGeometryObjectList:
|
|
183
|
+
if portObj['excitationAmplitude'] > 0.0:
|
|
184
|
+
self.simulationObj.mw.bc.LumpedPort(
|
|
185
|
+
geometryObj,
|
|
186
|
+
port_number=portObj['portNumber'],
|
|
187
|
+
width=portObj['width'],
|
|
188
|
+
height=portObj['height'],
|
|
189
|
+
direction=portObj['direction'],
|
|
190
|
+
Z0=portObj['R'],
|
|
191
|
+
power=portObj['excitationAmplitude']
|
|
192
|
+
)
|
|
193
|
+
else:
|
|
194
|
+
self.simulationObj.mw.bc.LumpedPort(
|
|
195
|
+
geometryObj,
|
|
196
|
+
port_number=portObj['portNumber'],
|
|
197
|
+
width=portObj['width'],
|
|
198
|
+
height=portObj['height'],
|
|
199
|
+
direction=portObj['direction'],
|
|
200
|
+
Z0=portObj['R']
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
self._temporaryInternalPortIndex += 1
|
|
204
|
+
|
|
205
|
+
def plotSParamUsingPortName(self, sourcePortName, targetPortName, dblim=[-40, 0], plotSmithChart=False):
|
|
206
|
+
sourcePortNumber = self.getPortNumber(sourcePortName)
|
|
207
|
+
targetPortNumber = self.getPortNumber(targetPortName)
|
|
208
|
+
|
|
209
|
+
self.plotSParamUsingPortNumbers(sourcePortNumber, targetPortNumber, dblim, plotSmithChart)
|
|
210
|
+
|
|
211
|
+
def plotSParamUsingPortNumbers(self, sourcePortNumber, targetPortNumber, dblim=[-40, 0], xunit="GHz", plotSmithChart=False, plotInterpolatedPoints:int=-1, plotS11=False):
|
|
212
|
+
simulationResult = self.simulationObj.data.mw
|
|
213
|
+
|
|
214
|
+
freqs = simulationResult.scalar.grid.freq
|
|
215
|
+
fmin = freqs.min()
|
|
216
|
+
fmax = freqs.max()
|
|
217
|
+
|
|
218
|
+
if plotInterpolatedPoints > 0:
|
|
219
|
+
#
|
|
220
|
+
# Add points into frequency axis and interpolate computed S param over these points it makes graph line smooth but it can provide wrong result!!!
|
|
221
|
+
#
|
|
222
|
+
freq_dense = np.linspace(fmin, fmax, plotInterpolatedPoints)
|
|
223
|
+
S_data = simulationResult.scalar.grid.model_S(sourcePortNumber, targetPortNumber, freq_dense)
|
|
224
|
+
plotLabel = f'S{sourcePortNumber}{targetPortNumber}'
|
|
225
|
+
plot_sp(freq_dense, S_data, labels=plotLabel, dblim=dblim)
|
|
226
|
+
else:
|
|
227
|
+
S21_data = simulationResult.scalar.grid.S(sourcePortNumber, targetPortNumber)
|
|
228
|
+
S11_data = simulationResult.scalar.grid.S(sourcePortNumber, sourcePortNumber)
|
|
229
|
+
plotLabel_S11 = f'S{sourcePortNumber}{sourcePortNumber}'
|
|
230
|
+
plotLabel_S21 = f'S{targetPortNumber}{sourcePortNumber}'
|
|
231
|
+
if plotS11:
|
|
232
|
+
plot_sp(freqs, [S11_data, S21_data], labels=[plotLabel_S11, plotLabel_S21], dblim=dblim, xunit=xunit)
|
|
233
|
+
else:
|
|
234
|
+
plot_sp(freqs, [S21_data], labels=[plotLabel_S21], dblim=dblim, xunit=xunit)
|
|
235
|
+
|
|
236
|
+
if plotSmithChart:
|
|
237
|
+
smith(S_data, f=freq_dense, labels=plotLabel) # smith chart
|
|
238
|
+
|
|
239
|
+
def addObjectToView(self, nameOrList: str | list, opacity:float=0.1):
|
|
240
|
+
objectList = []
|
|
241
|
+
if type(nameOrList) == str:
|
|
242
|
+
objectList = self.getAllObjectByName(nameOrList)
|
|
243
|
+
if type(nameOrList) == list:
|
|
244
|
+
for oneName in nameOrList:
|
|
245
|
+
objectList.extend(self.getAllObjectByName(oneName))
|
|
246
|
+
|
|
247
|
+
for geoObject in objectList:
|
|
248
|
+
self.simulationObj.display.add_object(geoObject, opacity=opacity)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: basicemergesolverhelperpackage
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.3
|
|
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
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
LICENSE
|
|
2
2
|
README.md
|
|
3
3
|
setup.py
|
|
4
|
+
src/basicemergesolverhelperpackage/EMergeConstants.py
|
|
5
|
+
src/basicemergesolverhelperpackage/EMergeHelperFunctions.py
|
|
6
|
+
src/basicemergesolverhelperpackage/__init__.py
|
|
4
7
|
src/basicemergesolverhelperpackage.egg-info/PKG-INFO
|
|
5
8
|
src/basicemergesolverhelperpackage.egg-info/SOURCES.txt
|
|
6
9
|
src/basicemergesolverhelperpackage.egg-info/dependency_links.txt
|
basicemergesolverhelperpackage-0.0.3/src/basicemergesolverhelperpackage.egg-info/top_level.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
basicemergesolverhelperpackage
|
basicemergesolverhelperpackage-0.0.2/src/basicemergesolverhelperpackage.egg-info/top_level.txt
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|