How to mark the cells above the boundary?
This is a very generic question, with no reference to what part of FEniCS you are using (legacy or dolfinx).
Additionally, «above» is a vague term, do you mean:
All cells connected to a facet that is on the boundary?
Or
All cells connected to a vertex that is on the boundary?
I want to create a mesh, divide it into top and bottom two parts, create a boundary in the middle, refine the mesh on both sides of the boundary
Are you using legacy dolfin or dolfinx?
I’m using the legacy dolfin
Consider the following MWE:
import dolfin
mesh = dolfin.UnitSquareMesh(10, 10)
class Midline(dolfin.SubDomain):
def inside(self, x, on_boundary):
return dolfin.near(x[0], 0.5)
ff = dolfin.MeshFunction("bool", mesh, mesh.topology().dim()-1, False)
Midline().mark(ff, True)
new_mesh = dolfin.refine(mesh, ff)
with dolfin.XDMFFile("mesh.xdmf") as f:
f.write(new_mesh)
type or paste code here
from fenics import *
import matplotlib.pyplot as plt
import numpy as np
from mshr import *
L = 10e-6
W = 2505e-9
W_bulk = 2.5e-6
Gap = 5e-9
nx = 100
ny = 25
rectangle = Rectangle(Point(0 , 0) , Point(L , W) )
subdomain1 = Rectangle(Point(3e-6 , 0), Point(10e-6 , 2.5e-6))
subdomain2 = Rectangle(Point(13e-9 ,0), Point(3e-6 , 2.5e-6))
subdomain3 = Rectangle(Point(3e-9 , 0), Point(13e-9 , 2.5e-6))
subdomain4 = Rectangle(Point(0 , 0), Point(3e-9 , 2.5e-6))
subdomain5 = Rectangle(Point(0 , 2.5e-6), Point(10e-6 , W))
domain = rectangle - subdomain1 - subdomain2 - subdomain3 - subdomain4 - subdomain5
mesh = generate_mesh(domain, 32)
subdomain_markers = MeshFunction(“size_t”, mesh, mesh.topology().dim())
subdomain_markers.set_all(0)
class SubDomain1(SubDomain):
def inside(self, x, on_boundary):
return between(x[0], (3e-6, 10e-6)) and between(x[1], (0, 2.5e-6))
class SubDomain2(SubDomain):
def inside(self, x, on_boundary):
return between(x[0], (13e-9, 3e-6)) and between(x[1], (0, 2.5e-6))
class SubDomain3(SubDomain):
def inside(self, x, on_boundary):
return between(x[0], (3e-9, 13e-9)) and between(x[1], (0, 2.5e-6))
class SubDomain4(SubDomain):
def inside(self, x, on_boundary):
return between(x[0], (0, 3e-9)) and between(x[1], (0, 2.5e-6))
class SubDomain5(SubDomain):
def inside(self, x, on_boundary):
return between(x[0], (0, 10e-6)) and between(x[1], (2.5e-6, W))
subdomain1_marker = SubDomain1()
subdomain1_marker.mark(subdomain_markers, 1)
subdomain2_marker = SubDomain2()
subdomain2_marker.mark(subdomain_markers, 2)
subdomain3_marker = SubDomain1()
subdomain3_marker.mark(subdomain_markers, 3)
subdomain4_marker = SubDomain2()
subdomain4_marker.mark(subdomain_markers, 4)
subdomain5_marker = SubDomain1()
subdomain5_marker.mark(subdomain_markers, 5)
for i in range(1, 6): # 假设有5个子域
mesh = refine(mesh, subdomain_markers, i)
boundary_markers = MeshFunction(“size_t”, mesh, mesh.topology().dim() - 1)
boundary_markers.set_all(0)
class BoundaryBetween(SubDomain):
def inside(self, x, on_boundary):
# 标记所有子域之间的边界点
return on_boundary and (
near(x[0], 3e-6) or near(x[0], 13e-9) or near(x[0], 3e-9) or near(x[1], 2.5e-6)
)
boundary_between = BoundaryBetween()
boundary_between.mark(boundary_markers, 1)
mesh = refine(mesh, boundary_markers, 2)
plot(mesh)
interactive()
RuntimeError Traceback (most recent call last)
in
47
48 subdomain1_marker = SubDomain1()
—> 49 subdomain1_marker.mark(subdomain_markers, 1)
50
51 subdomain2_marker = SubDomain2()
RuntimeError:
*** -------------------------------------------------------------------------
*** DOLFIN encountered an error. If you are not able to resolve this issue
*** using the information listed below, you can ask for help at
*** fenics-support@googlegroups.com
*** Remember to include the error message listed below and, if possible,
*** include a minimal running example to reproduce the error.
*** -------------------------------------------------------------------------
*** Error: Unable to create progress bar.
*** Reason: Number of steps for progress bar must be positive.
*** Where: This error was encountered inside Progress.cpp.
*** Process: 0
*** DOLFIN version: 2019.1.0
*** Git changeset: 74d7efe1e84d65e9433fd96c50f1d278fa3e3f3f
*** -------------------------------------------------------------------------
Please attach the actual code with 3x` encapsulation, such as
```python
# add code here
```
type or paste code here
from fenics import *
import matplotlib.pyplot as plt
import numpy as np
from mshr import *
L = 10e-6
W = 2505e-9
W_bulk = 2.5e-6
G_ap = 5e-9
nx = 100
ny = 25
rectangle = Rectangle(Point(0 , 0) , Point(L , W) )
subdomain1 = Rectangle(Point(3e-6 , 0), Point(10e-6 , 2.5e-6))
subdomain2 = Rectangle(Point(13e-9 ,0), Point(3e-6 , 2.5e-6))
subdomain3 = Rectangle(Point(3e-9 , 0), Point(13e-9 , 2.5e-6))
subdomain4 = Rectangle(Point(0 , 0), Point(3e-9 , 2.5e-6))
subdomain5 = Rectangle(Point(0 , 2.5e-6), Point(10e-6 , W))
domain = rectangle - subdomain1 - subdomain2 - subdomain3 - subdomain4 - subdomain5
mesh = generate_mesh(domain, 32)
subdomain_markers = MeshFunction("size_t", mesh, mesh.topology().dim())
subdomain_markers.set_all(0)
class SubDomain1(SubDomain):
def inside(self, x, on_boundary):
return between(x[0], (3e-6, 10e-6)) and between(x[1], (0, 2.5e-6))
class SubDomain2(SubDomain):
def inside(self, x, on_boundary):
return between(x[0], (13e-9, 3e-6)) and between(x[1], (0, 2.5e-6))
class SubDomain3(SubDomain):
def inside(self, x, on_boundary):
return between(x[0], (3e-9, 13e-9)) and between(x[1], (0, 2.5e-6))
class SubDomain4(SubDomain):
def inside(self, x, on_boundary):
return between(x[0], (0, 3e-9)) and between(x[1], (0, 2.5e-6))
class SubDomain5(SubDomain):
def inside(self, x, on_boundary):
return between(x[0], (0, 10e-6)) and between(x[1], (2.5e-6, W))
subdomain1_marker = SubDomain1()
subdomain1_marker.mark(subdomain_markers, 1)
subdomain2_marker = SubDomain2()
subdomain2_marker.mark(subdomain_markers, 2)
subdomain3_marker = SubDomain1()
subdomain3_marker.mark(subdomain_markers, 3)
subdomain4_marker = SubDomain2()
subdomain4_marker.mark(subdomain_markers, 4)
subdomain5_marker = SubDomain1()
subdomain5_marker.mark(subdomain_markers, 5)
for i in range(1, 6):
mesh = refine(mesh, subdomain_markers, i)
boundary_markers = MeshFunction("size_t", mesh, mesh.topology().dim() - 1)
boundary_markers.set_all(0)
class BoundaryBetween(SubDomain):
def inside(self, x, on_boundary):
return on_boundary and (
near(x[0], 3e-6) or near(x[0], 13e-9) or near(x[0], 3e-9) or near(x[1], 2.5e-6)
)
boundary_between = BoundaryBetween()
boundary_between.mark(boundary_markers, 1)
mesh = refine(mesh, boundary_markers, 2)
plot(mesh)
interactive()
RuntimeError Traceback (most recent call last)
in
47
48 subdomain1_marker = SubDomain1()
—> 49 subdomain1_marker.mark(subdomain_markers, 1)
50
51 subdomain2_marker = SubDomain2()
RuntimeError:
*** -------------------------------------------------------------------------
*** DOLFIN encountered an error. If you are not able to resolve this issue
*** using the information listed below, you can ask for help at
*** fenics-support@googlegroups.com
*** Remember to include the error message listed below and, if possible,
*** include a minimal running example to reproduce the error.
*** -------------------------------------------------------------------------
*** Error: Unable to create progress bar.
*** Reason: Number of steps for progress bar must be positive.
*** Where: This error was encountered inside Progress.cpp.
*** Process: 0
*** DOLFIN version: 2019.1.0
*** Git changeset: 74d7efe1e84d65e9433fd96c50f1d278fa3e3f3f
*** -------------------------------------------------------------------------
You cannot use MeshFunction
s that are not booleans when you want to refine your grid. i.e. you need to do:
from IPython import embed
from fenics import *
import matplotlib.pyplot as plt
import numpy as np
from mshr import *
L = 10e-6
W = 2505e-9
W_bulk = 2.5e-6
G_ap = 5e-9
nx = 100
ny = 25
rectangle = Rectangle(Point(0, 0), Point(L, W))
subdomain1 = Rectangle(Point(3e-6, 0), Point(10e-6, 2.5e-6))
subdomain2 = Rectangle(Point(13e-9, 0), Point(3e-6, 2.5e-6))
subdomain3 = Rectangle(Point(3e-9, 0), Point(13e-9, 2.5e-6))
subdomain4 = Rectangle(Point(0, 0), Point(3e-9, 2.5e-6))
subdomain5 = Rectangle(Point(0, 2.5e-6), Point(10e-6, W))
domain = rectangle - subdomain1 - subdomain2 - \
subdomain3 - subdomain4 - subdomain5
mesh = generate_mesh(domain, 64)
subdomain_markers = MeshFunction("bool", mesh, mesh.topology().dim(), False)
class SubDomain1(SubDomain):
def inside(self, x, on_boundary):
return between(x[0], (3e-6, 10e-6)) and between(x[1], (0, 2.5e-6))
class SubDomain2(SubDomain):
def inside(self, x, on_boundary):
return between(x[0], (13e-9, 3e-6)) and between(x[1], (0, 2.5e-6))
class SubDomain3(SubDomain):
def inside(self, x, on_boundary):
return between(x[0], (3e-9, 13e-9)) and between(x[1], (0, 2.5e-6))
class SubDomain4(SubDomain):
def inside(self, x, on_boundary):
return between(x[0], (0, 3e-9)) and between(x[1], (0, 2.5e-6))
class SubDomain5(SubDomain):
def inside(self, x, on_boundary):
return between(x[0], (0, 10e-6)) and between(x[1], (2.5e-6, W))
subdomain1_marker = SubDomain1()
subdomain1_marker.mark(subdomain_markers, True)
subdomain2_marker = SubDomain2()
subdomain2_marker.mark(subdomain_markers, True)
subdomain3_marker = SubDomain1()
subdomain3_marker.mark(subdomain_markers, True)
subdomain4_marker = SubDomain2()
subdomain4_marker.mark(subdomain_markers, True)
subdomain5_marker = SubDomain1()
subdomain5_marker.mark(subdomain_markers, True)
mesh = refine(mesh, subdomain_markers)
however, in your initial mesh, there are no cells (print mesh.num_cells()
before refining), so you have to wok on your mesh generation. It is likely that using a mesh of order 1e-6 is not a good idea. You should scale your problem so that the lenght scale of the mesh is of order 1.