I am having trouble integrating over some curved boundaries and was thinking about using the element markers of the boundary mesh for integration rather than conditionals.

Is it possible to use boundary element markers for NIntegrate? I could only find documentation on element markers being used for boundary conditions with NDSolve.

I am hoping to get rid of inaccuracies regarding the tolerance specified with conditional integration as well as making it faster, as I hope it won't have to check the condition on all of the boundary elements, but rather only on the subset of boundary elements regarding the specific region marker.

I am using Mathematica 12.1

Find some example code below, some integration over a cuboid:


(*Mesh generation*)
xmax = 1;
ymax = 1;
zmax = 1;

cubi = Cuboid[{0, 0, 0}, {xmax, ymax, zmax}];
mesh = ToElementMesh[cubi]

bmesh = ToBoundaryMesh[mesh]

(*Mesh and marker visualization*)
groups = bmesh["BoundaryElementMarkerUnion"]
temp = Most[Range[0, 1, 1/(Length[groups])]];
colors = ColorData["BrightBands"][#] & /@ temp;

surfaces = 
   bmesh["Wireframe"[ElementMarker == #, 
       "MeshElementStyle" -> FaceForm[colors[[#]]]]] & /@ groups];

 Show[{bmesh["Edgeframe"], choices /. surfaces}], {{choices, groups}, 
  groups, CheckboxBar}, ControlPlacement -> Top]

  ElementMarker == 
   1]] (*Here I can access the boundary element subset defined by the \
element marker*)

Element Marker stuff

Here is the integration part:

(*Conditional integration*)
tolerance = 1*10^-6;
boundaryFront [x_, y_, z_] := Abs[x] <= tolerance;
boundaryFrontPart[x_, y_, z_][ymin_,ymax_] := (Abs[x] <= tolerance && ymin <= y <= ymax);

areaTest1 = 
  Piecewise[{{1, boundaryFront[x, y, z]}, {0, True}}], {x, y, 
    z} \[Element] 
   mesh] (*does not work, integrating over mesh not boundary mesh*)

areaTest2 = 
  Piecewise[{{1, boundaryFront[x, y, z]}, {0, True}}], {x, y, 
    z} \[Element] bmesh](*works*)

areaTest3 = NIntegrate[
     boundaryFrontPart[x, y, z][0.25 ymax, 0.75 ymax]}, {0, 
     True}}], {x, y, z} \[Element] bmesh(*works, 
  integrating only some y-coords*)

(*Test integrating parts*)
numPieces = 10;
deltaY = ymax/numPieces;
pieces = Table[
      boundaryFrontPart[x, y, z][num*deltaY, (num + 1)*deltaY]}, {0, 
      True}}], {x, y, z} \[Element] bmesh]
  , {num, 0, numPieces - 1}]
areaTest4 = Plus @@ pieces

areaTest5 = NIntegrate[1, {x, y, z} \[Element] bmesh] (*Integrating area of whole bmesh*)

What I would like to do:

   bmeshPart = some function of bmesh and element marker

Does something like this work for you:

FEMNBoundaryIntegrate[1, {x, y, z}, mesh, 
 ElementMarker == 1 || ElementMarker == 3]
  • $\begingroup$ Thanks, this works great. $\endgroup$
    – Tobias
    Sep 28 '21 at 14:52

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.