Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/pip/requirements/pytest-7.2.2
Browse files Browse the repository at this point in the history
  • Loading branch information
MaxJPRey committed Mar 6, 2023
2 parents acef940 + cfa119a commit 36afd32
Show file tree
Hide file tree
Showing 12 changed files with 216 additions and 117 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
$begin '$base_index$'
$begin 'properties'
all_levels=000000000000
time(year=000000002023, month=000000000002, day=000000000021, hour=000000000008, min=000000000046, sec=000000000034)
time(year=000000002023, month=000000000003, day=000000000006, hour=000000000008, min=000000000021, sec=000000000023)
version=000000000000
$end 'properties'
$begin '$base_index$'
Expand Down Expand Up @@ -85,5 +85,7 @@ $begin '$index$'
$end '$index$'
$end '$index$'
'$index$'
'$index$'
'$index$'
'$index$'

8 changes: 7 additions & 1 deletion _unittest/test_40_3dlayout_edb.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

# Import required modules
from pyaedt import Hfss3dLayout
from pyaedt import is_ironpython

test_subfolder = "T40"
if config["desktopVersion"] > "2022.2":
Expand Down Expand Up @@ -307,12 +308,15 @@ def test_18_set_variable(self):
assert "var_test" in self.aedtapp.variable_manager.design_variable_names
assert self.aedtapp.variable_manager.design_variables["var_test"].expression == "234"

@pytest.mark.skipif(is_ironpython, reason="Not Supported.")
def test_19_dcir(self):
import pandas as pd

lock = self.dcir_example_project + ".lock"
if os.path.isfile(lock):
os.remove(lock)
hfss3d = Hfss3dLayout(self.dcir_example_project, "Galileo_G87173_204", specified_version=desktop_version)
assert hfss3d.get_dcir_solution_data("Siwave_DC_WP9QNY", "RL", "Path_Resistance")
assert hfss3d.get_dcir_solution_data("Siwave_DC_WP9QNY", "RL", "Path Resistance")
assert hfss3d.get_dcir_solution_data("Siwave_DC_WP9QNY", "Vias", "Current")
solution_data = hfss3d.get_dcir_solution_data("Siwave_DC_WP9QNY", "Sources", "Voltage")
assert hfss3d.post.available_report_quantities(is_siwave_dc=True, context="")
Expand All @@ -322,3 +326,5 @@ def test_19_dcir(self):
domain="DCIR",
context="RL",
)
assert isinstance(hfss3d.get_dcir_element_data_loop_resistance("Siwave_DC_WP9QNY"), pd.DataFrame)
assert isinstance(hfss3d.get_dcir_element_data_current_source("Siwave_DC_WP9QNY"), pd.DataFrame)
37 changes: 19 additions & 18 deletions examples/01-HFSS3DLayout/Dcir_in_3DLayout.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,34 +98,35 @@
hfss3dl.save_project()

###############################################################################
# Get element data
# ~~~~~~~~~~~~~~~~~~~
# Get loop resistance

loop_resistance = hfss3dl.get_dcir_element_data_loop_resistance(setup_name="my_setup")
print(loop_resistance)

# ~~~~~~~~~~~~~~~~~~~
# Get loop resistance from dcir result
loop_resistance = hfss3dl.get_dcir_solution_data(
setup_name="my_setup",
show="RL",
category="Loop_Resistance")
print({expression: loop_resistance.data_magnitude(expression) for expression in loop_resistance.expressions})
# Get current source

current_source = hfss3dl.get_dcir_element_data_current_source(setup_name="my_setup")
print(current_source)

# ~~~~~~~~~~~~~~~~~~~
# Get via information

via = hfss3dl.get_dcir_element_data_via(setup_name="my_setup")
print(via)


###############################################################################
# Get voltage
# ~~~~~~~~~~~
# Get voltage from dcir result
# Get voltage from dcir solution data
voltage = hfss3dl.get_dcir_solution_data(
setup_name="my_setup",
show="Sources",
category="Voltage")
print({ expression: voltage.data_magnitude(expression) for expression in voltage.expressions})

###############################################################################
# Get via
# ~~~~~~~
# Get via current from dcir result
via_current = hfss3dl.get_dcir_solution_data(
setup_name="my_setup",
show="Vias",
category="Current")
print({ expression: via_current.data_magnitude(expression) for expression in via_current.expressions[100:105]})
print({expression: voltage.data_magnitude(expression) for expression in voltage.expressions})

###############################################################################
# Close AEDT
Expand Down
10 changes: 3 additions & 7 deletions pyaedt/downloads.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,9 @@ def _retrieve_file(url, filename, directory, destination=None):
# grab the correct url retriever
if not is_ironpython:
urlretrieve = urllib.request.urlretrieve

dirpath = os.path.dirname(local_path)
if not os.path.isdir(destination):
os.mkdir(destination)
if not os.path.isdir(dirpath):
os.makedirs(dirpath)

destination_dir = os.path.join(destination, directory)
if not os.path.isdir(destination_dir):
os.makedirs(destination_dir)
# Perform download
if os.name == "posix":
command = "wget {} -O {}".format(url, local_path)
Expand Down
14 changes: 8 additions & 6 deletions pyaedt/generic/general_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,19 +292,21 @@ def open_file(file_path, file_options="r"):
object
Opened file.
"""
file_path = os.path.abspath(file_path.replace("\\", "/") if file_path[0] != "\\" else file_path)
file_path = file_path.replace("\\", "/") if file_path[0] != "\\" else file_path
dir_name = os.path.dirname(file_path)
if "r" in file_options:
if os.path.exists(file_path):
return open(file_path, file_options)
elif settings.remote_rpc_session and settings.remote_rpc_session.filemanager.pathexists(file_path):
return settings.remote_rpc_session.open_file(file_path, file_options)
elif settings.remote_rpc_session and settings.remote_rpc_session.filemanager.pathexists(
file_path
): # pragma: no cover
local_file = os.path.join(tempfile.gettempdir(), os.path.split(file_path)[-1])
settings.remote_rpc_session.filemanager.download_file(file_path, local_file)
return open(local_file, file_options)
elif os.path.exists(dir_name):
return open(file_path, file_options)
elif settings.remote_rpc_session:
return settings.remote_rpc_session.open_file(file_path, file_options)
else:
settings.logger.error("The file: %s does not exist", dir_name)
settings.logger.error("The file or folder %s does not exist", dir_name)


def _log_method(func, new_args, new_kwargs):
Expand Down
158 changes: 128 additions & 30 deletions pyaedt/hfss3dlayout.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import fnmatch
import io
import os
import re
import warnings
from collections import OrderedDict

Expand All @@ -17,9 +18,6 @@
from pyaedt.generic.general_methods import pyaedt_function_handler
from pyaedt.generic.general_methods import tech_to_control_file
from pyaedt.modules.Boundary import BoundaryObject3dLayout
from pyaedt.modules.PostProcessor import ReportDcirCategory
from pyaedt.modules.PostProcessor import ReportDcirShow
from pyaedt.modules.solutions import SolutionData


class Hfss3dLayout(FieldAnalysis3DLayout):
Expand Down Expand Up @@ -1881,7 +1879,7 @@ def _update_port_info(self, port):

@pyaedt_function_handler()
def get_model_from_mesh_results(self, binary=True):
"""Get the path for the parasolid file in the results folder.
"""Get the path for the parasolid file in the result folder.
The parasolid file is generated after the mesh is created in 3D Layout.
Parameters
Expand Down Expand Up @@ -2003,7 +2001,7 @@ def edit_source_from_file(
self.logger.error("Port not found.")
return False

def get_dcir_solution_data(self, setup_name, show="RL", category="Voltage"):
def get_dcir_solution_data(self, setup_name, show="RL", category="Loop_Resistance"):
"""Retrieve dcir solution data. Available element_names are dependent on element_type as below.
Sources ["Voltage", "Current", "Power"]
"RL" ['Loop Resistance', 'Path Resistance', 'Resistance', 'Inductance']
Expand All @@ -2019,39 +2017,23 @@ def get_dcir_solution_data(self, setup_name, show="RL", category="Voltage"):
Type of the element. Options are ``"Sources"`, ``"RL"`, ``"Vias"``, ``"Bondwires"``, and ``"Probes"``.
category : str, optional
Name of the element. Options are ``"Voltage"`, ``"Current"`, ``"Power"``, ``"Loop_Resistance"``,
``"Path_Resistance"``, ``"Resistance"``, ``"Inductance"``, ``"X"``, ``"Y"``, ``"Limit"`` and ``"IR_Drop"``.
``"Path_Resistance"``, ``"Resistance"``, ``"Inductance"``, ``"X"``, ``"Y"``, ``"Limit"`` and ``"IR Drop"``.
Returns
-------
pyaedt.modules.solutions.SolutionData
"""
if is_ironpython:
self._logger.error("Function is only supported in CPython.")
return False
show_id = ReportDcirShow[show].value
category = ReportDcirCategory[category].value

context = [
"NAME:Context",
"SimValueContext:=",
[37010, 0, 2, 0, False, False, -1, 1, 0, 1, 1, "", 0, 0, "DCIRID", False, show_id, "IDIID", False, "1"],
]
all_categories = list(
self.post.oreportsetup.GetAllCategories("Standard", "Rectangular Plot", setup_name, context)
)
if category not in all_categories: # pragma: no cover
if is_ironpython: # pragma: no cover
self._logger.error("Function is only supported in CPython.")
return False

all_categories = self.post.available_quantities_categories(context=show, is_siwave_dc=True)
if category not in all_categories:
return False # pragma: no cover
all_quantities = self.post.available_report_quantities(
is_siwave_dc=True, context=show, quantities_category=category
)
data = self.post.oreportsetup.GetSolutionDataPerVariation(
"Standard",
setup_name,
context,
["Index:=", "All"],
all_quantities,
context=show, is_siwave_dc=True, quantities_category=category
)
return SolutionData(list(data))

return self.post.get_solution_data(all_quantities, setup_sweep_name=setup_name, domain="DCIR", context=show)

def get_touchstone_data(self, setup_name=None, sweep_name=None, variations=None):
"""
Expand Down Expand Up @@ -2093,3 +2075,119 @@ def get_touchstone_data(self, setup_name=None, sweep_name=None, variations=None)
sol_data.set_active_variation(i)
s_parameters.append(TouchstoneData(solution_data=sol_data))
return s_parameters

def get_dcir_element_data_loop_resistance(self, setup_name):
"""Get dcir element data loop resistance.
Parameters
----------
setup_name : str
Name of the setup.
Returns
-------
pandas.Dataframe
"""
if is_ironpython: # pragma: no cover
self.logger.error("Method not supported in IronPython.")
return False
import pandas as pd

solution_data = self.get_dcir_solution_data(setup_name=setup_name, show="RL", category="Loop Resistance")

terms = []
pattern = r"LoopRes\((.*?)\)"
for ex in solution_data.expressions:
matches = re.findall(pattern, ex)
if matches:
terms.extend(matches[0].split(","))
terms = list(set(terms))

data = {}
for i in terms:
data2 = []
for ex in ["LoopRes({},{})".format(i, j) for j in terms]:
d = solution_data.data_magnitude(ex)
if d is not False:
data2.append(d[0])
else:
data2.append(False)
data[i] = data2

df = pd.DataFrame(data)
df.index = terms
return df

def get_dcir_element_data_current_source(self, setup_name):
"""Get dcir element data current source.
Parameters
----------
setup_name : str
Name of the setup.
Returns
-------
pandas.Dataframe
"""
if is_ironpython: # pragma: no cover
self.logger.error("Method not supported in IronPython.")
return False
import pandas as pd

solution_data = self.get_dcir_solution_data(setup_name=setup_name, show="Sources", category="Voltage")
terms = []
pattern = r"^V\((.*?)\)"
for t_name in solution_data.expressions:
matches = re.findall(pattern, t_name)
if matches:
terms.append(matches[0])
terms = list(set(terms))

data = {"Voltage": []}
for t_name in terms:
ex = "V({})".format(t_name)
value = solution_data.data_magnitude(ex, convert_to_SI=True)
if value is not False:
data["Voltage"].append(value[0])
df = pd.DataFrame(data)
df.index = terms
return df

def get_dcir_element_data_via(self, setup_name):
"""Get dcir element data via.
Parameters
----------
setup_name : str
Name of the setup.
Returns
-------
pandas.Dataframe
"""
if is_ironpython:
self.logger.error("Method not supported in IronPython.")
return False
import pandas as pd

cates = ["X", "Y", "Current", "Resistance", "IR Drop", "Power"]
df = None
for cat in cates:
data = {cat: []}
solution_data = self.get_dcir_solution_data(setup_name=setup_name, show="Vias", category=cat)
tmp_via_names = []
pattern = r"\((.*?)\)"
for t_name in solution_data.expressions:
matches = re.findall(pattern, t_name)
if matches:
tmp_via_names.append(matches[0])

for ex in solution_data.expressions:
value = solution_data.data_magnitude(ex, convert_to_SI=True)[0]
data[cat].append(value)

df_tmp = pd.DataFrame(data)
df_tmp.index = tmp_via_names
if not isinstance(df, pd.DataFrame):
df = df_tmp
else:
df.merge(df_tmp, left_index=True, right_index=True, how="outer")
return df
5 changes: 1 addition & 4 deletions pyaedt/modules/MaterialLib.py
Original file line number Diff line number Diff line change
Expand Up @@ -806,10 +806,7 @@ def import_materials_from_excel(self, material_file):
and val[keys.index(prop)]
and not (isinstance(val[keys.index(prop)], float) and math.isnan(val[keys.index(prop)]))
):
prop_value = val[keys.index(prop)]
if prop_value.dtype == "int64":
prop_value = prop_value.astype(float)
props[prop] = prop_value
props[prop] = float(val[keys.index(prop)])
new_material = Material(self, newname, props)
new_material.update()
self.material_keys[newname] = new_material
Expand Down

0 comments on commit 36afd32

Please sign in to comment.