====================================
Meshes in ScotchPy
====================================

Graphs are implemented in ScotchPy with the Mesh class.

The Mesh class
###############



.. class:: Mesh(init=True)

    The mesh constructor itself calls libscotch's ``meshAlloc`` function, and
    usually ``meshInit`` is called too.

    :param init:
        If True, the mesh allocation is followed by the init.
        If not, the :meth:`~Mesh.init` method needs to be called before
        :meth:`~Mesh.build` or :meth:`~Mesh.load`.

    The mesh object stores the arguments given to the :meth:`~Mesh.build`
    method as integers and numpy arrays. They are accessible even when the mesh
    has been constructed with :meth:`~Mesh.load`. They default to None if the
    argument was not given.

    |

    .. method:: init()

        This routine Initializes the fields of the Mesh object instance.
        Called by a class constructor when ``init=True`` (by default).
        Mandatory before calling either :meth:`~Mesh.build` or :meth:`~Mesh.load`, or after calling :meth:`~Mesh.exit` in order to re-use the same Mesh instance.

    |

    .. method:: exit()

        This routine cleans-up all fields of the instance. Is the opposite of the :meth:`~Mesh.init` routine.
        Called automatically when the object is destroyed.
        Calling explicitly this method is only required when an :meth:`~Mesh.init` call follows.

    |


    .. method:: build(velmbas = None, vnodbas = None, velmnbr = None, vnodnbr = None, verttab = None, vendtab = None, velotab = None, vnlotab = None, vlbltab = None, edgenbr = None, edgetab = None)

        This routine builds the mesh itself using the given values.
        Arguments should be given as ints and ideally numpy arrays of ints, although any iterable would work.
        Mutating these arrays is not recommended as it may cause runtime errors
        while Scotch handles them.

        Some arguments may be omitted, but :
            - ``velmbas`` and ``vnodbas`` must be given .
            - if ``vnlotab`` has no size, ``velmbas``, ``velmnbr`` and
                ``edgenbr`` must be given.

        :param velmbas: Base value for mesh vertex indices.
        :type velmbas: Integer
        :param vnodbas: Base value for mesh node indices.
        :type vnodbas: Integer
        :param velmnbr: Number of mesh vertices.
        :type velmnbr: Integer
        :param vnodnbr: Number of mesh nodes.
        :type vnodnbr: Integer
        :param verttab: Adjacency index array (**Required**).
        :type verttab: Any iterable of integers ideally numpy array
        :param vendtab: Adjacency end index array of size vertnbr if disjoint from verttab (**Optional**).
        :type vendtab: Any iterable of integers ideally numpy array
        :param velotab: Vertex load array of size vertnbr (**Optional**).
        :type velotab: Any iterable of integers ideally numpy array
        :param vlbltab: Vertex label array of size vertnbr (**Optional**).
        :type vlbltab: Any iterable of integers ideally numpy array
        :param edgenbr: Number of arcs (*which is twice the number of edges*).
        :type edgenbr: Integer
        :param edgetab: Adjacency array of size edgenbr (*more if not compact*) (**Required**).
        :type edgetab: Any iterable of integers ideally numpy array
        :param edlotab: Arc load array of size edgenbr (**Optional**).
        :type edlotab: Any iterable of integers ideally numpy array



    |

    .. method:: load(stream, baseval=-1)

        This routine builds the mesh with :meth:`~Mesh.build` from data included in the given file or stream.

        :param stream: Input file or stream to read from.
        :type stream: Either a file object (result of an ``open()``, don't forget to close
            it) or a filename, as a string or as a bytes object (such as
            ``b"file/name"``)

        :param baseval: The mesh base value for index arrays(0 or 1),
                        takes the baseval value from the ``stream`` data if -1.
        :type baseval: Integer

    |

    **The following routines can't be called before the mesh is properly built either with
    :meth:`~Mesh.build` or with :meth:`~Mesh.load`:**

    |


    .. method:: save(stream)

        This routine saves the mesh to the given file or stream in the Scotch mesh format.

        :param stream: input file or stream to read from.
        :type stream: Either a file object (result of an ``open()``, don't forget to close
                      it) or a filename, as a string or as a bytes object (such as
                      ``b"file/name"``)

    |

    .. method:: check()

        Runs a self-test to check data consistency after the
        :meth:`~Mesh.build` or :meth:`~Mesh.load` method is called, raises a :class:`LibraryError` if not.

    |

    .. method:: data(as_dict=None)

        This routine returns the values taken by the :meth:`~Mesh.build` method. The arrays
        are returned as numpy arrays.

        :param as_dict:
            If True, the requested data is returned as a dict.
            If not, it is returned as a 13-element tuple.
        :type as_dict: Boolean
        :returns: Values in this order: (``velmbas``, ``vnodbas``, ``velmnbr``, ``vnodnbr``,
            ``verttab``, ``vendtab``, ``velotab``, ``vnlotab``, ``vlbltab``, ``edgenbr``,
            ``edgetab``, ``edlotab``, ``degrnbr``). (**Not sure about the last one**)
        :rtype: Tuple or Dict

    |

    .. method:: size(as_dict=None)

        This routine returns the values of ``velmnbr``, ``vnodnbr`` and ``edgenbr`` taken by the :meth:`~Mesh.build` method.

        :param as_dict:
            If True, the requested data is returned as a dict.
            If not, it is returned as a 3-element tuple.
        :type as_dict: Boolean
        :returns: The values of ``velmnbr``, ``vnodnbr`` and ``edgenbr``.
        :rtype: Tuple or Dict

    |

    .. method:: graph(graf)

        This routine builds a graph from the mesh itself.

        :param graf: Graph to be built.
        :type graf: :class:`Graph`


    |

    .. method:: graph_dual(graf, ncomval)

        This routine builds the dual graph of the mesh itself.

        :param graf: Graph to be built.
        :type graf: :class:`Graph`
        :param ncomval: Number of components in the mesh.
        :type ncomval: Integer

    |

    .. method:: stat(as_dict=None)

        This routine gives various stats about the mesh:

        - ``vnlomin``, ``vnlomax``, ``vnlosum``, ``vnloavg``, ``vnloadl`` are the minimum node vertex load, the maximum node vertex load, the sum of all node vertex loads, the average node vertex load and the variance of the node vertex degrees, respectively.

        - ``edegmin``, ``edegmax``, ``edegavg``, ``edegdlt`` are the minimum element vertex degree, the maximum element vertex degree, the average element vertex degree and the variance of the element vertex degrees, respectively.

        - ``ndegmin``, ``ndegmax``, ``ndegavg``, ``ndegdlt`` are the minimum node vertex degree, the maximum node vertex degree, the average node vertex degree and the variance of the node vertex degrees, respectively.

        :param as_dict:
            If True, the requested data is returned as a dict.
            If not, it is returned as a 13-element tuple.
        :type as_dict: Boolean
        :returns: various stats about the mesh, in this specific order :(``vnlomin``, ``vnlomax``, ``vnlosum``, ``vnloavg``, ``vnloadl``,
         ``edegmin``, ``edegmax``, ``edegavg``, ``edegdlt``, ``ndegmin``, ``ndegmax``, ``ndegavg``, ``ndegdlt``).
        :rtype: Tuple or Dict

    |

    .. method:: order(strat=Strat(init=True), permtab=None, peritab=None, cblknbr=None, rangtab=None, treetab=None)

        This routine computes a block ordering of the unknowns of the symmetric sparse matrix
        the adjacency structure, which is represented by the mesh itself.


    :param strat: Strategy to be used for the ordering.
    :type strat: :class:`Strat`
    :param permtab: Array holding the permutation of the reordered matrix. If given, the values of the returned array are copied in this one. (**Optional**)
    :type permtab: Any kind of iterable or a numpy array
    :param peritab: Inverse permutation of the reordered matrix. If given, the values of the returned array are copied in this one. (**Optional**)
    :type peritab: Any kind of iterable or a numpy array
    :param cblknbr: Number of column blocks in the block ordering. If given, the value is copied in this one. (**Optional**)
    :type cblknbr: integer
    :param rangtab: Array of ranges for the column blocks. If given, the values of the returned array are copied in this one. (**Optional**)
    :type rangtab: Any kind of iterable or a numpy array
    :param treetab: Array of ascendants of permuted column blocks in the separators tree. If given, the values of the returned array are copied in this one. (**Optional**)
    :type treetab: Any kind of iterable or a numpy array



    |

    .. method:: order_init(ordering, permtab=None, peritab=None, cblknbr=None, rangtab=None, treetab=None)

        This routine initializes an ordering structure with respect to the mesh itself.
        If called using :class:`Ordering`'s constructor however, nothing is returned.

    :param ordering: Ordering to be initialized.
    :type ordering: :class:`Ordering`
    :param permtab: Array holding the permutation of the reordered matrix. If given, the values of the returned array are copied in this one. (**Optional**)
    :type permtab: Any kind of iterable or a numpy array
    :param peritab: Inverse permutation of the reordered matrix. If given, the values of the returned array are copied in this one. (**Optional**)
    :type peritab: Any kind of iterable or a numpy array
    :param cblknbr: Number of column blocks in the block ordering. If given, the value is copied in this one. (**Optional**)
    :type cblknbr: Integer
    :param rangtab: Array of ranges for the column blocks. If given, the values of the returned array are copied in this one. (**Optional**)
    :type rangtab: Any kind of iterable or a numpy array
    :param treetab: Array of ascendants of permuted column blocks in the separators tree. If given, the values of the returned array are copied in this one. (**Optional**)
    :type treetab: Any kind of iterable or a numpy array


    |

    .. method:: order_exit(ordering)

        This routine frees an ordering instance.

    :param ordering: Ordering to be freed.
    :type ordering: :class:`Ordering`

    |

    .. method:: order_check(ordering)

        This routine checks the consistency of the ordering instance.

    :param ordering: Ordering to be checked.
    :type ordering: :class:`Ordering`

    |

    .. method:: order_compute(ordering, strat)

        This routine computes a block ordering of the mesh itself with respect to the given strategy ``strat``. Stores the result in the given ordering instance ``ordering``.

    :param ordering: Ordering to be computed.
    :type ordering: :class:`Ordering`
    :param strat: Strategy to be used for the ordering.
    :type strat: :class:`Strat`

    |

    .. method:: order_save(ordering, stream)

        This routine saves the contents of the given ordering instance ``ordering`` to the given stream ``stream``.

    :param ordering: Ordering to be saved.
    :type ordering: :class:`Ordering`
    :param stream: Input file or stream to write to.
    :type stream: Either a file object (result of an ``open()``, don't forget to close
                  it) or a filename, as a string or as a bytes object (such as
                  ``b"file/name"``)

    |

    .. method:: order_save_map(ordering, stream)

        This routine saves the contents of the given ordering instance ``ordering`` to the given stream ``stream`` in the Scotch mapping format.

    :param ordering: Ordering to be saved.
    :type ordering: :class:`Ordering`
    :param stream: Input file or stream to write to.
    :type stream: Either a file object (result of an ``open()``, don't forget to close
                  it) or a filename, as a string or as a bytes object (such as
                  ``b"file/name"``)

    |

    .. method:: order_save_tree(ordering, stream)

        This routine saves the contents of the given ordering instance ``ordering`` to the given stream ``stream`` in the tree output format format.

    :param ordering: Ordering to be saved.
    :type ordering: :class:`Ordering`
    :param stream: Input file or stream to write to.
    :type stream: Either a file object (result of an ``open()``, don't forget to close
                  it) or a filename, as a string or as a bytes object (such as
                  ``b"file/name"``)

    |

.. function:: mesh_alloc()

    Recreates the ``meshAlloc`` function, returning a non-initialized
    :class:`Mesh` instance. It will need the :meth:`~Mesh.init` method to be
    called before the instance be built or loaded upon.

    |

.. function:: build_mesh(*args, **kwargs)

    Returns a properly built mesh instance. Positional and keyword arguments
    need to be given in the same fashion as :meth:`Mesh.build` takes them.

    |
.. function:: load_mesh(*args, **kwargs)

    Returns a mesh instance loaded from the given file or stream. Positional
    arguments need to be given in the same fashion as :meth:`Mesh.load` takes
    them.
