12
$\begingroup$

Thanks to @user21 response and FEMAddOns I have been able to create a multi-region mesh. I am trying to make a smooth transitional mesh refinement with respect to a certain subregion. I plan to do this for certain polygons inside the mesh domain later, but for now I tried it on a simple test case:

<< NDSolve`FEM`
<< FEMAddOns`

rmid = ImplicitRegion[  
  Sin[x] - 0.5 x <= y && y <= Sin [x] - 0.25 x + 0.2 && x >= 0 && 
   x <= 3 && y >= -1, {x, y}];

rup = ImplicitRegion[  
  Sin [x] - 0.25 x + 0.2 <= y && y <= 1.5 && x >= 0 && x <= 3, {x, y}];

rdown = ImplicitRegion[  
  Sin[x] - 0.5 x >= y && y >= -1 && x >= 0 && x <= 3, {x, y}];

uniondomain = RegionUnion[rup, rdown, rmid];
ndomain = ToNumericalRegion@uniondomain;
symbounds = RegionBounds[uniondomain];
bm1 = ToBoundaryMesh[rmid, symbounds];
bm2 = ToBoundaryMesh[rup, symbounds];
bm3 = ToBoundaryMesh[rdown, symbounds];
bm = BoundaryElementMeshJoin[bm1, bm2, bm3];

mesh1 = ToElementMesh[bm, 
   "RegionMarker" -> {{{1.45`, 1.1}, 1, 0.05}, {{1.5`, 0.6}, 2, 
      0.003}, {{1.54`, -0.38`}, 3, 0.05}}];
mesh1["Wireframe"[
  "MeshElementStyle" -> {FaceForm[Red], FaceForm[LightBlue], 
    FaceForm[Yellow]}, ImageSize -> Medium]]

which is good so far:

enter image description here

However, I can't get the refinement function to work as function of distance from the middle high-resolution region.

f = Function[{vertices, area}, Block[{x, y}, {x, y} = Mean[vertices];
    If[RegionMember[rmid, {x, y}], area > 0.003, 
     area > 0.003 + 20*(RegionDistance[rmid])^2[{x, y}]]]];
mesh2 = ToElementMesh[bm, 
   "RegionMarker" -> {{{1.45`, 1.1}, 1, 0.05}, {{1.5`, 0.6}, 2, 
      0.003}, {{1.54`, -0.38`}, 3, 0.05}}, 
   MeshRefinementFunction -> f];
mesh2["Wireframe"[
  "MeshElementStyle" -> {FaceForm[Red], FaceForm[LightBlue], 
    FaceForm[Yellow]}, ImageSize -> Medium]]

I've been playing with various functions with no luck. I also used the DistMeshgenerator, but that one was even harder because I didn't know how to get it to work for a multi-region mesh. Is there a better way than RegionDistance to do this or it is my refinement function that needs to be somewhat more effective?

Just to clarify, I know for this case the boundaries have function definitions and a simple distance can be obtained based on those, but I am looking for a more general solution that can be used on arbitrary regions defined by polygons etc.

$\endgroup$

1 Answer 1

8
$\begingroup$

For this to be efficient you'd need to use discretized versions of rmid. Note that I used SignedRegionDistance - RegionDistance should also work, but the given region distance function did not provide a refinement (too coarse, I believe). Here is an example:

f = With[{rmf = RegionMember[DiscretizeRegion[rmid]], 
    rdf = SignedRegionDistance[DiscretizeRegion[rmid]]},
   Function[{vertices, area}, Block[{x, y}, {x, y} = Mean[vertices];
     If[rmf[{x, y}], area > 0.0005, area > rdf[{x, y}]/200]]]];
mesh2 = ToElementMesh[bm, 
   "RegionMarker" -> {{{1.45`, 1.1}, 1, 0.05}, {{1.5`, 0.6}, 2, 
      0.003}, {{1.54`, -0.38`}, 3, 0.05}}, 
   MeshRefinementFunction -> f];
mesh2["Wireframe"[
  "MeshElementStyle" -> {FaceForm[Red], FaceForm[LightBlue], 
    FaceForm[Yellow]}, ImageSize -> Medium]]

enter image description here

$\endgroup$
1
  • 2
    $\begingroup$ As always, you solved it very nice and elegant! This actually works pretty well, especially if the boundaries are required to be more finely resolved in some applications. For my application, I want them to be gradually from the middle region and larger, so f = With[{rmf = RegionMember[DiscretizeRegion[rmid]], rdf = SignedRegionDistance[DiscretizeRegion[rmid]]}, Function[{vertices, area}, Block[{x, y}, {x, y} = Mean[vertices]; If[rmf[{x, y}], area > 0.0005, area > 0.0005 + rdf[{x, y}]/200]]]] gives a nice transition with your solution. (since distances are zero on boundaries) $\endgroup$
    – MathX
    Feb 21 at 15:00

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.