Skip to content

Added set_spice_model method to Hfss3dLayout #803

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
*----------------------------------------------------------------------
* SPICE Model generated by Murata Manufacturing Co., Ltd.
* Copyright(C) Murata Manufacturing Co., Ltd.
* Description :3225M(1210)/X7R/2.2uF/100V
* Murata P/N :GRM32ER72A225KA35
* Property : C = 2.2[uF]
* Data Generated on Mar 14, 2018
*----------------------------------------------------------------------
* Applicable Conditions:
* Frequency Range = 100Hz-6GHz
* Temperature = 25 degC
* DC Bias Voltage = 0V
* Small Signal Operation
*----------------------------------------------------------------------
.SUBCKT GRM32ER72A225KA35_25C_0V port1 port2
C1 port1 11 2.18e-6
L2 11 12 1.28e-10
R3 12 13 2.50e-3
C4 13 14 8.43e-5
R4 13 14 91.0
C5 14 15 3.62e-4
R5 14 15 1.44
C6 15 16 2.76e-4
R6 15 16 1.91e-1
C7 16 17 2.39e-4
R7 16 17 2.22e-2
C8 17 18 1.82e-4
R8 17 18 2.69e-3
L9 18 19 3.18e-10
R9 18 19 3.02e-2
L10 19 20 1.76e-11
R10 19 20 2.18e-2
C11 20 21 4.33e-6
L11 20 21 1.35e-10
R11 20 21 3.50e-2
C12 21 22 2.64e-6
L12 21 22 7.74e-11
R12 21 22 1.86e-2
C13 22 port2 1.81e-12
L13 22 port2 2.74e-10
R13 22 port2 46.5
R100 port1 11 2.27e+8
.ENDS GRM32ER72A225KA35_25C_0V
6 changes: 6 additions & 0 deletions _unittest/test_40_3dlayout_edb.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,9 @@ def test_04_add_mesh_operations(self):

def test_05_change_property(self):
assert self.aedtapp.modeler.change_property("Excitations:J2B3-2", "Impedance", "49ohm", "EM Design")

def test_06_assign_spice_model(self):
model_path = os.path.join(self.local_scratch.path, test_project_name + ".aedb", "GRM32ER72A225KA35_25C_0V.sp")
assert self.aedtapp.modeler.set_spice_model(
component_name="C3A3", model_path=model_path, subcircuit_name="GRM32ER72A225KA35_25C_0V"
)
2 changes: 1 addition & 1 deletion pyaedt/application/Analysis3DLayout.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def __init__(
self._oboundary = self._odesign.GetModule("Excitations")
self.logger.info("Analysis Loaded")
self._modeler = Modeler3DLayout(self)
self._modeler.primitives.init_padstacks()
self._modeler.init_padstacks()
self.logger.info("Modeler Loaded")
self._mesh = Mesh3d(self)
self._post = PostProcessor(self)
Expand Down
7 changes: 5 additions & 2 deletions pyaedt/application/Design.py
Original file line number Diff line number Diff line change
Expand Up @@ -972,9 +972,12 @@ def oproject(self, proj_name=None):
time.sleep(0.5)
proj = self.odesktop.GetActiveProject()
self.logger.info("Archive {} has been restored to project {}".format(proj_name, proj.GetName()))
elif ".def" in proj_name:
elif ".def" in proj_name or proj_name[-5:] == ".aedb":
oTool = self.odesktop.GetTool("ImportExport")
oTool.ImportEDB(proj_name)
if ".def" in proj_name:
oTool.ImportEDB(proj_name)
else:
oTool.ImportEDB(os.path.join(proj_name, "edb.def"))
proj = self.odesktop.GetActiveProject()
proj.Save()
self.logger.info("EDB folder %s has been imported to project %s", proj_name, proj.GetName())
Expand Down
3 changes: 2 additions & 1 deletion pyaedt/hfss3dlayout.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ class Hfss3dLayout(FieldAnalysis3DLayout):
----------
projectname : str, optional
Name of the project to select or the full path to the project
or AEDTZ archive to open. The default is ``None``, in which
or AEDTZ archive to open or the path to aedb folder or edb.def file.
The default is ``None``, in which
case an attempt is made to get an active project. If no
projects are present, an empty project is created.
designname : str, optional
Expand Down
115 changes: 114 additions & 1 deletion pyaedt/modeler/Model3DLayout.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import time
import re
from warnings import warn

from pyaedt.generic.constants import AEDT_UNITS
Expand All @@ -10,6 +11,7 @@
is_ironpython,
_pythonver,
inside_desktop,
get_filename_without_extension,
)
from pyaedt.modules.LayerStackup import Layers
from pyaedt.modeler.Modeler import Modeler
Expand Down Expand Up @@ -68,7 +70,9 @@ def __init__(self, app):

self.logger.info("Primitives loaded.")
self.layers.refresh_all_layers()

self.o_def_manager = self._app.odefinition_manager
self.o_component_manager = self.o_def_manager.GetManager("Component")
self.o_model_manager = self.o_def_manager.GetManager("Model")
pass

@property
Expand Down Expand Up @@ -669,3 +673,112 @@ def set_temperature_dependence(
else:
self.logger.info("Assigned Objects Temperature")
return True

@aedt_exception_handler
def set_spice_model(self, component_name, model_path, model_name=None, subcircuit_name=None, pin_map=None):
"""Assign a Spice model to a component.

Parameters
----------
component_name : str
Name of the component.
model_path : str, optional
Full path to the model file. The default is ``None``.
model_name : str, optional
Name of the model. The default is ``None`` which means that model_name is file name without extension.
subcircuit_name : str, optional
Name of the subcircuit. The default is ``None`` which means that subcircuit name is the model_name.
pin_map : list, optional
List of [spice_pin_name, aedt_pin_name] to optional
customize the pin mapping between Spice Pins and AEDT Pins.
Returns
-------
bool
``True`` when successful, ``False`` when failed.

Examples
--------

>>> from pyaedt import Hfss3dLayout
>>> h3d = Hfss3dLayout("myproject")
>>> h3d.modeler.set_spice_model(component_name="A1",
... modelpath="pathtospfile",
... modelname="spicemodelname",
... subcircuit_name="SUBCK1")

"""
if not model_name:
model_name = get_filename_without_extension(model_path)
if model_name not in list(self.o_model_manager.GetNames()):
args = [
"NAME:" + model_name,
"Name:=",
model_name,
"ModTime:=",
1643711258,
"Library:=",
"",
"LibLocation:=",
"Project",
"ModelType:=",
"dcirspice",
"Description:=",
"",
"ImageFile:=",
"",
"SymbolPinConfiguration:=",
0,
["NAME:PortInfoBlk"],
["NAME:PortOrderBlk"],
"filename:=",
model_path,
"modelname:=",
model_name,
]
self.o_model_manager.Add(args)
if not subcircuit_name:
subcircuit_name = model_name
with open(model_path, "r") as f:
for line in f:
if "subckt" in line.lower():
pinNames = [i.strip() for i in re.split(" |\t", line) if i]
pinNames.remove(pinNames[0])
pinNames.remove(pinNames[0])
break
componentPins = [i.GetName() for i in self.edb.core_components.get_pin_from_component(component_name)]
componentPins.reverse()
if not pin_map:
pin_map = []
i = 0
if len(componentPins) >= len(pinNames):
for pn in pinNames:
pin_map.append(pn + ":=")
pin_map.append(componentPins[i])
i += 1
args2 = [
"CompPropEnabled:=",
True,
"Pid:=",
-1,
"Pmo:=",
"0",
"CompPropType:=",
0,
"PinPairRLC:=",
[
"RLCModelType:=",
4,
"SPICE_file_path:=",
model_path,
"SPICE_model_name:=",
model_name,
"SPICE_subckt:=",
subcircuit_name,
"terminal_pin_map:=",
pin_map,
],
]
args = ["NAME:ModelChanges", ["NAME:UpdateModel0", ["NAME:ComponentNames", component_name], "Prop:=", args2]]
self.oeditor.UpdateModels(args)
self.logger.info("Spice Model Correctly assigned to {}.".format(component_name))
return True