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.
Files changed (14) hide show
  1. {basicemergesolverhelperpackage-0.0.2 → basicemergesolverhelperpackage-0.0.3}/PKG-INFO +1 -1
  2. {basicemergesolverhelperpackage-0.0.2 → basicemergesolverhelperpackage-0.0.3}/setup.py +2 -2
  3. basicemergesolverhelperpackage-0.0.3/src/basicemergesolverhelperpackage/EMergeConstants.py +44 -0
  4. basicemergesolverhelperpackage-0.0.3/src/basicemergesolverhelperpackage/EMergeHelperFunctions.py +248 -0
  5. basicemergesolverhelperpackage-0.0.3/src/basicemergesolverhelperpackage/__init__.py +9 -0
  6. {basicemergesolverhelperpackage-0.0.2 → basicemergesolverhelperpackage-0.0.3}/src/basicemergesolverhelperpackage.egg-info/PKG-INFO +1 -1
  7. {basicemergesolverhelperpackage-0.0.2 → basicemergesolverhelperpackage-0.0.3}/src/basicemergesolverhelperpackage.egg-info/SOURCES.txt +3 -0
  8. basicemergesolverhelperpackage-0.0.3/src/basicemergesolverhelperpackage.egg-info/top_level.txt +1 -0
  9. basicemergesolverhelperpackage-0.0.2/src/basicemergesolverhelperpackage.egg-info/top_level.txt +0 -1
  10. {basicemergesolverhelperpackage-0.0.2 → basicemergesolverhelperpackage-0.0.3}/LICENSE +0 -0
  11. {basicemergesolverhelperpackage-0.0.2 → basicemergesolverhelperpackage-0.0.3}/README.md +0 -0
  12. {basicemergesolverhelperpackage-0.0.2 → basicemergesolverhelperpackage-0.0.3}/setup.cfg +0 -0
  13. {basicemergesolverhelperpackage-0.0.2 → basicemergesolverhelperpackage-0.0.3}/src/basicemergesolverhelperpackage.egg-info/dependency_links.txt +0 -0
  14. {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.2
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.2",
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=["src"]),
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)
@@ -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)
@@ -0,0 +1,9 @@
1
+ """
2
+ BasicMfemMesher - Mesh creation utilities for Palace solver.
3
+ """
4
+
5
+ from .EMergeHelperFunctions import EMergeHelperFunctions
6
+ from .EMergeConstants import *
7
+
8
+ __version__ = "0.0.2"
9
+ __all__ = ["EMergeHelperFunctions", "EMergeConstants"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: basicemergesolverhelperpackage
3
- Version: 0.0.2
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