Source code for mozart.mesh.triangle
import numpy as np
[docs]def compute_n4s(n4e):
"""
Get a matrix whose each row contains end points of the corresponding side (or edge)
Paramters
- ``n4e`` (``int32 array``) : nodes for elements
Returns
- ``n4s`` (``int32 array``) : nodes for sides
Example
>>> n4e = np.array([[1, 3, 0], [3, 1, 2]])
>>> n4s = compute_n4s(n4e)
>>> n4s
array([[1, 3],
[3, 0],
[1, 2],
[0, 1],
[2, 3]])
"""
allSides = np.vstack((np.vstack((n4e[:,[0,1]], n4e[:,[1,2]])),n4e[:,[2,0]]))
tmp=np.sort(allSides)
x, y = tmp.T
_, ind = np.unique(x + y*1.0j, return_index=True)
n4sInd = np.sort(ind)
n4s = allSides[n4sInd,:]
return n4s
[docs]def compute_s4e(n4e):
"""
Get a matrix whose each row contains three side numbers of the corresponding element
Paramters
- ``n4e`` (``int32 array``) : nodes for elements
Returns
- ``s4e`` (``int32 array``) : sides for elements
Example
>>> n4e = np.array([[1, 3, 0], [3, 1, 2]])
>>> s4e = compute_s4e(n4e)
>>> s4e
array([[0, 1, 3],
[0, 2, 4]])
"""
allSides = np.vstack((np.vstack((n4e[:,[0,1]], n4e[:,[1,2]])),n4e[:,[2,0]]))
tmp=np.sort(allSides)
x, y = tmp.T
_, ind, back = np.unique(x + y*1.0j, return_index=True, return_inverse=True)
sortInd = ind.argsort()
sideNr = np.zeros(ind.size, dtype = int)
sideNr[sortInd] = np.arange(0,ind.size)
s4e = sideNr[back].reshape(3,-1).transpose().astype('int')
return s4e
[docs]def compute_e4s(n4e):
"""
Get a matrix whose each row contains two elements sharing the corresponding side
If second column is -1, the corresponding side is on the boundary
Paramters
- ``n4e`` (``int32 array``) : nodes for elements
Returns
- ``e4s`` (``int32 array``) : elements for sides
Example
>>> n4e = np.array([[1, 3, 0], [3, 1, 2]])
>>> e4s = compute_e4s(n4e)
>>> e4s
array([[ 0, 1],
[ 0, -1],
[ 1, -1],
[ 0, -1],
[ 1, -1]])
"""
allSides = np.vstack((np.vstack((n4e[:,[0,1]], n4e[:,[1,2]])),n4e[:,[2,0]]))
tmp=np.sort(allSides)
x, y = tmp.T
_, ind, back = np.unique(x + y*1.0j, return_index=True, return_inverse=True)
n4sInd = np.sort(ind)
nrElems = n4e.shape[0]
elemNumbers = np.hstack((np.hstack((np.arange(0,nrElems),np.arange(0,nrElems))),np.arange(0,nrElems)))
e4s=np.zeros((ind.size,2),int)
e4s[:,0]=elemNumbers[n4sInd] + 1
allElems4s=np.zeros(allSides.shape[0],int)
tmp2 = np.bincount((back + 1),weights = (elemNumbers + 1))
allElems4s[ind]=tmp2[1::]
e4s[:,1] = allElems4s[n4sInd] - e4s[:,0]
e4s=e4s-1
return e4s
[docs]def refineUniformRed(c4n, n4e, n4Db, n4Nb):
"""
Refine a given mesh uniformly using the red refinement
Paramters
- ``c4n`` (``float64 array``) : coordinates for elements
- ``n4e`` (``int32 array``) : nodes for elements
- ``n4Db`` (``int32 array``) : nodes for Difichlet boundary
- ``n4Nb`` (``int32 array``) : nodes for Neumann boundary
Returns
- ``c4nNew`` (``float64 array``) : coordinates for element obtained from red refinement
- ``n4eNew`` (``int32 array``) : nodes for element obtained from red refinement
- ``n4DbNew`` (``int32 array``) : nodes for Dirichlet boundary obtained from red refinement
- ``n4NbNew`` (``int32 array``) : nodes for Neumann boundary obtained from red refinement
Example
>>> c4n = np.array([[0., 0.], [1., 0.], [1., 1.], [0., 1.]])
>>> n4e = np.array([[1, 3, 0], [3, 1, 2]])
>>> n4Db = np.array([[0, 1], [1, 2]])
>>> n4Nb = np.array([[2, 3],[3, 0]])
>>> c4nNew, n4eNew, n4DbNew, n4NbNew = refineUniformRed(c4n, n4e, n4Db, n4Nb)
>>> c4nNew
array([[ 0. , 0. ],
[ 1. , 0. ],
[ 1. , 1. ],
[ 0. , 1. ],
[ 0.5, 0.5],
[ 0. , 0.5],
[ 1. , 0.5],
[ 0.5, 0. ],
[ 0.5, 1. ]])
>>> n4eNew
array([[1, 4, 7],
[4, 3, 5],
[5, 7, 4],
[7, 5, 0],
[3, 4, 8],
[4, 1, 6],
[6, 8, 4],
[8, 6, 2]])
>>> n4DbNew
array([[0, 7],
[7, 1],
[1, 6],
[6, 2]])
>>>n4NbNew
array([[2, 8],
[8, 3],
[3, 5],
[5, 0]])
"""
nrNodes = c4n.shape[0]
nrElems = n4e.shape[0]
n4s = compute_n4s(n4e)
nrSides = n4s.shape[0]
from scipy.sparse import coo_matrix
newNodes4s = coo_matrix((np.arange(0,nrSides)+nrNodes, (n4s[:,0], n4s[:,1])), shape=(nrNodes, nrNodes))
newNodes4s = newNodes4s.tocsr()
newNodes4s = newNodes4s + newNodes4s.transpose()
mid4s = (c4n[n4s[:,0],:] + c4n[n4s[:,1],:]) * 0.5
c4nNew = np.vstack((c4n, mid4s))
n4eNew = np.zeros((4 * nrElems, 3), dtype=int)
for elem in range(0,nrElems):
nodes = n4e[elem,:]
newNodes = np.array([newNodes4s[nodes[0],nodes[1]], newNodes4s[nodes[1],nodes[2]], newNodes4s[nodes[2],nodes[0]]])
n4eNew[4*elem + np.arange(0,4),:] = np.array([[nodes[0], newNodes[0], newNodes[2]],
[newNodes[0], nodes[1], newNodes[1]], [newNodes[1], newNodes[2], newNodes[0]],
[newNodes[2], newNodes[1], nodes[2]]])
n4DbNew = np.zeros((2 * n4Db.shape[0], 2), dtype = int)
for side in range(0, n4Db.shape[0]):
nodes = n4Db[side,:]
newNodes = newNodes4s[nodes[0], nodes[1]]
n4DbNew[2*side + np.arange(0,2),:] = np.array([[nodes[0], newNodes], [newNodes, nodes[1]]])
n4NbNew = np.zeros((2 * n4Nb.shape[0], 2), dtype = int)
for side in range(0, n4Nb.shape[0]):
nodes = n4Nb[side,:]
newNodes = newNodes4s[nodes[0], nodes[1]]
n4NbNew[2*side + np.arange(0,2),:] = np.array([[nodes[0], newNodes], [newNodes, nodes[1]]])
return (c4nNew, n4eNew, n4DbNew, n4NbNew)