TransWikia.com

Mesh Generation help

Mathematica Asked by kmulc on January 13, 2021

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];
ResourceFunction["FEMAddOnsInstall"][]
Needs["FEMAddOns`"]
bmesh = FEMUtils`BoundaryElementMeshJoin[Subscript[bm, w], 
  Subscript[bm, p]]

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

Show[{bmesh["Wireframe"], 
  Graphics[MapThread[{PointSize[0.02], #1, 
      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"]}]
```

2 Answers

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["NDSolve`FEM`"]
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]]]}]

enter image description here

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

Answered by user21 on January 13, 2021

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 *)
(*ResourceFunction["FEMAddOnsInstall"][]*)
Needs["FEMAddOns`"]
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"], 
  Graphics[MapThread[{PointSize[0.02], #1, 
      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"]

Output

Answered by Tim Laska on January 13, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP