# Mesh Generation help

I am having trouble generating a mesh of a rectangle inside another rectangle. I have been following the steps on this article: https://reference.wolfram.com/language/PDEModels/tutorial/HeatTransfer/ModelCollection/ShrinkFitting.html

However, I have been getting an error that I cannot combine the inner rectangle to the outer rectangle with a hole in it. It says "Coordinate Skeleton[2] should be a pair of numbers, or a Scaled or Offset form." in the debugger. Here is my code, it is more or less what the tutorial does.

bathx = 30;
bathy = 30;
plastic = Rectangle[{10, 10}, {20, 20}];
waterbath =
RegionDifference[Rectangle[{0, 0}, {bathx, bathy}], plastic];
\[CapitalOmega] = RegionUnion[plastic, waterbath];
bounds = 1.1*{{0, bathx}, {0, bathy}};
mesh = ToElementMesh[\[CapitalOmega], bounds];

Show[mesh["Wireframe"]]

Subscript[bm, w] = ToBoundaryMesh[waterbath];
Subscript[bm, p] = ToBoundaryMesh[plastic];
Needs["FEMAddOns"]
bmesh = FEMUtilsBoundaryElementMeshJoin[Subscript[bm, w],
Subscript[bm, p]]

waterbathCoordinate = {1, 1};
plasticCoordinate = {15, 15};
markerColors = {Blue, Orange};
markerCoordinates = {{waterbathCoordinate}, {plasticCoordinate}};

Show[{bmesh["Wireframe"],
Point /@ #2} &, {markerColors, markerCoordinates}]]}]

markerSpecification = {{plasticCoordinate, 1}, {waterbathCoordinate,
2}};

mesh2 = ToElementMesh[bmesh, "RegionMarker" -> markerSpecification,
"MaxCellMeasure" -> 5*10^-6];
GraphicsRow[{mesh2[
"Wireframe"[
"MeshElementStyle" ->
Map[Directive[FaceForm[#], EdgeForm[]] &, markerColors]]],
mesh2["Wireframe"[
Sequence[PlotRange -> {bounds},
"MeshElementStyle" -> Map[FaceForm[#] &, markerColors]]]]}]

Show[{mesh2["Wireframe"]}]
$$$$

• Your MaxCellMeasure on mesh2 is tiny and it crashed my kernel. Try something more like "MaxCellMeasure" -> 1. Jul 24, 2020 at 0:08

The linked example was for a much smaller domain and hence too small of a mesh size specification. The following code should accomplish what you need.

(* Uncomment if not installed *)
bathx = 30;
bathy = 30;
bounds = 1.1*{{0, bathx}, {0, bathy}};
plastic = Rectangle[{10, 10}, {20, 20}];
waterbath = Rectangle[{0, 0}, {bathx, bathy}];

bmw = ToBoundaryMesh[waterbath];
bmp = ToBoundaryMesh[plastic];
bmesh = BoundaryElementMeshJoin[bmw, bmp];

waterbathCoordinate = {1, 1};
plasticCoordinate = {15, 15};
markerColors = {Blue, Orange};
markerCoordinates = {{waterbathCoordinate}, {plasticCoordinate}};

Show[{bmesh["Wireframe"],
Point /@ #2} &, {markerColors, markerCoordinates}]]}]

markerSpecification = {{plasticCoordinate, 1}, {waterbathCoordinate,
2}};

mesh2 = ToElementMesh[bmesh, "RegionMarker" -> markerSpecification,
"MaxCellMeasure" -> {"Length" -> 1}];
GraphicsRow[{mesh2[
"Wireframe"[
"MeshElementStyle" ->
Map[Directive[FaceForm[#], EdgeForm[]] &, markerColors]]],
mesh2["Wireframe"[
Sequence[PlotRange -> {bounds},
"MeshElementStyle" -> Map[FaceForm[#] &, markerColors]]]]}]
mesh2["Wireframe"]


Tim's answer is spot on. Here is a slightly different approach that uses a trick. The idea is to use the waterbath as the region and tell ToElementMesh to also mesh the interior region (the plastic). If this approach is applicable in your case then you can reduce the amount of code somewhat.

Needs["NDSolveFEM"]
bathx = 30;
bathy = 30;
plastic = Rectangle[{10, 10}, {20, 20}];
waterbath =
RegionDifference[Rectangle[{0, 0}, {bathx, bathy}], plastic];
waterbathCoordinate = {1, 1};
plasticCoordinate = {15, 15};
markerColors = {Blue, Orange};
markerSpecification = {{plasticCoordinate, 1,
0.25}, {waterbathCoordinate, 2, 1.}};
mesh = ToElementMesh[waterbath, "RegionHoles" -> None,
"RegionMarker" -> markerSpecification]
GraphicsRow[{mesh[
"Wireframe"[
"MeshElementStyle" ->
Map[Directive[FaceForm[#], EdgeForm[]] &, markerColors]]],
mesh["Wireframe"[
"MeshElementStyle" -> Map[FaceForm[#] &, markerColors]]]}]


Also, note that I used a different granularity in the subsections of the mesh.