6

We are trying to implement buckling using a newly implemented FEM solver. However, if we try to reproduce the buckling phenomena using a thin rod, it is just compressed, and we cannot observe the buckling phenomenon. It may be due to the absence of small noise in the shape of the rod, but we are not sure how to implement this phenomenon. The code we use is attached below.

Needs["NDSolve`FEM`"];

length = 50; radius = 1; YoungModulus = 260000; PoissonRatio = 0.3; MassDensity = 1300; Pressure = -1 100000 ; MaxCellMeasureLength = radius/4;

vars = {{u[x, y, z], v[x, y, z], w[x, y, z]}, {x, y, z}}; pars = <| "YoungModulus" -> YoungModulus , "PoissonRatio" -> PoissonRatio, "MassDensity" -> MassDensity|>; op1 = SolidMechanicsPDEComponent[vars, pars];

[CapitalOmega] = Cylinder[{{0, 0, 0}, {0, 0, length}}, radius];

mesh = ToElementMesh[[CapitalOmega] , MeshQualityGoal -> 1, MaxCellMeasure -> {"Length" -> MaxCellMeasureLength}];

Subscript[[CapitalGamma], load] = SolidBoundaryLoadValue[ElementMarker == 2, vars, pars, <|"Pressure" -> Pressure {0, 0, 1}|>];

Subscript[[CapitalGamma], base] = SolidDisplacementCondition[ElementMarker == 3, vars, pars, <|"Displacement" -> {0, 0, 0}|>];

pde = {op1 == Subscript[[CapitalGamma], load], Subscript[[CapitalGamma], base]};

measure = AbsoluteTiming[ MaxMemoryUsed[ displacement = NDSolveValue[ pde, {u[x, y, z], v[x, y, z], w[x, y, z]}, {x, y, z} [Element] mesh] ]/(1024.^2)]; Print["Time -> ", measure[[1]], "\nMemory -> ", measure[[2]]];

visualizeDeformation[fun : {__InterpolatingFunction}, OptionsPattern[]] := Module[{mesh}, mesh = fun[[1]]["ElementMesh"]; Show[{mesh["Wireframe"["MeshElement" -> "BoundaryElements"]], ElementMeshDeformation[mesh, fun, "ScalingFactor" -> 1 ][ "Wireframe"[ "ElementMeshDirective" -> Directive[EdgeForm[Red], FaceForm[]]]]}, Axes -> True]];

visualizeDeformation[displacement[[All, 0]]]

2023/12/4 Thank you very much for all the comments - they are all informative. But I think I need to clarify why I need the slight shape deviation. I am dealing with interdigitation of blood vessels caused by blood pressure or vessel growth to a longitudinal direction, which seems to have a certain characteristic length. My main interest is where this length comes from.

enter image description here

I started from the linear theory to predict initial growth of pattern as we usually do in other PDE. Euler-Bernoulli beam theory is

0 = -P h''(x) - EI h''''(x)

where P is the pressure caused by growth, and EI is Young's modulus times inertia. This describes the balance of force from pressure and force from elasticity, so if we assume the viscosity-dominant condition in which growth is slow and the growth of the deviation is proportional to the force, the dynamic version of the equation becomes

enter image description here

Then by the linear stability analysis we can obtain

enter image description here

enter image description here

which seem to match the numerical simulation result.

L = 6.28;
EI = 1;
P = 25;
simulationLength = 10;

dx = 0.2; dt = 0.0001; nStep = 100; loopPerStep = Round[simulationLength/dt/nStep]; n = Round[L/dx];

h0 = Table[0.01 (RandomReal[] - 0.5), {n}];

dd[l_] := (RotateLeft[l] + RotateRight[l] - 2 l)/dx/dx; dhdt[h_] := h + dt (-P dd[h] - EI dd[dd[h]]); oneStep[h_] := Nest[dhdt, h0, loopPerStep];

result = NestList[oneStep, h0, nStep]; { Sqrt[P/(2 EI)] // N, ListLinePlot[result[[2]]]}

I am curious whether we could obtain similar winding pattern using FEM simulation. I am not sure whether I can get this by simply changing the pressure direction, and still want to know how to introduce slight shape deviation (in this case h0 = Table[0.01 (RandomReal[] - 0.5), {n}];)

Thank you very much in advance.

AsukaMinato
  • 9,758
  • 1
  • 14
  • 40
Takashi Miura
  • 321
  • 1
  • 6
  • 2
    As long as everything is symmetrical, there will be no buckling. Destroy the symmetry, e.g. by a small lateral force or by shifting one end very little. – Daniel Huber Oct 04 '23 at 09:05
  • Thank you very much for your reply. We could bend the rod by setting the pressure vector to Pressure {0.00001, 0, 1}. We are also interested in breaking symmetry by adding small noise to shape (We usually deal with Turing instability, and in the system, we introduce deviation in the initial distribution). Is there an easy way to introduce a slight deviation to the rod shape, for example, by adding small white noise to the node coordinates of the mesh? – Takashi Miura Oct 04 '23 at 09:56
  • Changing the mesh only has an effect on accuracy. To introduce asymmetries you must change the shape. – Daniel Huber Oct 04 '23 at 11:05
  • The buckling shape is calculated as the Eigenvector corresponding to the first Eigenvalue of the system. The buckling load as the Eigenvalue, e.g. if you have a unit force F=1, then the buckling load would be the first Eigenvalue multiplied with F. – wvt_beginner Oct 10 '23 at 08:19
  • @wvt_beginner, you are saying that NDEigensystem[{op1, Subscript[\[CapitalGamma], base]}, {u[x, y, z], v[x, y, z], w[x, y, z]}, {x, y, z} \[Element] mesh, 1] is all that is needed? – user21 Oct 11 '23 at 07:51
  • @user21: in solid mechanics (fea in this case), the buckling shape is calculated as the Eigenvector(s) of the global stiffness matrix (assuming linear system behavior). In case you do not have boundary conditions set yet the first 6 Eigenvalues will be zero for a 3D problem, indicating that there a 6 rigid body motions possible. Be aware that for a 1000dof system the characteristic polynom will be of degree 1000. In that very case the op posted one is using a sledge-hammer to crack a nut, since this problem here reduces to the third Euler case of beam buckling. – wvt_beginner Oct 11 '23 at 12:43
  • @wvt_beginner, that's exactly what the NDEigensystem above does, no? If you one does not have boundary conditions then yes, the first 6 modes are rigid body modes. Maybe I don't understand the result. Once you have the first eigenvalue - what does it tell you. I mean an eigenvalue analysis is nothing fancy. What is so special about computing the buckling shape? Is it really just the first eigenmode? – user21 Oct 11 '23 at 12:51
  • @user21: The first nonzero Eigenvalue corresponds to the buckling load, under which the system will buckle. This is extremely important for engineering purposes because in the direct neighbourhood of the buckling point the system stiffness is practically zero. – wvt_beginner Oct 11 '23 at 13:29

2 Answers2

5

We have already discussed this issue once here. Due to large deformations of the thin beam in a case of buckling we need probably some nonlinear model. As is known, in the case of a cylinder, loss of stability is observed under load $F=\pi^2 Y I/4 l^2$, where $I=\pi r^4/4$, $r$ is a radius, $l$ is a length of cylinder. In a discussed case we have

length = 50;
radius = 1;
YoungModulus = 260000;inert = Pi radius^4/4; F=Pi^2 Y inert/4/length^2 // N 
(*201.541*) 

Thus, if the load is greater than 201.541 Newton, then loss of stability will be observed. The final shape of the rod can be calculated using thin rod theory, for example

Pressure = -70; 
L = length; Y = YoungModulus; fX = 
 Pi radius^2 (-Pressure);
q[t0_] := 
 Sqrt[1/2 inert Y/fX] 2 Sqrt[1/(1 - Cos[t0])]
   EllipticF[t0/2, Csc[t0/2]^2]
t0 = t /. NSolve[q[t] - L == 0 && 0 <= t <= Pi, t, Reals][[1]]

(Out[]= 0.827734)

Using parameter t0 we can compute coordinate of the rod in parametric form as follows

yl[t_] := -Sqrt[2 inert Y/fX] (Sqrt[1 - Cos[t0]] - 
     Sqrt[Cos[t] - Cos[t0]]);
xl[t_?NumericQ] := 
  Sqrt[.5 inert Y/fX] NIntegrate[
    Cos[tet]/Sqrt[Cos[tet] - Cos[t0]], {tet, 0, t}];

ParametricPlot[{xl[t], yl[t]}, {t, 0, t0}, PlotRange -> All, FrameLabel -> {"x", "y"}, PlotStyle -> Blue, Frame -> True, AspectRatio -> 1/2]

Figure 1

This is the shape the cylinder should take in the event of loss of stability. We can use this data in a 3D linear model. To do this, we calculate the deformation of the end of the rod as follows

final = {xl[t0] - L, yl[t0], 0}

Out[]= {-8.26458, -24.5092, 0}

In the example we are considering, the load is carried out along the x-axis.

Needs["NDSolve`FEM`"];

length = 50; radius = 1; YoungModulus = 260000; PoissonRatio = 0.3; MassDensity = 1300; Pressure = -70; MaxCellMeasureLength = radius/4;

vars = {{u[x, y, z], v[x, y, z], w[x, y, z]}, {x, y, z}}; pars = <| "YoungModulus" -> YoungModulus, "PoissonRatio" -> PoissonRatio, "MassDensity" -> MassDensity|>; op1 = SolidMechanicsPDEComponent[vars, pars];

[CapitalOmega] = Cylinder[{{0, 0, 0}, {length, 0, 0}}, radius];

mesh = ToElementMesh[[CapitalOmega], MeshQualityGoal -> 1, MaxCellMeasure -> {"Length" -> MaxCellMeasureLength}];

Subscript[[CapitalGamma], load] = SolidBoundaryLoadValue[x == length, vars, pars, <|"Force" -> fX {1, 0, 0}|>];

Subscript[[CapitalGamma], base] = {SolidFixedCondition[x == 0, vars, pars], SolidDisplacementCondition[x == length, vars, pars, <|"Displacement" -> final|>]};

pde = {op1 == Subscript[[CapitalGamma], load], Subscript[[CapitalGamma], base]};

{U, V, W} = NDSolveValue[pde, {u, v, w}, {x, y, z} [Element] mesh]

Visualization

Show[{ElementMeshDeformation[mesh, {U, V, W}, "ScalingFactor" -> 1][
   "Wireframe"[
    "ElementMeshDirective" -> Directive[EdgeForm[Blue], FaceForm[]]]],
   mesh["Wireframe"["MeshElementStyle" -> EdgeForm[Gray]]], 
  ParametricPlot3D[{xl[t], yl[t], 0}, {t, 0, t0}, PlotRange -> All, 
   PlotStyle -> Red, AspectRatio -> 1/2]}, Axes -> True, 
 AxesLabel -> {x, y, z}]

Figure 2

We see that the cylinder does not take the shape of a thin rod.

Alex Trounev
  • 44,369
  • 3
  • 48
  • 106
  • Thank you Alex. This is not what I am looking for. There is a (linear) theory that relates the first (non rigid body mode?) eigenvalue to the buckling force. That's what I'd like to understand. Here is an overview description of what I am looking for. One thing that confuses me is that a load is never considered in an eigenvalue analysis; only the mass matrix and the stiffness matrix play a role. But here we need to interoperate the test load. – user21 Oct 16 '23 at 08:59
  • @user21: If you apply a load of say F=1, then the buckling load is F multiplied with the first nonzero Eigenvalue. You are confusing the general Eigenvalue problem with the special Eigenvalue problem. For buckling problems you are solving the special Eigenvalue problem. Let K be the stiffness matrix, I the Identity matrix, lambda the Eigebnvalues and phi the Eigenvectors: (K - lambdaI)phi=0. If you use the Mass matrix instead of the Identity matrix you would identify the Eigenvalues with the square of the natural frequencies. – wvt_beginner Oct 16 '23 at 11:18
  • @user21 Ah, now I see that this question comes from you and not from Takashi Miura. His question much simpler and concerning buckling phenomenon only. While you want me to do a detailed analysis of all vibration modes. :) – Alex Trounev Oct 16 '23 at 12:21
  • @wvt_beginner, thanks once more, I have tired to collect what I understand from your comments in the 'answer' below. Maybe you can spot from the code where I went wrong. – user21 Oct 16 '23 at 12:37
  • @AlexTrounev, no this is not question, but my interpretation of what is wanted. Because I myself am interrested in an answer to this I gave a bounty in the hope that someone can put my out of my ignorance. This type of analysis is what is typically done for (linear) buckling analysis, but as you see I don't understand how this is supposed to work. – user21 Oct 16 '23 at 12:38
3

This is not an answer but are the pieces I gather from the comments on how this should be done. But something is wrong and that's too much to discuss in a comment. So here it goes:

Set up:

Needs["NDSolve`FEM`"];

length = 50; radius = 1; YoungModulus = 260000; PoissonRatio = 3/10; (MassDensity=1300;)

vars = {{u[x, y, z], v[x, y, z], w[x, y, z]}, {x, y, z}}; pars = <| "YoungModulus" -> YoungModulus, "PoissonRatio" -> PoissonRatio|>; op1 = SolidMechanicsPDEComponent[vars, pars];

region = Cylinder[{{0, 0, 0}, {0, 0, length}}, radius]; mesh = ToElementMesh[region];

Extract assemble the system matrices:

(* no rigid body modes should be present *)
{dPDE, dBCs, vd, sd, md} = 
  NDSolve`FEM`ProcessPDEEquations[{op1 == 
     SolidBoundaryLoadValue[z == length, vars, 
      pars, <|"Pressure" -> {0, 0, -1}|>], 
    SolidDisplacementCondition[z == 0, vars, 
     pars, <|"Displacement" -> {0, 0, 0}|>]}, {u[x, y, z], v[x, y, z],
     w[x, y, z]}, {x, y, z} \[Element] mesh];

Get the matrices:

{loadV, stiffnessM, dampingM, massM} = dPDE["SystemMatrices"];

Apply the boundary conditions:

DeployBoundaryConditions[{loadV, stiffnessM}, dBCs]

Compute the eigenvalue:

Eigenvalues[stiffnessM, -1, Method -> "Arnoldi"]
(* {0.00069054} *)

(And as requested in a comment, the first 20 eigenvalues, with this method)

Reverse[Eigenvalues[stiffnessM, -20, Method -> "Arnoldi"]]
(* {0.00069054, 0.000690565, 0.0266785, 0.0266805, 0.205952, 0.205977, 0.384391, 0.77103, 0.771207, 1., 1., 1., 1., 1., 1., 1., 1.39559, 2.02578, 2.02638, 3.46523} *)

Now, when we compare this to theory, (that Alex provided) we have:

inert = Pi  radius^4/4
(* pinned on one end *)
k = 2;
F = Pi^2  pars["YoungModulus"]  inert/(k*length)^2;
F//N
(* 201.541 *)

Something is wrong here. The one thing that confuses me is that the load actually does not play a role in this.

Update 1: In place of the force I now used a forced displacement:

(* no rigid body modes should be present *)
{dPDE, dBCs, vd, sd, md} = 
  NDSolve`FEM`ProcessPDEEquations[{op1 == {0, 0, 0}, 
    SolidDisplacementCondition[z == length, vars, 
     pars, <|"Displacement" -> {None, None, -1}|>], 
    SolidDisplacementCondition[z == 0, vars, 
     pars, <|"Displacement" -> {0, 0, 0}|>]}, {u[x, y, z], v[x, y, z],
     w[x, y, z]}, {x, y, z} \[Element] mesh];

The rest is the same and then I get an eigenvalue of:

Eigenvalues[stiffnessM, -1, Method -> "Arnoldi"]
(* {0.00174763} *)

Still no cookies :-(

Update 2: In place of the pressure I used a force:

{dPDE, dBCs, vd, sd, md} = 
  NDSolve`FEM`ProcessPDEEquations[{op1 == 
     SolidBoundaryLoadValue[z == length, vars, 
      pars, <|"Force" -> {0, 0, -1}|>], 
    SolidDisplacementCondition[z == 0, vars, 
     pars, <|"Displacement" -> {0, 0, 0}|>]}, {u[x, y, z], v[x, y, z],
     w[x, y, z]}, {x, y, z} \[Element] mesh];

Rest is the same, then we have:

Eigenvalues[stiffnessM, -1, Method -> "Arnoldi"]
{0.00069}
user21
  • 39,710
  • 8
  • 110
  • 167
  • The pressure is applied to a number of nodes not a single one, right? So, on how many nodes is pressure applied? – wvt_beginner Oct 16 '23 at 13:09
  • @wvt_beginner The pressure is not applied to nodes, it's a surface force and applied to at the surface of all boundary elements that meat the z==length criteria. Should I be using a forced displacement instead? – user21 Oct 16 '23 at 13:51
  • strange indeed. But anyway if you apply forces or pressures on surfaces, these have to be transferred to nodes at the final assembly process of the load vector. Which doesn't apply here, since you are solving an ordinary Eigenvalue problem, which implies that the lhs is zero. Could you do me a favour and solve for the first 10...20 Eigenvalues? – wvt_beginner Oct 16 '23 at 14:36
  • @wvt_beginner, that's what I mean: I am not sure how the load is actually supposed to enter this whole scheme. I have added the first 20 eigenvalues to the scheme. Even when I try to scale by a factor of Pi r^2 I don't get anywhere near the 200 N from the theory. – user21 Oct 16 '23 at 15:15
  • the load does not enter the scheme at all. What you are doing is linear buckling analysis. The load will enter the scheme for nonlinear or post buckling analysis. – wvt_beginner Oct 16 '23 at 16:03
  • 1
    @user21 See example on https://comet-fenics.readthedocs.io/en/latest/demo/buckling_3D/buckling_3d_solid.html – Alex Trounev Oct 17 '23 at 03:24
  • @AlexTrounev, that's a good find. I'll see if I can figure it out from that post or maybe get the book. – user21 Oct 17 '23 at 04:53
  • Thank you very much for the discussions. I am dealing with interdigitation of blood vessels caused by blood pressure or vessel growth to a longitudinal direction, which seems to have a certain characteristic length. My main interest is where this length comes from. – Takashi Miura Dec 04 '23 at 07:04