- Thank you received: 0
How to deal with the dirichlet boundary condition
4 years 2 months ago #3088
by wen jing
How to deal with the dirichlet boundary condition was created by wen jing
If the Stokes-Darcy problem is dirichlet boundary condition, that is the speed of Stokes domain and the pressure of Darcy region are known. According to the code that previously dealt with Neumann boundary conditions we made the following modifications. However, that's not what we want. Anybody know why?
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from fealpy.tools.show import showmultirate, show_error_table
from ngsolve import *
from netgen.geom2d import SplineGeometry
from numpy import pi
import netgen.gui
ngsglobals.msg_level=1
errorType = ['$||us - us_h||_{\Omega,0}$',
'$||ud - ud_h||_{\Omega, 0}$'
]
maxit = 1
errorMatrix = np.zeros((2, maxit), dtype=np.float)
NDof = np.zeros(maxit, dtype=np.float)
def topBottom():
geometry = SplineGeometry()
# point coordinates ...
pnts = [ (0,0), (1,0), (1,0.5), (1,1), (0,1), (0, 0.5)]
pnums = [geometry.AppendPoint(*p) for p in pnts]
# start-point, end-point, boundary-condition, domain on left side, domain on right side:
lines = [ (pnums[0],pnums[1],"gammaD",2,0), (pnums[1],pnums[2],"gammaD",2,0),
(pnums[2],pnums[3],"gammaS",1,0), (pnums[3],pnums[4],"gammaS",1,0),
(pnums[4],pnums[5],"gammaS",1,0),
(pnums[5],pnums[0],"gammaD",2,0), (pnums[5],pnums[2],"gammaSD",1,2)]
for p1,p2,bc,left,right in lines:
geometry.Append( ["line", p1, p2], bc=bc, leftdomain=left, rightdomain=right)
return geometry
def GetInterfaceIndicator(mesh):
dom_indicator = GridFunction(L2(mesh,order=0))
dom_indicator.Set(CoefficientFunction([1,2]))
ffes = FacetFESpace(mesh,order=0)
dom_ind_average = GridFunction(ffes)
mf = BilinearForm(ffes,symmetric=True)
mf += SymbolicBFI(ffes.TrialFunction()*ffes.TestFunction(),element_boundary=True)
mf.Assemble()
ff = LinearForm(ffes)
ff += SymbolicLFI(dom_indicator*ffes.TestFunction(),element_boundary=True)
ff.Assemble()
dom_ind_average.vec.data = mf.mat.Inverse() * ff.vec
interface_indicator = BitArray(ffes.ndof)
for i in range(len(dom_ind_average.vec)):
if (dom_ind_average.vec > 1.75) or (dom_ind_average.vec < 1.25):
interface_indicator = False
else:
interface_indicator = True
print(sum(interface_indicator))
return interface_indicator
def GetFaceIndicator(mesh):
dom_indicator = GridFunction(L2(mesh,order=0))
dom_indicator.Set(CoefficientFunction([1,2]))
ffes = FacetFESpace(mesh,order=0)
dom_ind_average = GridFunction(ffes)
mf = BilinearForm(ffes,symmetric=True)
mf += SymbolicBFI(ffes.TrialFunction()*ffes.TestFunction(),element_boundary=True)
mf.Assemble()
ff = LinearForm(ffes)
ff += SymbolicLFI(dom_indicator*ffes.TestFunction(),element_boundary=True)
ff.Assemble()
dom_ind_average.vec.data = mf.mat.Inverse() * ff.vec
stokes_indicator = BitArray(ffes.ndof)
darcy_indicator = BitArray(ffes.ndof)
for i in range(len(dom_ind_average.vec)):
if (dom_ind_average.vec > 1.75): # exclude darcy part
stokes_indicator = False
else:
stokes_indicator = True
if (dom_ind_average.vec < 1.25): # exclude darcy part
darcy_indicator = False
else:
darcy_indicator = True
#print("facets marked as stokes facets:", stokes_indicator)
#print("facets marked as darcy facets:", darcy_indicator)
return stokes_indicator, darcy_indicator
def tang(vec):
return vec - (vec*n)*n
stokesId = [1,0]
darcyId = [0,1]
nu = 1.
kinv = 1.
gamma = (1.+4.*pi*pi)/2.
hmax = 1.0/8
u1 = sin(pi*x)*exp(y/2.)
u2 = cos(pi*x)*exp(y/2.)
uexS = CoefficientFunction((-1./2./pi/pi*u1,1./pi*u2))
uexD = CoefficientFunction((-2.*u1,1./pi*u2))
pexS = CoefficientFunction(-1./pi*u2)
pexD = CoefficientFunction(-2./pi*u2)
cst1 = 1.+nu*(-.5+1./8./pi/pi)
cst2 = -.5/pi+nu*(pi-.25/pi)
cst3 = 0.5/pi-2.*pi
stokesSource = CoefficientFunction((cst1*u1,cst2*u2))
darcySource = CoefficientFunction(cst3*u2)
dcFlag = False
n = specialcf.normal(2)
h = specialcf.mesh_size
order = 1
orderp = order-1
penalty = 10*order*(order+1)/h
InitialMeshSize = 1
for i in range(maxit):
hmax = InitialMeshSize/2**i
mesh = Mesh(topBottom().GenerateMesh (maxh=hmax))
dom1 = GridFunction(L2(mesh,order=0))
dom2 = GridFunction(L2(mesh,order=0))
dom1.Set(CoefficientFunction(stokesId))
dom2.Set(CoefficientFunction(darcyId))
V1 = HDiv(mesh, order=order, dirichlet="gammaS")
# FIXME define trace space only on stokes domain
V2 = FESpace ("vectorfacet", mesh, order=order, dirichlet="gammaS",definedon = [1], flags
={"highest_order_dc": dcFlag})
V3 = L2(mesh, order=orderp)
V = FESpace([V1,V2, V3], flags={"dgjumps": True})
u,uhat, p = V.TrialFunction()
v,vhat, q = V.TestFunction()
crossTerm = -div(u)*q-div(v)*p
du = grad(u)
dv = grad(v)
gradu = CoefficientFunction ( (du,), dims=(2,2) )
gradv = CoefficientFunction ( (dv,), dims=(2,2) )
epsu = 0.5*(gradu+gradu.trans)
epsv = 0.5*(gradv+gradv.trans)
interface_indicator = GetInterfaceIndicator(mesh)
a = BilinearForm(V)
# dg stokes
stokesCell = 2*nu*InnerProduct(epsu,epsv)
stokesFacet1 = 2*nu*InnerProduct ( epsu*n, tang(vhat-v) )
stokesFacet2 = 2*nu*InnerProduct ( epsv*n, tang(uhat-u) )
stokesFacet3 = penalty*nu*InnerProduct (tang(vhat-v),tang(uhat-u) )
# Hdiv darcy
darcyCell = kinv*u*v
# interface (only stokes part is needed)
interfaceTerm = gamma*sqrt(kinv)*(tang(uhat)*tang(vhat))
## DEBUGGING
# Stokes is correct
a += SymbolicBFI ( stokesCell+dom2*darcyCell + crossTerm, definedon=[1])
a += SymbolicBFI ( darcyCell + crossTerm, definedon = [2])
a += SymbolicBFI ( (stokesFacet1+stokesFacet2+stokesFacet3), element_boundary=True, definedon=[1])
interfacebfi = SymbolicBFI (interfaceTerm, VOL, skeleton=True)
interfacebfi.SetDefinedOnElements(interface_indicator)
a += interfacebfi
a.Assemble()
c = Preconditioner(type="direct", bf=a, flags = { "inverse" : "pardiso" } )
f = LinearForm(V)
f += SymbolicLFI(dom1*stokesSource*v-dom2*darcySource*q)
f += -pexD*(v.Trace()*n)*ds(definedon=mesh.Boundaries("gammaD"))
f += -pexS*(v.Trace()*n)*ds(definedon=mesh.Boundaries("gammaS"))
f.Assemble()
u = GridFunction(V)
u.components[0].Set(dom1*uexS,definedon=mesh.Boundaries("gammaS"))
u.components[1].Set(uexS,definedon=mesh.Boundaries("gammaS"))
bvp = BVP(bf=a,lf=f,gf=u,pre=c, maxsteps=1000, prec=1e-11)
errS = dom1*(u.components[0]-uexS)*(u.components[0]-uexS)
errD = dom2*(u.components[0]-uexD)*(u.components[0]-uexD)
erru1 = sqrt( Integrate(errS,mesh,order = 2*order) )
erru2 = sqrt( Integrate(errD,mesh,order = 2*order) )
errorMatrix[0, i] = erru1
errorMatrix[1, i] = erru2
show_error_table(NDof, errorType, errorMatrix)
plt.show()
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from fealpy.tools.show import showmultirate, show_error_table
from ngsolve import *
from netgen.geom2d import SplineGeometry
from numpy import pi
import netgen.gui
ngsglobals.msg_level=1
errorType = ['$||us - us_h||_{\Omega,0}$',
'$||ud - ud_h||_{\Omega, 0}$'
]
maxit = 1
errorMatrix = np.zeros((2, maxit), dtype=np.float)
NDof = np.zeros(maxit, dtype=np.float)
def topBottom():
geometry = SplineGeometry()
# point coordinates ...
pnts = [ (0,0), (1,0), (1,0.5), (1,1), (0,1), (0, 0.5)]
pnums = [geometry.AppendPoint(*p) for p in pnts]
# start-point, end-point, boundary-condition, domain on left side, domain on right side:
lines = [ (pnums[0],pnums[1],"gammaD",2,0), (pnums[1],pnums[2],"gammaD",2,0),
(pnums[2],pnums[3],"gammaS",1,0), (pnums[3],pnums[4],"gammaS",1,0),
(pnums[4],pnums[5],"gammaS",1,0),
(pnums[5],pnums[0],"gammaD",2,0), (pnums[5],pnums[2],"gammaSD",1,2)]
for p1,p2,bc,left,right in lines:
geometry.Append( ["line", p1, p2], bc=bc, leftdomain=left, rightdomain=right)
return geometry
def GetInterfaceIndicator(mesh):
dom_indicator = GridFunction(L2(mesh,order=0))
dom_indicator.Set(CoefficientFunction([1,2]))
ffes = FacetFESpace(mesh,order=0)
dom_ind_average = GridFunction(ffes)
mf = BilinearForm(ffes,symmetric=True)
mf += SymbolicBFI(ffes.TrialFunction()*ffes.TestFunction(),element_boundary=True)
mf.Assemble()
ff = LinearForm(ffes)
ff += SymbolicLFI(dom_indicator*ffes.TestFunction(),element_boundary=True)
ff.Assemble()
dom_ind_average.vec.data = mf.mat.Inverse() * ff.vec
interface_indicator = BitArray(ffes.ndof)
for i in range(len(dom_ind_average.vec)):
if (dom_ind_average.vec > 1.75) or (dom_ind_average.vec < 1.25):
interface_indicator = False
else:
interface_indicator = True
print(sum(interface_indicator))
return interface_indicator
def GetFaceIndicator(mesh):
dom_indicator = GridFunction(L2(mesh,order=0))
dom_indicator.Set(CoefficientFunction([1,2]))
ffes = FacetFESpace(mesh,order=0)
dom_ind_average = GridFunction(ffes)
mf = BilinearForm(ffes,symmetric=True)
mf += SymbolicBFI(ffes.TrialFunction()*ffes.TestFunction(),element_boundary=True)
mf.Assemble()
ff = LinearForm(ffes)
ff += SymbolicLFI(dom_indicator*ffes.TestFunction(),element_boundary=True)
ff.Assemble()
dom_ind_average.vec.data = mf.mat.Inverse() * ff.vec
stokes_indicator = BitArray(ffes.ndof)
darcy_indicator = BitArray(ffes.ndof)
for i in range(len(dom_ind_average.vec)):
if (dom_ind_average.vec > 1.75): # exclude darcy part
stokes_indicator = False
else:
stokes_indicator = True
if (dom_ind_average.vec < 1.25): # exclude darcy part
darcy_indicator = False
else:
darcy_indicator = True
#print("facets marked as stokes facets:", stokes_indicator)
#print("facets marked as darcy facets:", darcy_indicator)
return stokes_indicator, darcy_indicator
def tang(vec):
return vec - (vec*n)*n
stokesId = [1,0]
darcyId = [0,1]
nu = 1.
kinv = 1.
gamma = (1.+4.*pi*pi)/2.
hmax = 1.0/8
u1 = sin(pi*x)*exp(y/2.)
u2 = cos(pi*x)*exp(y/2.)
uexS = CoefficientFunction((-1./2./pi/pi*u1,1./pi*u2))
uexD = CoefficientFunction((-2.*u1,1./pi*u2))
pexS = CoefficientFunction(-1./pi*u2)
pexD = CoefficientFunction(-2./pi*u2)
cst1 = 1.+nu*(-.5+1./8./pi/pi)
cst2 = -.5/pi+nu*(pi-.25/pi)
cst3 = 0.5/pi-2.*pi
stokesSource = CoefficientFunction((cst1*u1,cst2*u2))
darcySource = CoefficientFunction(cst3*u2)
dcFlag = False
n = specialcf.normal(2)
h = specialcf.mesh_size
order = 1
orderp = order-1
penalty = 10*order*(order+1)/h
InitialMeshSize = 1
for i in range(maxit):
hmax = InitialMeshSize/2**i
mesh = Mesh(topBottom().GenerateMesh (maxh=hmax))
dom1 = GridFunction(L2(mesh,order=0))
dom2 = GridFunction(L2(mesh,order=0))
dom1.Set(CoefficientFunction(stokesId))
dom2.Set(CoefficientFunction(darcyId))
V1 = HDiv(mesh, order=order, dirichlet="gammaS")
# FIXME define trace space only on stokes domain
V2 = FESpace ("vectorfacet", mesh, order=order, dirichlet="gammaS",definedon = [1], flags
={"highest_order_dc": dcFlag})
V3 = L2(mesh, order=orderp)
V = FESpace([V1,V2, V3], flags={"dgjumps": True})
u,uhat, p = V.TrialFunction()
v,vhat, q = V.TestFunction()
crossTerm = -div(u)*q-div(v)*p
du = grad(u)
dv = grad(v)
gradu = CoefficientFunction ( (du,), dims=(2,2) )
gradv = CoefficientFunction ( (dv,), dims=(2,2) )
epsu = 0.5*(gradu+gradu.trans)
epsv = 0.5*(gradv+gradv.trans)
interface_indicator = GetInterfaceIndicator(mesh)
a = BilinearForm(V)
# dg stokes
stokesCell = 2*nu*InnerProduct(epsu,epsv)
stokesFacet1 = 2*nu*InnerProduct ( epsu*n, tang(vhat-v) )
stokesFacet2 = 2*nu*InnerProduct ( epsv*n, tang(uhat-u) )
stokesFacet3 = penalty*nu*InnerProduct (tang(vhat-v),tang(uhat-u) )
# Hdiv darcy
darcyCell = kinv*u*v
# interface (only stokes part is needed)
interfaceTerm = gamma*sqrt(kinv)*(tang(uhat)*tang(vhat))
## DEBUGGING
# Stokes is correct
a += SymbolicBFI ( stokesCell+dom2*darcyCell + crossTerm, definedon=[1])
a += SymbolicBFI ( darcyCell + crossTerm, definedon = [2])
a += SymbolicBFI ( (stokesFacet1+stokesFacet2+stokesFacet3), element_boundary=True, definedon=[1])
interfacebfi = SymbolicBFI (interfaceTerm, VOL, skeleton=True)
interfacebfi.SetDefinedOnElements(interface_indicator)
a += interfacebfi
a.Assemble()
c = Preconditioner(type="direct", bf=a, flags = { "inverse" : "pardiso" } )
f = LinearForm(V)
f += SymbolicLFI(dom1*stokesSource*v-dom2*darcySource*q)
f += -pexD*(v.Trace()*n)*ds(definedon=mesh.Boundaries("gammaD"))
f += -pexS*(v.Trace()*n)*ds(definedon=mesh.Boundaries("gammaS"))
f.Assemble()
u = GridFunction(V)
u.components[0].Set(dom1*uexS,definedon=mesh.Boundaries("gammaS"))
u.components[1].Set(uexS,definedon=mesh.Boundaries("gammaS"))
bvp = BVP(bf=a,lf=f,gf=u,pre=c, maxsteps=1000, prec=1e-11)
errS = dom1*(u.components[0]-uexS)*(u.components[0]-uexS)
errD = dom2*(u.components[0]-uexD)*(u.components[0]-uexD)
erru1 = sqrt( Integrate(errS,mesh,order = 2*order) )
erru2 = sqrt( Integrate(errD,mesh,order = 2*order) )
errorMatrix[0, i] = erru1
errorMatrix[1, i] = erru2
show_error_table(NDof, errorType, errorMatrix)
plt.show()
Time to create page: 0.100 seconds