8
$\begingroup$

How to assign marker at the boundary edges as 1, 2, 3, 4 respectively and set all of the inside elements of region as 0? for example:

enter image description here

Code:

<< NDSolve`FEM`
bmesh = ToBoundaryMesh[Disk[{0, 0}, 0.5]];
ToElementMesh[bmesh]["Wireframe"]

enter image description here

Thank you very much.

$\endgroup$
1
  • $\begingroup$ @RunnyKine, I think I can get what I want from your answer, let me work on it. Thanks $\endgroup$
    – user1362
    Apr 15 '16 at 23:24
5
$\begingroup$

Since this question has a FEM tag, I assume that the mesh is for applying boundary conditions to a PDE. If that is the case, then the solution suggested by @RunnyKine can be improved.

What you are looking for are the "PointMarkerFunction" and the "BoundaryMarkerFunction". Now, it is important to understand that markers can be applied to points for DirichletConditions via PointElements, to edges/surfaces for NeumannValues via BoundaryElements and to region components via MeshElements for PDE coefficients. Once markers are in a mesh these are independent from each other. That means a NeumannValue that looks for a ElementMaker does not care about markers in point or mesh elements only about markers in boundary elements. So if you ask for markers in edges that will ever only be useful for NeumannValues.

To get your requested marker in the mesh you can use a small function

Needs["NDSolve`FEM`"]
boundaryMarkerFunction = 
  Compile[{{boundaryElementCoords, _Real, 
     3}, {pointMarkres, _Integer, 2}},
   Range[Length[boundaryElementCoords]]];

This is going to return a marker for every boundary element. To create the mesh use:

mesh = ToElementMesh[Disk[{0, 0}, 0.5], 
   "BoundaryMarkerFunction" -> 
    boundaryMarkerFunction    
(*Optional for better visualization of this example *)   
   "MaxCellMeasure" -> 0.1,
   "MaxBoundaryCellMeasure" -> 0.2,
   PrecisionGoal -> 10^-3
   ];

This then gives

Show[mesh[
  "Wireframe"["MeshElement" -> "BoundaryElements", 
   "MeshElementMarkerStyle" -> Red]]
 , mesh["Wireframe"["MeshElement" -> "MeshElements", 
   "MeshElementMarkerStyle" -> Blue]]
 ]

enter image description here

There are a few things to note: First, the default mesh element marker is 0, so there was no need to set anything. If you want a different marker then 0, you can use "RegionMarker"\[Rule]{{{0,0},1}} to specify a 1 marker.

Next, if you look at the PointElement markers you'll see:

Show[mesh[
  "Wireframe"["MeshElement" -> "PointElements", 
   "MeshElementMarkerStyle" -> Magenta]]
 , mesh["Wireframe"]
 ]

enter image description here

So, the makers there have been derived from the edge markers specified. You can overwrite that by specifying a PointMarkerFunction. There are a few examples in the FEM documentation of ToElementMesh in the options sections and in the ElementMesh generation tutorial.

Why should you use ToElementMesh for that? To main reasons: First the FEM code will not understand the labels specified for the mesh region (that could be made to work) but secondly, the mesh is much more accurate:

(* MeshRegion *)
\[Pi] (1/2)^2 - 0.782472
0.0029261633974483336`

(* ElementMesh *)
\[Pi] (1/2)^2 - Total[Join @@ mesh["MeshElementMeasure"]]
0.0000174314511414142`

So, even for such a coarse FEM ElementMesh, the accuracy of the area is much better because it's a second order mesh and the MeshRegion is first order only. If you do FEM then I'd recommend to use ToElementMesh

$\endgroup$
3
  • $\begingroup$ Do you think some of these FEM functionalities will be built-in in future versions? $\endgroup$
    – RunnyKine
    Apr 18 '16 at 16:29
  • 1
    $\begingroup$ @RunnyKine, I guess if there are enough requests for that (you may want to send that request to the support) it may happen. $\endgroup$
    – user21
    Apr 18 '16 at 20:18
  • $\begingroup$ Ok. Will send a request. Thanks. $\endgroup$
    – RunnyKine
    Apr 18 '16 at 20:48
10
$\begingroup$

Here is an approach using built-in functions:

reg = DiscretizeRegion[Disk[{0, 0}, 0.5], MeshCellHighlight -> {{2, All} -> White}]

Mathematica graphics

Now, we obtain the outer points:

int = MeshCellIndex[reg, {0, "Interior"}][[All,2]] (* interior points *)
ext = Complement[MeshCellIndex[reg, 0][[All,2]], int] (* exterior points *)

Finally, we set the properties of the region (interior and exterior points) using PropertyValue and MeshCellLabel:

PropertyValue[{reg, {0, ext}}, MeshCellLabel] = 
  Style[#, Bold, Darker @ Red, 8] & /@ Range @ Length @ ext;

PropertyValue[{reg, {0, int}}, MeshCellLabel] = 
  Style[#, Bold, Darker @ Blue, 8] & /@ Table[0, Length @ int];

Let's visualize:

reg

Mathematica graphics

Note that this is still very much a region and you can compute various properties as usual:

Area @ reg

0.782472

$\endgroup$
1
  • $\begingroup$ I added an answer that refers to yours and I wanted to notify you about that. $\endgroup$
    – user21
    Apr 18 '16 at 7:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy