There is two ways you can go about this. As Anton noted, NDSolve will return Indeterimate
for solution function evaluations that are outside of the region. This is the correct behavior for the finite element method as generally speaking no information is available beyond the boundary condition. That behavior, however, can be changed. This is explained in the ExtrapolationHandler section of the NDSolve Finite Element Options tutorial.
Clear[u];
reg = Ball[{0, 0, 0}, 1];
sol = NDSolveValue[{D[u[t, x, y, z], t] - \!\(
\*SubsuperscriptBox[\(\[Del]\), \({x, y, z}\), \(2\)]\(u[t, x, y,
z]\)\) == NeumannValue[0, True],
u[0, x, y, z] == 0.5 Tanh[30 z] + 0.5},
u, {t, 0, 1}, {x, y, z} \[Element] reg,
"ExtrapolationHandler" -> {Automatic,
"WarningMessage" -> False}]
Now, the function evaluation uses extrapolation and gives no message:
sol[1, 2, 2, 2]
0.46176609059001855`
The second approach would be to use the same mesh both for NDSolve
and NIntegrate
. First we create a boundary mesh that has an interface at z==0
:
Needs["OpenCascadeLink`"]
s1 = OpenCascadeShape[Ball[]];
s2 = OpenCascadeShape[
Polygon[{{-2, -2, 0}, {2, -2, 0}, {2, 2, 0}, {-2, 2, 0}}]];
surface = OpenCascadeShapeFaces[s1];
innerDisk = OpenCascadeShapeIntersection[s1, s2];
boundary = OpenCascadeShapeUnion[Join[surface, {innerDisk}]];
(bmesh = OpenCascadeShapeSurfaceMeshToBoundaryMesh[
boundary])["Wireframe"]
Next, we generate the mesh:
Needs["NDSolve`FEM`"]
mesh = ToElementMesh[bmesh,
"RegionMarker" -> {{{0, 0, -1/2}, 1}, {{0, 0, 1/2}, 2}}];
Let's visualize:
parts = Map[
mesh["Wireframe"[ElementMarker == #[[1]],
"MeshElement" -> "MeshElements",
"ElementMeshDirective" ->
Directive[EdgeForm[], FaceForm[#[[2]]]]]] &, {{1, Gray}, {2,
Orange}}]
Rasterize[Show[parts, PlotRange -> {All, {-0.02, 2}, All}]]
Solve:
sol = NDSolveValue[{D[u[t, x, y, z], t] - \!\(
\*SubsuperscriptBox[\(\[Del]\), \({x, y, z}\), \(2\)]\(u[t, x, y,
z]\)\) == NeumannValue[0, True],
u[0, x, y, z] == 0.5 Tanh[30 z] + 0.5},
u, {t, 0, 1}, {x, y, z} \[Element] mesh]
data = Table[
NIntegrate[If[z > 0, sol[t, x, y, z], 0], {x, y, z} \[Element] mesh,
AccuracyGoal -> 6, PrecisionGoal -> 6], {t, .05, 1, .05}]
ListPlot[data]