padne.solver

Attributes

Exceptions

SolverWarning

A warning that is raised by the solver when it encounters a problem

Classes

Functions

construct_strtrees_from_layers(...)

Construct STRtrees for each layer in the problem.

collect_seed_points(→ list[padne.mesh.Point])

Collect all seed points (component pads) that are on this layer.

laplace_operator(→ scipy.sparse.coo_matrix)

Compute the Laplace operator for a given mesh. This is in "mesh-local"

find_connected_layer_geom_indices(→ set[tuple[int, int]])

compute_connectivity(...)

Run the geometric-connectivity pre-pass.

generate_meshes_for_problem(...)

generate_disconnected_meshes(→ list[list[padne.mesh.Mesh]])

Generate simple triangulations for disconnected copper regions.

stamp_network_into_system(→ None)

setup_ground_node(→ None)

process_mesh_laplace_operators(→ None)

produce_layer_solutions(→ list[LayerSolution])

network_has_a_dead_terminal(→ bool)

Check if a network has any connection on a dead (disconnected) copper region.

filter_dead_networks(→ list[padne.problem.Network])

Drop networks whose connections all lie on disconnected copper.

find_best_ground_node_index(→ int)

compute_triangle_gradient(→ padne.mesh.Vector)

Compute the gradient of a function that is a linear interpolation of the

compute_power_density(→ padne.mesh.TwoForm)

Compute the power density at the mesh faces.

allocate_system(→ tuple[scipy.sparse.lil_matrix, ...)

Allocate the global system matrix L and right-hand side vector r.

solve_system(→ tuple[numpy.ndarray, SolverInfo])

Solve L * v = r and return the solution vector together with diagnostics.

assemble_system(→ tuple[scipy.sparse.lil_matrix, ...)

Allocate (L, r) and stamp the mesh Laplacians, all networks, and the

solve(→ Solution)

Solve the given PCB problem to find voltage and current distribution.

Module Contents

padne.solver.log[source]
padne.solver.DTYPE[source]
exception padne.solver.SolverWarning[source]

Bases: Warning

A warning that is raised by the solver when it encounters a problem that does not prevent it from solving the problem, but may indicate a potential issue with the problem definition.

class padne.solver.SolverInfo[source]

Diagnostic information from the solver.

ground_node_current: float[source]
residual_norm: float[source]
class padne.solver.LayerSolution[source]
meshes: list[padne.mesh.Mesh][source]
potentials: list[padne.mesh.ZeroForm][source]
power_densities: list[padne.mesh.TwoForm] = [][source]
disconnected_meshes: list[padne.mesh.Mesh] = [][source]
class padne.solver.Solution[source]
problem: Solution.problem[source]
layer_solutions: list[LayerSolution][source]
solver_info: SolverInfo[source]
padne.solver.construct_strtrees_from_layers(layers: list[padne.problem.Layer]) list[shapely.strtree.STRtree][source]

Construct STRtrees for each layer in the problem.

Args:

layers: List of layers to construct STRtrees for

Returns:

List of STRtrees, one for each layer

class padne.solver.ConnectivityGraph[source]
nodes: list[ConnectivityGraph.Node] = [][source]
class Node[source]
layer_i: int[source]
geom_i: int[source]
is_root: bool = False[source]
neighbors: set[ConnectivityGraph][source]
classmethod create_from_problem(problem: ConnectivityGraph.create_from_problem.problem, strtrees: list[shapely.strtree.STRtree]) ConnectivityGraph[source]
compute_connected_nodes() list[Node][source]

Return a list of all nodes that are either root nodes themselves or are connected to a root node via any connection.

padne.solver.collect_seed_points(problem: collect_seed_points.problem, layer: collect_seed_points.problem) list[padne.mesh.Point][source]

Collect all seed points (component pads) that are on this layer.

Args:

problem: The entire problem containing all lumped elements layer: The specific layer to collect seed points for

Returns:

List of Points to be used as mesh seed points

padne.solver.laplace_operator(mesh: laplace_operator.mesh) scipy.sparse.coo_matrix[source]

Compute the Laplace operator for a given mesh. This is in “mesh-local” indices, so the variable indices are given by the mesh.vertices indices.

class padne.solver.VertexIndexer[source]
global_index_to_vertex_index: list[tuple[int, int]] = [][source]
mesh_vertex_index_to_global_index: dict[tuple[int, int], int][source]
classmethod create(meshes: list[padne.mesh.Mesh]) VertexIndexer[source]
padne.solver.find_connected_layer_geom_indices(connectivity_graph: ConnectivityGraph) set[tuple[int, int]][source]
padne.solver.compute_connectivity(prob: padne.problem.Problem) tuple[list[shapely.strtree.STRtree], ConnectivityGraph, set[tuple[int, int]]][source]

Run the geometric-connectivity pre-pass.

Builds an STRtree per layer, derives the connectivity graph that links layer geometries via lumped-element networks, and flattens the connected set into the (layer_i, geom_i) pairs reachable from a driven network.

Returns (strtrees, connectivity_graph, connected_layer_mesh_pairs).

padne.solver.generate_meshes_for_problem(prob: padne.problem.Problem, mesher: padne.mesh.Mesher, connected_layer_mesh_pairs: set[tuple[int, int]], strtrees: list[shapely.strtree.STRtree]) tuple[list[padne.mesh.Mesh], list[int]][source]
padne.solver.generate_disconnected_meshes(prob: padne.problem.Problem, connected_layer_mesh_pairs: set[tuple[int, int]]) list[list[padne.mesh.Mesh]][source]

Generate simple triangulations for disconnected copper regions.

Args:

prob: The Problem containing layers and geometry connected_layer_mesh_pairs: Set of (layer_i, geom_i) pairs that are electrically connected

Returns:

List of disconnected meshes per layer: disconnected_meshes_by_layer[layer_i] = [mesh1, mesh2, …]

class padne.solver.NodeIndexer[source]
node_to_global_index: dict[padne.problem.NodeID, int][source]
extra_source_to_global_index: dict[padne.problem.BaseLumped, int][source]
internal_node_count: int = 0[source]
classmethod create(prob: padne.problem.Problem, meshes: list[padne.mesh.Mesh], mesh_index_to_layer_index: list[int], vindex: VertexIndexer, filtered_networks: list[padne.problem.Network]) NodeIndexer[source]
padne.solver.stamp_network_into_system(network: padne.problem.Network, node_indexer: NodeIndexer, L: scipy.sparse.lil_matrix, r: numpy.ndarray) None[source]
padne.solver.setup_ground_node(i_gnd: int, L: scipy.sparse.lil_matrix, r: numpy.ndarray) None[source]
padne.solver.process_mesh_laplace_operators(meshes: list[padne.mesh.Mesh], conductances: list[float], vindex: VertexIndexer, L: scipy.sparse.lil_matrix) None[source]
padne.solver.produce_layer_solutions(layers: list[padne.problem.Layer], vindex: VertexIndexer, meshes: list[padne.mesh.Mesh], mesh_index_to_layer_index: list[int], v: numpy.ndarray, disconnected_meshes_by_layer: list[list[padne.mesh.Mesh]]) list[LayerSolution][source]
padne.solver.network_has_a_dead_terminal(network: padne.problem.Network, prob: padne.problem.Problem, connected_layer_mesh_pairs: set[tuple[int, int]], strtrees: list[shapely.strtree.STRtree]) bool[source]

Check if a network has any connection on a dead (disconnected) copper region.

padne.solver.filter_dead_networks(prob: padne.problem.Problem, strtrees: list[shapely.strtree.STRtree], connected_layer_mesh_pairs: set[tuple[int, int]]) list[padne.problem.Network][source]

Drop networks whose connections all lie on disconnected copper.

A network with at least one connection on dead copper would contribute rows that cannot be solved meaningfully, so it is excluded from the system. See network_has_a_dead_terminal for the per-network check.

padne.solver.find_best_ground_node_index(prob: padne.problem.Problem, node_indexer: NodeIndexer) int[source]
padne.solver.compute_triangle_gradient(vertices: list[padne.mesh.Vertex], values: list[float]) padne.mesh.Vector[source]

Compute the gradient of a function that is a linear interpolation of the values at the vertices of a triangle.

padne.solver.compute_power_density(voltage: padne.mesh.ZeroForm, conductivity: float) padne.mesh.TwoForm[source]

Compute the power density at the mesh faces.

padne.solver.allocate_system(vindex: VertexIndexer, node_indexer: NodeIndexer) tuple[scipy.sparse.lil_matrix, numpy.ndarray][source]

Allocate the global system matrix L and right-hand side vector r.

The size accounts for mesh vertices, internal network nodes, extra variables for voltage sources/regulators, plus one ground-node row.

padne.solver.solve_system(L: scipy.sparse.lil_matrix, r: numpy.ndarray) tuple[numpy.ndarray, SolverInfo][source]

Solve L * v = r and return the solution vector together with diagnostics.

padne.solver.assemble_system(prob: padne.problem.Problem, meshes: list[padne.mesh.Mesh], mesh_index_to_layer_index: list[int], vindex: VertexIndexer, filtered_networks: list[padne.problem.Network], node_indexer: NodeIndexer) tuple[scipy.sparse.lil_matrix, numpy.ndarray][source]

Allocate (L, r) and stamp the mesh Laplacians, all networks, and the ground node. Returns the system ready to be passed to solve_system.

padne.solver.solve(prob: padne.problem.Problem, mesher_config: padne.mesh.Mesher.Config | None = None) Solution[source]

Solve the given PCB problem to find voltage and current distribution.

Args:

problem: The Problem object containing layers and lumped elements mesher_config: Configuration for mesh generation, uses defaults if None

Returns:

A Solution object with the computed results