I'm trying to follow the documentation for Element Mesh Generation, but somehow I cannot understand it correctly. Here is a simplified version of my real problem.
I'm trying to simulate the temperature distribution in a pipeline. In the pipeline, there should be a fluid (fluid flow) and a solid domain (pipe wall). These 2 domains have different equations and should be connected with each other with NeumannValue
.
E.g. I'd like to have something like this
wall[x_, y_, z_] := ((0.9/10)^2 <= x^2 + y^2 <= 0.1^2) && 0 <= z <= 1
fluid[x_,y_,z_] := x^2 + y^2 < (0.9/10)^2 && 0 <= z <= 1
RegionUnion doesn't give me what I want, because the internal boundary would disappear. Does anyone have an idea?
EDIT:
here is something I tried
- I thought to build a solid region and a fluid region, retrieve their
boundary elements and coordinates and use
ToBoundaryMesh
could work, but it didn't.
000
\[CapitalOmega]1 = ImplicitRegion[wall[x, y, z], {x, y, z}];
With[{mesh = ToElementMesh[\[CapitalOmega]1]},co1 = mesh["Coordinates"]; be1 = mesh["BoundaryElements"];]
\[CapitalOmega]2 = ImplicitRegion[fluid[x, y, z], {x, y, z}];
With[{mesh = ToElementMesh[\[CapitalOmega]2]},
co2 = mesh["Coordinates"];
be2 = mesh["BoundaryElements"];]
bmesh = ToBoundaryMesh["Coordinates" -> Join[co1, co2], "BoundaryElements" -> Join[be1, be2]]
ToBoundaryMesh::fememib: The input has or generated an intersecting boundary and cannot be processed.
Obviously, it only contains the pipe wall not the fluid.
bmesh = ToBoundaryMesh[ImplicitRegion[wall[x, y, z], {x, y, z}]]
ToElementMesh[bmesh, "RegionHoles" -> None]["Wireframe"]
Update
@user21's solution somehow fails in the other situations. E.g.
L = 0.5;
hi = 2/3 1.25;
ri = 0.01;
m = ToElementMesh[
ImplicitRegion[-L/2 <= x <= L/2 &&
0 <= y <= 1.25 && ! (x^2 + (y - hi)^2 < ri^2), {x, y}],
"RegionHoles" -> None(*,"RegionMarker"\[Rule]{{{0,hi},1,10},{{0,
1.25/3},2,0.1}},*), "MeshOrder" -> 1, MaxCellMeasure -> Infinity]
m["Wireframe"]
coords = m["Coordinates"];
c1 = Join[coords, ConstantArray[{0.}, {Length[coords]}], 2];
c2 = Join[coords, ConstantArray[{1.}, {Length[coords]}], 2];
ele = m["MeshElements"];
max = Max[ElementIncidents[ele]]
tohigherIndex[type_[inci_, marker___], max_] :=
type[inci + max, marker]
tmpBM = ToBoundaryMesh[m];
sides = QuadElement[Map[Join[#1, Reverse[#1 + max]] &, #]] & /@
ElementIncidents[
Flatten[MeshElementSplitByMarker[tmpBM["BoundaryElements"]]]];
bm = ToBoundaryMesh["Coordinates" -> Join[c1, c2],
"BoundaryElements" ->
Join[ele, tohigherIndex[#, max] & /@ ele, sides]]
bm["Wireframe"]
The code above gives me the following error
TriangleElement::femdmi: Mesh element type TriangleElement does not match incidents {}.
ToBoundaryMesh::fembdel: TriangleElement[{{60,96,95},{19,95,96},{60,59,9},{95,59,60},{19,11,635},{1182,10,67},{10,1182,11},{1182,67,79},{95,635,79},{635,95,19},{79,635,1182},{1182,635,11}}] is not a valid mesh element. Possible causes are that the mesh element type is not valid, not enough coordinates have been specified, or that incidents have values less than or equal to zero.
Is there any solution that can be generalized to random geometry?