I sometimes work with pipes which can take up complicated positions in 3D geometries. Here is a minimum working example of what I am trying to do.
Suppose I want to mesh and calculate vibration frequencies for this solid curved tube.
R0 = 1;
r = 0.05;
ϕ = 0.654 π;
g = Graphics3D[{CapForm["Butt"],
Tube[Table[{R0 Cos[θ], R0 Sin[θ], 0}, {θ,
0, ϕ, ϕ/25}], r]}, Axes -> True,
AxesLabel -> {"x", "y", "z"}]
I can make a mesh for my tube easily:
Needs["NDSolve`FEM`"];
reg = BoundaryDiscretizeGraphics[g,
MaxCellMeasure -> {"Area" -> 0.001} ]
Now I need a stress operator and boundary conditions. I give the stress operator below and add boundary conditions on one end of the tube which is easy. However, on the other end of the tube I also want to add boundary conditions which is difficult and the reason for my question. To get going I don't add boundary conditions on the "difficult" end.
ClearAll[stressOperator, u, v, w, x, y, z, Y, ν];
stressOperator[
Y_, ν_] := {Inactive[
Div][{{0, 0, -((Y*ν)/((1 - 2*ν)*(1 + ν)))}, {0, 0,
0}, {-Y/(2*(1 + ν)), 0, 0}} .
Inactive[Grad][w[x, y, z], {x, y, z}], {x, y, z}] +
Inactive[
Div][{{0, -((Y*ν)/((1 - 2*ν)*(1 + ν))),
0}, {-Y/(2*(1 + ν)), 0, 0}, {0, 0, 0}} .
Inactive[Grad][v[x, y, z], {x, y, z}], {x, y, z}] +
Inactive[
Div][{{-((Y*(1 - ν))/((1 - 2*ν)*(1 + ν))), 0,
0}, {0, -Y/(2*(1 + ν)), 0}, {0, 0, -Y/(2*(1 + ν))}} .
Inactive[Grad][u[x, y, z], {x, y, z}], {x, y, z}],
Inactive[Div][{{0, 0, 0}, {0,
0, -((Y*ν)/((1 -
2*ν)*(1 + ν)))}, {0, -Y/(2*(1 + ν)), 0}} .
Inactive[Grad][w[x, y, z], {x, y, z}], {x, y, z}] +
Inactive[
Div][{{0, -Y/(2*(1 + ν)),
0}, {-((Y*ν)/((1 - 2*ν)*(1 + ν))), 0, 0}, {0, 0,
0}} . Inactive[Grad][u[x, y, z], {x, y, z}], {x, y, z}] +
Inactive[
Div][{{-Y/(2*(1 + ν)), 0,
0}, {0, -((Y*(1 - ν))/((1 - 2*ν)*(1 + ν))), 0}, {0,
0, -Y/(2*(1 + ν))}} .
Inactive[Grad][v[x, y, z], {x, y, z}], {x, y, z}],
Inactive[Div][{{0, 0, 0}, {0,
0, -Y/(2*(1 + ν))}, {0, -((Y*ν)/((1 -
2*ν)*(1 + ν))), 0}} .
Inactive[Grad][v[x, y, z], {x, y, z}], {x, y, z}] +
Inactive[
Div][{{0, 0, -Y/(2*(1 + ν))}, {0, 0,
0}, {-((Y*ν)/((1 - 2*ν)*(1 + ν))), 0, 0}} .
Inactive[Grad][u[x, y, z], {x, y, z}], {x, y, z}] +
Inactive[
Div][{{-Y/(2*(1 + ν)), 0, 0}, {0, -Y/(2*(1 + ν)), 0}, {0,
0, -((Y*(1 - ν))/((1 - 2*ν)*(1 + ν)))}} .
Inactive[Grad][w[x, y, z], {x, y, z}], {x, y, z}]};
Here is the code for the boundary conditions on the easy end;
{vals, funs} = NDEigensystem[{stressOperator[10^3, 33/100],
DirichletCondition[u[x, y, z] == 0,
y == 0 && (x - R0)^2 + z^2 <= r^2],
DirichletCondition[v[x, y, z] == 0,
y == 0 && (x - R0)^2 + z^2 <= r^2],
DirichletCondition[w[x, y, z] == 0,
y == 0 && (x - R0)^2 + z^2 <= r^2]},
{u, v, w}, {x, y, z} \[Element] mesh, 12];
Here are the vibration frequencies:
TableForm[Sqrt[vals], TableHeadings -> {Automatic, None}]
This is an example of a deflected vibration eigenmode:
n = 6;
fac = 0.02;
uif = funs[[n, 1]];
vif = funs[[n, 2]];
wif = funs[[n, 3]];
dmesh = ElementMeshDeformation[mesh, {uif, vif, wif},
"ScalingFactor" -> fac];
Show[mesh["Wireframe"],
dmesh["Wireframe"[
"ElementMeshDirective" -> Directive[EdgeForm[Red], FaceForm[]]]],
Axes -> True, AxesLabel -> {"x", "y", "z"}]
So everything seems to be working and the issue is: How do I add a DirichletCondition boundary condition on the difficult end? I have to be able to specify the region. My first thought was to identify nodes, making the end region I wish to specify, and then make a MeshRegion. This is not straightforward, particularly in the general case, because you have to define a region to select the coordinates. So the most general question would be: How do you define a region of a mesh where you wish to add a boundary condition?








BoundaryElementMarkerUnionWritten up anywhere? I can find a little underElemetMesh. I notice that as you change the area of the mesh elements the number of features you get changes. How does the code look for features? Is it to do with change in normal direction? Should I ask a new question on this? – Hugh Jul 07 '21 at 14:30