Replies: 1 comment 5 replies
-
It seems to assume that dof number is |
Beta Was this translation helpful? Give feedback.
5 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Dear Ferrite Developer,
In the following code, when I want to apply nodal force the results is incorrect.
For traction it works but for nodal force is incorrect.
is the function apply_nodal_force_3d! correct?
Could you kindly provide your guidance on this?
Thank you.
using Ferrite
using Comodo
function apply_nodal_force_3d!(grid, node_set_name, load_vector, f_ext)
node_set = getnodeset(grid, node_set_name)
for node_id in node_set
f_ext[3node_id-2] += load_vector[1]
f_ext[3node_id-1] += load_vector[2]
f_ext[3node_id] += load_vector[3]
end
end
function get_material_matrix_3d(E, ν)
C_voigt = E / ((1 + ν) * (1 - 2 * ν)) * [
1-ν ν ν 0 0 0;
ν 1-ν ν 0 0 0;
ν ν 1-ν 0 0 0;
0 0 0 (1-2ν)/2 0 0;
0 0 0 0 (1-2ν)/2 0;
0 0 0 0 0 (1-2ν)/2
]
return fromvoigt(SymmetricTensor{4,3}, C_voigt)
end
function assemble_cell_3d!(ke, cell_values, E, ν)
C = get_material_matrix_3d(E, ν)
for qp in 1:getnquadpoints(cell_values)
dΩ = getdetJdV(cell_values, qp)
for i in 1:getnbasefunctions(cell_values)
∇Ni = shape_gradient(cell_values, qp, i)
for j in 1:getnbasefunctions(cell_values)
∇δNj = shape_symmetric_gradient(cell_values, qp, j)
ke[i, j] += (∇Ni ⊡ C ⊡ ∇δNj) * dΩ
end
end
end
return ke
end
function assemble_global_3d!(K, dh, cell_values, E, ν)
n_basefuncs = getnbasefunctions(cell_values)
ke = zeros(n_basefuncs, n_basefuncs)
assembler = start_assemble(K)
for (cell_index, cell) in enumerate(CellIterator(dh))
reinit!(cell_values, cell)
fill!(ke, 0.0)
material_E = typeof(E) <: AbstractVector ? E[cell_index] : E
assemble_cell_3d!(ke, cell_values, material_E, ν)
assemble!(assembler, celldofs(cell), ke)
end
return K
end
Control parameters
Lx = 1.0
Ly = 1.0
Lz = 1.0
pointSpacing = 0.08
Dimensions for the box and spacing
boxDim = [Lx, Ly, Lz]
Generate tetrahedral mesh
E, V, Fb, CFb_type = tetbox(boxDim, pointSpacing)
Find extreme coordinates
min_x = minimum([v[1] for v in V])
max_x = maximum([v[1] for v in V])
min_y = minimum([v[2] for v in V])
max_y = maximum([v[2] for v in V])
min_z = minimum([v[3] for v in V])
max_z = maximum([v[3] for v in V])
Adjust vertex positions to start from the origin
V = [(v[1] - min_x, v[2] - min_y, v[3] - min_z) for v in V]
Recalculate extreme coordinates after adjustment
min_x = minimum([v[1] for v in V])
max_x = maximum([v[1] for v in V])
min_y = minimum([v[2] for v in V])
max_y = maximum([v[2] for v in V])
min_z = minimum([v[3] for v in V])
max_z = maximum([v[3] for v in V])
cells = [Ferrite.Tetrahedron((e[1], e[2], e[3], e[4])) for e in E]
nodes = [Ferrite.Node((v[1], v[2], v[3])) for v in V]
grid = Grid(cells, nodes)
addnodeset!(grid, "top", x -> abs(x[3] - (max_z)) < 1e-6)
addfacetset!(grid, "bottom", x -> abs(x[3] - (min_z)) < 1e-6)
function create_values()
order = 1
dim = 3
ip = Lagrange{RefTetrahedron,order}()^dim
qr = QuadratureRule{RefTetrahedron}(2)
qr_face = FacetQuadratureRule{RefTetrahedron}(1)
cell_values = CellValues(qr, ip)
facet_values = FacetValues(qr_face, ip)
return cell_values, facet_values
end
Function to create a DOF handler
function create_dofhandler(grid)
dh = Ferrite.DofHandler(grid)
Ferrite.add!(dh, :u, Ferrite.Lagrange{Ferrite.RefTetrahedron,1}()^3)
Ferrite.close!(dh)
return dh
end
Function to create boundary conditions
Function to create boundary conditions
function create_bc(dh, grid)
ch = Ferrite.ConstraintHandler(dh)
dbc = Dirichlet(:u, getfacetset(grid, "bottom"), (x, t) -> [0.0, 0.0, 0.0], [1, 2, 3])
add!(ch, dbc)
Ferrite.close!(ch)
return ch
end
dh = create_dofhandler(grid)
ch = create_bc(dh, grid)
cell_values, facet_values = create_values()
loads = [0.0, 0.0, 1e4]
E = 210e6
ν = 0.3 # Poisson's ratio
Neumann_bc = "top"
Allocate and assemble the global stiffness matrix
K = allocate_matrix(dh)
assemble_global_3d!(K, dh, cell_values, E, ν)
Initialize external force vector
f_ext = zeros(ndofs(dh))
apply_nodal_force_3d!(grid, Neumann_bc, loads, f_ext)
apply!(K, f_ext, ch) # Apply constraints
u = K \ f_ext # Solve the system Ku = f_ext
DD = u;
display(maximum(DD))
VTKGridFile("my_solution", grid) do vtk
write_solution(vtk, dh, DD)
end;
VTKGridFile("boundary-conditions", dh) do vtk
Ferrite.write_constraints(vtk,ch)
end
Beta Was this translation helpful? Give feedback.
All reactions