DirichletCondition doesn't always work with RegionBoundary

I am trying to solve the heat equation on a circle with a square shaped hole in it. It works:

With[{outer = Disk[], inner = Rectangle[{-1/2, -1/2}, {1/2, 1/2}]},
sol = NDSolveValue[{
Laplacian[u[x, y], {x, y}] == 0,
DirichletCondition[
u[x, y] == 0, {x, y} \[Element] RegionBoundary@outer],
DirichletCondition[
u[x, y] ==
1, (Abs[x] == 1/2 && Abs[y] <= 1/2) || (Abs[y] == 1/2 &&
Abs[x] <= 1/2)]},
u, {x, y} \[Element] RegionDifference[outer, inner]]]

(* InterpolatingFunction object *)

DensityPlot[sol[x, y], {x, y} \[Element] Disk[],
ColorFunction -> "TemperatureMap"]


However, when I try to make the inner boundary condition less verbose using RegionBoundary, it fails with an (apparently erroneous) error message:

With[{outer = Disk[], inner = Rectangle[{-1/2, -1/2}, {1/2, 1/2}]},
sol = NDSolveValue[{
Laplacian[u[x, y], {x, y}] == 0,
DirichletCondition[
u[x, y] == 0, {x, y} \[Element] RegionBoundary@outer],
DirichletCondition[
u[x, y] == 1, {x, y} \[Element] RegionBoundary@inner]},
u, {x, y} \[Element] RegionDifference[outer, inner]]]

(* NDSolveValue::bcnop "No places were found on the boundary where \
{x,y}\[Element]Line[{{-(1/2),-(1/2)},{1/2,-(1/2)},{1/2,1/2},{-(1/2),1/\
2},{-(1/2),-(1/2)}}] was True, so DirichletCondition[u==1,{x,y}\
\[Element]Line[{{-(1/2),-(1/2)},{1/2,-(1/2)},{1/2,1/2},{-(1/2),1/2},{-\
(1/2),-(1/2)}}]] will effectively be ignored" *)
(* another InterpolatingFunction *)


And indeed the solution does not seem to make use of that condition, but I can't figure out why it doesn't, or what I should change to make it work.

• DirichletCondition[u[x, y] == 1, {x, y} \[Element] RegionBoundary@inner // N] works better. May 24, 2021 at 8:51

If you use ToElementMesh, you can capture the features of the rectangle much better.

(*Import required FEM package*)
Needs["NDSolveFEM"];
With[{outer = Disk[], inner = Rectangle[{-1 / 2, -1 / 2}, {1 / 2, 1 /
2}]},
(mesh = ToElementMesh[RegionDifference[
outer, inner]])["Wireframe"]
]


If you use the FEM mesh and replace RegionBoundary with RegionMember for the inner surface, then you will get the solution you desire.

With[{outer = Disk[], inner = Rectangle[{-1 / 2, -1 / 2}, {1 / 2, 1 /
2}]},
mesh = ToElementMesh[RegionDifference[
outer, inner]];
sol = NDSolveValue[{
Laplacian[u[x, y], {x, y}] == 0,
DirichletCondition[
u[x, y] == 0, {x, y} ∈ RegionBoundary @ outer],
DirichletCondition[u[
x, y] == 1, {x, y} ∈ RegionMember @ inner]
}, u, {x, y} ∈ mesh]
]

DensityPlot[sol[x, y], {x, y} ∈ mesh,
ColorFunction -> "TemperatureMap"
]


Finally, RegionBoundary may be used if you use a real number to define the rectangle. For example:

With[{outer = Disk[], inner = Rectangle[{-1./ 2, -1 / 2}, {1 / 2, 1 /
2}]},
mesh = ToElementMesh[RegionDifference[
outer, inner]];
sol = NDSolveValue[{
Laplacian[u[x, y], {x, y}] == 0,
DirichletCondition[
u[x, y] == 0, {x, y} ∈ RegionBoundary @ outer],
DirichletCondition[u[
x, y] == 1, {x, y} ∈ RegionBoundary @ inner]
}, u, {x, y} ∈ mesh]
]

DensityPlot[sol[x, y], {x, y} ∈ mesh,
ColorFunction -> "TemperatureMap"
]