I released a new version with the point mass bug fix. I also added a unit test. Keep in mind that the mass matrix for point masses are defined in the body frame rather than the element frame, which changes your example a little bit since you need to rotate the mass matrices for the lumped masses. Here’s the updated version:
using GXBeam, StaticArrays, LinearAlgebra
stiff = [1000000 0 0 -.5 -1 -50000; 0 3000000 0 0 0 0; 0 0 3000000 0 0 0; 0 0 0 7 .1 -.02; 0 0 0 0 5 .1; 0 0 0 0 0 3000]
stiff = Symmetric(stiff)
mass = [.02 0 0 0 -5e-7 -1e-7; 0 .02 0 5e-7 0 1e-4; 0 0 .02 1e-7 -1e-4 0; 0 0 0 1e-5 1e-8 2e-10; 0 0 0 0 6e-7 9e-9; 0 0 0 0 0 1e-5]
mass = Symmetric(mass)
nodes = [SA_F64[0,i,0] for i in 0:.1:1]
nElements = length(nodes)-1
start = 1:nElements
stop = 2:(nElements+1)
transformation = [[0 -1 0; 1 0 0; 0 0 1] for _ in 1:nElements];
stiffness = [stiff for i in 1:nElements]
massmatrix = [mass./0.1 for i in 1:nElements] # here I divide by the element length, which I don't do for the lumped mass
assembly = GXBeam.Assembly(nodes, start, stop, stiffness=stiffness, frames=transformation, mass=massmatrix);
prescribed_conditions = Dict(1 => GXBeam.PrescribedConditions(ux=0, uy=0, uz=0, theta_x=0, theta_y=0, theta_z=0));
system, λ, V, converged = GXBeam.eigenvalue_analysis(assembly, prescribed_conditions = prescribed_conditions, nev = 10);
frequencies = imag(λ[1:2:10])/2π
nodes = sort(vcat(nodes,nodes[2:end]))
nElements = length(nodes)-1
start = 1:nElements
stop = 2:(nElements+1)
transformation = [[0 -1 0; 1 0 0; 0 0 1] for _ in 1:nElements];
stiffness = [i%2==0 ? 0*stiff : stiff for i in 1:nElements]
pointmass = Dict(2 => PointMass(GXBeam.transform_properties(mass, transformation[2]')))
for i in 4:2:nElements
pointmass[i] = PointMass(GXBeam.transform_properties(mass, transformation[i]'))
end
pointmass[nElements] = PointMass(GXBeam.transform_properties(mass, transformation[nElements]')./2) # last lumped mass is half of the others, as it represents the last half of an element
assembly = GXBeam.Assembly(nodes, start, stop, stiffness=stiffness, frames=transformation);
prescribed_conditions = Dict(1 => GXBeam.PrescribedConditions(ux=0, uy=0, uz=0, theta_x=0, theta_y=0, theta_z=0));
system, λ, V, converged = GXBeam.eigenvalue_analysis(assembly, prescribed_conditions = prescribed_conditions, nev = 10, point_masses=pointmass);
frequencies = imag(λ[1:2:10])/2π
First and then second answers:
5-element Vector{Float64}:
2.778377726671564
18.02510603873221
27.589923228529937
53.92848744691813
66.28028876304779
5-element Vector{Float64}:
2.762457025865554
17.31061493577968
27.432545128177775
48.88599842911449
66.07594276651227
Here’s how to get the exact same results using the point mass matrices instead of element mass matrices, which is informative for showing how they’re implemented.
using GXBeam, StaticArrays, LinearAlgebra
stiff = [1000000 0 0 -.5 -1 -50000; 0 3000000 0 0 0 0; 0 0 3000000 0 0 0; 0 0 0 7 .1 -.02; 0 0 0 0 5 .1; 0 0 0 0 0 3000]
stiff = Symmetric(stiff)
mass = [.02 0 0 0 -5e-7 -1e-7; 0 .02 0 5e-7 0 1e-4; 0 0 .02 1e-7 -1e-4 0; 0 0 0 1e-5 1e-8 2e-10; 0 0 0 0 6e-7 9e-9; 0 0 0 0 0 1e-5]
mass = Symmetric(mass)
nodes = [SA_F64[0,i,0] for i in 0:.1:1]
nElements = length(nodes)-1
start = 1:nElements
stop = 2:(nElements+1)
transformation = [[0 -1 0; 1 0 0; 0 0 1] for _ in 1:nElements];
stiffness = [stiff for i in 1:nElements]
massmatrix = [mass./0.1 for i in 1:nElements] # here I divide by the element length, which I don't do for the lumped mass
assembly = GXBeam.Assembly(nodes, start, stop, stiffness=stiffness, frames=transformation, mass=massmatrix);
prescribed_conditions = Dict(1 => GXBeam.PrescribedConditions(ux=0, uy=0, uz=0, theta_x=0, theta_y=0, theta_z=0));
system, λ, V, converged = GXBeam.eigenvalue_analysis(assembly, prescribed_conditions = prescribed_conditions, nev = 10);
frequencies = imag(λ[1:2:10])/2π
pointmass = Dict(1 => PointMass(GXBeam.transform_properties(mass, transformation[1]')))
for i in 2:nElements
pointmass[i] = PointMass(GXBeam.transform_properties(mass, transformation[i]'))
end
assembly = GXBeam.Assembly(nodes, start, stop, stiffness=stiffness, frames=transformation);
prescribed_conditions = Dict(1 => GXBeam.PrescribedConditions(ux=0, uy=0, uz=0, theta_x=0, theta_y=0, theta_z=0));
system, λ, V, converged = GXBeam.eigenvalue_analysis(assembly, prescribed_conditions = prescribed_conditions, nev = 10, point_masses=pointmass);
frequencies = imag(λ[1:2:10])/2π