Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
fda0e7a
FEAT: N port component multi
hui-zhou-a Dec 18, 2025
ab70b32
chore: adding changelog file 7029.added.md [dependabot-skip]
pyansys-ci-bot Dec 18, 2025
8acffd6
CHORE: Auto fixes from pre-commit hooks
pre-commit-ci[bot] Dec 18, 2025
ab46bc4
REFACTOR: SPIsim COM
hui-zhou-a Jun 24, 2026
b84ea10
Merge branch 'refs/heads/main' into proposal_pydantic_for_arguments
hui-zhou-a Jun 24, 2026
f5fd6a7
Merge branch 'main' into refactor-spisim-com
hui-zhou-a Jun 27, 2026
1e2f2c4
draft
hui-zhou-a Jun 28, 2026
c7f1971
finsh feature
hui-zhou-a Jun 28, 2026
e6eb4db
fix
hui-zhou-a Jun 28, 2026
c3d490b
fix dcostring
hui-zhou-a Jun 28, 2026
1e33c71
draft
hui-zhou-a Jun 28, 2026
30853c1
minor
hui-zhou-a Jun 28, 2026
5b93baf
Merge branch 'main' into refactor-spisim-com
hui-zhou-a Jun 28, 2026
082b6f9
minor
hui-zhou-a Jun 28, 2026
efb485a
Merge remote-tracking branch 'origin/refactor-spisim-com' into refact…
hui-zhou-a Jun 28, 2026
44f2448
CHORE: Auto fixes from pre-commit hooks
pre-commit-ci[bot] Jun 28, 2026
ffd2b6a
chore: adding changelog file 7855.added.md [dependabot-skip]
pyansys-ci-bot Jun 28, 2026
1ba45ea
fix docstring
hui-zhou-a Jun 28, 2026
59bccb1
Merge branch 'refactor-spisim-com' of https://github.com/ansys/pyaedt…
hui-zhou-a Jun 28, 2026
74eb2d0
CHORE: Auto fixes from pre-commit hooks
pre-commit-ci[bot] Jun 28, 2026
6ebe312
Apply suggestions from code review
hui-zhou-a Jun 29, 2026
99af670
Merge branch 'main' into refactor-spisim-com
hui-zhou-a Jun 29, 2026
b5390da
CHORE: Auto fixes from pre-commit hooks
pre-commit-ci[bot] Jun 29, 2026
d0bfc78
Merge branch 'main' into proposal_pydantic_for_arguments
hui-zhou-a Jun 30, 2026
a752038
draft
hui-zhou-a Jun 30, 2026
ad47e25
docstring
hui-zhou-a Jun 30, 2026
92b1620
CHORE: Auto fixes from pre-commit hooks
pre-commit-ci[bot] Jun 30, 2026
86a2dff
minor fix
hui-zhou-a Jun 30, 2026
f69b027
minor fix
hui-zhou-a Jun 30, 2026
166c171
minor fix
hui-zhou-a Jun 30, 2026
4c47066
Merge remote-tracking branch 'origin/proposal_pydantic_for_arguments'…
hui-zhou-a Jun 30, 2026
f33be0f
CHORE: Auto fixes from pre-commit hooks
pre-commit-ci[bot] Jun 30, 2026
9b912c2
minor fix
hui-zhou-a Jul 1, 2026
b84e354
Merge remote-tracking branch 'origin/proposal_pydantic_for_arguments'…
hui-zhou-a Jul 1, 2026
a391cd4
sss support
hui-zhou-a Jul 1, 2026
5c732fb
Merge branch 'main' into proposal_pydantic_for_arguments
hui-zhou-a Jul 1, 2026
319bf3d
CHORE: Auto fixes from pre-commit hooks
pre-commit-ci[bot] Jul 1, 2026
3678693
Merge remote-tracking branch 'origin/proposal_pydantic_for_arguments'…
hui-zhou-a Jul 1, 2026
4e08ed4
minor fix
hui-zhou-a Jul 1, 2026
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
1 change: 1 addition & 0 deletions doc/changelog.d/7029.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
N port component multi
1 change: 1 addition & 0 deletions doc/changelog.d/7855.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Spisim compute com from single snp with THRU FEXT NEXT
271 changes: 271 additions & 0 deletions src/ansys/aedt/core/modeler/circuits/primitives_circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
import re
import secrets

from pydantic import BaseModel
from pydantic import Field

from ansys.aedt.core.base import PyAedtBase
from ansys.aedt.core.generic.constants import AEDT_UNITS
from ansys.aedt.core.generic.file_utils import generate_unique_name
Expand Down Expand Up @@ -1628,6 +1631,274 @@ def create_wire(self, points: list, name: str = "", page: int = 1) -> Wire | boo
except Exception:
return False

@pyaedt_function_handler()
def __create_nport_multi(
self,
component_type: int,
component_name: str,
num_ports: str,
array_name: str,
array_id_name: str,
files: list,
location: tuple | list | None = None,
page: int = 1,
angle: float = 0.0,
flip: bool = False,
) -> CircuitComponent:
"""Create an N-port multi-component by importing a Sand W component file.

Parameters
----------
component_name : str
Name of the component to create.
num_ports : int
Number of ports or transmission lines.
array_name : str
Name of the array variable.
array_id_name : str
Name of the array ID variable.
files : list
List of touchstone file paths to import.
location : tuple, optional
Tuple of ``(x, y)`` coordinates for component location.
If ``None``, default location is used. Default is ``None``.
page : int, optional
Schematics page number. Default is ``1``.
angle : float, optional
Rotation angle in degrees. Default is ``0.0``.
flip : bool, optional
Whether to flip the component. Default is ``False``.

Returns
-------
:class:`ansys.aedt.core.modeler.cad.object_3dcircuit.CircuitComponent`
Component object.
"""

def convert_to_meter(value):
"""Convert numbers automatically to mils.

It is rounded to the nearest 100 mil which is minimum schematic snap unit.
"""
value = Quantity(value, "mil")

value = value.to("mil")
value.value = round(value.value, -2)
value = value.to("meter")
return value.value

class Files(BaseModel):
files: list[str] = Field(..., min_length=1)

@classmethod
def create(cls, **kwargs):
return cls.model_validate(kwargs)

def to_aedt_args(self):
args = ["NAME:Files"]
if self.files is not None:
args.extend(["Files:=", self.files])
return args

class Options(BaseModel):
num_ports_or_lines: int = Field(..., ge=1)
array_name: str
array_id_name: str
comp_name: str

@classmethod
def create(cls, **kwargs):
return cls.model_validate(kwargs)

def to_aedt_args(self):
args = ["NAME:Options"]
if self.num_ports_or_lines is not None:
args.extend(["NumPortsOrLines:=", self.num_ports_or_lines])
args.extend(["CreateArray:=", True])
if self.array_name is not None:
args.extend(["ArrayName:=", self.array_name])
if self.array_id_name is not None:
args.extend(["ArrayIdName:=", self.array_id_name])
args.extend(["CompType:=", component_type])
if self.comp_name is not None:
args.extend(["CompName:=", self.comp_name])
return args

class ComponentProps(BaseModel):
name: str

@classmethod
def create(cls, **kwargs):
return cls.model_validate(kwargs)

def to_aedt_args(self):
args = ["NAME:ComponentProps"]
if self.name is not None:
args.extend(["Name:=", self.name])
return args

class Attributes(BaseModel):
page: int = 1
x: float
y: float
angle: float = 0.0
flip: bool = False

@classmethod
def create(cls, **kwargs):
kwargs["x"] = convert_to_meter(kwargs.pop("x"))
kwargs["y"] = convert_to_meter(kwargs.pop("y"))
return cls.model_validate(kwargs)

def to_aedt_args(self):
args = ["NAME:Attributes"]
if self.page is not None:
args.extend(["Page:=", self.page])
if self.x is not None:
args.extend(["X:=", self.x])
if self.y is not None:
args.extend(["Y:=", self.y])
if self.angle is not None:
args.extend(["Angle:=", self.angle])
if self.flip is not None:
args.extend(["Flip:=", self.flip])
return args

if location is None:
x, y = self._get_location(location)
else:
x, y = location
for f in files:
if not Path(f).exists():
raise FileNotFoundError(f"Cannot find file: {str(f)}")

files_args = Files.create(files=[str(f) for f in files]).to_aedt_args()
options_args = Options.create(
num_ports_or_lines=num_ports,
array_name=array_name,
array_id_name=array_id_name,
comp_name=component_name,
).to_aedt_args()
self.ocomponent_manager.ImportSandWComponent(files_args, options_args)

props_args = ComponentProps.create(name=component_name).to_aedt_args()
attributes_args = Attributes.create(x=x, y=y, page=page, flip=flip, angle=angle).to_aedt_args()

comp_name = self.oeditor.CreateComponent(props_args, attributes_args)
comp_id = int(comp_name.split(";")[-1])
self.add_id_to_component(comp_id, comp_name)
return self.components[comp_id]

@pyaedt_function_handler()
def create_touchstone_component_multi(
self,
component_name: str,
num_ports: str,
array_name: str,
array_id_name: str,
files: list,
location: tuple | list | None = None,
page: int = 1,
angle: float = 0.0,
flip: bool = False,
) -> CircuitComponent:
"""Create an N-port multi-component by importing touchstone files.

Parameters
----------
component_name : str
Name of the component to create.
num_ports : int
Number of ports or transmission lines.
array_name : str
Name of the array variable.
array_id_name : str
Name of the array ID variable.
files : list
List of touchstone file paths to import.
location : tuple, optional
Tuple of ``(x, y)`` coordinates for component location.
If ``None``, default location is used. Default is ``None``.
page : int, optional
Schematics page number. Default is ``1``.
angle : float, optional
Rotation angle in degrees. Default is ``0.0``.
flip : bool, optional
Whether to flip the component. Default is ``False``.

Returns
-------
:class:`ansys.aedt.core.modeler.cad.object_3dcircuit.CircuitComponent`
Component object.
"""
return self.__create_nport_multi(
component_type=2,
component_name=component_name,
num_ports=num_ports,
array_name=array_name,
array_id_name=array_id_name,
files=files,
location=location,
page=page,
angle=angle,
flip=flip,
)

@pyaedt_function_handler()
def create_state_space_component_multi(
self,
component_name: str,
num_ports: str,
array_name: str,
array_id_name: str,
files: list,
location: tuple | list | None = None,
page: int = 1,
angle: float = 0.0,
flip: bool = False,
) -> CircuitComponent:
"""Create an N-port multi-component by importing state space files.

Parameters
----------
component_name : str
Name of the component to create.
num_ports : int
Number of ports or transmission lines.
array_name : str
Name of the array variable.
array_id_name : str
Name of the array ID variable.
files : list
List of state space file paths to import.
location : tuple, optional
Tuple of ``(x, y)`` coordinates for component location.
If ``None``, default location is used. Default is ``None``.
page : int, optional
Schematics page number. Default is ``1``.
angle : float, optional
Rotation angle in degrees. Default is ``0.0``.
flip : bool, optional
Whether to flip the component. Default is ``False``.

Returns
-------
:class:`ansys.aedt.core.modeler.cad.object_3dcircuit.CircuitComponent`
Component object.
"""
return self.__create_nport_multi(
component_type=1,
component_name=component_name,
num_ports=num_ports,
array_name=array_name,
array_id_name=array_id_name,
files=files,
location=location,
page=page,
angle=angle,
flip=flip,
)


class ComponentInfo(PyAedtBase):
"""Manages Circuit Catalog info."""
Expand Down
Loading
Loading