mirror of
https://github.com/JuliaFEM/JuliaFEM.jl.git
synced 2026-08-06 04:21:33 +00:00
16534d9e4e
Use FEMBeam.jl to solve beam problems. Added an example, where natural frequencies of frequencies of 3d frame structure are calculated. Some minor modifications to Modal analysis is done to make Xdmf writing of 6 dof nodes work.
96 lines
3.4 KiB
Julia
96 lines
3.4 KiB
Julia
# This file is a part of JuliaFEM.
|
|
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
|
|
|
|
# # Natural frequency analysis of 3d frame structure
|
|
|
|
# For general information about Euler-Bernoulli beam theory, see
|
|
# [this](https://en.wikipedia.org/wiki/Euler%E2%80%93Bernoulli_beam_theory)
|
|
# wikipedia page.
|
|
|
|
# The model is a 3d frame, shown in picture.
|
|
|
|
# 
|
|
|
|
using JuliaFEM
|
|
using JuliaFEM.Preprocess
|
|
using FEMBase.Test
|
|
using Logging
|
|
Logging.configure(level=INFO)
|
|
add_elements! = JuliaFEM.add_elements!
|
|
|
|
# Reading mesh
|
|
|
|
datadir = Pkg.dir("JuliaFEM", "examples", "3d_frame")
|
|
mesh = aster_read_mesh(joinpath(datadir, "model.med"))
|
|
println("Number of nodes in a model: ", length(mesh.nodes))
|
|
|
|
# Create beam elements. For 3d model, we need to define at least
|
|
# [Young's modulus](https://en.wikipedia.org/wiki/Young%27s_modulus),
|
|
# [shear modulus](https://en.wikipedia.org/wiki/Shear_modulus),
|
|
# [density](https://en.wikipedia.org/wiki/Density)
|
|
# cross-section area, moment of inertia in local coordinate
|
|
# system and polar moment of inertia.
|
|
|
|
beam_elements = create_elements(mesh, "FRAME")
|
|
info("Number of elements: ", length(beam_elements))
|
|
update!(beam_elements, "youngs modulus", 210.0e6)
|
|
update!(beam_elements, "shear modulus", 84.0e6)
|
|
update!(beam_elements, "density", 7850.0e-3)
|
|
update!(beam_elements, "cross-section area", 20.0e-2)
|
|
update!(beam_elements, "torsional moment of inertia 1", 10.0e-5)
|
|
update!(beam_elements, "torsional moment of inertia 2", 10.0e-5)
|
|
update!(beam_elements, "polar moment of inertia", 30.0e-5)
|
|
|
|
# The direction of beam is defined in same way than in ABAQUS.
|
|
# That is, we have a tangent direction and one normal direction.
|
|
# The third direction is then cross product of tangent and normal.
|
|
# Because the second area moment is same in both directions, we can
|
|
# choose normal direction freely.
|
|
|
|
for element in beam_elements
|
|
X1, X2 = element("geometry", 0.0)
|
|
t = (X2-X1)/norm(X2-X1)
|
|
I = eye(3)
|
|
k = indmax([norm(cross(t, I[:,k])) for k in 1:3])
|
|
n = cross(t, I[:,k])/norm(cross(t, I[:,k]))
|
|
update!(element, "normal", n)
|
|
end
|
|
|
|
# Create boundary conditions: fix all degrees of freedom for nodes in
|
|
# a set FIXED. Here we first create elements of type `Poi1` for each
|
|
# node j in set FIXED, update geometry field and then create new fields
|
|
# `fixed displacmeent 1`, `fixed displacement 2`, and so on, where the
|
|
# displacement / rotation is prescribed.
|
|
|
|
bc_elements = [Element(Poi1, [j]) for j in mesh.node_sets[:FIXED]]
|
|
update!(bc_elements, "geometry", mesh.nodes)
|
|
for i=1:3
|
|
update!(bc_elements, "fixed displacement $i", 0.0)
|
|
update!(bc_elements, "fixed rotation $i", 0.0)
|
|
end
|
|
|
|
# Create a problem, containing beam elements and boundary conditions:
|
|
|
|
frame = Problem(Beam, "3d frame", 6)
|
|
add_elements!(frame, beam_elements)
|
|
add_elements!(frame, bc_elements)
|
|
|
|
# Perform modal analysis
|
|
|
|
step = Analysis(Modal)
|
|
xdmf = Xdmf(joinpath(datadir, "3d_frame_results"); overwrite=true)
|
|
add_results_writer!(step, xdmf)
|
|
add_problems!(step, [frame])
|
|
run!(step)
|
|
close(xdmf.hdf)
|
|
|
|
# Each `Analysis` can have properties, e.g. time, maximum number of iterations,
|
|
# convergence tolerance and so on. Eigenvalues of calculation are stored as a
|
|
# properties of analysis:
|
|
|
|
freqs = sqrt.(step.properties.eigvals) / (2*pi)
|
|
println("Natural frequencies [Hz]: $(round.(freqs, 2))")
|
|
|
|
# [](https://www.youtube.com/watch?v=GzktCqeASmo)
|
|
|