optiwindnet.converting ====================== .. py:module:: optiwindnet.converting .. autoapi-nested-parse:: Conversions that cross graph kinds. Every function here takes one kind and returns another: a site to a location graph ``L``, ``L`` and ``A`` to a topology ``S``, ``S`` to a routeset ``G``, and ``S`` to or from its bit and terse encodings. For a variant of the same kind, see :mod:`optiwindnet.transforming`. Module Contents --------------- .. py:function:: linkbits_from_S(A: networkx.Graph, S: networkx.Graph) -> bitarray.frozenbitarray Encode topology ``S`` over ``A``'s canonical undirected available-links set. Terminal-terminal positions follow the lexicographic edge order cached by :func:`~optiwindnet.mesh.make_planar_embedding`. The ``R * T`` feeder positions follow in terminal-major order, with roots from ``-R`` to ``-1``. ``A`` must provide its ``'_canonical_terminal_links'`` graph attribute. ``S`` must be an undetoured topology containing only terminals and roots. .. py:function:: S_from_linkbits(linkbits: bitarray.bitarray, A: networkx.Graph) -> networkx.Graph Decode canonical ``linkbits`` into an undetoured topology ``S``. Uses the same terminal-link and feeder ordering as :func:`linkbits_from_S`. ``A`` must provide its ``'_canonical_terminal_links'`` graph attribute. The bit count must match ``A``'s available-links set; a mismatch raises ``ValueError``. Equal bit counts are not proof of a common origin: compare ``A``'s ``'_linkset_id'`` with the producer's to confirm that the bits and the graph describe the same available-links set. The result contains all ``T`` terminals and ``R`` roots, including isolated nodes, without node attributes. Only connectivity is recovered: loads, capacity, topology type and other solution metadata are not encoded. No feasibility validation or load calculation is performed. .. py:function:: L_from_site(*, VertexC: numpy.ndarray, T: int, R: int, B: int = 0, border: numpy.ndarray | None = None, obstacles: list[numpy.ndarray] | None = None, name: str = '', handle: str = 'L_from_site', landscape_angle: float | None = None) -> networkx.Graph Create L from a location's attributes. :param VertexC: numpy.ndarray (V, 2) with all (x, y) coordinates (V = R + T + B) :param T: int number of wtg :param R: int number of oss :param B: number of border and obstacle zones' vertices :param border: array (B,) of VertexC indices that define the border (ccw) :param obstacles: sequence of numpy.ndarray of VertexC indices :param name: site name :param handle: site identifier :returns: Graph containing ``N = R + T`` nodes and no edges (all args become graph attributes). .. py:function:: G_from_S(S: networkx.Graph, A: networkx.Graph) -> networkx.Graph Create G from S and A. Graph ``S`` contains the topology of a routeset network (nodes only, no contours or detours). ``S`` must have been created from the available links in ``A``, whose contour information is used to obtain a routeset ``G`` (possibly with contours, but not with detours – use PathFinder afterward). .. py:function:: S_from_G(G: networkx.Graph) -> networkx.Graph Get ``G``'s topology (contours, detours, lengths and coords are dropped). Terminal ``'inflow'`` attributes are preserved so that recalculating loads on ``S`` uses the same terminal contributions as on ``G``, as are the graph attributes that record the quantization of the solve (``'power_per_inflow'``, ``'capacity_nominal'`` and ``'power_rtol'``). Declared nominal power belongs to the site and routed graphs, not the topology. If using ``S`` to warm-start a MILP model, call after :func:`S_from_G`: - :func:`as_hooked_to_nearest` for ``Topology.BRANCHED``; - :func:`as_hooked_to_head` for ``Topology.RADIAL``. This makes a radial ``S`` feasible and avoids a trivially suboptimal branched ``S``. For RINGED routesets, cycle-closing links are retained, so ``S`` preserves the ring partition of ``G``. :param G: feasible routed solution with a tree, path or ring topology. :returns: Topology of ``G``. :raises ValueError: a routed link does not form a chain between two real nodes. .. py:function:: L_from_G(G: networkx.Graph) -> networkx.Graph Return new location with nodes and site attributes from G. The returned location graph ``L`` retains only roots, nodes and basic graph attributes. All edges and remaining attributes are not carried from ``G``. Of the turbine power, only the declaration is kept (terminal ``'power'`` under ``'powers_set'``, otherwise ``'power_per_inflow'`` and the inflow other than one), not the quantization of the solve. :param G: routeset graph to extract site data from. :returns: Site graph (no edges) with lean attributes. .. py:function:: S_from_terse_links(terse_links, R=None, T=None, topology=None, **kwargs) Create topology ``S`` from a self-describing or legacy encoding. .. py:function:: terse_links_from_S(S) Return the self-describing compact representation of topology ``S``.