Skip to content

Commit a3b3d96

Browse files
svandenb-devmaxcapodi78PipKat
authored
EDB - Load amat material file from Aedt (#3713)
* edb intersection bug fix * pyaedt cutout bug fix * load amat material in edb * load amat material in edb * load amat material in edb * load amat material in edb * New methods: add_material_from_aedt which expect an aedt material name load_material_from_amat which load all materials in amat current limitations: supports only materials with float value (no nonlinear materials and no formulas) * Implemented suggestion * Implemented suggestion * Implemented suggestion * Implemented suggestion * added docstring * Update pyaedt/edb_core/materials.py Co-authored-by: Kathy Pippert <[email protected]> * Update pyaedt/edb_core/materials.py Co-authored-by: Kathy Pippert <[email protected]> --------- Co-authored-by: maxcapodi78 <Shark78> Co-authored-by: Massimo Capodiferro <[email protected]> Co-authored-by: Kathy Pippert <[email protected]>
1 parent 5e770b5 commit a3b3d96

File tree

6 files changed

+183
-3
lines changed

6 files changed

+183
-3
lines changed

_unittest/test_00_EDB.py

+13
Original file line numberDiff line numberDiff line change
@@ -2855,6 +2855,7 @@ def test_145_arc_data(self):
28552855
assert self.edbapp.nets["1.2V_DVDDL"].primitives[0].arcs[0].height
28562856

28572857
def test_145_via_volume(self):
2858+
#
28582859
vias = [
28592860
via
28602861
for via in list(self.edbapp.padstacks.padstack_instances.values())
@@ -2903,3 +2904,15 @@ def test_147_find_dc_shorts(self):
29032904
edbapp.nets["DDR4_DM3"].find_dc_short(True)
29042905
assert len(edbapp.nets["DDR4_DM3"].find_dc_short()) == 0
29052906
edbapp.close()
2907+
2908+
def test_148_load_amat(self):
2909+
assert "Rogers RO3003 (tm)" in self.edbapp.materials.materials_in_aedt
2910+
material_file = os.path.join(self.edbapp.materials.syslib, "Materials.amat")
2911+
assert self.edbapp.materials.add_material_from_aedt("Arnold_Magnetics_N28AH_-40C")
2912+
assert "Arnold_Magnetics_N28AH_-40C" in self.edbapp.materials.materials.keys()
2913+
assert self.edbapp.materials.load_amat(material_file)
2914+
material_list = list(self.edbapp.materials.materials.keys())
2915+
assert material_list
2916+
assert len(material_list) > 0
2917+
assert self.edbapp.materials.materials["Rogers RO3003 (tm)"].loss_tangent == 0.0013
2918+
assert self.edbapp.materials.materials["Rogers RO3003 (tm)"].permittivity == 3.0

doc/source/Getting_started/Quickcode.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ page on the Ansys Developer portal, you can post questions, share ideas, and get
3131
To reach the project support team, email `[email protected] <[email protected]>`_.
3232

3333

34-
Example Workflow
34+
Example workflow
3535
----------------
3636
Here’s a brief example of how PyAEDT works:
3737

doc/styles/Vocab/ANSYS/accept.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -81,5 +81,6 @@ EDT
8181
pyansys
8282
Slurm
8383
Python.NET
84-
84+
Toolkits
85+
toolkits
8586

ignore_words.txt

+1
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,4 @@ ro
3131
aline
3232
COM
3333
gRPC
34+
Toolkits

pyaedt/edb_core/materials.py

+162
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
from __future__ import absolute_import # noreorder
22

33
import difflib
4+
import fnmatch
45
import logging
6+
import os
57
import warnings
68

79
from pyaedt import is_ironpython
@@ -365,12 +367,38 @@ def __getitem__(self, item):
365367

366368
def __init__(self, pedb):
367369
self._pedb = pedb
370+
self._syslib = os.path.join(self._pedb.base_path, "syslib")
371+
self._personal_lib = None
372+
self._materials_in_aedt = None
368373
if not self.materials:
369374
self.add_material("air")
370375
self.add_material("copper", 1, 0.999991, 5.8e7, 0, 0)
371376
self.add_material("fr4_epoxy", 4.4, 1, 0, 0.02, 0)
372377
self.add_material("solder_mask", 3.1, 1, 0, 0.035, 0)
373378

379+
@property
380+
def materials_in_aedt(self):
381+
"""Retrieve the dictionary of materials available in AEDT syslib."""
382+
if self._materials_in_aedt:
383+
return self._materials_in_aedt
384+
self._materials_in_aedt = self._read_materials()
385+
return self._materials_in_aedt
386+
387+
@property
388+
def syslib(self):
389+
"""Retrieve the project sys library."""
390+
return self._syslib
391+
392+
@property
393+
def personallib(self):
394+
"""Get or Set the user personallib."""
395+
return self._personal_lib
396+
397+
@personallib.setter
398+
def personallib(self, value):
399+
self._personal_lib = value
400+
self._materials_in_aedt = self._read_materials()
401+
374402
@pyaedt_function_handler()
375403
def _edb_value(self, value):
376404
return self._pedb.edb_value(value)
@@ -807,3 +835,137 @@ def get_property_by_material_name(self, property_name, material_name):
807835
else:
808836
return property_box.ToDouble()
809837
return False
838+
839+
@pyaedt_function_handler()
840+
def add_material_from_aedt(self, material_name):
841+
"""Add a material read from ``syslib amat`` library.
842+
843+
Parameters
844+
----------
845+
material_name : str
846+
Material name.
847+
848+
Returns
849+
-------
850+
bool
851+
"True`` when successful, ``False`` when failed.
852+
"""
853+
if material_name in self.materials_in_aedt:
854+
if material_name in list(self.materials.keys()):
855+
self._pedb.logger.warning("Material {} already exists. Skipping it.".format(material_name))
856+
return False
857+
new_material = self.add_material(name=material_name)
858+
material = self.materials_in_aedt[material_name]
859+
try:
860+
new_material.permittivity = float(material["permittivity"])
861+
except (KeyError, TypeError):
862+
pass
863+
try:
864+
new_material.conductivity = float(material["conductivity"])
865+
except (KeyError, TypeError):
866+
pass
867+
try:
868+
new_material.mass_density = float(material["mass_density"])
869+
except (KeyError, TypeError):
870+
pass
871+
try:
872+
new_material.permeability = float(material["permeability"])
873+
except (KeyError, TypeError):
874+
pass
875+
try:
876+
new_material.loss_tangent = float(material["dielectric_loss_tangent"])
877+
except (KeyError, TypeError):
878+
pass
879+
try:
880+
new_material.specific_heat = float(material["specific_heat"])
881+
except (KeyError, TypeError):
882+
pass
883+
try:
884+
new_material.thermal_expansion_coefficient = float(material["thermal_expansion_coeffcient"])
885+
except (KeyError, TypeError):
886+
pass
887+
return True
888+
889+
@pyaedt_function_handler()
890+
def load_amat(self, amat_file):
891+
"""Load material from an amat file and add materials to Edb.
892+
893+
Parameters
894+
----------
895+
amat_file : str
896+
Full path to the amat file to read and add to the Edb.
897+
"""
898+
material_dict = self._read_materials(amat_file)
899+
for material_name, material in material_dict.items():
900+
if not material_name in list(self.materials.keys()):
901+
new_material = self.add_material(name=material_name)
902+
try:
903+
new_material.permittivity = float(material["permittivity"])
904+
except (KeyError, TypeError):
905+
pass
906+
try:
907+
new_material.conductivity = float(material["conductivity"])
908+
except (KeyError, TypeError):
909+
pass
910+
try:
911+
new_material.mass_density = float(material["mass_density"])
912+
except (KeyError, TypeError):
913+
pass
914+
try:
915+
new_material.permeability = float(material["permeability"])
916+
except (KeyError, TypeError):
917+
pass
918+
try:
919+
new_material.loss_tangent = float(material["dielectric_loss_tangent"])
920+
except (KeyError, TypeError):
921+
pass
922+
try:
923+
new_material.specific_heat = float(material["specific_heat"])
924+
except (KeyError, TypeError):
925+
pass
926+
try:
927+
new_material.thermal_expansion_coefficient = float(material["thermal_expansion_coeffcient"])
928+
except (KeyError, TypeError):
929+
pass
930+
return True
931+
932+
@pyaedt_function_handler()
933+
def _read_materials(self, mat_file=None):
934+
def get_mat_list(file_name, mats):
935+
from pyaedt.generic.LoadAEDTFile import load_entire_aedt_file
936+
937+
mread = load_entire_aedt_file(file_name)
938+
for mat, mdict in mread.items():
939+
if mat != "$base_index$":
940+
try:
941+
mats[mat] = mdict["MaterialDef"][mat]
942+
except KeyError:
943+
mats[mat] = mdict
944+
945+
if mat_file and os.path.exists(mat_file):
946+
materials = {}
947+
get_mat_list(mat_file, materials)
948+
return materials
949+
950+
amat_sys = [
951+
os.path.join(dirpath, filename)
952+
for dirpath, _, filenames in os.walk(self.syslib)
953+
for filename in filenames
954+
if fnmatch.fnmatch(filename, "*.amat")
955+
]
956+
amat_personal = []
957+
if self.personallib:
958+
amat_personal = [
959+
os.path.join(dirpath, filename)
960+
for dirpath, _, filenames in os.walk(self.personallib)
961+
for filename in filenames
962+
if fnmatch.fnmatch(filename, "*.amat")
963+
]
964+
materials = {}
965+
for amat in amat_sys:
966+
get_mat_list(amat, materials)
967+
968+
if amat_personal:
969+
for amat in amat_personal:
970+
get_mat_list(amat, materials)
971+
return materials

pyaedt/edb_core/stackup.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,10 @@ def add_layer(
666666
fillMaterial = "fr4_epoxy"
667667

668668
if material.lower() not in materials_lower:
669-
logger.error(material + " does not exist in material library")
669+
if material in self._pedb.materials.materials_in_aedt:
670+
self._pedb.materials.add_material_from_aedt("material")
671+
else:
672+
logger.error(material + " does not exist in material library")
670673
else:
671674
material = materials_lower[material.lower()]
672675

0 commit comments

Comments
 (0)