pyedb 0.2.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 pyedb might be problematic. Click here for more details.

Files changed (128) hide show
  1. pyedb/__init__.py +17 -0
  2. pyedb/dotnet/__init__.py +0 -0
  3. pyedb/dotnet/application/Variables.py +2261 -0
  4. pyedb/dotnet/application/__init__.py +0 -0
  5. pyedb/dotnet/clr_module.py +103 -0
  6. pyedb/dotnet/edb.py +4237 -0
  7. pyedb/dotnet/edb_core/__init__.py +1 -0
  8. pyedb/dotnet/edb_core/cell/__init__.py +0 -0
  9. pyedb/dotnet/edb_core/cell/hierarchy/__init__.py +0 -0
  10. pyedb/dotnet/edb_core/cell/hierarchy/model.py +66 -0
  11. pyedb/dotnet/edb_core/components.py +2669 -0
  12. pyedb/dotnet/edb_core/configuration.py +423 -0
  13. pyedb/dotnet/edb_core/definition/__init__.py +0 -0
  14. pyedb/dotnet/edb_core/definition/component_def.py +166 -0
  15. pyedb/dotnet/edb_core/definition/component_model.py +30 -0
  16. pyedb/dotnet/edb_core/definition/definition_obj.py +18 -0
  17. pyedb/dotnet/edb_core/definition/definitions.py +12 -0
  18. pyedb/dotnet/edb_core/dotnet/__init__.py +0 -0
  19. pyedb/dotnet/edb_core/dotnet/database.py +1218 -0
  20. pyedb/dotnet/edb_core/dotnet/layout.py +238 -0
  21. pyedb/dotnet/edb_core/dotnet/primitive.py +1517 -0
  22. pyedb/dotnet/edb_core/edb_data/__init__.py +0 -0
  23. pyedb/dotnet/edb_core/edb_data/components_data.py +938 -0
  24. pyedb/dotnet/edb_core/edb_data/connectable.py +113 -0
  25. pyedb/dotnet/edb_core/edb_data/control_file.py +1268 -0
  26. pyedb/dotnet/edb_core/edb_data/design_options.py +35 -0
  27. pyedb/dotnet/edb_core/edb_data/edbvalue.py +45 -0
  28. pyedb/dotnet/edb_core/edb_data/hfss_extent_info.py +330 -0
  29. pyedb/dotnet/edb_core/edb_data/hfss_simulation_setup_data.py +1607 -0
  30. pyedb/dotnet/edb_core/edb_data/layer_data.py +576 -0
  31. pyedb/dotnet/edb_core/edb_data/nets_data.py +281 -0
  32. pyedb/dotnet/edb_core/edb_data/obj_base.py +19 -0
  33. pyedb/dotnet/edb_core/edb_data/padstacks_data.py +2080 -0
  34. pyedb/dotnet/edb_core/edb_data/ports.py +287 -0
  35. pyedb/dotnet/edb_core/edb_data/primitives_data.py +1397 -0
  36. pyedb/dotnet/edb_core/edb_data/simulation_configuration.py +2914 -0
  37. pyedb/dotnet/edb_core/edb_data/simulation_setup.py +716 -0
  38. pyedb/dotnet/edb_core/edb_data/siwave_simulation_setup_data.py +1205 -0
  39. pyedb/dotnet/edb_core/edb_data/sources.py +514 -0
  40. pyedb/dotnet/edb_core/edb_data/terminals.py +632 -0
  41. pyedb/dotnet/edb_core/edb_data/utilities.py +148 -0
  42. pyedb/dotnet/edb_core/edb_data/variables.py +91 -0
  43. pyedb/dotnet/edb_core/general.py +181 -0
  44. pyedb/dotnet/edb_core/hfss.py +1646 -0
  45. pyedb/dotnet/edb_core/layout.py +1244 -0
  46. pyedb/dotnet/edb_core/layout_validation.py +272 -0
  47. pyedb/dotnet/edb_core/materials.py +939 -0
  48. pyedb/dotnet/edb_core/net_class.py +335 -0
  49. pyedb/dotnet/edb_core/nets.py +1215 -0
  50. pyedb/dotnet/edb_core/padstack.py +1389 -0
  51. pyedb/dotnet/edb_core/siwave.py +1427 -0
  52. pyedb/dotnet/edb_core/stackup.py +2703 -0
  53. pyedb/edb_logger.py +396 -0
  54. pyedb/generic/__init__.py +0 -0
  55. pyedb/generic/constants.py +1063 -0
  56. pyedb/generic/data_handlers.py +320 -0
  57. pyedb/generic/design_types.py +104 -0
  58. pyedb/generic/filesystem.py +150 -0
  59. pyedb/generic/general_methods.py +1535 -0
  60. pyedb/generic/plot.py +1840 -0
  61. pyedb/generic/process.py +285 -0
  62. pyedb/generic/settings.py +224 -0
  63. pyedb/ipc2581/__init__.py +0 -0
  64. pyedb/ipc2581/bom/__init__.py +0 -0
  65. pyedb/ipc2581/bom/bom.py +21 -0
  66. pyedb/ipc2581/bom/bom_item.py +32 -0
  67. pyedb/ipc2581/bom/characteristics.py +37 -0
  68. pyedb/ipc2581/bom/refdes.py +16 -0
  69. pyedb/ipc2581/content/__init__.py +0 -0
  70. pyedb/ipc2581/content/color.py +38 -0
  71. pyedb/ipc2581/content/content.py +55 -0
  72. pyedb/ipc2581/content/dictionary_color.py +29 -0
  73. pyedb/ipc2581/content/dictionary_fill.py +28 -0
  74. pyedb/ipc2581/content/dictionary_line.py +30 -0
  75. pyedb/ipc2581/content/entry_color.py +13 -0
  76. pyedb/ipc2581/content/entry_line.py +14 -0
  77. pyedb/ipc2581/content/fill.py +15 -0
  78. pyedb/ipc2581/content/layer_ref.py +10 -0
  79. pyedb/ipc2581/content/standard_geometries_dictionary.py +72 -0
  80. pyedb/ipc2581/ecad/__init__.py +0 -0
  81. pyedb/ipc2581/ecad/cad_data/__init__.py +0 -0
  82. pyedb/ipc2581/ecad/cad_data/assembly_drawing.py +26 -0
  83. pyedb/ipc2581/ecad/cad_data/cad_data.py +37 -0
  84. pyedb/ipc2581/ecad/cad_data/component.py +41 -0
  85. pyedb/ipc2581/ecad/cad_data/drill.py +30 -0
  86. pyedb/ipc2581/ecad/cad_data/feature.py +54 -0
  87. pyedb/ipc2581/ecad/cad_data/layer.py +41 -0
  88. pyedb/ipc2581/ecad/cad_data/layer_feature.py +151 -0
  89. pyedb/ipc2581/ecad/cad_data/logical_net.py +32 -0
  90. pyedb/ipc2581/ecad/cad_data/outline.py +25 -0
  91. pyedb/ipc2581/ecad/cad_data/package.py +104 -0
  92. pyedb/ipc2581/ecad/cad_data/padstack_def.py +38 -0
  93. pyedb/ipc2581/ecad/cad_data/padstack_hole_def.py +24 -0
  94. pyedb/ipc2581/ecad/cad_data/padstack_instance.py +62 -0
  95. pyedb/ipc2581/ecad/cad_data/padstack_pad_def.py +26 -0
  96. pyedb/ipc2581/ecad/cad_data/path.py +89 -0
  97. pyedb/ipc2581/ecad/cad_data/phy_net.py +80 -0
  98. pyedb/ipc2581/ecad/cad_data/pin.py +31 -0
  99. pyedb/ipc2581/ecad/cad_data/polygon.py +169 -0
  100. pyedb/ipc2581/ecad/cad_data/profile.py +40 -0
  101. pyedb/ipc2581/ecad/cad_data/stackup.py +31 -0
  102. pyedb/ipc2581/ecad/cad_data/stackup_group.py +42 -0
  103. pyedb/ipc2581/ecad/cad_data/stackup_layer.py +21 -0
  104. pyedb/ipc2581/ecad/cad_data/step.py +275 -0
  105. pyedb/ipc2581/ecad/cad_header.py +33 -0
  106. pyedb/ipc2581/ecad/ecad.py +19 -0
  107. pyedb/ipc2581/ecad/spec.py +46 -0
  108. pyedb/ipc2581/history_record.py +37 -0
  109. pyedb/ipc2581/ipc2581.py +387 -0
  110. pyedb/ipc2581/logistic_header.py +25 -0
  111. pyedb/misc/__init__.py +0 -0
  112. pyedb/misc/aedtlib_personalib_install.py +14 -0
  113. pyedb/misc/downloads.py +322 -0
  114. pyedb/misc/misc.py +67 -0
  115. pyedb/misc/pyedb.runtimeconfig.json +13 -0
  116. pyedb/misc/siw_feature_config/__init__.py +0 -0
  117. pyedb/misc/siw_feature_config/emc/__init__.py +0 -0
  118. pyedb/misc/siw_feature_config/emc/component_tags.py +46 -0
  119. pyedb/misc/siw_feature_config/emc/net_tags.py +37 -0
  120. pyedb/misc/siw_feature_config/emc/tag_library.py +62 -0
  121. pyedb/misc/siw_feature_config/emc/xml_generic.py +78 -0
  122. pyedb/misc/siw_feature_config/emc_rule_checker_settings.py +179 -0
  123. pyedb/misc/utilities.py +27 -0
  124. pyedb/modeler/geometry_operators.py +2082 -0
  125. pyedb-0.2.0.dist-info/LICENSE +21 -0
  126. pyedb-0.2.0.dist-info/METADATA +208 -0
  127. pyedb-0.2.0.dist-info/RECORD +128 -0
  128. pyedb-0.2.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,939 @@
1
+ from __future__ import absolute_import # noreorder
2
+
3
+ import difflib
4
+ import logging
5
+ import os
6
+ import re
7
+ import warnings
8
+
9
+ from pyedb.dotnet.clr_module import _clr
10
+ from pyedb.dotnet.edb_core.general import convert_py_list_to_net_list
11
+ from pyedb.generic.general_methods import is_ironpython, pyedb_function_handler
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ class Material(object):
17
+ """Manages EDB methods for material property management."""
18
+
19
+ def __init__(self, pclass, edb_material_def):
20
+ self._pclass = pclass
21
+ self._name = edb_material_def.GetName()
22
+ self._edb_material_def = edb_material_def
23
+ self._conductivity = 0.0
24
+ self._loss_tangent = 0.0
25
+ self._magnetic_loss_tangent = 0.0
26
+ self._mass_density = 0.0
27
+ self._permittivity = 0.0
28
+ self._permeability = 0.0
29
+ self._poisson_ratio = 0.0
30
+ self._specific_heat = 0.0
31
+ self._thermal_conductivity = 0.0
32
+ self._youngs_modulus = 0.0
33
+ self._thermal_expansion_coefficient = 0.0
34
+ self._dc_conductivity = 0.0
35
+ self._dc_permittivity = 0.0
36
+ self._dielectric_model_frequency = 0.0
37
+ self._loss_tangent_at_frequency = 0.0
38
+ self._permittivity_at_frequency = 0.0
39
+
40
+ def _edb_value(self, value):
41
+ return self._pclass._edb_value(value)
42
+
43
+ @property
44
+ def name(self):
45
+ """Retrieve material name."""
46
+ return self._name
47
+
48
+ @property
49
+ def _db(self):
50
+ return self._pclass._db
51
+
52
+ @property
53
+ def _edb(self):
54
+ return self._pclass._edb
55
+
56
+ @pyedb_function_handler()
57
+ def _get_property(self, property_name):
58
+ if is_ironpython: # pragma: no cover
59
+ property_box = _clr.StrongBox[float]()
60
+ self._edb_material_def.GetProperty(property_name, property_box)
61
+ return float(property_box)
62
+ else:
63
+ _, property_box = self._edb_material_def.GetProperty(property_name)
64
+ if isinstance(property_box, float):
65
+ return property_box
66
+ else:
67
+ return property_box.ToDouble()
68
+
69
+ @property
70
+ def conductivity(self):
71
+ material_id = self._edb.definition.MaterialPropertyId.Conductivity
72
+ self._conductivity = self._get_property(material_id)
73
+ return self._conductivity
74
+
75
+ @conductivity.setter
76
+ def conductivity(self, value):
77
+ """Retrieve material conductivity."""
78
+ material_id = self._edb.definition.MaterialPropertyId.Conductivity
79
+ self._edb_material_def.SetProperty(material_id, self._edb_value(value))
80
+ self._conductivity = value
81
+
82
+ @property
83
+ def permittivity(self):
84
+ """Retrieve material permittivity."""
85
+ material_id = self._edb.definition.MaterialPropertyId.Permittivity
86
+ self._permittivity = self._get_property(material_id)
87
+ return self._permittivity
88
+
89
+ @permittivity.setter
90
+ def permittivity(self, value):
91
+ material_id = self._edb.definition.MaterialPropertyId.Permittivity
92
+ self._edb_material_def.SetProperty(material_id, self._edb_value(value))
93
+ self._permittivity = value
94
+
95
+ @property
96
+ def permeability(self):
97
+ """Retrieve material permeability."""
98
+ material_id = self._edb.definition.MaterialPropertyId.Permeability
99
+ self._permeability = self._get_property(material_id)
100
+ return self._permeability
101
+
102
+ @permeability.setter
103
+ def permeability(self, value):
104
+ material_id = self._edb.definition.MaterialPropertyId.Permeability
105
+ self._edb_material_def.SetProperty(material_id, self._edb_value(value))
106
+ self._permeability = value
107
+
108
+ @property
109
+ def loss_tangent(self):
110
+ """Retrieve material loss tangent."""
111
+ material_id = self._edb.definition.MaterialPropertyId.DielectricLossTangent
112
+ self._loss_tangent = self._get_property(material_id)
113
+ return self._loss_tangent
114
+
115
+ @loss_tangent.setter
116
+ def loss_tangent(self, value):
117
+ material_id = self._edb.definition.MaterialPropertyId.DielectricLossTangent
118
+ self._edb_material_def.SetProperty(material_id, self._edb_value(value))
119
+ self._loss_tangent = value
120
+
121
+ @property
122
+ def dc_conductivity(self):
123
+ """"""
124
+ if self._edb_material_def.GetDielectricMaterialModel():
125
+ return self._edb_material_def.GetDielectricMaterialModel().GetDCConductivity()
126
+
127
+ @dc_conductivity.setter
128
+ def dc_conductivity(self, value):
129
+ if self._edb_material_def.GetDielectricMaterialModel():
130
+ self._edb_material_def.GetDielectricMaterialModel().SetDCConductivity(value)
131
+
132
+ @property
133
+ def dc_permittivity(self):
134
+ """"""
135
+ if self._edb_material_def.GetDielectricMaterialModel():
136
+ return self._edb_material_def.GetDielectricMaterialModel().GetDCRelativePermitivity()
137
+
138
+ @dc_permittivity.setter
139
+ def dc_permittivity(self, value):
140
+ if self._edb_material_def.GetDielectricMaterialModel():
141
+ self._edb_material_def.GetDielectricMaterialModel().SetDCRelativePermitivity(value)
142
+
143
+ @property
144
+ def dielectric_model_frequency(self):
145
+ """
146
+
147
+ Returns
148
+ -------
149
+ Frequency in GHz
150
+ """
151
+ if self._edb_material_def.GetDielectricMaterialModel():
152
+ return self._edb_material_def.GetDielectricMaterialModel().GetFrequency()
153
+
154
+ @dielectric_model_frequency.setter
155
+ def dielectric_model_frequency(self, value):
156
+ if self._edb_material_def.GetDielectricMaterialModel():
157
+ self._edb_material_def.GetDielectricMaterialModel().SetFrequency(value)
158
+
159
+ @property
160
+ def loss_tangent_at_frequency(self):
161
+ if self._edb_material_def.GetDielectricMaterialModel():
162
+ return self._edb_material_def.GetDielectricMaterialModel().GetLossTangentAtFrequency()
163
+
164
+ @loss_tangent_at_frequency.setter
165
+ def loss_tangent_at_frequency(self, value):
166
+ if self._edb_material_def.GetDielectricMaterialModel():
167
+ self._edb_material_def.GetDielectricMaterialModel().SetLossTangentAtFrequency(self._edb_value(value))
168
+
169
+ @property
170
+ def permittivity_at_frequency(self):
171
+ if self._edb_material_def.GetDielectricMaterialModel():
172
+ return self._edb_material_def.GetDielectricMaterialModel().GetRelativePermitivityAtFrequency()
173
+
174
+ @permittivity_at_frequency.setter
175
+ def permittivity_at_frequency(self, value):
176
+ if self._edb_material_def.GetDielectricMaterialModel():
177
+ self._edb_material_def.GetDielectricMaterialModel().SetRelativePermitivityAtFrequency(value)
178
+
179
+ @property
180
+ def magnetic_loss_tangent(self):
181
+ """Retrieve material magnetic loss tangent."""
182
+ material_id = self._edb.definition.MaterialPropertyId.MagneticLossTangent
183
+ self._magnetic_loss_tangent = self._get_property(material_id)
184
+ return self._magnetic_loss_tangent
185
+
186
+ @magnetic_loss_tangent.setter
187
+ def magnetic_loss_tangent(self, value):
188
+ material_id = self._edb.definition.MaterialPropertyId.MagneticLossTangent
189
+ self._edb_material_def.SetProperty(material_id, self._edb_value(value))
190
+ self._magnetic_loss_tangent = value
191
+
192
+ @property
193
+ def thermal_conductivity(self):
194
+ """Retrieve material thermal conductivity."""
195
+ material_id = self._edb.definition.MaterialPropertyId.ThermalConductivity
196
+ self._thermal_conductivity = self._get_property(material_id)
197
+ return self._thermal_conductivity
198
+
199
+ @thermal_conductivity.setter
200
+ def thermal_conductivity(self, value):
201
+ material_id = self._edb.definition.MaterialPropertyId.ThermalConductivity
202
+ self._edb_material_def.SetProperty(material_id, self._edb_value(value))
203
+ self._thermal_conductivity = value
204
+
205
+ @property
206
+ def mass_density(self):
207
+ """Retrieve material mass density."""
208
+ material_id = self._edb.definition.MaterialPropertyId.MassDensity
209
+ self._mass_density = self._get_property(material_id)
210
+ return self._mass_density
211
+
212
+ @mass_density.setter
213
+ def mass_density(self, value):
214
+ material_id = self._edb.definition.MaterialPropertyId.MassDensity
215
+ self._edb_material_def.SetProperty(material_id, self._edb_value(value))
216
+ self._mass_density = value
217
+
218
+ @property
219
+ def youngs_modulus(self):
220
+ """Retrieve material Young's Modulus."""
221
+ material_id = self._edb.definition.MaterialPropertyId.YoungsModulus
222
+ self._youngs_modulus = self._get_property(material_id)
223
+ return self._youngs_modulus
224
+
225
+ @youngs_modulus.setter
226
+ def youngs_modulus(self, value):
227
+ material_id = self._edb.definition.MaterialPropertyId.YoungsModulus
228
+ self._edb_material_def.SetProperty(material_id, self._edb_value(value))
229
+ self._youngs_modulus = value
230
+
231
+ @property
232
+ def specific_heat(self):
233
+ """Retrieve material Specific Heat."""
234
+ material_id = self._edb.definition.MaterialPropertyId.SpecificHeat
235
+ self._specific_heat = self._get_property(material_id)
236
+ return self._specific_heat
237
+
238
+ @specific_heat.setter
239
+ def specific_heat(self, value):
240
+ material_id = self._edb.definition.MaterialPropertyId.SpecificHeat
241
+ self._edb_material_def.SetProperty(material_id, self._edb_value(value))
242
+ self._specific_heat = value
243
+
244
+ @property
245
+ def poisson_ratio(self):
246
+ """Retrieve material Poisson Ratio."""
247
+ material_id = self._edb.definition.MaterialPropertyId.PoissonsRatio
248
+ self._poisson_ratio = self._get_property(material_id)
249
+ return self._poisson_ratio
250
+
251
+ @poisson_ratio.setter
252
+ def poisson_ratio(self, value):
253
+ material_id = self._edb.definition.MaterialPropertyId.PoissonsRatio
254
+ self._edb_material_def.SetProperty(material_id, self._edb_value(value))
255
+ self._poisson_ratio = value
256
+
257
+ @property
258
+ def thermal_expansion_coefficient(self):
259
+ """Retrieve material Thermal Coefficient.."""
260
+ material_id = self._edb.definition.MaterialPropertyId.ThermalExpansionCoefficient
261
+ self._thermal_expansion_coefficient = self._get_property(material_id)
262
+ return self._thermal_expansion_coefficient
263
+
264
+ @thermal_expansion_coefficient.setter
265
+ def thermal_expansion_coefficient(self, value):
266
+ material_id = self._edb.definition.MaterialPropertyId.ThermalExpansionCoefficient
267
+ self._edb_material_def.SetProperty(material_id, self._edb_value(value))
268
+ self._thermal_expansion_coefficient = value
269
+
270
+ @pyedb_function_handler()
271
+ def _json_format(self):
272
+ out_dict = {}
273
+ if self.permittivity == 0: # pragma no cover
274
+ self.permittivity = 1.0
275
+ if self.permeability == 0: # pragma no cover
276
+ self.permeability = 1.0
277
+ self._name = self.name
278
+ self._conductivity = self.conductivity
279
+ self._loss_tangent = self.loss_tangent
280
+ self._magnetic_loss_tangent = self.magnetic_loss_tangent
281
+ self._mass_density = self.mass_density
282
+ self._permittivity = self.permittivity
283
+ self._permeability = self.permeability
284
+ self._poisson_ratio = self.poisson_ratio
285
+ self._specific_heat = self.specific_heat
286
+ self._thermal_conductivity = self.thermal_conductivity
287
+ self._youngs_modulus = self.youngs_modulus
288
+ self._thermal_expansion_coefficient = self.thermal_expansion_coefficient
289
+ self._dc_conductivity = self.dc_conductivity
290
+ self._dc_permittivity = self.dc_permittivity
291
+ self._dielectric_model_frequency = self.dielectric_model_frequency
292
+ self._loss_tangent_at_frequency = self.loss_tangent_at_frequency
293
+ self._permittivity_at_frequency = self.permittivity_at_frequency
294
+ for k, v in self.__dict__.items():
295
+ if not k == "_pclass" and not k == "_edb_material_def":
296
+ out_dict[k[1:]] = v
297
+ return out_dict
298
+
299
+ @pyedb_function_handler()
300
+ def _load(self, input_dict):
301
+ default_material = {
302
+ "name": "default",
303
+ "conductivity": 0,
304
+ "loss_tangent": 0,
305
+ "magnetic_loss_tangent": 0,
306
+ "mass_density": 0,
307
+ "permittivity": 1,
308
+ "permeability": 1,
309
+ "poisson_ratio": 0,
310
+ "specific_heat": 0,
311
+ "thermal_conductivity": 0,
312
+ "youngs_modulus": 0,
313
+ "thermal_expansion_coefficient": 0,
314
+ "dielectric_model_frequency": None,
315
+ "dc_permittivity": None,
316
+ }
317
+ if input_dict:
318
+ for k, v in input_dict.items():
319
+ default_material[k] = v
320
+
321
+ self.conductivity = default_material["conductivity"]
322
+ self.loss_tangent = default_material["loss_tangent"]
323
+ self.magnetic_loss_tangent = default_material["magnetic_loss_tangent"]
324
+ self.mass_density = default_material["mass_density"]
325
+ self.permittivity = default_material["permittivity"]
326
+ self.permeability = default_material["permeability"]
327
+ self.poisson_ratio = default_material["poisson_ratio"]
328
+ self.specific_heat = default_material["specific_heat"]
329
+ self.thermal_conductivity = default_material["thermal_conductivity"]
330
+ self.youngs_modulus = default_material["youngs_modulus"]
331
+ self.thermal_expansion_coefficient = default_material["thermal_expansion_coefficient"]
332
+ if default_material["dielectric_model_frequency"] is not None: # pragma: no cover
333
+ if self._edb_material_def.GetDielectricMaterialModel():
334
+ model = self._edb_material_def.GetDielectricMaterialModel()
335
+ self.dielectric_model_frequency = default_material["dielectric_model_frequency"]
336
+ self.loss_tangent_at_frequency = default_material["loss_tangent_at_frequency"]
337
+ self.permittivity_at_frequency = default_material["permittivity_at_frequency"]
338
+ if default_material["dc_permittivity"] is not None:
339
+ model.SetUseDCRelativePermitivity(True)
340
+ self.dc_permittivity = default_material["dc_permittivity"]
341
+ self.dc_conductivity = default_material["dc_conductivity"]
342
+ else:
343
+ if not self._pclass.add_djordjevicsarkar_material(
344
+ default_material["name"],
345
+ default_material["permittivity_at_frequency"],
346
+ default_material["loss_tangent_at_frequency"],
347
+ default_material["dielectric_model_frequency"],
348
+ default_material["dc_permittivity"],
349
+ default_material["dc_conductivity"],
350
+ ):
351
+ self._pclass._pedb.logger.warning(
352
+ 'Cannot set DS model for material "{}". Check for realistic '
353
+ "values that define DS Model".format(default_material["name"])
354
+ )
355
+ else:
356
+ # To unset DS model if already assigned to the material in database
357
+ if self._edb_material_def.GetDielectricMaterialModel():
358
+ self._edb_material_def.SetDielectricMaterialModel(self._edb_value(None))
359
+
360
+
361
+ # TODO: Cleanup
362
+ class Materials(object):
363
+ """Manages EDB methods for material management accessible from `Edb.materials` property."""
364
+
365
+ def __getitem__(self, item):
366
+ return self.materials[item]
367
+
368
+ def __init__(self, pedb):
369
+ self._pedb = pedb
370
+ self._syslib = os.path.join(self._pedb.base_path, "syslib")
371
+ if not self.materials:
372
+ self.add_material("air")
373
+ self.add_material("copper", 1, 0.999991, 5.8e7, 0, 0)
374
+ self.add_material("fr4_epoxy", 4.4, 1, 0, 0.02, 0)
375
+ self.add_material("solder_mask", 3.1, 1, 0, 0.035, 0)
376
+
377
+ @property
378
+ def syslib(self):
379
+ """Retrieve the project sys library."""
380
+ return self._syslib
381
+
382
+ @pyedb_function_handler()
383
+ def _edb_value(self, value):
384
+ return self._pedb.edb_value(value)
385
+
386
+ @property
387
+ def _edb(self):
388
+ return self._pedb.edb_api
389
+
390
+ @property
391
+ def _db(self):
392
+ return self._pedb.active_db
393
+
394
+ @property
395
+ def materials(self):
396
+ """Retrieve dictionary of material from material library."""
397
+ return {obj.GetName(): Material(self, obj) for obj in list(self._db.MaterialDefs)}
398
+
399
+ @pyedb_function_handler()
400
+ def add_material(
401
+ self,
402
+ name="air",
403
+ permittivity=1.0006,
404
+ permeability=1.0000004,
405
+ conductivity=0,
406
+ dielectric_loss_tangent=0,
407
+ magnetic_loss_tangent=0,
408
+ ):
409
+ """Add a new material.
410
+
411
+ Parameters
412
+ ----------
413
+ name : str, optional
414
+ Material Name. The default is ``"air"``.
415
+ permittivity : float, str, optional
416
+ Material permittivity. The default is ``1.0006``.
417
+ permeability : float, str, optional
418
+ Material permeability. The default is ``1.0000004``.
419
+ conductivity : float, str, optional
420
+ Material conductivity. The default is ``0``.
421
+ dielectric_loss_tangent : float, str, optional
422
+ Material dielectric loss tangent. The default is ``0``.
423
+ magnetic_loss_tangent : float, str, optional
424
+ Material magnetic loss tangent. The default is ``0``.
425
+
426
+ Returns
427
+ -------
428
+ :class:`pyedb.dotnet.edb_core.materials.Material`
429
+ """
430
+ if not name in self.materials:
431
+ self._edb.definition.MaterialDef.Create(self._db, name)
432
+ new_material = self.materials[name]
433
+ new_material.permittivity = permittivity
434
+ new_material.permeability = permeability
435
+ new_material.conductivity = conductivity
436
+ new_material.loss_tangent = dielectric_loss_tangent
437
+ new_material.magnetic_loss_tangent = magnetic_loss_tangent
438
+ return new_material
439
+ else: # pragma: no cover
440
+ warnings.warn("Material {} already exists in material library.".format(name))
441
+ return False
442
+
443
+ @pyedb_function_handler()
444
+ def add_conductor_material(self, name, conductivity):
445
+ """Add a new conductor material in library.
446
+
447
+ Parameters
448
+ ----------
449
+ name : str
450
+ Name of the new material.
451
+ conductivity : float
452
+ Conductivity of the new material.
453
+
454
+ Returns
455
+ -------
456
+ :class:`pyedb.dotnet.edb_core.materials.Material`
457
+
458
+ """
459
+ if not name in self.materials:
460
+ self._edb.definition.MaterialDef.Create(self._db, name)
461
+ new_material = self.materials[name]
462
+ new_material.conductivity = conductivity
463
+ new_material.permittivity = 1
464
+ new_material.permeability = 1
465
+ return new_material
466
+ else: # pragma: no cover
467
+ warnings.warn("Material {} already exists in material library.".format(name))
468
+ return False
469
+
470
+ @pyedb_function_handler()
471
+ def add_dielectric_material(self, name, permittivity, loss_tangent, permeability=1):
472
+ """Add a new dielectric material in library.
473
+
474
+ Parameters
475
+ ----------
476
+ name : str
477
+ Name of the new material.
478
+ permittivity : float
479
+ Permittivity of the new material.
480
+ loss_tangent : float
481
+ Loss tangent of the new material.
482
+ permeability : float
483
+ Permeability of the new material.
484
+
485
+ Returns
486
+ -------
487
+ :class:`pyedb.dotnet.edb_core.materials.Material`
488
+ """
489
+ if not name in self.materials:
490
+ self._edb.definition.MaterialDef.Create(self._db, name)
491
+ new_material = self.materials[name]
492
+ new_material.permittivity = permittivity
493
+ new_material.loss_tangent = loss_tangent
494
+ new_material.permeability = permeability
495
+ return new_material
496
+ else:
497
+ warnings.warn("Material {} already exists in material library.".format(name))
498
+ return False
499
+
500
+ @pyedb_function_handler()
501
+ def get_djordjevicsarkar_model(self, material_name=None):
502
+ """Djordjevic-Sarkar model if present.
503
+
504
+ Parameters
505
+ ----------
506
+ material_name : str
507
+
508
+ Returns
509
+ -------
510
+
511
+ """
512
+ material = self.materials[material_name]
513
+ if material:
514
+ return material.GetDielectricMaterialModel()
515
+
516
+ @pyedb_function_handler()
517
+ def add_djordjevicsarkar_material(
518
+ self, name, permittivity, loss_tangent, test_frequency, dc_permittivity=None, dc_conductivity=None
519
+ ):
520
+ """Create a Djordjevic_Sarkar dielectric.
521
+
522
+ Parameters
523
+ ----------
524
+ name : str
525
+ Name of the dielectric.
526
+ permittivity : float
527
+ Relative permittivity of the dielectric.
528
+ loss_tangent : float
529
+ Loss tangent for the material.
530
+ test_frequency : float
531
+ Test frequency in GHz for the dielectric.
532
+ dc_permittivity : float, optional
533
+ DC Relative permittivity of the dielectric.
534
+ dc_conductivity : float, optional
535
+ DC Conductivity of the dielectric.
536
+
537
+ Returns
538
+ -------
539
+ :class:`pyedb.dotnet.edb_core.materials.Material`
540
+ Material definition.
541
+ """
542
+ material_def = self._edb.definition.DjordjecvicSarkarModel()
543
+ material_def.SetFrequency(test_frequency)
544
+ material_def.SetLossTangentAtFrequency(self._edb_value(loss_tangent))
545
+ material_def.SetRelativePermitivityAtFrequency(permittivity)
546
+ if dc_conductivity is not None:
547
+ material_def.SetDCConductivity(dc_conductivity)
548
+ if dc_permittivity is not None:
549
+ material_def.SetUseDCRelativePermitivity(True)
550
+ material_def.SetDCRelativePermitivity(dc_permittivity)
551
+ return self._add_dielectric_material_model(name, material_def)
552
+
553
+ @pyedb_function_handler()
554
+ def add_debye_material(
555
+ self,
556
+ name,
557
+ permittivity_low,
558
+ permittivity_high,
559
+ loss_tangent_low,
560
+ loss_tangent_high,
561
+ lower_freqency,
562
+ higher_frequency,
563
+ ):
564
+ """Create a dielectric with the Debye model.
565
+
566
+ Parameters
567
+ ----------
568
+ name : str
569
+ Name of the dielectric.
570
+ permittivity_low : float
571
+ Relative permittivity of the dielectric at the frequency specified
572
+ for ``lower_frequency``.
573
+ permittivity_high : float
574
+ Relative permittivity of the dielectric at the frequency specified
575
+ for ``higher_frequency``.
576
+ loss_tangent_low : float
577
+ Loss tangent for the material at the frequency specified
578
+ for ``lower_frequency``.
579
+ loss_tangent_high : float
580
+ Loss tangent for the material at the frequency specified
581
+ for ``higher_frequency``.
582
+ lower_freqency : float
583
+ Value for the lower frequency.
584
+ higher_frequency : float
585
+ Value for the higher frequency.
586
+
587
+ Returns
588
+ -------
589
+ :class:`pyedb.dotnet.edb_core.materials.Material`
590
+ Material definition.
591
+ """
592
+ material_def = self._edb.definition.DebyeModel()
593
+ material_def.SetFrequencyRange(lower_freqency, higher_frequency)
594
+ material_def.SetLossTangentAtHighLowFrequency(loss_tangent_low, loss_tangent_high)
595
+ material_def.SetRelativePermitivityAtHighLowFrequency(
596
+ self._edb_value(permittivity_low), self._edb_value(permittivity_high)
597
+ )
598
+ return self._add_dielectric_material_model(name, material_def)
599
+
600
+ @pyedb_function_handler()
601
+ def add_multipole_debye_material(
602
+ self,
603
+ name,
604
+ frequencies,
605
+ permittivities,
606
+ loss_tangents,
607
+ ):
608
+ """Create a dielectric with the Multipole Debye model.
609
+
610
+ Parameters
611
+ ----------
612
+ name : str
613
+ Name of the dielectric.
614
+ frequencies : list
615
+ Frequencies in GHz.
616
+ permittivities : list
617
+ Relative permittivities at each frequency.
618
+ loss_tangents : list
619
+ Loss tangents at each frequency.
620
+
621
+ Returns
622
+ -------
623
+ :class:`pyedb.dotnet.edb_core.materials.Material`
624
+ Material definition.
625
+
626
+ Examples
627
+ --------
628
+ >>> from pyedb import Edb
629
+ >>> edb = Edb()
630
+ >>> freq = [0, 2, 3, 4, 5, 6]
631
+ >>> rel_perm = [1e9, 1.1e9, 1.2e9, 1.3e9, 1.5e9, 1.6e9]
632
+ >>> loss_tan = [0.025, 0.026, 0.027, 0.028, 0.029, 0.030]
633
+ >>> diel = edb.materials.add_multipole_debye_material("My_MP_Debye", freq, rel_perm, loss_tan)
634
+ """
635
+ frequencies = [float(i) for i in frequencies]
636
+ permittivities = [float(i) for i in permittivities]
637
+ loss_tangents = [float(i) for i in loss_tangents]
638
+ material_def = self._edb.definition.MultipoleDebyeModel()
639
+ material_def.SetParameters(
640
+ convert_py_list_to_net_list(frequencies),
641
+ convert_py_list_to_net_list(permittivities),
642
+ convert_py_list_to_net_list(loss_tangents),
643
+ )
644
+ return self._add_dielectric_material_model(name, material_def)
645
+
646
+ @pyedb_function_handler()
647
+ def _add_dielectric_material_model(self, name, material_model):
648
+ if self._edb.definition.MaterialDef.FindByName(self._db, name).IsNull():
649
+ self._edb.definition.MaterialDef.Create(self._db, name)
650
+ material_def = self._edb.definition.MaterialDef.FindByName(self._db, name)
651
+ succeeded = material_def.SetDielectricMaterialModel(material_model)
652
+ if succeeded:
653
+ return material_def
654
+ return False
655
+
656
+ @pyedb_function_handler()
657
+ def duplicate(self, material_name, new_material_name):
658
+ """Duplicate a material from the database.
659
+
660
+
661
+ Parameters
662
+ ----------
663
+ material_name : str
664
+ Name of the existing material.
665
+ new_material_name : str
666
+ Name of the new duplicated material.
667
+
668
+ Returns
669
+ -------
670
+ EDB material : class: 'Ansys.Ansoft.Edb.definition.MaterialDef'
671
+
672
+
673
+ Examples
674
+ --------
675
+
676
+ >>> from pyedb import Edb
677
+ >>> edb_app = Edb()
678
+ >>> my_material = edb_app.materials.duplicate("copper", "my_new_copper")
679
+
680
+ """
681
+ material_list = {i.lower(): i for i in list(self.materials.keys())}
682
+ if material_name.lower() in material_list and new_material_name not in self.materials:
683
+ material_name = material_list[material_name.lower()]
684
+ permittivity = self._edb_value(self.materials[material_name].permittivity)
685
+ permeability = self._edb_value(self.materials[material_name].permeability)
686
+ conductivity = self._edb_value(self.materials[material_name].conductivity)
687
+ dielectric_loss_tangent = self._edb_value(self.materials[material_name].loss_tangent)
688
+ magnetic_loss_tangent = self._edb_value(self.materials[material_name].magnetic_loss_tangent)
689
+ thermal_conductivity = self._edb_value(self.materials[material_name].thermal_conductivity)
690
+ thermal_expansion_coefficient = self._edb_value(self.materials[material_name].thermal_expansion_coefficient)
691
+ youngs_modulus = self._edb_value(self.materials[material_name].youngs_modulus)
692
+ poisson_ratio = self._edb_value(self.materials[material_name].poisson_ratio)
693
+ mass_density = self._edb_value(self.materials[material_name].mass_density)
694
+ material_model = self.materials[material_name]._edb_material_def.GetDielectricMaterialModel()
695
+ edb_material = self._edb.definition.MaterialDef.Create(self._db, new_material_name)
696
+ edb_material.SetProperty(self._edb.definition.MaterialPropertyId.Permittivity, permittivity)
697
+ edb_material.SetProperty(self._edb.definition.MaterialPropertyId.Permeability, permeability)
698
+ edb_material.SetProperty(self._edb.definition.MaterialPropertyId.Conductivity, conductivity)
699
+ edb_material.SetProperty(
700
+ self._edb.definition.MaterialPropertyId.DielectricLossTangent, dielectric_loss_tangent
701
+ )
702
+ edb_material.SetProperty(self._edb.definition.MaterialPropertyId.ThermalConductivity, thermal_conductivity)
703
+ edb_material.SetProperty(
704
+ self._edb.definition.MaterialPropertyId.ThermalExpansionCoefficient, thermal_expansion_coefficient
705
+ )
706
+ edb_material.SetProperty(self._edb.definition.MaterialPropertyId.MassDensity, mass_density)
707
+ edb_material.SetProperty(self._edb.definition.MaterialPropertyId.YoungsModulus, youngs_modulus)
708
+ edb_material.SetProperty(self._edb.definition.MaterialPropertyId.PoissonsRatio, poisson_ratio)
709
+ edb_material.SetProperty(self._edb.definition.MaterialPropertyId.MagneticLossTangent, magnetic_loss_tangent)
710
+ edb_material.SetProperty(self._edb.definition.MaterialPropertyId.MagneticLossTangent, magnetic_loss_tangent)
711
+ edb_material.SetDielectricMaterialModel(material_model)
712
+
713
+ return edb_material
714
+
715
+ @pyedb_function_handler()
716
+ def _load_materials(self, material=None):
717
+ if self.materials:
718
+ mat_keys = [i.lower() for i in self.materials.keys()]
719
+ mat_keys_case = [i for i in self.materials.keys()]
720
+ else:
721
+ mat_keys = []
722
+ mat_keys_case = []
723
+
724
+ if not material:
725
+ return
726
+ if material["name"].lower() not in mat_keys:
727
+ if "conductivity" not in material:
728
+ self.add_dielectric_material(material["name"], material["permittivity"], material["loss_tangent"])
729
+ elif material["conductivity"] > 1e4:
730
+ self.add_conductor_material(material["name"], material["conductivity"])
731
+ else:
732
+ self.add_dielectric_material(material["name"], material["permittivity"], material["loss_tangent"])
733
+ self.materials[material["name"]]._load(material)
734
+ else:
735
+ self.materials[mat_keys_case[mat_keys.index(material["name"].lower())]]._load(material)
736
+
737
+ @pyedb_function_handler()
738
+ def material_name_to_id(self, property_name):
739
+ """Convert a material property name to a material property ID.
740
+
741
+ Parameters
742
+ ----------
743
+ property_name : str
744
+ Name of the material property.
745
+
746
+ Returns
747
+ -------
748
+ ID of the material property.
749
+ """
750
+ props = {
751
+ "Permittivity": self._edb.definition.MaterialPropertyId.Permittivity,
752
+ "Permeability": self._edb.definition.MaterialPropertyId.Permeability,
753
+ "Conductivity": self._edb.definition.MaterialPropertyId.Conductivity,
754
+ "DielectricLossTangent": self._edb.definition.MaterialPropertyId.DielectricLossTangent,
755
+ "MagneticLossTangent": self._edb.definition.MaterialPropertyId.MagneticLossTangent,
756
+ "ThermalConductivity": self._edb.definition.MaterialPropertyId.ThermalConductivity,
757
+ "MassDensity": self._edb.definition.MaterialPropertyId.MassDensity,
758
+ "SpecificHeat": self._edb.definition.MaterialPropertyId.SpecificHeat,
759
+ "YoungsModulus": self._edb.definition.MaterialPropertyId.YoungsModulus,
760
+ "PoissonsRatio": self._edb.definition.MaterialPropertyId.PoissonsRatio,
761
+ "ThermalExpansionCoefficient": self._edb.definition.MaterialPropertyId.ThermalExpansionCoefficient,
762
+ "InvalidProperty": self._edb.definition.MaterialPropertyId.InvalidProperty,
763
+ }
764
+
765
+ found_el = difflib.get_close_matches(property_name, list(props.keys()), 1, 0.7)
766
+ if found_el:
767
+ return props[found_el[0]]
768
+ else:
769
+ return self._edb.definition.MaterialPropertyId.InvalidProperty
770
+
771
+ @pyedb_function_handler()
772
+ def get_property_by_material_name(self, property_name, material_name):
773
+ """Get the property of a material. If it is executed in IronPython,
774
+ you must only use the first element of the returned tuple, which is a float.
775
+
776
+ Parameters
777
+ ----------
778
+ material_name : str
779
+ Name of the existing material.
780
+ property_name : str
781
+ Name of the material property.
782
+ ``permittivity``
783
+ ``permeability``
784
+ ``conductivity``
785
+ ``dielectric_loss_tangent``
786
+ ``magnetic_loss_tangent``
787
+
788
+ Returns
789
+ -------
790
+ float
791
+ The float value of the property.
792
+
793
+
794
+ Examples
795
+ --------
796
+ >>> from pyedb import Edb
797
+ >>> edb_app = Edb()
798
+ >>> returned_tuple = edb_app.materials.get_property_by_material_name("conductivity", "copper")
799
+ >>> edb_value = returned_tuple[0]
800
+ >>> float_value = returned_tuple[1]
801
+
802
+ """
803
+ if self._edb.definition.MaterialDef.FindByName(self._pedb._db, material_name).IsNull():
804
+ self._pedb.logger.error("This material doesn't exists.")
805
+ else:
806
+ original_material = self._edb.definition.MaterialDef.FindByName(self._pedb._db, material_name)
807
+ if is_ironpython: # pragma: no cover
808
+ property_box = _clr.StrongBox[float]()
809
+ original_material.GetProperty(self.material_name_to_id(property_name), property_box)
810
+ return float(property_box)
811
+ else:
812
+ _, property_box = original_material.GetProperty(
813
+ self.material_name_to_id(property_name), self._edb_value(0.0)
814
+ )
815
+ if isinstance(property_box, float):
816
+ return property_box
817
+ else:
818
+ return property_box.ToDouble()
819
+ return False
820
+
821
+ @pyedb_function_handler()
822
+ def load_amat(self, amat_file):
823
+ """Load materials from an AMAT file.
824
+
825
+ Parameters
826
+ ----------
827
+ amat_file : str
828
+ Full path to the AMAT file to read and add to the Edb.
829
+
830
+ Returns
831
+ -------
832
+ bool
833
+ """
834
+ if not os.path.exists(amat_file):
835
+ self._pedb.logger.error("File path {} does not exist.".format(amat_file))
836
+ material_dict = self.read_materials(amat_file)
837
+ for material_name, material in material_dict.items():
838
+ if not material_name in list(self.materials.keys()):
839
+ new_material = self.add_material(name=material_name)
840
+ properties = [
841
+ "permittivity",
842
+ "conductivity",
843
+ "mass_density",
844
+ "permeability",
845
+ "specific_heat",
846
+ "thermal_expansion_coefficient",
847
+ ]
848
+ for mat_prop_name, mat_prop_value in material.items():
849
+ if mat_prop_name in properties:
850
+ setattr(new_material, mat_prop_name, mat_prop_value)
851
+ if mat_prop_name == "tangent_delta":
852
+ new_material.loss_tangent = mat_prop_value
853
+ return True
854
+
855
+ @staticmethod
856
+ @pyedb_function_handler()
857
+ def read_materials(amat_file):
858
+ """Read materials from an AMAT file.
859
+
860
+ Parameters
861
+ ----------
862
+ amat_file : str
863
+ Full path to the AMAT file to read.
864
+
865
+ Returns
866
+ -------
867
+ dict
868
+ {material name: dict of material property to value}.
869
+ """
870
+
871
+ def get_line_float_value(line):
872
+ """Retrieve the float value expected in the line of an AMAT file.
873
+ The associated string is expected to follow one of the following cases:
874
+ - simple('permittivity', 12.)
875
+ - permittivity='12'.
876
+ """
877
+ try:
878
+ return float(re.split(",|=", line)[-1].strip(")'"))
879
+ except ValueError:
880
+ return None
881
+
882
+ res = {}
883
+ _begin_search = re.compile(r"^\$begin '(.+)'")
884
+ _end_search = re.compile(r"^\$end '(.+)'")
885
+ amat_keys = [
886
+ "thermal_conductivity",
887
+ "permittivity",
888
+ "dielectric_loss_tangent",
889
+ "permeability",
890
+ "magnetic_loss_tangent",
891
+ "thermal_expansion_coeffcient",
892
+ "specific_heat",
893
+ "mass_density",
894
+ ]
895
+ keys = [
896
+ "thermal_conductivity",
897
+ "permittivity",
898
+ "tangent_delta",
899
+ "permeability",
900
+ "magnetic_loss_tangent",
901
+ "thermal_expansion_coeffcient",
902
+ "specific_heat",
903
+ "mass_density",
904
+ ]
905
+
906
+ with open(amat_file, "r") as amat_fh:
907
+ raw_lines = amat_fh.read().splitlines()
908
+ mat_found = ""
909
+ for line in raw_lines:
910
+ b = _begin_search.search(line)
911
+ if b: # walk down a level
912
+ mat_found = b.group(1)
913
+ res.setdefault(mat_found, {})
914
+ if mat_found:
915
+ for amat_key, key in zip(amat_keys, keys):
916
+ if amat_key in line:
917
+ value = get_line_float_value(line)
918
+ if value is not None:
919
+ res[mat_found][key] = value
920
+ # Extra case to avoid confusion ("conductivity" is included in "thermal_conductivity")
921
+ if "conductivity" in line and "thermal_conductivity" not in line:
922
+ value = get_line_float_value(line)
923
+ if value is not None:
924
+ res[mat_found]["conductivity"] = value
925
+ end = _end_search.search(line)
926
+ if end:
927
+ mat_found = ""
928
+
929
+ # Clean unwanted data
930
+ try:
931
+ del res["$index$"]
932
+ except KeyError:
933
+ pass
934
+ try:
935
+ del res["$base_index$"]
936
+ except KeyError:
937
+ pass
938
+
939
+ return res