我大部分时间都对 Fenics 中边界条件的应用感到困惑。假设我有一个矩形梁的 xml 网格,并且想要在我的网格文件中梁的左侧谁能告诉我如何实现这一目标?
我知道通过定义像这里这样的子域来做到这一点的另一种方法:
class Left(SubDomain):
def inside(self, x, on_boundary):
return near(x[0], 0.0)
但是对于复杂的几何形状,我确信这种方法没有用。
谢谢。
我大部分时间都对 Fenics 中边界条件的应用感到困惑。假设我有一个矩形梁的 xml 网格,并且想要在我的网格文件中梁的左侧谁能告诉我如何实现这一目标?
我知道通过定义像这里这样的子域来做到这一点的另一种方法:
class Left(SubDomain):
def inside(self, x, on_boundary):
return near(x[0], 0.0)
但是对于复杂的几何形状,我确信这种方法没有用。
谢谢。
这取决于你是如何生成文件的。例如,您的网格生成器可以根据其输入生成一些单元格或分面标记。然后dolfin-convert脚本可能会也可能不会成功地将所有这些标记转换为 XML。然后将它们存储在 XML 网格文件或单独的 XML 中。然后,您可以将它们用作FacetFunction
# if stored within mesh
facet_domains = mesh.domains().facet_domains(mesh) # older versions of DOLFIN
facet_domains = mesh.domains().facet_domains() # newer versions of DOLFIN
# if stored separately
facet_domains = MeshFunction('uint', mesh, file) # older versions of DOLFIN
facet_domains = MeshFunction('size_t', mesh, file) # newer versions of DOLFIN
# now define homogenous Dirichlet BC where facet_domains is equal to 42
bc42 = DirichletBC(V, 0.0, facet_domains, 42)
# now integrate over interior facets where facet_domains equals 43
dS = Measure('dS')[facet_domains]
dS43 = dS(43)
integral43 = foo*dS43
如果您的网格生成器没有为您提供所需的标记,您可以首先使用 生成这些标记EntityIterators,例如
facet_domains = FacetFunction('size_t', mesh, 0)
for c in cells(mesh):
# here some conditions on c
for f in facets(c):
# here some conditions on f
facet_domains[f] = some_computed_value
然后你可以facet_domains按照上面的建议使用这些。
DirichletBC在一个特定的顶点应用
由于仅支持s,DirichletBC因此无法通过MeshFunctions定义一个顶点。但是您可以利用并执行以下操作:DirichletBCFacetFunctionDirichletBC(..., method='pointwise')
import numpy as np
class Pinpoint(SubDomain):
TOL = 1e-3
def __init__(self, coords):
self.coords = np.array(coords)
SubDomain.__init__(self)
def move(self, coords):
self.coords[:] = np.array(coords)
def inside(self, x, on_boundary):
return np.linalg.norm(x-self.coords) < TOL
pinpoint = Pinpoint([0.,0.,0.])
V = VectorFunctionSpace(mesh, "Lagrange", 1)
bc = DirichletBC(V.sub(0), 0.0, pinpoint, 'pointwise')
请注意,这仅对V连续分段线性函数有意义。构造函数Pinpoint.__init__接受一个coords参数(类型tuple,list或np.array),允许指定要应用 BC 的坐标。方法Pinpoint.move也可以用于更改这一点而无需创建新DirichletBC实例 - 特别是在mesh移动时。
另一种可能性是直接摆弄Tensors 的条目。