B
    ]t\>7                 @   sD   d Z ddlZddlmZ ddlZG dd deZG dd deZ	dS )z'
Mesh refinement for triangular grids.
    N)Triangulationc               @   s   e Zd ZdZdd ZdS )
TriRefinera  
    Abstract base class for classes implementing mesh refinement.

    A TriRefiner encapsulates a Triangulation object and provides tools for
    mesh refinement and interpolation.

    Derived classes must implements:

        - ``refine_triangulation(return_tri_index=False, **kwargs)`` , where
          the optional keyword arguments *kwargs* are defined in each
          TriRefiner concrete implementation, and which returns :

              - a refined triangulation
              - optionally (depending on *return_tri_index*), for each
                point of the refined triangulation: the index of
                the initial triangulation triangle to which it belongs.

        - ``refine_field(z, triinterpolator=None, **kwargs)`` , where:

              - *z* array of field values (to refine) defined at the base
                triangulation nodes
              - *triinterpolator* is a
                :class:`~matplotlib.tri.TriInterpolator` (optional)
              - the other optional keyword arguments *kwargs* are defined in
                each TriRefiner concrete implementation

          and which returns (as a tuple) a refined triangular mesh and the
          interpolated values of the field at the refined triangulation nodes.

    c             C   s   t |tstd|| _d S )NzExpected a Triangulation object)
isinstancer   
ValueError_triangulation)selftriangulation r	   7lib/python3.7/site-packages/matplotlib/tri/trirefine.py__init__)   s    
zTriRefiner.__init__N)__name__
__module____qualname____doc__r   r	   r	   r	   r
   r   
   s   r   c               @   s:   e Zd ZdZdd ZdddZdd	d
ZedddZdS )UniformTriRefinerz
    Uniform mesh refinement by recursive subdivisions.

    Parameters
    ----------
    triangulation : :class:`~matplotlib.tri.Triangulation`
                     The encapsulated triangulation (to be refined)
    c             C   s   t | | d S )N)r   r   )r   r   r	   r	   r
   r   =   s    zUniformTriRefiner.__init__F   c             C   s  | j }|jjd }tj|tjd}x t|D ]}| ||\}}q,W |jjd }|j}|rtj	|tjd }	| j j
}
|
dkrt|ddd|	|< n\|
| }t|| ddd|	||ddf < t||  ddd|	|| ddf < ||	fS |S dS )ao  
        Computes an uniformly refined triangulation *refi_triangulation* of
        the encapsulated :attr:`triangulation`.

        This function refines the encapsulated triangulation by splitting each
        father triangle into 4 child sub-triangles built on the edges midside
        nodes, recursively (level of recursion *subdiv*).
        In the end, each triangle is hence divided into ``4**subdiv``
        child triangles.
        The default value for *subdiv* is 3 resulting in 64 refined
        subtriangles for each triangle of the initial triangulation.

        Parameters
        ----------
        return_tri_index : boolean, optional
            Boolean indicating whether an index table indicating the father
            triangle index of each point will be returned. Default value
            False.
        subdiv : integer, optional
            Recursion level for the subdivision. Defaults value 3.
            Each triangle will be divided into ``4**subdiv`` child triangles.

        Returns
        -------
        refi_triangulation : :class:`~matplotlib.tri.Triangulation`
            The returned refined triangulation
        found_index : array-like of integers
            Index of the initial triangulation containing triangle, for each
            point of *refi_triangulation*.
            Returned only if *return_tri_index* is set to True.

        r   )dtypeNr   )r   	trianglesshapenparangeint32range_refine_triangulation_oncexonesmaskrepeatZreshape)r   return_tri_indexsubdivZrefi_triangulationntri	ancestors_	refi_nptsZrefi_trianglesfound_indexZtri_maskZancestor_maskr	   r	   r
   refine_triangulation@   s*    !
 z&UniformTriRefiner.refine_triangulationNc             C   sf   |dkrt j| j|}nt|t jjs0td|}| j|dd\}}|j|j	|j
|dd }||fS )a  
        Refines a field defined on the encapsulated triangulation.

        Returns *refi_tri* (refined triangulation), *refi_z* (interpolated
        values of the field at the node of the refined triangulation).

        Parameters
        ----------
        z : 1d-array-like of length ``n_points``
            Values of the field to refine, defined at the nodes of the
            encapsulated triangulation. (``n_points`` is the number of points
            in the initial triangulation)
        triinterpolator : :class:`~matplotlib.tri.TriInterpolator`, optional
            Interpolator used for field interpolation. If not specified,
            a :class:`~matplotlib.tri.CubicTriInterpolator` will
            be used.
        subdiv : integer, optional
            Recursion level for the subdivision. Defaults to 3.
            Each triangle will be divided into ``4**subdiv`` child triangles.

        Returns
        -------
        refi_tri : :class:`~matplotlib.tri.Triangulation` object
                     The returned refined triangulation
        refi_z : 1d array of length: *refi_tri* node count.
                   The returned interpolated field (at *refi_tri* nodes)
        Nz!Expected a TriInterpolator objectT)r    r   )Z	tri_indexr   )
matplotlibZtriZCubicTriInterpolatorr   r   ZTriInterpolatorr   r&   Z_interpolate_multikeysr   y)r   zZtriinterpolatorr    ZinterpZrefi_trir%   Zrefi_zr	   r	   r
   refine_field   s    
zUniformTriRefiner.refine_fieldc       $   
   C   s>  | j }| j}| j}| j}t|d }t|d }|dk	rrt|}t||fkrrtdt|t|t	|dk}d| | d }	||	 }
t
|
}t
|
}||d|< ||d|< tttj|tjdtj|tjdtj|tjdg}tttj
|tjdtj|tjdtj|tjdd g}|||f }||k}|| }|| }||||f  ||||d d f   d	 }||||f  ||||d d f   d	 }|||d< |||d< |}tj|dgtjd}|}xXtdD ]L}||k}t	|}|| }tj|tjd| |dd|f |< ||7 }qW t|}|| }|| }t||ddf t|tjdtjd }tj|dd
} || }!||| f |||!f< tj|d dgtjd}"t|dddf |dddf |dddf gj|"dddddf< t|dddf |dddf |dddf gj|"dddddf< t|dddf |dddf |dddf gj|"dddddf< t|dddf |dddf |dddf gj|"dddddf< t|||"}#| jdk	r|#t| jd |dkr*|#S |#t|dfS dS )a  
        This function refines a matplotlib.tri *triangulation* by splitting
        each triangle into 4 child-masked_triangles built on the edges midside
        nodes.
        The masked triangles, if present, are also split but their children
        returned masked.

        If *ancestors* is not provided, returns only a new triangulation:
        child_triangulation.

        If the array-like key table *ancestor* is given, it shall be of shape
        (ntri,) where ntri is the number of *triangulation* masked_triangles.
        In this case, the function returns
        (child_triangulation, child_ancestors)
        child_ancestors is defined so that the 4 child masked_triangles share
        the same index as their father: child_ancestors.shape = (4 * ntri,).

        r   NzYIncompatible shapes provide for triangulation.masked_triangles and ancestors: {0} and {1}r   r      )r      g      ?)Zaxis   )r   r(   	neighborsr   r   r   Zasarrayr   formatsumZzerosZravelZvstackr   r   r   emptyr   Zlogical_notabsZouterZargminTr   r   Zset_maskr   )$r   r"   r   r(   r.   r   Znptsr!   ZbordersZ	added_ptsr$   Zrefi_xZrefi_yZ
edge_elemsZedge_apexesZedge_neighborsZmask_mastersZmastersZapex_mastersZx_addZy_addZnew_pt_cornerZnew_pt_midsideZcum_sumZimidZmask_st_locZn_masters_locZelem_masters_locZmask_slavesZslavesZslaves_mastersZ
diff_tableZslave_masters_apexZslaves_apexZchild_trianglesZchild_triangulationr	   r	   r
   r      s    



 
((((
z,UniformTriRefiner._refine_triangulation_once)Fr   )Nr   )N)	r   r   r   r   r   r&   r*   staticmethodr   r	   r	   r	   r
   r   /   s   
H
+r   )
r   Znumpyr   Zmatplotlib.tri.triangulationr   Zmatplotlib.tri.triinterpolater'   objectr   r   r	   r	   r	   r
   <module>   s
   %