10
$\begingroup$

In this simple example I try to mesh a rectangle, the mesh should include a fixed line.

Using "IncludePoints" I get

Needs["NDSolve`FEM`"] addpts = Table[{1/2, yi}, {yi, Subdivide[1/3, 2/3, 3]}]; mesh = ToElementMesh[ Rectangle[{0, 0}, {1, 1}] , "MeshOrder" -> 1,MeshElementType -> "TriangleElement" , "IncludePoints" -> addpts ] Show[{mesh["Wireframe"], Graphics[{Thickness[Large], PointSize[Large], , Red, Line[addpts],Point[addpts]}]}] 

enter image description here

The result does not quite meet my expectations yet.

How can I force the meshing to include the complete red line without the element sides intersecting the line?

I tried without success to mesh RegionUnion[Rectangle[{0, 0}, {1, 1} ], Line[{{1/2, 1/3}, {1/2, 2/3 }}]]

Any idea how to realize this special meshing? Thanks!

$\endgroup$
1

2 Answers 2

10
$\begingroup$

The method I have used is to explicitly create a boundary mesh first. Although I find it a bit clumsy.

Needs["NDSolve`FEM`"] rectangleCoords = {{0, 0}, {0, 1}, {1, 1}, {1, 0}}; interiorCoords = Table[{1/2, yi}, {yi, Subdivide[1/3, 2/3, 3]}]; coordinates = Join[rectangleCoords, interiorCoords]; rectangle = {{1, 2}, {2, 3}, {3, 4}, {4, 1}}; interiorLine = {{5, 6}, {6, 7}, {7, 8}}; bmesh = ToBoundaryMesh[ "Coordinates" -> coordinates, "BoundaryElements" -> {LineElement[rectangle], LineElement[interiorLine]} ]; bmesh["Wireframe"]; mesh = ToElementMesh[bmesh]; graphic = mesh["Wireframe"]; Show[graphic, Epilog -> {Red, PointSize[.02], Point[interiorCoords]}] 

enter image description here

$\endgroup$
5
  • $\begingroup$ Clever answer, thanks! $\endgroup$ Commented Aug 16 at 16:20
  • $\begingroup$ "clumsy" is a fine description. Possible generalization with an inner fixed curve remains unclear to me $\endgroup$ Commented Aug 16 at 16:28
  • 1
    $\begingroup$ Yes. With COMSOL it is easy to place a line inside a rectangle. Then the mesher respects the line. The MMA accomplishments in FEM numerics are really impressive. But we need improvements in geometry creation, subregion and boundary selection, and meshing to advance beyond solving toy demo models. $\endgroup$ Commented Aug 16 at 22:33
  • 1
    $\begingroup$ There is a section on Element Meshes with Subregions and also a section on Internal boundaries in the OpenCascadeLink. You can generate complex geometries and meshes as shown on the Finite Element page $\endgroup$ Commented Aug 19 at 4:26
  • $\begingroup$ @user21 Thanks for the links! $\endgroup$ Commented Aug 19 at 9:06
10
$\begingroup$

You are mixing components of different dimensions. If you do instead:

ru = RegionUnion[RegionBoundary[Rectangle[{0, 0}, {1, 1}]], Line[{{1/2, 1/3}, {1/2, 2/3}}]] 

enter image description here

You can then use:

mesh = ToElementMesh[DiscretizeRegion[ru]] Show[mesh["Wireframe"], Epilog -> {Red, PointSize[.02], Line[{{1/2, 1/3}, {1/2, 2/3}}]}] 

enter image description here

This generalizes nicely:

ru = RegionUnion[RegionBoundary[Rectangle[{0, 0}, {1, 1}]], Circle[{1/2, 1/2}, 1/4, {0, \[Pi]}]]; mesh = ToElementMesh[DiscretizeRegion[ru]]; Show[mesh["Wireframe"], Epilog -> {Red, PointSize[.02], Circle[{1/2, 1/2}, 1/4, {0, \[Pi]}]}] 

enter image description here

I'll try to remove the need to call DiscretizeRegion in the 2D case for the next version.

$\endgroup$
11
  • $\begingroup$ Thanks for your very helpful answer! $\endgroup$ Commented Aug 18 at 13:20
  • $\begingroup$ How could I make your answer work in Mathematica v12.2? Thanks! $\endgroup$ Commented Aug 18 at 14:44
  • 1
    $\begingroup$ This answer is better than mine. Thanks @user21. $\endgroup$ Commented Aug 18 at 15:50
  • 2
    $\begingroup$ @azerbajdzan @UlrichNeumann Discretize the region before union. Clear[ru, mesh]; ru = RegionUnion[ DiscretizeRegion@RegionBoundary[Rectangle[{0, 0}, {1, 1}]], DiscretizeRegion@Circle[{1/2, 1/2}, 1/4, {0, \[Pi]}]]; mesh = ToElementMesh[ru, AccuracyGoal -> 2]; Show[mesh["Wireframe"], Epilog -> {Red, PointSize[.02], Circle[{1/2, 1/2}, 1/4, {0, \[Pi]}]}] $\endgroup$ Commented Aug 18 at 23:03
  • 3
    $\begingroup$ @azerbajdzan Set AccuracyGoal in the DiscretizeRegion. Clear[ru, mesh]; ru = RegionUnion[ DiscretizeRegion[RegionBoundary[Rectangle[{0, 0}, {1, 1}]], MaxCellMeasure -> \[Infinity]], DiscretizeRegion[Circle[{1/2, 1/2}, 1/4, {0, \[Pi]}], MaxCellMeasure -> \[Infinity], AccuracyGoal -> 3]]; mesh = ToElementMesh[ru]; Show[mesh["Wireframe"], Epilog -> {Red, PointSize[.02]}] . $\endgroup$ Commented Aug 18 at 23:10

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.