Skip to content

Commit

Permalink
Plot on layers (#4531)
Browse files Browse the repository at this point in the history
Co-authored-by: maxcapodi78 <Shark78>
  • Loading branch information
maxcapodi78 authored Apr 18, 2024
1 parent 567fd28 commit 7bb9087
Show file tree
Hide file tree
Showing 3 changed files with 244 additions and 28 deletions.
48 changes: 48 additions & 0 deletions _unittest/test_41_3dlayout_modeler.py
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,19 @@ def test_41_test_create_polygon(self):
@pytest.mark.skipif(config["desktopVersion"] < "2023.2", reason="Working only from 2023 R2")
def test_42_post_processing(self, add_app):
test_post1 = add_app(project_name=test_post, application=Maxwell3d, subfolder=test_subfolder)

assert test_post1.post.create_fieldplot_layers(
[],
"Mag_H",
intrinsics={"Time": "1ms"},
nets=["GND", "V3P3_S5"],
)

assert test_post1.post.create_fieldplot_layers(
["UNNAMED_006"],
"Mag_H",
intrinsics={"Time": "1ms"},
)
assert test_post1.post.create_fieldplot_layers_nets(
[["TOP", "GND", "V3P3_S5"], ["PWR", "V3P3_S5"]],
"Mag_Volume_Force_Density",
Expand All @@ -679,19 +692,54 @@ def test_42_post_processing(self, add_app):
intrinsics={"Freq": "1GHz", "Phase": "0deg"},
plot_name="Test_Layers4",
)
assert test_post2.post.create_fieldplot_layers(
["TOP", "UNNAMED_004"],
"Mag_E",
intrinsics={"Freq": "1GHz", "Phase": "0deg"},
nets=["GND", "V3P3_S5"],
)
self.aedtapp.close_project(test_post2.project_name)

@pytest.mark.skipif(config["desktopVersion"] < "2023.2", reason="Working only from 2023 R2")
def test_42_post_processing_3d_layout(self, add_app):
test = add_app(
project_name="test_post_3d_layout_solved_23R2", application=Hfss3dLayout, subfolder=test_subfolder
)
assert test.post.create_fieldplot_layers(
[],
"Mag_H",
intrinsics={"Time": "1ms"},
)

assert test.post.create_fieldplot_layers(
["UNNAMED_002", "TOP"],
"Mag_H",
intrinsics={"Time": "1ms"},
)
assert test.post.create_fieldplot_layers(
["TOP"],
"Mag_H",
intrinsics={"Time": "1ms"},
)
assert test.post.create_fieldplot_layers(
["TOP", "PWR"],
"Mag_E",
intrinsics={"Freq": "1GHz"},
nets=["GND", "V3P3_S5"],
)
assert test.post.create_fieldplot_layers(
[],
"Mag_E",
intrinsics={"Freq": "1GHz"},
nets=["GND", "V3P3_S5"],
)
pl1 = test.post.create_fieldplot_layers_nets(
[["TOP", "GND", "V3P3_S5"], ["PWR", "V3P3_S5"]],
"Mag_E",
intrinsics={"Freq": "1GHz"},
plot_name="Test_Layers",
)

assert pl1
assert pl1.export_image_from_aedtplt(tempfile.gettempdir())
self.aedtapp.close_project(test.project_name)
Expand Down
216 changes: 188 additions & 28 deletions pyaedt/modules/PostProcessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -3040,6 +3040,7 @@ def _create_fieldplot(
plot_name=None,
filter_boxes=None,
field_type=None,
create_plot=True,
):
if not list_type.startswith("Layer") and self._app.design_type != "HFSS 3D Layout Design":
assignment = self._app.modeler.convert_to_selections(assignment, True)
Expand Down Expand Up @@ -3083,14 +3084,13 @@ def _create_fieldplot(
plot.name = plot_name
plot.plot_folder = plot_name
plot.filter_boxes = filter_boxes
plt = plot.create()
if "Maxwell" in self._app.design_type and "Transient" in self.post_solution_type:
self.ofieldsreporter.SetPlotsViewSolutionContext([plot_name], setup, "Time:" + intrinsics["Time"])
if plt:
self.field_plots[plot_name] = plot
return plot
else:
return False
if create_plot:
plt = plot.create()
if plt:
return plot
else:
return False
return plot

@pyaedt_function_handler(quantityName="quantity", setup_name="setup")
def _create_fieldplot_line_traces(
Expand Down Expand Up @@ -3294,10 +3294,168 @@ def create_fieldplot_line_traces(
field_type=field_type,
)

@pyaedt_function_handler()
def _get_3dl_layers_nets(self, layers, nets, setup):
lst_faces = []
new_layers = []
if not layers:
new_layers.extend(["{}".format(i) for i in self._app.modeler.edb.stackup.dielectric_layers.keys()])
for layer in self._app.modeler.edb.stackup.signal_layers.keys():
if not nets:
nets = list(self._app.modeler.edb.nets.nets.keys())
for el in nets:
try:
get_ids = self._odesign.GetGeometryIdsForNetLayerCombination(el, layer, setup)
except:
get_ids = []
if isinstance(get_ids, (tuple, list)) and len(get_ids) > 2:
lst_faces.extend([int(i) for i in get_ids[2:]])

else:
for layer in layers:
if layer in self._app.modeler.edb.stackup.dielectric_layers:
new_layers.append("{}".format(layer))
elif layer in self._app.modeler.edb.stackup.signal_layers:
if not nets:
nets = list(self._app.modeler.edb.nets.nets.keys())
for el in nets:
try:
get_ids = self._odesign.GetGeometryIdsForNetLayerCombination(el, layer, setup)
except:
get_ids = []
if isinstance(get_ids, (tuple, list)) and len(get_ids) > 2:
lst_faces.extend([int(i) for i in get_ids[2:]])
return lst_faces, new_layers

@pyaedt_function_handler()
def _get_3d_layers_nets(self, layers, nets):
dielectrics = []
new_layers = []
for k, v in self._app.modeler.user_defined_components.items():
if v.layout_component:
if not layers and not nets:
new_layers.extend(
[
"{}:{}#t=fill".format(k, i)
for i in v.layout_component.edb_object.stackup.signal_layers.keys()
]
)
new_layers.extend(
["{}:{}".format(k, i) for i in v.layout_component.edb_object.stackup.dielectric_layers.keys()]
)
elif not nets:
for layer in layers:
if layer in v.layout_component.edb_object.stackup.signal_layers:
new_layers.append("{}:{}#t=fill".format(k, layer))
elif layer in v.layout_component.edb_object.stackup.dielectric_layers:
new_layers.append("{}:{}".format(k, layer))
elif not layers:
for v in self._app.modeler.user_defined_components.values():
new_layers.extend(
[[i] + nets for i in v.layout_component.edb_object.stackup.signal_layers.keys()]
)
else:
for layer in layers:
if layer in v.layout_component.edb_object.stackup.signal_layers:
new_layers.append([layer] + nets)
elif layer in v.layout_component.edb_object.stackup.dielectric_layers:
dielectrics.append("{}:{}".format(k, layer))
return dielectrics, new_layers

@pyaedt_function_handler()
def create_fieldplot_layers(
self, layers, quantity, setup=None, nets=None, plot_on_surface=True, intrinsics=None, name=None
):
# type: (list, str, str, list, bool, dict, str) -> FieldPlot
"""Create a field plot of stacked layer plot.
This plot is valid from AEDT 2023 R2 and later in HFSS 3D Layout.
It will also work when a layout components in 3d modeler is used.
In order to plot on signal layers use the method ``create_fieldplot_layers_nets``.
Parameters
----------
layers : list
List of layers to plot. For example:
``["Layer1","Layer2"]``. If empty list is provided
all layers will be considered.
quantity : str
Name of the quantity to plot.
setup : str, optional
Name of the setup. The default is ``None``, in which case the ``nominal_adaptive``
setup is used. Make sure to build a setup string in the form of
``"SetupName : SetupSweep"``, where ``SetupSweep`` is the sweep name to
use in the export or ``LastAdaptive``.
nets : list, optional
List of nets to filter the field plot. Optional.
intrinsics : dict, optional
Dictionary containing all intrinsic variables.
The default is ``None``.
name : str, optional
Name of the field plot to create.
Returns
-------
:class:``pyaedt.modules.solutions.FieldPlot`` or bool
Plot object.
References
----------
>>> oModule.CreateFieldPlot
"""
if not setup:
setup = self._app.existing_analysis_sweeps[0]
if nets is None:
nets = []
if not (
"APhi" in self.post_solution_type and settings.aedt_version >= "2023.2"
) and not self._app.design_type in ["HFSS", "HFSS 3D Layout Design"]:
self.logger.error("This method requires AEDT 2023 R2 and Maxwell 3D Transient APhi Formulation.")
return False
if intrinsics is None:
intrinsics = {}
if name and name in list(self.field_plots.keys()):
self.logger.info("Plot {} exists. returning the object.".format(name))
return self.field_plots[name]

if self._app.design_type in ["HFSS 3D Layout Design"]:
lst_faces, new_layers = self._get_3dl_layers_nets(layers, nets, setup)
if new_layers:
plt = self._create_fieldplot(
new_layers, quantity, setup, intrinsics, "ObjList", name, create_plot=False
)
plt.surfaces = lst_faces
out = plt.create()
if out:
return plt
return False
else:
return self._create_fieldplot(lst_faces, quantity, setup, intrinsics, "FacesList", name)
else:
dielectrics, new_layers = self._get_3d_layers_nets(layers, nets)
if nets and plot_on_surface:
plot_type = "LayerNetsExtFace"
elif nets:
plot_type = "LayerNets"
else:
plot_type = "ObjList"
if new_layers:
plt = self._create_fieldplot(
new_layers, quantity, setup, intrinsics, plot_type, name, create_plot=False
)
if dielectrics:
plt.volumes = dielectrics
out = plt.create()
if out:
return plt
elif dielectrics:
return self._create_fieldplot(dielectrics, quantity, setup, intrinsics, "ObjList", name)
return False

@pyaedt_function_handler(quantity_name="quantity", setup_name="setup")
def create_fieldplot_layers_nets(
self, layers_nets, quantity, setup=None, intrinsics=None, plot_on_surface=True, plot_name=None
): # pragma: no cover
):
# type: (list, str, str, dict, bool, str) -> FieldPlot
"""Create a field plot of stacked layer plot.
This plot is valid from AEDT 2023 R2 and later in HFSS 3D Layout
Expand Down Expand Up @@ -3335,21 +3493,7 @@ def create_fieldplot_layers_nets(
>>> oModule.CreateFieldPlot
"""
new_list = []
for layer in layers_nets:
if "no-layer" in layer[0]:
for v in self._app.modeler.user_defined_components.values():
new_list.extend(
[[i] + layer[1:] for i in v.layout_component.edb_object.stackup.stackup_layers.keys()]
)
else:
new_list.append(layer)
layers_nets = new_list
for layer in layers_nets:
if len(layer) == 1 or "no-net" in layer[1]:
for v in self._app.modeler.user_defined_components.values():
if layer[0] in v.layout_component.edb_object.stackup.stackup_layers:
layer.extend(list(v.layout_component.edb_object.nets.nets.keys()))

if not (
"APhi" in self.post_solution_type and settings.aedt_version >= "2023.2"
) and not self._app.design_type in ["HFSS", "HFSS 3D Layout Design"]:
Expand All @@ -3370,11 +3514,27 @@ def create_fieldplot_layers_nets(
if isinstance(get_ids, (tuple, list)) and len(get_ids) > 2:
lst.extend([int(i) for i in get_ids[2:]])
return self._create_fieldplot(lst, quantity, setup, intrinsics, "FacesList", plot_name)
if plot_on_surface:
plot_type = "LayerNetsExtFace"
else:
plot_type = "LayerNets"
return self._create_fieldplot(layers_nets, quantity, setup, intrinsics, plot_type, plot_name)
new_list = []
for layer in layers_nets:
if "no-layer" in layer[0]:
for v in self._app.modeler.user_defined_components.values():
new_list.extend(
[[i] + layer[1:] for i in v.layout_component.edb_object.stackup.signal_layers.keys()]
)
else:
new_list.append(layer)
layers_nets = new_list
for layer in layers_nets:
if len(layer) == 1 or "no-net" in layer[1]:
for v in self._app.modeler.user_defined_components.values():
if layer[0] in v.layout_component.edb_object.stackup.stackup_layers:
layer.extend(list(v.layout_component.edb_object.nets.nets.keys()))
if plot_on_surface:
plot_type = "LayerNetsExtFace"
else:
plot_type = "LayerNets"
return self._create_fieldplot(layers_nets, quantity, setup, intrinsics, plot_type, plot_name)

@pyaedt_function_handler(
objlist="assignment", quantityName="quantity", IntrinsincDict="intrinsics", setup_name="setup"
Expand Down
8 changes: 8 additions & 0 deletions pyaedt/modules/solutions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3113,6 +3113,14 @@ def create(self):
self.oField.CreateFieldPlot(self.surfacePlotInstructionLineTraces, "FieldLineTrace")
else:
self.oField.CreateFieldPlot(self.surfacePlotInstruction, "Field")
if (
"Maxwell" in self._postprocessor._app.design_type
and "Transient" in self._postprocessor.post_solution_type
):
self._postprocessor.ofieldsreporter.SetPlotsViewSolutionContext(
[self.name], self.solution, "Time:" + self.intrinsics["Time"]
)
self._postprocessor.field_plots[self.name] = self
return True
except Exception:
return False
Expand Down

0 comments on commit 7bb9087

Please sign in to comment.