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.
- pyedb/__init__.py +17 -0
- pyedb/dotnet/__init__.py +0 -0
- pyedb/dotnet/application/Variables.py +2261 -0
- pyedb/dotnet/application/__init__.py +0 -0
- pyedb/dotnet/clr_module.py +103 -0
- pyedb/dotnet/edb.py +4237 -0
- pyedb/dotnet/edb_core/__init__.py +1 -0
- pyedb/dotnet/edb_core/cell/__init__.py +0 -0
- pyedb/dotnet/edb_core/cell/hierarchy/__init__.py +0 -0
- pyedb/dotnet/edb_core/cell/hierarchy/model.py +66 -0
- pyedb/dotnet/edb_core/components.py +2669 -0
- pyedb/dotnet/edb_core/configuration.py +423 -0
- pyedb/dotnet/edb_core/definition/__init__.py +0 -0
- pyedb/dotnet/edb_core/definition/component_def.py +166 -0
- pyedb/dotnet/edb_core/definition/component_model.py +30 -0
- pyedb/dotnet/edb_core/definition/definition_obj.py +18 -0
- pyedb/dotnet/edb_core/definition/definitions.py +12 -0
- pyedb/dotnet/edb_core/dotnet/__init__.py +0 -0
- pyedb/dotnet/edb_core/dotnet/database.py +1218 -0
- pyedb/dotnet/edb_core/dotnet/layout.py +238 -0
- pyedb/dotnet/edb_core/dotnet/primitive.py +1517 -0
- pyedb/dotnet/edb_core/edb_data/__init__.py +0 -0
- pyedb/dotnet/edb_core/edb_data/components_data.py +938 -0
- pyedb/dotnet/edb_core/edb_data/connectable.py +113 -0
- pyedb/dotnet/edb_core/edb_data/control_file.py +1268 -0
- pyedb/dotnet/edb_core/edb_data/design_options.py +35 -0
- pyedb/dotnet/edb_core/edb_data/edbvalue.py +45 -0
- pyedb/dotnet/edb_core/edb_data/hfss_extent_info.py +330 -0
- pyedb/dotnet/edb_core/edb_data/hfss_simulation_setup_data.py +1607 -0
- pyedb/dotnet/edb_core/edb_data/layer_data.py +576 -0
- pyedb/dotnet/edb_core/edb_data/nets_data.py +281 -0
- pyedb/dotnet/edb_core/edb_data/obj_base.py +19 -0
- pyedb/dotnet/edb_core/edb_data/padstacks_data.py +2080 -0
- pyedb/dotnet/edb_core/edb_data/ports.py +287 -0
- pyedb/dotnet/edb_core/edb_data/primitives_data.py +1397 -0
- pyedb/dotnet/edb_core/edb_data/simulation_configuration.py +2914 -0
- pyedb/dotnet/edb_core/edb_data/simulation_setup.py +716 -0
- pyedb/dotnet/edb_core/edb_data/siwave_simulation_setup_data.py +1205 -0
- pyedb/dotnet/edb_core/edb_data/sources.py +514 -0
- pyedb/dotnet/edb_core/edb_data/terminals.py +632 -0
- pyedb/dotnet/edb_core/edb_data/utilities.py +148 -0
- pyedb/dotnet/edb_core/edb_data/variables.py +91 -0
- pyedb/dotnet/edb_core/general.py +181 -0
- pyedb/dotnet/edb_core/hfss.py +1646 -0
- pyedb/dotnet/edb_core/layout.py +1244 -0
- pyedb/dotnet/edb_core/layout_validation.py +272 -0
- pyedb/dotnet/edb_core/materials.py +939 -0
- pyedb/dotnet/edb_core/net_class.py +335 -0
- pyedb/dotnet/edb_core/nets.py +1215 -0
- pyedb/dotnet/edb_core/padstack.py +1389 -0
- pyedb/dotnet/edb_core/siwave.py +1427 -0
- pyedb/dotnet/edb_core/stackup.py +2703 -0
- pyedb/edb_logger.py +396 -0
- pyedb/generic/__init__.py +0 -0
- pyedb/generic/constants.py +1063 -0
- pyedb/generic/data_handlers.py +320 -0
- pyedb/generic/design_types.py +104 -0
- pyedb/generic/filesystem.py +150 -0
- pyedb/generic/general_methods.py +1535 -0
- pyedb/generic/plot.py +1840 -0
- pyedb/generic/process.py +285 -0
- pyedb/generic/settings.py +224 -0
- pyedb/ipc2581/__init__.py +0 -0
- pyedb/ipc2581/bom/__init__.py +0 -0
- pyedb/ipc2581/bom/bom.py +21 -0
- pyedb/ipc2581/bom/bom_item.py +32 -0
- pyedb/ipc2581/bom/characteristics.py +37 -0
- pyedb/ipc2581/bom/refdes.py +16 -0
- pyedb/ipc2581/content/__init__.py +0 -0
- pyedb/ipc2581/content/color.py +38 -0
- pyedb/ipc2581/content/content.py +55 -0
- pyedb/ipc2581/content/dictionary_color.py +29 -0
- pyedb/ipc2581/content/dictionary_fill.py +28 -0
- pyedb/ipc2581/content/dictionary_line.py +30 -0
- pyedb/ipc2581/content/entry_color.py +13 -0
- pyedb/ipc2581/content/entry_line.py +14 -0
- pyedb/ipc2581/content/fill.py +15 -0
- pyedb/ipc2581/content/layer_ref.py +10 -0
- pyedb/ipc2581/content/standard_geometries_dictionary.py +72 -0
- pyedb/ipc2581/ecad/__init__.py +0 -0
- pyedb/ipc2581/ecad/cad_data/__init__.py +0 -0
- pyedb/ipc2581/ecad/cad_data/assembly_drawing.py +26 -0
- pyedb/ipc2581/ecad/cad_data/cad_data.py +37 -0
- pyedb/ipc2581/ecad/cad_data/component.py +41 -0
- pyedb/ipc2581/ecad/cad_data/drill.py +30 -0
- pyedb/ipc2581/ecad/cad_data/feature.py +54 -0
- pyedb/ipc2581/ecad/cad_data/layer.py +41 -0
- pyedb/ipc2581/ecad/cad_data/layer_feature.py +151 -0
- pyedb/ipc2581/ecad/cad_data/logical_net.py +32 -0
- pyedb/ipc2581/ecad/cad_data/outline.py +25 -0
- pyedb/ipc2581/ecad/cad_data/package.py +104 -0
- pyedb/ipc2581/ecad/cad_data/padstack_def.py +38 -0
- pyedb/ipc2581/ecad/cad_data/padstack_hole_def.py +24 -0
- pyedb/ipc2581/ecad/cad_data/padstack_instance.py +62 -0
- pyedb/ipc2581/ecad/cad_data/padstack_pad_def.py +26 -0
- pyedb/ipc2581/ecad/cad_data/path.py +89 -0
- pyedb/ipc2581/ecad/cad_data/phy_net.py +80 -0
- pyedb/ipc2581/ecad/cad_data/pin.py +31 -0
- pyedb/ipc2581/ecad/cad_data/polygon.py +169 -0
- pyedb/ipc2581/ecad/cad_data/profile.py +40 -0
- pyedb/ipc2581/ecad/cad_data/stackup.py +31 -0
- pyedb/ipc2581/ecad/cad_data/stackup_group.py +42 -0
- pyedb/ipc2581/ecad/cad_data/stackup_layer.py +21 -0
- pyedb/ipc2581/ecad/cad_data/step.py +275 -0
- pyedb/ipc2581/ecad/cad_header.py +33 -0
- pyedb/ipc2581/ecad/ecad.py +19 -0
- pyedb/ipc2581/ecad/spec.py +46 -0
- pyedb/ipc2581/history_record.py +37 -0
- pyedb/ipc2581/ipc2581.py +387 -0
- pyedb/ipc2581/logistic_header.py +25 -0
- pyedb/misc/__init__.py +0 -0
- pyedb/misc/aedtlib_personalib_install.py +14 -0
- pyedb/misc/downloads.py +322 -0
- pyedb/misc/misc.py +67 -0
- pyedb/misc/pyedb.runtimeconfig.json +13 -0
- pyedb/misc/siw_feature_config/__init__.py +0 -0
- pyedb/misc/siw_feature_config/emc/__init__.py +0 -0
- pyedb/misc/siw_feature_config/emc/component_tags.py +46 -0
- pyedb/misc/siw_feature_config/emc/net_tags.py +37 -0
- pyedb/misc/siw_feature_config/emc/tag_library.py +62 -0
- pyedb/misc/siw_feature_config/emc/xml_generic.py +78 -0
- pyedb/misc/siw_feature_config/emc_rule_checker_settings.py +179 -0
- pyedb/misc/utilities.py +27 -0
- pyedb/modeler/geometry_operators.py +2082 -0
- pyedb-0.2.0.dist-info/LICENSE +21 -0
- pyedb-0.2.0.dist-info/METADATA +208 -0
- pyedb-0.2.0.dist-info/RECORD +128 -0
- 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
|