# MeshRefinementFunction analogue for ToElementMesh

MeshRefinementFunction according to the documentation is an option for DiscretizeRegion. Is there an analogue for ToElementMesh?

The following code

Needs["NDSolveFEM"];
f = Function[{vertices, area}, If[Mean[vertices] > 1, area > 0.1, area > 0.01]];
ToElementMesh[Interval[{0, 2}], MeshRefinementFunction -> f]


gives the error

ToElementMesh::mrff: The MeshRefinementFunction Function[{vertices, area}, If[Mean[vertices]>1, area > 0.1, area > 0.01]] is not valid and will be ignored. The function does not return either True or False.

so I have to use an ugly workaround

mymesh = DiscretizeRegion[Interval[{0, 2}], MeshRefinementFunction -> f];
ToElementMesh[mymesh]

• I found a similar question here, unanswered: community.wolfram.com/groups/-/m/t/1928814 – Yasha Gindikin Jun 24 '20 at 15:16
• The error message says it all. Try to apply your function f to an actual list of vertex positions vertices and a number area. Then you will see that the If statement does not evaluate because Mean[vertices] is a vector and not a number. – Henrik Schumacher Jun 24 '20 at 15:26
• @HenrikSchumacher I am afraid this is a too smart observation for me.:( How should I fix the function f to work with ToElementMesh? – Yasha Gindikin Jun 24 '20 at 15:46
• That depends on what you try to express by Mean[vertices] > 1... Maybe you meant to write f = Function[{vertices, area}, If[Thread[Mean[vertices] > 1], area > 0.1, area > 0.01]]? > might thread over vectors in other languages, but it does not in Mathematica: Things like {0,0,0}>1 do not produce True or False, and thus If[{0,0,0}>1, [...], [...]] stays just unevaluated. So no True nor False either. – Henrik Schumacher Jun 24 '20 at 15:50
• @HenrikSchumacher I just wanted a fine mesh for 0<x<1 and a rough mesh for x>1. – Yasha Gindikin Jun 24 '20 at 15:52

Update

The real observation is that MeshRefinementFunction does not work for 1D with ToElementMesh. Yes, that's unfortunately the case but you can easily use

Needs["NDSolveFEM"];
f = Function[{vertices, area},
If[Mean[vertices] > 1, area > 0.1, area > 0.01]];
mr = DiscretizeRegion[Interval[{0, 2}], MeshRefinementFunction -> f];
ToElementMesh[mr]


I'll add a note to the documentation until this is implemented.

• BTW, calling mr in a context like this ParallelTable[NDEigenvalues[...,x\in mr]] does not work. Like the mr  is not distributed across the parallel kernels. However, explicit construction like ParallelTable[NDEigenvalues[...,x\in ToElementMesh[DiscretizeRegion[...]]]] does work, fortunately. – Yasha Gindikin Jun 24 '20 at 18:08