In [1]:
import sys
sys.path.append('../')
import numpy as np
import matplotlib.pyplot as plt
from spfem.geometry import GeometryMeshPyTriangle
%matplotlib inline
In [2]:
g = GeometryMeshPyTriangle(np.array([(0, 0), (1, 0), (1, 0.2), (2, 0.4), (2, 0.6), (1, 0.8), (1, 1), (0, 1)]))
m = g.mesh(0.03)
m.draw()
m.show()
In [3]:
from spfem.element import ElementTriP1, ElementTriP2, ElementH1Vec
from spfem.assembly import AssemblerElement
Next we create assemblers for the elements. We can give different elements for the solution vector and the test function. In this case we form the blocks $A$ and $B$ separately.
In [4]:
a = AssemblerElement(m, ElementH1Vec(ElementTriP2()))
b = AssemblerElement(m, ElementH1Vec(ElementTriP2()), ElementTriP1())
c = AssemblerElement(m, ElementTriP1())
In [5]:
def stokes_bilinear_a(du, dv):
def inner_product(a, b):
return a[0][0]*b[0][0] +\
a[0][1]*b[0][1] +\
a[1][0]*b[1][0] +\
a[1][1]*b[1][1]
def eps(dw): # symmetric part of the velocity gradient
import copy
dW = copy.deepcopy(dw)
dW[0][1] = .5*(dw[0][1] + dw[1][0])
dW[1][0] = dW[0][1]
return dW
return inner_product(eps(du), eps(dv))
A = a.iasm(stokes_bilinear_a) # iasm takes a function handle defining the weak form
In [6]:
def stokes_bilinear_b(du, v):
return (du[0][0]+du[1][1])*v
B = b.iasm(stokes_bilinear_b)
In [18]:
from spfem.utils import stack
from scipy.sparse import csr_matrix
eps = 1e-3
C = c.iasm(lambda u, v: u*v)
K = stack(np.array([[A, B.T], [B, -eps*C]])).tocsr()
In [19]:
from spfem.utils import direct
import copy
x = np.zeros(K.shape[0])
f = copy.deepcopy(x)
# find DOF sets
dirichlet_dofs, _ = a.find_dofs(lambda x, y: x >= 1.0)
inflow_dofs, inflow_locs = a.find_dofs(lambda x, y: x == 2.0, dofrows=[0])
# set inflow condition and solve with direct method
def inflow_profile(y):
return (y-0.4)*(y-0.6)
x[inflow_dofs] = inflow_profile(inflow_locs[1, :])
I = np.setdiff1d(np.arange(K.shape[0]), dirichlet_dofs)
x = direct(K, f, x=x, I=I)
In [20]:
m.plot(x[np.arange(C.shape[0]) + A.shape[0]])
m.plot(np.sqrt(x[a.dofnum_u.n_dof[0, :]]**2+x[a.dofnum_u.n_dof[0, :]]**2), smooth=True)
plt.figure()
plt.quiver(m.p[0, :], m.p[1, :], x[a.dofnum_u.n_dof[0, :]], x[a.dofnum_u.n_dof[1, :]])
m.show()