AbstractBuilder

class pmrf.models.adapters.delegated.AbstractBuilder(*, name: str | None = None, metadata: Any = None)

Bases: Model, ABC

Abstract base for an RF model implemented by building another model.

Subclasses implement build() and may then be used anywhere a pmrf.Model is accepted. The returned model supplies the complete RF interface of the builder, including its port count and expanded topology.

build() is a pure, lazy realization hook rather than a one-time initializer. It may be called during RF evaluation, JAX tracing, port discovery, topology expansion, or explicit introspection. Implementations must not perform I/O or mutation, and ParamRF does not cache the returned model. Its type, PyTree topology, and port count must remain stable for a given set of static fields; topology must not depend on dynamic fitted parameter values.

A composite that has no parameters of its own does not need a builder. Prefer a plain function that takes the components and returns the model, e.g. def board(line1, line2): return line1 ** line2.

expand()

Expands this model into its internal graph representation for circuit flattening.

Used by Circuit.flattened to unpack composite models into a single flat netlist for a global matrix solve.

pmrf.models.AbstractBuilder delegates this to its built model, as does a direct Model.build() override, so user classes rarely need it. It is mainly for built-in composites such as pmrf.models.Cascade and pmrf.models.Renumbered.

Returns:

If the model is a composite or routing container, it returns a tuple of: - port_mapping: A list of length nports mapping each external port index

of this model to an internal (Model, port_index) tuple.

  • internal_connections: A list of sub-nodes (connections) to add to the netlist. Each node is a list of (Model, port_index) tuples.

If the model is a fundamental leaf component, it returns None.

Return type:

tuple or None

Examples

A 2-port model holding an inductor and capacitor in series:

>>> def expand(self):
...     L, C = self.inductor, self.capacitor
...     port_mapping = [(L, 0), (C, 1)]
...     internal_connections = [[(L, 1), (C, 0)]]
...     return port_mapping, internal_connections
mna(frequency: Frequency) → MNAStamp

(experimental) Modified Nodal Analysis (MNA) stamp.

Can be overridden in sub-classes.

Otherwise converts from another domain (y2mna, z2mna, etc.). Y is preferred because it gives the sparsest stamp; other domains add auxiliary variables.

primary_matrix(frequency: Frequency, **kwargs)

The primary matrix (e.g. s, a etc.) as a function of frequency.

The primary matrix represents the matrix returned by pmrf.Model.primary_domain, which is either overridden by sub-classes, or is the first property directly overridden out of pmrf.Model.s(), pmrf.Model.a(), pmrf.Model.y(), pmrf.Model.z() (in that order), unless :meth:pmrf.Model.build is overridden, in which case the primary matrix of the built model is returned.

This method can also be overridden itself in order to dynamically implement one of the matrices as opposed to overriding it explicitly.

If this method is called and self.primary_domain is ‘s’, then ‘z0’ should be passed in kwargs.

Parameters:
  • freq (Frequency) – Frequency grid.

  • kwargs – Keyword arguments forwarded to the primary matrix function, such as z0.

Return type:

jnp.ndarray

Raises:

NotImplementedError – If no primary property is overridden.

property number_of_ports: int

Number of ports.

Return type:

int

property primary_domain: str

The primary domain (e.g. "s", "a") as a string.

The primary property is the first overridden among PRIMARY_DOMAINS, unless build is overridden, in which case the primary property of the built model is returned.

Return type:

str

Raises:

NotImplementedError – If no primary property is overridden.