Skip to content

Commit 0c28372

Browse files
authored
wip (#10)
* cahce stresses at mid surface to determine cell upgrade * store stresses in qp in own structure
1 parent f83c694 commit 0c28372

6 files changed

+175
-69
lines changed

docs/examples/doubly_curved.jl

+15-7
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ using Test
164164

165165
#For debug plotting
166166
if false
167-
using Plots; pyplot(); PyPlot.pygui(true)
167+
using Plots; plotly()
168168
using JLD2; using FileIO
169169

170170

@@ -183,11 +183,19 @@ if false
183183
σxx_lumped = getindex.(output.outputdata["Stress at 50%"].data[end][1].stresses, 1, 1)
184184
σyy_lumped = getindex.(output.outputdata["Stress at 50%"].data[end][1].stresses, 2, 2)
185185
σxy_lumped = getindex.(output.outputdata["Stress at 50%"].data[end][1].stresses, 1, 2)
186+
σxz_lumped = getindex.(output.outputdata["Stress at 50%"].data[end][1].stresses, 1, 3)./ σ₀
187+
σyz_lumped = getindex.(output.outputdata["Stress at 50%"].data[end][1].stresses, 2, 3)./ σ₀
188+
σzz_lumped = getindex.(output.outputdata["Stress at 50%"].data[end][1].stresses, 3, 3)./ σ₀
186189
zcoords = getindex.(output.outputdata["Stress at 50%"].data[end][1].local_coords, 3)
190+
zcoords .-= mean(zcoords)
187191

188-
plot!(fig[1], σxx_lumped, zcoords, label = "Lumped")
189-
plot!(fig[2], σyy_lumped, zcoords, label = "Lumped")
190-
plot!(fig[3], σxy_lumped, zcoords, label = "Lumped")
192+
plot!(fig[1], σxx_lumped, zcoords, label = "layered")
193+
plot!(fig[2], σyy_lumped, zcoords, label = "layered")
194+
plot!(fig[3], σxy_lumped, zcoords, label = "layered")
195+
196+
plot!(fig[6], σxz_lumped, zcoords, label = "layered")
197+
plot!(fig[5], σyz_lumped, zcoords, label = "layered")
198+
plot!(fig[4], σzz_lumped, zcoords, label = "layered")
191199

192200
#Reference
193201
#σ_dr_xx = getindex.(data_dr.stresses, 1, 3)./ σ₀
@@ -211,9 +219,9 @@ if false
211219
#plot!(fig[1], σ_dr_xx./ σ₀, z_dr, label = "Ref")
212220
#plot!(fig[2], σ_dr_yy, z_dr, label = "Ref")
213221
#plot!(fig[3], σ_dr_xy, z_dr, label = "Ref")
214-
plot!(fig[4], σ_dr_zz, z_dr, label = "Ref")
215-
plot!(fig[5], σ_dr_zy, z_dr, label = "Ref")
216-
plot!(fig[6], σ_dr_zx, z_dr, label = "Ref")
222+
#plot!(fig[4], σ_dr_zz, z_dr, label = "Ref")
223+
#plot!(fig[5], σ_dr_zy, z_dr, label = "Ref")
224+
#plot!(fig[6], σ_dr_zx, z_dr, label = "Ref")
217225

218226
end
219227

src/igashell_integrationdata.jl

+14-4
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ struct IGAShellIntegrationData{dim_p,dim_s,T,ISV<:IGAShellValues,M}
117117
cell_values_interface::ISV
118118
cell_values_vertices::ISV
119119

120-
active_cell_values::Base.RefValue{ISV}
120+
cell_value_mid_interfaces::ISV #For getting stress at interface
121121

122122
iqr::QuadratureRule{dim_p,RefCube,T}
123123
oqr::QuadratureRule{1,RefCube,T}
@@ -128,6 +128,8 @@ struct IGAShellIntegrationData{dim_p,dim_s,T,ISV<:IGAShellValues,M}
128128
qr_vertices::Array{QuadratureRule{dim_p,RefCube,T}, 1}
129129

130130
cache_values::CachedOOPBasisValues{dim_p,T,M}
131+
interfacestresses::Array{SymmetricTensor{2,3,Float64,6},2} #rows: cells, cols: stress on interface/qp
132+
qpstresses::Vector{Vector{SymmetricTensor{2,3,Float64,6}}} #Vector of cells of qps stresses
131133

132134
extraction_operators::Vector{IGA.BezierExtractionOperator{T}}
133135
oop_order::Int
@@ -260,6 +262,15 @@ function IGAShellIntegrationData(data::IGAShellData{dim_p,dim_s,T}, C::Vector{IG
260262
cell_values_sr = IGAShellValues(data.thickness, QuadratureRule{dim_p,RefCube}(1), oqr, mid_ip, getnbasefunctions(cache.basis_values_discont), oop_ip)
261263
set_oop_basefunctions!(cell_values_sr, initial_basis_values)
262264

265+
#
266+
oop_ip = [ip_layered for i in 1:getnbasefunctions(mid_ip)]
267+
cell_values_mid_interface = IGAShellValues(data.thickness, QuadratureRule{dim_p,RefCube}(1), oqr_cohesive[1], mid_ip, getnbasefunctions(ip_layered), oop_ip)
268+
set_oop_basefunctions!(cell_values_mid_interface, cache.basis_cohesive_layered[1])
269+
270+
#Store stresses (cauchy) in gauss points and at interfaces
271+
interfacestresses = zeros(SymmetricTensor{2,3,T,6}, ninterfaces(data), getncells(data))
272+
qpstresses = [zeros(SymmetricTensor{2,3,T,6}, getnquadpoints(cell_values)) for _ in 1:getncells(data)]
273+
263274
###
264275
# Cohesive data
265276
cell_values_cohesive_top = IGAShellValues(data.thickness, iqr_inp_cohesive, oqr_cohesive[2], mid_ip, getnbasefunctions(ip_discont))
@@ -272,10 +283,9 @@ function IGAShellIntegrationData(data::IGAShellData{dim_p,dim_s,T}, C::Vector{IG
272283
cell_values_sr,
273284
cell_values_cohesive_top, cell_values_cohesive_bot,
274285
face_values, side_values, interface_values, vertices_values,
275-
#cell_values_face_top, cell_values_face_bot,
276-
Ref(cell_values), #Ref(face_values),
286+
cell_values_mid_interface,
277287
iqr, oqr, iqr_inp_cohesive, oqr_face, oqr_cohesive, iqr_sides, iqr_vertices,
278-
cache,
288+
cache, interfacestresses, qpstresses,
279289
C, order)
280290
end
281291

src/igashell_main.jl

+78-35
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,11 @@ function Five.assemble_stiffnessmatrix_and_forcevector!( dh::Ferrite.AbstractDof
401401
_assemble_stiffnessmatrix_and_forcevector!(dh, igashell, state, IGASHELL_STIFFMAT)
402402
end
403403

404+
405+
function Five.assemble_massmatrix!(dh::Ferrite.AbstractDofHandler, part::IGAShell, state::StateVariables)
406+
return nothing
407+
end
408+
404409
function _assemble_stiffnessmatrix_and_forcevector!( dh::Ferrite.AbstractDofHandler,
405410
igashell::IGAShell{dim_p,dim_s,T},
406411
state::StateVariables,
@@ -457,14 +462,15 @@ function _assemble_stiffnessmatrix_and_forcevector!( dh::Ferrite.AbstractDofHand
457462
ke = zeros(T, ndofs_layer, ndofs_layer)
458463

459464
states = @view materialstates[:, ilay]
465+
stress_state = igashell.integration_data.qpstresses[ic]
460466

461467
resize_cache2!(igashell.cache.cache2, ndofs_layer)
462468

463469
if assemtype == IGASHELL_STIFFMAT
464470
@timeit "integrate shell" _get_layer_forcevector_and_stiffnessmatrix!(
465471
cv,
466472
ke, fe,
467-
getmaterial(layerdata(igashell)), states,
473+
getmaterial(layerdata(igashell)), states, stress_state,
468474
ue_layer, ilay, nlayers(igashell), active_dofs,
469475
is_small_deformation_theory(layerdata(igashell)), IGASHELL_STIFFMAT, getwidth(layerdata(igashell)), igashell.cache.cache2)
470476

@@ -475,7 +481,7 @@ function _assemble_stiffnessmatrix_and_forcevector!( dh::Ferrite.AbstractDofHand
475481
@timeit "integrate shell" _get_layer_forcevector_and_stiffnessmatrix!(
476482
cv,
477483
ke, fe,
478-
getmaterial(layerdata(igashell)), ⁿstates,
484+
getmaterial(layerdata(igashell)), ⁿstates, stress_state,
479485
ue_layer, ilay, nlayers(igashell), active_dofs,
480486
is_small_deformation_theory(layerdata(igashell)), IGASHELL_FSTAR, getwidth(layerdata(igashell)), igashell.cache.cache2)
481487

@@ -538,7 +544,7 @@ function _assemble_stiffnessmatrix_and_forcevector!( dh::Ferrite.AbstractDofHand
538544

539545
states = @view interfacestates[:, iint]
540546

541-
active_dofs = active_interface_dofs[iint] #1:Ferrite.ndofs_per_cell(dh,ic)#
547+
active_dofs = 1:Ferrite.ndofs_per_cell(dh,ic)#active_interface_dofs[iint] #
542548
ndofs_interface = length(active_dofs)
543549

544550
resize!(ue_interface, ndofs_interface)
@@ -599,10 +605,6 @@ function _assemble_stiffnessmatrix_and_forcevector!( dh::Ferrite.AbstractDofHand
599605

600606
end
601607

602-
function Five.assemble_massmatrix!( dh::Ferrite.AbstractDofHandler, igashell::IGAShell{dim_p,dim_s,T}, system_arrays::StateVariables) where {dim_p,dim_s,T}
603-
604-
end
605-
606608
function Five.post_part!(dh, igashell::IGAShell{dim_p,dim_s,T}, states) where {dim_s, dim_p, T}
607609
#if dim_s == 2
608610
# return
@@ -612,50 +614,88 @@ function Five.post_part!(dh, igashell::IGAShell{dim_p,dim_s,T}, states) where {d
612614

613615
cellstate = getcellstate(adapdata(igashell), ic)
614616

615-
if !is_lumped(cellstate) && !is_layered(cellstate)
617+
if is_mixed(cellstate) || is_fully_discontiniuos(cellstate)
616618
continue
617619
end
618620

619621
#Get cellvalues for cell
620622
Ce = get_extraction_operator(intdata(igashell), ic)
621-
622-
#Extract stresses from states
623-
σ_states = states.partstates[ic].materialstates[:]
624-
σ_states = getproperty.(σ_states, )
623+
625624
#Data for cell
626625
_celldofs = celldofs(dh, cellid)
627626
ue = states.d[_celldofs]
628627

629628
nnodes = Ferrite.nnodes_per_cell(igashell)
630629
X = zeros(Vec{dim_s,T}, nnodes)
631630
Ferrite.cellcoords!(X, dh, cellid)
632-
Xᵇ= IGA.compute_bezier_points(Ce, X)
633-
celldata = (celldofs = _celldofs,
634-
Xᵇ=Xᵇ, X=X, ue=ue,
635-
nlayers=nlayers(igashell), ninterfaces=ninterfaces(igashell),
636-
cellid=cellid, ic=ic)
631+
Xᵇ = IGA.compute_bezier_points(Ce, X)
637632

638-
#Build basis_values for cell
639-
cv = build_cellvalue!(igashell, cellstate)
640-
IGA.set_bezier_operator!(cv, Ce)
641-
reinit!(cv, Xᵇ)
633+
if is_lumped(cellstate)
634+
_post_lumped(igashell, Xᵇ, X, ue, Ce, cellstate, ic, cellid)
635+
elseif is_layered(cellstate)
636+
_post_layered(igashell, Xᵇ, X, ue, Ce, cellstate, ic, cellid)
637+
else
638+
continue
639+
end
642640

643-
#Build basis_values for stress_recovory
644-
cv_sr = intdata(igashell).cell_values_sr
645-
oop_values = _build_oop_basisvalue!(igashell, cellstate)
646-
set_oop_basefunctions!(cv_sr, oop_values)
647-
IGA.set_bezier_operator!(cv_sr, Ce)
648-
reinit!(cv_sr, Xᵇ)
641+
end
649642

650-
recover_cell_stresses(srdata(igashell), σ_states, celldata, cv_sr, cv)
643+
end
644+
645+
function _post_layered(igashell, Xᵇ, X, ue, Ce, cellstate, ic::Int, cellid::Int)
646+
647+
#Shape values for evaluating stresses at center of cell
648+
cv_mid_interface = igashell.integration_data.cell_value_mid_interfaces
649+
set_bezier_operator!(cv_mid_interface, Ce)
650+
651+
#oop_values = _build_oop_basisvalue!(igashell, cellstate)
652+
#set_oop_basefunctions!(cv_mid_interface, oop_values)
653+
654+
reinit!(cv_mid_interface, Xᵇ)
655+
active_layer_dofs = build_active_layer_dofs(igashell, cellstate)
656+
657+
iqp = 0
658+
for ilay in 1:nlayers(igashell)-1
659+
iqp += 1
660+
active_dofs = active_layer_dofs[ilay]
661+
ue_layer = ue[active_dofs]
662+
663+
#Only one quad points per layer
664+
σ, _, _ = _eval_stress_center(cv_mid_interface, igashell.layerdata.layer_materials[ilay], iqp, Xᵇ, ue_layer, active_dofs, is_small_deformation_theory(igashell.layerdata))
665+
666+
igashell.integration_data.interfacestresses[ilay, ic] = σ
651667
end
668+
end
669+
670+
function _post_lumped(igashell, Xᵇ, X, ue, Ce, cellstate, ic::Int, cellid::Int)
652671

672+
#Extract stresses from states
673+
σ_states = igashell.integration_data.qpstresses[ic]
674+
675+
celldata = (Xᵇ=Xᵇ, X=X, ue=ue,
676+
nlayers=nlayers(igashell), ninterfaces=ninterfaces(igashell),
677+
cellid=cellid, ic=ic)
678+
679+
#Build basis_values for cell
680+
cv = build_cellvalue!(igashell, cellstate)
681+
IGA.set_bezier_operator!(cv, Ce)
682+
reinit!(cv, Xᵇ)
683+
684+
#Build basis_values for stress_recovory
685+
cv_sr = intdata(igashell).cell_values_sr
686+
oop_values = _build_oop_basisvalue!(igashell, cellstate)
687+
set_oop_basefunctions!(cv_sr, oop_values)
688+
IGA.set_bezier_operator!(cv_sr, Ce)
689+
reinit!(cv_sr, Xᵇ)
690+
691+
recover_cell_stresses(srdata(igashell), σ_states, celldata, cv_sr, cv)
692+
653693
end
654694

655695
function _get_layer_forcevector_and_stiffnessmatrix!(
656696
cv::IGAShellValues{dim_s,dim_p,T},
657697
ke::AbstractMatrix, fe::AbstractVector,
658-
material, materialstate,
698+
material, materialstate, stress_state,
659699
ue_layer::AbstractVector{T}, ilay::Int, nlayers::Int, active_dofs::Vector{Int},
660700
is_small_deformation_theory::Bool, calculate_what::IGASHELL_ASSEMBLETYPE, width::T, cache::IGAShellCacheSolid{dim_s,T}) where {dim_s,dim_p,T}
661701

@@ -704,13 +744,13 @@ function _get_layer_forcevector_and_stiffnessmatrix!(
704744
_calculate_linear_forces!(fe, ke, cv,
705745
ilay, qpᴸ, qp, width,
706746
F, R, δF, δɛ,
707-
material, materialstate,
747+
material, materialstate, stress_state,
708748
ndofs_layer)
709749
else
710750
_calculate_nonlinear_forces!(fe, ke, cv,
711751
ilay, qpᴸ, qp, width,
712752
F, R, δF, δɛ,
713-
material, materialstate,
753+
material, materialstate, stress_state,
714754
ndofs_layer)
715755
end
716756
elseif calculate_what === IGASHELL_FSTAR
@@ -727,7 +767,7 @@ function _get_layer_forcevector_and_stiffnessmatrix!(
727767

728768
end
729769

730-
function _calculate_linear_forces!(fe, ke, cv, ilay, layer_qp, qp, width, F::Tensor{2,dim_s}, R, δF, δɛ, material, materialstates, ndofs_layer) where {dim_s}
770+
function _calculate_linear_forces!(fe, ke, cv, ilay, layer_qp, qp, width, F::Tensor{2,dim_s}, R, δF, δɛ, material, materialstates, stress_state, ndofs_layer) where {dim_s}
731771
ɛ = symmetric(F) - one(SymmetricTensor{2,dim_s})
732772

733773
δɛ .= symmetric.(δF)
@@ -740,8 +780,7 @@ function _calculate_linear_forces!(fe, ke, cv, ilay, layer_qp, qp, width, F::Ten
740780
∂σ∂ɛ = otimesu(R,R) ∂̂σ∂ɛ otimesu(R',R')
741781
σ = R_̂σR'
742782

743-
#σ, ∂σ∂ɛ, new_matstate = constitutive_driver(material[ilay], ɛ, ⁿmaterialstates[layer_qp])
744-
#materialstates[layer_qp] = new_matstate
783+
stress_state[qp] = _to3d(_̂σ)
745784

746785
for i in 1:ndofs_layer
747786

@@ -762,7 +801,7 @@ function _calculate_linear_forces!(fe, ke, cv, ilay, layer_qp, qp, width, F::Ten
762801

763802
end
764803

765-
function _calculate_nonlinear_forces!(fe, ke, cv, ilay, layer_qp, qp, width, F, R, δF, δE, material, materialstates, ndofs_layer)
804+
function _calculate_nonlinear_forces!(fe, ke, cv, ilay, layer_qp, qp, width, F, R, δF, δE, material, materialstates, stress_state, ndofs_layer)
766805
= getdetJdV(cv,qp)*width
767806

768807
E = symmetric(1/2 * (F' F - one(F)))
@@ -774,6 +813,10 @@ function _calculate_nonlinear_forces!(fe, ke, cv, ilay, layer_qp, qp, width, F,
774813
∂S∂E = otimesu(R,R) _∂S∂E otimesu(R',R')
775814
S = R_SR'
776815

816+
σ = inv(det(F)) * symmetric(F S F')
817+
_̂σ = symmetric(R'σR)
818+
stress_state[qp] = _to3d(_̂σ)
819+
777820
#σ = inv(det(F)) * F ⋅ S ⋅ F'
778821

779822
# Hoist computations of δE

0 commit comments

Comments
 (0)