Modal analysis of a beam

Beam simply supported at both ends

using Muscade, StaticArrays, GLMakie
include("BeamElements.jl");

L = 1;  # Beam length [m]
q = 0.0;  # Uniform lateral load [N/m]
EI₂ = 1;  # Bending stiffness [Nm²]
EI₃ = 1;  # Bending stiffness [Nm²]
EA = 1e6;  # Axial stiffness [N]
GJ = 1e6;  # Torsional stiffness [Nm²]
μ = 1;
ι₁= 1;

Create model

nel         = 50
Nnod        = nel+1
nodeCoord   = hcat((0:L/nel:L),zeros(Float64,Nnod,2))
mat         = BeamCrossSection(EA=EA,EI₂=EI₂,EI₃=EI₃,GJ=GJ,μ=μ,ι₁=ι₁)
model       = Model(:TestModel)
nodid       = addnode!(model,nodeCoord)
mesh        = hcat(nodid[1:Nnod-1],nodid[2:Nnod])
eleid       = addelement!(model,EulerBeam3D,mesh;mat=mat,orient2=SVector(0.,1.,0.));

Set boundary conditions and constraints

[addelement!(model,Hold,[nodid[1]]  ;field) for field∈[:t1,:t2,:t3,:r1]]                                # Simply supported end 1
[addelement!(model,Hold,[nodid[end]];field) for field∈[:t1,:t2,:t3,:r1]]                                # Simply supported end 2
[addelement!(model,Hold,[nodid[nodeidx]];field=:t3) for nodeidx∈2:Nnod-1]                               # Enforce beam motions in one dimension to obtain planar modeshapes
[addelement!(model,DofLoad,[nodid[nodeidx]];field=:t2,value=t->sin(t)*q*L/Nnod) for nodeidx=1:Nnod];    # Distributed vertical load q

Static analysis

initialstate    = initialize!(model);
state           = solve(SweepX{0};initialstate,time=[0.]);



Muscade: SweepX{0} solver

    step   1 converged in   1 iterations. |Δx|=0.0e+00 |Lλ|=0.0e+00

    nel=158, ndof=363, nstep=1, niter=1, niter/nstep= 1.00
    SweepX{0} time:   23 [s]
Muscade done.

Solve eigenvalue problem

nmod            = 15
res             = solve(EigX{ℝ};state=state[1],nmod);



Muscade: EigX{Real} solver


    Assembling
    Solving Eigenvalues


    EigX{Real} time:   22 [s]
Muscade done.

Analytical solutions for the natural frequency of a simply supported beam See e.g. https://roymech.org/UsefulTables/Vibrations/NaturalVibrations_derivation.html

fₙ(k) = √(EI₂/μ)*(k^2*π)/(2*L^2)
Φₙ(k,x) = sin.(k*π/L.*x);

Display solution and comparison against analytical solution

fig      = Figure(size = (2000,1000))
axes = [Axis(fig[idxLine,1], yminorgridvisible = false,xminorgridvisible = false ) for idxLine=1:3]
axes[1].title = "Modeshapes of a simply supported beam. Muscade (" *string(nel)*" elements): markers. Analytical solution: lines. "
for idxMod=1:nmod
    eigres  = increment(state[1],res,[idxMod],[1]);
    t2_eig  = getdof(eigres;field=:t2,nodID=nodid[1:Nnod])
    δ       = sign(Φₙ(idxMod,0:L/nel:L)'*t2_eig) * maximum(t2_eig)
    selectAxis = axes[mod(idxMod-1,3)+1]
    labelStr= "Mode "*string(idxMod)*", Muscade: "*string(round(res.ω[idxMod]/(2π),digits=3))*" Hz, Analytical: " *string(round(fₙ(idxMod),digits=3))* " Hz"
    scatter!(selectAxis,(0:L/nel:L),  t2_eig[:]/δ,          label=labelStr  );
    lines!(  selectAxis,(0:L/nel:L),  Φₙ(idxMod,0:L/nel:L)                  );
end
for ax∈axes;
    xlims!(ax,0,1); ylims!(ax, -2,2); axislegend(ax)
end

currentDir = @__DIR__
if occursin("build", currentDir)
    save(normpath(joinpath(currentDir,"..","src","assets","beamModes.png")),fig)
elseif occursin("examples", currentDir)
    save(normpath(joinpath(currentDir,"beamModes.png")),fig)
end

Result


This page was generated using Literate.jl.