The area of a unit disk is $2\pi$? (NIntegrate over a numerical region)

According to the documentation of ToNumericalRegion:

The region r should be a constant region for which ConstantRegionQ gives True.

However,

Needs["NDSolve`FEM`"]
inDisk[x_?NumericQ, y_?NumericQ] := x^2 + y^2 <= 1
r = ToNumericalRegion[ImplicitRegion[inDisk[x, y] == True, {{x, -1, 1}, {y, -1, 1}}]];
ConstantRegionQ @ r

False

so your region definition doesn't meet the requirements of ToNumericalRegion.

The following works.

r = ImplicitRegion[x^2 + y^2 <= 1, {{x, -1, 1}, {y, -1, 1}}];
ConstantRegionQ @ r

True

Area @ r

π

NIntegrate[1, {x, y} ∈ r]

3.14159


I noticed that ContourPlot does an awesome job discretizing the region. I don't know how this scales and how complicated your real problem is, but for the disk it works quite well:

ContourPlot excludes complex numbers from the region by default, so a convenient way to plot the region is to set the function value to the imaginary unit if the point is outside the region. Then we can get the mesh by using DiscretizeGraphics.

inDisk[x_?NumericQ, y_?NumericQ] := x^2 + y^2 <= 1;
mr = DiscretizeGraphics@
   ContourPlot[
    Piecewise[{{0, inDisk[x, y]}}, I], {x, -1, 1}, {y, -1, 1}, 
    Mesh -> All, PlotPoints -> 15]

enter image description here

If we want we can simplify the mesh:

simplemr = 
  TriangulateMesh[mr, MaxCellMeasure -> Infinity, 
   PerformanceGoal -> "Speed"]

enter image description here

And then integrate over this region:

NIntegrate[1, {x, y} ∈ simplemr]

3.14027

Not perfect, but close.

Edit: A cleaner solution might be to use RegionFunction instead of the imaginary unit, for example:

inDisk[x_?NumericQ, y_?NumericQ, f_] := x^2 + y^2 <= 1;
mr = BoundaryDiscretizeGraphics@
   ContourPlot[0, {x, -1, 1}, {y, -1, 1}, PlotPoints -> 5, 
    MaxRecursion -> 6, RegionFunction -> inDisk];
NIntegrate[1, {x, y} ∈ mr]

3.14118

Note that I added an argument f to inDisk, because that's the form RegionFunction expects. Also BoundaryDiscretizeGraphics should suffice here. Larger values of MaxRecursion can make the mesh region more accurate.


The circumference of a unit disk is 2π.

When you hide the internal of the function and the == is the only thing ImplicitRegion does see it tries to construct a region with RegionDimension 1:

Needs["NDSolve`FEM`"]
inDisk[x_?NumericQ, y_?NumericQ] := x^2 + y^2 <= 1
nrDisk = ToNumericalRegion[
   ImplicitRegion[inDisk[x, y] == True, {{x, -1, 1}, {y, -1, 1}}]];
2 Pi - NIntegrate[1, {x, y} \[Element] nrDisk]

0.00264963

What will work better in this case is to use:

mesh = ToElementMesh[
   ImplicitRegion[
    If[inDisk[x, y], 1, -1] > 0, {{x, -1, 1}, {y, -1, 1}}]];
Pi - NIntegrate[1, {x, y} \[Element] mesh]
7.120859435438831`*^-7

Note that since there is no symbolic region associated with the mesh it's not really necessary to put the mesh in a NumericalRegion.

You can do this:

nr = ToNumericalRegion[
   ImplicitRegion[
    If[inDisk[x, y], 1, -1] > 0, {{x, -1, 1}, {y, -1, 1}}]];
ToElementMesh[nr]
Pi - NIntegrate[1, {x, y} \[Element] nr]
3.9561815157185265`*^-7

I'd need to look at why one needs to help NIntegrate with the numerical region in this case by calling ToElementMesh prior to calling NIntegrate.

There is a suggestion that ImplicitRegion should be able handle boolean region specifications better but that's out of my control so I can not say when and if this will come.