Files
JuliaFEM.jl/examples/3d_frame.jl
T
Jukka Aho 16534d9e4e Use FEMBeam.jl (#200)
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.
2018-06-04 21:29:37 +03:00

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.
# ![](3d_frame/model.png)
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))")
# [![mode5](3d_frame/natfreq.png)](https://www.youtube.com/watch?v=GzktCqeASmo)