
    _-Phcp                         d Z ddlZddlmZ d ZddZd ZddZd	 Z	 G d
 d          Z
d ZddZd Zd Zd ZddZdS )z%Poisson problem with finite elements.    N)sparsec                    t          j        | |dddf         df         | |dddf         df         z
  | |dddf         df         | |dddf         df         z
  t          j        |j        d                   f          j        }t          j        | |dddf         df         | |dddf         df         z
  | |dddf         df         | |dddf         df         z
  t          j        |j        d                   f          j        }t          j        t          j        ||          dddf         dk              }|S )z6Check the ccw orientation of each simplex in the mesh.N   r      )npvstackzerosshapeTallcross)VEE01E12orientations        Q/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/pyamg/gallery/fem.py
check_meshr      sU   
)QqAwz]QqAwz]2qAwz]QqAwz]2Xagaj))+ , ,,-  )QqAwz]QqAwz]2qAwz]QqAwz]2Xagaj))+ , ,,-  &#s++AAAqD1A566K    Fc                 (   t          | t          j                  rt          |t          j                  st          d          | j        d         dk    s|j        d         dk    rt          d          |j        d         }t          j        t          j        d|          t          j        dt                              }t          j
        t          j        |dz  ft                    |                                |ff          }||j        z  }t          j        |d	          }t          j        |j        |j        f          j        }| |d
d
df         d
d
f         | |d
d
df         d
d
f         z   dz  }	t          j        | |	f          } |                                dz   }
|
t          j        |j        d                   z   }||_        ||j        z   }t          j        |t          j        |j        d         dft                    f          }||d
d
df         |d
d
df         f         |d
d
df<   ||d
d
df         |d
d
df         f         |d
d
df<   ||d
d
df         |d
d
df         f         |d
d
df<   |r| ||fS | |fS )aw  Generate a quadratic element list by adding midpoints to each edge.

    Parameters
    ----------
    V : ndarray
        nv x 2 list of coordinates

    E : ndarray
        ne x 3 list of vertices

    return_edges : bool
        indicate whether list of the refined edges is returned

    Returns
    -------
    V2 : ndarray
        nv2 x 2 list of coordinates

    E2 : ndarray
        ne2 x 6 list of vertices

    Edges : ndarray
        nedge x 2 list of edges where the midpoint is generated

    Notes
    -----
        - midpoints are introduced and globally numbered at the end of the vertex list
        - the element list includes the new list between v0-v1, v1-v2, and v2-v0

    Examples
    --------
    >>> import numpy as np
    >>> from pyamg.gallery import fem
    >>> V = np.array([[0.,0.], [1.,0.], [0.,1.], [1.,1.]])
    >>> E = np.array([[0,1,2], [2,3,1]])
    >>> V2, E2 = fem.generate_quadratic(V, E)
    >>> print(V2)
    [[0.  0. ]
     [1.  0. ]
     [0.  1. ]
     [1.  1. ]
     [0.5 0. ]
     [0.5 0.5]
     [0.  0.5]
     [0.5 1. ]
     [1.  0.5]]
    >>> print(E2)
    [[0 1 2 4 5 6]
     [2 3 1 7 8 5]]
    V and E must be ndarrayr   r      )V should be nv x 2 and E should be ne x 3r   r   dtypeN       @      )
isinstancer   ndarray
ValueErrorr
   kronarangeonesintr   
coo_matrixravelr   trilr   rowcolmaxdatahstackr	   )r   r   return_edgesneIDGV2VV2VmidEdgesVmidmaxindexnewIDs               r   generate_quadraticr:      s   f a$$ 4Jq"*,E,E 42333wqzQ!'!*//DEEE	
B 
1b!!274s#;#;#;	<	<B27BqD7#666B8HIJJA
ac'C [b!!FIvz6:.//1EeAAAqDk111n%1+qqq. 11S8D
	1d)A uuww{HryQ000EFKfhF 		1bh
Ac:::;<<AQqqq!tWa1g%&AaaadGQqqq!tWa1g%&AaaadGQqqq!tWa1g%&AaaadG !U{a4Kr   c           	         t          | t          j                  rt          |t          j                  st          d          | j        d         dk    s|j        d         dk    rt          d          d}g d}|D ]}t          j        t          j        | ||         df                   dz  t          j        | ||         df                   dz  z             }t          ||                                          }|S )a	  Compute the diameter of a mesh.

    Parameters
    ----------
    V : ndarray
        nv x 2 list of coordinates

    E : ndarray
        ne x 3 list of vertices

    Returns
    -------
    h : float
        maximum diameter of a circumcircle over all elements
        longest edge

    Examples
    --------
    >>> import numpy as np
    >>> dx = 1
    >>> V = np.array([[0,0], [dx,0], [0,dx], [dx,dx]])
    >>> E = np.array([[0,1,2], [2,3,1]])
    >>> h = diameter(V, E)
    >>> print(h)
    1.4142135623730951

    r   r   r   r   r   r   )r   r   r   r   )r!   r   r"   r#   r
   sqrtdiffr-   )r   r   hIehss         r   diameterrB   l   s    8 a$$ 4Jq"*,E,E 42333wqzQ!'!*//DEEE	AA  WRWQqtQwZ((!+bga!aj.A.A1.DDEE26688Hr   c                 
   |j         d         }| j         d         }|t          j        d|          }t          j        |          }|                                }t          j        t          j        d|          g d          }t          j        |dz  f          }t          j        |||ff||f          }|j        |z  }t          j        |j	        j                   |_	        t          j
        |d                                          }	t          |	j	                  }
t          j        d|
          |	_	        t          j        |	j        |	j        f          j        }|j         d         }
|	                                }	t          j        |ddddgf         |ddddgf         |ddddgf         f          }|                    d           |	|dddf         |dddf         f                             d|f          j        }t          j        |
ft(          	          }d
|||ddf                                         <   t          t          j        |dk              d                   }||                             d          }t          j        |dk              d         }d
|||ddf         <   t          t          j        |dk              d                   }t          j        |dk              d         }d| ||df         df         z  d| ||df         df         z  z   }d| ||df         df         z  d| ||df         df         z  z   }t          j        ||f          j        }t          j        | |f          } t          j        |
ft.          	          }|t          j        d|          z   ||<   t          j        |ft(          	          }d||<   d||<   t          j        ||d          }||df         }||df         }||df         }|||df                                                  }|||df                                                  }|||df                                                  }t          j        |||f          j        }t          j        |||f          j        } t          j        |||f          j        }!t          j        |||f          j        }"t          j        ||| |!|"f          }| |fS )a  Refine a triangular mesh.

    Parameters
    ----------
    V : ndarray
        nv x 2 list of coordinates

    E : ndarray
        ne x 3 list of vertices

    marked_elements : array
        list of marked elements for refinement.  None means uniform.

    Returns
    -------
    Vref : ndarray
        nv x 2 list of coordinates

    Eref : ndarray
        ne x 3 list of vertices

    Notes
    -----
        - Peforms quad-section in the following where n0, n1, and n2 are
          the original vertices

                   n2
                  / |
                /   |
              /     |
           n5-------n4
          / \      /|
        /    \    / |
      /       \  /  |
    n0 --------n3-- n1
    r   N)r   r   r   r   r
   r   r   axisr   T      ?F)r
   r   r%   r)   r$   r&   r   r(   r   r.   triutocoolenr   r+   r,   tocsrsortreshaper	   boolwheresumr'   delete)#r   r   marked_elementsNelNvr,   r+   r.   r4   V2VupperNedgesEdgeListedgesElementToEdgemarked_edgesnsplitedge_numedges3edges1x_newy_newV_newnew_ididsE_newn0n1n2n3n4n5t1t2t3t4s#                                      r   refine2dtriro      s   J '!*C	
B)As++h//O ''))C
'")As##YYY
/
/C7CE8D

TC:.sBi
@
@
@C
%#+C wsx~&&CH{3""((**H FIa((HMy(,5668H^AF ~~HIqQF|QF|QF|% & &E 
JJAJU111a4[%1+56>>3xHHJM8VIT222L>BL1288::; ,!+,,Q/00FM*..A.66HXh!m$$Q'F-1Lvqqqy)*,!+,,Q/00FXh!m$$Q'F
 8L!O,a/01
q,/*A-.
/0E8L!O,a/01
q,/*A-.
/0E Iuen%%'E
	1e*AXvis+++F 	!V 4 44F< '3&
%
%
%CCKCKIaq111E	
619B	
619B	
619B	fai(	)	/	/	1	1B	fai(	)	/	/	1	1B	fai(	)	/	/	1	1B	BB<	 	 	"B	BB<	 	 	"B	BB<	 	 	"B	BB<	 	 	"BIub"b"-..Ee8Or   c                 &   |j         dk    r|j        }|j        }n)|j         dk    r|j        }|j        }nt          d          t          | t          j                  st          d          |j	        d         dk    rt          d          |j         dk    r |j	        d         dk    rt          d          |j         dk    r |j	        d         dk    rt          d	          |j         d
vrt          d          d}t          j
        g d          }t          j
        ddgddgddgddgddgddgg          }|dddf         dz   dz  |dddf         dz   dz  }}|dz  }|j         dk    rt          j        d          }	d }
|
}n4|j         dk    rt          j        d          }	d }|}nt          d          |D ]}||df         }||df         }t          j        |d         |d         z
  |d         |d         z
  z  |d         |d         z
  |d         |d         z
  z  z
            }t          |||          D ]@\  }}}||dz  |z  t          j        | ||	                   |||                    dz  z  z  }At          j        |          S )a  Calculate the L2 norm of a function on mesh (V,E).

    Parameters
    ----------
    u : array
        (nv,) list of function values

    mesh : object
        mesh object

    Returns
    -------
    val : float
        the value of the L2 norm of u, ||u||_2,V

    Notes
    -----
        - modepy is used to generate the quadrature points
          q = modepy.XiaoGimbutasSimplexQuadrature(4,2)

    Examples
    --------
    >>> import numpy as np
    >>> from pyamg.gallery import fem
    >>> V = np.array([[0,0], [1,0], [0,1], [1,1]])
    >>> E = np.array([[0,1,2], [1,3,2]])
    >>> mesh = Mesh(V, E, degree=1)
    >>> X, Y = mesh.V[:, 0], mesh.V[:, 1]
    >>> u = X + Y
    >>> unorm = fem.l2norm(u, mesh)
    >>> print(f'{unorm:2.6}')
    1.08012
    >>> mesh = Mesh(V, E, degree=2)
    >>> X, Y = mesh.V2[:, 0], mesh.V2[:, 1]
    >>> u = X + Y
    >>> unorm = fem.l2norm(u, mesh)
    >>> print(f'{unorm:2.6}')
    1.08012
    r   r   !only mesh.degree 1 or 2 supportedzu must be ndarrayzV should be nv x 2r   zE should be nv x 3   zE should be nv x 6r   r   degree = 1 or 2 supportedr   ė?rv   rv   E#'%?rw   rw   &y緡yLy纡xēx#ԓx#'
;G?ʓx#Гx#'
;G?NrG   c                 <    t          j        d| z
  |z
  | |g          S )Nr   r   arrayxys     r   basis1zl2norm.<locals>.basis1h  s+    8QqSU  ! ! !r   c           
          t          j        d| z
  |z
  dd| z  z
  d|z  z
  z  | d| z  dz
  z  |d|z  dz
  z  d| z  d| z
  |z
  z  d| z  |z  d|z  d| z
  |z
  z  g          S )Nr   r   r   r   r   s     r   basis2zl2norm.<locals>.basis2p  s    8ac!ea!eAaCi0!AY!AYqS!A#a%[qSUqS!A#a%[* + + +r   )degreer   r   V2E2r#   r!   r   r"   r
   r   r%   abszipdotr<   )umeshr   r   valwwxyxxyyr?   r   basisr   r@   r   r   jacwvxvyvs                       r   l2normr     s   P {aFF			GG<===a$$ .,---wqzQ-...{aAGAJ!OO-...{aAGAJ!OO-...{&  4555
C 
 R R R 
S 
SB	(*>?(*>?(*>?(*>?')=>(*=>@ 
A 
AB Ahqj!^bAhqj!^B#IB{aIaLL	! 	! 	! 			IaLL	+ 	+ 	+ <=== 	F 	FadGadG fad1Q4i!A$qt),!QqT	AaD1I/FFGG b"b// 	F 	FJBBC!Gr>BF1QqT7EE"bMM$B$BA$EEECC	F 73<<r   c                   .    e Zd ZdZd
dZd Zd ZddZd	S )Meshz:Simple mesh object that holds vertices and mesh functions.r   c                 F   t          j        |                                dz   fd          }d||                                <   t          j        |          }|j        d         |k    r}t          d           t          j        |          d         }t          j        |                                dz             }t          j        |          ||<   ||         }||ddf         }t          ||          st          d          || _        || _        |dddf         | _        |dddf         | _        || _        || _        |j        d         | _        t%          ||          | _        d| _        d| _        d| _        d| _        |dk    r|                                  dS dS )	zInitialize mesh.

        Parameters
        ----------
        V : ndarray
            nv x 2 list of coordinates

        E : ndarray
            ne x 3 list of vertices
        r   FTr   zfixing V and ENz#triangles must be counter clockwiser   )r   fullr-   r)   rP   r
   printrO   r%   r   r#   r   r   XYr   nvr1   rB   r>   r   r   r6   r9   r:   )selfr   r   r   rc   r   r?   Js           r   __init__zMesh.__init__  s}    gquuwwqylE**AGGIIVC[[71:"###a A	!%%''!)$$A9R==AaD!A!QQQ$A!Q 	DBCCC111a4111a4'!*!Q

Q;;##%%%%% ;r   c                 0   | j         t          | j        | j        d          \  | _         | _        | _        | j         dddf         | _        | j         dddf         | _        | j        t          j
        | j        j        d                   z   | _        dS dS )zGenerate a quadratic mesh.NT)r0   r   r   )r   r:   r   r   r   r6   X2Y2r   r   r%   r
   r9   )r   s    r   r:   zMesh.generate_quadratic  s    7?+=dfdfKO,Q ,Q ,Q(DGTWdjgaaadmDGgaaadmDG29TZ-=a-@#A#AADJJJ ?r   c                    d| _         d| _        d| _        d| _        t	          |          D ])}t          | j        | j                  \  | _        | _        *| j        j        d         | _	        | j        j        d         | _
        t          | j        | j                  | _        | j        dddf         | _        | j        dddf         | _        | j        dk    r|                                  dS dS )z~Refine the mesh.

        Parameters
        ----------
        levels : int
            Number of refinement levels.
        Nr   r   r   )r   r   r6   r9   rangero   r   r   r
   r   r1   rB   r>   r   r   r   r:   )r   levels_s      r   refinezMesh.refine  s     

v 	9 	9A(88NDFDFF&,q/&,q/$&$&))11;!##%%%%% r   
   {Gz?c                    | j         }| j        ddg df                                         }| j        ddg df                                         }t          j        |j        d         ft                    }t          j        |||ff||f          }|	                                 |
                                 t          j        |j        dk              d         }t          j        |j        |                   }d|j        dd<   t          j        |                    d                                                    }	| j                                        }
|
|df         |
|df         z
  d	z  |
|df         |
|df         z
  d	z  z   }d
}t)          |          D ]}||
z  }
|
|	dddf         z  }
| j        |ddf         |
|ddf<   t          j        |
|df         |
|df         z
  d	z  |
|df         |
|df         z
  d	z  z             }t          j        t          j        ||z
            |z            }|}||k     r n|
| _        |S )a  Constrained Laplacian Smoothing.

        Parameters
        ----------
        maxit : int
            Iterations
        tol : float
            Convergence toleratnce measured in the maximum
            absolute distance the mesh moves (in one iteration).

        N)r   r   r   r   r   r   )r   r   r   r   r   r   r   r   rD   r   rE   r   d   )r   r   r)   r   r&   r
   r'   r   r(   sum_duplicateseliminate_zerosrO   r.   uniquer+   r   rP   flattenr   copyr   r<   r-   r   )r   maxittolr   edge0edge1r.   r3   bidWVnew
edgelength_itnewedgelengthmoves                  r   smoothzMesh.smooth  sn    W qqq,,,,-3355qqq,,,,-3355wA(444teU^4RHEEE		 hqv{##A&ic
## qqq	HQUUU]]##++--v{{}}5!8ntE1H~595!8ntE1H~59:
 << 		 		Ct8DAaaagJD6#qqq&>DaaaLGT%(^d5!8n%Dq$H'+E1H~UAX'F&J%K L LM6"&!;<<}LMMD&Jczz  
r   N)r   )r   r   )__name__
__module____qualname____doc__r   r:   r   r    r   r   r   r     sd        DD
+& +& +& +&ZB B B& & &./ / / / / /r   r   c                 :    | ||          }t          |t          t          f          rt          j        d          |z  S t          |t          j                  r$|j        dk    r|S t          d|j                   t          dt          |                     )zkStandardize diffusion tensor/scalar.

    This will return an ndarray or a scalar, depending on input.
    r   )r   r   zPkappa must return a scalar or ndarray of shape (2,2), received ndarray of shape zDkappa must return a scalar or ndarray of shape (2,2), received type )	r!   r'   floatr   eyer"   r
   r#   type)kappa_lmbdar   r   kappas       r   _compute_diffusion_matrixr     s    
 K1E%#u&& !vayy5  %$$ E;&  L D6;kD D E E 	E
 4&*5kk4 4 5 5 5r   r   c                    |dvrt          d          |d }|d }t          |          rt          |          st          d          | j        }|dk    r| j        }| j        }| j        }n+|dk    r| j        }| j        }| j        }nt          d	          |dk    rd
nd}t          j
        ||dz  f          }	t          j
        ||dz  ft                    }
t          j
        ||dz  ft                    }t          j
        ||f          }t          j
        ||ft                    }t          j
        ||ft                    }t          d|          D ]}||ddf         }||d                  ||d                  }}||d                  ||d                  }}||d                  ||d                  }}t          j        ||z
  ||z
  g||z
  ||z
  gg          }t          j                            |j                  }t          j                            |          }|dk    rt          j        g dg dg          }|                    |          }t'          |||                                         ||                                                   }|dz  |j        z  |z  |z  } |||                                         ||                                                   |dz  z  t          j        d          z  }|dk    rt          j        g d          }t          j        ddgddgddgddgddgddgg          } | dddf         dz   dz  | dddf         dz   dz  }"}!|d z  }t          j
        ||f          }t          j
        |f          }t-          ||!|"          D ]m\  }#}$}%t          j        d|$z
  |%z
  dd|$z  z
  d|%z  z
  z  |$d|$z  dz
  z  |%d|%z  dz
  z  d!|$z  d|$z
  |%z
  z  d!|$z  |%z  d!|%z  d|$z
  |%z
  z  g          }&t          j        d!|$z  d!|%z  z   d
z
  d!|$z  dz
  dd"|$z  d!|%z  z
  d!z   d!|%z  d#|%z  gd!|$z  d!|%z  z   d
z
  dd!|%z  dz
  d#|$z  d!|$z  d#|$z  d$|%z  z
  d!z   gg          }|                    |          }|                    t          j        |$|%g                    t          j        ||g          z   \  }'}(t'          ||'|(          }||dz  |#z  |j        z  |z  |z  z  }||dz  |#z   ||'|(          z  |&z  z  }o|                                |	|ddf<   t          j        |t          j        |                   |          |
|ddf<   t          j        |t          j        |                   |          ||ddf<   |                                ||ddf<   |t          j        |                   ||ddf<   d||ddf<   t7          j        |	                                |
                                |                                ff          })|)                                 t7          j        |                                |                                |                                ff                                                                          }*|)|*fS )%a  Finite element discretization of a Poisson problem.

    - div . kappa(x,y) grad u = f(x,y)

    Parameters
    ----------
    V : ndarray
        nv x 2 list of coordinates

    E : ndarray
        ne x 3 or 6 list of vertices

    kappa : function
        diffusion coefficient, kappa(x,y) with vector input
        can either return a scalar value or a 2x2 matrix that transforms <grad u>

    f : function
        right hand side, f(x,y) with vector input

    degree : 1 or 2
        polynomial degree of the bases (assumed to be Lagrange locally)

    Returns
    -------
    A : sparse matrix
        finite element matrix where A_ij = <kappa grad phi_i, grad phi_j>

    b : array
        finite element rhs where b_ij = <f, phi_j>

    Notes
    -----
        - modepy is used to generate the quadrature points
          q = modepy.XiaoGimbutasSimplexQuadrature(4,2)

    Examples
    --------
    >>> import numpy as np
    >>> from pyamg.gallery import fem
    >>> import scipy.sparse.linalg as sla
    >>> V = np.array(
    ... [[  0,  0],
    ...  [  1,  0],
    ...  [2*1,  0],
    ...  [  0,  1],
    ...  [  1,  1],
    ...  [2*1,  1],
    ...  [  0,2*1],
    ...  [  1,2*1],
    ...  [2*1,2*1]])
    >>> E = np.array(
    ... [[0, 1, 3],
    ...  [1, 2, 4],
    ...  [1, 4, 3],
    ...  [2, 5, 4],
    ...  [3, 4, 6],
    ...  [4, 5, 7],
    ...  [4, 7, 6],
    ...  [5, 8, 7]])
    >>> mesh = Mesh(V, E)
    >>> A, b = fem.gradgradform(mesh)
    >>> print(A.toarray())
    [[ 1.  -0.5  0.  -0.5  0.   0.   0.   0.   0. ]
     [-0.5  2.  -0.5  0.  -1.   0.   0.   0.   0. ]
     [ 0.  -0.5  1.   0.   0.  -0.5  0.   0.   0. ]
     [-0.5  0.   0.   2.  -1.   0.  -0.5  0.   0. ]
     [ 0.  -1.   0.  -1.   4.  -1.   0.  -1.   0. ]
     [ 0.   0.  -0.5  0.  -1.   2.   0.   0.  -0.5]
     [ 0.   0.   0.  -0.5  0.   0.   1.  -0.5  0. ]
     [ 0.   0.   0.   0.  -1.   0.  -0.5  2.  -0.5]
     [ 0.   0.   0.   0.   0.  -0.5  0.  -0.5  1. ]]
    >>> print(b)
    [0. 0. 0. 0. 0. 0. 0. 0. 0.]
    >>> f = lambda x, y : 0*x + 1.0
    >>> g = lambda x, y : 0*x + 0.0
    >>> g1 = lambda x, y : 0*x + 1.0
    >>> tol = 1e-12
    >>> X, Y = V[:,0], V[:,1]
    >>> id1 = np.where(abs(Y) < tol)[0]    # north
    >>> id2 = np.where(abs(Y-2) < tol)[0]  # south
    >>> bc = [{'id': id1, 'g': g},
    ...       {'id': id2, 'g': g}]
    >>> A, b = fem.gradgradform(mesh, f=f)
    >>> A, b = fem.applybc(A, b, mesh, bc)
    >>> A = A.tocsr()
    >>> u = sla.spsolve(A, b)
    >>> print(A.toarray())
    [[ 1.  0.  0.  0.  0.  0.  0.  0.  0.]
     [ 0.  1.  0.  0.  0.  0.  0.  0.  0.]
     [ 0.  0.  1.  0.  0.  0.  0.  0.  0.]
     [ 0.  0.  0.  2. -1.  0.  0.  0.  0.]
     [ 0.  0.  0. -1.  4. -1.  0.  0.  0.]
     [ 0.  0.  0.  0. -1.  2.  0.  0.  0.]
     [ 0.  0.  0.  0.  0.  0.  1.  0.  0.]
     [ 0.  0.  0.  0.  0.  0.  0.  1.  0.]
     [ 0.  0.  0.  0.  0.  0.  0.  0.  1.]]
    >>> print(b)
    [0.  0.  0.  0.5 1.  0.5 0.  0.  0. ]
    >>> print(u)
    [0.  0.  0.  0.5 0.5 0.5 0.  0.  0. ]
    rs   rt   Nc                     dS )N        r   _x_ys     r   fzgradgradform.<locals>.f      3r   c                     dS )N      ?r   r   s     r   r   zgradgradform.<locals>.kappa  r   r   z#f, kappa must be callable functionsr   r   rq   r   rr   r   r   )r   r   r   )r   r   r   r   g      @r   ru   rx   ry   rz   r{   r|   r}   r~   r   r   r   r   r   rG   r      )r#   callabler1   r   r   r   r   r   r   r   r	   r'   r   r   linalginvr   detr   r   meanr&   r   r)   repeatr%   tiler   r(   r   toarray)+r   r   r   r   r1   r   r   r   mAAIAJAbbibjbeiKx0y0x1y1x2y2r   invJdetJdbasisdphi	kappaelemAelembelemr   r   r   r   wr   r   r   xtytAbs+                                              r   gradgradformr  "  s"   L V4555y	 	 	 }	 	 	 A;; @huoo @>???	B{{FFF	1GGG<=== q[[aA	2q!t*		B	2q!t*C	(	(	(B	2q!t*C	(	(	(B	2q'		B	2q'	%	%	%B	2q'	%	%	%B Arll J Jb!!!eH1Q4!AaD'B1Q4!AaD'B1Q4!AaD'B HrBwR(BwR(* + +y}}QS!!y}}QQ;;Xzzz)zz+ , ,F 88F##D 2%1adiikkRRICZ46)I5<E Aadiikk1Q499;;//4#:>NEQ;; Z Z Z [ [B02FG02FG02FG02FG/1EF02EFH I IB Ahqj!^bAhqj!^B#IBHaV$$EHaTNNEr2r?? < <1a1Q3q51QqS519"5"#QqSU)"#QqSU)"#A#qs1u+"#A#a%"#A#qs1u+"/ 0 0 qS1Q3Y]AaCEq"Q$1*q.!A#QSTUQUVqS1Q3Y]1Q3q5BqD!A#r!taPQczTU~V#   xx'' rxA//0028RH3E3EEB5eRDD	$(a$&09<tCC $(a!!B))3e;; KKMM2qqq5	Ia	!oq112qqq5	GAbillOQ//2qqq5	KKMM2qqq5	billO2qqq5	2qqq5		 	288::

BHHJJ'?@AAA288::

BHHJJ'?@AAIIKKQQSSA a4Kr   c                 
   | j         |                                  | j        | j        }}| j        }| j        }d}d}t          j        |||z  f          }t          j        |||z  ft                    }t          j        |||z  ft                    }	t          j        |||z  f          }
t          j        |||z  ft                    }t          j        |||z  ft                    }t          d|          D ]}||ddf         }||d                  ||d                  }}||d                  ||d                  }}||d                  ||d                  }}t          j
        ||z
  ||z
  g||z
  ||z
  gg          }t          j                            |j                  }t          j                            |          }t          j
        g d          }t          j
        d	d
gddgddgddgddgddgg          }|dddf         dz   dz  |dddf         dz   dz  }}|dz  }t          j        d          }t          j        d          }t          |||          D ]\  }}} t          j
        d|z
  | z
  || g          }!t          j
        d|z  d| z  z   dz
  d|z  dz
  dd|z  d| z  z
  dz   d| z  d| z  gd|z  d| z  z   dz
  dd| z  dz
  d|z  d|z  d|z  d| z  z
  dz   gg          }"|                    |"          }#||dz  |z  t          j        |!|#dddf                   z  z  }||dz  |z  t          j        |!|#dddf                   z  z  }|#j                            |#           |                                ||ddf<   t          j        |t          j        |                   |          ||ddf<   t          j        |t          j        |                   |          |	|ddf<   |                                |
|ddf<   t          j        |t          j        |                   |          ||ddf<   t          j        |t          j        |                   |          ||ddf<   t-          j        |                                |                                |	                                ff          }$|$                                 t-          j        |
                                |                                |                                ff          }%|%                                 |$|%fS )zCalculate the (div u , p) form that arises in Stokes assumes P2-P1 elements.

    Parameters
    ----------
    mesh : Mesh
        Mesh object

    Returns
    -------
    BX, BY : ndarray
        div block B = [BX, BY].T in [[A, B], [B.T 0]]
    Nrr   r   r   r   r   r   ru   rx   ry   rz   r{   r|   r}   r~   r   r   r   r   r   rG   )r   rr   r   r   r   r   )r   r:   r   r   r1   r   r   r	   r'   r   r   r   r   r   r   r   r   outerr)   r   r%   r   r   r(   r   )&r   r   r   r1   r   m1m2DXDXIDXJDYDYIDYJr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   DXelemDYelemr   r   r   r   r   r   BXBYs&                                         r   divformr    sO    w!!!646qA	BA	
B	
B	2r"u+		B
(B2;c
*
*
*C
(B2;c
*
*
*C	2r"u+		B
(B2;c
*
*
*C
(B2;c
*
*
*C Arll 53 53b!!!eH1Q4!AaD'B1Q4!AaD'B1Q4!AaD'BHrBwR(BwR(* + +y}}QS!!y}}QX V V V W WX,.BC,.BC,.BC,.BC,.BC,/BCE F F QQQT(1*a"QQQT(1*aB
c	&!!&!!2r2 	 	GAq!Xqs1uam,,F X1qsQ!A1bdQqSj1nacRPQTR1qsQAqs1u1ac2a4!A#:PQ>R  F
 88F##Dtax1nad(D(DEEFtax1nad(D(DEEFFJJt LLNN2qqq5	Yq2/44BE
WQry}}-r22BE
LLNN2qqq5	Yq2/44BE
WQry}}-r22BE

 
	BHHJJciikk(BC	D	DB		BHHJJciikk(BC	D	DBr6Mr   c                 z   |D ]\}t          |d                   st          d          d|                                vrd|d<   d|                                vrd|d<   ]|D ]z}|d         dk    rl|d         }g }t          |j        |j                  D ].\  }}|d         |v r|d         |v r|                    |           /t          j        ||f          |d<   {t          j	        | j
        d         f          }	|D ]y}|d         |d         z   }|d         dk    r|j        }
|j        }n*|d         dk    r|j        }
|j        }nt          d	           |d         |
|         ||                   |	|<   z|| |	z  z
  }|D ]}|d         |d         z   }|	|         ||<   t          j        | j
        d         fd
          }|D ]}|d         |d         z   }d||<   t!          t          | j        | j                            D ]3\  }\  }}||         s||         r||k    rd| j        |<   )d| j        |<   4| |fS )a	  Apply boundary conditions.

    Parameters
    ----------
    A : sparse matrix
        Fully assembled sparse matrix
    b : ndarray
        Fully assembled right-hand side
    mesh : Mesh
        Mesh object
    bc : list
       list of boundary conditions
       bc = [bc1, bc2, ..., bck]
       where bck = {'id': id,    a list of vertices for boundary "k"
                     'g': g,     g = g(x,y) is a function for the vertices on boundary "k"
                   'var': var    the variable, given as a start in the dof list
                'degree': degree degree of the variable, either 1 or 2
                   }

    Returns
    -------
    A : sparse matrix
        Modified, assembled sparse matrix
    b : ndarray
        Modified, assembled right-hand side
    gz$each bc g must be callable functionsr   r   varr   r   idrq   FTr   r   )r   r#   keysr   r9   r6   appendr   r/   r	   r
   r   r   r   r   r   	enumerater+   r,   r.   )r  r  r   bccidxnewidxjedu0r   r   Dflagkis                  r   applybcr%  a  s   6   # 	ECDDD16688##AhK  AeH  / /X;!D'CFTZ44 % %2a5C<<BqESLLMM!$$$if..AdG 
171:-	 	 B 
) 
)h4 X;!AAAx[AAAA@AAA!C&33((3 	
AF
A   h4 C# GQWQZM5))E  h4 c

s15!%0011    	6Aq8 	 uQx 	 Avvq		q	a4Kr   c                 h   |                                   t          | |d          \  }}t          | |d          \  }}t          |           \  }}t          j        |d|j        gd||j        g||dgg          }	t          j        ||t          j        |j	        d         f          f          }
|	|
fS )zStokes Flow.r   )r   r   Nr   )
r:   r  r  r   bmatr   r   r/   r	   r
   )r   fufvAubuAvbvr  r  Cr  s              r   stokesr/    s    $"Q///FB$"Q///FBT]]FBb$%B%"d^% 	& 	&A 		2r28RXa[N33455Aa4Kr   c                 (    t          d|  d          )aK  Construct model elliptic problem.

    Parameters
    ----------
    num : int or string
        A tag for a particular problem.  See the notes below.

    Returns
    -------
    A
    b
    V
    E
    f
    kappa
    bc

    See Also
    --------
    poissonfem - build the FE matrix and right hand side
    Notes
    -----
    zmodel (num=z) is unimplemented)NotImplementedError)nums    r   modelr3    s    0 CCCCC
D
DDr   )F)N)NNr   )r   )r   numpyr   scipyr   r   r:   rB   ro   r   r   r   r  r  r%  r/  r3  r   r   r   <module>r6     s?   + +          
 
 
V V V Vr' ' 'T~ ~ ~ ~Bp p pfB B B B B B B BJ5 5 5&] ] ] ]@\ \ \~U U Up  E E E E E Er   