padne.solver ============ .. py:module:: padne.solver Attributes ---------- .. autoapisummary:: padne.solver.log padne.solver.DTYPE Exceptions ---------- .. autoapisummary:: padne.solver.SolverWarning Classes ------- .. autoapisummary:: padne.solver.SolverInfo padne.solver.LayerSolution padne.solver.Solution padne.solver.ConnectivityGraph padne.solver.VertexIndexer padne.solver.NodeIndexer Functions --------- .. autoapisummary:: padne.solver.construct_strtrees_from_layers padne.solver.collect_seed_points padne.solver.laplace_operator padne.solver.find_connected_layer_geom_indices padne.solver.compute_connectivity padne.solver.generate_meshes_for_problem padne.solver.generate_disconnected_meshes padne.solver.stamp_network_into_system padne.solver.setup_ground_node padne.solver.process_mesh_laplace_operators padne.solver.produce_layer_solutions padne.solver.network_has_a_dead_terminal padne.solver.filter_dead_networks padne.solver.find_best_ground_node_index padne.solver.compute_triangle_gradient padne.solver.compute_power_density padne.solver.allocate_system padne.solver.solve_system padne.solver.assemble_system padne.solver.solve Module Contents --------------- .. py:data:: log .. py:data:: DTYPE .. py:exception:: SolverWarning Bases: :py:obj:`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. .. py:class:: SolverInfo Diagnostic information from the solver. .. py:attribute:: ground_node_current :type: float .. py:attribute:: residual_norm :type: float .. py:class:: LayerSolution .. py:attribute:: meshes :type: list[padne.mesh.Mesh] .. py:attribute:: potentials :type: list[padne.mesh.ZeroForm] .. py:attribute:: power_densities :type: list[padne.mesh.TwoForm] :value: [] .. py:attribute:: disconnected_meshes :type: list[padne.mesh.Mesh] :value: [] .. py:class:: Solution .. py:attribute:: problem :type: Solution.problem .. py:attribute:: layer_solutions :type: list[LayerSolution] .. py:attribute:: solver_info :type: SolverInfo .. py:function:: construct_strtrees_from_layers(layers: list[padne.problem.Layer]) -> list[shapely.strtree.STRtree] 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 .. py:class:: ConnectivityGraph .. py:attribute:: nodes :type: list[ConnectivityGraph.Node] :value: [] .. py:class:: Node .. py:attribute:: layer_i :type: int .. py:attribute:: geom_i :type: int .. py:attribute:: is_root :type: bool :value: False .. py:attribute:: neighbors :type: set[ConnectivityGraph] .. py:method:: create_from_problem(problem: ConnectivityGraph.create_from_problem.problem, strtrees: list[shapely.strtree.STRtree]) -> ConnectivityGraph :classmethod: .. py:method:: compute_connected_nodes() -> list[Node] Return a list of all nodes that are either root nodes themselves or are connected to a root node via any connection. .. py:function:: collect_seed_points(problem: collect_seed_points.problem, layer: collect_seed_points.problem) -> list[padne.mesh.Point] 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 .. py:function:: laplace_operator(mesh: laplace_operator.mesh) -> scipy.sparse.coo_matrix 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. .. py:class:: VertexIndexer .. py:attribute:: global_index_to_vertex_index :type: list[tuple[int, int]] :value: [] .. py:attribute:: mesh_vertex_index_to_global_index :type: dict[tuple[int, int], int] .. py:method:: create(meshes: list[padne.mesh.Mesh]) -> VertexIndexer :classmethod: .. py:function:: find_connected_layer_geom_indices(connectivity_graph: ConnectivityGraph) -> set[tuple[int, int]] .. py:function:: compute_connectivity(prob: padne.problem.Problem) -> tuple[list[shapely.strtree.STRtree], ConnectivityGraph, set[tuple[int, int]]] 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). .. py:function:: 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]] .. py:function:: generate_disconnected_meshes(prob: padne.problem.Problem, connected_layer_mesh_pairs: set[tuple[int, int]]) -> list[list[padne.mesh.Mesh]] 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, ...] .. py:class:: NodeIndexer .. py:attribute:: node_to_global_index :type: dict[padne.problem.NodeID, int] .. py:attribute:: extra_source_to_global_index :type: dict[padne.problem.BaseLumped, int] .. py:attribute:: internal_node_count :type: int :value: 0 .. py:method:: 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 :classmethod: .. py:function:: stamp_network_into_system(network: padne.problem.Network, node_indexer: NodeIndexer, L: scipy.sparse.lil_matrix, r: numpy.ndarray) -> None .. py:function:: setup_ground_node(i_gnd: int, L: scipy.sparse.lil_matrix, r: numpy.ndarray) -> None .. py:function:: process_mesh_laplace_operators(meshes: list[padne.mesh.Mesh], conductances: list[float], vindex: VertexIndexer, L: scipy.sparse.lil_matrix) -> None .. py:function:: 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] .. py:function:: 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 Check if a network has any connection on a dead (disconnected) copper region. .. py:function:: filter_dead_networks(prob: padne.problem.Problem, strtrees: list[shapely.strtree.STRtree], connected_layer_mesh_pairs: set[tuple[int, int]]) -> list[padne.problem.Network] 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. .. py:function:: find_best_ground_node_index(prob: padne.problem.Problem, node_indexer: NodeIndexer) -> int .. py:function:: compute_triangle_gradient(vertices: list[padne.mesh.Vertex], values: list[float]) -> padne.mesh.Vector Compute the gradient of a function that is a linear interpolation of the values at the vertices of a triangle. .. py:function:: compute_power_density(voltage: padne.mesh.ZeroForm, conductivity: float) -> padne.mesh.TwoForm Compute the power density at the mesh faces. .. py:function:: allocate_system(vindex: VertexIndexer, node_indexer: NodeIndexer) -> tuple[scipy.sparse.lil_matrix, numpy.ndarray] 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. .. py:function:: solve_system(L: scipy.sparse.lil_matrix, r: numpy.ndarray) -> tuple[numpy.ndarray, SolverInfo] Solve L * v = r and return the solution vector together with diagnostics. .. py:function:: 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] Allocate (L, r) and stamp the mesh Laplacians, all networks, and the ground node. Returns the system ready to be passed to `solve_system`. .. py:function:: solve(prob: padne.problem.Problem, mesher_config: Optional[padne.mesh.Mesher.Config] = None) -> Solution 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