Fenics:Meshfunction 用法

计算科学 芬尼克斯
2021-12-12 10:49:48

我大部分时间都对 Fenics 中边界条件的应用感到困惑。假设我有一个矩形梁的 xml 网格,并且想要在我的网格文件中梁的左侧谁能告诉我如何实现这一目标?u=0

我知道通过定义像这里这样的子域来做到这一点的另一种方法:

class Left(SubDomain):
def inside(self, x, on_boundary):
    return near(x[0], 0.0)

但是对于复杂的几何形状,我确信这种方法没有用。

谢谢。

1个回答

这取决于你是如何生成文件的。例如,您的网格生成器可以根据其输入生成一些单元格或分面标记。然后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参数(类型tuplelistnp.array),允许指定要应用 BC 的坐标。方法Pinpoint.move也可以用于更改这一点而无需创建新DirichletBC实例 - 特别是在mesh移动时。

另一种可能性是直接摆弄Tensors 的条目。