我要解决以下系统:
在正方形的流体域中,该流体域是两个域Omega_fluid和Omega_solid的并集,后者是与正方形相交的2D或3D欧几里德碗的集合。
要点是,如果我使用FEniCS和以下代码来计算,则所得的矢量khi以及更明显的其梯度在3D中不是周期性的:
## Usual python packages
import numpy as np
import pylab as pl
from pylab import *
import matplotlib.pyplot as plt
from math import sqrt
## FEniCS
from fenics import *
from dolfin import *
from mshr import *
## A periodic boundary defined as a SubDomain
tol=1e-10
xinf=0.0
yinf=0.0
zinf=0.0
xsup=1.0
ysup=1.0
zsup=1.0
dimension=3
class PeriodicBoundary(SubDomain):
# Left boundary is "target domain" G
def inside(self, x, on_boundary):
return on_boundary and not(near(x[0],xsup,tol) or near(x[1],ysup,tol) or near(x[2],zsup,tol))## a special thank to Arnold Douglas
# Map right boundary (H) to left boundary (G)
def map(self, x, y):
for i in range(dimension):
if near(x[i],1.0,tol):
y[i]=0.0
else:
y[i]=x[i]
## Creates a mesh for the unit square minus a circular inclusion
c_x=0.5
c_y=0.5
c_z=0.5
cen=[c_x,c_y,c_z]
r=0.35
res=15
box=Box(Point(-1,-1,-1),Point(2,2,2))
domain=box
# Creates a periodic inclusion, useful if cen != [0.5,0.5]
l_sph=[]
for i in range(-1,2):
for j in range(-1,2):
for k in range(-1,2):
l_sph.append(Sphere(Point(cen[0]+i,cen[1]+j,cen[2]+k),r))
for sph_per in l_sph:
domain=domain-sph_per
domain=domain*Box(Point(0,0,0),Point(1,1,1))
# A first mesh for the periodic domain
mesh_s_r=generate_mesh(domain,res)
## Refines the mesh at the edges of the square and of the inclusion
# not relevant
## Computes khi with a Finite Element Method
# A vector function space for the weak problem
V=VectorFunctionSpace(mesh_s_r, 'P', 2, constrained_domain=PeriodicBoundary())
# A SubDomain for the inclusion boundary
l_cen=[]
for i in range(-1,2):
for j in range(-1,2):
for k in range(-1,2):
l_cen.append([cen[0]+i,cen[1]+j,cen[2]+k])
class periodic_inclusion(SubDomain):
def inside(self,x,on_boundary):
return (on_boundary and any([between((x[0]-c[0]), (-r-tol, r+tol)) for c in l_cen]) and any([between((x[1]-c[1]), (-r-tol, r+tol)) for c in l_cen]) and any([between((x[2]-c[2]), (-r-tol, r+tol)) for c in l_cen]))
## Marks for the domain boundaries
Gamma_sf = periodic_inclusion()
boundaries = MeshFunction("size_t", mesh_s_r, mesh_s_r.topology().dim()-1)
boundaries.set_all(1)
Gamma_sf.mark(boundaries, 7)
ds = Measure("ds")(subdomain_data=boundaries)
num_ff=1
num_front_sphere=7
# We solve the problem
normale = FacetNormal(mesh_s_r)
nb_noeuds=V.dim()
u = TrialFunction(V)
v = TestFunction(V)
a=tr(dot((grad(u)).T, grad(v)))*dx
L=-dot(normale,v)*ds(num_front_sphere)
##
u=Function(V)
solve(a==L,u)
# Mean value of khi
moy_u_x=assemble(u[0]*dx)/(1-4/3*pi*r**3)
moy_u_y=assemble(u[1]*dx)/(1-4/3*pi*r**3)
moy_u_z=assemble(u[2]*dx)/(1-4/3*pi*r**3)
moy=Function(V)
moy=Constant((moy_u_x,moy_u_y,moy_u_z))
khi=project(u-moy,V)
## Plots with matplotlib
for b in range(0,3):
p_gk=plot(-grad(khi)[:,b])
#plt.colorbar(p_gk)
#plt.savefig("inc_s"+str(c_x)+str(c_y)+str(c_z)+"m_dkhi"+"_d"+str(b+1)+".png")
plt.show(p_gk)
plt.close()
以下矢量场是Grad khi的矢量分量,因此无散度,是高度非周期的。
事实上,这种情况是特定于三维的:二维的相同代码给出了一个周期性的矢量场,如下图所示:
Values of khi, in black and blue, on opposite sides of the cell
The first component of vector khi
The second component of vector khi
我们观察到定义矢量函数空间时将调用类PeriodicBoundary(),并且不应将网格视为周期性的。这是否证明了周期性边界条件的失败?但是,它并不能解释我们在二维情况下的发现:khi的切向分量在相反的边界上完全匹配,法向分量匹配,除了符号变化的边界的一些点以外-我打印了正常分量以确保其与图上显示“零”的位置匹配。
谢谢您的帮助,
安托万·莫罗(拉罗谢尔大学)